From 7861a4e3d9376c72bc81d50a245e0a5e03c209e1 Mon Sep 17 00:00:00 2001 From: petec Date: Tue, 27 Aug 2013 00:07:02 -0400 Subject: [PATCH 1/6] Remove WDL library repo from licecap repo --- .../InfoPlist.strings | 0 .../MainMenu.xib | 0 WDL/IPlug/Containers.h | 173 - WDL/IPlug/Example/IPlugExample.cpp | 185 - WDL/IPlug/Example/IPlugExample.exp | 2 - WDL/IPlug/Example/IPlugExample.h | 29 - WDL/IPlug/Example/IPlugExample.rc | 7 - WDL/IPlug/Example/IPlugExample.vcproj | 299 - .../IPlugExample.xcodeproj/project.pbxproj | 675 - WDL/IPlug/Example/IPlugExampleAU-Info.plist | 22 - WDL/IPlug/Example/IPlugExample_Prefix.pch | 7 - WDL/IPlug/Example/Info.plist | 26 - WDL/IPlug/Example/README.txt | 4 - WDL/IPlug/Example/img/BG_400x200.png | Bin 1856 -> 0 bytes WDL/IPlug/Example/img/VU-meter_sm.png | Bin 743112 -> 0 bytes WDL/IPlug/Example/img/fader-cap_sm.png | Bin 3733 -> 0 bytes WDL/IPlug/Example/img/knob_sm.png | Bin 4198 -> 0 bytes WDL/IPlug/Example/img/toggle-switch.png | Bin 18625 -> 0 bytes WDL/IPlug/Example/resource.h | 54 - WDL/IPlug/Hosts.cpp | 63 - WDL/IPlug/Hosts.h | 43 - WDL/IPlug/IControl.cpp | 449 - WDL/IPlug/IControl.h | 402 - WDL/IPlug/IGraphics.cpp | 446 - WDL/IPlug/IGraphics.h | 162 - WDL/IPlug/IGraphicsCarbon.cpp | 264 - WDL/IPlug/IGraphicsCarbon.h | 37 - WDL/IPlug/IGraphicsCocoa.h | 40 - WDL/IPlug/IGraphicsCocoa.mm | 156 - WDL/IPlug/IGraphicsLice.cpp | 295 - WDL/IPlug/IGraphicsLice.h | 68 - WDL/IPlug/IGraphicsMac.h | 96 - WDL/IPlug/IGraphicsMac.mm | 313 - WDL/IPlug/IGraphicsWin.cpp | 718 - WDL/IPlug/IGraphicsWin.h | 79 - WDL/IPlug/IParam.cpp | 185 - WDL/IPlug/IParam.h | 82 - WDL/IPlug/IPlug.sln | 39 - WDL/IPlug/IPlug.vcproj | 350 - WDL/IPlug/IPlug.vcxproj | 213 - WDL/IPlug/IPlug.xcodeproj/project.pbxproj | 1009 -- WDL/IPlug/IPlugAU.cpp | 1558 -- WDL/IPlug/IPlugAU.h | 147 - WDL/IPlug/IPlugAU.r | 140 - WDL/IPlug/IPlugAU_ViewFactory.mm | 50 - WDL/IPlug/IPlugBase.cpp | 692 - WDL/IPlug/IPlugBase.h | 247 - WDL/IPlug/IPlugStructs.cpp | 147 - WDL/IPlug/IPlugStructs.h | 300 - WDL/IPlug/IPlugVST.cpp | 685 - WDL/IPlug/IPlugVST.h | 84 - WDL/IPlug/IPlug_Prefix.pch | 7 - WDL/IPlug/IPlug_include_in_plug_hdr.h | 32 - WDL/IPlug/IPlug_include_in_plug_src.h | 94 - WDL/IPlug/Log.cpp | 405 - WDL/IPlug/Log.h | 56 - WDL/IPlug/README.txt | 4 - WDL/IPlug/VSTHosts.cpp | 55 - WDL/IPlug/VSTHosts.h | 32 - WDL/IPlug/lice.vcproj | 1165 -- WDL/MersenneTwister.h | 411 - WDL/adpcm_decode.h | 317 - WDL/adpcm_encode.h | 137 - WDL/assocarray.h | 317 - WDL/audiobuffercontainer.cpp | 495 - WDL/audiobuffercontainer.h | 106 - WDL/blowfish.c | 399 - WDL/blowfish.h | 23 - WDL/chunkalloc.h | 93 - WDL/circbuf.h | 171 - WDL/cmath/bessel_polynomial.h | 75 - WDL/cmath/complex_number.h | 368 - WDL/cmath/custom_math.h | 209 - WDL/cmath/durand_kerner.h | 117 - WDL/cmath/factorial.h | 114 - WDL/cmath/horner.h | 71 - WDL/cmath/test_bessel.c | 119 - WDL/cmath/test_eval.c | 87 - WDL/convoengine.cpp | 1057 -- WDL/convoengine.h | 161 - WDL/db2val.h | 22 - WDL/denormal.h | 166 - WDL/des.cpp | 325 - WDL/des.h | 34 - WDL/destroycheck.h | 65 - WDL/dirscan.h | 245 - WDL/eel2/.gitignore | 1 - WDL/eel2/Makefile | 22 - WDL/eel2/a2i.php | 243 - WDL/eel2/a2x64.php | 305 - WDL/eel2/asm-nseel-ppc-gcc.c | 1377 -- WDL/eel2/asm-nseel-x64-macho.asm | 1881 --- WDL/eel2/asm-nseel-x64-macho.o | Bin 9979 -> 0 bytes WDL/eel2/asm-nseel-x64.asm | 1880 --- WDL/eel2/asm-nseel-x64.obj | Bin 9975 -> 0 bytes WDL/eel2/asm-nseel-x86-gcc.c | 2035 --- WDL/eel2/asm-nseel-x86-msvc.c | 3931 ----- WDL/eel2/eel2.l | 73 - WDL/eel2/eel2.y | 147 - WDL/eel2/gen-lex-yacc | 1 - WDL/eel2/glue_port.h | 995 -- WDL/eel2/glue_ppc.h | 257 - WDL/eel2/glue_x86.h | 355 - WDL/eel2/glue_x86_64.h | 261 - WDL/eel2/ns-eel-addfuncs.h | 87 - WDL/eel2/ns-eel-int.h | 318 - WDL/eel2/ns-eel.h | 207 - WDL/eel2/nseel-caltab.c | 545 - WDL/eel2/nseel-cfunc.c | 133 - WDL/eel2/nseel-compiler.c | 4574 ------ WDL/eel2/nseel-eval.c | 151 - WDL/eel2/nseel-lextab.c | 290 - WDL/eel2/nseel-ram.c | 342 - WDL/eel2/nseel-yylex.c | 189 - WDL/eel2/preproc_test.cpp | 76 - WDL/eel2/test.cpp | 65 - WDL/eel2/test_vc6.dsp | 144 - WDL/eel2/test_vc6.dsw | 29 - WDL/eel2/y.tab.c | 1819 --- WDL/eel2/y.tab.h | 84 - WDL/fastqueue.h | 187 - WDL/ffmpeg.h | 533 - WDL/fft.c | 1647 --- WDL/fft.h | 73 - WDL/filebrowse.cpp | 380 - WDL/filebrowse.h | 52 - WDL/filename.h | 65 - WDL/fileread.h | 796 - WDL/filewrite.h | 642 - WDL/giflib/AUTHORS | 36 - WDL/giflib/COPYING | 19 - WDL/giflib/ChangeLog | 549 - WDL/giflib/DEVELOPERS | 29 - WDL/giflib/README | 69 - WDL/giflib/config.h | 11 - WDL/giflib/dgif_lib.c | 1088 -- WDL/giflib/egif_lib.c | 1103 -- WDL/giflib/gif_hash.c | 152 - WDL/giflib/gif_hash.h | 50 - WDL/giflib/gif_lib.h | 336 - WDL/giflib/gif_lib_private.h | 59 - WDL/giflib/gifalloc.c | 441 - WDL/gpu/gpu.cpp | 317 - WDL/gpu/gpu.h | 121 - WDL/gpu/wglext.h | 611 - WDL/heapbuf.h | 346 - WDL/history.txt | 470 - WDL/jnetlib/Makefile | 20 - WDL/jnetlib/asyncdns.cpp | 266 - WDL/jnetlib/asyncdns.h | 74 - WDL/jnetlib/connection.cpp | 479 - WDL/jnetlib/connection.h | 188 - WDL/jnetlib/httpget.cpp | 445 - WDL/jnetlib/httpget.h | 152 - WDL/jnetlib/httpserv.cpp | 254 - WDL/jnetlib/httpserv.h | 114 - WDL/jnetlib/irc_util.h | 59 - WDL/jnetlib/jnetlib.h | 47 - WDL/jnetlib/listen.cpp | 73 - WDL/jnetlib/listen.h | 62 - WDL/jnetlib/netinc.h | 75 - WDL/jnetlib/test.cpp | 555 - WDL/jnetlib/test.dsp | 166 - WDL/jnetlib/test.dsw | 29 - WDL/jnetlib/testbnc.cpp | 102 - WDL/jnetlib/util.cpp | 36 - WDL/jnetlib/util.h | 39 - WDL/jnetlib/webserver.cpp | 398 - WDL/jnetlib/webserver.h | 224 - WDL/jpeglib/README | 385 - WDL/jpeglib/example.c | 433 - WDL/jpeglib/jcapimin.c | 280 - WDL/jpeglib/jcapistd.c | 161 - WDL/jpeglib/jccoefct.c | 449 - WDL/jpeglib/jccolor.c | 459 - WDL/jpeglib/jcdctmgr.c | 387 - WDL/jpeglib/jchuff.c | 909 -- WDL/jpeglib/jchuff.h | 47 - WDL/jpeglib/jcinit.c | 72 - WDL/jpeglib/jcmainct.c | 293 - WDL/jpeglib/jcmarker.c | 664 - WDL/jpeglib/jcmaster.c | 590 - WDL/jpeglib/jcomapi.c | 106 - WDL/jpeglib/jconfig.h | 15 - WDL/jpeglib/jcparam.c | 610 - WDL/jpeglib/jcphuff.c | 833 -- WDL/jpeglib/jcprepct.c | 354 - WDL/jpeglib/jcsample.c | 519 - WDL/jpeglib/jctrans.c | 388 - WDL/jpeglib/jdapimin.c | 395 - WDL/jpeglib/jdapistd.c | 275 - WDL/jpeglib/jdatadst.c | 151 - WDL/jpeglib/jdatasrc.c | 212 - WDL/jpeglib/jdcoefct.c | 736 - WDL/jpeglib/jdcolor.c | 396 - WDL/jpeglib/jdct.h | 176 - WDL/jpeglib/jddctmgr.c | 269 - WDL/jpeglib/jdhuff.c | 651 - WDL/jpeglib/jdhuff.h | 201 - WDL/jpeglib/jdinput.c | 381 - WDL/jpeglib/jdmainct.c | 512 - WDL/jpeglib/jdmarker.c | 1360 -- WDL/jpeglib/jdmaster.c | 557 - WDL/jpeglib/jdmerge.c | 400 - WDL/jpeglib/jdphuff.c | 668 - WDL/jpeglib/jdpostct.c | 290 - WDL/jpeglib/jdsample.c | 478 - WDL/jpeglib/jdtrans.c | 143 - WDL/jpeglib/jerror.c | 252 - WDL/jpeglib/jerror.h | 291 - WDL/jpeglib/jfdctflt.c | 168 - WDL/jpeglib/jfdctfst.c | 224 - WDL/jpeglib/jfdctint.c | 283 - WDL/jpeglib/jidctflt.c | 242 - WDL/jpeglib/jidctfst.c | 368 - WDL/jpeglib/jidctint.c | 389 - WDL/jpeglib/jidctred.c | 398 - WDL/jpeglib/jinclude.h | 91 - WDL/jpeglib/jmemmgr.c | 1118 -- WDL/jpeglib/jmemnobs.c | 109 - WDL/jpeglib/jmemsys.h | 198 - WDL/jpeglib/jmorecfg.h | 363 - WDL/jpeglib/jpegint.h | 392 - WDL/jpeglib/jpeglib.h | 1096 -- WDL/jpeglib/jquant1.c | 856 -- WDL/jpeglib/jquant2.c | 1310 -- WDL/jpeglib/jutils.c | 179 - WDL/jpeglib/jversion.h | 14 - WDL/lameencdec.cpp | 1004 -- WDL/lameencdec.h | 136 - WDL/libpng/LICENSE | 111 - WDL/libpng/README | 202 - WDL/libpng/png.c | 2870 ---- WDL/libpng/png.h | 2654 ---- WDL/libpng/pngconf.h | 596 - WDL/libpng/pngdebug.h | 157 - WDL/libpng/pngerror.c | 685 - WDL/libpng/pngget.c | 1124 -- WDL/libpng/pnginfo.h | 269 - WDL/libpng/pnglibconf.h | 189 - WDL/libpng/pngmem.c | 667 - WDL/libpng/pngpread.c | 1846 --- WDL/libpng/pngpriv.h | 1629 -- WDL/libpng/pngread.c | 1308 -- WDL/libpng/pngrio.c | 176 - WDL/libpng/pngrtran.c | 5023 ------- WDL/libpng/pngrutil.c | 4160 ------ WDL/libpng/pngset.c | 1284 -- WDL/libpng/pngstruct.h | 360 - WDL/libpng/pngtest.c | 1820 --- WDL/libpng/pngtrans.c | 678 - WDL/libpng/pngwio.c | 254 - WDL/libpng/pngwrite.c | 1655 --- WDL/libpng/pngwtran.c | 633 - WDL/libpng/pngwutil.c | 3180 ---- WDL/lice/Makefile | 24 - WDL/lice/glew/include/GL/WGLEXT.H | 631 - WDL/lice/glew/include/GL/glew.h | 12262 ---------------- WDL/lice/glew/include/GL/glxew.h | 1397 -- WDL/lice/glew/include/GL/wglew.h | 1165 -- WDL/lice/glew/src/glew.c | 12180 --------------- WDL/lice/glew/src/glewinfo.c | 7180 --------- WDL/lice/glew/src/visualinfo.c | 1173 -- WDL/lice/lice.cpp | 2173 --- WDL/lice/lice.dsp | 942 -- WDL/lice/lice.dsw | 59 - WDL/lice/lice.h | 554 - WDL/lice/lice.vcxproj | 431 - WDL/lice/lice_arc.cpp | 496 - WDL/lice/lice_bezier.h | 295 - WDL/lice/lice_bmp.cpp | 114 - WDL/lice/lice_colorspace.cpp | 134 - WDL/lice/lice_combine.h | 831 -- WDL/lice/lice_extended.h | 164 - WDL/lice/lice_gif.cpp | 159 - WDL/lice/lice_gif_write.cpp | 323 - WDL/lice/lice_gl_ctx.cpp | 264 - WDL/lice/lice_gl_ctx.h | 27 - WDL/lice/lice_glbitmap.cpp | 708 - WDL/lice/lice_glbitmap.h | 110 - WDL/lice/lice_ico.cpp | 186 - WDL/lice/lice_image.cpp | 148 - WDL/lice/lice_jpg.cpp | 310 - WDL/lice/lice_jpg_write.cpp | 117 - WDL/lice/lice_lcf.cpp | 663 - WDL/lice/lice_lcf.h | 110 - WDL/lice/lice_line.cpp | 1612 -- WDL/lice/lice_lvg.cpp | 620 - WDL/lice/lice_palette.cpp | 327 - WDL/lice/lice_pcx.cpp | 108 - WDL/lice/lice_png.cpp | 364 - WDL/lice/lice_png_write.cpp | 131 - WDL/lice/lice_svg.cpp | 851 -- WDL/lice/lice_texgen.cpp | 341 - WDL/lice/lice_text.cpp | 1390 -- WDL/lice/lice_text.h | 110 - WDL/lice/lice_textnew.cpp | 1014 -- WDL/lice/makedist.bat | 2 - WDL/lice/test/Controller.h | 9 - WDL/lice/test/Controller.mm | 40 - WDL/lice/test/English.lproj/InfoPlist.strings | Bin 202 -> 0 bytes .../English.lproj/MainMenu.nib/classes.nib | 7 - .../test/English.lproj/MainMenu.nib/info.nib | 21 - .../MainMenu.nib/keyedobjects.nib | Bin 13648 -> 0 bytes WDL/lice/test/Info.plist | 28 - WDL/lice/test/fly.cpp | 286 - WDL/lice/test/image.png | Bin 4910 -> 0 bytes WDL/lice/test/imgs2gif.cpp | 100 - WDL/lice/test/main.cpp | 1026 -- WDL/lice/test/main.ico | Bin 24942 -> 0 bytes WDL/lice/test/main.m | 14 - WDL/lice/test/resource.h | 27 - WDL/lice/test/test.dsp | 120 - WDL/lice/test/test.rc | 107 - WDL/lice/test/test.xcodeproj/project.pbxproj | 918 -- WDL/lineparse.h | 331 - WDL/makedist.bat | 13 - WDL/mergesort.h | 65 - WDL/mp3write.h | 138 - WDL/mutex.h | 238 - WDL/nsv/nsvbs.h | 272 - WDL/nsv/nsvlib.cpp | 738 - WDL/nsv/nsvlib.h | 390 - WDL/pcmfmtcvt.h | 528 - WDL/plush2/pl_cam.cpp | 748 - WDL/plush2/pl_make.cpp | 480 - WDL/plush2/pl_math.cpp | 67 - WDL/plush2/pl_obj.cpp | 128 - WDL/plush2/pl_pf_tex.h | 442 - WDL/plush2/pl_putface.cpp | 707 - WDL/plush2/pl_read_3ds.cpp | 347 - WDL/plush2/pl_read_cob.cpp | 181 - WDL/plush2/pl_read_jaw.cpp | 69 - WDL/plush2/pl_spline.cpp | 50 - WDL/plush2/plush.h | 598 - WDL/plush2/plush2.dsp | 217 - WDL/poollist.h | 155 - WDL/projectcontext.cpp | 678 - WDL/projectcontext.h | 50 - WDL/ptrlist.h | 223 - WDL/queue.h | 273 - WDL/reminder.h | 13 - WDL/resample.cpp | 597 - WDL/resample.h | 101 - WDL/rfb_client.cpp | 443 - WDL/rfb_client.h | 70 - WDL/rng.cpp | 95 - WDL/rng.h | 42 - WDL/rpool.h | 186 - WDL/sc_bounce/stream-config.php | 21 - WDL/sc_bounce/stream.php | 243 - WDL/scsrc.cpp | 700 - WDL/scsrc.h | 114 - WDL/sha.cpp | 133 - WDL/sha.h | 54 - WDL/sharedpool.h | 128 - WDL/shm_connection.cpp | 521 - WDL/shm_connection.h | 87 - WDL/shm_msgreply.cpp | 346 - WDL/shm_msgreply.h | 86 - WDL/simple_pitchshift.h | 311 - WDL/simple_pitchshift2.h | 315 - WDL/sinewavegen.h | 59 - WDL/stringpool.h | 92 - WDL/swell/Makefile.libSwell | 65 - WDL/swell/commctrl.h | 1 - WDL/swell/mac_resgen.php | 283 - WDL/swell/make-libSwells.sh | 10 - .../English.lproj/InfoPlist.strings | Bin 92 -> 0 bytes .../sample_project/English.lproj/MainMenu.xib | 520 - WDL/swell/sample_project/Info.plist | 28 - WDL/swell/sample_project/app_main.cpp | 198 - WDL/swell/sample_project/main.h | 23 - WDL/swell/sample_project/main.m | 14 - WDL/swell/sample_project/main_dialog.cpp | 55 - WDL/swell/sample_project/resource.h | 21 - WDL/swell/sample_project/sample_project.dsp | 119 - WDL/swell/sample_project/sample_project.dsw | 29 - WDL/swell/sample_project/sample_project.rc | 118 - .../TemplateIcon.icns | Bin 52318 -> 0 bytes .../sample_project.xcodeproj/project.pbxproj | 369 - .../sample_project/sample_project_Prefix.pch | 7 - WDL/swell/sample_project/version.plist | 16 - WDL/swell/shlobj.h | 1 - WDL/swell/swell-appstub-generic.cpp | 44 - WDL/swell/swell-appstub.mm | 42 - WDL/swell/swell-dlg-generic.cpp | 212 - WDL/swell/swell-dlg.mm | 3214 ---- WDL/swell/swell-dlggen.h | 280 - WDL/swell/swell-functions.h | 1092 -- WDL/swell/swell-gdi-generic.cpp | 676 - WDL/swell/swell-gdi-internalpool.h | 194 - WDL/swell/swell-gdi-lice.cpp | 1284 -- WDL/swell/swell-gdi.mm | 1530 -- WDL/swell/swell-ini.cpp | 551 - WDL/swell/swell-internal.h | 758 - WDL/swell/swell-kb-generic.cpp | 110 - WDL/swell/swell-kb.mm | 601 - WDL/swell/swell-menu-generic.cpp | 631 - WDL/swell/swell-menu.mm | 919 -- WDL/swell/swell-menugen.h | 94 - WDL/swell/swell-misc-generic.cpp | 20 - WDL/swell/swell-misc.mm | 566 - WDL/swell/swell-miscdlg-generic.cpp | 184 - WDL/swell/swell-miscdlg-gtk.cpp | 141 - WDL/swell/swell-miscdlg.mm | 354 - WDL/swell/swell-modstub-generic.cpp | 111 - WDL/swell/swell-modstub.mm | 70 - WDL/swell/swell-types.h | 1337 -- WDL/swell/swell-wnd-generic.cpp | 3562 ----- WDL/swell/swell-wnd.mm | 6128 -------- WDL/swell/swell.cpp | 909 -- WDL/swell/swell.h | 147 - WDL/swell/swellappmain.h | 14 - WDL/swell/swellappmain.mm | 232 - WDL/swell/test-gtk.cpp | 16 - WDL/swell/test.cpp | 7 - WDL/swell/windows.h | 165 - WDL/timing.c | 85 - WDL/timing.h | 43 - WDL/tinyxml/libxml_tinyxml.cpp | 132 - WDL/tinyxml/libxml_tinyxml.h | 52 - WDL/tinyxml/svgtiny_colors.c | 955 -- WDL/tinyxml/tinystr.cpp | 116 - WDL/tinyxml/tinystr.h | 320 - WDL/tinyxml/tinyxml.cpp | 1888 --- WDL/tinyxml/tinyxml.h | 1802 --- WDL/tinyxml/tinyxmlerror.cpp | 53 - WDL/tinyxml/tinyxmlparser.cpp | 1638 --- WDL/verbengine.h | 298 - WDL/vorbisencdec.h | 468 - WDL/wavwrite.h | 318 - WDL/wdlcstring.h | 163 - WDL/wdlstring.h | 290 - WDL/wdltypes.h | 77 - WDL/win32_curses/curses.h | 180 - WDL/win32_curses/curses_win32.cpp | 742 - WDL/win32_curses/test.cpp | 80 - WDL/win32_utf8.c | 984 -- WDL/win32_utf8.h | 202 - WDL/win7filedialog.cpp | 507 - WDL/win7filedialog.h | 2206 --- WDL/wingui/dlgitemborder.h | 204 - WDL/wingui/membitmap.h | 94 - WDL/wingui/richeditctrl.h | 83 - WDL/wingui/scrollbar/coolscroll.cpp | 3741 ----- WDL/wingui/scrollbar/coolscroll.h | 93 - WDL/wingui/virtwnd-controls.h | 370 - WDL/wingui/virtwnd-iaccessible.cpp | 866 -- WDL/wingui/virtwnd-iconbutton.cpp | 1118 -- WDL/wingui/virtwnd-listbox.cpp | 728 - WDL/wingui/virtwnd-nsaccessibility.mm | 644 - WDL/wingui/virtwnd-skin.h | 91 - WDL/wingui/virtwnd-slider.cpp | 1173 -- WDL/wingui/virtwnd.cpp | 1635 --- WDL/wingui/virtwnd.h | 224 - WDL/wingui/wndsize.cpp | 349 - WDL/wingui/wndsize.h | 143 - WDL/zlib/adler32.c | 179 - WDL/zlib/compress.c | 80 - WDL/zlib/crc32.c | 449 - WDL/zlib/crc32.h | 441 - WDL/zlib/deflate.c | 1965 --- WDL/zlib/deflate.h | 346 - WDL/zlib/gzclose.c | 25 - WDL/zlib/gzguts.h | 190 - WDL/zlib/gzlib.c | 564 - WDL/zlib/gzread.c | 584 - WDL/zlib/gzwrite.c | 593 - WDL/zlib/infback.c | 640 - WDL/zlib/inffast.c | 340 - WDL/zlib/inffast.h | 11 - WDL/zlib/inffixed.h | 94 - WDL/zlib/inflate.c | 1501 -- WDL/zlib/inflate.h | 122 - WDL/zlib/inftrees.c | 306 - WDL/zlib/inftrees.h | 62 - WDL/zlib/ioapi.c | 247 - WDL/zlib/ioapi.h | 208 - WDL/zlib/trees.c | 1224 -- WDL/zlib/trees.h | 128 - WDL/zlib/uncompr.c | 59 - WDL/zlib/unzip.c | 2125 --- WDL/zlib/unzip.h | 437 - WDL/zlib/zconf.h | 466 - WDL/zlib/zconf.in.h | 332 - WDL/zlib/zip.c | 2012 --- WDL/zlib/zip.h | 362 - WDL/zlib/zlib.h | 1732 --- WDL/zlib/zutil.c | 303 - WDL/zlib/zutil.h | 248 - licecap/background.png => background.png | Bin licecap/capturewindow.mm => capturewindow.mm | 0 licecap/icon1.ico => icon1.ico | Bin licecap/installer.nsi => installer.nsi | 0 .../licecap-Info.plist => licecap-Info.plist | 0 licecap/licecap.dsw => licecap.dsw | 0 licecap/licecap.icns => licecap.icns | Bin licecap/licecap.rc => licecap.rc | 0 .../project.pbxproj | 0 .../licecap_Prefix.pch => licecap_Prefix.pch | 0 licecap/licecap_cli.cpp => licecap_cli.cpp | 0 licecap/licecap_cli.dsp => licecap_cli.dsp | 0 licecap/licecap_gui.dsp => licecap_gui.dsp | 0 licecap/licecap_ui.cpp => licecap_ui.cpp | 0 .../licecap_version.h => licecap_version.h | 0 licecap/license.txt => license.txt | 0 licecap/main.m => main.m | 0 licecap/makedmg.sh => makedmg.sh | 0 licecap/pkg-dmg => pkg-dmg | 0 licecap/requires_wdl.txt => requires_wdl.txt | 0 licecap/resource.h => resource.h | 0 licecap/stage_DS_Store => stage_DS_Store | Bin licecap/whatsnew.txt => whatsnew.txt | 0 514 files changed, 254056 deletions(-) rename {licecap/English.lproj => English.lproj}/InfoPlist.strings (100%) rename {licecap/English.lproj => English.lproj}/MainMenu.xib (100%) delete mode 100644 WDL/IPlug/Containers.h delete mode 100644 WDL/IPlug/Example/IPlugExample.cpp delete mode 100644 WDL/IPlug/Example/IPlugExample.exp delete mode 100644 WDL/IPlug/Example/IPlugExample.h delete mode 100644 WDL/IPlug/Example/IPlugExample.rc delete mode 100644 WDL/IPlug/Example/IPlugExample.vcproj delete mode 100644 WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj delete mode 100644 WDL/IPlug/Example/IPlugExampleAU-Info.plist delete mode 100644 WDL/IPlug/Example/IPlugExample_Prefix.pch delete mode 100644 WDL/IPlug/Example/Info.plist delete mode 100644 WDL/IPlug/Example/README.txt delete mode 100644 WDL/IPlug/Example/img/BG_400x200.png delete mode 100644 WDL/IPlug/Example/img/VU-meter_sm.png delete mode 100644 WDL/IPlug/Example/img/fader-cap_sm.png delete mode 100644 WDL/IPlug/Example/img/knob_sm.png delete mode 100644 WDL/IPlug/Example/img/toggle-switch.png delete mode 100644 WDL/IPlug/Example/resource.h delete mode 100644 WDL/IPlug/Hosts.cpp delete mode 100644 WDL/IPlug/Hosts.h delete mode 100644 WDL/IPlug/IControl.cpp delete mode 100644 WDL/IPlug/IControl.h delete mode 100644 WDL/IPlug/IGraphics.cpp delete mode 100644 WDL/IPlug/IGraphics.h delete mode 100644 WDL/IPlug/IGraphicsCarbon.cpp delete mode 100644 WDL/IPlug/IGraphicsCarbon.h delete mode 100644 WDL/IPlug/IGraphicsCocoa.h delete mode 100644 WDL/IPlug/IGraphicsCocoa.mm delete mode 100644 WDL/IPlug/IGraphicsLice.cpp delete mode 100644 WDL/IPlug/IGraphicsLice.h delete mode 100644 WDL/IPlug/IGraphicsMac.h delete mode 100644 WDL/IPlug/IGraphicsMac.mm delete mode 100644 WDL/IPlug/IGraphicsWin.cpp delete mode 100644 WDL/IPlug/IGraphicsWin.h delete mode 100644 WDL/IPlug/IParam.cpp delete mode 100644 WDL/IPlug/IParam.h delete mode 100644 WDL/IPlug/IPlug.sln delete mode 100644 WDL/IPlug/IPlug.vcproj delete mode 100644 WDL/IPlug/IPlug.vcxproj delete mode 100644 WDL/IPlug/IPlug.xcodeproj/project.pbxproj delete mode 100644 WDL/IPlug/IPlugAU.cpp delete mode 100644 WDL/IPlug/IPlugAU.h delete mode 100644 WDL/IPlug/IPlugAU.r delete mode 100644 WDL/IPlug/IPlugAU_ViewFactory.mm delete mode 100644 WDL/IPlug/IPlugBase.cpp delete mode 100644 WDL/IPlug/IPlugBase.h delete mode 100644 WDL/IPlug/IPlugStructs.cpp delete mode 100644 WDL/IPlug/IPlugStructs.h delete mode 100644 WDL/IPlug/IPlugVST.cpp delete mode 100644 WDL/IPlug/IPlugVST.h delete mode 100644 WDL/IPlug/IPlug_Prefix.pch delete mode 100644 WDL/IPlug/IPlug_include_in_plug_hdr.h delete mode 100644 WDL/IPlug/IPlug_include_in_plug_src.h delete mode 100644 WDL/IPlug/Log.cpp delete mode 100644 WDL/IPlug/Log.h delete mode 100644 WDL/IPlug/README.txt delete mode 100644 WDL/IPlug/VSTHosts.cpp delete mode 100644 WDL/IPlug/VSTHosts.h delete mode 100644 WDL/IPlug/lice.vcproj delete mode 100644 WDL/MersenneTwister.h delete mode 100644 WDL/adpcm_decode.h delete mode 100644 WDL/adpcm_encode.h delete mode 100644 WDL/assocarray.h delete mode 100644 WDL/audiobuffercontainer.cpp delete mode 100644 WDL/audiobuffercontainer.h delete mode 100644 WDL/blowfish.c delete mode 100644 WDL/blowfish.h delete mode 100644 WDL/chunkalloc.h delete mode 100644 WDL/circbuf.h delete mode 100644 WDL/cmath/bessel_polynomial.h delete mode 100644 WDL/cmath/complex_number.h delete mode 100644 WDL/cmath/custom_math.h delete mode 100644 WDL/cmath/durand_kerner.h delete mode 100644 WDL/cmath/factorial.h delete mode 100644 WDL/cmath/horner.h delete mode 100644 WDL/cmath/test_bessel.c delete mode 100644 WDL/cmath/test_eval.c delete mode 100644 WDL/convoengine.cpp delete mode 100644 WDL/convoengine.h delete mode 100644 WDL/db2val.h delete mode 100644 WDL/denormal.h delete mode 100644 WDL/des.cpp delete mode 100644 WDL/des.h delete mode 100644 WDL/destroycheck.h delete mode 100644 WDL/dirscan.h delete mode 100644 WDL/eel2/.gitignore delete mode 100644 WDL/eel2/Makefile delete mode 100644 WDL/eel2/a2i.php delete mode 100644 WDL/eel2/a2x64.php delete mode 100644 WDL/eel2/asm-nseel-ppc-gcc.c delete mode 100644 WDL/eel2/asm-nseel-x64-macho.asm delete mode 100644 WDL/eel2/asm-nseel-x64-macho.o delete mode 100644 WDL/eel2/asm-nseel-x64.asm delete mode 100644 WDL/eel2/asm-nseel-x64.obj delete mode 100644 WDL/eel2/asm-nseel-x86-gcc.c delete mode 100644 WDL/eel2/asm-nseel-x86-msvc.c delete mode 100644 WDL/eel2/eel2.l delete mode 100644 WDL/eel2/eel2.y delete mode 100644 WDL/eel2/gen-lex-yacc delete mode 100644 WDL/eel2/glue_port.h delete mode 100644 WDL/eel2/glue_ppc.h delete mode 100644 WDL/eel2/glue_x86.h delete mode 100644 WDL/eel2/glue_x86_64.h delete mode 100644 WDL/eel2/ns-eel-addfuncs.h delete mode 100644 WDL/eel2/ns-eel-int.h delete mode 100644 WDL/eel2/ns-eel.h delete mode 100644 WDL/eel2/nseel-caltab.c delete mode 100644 WDL/eel2/nseel-cfunc.c delete mode 100644 WDL/eel2/nseel-compiler.c delete mode 100644 WDL/eel2/nseel-eval.c delete mode 100644 WDL/eel2/nseel-lextab.c delete mode 100644 WDL/eel2/nseel-ram.c delete mode 100644 WDL/eel2/nseel-yylex.c delete mode 100644 WDL/eel2/preproc_test.cpp delete mode 100644 WDL/eel2/test.cpp delete mode 100644 WDL/eel2/test_vc6.dsp delete mode 100644 WDL/eel2/test_vc6.dsw delete mode 100644 WDL/eel2/y.tab.c delete mode 100644 WDL/eel2/y.tab.h delete mode 100644 WDL/fastqueue.h delete mode 100644 WDL/ffmpeg.h delete mode 100644 WDL/fft.c delete mode 100644 WDL/fft.h delete mode 100644 WDL/filebrowse.cpp delete mode 100644 WDL/filebrowse.h delete mode 100644 WDL/filename.h delete mode 100644 WDL/fileread.h delete mode 100644 WDL/filewrite.h delete mode 100644 WDL/giflib/AUTHORS delete mode 100644 WDL/giflib/COPYING delete mode 100644 WDL/giflib/ChangeLog delete mode 100644 WDL/giflib/DEVELOPERS delete mode 100644 WDL/giflib/README delete mode 100644 WDL/giflib/config.h delete mode 100644 WDL/giflib/dgif_lib.c delete mode 100644 WDL/giflib/egif_lib.c delete mode 100644 WDL/giflib/gif_hash.c delete mode 100644 WDL/giflib/gif_hash.h delete mode 100644 WDL/giflib/gif_lib.h delete mode 100644 WDL/giflib/gif_lib_private.h delete mode 100644 WDL/giflib/gifalloc.c delete mode 100644 WDL/gpu/gpu.cpp delete mode 100644 WDL/gpu/gpu.h delete mode 100644 WDL/gpu/wglext.h delete mode 100644 WDL/heapbuf.h delete mode 100644 WDL/history.txt delete mode 100644 WDL/jnetlib/Makefile delete mode 100644 WDL/jnetlib/asyncdns.cpp delete mode 100644 WDL/jnetlib/asyncdns.h delete mode 100644 WDL/jnetlib/connection.cpp delete mode 100644 WDL/jnetlib/connection.h delete mode 100644 WDL/jnetlib/httpget.cpp delete mode 100644 WDL/jnetlib/httpget.h delete mode 100644 WDL/jnetlib/httpserv.cpp delete mode 100644 WDL/jnetlib/httpserv.h delete mode 100644 WDL/jnetlib/irc_util.h delete mode 100644 WDL/jnetlib/jnetlib.h delete mode 100644 WDL/jnetlib/listen.cpp delete mode 100644 WDL/jnetlib/listen.h delete mode 100644 WDL/jnetlib/netinc.h delete mode 100644 WDL/jnetlib/test.cpp delete mode 100644 WDL/jnetlib/test.dsp delete mode 100644 WDL/jnetlib/test.dsw delete mode 100644 WDL/jnetlib/testbnc.cpp delete mode 100644 WDL/jnetlib/util.cpp delete mode 100644 WDL/jnetlib/util.h delete mode 100644 WDL/jnetlib/webserver.cpp delete mode 100644 WDL/jnetlib/webserver.h delete mode 100644 WDL/jpeglib/README delete mode 100644 WDL/jpeglib/example.c delete mode 100644 WDL/jpeglib/jcapimin.c delete mode 100644 WDL/jpeglib/jcapistd.c delete mode 100644 WDL/jpeglib/jccoefct.c delete mode 100644 WDL/jpeglib/jccolor.c delete mode 100644 WDL/jpeglib/jcdctmgr.c delete mode 100644 WDL/jpeglib/jchuff.c delete mode 100644 WDL/jpeglib/jchuff.h delete mode 100644 WDL/jpeglib/jcinit.c delete mode 100644 WDL/jpeglib/jcmainct.c delete mode 100644 WDL/jpeglib/jcmarker.c delete mode 100644 WDL/jpeglib/jcmaster.c delete mode 100644 WDL/jpeglib/jcomapi.c delete mode 100644 WDL/jpeglib/jconfig.h delete mode 100644 WDL/jpeglib/jcparam.c delete mode 100644 WDL/jpeglib/jcphuff.c delete mode 100644 WDL/jpeglib/jcprepct.c delete mode 100644 WDL/jpeglib/jcsample.c delete mode 100644 WDL/jpeglib/jctrans.c delete mode 100644 WDL/jpeglib/jdapimin.c delete mode 100644 WDL/jpeglib/jdapistd.c delete mode 100644 WDL/jpeglib/jdatadst.c delete mode 100644 WDL/jpeglib/jdatasrc.c delete mode 100644 WDL/jpeglib/jdcoefct.c delete mode 100644 WDL/jpeglib/jdcolor.c delete mode 100644 WDL/jpeglib/jdct.h delete mode 100644 WDL/jpeglib/jddctmgr.c delete mode 100644 WDL/jpeglib/jdhuff.c delete mode 100644 WDL/jpeglib/jdhuff.h delete mode 100644 WDL/jpeglib/jdinput.c delete mode 100644 WDL/jpeglib/jdmainct.c delete mode 100644 WDL/jpeglib/jdmarker.c delete mode 100644 WDL/jpeglib/jdmaster.c delete mode 100644 WDL/jpeglib/jdmerge.c delete mode 100644 WDL/jpeglib/jdphuff.c delete mode 100644 WDL/jpeglib/jdpostct.c delete mode 100644 WDL/jpeglib/jdsample.c delete mode 100644 WDL/jpeglib/jdtrans.c delete mode 100644 WDL/jpeglib/jerror.c delete mode 100644 WDL/jpeglib/jerror.h delete mode 100644 WDL/jpeglib/jfdctflt.c delete mode 100644 WDL/jpeglib/jfdctfst.c delete mode 100644 WDL/jpeglib/jfdctint.c delete mode 100644 WDL/jpeglib/jidctflt.c delete mode 100644 WDL/jpeglib/jidctfst.c delete mode 100644 WDL/jpeglib/jidctint.c delete mode 100644 WDL/jpeglib/jidctred.c delete mode 100644 WDL/jpeglib/jinclude.h delete mode 100644 WDL/jpeglib/jmemmgr.c delete mode 100644 WDL/jpeglib/jmemnobs.c delete mode 100644 WDL/jpeglib/jmemsys.h delete mode 100644 WDL/jpeglib/jmorecfg.h delete mode 100644 WDL/jpeglib/jpegint.h delete mode 100644 WDL/jpeglib/jpeglib.h delete mode 100644 WDL/jpeglib/jquant1.c delete mode 100644 WDL/jpeglib/jquant2.c delete mode 100644 WDL/jpeglib/jutils.c delete mode 100644 WDL/jpeglib/jversion.h delete mode 100644 WDL/lameencdec.cpp delete mode 100644 WDL/lameencdec.h delete mode 100644 WDL/libpng/LICENSE delete mode 100644 WDL/libpng/README delete mode 100644 WDL/libpng/png.c delete mode 100644 WDL/libpng/png.h delete mode 100644 WDL/libpng/pngconf.h delete mode 100644 WDL/libpng/pngdebug.h delete mode 100644 WDL/libpng/pngerror.c delete mode 100644 WDL/libpng/pngget.c delete mode 100644 WDL/libpng/pnginfo.h delete mode 100644 WDL/libpng/pnglibconf.h delete mode 100644 WDL/libpng/pngmem.c delete mode 100644 WDL/libpng/pngpread.c delete mode 100644 WDL/libpng/pngpriv.h delete mode 100644 WDL/libpng/pngread.c delete mode 100644 WDL/libpng/pngrio.c delete mode 100644 WDL/libpng/pngrtran.c delete mode 100644 WDL/libpng/pngrutil.c delete mode 100644 WDL/libpng/pngset.c delete mode 100644 WDL/libpng/pngstruct.h delete mode 100644 WDL/libpng/pngtest.c delete mode 100644 WDL/libpng/pngtrans.c delete mode 100644 WDL/libpng/pngwio.c delete mode 100644 WDL/libpng/pngwrite.c delete mode 100644 WDL/libpng/pngwtran.c delete mode 100644 WDL/libpng/pngwutil.c delete mode 100644 WDL/lice/Makefile delete mode 100644 WDL/lice/glew/include/GL/WGLEXT.H delete mode 100644 WDL/lice/glew/include/GL/glew.h delete mode 100644 WDL/lice/glew/include/GL/glxew.h delete mode 100644 WDL/lice/glew/include/GL/wglew.h delete mode 100644 WDL/lice/glew/src/glew.c delete mode 100644 WDL/lice/glew/src/glewinfo.c delete mode 100644 WDL/lice/glew/src/visualinfo.c delete mode 100644 WDL/lice/lice.cpp delete mode 100644 WDL/lice/lice.dsp delete mode 100644 WDL/lice/lice.dsw delete mode 100644 WDL/lice/lice.h delete mode 100644 WDL/lice/lice.vcxproj delete mode 100644 WDL/lice/lice_arc.cpp delete mode 100644 WDL/lice/lice_bezier.h delete mode 100644 WDL/lice/lice_bmp.cpp delete mode 100644 WDL/lice/lice_colorspace.cpp delete mode 100644 WDL/lice/lice_combine.h delete mode 100644 WDL/lice/lice_extended.h delete mode 100644 WDL/lice/lice_gif.cpp delete mode 100644 WDL/lice/lice_gif_write.cpp delete mode 100644 WDL/lice/lice_gl_ctx.cpp delete mode 100644 WDL/lice/lice_gl_ctx.h delete mode 100644 WDL/lice/lice_glbitmap.cpp delete mode 100644 WDL/lice/lice_glbitmap.h delete mode 100644 WDL/lice/lice_ico.cpp delete mode 100644 WDL/lice/lice_image.cpp delete mode 100644 WDL/lice/lice_jpg.cpp delete mode 100644 WDL/lice/lice_jpg_write.cpp delete mode 100644 WDL/lice/lice_lcf.cpp delete mode 100644 WDL/lice/lice_lcf.h delete mode 100644 WDL/lice/lice_line.cpp delete mode 100644 WDL/lice/lice_lvg.cpp delete mode 100644 WDL/lice/lice_palette.cpp delete mode 100644 WDL/lice/lice_pcx.cpp delete mode 100644 WDL/lice/lice_png.cpp delete mode 100644 WDL/lice/lice_png_write.cpp delete mode 100644 WDL/lice/lice_svg.cpp delete mode 100644 WDL/lice/lice_texgen.cpp delete mode 100644 WDL/lice/lice_text.cpp delete mode 100644 WDL/lice/lice_text.h delete mode 100644 WDL/lice/lice_textnew.cpp delete mode 100644 WDL/lice/makedist.bat delete mode 100644 WDL/lice/test/Controller.h delete mode 100644 WDL/lice/test/Controller.mm delete mode 100644 WDL/lice/test/English.lproj/InfoPlist.strings delete mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/classes.nib delete mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/info.nib delete mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib delete mode 100644 WDL/lice/test/Info.plist delete mode 100644 WDL/lice/test/fly.cpp delete mode 100644 WDL/lice/test/image.png delete mode 100644 WDL/lice/test/imgs2gif.cpp delete mode 100644 WDL/lice/test/main.cpp delete mode 100644 WDL/lice/test/main.ico delete mode 100644 WDL/lice/test/main.m delete mode 100644 WDL/lice/test/resource.h delete mode 100644 WDL/lice/test/test.dsp delete mode 100644 WDL/lice/test/test.rc delete mode 100644 WDL/lice/test/test.xcodeproj/project.pbxproj delete mode 100644 WDL/lineparse.h delete mode 100644 WDL/makedist.bat delete mode 100644 WDL/mergesort.h delete mode 100644 WDL/mp3write.h delete mode 100644 WDL/mutex.h delete mode 100644 WDL/nsv/nsvbs.h delete mode 100644 WDL/nsv/nsvlib.cpp delete mode 100644 WDL/nsv/nsvlib.h delete mode 100644 WDL/pcmfmtcvt.h delete mode 100644 WDL/plush2/pl_cam.cpp delete mode 100644 WDL/plush2/pl_make.cpp delete mode 100644 WDL/plush2/pl_math.cpp delete mode 100644 WDL/plush2/pl_obj.cpp delete mode 100644 WDL/plush2/pl_pf_tex.h delete mode 100644 WDL/plush2/pl_putface.cpp delete mode 100644 WDL/plush2/pl_read_3ds.cpp delete mode 100644 WDL/plush2/pl_read_cob.cpp delete mode 100644 WDL/plush2/pl_read_jaw.cpp delete mode 100644 WDL/plush2/pl_spline.cpp delete mode 100644 WDL/plush2/plush.h delete mode 100644 WDL/plush2/plush2.dsp delete mode 100644 WDL/poollist.h delete mode 100644 WDL/projectcontext.cpp delete mode 100644 WDL/projectcontext.h delete mode 100644 WDL/ptrlist.h delete mode 100644 WDL/queue.h delete mode 100644 WDL/reminder.h delete mode 100644 WDL/resample.cpp delete mode 100644 WDL/resample.h delete mode 100644 WDL/rfb_client.cpp delete mode 100644 WDL/rfb_client.h delete mode 100644 WDL/rng.cpp delete mode 100644 WDL/rng.h delete mode 100644 WDL/rpool.h delete mode 100644 WDL/sc_bounce/stream-config.php delete mode 100644 WDL/sc_bounce/stream.php delete mode 100644 WDL/scsrc.cpp delete mode 100644 WDL/scsrc.h delete mode 100644 WDL/sha.cpp delete mode 100644 WDL/sha.h delete mode 100644 WDL/sharedpool.h delete mode 100644 WDL/shm_connection.cpp delete mode 100644 WDL/shm_connection.h delete mode 100644 WDL/shm_msgreply.cpp delete mode 100644 WDL/shm_msgreply.h delete mode 100644 WDL/simple_pitchshift.h delete mode 100644 WDL/simple_pitchshift2.h delete mode 100644 WDL/sinewavegen.h delete mode 100644 WDL/stringpool.h delete mode 100644 WDL/swell/Makefile.libSwell delete mode 100644 WDL/swell/commctrl.h delete mode 100755 WDL/swell/mac_resgen.php delete mode 100644 WDL/swell/make-libSwells.sh delete mode 100644 WDL/swell/sample_project/English.lproj/InfoPlist.strings delete mode 100644 WDL/swell/sample_project/English.lproj/MainMenu.xib delete mode 100644 WDL/swell/sample_project/Info.plist delete mode 100644 WDL/swell/sample_project/app_main.cpp delete mode 100644 WDL/swell/sample_project/main.h delete mode 100644 WDL/swell/sample_project/main.m delete mode 100644 WDL/swell/sample_project/main_dialog.cpp delete mode 100644 WDL/swell/sample_project/resource.h delete mode 100644 WDL/swell/sample_project/sample_project.dsp delete mode 100644 WDL/swell/sample_project/sample_project.dsw delete mode 100644 WDL/swell/sample_project/sample_project.rc delete mode 100644 WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns delete mode 100644 WDL/swell/sample_project/sample_project.xcodeproj/project.pbxproj delete mode 100644 WDL/swell/sample_project/sample_project_Prefix.pch delete mode 100644 WDL/swell/sample_project/version.plist delete mode 100644 WDL/swell/shlobj.h delete mode 100644 WDL/swell/swell-appstub-generic.cpp delete mode 100644 WDL/swell/swell-appstub.mm delete mode 100644 WDL/swell/swell-dlg-generic.cpp delete mode 100644 WDL/swell/swell-dlg.mm delete mode 100644 WDL/swell/swell-dlggen.h delete mode 100644 WDL/swell/swell-functions.h delete mode 100644 WDL/swell/swell-gdi-generic.cpp delete mode 100644 WDL/swell/swell-gdi-internalpool.h delete mode 100644 WDL/swell/swell-gdi-lice.cpp delete mode 100644 WDL/swell/swell-gdi.mm delete mode 100644 WDL/swell/swell-ini.cpp delete mode 100644 WDL/swell/swell-internal.h delete mode 100644 WDL/swell/swell-kb-generic.cpp delete mode 100644 WDL/swell/swell-kb.mm delete mode 100644 WDL/swell/swell-menu-generic.cpp delete mode 100644 WDL/swell/swell-menu.mm delete mode 100644 WDL/swell/swell-menugen.h delete mode 100644 WDL/swell/swell-misc-generic.cpp delete mode 100644 WDL/swell/swell-misc.mm delete mode 100644 WDL/swell/swell-miscdlg-generic.cpp delete mode 100644 WDL/swell/swell-miscdlg-gtk.cpp delete mode 100644 WDL/swell/swell-miscdlg.mm delete mode 100644 WDL/swell/swell-modstub-generic.cpp delete mode 100644 WDL/swell/swell-modstub.mm delete mode 100644 WDL/swell/swell-types.h delete mode 100644 WDL/swell/swell-wnd-generic.cpp delete mode 100644 WDL/swell/swell-wnd.mm delete mode 100644 WDL/swell/swell.cpp delete mode 100644 WDL/swell/swell.h delete mode 100644 WDL/swell/swellappmain.h delete mode 100644 WDL/swell/swellappmain.mm delete mode 100644 WDL/swell/test-gtk.cpp delete mode 100644 WDL/swell/test.cpp delete mode 100644 WDL/swell/windows.h delete mode 100644 WDL/timing.c delete mode 100644 WDL/timing.h delete mode 100644 WDL/tinyxml/libxml_tinyxml.cpp delete mode 100644 WDL/tinyxml/libxml_tinyxml.h delete mode 100644 WDL/tinyxml/svgtiny_colors.c delete mode 100644 WDL/tinyxml/tinystr.cpp delete mode 100644 WDL/tinyxml/tinystr.h delete mode 100644 WDL/tinyxml/tinyxml.cpp delete mode 100644 WDL/tinyxml/tinyxml.h delete mode 100644 WDL/tinyxml/tinyxmlerror.cpp delete mode 100644 WDL/tinyxml/tinyxmlparser.cpp delete mode 100644 WDL/verbengine.h delete mode 100644 WDL/vorbisencdec.h delete mode 100644 WDL/wavwrite.h delete mode 100644 WDL/wdlcstring.h delete mode 100644 WDL/wdlstring.h delete mode 100644 WDL/wdltypes.h delete mode 100644 WDL/win32_curses/curses.h delete mode 100644 WDL/win32_curses/curses_win32.cpp delete mode 100644 WDL/win32_curses/test.cpp delete mode 100644 WDL/win32_utf8.c delete mode 100644 WDL/win32_utf8.h delete mode 100644 WDL/win7filedialog.cpp delete mode 100644 WDL/win7filedialog.h delete mode 100644 WDL/wingui/dlgitemborder.h delete mode 100644 WDL/wingui/membitmap.h delete mode 100644 WDL/wingui/richeditctrl.h delete mode 100644 WDL/wingui/scrollbar/coolscroll.cpp delete mode 100644 WDL/wingui/scrollbar/coolscroll.h delete mode 100644 WDL/wingui/virtwnd-controls.h delete mode 100644 WDL/wingui/virtwnd-iaccessible.cpp delete mode 100644 WDL/wingui/virtwnd-iconbutton.cpp delete mode 100644 WDL/wingui/virtwnd-listbox.cpp delete mode 100644 WDL/wingui/virtwnd-nsaccessibility.mm delete mode 100644 WDL/wingui/virtwnd-skin.h delete mode 100644 WDL/wingui/virtwnd-slider.cpp delete mode 100644 WDL/wingui/virtwnd.cpp delete mode 100644 WDL/wingui/virtwnd.h delete mode 100644 WDL/wingui/wndsize.cpp delete mode 100644 WDL/wingui/wndsize.h delete mode 100644 WDL/zlib/adler32.c delete mode 100644 WDL/zlib/compress.c delete mode 100644 WDL/zlib/crc32.c delete mode 100644 WDL/zlib/crc32.h delete mode 100644 WDL/zlib/deflate.c delete mode 100644 WDL/zlib/deflate.h delete mode 100644 WDL/zlib/gzclose.c delete mode 100644 WDL/zlib/gzguts.h delete mode 100644 WDL/zlib/gzlib.c delete mode 100644 WDL/zlib/gzread.c delete mode 100644 WDL/zlib/gzwrite.c delete mode 100644 WDL/zlib/infback.c delete mode 100644 WDL/zlib/inffast.c delete mode 100644 WDL/zlib/inffast.h delete mode 100644 WDL/zlib/inffixed.h delete mode 100644 WDL/zlib/inflate.c delete mode 100644 WDL/zlib/inflate.h delete mode 100644 WDL/zlib/inftrees.c delete mode 100644 WDL/zlib/inftrees.h delete mode 100644 WDL/zlib/ioapi.c delete mode 100644 WDL/zlib/ioapi.h delete mode 100644 WDL/zlib/trees.c delete mode 100644 WDL/zlib/trees.h delete mode 100644 WDL/zlib/uncompr.c delete mode 100644 WDL/zlib/unzip.c delete mode 100644 WDL/zlib/unzip.h delete mode 100644 WDL/zlib/zconf.h delete mode 100644 WDL/zlib/zconf.in.h delete mode 100644 WDL/zlib/zip.c delete mode 100644 WDL/zlib/zip.h delete mode 100644 WDL/zlib/zlib.h delete mode 100644 WDL/zlib/zutil.c delete mode 100644 WDL/zlib/zutil.h rename licecap/background.png => background.png (100%) rename licecap/capturewindow.mm => capturewindow.mm (100%) rename licecap/icon1.ico => icon1.ico (100%) rename licecap/installer.nsi => installer.nsi (100%) rename licecap/licecap-Info.plist => licecap-Info.plist (100%) rename licecap/licecap.dsw => licecap.dsw (100%) rename licecap/licecap.icns => licecap.icns (100%) rename licecap/licecap.rc => licecap.rc (100%) rename {licecap/licecap.xcodeproj => licecap.xcodeproj}/project.pbxproj (100%) rename licecap/licecap_Prefix.pch => licecap_Prefix.pch (100%) rename licecap/licecap_cli.cpp => licecap_cli.cpp (100%) rename licecap/licecap_cli.dsp => licecap_cli.dsp (100%) rename licecap/licecap_gui.dsp => licecap_gui.dsp (100%) rename licecap/licecap_ui.cpp => licecap_ui.cpp (100%) rename licecap/licecap_version.h => licecap_version.h (100%) rename licecap/license.txt => license.txt (100%) rename licecap/main.m => main.m (100%) rename licecap/makedmg.sh => makedmg.sh (100%) rename licecap/pkg-dmg => pkg-dmg (100%) rename licecap/requires_wdl.txt => requires_wdl.txt (100%) rename licecap/resource.h => resource.h (100%) rename licecap/stage_DS_Store => stage_DS_Store (100%) rename licecap/whatsnew.txt => whatsnew.txt (100%) diff --git a/licecap/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings similarity index 100% rename from licecap/English.lproj/InfoPlist.strings rename to English.lproj/InfoPlist.strings diff --git a/licecap/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib similarity index 100% rename from licecap/English.lproj/MainMenu.xib rename to English.lproj/MainMenu.xib diff --git a/WDL/IPlug/Containers.h b/WDL/IPlug/Containers.h deleted file mode 100644 index f8da2cb6..00000000 --- a/WDL/IPlug/Containers.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef _CONTAINERS_ -#define _CONTAINERS_ - -#ifdef WIN32 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#undef WINVER -#define WINVER 0x0501 -#pragma warning(disable:4018 4267) // size_t/signed/unsigned mismatch.. -#pragma warning(disable:4800) // if (pointer) ... -#pragma warning(disable:4805) // Compare bool and BOOL. -#endif - -#include -#include -#include -#include -#include "../mutex.h" -#include "../wdlstring.h" -#include "../ptrlist.h" - -#define FREE_NULL(p) {free(p);p=0;} -#define DELETE_NULL(p) {delete(p); p=0;} -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define MAX(x,y) ((x)<(y)?(y):(x)) -#define BOUNDED(x,lo,hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) -#define CSTR_NOT_EMPTY(cStr) ((cStr) && (cStr)[0] != '\0') - -#define MAKE_QUOTE(str) #str -#define MAKE_STR(str) MAKE_QUOTE(str) - -#define PI 3.141592653589793238 -#define AMP_DB 8.685889638065036553 -#define IAMP_DB 0.11512925464970 - -inline double DBToAmp(double dB) -{ - return exp(IAMP_DB * dB); -} - -inline double AmpToDB(double amp) -{ - return AMP_DB * log(fabs(amp)); -} - -#ifndef REMINDER - #if defined WIN32 - // This enables: #pragma REMINDER("change this line!") with click-through from VC++. - #define REMINDER(msg) message(__FILE__ "(" MAKE_STR(__LINE__) "): " msg) - #else if defined __APPLE__ - #define REMINDER(msg) WARNING msg - #endif -#endif - -template inline void SWAP(T& a, T& b) -{ - T tmp = a; a = b; b = tmp; -} - -typedef unsigned char BYTE; -class ByteChunk -{ -public: - - ByteChunk() {} - ~ByteChunk() {} - - template inline int Put(const T* pVal) - { - int n = mBytes.GetSize(); - mBytes.Resize(n + sizeof(T)); - memcpy(mBytes.Get() + n, (BYTE*) pVal, sizeof(T)); - return mBytes.GetSize(); - } - - template inline int Get(T* pVal, int startPos) - { - int endPos = startPos + sizeof(T); - if (startPos >= 0 && endPos <= mBytes.GetSize()) { - memcpy((BYTE*) pVal, mBytes.Get() + startPos, sizeof(T)); - return endPos; - } - return -1; - } - - inline int PutStr(const char* str) - { - int slen = strlen(str); - Put(&slen); - int n = mBytes.GetSize(); - mBytes.Resize(n + slen); - memcpy(mBytes.Get() + n, (BYTE*) str, slen); - return mBytes.GetSize(); - } - - inline int GetStr(WDL_String* pStr, int startPos) - { - int len; - int strStartPos = Get(&len, startPos); - if (strStartPos >= 0) { - int strEndPos = strStartPos + len; - if (strEndPos <= mBytes.GetSize() && len > 0) { - pStr->Set((char*) (mBytes.Get() + strStartPos), len); - } - return strEndPos; - } - return -1; - } - - inline int PutBool(bool b) - { - int n = mBytes.GetSize(); - mBytes.Resize(n + 1); - *(mBytes.Get() + n) = (BYTE) (b ? 1 : 0); - return mBytes.GetSize(); - } - - inline int GetBool(bool* pB, int startPos) - { - int endPos = startPos + 1; - if (startPos >= 0 && endPos <= mBytes.GetSize()) { - BYTE byt = *(mBytes.Get() + startPos); - *pB = (byt); - return endPos; - } - return -1; - } - - inline int PutChunk(ByteChunk* pRHS) - { - int n = mBytes.GetSize(); - int nRHS = pRHS->Size(); - mBytes.Resize(n + nRHS); - memcpy(mBytes.Get() + n, pRHS->GetBytes(), nRHS); - return mBytes.GetSize(); - } - - inline void Clear() - { - mBytes.Resize(0); - } - - inline int Size() - { - return mBytes.GetSize(); - } - - inline int Resize(int newSize) - { - int n = mBytes.GetSize(); - mBytes.Resize(newSize); - if (newSize > n) { - memset(mBytes.Get() + n, 0, (newSize - n)); - } - return n; - } - - inline BYTE* GetBytes() - { - return mBytes.Get(); - } - - inline bool IsEqual(ByteChunk* pRHS) - { - return (pRHS && pRHS->Size() == Size() && !memcmp(pRHS->GetBytes(), GetBytes(), Size())); - } - -private: - - WDL_TypedBuf mBytes; -}; - -#endif diff --git a/WDL/IPlug/Example/IPlugExample.cpp b/WDL/IPlug/Example/IPlugExample.cpp deleted file mode 100644 index 6deda431..00000000 --- a/WDL/IPlug/Example/IPlugExample.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "IPlugExample.h" -#include "../IPlug_include_in_plug_src.h" -#include "../IControl.h" -#include "resource.h" -#include - -const int kNumPrograms = 1; - -enum EParams { - kGainL = 0, - kGainR, - kPan, - kChannelSw, - kNumParams -}; - -enum EChannelSwitch { - kDefault = 0, - kReversed, - kAllLeft, - kAllRight, - kOff, - kNumChannelSwitchEnums -}; - -enum ELayout -{ - kW = 400, - kH = 200, - - kSwitch_N = 5, // # of sub-bitmaps. - kMeter_N = 51, // # of sub-bitmaps. - - kFader_Len = 150, - kGainL_X = 80, - kGainL_Y = 20, - kGainR_X = 350, - kGainR_Y = 20, - - kSwitch_X = 20, - kSwitch_Y = 40, - - kPan_X = 225, - kPan_Y = 145, - - kMeterL_X = 135, - kMeterL_Y = 20, - kMeterR_X = 250, - kMeterR_Y = 20 -}; - -PlugExample::PlugExample(IPlugInstanceInfo instanceInfo) -: IPLUG_CTOR(kNumParams, 6, instanceInfo), prevL(0.0), prevR(0.0) -{ - TRACE; - - // Define parameter ranges, display units, labels. - - GetParam(kGainL)->InitDouble("Gain L", 0.0, -44.0, 12.0, 0.1, "dB"); - GetParam(kGainL)->NegateDisplay(); - GetParam(kGainR)->InitDouble("Gain R", 0.0, -44.0, 12.0, 0.1, "dB"); - GetParam(kPan)->InitInt("Pan", 0, -100, 100, "%"); - - // Params can be enums. - - GetParam(kChannelSw)->InitEnum("Channel", kDefault, kNumChannelSwitchEnums); - GetParam(kChannelSw)->SetDisplayText(kDefault, "default"); - GetParam(kChannelSw)->SetDisplayText(kReversed, "reversed"); - GetParam(kChannelSw)->SetDisplayText(kAllLeft, "all L"); - GetParam(kChannelSw)->SetDisplayText(kAllRight, "all R"); - GetParam(kChannelSw)->SetDisplayText(kOff, "mute"); - - MakePreset("preset 1", -5.0, 5.0, 17, kReversed); - MakePreset("preset 2", -15.0, 25.0, 37, kAllRight); - MakeDefaultPreset("-", 4); - - // Instantiate a graphics engine. - - IGraphics* pGraphics = MakeGraphics(this, kW, kH); // MakeGraphics(this, kW, kH); - pGraphics->AttachBackground(BG_ID, BG_FN); - - // Attach controls to the graphics engine. Controls are automatically associated - // with a parameter if you construct the control with a parameter index. - - // Attach a couple of meters, not associated with any parameter, - // which we keep indexes for, so we can push updates from the plugin class. - - IBitmap bitmap = pGraphics->LoadIBitmap(METER_ID, METER_FN, kMeter_N); - mMeterIdx_L = pGraphics->AttachControl(new IBitmapControl(this, kMeterL_X, kMeterL_Y, &bitmap)); - mMeterIdx_R = pGraphics->AttachControl(new IBitmapControl(this, kMeterR_X, kMeterR_Y, &bitmap)); - - // Attach a couple of faders, associated with the parameters GainL and GainR. - - bitmap = pGraphics->LoadIBitmap(FADER_ID, FADER_FN); - pGraphics->AttachControl(new IFaderControl(this, kGainL_X, kGainL_Y, kFader_Len, kGainL, &bitmap, kVertical)); - pGraphics->AttachControl(new IFaderControl(this, kGainR_X, kGainR_Y, kFader_Len, kGainR, &bitmap, kVertical)); - - // Attach a 5-position switch associated with the ChannelSw parameter. - - bitmap = pGraphics->LoadIBitmap(TOGGLE_ID, TOGGLE_FN, kSwitch_N); - pGraphics->AttachControl(new ISwitchControl(this, kSwitch_X, kSwitch_Y, kChannelSw, &bitmap)); - - // Attach a rotating knob associated with the Pan parameter. - - bitmap = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN); - pGraphics->AttachControl(new IKnobRotaterControl(this, kPan_X, kPan_Y, kPan, &bitmap)); - - // See IControl.h for other control types, - // IKnobMultiControl, ITextControl, IBitmapOverlayControl, IFileSelectorControl, IGraphControl, etc. - - // Attach the graphics engine to the plugin. - - AttachGraphics(pGraphics); - - // No cleanup necessary, the graphics engine manages all of its resources and cleans up when closed. -} - -void PlugExample::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames) -{ - // Mutex is already locked for us. - - double* in1 = inputs[0]; - double* in2 = inputs[1]; - double* out1 = outputs[0]; - double* out2 = outputs[1]; - - double gain1 = GetParam(kGainL)->DBToAmp(); - double gain2 = GetParam(kGainR)->DBToAmp(); - double pan = 0.01 * GetParam(kPan)->Value(); - EChannelSwitch chanSwitch = (EChannelSwitch) int(GetParam(kChannelSw)->Value()); - double peakL = 0.0, peakR = 0.0; - - for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2) { - - *out1 = *in1 * gain1 * (1.0 - pan); - *out2 = *in2 * gain2 * (1.0 + pan); - - // In an actual plugin you'd switch outside of the sample loop, - // it's very inefficient to switch on every sample like this. - - switch (chanSwitch) { - - case kReversed: - SWAP(*out1, *out2); - break; - - case kAllLeft: - *out1 += *out2; - *out2 = 0.0; - break; - - case kAllRight: - *out2 += *out1; - *out1 = 0.0; - break; - - case kOff: - *out1 = *out2 = 0.0; - break; - - default: - break; - } - - peakL = MAX(peakL, fabs(*out1)); - peakR = MAX(peakR, fabs(*out2)); - } - - const double METER_ATTACK = 0.6, METER_DECAY = 0.1; - double xL = (peakL < prevL ? METER_DECAY : METER_ATTACK); - double xR = (peakR < prevR ? METER_DECAY : METER_ATTACK); - - peakL = peakL * xL + prevL * (1.0 - xL); - peakR = peakR * xR + prevR * (1.0 - xR); - - prevL = peakL; - prevR = peakR; - - if (GetGUI()) { - GetGUI()->SetControlFromPlug(mMeterIdx_L, peakL); - GetGUI()->SetControlFromPlug(mMeterIdx_R, peakR); - } -} - - diff --git a/WDL/IPlug/Example/IPlugExample.exp b/WDL/IPlug/Example/IPlugExample.exp deleted file mode 100644 index 77215542..00000000 --- a/WDL/IPlug/Example/IPlugExample.exp +++ /dev/null @@ -1,2 +0,0 @@ -_PlugExample_Entry -_PlugExample_ViewEntry diff --git a/WDL/IPlug/Example/IPlugExample.h b/WDL/IPlug/Example/IPlugExample.h deleted file mode 100644 index 17595840..00000000 --- a/WDL/IPlug/Example/IPlugExample.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __PLUGEXAMPLE__ -#define __PLUGEXAMPLE__ - -// In the project settings, define either VST_API or AU_API. -#include "../IPlug_include_in_plug_hdr.h" - -class PlugExample : public IPlug -{ -public: - - PlugExample(IPlugInstanceInfo instanceInfo); - ~PlugExample() {} // Nothing to clean up. - - // Implement these if your audio or GUI logic requires doing something - // when params change or when audio processing stops/starts. - void Reset() {} - void OnParamChange(int paramIdx) {} - - void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames); - -private: - - int mMeterIdx_L, mMeterIdx_R; - double prevL, prevR; -}; - -//////////////////////////////////////// - -#endif diff --git a/WDL/IPlug/Example/IPlugExample.rc b/WDL/IPlug/Example/IPlugExample.rc deleted file mode 100644 index 472169ca..00000000 --- a/WDL/IPlug/Example/IPlugExample.rc +++ /dev/null @@ -1,7 +0,0 @@ -#include "resource.h" - -TOGGLE_ID PNG TOGGLE_FN -KNOB_ID PNG KNOB_FN -FADER_ID PNG FADER_FN -BG_ID PNG BG_FN -METER_ID PNG METER_FN diff --git a/WDL/IPlug/Example/IPlugExample.vcproj b/WDL/IPlug/Example/IPlugExample.vcproj deleted file mode 100644 index 973e432e..00000000 --- a/WDL/IPlug/Example/IPlugExample.vcproj +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj b/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj deleted file mode 100644 index ec3ceb55..00000000 --- a/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj +++ /dev/null @@ -1,675 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 44; - objects = { - -/* Begin PBXBuildFile section */ - 45BFA26B1060DF5E00307BE8 /* libIPlug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BFA2581060DDDB00307BE8 /* libIPlug.a */; }; - 45BFA2861060DFDB00307BE8 /* libIPlug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BFA2581060DDDB00307BE8 /* libIPlug.a */; }; - 522988B10D14D52B00B3A00C /* IPlugExample.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */; }; - 523F19130D19AD7600ACA98D /* BG_400x200.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440E0D0E55A200961B48 /* BG_400x200.png */; }; - 523F19140D19AD7A00ACA98D /* fader-cap_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */; }; - 523F19150D19AD7E00ACA98D /* knob_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844100D0E55A200961B48 /* knob_sm.png */; }; - 523F19160D19AD8100ACA98D /* toggle-switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844110D0E55A200961B48 /* toggle-switch.png */; }; - 523F19170D19AD8500ACA98D /* VU-meter_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844120D0E55A200961B48 /* VU-meter_sm.png */; }; - 525FE3870D15C0E900E4C9FB /* IPlugAU.r in Rez */ = {isa = PBXBuildFile; fileRef = 525FE3860D15C0E900E4C9FB /* IPlugAU.r */; }; - 526F9C020D7DC7D700562CF8 /* IPlugExample.exp in Sources */ = {isa = PBXBuildFile; fileRef = 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */; }; - 526F9C030D7DC7D700562CF8 /* IPlugExample.exp in Sources */ = {isa = PBXBuildFile; fileRef = 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */; }; - 52780D5E0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */; }; - 52C4DB190D0E51270007A920 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; }; - 52E41BB70D14C11C00A0943B /* IPlugExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */; }; - 52E41C7A0D14C12800A0943B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; }; - 52E41C7F0D14C12C00A0943B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; - 52E41DA70D14C2DC00A0943B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D920D14C2D600A0943B /* AudioToolbox.framework */; }; - 52E41DA80D14C2DF00A0943B /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */; }; - 52E41DA90D14C2E400A0943B /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CC40D14C2B000A0943B /* CoreServices.framework */; }; - 52E41DAA0D14C2E700A0943B /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CB90D14C2A900A0943B /* CoreAudio.framework */; }; - 52E844130D0E55A200961B48 /* BG_400x200.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440E0D0E55A200961B48 /* BG_400x200.png */; }; - 52E844140D0E55A200961B48 /* fader-cap_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */; }; - 52E844150D0E55A200961B48 /* knob_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844100D0E55A200961B48 /* knob_sm.png */; }; - 52E844160D0E55A200961B48 /* toggle-switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844110D0E55A200961B48 /* toggle-switch.png */; }; - 52E844170D0E55A200961B48 /* VU-meter_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844120D0E55A200961B48 /* VU-meter_sm.png */; }; - 52FBBED10D0CF139001C8B8A /* IPlugExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */; }; - 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 45BFA2571060DDDB00307BE8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = D2AAC07E0554694100DB518D; - remoteInfo = IPlug; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 522988A80D14D49B00B3A00C /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 525C4CEC0D1CD7EE00AB2038 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 7; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 32DBCF630370AF2F00C91783 /* IPlugExample_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugExample_Prefix.pch; sourceTree = ""; }; - 525FE3860D15C0E900E4C9FB /* IPlugAU.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = IPlugAU.r; path = ../IPlugAU.r; sourceTree = SOURCE_ROOT; }; - 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = IPlugExample.exp; sourceTree = ""; }; - 5276FBE30D158937006A299A /* IPlug_include_in_plug_hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_hdr.h; path = ../IPlug_include_in_plug_hdr.h; sourceTree = SOURCE_ROOT; }; - 5276FBE40D15893B006A299A /* IPlug_include_in_plug_src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_src.h; path = ../IPlug_include_in_plug_src.h; sourceTree = SOURCE_ROOT; }; - 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IPlugAU_ViewFactory.mm; path = ../IPlugAU_ViewFactory.mm; sourceTree = SOURCE_ROOT; }; - 528A62261159258E00BD5F20 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; - 528A62281159258E00BD5F20 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; - 528A622A1159258E00BD5F20 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 528A622C1159258E00BD5F20 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - 52C4DB180D0E51270007A920 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = IPlug.xcodeproj; path = ../IPlug.xcodeproj; sourceTree = SOURCE_ROOT; }; - 52E41BB20D14C0F500A0943B /* IPlugExample.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPlugExample.component; sourceTree = BUILT_PRODUCTS_DIR; }; - 52E41BB30D14C0F500A0943B /* IPlugExampleAU-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "IPlugExampleAU-Info.plist"; sourceTree = ""; }; - 52E41CB90D14C2A900A0943B /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; - 52E41CC40D14C2B000A0943B /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; - 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; - 52E41D920D14C2D600A0943B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; - 52E8440E0D0E55A200961B48 /* BG_400x200.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = BG_400x200.png; sourceTree = ""; }; - 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "fader-cap_sm.png"; sourceTree = ""; }; - 52E844100D0E55A200961B48 /* knob_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = knob_sm.png; sourceTree = ""; }; - 52E844110D0E55A200961B48 /* toggle-switch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "toggle-switch.png"; sourceTree = ""; }; - 52E844120D0E55A200961B48 /* VU-meter_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "VU-meter_sm.png"; sourceTree = ""; }; - 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugExample.cpp; sourceTree = ""; }; - 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugExample.h; sourceTree = ""; }; - 52FBBED30D0CF143001C8B8A /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = ""; }; - 8D5B49B6048680CD000E48DA /* IPlugExample.vst */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPlugExample.vst; sourceTree = BUILT_PRODUCTS_DIR; }; - 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 52E41BB00D14C0F500A0943B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 52E41C7A0D14C12800A0943B /* Carbon.framework in Frameworks */, - 52E41C7F0D14C12C00A0943B /* Cocoa.framework in Frameworks */, - 52E41DA70D14C2DC00A0943B /* AudioToolbox.framework in Frameworks */, - 52E41DA80D14C2DF00A0943B /* AudioUnit.framework in Frameworks */, - 52E41DA90D14C2E400A0943B /* CoreServices.framework in Frameworks */, - 52E41DAA0D14C2E700A0943B /* CoreAudio.framework in Frameworks */, - 45BFA2861060DFDB00307BE8 /* libIPlug.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D5B49B3048680CD000E48DA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, - 52C4DB190D0E51270007A920 /* Carbon.framework in Frameworks */, - 45BFA26B1060DF5E00307BE8 /* libIPlug.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 089C166AFE841209C02AAC07 /* IPlugExample */ = { - isa = PBXGroup; - children = ( - 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */, - 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */, - 525FE3860D15C0E900E4C9FB /* IPlugAU.r */, - 5276FBE40D15893B006A299A /* IPlug_include_in_plug_src.h */, - 5276FBE30D158937006A299A /* IPlug_include_in_plug_hdr.h */, - 52FBBED30D0CF143001C8B8A /* resource.h */, - 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */, - 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */, - 08FB77AFFE84173DC02AAC07 /* Classes */, - 32C88E010371C26100C91783 /* Other Sources */, - 089C167CFE841241C02AAC07 /* Resources */, - 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, - 19C28FB8FE9D52D311CA2CBB /* Products */, - ); - name = IPlugExample; - sourceTree = ""; - }; - 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, - 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, - ); - name = "Frameworks and Libraries"; - sourceTree = ""; - }; - 089C167CFE841241C02AAC07 /* Resources */ = { - isa = PBXGroup; - children = ( - 52E8440D0D0E55A200961B48 /* img */, - 8D5B49B7048680CD000E48DA /* Info.plist */, - 52E41BB30D14C0F500A0943B /* IPlugExampleAU-Info.plist */, - ); - name = Resources; - sourceTree = ""; - }; - 08FB77AFFE84173DC02AAC07 /* Classes */ = { - isa = PBXGroup; - children = ( - ); - name = Classes; - sourceTree = ""; - }; - 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */, - 52E41D920D14C2D600A0943B /* AudioToolbox.framework */, - 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */, - 52E41CC40D14C2B000A0943B /* CoreServices.framework */, - 52E41CB90D14C2A900A0943B /* CoreAudio.framework */, - 52C4DB180D0E51270007A920 /* Carbon.framework */, - 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, - 528A62261159258E00BD5F20 /* AudioUnit.framework */, - 528A62281159258E00BD5F20 /* Carbon.framework */, - 528A622A1159258E00BD5F20 /* Cocoa.framework */, - 528A622C1159258E00BD5F20 /* CoreAudio.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 089C167FFE841241C02AAC07 /* AppKit.framework */, - D2F7E65807B2D6F200F64583 /* CoreData.framework */, - 089C1672FE841209C02AAC07 /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FB8FE9D52D311CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D5B49B6048680CD000E48DA /* IPlugExample.vst */, - 52E41BB20D14C0F500A0943B /* IPlugExample.component */, - ); - name = Products; - sourceTree = ""; - }; - 32C88E010371C26100C91783 /* Other Sources */ = { - isa = PBXGroup; - children = ( - 32DBCF630370AF2F00C91783 /* IPlugExample_Prefix.pch */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 45BFA2541060DDDB00307BE8 /* Products */ = { - isa = PBXGroup; - children = ( - 45BFA2581060DDDB00307BE8 /* libIPlug.a */, - ); - name = Products; - sourceTree = ""; - }; - 52E8440D0D0E55A200961B48 /* img */ = { - isa = PBXGroup; - children = ( - 52E8440E0D0E55A200961B48 /* BG_400x200.png */, - 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */, - 52E844100D0E55A200961B48 /* knob_sm.png */, - 52E844110D0E55A200961B48 /* toggle-switch.png */, - 52E844120D0E55A200961B48 /* VU-meter_sm.png */, - ); - path = img; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 522988B40D14D54000B3A00C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 522988B10D14D52B00B3A00C /* IPlugExample.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 52E41BB10D14C0F500A0943B /* IPlugExampleAU */ = { - isa = PBXNativeTarget; - buildConfigurationList = 52E41BB60D14C0F500A0943B /* Build configuration list for PBXNativeTarget "IPlugExampleAU" */; - buildPhases = ( - 522988B40D14D54000B3A00C /* Headers */, - 52E41BAE0D14C0F500A0943B /* Resources */, - 52E41BAF0D14C0F500A0943B /* Sources */, - 52E41BB00D14C0F500A0943B /* Frameworks */, - 5229883B0D14CE8600B3A00C /* Rez */, - 522988A80D14D49B00B3A00C /* CopyFiles */, - 525C4CEC0D1CD7EE00AB2038 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = IPlugExampleAU; - productName = IPlugExampleAU; - productReference = 52E41BB20D14C0F500A0943B /* IPlugExample.component */; - productType = "com.apple.product-type.bundle"; - }; - 8D5B49AC048680CD000E48DA /* IPlugExample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "IPlugExample" */; - buildPhases = ( - 8D5B49AF048680CD000E48DA /* Resources */, - 8D5B49B1048680CD000E48DA /* Sources */, - 8D5B49B3048680CD000E48DA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = IPlugExample; - productInstallPath = "$(HOME)/Library/Bundles"; - productName = IPlugExample; - productReference = 8D5B49B6048680CD000E48DA /* IPlugExample.vst */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 089C1669FE841209C02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "IPlugExample" */; - compatibilityVersion = "Xcode 3.0"; - hasScannedForEncodings = 1; - mainGroup = 089C166AFE841209C02AAC07 /* IPlugExample */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 45BFA2541060DDDB00307BE8 /* Products */; - ProjectRef = 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 8D5B49AC048680CD000E48DA /* IPlugExample */, - 52E41BB10D14C0F500A0943B /* IPlugExampleAU */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 45BFA2581060DDDB00307BE8 /* libIPlug.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libIPlug.a; - remoteRef = 45BFA2571060DDDB00307BE8 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 52E41BAE0D14C0F500A0943B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 523F19130D19AD7600ACA98D /* BG_400x200.png in Resources */, - 523F19140D19AD7A00ACA98D /* fader-cap_sm.png in Resources */, - 523F19150D19AD7E00ACA98D /* knob_sm.png in Resources */, - 523F19160D19AD8100ACA98D /* toggle-switch.png in Resources */, - 523F19170D19AD8500ACA98D /* VU-meter_sm.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D5B49AF048680CD000E48DA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 52E844130D0E55A200961B48 /* BG_400x200.png in Resources */, - 52E844140D0E55A200961B48 /* fader-cap_sm.png in Resources */, - 52E844150D0E55A200961B48 /* knob_sm.png in Resources */, - 52E844160D0E55A200961B48 /* toggle-switch.png in Resources */, - 52E844170D0E55A200961B48 /* VU-meter_sm.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXRezBuildPhase section */ - 5229883B0D14CE8600B3A00C /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - 525FE3870D15C0E900E4C9FB /* IPlugAU.r in Rez */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXRezBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 52E41BAF0D14C0F500A0943B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 52E41BB70D14C11C00A0943B /* IPlugExample.cpp in Sources */, - 52780D5E0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm in Sources */, - 526F9C020D7DC7D700562CF8 /* IPlugExample.exp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D5B49B1048680CD000E48DA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 52FBBED10D0CF139001C8B8A /* IPlugExample.cpp in Sources */, - 526F9C030D7DC7D700562CF8 /* IPlugExample.exp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB913B08733D840010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = VST_API; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "$(HOME)/Library/Bundles"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../IPlug/build/Debug\"", - ); - PRODUCT_NAME = IPlugExample; - WRAPPER_EXTENSION = vst; - ZERO_LINK = YES; - }; - name = Debug; - }; - 1DEB913C08733D840010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = VST_API; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "$(HOME)/Library/Bundles"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../IPlug/build/Debug\"", - ); - PRODUCT_NAME = IPlugExample; - WRAPPER_EXTENSION = vst; - }; - name = Release; - }; - 1DEB913F08733D840010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_EXTENSION = ""; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - HEADER_SEARCH_PATHS = ( - ., - ../IPlug, - ); - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_PREPROCESS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - WRAPPER_EXTENSION = ""; - }; - name = Debug; - }; - 1DEB914008733D840010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - EXECUTABLE_EXTENSION = ""; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - HEADER_SEARCH_PATHS = ( - ., - ../IPlug, - ); - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_PREPROCESS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - WRAPPER_EXTENSION = ""; - }; - name = Release; - }; - 528359A90D7F0C3A00577159 /* Tracer */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - EXECUTABLE_EXTENSION = ""; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - HEADER_SEARCH_PATHS = ( - ., - ../IPlug, - ); - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_PREPROCESS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - WRAPPER_EXTENSION = ""; - }; - name = Tracer; - }; - 528359AA0D7F0C3A00577159 /* Tracer */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = VST_API; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "$(HOME)/Library/Bundles"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../IPlug/build/Debug\"", - ); - PRODUCT_NAME = IPlugExample; - WRAPPER_EXTENSION = vst; - }; - name = Tracer; - }; - 528359AB0D7F0C3A00577159 /* Tracer */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - EXPORTED_SYMBOLS_FILE = IPlugExample.exp; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G4; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - TRACER_BUILD, - AU_API, - ); - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; - INFOPLIST_PREPROCESS = YES; - INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; - LIBRARY_SEARCH_PATHS = ( - ../IPlug/Build/Tracer, - "\"$(SRCROOT)/../Crypto/build/Release\"", - ); - LIBRARY_STYLE = Bundle; - OTHER_LDFLAGS = "-bundle"; - OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; - PREBINDING = YES; - PRODUCT_NAME = IPlugExample; - REZ_SEARCH_PATHS = ( - /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, - /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, - ); - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; - WRAPPER_EXTENSION = component; - ZERO_LINK = NO; - }; - name = Tracer; - }; - 52E41BB40D14C0F500A0943B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - EXPORTED_SYMBOLS_FILE = IPlugExample.exp; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G4; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = AU_API; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; - INFOPLIST_PREPROCESS = YES; - INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; - LIBRARY_SEARCH_PATHS = ( - "\"$(SRCROOT)/../IPlug/build/Debug\"", - "\"$(SRCROOT)/../Crypto/build/Release\"", - ); - LIBRARY_STYLE = Bundle; - OTHER_LDFLAGS = "-bundle"; - OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; - PREBINDING = YES; - PRODUCT_NAME = IPlugExample; - REZ_SEARCH_PATHS = ( - /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, - /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, - ); - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; - WRAPPER_EXTENSION = component; - ZERO_LINK = NO; - }; - name = Debug; - }; - 52E41BB50D14C0F500A0943B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - EXPORTED_SYMBOLS_FILE = IPlugExample.exp; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G4; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = AU_API; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; - INFOPLIST_PREPROCESS = YES; - INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; - LIBRARY_SEARCH_PATHS = ( - ../IPlug/Build/Release, - "\"$(SRCROOT)/../Crypto/build/Release\"", - ); - LIBRARY_STYLE = Bundle; - OTHER_LDFLAGS = "-bundle"; - OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; - PREBINDING = YES; - PRODUCT_NAME = IPlugExample; - REZ_SEARCH_PATHS = ( - /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, - /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, - ); - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; - WRAPPER_EXTENSION = component; - ZERO_LINK = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "IPlugExample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB913B08733D840010E9CD /* Debug */, - 1DEB913C08733D840010E9CD /* Release */, - 528359AA0D7F0C3A00577159 /* Tracer */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "IPlugExample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB913F08733D840010E9CD /* Debug */, - 1DEB914008733D840010E9CD /* Release */, - 528359A90D7F0C3A00577159 /* Tracer */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 52E41BB60D14C0F500A0943B /* Build configuration list for PBXNativeTarget "IPlugExampleAU" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 52E41BB40D14C0F500A0943B /* Debug */, - 52E41BB50D14C0F500A0943B /* Release */, - 528359AB0D7F0C3A00577159 /* Tracer */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 089C1669FE841209C02AAC07 /* Project object */; -} diff --git a/WDL/IPlug/Example/IPlugExampleAU-Info.plist b/WDL/IPlug/Example/IPlugExampleAU-Info.plist deleted file mode 100644 index 6f397ec4..00000000 --- a/WDL/IPlug/Example/IPlugExampleAU-Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.Schwa.audiounit.IPlugExample - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSPrincipalClass - PlugExample_View - - diff --git a/WDL/IPlug/Example/IPlugExample_Prefix.pch b/WDL/IPlug/Example/IPlugExample_Prefix.pch deleted file mode 100644 index 4d9bfcab..00000000 --- a/WDL/IPlug/Example/IPlugExample_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'IPlugExample' target in the 'IPlugExample' project. -// - -#ifdef __OBJC__ - #import -#endif diff --git a/WDL/IPlug/Example/Info.plist b/WDL/IPlug/Example/Info.plist deleted file mode 100644 index c9e1c5a2..00000000 --- a/WDL/IPlug/Example/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleName - ${PRODUCT_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.Schwa.vst.IPlugExample - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSPrincipalClass - - - diff --git a/WDL/IPlug/Example/README.txt b/WDL/IPlug/Example/README.txt deleted file mode 100644 index 3a49dbaa..00000000 --- a/WDL/IPlug/Example/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -IPlug version 20070607 - -The image files in this package were created by White Tie. You may not use these images as part of any product that is offered for sale. - diff --git a/WDL/IPlug/Example/img/BG_400x200.png b/WDL/IPlug/Example/img/BG_400x200.png deleted file mode 100644 index 43f57061bcedf7e9f9b51a8d32ee8a467bfa5076..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1856 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpWt8ulAh%XTY(f~age(c!@6@aFM%AEbVpxD z28NCO+hglc$SgNJZS+>y5k(1_I0*H&wc`AG0_*SD`3Q(B}KS$AStD3W^_ir@1#U zG`1Y@Tp}`wfsyI|dj(b|7LE`Wp0K5wmYf0~TA#9U2)y9J69Y#H zP=2|#C+8V%i8Vik85|ZUCv32a_4G=JJCJa8J_7@jEMxQ4mtH|kpPAUQ|FJLtO^{gQ z7d}a7hPXk*XLW`K2loRBrMo6gIk2bU;4FJa1{NzOw$+!XE@64b%5&`xCxgNTL4%07 z>r_+?^b}xnU>V(ly7)=YKIbyV27#gKxT&Y6Kg$+w8R{^Un22WQ%mvv4F FO#oXOk*fdz diff --git a/WDL/IPlug/Example/img/VU-meter_sm.png b/WDL/IPlug/Example/img/VU-meter_sm.png deleted file mode 100644 index 1e81c73b7b10be853a5aa3fb415ef982e85ce666..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 743112 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 z zvMZ8Jr=48P}HAOay(Rcn?~hRu$uwE;5)Y3=5vq z-WEIe$k{m2OgybGWo^Wmmq*d4BHno9oE|7p3eyq^4~nMw#a}LOjR+RvO?1)qfYkl6 z-ZOY6f3bDeVkf-V1X+c~Trg@|8dQDuy%lg`9vhmwAxF{!MM%PgE9gfnZbKXaVUl;0#xh9eTPkSER;Z8r2|?!uv9j z8@O<0=w%K~SOMHVu_Fk2Kx$>wPh zUFG5V7jwYG!!z*Y?J9YPNgaz}fBuRF-t19nVPCDFO>=fQLE0!49h zSzvQ7HRN=lhz6Xxn1&BH!SE#TNTrzMuOJJ1@X5Y~90+q~_j|Q$47+{ocs*`O2;|%O z-Ux_rrx*dhtC?-9Oeie*X^ExXLj!SyBrc}kEJ~xsMe!FmE1_&&;DmJ0cfT(Ap}D|N zN55&1ZRhW%mIi!dVo!#MKj^8~fRs=qES6707n_CD)!tLttKczGZWEspi&#LLx4flLNtrGrH! z{`R-82me(wQhqV=-CJJ+4^`-qpcN~g1PddibgY1EXrT#u^wzjW4W`e~L;Tj-3Oq4v z*+KUohc5?I6kAXhD-&o#<|srmeYeGlA8FJ16qaah4OL6@(RENl5hUNCyG|J?PSh8}~;7{#VIG!l}DYgob>kN|pK zLv5N${D?;^Rw}@V#50C@Tj90ykVD-_Dn2~>^A#k0+W1a(iyhD<|81V@gEZpse9S=V zCyA2vt zKixWV!+nV#GeGfq-%1qX%C~$?KVG@i?CQM34zTw6Mml<6q%rD8KlyE%hGb%2Me}KD zi2Wq*ouGeGCuM~;c{q*Zhc5gqI@9xVXE?pfbbI@pBt14u_JFDJoUbOZ8rk5#gktXQ z8hT!M(#Qb0kw74(NEd3z?Z~gbwCG|il2~LNy9;DZeI9W^`G~J)icK1DRt#eZ?G7j9 z2*gCMr;`GO?$H>1K?$_KJEk~2Ki@7Te*a{=YdSF{GZb7_a1#^`Ig)r=r_*a_gwjfA zWM(Gcd)G;_W=^)<=k#XjJbm*_6MPU5LLx8=`#cl=#gkJXJ^5}|be;4kH8X8GK~oHp z_q{{+DK=9C5J@1M|MQ2`flZqN&iC<#P72U=-FNG1S7^R*sA6b^R|u8mt2%b}A48;2 zv{m~sk?oE_pwq8egtI2;%$V}Z1v}h1Gi;S@NT%m%P>(_^J!T^>9MBy8J zb;dNNtEuLdC}olpi1ZAev<<<&av4ZeJ0*rv#RpUAorgh`@+ zG;1&wM<;WJ21mBA z3=A~tt75*DNyC6^q5+!F^Bk%X@BqI}Rcr+2{ceo5gUQpMAFzxb&CemAh{u+N; zD1n-Rp+c$Su9vRpML_E?U|e@uDcO&H+UI7B0;#`8x#zLR)Lq~!#$yxjgfO=-;{RDy z@?4V-5H|o8KY(_lEpGbN|b=zvb{z`(F6ua zQM-cxn??tX8q0$L@8MvA5(*u;zc+S7FQ5nIaGkruGXhb#VR0=~P1NtnnKkysoaG4% zCLXq58xY#htb66I*)?UEpXCf_Yj@0BH6=_RKt%=$^zawAMXac!6#-8*w zwIBZMuwVm>GDvlejbU$Zw6qHlDzwlRE!>A%d_Zv9?LwM-->Z{*4mL&M50jm}$47e` zbSL*Mcp*TifGI|*t4x!^5-(S3S(GkO&elJ)0~3=X!Id@H%OpFilJbh89*@#LEyYU- z!_;ZO&CT4l@X;$&hq+@z^T*v7Xw#h%=PlTv!WzlWS>2ST`u>nIU+t?y0D=r{(#`%_ z!XyJjv{uHEFung=$i3a^)*!mEiHotzW`M*q3Je{=st^z&_^$W4!|P>fW2JAZQCGzZ zaB6<}xvHBR!o_KCOphorlQ8UKuCOYVI?N<0kyRF@Rkc6|A`?rMQdONYQBEE=Q=rFU zVpjYMl>GLusTq; z+=NkhF<8wxXF{p!nyQ#Mp~Fw!So`(=S@BLM04v@wbqWhfaBvy;ln-(rTkoc%Vkrg~ z5cp+j?v_h95>P=?b@Df~;`k*Z-&+dC&g^+!0-4D7y=bwK!L6D>O^xGlBI7dyh9d^m znq++0E&kb_`@iY@&x`lncKd4AbY*SruT_)Wdd*NDCNVb6HYkamu(Fp&)YUjX;DdU5 zjT3prUqk34>!e+gYqY`BqKUgq=xk%pE1G_vqp#Dm6VoL62XXg_zITFUqBvnRLMFyQ$OWY4;@lO#|BP4y1!gnxrwlaWnW9>$_vF@rIPH zb-0T&b!z=lhu2@bdno#Bc3sWQ0aS77b!~tR@6KO)^8dBrjYQ?hqX|T#Bp)coKo#@P{Y5Hs)f5B-_JK1?e6KlfKv4D;b+!~>FGrJaYaUY>hgqz zrn;`Kps=`{%cK#ypN$=Hu9XALXTfL=Z%HB4L@|nJU7}Q!HhovzJ0mm7i1DnTb*(C6 z)U-z!+D--t1`ne8U6=+SDc^K=D=%W9>C0M|8?mx7Kj+2#8oknyO7eWz37DBmCG^kk z`k`3s#`0rZ%A^-(Gtc)L%aYD+=D^#pDZlL7c%R0ehv#0hUA-n6=m9NSM35CCp#Sp6 ztvM)IwwZZe;RbTiMF2?l!23J+ax?n#&O0cF(*z8Uq+!=^LRaL}0mFQ6Y=YzRe-1p1 z$WMEk-oG=`$<>F|rUOmO4>j3U=@5B6Tl@Fx$^IT3Sor#4J?X@TpiF?-j1)I5$g0q) z0(*w+9MWI;FFpse#rXJFE#xD+eRDVFi@6K}k5XL@mq1L+*M|o>Am%{=&_FFTUha*t zbUz=H*3#GJE0x#pwnj)&2G1b;mY+iv3{6t_xPd*2g^HMqBSSIfPVKUaCry7Iq{b+f zFm0_7(OnGr{*Xsa%M%Me4N3r`hrU9s*o6KtN#5IY}r=;b$%`= z0L^GrMq-4Y3R^GlK<`ZA26y(i?qHZ9gakg%{Wzye3^GRsm%)RB;T=6tD`Jri;vtOs zp9_x^3+w;43-9v!n&p2kJZADs!@Q~dxRL*_3lGuYSDcW9qRw0bl&;pT%4rgVS6vmu zgLfeiSl2+GZMWGiv0ekTo~264NwX#eGIO<`AC_(Mzdjy^jgkS1<3IEBYY(!lO+t{I zvB0q_oDCURS&puxcb|+04J0IVH9Usy91{oWVn!-umJ{0a07pB6gDod2dQ$-ckIlP zCQm;2P(za3aiA5($)@$K{%K4|t=-)#D%QN~8$vyjTsabU>JE0RJmdXq{eFoCosl48 zPNF(IDw!u_uKc>w%#p@vJCd`mu`UOZtlavUIf!39;on)2E+o-y`*G?RwV@W|)ki9SuI zJH|aRNk30Tb#LUrMD~bq7;&4rIIp`A!D`CheG5d42QGQ|K(_^Ac|D~&+z|pcuV2E^U zi}5)fa};h1lcA$t$O$tEpH*vwUZc~?by3EK0J}#q&ncA4AJ!gG4uMU1*4dke2Zy)k zE~0P01V{o_tmfh-_l9!dEr##4HNTji5 z51$szZBy_VNiF+Up08Cr;-E7rbT8Z23A1bBoNU2|LD@*`rWZTe-v5E{sKbXM4E|`* zxrg<+G_-2ku-m54jiU8Wqu~fm){;qQ{p6IbZXO!UdgJPW=%sB6l*mJWnl2#f7M;L> zuA>LZvUn2>-RKq0z^IhX)m5ZyybWFec?o3JqfGfh)f*8dxWC7fJXBR2|8EF9XT&CN zzQr3RD8dUCm=w3e0R9KGyq^bz4s=Av@L#&kD*8@Qfflh|rQxaQf4hCFT`ge1MWK*} z`vM}?7F+AdwZ{wG7GtcUj_|k}$q>xQ;Jv9v>|OoMX=Bi!(>=G#2J9p+GerwM8=L&tZq3rTu>5i5Hrb%v zk~582>xN_5I|=@Swi;y@eM8ClnylPp!FsaM>aG7n;8DlGpmgIx!f`czl~0V9$xyI% z+n#h>fBZ+>>AbTBn*h4mihAT8kh0ijTY3gTsL>_s)czK*Y0xd5r%Az&4k;_g1Cr9f zwk+QG4`HfvhC{Kv3(Y65n6X~l@8|Dn7z7o0Zm9q706fCq0qAf=(>29axDR;atur=@ zio^tJv$b^7kB`uLlRFx9(qrM#AIAt+$5kil*_DhJ7e}V>rEtEX|@45qmKpX&~n^Xw7CT+wf1gc=5!zkW0qsuQMT6 z%v*V+0^^Z}!gJFr0dRSxPd!*L6j#Deucb17?SyM)n^F zFVdQQA;F!CaN{epRTAb?Yc+A&6iU2w8(?mpZd0J$Hf6;DBwK#T00c~kLP_sw@ao~~ zGxBPp2ZW&+=T~=+t*9nN#BYhV-cI_V?4o&YJmv=go;Z=ycCWbZb#o$!L#qfTw~55| z(G+D%@oXNIx%NRpHLhn{U{O7qTscdgJ!-VTkM?R@wu`Xih_vI7i~&sG`k%ZRXGZ`HFZ(Ste+&1gYM7r-vk=>o@=X) z%)vy&2l>y_36sQoEzpC`B+_C>QNv|wUcfr*&av9i`ygkd`TiXH$Zf#)DtUh@OE@ru zOU#mOYAq(-6g3)a^vuP2`{!C6XX~0m)r!4h<3IX&XM)06+|qKSd%iyh0}!_VzvFjk zk2>uM%t#G9sE%>{F;PpNzSmIrAx8{jIliet%>vNBzhJk3-KxPmZ^Ir0l4gp+07*-r z)k;_QQr?!wMi*-bI;o?fg_$*1RqK8G|BByTecaqzFehX!r!9HBw+(h4WNWvmEsT_J z&w$#N#vyh1ZKMn0`N_ZdF_FYp!Wu(BK|w-2jr%b%G5v;pF@`}w#D^JRof5*@MJ=r1 zuhfWK8+WK3CacggJJYR7N=r&Z#eH!}*$Hiv6kF(_X$>>8kg$+gef;00D#Tq;wqD81 z18NcE5dx^ivsNZOMsR4A7&bL^^23)D_8QO%IFV$(#WlBQTR%0_M=>UQZG=nX}V%DQV)}0o(>9v*47XL ziBA?$Z>SaSJYDnt3_(PhutkwgAR#qdgu`kpyfZp%?HMlYPOlu+!MY>=)7BiJ~wk949-NIw(>Ib=6$k z^h)dJpT>oqsTumuk&)Qz&s*0sNA}VQIB*goEaA(K)<0+X$p zH&1^5n}voZFqqT7LxcC#p+eoThETG`9=~xf>Tspig;e3vgusXr(r*B-Zzi8wH;}XE zES88X28t|%PIk%-vzD%V3Oy9?e;0`4U2`J1juK}I-2KxLFgzU~r`XnPA^)`T;vS94 z2^Y4E3aL89OsZPFh^ebz(5LHW6UD^7NBiiEfr`1>EkuiL=*_ z!tE-iH?bH(7@wIpy8VMKswQfiyAZgXL6lp;HE`Z=wMpkhb)<{Vw33$qnTOgMlBA zu|0XX$wGok0#1IEuXXb+Ag|3{GR2CP2)9?&HtPISicX+obZbEl>Ovwo=G|i)$ zjme&?x)s8SuY27cEhM@&ifqo5?3>b;HQJc9D+sF=@Eg(qtgT4!P=S@4_t1kD1=L0m zUkj2>paVgQYuHIA+li~d7(7%~SPvwFhF=nth)!B-;wO{NK?z6p`mFb^Eh4;GBRsWq zq2w+#$}fjucNNv6u>khRIg^&B1T(Uu8sVB5{9IZi?60qQd8?KWn+rR|Q0KY^wkw;r z1O3agC|`4+Ktjs-WjCrKXKTb%XR?wEDP&c?kZ9IYO`{VEDH)&SP{vl1A!oreY*t=T zb}R%pjN39H6;Ij7dTH}N&>!E&M6PN3+R!NC^dn3g*?z4^e#e!{+}P{fL(eG+>*gO( zqeo~u5;7`|U7Wp4!W))61h0nk!;{y<9Dm!ZC4l<-hEBCb4^V%7`^h;qp&g$&#HOY1(k4cG3x6B2vlarTp@B@2h75{e)}!BL zrRl8gtTBQwo$)hckKf~^$mjt>vRBMtOz;Z;$=hic1K!n!=yAz@$=GuSVhvqxR*$L+>ek!IL2A!>R!uSQe}-{z@cTL9GKcaSorOE;<`gg6XpgVEVyjX&FU5{0Nwu&@-0ADt z+@(@Ulr6whp4CXldd74DK|4mrS{Edw6DZ<{9)Z#_Mef0~o*XnsMV1)G160sp$nG&x zQ5AQkmddStOQGtL0VRY2Fjt39)uzw541yp)qB#ULlN!)K`LD~Y4}IJ5Rjxd@wY7b? z(T(NA%H~`4t=8c6dHLhzRAV5R?m?jI{<%nxLs>jIm)apF_Xy8SF+%=YN{fJTw}B3! z(Y*Wmwiosdl5X_g1v7h;Mjvh{*n~v_tm47(A@QAYmQOic@s94*wMda-X_b|Lx)PvHI6c%kor?Z zIawN0+_-tXbP2Er7$--Whu@k}-(Q-rN#D%4>CjzEf7|NIrYrBp%kS2z59m!&+-!|n zgCID1ol}G3o`FxLcy<{`HeMwr?Wq!X-VN+c0+0QPI`8NFov+;+a}!~f`#3 zE-nyHR96c=HUJ*I3n1dqzQYAh{@;M#Od06Q+r0&{pZbo&-Pj6Duev z80s4Exc?g7%}QY!sIlym+Bj6lCwHMlfpB1p{Z+B(*K)nNwRT}|_xo+9w>NN+esqjF zLN`+uXcmiquy3!fYIr9>ylYXi1lX{g?lEo%v1tggC^G|w4k^ZRa%3@09x_ae?RCVNLWmy!ZHzY5w==xLv3MliU^ zRkP~#_087M=U%aVKCtN}&_Fyn7?zy0rxxr_z225hJcXB@ysIMH9 zqWpEn3G^e5wm@k3hk9`)kf(D7R|y72Bq1plHSv>?TCZxA^w$c`jo14wV067}D=%MW zY~?)sX1lk?^*REEksOju#XZ4CzQyOP?(+S3KigPd(t3$@sAi=d1>t@nOq0V47C{1B zY}A@EQY9*JnEiY0MJN!crqa=9@WJZF_d)hM1GtIQm#pn!J6wn0w$k~SKW#72fL+Ck zUH1m15nd zYRxKxm)$0Zjm|6BJFhd0usbmoap0^~tSBmN+4`5PxS6Z=P;DREZ%{~FA&w}FvEuP$ zS6yn>-_Oj0h?sfjo{hFQ4PR!D*osSvow$Ie`Ew!;4vy(kPH7FbUgzBl2Ri}1G7V$~ zkJc>z@9(QcD|<6$AIoi|04y!L93^Gb?zwV@Lk_L@{jFj$+5c)9whI{aQ~amw<`qZF zm1e#{CCPk2pxXcAbqoTag}C9uJQ|tY&|}+tnS{QC#Yn6z)9IW+L0E#&1jXuua0;?t zNMv63uP&Z{6MjICmAo~>{tb2Ip4M2S%KU8_!Rz}wx4w!Nn9VpPhq4&9D;}d9u-R-=E~)*!J+qZ!suU>^8Djo0|UH z$oe}fIy&ZpJ0a;^W7t`ckz~~M{($~h*HfkYaFxsJhzR6%X|33N*!NWbD604eg zksKw0bV3cV*{Uem5dioPOCv&jI;}FGPLu@<-cXf2U3#Q7O?A{wwl5aN_4 zueW(ktt9OnDogyHh9~`Qj^`EMp8z8&aNxq9#9`%98<3PFp2^)2F7hsi=-&FkZ+?-rDD;NLZ+#!jikHBxh$ZsGTAH=t{Xt`*;jW+c)@zkQ*kRpLk;c$z1617HPsTwBMy| zS4^GdWWG-2b%(cyF^+_YdXlPQ_UVK>PgWbSLK94r3jRk?71ypMM?Kcy=ODikAcZ^ku#kL6! zhjoC;DOkAcqf{k(RUIQbzm4f|rwMYGvi*2-*K?XX9=A`M`hatWgmM zCzE~k|6~EaMAIaZX(VGGy*}0H(O^j_W86n=K3@poBNH*dKDPfDTzJhXpT)7PB0!sp zWM-EHOZcSx9d8Za&b;nzKm;p?godi0ga6ex*9UoQ_+p>npST@N*h?i89;Y`pcXbK& zpRUrSP(5IZci)_bS>l=gkI#=%;CWBc|Kzwq@uPIsnjSwy20hU{liL;kU?NLAFOFO~ zIRKSb(B;~E+hk0bua-P}7|K2KCF1_~cJ3ftD!oV+J)Z|wwk#Z6++fEiagEtV`*Mv6 zE}n7|Kfj;r{vW<-73w~B^C@xW+DRa5bB_yWo!MyHq-!;OIA%8qh{3Nq(d-g)D5L=2 zw>9biN(&HYPrVWaeg=z}%5;0qHtwG-C$ohaa@?=V6Z-PNoZ|f$WLx@UIDBH?&{Fh# z;j<1NZ_HOcwtk0)Mc}Fg!Dot4;NyjSLhYv%CKv<`+y1K>OiIFRf7;Igh=$z^PRBT7 zoCHvx*xO+#Imp=~pJmM=#4~0!Q8Eg(A=eg;a+C$gmF8pvFM#*^ED`aLVidu<@7spwEg%6cF=y9DVVE zQ|wfW%S}Bky-eWPhcgSxr@*jb!?R*L=5pSK1~5O~|73o=9uA_5(PmAH{A*SmUUjnw zIk*x%-?Pm~Ef8a%KKU5oIjpvGyw&A=Ja(-wdEVxXzz;u(U{zGmdY-*<14(&?SSgTk zdV={}&A6}qS605a?K|@nBUZ%)tZ=}Sk;a}m2SErX} zDRue%-rTNSk`!Nq1@~z&wT`-(h0o>e$0MLHsea|mQm|!CVzKhFK*MIt91IWs9D7Vn z=i5({0Ex})+6RZj`GRV?T1YB_;DuB$MQwED83=6x|8rXyG3#8m?R$uD-x*B*NOLh9 zL8Ef@;`GIX(^b#sxtJKIhjXBymjZ&0fQTp#hzFMx@AD{nD_#Qzzd!Y{3+L+RYh5?I z;~G1K(I*Wa#dcI>qqS}8bC>mdqsp~b6oe#3s!AXT` zYOvAn1c#I`?K7m)NrPxvFvNeBmn&g>j`;04lKFG=%WX@Vo*UbDjDJ5z{$M;tG?&q9 z3Nye}uU^63zW4(EKIE~#d!rZI?{6=U+mVd%XezDqJkQbNl?^%Ven(j!C;+lMnEA=H z@2~kfBU{GTv${$Dr;6An&MrpiU9*wgU_{(q-sBbz*CyN5?jM3b`2ld5< z3KjceB9nkLqC|&*WXHM?@KrJkS=W2Y^yKkJuzmT+EncB0z|xhEn@dnerbG{OSC1p| z_oB3#SwFVtoo9AhLG3aGNg=hWOW&4Gqoxz$@=+S@ngcd6vA`xe71q(+BBQalH$E&Z z`%FXM%=2>~VC(hXnQd7{_a@)1UY{KS(hK~IUT+M3SJNB%ug4V?U5?8Z!%|kIzhr#& zZ>53aho)aBGEhN(d>CKh*3fR^Xo=%JfWQVIL`xs1)I_dubJ7xTn-8(qopK`_HbV;! zLQ+@%1H`6*(-U)T%H;}scOL!!e5-xiU#M#lSDcq>>{;j$?z{+XZBM4Y65e@1@y2>E z;~?gi!ke?;GNi~*V<7yJp~$o4`5t6J^lvb>6%>KC+8lxh6pTVsK~yAo`*6)UG+Dcv zW>Hbm-u|;ac%l+~!cE&3DkCHWsBM8q|Mxn>r*+3yN7h+{GcAR^H8B@r*CFNfe^?Tv)`HnFUp9d&7DK4f|E>nve2adLX9S-j-G?9G9UmE?r z9CEfD*1;Ov0o4KYxT2u#A6S&B(OsXfqpO(lH@tc72(~!y{F|iRJF2LQJhy!!O{`_rNL{^Di#m7O&cxIg9r;{PEHCw-zh9gNGjfWJovV*RD$i4PSE9~-#S-oM zjdi(kyb>H474);H2z}0qW7^>^XlJwMdB3;o!|Lq3az62Zr?*NMiJZja3JED2bS~I@ zqbn)da8pYr#*wmxE*qJen!5RiV-nJnG3;-?JypysK6m4PL@Y3=G%(zNKsC0ozyrq0 zJUb2q@nmKud9Pcm=$AKvqjapBVuzy)Bb{Q8$yp~~ry!bmA)MQn-D8??RB|wn{>Z^i zYDP{VNzd`Iv|0r_P;$CGt0-tHuWD`nJshy9#mj+S;b`f;IhCdu^CGc^{t&YO2B)+z zD?ekTHgCnp?m)>uzlG0-6SMs5TUzdkH8m&wkz#UYS+>7mpYu0&wANf5!j3f-TjOCP zd{0l$HWOE-Rv9!Bn~aoV1Eo)`P&G;pde@? zqQrWHDwahkv+h}px+LjIvt(*OVrn9@CGQrbg?XRaUi`(CfvXo3mV!#ZB2uv?krx+w zIkJ*oJ_8U_Ks_|SSA9q*GV#`V$IH^vYEL*iLTXM+)lb{7E1sPK=MskxooedzApr1~|If?mQmoDUVW90y!B#w( zqEO`TkSpf&;9xO6ZPmMj0ahSfH!ziCG z=hUV#=?n=2*8VLTye2^ZBV50~&QL-SkfrH-cCJ6DF2j?T`$al>eHkZsaML2yj3?8a zmi$FH$c%*>?e4|=9-%r*k}Pc#xPx2WPdETKc=z!zCWfrIhi48howUeooQETI3{pE#6uBwx-mg zM>7*1%x#s9$6saLjC)=kO+QNK?#=cvJ@}XrZM}Z{z|7AsO-nl}MVSbxWNvAR9r*sk zO+S(zcq33Emog=c4cD@ze?}vrWvN}ZV>3ajm63+G5HRfqKJ(P{^q?wRXE9jF@nl*n zEov+y9GE>9ZaO-;&55kG=Idp3Ik{g)b7krrh=HK+ZaUbRqL`g#uYA-~NLE$K#DTe6 z5Ez`}RI(=C;p}!a$|&gV2nHKdWsSh-DG9UJ%-c*&oZlB|RD6f*Q|V!{vH+*Mw&;24 zN!Fgk6Quu$p_`qo!{uB5H_#F-?{#vD%j12IsFF=8B*c>TqnxIc^Elg+v4xn3%8n%o z@dXhM_6W6GU0fMQ0Jxd&3aw_nA0J3Z6TDrO_>vm!fs$>YAc>7l-gN^D6@aqVeRj}t zc-+x!ZSfx;cNDE0FTQLx`k^Z61r=C!%d$XdCn(Wi#t#?rNhKz&tQvew?Ch(Mjz+yl9 zmWqf;#*>b+&?Lcsj!uD-CJ)x~M=IjkQCkW#HW7h}DtM&qyZAvHS#Y?^+x18Vc<_XlYTf5)u$>FP!l*!BR4``=Jh- zpx)*9gav0bP0?XZ)9mK|qy~Pe1y~BsghmS5NaX&k-&D`PaHuE!$<1e6nr@5?@Fmd6J)6NWtceB;K|D zKPnch0@JPr@Ug#p*}zY+{nqC~{%&M)e@_^u1VAPOe$6tZB%~lj!h1FbW%$_pre49Q zFU5(pgU3zY{Zk5f>!ix#$fSj+_NFT}SG&Ukz#AQSF^zV+Y2PIMDYpn*mLbjhrBdPbJ9 z{OqT0?kHn^0WPjhfXPdBZK3l&(RC!tnM_-ROK}uvt zPU=QAORN?EV6=EFy+?DgbFU#L95njNV84R5z*0De!z0s6m>)m z_?X-cFq7+XCIC9$Y3DBPfZn8-e4KA{uVNe-TOy>2RTU=xz5O1%)>P(j^ePBJ_;&^0 zQGh@az~j0+>5-8BU@mMswMaKxK`K&_R#9g+_`vLgMY!S8OYQAR;f&+qx!$YbzAVZ+ z?&$I(fJE)P@O0ejM_~(v7KabbyADJ7nP)PdFI2#NdDeaMc~M-{#~Dywg26m^zAckv zVQAsdK=+w-x>KJ1rvwz`C-nGEuQXXnqevoog4yWMSi{od!I#au1Q$&L2U%e7?m zpA?0-innEJat6sr{kIBG)txB4KetOYO}wO=Wbryqi#O|X(JZ20cPN>mt`*K!OZG=( zHUtXlm`z#v;1j?F$ zrnYXIf8OE+{SOGyMdhkrQtI=@+DY*`i6H5AFPG0ZuC9RY3;@GDsd&~WpmVb(Zvr_D zN(P=O%aMs(vHoJJLb$n!qX?&{zWE0I-K7lmrwJLrX-QeCfItB#AoU7Z%j0MrGzhV_wFIC7 z>DLYy4QhNmQ?nNJpHWJ5Scd2?GExcVI@;R#M`hBj&O4OZrx&nfe|MFaPU*+46b~$} z6004Q3YHPS+~;473`R7+rNy`7) zF}^^vrQbchy>$@4p-4)?+H`GXn1RiN`&z5wjSrod)Xk`!GG|h%PPkm}5nWmc8k>l{ z-&s-2EN0v>7&}8Cp{oo(;DLRmymC!9REY~8P9?5gUXP2Nh4B^7%S}{b0-_!^c@ssF zMK<}=7s zcD#8tsrdmiQudfuBLy&h&91kr8#;xP*7%krBZ5Fqj;xGAM;mK3D^aCAuU48qf_nP- zWtbjy`t_B-Vv+N4l+kf&^_AfIDf5Fs*p@zE)d)q3Ntq_gM3hsghy2!s08jz(dDX|f zy+K(FlIky7o8$+`6rtr#LgsE%ge;XjKK986#_sBkD771#z4(kkT;HO;fapYPOKH)RjC=Cc=RUr z37;}XpOds-WjF+|g96lHH63mhxC6J|l)4O7K)_AUXVgbld`OPr{=rs{%pA-TRcYV? zTBVNw3@XHIt{}ux^uzGvb;pb+4h9KKZyrSCN$3#jr7PQQG)siU;B3G(pq38`yCTOi zS}d(4t0NmdHTkQ}BG0kI)bHO=xPU%7`|z<3|mm=hKT$*)-x!~I5pLG z%&M=M=u+TSRXTyBC5;bCEN160P}nem5bS1=JTywgZ^82M=~Ypb#qTP?AhU)oWC39k z8UE&*y87jP(|TX*`#qG;^RVUPyx|+>qe_uzJSMQ61NL|@TE=>Q6SxN|V@6ptG*gu6 zcA-|WP~)xBR~;ITCbGOCmWcIxkB{MlNRW4+i><7fp;#s$LG5*YYy{)`P1M8aJV;xG`pdw{vv2!O zYOPdh=;kDa;c_R75V)X!$K~7ggu6&eJ&fxFa+?4pGlw_Wg zqO{1aqsQ~JY#1J>;*JTlql~tr{EEFK7Z0iEKN3zNLQLFBS1o~cWu@GrcK;Q%ni_pj z#9bI9W|q~iJ4c*$83|z|+4TD-9Te!rAw1{@owRaU0~`#jsfX3ANkCL$fat0RF9F^F zK+~huHv^m6yls!SBkI|i>A5atTzX03HK~JXvlT#%=i$T4kOeDnlydJe11H6ksIYaL zrVa#wh1A(`LXh+q1J=fsA9leKZz7y6sjdOUPXw@yy-ID|w;;LqB`vd5R<{7SbzbN% z_l)7~*|7xrR@gE}Vt>iS;=lU-M$Mmkd2Atk_z-D2mGN6d zb=bY#at_YE789mz+Y4$Q`s67T8}Ij>&!_j}Z;RJR7$&6BDnL&yI>buVqZFe5uBJdB zH=KvKsI)v@TJUD6?6q!rFL8h#_lz4)uw%y^55OTfU91Nh?JGi?4()yug{PL`$|X*- z*ju`g{nWc5TLbBb+DaWUhT~O7kzH-MQ}rRzuCViTzzF(6iP9j5`_%fot32Nr{@@vEvy`Q8JxCOyTuI0X1Wn z9p1KEixqmuAfQ{0p>{o~1*JzBqsSgdS{C5>P(^Ns18MGGp#JnulhFKg3*Rp#XP{v@ zLO+}PoOgD)#voEak~6slxXbd!$L&{Je31n#TiS9>zxJZ;KogVh)O~36>9;V%1ey>9 zJJ7mm$A?kdow11jizcTxhJHTmg`bIcQEV2p8|^VNg7M@;d9J171q#sR#g%nM;2P!r zV?=Zt|Q+Egm|MCDcy#2nNwvgz{uD+`R-^ z@eBSl`odw$*3vtbg+eKNH4q(!%I_slBwRC8qQDFg^q05^u|H{=^!qsKqj`s*eni`)QY3>I#Vuixpe?ia5g4t8Dy( zC%nj=Tqt*w5}Z1HckQlvUQDKjLvGw%Q07wnk;CUh4uWNKwOoIPi*a zbiYgCK20a=sFVU1^A8~>ITe0qYWSieNdRNI2*bW~bAvRtD+(buq7Rm2Ug3GoIlERG z7c^H;`}%tr+j4TaM8R;fIqH`H(CEBLo{vy~)`Xc$pd3dR<%Ru2SR62La+S0HMc}iL zVotF5zUqY`qKBgGjPx&EH1N_-TBJ{wc=rHE2LtVJT@UL`R<Ey0V5a%-2F(7T(c<>~Wwf!d!T7Xu(xe7+Go4zQSHA$KjNuo4qnjCP0x{w*iRh>9l za)J^HbLU_OouyD}M1PD^Q5%kobdLK#deb!q|ht^hwVYhHjJs z@*E8CRsTu}TR_qCy?EvGdK$N8WqvKy)?k|Y{DE1F#A<%GHPYN;>Rt9 zrreWP&vpbVdNE{&$p5HEAj|dL_R)`S>r}>c8~qJ{{#M(XGrmXs_*wBkRo*g?yaqZk z_zty-lK?uczNu|;b{1X9jQgKZUJbd(``-#fMAKZ>!(2bL!JR?x_Kr84m6bL(Po*7j zn`p;6M6o$+fZEv3&k^NRO8#hFON=KeQ8#J~U&0MAa35Oh05(0qq-|O za^eA{!vvIx)zfgri}jc5Eu$&_%Eb#~Q`1NdO>FK1g%2?n2WUhK0Y*4DGhHM=*#h8^ zL>H&q-EZt(?RA3yt&?cVUJr~|ehJKtdPOot@6 zs!vC=9(Z$ zF3KemJ6-^xuDJhk<>km(RLLnY_l4O1pDe(H_SF+23?XfBZf$lP#CfeT0A*j!AL~$lmrhytIRyD@=e5>4oniz%_Z~r3KSIh54z=y* zaa@~XOTKs!wOGes#)PD^6WI58VH#vWW)Orf)zYzyLq7YWOEzF}aCkWH3=ocu$(fjc zN2O92BTtj@D#Ag2-1#1$a~9Uv=&@WYuTa{WrC?b-G0w0q1xiq`LacsHkSlIcNqhIP zeVNX3C}9N-RQm>=IcyG203kMm;&1zcd7J6|eU6P*-;{*~4rfm%VBzxl##T69EDFac z^)7x8l(cio{O;gyaP##o>L~TgZ_;40>!Z&iDMDjEX?NapWBm;Ka~)MG|NVXQw$)3c zHnw)o#=^!1f_%X4-WcL+y_M+>GjMN#qyvhrB_pXcKCWM%I2#L6$R&5W_xe?Jfy3MP z_Gvz^wv{sqBxGAH!xa%=S36hmZ*OR<)5|@-f$oY}gO25Bt!aD|3Y&#WSbja?tzNI# z!8d`UtJpX;5Uzsa#+eGWEX^dMGzBeVd z$!_TMJDO?GO0@BEa>?|xWZPPvSkI51qXwly1;|DoA!F6*|)ZyAy#w1EX zuK!}A1i?eoCzv9etILbkfQgt=S*&Z0a=y z^m*UGFoaF4humwk&0d83vrEhtvWzJO#wl1Tr!9q}NY8IX$a)1N@lr}%)i(_loTZDb z(>6`i@l$cbyXTAyzu#ZvC^v}w?oexo^s1(^)3hIz$>LWjKhdp_NmGNoXUjxykTD!< z1`c+tmQZ#!!wQHAh!MW?l)Sq7Ibk^5j%~!K{VoXQ`>Zs0-i$9SR<_~OnSFE=JUQAw{GmHrf1kS%YK${v?s^I} zPFBj^b;M>N!k&;a%hVYZv)2>ZHOb7^w{sI^=_?Pgd!jjM+?mj;F{2p836v zrUff!b-)p`d$jvnvmihF2X+P3$7!X7zU}uu4z?9jHz-VX#g=k^_2fIOxN>WtFtP|-;jH$8 zT9Q~{7SG5G*E6$&(L1-#>y6FRC2ObudR=hHS9A~8omE`YZQM`T`^V9ve+XfMpyV~< z$9Jnc!0(lUf;CRH9Oqx3FO?9R)Np|k(f()e6#u;s>fKR6ihwn{h4|5Z>WuO4V)4x5 zP<}t#-oImEOn#KqJoGaf)A`8+iTBnQ#}`Fh`6fnc!mxHX$}8aD6{#LoChgVvUoYTa zti_r4<0dCYoJEm}1%3puaW>U=Fm+v*08!>OHrUk@51?)bIO^O|9*TAsoNVSbwAjkQ zL_}tl6ja1DUv=f9?>z`prq=m=`=l6V)<~COE*|G_nB|jq-CI`nl!Fp~Q;&@)9JGbp zEcPxfvYk}K>d&j3_J$z8h<7)D3K;Y>DFK7tui`KRBkUOtm%bR4xrEbT^)~2hc&8CR-;it z_-m!|`N^+~F`|eC=Wp(Y$LQu*FSaaW%a9`Pi*pp@fTlxew8-S1Wb6w9k?X);%)k_> zWHT^9+|H6zF(N2&I4iQ+_od7G;`+faLBU);zhoo6r3|7 z95#EN_Rf%Sqeu0nS|e5`UuzYUi@LY!acAC=AD{I;TY6c;eIS~6ef#K!*yyPvgjkaPxU_5og4K>Y z!OpvVZ%udpEh8!TbL)?gu%jIctti9+6aYU;uEOQas0^7oXG@NavH7N*Y~|tt-?-z{ zHcz&{G~oXf?D>81j%59>!iUZMYPg00Q+Ifu6sA{^+wH)gQ!HE42P)I_<5AY5IlWk+nRLnrtcRb zi^r`3-7;bUX!J~>lI?2%jUFYM1&8jV=iTnp$I&<^gFlmU+OcWS^!qY4#oM{#M~aCa zA1*tb@~iMCAdzTeQ|?@{=1?}S@n%;y&$i^O#Gsj5jt3}P>w1MV?(v6svzwqE$=a-c zx83X!03&IfS*<*5qkWA9H4ugw*Q|8Q5FJUK=DOH%E>Ok zTssbwug23oY<4^>X1@R7^ET7=af6@I`KC^j)M(gV#0|ELk|O-tz+#=sLXLAtiINnN zq)^1?zDSU|(qX{4a^haRlGSLVjipk?rl#%@?4Tca&55e#OSlu$42r-LhLfuOWCA(s zvgAxR!xoJ8B`|S#><#^f_T$9%VB!6ibdf<m_RAn5-^(^+LQsN~*DFpqG- z(+{D5lo%9=l4Q{h8+gxrM_Ce!&6A(ssyJ|NNu_~Mn(I*muE6jo$+YHdaw5MYAF>h9 z*~DFZ1v51WMf#83{WV31u@w{InsgD%LowyS$1N~}_?X}G=z17cqv3}eU_9LW>Kw(K zeN8EWe0#Wt$@INQCC#sl%~^L5J?C4k%hGwhh24r=+JaE6T;l(d=@lNfVBi}LIK|#j zfIof3C1E)o1{ij@W%hu6CV2$tkSf|tIlSLT&&FkJcLjBp4DVOKC;D1wPH=5UR=hFgf99w zBMWSKycE(KLsfe&_F454Wu{fGvyUVAF(fY)u^!4t=p+z>`*;}Yy zDPLyJwp(m$#`e43y`tHb1dub6BrbeLdu!mu2~IC7-0J`@D+1DS4W9|dEL;Em&fV*{ z?&A8t<+ay4owLifN)6wBFhPH#{ZcZNMc;^a6<-8;JB~M*>fp?eSe)SP)9JkPRzZpV zm?TuuWD2WRc0pxT*u*6!8M>!CR6fQy_n*2RL6SYPfrO0)mh&Htrv8 zZENjwcI*spJe9$IU79s^s+M4AzHDUT`NMH9*fu4x1U8Q={d;zG`cFo$t4ED|8bAZ_=4DDo~;?9f|$Q_!< z)|$~Kuw1q}>dUh>f~40|g08g|qoaMQ+^FK^98c0~az-)#9jPr`r5>c_b88IMhG_b7 z5NPH>n`o_Q;$T9LxEpYElR^ZG5@S^mprD?31(cMa@k8+c0HyCAtHX*&O$@n9 zM6lIl{nSk4ZC7g9eDZ)H+&Pmlpxh4rG{A}n*4~mkTsnw|$%ytx1(z5Sg5d}dj{?I8 zBEAZSu$7t$6%n-NYM#V&P6$3dHDSftBeQ0+IHRoxAU@hS-`-;IaA=&yS*PdE+YB`n zlS{Sb+PmGDc8Os7@aFJRy@iXgm0cxz#H<$0V8Pb;W;`5nX zS3eTv}`q3(%Nxu z*0q>HkQ$g^zw&L+8RG|Nu#pW0fy@{I%@>WyT-rf4VO0ZTPnssnK$b$a?Z^%6Z({O% z75=nWIXs-!N=LiE>EwEYpq5+^vgvp_=2;vVsaI>i0$^Q<>6H@Y(_B0?o$r@ty}fTq zHg}h|)5>S{=4sZU|HqxDL`5rO@Iz>3n!heg_zwl?UHA|vKc?6kwqNCGbU6Hok&;H$ zV`Oi*8ZCTxtFOUh^L`i#mm2c|K47K#7Z!g zB6y=>9%)11H<8}&#n^qqL5=@$=f&|!5Q_g_q`g&CS5e!(3kcHE-JR0i-QC?GNJ@9N zbc1vWNDD}JBPr4?CEX4G>HB`)KH7U9>^+7@I0g(@>$ldN&%Ceua(01MoHuYM9I+2- z)sS!){-~ce)V&dhit_O0);WC&Chm=}bsdMI&i&z}+MU3dE-B*5tYoTF9gR=sMI!}3!! z3ohv!90-S4^onq$OH${6=13{Foza62S-V@l;-hvtX*=*g^lKFm(=3aY4-4k(z`Ubi z`508x{3zCcGmGJF&GW7SRn2(zd!H+xPooO0e|^30-@fLxA5UHdDh?gCWvGj26yOTj zTK5BQUekL!`B((7LLWGswsX8tC`F|71X*HXR(* zhMRh}tCA0%ONg@sJJHWoxzufUe`j3KVsVVnYKR3q*|ikLsuGAupo9d$FPmah@=6qz z(f{3DS=lmX9%p`W`t<2x>0+k5NP+saJ(M+0kV5J~s%8l{kv#~)smQC?pyOsN6&B^x z-_hLsn1qCwxZOe5N=kKQ%YeL~NN2c6WthTvm?CeCJX7Jv2Z#8k$o(BYJf_4zeZr&b z$9?x!P-Dg;@T~webS?hl`+A!eDcp;LO7WIcFZxl+O08Zmjt&sDm2w5Nku8+Ev`#p; z3d8?t^8o)Lak+_pbmXvCZE%18INu4pwxCzZ@fNltnh~+UhMp}GGkSnrt^{f{6EDZqY(xdCiec<;hn&qt z&6@A!^6SY{%lv6Yg;m%7T7KEL)b#B$hGjg$`kvs-y3TWvF6YaKWnhtd$pMVx`u+`H zL%l*$;uL@@RcUuY6K$AWNvH-NjAYsycZ;qn4r2b^X~wl3wW#yj4$rd@Cx+Gz2b{Sq z`R4C!4G~riFw3U5i@ETTzO ze4$CP*}=F5T!InD)lR={l)u+Ybf||>#nIp>F-i`Pyl^#^s*v*2GwZf@_UDOMZ5kIwpnSkW4(t}60SVpm(;y;F&v z;1BQ_c-gskNe5o4LFY*&(T9;zow^{c%i%J?B>p=5UWam zJs`_d!UF@}a_Idz8r=C*?>=$X!Ij>5{B9N)`}B_tFFvMs~J$!^Xk4i$1NlZ!12 zGBV?csu9M#v5Z$%R<-zZ=>=wSMH-CV_4XjufAt`!#>pw(U7oXgyyMX9k}-+XoD`LU zSG6zg=25s2H-*~mM7L%4{ku_J&t`F-~@d>Z{bo&^CVdkDG5nJ$Qj3Y+}Ns{X~2h&pSP-`o84c4JF)K zLsJvfn~9}ae5f0g20sLb5#OrQL4tl*#nh;}ZGPr;)#-i*F=V<73jys=_v* zEPge#-%a2yp=IkImV*<#hV^#u>*RpWt}Y+lBpKxrplSNH@n;lWDNlFc*B@xmIe&Bv zE&HQQ^bToUh|^t!@AL%v^^vE%U0EB4s>VY#fH;I*UJP1end#bNxa5#HQ^3e{TD+Zw zy~QgAzK_M};mXFK-4jv_&d$NUaMmWqf=!d<=S${uh#*MSP(VGdO z&-yIg3{h4Lu2f}v!umL#7C|MS7Mm5i?bpuQY1rF>ud3VC3KEU35syD8WGsi&1rKi@ zb&QM#A5Q~t2E@>~9akk9-6J*FQe6oTpVm%JKBLYY%URkQr(xkM?G~CuZX-cXUE)y? zH?b|og#h)3hS1Y}e8B0_KR#>DA$JB@Q-fX-c2W6WShOEK-j^hJZ%X>(TV%QkoXivfnJx-nu)~E1x}DE=ENzJWr0u49~tmf zl8t&hKDQ^mET2Ow=*s}Popb2Q=K&fr{Mix_GKBn`lRfVPexXh_vWFu>1~xbSo+a^n z>N#C)cYDqQy`EtbV&VlEMaeYj&Nt(98uXT*mUDV?PTP4qgcSU%tdBOVl`22VoaQm+-?`FfP zi)H_oL~|7MWfY=qU2T{np`pc%cX^F@AxsF zuyq0cA)z?lBq`2FDQKxeF}hqa5eednlGJHwxLJ~I90 z{taR)%L$aSbDZ|h0RaKgi!HiL$|pW@Ba?9ebV)g+=~Z-c8}nA* zpvb~Vv>l9Cl4XQ1xNmCT$5hPG$Hm!#;C$I>=c|zI9DV20U-{wsZ*ocB>)UR5styJl z<-970KOhgvhz`Oon8%`VO2AQ?_}*QTyp94v!i(_Q8iUjfqddyv#Pc(W5IMz+wN}K+kLTdn7)V?B%nZxXP7b3<*y<_AkgHz6`HVfvb&wC%uOg@Q!&`1Fgl2pxe~^?~DqsWTe4kqM7WL9NYK@BK zw)tSB{uDcOvc3M+&2jc#z{6$N9S)!|9m|2BkAdoo;g>S`bY`_WowMoXPI&}(9hvz- zRwS{DPqk-0Xv$a-*0#cAMnPie3BFe?${*+FAqJGd}moiikic^sV|d)A+xP zygRkvjUp7Yi8UGIS7z{5x9*{GH)z3e*EEaO01==HO%o- zp<(gM3Ce@9f`WoQZS*K}g{kU_BJv(u&!oLW6&{KI)g_6Luj?sEiyh7^9tJp1{PAgr zO-h=9a_o~6@6ahU3i}RG&E0}XyNZh*OuQ30$=bnqrK_0NRfZ@z9lw&?f+{*HQJZ$* zdQpN4ku#dJXHK71Wt35KOi76)unqY>ohyRsz<-WDK>-a+%{F!+E?p}0r@|s3K=2s> zg0KCyLHPBhN}uHQQmKqHU5S8$mo=I}n`wJIQr6DgE*W*NhcJm2 z#!M}bnU9z`3nPCxt_+uQ_>re@_1d3$T=Rnr6|dD0w5-ulD92y7s|Q1a4sRGx6+kTL z4Y%9`6S&yd_a=$*{NV1+bx(5t-F;}G`VS|D%6NwOJb@?EhB=5q}{Q`4Jot_^_2pxO-*67MHP~0~ZODeFBQn+4a}|qI(2?GoV2NY8hl6 z&M3cjL|mr4j%z3@5}w9HDtqDp}%=|+}(*jW>#2$oF3(EftFjG+V|vq}MA)WhNSp#qd&vZpAOfvt0r1zr*=fY%n5yyIHf8xpW!st@b8 z7cBI-;(*<)x>|JJ4NN@%+Goy!E263~YS|#5##EresK%EQUiy(TjICtNk6f&vDsn?A z0pcwwh~Zdr_x@pBa5J!N*8g5tH&JAc)%xikz3X;1FWC|~Wodfz_VuDe`0=sp<)iT3 zd@@GEF?4fv7u!YMKJ3O^W7%%Q9F6b?j>B}SOxpCHQ&;00gM(6JBjC6&wlpfkY_;i* zR0x?%Gw zDMjJTMlh72Nzw8Hk!p@+P66v92=fo#)7k&d|CJjbQ0G_od&b=?uEpv$KnQ5|T}_lJ zokCL6Y%?n$b8MRGkM(aP*gv00^AGJs(hULWjxJ{6ZIvY@B?o?vG?4Q(=hnO)|C968 ztL6SEp+y)nEmJrbhJ5!y)9dkmuq7v_>U6m&b;3dspNL>5Yyf5kN$|HkTv;TKT`uV~ z6wzQM8U(0BIXXQyce5t~&0avy2f#%Q%}uKY$+0o(%@I-wSeZmi1PDi0gb0%h;aukC z_hT50iM~|qx}u{Ttl-KR5SwbMmg~@i>RA&%zc)a4FJ7nf=l=d5$2`UH{;vQ6n*0Dy zG!oH}^eSu}!mzWQL$e-GmG18Ceg)q3)xYrb1F4O%)?Ib=5Bo1Oi!nKy<8pCS7Dy1V zus*xVWheoM`(NEIL-XrX&^ z@JL&r03uo-W@-)$3=&Xd^46+VbG4nFQQ0JZ;}xYdAW5#Mpb)MXWV)94)v=zYc3%qJ ze_SEWo*iv^{0P(C-Q)gX7Hi>#w5z%Kd6|HqGNALj>w&t{MQ&PzFCVe6UoF7GFVM;T zp#L`u;AbTbWPS1_P>P@9>k6U2A8ghP)fasDthB&2sHJ5xhHx`6oB^SBB%3gVfq|CAYvB;tm zsQ&A9_TTmGF{5F+90pZ5V+V%@RfzEltQjhGyqcni;&Z_@L$sb42j&UO-+lRK{feF4}*N?ai#}8Do&e%j)V7>>W?@r$2yme%J=cY;|ORH zCdkCm>!cy0hr05?Af5Xruk*J1?w~8oZU9)LHQ*I8S9pDJW`(C`E5CW0`- z<&c0`CQjmpT#Et)1r7x#SU>(yf4>*G@k!(o)zCQ87bM+vFc%UMxgPKV3w zY{1OH_X(R;xn!VfdVatH%_W$9dZ;w$`4*nL5LYX11^yRw{QArL6O+>e1oIz!?T}il zMHBkx^pJu24O3V47mJ1_mEx?7x@M$`>Et7guf(R)s(KRTe(Q-QWNc|U(#t7WdL>Tg>e`pxH}^pf*bQJu-M6sdAy&ftfNX<~w>@Qq`o(`RjT zsDl)EvMAh3L3FH0bFov_+{FwX)Ash1glA|kyK$g7iXsSv_*Y9_3GPSI_Gah;9mb8p zkMmw$_l#QF^Jg!xB-1A+#Bdvd_>(>pb!zf5Hybu^Y0`4TR~AfloNZO1bBIsDhi=HR&bm@tApPDD*e38o<3<@5)$#f8OftG z=~~Y{rg1Cweud%s&vGS%p%Kok9`D@Ue1p(F#1FA(y0*j0M>=T}Dz6w7!=e^Vy+h}g zD^Z}2|4hpI+z&{_lnDzU<@{&sb6kBvLLnBS9&+DODS|$h637_esRvq_Z(k8u`Q;jP z1GWzuVC8?Ch{&3wIv44Z)ck&D>|rRasTl@ZpRg{xl#n!$C~lwlZhCqkh3>Dg0m)u% z*cN;^Uro->8KgWowBgE^(dj`_Zy8qf=|CY1sIg#jnl>9_5g*io-@H>DTEZc}O8?>) z?(bg*6OKkU;y6|hC{`pzb&O*=)F}rK@cQWk!`F`M-9y)t6*f>6@kxD+QJUnGq9JkqWPWS)8WXuQ#p$UPZ(M=nqK{sov!aH%g^2r)Hx2Ex2RO)I{w zwDi?|PTR_X>jL*%_-H)JiW!$R0%sF4Xq2}h3LQoux?7V8Z|>@2Xn%SCa2O)WOd}iY zvWWCkLAkEf#{Wzc3uX!SeiRC^G!(^43y80p!Ai8|TLdfX4 z#=COo|3oADNRp^8_Om}QmNBnM99 zUo?YWw?|M?r^1vwwb8iT`~$B2bfpw0Io+n*+nWyIg>=!_f;xBIp21s(C>JXPL*4KS z&Nts8jhNsF+oOX~RWRMYzL9b=#EB;s6s^+gYdrkt^b3^uHH91<*JGSu0l%p5HrydF za_ZC#vCU_a87vDS1NU!QNB{m!X6W#D#D+jJymeBpkQ3iu-9+G#P3i}(U^B4tIbG`* z(x1$W80e+NCwJEf)2cD(4Nxe%>rfUdaWCsrJ!D_A?@LJYK*}WcUl-P_){caQUm{7z@Iw=_k#^=4yJ9IQ9D{-%xrI3tL1gi)GSDh`j*(>`USG;yR< zRtB0(ra}v4VxFK86C%>Rjfz`8)_LAd6I~+Q2HXlJXoeOFeLHzNGIV3;?}078zn^Ed z!-vGj=P^-AHxe3lxg1kZn|XHjS^V3#Z)(4$;9G!Usk@ej$Wv~}8Q?Sq^Hd}v8;4O5 z!KaCxJZQip0pgI&%hwXl6t`03?lXlVkmu^37~jUF_Yn?lrp{>!_+Me-Oyu>AkGuB5 zsX?npLw7&5O-;F3G~lICWr~Ot>Eqz!TA961b;72_T*V8@(y^cbixkv&lT{{2|PpKO!;@=$J4O3;3f8czKZE zJE~D`P~Le4yaqCk1>4{o0PcEnM>ee_vNaMeDPaoqthj1OAMXQ5lLUlbJqB$pV;$$|Bl9QTM^M|*Pz|1=!zJ=rviA4f?hkZI6}(s!ef!GwA5hDqQ^ zWz!b_WAvMb1y#Ny$2qZeE@SEQJ4HpdqfJN7R^ZePtdu`gWPSC2Yw_+2bO&WFSgQPc zW}&=&qo%>hT0+#0q&WK@1<X2aykRNJ~gK}FdnCihzyEG=@+zId^Go#8%9tL6Ig zIopQA)_(zVz6$j&;lK)70X{u|@;VuS?ng+vS!np+3fj6d7X*aJ_&w#mZDvtQn}1fn zF1d17`pD{G^H6Fl1ZxQ%0e7R0C|nb=NCk20uJ_&5hnVl)-B8;PVSg&pRbGtKG;
f41med&6h|{tpLY!n>_VGnX2Enk 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 z

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

h>eY)cF&iOX&L{&LDm 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

esb39kJk66?6D}Ef?EiB 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 diff --git a/WDL/IPlug/Example/img/toggle-switch.png b/WDL/IPlug/Example/img/toggle-switch.png deleted file mode 100644 index 7a94d82f24686b28cd6355e64f913e31147ff486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18625 zcmV)@K!LxBP)=5WoA`Y6~Hzv zsyms9tgQDuJ={G!B7Q%2`hWh*4;`X@1R4CHrPq^wH~6DI$>0N2sDB7Tsrij4Uu^gy zw*DO*b6HyYJ2B>W{p-Si82k!vjlwuW2#)`N55r56gHQrrQ!UuAQ1*z6i)jUd|5*5d z%TtiTrJP$fB~>nXMhUe9VQE1~41Z97s2rpy;B`*5Kw?Ok^2O;P0u8<=1cPsHITovn zoO6egIwghUQMw=~&zZ&CR1~|pU@cHn3ZLeAA=+FC!r>x(lrTpXhztlq@bZG$7Oi@| zwPY7X#kJ_1L&Plnm9QOFjWfQMP_j{2R-6=KLr{^!B^XGN>I+MO>e4C}*_5@kB3hq)yT-Rfbc9sU7<1G;1=DXeWDq0N~P&?FDxajekEIL(rt=3p=2 zK0-JmyU47(D+AIv{NCrK@92msAqdfh{KIn;Ipt8;l69rrJCbjar3O+ zd%SjK`}XxeJzsfsx&DVgW@K>@`~^&7bCU*n9_07#1zt%0q+O7!ag;o!S!$CUM+c+; zsil358J+_Ish}WZ2)HrWgW$f!Ma>mruIljj!kY8b^Y46brBSa@(rjw?fXgp0tCuS) zgnj&R@Z{!QH_M$pQZQ;!y8{31%He{G+GAtrfj8uTK`0JN;Wju#;8L>S6vb@X-d$ix zG=KJ$muc`ve>65Yw;w$s8@E>jHgm>vgX&yi(O%BU9=bfGR?f)ypZ(!c(%|@m{182O zfx&|CEEj1UXIoF6RCYGj-K5hYB#K5~?dDDRd&ETO27bH-6$@oZCm8E*T!DV24Vbqo#svu2*>tm z!N4KG2C1A^$zj4AFlRaG5n6x~q%o&EjM=s7!t#1!HcVz$R>E6U%R#}RqL`vk zA)lEg^OVB2aw`nBGoE~U>)!phTGe31yLXSx&(9O*`gM{f34t4u$hMQ(3orh{n>+Ji zJLRiMmTqOt0#9NIT&N#`4;>^b{fSEJmA(aO089n~{*$I$?Cf-t8$J_TPJLmwlXX8> zy>+{})allXEM-v?<<;3{&z+tB_S_rqTx&%j2w^*^pxb(0%FsuTB1}mj3bP{PI6nH1 zK@Q%9ao+^LN>fH!bKogCVRvU&URrW0-YZ47mxk5(n7aOEW>>GXu#)6?l%zS|k{Y25 zho>;cU?1ILq(B4&DzujoPz_{B91Msi@H@WK%Y? zgo|~!Q<@9D3+~Tgn#C`J9>mLEdKzIwNkbSdK_M(-a*Cq@VorgRIR_7g4|X8TZ^O-U zOE3!rZNq0^{-Fs(aIQiF;bcTYew-g|LzYlM8EznWj+viOU)RECP$CKpHb!9{pgAUY zsLXMzjpGW_cYC~n6h~m9ElfhD3<2#yc_P4BP{M5(qYDGWL4 z{C8quj6iy!MvQmR(H=P}a}=jCOrvHnI(g+OCJA&}!e|pgTcx}xxZR7oGkKo5fgf~i z+es|T&SYXXdL2fN8i5bZzmyP!cRKC4$4?%(2CeJnvJ5#|aER!{32k1ze~FaOQ|@avC0{IhPaGb`s) zDjgoZi-BOXUtat4AMNaJoq=%4fA52z{9l%3Wy4oz$IyszTj{!JA75Sn?H_;o`LF-$ zB#mcbs=x_Vz|AN;4=e;9Jh<~F2>j1BH=mrRDgX|68=G1XIxs{$in_C_w{QFip66}b z7Vv<4$|71Qd>-(k)!W~^d+YX%_aLbs-gKBoGi5d*kBT+WmJx2#SK3hZd+W zl(|N0Z)fq&otxiJ)6_o&Z_-mfRe40a-C72%EW*NCMqfw|aOEIpceERL-M=9uL-KXE z+isLJbMgpGwPrA*K&@zDj5cVFOIw}zn1`M&)SuJ-Ts4g_bkqdd*ANbaK>o0+hH8+W|yN#u9KSF?khcPTJDJ@dknLf@O^rkUdDGOKjqP_t$I`TWQV=018A-7s(4hF&f zD1Y;^KqG}cPChd((Ha#?$^s5A zw+8b2qfG~8Yo#OQ6GKK^_N?*)y-IC)ncUT!NvI)X$8jS%!h?q0dU!C)0`dM7GVqZT zuC>K@n>n!b)Pn8{ElL?a?wmjfAg2-a#E?yl35EkhwSR2Xm+M%!Ur~_$1io77Ww#K!S62>8};|UbX_e1!7hAU2a1JDv3N+J4p zDIKyOO+%wDf_7jMC|sne$k%8ynkR7m@es)Inp#j*hL)Fh% z*S7UCf{YhvVDC(yBKHs7@f-JrF#)bpsSwXg`cnYf$#B9xQW&%JoGegZNz|O2$af)_ z8exn#;f>QYmH#daqt1KyPy`-x-ZWmI{lJ7V4L6fbk}W7_d68RqWAp8COAWPT1So68 zc%7J}nF#{*r+O3uE@YVp9>0MTLkP(n5Qv(a8ZDV0^S-e&xs7(1W=095OhgJrQ2@A! zQ}Ep3MPcLn5Ksyj5(hLv%d15*9Q~atoq!M6&ryUa3xoq9Bn+ZpctVopnOA^7Ae0NS z1-GEUb21xTo9pR-n(Z{aDZVb-h}Mj795=GmDe%$HC=GxIE?~n@I9Zzd;Hm)%1@B2= zAfP3l=kN8R&XSp%%-RSy9@WrgrL2$eN~OBPn3W${7@+`S3?@N_!vn(+L~&G2lBfd1 z0>Tt{TFOwEdcE;zduQV%oC@GZWNB%IEG?cTm9PeJr$@H7pMZxwmTnKz!XEtYCTK06 zS~FlDR+gt;n#5rO!o&#(1lj?^bqikD1!xRz&_ylPYBTiG#n;K@ORtf+xdmDYD>BA! zY(62YtJlT#8(+XgNj4Wj7(5#n`!Q>hFlucBc41{%>dWED(f|ah^rCJpiQ_5^mk;Xq zV8~pEx}oQK^o6r8l5;DU$?R+c0-sOLzOX1RUc5kWuil3!?9tuU7TMTX&+$}_OTgiv z9gh?SYz*AEU}&spA8_L^j-yJ9nu($s2vo<{AgCv8C`-cG*(SMg{xX@Fsl&IY#Pt{q zSCfA4tyc+Xk?ig5lJn;;iEgjEzllZ<9VWRCrCb??0EYv#f`;qs=Kux4lQy)U1cnbj z=hy2sva~!;W*Q+0Ltg};OSgA6$>*PcMp}Dq(rCi(7Z>U3s#n^^rIUrxpcHgL8;8gU z0rl020_6^5ZGWVGoTfRhG76hLrEL*VB585-3}%G72LW7-q$4~ zfQoE*FGWS#!iF0=W*G3>D}gdU(f^K%M=fW%8?JpwejEZ z6?3w_{)jgk3s-0AjkQtP5gQmBA()A@7})TE_JYQX4-`TR7NSwZ5PA^YAVYAwah&XZ z^UXKp$>S$rBapi=2jYt$ag6rTq1UcmBlqs!Uq7>a{v+QH_GBJ4)_{#xKp=2e6e3W@ znR<9re59!oMA;9xH`o;Z9SQ@3bpOWJH{eSYGe7*nkI36^zXL=%0iwo!1&z?R1TL^@|YRt|( zl*!qc1&6I{MWzSRUSQ6{s462X8Zq7!U#obd=O(lju4ZmjIR-I2r-p@FRIkl!hGF$8 z9;{cZ_3c`L1?KlYvAs>zs2p=$C^-u`Mc4BF{5Go003VuK_FNyJ+qiw(nQr;BO&eTx?;=dyYp7A||)zK32Y~(NrgJc!`E>HmDnkWPg2f|X|(RMu_wGqLj7$Z!@k(#kn%n0G{3)JL9VH74osog+H zPyifbb#zC$F;M)*m9V<2jF&SIEI~sB?R5MgltO`UT|GpRBQ@nDObK%6+SxV>c(Wy{ z4?#Iz0EEElKDV`}1Vz}+?c5c5hX)13VM1Y00MwKb&P9V(!N(D2P zBlyOVhM9RNGIcfHnhDBl5Z|xr&q*MJ$!n zgb_kfVDurr1q0;>Go~t@=4OREi4#|--G;FwJ^ab_UhYU7FD|R`*F?rj;$n!hZBm7a z7q_!u0%mE!MU07oS{srAw`)$H6Gt>B&S7=jV{jZ&2eW}CFI_;uG7KT))5UI{u@*0A zio)cOjq1&bQ{==^&546&+tHjjyQsiQcg}IdtV9bTC$7iWl7wtPdJQWau>tu|EN&)JT4~=Y=l|F2YU`|Thv{zXgXfDwA*?#-&|;Z(44C+*;WODHns+hJ zcHPQcucJ9}so0jhQ?-$L3{D);oH)vTu#Kf!-Ms?oMZFiTUD@8f{-@`QSC{LRAA^f8 zq7%YnlLl@cRLMn} z#o5;OlgiG{x|<{&_}Cau9Jxsft~qfeTZF04Qvp(Q;>fg|IAT^3B~Dx%M_XGP&eqnt z6-6k_oiUfY41OMxAgn^V<2Aw66eo^RTVq(J}!RgeVixz+8)Fi+Vq z)sN@IId({VuTFCo1fsBgh?M}hI}-e0m=mW^WO$eYnJ9~h@JOR^zPr5iYHMSoCA!hi z;gfga@j%VN@~1_%wsy$h{_RIQ_wMZethK{GN@BL2=d4o{G=XU$8|O{KhoT2LagwK} zQX80WAkz!Bvn=`a*3J8GwHAUE&(oYZ=ej)n!ehxevXff);x9b+%!lngzM918R-RdV zyf`T*PP1}g2@dxXJ3HIS4L=ZDj=QkiX?H(ZUA^60TI$rn#90(ad9BjyInMmI=T_di z*4hO@61J13bQ^?(v_ffx9Gep-kG)6=*-1iVc5wFvW+}ATaoH3^(pjP8>VIj6IBCJMix#a^m^|vFQeB2pFq(0S*!3!0!x? zB~Btz7Kj};`VMd69Dx(JuR(3Iz84JSMJM9KO8*{8PT+7^)E| z9gH0(xtg>edhq5Yp~SF7(g4{1(dR^Wy%QNH}2)!b}ArU&`6NV@u zRipzT5u?0A(5V@w5^1k7p!j7@F_e&$;=g$6+g8cWE=<|A_B+b_kv2d>U7$(cxKR; zZGtdoXtm}MKd_1C<5?(pQ5J#C2#LDCaQ;R5MZJDtSz`nm$%&KaNa#H{L}{$i^>K)= zK|@s(3WpBC%iV5!2L6myYgMwa*dWbjl?0)W+yfZG7P$~*(Rh7;8lL$!&1Z}xOW4B zAx2VUMLgDk%X3qIhDE4cs`x1ZK0t^7gsLP`Gg6pPX{TFN4YbI1cDBi*M-LR< zLvDj0g^|l=3;w;=Zqb`JzahK3JL7|1NlFPk#u$?8m=Y_VK_yjO1H(J0APYljDGFhd zlpBSuR*QW8*=J;?-XO2P{ylQ;+yY6H41(Yu?%|QofBT8}&2K)U-ENnNF>$Rd3{%1= zh_hy2xF{S4yD26_9fw?T*=xqtsYd9?O` z+_>>IU0Zv!&zBnkII~OZ97WJ9GIw7K$i_$%8$*#F@Hvo?Sh+US&`L>_$0&UF-W?ET zoqYW9Z=`@Y4WOOCoF#BpH%xXy$M6nhDqupsvJrIM0Qm(-1L+UXK0PE*^AkY~41$+& z9_?pwI21UGo9#4B%%gg)Lb&EgP8`!YiDme1s0o~J@FDF&8!ZxK;(i3qT}45&a)}*x zz1XaY%w}}yq<3KP2J;!OR%)X;ad^6+7#MvX6Y^8!&=~5FGU7gW#TN=~&vBykK#)qM zwq3OI8GTkDN=drV`+L-QP^~_*ac244jZvI9nJjVeAkDatYzxUpN%#3F_6pI`bGCdECYnNrOwbC_W=zT$gtzWcK)SKj>P7|meVFC4{>MCOGAA-j^4 zrs4 zXMN+*+qaE7y@ zXK4?IR0-n7p09A?h@wZ7bhT1_1h(+iOE10tVY|J1uHD&N!b~I#s+&toXTN^=^6P)o zY|cN>%<7Q~0b2=SRHiX9I5luZ8!_uNNo24nN6!JH?P_>`M-d*}SP~+_%I;$I%&j1J z{cqs?2niAJ`L03PYew_f6^Z1b7?hc!hEX%fT%x2w6UZmPlQYA@*cU|eR9p~91KIKS zh72JIGm_bX+TiT4%?n#-gc*?wECp0IFn&dT@OtTLHOU^6Qp=SxM2r`N+rUADcT4m-YK5IDxoA3 zqb+$VzTZ&<2#Bzjm7#XaD}ci`cWedOx3b)_3=2aE0_t|$ETV=SCDefxQ}HE}MvPSQsi=+i=6 z<=&bsBZo^FtNH?i?t28@fg^2!Gj4OqMZx8&3Tl))nG<75VYVzRO_osrR2A2^Ao>LSE9Y8b4s1W4XKf??ELXA6k6by$XcbL`M_`AwflH zGjck~Y@F(c%CK;x2{Fx!)50*FqZnZnXAX%}rXsFNv-kH=$@Bu*=8SP@`5?I}db6-l z6nJ$&Wi}3V0jAQK92KSQcX1rMvCBKxBi1v8QlE{m0&&=$tXj8gJnAuQhYj!TAN?F< z?B@hIW}sn*oi$FkAzM0zr_*ouvy&VS(9t*vG4f>VIGQ=akR4GwH9RdRjtyx?kkN?4aRy1p9x{!;=Gcodb1E~0Bbg+SIAok;1w)A0 z7LjZ)^$=sLs}01N@tim^WuG{WAdnnkc;#@-iPO_VPE0wD6L8`t3ZzQ}t8b6_JR>eF zb}VYsJ|~WHni5W8!Zj$F!#z)%6Q@tIab<5Yht~0shr% z_Zwm1%ZrS+6}{?|IB|M*#N`JhyD)b;cGdIkC0P1Zn8)UbBW9VT-dokY$Jb~=H>|>r zi&$)cAh{e;PEvAGPMp|3L1U2VIKmP^VdX)!5x$+U)D}KnE;J|3^Q=Z@Wr5?n3%+o8 zPjli#PTC@ahY&G2DJKp=9ViH7&pr%9Gq*)GW{K@L?Vog5w3KL0TD$5eCbZ>@%-6^<_EKL^(AVBxS6ET z?rwe&@~>_NsYulg=ZcQFTjWJMOZhgE7|kuF;>7L8c8npyw>-M!*WD|*o7dN(^((8p zU;k-Xyte#@l^?T3(ol>zvQ6Rl!98&|5FYsxE;(`OovSE)HaedopRt<)QJ+5|z2cPwju+zMSJAN#)zZa%r|^329|Y?RroLUXH2 zk>oioCr%inCEzoR2bN0~3Wv{j)4he%j^|%K`!f9__s3%+?4!;axwCmEm=#N22*X8l zrzf&vk4jD)osJWyYt%sY&1uea0uK>qN%my>No9R!-R&eD5|Pon-#5tvl5xZ%^9Ati zMF@qS3XnKeDDuQqoH)_v#7PcXk!5)t#c{N`wc)I9ZCIVCOYV%}#9byU1hhe_A%r8( zZMu#>>zLo z$LHvk=nOi)oQe~tXE!`YE@)0u9+MsL-`YZDX??~Ela&daxIb_IJJQ;25fRf?#j3P9 zQl?|R0md6c$SRJ8xf<{*qa83gPQg2A;^w?{*qn_F2Pr}$r-YU zUmYf;i0o|bkdJ=(cRMdPU;A0Dx$qk&vvyccJE&RQ>8Hox#8IILFbt+8to;HD;XGvF zc9A8Y-oN?at;#~Ua?iUjIdNY(jy%uCUaodzCoAE_U(C77AEtZ7Y96OsG-G?PBupqF z$K%8ai8KV|%F;DF6^YpCZO1ogK(=Pw`Q5bL`{35NR{J1KtJ%Zw+-@H z#0i30!_C|WgnKQVpGZtW6Lc%e)0PDh7xMcEYe`Z~S)|8677cLX@DkimsKCi_BPHt; zdjbk+=n^`>J>oB-!p69zZg*SvH&p3!`!b`|$aN;0lW_qoJT}ZK71{VLd z!MZwJa^hG{EXV>2*2cOJFf55wswU^r>CtFopd*?SM@yVIS)K}iRe(oxxjV{b0V=^X zCyw?xaie%pPmL3&$px6@YLcT43KQ0H&x8|4k2wE5=fsT@=s73u8FS(uU+ncd&pC0= zIdP}NiQD;I;>3~vh&XX}i4!*n!~707an4YmxRQpx15VuULZ3KugVX90cQQ^~{{+qc zUEsv+Z)KJH#CM)iq187FRNs77_q8%ef$ zs+_n9ed5dz9SEAwf)h6^(0;ePlD5cca^m#Kfhg_yje^xqYJ7NFoH$Jn5$wf_S9D=) z(GPZ5!5{yP#D{9NM#3-@SOR=NGh_P1O%?Rigv)h%3fX*ta#d4Uf=s);F7X_noIP`% zEG{C5y+Y!+OP;JhAP*kil~`c4Nm$m-)RlQmA0}bzO3Ip%!SWpIPv^PB`P#NeUb_4i zJYL7D{veDmzr@bYCi&*uFUi$wA4`GCed0tIVQ(r8r0 z^74{un?wdUasAwSk}#Oh%H|8m#L!saP%|)??ry?Kl+En((&!T2PQ&um^$lrhbF$6tMe)z*5lQ-UYgY>!)d9e0~tgSsHpMLiD ztdd=)-{WFqH*~tC7}(A}CFE0v-5yvQu!*K1| zRf6mb91eu{o5n$Ajv5eUm=mYEKV%*v>vflq3f=?_H`*Vfx;A9_Zxl+=0FprCe9e~< z*x?GPXTxd5z_MioqCz6gbbkX!Li_iPbzdWDc<@m*!-a;d8DOlOQYyn7O_A<53*y5W zqUOZOFb~mHGA=SjfG}hS(@RBbrf)xqB0)Ho#d3t>>N?V60YJlT(8V}ToaP+p9vG%g zNg_!Pl0Kx#4`t>Tx;0J(2u6l4A#~p&7eyo5?=}8Maag0%XqjigPlSQ$6&baqp_Lcq6EXz*peS9TTsYO4_?;SQWBK3 zR7Da5P6LP$)`D~pkPMowTC&tMKfud2f(-X?5+e_*DYX^HK;{ zQLQLY5I6F*Abt?G;Y;+uZe*2h)J$0`ZNp}L81 zi)ny6qM=a;KM2}k5bkAZjCgVQJDZlvFqGSDje3mCXG*Rq4~+1?M16pOc0cSu7>H3bW|&5K&N$lHh~!G|^}`TIyst7g(_SE#L$O6h-rysk_{B3 z&BUM;X)j?|X?1&h*zG~^(m`;Un>{kc95+mu;P01x*D!y$p>U zoiUs^`0|eApa@q{V6VB57{I{LF-Oz?CjF$Aq;^CaQq1g%>Z{So_$R188M5)W2Hg;^%q1#Uot|!N} z_uu=2|G8G1z4z7i&;N^ukM6z!6Ku^KeqsNnBXQzJtyENgLa|*DQ{H5{iO2>&ywn*) z{-_>;@r@7O`-A`G;)PfK^8SO>_n$m@_%a9t3rK%waq;YpBXQ!!Ew6DH)GXYOGZ^y6 z;)I)x1$>Uqo;m-?ndOz=Vk&}to)nozUh8m9+@$sX=u`fY7~`RBVTv@9Xt4If5jb(v zY+1oK9D9m9Vd|kr=ER-g9Gf12wL|wiOdo+0cfxb+5sHbPn9BJ$IX#5pAk}7{}VQ>@hcz}!vMspI)3~S+NoE0igG(MAtX@56+ z+70yMQHhRVGxQXOik`j!PlW_H!BCx+FeUAbC@=HuHPaXB^f+-R6XZMO#EtgEr@)Cj zxpv6p6V_34(@{8a6ZHL@6F2d~LpPDF5QT*C)BfW-;KZ3Wejos&j)uV+&`pUGC!QuJ zj#{!GoT9?Ja4C!0);=drh?EpOhCeAJeFDMBLOcyl995h++pgnUgu*i{tQ_h(niB`Y zW%(}2^A>{OEo>N@7j0SQNpj-EDRJVIZ6NxOG0=qPxl09O73Ml~#I|Sg{KSFx^Eh3j zX}Vzv9v4ZrL6Aa(_R2-7Tgsl46DJYKSkKUbrDjl27F1^{ZzqJ=!gZHHD3{{7spm8@ z+6x@dS@2;k-)nWQ%4>jjM4q=njFWQWaA*)O4n|6uPi?1}TUIqDmhI10f6@_RDZ$Qu zwjHLfLle(&>OqBxUVPK86kY1tvso{`Qy>f;QT9T0Ydk(Dj)4%M5o%d=xNWnrouxZl z+w*5<{10ZEjU})hW~ohT!ENgzvspKTwR_dG=Zao@x5$tamu(Aj5au)`Ck`2<)VExF z$*)$fX;aY7>El3>Ke zZsJaqL^vWRjxU0}J(dAdX&OVsaX4{gkP{ch(dOosv%a}yb$Zc+E^&l}o=d7Bc7t@9 zu4B#E7INa4trOL0IdT0BW!az{LOi-=0^g_=^}2=4sP)=}i-nF&>VZ$)f(A}j_?-30 z<;Ud2$=Xw-pfpc;n(To0))wmZ^_gZhS!vFU=fvG_lh)2Q5lPajxIvr4^uW_>gK{2I z#ppRECl2)@NJjHK^5DhHT(fIcoK|aVGx&MlpqCZ{$%Q*3V*qmE2-(@*A|L(o*E=sS zo&8yDVfi;sk?*jg=)h!}fOe0|iBn_6WbG^L7RU3@wzk2RKfQlz^{vX>+{(R&E}LJN zCtukPNi*cc6~s>BWM!uDi#fmgVcPDk=2^N0ZoS7q7-@t$0v|d^gPb_3IdL)(N=2IO z^mf}fsON3XxZ!Tv?R{|T@$F`3cc-4^Ig8>rZ`5kNSugnZ%?lT=C9P_NNMbWbG3-BVsAV>8Cc?z63p*e9fNh%l@R@RO8Kz$BPvr3X8Cl1mBEG?Mk>+sij zO0$bqzAP0oB(mldIdL>ooIy+kcp*D(;xVoe9bWKlnfF3uV+C&uY;i0Ic38yIv9cg1 z-+JBW#Bt4u6S=IEfjI$aiC~J0Co#FiA7^S3H=H=}v^jBNpA)ygjczJrXi}bd&WU@@ zi5uFvdd`U(bn)NGK5@VP=)*tj_BykM3i6$D;u6h?)4aIf9ZsB~pFQWq8BQERCncc) z1j2)MM8qP@(sYKvKX@jbIE48l1~?3>bf!K_9LFU|5|QnlO^Nx$YRae1i8F7#{@Od_ z`qy9dn=W8tapueg^75rO$+825q}g%IvbpHQI?pfW)x`DYL!y9@*aB zATPc2BIe+VB25)d5m`J@9Fd0)?~=W}Jq9Kj;gDS*G}j=}4HuNn zs4AzZ8AMHk##n1_mwf*Dr;bsqUwst$>`t>i#r=NW)kV-LU3L3#*+*-fm0freqK>!SK{Vw4i9=l<}cJEM>|l>6+{gC~c&@Odur zwI_ef7*u%AJY~QCJEy2x;hR2VvV->ekWT zrpl5_psOf$9ZLYe}AYl*t98mSUa?-eeI4|Rg z?2A!IirGHgKbE%Bhx*4u9H&fnoxzgwMV~^C0?Ae->a|Qe%N?)G@A`X$!+qk=D=?y> z0jr0MvM>ypqYLSWno5M8R1_|-1&-vxxeBPPu%P;pfF>*Q#3s*0xtA#l0>fewbGhe+8K10xK+7jKB~F}B z-Ku0Yf5VZLmA9!Zt12k~s#OXz6_sVFXT+6bdx4_JLbxH!p|aH$F~*B-3`rMNoCMj! ziSBEKlB00q#J)hx0FpCbE>Z0iwS>c>EBp6wah7FCO<~9-tw>-dhqki5zApDk(0~o# z)O3m%*C$S$H{o>76h>SE+7&!IvuzjA^a#t&HBkZ&k#Yy#mw7ph-b*`0)Q&jQ1ys3nX)I7IkoQhO4hY-N_RohS^k1py{e zSy>obZtyZ(!ecBa4&BpyYwS9sdU>h(_23;b#vP1BawskAg@ASKv39+cA$%LwNNv~i zxDmz(FmiYfP>O~)ap*O&?!2qlyHqL(A^n-_WU{LWx_`gdK_BjK$>9Ve?xJRJ?WA*} zer1(WM4B=m;Xu%%xb~4{2OXF@^l>#c)!7|K9-s)hzpFNdWU~eZ`G;78)%+3ME=tY5 z`(9+)K9=o8Mr$#qPn;|nhLCKF%JXv7U;&1yuvFc84Q5B7kVC76P{ki~Z){nCaRxP0 zCd!oQAqUF7@I(5$NV_eKa5jl5u6gouPXug%Q*H)i(uq;S(dRso zBlL+=cpxM}NO}?PL;W@GTlG7z3NuOK^%<3hJy3{Z7zug6fcX*o#2J8+AzkSM2h$0n zP-`9axV8G#h+eki4?FkSf+LsO&=-BfFdW03~SWX-(6&IO|9-~AY zf|aCV0-*dToH#}X8*Yyfh#na@I>;a;6K^~TrzeiAp;1^ka&Uqi_4+VQ96OlH3=32q zo9V%<({SS0=;UgIK=kmNjwE<%ssHm3ZxM0kPB~)uoE$AC?|2^4%;Eu(RMtxvsRsX zxG;bAOR~@UDU;$3z%T2y34P*@2&)x+65o(uVOZIC>GJFUcfH=YKf;D+IT%V#-1o-! zi971qf!N3TQZa<_;pbK^|IOtWU;7J4(0BUBE&I7}|6u;|rB^3%;;jGXpZ<&EAHnID zu-fb_Ev?)P{K_^ggLN0r6nD5}B2=l=Hr{#r_x|-C|HJ?Me|_!MxBeQB-A4tB6Y`tX z4{p0Aso})E{FnD1+&)!K+)*{tKiJym#9jCV4D{4FamPKld^Vi8NvFsYrk>}VxaXX> zQQ8@iWIQEK+>ssXG&ym{2V_hznrE+>r^tyr;ZPkdPkl#Z%Zd1Dk0=N!!<{?8a zn8ln-WV?kZ_BiD!lF#y@XcMWnQ{u$+1(Dn~JS9R-oU_EZ6*`tP=MZ}qd4Y~=RpTsK zOKG+tES{uAwhlt(TprenR5Npq&xzaL!68@+%Atb!EN4NzT78S8%yxwfLNO0SMNV83 z-t%3@ooBuftzP#knnXd0cFvLKB)ip|kP|00q6Be>Gsg<6LKDlL2`WDkU9w!n+;$v0 zbTWr}nd=0zF75H?X6SG%MKv2`@m+;Gmo{_)P8=efkeEkVU=yqEaJyj__Ttvv?fKdZ z{_izs8%x%VrTWCdt!%+A+7|ZU0d>`!xn3UK&5OL9ifo&34H=LOcxfUCUmo zy5TE!?$q0l+gCPjul?h*m4)Ty|D?jmS=?ZQ#|EKunH#nrh|mk&|Eyc|zKDA18p)VL za*aJ?5|uwaCypv&4w83#u#1{4oVn2P-*>9yr)S?;SZUOnlq~4K#PhJT>SgT$CEbs` z;PK5ZFUfQ4Xa(O0hL#o`AzR~2$%)fKq0vH2p@C!D3s!E;BvHIT(qjIFSI*M;pL%1b z-`2wpd2)Nhw`YCN_QB(=)xISp&*Z7lBH?@yf|CcM<5J@cVoFY&svnI4afw>bvOI~SB-+~8a<=z1r`%;>=Hvk_sKtb&&K?nHI%LkeoMTbYB29U^11?^zFVxm&XR68Ex!JLt zxcmQlkLz5Z(Ex)pY<`MM-ottfTLdR)s?rsG6 zhYh-LA>8*Qyu&v9e`kyQ>NmgMS-$+j&lbX^kGNax!WZhGX5o67Ajjausex06%W_h& zd1i<9c2ST|Zr#8A_FSd4^5CA!7Ut)P^R+|LB$cf=Q#(#(UugUyn5+I(H|?#aS+-rU z94F6MeYsLzKe7DUXkHVT`4ZG|j>`~iYNwhiAb#@HgrDRAP{VL3Kl1d+H% zFoN#(+F*~&^#ZTK9rl2QZp(sMEGPL+!lSLC$M?9!doV{uL@oyASTcc8)uu~d`b3;K7%;?O8QPab z^WZr=2-1n-Ci0Vt#&+1VIR6nN!fz`PJKB{qs*h``gO<@BQKbw6u8U z8xy?9w2TZ*7-t5mi?6j%68d!i!R_yT`q{7kJI@I(zj*OgGC#jSYqgLx8na|>ZjLn9 z8U)gf>Q`TX_FsN`^V+p$WB#r#+d42I+eZ-uF`QU4xRA*DLLy}m`lNwjWcBuq_qTU8 z-u(XCKP2^fjku5)An)M9#k1u758flc{rnoiI_2w|4`i~u6MIG_*;eDEB5otDSVsUYa zK7Rb@Vz1kt)508$#Uqy!C`cx2O$V~xv=%Ba5b$0|2o&yO^m?6!=XuuL{0wQ%)rcQ> zl6L@sncls7TW$l)G%D2dY$CDfaJ^AG81_Vs$lB7etSha-rVKkZ3ySuyev(G;v8=LFo!GpUJ!2a;zLs{*AdwWaPv?YSx;--rJ9dUaLNUsdx*5FdiXz+)OayPM}QwLnWnOz?vT_X$K~X$Lqg_#QrR zlI?Wb^LOvwdgtBm|M1^}(MMzu>faYc7SxyaB8N%Yhbf94$@UZq_K(AbpTpU^-Pv2f zv+VuzbSk^&p#d9^hVC8L-|!pDi8IhQ2{x5TdtDe^YDm(DoGeW}LlHsEV8wq#X#6%QX0hVmAj)EVGvx{=T?s9#Pva02yT}gCLLk1O1rEN%w?f;<-!`+9%u|-io%jo z@qC>TmbX6p$VLNpAKK6F3&i$MA#@{emHpE`;8NX$sfk|!-Emc^Z)7m%1I@GE@9a-}kHhDvm+t|8qABO?ly(Lw>*9gP=Onp4#0eGaX@Ss%o%xd!syhB6|FGi*$s zxPAaCL%NBnJ1%PhbA#iQwd;eBp-?zKfi$qMSp`!SeNeI?%4jVeXka&% z6Q^p{ivp%Rd2tC$)}`Zd2v7^I<3)uBiw(&+aIk1PBG?tbsn?z(a_dr+8bQ!$5CoD| z6oyra%QDzt)3i=f7e{g8OnGL=;&V>%{<6Gx3VA~+$qt?>j4mZtnDYL=@$Xu#?XzV{ z8Ke>fvpk5n6w-teS!N%RR_+sbfD!kGp(1e#$JLZ0+njKrpn)Is zY-|gliFf*@QVUp>htYn}LxP^v5FNeyGdk_WYoZW(p$0d?iPXt(deA*IWEe$oI~ZtE zYA@T@0A3uX4XRh1Qq^YWCgV796VD7abQ?WV8Mw{#CYsz*Q^I(O<{ik$-RX2Bg9mAh zh{hk)g^^J@a&PPin?*7b8`5@ewzCb12BH3j1cC4E?d?H&`K=CslI|)sRc3t+cF~)v zPn;p`mNt!Ozk&>UAO^xdn;mUJGranSJ3Nb@pii7QfQ>OF)IC)}!RG^JGqN|UkgiPeb4NM1g!tKP7 zhDV5fX74zmrsBjM8woi?uNl{{?l4XqJDkr{#ubaP_?@y4lZI+Ei$~M&j!LjPg8hh5 zlj6wXJU%Dx$THI5Ict&;k8|y(!igKlhnu9eQ{lu-y3r`Y-c#ko(Mj3hcfpAp74*In zPTVNhK31Q&36tHCIdO~*^4pHvC+`1`oVYW6PMjEQ6nBslSAXi9xHkqkaU~l$$ccON zX>;Pv4RYejJLbO=oH%&)^lsHN=EM#3iF?k88=oRS=fpkd#7)x9b57im9O^kIZsbs% zV0=!0m -#include "Log.h" - -EHost LookUpHost(const char* inHost) -{ - char host[256]; - ToLower(host, inHost); - - // C4 is version >= 8.2 - if (strstr(host, "cubase")) { - return kHostCubase; - } - if (strstr(host, "reaper")) { - return kHostReaper; - } - if (strstr(host, "nuendo")) { - return kHostNuendo; - } - if (strstr(host, "cakewalk")) { - return kHostSonar; - } - if (strstr(host, "samplitude")) { - return kHostSamplitude; - } - if (strstr(host, "fruity")) { - return kHostFL; - } - if (strstr(host, "live")) { - return kHostAbletonLive; - } - if (strstr(host, "melodyne")) { - return kHostMelodyneStudio; - } - if (strstr(host, "vstmanlib")) { - return kHostVSTScanner; - } - if (strstr(host, "aulab")) { - return kHostAULab; - } - if (strstr(host, "forte")) { - return kHostForte; - } - if (strstr(host, "chainer")) { - return kHostChainer; - } - if (strstr(host, "audition")) { - return kHostAudition; - } - if (strstr(host, "orion")) { - return kHostOrion; - } - if (strstr(host, "sawstudio")) { - return kHostSAWStudio; - } - if (strstr(host, "logic")) { - return kHostLogic; - } - if (strstr(host, "digital")) { - return kHostDigitalPerformer; - } - return kHostUnknown; -} \ No newline at end of file diff --git a/WDL/IPlug/Hosts.h b/WDL/IPlug/Hosts.h deleted file mode 100644 index c9210f78..00000000 --- a/WDL/IPlug/Hosts.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _PLUGINHOSTS_ -#define _PLUGINHOSTS_ - -#include -#include - -enum EHost { - kHostUninit = -1, - kHostUnknown = 0, - kHostReaper, - kHostProTools, - kHostCubase, - kHostNuendo, - kHostSonar, - kHostVegas, - kHostFL, - kHostSamplitude, - kHostAbletonLive, - kHostTracktion, - kHostNTracks, - kHostMelodyneStudio, - kHostVSTScanner, - kHostAULab, - kHostForte, - kHostChainer, - kHostAudition, - kHostOrion, - kHostBias, - kHostSAWStudio, - kHostLogic, - kHostDigitalPerformer, - - // These hosts don't report the host name: - // EnergyXT2 - // MiniHost -}; - -EHost LookUpHost(const char* host); - -#endif - - - \ No newline at end of file diff --git a/WDL/IPlug/IControl.cpp b/WDL/IPlug/IControl.cpp deleted file mode 100644 index 35cdf4d7..00000000 --- a/WDL/IPlug/IControl.cpp +++ /dev/null @@ -1,449 +0,0 @@ -#include "IControl.h" -#include "math.h" -#include "Log.h" - -const float GRAYED_ALPHA = 0.25f; - -void IControl::SetValueFromPlug(double value) -{ - if (mDefaultValue < 0.0) { - mDefaultValue = mValue = value; - SetDirty(false); - Redraw(); - } - else - if (mValue != value) { - mValue = value; - SetDirty(false); - Redraw(); - } -} - -void IControl::SetValueFromUserInput(double value) -{ - if (mValue != value) { - mValue = value; - SetDirty(); - Redraw(); - } -} - -void IControl::SetDirty(bool pushParamToPlug) -{ - mValue = BOUNDED(mValue, mClampLo, mClampHi); - mDirty = true; - if (pushParamToPlug && mPlug && mParamIdx >= 0) { - mPlug->SetParameterFromGUI(mParamIdx, mValue); - } -} - -void IControl::SetClean() -{ - mDirty = mRedraw; - mRedraw = false; -} - -void IControl::Hide(bool hide) -{ - mHide = hide; - mRedraw = true; - SetDirty(false); -} - -void IControl::GrayOut(bool gray) -{ - mGrayed = gray; - mBlend.mWeight = (gray ? GRAYED_ALPHA : 1.0f); - SetDirty(false); -} - -void IControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (pMod->R) { - PromptUserInput(); - } -} - -void IControl::OnMouseDblClick(int x, int y, IMouseMod* pMod) -{ - if (mDefaultValue >= 0.0) { - mValue = mDefaultValue; - SetDirty(); - } -} - -void IControl::OnMouseWheel(int x, int y, IMouseMod* pMod, int d) -{ - if (pMod->C || pMod->S) { - mValue += 0.001 * d; - } - else { - mValue += 0.01 * d; - } - SetDirty(); -} - -void IControl::PromptUserInput() -{ - if (mParamIdx >= 0 && !mDisablePrompt) { - mPlug->GetGUI()->PromptUserInput(this, mPlug->GetParam(mParamIdx)); - Redraw(); - } -} - -bool IBitmapControl::Draw(IGraphics* pGraphics) -{ - int i = 1; - if (mBitmap.N > 1) { - i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1)); - i = BOUNDED(i, 1, mBitmap.N); - } - return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend); -} - -void ISwitchControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (pMod->R) { - PromptUserInput(); - } - else - if (mBitmap.N > 1) { - mValue += 1.0 / (double) (mBitmap.N - 1); - } - else { - mValue += 1.0; - } - if (mValue > 1.001) { - mValue = 0.0; - } - SetDirty(); -} - -IInvisibleSwitchControl::IInvisibleSwitchControl(IPlugBase* pPlug, IRECT* pR, int paramIdx) -: IControl(pPlug, pR, paramIdx, IChannelBlend::kBlendClobber) -{ - mDisablePrompt = true; -} - -void IInvisibleSwitchControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (mValue < 0.5) { - mValue = 1.0; - } - else { - mValue = 0.0; - } - SetDirty(); -} - -IRadioButtonsControl::IRadioButtonsControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, int nButtons, - IBitmap* pBitmap, EDirection direction) -: IControl(pPlug, pR, paramIdx), mBitmap(*pBitmap) -{ - mRECTs.Resize(nButtons); - int x = mRECT.L, y = mRECT.T, h = int((double) pBitmap->H / (double) pBitmap->N); - if (direction == kHorizontal) { - int dX = int((double) (pR->W() - nButtons * pBitmap->W) / (double) (nButtons - 1)); - for (int i = 0; i < nButtons; ++i) { - mRECTs.Get()[i] = IRECT(x, y, x + pBitmap->W, y + h); - x += pBitmap->W + dX; - } - } - else { - int dY = int((double) (pR->H() - nButtons * h) / (double) (nButtons - 1)); - for (int i = 0; i < nButtons; ++i) { - mRECTs.Get()[i] = IRECT(x, y, x + pBitmap->W, y + h); - y += h + dY; - } - } -} - -void IRadioButtonsControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (pMod->R) { - PromptUserInput(); - return; - } - int i, n = mRECTs.GetSize(); - for (i = 0; i < n; ++i) { - if (mRECTs.Get()[i].Contains(x, y)) { - mValue = (double) i / (double) (n - 1); - break; - } - } - SetDirty(); -} - -bool IRadioButtonsControl::Draw(IGraphics* pGraphics) -{ - int i, n = mRECTs.GetSize(); - int active = int(0.5 + mValue * (double) (n - 1)); - active = BOUNDED(active, 0, n - 1); - for (i = 0; i < n; ++i) { - if (i == active) { - pGraphics->DrawBitmap(&mBitmap, &mRECTs.Get()[i], 2, &mBlend); - } - else { - pGraphics->DrawBitmap(&mBitmap, &mRECTs.Get()[i], 1, &mBlend); - } - } - return true; -} - -void IContactControl::OnMouseUp(int x, int y, IMouseMod* pMod) -{ - mValue = 0.0; - SetDirty(); -} - -IFaderControl::IFaderControl(IPlugBase* pPlug, int x, int y, int len, int paramIdx, IBitmap* pBitmap, EDirection direction) -: IControl(pPlug, &IRECT(), paramIdx), mLen(len), mBitmap(*pBitmap), mDirection(direction) -{ - if (direction == kVertical) { - mHandleHeadroom = mBitmap.H; - mRECT = mTargetRECT = IRECT(x, y, x + mBitmap.W, y + len); - } - else { - mHandleHeadroom = mBitmap.W; - mRECT = mTargetRECT = IRECT(x, y, x + len, y + mBitmap.H); - } -} - -IRECT IFaderControl::GetHandleRECT(double value) const -{ - if (value < 0.0) { - value = mValue; - } - IRECT r(mRECT.L, mRECT.T, mRECT.L + mBitmap.W, mRECT.T + mBitmap.H); - if (mDirection == kVertical) { - int offs = int((1.0 - value) * (double) (mLen - mHandleHeadroom)); - r.T += offs; - r.B += offs; - } - else { - int offs = int(value * (double) (mLen - mHandleHeadroom)); - r.L += offs; - r.R += offs; - } - return r; -} - -void IFaderControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (pMod->R) { - PromptUserInput(); - return; - } - - return SnapToMouse(x, y); -} - -void IFaderControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) -{ - return SnapToMouse(x, y); -} - -void IFaderControl::SnapToMouse(int x, int y) -{ - if (mDirection == kVertical) { - mValue = 1.0 - (double) (y - mRECT.T - mHandleHeadroom / 2) / (double) (mLen - mHandleHeadroom); - } - else { - mValue = (double) (x - mRECT.L - mHandleHeadroom / 2) / (double) (mLen - mHandleHeadroom); - } - SetDirty(); -} - -bool IFaderControl::Draw(IGraphics* pGraphics) -{ - IRECT r = GetHandleRECT(); - return pGraphics->DrawBitmap(&mBitmap, &r, 1, &mBlend); -} - -void IKnobControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) -{ - double gearing = mGearing; - if (pMod->C || pMod->S) gearing *= 10.0; - - if (mDirection == kVertical) - { - mValue += (double) dY / (double) (mRECT.T - mRECT.B) / gearing; - } - else - { - mValue += (double) dX / (double) (mRECT.R - mRECT.L) / gearing; - } - - SetDirty(); -} - -IKnobLineControl::IKnobLineControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, - const IColor* pColor, double innerRadius, double outerRadius, - double minAngle, double maxAngle, EDirection direction, double gearing) -: IKnobControl(pPlug, pR, paramIdx, direction, gearing), - mColor(*pColor) -{ - mMinAngle = (float) minAngle; - mMaxAngle = (float) maxAngle; - mInnerRadius = (float) innerRadius; - mOuterRadius = (float) outerRadius; - if (mOuterRadius == 0.0f) { - mOuterRadius = 0.5f * (float) pR->W(); - } - mBlend = IChannelBlend(IChannelBlend::kBlendClobber); -} - -bool IKnobLineControl::Draw(IGraphics* pGraphics) -{ - double v = mMinAngle + mValue * (mMaxAngle - mMinAngle); - float sinV = (float) sin(v); - float cosV = (float) cos(v); - float cx = mRECT.MW(), cy = mRECT.MH(); - float x1 = cx + mInnerRadius * sinV, y1 = cy - mInnerRadius * cosV; - float x2 = cx + mOuterRadius * sinV, y2 = cy - mOuterRadius * cosV; - return pGraphics->DrawLine(&mColor, x1, y1, x2, y2, &mBlend, true); -} - -bool IKnobRotaterControl::Draw(IGraphics* pGraphics) -{ - int cX = (mRECT.L + mRECT.R) / 2; - int cY = (mRECT.T + mRECT.B) / 2; - double angle = mMinAngle + mValue * (mMaxAngle - mMinAngle); - return pGraphics->DrawRotatedBitmap(&mBitmap, cX, cY, angle, mYOffset, &mBlend); -} - -// Same as IBitmapControl::Draw. -bool IKnobMultiControl::Draw(IGraphics* pGraphics) -{ - int i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1)); - i = BOUNDED(i, 1, mBitmap.N); - return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend); -} - -bool IKnobRotatingMaskControl::Draw(IGraphics* pGraphics) -{ - double angle = mMinAngle + mValue * (mMaxAngle - mMinAngle); - return pGraphics->DrawRotatedMask(&mBase, &mMask, &mTop, mRECT.L, mRECT.T, angle, &mBlend); -} - -bool IBitmapOverlayControl::Draw(IGraphics* pGraphics) -{ - if (mValue < 0.5) { - mTargetRECT = mTargetArea; - return true; // Don't draw anything. - } - else { - mTargetRECT = mRECT; - return IBitmapControl::Draw(pGraphics); - } -} - -void ITextControl::SetTextFromPlug(char* str) -{ - if (strcmp(mStr.Get(), str)) { - SetDirty(false); - mStr.Set(str); - } -} - -bool ITextControl::Draw(IGraphics* pGraphics) -{ - char* cStr = mStr.Get(); - if (CSTR_NOT_EMPTY(cStr)) { - return pGraphics->DrawIText(&mText, cStr, &mRECT); - } - return true; -} - -ICaptionControl::ICaptionControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IText* pText, bool showParamLabel) -: ITextControl(pPlug, pR, pText), mShowParamLabel(showParamLabel) -{ - mParamIdx = paramIdx; -} - -bool ICaptionControl::Draw(IGraphics* pGraphics) -{ - IParam* pParam = mPlug->GetParam(mParamIdx); - char cStr[32]; - pParam->GetDisplayForHost(cStr); - mStr.Set(cStr); - if (mShowParamLabel) { - mStr.Append(" "); - mStr.Append(pParam->GetLabelForHost()); - } - return ITextControl::Draw(pGraphics); -} - -IURLControl::IURLControl(IPlugBase* pPlug, IRECT* pR, const char* url, const char* backupURL, const char* errMsgOnFailure) -: IControl(pPlug, pR) -{ - memset(mURL, 0, MAX_URL_LEN); - memset(mBackupURL, 0, MAX_URL_LEN); - memset(mErrMsg, 0, MAX_NET_ERR_MSG_LEN); - if (CSTR_NOT_EMPTY(url)) { - strcpy(mURL, url); - } - if (CSTR_NOT_EMPTY(backupURL)) { - strcpy(mBackupURL, backupURL); - } - if (CSTR_NOT_EMPTY(errMsgOnFailure)) { - strcpy(mErrMsg, errMsgOnFailure); - } -} - -void IURLControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - bool opened = false; - if (CSTR_NOT_EMPTY(mURL)) { - opened = mPlug->GetGUI()->OpenURL(mURL, mErrMsg); - } - if (!opened && CSTR_NOT_EMPTY(mBackupURL)) { - opened = mPlug->GetGUI()->OpenURL(mBackupURL, mErrMsg); - } -} - -void IFileSelectorControl::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - if (mPlug && mPlug->GetGUI()) { - mState = kFSSelecting; - SetDirty(false); - - mPlug->GetGUI()->PromptForFile(&mFile, mFileAction, mDir.Get(), mExtensions.Get()); - mValue += 1.0; - if (mValue > 1.0) { - mValue = 0.0; - } - mState = kFSDone; - SetDirty(); - } -} - -bool IFileSelectorControl::Draw(IGraphics* pGraphics) -{ - if (mState == kFSSelecting) { - pGraphics->DrawBitmap(&mBitmap, &mRECT, 0, 0); - } - return true; -} - -void IFileSelectorControl::GetLastSelectedFileForPlug(WDL_String* pStr) -{ - pStr->Set(mFile.Get()); -} - -void IFileSelectorControl::SetLastSelectedFileFromPlug(char* file) -{ - mFile.Set(file); -} - -bool IFileSelectorControl::IsDirty() -{ - if (mDirty) { - return true; - } - if (mState == kFSDone) { - mState = kFSNone; - return true; - } - return false; -} diff --git a/WDL/IPlug/IControl.h b/WDL/IPlug/IControl.h deleted file mode 100644 index ef7350a0..00000000 --- a/WDL/IPlug/IControl.h +++ /dev/null @@ -1,402 +0,0 @@ -#ifndef _ICONTROL_ -#define _ICONTROL_ - -#include "IPlugBase.h" -#include "IGraphics.h" - -// A control is anything on the GUI, it could be a static bitmap, or -// something that moves or changes. The control could manipulate -// canned bitmaps or do run-time vector drawing, or whatever. -// -// Some controls respond to mouse actions, either by moving a bitmap, -// transforming a bitmap, or cycling through a set of bitmaps. -// Other controls are readouts only. - -class IControl -{ -public: - - // If paramIdx is > -1, this control will be associated with a plugin parameter. - IControl(IPlugBase* pPlug, IRECT* pR, int paramIdx = -1, IChannelBlend blendMethod = IChannelBlend::kBlendNone) - : mPlug(pPlug), mRECT(*pR), mTargetRECT(*pR), mParamIdx(paramIdx), mValue(0.0), mDefaultValue(-1.0), - mBlend(blendMethod), mDirty(true), mHide(false), mGrayed(false), mDisablePrompt(false), mDblAsSingleClick(false), - mClampLo(0.0), mClampHi(1.0) {} - - virtual ~IControl() {} - - virtual void OnMouseDown(int x, int y, IMouseMod* pMod); - virtual void OnMouseUp(int x, int y, IMouseMod* pMod) {} - virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) {} - virtual void OnMouseDblClick(int x, int y, IMouseMod* pMod); - virtual void OnMouseWheel(int x, int y, IMouseMod* pMod, int d); - virtual void OnKeyDown(int x, int y, int key) {} - - // For efficiency, mouseovers/mouseouts are ignored unless you call IGraphics::HandleMouseOver. - virtual void OnMouseOver(int x, int y, IMouseMod* pMod) {} - virtual void OnMouseOut() {} - - // By default, mouse double click has its own handler. A control can set mDblAsSingleClick to true to change, - // which maps double click to single click for this control (and also causes the mouse to be - // captured by the control on double click). - bool MouseDblAsSingleClick() { return mDblAsSingleClick; } - - virtual bool Draw(IGraphics* pGraphics) = 0; - - // Ask the IGraphics object to open an edit box so the user can enter a value for this control. - void PromptUserInput(); - - int ParamIdx() { return mParamIdx; } - virtual void SetValueFromPlug(double value); - void SetValueFromUserInput(double value); - double GetValue() { return mValue; } - - IRECT* GetRECT() { return &mRECT; } // The draw area for this control. - IRECT* GetTargetRECT() { return &mTargetRECT; } // The mouse target area (default = draw area). - void SetTargetArea(IRECT* pR) { mTargetRECT = *pR; } - - virtual void Hide(bool hide); - bool IsHidden() const { return mHide; } - - virtual void GrayOut(bool gray); - bool IsGrayed() { return mGrayed; } - - // Override if you want the control to be hit only if a visible part of it is hit, or whatever. - virtual bool IsHit(int x, int y) { return mTargetRECT.Contains(x, y); } - - void SetBlendMethod(IChannelBlend::EBlendMethod blendMethod) { mBlend = IChannelBlend(blendMethod); } - - virtual void SetDirty(bool pushParamToPlug = true); - virtual void SetClean(); - virtual bool IsDirty() { return mDirty; } - void Clamp(double lo, double hi) { mClampLo = lo; mClampHi = hi; } - void DisablePrompt(bool disable) { mDisablePrompt = disable; } // Disables the right-click manual value entry. - - // Sometimes a control changes its state as part of its Draw method. - // Redraw() prevents the control from being cleaned immediately after drawing. - void Redraw() { mRedraw = true; } - - // This is an idle call from the GUI thread, as opposed to - // IPlugBase::OnIdle which is called from the audio processing thread. - // Only active if USE_IDLE_CALLS is defined. - virtual void OnGUIIdle() {} - -protected: - - IPlugBase* mPlug; - IRECT mRECT, mTargetRECT; - int mParamIdx; - double mValue, mDefaultValue, mClampLo, mClampHi; - bool mDirty, mHide, mGrayed, mRedraw, mDisablePrompt, mClamped, mDblAsSingleClick; - IChannelBlend mBlend; -}; - -enum EDirection { kVertical, kHorizontal }; - -// Draws a bitmap, or one frame of a stacked bitmap depending on the current value. -class IBitmapControl : public IControl -{ -public: - - IBitmapControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, - IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) - : IControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, blendMethod), mBitmap(*pBitmap) {} - - IBitmapControl(IPlugBase* pPlug, int x, int y, IBitmap* pBitmap, - IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) - : IControl(pPlug, &IRECT(x, y, pBitmap), -1, blendMethod), mBitmap(*pBitmap) {} - - virtual ~IBitmapControl() {} - - virtual bool Draw(IGraphics* pGraphics); - -protected: - IBitmap mBitmap; -}; - -// A switch. Click to cycle through the bitmap states. -class ISwitchControl : public IBitmapControl -{ -public: - - ISwitchControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, - IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) - : IBitmapControl(pPlug, x, y, paramIdx, pBitmap, blendMethod) {} - ~ISwitchControl() {} - - void OnMouseDown(int x, int y, IMouseMod* pMod); -}; - -// On/off switch that has a target area only. -class IInvisibleSwitchControl : public IControl -{ -public: - - IInvisibleSwitchControl(IPlugBase* pPlug, IRECT* pR, int paramIdx); - ~IInvisibleSwitchControl() {} - - void OnMouseDown(int x, int y, IMouseMod* pMod); - - virtual bool Draw(IGraphics* pGraphics) { return true; } -}; - -// A set of buttons that maps to a single selection. Bitmap has 2 states, off and on. -class IRadioButtonsControl : public IControl -{ -public: - - IRadioButtonsControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, int nButtons, IBitmap* pBitmap, - EDirection direction = kVertical); - ~IRadioButtonsControl() {} - - void OnMouseDown(int x, int y, IMouseMod* pMod); - bool Draw(IGraphics* pGraphics); - -protected: - WDL_TypedBuf mRECTs; - IBitmap mBitmap; -}; - -// A switch that reverts to 0.0 when released. -class IContactControl : public ISwitchControl -{ -public: - - IContactControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap) - : ISwitchControl(pPlug, x, y, paramIdx, pBitmap) {} - ~IContactControl() {} - - void OnMouseUp(int x, int y, IMouseMod* pMod); -}; - -// A fader. The bitmap snaps to a mouse click or drag. -class IFaderControl : public IControl -{ -public: - - IFaderControl(IPlugBase* pPlug, int x, int y, int len, int paramIdx, IBitmap* pBitmap, - EDirection direction = kVertical); - ~IFaderControl() {} - - int GetLength() const { return mLen; } - // Size of the handle in pixels. - int GetHandleHeadroom() const { return mHandleHeadroom; } - // Size of the handle in terms of the control value. - double GetHandleValueHeadroom() const { return (double) mHandleHeadroom / (double) mLen; } - // Where is the handle right now? - IRECT GetHandleRECT(double value = -1.0) const; - - virtual void OnMouseDown(int x, int y, IMouseMod* pMod); - virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod); - - virtual bool Draw(IGraphics* pGraphics); - -protected: - void SnapToMouse(int x, int y); - int mLen, mHandleHeadroom; - IBitmap mBitmap; - EDirection mDirection; -}; - -const double DEFAULT_GEARING = 4.0; - -// Parent for knobs, to handle mouse action and ballistics. -class IKnobControl : public IControl -{ -public: - - IKnobControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, EDirection direction = kVertical, - double gearing = DEFAULT_GEARING) - : IControl(pPlug, pR, paramIdx), mDirection(direction), mGearing(gearing) {} - virtual ~IKnobControl() {} - - void SetGearing(double gearing) { mGearing = gearing; } - virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod); - -protected: - EDirection mDirection; - double mGearing; -}; - -// A knob that is just a line. -class IKnobLineControl : public IKnobControl -{ -public: - - IKnobLineControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, - const IColor* pColor, double innerRadius = 0.0, double outerRadius = 0.0, - double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, - EDirection direction = kVertical, double gearing = DEFAULT_GEARING); - ~IKnobLineControl() {} - - bool Draw(IGraphics* pGraphics); - -private: - IColor mColor; - float mMinAngle, mMaxAngle, mInnerRadius, mOuterRadius; -}; - -// A rotating knob. The bitmap rotates with any mouse drag. -class IKnobRotaterControl : public IKnobControl -{ -public: - - IKnobRotaterControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, - double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, int yOffsetZeroDeg = 0, - EDirection direction = kVertical, double gearing = DEFAULT_GEARING) - : IKnobControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, direction, gearing), - mBitmap(*pBitmap), mMinAngle(minAngle), mMaxAngle(maxAngle), mYOffset(yOffsetZeroDeg) {} - ~IKnobRotaterControl() {} - - bool Draw(IGraphics* pGraphics); - -private: - IBitmap mBitmap; - double mMinAngle, mMaxAngle; - int mYOffset; -}; - -// A multibitmap knob. The bitmap cycles through states as the mouse drags. -class IKnobMultiControl : public IKnobControl -{ -public: - - IKnobMultiControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, - EDirection direction = kVertical, double gearing = DEFAULT_GEARING) - : IKnobControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, direction, gearing), mBitmap(*pBitmap) {} - ~IKnobMultiControl() {} - - bool Draw(IGraphics* pGraphics); - -private: - IBitmap mBitmap; -}; - -// A knob that consists of a static base, a rotating mask, and a rotating top. -// The bitmaps are assumed to be symmetrical and identical sizes. -class IKnobRotatingMaskControl : public IKnobControl -{ -public: - - IKnobRotatingMaskControl(IPlugBase* pPlug, int x, int y, int paramIdx, - IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, - double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, - EDirection direction = kVertical, double gearing = DEFAULT_GEARING) - : IKnobControl(pPlug, &IRECT(x, y, pBase), paramIdx, direction, gearing), - mBase(*pBase), mMask(*pMask), mTop(*pTop), mMinAngle(minAngle), mMaxAngle(maxAngle) {} - ~IKnobRotatingMaskControl() {} - - bool Draw(IGraphics* pGraphics); - -private: - IBitmap mBase, mMask, mTop; - double mMinAngle, mMaxAngle; -}; - -// Bitmap shows when value = 0, then toggles its target area to the whole bitmap -// and waits for another click to hide itself. -class IBitmapOverlayControl : public ISwitchControl -{ -public: - - IBitmapOverlayControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, IRECT* pTargetArea) - : ISwitchControl(pPlug, x, y, paramIdx, pBitmap), mTargetArea(*pTargetArea) {} - - IBitmapOverlayControl(IPlugBase* pPlug, int x, int y, IBitmap* pBitmap, IRECT* pTargetArea) - : ISwitchControl(pPlug, x, y, -1, pBitmap), mTargetArea(*pTargetArea) {} - - ~IBitmapOverlayControl() {} - - bool Draw(IGraphics* pGraphics); - -private: - IRECT mTargetArea; // Keep this around to swap in & out. -}; - -// Output text to the screen. -class ITextControl : public IControl -{ -public: - - ITextControl(IPlugBase* pPlug, IRECT* pR, IText* pText, const char* str = "") - : IControl(pPlug, pR), mText(*pText) - { - mStr.Set(str); - } - ~ITextControl() {} - - void SetTextFromPlug(char* str); - void ClearTextFromPlug() { SetTextFromPlug(""); } - - bool Draw(IGraphics* pGraphics); - -protected: - IText mText; - WDL_String mStr; -}; - -// If paramIdx is specified, the text is automatically set to the output -// of Param::GetDisplayForHost(). If showParamLabel = true, Param::GetLabelForHost() is appended. -class ICaptionControl : public ITextControl -{ -public: - - ICaptionControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IText* pText, bool showParamLabel = true); - ~ICaptionControl() {} - - bool Draw(IGraphics* pGraphics); - -protected: - bool mShowParamLabel; -}; - -#define MAX_URL_LEN 256 -#define MAX_NET_ERR_MSG_LEN 1024 - -class IURLControl : public IControl -{ -public: - - IURLControl(IPlugBase* pPlug, IRECT* pR, const char* url, const char* backupURL = 0, const char* errMsgOnFailure = 0); - ~IURLControl() {} - - void OnMouseDown(int x, int y, IMouseMod* pMod); - bool Draw(IGraphics* pGraphics) { return true; } - -protected: - char mURL[MAX_URL_LEN], mBackupURL[MAX_URL_LEN], mErrMsg[MAX_NET_ERR_MSG_LEN]; -}; - -// This is a weird control for a few reasons. -// - Although its numeric mValue is not meaningful, it needs to be associated with a plugin parameter -// so it can inform the plug when the file selection has changed. If the associated plugin parameter is -// declared after kNumParams in the EParams enum, the parameter will be a dummy for this purpose only. -// - Because it puts up a modal window, it needs to redraw itself twice when it's dirty, -// because moving the modal window will clear the first dirty state. -class IFileSelectorControl : public IControl -{ -public: - - enum EFileSelectorState { kFSNone, kFSSelecting, kFSDone }; - - IFileSelectorControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IBitmap* pBitmap, - IGraphics::EFileAction action, char* dir = "", char* extensions = "") // extensions = "txt wav" for example. - : IControl(pPlug, pR, paramIdx), mBitmap(*pBitmap), - mFileAction(action), mDir(dir), mExtensions(extensions), mState(kFSNone) {} - ~IFileSelectorControl() {} - - void OnMouseDown(int x, int y, IMouseMod* pMod); - - void GetLastSelectedFileForPlug(WDL_String* pStr); - void SetLastSelectedFileFromPlug(char* file); - - bool Draw(IGraphics* pGraphics); - bool IsDirty(); - -private: - IBitmap mBitmap; - WDL_String mDir, mFile, mExtensions; - IGraphics::EFileAction mFileAction; - EFileSelectorState mState; -}; - -#endif diff --git a/WDL/IPlug/IGraphics.cpp b/WDL/IPlug/IGraphics.cpp deleted file mode 100644 index d7398760..00000000 --- a/WDL/IPlug/IGraphics.cpp +++ /dev/null @@ -1,446 +0,0 @@ -#include "IGraphics.h" -#include "IControl.h" - -#define DEFAULT_FPS 24 - -// If not dirty for this many timer ticks, we call OnGUIIDle. -// Only looked at if USE_IDLE_CALLS is defined. -#define IDLE_TICKS 20 - -IGraphics::IGraphics(IPlugBase* pPlug, int w, int h, int refreshFPS) -: mPlug(pPlug), mWidth(w), mHeight(h), mIdleTicks(0), - mMouseCapture(-1), mMouseOver(-1), mMouseX(0), mMouseY(0), mHandleMouseOver(false), mStrict(true), mDisplayControlValue(false) -{ - mFPS = (refreshFPS > 0 ? refreshFPS : DEFAULT_FPS); -} - -IGraphics::~IGraphics() -{ - mControls.Empty(true); -} - -void IGraphics::Resize(int w, int h) -{ - // The OS implementation class has to do all the work, then call up to here. - mWidth = w; - mHeight = h; - ReleaseMouseCapture(); - mControls.Empty(true); - mPlug->ResizeGraphics(w, h); -} - -void IGraphics::AttachBackground(int ID, const char* name) -{ - IBitmap bg = LoadIBitmap(ID, name); - IControl* pBG = new IBitmapControl(mPlug, 0, 0, -1, &bg, IChannelBlend::kBlendClobber); - mControls.Insert(0, pBG); -} - -int IGraphics::AttachControl(IControl* pControl) -{ - mControls.Add(pControl); - return mControls.GetSize() - 1; -} - -void IGraphics::HideControl(int paramIdx, bool hide) -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->ParamIdx() == paramIdx) { - pControl->Hide(hide); - } - // Could be more than one, don't break until we check them all. - } -} - -void IGraphics::GrayOutControl(int paramIdx, bool gray) -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->ParamIdx() == paramIdx) { - pControl->GrayOut(gray); - } - // Could be more than one, don't break until we check them all. - } -} - -void IGraphics::ClampControl(int paramIdx, double lo, double hi, bool normalized) -{ - if (!normalized) { - IParam* pParam = mPlug->GetParam(paramIdx); - lo = pParam->GetNormalized(lo); - hi = pParam->GetNormalized(hi); - } - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->ParamIdx() == paramIdx) { - pControl->Clamp(lo, hi); - } - // Could be more than one, don't break until we check them all. - } -} - -void IGraphics::SetParameterFromPlug(int paramIdx, double value, bool normalized) -{ - if (!normalized) { - IParam* pParam = mPlug->GetParam(paramIdx); - value = pParam->GetNormalized(value); - } - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->ParamIdx() == paramIdx) { - //WDL_MutexLock lock(&mMutex); - pControl->SetValueFromPlug(value); - // Could be more than one, don't break until we check them all. - } - } -} - -void IGraphics::SetControlFromPlug(int controlIdx, double normalizedValue) -{ - if (controlIdx >= 0 && controlIdx < mControls.GetSize()) { - //WDL_MutexLock lock(&mMutex); - mControls.Get(controlIdx)->SetValueFromPlug(normalizedValue); - } -} - -void IGraphics::SetAllControlsDirty() -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - pControl->SetDirty(false); - } -} - -void IGraphics::SetParameterFromGUI(int paramIdx, double normalizedValue) -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->ParamIdx() == paramIdx) { - pControl->SetValueFromUserInput(normalizedValue); - // Could be more than one, don't break until we check them all. - } - } -} - -bool IGraphics::DrawBitmap(IBitmap* pBitmap, IRECT* pR, int bmpState, const IChannelBlend* pBlend) -{ - int srcY = 0; - if (pBitmap->N > 1 && bmpState > 1) { - srcY = int(0.5 + (double) pBitmap->H * (double) (bmpState - 1) / (double) pBitmap->N); - } - return DrawBitmap(pBitmap, pR, 0, srcY, pBlend); -} - -bool IGraphics::DrawRect(const IColor* pColor, IRECT* pR) -{ - bool rc = DrawHorizontalLine(pColor, pR->T, pR->L, pR->R); - rc &= DrawHorizontalLine(pColor, pR->B, pR->L, pR->R); - rc &= DrawVerticalLine(pColor, pR->L, pR->T, pR->B); - rc &= DrawVerticalLine(pColor, pR->R, pR->T, pR->B); - return rc; -} - -bool IGraphics::DrawVerticalLine(const IColor* pColor, IRECT* pR, float x) -{ - x = BOUNDED(x, 0.0f, 1.0f); - int xi = pR->L + int(x * (float) (pR->R - pR->L)); - return DrawVerticalLine(pColor, xi, pR->T, pR->B); -} - -bool IGraphics::DrawHorizontalLine(const IColor* pColor, IRECT* pR, float y) -{ - y = BOUNDED(y, 0.0f, 1.0f); - int yi = pR->B - int(y * (float) (pR->B - pR->T)); - return DrawHorizontalLine(pColor, yi, pR->L, pR->R); -} - -bool IGraphics::DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi) -{ - IChannelBlend clobber(IChannelBlend::kBlendClobber); - return DrawLine(pColor, (float) xi, (float) yLo, (float) xi, (float) yHi, &clobber); -} - -bool IGraphics::DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi) -{ - IChannelBlend clobber(IChannelBlend::kBlendClobber); - return DrawLine(pColor, (float) xLo, (float) yi, (float) xHi, (float) yi, &clobber); -} - -bool IGraphics::DrawRadialLine(const IColor* pColor, float cx, float cy, float angle, float rMin, float rMax, - const IChannelBlend* pBlend, bool antiAlias) -{ - float sinV = sin(angle); - float cosV = cos(angle); - float xLo = cx + rMin * sinV; - float xHi = cx + rMax * sinV; - float yLo = cy - rMin * cosV; - float yHi = cy - rMax * cosV; - return DrawLine(pColor, xLo, yLo, xHi, yHi, pBlend, antiAlias); -} - -bool IGraphics::IsDirty(IRECT* pR) -{ - bool dirty = false; - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (pControl->IsDirty()) { - *pR = pR->Union(pControl->GetRECT()); - dirty = true; - } - } - -#ifdef USE_IDLE_CALLS - if (dirty) { - mIdleTicks = 0; - } - else - if (++mIdleTicks > IDLE_TICKS) { - OnGUIIdle(); - mIdleTicks = 0; - } -#endif - - return dirty; -} - -void IGraphics::DisplayControlValue(IControl* pControl) -{ -// char str[32]; -// int paramIdx = pControl->ParamIdx(); -// if (paramIdx >= 0) { -// IParam* pParam = mPlug->GetParam(paramIdx); -// pParam->GetDisplayForHost(str); -// IRECT r = *(pControl->GetRECT()); -// r.L = r.MW() - 10; -// r.R = r.L + 20; -// r.T = r.MH() - 5; -// r.B = r.T + 10; -// DrawIText(&IText(), str, &r); -// } -} - -// The OS is announcing what needs to be redrawn, -// which may be a larger area than what is strictly dirty. -bool IGraphics::Draw(IRECT* pR) -{ -// #pragma REMINDER("Mutex set while drawing") -// WDL_MutexLock lock(&mMutex); - - int i, j, n = mControls.GetSize(); - if (!n) { - return true; - } - - if (mStrict) { - mDrawRECT = *pR; - int n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (int i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - if (!(pControl->IsHidden()) && pR->Intersects(pControl->GetRECT())) { - pControl->Draw(this); -// if (mDisplayControlValue && i == mMouseCapture) { -// DisplayControlValue(pControl); -// } - } - pControl->SetClean(); - } - } - else { - IControl* pBG = mControls.Get(0); - if (pBG->IsDirty()) { // Special case when everything needs to be drawn. - mDrawRECT = *(pBG->GetRECT()); - for (int j = 0; j < n; ++j) { - IControl* pControl2 = mControls.Get(j); - if (!j || !(pControl2->IsHidden())) { - pControl2->Draw(this); - pControl2->SetClean(); - } - } - } - else { - for (i = 1; i < n; ++i) { - IControl* pControl = mControls.Get(i); - if (pControl->IsDirty()) { - mDrawRECT = *(pControl->GetRECT()); - for (j = 0; j < n; ++j) { - IControl* pControl2 = mControls.Get(j); - if ((i == j) || (!(pControl2->IsHidden()) && pControl2->GetRECT()->Intersects(&mDrawRECT))) { - pControl2->Draw(this); - } - } - pControl->SetClean(); - } - } - } - } - - return DrawScreen(pR); - -} - -void IGraphics::SetStrictDrawing(bool strict) -{ - mStrict = strict; - SetAllControlsDirty(); -} - -void IGraphics::OnMouseDown(int x, int y, IMouseMod* pMod) -{ - ReleaseMouseCapture(); - int c = GetMouseControlIdx(x, y); - if (c >= 0) { - mMouseCapture = c; - mMouseX = x; - mMouseY = y; - mDisplayControlValue = (pMod->R); - IControl* pControl = mControls.Get(c); - pControl->OnMouseDown(x, y, pMod); - int paramIdx = pControl->ParamIdx(); - if (paramIdx >= 0) { - mPlug->BeginInformHostOfParamChange(paramIdx); - } - } -} - -void IGraphics::OnMouseUp(int x, int y, IMouseMod* pMod) -{ - int c = GetMouseControlIdx(x, y); - mMouseCapture = mMouseX = mMouseY = -1; - mDisplayControlValue = false; - if (c >= 0) { - IControl* pControl = mControls.Get(c); - pControl->OnMouseUp(x, y, pMod); - int paramIdx = pControl->ParamIdx(); - if (paramIdx >= 0) { - mPlug->EndInformHostOfParamChange(paramIdx); - } - } -} - -bool IGraphics::OnMouseOver(int x, int y, IMouseMod* pMod) -{ - if (mHandleMouseOver) { - int c = GetMouseControlIdx(x, y); - if (c >= 0) { - mMouseX = x; - mMouseY = y; - mControls.Get(c)->OnMouseOver(x, y, pMod); - if (mMouseOver >= 0 && mMouseOver != c) { - mControls.Get(mMouseOver)->OnMouseOut(); - } - mMouseOver = c; - } - } - return mHandleMouseOver; -} - -void IGraphics::OnMouseOut() -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - pControl->OnMouseOut(); - } - mMouseOver = -1; -} - -void IGraphics::OnMouseDrag(int x, int y, IMouseMod* pMod) -{ - int c = mMouseCapture; - if (c >= 0) { - int dX = x - mMouseX; - int dY = y - mMouseY; - if (dX != 0 || dY != 0) { - mMouseX = x; - mMouseY = y; - mControls.Get(c)->OnMouseDrag(x, y, dX, dY, pMod); - } - } -} - -bool IGraphics::OnMouseDblClick(int x, int y, IMouseMod* pMod) -{ - ReleaseMouseCapture(); - bool newCapture = false; - int c = GetMouseControlIdx(x, y); - if (c >= 0) { - IControl* pControl = mControls.Get(c); - if (pControl->MouseDblAsSingleClick()) { - mMouseCapture = c; - mMouseX = x; - mMouseY = y; - pControl->OnMouseDown(x, y, pMod); - newCapture = true; - } - else { - pControl->OnMouseDblClick(x, y, pMod); - } - } - return newCapture; -} - -void IGraphics::OnMouseWheel(int x, int y, IMouseMod* pMod, int d) -{ - int c = GetMouseControlIdx(x, y); - if (c >= 0) { - mControls.Get(c)->OnMouseWheel(x, y, pMod, d); - } -} - -void IGraphics::ReleaseMouseCapture() -{ - mMouseCapture = mMouseX = mMouseY = -1; -} - -void IGraphics::OnKeyDown(int x, int y, int key) -{ - int c = GetMouseControlIdx(x, y); - if (c >= 0) { - mControls.Get(c)->OnKeyDown(x, y, key); - } -} - -int IGraphics::GetMouseControlIdx(int x, int y) -{ - if (mMouseCapture >= 0) { - return mMouseCapture; - } - // The BG is a control and will catch everything, so assume the programmer - // attached the controls from back to front, and return the frontmost match. - int i = mControls.GetSize() - 1; - IControl** ppControl = mControls.GetList() + i; - for (/* */; i >= 0; --i, --ppControl) { - IControl* pControl = *ppControl; - if (!pControl->IsHidden() && !pControl->IsGrayed() && pControl->IsHit(x, y)) { - return i; - } - } - return -1; -} - -void IGraphics::OnGUIIdle() -{ - int i, n = mControls.GetSize(); - IControl** ppControl = mControls.GetList(); - for (i = 0; i < n; ++i, ++ppControl) { - IControl* pControl = *ppControl; - pControl->OnGUIIdle(); - } -} diff --git a/WDL/IPlug/IGraphics.h b/WDL/IPlug/IGraphics.h deleted file mode 100644 index 6b915620..00000000 --- a/WDL/IPlug/IGraphics.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef _IGRAPHICS_ -#define _IGRAPHICS_ - -#include "IPlugStructs.h" - -class IPlugBase; -class IControl; -class IParam; - -class IGraphics -{ -public: - - virtual void PrepDraw() = 0; // Called once, when the IGraphics class is attached to the IPlug class. - bool IsDirty(IRECT* pR); // Ask the plugin what needs to be redrawn. - bool Draw(IRECT* pR); // The system announces what needs to be redrawn. Ordering and drawing logic. - virtual bool DrawScreen(IRECT* pR) = 0; // Tells the OS class to put the final bitmap on the screen. - - // Methods for the drawing implementation class. - virtual bool DrawBitmap(IBitmap* pBitmap, IRECT* pDest, int srcX, int srcY, - const IChannelBlend* pBlend = 0) = 0; - virtual bool DrawRotatedBitmap(IBitmap* pBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg = 0, - const IChannelBlend* pBlend = 0) = 0; - virtual bool DrawRotatedMask(IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, int x, int y, double angle, - const IChannelBlend* pBlend = 0) = 0; - virtual bool DrawPoint(const IColor* pColor, float x, float y, - const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; - // Live ammo! Will crash if out of bounds! etc. - virtual bool ForcePixel(const IColor* pColor, int x, int y) = 0; - virtual bool DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, - const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; - virtual bool DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, - const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; - virtual bool DrawCircle(const IColor* pColor, float cx, float cy, float r, - const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; - virtual bool FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend = 0) = 0; - virtual bool DrawIText(IText* pTxt, char* str, IRECT* pR) = 0; - virtual IColor GetPoint(int x, int y) = 0; - virtual void* GetData() = 0; - - // Methods for the OS implementation class. - virtual void Resize(int w, int h); - virtual bool WindowIsOpen() { return (GetWindow()); } - virtual void PromptUserInput(IControl* pControl, IParam* pParam) = 0; - virtual void HostPath(WDL_String* pPath) = 0; // Full path to host executable. - virtual void PluginPath(WDL_String* pPath) = 0; // Full path to plugin dll. - // Run the "open file" or "save file" dialog. Default to host executable path. - enum EFileAction { kFileOpen, kFileSave }; - virtual void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = 0, - char* extensions = 0) = 0; // extensions = "txt wav" for example. - virtual bool PromptForColor(IColor* pColor, char* prompt = 0) = 0; - - virtual bool OpenURL(const char* url, - const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0) = 0; - - // Strict (default): draw everything within the smallest rectangle that contains everything dirty. - // Every control is guaranteed to get no more than one Draw() call per cycle. - // Fast: draw only controls that intersect something dirty. - // If there are overlapping controls, fast drawing can generate multiple Draw() calls per cycle - // (a control may be asked to draw multiple parts of itself, if it intersects with something dirty.) - void SetStrictDrawing(bool strict); - - virtual void* OpenWindow(void* pParentWnd) = 0; - virtual void* OpenWindow(void* pParentWnd, void* pParentControl) { return 0; } // For OSX Carbon hosts ... ugh. - virtual void CloseWindow() = 0; - virtual void* GetWindow() = 0; - - //////////////////////////////////////// - - IGraphics(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); - virtual ~IGraphics(); - - int Width() { return mWidth; } - int Height() { return mHeight; } - int FPS() { return mFPS; } - - IPlugBase* GetPlug() { return mPlug; } - - virtual IBitmap LoadIBitmap(int ID, const char* name, int nStates = 1) = 0; - virtual IBitmap ScaleBitmap(IBitmap* pSrcBitmap, int destW, int destH) = 0; - virtual IBitmap CropBitmap(IBitmap* pSrcBitmap, IRECT* pR) = 0; - virtual void AttachBackground(int ID, const char* name); - // Returns the control index of this control (not the number of controls). - int AttachControl(IControl* pControl); - - IControl* GetControl(int idx) { return mControls.Get(idx); } - void HideControl(int paramIdx, bool hide); - void GrayOutControl(int paramIdx, bool gray); - - // Normalized means the value is in [0, 1]. - void ClampControl(int paramIdx, double lo, double hi, bool normalized); - void SetParameterFromPlug(int paramIdx, double value, bool normalized); - // For setting a control that does not have a parameter associated with it. - void SetControlFromPlug(int controlIdx, double normalizedValue); - - void SetAllControlsDirty(); - - // This is for when the gui needs to change a control value that it can't redraw - // for context reasons. If the gui has redrawn the control, use IPlug::SetParameterFromGUI. - void SetParameterFromGUI(int paramIdx, double normalizedValue); - - // Convenience wrappers. - bool DrawBitmap(IBitmap* pBitmap, IRECT* pR, int bmpState = 1, const IChannelBlend* pBlend = 0); - bool DrawRect(const IColor* pColor, IRECT* pR); - bool DrawVerticalLine(const IColor* pColor, IRECT* pR, float x); - bool DrawHorizontalLine(const IColor* pColor, IRECT* pR, float y); - virtual bool DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi); - virtual bool DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi); - bool DrawRadialLine(const IColor* pColor, float cx, float cy, float angle, float rMin, float rMax, - const IChannelBlend* pBlend = 0, bool antiAlias = false); - - void OnMouseDown(int x, int y, IMouseMod* pMod); - void OnMouseUp(int x, int y, IMouseMod* pMod); - void OnMouseDrag(int x, int y, IMouseMod* pMod); - // Returns true if the control receiving the double click will treat it as a single click - // (meaning the OS should capture the mouse). - bool OnMouseDblClick(int x, int y, IMouseMod* pMod); - void OnMouseWheel(int x, int y, IMouseMod* pMod, int d); - void OnKeyDown(int x, int y, int key); - - void DisplayControlValue(IControl* pControl); - - // For efficiency, mouseovers/mouseouts are ignored unless you explicity say you can handle them. - void HandleMouseOver(bool canHandle) { mHandleMouseOver = canHandle; } - bool OnMouseOver(int x, int y, IMouseMod* pMod); // Returns true if mouseovers are handled. - void OnMouseOut(); - // Some controls may not need to capture the mouse for dragging, they can call ReleaseCapture when the mouse leaves. - void ReleaseMouseCapture(); - - // This is an idle call from the GUI thread, as opposed to - // IPlug::OnIdle which is called from the audio processing thread. - void OnGUIIdle(); - - virtual void RetainBitmap(IBitmap* pBitmap) = 0; - virtual void ReleaseBitmap(IBitmap* pBitmap) = 0; - - WDL_Mutex mMutex; - - struct IMutexLock - { - WDL_Mutex* mpMutex; - IMutexLock(IGraphics* pGraphics) : mpMutex(&(pGraphics->mMutex)) { mpMutex->Enter(); } - ~IMutexLock() { mpMutex->Leave(); } - }; - -protected: - - WDL_PtrList mControls; - IPlugBase* mPlug; - IRECT mDrawRECT; - - bool CanHandleMouseOver() { return mHandleMouseOver; } - -private: - - int mWidth, mHeight, mFPS, mIdleTicks; - int GetMouseControlIdx(int x, int y); - int mMouseCapture, mMouseOver, mMouseX, mMouseY; - bool mHandleMouseOver, mStrict, mDisplayControlValue; -}; - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsCarbon.cpp b/WDL/IPlug/IGraphicsCarbon.cpp deleted file mode 100644 index f9d64fd4..00000000 --- a/WDL/IPlug/IGraphicsCarbon.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "IGraphicsCarbon.h" - -IRECT GetRegionRect(EventRef pEvent, int gfxW, int gfxH) -{ - RgnHandle pRgn = 0; - if (GetEventParameter(pEvent, kEventParamRgnHandle, typeQDRgnHandle, 0, sizeof(RgnHandle), 0, &pRgn) == noErr && pRgn) { - Rect rct; - GetRegionBounds(pRgn, &rct); - return IRECT(rct.left, rct.top, rct.right, rct.bottom); - } - return IRECT(0, 0, gfxW, gfxH); -} - -IRECT GetControlRect(EventRef pEvent, int gfxW, int gfxH) -{ - Rect rct; - if (GetEventParameter(pEvent, kEventParamCurrentBounds, typeQDRectangle, 0, sizeof(Rect), 0, &rct) == noErr) { - int w = rct.right - rct.left; - int h = rct.bottom - rct.top; - if (w > 0 && h > 0) { - return IRECT(0, 0, w, h); - } - } - return IRECT(0, 0, gfxW, gfxH); -} - -// static -pascal OSStatus IGraphicsCarbon::CarbonEventHandler(EventHandlerCallRef pHandlerCall, EventRef pEvent, void* pGraphicsCarbon) -{ - IGraphicsCarbon* _this = (IGraphicsCarbon*) pGraphicsCarbon; - IGraphicsMac* pGraphicsMac = _this->mGraphicsMac; - UInt32 eventClass = GetEventClass(pEvent); - UInt32 eventKind = GetEventKind(pEvent); - switch (eventClass) { - case kEventClassControl: { - switch (eventKind) { - case kEventControlDraw: { - - int gfxW = pGraphicsMac->Width(), gfxH = pGraphicsMac->Height(); - IRECT r = GetRegionRect(pEvent, gfxW, gfxH); - - CGrafPtr port = 0; - if (_this->mIsComposited) { - GetEventParameter(pEvent, kEventParamCGContextRef, typeCGContextRef, 0, sizeof(CGContextRef), 0, &(_this->mCGC)); - CGContextTranslateCTM(_this->mCGC, 0, gfxH); - CGContextScaleCTM(_this->mCGC, 1.0, -1.0); - pGraphicsMac->Draw(&r); - } - else { - #pragma REMINDER("not swapping gfx ports in non-composited mode") - - int ctlH = r.H(); - _this->mContentYOffset = ctlH - gfxH; - - //Rect rct; - //GetWindowBounds(_this->mWindow, kWindowContentRgn, &rct); - //int wndH = rct.bottom - rct.top; - //if (wndH > gfxH) { - // int yOffs = wndH - gfxH; - // _this->mContentYOffset = yOffs; - // } - - GetEventParameter(pEvent, kEventParamGrafPort, typeGrafPtr, 0, sizeof(CGrafPtr), 0, &port); - QDBeginCGContext(port, &(_this->mCGC)); - // Old-style controls drawing, ask the plugin what's dirty rather than relying on the OS. - r.R = r.T = r.R = r.B = 0; - _this->mGraphicsMac->IsDirty(&r); - } - - pGraphicsMac->Draw(&r); - - if (port) { - CGContextFlush(_this->mCGC); - QDEndCGContext(port, &(_this->mCGC)); - } - - return noErr; - } - case kEventControlBoundsChanged: { - int gfxW = pGraphicsMac->Width(), gfxH = pGraphicsMac->Height(); - IRECT r = GetControlRect(pEvent, gfxW, gfxH); - //pGraphicsMac->GetPlug()->UserResizedWindow(&r); - return noErr; - } - case kEventControlDispose: { - // kComponentCloseSelect call should already have done this for us (and deleted mGraphicsMac, for that matter). - // pGraphicsMac->CloseWindow(); - return noErr; - } - } - break; - } - case kEventClassMouse: { - HIPoint hp; - GetEventParameter(pEvent, kEventParamWindowMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hp); - HIPointConvert(&hp, kHICoordSpaceWindow, _this->mWindow, kHICoordSpaceView, _this->mView); - int x = (int) hp.x; - int y = (int) hp.y; - - UInt32 mods; - GetEventParameter(pEvent, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &mods); - IMouseMod mmod(true, (mods & cmdKey), (mods & shiftKey), (mods & controlKey), (mods & optionKey)); - - switch (eventKind) { - case kEventMouseDown: { - CallNextEventHandler(pHandlerCall, pEvent); // Activates the window, if inactive. - - UInt32 clickCount = 0; - GetEventParameter(pEvent, kEventParamClickCount, typeUInt32, 0, sizeof(UInt32), 0, &clickCount); - if (clickCount > 1) { - pGraphicsMac->OnMouseDblClick(x, y, &mmod); - } - else { - pGraphicsMac->OnMouseDown(x, y, &mmod); - } - return noErr; - } - case kEventMouseUp: { - pGraphicsMac->OnMouseUp(x, y, &mmod); - return noErr; - } - case kEventMouseMoved: { - pGraphicsMac->OnMouseOver(x, y, &mmod); - return noErr; - } - case kEventMouseDragged: { - pGraphicsMac->OnMouseDrag(x, y, &mmod); - return noErr; - } - case kEventMouseWheelMoved: { - EventMouseWheelAxis axis; - GetEventParameter(pEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0, sizeof(EventMouseWheelAxis), 0, &axis); - if (axis == kEventMouseWheelAxisY) { - int d; - GetEventParameter(pEvent, kEventParamMouseWheelDelta, typeSInt32, 0, sizeof(SInt32), 0, &d); - pGraphicsMac->OnMouseWheel(x, y, &mmod, d); - return noErr; - } - } - } - break; - } - } - return eventNotHandledErr; -} - -// static -pascal void IGraphicsCarbon::CarbonTimerHandler(EventLoopTimerRef pTimer, void* pGraphicsCarbon) -{ - IGraphicsCarbon* _this = (IGraphicsCarbon*) pGraphicsCarbon; - IRECT r; - if (_this->mGraphicsMac->IsDirty(&r)) { - if (_this->mIsComposited) { - HIViewSetNeedsDisplayInRect(_this->mView, &CGRectMake(r.L, r.T, r.W(), r.H()), true); - } - else { - int h = _this->mGraphicsMac->Height(); - SetRectRgn(_this->mRgn, r.L, h - r.B, r.R, h - r.T); - UpdateControls(_this->mWindow, 0);// _this->mRgn); - } - } -} - -void ResizeWindow(WindowRef pWindow, int w, int h) -{ - Rect gr; // Screen. - GetWindowBounds(pWindow, kWindowContentRgn, &gr); - gr.right = gr.left + w; - gr.bottom = gr.top + h; - SetWindowBounds(pWindow, kWindowContentRgn, &gr); -} - -IGraphicsCarbon::IGraphicsCarbon(IGraphicsMac* pGraphicsMac, WindowRef pWindow, ControlRef pParentControl) -: mGraphicsMac(pGraphicsMac), mWindow(pWindow), mView(0), mTimer(0), mControlHandler(0), mWindowHandler(0), mCGC(0), - mContentXOffset(0), mContentYOffset(0) -{ - TRACE; - - Rect r; // Client. - r.left = r.top = 0; - r.right = pGraphicsMac->Width(); - r.bottom = pGraphicsMac->Height(); - //ResizeWindow(pWindow, r.right, r.bottom); - - WindowAttributes winAttrs = 0; - GetWindowAttributes(pWindow, &winAttrs); - mIsComposited = (winAttrs & kWindowCompositingAttribute); - mRgn = NewRgn(); - - UInt32 features = kControlSupportsFocus | kControlHandlesTracking | kControlSupportsEmbedding; - if (mIsComposited) { - features |= kHIViewIsOpaque | kHIViewFeatureDoesNotUseSpecialParts; - } - CreateUserPaneControl(pWindow, &r, features, &mView); - - const EventTypeSpec controlEvents[] = { - //{ kEventClassControl, kEventControlInitialize }, - //{kEventClassControl, kEventControlGetOptimalBounds}, - //{ kEventClassControl, kEventControlHitTest }, - { kEventClassControl, kEventControlClick }, - //{ kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassControl, kEventControlDraw }, - { kEventClassControl, kEventControlDispose }, - { kEventClassControl, kEventControlBoundsChanged } - }; - InstallControlEventHandler(mView, CarbonEventHandler, GetEventTypeCount(controlEvents), controlEvents, this, &mControlHandler); - - const EventTypeSpec windowEvents[] = { - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved } - }; - InstallWindowEventHandler(mWindow, CarbonEventHandler, GetEventTypeCount(windowEvents), windowEvents, this, &mWindowHandler); - - double t = 2.0*kEventDurationSecond/(double)pGraphicsMac->FPS(); - OSStatus s = InstallEventLoopTimer(GetMainEventLoop(), 0.0, t, CarbonTimerHandler, this, &mTimer); - - if (mIsComposited) { - if (!pParentControl) { - HIViewRef hvRoot = HIViewGetRoot(pWindow); - s = HIViewFindByID(hvRoot, kHIViewWindowContentID, &pParentControl); - } - s = HIViewAddSubview(pParentControl, mView); - } - else { - if (!pParentControl) { - if (GetRootControl(pWindow, &pParentControl) != noErr) { - CreateRootControl(pWindow, &pParentControl); - } - } - s = EmbedControl(mView, pParentControl); - } - - if (s == noErr) { - SizeControl(mView, r.right, r.bottom); // offset? - } -} - -IGraphicsCarbon::~IGraphicsCarbon() -{ - // Called from IGraphicsMac::CloseWindow. - RemoveEventLoopTimer(mTimer); - RemoveEventHandler(mControlHandler); - RemoveEventHandler(mWindowHandler); - mTimer = 0; - mView = 0; - DisposeRgn(mRgn); -} - -void IGraphicsCarbon::OffsetContentRect(CGRect* pR) -{ - *pR = CGRectOffset(*pR, (float) mContentXOffset, (float) mContentYOffset); -} - -bool IGraphicsCarbon::Resize(int w, int h) -{ - if (mWindow && mView) { - ResizeWindow(mWindow, w, h); - return (HIViewSetFrame(mView, &CGRectMake(0, 0, w, h)) == noErr); - } - return false; -} diff --git a/WDL/IPlug/IGraphicsCarbon.h b/WDL/IPlug/IGraphicsCarbon.h deleted file mode 100644 index 25a4850d..00000000 --- a/WDL/IPlug/IGraphicsCarbon.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _IGRAPHICSCARBON_ -#define _IGRAPHICSCARBON_ - -#include -#include "IGraphicsMac.h" - -class IGraphicsCarbon -{ -public: - - IGraphicsCarbon(IGraphicsMac* pGraphicsMac, WindowRef pWindow, ControlRef pParentControl); - ~IGraphicsCarbon(); - - ControlRef GetView() { return mView; } - CGContextRef GetCGContext() { return mCGC; } - void OffsetContentRect(CGRect* pR); - bool Resize(int w, int h); - -private: - - IGraphicsMac* mGraphicsMac; - bool mIsComposited; - int mContentXOffset, mContentYOffset; - RgnHandle mRgn; - WindowRef mWindow; - ControlRef mView; // was HIViewRef - EventLoopTimerRef mTimer; - EventHandlerRef mControlHandler, mWindowHandler; - CGContextRef mCGC; - -public: - - static pascal OSStatus CarbonEventHandler(EventHandlerCallRef pHandlerCall, EventRef pEvent, void* pGraphicsCarbon); - static pascal void CarbonTimerHandler(EventLoopTimerRef pTimer, void* pGraphicsCarbon); -}; - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsCocoa.h b/WDL/IPlug/IGraphicsCocoa.h deleted file mode 100644 index 06cda044..00000000 --- a/WDL/IPlug/IGraphicsCocoa.h +++ /dev/null @@ -1,40 +0,0 @@ -#import -#include -#include -#import -#include "IGraphicsMac.h" - -// Cocoa objects can be supplied by any existing component, -// so we need to make sure the C++ static lib code gets the -// IGraphicsCocoa that it expects. -#define IGRAPHICS_COCOA IGraphicsCocoa_v1002 - -NSString* ToNSString(const char* cStr); - -inline CGRect ToCGRect(int h, IRECT* pR) -{ - int B = h - pR->B; - return CGRectMake(pR->L, B, pR->W(), B + pR->H()); -} - -@interface IGRAPHICS_COCOA : NSView -{ - IGraphicsMac* mGraphics; - NSTimer* mTimer; -} -- (id) init; -- (id) initWithIGraphics: (IGraphicsMac*) pGraphics; -- (BOOL) isOpaque; -- (BOOL) acceptsFirstResponder; -- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent; -- (void) viewDidMoveToWindow; -- (void) drawRect: (NSRect) rect; -- (void) onTimer: (NSTimer*) pTimer; -- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY; -- (void) mouseDown: (NSEvent*) pEvent; -- (void) mouseUp: (NSEvent*) pEvent; -- (void) mouseDragged: (NSEvent*) pEvent; -- (void) mouseMoved: (NSEvent*) pEvent; -- (void) scrollWheel: (NSEvent*) pEvent; -- (void) killTimer; -@end diff --git a/WDL/IPlug/IGraphicsCocoa.mm b/WDL/IPlug/IGraphicsCocoa.mm deleted file mode 100644 index 2aa138d6..00000000 --- a/WDL/IPlug/IGraphicsCocoa.mm +++ /dev/null @@ -1,156 +0,0 @@ -#include "IGraphicsCocoa.h" - -inline NSRect ToNSRect(IGraphics* pGraphics, IRECT* pR) -{ - int B = pGraphics->Height() - pR->B; - return NSMakeRect(pR->L, B, pR->W(), pR->H()); -} - -inline IRECT ToIRECT(IGraphics* pGraphics, NSRect* pR) -{ - int x = pR->origin.x, y = pR->origin.y, w = pR->size.width, h = pR->size.height, gh = pGraphics->Height(); - return IRECT(x, gh - (y + h), x + w, gh - y); -} - -NSString* ToNSString(const char* cStr) -{ - return [NSString stringWithCString:cStr]; -} - -inline IMouseMod GetMouseMod(NSEvent* pEvent) -{ - int mods = [pEvent modifierFlags]; - return IMouseMod(true, (mods & NSRightMouseDownMask) || (mods & NSCommandKeyMask), (mods & NSShiftKeyMask), (mods & NSControlKeyMask), (mods & NSAlternateKeyMask)); -} - -@implementation IGRAPHICS_COCOA - -- (id) init -{ - TRACE; - - mGraphics = 0; - mTimer = 0; - return self; -} - -- (id) initWithIGraphics: (IGraphicsMac*) pGraphics -{ - TRACE; - - mGraphics = pGraphics; - NSRect r; - r.origin.x = r.origin.y = 0.0f; - r.size.width = (float) pGraphics->Width(); - r.size.height = (float) pGraphics->Height(); - self = [super initWithFrame:r]; - - double sec = 1.0 / (double) pGraphics->FPS(); - mTimer = [NSTimer timerWithTimeInterval:sec target:self selector:@selector(onTimer:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer: mTimer forMode: (NSString*) kCFRunLoopCommonModes]; - - return self; -} - -- (BOOL) isOpaque -{ - return YES; -} - -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent -{ - return YES; -} - -- (void) viewDidMoveToWindow -{ - NSWindow* pWindow = [self window]; - if (pWindow) { - [pWindow makeFirstResponder: self]; - [pWindow setAcceptsMouseMovedEvents: YES]; - } -} - -- (void) drawRect: (NSRect) rect -{ - mGraphics->Draw(&ToIRECT(mGraphics, &rect)); -} - -- (void) onTimer: (NSTimer*) pTimer -{ - IRECT r; - if (pTimer == mTimer && mGraphics && mGraphics->IsDirty(&r)) { - [self setNeedsDisplayInRect:ToNSRect(mGraphics, &r)]; - } -} - -- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY -{ - NSPoint pt = [self convertPoint:[pEvent locationInWindow] fromView:nil]; - *pX = (int) pt.x; - *pY = mGraphics->Height() - (int) pt.y; -} - -- (void) mouseDown: (NSEvent*) pEvent -{ - int x, y; - [self getMouseXY:pEvent x:&x y:&y]; - if ([pEvent clickCount] > 1) { - mGraphics->OnMouseDblClick(x, y, &GetMouseMod(pEvent)); - } - else { - mGraphics->OnMouseDown(x, y, &GetMouseMod(pEvent)); - } -} - -- (void) mouseUp: (NSEvent*) pEvent -{ - int x, y; - [self getMouseXY:pEvent x:&x y:&y]; - mGraphics->OnMouseUp(x, y, &GetMouseMod(pEvent)); -} - -- (void) mouseDragged: (NSEvent*) pEvent -{ - int x, y; - [self getMouseXY:pEvent x:&x y:&y]; - mGraphics->OnMouseDrag(x, y, &GetMouseMod(pEvent)); -} - -- (void) mouseMoved: (NSEvent*) pEvent -{ - int x, y; - [self getMouseXY:pEvent x:&x y:&y]; - mGraphics->OnMouseOver(x, y, &GetMouseMod(pEvent)); -} - -- (void) scrollWheel: (NSEvent*) pEvent -{ - int x, y; - [self getMouseXY:pEvent x:&x y:&y]; - int d = [pEvent deltaY]; - mGraphics->OnMouseWheel(x, y, &GetMouseMod(pEvent), d); -} - -- (void) killTimer -{ - [mTimer invalidate]; - mTimer = 0; -} - -- (void) removeFromSuperview -{ - if (mGraphics) - { - IGraphics* graphics = mGraphics; - mGraphics = 0; - graphics->CloseWindow(); - } -} - -@end diff --git a/WDL/IPlug/IGraphicsLice.cpp b/WDL/IPlug/IGraphicsLice.cpp deleted file mode 100644 index ead35474..00000000 --- a/WDL/IPlug/IGraphicsLice.cpp +++ /dev/null @@ -1,295 +0,0 @@ -#include "IGraphicsLice.h" -#include "IControl.h" -#include "math.h" -#include "Log.h" - -extern HINSTANCE gHInstance; - -class BitmapStorage -{ -public: - - struct BitmapKey - { - int id; - LICE_IBitmap* bitmap; - }; - - WDL_PtrList m_bitmaps; - WDL_Mutex m_mutex; - - LICE_IBitmap* Find(int id) - { - WDL_MutexLock lock(&m_mutex); - int i, n = m_bitmaps.GetSize(); - for (i = 0; i < n; ++i) - { - BitmapKey* key = m_bitmaps.Get(i); - if (key->id == id) return key->bitmap; - } - return 0; - } - - void Add(LICE_IBitmap* bitmap, int id = -1) - { - WDL_MutexLock lock(&m_mutex); - BitmapKey* key = m_bitmaps.Add(new BitmapKey); - key->id = id; - key->bitmap = bitmap; - } - - void Remove(LICE_IBitmap* bitmap) - { - WDL_MutexLock lock(&m_mutex); - int i, n = m_bitmaps.GetSize(); - for (i = 0; i < n; ++i) - { - if (m_bitmaps.Get(i)->bitmap == bitmap) - { - m_bitmaps.Delete(i, true); - delete(bitmap); - break; - } - } - } - - ~BitmapStorage() - { - int i, n = m_bitmaps.GetSize(); - for (i = 0; i < n; ++i) - { - delete(m_bitmaps.Get(i)->bitmap); - } - m_bitmaps.Empty(true); - } -}; - -static BitmapStorage s_bitmapCache; - -inline LICE_pixel LiceColor(const IColor* pColor) -{ - return LICE_RGBA(pColor->R, pColor->G, pColor->B, pColor->A); -} - -inline float LiceWeight(const IChannelBlend* pBlend) -{ - return (pBlend ? pBlend->mWeight : 1.0f); -} - -inline int LiceBlendMode(const IChannelBlend* pBlend) -{ - if (!pBlend) { - return LICE_BLIT_MODE_COPY | LICE_BLIT_USE_ALPHA; - } - switch (pBlend->mMethod) { - case IChannelBlend::kBlendClobber: { - return LICE_BLIT_MODE_COPY; - } - case IChannelBlend::kBlendAdd: { - return LICE_BLIT_MODE_ADD | LICE_BLIT_USE_ALPHA; - } - case IChannelBlend::kBlendColorDodge: { - return LICE_BLIT_MODE_DODGE | LICE_BLIT_USE_ALPHA; - } - case IChannelBlend::kBlendNone: - default: { - return LICE_BLIT_MODE_COPY | LICE_BLIT_USE_ALPHA; - } - } -} - -IGraphicsLice::IGraphicsLice(IPlugBase* pPlug, int w, int h, int refreshFPS) -: IGraphics(pPlug, w, h, refreshFPS), mDrawBitmap(0), mTmpBitmap(0) -{} - -IGraphicsLice::~IGraphicsLice() -{ - DELETE_NULL(mDrawBitmap); - DELETE_NULL(mTmpBitmap); -} - -IBitmap IGraphicsLice::LoadIBitmap(int ID, const char* name, int nStates) -{ - LICE_IBitmap* lb = s_bitmapCache.Find(ID); - if (!lb) - { - lb = OSLoadBitmap(ID, name); - bool imgResourceFound = (lb); - assert(imgResourceFound); // Protect against typos in resource.h and .rc files. - s_bitmapCache.Add(lb, ID); - } - return IBitmap(lb, lb->getWidth(), lb->getHeight(), nStates); -} - -void IGraphicsLice::RetainBitmap(IBitmap* pBitmap) -{ - s_bitmapCache.Add((LICE_IBitmap*)pBitmap->mData); -} - -void IGraphicsLice::ReleaseBitmap(IBitmap* pBitmap) -{ - s_bitmapCache.Remove((LICE_IBitmap*)pBitmap->mData); -} - -void IGraphicsLice::PrepDraw() -{ - mDrawBitmap = new LICE_SysBitmap(Width(), Height()); - mTmpBitmap = new LICE_MemBitmap(); -} - -bool IGraphicsLice::DrawBitmap(IBitmap* pIBitmap, IRECT* pDest, int srcX, int srcY, const IChannelBlend* pBlend) -{ - LICE_IBitmap* pLB = (LICE_IBitmap*) pIBitmap->mData; - IRECT r = pDest->Intersect(&mDrawRECT); - srcX += r.L - pDest->L; - srcY += r.T - pDest->T; - _LICE::LICE_Blit(mDrawBitmap, pLB, r.L, r.T, srcX, srcY, r.W(), r.H(), LiceWeight(pBlend), LiceBlendMode(pBlend)); - return true; -} - -bool IGraphicsLice::DrawRotatedBitmap(IBitmap* pIBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg, - const IChannelBlend* pBlend) -{ - LICE_IBitmap* pLB = (LICE_IBitmap*) pIBitmap->mData; - - //double dA = angle * PI / 180.0; - // Can't figure out what LICE_RotatedBlit is doing for irregular bitmaps exactly. - //double w = (double) bitmap.W; - //double h = (double) bitmap.H; - //double sinA = fabs(sin(dA)); - //double cosA = fabs(cos(dA)); - //int W = int(h * sinA + w * cosA); - //int H = int(h * cosA + w * sinA); - - int W = pIBitmap->W; - int H = pIBitmap->H; - int destX = destCtrX - W / 2; - int destY = destCtrY - H / 2; - - _LICE::LICE_RotatedBlit(mDrawBitmap, pLB, destX, destY, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) angle, - false, LiceWeight(pBlend), LiceBlendMode(pBlend) | LICE_BLIT_FILTER_BILINEAR, 0.0f, (float) yOffsetZeroDeg); - - return true; -} - -bool IGraphicsLice::DrawRotatedMask(IBitmap* pIBase, IBitmap* pIMask, IBitmap* pITop, int x, int y, double angle, - const IChannelBlend* pBlend) -{ - LICE_IBitmap* pBase = (LICE_IBitmap*) pIBase->mData; - LICE_IBitmap* pMask = (LICE_IBitmap*) pIMask->mData; - LICE_IBitmap* pTop = (LICE_IBitmap*) pITop->mData; - - double dA = angle * PI / 180.0; - int W = pIBase->W; - int H = pIBase->H; -// RECT srcR = { 0, 0, W, H }; - float xOffs = (W % 2 ? -0.5f : 0.0f); - - if (!mTmpBitmap) { - mTmpBitmap = new LICE_MemBitmap(); - } - _LICE::LICE_Copy(mTmpBitmap, pBase); - _LICE::LICE_ClearRect(mTmpBitmap, 0, 0, W, H, LICE_RGBA(255, 255, 255, 0)); - - _LICE::LICE_RotatedBlit(mTmpBitmap, pMask, 0, 0, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) dA, - true, 1.0f, LICE_BLIT_MODE_ADD | LICE_BLIT_FILTER_BILINEAR | LICE_BLIT_USE_ALPHA, xOffs, 0.0f); - _LICE::LICE_RotatedBlit(mTmpBitmap, pTop, 0, 0, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) dA, - true, 1.0f, LICE_BLIT_MODE_COPY | LICE_BLIT_FILTER_BILINEAR | LICE_BLIT_USE_ALPHA, xOffs, 0.0f); - - IRECT r = IRECT(x, y, x + W, y + H).Intersect(&mDrawRECT); - _LICE::LICE_Blit(mDrawBitmap, mTmpBitmap, r.L, r.T, r.L - x, r.T - y, r.R - r.L, r.B - r.T, - LiceWeight(pBlend), LiceBlendMode(pBlend)); -// ReaperExt::LICE_Blit(mDrawBitmap, mTmpBitmap, x, y, &srcR, LiceWeight(pBlend), LiceBlendMode(pBlend)); - return true; -} - -bool IGraphicsLice::DrawPoint(const IColor* pColor, float x, float y, - const IChannelBlend* pBlend, bool antiAlias) -{ - float weight = (pBlend ? pBlend->mWeight : 1.0f); - _LICE::LICE_PutPixel(mDrawBitmap, int(x + 0.5f), int(y + 0.5f), LiceColor(pColor), weight, LiceBlendMode(pBlend)); - return true; -} - -bool IGraphicsLice::ForcePixel(const IColor* pColor, int x, int y) -{ - LICE_pixel* px = mDrawBitmap->getBits(); - px += x + y * mDrawBitmap->getRowSpan(); - *px = LiceColor(pColor); - return true; -} - -bool IGraphicsLice::DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, - const IChannelBlend* pBlend, bool antiAlias) -{ - _LICE::LICE_Line(mDrawBitmap, x1, y1, x2, y2, LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); - return true; -} - -bool IGraphicsLice::DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, - const IChannelBlend* pBlend, bool antiAlias) -{ - _LICE::LICE_Arc(mDrawBitmap, cx, cy, r, minAngle, maxAngle, LiceColor(pColor), - LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); - return true; -} - -bool IGraphicsLice::DrawCircle(const IColor* pColor, float cx, float cy, float r, - const IChannelBlend* pBlend, bool antiAlias) -{ - _LICE::LICE_Circle(mDrawBitmap, cx, cy, r, LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); - return true; -} - -bool IGraphicsLice::FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend) -{ - _LICE::LICE_FillRect(mDrawBitmap, pR->L, pR->T, pR->W(), pR->H(), LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend)); - return true; -} - -IColor IGraphicsLice::GetPoint(int x, int y) -{ - LICE_pixel pix = _LICE::LICE_GetPixel(mDrawBitmap, x, y); - return IColor(LICE_GETA(pix), LICE_GETR(pix), LICE_GETG(pix), LICE_GETB(pix)); -} - -bool IGraphicsLice::DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi) -{ - _LICE::LICE_Line(mDrawBitmap, (float)xi, (float)yLo, (float)xi, (float)yHi, LiceColor(pColor), 1.0f, LICE_BLIT_MODE_COPY, false); - return true; -} - -bool IGraphicsLice::DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi) -{ - _LICE::LICE_Line(mDrawBitmap, (float)xLo, (float)yi, (float)xHi, (float)yi, LiceColor(pColor), 1.0f, LICE_BLIT_MODE_COPY, false); - return true; -} - -IBitmap IGraphicsLice::ScaleBitmap(IBitmap* pIBitmap, int destW, int destH) -{ - LICE_IBitmap* pSrc = (LICE_IBitmap*) pIBitmap->mData; - LICE_MemBitmap* pDest = new LICE_MemBitmap(destW, destH); - _LICE::LICE_ScaledBlit(pDest, pSrc, 0, 0, destW, destH, 0.0f, 0.0f, (float) pIBitmap->W, (float) pIBitmap->H, 1.0f, - LICE_BLIT_MODE_COPY | LICE_BLIT_FILTER_BILINEAR); - - IBitmap bmp(pDest, destW, destH, pIBitmap->N); - RetainBitmap(&bmp); - return bmp; -} - -IBitmap IGraphicsLice::CropBitmap(IBitmap* pIBitmap, IRECT* pR) -{ - int destW = pR->W(), destH = pR->H(); - LICE_IBitmap* pSrc = (LICE_IBitmap*) pIBitmap->mData; - LICE_MemBitmap* pDest = new LICE_MemBitmap(destW, destH); - _LICE::LICE_Blit(pDest, pSrc, 0, 0, pR->L, pR->T, destW, destH, 1.0f, LICE_BLIT_MODE_COPY); - - IBitmap bmp(pDest, destW, destH, pIBitmap->N); - RetainBitmap(&bmp); - return bmp; -} - -LICE_pixel* IGraphicsLice::GetBits() -{ - return mDrawBitmap->getBits(); -} \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsLice.h b/WDL/IPlug/IGraphicsLice.h deleted file mode 100644 index 44c00256..00000000 --- a/WDL/IPlug/IGraphicsLice.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _IGRAPHICSLICE_ -#define _IGRAPHICSLICE_ - -#include "IControl.h" -#include "../lice/lice.h" - -// Specialty stuff for calling in to Reaper for Lice functionality. -#ifdef REAPER_SPECIAL - #include "../IPlugExt/ReaperExt.h" - #define _LICE ReaperExt -#else - #define _LICE -#endif - -class IGraphicsLice : public IGraphics -{ -public: - - IGraphicsLice(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); - ~IGraphicsLice(); - - void PrepDraw(); - - bool DrawBitmap(IBitmap* pBitmap, IRECT* pDest, int srcX, int srcY, - const IChannelBlend* pBlend = 0); - virtual bool DrawRotatedBitmap(IBitmap* pBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg = 0, - const IChannelBlend* pBlend = 0); - virtual bool DrawRotatedMask(IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, int x, int y, double angle, - const IChannelBlend* pBlend = 0); - bool DrawPoint(const IColor* pColor, float x, float y, - const IChannelBlend* pBlend = 0, bool antiAlias = false); - bool ForcePixel(const IColor* pColor, int x, int y); - bool DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, - const IChannelBlend* pBlend = 0, bool antiAlias = false); - bool DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, - const IChannelBlend* pBlend = 0, bool antiAlias = false); - bool DrawCircle(const IColor* pColor, float cx, float cy, float r, - const IChannelBlend* pBlend = 0, bool antiAlias = false); - bool FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend = 0); - IColor GetPoint(int x, int y); - void* GetData() { return GetBits(); } - bool DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi); - bool DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi); - - // The backing store for any bitmaps created by LoadIBitmap, ScaleBitmap, or CropBitmap, - // or any bitmaps passed to RetainBitmap, will be retained across all plugin instances - // until explicitly released, or until the dll completely unloads. - - IBitmap LoadIBitmap(int ID, const char* name, int nStates = 1); - - // Specialty use... - IBitmap ScaleBitmap(IBitmap* pBitmap, int destW, int destH); - IBitmap CropBitmap(IBitmap* pBitmap, IRECT* pR); - void RetainBitmap(IBitmap* pBitmap); - void ReleaseBitmap(IBitmap* pBitmap); - LICE_pixel* GetBits(); - -protected: - virtual LICE_IBitmap* OSLoadBitmap(int ID, const char* name) = 0; - LICE_SysBitmap* mDrawBitmap; - -private: - LICE_MemBitmap* mTmpBitmap; -}; - -//////////////////////////////////////// - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsMac.h b/WDL/IPlug/IGraphicsMac.h deleted file mode 100644 index ddb82df0..00000000 --- a/WDL/IPlug/IGraphicsMac.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _IGRAPHICSMAC_ -#define _IGRAPHICSMAC_ - -#include "IGraphicsLice.h" -#include "../swell/swell.h" -#include - -class IGraphicsCarbon; -class NSMutableDictionary; - -class IGraphicsMac : public IGraphicsLice -{ -public: - - IGraphicsMac(IPlugBase* pPlug, int w, int h, int refreshFPS = FPS); - virtual ~IGraphicsMac(); - - void SetBundleID(const char* bundleID) { mBundleID.Set(bundleID); } - - bool DrawScreen(IRECT* pR); - - void* OpenWindow(void* pWindow); - void* OpenWindow(void* pWindow, void* pControl); - - void* OpenCocoaWindow(void* pParentView); - void* OpenCarbonWindow(void* pParentWnd, void* pParentControl); - - void CloseWindow(); - bool WindowIsOpen(); - void Resize(int w, int h); - - void HostPath(WDL_String* pPath); - void PluginPath(WDL_String* pPath); - - void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = "", - char* extensions = ""); // extensions = "txt wav" for example. - bool PromptForColor(IColor* pColor, char* prompt = ""); - void PromptUserInput(IControl* pControl, IParam* pParam); - bool OpenURL(const char* url, const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0); - - void* GetWindow(); - - int mIdleTicks; - - const char* GetBundleID() { return mBundleID.Get(); } - static int GetUserOSVersion(); // Returns a number like 0x1050 (10.5). - bool DrawIText(IText* pTxt, char* str, IRECT* pR); - -protected: - - virtual LICE_IBitmap* OSLoadBitmap(int ID, const char* name); - -private: - - IGraphicsCarbon* mGraphicsCarbon; - void* mGraphicsCocoa; // Can't forward-declare IGraphicsCocoa because it's an obj-C object. - - WDL_String mBundleID; - NSMutableDictionary* mTxtAttrs; - IText mTxt; -}; - -inline CFStringRef MakeCFString(const char* cStr) -{ - return CFStringCreateWithCString(0, cStr, kCFStringEncodingUTF8); -} - -struct CFStrLocal -{ - CFStringRef mCFStr; - CFStrLocal(const char* cStr) - { - mCFStr = MakeCFString(cStr); - } - ~CFStrLocal() - { - CFRelease(mCFStr); - } -}; - -struct CStrLocal -{ - char* mCStr; - CStrLocal(CFStringRef cfStr) - { - int n = CFStringGetLength(cfStr) + 1; - mCStr = (char*) malloc(n); - CFStringGetCString(cfStr, mCStr, n, kCFStringEncodingUTF8); - } - ~CStrLocal() - { - FREE_NULL(mCStr); - } -}; - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsMac.mm b/WDL/IPlug/IGraphicsMac.mm deleted file mode 100644 index 3bdf62c2..00000000 --- a/WDL/IPlug/IGraphicsMac.mm +++ /dev/null @@ -1,313 +0,0 @@ -#include -#include "IGraphicsMac.h" -#include "IControl.h" -#include "Log.h" -#import "IGraphicsCocoa.h" -#include "IGraphicsCarbon.h" -#include "../swell/swell-internal.h" - -struct CocoaAutoReleasePool -{ - NSAutoreleasePool* mPool; - - CocoaAutoReleasePool() - { - mPool = [[NSAutoreleasePool alloc] init]; - } - - ~CocoaAutoReleasePool() - { - [mPool release]; - } -}; - -inline NSColor* ToNSColor(IColor* pColor) -{ - double r = (double) pColor->R / 255.0; - double g = (double) pColor->G / 255.0; - double b = (double) pColor->B / 255.0; - double a = (double) pColor->A / 255.0; - return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a]; -} - -IGraphicsMac::IGraphicsMac(IPlugBase* pPlug, int w, int h, int refreshFPS) -: IGraphicsLice(pPlug, w, h, refreshFPS), mGraphicsCarbon(0), mGraphicsCocoa(0), mTxtAttrs(0) -{ - NSApplicationLoad(); - -} - -IGraphicsMac::~IGraphicsMac() -{ - CloseWindow(); - if (mTxtAttrs) { - [mTxtAttrs release]; - mTxtAttrs = 0; - } -} - -LICE_IBitmap* LoadImgFromResourceOSX(const char* bundleID, const char* filename) -{ - if (!filename) return 0; - CocoaAutoReleasePool pool; - - const char* ext = filename+strlen(filename)-1; - while (ext >= filename && *ext != '.') --ext; - ++ext; - - bool ispng = !stricmp(ext, "png"); - bool isjpg = !stricmp(ext, "jpg"); - if (!ispng && !isjpg) return 0; - - NSBundle* pBundle = [NSBundle bundleWithIdentifier:ToNSString(bundleID)]; - NSString* pFile = [[[NSString stringWithCString:filename] lastPathComponent] stringByDeletingPathExtension]; - if (pBundle && pFile) - { - NSString* pPath = 0; - if (ispng) pPath = [pBundle pathForResource:pFile ofType:@"png"]; - if (isjpg) pPath = [pBundle pathForResource:pFile ofType:@"jpg"]; - - if (pPath) - { - const char* resourceFileName = [pPath cString]; - if (CSTR_NOT_EMPTY(resourceFileName)) - { - if (ispng) return LICE_LoadPNG(resourceFileName); - if (isjpg) return LICE_LoadJPG(resourceFileName); - } - } - } - return 0; -} - -LICE_IBitmap* IGraphicsMac::OSLoadBitmap(int ID, const char* name) -{ - return LoadImgFromResourceOSX(GetBundleID(), name); -} - -bool IGraphicsMac::DrawScreen(IRECT* pR) -{ - CGContextRef pCGC = 0; - CGRect r = CGRectMake(0, 0, Width(), Height()); - if (mGraphicsCocoa) { - pCGC = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; // Leak? - NSGraphicsContext* gc = [NSGraphicsContext graphicsContextWithGraphicsPort: pCGC flipped: YES]; - pCGC = (CGContextRef) [gc graphicsPort]; - } - else - if (mGraphicsCarbon) { - pCGC = mGraphicsCarbon->GetCGContext(); - mGraphicsCarbon->OffsetContentRect(&r); - // Flipping is handled in IGraphicsCarbon. - } - if (!pCGC) { - return false; - } - - HDC__ * srcCtx = (HDC__*) mDrawBitmap->getDC(); - CGImageRef img = CGBitmapContextCreateImage(srcCtx->ctx); - CGContextDrawImage(pCGC, r, img); - CGImageRelease(img); - return true; -} - -void* IGraphicsMac::OpenWindow(void* pParent) -{ - return OpenCocoaWindow(pParent); -} - -void* IGraphicsMac::OpenWindow(void* pWindow, void* pControl) -{ - return OpenCarbonWindow(pWindow, pControl); -} - -void* IGraphicsMac::OpenCocoaWindow(void* pParentView) -{ - TRACE; - CloseWindow(); - mGraphicsCocoa = (IGRAPHICS_COCOA*) [[IGRAPHICS_COCOA alloc] initWithIGraphics: this]; - if (pParentView) { // Cocoa VST host. - [(NSView*) pParentView addSubview: (IGRAPHICS_COCOA*) mGraphicsCocoa]; - } - // Else we are being called by IGraphicsCocoaFactory, which is being called by a Cocoa AU host, - // and the host will take care of attaching the view to the window. - return mGraphicsCocoa; -} - -void* IGraphicsMac::OpenCarbonWindow(void* pParentWnd, void* pParentControl) -{ - TRACE; - CloseWindow(); - WindowRef pWnd = (WindowRef) pParentWnd; - ControlRef pControl = (ControlRef) pParentControl; - // On 10.5 or later we could have used HICocoaViewCreate, but for 10.4 we have to support Carbon explicitly. - mGraphicsCarbon = new IGraphicsCarbon(this, pWnd, pControl); - return mGraphicsCarbon->GetView(); -} - -void IGraphicsMac::CloseWindow() -{ - if (mGraphicsCarbon) - { - DELETE_NULL(mGraphicsCarbon); - } - else - if (mGraphicsCocoa) - { - IGRAPHICS_COCOA* graphicscocoa = (IGRAPHICS_COCOA*)mGraphicsCocoa; - [graphicscocoa killTimer]; - mGraphicsCocoa = 0; - if (graphicscocoa->mGraphics) - { - graphicscocoa->mGraphics = 0; - [graphicscocoa removeFromSuperview]; // Releases. - } - - } -} - -bool IGraphicsMac::WindowIsOpen() -{ - return (mGraphicsCarbon || mGraphicsCocoa); -} - -void IGraphicsMac::Resize(int w, int h) -{ - IGraphics::Resize(w, h); - if (mDrawBitmap) { - mDrawBitmap->resize(w, h); - } - - if (mGraphicsCarbon) { - mGraphicsCarbon->Resize(w, h); - } - else - if (mGraphicsCocoa) { - NSSize size = { w, h }; - [(IGRAPHICS_COCOA*) mGraphicsCocoa setFrameSize: size ]; - } -} - -void IGraphicsMac::HostPath(WDL_String* pPath) -{ - CocoaAutoReleasePool pool; - NSBundle* pBundle = [NSBundle bundleWithIdentifier: ToNSString(GetBundleID())]; - if (pBundle) { - NSString* path = [pBundle executablePath]; - if (path) { - pPath->Set([path cString]); - } - } -} - -void IGraphicsMac::PluginPath(WDL_String* pPath) -{ - CocoaAutoReleasePool pool; - NSBundle* pBundle = [NSBundle bundleWithIdentifier: ToNSString(GetBundleID())]; - if (pBundle) { - NSString* path = [[pBundle bundlePath] stringByDeletingLastPathComponent]; - if (path) { - pPath->Set([path cString]); - pPath->Append("/"); - } - } -} - -// extensions = "txt wav" for example -void IGraphicsMac::PromptForFile(WDL_String* pFilename, EFileAction action, char* dir, char* extensions) -{ -} - -bool IGraphicsMac::PromptForColor(IColor* pColor, char* prompt) -{ - return false; -} - -void IGraphicsMac::PromptUserInput(IControl* pControl, IParam* pParam) -{ -} - -bool IGraphicsMac::OpenURL(const char* url, - const char* msgWindowTitle, const char* confirmMsg, const char* errMsgOnFailure) -{ -#pragma REMINDER("Warning and error messages for OpenURL not implemented") - NSURL* pURL = 0; - if (strstr(url, "http")) { - pURL = [NSURL URLWithString:ToNSString(url)]; - } - else { - pURL = [NSURL fileURLWithPath:ToNSString(url)]; - } - if (pURL) { - bool ok = ([[NSWorkspace sharedWorkspace] openURL:pURL]); - // [pURL release]; - return ok; - } - return true; -} - -void* IGraphicsMac::GetWindow() -{ - return mGraphicsCocoa; -} - -// static -int IGraphicsMac::GetUserOSVersion() // Returns a number like 0x1050 (10.5). -{ - SInt32 ver = 0; - Gestalt(gestaltSystemVersion, &ver); - Trace(TRACELOC, "%x", ver); - return ver; -} - -bool IGraphicsMac::DrawIText(IText* pTxt, char* cStr, IRECT* pR) -{ - bool init = (mTxtAttrs); - if (!init) { - mTxtAttrs = [[NSMutableDictionary alloc] init]; - } - - int fontSize = int(0.75 * (double) pTxt->mSize); - int yAdj = fontSize / 4; - bool antialias = (fontSize >= 12); - - if (!init) { // || strcmp(pTxt->mFont, mTxt.mFont)) { - NSFont* font = [NSFont fontWithName: ToNSString(pTxt->mFont) size: fontSize]; - [mTxtAttrs setValue: font forKey: NSFontAttributeName]; - strcpy(mTxt.mFont, pTxt->mFont); - } - - if (!init || pTxt->mColor != mTxt.mColor) { - [mTxtAttrs setValue: ToNSColor(&(pTxt->mColor)) forKey: NSForegroundColorAttributeName]; - mTxt.mColor = pTxt->mColor; - } - - if (!init || pTxt->mAlign != mTxt.mAlign) { - NSTextAlignment align; - switch (pTxt->mAlign) { - case IText::kAlignNear: align = NSLeftTextAlignment; break; - case IText::kAlignFar: align = NSRightTextAlignment; break; - case IText::kAlignCenter: - default: align = NSCenterTextAlignment; break; - } - NSMutableParagraphStyle* paraStyle = [[NSMutableParagraphStyle alloc] init]; - [paraStyle setAlignment: align]; - [mTxtAttrs setValue: paraStyle forKey: NSParagraphStyleAttributeName]; - [paraStyle release]; - mTxt.mAlign = pTxt->mAlign; - } - - [NSGraphicsContext saveGraphicsState]; - HDC__* destCtx = (HDC__*) mDrawBitmap->getDC(); - NSGraphicsContext* destGC = [NSGraphicsContext graphicsContextWithGraphicsPort:destCtx->ctx flipped:YES]; - [destGC setShouldAntialias: antialias]; - [NSGraphicsContext setCurrentContext:destGC]; - NSRect r = { pR->L, pR->T+yAdj+6, pR->W(), pR->H() }; - NSString* str = ToNSString(cStr); - [str drawWithRect:r options: NSStringDrawingUsesDeviceMetrics attributes: mTxtAttrs]; - [NSGraphicsContext restoreGraphicsState]; - - return true; -} - - \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsWin.cpp b/WDL/IPlug/IGraphicsWin.cpp deleted file mode 100644 index 9c2a5c16..00000000 --- a/WDL/IPlug/IGraphicsWin.cpp +++ /dev/null @@ -1,718 +0,0 @@ -#include "IGraphicsWin.h" -#include "IControl.h" -#include "Log.h" -#include - -#pragma warning(disable:4244) // Pointer size cast mismatch. -#pragma warning(disable:4312) // Pointer size cast mismatch. -#pragma warning(disable:4311) // Pointer size cast mismatch. - -static int nWndClassReg = 0; -static const char* wndClassName = "IPlugWndClass"; -static double sFPS = 0.0; - -#define MAX_PARAM_LEN 32 -#define PARAM_EDIT_ID 99 - -enum EParamEditMsg { - kNone, - kEditing, - kUpdate, - kCancel, - kCommit -}; - -#define IPLUG_TIMER_ID 2 - -inline IMouseMod GetMouseMod(WPARAM wParam) -{ - return IMouseMod((wParam & MK_LBUTTON), (wParam & MK_RBUTTON), - (wParam & MK_SHIFT), (wParam & MK_CONTROL), GetKeyState(VK_MENU) < 0); -} - -// static -LRESULT CALLBACK IGraphicsWin::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_CREATE) { - LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam; - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM) (lpcs->lpCreateParams)); - int mSec = int(1000.0 / sFPS); - SetTimer(hWnd, IPLUG_TIMER_ID, mSec, NULL); - return 0; - } - - IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); - char txt[MAX_PARAM_LEN]; - double v; - - if (!pGraphics || hWnd != pGraphics->mPlugWnd) { - return DefWindowProc(hWnd, msg, wParam, lParam); - } - if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg == kEditing) { - if (msg == WM_RBUTTONDOWN) { - pGraphics->mParamEditMsg = kCancel; - return 0; - } - return DefWindowProc(hWnd, msg, wParam, lParam); - } - - switch (msg) { - - case WM_TIMER: { - if (wParam == IPLUG_TIMER_ID) { - - if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg != kNone) { - switch (pGraphics->mParamEditMsg) { - case kUpdate: { - pGraphics->mEdParam->GetDisplayForHost(txt); - SendMessage(pGraphics->mParamEditWnd, WM_SETTEXT, 0, (LPARAM) txt); - break; - } - case kCommit: { - SendMessage(pGraphics->mParamEditWnd, WM_GETTEXT, MAX_PARAM_LEN, (LPARAM) txt); - if (pGraphics->mEdParam->GetNDisplayTexts()) { - int vi = 0; - pGraphics->mEdParam->MapDisplayText(txt, &vi); - v = (double) vi; - } - else { - v = atof(txt); - if (pGraphics->mEdParam->DisplayIsNegated()) { - v = -v; - } - } - pGraphics->mEdControl->SetValueFromUserInput(pGraphics->mEdParam->GetNormalized(v)); - // Fall through. - } - case kCancel: - { - SetWindowLongPtr(pGraphics->mParamEditWnd, GWLP_WNDPROC, (LPARAM) pGraphics->mDefEditProc); - DestroyWindow(pGraphics->mParamEditWnd); - pGraphics->mParamEditWnd = 0; - pGraphics->mEdParam = 0; - pGraphics->mEdControl = 0; - pGraphics->mDefEditProc = 0; - } - break; - } - pGraphics->mParamEditMsg = kNone; - return 0; - } - - IRECT dirtyR; - if (pGraphics->IsDirty(&dirtyR)) { - RECT r = { dirtyR.L, dirtyR.T, dirtyR.R, dirtyR.B }; - InvalidateRect(hWnd, &r, FALSE); - UpdateWindow(hWnd); - if (pGraphics->mParamEditWnd) { - pGraphics->mParamEditMsg = kUpdate; - } - } - } - return 0; - } - case WM_RBUTTONDOWN: { - if (pGraphics->mParamEditWnd) { - pGraphics->mParamEditMsg = kCancel; - return 0; - } - // Else fall through. - } - case WM_LBUTTONDOWN: { - SetCapture(hWnd); - pGraphics->OnMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); - return 0; - } - case WM_MOUSEMOVE: { - if (!(wParam & (MK_LBUTTON | MK_RBUTTON))) { - if (pGraphics->OnMouseOver(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { - TRACKMOUSEEVENT eventTrack = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hWnd, HOVER_DEFAULT }; - TrackMouseEvent(&eventTrack); - } - } - else - if (GetCapture() == hWnd) { - pGraphics->OnMouseDrag(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); - } - return 0; - } - case WM_MOUSELEAVE: { - pGraphics->OnMouseOut(); - return 0; - } - case WM_LBUTTONUP: - case WM_RBUTTONUP: { - ReleaseCapture(); - pGraphics->OnMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); - return 0; - } - case WM_LBUTTONDBLCLK: { - if (pGraphics->OnMouseDblClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { - SetCapture(hWnd); - } - return 0; - } - case WM_MOUSEWHEEL: { - int d = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; - int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - RECT r; - GetWindowRect(hWnd, &r); - pGraphics->OnMouseWheel(x - r.left, y - r.top, &GetMouseMod(wParam), d); - return 0; - } - - case WM_KEYDOWN: - { - bool ok = true; - int key; - - if (wParam == VK_SPACE) key = KEY_SPACE; - else if (wParam == VK_UP) key = KEY_UPARROW; - else if (wParam == VK_DOWN) key = KEY_DOWNARROW; - else if (wParam == VK_LEFT) key = KEY_LEFTARROW; - else if (wParam == VK_RIGHT) key = KEY_RIGHTARROW; - else if (wParam >= '0' && wParam <= '9') key = KEY_DIGIT_0+wParam-'0'; - else if (wParam >= 'A' && wParam <= 'Z') key = KEY_ALPHA_A+wParam-'A'; - else if (wParam >= 'a' && wParam <= 'z') key = KEY_ALPHA_A+wParam-'a'; - else ok = false; - - if (ok) - { - POINT p; - GetCursorPos(&p); - ScreenToClient(hWnd, &p); - pGraphics->OnKeyDown(p.x, p.y, key); - } - } - return 0; - - case WM_PAINT: { - RECT r; - if (GetUpdateRect(hWnd, &r, FALSE)) { - IRECT ir(r.left, r.top, r.right, r.bottom); - pGraphics->Draw(&ir); - } - return 0; - } - - //case WM_CTLCOLOREDIT: { - // // An edit control just opened. - // HDC dc = (HDC) wParam; - // SetTextColor(dc, ///); - // return 0; - //} - - case WM_CLOSE: { - pGraphics->CloseWindow(); - return 0; - } - } - return DefWindowProc(hWnd, msg, wParam, lParam); -} - -// static -LRESULT CALLBACK IGraphicsWin::ParamEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); - - if (pGraphics && pGraphics->mParamEditWnd && pGraphics->mParamEditWnd == hWnd) - { - switch (msg) { - case WM_KEYDOWN: { - if (wParam == VK_RETURN) { - pGraphics->mParamEditMsg = kCommit; - return 0; - } - break; - } - case WM_SETFOCUS: { - pGraphics->mParamEditMsg = kEditing; - break; - } - case WM_KILLFOCUS: { - pGraphics->mParamEditMsg = kNone; - break; - } - case WM_COMMAND: { - switch HIWORD(wParam) { - case CBN_SELCHANGE: { - if (pGraphics->mParamEditWnd) { - pGraphics->mParamEditMsg = kCommit; - return 0; - } - } - - } - break; // Else let the default proc handle it. - } - } - return CallWindowProc(pGraphics->mDefEditProc, hWnd, msg, wParam, lParam); - } - return DefWindowProc(hWnd, msg, wParam, lParam); -} - -IGraphicsWin::IGraphicsWin(IPlugBase* pPlug, int w, int h, int refreshFPS) -: IGraphicsLice(pPlug, w, h, refreshFPS), mPlugWnd(0), mParamEditWnd(0), - mPID(0), mParentWnd(0), mMainWnd(0), mCustomColorStorage(0), - mEdControl(0), mEdParam(0), mDefEditProc(0), mParamEditMsg(kNone), mIdleTicks(0), - mFontActive(false), mHInstance(0) -{ -} - -IGraphicsWin::~IGraphicsWin() -{ - CloseWindow(); - FREE_NULL(mCustomColorStorage); -} - -LICE_IBitmap* IGraphicsWin::OSLoadBitmap(int ID, const char* name) -{ - const char* ext = name+strlen(name)-1; - while (ext > name && *ext != '.') --ext; - ++ext; - - if (!stricmp(ext, "png")) return _LICE::LICE_LoadPNGFromResource(mHInstance, ID, 0); - if (!stricmp(ext, "jpg") || !stricmp(ext, "jpeg")) return _LICE::LICE_LoadJPGFromResource(mHInstance, ID, 0); - return 0; -} - -void GetWindowSize(HWND pWnd, int* pW, int* pH) -{ - if (pWnd) { - RECT r; - GetWindowRect(pWnd, &r); - *pW = r.right - r.left; - *pH = r.bottom - r.top; - } - else { - *pW = *pH = 0; - } -} - -bool IsChildWindow(HWND pWnd) -{ - if (pWnd) { - int style = GetWindowLong(pWnd, GWL_STYLE); - int exStyle = GetWindowLong(pWnd, GWL_EXSTYLE); - return ((style & WS_CHILD) && !(exStyle & WS_EX_MDICHILD)); - } - return false; -} - -#define SETPOS_FLAGS SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE - -void IGraphicsWin::Resize(int w, int h) -{ - int dw = w - Width(), dh = h - Height(); - IGraphics::Resize(w, h); - if (mDrawBitmap) { - mDrawBitmap->resize(w, h); - } - if (WindowIsOpen()) { - HWND pParent = 0, pGrandparent = 0; - int w = 0, h = 0, parentW = 0, parentH = 0, grandparentW = 0, grandparentH = 0; - GetWindowSize(mPlugWnd, &w, &h); - if (IsChildWindow(mPlugWnd)) { - pParent = GetParent(mPlugWnd); - GetWindowSize(pParent, &parentW, &parentH); - if (IsChildWindow(pParent)) { - pGrandparent = GetParent(pParent); - GetWindowSize(pGrandparent, &grandparentW, &grandparentH); - } - } - SetWindowPos(mPlugWnd, 0, 0, 0, w + dw, h + dh, SETPOS_FLAGS); - if (pParent) { - SetWindowPos(pParent, 0, 0, 0, parentW + dw, parentH + dh, SETPOS_FLAGS); - } - if (pGrandparent) { - SetWindowPos(pGrandparent, 0, 0, 0, grandparentW + dw, grandparentH + dh, SETPOS_FLAGS); - } - - RECT r = { 0, 0, w, h }; - InvalidateRect(mPlugWnd, &r, FALSE); - } -} - -bool IGraphicsWin::DrawScreen(IRECT* pR) -{ - PAINTSTRUCT ps; - HWND hWnd = (HWND) GetWindow(); - HDC dc = BeginPaint(hWnd, &ps); - BitBlt(dc, pR->L, pR->T, pR->W(), pR->H(), mDrawBitmap->getDC(), pR->L, pR->T, SRCCOPY); - EndPaint(hWnd, &ps); - return true; -} - -void* IGraphicsWin::OpenWindow(void* pParentWnd) -{ - int x = 0, y = 0, w = Width(), h = Height(); - mParentWnd = (HWND) pParentWnd; - - if (mPlugWnd) { - RECT pR, cR; - GetWindowRect((HWND) pParentWnd, &pR); - GetWindowRect(mPlugWnd, &cR); - CloseWindow(); - x = cR.left - pR.left; - y = cR.top - pR.top; - w = cR.right - cR.left; - h = cR.bottom - cR.top; - } - - if (nWndClassReg++ == 0) { - WNDCLASS wndClass = { CS_DBLCLKS, WndProc, 0, 0, mHInstance, 0, LoadCursor(NULL, IDC_ARROW), 0, 0, wndClassName }; - RegisterClass(&wndClass); - } - - sFPS = FPS(); - mPlugWnd = CreateWindow(wndClassName, "IPlug", WS_CHILD | WS_VISIBLE, // | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - x, y, w, h, (HWND) pParentWnd, 0, mHInstance, this); - //SetWindowLong(mPlugWnd, GWL_USERDATA, (LPARAM) this); - - if (!mPlugWnd && --nWndClassReg == 0) { - UnregisterClass(wndClassName, mHInstance); - } - else { - SetAllControlsDirty(); - } - - return mPlugWnd; -} - -#define MAX_CLASSNAME_LEN 128 -void GetWndClassName(HWND hWnd, WDL_String* pStr) -{ - char cStr[MAX_CLASSNAME_LEN]; - cStr[0] = '\0'; - GetClassName(hWnd, cStr, MAX_CLASSNAME_LEN); - pStr->Set(cStr); -} - -BOOL CALLBACK IGraphicsWin::FindMainWindow(HWND hWnd, LPARAM lParam) -{ - IGraphicsWin* pGraphics = (IGraphicsWin*) lParam; - if (pGraphics) { - DWORD wPID; - GetWindowThreadProcessId(hWnd, &wPID); - WDL_String str; - GetWndClassName(hWnd, &str); - if (wPID == pGraphics->mPID && !strcmp(str.Get(), pGraphics->mMainWndClassName.Get())) { - pGraphics->mMainWnd = hWnd; - return FALSE; // Stop enumerating. - } - } - return TRUE; -} - -HWND IGraphicsWin::GetMainWnd() -{ - if (!mMainWnd) { - if (mParentWnd) { - HWND parentWnd = mParentWnd; - while (parentWnd) { - mMainWnd = parentWnd; - parentWnd = GetParent(mMainWnd); - } - GetWndClassName(mMainWnd, &mMainWndClassName); - } - else - if (CSTR_NOT_EMPTY(mMainWndClassName.Get())) { - mPID = GetCurrentProcessId(); - EnumWindows(FindMainWindow, (LPARAM) this); - } - } - return mMainWnd; -} - -#define TOOLWIN_BORDER_W 6 -#define TOOLWIN_BORDER_H 23 - -IRECT IGraphicsWin::GetWindowRECT() -{ - if (mPlugWnd) { - RECT r; - GetWindowRect(mPlugWnd, &r); - r.right -= TOOLWIN_BORDER_W; - r.bottom -= TOOLWIN_BORDER_H; - return IRECT(r.left, r.top, r.right, r.bottom); - } - return IRECT(); -} - -void IGraphicsWin::SetWindowTitle(char* str) -{ - SetWindowText(mPlugWnd, str); -} - -void IGraphicsWin::CloseWindow() -{ - if (mPlugWnd) { - DestroyWindow(mPlugWnd); - mPlugWnd = 0; - - if (--nWndClassReg == 0) { - UnregisterClass(wndClassName, mHInstance); - } - } -} - -#define PARAM_EDIT_W 36 -#define PARAM_EDIT_H 16 -#define PARAM_EDIT_H_PER_ENUM 36 -#define PARAM_LIST_MIN_W 24 -#define PARAM_LIST_W_PER_CHAR 8 - -void IGraphicsWin::PromptUserInput(IControl* pControl, IParam* pParam) -{ - if (!pControl || !pParam || mParamEditWnd) { - return; - } - - IRECT* pR = pControl->GetRECT(); - int cX = int(pR->MW()), cY = int(pR->MH()); - char currentText[MAX_PARAM_NAME_LEN]; - pParam->GetDisplayForHost(currentText); - - int n = pParam->GetNDisplayTexts(); - if (n) { - int i, currentIdx = -1; - int w = PARAM_LIST_MIN_W, h = PARAM_EDIT_H_PER_ENUM * (n + 1); - for (i = 0; i < n; ++i) { - const char* str = pParam->GetDisplayText(i); - w = MAX(w, PARAM_LIST_MIN_W + strlen(str) * PARAM_LIST_W_PER_CHAR); - if (!strcmp(str, currentText)) { - currentIdx = i; - } - } - - mParamEditWnd = CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, - cX - w/2, cY, w, h, mPlugWnd, (HMENU) PARAM_EDIT_ID, mHInstance, 0); - - for (i = 0; i < n; ++i) { - const char* str = pParam->GetDisplayText(i); - SendMessage(mParamEditWnd, CB_ADDSTRING, 0, (LPARAM) str); - } - SendMessage(mParamEditWnd, CB_SETCURSEL, (WPARAM) currentIdx, 0); - } - else { - int w = PARAM_EDIT_W, h = PARAM_EDIT_H; - mParamEditWnd = CreateWindow("EDIT", currentText, WS_CHILD | WS_VISIBLE | ES_CENTER | ES_MULTILINE, - cX - w/2, cY - h/2, w, h, mPlugWnd, (HMENU) PARAM_EDIT_ID, mHInstance, 0); - } - - mDefEditProc = (WNDPROC) SetWindowLongPtr(mParamEditWnd, GWLP_WNDPROC, (LONG_PTR) ParamEditProc); - SetWindowLong(mParamEditWnd, GWLP_USERDATA, (LPARAM) this); - - IText txt; - HFONT font = CreateFont(txt.mSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, txt.mFont); - SendMessage(mParamEditWnd, WM_SETFONT, (WPARAM) font, 0); - //DeleteObject(font); - - mEdControl = pControl; - mEdParam = pParam; -} - -#define MAX_PATH_LEN 256 - -void GetModulePath(HMODULE hModule, WDL_String* pPath) -{ - pPath->Set(""); - char pathCStr[MAX_PATH_LEN]; - pathCStr[0] = '\0'; - if (GetModuleFileName(hModule, pathCStr, MAX_PATH_LEN)) { - int s = -1; - for (int i = 0; i < strlen(pathCStr); ++i) { - if (pathCStr[i] == '\\') { - s = i; - } - } - if (s >= 0 && s + 1 < strlen(pathCStr)) { - pPath->Set(pathCStr, s + 1); - } - } -} - -void IGraphicsWin::HostPath(WDL_String* pPath) -{ - GetModulePath(0, pPath); -} - -void IGraphicsWin::PluginPath(WDL_String* pPath) -{ - GetModulePath(mHInstance, pPath); -} - -void IGraphicsWin::PromptForFile(WDL_String* pFilename, EFileAction action, char* dir, char* extensions) -{ - pFilename->Set(""); - if (!WindowIsOpen()) { - return; - } - - WDL_String pathStr; - char fnCStr[MAX_PATH_LEN], dirCStr[MAX_PATH_LEN]; - fnCStr[0] = '\0'; - dirCStr[0] = '\0'; - if (CSTR_NOT_EMPTY(dir)) { - pathStr.Set(dir); - strcpy(dirCStr, dir); - } - else { - HostPath(&pathStr); - } - - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(OPENFILENAME)); - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = mPlugWnd; - ofn.lpstrFile = fnCStr; - ofn.nMaxFile = MAX_PATH_LEN - 1; - ofn.lpstrInitialDir = dirCStr; - ofn.Flags = OFN_PATHMUSTEXIST; - - //if (!extensions.empty()) { - //static char extStr[256]; - //static char defExtStr[16]; - //int i, j, p; - - //for (j = 0, p = 0; j < extensions.size(); ++j) { - // extStr[p++] = extensions[j++]; - //} - //extStr[p++] = '\0'; - - //StrVector exts = SplitStr(extensions); - //for (i = 0, p = 0; i < exts.size(); ++i) { - // const std::string& ext = exts[i]; - // if (i) { - // extStr[p++] = ';'; - // } - // extStr[p++] = '*'; - // extStr[p++] = '.'; - // for (j = 0; j < ext.size(); ++j) { - // extStr[p++] = ext[j]; - // } - //} - //extStr[p++] = '\0'; - //extStr[p++] = '\0'; - //ofn.lpstrFilter = extStr; - // - //strcpy(defExtStr, exts.front().c_str()); - //ofn.lpstrDefExt = defExtStr; - //} - - bool rc = false; - switch (action) { - case kFileSave: - ofn.Flags |= OFN_OVERWRITEPROMPT; - rc = GetSaveFileName(&ofn); - break; - - case kFileOpen: - default: - ofn.Flags |= OFN_FILEMUSTEXIST; - rc = GetOpenFileName(&ofn); - break; - } - - if (rc) { - pFilename->Set(ofn.lpstrFile); - } -} - -UINT_PTR CALLBACK CCHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) -{ - if (uiMsg == WM_INITDIALOG && lParam) { - CHOOSECOLOR* cc = (CHOOSECOLOR*) lParam; - if (cc && cc->lCustData) { - char* str = (char*) cc->lCustData; - SetWindowText(hdlg, str); - } - } - return 0; -} - -bool IGraphicsWin::PromptForColor(IColor* pColor, char* prompt) -{ - if (!mPlugWnd) { - return false; - } - if (!mCustomColorStorage) { - mCustomColorStorage = (COLORREF*) calloc(16, sizeof(COLORREF)); - } - CHOOSECOLOR cc; - memset(&cc, 0, sizeof(CHOOSECOLOR)); - cc.lStructSize = sizeof(CHOOSECOLOR); - cc.hwndOwner = mPlugWnd; - cc.rgbResult = RGB(pColor->R, pColor->G, pColor->B); - cc.lpCustColors = mCustomColorStorage; - cc.lCustData = (LPARAM) prompt; - cc.lpfnHook = CCHookProc; - cc.Flags = CC_RGBINIT | CC_ANYCOLOR | CC_FULLOPEN | CC_SOLIDCOLOR | CC_ENABLEHOOK; - - if (ChooseColor(&cc)) { - pColor->R = GetRValue(cc.rgbResult); - pColor->G = GetGValue(cc.rgbResult); - pColor->B = GetBValue(cc.rgbResult); - return true; - } - return false; -} - -#define MAX_INET_ERR_CODE 32 -bool IGraphicsWin::OpenURL(const char* url, - const char* msgWindowTitle, const char* confirmMsg, const char* errMsgOnFailure) -{ - if (confirmMsg && MessageBox(mPlugWnd, confirmMsg, msgWindowTitle, MB_YESNO) != IDYES) { - return false; - } - DWORD inetStatus = 0; - if (InternetGetConnectedState(&inetStatus, 0)) { - if ((int) ShellExecute(mPlugWnd, "open", url, 0, 0, SW_SHOWNORMAL) > MAX_INET_ERR_CODE) { - return true; - } - } - if (errMsgOnFailure) { - MessageBox(mPlugWnd, errMsgOnFailure, msgWindowTitle, MB_OK); - } - return false; -} - -bool IGraphicsWin::DrawIText(IText* pText, char* str, IRECT* pR) -{ - if (!str || str == '\0') { - return true; - } - - HDC pDC = mDrawBitmap->getDC(); - - bool setColor = (pText->mColor != mActiveFontColor); - if (!mFontActive) { - int h = pText->mSize; - int esc = 10 * pText->mOrientation; - int wt = (pText->mStyle == IText::kStyleBold ? FW_BOLD : 0); - int it = (pText->mStyle == IText::kStyleItalic ? 1 : 0); - HFONT font = CreateFont(h, 0, esc, esc, wt, it, 0, 0, 0, 0, 0, 0, 0, pText->mFont); - SelectObject(pDC, font); // leak? - SetBkMode(pDC, TRANSPARENT); - mFontActive = true; - setColor = true; - } - - if (setColor) { - SetTextColor(pDC, RGB(pText->mColor.R, pText->mColor.G, pText->mColor.B)); - mActiveFontColor = pText->mColor; - } - - UINT fmt = DT_NOCLIP; - switch(pText->mAlign) { - case IText::kAlignCenter: fmt |= DT_CENTER; break; - case IText::kAlignFar: fmt |= DT_RIGHT; break; - case IText::kAlignNear: - default: fmt |= DT_LEFT; break; - } - - RECT R = { pR->L, pR->T, pR->R, pR->B }; - return !!DrawText(pDC, str, strlen(str), &R, fmt); -} - diff --git a/WDL/IPlug/IGraphicsWin.h b/WDL/IPlug/IGraphicsWin.h deleted file mode 100644 index b62db7ca..00000000 --- a/WDL/IPlug/IGraphicsWin.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _IGRAPHICSWIN_ -#define _IGRAPHICSWIN_ - -#include "IGraphicsLice.h" - -#include -#include -#include - -class IGraphicsWin : public IGraphicsLice -{ -public: - - IGraphicsWin(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); - virtual ~IGraphicsWin(); - - void SetHInstance(HINSTANCE hInstance) { mHInstance = hInstance; } - - void Resize(int w, int h); - bool DrawScreen(IRECT* pR); - - void* OpenWindow(void* pParentWnd); - void CloseWindow(); - bool WindowIsOpen() { return (mPlugWnd); } - - void HostPath(WDL_String* pPath); - void PluginPath(WDL_String* pPath); - - void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = "", - char* extensions = ""); // extensions = "txt wav" for example. - - bool PromptForColor(IColor* pColor, char* prompt = ""); - void PromptUserInput(IControl* pControl, IParam* pParam); - - bool OpenURL(const char* url, - const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0); - - // Specialty use! - void* GetWindow() { return mPlugWnd; } - HWND GetParentWindow() { return mParentWnd; } - HWND GetMainWnd(); - void SetMainWndClassName(char* name) { mMainWndClassName.Set(name); } - void GetMainWndClassName(char* name) { strcpy(name, mMainWndClassName.Get()); } - IRECT GetWindowRECT(); - void SetWindowTitle(char* str); - - bool DrawIText(IText* pText, char* str, IRECT* pR); - -protected: - LICE_IBitmap* OSLoadBitmap(int ID, const char* name); - -private: - bool mFontActive; - IColor mActiveFontColor; - - HINSTANCE mHInstance; - HWND mPlugWnd, mParamEditWnd; - // Ed = being edited manually. - IControl* mEdControl; - IParam* mEdParam; - WNDPROC mDefEditProc; - int mParamEditMsg; - int mIdleTicks; - COLORREF* mCustomColorStorage; - - DWORD mPID; - HWND mParentWnd, mMainWnd; - WDL_String mMainWndClassName; - -public: - - static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK ParamEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - static BOOL CALLBACK FindMainWindow(HWND hWnd, LPARAM lParam); -}; - -//////////////////////////////////////// - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IParam.cpp b/WDL/IPlug/IParam.cpp deleted file mode 100644 index 8885e0fc..00000000 --- a/WDL/IPlug/IParam.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "IParam.h" -#include - -#define MAX_PARAM_DISPLAY_PRECISION 6 -#define MAX_PARAM_DISPLAY_LEN 8 - -IParam::IParam() -: mType(kTypeNone), mValue(0.0), mMin(0.0), mMax(1.0), mStep(1.0), - mDisplayPrecision(0), mNegateDisplay(false), mShape(1.0) -{ - memset(mName, 0, MAX_PARAM_NAME_LEN * sizeof(char)); - memset(mLabel, 0, MAX_PARAM_NAME_LEN * sizeof(char)); -} - -IParam::~IParam() -{ -} - -void IParam::InitBool(const char* name, bool defaultVal, const char* label) -{ - if (mType == kTypeNone) { - mType = kTypeBool; - } - InitEnum(name, (defaultVal ? 1 : 0), 2); - - SetDisplayText(0, "off"); - SetDisplayText(1, "on"); -} - -void IParam::InitEnum(const char* name, int defaultVal, int nEnums) -{ - if (mType == kTypeNone) { - mType = kTypeEnum; - } - InitInt(name, defaultVal, 0, nEnums - 1); -} - -void IParam::InitInt(const char* name, int defaultVal, int minVal, int maxVal, const char* label) -{ - if (mType == kTypeNone) { - mType = kTypeInt; - } - InitDouble(name, (double) defaultVal, (double) minVal, (double) maxVal, 1.0, label); -} - -void IParam::InitDouble(const char* name, double defaultVal, double minVal, double maxVal, double step, const char* label) -{ - if (mType == kTypeNone) { - mType = kTypeDouble; - } - strcpy(mName, name); - strcpy(mLabel, label); - mValue = defaultVal; - mMin = minVal; - mMax = MAX(maxVal, minVal + step); - mStep = step; - - for (mDisplayPrecision = 0; - mDisplayPrecision < MAX_PARAM_DISPLAY_PRECISION && step != floor(step); - ++mDisplayPrecision, step *= 10.0) { - ; - } -} - -void IParam::SetShape(double shape) -{ - if (shape != 0.0) { - mShape = shape; - } -} - -void IParam::SetDisplayText(int value, const char* text) -{ - int n = mDisplayTexts.GetSize(); - mDisplayTexts.Resize(n + 1); - DisplayText* pDT = mDisplayTexts.Get() + n; - pDT->mValue = value; - strcpy(pDT->mText, text); -} - -double IParam::DBToAmp() -{ - return ::DBToAmp(mValue); -} - -void IParam::SetNormalized(double normalizedValue) -{ - mValue = FromNormalizedParam(normalizedValue, mMin, mMax, mShape); - if (mType != kTypeDouble) { - mValue = floor(0.5 + mValue / mStep) * mStep; - } - mValue = MIN(mValue, mMax); -} - -double IParam::GetNormalized() -{ - return GetNormalized(mValue); -} - -double IParam::GetNormalized(double nonNormalizedValue) -{ - nonNormalizedValue = BOUNDED(nonNormalizedValue, mMin, mMax); - return ToNormalizedParam(nonNormalizedValue, mMin, mMax, mShape); -} - -void IParam::GetDisplayForHost(double value, bool normalized, char* rDisplay) -{ - if (normalized) { - value = FromNormalizedParam(value, mMin, mMax, mShape); - } - - const char* displayText = GetDisplayText((int) value); - if (CSTR_NOT_EMPTY(displayText)) { - strcpy(rDisplay, displayText); - return; - } - - double displayValue = value; - if (mNegateDisplay) { - displayValue = -displayValue; - } - - if (displayValue == 0.0) { - strcpy(rDisplay, "0"); - } - else - if (mDisplayPrecision == 0) { - sprintf(rDisplay, "%d", int(displayValue)); - } - else { - char fmt[16]; - sprintf(fmt, "%%.%df", mDisplayPrecision); - sprintf(rDisplay, fmt, displayValue); - } -} - -const char* IParam::GetNameForHost() -{ - return mName; -} - -const char* IParam::GetLabelForHost() -{ - return mLabel; -} - -int IParam::GetNDisplayTexts() -{ - return mDisplayTexts.GetSize(); -} - -const char* IParam::GetDisplayText(int value) -{ - int n = mDisplayTexts.GetSize(); - if (n) { - DisplayText* pDT = mDisplayTexts.Get(); - for (int i = 0; i < n; ++i, ++pDT) { - if (value == pDT->mValue) { - return pDT->mText; - } - } - } - return ""; -} - -bool IParam::MapDisplayText(char* str, int* pValue) -{ - int n = mDisplayTexts.GetSize(); - if (n) { - DisplayText* pDT = mDisplayTexts.Get(); - for (int i = 0; i < n; ++i, ++pDT) { - if (!strcmp(str, pDT->mText)) { - *pValue = pDT->mValue; - return true; - } - } - } - return false; -} - -void IParam::GetBounds(double* pMin, double* pMax) -{ - *pMin = mMin; - *pMax = mMax; -} \ No newline at end of file diff --git a/WDL/IPlug/IParam.h b/WDL/IPlug/IParam.h deleted file mode 100644 index 5450f89f..00000000 --- a/WDL/IPlug/IParam.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _IPARAM_ -#define _IPARAM_ - -#include "Containers.h" -#include - -const int MAX_PARAM_NAME_LEN = 32; - -inline double ToNormalizedParam(double nonNormalizedValue, double min, double max, double shape) -{ - return pow((nonNormalizedValue - min) / (max - min), 1.0 / shape); -} - -inline double FromNormalizedParam(double normalizedValue, double min, double max, double shape) -{ - return min + pow((double) normalizedValue, shape) * (max - min); -} - -class IParam -{ -public: - - enum EParamType { kTypeNone, kTypeBool, kTypeInt, kTypeEnum, kTypeDouble }; - - IParam(); - ~IParam(); - - EParamType Type() { return mType; } - - void InitBool(const char* name, bool defaultVal, const char* label = ""); - void InitEnum(const char* name, int defaultVal, int nEnums); - void InitInt(const char* name, int defaultVal, int minVal, int maxVal, const char* label = ""); - void InitDouble(const char* name, double defaultVal, double minVal, double maxVal, double step, const char* label = ""); - - void Set(double value) { mValue = BOUNDED(value, mMin, mMax); } - void SetDisplayText(int value, const char* text); - - // The higher the shape, the more resolution around host value zero. - void SetShape(double shape); - - // Call this if your param is (x, y) but you want to always display (-x, -y). - void NegateDisplay() { mNegateDisplay = true; } - bool DisplayIsNegated() const { return mNegateDisplay; } - - // Accessors / converters. - // These all return the readable value, not the VST (0,1). - double Value() const { return mValue; } - bool Bool() const { return (mValue >= 0.5); } - int Int() const { return int(mValue); } - double DBToAmp(); - - void SetNormalized(double normalizedValue); - double GetNormalized(); - double GetNormalized(double nonNormalizedValue); - void GetDisplayForHost(char* rDisplay) { GetDisplayForHost(mValue, false, rDisplay); } - void GetDisplayForHost(double value, bool normalized, char* rDisplay); - const char* GetNameForHost(); - const char* GetLabelForHost(); - - int GetNDisplayTexts(); - const char* GetDisplayText(int value); - bool MapDisplayText(char* str, int* pValue); // Reverse map back to value. - void GetBounds(double* pMin, double* pMax); - -private: - - // All we store is the readable values. - // SetFromHost() and GetForHost() handle conversion from/to (0,1). - EParamType mType; - double mValue, mMin, mMax, mStep, mShape; - int mDisplayPrecision; - char mName[MAX_PARAM_NAME_LEN], mLabel[MAX_PARAM_NAME_LEN]; - bool mNegateDisplay; - - struct DisplayText { - int mValue; - char mText[MAX_PARAM_NAME_LEN]; - }; - WDL_TypedBuf mDisplayTexts; -}; - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug.sln b/WDL/IPlug/IPlug.sln deleted file mode 100644 index be221b88..00000000 --- a/WDL/IPlug/IPlug.sln +++ /dev/null @@ -1,39 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IPlugExample", "Example\IPlugExample.vcproj", "{D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IPlug", "IPlug.vcproj", "{D744660A-89B6-4EA7-A085-BF92ABE4540F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lice", "lice.vcproj", "{141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - Tracer|Win32 = Tracer|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Debug|Win32.ActiveCfg = Debug|Win32 - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Debug|Win32.Build.0 = Debug|Win32 - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Release|Win32.ActiveCfg = Release|Win32 - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Release|Win32.Build.0 = Release|Win32 - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Tracer|Win32.ActiveCfg = Tracer|Win32 - {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Tracer|Win32.Build.0 = Tracer|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Debug|Win32.Build.0 = Debug|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Release|Win32.ActiveCfg = Release|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Release|Win32.Build.0 = Release|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Tracer|Win32.ActiveCfg = Tracer|Win32 - {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Tracer|Win32.Build.0 = Tracer|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Debug|Win32.ActiveCfg = Debug|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Debug|Win32.Build.0 = Debug|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Release|Win32.ActiveCfg = Release|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Release|Win32.Build.0 = Release|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Tracer|Win32.ActiveCfg = Release|Win32 - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Tracer|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/WDL/IPlug/IPlug.vcproj b/WDL/IPlug/IPlug.vcproj deleted file mode 100644 index 16e966b0..00000000 --- a/WDL/IPlug/IPlug.vcproj +++ /dev/null @@ -1,350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/WDL/IPlug/IPlug.vcxproj b/WDL/IPlug/IPlug.vcxproj deleted file mode 100644 index 7c4564b8..00000000 --- a/WDL/IPlug/IPlug.vcxproj +++ /dev/null @@ -1,213 +0,0 @@ - - - - Debug - Win32 - - - Debug - X64 - - - Release - Win32 - - - Release - X64 - - - Tracer - Win32 - - - Tracer - X64 - - - - {D744660A-89B6-4EA7-A085-BF92ABE4540F} - Win32Proj - - - - StaticLibrary - MultiByte - - - StaticLibrary - MultiByte - false - - - StaticLibrary - MultiByte - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.20506.1 - $(Platform)/$(Configuration)/ - $(Platform)/$(Configuration)/ - IPlug - .lib - $(Platform)/$(Configuration)/ - $(Platform)/$(Configuration)/ - IPlug - .lib - $(Platform)/$(Configuration)/ - $(Platform)/$(Configuration)/ - IPlug - .lib - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - - - - Disabled - %(AdditionalIncludeDirectories) - WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - false - - - Level3 - EditAndContinue - - - lice.lib;wininet.lib;%(AdditionalDependencies) - %(IgnoreSpecificDefaultLibraries) - ../lice/$(Platform)/$(Configuration) - - - - - MaxSpeed - AnySuitable - true - Speed - false - %(AdditionalIncludeDirectories) - WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreaded - false - StreamingSIMDExtensions2 - Fast - false - - - Level3 - ProgramDatabase - true - - - lice.lib;wininet.lib;%(AdditionalDependencies) - ../lice/$(Platform)/$(Configuration) - - - - - MaxSpeed - %(AdditionalIncludeDirectories) - TRACER_BUILD;WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - lice.lib;wininet.lib;%(AdditionalDependencies) - ../lice/$(Platform)/$(Configuration) - - - - - StreamingSIMDExtensions2 - Fast - true - Speed - true - - - wininet.lib;lice.lib - ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) - - - - - ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) - wininet.lib;lice.lib - - - true - - - - - ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) - wininet.lib;lice.lib - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/WDL/IPlug/IPlug.xcodeproj/project.pbxproj b/WDL/IPlug/IPlug.xcodeproj/project.pbxproj deleted file mode 100644 index 441fd7c5..00000000 --- a/WDL/IPlug/IPlug.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1009 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 44; - objects = { - -/* Begin PBXBuildFile section */ - 452A87500FCBFE1900360071 /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A874E0FCBFE1900360071 /* aeffect.h */; }; - 452A87510FCBFE1900360071 /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A874F0FCBFE1900360071 /* aeffectx.h */; }; - 452A87830FCBFFDD00360071 /* lice_arc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87670FCBFFDD00360071 /* lice_arc.cpp */; }; - 452A87840FCBFFDD00360071 /* lice_bezier.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87680FCBFFDD00360071 /* lice_bezier.h */; }; - 452A87850FCBFFDD00360071 /* lice_bmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87690FCBFFDD00360071 /* lice_bmp.cpp */; }; - 452A87860FCBFFDD00360071 /* lice_colorspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */; }; - 452A87870FCBFFDD00360071 /* lice_combine.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A876B0FCBFFDD00360071 /* lice_combine.h */; }; - 452A87880FCBFFDD00360071 /* lice_extended.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A876C0FCBFFDD00360071 /* lice_extended.h */; }; - 452A878F0FCBFFDD00360071 /* lice_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87730FCBFFDD00360071 /* lice_image.cpp */; }; - 452A87900FCBFFDD00360071 /* lice_jpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87740FCBFFDD00360071 /* lice_jpg.cpp */; }; - 452A87910FCBFFDD00360071 /* lice_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87750FCBFFDD00360071 /* lice_line.cpp */; }; - 452A87940FCBFFDD00360071 /* lice_png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87780FCBFFDD00360071 /* lice_png.cpp */; }; - 452A87970FCBFFDD00360071 /* lice_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877B0FCBFFDD00360071 /* lice_text.cpp */; }; - 452A87980FCBFFDD00360071 /* lice_text.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A877C0FCBFFDD00360071 /* lice_text.h */; }; - 452A87990FCBFFDD00360071 /* lice_textnew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */; }; - 452A879A0FCBFFDD00360071 /* lice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877E0FCBFFDD00360071 /* lice.cpp */; }; - 452A879B0FCBFFDD00360071 /* lice.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87810FCBFFDD00360071 /* lice.h */; }; - 452A87A50FCC004600360071 /* swell.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87A40FCC004600360071 /* swell.h */; }; - 452A89060FCC0A2D00360071 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88ED0FCC0A2D00360071 /* adler32.c */; }; - 452A89070FCC0A2D00360071 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88EE0FCC0A2D00360071 /* compress.c */; }; - 452A89080FCC0A2D00360071 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88EF0FCC0A2D00360071 /* crc32.c */; }; - 452A89090FCC0A2D00360071 /* crc32.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F00FCC0A2D00360071 /* crc32.h */; }; - 452A890A0FCC0A2D00360071 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F10FCC0A2D00360071 /* deflate.c */; }; - 452A890B0FCC0A2D00360071 /* deflate.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F20FCC0A2D00360071 /* deflate.h */; }; - 452A890D0FCC0A2D00360071 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F40FCC0A2D00360071 /* infback.c */; }; - 452A890E0FCC0A2D00360071 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F50FCC0A2D00360071 /* inffast.c */; }; - 452A890F0FCC0A2D00360071 /* inffast.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F60FCC0A2D00360071 /* inffast.h */; }; - 452A89100FCC0A2D00360071 /* inffixed.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F70FCC0A2D00360071 /* inffixed.h */; }; - 452A89110FCC0A2D00360071 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F80FCC0A2D00360071 /* inflate.c */; }; - 452A89120FCC0A2D00360071 /* inflate.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F90FCC0A2D00360071 /* inflate.h */; }; - 452A89130FCC0A2D00360071 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FA0FCC0A2D00360071 /* inftrees.c */; }; - 452A89140FCC0A2D00360071 /* inftrees.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88FB0FCC0A2D00360071 /* inftrees.h */; }; - 452A89150FCC0A2D00360071 /* minigzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FC0FCC0A2D00360071 /* minigzip.c */; }; - 452A89160FCC0A2D00360071 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FD0FCC0A2D00360071 /* trees.c */; }; - 452A89170FCC0A2D00360071 /* trees.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88FE0FCC0A2D00360071 /* trees.h */; }; - 452A89180FCC0A2D00360071 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FF0FCC0A2D00360071 /* uncompr.c */; }; - 452A89190FCC0A2D00360071 /* zconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89000FCC0A2D00360071 /* zconf.h */; }; - 452A891A0FCC0A2D00360071 /* zconf.in.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89010FCC0A2D00360071 /* zconf.in.h */; }; - 452A891B0FCC0A2D00360071 /* zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89020FCC0A2D00360071 /* zlib.h */; }; - 452A891C0FCC0A2D00360071 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89030FCC0A2D00360071 /* zutil.c */; }; - 452A891D0FCC0A2D00360071 /* zutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89040FCC0A2D00360071 /* zutil.h */; }; - 452A891E0FCC0A2D00360071 /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89050FCC0A2D00360071 /* gzio.c */; }; - 452A895D0FCC0A4C00360071 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89220FCC0A4C00360071 /* jcapimin.c */; }; - 452A895E0FCC0A4C00360071 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89230FCC0A4C00360071 /* jcapistd.c */; }; - 452A895F0FCC0A4C00360071 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89240FCC0A4C00360071 /* jccoefct.c */; }; - 452A89600FCC0A4C00360071 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89250FCC0A4C00360071 /* jccolor.c */; }; - 452A89610FCC0A4C00360071 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89260FCC0A4C00360071 /* jcdctmgr.c */; }; - 452A89620FCC0A4C00360071 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89270FCC0A4C00360071 /* jchuff.c */; }; - 452A89630FCC0A4C00360071 /* jchuff.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89280FCC0A4C00360071 /* jchuff.h */; }; - 452A89640FCC0A4C00360071 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89290FCC0A4C00360071 /* jcinit.c */; }; - 452A89650FCC0A4C00360071 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892A0FCC0A4C00360071 /* jcmainct.c */; }; - 452A89660FCC0A4C00360071 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892B0FCC0A4C00360071 /* jcmarker.c */; }; - 452A89670FCC0A4C00360071 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892C0FCC0A4C00360071 /* jcmaster.c */; }; - 452A89680FCC0A4C00360071 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892D0FCC0A4C00360071 /* jcomapi.c */; }; - 452A89690FCC0A4C00360071 /* jconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A892E0FCC0A4C00360071 /* jconfig.h */; }; - 452A896A0FCC0A4C00360071 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892F0FCC0A4C00360071 /* jcparam.c */; }; - 452A896B0FCC0A4C00360071 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89300FCC0A4C00360071 /* jcphuff.c */; }; - 452A896C0FCC0A4C00360071 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89310FCC0A4C00360071 /* jcprepct.c */; }; - 452A896D0FCC0A4C00360071 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89320FCC0A4C00360071 /* jcsample.c */; }; - 452A896E0FCC0A4C00360071 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89330FCC0A4C00360071 /* jctrans.c */; }; - 452A896F0FCC0A4C00360071 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89340FCC0A4C00360071 /* jdapimin.c */; }; - 452A89700FCC0A4C00360071 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89350FCC0A4C00360071 /* jdapistd.c */; }; - 452A89710FCC0A4C00360071 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89360FCC0A4C00360071 /* jdatadst.c */; }; - 452A89720FCC0A4C00360071 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89370FCC0A4C00360071 /* jdatasrc.c */; }; - 452A89730FCC0A4C00360071 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89380FCC0A4C00360071 /* jdcoefct.c */; }; - 452A89740FCC0A4C00360071 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89390FCC0A4C00360071 /* jdcolor.c */; }; - 452A89750FCC0A4C00360071 /* jdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A893A0FCC0A4C00360071 /* jdct.h */; }; - 452A89760FCC0A4C00360071 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893B0FCC0A4C00360071 /* jddctmgr.c */; }; - 452A89770FCC0A4C00360071 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893C0FCC0A4C00360071 /* jdhuff.c */; }; - 452A89780FCC0A4C00360071 /* jdhuff.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A893D0FCC0A4C00360071 /* jdhuff.h */; }; - 452A89790FCC0A4C00360071 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893E0FCC0A4C00360071 /* jdinput.c */; }; - 452A897A0FCC0A4C00360071 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893F0FCC0A4C00360071 /* jdmainct.c */; }; - 452A897B0FCC0A4C00360071 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89400FCC0A4C00360071 /* jdmarker.c */; }; - 452A897C0FCC0A4C00360071 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89410FCC0A4C00360071 /* jdmaster.c */; }; - 452A897D0FCC0A4C00360071 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89420FCC0A4C00360071 /* jdmerge.c */; }; - 452A897E0FCC0A4C00360071 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89430FCC0A4C00360071 /* jdphuff.c */; }; - 452A897F0FCC0A4C00360071 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89440FCC0A4C00360071 /* jdpostct.c */; }; - 452A89800FCC0A4C00360071 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89450FCC0A4C00360071 /* jdsample.c */; }; - 452A89810FCC0A4C00360071 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89460FCC0A4C00360071 /* jdtrans.c */; }; - 452A89820FCC0A4C00360071 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89470FCC0A4C00360071 /* jerror.c */; }; - 452A89830FCC0A4C00360071 /* jerror.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89480FCC0A4C00360071 /* jerror.h */; }; - 452A89840FCC0A4C00360071 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89490FCC0A4C00360071 /* jfdctflt.c */; }; - 452A89850FCC0A4C00360071 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894A0FCC0A4C00360071 /* jfdctfst.c */; }; - 452A89860FCC0A4C00360071 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894B0FCC0A4C00360071 /* jfdctint.c */; }; - 452A89870FCC0A4C00360071 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894C0FCC0A4C00360071 /* jidctflt.c */; }; - 452A89880FCC0A4C00360071 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894D0FCC0A4C00360071 /* jidctfst.c */; }; - 452A89890FCC0A4C00360071 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894E0FCC0A4C00360071 /* jidctint.c */; }; - 452A898A0FCC0A4C00360071 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894F0FCC0A4C00360071 /* jidctred.c */; }; - 452A898B0FCC0A4C00360071 /* jinclude.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89500FCC0A4C00360071 /* jinclude.h */; }; - 452A898C0FCC0A4C00360071 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89510FCC0A4C00360071 /* jmemmgr.c */; }; - 452A898D0FCC0A4C00360071 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89520FCC0A4C00360071 /* jmemnobs.c */; }; - 452A898E0FCC0A4C00360071 /* jmemsys.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89530FCC0A4C00360071 /* jmemsys.h */; }; - 452A898F0FCC0A4C00360071 /* jmorecfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89540FCC0A4C00360071 /* jmorecfg.h */; }; - 452A89900FCC0A4C00360071 /* jpegint.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89550FCC0A4C00360071 /* jpegint.h */; }; - 452A89910FCC0A4C00360071 /* jpeglib.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89560FCC0A4C00360071 /* jpeglib.h */; }; - 452A89920FCC0A4C00360071 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89570FCC0A4C00360071 /* jquant1.c */; }; - 452A89930FCC0A4C00360071 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89580FCC0A4C00360071 /* jquant2.c */; }; - 452A89940FCC0A4C00360071 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89590FCC0A4C00360071 /* jutils.c */; }; - 452A89950FCC0A4C00360071 /* jversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A895A0FCC0A4C00360071 /* jversion.h */; }; - 452A89AA0FCC0A6500360071 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89960FCC0A6500360071 /* png.c */; }; - 452A89AB0FCC0A6500360071 /* png.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89970FCC0A6500360071 /* png.h */; }; - 452A89AC0FCC0A6500360071 /* pngconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89980FCC0A6500360071 /* pngconf.h */; }; - 452A89AD0FCC0A6500360071 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89990FCC0A6500360071 /* pngerror.c */; }; - 452A89AE0FCC0A6500360071 /* pnggccrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899A0FCC0A6500360071 /* pnggccrd.c */; }; - 452A89AF0FCC0A6500360071 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899B0FCC0A6500360071 /* pngget.c */; }; - 452A89B00FCC0A6500360071 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899C0FCC0A6500360071 /* pngmem.c */; }; - 452A89B10FCC0A6500360071 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899D0FCC0A6500360071 /* pngpread.c */; }; - 452A89B20FCC0A6500360071 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899E0FCC0A6500360071 /* pngread.c */; }; - 452A89B30FCC0A6500360071 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899F0FCC0A6500360071 /* pngrtran.c */; }; - 452A89B40FCC0A6500360071 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A00FCC0A6500360071 /* pngrutil.c */; }; - 452A89B50FCC0A6500360071 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A10FCC0A6500360071 /* pngset.c */; }; - 452A89B70FCC0A6500360071 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A30FCC0A6500360071 /* pngtrans.c */; }; - 452A89B80FCC0A6500360071 /* pngvcrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A40FCC0A6500360071 /* pngvcrd.c */; }; - 452A89B90FCC0A6500360071 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A50FCC0A6500360071 /* pngwio.c */; }; - 452A89BB0FCC0A6500360071 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A70FCC0A6500360071 /* pngwtran.c */; }; - 452A89BC0FCC0A6500360071 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A80FCC0A6500360071 /* pngwutil.c */; }; - 452A89BD0FCC0A6500360071 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A90FCC0A6500360071 /* pngrio.c */; }; - 452A8A030FCC0F4E00360071 /* swell-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A8A020FCC0F4E00360071 /* swell-internal.h */; }; - 45B61BC610B15E25009E1E8C /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45B61BC510B15E25009E1E8C /* swell-gdi.mm */; }; - 521F387F0D1704080060FE32 /* IPlug_include_in_plug_src.h in Headers */ = {isa = PBXBuildFile; fileRef = 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */; }; - 521F38800D1704080060FE32 /* IPlug_include_in_plug_hdr.h in Headers */ = {isa = PBXBuildFile; fileRef = 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */; }; - 52780D4C0D20A1A000C2BCA7 /* IGraphicsCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */; }; - 52A2156B0D11C1E4006341F0 /* Hosts.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A2156A0D11C1E4006341F0 /* Hosts.h */; }; - 52A2156D0D11C1EC006341F0 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A2156C0D11C1EC006341F0 /* Hosts.cpp */; }; - 52A215720D11C200006341F0 /* IPlugBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A2156E0D11C200006341F0 /* IPlugBase.h */; }; - 52A215730D11C200006341F0 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A2156F0D11C200006341F0 /* IPlugBase.cpp */; }; - 52A215780D11C20C006341F0 /* IPlugVST.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A215760D11C20C006341F0 /* IPlugVST.h */; }; - 52A215790D11C20C006341F0 /* IPlugVST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A215770D11C20C006341F0 /* IPlugVST.cpp */; }; - 52A4AB440D2BFA510042A248 /* IGraphicsCarbon.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */; }; - 52A4AB450D2BFA510042A248 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */; }; - 52C4DA4F0D0E50F90007A920 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DA4E0D0E50F90007A920 /* Carbon.framework */; }; - 52E41BA90D14C09E00A0943B /* IPlugAU.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E41BA70D14C09E00A0943B /* IPlugAU.h */; }; - 52E41BAA0D14C09E00A0943B /* IPlugAU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */; }; - 52FBBEA60D0CF0D3001C8B8A /* Containers.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE870D0CF0D3001C8B8A /* Containers.h */; }; - 52FBBEA70D0CF0D3001C8B8A /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */; }; - 52FBBEA80D0CF0D3001C8B8A /* IControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE890D0CF0D3001C8B8A /* IControl.h */; }; - 52FBBEA90D0CF0D3001C8B8A /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */; }; - 52FBBEAA0D0CF0D3001C8B8A /* IGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */; }; - 52FBBEAC0D0CF0D3001C8B8A /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */; }; - 52FBBEAD0D0CF0D3001C8B8A /* IGraphicsLice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */; }; - 52FBBEAE0D0CF0D3001C8B8A /* IGraphicsLice.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */; }; - 52FBBEB00D0CF0D3001C8B8A /* IGraphicsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */; }; - 52FBBEB10D0CF0D3001C8B8A /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */; }; - 52FBBEB50D0CF0D3001C8B8A /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */; }; - 52FBBEB60D0CF0D3001C8B8A /* IParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE970D0CF0D3001C8B8A /* IParam.h */; }; - 52FBBEBB0D0CF0D3001C8B8A /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */; }; - 52FBBEBC0D0CF0D3001C8B8A /* IPlugStructs.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */; }; - 52FBBEBD0D0CF0D3001C8B8A /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */; }; - 52FBBEBE0D0CF0D3001C8B8A /* Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBEA20D0CF0D3001C8B8A /* Log.h */; }; - D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 32DBCF5E0370ADEE00C91783 /* IPlug_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_Prefix.pch; sourceTree = ""; }; - 452A874E0FCBFE1900360071 /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffect.h; sourceTree = ""; }; - 452A874F0FCBFE1900360071 /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffectx.h; sourceTree = ""; }; - 452A87670FCBFFDD00360071 /* lice_arc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_arc.cpp; path = ../lice/lice_arc.cpp; sourceTree = SOURCE_ROOT; }; - 452A87680FCBFFDD00360071 /* lice_bezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_bezier.h; path = ../lice/lice_bezier.h; sourceTree = SOURCE_ROOT; }; - 452A87690FCBFFDD00360071 /* lice_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_bmp.cpp; path = ../lice/lice_bmp.cpp; sourceTree = SOURCE_ROOT; }; - 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_colorspace.cpp; path = ../lice/lice_colorspace.cpp; sourceTree = SOURCE_ROOT; }; - 452A876B0FCBFFDD00360071 /* lice_combine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_combine.h; path = ../lice/lice_combine.h; sourceTree = SOURCE_ROOT; }; - 452A876C0FCBFFDD00360071 /* lice_extended.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_extended.h; path = ../lice/lice_extended.h; sourceTree = SOURCE_ROOT; }; - 452A87730FCBFFDD00360071 /* lice_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_image.cpp; path = ../lice/lice_image.cpp; sourceTree = SOURCE_ROOT; }; - 452A87740FCBFFDD00360071 /* lice_jpg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg.cpp; path = ../lice/lice_jpg.cpp; sourceTree = SOURCE_ROOT; }; - 452A87750FCBFFDD00360071 /* lice_line.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_line.cpp; path = ../lice/lice_line.cpp; sourceTree = SOURCE_ROOT; }; - 452A87780FCBFFDD00360071 /* lice_png.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png.cpp; path = ../lice/lice_png.cpp; sourceTree = SOURCE_ROOT; }; - 452A877B0FCBFFDD00360071 /* lice_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_text.cpp; path = ../lice/lice_text.cpp; sourceTree = SOURCE_ROOT; }; - 452A877C0FCBFFDD00360071 /* lice_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_text.h; path = ../lice/lice_text.h; sourceTree = SOURCE_ROOT; }; - 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_textnew.cpp; path = ../lice/lice_textnew.cpp; sourceTree = SOURCE_ROOT; }; - 452A877E0FCBFFDD00360071 /* lice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice.cpp; path = ../lice/lice.cpp; sourceTree = SOURCE_ROOT; }; - 452A87810FCBFFDD00360071 /* lice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice.h; path = ../lice/lice.h; sourceTree = SOURCE_ROOT; }; - 452A87A40FCC004600360071 /* swell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swell.h; path = ../swell/swell.h; sourceTree = SOURCE_ROOT; }; - 452A88ED0FCC0A2D00360071 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ../zlib/adler32.c; sourceTree = SOURCE_ROOT; }; - 452A88EE0FCC0A2D00360071 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ../zlib/compress.c; sourceTree = SOURCE_ROOT; }; - 452A88EF0FCC0A2D00360071 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ../zlib/crc32.c; sourceTree = SOURCE_ROOT; }; - 452A88F00FCC0A2D00360071 /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = ../zlib/crc32.h; sourceTree = SOURCE_ROOT; }; - 452A88F10FCC0A2D00360071 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ../zlib/deflate.c; sourceTree = SOURCE_ROOT; }; - 452A88F20FCC0A2D00360071 /* deflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = deflate.h; path = ../zlib/deflate.h; sourceTree = SOURCE_ROOT; }; - 452A88F40FCC0A2D00360071 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ../zlib/infback.c; sourceTree = SOURCE_ROOT; }; - 452A88F50FCC0A2D00360071 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../zlib/inffast.c; sourceTree = SOURCE_ROOT; }; - 452A88F60FCC0A2D00360071 /* inffast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffast.h; path = ../zlib/inffast.h; sourceTree = SOURCE_ROOT; }; - 452A88F70FCC0A2D00360071 /* inffixed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffixed.h; path = ../zlib/inffixed.h; sourceTree = SOURCE_ROOT; }; - 452A88F80FCC0A2D00360071 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ../zlib/inflate.c; sourceTree = SOURCE_ROOT; }; - 452A88F90FCC0A2D00360071 /* inflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inflate.h; path = ../zlib/inflate.h; sourceTree = SOURCE_ROOT; }; - 452A88FA0FCC0A2D00360071 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ../zlib/inftrees.c; sourceTree = SOURCE_ROOT; }; - 452A88FB0FCC0A2D00360071 /* inftrees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inftrees.h; path = ../zlib/inftrees.h; sourceTree = SOURCE_ROOT; }; - 452A88FC0FCC0A2D00360071 /* minigzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minigzip.c; path = ../zlib/minigzip.c; sourceTree = SOURCE_ROOT; }; - 452A88FD0FCC0A2D00360071 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ../zlib/trees.c; sourceTree = SOURCE_ROOT; }; - 452A88FE0FCC0A2D00360071 /* trees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = trees.h; path = ../zlib/trees.h; sourceTree = SOURCE_ROOT; }; - 452A88FF0FCC0A2D00360071 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ../zlib/uncompr.c; sourceTree = SOURCE_ROOT; }; - 452A89000FCC0A2D00360071 /* zconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zconf.h; path = ../zlib/zconf.h; sourceTree = SOURCE_ROOT; }; - 452A89010FCC0A2D00360071 /* zconf.in.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zconf.in.h; path = ../zlib/zconf.in.h; sourceTree = SOURCE_ROOT; }; - 452A89020FCC0A2D00360071 /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = ../zlib/zlib.h; sourceTree = SOURCE_ROOT; }; - 452A89030FCC0A2D00360071 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ../zlib/zutil.c; sourceTree = SOURCE_ROOT; }; - 452A89040FCC0A2D00360071 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = ../zlib/zutil.h; sourceTree = SOURCE_ROOT; }; - 452A89050FCC0A2D00360071 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzio.c; path = ../zlib/gzio.c; sourceTree = SOURCE_ROOT; }; - 452A89220FCC0A4C00360071 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../jpeglib/jcapimin.c; sourceTree = SOURCE_ROOT; }; - 452A89230FCC0A4C00360071 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../jpeglib/jcapistd.c; sourceTree = SOURCE_ROOT; }; - 452A89240FCC0A4C00360071 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../jpeglib/jccoefct.c; sourceTree = SOURCE_ROOT; }; - 452A89250FCC0A4C00360071 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../jpeglib/jccolor.c; sourceTree = SOURCE_ROOT; }; - 452A89260FCC0A4C00360071 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../jpeglib/jcdctmgr.c; sourceTree = SOURCE_ROOT; }; - 452A89270FCC0A4C00360071 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../jpeglib/jchuff.c; sourceTree = SOURCE_ROOT; }; - 452A89280FCC0A4C00360071 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../jpeglib/jchuff.h; sourceTree = SOURCE_ROOT; }; - 452A89290FCC0A4C00360071 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../jpeglib/jcinit.c; sourceTree = SOURCE_ROOT; }; - 452A892A0FCC0A4C00360071 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../jpeglib/jcmainct.c; sourceTree = SOURCE_ROOT; }; - 452A892B0FCC0A4C00360071 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../jpeglib/jcmarker.c; sourceTree = SOURCE_ROOT; }; - 452A892C0FCC0A4C00360071 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../jpeglib/jcmaster.c; sourceTree = SOURCE_ROOT; }; - 452A892D0FCC0A4C00360071 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../jpeglib/jcomapi.c; sourceTree = SOURCE_ROOT; }; - 452A892E0FCC0A4C00360071 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../jpeglib/jconfig.h; sourceTree = SOURCE_ROOT; }; - 452A892F0FCC0A4C00360071 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../jpeglib/jcparam.c; sourceTree = SOURCE_ROOT; }; - 452A89300FCC0A4C00360071 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../jpeglib/jcphuff.c; sourceTree = SOURCE_ROOT; }; - 452A89310FCC0A4C00360071 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../jpeglib/jcprepct.c; sourceTree = SOURCE_ROOT; }; - 452A89320FCC0A4C00360071 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../jpeglib/jcsample.c; sourceTree = SOURCE_ROOT; }; - 452A89330FCC0A4C00360071 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../jpeglib/jctrans.c; sourceTree = SOURCE_ROOT; }; - 452A89340FCC0A4C00360071 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../jpeglib/jdapimin.c; sourceTree = SOURCE_ROOT; }; - 452A89350FCC0A4C00360071 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../jpeglib/jdapistd.c; sourceTree = SOURCE_ROOT; }; - 452A89360FCC0A4C00360071 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../jpeglib/jdatadst.c; sourceTree = SOURCE_ROOT; }; - 452A89370FCC0A4C00360071 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../jpeglib/jdatasrc.c; sourceTree = SOURCE_ROOT; }; - 452A89380FCC0A4C00360071 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../jpeglib/jdcoefct.c; sourceTree = SOURCE_ROOT; }; - 452A89390FCC0A4C00360071 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../jpeglib/jdcolor.c; sourceTree = SOURCE_ROOT; }; - 452A893A0FCC0A4C00360071 /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jdct.h; path = ../jpeglib/jdct.h; sourceTree = SOURCE_ROOT; }; - 452A893B0FCC0A4C00360071 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../jpeglib/jddctmgr.c; sourceTree = SOURCE_ROOT; }; - 452A893C0FCC0A4C00360071 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../jpeglib/jdhuff.c; sourceTree = SOURCE_ROOT; }; - 452A893D0FCC0A4C00360071 /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jdhuff.h; path = ../jpeglib/jdhuff.h; sourceTree = SOURCE_ROOT; }; - 452A893E0FCC0A4C00360071 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../jpeglib/jdinput.c; sourceTree = SOURCE_ROOT; }; - 452A893F0FCC0A4C00360071 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../jpeglib/jdmainct.c; sourceTree = SOURCE_ROOT; }; - 452A89400FCC0A4C00360071 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../jpeglib/jdmarker.c; sourceTree = SOURCE_ROOT; }; - 452A89410FCC0A4C00360071 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../jpeglib/jdmaster.c; sourceTree = SOURCE_ROOT; }; - 452A89420FCC0A4C00360071 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../jpeglib/jdmerge.c; sourceTree = SOURCE_ROOT; }; - 452A89430FCC0A4C00360071 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../jpeglib/jdphuff.c; sourceTree = SOURCE_ROOT; }; - 452A89440FCC0A4C00360071 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../jpeglib/jdpostct.c; sourceTree = SOURCE_ROOT; }; - 452A89450FCC0A4C00360071 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../jpeglib/jdsample.c; sourceTree = SOURCE_ROOT; }; - 452A89460FCC0A4C00360071 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../jpeglib/jdtrans.c; sourceTree = SOURCE_ROOT; }; - 452A89470FCC0A4C00360071 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../jpeglib/jerror.c; sourceTree = SOURCE_ROOT; }; - 452A89480FCC0A4C00360071 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../jpeglib/jerror.h; sourceTree = SOURCE_ROOT; }; - 452A89490FCC0A4C00360071 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../jpeglib/jfdctflt.c; sourceTree = SOURCE_ROOT; }; - 452A894A0FCC0A4C00360071 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../jpeglib/jfdctfst.c; sourceTree = SOURCE_ROOT; }; - 452A894B0FCC0A4C00360071 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../jpeglib/jfdctint.c; sourceTree = SOURCE_ROOT; }; - 452A894C0FCC0A4C00360071 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../jpeglib/jidctflt.c; sourceTree = SOURCE_ROOT; }; - 452A894D0FCC0A4C00360071 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../jpeglib/jidctfst.c; sourceTree = SOURCE_ROOT; }; - 452A894E0FCC0A4C00360071 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../jpeglib/jidctint.c; sourceTree = SOURCE_ROOT; }; - 452A894F0FCC0A4C00360071 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../jpeglib/jidctred.c; sourceTree = SOURCE_ROOT; }; - 452A89500FCC0A4C00360071 /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jinclude.h; path = ../jpeglib/jinclude.h; sourceTree = SOURCE_ROOT; }; - 452A89510FCC0A4C00360071 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../jpeglib/jmemmgr.c; sourceTree = SOURCE_ROOT; }; - 452A89520FCC0A4C00360071 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../jpeglib/jmemnobs.c; sourceTree = SOURCE_ROOT; }; - 452A89530FCC0A4C00360071 /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jmemsys.h; path = ../jpeglib/jmemsys.h; sourceTree = SOURCE_ROOT; }; - 452A89540FCC0A4C00360071 /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jmorecfg.h; path = ../jpeglib/jmorecfg.h; sourceTree = SOURCE_ROOT; }; - 452A89550FCC0A4C00360071 /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jpegint.h; path = ../jpeglib/jpegint.h; sourceTree = SOURCE_ROOT; }; - 452A89560FCC0A4C00360071 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../jpeglib/jpeglib.h; sourceTree = SOURCE_ROOT; }; - 452A89570FCC0A4C00360071 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../jpeglib/jquant1.c; sourceTree = SOURCE_ROOT; }; - 452A89580FCC0A4C00360071 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../jpeglib/jquant2.c; sourceTree = SOURCE_ROOT; }; - 452A89590FCC0A4C00360071 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../jpeglib/jutils.c; sourceTree = SOURCE_ROOT; }; - 452A895A0FCC0A4C00360071 /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jversion.h; path = ../jpeglib/jversion.h; sourceTree = SOURCE_ROOT; }; - 452A89960FCC0A6500360071 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../libpng/png.c; sourceTree = SOURCE_ROOT; }; - 452A89970FCC0A6500360071 /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = png.h; path = ../libpng/png.h; sourceTree = SOURCE_ROOT; }; - 452A89980FCC0A6500360071 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = ../libpng/pngconf.h; sourceTree = SOURCE_ROOT; }; - 452A89990FCC0A6500360071 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../libpng/pngerror.c; sourceTree = SOURCE_ROOT; }; - 452A899A0FCC0A6500360071 /* pnggccrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pnggccrd.c; path = ../libpng/pnggccrd.c; sourceTree = SOURCE_ROOT; }; - 452A899B0FCC0A6500360071 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../libpng/pngget.c; sourceTree = SOURCE_ROOT; }; - 452A899C0FCC0A6500360071 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../libpng/pngmem.c; sourceTree = SOURCE_ROOT; }; - 452A899D0FCC0A6500360071 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../libpng/pngpread.c; sourceTree = SOURCE_ROOT; }; - 452A899E0FCC0A6500360071 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../libpng/pngread.c; sourceTree = SOURCE_ROOT; }; - 452A899F0FCC0A6500360071 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; }; - 452A89A00FCC0A6500360071 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; }; - 452A89A10FCC0A6500360071 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../libpng/pngset.c; sourceTree = SOURCE_ROOT; }; - 452A89A30FCC0A6500360071 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; }; - 452A89A40FCC0A6500360071 /* pngvcrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngvcrd.c; path = ../libpng/pngvcrd.c; sourceTree = SOURCE_ROOT; }; - 452A89A50FCC0A6500360071 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../libpng/pngwio.c; sourceTree = SOURCE_ROOT; }; - 452A89A70FCC0A6500360071 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; }; - 452A89A80FCC0A6500360071 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; }; - 452A89A90FCC0A6500360071 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../libpng/pngrio.c; sourceTree = SOURCE_ROOT; }; - 452A8A020FCC0F4E00360071 /* swell-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-internal.h"; path = "../swell/swell-internal.h"; sourceTree = SOURCE_ROOT; }; - 45B61BC510B15E25009E1E8C /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../swell/swell-gdi.mm"; sourceTree = SOURCE_ROOT; }; - 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_include_in_plug_src.h; sourceTree = ""; }; - 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_include_in_plug_hdr.h; sourceTree = ""; }; - 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsCocoa.h; sourceTree = ""; }; - 52A2156A0D11C1E4006341F0 /* Hosts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hosts.h; sourceTree = ""; }; - 52A2156C0D11C1EC006341F0 /* Hosts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hosts.cpp; sourceTree = ""; }; - 52A2156E0D11C200006341F0 /* IPlugBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugBase.h; sourceTree = ""; }; - 52A2156F0D11C200006341F0 /* IPlugBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugBase.cpp; sourceTree = ""; }; - 52A215760D11C20C006341F0 /* IPlugVST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugVST.h; sourceTree = ""; }; - 52A215770D11C20C006341F0 /* IPlugVST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugVST.cpp; sourceTree = ""; }; - 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsCarbon.h; sourceTree = ""; }; - 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphicsCarbon.cpp; sourceTree = ""; }; - 52C4DA4E0D0E50F90007A920 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 52E41BA70D14C09E00A0943B /* IPlugAU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugAU.h; sourceTree = ""; }; - 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugAU.cpp; sourceTree = ""; }; - 52FBBE870D0CF0D3001C8B8A /* Containers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Containers.h; sourceTree = ""; }; - 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IControl.cpp; sourceTree = ""; }; - 52FBBE890D0CF0D3001C8B8A /* IControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IControl.h; sourceTree = ""; }; - 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphics.cpp; sourceTree = ""; }; - 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphics.h; sourceTree = ""; }; - 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IGraphicsCocoa.mm; sourceTree = ""; }; - 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphicsLice.cpp; sourceTree = ""; }; - 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsLice.h; sourceTree = ""; }; - 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsMac.h; sourceTree = ""; }; - 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IGraphicsMac.mm; sourceTree = ""; }; - 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IParam.cpp; sourceTree = ""; }; - 52FBBE970D0CF0D3001C8B8A /* IParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IParam.h; sourceTree = ""; }; - 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugStructs.cpp; sourceTree = ""; }; - 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugStructs.h; sourceTree = ""; }; - 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Log.cpp; sourceTree = ""; }; - 52FBBEA20D0CF0D3001C8B8A /* Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = ""; }; - D2AAC07E0554694100DB518D /* libIPlug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPlug.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D2F7E8BE07B2D77200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D2AAC07C0554694100DB518D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */, - 52C4DA4F0D0E50F90007A920 /* Carbon.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DFFF38A50411DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - D2AAC07E0554694100DB518D /* libIPlug.a */, - ); - name = Products; - sourceTree = ""; - }; - 0867D691FE84028FC02AAC07 /* IPlug */ = { - isa = PBXGroup; - children = ( - 452A875D0FCBFF5B00360071 /* LICE */, - 452A874D0FCBFE1900360071 /* VST_SDK */, - 52FBBE770D0CF0D3001C8B8A /* IPlug */, - 08FB77AEFE84172EC02AAC07 /* Classes */, - 32C88DFF0371C24200C91783 /* Other Sources */, - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, - 034768DFFF38A50411DB9C8B /* Products */, - ); - name = IPlug; - sourceTree = ""; - }; - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, - 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, - ); - name = "External Frameworks and Libraries"; - sourceTree = ""; - }; - 08FB77AEFE84172EC02AAC07 /* Classes */ = { - isa = PBXGroup; - children = ( - ); - name = Classes; - sourceTree = ""; - }; - 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 52C4DA4E0D0E50F90007A920 /* Carbon.framework */, - 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 0867D6A5FE840307C02AAC07 /* AppKit.framework */, - D2F7E8BE07B2D77200F64583 /* CoreData.framework */, - 0867D69BFE84028FC02AAC07 /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 32C88DFF0371C24200C91783 /* Other Sources */ = { - isa = PBXGroup; - children = ( - 32DBCF5E0370ADEE00C91783 /* IPlug_Prefix.pch */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 452A874D0FCBFE1900360071 /* VST_SDK */ = { - isa = PBXGroup; - children = ( - 452A874E0FCBFE1900360071 /* aeffect.h */, - 452A874F0FCBFE1900360071 /* aeffectx.h */, - ); - name = VST_SDK; - path = ../../VST_SDK; - sourceTree = SOURCE_ROOT; - }; - 452A875D0FCBFF5B00360071 /* LICE */ = { - isa = PBXGroup; - children = ( - 452A88EB0FCC0A1E00360071 /* zlib */, - 452A88E80FCC09FD00360071 /* jpeglib */, - 452A88E70FCC09EF00360071 /* libpng */, - 452A87670FCBFFDD00360071 /* lice_arc.cpp */, - 452A87680FCBFFDD00360071 /* lice_bezier.h */, - 452A87690FCBFFDD00360071 /* lice_bmp.cpp */, - 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */, - 452A876B0FCBFFDD00360071 /* lice_combine.h */, - 452A876C0FCBFFDD00360071 /* lice_extended.h */, - 452A87730FCBFFDD00360071 /* lice_image.cpp */, - 452A87740FCBFFDD00360071 /* lice_jpg.cpp */, - 452A87750FCBFFDD00360071 /* lice_line.cpp */, - 452A87780FCBFFDD00360071 /* lice_png.cpp */, - 452A877B0FCBFFDD00360071 /* lice_text.cpp */, - 452A877C0FCBFFDD00360071 /* lice_text.h */, - 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */, - 452A877E0FCBFFDD00360071 /* lice.cpp */, - 452A87810FCBFFDD00360071 /* lice.h */, - 452A87600FCBFFA500360071 /* SWELL */, - ); - name = LICE; - sourceTree = ""; - }; - 452A87600FCBFFA500360071 /* SWELL */ = { - isa = PBXGroup; - children = ( - 45B61BC510B15E25009E1E8C /* swell-gdi.mm */, - 452A8A020FCC0F4E00360071 /* swell-internal.h */, - 452A87A40FCC004600360071 /* swell.h */, - ); - name = SWELL; - sourceTree = ""; - }; - 452A88E70FCC09EF00360071 /* libpng */ = { - isa = PBXGroup; - children = ( - 452A89960FCC0A6500360071 /* png.c */, - 452A89970FCC0A6500360071 /* png.h */, - 452A89980FCC0A6500360071 /* pngconf.h */, - 452A89990FCC0A6500360071 /* pngerror.c */, - 452A899A0FCC0A6500360071 /* pnggccrd.c */, - 452A899B0FCC0A6500360071 /* pngget.c */, - 452A899C0FCC0A6500360071 /* pngmem.c */, - 452A899D0FCC0A6500360071 /* pngpread.c */, - 452A899E0FCC0A6500360071 /* pngread.c */, - 452A899F0FCC0A6500360071 /* pngrtran.c */, - 452A89A00FCC0A6500360071 /* pngrutil.c */, - 452A89A10FCC0A6500360071 /* pngset.c */, - 452A89A30FCC0A6500360071 /* pngtrans.c */, - 452A89A40FCC0A6500360071 /* pngvcrd.c */, - 452A89A50FCC0A6500360071 /* pngwio.c */, - 452A89A70FCC0A6500360071 /* pngwtran.c */, - 452A89A80FCC0A6500360071 /* pngwutil.c */, - 452A89A90FCC0A6500360071 /* pngrio.c */, - ); - name = libpng; - sourceTree = ""; - }; - 452A88E80FCC09FD00360071 /* jpeglib */ = { - isa = PBXGroup; - children = ( - 452A89220FCC0A4C00360071 /* jcapimin.c */, - 452A89230FCC0A4C00360071 /* jcapistd.c */, - 452A89240FCC0A4C00360071 /* jccoefct.c */, - 452A89250FCC0A4C00360071 /* jccolor.c */, - 452A89260FCC0A4C00360071 /* jcdctmgr.c */, - 452A89270FCC0A4C00360071 /* jchuff.c */, - 452A89280FCC0A4C00360071 /* jchuff.h */, - 452A89290FCC0A4C00360071 /* jcinit.c */, - 452A892A0FCC0A4C00360071 /* jcmainct.c */, - 452A892B0FCC0A4C00360071 /* jcmarker.c */, - 452A892C0FCC0A4C00360071 /* jcmaster.c */, - 452A892D0FCC0A4C00360071 /* jcomapi.c */, - 452A892E0FCC0A4C00360071 /* jconfig.h */, - 452A892F0FCC0A4C00360071 /* jcparam.c */, - 452A89300FCC0A4C00360071 /* jcphuff.c */, - 452A89310FCC0A4C00360071 /* jcprepct.c */, - 452A89320FCC0A4C00360071 /* jcsample.c */, - 452A89330FCC0A4C00360071 /* jctrans.c */, - 452A89340FCC0A4C00360071 /* jdapimin.c */, - 452A89350FCC0A4C00360071 /* jdapistd.c */, - 452A89360FCC0A4C00360071 /* jdatadst.c */, - 452A89370FCC0A4C00360071 /* jdatasrc.c */, - 452A89380FCC0A4C00360071 /* jdcoefct.c */, - 452A89390FCC0A4C00360071 /* jdcolor.c */, - 452A893A0FCC0A4C00360071 /* jdct.h */, - 452A893B0FCC0A4C00360071 /* jddctmgr.c */, - 452A893C0FCC0A4C00360071 /* jdhuff.c */, - 452A893D0FCC0A4C00360071 /* jdhuff.h */, - 452A893E0FCC0A4C00360071 /* jdinput.c */, - 452A893F0FCC0A4C00360071 /* jdmainct.c */, - 452A89400FCC0A4C00360071 /* jdmarker.c */, - 452A89410FCC0A4C00360071 /* jdmaster.c */, - 452A89420FCC0A4C00360071 /* jdmerge.c */, - 452A89430FCC0A4C00360071 /* jdphuff.c */, - 452A89440FCC0A4C00360071 /* jdpostct.c */, - 452A89450FCC0A4C00360071 /* jdsample.c */, - 452A89460FCC0A4C00360071 /* jdtrans.c */, - 452A89470FCC0A4C00360071 /* jerror.c */, - 452A89480FCC0A4C00360071 /* jerror.h */, - 452A89490FCC0A4C00360071 /* jfdctflt.c */, - 452A894A0FCC0A4C00360071 /* jfdctfst.c */, - 452A894B0FCC0A4C00360071 /* jfdctint.c */, - 452A894C0FCC0A4C00360071 /* jidctflt.c */, - 452A894D0FCC0A4C00360071 /* jidctfst.c */, - 452A894E0FCC0A4C00360071 /* jidctint.c */, - 452A894F0FCC0A4C00360071 /* jidctred.c */, - 452A89500FCC0A4C00360071 /* jinclude.h */, - 452A89510FCC0A4C00360071 /* jmemmgr.c */, - 452A89520FCC0A4C00360071 /* jmemnobs.c */, - 452A89530FCC0A4C00360071 /* jmemsys.h */, - 452A89540FCC0A4C00360071 /* jmorecfg.h */, - 452A89550FCC0A4C00360071 /* jpegint.h */, - 452A89560FCC0A4C00360071 /* jpeglib.h */, - 452A89570FCC0A4C00360071 /* jquant1.c */, - 452A89580FCC0A4C00360071 /* jquant2.c */, - 452A89590FCC0A4C00360071 /* jutils.c */, - 452A895A0FCC0A4C00360071 /* jversion.h */, - ); - name = jpeglib; - sourceTree = ""; - }; - 452A88EB0FCC0A1E00360071 /* zlib */ = { - isa = PBXGroup; - children = ( - 452A88ED0FCC0A2D00360071 /* adler32.c */, - 452A88EE0FCC0A2D00360071 /* compress.c */, - 452A88EF0FCC0A2D00360071 /* crc32.c */, - 452A88F00FCC0A2D00360071 /* crc32.h */, - 452A88F10FCC0A2D00360071 /* deflate.c */, - 452A88F20FCC0A2D00360071 /* deflate.h */, - 452A88F40FCC0A2D00360071 /* infback.c */, - 452A88F50FCC0A2D00360071 /* inffast.c */, - 452A88F60FCC0A2D00360071 /* inffast.h */, - 452A88F70FCC0A2D00360071 /* inffixed.h */, - 452A88F80FCC0A2D00360071 /* inflate.c */, - 452A88F90FCC0A2D00360071 /* inflate.h */, - 452A88FA0FCC0A2D00360071 /* inftrees.c */, - 452A88FB0FCC0A2D00360071 /* inftrees.h */, - 452A88FC0FCC0A2D00360071 /* minigzip.c */, - 452A88FD0FCC0A2D00360071 /* trees.c */, - 452A88FE0FCC0A2D00360071 /* trees.h */, - 452A88FF0FCC0A2D00360071 /* uncompr.c */, - 452A89000FCC0A2D00360071 /* zconf.h */, - 452A89010FCC0A2D00360071 /* zconf.in.h */, - 452A89020FCC0A2D00360071 /* zlib.h */, - 452A89030FCC0A2D00360071 /* zutil.c */, - 452A89040FCC0A2D00360071 /* zutil.h */, - 452A89050FCC0A2D00360071 /* gzio.c */, - ); - name = zlib; - sourceTree = ""; - }; - 52FBBE770D0CF0D3001C8B8A /* IPlug */ = { - isa = PBXGroup; - children = ( - 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */, - 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */, - 52E41BA70D14C09E00A0943B /* IPlugAU.h */, - 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */, - 52A215760D11C20C006341F0 /* IPlugVST.h */, - 52A215770D11C20C006341F0 /* IPlugVST.cpp */, - 52A2156E0D11C200006341F0 /* IPlugBase.h */, - 52A2156F0D11C200006341F0 /* IPlugBase.cpp */, - 52A2156C0D11C1EC006341F0 /* Hosts.cpp */, - 52A2156A0D11C1E4006341F0 /* Hosts.h */, - 52FBBE870D0CF0D3001C8B8A /* Containers.h */, - 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */, - 52FBBE890D0CF0D3001C8B8A /* IControl.h */, - 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */, - 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */, - 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */, - 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */, - 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */, - 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */, - 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */, - 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */, - 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */, - 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */, - 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */, - 52FBBE970D0CF0D3001C8B8A /* IParam.h */, - 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */, - 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */, - 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */, - 52FBBEA20D0CF0D3001C8B8A /* Log.h */, - ); - name = IPlug; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC07A0554694100DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 52FBBEA60D0CF0D3001C8B8A /* Containers.h in Headers */, - 52FBBEA80D0CF0D3001C8B8A /* IControl.h in Headers */, - 52FBBEAA0D0CF0D3001C8B8A /* IGraphics.h in Headers */, - 52FBBEAE0D0CF0D3001C8B8A /* IGraphicsLice.h in Headers */, - 52FBBEB00D0CF0D3001C8B8A /* IGraphicsMac.h in Headers */, - 52FBBEB60D0CF0D3001C8B8A /* IParam.h in Headers */, - 52FBBEBC0D0CF0D3001C8B8A /* IPlugStructs.h in Headers */, - 52FBBEBE0D0CF0D3001C8B8A /* Log.h in Headers */, - 52A2156B0D11C1E4006341F0 /* Hosts.h in Headers */, - 52A215720D11C200006341F0 /* IPlugBase.h in Headers */, - 52A215780D11C20C006341F0 /* IPlugVST.h in Headers */, - 52E41BA90D14C09E00A0943B /* IPlugAU.h in Headers */, - 521F387F0D1704080060FE32 /* IPlug_include_in_plug_src.h in Headers */, - 521F38800D1704080060FE32 /* IPlug_include_in_plug_hdr.h in Headers */, - 52780D4C0D20A1A000C2BCA7 /* IGraphicsCocoa.h in Headers */, - 52A4AB440D2BFA510042A248 /* IGraphicsCarbon.h in Headers */, - 452A87500FCBFE1900360071 /* aeffect.h in Headers */, - 452A87510FCBFE1900360071 /* aeffectx.h in Headers */, - 452A87840FCBFFDD00360071 /* lice_bezier.h in Headers */, - 452A87870FCBFFDD00360071 /* lice_combine.h in Headers */, - 452A87880FCBFFDD00360071 /* lice_extended.h in Headers */, - 452A87980FCBFFDD00360071 /* lice_text.h in Headers */, - 452A879B0FCBFFDD00360071 /* lice.h in Headers */, - 452A87A50FCC004600360071 /* swell.h in Headers */, - 452A89090FCC0A2D00360071 /* crc32.h in Headers */, - 452A890B0FCC0A2D00360071 /* deflate.h in Headers */, - 452A890F0FCC0A2D00360071 /* inffast.h in Headers */, - 452A89100FCC0A2D00360071 /* inffixed.h in Headers */, - 452A89120FCC0A2D00360071 /* inflate.h in Headers */, - 452A89140FCC0A2D00360071 /* inftrees.h in Headers */, - 452A89170FCC0A2D00360071 /* trees.h in Headers */, - 452A89190FCC0A2D00360071 /* zconf.h in Headers */, - 452A891A0FCC0A2D00360071 /* zconf.in.h in Headers */, - 452A891B0FCC0A2D00360071 /* zlib.h in Headers */, - 452A891D0FCC0A2D00360071 /* zutil.h in Headers */, - 452A89630FCC0A4C00360071 /* jchuff.h in Headers */, - 452A89690FCC0A4C00360071 /* jconfig.h in Headers */, - 452A89750FCC0A4C00360071 /* jdct.h in Headers */, - 452A89780FCC0A4C00360071 /* jdhuff.h in Headers */, - 452A89830FCC0A4C00360071 /* jerror.h in Headers */, - 452A898B0FCC0A4C00360071 /* jinclude.h in Headers */, - 452A898E0FCC0A4C00360071 /* jmemsys.h in Headers */, - 452A898F0FCC0A4C00360071 /* jmorecfg.h in Headers */, - 452A89900FCC0A4C00360071 /* jpegint.h in Headers */, - 452A89910FCC0A4C00360071 /* jpeglib.h in Headers */, - 452A89950FCC0A4C00360071 /* jversion.h in Headers */, - 452A89AB0FCC0A6500360071 /* png.h in Headers */, - 452A89AC0FCC0A6500360071 /* pngconf.h in Headers */, - 452A8A030FCC0F4E00360071 /* swell-internal.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - D2AAC07D0554694100DB518D /* IPlug */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "IPlug" */; - buildPhases = ( - D2AAC07A0554694100DB518D /* Headers */, - D2AAC07B0554694100DB518D /* Sources */, - D2AAC07C0554694100DB518D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = IPlug; - productName = IPlug; - productReference = D2AAC07E0554694100DB518D /* libIPlug.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "IPlug" */; - compatibilityVersion = "Xcode 3.0"; - hasScannedForEncodings = 1; - mainGroup = 0867D691FE84028FC02AAC07 /* IPlug */; - productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D2AAC07D0554694100DB518D /* IPlug */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - D2AAC07B0554694100DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 52FBBEA70D0CF0D3001C8B8A /* IControl.cpp in Sources */, - 52FBBEA90D0CF0D3001C8B8A /* IGraphics.cpp in Sources */, - 52FBBEAC0D0CF0D3001C8B8A /* IGraphicsCocoa.mm in Sources */, - 52FBBEAD0D0CF0D3001C8B8A /* IGraphicsLice.cpp in Sources */, - 52FBBEB10D0CF0D3001C8B8A /* IGraphicsMac.mm in Sources */, - 52FBBEB50D0CF0D3001C8B8A /* IParam.cpp in Sources */, - 52FBBEBB0D0CF0D3001C8B8A /* IPlugStructs.cpp in Sources */, - 52FBBEBD0D0CF0D3001C8B8A /* Log.cpp in Sources */, - 52A2156D0D11C1EC006341F0 /* Hosts.cpp in Sources */, - 52A215730D11C200006341F0 /* IPlugBase.cpp in Sources */, - 52A215790D11C20C006341F0 /* IPlugVST.cpp in Sources */, - 52E41BAA0D14C09E00A0943B /* IPlugAU.cpp in Sources */, - 52A4AB450D2BFA510042A248 /* IGraphicsCarbon.cpp in Sources */, - 452A87830FCBFFDD00360071 /* lice_arc.cpp in Sources */, - 452A87850FCBFFDD00360071 /* lice_bmp.cpp in Sources */, - 452A87860FCBFFDD00360071 /* lice_colorspace.cpp in Sources */, - 452A878F0FCBFFDD00360071 /* lice_image.cpp in Sources */, - 452A87900FCBFFDD00360071 /* lice_jpg.cpp in Sources */, - 452A87910FCBFFDD00360071 /* lice_line.cpp in Sources */, - 452A87940FCBFFDD00360071 /* lice_png.cpp in Sources */, - 452A87970FCBFFDD00360071 /* lice_text.cpp in Sources */, - 452A87990FCBFFDD00360071 /* lice_textnew.cpp in Sources */, - 452A879A0FCBFFDD00360071 /* lice.cpp in Sources */, - 452A89060FCC0A2D00360071 /* adler32.c in Sources */, - 452A89070FCC0A2D00360071 /* compress.c in Sources */, - 452A89080FCC0A2D00360071 /* crc32.c in Sources */, - 452A890A0FCC0A2D00360071 /* deflate.c in Sources */, - 452A890D0FCC0A2D00360071 /* infback.c in Sources */, - 452A890E0FCC0A2D00360071 /* inffast.c in Sources */, - 452A89110FCC0A2D00360071 /* inflate.c in Sources */, - 452A89130FCC0A2D00360071 /* inftrees.c in Sources */, - 452A89150FCC0A2D00360071 /* minigzip.c in Sources */, - 452A89160FCC0A2D00360071 /* trees.c in Sources */, - 452A89180FCC0A2D00360071 /* uncompr.c in Sources */, - 452A891C0FCC0A2D00360071 /* zutil.c in Sources */, - 452A891E0FCC0A2D00360071 /* gzio.c in Sources */, - 452A895D0FCC0A4C00360071 /* jcapimin.c in Sources */, - 452A895E0FCC0A4C00360071 /* jcapistd.c in Sources */, - 452A895F0FCC0A4C00360071 /* jccoefct.c in Sources */, - 452A89600FCC0A4C00360071 /* jccolor.c in Sources */, - 452A89610FCC0A4C00360071 /* jcdctmgr.c in Sources */, - 452A89620FCC0A4C00360071 /* jchuff.c in Sources */, - 452A89640FCC0A4C00360071 /* jcinit.c in Sources */, - 452A89650FCC0A4C00360071 /* jcmainct.c in Sources */, - 452A89660FCC0A4C00360071 /* jcmarker.c in Sources */, - 452A89670FCC0A4C00360071 /* jcmaster.c in Sources */, - 452A89680FCC0A4C00360071 /* jcomapi.c in Sources */, - 452A896A0FCC0A4C00360071 /* jcparam.c in Sources */, - 452A896B0FCC0A4C00360071 /* jcphuff.c in Sources */, - 452A896C0FCC0A4C00360071 /* jcprepct.c in Sources */, - 452A896D0FCC0A4C00360071 /* jcsample.c in Sources */, - 452A896E0FCC0A4C00360071 /* jctrans.c in Sources */, - 452A896F0FCC0A4C00360071 /* jdapimin.c in Sources */, - 452A89700FCC0A4C00360071 /* jdapistd.c in Sources */, - 452A89710FCC0A4C00360071 /* jdatadst.c in Sources */, - 452A89720FCC0A4C00360071 /* jdatasrc.c in Sources */, - 452A89730FCC0A4C00360071 /* jdcoefct.c in Sources */, - 452A89740FCC0A4C00360071 /* jdcolor.c in Sources */, - 452A89760FCC0A4C00360071 /* jddctmgr.c in Sources */, - 452A89770FCC0A4C00360071 /* jdhuff.c in Sources */, - 452A89790FCC0A4C00360071 /* jdinput.c in Sources */, - 452A897A0FCC0A4C00360071 /* jdmainct.c in Sources */, - 452A897B0FCC0A4C00360071 /* jdmarker.c in Sources */, - 452A897C0FCC0A4C00360071 /* jdmaster.c in Sources */, - 452A897D0FCC0A4C00360071 /* jdmerge.c in Sources */, - 452A897E0FCC0A4C00360071 /* jdphuff.c in Sources */, - 452A897F0FCC0A4C00360071 /* jdpostct.c in Sources */, - 452A89800FCC0A4C00360071 /* jdsample.c in Sources */, - 452A89810FCC0A4C00360071 /* jdtrans.c in Sources */, - 452A89820FCC0A4C00360071 /* jerror.c in Sources */, - 452A89840FCC0A4C00360071 /* jfdctflt.c in Sources */, - 452A89850FCC0A4C00360071 /* jfdctfst.c in Sources */, - 452A89860FCC0A4C00360071 /* jfdctint.c in Sources */, - 452A89870FCC0A4C00360071 /* jidctflt.c in Sources */, - 452A89880FCC0A4C00360071 /* jidctfst.c in Sources */, - 452A89890FCC0A4C00360071 /* jidctint.c in Sources */, - 452A898A0FCC0A4C00360071 /* jidctred.c in Sources */, - 452A898C0FCC0A4C00360071 /* jmemmgr.c in Sources */, - 452A898D0FCC0A4C00360071 /* jmemnobs.c in Sources */, - 452A89920FCC0A4C00360071 /* jquant1.c in Sources */, - 452A89930FCC0A4C00360071 /* jquant2.c in Sources */, - 452A89940FCC0A4C00360071 /* jutils.c in Sources */, - 452A89AA0FCC0A6500360071 /* png.c in Sources */, - 452A89AD0FCC0A6500360071 /* pngerror.c in Sources */, - 452A89AE0FCC0A6500360071 /* pnggccrd.c in Sources */, - 452A89AF0FCC0A6500360071 /* pngget.c in Sources */, - 452A89B00FCC0A6500360071 /* pngmem.c in Sources */, - 452A89B10FCC0A6500360071 /* pngpread.c in Sources */, - 452A89B20FCC0A6500360071 /* pngread.c in Sources */, - 452A89B30FCC0A6500360071 /* pngrtran.c in Sources */, - 452A89B40FCC0A6500360071 /* pngrutil.c in Sources */, - 452A89B50FCC0A6500360071 /* pngset.c in Sources */, - 452A89B70FCC0A6500360071 /* pngtrans.c in Sources */, - 452A89B80FCC0A6500360071 /* pngvcrd.c in Sources */, - 452A89B90FCC0A6500360071 /* pngwio.c in Sources */, - 452A89BB0FCC0A6500360071 /* pngwtran.c in Sources */, - 452A89BC0FCC0A6500360071 /* pngwutil.c in Sources */, - 452A89BD0FCC0A6500360071 /* pngrio.c in Sources */, - 45B61BC610B15E25009E1E8C /* swell-gdi.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB921F08733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlug_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = _DEBUG; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../wdl/lice/build/Debug\"", - ); - PRODUCT_NAME = IPlug; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - ZERO_LINK = YES; - }; - name = Debug; - }; - 1DEB922008733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlug_Prefix.pch; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../wdl/lice/build/Release\"", - ); - PRODUCT_NAME = IPlug; - }; - name = Release; - }; - 1DEB922308733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_PREPROCESSOR_DEFINITIONS = _DEBUG; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - }; - name = Debug; - }; - 1DEB922408733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - }; - name = Release; - }; - 528359A40D7F0BF500577159 /* Tracer */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - }; - name = Tracer; - }; - 528359A50D7F0BF500577159 /* Tracer */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlug_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = TRACER_BUILD; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../wdl/lice/build/Release\"", - ); - PRODUCT_NAME = IPlug; - }; - name = Tracer; - }; - 52CC00400D2DFBE900EE9465 /* Reaper Special x86 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - }; - name = "Reaper Special x86"; - }; - 52CC00410D2DFBE900EE9465 /* Reaper Special x86 */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlug_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = REAPER_SPECIAL; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../wdl/lice/build/Release\"", - ); - PRODUCT_NAME = IPlug; - }; - name = "Reaper Special x86"; - }; - 52CC00440D2DFC3900EE9465 /* Reaper Special ppc */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_PKGINFO_FILE = YES; - INFOPLIST_EXPAND_BUILD_SETTINGS = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; - }; - name = "Reaper Special ppc"; - }; - 52CC00450D2DFC3900EE9465 /* Reaper Special ppc */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = IPlug_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = REAPER_SPECIAL; - INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../wdl/lice/build/Release\"", - ); - PRODUCT_NAME = IPlug; - }; - name = "Reaper Special ppc"; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "IPlug" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB921F08733DC00010E9CD /* Debug */, - 1DEB922008733DC00010E9CD /* Release */, - 528359A50D7F0BF500577159 /* Tracer */, - 52CC00410D2DFBE900EE9465 /* Reaper Special x86 */, - 52CC00450D2DFC3900EE9465 /* Reaper Special ppc */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "IPlug" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB922308733DC00010E9CD /* Debug */, - 1DEB922408733DC00010E9CD /* Release */, - 528359A40D7F0BF500577159 /* Tracer */, - 52CC00400D2DFBE900EE9465 /* Reaper Special x86 */, - 52CC00440D2DFC3900EE9465 /* Reaper Special ppc */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/WDL/IPlug/IPlugAU.cpp b/WDL/IPlug/IPlugAU.cpp deleted file mode 100644 index f883dd42..00000000 --- a/WDL/IPlug/IPlugAU.cpp +++ /dev/null @@ -1,1558 +0,0 @@ -#include "IPlugAU.h" -#include "IGraphicsMac.h" -#include "Log.h" -#include "Hosts.h" - -//#include "/Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h" - -#define kAudioUnitRemovePropertyListenerWithUserDataSelect 0x0012 - -typedef AudioStreamBasicDescription STREAM_DESC; - -/* inline */ void MakeDefaultASBD(STREAM_DESC* pASBD, double sampleRate, int nChannels, bool interleaved) -{ - memset(pASBD, 0, sizeof(STREAM_DESC)); - pASBD->mSampleRate = sampleRate; - pASBD->mFormatID = kAudioFormatLinearPCM; - pASBD->mFormatFlags = kAudioFormatFlagsCanonical; - pASBD->mBitsPerChannel = 8 * sizeof(AudioSampleType); - pASBD->mChannelsPerFrame = nChannels; - pASBD->mFramesPerPacket = 1; - int nBytes = sizeof(AudioSampleType); - if (interleaved) { - nBytes *= nChannels; - } - else { - pASBD->mFormatFlags |= kAudioFormatFlagIsNonInterleaved; - } - pASBD->mBytesPerPacket = pASBD->mBytesPerFrame = nBytes; -} - -template -int PtrListAddFromStack(WDL_PtrList* pList, C* pStackInstance) -{ - C* pNew = new C; - memcpy(pNew, pStackInstance, sizeof(C)); - pList->Add(pNew); - return pList->GetSize() - 1; -} - -template -int PtrListInitialize(WDL_PtrList* pList, int size) -{ - for (int i = 0; i < size; ++i) { - C* pNew = new C; - memset(pNew, 0, sizeof(C)); - pList->Add(pNew); - } - return size; -} - -#define GET_COMP_PARAM(TYPE, IDX) *((TYPE*)&(params->params[IDX])) -#define NO_OP(select) case select: return badComponentSelector; - -// static -ComponentResult IPlugAU::IPlugAUEntry(ComponentParameters *params, void* pPlug) -{ - int select = params->what; - - Trace(TRACELOC, "(%d:%s)", select, AUSelectStr(select)); - - if (select == kComponentOpenSelect) { - IPlugAU* _this = MakePlug(); - _this->HostSpecificInit(); - _this->PruneUninitializedPresets(); - _this->mCI = GET_COMP_PARAM(ComponentInstance, 0); - SetComponentInstanceStorage(_this->mCI, (Handle) _this); - return noErr; - } - - IPlugAU* _this = (IPlugAU*) pPlug; - - if (select == kComponentCloseSelect) { - DELETE_NULL(_this); - return noErr; - } - - IPlugBase::IMutexLock lock(_this); - - switch (select) { - case kComponentVersionSelect: { - return _this->GetEffectVersion(false); - } - case kAudioUnitInitializeSelect: { - if (!(_this->CheckLegalIO())) { - return badComponentSelector; - } - _this->mActive = true; - _this->OnParamReset(); - _this->OnActivate(true); - return noErr; - } - case kAudioUnitUninitializeSelect: { - _this->mActive = false; - _this->ClearConnections(); - _this->OnActivate(false); - return noErr; - } - case kAudioUnitGetPropertyInfoSelect: { - AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); - AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); - AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); - UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 1); - Boolean* pWriteable = GET_COMP_PARAM(Boolean*, 0); - - UInt32 dataSize = 0; - if (!pDataSize) { - pDataSize = &dataSize; - } - Boolean writeable; - if (!pWriteable) { - pWriteable = &writeable; - } - *pWriteable = false; - return _this->GetProperty(propID, scope, element, pDataSize, pWriteable, 0); - } - case kAudioUnitGetPropertySelect: { - AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); - AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); - AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); - void* pData = GET_COMP_PARAM(void*, 1); - UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 0); - - UInt32 dataSize = 0; - if (!pDataSize) { - pDataSize = &dataSize; - } - Boolean writeable = false; - return _this->GetProperty(propID, scope, element, pDataSize, &writeable, pData); - } - case kAudioUnitSetPropertySelect: { - AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); - AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); - AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); - const void* pData = GET_COMP_PARAM(const void*, 1); - UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 0); - return _this->SetProperty(propID, scope, element, pDataSize, pData); - } - case kAudioUnitAddPropertyListenerSelect: { - PropertyListener listener; - listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 2); - listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 1); - listener.mProcArgs = GET_COMP_PARAM(void*, 0); - int i, n = _this->mPropertyListeners.GetSize(); - for (i = 0; i < n; ++i) { - PropertyListener* pListener = _this->mPropertyListeners.Get(i); - if (listener.mPropID == pListener->mPropID && listener.mListenerProc == pListener->mListenerProc) { - return noErr; - } - } - PtrListAddFromStack(&(_this->mPropertyListeners), &listener); - return noErr; - } - case kAudioUnitRemovePropertyListenerSelect: { - PropertyListener listener; - listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 1); - listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 0); - int i, n = _this->mPropertyListeners.GetSize(); - for (i = 0; i < n; ++i) { - PropertyListener* pListener = _this->mPropertyListeners.Get(i); - if (listener.mPropID == pListener->mPropID && listener.mListenerProc == pListener->mListenerProc) { - _this->mPropertyListeners.Delete(i); - break; - } - } - return noErr; - } - case kAudioUnitRemovePropertyListenerWithUserDataSelect: { - PropertyListener listener; - listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 2); - listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 1); - listener.mProcArgs = GET_COMP_PARAM(void*, 0); - int i, n = _this->mPropertyListeners.GetSize(); - for (i = 0; i < n; ++i) { - PropertyListener* pListener = _this->mPropertyListeners.Get(i); - if (listener.mPropID == pListener->mPropID && - listener.mListenerProc == pListener->mListenerProc && listener.mProcArgs == pListener->mProcArgs) { - _this->mPropertyListeners.Delete(i); - break; - } - } - return noErr; - } - case kAudioUnitAddRenderNotifySelect: { - AURenderCallbackStruct acs; - acs.inputProc = GET_COMP_PARAM(AURenderCallback, 1); - acs.inputProcRefCon = GET_COMP_PARAM(void*, 0); - PtrListAddFromStack(&(_this->mRenderNotify), &acs); - return noErr; - } - case kAudioUnitRemoveRenderNotifySelect: { - AURenderCallbackStruct acs; - acs.inputProc = GET_COMP_PARAM(AURenderCallback, 1); - acs.inputProcRefCon = GET_COMP_PARAM(void*, 0); - int i, n = _this->mRenderNotify.GetSize(); - for (i = 0; i < n; ++i) { - AURenderCallbackStruct* pACS = _this->mRenderNotify.Get(i); - if (acs.inputProc == pACS->inputProc) { - _this->mRenderNotify.Delete(i); - break; - } - } - return noErr; - } - case kAudioUnitGetParameterSelect: { - AudioUnitParameterID paramID = GET_COMP_PARAM(AudioUnitParameterID, 3); - AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 2); - AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 1); - AudioUnitParameterValue* pValue = GET_COMP_PARAM(AudioUnitParameterValue*, 0); - return GetParamProc(pPlug, paramID, scope, element, pValue); - } - case kAudioUnitSetParameterSelect: { - AudioUnitParameterID paramID = GET_COMP_PARAM(AudioUnitParameterID, 4); - AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); - AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); - AudioUnitParameterValue value = GET_COMP_PARAM(AudioUnitParameterValue, 1); - UInt32 offset = GET_COMP_PARAM(UInt32, 0); - return SetParamProc(pPlug, paramID, scope, element, value, offset); - } - case kAudioUnitScheduleParametersSelect: { - AudioUnitParameterEvent* pEvent = GET_COMP_PARAM(AudioUnitParameterEvent*, 1); - UInt32 nEvents = GET_COMP_PARAM(UInt32, 0); - for (int i = 0; i < nEvents; ++i, ++pEvent) { - if (pEvent->eventType == kParameterEvent_Immediate) { - ComponentResult r = SetParamProc(pPlug, pEvent->parameter, pEvent->scope, pEvent->element, - pEvent->eventValues.immediate.value, pEvent->eventValues.immediate.bufferOffset); - if (r != noErr) { - return r; - } - } - } - return noErr; - } - case kAudioUnitRenderSelect: { - AudioUnitRenderActionFlags* pFlags = GET_COMP_PARAM(AudioUnitRenderActionFlags*, 4); - const AudioTimeStamp* pTimestamp = GET_COMP_PARAM(AudioTimeStamp*, 3); - UInt32 outputBusIdx = GET_COMP_PARAM(UInt32, 2); - UInt32 nFrames = GET_COMP_PARAM(UInt32, 1); - AudioBufferList* pBufferList = GET_COMP_PARAM(AudioBufferList*, 0); - return RenderProc(_this, pFlags, pTimestamp, outputBusIdx, nFrames, pBufferList); - } - case kAudioUnitResetSelect: { - _this->Reset(); - return noErr; - } - case kMusicDeviceMIDIEventSelect: { // Ignore kMusicDeviceSysExSelect for now. - IMidiMsg msg; - msg.mStatus = GET_COMP_PARAM(UInt32, 3); - msg.mData1 = GET_COMP_PARAM(UInt32, 2); - msg.mData2 = GET_COMP_PARAM(UInt32, 1); - msg.mOffset = GET_COMP_PARAM(UInt32, 0); - _this->ProcessMidiMsg(&msg); - return noErr; - } - NO_OP(kMusicDeviceSysExSelect); - case kMusicDevicePrepareInstrumentSelect: { - return noErr; - } - case kMusicDeviceReleaseInstrumentSelect: { - return noErr; - } - case kMusicDeviceStartNoteSelect: { - MusicDeviceInstrumentID deviceID = GET_COMP_PARAM(MusicDeviceInstrumentID, 4); - MusicDeviceGroupID groupID = GET_COMP_PARAM(MusicDeviceGroupID, 3); - NoteInstanceID* pNoteID = GET_COMP_PARAM(NoteInstanceID*, 2); - UInt32 offset = GET_COMP_PARAM(UInt32, 1); - MusicDeviceNoteParams* pNoteParams = GET_COMP_PARAM(MusicDeviceNoteParams*, 0); - int note = (int) pNoteParams->mPitch; - *pNoteID = note; - IMidiMsg msg; - msg.MakeNoteOnMsg(note, (int) pNoteParams->mVelocity, offset); - return noErr; - } - case kMusicDeviceStopNoteSelect: { - MusicDeviceGroupID groupID = GET_COMP_PARAM(MusicDeviceGroupID, 2); - NoteInstanceID noteID = GET_COMP_PARAM(NoteInstanceID, 1); - UInt32 offset = GET_COMP_PARAM(UInt32, 0); - // noteID is supposed to be some incremented unique ID, but we're just storing note number in it. - IMidiMsg msg; - msg.MakeNoteOffMsg(noteID, offset); - return noErr; - } - case kComponentCanDoSelect: { - switch (params->params[0]) { - case kAudioUnitInitializeSelect: - case kAudioUnitUninitializeSelect: - case kAudioUnitGetPropertyInfoSelect: - case kAudioUnitGetPropertySelect: - case kAudioUnitSetPropertySelect: - case kAudioUnitAddPropertyListenerSelect: - case kAudioUnitRemovePropertyListenerSelect: - case kAudioUnitGetParameterSelect: - case kAudioUnitSetParameterSelect: - case kAudioUnitResetSelect: - case kAudioUnitRenderSelect: - case kAudioUnitAddRenderNotifySelect: - case kAudioUnitRemoveRenderNotifySelect: - case kAudioUnitScheduleParametersSelect: - return 1; - default: - return 0; - } - } - default: return badComponentSelector; - } -} - -struct AudioUnitCarbonViewCreateGluePB { - unsigned char componentFlags; - unsigned char componentParamSize; - short componentWhat; - ControlRef* outControl; - const Float32Point* inSize; - const Float32Point* inLocation; - ControlRef inParentControl; - WindowRef inWindow; - AudioUnit inAudioUnit; - AudioUnitCarbonView inView; -}; - -struct CarbonViewInstance { - ComponentInstance mCI; - IPlugAU* mPlug; -}; - -// static -ComponentResult IPlugAU::IPlugAUCarbonViewEntry(ComponentParameters *params, void* pView) -{ - int select = params->what; - - Trace(TRACELOC, "%d:%s", select, AUSelectStr(select)); - - if (select == kComponentOpenSelect) { - CarbonViewInstance* pCVI = new CarbonViewInstance; - pCVI->mCI = GET_COMP_PARAM(ComponentInstance, 0); - pCVI->mPlug = 0; - SetComponentInstanceStorage(pCVI->mCI, (Handle) pCVI); - return noErr; - } - - CarbonViewInstance* pCVI = (CarbonViewInstance*) pView; - - switch (select) { - case kComponentCloseSelect: { - IPlugAU* _this = pCVI->mPlug; - if (_this && _this->GetGUI()) { - _this->GetGUI()->CloseWindow(); - } - DELETE_NULL(pCVI); - return noErr; - } - case kAudioUnitCarbonViewCreateSelect: { - AudioUnitCarbonViewCreateGluePB* pb = (AudioUnitCarbonViewCreateGluePB*) params; - IPlugAU* _this = (IPlugAU*) GetComponentInstanceStorage(pb->inAudioUnit); - pCVI->mPlug = _this; - if (_this && _this->GetGUI()) { - *(pb->outControl) = (ControlRef) (_this->GetGUI()->OpenWindow(pb->inWindow, pb->inParentControl)); - return noErr; - } - return badComponentSelector; - } - default: return badComponentSelector; - } -} - -#define ASSERT_SCOPE(reqScope) if (scope != reqScope) { return kAudioUnitErr_InvalidProperty; } -#define ASSERT_INPUT_OR_GLOBAL_SCOPE \ - if (scope != kAudioUnitScope_Input && scope != kAudioUnitScope_Global) { \ - return kAudioUnitErr_InvalidProperty; \ - } -#undef NO_OP -#define NO_OP(propID) case propID: return kAudioUnitErr_InvalidProperty; - -// pData == 0 means return property info only. -ComponentResult IPlugAU::GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, - UInt32* pDataSize, Boolean* pWriteable, void* pData) -{ - Trace(TRACELOC, "%s(%d:%s):(%d:%s):%d", (pData ? "" : "info:"), propID, AUPropertyStr(propID), scope, AUScopeStr(scope), element); - - // Writeable defaults to false, we only need to set it if true. - - switch (propID) { - case kAudioUnitProperty_ClassInfo: { // 0, - *pDataSize = sizeof(CFPropertyListRef); - *pWriteable = true; - if (pData) { - CFPropertyListRef* pList = (CFPropertyListRef*) pData; - return GetState(pList); - } - return noErr; - } - case kAudioUnitProperty_MakeConnection: { // 1, - ASSERT_INPUT_OR_GLOBAL_SCOPE; - *pDataSize = sizeof(AudioUnitConnection); - *pWriteable = true; - return noErr; - } - case kAudioUnitProperty_SampleRate: { // 2, - *pDataSize = sizeof(Float64); - *pWriteable = true; - if (pData) { - *((Float64*) pData) = GetSampleRate(); - } - return noErr; - } - case kAudioUnitProperty_ParameterList: { // 3, listenable - int n = (scope == kAudioUnitScope_Global ? NParams() : 0); - *pDataSize = n * sizeof(AudioUnitParameterID); - if (pData && n) { - AudioUnitParameterID* pParamID = (AudioUnitParameterID*) pData; - for (int i = 0; i < n; ++i, ++pParamID) { - *pParamID = (AudioUnitParameterID) i; - } - } - return noErr; - } - case kAudioUnitProperty_ParameterInfo: { // 4, listenable - ASSERT_SCOPE(kAudioUnitScope_Global); - *pDataSize = sizeof(AudioUnitParameterInfo); - if (pData) { - AudioUnitParameterInfo* pInfo = (AudioUnitParameterInfo*) pData; - memset(pInfo, 0, sizeof(AudioUnitParameterInfo)); - pInfo->flags = kAudioUnitParameterFlag_CFNameRelease | - kAudioUnitParameterFlag_HasCFNameString | - kAudioUnitParameterFlag_IsReadable | - kAudioUnitParameterFlag_IsWritable; - IParam* pParam = GetParam(element); - const char* paramName = pParam->GetNameForHost(); - pInfo->cfNameString = MakeCFString(pParam->GetNameForHost()); - strcpy(pInfo->name, paramName); // Max 52. - switch (pParam->Type()) { - case IParam::kTypeBool: - pInfo->unit = kAudioUnitParameterUnit_Boolean; - break; - case IParam::kTypeEnum: - pInfo->unit = kAudioUnitParameterUnit_Indexed; - break; - default: { - const char* label = pParam->GetLabelForHost(); - if (CSTR_NOT_EMPTY(label)) { - pInfo->unit = kAudioUnitParameterUnit_CustomUnit; - pInfo->unitName = MakeCFString(label); - } - else { - pInfo->unit = kAudioUnitParameterUnit_Generic; - } - } - } - double vMin, vMax; - pParam->GetBounds(&vMin, &vMax); - pInfo->minValue = vMin; - pInfo->maxValue = vMax; - pInfo->defaultValue = pParam->Value(); - } - return noErr; - } - case kAudioUnitProperty_FastDispatch: { // 5, - return GetProc(element, pDataSize, pData); - } - NO_OP(kAudioUnitProperty_CPULoad); // 6, - case kAudioUnitProperty_StreamFormat: { // 8, - BusChannels* pBus = GetBus(scope, element); - if (!pBus) { - return kAudioUnitErr_InvalidProperty; - } - *pDataSize = sizeof(STREAM_DESC); - *pWriteable = true; - if (pData) { - int nChannels = pBus->mNHostChannels; // Report how many channels the host has connected. - if (nChannels < 0) { // Unless the host hasn't connected any yet, in which case report the default. - nChannels = pBus->mNPlugChannels; - } - STREAM_DESC* pASBD = (STREAM_DESC*) pData; - MakeDefaultASBD(pASBD, GetSampleRate(), nChannels, false); - } - return noErr; - } - case kAudioUnitProperty_ElementCount: { // 11, - *pDataSize = sizeof(UInt32); - if (pData) { - int n = 0; - if (scope == kAudioUnitScope_Input) { - n = mInBuses.GetSize(); - } - else - if (scope == kAudioUnitScope_Output) { - n = mOutBuses.GetSize(); - } - else - if (scope == kAudioUnitScope_Global) { - n = 1; - } - *((UInt32*) pData) = n; - } - return noErr; - } - case kAudioUnitProperty_Latency: { // 12, // listenable - ASSERT_SCOPE(kAudioUnitScope_Global); - *pDataSize = sizeof(Float64); - if (pData) { - *((Float64*) pData) = (double) GetLatency() / GetSampleRate(); - } - return noErr; - } - case kAudioUnitProperty_SupportedNumChannels: { // 13, - ASSERT_SCOPE(kAudioUnitScope_Global); - int n = mChannelIO.GetSize(); - *pDataSize = n * sizeof(AUChannelInfo); - if (pData) { - AUChannelInfo* pChInfo = (AUChannelInfo*) pData; - for (int i = 0; i < n; ++i, ++pChInfo) { - ChannelIO* pIO = mChannelIO.Get(i); - pChInfo->inChannels = pIO->mIn; - pChInfo->outChannels = pIO->mOut; - Trace(TRACELOC, "IO:%d:%d", pIO->mIn, pIO->mOut); - } - } - return noErr; - } - case kAudioUnitProperty_MaximumFramesPerSlice: { // 14, - ASSERT_SCOPE(kAudioUnitScope_Global); - *pDataSize = sizeof(UInt32); - *pWriteable = true; - if (pData) { - *((UInt32*) pData) = GetBlockSize(); - } - return noErr; - } - NO_OP(kAudioUnitProperty_SetExternalBuffer); // 15, - case kAudioUnitProperty_ParameterValueStrings: { // 16, - ASSERT_SCOPE(kAudioUnitScope_Global); - IParam* pParam = GetParam(element); - int n = pParam->GetNDisplayTexts(); - if (!n) { - *pDataSize = 0; - return kAudioUnitErr_InvalidProperty; - } - *pDataSize = sizeof(CFArrayRef); - if (pData) { - CFMutableArrayRef nameArray = CFArrayCreateMutable(0, n, 0); - for (int i = 0; i < n; ++i) { - const char* str = pParam->GetDisplayText(i); - CFArrayAppendValue(nameArray, MakeCFString(str)); // Release here? - } - *((CFArrayRef*) pData) = nameArray; - } - return noErr; - } - case kAudioUnitProperty_GetUIComponentList: { // 18, - if (GetGUI()) { - *pDataSize = sizeof(ComponentDescription); - if (pData) { - ComponentDescription* pDesc = (ComponentDescription*) pData; - pDesc->componentType = kAudioUnitCarbonViewComponentType; - pDesc->componentSubType = GetUniqueID(); - pDesc->componentManufacturer = GetMfrID(); - pDesc->componentFlags = 0; - pDesc->componentFlagsMask = 0; - } - return noErr; - } - return kAudioUnitErr_InvalidProperty; - } - NO_OP(kAudioUnitProperty_AudioChannelLayout); // 19, - case kAudioUnitProperty_TailTime: { // 20, // listenable - return GetProperty(kAudioUnitProperty_Latency, scope, element, pDataSize, pWriteable, pData); - } - case kAudioUnitProperty_BypassEffect: { // 21, - ASSERT_SCOPE(kAudioUnitScope_Global); - *pWriteable = true; - *pDataSize = sizeof(UInt32); - if (pData) { - *((UInt32*) pData) = (mBypassed ? 1 : 0); - } - return noErr; - } - case kAudioUnitProperty_LastRenderError: { // 22, - ASSERT_SCOPE(kAudioUnitScope_Global); - *pDataSize = sizeof(OSStatus); - if (pData) { - *((OSStatus*) pData) = noErr; - } - return noErr; - } - case kAudioUnitProperty_SetRenderCallback: { // 23, - ASSERT_INPUT_OR_GLOBAL_SCOPE; - if (element >= mInBuses.GetSize()) { - return kAudioUnitErr_InvalidProperty; - } - *pDataSize = sizeof(AURenderCallbackStruct); - *pWriteable = true; - return noErr; - } - case kAudioUnitProperty_FactoryPresets: { // 24, // listenable - *pDataSize = sizeof(CFArrayRef); - if (pData) { - int i, n = NPresets(); - CFMutableArrayRef presetArray = CFArrayCreateMutable(0, n, 0); - for (i = 0; i < n; ++i) { - AUPreset* pAUPreset = new AUPreset; - pAUPreset->presetNumber = i; - pAUPreset->presetName = MakeCFString(GetPresetName(i)); - CFArrayAppendValue(presetArray, pAUPreset); - } - *((CFMutableArrayRef*) pData) = presetArray; - } - return noErr; - } - NO_OP(kAudioUnitProperty_ContextName); // 25, - NO_OP(kAudioUnitProperty_RenderQuality); // 26, - case kAudioUnitProperty_HostCallbacks: { // 27, - ASSERT_SCOPE(kAudioUnitScope_Global); - *pDataSize = sizeof(HostCallbackInfo); - *pWriteable = true; - return noErr; - } - NO_OP(kAudioUnitProperty_InPlaceProcessing); // 29, - NO_OP(kAudioUnitProperty_ElementName); // 30, - case kAudioUnitProperty_CocoaUI: { // 31, - if (GetGUI() && IGraphicsMac::GetUserOSVersion() >= 0x1050) { - *pDataSize = sizeof(AudioUnitCocoaViewInfo); // Just one view. - if (pData) { - AudioUnitCocoaViewInfo* pViewInfo = (AudioUnitCocoaViewInfo*) pData; - CFStrLocal bundleID(mOSXBundleID.Get()); - CFBundleRef pBundle = CFBundleGetBundleWithIdentifier(bundleID.mCFStr); - CFURLRef url = CFBundleCopyBundleURL(pBundle); - pViewInfo->mCocoaAUViewBundleLocation = url; - pViewInfo->mCocoaAUViewClass[0] = MakeCFString(mCocoaViewFactoryClassName.Get()); - } - return noErr; - } - return kAudioUnitErr_InvalidProperty; - } - NO_OP(kAudioUnitProperty_SupportedChannelLayoutTags);// 32, - case kAudioUnitProperty_ParameterIDName: { // 34, - *pDataSize = sizeof(AudioUnitParameterIDName); - if (pData && scope == kAudioUnitScope_Global) { - AudioUnitParameterIDName* pIDName = (AudioUnitParameterIDName*) pData; - IParam* pParam = GetParam(pIDName->inID); - char cStr[MAX_PARAM_NAME_LEN]; - strcpy(cStr, pParam->GetNameForHost()); - if (pIDName->inDesiredLength != kAudioUnitParameterName_Full) { - int n = MIN(MAX_PARAM_NAME_LEN - 1, pIDName->inDesiredLength); - cStr[n] = '\0'; - } - pIDName->outName = MakeCFString(cStr); - } - return noErr; - } - NO_OP(kAudioUnitProperty_ParameterClumpName); // 35, - case kAudioUnitProperty_CurrentPreset: // 28, - case kAudioUnitProperty_PresentPreset: { // 36, // listenable - *pDataSize = sizeof(AUPreset); - *pWriteable = true; - if (pData) { - AUPreset* pAUPreset = (AUPreset*) pData; - pAUPreset->presetNumber = GetCurrentPresetIdx(); - const char* name = GetPresetName(pAUPreset->presetNumber); - pAUPreset->presetName = MakeCFString(name); - } - return noErr; - } - NO_OP(kAudioUnitProperty_OfflineRender); // 37, - case kAudioUnitProperty_ParameterStringFromValue: { // 33, - *pDataSize = sizeof(AudioUnitParameterStringFromValue); - if (pData && scope == kAudioUnitScope_Global) { - AudioUnitParameterStringFromValue* pSFV = (AudioUnitParameterStringFromValue*) pData; - IParam* pParam = GetParam(pSFV->inParamID); - int v = (pSFV->inValue ? *(pSFV->inValue) : pParam->Int()); - const char* str = pParam->GetDisplayText(v); - pSFV->outString = MakeCFString(str); - } - return noErr; - } - case kAudioUnitProperty_ParameterValueFromString: { // 38, - *pDataSize = sizeof(AudioUnitParameterValueFromString); - if (pData) { - AudioUnitParameterValueFromString* pVFS = (AudioUnitParameterValueFromString*) pData; - if (scope == kAudioUnitScope_Global) { - CStrLocal cStr(pVFS->inString); - IParam* pParam = GetParam(pVFS->inParamID); - int v; - if (pParam->MapDisplayText(cStr.mCStr, &v)) { - pVFS->outValue = (AudioUnitParameterValue) v; - } - } - } - return noErr; - } - NO_OP(kAudioUnitProperty_IconLocation); // 39, - NO_OP(kAudioUnitProperty_PresentationLatency); // 40, - NO_OP(kAudioUnitProperty_DependentParameters); // 45, - case kMusicDeviceProperty_InstrumentCount: { - ASSERT_SCOPE(kAudioUnitScope_Global); - if (IsInst()) { - *pDataSize = sizeof(UInt32); - if (pData) { - *((UInt32*) pData) = 1; //(mBypassed ? 1 : 0); - } - return noErr; - } - else { - return kAudioUnitErr_InvalidProperty; - } - } - - #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 - NO_OP(kAudioUnitProperty_AUHostIdentifier); // 46, - NO_OP(kAudioUnitProperty_MIDIOutputCallbackInfo); // 47, - NO_OP(kAudioUnitProperty_MIDIOutputCallback); // 48, - NO_OP(kAudioUnitProperty_InputSamplesInOutput); // 49, - NO_OP(kAudioUnitProperty_ClassInfoFromDocument); // 50 - #endif - - default: { - return kAudioUnitErr_InvalidProperty; - } - } -} - -ComponentResult IPlugAU::SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, - UInt32* pDataSize, const void* pData) -{ - Trace(TRACELOC, "(%d:%s):(%d:%s):%d", propID, AUPropertyStr(propID), scope, AUScopeStr(scope), element); - - InformListeners(propID, scope); - - switch (propID) { - - case kAudioUnitProperty_ClassInfo: { // 0, - return SetState(*((CFPropertyListRef*) pData)); - } - case kAudioUnitProperty_MakeConnection: { // 1, - ASSERT_INPUT_OR_GLOBAL_SCOPE; - AudioUnitConnection* pAUC = (AudioUnitConnection*) pData; - if (pAUC->destInputNumber >= mInBusConnections.GetSize()) { - return kAudioUnitErr_InvalidProperty; - } - InputBusConnection* pInBusConn = mInBusConnections.Get(pAUC->destInputNumber); - memset(pInBusConn, 0, sizeof(InputBusConnection)); - bool negotiatedOK = true; - if (pAUC->sourceAudioUnit) { // Opening connection. - AudioStreamBasicDescription srcASBD; - UInt32 size = sizeof(AudioStreamBasicDescription); - negotiatedOK = // Ask whoever is sending us audio what the format is. - (AudioUnitGetProperty(pAUC->sourceAudioUnit, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, pAUC->sourceOutputNumber, &srcASBD, &size) == noErr); - negotiatedOK &= // Try to set our own format to match. - (SetProperty(kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, - pAUC->destInputNumber, &size, &srcASBD) == noErr); - if (negotiatedOK) { // Connection terms successfully negotiated. - pInBusConn->mUpstreamUnit = pAUC->sourceAudioUnit; - pInBusConn->mUpstreamBusIdx = pAUC->sourceOutputNumber; - // Will the upstream unit give us a fast render proc for input? - AudioUnitRenderProc srcRenderProc; - size = sizeof(AudioUnitRenderProc); - if (AudioUnitGetProperty(pAUC->sourceAudioUnit, kAudioUnitProperty_FastDispatch, kAudioUnitScope_Global, kAudioUnitRenderSelect, - &srcRenderProc, &size) == noErr) { - // Yes, we got a fast render proc, and we also need to store the pointer to the upstream audio unit object. - pInBusConn->mUpstreamRenderProc = srcRenderProc; - pInBusConn->mUpstreamObj = GetComponentInstanceStorage(pAUC->sourceAudioUnit); - } - // Else no fast render proc, so leave the input bus connection struct's upstream render proc and upstream object empty, - // and we will need to make a component call through the component manager to get input data. - } - // Else this is a call to close the connection, which we effectively did by clearing the InputBusConnection struct, - // which counts as a successful negotiation. - } - AssessInputConnections(); - return (negotiatedOK ? noErr : kAudioUnitErr_InvalidProperty); - } - case kAudioUnitProperty_SampleRate: { // 2, - SetSampleRate(*((Float64*) pData)); - Reset(); - return noErr; - } - NO_OP(kAudioUnitProperty_ParameterList); // 3, - NO_OP(kAudioUnitProperty_ParameterInfo); // 4, - NO_OP(kAudioUnitProperty_FastDispatch); // 5, - NO_OP(kAudioUnitProperty_CPULoad); // 6, - case kAudioUnitProperty_StreamFormat: { // 8, - AudioStreamBasicDescription* pASBD = (AudioStreamBasicDescription*) pData; - int nHostChannels = pASBD->mChannelsPerFrame; - BusChannels* pBus = GetBus(scope, element); - if (!pBus) { - return kAudioUnitErr_InvalidProperty; - } - pBus->mNHostChannels = 0; - // The connection is OK if the plugin expects the same number of channels as the host is attempting to connect, - // or if the plugin supports mono channels (meaning it's flexible about how many inputs to expect) - // and the plugin supports at least as many channels as the host is attempting to connect. - bool connectionOK = (nHostChannels > 0); - connectionOK &= CheckLegalIO(scope, element, nHostChannels); - connectionOK &= (pASBD->mFormatID == kAudioFormatLinearPCM && pASBD->mFormatFlags & kAudioFormatFlagsCanonical); - - Trace(TRACELOC, "%d:%d:%s:%s:%s", - nHostChannels, pBus->mNPlugChannels, - (pASBD->mFormatID == kAudioFormatLinearPCM ? "linearPCM" : "notLinearPCM"), - (pASBD->mFormatFlags & kAudioFormatFlagsCanonical ? "canonicalFormat" : "notCanonicalFormat"), - (connectionOK ? "connectionOK" : "connectionNotOK")); - - // bool interleaved = !(pASBD->mFormatFlags & kAudioFormatFlagIsNonInterleaved); - if (connectionOK) { - pBus->mNHostChannels = nHostChannels; - if (pASBD->mSampleRate > 0.0) { - SetSampleRate(pASBD->mSampleRate); - } - } - AssessInputConnections(); - return (connectionOK ? noErr : kAudioUnitErr_InvalidProperty); - } - NO_OP(kAudioUnitProperty_ElementCount); // 11, - NO_OP(kAudioUnitProperty_Latency); // 12, - NO_OP(kAudioUnitProperty_SupportedNumChannels); // 13, - case kAudioUnitProperty_MaximumFramesPerSlice: { // 14, - SetBlockSize(*((UInt32*) pData)); - Reset(); - return noErr; - } - NO_OP(kAudioUnitProperty_SetExternalBuffer); // 15, - NO_OP(kAudioUnitProperty_ParameterValueStrings); // 16, - NO_OP(kAudioUnitProperty_GetUIComponentList); // 18, - NO_OP(kAudioUnitProperty_AudioChannelLayout); // 19, - NO_OP(kAudioUnitProperty_TailTime); // 20, - case kAudioUnitProperty_BypassEffect: { // 21, - mBypassed = (*((UInt32*) pData) != 0); - Reset(); - return noErr; - } - NO_OP(kAudioUnitProperty_LastRenderError); // 22, - case kAudioUnitProperty_SetRenderCallback: { // 23, - ASSERT_SCOPE(kAudioUnitScope_Input); // if global scope, set all - if (element >= mInBusConnections.GetSize()) { - return kAudioUnitErr_InvalidProperty; - } - InputBusConnection* pInBusConn = mInBusConnections.Get(element); - memset(pInBusConn, 0, sizeof(InputBusConnection)); - AURenderCallbackStruct* pCS = (AURenderCallbackStruct*) pData; - if (pCS->inputProc != 0) { - pInBusConn->mUpstreamRenderCallback = *pCS; - } - AssessInputConnections(); - return noErr; - } - NO_OP(kAudioUnitProperty_FactoryPresets); // 24, - NO_OP(kAudioUnitProperty_ContextName); // 25, - NO_OP(kAudioUnitProperty_RenderQuality); // 26, - case kAudioUnitProperty_HostCallbacks: { // 27, - ASSERT_SCOPE(kAudioUnitScope_Global); - memcpy(&mHostCallbacks, pData, sizeof(HostCallbackInfo)); - return noErr; - } - NO_OP(kAudioUnitProperty_InPlaceProcessing); // 29, - NO_OP(kAudioUnitProperty_ElementName); // 30, - NO_OP(kAudioUnitProperty_CocoaUI); // 31, - NO_OP(kAudioUnitProperty_SupportedChannelLayoutTags); // 32, - NO_OP(kAudioUnitProperty_ParameterIDName); // 34, - NO_OP(kAudioUnitProperty_ParameterClumpName); // 35, - case kAudioUnitProperty_CurrentPreset: // 28, - case kAudioUnitProperty_PresentPreset: { // 36, - int presetIdx = ((AUPreset*) pData)->presetNumber; - RestorePreset(presetIdx); - return noErr; - } - NO_OP(kAudioUnitProperty_OfflineRender); // 37, - NO_OP(kAudioUnitProperty_ParameterStringFromValue); // 33, - NO_OP(kAudioUnitProperty_ParameterValueFromString); // 38, - NO_OP(kAudioUnitProperty_IconLocation); // 39, - NO_OP(kAudioUnitProperty_PresentationLatency); // 40, - NO_OP(kAudioUnitProperty_DependentParameters); // 45, - - #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 - case kAudioUnitProperty_AUHostIdentifier: { // 46, - AUHostIdentifier* pHostID = (AUHostIdentifier*) pData; - CStrLocal hostStr(pHostID->hostName); - int hostVer = (pHostID->hostVersion.majorRev << 16) + (pHostID->hostVersion.minorAndBugRev << 8); - SetHost("", hostStr.mCStr, hostVer); - return noErr; - } - NO_OP(kAudioUnitProperty_MIDIOutputCallbackInfo); // 47, - NO_OP(kAudioUnitProperty_MIDIOutputCallback); // 48, - NO_OP(kAudioUnitProperty_InputSamplesInOutput); // 49, - NO_OP(kAudioUnitProperty_ClassInfoFromDocument) // 50 - #endif - - default: { - return kAudioUnitErr_InvalidProperty; - } - } -} - -const char* AUInputTypeStr(IPlugAU::EAUInputType type) -{ - switch (type) { - case IPlugAU::eDirectFastProc: return "DirectFastProc"; - case IPlugAU::eDirectNoFastProc: return "DirectNoFastProc"; - case IPlugAU::eRenderCallback: return "RenderCallback"; - case IPlugAU::eNotConnected: - default: return "NotConnected"; - } -} - -int IPlugAU::NHostChannelsConnected(WDL_PtrList* pBuses, int excludeIdx) -{ - bool init = false; - int nCh = 0, n = pBuses->GetSize(); - for (int i = 0; i < n; ++i) { - if (i != excludeIdx) { - int nHostChannels = pBuses->Get(i)->mNHostChannels; - if (nHostChannels >= 0) { - nCh += nHostChannels; - init = true; - } - } - } - if (init) { - return nCh; - } - return -1; -} - -bool IPlugAU::CheckLegalIO(AudioUnitScope scope, int busIdx, int nChannels) -{ - if (scope == kAudioUnitScope_Input) { - int nIn = MAX(NHostChannelsConnected(&mInBuses, busIdx), 0); - int nOut = (mActive ? NHostChannelsConnected(&mOutBuses) : -1); - return LegalIO(nIn + nChannels, nOut); - } - else { - int nIn = (mActive ? NHostChannelsConnected(&mInBuses) : -1); - int nOut = MAX(NHostChannelsConnected(&mOutBuses, busIdx), 0); - return LegalIO(nIn, nOut + nChannels); - } -} - -bool IPlugAU::CheckLegalIO() -{ - int nIn = NHostChannelsConnected(&mInBuses); - int nOut = NHostChannelsConnected(&mOutBuses); - return ((!nIn && !nOut) || LegalIO(nIn, nOut)); -} - -void IPlugAU::AssessInputConnections() -{ - TRACE; - IMutexLock lock(this); - - SetInputChannelConnections(0, NInChannels(), false); - - int nIn = mInBuses.GetSize(); - for (int i = 0; i < nIn; ++i) { - BusChannels* pInBus = mInBuses.Get(i); - InputBusConnection* pInBusConn = mInBusConnections.Get(i); - - // AU supports 3 ways to get input from the host (or whoever is upstream). - if (pInBusConn->mUpstreamRenderProc && pInBusConn->mUpstreamObj) { - // 1: direct input connection with fast render proc (and buffers) supplied by the upstream unit. - pInBusConn->mInputType = eDirectFastProc; - } - else - if (pInBusConn->mUpstreamUnit) { - // 2: direct input connection with no render proc, buffers supplied by the upstream unit. - pInBusConn->mInputType = eDirectNoFastProc; - } - else - if (pInBusConn->mUpstreamRenderCallback.inputProc) { - // 3: no direct connection, render callback, buffers supplied by us. - pInBusConn->mInputType = eRenderCallback; - } - else { - pInBusConn->mInputType = eNotConnected; - } - pInBus->mConnected = (pInBusConn->mInputType != eNotConnected); - - int startChannelIdx = pInBus->mPlugChannelStartIdx; - if (pInBus->mConnected) { - // There's an input connection, so we need to tell the plug to expect however many channels - // are in the negotiated host stream format. - if (pInBus->mNHostChannels < 0) { - // The host set up a connection without specifying how many channels in the stream. - // Assume the host will send all the channels the plugin asks for, and hope for the best. - Trace(TRACELOC, "AssumeChannels:%d", pInBus->mNPlugChannels); - pInBus->mNHostChannels = pInBus->mNPlugChannels; - } - int nConnected = pInBus->mNHostChannels; - int nUnconnected = MAX(pInBus->mNPlugChannels - nConnected, 0); - SetInputChannelConnections(startChannelIdx, nConnected, true); - SetInputChannelConnections(startChannelIdx + nConnected, nUnconnected, false); - } - - Trace(TRACELOC, "%d:%s:%d:%d:%d", i, AUInputTypeStr(pInBusConn->mInputType), startChannelIdx, pInBus->mNPlugChannels, pInBus->mNHostChannels); - } -} - -inline void PutNumberInDict(CFMutableDictionaryRef pDict, const char* key, void* pNumber, CFNumberType type) -{ - CFStrLocal cfKey(key); - CFNumberRef pValue = CFNumberCreate(0, type, pNumber); - CFDictionarySetValue(pDict, cfKey.mCFStr, pValue); - CFRelease(pValue); -} - -inline void PutStrInDict(CFMutableDictionaryRef pDict, const char* key, const char* value) -{ - CFStrLocal cfKey(key); - CFStrLocal cfValue(value); - CFDictionarySetValue(pDict, cfKey.mCFStr, cfValue.mCFStr); -} - -inline void PutDataInDict(CFMutableDictionaryRef pDict, const char* key, ByteChunk* pChunk) -{ - CFStrLocal cfKey(key); - CFDataRef pData = CFDataCreate(0, pChunk->GetBytes(), pChunk->Size()); - CFDictionarySetValue(pDict, cfKey.mCFStr, pData); - CFRelease(pData); -} - -inline bool GetNumberFromDict(CFDictionaryRef pDict, const char* key, void* pNumber, CFNumberType type) -{ - CFStrLocal cfKey(key); - CFNumberRef pValue = (CFNumberRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); - if (pValue) { - CFNumberGetValue(pValue, type, pNumber); - return true; - } - return false; -} - -inline bool GetStrFromDict(CFDictionaryRef pDict, const char* key, char* value) -{ - CFStrLocal cfKey(key); - CFStringRef pValue = (CFStringRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); - if (pValue) { - CStrLocal cStr(pValue); - strcpy(value, cStr.mCStr); - return true; - } - value[0] = '\0'; - return false; -} - -inline bool GetDataFromDict(CFDictionaryRef pDict, const char* key, ByteChunk* pChunk) -{ - CFStrLocal cfKey(key); - CFDataRef pData = (CFDataRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); - if (pData) { - int n = CFDataGetLength(pData); - pChunk->Resize(n); - memcpy(pChunk->GetBytes(), CFDataGetBytePtr(pData), n); - return true; - } - return false; -} - -ComponentResult IPlugAU::GetState(CFPropertyListRef* ppPropList) -{ - ComponentDescription cd; - ComponentResult r = GetComponentInfo((Component) mCI, &cd, 0, 0, 0); - if (r != noErr) { - return r; - } - - CFMutableDictionaryRef pDict = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - int version = GetEffectVersion(false); - PutNumberInDict(pDict, kAUPresetVersionKey, &version, kCFNumberSInt32Type); - PutNumberInDict(pDict, kAUPresetTypeKey, &(cd.componentType), kCFNumberSInt32Type); - PutNumberInDict(pDict, kAUPresetSubtypeKey, &(cd.componentSubType), kCFNumberSInt32Type); - PutNumberInDict(pDict, kAUPresetManufacturerKey, &(cd.componentManufacturer), kCFNumberSInt32Type); - PutStrInDict(pDict, kAUPresetNameKey, GetPresetName(GetCurrentPresetIdx())); - - ByteChunk chunk; - if (DoesStateChunks()) { - if (SerializeState(&chunk)) { - PutDataInDict(pDict, kAUPresetDataKey, &chunk); - } - } - else { - SerializeParams(&chunk); - PutDataInDict(pDict, kAUPresetDataKey, &chunk); - } - - *ppPropList = pDict; -TRACE; - return noErr; -} - -ComponentResult IPlugAU::SetState(CFPropertyListRef pPropList) -{ - ComponentDescription cd; - ComponentResult r = GetComponentInfo((Component) mCI, &cd, 0, 0, 0); - if (r != noErr) { - return r; - } - - CFDictionaryRef pDict = (CFDictionaryRef) pPropList; - int version, type, subtype, mfr; - char presetName[64]; - if (!GetNumberFromDict(pDict, kAUPresetVersionKey, &version, kCFNumberSInt32Type) || - !GetNumberFromDict(pDict, kAUPresetTypeKey, &type, kCFNumberSInt32Type) || - !GetNumberFromDict(pDict, kAUPresetSubtypeKey, &subtype, kCFNumberSInt32Type) || - !GetNumberFromDict(pDict, kAUPresetManufacturerKey, &mfr, kCFNumberSInt32Type) || - !GetStrFromDict(pDict, kAUPresetNameKey, presetName) || - //version != GetEffectVersion(false) || - type != cd.componentType || - subtype != cd.componentSubType || - mfr != cd.componentManufacturer) { - return kAudioUnitErr_InvalidPropertyValue; - } - RestorePreset(presetName); - - ByteChunk chunk; - if (!GetDataFromDict(pDict, kAUPresetDataKey, &chunk)) { - return kAudioUnitErr_InvalidPropertyValue; - } - - if (DoesStateChunks()) { - if (!UnserializeState(&chunk, 0)) { - return kAudioUnitErr_InvalidPropertyValue; - } - } - else { - if (!UnserializeParams(&chunk, 0)) { - return kAudioUnitErr_InvalidPropertyValue; - } - } - - RedrawParamControls(); - return noErr; -} - -// pData == 0 means return property info only. -ComponentResult IPlugAU::GetProc(AudioUnitElement element, UInt32* pDataSize, void* pData) -{ - Trace(TRACELOC, "%s:(%d:%s)", (pData ? "" : "Info"), element, AUSelectStr(element)); - - switch (element) { - case kAudioUnitGetParameterSelect: { - *pDataSize = sizeof(AudioUnitGetParameterProc); - if (pData) { - *((AudioUnitGetParameterProc*) pData) = (AudioUnitGetParameterProc) IPlugAU::GetParamProc; - } - return noErr; - } - case kAudioUnitSetParameterSelect: { - *pDataSize = sizeof(AudioUnitSetParameterProc); - if (pData) { - *((AudioUnitSetParameterProc*) pData) = (AudioUnitSetParameterProc) IPlugAU::SetParamProc; - } - return noErr; - } - case kAudioUnitRenderSelect: { - *pDataSize = sizeof(AudioUnitRenderProc); - if (pData) { - *((AudioUnitRenderProc*) pData) = (AudioUnitRenderProc) IPlugAU::RenderProc; - } - return noErr; - } - default: - return kAudioUnitErr_InvalidElement; - } -} - -// static -ComponentResult IPlugAU::GetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, - AudioUnitParameterValue* pValue) -{ - Trace(TRACELOC, "%d:(%d:%s):%d", paramID, scope, AUScopeStr(scope), element); - - ASSERT_SCOPE(kAudioUnitScope_Global); - IPlugAU* _this = (IPlugAU*) pPlug; - IMutexLock lock(_this); - *pValue = _this->GetParam(paramID)->Value(); - return noErr; -} - -// static -ComponentResult IPlugAU::SetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, - AudioUnitParameterValue value, UInt32 offsetFrames) -{ - Trace(TRACELOC, "%d:(%d:%s):%d", paramID, scope, AUScopeStr(scope), element); - - // In the SDK, offset frames is only looked at in group scope. - ASSERT_SCOPE(kAudioUnitScope_Global); - IPlugAU* _this = (IPlugAU*) pPlug; - IMutexLock lock(_this); - IParam* pParam = _this->GetParam(paramID); - pParam->Set(value); - if (_this->GetGUI()) { - _this->GetGUI()->SetParameterFromPlug(paramID, value, false); - } - _this->OnParamChange(paramID); - return noErr; -} - -struct BufferList { - int mNumberBuffers; - AudioBuffer mBuffers[MAX_IO_CHANNELS]; -}; - -inline ComponentResult RenderCallback(AURenderCallbackStruct* pCB, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, - UInt32 inputBusIdx, UInt32 nFrames, AudioBufferList* pOutBufList) -{ - TRACE; - return pCB->inputProc(pCB->inputProcRefCon, pFlags, pTimestamp, inputBusIdx, nFrames, pOutBufList); -} - -// static -ComponentResult IPlugAU::RenderProc(void* pPlug, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, - UInt32 outputBusIdx, UInt32 nFrames, AudioBufferList* pOutBufList) -{ - Trace(TRACELOC, "%d:%d:%d", outputBusIdx, pOutBufList->mNumberBuffers, nFrames); - - IPlugAU* _this = (IPlugAU*) pPlug; - if (_this->mBypassed) { - return noErr; - } - - if (!(pTimestamp->mFlags & kAudioTimeStampSampleTimeValid) || - outputBusIdx >= _this->mOutBuses.GetSize() || - nFrames > _this->GetBlockSize()) { - return kAudioUnitErr_InvalidPropertyValue; - } - - int nRenderNotify = _this->mRenderNotify.GetSize(); - if (nRenderNotify) { - for (int i = 0; i < nRenderNotify; ++i) { - AURenderCallbackStruct* pRN = _this->mRenderNotify.Get(i); - AudioUnitRenderActionFlags flags = kAudioUnitRenderAction_PreRender; - RenderCallback(pRN, &flags, pTimestamp, outputBusIdx, nFrames, pOutBufList); - } - } - - double renderTimestamp = pTimestamp->mSampleTime; - if (renderTimestamp != _this->mRenderTimestamp) { // Pull input buffers. - - BufferList bufList; - AudioBufferList* pInBufList = (AudioBufferList*) &bufList; - - int nIn = _this->mInBuses.GetSize(); - for (int i = 0; i < nIn; ++i) { - BusChannels* pInBus = _this->mInBuses.Get(i); - InputBusConnection* pInBusConn = _this->mInBusConnections.Get(i); - - if (pInBus->mConnected) { - pInBufList->mNumberBuffers = pInBus->mNHostChannels; - for (int b = 0; b < pInBufList->mNumberBuffers; ++b) { - AudioBuffer* pBuffer = &(pInBufList->mBuffers[b]); - pBuffer->mNumberChannels = 1; - pBuffer->mDataByteSize = nFrames * sizeof(AudioSampleType); - pBuffer->mData = 0; - } - - AudioUnitRenderActionFlags flags = 0; - ComponentResult r = noErr; - switch (pInBusConn->mInputType) { - case eDirectFastProc: { - r = pInBusConn->mUpstreamRenderProc(pInBusConn->mUpstreamObj, &flags, pTimestamp, pInBusConn->mUpstreamBusIdx, nFrames, pInBufList); - break; - } - case eDirectNoFastProc: { - r = AudioUnitRender(pInBusConn->mUpstreamUnit, &flags, pTimestamp, pInBusConn->mUpstreamBusIdx, nFrames, pInBufList); - break; - } - case eRenderCallback: { - AudioSampleType* pScratchInput = _this->mInScratchBuf.Get() + pInBus->mPlugChannelStartIdx * nFrames; - for (int b = 0; b < pInBufList->mNumberBuffers; ++b, pScratchInput += nFrames) { - pInBufList->mBuffers[b].mData = pScratchInput; - } - r = RenderCallback(&(pInBusConn->mUpstreamRenderCallback), &flags, pTimestamp, i /* 0 */, nFrames, pInBufList); - break; - } - default: { - bool inputBusAssessed = false; - assert(inputBusAssessed); // InputBus.mConnected should be false, we didn't correctly assess the input connections. - } - } - if (r != noErr) { - return r; // Something went wrong upstream. - } - - for (int i = 0, chIdx = pInBus->mPlugChannelStartIdx; i < pInBus->mNHostChannels; ++i, ++chIdx) { - _this->AttachInputBuffers(chIdx, 1, (AudioSampleType**) &(pInBufList->mBuffers[i].mData), nFrames); - } - } - } - _this->mRenderTimestamp = renderTimestamp; - } - - BusChannels* pOutBus = _this->mOutBuses.Get(outputBusIdx); - if (!(pOutBus->mConnected) || pOutBus->mNHostChannels != pOutBufList->mNumberBuffers) { - int startChannelIdx = pOutBus->mPlugChannelStartIdx; - int nConnected = MIN(pOutBus->mNHostChannels, pOutBufList->mNumberBuffers); - int nUnconnected = MAX(pOutBus->mNPlugChannels - nConnected, 0); - _this->SetOutputChannelConnections(startChannelIdx, nConnected, true); - _this->SetOutputChannelConnections(startChannelIdx + nConnected, nUnconnected, false); - pOutBus->mConnected = true; - } - - for (int i = 0, chIdx = pOutBus->mPlugChannelStartIdx; i < pOutBufList->mNumberBuffers; ++i, ++chIdx) { - if (!(pOutBufList->mBuffers[i].mData)) { // Grr. Downstream unit didn't give us buffers. - pOutBufList->mBuffers[i].mData = _this->mOutScratchBuf.Get() + chIdx * nFrames; - } - _this->AttachOutputBuffers(chIdx, 1, (AudioSampleType**) &(pOutBufList->mBuffers[i].mData)); - } - - _this->ProcessBuffers((AudioSampleType) 0, nFrames); - - if (nRenderNotify) { - for (int i = 0; i < nRenderNotify; ++i) { - AURenderCallbackStruct* pRN = _this->mRenderNotify.Get(i); - AudioUnitRenderActionFlags flags = kAudioUnitRenderAction_PostRender; - RenderCallback(pRN, &flags, pTimestamp, outputBusIdx, nFrames, pOutBufList); - } - } - - return noErr; -} - -IPlugAU::BusChannels* IPlugAU::GetBus(AudioUnitScope scope, AudioUnitElement busIdx) -{ - if (scope == kAudioUnitScope_Input && busIdx >= 0 && busIdx < mInBuses.GetSize()) { - return mInBuses.Get(busIdx); - } - if (scope == kAudioUnitScope_Output && busIdx >= 0 && busIdx < mOutBuses.GetSize()) { - return mOutBuses.Get(busIdx); - } - // Global bus is an alias for output bus zero. - if (scope == kAudioUnitScope_Global && mOutBuses.GetSize()) { - return mOutBuses.Get(busIdx); - } - return 0; -} - -// Garageband doesn't always report tempo when the transport is stopped, so we need it to persist in the class. -#define DEFAULT_TEMPO 120.0 - -void IPlugAU::ClearConnections() -{ - int nInBuses = mInBuses.GetSize(); - for (int i = 0,; i < nInBuses; ++i) { - BusChannels* pInBus = mInBuses.Get(i); - pInBus->mConnected = false; - pInBus->mNHostChannels = -1; - InputBusConnection* pInBusConn = mInBusConnections.Get(i); - memset(pInBusConn, 0, sizeof(InputBusConnection)); - } - int nOutBuses = mOutBuses.GetSize(); - for (int i = 0,; i < nOutBuses; ++i) { - BusChannels* pOutBus = mOutBuses.Get(i); - pOutBus->mConnected = false; - pOutBus->mNHostChannels = -1; - } -} - -IPlugAU::IPlugAU(IPlugInstanceInfo instanceInfo, - int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency, - bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) -: IPlugBase(nParams, channelIOStr, nPresets, - effectName, productName, mfrName, vendorVersion, uniqueID, mfrID, latency, - plugDoesMidi, plugDoesChunks, plugIsInst), - mCI(0), mBypassed(false), mRenderTimestamp(-1.0), mTempo(DEFAULT_TEMPO), mActive(false) -{ - Trace(TRACELOC, "%s", effectName); - - memset(&mHostCallbacks, 0, sizeof(HostCallbackInfo)); - memset(&mMidiCallback, 0, sizeof(AUMIDIOutputCallbackStruct)); - - mOSXBundleID.Set(instanceInfo.mOSXBundleID.Get()); - mCocoaViewFactoryClassName.Set(instanceInfo.mCocoaViewFactoryClassName.Get()); - - // Every channel pair requested on input or output is a separate bus. - int nInputs = NInChannels(), nOutputs = NOutChannels(); - int nInBuses = (int) ceil(nInputs / 2); - int nOutBuses = (int) ceil(nOutputs / 2); - - PtrListInitialize(&mInBusConnections, nInBuses); - PtrListInitialize(&mInBuses, nInBuses); - PtrListInitialize(&mOutBuses, nOutBuses); - - for (int i = 0, startCh = 0; i < nInBuses; ++i, startCh += 2) { - BusChannels* pInBus = mInBuses.Get(i); - pInBus->mNHostChannels = -1; - pInBus->mPlugChannelStartIdx = startCh; - pInBus->mNPlugChannels = MIN(nInputs - startCh, 2); - } - for (int i = 0, startCh = 0; i < nOutBuses; ++i, startCh += 2) { - BusChannels* pOutBus = mOutBuses.Get(i); - pOutBus->mNHostChannels = -1; - pOutBus->mPlugChannelStartIdx = startCh; - pOutBus->mNPlugChannels = MIN(nOutputs - startCh, 2); - } - - AssessInputConnections(); - - SetBlockSize(DEFAULT_BLOCK_SIZE); -} - -IPlugAU::~IPlugAU() -{ - mRenderNotify.Empty(true); - mInBuses.Empty(true); - mOutBuses.Empty(true); - mInBusConnections.Empty(true); - mPropertyListeners.Empty(true); -} - -void SendAUEvent(AudioUnitEventType type, ComponentInstance ci, int idx) -{ - AudioUnitEvent auEvent; - memset(&auEvent, 0, sizeof(AudioUnitEvent)); - auEvent.mEventType = type; - auEvent.mArgument.mParameter.mAudioUnit = ci; - auEvent.mArgument.mParameter.mParameterID = idx; - auEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global; - auEvent.mArgument.mParameter.mElement = 0; - AUEventListenerNotify(0, 0, &auEvent); -} - -void IPlugAU::BeginInformHostOfParamChange(int idx) -{ - Trace(TRACELOC, "%d", idx); - SendAUEvent(kAudioUnitEvent_BeginParameterChangeGesture, mCI, idx); -} - -void IPlugAU::InformHostOfParamChange(int idx, double normalizedValue) -{ - Trace(TRACELOC, "%d:%f", idx, normalizedValue); - SendAUEvent(kAudioUnitEvent_ParameterValueChange, mCI, idx); -} - -void IPlugAU::EndInformHostOfParamChange(int idx) -{ - Trace(TRACELOC, "%d", idx); - SendAUEvent(kAudioUnitEvent_EndParameterChangeGesture, mCI, idx); -} - -// Samples since start of project. -int IPlugAU::GetSamplePos() -{ - if (mHostCallbacks.transportStateProc) { - double samplePos = 0.0, loopStartBeat, loopEndBeat; - Boolean playing, changed, looping; - mHostCallbacks.transportStateProc(mHostCallbacks.hostUserData, &playing, &changed, &samplePos, - &looping, &loopStartBeat, &loopEndBeat); - return (int) samplePos; - } - return 0; -} - -double IPlugAU::GetTempo() -{ - if (mHostCallbacks.beatAndTempoProc) { - double currentBeat = 0.0, tempo = 0.0; - mHostCallbacks.beatAndTempoProc(mHostCallbacks.hostUserData, ¤tBeat, &tempo); - if (tempo > 0.0) { - mTempo = tempo; - } - } - return mTempo; -} - -void IPlugAU::GetTimeSig(int* pNum, int* pDenom) -{ - UInt32 sampleOffsetToNextBeat = 0, tsDenom = 0; - float tsNum = 0.0f; - double currentMeasureDownBeat = 0.0; - if (mHostCallbacks.musicalTimeLocationProc) { - mHostCallbacks.musicalTimeLocationProc(mHostCallbacks.hostUserData, &sampleOffsetToNextBeat, - &tsNum, &tsDenom, ¤tMeasureDownBeat); - *pNum = (int) tsNum; - *pDenom = (int) tsDenom; - } -} - -EHost IPlugAU::GetHost() -{ - EHost host = IPlugBase::GetHost(); - if (host == kHostUninit) { - CFBundleRef mainBundle = CFBundleGetMainBundle(); - if (mainBundle) { - CFStringRef id = CFBundleGetIdentifier(mainBundle); - if (id) { - CStrLocal str(id); - SetHost(str.mCStr, 0); - host = IPlugBase::GetHost(); - } - } - if (host == kHostUninit) { - SetHost("", 0); - host = IPlugBase::GetHost(); - } - } - return host; -} - -void IPlugAU::HostSpecificInit() -{ - EHost host = GetHost(); -} - -void IPlugAU::SetBlockSize(int blockSize) -{ - TRACE; - int nIn = NInChannels() * blockSize; - int nOut = NOutChannels() * blockSize; - mInScratchBuf.Resize(nIn); - mOutScratchBuf.Resize(nOut); - memset(mInScratchBuf.Get(), 0, nIn * sizeof(AudioSampleType)); - memset(mOutScratchBuf.Get(), 0, nOut * sizeof(AudioSampleType)); - IPlugBase::SetBlockSize(blockSize); -} - -void IPlugAU::InformListeners(AudioUnitPropertyID propID, AudioUnitScope scope) -{ - TRACE; - int i, n = mPropertyListeners.GetSize(); - for (i = 0; i < n; ++i) { - PropertyListener* pListener = mPropertyListeners.Get(i); - if (pListener->mPropID == propID) { - pListener->mListenerProc(pListener->mProcArgs, mCI, propID, scope, 0); - } - } -} - -void IPlugAU::SetLatency(int samples) -{ - TRACE; - int i, n = mPropertyListeners.GetSize(); - for (i = 0; i < n; ++i) { - PropertyListener* pListener = mPropertyListeners.Get(i); - if (pListener->mPropID == kAudioUnitProperty_Latency) { - pListener->mListenerProc(pListener->mProcArgs, mCI, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0); - } - } - IPlugBase::SetLatency(samples); -} - -bool IPlugAU::SendMidiMsg(IMidiMsg* pMsg) -{ - // I believe AU passes midi messages through automatically. - // For the case where we're generating midi messages, we'll use AUMIDIOutputCallback. - // See AudioUnitProperties.h. - if (mMidiCallback.midiOutputCallback) { - // Todo. - } - return false; -} - -bool IPlugAU::SendMidiMsgs(WDL_TypedBuf* pMsgs) -{ - int i, n = pMsgs->GetSize(); - IMidiMsg* pMsg = pMsgs->Get(); - for (i = 0; i < n; ++i, ++pMsg) { - SendMidiMsg(pMsg); - } - return true; -} diff --git a/WDL/IPlug/IPlugAU.h b/WDL/IPlug/IPlugAU.h deleted file mode 100644 index ddea6040..00000000 --- a/WDL/IPlug/IPlugAU.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef _IPLUGAPI_ -#define _IPLUGAPI_ -// Only load one API class! - -#include "IPlugBase.h" -#include -#include -#include -#include -#include - -// Argh! -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 - typedef Float32 AudioSampleType; - typedef Float32 AudioUnitParameterValue; - typedef OSStatus (*AUMIDIOutputCallback)(void*, const AudioTimeStamp*, UInt32, const struct MIDIPacketList*); - struct AUMIDIOutputCallbackStruct { AUMIDIOutputCallback midiOutputCallback; void* userData; }; - #define kAudioFormatFlagsCanonical (kAudioFormatFlagIsFloat|kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsPacked) -#endif - -#define MAX_IO_CHANNELS 128 - -struct IPlugInstanceInfo -{ - WDL_String mOSXBundleID, mCocoaViewFactoryClassName; -}; - -class IPlugAU : public IPlugBase -{ -public: - - // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). - IPlugAU(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency, - bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst); - - virtual ~IPlugAU(); - - // ---------------------------------------- - // See IPlugBase for the full list of methods that your plugin class can implement. - - void BeginInformHostOfParamChange(int idx); - void InformHostOfParamChange(int idx, double normalizedValue); - void EndInformHostOfParamChange(int idx); - - int GetSamplePos(); // Samples since start of project. - double GetTempo(); - void GetTimeSig(int* pNum, int* pDenom); - EHost GetHost(); // GetHostVersion() is inherited. - - // Tell the host that the graphics resized. - // Should be called only by the graphics object when it resizes itself. - void ResizeGraphics(int w, int h) {} - - enum EAUInputType { - eNotConnected = 0, - eDirectFastProc, - eDirectNoFastProc, - eRenderCallback - }; - -protected: - - void HostSpecificInit(); - void SetBlockSize(int blockSize); - void SetLatency(int samples); - bool SendMidiMsg(IMidiMsg* pMsg); - bool SendMidiMsgs(WDL_TypedBuf* pMsgs); - -private: - - WDL_String mOSXBundleID, mCocoaViewFactoryClassName; - ComponentInstance mCI; - bool mActive, mBypassed; - double mRenderTimestamp, mTempo; - HostCallbackInfo mHostCallbacks; - - // InScratchBuf is only needed if the upstream connection is a callback. - // OutScratchBuf is only needed if the downstream connection fails to give us a buffer. - WDL_TypedBuf mInScratchBuf, mOutScratchBuf; - WDL_PtrList mRenderNotify; - AUMIDIOutputCallbackStruct mMidiCallback; - - // Every stereo pair of plugin input or output is a bus. - // Buses can have zero host channels if the host hasn't connected the bus at all, - // one host channel if the plugin supports mono and the host has supplied a mono stream, - // or two host channels if the host has supplied a stereo stream. - struct BusChannels { - bool mConnected; - int mNHostChannels, mNPlugChannels, mPlugChannelStartIdx; - }; - WDL_PtrList mInBuses, mOutBuses; - BusChannels* GetBus(AudioUnitScope scope, AudioUnitElement busIdx); - int NHostChannelsConnected(WDL_PtrList* pBuses, int excludeIdx = -1); - void ClearConnections(); - - struct InputBusConnection { - void* mUpstreamObj; - AudioUnit mUpstreamUnit; - int mUpstreamBusIdx; - AudioUnitRenderProc mUpstreamRenderProc; - AURenderCallbackStruct mUpstreamRenderCallback; - EAUInputType mInputType; - }; - WDL_PtrList mInBusConnections; - - bool CheckLegalIO(AudioUnitScope scope, int busIdx, int nChannels); - bool CheckLegalIO(); - void AssessInputConnections(); - - struct PropertyListener { - AudioUnitPropertyID mPropID; - AudioUnitPropertyListenerProc mListenerProc; - void* mProcArgs; - }; - WDL_PtrList mPropertyListeners; - - ComponentResult GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, - UInt32* pDataSize, Boolean* pWriteable); - ComponentResult GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, - UInt32* pDataSize, Boolean* pWriteable, void* pData); - ComponentResult SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, - UInt32* pDataSize, const void* pData); - ComponentResult GetProc(AudioUnitElement element, UInt32* pDataSize, void* pData); - ComponentResult GetState(CFPropertyListRef* ppPropList); - ComponentResult SetState(CFPropertyListRef pPropList); - void InformListeners(AudioUnitPropertyID propID, AudioUnitScope scope); - - -public: - - static ComponentResult IPlugAUEntry(ComponentParameters *params, void* pVPlug); - static ComponentResult IPlugAUCarbonViewEntry(ComponentParameters *params, void* pView); - static ComponentResult GetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, - AudioUnitParameterValue* pValue); - static ComponentResult SetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, - AudioUnitParameterValue value, UInt32 offsetFrames); - static ComponentResult RenderProc(void* pPlug, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, - UInt32 outputBusIdx, UInt32 nFrames, AudioBufferList* pBufferList); -}; - -IPlugAU* MakePlug(); - -#endif - - diff --git a/WDL/IPlug/IPlugAU.r b/WDL/IPlug/IPlugAU.r deleted file mode 100644 index b6d13b11..00000000 --- a/WDL/IPlug/IPlugAU.r +++ /dev/null @@ -1,140 +0,0 @@ -#include "resource.h" // This is your plugin's resource.h. -#include - -#define UseExtendedThingResource 1 - -#include - -// this is a define used to indicate that a component has no static data that would mean -// that no more than one instance could be open at a time - never been true for AUs -#ifndef cmpThreadSafeOnMac -#define cmpThreadSafeOnMac 0x10000000 -#endif - -#undef TARGET_REZ_MAC_PPC -#ifdef ppc_YES - #define TARGET_REZ_MAC_PPC 1 -#else - #define TARGET_REZ_MAC_PPC 0 -#endif - -#undef TARGET_REZ_MAC_X86 -#ifdef i386_YES - #define TARGET_REZ_MAC_X86 1 -#else - #define TARGET_REZ_MAC_X86 0 -#endif - -#if TARGET_OS_MAC - #if TARGET_REZ_MAC_PPC && TARGET_REZ_MAC_X86 - #define TARGET_REZ_FAT_COMPONENTS 1 - #define Target_PlatformType platformPowerPCNativeEntryPoint - #define Target_SecondPlatformType platformIA32NativeEntryPoint - #elif TARGET_REZ_MAC_X86 - #define Target_PlatformType platformIA32NativeEntryPoint - #else - #define Target_PlatformType platformPowerPCNativeEntryPoint - #endif - #define Target_CodeResType 'dlle' - #define TARGET_REZ_USE_DLLE 1 -#else - #error get a real platform type -#endif // not TARGET_OS_MAC - -#ifndef TARGET_REZ_FAT_COMPONENTS - #define TARGET_REZ_FAT_COMPONENTS 0 -#endif - -// ---------------- - -//#ifdef _DEBUG -// #define PLUG_PUBLIC_NAME PLUG_NAME "_DEBUG" -//#else -#define PLUG_PUBLIC_NAME PLUG_NAME -//#endif - -#define RES_ID 1000 -#define RES_NAME PLUG_MFR ": " PLUG_PUBLIC_NAME - -resource 'STR ' (RES_ID, purgeable) { - RES_NAME -}; - -resource 'STR ' (RES_ID + 1, purgeable) { - PLUG_PUBLIC_NAME " AU" -}; - -resource 'dlle' (RES_ID) { - PLUG_ENTRY_STR -}; - -resource 'thng' (RES_ID, RES_NAME) { -#if PLUG_IS_INST - kAudioUnitType_MusicDevice, -#else - kAudioUnitType_Effect, -#endif - PLUG_UNIQUE_ID, - PLUG_MFR_ID, - 0, 0, 0, 0, // no 68K - 'STR ', RES_ID, - 'STR ', RES_ID + 1, - 0, 0, // icon - PLUG_VER, - componentHasMultiplePlatforms | componentDoAutoVersion, - 0, - { - cmpThreadSafeOnMac, - Target_CodeResType, RES_ID, - Target_PlatformType, -#if TARGET_REZ_FAT_COMPONENTS - cmpThreadSafeOnMac, - Target_CodeResType, RES_ID, - Target_SecondPlatformType, -#endif - } -}; - -#undef RES_ID -#define RES_ID 2000 -#undef RES_NAME -#define RES_NAME PLUG_MFR ": " PLUG_PUBLIC_NAME " Carbon View" - -resource 'STR ' (RES_ID, purgeable) { - RES_NAME -}; - -resource 'STR ' (RES_ID + 1, purgeable) { - PLUG_PUBLIC_NAME " AU Carbon View" -}; - -resource 'dlle' (RES_ID) { - PLUG_VIEW_ENTRY_STR -}; - -resource 'thng' (RES_ID, RES_NAME) { - kAudioUnitCarbonViewComponentType, - PLUG_UNIQUE_ID, - PLUG_MFR_ID, - 0, 0, 0, 0, // no 68K - 'STR ', RES_ID, - 'STR ', RES_ID + 1, - 0, 0, // icon - PLUG_VER, - componentHasMultiplePlatforms | componentDoAutoVersion, - 0, - { - cmpThreadSafeOnMac, - Target_CodeResType, RES_ID, - Target_PlatformType, -#if TARGET_REZ_FAT_COMPONENTS - cmpThreadSafeOnMac, - Target_CodeResType, RES_ID, - Target_SecondPlatformType, -#endif - } -}; - -#undef RES_ID - - diff --git a/WDL/IPlug/IPlugAU_ViewFactory.mm b/WDL/IPlug/IPlugAU_ViewFactory.mm deleted file mode 100644 index da6ce9af..00000000 --- a/WDL/IPlug/IPlugAU_ViewFactory.mm +++ /dev/null @@ -1,50 +0,0 @@ -#import -#include "../IPlug/IGraphicsCocoa.h" -#include "resource.h" // This is your plugin's resource.h. - -@interface VIEW_CLASS : NSObject -{ - IPlugBase* mPlug; -} -- (id) init; -- (NSView*) uiViewForAudioUnit: (AudioUnit) audioUnit withSize: (NSSize) preferredSize; -- (unsigned) interfaceVersion; -- (NSString*) description; -@end - -@implementation VIEW_CLASS - -- (id) init -{ - TRACE; - mPlug = 0; - return [super init]; -} - -- (NSView*) uiViewForAudioUnit: (AudioUnit) audioUnit withSize: (NSSize) preferredSize -{ - TRACE; - mPlug = (IPlugBase*) GetComponentInstanceStorage(audioUnit); - if (mPlug) { - IGraphics* pGraphics = mPlug->GetGUI(); - if (pGraphics) { - IGRAPHICS_COCOA* pView = (IGRAPHICS_COCOA*) pGraphics->OpenWindow(0); - return pView; - } - } - return 0; -} - -- (unsigned) interfaceVersion -{ - return 0; -} - -- (NSString *) description -{ - return ToNSString(PLUG_NAME " View"); -} - -@end - - diff --git a/WDL/IPlug/IPlugBase.cpp b/WDL/IPlug/IPlugBase.cpp deleted file mode 100644 index 8882ef03..00000000 --- a/WDL/IPlug/IPlugBase.cpp +++ /dev/null @@ -1,692 +0,0 @@ -#include "IPlugBase.h" -#include "IGraphics.h" -#include "IControl.h" -#include -#include -#include - -const double DEFAULT_SAMPLE_RATE = 44100.0; - -template -void CastCopy(DEST* pDest, SRC* pSrc, int n) -{ - for (int i = 0; i < n; ++i, ++pDest, ++pSrc) { - *pDest = (DEST) *pSrc; - } -} - -void GetVersionParts(int version, int* pVer, int* pMaj, int* pMin) -{ - *pVer = (version & 0xFFFF0000) >> 16; - *pMaj = (version & 0x0000FF00) >> 8; - *pMin = version & 0x000000FF; -} - -int GetDecimalVersion(int version) -{ - int ver, rmaj, rmin; - GetVersionParts(version, &ver, &rmaj, &rmin); - return 10000 * ver + 100 * rmaj + rmin; -} - -void GetVersionStr(int version, char* str) -{ - int ver, rmaj, rmin; - GetVersionParts(version, &ver, &rmaj, &rmin); - //if (rmin) { - // sprintf(str, "v%d.%d.%d", ver, rmaj, rmin); - //} - //else - //if (rmaj) { - sprintf(str, "v%d.%02d", ver, rmaj); - //} - //else { - // sprintf(str, "v%d", ver); - //} -} - -IPlugBase::IPlugBase(int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency, - bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) -: mUniqueID(uniqueID), mMfrID(mfrID), mVersion(vendorVersion), - mSampleRate(DEFAULT_SAMPLE_RATE), mBlockSize(0), mLatency(latency), mHost(kHostUninit), mHostVersion(0), - mStateChunks(plugDoesChunks), mGraphics(0), mCurrentPresetIdx(0), mIsInst(plugIsInst) -{ - Trace(TRACELOC, "%s:%s", effectName, CurrentTime()); - - for (int i = 0; i < nParams; ++i) { - mParams.Add(new IParam); - } - - for (int i = 0; i < nPresets; ++i) { - mPresets.Add(new IPreset(i)); - } - - strcpy(mEffectName, effectName); - strcpy(mProductName, productName); - strcpy(mMfrName, mfrName); - - int nInputs = 0, nOutputs = 0; - while (channelIOStr) { - int nIn = 0, nOut = 0; - assert(sscanf(channelIOStr, "%d-%d", &nIn, &nOut) == 2); - nInputs = MAX(nInputs, nIn); - nOutputs = MAX(nOutputs, nOut); - mChannelIO.Add(new ChannelIO(nIn, nOut)); - channelIOStr = strstr(channelIOStr, " "); - if (channelIOStr) { - ++channelIOStr; - } - } - - mInData.Resize(nInputs); - mOutData.Resize(nOutputs); - - double** ppInData = mInData.Get(); - for (int i = 0; i < nInputs; ++i, ++ppInData) { - InChannel* pInChannel = new InChannel; - pInChannel->mConnected = false; - pInChannel->mSrc = ppInData; - mInChannels.Add(pInChannel); - } - double** ppOutData = mOutData.Get(); - for (int i = 0; i < nOutputs; ++i, ++ppOutData) { - OutChannel* pOutChannel = new OutChannel; - pOutChannel->mConnected = false; - pOutChannel->mDest = ppOutData; - pOutChannel->mFDest = 0; - mOutChannels.Add(pOutChannel); - } -} - -IPlugBase::~IPlugBase() -{ - TRACE; - DELETE_NULL(mGraphics); - mParams.Empty(true); - mPresets.Empty(true); - mInChannels.Empty(true); - mOutChannels.Empty(true); - mChannelIO.Empty(true); -} - -int IPlugBase::GetHostVersion(bool decimal) -{ - GetHost(); - if (decimal) { - return GetDecimalVersion(mHostVersion); - } - return mHostVersion; -} - -void IPlugBase::GetHostVersionStr(char* str) -{ - GetVersionStr(mHostVersion, str); -} - -bool IPlugBase::LegalIO(int nIn, int nOut) -{ - bool legal = false; - int i, n = mChannelIO.GetSize(); - for (i = 0; i < n && !legal; ++i) { - ChannelIO* pIO = mChannelIO.Get(i); - legal = ((nIn < 0 || nIn == pIO->mIn) && (nOut < 0 || nOut == pIO->mOut)); - } - Trace(TRACELOC, "%d:%d:%s", nIn, nOut, (legal ? "legal" : "illegal")); - return legal; -} - -void IPlugBase::LimitToStereoIO() -{ - int nIn = NInChannels(), nOut = NOutChannels(); - if (nIn > 2) { - SetInputChannelConnections(2, nIn - 2, false); - } - if (nOut > 2) { - SetOutputChannelConnections(2, nOut - 2, true); - } -} - -void IPlugBase::SetHost(const char* host, int version) -{ - mHost = LookUpHost(host); - mHostVersion = version; - - char vStr[32]; - GetVersionStr(version, vStr); - Trace(TRACELOC, "host_%sknown:%s:%s", (mHost == kHostUnknown ? "un" : ""), host, vStr); -} - -void IPlugBase::AttachGraphics(IGraphics* pGraphics) -{ - if (pGraphics) { - WDL_MutexLock lock(&mMutex); - int i, n = mParams.GetSize(); - for (i = 0; i < n; ++i) { - pGraphics->SetParameterFromPlug(i, GetParam(i)->GetNormalized(), true); - } - pGraphics->PrepDraw(); - mGraphics = pGraphics; - } -} - -// Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. -int IPlugBase::GetEffectVersion(bool decimal) -{ - if (decimal) { - return GetDecimalVersion(mVersion); - } - return mVersion; -} - -void IPlugBase::GetEffectVersionStr(char* str) -{ - GetVersionStr(mVersion, str); - #if defined _DEBUG - strcat(str, "D"); - #elif defined TRACER_BUILD - strcat(str, "T"); - #endif -} - -double IPlugBase::GetSamplesPerBeat() -{ - double tempo = GetTempo(); - if (tempo > 0.0) { - return GetSampleRate() * 60.0 / tempo; - } - return 0.0; -} - -void IPlugBase::SetSampleRate(double sampleRate) -{ - mSampleRate = sampleRate; -} - -void IPlugBase::SetBlockSize(int blockSize) -{ - if (blockSize != mBlockSize) { - int i, nIn = NInChannels(), nOut = NOutChannels(); - for (i = 0; i < nIn; ++i) { - InChannel* pInChannel = mInChannels.Get(i); - pInChannel->mScratchBuf.Resize(blockSize); - memset(pInChannel->mScratchBuf.Get(), 0, blockSize * sizeof(double)); - } - for (i = 0; i < nOut; ++i) { - OutChannel* pOutChannel = mOutChannels.Get(i); - pOutChannel->mScratchBuf.Resize(blockSize); - memset(pOutChannel->mScratchBuf.Get(), 0, blockSize * sizeof(double)); - } - mBlockSize = blockSize; - } -} - -void IPlugBase::SetInputChannelConnections(int idx, int n, bool connected) -{ - int iEnd = MIN(idx + n, mInChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - InChannel* pInChannel = mInChannels.Get(i); - pInChannel->mConnected = connected; - if (!connected) { - *(pInChannel->mSrc) = pInChannel->mScratchBuf.Get(); - } - } -} - -void IPlugBase::SetOutputChannelConnections(int idx, int n, bool connected) -{ - int iEnd = MIN(idx + n, mOutChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - OutChannel* pOutChannel = mOutChannels.Get(i); - pOutChannel->mConnected = connected; - if (!connected) { - *(pOutChannel->mDest) = pOutChannel->mScratchBuf.Get(); - } - } -} - -bool IPlugBase::IsInChannelConnected(int chIdx) -{ - return (chIdx < mInChannels.GetSize() && mInChannels.Get(chIdx)->mConnected); -} - -bool IPlugBase:: IsOutChannelConnected(int chIdx) -{ - return (chIdx < mOutChannels.GetSize() && mOutChannels.Get(chIdx)->mConnected); -} - -void IPlugBase::AttachInputBuffers(int idx, int n, double** ppData, int nFrames) -{ - int iEnd = MIN(idx + n, mInChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - InChannel* pInChannel = mInChannels.Get(i); - if (pInChannel->mConnected) { - *(pInChannel->mSrc) = *(ppData++); - } - } -} - -void IPlugBase::AttachInputBuffers(int idx, int n, float** ppData, int nFrames) -{ - int iEnd = MIN(idx + n, mInChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - InChannel* pInChannel = mInChannels.Get(i); - if (pInChannel->mConnected) { - double* pScratch = pInChannel->mScratchBuf.Get(); - CastCopy(pScratch, *(ppData++), nFrames); - *(pInChannel->mSrc) = pScratch; - } - } -} - -void IPlugBase::AttachOutputBuffers(int idx, int n, double** ppData) -{ - int iEnd = MIN(idx + n, mOutChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - OutChannel* pOutChannel = mOutChannels.Get(i); - if (pOutChannel->mConnected) { - *(pOutChannel->mDest) = *(ppData++); - } - } -} - -void IPlugBase::AttachOutputBuffers(int idx, int n, float** ppData) -{ - int iEnd = MIN(idx + n, mOutChannels.GetSize()); - for (int i = idx; i < iEnd; ++i) { - OutChannel* pOutChannel = mOutChannels.Get(i); - if (pOutChannel->mConnected) { - *(pOutChannel->mDest) = pOutChannel->mScratchBuf.Get(); - pOutChannel->mFDest = *(ppData++); - } - } -} - -#pragma REMINDER("lock mutex before calling into any IPlugBase processing functions") - -void IPlugBase::ProcessBuffers(double sampleType, int nFrames) -{ - ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); -} - -void IPlugBase::ProcessBuffers(float sampleType, int nFrames) -{ - ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); - int i, n = NOutChannels(); - OutChannel** ppOutChannel = mOutChannels.GetList(); - for (i = 0; i < n; ++i, ++ppOutChannel) { - OutChannel* pOutChannel = *ppOutChannel; - if (pOutChannel->mConnected) { - CastCopy(pOutChannel->mFDest, *(pOutChannel->mDest), nFrames); - } - } -} - -void IPlugBase::ProcessBuffersAccumulating(float sampleType, int nFrames) -{ - ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); - int i, n = NOutChannels(); - OutChannel** ppOutChannel = mOutChannels.GetList(); - for (i = 0; i < n; ++i, ++ppOutChannel) { - OutChannel* pOutChannel = *ppOutChannel; - if (pOutChannel->mConnected) { - float* pDest = pOutChannel->mFDest; - double* pSrc = *(pOutChannel->mDest); - for (int j = 0; j < nFrames; ++j, ++pDest, ++pSrc) { - *pDest += (float) *pSrc; - } - } - } -} - -// If latency changes after initialization (often not supported by the host). -void IPlugBase::SetLatency(int samples) -{ - mLatency = samples; -} - -void IPlugBase::SetParameterFromGUI(int idx, double normalizedValue) -{ - Trace(TRACELOC, "%d:%f", idx, normalizedValue); - WDL_MutexLock lock(&mMutex); - GetParam(idx)->SetNormalized(normalizedValue); - InformHostOfParamChange(idx, normalizedValue); - OnParamChange(idx); -} - -void IPlugBase::OnParamReset() -{ - for (int i = 0; i < mParams.GetSize(); ++i) { - OnParamChange(i); - } - //Reset(); -} - -// Default passthrough. -void IPlugBase::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames) -{ - // Mutex is already locked. - int i, nIn = mInChannels.GetSize(), nOut = mOutChannels.GetSize(); - for (i = 0; i < nIn; ++i) { - memcpy(outputs[i], inputs[i], nFrames * sizeof(double)); - } - for (/* same i */; i < nOut; ++i) { - memset(outputs[i], 0, nFrames * sizeof(double)); - } -} - -// Default passthrough. -void IPlugBase::ProcessMidiMsg(IMidiMsg* pMsg) -{ - SendMidiMsg(pMsg); -} - -IPreset* GetNextUninitializedPreset(WDL_PtrList* pPresets) -{ - int n = pPresets->GetSize(); - for (int i = 0; i < n; ++i) { - IPreset* pPreset = pPresets->Get(i); - if (!(pPreset->mInitialized)) { - return pPreset; - } - } - return 0; -} - -void IPlugBase::MakeDefaultPreset(char* name, int nPresets) -{ - for (int i = 0; i < nPresets; ++i) { - IPreset* pPreset = GetNextUninitializedPreset(&mPresets); - if (pPreset) { - pPreset->mInitialized = true; - strcpy(pPreset->mName, (name ? name : "Default")); - SerializeParams(&(pPreset->mChunk)); - } - } -} - -#define GET_PARAM_FROM_VARARG(paramType, vp, v) \ -{ \ - v = 0.0; \ - switch (paramType) { \ - case IParam::kTypeBool: \ - case IParam::kTypeInt: \ - case IParam::kTypeEnum: { \ - v = (double) va_arg(vp, int); \ - break; \ - } \ - case IParam::kTypeDouble: \ - default: { \ - v = (double) va_arg(vp, double); \ - break; \ - } \ - } \ -} - -void IPlugBase::MakePreset(char* name, ...) -{ - IPreset* pPreset = GetNextUninitializedPreset(&mPresets); - if (pPreset) { - pPreset->mInitialized = true; - strcpy(pPreset->mName, name); - int i, n = mParams.GetSize(); - - double v = 0.0; - va_list vp; - va_start(vp, name); - for (i = 0; i < n; ++i) { - GET_PARAM_FROM_VARARG(GetParam(i)->Type(), vp, v); - pPreset->mChunk.Put(&v); - } - } -} - -#define PARAM_UNINIT 99.99e-9 - -void IPlugBase::MakePresetFromNamedParams(char* name, int nParamsNamed, ...) -{ - IPreset* pPreset = GetNextUninitializedPreset(&mPresets); - if (pPreset) { - pPreset->mInitialized = true; - strcpy(pPreset->mName, name); - - int i = 0, n = mParams.GetSize(); - - WDL_TypedBuf vals; - vals.Resize(n); - double* pV = vals.Get(); - for (i = 0; i < n; ++i, ++pV) { - *pV = PARAM_UNINIT; - } - - va_list vp; - va_start(vp, nParamsNamed); - for (int i = 0; i < nParamsNamed; ++i) { - int paramIdx = (int) va_arg(vp, int); - // This assert will fire if any of the passed-in param values do not match - // the type that the param was initialized with (int for bool, int, enum; double for double). - assert(paramIdx >= 0 && paramIdx < n); - GET_PARAM_FROM_VARARG(GetParam(paramIdx)->Type(), vp, *(vals.Get() + paramIdx)); - } - va_end(vp); - - pV = vals.Get(); - for (int i = 0; i < n; ++i, ++pV) { - if (*pV == PARAM_UNINIT) { // Any that weren't explicitly set, use the defaults. - *pV = GetParam(i)->Value(); - } - pPreset->mChunk.Put(pV); - } - } -} - -#define DEFAULT_USER_PRESET_NAME "user preset" - -void MakeDefaultUserPresetName(WDL_PtrList* pPresets, char* str) -{ - int nDefaultNames = 0; - int n = pPresets->GetSize(); - for (int i = 0; i < n; ++i) { - IPreset* pPreset = pPresets->Get(i); - if (strstr(pPreset->mName, DEFAULT_USER_PRESET_NAME)) { - ++nDefaultNames; - } - } - sprintf(str, "%s %d", DEFAULT_USER_PRESET_NAME, nDefaultNames + 1); -} - -void IPlugBase::EnsureDefaultPreset() -{ - if (!(mPresets.GetSize())) { - mPresets.Add(new IPreset(0)); - MakeDefaultPreset(); - } -} - -void IPlugBase::PruneUninitializedPresets() -{ - int i = 0; - while (i < mPresets.GetSize()) { - IPreset* pPreset = mPresets.Get(i); - if (pPreset->mInitialized) { - ++i; - } - else { - mPresets.Delete(i, true); - } - } -} - -bool IPlugBase::RestorePreset(int idx) -{ - bool restoredOK = false; - if (idx >= 0 && idx < mPresets.GetSize()) { - IPreset* pPreset = mPresets.Get(idx); - - if (!(pPreset->mInitialized)) { - pPreset->mInitialized = true; - MakeDefaultUserPresetName(&mPresets, pPreset->mName); - restoredOK = SerializeParams(&(pPreset->mChunk)); - } - else { - restoredOK = (UnserializeParams(&(pPreset->mChunk), 0) > 0); - } - - if (restoredOK) { - mCurrentPresetIdx = idx; - RedrawParamControls(); - } - } - return restoredOK; -} - -bool IPlugBase::RestorePreset(const char* name) -{ - if (CSTR_NOT_EMPTY(name)) { - int n = mPresets.GetSize(); - for (int i = 0; i < n; ++i) { - IPreset* pPreset = mPresets.Get(i); - if (!strcmp(pPreset->mName, name)) { - return RestorePreset(i); - } - } - } - return false; -} - -const char* IPlugBase::GetPresetName(int idx) -{ - if (idx >= 0 && idx < mPresets.GetSize()) { - return mPresets.Get(idx)->mName; - } - return ""; -} - -void IPlugBase::ModifyCurrentPreset(const char* name) -{ - if (mCurrentPresetIdx >= 0 && mCurrentPresetIdx < mPresets.GetSize()) { - IPreset* pPreset = mPresets.Get(mCurrentPresetIdx); - pPreset->mChunk.Clear(); - - - SerializeParams(&(pPreset->mChunk)); - - if (CSTR_NOT_EMPTY(name)) - { - strcpy(pPreset->mName, name); - } - } -} - -bool IPlugBase::SerializePresets(ByteChunk* pChunk) -{ - bool savedOK = true; - int n = mPresets.GetSize(); - for (int i = 0; i < n && savedOK; ++i) { - IPreset* pPreset = mPresets.Get(i); - pChunk->PutStr(pPreset->mName); - pChunk->PutBool(pPreset->mInitialized); - if (pPreset->mInitialized) { - savedOK &= (pChunk->PutChunk(&(pPreset->mChunk)) > 0); - } - } - return savedOK; -} - -int IPlugBase::UnserializePresets(ByteChunk* pChunk, int startPos) -{ - WDL_String name; - int n = mPresets.GetSize(), pos = startPos; - for (int i = 0; i < n && pos >= 0; ++i) { - IPreset* pPreset = mPresets.Get(i); - pos = pChunk->GetStr(&name, pos); - strcpy(pPreset->mName, name.Get()); - pos = pChunk->GetBool(&(pPreset->mInitialized), pos); - if (pPreset->mInitialized) { - pos = UnserializeParams(pChunk, pos); - if (pos > 0) { - pPreset->mChunk.Clear(); - SerializeParams(&(pPreset->mChunk)); - } - } - } - RestorePreset(mCurrentPresetIdx); - return pos; -} - -bool IPlugBase::SerializeParams(ByteChunk* pChunk) -{ - TRACE; - - WDL_MutexLock lock(&mMutex); - bool savedOK = true; - int i, n = mParams.GetSize(); - for (i = 0; i < n && savedOK; ++i) { - IParam* pParam = mParams.Get(i); - double v = pParam->Value(); - savedOK &= (pChunk->Put(&v) > 0); - } - return savedOK; -} - -int IPlugBase::UnserializeParams(ByteChunk* pChunk, int startPos) -{ - TRACE; - - WDL_MutexLock lock(&mMutex); - int i, n = mParams.GetSize(), pos = startPos; - for (i = 0; i < n && pos >= 0; ++i) { - IParam* pParam = mParams.Get(i); - double v = 0.0; - Trace(TRACELOC, "%d %s", i, pParam->GetNameForHost()); - pos = pChunk->Get(&v, pos); - pParam->Set(v); - } - OnParamReset(); - return pos; -} - -void IPlugBase::RedrawParamControls() -{ - if (mGraphics) { - int i, n = mParams.GetSize(); - for (i = 0; i < n; ++i) { - double v = mParams.Get(i)->Value(); - mGraphics->SetParameterFromPlug(i, v, false); - } - } -} - -void IPlugBase::DumpPresetSrcCode(const char* filename, const char* paramEnumNames[]) -{ - static bool sDumped = false; - if (!sDumped) { - sDumped = true; - int i, n = NParams(); - FILE* fp = fopen(filename, "w"); - fprintf(fp, " MakePresetFromNamedParams(\"name\", %d", n - 1); - for (i = 0; i < n - 1; ++i) { - IParam* pParam = GetParam(i); - char paramVal[32]; - switch (pParam->Type()) { - case IParam::kTypeBool: - sprintf(paramVal, "%s", (pParam->Bool() ? "true" : "false")); - break; - case IParam::kTypeInt: - sprintf(paramVal, "%d", pParam->Int()); - break; - case IParam::kTypeEnum: - sprintf(paramVal, "%d", pParam->Int()); - break; - case IParam::kTypeDouble: - default: - sprintf(paramVal, "%.2f", pParam->Value()); - break; - } - fprintf(fp, ",\n %s, %s", paramEnumNames[i], paramVal); - } - fprintf(fp, ");\n"); - fclose(fp); - } -} \ No newline at end of file diff --git a/WDL/IPlug/IPlugBase.h b/WDL/IPlug/IPlugBase.h deleted file mode 100644 index b8c3e506..00000000 --- a/WDL/IPlug/IPlugBase.h +++ /dev/null @@ -1,247 +0,0 @@ -#ifndef _IPLUGBASE_ -#define _IPLUGBASE_ - -#define IPLUG_VERSION 0x010000 - -#include "Containers.h" -#include "IPlugStructs.h" -#include "IParam.h" -#include "Hosts.h" -#include "Log.h" - -// Uncomment to enable IPlug::OnIdle() and IGraphics::OnGUIIdle(). -// #define USE_IDLE_CALLS - -#define MAX_EFFECT_NAME_LEN 128 -#define DEFAULT_BLOCK_SIZE 1024 - -// All version ints are stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. - -class IGraphics; - -class IPlugBase -{ -public: - - // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). - IPlugBase(int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency, - bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst); - - // ---------------------------------------- - // Your plugin class implements these. - // There are default impls, mostly just for reference. - - virtual ~IPlugBase(); - - // Implementations should set a mutex lock like in the no-op! - virtual void Reset() { TRACE; IMutexLock lock(this); } - virtual void OnParamChange(int paramIdx) { IMutexLock lock(this); } - - // Default passthrough. Inputs and outputs are [nChannel][nSample]. - // Mutex is already locked. - virtual void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames); - - // In case the audio processing thread needs to do anything when the GUI opens - // (like for example, set some state dependent initial values for controls). - virtual void OnGUIOpen() { TRACE; } - virtual void OnGUIClose() { TRACE; } - - // This is an idle call from the audio processing thread, as opposed to - // IGraphics::OnGUIIdle which is called from the GUI thread. - // Only active if USE_IDLE_CALLS is defined. - virtual void OnIdle() {} - - // Not usually needed ... Reset is called on activate regardless of whether this is implemented. - // Also different hosts have different interpretations of "activate". - // Implementations should set a mutex lock like in the no-op! - virtual void OnActivate(bool active) { TRACE; IMutexLock lock(this); } - - virtual void ProcessMidiMsg(IMidiMsg* pMsg); - virtual bool MidiNoteName(int noteNumber, char* rName) { *rName = '\0'; return false; } - - // Implementations should set a mutex lock. - virtual bool SerializeState(ByteChunk* pChunk) { return SerializeParams(pChunk); } - // Return the new chunk position (endPos). - virtual int UnserializeState(ByteChunk* pChunk, int startPos) { return UnserializeParams(pChunk, startPos); } - - // ---------------------------------------- - // Your plugin class, or a control class, can call these functions. - - int NParams() { return mParams.GetSize(); } - IParam* GetParam(int idx) { return mParams.Get(idx); } - IGraphics* GetGUI() { return mGraphics; } - - const char* GetEffectName() { return mEffectName; } - int GetEffectVersion(bool decimal); // Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. - void GetEffectVersionStr(char* str); - const char* GetMfrName() { return mMfrName; } - const char* GetProductName() { return mProductName; } - - int GetUniqueID() { return mUniqueID; } - int GetMfrID() { return mMfrID; } - - void SetParameterFromGUI(int idx, double normalizedValue); - // If a parameter change comes from the GUI, midi, or external input, - // the host needs to be informed in case the changes are being automated. - virtual void BeginInformHostOfParamChange(int idx) = 0; - virtual void InformHostOfParamChange(int idx, double normalizedValue) = 0; - virtual void EndInformHostOfParamChange(int idx) = 0; - - // ---------------------------------------- - // Useful stuff for your plugin class or an outsider to call, - // most of which is implemented by the API class. - - double GetSampleRate() { return mSampleRate; } - int GetBlockSize() { return mBlockSize; } - int GetLatency() { return mLatency; } - - // In ProcessDoubleReplacing you are always guaranteed to get valid pointers - // to all the channels the plugin requested. If the host hasn't connected all the pins, - // the unconnected channels will be full of zeros. - int NInChannels() { return mInChannels.GetSize(); } - int NOutChannels() { return mOutChannels.GetSize(); } - bool IsInChannelConnected(int chIdx); - bool IsOutChannelConnected(int chIdx); - - virtual int GetSamplePos() = 0; // Samples since start of project. - virtual double GetTempo() = 0; - double GetSamplesPerBeat(); - virtual void GetTimeSig(int* pNum, int* pDenom) = 0; - - virtual EHost GetHost() { return mHost; } - int GetHostVersion(bool decimal); // Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. - void GetHostVersionStr(char* str); - - // Tell the host that the graphics resized. - // Should be called only by the graphics object when it resizes itself. - virtual void ResizeGraphics(int w, int h) = 0; - - // Not fully supported. A call back from the host saying the user has resized the window. - // If the plugin supports different sizes, it may wish to resize. - virtual void UserResizedWindow(IRECT* pR) {} - - void EnsureDefaultPreset(); - -protected: - - // ---------------------------------------- - // Useful stuff for your plugin class to call, implemented here or in the API class, or partly in both. - - struct ChannelIO - { - int mIn, mOut; - ChannelIO(int nIn, int nOut) : mIn(nIn), mOut(nOut) {} - }; - WDL_PtrList mChannelIO; - bool LegalIO(int nIn, int nOut); // -1 for either means check the other value only. - void LimitToStereoIO(); - - void SetHost(const char* host, int version); // Version = 0xVVVVRRMM. - virtual void HostSpecificInit() = 0; - - virtual void AttachGraphics(IGraphics* pGraphics); - - void SetSampleRate(double sampleRate); - virtual void SetBlockSize(int blockSize); - // If latency changes after initialization (often not supported by the host). - virtual void SetLatency(int samples); - virtual bool SendMidiMsg(IMidiMsg* pMsg) = 0; - virtual bool SendMidiMsgs(WDL_TypedBuf* pMsgs) = 0; - bool IsInst() { return mIsInst; } - - void MakeDefaultPreset(char* name = 0, int nPresets = 1); - // MakePreset(name, param1, param2, ..., paramN) - void MakePreset(char* name, ...); - // MakePresetFromNamedParams(name, nParamsNamed, paramEnum1, paramVal1, paramEnum2, paramVal2, ..., paramEnumN, paramVal2) - // nParamsNamed may be less than the total number of params. - void MakePresetFromNamedParams(char* name, int nParamsNamed, ...); - - bool DoesStateChunks() { return mStateChunks; } - // Will append if the chunk is already started. - bool SerializeParams(ByteChunk* pChunk); - // Returns the new chunk position (endPos). - int UnserializeParams(ByteChunk* pChunk, int startPos); - void RedrawParamControls(); // Called after restoring state. - - // ---------------------------------------- - // Internal IPlug stuff (but API classes need to get at it). - - void OnParamReset(); // Calls OnParamChange(each param) + Reset(). - - int NPresets() { return mPresets.GetSize(); } - int GetCurrentPresetIdx() { return mCurrentPresetIdx; } - void PruneUninitializedPresets(); - bool RestorePreset(int idx); - bool RestorePreset(const char* name); - const char* GetPresetName(int idx); - void ModifyCurrentPreset(const char* name = 0); // Sets the currently active preset to whatever current params are. - bool SerializePresets(ByteChunk* pChunk); - // Returns the new chunk position (endPos). - int UnserializePresets(ByteChunk* pChunk, int startPos); - - // Dump the current state as source code for a call to MakePresetFromNamedParams. - void DumpPresetSrcCode(const char* filename, const char* paramEnumNames[]); - - // Set connection state for n channels. - // If a channel is connected, we expect a call to attach the buffers before each process call. - // If a channel is not connected, we attach scratch buffers now and don't need to do anything else. - void SetInputChannelConnections(int idx, int n, bool connected); - void SetOutputChannelConnections(int idx, int n, bool connected); - - void AttachInputBuffers(int idx, int n, double** ppData, int nFrames); - void AttachInputBuffers(int idx, int n, float** ppData, int nFrames); - void AttachOutputBuffers(int idx, int n, double** ppData); - void AttachOutputBuffers(int idx, int n, float** ppData); - void ProcessBuffers(float sampleType, int nFrames); - void ProcessBuffers(double sampleType, int nFrames); - void ProcessBuffersAccumulating(float sampleType, int nFrames); - -public: - - WDL_Mutex mMutex; - - struct IMutexLock - { - WDL_Mutex* mpMutex; - IMutexLock(IPlugBase* pPlug) : mpMutex(&(pPlug->mMutex)) { mpMutex->Enter(); } - ~IMutexLock() { if (mpMutex) { mpMutex->Leave(); } } - void Destroy() { mpMutex->Leave(); mpMutex = 0; } - }; - -private: - - char mEffectName[MAX_EFFECT_NAME_LEN], mProductName[MAX_EFFECT_NAME_LEN], mMfrName[MAX_EFFECT_NAME_LEN]; - int mUniqueID, mMfrID, mVersion; // Version stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. - - EHost mHost; - int mHostVersion; // Version stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. - - bool mStateChunks, mIsInst; - double mSampleRate; - int mBlockSize, mLatency; - - WDL_PtrList mParams; - IGraphics* mGraphics; - - WDL_PtrList mPresets; - int mCurrentPresetIdx; - - WDL_TypedBuf mInData, mOutData; - struct InChannel { - bool mConnected; - double** mSrc; // Points into mInData. - WDL_TypedBuf mScratchBuf; - }; - struct OutChannel { - bool mConnected; - double** mDest; // Points into mOutData. - float* mFDest; - WDL_TypedBuf mScratchBuf; - }; - WDL_PtrList mInChannels; - WDL_PtrList mOutChannels; -}; - -#endif diff --git a/WDL/IPlug/IPlugStructs.cpp b/WDL/IPlug/IPlugStructs.cpp deleted file mode 100644 index 3791b7d1..00000000 --- a/WDL/IPlug/IPlugStructs.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "IPlugStructs.h" -#include "Log.h" - -//bool IText::operator==(const IText& rhs) const -//{ -// int s = sizeof(*this); -// int r = sizeof(rhs); -// return (s == r && !strcmp(mFont.Get(), rhs.mFont.Get()) && memcmp(this, &rhs, s) == 0); -//} -// -//bool IText::operator<(const IText& rhs) const -//{ -// if (mFont != rhs.mFont) { -// return (mFont < rhs.mFont); -// } -// int s = sizeof(*this); -// int r = sizeof(rhs); -// if (s != r) { -// return (s < r); -// } -// return memcmp(this, &rhs, MIN(s, r)); -//} - -void IMidiMsg::MakeNoteOnMsg(int noteNumber, int velocity, int offset) -{ - Clear(); - mStatus = kNoteOn << 4; - mData1 = noteNumber; - mData2 = velocity; - mOffset = offset; -} - -void IMidiMsg::MakeNoteOffMsg(int noteNumber, int offset) -{ - Clear(); - mStatus = kNoteOff << 4; - mData1 = noteNumber; - mOffset = offset; -} - -void IMidiMsg::MakePitchWheelMsg(double value) -{ - Clear(); - mStatus = kPitchWheel << 4; - int i = 8192 + (int) (value * 8192.0); - i = BOUNDED(i, 0, 16383); - mData2 = i>>7; - mData1 = i&0x7F; -} - -void IMidiMsg::MakeControlChangeMsg(EControlChangeMsg idx, double value) -{ - Clear(); - mStatus = kControlChange << 4; - mData1 = idx; - mData2 = (int) (value * 127.0); -} - -IMidiMsg::EStatusMsg IMidiMsg::StatusMsg() const -{ - unsigned int e = mStatus >> 4; - if (e < kNoteOff || e > kPitchWheel) { - return kNone; - } - return (EStatusMsg) e; -} - -int IMidiMsg::NoteNumber() const -{ - switch (StatusMsg()) { - case kNoteOn: - case kNoteOff: - case kPolyAftertouch: - return mData1; - default: - return -1; - } -} - -int IMidiMsg::Velocity() const -{ - switch (StatusMsg()) { - case kNoteOn: - case kNoteOff: - return mData2; - default: - return -1; - } -} - -int IMidiMsg::Program() const -{ - if (StatusMsg() == kProgramChange) { - return mData1; - } - return -1; -} - -double IMidiMsg::PitchWheel() const -{ - if (StatusMsg() == kPitchWheel) { - int iVal = (mData2 << 7) + mData1; - return (double) (iVal - 8192) / 8192.0; - } - return 0.0; -} - -IMidiMsg::EControlChangeMsg IMidiMsg::ControlChangeIdx() const -{ - return (EControlChangeMsg) mData1; -} - -double IMidiMsg::ControlChange(EControlChangeMsg idx) const -{ - if (StatusMsg() == kControlChange && ControlChangeIdx() == idx) { - return (double) mData2 / 127.0; - } - return -1.0; -} - -void IMidiMsg::Clear() -{ - mOffset = 0; - mStatus = mData1 = mData2 = 0; -} - -const char* StatusMsgStr(IMidiMsg::EStatusMsg msg) -{ - switch (msg) { - case IMidiMsg::kNone: return "none"; - case IMidiMsg::kNoteOff: return "noteoff"; - case IMidiMsg::kNoteOn: return "noteon"; - case IMidiMsg::kPolyAftertouch: return "aftertouch"; - case IMidiMsg::kControlChange: return "controlchange"; - case IMidiMsg::kProgramChange: return "programchange"; - case IMidiMsg::kChannelAftertouch: return "channelaftertouch"; - case IMidiMsg::kPitchWheel: return "pitchwheel"; - default: return "unknown"; - }; -} - -void IMidiMsg::LogMsg() -{ -#ifdef TRACER_BUILD - Trace(TRACELOC, "midi:(%s:%d:%d)", StatusMsgStr(StatusMsg()), NoteNumber(), Velocity()); -#endif -} \ No newline at end of file diff --git a/WDL/IPlug/IPlugStructs.h b/WDL/IPlug/IPlugStructs.h deleted file mode 100644 index b972c31c..00000000 --- a/WDL/IPlug/IPlugStructs.h +++ /dev/null @@ -1,300 +0,0 @@ -#ifndef _IPLUGSTRUCTS_ -#define _IPLUGSTRUCTS_ - -#include "Containers.h" - -// Abstracting the graphics made it easy to go ahead and abstract the OS ... -// the cost is this crap redefining some basic stuff. - -struct IBitmap -{ - void* mData; - int W, H, N; // N = number of states (for multibitmaps). - IBitmap(void* pData = 0, int w = 0, int h = 0, int n = 1) : mData(pData), W(w), H(h), N(n) {} -}; - -struct IColor -{ - int A, R, G, B; - IColor(int a = 255, int r = 0, int g = 0, int b = 0) : A(a), R(r), G(g), B(b) {} - bool operator==(const IColor& rhs) { return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); } - bool operator!=(const IColor& rhs) { return !operator==(rhs); } - bool Empty() const { return A == 0 && R == 0 && G == 0 && B == 0; } - void Clamp() { A = MIN(A, 255); R = MIN(R, 255); G = MIN(G, 255); B = MIN(B, 255); } -}; - -const IColor COLOR_TRANSPARENT(0, 0, 0, 0); -const IColor COLOR_BLACK(255, 0, 0, 0); -const IColor COLOR_GRAY(255, 127, 127, 127); -const IColor COLOR_WHITE(255, 255, 255, 255); -const IColor COLOR_RED(255, 255, 0, 0); -const IColor COLOR_GREEN(255, 0, 255, 0); -const IColor COLOR_BLUE(255, 0, 0, 255); -const IColor COLOR_YELLOW(255, 255, 255, 0); -const IColor COLOR_ORANGE(255, 255, 127, 0); - -struct IChannelBlend -{ - enum EBlendMethod { - kBlendNone, // Copy over whatever is already there, but look at src alpha. - kBlendClobber, // Copy completely over whatever is already there. - kBlendAdd, - kBlendColorDodge, - // etc - }; - EBlendMethod mMethod; - float mWeight; - - IChannelBlend(EBlendMethod method = kBlendNone, float weight = 1.0f) : mMethod(method), mWeight(weight) {} -}; - -const int DEFAULT_TEXT_SIZE = 14; -const IColor DEFAULT_TEXT_COLOR = COLOR_BLACK; -const char* const DEFAULT_FONT = "Arial"; -const int FONT_LEN = 32; - -struct IText -{ - char mFont[FONT_LEN]; - int mSize; - IColor mColor; - enum EStyle { kStyleNormal, kStyleBold, kStyleItalic } mStyle; - enum EAlign { kAlignNear, kAlignCenter, kAlignFar } mAlign; - int mOrientation; // Degrees ccwise from normal. - - IText(int size = DEFAULT_TEXT_SIZE, const IColor* pColor = 0, char* font = 0, - EStyle style = kStyleNormal, EAlign align = kAlignCenter, int orientation = 0) - : mSize(size), mColor(pColor ? *pColor : DEFAULT_TEXT_COLOR), //mFont(font ? font : DEFAULT_FONT), - mStyle(style), mAlign(align), mOrientation(orientation) - { - strcpy(mFont, (font ? font : DEFAULT_FONT)); - } - - IText(const IColor* pColor) - : mSize(DEFAULT_TEXT_SIZE), mColor(*pColor), //mFont(DEFAULT_FONT), - mStyle(kStyleNormal), mAlign(kAlignCenter), mOrientation(0) - { - strcpy(mFont, DEFAULT_FONT); - } - - // bool operator==(const IText& rhs) const; - // bool operator!=(const IText& rhs) const { return !operator==(rhs); } - // bool operator<(const IText& rhs) const; // For sorting. -}; - -struct IRECT -{ - int L, T, R, B; - - IRECT() { L = T = R = B = 0; } - IRECT(int l, int t, int r, int b) : L(l), R(r), T(t), B(b) {} - IRECT(int x, int y, IBitmap* pBitmap) : L(x), T(y), R(x + pBitmap->W), B(y + pBitmap->H / pBitmap->N) {} - - bool Empty() const { - return (L == 0 && T == 0 && R == 0 && B == 0); - } - void Clear() { - L = T = R = B = 0; - } - bool operator==(const IRECT& rhs) const { - return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B); - } - bool operator!=(const IRECT& rhs) const { - return !(*this == rhs); - } - - inline int W() const { return R - L; } - inline int H() const { return B - T; } - inline float MW() const { return 0.5f * (float) (L + R); } - inline float MH() const { return 0.5f * (float) (T + B); } - - inline IRECT Union(IRECT* pRHS) { - if (Empty()) { return *pRHS; } - if (pRHS->Empty()) { return *this; } - return IRECT(MIN(L, pRHS->L), MIN(T, pRHS->T), MAX(R, pRHS->R), MAX(B, pRHS->B)); - } - inline IRECT Intersect(IRECT* pRHS) { - if (Intersects(pRHS)) { - return IRECT(MAX(L, pRHS->L), MAX(T, pRHS->T), MIN(R, pRHS->R), MIN(B, pRHS->B)); - } - return IRECT(); - } - inline bool Intersects(IRECT* pRHS) { - return (!Empty() && !pRHS->Empty() && R >= pRHS->L && L < pRHS->R && B >= pRHS->T && T < pRHS->B); - } - inline bool Contains(IRECT* pRHS) { - return (!Empty() && !pRHS->Empty() && pRHS->L >= L && pRHS->R <= R && pRHS->T >= T && pRHS->B <= B); - } - inline bool Contains(int x, int y) { - return (!Empty() && x >= L && x < R && y >= T && y < B); - } - - void Clank(IRECT* pRHS) { - if (L < pRHS->L) { - R = MIN(pRHS->R - 1, R + pRHS->L - L); - L = pRHS->L; - } - if (T < pRHS->T) { - B = MIN(pRHS->B - 1, B + pRHS->T - T); - T = pRHS->T; - } - if (R >= pRHS->R) { - L = MAX(pRHS->L, L - (R - pRHS->R + 1)); - R = pRHS->R - 1; - } - if (B >= pRHS->B) { - T = MAX(pRHS->T, T - (B - pRHS->B + 1)); - B = pRHS->B - 1; - } - } -}; - -struct IMouseMod -{ - bool L, R, S, C, A; - IMouseMod(bool l = false, bool r = false, bool s = false, bool c = false, bool a = false) - : L(l), R(r), S(s), C(c), A(a) {} -}; - -struct IMidiMsg -{ - int mOffset; - BYTE mStatus, mData1, mData2; - - enum EStatusMsg { - kNone = 0, - kNoteOff = 8, - kNoteOn = 9, - kPolyAftertouch = 10, - kControlChange = 11, - kProgramChange = 12, - kChannelAftertouch = 13, - kPitchWheel = 14 - }; - - enum EControlChangeMsg { - kModWheel = 1, - kBreathController = 2, - kUndefined003 = 3, - kFootController = 4, - kPortamentoTime = 5, - kChannelVolume = 7, - kBalance = 8, - kUndefined009 = 9, - kPan = 10, - kExpressionController = 11, - kEffectControl1 = 12, - kEffectControl2 = 13, - kUndefined014 = 14, - kUndefined015 = 15, - kGeneralPurposeController1 = 16, - kGeneralPurposeController2 = 17, - kGeneralPurposeController3 = 18, - kGeneralPurposeController4 = 19, - kUndefined020 = 20, - kUndefined021 = 21, - kUndefined022 = 22, - kUndefined023 = 23, - kUndefined024 = 24, - kUndefined025 = 25, - kUndefined026 = 26, - kUndefined027 = 27, - kUndefined028 = 28, - kUndefined029 = 29, - kUndefined030 = 30, - kUndefined031 = 31, - kSustainOnOff = 64, - kPortamentoOnOff = 65, - kSustenutoOnOff = 66, - kSoftPedalOnOff = 67, - kLegatoOnOff = 68, - kHold2OnOff = 69, - kSoundVariation = 70, - kResonance = 71, - kReleaseTime = 72, - kAttackTime = 73, - kCutoffFrequency = 74, - kDecayTime = 75, - kVibratoRate = 76, - kVibratoDepth = 77, - kVibratoDelay = 78, - kSoundControllerUndefined = 79, - kUndefined085 = 85, - kUndefined086 = 86, - kUndefined087 = 87, - kUndefined088 = 88, - kUndefined089 = 89, - kUndefined090 = 90, - kTremoloDepth = 92, - kChorusDepth = 93, - kPhaserDepth = 95, - kUndefined102 = 102, - kUndefined103 = 103, - kUndefined104 = 104, - kUndefined105 = 105, - kUndefined106 = 106, - kUndefined107 = 107, - kUndefined108 = 108, - kUndefined109 = 109, - kUndefined110 = 110, - kUndefined111 = 111, - kUndefined112 = 112, - kUndefined113 = 113, - kUndefined114 = 114, - kUndefined115 = 115, - kUndefined116 = 116, - kUndefined117 = 117, - kUndefined118 = 118, - kUndefined119 = 119, - kAllNotesOff = 123 - }; - - IMidiMsg(int offs = 0, BYTE s = 0, BYTE d1 = 0, BYTE d2 = 0) : mOffset(offs), mStatus(s), mData1(d1), mData2(d2) {} - - void MakeNoteOnMsg(int noteNumber, int velocity, int offset); - void MakeNoteOffMsg(int noteNumber, int offset); - void MakePitchWheelMsg(double value); // Value in [-1, 1], converts to [0, 16384) where 8192 = no pitch change. - void MakeControlChangeMsg(EControlChangeMsg idx, double value); // Value in [0, 1]. - - EStatusMsg StatusMsg() const; - int NoteNumber() const; // Returns [0, 128), -1 if NA. - int Velocity() const; // Returns [0, 128), -1 if NA. - int Program() const; // Returns [0, 128), -1 if NA. - double PitchWheel() const; // Returns [-1.0, 1.0], zero if NA. - EControlChangeMsg ControlChangeIdx() const; - double ControlChange(EControlChangeMsg idx) const; // return [0, 1], -1 if NA. - static bool ControlChangeOnOff(double msgValue) { return (msgValue >= 0.5); } // true = on. - void Clear(); - void LogMsg(); -}; - -const int MAX_PRESET_NAME_LEN = 256; -#define UNUSED_PRESET_NAME "empty" - -struct IPreset -{ - bool mInitialized; - char mName[MAX_PRESET_NAME_LEN]; - ByteChunk mChunk; - - IPreset(int idx) - : mInitialized(false) - { - sprintf(mName, "- %d -", idx+1); - } -}; - -enum -{ - KEY_SPACE, - KEY_UPARROW, - KEY_DOWNARROW, - KEY_LEFTARROW, - KEY_RIGHTARROW, - KEY_DIGIT_0, - KEY_DIGIT_9=KEY_DIGIT_0+9, - KEY_ALPHA_A, - KEY_ALPHA_Z=KEY_ALPHA_A+25 -}; - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlugVST.cpp b/WDL/IPlug/IPlugVST.cpp deleted file mode 100644 index 327dd88b..00000000 --- a/WDL/IPlug/IPlugVST.cpp +++ /dev/null @@ -1,685 +0,0 @@ -#include "IPlugVST.h" -#include "IGraphics.h" -#include - -const int VST_VERSION = 2400; - - -int VSTSpkrArrType(int nchan) -{ - if (!nchan) return kSpeakerArrEmpty; - if (nchan == 1) return kSpeakerArrMono; - if (nchan == 2) return kSpeakerArrStereo; - return kSpeakerArrUserDefined; -} - - -IPlugVST::IPlugVST(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency, - bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) -: IPlugBase(nParams, channelIOStr, nPresets, effectName, productName, mfrName, - vendorVersion, uniqueID, mfrID, latency, - plugDoesMidi, plugDoesChunks, plugIsInst), - mDoesMidi(plugDoesMidi), mHostCallback(instanceInfo.mVSTHostCallback), mHostSpecificInitDone(false) -{ - Trace(TRACELOC, "%s", effectName); - - mHasVSTExtensions = VSTEXT_NONE; - - int nInputs = NInChannels(), nOutputs = NOutChannels(); - - memset(&mAEffect, 0, sizeof(AEffect)); - mAEffect.object = this; - mAEffect.magic = kEffectMagic; - mAEffect.dispatcher = VSTDispatcher; - mAEffect.getParameter = VSTGetParameter; - mAEffect.setParameter = VSTSetParameter; - mAEffect.numPrograms = nPresets; - mAEffect.numParams = nParams; - mAEffect.numInputs = nInputs; - mAEffect.numOutputs = nOutputs; - mAEffect.uniqueID = uniqueID; - mAEffect.version = GetEffectVersion(true); - mAEffect.__ioRatioDeprecated = 1.0f; - mAEffect.__processDeprecated = VSTProcess; - mAEffect.processReplacing = VSTProcessReplacing; - mAEffect.processDoubleReplacing = VSTProcessDoubleReplacing; - mAEffect.initialDelay = latency; - mAEffect.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing; - if (plugDoesChunks) { - mAEffect.flags |= effFlagsProgramChunks; - } - if (LegalIO(1, -1)) { - mAEffect.flags |= __effFlagsCanMonoDeprecated; - } - if (plugIsInst) { - mAEffect.flags |= effFlagsIsSynth; - } - - memset(&mEditRect, 0, sizeof(ERect)); - - memset(&mInputSpkrArr, 0, sizeof(VstSpeakerArrangement)); - memset(&mOutputSpkrArr, 0, sizeof(VstSpeakerArrangement)); - mInputSpkrArr.numChannels = nInputs; - mOutputSpkrArr.numChannels = nOutputs; - mInputSpkrArr.type = VSTSpkrArrType(nInputs); - mOutputSpkrArr.type = VSTSpkrArrType(nOutputs); - - // Default everything to connected, then disconnect pins if the host says to. - SetInputChannelConnections(0, nInputs, true); - SetOutputChannelConnections(0, nOutputs, true); - - SetBlockSize(DEFAULT_BLOCK_SIZE); -} - -void IPlugVST::BeginInformHostOfParamChange(int idx) -{ - mHostCallback(&mAEffect, audioMasterBeginEdit, idx, 0, 0, 0.0f); -} - -void IPlugVST::InformHostOfParamChange(int idx, double normalizedValue) -{ - mHostCallback(&mAEffect, audioMasterAutomate, idx, 0, 0, (float) normalizedValue); -} - -void IPlugVST::EndInformHostOfParamChange(int idx) -{ - mHostCallback(&mAEffect, audioMasterEndEdit, idx, 0, 0, 0.0f); -} - -inline VstTimeInfo* GetTimeInfo(audioMasterCallback hostCallback, AEffect* pAEffect, int filter = 0) -{ -#pragma warning(disable:4312) // Pointer size cast mismatch. - VstTimeInfo* pTI = (VstTimeInfo*) hostCallback(pAEffect, audioMasterGetTime, 0, filter, 0, 0); -#pragma warning(default:4312) - if (pTI && (!filter || (pTI->flags & filter))) { - return pTI; - } - return 0; -} - -int IPlugVST::GetSamplePos() -{ - VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect); - if (pTI && pTI->samplePos >= 0.0) { - return int(pTI->samplePos); - } - return 0; -} - -double IPlugVST::GetTempo() -{ - if (mHostCallback) { - VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect, kVstTempoValid); - if (pTI && pTI->tempo >= 0.0) { - return pTI->tempo; - } - } - return 0.0; -} - -void IPlugVST::GetTimeSig(int* pNum, int* pDenom) -{ - *pNum = *pDenom = 0; - VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect, kVstTimeSigValid); - if (pTI && pTI->timeSigNumerator >= 0.0 && pTI->timeSigDenominator >= 0.0) { - *pNum = pTI->timeSigNumerator; - *pDenom = pTI->timeSigDenominator; - } -} - -EHost IPlugVST::GetHost() -{ - EHost host = IPlugBase::GetHost(); - if (host == kHostUninit) { - char vendorStr[256], productStr[256]; - productStr[0] = '\0'; - int version = 0; - mHostCallback(&mAEffect, audioMasterGetProductString, 0, 0, productStr, 0.0f); - if (CSTR_NOT_EMPTY(vendorStr) || CSTR_NOT_EMPTY(productStr)) { - int decVer = mHostCallback(&mAEffect, audioMasterGetVendorVersion, 0, 0, 0, 0.0f); - int ver = decVer / 10000; - int rmaj = (decVer - 10000 * ver) / 100; - int rmin = (decVer - 10000 * ver - 100 * rmaj); - version = (ver << 16) + (rmaj << 8) + rmin; - } - SetHost(productStr, version); - host = IPlugBase::GetHost(); - } - return host; -} - -void IPlugVST::AttachGraphics(IGraphics* pGraphics) -{ - if (pGraphics) { - IPlugBase::AttachGraphics(pGraphics); - mAEffect.flags |= effFlagsHasEditor; - mEditRect.left = mEditRect.top = 0; - mEditRect.right = pGraphics->Width(); - mEditRect.bottom = pGraphics->Height(); - } -} - -void IPlugVST::ResizeGraphics(int w, int h) -{ - IGraphics* pGraphics = GetGUI(); - if (pGraphics) { - mEditRect.left = mEditRect.top = 0; - mEditRect.right = pGraphics->Width(); - mEditRect.bottom = pGraphics->Height(); - } -} - -void IPlugVST::SetLatency(int samples) -{ - mAEffect.initialDelay = samples; - IPlugBase::SetLatency(samples); -} - -bool IPlugVST::SendVSTEvent(VstEvent* pEvent) -{ - // It would be more efficient to bundle these and send at the end of a processed block, - // but that would require writing OnBlockEnd and making sure it always gets called, - // and who cares anyway, midi events aren't that dense. - VstEvents events; - memset(&events, 0, sizeof(VstEvents)); - events.numEvents = 1; - events.events[0] = pEvent; - return (mHostCallback(&mAEffect, audioMasterProcessEvents, 0, 0, &events, 0.0f) == 1); -} - -bool IPlugVST::SendMidiMsg(IMidiMsg* pMsg) -{ - VstMidiEvent midiEvent; - memset(&midiEvent, 0, sizeof(VstMidiEvent)); - - midiEvent.type = kVstMidiType; - midiEvent.byteSize = sizeof(VstMidiEvent); // Should this be smaller? - midiEvent.deltaFrames = pMsg->mOffset; - midiEvent.midiData[0] = pMsg->mStatus; - midiEvent.midiData[1] = pMsg->mData1; - midiEvent.midiData[2] = pMsg->mData2; - - return SendVSTEvent((VstEvent*) &midiEvent); -} - -bool IPlugVST::SendMidiMsgs(WDL_TypedBuf* pMsgs) -{ - // Todo: bundle and SendVSTEvents. - bool rc = true; - int n = pMsgs->GetSize(); - IMidiMsg* pMsg = pMsgs->Get(); - for (int i = 0; i < n; ++i, ++pMsg) { - rc &= SendMidiMsg(pMsg); - } - return rc; -} - -audioMasterCallback IPlugVST::GetHostCallback() -{ - return mHostCallback; -} - -void IPlugVST::HostSpecificInit() -{ - if (!mHostSpecificInitDone) { - mHostSpecificInitDone = true; - EHost host = GetHost(); - switch (host) { - case kHostAudition: - case kHostOrion: - case kHostForte: - case kHostSAWStudio: - LimitToStereoIO(); - break; - } - - // This won't always solve a picky host problem -- for example Forte - // looks at mAEffect IO count before identifying itself. - mAEffect.numInputs = mInputSpkrArr.numChannels = NInChannels(); - mAEffect.numOutputs = mOutputSpkrArr.numChannels = NOutChannels(); - } -} - -#define IPLUG_VERSION_MAGIC 'pfft' - -void InitializeVSTChunk(ByteChunk* pChunk) -{ - pChunk->Clear(); - int magic = IPLUG_VERSION_MAGIC; - pChunk->Put(&magic); - int ver = IPLUG_VERSION; - pChunk->Put(&ver); -} - -int GetIPlugVerFromChunk(ByteChunk* pChunk, int* pPos) -{ - int magic = 0, ver = 0; - int pos = pChunk->Get(&magic, *pPos); - if (pos > *pPos && magic == IPLUG_VERSION_MAGIC) { - *pPos = pChunk->Get(&ver, pos); - } - return ver; -} - -VstIntPtr VSTCALLBACK IPlugVST::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt) -{ - // VSTDispatcher is an IPlugVST class member, we can access anything in IPlugVST from here. - IPlugVST* _this = (IPlugVST*) pEffect->object; - if (!_this) { - return 0; - } - IPlugBase::IMutexLock lock(_this); - - // Handle a couple of opcodes here to make debugging easier. - switch (opCode) { - case effEditIdle: - case __effIdleDeprecated: - #ifdef USE_IDLE_CALLS - _this->OnIdle(); - #endif - return 0; - } - - Trace(TRACELOC, "%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (int) value); - - switch (opCode) { - - case effOpen: { - _this->HostSpecificInit(); - _this->OnParamReset(); - return 0; - } - case effClose: { - lock.Destroy(); - DELETE_NULL(_this); - return 0; - } - case effGetParamLabel: { - if (idx >= 0 && idx < _this->NParams()) - { - strcpy((char*) ptr, _this->GetParam(idx)->GetLabelForHost()); - } - return 0; - } - case effGetParamDisplay: { - if (idx >= 0 && idx < _this->NParams()) - { - _this->GetParam(idx)->GetDisplayForHost((char*) ptr); - } - return 0; - } - case effGetParamName: { - if (idx >= 0 && idx < _this->NParams()) - { - strcpy((char*) ptr, _this->GetParam(idx)->GetNameForHost()); - } - return 0; - } - case effSetSampleRate: { - _this->SetSampleRate(opt); - _this->Reset(); - return 0; - } - case effSetBlockSize: { - _this->SetBlockSize(value); - _this->Reset(); - return 0; - } - case effMainsChanged: { - if (!value) { - _this->OnActivate(false); - _this->Reset(); - } - else { - _this->OnActivate(true); - } - return 0; - } - case effEditGetRect: { - if (ptr && _this->GetGUI()) { - *(ERect**) ptr = &(_this->mEditRect); - return 1; - } - ptr = 0; - return 0; - } - case effEditOpen: - { - IGraphics* pGraphics = _this->GetGUI(); - if (pGraphics) - { -#ifdef _WIN32 - if (!pGraphics->OpenWindow(ptr)) pGraphics=0; -#else // OSX, check if we are in a Cocoa VST host - bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA); - if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0; - if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0; -#endif - if (pGraphics) - { - _this->OnGUIOpen(); - return 1; - } - } - return 0; - } - case effEditClose: { - if (_this->GetGUI()) { - _this->OnGUIClose(); - _this->GetGUI()->CloseWindow(); - return 1; - } - return 0; - } - case __effIdentifyDeprecated: { - return 'NvEf'; // Random deprecated magic. - } - case effGetChunk: { - BYTE** ppData = (BYTE**) ptr; - if (ppData) { - bool isBank = (!idx); - ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); - InitializeVSTChunk(pChunk); - bool savedOK = true; - if (isBank) { - _this->ModifyCurrentPreset(); - //savedOK = _this->SerializePresets(pChunk); - savedOK = _this->SerializeState(pChunk); - } - else { - savedOK = _this->SerializeState(pChunk); - } - if (savedOK && pChunk->Size()) { - *ppData = pChunk->GetBytes(); - return pChunk->Size(); - } - } - return 0; - } - case effSetChunk: { - if (ptr) { - bool isBank = (!idx); - ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); - pChunk->Resize(value); - memcpy(pChunk->GetBytes(), ptr, value); - int pos = 0; - int iplugVer = GetIPlugVerFromChunk(pChunk, &pos); - isBank &= (iplugVer >= 0x010000); - if (isBank) { - //pos = _this->UnserializePresets(pChunk, pos); - pos = _this->UnserializeState(pChunk, pos); - } - else { - pos = _this->UnserializeState(pChunk, pos); - _this->ModifyCurrentPreset(); - } - if (pos >= 0) { - _this->RedrawParamControls(); - return 1; - } - } - return 0; - } - case effProcessEvents: { - VstEvents* pEvents = (VstEvents*) ptr; - if (pEvents && pEvents->events) { - for (int i = 0; i < pEvents->numEvents; ++i) { - VstEvent* pEvent = pEvents->events[i]; - if (pEvent) { - if (pEvent->type == kVstMidiType) { - VstMidiEvent* pME = (VstMidiEvent*) pEvent; - IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]); - _this->ProcessMidiMsg(&msg); - //#ifdef TRACER_BUILD - // msg.LogMsg(); - //#endif - } - else { - _this->SendVSTEvent(pEvent); // Pass sysex messages through. - } - } - } - return 1; - } - return 0; - } - case effCanBeAutomated: { - return 1; - } - case effGetInputProperties: { - if (ptr && idx >= 0 && idx < _this->NInChannels()) { - VstPinProperties* pp = (VstPinProperties*) ptr; - pp->flags = kVstPinIsActive; - if (!(idx%2) && idx < _this->NInChannels()-1) - { - pp->flags |= kVstPinIsStereo; - } - sprintf(pp->label, "Input %d", idx + 1); - return 1; - } - return 0; - } - case effGetOutputProperties: { - if (ptr && idx >= 0 && idx < _this->NOutChannels()) { - VstPinProperties* pp = (VstPinProperties*) ptr; - pp->flags = kVstPinIsActive; - if (!(idx%2) && idx < _this->NOutChannels()-1) - { - pp->flags |= kVstPinIsStereo; - } - sprintf(pp->label, "Output %d", idx + 1); - return 1; - } - return 0; - } - case effGetPlugCategory: { - if (_this->IsInst()) return kPlugCategSynth; - return kPlugCategEffect; - } - case effProcessVarIo: { - // VstVariableIo* pIO = (VstVariableIo*) ptr; // For offline processing (of audio files?) - return 0; - } - case effSetSpeakerArrangement: { - VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value; - VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr; - if (pInputArr) { - int n = pInputArr->numChannels; - _this->SetInputChannelConnections(0, n, true); - _this->SetInputChannelConnections(n, _this->NInChannels() - n, false); - } - if (pOutputArr) { - int n = pOutputArr->numChannels; - _this->SetOutputChannelConnections(0, n, true); - _this->SetOutputChannelConnections(n, _this->NOutChannels() - n, false); - } - return 1; - } - case effGetSpeakerArrangement: { - VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value; - VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr; - if (ppInputArr) { - *ppInputArr = &(_this->mInputSpkrArr); - } - if (ppOutputArr) { - *ppOutputArr = &(_this->mOutputSpkrArr); - } - return 1; - } - case effGetEffectName: { - if (ptr) { - strcpy((char*) ptr, _this->GetEffectName()); - return 1; - } - return 0; - } - case effGetProductString: { - if (ptr) { - strcpy((char*) ptr, _this->GetProductName()); - return 1; - } - return 0; - } - case effGetVendorString: { - if (ptr) { - strcpy((char*) ptr, _this->GetMfrName()); - return 1; - } - return 0; - } - case effCanDo: { - if (ptr) { - Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr); - if (!strcmp((char*) ptr, "receiveVstTimeInfo")) { - return 1; - } - if (_this->mDoesMidi) { - if (!strcmp((char*) ptr, "sendVstEvents") || - !strcmp((char*) ptr, "sendVstMidiEvent") || - !strcmp((char*) ptr, "receiveVstEvents") || - !strcmp((char*) ptr, "receiveVstMidiEvent")) { // || - //!strcmp((char*) ptr, "midiProgramNames")) { - return 1; - } - } - // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ - if (!strcmp((char*) ptr, "hasCockosExtensions")) - { - _this->mHasVSTExtensions |= VSTEXT_COCKOS; - return 0xbeef0000; - } - else if (!strcmp((char*) ptr, "hasCockosViewAsConfig")) - { - _this->mHasVSTExtensions |= VSTEXT_COCOA; - return 0xbeef0000; - } - } - return 0; - } - case effVendorSpecific: { - // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ - if (idx == effGetParamDisplay && ptr) { - if (value >= 0 && value < _this->NParams()) { - _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr); - } - return 0xbeef; - } - return 0; - } - case effGetProgram: { - return _this->GetCurrentPresetIdx(); - } - case effSetProgram: { - if (!(_this->DoesStateChunks())) { - _this->ModifyCurrentPreset(); - } - _this->RestorePreset((int) value); - return 0; - } - case effGetProgramNameIndexed: { - strcpy((char*) ptr, _this->GetPresetName(idx)); - return (CSTR_NOT_EMPTY((char*) ptr) ? 1 : 0); - } - case effSetProgramName: { - if (ptr) { - _this->ModifyCurrentPreset((char*) ptr); - } - return 0; - } - case effGetProgramName: { - if (ptr) { - int idx = _this->GetCurrentPresetIdx(); - strcpy((char*) ptr, _this->GetPresetName(idx)); - } - return 0; - } - case effGetMidiKeyName: { - if (ptr) { - MidiKeyName* pMKN = (MidiKeyName*) ptr; - pMKN->keyName[0] = '\0'; - if (_this->MidiNoteName(pMKN->thisKeyNumber, pMKN->keyName)) { - return 1; - } - } - return 0; - } - case effGetVstVersion: { - return VST_VERSION; - } - case effBeginSetProgram: - case effEndSetProgram: - case effGetMidiProgramName: - case effHasMidiProgramsChanged: - case effGetMidiProgramCategory: - case effGetCurrentMidiProgram: - case effSetBypass: - default: { - return 0; - } - } -} - -template -void IPlugVST::VSTPrepProcess(SAMPLETYPE** inputs, SAMPLETYPE** outputs, VstInt32 nFrames) -{ - if (mDoesMidi) { - mHostCallback(&mAEffect, __audioMasterWantMidiDeprecated, 0, 0, 0, 0.0f); - } - AttachInputBuffers(0, NInChannels(), inputs, nFrames); - AttachOutputBuffers(0, NOutChannels(), outputs); -} - -// Deprecated. -void VSTCALLBACK IPlugVST::VSTProcess(AEffect* pEffect, float** inputs, float** outputs, VstInt32 nFrames) -{ - TRACE; - IPlugVST* _this = (IPlugVST*) pEffect->object; - IMutexLock lock(_this); - _this->VSTPrepProcess(inputs, outputs, nFrames); - _this->ProcessBuffersAccumulating((float) 0.0f, nFrames); -} - -void VSTCALLBACK IPlugVST::VSTProcessReplacing(AEffect* pEffect, float** inputs, float** outputs, VstInt32 nFrames) -{ - TRACE; - IPlugVST* _this = (IPlugVST*) pEffect->object; - IMutexLock lock(_this); - _this->VSTPrepProcess(inputs, outputs, nFrames); - _this->ProcessBuffers((float) 0.0f, nFrames); -} - -void VSTCALLBACK IPlugVST::VSTProcessDoubleReplacing(AEffect* pEffect, double** inputs, double** outputs, VstInt32 nFrames) -{ - TRACE; - IPlugVST* _this = (IPlugVST*) pEffect->object; - IMutexLock lock(_this); - _this->VSTPrepProcess(inputs, outputs, nFrames); - _this->ProcessBuffers((double) 0.0, nFrames); -} - -float VSTCALLBACK IPlugVST::VSTGetParameter(AEffect *pEffect, VstInt32 idx) -{ - Trace(TRACELOC, "%d", idx); - IPlugVST* _this = (IPlugVST*) pEffect->object; - IMutexLock lock(_this); - if (idx >= 0 && idx < _this->NParams()) { - return (float) _this->GetParam(idx)->GetNormalized(); - } - return 0.0f; -} - -void VSTCALLBACK IPlugVST::VSTSetParameter(AEffect *pEffect, VstInt32 idx, float value) -{ - Trace(TRACELOC, "%d:%f", idx, value); - IPlugVST* _this = (IPlugVST*) pEffect->object; - IMutexLock lock(_this); - if (idx >= 0 && idx < _this->NParams()) { - if (_this->GetGUI()) { - _this->GetGUI()->SetParameterFromPlug(idx, value, true); - } - _this->GetParam(idx)->SetNormalized(value); - _this->OnParamChange(idx); - } -} diff --git a/WDL/IPlug/IPlugVST.h b/WDL/IPlug/IPlugVST.h deleted file mode 100644 index ee69abda..00000000 --- a/WDL/IPlug/IPlugVST.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _IPLUGAPI_ -#define _IPLUGAPI_ -// Only load one API class! - -#include "IPlugBase.h" -#include "../../VST_SDK/aeffectx.h" - -struct IPlugInstanceInfo -{ - audioMasterCallback mVSTHostCallback; -}; - -class IPlugVST : public IPlugBase -{ -public: - - // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). - IPlugVST(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, - const char* effectName, const char* productName, const char* mfrName, - int vendorVersion, int uniqueID, int mfrID, int latency = 0, - bool plugDoesMidi = false, bool plugDoesChunks = false, - bool plugIsInst = false); - - // ---------------------------------------- - // See IPlugBase for the full list of methods that your plugin class can implement. - - void BeginInformHostOfParamChange(int idx); - void InformHostOfParamChange(int idx, double normalizedValue); - void EndInformHostOfParamChange(int idx); - - int GetSamplePos(); // Samples since start of project. - double GetTempo(); - void GetTimeSig(int* pNum, int* pDenom); - EHost GetHost(); // GetHostVersion() is inherited. - - // Tell the host that the graphics resized. - // Should be called only by the graphics object when it resizes itself. - void ResizeGraphics(int w, int h); - -protected: - - void HostSpecificInit(); - void AttachGraphics(IGraphics* pGraphics); - void SetLatency(int samples); - bool SendMidiMsg(IMidiMsg* pMsg); - bool SendMidiMsgs(WDL_TypedBuf* pMsgs); - audioMasterCallback GetHostCallback(); - -private: - - template - void VSTPrepProcess(SAMPLETYPE** inputs, SAMPLETYPE** outputs, VstInt32 nFrames); - - ERect mEditRect; - audioMasterCallback mHostCallback; - - bool SendVSTEvent(VstEvent* pEvent); - bool SendVSTEvents(WDL_TypedBuf* pEvents); - - VstSpeakerArrangement mInputSpkrArr, mOutputSpkrArr; - - bool mHostSpecificInitDone; - bool mDoesMidi; - - enum { VSTEXT_NONE=0, VSTEXT_COCKOS, VSTEXT_COCOA }; // list of VST extensions supported by host - int mHasVSTExtensions; - - ByteChunk mState; // Persistent storage if the host asks for plugin state. - ByteChunk mBankState; // Persistent storage if the host asks for bank state. - -public: - - static VstIntPtr VSTCALLBACK VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt); - static void VSTCALLBACK VSTProcess(AEffect *pEffect, float **inputs, float **outputs, VstInt32 nFrames); // Deprecated. - static void VSTCALLBACK VSTProcessReplacing(AEffect *pEffect, float **inputs, float **outputs, VstInt32 nFrames); - static void VSTCALLBACK VSTProcessDoubleReplacing(AEffect *pEffect, double **inputs, double **outputs, VstInt32 nFrames); - static float VSTCALLBACK VSTGetParameter(AEffect *pEffect, VstInt32 idx); - static void VSTCALLBACK VSTSetParameter(AEffect *pEffect, VstInt32 idx, float value); - AEffect mAEffect; -}; - -IPlugVST* MakePlug(); - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug_Prefix.pch b/WDL/IPlug/IPlug_Prefix.pch deleted file mode 100644 index f0850233..00000000 --- a/WDL/IPlug/IPlug_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'IPlug' target in the 'IPlug' project. -// - -#ifdef __OBJC__ - #import -#endif diff --git a/WDL/IPlug/IPlug_include_in_plug_hdr.h b/WDL/IPlug/IPlug_include_in_plug_hdr.h deleted file mode 100644 index 7540fa38..00000000 --- a/WDL/IPlug/IPlug_include_in_plug_hdr.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _IPLUG_INCLUDE_HDR_ -#define _IPLUG_INCLUDE_HDR_ - -// Include this file in the main header for your plugin, -// after #defining either VST_API or AU_API. - -#include "resource.h" // This is your plugin's resource.h. - -#if defined VST_API - #include "IPlugVST.h" - typedef IPlugVST IPlug; - #define API_EXT "vst" -#elif defined AU_API - #include "IPlugAU.h" - typedef IPlugAU IPlug; - #define API_EXT "audiounit" -#else - #error "No API defined!" -#endif - -#if defined _WIN32 - #include "IGraphicsWin.h" - #define EXPORT __declspec(dllexport) -#elif defined __APPLE__ - #include "IGraphicsMac.h" - #define EXPORT - #define BUNDLE_ID "com." BUNDLE_MFR "." API_EXT "." BUNDLE_NAME -#else - #error "No OS defined!" -#endif - -#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug_include_in_plug_src.h b/WDL/IPlug/IPlug_include_in_plug_src.h deleted file mode 100644 index f53d9dac..00000000 --- a/WDL/IPlug/IPlug_include_in_plug_src.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _IPLUG_INCLUDE_SRC_ -#define _IPLUG_INCLUDE_SRC_ - -// Include this file in the main source for your plugin, -// after #including the main header for your plugin. - -#if defined _WIN32 - HINSTANCE gHInstance = 0; - BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD fdwReason, LPVOID res) - { - gHInstance = hDllInst; - return TRUE; - } - IGraphics* MakeGraphics(IPlug* pPlug, int w, int h, int FPS = 0) - { - IGraphicsWin* pGraphics = new IGraphicsWin(pPlug, w, h, FPS); - pGraphics->SetHInstance(gHInstance); - return pGraphics; - } -#elif defined __APPLE__ - IGraphics* MakeGraphics(IPlug* pPlug, int w, int h, int FPS = 0) - { - IGraphicsMac* pGraphics = new IGraphicsMac(pPlug, w, h, FPS); - pGraphics->SetBundleID(BUNDLE_ID); - return pGraphics; - } -#else - #error "No OS defined!" -#endif - -#if defined VST_API - extern "C" - { - EXPORT void* VSTPluginMain(audioMasterCallback hostCallback) - { - static WDL_Mutex sMutex; - WDL_MutexLock lock(&sMutex); - IPlugInstanceInfo instanceInfo; - instanceInfo.mVSTHostCallback = hostCallback; - IPlugVST* pPlug = new PLUG_CLASS_NAME(instanceInfo); - if (pPlug) { - pPlug->EnsureDefaultPreset(); - pPlug->mAEffect.numPrograms = MAX(pPlug->mAEffect.numPrograms, 1); - return &(pPlug->mAEffect); - } - return 0; - } - EXPORT int main(audioMasterCallback hostCallback) - { - return (int) VSTPluginMain(hostCallback); - } - }; -#elif defined AU_API - IPlug* MakePlug() - { - static WDL_Mutex sMutex; - WDL_MutexLock lock(&sMutex); - IPlugInstanceInfo instanceInfo; - instanceInfo.mOSXBundleID.Set(BUNDLE_ID); - instanceInfo.mCocoaViewFactoryClassName.Set(VIEW_CLASS_STR); - return new PLUG_CLASS_NAME(instanceInfo); - } - extern "C" - { - ComponentResult PLUG_ENTRY(ComponentParameters* params, void* pPlug) - { - return IPlugAU::IPlugAUEntry(params, pPlug); - } - ComponentResult PLUG_VIEW_ENTRY(ComponentParameters* params, void* pView) - { - return IPlugAU::IPlugAUCarbonViewEntry(params, pView); - } - }; -#else - #error "No API defined!" -#endif - -#if defined _DEBUG - #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME " DEBUG") -#elif defined TRACER_BUILD - #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME " TRACER") -#elif defined TIMESTAMP_PLUG_NAME - #pragma REMINDER("plug name is timestamped") - #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME) -#else - #define PUBLIC_NAME PLUG_NAME -#endif - -#define IPLUG_CTOR(nParams, nPresets, instanceInfo) \ - IPlug(instanceInfo, nParams, PLUG_CHANNEL_IO, nPresets, \ - PUBLIC_NAME, "", PLUG_MFR, PLUG_VER, PLUG_UNIQUE_ID, PLUG_MFR_ID, \ - PLUG_LATENCY, PLUG_DOES_MIDI, PLUG_DOES_STATE_CHUNKS, PLUG_IS_INST) - -#endif \ No newline at end of file diff --git a/WDL/IPlug/Log.cpp b/WDL/IPlug/Log.cpp deleted file mode 100644 index 1509d09c..00000000 --- a/WDL/IPlug/Log.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include "Log.h" -#include "stdio.h" -#include "string.h" -#include "time.h" -#include - -#ifdef _WIN32 - #define LOGFILE "C:\\IPlugLog.txt" -#else - #define LOGFILE "/IPlugLog.txt" -#endif - -const int TXTLEN = 1024; - -// _vsnsprintf - -#define VARARGS_TO_STR(str) { \ - try { \ - va_list argList; \ - va_start(argList, format); \ - int i = vsnprintf(str, TXTLEN-2, format, argList); \ - if (i < 0 || i > TXTLEN-2) { \ - str[TXTLEN-1] = '\0'; \ - } \ - va_end(argList); \ - } \ - catch(...) { \ - strcpy(str, "parse error"); \ - } \ - strcat(str, "\r\n"); \ -} - -struct LogFile -{ - FILE* mFP; - - LogFile() - { - mFP = fopen(LOGFILE, "w"); - assert(mFP); - } - - ~LogFile() - { - fclose(mFP); - mFP = 0; - } -}; - -Timer::Timer() -{ - mT = clock(); -} - -bool Timer::Every(double sec) -{ - if (clock() - mT > sec * CLOCKS_PER_SEC) { - mT = clock(); - return true; - } - return false; -}; - -// Needs rewriting for WDL. -//StrVector ReadFileIntoStr(WDL_String* pFileName) -//{ -// WDL_PtrList lines; -// if (!strlen(pFileName->Get())) { -// WDL_String line; -// std::ifstream ifs(pFileName->Get()); -// if (ifs) { -// while (std::getline(ifs, line, '\n')) { -// if (!line.empty()) { -// lines.push_back(line); -// } -// } -// ifs.close(); -// } -// } -// return lines; -//} - -// Needs rewriting for WDL. -//int WriteBufferToFile(const DBuffer& buf, const std::string& fileName) -//{ -// std::ofstream ofs(fileName.c_str()); -// if (ofs) { -// for (int i = 0, p = buf.Pos(); i < buf.Size(); ++i, ++p) { -// ofs << buf[p] << ' '; -// } -// ofs << '\n'; -// ofs.close(); -// return buf.Size(); -// } -// return 0; -//} - -bool IsWhitespace(char c) -{ - return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); -} - -// Needs rewriting for WDL. -//StrVector SplitStr(const std::string& line, char separator) -//{ -// std::string field; -// StrVector fields; -// for (int i = 0; i < line.size(); ++i) { -// bool sep = (line[i] == separator); -// sep |= (IsWhitespace(separator) && IsWhitespace(line[i])); -// -// if (!sep) { -// field.push_back(line[i]); -// } -// else -// if (!field.empty()) { -// fields.push_back(field); -// field.clear(); -// } -// } -// if (!field.empty()) { -// fields.push_back(field); -// } -// return fields; -//} - -void ToLower(char* cDest, const char* cSrc) -{ - int i, n = (int) strlen(cSrc); - for (i = 0; i < n; ++i) { - cDest[i] = tolower(cSrc[i]); - } - cDest[i] = '\0'; -} - -const char* CurrentTime() -{ - time_t t = time(0); - tm* pT = localtime(&t); - - char cStr[64]; - strftime(cStr, 64, "%Y%m%d %H:%M ", pT); - - char cTZ[64], tz[64]; - strftime(cTZ, 64, "%Z", pT); - int i, j, nZ = strlen(cTZ); - for (i = 0, j = 0; i < nZ; ++i) { - if (isupper(cTZ[i])) { - tz[j++] = cTZ[i]; - } - } - tz[j] = '\0'; - - static char sTimeStr[256]; - strcpy(sTimeStr, cStr); - strcat(sTimeStr, tz); - return sTimeStr; -} - -void CompileTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, WDL_String* pStr) -{ - pStr->Set("["); - pStr->Append(Mmm_dd_yyyy); - pStr->SetLen(7); - pStr->DeleteSub(4, 1); - pStr->Append(" "); - pStr->Append(hh_mm_ss); - pStr->SetLen(12); - pStr->Append("]"); -} - -const char* AppendTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, const char* cStr) -{ - static WDL_String str(cStr); - WDL_String tStr; - CompileTimestamp(Mmm_dd_yyyy, hh_mm_ss, &tStr); - str.Append(" "); - str.Append(tStr.Get()); - return str.Get(); -} - -#if defined TRACER_BUILD - - int GetOrdinalThreadID(int sysThreadID) - { - static WDL_TypedBuf sThreadIDs; - int i, n = sThreadIDs.GetSize(); - int* pThreadID = sThreadIDs.Get(); - for (i = 0; i < n; ++i, ++pThreadID) { - if (sysThreadID == *pThreadID) { - return i; - } - } - sThreadIDs.Resize(n + 1); - *(sThreadIDs.Get() + n) = sysThreadID; - return n; - } - - #define MAX_LOG_LINES 16384 - void Trace(const char* funcName, int line, const char* format, ...) - { - static int sTrace = 0; - if (sTrace++ < MAX_LOG_LINES) { - static LogFile sLogFile; - static WDL_Mutex sLogMutex; - char str[TXTLEN]; - VARARGS_TO_STR(str); - printf("[%d:%s:%d]%s", GetOrdinalThreadID(SYS_THREAD_ID), funcName, line, str); - - //WDL_MutexLock lock(&sLogMutex); - //fprintf(sLogFile.mFP, "[%d:%s:%d]%s", GetOrdinalThreadID(SYS_THREAD_ID), funcName, line, str); - //fflush(sLogFile.mFP); - } - } - - #include "../../VST_SDK/aeffectx.h" - const char* VSTOpcodeStr(int opCode) - { - switch (opCode) { - case effOpen: return "effOpen"; - case effClose: return "effClose"; - case effSetProgram: return "effSetProgram"; - case effGetProgram: return "effGetProgram"; - case effSetProgramName: return "effSetProgramName"; - case effGetProgramName: return "effGetProgramName"; - case effGetParamLabel: return "effGetParamLabel"; - case effGetParamDisplay: return "effGetParamDisplay"; - case effGetParamName: return "effGetParamName"; - case __effGetVuDeprecated: return "__effGetVuDeprecated"; - case effSetSampleRate: return "effSetSampleRate"; - case effSetBlockSize: return "effSetBlockSize"; - case effMainsChanged: return "effMainsChanged"; - case effEditGetRect: return "effEditGetRect"; - case effEditOpen: return "effEditOpen"; - case effEditClose: return "effEditClose"; - case __effEditDrawDeprecated: return "__effEditDrawDeprecated"; - case __effEditMouseDeprecated: return "__effEditMouseDeprecated"; - case __effEditKeyDeprecated: return "__effEditKeyDeprecated"; - case effEditIdle: return "effEditIdle"; - case __effEditTopDeprecated: return "__effEditTopDeprecated"; - case __effEditSleepDeprecated: return "__effEditSleepDeprecated"; - case __effIdentifyDeprecated: return "__effIdentifyDeprecated"; - case effGetChunk: return "effGetChunk"; - case effSetChunk: return "effSetChunk"; - case effProcessEvents: return "effProcessEvents"; - case effCanBeAutomated: return "effCanBeAutomated"; - case effString2Parameter: return "effString2Parameter"; - case __effGetNumProgramCategoriesDeprecated: return "__effGetNumProgramCategoriesDeprecated"; - case effGetProgramNameIndexed: return "effGetProgramNameIndexed"; - case __effCopyProgramDeprecated: return "__effCopyProgramDeprecated"; - case __effConnectInputDeprecated: return "__effConnectInputDeprecated"; - case __effConnectOutputDeprecated: return "__effConnectOutputDeprecated"; - case effGetInputProperties: return "effGetInputProperties"; - case effGetOutputProperties: return "effGetOutputProperties"; - case effGetPlugCategory: return "effGetPlugCategory"; - case __effGetCurrentPositionDeprecated: return "__effGetCurrentPositionDeprecated"; - case __effGetDestinationBufferDeprecated: return "__effGetDestinationBufferDeprecated"; - case effOfflineNotify: return "effOfflineNotify"; - case effOfflinePrepare: return "effOfflinePrepare"; - case effOfflineRun: return "effOfflineRun"; - case effProcessVarIo: return "effProcessVarIo"; - case effSetSpeakerArrangement: return "effSetSpeakerArrangement"; - case __effSetBlockSizeAndSampleRateDeprecated: return "__effSetBlockSizeAndSampleRateDeprecated"; - case effSetBypass: return "effSetBypass"; - case effGetEffectName: return "effGetEffectName"; - case __effGetErrorTextDeprecated: return "__effGetErrorTextDeprecated"; - case effGetVendorString: return "effGetVendorString"; - case effGetProductString: return "effGetProductString"; - case effGetVendorVersion: return "effGetVendorVersion"; - case effVendorSpecific: return "effVendorSpecific"; - case effCanDo: return "effCanDo"; - case effGetTailSize: return "effGetTailSize"; - case __effIdleDeprecated: return "__effIdleDeprecated"; - case __effGetIconDeprecated: return "__effGetIconDeprecated"; - case __effSetViewPositionDeprecated: return "__effSetViewPositionDeprecated"; - case effGetParameterProperties: return "effGetParameterProperties"; - case __effKeysRequiredDeprecated: return "__effKeysRequiredDeprecated"; - case effGetVstVersion: return "effGetVstVersion"; - case effEditKeyDown: return "effEditKeyDown"; - case effEditKeyUp: return "effEditKeyUp"; - case effSetEditKnobMode: return "effSetEditKnobMode"; - case effGetMidiProgramName: return "effGetMidiProgramName"; - case effGetCurrentMidiProgram: return "effGetCurrentMidiProgram"; - case effGetMidiProgramCategory: return "effGetMidiProgramCategory"; - case effHasMidiProgramsChanged: return "effHasMidiProgramsChanged"; - case effGetMidiKeyName: return "effGetMidiKeyName"; - case effBeginSetProgram: return "effBeginSetProgram"; - case effEndSetProgram: return "effEndSetProgram"; - case effGetSpeakerArrangement: return "effGetSpeakerArrangement"; - case effShellGetNextPlugin: return "effShellGetNextPlugin"; - case effStartProcess: return "effStartProcess"; - case effStopProcess: return "effStopProcess"; - case effSetTotalSampleToProcess: return "effSetTotalSampleToProcess"; - case effSetPanLaw: return "effSetPanLaw"; - case effBeginLoadBank: return "effBeginLoadBank"; - case effBeginLoadProgram: return "effBeginLoadProgram"; - case effSetProcessPrecision: return "effSetProcessPrecision"; - case effGetNumMidiInputChannels: return "effGetNumMidiInputChannels"; - case effGetNumMidiOutputChannels: return "effGetNumMidiOutputChannels"; - default: return "unknown"; - } - } - #if defined __APPLE__ - #include - #include - const char* AUSelectStr(int select) - { - switch (select) { - case kComponentOpenSelect: return "kComponentOpenSelect"; - case kComponentCloseSelect: return "kComponentCloseSelect"; - case kComponentVersionSelect: return "kComponentVersionSelect"; - case kAudioUnitInitializeSelect: return "kAudioUnitInitializeSelect"; - case kAudioUnitUninitializeSelect: return "kAudioUnitUninitializeSelect"; - case kAudioUnitGetPropertyInfoSelect: return "kAudioUnitGetPropertyInfoSelect"; - case kAudioUnitGetPropertySelect: return "kAudioUnitGetPropertySelect"; - case kAudioUnitSetPropertySelect: return "kAudioUnitSetPropertySelect"; - case kAudioUnitAddPropertyListenerSelect: return "kAudioUnitAddPropertyListenerSelect"; - case kAudioUnitRemovePropertyListenerSelect: return "kAudioUnitRemovePropertyListenerSelect"; - case kAudioUnitAddRenderNotifySelect: return "kAudioUnitAddRenderNotifySelect"; - case kAudioUnitRemoveRenderNotifySelect: return "kAudioUnitRemoveRenderNotifySelect"; - case kAudioUnitGetParameterSelect: return "kAudioUnitGetParameterSelect"; - case kAudioUnitSetParameterSelect: return "kAudioUnitSetParameterSelect"; - case kAudioUnitScheduleParametersSelect: return "kAudioUnitScheduleParametersSelect"; - case kAudioUnitRenderSelect: return "kAudioUnitRenderSelect"; - case kAudioUnitResetSelect: return "kAudioUnitResetSelect"; - case kComponentCanDoSelect: return "kComponentCanDoSelect"; - case kAudioUnitCarbonViewRange: return "kAudioUnitCarbonViewRange"; - case kAudioUnitCarbonViewCreateSelect: return "kAudioUnitCarbonViewCreateSelect"; - case kAudioUnitCarbonViewSetEventListenerSelect: return "kAudioUnitCarbonViewSetEventListenerSelect"; - default: return "unknown"; - } - } - const char* AUPropertyStr(int propID) - { - switch (propID) { - case kAudioUnitProperty_ClassInfo: return "kAudioUnitProperty_ClassInfo"; - case kAudioUnitProperty_MakeConnection: return "kAudioUnitProperty_MakeConnection"; - case kAudioUnitProperty_SampleRate: return "kAudioUnitProperty_SampleRate"; - case kAudioUnitProperty_ParameterList: return "kAudioUnitProperty_ParameterList"; - case kAudioUnitProperty_ParameterInfo: return "kAudioUnitProperty_ParameterInfo"; - case kAudioUnitProperty_FastDispatch: return "kAudioUnitProperty_FastDispatch"; - case kAudioUnitProperty_CPULoad: return "kAudioUnitProperty_CPULoad"; - case kAudioUnitProperty_StreamFormat: return "kAudioUnitProperty_StreamFormat"; - case kAudioUnitProperty_ElementCount: return "kAudioUnitProperty_ElementCount"; - case kAudioUnitProperty_Latency: return "kAudioUnitProperty_Latency"; - case kAudioUnitProperty_SupportedNumChannels: return "kAudioUnitProperty_SupportedNumChannels"; - case kAudioUnitProperty_MaximumFramesPerSlice: return "kAudioUnitProperty_MaximumFramesPerSlice"; - case kAudioUnitProperty_SetExternalBuffer: return "kAudioUnitProperty_SetExternalBuffer"; - case kAudioUnitProperty_ParameterValueStrings: return "kAudioUnitProperty_ParameterValueStrings"; - case kAudioUnitProperty_GetUIComponentList: return "kAudioUnitProperty_GetUIComponentList"; - case kAudioUnitProperty_AudioChannelLayout: return "kAudioUnitProperty_AudioChannelLayout"; - case kAudioUnitProperty_TailTime: return "kAudioUnitProperty_TailTime"; - case kAudioUnitProperty_BypassEffect: return "kAudioUnitProperty_BypassEffect"; - case kAudioUnitProperty_LastRenderError: return "kAudioUnitProperty_LastRenderError"; - case kAudioUnitProperty_SetRenderCallback: return "kAudioUnitProperty_SetRenderCallback"; - case kAudioUnitProperty_FactoryPresets: return "kAudioUnitProperty_FactoryPresets"; - case kAudioUnitProperty_ContextName: return "kAudioUnitProperty_ContextName"; - case kAudioUnitProperty_RenderQuality: return "kAudioUnitProperty_RenderQuality"; - case kAudioUnitProperty_HostCallbacks: return "kAudioUnitProperty_HostCallbacks"; - case kAudioUnitProperty_CurrentPreset: return "kAudioUnitProperty_CurrentPreset"; - case kAudioUnitProperty_InPlaceProcessing: return "kAudioUnitProperty_InPlaceProcessing"; - case kAudioUnitProperty_ElementName: return "kAudioUnitProperty_ElementName"; - case kAudioUnitProperty_CocoaUI: return "kAudioUnitProperty_CocoaUI"; - case kAudioUnitProperty_SupportedChannelLayoutTags: return "kAudioUnitProperty_SupportedChannelLayoutTags"; - case kAudioUnitProperty_ParameterIDName: return "kAudioUnitProperty_ParameterIDName"; - case kAudioUnitProperty_ParameterClumpName: return "kAudioUnitProperty_ParameterClumpName"; - case kAudioUnitProperty_PresentPreset: return "kAudioUnitProperty_PresentPreset"; - case kAudioUnitProperty_OfflineRender: return "kAudioUnitProperty_OfflineRender"; - case kAudioUnitProperty_ParameterStringFromValue: return "kAudioUnitProperty_ParameterStringFromValue"; - case kAudioUnitProperty_ParameterValueFromString: return "kAudioUnitProperty_ParameterValueFromString"; - case kAudioUnitProperty_IconLocation: return "kAudioUnitProperty_IconLocation"; - case kAudioUnitProperty_PresentationLatency: return "kAudioUnitProperty_PresentationLatency"; - case kAudioUnitProperty_DependentParameters: return "kAudioUnitProperty_DependentParameters"; - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - case kAudioUnitProperty_AUHostIdentifier: return "kAudioUnitProperty_AUHostIdentifier"; - case kAudioUnitProperty_MIDIOutputCallbackInfo: return "kAudioUnitProperty_MIDIOutputCallbackInfo"; - case kAudioUnitProperty_MIDIOutputCallback: return "kAudioUnitProperty_MIDIOutputCallback"; - case kAudioUnitProperty_InputSamplesInOutput: return "kAudioUnitProperty_InputSamplesInOutput"; - case kAudioUnitProperty_ClassInfoFromDocument: return "kAudioUnitProperty_ClassInfoFromDocument"; - #endif - default: return "unknown"; - } - } - const char* AUScopeStr(int scope) - { - switch (scope) { - case kAudioUnitScope_Global: return "kAudioUnitScope_Global"; - case kAudioUnitScope_Input: return "kAudioUnitScope_Input"; - case kAudioUnitScope_Output: return "kAudioUnitScope_Output"; - case kAudioUnitScope_Group: return "kAudioUnitScope_Group"; - case kAudioUnitScope_Part: return "kAudioUnitScope_Part"; - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - case kAudioUnitScope_Note: return "kAudioUnitScope_Note"; - #endif - default: return "unknown"; - } - } - #endif // __APPLE__ -#else - void Trace(const char* funcName, int line, const char* format, ...) {} - const char* VSTOpcodeStr(int opCode) { return ""; } - const char* AUSelectStr(int select) { return ""; } - const char* AUPropertyStr(int propID) { return ""; } - const char* AUScopeStr(int scope) { return ""; } -#endif // TRACER_BUILD \ No newline at end of file diff --git a/WDL/IPlug/Log.h b/WDL/IPlug/Log.h deleted file mode 100644 index b1a34513..00000000 --- a/WDL/IPlug/Log.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _LOG_ -#define _LOG_ - -#include "stdarg.h" -#include "Containers.h" - -#if defined _WIN32 - #define SYS_THREAD_ID (int) GetCurrentThreadId() -#elif defined __APPLE__ - #define SYS_THREAD_ID (int) pthread_self() -#else - #error "No OS defined!" -#endif - -#if defined TRACER_BUILD - #define TRACE Trace(TRACELOC, ""); -#else - #define TRACE -#endif - -#define TRACELOC __FUNCTION__,__LINE__ -void Trace(const char* funcName, int line, const char* fmtStr, ...); - -// To trace some arbitrary data: Trace(TRACELOC, "%s:%d", myStr, myInt); -// To simply create a trace entry in the log: TRACE; -// No need to wrap tracer calls in #ifdef TRACER_BUILD because Trace is a no-op unless TRACER_BUILD is defined. - -const char* VSTOpcodeStr(int opCode); -const char* AUSelectStr(int select); -const char* AUPropertyStr(int propID); -const char* AUScopeStr(int scope); - -struct Timer -{ - int mT; - Timer(); - - // Returns true every sec seconds. - bool Every(double sec); -}; - -// Not yet ported to WDL. -// Snarf the whole file into a StrVector. -//StrVector ReadFileIntoStr(WDL_String* pFileName); -//int WriteBufferToFile(const DBuffer& buf, WDL_String* pFileName); -// Split line into fields. Whitespace is treated as contiguous. -//StrVector SplitStr(WDL_String* pFileName, char separator = ' '); -void ToLower(char* cDest, const char* cSrc); - -const char* CurrentTime(); -void CompileTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, WDL_String* pStr); -const char* AppendTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, const char* cStr); -#define APPEND_TIMESTAMP(str) AppendTimestamp(__DATE__, __TIME__, str) - -#endif - diff --git a/WDL/IPlug/README.txt b/WDL/IPlug/README.txt deleted file mode 100644 index 3a49dbaa..00000000 --- a/WDL/IPlug/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -IPlug version 20070607 - -The image files in this package were created by White Tie. You may not use these images as part of any product that is offered for sale. - diff --git a/WDL/IPlug/VSTHosts.cpp b/WDL/IPlug/VSTHosts.cpp deleted file mode 100644 index 33e2dbca..00000000 --- a/WDL/IPlug/VSTHosts.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "VSTHosts.h" -#include - -void ToLower(char* cStr) -{ - int i, n = (int) strlen(cStr); - for (i = 0; i < n; ++i) { - cStr[i] = tolower(cStr[i]); - } -} - -EVSTHost LookUpHost(char* vendorStr, char* productStr, int version) -{ - ToLower(vendorStr); - ToLower(productStr); - - // Cockos:REAPER:1990 - if (strstr(productStr, "reaper")) { - return kHostReaper; - } - // Steinberg:Cubase VST:8200 ... C4 = (version >= 8200) - if (strstr(productStr, "cubase")) { - return kHostCubase; - } - // Steinberg:Nuendo:2200 - if (strstr(productStr, "nuendo")) { - return kHostNuendo; - } - // Twelve Tone Systems:Cakewalk VST Wizard 4.5:4 - if (strstr(productStr, "cakewalk")) { - return kHostSonar; - } - // MAGIX:Samplitude:9001 - if (strstr(productStr, "samplitude")) { - return kHostSamplitude; - } - // Image-Line:Fruity Wrapper:6400 - if (strstr(productStr, "fruity")) { - return kHostFL; - } - // Ableton:Live:5020 - if (strstr(vendorStr, "ableton") && strstr(productStr, "live")) { - return kHostAbletonLive; - } - // Celemony Software GmbH:Melodyne:0 - if (strstr(productStr, "melodyne")) { - return kHostMelodyneStudio; - } - // Vincent Burel Inc:VSTMANLIB:1031 - if (strstr(productStr, "vstmanlib")) { - return kHostVSTScanner; - } - - return kHostUnknown; -} \ No newline at end of file diff --git a/WDL/IPlug/VSTHosts.h b/WDL/IPlug/VSTHosts.h deleted file mode 100644 index ff777596..00000000 --- a/WDL/IPlug/VSTHosts.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _VSTHOSTS_ -#define _VSTHOSTS_ - -#include -#include - -enum EVSTHost { - kHostUnknown = 0, - kHostReaper, - kHostProTools, - kHostCubase, - kHostNuendo, - kHostSonar, - kHostVegas, - kHostFL, - kHostSamplitude, - kHostAbletonLive, - kHostTracktion, - kHostNTracks, - kHostMelodyneStudio, - kHostVSTScanner, - - // These hosts don't report the host name: - // MiniHost -}; - -EVSTHost LookUpHost(char* vendorStr, char* productStr, int version); - -#endif - - - \ No newline at end of file diff --git a/WDL/IPlug/lice.vcproj b/WDL/IPlug/lice.vcproj deleted file mode 100644 index fa51cbe8..00000000 --- a/WDL/IPlug/lice.vcproj +++ /dev/null @@ -1,1165 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/WDL/MersenneTwister.h b/WDL/MersenneTwister.h deleted file mode 100644 index 279cfab3..00000000 --- a/WDL/MersenneTwister.h +++ /dev/null @@ -1,411 +0,0 @@ -// Taken from http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html - - -// MersenneTwister.h -// Mersenne Twister random number generator -- a C++ class MTRand -// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com - -// The Mersenne Twister is an algorithm for generating random numbers. It -// was designed with consideration of the flaws in various other generators. -// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, -// are far greater. The generator is also fast; it avoids multiplication and -// division, and it benefits from caches and pipelines. For more information -// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html - -// Reference -// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally -// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on -// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. - -// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, -// Copyright (C) 2000 - 2003, Richard J. Wagner -// 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. The names of its contributors may not be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The original code included the following notice: -// -// When you use this, send an email to: matumoto@math.keio.ac.jp -// with an appropriate reference to your work. -// -// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu -// when you write. - -#ifndef _MERSENNETWISTER_H_ -#define _MERSENNETWISTER_H_ - -// Not thread safe (unless auto-initialization is avoided and each thread has -// its own MTRand object) - -#include -#include -#include -#include - -class MTRand { -// Data -public: - typedef unsigned int uint32; // unsigned integer type, at least 32 bits - - enum { N = 624 }; // length of state vector - enum { SAVE = N + 1 }; // length of array for save() - -protected: - enum { M = 397 }; // period parameter - - uint32 state[N]; // internal state - uint32 *pNext; // next value to get from state - int left; // number of values left before reload needed - - -//Methods -public: - MTRand( const uint32& oneSeed ); // initialize with a simple uint32 - MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array - MTRand(); // auto-initialize with /dev/urandom or time() and clock() - - // Do NOT use for CRYPTOGRAPHY without securely hashing several returned - // values together, otherwise the generator state can be learned after - // reading 624 consecutive values. - - // Access to 32-bit random numbers - double rand(); // real number in [0,1] - double rand( const double& n ); // real number in [0,n] - double randExc(); // real number in [0,1) - double randExc( const double& n ); // real number in [0,n) - double randDblExc(); // real number in (0,1) - double randDblExc( const double& n ); // real number in (0,n) - uint32 randInt(); // integer in [0,2^32-1] - uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 - double operator()() { return rand(); } // same as rand() - - // Access to 53-bit random numbers (capacity of IEEE double precision) - double rand53(); // real number in [0,1) - - // Access to nonuniform random number distributions - double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); - - // Re-seeding functions with same behavior as initializers - void seed( const uint32 oneSeed ); - void seed( uint32 *const bigSeed, const uint32 seedLength = N ); - void seed(); - - // Saving and loading generator state - void save( uint32* saveArray ) const; // to array of size SAVE - void load( uint32 *const loadArray ); // from such array - -protected: - void initialize( const uint32 oneSeed ); - void reload(); - uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } - uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } - uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } - uint32 mixBits( const uint32& u, const uint32& v ) const - { return hiBit(u) | loBits(v); } - uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const - { return m ^ (mixBits(s0,s1)>>1) ^ (-((int)loBit(s1)) & 0x9908b0dfUL); } - -public: - // This was protected, but we need it exposed so FIRan1.h can use it for seeding - static uint32 hash( time_t t, clock_t c ); -}; - - -inline MTRand::MTRand( const uint32& oneSeed ) - { seed(oneSeed); } - -inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) - { seed(bigSeed,seedLength); } - -inline MTRand::MTRand() - { seed(); } - -inline double MTRand::rand() - { return double(randInt()) * (1.0/4294967295.0); } - -inline double MTRand::rand( const double& n ) - { return rand() * n; } - -inline double MTRand::randExc() - { return double(randInt()) * (1.0/4294967296.0); } - -inline double MTRand::randExc( const double& n ) - { return randExc() * n; } - -inline double MTRand::randDblExc() - { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } - -inline double MTRand::randDblExc( const double& n ) - { return randDblExc() * n; } - -inline double MTRand::rand53() -{ - uint32 a = randInt() >> 5, b = randInt() >> 6; - return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada -} - -inline double MTRand::randNorm( const double& mean, const double& variance ) -{ - // Return a real number from a normal (Gaussian) distribution with given - // mean and variance by Box-Muller method - double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; - double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); - return mean + r * cos(phi); -} - -inline MTRand::uint32 MTRand::randInt() -{ - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - - if( left == 0 ) reload(); - --left; - - register uint32 s1; - s1 = *pNext++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680UL; - s1 ^= (s1 << 15) & 0xefc60000UL; - return ( s1 ^ (s1 >> 18) ); -} - -inline MTRand::uint32 MTRand::randInt( const uint32& n ) -{ - // Find which bits are used in n - // Optimized by Magnus Jonsson (magnus@smartelectronix.com) - uint32 used = n; - used |= used >> 1; - used |= used >> 2; - used |= used >> 4; - used |= used >> 8; - used |= used >> 16; - - // Draw numbers until one is found in [0,n] - uint32 i; - do - i = randInt() & used; // toss unused bits to shorten search - while( i > n ); - return i; -} - - -inline void MTRand::seed( const uint32 oneSeed ) -{ - // Seed the generator with a simple uint32 - initialize(oneSeed); - reload(); -} - - -inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) -{ - // Seed the generator with an array of uint32's - // There are 2^19937-1 possible initial states. This function allows - // all of those to be accessed by providing at least 19937 bits (with a - // default seed length of N = 624 uint32's). Any bits above the lower 32 - // in each element are discarded. - // Just call seed() if you want to get array from /dev/urandom - initialize(19650218UL); - register int i = 1; - register uint32 j = 0; - register int k = ( N > seedLength ? N : seedLength ); - for( ; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); - state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; - state[i] &= 0xffffffffUL; - ++i; ++j; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - if( j >= seedLength ) j = 0; - } - for( k = N - 1; k; --k ) - { - state[i] = - state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); - state[i] -= i; - state[i] &= 0xffffffffUL; - ++i; - if( i >= N ) { state[0] = state[N-1]; i = 1; } - } - state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array - reload(); -} - - -inline void MTRand::seed() -{ - // Seed the generator with an array from /dev/urandom if available - // Otherwise use a hash of time() and clock() values - - // No point in trying this on Windows machines - won't work, so it just slows things down -#ifndef WIN32 - // First try getting an array from /dev/urandom - FILE* urandom = fopen( "/dev/urandom", "rb" ); - if( urandom ) - { - uint32 bigSeed[N]; - register uint32 *s = bigSeed; - register int i = N; - register bool success = true; - while( success && i-- ) - success = fread( s++, sizeof(uint32), 1, urandom ); - fclose(urandom); - if( success ) { seed( bigSeed, N ); return; } - } -#endif - - // Was not successful, so use time() and clock() instead - seed( hash( time(NULL), clock() ) ); -} - - -inline void MTRand::initialize( const uint32 seed ) -{ - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - register uint32 *s = state; - register uint32 *r = state; - register int i = 1; - *s++ = seed & 0xffffffffUL; - for( ; i < N; ++i ) - { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; - } -} - - -inline void MTRand::reload() -{ - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - register uint32 *p = state; - register int i; - for( i = int(N) - int(M); i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for( i = M; --i; ++p ) - *p = twist( p[int(M)-int(N)], p[0], p[1] ); - *p = twist( p[int(M)-int(N)], p[0], state[0] ); - - left = N, pNext = state; -} - - -inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) -{ - // Get a uint32 from t and c - // Better than uint32(x) in case x is floating point in [0,1] - // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) - - static uint32 differ = 0; // guarantee time-based seeds will change - - uint32 h1 = 0; - unsigned char *p = (unsigned char *) &t; - for( size_t i = 0; i < sizeof(t); ++i ) - { - h1 *= UCHAR_MAX + 2U; - h1 += p[i]; - } - uint32 h2 = 0; - p = (unsigned char *) &c; - for( size_t j = 0; j < sizeof(c); ++j ) - { - h2 *= UCHAR_MAX + 2U; - h2 += p[j]; - } - return ( h1 + differ++ ) ^ h2; -} - - -inline void MTRand::save( uint32* saveArray ) const -{ - register uint32 *sa = saveArray; - register const uint32 *s = state; - register int i = N; - for( ; i--; *sa++ = *s++ ) {} - *sa = left; -} - - -inline void MTRand::load( uint32 *const loadArray ) -{ - register uint32 *s = state; - register uint32 *la = loadArray; - register int i = N; - for( ; i--; *s++ = *la++ ) {} - left = *la; - pNext = &state[N-left]; -} - - - -#endif // MERSENNETWISTER_H - -// Change log: -// -// v0.1 - First release on 15 May 2000 -// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus -// - Translated from C to C++ -// - Made completely ANSI compliant -// - Designed convenient interface for initialization, seeding, and -// obtaining numbers in default or user-defined ranges -// - Added automatic seeding from /dev/urandom or time() and clock() -// - Provided functions for saving and loading generator state -// -// v0.2 - Fixed bug which reloaded generator one step too late -// -// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew -// -// v0.4 - Removed trailing newline in saved generator format to be consistent -// with output format of built-in types -// -// v0.5 - Improved portability by replacing static const int's with enum's and -// clarifying return values in seed(); suggested by Eric Heimburg -// - Removed MAXINT constant; use 0xffffffffUL instead -// -// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits -// - Changed integer [0,n] generator to give better uniformity -// -// v0.7 - Fixed operator precedence ambiguity in reload() -// - Added access for real numbers in (0,1) and (0,n) -// -// v0.8 - Included time.h header to properly support time_t and clock_t -// -// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto -// - Allowed for seeding with arrays of any length -// - Added access for real numbers in [0,1) with 53-bit resolution -// - Added access for real numbers from normal (Gaussian) distributions -// - Increased overall speed by optimizing twist() -// - Doubled speed of integer [0,n] generation -// - Fixed out-of-range number generation on 64-bit machines -// - Improved portability by substituting literal constants for long enum's -// - Changed license from GNU LGPL to BSD diff --git a/WDL/adpcm_decode.h b/WDL/adpcm_decode.h deleted file mode 100644 index efcaf332..00000000 --- a/WDL/adpcm_decode.h +++ /dev/null @@ -1,317 +0,0 @@ -#ifndef _WDL_ADPCM_DECODE_H_ -#define _WDL_ADPCM_DECODE_H_ - -#include "queue.h" - -#define MSADPCM_TYPE 2 -#define IMAADPCM_TYPE 0x11 -#define CADPCM2_TYPE 0xac0c - -class WDL_adpcm_decoder -{ - typedef struct - { - int cf1,cf2,deltas,spl1,spl2; - } WDL_adpcm_decode_chanctx; - -public: - enum { MSADPCM_PREAMBLELEN=7, IMA_PREAMBLELEN=4 }; - static INT64 sampleLengthFromBytes(INT64 nbytes, int blockalign, int nch, int type, int bps) - { - if (!bps||type!=CADPCM2_TYPE) bps=4; - // remove overhead of headers - INT64 nblocks=((nbytes+blockalign-1)/blockalign); - - // remove preambles - if (type==IMAADPCM_TYPE||type==CADPCM2_TYPE) nbytes -= nblocks*IMA_PREAMBLELEN*nch; - else nbytes -= nblocks*MSADPCM_PREAMBLELEN*nch; - - // scale from bytes to samples - nbytes = (nbytes*8)/(nch*bps); - - if (type==IMAADPCM_TYPE||type==CADPCM2_TYPE) nbytes++; // IMA has just one initial sample - else nbytes+=2; // msadpcm has 2 initial sample values - - return nbytes; - } - - WDL_adpcm_decoder(int blockalign,int nch, int type, int bps) - { - m_bps=0; - m_type=0; - m_nch=0; - m_blockalign=0; - m_srcbuf=0; - m_chans=0; - setParameters(blockalign,nch,type,bps); - } - ~WDL_adpcm_decoder() - { - free(m_srcbuf); - free(m_chans); - } - - - void resetState() - { - if (m_chans) memset(m_chans,0,m_nch*sizeof(WDL_adpcm_decode_chanctx)); - m_srcbuf_valid=0; - samplesOut.Clear(); - samplesOut.Compact(); - } - - void setParameters(int ba, int nch, int type, int bps) - { - if (m_blockalign != ba||nch != m_nch||type!=m_type||bps != m_bps) - { - free(m_srcbuf); - free(m_chans); - m_bps=bps; - m_blockalign=ba; - m_nch=nch; - m_srcbuf_valid=0; - m_srcbuf=(unsigned char*)malloc(ba); - m_chans=(WDL_adpcm_decode_chanctx*)malloc(sizeof(WDL_adpcm_decode_chanctx)*nch); - m_type=type; - resetState(); - } - } - - int blockAlign() { return m_blockalign; } - - int samplesPerBlock() - { - if (m_type==IMAADPCM_TYPE||m_type==CADPCM2_TYPE) - { - if (m_bps == 2) return (m_blockalign/m_nch - IMA_PREAMBLELEN)*4 + 1; - return (m_blockalign/m_nch - IMA_PREAMBLELEN)*2 + 1; //4 bit - } - return (m_blockalign/m_nch - MSADPCM_PREAMBLELEN)*2 + 2; // 4 bit - } - - INT64 samplesToSourceBytes(INT64 outlen_samples) // length in samplepairs - { - outlen_samples -= samplesOut.Available()/m_nch; - if (outlen_samples<1) return 0; // no data required - - int spls_block = samplesPerBlock(); - if (spls_block<1) return 0; - INT64 nblocks = (outlen_samples+spls_block-1)/spls_block; - INT64 v=nblocks * m_blockalign; - - v -= m_srcbuf_valid; - - return max(v,0); - } - - void AddInput(void *buf, int len, short *parm_cotab=NULL) - { - unsigned char *rdbuf = (unsigned char *)buf; - if (m_srcbuf_valid) - { - int v=min(len,m_blockalign-m_srcbuf_valid); - memcpy(m_srcbuf+m_srcbuf_valid,rdbuf,v); - len-=v; - rdbuf+=v; - if ((m_srcbuf_valid+=v)>=m_blockalign) - { - DecodeBlock(m_srcbuf,parm_cotab); - m_srcbuf_valid=0; - } - } - - while (len >= m_blockalign) - { - DecodeBlock(rdbuf,parm_cotab); - rdbuf+=m_blockalign; - len-=m_blockalign; - } - if (len>0) memcpy(m_srcbuf,rdbuf,m_srcbuf_valid=len); - } - - - int sourceBytesQueued() { return m_srcbuf_valid; } - WDL_TypedQueue samplesOut; - -private: - static int getwordsigned(unsigned char **rdptr) - { - int s = (*rdptr)[0] + ((*rdptr)[1]<<8); - (*rdptr)+=2; - if (s & 0x8000) s -= 0x10000; - return s; - } - - bool DecodeBlockIMA(unsigned char *buf) - { - int samples_block = samplesPerBlock(); - - int nch=m_nch; - int ch; - short *outptr = samplesOut.Add(NULL,samples_block * nch); - - for (ch=0;ch>2; break; - default: nib=lastbyte>>4; bstate=0; break; - } - nib &= 8|4; - } - else - { - if ((bstate^=1)) nib=(lastbyte=*buf++)&0xf; - else nib=lastbyte>>4; - } - - int step_index=m_chans[ch].cf1; - if (step_index<0)step_index=0; - else if (step_index>88)step_index=88; - - int step=step_table[step_index]; - - int diff = ((nib&7)*step)/4 + step/8; - - int v=m_chans[ch].spl1 + ((nib&8) ? -diff : diff); - - if (v<-32768)v=-32768; - else if (v>32767)v=32767; - - outptr[wrpos]=(short)v; - wrpos+=nch; - - m_chans[ch].spl1=v; - - m_chans[ch].cf1=step_index + index_table[nib&7]; - - - // advance channelcounts - if (++cnt==chunksize) - { - if (++ch>=nch) - { - ch=0; - outptr += chunksize*nch; - } - wrpos = ch; - cnt=0; - } - } - - return true; - } - - bool DecodeBlock(unsigned char *buf, short *parm_cotab=NULL) - { - if (m_type==IMAADPCM_TYPE||m_type==CADPCM2_TYPE) return DecodeBlockIMA(buf); - static short cotab[14] = { 256,0, 512,-256, 0,0, 192,64, 240, 0,460, -208, 392, -232 }; - static short adtab[16] = { 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 }; - - short *use_cotab = parm_cotab ? parm_cotab : cotab; - int nch = m_nch; - int ch; - for(ch=0;ch 6) return false; - c*=2; - m_chans[ch].cf1 = use_cotab[c]; - m_chans[ch].cf2 = use_cotab[c+1]; - } - for(ch=0;ch>4; - else nib=lastbyte&0xf; - - int sn=nib; - if (sn & 8) sn -= 16; - - int pred = ( ((m_chans[ch].spl1 * m_chans[ch].cf1) + - (m_chans[ch].spl2 * m_chans[ch].cf2)) / 256) + - (sn * m_chans[ch].deltas); - - m_chans[ch].spl2 = m_chans[ch].spl1; - - if (pred < -32768) pred=-32768; - else if (pred > 32767) pred=32767; - - *outptr++ = m_chans[ch].spl1 = pred; - - int i= (adtab[nib] * m_chans[ch].deltas) / 256; - if (i <= 16) m_chans[ch].deltas=16; - else m_chans[ch].deltas = i; - } - } - return true; - } - - WDL_adpcm_decode_chanctx *m_chans; - unsigned char *m_srcbuf; - int m_srcbuf_valid; - - int m_blockalign,m_nch,m_type,m_bps; - - -}; - - -#endif \ No newline at end of file diff --git a/WDL/adpcm_encode.h b/WDL/adpcm_encode.h deleted file mode 100644 index 558dc192..00000000 --- a/WDL/adpcm_encode.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef _WDL_ADPCM_ENCODE_H_ -#define _WDL_ADPCM_ENCODE_H_ - - -#include "pcmfmtcvt.h" - -void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps, - unsigned char *bufout, int *bufout_used, short **predState); - -#define WDL_adpcm_encode_IMA_samplesneededbytes(bytes,bps) ((((bytes)-4)*8)/(bps)+1) - - -// untested. also probably slow. -#ifdef WDL_ADPCM_ENCODE_IMPL - - -static signed char ima_adpcm_index_table[8] = { -1, -1, -1, -1, 2, 4, 6, 8, }; -static short ima_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 -}; - -static char calcBestNibble(int *initial_step_index, int lastSpl, int thisSpl, short *lastsplout, int bps) -{ - - int step=ima_adpcm_step_table[*initial_step_index]; - - char sign=0; - int adiff = thisSpl - lastSpl; - if (adiff<0) { adiff=-adiff; sign=8; } - - // adiff == (nib*step)/4 + step/8 - // adiff - step/8 = nib*step/4 - // nib = 4*(adiff-step/8)/step = 4*adiff/step - 0.5 - int nib = step ? ((4 * adiff - step/2) / step) : 0; - if (nib<0) nib=0; - else if(nib>7) nib=7; - - if (bps==2) nib&=4; - - int diff = (nib*step)/4 + step/8; - *lastsplout = lastSpl + (sign?-diff:diff); - - - *initial_step_index += ima_adpcm_index_table[nib]; - - if (*initial_step_index<0)*initial_step_index=0; - else if (*initial_step_index>88)*initial_step_index=88; - - return (char)nib|sign; -} - - - -void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps, - unsigned char *bufout, int *bufout_used, short **predState) -{ - int x; - if (!*predState) *predState=(short *)calloc(nch,sizeof(short)); - - short *pstate = *predState; - for(x=0;x>8; - spl+=nch; - - *wrptr++ = step_index&0xff; *wrptr++ = step_index>>8; - - wrptr += (nch-1)*4; - - - int outpos=0; - const int outblocklen = bps == 2 ? 16 : 8; - unsigned char buildchar=0; - - while (left-->0) - { - short this_spl; - double_TO_INT16(this_spl,*spl); - char nib = calcBestNibble(&step_index,last_out,this_spl,&last_out,bps); - - spl+=nch; - - // update output - if (bps == 2) - { - nib>>=2; - switch (outpos&3) - { - case 0: buildchar = nib; break; - case 1: buildchar |= nib<<2; break; - case 2: buildchar |= nib<<4; break; - case 3: *wrptr++ = buildchar | (nib<<6); break; - } - } - else - { - if (!(outpos&1)) buildchar = nib; - else *wrptr++ = buildchar | (nib<<4); - } - - // skip other channels - if (++outpos == outblocklen) - { - wrptr += ((nch-1)*outblocklen*bps)/8; - outpos=0; - } - } - pstate[x] = step_index; - - } - *bufout_used = (((numsamples-1)*bps)/8 + 4)*nch; - - -} - -#endif - - -#endif//_WDL_ADPCM_ENCODE_H_ \ No newline at end of file diff --git a/WDL/assocarray.h b/WDL/assocarray.h deleted file mode 100644 index 4406e732..00000000 --- a/WDL/assocarray.h +++ /dev/null @@ -1,317 +0,0 @@ -#ifndef _WDL_ASSOCARRAY_H_ -#define _WDL_ASSOCARRAY_H_ - -#include "heapbuf.h" - - -// on all of these, if valdispose is set, the array will dispose of values as needed. -// if keydup/keydispose are set, copies of (any) key data will be made/destroyed as necessary - - -// WDL_AssocArrayImpl can be used on its own, and can contain structs for keys or values -template class WDL_AssocArrayImpl -{ -public: - - explicit WDL_AssocArrayImpl(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) - { - m_keycmp = keycmp; - m_keydup = keydup; - m_keydispose = keydispose; - m_valdispose = valdispose; - } - - ~WDL_AssocArrayImpl() - { - DeleteAll(); - } - - VAL* GetPtr(KEY key, KEY *keyPtrOut=NULL) const - { - bool ismatch = false; - int i = LowerBound(key, &ismatch); - if (ismatch) - { - KeyVal* kv = m_data.Get()+i; - if (keyPtrOut) *keyPtrOut = kv->key; - return &(kv->val); - } - return 0; - } - - bool Exists(KEY key) const - { - bool ismatch = false; - LowerBound(key, &ismatch); - return ismatch; - } - - void Insert(KEY key, VAL val, KEY *keyPtrOut=NULL) - { - bool ismatch = false; - int i = LowerBound(key, &ismatch); - if (ismatch) - { - KeyVal* kv = m_data.Get()+i; - if (m_valdispose) m_valdispose(kv->val); - kv->val = val; - if (keyPtrOut) *keyPtrOut = kv->key; - } - else - { - KeyVal* kv = m_data.Resize(m_data.GetSize()+1)+i; - memmove(kv+1, kv, (m_data.GetSize()-i-1)*sizeof(KeyVal)); - if (m_keydup) key = m_keydup(key); - kv->key = key; - kv->val = val; - if (keyPtrOut) *keyPtrOut = key; - } - } - - void Delete(KEY key) - { - bool ismatch = false; - int i = LowerBound(key, &ismatch); - if (ismatch) - { - KeyVal* kv = m_data.Get()+i; - if (m_keydispose) m_keydispose(kv->key); - if (m_valdispose) m_valdispose(kv->val); - memmove(kv, kv+1, (m_data.GetSize()-i-1)*sizeof(KeyVal)); - m_data.Resize(m_data.GetSize()-1); - } - } - - void DeleteByIndex(int idx) - { - if (idx>=0&&idxkey); - if (m_valdispose) m_valdispose(kv->val); - memmove(kv, kv+1, (m_data.GetSize()-idx-1)*sizeof(KeyVal)); - m_data.Resize(m_data.GetSize()-1); - } - } - - void DeleteAll(bool resizedown=false) - { - if (m_keydispose || m_valdispose) - { - int i; - for (i = 0; i < m_data.GetSize(); ++i) - { - KeyVal* kv = m_data.Get()+i; - if (m_keydispose) m_keydispose(kv->key); - if (m_valdispose) m_valdispose(kv->val); - } - } - m_data.Resize(0, resizedown); - } - - int GetSize() const - { - return m_data.GetSize(); - } - - VAL* EnumeratePtr(int i, KEY* key=0) const - { - if (i >= 0 && i < m_data.GetSize()) - { - KeyVal* kv = m_data.Get()+i; - if (key) *key = kv->key; - return &(kv->val); - } - return 0; - } - - KEY* ReverseLookupPtr(VAL val) const - { - int i; - for (i = 0; i < m_data.GetSize(); ++i) - { - KeyVal* kv = m_data.Get()+i; - if (kv->val == val) return &kv->key; - } - return 0; - } - - void ChangeKey(KEY oldkey, KEY newkey) - { - bool ismatch=false; - int i = LowerBound(oldkey, &ismatch); - if (ismatch) - { - KeyVal* kv = m_data.Get()+i; - if (m_keydispose) m_keydispose(kv->key); - if (m_keydup) newkey = m_keydup(newkey); - kv->key = newkey; - Resort(); - } - } - - // fast add-block mode - void AddUnsorted(KEY key, VAL val) - { - int i=m_data.GetSize(); - KeyVal* kv = m_data.Resize(i+1)+i; - if (m_keydup) key = m_keydup(key); - kv->key = key; - kv->val = val; - } - - void Resort() - { - if (m_data.GetSize() > 1 && m_keycmp) - { - qsort(m_data.Get(),m_data.GetSize(),sizeof(KeyVal),(int(*)(const void *,const void *))m_keycmp); - - // AddUnsorted can add duplicate keys - // unfortunately qsort is not guaranteed to preserve order, - // ideally this filter would always preserve the last-added key - int i; - for (i=0; i < m_data.GetSize()-1; ++i) - { - KeyVal* kv=m_data.Get()+i; - KeyVal* nv=kv+1; - if (!m_keycmp(&kv->key, &nv->key)) - { - DeleteByIndex(i--); - } - } - } - } - - int LowerBound(KEY key, bool* ismatch) const - { - int a = 0; - int c = m_data.GetSize(); - while (a != c) - { - int b = (a+c)/2; - KeyVal* kv=m_data.Get()+b; - int cmp = m_keycmp(&key, &kv->key); - if (cmp > 0) a = b+1; - else if (cmp < 0) c = b; - else - { - *ismatch = true; - return b; - } - } - *ismatch = false; - return a; - } - - int GetIdx(KEY key) const - { - bool ismatch=false; - int i = LowerBound(key, &ismatch); - if (ismatch) return i; - return -1; - } - - void SetGranul(int gran) - { - m_data.SetGranul(gran); - } - -private: - - struct KeyVal - { - KEY key; - VAL val; - }; - WDL_TypedBuf m_data; - - int (*m_keycmp)(KEY *k1, KEY *k2); - KEY (*m_keydup)(KEY); - void (*m_keydispose)(KEY); - void (*m_valdispose)(VAL); - -}; - - -// WDL_AssocArray adds useful functions but cannot contain structs for keys or values -template class WDL_AssocArray : public WDL_AssocArrayImpl -{ -public: - - explicit WDL_AssocArray(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) - : WDL_AssocArrayImpl(keycmp, keydup, keydispose, valdispose) - { - } - - VAL Get(KEY key, VAL notfound=0) const - { - VAL* p = this->GetPtr(key); - if (p) return *p; - return notfound; - } - - VAL Enumerate(int i, KEY* key=0, VAL notfound=0) const - { - VAL* p = this->EnumeratePtr(i, key); - if (p) return *p; - return notfound; - } - - KEY ReverseLookup(VAL val, KEY notfound=0) const - { - KEY* p=this->ReverseLookupPtr(val); - if (p) return *p; - return notfound; - } -}; - - -template class WDL_IntKeyedArray : public WDL_AssocArray -{ -public: - - explicit WDL_IntKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpint, NULL, NULL, valdispose) {} - ~WDL_IntKeyedArray() {} - -private: - - static int cmpint(int *i1, int *i2) { return *i1-*i2; } -}; - - -template class WDL_StringKeyedArray : public WDL_AssocArray -{ -public: - - explicit WDL_StringKeyedArray(bool caseSensitive=true, void (*valdispose)(VAL)=0) : WDL_AssocArray(caseSensitive?cmpstr:cmpistr, dupstr, freestr, valdispose) {} - - ~WDL_StringKeyedArray() { } - -private: - - static const char *dupstr(const char *s) { return strdup(s); } // these might not be necessary but depending on the libc maybe... - static int cmpstr(const char **s1, const char **s2) { return strcmp(*s1, *s2); } - static int cmpistr(const char **a, const char **b) { return stricmp(*a,*b); } - static void freestr(const char* s) { free((void*)s); } - -public: - static void freecharptr(char *p) { free(p); } -}; - - -template class WDL_PtrKeyedArray : public WDL_AssocArray -{ -public: - - explicit WDL_PtrKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpptr, 0, 0, valdispose) {} - - ~WDL_PtrKeyedArray() {} - -private: - - static int cmpptr(INT_PTR* a, INT_PTR* b) { return *a-*b; } -}; - - -#endif - diff --git a/WDL/audiobuffercontainer.cpp b/WDL/audiobuffercontainer.cpp deleted file mode 100644 index c7406dde..00000000 --- a/WDL/audiobuffercontainer.cpp +++ /dev/null @@ -1,495 +0,0 @@ -#include "audiobuffercontainer.h" -#include "queue.h" -#include - -void ChannelPinMapper::SetNPins(int nPins) -{ - if (nPins<0) nPins=0; - else if (nPins>CHANNELPINMAPPER_MAXPINS) nPins=CHANNELPINMAPPER_MAXPINS; - int i; - for (i = m_nPins; i < nPins; ++i) { - ClearPin(i); - if (i < m_nCh) { - SetPin(i, i, true); - } - } - m_nPins = nPins; -} - -void ChannelPinMapper::SetNChannels(int nCh) -{ - int i; - for (i = m_nCh; i < nCh && i < m_nPins; ++i) { - SetPin(i, i, true); - } - m_nCh = nCh; -} - -void ChannelPinMapper::Init(WDL_UINT64* pMapping, int nPins) -{ - if (nPins<0) nPins=0; - else if (nPins>CHANNELPINMAPPER_MAXPINS) nPins=CHANNELPINMAPPER_MAXPINS; - memcpy(m_mapping, pMapping, nPins*sizeof(WDL_UINT64)); - m_nPins = m_nCh = nPins; -} - -#define BITMASK64(bitIdx) (((WDL_UINT64)1)<<(bitIdx)) - -void ChannelPinMapper::ClearPin(int pinIdx) -{ - if (pinIdx >=0 && pinIdx < CHANNELPINMAPPER_MAXPINS) m_mapping[pinIdx] = 0; -} - -void ChannelPinMapper::SetPin(int pinIdx, int chIdx, bool on) -{ - if (pinIdx >=0 && pinIdx < CHANNELPINMAPPER_MAXPINS) - { - if (on) - { - m_mapping[pinIdx] |= BITMASK64(chIdx); - } - else - { - m_mapping[pinIdx] &= ~BITMASK64(chIdx); - } - } -} - -bool ChannelPinMapper::TogglePin(int pinIdx, int chIdx) -{ - bool on = GetPin(pinIdx, chIdx); - on = !on; - SetPin(pinIdx, chIdx, on); - return on; -} - -bool ChannelPinMapper::GetPin(int pinIdx, int chIdx) -{ - if (pinIdx >= 0 && pinIdx < CHANNELPINMAPPER_MAXPINS) - { - WDL_UINT64 map = m_mapping[pinIdx]; - return !!(map & BITMASK64(chIdx)); - } - return false; -} - -bool ChannelPinMapper::PinHasMoreMappings(int pinIdx, int chIdx) -{ - if (pinIdx >= 0 && pinIdx < CHANNELPINMAPPER_MAXPINS) - { - WDL_UINT64 map = m_mapping[pinIdx]; - return (chIdx < 63 && map >= BITMASK64(chIdx+1)); - } - return false; -} - -bool ChannelPinMapper::IsStraightPassthrough() -{ - if (m_nCh != m_nPins) return false; - WDL_UINT64* pMap = m_mapping; - int i; - for (i = 0; i < m_nPins; ++i, ++pMap) { - if (*pMap != BITMASK64(i)) return false; - } - return true; -} - -#define PINMAPPER_MAGIC 1000 - -// return is on the heap -char* ChannelPinMapper::SaveStateNew(int* pLen) -{ - m_cfgret.Clear(); - int magic = PINMAPPER_MAGIC; - WDL_Queue__AddToLE(&m_cfgret, &magic); - WDL_Queue__AddToLE(&m_cfgret, &m_nCh); - WDL_Queue__AddToLE(&m_cfgret, &m_nPins); - WDL_Queue__AddDataToLE(&m_cfgret, m_mapping, m_nPins*sizeof(WDL_UINT64), sizeof(WDL_UINT64)); - *pLen = m_cfgret.GetSize(); - return (char*)m_cfgret.Get(); -} - -bool ChannelPinMapper::LoadState(char* buf, int len) -{ - WDL_Queue chunk; - chunk.Add(buf, len); - int* pMagic = WDL_Queue__GetTFromLE(&chunk, (int*)0); - if (!pMagic || *pMagic != PINMAPPER_MAGIC) return false; - int* pNCh = WDL_Queue__GetTFromLE(&chunk, (int*) 0); - int* pNPins = WDL_Queue__GetTFromLE(&chunk, (int*) 0); - if (!pNCh || !pNPins || !(*pNCh) || !(*pNPins)) return false; - SetNPins(*pNCh); - SetNChannels(*pNCh); - int maplen = *pNPins*sizeof(WDL_UINT64); - if (chunk.Available() < maplen) return false; - void* pMap = WDL_Queue__GetDataFromLE(&chunk, maplen, sizeof(WDL_UINT64)); - - int sz= m_nPins*sizeof(WDL_UINT64); - if (sz>maplen) sz=maplen; - memcpy(m_mapping, pMap, sz); - return true; -} - -template void BufConvertT(TDEST* dest, TSRC* src, int nFrames, int destStride, int srcStride) -{ - int i; - for (i = 0; i < nFrames; ++i) - { - dest[i*destStride] = (TDEST)src[i*srcStride]; - } -} - -template void BufMixT(T* dest, T* src, int nFrames, bool addToDest, double wt_start, double wt_end) -{ - int i; - - if (wt_start == 1.0 && wt_end == 1.0) - { - if (addToDest) - { - for (i = 0; i < nFrames; ++i) - { - dest[i] += src[i]; - } - } - else - { - memcpy(dest, src, nFrames*sizeof(T)); - } - } - else - { - double dw = (wt_end-wt_start)/(double)nFrames; - double cw = wt_start; - - if (addToDest) - { - for (i = 0; i < nFrames; ++i) - { - dest[i] += (T)(1.0-cw)*dest[i]+(T)cw*src[i]; - cw += dw; - } - } - else - { - for (i = 0; i < nFrames; ++i) - { - dest[i] = (T)(1.0-cw)*dest[i]+(T)cw*src[i]; - cw += dw; - } - } - } -} - -// static -bool AudioBufferContainer::BufConvert(void* dest, void* src, int destFmt, int srcFmt, int nFrames, int destStride, int srcStride) -{ - if (destFmt == FMT_32FP) - { - if (srcFmt == FMT_32FP) - { - BufConvertT((float*)dest, (float*)src, nFrames, destStride, srcStride); - return true; - } - else if (srcFmt == FMT_64FP) - { - BufConvertT((float*)dest, (double*)src, nFrames, destStride, srcStride); - return true; - } - } - else if (destFmt == FMT_64FP) - { - if (srcFmt == FMT_32FP) - { - BufConvertT((double*)dest, (float*)src, nFrames, destStride, srcStride); - return true; - } - else if (srcFmt == FMT_64FP) - { - BufConvertT((double*)dest, (double*)src, nFrames, destStride, srcStride); - return true; - } - } - return false; -} - -AudioBufferContainer::AudioBufferContainer() -{ - m_nCh = 0; - m_nFrames = 0; - m_fmt = FMT_32FP; - m_interleaved = true; - m_hasData = false; -} - -void AudioBufferContainer::Resize(int nCh, int nFrames, bool preserveData) -{ - if (!m_hasData) - { - preserveData = false; - } - - int newsz = nCh*nFrames*(int)m_fmt; - - if (preserveData && (nCh != m_nCh || nFrames != m_nFrames)) - { - GetAllChannels(m_fmt, true); // causes m_data to be interleaved - } - - m_data.Resize(newsz); - m_hasData = preserveData; - m_nCh = nCh; - m_nFrames = nFrames; -} - -void AudioBufferContainer::Reformat(int fmt, bool preserveData) -{ - if (!m_hasData) - { - preserveData = false; - } - - int newsz = m_nCh*m_nFrames*(int)fmt; - - if (preserveData && fmt != m_fmt) - { - int oldsz = m_data.GetSize(); - void* src = m_data.Resize(oldsz+newsz); - void* dest = (unsigned char*)src+oldsz; - BufConvert(dest, src, fmt, m_fmt, m_nCh*m_nFrames, 1, 1); - memmove(src, dest, newsz); - } - - m_data.Resize(newsz); - m_hasData = preserveData; - m_fmt = fmt; -} - -// src=NULL to memset(0) -void* AudioBufferContainer::SetAllChannels(int fmt, void* src, int nCh, int nFrames) -{ - Reformat(fmt, false); - Resize(nCh, nFrames, false); - - int sz = nCh*nFrames*(int)fmt; - void* dest = GetAllChannels(fmt, false); - if (src) - { - memcpy(dest, src, sz); - } - else - { - memset(dest, 0, sz); - } - - m_interleaved = true; - m_hasData = true; - return dest; -} - -// src=NULL to memset(0) -void* AudioBufferContainer::SetChannel(int fmt, void* src, int chIdx, int nFrames) -{ - Reformat(fmt, true); - if (nFrames > m_nFrames || chIdx >= m_nCh) - { - int maxframes = (nFrames > m_nFrames ? nFrames : m_nFrames); - Resize(chIdx+1, maxframes, true); - } - - int sz = nFrames*(int)fmt; - void* dest = GetChannel(fmt, chIdx, true); - if (src) - { - memcpy(dest, src, sz); - } - else - { - memset(dest, 0, sz); - } - - m_interleaved = false; - m_hasData = true; - return dest; -} - -void* AudioBufferContainer::MixChannel(int fmt, void* src, int chIdx, int nFrames, bool addToDest, double wt_start, double wt_end) -{ - Reformat(fmt, true); - if (nFrames > m_nFrames || chIdx >= m_nCh) - { - int maxframes = (nFrames > m_nFrames ? nFrames : m_nFrames); - Resize(chIdx+1, maxframes, true); - } - - void* dest = GetChannel(fmt, chIdx, true); - - if (fmt == FMT_32FP) - { - BufMixT((float*)dest, (float*)src, nFrames, addToDest, wt_start, wt_end); - } - else if (fmt == FMT_64FP) - { - BufMixT((double*)dest, (double*)src, nFrames, addToDest, wt_start, wt_end); - } - - m_interleaved = false; - m_hasData = true; - return dest; -} - - -void* AudioBufferContainer::GetAllChannels(int fmt, bool preserveData) -{ - Reformat(fmt, preserveData); - ReLeave(true, preserveData); - - m_hasData = true; // because caller may use the returned pointer to populate the container - - return m_data.Get(); -} - -void* AudioBufferContainer::GetChannel(int fmt, int chIdx, bool preserveData) -{ - Reformat(fmt, preserveData); - if (chIdx >= m_nCh) - { - Resize(chIdx+1, m_nFrames, true); - } - ReLeave(false, preserveData); - - m_hasData = true; // because caller may use the returned pointer to populate the container - - int offsz = chIdx*m_nFrames*(int)fmt; - return (unsigned char*)m_data.Get()+offsz; -} - -void AudioBufferContainer::ReLeave(bool interleave, bool preserveData) -{ - if (interleave != m_interleaved && preserveData && m_hasData) - { - int elemsz = (int)m_fmt; - int chansz = m_nFrames*elemsz; - int bufsz = m_nCh*chansz; - int i; - - unsigned char* src = (unsigned char*)m_data.Resize(bufsz*2); - unsigned char* dest = src+bufsz; - - if (interleave) - { - for (i = 0; i < m_nCh; ++i) - { - BufConvert((void*)(dest+i*elemsz), (void*)(src+i*chansz), m_fmt, m_fmt, m_nFrames, m_nCh, 1); - } - } - else - { - for (i = 0; i < m_nCh; ++i) - { - BufConvert((void*)(dest+i*chansz), (void*)(src+i*elemsz), m_fmt, m_fmt, m_nFrames, 1, m_nCh); - } - } - - memcpy(src, dest, bufsz); // no overlap - m_data.Resize(bufsz); - } - - m_hasData = preserveData; - m_interleaved = interleave; -} - -void AudioBufferContainer::CopyFrom(AudioBufferContainer* rhs) -{ - int sz = rhs->m_data.GetSize(); - void* dest = m_data.Resize(sz); - - if (rhs->m_hasData) - { - void* src = rhs->m_data.Get(); - memcpy(dest, src, sz); - } - - m_nCh = rhs->m_nCh; - m_nFrames = rhs->m_nFrames; - m_fmt = rhs->m_fmt; - m_interleaved = rhs->m_interleaved; - m_hasData = rhs->m_hasData; -} - - -void SetPinsFromChannels(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper) -{ - if (mapper->IsStraightPassthrough()) - { - dest->CopyFrom(src); - return; - } - - int nch = mapper->GetNChannels(); - int npins = mapper->GetNPins(); - int nframes = src->GetNFrames(); - int fmt = src->GetFormat(); - - dest->Resize(npins, nframes, false); - - int c, p; - for (p = 0; p < npins; ++p) - { - bool pinused = false; - for (c = 0; c < nch; ++c) - { - if (mapper->GetPin(p, c)) - { - void* srcbuf = src->GetChannel(fmt, c, true); - dest->MixChannel(fmt, srcbuf, p, nframes, pinused, 1.0, 1.0); - pinused = true; - - if (!mapper->PinHasMoreMappings(p, c)) - { - break; - } - } - } - - if (!pinused) - { - dest->SetChannel(fmt, 0, p, nframes); // clear unused pins - } - } -} - -void SetChannelsFromPins(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper, double wt_start, double wt_end) -{ - if (wt_start == 1.0 && wt_end == 1.0 && mapper->IsStraightPassthrough()) - { - dest->CopyFrom(src); - return; - } - - int nch = mapper->GetNChannels(); - int npins = mapper->GetNPins(); - int nframes = src->GetNFrames(); - int fmt = src->GetFormat(); - - dest->Resize(nch, nframes, true); - - int c, p; - for (c = 0; c < nch; ++c) - { - bool chanused = false; - for (p = 0; p < npins; ++p) - { - if (mapper->GetPin(p, c)) - { - void* srcbuf = src->GetChannel(fmt, p, true); - dest->MixChannel(fmt, srcbuf, c, nframes, chanused, wt_start, wt_end); - chanused = true; - } - } - // don't clear unused channels - } -} - - - diff --git a/WDL/audiobuffercontainer.h b/WDL/audiobuffercontainer.h deleted file mode 100644 index ab8c3d30..00000000 --- a/WDL/audiobuffercontainer.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef _AUDIOBUFFERCONTAINER_ -#define _AUDIOBUFFERCONTAINER_ - -#include "wdltypes.h" -#include -#include -#include "ptrlist.h" -#include "queue.h" - - -#define CHANNELPINMAPPER_MAXPINS 64 - -class ChannelPinMapper -{ -public: - - ChannelPinMapper() : m_nCh(0), m_nPins(0) {} - ~ChannelPinMapper() {} - - void SetNPins(int nPins); - void SetNChannels(int nCh); - // or ... - void Init(WDL_UINT64* pMapping, int nPins); - - int GetNPins() { return m_nPins; } - int GetNChannels() { return m_nCh; } - - void ClearPin(int pinIdx); - void SetPin(int pinIdx, int chIdx, bool on); - bool TogglePin(int pinIdx, int chIdx); - - // true if this pin is mapped to this channel - bool GetPin(int pinIdx, int chIdx); - // true if this pin is to any higher channel - bool PinHasMoreMappings(int pinIdx, int chIdx); - // true if this mapper is a straight 1:1 passthrough - bool IsStraightPassthrough(); - - char* SaveStateNew(int* pLen); // owned - bool LoadState(char* buf, int len); - - WDL_UINT64 m_mapping[CHANNELPINMAPPER_MAXPINS]; - -private: - - WDL_Queue m_cfgret; - int m_nCh, m_nPins; -}; - - -// use for float and double only ... ints will break it -class AudioBufferContainer -{ -public: - - AudioBufferContainer(); - ~AudioBufferContainer() {} - - enum - { - FMT_32FP=4, - FMT_64FP=8 - }; - - static bool BufConvert(void* dest, void* src, int destFmt, int srcFmt, int nFrames, int destStride, int srcStride); - - int GetNChannels() { return m_nCh; } - int GetNFrames() { return m_nFrames; } - int GetFormat() { return m_fmt; } - - void Resize(int nCh, int nFrames, bool preserveData); - // call Reformat(GetFormat(), false) to discard current data (for efficient repopulating) - void Reformat(int fmt, bool preserveData); - - // src=NULL to memset(0) - void* SetAllChannels(int fmt, void* src, int nCh, int nFrames); - - // src=NULL to memset(0) - void* SetChannel(int fmt, void* src, int chIdx, int nFrames); - - void* MixChannel(int fmt, void* src, int chIdx, int nFrames, bool addToDest, double wt_start, double wt_end); - - void* GetAllChannels(int fmt, bool preserveData); - void* GetChannel(int fmt, int chIdx, bool preserveData); - - void CopyFrom(AudioBufferContainer* rhs); - -private: - - void ReLeave(bool interleave, bool preserveData); - - WDL_HeapBuf m_data; - int m_nCh; - int m_nFrames; - - int m_fmt; - bool m_interleaved; - bool m_hasData; -} WDL_FIXALIGN; - - -void SetPinsFromChannels(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper); -void SetChannelsFromPins(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper, double wt_start=1.0, double wt_end=1.0); - - -#endif diff --git a/WDL/blowfish.c b/WDL/blowfish.c deleted file mode 100644 index f9151ab3..00000000 --- a/WDL/blowfish.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Author : Paul Kocher - * E-mail : pck@netcom.com - * Date : 1997 - * Description: C implementation of the Blowfish algorithm. - -*/ - -#include "blowfish.h" - -#define N 16 - -static const unsigned int ORIG_P[16 + 2] = { - 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, - 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, - 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, - 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, - 0x9216D5D9L, 0x8979FB1BL - -}; - -static const unsigned int ORIG_S[4*256] = { - 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, - 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, - 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, - 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, - 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, - 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, - 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, - 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, - 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, - 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, - 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, - 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, - 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, - 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, - 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, - 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, - 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, - 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, - 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, - 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, - 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, - 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, - 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, - 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, - 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, - 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, - 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, - 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, - 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, - 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, - 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, - 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, - 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, - 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, - 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, - 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, - 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, - 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, - 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, - 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, - 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, - 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, - 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, - 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, - 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, - 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, - 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, - 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, - 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, - 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, - 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, - 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, - 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, - 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, - 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, - 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, - 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, - 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, - 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, - 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, - 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, - 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, - 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, - 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL, - 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, - 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, - 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, - 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, - 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, - 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, - 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, - 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, - 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, - 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, - 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, - 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, - 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, - 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, - 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, - 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, - 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, - 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, - 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, - 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, - 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, - 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, - 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, - 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, - 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, - 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, - 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, - 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, - 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, - 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, - 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, - 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, - 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, - 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, - 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, - 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, - 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, - 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, - 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, - 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, - 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, - 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, - 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, - 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, - 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, - 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, - 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, - 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, - 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, - 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, - 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, - 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, - 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, - 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, - 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, - 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, - 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, - 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, - 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, - 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, - 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, - 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, - 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, - 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L, - 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, - 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, - 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, - 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, - 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, - 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, - 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, - 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, - 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, - 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, - 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, - 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, - 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, - 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, - 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, - 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, - 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, - 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, - 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, - 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, - 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, - 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, - 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, - 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, - 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, - 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, - 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, - 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, - 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, - 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, - 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, - 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, - 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, - 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, - 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, - 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, - 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, - 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, - 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, - 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, - 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, - 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, - 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, - 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, - 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, - 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, - 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, - 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, - 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, - 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, - 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, - 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, - 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, - 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, - 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, - 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, - 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, - 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, - 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, - 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, - 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, - 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, - 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, - 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L, - 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, - 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, - 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, - 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, - 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, - 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, - 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, - 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, - 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, - 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, - 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, - 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, - 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, - 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, - 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, - 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, - 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, - 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, - 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, - 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, - 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, - 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, - 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, - 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, - 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, - 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, - 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, - 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, - 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, - 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, - 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, - 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, - 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, - 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, - 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, - 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, - 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, - 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, - 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, - 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, - 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, - 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, - 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, - 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, - 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, - 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, - 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, - 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, - 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, - 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, - 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, - 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, - 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, - 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, - 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, - 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, - 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, - 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, - 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, - 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, - 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, - 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, - 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, - 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L - -}; - -#define F(x) (((s[(x>>24)&0xff] + s[256+((x>>16)&0xff)]) ^ s[512+((x>>8)&0xff)]) + s[768+(x&0xff)]) - -static char __bigE; - -static void BSWAPONBIGE(unsigned int *a,unsigned int *a2) -{ - if (__bigE>0) - { - unsigned char *b=(unsigned char *)a; - unsigned char c=b[0]; - b[0]=b[3]; - b[3]=c; - c=b[1]; - b[1]=b[2]; - b[2]=c; - - b=(unsigned char *)a2; - c=b[0]; - b[0]=b[3]; - b[3]=c; - c=b[1]; - b[1]=b[2]; - b[2]=c; - - } -} - -void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr) -{ - BSWAPONBIGE(xl,xr); - { - unsigned int Xl=*xl; - unsigned int Xr=*xr; - int i=N/2; - unsigned int *p=ctx->P; - unsigned int *s=(unsigned int *)ctx->S; - while (i--) - { - Xl ^= *p++; - Xr ^= F(Xl) ^ *p++; - Xl ^= F(Xr); - } - *xr = Xl ^ *p++; - *xl = Xr ^ *p; - } - BSWAPONBIGE(xl,xr); -} - -void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr) -{ - BSWAPONBIGE(xl,xr); - { - unsigned int Xl=*xl; - unsigned int Xr=*xr; - unsigned int *p=ctx->P + N + 1; - unsigned int *s=(unsigned int *)ctx->S; - int i=N/2; - while (i--) - { - Xl ^= *p--; - Xr ^= F(Xl) ^ *p--; - Xl ^= F(Xr); - } - *xr = Xl ^ *p--; - *xl = Xr ^ *p; - } - BSWAPONBIGE(xl,xr); -} - -void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen) { - int i, j=0; - unsigned int *s=(unsigned int *)ORIG_P; - unsigned int *p=ctx->P; - - unsigned int datal=0, datar=0; - - if (!__bigE) - { - int a=1; - __bigE = (*(char *)&a) ? -1 : 1; - } - - i=N+2; - while (i--) - { - int k=4; - unsigned int data = 0; - while (k--) - { - data = (data << 8) | key[j]; - if (++j >= keyLen) j = 0; - } - *p++=*s++ ^ data; - } - for(i=0;i<256*4; i++) ctx->S[i]=ORIG_S[i]; - - p=ctx->P; - i=(N+2)/2; - while (i--) - { - BSWAPONBIGE(&datal,&datar); - Blowfish_Encrypt(ctx, &datal, &datar); - BSWAPONBIGE(&datal,&datar); - *p++=datal; - *p++=datar; - } - - s=ctx->S; - i=256/2*4; - while (i--) - { - BSWAPONBIGE(&datal,&datar); - Blowfish_Encrypt(ctx, &datal, &datar); - BSWAPONBIGE(&datal,&datar); - *s++ = datal; - *s++ = datar; - } -} diff --git a/WDL/blowfish.h b/WDL/blowfish.h deleted file mode 100644 index 7bd4c4f8..00000000 --- a/WDL/blowfish.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Author : Paul Kocher - * E-mail : pck@netcom.com - * Date : 1997 - * Description: C implementation of the Blowfish algorithm. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned int P[16 + 2]; - unsigned int S[4*256]; -} BLOWFISH_CTX; - -void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen); -void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr); -void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr); - -#ifdef __cplusplus -}; -#endif \ No newline at end of file diff --git a/WDL/chunkalloc.h b/WDL/chunkalloc.h deleted file mode 100644 index 14fc35b1..00000000 --- a/WDL/chunkalloc.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef _WDL_CHUNKALLOC_H_ -#define _WDL_CHUNKALLOC_H_ - -#include "wdltypes.h" - -class WDL_ChunkAlloc -{ - struct _hdr - { - struct _hdr *_next; - char data[16]; - }; - - _hdr *m_chunks; - int m_chunksize, m_chunkused; - - public: - - WDL_ChunkAlloc(int chunksize=65500) { m_chunks=NULL; m_chunkused=0; m_chunksize=chunksize>16?16:chunksize; } - ~WDL_ChunkAlloc() { Free(); } - - void Free() - { - _hdr *a = m_chunks; - m_chunks=0; - m_chunkused=0; - while (a) { _hdr *f=a; a=a->_next; free(f); } - } - - void *Alloc(int sz, int align=0) - { - if (sz<1) return NULL; - - if (align < 1 || (align & (align-1))) align=1; - - if (m_chunks) - { - int use_sz=sz; - char *p = m_chunks->data + m_chunkused; - int a = ((int) (INT_PTR)p) & (align-1); - if (a) - { - use_sz += align-a; - p += align-a; - } - if (use_sz <= m_chunksize - m_chunkused) - { - m_chunkused += use_sz; - return p; - } - } - - // we assume that malloc always gives at least 8 byte alignment, and our _next ptr may offset that by 4, - // so no need to allocate extra if less than 4 bytes of alignment requested - int use_align = (align>=4 ? align : 0); - int alloc_sz=sz+use_align; - if (alloc_sz < m_chunksize) - { - // if existing chunk has less free space in it than we would at chunksize, allocate chunksize - if (!m_chunks || m_chunkused > alloc_sz) alloc_sz=m_chunksize; - } - _hdr *nc = (_hdr *)malloc(sizeof(_hdr) + alloc_sz - 16); - if (!nc) return NULL; - - int use_sz=sz; - char *ret = nc->data; - int a = ((int) (INT_PTR)ret) & (align-1); - if (a) - { - use_sz += align-a; - ret += align-a; - } - - if (m_chunks && (m_chunksize-m_chunkused) >= (alloc_sz - use_sz)) - { - // current chunk has as much or more free space than our chunk, put our chunk on the list second - nc->_next = m_chunks->_next; - m_chunks->_next=nc; - } - else - { - // push our chunk to the top of the list - nc->_next = m_chunks; - m_chunks=nc; - m_chunkused = alloc_sz >= m_chunksize ? use_sz : m_chunksize; - } - - return ret; - } - -}; - -#endif diff --git a/WDL/circbuf.h b/WDL/circbuf.h deleted file mode 100644 index 96d7bc32..00000000 --- a/WDL/circbuf.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - WDL - circbuf.h - Copyright (C) 2005 Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple class for a circular FIFO queue of bytes. It - has a strong advantage over WDL_Queue with large buffers, as it does far - fewer memcpy()'s. - -*/ - -#ifndef _WDL_CIRCBUF_H_ -#define _WDL_CIRCBUF_H_ - -#include "heapbuf.h" - -class WDL_CircBuf -{ -public: - WDL_CircBuf() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_CircBuf")) - { - m_size = 0; - m_inbuf = 0; - m_head = m_tail = 0; - } - ~WDL_CircBuf() - { - } - void SetSize(int size, bool keepcontents=false) - { - WDL_HeapBuf tmp(4096 WDL_HEAPBUF_TRACEPARM("WDL_CircBuf/TEMP")); - if (keepcontents) - { - int ms=NbInBuf(); - if (ms>size) ms=size; - if (ms>0) Get(tmp.Resize(ms),ms); - } - m_size = size; - m_hb.Resize(size); - Reset(); - if (tmp.GetSize()) Add(tmp.Get(),tmp.GetSize()); // add old data back in - } - void Reset() - { - m_head = (char *)m_hb.Get(); - m_tail = (char *)m_hb.Get(); - m_endbuf = (char *)m_hb.Get() + m_size; - m_inbuf = 0; - } - int Add(const void *buf, int l) - { - char *p = (char *)buf; - if (l > m_size) l = m_size; - int put = l; - int l2; - if (!m_size) return 0; - l2 = m_endbuf - m_head; - if (l2 <= l) - { - memcpy(m_head, p, l2); - m_head = (char *)m_hb.Get(); - p += l2; - l -= l2; - } - if (l) - { - memcpy(m_head, p, l); - m_head += l; - p += l; - } - m_inbuf += put; - if (m_inbuf > m_size) m_inbuf = m_size; - return put; - } - int Get(void *buf, int l) - { - char *p = (char *)buf; - int got = 0; - if (!m_size) return 0; - if (m_inbuf <= 0) return 0; - if (l > m_inbuf) l = m_inbuf; - m_inbuf -= l; - got = l; - if (m_tail+l >= m_endbuf) - { - int l1 = m_endbuf - m_tail; - l -= l1; - memcpy(p, m_tail, l1); - m_tail = (char *)m_hb.Get(); - p += l1; - memcpy(p, m_tail, l); - m_tail += l; - } - else - { - memcpy(p, m_tail, l); - m_tail += l; - } - return got; - } - int Available() { return m_size - m_inbuf; } - int NbInBuf() { return m_inbuf; } - -private: - WDL_HeapBuf m_hb; - char *m_head, *m_tail, *m_endbuf; - int m_size, m_inbuf; -} WDL_FIXALIGN; - - -template -class WDL_TypedCircBuf -{ -public: - - WDL_TypedCircBuf() {} - ~WDL_TypedCircBuf() {} - - void SetSize(int size, bool keepcontents = false) - { - mBuf.SetSize(size * sizeof(T), keepcontents); - } - - void Reset() - { - mBuf.Reset(); - } - - int Add(const T* buf, int l) - { - return mBuf.Add(buf, l * sizeof(T)) / sizeof(T); - } - - int Get(T* buf, int l) - { - return mBuf.Get(buf, l * sizeof(T)) / sizeof(T); - } - - int Available() - { - return mBuf.Available() / sizeof(T); - } - int NbInBuf() - { - return mBuf.NbInBuf() / sizeof(T); - } - -private: - WDL_CircBuf mBuf; -} WDL_FIXALIGN; - -#endif diff --git a/WDL/cmath/bessel_polynomial.h b/WDL/cmath/bessel_polynomial.h deleted file mode 100644 index 030d32b0..00000000 --- a/WDL/cmath/bessel_polynomial.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - bessel_polynomial.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - algorithm to calculate coefficients for a bessel polynomial from krall & fink - series. -*/ - -#ifndef _BESSEL_POLYNOMIAL_H_ -#define _BESSEL_POLYNOMIAL_H_ - -#include "custom_math.h" -#include "factorial.h" - -#ifdef _BESSEL_USE_INLINE_ - #define _BESSEL_INLINE _CMATH_INLINE -#else - #define _BESSEL_INLINE -#endif - -#ifndef _CMATH_ANSI - #define _BESSEL_MAX_ORDER 10 -#else - #define _BESSEL_MAX_ORDER 3 -#endif - -/* return a coefficient */ -_BESSEL_INLINE cmath_std_int_t -bessel_coefficient(const cmath_uint16_t k, const cmath_uint16_t n) -{ - register cmath_std_int_t c; - const cmath_uint16_t nmk = (cmath_uint16_t)(n - k); - c = factorial(2*n - k); - c /= (factorial(nmk)*factorial(k)) * (1 << nmk); - return c; -} - -/* calculate all coefficients for n-th order polynomial */ -_BESSEL_INLINE -void bessel_polynomial( cmath_std_int_t *coeff, - const cmath_uint16_t order, - const cmath_uint16_t reverse ) -{ - register cmath_uint16_t i = (cmath_uint16_t)(order + 1); - if (reverse) - { - while (i--) - coeff[order-i] = bessel_coefficient(i, order); - } - else - { - while (i--) - coeff[i] = bessel_coefficient(i, order); - } -} - -#endif /* _BESSEL_POLYNOMIAL_H */ diff --git a/WDL/cmath/complex_number.h b/WDL/cmath/complex_number.h deleted file mode 100644 index c5be1931..00000000 --- a/WDL/cmath/complex_number.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - complex_number.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - portable complex number operations -*/ - -#ifndef _COMPLEX_NUMBER_H_ -#define _COMPLEX_NUMBER_H_ - -#include "custom_math.h" - -/* settings */ -#ifndef _CNUM_NO_INLINE - #define _CNUM_INLINE _CMATH_INLINE -#else - #define _CNUM_INLINE -#endif - -#ifndef _CNUM_NO_ALIAS - #define _CNUM_ALIAS _CMATH_MAY_ALIAS -#else - #define _CNUM_ALIAS -#endif - -/* types & constants */ -#ifndef cnum_t - #define cnum_t cmath_t -#endif - -typedef struct -{ - cnum_t r _CMATH_ALIGN(8); - cnum_t i _CMATH_ALIGN(8); -} _CNUM_ALIAS cnum_s; - -const cnum_s cnum_zero = {0, 0}; -const cnum_s cnum_i1 = {0, 1}; -const cnum_s cnum_r1 = {1, 0}; -const cnum_s cnum_r2 = {2, 0}; - -/* methods */ -#define _CNUM(r, i) cnum_new(r, i) -#define _CNUMD(x, r, i) cnum_s x = {r, i} - -_CNUM_INLINE -cnum_s cnum_set(cnum_s *x, const cnum_t r, const cnum_t i) -{ - x->r = r; - x->i = i; - return *x; -} - -_CNUM_INLINE -cnum_s cnum_from(cnum_s *x, const cnum_s y) -{ - x->r = y.r; - x->i = y.i; - return *x; -} - -_CNUM_INLINE -cnum_s cnum_new(const cnum_t r, const cnum_t i) -{ - cnum_s x; - x.r = r; - x.i = i; - return x; -} - -_CNUM_INLINE -cnum_s cnum_cartesian(const cnum_s x) -{ - return cnum_new(x.r * cmath_cos(x.i), x.r * cmath_sin(x.i)); -} - -_CNUM_INLINE -cnum_s cnum_polar(const cnum_s x) -{ - return cnum_new(cmath_cabs(x.r, x.i), cmath_carg(x.r, x.i)); -} - -_CNUM_INLINE -cnum_s cnum_conjugate(const cnum_s x) -{ - return cnum_new(x.r, -x.i); -} - -_CNUM_INLINE -cnum_s cnum_negative(const cnum_s x) -{ - return cnum_new(-x.r, -x.i); -} - -_CNUM_INLINE -cnum_s cnum_swap(const cnum_s x) -{ - return cnum_new(x.i, x.r); -} - -_CNUM_INLINE -cnum_s cnum_add(const cnum_s x, const cnum_s y) -{ - return cnum_new(x.r + y.r, x.i + y.i); -} - -_CNUM_INLINE -cnum_s cnum_add_r(const cnum_s x, const cnum_t y) -{ - return cnum_new(x.r + y, x.i + y); -} - -_CNUM_INLINE -cnum_s cnum_sub(const cnum_s x, const cnum_s y) -{ - return cnum_new(x.r - y.r, x.i - y.i); -} - -_CNUM_INLINE -cnum_s cnum_sub_r(register cnum_s x, const cnum_t y) -{ - return cnum_new(x.r - y, x.i - y); -} - -_CNUM_INLINE -cnum_s cnum_r_sub(const cnum_t x, register cnum_s y) -{ - return cnum_new(x - y.r, x - y.i); -} - -_CNUM_INLINE -cnum_s cnum_mul(const cnum_s x, const cnum_s y) -{ - return cnum_new(x.r*y.r - x.i*y.i, x.r*y.i + x.i*y.r); -} - -_CNUM_INLINE -cnum_s cnum_mul_r(const cnum_s x, const cnum_t y) -{ - return cnum_new(x.r*y, x.i*y); -} - -#define cnum_sqr(x) \ - cnum_mul(x, x) - -_CNUM_INLINE -cnum_s cnum_div_r(const cnum_s x, const cnum_t y) -{ - return cnum_new(x.r/y, x.i/y); -} - -_CNUM_INLINE -cnum_s cnum_r_div(const cnum_t x, const cnum_s y) -{ - return cnum_new(x/y.r, x/y.i); -} - -_CNUM_INLINE -cnum_s cnum_div(const cnum_s x, const cnum_s y) -{ - return cnum_div_r(cnum_mul(x, cnum_conjugate(y)), - (y.r*y.r + cmath_abs(y.i*y.i))); -} - -#define cnum_inv(x) \ - cnum_div(cnum_r1, x) - -#define _CNUM_CHECK_EXP_D_ \ - cmath_abs(deg - cmath_round(deg)) == 0 - -_CNUM_INLINE -cnum_s cnum_exp(const cnum_s x) -{ - cnum_t sin_i = cmath_sin(x.i); - cnum_t cos_i = cmath_cos(x.i); - const cnum_t exp_r = cmath_exp(x.r); - - #ifndef _CNUM_NO_CHECK_EXP_ - register cnum_t deg; - - if (x.r == 0) - return cnum_zero; - deg = x.i / cmath_pi; - if (_CNUM_CHECK_EXP_D_) - sin_i = 0; - deg += 0.5; - if (_CNUM_CHECK_EXP_D_) - cos_i = 0; - deg = x.i / cmath_pi2; - if (_CNUM_CHECK_EXP_D_) - cos_i = 1; - #endif - - return cnum_new(exp_r*cos_i, exp_r*sin_i); -} - -_CNUM_INLINE -cnum_s cnum_log_k(const cnum_s x, const cmath_int32_t k) -{ - return cnum_new(cmath_log(cmath_cabs(x.r, x.i)), - (cmath_carg(x.r, x.i) + (cmath_pi2*k))); -} - -#define cnum_log(x) \ - cnum_log_k(x, 0) - -#define cnum_log_b_k(x, b, k) \ - cnum_div(cnum_log_k(x, k), cnum_log_k(b, k)) - -#define cnum_log_b(b, x) \ - cnum_div(cnum_log(x), cnum_log(b)) - -#define cnum_log2(x) \ - cnum_log_b(x, 2) - -#define cnum_log2_k(x, k) \ - cnum_log_b_k(x, 2, k) - -#define cnum_log10(x) \ - cnum_log_b(x, 2) - -#define cnum_log10_k(x, k) \ - cnum_log_b_k(x, 10, k) - -#define _CNUM_CHECK_POW_C_ \ - if (x.r == 0 && x.i == 0) \ - return cnum_zero; \ - if (y.r == 0 && y.i == 0) \ - return cnum_r1 \ - -_CNUM_INLINE -cnum_s cnum_pow_c_k(const cnum_s x, const cnum_s y, const cmath_int32_t k) -{ - _CNUM_CHECK_POW_C_; - return cnum_exp(cnum_mul(cnum_log_k(x, k), y)); -} - -_CNUM_INLINE -cnum_s cnum_pow_c(const cnum_s x, const cnum_s y) -{ - _CNUM_CHECK_POW_C_; - return cnum_exp(cnum_mul(cnum_log(x), y)); -} - -_CNUM_INLINE -cnum_s cnum_pow(const cnum_s x, const cnum_t n) -{ - const cnum_t r_pow_n = cmath_pow(cmath_cabs(x.r, x.i), n); - const cnum_t theta_n = cmath_carg(x.r, x.i) * n; - if (n == 0) - return cnum_new(1, 0); - if (n == 1) - return x; - return cnum_new(r_pow_n * cmath_cos(theta_n), r_pow_n * cmath_sin(theta_n)); -} - -#define cnum_root_c_k(x, y, k) \ - cnum_exp(cnum_div(cnum_log_k(x, k), y)) - -#define cnum_root_c(x, y) \ - cnum_exp(cnum_div(cnum_log(x), y)) - -#define cnum_root(x, n) \ - cnum_pow(x, 1/n) - -#define cnum_sqrt(x) \ - cnum_pow(x, 0.5) - -#define cnum_sin(x) \ - cnum_new(cmath_sin((x).r)*cmath_cosh((x).i), \ - cmath_cos((x).r)*cmath_sinh((x).i)) - -#define cnum_sinh(x) \ - cnum_new(cmath_sinh(x.r)*cmath_cos(x.i), cmath_cosh(x.r)*sin(x.i)) - -#define cnum_cos(x) \ - cnum_new(cmath_cos(x.r)*cmath_cosh(x.i), -cmath_sin(x.r)*cmath_sinh(x.i)) - -#define cnum_cosh(x) \ - cnum_new(cmath_cosh(x.r)*cmath_cos(x.i), cmath_sinh(x.r)*cmath_sin(x.i)) - -#define cnum_tan(x) \ - cnum_div(cnum_sin(x), cnum_cos(x)) - -#define cnum_tanh(x) \ - cnum_div(cnum_sinh(x), cnum_cosh(x)) - -#define cnum_csc(x) \ - cnum_inv(cnum_sin(x)) - -#define cnum_sec(x) \ - cnum_inv(cnum_cos(x)) - -#define cnum_cotan(x) \ - cnum_inv(cnum_tan(x)) - -#define cnum_asin(x) \ - cnum_negative(cnum_mul(cnum_i1, cnum_log(cnum_add(cnum_mul(cnum_i1, x), \ - cnum_sqrt(cnum_sub(cnum_r1, cnum_sqr(x))))))) - -#define cnum_acos(x) \ - cnum_negative(cnum_mul(cnum_i1, cnum_log(cnum_add(x, cnum_mul(cnum_i1, \ - cnum_sqrt(cnum_sub(cnum_r1, cnum_sqr(x)))))))) - -#define cnum_atan(x) \ - cnum_div(cnum_mul(cnum_i1, cnum_log(cnum_div(cnum_sub(cnum_r1, \ - cnum_mul(cnum_i1, x)), cnum_add(cnum_r1, cnum_mul(cnum_i1, x))))), cnum_r2) - -#define cnum_acsc(x) \ - cnum_asin(cnum_inv(x)) - -#define cnum_asec(x) \ - cnum_acos(cnum_inv(x)) - -#define cnum_acot(x) \ - cnum_atan(cnum_inv(x)) - -#define cnum_csch(x) \ - cnum_inv(cnum_sinh(x)) - -#define cnum_sech(x) \ - cnum_inv(cnum_cosh(x)) - -#define cnum_coth(x) \ - cnum_inv(cnum_tanh(x)) - -#define cnum_asinh(x) \ - cnum_log(cnum_add(x, cnum_sqrt(cnum_add(cnum_r1, cnum_sqr(x))))) - -#define cnum_acosh(x) \ - cnum_log(cnum_add(x, cnum_mul(cnum_sqrt(cnum_add(x, cnum_r1)), \ - cnum_sqrt(cnum_sub(x, cnum_r1))))) - -#define cnum_atanh(x) \ - cnum_div(cnum_sub(cnum_log(cnum_add(cnum_r1, x)), \ - cnum_log(cnum_sub(cnum_r1, x))), cnum_r2) - -#define cnum_acsch(x) \ - cnum_asinh(cnum_inv(x)) - -#define cnum_asech(x) \ - cnum_acosh(cnum_inv(x)) - -#define cnum_asech(x) \ - cnum_acosh(cnum_inv(x)) - -#define cnum_acoth(x) \ - cnum_atanh(cnum_inv(x)) - -#endif /* _COMPLEX_NUMBER_H_ */ diff --git a/WDL/cmath/custom_math.h b/WDL/cmath/custom_math.h deleted file mode 100644 index a624b3a2..00000000 --- a/WDL/cmath/custom_math.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - custom_math.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - portable definitions for ansi c and cross compiler compatibility. - contains: numeric constants, custom math functions, macros & other. -*/ - -#ifndef _CUSTOM_MATH_H_ -#define _CUSTOM_MATH_H_ - -#include "math.h" - -/* check for "c89" mode */ -#if (defined _MSC_VER && defined __STDC__) || \ - (defined __GNUC__ && defined __STRICT_ANSI__) - #define _CMATH_ANSI -#endif - -/* enable inline */ -#if defined __cplusplus || (!defined _CMATH_ANSI && defined _CMATH_USE_INLINE) - #ifdef _MSC_VER - #define _CMATH_INLINE __inline - #else - #define _CMATH_INLINE inline - #endif -#else - #define _CMATH_INLINE -#endif - -/* align type to size of type */ -#if defined __GNUC__ || defined __TINYC__ - #define _CMATH_ALIGN(x) __attribute__ ((aligned(x))) - #define _CMATH_ALIGN_T(x) __attribute__ ((aligned(sizeof(x)))) -#else - #define _CMATH_ALIGN(x) - #define _CMATH_ALIGN_T(x) -#endif - -/* printf max integer */ -#ifndef _CMATH_ANSI - #ifdef _WIN32 - #define _CMATH_PR_STD_UINT "I64u" - #define _CMATH_PR_STD_INT "I64i" - #define _CMATH_PR_STD_HEX "I64x" - #else - #define _CMATH_PR_STD_UINT "llu" - #define _CMATH_PR_STD_INT "lli" - #define _CMATH_PR_STD_HEX "llx" - #endif -#else - #define _CMATH_PR_STD_UINT "u" - #define _CMATH_PR_STD_INT "d" - #define _CMATH_PR_STD_HEX "x" -#endif - -/* msvc specifics */ -#ifdef _MSC_VER - #pragma warning(disable : 4514) - - #define MK_L(x) (x) - #define MK_UL(x) (x) - #define MK_LL(x) (x) - #define MK_ULL(x) (x) -#else - #define MK_L(x) (x##L) - #define MK_UL(x) (x##UL) - #ifdef _CMATH_ANSI - #define MK_LL(x) (x##L) - #define MK_ULL(x) (x##UL) - #else - #define MK_LL(x) (x##LL) - #define MK_ULL(x) (x##ULL) - #endif -#endif - -/* definitions depending on c standard */ -#ifdef _CMATH_ANSI - #define cmath_std_signbit MK_UL(0x7fffffff) - #define cmath_std_float_t float - #define cmath_std_int_t int -#else - #define cmath_std_signbit MK_ULL(0x7fffffffffffffff) - #define cmath_std_float_t double - #ifdef _MSC_VER - #define cmath_std_int_t __int64 - #else - #define cmath_std_int_t long long - #endif -#endif - -/* types and constants */ -#ifndef cmath_t - #define cmath_t double -#endif - -#define cmath_std_uint_t unsigned cmath_std_int_t - -#define cmath_pi 3.1415926535897932384626433832795 -#define cmath_pi2 6.2831853071795864769252867665590 -#define cmath_pi_2 1.5707963267948966192313216916398 -#define cmath_e 2.7182818284590452353602874713526 -#define cmath_sqrt2 1.4142135623730950488016887242097 -#define cmath_pi_180 0.0174532925199432957692369076848 -#define cmath_180_pi 57.295779513082320876798154814105 - -#define cmath_int8_t char -#define cmath_uint8_t unsigned char -#define cmath_int16_t short -#define cmath_uint16_t unsigned short -#define cmath_int32_t int -#define cmath_uint32_t unsigned int - -/* aliased types */ -#ifdef __GNUC__ - #define _CMATH_MAY_ALIAS __attribute__((__may_alias__)) -#else - #define _CMATH_MAY_ALIAS -#endif - -typedef cmath_t _CMATH_MAY_ALIAS cmath_t_a; - -/* possible approximations */ -#define cmath_sin sin -#define cmath_cos cos -#define cmath_tan tan -#define cmath_asin asin -#define cmath_acos acos -#define cmath_atan atan -#define cmath_atan2 atan2 -#define cmath_sinh sinh -#define cmath_cosh cosh -#define cmath_tanh tanh -#define cmath_exp exp -#define cmath_pow pow -#define cmath_sqrt sqrt -#define cmath_log log -#define cmath_log2 log2 -#define cmath_log10 log10 - -/* methods */ -#define cmath_array_size(x) \ - (sizeof(x) / sizeof(*(x))) - -#define poly_order(x) \ - (sizeof(x) / sizeof(*(x)) - 1) - -#define cmath_cabs(a, b) \ - cmath_sqrt((a)*(a) + (b)*(b)) - -#define cmath_carg(a, b) \ - cmath_atan2((b), (a)) - -#define cmath_radians(x) \ - ((x)*cmath_pi_180) - -#define cmath_degrees(x) \ - ((x)*cmath_180_pi) - -_CMATH_INLINE -cmath_t cmath_powi(const cmath_t x, register cmath_uint16_t n) -{ - register cmath_t result = 1; - while (n--) - result *= x; - return result; -} - -_CMATH_INLINE -cmath_t cmath_abs(const cmath_t x) -{ - register union - { - cmath_std_int_t i; - cmath_std_float_t j; - } u; - u.j = (cmath_std_float_t)x; - u.i &= cmath_std_signbit; - return u.j; -} - -_CMATH_INLINE -cmath_t cmath_round(const cmath_t x) -{ - if (x < 0.0) - return (cmath_t)(cmath_std_int_t)(x - 0.5); - else - return (cmath_t)(cmath_std_int_t)(x + 0.5); -} - -#endif /* _CUSTOM_MATH_H_ */ diff --git a/WDL/cmath/durand_kerner.h b/WDL/cmath/durand_kerner.h deleted file mode 100644 index 36572fce..00000000 --- a/WDL/cmath/durand_kerner.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - durand_kerner.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - durand-kerner (weierstrass) algorithm for finding complex roots - of polynomials. - accuracy depends a lot on data type precision. -*/ - -#ifndef _DURAND_KERNER_H_ -#define _DURAND_KERNER_H_ - -#include "horner.h" -#include "custom_math.h" -#include "complex_number.h" - -/* settings */ -#ifdef _DURAND_KERNER_USE_INLINE_ - #define _DURAND_KERNER_INLINE _CMATH_INLINE -#else - #define _DURAND_KERNER_INLINE -#endif - -#define DK_EPSILON 1E-16 -#define DK_MAX_ITR 1E+3 -#define DK_MAX_N 256 - -const cnum_s dk_demoivre_c = {0.4, 0.9}; - -/* accepts an array of complex numbers */ -_DURAND_KERNER_INLINE -void durand_kerner_c -(const cnum_s *coeff, cnum_s *roots, const cmath_uint16_t order) -{ - register cmath_uint16_t i, j; - register cmath_uint32_t itr; - cnum_s coeff_sc[DK_MAX_N]; - cnum_s x; - cnum_s hor; /* needs an address or breaks g++ 4.x */ - - i = 0; - while(i < order) - { - cnum_from(&roots[i], cnum_pow(dk_demoivre_c, i)); - i++; - } - - cnum_from(&coeff_sc[0], cnum_r1); - i = 1; - while(i < order+1) - { - cnum_from(&coeff_sc[i], cnum_div(coeff[i], coeff[0])); - i++; - } - - itr = 0; - while(itr < DK_MAX_ITR) - { - i = 0; - while(i < order) - { - j = 0; - x = cnum_r1; - while (j < order) - { - if (i != j) - x = cnum_mul(cnum_sub(roots[i], roots[j]), x); - j++; - } - hor = horner_eval_c(coeff_sc, roots[i], order); - x = cnum_div(hor, x); - x = cnum_sub(roots[i], x); - if (cmath_abs(cmath_abs(x.r) - cmath_abs(roots[i].r)) < DK_EPSILON && - cmath_abs(cmath_abs(x.i) - cmath_abs(roots[i].i)) < DK_EPSILON) - return; - cnum_from(&roots[i], x); - i++; - } - itr++; - } -} - -/* accepts an array of real numbers */ -_DURAND_KERNER_INLINE -void durand_kerner -(const cmath_t *coeff, cnum_s *roots, const cmath_uint16_t order) -{ - register cmath_uint16_t i; - cnum_s coeff_c[DK_MAX_N]; - i = 0; - while(i < (order+1)) - { - cnum_set(&coeff_c[i], coeff[i], 0); - i++; - } - durand_kerner_c(coeff_c, roots, order); -} - -#endif /* _DURAND_KERNER_H_ */ diff --git a/WDL/cmath/factorial.h b/WDL/cmath/factorial.h deleted file mode 100644 index f19803da..00000000 --- a/WDL/cmath/factorial.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - factorial.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - methods to return low-order factorials depending on allowed data types. - - 20! = 2432902008176640000 is the maximum factorial to be held - in a unsigned 64bit integer. - 13! = 479001600 is the maximum factorial to be held in a unsigned - 32bit integer. -*/ - -#ifndef _FACTORIAL_H_ -#define _FACTORIAL_H_ - -#include "custom_math.h" - -#define FACTORIAL_LOWER \ - MK_ULL(1), \ - MK_ULL(1), \ - MK_ULL(2), \ - MK_ULL(6), \ - MK_ULL(24), \ - MK_ULL(120), \ - MK_ULL(720), \ - MK_ULL(5040), \ - MK_ULL(40320), \ - MK_ULL(362880), \ - MK_ULL(3628800), \ - MK_ULL(39916800), \ - MK_ULL(479001600) - -#define FACTORIAL_HIGHER \ - MK_ULL(6227020800), \ - MK_ULL(87178291200), \ - MK_ULL(1307674368000), \ - MK_ULL(20922789888000), \ - MK_ULL(355687428096000), \ - MK_ULL(6402373705728000), \ - MK_ULL(121645100408832000), \ - MK_ULL(2432902008176640000) - -static const cmath_std_uint_t _factorials[] = -{ - #ifdef _CMATH_ANSI - FACTORIAL_LOWER - #else - FACTORIAL_LOWER, - FACTORIAL_HIGHER - #endif -}; - -static const cmath_t _inv_factorials[] = -{ - 1.00000000000000000000000000000000, - 1.00000000000000000000000000000000, - 0.50000000000000000000000000000000, - 0.16666666666666666666666666666667, - 0.04166666666666666666666666666666, - 0.00833333333333333333333333333333, - 0.00138888888888888888888888888888, - 0.00019841269841269841269841269841, - 0.00002480158730158730158730158730, - 0.00000275573192239858906525573192, - 0.00000027557319223985890652557319, - 0.00000002505210838544171877505210, - 0.00000000208767569878680989792100, - 0.00000000016059043836821614599390, - 0.00000000001147074559772972471385, - 0.00000000000076471637318198164750, - 0.00000000000004779477332387385297, - 0.00000000000000281145725434552076, - 0.00000000000000015619206968586225, - 0.00000000000000000822063524662433, - 0.00000000000000000041103176233122 -}; - -_CMATH_INLINE -cmath_std_uint_t factorial(const cmath_uint32_t x) -{ - if(x >= cmath_array_size(_factorials)) - return 0; - else - return _factorials[x]; -} - -_CMATH_INLINE -cmath_t inv_factorial(const cmath_uint32_t x) -{ - if(x >= cmath_array_size(_inv_factorials)) - return 0; - else - return _inv_factorials[x]; -} - -#endif /* _FACTORIAL_H_ */ diff --git a/WDL/cmath/horner.h b/WDL/cmath/horner.h deleted file mode 100644 index d943457f..00000000 --- a/WDL/cmath/horner.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - horner.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - algorithm to evaluate integer order polynomials using horner's scheme. -*/ - -#ifndef _HORNER_H_ -#define _HORNER_H_ - -#include "custom_math.h" -#include "complex_number.h" - -/* settings */ -#ifndef _HORNER_INLINE - #define _HORNER_INLINE _CMATH_INLINE -#else - #define _HORNER_INLINE -#endif - -/* real */ -_HORNER_INLINE -cmath_t horner_eval -(const cmath_t *coeff, const cmath_t x, cmath_uint16_t order) -{ - register cmath_t y = coeff[0]; - register cmath_uint16_t n = 1; - order += 1; - while(n < order) - { - y = y*x + coeff[n]; - n++; - } - return y; -} - -/* complex */ -_HORNER_INLINE -cnum_s horner_eval_c -(const cnum_s *coeff, const cnum_s x, cmath_uint16_t order) -{ - register cmath_uint16_t n = 1; - cnum_s y = coeff[0]; - order += 1; - while(n < order) - { - y = cnum_add(cnum_mul(y, x), coeff[n]); - n++; - } - return y; -} - -#endif /* _HORNER_H_ */ diff --git a/WDL/cmath/test_bessel.c b/WDL/cmath/test_bessel.c deleted file mode 100644 index 83915a6c..00000000 --- a/WDL/cmath/test_bessel.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - test_bessel.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - test bessel_polynomial.h and other related headers - - gcc -W -Wall -Wextra -ansi pedantic - cl /W4 /Za - - reduced precisions for ansi c -*/ - -#include "stdio.h" -#include "custom_math.h" -#include "bessel_polynomial.h" -#include "durand_kerner.h" - -int main(void) -{ - register cmath_uint16_t i = 0; - register cmath_int16_t diff = 0; - - cmath_uint32_t in_order = _BESSEL_MAX_ORDER + 1; - cmath_uint16_t order; - const cmath_uint16_t reverse = 1; - - cmath_std_int_t coeff[_BESSEL_MAX_ORDER + 1]; - - cnum_t dk_coeff[_BESSEL_MAX_ORDER + 1]; - cnum_s dk_roots[_BESSEL_MAX_ORDER]; - - /* */ - #ifdef _CMATH_ANSI - puts("\n\nansi c is: on"); - #else - puts("\n\nansi c is: off"); - #endif - - /* */ - while (in_order > _BESSEL_MAX_ORDER) - { - printf("\nenter order of bessel polynomial (0 - %d): ", _BESSEL_MAX_ORDER); - scanf("%u", &in_order); - } - - order = (cmath_uint16_t)in_order; - bessel_polynomial(coeff, order, reverse); - - printf("\norder [N]: %d", order); - printf("\nreversed bessel: %d\n\n", reverse); - printf("list of coefficients:\n"); - while (i <= order) - { - printf("order[%2d]: ", (order - i)); - printf("%"_CMATH_PR_STD_INT"\n", coeff[i]); - i++; - } - puts("\npolynomial:"); - printf("y(x) = "); - - i = 0; - while (i <= order) - { - diff = (cmath_int16_t)(order - i); - if (diff > 0) - if (coeff[i] > 1) - { - printf("%"_CMATH_PR_STD_INT, coeff[i]); - if (diff > 1) - printf("*x^%d + ", diff); - else - printf("*x + "); - } - else - printf("x^%d + ", diff); - else - printf("%"_CMATH_PR_STD_INT"", coeff[i]); - i++; - } - - /* */ - puts("\n\nlist roots:"); - i = 0; - while (i < order+1) - { - dk_coeff[i] = (cnum_t)coeff[i]; - i++; - } - - durand_kerner(dk_coeff, dk_roots, order); - - i = 0; - while (i < order) - { - printf("root[%2d]: %.15f \t % .15f*i\n", - i+1, (double)dk_roots[i].r, (double)dk_roots[i].i); - i++; - } - - return 0; -} diff --git a/WDL/cmath/test_eval.c b/WDL/cmath/test_eval.c deleted file mode 100644 index fabf9ff1..00000000 --- a/WDL/cmath/test_eval.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - test_eval.h - Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - test horner.h for complex numbers and other related headers - - gcc -W -Wall -Wextra -ansi pedantic - cl /W4 /Za - - reduced precisions for ansi c -*/ - -#include "stdio.h" -#include "complex_number.h" -#include "horner.h" -#include "durand_kerner.h" - -int main(void) -{ - cmath_uint16_t i = 0; - - cnum_t y[] = {2, -6, 2, -1}; - cnum_s cy[] = {{2, 0}, {-6, 0}, {2, 0}, {-1, 0}}; - - cnum_t fx = horner_eval(y, 5, poly_order(y)); - cnum_s fcx = horner_eval_c(cy, _CNUM(5, 0), poly_order(y)); - - cnum_t dk_coeff[] = {12, -7, 0.001, 0, 3, -5}; - cnum_s dk_roots[5]; - - cnum_s dk_coeff_c[] = {{12, 0}, {-7, 0}, {0.001, 0}, {0, 0}, {3, 0}, {-5, 0}}; - cnum_s dk_roots_c[5]; - - durand_kerner(dk_coeff, dk_roots, poly_order(dk_coeff)); - durand_kerner_c(dk_coeff_c, dk_roots_c, poly_order(dk_coeff_c)); - - /* */ - #ifdef _CMATH_ANSI - puts("\n\nansi c is: on"); - #else - puts("\n\nansi c is: off"); - #endif - - /* */ - puts("\n\nevaluate polynomials:\n"); - printf("* y[]: %.15f\n", (double)fx); - printf("* cy[]: %.15f \t %.15f*i\n", (double)fcx.r, (double)fcx.i); - - /* */ - puts("\nfind roots:"); - puts("\n* dk_coeff[]:"); - i = 0; - while (i < poly_order(dk_coeff)) - { - printf("root[%2d]: %.15f \t % .15f*i\n", - i+1, (double)dk_roots[i].r, (double)dk_roots[i].i); - i++; - } - i = 0; - puts("\n* dk_coeff_c[]:"); - while (i < poly_order(dk_coeff_c)) - { - printf("root[%2d]: %.15f \t % .15f*i\n", - i+1, (double)dk_roots_c[i].r, (double)dk_roots_c[i].i); - i++; - } - - return 0; -} diff --git a/WDL/convoengine.cpp b/WDL/convoengine.cpp deleted file mode 100644 index 204ed35e..00000000 --- a/WDL/convoengine.cpp +++ /dev/null @@ -1,1057 +0,0 @@ -/* - WDL - convoengine.cpp - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -#ifdef _WIN32 -#include -#endif -#include -#include -#include -#include -#include "convoengine.h" - -#include "denormal.h" - -//#define TIMING -#include "timing.c" - -static void WDL_CONVO_CplxMul2(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_CONVO_IMPULSEBUFCPLXf *b, int n) -{ - WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - if (n<2 || (n&1)) return; - - do { - t1 = a[0].re * b[0].re; - t2 = a[0].im * b[0].im; - t3 = a[0].im * b[0].re; - t4 = a[0].re * b[0].im; - t5 = a[1].re * b[1].re; - t6 = a[1].im * b[1].im; - t7 = a[1].im * b[1].re; - t8 = a[1].re * b[1].im; - t1 -= t2; - t3 += t4; - t5 -= t6; - t7 += t8; - c[0].re = t1; - c[1].re = t5; - c[0].im = t3; - c[1].im = t7; - a += 2; - b += 2; - c += 2; - } while (n -= 2); -} -static void WDL_CONVO_CplxMul3(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_CONVO_IMPULSEBUFCPLXf *b, int n) -{ - WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - if (n<2 || (n&1)) return; - - do { - t1 = a[0].re * b[0].re; - t2 = a[0].im * b[0].im; - t3 = a[0].im * b[0].re; - t4 = a[0].re * b[0].im; - t5 = a[1].re * b[1].re; - t6 = a[1].im * b[1].im; - t7 = a[1].im * b[1].re; - t8 = a[1].re * b[1].im; - t1 -= t2; - t3 += t4; - t5 -= t6; - t7 += t8; - c[0].re += t1; - c[1].re += t5; - c[0].im += t3; - c[1].im += t7; - a += 2; - b += 2; - c += 2; - } while (n -= 2); -} - -static bool CompareQueueToBuf(WDL_FastQueue *q, const void *data, int len) -{ - int offs=0; - while (len>0) - { - void *td=NULL; - int sz=q->GetPtr(offs,&td); - if (sz<1) return true; // not enough data = not equal! - if (sz>len) sz=len; - - int i=sz/sizeof(WDL_FFT_REAL); - WDL_FFT_REAL *a1=(WDL_FFT_REAL*)td; - WDL_FFT_REAL *b1=(WDL_FFT_REAL*)data; - while (i--) - { - if (fabs(*a1-*b1)>1.0e-7) return true; - a1++; - b1++; - } - - data = ((char *)data)+sz; - offs+=sz; - len-=sz; - } - return false; -} - - -WDL_ConvolutionEngine::WDL_ConvolutionEngine() -{ - WDL_fft_init(); - m_impulse_nch=1; - m_fft_size=0; - m_impulse_len=0; - m_proc_nch=0; -} - -WDL_ConvolutionEngine::~WDL_ConvolutionEngine() -{ -} - -int WDL_ConvolutionEngine::SetImpulse(WDL_ImpulseBuffer *impulse, int fft_size, int impulse_sample_offset, int max_imp_size, bool forceBrute) -{ - int impulse_len=0; - int x; - int nch=impulse->GetNumChannels(); - for (x = 0; x < nch; x ++) - { - int l=impulse->impulses[x].GetSize()-impulse_sample_offset; - if (max_imp_size && l>max_imp_size) l=max_imp_size; - if (impulse_len < l) impulse_len=l; - } - m_impulse_nch=nch; - - if (m_impulse_nch>1) // detect mono signals pretending to be multichannel - { - for (x = 1; x < m_impulse_nch; x ++) - { - if (impulse->impulses[x].GetSize()!=impulse->impulses[0].GetSize()|| - memcmp(impulse->impulses[x].Get(),impulse->impulses[0].Get(), - impulse->impulses[0].GetSize()*sizeof(WDL_FFT_REAL))) - break; - } - if (x >= m_impulse_nch) m_impulse_nch=1; - } - - m_impulse_len=impulse_len; - m_proc_nch=-1; - - - if (forceBrute) - { - m_fft_size=0; - - // save impulse - for (x = 0; x < m_impulse_nch; x ++) - { - WDL_FFT_REAL *imp=impulse->impulses[x].Get()+impulse_sample_offset; - int lenout=impulse->impulses[x].GetSize()-impulse_sample_offset; - if (max_imp_size && lenout>max_imp_size) lenout=max_imp_size; - - WDL_CONVO_IMPULSEBUFf *impout=m_impulse[x].Resize(lenout)+lenout; - while (lenout-->0) *--impout = (WDL_CONVO_IMPULSEBUFf) *imp++; - } - - for (x = 0; x < WDL_CONVO_MAX_PROC_NCH; x ++) - { - m_samplesin[x].Clear(); - m_samplesin2[x].Clear(); - m_samplesout[x].Clear(); - } - - return 0; - } - - - if (fft_size<=0) - { - int msz=fft_size<=-16? -fft_size*2 : 32768; - - fft_size=32; - while (fft_size < impulse_len*2 && fft_size < msz) fft_size*=2; - } - - m_fft_size=fft_size; - - int impchunksize=fft_size/2; - int nblocks=(impulse_len+impchunksize-1)/impchunksize; - //char buf[512]; - //sprintf(buf,"il=%d, ffts=%d, cs=%d, nb=%d\n",impulse_len,fft_size,impchunksize,nblocks); - //OutputDebugString(buf); - - const bool smallerSizeMode=sizeof(WDL_CONVO_IMPULSEBUFf)!=sizeof(WDL_FFT_REAL); - - WDL_FFT_REAL scale=(WDL_FFT_REAL) (1.0/fft_size); - for (x = 0; x < m_impulse_nch; x ++) - { - WDL_FFT_REAL *imp=impulse->impulses[x].Get()+impulse_sample_offset; - - WDL_FFT_REAL *imp2=x < m_impulse_nch-1 ? impulse->impulses[x+1].Get()+impulse_sample_offset : NULL; - - WDL_CONVO_IMPULSEBUFf *impout=m_impulse[x].Resize((nblocks+!!smallerSizeMode)*fft_size*2); - char *zbuf=m_impulse_zflag[x].Resize(nblocks); - int lenout=impulse->impulses[x].GetSize()-impulse_sample_offset; - if (max_imp_size && lenout>max_imp_size) lenout=max_imp_size; - - int bl; - for (bl = 0; bl < nblocks; bl ++) - { - - int thissz=lenout; - if (thissz > impchunksize) thissz=impchunksize; - - lenout -= thissz; - int i=0; - WDL_FFT_REAL mv=0.0; - WDL_FFT_REAL mv2=0.0; - WDL_FFT_REAL *imptmp = (WDL_FFT_REAL *)impout; //-V615 - - for (; i < thissz; i ++) - { - WDL_FFT_REAL v=*imp++; - WDL_FFT_REAL v2=(WDL_FFT_REAL)fabs(v); - if (v2 > mv) mv=v2; - - imptmp[i*2]=denormal_filter_aggressive(v * scale); - - if (imp2) - { - v=*imp2++; - v2=(WDL_FFT_REAL)fabs(v); - if (v2>mv2) mv2=v2; - imptmp[i*2+1]=denormal_filter_aggressive(v*scale); - } - else imptmp[i*2+1]=0.0; - } - for (; i < fft_size; i ++) - { - imptmp[i*2]=0.0; - imptmp[i*2+1]=0.0; - } - if (mv>1.0e-14||mv2>1.0e-14) - { - *zbuf++=mv>1.0e-14 ? 2 : 1; // 1 means only second channel has content - WDL_fft((WDL_FFT_COMPLEX*)impout,fft_size,0); - - if (smallerSizeMode) - { - int x,n=fft_size*2; - for(x=0;x=m_impulse_nch) wch-=m_impulse_nch; - WDL_CONVO_IMPULSEBUFf *imp=m_impulse[wch].Get(); - int imp_len = m_impulse[wch].GetSize(); - - - if (imp_len>0) - { - if (m_samplesin2[ch].Available()mso) mso=so; - - if (x>=nch) - { - m_samplesin[x].Clear(); - m_samplesout[x].Clear(); - } - else - { - if (m_impulse_len<1||!nblocks) - { - if (m_samplesin[x].Available()) - { - int s=m_samplesin[x].Available(); - void *buf=m_samplesout[x].Add(NULL,s); - m_samplesin[x].GetToBuf(0,buf,s); - m_samplesin[x].Clear(); - } - } - - if (so < mso) - { - memset(m_samplesout[x].Add(NULL,mso-so),0,mso-so); - } - } - - int sz=0; - if (x=m_impulse_nch) srcc=m_impulse_nch-1; - - bool allow_mono_input_mode=true; - bool mono_impulse_mode=false; - - if (m_impulse_nch==1 && ch= sz && - m_samplesout[ch].Available() < want*(int)sizeof(WDL_FFT_REAL)) - { - int histpos; - if ((histpos=++m_hist_pos[ch]) >= nblocks) histpos=m_hist_pos[ch]=0; - - // get samples from input, to history - WDL_FFT_REAL *optr = m_samplehist[ch].Get()+histpos*m_fft_size*2; - - m_samplesin[ch].GetToBuf(0,optr+sz,in_needed*sizeof(WDL_FFT_REAL)); - m_samplesin[ch].Advance(in_needed*sizeof(WDL_FFT_REAL)); - - - bool mono_input_mode=false; - - bool nonzflag=false; - if (mono_impulse_mode) - { - if (++m_hist_pos[ch+1] >= nblocks) m_hist_pos[ch+1]=0; - m_samplesin[ch+1].GetToBuf(0,workbuf2,sz*sizeof(WDL_FFT_REAL)); - m_samplesin[ch+1].Advance(sz*sizeof(WDL_FFT_REAL)); - int i; - for (i = 0; i < sz; i ++) // unpack samples - { - WDL_FFT_REAL f = optr[i*2]=denormal_filter_aggressive(optr[sz+i]); - if (!nonzflag && (f<-1.0e-6 || f>1.0e-6)) nonzflag=true; - f=optr[i*2+1]=denormal_filter_aggressive(workbuf2[i]); - if (!nonzflag && (f<-1.0e-6 || f>1.0e-6)) nonzflag=true; - } - } - else - { - if (allow_mono_input_mode && - ch < m_proc_nch-1 && - srcc1.0e-6)) nonzflag=true; - } - } - - int i; - for (i = 1; mono_input_mode && i < nblocks; i ++) // start @ 1, since hist[histpos] is no longer used for here - { - int srchistpos = histpos-i; - if (srchistpos < 0) srchistpos += nblocks; - if (useSilentList[srchistpos]==2) mono_input_mode=false; - } - - if (nonzflag||!useSilentList) memset(optr+sz*2,0,sz*2*sizeof(WDL_FFT_REAL)); - - -#ifdef WDLCONVO_ZL_ACCOUNTING - m_zl_fftcnt++; -#endif - - if (nonzflag) WDL_fft((WDL_FFT_COMPLEX*)optr,m_fft_size,0); - - if (useSilentList) useSilentList[histpos]=nonzflag ? (mono_input_mode ? 1 : 2) : 0; - - int mzfl=2; - if (mono_input_mode) - { - mzfl=1; - - m_samplesin[ch+1].Advance(sz*sizeof(WDL_FFT_REAL)); - - // save a valid copy in sample hist incase we switch from mono to stereo - if (++m_hist_pos[ch+1] >= nblocks) m_hist_pos[ch+1]=0; - WDL_FFT_REAL *optr2 = m_samplehist[ch+1].Get()+m_hist_pos[ch+1]*m_fft_size*2; - memcpy(optr2,optr,m_fft_size*2*sizeof(WDL_FFT_REAL)); - } - - int applycnt=0; - char *useImpSilentList=m_impulse_zflag[srcc].GetSize() == nblocks ? m_impulse_zflag[srcc].Get() : NULL; - - WDL_CONVO_IMPULSEBUFf *impulseptr=m_impulse[srcc].Get(); - for (i = 0; i < nblocks; i ++, impulseptr+=m_fft_size*2) - { - int srchistpos = histpos-i; - if (srchistpos < 0) srchistpos += nblocks; - - if (useImpSilentList && useImpSilentList[i]32768) maxfft_size=32768; - - - const int MAX_SIZE_FOR_BRUTE=64; - - int fftsize = MAX_SIZE_FOR_BRUTE; - int impulsechunksize = MAX_SIZE_FOR_BRUTE; - - if (known_blocksize && !(known_blocksize&(known_blocksize-1)) && known_blocksize>MAX_SIZE_FOR_BRUTE*2) - { - fftsize=known_blocksize/2; - impulsechunksize=known_blocksize/2; - } - if (latency_allowed*2 > fftsize) - { - int x = 16; - while (x <= latency_allowed) x*=2; - if (x>32768) x=32768; - fftsize=impulsechunksize=x; - } - - int offs=0; - int samplesleft=impulse->impulses[0].GetSize()-impulse_offset; - if (max_imp_size>0 && samplesleft>max_imp_size) samplesleft=max_imp_size; - - do - { - WDL_ConvolutionEngine *eng=new WDL_ConvolutionEngine; - - bool wantBrute = !latency_allowed && !offs; - if (impulsechunksize*(wantBrute ? 2 : 3) >= samplesleft) impulsechunksize=samplesleft; // early-out, no point going to a larger FFT (since if we did this, we wouldnt have enough samples for a complete next pass) - if (fftsize>=maxfft_size) { impulsechunksize=samplesleft; fftsize=maxfft_size; } // if FFTs are as large as possible, finish up - - eng->SetImpulse(impulse,fftsize,offs+impulse_offset,impulsechunksize, wantBrute); - eng->m_zl_delaypos = offs; - eng->m_zl_dumpage=0; - m_engines.Add(eng); - -#ifdef WDLCONVO_ZL_ACCOUNTING - char buf[512]; - wsprintf(buf,"ce%d: offs=%d, len=%d, fftsize=%d\n",m_engines.GetSize(),offs,impulsechunksize,fftsize); - OutputDebugString(buf); -#endif - - samplesleft -= impulsechunksize; - offs+=impulsechunksize; - -#if 1 // this seems about 10% faster (maybe due to better cache use from less sized ffts used?) - impulsechunksize=offs*3; - fftsize=offs*2; -#else - impulsechunksize=fftsize; - - fftsize*=2; -#endif - } - while (samplesleft > 0); - - return GetLatency(); -} - -int WDL_ConvolutionEngine_Div::GetLatency() -{ - return m_engines.GetSize() ? m_engines.Get(0)->GetLatency() : 0; -} - - -void WDL_ConvolutionEngine_Div::Reset() -{ - int x; - for (x = 0; x < m_engines.GetSize(); x ++) - { - WDL_ConvolutionEngine *eng=m_engines.Get(x); - eng->Reset(); - } - for (x = 0; x < WDL_CONVO_MAX_PROC_NCH; x ++) - { - m_samplesout[x].Clear(); - } - - m_need_feedsilence=true; -} - -WDL_ConvolutionEngine_Div::~WDL_ConvolutionEngine_Div() -{ - timingPrint(); - m_engines.Empty(true); -} - -void WDL_ConvolutionEngine_Div::Add(WDL_FFT_REAL **bufs, int len, int nch) -{ - m_proc_nch=nch; - - bool ns=m_need_feedsilence; - m_need_feedsilence=false; - - int x; - for (x = 0; x < m_engines.GetSize(); x ++) - { - WDL_ConvolutionEngine *eng=m_engines.Get(x); - if (ns) - { - eng->m_zl_dumpage = (x>0 && x < m_engines.GetSize()-1) ? (eng->GetLatency()/4) : 0; // reduce max number of ffts per block by staggering them - - if (eng->m_zl_dumpage>0) - eng->Add(NULL,eng->m_zl_dumpage,nch); // added silence to input (to control when fft happens) - } - - eng->Add(bufs,len,nch); - - if (ns) eng->AddSilenceToOutput(eng->m_zl_delaypos,nch); // add silence to output (to delay output to its correct time) - - } -} -WDL_FFT_REAL **WDL_ConvolutionEngine_Div::Get() -{ - int x; - for (x = 0; x < m_proc_nch; x ++) - { - m_get_tmpptrs[x]=(WDL_FFT_REAL *)m_samplesout[x].Get(); - } - return m_get_tmpptrs; -} - -void WDL_ConvolutionEngine_Div::Advance(int len) -{ - int x; - for (x = 0; x < m_proc_nch; x ++) - { - m_samplesout[x].Advance(len*sizeof(WDL_FFT_REAL)); - m_samplesout[x].Compact(); - } -} - -int WDL_ConvolutionEngine_Div::Avail(int wantSamples) -{ - timingEnter(1); - int wso=wantSamples; - int x; -#ifdef WDLCONVO_ZL_ACCOUNTING - int cnt=0; - static int maxcnt=-1; - int h=0; -#endif - for (x = 0; x < m_engines.GetSize(); x ++) - { - WDL_ConvolutionEngine *eng=m_engines.Get(x); -#ifdef WDLCONVO_ZL_ACCOUNTING - eng->m_zl_fftcnt=0; -#endif - int a=eng->Avail(wso+eng->m_zl_dumpage) - eng->m_zl_dumpage; -#ifdef WDLCONVO_ZL_ACCOUNTING - cnt += !!eng->m_zl_fftcnt; - -#if 0 - if (eng->m_zl_fftcnt) - h|=1<m_zl_fftcnt && x==m_engines.GetSize()-1 && cnt>1) - { - char buf[512]; - wsprintf(buf,"fft flags=%08x (%08x=max)\n",h,1<maxcnt)maxcnt=cnt; - if (GetTickCount()>lastt+1000) - { - lastt=GetTickCount(); - char buf[512]; - wsprintf(buf,"maxcnt=%d\n",maxcnt); - OutputDebugString(buf); - maxcnt=-1; - } -#endif - if (wantSamples>0) - { - WDL_FFT_REAL *tp[WDL_CONVO_MAX_PROC_NCH]; - for (x =0; x < m_proc_nch; x ++) - { - memset(tp[x]=(WDL_FFT_REAL*)m_samplesout[x].Add(NULL,wantSamples*sizeof(WDL_FFT_REAL)),0,wantSamples*sizeof(WDL_FFT_REAL)); - } - - for (x = 0; x < m_engines.GetSize(); x ++) - { - WDL_ConvolutionEngine *eng=m_engines.Get(x); - if (eng->m_zl_dumpage>0) { eng->Advance(eng->m_zl_dumpage); eng->m_zl_dumpage=0; } - - WDL_FFT_REAL **p=eng->Get(); - if (p) - { - int i; - for (i =0; i < m_proc_nch; i ++) - { - WDL_FFT_REAL *o=tp[i]; - WDL_FFT_REAL *in=p[i]; - int j=wantSamples; - while (j-->0) *o++ += *in++; - } - } - eng->Advance(wantSamples); - } - } - timingLeave(1); - - int av=m_samplesout[0].Available()/sizeof(WDL_FFT_REAL); - return av>wso ? wso : av; -} - - -#ifdef WDL_TEST_CONVO - -#include - -int main(int argc, char **argv) -{ - if (argc!=5) - { - printf("usage: convoengine fftsize implen oneoffs pingoffs\n"); - return -1; - } - - int fftsize=atoi(argv[1]); - int implen = atoi(argv[2]); - int oneoffs = atoi(argv[3]); - int pingoffs=atoi(argv[4]); - - if (implen < 1 || oneoffs < 0 || oneoffs >= implen || pingoffs < 0) - { - printf("invalid parameters\n"); - return -1; - } - - WDL_ImpulseBuffer imp; - imp.nch=1; - memset(imp.impulses[0].Resize(implen),0,implen*sizeof(WDL_FFT_REAL)); - imp.impulses[0].Get()[oneoffs]=1.0; - - -#if WDL_TEST_CONVO==2 - WDL_ConvolutionEngine_Div engine; -#else - WDL_ConvolutionEngine engine; -#endif - engine.SetImpulse(&imp,fftsize); - WDL_TypedBuf m_tmpbuf; - memset(m_tmpbuf.Resize(pingoffs+1),0,pingoffs*sizeof(WDL_FFT_REAL)); - m_tmpbuf.Get()[pingoffs]=1.0; - WDL_FFT_REAL *p=m_tmpbuf.Get(); - engine.Add(&p,pingoffs+1,1); - - p=m_tmpbuf.Resize(4096); - memset(p,0,m_tmpbuf.GetSize()*sizeof(WDL_FFT_REAL)); - - int avail; - while ((avail=engine.Avail(pingoffs+oneoffs + 8192)) < pingoffs+oneoffs + 8192) - { - engine.Add(&p,4096,1); - } - WDL_FFT_REAL **output = engine.Get(); - if (!output || !*output) - { - printf("cant get output\n"); - return -1; - } - int x; - for (x = 0; x < avail; x ++) - { - WDL_FFT_REAL val=output[0][x]; - WDL_FFT_REAL expval = (x==pingoffs+oneoffs) ? 1.0:0.0; - if (fabs(val-expval)>0.000000001) - { - printf("%d: %.4fdB - %f %f\n",x,log10(max(val,0.000000000001))*20.0 - log10(max(expval,0.000000000001))*20.0,val,expval); - } - } - - return 0; -} - -#endif - - -int WDL_ImpulseBuffer::SetLength(int samples) -{ - int x; - for(x=0;xWDL_CONVO_MAX_IMPULSE_NCH) usench=WDL_CONVO_MAX_IMPULSE_NCH; - - if (usench > m_nch) - { - int len = GetLength(); - int x,ax=0; - for(x=m_nch;x impulses[WDL_CONVO_MAX_IMPULSE_NCH]; - -private: - int m_nch; - -}; - -class WDL_ConvolutionEngine -{ -public: - WDL_ConvolutionEngine(); - ~WDL_ConvolutionEngine(); - - int SetImpulse(WDL_ImpulseBuffer *impulse, int fft_size=-1, int impulse_sample_offset=0, int max_imp_size=0, bool forceBrute=false); - - int GetFFTSize() { return m_fft_size; } - int GetLatency() { return m_fft_size/2; } - - void Reset(); // clears out any latent samples - - void Add(WDL_FFT_REAL **bufs, int len, int nch); - - int Avail(int wantSamples); - WDL_FFT_REAL **Get(); // returns length valid - void Advance(int len); - -private: - WDL_TypedBuf m_impulse[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel - WDL_TypedBuf m_impulse_zflag[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel - - int m_impulse_nch; - int m_fft_size; - int m_impulse_len; - int m_proc_nch; - - WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH]; - WDL_Queue m_samplesin2[WDL_CONVO_MAX_PROC_NCH]; - WDL_FastQueue m_samplesin[WDL_CONVO_MAX_PROC_NCH]; - - int m_hist_pos[WDL_CONVO_MAX_PROC_NCH]; - - WDL_TypedBuf m_samplehist[WDL_CONVO_MAX_PROC_NCH]; // FFT'd sample blocks per channel - WDL_TypedBuf m_samplehist_zflag[WDL_CONVO_MAX_IMPULSE_NCH]; - WDL_TypedBuf m_overlaphist[WDL_CONVO_MAX_PROC_NCH]; - WDL_TypedBuf m_combinebuf; - - WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH]; - -public: - - // _div stuff - int m_zl_delaypos; - int m_zl_dumpage; - -//#define WDLCONVO_ZL_ACCOUNTING -#ifdef WDLCONVO_ZL_ACCOUNTING - int m_zl_fftcnt;//removeme (testing of benchmarks) -#endif - void AddSilenceToOutput(int len, int nch); - -} WDL_FIXALIGN; - -// low latency version -class WDL_ConvolutionEngine_Div -{ -public: - WDL_ConvolutionEngine_Div(); - ~WDL_ConvolutionEngine_Div(); - - int SetImpulse(WDL_ImpulseBuffer *impulse, int maxfft_size=0, int known_blocksize=0, int max_imp_size=0, int impulse_offset=0, int latency_allowed=0); - - int GetLatency(); - void Reset(); - - void Add(WDL_FFT_REAL **bufs, int len, int nch); - - int Avail(int wantSamples); - WDL_FFT_REAL **Get(); // returns length valid - void Advance(int len); - -private: - WDL_PtrList m_engines; - - WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH]; - WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH]; - - int m_proc_nch; - bool m_need_feedsilence; - -} WDL_FIXALIGN; - - -#endif \ No newline at end of file diff --git a/WDL/db2val.h b/WDL/db2val.h deleted file mode 100644 index 46abd76c..00000000 --- a/WDL/db2val.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _WDL_DB2VAL_H_ -#define _WDL_DB2VAL_H_ - -#include - -#define TWENTY_OVER_LN10 8.6858896380650365530225783783321 -#define LN10_OVER_TWENTY 0.11512925464970228420089957273422 -#define DB2VAL(x) exp((x)*LN10_OVER_TWENTY) - -static inline double VAL2DB(double x) -{ - if (x < 0.0000000298023223876953125) return -150.0; - double v=log(x)*TWENTY_OVER_LN10; - return v<-150.0?-150.0:v; -} - -static inline double VAL2DB_EX(double x, double mindb) -{ - return x <= DB2VAL(mindb) ? mindb : (log(x)*TWENTY_OVER_LN10); -} - -#endif \ No newline at end of file diff --git a/WDL/denormal.h b/WDL/denormal.h deleted file mode 100644 index d7dc4197..00000000 --- a/WDL/denormal.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef _WDL_DENORMAL_H_ -#define _WDL_DENORMAL_H_ - -typedef struct -{ - #ifdef __ppc__ // todo: other big endian platforms... - unsigned int hw; - unsigned int lw; - #else - unsigned int lw; - unsigned int hw; - #endif -} WDL_DenormalTwoInts; - -typedef union { double fl; WDL_DenormalTwoInts w; } WDL_DenormalDoubleAccess; -typedef union { float fl; unsigned int w; } WDL_DenormalFloatAccess; - - -// note: the _aggressive versions filter out anything less than around 1.0e-16 or so (approximately) to 0.0, including -0.0 (becomes 0.0) -// note: new! the _aggressive versions also filter inf and NaN to 0.0 - -#ifdef __cplusplus -#define WDL_DENORMAL_INLINE inline -#elif defined(_MSC_VER) -#define WDL_DENORMAL_INLINE __inline -#else -#define WDL_DENORMAL_INLINE -#endif - -#define WDL_DENORMAL_DOUBLE_HW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.hw) -#define WDL_DENORMAL_DOUBLE_LW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.lw) -#define WDL_DENORMAL_FLOAT_W(a) (((const WDL_DenormalFloatAccess*)(a))->w) - -#define WDL_DENORMAL_DOUBLE_HW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.hw) -#define WDL_DENORMAL_DOUBLE_LW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.lw) -#define WDL_DENORMAL_FLOAT_W_NC(a) (((WDL_DenormalFloatAccess*)(a))->w) - -#define WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF 0x3cA00000 // 0x3B8000000 maybe instead? that's 10^-5 smaller or so -#define WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF 0x25000000 - - -static double WDL_DENORMAL_INLINE denormal_filter_double(double a) -{ - return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; -} - -static double WDL_DENORMAL_INLINE denormal_filter_double2(double a) -{ - return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) > 0x100000 ? a : 0.0; -} - -static double WDL_DENORMAL_INLINE denormal_filter_double_aggressive(double a) -{ - return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; -} - -static float WDL_DENORMAL_INLINE denormal_filter_float(float a) -{ - return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; -} - -static float WDL_DENORMAL_INLINE denormal_filter_float2(float a) -{ - return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) > 0x800000 ? a : 0.0f; -} - - -static float WDL_DENORMAL_INLINE denormal_filter_float_aggressive(float a) -{ - return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; -} -static void WDL_DENORMAL_INLINE denormal_fix_double(double *a) -{ - if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; -} - -static void WDL_DENORMAL_INLINE denormal_fix_double_aggressive(double *a) -{ - if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; -} - -static void WDL_DENORMAL_INLINE denormal_fix_float(float *a) -{ - if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; -} -static void WDL_DENORMAL_INLINE denormal_fix_float_aggressive(float *a) -{ - if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; -} - - - -#ifdef __cplusplus // automatic typed versions (though one should probably use the explicit versions... - - -static double WDL_DENORMAL_INLINE denormal_filter(double a) -{ - return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; -} -static double WDL_DENORMAL_INLINE denormal_filter_aggressive(double a) -{ - return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; -} - -static float WDL_DENORMAL_INLINE denormal_filter(float a) -{ - return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; -} - -static float WDL_DENORMAL_INLINE denormal_filter_aggressive(float a) -{ - return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; -} - -static void WDL_DENORMAL_INLINE denormal_fix(double *a) -{ - if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; -} -static void WDL_DENORMAL_INLINE denormal_fix_aggressive(double *a) -{ - if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; -} -static void WDL_DENORMAL_INLINE denormal_fix(float *a) -{ - if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; -} -static void WDL_DENORMAL_INLINE denormal_fix_aggressive(float *a) -{ - if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; -} - - - -#endif // cplusplus versions - - - - -//////////////////// -// this isnt a denormal function but it is similar, so we'll put it here as a bonus - -static void WDL_DENORMAL_INLINE GetDoubleMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 -{ - unsigned int hw = WDL_DENORMAL_DOUBLE_HW(in)&0x7fffffff; - if (hw >= WDL_DENORMAL_DOUBLE_HW(out) && (hw>WDL_DENORMAL_DOUBLE_HW(out) || WDL_DENORMAL_DOUBLE_LW(in) > WDL_DENORMAL_DOUBLE_LW(out))) - { - WDL_DENORMAL_DOUBLE_LW_NC(out) = WDL_DENORMAL_DOUBLE_LW(in); - WDL_DENORMAL_DOUBLE_HW_NC(out) = hw; - } -} - -static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(float *out, const float *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 -{ - unsigned int hw = WDL_DENORMAL_FLOAT_W(in)&0x7fffffff; - if (hw > WDL_DENORMAL_FLOAT_W(out)) WDL_DENORMAL_FLOAT_W_NC(out)=hw; -} - - -#ifdef __cplusplus -static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 -{ - GetDoubleMaxAbsValue(out,in); -} -#endif - -#endif diff --git a/WDL/des.cpp b/WDL/des.cpp deleted file mode 100644 index cab4dd4e..00000000 --- a/WDL/des.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* Loosely based on: - * - * D3DES (V5.09) - - * - * A portable, public domain, version of the Data Encryption Standard. - * - * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. - * - * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. - * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. - */ - - -#include "des.h" - -static const unsigned char pc1[56] = { - 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 -}; -static const unsigned char totrot[16] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; - -static const unsigned char pc2[48] = { - 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; - -static unsigned int SP1[64] = { - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static unsigned int SP2[64] = { - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static unsigned int SP3[64] = { - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static unsigned int SP4[64] = { - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static unsigned int SP5[64] = { - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static unsigned int SP6[64] = { - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static unsigned int SP7[64] = { - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static unsigned int SP8[64] = { - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -WDL_DES::WDL_DES() -{ -} -WDL_DES::~WDL_DES() -{ -} - -void WDL_DES::SetKey(const unsigned char *key8, bool isEncrypt) -{ - int i; - unsigned char pc1m[56], pcr[56]; - for ( i = 0; i < 56; i++ ) - { - int l = pc1[i]; - int m = l & 07; - pc1m[i] = (key8[l >> 3] & (1<> 10) | - ((m_keydata[i+1] & 0x00000fc0) >> 6); - - unsigned int b= ((m_keydata[i] & 0x0003f000) << 12) | - ((m_keydata[i] & 0x0000003f) << 16) | - ((m_keydata[i+1] & 0x0003f000) >> 4) | - (m_keydata[i+1] & 0x0000003f); - m_keydata[i]=a; - m_keydata[i+1]=b; - } - - -} - -void WDL_DES::Process8(unsigned char *buf8) -{ - unsigned int leftt=(buf8[0]<<24)|(buf8[1]<<16)|(buf8[2]<<8)|(buf8[3]); - unsigned int right=(buf8[4]<<24)|(buf8[5]<<16)|(buf8[6]<<8)|(buf8[7]); - - unsigned int *keys = m_keydata; - unsigned int fval, work; - int round; - - work = ((leftt >> 4) ^ right) & 0x0f0f0f0f; - right ^= work; - leftt ^= (work << 4); - work = ((leftt >> 16) ^ right) & 0x0000ffff; - right ^= work; - leftt ^= (work << 16); - work = ((right >> 2) ^ leftt) & 0x33333333; - leftt ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ leftt) & 0x00ff00ff; - leftt ^= work; - right ^= (work << 8); - right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffff; - work = (leftt ^ right) & 0xaaaaaaaa; - leftt ^= work; - right ^= work; - leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffff; - - for (round = 0; round < 8; round++) - { - work = (right << 28) | (right >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3f]; - fval |= SP5[(work >> 8) & 0x3f]; - fval |= SP3[(work >> 16) & 0x3f]; - fval |= SP1[(work >> 24) & 0x3f]; - work = right ^ *keys++; - fval |= SP8[ work & 0x3f]; - fval |= SP6[(work >> 8) & 0x3f]; - fval |= SP4[(work >> 16) & 0x3f]; - fval |= SP2[(work >> 24) & 0x3f]; - leftt ^= fval; - work = (leftt << 28) | (leftt >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3f]; - fval |= SP5[(work >> 8) & 0x3f]; - fval |= SP3[(work >> 16) & 0x3f]; - fval |= SP1[(work >> 24) & 0x3f]; - work = leftt ^ *keys++; - fval |= SP8[ work & 0x3f]; - fval |= SP6[(work >> 8) & 0x3f]; - fval |= SP4[(work >> 16) & 0x3f]; - fval |= SP2[(work >> 24) & 0x3f]; - right ^= fval; - } - - right = (right << 31) | (right >> 1); - work = (leftt ^ right) & 0xaaaaaaaa; - leftt ^= work; - right ^= work; - leftt = (leftt << 31) | (leftt >> 1); - work = ((leftt >> 8) ^ right) & 0x00ff00ff; - right ^= work; - leftt ^= (work << 8); - work = ((leftt >> 2) ^ right) & 0x33333333; - right ^= work; - leftt ^= (work << 2); - work = ((right >> 16) ^ leftt) & 0x0000ffff; - leftt ^= work; - right ^= (work << 16); - work = ((right >> 4) ^ leftt) & 0x0f0f0f0f; - leftt ^= work; - right ^= (work << 4); - - buf8[0] = (right>>24)&0xff; - buf8[1] = (right>>16)&0xff; - buf8[2] = (right>>8)&0xff; - buf8[3] = (right)&0xff; - buf8[4] = (leftt>>24)&0xff; - buf8[5] = (leftt>>16)&0xff; - buf8[6] = (leftt>>8)&0xff; - buf8[7] = (leftt)&0xff; -} diff --git a/WDL/des.h b/WDL/des.h deleted file mode 100644 index 861bd015..00000000 --- a/WDL/des.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Loosely based on: - * - * D3DES (V5.09) - - * - * A portable, public domain, version of the Data Encryption Standard. - * - * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. - * - * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. - * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. - */ - - -#ifndef _WDL_DES_H_ -#define _WDL_DES_H_ - - -class WDL_DES -{ -public: - WDL_DES(); - ~WDL_DES(); - - void SetKey(const unsigned char *key8, bool isEncrypt); - - void Process8(unsigned char *buf8); - -private: - - unsigned int m_keydata[32]; - -}; - -#endif \ No newline at end of file diff --git a/WDL/destroycheck.h b/WDL/destroycheck.h deleted file mode 100644 index d8deee3a..00000000 --- a/WDL/destroycheck.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _WDL_DESTROYCHECK_H_ -#define _WDL_DESTROYCHECK_H_ - -// this is a useful class for verifying that an object (usually "this") hasn't been destroyed: -// to use it you add a WDL_DestroyState as a member of your class, then use the WDL_DestroyCheck -// helper class (creating it when the pointer is known valid, and checking it later to see if it -// is still valid). -// -// example: -// class myClass { -// WDL_DestroyState dest; -// ... -// }; -// -// calling code (on myClass *classInstnace): -// WDL_DestroyCheck chk(&classInstance->dest); -// somefunction(); -// if (!chk.isOK()) printf("classInstance got deleted!\n"); -// -// NOTE: only use this when these objects will be accessed from the same thread -- it will fail miserably -// in a multithreaded environment - - - - -class WDL_DestroyCheck -{ - public: - class WDL_DestroyStateNextRec { public: WDL_DestroyCheck *next; }; - - WDL_DestroyStateNextRec n, *prev; - WDL_DestroyCheck(WDL_DestroyStateNextRec *state) - { - n.next=NULL; - if ((prev=state)) - { - if ((n.next=prev->next)) n.next->prev = &n; - prev->next=this; - } - } - ~WDL_DestroyCheck() - { - if (prev) - { - prev->next = n.next; - if (n.next) n.next->prev = prev; - } - } - - bool isOK() { return !!prev; } -}; - -class WDL_DestroyState : public WDL_DestroyCheck::WDL_DestroyStateNextRec -{ - public: - WDL_DestroyState() { next=NULL; } - - ~WDL_DestroyState() - { - WDL_DestroyCheck *p = next; - while (p) { WDL_DestroyCheck *np = p->n.next; p->prev=NULL; p->n.next=NULL; p=np; } - } -}; - -#endif diff --git a/WDL/dirscan.h b/WDL/dirscan.h deleted file mode 100644 index a03a62bf..00000000 --- a/WDL/dirscan.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - WDL - dirscan.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides the interface and implementation for WDL_DirScan, a simple - (and somewhat portable) directory reading class. On non-Win32 systems it wraps - opendir()/readdir()/etc. On Win32, it uses FindFirst*, and supports wildcards as - well. - - -*/ - - -#ifndef _WDL_DIRSCAN_H_ -#define _WDL_DIRSCAN_H_ - -#include "wdlstring.h" - -#ifndef _WIN32 -#include -#include -#include -#endif - -class WDL_DirScan -{ - public: - WDL_DirScan() : -#ifdef _WIN32 - m_h(INVALID_HANDLE_VALUE) - #ifndef WDL_NO_SUPPORT_UTF8 - , m_wcmode(false) - #endif -#else - m_h(NULL), m_ent(NULL) -#endif - { - } - - ~WDL_DirScan() - { - Close(); - } - - int First(const char *dirname -#ifdef _WIN32 - , int isExactSpec=0 -#endif - ) // returns 0 if success - { - int l=strlen(dirname); - if (l < 1) return -1; - - WDL_String scanstr(dirname); -#ifdef _WIN32 - if (!isExactSpec) -#endif - if (dirname[l-1] == '\\' || dirname[l-1] == '/') scanstr.SetLen(l-1); - - m_leading_path.Set(scanstr.Get()); - -#ifdef _WIN32 - if (!isExactSpec) scanstr.Append("\\*"); - else - { - // remove trailing stuff from m_leading_path - char *p=m_leading_path.Get(); - while (*p) p++; - while (p > m_leading_path.Get() && *p != '/' && *p != '\\') p--; - if (p > m_leading_path.Get()) *p=0; - } -#else - if (l && !scanstr.Get()[0]) - scanstr.Set("/"); // fix for scanning / -#endif - - Close(); -#ifdef _WIN32 - #ifndef WDL_NO_SUPPORT_UTF8 - m_h=INVALID_HANDLE_VALUE; - m_wcmode = GetVersion()< 0x80000000; - - if (m_wcmode) - { - int reqbuf = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,NULL,0); - if (reqbuf > 1000) - { - WDL_TypedBuf tmp; - tmp.Resize(reqbuf+10); - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,tmp.Get(),tmp.GetSize())) - m_h=FindFirstFileW(tmp.Get(),&m_fd); - } - else - { - WCHAR wfilename[1024]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,wfilename,1024)) - m_h=FindFirstFileW(wfilename,&m_fd); - } - } - - if (m_h==INVALID_HANDLE_VALUE) m_wcmode=false; - - if (m_h==INVALID_HANDLE_VALUE) - #endif - m_h=FindFirstFile(scanstr.Get(),(WIN32_FIND_DATA*)&m_fd); - return (m_h == INVALID_HANDLE_VALUE); -#else - m_ent=0; - m_h=opendir(scanstr.Get()); - return !m_h || Next(); -#endif - } - int Next() // returns 0 on success - { -#ifdef _WIN32 - if (m_h == INVALID_HANDLE_VALUE) return -1; - #ifndef WDL_NO_SUPPORT_UTF8 - if (m_wcmode) return !FindNextFileW(m_h,&m_fd); - #endif - return !FindNextFile(m_h,(WIN32_FIND_DATA*)&m_fd); -#else - if (!m_h) return -1; - return !(m_ent=readdir(m_h)); -#endif - } - void Close() - { -#ifdef _WIN32 - if (m_h != INVALID_HANDLE_VALUE) FindClose(m_h); - m_h=INVALID_HANDLE_VALUE; -#else - if (m_h) closedir(m_h); - m_h=0; m_ent=0; -#endif - } - -#ifdef _WIN32 - char *GetCurrentFN() - { -#ifndef WDL_NO_SUPPORT_UTF8 - if (m_wcmode) - { - if (!WideCharToMultiByte(CP_UTF8,0,m_fd.cFileName,-1,m_tmpbuf,sizeof(m_tmpbuf),NULL,NULL)) - m_tmpbuf[0]=0; - return m_tmpbuf; - } -#endif - return ((WIN32_FIND_DATA *)&m_fd)->cFileName; - } -#else - char *GetCurrentFN() const { return m_ent?m_ent->d_name : (char *)""; } -#endif - void GetCurrentFullFN(WDL_String *str) - { - str->Set(m_leading_path.Get()); -#ifdef _WIN32 - str->Append("\\"); -#else - str->Append("/"); -#endif - str->Append(GetCurrentFN()); - } - int GetCurrentIsDirectory() const - { -#ifdef _WIN32 - return !!(m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); -#else - return m_ent && (m_ent->d_type & DT_DIR); -#endif - } - - // these are somewhat windows specific calls, eh -#ifdef _WIN32 - DWORD GetCurrentFileSize(DWORD *HighWord=NULL) const { if (HighWord) *HighWord = m_fd.nFileSizeHigh; return m_fd.nFileSizeLow; } - void GetCurrentLastWriteTime(FILETIME *ft) const { *ft = m_fd.ftLastWriteTime; } - void GetCurrentLastAccessTime(FILETIME *ft) const { *ft = m_fd.ftLastAccessTime; } - void GetCurrentCreationTime(FILETIME *ft) const { *ft = m_fd.ftCreationTime; } -#elif defined(_WDL_SWELL_H_) - - // todo: compat for more of these functions - - void GetCurrentLastWriteTime(FILETIME *ft) - { - WDL_String tmp; - GetCurrentFullFN(&tmp); - struct stat st={0,}; - stat(tmp.Get(),&st); - unsigned long long a=(unsigned long long)st.st_mtime; // seconds since january 1st, 1970 - a+=((unsigned long long)(60*60*24*(365*4+1)/4))*(unsigned long long)(1970-1601); // this is approximate - a*=1000*10000; // seconds to 1/10th microseconds (100 nanoseconds) - ft->dwLowDateTime=a & 0xffffffff; - ft->dwHighDateTime=a>>32; - } - DWORD GetCurrentFileSize(DWORD *HighWord=NULL) - { - WDL_String tmp; - GetCurrentFullFN(&tmp); - struct stat st={0,}; - stat(tmp.Get(),&st); - - if (HighWord) *HighWord = (DWORD)(st.st_size>>32); - return (DWORD)(st.st_size&0xffffffff); - } - -#endif - - private: -#ifdef _WIN32 - -#ifndef WDL_NO_SUPPORT_UTF8 - bool m_wcmode; - WIN32_FIND_DATAW m_fd; - char m_tmpbuf[MAX_PATH*5]; // even if each byte gets encoded as 4 utf-8 bytes this should be plenty ;) -#else - WIN32_FIND_DATA m_fd; -#endif - HANDLE m_h; -#else - DIR *m_h; - struct dirent *m_ent; -#endif - WDL_String m_leading_path; -} WDL_FIXALIGN; - -#endif diff --git a/WDL/eel2/.gitignore b/WDL/eel2/.gitignore deleted file mode 100644 index 6e582baf..00000000 --- a/WDL/eel2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!asm-nseel-x64-macho.o diff --git a/WDL/eel2/Makefile b/WDL/eel2/Makefile deleted file mode 100644 index 952b939b..00000000 --- a/WDL/eel2/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -CC=gcc -CFLAGS=-O -g -CXX=g++ - -OBJS=nseel-caltab.o nseel-compiler.o nseel-eval.o nseel-lextab.o nseel-ram.o nseel-yylex.o - -default: test - -nseel-compiler.o: glue*.h -nseel-cfunc.o: asm*.c - -ifdef PORTABLE - CFLAGS += -DEEL_TARGET_PORTABLE - OBJS += nseel-cfunc.o -endif -CXXFLAGS=$(CFLAGS) - -test: test.o $(OBJS) - g++ -o $@ $^ $(CXXFLAGS) - -clean: - -rm test.o $(OBJS) diff --git a/WDL/eel2/a2i.php b/WDL/eel2/a2i.php deleted file mode 100644 index cf0e620a..00000000 --- a/WDL/eel2/a2i.php +++ /dev/null @@ -1,243 +0,0 @@ -1) - $end_restore = substr($line,1-strlen($lastchunk)); - else $end_restore=""; - - $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); - - // get rid of chars we can ignore - $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); - - $sline=str_replace("\\n","", $sline); - $sline=str_replace("\"","", $sline); - $sline=str_replace("$","", $sline); - $sline=str_replace("%","", $sline); - - - // get rid of excess whitespace, especially around commas - $sline=str_replace(" "," ", $sline); - $sline=str_replace(" "," ", $sline); - $sline=str_replace(" "," ", $sline); - $sline=str_replace(", ",",", $sline); - $sline=str_replace(" ,",",", $sline); - - $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); - - - if (preg_match("/^([0-9]+):/",trim($sline))) - { - $d = (int) $sline; - $a = strstr($sline,":"); - if ($a) $sline = substr($a,1); - - if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; - else $thislbl = "label_" . $labelcnt++; - - $btfut[$d]=""; - $bthist[$d] = $thislbl; - - fputs($out,$thislbl . ":\n"); - } - - $sploded = explode(" ",trim($sline)); - if ($sline != "" && count($sploded)>0) - { - $inst = trim($sploded[0]); - $suffix = ""; - - $instline = strstr($sline,$inst); - $beg_restore .= substr($sline,0,-strlen($instline)); - - $parms = trim(substr($instline,strlen($inst))); - - if ($inst=="j") $inst="jmp"; - - //if ($inst == "fdiv" && $parms == "") $inst="fdivr"; - - if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; - else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; - else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fabs" && $inst != "fchs" && substr($inst,-1) == "s") $suffix = "s"; - - - if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); - - $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); - - $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","EEL_ASM_TYPE [$2+$1]",$parms); - $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","EEL_ASM_TYPE [$1]",$parms); - - if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } - - if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword ptr "; - else if ($suffix == "l") $suffixstr = "dword ptr "; - else if ($suffix == "s") $suffixstr = "dword ptr "; - else $suffixstr = ""; - $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); - $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); - - - $parms=str_replace("NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR","NSEEL_LOOPFUNC_SUPPORT_MAXLEN", $parms); - $parms=str_replace("EEL_F_SUFFIX","EEL_ASM_TYPE", $parms); - $parms=str_replace("EEL_F_SSTR","EEL_F_SIZE", $parms); - - $plist = explode(",",$parms); - if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; - else if (count($plist)==2) - { - $parms = trim($plist[1]) . ", " . trim($plist[0]); - } - else - { - } - - if ($inst=="fsts") $inst="fstsw"; - if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); - if (substr($inst,0,1) == "j") - { - if (substr($parms,-1) == "f") - { - $d = (int) substr($parms,0,-1); - if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; - else $btfut[$d] = $thislbl = "label_" . $labelcnt++; - $parms = $thislbl; - } - else if (substr($parms,-1) == "b") - { - $d = (int) substr($parms,0,-1); - if ($bthist[$d]=="") echo "Error resolving label $parms\n"; - $parms = $bthist[$d]; - } - } - if (stristr($parms,"[0xfefefefe]")) - { - if ($inst == "fmul" || $inst=="fadd" || $inst == "fcomp") - { - if ($inst=="fmul") $hdr="0x0D"; - if ($inst=="fadd") $hdr="0x05"; - if ($inst=="fcomp") $hdr="0x1D"; - - fputs($out,"#if EEL_F_SIZE == 8\n"); - fputs($out,"_emit 0xDC; // $inst qword ptr [0xfefefefe]\n"); - fputs($out,"_emit $hdr;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"#else\n"); - fputs($out,"_emit 0xD8; // $inst dword ptr [0xfefefefe]\n"); - fputs($out,"_emit $hdr;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"_emit 0xFE;\n"); - fputs($out,"#endif\n"); - $nowrite=1; - } - } - - - $sline = $inst; - if ($parms !="") $sline .= " " . $parms; - $sline .= ";"; - - } - - $sline=preg_replace("/FPREG_([0-9]+)/","st($1)",$sline); - $line = $beg_restore . $sline . $end_restore; - - } - - - } - } - - if (!$nowrite) - { - if (strstr($line,"__TEMP_REPLACE__")) - { - $a = strstr($line,"//REPLACE="); - if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); - $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); - } - fputs($out,$line . "\n"); - } -} - -if ($inblock) echo "Error (ended in __asm__ block???)\n"; - - -fclose($in); -fclose($out); - -}; - -process_file("asm-nseel-x86-gcc.c" , "asm-nseel-x86-msvc.c"); -// process_file("asm-miscfunc-x86-gcc.c" , "asm-miscfunc-x86-msvc.c"); -//process_file("asm-megabuf-x86-gcc.c" , "asm-megabuf-x86-msvc.c"); - -?> diff --git a/WDL/eel2/a2x64.php b/WDL/eel2/a2x64.php deleted file mode 100644 index c3142b8c..00000000 --- a/WDL/eel2/a2x64.php +++ /dev/null @@ -1,305 +0,0 @@ -1) - $end_restore = substr($line,1-strlen($lastchunk)); - else $end_restore=""; - - $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); - - $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); - - // get rid of chars we can ignore - $sline=str_replace("\\n","", $sline); - $sline=str_replace("\"","", $sline); - $sline=str_replace("$","", $sline); - $sline=str_replace("%","", $sline); - - - // get rid of excess whitespace, especially around commas - $sline=str_replace(" "," ", $sline); - $sline=str_replace(" "," ", $sline); - $sline=str_replace(" "," ", $sline); - $sline=str_replace(", ",",", $sline); - $sline=str_replace(" ,",",", $sline); - - $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); - - - if (preg_match("/^([0-9]+):/",trim($sline))) - { - $d = (int) $sline; - $a = strstr($sline,":"); - if ($a) $sline = substr($a,1); - - if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; - else $thislbl = "label_" . $labelcnt++; - - $btfut[$d]=""; - $bthist[$d] = $thislbl; - - fputs($out,$thislbl . ":\n"); - } - - $sploded = explode(" ",trim($sline)); - if ($sline != "" && count($sploded)>0) - { - $inst = trim($sploded[0]); - $suffix = ""; - - $instline = strstr($sline,$inst); - $beg_restore .= substr($sline,0,-strlen($instline)); - - $parms = trim(substr($instline,strlen($inst))); - - if ($inst=="j") $inst="jmp"; - -// if ($inst == "fdiv" && $parms == "") $inst="fdivr"; - - if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; - else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; - else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fchs" && $inst != "fabs" && substr($inst,-1) == "s") $suffix = "s"; - - - if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); - - $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); - - $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","qword [$2+$1]",$parms); - $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","qword [$1]",$parms); - - if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } - - if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword "; - else if ($suffix == "l") $suffixstr = "dword "; - else if ($suffix == "s") $suffixstr = "dword "; - else $suffixstr = ""; - $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); - $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); - - - $parms=str_replace("NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR","10000000", $parms); - $parms=str_replace("EEL_F_SUFFIX","qword", $parms); - $parms=str_replace("EEL_F_SSTR","8", $parms); - - $plist = explode(",",$parms); - if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; - else if (count($plist)==2) - { - if ($suffixstr != "dword " || strstr($plist[0],"[")) - makeregs64($plist[0]); - if ($suffixstr != "dword " || stristr($plist[0],"ffffffff") || strstr($plist[1],"[")) makeregs64($plist[1]); - - if (!stristr($plist[0],"[") && - !stristr($plist[1],"[")) { makeregs64($plist[1]); makeregs64($plist[0]); } - - $parms = trim($plist[1]) . ", " . trim($plist[0]); - } - else - { - // if ($suffixstr != "dword ") - makeregs64($parms); - } - - if ($inst=="fsts") $inst="fstsw"; - if ($inst=="fistp") $inst="fisttp"; - if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); - if (substr($inst,0,1) == "j") - { - if (substr($parms,-1) == "f") - { - $d = (int) substr($parms,0,-1); - if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; - else $btfut[$d] = $thislbl = "label_" . $labelcnt++; - $parms = $thislbl; - } - else if (substr($parms,-1) == "b") - { - $d = (int) substr($parms,0,-1); - if ($bthist[$d]=="") echo "Error resolving label $parms\n"; - $parms = $bthist[$d]; - } - } - $parms = preg_replace("/0x[fe,FE]{8}/","qword 0xFEFEFEFEFEFEFEFE",$parms); - - - - $sline = $inst; - if ($parms !="") $sline .= " " . $parms; - - } - - $sline=preg_replace("/FPREG_([0-9]+)/","st$1",$sline); - $line = $beg_restore . $sline . $end_restore; - - } - - - } - } - - if ($inblock) - { - if (strstr($line,"__TEMP_REPLACE__")) - { - $a = strstr($line,"; REPLACE="); - if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); - $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); - } - fputs($out,$line . "\n"); - } -} - -if ($inblock) echo "Error (ended in __asm__ block???)\n"; - - -fclose($in); -fclose($out); - -}; - -$nasm="nasm"; -$want_funclead=""; - -$fmt = "win64"; -if (isset($argv[1]) && $argv[1] != "") $fmt = $argv[1]; - -$fnout = "asm-nseel-x64.asm"; - -if ($fmt == "macho64") { $fnout="asm-nseel-x64-macho.asm"; $nasm = "nasm64"; $want_funclead = "_"; } -if ($fmt == "macho64x") { $fnout="asm-nseel-x64-macho.asm"; $nasm = "nasm"; $want_funclead = "_"; $fmt="macho64"; } -if ($fmt == "win64x") { $nasm="nasm64"; $fmt = "win64"; } - -process_file("asm-nseel-x86-gcc.c" , $fnout, $fmt != "win64" ? "%define AMD64ABI\n" : ""); - - -system("$nasm -f $fmt $fnout"); - -?> diff --git a/WDL/eel2/asm-nseel-ppc-gcc.c b/WDL/eel2/asm-nseel-ppc-gcc.c deleted file mode 100644 index 3ce27e36..00000000 --- a/WDL/eel2/asm-nseel-ppc-gcc.c +++ /dev/null @@ -1,1377 +0,0 @@ -#define FUNCTION_MARKER "mr r0, r0\n" \ - "mr r1, r1\n" \ - "mr r2, r2\n" - -#if EEL_F_SIZE == 8 - -void nseel_asm_1pdd(void) -{ - - __asm__( - FUNCTION_MARKER - "addis r5, 0, 0xdead\n" - "ori r5, r5, 0xbeef\n" - "mtctr r5\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: ); -} -void nseel_asm_1pdd_end(void){} - -void nseel_asm_2pdd(void) -{ - - __asm__( - FUNCTION_MARKER - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "fmr f2, f1\n" - "lfd f1, 0(r14)\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: ); -}; -void nseel_asm_2pdd_end(void){} - -void nseel_asm_2pdds(void) -{ - __asm__( - FUNCTION_MARKER - "addis r5, 0, 0xdead\n" - "ori r5, r5, 0xbeef\n" - "fmr f2, f1\n" - "lfd f1, 0(r14)\n" - "mtctr r5\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - "stfd f1, 0(r14)\n" - "mr r3, r14\n" - FUNCTION_MARKER - :: ); -} -void nseel_asm_2pdds_end(void){} - -#else // 32 bit floating point calls - -#error no 32 bit float support - -#endif - -//--------------------------------------------------------------------------------------------------------------- - - - -// do nothing, eh -void nseel_asm_exec2(void) -{ - __asm__( - FUNCTION_MARKER - FUNCTION_MARKER - ); -} -void nseel_asm_exec2_end(void) { } - - - -void nseel_asm_invsqrt(void) -{ - __asm__( - FUNCTION_MARKER - "frsqrte f1, f1\n" // less accurate than our x86 equivilent, but invsqrt() is inherently inaccurate anyway - FUNCTION_MARKER - ); -} -void nseel_asm_invsqrt_end(void) {} - -void nseel_asm_dbg_getstackptr(void) -{ - __asm__( - FUNCTION_MARKER - "addis r11, 0, 0x4330\n" - "xoris r10, r1, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_dbg_getstackptr_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_sqr(void) -{ - __asm__( - FUNCTION_MARKER - "fmul f1, f1, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_sqr_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_abs(void) -{ - __asm__( - FUNCTION_MARKER - "fabs f1, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_abs_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_assign(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f1, 0(r3)\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_assign_end(void) {} -// -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_assign_fromfp(void) -{ - __asm__( - FUNCTION_MARKER - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_assign_fromfp_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_assign_fast(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f1, 0(r3)\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_assign_fast_end(void) {} -// -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_assign_fast_fromfp(void) -{ - __asm__( - FUNCTION_MARKER - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_assign_fast_fromfp_end(void) {} - - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_add(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fadd f1, f1, f2\n" - FUNCTION_MARKER - ); -} -void nseel_asm_add_end(void) {} - -void nseel_asm_add_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fadd f1, f1, f2\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_add_op_end(void) {} - -void nseel_asm_add_op_fast(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fadd f1, f1, f2\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_add_op_fast_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_sub(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fsub f1, f2, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_sub_end(void) {} - -void nseel_asm_sub_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fsub f1, f2, f1\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_sub_op_end(void) {} - -void nseel_asm_sub_op_fast(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fsub f1, f2, f1\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_sub_op_fast_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_mul(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fmul f1, f2, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_mul_end(void) {} - -void nseel_asm_mul_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fmul f1, f2, f1\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_mul_op_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_div(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fdiv f1, f2, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_div_end(void) {} - -void nseel_asm_div_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fdiv f1, f2, f1\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_div_op_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_mod(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fabs f1, f1\n" - "fabs f2, f2\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - - "divw r12, r11, r10\n" - "mullw r12, r12, r10\n" - "subf r10, r12, r11\n" - - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_mod_end(void) {} - -void nseel_asm_shl(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "slw r10, r11, r10\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_shl_end(void) {} - -void nseel_asm_shr(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "sraw r10, r11, r10\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_shr_end(void) {} - -void nseel_asm_mod_op(void) -{ - - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fabs f1, f1\n" - "fabs f2, f2\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - - "divw r12, r11, r10\n" - "mullw r12, r12, r10\n" - "subf r10, r12, r11\n" - - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); - -} -void nseel_asm_mod_op_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_or(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "or r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_or_end(void) {} - -void nseel_asm_or0(void) -{ - __asm__( - FUNCTION_MARKER - "fctiwz f1, f1\n" - "addis r11, 0, 0x4330\n" - "stfd f1, -8(r1)\n" - "lwz r10, -4(r1)\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_or0_end(void) {} - -void nseel_asm_or_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "or r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_or_op_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_xor(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "xor r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - ); -} -void nseel_asm_xor_end(void) {} - -void nseel_asm_xor_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "xor r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_xor_op_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_and(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "and r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - FUNCTION_MARKER - );} -void nseel_asm_and_end(void) {} - -void nseel_asm_and_op(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fctiwz f1, f1\n" - "fctiwz f2, f2\n" - "stfd f1, -8(r1)\n" - "stfd f2, -16(r1)\n" - "lwz r10, -4(r1)\n" - "lwz r11, -12(r1)\n" //r11 and r12 have the integers - "and r10, r10, r11\n" // r10 has the result - "addis r11, 0, 0x4330\n" - "xoris r10, r10, 0x8000\n" - "stw r11, -8(r1)\n" // 0x43300000 - "stw r10, -4(r1)\n" // our integer sign flipped - "lfd f1, -8(r1)\n" - "fsub f1, f1, f30\n" - "mr r3, r14\n" - "stfd f1, 0(r14)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_and_op_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_uplus(void) // this is the same as doing nothing, it seems -{ - __asm__( - FUNCTION_MARKER - FUNCTION_MARKER - ); -} -void nseel_asm_uplus_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_uminus(void) -{ - __asm__( - FUNCTION_MARKER - "fneg f1, f1\n" - FUNCTION_MARKER - ); -} -void nseel_asm_uminus_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_sign(void) -{ - __asm__( - FUNCTION_MARKER - "li r9, 0\n" - "stw r9, -4(r1)\n" - "lis r9, 0xbf80\n" // -1 in float - "lfs f2, -4(r1)\n" - - "fcmpu cr7, f1, f2\n" - "blt- cr7, 0f\n" - "ble- cr7, 1f\n" - " lis r9, 0x3f80\n" // 1 in float - "0:\n" - " stw r9, -4(r1)\n" - " lfs f1, -4(r1)\n" - "1:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_sign_end(void) {} - - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_bnot(void) -{ - __asm__( - FUNCTION_MARKER - "cmpwi cr0, r3, 0\n" - "addis r3, 0, 0\n" - "bne cr0, 0f\n" - "addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - ); -} -void nseel_asm_bnot_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_if(void) -{ - __asm__( - FUNCTION_MARKER - "cmpwi cr0, r3, 0\n" - "beq cr0, 0f\n" - " addis r6, 0, 0xdead\n" - " ori r6, r6, 0xbeef\n" - " mtctr r6\n" - " bctrl\n" - "b 1f\n" - "0:\n" - " addis r6, 0, 0xdead\n" - " ori r6, r6, 0xbeef\n" - " mtctr r6\n" - " bctrl\n" - "1:\n" - FUNCTION_MARKER - :: ); -} -void nseel_asm_if_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_repeat(void) -{ - __asm__( - FUNCTION_MARKER - "fctiwz f1, f1\n" - "stfd f1, -8(r1)\n" - "lwz r5, -4(r1)\n" // r5 has count now - "cmpwi cr0, r5, 0\n" - "ble cr0, 1f\n" // skip the loop - - "addis r7, 0, ha16(%0)\n" - "addi r7, r7, lo16(%0)\n" - - "stwu r16, -16(r1)\n" // set up the stack for the loop, save r16 - - "cmpw cr0, r7, r5\n" - "bge cr0, 0f\n" - "mr r5, r7\n" // set r5 to max if we have to -"0:\n" - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" - - "addi r5, r5, -1\n" - "stw r5, 4(r1)\n" - - "mtctr r6\n" - "bctrl\n" - - "lwz r16, 0(r1)\n" - "lwz r5, 4(r1)\n" - - "cmpwi cr0, r5, 0\n" - "bgt cr0, 0b\n" - - "addi r1, r1, 16\n" // restore old stack - - "1:\n" - FUNCTION_MARKER - ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) - ); -} -void nseel_asm_repeat_end(void) {} - -void nseel_asm_repeatwhile(void) -{ - __asm__( - FUNCTION_MARKER - "stwu r16, -16(r1)\n" // save r16 to stack, update stack - "addis r5, 0, ha16(%0)\n" - "addi r5, r5, lo16(%0)\n" -"0:\n" - - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" - "stw r5, 4(r1)\n" // save maxcnt - - "mtctr r6\n" - "bctrl\n" - - "lwz r16, 0(r1)\n" // restore r16 - "lwz r5, 4(r1)\n" // restore, check maxcnt - - "cmpwi cr7, r3, 0\n" // check return value - "addi r5, r5, -1\n" - - "beq cr7, 1f\n" - - "cmpwi cr0, r5, 0\n" - "bgt cr0, 0b\n" - "1:\n" - "addi r1, r1, 16\n" // restore stack - FUNCTION_MARKER - ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) - ); -} -void nseel_asm_repeatwhile_end(void) {} - - -void nseel_asm_band(void) -{ - __asm__( - FUNCTION_MARKER - "cmpwi cr7, r3, 0\n" - "beq cr7, 0f\n" - " addis r6, 0, 0xdead\n" - " ori r6, r6, 0xbeef\n" - " mtctr r6\n" - " bctrl\n" - "0:\n" - FUNCTION_MARKER - :: ); -} -void nseel_asm_band_end(void) {} - -void nseel_asm_bor(void) -{ - __asm__( - FUNCTION_MARKER - "cmpwi cr7, r3, 0\n" - "bne cr7, 0f\n" - " addis r6, 0, 0xdead\n" - " ori r6, r6, 0xbeef\n" - " mtctr r6\n" - " bctrl\n" - "0:\n" - FUNCTION_MARKER - :: ); -} -void nseel_asm_bor_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_equal(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fsub f1, f1, f2\n" - "fabs f1, f1\n" - "fcmpu cr7, f1, f31\n" - "addis r3, 0, 0\n" - "bge cr7, 0f\n" - "addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_equal_end(void) {} -// -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_notequal(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fsub f1, f1, f2\n" - "fabs f1, f1\n" - "fcmpu cr7, f1, f31\n" - "addis r3, 0, 0\n" - "blt cr7, 0f\n" - " addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_notequal_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_below(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f1, f2\n" - "addis r3, 0, 0\n" - "ble cr7, 0f\n" - "addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_below_end(void) {} - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_beloweq(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f1, f2\n" - "addis r3, 0, 0\n" - "blt cr7, 0f\n" - " addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_beloweq_end(void) {} - - -//--------------------------------------------------------------------------------------------------------------- -void nseel_asm_above(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f1, f2\n" - "addis r3, 0, 0\n" - "bge cr7, 0f\n" - "addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_above_end(void) {} - -void nseel_asm_aboveeq(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f1, f2\n" - "addis r3, 0, 0\n" - "bgt cr7, 0f\n" - "addis r3, 0, 1\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_aboveeq_end(void) {} - - - -void nseel_asm_min(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f1, 0(r3)\n" - "lfd f2, 0(r14)\n" - "fcmpu cr7, f2, f1\n" - "bgt cr7, 0f\n" - "mr r3, r14\n" - "0:\n" - FUNCTION_MARKER - ); -} -void nseel_asm_min_end(void) {} - -void nseel_asm_max(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f1, 0(r3)\n" - "lfd f2, 0(r14)\n" - "fcmpu cr7, f2, f1\n" - "blt cr7, 0f\n" - "mr r3, r14\n" - "0:\n" - FUNCTION_MARKER - ); -} - -void nseel_asm_max_end(void) {} - - -void nseel_asm_min_fp(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f2, f1\n" - "bgt cr7, 0f\n" - "fmr f1, f2\n" - "0:\n" - FUNCTION_MARKER - ); -} -void nseel_asm_min_fp_end(void) {} - -void nseel_asm_max_fp(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, 0(r14)\n" - "fcmpu cr7, f2, f1\n" - "blt cr7, 0f\n" - "fmr f1, f2\n" - "0:\n" - FUNCTION_MARKER - ); -} - -void nseel_asm_max_fp_end(void) {} - - - - - - -void _asm_generic3parm(void) -{ - __asm__( - FUNCTION_MARKER - "mr r6, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mr r4, r15\n" - "mr r5, r14\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic3parm_end(void) {} - -void _asm_generic3parm_retd(void) -{ - __asm__( - FUNCTION_MARKER - "mr r6, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mr r4, r15\n" - "mr r5, r14\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic3parm_retd_end(void) {} - - -void _asm_generic2parm(void) // this prob neds to be fixed for ppc -{ - __asm__( - FUNCTION_MARKER - "mr r5, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mr r4, r14\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic2parm_end(void) {} - - -void _asm_generic2parm_retd(void) -{ - __asm__( - FUNCTION_MARKER - "mr r5, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mr r4, r14\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic2parm_retd_end(void) {} - -void _asm_generic1parm(void) // this prob neds to be fixed for ppc -{ - __asm__( - FUNCTION_MARKER - "mr r4, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic1parm_end(void) {} - - - -void _asm_generic1parm_retd(void) -{ - __asm__( - FUNCTION_MARKER - "mr r4, r3\n" - "addis r3, 0, 0xdead\n" - "ori r3, r3, 0xbeef\n" - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} -void _asm_generic1parm_retd_end(void) {} - - - - -void _asm_megabuf(void) -{ - __asm__( - FUNCTION_MARKER - "lfd f2, -8(r13)\n" - "mr r3, r13\n" - - "fadd f1, f2, f1\n" - - // f1 has (float) index of array, r3 has EEL_F ** - "fctiwz f1, f1\n" - "stfd f1, -8(r1)\n" - "lwz r4, -4(r1)\n" // r4 is index of array - - "andis. r15, r4, %0\n" // check to see if it has any bits in 0xFF800000, which is 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - "bne cr0, 0f\n" // out of range, jump to error - - // shr 14 (16 for NSEEL_RAM_ITEMSPERBLOCK, minus two for pointer size), which is rotate 18 - // mask 7 bits (NSEEL_RAM_BLOCKS), but leave two empty bits (pointer size) - "rlwinm r15, r4, %1, %2, 29\n" - "lwzx r15, r3, r15\n" // r15 = (r3+r15) - "cmpi cr0, r15, 0\n" - "bne cr0, 1f\n" // if nonzero, jump to final calculation - - "0:\n" - // set up function call - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - "mtctr r7\n" - "subi r1, r1, 64\n" - "bctrl\n" - "addi r1, r1, 64\n" - "b 2f\n" - "1:\n" - // good news: we can do a direct addr return - // bad news: more rlwinm ugliness! - // shift left by 3 (sizeof(EEL_F)), mask off lower 3 bits, only allow 16 bits (NSEEL_RAM_ITEMSPERBLOCK) through - "rlwinm r3, r4, 3, %3, 28\n" - - // add offset of loaded block - "add r3, r3, r15\n" - - "2:\n" - FUNCTION_MARKER - :: - "i" ((0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1))>>16), - "i" (32 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 2), - "i" (30 - NSEEL_RAM_BLOCKS_LOG2), - "i" (28 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 1) - ); -} - -void _asm_megabuf_end(void) {} - -void _asm_gmegabuf(void) -{ - __asm__( - FUNCTION_MARKER - "fadd f1, f31, f1\n" - "addis r3, 0, 0xdead\n" // set up context pointer - "ori r3, r3, 0xbeef\n" - - "fctiwz f1, f1\n" - "subi r1, r1, 64\n" - - "addis r7, 0, 0xdead\n" - "ori r7, r7, 0xbeef\n" - - "stfd f1, 8(r1)\n" - "mtctr r7\n" - - "lwz r4, 12(r1)\n" - - "bctrl\n" - "addi r1, r1, 64\n" - FUNCTION_MARKER - :: - ); -} - -void _asm_gmegabuf_end(void) {} - -void nseel_asm_fcall(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" - "mtctr r6\n" - "bctrl\n" - FUNCTION_MARKER - ); -} -void nseel_asm_fcall_end(void) {} - - - -void nseel_asm_stack_push(void) -{ - __asm__( - FUNCTION_MARKER - - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - - "lfd f1, 0(r3)\n" // f1 is value to copy to stack - "lwz r3, 0(r6)\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "addi r3, r3, 0x8\n" - - "and r3, r3, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "or r3, r3, r14\n" - - "stfd f1, 0(r3)\n" // copy parameter to stack - - "stw r3, 0(r6)\n" // update stack state - FUNCTION_MARKER - ); -} -void nseel_asm_stack_push_end(void) {} - -void nseel_asm_stack_pop(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - "lwz r15, 0(r6)\n" // return the old stack pointer - - "lfd f1, 0(r15)\n" - "subi r15, r15, 0x8\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "and r15, r15, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "or r15, r15, r14\n" - "stw r15, 0(r6)\n" - - "stfd f1, 0(r3)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_stack_pop_end(void) {} - - - -void nseel_asm_stack_pop_fast(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - "lwz r3, 0(r6)\n" // return the old stack pointer - - "mr r15, r3\n" // update stack pointer - "subi r15, r15, 0x8\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "and r15, r15, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "or r15, r15, r14\n" - "stw r15, 0(r6)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_stack_pop_fast_end(void) {} - -void nseel_asm_stack_peek(void) -{ - __asm__( - FUNCTION_MARKER - "fctiwz f1, f1\n" - "stfd f1, -8(r1)\n" - - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - - "lwz r14, -4(r1)\n" - "rlwinm r14, r14, 3, 0, 28\n" // slwi r14, r14, 3 -- 3 is log2(sizeof(EEL_F)) -- 28 represents 31-3 - "lwz r3, 0(r6)\n" // return the old stack pointer - - "sub r3, r3, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "and r3, r3, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "or r3, r3, r14\n" - FUNCTION_MARKER - ); -} -void nseel_asm_stack_peek_end(void) {} - - -void nseel_asm_stack_peek_top(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - "lwz r3, 0(r6)\n" // return the old stack pointer - FUNCTION_MARKER - ); -} -void nseel_asm_stack_peek_top_end(void) {} - - -void nseel_asm_stack_peek_int(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - "lwz r3, 0(r6)\n" // return the old stack pointer - - "addis r14, 0, 0xdead\n" // add manual offset - "ori r14, r14, 0xbeef\n" - "sub r3, r3, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "and r3, r3, r14\n" - - "addis r14, 0, 0xdead\n" - "ori r14, r14, 0xbeef\n" - "or r3, r3, r14\n" - FUNCTION_MARKER - ); -} -void nseel_asm_stack_peek_int_end(void) {} - -void nseel_asm_stack_exch(void) -{ - __asm__( - FUNCTION_MARKER - "addis r6, 0, 0xdead\n" - "ori r6, r6, 0xbeef\n" // r6 is stack - "lfd f1, 0(r3)\n" - "lwz r14, 0(r6)\n" - "lfd f2, 0(r14)\n" - - "stfd f1, 0(r14)\n" - "stfd f2, 0(r3)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_stack_exch_end(void) {} - - -void nseel_asm_booltofp(void) -{ - __asm__( - FUNCTION_MARKER - "cmpwi cr7, r3, 0\n" - "li r14, 0\n" - "beq cr7, 0f\n" - "addis r14, 0, 0x3f80\n" - "0:\n" - "stw r14, -8(r1)\n" - "lfs f1, -8(r1)\n" - FUNCTION_MARKER - ); -} -void nseel_asm_booltofp_end(void){ } - -void nseel_asm_fptobool(void) -{ - __asm__( - FUNCTION_MARKER - "fabs f1, f1\n" - "fcmpu cr7, f1, f31\n" - "addis r3, 0, 1\n" - "bge cr7, 0f\n" - " addis r3, 0, 0\n" - "0:\n" - FUNCTION_MARKER - :: - ); -} -void nseel_asm_fptobool_end(void){ } - diff --git a/WDL/eel2/asm-nseel-x64-macho.asm b/WDL/eel2/asm-nseel-x64-macho.asm deleted file mode 100644 index 3f10c37d..00000000 --- a/WDL/eel2/asm-nseel-x64-macho.asm +++ /dev/null @@ -1,1881 +0,0 @@ -; THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2x64.php - -%define AMD64ABI -%define EEL_F_SIZE 8 -%define TARGET_X64 -SECTION .text - - -global _nseel_asm_1pdd -_nseel_asm_1pdd: - - - mov rdi, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp] - movq xmm0, [rsp] -%ifdef AMD64ABI - mov r15, rsi - call rdi - mov rsi, r15 -%else - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - sub rsp, 16 - fstp qword [rsp] - call rdi - add rsp, 16 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_1pdd_end -_nseel_asm_1pdd_end: - - -global _nseel_asm_2pdd -_nseel_asm_2pdd: - - - mov rdi, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp+8] - fstp qword [rsp] - movq xmm1, [rsp+8] - movq xmm0, [rsp] -%ifdef AMD64ABI - mov r15, rsi - call rdi - mov rsi, r15 -%else - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - sub rsp, 16 - fstp qword [rsp+8] - fstp qword [rsp] - call rdi - add rsp, 16 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_2pdd_end -_nseel_asm_2pdd_end: - - -global _nseel_asm_2pdds -_nseel_asm_2pdds: - - - mov rax, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp] - movq xmm0, [rdi] - movq xmm1, [rsp] -%ifdef AMD64ABI - mov r15, rsi - mov r14, rdi - call rax - mov rsi, r15 - movq [r14], xmm0 - mov rax, r14 ; set return value -%else - call rax - movq [rdi], xmm0 - mov rax, rdi ; set return value -%endif - add rsp, 128 -%else - sub rsp, 8 - fstp qword [rsp] - push dword [rdi+4] ; push parameter - push dword [rdi] ; push the rest of the parameter - call rax - add rsp, 16 - fstp qword [rdi] ; store result - mov rax, rdi ; set return value -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_2pdds_end -_nseel_asm_2pdds_end: - - -global _nseel_asm_exec2 -_nseel_asm_exec2: - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_exec2_end -_nseel_asm_exec2_end: - - -global _nseel_asm_invsqrt -_nseel_asm_invsqrt: - - mov rdx, 0x5f3759df - fst dword [rsi] -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - sub rcx, rcx - fmul qword [rax] -%else - fmul qword [qword 0xFEFEFEFEFEFEFEFE] -%endif - mov ecx, dword [rsi] - sar rcx, 1 - sub rdx, rcx - mov dword [rsi], edx - fmul dword [rsi] - fmul dword [rsi] -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rax] -%else - fadd qword [qword 0xFEFEFEFEFEFEFEFE] -%endif - fmul dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_invsqrt_end -_nseel_asm_invsqrt_end: - - -global _nseel_asm_sin -_nseel_asm_sin: - - fsin -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sin_end -_nseel_asm_sin_end: - - -global _nseel_asm_cos -_nseel_asm_cos: - - fcos -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_cos_end -_nseel_asm_cos_end: - - -global _nseel_asm_tan -_nseel_asm_tan: - - fptan - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_tan_end -_nseel_asm_tan_end: - - -global _nseel_asm_sqr -_nseel_asm_sqr: - - fmul st0, st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sqr_end -_nseel_asm_sqr_end: - - -global _nseel_asm_sqrt -_nseel_asm_sqrt: - - fabs - fsqrt -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sqrt_end -_nseel_asm_sqrt_end: - - -global _nseel_asm_log -_nseel_asm_log: - - fldln2 - fxch - fyl2x -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_log_end -_nseel_asm_log_end: - - -global _nseel_asm_log10 -_nseel_asm_log10: - - fldlg2 - fxch - fyl2x - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_log10_end -_nseel_asm_log10_end: - - -global _nseel_asm_abs -_nseel_asm_abs: - - fabs -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_abs_end -_nseel_asm_abs_end: - - -global _nseel_asm_assign -_nseel_asm_assign: -%ifdef TARGET_X64 - - mov rdx, qword [rax] - mov rcx, rdx - shr rdx, 32 - and rdx, 0x7FF00000 - jz label_0 - cmp rdx, 0x7FF00000 - je label_0 - jmp label_1 -label_0: - - sub rcx, rcx -label_1: - - mov qword [rdi], rcx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov edx, dword [rax+4] - mov ecx, dword [rax] - and rdx, 0x7ff00000 - jz label_2 ; if exponent=zero, zero - cmp rdx, 0x7ff00000 - je label_2 ; if exponent=all 1s, zero - mov edx, dword [rax+4] ; reread - jmp label_3 -label_2: - - sub rcx, rcx - sub rdx, rdx -label_3: - - mov dword [rdi], ecx - mov dword [rdi+4], edx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_assign_end -_nseel_asm_assign_end: - - -global _nseel_asm_assign_fromfp -_nseel_asm_assign_fromfp: -%ifdef TARGET_X64 - - fstp qword [rdi] - mov rdx, qword [rdi] - mov r15, 0x7FF0000000000000 - and rdx, r15 - jz label_4 - cmp rdx, r15 - jne label_5 -label_4: - - sub rcx, rcx - mov qword [rdi], rcx -label_5: - - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - fstp qword [rdi] - mov edx, dword [rdi+4] - and rdx, 0x7ff00000 - jz label_6 - cmp rdx, 0x7ff00000 - jne label_7 -label_6: - - fldz - fstp qword [rdi] -label_7: - - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_assign_fromfp_end -_nseel_asm_assign_fromfp_end: - - -global _nseel_asm_assign_fast -_nseel_asm_assign_fast: -%ifdef TARGET_X64 - - mov rdx, qword [rax] - mov qword [rdi], rdx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov edx, dword [rax+4] - mov ecx, dword [rax] - mov dword [rdi], ecx - mov dword [rdi+4], edx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_assign_fast_end -_nseel_asm_assign_fast_end: - - -global _nseel_asm_add -_nseel_asm_add: - - fadd -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_add_end -_nseel_asm_add_end: - - -global _nseel_asm_add_op -_nseel_asm_add_op: - - fadd qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_add_op_end -_nseel_asm_add_op_end: - - -global _nseel_asm_sub -_nseel_asm_sub: - -%ifdef __GNUC__ - fsubr ; gnuc has fsub/fsubr backwards, ack -%else - fsub -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sub_end -_nseel_asm_sub_end: - - -global _nseel_asm_sub_op -_nseel_asm_sub_op: - - fsubr qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sub_op_end -_nseel_asm_sub_op_end: - - -global _nseel_asm_mul -_nseel_asm_mul: - - fmul -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_mul_end -_nseel_asm_mul_end: - - -global _nseel_asm_mul_op -_nseel_asm_mul_op: - - fmul qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_mul_op_end -_nseel_asm_mul_op_end: - - -global _nseel_asm_div -_nseel_asm_div: - -%ifdef __GNUC__ - fdivr ; gcc inline asm seems to have fdiv/fdivr backwards -%else - fdiv -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_div_end -_nseel_asm_div_end: - - -global _nseel_asm_div_op -_nseel_asm_div_op: - - fld qword [rdi] -%ifndef __GNUC__ - fxch ; gcc inline asm seems to have fdiv/fdivr backwards -%endif - fdiv - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_div_op_end -_nseel_asm_div_op_end: - - -global _nseel_asm_mod -_nseel_asm_mod: - - fabs - fisttp dword [rsi] - fabs - fisttp dword [rsi+4] - xor rdx, rdx -%ifdef TARGET_X64 - sub rax, rax -%endif - cmp dword [rsi], 0 - je label_8 ; skip devide, set return to 0 - mov eax, dword [rsi+4] - div dword [rsi] -label_8: - - mov dword [rsi], edx - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_mod_end -_nseel_asm_mod_end: - - -global _nseel_asm_shl -_nseel_asm_shl: - - fisttp dword [rsi] - fisttp dword [rsi+4] - mov ecx, dword [rsi] - mov eax, dword [rsi+4] - shl rax, cl - mov dword [rsi], eax - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_shl_end -_nseel_asm_shl_end: - - -global _nseel_asm_shr -_nseel_asm_shr: - - fisttp dword [rsi] - fisttp dword [rsi+4] - mov ecx, dword [rsi] - mov eax, dword [rsi+4] - sar rax, cl - mov dword [rsi], eax - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_shr_end -_nseel_asm_shr_end: - - -global _nseel_asm_mod_op -_nseel_asm_mod_op: - - fld qword [rdi] - fxch - fabs - fisttp dword [rdi] - fabs - fisttp dword [rsi] -%ifdef TARGET_X64 - sub rax, rax -%endif - xor rdx, rdx - cmp dword [rdi], 0 - je label_9 ; skip devide, set return to 0 - mov eax, dword [rsi] - div dword [rdi] -label_9: - - mov dword [rdi], edx - fild dword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_mod_op_end -_nseel_asm_mod_op_end: - - -global _nseel_asm_or -_nseel_asm_or: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - or qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - or dword [rsi], edi - or dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_or_end -_nseel_asm_or_end: - - -global _nseel_asm_or0 -_nseel_asm_or0: - - frndint -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_or0_end -_nseel_asm_or0_end: - - -global _nseel_asm_or_op -_nseel_asm_or_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - or qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - or dword [rdi], eax - or dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_or_op_end -_nseel_asm_or_op_end: - - -global _nseel_asm_xor -_nseel_asm_xor: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - xor qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - xor dword [rsi], edi - xor dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_xor_end -_nseel_asm_xor_end: - - -global _nseel_asm_xor_op -_nseel_asm_xor_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - xor qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - xor dword [rdi], eax - xor dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_xor_op_end -_nseel_asm_xor_op_end: - - -global _nseel_asm_and -_nseel_asm_and: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - and qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - and dword [rsi], edi - and dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_and_end -_nseel_asm_and_end: - - -global _nseel_asm_and_op -_nseel_asm_and_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - and qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - and dword [rdi], eax - and dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_and_op_end -_nseel_asm_and_op_end: - - -global _nseel_asm_uplus -_nseel_asm_uplus: - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_uplus_end -_nseel_asm_uplus_end: - - -global _nseel_asm_uminus -_nseel_asm_uminus: - - fchs -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_uminus_end -_nseel_asm_uminus_end: - - -global _nseel_asm_sign -_nseel_asm_sign: - - -%ifdef TARGET_X64 - - - fst qword [rsp+-8] - mov rdx, qword [rsp+-8] - mov rcx, 0x7FFFFFFFFFFFFFFF - test rdx, rcx - jz label_10 ; zero zero, return the value passed directly - ; calculate sign - inc rcx ; rcx becomes 0x80000... - fstp st0 - fld1 - test rdx, rcx - jz label_10 - fchs -label_10: - - -%else - - fst -dword [rsp+4] - mov ecx, -dword [rsp+4] - mov rdx, 0x7FFFFFFF - test rcx, rdx - jz label_11 ; zero zero, return the value passed directly - ; calculate sign - inc rdx ; edx becomes 0x8000... - fstp st0 - fld1 - test rcx, rdx - jz label_11 - fchs -label_11: - - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_sign_end -_nseel_asm_sign_end: - - -global _nseel_asm_bnot -_nseel_asm_bnot: - - test rax, rax - setz al - and rax, 0xff -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_bnot_end -_nseel_asm_bnot_end: - - -global _nseel_asm_if -_nseel_asm_if: - -%ifdef TARGET_X64 - sub rsp, 8 - test rax, rax - jz label_12 - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax - jmp label_13 -label_12: - - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax -label_13: - - add rsp, 8 -%else - sub rsp, 12 - test rax, rax - jz label_14 - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax - jmp label_15 -label_14: - - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax -label_15: - - add rsp, 12 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_if_end -_nseel_asm_if_end: - - -global _nseel_asm_repeat -_nseel_asm_repeat: - -%ifdef TARGET_X64 - fisttp qword [rsi] - mov rcx, qword [rsi] -%else - fisttp dword [rsi] - mov ecx, dword [rsi] -%endif - cmp rcx, 1 - jl label_16 - cmp rcx, 10000000 - jl label_17 - mov rcx, 10000000 -label_17: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 ; keep stack aligned to 16 byte -%else - sub rsp, 4 ; keep stack aligned to 16 byte -%endif - push rsi ; revert back to last temp workspace - push rcx - - call rdx - - pop rcx - pop rsi -%ifdef TARGET_X64 - add rsp, 8 ; keep stack aligned to 16 byte -%else - add rsp, 4 ; keep stack aligned to 16 byte -%endif - dec rcx - jnz label_17 -label_16: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_repeat_end -_nseel_asm_repeat_end: - - -global _nseel_asm_fcall -_nseel_asm_fcall: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 - call rdx - add rsp, 8 -%else - sub rsp, 12 ; keep stack 16 byte aligned, 4 bytes for return address - call rdx - add rsp, 12 -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_fcall_end -_nseel_asm_fcall_end: - - -global _nseel_asm_repeatwhile -_nseel_asm_repeatwhile: - - mov rcx, 10000000 -label_18: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - -%ifdef TARGET_X64 - sub rsp, 8 ; keep stack aligned -- required on x86 and x64 -%else - sub rsp, 4 ; keep stack aligned -- required on x86 and x64 -%endif - push rsi ; revert back to last temp workspace - push rcx - call rdx - pop rcx - pop rsi -%ifdef TARGET_X64 - add rsp, 8 ; keep stack aligned -- required on x86 and x64 -%else - add rsp, 4 ; keep stack aligned -- required on x86 and x64 -%endif - test rax, rax - jz label_19 - dec rcx - jnz label_18 -label_19: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_repeatwhile_end -_nseel_asm_repeatwhile_end: - - -global _nseel_asm_band -_nseel_asm_band: - - test rax, rax - jz label_20 - - mov rcx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 -%else - sub rsp, 12 -%endif - call rcx -%ifdef TARGET_X64 - add rsp, 8 -%else - add rsp, 12 -%endif -label_20: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_band_end -_nseel_asm_band_end: - - -global _nseel_asm_bor -_nseel_asm_bor: - - test rax, rax - jnz label_21 - - mov rcx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 -%else - sub rsp, 12 -%endif - call rcx -%ifdef TARGET_X64 - add rsp, 8 -%else - add rsp, 12 -%endif -label_21: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_bor_end -_nseel_asm_bor_end: - - -global _nseel_asm_equal -_nseel_asm_equal: - - fsub - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 ; old behavior: if 256 set, true (NaN means true) -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_equal_end -_nseel_asm_equal_end: - - -global _nseel_asm_notequal -_nseel_asm_notequal: - - fsub - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 - xor rax, 256 ; old behavior: if 256 set, FALSE (NaN makes for false) -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_notequal_end -_nseel_asm_notequal_end: - - -global _nseel_asm_above -_nseel_asm_above: - - fcompp - fstsw ax - and rax, 1280 ; (1024+256) old behavior: NaN would mean 1, preserve that -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_above_end -_nseel_asm_above_end: - - -global _nseel_asm_beloweq -_nseel_asm_beloweq: - - fcompp - fstsw ax - and rax, 256 ; old behavior: NaN would be 0 (ugh) - xor rax, 256 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_beloweq_end -_nseel_asm_beloweq_end: - - -global _nseel_asm_booltofp -_nseel_asm_booltofp: - - test rax, rax - jz label_22 - fld1 - jmp label_23 -label_22: - - fldz -label_23: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_booltofp_end -_nseel_asm_booltofp_end: - - -global _nseel_asm_fptobool -_nseel_asm_fptobool: - - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 - xor rax, 256 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_fptobool_end -_nseel_asm_fptobool_end: - - -global _nseel_asm_min -_nseel_asm_min: - - fld qword [rdi] - fcomp qword [rax] - push rax - fstsw ax - test rax, 256 - pop rax - jz label_24 - mov rax, rdi -label_24: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_min_end -_nseel_asm_min_end: - - -global _nseel_asm_max -_nseel_asm_max: - - fld qword [rdi] - fcomp qword [rax] - push rax - fstsw ax - test rax, 256 - pop rax - jnz label_25 - mov rax, rdi -label_25: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_max_end -_nseel_asm_max_end: - - -global _nseel_asm_min_fp -_nseel_asm_min_fp: - - fcom - fstsw ax - test rax, 256 - jz label_26 - fxch -label_26: - - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_min_fp_end -_nseel_asm_min_fp_end: - - -global _nseel_asm_max_fp -_nseel_asm_max_fp: - - fcom - fstsw ax - test rax, 256 - jnz label_27 - fxch -label_27: - - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _nseel_asm_max_fp_end -_nseel_asm_max_fp_end: - - -global __asm_generic3parm -__asm_generic3parm: - -%ifdef TARGET_X64 - -%ifdef AMD64ABI - - mov r15, rsi - mov rdx, rdi ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - - mov rsi, rcx ; second parameter = parm - mov rcx, rax ; fourth parameter = parm - mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rax - - mov rsi, r15 - add rsp, 128 - -%else - mov rdx, rcx ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r8, rdi ; third parameter = parm - mov r9, rax ; fourth parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif - -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - push rax ; push parameter - push rdi ; push parameter - push rcx ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic3parm_end -__asm_generic3parm_end: - - -global __asm_generic3parm_retd -__asm_generic3parm_retd: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov r15, rsi - mov rdx, rdi ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rsi, rcx ; second parameter = parm - mov rcx, rax ; fourth parameter = parm - mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rax - mov rsi, r15 -%else - mov rdx, rcx ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r8, rdi ; third parameter = parm - mov r9, rax ; fourth parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - sub rsp, 16 - mov dword [rsp+8], edi - mov rdx, qword 0xFEFEFEFEFEFEFEFE - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov dword [rsp+12], eax - mov dword [rsp+4], ecx - mov dword [rsp], edx - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic3parm_retd_end -__asm_generic3parm_retd_end: - - -global __asm_generic2parm -__asm_generic2parm: - -%ifdef TARGET_X64 - -%ifdef AMD64ABI - mov r15, rsi - mov rsi, rdi ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rax ; third parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rcx - mov rsi, r15 - add rsp, 128 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rdi ; second parameter = parm - mov r8, rax ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 4 ; keep stack aligned - push rax ; push parameter - push rdi ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic2parm_end -__asm_generic2parm_end: - - -global __asm_generic2parm_retd -__asm_generic2parm_retd: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov r15, rsi - mov rsi, rdi ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - mov rdx, rax ; third parameter = parm - sub rsp, 128 - call rcx - mov rsi, r15 -%else - mov rdx, rdi ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - mov r8, rax ; third parameter = parm - sub rsp, 128 - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - sub rsp, 16 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rsp], edx - mov dword [rsp+4], edi - mov dword [rsp+8], eax - call rcx - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic2parm_retd_end -__asm_generic2parm_retd_end: - - -global __asm_generic1parm -__asm_generic1parm: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r15, rsi - mov rsi, rax ; second parameter = parm - sub rsp, 128 - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - call rcx - mov rsi, r15 - add rsp, 128 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rax ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 8 ; keep stack aligned - push rax ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic1parm_end -__asm_generic1parm_end: - - -global __asm_generic1parm_retd -__asm_generic1parm_retd: - -%ifdef TARGET_X64 - sub rsp, 128 -%ifdef AMD64ABI - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; function address - mov r15, rsi ; save rsi - mov rsi, rax ; second parameter = parameter - - call rcx - - mov rsi, r15 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - - mov rdx, rax ; second parameter = parm - - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE ; context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; func-addr - sub rsp, 16 - mov dword [rsp+4], eax ; push parameter - mov dword [rsp], edx ; push context pointer - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_generic1parm_retd_end -__asm_generic1parm_retd_end: - - -global __asm_megabuf -__asm_megabuf: - - - -%ifdef TARGET_X64 - - -%ifdef AMD64ABI - - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - - fadd qword [rdx] - fisttp dword [rsi] - sub rdx, rdx - - ; check if (%rsi) is in range, and buffer available, otherwise call function - mov edx, dword [rsi] - test rdx, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_28 - mov rax, rdx - shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) - and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov rax, qword [rdi+rax] - test rax, rax - jz label_28 - and rdx, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdx, 3 ; log2(sizeof(EEL_F)) - add rax, rdx - jmp label_29 - - -label_28: - - mov r15, rsi ; save rsi - mov rsi, rdx ; esi becomes second parameter (edi is first, context pointer) - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdx - mov rsi, r15 ; restore rsi - add rsp, 128 -label_29: - - -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rdi, rdi - - fadd qword [rdx] - - fisttp dword [rsi] - - ; check if (%esi) is in range... - mov edi, dword [rsi] - test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_30 - mov rax, rdi - shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) - and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov rax, qword [rcx+rax] - test rax, rax - jz label_30 - and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdi, 3 ; log2(sizeof(EEL_F)) - add rax, rdi - jmp label_31 - -label_30: - - mov rdx, rdi ; rdx is second parameter (rcx is first) - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; function ptr - sub rsp, 128 - call rdi - add rsp, 128 -label_31: - -%endif - - -%else - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [qword 0xFEFEFEFEFEFEFEFE] - fisttp dword [rsi] - - ; check if (%esi) is in range, and buffer available, otherwise call function - mov edi, dword [rsi] - test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_32 - - mov rax, rdi - shr rax, 14 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void *)) - and rax, 0x1FC ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov eax, dword [rdx+rax] - test rax, rax - jz label_32 - and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdi, 3 ; log2(sizeof(EEL_F)) - add rax, rdi - jmp label_33 - - -label_32: - - sub rsp, 8 ; keep stack aligned - push rdi ; parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -label_33: - - - -%endif - - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_megabuf_end -__asm_megabuf_end: - - -global __asm_gmegabuf -__asm_gmegabuf: - - - -%ifdef TARGET_X64 - - -%ifdef AMD64ABI - - mov r15, rsi - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rdx] - fisttp dword [r15] - xor rsi, rsi - mov esi, dword [r15] ; r15 = esi (from above) - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdx - mov rsi, r15 - add rsp, 128 - -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rdx] - fisttp dword [rsi] - xor rdx, rdx - mov edx, dword [rsi] - mov rdi, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdi - add rsp, 128 -%endif - - -%else - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [qword 0xFEFEFEFEFEFEFEFE] - fisttp dword [rsi] - sub rsp, 8 ; keep stack aligned - push dword [rsi] ; parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif - - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global __asm_gmegabuf_end -__asm_gmegabuf_end: - - -global _nseel_asm_stack_push -_nseel_asm_stack_push: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rax] - mov rax, qword [rdi] - add rax, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx - mov qword [rax], rcx - mov qword [rdi], rax -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - - mov ecx, dword [rax] - mov edx, dword [rax+4] - - mov eax, dword [rdi] - - add rax, 8 - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE - - mov dword [rax], ecx - mov dword [rax+4], edx - - mov dword [rdi], eax -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_push_end -_nseel_asm_stack_push_end: - - -global _nseel_asm_stack_pop -_nseel_asm_stack_pop: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - movq xmm0, [rcx] - sub rcx, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rcx, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rcx, rdx - mov qword [rdi], rcx - movq [rax], xmm0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - fld qword [rcx] - sub rcx, 8 - and rcx, qword 0xFEFEFEFEFEFEFEFE - or rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rdi], ecx - fstp qword [rax] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_pop_end -_nseel_asm_stack_pop_end: - - -global _nseel_asm_stack_pop_fast -_nseel_asm_stack_pop_fast: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - mov rax, rcx - sub rcx, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rcx, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rcx, rdx - mov qword [rdi], rcx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - mov rax, rcx - sub rcx, 8 - and rcx, qword 0xFEFEFEFEFEFEFEFE - or rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rdi], ecx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_pop_fast_end -_nseel_asm_stack_pop_fast_end: - - -global _nseel_asm_stack_peek_int -_nseel_asm_stack_peek_int: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rax, qword [rdi] - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov eax, dword [rdi] - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rax, rdx - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_peek_int_end -_nseel_asm_stack_peek_int_end: - - -global _nseel_asm_stack_peek -_nseel_asm_stack_peek: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - fisttp dword [rsi] - mov rax, qword [rdi] - mov rdx, qword [rsi] - shl rdx, 3 ; log2(sizeof(EEL_F)) - sub rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - fisttp dword [rsi] - mov eax, dword [rdi] - mov edx, dword [rsi] - shl rdx, 3 ; log2(sizeof(EEL_F)) - sub rax, rdx - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_peek_end -_nseel_asm_stack_peek_end: - - -global _nseel_asm_stack_peek_top -_nseel_asm_stack_peek_top: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rax, qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov eax, dword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_peek_top_end -_nseel_asm_stack_peek_top_end: - - -global _nseel_asm_stack_exch -_nseel_asm_stack_exch: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - movq xmm0, [rcx] - movq xmm1, [rax] - movq [rax], xmm0 - movq [rcx], xmm1 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - fld qword [rcx] - fld qword [rax] - fstp qword [rcx] - fstp qword [rax] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global _nseel_asm_stack_exch_end -_nseel_asm_stack_exch_end: -%ifdef TARGET_X64 - - -global _win64_callcode -_win64_callcode: - -%ifdef AMD64ABI - mov rax, rdi -%else - mov rax, rcx -%endif - - push rbx - push rbp -%ifndef AMD64ABI - push rdi - push rsi - push r12 - push r13 -%endif - push r14 ; on AMD64ABI, we'll use r14/r15 to save edi/esi - push r15 - call rax - pop r15 - pop r14 -%ifndef AMD64ABI - pop r13 - pop r12 - pop rsi - pop rdi - fclex -%endif - pop rbp - pop rbx - ret -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif diff --git a/WDL/eel2/asm-nseel-x64-macho.o b/WDL/eel2/asm-nseel-x64-macho.o deleted file mode 100644 index f40f6e0b5f0d509511ab44416b5d7e5b19ed8fe8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9979 zcmbuFe{fXQ6~`YEvO#2nbqXSFEuBzJZ7sV(s6!FATD^1_tyNHpu(L^aLnO&A*(P$>VJ>%wGzT@k6-BDtl)Arh*F1Ko|-RJU@;dWk1&-L|gd#}IDvR=N(vg`*- zN$sCNDtzW2^*d`<*{6z!R@)Pa`uA%KwNfeb!fIokV|Yv5|6u)+CuV>wgA{j_JyGoE z&=HEg+Wt6qXN~H4)w1STs^Im5K8Ry7___B`33spQqZ(RItBJV5!m>Rc0s z>vBOgFs>Tkw&xB82ZN%<8VpwQTNt!IKU8se@)MQp^2LfZC&_1NULKVB;kP8oeEvxO zjAWV5AJ6yYPskFP&mXH=dqiqwUghQ}dqDO6?XzVkN7<)$O;?S5%C47IGGDm7(#*2) zB$G>$!sXJN%sXwHM-o{m^CP{IWPUi{c&^m4$(jXo=~3oK#w5x7@R!dou4^tm%KS*5 zB$*$sKd-nWI*@Yt5q`tqt)lR6fRUPoNyVMy32)Abh&Ucm$K_JpFb=~<_mLGZm!x} zbki=i=j}{T6?+SV`Junl$NA=2g$JI;tjV=Hk+^U+f>FZ=@v) zRL|=yl(sU@lN3}vyTHP0qNg#i8jPF+Yk7TQ4-t0+rpM}8irONK*Mn22^Q1)Ay z>2!ihk1}6IpRJ}J960BiwoG5;dxj8Zs|xA1rtCANTcEPvr4Gm~L-#n@WSO6mF<$}$ zkwQQk%Dm%bLbl-5(n>83Ocq{RmKM1Es$)4>>{3*x6>m&2aLKG>;5wL6)X4CS4X1~K zbRP0Gc(;|FtL%Q&dvvy1beevdtjg8Y(BjN~x-<)`?Y}zy-*>LnWBe@X9 z)77+oIiNC6R!+21i|Gq^?hMN{6%SMy-;$Ba(I+sVW;loJIdiqJzvN5J>{oW3vMbKB z^j1$l6sD=3G1K3G^fy2^Px|pv@$m3Cq@6Yue{yVOUiu1%Ml{ME8r_xlGGFpVV@;z* z^URZUey+%oj3M)-cq-=%EDdfQ4;(!+J;I)2bNI0PYC|Gd(~y{LU6inIY^ce1G}PR_ zCUQq)O=NB4&QV`XCaGY>aG(+`VCa{)-LtonXt?24-1Skj}L?2{`4!t$c`5 zIs*O~cnrLpe{fSe0sb|39DG%cTR)Ay*X;lM;F;jP;ETauqYnV5`QYEzy8JotBK|Q> z=_+styac=jyaN0%_$KgC@U7rEyih6K1-=;^1MdXi16DI#eH#1?@DA`Z;630$@DIU7 z@T1@>FLeDq1sB;X>g;#5wMPTE$P_)ljx5Ee+xVxtlN8qp(j(v-Wd$~<6>|V z3Kki>6s-U1W|hI;1|Ot1r`KqmaQi;Q{J#edP(L^wr#h~mhy8FC90HHho9jOU^P9O2 z`-A_YO7bP(n^E6r@b%yX>Yt;1!uIpAKlXuFg5NQC6x@OOdbCHkcOf{9_Wlz54)}Gj z?oTK91=Q!jTE7ge{e9EWUxo4f6vlTs_;&D^G2Umvi!uIf)DQ0eAo{Znd=`8O)~D8A z0bUFHTa9=d!9PI!1>~FkC+Xqz1+Wd?Pi0)c4E#s%8t_6o*PMEsZ;QdVfp0K)4ftWy z^Et-$x;@_kzlioF5l^qz-Qd5|o6|vz$5Uj-=|k`V@JeGmc-%SO{TQE|F`kcuZ-o6L zf!li&}*hrqMxT;RkP4vweK zqs?I5pL@aD-}7MYuNSQSZ8qlPUT`1gX8^o__7$f;f$sz#!hRjWe*FuWuYsJ#4W0%2 zW$^!~G2hRD^?5XI#G8-(eIMdq34RwUE-@gUx^)wFF>uC$IHQUPrdeq;mT0 z@A8y|4GnWSOFE!lsmR1UJ_t<(b;A>7OLrNCr=#3)Q`3=blU@kRC_;-3O=z*H ziZy$BMCenb)9r1ZPQ{#(^15iEJK32?$+(ca6_u=F=}Z;VQf(FcaxvM^Sh+Fp;wCJk zh$g*VAWIjgk=;)Y!>-rqtuKoicQa**$x?-u#Ccp%_4v7 z*7mK^6QSvei@YP~mYBNEq~}l}G!^Mho>mk372f@{$+w@_t+zF9iRmfnag_A=Np^eo z6QSRO5r~}l$8Wng5TWUZi@Ys%OH5tNdngl@Q5c?B7q`UJC0b$~o^|9Dm@3zH+otx8xC|?b zO^aq@0+@Xo?`${wXFI+n8}qczDKP!e@c4wf%+$u3lUqG~a0*OSbG#$DExtwe6-7Q} zGTD(ydXM#Hl$qK@DwE_o=~kDST3S3(M(9(-wtEz@?LGw=d0WPA628;AlS~brQ{wt_ zEf5{mjjp0}vve+H(Ns3QNlt31w1VDy6hiJl!%7vt z&mvz2qbV{e`&D*p&#kaSV88t3- z_1oIJnwCWQpleCC#;uMR?d9lVyhC_jgZC1=m*U-o_cFY{g7>v}(@oNK7z*o*b`{b# qA?+ljtwY*8tj)u^Az|$&to?*_o5H$LVeK%iLxi>Gu=ae-V(Y*9^pnB> diff --git a/WDL/eel2/asm-nseel-x64.asm b/WDL/eel2/asm-nseel-x64.asm deleted file mode 100644 index 429352f8..00000000 --- a/WDL/eel2/asm-nseel-x64.asm +++ /dev/null @@ -1,1880 +0,0 @@ -; THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2x64.php - -%define EEL_F_SIZE 8 -%define TARGET_X64 -SECTION .text - - -global nseel_asm_1pdd -nseel_asm_1pdd: - - - mov rdi, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp] - movq xmm0, [rsp] -%ifdef AMD64ABI - mov r15, rsi - call rdi - mov rsi, r15 -%else - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - sub rsp, 16 - fstp qword [rsp] - call rdi - add rsp, 16 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_1pdd_end -nseel_asm_1pdd_end: - - -global nseel_asm_2pdd -nseel_asm_2pdd: - - - mov rdi, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp+8] - fstp qword [rsp] - movq xmm1, [rsp+8] - movq xmm0, [rsp] -%ifdef AMD64ABI - mov r15, rsi - call rdi - mov rsi, r15 -%else - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - sub rsp, 16 - fstp qword [rsp+8] - fstp qword [rsp] - call rdi - add rsp, 16 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_2pdd_end -nseel_asm_2pdd_end: - - -global nseel_asm_2pdds -nseel_asm_2pdds: - - - mov rax, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 128 - fstp qword [rsp] - movq xmm0, [rdi] - movq xmm1, [rsp] -%ifdef AMD64ABI - mov r15, rsi - mov r14, rdi - call rax - mov rsi, r15 - movq [r14], xmm0 - mov rax, r14 ; set return value -%else - call rax - movq [rdi], xmm0 - mov rax, rdi ; set return value -%endif - add rsp, 128 -%else - sub rsp, 8 - fstp qword [rsp] - push dword [rdi+4] ; push parameter - push dword [rdi] ; push the rest of the parameter - call rax - add rsp, 16 - fstp qword [rdi] ; store result - mov rax, rdi ; set return value -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_2pdds_end -nseel_asm_2pdds_end: - - -global nseel_asm_exec2 -nseel_asm_exec2: - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_exec2_end -nseel_asm_exec2_end: - - -global nseel_asm_invsqrt -nseel_asm_invsqrt: - - mov rdx, 0x5f3759df - fst dword [rsi] -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - sub rcx, rcx - fmul qword [rax] -%else - fmul qword [qword 0xFEFEFEFEFEFEFEFE] -%endif - mov ecx, dword [rsi] - sar rcx, 1 - sub rdx, rcx - mov dword [rsi], edx - fmul dword [rsi] - fmul dword [rsi] -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rax] -%else - fadd qword [qword 0xFEFEFEFEFEFEFEFE] -%endif - fmul dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_invsqrt_end -nseel_asm_invsqrt_end: - - -global nseel_asm_sin -nseel_asm_sin: - - fsin -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sin_end -nseel_asm_sin_end: - - -global nseel_asm_cos -nseel_asm_cos: - - fcos -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_cos_end -nseel_asm_cos_end: - - -global nseel_asm_tan -nseel_asm_tan: - - fptan - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_tan_end -nseel_asm_tan_end: - - -global nseel_asm_sqr -nseel_asm_sqr: - - fmul st0, st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sqr_end -nseel_asm_sqr_end: - - -global nseel_asm_sqrt -nseel_asm_sqrt: - - fabs - fsqrt -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sqrt_end -nseel_asm_sqrt_end: - - -global nseel_asm_log -nseel_asm_log: - - fldln2 - fxch - fyl2x -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_log_end -nseel_asm_log_end: - - -global nseel_asm_log10 -nseel_asm_log10: - - fldlg2 - fxch - fyl2x - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_log10_end -nseel_asm_log10_end: - - -global nseel_asm_abs -nseel_asm_abs: - - fabs -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_abs_end -nseel_asm_abs_end: - - -global nseel_asm_assign -nseel_asm_assign: -%ifdef TARGET_X64 - - mov rdx, qword [rax] - mov rcx, rdx - shr rdx, 32 - and rdx, 0x7FF00000 - jz label_0 - cmp rdx, 0x7FF00000 - je label_0 - jmp label_1 -label_0: - - sub rcx, rcx -label_1: - - mov qword [rdi], rcx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov edx, dword [rax+4] - mov ecx, dword [rax] - and rdx, 0x7ff00000 - jz label_2 ; if exponent=zero, zero - cmp rdx, 0x7ff00000 - je label_2 ; if exponent=all 1s, zero - mov edx, dword [rax+4] ; reread - jmp label_3 -label_2: - - sub rcx, rcx - sub rdx, rdx -label_3: - - mov dword [rdi], ecx - mov dword [rdi+4], edx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_assign_end -nseel_asm_assign_end: - - -global nseel_asm_assign_fromfp -nseel_asm_assign_fromfp: -%ifdef TARGET_X64 - - fstp qword [rdi] - mov rdx, qword [rdi] - mov r15, 0x7FF0000000000000 - and rdx, r15 - jz label_4 - cmp rdx, r15 - jne label_5 -label_4: - - sub rcx, rcx - mov qword [rdi], rcx -label_5: - - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - fstp qword [rdi] - mov edx, dword [rdi+4] - and rdx, 0x7ff00000 - jz label_6 - cmp rdx, 0x7ff00000 - jne label_7 -label_6: - - fldz - fstp qword [rdi] -label_7: - - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_assign_fromfp_end -nseel_asm_assign_fromfp_end: - - -global nseel_asm_assign_fast -nseel_asm_assign_fast: -%ifdef TARGET_X64 - - mov rdx, qword [rax] - mov qword [rdi], rdx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov edx, dword [rax+4] - mov ecx, dword [rax] - mov dword [rdi], ecx - mov dword [rdi+4], edx - mov rax, rdi -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_assign_fast_end -nseel_asm_assign_fast_end: - - -global nseel_asm_add -nseel_asm_add: - - fadd -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_add_end -nseel_asm_add_end: - - -global nseel_asm_add_op -nseel_asm_add_op: - - fadd qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_add_op_end -nseel_asm_add_op_end: - - -global nseel_asm_sub -nseel_asm_sub: - -%ifdef __GNUC__ - fsubr ; gnuc has fsub/fsubr backwards, ack -%else - fsub -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sub_end -nseel_asm_sub_end: - - -global nseel_asm_sub_op -nseel_asm_sub_op: - - fsubr qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sub_op_end -nseel_asm_sub_op_end: - - -global nseel_asm_mul -nseel_asm_mul: - - fmul -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_mul_end -nseel_asm_mul_end: - - -global nseel_asm_mul_op -nseel_asm_mul_op: - - fmul qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_mul_op_end -nseel_asm_mul_op_end: - - -global nseel_asm_div -nseel_asm_div: - -%ifdef __GNUC__ - fdivr ; gcc inline asm seems to have fdiv/fdivr backwards -%else - fdiv -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_div_end -nseel_asm_div_end: - - -global nseel_asm_div_op -nseel_asm_div_op: - - fld qword [rdi] -%ifndef __GNUC__ - fxch ; gcc inline asm seems to have fdiv/fdivr backwards -%endif - fdiv - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_div_op_end -nseel_asm_div_op_end: - - -global nseel_asm_mod -nseel_asm_mod: - - fabs - fisttp dword [rsi] - fabs - fisttp dword [rsi+4] - xor rdx, rdx -%ifdef TARGET_X64 - sub rax, rax -%endif - cmp dword [rsi], 0 - je label_8 ; skip devide, set return to 0 - mov eax, dword [rsi+4] - div dword [rsi] -label_8: - - mov dword [rsi], edx - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_mod_end -nseel_asm_mod_end: - - -global nseel_asm_shl -nseel_asm_shl: - - fisttp dword [rsi] - fisttp dword [rsi+4] - mov ecx, dword [rsi] - mov eax, dword [rsi+4] - shl rax, cl - mov dword [rsi], eax - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_shl_end -nseel_asm_shl_end: - - -global nseel_asm_shr -nseel_asm_shr: - - fisttp dword [rsi] - fisttp dword [rsi+4] - mov ecx, dword [rsi] - mov eax, dword [rsi+4] - sar rax, cl - mov dword [rsi], eax - fild dword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_shr_end -nseel_asm_shr_end: - - -global nseel_asm_mod_op -nseel_asm_mod_op: - - fld qword [rdi] - fxch - fabs - fisttp dword [rdi] - fabs - fisttp dword [rsi] -%ifdef TARGET_X64 - sub rax, rax -%endif - xor rdx, rdx - cmp dword [rdi], 0 - je label_9 ; skip devide, set return to 0 - mov eax, dword [rsi] - div dword [rdi] -label_9: - - mov dword [rdi], edx - fild dword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_mod_op_end -nseel_asm_mod_op_end: - - -global nseel_asm_or -nseel_asm_or: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - or qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - or dword [rsi], edi - or dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_or_end -nseel_asm_or_end: - - -global nseel_asm_or0 -nseel_asm_or0: - - frndint -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_or0_end -nseel_asm_or0_end: - - -global nseel_asm_or_op -nseel_asm_or_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - or qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - or dword [rdi], eax - or dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_or_op_end -nseel_asm_or_op_end: - - -global nseel_asm_xor -nseel_asm_xor: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - xor qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - xor dword [rsi], edi - xor dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_xor_end -nseel_asm_xor_end: - - -global nseel_asm_xor_op -nseel_asm_xor_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - xor qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - xor dword [rdi], eax - xor dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_xor_op_end -nseel_asm_xor_op_end: - - -global nseel_asm_and -nseel_asm_and: - - fisttp qword [rsi] - fisttp qword [rsi+8] -%ifdef TARGET_X64 - mov rdi, qword [rsi+8] - and qword [rsi], rdi -%else - mov edi, dword [rsi+8] - mov ecx, dword [rsi+12] - and dword [rsi], edi - and dword [rsi+4], ecx -%endif - fild qword [rsi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_and_end -nseel_asm_and_end: - - -global nseel_asm_and_op -nseel_asm_and_op: - - fld qword [rdi] - fxch - fisttp qword [rdi] - fisttp qword [rsi] -%ifdef TARGET_X64 - mov rax, qword [rsi] - and qword [rdi], rax -%else - mov eax, dword [rsi] - mov ecx, dword [rsi+4] - and dword [rdi], eax - and dword [rdi+4], ecx -%endif - fild qword [rdi] - mov rax, rdi - fstp qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_and_op_end -nseel_asm_and_op_end: - - -global nseel_asm_uplus -nseel_asm_uplus: - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_uplus_end -nseel_asm_uplus_end: - - -global nseel_asm_uminus -nseel_asm_uminus: - - fchs -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_uminus_end -nseel_asm_uminus_end: - - -global nseel_asm_sign -nseel_asm_sign: - - -%ifdef TARGET_X64 - - - fst qword [rsp+-8] - mov rdx, qword [rsp+-8] - mov rcx, 0x7FFFFFFFFFFFFFFF - test rdx, rcx - jz label_10 ; zero zero, return the value passed directly - ; calculate sign - inc rcx ; rcx becomes 0x80000... - fstp st0 - fld1 - test rdx, rcx - jz label_10 - fchs -label_10: - - -%else - - fst -dword [rsp+4] - mov ecx, -dword [rsp+4] - mov rdx, 0x7FFFFFFF - test rcx, rdx - jz label_11 ; zero zero, return the value passed directly - ; calculate sign - inc rdx ; edx becomes 0x8000... - fstp st0 - fld1 - test rcx, rdx - jz label_11 - fchs -label_11: - - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_sign_end -nseel_asm_sign_end: - - -global nseel_asm_bnot -nseel_asm_bnot: - - test rax, rax - setz al - and rax, 0xff -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_bnot_end -nseel_asm_bnot_end: - - -global nseel_asm_if -nseel_asm_if: - -%ifdef TARGET_X64 - sub rsp, 8 - test rax, rax - jz label_12 - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax - jmp label_13 -label_12: - - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax -label_13: - - add rsp, 8 -%else - sub rsp, 12 - test rax, rax - jz label_14 - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax - jmp label_15 -label_14: - - mov rax, qword 0xFEFEFEFEFEFEFEFE - call rax -label_15: - - add rsp, 12 -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_if_end -nseel_asm_if_end: - - -global nseel_asm_repeat -nseel_asm_repeat: - -%ifdef TARGET_X64 - fisttp qword [rsi] - mov rcx, qword [rsi] -%else - fisttp dword [rsi] - mov ecx, dword [rsi] -%endif - cmp rcx, 1 - jl label_16 - cmp rcx, 10000000 - jl label_17 - mov rcx, 10000000 -label_17: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 ; keep stack aligned to 16 byte -%else - sub rsp, 4 ; keep stack aligned to 16 byte -%endif - push rsi ; revert back to last temp workspace - push rcx - - call rdx - - pop rcx - pop rsi -%ifdef TARGET_X64 - add rsp, 8 ; keep stack aligned to 16 byte -%else - add rsp, 4 ; keep stack aligned to 16 byte -%endif - dec rcx - jnz label_17 -label_16: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_repeat_end -nseel_asm_repeat_end: - - -global nseel_asm_fcall -nseel_asm_fcall: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 - call rdx - add rsp, 8 -%else - sub rsp, 12 ; keep stack 16 byte aligned, 4 bytes for return address - call rdx - add rsp, 12 -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_fcall_end -nseel_asm_fcall_end: - - -global nseel_asm_repeatwhile -nseel_asm_repeatwhile: - - mov rcx, 10000000 -label_18: - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - -%ifdef TARGET_X64 - sub rsp, 8 ; keep stack aligned -- required on x86 and x64 -%else - sub rsp, 4 ; keep stack aligned -- required on x86 and x64 -%endif - push rsi ; revert back to last temp workspace - push rcx - call rdx - pop rcx - pop rsi -%ifdef TARGET_X64 - add rsp, 8 ; keep stack aligned -- required on x86 and x64 -%else - add rsp, 4 ; keep stack aligned -- required on x86 and x64 -%endif - test rax, rax - jz label_19 - dec rcx - jnz label_18 -label_19: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_repeatwhile_end -nseel_asm_repeatwhile_end: - - -global nseel_asm_band -nseel_asm_band: - - test rax, rax - jz label_20 - - mov rcx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 -%else - sub rsp, 12 -%endif - call rcx -%ifdef TARGET_X64 - add rsp, 8 -%else - add rsp, 12 -%endif -label_20: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_band_end -nseel_asm_band_end: - - -global nseel_asm_bor -nseel_asm_bor: - - test rax, rax - jnz label_21 - - mov rcx, qword 0xFEFEFEFEFEFEFEFE -%ifdef TARGET_X64 - sub rsp, 8 -%else - sub rsp, 12 -%endif - call rcx -%ifdef TARGET_X64 - add rsp, 8 -%else - add rsp, 12 -%endif -label_21: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_bor_end -nseel_asm_bor_end: - - -global nseel_asm_equal -nseel_asm_equal: - - fsub - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 ; old behavior: if 256 set, true (NaN means true) -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_equal_end -nseel_asm_equal_end: - - -global nseel_asm_notequal -nseel_asm_notequal: - - fsub - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 - xor rax, 256 ; old behavior: if 256 set, FALSE (NaN makes for false) -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_notequal_end -nseel_asm_notequal_end: - - -global nseel_asm_above -nseel_asm_above: - - fcompp - fstsw ax - and rax, 1280 ; (1024+256) old behavior: NaN would mean 1, preserve that -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_above_end -nseel_asm_above_end: - - -global nseel_asm_beloweq -nseel_asm_beloweq: - - fcompp - fstsw ax - and rax, 256 ; old behavior: NaN would be 0 (ugh) - xor rax, 256 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_beloweq_end -nseel_asm_beloweq_end: - - -global nseel_asm_booltofp -nseel_asm_booltofp: - - test rax, rax - jz label_22 - fld1 - jmp label_23 -label_22: - - fldz -label_23: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_booltofp_end -nseel_asm_booltofp_end: - - -global nseel_asm_fptobool -nseel_asm_fptobool: - - fabs -%ifdef TARGET_X64 - mov rax, qword 0xFEFEFEFEFEFEFEFE - fcomp qword [rax] ; [g_closefact] -%else - fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] -%endif - fstsw ax - and rax, 256 - xor rax, 256 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_fptobool_end -nseel_asm_fptobool_end: - - -global nseel_asm_min -nseel_asm_min: - - fld qword [rdi] - fcomp qword [rax] - push rax - fstsw ax - test rax, 256 - pop rax - jz label_24 - mov rax, rdi -label_24: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_min_end -nseel_asm_min_end: - - -global nseel_asm_max -nseel_asm_max: - - fld qword [rdi] - fcomp qword [rax] - push rax - fstsw ax - test rax, 256 - pop rax - jnz label_25 - mov rax, rdi -label_25: - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_max_end -nseel_asm_max_end: - - -global nseel_asm_min_fp -nseel_asm_min_fp: - - fcom - fstsw ax - test rax, 256 - jz label_26 - fxch -label_26: - - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_min_fp_end -nseel_asm_min_fp_end: - - -global nseel_asm_max_fp -nseel_asm_max_fp: - - fcom - fstsw ax - test rax, 256 - jnz label_27 - fxch -label_27: - - fstp st0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global nseel_asm_max_fp_end -nseel_asm_max_fp_end: - - -global _asm_generic3parm -_asm_generic3parm: - -%ifdef TARGET_X64 - -%ifdef AMD64ABI - - mov r15, rsi - mov rdx, rdi ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - - mov rsi, rcx ; second parameter = parm - mov rcx, rax ; fourth parameter = parm - mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rax - - mov rsi, r15 - add rsp, 128 - -%else - mov rdx, rcx ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r8, rdi ; third parameter = parm - mov r9, rax ; fourth parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif - -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - push rax ; push parameter - push rdi ; push parameter - push rcx ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic3parm_end -_asm_generic3parm_end: - - -global _asm_generic3parm_retd -_asm_generic3parm_retd: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov r15, rsi - mov rdx, rdi ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rsi, rcx ; second parameter = parm - mov rcx, rax ; fourth parameter = parm - mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rax - mov rsi, r15 -%else - mov rdx, rcx ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r8, rdi ; third parameter = parm - mov r9, rax ; fourth parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - sub rsp, 16 - mov dword [rsp+8], edi - mov rdx, qword 0xFEFEFEFEFEFEFEFE - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov dword [rsp+12], eax - mov dword [rsp+4], ecx - mov dword [rsp], edx - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic3parm_retd_end -_asm_generic3parm_retd_end: - - -global _asm_generic2parm -_asm_generic2parm: - -%ifdef TARGET_X64 - -%ifdef AMD64ABI - mov r15, rsi - mov rsi, rdi ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rax ; third parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rcx - mov rsi, r15 - add rsp, 128 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rdi ; second parameter = parm - mov r8, rax ; third parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 4 ; keep stack aligned - push rax ; push parameter - push rdi ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic2parm_end -_asm_generic2parm_end: - - -global _asm_generic2parm_retd -_asm_generic2parm_retd: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov r15, rsi - mov rsi, rdi ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - mov rdx, rax ; third parameter = parm - sub rsp, 128 - call rcx - mov rsi, r15 -%else - mov rdx, rdi ; second parameter = parm - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - mov r8, rax ; third parameter = parm - sub rsp, 128 - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - sub rsp, 16 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rsp], edx - mov dword [rsp+4], edi - mov dword [rsp+8], eax - call rcx - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic2parm_retd_end -_asm_generic2parm_retd_end: - - -global _asm_generic1parm -_asm_generic1parm: - -%ifdef TARGET_X64 -%ifdef AMD64ABI - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov r15, rsi - mov rsi, rax ; second parameter = parm - sub rsp, 128 - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function - call rcx - mov rsi, r15 - add rsp, 128 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdx, rax ; second parameter = parm - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - sub rsp, 128 - call rdi - add rsp, 128 -%endif -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 8 ; keep stack aligned - push rax ; push parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic1parm_end -_asm_generic1parm_end: - - -global _asm_generic1parm_retd -_asm_generic1parm_retd: - -%ifdef TARGET_X64 - sub rsp, 128 -%ifdef AMD64ABI - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; function address - mov r15, rsi ; save rsi - mov rsi, rax ; second parameter = parameter - - call rcx - - mov rsi, r15 -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function - - mov rdx, rax ; second parameter = parm - - call rdi -%endif - movq [rsp], xmm0 - fld qword [rsp] - add rsp, 128 -%else - - mov rdx, qword 0xFEFEFEFEFEFEFEFE ; context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; func-addr - sub rsp, 16 - mov dword [rsp+4], eax ; push parameter - mov dword [rsp], edx ; push context pointer - call rdi - add rsp, 16 - -%endif -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_generic1parm_retd_end -_asm_generic1parm_retd_end: - - -global _asm_megabuf -_asm_megabuf: - - - -%ifdef TARGET_X64 - - -%ifdef AMD64ABI - - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - - mov rdx, qword 0xFEFEFEFEFEFEFEFE - - fadd qword [rdx] - fisttp dword [rsi] - sub rdx, rdx - - ; check if (%rsi) is in range, and buffer available, otherwise call function - mov edx, dword [rsi] - test rdx, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_28 - mov rax, rdx - shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) - and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov rax, qword [rdi+rax] - test rax, rax - jz label_28 - and rdx, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdx, 3 ; log2(sizeof(EEL_F)) - add rax, rdx - jmp label_29 - - -label_28: - - mov r15, rsi ; save rsi - mov rsi, rdx ; esi becomes second parameter (edi is first, context pointer) - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdx - mov rsi, r15 ; restore rsi - add rsp, 128 -label_29: - - -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rdi, rdi - - fadd qword [rdx] - - fisttp dword [rsi] - - ; check if (%esi) is in range... - mov edi, dword [rsi] - test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_30 - mov rax, rdi - shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) - and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov rax, qword [rcx+rax] - test rax, rax - jz label_30 - and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdi, 3 ; log2(sizeof(EEL_F)) - add rax, rdi - jmp label_31 - -label_30: - - mov rdx, rdi ; rdx is second parameter (rcx is first) - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; function ptr - sub rsp, 128 - call rdi - add rsp, 128 -label_31: - -%endif - - -%else - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [qword 0xFEFEFEFEFEFEFEFE] - fisttp dword [rsi] - - ; check if (%esi) is in range, and buffer available, otherwise call function - mov edi, dword [rsi] - test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) - jnz label_32 - - mov rax, rdi - shr rax, 14 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void *)) - and rax, 0x1FC ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) - mov eax, dword [rdx+rax] - test rax, rax - jz label_32 - and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) - shl rdi, 3 ; log2(sizeof(EEL_F)) - add rax, rdi - jmp label_33 - - -label_32: - - sub rsp, 8 ; keep stack aligned - push rdi ; parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -label_33: - - - -%endif - - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_megabuf_end -_asm_megabuf_end: - - -global _asm_gmegabuf -_asm_gmegabuf: - - - -%ifdef TARGET_X64 - - -%ifdef AMD64ABI - - mov r15, rsi - mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rdx] - fisttp dword [r15] - xor rsi, rsi - mov esi, dword [r15] ; r15 = esi (from above) - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdx - mov rsi, r15 - add rsp, 128 - -%else - mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [rdx] - fisttp dword [rsi] - xor rdx, rdx - mov edx, dword [rsi] - mov rdi, qword 0xFEFEFEFEFEFEFEFE - sub rsp, 128 - call rdi - add rsp, 128 -%endif - - -%else - mov rdx, qword 0xFEFEFEFEFEFEFEFE - fadd qword [qword 0xFEFEFEFEFEFEFEFE] - fisttp dword [rsi] - sub rsp, 8 ; keep stack aligned - push dword [rsi] ; parameter - push rdx ; push context pointer - mov rdi, qword 0xFEFEFEFEFEFEFEFE - call rdi - add rsp, 16 - -%endif - - - -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 - - -global _asm_gmegabuf_end -_asm_gmegabuf_end: - - -global nseel_asm_stack_push -nseel_asm_stack_push: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rax] - mov rax, qword [rdi] - add rax, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx - mov qword [rax], rcx - mov qword [rdi], rax -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - - mov ecx, dword [rax] - mov edx, dword [rax+4] - - mov eax, dword [rdi] - - add rax, 8 - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE - - mov dword [rax], ecx - mov dword [rax+4], edx - - mov dword [rdi], eax -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_push_end -nseel_asm_stack_push_end: - - -global nseel_asm_stack_pop -nseel_asm_stack_pop: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - movq xmm0, [rcx] - sub rcx, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rcx, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rcx, rdx - mov qword [rdi], rcx - movq [rax], xmm0 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - fld qword [rcx] - sub rcx, 8 - and rcx, qword 0xFEFEFEFEFEFEFEFE - or rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rdi], ecx - fstp qword [rax] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_pop_end -nseel_asm_stack_pop_end: - - -global nseel_asm_stack_pop_fast -nseel_asm_stack_pop_fast: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - mov rax, rcx - sub rcx, 8 - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rcx, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rcx, rdx - mov qword [rdi], rcx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - mov rax, rcx - sub rcx, 8 - and rcx, qword 0xFEFEFEFEFEFEFEFE - or rcx, qword 0xFEFEFEFEFEFEFEFE - mov dword [rdi], ecx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_pop_fast_end -nseel_asm_stack_pop_fast_end: - - -global nseel_asm_stack_peek_int -nseel_asm_stack_peek_int: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rax, qword [rdi] - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov eax, dword [rdi] - mov rdx, qword 0xFEFEFEFEFEFEFEFE - sub rax, rdx - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_peek_int_end -nseel_asm_stack_peek_int_end: - - -global nseel_asm_stack_peek -nseel_asm_stack_peek: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - fisttp dword [rsi] - mov rax, qword [rdi] - mov rdx, qword [rsi] - shl rdx, 3 ; log2(sizeof(EEL_F)) - sub rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - and rax, rdx - mov rdx, qword 0xFEFEFEFEFEFEFEFE - or rax, rdx -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - fisttp dword [rsi] - mov eax, dword [rdi] - mov edx, dword [rsi] - shl rdx, 3 ; log2(sizeof(EEL_F)) - sub rax, rdx - and rax, qword 0xFEFEFEFEFEFEFEFE - or rax, qword 0xFEFEFEFEFEFEFEFE -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_peek_end -nseel_asm_stack_peek_end: - - -global nseel_asm_stack_peek_top -nseel_asm_stack_peek_top: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rax, qword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov eax, dword [rdi] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_peek_top_end -nseel_asm_stack_peek_top_end: - - -global nseel_asm_stack_exch -nseel_asm_stack_exch: -%ifdef TARGET_X64 - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov rcx, qword [rdi] - movq xmm0, [rcx] - movq xmm1, [rax] - movq [rax], xmm0 - movq [rcx], xmm1 -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%else - - mov rdi, qword 0xFEFEFEFEFEFEFEFE - mov ecx, dword [rdi] - fld qword [rcx] - fld qword [rax] - fstp qword [rcx] - fstp qword [rax] -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif - - -global nseel_asm_stack_exch_end -nseel_asm_stack_exch_end: -%ifdef TARGET_X64 - - -global win64_callcode -win64_callcode: - -%ifdef AMD64ABI - mov rax, rdi -%else - mov rax, rcx -%endif - - push rbx - push rbp -%ifndef AMD64ABI - push rdi - push rsi - push r12 - push r13 -%endif - push r14 ; on AMD64ABI, we'll use r14/r15 to save edi/esi - push r15 - call rax - pop r15 - pop r14 -%ifndef AMD64ABI - pop r13 - pop r12 - pop rsi - pop rdi - fclex -%endif - pop rbp - pop rbx - ret -db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 -%endif diff --git a/WDL/eel2/asm-nseel-x64.obj b/WDL/eel2/asm-nseel-x64.obj deleted file mode 100644 index a9c13738826fc63684235bf48f2c5e19b54b1beb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9975 zcmbuDe{56N6~|vlNCE>VTct2DM4?J5p_Meh2p}P7CfF`x;>T!1D`;FNu@es`Hn9!S zgc_p3rYBb$t2%_%twP(RcGdPz*G+(`m9T0fteX;;XiVaSpskRJwv0_{h^Bbo``%05 zIrrL53QvlB&gXv5x##|P_q~_a@8%h!yZ7#y_87)*4g0E$`MYC|Eq^YeZ4-W_X69OD z?0&&K>0aX9Y3E9<{CCNVg`)S)DrnOmh~D?45h%GEUTdi z89Xy}44{A_VNN>bB=!}E-iwA&YKY#OhHp0a?TO>+_IVk%6xhmu0VEKCT#hQL$me43_ryk9= zvNCv%#f2pGD9uJ~tF~p3P)P03KI&0>L~gw7mCaR_6HYTydvt<&)E;^A;rg}1X+~;~ z_EV4ABP9>j@92G+jM}N9WdG>>hf1CtANJsHXMw1`(z{vSu(5@SuNHh-Z3lLS1yQ(G!~6!q&A*A#b|~!_IdZ%PY+Bik#zP6 zksiPUNeXE!wdEq=A$C6xnxpkFj-5Jf99=BV$zOSi^D_@Ur_07Y=_}7QIcY_@Kc1rb zsI7&jugp=+yt~D)7s|e~K6d29EEngL+S7w`6>#E0`~kv7Cz9h0BL~VSUmd$4Dhx~} zod;^`O0h1dK53_1m?NblL9e-U$vG)X-kw;1WleretD?3#lH55{MI&DnW}htbmvS7! zycEmF2}(0kJA*!+OFuL?n;N%FfA;qbB8=x03iGnNFSeVL+s!`r^>F5OZsxU;mQL-@ zlw^)~Q+Jb^Q`^l84^qsOJ0dq+=K5@J$)u8tZXPuWod;@XszI0+)$rW2(J->Ld~(>6 z*erT+{2eo*W!Oxj@AgtrF_~`|+YfL_v9Asj(zrZY?iJhRO@} zKGX1Y!!r$y4g2;rZa4py9&GZyI()Oi+tAeTe8Yj~_a~ny$0n4~f2a%uLw*?Yn#N9S z%kxD$)^*h-8#J(+%Sh z{K=P2mprbKbs)!?MlcfcHTy%}Dr4Bu*nK?R!sBEm$WNK3N+X*=&N0nyjWmH=WtxaadO$v5nwK?l24pD~3O~+z zy`_x^BF#va!v(ClYX1@Jgo4)SfLsnf_;Kwe>* zrx~$(UuXQu(clM{A3s+efPF=F?=(P(ru_H4Wk%|RCRjz;=He#kV}HF6u|*Gw~|k;Q1g&NM4E@&t%cNJqL^ zBfCJ>GEJ*Sx;kys44%Ag7t;uNoNxd5dZO!-zfe)m1kfjXm@E@b0jv zGL2M#lorw1*uaRBxn`rI$u}HQyKR=pJ--c6&$2v?j5ty2Ps~O+r2dUrBJ;E%>TQnLp!qtBdPyU4&40i&Z)@bwAlI4ZLygEaU-3D*rXGxv zlM0Ylrg=&u-vs$N)3j@(2jn)>{Fo7YHfpO^;J;e--QpR7ZZxnBJq_tIXz5Y&$YPdqW85B{HL`tHH#^3F4 zsUaH6S2V%S!_h-sF`{yaqHAq#^S1e8(U`C0U?kQ>^h%2o7Y%k2Ej*>YB}_*FPic?& zXgoZn9mUi9hr0B3IygC2MG*?Okqq$k_UbCGsIF2p_@E>Tcxrnz8f>Ej@mV0F${Xkk zcLX9dpDng|mKa|&mOapI%pRSgKN-gNrH^e~czU}x%u0tO9LcEi29TfjYD*v{_qI|Dm{#R%Q804$Oxtn?Z`w z*Bm}fE4O?_ga62dkN6Lf@i|1*g~Op(m>tE<4pNkXNGvRyNXi+cD6v0?2%g&R>!$6# zZnYf|tRk5rpq{WDh~p{?Sh=iMkT!p(zbn{M8}W5@7#hi}^LF`Ttr^4;YY{bCW{YIj z>6vYD#>~}PW{YTGCecxM!)}{H`qx}1}B}Z6bm{B3}wie(y#j6g%i aD1Ud0K2s7}>LbC<`Z}*Xu3Eyae&hd+%t -#include - -#define YY_USER_ACTION yylloc->first_line = yylineno; - -#define YY_FATAL_ERROR(msg) { ((struct yyguts_t*)yyscanner)->yyextra_r->errVar=1; } -#define YY_INPUT(buf,result,max_size) { (result) = nseel_gets(yyextra,(buf),max_size); } - -#define YY_EXTRA_TYPE compileContext * - -#undef YY_BUF_SIZE -#define YY_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN*2) - -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN) - -#include "y.tab.h" - -#ifdef _WIN32 -#define YY_NO_UNISTD_H -#endif - -#include "ns-eel-int.h" - -int nseel_gets(compileContext *ctx, char *buf, size_t sz); - -#define PARSENUM *yylval = nseel_translate(yyextra,yytext); return VALUE; -#define EEL_ACTION(x) return x; - -#ifdef stdin -#undef stdin -#endif -#define stdin (0) - -#ifdef stdout -#undef stdout -#endif -#define stdout (0) - -static int g_fake_errno; -#ifdef errno -#undef errno -#endif - -#define errno g_fake_errno - -%} - -%% - -[0-9]+\.?[0-9]* PARSENUM; -\.[0-9]+ PARSENUM; -0[xX][0-9a-fA-F]+ PARSENUM; - -[a-zA-Z_][a-zA-Z0-9\._]* do { int toktype=IDENTIFIER; *yylval = nseel_lookup(yyextra,&toktype, yytext); return toktype; } while (0); - -[ \t\r\n]+ /* whitespace */ - -. return (int)yytext[0]; - -%% diff --git a/WDL/eel2/eel2.y b/WDL/eel2/eel2.y deleted file mode 100644 index b5317cc2..00000000 --- a/WDL/eel2/eel2.y +++ /dev/null @@ -1,147 +0,0 @@ -%pure-parser -%name-prefix="nseel" -%parse-param { compileContext* context } -%lex-param { void* scanner } - - -/* this will prevent y.tab.c from ever calling yydestruct(), since we do not use it and it is a waste */ -%destructor { - #define yydestruct(a,b,c,d,e) 0 -} VALUE - - -%{ -#ifdef _WIN32 -#include -#endif -#include -#include -#include -#include - -#include "y.tab.h" -#include "ns-eel-int.h" - -#define scanner context->scanner -#define YY_(x) ("") - -%} - -%token VALUE IDENTIFIER FUNCTION1 FUNCTION2 FUNCTION3 FUNCTIONX - - -%start program - -%% - -more_params: - expression - | expression ',' more_params - { - $$ = nseel_createMoreParametersOpcode(context,$1,$3); - } - ; - -value_thing: - VALUE - | IDENTIFIER - | '(' expression ')' - { - $$ = $2; - } - | FUNCTION1 '(' expression ')' - { - $$ = nseel_setCompiledFunctionCallParameters($1, $3, 0, 0); - } - | FUNCTION2 '(' expression ',' expression ')' - { - $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, 0); - } - | FUNCTION3 '(' expression ',' expression ',' expression ')' - { - $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, $7); - } - | FUNCTIONX '(' expression ',' expression ',' more_params ')' - { - $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, $7); - } - ; - -unary_expr: - value_thing - | '+' unary_expr - { - $$ = $2; - } - | '-' unary_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,$2,0); - } - ; - - -div_expr: - unary_expr - | div_expr '/' unary_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,$1,$3); - } - ; - - -mul_expr: - div_expr - | mul_expr '*' div_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,$1,$3); - } - ; - - -sub_expr: - mul_expr - | sub_expr '-' mul_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_SUB,2,$1,$3); - } - ; - -add_expr: - sub_expr - | add_expr '+' sub_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_ADD,2,$1,$3); - } - ; - -andor_expr: - add_expr - | andor_expr '&' add_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_AND,2,$1,$3); - } - | andor_expr '|' add_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_OR,2,$1,$3); - } - ; - -expression: - andor_expr - | expression '%' andor_expr - { - $$ = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,$1,$3); - } - ; - - -program: - expression - { - int a = @1.first_line; - context->result = $1; - } - ; - - -%% diff --git a/WDL/eel2/gen-lex-yacc b/WDL/eel2/gen-lex-yacc deleted file mode 100644 index 6fd3b4cf..00000000 --- a/WDL/eel2/gen-lex-yacc +++ /dev/null @@ -1 +0,0 @@ -yacc -v -d eel2.y && flex eel2.l diff --git a/WDL/eel2/glue_port.h b/WDL/eel2/glue_port.h deleted file mode 100644 index eb8fb2c9..00000000 --- a/WDL/eel2/glue_port.h +++ /dev/null @@ -1,995 +0,0 @@ -#ifndef _EEL_GLUE_PORTABLE_H_ -#define _EEL_GLUE_PORTABLE_H_ - - -#define DECL_ASMFUNC(x) -#define GLUE_JMP_TYPE int -#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((GLUE_JMP_TYPE *)(endOfInstruction))[-1] = (offset)) - -#define GLUE_HAS_FXCH -#define GLUE_MAX_FPSTACK_SIZE 64 -#define BIF_FPSTACKUSE(x) (0) // fp stack is not used within functions -#define BIF_GETFPSTACKUSE(x) (1) - -enum { - EEL_BC_NOP=1, - EEL_BC_RET, - EEL_BC_JMP_NC, // followed by GLUE_JMP_TYPE - EEL_BC_JMP_IF_P1_Z, - EEL_BC_JMP_IF_P1_NZ, - - EEL_BC_MOV_FPTOP_DV, - EEL_BC_MOV_P1_DV, // followed by INT_PTR ptr - EEL_BC_MOV_P2_DV, - EEL_BC_MOV_P3_DV, - EEL_BC__RESET_WTP, - - EEL_BC_PUSH_P1, - EEL_BC_PUSH_P1PTR_AS_VALUE, - EEL_BC_POP_P1, - EEL_BC_POP_P2, - EEL_BC_POP_P3, - EEL_BC_POP_VALUE_TO_ADDR, - - EEL_BC_SET_P2_FROM_P1, - EEL_BC_SET_P3_FROM_P1, - EEL_BC_COPY_VALUE_AT_P1_TO_ADDR, - EEL_BC_SET_P1_FROM_WTP, - EEL_BC_SET_P2_FROM_WTP, - EEL_BC_SET_P3_FROM_WTP, - - EEL_BC_POP_FPSTACK_TO_PTR, - EEL_BC_POP_FPSTACK_TOSTACK, - - EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, - EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, - EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, - EEL_BC_POP_FPSTACK_TO_WTP, - EEL_BC_SET_P1_Z, - EEL_BC_SET_P1_NZ, - - EEL_BC_LOOP_LOADCNT, - EEL_BC_LOOP_END, - - EEL_BC_WHILE_SETUP, - EEL_BC_WHILE_END, - EEL_BC_WHILE_CHECK_RV, - - - - EEL_BC_BNOT, - EEL_BC_EQUAL, - EEL_BC_NOTEQUAL, - EEL_BC_ABOVE, - EEL_BC_BELOWEQ, - - - EEL_BC_ADD, - EEL_BC_SUB, - EEL_BC_MUL, - EEL_BC_DIV, - EEL_BC_AND, - EEL_BC_OR, - EEL_BC_OR0, - EEL_BC_XOR, - - EEL_BC_ADD_OP, - EEL_BC_SUB_OP, - EEL_BC_ADD_OP_FAST, - EEL_BC_SUB_OP_FAST, - EEL_BC_MUL_OP, - EEL_BC_DIV_OP, - EEL_BC_AND_OP, - EEL_BC_OR_OP, - EEL_BC_XOR_OP, - - EEL_BC_UMINUS, - - EEL_BC_ASSIGN, - EEL_BC_ASSIGN_FAST, - EEL_BC_ASSIGN_FAST_FROMFP, - EEL_BC_ASSIGN_FROMFP, - EEL_BC_MOD, - EEL_BC_MOD_OP, - EEL_BC_SHR, - EEL_BC_SHL, - - EEL_BC_SQR, - EEL_BC_MIN, - EEL_BC_MAX, - EEL_BC_MIN_FP, - EEL_BC_MAX_FP, - EEL_BC_ABS, - EEL_BC_SIGN, - EEL_BC_INVSQRT, - - EEL_BC_FXCH, - EEL_BC_POP_FPSTACK, - - EEL_BC_FCALL, - EEL_BC_BOOLTOFP, - EEL_BC_FPTOBOOL, - - EEL_BC_CFUNC_1PDD, - EEL_BC_CFUNC_2PDD, - EEL_BC_CFUNC_2PDDS, - - EEL_BC_MEGABUF, - EEL_BC_GMEGABUF, - - EEL_BC_GENERIC1PARM, - EEL_BC_GENERIC2PARM, - EEL_BC_GENERIC3PARM, - EEL_BC_GENERIC1PARM_RETD, - EEL_BC_GENERIC2PARM_RETD, - EEL_BC_GENERIC3PARM_RETD, - - EEL_BC_USERSTACK_PUSH, - EEL_BC_USERSTACK_POP, - EEL_BC_USERSTACK_POPFAST, - EEL_BC_USERSTACK_PEEK, - EEL_BC_USERSTACK_PEEK_INT, - EEL_BC_USERSTACK_PEEK_TOP, - EEL_BC_USERSTACK_EXCH, - - EEL_BC_DBG_GETSTACKPTR, - -}; - -#define BC_DECL(x) static const EEL_BC_TYPE GLUE_##x[] = { EEL_BC_##x }; -#define BC_DECL_JMP(x) static const EEL_BC_TYPE GLUE_##x[1 + sizeof(GLUE_JMP_TYPE) / sizeof(EEL_BC_TYPE)] = { EEL_BC_##x }; -BC_DECL_JMP(JMP_NC) -BC_DECL_JMP(JMP_IF_P1_Z) -BC_DECL_JMP(JMP_IF_P1_NZ) -BC_DECL(RET) -BC_DECL(FXCH) -BC_DECL(POP_FPSTACK) -#define GLUE_POP_FPSTACK_SIZE sizeof(EEL_BC_TYPE) -BC_DECL(PUSH_P1) -BC_DECL(PUSH_P1PTR_AS_VALUE) -BC_DECL(POP_FPSTACK_TOSTACK) -BC_DECL(POP_FPSTACK_TO_WTP) -BC_DECL(SET_P1_Z) -BC_DECL(SET_P1_NZ) -BC_DECL_JMP(LOOP_LOADCNT) -BC_DECL_JMP(LOOP_END) -static const EEL_BC_TYPE GLUE_LOOP_CLAMPCNT[1]={EEL_BC_NOP}; -static const EEL_BC_TYPE GLUE_LOOP_BEGIN[1]={EEL_BC_NOP}; -static const EEL_BC_TYPE GLUE_WHILE_BEGIN[1]={EEL_BC_NOP}; - -BC_DECL(WHILE_SETUP) -BC_DECL_JMP(WHILE_END) -BC_DECL_JMP(WHILE_CHECK_RV) - -#define GLUE_MOV_PX_DIRECTVALUE_SIZE (sizeof(EEL_BC_TYPE) + sizeof(INT_PTR)) -#define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE GLUE_MOV_PX_DIRECTVALUE_SIZE -static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) -{ - static const EEL_BC_TYPE tab[] = { - EEL_BC_MOV_FPTOP_DV, - EEL_BC_MOV_P1_DV, - EEL_BC_MOV_P2_DV, - EEL_BC_MOV_P3_DV, - }; - *(EEL_BC_TYPE *)b = tab[wv+1]; - *(INT_PTR *) ((char *)b + sizeof(EEL_BC_TYPE)) = v; -} - -#define GLUE_FUNC_ENTER_SIZE 0 -#define GLUE_FUNC_LEAVE_SIZE 0 -static const EEL_BC_TYPE GLUE_FUNC_ENTER[1]={-1}; -static const EEL_BC_TYPE GLUE_FUNC_LEAVE[1]={-1}; - -static int GLUE_RESET_WTP(unsigned char *out, void *ptr) -{ - BC_DECL(_RESET_WTP) - if (out) memcpy(out,&GLUE__RESET_WTP,sizeof(GLUE__RESET_WTP)); - if (out) *(void **) (out+sizeof(GLUE__RESET_WTP)) = ptr; - return sizeof(GLUE__RESET_WTP) + sizeof(void *); -} - -#define GLUE_POP_PX_SIZE sizeof(EEL_BC_TYPE) -static void GLUE_POP_PX(void *b, int wv) -{ - static const EEL_BC_TYPE tab[3] ={ - EEL_BC_POP_P1, - EEL_BC_POP_P2, - EEL_BC_POP_P3, - }; - *(EEL_BC_TYPE *)b = tab[wv]; -} - -#define GLUE_SET_PX_FROM_P1_SIZE sizeof(EEL_BC_TYPE) -static void GLUE_SET_PX_FROM_P1(void *b, int wv) -{ - static const unsigned int tab[3]={ - EEL_BC_NOP, - EEL_BC_SET_P2_FROM_P1, - EEL_BC_SET_P3_FROM_P1, - }; - *(EEL_BC_TYPE *)b = tab[wv]; -} - -static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) -{ - if (buf) - { - *(EEL_BC_TYPE *)buf = EEL_BC_POP_VALUE_TO_ADDR; - *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; - } - return sizeof(EEL_BC_TYPE) + sizeof(void *); -} - -static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) -{ - if (buf) - { - *(EEL_BC_TYPE *)buf = EEL_BC_COPY_VALUE_AT_P1_TO_ADDR; - *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; - } - return sizeof(EEL_BC_TYPE) + sizeof(void *); -} - - - - -static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) -{ - int mv=5; - char *p=(char*)_p; - p+=sizeof(EEL_BC_TYPE); - while (*(INT_PTR*)p && mv-- > 0) p++; - if (!mv) return p; - - *(INT_PTR *)p = newv; - return (unsigned char *) p + sizeof(INT_PTR) - sizeof(EEL_BC_TYPE); -} - -#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(EEL_BC_TYPE) -static void GLUE_SET_PX_FROM_WTP(void *b, int wv) -{ - static const EEL_BC_TYPE tab[3]={ - EEL_BC_SET_P1_FROM_WTP, - EEL_BC_SET_P2_FROM_WTP, - EEL_BC_SET_P3_FROM_WTP, - }; - *(EEL_BC_TYPE *)b = tab[wv]; -} - -static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) -{ - if (buf) - { - *(EEL_BC_TYPE *)buf = EEL_BC_POP_FPSTACK_TO_PTR; - *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; - } - return sizeof(EEL_BC_TYPE) + sizeof(void *); -} - - #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE sizeof(EEL_BC_TYPE) - static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) - { - static const EEL_BC_TYPE tab[3] = { - EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, - EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, - EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, - }; - *(EEL_BC_TYPE *)b = tab[wv]; - } - -#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) -static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) -{ - GLUE_SET_PX_FROM_WTP(buf,wv); - memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); -}; - -static unsigned char GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo - -#define GLUE_INLINE_LOOPS - -// end of bytecode glue, now for stubbage - -#define EEL_BC_ENDOF(x) (((char*)(x))+sizeof(x)) -#define BC_DECLASM(x,y) static EEL_BC_TYPE nseel_asm_##x[1]={EEL_BC_##y}; - -BC_DECLASM(if,NOP) -BC_DECLASM(band,NOP) -BC_DECLASM(bor,NOP) -BC_DECLASM(repeat,NOP) -BC_DECLASM(repeatwhile,NOP) - -BC_DECLASM(bnot,BNOT) -BC_DECLASM(equal,EQUAL) -BC_DECLASM(notequal,NOTEQUAL) -BC_DECLASM(above,ABOVE) -BC_DECLASM(beloweq,BELOWEQ) - -BC_DECLASM(add,ADD) -BC_DECLASM(sub,SUB) -BC_DECLASM(mul,MUL) -BC_DECLASM(div,DIV) -BC_DECLASM(and,AND) -BC_DECLASM(or,OR) -BC_DECLASM(or0,OR0) -BC_DECLASM(xor,XOR) - -BC_DECLASM(add_op,ADD_OP) -BC_DECLASM(sub_op,SUB_OP) -BC_DECLASM(add_op_fast,ADD_OP_FAST) -BC_DECLASM(sub_op_fast,SUB_OP_FAST) -BC_DECLASM(mul_op,MUL_OP) -BC_DECLASM(div_op,DIV_OP) -BC_DECLASM(and_op,AND_OP) -BC_DECLASM(or_op,OR_OP) -BC_DECLASM(xor_op,XOR_OP) - -BC_DECLASM(uminus,UMINUS) - -BC_DECLASM(assign,ASSIGN) -BC_DECLASM(assign_fast,ASSIGN_FAST) -BC_DECLASM(assign_fast_fromfp,ASSIGN_FAST_FROMFP) -BC_DECLASM(assign_fromfp,ASSIGN_FROMFP) -BC_DECLASM(mod,MOD) -BC_DECLASM(mod_op,MOD_OP) -BC_DECLASM(shr,SHR) -BC_DECLASM(shl,SHL) -BC_DECLASM(sqr,SQR) - -BC_DECLASM(min,MIN) -BC_DECLASM(max,MAX) -BC_DECLASM(min_fp,MIN_FP) -BC_DECLASM(max_fp,MAX_FP) -BC_DECLASM(abs,ABS) -BC_DECLASM(sign,SIGN) -BC_DECLASM(invsqrt,INVSQRT) -BC_DECLASM(dbg_getstackptr,DBG_GETSTACKPTR) - -BC_DECLASM(booltofp,BOOLTOFP) -BC_DECLASM(fptobool,FPTOBOOL) - -#define BC_DECLASM_N(x,y,n) static EEL_BC_TYPE nseel_asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; - -#define BC_DECLASM_N_EXPORT(x,y,n) EEL_BC_TYPE _asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; EEL_BC_TYPE _asm_##x##_end[1]={1,}; - -BC_DECLASM_N(stack_push,USERSTACK_PUSH,3) -BC_DECLASM_N(stack_pop,USERSTACK_POP,3) -BC_DECLASM_N(stack_pop_fast,USERSTACK_POPFAST,3) -BC_DECLASM_N(stack_peek,USERSTACK_PEEK,3) - -BC_DECLASM_N(stack_peek_int,USERSTACK_PEEK_INT,4) - -BC_DECLASM_N(stack_peek_top,USERSTACK_PEEK_TOP,1) -BC_DECLASM_N(stack_exch,USERSTACK_EXCH,1) - -BC_DECLASM_N(fcall,FCALL,1) - -BC_DECLASM_N(1pdd,CFUNC_1PDD,1) -BC_DECLASM_N(2pdd,CFUNC_2PDD,1) -BC_DECLASM_N(2pdds,CFUNC_2PDDS,1) - -BC_DECLASM_N_EXPORT(megabuf,MEGABUF,0) -BC_DECLASM_N_EXPORT(gmegabuf,GMEGABUF,2) -BC_DECLASM_N_EXPORT(generic1parm,GENERIC1PARM,2) -BC_DECLASM_N_EXPORT(generic2parm,GENERIC2PARM,2) -BC_DECLASM_N_EXPORT(generic3parm,GENERIC3PARM,2) -BC_DECLASM_N_EXPORT(generic1parm_retd,GENERIC1PARM_RETD,2) -BC_DECLASM_N_EXPORT(generic2parm_retd,GENERIC2PARM_RETD,2) -BC_DECLASM_N_EXPORT(generic3parm_retd,GENERIC3PARM_RETD,2) - - -#define nseel_asm_1pdd_end EEL_BC_ENDOF(nseel_asm_1pdd) -#define nseel_asm_2pdd_end EEL_BC_ENDOF(nseel_asm_2pdd) -#define nseel_asm_2pdds_end EEL_BC_ENDOF(nseel_asm_2pdds) - -#define nseel_asm_fcall_end EEL_BC_ENDOF(nseel_asm_fcall) - -#define nseel_asm_if_end EEL_BC_ENDOF(nseel_asm_if) -#define nseel_asm_band_end EEL_BC_ENDOF(nseel_asm_band) -#define nseel_asm_bor_end EEL_BC_ENDOF(nseel_asm_bor) -#define nseel_asm_repeat_end EEL_BC_ENDOF(nseel_asm_repeat) -#define nseel_asm_repeatwhile_end EEL_BC_ENDOF(nseel_asm_repeatwhile) -#define nseel_asm_bnot_end EEL_BC_ENDOF(nseel_asm_bnot) -#define nseel_asm_equal_end EEL_BC_ENDOF(nseel_asm_equal) -#define nseel_asm_notequal_end EEL_BC_ENDOF(nseel_asm_notequal) -#define nseel_asm_above_end EEL_BC_ENDOF(nseel_asm_above) -#define nseel_asm_beloweq_end EEL_BC_ENDOF(nseel_asm_beloweq) - -#define nseel_asm_min_end EEL_BC_ENDOF(nseel_asm_min) -#define nseel_asm_max_end EEL_BC_ENDOF(nseel_asm_max) -#define nseel_asm_abs_end EEL_BC_ENDOF(nseel_asm_abs) -#define nseel_asm_min_fp_end EEL_BC_ENDOF(nseel_asm_min_fp) -#define nseel_asm_max_fp_end EEL_BC_ENDOF(nseel_asm_max_fp) -#define nseel_asm_sign_end EEL_BC_ENDOF(nseel_asm_sign) -#define nseel_asm_invsqrt_end EEL_BC_ENDOF(nseel_asm_invsqrt) -#define nseel_asm_dbg_getstackptr_end EEL_BC_ENDOF(nseel_asm_dbg_getstackptr) - - -#define nseel_asm_add_end EEL_BC_ENDOF(nseel_asm_add) -#define nseel_asm_sub_end EEL_BC_ENDOF(nseel_asm_sub) -#define nseel_asm_mul_end EEL_BC_ENDOF(nseel_asm_mul) -#define nseel_asm_div_end EEL_BC_ENDOF(nseel_asm_div) -#define nseel_asm_and_end EEL_BC_ENDOF(nseel_asm_and) -#define nseel_asm_or_end EEL_BC_ENDOF(nseel_asm_or) -#define nseel_asm_or0_end EEL_BC_ENDOF(nseel_asm_or0) -#define nseel_asm_xor_end EEL_BC_ENDOF(nseel_asm_xor) - -#define nseel_asm_add_op_end EEL_BC_ENDOF(nseel_asm_add_op) -#define nseel_asm_sub_op_end EEL_BC_ENDOF(nseel_asm_sub_op) -#define nseel_asm_add_op_fast_end EEL_BC_ENDOF(nseel_asm_add_op_fast) -#define nseel_asm_sub_op_fast_end EEL_BC_ENDOF(nseel_asm_sub_op_fast) -#define nseel_asm_mul_op_end EEL_BC_ENDOF(nseel_asm_mul_op) -#define nseel_asm_div_op_end EEL_BC_ENDOF(nseel_asm_div_op) -#define nseel_asm_and_op_end EEL_BC_ENDOF(nseel_asm_and_op) -#define nseel_asm_or_op_end EEL_BC_ENDOF(nseel_asm_or_op) -#define nseel_asm_xor_op_end EEL_BC_ENDOF(nseel_asm_xor_op) - -#define nseel_asm_uminus_end EEL_BC_ENDOF(nseel_asm_uminus) -#define nseel_asm_assign_end EEL_BC_ENDOF(nseel_asm_assign) -#define nseel_asm_assign_fast_end EEL_BC_ENDOF(nseel_asm_assign_fast) -#define nseel_asm_assign_fast_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fast_fromfp) -#define nseel_asm_assign_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fromfp) -#define nseel_asm_mod_end EEL_BC_ENDOF(nseel_asm_mod) -#define nseel_asm_mod_op_end EEL_BC_ENDOF(nseel_asm_mod_op) -#define nseel_asm_shr_end EEL_BC_ENDOF(nseel_asm_shr) -#define nseel_asm_shl_end EEL_BC_ENDOF(nseel_asm_shl) - -#define nseel_asm_sqr_end EEL_BC_ENDOF(nseel_asm_sqr) - - -#define nseel_asm_booltofp_end EEL_BC_ENDOF(nseel_asm_booltofp) -#define nseel_asm_fptobool_end EEL_BC_ENDOF(nseel_asm_fptobool) - -#define nseel_asm_stack_push_end EEL_BC_ENDOF(nseel_asm_stack_push) -#define nseel_asm_stack_pop_end EEL_BC_ENDOF(nseel_asm_stack_pop) -#define nseel_asm_stack_pop_fast_end EEL_BC_ENDOF(nseel_asm_stack_pop_fast) -#define nseel_asm_stack_peek_end EEL_BC_ENDOF(nseel_asm_stack_peek) -#define nseel_asm_stack_peek_int_end EEL_BC_ENDOF(nseel_asm_stack_peek_int) -#define nseel_asm_stack_peek_top_end EEL_BC_ENDOF(nseel_asm_stack_peek_top) -#define nseel_asm_stack_exch_end EEL_BC_ENDOF(nseel_asm_stack_exch) - - -static void *GLUE_realAddress(void *fn, void *fn_e, int *size) -{ - *size = (char *)fn_e - (char *)fn; - return fn; -} - -#define EEL_BC_STACKSIZE (65536) - -// todo: check for stack overflows! we could determine if this is possible at compile time. -#define EEL_BC_STACK_ADV_SIZE 8 -#define EEL_BC_STACK_FWD() (stackptr += EEL_BC_STACK_ADV_SIZE) -#define EEL_BC_STACK_REW() (stackptr -= EEL_BC_STACK_ADV_SIZE) - -#define EEL_BC_TRUE ((EEL_F*)(INT_PTR)1) - - - - -static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) -{ - char __stack[EEL_BC_STACKSIZE]; - char *iptr = (char*)cp; - char *stackptr=__stack; - EEL_F *p1, *p2, *p3, *wtp = (EEL_F*)bp; -#define fp_top (_fpstacktop[0]) -#define fp_top2 (_fpstacktop[-1]) -#define fp_push(x) *++_fpstacktop=(x) -#define fp_pop() (*_fpstacktop--) -#define fp_rewind(x) { _fpstacktop -= (x); } - - EEL_F fpstack[GLUE_MAX_FPSTACK_SIZE]; - EEL_F *_fpstacktop=fpstack-1; - for (;;) - { - EEL_BC_TYPE inst = *(EEL_BC_TYPE *)iptr; - iptr += sizeof(EEL_BC_TYPE); - switch (inst) - { - case EEL_BC_FXCH: - { - EEL_F a = fp_top; - fp_top=fp_top2; - fp_top2=a; - } - break; - case EEL_BC_POP_FPSTACK: fp_rewind(1); break; - case EEL_BC_NOP: break; - case EEL_BC_RET: - EEL_BC_STACK_REW(); - if (stackptr < __stack) - { - return; - } - memcpy(&iptr, stackptr, sizeof(void *)); - break; - case EEL_BC_JMP_NC: - iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; - break; - case EEL_BC_JMP_IF_P1_Z: - iptr += p1 ? sizeof(GLUE_JMP_TYPE) : sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; - break; - case EEL_BC_JMP_IF_P1_NZ: - iptr += p1 ? sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr : sizeof(GLUE_JMP_TYPE); - break; - case EEL_BC_MOV_FPTOP_DV: - fp_push(**(EEL_F **)iptr); - iptr += sizeof(void*); - break; - case EEL_BC_MOV_P1_DV: - p1 = *(void **)iptr; - iptr += sizeof(void*); - break; - case EEL_BC_MOV_P2_DV: - p2 = *(void **)iptr; - iptr += sizeof(void*); - break; - case EEL_BC_MOV_P3_DV: - p3 = *(void **)iptr; - iptr += sizeof(void*); - break; - case EEL_BC__RESET_WTP: - wtp = *(void **)iptr; - iptr += sizeof(void*); - break; - case EEL_BC_PUSH_P1: - memcpy(stackptr,&p1,sizeof(void *)); - EEL_BC_STACK_FWD(); - break; - case EEL_BC_PUSH_P1PTR_AS_VALUE: - memcpy(stackptr,p1,sizeof(EEL_F)); - EEL_BC_STACK_FWD(); - break; - case EEL_BC_POP_P1: - EEL_BC_STACK_REW(); - memcpy(&p1,stackptr,sizeof(void *)); - break; - case EEL_BC_POP_P2: - EEL_BC_STACK_REW(); - memcpy(&p2,stackptr,sizeof(void *)); - break; - case EEL_BC_POP_P3: - EEL_BC_STACK_REW(); - memcpy(&p3,stackptr,sizeof(void *)); - break; - case EEL_BC_POP_VALUE_TO_ADDR: - EEL_BC_STACK_REW(); - memcpy(*(void **)iptr,stackptr,sizeof(EEL_F)); - iptr += sizeof(void*); - break; - case EEL_BC_SET_P2_FROM_P1: - p2=p1; - break; - case EEL_BC_SET_P3_FROM_P1: - p3=p1; - break; - case EEL_BC_COPY_VALUE_AT_P1_TO_ADDR: - memcpy(*(void **)iptr,p1,sizeof(EEL_F)); - iptr += sizeof(void*); - break; - case EEL_BC_SET_P1_FROM_WTP: - p1 = wtp; - break; - case EEL_BC_SET_P2_FROM_WTP: - p2 = wtp; - break; - case EEL_BC_SET_P3_FROM_WTP: - p3 = wtp; - break; - case EEL_BC_POP_FPSTACK_TO_PTR: - *((EEL_F *)iptr) = fp_pop(); - iptr += sizeof(void *); - break; - case EEL_BC_POP_FPSTACK_TOSTACK: - *(EEL_F*)stackptr = fp_pop(); - EEL_BC_STACK_FWD(); - break; - case EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK: - fp_push(*p1); - break; - case EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK: - fp_push(*p2); - break; - case EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK: - fp_push(*p3); - break; - case EEL_BC_POP_FPSTACK_TO_WTP: - *wtp++ = fp_pop(); - break; - case EEL_BC_SET_P1_Z: - p1=NULL; - break; - case EEL_BC_SET_P1_NZ: - p1 = EEL_BC_TRUE; - break; - - case EEL_BC_LOOP_LOADCNT: - if ((*(int *)stackptr = (int) fp_pop()) < 1) - { - iptr+= sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; - } - else - { - iptr += sizeof(GLUE_JMP_TYPE); - if (*(int *)stackptr > NSEEL_LOOPFUNC_SUPPORT_MAXLEN) *(int *)stackptr=NSEEL_LOOPFUNC_SUPPORT_MAXLEN; - stackptr += EEL_BC_STACK_ADV_SIZE; - *(void **)stackptr = wtp; - stackptr += EEL_BC_STACK_ADV_SIZE; - } - break; - case EEL_BC_LOOP_END: - if (--*(int *)(stackptr-2*EEL_BC_STACK_ADV_SIZE) <= 0) - { - stackptr -= 2*EEL_BC_STACK_ADV_SIZE; - iptr += sizeof(GLUE_JMP_TYPE); - } - else - { - wtp = *(void **) (stackptr - EEL_BC_STACK_ADV_SIZE); - iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // back to the start! - } - break; - - case EEL_BC_WHILE_SETUP: - *(int *)stackptr = NSEEL_LOOPFUNC_SUPPORT_MAXLEN; - stackptr += EEL_BC_STACK_ADV_SIZE; - *(void **)stackptr = wtp; - stackptr += EEL_BC_STACK_ADV_SIZE; - break; - case EEL_BC_WHILE_END: - if (--*(int *)(stackptr-2*EEL_BC_STACK_ADV_SIZE) <= 0) - { - stackptr -= EEL_BC_STACK_ADV_SIZE*2; - iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // endpt - } - else - { - iptr += sizeof(GLUE_JMP_TYPE); - } - break; - case EEL_BC_WHILE_CHECK_RV: - if (p1) - { - iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // loop - wtp = *(void **) (stackptr - EEL_BC_STACK_ADV_SIZE); - } - else - { - // done - stackptr -= EEL_BC_STACK_ADV_SIZE*2; - iptr += sizeof(GLUE_JMP_TYPE); - } - break; - case EEL_BC_BNOT: - p1 = p1 ? NULL : EEL_BC_TRUE; - break; - case EEL_BC_EQUAL: - p1 = fabs(fp_top - fp_top2) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; - fp_rewind(2); - break; - case EEL_BC_NOTEQUAL: - p1 = fabs(fp_top - fp_top2) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; - fp_rewind(2); - break; - case EEL_BC_ABOVE: - p1 = fp_top < fp_top2 ? EEL_BC_TRUE : NULL; - fp_rewind(2); - break; - case EEL_BC_BELOWEQ: - p1 = fp_top >= fp_top2 ? EEL_BC_TRUE : NULL; - fp_rewind(2); - break; - - case EEL_BC_ADD: - fp_top2 += fp_top; - fp_rewind(1); - break; - case EEL_BC_SUB: - fp_top2 -= fp_top; - fp_rewind(1); - break; - case EEL_BC_MUL: - fp_top2 *= fp_top; - fp_rewind(1); - break; - case EEL_BC_DIV: - fp_top2 /= fp_top; - fp_rewind(1); - break; - case EEL_BC_AND: - fp_top2 = (EEL_F) (((int)fp_top) & (int)(fp_top2)); - fp_rewind(1); - break; - case EEL_BC_OR: - fp_top2 = (EEL_F) (((int)fp_top) | (int)(fp_top2)); - fp_rewind(1); - break; - case EEL_BC_OR0: - fp_top = (EEL_F) ((int)(fp_top)); - break; - case EEL_BC_XOR: - fp_top2 = (EEL_F) (((int)fp_top) ^ (int)(fp_top2)); - fp_rewind(1); - break; - - case EEL_BC_ADD_OP: - *(p1 = p2) = denormal_filter_double2(*p2 + fp_pop()); - break; - case EEL_BC_SUB_OP: - *(p1 = p2) = denormal_filter_double2(*p2 - fp_pop()); - break; - case EEL_BC_ADD_OP_FAST: - *(p1 = p2) += fp_pop(); - break; - case EEL_BC_SUB_OP_FAST: - *(p1 = p2) -= fp_pop(); - break; - case EEL_BC_MUL_OP: - *(p1 = p2) = denormal_filter_double2(*p2 * fp_pop()); - break; - case EEL_BC_DIV_OP: - *(p1 = p2) = denormal_filter_double2(*p2 * fp_pop()); - break; - case EEL_BC_AND_OP: - p1 = p2; - *p2 = (EEL_F) (((int)*p2) & (int)fp_pop()); - break; - case EEL_BC_OR_OP: - p1 = p2; - *p2 = (EEL_F) (((int)*p2) | (int)fp_pop()); - break; - case EEL_BC_XOR_OP: - p1 = p2; - *p2 = (EEL_F) (((int)*p2) ^ (int)fp_pop()); - break; - case EEL_BC_UMINUS: - fp_top = -fp_top; - break; - case EEL_BC_ASSIGN: - *p2 = denormal_filter_double2(*p1); - p1 = p2; - break; - - case EEL_BC_ASSIGN_FAST: - *p2 = *p1; - break; - case EEL_BC_ASSIGN_FAST_FROMFP: - *p2 = fp_pop(); - p1 = p2; - break; - case EEL_BC_ASSIGN_FROMFP: - *p2 = denormal_filter_double2(fp_pop()); - p1 = p2; - break; - case EEL_BC_MOD: - { - int a = (int) (fp_pop()); - fp_top = a ? (EEL_F) ((int)fp_top % a) : 0.0; - } - break; - case EEL_BC_MOD_OP: - { - int a = (int) (fp_pop()); - *p2 = a ? (EEL_F) ((int)*p2 % a) : 0.0; - p1=p2; - - } - break; - case EEL_BC_SHR: - fp_top2 = (EEL_F) (((int)fp_top2) >> (int)fp_top); - fp_rewind(1); - break; - case EEL_BC_SHL: - fp_top2 = (EEL_F) (((int)fp_top2) << (int)fp_top); - fp_rewind(1); - break; - case EEL_BC_SQR: - fp_top *= fp_top; - break; - case EEL_BC_MIN: - if (*p1 > *p2) p1 = p2; - break; - case EEL_BC_MAX: - if (*p1 < *p2) p1 = p2; - break; - case EEL_BC_MIN_FP: - { - EEL_F a=fp_pop(); - if (afp_top) fp_top=a; - } - break; - case EEL_BC_ABS: - fp_top = fabs(fp_top); - break; - case EEL_BC_SIGN: - if (fp_top<0.0) fp_top=-1.0; - else if (fp_top>0.0) fp_top=1.0; - break; - case EEL_BC_DBG_GETSTACKPTR: - fp_top = (int)(INT_PTR)stackptr; - break; - case EEL_BC_INVSQRT: - { - float y = (float)fp_top; - int i = 0x5f3759df - ( (* (int *) &y) >> 1 ); - y = *(float *) &i; - fp_top = y * ( 1.5F - ( (fp_top * 0.5) * y * y ) ); - } - break; - case EEL_BC_FCALL: - { - char *newiptr = *(char **)iptr; - iptr += sizeof(void *); - memcpy(stackptr, &iptr, sizeof(void *)); - EEL_BC_STACK_FWD(); - iptr = newiptr; - } - break; - case EEL_BC_BOOLTOFP: - fp_push(p1 ? 1.0 : 0.0); - break; - case EEL_BC_FPTOBOOL: - p1 = fabs(fp_pop()) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; - break; - - case EEL_BC_CFUNC_1PDD: - { - double (*f)(double) = (double (*)(double)) *(void **)iptr; - fp_top = f(fp_top); - iptr += sizeof(void *); - } - break; - case EEL_BC_CFUNC_2PDD: - { - double (*f)(double,double) = (double (*)(double,double)) *(void **)iptr; - fp_top2 = f(fp_top2,fp_top); - fp_rewind(1); - iptr += sizeof(void *); - } - break; - case EEL_BC_CFUNC_2PDDS: - { - double (*f)(double,double) = (double (*)(double,double)) *(void **)iptr; - *p2 = f(*p2,fp_pop()); - p1 = p2; - iptr += sizeof(void *); - } - break; - - case EEL_BC_MEGABUF: - { - unsigned int idx=(unsigned int) (fp_pop() + NSEEL_CLOSEFACTOR); - EEL_F **f = (EEL_F **)rt,*f2; - p1 = (idx < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK && (f2=f[idx/NSEEL_RAM_ITEMSPERBLOCK])) ? - (f2 + (idx&(NSEEL_RAM_ITEMSPERBLOCK-1))) : - __NSEEL_RAMAlloc((void*)rt,idx); - } - break; - case EEL_BC_GMEGABUF: - { - p1 = __NSEEL_RAMAllocGMEM(*(EEL_F ****)iptr,(int) (fp_pop() + NSEEL_CLOSEFACTOR)); - iptr += sizeof(void *)*2; // also includes ptr to __NSEEL_RAMAllocGMEM, which we ignore - } - break; - case EEL_BC_GENERIC1PARM: - { - EEL_F *(*f)(void *,EEL_F*) = (EEL_F *(*)(void *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - p1 = f(*(void **)iptr,p1); - iptr += sizeof(void *)*2; - } - break; - case EEL_BC_GENERIC2PARM: - { - EEL_F *(*f)(void *,EEL_F*,EEL_F*) = (EEL_F *(*)(void *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - p1 = f(*(void **)iptr,p2, p1); - iptr += sizeof(void *)*2; - } - break; - case EEL_BC_GENERIC3PARM: - { - EEL_F *(*f)(void *,EEL_F*,EEL_F*,EEL_F*) = (EEL_F *(*)(void *, EEL_F *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - p1 = f(*(void **)iptr,p3, p2, p1); - iptr += sizeof(void *)*2; - } - break; - case EEL_BC_GENERIC1PARM_RETD: - { - EEL_F (*f)(void *,EEL_F*) = (EEL_F (*)(void *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - fp_push(f(*(void **)iptr,p1)); - iptr += sizeof(void *)*2; - } - break; - case EEL_BC_GENERIC2PARM_RETD: - { - EEL_F (*f)(void *,EEL_F*,EEL_F*) = (EEL_F (*)(void *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - fp_push(f(*(void **)iptr,p2, p1)); - iptr += sizeof(void *)*2; - } - break; - case EEL_BC_GENERIC3PARM_RETD: - { - EEL_F (*f)(void *,EEL_F*,EEL_F*,EEL_F*) = (EEL_F (*)(void *, EEL_F *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); - fp_push(f(*(void **)iptr,p3, p2, p1)); - iptr += sizeof(void *)*2; - } - break; - - case EEL_BC_USERSTACK_PUSH: - { - UINT_PTR *sptr = *(UINT_PTR **)iptr; - (*sptr) += 8; - (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); - (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); - *(EEL_F *)*sptr = *p1; - } - iptr += sizeof(void*)*3; - break; - case EEL_BC_USERSTACK_POP: - { - UINT_PTR *sptr = *(UINT_PTR **)iptr; - *p1 = *(EEL_F *)*sptr; - (*sptr) -= 8; - (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); - (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); - } - iptr += sizeof(void*)*3; - break; - case EEL_BC_USERSTACK_POPFAST: - { - UINT_PTR *sptr = *(UINT_PTR **)iptr; - p1 = (EEL_F *)*sptr; - (*sptr) -= 8; - (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); - (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); - } - iptr += sizeof(void*)*3; - break; - case EEL_BC_USERSTACK_PEEK: - { - UINT_PTR sptr = **(UINT_PTR **)iptr; - sptr -= sizeof(EEL_F) * (int)(fp_pop()); - sptr &= *(UINT_PTR*)(iptr+sizeof(void *)); - sptr |= *(UINT_PTR*)(iptr+2*sizeof(void *)); - p1 = (EEL_F *)sptr; - } - iptr += sizeof(void*)*3; - break; - case EEL_BC_USERSTACK_PEEK_INT: - { - UINT_PTR sptr = **(UINT_PTR **)iptr; - sptr -= *(UINT_PTR*)(iptr+sizeof(void*)); - sptr &= *(UINT_PTR*)(iptr+2*sizeof(void *)); - sptr |= *(UINT_PTR*)(iptr+3*sizeof(void *)); - p1 = (EEL_F *)sptr; - } - iptr += sizeof(void*)*4; - break; - case EEL_BC_USERSTACK_PEEK_TOP: - p1 = (EEL_F *)**(UINT_PTR **)iptr; - iptr += sizeof(void*); - break; - case EEL_BC_USERSTACK_EXCH: - { - EEL_F *p=(EEL_F *)**(UINT_PTR **)iptr; - EEL_F a=*p; - *p=*p1; - *p1=a; - } - iptr += sizeof(void*); - break; - } - } -#undef fp_top -#undef fp_top2 -#undef fp_pop -#undef fp_push -}; - -#endif diff --git a/WDL/eel2/glue_ppc.h b/WDL/eel2/glue_ppc.h deleted file mode 100644 index 22607259..00000000 --- a/WDL/eel2/glue_ppc.h +++ /dev/null @@ -1,257 +0,0 @@ -#ifndef _NSEEL_GLUE_PPC_H_ -#define _NSEEL_GLUE_PPC_H_ - -#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support -#define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible) - - -// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction. -// on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so -// we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions) -#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC) - -static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b - -static const unsigned int GLUE_JMP_IF_P1_Z[]= -{ - 0x2f830000, //cmpwi cr7, r3, 0 - 0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction -}; -static const unsigned int GLUE_JMP_IF_P1_NZ[]= -{ - 0x2f830000, //cmpwi cr7, r3, 0 - 0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction -}; - - -#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8 -static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) -{ - static const unsigned short tab[3][2] = { - {0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw - {0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw - {0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw - }; - unsigned int uv=(unsigned int)v; - unsigned short *p=(unsigned short *)b; - - *p++ = tab[wv][0]; // addis rX, r0, hw - *p++ = (uv>>16)&0xffff; - *p++ = tab[wv][1]; // ori rX, rX, lw - *p++ = uv&0xffff; -} - - -// mflr r5 -// stwu r5, -16(r1) -const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 }; -#define GLUE_FUNC_ENTER_SIZE 8 - -// lwz r5, 0(r1) -// addi r1, r1, 16 -// mtlr r5 -const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 }; -#define GLUE_FUNC_LEAVE_SIZE 12 - -const static unsigned int GLUE_RET[]={0x4E800020}; // blr - -static int GLUE_RESET_WTP(unsigned char *out, void *ptr) -{ - const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src) - if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17)); - return sizeof(GLUE_SET_WTP_FROM_R17); - -} - - - -// stwu r3, -16(r1) -const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0}; - - -#define GLUE_POP_PX_SIZE 8 -static void GLUE_POP_PX(void *b, int wv) -{ - static const unsigned int tab[3] ={ - 0x80610000, // lwz r3, 0(r1) - 0x81c10000, // lwz r14, 0(r1) - 0x81e10000, // lwz r15, 0(r1) - }; - ((unsigned int *)b)[0] = tab[wv]; - ((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16 -} - -#define GLUE_SET_PX_FROM_P1_SIZE 4 -static void GLUE_SET_PX_FROM_P1(void *b, int wv) -{ - static const unsigned int tab[3]={ - 0x7c631b78, // never used: mr r3, r3 - 0x7c6e1b78, // mr r14, r3 - 0x7c6f1b78, // mr r15, r3 - }; - *(unsigned int *)b = tab[wv]; -} - - - -// lfd f2, 0(r3) -// stfdu f2, -16(r1) -static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 }; - -static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) -{ - // lfd f2, 0(r1) - // addi r1,r1,16 - // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) - // stfd f2, 0(r3) - if (buf) - { - unsigned int *bufptr = (unsigned int *)buf; - *bufptr++ = 0xC8410000; - *bufptr++ = 0x38210010; - GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); - bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; - *bufptr++ = 0xd8430000; - } - return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; -} - -static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) -{ - // lfd f2, 0(r3) - // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) - // stfd f2, 0(r3) - - if (buf) - { - unsigned int *bufptr = (unsigned int *)buf; - *bufptr++ = 0xc8430000; - GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); - bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; - *bufptr++ = 0xd8430000; - } - - return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; -} - - -static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) -{ - static const double consttab[] = { - NSEEL_CLOSEFACTOR, - 4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/, - }; - // we could have r18 refer to the current user-stack pointer, someday, perhaps - __asm__( - "subi r1, r1, 128\n" - "stfd f31, 8(r1)\n" - "stfd f30, 16(r1)\n" - "stmw r13, 32(r1)\n" - "mtctr %0\n" - "mr r17, %1\n" - "mr r13, %2\n" - "lfd f31, 0(%3)\n" - "lfd f30, 8(%3)\n" - "subi r17, r17, 8\n" - "mflr r0\n" - "stw r0, 24(r1)\n" - "bctrl\n" - "lwz r0, 24(r1)\n" - "mtlr r0\n" - "lmw r13, 32(r1)\n" - "lfd f31, 8(r1)\n" - "lfd f30, 16(r1)\n" - "addi r1, r1, 128\n" - ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab)); -}; - -static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) -{ - // 64 bit ppc would take some work - unsigned int *p=(unsigned int *)_p; - while ((p[0]&0x0000FFFF) != 0x0000dead && - (p[1]&0x0000FFFF) != 0x0000beef) p++; - p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF); - p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF); - - return (unsigned char *)(p+1); -} - - #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int) - static void GLUE_SET_PX_FROM_WTP(void *b, int wv) - { - static const unsigned int tab[3]={ - 0x7e038378, // mr r3, r16 - 0x7e0e8378, // mr r14, r16 - 0x7e0f8378, // mr r15, r16 - }; - *(unsigned int *)b = tab[wv]; - } - static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) - { - // set r3 to destptr - // stfd f1, 0(r3) - if (buf) - { - unsigned int *bufptr = (unsigned int *)buf; - GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); - bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; - - *bufptr++ = 0xD8230000; // stfd f1, 0(r3) - } - return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int); - } - #define GLUE_POP_FPSTACK_SIZE 0 - static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack - - static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = { - 0xdc21fff0, // stfdu f1, -16(r1) - }; - - static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = { - 0xdc300008, // stfdu f1, 8(r16) - }; - - #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4 - static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) - { - static const unsigned int tab[3] = { - 0xC8230000, // lfd f1, 0(r3) - 0xC82E0000, // lfd f1, 0(r14) - 0xC82F0000, // lfd f1, 0(r15) - }; - *(unsigned int *)b = tab[wv]; - } - -#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) -static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) -{ - memcpy(buf,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); - GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after -}; - -static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo - - -static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0 -static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1 - - -static void *GLUE_realAddress(void *fn, void *fn_e, int *size) -{ - // magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2 - static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 }; - unsigned char *p = (unsigned char *)fn; - - while (memcmp(p,sig,sizeof(sig))) p+=4; - p+=sizeof(sig); - fn = p; - - while (memcmp(p,sig,sizeof(sig))) p+=4; - *size = p - (unsigned char *)fn; - return fn; -} - -// end of ppc - -#endif diff --git a/WDL/eel2/glue_x86.h b/WDL/eel2/glue_x86.h deleted file mode 100644 index c7c62a38..00000000 --- a/WDL/eel2/glue_x86.h +++ /dev/null @@ -1,355 +0,0 @@ -#ifndef _NSEEL_GLUE_X86_H_ -#define _NSEEL_GLUE_X86_H_ - -#define GLUE_MAX_FPSTACK_SIZE 8 - -// endOfInstruction is end of jump with relative offset, offset is offset from end of instruction to jump to -#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset)) - -static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp -static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz -static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz - -#define GLUE_FUNC_ENTER_SIZE 0 -#define GLUE_FUNC_LEAVE_SIZE 0 -const static unsigned int GLUE_FUNC_ENTER[1]; -const static unsigned int GLUE_FUNC_LEAVE[1]; - - // x86 - // stack is 16 byte aligned - // when pushing values to stack, alignment pushed first, then value (value is at the lower address) - // when pushing pointers to stack, alignment pushed first, then pointer (pointer is at the lower address) - - static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = - { - 0x83, 0xEC, 8, /* sub esp, 8 */ - 0xff, 0x70, 0x4, /* push dword [eax+4] */ - 0xff, 0x30, /* push dword [eax] */ - }; - - static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) - { - if (buf) - { - *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue - - *buf++ = 0x8f; *buf++ = 0x00; // pop dword [eax] - *buf++ = 0x8f; *buf++ = 0x40; *buf++ = 4; // pop dword [eax+4] - - *buf++ = 0x59; // pop ecx (alignment) - *buf++ = 0x59; // pop ecx (alignment) - } - - return 12; - } - - static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) - { - if (buf) - { - *buf++ = 0x8B; *buf++ = 0x38; // mov edi, [eax] - *buf++ = 0x8B; *buf++ = 0x48; *buf++ = 0x04; // mov ecx, [eax+4] - - - *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue - *buf++ = 0x89; *buf++ = 0x38; // mov [eax], edi - *buf++ = 0x89; *buf++ = 0x48; *buf++ = 0x04; // mov [eax+4], ecx - } - - return 2 + 3 + 5 + 2 + 3; - } - - static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) - { - if (buf) - { - *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue - *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [eax] - } - return 1+4+2; - } - - - #define GLUE_MOV_PX_DIRECTVALUE_SIZE 5 - #define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE 6 // length when wv == -1 - - static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) - { - if (wv==-1) - { - const static unsigned char t[2] = {0xDD, 0x05}; - memcpy(b,t,2); - b= ((unsigned char *)b)+2; - } - else - { - const static unsigned char tab[3] = { - 0xB8 /* mov eax, dv*/, - 0xBF /* mov edi, dv */ , - 0xB9 /* mov ecx, dv */ - }; - *((unsigned char *)b) = tab[wv]; // mov eax, dv - b= ((unsigned char *)b)+1; - } - *(INT_PTR *)b = v; - } - const static unsigned char GLUE_PUSH_P1[4]={0x83, 0xEC, 12, 0x50}; // sub esp, 12, push eax - - #define GLUE_POP_PX_SIZE 4 - static void GLUE_POP_PX(void *b, int wv) - { - static const unsigned char tab[3][GLUE_POP_PX_SIZE]= - { - {0x58,/*pop eax*/ 0x83, 0xC4, 12 /* add esp, 12*/}, - {0x5F,/*pop edi*/ 0x83, 0xC4, 12}, - {0x59,/*pop ecx*/ 0x83, 0xC4, 12}, - }; - memcpy(b,tab[wv],GLUE_POP_PX_SIZE); - } - - #define GLUE_SET_PX_FROM_P1_SIZE 2 - static void GLUE_SET_PX_FROM_P1(void *b, int wv) - { - static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ - {0x90,0x90}, // should never be used! (nopnop) - {0x89,0xC7}, // mov edi, eax - {0x89,0xC1}, // mov ecx, eax - }; - memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); - } - - #define GLUE_POP_FPSTACK_SIZE 2 - static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 - - static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { - 0x83, 0xEC, 16, // sub esp, 16 - 0xDD, 0x1C, 0x24 // fstp qword (%esp) - }; - - static const unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { - 0xDD, 0x04, 0x24, // fld qword (%esp) - 0x83, 0xC4, 16 // add esp, 16 - }; - - static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { - 0xDD, 0x1E, /* fstp qword [esi] */ - 0x83, 0xC6, 8, /* add esi, 8 */ - }; - - #define GLUE_SET_PX_FROM_WTP_SIZE 2 - static void GLUE_SET_PX_FROM_WTP(void *b, int wv) - { - static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ - {0x89,0xF0}, // mov eax, esi - {0x89,0xF7}, // mov edi, esi - {0x89,0xF1}, // mov ecx, esi - }; - memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); - } - - #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 - static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) - { - static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ - {0xDD,0x00}, // fld qword [eax] - {0xDD,0x07}, // fld qword [edi] - {0xDD,0x01}, // fld qword [ecx] - }; - memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); - } - -#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) -static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) -{ - GLUE_SET_PX_FROM_WTP(buf,wv); - memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); -}; - - -const static unsigned char GLUE_RET=0xC3; - -static int GLUE_RESET_WTP(unsigned char *out, void *ptr) -{ - if (out) - { - *out++ = 0xBE; // mov esi, constant - memcpy(out,&ptr,sizeof(void *)); - out+=sizeof(void *); - } - return 1+sizeof(void *); -} - - -static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR ramptr) -{ - #ifndef NSEEL_EEL1_COMPAT_MODE - short oldsw, newsw; - #endif - #ifdef _MSC_VER - - __asm - { -#ifndef NSEEL_EEL1_COMPAT_MODE - fnstcw [oldsw] - mov ax, [oldsw] - or ax, 0xC00 - mov [newsw], ax - fldcw [newsw] -#endif - - mov eax, cp - mov ebx, ramptr - - pushad - mov ebp, esp - and esp, -16 - - // on win32, which _MSC_VER implies, we keep things aligned to 16 bytes, and if we call a win32 function, - // the stack is 16 byte aligned before the call, meaning that if calling a function with no frame pointer, - // the stack would be aligned to a 16 byte boundary +4, which isn't good for performance. Having said that, - // normally we compile with frame pointers (which brings that to 16 byte + 8, which is fine), or ICC, which - // for nontrivial functions will align the stack itself (for very short functions, it appears to weigh the - // cost of aligning the stack vs that of the slower misaligned double accesses). - - // it may be worthwhile (at some point) to put some logic in the code that calls out to functions - // (generic1parm etc) to detect which alignment would be most optimal. - sub esp, 12 - call eax - mov esp, ebp - popad -#ifndef NSEEL_EEL1_COMPAT_MODE - fldcw [oldsw] -#endif - }; - - #else // gcc x86 - __asm__( -#ifndef NSEEL_EEL1_COMPAT_MODE - "fnstcw %2\n" - "movw %2, %%ax\n" - "orw $0xC00, %%ax\n" - "movw %%ax, %3\n" - "fldcw %3\n" -#endif - "pushl %%ebx\n" - "movl %%ecx, %%ebx\n" - "pushl %%ebp\n" - "movl %%esp, %%ebp\n" - "andl $-16, %%esp\n" // align stack to 16 bytes - "subl $12, %%esp\n" // call will push 4 bytes on stack, align for that - "call *%%edx\n" - "leave\n" - "popl %%ebx\n" -#ifndef NSEEL_EEL1_COMPAT_MODE - "fldcw %2\n" -#endif - :: - "d" (cp), "c" (ramptr) -#ifndef NSEEL_EEL1_COMPAT_MODE - , "g" (&oldsw), "g" (&newsw) -#endif - : "%eax","%esi","%edi"); - #endif //gcc x86 -} - -static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) -{ - char *p=(char*)_p; - INT_PTR scan = 0xFEFEFEFE; - while (*(INT_PTR *)p != scan) p++; - *(INT_PTR *)p = newv; - return (unsigned char *) (((INT_PTR*)p)+1); -} - -#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) - - -#define GLUE_INLINE_LOOPS - -static const unsigned char GLUE_LOOP_LOADCNT[]={ - 0xDB, 0x1E, //fistp dword [esi] - 0x8B, 0x0E, // mov ecx, [esi] - 0x81, 0xf9, 1,0,0,0, // cmp ecx, 1 - 0x0F, 0x8C, 0,0,0,0, // JL -}; -static const unsigned char GLUE_LOOP_CLAMPCNT[]={ - 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN - 0x0F, 0x8C, 5,0,0,0, // JL over-the-mov - 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN -}; -static const unsigned char GLUE_LOOP_BEGIN[]={ - 0x56, //push esi - 0x51, // push ecx - 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 -}; -static const unsigned char GLUE_LOOP_END[]={ - 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 - 0x59, //pop ecx - 0x5E, // pop esi - 0x49, // dec ecx - 0x0f, 0x85, 0,0,0,0, // jnz ... -}; - - -static const unsigned char GLUE_WHILE_SETUP[]={ - 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN -}; -static const unsigned char GLUE_WHILE_BEGIN[]={ - 0x56, //push esi - 0x51, // push ecx - 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 -}; -static const unsigned char GLUE_WHILE_END[]={ - 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 - 0x59, //pop ecx - 0x5E, // pop esi - - - 0x49, // dec ecx - 0x0f, 0x84, 0,0,0,0, // jz endpt -}; -static const unsigned char GLUE_WHILE_CHECK_RV[] = { - 0x85, 0xC0, // test eax, eax - 0x0F, 0x85, 0,0,0,0 // jnz looppt -}; - -static const unsigned char GLUE_SET_P1_Z[] = { 0x29, 0xC0 }; // sub eax, eax -static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 - -#define GLUE_HAS_FXCH -static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; - -#define GLUE_HAS_FLDZ -static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; -#define GLUE_HAS_FLD1 -static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; - -static EEL_F negativezeropointfive=-0.5f; -static EEL_F onepointfive=1.5f; -#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, - - -#define GLUE_HAS_NATIVE_TRIGSQRTLOG - -static void *GLUE_realAddress(void *fn, void *fn_e, int *size) -{ - static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; - unsigned char *p = (unsigned char *)fn; - - #if defined(_DEBUG) && defined(_MSC_VER) - if (*p == 0xE9) // this means jump to the following address (debug stub) - { - p += 5 + *(int *)(p+1); - } - #endif - - while (memcmp(p,sig,sizeof(sig))) p++; - p+=sizeof(sig); - fn = p; - - while (memcmp(p,sig,sizeof(sig))) p++; - *size = p - (unsigned char *)fn; - return fn; -} - -#endif diff --git a/WDL/eel2/glue_x86_64.h b/WDL/eel2/glue_x86_64.h deleted file mode 100644 index 95598c62..00000000 --- a/WDL/eel2/glue_x86_64.h +++ /dev/null @@ -1,261 +0,0 @@ -#ifndef _NSEEL_GLUE_X86_64_H_ -#define _NSEEL_GLUE_X86_64_H_ - -#define GLUE_MAX_FPSTACK_SIZE 8 -#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset)) - -#define GLUE_PREFER_NONFP_DV_ASSIGNS - -static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp -static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz -static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz - - -#define GLUE_FUNC_ENTER_SIZE 0 -#define GLUE_FUNC_LEAVE_SIZE 0 -const static unsigned int GLUE_FUNC_ENTER[1]; -const static unsigned int GLUE_FUNC_LEAVE[1]; - - // on x86-64: - // stack is always 16 byte aligned - // pushing values to the stack (for eel functions) has alignment pushed first, then value (value is at the lower address) - // pushing pointers to the stack has the pointer pushed first, then the alignment (pointer is at the higher address) - #define GLUE_MOV_PX_DIRECTVALUE_SIZE 10 - static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wr) { - const static unsigned short tab[3] = - { - 0xB848 /* mov rax, dv*/, - 0xBF48 /* mov rdi, dv */ , - 0xB948 /* mov rcx, dv */ - }; - unsigned short *bb = (unsigned short *)b; - *bb++ = tab[wr]; // mov rax, directvalue - *(INT_PTR *)bb = v; - } - - const static unsigned char GLUE_PUSH_P1[2]={ 0x50,0x50}; // push rax (pointer); push rax (alignment) - - #define GLUE_POP_PX_SIZE 2 - static void GLUE_POP_PX(void *b, int wv) - { - static const unsigned char tab[3][GLUE_POP_PX_SIZE]= - { - {0x58,/*pop eax*/ 0x58}, // pop alignment, then pop pointer - {0x5F,/*pop edi*/ 0x5F}, - {0x59,/*pop ecx*/ 0x59}, - }; - memcpy(b,tab[wv],GLUE_POP_PX_SIZE); - } - - static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = - { - 0x50, /*push rax - for alignment */ - 0xff, 0x30, /* push qword [rax] */ - }; - - static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) // trashes P2 (rdi) and P3 (rcx) - { - if (buf) - { - *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue - *buf++ = 0x8f; *buf++ = 0x01; // pop qword [rcx] - *buf++ = 0x5F ; // pop rdi (alignment, safe to trash rdi though) - } - return 1+10+2; - } - - static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) // trashes P2/P3 - { - if (buf) - { - *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue - *buf++ = 0x48; *buf++ = 0x8B; *buf++ = 0x38; // mov rdi, [rax] - *buf++ = 0x48; *buf++ = 0x89; *buf++ = 0x39; // mov [rcx], rdi - } - - return 3 + 10 + 3; - } - - static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) - { - if (buf) - { - *buf++ = 0x48; - *buf++ = 0xB8; - *(void **) buf = destptr; buf+=8; // mov rax, directvalue - *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [rax] - } - return 2+8+2; - } - - - #define GLUE_SET_PX_FROM_P1_SIZE 3 - static void GLUE_SET_PX_FROM_P1(void *b, int wv) - { - static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ - {0x90,0x90,0x90}, // should never be used! (nopnop) - {0x48,0x89,0xC7}, // mov rdi, rax - {0x48,0x89,0xC1}, // mov rcx, rax - }; - memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); - } - - - #define GLUE_POP_FPSTACK_SIZE 2 - static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 - - static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { - 0x48, 0x81, 0xEC, 16, 0,0,0, // sub rsp, 16 - 0xDD, 0x1C, 0x24 // fstp qword (%rsp) - }; - - static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { - 0xDD, 0x1E, /* fstp qword [rsi] */ - 0x48, 0x81, 0xC6, 8, 0,0,0,/* add rsi, 8 */ - }; - - #define GLUE_SET_PX_FROM_WTP_SIZE 3 - static void GLUE_SET_PX_FROM_WTP(void *b, int wv) - { - static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ - {0x48, 0x89,0xF0}, // mov rax, rsi - {0x48, 0x89,0xF7}, // mov rdi, rsi - {0x48, 0x89,0xF1}, // mov rcx, rsi - }; - memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); - } - - #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 - static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) - { - static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ - {0xDD,0x00}, // fld qword [rax] - {0xDD,0x07}, // fld qword [rdi] - {0xDD,0x01}, // fld qword [rcx] - }; - memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); - } - static unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { - 0xDD, 0x04, 0x24, // fld qword (%rsp) - 0x48, 0x81, 0xC4, 16, 0,0,0, // add rsp, 16 - }; - - -#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) -static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) -{ - GLUE_SET_PX_FROM_WTP(buf,wv); - memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); -}; - - -const static unsigned char GLUE_RET=0xC3; - -static int GLUE_RESET_WTP(unsigned char *out, void *ptr) -{ - if (out) - { - *out++ = 0x48; - *out++ = 0xBE; // mov rsi, constant64 - *(void **)out = ptr; - out+=sizeof(void *); - } - return 2+sizeof(void *); -} - -extern void win64_callcode(INT_PTR code, INT_PTR ram_tab); -#define GLUE_CALL_CODE(bp, cp, rt) win64_callcode(cp, rt) - -static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) -{ - char *p=(char*)_p; - INT_PTR scan = 0xFEFEFEFEFEFEFEFE; - while (*(INT_PTR *)p != scan) p++; - *(INT_PTR *)p = newv; - return (unsigned char *) (((INT_PTR*)p)+1); -} - -#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) - -#define GLUE_INLINE_LOOPS - -static const unsigned char GLUE_LOOP_LOADCNT[]={ - 0xDD, 0x0E, //fistTp qword [rsi] - 0x48, 0x8B, 0x0E, // mov rcx, [rsi] - 0x48, 0x81, 0xf9, 1,0,0,0, // cmp rcx, 1 - 0x0F, 0x8C, 0,0,0,0, // JL -}; -static const unsigned char GLUE_LOOP_CLAMPCNT[]={ - 0x48, 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN - 0x0F, 0x8C, 10,0,0,0, // JL over-the-mov - 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN -}; -static const unsigned char GLUE_LOOP_BEGIN[]={ - 0x56, //push rsi - 0x51, // push rcx -}; -static const unsigned char GLUE_LOOP_END[]={ - 0x59, //pop rcx - 0x5E, // pop rsi - 0xff, 0xc9, // dec rcx - 0x0f, 0x85, 0,0,0,0, // jnz ... -}; - - - -static const unsigned char GLUE_WHILE_SETUP[]={ - 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN -}; -static const unsigned char GLUE_WHILE_BEGIN[]={ - 0x56, //push rsi - 0x51, // push rcx -}; -static const unsigned char GLUE_WHILE_END[]={ - 0x59, //pop rcx - 0x5E, // pop rsi - - 0xff, 0xc9, // dec rcx - 0x0f, 0x84, 0,0,0,0, // jz endpt -}; -static const unsigned char GLUE_WHILE_CHECK_RV[] = { - 0x85, 0xC0, // test eax, eax - 0x0F, 0x85, 0,0,0,0 // jnz looppt -}; - -static const unsigned char GLUE_SET_P1_Z[] = { 0x48, 0x29, 0xC0 }; // sub rax, rax -static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 - - -#define GLUE_HAS_FXCH -static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; - -#define GLUE_HAS_FLDZ -static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; -#define GLUE_HAS_FLD1 -static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; - - -static EEL_F negativezeropointfive=-0.5f; -static EEL_F onepointfive=1.5f; -#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, - -#define GLUE_HAS_NATIVE_TRIGSQRTLOG - - -static void *GLUE_realAddress(void *fn, void *fn_e, int *size) -{ - static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; - unsigned char *p = (unsigned char *)fn; - - while (memcmp(p,sig,sizeof(sig))) p++; - p+=sizeof(sig); - fn = p; - - while (memcmp(p,sig,sizeof(sig))) p++; - *size = p - (unsigned char *)fn; - return fn; -} - -// end of x86-64 - -#endif diff --git a/WDL/eel2/ns-eel-addfuncs.h b/WDL/eel2/ns-eel-addfuncs.h deleted file mode 100644 index e1e0d6f7..00000000 --- a/WDL/eel2/ns-eel-addfuncs.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Nullsoft Expression Evaluator Library (NS-EEL) - Copyright (C) 1999-2003 Nullsoft, Inc. - - ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef __NS_EEL_ADDFUNCS_H__ -#define __NS_EEL_ADDFUNCS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct _compileContext; - -void *NSEEL_PProc_RAM(void *data, int data_size, struct _compileContext *ctx); -void *NSEEL_PProc_THIS(void *data, int data_size, struct _compileContext *ctx); - - -#ifdef EEL_TARGET_PORTABLE - -extern EEL_BC_TYPE _asm_generic3parm[]; // 3 double * parms, returning double * -extern EEL_BC_TYPE _asm_generic3parm_end[]; -extern EEL_BC_TYPE _asm_generic3parm_retd[]; // 3 double * parms, returning double -extern EEL_BC_TYPE _asm_generic3parm_retd_end[]; -extern EEL_BC_TYPE _asm_generic2parm[]; // 2 double * parms, returning double * -extern EEL_BC_TYPE _asm_generic2parm_end[]; -extern EEL_BC_TYPE _asm_generic2parm_retd[]; // 2 double * parms, returning double -extern EEL_BC_TYPE _asm_generic2parm_retd_end[]; -extern EEL_BC_TYPE _asm_generic1parm[]; // 1 double * parms, returning double * -extern EEL_BC_TYPE _asm_generic1parm_end[]; -extern EEL_BC_TYPE _asm_generic1parm_retd[]; // 1 double * parms, returning double -extern EEL_BC_TYPE _asm_generic1parm_retd_end[]; - -#else - -void _asm_generic3parm(void); // 3 double * parms, returning double * -void _asm_generic3parm_end(void); -void _asm_generic3parm_retd(void); // 3 double * parms, returning double -void _asm_generic3parm_retd_end(void); -void _asm_generic2parm(void); // 2 double * parms, returning double * -void _asm_generic2parm_end(void); -void _asm_generic2parm_retd(void); // 2 double * parms, returning double -void _asm_generic2parm_retd_end(void); -void _asm_generic1parm(void); // 1 double * parms, returning double * -void _asm_generic1parm_end(void); -void _asm_generic1parm_retd(void); // 1 double * parms, returning double -void _asm_generic1parm_retd_end(void); - -#endif - -#if EEL_F_SIZE == 4 -#define EEL_F_SSTR "4" -#define EEL_F_SUFFIX "s" -#else -#define EEL_F_SSTR "8" -#define EEL_F_SUFFIX "l" -#endif - -#ifdef _MSC_VER -#define NSEEL_CGEN_CALL __cdecl -#else -#define NSEEL_CGEN_CALL -#endif - -#ifdef __cplusplus -}; - -#endif -#endif//__NS_EEL_ADDFUNCS_H__ diff --git a/WDL/eel2/ns-eel-int.h b/WDL/eel2/ns-eel-int.h deleted file mode 100644 index e9e04702..00000000 --- a/WDL/eel2/ns-eel-int.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - Nullsoft Expression Evaluator Library (NS-EEL) - Copyright (C) 1999-2003 Nullsoft, Inc. - - ns-eel-int.h: internal code definition header. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef __NS_EELINT_H__ -#define __NS_EELINT_H__ - -#ifdef _WIN32 -#include -#else -#include "../wdltypes.h" -#endif - -#include "ns-eel.h" -#include "ns-eel-addfuncs.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -enum { - - // these ignore fn in opcodes, just use fntype to determine function - FN_MULTIPLY=0, - FN_DIVIDE, - FN_JOIN_STATEMENTS, - FN_ADD, - FN_SUB, - FN_AND, - FN_OR, - FN_UMINUS, - FN_UPLUS, - FUNCTYPE_SIMPLEMAX, - - - FUNCTYPE_FUNCTIONTYPEREC, // fn is a functionType * - FUNCTYPE_EELFUNC, // fn is a _codeHandleFunctionRec * - - - // _codeHandleFunctionRec*, relname in opcode field is the namespace specifier - // (i.e. if called via this.something.function(), "something".) - // note that calls to function() or some.function() are both normal FUNCTYPE_EELFUNC calls, as they can be resolved - // earlier in the process - FUNCTYPE_EELFUNC_THIS, // fn is a _codeHandleFunctionRec * to base function, relname set -}; - - - -#define YYSTYPE opcodeRec * - -#define NSEEL_CLOSEFACTOR 0.00001 - -typedef struct -{ - int srcByteCount; - int destByteCount; -} lineRecItem; - - -typedef struct opcodeRec opcodeRec; - -typedef struct _codeHandleFunctionRec -{ - struct _codeHandleFunctionRec *next; // main linked list (only used for high level functions) - struct _codeHandleFunctionRec *derivedCopies; // separate linked list, head being the main function, other copies being derived versions - - void *startptr; // compiled code (may be cleared + recompiled when shraed) - opcodeRec *opcodes; - - int startptr_size; - int tmpspace_req; - - int num_params; - - int rvMode; // RETURNVALUE_* - int fpStackUsage; // 0-8, usually - int canHaveDenormalOutput; - - // local storage's first items are the parameters, then locals. Note that the opcodes will reference localstorage[] via VARPTRPTR, but - // the values localstorage[x] points are reallocated from context-to-context, if it is a common function. - - // separately allocated list of pointers, the contents of the list should be zeroed on context changes if a common function - // note that when making variations on a function (context), it is shared, but since it is zeroed on context changes, it is context-local - int localstorage_size; - EEL_F **localstorage; - - int isCommonFunction; - int usesThisPointer; - - char fname[NSEEL_MAX_VARIABLE_NAMELEN+1]; -} _codeHandleFunctionRec; - -#define LLB_DSIZE (65536-64) -typedef struct _llBlock { - struct _llBlock *next; - int sizeused; - char block[LLB_DSIZE]; -} llBlock; - -typedef struct { - llBlock *blocks, - *blocks_data; - void *workTable; // references a chunk in blocks_data - - void *code; - int code_size; // in case the caller wants to write it out - int code_stats[4]; - - int want_stack; - void *stack; // references a chunk in blocks_data, somewhere within the complete NSEEL_STACK_SIZE aligned at NSEEL_STACK_SIZE - - void *ramPtr; - - int workTable_size; // size (minus padding/extra space) of workTable -- only used if EEL_VALIDATE_WORKTABLE_USE set, but might be handy to have around too -} codeHandleType; - - - -typedef struct _compileContext -{ - EEL_F **varTable_Values; - char ***varTable_Names; - int varTable_numBlocks; - - int errVar; - opcodeRec *result; - char last_error_string[256]; - -#ifdef NSEEL_USE_OLD_PARSER - int colCount; - YYSTYPE yylval; - int yychar; /* the lookahead symbol */ - int yynerrs; /* number of parse errors so far */ - - char *llsave[16]; /* Look ahead buffer */ - char llbuf[NSEEL_MAX_VARIABLE_NAMELEN*2+128]; /* work buffer */ - char *llp1;// = &llbuf[0]; /* pointer to next avail. in token */ - char *llp2;// = &llbuf[0]; /* pointer to end of lookahead */ - char *llend;// = &llbuf[0]; /* pointer to end of token */ - char *llebuf;// = &llbuf[sizeof llbuf]; - int lleof; -#else - void *scanner; - #ifdef NSEEL_SUPER_MINIMAL_LEXER - char *rdbuf, *rdbuf_start; - #else - const char *inputbufferptr; - int errVar_l; - #endif -#endif - - llBlock *tmpblocks_head, // used while compiling, and freed after compiling - - *blocks_head, // used while compiling, transferred to code context (these are pages marked as executable) - *blocks_head_data, // used while compiling, transferred to code context - - *pblocks; // persistent blocks, stores data used by varTable_Names, varTable_Values, etc. - - int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes - - lineRecItem *compileLineRecs; - int compileLineRecs_size; - int compileLineRecs_alloc; - - _codeHandleFunctionRec *functions_local, *functions_common; - - // state used while generating functions - int optimizeDisableFlags; - struct opcodeRec *directValueCache; // linked list using fn as next - - int isSharedFunctions; - int function_usesThisPointer; - // [0] is parameter+local symbols (combined space) - // [1] is symbols which get implied "this." if used - int function_localTable_Size[2]; // for parameters only - char **function_localTable_Names[2]; // lists of pointers - EEL_F **function_localTable_ValuePtrs; - const char *function_curName; // name of current function - - codeHandleType *tmpCodeHandle; - - struct - { - int needfree; - int __pad; - double closefact; - EEL_F *blocks[NSEEL_RAM_BLOCKS]; - } ram_state -#ifdef __GNUC__ - __attribute__ ((aligned (8))) -#endif - ; - - void *gram_blocks; - - void *caller_this; -} -compileContext; - -#define NSEEL_VARS_PER_BLOCK 64 - -#define NSEEL_NPARAMS_FLAG_CONST 0x80000 -typedef struct { - const char *name; - void *afunc; - void *func_e; - int nParams; - void *replptrs[4]; - NSEEL_PPPROC pProc; -} functionType; - - -typedef struct -{ - int refcnt; - char isreg; -} varNameHdr; - -extern functionType *nseel_getFunctionFromTable(int idx); - -opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value); -opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue); -opcodeRec *nseel_createCompiledValuePtrPtr(compileContext *ctx, EEL_F **addrValue); - -opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2); -opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2); -opcodeRec *nseel_createCompiledFunctionCall(compileContext *ctx, int np, int ftype, void *fn); -opcodeRec *nseel_createCompiledFunctionCallEELThis(compileContext *ctx, _codeHandleFunctionRec *fn, const char *thistext); -opcodeRec *nseel_setCompiledFunctionCallParameters(opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3); - -opcodeRec *nseel_createCompiledValueFromNamespaceName(compileContext *ctx, const char *relName); -EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg); -_codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr); - -extern EEL_F nseel_globalregs[100]; - -#ifdef NSEEL_USE_OLD_PARSER - #define VALUE 258 - #define IDENTIFIER 259 - #define FUNCTION1 260 - #define FUNCTION2 261 - #define FUNCTION3 262 - #define UMINUS 263 - #define UPLUS 264 - - #define INTCONST 1 - #define DBLCONST 2 - #define HEXCONST 3 - #define VARIABLE 4 - #define OTHER 5 -#else - #include "y.tab.h" -#endif - -opcodeRec *nseel_translate(compileContext *ctx, const char *tmp); -int nseel_gettokenlen(compileContext *ctx, int maxlen); -opcodeRec *nseel_lookup(compileContext *ctx, int *typeOfObject, const char *sname); -int nseel_yyerror(compileContext *ctx); -int nseel_yylex(compileContext *ctx, char **exp); -int nseel_yyparse(compileContext *ctx, char *exp); -void nseel_llinit(compileContext *ctx); -int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz); - -struct lextab { - int llendst; /* Last state number */ - char *lldefault; /* Default state table */ - char *llnext; /* Next state table */ - char *llcheck; /* Check table */ - int *llbase; /* Base table */ - int llnxtmax; /* Last in next table */ - int (*llmove)(); /* Move between states */ - char *llfinal; /* Final state descriptions */ - int (*llactr)(); /* Action routine */ - int *lllook; /* Look ahead vector if != NULL */ - char *llign; /* Ignore char vec if != NULL */ - char *llbrk; /* Break char vec if != NULL */ - char *llill; /* Illegal char vec if != NULL */ -}; -extern struct lextab nseel_lextab; - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **blocks, unsigned int w); -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w); -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr); -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which); -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr); - - - -#ifndef max -#define max(x,y) ((x)<(y)?(y):(x)) -#define min(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifdef __cplusplus -} -#endif - -#endif//__NS_EELINT_H__ diff --git a/WDL/eel2/ns-eel.h b/WDL/eel2/ns-eel.h deleted file mode 100644 index 27fde9a4..00000000 --- a/WDL/eel2/ns-eel.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - Nullsoft Expression Evaluator Library (NS-EEL) - Copyright (C) 1999-2003 Nullsoft, Inc. - - ns-eel.h: main application interface header - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - - -#ifndef __NS_EEL_H__ -#define __NS_EEL_H__ - -// put standard includes here -#include -#include - -#ifdef _MSC_VER -#define strcasecmp stricmp -#define strncasecmp strnicmp -#endif - -#ifndef EEL_F_SIZE -#define EEL_F_SIZE 8 -#endif - -#include "../wdltypes.h" - -#if EEL_F_SIZE == 4 -typedef float EEL_F; -#else -typedef double EEL_F WDL_FIXALIGN; -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -// host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once) - - // implement if you will be running the code in same VM from multiple threads, - // or VMs that have the same GRAM pointer from different threads, or multiple - // VMs that have a NULL GRAM pointer from multiple threads. - // if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank. - - // or if you're daring.... - -void NSEEL_HOSTSTUB_EnterMutex(); -void NSEEL_HOSTSTUB_LeaveMutex(); - - -int NSEEL_init(); // returns 0 on success. clears any added functions as well - - - -// adds a function that returns a value (EEL_F) -#define NSEEL_addfunc_retval(name,np,pproc,fptr) \ - NSEEL_addfunctionex(name,np,(char *)_asm_generic##np##parm_retd,(char *)_asm_generic##np##parm_retd##_end-(char *)_asm_generic##np##parm_retd,(void*)(pproc),(void*)(fptr)) - -// adds a function that returns a pointer (EEL_F*) -#define NSEEL_addfunc_retptr(name,np,pproc,fptr) \ - NSEEL_addfunctionex(name,np,(char *)_asm_generic##np##parm,(char *)_asm_generic##np##parm##_end-(char *)_asm_generic##np##parm,(void*)(pproc),(void*)(fptr)) - -// adds a void or bool function -#define NSEEL_addfunc_retbool(name,np,pproc,fptr) \ - NSEEL_addfunctionex(name,(np)|(/*BIF_RETURNSBOOL*/0x00400),(char *)_asm_generic##np##parm_retd,(char *)_asm_generic##np##parm_retd##_end-(char *)_asm_generic##np##parm_retd,(void*)(pproc),(void*)(fptr)) - - -#define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0) -#define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0) - -typedef void *(*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data); - -void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2); - -void NSEEL_quit(); - -int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles -EEL_F *NSEEL_getglobalregs(); - -typedef void *NSEEL_VMCTX; -typedef void *NSEEL_CODEHANDLE; - -NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle -void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well - -void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx); -void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx); -void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx); -void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop - -EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation) -int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0 - -void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used -void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory -int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested? - -// if you set this, it uses a local GMEM context. -// Must be set before compilation. -// void *p=NULL; -// NSEEL_VM_SetGRAM(ctx,&p); -// .. do stuff -// NSEEL_VM_FreeGRAM(&p); -void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram); -void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context. -void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr); - - -NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, const char *code, int lineoffs); -#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS 1 // allows that code's functions to be used in other code (note you shouldn't destroy that codehandle without destroying others first if used) -#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET 2 // resets common code functions - -NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags); - -char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx); -void NSEEL_code_execute(NSEEL_CODEHANDLE code); -void NSEEL_code_free(NSEEL_CODEHANDLE code); -int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes - - -// global memory control/view -extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes -extern unsigned int NSEEL_RAM_memused; -extern int NSEEL_RAM_memused_errors; - - - -// configuration: - - // the old parser may have more quirks. - // Changes in the new parser: - // 1) expressions such as a = (1+5;3); now work as expected (a is set to 3, rather than 4). - // 2) 0xHEXNUMBER is now allowed (old parser required $xHEXNUMBER - // 3) error notices (unsure which is more accurate) - // 4) new parser allows more than 3 parameter eel-functions (up to NSEEL_MAX_EELFUNC_PARAMETERS) - - //#define NSEEL_USE_OLD_PARSER -#define NSEEL_SUPER_MINIMAL_LEXER // smaller code that uses far less ram, but the flex version we'll keep around too in case we want to do fancier things someday - - // #define NSEEL_EEL1_COMPAT_MODE // supports old behaviors (continue after failed compile), old functions _bnot etc. - -#define NSEEL_MAX_VARIABLE_NAMELEN 128 // define this to override the max variable length -#define NSEEL_MAX_EELFUNC_PARAMETERS 40 - -// maximum loop length -#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576 // scary, we can do a million entries. probably will never want to, though. -#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR "1048576" - - -#define NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE 2048 - -// when a VM ctx doesn't have a GRAM context set, make the global one this big -#define NSEEL_SHARED_GRAM_SIZE (1<<20) - - - - -// note: if you wish to change NSEEL_RAM_*, and your target is x86-64, you will need to regenerate things. - -// on osx: -// php a2x64.php win64x -// php a2x64.php macho64 - -// or on win32: -// php a2x64.php -// php a2x64.php macho64x -// this will regenerate the .asm files and object files - -// 128*65536 = ~8million entries. (64MB RAM used) - - -#define NSEEL_RAM_BLOCKS_LOG2 7 -#define NSEEL_RAM_ITEMSPERBLOCK_LOG2 16 - -#define NSEEL_RAM_BLOCKS (1 << NSEEL_RAM_BLOCKS_LOG2) -#define NSEEL_RAM_ITEMSPERBLOCK (1<yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#define YYLEX nseel_yylex(ctx,&exp) - -/* If nonreentrant, generate the variables here */ - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#define YYINITDEPTH 5000 -#define YYMAXDEPTH 5000 - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0) - -//#ln 131 "bison.simple" -int nseel_yyparse(compileContext *ctx, char *exp) -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - - int yystacksize = YYINITDEPTH; - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - - ctx->yylval = 0; - yystate = 0; - yyerrstatus = 0; - ctx->yynerrs = 0; - ctx->yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. */ - - yyssp = yyss - 1; - yyvsp = yyvs; - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ -// YYSTYPE *yyvs1 = yyvs; - // short *yyss1 = yyss; - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - - if (yystacksize >= YYMAXDEPTH) - { - YYERROR("internal error: parser stack overflow"); - return 2; - } - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; - - - if (yyssp >= yyss + yystacksize - 1) YYABORT; - } - - -// yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (ctx->yychar == YYEMPTY) - { -// yyStackSize = yyssp - (yyss - 1); - ctx->yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (ctx->yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - ctx->yychar = YYEOF; /* Don't call YYLEX any more */ - - } - else - { - yychar1 = YYTRANSLATE(ctx->yychar); - - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - - - /* Discard the token being shifted unless it is eof. */ - if (ctx->yychar != YYEOF) - ctx->yychar = YYEMPTY; - - *++yyvsp = ctx->yylval; - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - - - switch (yyn) { - -case 1: -//#ln 32 "cal.y" -{ yyval = yyvsp[0]; ctx->result = yyvsp[0]; ; - break;} -case 2: -//#ln 34 "cal.y" -{ { - ctx->result = yyval = yyvsp[0]; // unused! - } - ; - break;} -case 3: -//#ln 50 "cal.y" -{ yyval = yyvsp[0] ; - break;} -case 4: -//#ln 55 "cal.y" -{ yyval = yyvsp[0];; - break;} -case 5: -//#ln 57 "cal.y" -{ yyval = yyvsp[0];; - break;} -case 6: -//#ln 59 "cal.y" -{ yyval = yyvsp[-1];; - break;} -case 7: -//#ln 64 "cal.y" -{ yyval = yyvsp[0]; ; - break;} -case 8: -//#ln 66 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_MULTIPLY, 2, yyvsp[-2], yyvsp[0]); - break;} -case 9: -//#ln 72 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_DIVIDE, 2, yyvsp[-2], yyvsp[0]); - break;} -case 10: -//#ln 78 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_JOIN_STATEMENTS, 2, yyvsp[-2], yyvsp[0]); - break;} -case 11: -//#ln 84 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_ADD, 2, yyvsp[-2], yyvsp[0]); - break;} -case 12: -//#ln 90 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_SUB, 2, yyvsp[-2], yyvsp[0]); - break;} -case 13: -//#ln 96 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_AND, 2, yyvsp[-2], yyvsp[0]); - break;} -case 14: -//#ln 102 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_OR, 2, yyvsp[-2], yyvsp[0]); - break;} -case 15: -//#ln 108 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_UMINUS, 1, yyvsp[0], 0); - break;} -case 16: -//#ln 114 "cal.y" -{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_UPLUS, 1, yyvsp[0], 0); - break;} -case 17: -//#ln 120 "cal.y" -{ yyval = yyvsp[0]; - break;} -case 18: -//#ln 125 "cal.y" -{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-3], yyvsp[-1], 0, 0); - break;} -case 19: -//#ln 131 "cal.y" -{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-5], yyvsp[-3], yyvsp[-1], 0); - break;} -case 20: -//#ln 137 "cal.y" -{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]); - break;} -} - /* the action file gets copied in in place of this dollarsign */ -//#ln 362 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; - - *++yyvsp = yyval; - - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++ctx->yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; -#error this should not compile - msg = (char *) xmalloc(size + 15); - strcpy(msg, "syntax error"); - - if (count < 5) - { - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - YYERROR(msg); - free(msg); - } - else -#endif /* YYERROR_VERBOSE */ - YYERROR("syntax error"); - } - -//yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (ctx->yychar == YYEOF) YYABORT; - - ctx->yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; - - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = ctx->yylval; - - yystate = yyn; - goto yynewstate; -} - -#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-cfunc.c b/WDL/eel2/nseel-cfunc.c deleted file mode 100644 index fff36061..00000000 --- a/WDL/eel2/nseel-cfunc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) v2 - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - nseel-cfunc.c: assembly/C implementation of operator/function templates - This file should be ideally compiled with optimizations towards "minimize size" - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - - -#include "ns-eel-int.h" -#include -#include - - - -// these are used by our assembly code - - -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0dfUL /* constant vector a */ -#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ - -static unsigned int genrand_int32(void) -{ - - unsigned int y; - static unsigned int mag01[2]={0x0UL, MATRIX_A}; - /* mag01[x] = x * MATRIX_A for x=0,1 */ - - static unsigned int mt[N]; /* the array for the state vector */ - static int mti; /* mti==N+1 means mt[N] is not initialized */ - - - if (!mti) - { - unsigned int s=0x4141f00d; - mt[0]= s & 0xffffffffUL; - for (mti=1; mti> 30)) + mti); - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - mt[mti] &= 0xffffffffUL; - /* for >32 bit machines */ - } - } - - if (mti >= N) { /* generate N words at one time */ - int kk; - - for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; - } - for (;kk> 1) ^ mag01[y & 0x1UL]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; - - mti = 0; - } - - y = mt[mti++]; - - /* Tempering */ - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); - - return y; -} - - - -//--------------------------------------------------------------------------------------------------------------- -EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f) -{ - EEL_F x=floor(f); - if (x < 1.0) x=1.0; - -#ifdef NSEEL_EEL1_COMPAT_MODE - return (EEL_F)(genrand_int32()%(int)x); -#else - return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x); -#endif -} - -//--------------------------------------------------------------------------------------------------------------- - - -#ifndef EEL_TARGET_PORTABLE - -#ifdef __ppc__ -#include "asm-nseel-ppc-gcc.c" -#else - #ifdef _MSC_VER - #ifdef _WIN64 - //nasm - #else - #include "asm-nseel-x86-msvc.c" - #endif - #elif !defined(__LP64__) - #define FUNCTION_MARKER "\n.byte 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90\n" - #include "asm-nseel-x86-gcc.c" - #endif -#endif - -#endif diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c deleted file mode 100644 index 95eceb91..00000000 --- a/WDL/eel2/nseel-compiler.c +++ /dev/null @@ -1,4574 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) v2 - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - nseel-compiler.c - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - - -// for VirtualProtect - -#include "ns-eel-int.h" - -#include "../denormal.h" -#include "../wdlcstring.h" - -#include -#include -#include -#include - -#ifdef __APPLE__ - #ifdef __LP64__ - #define EEL_USE_MPROTECT - #endif -#endif - -#ifdef EEL_USE_MPROTECT -#include -#include -#include -#endif - -#define NSEEL_VARS_MALLOC_CHUNKSIZE 8 - -//#define LOG_OPT -//#define EEL_PPC_NOFREECODE -//#define EEL_PRINT_FAILS -//#define EEL_VALIDATE_WORKTABLE_USE -//#define EEL_VALIDATE_FSTUBS - - -#ifdef EEL_PRINT_FAILS - #ifdef _WIN32 - #define RET_MINUS1_FAIL(x) { OutputDebugString(x); return -1; } - #else - #define RET_MINUS1_FAIL(x) { printf("%s\n",x); return -1; } - #endif -#else -#define RET_MINUS1_FAIL(x) return -1; -#endif - - - -#ifdef EEL_VALIDATE_WORKTABLE_USE - #define MIN_COMPUTABLE_SIZE 0 - #define COMPUTABLE_EXTRA_SPACE 64 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking -#else - #define MIN_COMPUTABLE_SIZE 32 // always use at least this big of a temp storage table (and reset the temp ptr when it goes past this boundary) - #define COMPUTABLE_EXTRA_SPACE 16 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking -#endif - - -/* - P1 is rightmost parameter - P2 is second rightmost, if any - P3 is third rightmost, if any - registers on x86 are (RAX etc on x86-64) - P1(ret) EAX - P2 EDI - P3 ECX - WTP RSI - x86_64: r12 is a pointer to ram_state.blocks - x86_64: r13 is a pointer to closenessfactor - - registers on PPC are: - P1(ret) r3 - P2 r14 - P3 r15 - WTP r16 (r17 has the original value) - r13 is a pointer to ram_state.blocks - - ppc uses f31 and f30 and others for certain constants - - */ - -#ifdef EEL_TARGET_PORTABLE - -#define EEL_DOESNT_NEED_EXEC_PERMS -#include "glue_port.h" - -#elif defined(__ppc__) - -#include "glue_ppc.h" - -#elif defined(_WIN64) || defined(__LP64__) - -#include "glue_x86_64.h" - -#else - -#include "glue_x86.h" - -#endif - -#ifndef GLUE_INVSQRT_NEEDREPL -#define GLUE_INVSQRT_NEEDREPL 0 -#endif - - -// used by //#eel-no-optimize:xxx, in ctx->optimizeDisableFlags -#define OPTFLAG_NO_OPTIMIZE 1 -#define OPTFLAG_NO_FPSTACK 2 -#define OPTFLAG_NO_INLINEFUNC 4 -#define OPTFLAG_FULL_DENORMAL_CHECKS 8 // if set, denormals/NaN are always filtered on assign -#define OPTFLAG_NO_DENORMAL_CHECKS 16 // if set and FULL not set, denormals/NaN are never filtered on assign - - - - -static int nseel_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments -int *NSEEL_getstats() -{ - return nseel_evallib_stats; -} -EEL_F *NSEEL_getglobalregs() -{ - return nseel_globalregs; -} - -// this stuff almost works -static int findByteOffsetInSource(compileContext *ctx, int byteoffs,int *destoffs) -{ - int x; - if (!ctx->compileLineRecs || !ctx->compileLineRecs_size) return *destoffs=0; - if (byteoffs < ctx->compileLineRecs[0].destByteCount) - { - *destoffs=0; - return 1; - } - for (x = 0; x < ctx->compileLineRecs_size-1; x ++) - { - if (byteoffs >= ctx->compileLineRecs[x].destByteCount && - byteoffs < ctx->compileLineRecs[x+1].destByteCount) break; - } - *destoffs=ctx->compileLineRecs[(x&&x==ctx->compileLineRecs_size-1)?x-1:x].srcByteCount; - - return x+2; -} - - -static void onCompileNewLine(compileContext *ctx, int srcBytes, int destBytes) -{ - if (!ctx->compileLineRecs || ctx->compileLineRecs_size >= ctx->compileLineRecs_alloc) - { - ctx->compileLineRecs_alloc = ctx->compileLineRecs_size+1024; - ctx->compileLineRecs = (lineRecItem *)realloc(ctx->compileLineRecs,sizeof(lineRecItem)*ctx->compileLineRecs_alloc); - } - if (ctx->compileLineRecs) - { - ctx->compileLineRecs[ctx->compileLineRecs_size].srcByteCount=srcBytes; - ctx->compileLineRecs[ctx->compileLineRecs_size++].destByteCount=destBytes; - } -} - -static void *__newBlock(llBlock **start,int size, int wantMprotect); - -#define OPCODE_IS_TRIVIAL(x) ((x)->opcodeType <= OPCODETYPE_VARPTRPTR) -enum { - OPCODETYPE_DIRECTVALUE=0, - OPCODETYPE_VALUE_FROM_NAMESPACENAME, // this.* are encoded this way - OPCODETYPE_VARPTR, - OPCODETYPE_VARPTRPTR, - OPCODETYPE_FUNC1, - OPCODETYPE_FUNC2, - OPCODETYPE_FUNC3, - OPCODETYPE_FUNCX, - - OPCODETYPE_MOREPARAMS, - - OPCODETYPE_INVALID, -}; - -struct opcodeRec -{ - int opcodeType; - int fntype; - void *fn; - - union { - struct opcodeRec *parms[3]; - struct { - double directValue; - EEL_F *valuePtr; // if direct value, valuePtr can be cached - } dv; - } parms; - - // allocate extra if using this field. used with: - // OPCODETYPE_VALUE_FROM_NAMESPACENAME - /// or - // OPCODETYPE_FUNC* with fntype=FUNCTYPE_EELFUNC_THIS - char relname[1]; -}; - - - - -static void *newTmpBlock(compileContext *ctx, int size) -{ - const int align = 8; - const int a1=align-1; - char *p=(char*)__newBlock(&ctx->tmpblocks_head,size+a1, 0); - return p+((align-(((INT_PTR)p)&a1))&a1); -} - -static void *__newBlock_align(compileContext *ctx, int size, int align, int isForCode) -{ - const int a1=align-1; - char *p=(char*)__newBlock( - ( - isForCode < 0 ? (isForCode == -2 ? &ctx->pblocks : &ctx->tmpblocks_head) : - isForCode > 0 ? &ctx->blocks_head : - &ctx->blocks_head_data) ,size+a1, isForCode>0); - return p+((align-(((INT_PTR)p)&a1))&a1); -} - -static opcodeRec *newOpCode(compileContext *ctx) -{ - return (opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec),8, ctx->isSharedFunctions ? 0 : -1); -} - -#define newCodeBlock(x,a) __newBlock_align(ctx,x,a,1) -#define newDataBlock(x,a) __newBlock_align(ctx,x,a,0) -#define newCtxDataBlock(x,a) __newBlock_align(ctx,x,a,-2) - -static void freeBlocks(llBlock **start); - -#ifndef DECL_ASMFUNC -#define DECL_ASMFUNC(x) \ - void nseel_asm_##x(void); \ - void nseel_asm_##x##_end(void); - - -void _asm_megabuf(void); -void _asm_megabuf_end(void); -void _asm_gmegabuf(void); -void _asm_gmegabuf_end(void); - -#endif - - - DECL_ASMFUNC(booltofp) - DECL_ASMFUNC(fptobool) - DECL_ASMFUNC(sin) - DECL_ASMFUNC(cos) - DECL_ASMFUNC(tan) - DECL_ASMFUNC(1pdd) - DECL_ASMFUNC(2pdd) - DECL_ASMFUNC(2pdds) - DECL_ASMFUNC(1pp) - DECL_ASMFUNC(2pp) - DECL_ASMFUNC(sqr) - DECL_ASMFUNC(sqrt) - DECL_ASMFUNC(log) - DECL_ASMFUNC(log10) - DECL_ASMFUNC(abs) - DECL_ASMFUNC(min) - DECL_ASMFUNC(max) - DECL_ASMFUNC(min_fp) - DECL_ASMFUNC(max_fp) - DECL_ASMFUNC(sig) - DECL_ASMFUNC(sign) - DECL_ASMFUNC(band) - DECL_ASMFUNC(bor) - DECL_ASMFUNC(bnot) - DECL_ASMFUNC(if) - DECL_ASMFUNC(fcall) - DECL_ASMFUNC(repeat) - DECL_ASMFUNC(repeatwhile) - DECL_ASMFUNC(equal) - DECL_ASMFUNC(notequal) - DECL_ASMFUNC(below) - DECL_ASMFUNC(above) - DECL_ASMFUNC(beloweq) - DECL_ASMFUNC(aboveeq) - DECL_ASMFUNC(assign) - DECL_ASMFUNC(assign_fromfp) - DECL_ASMFUNC(assign_fast) - DECL_ASMFUNC(assign_fast_fromfp) - DECL_ASMFUNC(add) - DECL_ASMFUNC(sub) - DECL_ASMFUNC(add_op) - DECL_ASMFUNC(sub_op) - DECL_ASMFUNC(add_op_fast) - DECL_ASMFUNC(sub_op_fast) - DECL_ASMFUNC(mul) - DECL_ASMFUNC(div) - DECL_ASMFUNC(mul_op) - DECL_ASMFUNC(div_op) - DECL_ASMFUNC(mod) - DECL_ASMFUNC(shl) - DECL_ASMFUNC(shr) - DECL_ASMFUNC(mod_op) - DECL_ASMFUNC(or) - DECL_ASMFUNC(or0) - DECL_ASMFUNC(xor) - DECL_ASMFUNC(xor_op) - DECL_ASMFUNC(and) - DECL_ASMFUNC(or_op) - DECL_ASMFUNC(and_op) - DECL_ASMFUNC(uplus) - DECL_ASMFUNC(uminus) - DECL_ASMFUNC(invsqrt) - DECL_ASMFUNC(dbg_getstackptr) - DECL_ASMFUNC(exec2) - - DECL_ASMFUNC(stack_push) - DECL_ASMFUNC(stack_pop) - DECL_ASMFUNC(stack_pop_fast) // just returns value, doesn't mod param - DECL_ASMFUNC(stack_peek) - DECL_ASMFUNC(stack_peek_int) - DECL_ASMFUNC(stack_peek_top) - DECL_ASMFUNC(stack_exch) - -static void *NSEEL_PProc_GRAM(void *data, int data_size, compileContext *ctx) -{ - if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->gram_blocks); - return data; -} - -static void *NSEEL_PProc_Stack(void *data, int data_size, compileContext *ctx) -{ - codeHandleType *ch=ctx->tmpCodeHandle; - - if (data_size>0) - { - UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); - UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); - - ch->want_stack=1; - if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); - - data=EEL_GLUE_set_immediate(data, stackptr); - data=EEL_GLUE_set_immediate(data, m1); // and - data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or - } - return data; -} - -static void *NSEEL_PProc_Stack_PeekInt(void *data, int data_size, compileContext *ctx, INT_PTR offs) -{ - codeHandleType *ch=ctx->tmpCodeHandle; - - if (data_size>0) - { - UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); - UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); - - ch->want_stack=1; - if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); - - data=EEL_GLUE_set_immediate(data, stackptr); - data=EEL_GLUE_set_immediate(data, offs); - data=EEL_GLUE_set_immediate(data, m1); // and - data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or - } - return data; -} -static void *NSEEL_PProc_Stack_PeekTop(void *data, int data_size, compileContext *ctx) -{ - codeHandleType *ch=ctx->tmpCodeHandle; - - if (data_size>0) - { - UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); - - ch->want_stack=1; - if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); - - data=EEL_GLUE_set_immediate(data, stackptr); - } - return data; -} - -#if defined(_MSC_VER) && _MSC_VER >= 1400 -static double __floor(double a) { return floor(a); } -static double __ceil(double a) { return ceil(a); } -#define floor __floor -#define ceil __ceil -#endif - - -#ifdef NSEEL_EEL1_COMPAT_MODE -static double eel1band(double a, double b) -{ - return (fabs(a)>NSEEL_CLOSEFACTOR && fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; -} -static double eel1bor(double a, double b) -{ - return (fabs(a)>NSEEL_CLOSEFACTOR || fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; -} - -static double eel1sigmoid(double x, double constraint) -{ - double t = (1+exp(-x * (constraint))); - return fabs(t)>NSEEL_CLOSEFACTOR ? 1.0/t : 0; -} - -#endif - - - -#define FUNCTIONTYPE_PARAMETERCOUNTMASK 0xff - -#define BIF_NPARAMS_MASK 0x7fff00 -#define BIF_RETURNSONSTACK 0x000100 -#define BIF_LASTPARMONSTACK 0x000200 -#define BIF_RETURNSBOOL 0x000400 // this value is used in ns-eel.h in some macros, be sure to update it there if you change it here -#define BIF_LASTPARM_ASBOOL 0x000800 -#define BIF_WONTMAKEDENORMAL 0x100000 -#define BIF_CLEARDENORMAL 0x200000 - -#if defined(GLUE_HAS_FXCH) && GLUE_MAX_FPSTACK_SIZE > 0 - #define BIF_SECONDLASTPARMST 0x001000 // use with BIF_LASTPARMONSTACK only (last two parameters get passed on fp stack) - #define BIF_LAZYPARMORDERING 0x002000 // allow optimizer to avoid fxch when using BIF_TWOPARMSONFPSTACK_LAZY etc - #define BIF_REVERSEFPORDER 0x004000 // force a fxch (reverse order of last two parameters on fp stack, used by comparison functions) - - #ifndef BIF_FPSTACKUSE - #define BIF_FPSTACKUSE(x) (((x)>=0&&(x)<8) ? ((7-(x))<<16):0) - #endif - #ifndef BIF_GETFPSTACKUSE - #define BIF_GETFPSTACKUSE(x) (7 - (((x)>>16)&7)) - #endif -#else - // do not support fp stack use unless GLUE_HAS_FXCH and GLUE_MAX_FPSTACK_SIZE>0 - #define BIF_SECONDLASTPARMST 0 - #define BIF_LAZYPARMORDERING 0 - #define BIF_REVERSEFPORDER 0 - #define BIF_FPSTACKUSE(x) 0 - #define BIF_GETFPSTACKUSE(x) 0 -#endif - -#define BIF_TWOPARMSONFPSTACK (BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) -#define BIF_TWOPARMSONFPSTACK_LAZY (BIF_LAZYPARMORDERING|BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) - - - - -EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f); - -#define FNPTR_HAS_CONDITIONAL_EXEC(op) (op->fntype == FUNCTYPE_FUNCTIONTYPEREC && (functionType*)op->fn >= fnTable1 && (functionType*)op->fn < fnTable1+5) - -static functionType fnTable1[] = { - { "_if", nseel_asm_if,nseel_asm_if_end, 3|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL, }, - { "_and", nseel_asm_band,nseel_asm_band_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSBOOL } , - { "_or", nseel_asm_bor,nseel_asm_bor_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSBOOL } , - { "loop", nseel_asm_repeat,nseel_asm_repeat_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL }, - { "while", nseel_asm_repeatwhile,nseel_asm_repeatwhile_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL }, - - { "_not", nseel_asm_bnot,nseel_asm_bnot_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARM_ASBOOL|BIF_RETURNSBOOL|BIF_FPSTACKUSE(1), } , - - { "_equal", nseel_asm_equal,nseel_asm_equal_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2), {0} }, - { "_noteq", nseel_asm_notequal,nseel_asm_notequal_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2), {0} }, - -#ifdef GLUE_HAS_FXCH - { "_above", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2) }, - { "_aboeq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2) }, - { "_below", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2)}, - { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2) }, -#else - { "_above", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSBOOL }, - { "_aboeq", nseel_asm_aboveeq,nseel_asm_aboveeq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSBOOL }, - { "_below", nseel_asm_below,nseel_asm_below_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL }, - { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL }, -#endif - - -#ifndef GLUE_HAS_NATIVE_TRIGSQRTLOG - { "sin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&sin} }, - { "cos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&cos} }, - { "tan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&tan} }, - { "sqrt", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&sqrt}, }, - { "log", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log} }, - { "log10", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log10} }, -#else - { "sin", nseel_asm_sin,nseel_asm_sin_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, - { "cos", nseel_asm_cos,nseel_asm_cos_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, - { "tan", nseel_asm_tan,nseel_asm_tan_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, - { "sqrt", nseel_asm_sqrt,nseel_asm_sqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, - { "log", nseel_asm_log,nseel_asm_log_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, - { "log10", nseel_asm_log10,nseel_asm_log10_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, -#endif - - { "_set",nseel_asm_assign,nseel_asm_assign_end,2|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL, }, // if denormal flag set, we'll use assign which will take care of the denormal - { "_mod",nseel_asm_mod,nseel_asm_mod_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL }, - { "_shr",nseel_asm_shr,nseel_asm_shr_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL }, - { "_shl",nseel_asm_shl,nseel_asm_shl_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL }, - - { "_mulop",nseel_asm_mul_op,nseel_asm_mul_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // mulop/divop clear denormals manually - { "_divop",nseel_asm_div_op,nseel_asm_div_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, - - { "_orop",nseel_asm_or_op,nseel_asm_or_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // these go to int so they clear denormals too - { "_andop",nseel_asm_and_op,nseel_asm_and_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, - { "_xorop",nseel_asm_xor_op,nseel_asm_xor_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, - { "_modop",nseel_asm_mod_op,nseel_asm_mod_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, - - { "_addop",nseel_asm_add_op,nseel_asm_add_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // default versions of these clear denormals, but we can shortcut to non-denorm check versions if input is known non-denormal - { "_subop",nseel_asm_sub_op,nseel_asm_sub_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, - - - { "asin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&asin}, }, - { "acos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&acos}, }, - { "atan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&atan}, }, - { "atan2", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&atan2}, }, - { "pow", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&pow}, }, - { "_powop", nseel_asm_2pdds,nseel_asm_2pdds_end, 2|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&pow}, }, - { "exp", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&exp}, }, - { "abs", nseel_asm_abs,nseel_asm_abs_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0)|BIF_WONTMAKEDENORMAL }, - { "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, - { "min", nseel_asm_min,nseel_asm_min_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, - { "max", nseel_asm_max,nseel_asm_max_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, - { "sign", nseel_asm_sign,nseel_asm_sign_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL, }, - { "rand", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&nseel_int_rand}, }, - - { "floor", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&floor} }, - { "ceil", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&ceil} }, - - { "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), {GLUE_INVSQRT_NEEDREPL} }, - - { "__dbg_getstackptr", nseel_asm_dbg_getstackptr,nseel_asm_dbg_getstackptr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1), }, - - { "_xor", nseel_asm_xor,nseel_asm_xor_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL } , - -#ifdef NSEEL_EEL1_COMPAT_MODE - { "sigmoid", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&eel1sigmoid}, }, - - // these differ from _and/_or, they always evaluate both... - { "band", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1band}, }, - { "bor", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1bor}, }, - - {"exec2",nseel_asm_exec2,nseel_asm_exec2_end,2|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, - {"exec3",nseel_asm_exec2,nseel_asm_exec2_end,3|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, -#endif // end EEL1 compat - - - {"_mem",_asm_megabuf,_asm_megabuf_end,1|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL,{&__NSEEL_RAMAlloc}, - #ifdef GLUE_MEM_NEEDS_PPROC - NSEEL_PProc_RAM, - #else - NULL - #endif - }, - - {"_gmem",_asm_gmegabuf,_asm_gmegabuf_end,1|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL,{&__NSEEL_RAMAllocGMEM},NSEEL_PProc_GRAM}, - {"freembuf",_asm_generic1parm,_asm_generic1parm_end,1,{&__NSEEL_RAM_MemFree},NSEEL_PProc_RAM}, - {"memcpy",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemCpy},NSEEL_PProc_RAM}, - {"memset",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemSet},NSEEL_PProc_RAM}, - - {"stack_push",nseel_asm_stack_push,nseel_asm_stack_push_end,1|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, - {"stack_pop",nseel_asm_stack_pop,nseel_asm_stack_pop_end,1|BIF_FPSTACKUSE(1),{0,},NSEEL_PProc_Stack}, - {"stack_peek",nseel_asm_stack_peek,nseel_asm_stack_peek_end,1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, - {"stack_exch",nseel_asm_stack_exch,nseel_asm_stack_exch_end,1|BIF_FPSTACKUSE(1), {0,},NSEEL_PProc_Stack_PeekTop}, -}; - -static functionType *fnTableUser; -static int fnTableUser_size; - -functionType *nseel_getFunctionFromTable(int idx) -{ - if (idx<0) return 0; - if (idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) - { - idx -= sizeof(fnTable1)/sizeof(fnTable1[0]); - if (!fnTableUser || idx >= fnTableUser_size) return 0; - return fnTableUser+idx; - } - return fnTable1+idx; -} - -int NSEEL_init() // returns 0 on success -{ - -#ifdef EEL_VALIDATE_FSTUBS - int a; - for (a=0;a < sizeof(fnTable1)/sizeof(fnTable1[0]);a++) - { - char *code_startaddr = (char*)fnTable1[a].afunc; - char *endp = (char *)fnTable1[a].func_e; - // validate - int sz=0; - char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); - - if (f+sz > endp) - { -#ifdef _WIN32 - OutputDebugString("bad eel function stub\n"); -#else - printf("bad eel function stub\n"); -#endif - *(char *)NULL = 0; - } - } -#ifdef _WIN32 - OutputDebugString("eel function stub (builtin) validation complete\n"); -#else - printf("eel function stub (builtin) validation complete\n"); -#endif -#endif - - NSEEL_quit(); - return 0; -} - -void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2) -{ - if (!fnTableUser || !(fnTableUser_size&7)) - { - fnTableUser=(functionType *)realloc(fnTableUser,(fnTableUser_size+8)*sizeof(functionType)); - } - if (fnTableUser) - { - -#ifdef EEL_VALIDATE_FSTUBS - { - char *endp = code_startaddr+code_len; - // validate - int sz=0; - char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); - - if (f+sz > endp) - { -#ifdef _WIN32 - OutputDebugString("bad eel function stub\n"); -#else - printf("bad eel function stub\n"); -#endif - *(char *)NULL = 0; - } -#ifdef _WIN32 - OutputDebugString(name); - OutputDebugString(" - validated eel function stub\n"); -#else - printf("eel function stub validation complete for %s\n",name); -#endif - } -#endif - - memset(&fnTableUser[fnTableUser_size],0,sizeof(functionType)); - - if (!(nparms & BIF_RETURNSBOOL)) - { - if (code_startaddr == (void *)&_asm_generic1parm_retd || - code_startaddr == (void *)&_asm_generic2parm_retd || - code_startaddr == (void *)&_asm_generic3parm_retd) - { - nparms |= BIF_RETURNSONSTACK; - } - } - fnTableUser[fnTableUser_size].nParams = nparms; - fnTableUser[fnTableUser_size].name = name; - fnTableUser[fnTableUser_size].afunc = code_startaddr; - fnTableUser[fnTableUser_size].func_e = code_startaddr + code_len; - fnTableUser[fnTableUser_size].pProc = pproc; - fnTableUser[fnTableUser_size].replptrs[0]=fptr; - fnTableUser[fnTableUser_size].replptrs[1]=fptr2; - fnTableUser_size++; - } -} - -void NSEEL_quit() -{ - free(fnTableUser); - fnTableUser_size=0; - fnTableUser=0; -} - -//--------------------------------------------------------------------------------------------------------------- -static void freeBlocks(llBlock **start) -{ - llBlock *s=*start; - *start=0; - while (s) - { - llBlock *llB = s->next; - free(s); - s=llB; - } -} - -//--------------------------------------------------------------------------------------------------------------- -static void *__newBlock(llBlock **start, int size, int wantMprotect) -{ -#if !defined(EEL_DOESNT_NEED_EXEC_PERMS) && defined(_WIN32) - DWORD ov; - UINT_PTR offs,eoffs; -#endif - llBlock *llb; - int alloc_size; - if (*start && (LLB_DSIZE - (*start)->sizeused) >= size) - { - void *t=(*start)->block+(*start)->sizeused; - (*start)->sizeused+=(size+7)&~7; - return t; - } - - alloc_size=sizeof(llBlock); - if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE; - llb = (llBlock *)malloc(alloc_size); // grab bigger block if absolutely necessary (heh) - if (!llb) return NULL; - -#ifndef EEL_DOESNT_NEED_EXEC_PERMS - if (wantMprotect) - { - #ifdef _WIN32 - offs=((UINT_PTR)llb)&~4095; - eoffs=((UINT_PTR)llb + alloc_size + 4095)&~4095; - VirtualProtect((LPVOID)offs,eoffs-offs,PAGE_EXECUTE_READWRITE,&ov); - // MessageBox(NULL,"vprotecting, yay\n","a",0); - #elif defined(EEL_USE_MPROTECT) - { - static int pagesize = 0; - if (!pagesize) - { - pagesize=sysconf(_SC_PAGESIZE); - if (!pagesize) pagesize=4096; - } - uintptr_t offs,eoffs; - offs=((uintptr_t)llb)&~(pagesize-1); - eoffs=((uintptr_t)llb + alloc_size + pagesize-1)&~(pagesize-1); - mprotect((void*)offs,eoffs-offs,PROT_WRITE|PROT_READ|PROT_EXEC); - } - #endif - } -#endif - llb->sizeused=(size+7)&~7; - llb->next = *start; - *start = llb; - return llb->block; -} - - -//--------------------------------------------------------------------------------------------------------------- -opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value) -{ - opcodeRec *r=newOpCode(ctx); - if (r) - { - r->opcodeType = OPCODETYPE_DIRECTVALUE; - r->parms.dv.directValue = value; - r->parms.dv.valuePtr = NULL; - } - return r; -} - -opcodeRec *nseel_createCompiledValueFromNamespaceName(compileContext *ctx, const char *relName) -{ - int n=strlen(relName); - opcodeRec *r=(opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec)+NSEEL_MAX_VARIABLE_NAMELEN,8, ctx->isSharedFunctions ? 0 : -1); - if (!r) return 0; - r->opcodeType=OPCODETYPE_VALUE_FROM_NAMESPACENAME; - if (n > NSEEL_MAX_VARIABLE_NAMELEN) n=NSEEL_MAX_VARIABLE_NAMELEN; - memcpy(r->relname,relName,n); - r->relname[n]=0; - return r; -} - -opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue) -{ - opcodeRec *r=newOpCode(ctx); - if (r) - { - r->opcodeType = OPCODETYPE_VARPTR; - r->parms.dv.valuePtr=addrValue; - r->parms.dv.directValue=0.0; - } - return r; -} - -opcodeRec *nseel_createCompiledValuePtrPtr(compileContext *ctx, EEL_F **addrValue) -{ - opcodeRec *r=newOpCode(ctx); - if (r) - { - r->opcodeType = OPCODETYPE_VARPTRPTR; - r->parms.dv.valuePtr=(EEL_F *)addrValue; - r->parms.dv.directValue=0.0; - } - return r; -} - -opcodeRec *nseel_createCompiledFunctionCallEELThis(compileContext *ctx, _codeHandleFunctionRec *fnp, const char *relName) -{ - int n=strlen(relName); - opcodeRec *r=(opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec)+NSEEL_MAX_VARIABLE_NAMELEN,8, ctx->isSharedFunctions ? 0 : -1); - if (!r) return 0; - r->fntype=FUNCTYPE_EELFUNC_THIS; - r->fn = fnp; - if (fnp->num_params > 3) r->opcodeType = OPCODETYPE_FUNCX; - else if (fnp->num_params == 3) r->opcodeType = OPCODETYPE_FUNC3; - else if (fnp->num_params==2) r->opcodeType = OPCODETYPE_FUNC2; - else r->opcodeType = OPCODETYPE_FUNC1; - if (n > NSEEL_MAX_VARIABLE_NAMELEN) n=NSEEL_MAX_VARIABLE_NAMELEN; - memcpy(r->relname,relName,n); - r->relname[n]=0; - - return r; -} - -opcodeRec *nseel_createCompiledFunctionCall(compileContext *ctx, int np, int fntype, void *fn) -{ - opcodeRec *r=newOpCode(ctx); - if (!r) return 0; - r->fntype=fntype; - r->fn = fn; - - if (np > 3) r->opcodeType = OPCODETYPE_FUNCX; - else if (np == 3) r->opcodeType = OPCODETYPE_FUNC3; - else if (np==2) r->opcodeType = OPCODETYPE_FUNC2; - else r->opcodeType = OPCODETYPE_FUNC1; - - return r; -} - -opcodeRec *nseel_setCompiledFunctionCallParameters(opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3) -{ - if (fn) - { - opcodeRec *r = fn; - r->parms.parms[0] = code1; - r->parms.parms[1] = code2; - r->parms.parms[2] = code3; - } - return fn; -} - - -opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2) -{ - opcodeRec *r=code1 && code2 ? newOpCode(ctx) : NULL; - if (r) - { - r->opcodeType = OPCODETYPE_MOREPARAMS; - r->parms.parms[0] = code1; - r->parms.parms[1] = code2; - r->parms.parms[2] = 0; - } - return r; -} - -opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2) -{ - opcodeRec *r=code1 && (np<2 || code2) ? newOpCode(ctx) : NULL; - if (r) - { - r->opcodeType = np>=2 ? OPCODETYPE_FUNC2:OPCODETYPE_FUNC1; - r->fntype = fn; - r->fn = fn == FN_JOIN_STATEMENTS ? r : NULL; // for joins, fn is temporarily used for tail pointers - if (code1 && fn == FN_JOIN_STATEMENTS && code1->opcodeType == OPCODETYPE_FUNC2 && code1->fntype == fn) - { - opcodeRec *t = (opcodeRec *)code1->fn; - // keep joins in the form of dosomething->morestuff. - // in this instance, code1 is previous stuff to do, code2 is new stuff to do - r->parms.parms[0] = t->parms.parms[1]; - r->parms.parms[1] = code2; - - code1->fn = (t->parms.parms[1] = r); - return code1; - } - r->parms.parms[0] = code1; - r->parms.parms[1] = code2; - } - return r; -} - - -// these are bitmasks; on request you can tell what is supported, and compileOpcodes will return one of them -#define RETURNVALUE_IGNORE 0 // ignore return value -#define RETURNVALUE_NORMAL 1 // pointer -#define RETURNVALUE_FPSTACK 2 -#define RETURNVALUE_BOOL 4 // P1 is nonzero if true - - - - -static int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTable, const char *namespacePathToThis, - int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput); - - -static unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const char *namespacePathToThis, - int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput); - -_codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr) -{ - int n; - _codeHandleFunctionRec *subfr = fr->isCommonFunction ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); - if (!subfr) return 0; - // fr points to functionname()'s rec, nameptr to blah.functionname() - - *subfr = *fr; - n = strlen(nameptr); - if (n > sizeof(subfr->fname)-1) n=sizeof(subfr->fname)-1; - memcpy(subfr->fname,nameptr,n); - subfr->fname[n]=0; - - subfr->next = NULL; - subfr->startptr=0; // make sure this code gets recompiled (with correct member ptrs) for this instance! - - // subfr->derivedCopies already points to the right place - fr->derivedCopies = subfr; - - return subfr; - -} -static void combineNamespaceFields(char *nm, const char *prefix, const char *relname) // nm must be NSEEL_MAX_VARIABLE_NAMELEN+1 bytes -{ - int lfp = prefix ? strlen(prefix) : 0, lrn=strlen(relname); - - while (*relname == '.') // if relname begins with ., then remove a chunk of context from prefix - { - relname++; - while (lfp>0 && prefix[lfp-1] != '.') lfp--; - if (lfp>0) lfp--; - } - - if (lfp > NSEEL_MAX_VARIABLE_NAMELEN-3) lfp=NSEEL_MAX_VARIABLE_NAMELEN-3; - if (lfp>0) memcpy(nm,prefix,lfp); - - if (lrn > NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0)) lrn=NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0); - if (lrn > 0) - { - if (lfp>0) nm[lfp++] = '.'; - memcpy(nm+lfp,relname,lrn); - lfp+=lrn; - } - nm[lfp++]=0; -} - - -//--------------------------------------------------------------------------------------------------------------- -static void *nseel_getBuiltinFunctionAddress(compileContext *ctx, - int fntype, void *fn, - NSEEL_PPPROC *pProc, void ***replList, - void **endP, int *abiInfo, int preferredReturnValues) -{ - switch (fntype) - { -#define RF(x) *endP = nseel_asm_##x##_end; return (void*)nseel_asm_##x - case FN_ADD: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; RF(add); - case FN_SUB: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; RF(sub); - case FN_MULTIPLY: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2); RF(mul); - case FN_DIVIDE: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2); RF(div); -#ifndef EEL_TARGET_PORTABLE - case FN_JOIN_STATEMENTS: *abiInfo = BIF_WONTMAKEDENORMAL; RF(exec2); // shouldn't ever be used anyway, but scared to remove -#endif - case FN_AND: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(and); - case FN_OR: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(or); -#ifndef EEL_TARGET_PORTABLE - case FN_UPLUS: *abiInfo = BIF_WONTMAKEDENORMAL; RF(uplus); // shouldn't ever be used anyway, but scared to remove -#endif - case FN_UMINUS: *abiInfo = BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL; RF(uminus); -#undef RF - - case FUNCTYPE_FUNCTIONTYPEREC: - if (fn) - { - functionType *p=(functionType *)fn; - - // if prefers fpstack or bool, or ignoring value, then use fp-stack versions - if ((preferredReturnValues&(RETURNVALUE_BOOL|RETURNVALUE_FPSTACK)) || !preferredReturnValues) - { - static functionType min2={ "min", nseel_asm_min_fp,nseel_asm_min_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; - static functionType max2={ "max", nseel_asm_max_fp,nseel_asm_max_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; - - if (p->afunc == (void*)nseel_asm_min) p = &min2; - else if (p->afunc == (void*)nseel_asm_max) p = &max2; - } - - *replList=p->replptrs; - *pProc=p->pProc; - *endP = p->func_e; - *abiInfo = p->nParams & BIF_NPARAMS_MASK; - return p->afunc; - } - break; - } - - return 0; -} - - - -static void *nseel_getEELFunctionAddress(compileContext *ctx, - opcodeRec *op, - int *customFuncParmSize, int *customFuncLocalStorageSize, - EEL_F ***customFuncLocalStorage, int *computTableTop, - void **endP, int *isRaw, int wantCodeGenerated, - const char *namespacePathToThis, int *rvMode, int *fpStackUse, int *canHaveDenormalOutput) // if wantCodeGenerated is false, can return bogus pointers in raw mode -{ - _codeHandleFunctionRec *fn = (_codeHandleFunctionRec*)op->fn; - switch (op->fntype) - { - case FUNCTYPE_EELFUNC_THIS: - if (fn) - { - _codeHandleFunctionRec *fr_base = fn; - char nm[NSEEL_MAX_VARIABLE_NAMELEN+1]; - combineNamespaceFields(nm,namespacePathToThis,op->relname); - - fn = 0; // if this gets re-set, it will be the new function - - // find resolved function - if (!fn) - { - _codeHandleFunctionRec *fr = fr_base; - // scan for function - while (fr && !fn) - { - if (!strcasecmp(fr->fname,nm)) fn = fr; - fr=fr->derivedCopies; - } - } - - if (!fn) // generate copy of function - { - fn = eel_createFunctionNamespacedInstance(ctx,fr_base,nm); - } - } - - // fall through! - case FUNCTYPE_EELFUNC: - if (fn) - { - const char *fPrefix=NULL; - char prefix_buf[NSEEL_MAX_VARIABLE_NAMELEN+1]; - - _codeHandleFunctionRec *fr = (_codeHandleFunctionRec *) fn; - - if (fr->usesThisPointer) - { - char *p=fr->fname; - while (*p) p++; - while (p >= fr->fname && *p != '.') p--; - if (p >= fr->fname) - { - int l = p-fr->fname; - memcpy(prefix_buf,fr->fname,l); - prefix_buf[l]=0; - fPrefix = prefix_buf; - } - else - { - fPrefix = fr->fname; // default prefix is function name if no other context - } - } - - - if (!fr->startptr && fr->opcodes && fr->startptr_size > 0) - { - int sz; - fr->tmpspace_req=0; - fr->rvMode = RETURNVALUE_IGNORE; - fr->canHaveDenormalOutput=0; - - sz=compileOpcodes(ctx,fr->opcodes,NULL,128*1024*1024,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); - - if (!wantCodeGenerated) - { - // don't compile anything for now, just give stats - if (computTableTop) *computTableTop += fr->tmpspace_req; - *customFuncParmSize = fr->num_params; - *customFuncLocalStorage = fr->localstorage; - *customFuncLocalStorageSize = fr->localstorage_size; - *rvMode = fr->rvMode; - *fpStackUse = fr->fpStackUsage; - if (canHaveDenormalOutput) *canHaveDenormalOutput=fr->canHaveDenormalOutput; - - if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) - { - *isRaw = 1; - *endP = ((char *)1) + sz; - return (char *)1; - } - *endP = (void*)nseel_asm_fcall_end; - return (void*)nseel_asm_fcall; - } - - if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) - { - void *p=newTmpBlock(ctx,sz); - fr->tmpspace_req=0; - if (p) - { - fr->canHaveDenormalOutput=0; - sz=compileOpcodes(ctx,fr->opcodes,(unsigned char*)p,sz,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); - // recompile function with native context pointers - if (sz>0) - { - fr->startptr_size=sz; - fr->startptr=p; - } - } - } - else - { - unsigned char *codeCall; - fr->tmpspace_req=0; - fr->fpStackUsage=0; - fr->canHaveDenormalOutput=0; - codeCall=compileCodeBlockWithRet(ctx,fr->opcodes,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); - if (codeCall) - { - void *f=GLUE_realAddress(nseel_asm_fcall,nseel_asm_fcall_end,&sz); - fr->startptr = newTmpBlock(ctx,sz); - if (fr->startptr) - { - memcpy(fr->startptr,f,sz); - EEL_GLUE_set_immediate(fr->startptr,(INT_PTR)codeCall); - fr->startptr_size = sz; - } - } - } - } - if (fr->startptr) - { - if (computTableTop) *computTableTop += fr->tmpspace_req; - *customFuncParmSize = fr->num_params; - *customFuncLocalStorage = fr->localstorage; - *customFuncLocalStorageSize = fr->localstorage_size; - *rvMode = fr->rvMode; - *fpStackUse = fr->fpStackUsage; - if (canHaveDenormalOutput) *canHaveDenormalOutput= fr->canHaveDenormalOutput; - *endP = (char*)fr->startptr + fr->startptr_size; - *isRaw=1; - return fr->startptr; - } - } - break; - } - - return 0; -} - - - -// returns true if does something (other than calculating and throwing away a value) -static char optimizeOpcodes(compileContext *ctx, opcodeRec *op, int needsResult) -{ - opcodeRec *lastJoinOp=NULL; - char retv, retv_parm[3], joined_retv=0; - while (op && op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) - { - if (!optimizeOpcodes(ctx,op->parms.parms[0], 0) || OPCODE_IS_TRIVIAL(op->parms.parms[0])) - { - // direct value, can skip ourselves - memcpy(op,op->parms.parms[1],sizeof(*op)); - } - else - { - joined_retv |= 1; - lastJoinOp = op; - op = op->parms.parms[1]; - } - } - -start_over: // when an opcode changed substantially in optimization, goto here to reprocess it - - retv = retv_parm[0]=retv_parm[1]=retv_parm[2]=0; - - if (!op || // should never really happen - OPCODE_IS_TRIVIAL(op) || // should happen often (vars) - op->opcodeType < 0 || op->opcodeType >= OPCODETYPE_INVALID // should never happen (assert would be appropriate heh) - ) return joined_retv; - - if (!needsResult) - { - if (op->fntype == FUNCTYPE_EELFUNC || op->fntype == FUNCTYPE_EELFUNC_THIS) - { - needsResult=1; // assume eel functions are non-const for now - } - else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) - { - functionType *pfn = (functionType *)op->fn; - if (!pfn || !(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) needsResult=1; - } - } - - if (op->opcodeType>=OPCODETYPE_FUNC2) retv_parm[1] = optimizeOpcodes(ctx,op->parms.parms[1], needsResult); - if (op->opcodeType>=OPCODETYPE_FUNC3) retv_parm[2] = optimizeOpcodes(ctx,op->parms.parms[2], needsResult); - - retv_parm[0] = optimizeOpcodes(ctx,op->parms.parms[0], needsResult || - (FNPTR_HAS_CONDITIONAL_EXEC(op) && (retv_parm[1] || retv_parm[2] || op->opcodeType <= OPCODETYPE_FUNC1)) ); - - if (op->opcodeType != OPCODETYPE_MOREPARAMS) - { - if (op->fntype >= 0 && op->fntype < FUNCTYPE_SIMPLEMAX) - { - if (op->opcodeType == OPCODETYPE_FUNC1) // within FUNCTYPE_SIMPLE - { - if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) - { - switch (op->fntype) - { - case FN_UMINUS: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = - op->parms.parms[0]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_UPLUS: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - } - } - } - else if (op->opcodeType == OPCODETYPE_FUNC2) // within FUNCTYPE_SIMPLE - { - int dv0 = op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE; - int dv1 = op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE; - if (dv0 && dv1) - { - switch (op->fntype) - { - case FN_DIVIDE: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue / op->parms.parms[1]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_MULTIPLY: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue * op->parms.parms[1]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_ADD: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue + op->parms.parms[1]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_SUB: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue - op->parms.parms[1]->parms.dv.directValue; - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_AND: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = (double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) & ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue)); - op->parms.dv.valuePtr=NULL; - goto start_over; - case FN_OR: - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = (double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) | ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue)); - op->parms.dv.valuePtr=NULL; - goto start_over; - } - } - else if (dv0 || dv1) - { - double dvalue = op->parms.parms[!dv0]->parms.dv.directValue; - switch (op->fntype) - { - case FN_OR: - if (!(WDL_INT64)dvalue) - { - // replace with or0 - static functionType fr={"or0",nseel_asm_or0, nseel_asm_or0_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSONSTACK|BIF_CLEARDENORMAL, {0}, NULL}; - - op->opcodeType = OPCODETYPE_FUNC1; - op->fntype = FUNCTYPE_FUNCTIONTYPEREC; - op->fn = &fr; - if (dv0) op->parms.parms[0] = op->parms.parms[1]; - goto start_over; - } - break; - case FN_SUB: - if (dv0) - { - if (dvalue == 0.0) - { - op->opcodeType = OPCODETYPE_FUNC1; - op->fntype = FN_UMINUS; - op->parms.parms[0] = op->parms.parms[1]; - goto start_over; - } - break; - } - // fall through, if dv1 we can remove +0.0 - - case FN_ADD: - if (dvalue == 0.0) - { - memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); - goto start_over; - } - break; - case FN_AND: - if ((WDL_INT64)dvalue) break; - dvalue = 0.0; // treat x&0 as x*0, which optimizes to 0 - - // fall through - case FN_MULTIPLY: - if (dvalue == 0.0) // remove multiply by 0.0 (using 0.0 direct value as replacement), unless the nonzero side did something - { - if (!retv_parm[!!dv0]) - { - memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything - goto start_over; - } - else - { - // this is 0.0 * oldexpressionthatmustbeprocessed or oldexpressionthatmustbeprocessed*0.0 - op->fntype = FN_JOIN_STATEMENTS; - - if (dv0) // 0.0*oldexpression, reverse the order so that 0 is returned - { - // set to (oldexpression;0) - opcodeRec *tmp = op->parms.parms[1]; - op->parms.parms[1] = op->parms.parms[0]; - op->parms.parms[0] = tmp; - } - goto start_over; - } - } - else if (dvalue == 1.0) // remove multiply by 1.0 (using non-1.0 value as replacement) - { - memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); - goto start_over; - } - break; - case FN_DIVIDE: - if (dv1) - { - if (dvalue == 1.0) // remove divide by 1.0 (using non-1.0 value as replacement) - { - memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); - goto start_over; - } - else - { - // change to a multiply - if (op->parms.parms[1]->parms.dv.directValue == 0.0) - { - op->fntype = FN_MULTIPLY; - goto start_over; - } - else - { - double d = 1.0/op->parms.parms[1]->parms.dv.directValue; - - WDL_DenormalDoubleAccess *p = (WDL_DenormalDoubleAccess*)&d; - // allow conversion to multiply if reciprocal is exact - // we could also just look to see if the last few digits of the mantissa were 0, which would probably be good - // enough, but if the user really wants it they should do * (1/x) instead to force precalculation of reciprocal. - if (!p->w.lw && !(p->w.hw & 0xfffff)) - { - op->fntype = FN_MULTIPLY; - op->parms.parms[1]->parms.dv.directValue = d; - op->parms.parms[1]->parms.dv.valuePtr=NULL; - goto start_over; - } - } - } - } - else if (dvalue == 0.0) - { - if (!retv_parm[!!dv0]) - { - // if 0/x set to always 0. - // this is 0.0 / (oldexpression that can be eliminated) - memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything - } - else - { - opcodeRec *tmp; - // this is 0.0 / oldexpressionthatmustbeprocessed - op->fntype = FN_JOIN_STATEMENTS; - tmp = op->parms.parms[1]; - op->parms.parms[1] = op->parms.parms[0]; - op->parms.parms[0] = tmp; - // set to (oldexpression;0) - } - goto start_over; - } - break; - } - } - } - // FUNCTYPE_SIMPLE - } - else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC && op->fn) - { - - /* - probably worth doing reduction on: - _divop (constant change to multiply) - _and - _or - _not - _mod - _shr - _shl - _xor - abs - - maybe: - min - max - _equal - _noteq - _below - _above - _beleq - _aboeq - - - also, optimize should (recursively or maybe iteratively?) search transitive functions (mul/div) for more constant reduction possibilities - - - */ - - - functionType *pfn = (functionType *)op->fn; - - if (!(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) retv|=1; - - if (op->opcodeType==OPCODETYPE_FUNC1) // within FUNCTYPE_FUNCTIONTYPEREC - { - if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) - { - int suc=1; - EEL_F v = op->parms.parms[0]->parms.dv.directValue; - #define DOF(x) if (!strcmp(pfn->name,#x)) v = x(v); else - DOF(sin) - DOF(cos) - DOF(tan) - DOF(asin) - DOF(acos) - DOF(atan) - DOF(sqrt) - DOF(exp) - DOF(log) - DOF(log10) - /*else*/ suc=0; - #undef DOF - if (suc) - { - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = v; - op->parms.dv.valuePtr=NULL; - goto start_over; - } - - - } - } - else if (op->opcodeType==OPCODETYPE_FUNC2) // within FUNCTYPE_FUNCTIONTYPEREC - { - if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE && - op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE) - { - if (pfn->replptrs[0] == &pow || - pfn->replptrs[0] == &atan2) - { - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.directValue = pfn->replptrs[0]==pow ? - pow(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue) : - atan2(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue); - op->parms.dv.valuePtr=NULL; - goto start_over; - } - } - else if (pfn->replptrs[0] == &pow) - { - opcodeRec *first_parm = op->parms.parms[0]; - if (first_parm->opcodeType == op->opcodeType && first_parm->fn == op->fn && first_parm->fntype == op->fntype) - { - // since first_parm is a pow too, we can multiply the exponents. - - // set our base to be the base of the inner pow - op->parms.parms[0] = first_parm->parms.parms[0]; - - // make the old extra pow be a multiply of the exponents - first_parm->fntype = FN_MULTIPLY; - first_parm->parms.parms[0] = op->parms.parms[1]; - - // put that as the exponent - op->parms.parms[1] = first_parm; - - goto start_over; - } - } - } - else if (op->opcodeType==OPCODETYPE_FUNC3) // within FUNCTYPE_FUNCTIONTYPEREC - { - if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) - { - if (!strcmp(pfn->name,"_if")) - { - int s = fabs(op->parms.parms[0]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; - memcpy(op,op->parms.parms[s ? 1 : 2],sizeof(opcodeRec)); - goto start_over; - } - } - } - // FUNCTYPE_FUNCTIONTYPEREC - } - else - { - // unknown or eel func, assume non-const - retv |= 1; - } - } - - // if we need results, or our function has effects itself, then finish - if (retv || needsResult) - { - return retv || joined_retv || retv_parm[0] || retv_parm[1] || retv_parm[2]; - } - - // we don't need results here, and our function is const, which means we can remove it - { - int cnt=0, idx1=0, idx2=0, x; - for (x=0;x<3;x++) if (retv_parm[x]) { if (!cnt++) idx1=x; else idx2=x; } - - if (!cnt) // none of the parameters do anything, remove this opcode - { - if (lastJoinOp) - { - // replace previous join with its first linked opcode, removing this opcode completely - memcpy(lastJoinOp,lastJoinOp->parms.parms[0],sizeof(*lastJoinOp)); - } - else if (op->opcodeType != OPCODETYPE_DIRECTVALUE) - { - // allow caller to easily detect this as trivial and remove it - op->opcodeType = OPCODETYPE_DIRECTVALUE; - op->parms.dv.valuePtr=NULL; - op->parms.dv.directValue=0.0; - } - // return joined_retv below - } - else - { - // if parameters are non-const, and we're a conditional, preserve our function - if (FNPTR_HAS_CONDITIONAL_EXEC(op)) return 1; - - // otherwise, condense into either the non-const statement, or a join - if (cnt==1) - { - memcpy(op,op->parms.parms[idx1],sizeof(*op)); - } - else if (cnt == 2) - { - op->opcodeType = OPCODETYPE_FUNC2; - op->fntype = FN_JOIN_STATEMENTS; - op->fn = op; - op->parms.parms[0] = op->parms.parms[idx1]; - op->parms.parms[1] = op->parms.parms[idx2]; - op->parms.parms[2] = NULL; - } - else - { - // todo need to create a new opcodeRec here, for now just leave as is - // (non-conditional const 3 parameter functions are rare anyway) - } - return 1; - } - } - return joined_retv; -} - - -static int generateValueToReg(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int whichReg, const char *functionPrefix, int allowCache) -{ - EEL_F *b=NULL; - if (op->opcodeType==OPCODETYPE_VALUE_FROM_NAMESPACENAME) - { - char nm[NSEEL_MAX_VARIABLE_NAMELEN+1]; - - combineNamespaceFields(nm,functionPrefix,op->relname); - - b = nseel_int_register_var(ctx,nm,0); - if (!b) RET_MINUS1_FAIL("error registering var") - } - else - { - if (op->opcodeType != OPCODETYPE_DIRECTVALUE) allowCache=0; - - b=op->parms.dv.valuePtr; - if (b && op->opcodeType == OPCODETYPE_VARPTRPTR) b = *(EEL_F **)b; - if (!b && allowCache) - { - int n=50; // only scan last X items - opcodeRec *r = ctx->directValueCache; - while (r && n--) - { - if (r->parms.dv.directValue == op->parms.dv.directValue && (b=r->parms.dv.valuePtr)) break; - r=(opcodeRec*)r->fn; - } - } - if (!b) - { - ctx->l_stats[3]++; - b = newDataBlock(sizeof(EEL_F),sizeof(EEL_F)); - if (!b) RET_MINUS1_FAIL("error allocating data block") - - if (op->opcodeType != OPCODETYPE_VARPTRPTR) op->parms.dv.valuePtr = b; - #if EEL_F_SIZE == 8 - *b = denormal_filter_double2(op->parms.dv.directValue); - #else - *b = denormal_filter_float2(op->parms.dv.directValue); - #endif - - if (allowCache) - { - op->fn = ctx->directValueCache; - ctx->directValueCache = op; - } - } - } - - GLUE_MOV_PX_DIRECTVALUE_GEN(bufOut,(INT_PTR)b,whichReg); - return GLUE_MOV_PX_DIRECTVALUE_SIZE; -} - - -unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const char *namespacePathToThis, - int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput) -{ - unsigned char *p, *newblock2; - // generate code call - int funcsz=compileOpcodes(ctx,rec,NULL,1024*1024*128,NULL,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, NULL); - if (funcsz<0) return NULL; - - p = newblock2 = newCodeBlock(funcsz+ sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32); - if (!newblock2) return NULL; - #if GLUE_FUNC_ENTER_SIZE > 0 - memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); - p += GLUE_FUNC_ENTER_SIZE; - #endif - *fpStackUsage=0; - funcsz=compileOpcodes(ctx,rec,p, funcsz, computTableSize,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, canHaveDenormalOutput); - if (funcsz<0) return NULL; - p+=funcsz; - - #if GLUE_FUNC_LEAVE_SIZE > 0 - memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); - p+=GLUE_FUNC_LEAVE_SIZE; - #endif - memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET); - - ctx->l_stats[2]+=funcsz+2; - return newblock2; -} - - -static int compileNativeFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, - int *rvMode, int *fpStackUsage, int preferredReturnValues, int *canHaveDenormalOutput) -{ - // builtin function generation - int cfunc_abiinfo=0; - int local_fpstack_use=0; // how many items we have pushed onto the fp stack - int parm_size=0; - int need_fxch=0; - int pn; - int last_nt_parm=-1, last_nt_parm_type; - void *func_e=NULL; - int n_params= 1 + op->opcodeType - OPCODETYPE_FUNC1; - NSEEL_PPPROC preProc=0; - void **repl=NULL; - void *func = nseel_getBuiltinFunctionAddress(ctx, op->fntype, op->fn, &preProc,&repl,&func_e,&cfunc_abiinfo,preferredReturnValues); - - if (!func) RET_MINUS1_FAIL("error getting funcaddr") - - if (op->opcodeType == OPCODETYPE_FUNCX) - { - // this is not yet supported (calling conventions will need to be sorted, among other things) - RET_MINUS1_FAIL("funcx not supported for native functions") - } - *fpStackUsage=BIF_GETFPSTACKUSE(cfunc_abiinfo); - - *rvMode = RETURNVALUE_NORMAL; - - if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) - { - if (func == nseel_asm_stack_pop) - { - int func_size=0; - func = GLUE_realAddress(nseel_asm_stack_pop_fast,nseel_asm_stack_pop_fast_end,&func_size); - if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on popfast size":"failed on popfast addr") - - if (bufOut) - { - memcpy(bufOut,func,func_size); - NSEEL_PProc_Stack(bufOut,func_size,ctx); - } - return func_size; - } - else if (func == nseel_asm_stack_peek) - { - int f = (int) op->parms.parms[0]->parms.dv.directValue; - if (!f) - { - int func_size=0; - func = GLUE_realAddress(nseel_asm_stack_peek_top,nseel_asm_stack_peek_top_end,&func_size); - if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peek size":"failed on peek addr") - - if (bufOut) - { - memcpy(bufOut,func,func_size); - NSEEL_PProc_Stack_PeekTop(bufOut,func_size,ctx); - } - return func_size; - } - else - { - int func_size=0; - func = GLUE_realAddress(nseel_asm_stack_peek_int,nseel_asm_stack_peek_int_end,&func_size); - if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peekint size":"failed on peekint addr") - - if (bufOut) - { - memcpy(bufOut,func,func_size); - NSEEL_PProc_Stack_PeekInt(bufOut,func_size,ctx,f*sizeof(EEL_F)); - } - return func_size; - } - } - } - // end of built-in function specific special casing - - - // first pass, calculate any non-trivial parameters - for (pn=0; pn < n_params; pn++) - { - if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) - { - int canHaveDenorm=0; - int subfpstackuse=0; - int lsz=0; - int rvt=RETURNVALUE_NORMAL; - int may_need_fppush=-1; - if (last_nt_parm>=0) - { - if (last_nt_parm_type==RETURNVALUE_FPSTACK) - { - may_need_fppush= parm_size; - } - else - { - // push last result - if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1)) RET_MINUS1_FAIL("failed on size, pushp1") - if (bufOut) memcpy(bufOut + parm_size, &GLUE_PUSH_P1, sizeof(GLUE_PUSH_P1)); - parm_size += sizeof(GLUE_PUSH_P1); - } - } - - if (pn == n_params - 1) - { - if (cfunc_abiinfo&BIF_LASTPARMONSTACK) rvt=RETURNVALUE_FPSTACK; - else if (cfunc_abiinfo&BIF_LASTPARM_ASBOOL) rvt=RETURNVALUE_BOOL; - else if (func == nseel_asm_assign) rvt=RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL; - } - else if (pn == n_params -2 && (cfunc_abiinfo&BIF_SECONDLASTPARMST)) - { - rvt=RETURNVALUE_FPSTACK; - } - - lsz = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, rvt,&rvt, &subfpstackuse, &canHaveDenorm); - - if (canHaveDenorm && canHaveDenormalOutput) *canHaveDenormalOutput = 1; - - if (lsz<0) RET_MINUS1_FAIL("call coc failed") - - parm_size += lsz; - - if (may_need_fppush>=0) - { - if (local_fpstack_use+subfpstackuse >= (GLUE_MAX_FPSTACK_SIZE-1) || (ctx->optimizeDisableFlags&OPTFLAG_NO_FPSTACK)) - { - if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) - RET_MINUS1_FAIL("failed on size, popfpstacktostack") - - if (bufOut) - { - memmove(bufOut + may_need_fppush + sizeof(GLUE_POP_FPSTACK_TOSTACK), bufOut + may_need_fppush, parm_size - may_need_fppush); - memcpy(bufOut + may_need_fppush, &GLUE_POP_FPSTACK_TOSTACK, sizeof(GLUE_POP_FPSTACK_TOSTACK)); - - } - parm_size += sizeof(GLUE_POP_FPSTACK_TOSTACK); - } - else - { - local_fpstack_use++; - } - } - - if (subfpstackuse+local_fpstack_use > *fpStackUsage) *fpStackUsage = subfpstackuse+local_fpstack_use; - - last_nt_parm = pn; - last_nt_parm_type = rvt; - - if (pn == n_params - 1 && func == nseel_asm_assign) - { - if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS) && - (!canHaveDenorm || (ctx->optimizeDisableFlags & OPTFLAG_NO_DENORMAL_CHECKS))) - { - if (rvt == RETURNVALUE_FPSTACK) - { - cfunc_abiinfo |= BIF_LASTPARMONSTACK; - func = nseel_asm_assign_fast_fromfp; - func_e = nseel_asm_assign_fast_fromfp_end; - } - else - { - func = nseel_asm_assign_fast; - func_e = nseel_asm_assign_fast_end; - } - } - else - { - if (rvt == RETURNVALUE_FPSTACK) - { - cfunc_abiinfo |= BIF_LASTPARMONSTACK; - func = nseel_asm_assign_fromfp; - func_e = nseel_asm_assign_fromfp_end; - } - } - - } - } - } - - pn = last_nt_parm; - - if (pn >= 0) // if the last thing executed doesn't go to the last parameter, move it there - { - if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) - { - // do nothing, things are in the right place - } - else if (pn != n_params-1) - { - // generate mov p1->pX - if (bufOut_len < parm_size + GLUE_SET_PX_FROM_P1_SIZE) RET_MINUS1_FAIL("size, pxfromp1") - if (bufOut) GLUE_SET_PX_FROM_P1(bufOut + parm_size,n_params - 1 - pn); - parm_size += GLUE_SET_PX_FROM_P1_SIZE; - } - } - - // pop any pushed parameters - while (--pn >= 0) - { - if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) - { - if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) - { - if (!local_fpstack_use) - { - if (bufOut_len < parm_size + sizeof(GLUE_POP_STACK_TO_FPSTACK)) RET_MINUS1_FAIL("size, popstacktofpstack 2") - if (bufOut) memcpy(bufOut+parm_size,GLUE_POP_STACK_TO_FPSTACK,sizeof(GLUE_POP_STACK_TO_FPSTACK)); - parm_size += sizeof(GLUE_POP_STACK_TO_FPSTACK); - need_fxch = 1; - } - else - { - local_fpstack_use--; - } - } - else - { - if (bufOut_len < parm_size + GLUE_POP_PX_SIZE) RET_MINUS1_FAIL("size, poppx") - if (bufOut) GLUE_POP_PX(bufOut + parm_size,n_params - 1 - pn); - parm_size += GLUE_POP_PX_SIZE; - } - } - } - - // finally, set trivial pointers - for (pn=0; pn < n_params; pn++) - { - if (OPCODE_IS_TRIVIAL(op->parms.parms[pn])) - { - if (pn == n_params-2 && (cfunc_abiinfo&(BIF_SECONDLASTPARMST))) // second to last parameter - { - int a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, - RETURNVALUE_FPSTACK,NULL,NULL,canHaveDenormalOutput); - if (a<0) RET_MINUS1_FAIL("coc call here 2") - parm_size+=a; - need_fxch = 1; - } - else if (pn == n_params-1) // last parameter, but we should call compileOpcodes to get it in the right format (compileOpcodes can optimize that process if it needs to) - { - int rvt=0, a; - int wantFpStack = func == nseel_asm_assign; -#ifdef GLUE_PREFER_NONFP_DV_ASSIGNS // x86-64, and maybe others, prefer to avoid the fp stack for a simple copy - if (wantFpStack && - (op->parms.parms[pn]->opcodeType != OPCODETYPE_DIRECTVALUE || - (op->parms.parms[pn]->parms.dv.directValue != 1.0 && op->parms.parms[pn]->parms.dv.directValue != 0.0))) - { - wantFpStack=0; - } -#endif - - a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, - (cfunc_abiinfo & BIF_LASTPARMONSTACK) ? RETURNVALUE_FPSTACK : - (cfunc_abiinfo & BIF_LASTPARM_ASBOOL) ? RETURNVALUE_BOOL : - wantFpStack ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : - RETURNVALUE_NORMAL,&rvt, NULL,canHaveDenormalOutput); - - if (a<0) RET_MINUS1_FAIL("coc call here 3") - parm_size+=a; - need_fxch = 0; - - if (func == nseel_asm_assign) - { - if (rvt == RETURNVALUE_FPSTACK) - { - if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) - { - func = nseel_asm_assign_fast_fromfp; - func_e = nseel_asm_assign_fast_fromfp_end; - } - else - { - func = nseel_asm_assign_fromfp; - func_e = nseel_asm_assign_fromfp_end; - } - } - else if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) - { - // assigning a value (from a variable or other non-computer), can use a fast assign (no denormal/result checking) - func = nseel_asm_assign_fast; - func_e = nseel_asm_assign_fast_end; - } - } - } - else - { - if (bufOut_len < parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE) RET_MINUS1_FAIL("size, pxdvsz") - if (bufOut) - { - if (generateValueToReg(ctx,op->parms.parms[pn],bufOut + parm_size,n_params - 1 - pn,namespacePathToThis, 0/*nocaching, function gets pointer*/)<0) RET_MINUS1_FAIL("gvtr") - } - parm_size += GLUE_MOV_PX_DIRECTVALUE_SIZE; - } - } - } - -#ifdef GLUE_HAS_FXCH - if ((cfunc_abiinfo&(BIF_SECONDLASTPARMST)) && !(cfunc_abiinfo&(BIF_LAZYPARMORDERING))&& - ((!!need_fxch)^!!(cfunc_abiinfo&BIF_REVERSEFPORDER)) - ) - { - // emit fxch - if (bufOut_len < sizeof(GLUE_FXCH)) RET_MINUS1_FAIL("len,fxch") - if (bufOut) - { - memcpy(bufOut+parm_size,GLUE_FXCH,sizeof(GLUE_FXCH)); - } - parm_size+=sizeof(GLUE_FXCH); - } -#endif - - if (!*canHaveDenormalOutput) - { - // if add_op or sub_op, and non-denormal input, safe to omit denormal checks - if (func == (void*)nseel_asm_add_op) - { - func = nseel_asm_add_op_fast; - func_e = nseel_asm_add_op_fast_end; - } - else if (func == (void*)nseel_asm_sub_op) - { - func = nseel_asm_sub_op_fast; - func_e = nseel_asm_sub_op_fast_end; - } - } - - - if (cfunc_abiinfo & (BIF_CLEARDENORMAL | BIF_RETURNSBOOL) ) *canHaveDenormalOutput=0; - else if (!(cfunc_abiinfo & BIF_WONTMAKEDENORMAL)) *canHaveDenormalOutput=1; - - { - int func_size=0; - func = GLUE_realAddress(func,func_e,&func_size); - if (!func) RET_MINUS1_FAIL("failrealladdrfunc") - - if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("funcsz") - - if (bufOut) - { - unsigned char *p=bufOut + parm_size; - memcpy(p, func, func_size); - if (preProc) p=preProc(p,func_size,ctx); - if (repl) - { - if (repl[0]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[0]); - if (repl[1]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[1]); - if (repl[2]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[2]); - if (repl[3]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[3]); - } - } - - if (cfunc_abiinfo&BIF_RETURNSONSTACK) *rvMode = RETURNVALUE_FPSTACK; - else if (cfunc_abiinfo&BIF_RETURNSBOOL) *rvMode=RETURNVALUE_BOOL; - - return parm_size + func_size; - } - // end of builtin function generation -} - -static int compileEelFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, - int *rvMode, int *fpStackUse, int *canHaveDenormalOutput) -{ - int func_size=0, parm_size=0; - int pn; - int last_nt_parm=-1,last_nt_parm_mode=0; - void *func_e=NULL; - int n_params; - opcodeRec *parmptrs[NSEEL_MAX_EELFUNC_PARAMETERS]; - int cfp_numparams=-1; - int cfp_statesize=0; - EEL_F **cfp_ptrs=NULL; - int func_raw=0; - int do_parms; - int x; - - void *func; - - for (x=0; x < 3; x ++) parmptrs[x] = op->parms.parms[x]; - - if (op->opcodeType == OPCODETYPE_FUNCX) - { - n_params=0; - for (x=0;x<3;x++) - { - opcodeRec *prni=op->parms.parms[x]; - while (prni && n_params < NSEEL_MAX_EELFUNC_PARAMETERS) - { - const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; - parmptrs[n_params++] = isMP ? prni->parms.parms[0] : prni; - if (!isMP) break; - prni = prni->parms.parms[1]; - } - } - } - else - { - n_params = 1 + op->opcodeType - OPCODETYPE_FUNC1; - } - - *fpStackUse = 0; - func = nseel_getEELFunctionAddress(ctx, op, - &cfp_numparams,&cfp_statesize,&cfp_ptrs, - computTableSize, - &func_e, &func_raw, - !!bufOut,namespacePathToThis,rvMode,fpStackUse,canHaveDenormalOutput); - - if (func_raw) func_size = (char*)func_e - (char*)func; - else if (func) func = GLUE_realAddress(func,func_e,&func_size); - - if (!func) RET_MINUS1_FAIL("eelfuncaddr") - - *fpStackUse += 1; - - if (cfp_numparams>0 && n_params != cfp_numparams) - { - _codeHandleFunctionRec *fn = (_codeHandleFunctionRec*)op->fn; - snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"Function '%s' takes %d parameters, passed %d\n",fn->fname,cfp_numparams,n_params); - RET_MINUS1_FAIL("eelfuncnp") - } - - // user defined function - do_parms = cfp_numparams>0 && cfp_ptrs && cfp_statesize>0; - - // if function local/parameter state is zero, we need to allocate storage for it - if (cfp_statesize>0 && cfp_ptrs && !cfp_ptrs[0]) - { - EEL_F *pstate = newDataBlock(sizeof(EEL_F)*cfp_statesize,8); - if (!pstate) RET_MINUS1_FAIL("eelfuncdb") - - for (pn=0;pn= 0 && do_parms) - { - if (last_nt_parm_mode == RETURNVALUE_FPSTACK) - { - if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) RET_MINUS1_FAIL("eelfunc_size popfpstacktostack") - if (bufOut) memcpy(bufOut + parm_size,GLUE_POP_FPSTACK_TOSTACK,sizeof(GLUE_POP_FPSTACK_TOSTACK)); - parm_size+=sizeof(GLUE_POP_FPSTACK_TOSTACK); - } - else - { - if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1PTR_AS_VALUE)) RET_MINUS1_FAIL("eelfunc_size pushp1ptrasval") - - // push - if (bufOut) memcpy(bufOut + parm_size,&GLUE_PUSH_P1PTR_AS_VALUE,sizeof(GLUE_PUSH_P1PTR_AS_VALUE)); - parm_size+=sizeof(GLUE_PUSH_P1PTR_AS_VALUE); - } - } - - last_nt_parm_mode=0; - lsz = compileOpcodes(ctx,parmptrs[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, - do_parms ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : RETURNVALUE_IGNORE,&last_nt_parm_mode,&sUse, &needDenorm); - - // todo: if needDenorm, denorm convert when copying parameter - - if (lsz<0) RET_MINUS1_FAIL("eelfunc, coc fail") - - if (last_nt_parm_mode == RETURNVALUE_FPSTACK) sUse++; - if (sUse > *fpStackUse) *fpStackUse=sUse; - parm_size += lsz; - - last_nt_parm = pn; - } - // pop non-trivial results into place - if (last_nt_parm >=0 && do_parms) - { - while (--pn >= 0) - { - if (OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // skip and process after - if (pn == last_nt_parm) - { - if (last_nt_parm_mode == RETURNVALUE_FPSTACK) - { - // pop to memory directly - const int cpsize = GLUE_POP_FPSTACK_TO_PTR(NULL,NULL); - if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size popfpstacktoptr") - - if (bufOut) GLUE_POP_FPSTACK_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); - parm_size += cpsize; - } - else - { - // copy direct p1ptr to mem - const int cpsize = GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); - if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size copyvalueatp1toptr") - - if (bufOut) GLUE_COPY_VALUE_AT_P1_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); - parm_size += cpsize; - } - } - else - { - const int popsize = GLUE_POP_VALUE_TO_ADDR(NULL,NULL); - if (bufOut_len < parm_size + popsize) RET_MINUS1_FAIL("eelfunc size pop value to addr") - - if (bufOut) GLUE_POP_VALUE_TO_ADDR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); - parm_size+=popsize; - - } - } - } - - // finally, set any trivial parameters - if (do_parms) - { - const int cpsize = GLUE_MOV_PX_DIRECTVALUE_SIZE + GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); - for (pn=0; pn < n_params; pn++) - { - if (!OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // set trivial values, we already set nontrivials - - if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size trivial set") - - if (bufOut) - { - if (generateValueToReg(ctx,parmptrs[pn],bufOut + parm_size,0,namespacePathToThis, 1)<0) RET_MINUS1_FAIL("eelfunc gvr fail") - GLUE_COPY_VALUE_AT_P1_TO_PTR(bufOut + parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE,cfp_ptrs[pn]); - } - parm_size += cpsize; - - } - } - - if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("eelfunc size combined") - - if (bufOut) memcpy(bufOut + parm_size, func, func_size); - - return parm_size + func_size; - // end of EEL function generation -} - -#ifdef DUMP_OPS_DURING_COMPILE -void dumpOp(compileContext *ctx, opcodeRec *op, int start); -#endif - -#ifdef GLUE_MAX_JMPSIZE -#define CHECK_SIZE_FORJMP(x,y) if ((x)<0 || (x)>=GLUE_MAX_JMPSIZE) goto y; -#define RET_MINUS1_FAIL_FALLBACK(err,j) goto j; -#else -#define CHECK_SIZE_FORJMP(x,y) -#define RET_MINUS1_FAIL_FALLBACK(err,j) RET_MINUS1_FAIL(err) -#endif -static int compileOpcodesInternal(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, int *calledRvType, int preferredReturnValues, int *fpStackUse, int *canHaveDenormalOutput) -{ - int rv_offset=0; - if (!op) RET_MINUS1_FAIL("coi !op") - - *fpStackUse=0; - // special case: statement delimiting means we can process the left side into place, and iteratively do the second parameter without recursing - // also we don't need to save/restore anything to the stack (which the normal 2 parameter function processing does) - while (op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) - { - int fUse; - int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL,&fUse,NULL); - if (parm_size < 0) RET_MINUS1_FAIL("coc join fail") - op = op->parms.parms[1]; - if (!op) RET_MINUS1_FAIL("join got to null") - - if (fUse>*fpStackUse) *fpStackUse=fUse; - if (bufOut) bufOut += parm_size; - bufOut_len -= parm_size; - rv_offset += parm_size; -#ifdef DUMP_OPS_DURING_COMPILE - if (op->opcodeType != OPCODETYPE_FUNC2 || op->fntype != FN_JOIN_STATEMENTS) dumpOp(ctx,op,0); -#endif - } - - if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) - { - // special case: while - functionType *fn_ptr = (functionType *)op->fn; - if (op->opcodeType == OPCODETYPE_FUNC1 && fn_ptr == fnTable1 + 4) - { - *calledRvType = RETURNVALUE_BOOL; - -#ifndef GLUE_INLINE_LOOPS - // todo: PPC looping support when loop length is small enough - { - unsigned char *pwr=bufOut; - unsigned char *newblock2; - int stubsz; - void *stubfunc = GLUE_realAddress(nseel_asm_repeatwhile,nseel_asm_repeatwhile_end,&stubsz); - if (!stubfunc || bufOut_len < stubsz) RET_MINUS1_FAIL(stubfunc ? "repeatwhile size fail" :"repeatwhile addr fail") - - if (bufOut) - { - newblock2=compileCodeBlockWithRet(ctx,op->parms.parms[0],computTableSize,namespacePathToThis, RETURNVALUE_BOOL, NULL, fpStackUse, NULL); - if (!newblock2) RET_MINUS1_FAIL("repeatwhile ccbwr fail") - - memcpy(pwr,stubfunc,stubsz); - pwr=EEL_GLUE_set_immediate(pwr,(INT_PTR)newblock2); - } - - return rv_offset+stubsz; - } -#else - { - unsigned char *looppt, *jzoutpt; - int parm_size=0,subsz; - if (bufOut_len < parm_size + sizeof(GLUE_WHILE_SETUP) + sizeof(GLUE_WHILE_BEGIN)) RET_MINUS1_FAIL("while size fail 1") - if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_SETUP,sizeof(GLUE_WHILE_SETUP)); - parm_size+=sizeof(GLUE_WHILE_SETUP); - looppt = bufOut + parm_size; - if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_BEGIN,sizeof(GLUE_WHILE_BEGIN)); - parm_size+=sizeof(GLUE_WHILE_BEGIN); - - subsz = compileOpcodes(ctx,op->parms.parms[0],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL,fpStackUse, NULL); - if (subsz<0) RET_MINUS1_FAIL("while coc fail") - - if (bufOut_len < parm_size + sizeof(GLUE_WHILE_END) + sizeof(GLUE_WHILE_CHECK_RV)) RET_MINUS1_FAIL("which size fial 2") - - parm_size+=subsz; - if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_END, sizeof(GLUE_WHILE_END)); - parm_size+=sizeof(GLUE_WHILE_END); - jzoutpt = bufOut + parm_size; - - if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_CHECK_RV, sizeof(GLUE_WHILE_CHECK_RV)); - parm_size+=sizeof(GLUE_WHILE_CHECK_RV); - if (bufOut) - { - GLUE_JMP_SET_OFFSET(bufOut + parm_size,(looppt - (bufOut+parm_size)) ); - GLUE_JMP_SET_OFFSET(jzoutpt, (bufOut + parm_size) - jzoutpt); - } - return rv_offset+parm_size; - } - -#endif - } - - // special case: loop - if (op->opcodeType == OPCODETYPE_FUNC2 && fn_ptr == fnTable1+3) - { - int fUse; - int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_FPSTACK, NULL,&fUse, NULL); - if (parm_size < 0) RET_MINUS1_FAIL("loop coc fail") - - *calledRvType = RETURNVALUE_BOOL; - if (fUse > *fpStackUse) *fpStackUse=fUse; - -#ifndef GLUE_INLINE_LOOPS - // todo: PPC looping support when loop length is small enough - { - void *stub; - int stubsize; - unsigned char *newblock2, *p; - stub = GLUE_realAddress(nseel_asm_repeat,nseel_asm_repeat_end,&stubsize); - if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("loop size fail") - if (bufOut) - { - newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, RETURNVALUE_IGNORE, NULL,fpStackUse, NULL); - - p = bufOut + parm_size; - memcpy(p, stub, stubsize); - - p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); - } - return rv_offset + parm_size + stubsize; - } -#else - { - int subsz; - int fUse=0; - unsigned char *skipptr1,*loopdest; - if (bufOut_len < parm_size + sizeof(GLUE_LOOP_LOADCNT) + sizeof(GLUE_LOOP_CLAMPCNT) + sizeof(GLUE_LOOP_BEGIN)) RET_MINUS1_FAIL("loop size fail") - - // store, convert to int, compare against 1, if less than, skip to end - if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_LOADCNT,sizeof(GLUE_LOOP_LOADCNT)); - parm_size += sizeof(GLUE_LOOP_LOADCNT); - skipptr1 = bufOut+parm_size; - - // compare aginst max loop length, jump to loop start if not above it - if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_CLAMPCNT,sizeof(GLUE_LOOP_CLAMPCNT)); - parm_size += sizeof(GLUE_LOOP_CLAMPCNT); - - // loop code: - loopdest = bufOut + parm_size; - if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_BEGIN,sizeof(GLUE_LOOP_BEGIN)); - parm_size += sizeof(GLUE_LOOP_BEGIN); - - subsz = compileOpcodes(ctx,op->parms.parms[1],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL, &fUse, NULL); - if (subsz<0) RET_MINUS1_FAIL("loop coc fail") - if (fUse > *fpStackUse) *fpStackUse=fUse; - - parm_size += subsz; - - if (bufOut_len < parm_size + sizeof(GLUE_LOOP_END)) RET_MINUS1_FAIL("loop size fail 2") - - if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_END,sizeof(GLUE_LOOP_END)); - parm_size += sizeof(GLUE_LOOP_END); - - if (bufOut) - { - GLUE_JMP_SET_OFFSET(bufOut + parm_size,loopdest - (bufOut+parm_size)); - GLUE_JMP_SET_OFFSET(skipptr1, (bufOut+parm_size) - skipptr1); - } - - return rv_offset + parm_size; - - } -#endif - } - - // special case: BAND/BOR - if (op->opcodeType == OPCODETYPE_FUNC2 && (fn_ptr == fnTable1+1 || fn_ptr == fnTable1+2)) - { - int fUse=0; - int parm_size,parm_size_pre; - int retType=RETURNVALUE_IGNORE; - if (preferredReturnValues != RETURNVALUE_IGNORE) retType = RETURNVALUE_BOOL; - - *calledRvType = retType; - - parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL, &fUse, NULL); - if (parm_size < 0) RET_MINUS1_FAIL("loop band/bor coc fail") - - if (fUse > *fpStackUse) *fpStackUse=fUse; - - - parm_size_pre=parm_size; - - { - int sz2, fUse=0; - unsigned char *destbuf; - const int testsz=(fn_ptr == fnTable1+2) ? sizeof(GLUE_JMP_IF_P1_NZ) : sizeof(GLUE_JMP_IF_P1_Z); - if (bufOut_len < parm_size+testsz) RET_MINUS1_FAIL_FALLBACK("band/bor size fail",doNonInlinedAndOr_) - - if (bufOut) memcpy(bufOut+parm_size,(fn_ptr == fnTable1+2) ? GLUE_JMP_IF_P1_NZ : GLUE_JMP_IF_P1_Z,testsz); - parm_size += testsz; - destbuf = bufOut + parm_size; - - sz2= compileOpcodes(ctx,op->parms.parms[1],bufOut?bufOut+parm_size:NULL,bufOut_len-parm_size, computTableSize, namespacePathToThis, retType, NULL,&fUse, NULL); - - CHECK_SIZE_FORJMP(sz2,doNonInlinedAndOr_) - if (sz2<0) RET_MINUS1_FAIL("band/bor coc fail") - - parm_size+=sz2; - if (bufOut) GLUE_JMP_SET_OFFSET(destbuf, (bufOut + parm_size) - destbuf); - - if (fUse > *fpStackUse) *fpStackUse=fUse; - return rv_offset + parm_size; - } -#ifdef GLUE_MAX_JMPSIZE - if (0) - { - void *stub; - int stubsize; - unsigned char *newblock2, *p; - - // encode as function call -doNonInlinedAndOr_: - parm_size = parm_size_pre; - - if (fn_ptr == fnTable1+1) - { - stub = GLUE_realAddress(nseel_asm_band,nseel_asm_band_end,&stubsize); - } - else - { - stub = GLUE_realAddress(nseel_asm_bor,nseel_asm_bor_end,&stubsize); - } - - if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("band/bor len fail") - - if (bufOut) - { - fUse=0; - newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, retType, NULL, &fUse, NULL); - if (!newblock2) RET_MINUS1_FAIL("band/bor ccbwr fail") - - if (fUse > *fpStackUse) *fpStackUse=fUse; - - p = bufOut + parm_size; - memcpy(p, stub, stubsize); - - p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); - } - return rv_offset + parm_size + stubsize; - } -#endif - } - - if (op->opcodeType == OPCODETYPE_FUNC3 && fn_ptr == fnTable1 + 0) // special case: IF - { - int fUse=0; - int parm_size_pre; - int use_rv = RETURNVALUE_IGNORE; - int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL,&fUse, NULL); - if (parm_size < 0) RET_MINUS1_FAIL("if coc fail") - if (fUse > *fpStackUse) *fpStackUse=fUse; - - if (preferredReturnValues & RETURNVALUE_NORMAL) use_rv=RETURNVALUE_NORMAL; - else if (preferredReturnValues & RETURNVALUE_FPSTACK) use_rv=RETURNVALUE_FPSTACK; - else if (preferredReturnValues & RETURNVALUE_BOOL) use_rv=RETURNVALUE_BOOL; - - *calledRvType = use_rv; - parm_size_pre = parm_size; - - { - int csz,hasSecondHalf; - if (bufOut_len < parm_size + sizeof(GLUE_JMP_IF_P1_Z)) RET_MINUS1_FAIL_FALLBACK("if size fail",doNonInlineIf_) - if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_IF_P1_Z,sizeof(GLUE_JMP_IF_P1_Z)); - parm_size += sizeof(GLUE_JMP_IF_P1_Z); - csz=compileOpcodes(ctx,op->parms.parms[1],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); - if (fUse > *fpStackUse) *fpStackUse=fUse; - hasSecondHalf = preferredReturnValues || !OPCODE_IS_TRIVIAL(op->parms.parms[2]); - - CHECK_SIZE_FORJMP(csz,doNonInlineIf_) - if (csz<0) RET_MINUS1_FAIL("if coc fial") - - if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size, csz + (hasSecondHalf?sizeof(GLUE_JMP_NC):0)); - parm_size+=csz; - - if (hasSecondHalf) - { - if (bufOut_len < parm_size + sizeof(GLUE_JMP_NC)) RET_MINUS1_FAIL_FALLBACK("if len fail",doNonInlineIf_) - if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_NC,sizeof(GLUE_JMP_NC)); - parm_size+=sizeof(GLUE_JMP_NC); - - csz=compileOpcodes(ctx,op->parms.parms[2],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL, &fUse, canHaveDenormalOutput); - - CHECK_SIZE_FORJMP(csz,doNonInlineIf_) - if (csz<0) RET_MINUS1_FAIL("if coc 2 fail") - - // update jump address - if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size,csz); - parm_size+=csz; - if (fUse > *fpStackUse) *fpStackUse=fUse; - } - return rv_offset + parm_size; - } -#ifdef GLUE_MAX_JMPSIZE - if (0) - { - unsigned char *newblock2,*newblock3,*ptr; - void *stub; - int stubsize; -doNonInlineIf_: - parm_size = parm_size_pre; - stub = GLUE_realAddress(nseel_asm_if,nseel_asm_if_end,&stubsize); - - if (!stub || bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL(stub ? "if sz fail" : "if addr fail") - - if (bufOut) - { - fUse=0; - newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); - if (fUse > *fpStackUse) *fpStackUse=fUse; - newblock3 = compileCodeBlockWithRet(ctx,op->parms.parms[2],computTableSize,namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); - if (fUse > *fpStackUse) *fpStackUse=fUse; - if (!newblock2 || !newblock3) RET_MINUS1_FAIL("if subblock gen fail") - - ptr = bufOut + parm_size; - memcpy(ptr, stub, stubsize); - - ptr=EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock2); - EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock3); - } - return rv_offset + parm_size + stubsize; - } -#endif - } - } - - switch (op->opcodeType) - { - case OPCODETYPE_DIRECTVALUE: - if (preferredReturnValues == RETURNVALUE_BOOL) - { - int w = fabs(op->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; - int wsz=(w?sizeof(GLUE_SET_P1_NZ):sizeof(GLUE_SET_P1_Z)); - - *calledRvType = RETURNVALUE_BOOL; - if (bufOut_len < wsz) RET_MINUS1_FAIL("direct bool size fail3") - if (bufOut) memcpy(bufOut,w?GLUE_SET_P1_NZ:GLUE_SET_P1_Z,wsz); - return rv_offset+wsz; - } - else if (preferredReturnValues & RETURNVALUE_FPSTACK) - { -#ifdef GLUE_HAS_FLDZ - if (op->parms.dv.directValue == 0.0) - { - *fpStackUse = 1; - *calledRvType = RETURNVALUE_FPSTACK; - if (bufOut_len < sizeof(GLUE_FLDZ)) RET_MINUS1_FAIL("direct fp fail 1") - if (bufOut) memcpy(bufOut,GLUE_FLDZ,sizeof(GLUE_FLDZ)); - return rv_offset+sizeof(GLUE_FLDZ); - } -#endif -#ifdef GLUE_HAS_FLD1 - if (op->parms.dv.directValue == 1.0) - { - *fpStackUse = 1; - *calledRvType = RETURNVALUE_FPSTACK; - if (bufOut_len < sizeof(GLUE_FLD1)) RET_MINUS1_FAIL("direct fp fail 1") - if (bufOut) memcpy(bufOut,GLUE_FLD1,sizeof(GLUE_FLD1)); - return rv_offset+sizeof(GLUE_FLD1); - } -#endif - } - // fall through - - case OPCODETYPE_VALUE_FROM_NAMESPACENAME: - case OPCODETYPE_VARPTR: - case OPCODETYPE_VARPTRPTR: - - - #ifdef GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE - if (OPCODE_IS_TRIVIAL(op)) - { - if (preferredReturnValues & RETURNVALUE_FPSTACK) - { - *fpStackUse = 1; - if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE) RET_MINUS1_FAIL("direct fp fail 2") - if (bufOut) - { - if (generateValueToReg(ctx,op,bufOut,-1,namespacePathToThis, 1 /*allow caching*/)<0) RET_MINUS1_FAIL("direct fp fail gvr") - } - *calledRvType = RETURNVALUE_FPSTACK; - return rv_offset+GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE; - } - } - #endif - - if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_SIZE) - { - RET_MINUS1_FAIL("direct value fail 1") - } - if (bufOut) - { - if (generateValueToReg(ctx,op,bufOut,0,namespacePathToThis, !!(preferredReturnValues&RETURNVALUE_FPSTACK)/*cache if going to the fp stack*/)<0) RET_MINUS1_FAIL("direct value gvr fail3") - } - return rv_offset + GLUE_MOV_PX_DIRECTVALUE_SIZE; - - case OPCODETYPE_FUNCX: - case OPCODETYPE_FUNC1: - case OPCODETYPE_FUNC2: - case OPCODETYPE_FUNC3: - - if (op->fntype == FUNCTYPE_EELFUNC_THIS || op->fntype == FUNCTYPE_EELFUNC) - { - int a; - - a = compileEelFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,canHaveDenormalOutput); - if (a<0) return a; - rv_offset += a; - } - else - { - int a; - a = compileNativeFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,preferredReturnValues,canHaveDenormalOutput); - if (a<0)return a; - rv_offset += a; - } - return rv_offset; - } - - RET_MINUS1_FAIL("default opcode fail") -} - -#ifdef DUMP_OPS_DURING_COMPILE -FILE *g_debugfp; -int g_debugfp_indent; -int g_debugfp_histsz=0; - -void dumpOp(compileContext *ctx, opcodeRec *op, int start) -{ - if (start>=0) - { - if (g_debugfp) - { - static opcodeRec **hist; - - int x; - int hit=0; - if (!hist) hist = (opcodeRec**) calloc(1024,1024*sizeof(opcodeRec*)); - for(x=0;x=100) *(char *)1=0; - fprintf(g_debugfp,"%*s{ %p : %d%s: ",g_debugfp_indent," ",op,op->opcodeType, hit ? " -- DUPLICATE" : ""); - switch (op->opcodeType) - { - case OPCODETYPE_DIRECTVALUE: - fprintf(g_debugfp,"dv %f",op->parms.dv.directValue); - break; - case OPCODETYPE_VARPTR: - { - int wb; - for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - char **plist=ctx->varTable_Names[wb]; - if (!plist) break; - - if (op->parms.dv.valuePtr >= ctx->varTable_Values[wb] && op->parms.dv.valuePtr < ctx->varTable_Values[wb] + NSEEL_VARS_PER_BLOCK) - { - fprintf(g_debugfp,"var %s",plist[op->parms.dv.valuePtr - ctx->varTable_Values[wb]]); - break; - } - } - } - break; - case OPCODETYPE_FUNC1: - case OPCODETYPE_FUNC2: - case OPCODETYPE_FUNC3: - case OPCODETYPE_FUNCX: - if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) - { - functionType *p=(functionType*)op->fn; - fprintf(g_debugfp,"func %d: %s",p->nParams&0xff,p->name); - } - else - fprintf(g_debugfp,"sf %d",op->fntype); - break; - - } - fprintf(g_debugfp,"\n"); - g_debugfp_indent+=2; - } - } - else - { - if (g_debugfp) - { - g_debugfp_indent-=2; - fprintf(g_debugfp,"%*s}%p\n",g_debugfp_indent," ",op); - } - } -} -#endif - -int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, - int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput) -{ - int code_returns=RETURNVALUE_NORMAL; - int fpsu=0; - int codesz; - int denorm=0; - -#ifdef DUMP_OPS_DURING_COMPILE - dumpOp(ctx,op,1); -#endif - - codesz = compileOpcodesInternal(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis,&code_returns, supportedReturnValues,&fpsu,&denorm); - if (denorm && canHaveDenormalOutput) *canHaveDenormalOutput=1; - -#ifdef DUMP_OPS_DURING_COMPILE - dumpOp(ctx,op,-1); -#endif - - if (codesz < 0) return codesz; - - - /* - { - char buf[512]; - sprintf(buf,"opcode %d %d (%s): fpu use: %d\n",op->opcodeType,op->fntype, - op->opcodeType >= OPCODETYPE_FUNC1 && op->fntype == FUNCTYPE_FUNCTIONTYPEREC ? ( - ((functionType *)op->fn)->name - ) : "", - fpsu); - OutputDebugString(buf); - } - */ - - if (fpStackUse) *fpStackUse=fpsu; - - if (bufOut) bufOut += codesz; - bufOut_len -= codesz; - - - if (code_returns == RETURNVALUE_BOOL && !(supportedReturnValues & RETURNVALUE_BOOL) && supportedReturnValues) - { - int stubsize; - void *stub = GLUE_realAddress(nseel_asm_booltofp,nseel_asm_booltofp_end,&stubsize); - if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"booltofp size":"booltfp addr") - if (bufOut) - { - unsigned char *p=bufOut; - memcpy(bufOut,stub,stubsize); - bufOut += stubsize; - } - codesz+=stubsize; - bufOut_len -= stubsize; - - code_returns = RETURNVALUE_FPSTACK; - } - - - // default processing of code_returns to meet return value requirements - if (supportedReturnValues & code_returns) - { - if (rvType) *rvType = code_returns; - return codesz; - } - - - if (rvType) *rvType = RETURNVALUE_IGNORE; - - - if (code_returns == RETURNVALUE_NORMAL) - { - if (supportedReturnValues & (RETURNVALUE_FPSTACK|RETURNVALUE_BOOL)) - { - if (bufOut_len < GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE) RET_MINUS1_FAIL("pushvalatpxtofpstack,size") - if (bufOut) - { - GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(bufOut,0); // always fld qword [eax] but we might change that later - bufOut += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; - } - codesz += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; - bufOut_len -= GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; - - if (supportedReturnValues & RETURNVALUE_BOOL) - { - code_returns = RETURNVALUE_FPSTACK; - } - else - { - if (rvType) *rvType = RETURNVALUE_FPSTACK; - } - } - } - - if (code_returns == RETURNVALUE_FPSTACK) - { - if (supportedReturnValues & RETURNVALUE_BOOL) - { - int stubsize; - void *stub = GLUE_realAddress(nseel_asm_fptobool,nseel_asm_fptobool_end,&stubsize); - if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"fptobool size":"fptobool addr") - if (bufOut) - { - memcpy(bufOut,stub,stubsize); - bufOut += stubsize; - } - codesz+=stubsize; - bufOut_len -= stubsize; - - if (rvType) *rvType = RETURNVALUE_BOOL; - } - else if (supportedReturnValues & RETURNVALUE_NORMAL) - { - if (computTableSize) (*computTableSize) ++; - - if (bufOut_len < GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE) RET_MINUS1_FAIL("popfpstacktowtptopxsize") - - // generate fp-pop to temp space - if (bufOut) GLUE_POP_FPSTACK_TO_WTP_TO_PX(bufOut,0); - codesz+=GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE; - if (rvType) *rvType = RETURNVALUE_NORMAL; - } - else - { - // toss return value that will be ignored - if (bufOut_len < GLUE_POP_FPSTACK_SIZE) RET_MINUS1_FAIL("popfpstack size") - if (bufOut) memcpy(bufOut,GLUE_POP_FPSTACK,GLUE_POP_FPSTACK_SIZE); - codesz+=GLUE_POP_FPSTACK_SIZE; - } - } - - return codesz; -} - - - - -static char *preprocessCode(compileContext *ctx, char *expression, int src_offset_bytes, int dest_offset_bytes) -{ - char *expression_start=expression; - int len=0; - int alloc_len=strlen(expression)+1+64; - char *buf=(char *)malloc(alloc_len); - int semicnt=0; - // we need to call onCompileNewLine for each new line we get - - //onCompileNewLine(ctx, - - while (*expression) - { - if (len > alloc_len-64) - { - alloc_len = len+128; - buf=(char*)realloc(buf,alloc_len); - } - - if (expression[0] == '/') - { - if (expression[1] == '/') - { - expression+=2; - if (!strncasecmp(expression,"#eel-no-optimize:",17)) - { - ctx->optimizeDisableFlags = atoi(expression+17); - } - - while (expression[0] && expression[0] != '\n') expression++; - continue; - } - else if (expression[1] == '*') - { - expression+=2; - while (expression[0] && (expression[0] != '*' || expression[1] != '/')) - { - if (expression[0] == '\n') onCompileNewLine(ctx,expression+1-expression_start + src_offset_bytes,dest_offset_bytes+len); - expression++; - } - if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/ - continue; - } - } - - if (expression[0] == '(' && expression[1]==')') - { - expression+=2; - memcpy(buf+len,"(0)",3); - len+=3; - ctx->l_stats[0]+=3; - continue; - } - if (expression[0] == '$') - { - if (toupper(expression[1]) == 'X'||expression[1] == '~') - { - char isBits = expression[1] == '~'; - char *p=expression+2; - unsigned int v=strtoul(expression+2,&p,isBits ? 10 : 16); - char tmp[256]; - expression=p; - - if (isBits) - { - if (v>53) v=53; - sprintf(tmp,"%.1f",(double) ((((WDL_INT64)1) << v) - 1)); - } - else - { - sprintf(tmp,"%u",v); - } - memcpy(buf+len,tmp,strlen(tmp)); - len+=strlen(tmp); - ctx->l_stats[0]+=strlen(tmp); - continue; - - } - if (expression[1]=='\'' && expression[2] && expression[3]=='\'') - { - char tmp[64]; - sprintf(tmp,"%u",((unsigned char *)expression)[2]); - expression+=4; - - memcpy(buf+len,tmp,strlen(tmp)); - len+=strlen(tmp); - ctx->l_stats[0]+=strlen(tmp); - continue; - } - if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I') - { - static char *str="3.141592653589793"; - expression+=3; - memcpy(buf+len,str,17); - len+=17; //strlen(str); - ctx->l_stats[0]+=17; - continue; - } - if (toupper(expression[1]) == 'E') - { - static char *str="2.71828183"; - expression+=2; - memcpy(buf+len,str,10); - len+=10; //strlen(str); - ctx->l_stats[0]+=10; - continue; - } - if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I') - { - static char *str="1.61803399"; - expression+=4; - memcpy(buf+len,str,10); - len+=10; //strlen(str); - ctx->l_stats[0]+=10; - continue; - } - - } - - { - char c=*expression++; - - if (c == '\n') onCompileNewLine(ctx,expression-expression_start + src_offset_bytes,len + dest_offset_bytes); - if (isspace(c)) c=' '; - - if (c == '(') semicnt++; - else if (c == ')') { semicnt--; if (semicnt < 0) semicnt=0; } - else if (c == ';' && semicnt > 0) - { - // convert ; to % if next nonwhitespace char is alnum, otherwise convert to space - int p=0; - int nc; - int commentstate=0; - while ((nc=expression[p])) - { - if (!commentstate && nc == '/') - { - if (expression[p+1] == '/') commentstate=1; - else if (expression[p+1] == '*') commentstate=2; - } - - if (commentstate == 1 && nc == '\n') commentstate=0; - else if (commentstate == 2 && nc == '*' && expression[p+1]=='/') - { - p++; // skip * - commentstate=0; - } - else if (!commentstate && !isspace(nc)) break; - - p++; - } - // fucko, we should look for even more chars, me thinks - if (nc && (isalnum(nc) -#if 1 - || nc == '(' || nc == '_' || nc == '!' || nc == '$' || nc == '-' || nc == '+' /* unary +, -, !, symbols, etc, mean new statement */ -#endif - )) c='%'; - else c = ' '; // stray ; - } -#if 0 - else if (semicnt > 0 && c == ',') - { - int p=0; - int nc; - while ((nc=expression[p]) && isspace(nc)) p++; - if (nc == ',' || nc == ')') - { - expression += p+1; - buf[len++]=','; - buf[len++]='0'; - c=nc; // append this char - } - } -#endif - // list of operators - - else if (!isspace(c) && !isalnum(c)) // check to see if this operator is ours - { - - static char *symbollists[]= - { - "", // stop at any control char that is not parenthed - ":(,;?%", - ",):?;", // or || or && - ",);", // jf> removed :? from this, for = - ",);", - "", // rscan=5, only scans for a negative ] level - "", // rscan=6, like rscan==0 but lower precedence -- stop at any non-^ control char that is not parenthed - }; - - - static const struct - { - char op[2]; - char lscan,rscan; - char *func; - } preprocSymbols[] = - { - {{'+','='}, 0, 3, "_addop" }, - {{'-','='}, 0, 3, "_subop" }, - {{'%','='}, 0, 3, "_modop" }, - {{'|','='}, 0, 3, "_orop" }, - {{'&','='}, 0, 3, "_andop"}, - {{'~','='}, 0, 3, "_xorop" }, - - {{'/','='}, 0, 3, "_divop"}, - {{'*','='}, 0, 3, "_mulop"}, - {{'^','='}, 0, 3, "_powop"}, - - {{'=','='}, 1, 2, "_equal" }, - {{'<','='}, 1, 2, "_beleq" }, - {{'>','='}, 1, 2, "_aboeq" }, - {{'<','<'}, 0, 6, "_shl" }, - {{'>','>'}, 0, 6, "_shr" }, - {{'<',0 }, 1, 2, "_below" }, - {{'>',0 }, 1, 2, "_above" }, - {{'!','='}, 1, 2, "_noteq" }, - {{'|','|'}, 1, 2, "_or" }, - {{'&','&'}, 1, 2, "_and" }, - {{'=',0 }, 0, 3, "_set" }, - {{'~',0}, 0, 6, "_xor" }, - {{'%',0}, 0, 6, "_mod" }, - {{'^',0}, 0, 0, "pow" }, - - - {{'[',0 }, 0, 5, }, - {{'!',0 },-1, 0, }, // this should also ignore any leading +- - {{'?',0 }, 1, 4, }, - - }; - - - int n; - int ns=sizeof(preprocSymbols)/sizeof(preprocSymbols[0]); - for (n = 0; n < ns; n++) - { - if (c == preprocSymbols[n].op[0] && (!preprocSymbols[n].op[1] || expression[0] == preprocSymbols[n].op[1])) - { - break; - } - } - if (n < ns) - { - - int lscan=preprocSymbols[n].lscan; - int rscan=preprocSymbols[n].rscan; - - // parse left side of =, scanning back for an unparenthed nonwhitespace nonalphanumeric nonparenth? - // so megabuf(x+y)= would be fine, x=, but +x= would do +set(x,) - char *l_ptr=0; - char *r_ptr=0; - if (lscan >= 0) - { - char *scan=symbollists[lscan]; - int l_semicnt=0; - l_ptr=buf + len - 1; - while (l_ptr >= buf) - { - if (*l_ptr == ')') l_semicnt++; - else if (*l_ptr == '(') - { - l_semicnt--; - if (l_semicnt < 0) break; - } - else if (!l_semicnt) - { - if (!*scan) - { - if (!isspace(*l_ptr) && !isalnum(*l_ptr) && *l_ptr != '_' && *l_ptr != '.') break; - } - else - { - char *sc=scan; - if (lscan == 2 && ( // not currently used, even - (l_ptr[0]=='|' && l_ptr[1] == '|')|| - (l_ptr[0]=='&' && l_ptr[1] == '&') - ) - ) break; - while (*sc && *l_ptr != *sc) sc++; - if (*sc) break; - } - } - l_ptr--; - } - buf[len]=0; - - l_ptr++; - - len = l_ptr - buf; - - l_ptr = strdup(l_ptr); // doesn't need to be preprocessed since it just was - } - if (preprocSymbols[n].op[1]) expression++; - - r_ptr=expression; - { - // scan forward to an uncommented, unparenthed semicolon, comma, or ), or ] - int r_semicnt=0,r_semicnt2=0; - int r_qcnt=0; - char *scan=symbollists[rscan]; - int commentstate=0; - int hashadch=0; - while (*r_ptr) - { - if (!commentstate && *r_ptr == '/') - { - if (r_ptr[1] == '/') commentstate=1; - else if (r_ptr[1] == '*') commentstate=2; - } - if (commentstate == 1 && *r_ptr == '\n') commentstate=0; - else if (commentstate == 2 && *r_ptr == '*' && r_ptr[1]=='/') - { - r_ptr++; // skip * - commentstate=0; - } - else if (!commentstate) - { - if (*r_ptr == '(') { hashadch=1; r_semicnt++; } - else if (*r_ptr == '[') { hashadch=1; r_semicnt2++; } - else if (*r_ptr == ')') - { - r_semicnt--; - if (r_semicnt < 0 && r_semicnt2<=0) break; - } - else if (*r_ptr == ']') - { - r_semicnt2--; - if (r_semicnt2 < 0 && r_semicnt<=0) break; - } - else if (!r_semicnt && !r_semicnt2) - { - char *sc=scan; - if (*r_ptr == ';' || *r_ptr == ',') break; - - if (!rscan || rscan == 6) - { - if (*r_ptr == ':') break; - if (!isspace(*r_ptr) && !isalnum(*r_ptr) && *r_ptr != '_' && *r_ptr != '.' && - (rscan != 6 || *r_ptr != '^' || r_ptr[1] == '=') && hashadch) break; - if (isalnum(*r_ptr) || *r_ptr == '_')hashadch=1; - } - else if (rscan == 2 && - ((r_ptr[0]=='|' && r_ptr[1] == '|')|| - (r_ptr[0]=='&' && r_ptr[1] == '&') - ) - ) break; - - else if (rscan == 3 || rscan == 4) - { - if (*r_ptr == ':') r_qcnt--; - else if (*r_ptr == '?') r_qcnt++; - - if (r_qcnt < 3-rscan) break; - } - - while (*sc && *r_ptr != *sc) sc++; - if (*sc) break; - } - } - r_ptr++; - } - // expression -> r_ptr is our string (not including r_ptr) - - { - char *orp=r_ptr; - - char rps=*orp; - *orp=0; // temporarily terminate - - r_ptr=preprocessCode(ctx,expression,src_offset_bytes + (expression-expression_start),dest_offset_bytes + len); - expression=orp; - - *orp = rps; // fix termination(restore string) - } - - } - - if (r_ptr) - { - int thisl = strlen(l_ptr?l_ptr:"") + strlen(r_ptr) + 32; - - if (len+thisl > alloc_len-64) - { - alloc_len = len+thisl+128; - buf=(char*)realloc(buf,alloc_len); - } - - - if (n == ns-3) - { - char *lp = l_ptr; - char *rp = r_ptr; - while (lp && *lp && isspace(*lp)) lp++; - while (rp && *rp && isspace(*rp)) rp++; - if (lp && !strncasecmp(lp,"gmem",4) && (!lp[4] || isspace(lp[4]))) - { - len+=sprintf(buf+len,"_gmem(%s",r_ptr && *r_ptr ? r_ptr : "0"); - ctx->l_stats[0]+=strlen(l_ptr)+4; - } - else if (rp && *rp && strcmp(rp,"0")) - { - len+=sprintf(buf+len,"_mem((%s)+(%s)",lp,rp); - ctx->l_stats[0]+=strlen(lp)+strlen(rp)+8; - } - else - { - len+=sprintf(buf+len,"_mem(%s",lp); - ctx->l_stats[0]+=strlen(lp)+4; - } - - // skip the ] - if (*expression == ']') expression++; - - } - else if (n == ns-2) - { - len+=sprintf(buf+len,"_not(%s",r_ptr); - - ctx->l_stats[0]+=4; - } - else if (n == ns-1)// if (l_ptr,r_ptr1,r_ptr2) - { - char *rptr2=r_ptr; - char *tmp=r_ptr; - int parcnt=0; - int qcnt=1; - while (*rptr2) - { - if (*rptr2 == '?') qcnt++; - else if (*rptr2 == ':') qcnt--; - else if (*rptr2 == '(') parcnt++; - else if (*rptr2 == ')') parcnt--; - if (parcnt < 0) break; - if (!parcnt && !qcnt && *rptr2 == ':') break; - rptr2++; - } - if (*rptr2) *rptr2++=0; - while (isspace(*rptr2)) rptr2++; - - while (isspace(*tmp)) tmp++; - - len+=sprintf(buf+len,"_if(%s,%s,%s",l_ptr,*tmp?tmp:"0",*rptr2?rptr2:"0"); - ctx->l_stats[0]+=6; - } - else - { - len+=sprintf(buf+len,"%s(%s,%s",preprocSymbols[n].func,l_ptr?l_ptr:"",r_ptr); - ctx->l_stats[0]+=strlen(preprocSymbols[n].func)+2; - } - - } - - free(r_ptr); - free(l_ptr); - - - c = ')'; // close parenth below - } - } - -// if (c != ' ' || (len && buf[len-1] != ' ')) // don't bother adding multiple spaces - { - buf[len++]=c; - if (c != ' ') ctx->l_stats[0]++; - } - } - } - buf[len]=0; - - return buf; -} - -#ifdef PPROC_TEST - -int main(int argc, char* argv[]) -{ - compileContext ctx={0}; - char *p=preprocessCode(&ctx,argv[1]); - if (p)printf("%s\n",p); - free(p); - return 0; -} - -#endif - -#if 0 -static void movestringover(char *str, int amount) -{ - char tmp[1024+8]; - - int l=(int)strlen(str); - l=min(1024-amount-1,l); - - memcpy(tmp,str,l+1); - - while (l >= 0 && tmp[l]!='\n') l--; - l++; - - tmp[l]=0;//ensure we null terminate - - memcpy(str+amount,tmp,l+1); -} -#endif - -//------------------------------------------------------------------------------ -NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX _ctx, const char *__expression, int lineoffs) -{ - return NSEEL_code_compile_ex(_ctx,__expression,lineoffs,0); -} - -typedef struct topLevelCodeSegmentRec { - struct topLevelCodeSegmentRec *_next; - void *code; - int codesz; - int tmptable_use; -} topLevelCodeSegmentRec; - -NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX _ctx, const char *__expression, int lineoffs, int compile_flags) -{ - char *_expression; - compileContext *ctx = (compileContext *)_ctx; - char *expression,*expression_start; - codeHandleType *handle; - topLevelCodeSegmentRec *startpts_tail=NULL; - topLevelCodeSegmentRec *startpts=NULL; - _codeHandleFunctionRec *oldCommonFunctionList; - int curtabptr_sz=0; - void *curtabptr=NULL; - int had_err=0; - - if (!ctx) return 0; - - ctx->directValueCache=0; - ctx->optimizeDisableFlags=0; - - if (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET) - { - ctx->functions_common=NULL; // reset common function list - } - else - { - // reset common compiled function code, forcing a recompile if shared - _codeHandleFunctionRec *a = ctx->functions_common; - while (a) - { - _codeHandleFunctionRec *b = a->derivedCopies; - - if (a->localstorage) - { - // force local storage actual values to be reallocated if used again - memset(a->localstorage,0,sizeof(EEL_F *) * a->localstorage_size); - } - - a->startptr = NULL; // force this copy to be recompiled - - while (b) - { - b->startptr = NULL; // force derived copies to get recompiled - // no need to reset b->localstorage, since it points to a->localstorage - b=b->derivedCopies; - } - - a=a->next; - } - } - - ctx->last_error_string[0]=0; - - if (!__expression || !*__expression) return 0; - - - _expression = strdup(__expression); - if (!_expression) return 0; - - oldCommonFunctionList = ctx->functions_common; - { - // do in place replace of "$'x'" to "56 " or whatnot - // we avoid changing the length of the string here, due to wanting to know where errors occur - char *p=_expression; - while (*p) - { - if (p[0] == '$' && p[1]=='\'' && p[2] && p[3]=='\'') - { - char tmp[64]; - int a,tl; - sprintf(tmp,"%d",(int)((unsigned char *)p)[2]); - tl=strlen(tmp); - if (tl>3) tl=3; - for (a=0;aisSharedFunctions = !!(compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); - ctx->functions_local = NULL; - - freeBlocks(&ctx->tmpblocks_head); // free blocks - freeBlocks(&ctx->blocks_head); // free blocks - freeBlocks(&ctx->blocks_head_data); // free blocks - memset(ctx->l_stats,0,sizeof(ctx->l_stats)); - free(ctx->compileLineRecs); - ctx->compileLineRecs=0; - ctx->compileLineRecs_size=0; - ctx->compileLineRecs_alloc=0; - - handle = (codeHandleType*)newDataBlock(sizeof(codeHandleType),8); - - if (!handle) - { - free(_expression); - return 0; - } - - - memset(handle,0,sizeof(codeHandleType)); - - ctx->tmpCodeHandle = handle; - expression_start=expression=preprocessCode(ctx,_expression,0,0); - - while (*expression) - { - int computTableTop = 0; - int startptr_size=0; - void *startptr=NULL; - opcodeRec *start_opcode=NULL; - char *expr; - int function_numparms=0; - char is_fname[NSEEL_MAX_VARIABLE_NAMELEN+1]; - is_fname[0]=0; - - memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); - memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); - ctx->function_localTable_ValuePtrs=0; - ctx->function_usesThisPointer=0; - ctx->function_curName=NULL; - -#ifdef NSEEL_USE_OLD_PARSER - ctx->colCount=0; -#endif - - // single out segment - while (*expression == ';' || isspace(*expression)) expression++; - if (!*expression) break; - expr=expression; - - while (*expression && *expression != ';') expression++; - if (*expression) *expression++ = 0; - - // parse - - if (!strncasecmp(expr,"function",8) && isspace(expr[8])) - { - char *p = expr+8; - while (isspace(p[0])) p++; - if (isalpha(p[0]) || p[0] == '_') - { - int had_parms_locals=0; - char *sp=p; - int l; - while (isalnum(p[0]) || p[0] == '_') p++; - l=min(p-sp, sizeof(is_fname)-1); - memcpy(is_fname, sp, l); - is_fname[l]=0; - ctx->function_curName = is_fname; // only assigned for the duration of the loop, cleared later //-V507 - - expr = p; - - while (*expr) - { - const char *tn; - int tn_len; - p=expr; - while (isspace(*p)) p++; - - tn = p; - while (*p && !isspace(*p) && *p != '(') p++; - tn_len = p - tn; - - while (isspace(*p)) p++; - - if (*p == '(' && - ( - !tn_len || - (tn_len == 5 && !strncasecmp(tn,"local",tn_len)) || - (tn_len == 6 && !strncasecmp(tn,"static",tn_len)) || - (tn_len == 8 && !strncasecmp(tn,"instance",tn_len)) - ) - ) - { - int maxcnt=0,state=0; - int is_parms = 0; - int localTableContext = 0; - - if (tn_len == 0) - { - if (had_parms_locals) break; // formal parameters must be before instance() static() or local(), otherwise it is assumed to be the body of the function - is_parms = 1; - } - else - { - localTableContext = (tn_len == 8 && !strncasecmp(tn,"instance",tn_len)); //adding to "implied this" table - } - had_parms_locals=1; - - // skip past opening paren - p++; - - sp=p; - while (*p && *p != ')') - { - if (isspace(*p) || *p == ',') - { - if (state) maxcnt++; - state=0; - } - else state=1; - p++; - } - if (state) maxcnt++; - if (*p) - { - expr=p+1; - - if (maxcnt > 0) - { - char **ot = ctx->function_localTable_Names[localTableContext]; - int osz = ctx->function_localTable_Size[localTableContext]; - - maxcnt += osz; - - ctx->function_localTable_Names[localTableContext] = (char **)newTmpBlock(ctx,sizeof(char *) * maxcnt); - - if (ctx->function_localTable_Names[localTableContext]) - { - int i=osz; - if (osz && ot) memcpy(ctx->function_localTable_Names[localTableContext],ot,sizeof(char *) * osz); - p=sp; - while (p < expr-1 && i < maxcnt) - { - while (p < expr && (isspace(*p) || *p == ',')) p++; - sp=p; - while (p < expr-1 && (!isspace(*p) && *p != ',')) p++; - - if (isalpha(*sp) || *sp == '_') - { - char *newstr; - int l = (p-sp); - if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; - newstr = newTmpBlock(ctx,l+1); - if (newstr) - { - memcpy(newstr,sp,l); - newstr[l]=0; - ctx->function_localTable_Names[localTableContext][i++] = newstr; - } - } - } - - ctx->function_localTable_Size[localTableContext]=i; - - if (is_parms) function_numparms = i; - } - } - } - } - else break; - } - } - } - if (ctx->function_localTable_Size>0) - { - ctx->function_localTable_ValuePtrs = - ctx->isSharedFunctions ? newDataBlock(ctx->function_localTable_Size[0] * sizeof(EEL_F *),8) : - newTmpBlock(ctx,ctx->function_localTable_Size[0] * sizeof(EEL_F *)); - if (!ctx->function_localTable_ValuePtrs) - { - ctx->function_localTable_Size[0]=0; - function_numparms=0; - } - else - { - memset(ctx->function_localTable_ValuePtrs,0,sizeof(EEL_F *) * ctx->function_localTable_Size[0]); // force values to be allocated - } - } - - ctx->errVar=0; - -#ifdef NSEEL_USE_OLD_PARSER - nseel_llinit(ctx); - if (!nseel_yyparse(ctx,expr) && !ctx->errVar) - { - start_opcode = ctx->result; - } -#else - { - int nseelparse(compileContext* context); - -#ifdef NSEEL_SUPER_MINIMAL_LEXER - ctx->rdbuf_start = ctx->rdbuf = expr; - if (!nseelparse(ctx) && !ctx->errVar) - { - start_opcode = ctx->result; - } - ctx->rdbuf = NULL; -#else - - void nseelrestart (void *input_file ,void *yyscanner ); - - nseelrestart(NULL,ctx->scanner); - ctx->inputbufferptr = expr; - - if (!nseelparse(ctx) && !ctx->errVar) - { - start_opcode = ctx->result; - } - if (ctx->errVar && ctx->errVar_l>0) - { - const char *p=expr; - while (*p && ctx->errVar_l-->0) - { - while (*p && *p != '\n') { p++; ctx->errVar++; } - if (*p) { ctx->errVar++; p++; } - } - } - ctx->inputbufferptr=NULL; -#endif - - } -#endif - - if (start_opcode) - { - int rvMode=0, fUse=0; - -#ifdef LOG_OPT - char buf[512]; - int sd=0; - sprintf(buf,"pre opt sz=%d (tsackDepth=%d)\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL,RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); -#ifdef _WIN32 - OutputDebugString(buf); -#else - printf("%s\n",buf); -#endif -#endif - if (!(ctx->optimizeDisableFlags&OPTFLAG_NO_OPTIMIZE)) optimizeOpcodes(ctx,start_opcode,is_fname[0] ? 1 : 0); -#ifdef LOG_OPT - sprintf(buf,"post opt sz=%d, stack depth=%d\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL,NULL, RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); -#ifdef _WIN32 - OutputDebugString(buf); -#else - printf("%s\n",buf); -#endif -#endif - -#ifdef DUMP_OPS_DURING_COMPILE - g_debugfp_indent=0; - g_debugfp_histsz=0; - g_debugfp = fopen("C:/temp/foo.txt","w"); -#endif - startptr_size = compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL, - is_fname[0] ? (RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK) : RETURNVALUE_IGNORE, &rvMode, &fUse, NULL); // if not a function, force return value as address (avoid having to pop it ourselves - // if a function, allow the code to decide how return values are generated - -#ifdef DUMP_OPS_DURING_COMPILE - if (g_debugfp) fclose(g_debugfp); - g_debugfp=0; -#endif - - if (is_fname[0]) - { - _codeHandleFunctionRec *fr = ctx->isSharedFunctions ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : - newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); - if (fr) - { - memset(fr,0,sizeof(_codeHandleFunctionRec)); - fr->startptr_size = startptr_size; - fr->opcodes = start_opcode; - fr->rvMode = rvMode; - - fr->fpStackUsage=fUse; - fr->tmpspace_req = computTableTop; - - if (ctx->function_localTable_Size[0] > 0 && ctx->function_localTable_ValuePtrs) - { - fr->num_params=function_numparms; - fr->localstorage = ctx->function_localTable_ValuePtrs; - fr->localstorage_size = ctx->function_localTable_Size[0]; - } - - fr->usesThisPointer = ctx->function_usesThisPointer; - fr->isCommonFunction = ctx->isSharedFunctions; - - strcpy(fr->fname,is_fname); - - if (ctx->isSharedFunctions) - { - fr->next = ctx->functions_common; - ctx->functions_common = fr; - } - else - { - fr->next = ctx->functions_local; - ctx->functions_local = fr; - } - } - continue; - } - - if (!startptr_size) continue; // optimized away - if (startptr_size>0) - { - startptr = newTmpBlock(ctx,startptr_size); - if (startptr) - { - startptr_size=compileOpcodes(ctx,start_opcode,(unsigned char*)startptr,startptr_size,&computTableTop, NULL, RETURNVALUE_IGNORE, NULL,NULL, NULL); - if (startptr_size<=0) startptr = NULL; - - } - } - } - - if (!startptr) - { - int byteoffs = expr - expression_start; - int destoffs,linenumber; - char buf[50], *p; - int x,le; - -#ifdef NSEEL_EEL1_COMPAT_MODE - if (!startptr) continue; -#endif - - if (ctx->errVar > 0) byteoffs += ctx->errVar; - linenumber=findByteOffsetInSource(ctx,byteoffs,&destoffs); - if (destoffs < 0) destoffs=0; - - le=strlen(_expression); - if (destoffs >= le) destoffs=le; - p= _expression + destoffs; - x=0; - while (x < sizeof(buf)-1) - { - if (!*p) break; - if (x && (*p == '\r' || *p == '\n')) break; - - if (!isspace(*p) || (x && !isspace(p[-1]))) buf[x++]=*p; - - p++; - } - buf[x]=0; - - if (!ctx->last_error_string[0]) - snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"Around line %d '%s'",linenumber+lineoffs,buf); - - startpts=NULL; - startpts_tail=NULL; - had_err=1; - break; - } - - if (!is_fname[0]) // redundant check (if is_fname[0] is set and we succeeded, it should continue) - // but we'll be on the safe side - { - topLevelCodeSegmentRec *p = newTmpBlock(ctx,sizeof(topLevelCodeSegmentRec)); - p->_next=0; - p->code = startptr; - p->codesz = startptr_size; - p->tmptable_use = computTableTop; - - if (!startpts_tail) startpts_tail=startpts=p; - else - { - startpts_tail->_next=p; - startpts_tail=p; - } - - if (curtabptr_sz < computTableTop) - { - curtabptr_sz=computTableTop; - } - } - } - free(ctx->compileLineRecs); - ctx->compileLineRecs=0; - ctx->compileLineRecs_size=0; - ctx->compileLineRecs_alloc=0; - - memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); - memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); - ctx->function_localTable_ValuePtrs=0; - ctx->function_usesThisPointer=0; - ctx->function_curName=NULL; - - ctx->tmpCodeHandle = NULL; - - if (handle->want_stack) - { - if (!handle->stack) startpts=NULL; - } - - if (startpts) - { - curtabptr_sz += 2; // many functions use the worktable for temporary storage of up to 2 EEL_F's - - handle->workTable_size = curtabptr_sz; - handle->workTable = curtabptr = newDataBlock((curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F),32); - -#ifdef EEL_VALIDATE_WORKTABLE_USE - if (curtabptr) memset(curtabptr,0x3a,(curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F)); -#endif - if (!curtabptr) startpts=NULL; - } - - - if (startpts || (!had_err && (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS))) - { - unsigned char *writeptr; - topLevelCodeSegmentRec *p=startpts; - int size=sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE; // for ret at end :) - int wtpos=0; - - // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item as necessary - while (p) - { - if (wtpos <= 0) - { - wtpos=MIN_COMPUTABLE_SIZE; - size += GLUE_RESET_WTP(NULL,0); - } - size+=p->codesz; - wtpos -= p->tmptable_use; - p=p->_next; - } - handle->code = newCodeBlock(size,32); - if (handle->code) - { - writeptr=(unsigned char *)handle->code; - #if GLUE_FUNC_ENTER_SIZE > 0 - memcpy(writeptr,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); - writeptr += GLUE_FUNC_ENTER_SIZE; - #endif - p=startpts; - wtpos=0; - while (p) - { - if (wtpos <= 0) - { - wtpos=MIN_COMPUTABLE_SIZE; - writeptr+=GLUE_RESET_WTP(writeptr,curtabptr); - } - memcpy(writeptr,(char*)p->code,p->codesz); - writeptr += p->codesz; - wtpos -= p->tmptable_use; - - p=p->_next; - } - #if GLUE_FUNC_LEAVE_SIZE > 0 - memcpy(writeptr,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); - writeptr += GLUE_FUNC_LEAVE_SIZE; - #endif - memcpy(writeptr,&GLUE_RET,sizeof(GLUE_RET)); writeptr += sizeof(GLUE_RET); - ctx->l_stats[1]=size; - handle->code_size = writeptr - (unsigned char *)handle->code; - } - - handle->blocks = ctx->blocks_head; - handle->blocks_data = ctx->blocks_head_data; - ctx->blocks_head=0; - ctx->blocks_head_data=0; - } - else - { - // failed compiling, or failed calloc() - handle=NULL; // return NULL (after resetting blocks_head) - } - - - ctx->directValueCache=0; - ctx->functions_local = NULL; - - ctx->isSharedFunctions=0; - - freeBlocks(&ctx->tmpblocks_head); // free blocks - freeBlocks(&ctx->blocks_head); // free blocks of code (will be nonzero only on error) - freeBlocks(&ctx->blocks_head_data); // free blocks of data (will be nonzero only on error) - - if (handle) - { - handle->ramPtr = ctx->ram_state.blocks; - memcpy(handle->code_stats,ctx->l_stats,sizeof(ctx->l_stats)); - nseel_evallib_stats[0]+=ctx->l_stats[0]; - nseel_evallib_stats[1]+=ctx->l_stats[1]; - nseel_evallib_stats[2]+=ctx->l_stats[2]; - nseel_evallib_stats[3]+=ctx->l_stats[3]; - nseel_evallib_stats[4]++; - } - else - { - ctx->functions_common = oldCommonFunctionList; // failed compiling, remove any added common functions from the list - - // remove any derived copies of functions due to error, since we may have added some that have been freed - while (oldCommonFunctionList) - { - oldCommonFunctionList->derivedCopies=NULL; - oldCommonFunctionList=oldCommonFunctionList->next; - } - } - memset(ctx->l_stats,0,sizeof(ctx->l_stats)); - - free(expression_start); - free(_expression); - - return (NSEEL_CODEHANDLE)handle; -} - -//------------------------------------------------------------------------------ -void NSEEL_code_execute(NSEEL_CODEHANDLE code) -{ - INT_PTR tabptr; - INT_PTR codeptr; - codeHandleType *h = (codeHandleType *)code; - if (!h || !h->code) return; - - codeptr = (INT_PTR) h->code; -#if 0 - { - unsigned int *p=(unsigned int *)codeptr; - while (*p != GLUE_RET[0]) - { - printf("instr:%04X:%04X\n",*p>>16,*p&0xffff); - p++; - } - } -#endif - - tabptr=(INT_PTR)h->workTable; - //printf("calling code!\n"); - GLUE_CALL_CODE(tabptr,codeptr,(INT_PTR)h->ramPtr); - -} - - -char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx) -{ - compileContext *c=(compileContext *)ctx; - if (ctx && c->last_error_string[0]) return c->last_error_string; - return 0; -} - -//------------------------------------------------------------------------------ -void NSEEL_code_free(NSEEL_CODEHANDLE code) -{ - codeHandleType *h = (codeHandleType *)code; - if (h != NULL) - { -#ifdef EEL_VALIDATE_WORKTABLE_USE - if (h->workTable) - { - char *p = ((char*)h->workTable) + h->workTable_size*sizeof(EEL_F); - int x; - for(x=COMPUTABLE_EXTRA_SPACE*sizeof(EEL_F) - 1;x >= 0; x --) - if (p[x] != 0x3a) - { - char buf[512]; - sprintf(buf,"worktable overrun at byte %d (wts=%d), value = %f\n",x,h->workTable_size, *(EEL_F*)(p+(x&~(sizeof(EEL_F)-1)))); - OutputDebugString(buf); - break; - } - } -#endif - - nseel_evallib_stats[0]-=h->code_stats[0]; - nseel_evallib_stats[1]-=h->code_stats[1]; - nseel_evallib_stats[2]-=h->code_stats[2]; - nseel_evallib_stats[3]-=h->code_stats[3]; - nseel_evallib_stats[4]--; - -#ifdef EEL_PPC_NOFREECODE - #pragma warn leaky-code mode, not freeing code, will leak, fixme!!! -#else - freeBlocks(&h->blocks); -#endif - - freeBlocks(&h->blocks_data); - - - } - -} - - -//------------------------------------------------------------------------------ -static void NSEEL_VM_freevars(NSEEL_VMCTX _ctx) -{ - if (_ctx) - { - compileContext *ctx=(compileContext *)_ctx; - - free(ctx->varTable_Values); - free(ctx->varTable_Names); - ctx->varTable_Values=0; - ctx->varTable_Names=0; - - ctx->varTable_numBlocks=0; - } -} - - -NSEEL_VMCTX NSEEL_VM_alloc() // return a handle -{ - compileContext *ctx=calloc(1,sizeof(compileContext)); -#ifndef NSEEL_USE_OLD_PARSER - - #ifdef NSEEL_SUPER_MINIMAL_LEXER - ctx->scanner = ctx; - #else - if (ctx) - { - int nseellex_init(void ** ptr_yy_globals); - void nseelset_extra(void *user_defined , void *yyscanner); - if (nseellex_init(&ctx->scanner)) - { - free(ctx); - return NULL; - } - nseelset_extra(ctx,ctx->scanner); - } - #endif - -#endif - - if (ctx) ctx->ram_state.closefact = NSEEL_CLOSEFACTOR; - return ctx; -} - -void NSEEL_VM_free(NSEEL_VMCTX _ctx) // free when done with a VM and ALL of its code have been freed, as well -{ - - if (_ctx) - { - compileContext *ctx=(compileContext *)_ctx; - NSEEL_VM_freevars(_ctx); - NSEEL_VM_freeRAM(_ctx); - - freeBlocks(&ctx->pblocks); - - // these should be 0 normally but just in case - freeBlocks(&ctx->tmpblocks_head); // free blocks - freeBlocks(&ctx->blocks_head); // free blocks - freeBlocks(&ctx->blocks_head_data); // free blocks - - - free(ctx->compileLineRecs); - -#ifndef NSEEL_USE_OLD_PARSER - #ifndef NSEEL_SUPER_MINIMAL_LEXER - if (ctx->scanner) - { - int nseellex_destroy(void *yyscanner); - nseellex_destroy(ctx->scanner); - } - #endif - ctx->scanner=0; -#endif - free(ctx); - } - -} - -int *NSEEL_code_getstats(NSEEL_CODEHANDLE code) -{ - codeHandleType *h = (codeHandleType *)code; - if (h) - { - return h->code_stats; - } - return 0; -} - -void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr) -{ - if (ctx) - { - compileContext *c=(compileContext*)ctx; - c->caller_this=thisptr; - } -} - - - - - -void *NSEEL_PProc_RAM(void *data, int data_size, compileContext *ctx) -{ - if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->ram_state.blocks); - return data; -} - -void *NSEEL_PProc_THIS(void *data, int data_size, compileContext *ctx) -{ - if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->caller_this); - return data; -} - -void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx) -{ - compileContext *ctx = (compileContext *)_ctx; - int wb; - if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - int ti; - char **plist=ctx->varTable_Names[wb]; - if (!plist) break; - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (plist[ti]) - { - varNameHdr *v = ((varNameHdr*)plist[ti])-1; - if (!v->refcnt && !v->isreg) - { - plist[ti]=NULL; - } - } - } - } -} - -void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx) -{ - compileContext *ctx = (compileContext *)_ctx; - int wb; - if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - int ti; - char **plist=ctx->varTable_Names[wb]; - if (!plist) break; - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (plist[ti]) - { - varNameHdr *v = ((varNameHdr*)plist[ti])-1; - if (!v->isreg) - { - plist[ti]=NULL; - } - } - } - } -} - -void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx) -{ - compileContext *ctx = (compileContext *)_ctx; - int wb; - if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - int ti; - char **plist=ctx->varTable_Names[wb]; - if (!plist) break; - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (plist[ti]) - { - varNameHdr *v = ((varNameHdr*)plist[ti])-1; - v->refcnt=0; - } - } - } -} - -EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg) -{ - int match_wb = -1, match_ti=-1; - int wb; - int ti=0; - for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - char **plist=ctx->varTable_Names[wb]; - if (!plist) return NULL; // error! - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (!plist[ti]) - { - if (match_wb < 0) - { - match_wb=wb; - match_ti=ti; - } - } - else if (!strncasecmp(plist[ti],name,NSEEL_MAX_VARIABLE_NAMELEN)) - { - varNameHdr *v = ((varNameHdr*)plist[ti])-1; - v->refcnt++; - if (isReg) v->isreg=isReg; - break; - } - } - if (ti < NSEEL_VARS_PER_BLOCK) break; - } - - if (wb == ctx->varTable_numBlocks && match_wb >=0 && match_ti >= 0) - { - wb = match_wb; - ti = match_ti; - } - - if (wb == ctx->varTable_numBlocks) - { - ti=0; - // add new block - if (!(ctx->varTable_numBlocks&(NSEEL_VARS_MALLOC_CHUNKSIZE-1)) || !ctx->varTable_Values || !ctx->varTable_Names ) - { - ctx->varTable_Values = (EEL_F **)realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(EEL_F *)); - ctx->varTable_Names = (char ***)realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char **)); - - if (!ctx->varTable_Names || !ctx->varTable_Values) return NULL; - } - ctx->varTable_numBlocks++; - - ctx->varTable_Values[wb] = (EEL_F *)newCtxDataBlock(sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK,8); - ctx->varTable_Names[wb] = (char **)newCtxDataBlock(sizeof(char *)*NSEEL_VARS_PER_BLOCK,1); - if (ctx->varTable_Values[wb]) - { - memset(ctx->varTable_Values[wb],0,sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK); - } - if (ctx->varTable_Names[wb]) - { - memset(ctx->varTable_Names[wb],0,sizeof(char *)*NSEEL_VARS_PER_BLOCK); - } - } - - if (!ctx->varTable_Names[wb] || !ctx->varTable_Values[wb]) return NULL; - - if (!ctx->varTable_Names[wb][ti]) - { - int l = strlen(name); - char *b; - varNameHdr *vh; - if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; - b=newCtxDataBlock( sizeof(varNameHdr) + l+1,1); - if (!b) return NULL; // malloc fail - vh=(varNameHdr *)b; - vh->refcnt=1; - vh->isreg=isReg; - - b+=sizeof(varNameHdr); - - memcpy(b,name,l); - b[l] = 0; - - ctx->varTable_Names[wb][ti] = b; - ctx->varTable_Values[wb][ti]=0.0; - } - return ctx->varTable_Values[wb] + ti; -} - - - -EEL_F nseel_globalregs[100]; - - -//------------------------------------------------------------------------------ - -void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx) -{ - compileContext *tctx = (compileContext *) ctx; - int wb; - if (!tctx) return; - - for (wb = 0; wb < tctx->varTable_numBlocks; wb ++) - { - int ti; - char **plist=tctx->varTable_Names[wb]; - if (!plist) break; - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (plist[ti] && !func(plist[ti],tctx->varTable_Values[wb] + ti,userctx)) break; - } - if (ti < NSEEL_VARS_PER_BLOCK) - break; - } -} - - -//------------------------------------------------------------------------------ -EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, const char *var) -{ - compileContext *ctx = (compileContext *)_ctx; - if (!ctx) return 0; - - if (!strncasecmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4])) - { - int x=atoi(var+3); - if (x < 0 || x > 99) x=0; - return nseel_globalregs + x; - } - - return nseel_int_register_var(ctx,var,1); -} - -int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name) -{ - compileContext *ctx = (compileContext *)_ctx; - int wb; - if (!ctx) return -1; - - for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) - { - int ti; - if (!ctx->varTable_Values[wb] || !ctx->varTable_Names[wb]) break; - - for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) - { - if (ctx->varTable_Names[wb][ti] && !strcasecmp(ctx->varTable_Names[wb][ti],name)) - { - varNameHdr *h = ((varNameHdr *)ctx->varTable_Names[wb][ti])-1; - return h->refcnt; - } - } - } - - return -1; -} - - - -//------------------------------------------------------------------------------ -opcodeRec *nseel_lookup(compileContext *ctx, int *typeOfObject, const char *sname) -{ - char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; - int i; - *typeOfObject = IDENTIFIER; - - lstrcpyn_safe(tmp,sname,sizeof(tmp)); - - if (!strncasecmp(tmp,"reg",3) && strlen(tmp) == 5 && isdigit(tmp[3]) && isdigit(tmp[4]) && (i=atoi(tmp+3))>=0 && i<100) - { - return nseel_createCompiledValuePtr(ctx,nseel_globalregs+i); - } - - // scan for parameters/local variables before user functions - if (strncasecmp(tmp,"this.",5) && - ctx->function_localTable_Size[0] > 0 && - ctx->function_localTable_Names[0] && - ctx->function_localTable_ValuePtrs) - { - char **namelist = ctx->function_localTable_Names[0]; - for (i=0; i < ctx->function_localTable_Size[0]; i++) - { - if (namelist[i] && !strncasecmp(namelist[i],tmp,NSEEL_MAX_VARIABLE_NAMELEN)) - { - return nseel_createCompiledValuePtrPtr(ctx, ctx->function_localTable_ValuePtrs+i); - } - } - } - - // if instance name set, translate tmp or tmp.* into "this.tmp.*" - if (strncasecmp(tmp,"this.",5) && - ctx->function_localTable_Size[1] > 0 && - ctx->function_localTable_Names[1]) - { - char **namelist = ctx->function_localTable_Names[1]; - for (i=0; i < ctx->function_localTable_Size[1]; i++) - { - int tl = namelist[i] ? strlen(namelist[i]) : 0; - - if (tl && !strncasecmp(namelist[i],tmp,tl) && (tmp[tl] == 0 || tmp[tl] == '.')) - { - strcpy(tmp,"this."); - lstrcpyn_safe(tmp + 5, sname, sizeof(tmp) - 5); // update tmp with "this.tokenname" - break; - } - } - } - - - if (strncasecmp(tmp,"this.",5)) - { - const char *nptr = tmp; - -#ifdef NSEEL_EEL1_COMPAT_MODE - if (!strcasecmp(nptr,"if")) nptr="_if"; - else if (!strcasecmp(nptr,"bnot")) nptr="_not"; - else if (!strcasecmp(nptr,"assign")) nptr="_set"; - else if (!strcasecmp(nptr,"equal")) nptr="_equal"; - else if (!strcasecmp(nptr,"below")) nptr="_below"; - else if (!strcasecmp(nptr,"above")) nptr="_above"; - else if (!strcasecmp(nptr,"megabuf")) nptr="_mem"; - else if (!strcasecmp(nptr,"gmegabuf")) nptr="_gmem"; -#endif - - for (i=0;nseel_getFunctionFromTable(i);i++) - { - functionType *f=nseel_getFunctionFromTable(i); - if (!strcasecmp(f->name, nptr)) - { - int np=f->nParams&FUNCTIONTYPE_PARAMETERCOUNTMASK; - switch (np) - { - case 0: - case 1: *typeOfObject = FUNCTION1; break; - case 2: *typeOfObject = FUNCTION2; break; - case 3: *typeOfObject = FUNCTION3; break; - default: -#ifndef NSEEL_USE_OLD_PARSER - *typeOfObject = FUNCTIONX; // newly supported X-parameter functions -#else - *typeOfObject = FUNCTION1; // should never happen, unless the caller was silly -#endif - break; - } - return nseel_createCompiledFunctionCall(ctx,np,FUNCTYPE_FUNCTIONTYPEREC,(void *) f); - } - } - } - - { - _codeHandleFunctionRec *fr = NULL; - - char *postName = tmp; - while (*postName) postName++; - while (postName >= tmp && *postName != '.') postName--; - if (++postName <= tmp) postName=0; - - if (!fr) - { - fr = ctx->functions_local; - while (fr) - { - if (!strcasecmp(fr->fname,postName?postName:tmp)) break; - fr=fr->next; - } - } - if (!fr) - { - fr = ctx->functions_common; - while (fr) - { - if (!strcasecmp(fr->fname,postName?postName:tmp)) break; - fr=fr->next; - } - } - - if (fr) - { - *typeOfObject= -#ifndef NSEEL_USE_OLD_PARSER - fr->num_params>3?FUNCTIONX : -#endif - fr->num_params>=3?FUNCTION3 : fr->num_params==2?FUNCTION2 : FUNCTION1; - - if (!strncasecmp(tmp,"this.",5) && tmp[5]) // relative scoped call - { - // we're calling this. something, defer lookup of derived version to code generation - ctx->function_usesThisPointer = 1; - return nseel_createCompiledFunctionCallEELThis(ctx,fr,tmp+5); - } - - if (postName && fr->usesThisPointer) // if has context and calling an eel function that needs context - { - _codeHandleFunctionRec *scan=fr; - while (scan) - { - if (!strcasecmp(scan->fname,tmp)) break; - scan=scan->derivedCopies; - } - - // if didn't find a cached instance, create our fully qualified function instance - if (!scan) scan = eel_createFunctionNamespacedInstance(ctx,fr,tmp); - - - // use our derived/cached version if we didn't fail - if (scan) fr=scan; - } - - return nseel_createCompiledFunctionCall(ctx,fr->num_params,FUNCTYPE_EELFUNC,(void *)fr); - } - - } - - // instance variables - if (!strncasecmp(tmp,"this.",5) && tmp[5]) - { - ctx->function_usesThisPointer=1; - return nseel_createCompiledValueFromNamespaceName(ctx,tmp+5); - } - - { - EEL_F *p=nseel_int_register_var(ctx,tmp,0); - if (p) return nseel_createCompiledValuePtr(ctx,p); - } - return nseel_createCompiledValue(ctx,0.0); -} - - - - -//------------------------------------------------------------------------------ -opcodeRec *nseel_translate(compileContext *ctx, const char *tmp) -{ - if (tmp[0] == '0' && toupper(tmp[1])=='X') - { - char *p; - return nseel_createCompiledValue(ctx,(EEL_F)strtoul(tmp+2,&p,16)); - } - if (strstr(tmp,".")) return nseel_createCompiledValue(ctx,(EEL_F)atof(tmp)); - return nseel_createCompiledValue(ctx,(EEL_F)atoi(tmp)); // todo: this could be atof() too, eventually, but that might break things -} - diff --git a/WDL/eel2/nseel-eval.c b/WDL/eel2/nseel-eval.c deleted file mode 100644 index d1850e4d..00000000 --- a/WDL/eel2/nseel-eval.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) v2 - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - nseel-eval.c - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include -#include -#include "ns-eel-int.h" -#include "../wdlcstring.h" - -#ifndef NSEEL_USE_OLD_PARSER - - #ifdef NSEEL_SUPER_MINIMAL_LEXER - - int nseellex(opcodeRec **output, YYLTYPE * yylloc_param, compileContext *scctx) - { - int rv,toklen=0; - *output = 0; - while ((rv=scctx->rdbuf[0]) && (rv== ' ' || rv=='\t' || rv == '\r' || rv == '\n')) scctx->rdbuf++; - - if (rv) - { - char buf[NSEEL_MAX_VARIABLE_NAMELEN*2]; - int l; - char *ss = scctx->rdbuf++; - if (isalpha(rv) || rv == '_') - { - while ((rv=scctx->rdbuf[0]) && (isalnum(rv) || rv == '_' || rv == '.')) scctx->rdbuf++; - l = scctx->rdbuf - ss + 1; - if (l > sizeof(buf)) l=sizeof(buf); - lstrcpyn_safe(buf,ss,l); - - rv=0; - *output = nseel_lookup(scctx,&rv,buf); - } - else if ((rv >= '0' && rv <= '9') || (rv == '.' && (scctx->rdbuf[0] >= '0' && scctx->rdbuf[0] <= '9'))) - { - if (rv == '0' && (scctx->rdbuf[0] == 'x' || scctx->rdbuf[0] == 'X')) - { - scctx->rdbuf++; - while ((rv=scctx->rdbuf[0]) && ((rv>='0' && rv<='9') || (rv>='a' && rv<='f') || (rv>='A' && rv<='F'))) scctx->rdbuf++; - // this allows 0x, whereas the lex version will not parse that as a token - } - else - { - int pcnt=rv == '.'; - while ((rv=scctx->rdbuf[0]) && ((rv>='0' && rv<='9') || (rv == '.' && !pcnt++))) scctx->rdbuf++; - } - l = scctx->rdbuf - ss + 1; - if (l > sizeof(buf)) l=sizeof(buf); - lstrcpyn_safe(buf,ss,l); - *output = nseel_translate(scctx,buf); - rv=VALUE; - } - toklen = scctx->rdbuf - ss; - } - - yylloc_param->first_column = scctx->rdbuf - scctx->rdbuf_start - toklen; - return rv; - } - void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) - { - ctx->errVar=pos->first_column>0?pos->first_column:1; - } -#else - - int nseel_gets(compileContext *ctx, char *buf, size_t sz) - { - int n=0; - if (ctx->inputbufferptr) while (n < sz) - { - char c=ctx->inputbufferptr[0]; - if (!c) break; - if (c == '/' && ctx->inputbufferptr[1] == '*') - { - ctx->inputbufferptr+=2; // skip /* - - while (ctx->inputbufferptr[0] && (ctx->inputbufferptr[0] != '*' || ctx->inputbufferptr[1] != '/')) ctx->inputbufferptr++; - if (ctx->inputbufferptr[0]) ctx->inputbufferptr+=2; // skip */ - continue; - } - - ctx->inputbufferptr++; - buf[n++] = c; - } - return n; - - } - - - //#define EEL_TRACE_LEX - - #ifdef EEL_TRACE_LEX - #define nseellex nseellex2 - - #endif - #include "lex.nseel.c" - - #ifdef EEL_TRACE_LEX - - #undef nseellex - - int nseellex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) - { - int a=nseellex2(yylval_param,yylloc_param,yyscanner); - - char buf[512]; - sprintf(buf,"tok: %c (%d)\n",a,a); - OutputDebugString(buf); - return a; - } - #endif//EEL_TRACE_LEX - - - void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) - { - ctx->errVar=pos->first_column>0?pos->first_column:1; - ctx->errVar_l = pos->first_line; - } -#endif // !NSEEL_SUPER_MINIMAL_LEXER - -#else - -//--------------------------------------------------------------------------- -int nseel_yyerror(compileContext *ctx) -{ - ctx->errVar = ctx->colCount; - return 0; -} - - -#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-lextab.c b/WDL/eel2/nseel-lextab.c deleted file mode 100644 index 76dacedf..00000000 --- a/WDL/eel2/nseel-lextab.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) v2 - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - nseel-lextab.c - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "ns-eel-int.h" - -#ifdef NSEEL_USE_OLD_PARSER - -#define LEXSKIP (-1) - -static int _lmovb(struct lextab *lp, int c, int st) -{ - int base; - if (c == '.' && st >= 15 && st < 30) c='_'; // if in a token, treat . as _ (should probably modify llnext instead) - - while ((base = lp->llbase[st]+c) > lp->llnxtmax || - (lp->llcheck[base] & 0377) != st) { - - if (st != lp->llendst) { - base = lp->lldefault[st] & 0377; - st = base; - } - else - return(-1); - } - return(lp->llnext[base]&0377); -} - -static int _Alextab(compileContext *ctx, int __na__) -{ - // fucko: JF> 17 -> 19? - - if (__na__ >= 0 && __na__ <= 17) - { - ctx->colCount+=nseel_gettokenlen(ctx,256); - } - switch (__na__) - { - case 0: - { - char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; - nseel_gettoken(ctx,tmp, sizeof(tmp)); - if (tmp[0] < '0' || tmp[0] > '9') // not sure where this logic came from - { - ctx->yylval = nseel_lookup(ctx,&__na__,tmp); - return __na__; - } - } - case 1: - case 2: - case 3: - { - char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; - nseel_gettoken(ctx,tmp, sizeof(tmp)); - ctx->yylval = nseel_translate(ctx,tmp); - return VALUE; - } - case 4: - case 5: - { - char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; - nseel_gettoken(ctx,tmp, sizeof(tmp)); - ctx->yylval = nseel_lookup(ctx,&__na__,tmp); - return __na__; - } - case 6: return '+'; - case 7: return '-'; - case 8: return '*'; - case 9: return '/'; - case 10: return '%'; - case 11: return '&'; - case 12: return '|'; - case 13: return '('; - case 14: return ')'; - case 15: return '='; - case 16: return ','; - case 17: return ';'; - } - return (LEXSKIP); -} - - -static char _Flextab[] = - { - 1, 18, 17, 16, 15, 14, 13, 12, - 11, 10, 9, 8, 7, 6, 4, 5, - 5, 4, 4, 3, 3, 3, 3, 4, - 0, 4, 5, 0, 5, 4, 1, 3, - 0, 2, -1, 1, -1, - }; - - -static char _Nlextab[] = - { - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 1, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 1, 36, 36, 36, 36, 9, 8, 36, - 6, 5, 11, 13, 3, 12, 19, 10, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 36, 2, 36, 4, 36, 36, - 36, 29, 29, 29, 29, 29, 29, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 36, 36, 36, 36, 18, - 36, 29, 29, 29, 29, 29, 23, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 14, 18, - 18, 18, 18, 36, 7, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 36, - 36, 36, 36, 36, 36, 36, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 36, 36, 36, 36, 17, 36, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 36, 36, 36, 36, 36, 36, - 36, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 36, 36, 36, 36, 16, - 36, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 20, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 36, 36, 36, 36, 36, - 36, 36, 25, 25, 25, 25, 25, 25, - 36, 24, 36, 36, 36, 36, 36, 36, - 20, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 25, 25, 25, 25, 25, 25, - 36, 24, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 36, 36, 36, 36, - 36, 36, 36, 28, 28, 28, 28, 28, - 28, 36, 27, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 28, 28, 28, 28, 28, - 28, 31, 27, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 36, 36, 36, - 36, 36, 36, 36, 34, 34, 34, 33, - 34, 34, 36, 32, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 34, 34, 34, 33, - 34, 34, 36, 32, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 36, 36, - 36, 36, 36, 36, 36, 34, 34, 34, - 34, 34, 34, 36, 32, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 34, 34, 34, - 34, 34, 34, 36, 32, - }; - -static char _Clextab[] = - { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 0, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - 0, -1, -1, -1, -1, 0, 0, -1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -1, 0, -1, 0, -1, -1, - -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, -1, -1, -1, -1, 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, -1, 0, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, -1, - -1, -1, -1, -1, -1, -1, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - -1, -1, -1, -1, 14, -1, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, -1, -1, -1, -1, -1, -1, - -1, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, -1, -1, -1, -1, 15, - -1, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, -1, - 19, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, -1, -1, -1, -1, -1, - -1, -1, 23, 23, 23, 23, 23, 23, - -1, 23, -1, -1, -1, -1, -1, -1, - 19, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 23, 23, 23, 23, 23, 23, - -1, 23, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, -1, -1, -1, -1, - -1, -1, -1, 26, 26, 26, 26, 26, - 26, -1, 26, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 26, 26, 26, 26, 26, - 26, 30, 26, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, -1, -1, -1, - -1, -1, -1, -1, 30, 30, 30, 30, - 30, 30, -1, 30, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 30, 30, 30, 30, - 30, 30, -1, 30, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, -1, -1, - -1, -1, -1, -1, -1, 33, 33, 33, - 33, 33, 33, -1, 33, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 33, 33, 33, - 33, 33, 33, -1, 33, - }; - -static char _Dlextab[] = - { - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 15, 14, 14, 36, 36, 20, 19, 14, - 14, 23, 15, 15, 26, 23, 36, 19, - 36, 36, 33, 30, - }; - -static int _Blextab[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 77, 152, - 0, 0, 0, 227, 237, 0, 0, 249, - 0, 0, 306, 0, 0, 0, 363, 0, - 0, 420, 0, 0, 0, - }; - -struct lextab nseel_lextab = { - 36, - _Dlextab, - _Nlextab, - _Clextab, - _Blextab, - 524, - _lmovb, - _Flextab, - _Alextab, - - 0, - 0, - 0, - 0, - }; - - - -#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-ram.c b/WDL/eel2/nseel-ram.c deleted file mode 100644 index ff539b70..00000000 --- a/WDL/eel2/nseel-ram.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) v2 - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "ns-eel.h" -#include "ns-eel-int.h" -#include -#include -#include -#include - - -#ifdef _WIN32 -#include -#endif - -unsigned int NSEEL_RAM_limitmem=0; -unsigned int NSEEL_RAM_memused=0; -int NSEEL_RAM_memused_errors=0; - - - -int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx) -{ - if (ctx) - { - compileContext *c=(compileContext*)ctx; - if (c->ram_state.needfree) - return 1; - } - return 0; -} - -void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX ctx) // check to see if our free flag was set -{ - if (ctx) - { - compileContext *c=(compileContext*)ctx; - if (c->ram_state.needfree) - { - NSEEL_HOSTSTUB_EnterMutex(); - { - INT_PTR startpos=((INT_PTR)c->ram_state.needfree)-1; - EEL_F **blocks = c->ram_state.blocks; - INT_PTR pos=0; - int x; - for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) - { - if (pos >= startpos) - { - if (blocks[x]) - { - if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) - NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; - else NSEEL_RAM_memused_errors++; - free(blocks[x]); - blocks[x]=0; - } - } - pos+=NSEEL_RAM_ITEMSPERBLOCK; - } - c->ram_state.needfree=0; - } - NSEEL_HOSTSTUB_LeaveMutex(); - } - - } -} - - - - - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w) -{ - static EEL_F * volatile gmembuf; - static EEL_F fail; - if (blocks) - { - EEL_F **pblocks=*blocks; - - int is_locked=0; - - if (!pblocks) - { - if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); } - - if (!(pblocks=*blocks)) - { - pblocks = *blocks = (EEL_F **)calloc(sizeof(EEL_F *),NSEEL_RAM_BLOCKS); - if (!pblocks) { - if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); - return &fail; - } - } - } - - if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) - { - unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; - EEL_F *p=pblocks[whichblock]; - if (!p) - { - if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); } - - if (!(p=pblocks[whichblock])) - { - const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; - if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) - { - p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); - if (p) NSEEL_RAM_memused+=msize; - } - } - } - if (p) - { - if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); - return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); - } - } - if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); - return &fail; - } - - if (!gmembuf) - { - NSEEL_HOSTSTUB_EnterMutex(); - if (!gmembuf) gmembuf=(EEL_F*)calloc(sizeof(EEL_F),NSEEL_SHARED_GRAM_SIZE); - NSEEL_HOSTSTUB_LeaveMutex(); - if (!gmembuf) return &fail; - } - - return gmembuf+(((unsigned int)w)&((NSEEL_SHARED_GRAM_SIZE)-1)); -} - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **pblocks, unsigned int w) -{ - static EEL_F fail; - -// fprintf(stderr,"got request at %d, %d\n",w/NSEEL_RAM_ITEMSPERBLOCK, w&(NSEEL_RAM_ITEMSPERBLOCK-1)); - if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) - { - unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; - EEL_F *p=pblocks[whichblock]; - if (!p) - { - NSEEL_HOSTSTUB_EnterMutex(); - - if (!(p=pblocks[whichblock])) - { - - const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; - if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) - { - p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); - if (p) NSEEL_RAM_memused+=msize; - } - } - NSEEL_HOSTSTUB_LeaveMutex(); - } - if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); - } -// fprintf(stderr,"ret 0\n"); - return &fail; -} - - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which) -{ - // blocks points to ram_state.blocks, so back it up past closefact and pad to needfree - int *flag = (int *)((char *)blocks - sizeof(double) - 2*sizeof(int)); - int d=(int)(*which); - if (d < 0) d=0; - if (d < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) flag[0]=1+d; - return which; -} - - - - - - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr) -{ - int dest_offs = (int)(*dest + 0.0001); - int src_offs = (int)(*src + 0.0001); - int len = (int)(*lenptr + 0.0001); - - // trim to front - if (src_offs<0) - { - len += src_offs; - dest_offs -= src_offs; - src_offs=0; - } - if (dest_offs<0) - { - len += dest_offs; - src_offs -= dest_offs; - dest_offs=0; - } - - while (len > 0) - { - EEL_F *srcptr,*destptr; - int copy_len = len; - int maxdlen=NSEEL_RAM_ITEMSPERBLOCK - (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); - int maxslen=NSEEL_RAM_ITEMSPERBLOCK - (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); - - if (dest_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK || - src_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) break; - - if (copy_len > maxdlen) copy_len=maxdlen; - if (copy_len > maxslen) copy_len=maxslen; - - if (copy_len<1) break; - - srcptr = __NSEEL_RAMAlloc(blocks,src_offs); - destptr = __NSEEL_RAMAlloc(blocks,dest_offs); - if (!srcptr || !destptr) break; - - memmove(destptr,srcptr,sizeof(EEL_F)*copy_len); - src_offs+=copy_len; - dest_offs+=copy_len; - len-=copy_len; - } - return dest; -} - -EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr) -{ - int offs = (int)(*dest + 0.0001); - int len = (int)(*lenptr + 0.0001); - EEL_F t; - if (offs<0) - { - len += offs; - offs=0; - } - if (offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest; - - if (offs+len > NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) len = NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - offs; - - if (len < 1) return dest; - - - t=*v; // set value - -// int lastBlock=-1; - while (len > 0) - { - int lcnt; - EEL_F *ptr=__NSEEL_RAMAlloc(blocks,offs); - if (!ptr) break; - - lcnt=NSEEL_RAM_ITEMSPERBLOCK-(offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); - if (lcnt > len) lcnt=len; - - len -= lcnt; - offs += lcnt; - - while (lcnt--) - { - *ptr++=t; - } - } - return dest; -} - - -void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram) -{ - if (ctx) - { - compileContext *c=(compileContext*)ctx; - c->gram_blocks = gram; - } -} - - -void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx) -{ - if (ctx) - { - int x; - compileContext *c=(compileContext*)ctx; - EEL_F **blocks = c->ram_state.blocks; - for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) - { - if (blocks[x]) - { - if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) - NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; - else NSEEL_RAM_memused_errors++; - free(blocks[x]); - blocks[x]=0; - } - } - c->ram_state.needfree=0; // no need to free anymore - } -} - -void NSEEL_VM_FreeGRAM(void **ufd) -{ - if (ufd[0]) - { - EEL_F **blocks = (EEL_F **)ufd[0]; - int x; - for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) - { - if (blocks[x]) - { - if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) - NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; - else NSEEL_RAM_memused_errors++; - } - free(blocks[x]); - blocks[x]=0; - } - free(blocks); - ufd[0]=0; - } -} diff --git a/WDL/eel2/nseel-yylex.c b/WDL/eel2/nseel-yylex.c deleted file mode 100644 index e48b833d..00000000 --- a/WDL/eel2/nseel-yylex.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - Expression Evaluator Library (NS-EEL) - Copyright (C) 2004-2013 Cockos Incorporated - Copyright (C) 1999-2003 Nullsoft, Inc. - - nseel-yylex.c - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - - -#include "ns-eel-int.h" - - -#ifndef NSEEL_USE_OLD_PARSER - -# define YYMALLOC malloc -# define YYFREE free - -int nseellex(void * yylval_param,void * yylloc_param ,void *yyscanner); -void nseelerror(void *pos,compileContext *ctx, const char *str); - -#include -#include - -#include "y.tab.c" - -#else - -#define NBPW 16 -#define EOF (-1) - - -#define YYERRORVAL 256 /* yacc's value */ - -static int llset(compileContext *ctx); -static int llinp(compileContext *ctx, char **exp); -static int lexgetc(char **exp) -{ - char c= **exp; - if (c) (*exp)++; - return( c != 0 ? c : -1); -} -static int tst__b(register int c, char tab[]) -{ - return (tab[(c >> 3) & 037] & (1 << (c & 07)) ); -} - - -int nseel_gettokenlen(compileContext *ctx, int lltbsiz) -{ - char *lp; - int tp=0; - for (lp = ctx->llbuf; lp < ctx->llend && tp < lltbsiz; tp++, lp++); - return tp; - -} - -int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz) -{ - char *lp, *tp, *ep; - - tp = lltb; - ep = tp+lltbsiz-1; - for (lp = ctx->llbuf; lp < ctx->llend && tp < ep;) *tp++ = *lp++; - *tp = 0; - return(tp-lltb); -} - - -int nseel_yylex(compileContext *ctx, char **exp) -{ - register int c, st; - int final, l, llk, i; - register struct lextab *lp; - char *cp; - - while (1) - { - llk = 0; - if (llset(ctx)) return(0); - st = 0; - final = -1; - lp = &nseel_lextab; - - do { - if (lp->lllook && (l = lp->lllook[st])) { - for (c=0; cllsave[c] = ctx->llp1; - llk++; - } - if ((i = lp->llfinal[st]) != -1) { - final = i; - ctx->llend = ctx->llp1; - } - if ((c = llinp(ctx,exp)) < 0) - break; - if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) { - ctx->llp1--; - break; - } - } while ((st = (*lp->llmove)(lp, c, st)) != -1); - - - if (ctx->llp2 < ctx->llp1) - ctx->llp2 = ctx->llp1; - if (final == -1) { - ctx->llend = ctx->llp1; - if (st == 0 && c < 0) - return(0); - if ((cp = lp->llill) && tst__b(c, cp)) { - continue; - } - return(YYERRORVAL); - } - if ((c = (final >> 11) & 037)) - ctx->llend = ctx->llsave[c-1]; - if ((c = (*lp->llactr)(ctx,final&03777)) >= 0) - return(c); - } -} - -void nseel_llinit(compileContext *ctx) -{ - ctx->llp1 = ctx->llp2 = ctx->llend = ctx->llbuf; - ctx->llebuf = ctx->llbuf + sizeof(ctx->llbuf); - ctx->lleof = 0; -} - - -static int llinp(compileContext *ctx, char **exp) -{ - register int c; - register struct lextab *lp; - register char *cp; - - lp = &nseel_lextab; - cp = lp->llign; /* Ignore class */ - for (;;) { - /* - * Get the next character from the save buffer (if possible) - * If the save buffer's empty, then return EOF or the next - * input character. Ignore the character if it's in the - * ignore class. - */ - c = (ctx->llp1 < ctx->llp2) ? *ctx->llp1 & 0377 : (ctx->lleof) ? EOF : lexgetc(exp); - if (c >= 0) { /* Got a character? */ - if (cp && tst__b(c, cp)) - continue; /* Ignore it */ - if (ctx->llp1 >= ctx->llebuf) { /* No, is there room? */ - return -1; - } - *ctx->llp1++ = c; /* Store in token buff */ - } else - ctx->lleof = 1; /* Set EOF signal */ - return(c); - } -} - -static int llset(compileContext *ctx) -/* - * Return TRUE if EOF and nothing was moved in the look-ahead buffer - */ -{ - register char *lp1, *lp2; - - for (lp1 = ctx->llbuf, lp2 = ctx->llend; lp2 < ctx->llp2;) - *lp1++ = *lp2++; - ctx->llend = ctx->llp1 = ctx->llbuf; - ctx->llp2 = lp1; - return(ctx->lleof && lp1 == ctx->llbuf); -} - -#endif \ No newline at end of file diff --git a/WDL/eel2/preproc_test.cpp b/WDL/eel2/preproc_test.cpp deleted file mode 100644 index 65680b9f..00000000 --- a/WDL/eel2/preproc_test.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include "../wdltypes.h" -#include "../wdlstring.h" - -#ifdef _WIN32 -#define strcasecmp stricmp -#define strncasecmp strnicmp -#endif - -typedef struct compileContext { - int l_stats[4]; -} compileContext; -#define onCompileNewLine(a,b,c) {} -#include "tmp.c" - -int ppOut(char *input) -{ - if (input[0]) - { - compileContext ctx = { 0,}; - char *exp=preprocessCode(&ctx,input); - if (!exp) - { - return -1; - } - int cc=0; - while (*exp) - { - if (*exp != ' ' && *exp != '\t' && *exp != '\r' && *exp != '\n') { - - printf("%c",*exp); - if (cc++ >= 60) { cc=0; printf("\n"); } - } - exp++; - } - printf("\n"); - } - return 0; -} -int main(int argc, char **argv) -{ - if (argc != 2) { fprintf(stderr,"usage: preproc_test filename\n"); return 0; } - FILE *fp =fopen(argv[1],"rb"); - if (!fp) { fprintf(stderr,"error opening '%s'\n",argv[1]); return 1; } - - int insec=0; - WDL_FastString cursec; - for (;;) - { - char buf[4096]; - buf[0]=0; - fgets(buf,sizeof(buf),fp); - if (!buf[0]) break; - char *p=buf; - while (*p == ' ' || *p == '\t') p++; - if (p[0] == '@') - { - insec=1; - if (ppOut((char*)cursec.Get())) { fprintf(stderr,"Error preprocessing %s!\n",argv[1]); return -1; } - cursec.Set(""); - } - else if (insec) - { - cursec.Append(buf); - continue; - } - printf("%s",buf); - } - if (ppOut((char*)cursec.Get())) { fprintf(stderr,"Error preprocessing %s!\n",argv[1]); return -1; } - - fclose(fp); - return 0; -} diff --git a/WDL/eel2/test.cpp b/WDL/eel2/test.cpp deleted file mode 100644 index 3c345aef..00000000 --- a/WDL/eel2/test.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "ns-eel.h" -#include - -void NSEEL_HOSTSTUB_EnterMutex() -{ -} -void NSEEL_HOSTSTUB_LeaveMutex() -{ -} - -int main() -{ - printf("init\n"); - if (NSEEL_init()) - { - printf("Error initializing EEL\n"); - return -1; - } - - printf("alloc\n"); - NSEEL_VMCTX vm = NSEEL_VM_alloc(); - if (!vm) - { - printf("Error creating VM\n"); - return -1; - } - - printf("reg\n"); - double *var_ret = NSEEL_VM_regvar(vm,"ret"); - - if (var_ret) *var_ret=1.0; - - printf("compile\n"); - char buf[1024]; - gets(buf); - - - // note that you shouldnt pass a readonly string directly, since it may need to - // fudge with the string during the compilation (it will always restore it to the - // original value though). - NSEEL_CODEHANDLE ch = NSEEL_code_compile(vm,buf,0); - - if (ch) - { - int n; - for (n = 0; n < 10; n ++) - { - NSEEL_code_execute(ch); - printf("pass(%d), ret=%f\n",n+1,var_ret ? *var_ret : 0.0); - } - - NSEEL_code_free(ch); - } - else - { - char *err = NSEEL_code_getcodeerror(vm); - - printf("Error compiling code at '%s'\n",err?err:"????"); - } - - NSEEL_VM_free(vm); - - - return 0; -} \ No newline at end of file diff --git a/WDL/eel2/test_vc6.dsp b/WDL/eel2/test_vc6.dsp deleted file mode 100644 index 476cd67b..00000000 --- a/WDL/eel2/test_vc6.dsp +++ /dev/null @@ -1,144 +0,0 @@ -# Microsoft Developer Studio Project File - Name="test_vc6" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=test_vc6 - 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 "test_vc6.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 "test_vc6.mak" CFG="test_vc6 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "test_vc6 - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "test_vc6 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "test_vc6 - 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 "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "test_vc6 - 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 "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "test_vc6 - Win32 Release" -# Name "test_vc6 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "eel2" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\ns-eel-addfuncs.h" -# End Source File -# Begin Source File - -SOURCE=".\ns-eel-int.h" -# End Source File -# Begin Source File - -SOURCE=".\ns-eel.h" -# End Source File -# Begin Source File - -SOURCE=".\nseel-caltab.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-cfunc.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-compiler.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-eval.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-lextab.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-ram.c" -# End Source File -# Begin Source File - -SOURCE=".\nseel-yylex.c" -# End Source File -# End Group -# Begin Source File - -SOURCE=.\test.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/WDL/eel2/test_vc6.dsw b/WDL/eel2/test_vc6.dsw deleted file mode 100644 index d96be066..00000000 --- a/WDL/eel2/test_vc6.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "test_vc6"=.\test_vc6.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/WDL/eel2/y.tab.c b/WDL/eel2/y.tab.c deleted file mode 100644 index 61943771..00000000 --- a/WDL/eel2/y.tab.c +++ /dev/null @@ -1,1819 +0,0 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - -/* Substitute the variable and function names. */ -#define yyparse nseelparse -#define yylex nseellex -#define yyerror nseelerror -#define yylval nseellval -#define yychar nseelchar -#define yydebug nseeldebug -#define yynerrs nseelnerrs -#define yylloc nseellloc - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 13 "eel2.y" - -#ifdef _WIN32 -#include -#endif -#include -#include -#include -#include - -#include "y.tab.h" -#include "ns-eel-int.h" - -#define scanner context->scanner -#define YY_(x) ("") - - - -/* Line 189 of yacc.c */ -#line 99 "y.tab.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - VALUE = 258, - IDENTIFIER = 259, - FUNCTION1 = 260, - FUNCTION2 = 261, - FUNCTION3 = 262, - FUNCTIONX = 263 - }; -#endif -/* Tokens. */ -#define VALUE 258 -#define IDENTIFIER 259 -#define FUNCTION1 260 -#define FUNCTION2 261 -#define FUNCTION3 262 -#define FUNCTIONX 263 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 170 "y.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 33 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 66 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 19 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 27 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 63 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 263 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 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, 18, 16, 2, - 10, 11, 15, 12, 9, 13, 2, 14, 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, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 17, 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, 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, 1, 2, 3, 4, - 5, 6, 7, 8 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 9, 11, 13, 17, 22, 29, - 38, 47, 49, 52, 55, 57, 61, 63, 67, 69, - 73, 75, 79, 81, 85, 89, 91, 95 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 29, 0, -1, 28, -1, 28, 9, 20, -1, 3, - -1, 4, -1, 10, 28, 11, -1, 5, 10, 28, - 11, -1, 6, 10, 28, 9, 28, 11, -1, 7, - 10, 28, 9, 28, 9, 28, 11, -1, 8, 10, - 28, 9, 28, 9, 20, 11, -1, 21, -1, 12, - 22, -1, 13, 22, -1, 22, -1, 23, 14, 22, - -1, 23, -1, 24, 15, 23, -1, 24, -1, 25, - 13, 24, -1, 25, -1, 26, 12, 25, -1, 26, - -1, 27, 16, 26, -1, 27, 17, 26, -1, 27, - -1, 28, 18, 27, -1, 28, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 38, 38, 39, 46, 47, 48, 52, 56, 60, - 64, 71, 72, 76, 84, 85, 93, 94, 102, 103, - 110, 111, 118, 119, 123, 130, 131, 139 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "VALUE", "IDENTIFIER", "FUNCTION1", - "FUNCTION2", "FUNCTION3", "FUNCTIONX", "','", "'('", "')'", "'+'", "'-'", - "'/'", "'*'", "'&'", "'|'", "'%'", "$accept", "more_params", - "value_thing", "unary_expr", "div_expr", "mul_expr", "sub_expr", - "add_expr", "andor_expr", "expression", "program", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 44, - 40, 41, 43, 45, 47, 42, 38, 124, 37 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 19, 20, 20, 21, 21, 21, 21, 21, 21, - 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, - 26, 26, 27, 27, 27, 28, 28, 29 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 3, 1, 1, 3, 4, 6, 8, - 8, 1, 2, 2, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 3, 1, 3, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, - 11, 14, 16, 18, 20, 22, 25, 27, 0, 0, - 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 6, 15, - 17, 19, 21, 23, 24, 26, 7, 0, 0, 0, - 0, 0, 0, 8, 0, 0, 0, 0, 2, 9, - 10, 0, 3 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 57, 10, 11, 12, 13, 14, 15, 16, 58, - 18 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -28 -static const yytype_int8 yypact[] = -{ - 5, -28, -28, 4, 30, 35, 36, 5, 5, 5, - -28, -28, 16, 27, 39, 41, -15, 13, 55, 5, - 5, 5, 5, 21, -28, -28, 5, 5, 5, 5, - 5, 5, 5, -28, 23, 7, 15, 17, -28, -28, - 16, 27, 39, 41, 41, -15, -28, 5, 5, 5, - 32, 18, 19, -28, 5, 5, 33, 45, 20, -28, - -28, 5, -28 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -28, -4, -28, -3, 31, 34, 37, -27, 28, 0, - -28 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 17, 30, 31, 43, 44, 24, 25, 23, 1, 2, - 3, 4, 5, 6, 19, 7, 47, 8, 9, 34, - 35, 36, 37, 39, 48, 32, 49, 54, 55, 61, - 26, 32, 38, 32, 46, 32, 32, 32, 32, 32, - 20, 32, 27, 53, 59, 21, 22, 50, 51, 52, - 32, 32, 28, 29, 56, 33, 60, 62, 40, 0, - 45, 0, 41, 0, 0, 0, 42 -}; - -static const yytype_int8 yycheck[] = -{ - 0, 16, 17, 30, 31, 8, 9, 7, 3, 4, - 5, 6, 7, 8, 10, 10, 9, 12, 13, 19, - 20, 21, 22, 26, 9, 18, 9, 9, 9, 9, - 14, 18, 11, 18, 11, 18, 18, 18, 18, 18, - 10, 18, 15, 11, 11, 10, 10, 47, 48, 49, - 18, 18, 13, 12, 54, 0, 11, 61, 27, -1, - 32, -1, 28, -1, -1, -1, 29 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 4, 5, 6, 7, 8, 10, 12, 13, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, - 10, 10, 10, 28, 22, 22, 14, 15, 13, 12, - 16, 17, 18, 0, 28, 28, 28, 28, 11, 22, - 23, 24, 25, 26, 26, 27, 11, 9, 9, 9, - 28, 28, 28, 11, 9, 9, 28, 20, 28, 11, - 11, 9, 20 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, scanner) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, context); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - compileContext* context; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (context); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - compileContext* context; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, compileContext* context) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, context) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - compileContext* context; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , context); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, context); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, compileContext* context) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - compileContext* context; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (context); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 3: /* "VALUE" */ - -/* Line 1000 of yacc.c */ -#line 8 "eel2.y" - { - #define yydestruct(a,b,c,d,e) 0 -}; - -/* Line 1000 of yacc.c */ -#line 1123 "y.tab.c" - break; - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (compileContext* context); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (compileContext* context) -#else -int -yyparse (context) - compileContext* context; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: - -/* Line 1455 of yacc.c */ -#line 40 "eel2.y" - { - (yyval) = nseel_createMoreParametersOpcode(context,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 6: - -/* Line 1455 of yacc.c */ -#line 49 "eel2.y" - { - (yyval) = (yyvsp[(2) - (3)]); - } - break; - - case 7: - -/* Line 1455 of yacc.c */ -#line 53 "eel2.y" - { - (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), 0, 0); - } - break; - - case 8: - -/* Line 1455 of yacc.c */ -#line 57 "eel2.y" - { - (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(5) - (6)]), 0); - } - break; - - case 9: - -/* Line 1455 of yacc.c */ -#line 61 "eel2.y" - { - (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (8)]), (yyvsp[(3) - (8)]), (yyvsp[(5) - (8)]), (yyvsp[(7) - (8)])); - } - break; - - case 10: - -/* Line 1455 of yacc.c */ -#line 65 "eel2.y" - { - (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (8)]), (yyvsp[(3) - (8)]), (yyvsp[(5) - (8)]), (yyvsp[(7) - (8)])); - } - break; - - case 12: - -/* Line 1455 of yacc.c */ -#line 73 "eel2.y" - { - (yyval) = (yyvsp[(2) - (2)]); - } - break; - - case 13: - -/* Line 1455 of yacc.c */ -#line 77 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,(yyvsp[(2) - (2)]),0); - } - break; - - case 15: - -/* Line 1455 of yacc.c */ -#line 86 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 17: - -/* Line 1455 of yacc.c */ -#line 95 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 19: - -/* Line 1455 of yacc.c */ -#line 104 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_SUB,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 21: - -/* Line 1455 of yacc.c */ -#line 112 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_ADD,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 23: - -/* Line 1455 of yacc.c */ -#line 120 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_AND,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 24: - -/* Line 1455 of yacc.c */ -#line 124 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_OR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 26: - -/* Line 1455 of yacc.c */ -#line 132 "eel2.y" - { - (yyval) = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); - } - break; - - case 27: - -/* Line 1455 of yacc.c */ -#line 140 "eel2.y" - { - int a = (yylsp[(1) - (1)]).first_line; - context->result = (yyvsp[(1) - (1)]); - } - break; - - - -/* Line 1455 of yacc.c */ -#line 1599 "y.tab.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, context, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, context, yymsg); - } - else - { - yyerror (&yylloc, context, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[0] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, context); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[0] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[0] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, context); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, context, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, context); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, context); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 1675 of yacc.c */ -#line 147 "eel2.y" - - diff --git a/WDL/eel2/y.tab.h b/WDL/eel2/y.tab.h deleted file mode 100644 index 2c4942bb..00000000 --- a/WDL/eel2/y.tab.h +++ /dev/null @@ -1,84 +0,0 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - VALUE = 258, - IDENTIFIER = 259, - FUNCTION1 = 260, - FUNCTION2 = 261, - FUNCTION3 = 262, - FUNCTIONX = 263 - }; -#endif -/* Tokens. */ -#define VALUE 258 -#define IDENTIFIER 259 -#define FUNCTION1 260 -#define FUNCTION2 261 -#define FUNCTION3 262 -#define FUNCTIONX 263 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - diff --git a/WDL/fastqueue.h b/WDL/fastqueue.h deleted file mode 100644 index 7663322d..00000000 --- a/WDL/fastqueue.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - WDL - fastqueue.h - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file defines and implements a class which can queue arbitrary amounts of data. - It is optimized for lots of reads and writes with a significant queue (i.e. it doesnt - have to shuffle much memory around). - - The downside is that you can't just ask for a pointer to specific bytes, it may have to peice - it together into a buffer of your choosing (or you can step through the buffers using GetPtr()). - - -*/ - -#ifndef _WDL_FASTQUEUE_H_ -#define _WDL_FASTQUEUE_H_ - - -#include "ptrlist.h" - -class WDL_FastQueue -{ -public: - WDL_FastQueue() - { - m_avail=0; - m_bsize=65536-64; - m_offs=0; - } - ~WDL_FastQueue() - { - m_queue.Empty(true); - m_empties.Empty(true); - } - - void Add(const void *buf, int len) // buf can be NULL to add zeroes - { - char *inptr=(char *)buf; - while (len>0) - { - WDL_HeapBuf *qb=m_queue.Get(m_queue.GetSize()-1); - int os; - if (!qb || (os=qb->GetSize()) >= m_bsize) - { - int esz=m_empties.GetSize()-1; - - qb=m_empties.Get(esz); - if (qb) m_empties.Delete(esz); - else qb=new WDL_HeapBuf(4096 WDL_HEAPBUF_TRACEPARM("WDL_FastQueue")); - - if (qb) m_queue.Add(qb); - os=0; - } - - if (!qb) break; - - int addl=m_bsize-os; - if (addl>len) addl=len; - char *b=(char *)qb->Resize(os+addl,false)+os; - if (inptr) - { - memcpy(b,inptr,addl); - inptr+=addl; - } - else memset(b,0,addl); - len -= addl; - m_avail+=addl; - } - } - - void Clear() - { - int x=m_queue.GetSize(); - while (x > 0) - { - m_empties.Add(m_queue.Get(--x)); - m_queue.Delete(x); - } - m_offs=0; - m_avail=0; - } - - void Advance(int cnt) - { - m_offs += cnt; - m_avail -= cnt; - if (m_avail<0)m_avail=0; - - WDL_HeapBuf *mq; - while ((mq=m_queue.Get(0))) - { - int sz=mq->GetSize(); - if (m_offs < sz) break; - m_offs -= sz; - m_empties.Add(mq); - m_queue.Delete(0); - } - if (!mq||m_offs<0) m_offs=0; - } - - int Available() // bytes available - { - return m_avail; - } - - - int GetPtr(int offset, void **buf) // returns bytes available in this block - { - offset += m_offs; - - int x=0; - WDL_HeapBuf *mq; - while ((mq=m_queue.Get(x))) - { - int sz=mq->GetSize(); - if (offset < sz) - { - *buf = (char *)mq->Get() + offset; - return sz-offset; - } - x++; - offset -= sz; - } - *buf=NULL; - return 0; - } - - int SetFromBuf(int offs, void *buf, int len) // returns length set - { - int pos=0; - while (len > 0) - { - void *p=NULL; - int l=GetPtr(offs+pos,&p); - if (!l || !p) break; - if (l > len) l=len; - memcpy(p,(char *)buf + pos,l); - pos += l; - len -= l; - } - return pos; - } - - int GetToBuf(int offs, void *buf, int len) - { - int pos=0; - while (len > 0) - { - void *p=NULL; - int l=GetPtr(offs+pos,&p); - if (!l || !p) break; - if (l > len) l=len; - memcpy((char *)buf + pos,p,l); - pos += l; - len -= l; - } - return pos; - } - -private: - - WDL_PtrList m_queue, m_empties; - int m_offs; - int m_avail; - int m_bsize; - int __pad; -} WDL_FIXALIGN; - - -#endif //_WDL_FASTQUEUE_H_ \ No newline at end of file diff --git a/WDL/ffmpeg.h b/WDL/ffmpeg.h deleted file mode 100644 index e712fff2..00000000 --- a/WDL/ffmpeg.h +++ /dev/null @@ -1,533 +0,0 @@ -/* - WDL - ffmpeg.h - Copyright (C) 2005 Cockos Incorporated - Copyright (C) 1999-2004 Nullsoft, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -#ifndef _WDL_FFMPEG_H -#define _WDL_FFMPEG_H - -#ifdef _MSC_VER -#include "../sdks/ffmpeg/include/stdint.h" -#include "../sdks/ffmpeg/include/inttypes.h" -#endif - -extern "C" -{ -#include "../sdks/ffmpeg/include/libavformat/avformat.h" -#include "../sdks/ffmpeg/include/libswscale/swscale.h" -}; - -#include "queue.h" - -#ifndef INT64_C -#define INT64_C(val) val##i64 -#endif - -#ifndef INT64_MIN -#ifdef _MSC_VER -#define INT64_MIN (-0x7fffffffffffffff##i64 - 1) -#else -#define INT64_MIN (-0x7fffffffffffffffLL - 1) -#endif -#endif - -#ifndef INT64_MAX -#define INT64_MAX INT64_C(9223372036854775807) -#endif - -class WDL_VideoEncode -{ -public: - //bitrates are in kbps - WDL_VideoEncode(const char *format, int width, int height, double fps, int bitrate, const char *audioformat=NULL, int asr=44100, int ach=2, int abitrate=0) - { - m_init = 0; - m_img_resample_ctx = NULL; - m_stream = NULL; - m_astream = NULL; - m_video_enc = NULL; - m_audio_enc = NULL; - m_bit_buffer = NULL; - avcodec_get_frame_defaults(&m_cvtpic); - - //initialize FFMpeg - { - static int init = 0; - if(!init) av_register_all(); - init = 1; - } - - m_ctx = av_alloc_format_context(); - AVOutputFormat *fmt = guess_format(format, NULL, NULL); - if(!m_ctx || !fmt) return; - - m_ctx->oformat = fmt; - - m_stream = av_new_stream(m_ctx, m_ctx->nb_streams); - if(!m_stream) return; - - //init video - avcodec_get_context_defaults2(m_stream->codec, CODEC_TYPE_VIDEO); - m_video_enc = m_stream->codec; - - CodecID codec_id = av_guess_codec(m_ctx->oformat, NULL, NULL, NULL, CODEC_TYPE_VIDEO); - m_video_enc->codec_id = codec_id; - - AVCodec *codec; - codec = avcodec_find_encoder(codec_id); - if (!codec) return; - - m_video_enc->width = width; - m_video_enc->height = height; - m_video_enc->time_base.den = fps * 10000; - m_video_enc->time_base.num = 10000; - - m_video_enc->pix_fmt = PIX_FMT_BGRA; - if (codec && codec->pix_fmts) - { - const enum PixelFormat *p= codec->pix_fmts; - for (; *p!=-1; p++) { - if (*p == m_video_enc->pix_fmt) - break; - } - if (*p == -1) - m_video_enc->pix_fmt = codec->pix_fmts[0]; - } - - if(m_video_enc->pix_fmt != PIX_FMT_BGRA) - { - //this codec needs colorplane conversion - int sws_flags = SWS_BICUBIC; - m_img_resample_ctx = sws_getContext( - width, - height, - PIX_FMT_BGRA, - width, - height, - m_video_enc->pix_fmt, - sws_flags, NULL, NULL, NULL); - - if ( avpicture_alloc( (AVPicture*)&m_cvtpic, m_video_enc->pix_fmt, - m_video_enc->width, m_video_enc->height) ) - return; - } - - m_video_enc->bit_rate = bitrate*1024; - m_video_enc->gop_size = 12; /* emit one intra frame every twelve frames at most */ - - // some formats want stream headers to be separate - if(m_ctx->oformat->flags & AVFMT_GLOBALHEADER) - m_video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; - - m_video_enc->max_qdiff = 3; // set the default maximum quantizer difference between frames - m_video_enc->thread_count = 1; // set how many thread need be used in encoding - m_video_enc->rc_override_count = 0; // set ratecontrol override to 0 - if (!m_video_enc->rc_initial_buffer_occupancy) - { - m_video_enc->rc_initial_buffer_occupancy = m_video_enc->rc_buffer_size*3/4; // set decoder buffer size - } - m_video_enc->me_threshold = 0; // set motion estimation threshold value to 0 - m_video_enc->intra_dc_precision = 0; - m_video_enc->strict_std_compliance = 0; - m_ctx->preload = (int)(0.5 * AV_TIME_BASE); - m_ctx->max_delay = (int)(0.7 * AV_TIME_BASE); - m_ctx->loop_output = -1; - - m_ctx->timestamp = 0; - - av_log_set_callback(ffmpeg_avcodec_log); - av_log_set_level(AV_LOG_ERROR); - - if (avcodec_open(m_video_enc, codec) < 0) - { - return; - } - - //init audio - if(abitrate) - { - m_astream = av_new_stream(m_ctx, m_ctx->nb_streams); - if(!m_astream) return; - - avcodec_get_context_defaults2(m_astream->codec, CODEC_TYPE_AUDIO); - m_audio_enc = m_astream->codec; - - //use the format's default audio codec - CodecID codeca_id = av_guess_codec(m_ctx->oformat, audioformat, NULL, NULL, CODEC_TYPE_AUDIO); - m_audio_enc->codec_id = codeca_id; - - AVCodec *acodec; - acodec = avcodec_find_encoder(codeca_id); - if (!acodec) return; - - m_audio_enc->bit_rate = abitrate*1024; - m_audio_enc->sample_rate = asr; - m_audio_enc->channels = ach; - - if (avcodec_open(m_audio_enc, acodec) < 0) return; - } - - AVFormatParameters params, *ap = ¶ms; - memset(ap, 0, sizeof(*ap)); - if (av_set_parameters(m_ctx, ap) < 0) return; - - url_open_dyn_buf(&m_ctx->pb); - av_write_header(m_ctx); - - int size = width * height; - m_bit_buffer_size = 1024 * 256; - m_bit_buffer_size= FFMAX(m_bit_buffer_size, 4*size); - - m_bit_buffer = (uint8_t*)av_malloc(m_bit_buffer_size); - - m_init = 1; - } - ~WDL_VideoEncode() - { - if(m_stream && m_stream->codec) avcodec_close(m_stream->codec); - if(m_astream && m_astream->codec) avcodec_close(m_astream->codec); - av_free(m_bit_buffer); - av_free(m_cvtpic.data[0]); - av_free(m_ctx); - } - - int isInited() { return m_init; } - - void encodeVideo(const LICE_pixel *buf) - { - if(m_img_resample_ctx) - { - //convert to output format - uint8_t *p[1]={(uint8_t*)buf}; - int w[1]={m_video_enc->width*4}; - sws_scale(m_img_resample_ctx, p, w, - 0, m_video_enc->height, m_cvtpic.data, m_cvtpic.linesize); - } - int ret = avcodec_encode_video(m_video_enc, m_bit_buffer, m_bit_buffer_size, &m_cvtpic); - if(ret>0) - { - AVPacket pkt; - av_init_packet(&pkt); - pkt.stream_index = 0; - pkt.data = m_bit_buffer; - pkt.size = ret; - if (m_video_enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(m_video_enc->coded_frame->pts, m_video_enc->time_base, m_stream->time_base); - if(m_video_enc->coded_frame->key_frame) - pkt.flags |= PKT_FLAG_KEY; - av_interleaved_write_frame(m_ctx, &pkt); - } - } - - void encodeAudio(short *data, int nbsamples) - { - AVPacket pkt; - int l = nbsamples; - int fs = m_audio_enc->frame_size*m_audio_enc->channels; - while(l>=fs) - { - av_init_packet(&pkt); - pkt.size= avcodec_encode_audio(m_audio_enc, m_bit_buffer, m_bit_buffer_size, data); - if (m_audio_enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(m_audio_enc->coded_frame->pts, m_audio_enc->time_base, m_astream->time_base); - pkt.flags |= PKT_FLAG_KEY; - pkt.stream_index = 1; - pkt.data = m_bit_buffer; - av_interleaved_write_frame(m_ctx, &pkt); - - data += fs; - l -= fs; - } - } - - int getBytes(unsigned char *p, int size) - { - //looks like there's no other way to get data from ffmpeg's dynamic buffers apart from closing them - if (m_queue.GetSize() < size && m_init) - { - uint8_t *pb_buffer; - int l = url_close_dyn_buf(m_ctx-> pb, &pb_buffer); - if(l > 0) - { - m_queue.Add(pb_buffer, l); - av_free(pb_buffer); - } - url_open_dyn_buf(&m_ctx->pb); //sets up next dynamic buffer for ffmpeg - } - - int s = min(size, m_queue.GetSize()); - if(s) - { - memcpy(p, m_queue.Get(), s); - m_queue.Advance(s); - m_queue.Compact(); - } - return s; - } - - void close() - { - av_write_trailer(m_ctx); - uint8_t *pb_buffer; - int l = url_close_dyn_buf(m_ctx-> pb, &pb_buffer); - if(l) - { - m_queue.Add(pb_buffer, l); - av_free(pb_buffer); - } - m_init=0; - } - - //useful to get debugging information from ffmpeg - static void ffmpeg_avcodec_log(void *ptr, int val, const char * msg, va_list ap) - { - AVClass* avc= ptr ? *(AVClass**)ptr : NULL; - vprintf(msg, ap); - } - -protected: - int m_init; - - AVFormatContext *m_ctx; - AVStream *m_stream, *m_astream; - AVCodecContext *m_video_enc, *m_audio_enc; - struct SwsContext *m_img_resample_ctx; - AVFrame m_cvtpic; - uint8_t *m_bit_buffer; - int m_bit_buffer_size; - - WDL_Queue m_queue; -}; - -class WDL_VideoDecode -{ -public: - WDL_VideoDecode(const char *fn) - { - m_inited = 0; - m_ctx = NULL; - m_frame = NULL; - m_ic = NULL; - m_sws = NULL; - m_sws_destw=0; - m_sws_desth=0; - m_curtime=-1.0; - - //initialize FFMpeg - { - static int init = 0; - if(!init) av_register_all(); - init = 1; - } - - int ret = av_open_input_file(&m_ic, fn, NULL, 0, NULL); - if (ret < 0) return; - - ret = av_find_stream_info(m_ic); - if (ret < 0) return; - - // find the stream that corresponds to the stream type - int i, stream = -1; - for(i=0; i < (int)m_ic->nb_streams; i++) - { - int st = m_ic->streams[i]->codec->codec_type; - if(st==CODEC_TYPE_VIDEO) - { - stream = i; - break; - } - } - if(stream==-1) return; //no stream found - - m_ctx = m_ic->streams[stream]->codec; - - AVCodec *pCodec = avcodec_find_decoder(m_ctx->codec_id); - if(pCodec == NULL) return; // codec not found - - if(avcodec_open(m_ctx, pCodec)<0) return; // Could not open codec - - AVStream *st = m_ic->streams[stream]; - if(st->r_frame_rate.den && st->r_frame_rate.num) - m_fps = av_q2d(st->r_frame_rate); - else - m_fps = 1/av_q2d(st->codec->time_base); - - m_frame = avcodec_alloc_frame(); - - m_w = m_ctx->width; - m_h = m_ctx->height; - - m_pixfmt=st->codec->pix_fmt; - - if(m_ic->duration == AV_NOPTS_VALUE) - { - //FFmpeg can't get the duration - //approximate the duration of the file with the first packets bitrates - AVStream *st = m_ic->streams[stream]; - int bitrate = 0; - for(i=0; i < (int)m_ic->nb_streams; i++) - { - bitrate += m_ic->streams[i]->codec->bit_rate; - } - bitrate /= 8; - if(bitrate) - m_len = (double)m_ic->file_size/bitrate; - else - m_len = 30; //last resort - } - else - m_len = (double)m_ic->duration/AV_TIME_BASE; - m_stream = stream; - - m_inited = 1; - } - ~WDL_VideoDecode() - { - if(m_frame) av_free(m_frame); - if(m_ic) av_close_input_file(m_ic); - if(m_sws) sws_freeContext(m_sws); - } - int isInited() { return m_inited; } - int GetVideoFrameAtTime(LICE_IBitmap *dst, double atTime, double *startTime, double *endTime, bool resizeToBuf) - { - if(!m_inited) return 0; - if(m_curtime == -1.0 || atTime(1.0/m_fps)) - { - if(avformat_seek_file(m_ic, -1, INT64_MIN, atTime*AV_TIME_BASE, INT64_MAX, AVSEEK_FLAG_BACKWARD) < 0) - { - //fallback to old seeking API - av_seek_frame(m_ic, -1, atTime*AV_TIME_BASE, AVSEEK_FLAG_BACKWARD); - } - avcodec_flush_buffers(m_ctx); - } - - double startpts = -1; - while(1) - { - AVPacket packet; - if(av_read_frame(m_ic, &packet)<0) return 0; //end of file - if(packet.stream_index==m_stream) - { - double packetpts = getPresentationTime(&packet); - if(startpts == -1) startpts = packetpts; - - int frameFinished = 0; - int l = avcodec_decode_video(m_ctx, m_frame, &frameFinished, packet.data, packet.size); - if(l>=0) - { - // Did we get a video frame? - if(frameFinished) - { - double pts = startpts; - double epts = packetpts+(1.0/m_fps); - - if(eptsgetWidth(); - h = dst->getHeight(); - } - else - { - dst->resize(w, h); - } - unsigned int *bits = dst->getBits(); -/*#ifdef _WIN32 - uint8_t *dstd[4]= {(uint8_t *)bits+(dst->getRowSpan()*4*(h-1)),}; - int dst_stride[4]={-dst->getRowSpan()*4,}; -#else*/ - uint8_t *dstd[4]= {(uint8_t *)bits,}; - int dst_stride[4]={dst->getRowSpan()*4,}; -//#endif - - if (!m_sws || m_sws_desth != h || m_sws_destw != w) - { - int sws_flags = SWS_BICUBIC; - PixelFormat pfout = - #ifdef _WIN32 - PIX_FMT_RGB32; - #else - PIX_FMT_BGR32_1; - #endif - if(m_sws) sws_freeContext(m_sws); - m_sws = sws_getContext(m_w, m_h, m_pixfmt, w, h, pfout, sws_flags, NULL, NULL, NULL); - m_sws_desth = h; - m_sws_destw = w; - } - - if (m_sws) - sws_scale(m_sws, m_frame->data, m_frame->linesize, 0, m_h, dstd, dst_stride); - - av_free_packet(&packet); - return 1; - } - } - - av_free_packet(&packet); - } - } - - return 0; - } - -protected: - - double getPresentationTime(AVPacket *packet) - { - double mpts = 0; - if(packet->dts != AV_NOPTS_VALUE) mpts = (double)packet->dts; - mpts *= av_q2d(m_ic->streams[packet->stream_index]->time_base); - mpts -= (double)m_ic->start_time/AV_TIME_BASE; - return mpts; - } - - int m_inited; - - AVFormatContext *m_ic; - AVCodecContext *m_ctx; - - AVFrame *m_frame; - - int m_stream; - - int m_w, m_h, m_format; - double m_fps, m_len; - struct SwsContext *m_sws; - int m_sws_desth, m_sws_destw; - PixelFormat m_pixfmt; - - double m_curtime; -}; - -#endif diff --git a/WDL/fft.c b/WDL/fft.c deleted file mode 100644 index f58ab5df..00000000 --- a/WDL/fft.c +++ /dev/null @@ -1,1647 +0,0 @@ -/* - WDL - fft.cpp - Copyright (C) 2006 and later Cockos Incorporated - Copyright 1999 D. J. Bernstein - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - - This file implements the WDL FFT library. These routines are based on the - DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com - - The DJB FFT web page is: http://cr.yp.to/djbfft.html - -*/ - - -// this is based on djbfft - -#include -#include "fft.h" - - -#define FFT_MAXBITLEN 15 - -#ifdef _MSC_VER -#define inline __inline -#endif - -#define PI 3.1415926535897932384626433832795 - -static WDL_FFT_COMPLEX d16[3]; -static WDL_FFT_COMPLEX d32[7]; -static WDL_FFT_COMPLEX d64[15]; -static WDL_FFT_COMPLEX d128[31]; -static WDL_FFT_COMPLEX d256[63]; -static WDL_FFT_COMPLEX d512[127]; -static WDL_FFT_COMPLEX d1024[127]; -static WDL_FFT_COMPLEX d2048[255]; -static WDL_FFT_COMPLEX d4096[511]; -static WDL_FFT_COMPLEX d8192[1023]; -static WDL_FFT_COMPLEX d16384[2047]; -static WDL_FFT_COMPLEX d32768[4095]; - - -#define sqrthalf (d16[1].re) - -#define VOL *(volatile WDL_FFT_REAL *)& - -#define TRANSFORM(a0,a1,a2,a3,wre,wim) { \ - t6 = a2.re; \ - t1 = a0.re - t6; \ - t6 += a0.re; \ - a0.re = t6; \ - t3 = a3.im; \ - t4 = a1.im - t3; \ - t8 = t1 - t4; \ - t1 += t4; \ - t3 += a1.im; \ - a1.im = t3; \ - t5 = wre; \ - t7 = t8 * t5; \ - t4 = t1 * t5; \ - t8 *= wim; \ - t2 = a3.re; \ - t3 = a1.re - t2; \ - t2 += a1.re; \ - a1.re = t2; \ - t1 *= wim; \ - t6 = a2.im; \ - t2 = a0.im - t6; \ - t6 += a0.im; \ - a0.im = t6; \ - t6 = t2 + t3; \ - t2 -= t3; \ - t3 = t6 * wim; \ - t7 -= t3; \ - a2.re = t7; \ - t6 *= t5; \ - t6 += t8; \ - a2.im = t6; \ - t5 *= t2; \ - t5 -= t1; \ - a3.im = t5; \ - t2 *= wim; \ - t4 += t2; \ - a3.re = t4; \ - } - -#define TRANSFORMHALF(a0,a1,a2,a3) { \ - t1 = a2.re; \ - t5 = a0.re - t1; \ - t1 += a0.re; \ - a0.re = t1; \ - t4 = a3.im; \ - t8 = a1.im - t4; \ - t1 = t5 - t8; \ - t5 += t8; \ - t4 += a1.im; \ - a1.im = t4; \ - t3 = a3.re; \ - t7 = a1.re - t3; \ - t3 += a1.re; \ - a1.re = t3; \ - t8 = a2.im; \ - t6 = a0.im - t8; \ - t2 = t6 + t7; \ - t6 -= t7; \ - t8 += a0.im; \ - a0.im = t8; \ - t4 = t6 + t5; \ - t3 = sqrthalf; \ - t4 *= t3; \ - a3.re = t4; \ - t6 -= t5; \ - t6 *= t3; \ - a3.im = t6; \ - t7 = t1 - t2; \ - t7 *= t3; \ - a2.re = t7; \ - t2 += t1; \ - t2 *= t3; \ - a2.im = t2; \ - } - -#define TRANSFORMZERO(a0,a1,a2,a3) { \ - t5 = a2.re; \ - t1 = a0.re - t5; \ - t5 += a0.re; \ - a0.re = t5; \ - t8 = a3.im; \ - t4 = a1.im - t8; \ - t7 = a3.re; \ - t6 = t1 - t4; \ - a2.re = t6; \ - t1 += t4; \ - a3.re = t1; \ - t8 += a1.im; \ - a1.im = t8; \ - t3 = a1.re - t7; \ - t7 += a1.re; \ - a1.re = t7; \ - t6 = a2.im; \ - t2 = a0.im - t6; \ - t7 = t2 + t3; \ - a2.im = t7; \ - t2 -= t3; \ - a3.im = t2; \ - t6 += a0.im; \ - a0.im = t6; \ - } - -#define UNTRANSFORM(a0,a1,a2,a3,wre,wim) { \ - t6 = VOL wre; \ - t1 = VOL a2.re; \ - t1 *= t6; \ - t8 = VOL wim; \ - t3 = VOL a2.im; \ - t3 *= t8; \ - t2 = VOL a2.im; \ - t4 = VOL a2.re; \ - t5 = VOL a3.re; \ - t5 *= t6; \ - t7 = VOL a3.im; \ - t1 += t3; \ - t7 *= t8; \ - t5 -= t7; \ - t3 = t5 + t1; \ - t5 -= t1; \ - t2 *= t6; \ - t6 *= a3.im; \ - t4 *= t8; \ - t2 -= t4; \ - t8 *= a3.re; \ - t6 += t8; \ - t1 = a0.re - t3; \ - t3 += a0.re; \ - a0.re = t3; \ - t7 = a1.im - t5; \ - t5 += a1.im; \ - a1.im = t5; \ - t4 = t2 - t6; \ - t6 += t2; \ - t8 = a1.re - t4; \ - t4 += a1.re; \ - a1.re = t4; \ - t2 = a0.im - t6; \ - t6 += a0.im; \ - a0.im = t6; \ - a2.re = t1; \ - a3.im = t7; \ - a3.re = t8; \ - a2.im = t2; \ - } - - -#define UNTRANSFORMHALF(a0,a1,a2,a3) { \ - t6 = sqrthalf; \ - t1 = a2.re; \ - t2 = a2.im - t1; \ - t2 *= t6; \ - t1 += a2.im; \ - t1 *= t6; \ - t4 = a3.im; \ - t3 = a3.re - t4; \ - t3 *= t6; \ - t4 += a3.re; \ - t4 *= t6; \ - t8 = t3 - t1; \ - t7 = t2 - t4; \ - t1 += t3; \ - t2 += t4; \ - t4 = a1.im - t8; \ - a3.im = t4; \ - t8 += a1.im; \ - a1.im = t8; \ - t3 = a1.re - t7; \ - a3.re = t3; \ - t7 += a1.re; \ - a1.re = t7; \ - t5 = a0.re - t1; \ - a2.re = t5; \ - t1 += a0.re; \ - a0.re = t1; \ - t6 = a0.im - t2; \ - a2.im = t6; \ - t2 += a0.im; \ - a0.im = t2; \ - } - -#define UNTRANSFORMZERO(a0,a1,a2,a3) { \ - t2 = a3.im; \ - t3 = a2.im - t2; \ - t2 += a2.im; \ - t1 = a2.re; \ - t4 = a3.re - t1; \ - t1 += a3.re; \ - t5 = a0.re - t1; \ - a2.re = t5; \ - t6 = a0.im - t2; \ - a2.im = t6; \ - t7 = a1.re - t3; \ - a3.re = t7; \ - t8 = a1.im - t4; \ - a3.im = t8; \ - t1 += a0.re; \ - a0.re = t1; \ - t2 += a0.im; \ - a0.im = t2; \ - t3 += a1.re; \ - a1.re = t3; \ - t4 += a1.im; \ - a1.im = t4; \ - } - -#define R(a0,a1,b0,b1,wre,wim) { \ - t1 = a0 - a1; \ - t2 = b0 - b1; \ - t5 = t1 * wim; \ - t6 = t2 * wim; \ - t3 = VOL a0; \ - t1 *= wre; \ - t3 += a1; \ - t2 *= wre; \ - t1 -= t6; \ - t4 = VOL b0; \ - t2 += t5; \ - t4 += b1; \ - a0 = t3; \ - b1 = t2; \ - a1 = t4; \ - b0 = t1; \ - } - -#define RHALF(a0,a1,b0,b1) { \ - t1 = a0 - a1; \ - t2 = b0 - b1; \ - t3 = a0 + a1; \ - t5 = t1 - t2; \ - t1 += t2; \ - t4 = VOL b0; \ - t5 *= sqrthalf; \ - t4 += b1; \ - t1 *= sqrthalf; \ - a0 = t3; \ - b1 = t1; \ - a1 = t4; \ - b0 = t5; \ - } - -#define RZERO(a0,a1,b0,b1) { \ - t1 = a0 - a1; \ - t2 = b0 - b1; \ - t3 = a0 + a1; \ - t4 = b0 + b1; \ - b0 = t1; \ - a0 = t3; \ - b1 = t2; \ - a1 = t4; \ - } - -#define V(a0,a1,b0,b1,wre,wim) { \ - t5 = b0 * wre; \ - t1 = b1 * wim; \ - t6 = b1 * wre; \ - t5 += t1; \ - t3 = b0 * wim; \ - t2 = a0 - t5; \ - t6 -= t3; \ - t5 += a0; \ - t4 = a1 - t6; \ - t6 += a1; \ - a1 = t2; \ - a0 = t5; \ - b1 = t4; \ - b0 = t6; \ - } - -#define VHALF(a0,a1,b0,b1) { \ - t5 = b0 + b1; \ - t6 = b1 - b0; \ - t5 *= sqrthalf; \ - t2 = VOL a0; \ - t6 *= sqrthalf; \ - t2 -= t5; \ - t5 += a0; \ - t4 = a1 - t6; \ - t6 += a1; \ - a1 = t2; \ - a0 = t5; \ - b0 = t6; \ - b1 = t4; \ - } - -#define VZERO(a0,a1,b0,b1) { \ - t1 = a0 + b0; \ - t2 = a0 - b0; \ - t3 = a1 + b1; \ - t4 = a1 - b1; \ - a0 = t1; \ - b0 = t3; \ - a1 = t2; \ - b1 = t4; \ - } - -static void c2(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1; - - t1 = a[1].re; - a[1].re = a[0].re - t1; - a[0].re += t1; - - t1 = a[1].im; - a[1].im = a[0].im - t1; - a[0].im += t1; -} - -static inline void c4(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - t5 = a[2].re; - t1 = a[0].re - t5; - t7 = a[3].re; - t5 += a[0].re; - t3 = a[1].re - t7; - t7 += a[1].re; - t8 = t5 + t7; - a[0].re = t8; - t5 -= t7; - a[1].re = t5; - t6 = a[2].im; - t2 = a[0].im - t6; - t6 += a[0].im; - t5 = a[3].im; - a[2].im = t2 + t3; - t2 -= t3; - a[3].im = t2; - t4 = a[1].im - t5; - a[3].re = t1 + t4; - t1 -= t4; - a[2].re = t1; - t5 += a[1].im; - a[0].im = t6 + t5; - t6 -= t5; - a[1].im = t6; -} - -static void c8(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - t7 = a[4].im; - t4 = a[0].im - t7; - t7 += a[0].im; - a[0].im = t7; - - t8 = a[6].re; - t5 = a[2].re - t8; - t8 += a[2].re; - a[2].re = t8; - - t7 = a[6].im; - a[6].im = t4 - t5; - t4 += t5; - a[4].im = t4; - - t6 = a[2].im - t7; - t7 += a[2].im; - a[2].im = t7; - - t8 = a[4].re; - t3 = a[0].re - t8; - t8 += a[0].re; - a[0].re = t8; - - a[4].re = t3 - t6; - t3 += t6; - a[6].re = t3; - - t7 = a[5].re; - t3 = a[1].re - t7; - t7 += a[1].re; - a[1].re = t7; - - t8 = a[7].im; - t6 = a[3].im - t8; - t8 += a[3].im; - a[3].im = t8; - t1 = t3 - t6; - t3 += t6; - - t7 = a[5].im; - t4 = a[1].im - t7; - t7 += a[1].im; - a[1].im = t7; - - t8 = a[7].re; - t5 = a[3].re - t8; - t8 += a[3].re; - a[3].re = t8; - - t2 = t4 - t5; - t4 += t5; - - t6 = t1 - t4; - t8 = sqrthalf; - t6 *= t8; - a[5].re = a[4].re - t6; - t1 += t4; - t1 *= t8; - a[5].im = a[4].im - t1; - t6 += a[4].re; - a[4].re = t6; - t1 += a[4].im; - a[4].im = t1; - - t5 = t2 - t3; - t5 *= t8; - a[7].im = a[6].im - t5; - t2 += t3; - t2 *= t8; - a[7].re = a[6].re - t2; - t2 += a[6].re; - a[6].re = t2; - t5 += a[6].im; - a[6].im = t5; - - c4(a); -} - -static void c16(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - TRANSFORMZERO(a[0],a[4],a[8],a[12]); - TRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); - TRANSFORMHALF(a[2],a[6],a[10],a[14]); - TRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); - c4(a + 8); - c4(a + 12); - - c8(a); -} - -/* a[0...8n-1], w[0...2n-2]; n >= 2 */ -static void cpass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - register WDL_FFT_COMPLEX *a1; - register WDL_FFT_COMPLEX *a2; - register WDL_FFT_COMPLEX *a3; - - a2 = a + 4 * n; - a1 = a + 2 * n; - a3 = a2 + 2 * n; - --n; - - TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); - TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); - - for (;;) { - TRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); - TRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); - if (!--n) break; - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w += 2; - } -} - -static void c32(register WDL_FFT_COMPLEX *a) -{ - cpass(a,d32,4); - c8(a + 16); - c8(a + 24); - c16(a); -} - -static void c64(register WDL_FFT_COMPLEX *a) -{ - cpass(a,d64,8); - c16(a + 32); - c16(a + 48); - c32(a); -} - -static void c128(register WDL_FFT_COMPLEX *a) -{ - cpass(a,d128,16); - c32(a + 64); - c32(a + 96); - c64(a); -} - -static void c256(register WDL_FFT_COMPLEX *a) -{ - cpass(a,d256,32); - c64(a + 128); - c64(a + 192); - c128(a); -} - -static void c512(register WDL_FFT_COMPLEX *a) -{ - cpass(a,d512,64); - c128(a + 384); - c128(a + 256); - c256(a); -} - -/* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ -static void cpassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - register WDL_FFT_COMPLEX *a1; - register WDL_FFT_COMPLEX *a2; - register WDL_FFT_COMPLEX *a3; - register unsigned int k; - - a2 = a + 4 * n; - a1 = a + 2 * n; - a3 = a2 + 2 * n; - k = n - 2; - - TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); - TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - - do { - TRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); - TRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w += 2; - } while (k -= 2); - - TRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); - TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - - k = n - 2; - do { - TRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); - TRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w -= 2; - } while (k -= 2); -} - - -static void c1024(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d1024,128); - c256(a + 768); - c256(a + 512); - c512(a); -} - -static void c2048(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d2048,256); - c512(a + 1536); - c512(a + 1024); - c1024(a); -} - -static void c4096(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d4096,512); - c1024(a + 3072); - c1024(a + 2048); - c2048(a); -} - -static void c8192(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d8192,1024); - c2048(a + 6144); - c2048(a + 4096); - c4096(a); -} - -static void c16384(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d16384,2048); - c4096(a + 8192 + 4096); - c4096(a + 8192); - c8192(a); -} - -static void c32768(register WDL_FFT_COMPLEX *a) -{ - cpassbig(a,d32768,4096); - c8192(a + 16384 + 8192); - c8192(a + 16384); - c16384(a); -} - -#if 0 -static void mulr4(WDL_FFT_REAL *a,WDL_FFT_REAL *b) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - - t1 = a[2] * b[2]; - t2 = a[3] * b[3]; - t3 = a[3] * b[2]; - t4 = a[2] * b[3]; - t5 = a[0] * b[0]; - t6 = a[1] * b[1]; - t1 -= t2; - t3 += t4; - a[0] = t5; - a[1] = t6; - a[2] = t1; - a[3] = t3; -} - -#endif -/* n even, n > 0 */ -void WDL_fft_complexmul(WDL_FFT_COMPLEX *a,WDL_FFT_COMPLEX *b,int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - if (n<2 || (n&1)) return; - - do { - t1 = a[0].re * b[0].re; - t2 = a[0].im * b[0].im; - t3 = a[0].im * b[0].re; - t4 = a[0].re * b[0].im; - t5 = a[1].re * b[1].re; - t6 = a[1].im * b[1].im; - t7 = a[1].im * b[1].re; - t8 = a[1].re * b[1].im; - t1 -= t2; - t3 += t4; - t5 -= t6; - t7 += t8; - a[0].re = t1; - a[1].re = t5; - a[0].im = t3; - a[1].im = t7; - a += 2; - b += 2; - } while (n -= 2); -} - -void WDL_fft_complexmul2(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - if (n<2 || (n&1)) return; - - do { - t1 = a[0].re * b[0].re; - t2 = a[0].im * b[0].im; - t3 = a[0].im * b[0].re; - t4 = a[0].re * b[0].im; - t5 = a[1].re * b[1].re; - t6 = a[1].im * b[1].im; - t7 = a[1].im * b[1].re; - t8 = a[1].re * b[1].im; - t1 -= t2; - t3 += t4; - t5 -= t6; - t7 += t8; - c[0].re = t1; - c[1].re = t5; - c[0].im = t3; - c[1].im = t7; - a += 2; - b += 2; - c += 2; - } while (n -= 2); -} -void WDL_fft_complexmul3(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - if (n<2 || (n&1)) return; - - do { - t1 = a[0].re * b[0].re; - t2 = a[0].im * b[0].im; - t3 = a[0].im * b[0].re; - t4 = a[0].re * b[0].im; - t5 = a[1].re * b[1].re; - t6 = a[1].im * b[1].im; - t7 = a[1].im * b[1].re; - t8 = a[1].re * b[1].im; - t1 -= t2; - t3 += t4; - t5 -= t6; - t7 += t8; - c[0].re += t1; - c[1].re += t5; - c[0].im += t3; - c[1].im += t7; - a += 2; - b += 2; - c += 2; - } while (n -= 2); -} - - -static inline void u4(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - t1 = VOL a[1].re; - t3 = a[0].re - t1; - t6 = VOL a[2].re; - t1 += a[0].re; - t8 = a[3].re - t6; - t6 += a[3].re; - a[0].re = t1 + t6; - t1 -= t6; - a[2].re = t1; - - t2 = VOL a[1].im; - t4 = a[0].im - t2; - t2 += a[0].im; - t5 = VOL a[3].im; - a[1].im = t4 + t8; - t4 -= t8; - a[3].im = t4; - - t7 = a[2].im - t5; - t5 += a[2].im; - a[1].re = t3 + t7; - t3 -= t7; - a[3].re = t3; - a[0].im = t2 + t5; - t2 -= t5; - a[2].im = t2; -} - -static void u8(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - u4(a); - - t1 = a[5].re; - a[5].re = a[4].re - t1; - t1 += a[4].re; - - t3 = a[7].re; - a[7].re = a[6].re - t3; - t3 += a[6].re; - - t8 = t3 - t1; - t1 += t3; - - t6 = a[2].im - t8; - t8 += a[2].im; - a[2].im = t8; - - t5 = a[0].re - t1; - a[4].re = t5; - t1 += a[0].re; - a[0].re = t1; - - t2 = a[5].im; - a[5].im = a[4].im - t2; - t2 += a[4].im; - - t4 = a[7].im; - a[7].im = a[6].im - t4; - t4 += a[6].im; - - a[6].im = t6; - - t7 = t2 - t4; - t2 += t4; - - t3 = a[2].re - t7; - a[6].re = t3; - t7 += a[2].re; - a[2].re = t7; - - t6 = a[0].im - t2; - a[4].im = t6; - t2 += a[0].im; - a[0].im = t2; - - t6 = sqrthalf; - - t1 = a[5].re; - t2 = a[5].im - t1; - t2 *= t6; - t1 += a[5].im; - t1 *= t6; - t4 = a[7].im; - t3 = a[7].re - t4; - t3 *= t6; - t4 += a[7].re; - t4 *= t6; - - t8 = t3 - t1; - t1 += t3; - t7 = t2 - t4; - t2 += t4; - - t4 = a[3].im - t8; - a[7].im = t4; - t5 = a[1].re - t1; - a[5].re = t5; - t3 = a[3].re - t7; - a[7].re = t3; - t6 = a[1].im - t2; - a[5].im = t6; - - t8 += a[3].im; - a[3].im = t8; - t1 += a[1].re; - a[1].re = t1; - t7 += a[3].re; - a[3].re = t7; - t2 += a[1].im; - a[1].im = t2; -} - -static void u16(register WDL_FFT_COMPLEX *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - u8(a); - u4(a + 8); - u4(a + 12); - - UNTRANSFORMZERO(a[0],a[4],a[8],a[12]); - UNTRANSFORMHALF(a[2],a[6],a[10],a[14]); - UNTRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); - UNTRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); -} - -/* a[0...8n-1], w[0...2n-2] */ -static void upass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - register WDL_FFT_COMPLEX *a1; - register WDL_FFT_COMPLEX *a2; - register WDL_FFT_COMPLEX *a3; - - a2 = a + 4 * n; - a1 = a + 2 * n; - a3 = a2 + 2 * n; - n -= 1; - - UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); - UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); - - for (;;) { - UNTRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); - UNTRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); - if (!--n) break; - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w += 2; - } -} - -static void u32(register WDL_FFT_COMPLEX *a) -{ - u16(a); - u8(a + 16); - u8(a + 24); - upass(a,d32,4); -} - -static void u64(register WDL_FFT_COMPLEX *a) -{ - u32(a); - u16(a + 32); - u16(a + 48); - upass(a,d64,8); -} - -static void u128(register WDL_FFT_COMPLEX *a) -{ - u64(a); - u32(a + 64); - u32(a + 96); - upass(a,d128,16); -} - -static void u256(register WDL_FFT_COMPLEX *a) -{ - u128(a); - u64(a + 128); - u64(a + 192); - upass(a,d256,32); -} - -static void u512(register WDL_FFT_COMPLEX *a) -{ - u256(a); - u128(a + 256); - u128(a + 384); - upass(a,d512,64); -} - - -/* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ -static void upassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - register WDL_FFT_COMPLEX *a1; - register WDL_FFT_COMPLEX *a2; - register WDL_FFT_COMPLEX *a3; - register unsigned int k; - - a2 = a + 4 * n; - a1 = a + 2 * n; - a3 = a2 + 2 * n; - k = n - 2; - - UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); - UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - - do { - UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); - UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w += 2; - } while (k -= 2); - - UNTRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); - UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - - k = n - 2; - do { - UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); - UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); - a += 2; - a1 += 2; - a2 += 2; - a3 += 2; - w -= 2; - } while (k -= 2); -} - - - -static void u1024(register WDL_FFT_COMPLEX *a) -{ - u512(a); - u256(a + 512); - u256(a + 768); - upassbig(a,d1024,128); -} - -static void u2048(register WDL_FFT_COMPLEX *a) -{ - u1024(a); - u512(a + 1024); - u512(a + 1536); - upassbig(a,d2048,256); -} - - -static void u4096(register WDL_FFT_COMPLEX *a) -{ - u2048(a); - u1024(a + 2048); - u1024(a + 3072); - upassbig(a,d4096,512); -} - -static void u8192(register WDL_FFT_COMPLEX *a) -{ - u4096(a); - u2048(a + 4096); - u2048(a + 6144); - upassbig(a,d8192,1024); -} - -static void u16384(register WDL_FFT_COMPLEX *a) -{ - u8192(a); - u4096(a + 8192); - u4096(a + 8192 + 4096); - upassbig(a,d16384,2048); -} - -static void u32768(register WDL_FFT_COMPLEX *a) -{ - u16384(a); - u8192(a + 16384); - u8192(a + 16384 + 8192 ); - upassbig(a,d32768,4096); -} - - -static void __fft_gen(WDL_FFT_COMPLEX *buf, int sz, int isfull) -{ - int x; - double div=PI*0.25/(sz+1.0); - - if (isfull) div*=2.0; - - for (x = 0; x < sz; x ++) - { - buf[x].re = (WDL_FFT_REAL) cos((x+1)*div); - buf[x].im = (WDL_FFT_REAL) sin((x+1)*div); - } -} - -#ifndef WDL_FFT_NO_PERMUTE - -static unsigned int fftfreq_c(unsigned int i,unsigned int n) -{ - unsigned int m; - - if (n <= 2) return i; - - m = n >> 1; - if (i < m) return fftfreq_c(i,m) << 1; - - i -= m; - m >>= 1; - if (i < m) return (fftfreq_c(i,m) << 2) + 1; - i -= m; - return ((fftfreq_c(i,m) << 2) - 1) & (n - 1); -} - -static int _idxperm[2<= 8 */ -void WDL_fft_realmul(WDL_FFT_REAL *a,WDL_FFT_REAL *b,int n) -{ - if (n<8 || (n&3)) return; - mulr4(a,b); - WDL_fft_complexmul((WDL_FFT_COMPLEX *)(a + 4),(WDL_FFT_COMPLEX *)(b + 4),(n - 4) / 2); -} - - - - -//////////// begin WDL_FFT_REAL modes -static void r2(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2; - - t1 = a[0] + a[1]; - t2 = a[0] - a[1]; - a[0] = t1; - a[1] = t2; -} - -static void r4(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t6; - - t3 = a[0] + a[1]; - t4 = a[2] + a[3]; - t1 = a[0] - a[1]; - t2 = a[2] - a[3]; - t6 = t3 - t4; - t3 += t4; - a[2] = t1; - a[3] = t2; - a[0] = t3; - a[1] = t6; -} - -static void r8(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - t2 = a[0] + a[1]; - t8 = a[4] + a[5]; - t3 = a[2] - a[3]; - t6 = t2 - t8; - t2 += t8; - t1 = a[2] + a[3]; - t7 = a[6] + a[7]; - a[2] = t6; - t5 = t1 - t7; - t1 += t7; - t4 = a[0] - a[1]; - a[3] = t5; - t8 = t2 - t1; - t2 += t1; - t7 = a[6] - a[7]; - a[1] = t8; - t6 = t3 - t7; - t3 += t7; - a[0] = t2; - t6 *= sqrthalf; - t8 = a[4] - a[5]; - t3 *= sqrthalf; - t1 = t4 - t6; - t4 += t6; - t2 = t8 - t3; - t8 += t3; - a[6] = t1; - a[4] = t4; - a[7] = t2; - a[5] = t8; -} - -/* a[0...8n-1], w[0...2n-1]; n even, n >= 4 */ -static void rpass(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - register WDL_FFT_REAL *b; - register unsigned int k; - - b = a + 4 * n; - k = n - 2; - - RZERO(a[0],a[1],b[0],b[1]); - R(a[2],a[3],b[2],b[3],w[0].re,w[0].im); - R(a[4],a[5],b[4],b[5],w[1].re,w[1].im); - R(a[6],a[7],b[6],b[7],w[2].re,w[2].im); - - for (;;) { - R(a[8],a[9],b[8],b[9],w[3].re,w[3].im); - R(a[10],a[11],b[10],b[11],w[4].re,w[4].im); - R(a[12],a[13],b[12],b[13],w[5].re,w[5].im); - R(a[14],a[15],b[14],b[15],w[6].re,w[6].im); - if (!(k -= 2)) break; - a += 8; - b += 8; - w += 4; - } -} - -static void r16(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - - RZERO(a[0],a[1],a[8],a[9]); - R(a[2],a[3],a[10],a[11],d16[0].re,d16[0].im); - R(a[4],a[5],a[12],a[13],d16[1].re,d16[1].im); - R(a[6],a[7],a[14],a[15],d16[2].re,d16[2].im); - r8(a); - c4((WDL_FFT_COMPLEX *)(a + 8)); -} - -static void r32(register WDL_FFT_REAL *a) -{ - rpass(a,d32,4); - r16(a); - c8((WDL_FFT_COMPLEX *)(a + 16)); -} - -static void r64(register WDL_FFT_REAL *a) -{ - rpass(a,d64,8); - r32(a); - c16((WDL_FFT_COMPLEX *)(a + 32)); -} - -static void r128(register WDL_FFT_REAL *a) -{ - rpass(a,d128,16); - r64(a); - c32((WDL_FFT_COMPLEX *)(a + 64)); -} - -static void r256(register WDL_FFT_REAL *a) -{ - rpass(a,d256,32); - r128(a); - c64((WDL_FFT_COMPLEX *)(a + 128)); -} - -static void r512(register WDL_FFT_REAL *a) -{ - rpass(a,d512,64); - r256(a); - c128((WDL_FFT_COMPLEX *)(a + 256)); -} - - -/* a[0...8n-1], w[0...n-1]; n even, n >= 8 */ -static void rpassbig(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - register WDL_FFT_REAL *b; - register unsigned int k; - - b = a + 4 * n; - - RZERO(a[0],a[1],b[0],b[1]); - R(a[2],a[3],b[2],b[3],w[0].re,w[0].im); - - k = n - 2; - do { - R(a[4],a[5],b[4],b[5],w[1].re,w[1].im); - R(a[6],a[7],b[6],b[7],w[2].re,w[2].im); - a += 4; - b += 4; - w += 2; - } while (k -= 2); - - RHALF(a[4],a[5],b[4],b[5]); - R(a[6],a[7],b[6],b[7],w[0].im,w[0].re); - - k = n - 2; - do { - R(a[8],a[9],b[8],b[9],w[-1].im,w[-1].re); - R(a[10],a[11],b[10],b[11],w[-2].im,w[-2].re); - a += 4; - b += 4; - w -= 2; - } while (k -= 2); -} - - -static void r1024(register WDL_FFT_REAL *a) -{ - rpassbig(a,d1024,128); - r512(a); - c256((WDL_FFT_COMPLEX *)(a + 512)); -} - -static void r2048(register WDL_FFT_REAL *a) -{ - rpassbig(a,d2048,256); - r1024(a); - c512((WDL_FFT_COMPLEX *)(a + 1024)); -} - - -static void r4096(register WDL_FFT_REAL *a) -{ - rpassbig(a,d4096,512); - r2048(a); - c1024((WDL_FFT_COMPLEX *)(a + 2048)); -} - -static void r8192(register WDL_FFT_REAL *a) -{ - rpassbig(a,d8192,1024); - r4096(a); - c2048((WDL_FFT_COMPLEX *)(a + 4096)); -} - -static void r16384(register WDL_FFT_REAL *a) -{ - rpassbig(a,d16384,2048); - r8192(a); - c4096((WDL_FFT_COMPLEX *)(a + 8192)); -} - -static void r32768(register WDL_FFT_REAL *a) -{ - rpassbig(a,d32768,4096); - r16384(a); - c8192((WDL_FFT_COMPLEX *)(a + 16384)); -} - - - -static void v4(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t3, t5, t6; - - t5 = a[0] + a[1]; - t6 = a[0] - a[1]; - t1 = t5 + a[2]; - t5 -= a[2]; - t3 = t6 + a[3]; - t6 -= a[3]; - a[0] = t1; - a[1] = t5; - a[2] = t3; - a[3] = t6; -} - -static void v8(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; - - t5 = a[0] + a[1]; - t2 = a[4] + a[6]; - t8 = t5 + a[2]; - t5 -= a[2]; - t1 = a[0] - a[1]; - t7 = t8 + t2; - t8 -= t2; - t3 = a[4] - a[6]; - a[0] = t7; - t6 = a[5] + a[7]; - a[1] = t8; - t7 = t5 + t6; - t5 -= t6; - t4 = a[5] - a[7]; - a[4] = t7; - t6 = t4 - t3; - t3 += t4; - a[5] = t5; - t3 *= sqrthalf; - t2 = t1 + a[3]; - t1 -= a[3]; - t6 *= sqrthalf; - t7 = t2 - t3; - t3 += t2; - t8 = t1 - t6; - t6 += t1; - a[3] = t7; - a[7] = t8; - a[2] = t3; - a[6] = t6; -} - -/* a[0...8n-1], w[0...2n-1]; n even, n >= 4 */ -static void vpass(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - register WDL_FFT_REAL *b; - register unsigned int k; - - b = a + 4 * n; - k = n - 2; - - VZERO(a[0],a[1],b[0],b[1]); - V(a[2],a[3],b[2],b[3],w[0].re,w[0].im); - V(a[4],a[5],b[4],b[5],w[1].re,w[1].im); - V(a[6],a[7],b[6],b[7],w[2].re,w[2].im); - - for (;;) { - V(a[8],a[9],b[8],b[9],w[3].re,w[3].im); - V(a[10],a[11],b[10],b[11],w[4].re,w[4].im); - V(a[12],a[13],b[12],b[13],w[5].re,w[5].im); - V(a[14],a[15],b[14],b[15],w[6].re,w[6].im); - if (!(k -= 2)) break; - a += 8; - b += 8; - w += 4; - } -} - -static void v16(register WDL_FFT_REAL *a) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - - u4((WDL_FFT_COMPLEX *)(a + 8)); - v8(a); - VZERO(a[0],a[1],a[8],a[9]); - V(a[2],a[3],a[10],a[11],d16[0].re,d16[0].im); - V(a[4],a[5],a[12],a[13],d16[1].re,d16[1].im); - V(a[6],a[7],a[14],a[15],d16[2].re,d16[2].im); -} - -static void v32(register WDL_FFT_REAL *a) -{ - u8((WDL_FFT_COMPLEX *)(a + 16)); - v16(a); - vpass(a,d32,4); -} - -static void v64(register WDL_FFT_REAL *a) -{ - u16((WDL_FFT_COMPLEX *)(a + 32)); - v32(a); - vpass(a,d64,8); -} - -static void v128(register WDL_FFT_REAL *a) -{ - u32((WDL_FFT_COMPLEX *)(a + 64)); - v64(a); - vpass(a,d128,16); -} - -static void v256(register WDL_FFT_REAL *a) -{ - u64((WDL_FFT_COMPLEX *)(a + 128)); - v128(a); - vpass(a,d256,32); -} - -static void v512(register WDL_FFT_REAL *a) -{ - u128((WDL_FFT_COMPLEX *)(a + 256)); - v256(a); - vpass(a,d512,64); -} - - - -/* a[0...8n-1], w[0...n-1]; n even, n >= 8 */ -static void vpassbig(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) -{ - register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; - register WDL_FFT_REAL *b; - register unsigned int k; - - b = a + 4 * n; - - VZERO(a[0],a[1],b[0],b[1]); - V(a[2],a[3],b[2],b[3],w[0].re,w[0].im); - - k = n - 2; - do { - V(a[4],a[5],b[4],b[5],w[1].re,w[1].im); - V(a[6],a[7],b[6],b[7],w[2].re,w[2].im); - a += 4; - b += 4; - w += 2; - } while (k -= 2); - - VHALF(a[4],a[5],b[4],b[5]); - V(a[6],a[7],b[6],b[7],w[0].im,w[0].re); - - k = n - 2; - do { - V(a[8],a[9],b[8],b[9],w[-1].im,w[-1].re); - V(a[10],a[11],b[10],b[11],w[-2].im,w[-2].re); - a += 4; - b += 4; - w -= 2; - } while (k -= 2); -} - - -static void v1024(register WDL_FFT_REAL *a) -{ - u256((WDL_FFT_COMPLEX *)(a + 512)); - v512(a); - vpassbig(a,d1024,128); -} - -static void v2048(register WDL_FFT_REAL *a) -{ - u512((WDL_FFT_COMPLEX *)(a + 1024)); - v1024(a); - vpassbig(a,d2048,256); -} - - -static void v4096(register WDL_FFT_REAL *a) -{ - u1024((WDL_FFT_COMPLEX *)(a + 2048)); - v2048(a); - vpassbig(a,d4096,512); -} - -static void v8192(register WDL_FFT_REAL *a) -{ - u2048((WDL_FFT_COMPLEX *)(a + 4096)); - v4096(a); - vpassbig(a,d8192,1024); -} - -static void v16384(register WDL_FFT_REAL *a) -{ - u4096((WDL_FFT_COMPLEX *)(a + 8192)); - v8192(a); - vpassbig(a,d16384,2048); -} - -static void v32768(register WDL_FFT_REAL *a) -{ - u8192((WDL_FFT_COMPLEX *)(a + 16384)); - v16384(a); - vpassbig(a,d32768,4096); -} - - -void WDL_real_fft(WDL_FFT_REAL *buf, int len, int isInverse) -{ - switch (len) - { - case 2: r2(buf); break; -#define TMP(x) case x: if (!isInverse) r##x(buf); else v##x(buf); break; - TMP(4) - TMP(8) - TMP(16) - TMP(32) - TMP(64) - TMP(128) - TMP(256) - TMP(512) - TMP(1024) - TMP(2048) - TMP(4096) - TMP(8192) - TMP(16384) - TMP(32768) -#undef TMP - } -} - -#endif diff --git a/WDL/fft.h b/WDL/fft.h deleted file mode 100644 index 0d2dc9b2..00000000 --- a/WDL/fft.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - WDL - fft.h - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - - This file defines the interface to the WDL FFT library. These routines are based on the - DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com - - The DJB FFT web page is: http://cr.yp.to/djbfft.html - -*/ - -#ifndef _WDL_FFT_H_ -#define _WDL_FFT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef WDL_FFT_REALSIZE -#define WDL_FFT_REALSIZE 4 -#endif - -#if WDL_FFT_REALSIZE == 4 -typedef float WDL_FFT_REAL; -#elif WDL_FFT_REALSIZE == 8 -typedef double WDL_FFT_REAL; -#else -#error invalid FFT item size -#endif - -typedef struct { - WDL_FFT_REAL re; - WDL_FFT_REAL im; -} WDL_FFT_COMPLEX; - -extern void WDL_fft_init(); - -extern void WDL_fft_complexmul(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, int len); -extern void WDL_fft_complexmul2(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); -extern void WDL_fft_complexmul3(WDL_FFT_COMPLEX *destAdd, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); - -extern void WDL_fft(WDL_FFT_COMPLEX *, int len, int isInverse); - -#if 0 // these dont work right! -extern void WDL_fft_realmul(WDL_FFT_REAL *dest, WDL_FFT_REAL *src, int len); -extern void WDL_real_fft(WDL_FFT_REAL *, int len, int isInverse); -#endif - -int WDL_fft_permute(int fftsize, int idx); - -#ifdef __cplusplus -}; -#endif - -#endif \ No newline at end of file diff --git a/WDL/filebrowse.cpp b/WDL/filebrowse.cpp deleted file mode 100644 index 57bd7134..00000000 --- a/WDL/filebrowse.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// todo: support win7/vista extensions rather than GetOpenFileName? -- merge win7filedialog into here. - - -#include "filebrowse.h" - -#include "win32_utf8.h" -#include "wdlcstring.h" - - -#ifdef _WIN32 - #define PREF_DIRCH '\\' - #ifdef _MSC_VER // todo: win7filedialog.cpp support for mingw32 - #define WDL_FILEBROWSE_WIN7VISTAMODE - #endif -#else - #define PREF_DIRCH '/' -#endif - - - - -#ifdef WDL_FILEBROWSE_WIN7VISTAMODE // win7/vista file dialog support - #include "win7filedialog.cpp" - - // stuff since win7filedialog.h collides with shlobj.h below - #define tagSHCONTF tagSHCONTF___ - #define SHCONTF SHCONTF___ - #define SHCONTF_FOLDERS SHCONTF_FOLDERS___ - #define SHCONTF_NONFOLDERS SHCONTF_NONFOLDERS___ - #define SHCONTF_INCLUDEHIDDEN SHCONTF_INCLUDEHIDDEN___ - #define SHCONTF_SHAREABLE SHCONTF_SHAREABLE__ - #define SHCONTF_INIT_ON_FIRST_NEXT SHCONTF_INIT_ON_FIRST_NEXT__ - #define SHCONTF_NETPRINTERSRCH SHCONTF_NETPRINTERSRCH__ - #define SHCONTF_STORAGE SHCONTF_STORAGE__ -#endif - - -#ifdef _WIN32 -// include after win7filedialog.* - - #include - #include -#endif - -#ifndef BIF_NEWDIALOGSTYLE - #define BIF_NEWDIALOGSTYLE 0x40 -#endif - - -static void WDL_fixfnforopenfn(char *buf) -{ - char *p=buf; - while (*p) - { - if (*p == '/' || *p == '\\') *p=PREF_DIRCH; - p++; - } -#ifdef _WIN32 - if (buf[0] && buf[1] == ':') - { - p=buf+2; - char *op=p; - while (*p) - { - while (p[0]=='\\' && p[1] == '\\') p++; - *op++ = *p++; - } - *op=0; - } -#endif -} - - -#ifdef _WIN32 -static int CALLBACK WINAPI WDL_BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) -{ - switch (uMsg) - { - case BFFM_INITIALIZED: - if (lpData && ((char *)lpData)[0]) SendMessage(hwnd,BFFM_SETSELECTION,1,(LPARAM)lpData); - break; - } - return 0; -} -#endif - - -bool WDL_ChooseDirectory(HWND parent, const char *text, const char *initialdir, char *fn, int fnsize, bool preservecwd) -{ - char olddir[2048]; - GetCurrentDirectory(sizeof(olddir),olddir); -#ifdef _WIN32 - char name[4096]; - lstrcpyn_safe(name,initialdir?initialdir:"",sizeof(name)); - BROWSEINFO bi={parent,NULL, name, text, BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE, WDL_BrowseCallbackProc, (LPARAM)name,}; - LPITEMIDLIST idlist = SHBrowseForFolder( &bi ); - if (idlist) - { - SHGetPathFromIDList( idlist, name ); - IMalloc *m; - SHGetMalloc(&m); - m->Free(idlist); - lstrcpyn_safe(fn,name,fnsize); - return true; - } - return false; - -#else - bool r = BrowseForDirectory(text,initialdir,fn,fnsize); - if (preservecwd) SetCurrentDirectory(olddir); - return r; -#endif -} - -static const char *stristr(const char* a, const char* b) -{ - int i; - int len = strlen(b); - int n = strlen(a)-len; - for (i = 0; i <= n; ++i) - if (!strnicmp(a+i, b, len)) - return a+i; - return NULL; -} - -bool WDL_ChooseFileForSave(HWND parent, - const char *text, - const char *initialdir, - const char *initialfile, - const char *extlist, - const char *defext, - bool preservecwd, - char *fn, - int fnsize, - const char *dlgid, - void *dlgProc, -#ifdef _WIN32 - HINSTANCE hInstance -#else - struct SWELL_DialogResourceIndex *reshead -#endif - ) -{ - char cwd[2048]; - GetCurrentDirectory(sizeof(cwd),cwd); - -#ifdef _WIN32 - char temp[4096]; - memset(temp,0,sizeof(temp)); - if (initialfile) lstrcpyn_safe(temp,initialfile,sizeof(temp)); - WDL_fixfnforopenfn(temp); - -#ifdef WDL_FILEBROWSE_WIN7VISTAMODE - { - Win7FileDialog fd(text, 1); - if(fd.inited()) - { - fd.addOptions(FOS_DONTADDTORECENT); - //vista+ file open dialog - char olddir[2048]; - GetCurrentDirectory(sizeof(olddir),olddir); - - fd.setFilterList(extlist); - if (defext) - { - fd.setDefaultExtension(defext); - - int i = 0; - const char *p = extlist; - while(*p) - { - if(*p) p+=strlen(p)+1; - if(!*p) break; - if(stristr(p, defext)) - { - fd.setFileTypeIndex(i+1); - break; - } - i++; - p+=strlen(p)+1; - } - } - fd.setFolder(initialdir?initialdir:olddir, 0); - if(initialfile) - { - //check for folder name - char *p = temp+strlen(temp); - while(p>temp && *p!='/' && *p!='\\') p--; - if(*p=='/'||*p=='\\') - { - //folder found - *p=0; - fd.setFolder(temp, 0); - fd.setFilename(p+1); - } - else - fd.setFilename(temp); - } - fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); - - if(fd.show(parent)) - { - //ifilesavedialog saves the last folder automatically - fd.getResult(fn, fnsize); - - if (preservecwd) SetCurrentDirectory(olddir); - return true; - } - - if (preservecwd) SetCurrentDirectory(olddir); - return NULL; - } - } -#endif - - - OPENFILENAME l={sizeof(l),parent, hInstance, extlist, NULL,0, 0, temp, sizeof(temp)-1, NULL, 0, initialdir&&initialdir[0] ? initialdir : cwd, text, - OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT,0,0,defext, 0, (LPOFNHOOKPROC)dlgProc, dlgid}; - - if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; - if (preservecwd) l.Flags |= OFN_NOCHANGEDIR; - - if (!GetSaveFileName(&l)||!temp[0]) - { - if (preservecwd) SetCurrentDirectory(cwd); - return false; - } - if (preservecwd) SetCurrentDirectory(cwd); - lstrcpyn_safe(fn,temp,fnsize); - return true; - -#else - BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); - char if_temp[4096]; - if (initialfile) - { - lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); - WDL_fixfnforopenfn(if_temp); - initialfile = if_temp; - } - - bool r = BrowseForSaveFile(text,initialdir,initialfile,extlist,fn,fnsize); - - if (preservecwd) SetCurrentDirectory(cwd); - - return r; -#endif -} - - -char *WDL_ChooseFileForOpen(HWND parent, - const char *text, - const char *initialdir, - const char *initialfile, - const char *extlist, - const char *defext, - - bool preservecwd, - bool allowmul, - - const char *dlgid, - void *dlgProc, -#ifdef _WIN32 - HINSTANCE hInstance -#else - struct SWELL_DialogResourceIndex *reshead -#endif - ) -{ - char olddir[2048]; - GetCurrentDirectory(sizeof(olddir),olddir); - -#ifdef _WIN32 - -#ifdef WDL_FILEBROWSE_WIN7VISTAMODE - if (!allowmul) // todo : check impl of multiple select, too? - { - Win7FileDialog fd(text); - if(fd.inited()) - { - //vista+ file open dialog - fd.addOptions(FOS_FILEMUSTEXIST); - fd.setFilterList(extlist); - if (defext) - { - fd.setDefaultExtension(defext); - - int i = 0; - const char *p = extlist; - while(*p) - { - if(*p) p+=strlen(p)+1; - if(!*p) break; - if(stristr(p, defext)) - { - fd.setFileTypeIndex(i+1); - break; - } - i++; - p+=strlen(p)+1; - } - } - fd.setFolder(initialdir?initialdir:olddir, 0); - fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); - if(initialfile) - { - char temp[4096]; - lstrcpyn_safe(temp,initialfile,sizeof(temp)); - //check for folder name - char *p = temp+strlen(temp); - while(p>temp && *p!='/' && *p!='\\') p--; - if(*p=='/'||*p=='\\') - { - //folder found - *p=0; - fd.setFolder(temp, 0); - fd.setFilename(p+1); - } - else - fd.setFilename(temp); - } - - if(fd.show(parent)) - { - char temp[4096]; - temp[0]=0; - //ifileopendialog saves the last folder automatically - fd.getResult(temp, sizeof(temp)-1); - - - - if (preservecwd) SetCurrentDirectory(olddir); - return temp[0] ? strdup(temp) : NULL; - } - - if (preservecwd) SetCurrentDirectory(olddir); - return NULL; - } - } -#endif - - int temp_size = allowmul ? 256*1024-1 : 4096-1; - char *temp = (char *)calloc(temp_size+1,1); - - OPENFILENAME l={sizeof(l), parent, hInstance, extlist, NULL, 0, 0, temp, temp_size, NULL, 0, initialdir, text, - OFN_HIDEREADONLY|OFN_EXPLORER|OFN_FILEMUSTEXIST,0,0, (char *)(defext ? defext : ""), 0, (LPOFNHOOKPROC)dlgProc, dlgid}; - - if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; - if (allowmul) l.Flags|=OFN_ALLOWMULTISELECT; - if (preservecwd) l.Flags|=OFN_NOCHANGEDIR; - - if (initialfile) lstrcpyn_safe(temp,initialfile,temp_size); - - WDL_fixfnforopenfn(temp); - - if (!l.lpstrInitialDir||!l.lpstrInitialDir[0]) l.lpstrInitialDir=olddir; - - int r = GetOpenFileName(&l); - if (preservecwd) SetCurrentDirectory(olddir); - - if (!r) free(temp); - return r?temp:NULL; - -#else - char if_temp[4096]; - if (initialfile) - { - lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); - WDL_fixfnforopenfn(if_temp); - initialfile = if_temp; - } - - // defext support? - BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); - char *ret = BrowseForFiles(text,initialdir,initialfile,allowmul,extlist); - if (preservecwd) SetCurrentDirectory(olddir); - - return ret; -#endif -} diff --git a/WDL/filebrowse.h b/WDL/filebrowse.h deleted file mode 100644 index 642c254f..00000000 --- a/WDL/filebrowse.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _WDL_FILEBROWSE_H_ -#define _WDL_FILEBROWSE_H_ - -#ifdef _WIN32 -#include -#else -#include "swell/swell.h" -#endif - - -bool WDL_ChooseDirectory(HWND parent, const char *text, const char *initialdir, char *fn, int fnsize, bool preservecwd); -bool WDL_ChooseFileForSave(HWND parent, - const char *text, - const char *initialdir, - const char *initialfile, - const char *extlist, - const char *defext, - bool preservecwd, - char *fn, - int fnsize, - const char *dlgid=NULL, - void *dlgProc=NULL, -#ifdef _WIN32 - HINSTANCE hInstance=NULL -#else - struct SWELL_DialogResourceIndex *reshead=NULL -#endif - ); - - -char *WDL_ChooseFileForOpen(HWND parent, - const char *text, - const char *initialdir, - const char *initialfile, - const char *extlist, - const char *defext, - - bool preservecwd, - bool allowmul, - - const char *dlgid=NULL, - void *dlgProc=NULL, -#ifdef _WIN32 - HINSTANCE hInstance=NULL -#else - struct SWELL_DialogResourceIndex *reshead=NULL -#endif - ); - - - -#endif \ No newline at end of file diff --git a/WDL/filename.h b/WDL/filename.h deleted file mode 100644 index 763de3d1..00000000 --- a/WDL/filename.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - WDL - filename.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -#ifndef _WDL_FILENAME_H_ -#define _WDL_FILENAME_H_ - -#include -#include - - -char WDL_filename_filterchar(char p, char repl='_', bool filterSlashes=true) -{ - if (p == '?' || - p == '*' || - p == ':' || - p == '\"' || - p == '|' || - p == '<' || - p == '>') - { - return repl; - } - - if (filterSlashes && (p == '/' || p == '\\' )) - { - return repl; - } - - return p; -} - - -void WDL_filename_filterstr(char *buf, char repl='_', bool filterSlashes=true) -{ - char *rd = buf; - while (*rd) - { - char r=WDL_filename_filterchar(*rd++,repl,filterSlashes); - if (r) *buf++ = r; - } - *buf=0; -} - - - -#endif // _WDL_FILENAME_H_ \ No newline at end of file diff --git a/WDL/fileread.h b/WDL/fileread.h deleted file mode 100644 index 77960515..00000000 --- a/WDL/fileread.h +++ /dev/null @@ -1,796 +0,0 @@ -/* - WDL - fileread.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides the WDL_FileRead object, which can be used to read files. - On windows systems it supports reading synchronous, asynchronous, memory mapped, and asynchronous unbuffered. - On non-windows systems it acts as a wrapper for fopen()/etc. - - -*/ - - -#ifndef _WDL_FILEREAD_H_ -#define _WDL_FILEREAD_H_ - - - - -#include "ptrlist.h" - - - -#if defined(_WIN32) && !defined(WDL_NO_WIN32_FILEREAD) - #ifndef WDL_WIN32_NATIVE_READ - #define WDL_WIN32_NATIVE_READ - #endif -#else - #ifdef WDL_WIN32_NATIVE_READ - #undef WDL_WIN32_NATIVE_READ - #endif - - #if !defined(WDL_NO_POSIX_FILEREAD) - #define WDL_POSIX_NATIVE_READ - #include - #include - #include - #include - #ifdef __APPLE__ - #include - #include - #endif - #endif - -#endif - - - -#ifdef _MSC_VER -#define WDL_FILEREAD_POSTYPE __int64 -#else -#define WDL_FILEREAD_POSTYPE long long -#endif -class WDL_FileRead -{ - -#ifdef WDL_WIN32_NATIVE_READ - - -class WDL_FileRead__ReadEnt -{ -public: - WDL_FileRead__ReadEnt(int sz, char *buf) - { - m_size=0; - memset(&m_ol,0,sizeof(m_ol)); - m_ol.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL); - m_buf=buf; - } - ~WDL_FileRead__ReadEnt() - { - CloseHandle(m_ol.hEvent); - } - - OVERLAPPED m_ol; - DWORD m_size; - LPVOID m_buf; -}; - -#endif - -#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) - BOOL HasUTF8(const char *_str) - { - const unsigned char *str = (const unsigned char *)_str; - if (!str) return FALSE; - while (*str) - { - unsigned char c = *str; - if (c >= 0xC2) - { - if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; - else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - } - str++; - } - return FALSE; - } -#endif - -public: - // allow_async=1 for unbuffered async, 2 for buffered async, =-1 for unbuffered sync - // async aspect is unused on OS X, but the buffered mode affects F_NOCACHE - WDL_FileRead(const char *filename, int allow_async=1, int bufsize=8192, int nbufs=4, unsigned int mmap_minsize=0, unsigned int mmap_maxsize=0) : m_bufspace(4096 WDL_HEAPBUF_TRACEPARM("WDL_FileRead")) - { - m_async_hashaderr=false; - m_sync_bufmode_used=m_sync_bufmode_pos=0; - m_async_readpos=m_file_position=0; - m_fsize=0; - m_fsize_maychange=false; - m_syncrd_firstbuf=true; - m_mmap_view=0; - m_mmap_totalbufmode=0; - -#define WDL_UNBUF_ALIGN 8192 - if (bufsize&(WDL_UNBUF_ALIGN-1)) bufsize=(bufsize&~(WDL_UNBUF_ALIGN-1))+WDL_UNBUF_ALIGN; // ensure bufsize is multiple of 4kb - -#ifdef WDL_WIN32_NATIVE_READ - - m_mmap_fmap=0; - bool isNT = GetVersion()<0x80000000; - m_async = isNT ? allow_async : 0; - - int flags=FILE_ATTRIBUTE_NORMAL; - if (m_async>0) - { - flags|=FILE_FLAG_OVERLAPPED; - if (m_async==1) flags|=FILE_FLAG_NO_BUFFERING; - } - else if (nbufs*bufsize>=WDL_UNBUF_ALIGN && !mmap_maxsize && m_async==-1) - flags|=FILE_FLAG_NO_BUFFERING; // non-async mode unbuffered if we do our own buffering - -#ifndef WDL_NO_SUPPORT_UTF8 - m_fh = INVALID_HANDLE_VALUE; - if (isNT && HasUTF8(filename)) // only convert to wide if there are UTF-8 chars - { - int szreq=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,NULL,0); - if (szreq > 1000) - { - WDL_TypedBuf wfilename; - wfilename.Resize(szreq+10); - - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename.Get(),wfilename.GetSize())) - { - m_fh = CreateFileW(wfilename.Get(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); - if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) - { - m_fh = CreateFileW(wfilename.Get(),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); - m_fsize_maychange=true; - } - } - } - else - { - WCHAR wfilename[1024]; - - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename,1024)) - { - m_fh = CreateFileW(wfilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); - if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) - { - m_fh = CreateFileW(wfilename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); - m_fsize_maychange=true; - } - } - } - } - if (m_fh == INVALID_HANDLE_VALUE) -#endif - { - m_fh = CreateFileA(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); - if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) - { - m_fh = CreateFileA(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); - m_fsize_maychange=true; - } - } - - if (m_fh != INVALID_HANDLE_VALUE) - { - DWORD h=0; - DWORD l=GetFileSize(m_fh,&h); - m_fsize=(((WDL_FILEREAD_POSTYPE)h)<<32)|l; - - if (!h && l < mmap_maxsize && m_async<=0) - { - if (l >= mmap_minsize) - { - m_mmap_fmap=CreateFileMapping(m_fh,NULL,PAGE_READONLY,NULL,0,NULL); - if (m_mmap_fmap) - { - m_mmap_view=MapViewOfFile(m_mmap_fmap,FILE_MAP_READ,0,0,(int)m_fsize); - if (!m_mmap_view) - { - CloseHandle(m_mmap_fmap); - m_mmap_fmap=0; - } - else m_fsize_maychange=false; - } - } - else if (l>0) - { - m_mmap_totalbufmode = malloc(l); - DWORD sz; - ReadFile(m_fh,m_mmap_totalbufmode,l,&sz,NULL); - m_fsize_maychange=false; - } - } - - if (m_async>0) - { - m_async_bufsize=bufsize; - int x; - char *bptr=(char *)m_bufspace.Resize(nbufs*bufsize + (WDL_UNBUF_ALIGN-1)); - int a=((int)(INT_PTR)bptr)&(WDL_UNBUF_ALIGN-1); - if (a) bptr += WDL_UNBUF_ALIGN-a; - for (x = 0; x < nbufs; x ++) - { - WDL_FileRead__ReadEnt *t=new WDL_FileRead__ReadEnt(m_async_bufsize,bptr); - m_empties.Add(t); - bptr+=m_async_bufsize; - } - } - else if (!m_mmap_view && !m_mmap_totalbufmode && nbufs*bufsize>=WDL_UNBUF_ALIGN) - { - m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); - } - } - -#elif defined(WDL_POSIX_NATIVE_READ) - m_filedes_locked=false; - m_filedes_rdpos=0; - m_filedes=open(filename,O_RDONLY); - if (m_filedes>=0) - { - if (flock(m_filedes,LOCK_SH|LOCK_NB)>=0) // get shared lock - m_filedes_locked=true; - else - m_fsize_maychange=true; // if couldnt get shared lock, then it may change - -#ifdef __APPLE__ - if (allow_async==1 || allow_async==-1) - { - struct statfs sfs; - if (fstatfs(m_filedes,&sfs)||(sfs.f_flags&MNT_LOCAL)) // don't use F_NOCACHE on nfs/smb/afp mounts, we need caching there! - fcntl(m_filedes,F_NOCACHE,1); - } -#endif - m_fsize=lseek(m_filedes,0,SEEK_END); - lseek(m_filedes,0,SEEK_SET); - - if (m_fsize < mmap_maxsize) - { - if (m_fsize >= mmap_minsize) - { - m_mmap_view = mmap(NULL,m_fsize,PROT_READ,MAP_SHARED,m_filedes,0); - if (m_mmap_view == MAP_FAILED) m_mmap_view = 0; - else m_fsize_maychange=false; - } - else - { - m_mmap_totalbufmode = malloc(m_fsize); - m_fsize = pread(m_filedes,m_mmap_totalbufmode,m_fsize,0); - m_fsize_maychange=false; - } - } - - } - if (!m_mmap_view && !m_mmap_totalbufmode && m_filedes>=0 && nbufs*bufsize>=WDL_UNBUF_ALIGN) - m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); - -#else - m_fp=fopen(filename,"rb"); - if(m_fp) - { - fseek(m_fp,0,SEEK_END); - m_fsize=ftell(m_fp); - fseek(m_fp,0,SEEK_SET); - } - if (m_fp && nbufs*bufsize>=WDL_UNBUF_ALIGN) - m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); -#endif - } - - ~WDL_FileRead() - { - free(m_mmap_totalbufmode); - m_mmap_totalbufmode=0; - -#ifdef WDL_WIN32_NATIVE_READ - int x; - for (x = 0; x < m_empties.GetSize();x ++) delete m_empties.Get(x); - m_empties.Empty(); - for (x = 0; x < m_full.GetSize();x ++) delete m_full.Get(x); - m_full.Empty(); - for (x = 0; x < m_pending.GetSize();x ++) - { - WaitForSingleObject(m_pending.Get(x)->m_ol.hEvent,INFINITE); - delete m_pending.Get(x); - } - m_pending.Empty(); - - if (m_mmap_view) UnmapViewOfFile(m_mmap_view); - m_mmap_view=0; - - if (m_mmap_fmap) CloseHandle(m_mmap_fmap); - m_mmap_fmap=0; - - if (m_fh != INVALID_HANDLE_VALUE) CloseHandle(m_fh); - m_fh=INVALID_HANDLE_VALUE; -#elif defined(WDL_POSIX_NATIVE_READ) - if (m_mmap_view) munmap(m_mmap_view,m_fsize); - m_mmap_view=0; - if (m_filedes>=0) - { - if (m_filedes_locked) flock(m_filedes,LOCK_UN); // release shared lock - close(m_filedes); - } - m_filedes=-1; -#else - if (m_fp) fclose(m_fp); - m_fp=0; -#endif - - } - - bool IsOpen() - { -#ifdef WDL_WIN32_NATIVE_READ - return (m_fh != INVALID_HANDLE_VALUE); -#elif defined(WDL_POSIX_NATIVE_READ) - return m_filedes >= 0; -#else - return m_fp != NULL; -#endif - } - -#ifdef WDL_WIN32_NATIVE_READ - - int RunReads() - { - int retval=0; - - while (m_pending.GetSize()) - { - WDL_FileRead__ReadEnt *ent=m_pending.Get(0); - DWORD s=0; - - if (!ent->m_size && !GetOverlappedResult(m_fh,&ent->m_ol,&s,FALSE)) break; - m_pending.Delete(0); - if (!ent->m_size) ent->m_size=s; - m_full.Add(ent); - } - - - int x=m_empties.GetSize(); - - if (x>0) - { - int cnt=0; - if (m_async_readpos < m_file_position) m_async_readpos = m_file_position; - - if (m_async==1) m_async_readpos &= ~((WDL_FILEREAD_POSTYPE) WDL_UNBUF_ALIGN-1); - - while (x>0) - { - - if (m_async_readpos >= m_fsize) break; - - WDL_FileRead__ReadEnt *t=m_empties.Get(--x); - - ResetEvent(t->m_ol.hEvent); - - *(WDL_FILEREAD_POSTYPE *)&t->m_ol.Offset = m_async_readpos; - - m_async_readpos += m_async_bufsize; - DWORD dw; - if (ReadFile(m_fh,t->m_buf,m_async_bufsize,&dw,&t->m_ol)) - { - if (!dw) - { - retval++; - break; - } - - m_empties.Delete(x); - t->m_size=dw; - m_pending.Add(t); - } - else - { - if (GetLastError() != ERROR_IO_PENDING) - { - retval++; - break; - } - t->m_size=0; - m_empties.Delete(x); - m_pending.Add(t); - } - //if (cnt++>1) - break; - } - } - return retval; - } - - int AsyncRead(char *buf, int maxlen) - { - char *obuf=buf; - int lenout=0; - if (m_file_position+maxlen > m_fsize) - { - maxlen=(int) (m_fsize-m_file_position); - } - if (maxlen<1) return 0; - - int errcnt=!!m_async_hashaderr; - do - { - while (m_full.GetSize() > 0) - { - WDL_FileRead__ReadEnt *ti=m_full.Get(0); - WDL_FILEREAD_POSTYPE tiofs=*(WDL_FILEREAD_POSTYPE *)&ti->m_ol.Offset; - if (m_file_position >= tiofs && m_file_position < tiofs + ti->m_size) - { - if (maxlen < 1) break; - - int l=ti->m_size-(int) (m_file_position-tiofs); - if (l > maxlen) l=maxlen; - - memcpy(buf,(char *)ti->m_buf+m_file_position - tiofs,l); - buf += l; - m_file_position += l; - maxlen -= l; - lenout += l; - } - else - { - m_empties.Add(ti); - m_full.Delete(0); - } - } - - if (maxlen > 0 && m_async_readpos != m_file_position) - { - int x; - for (x = 0; x < m_pending.GetSize(); x ++) - { - WDL_FileRead__ReadEnt *ent=m_pending.Get(x); - WDL_FILEREAD_POSTYPE tiofs=*(WDL_FILEREAD_POSTYPE *)&ent->m_ol.Offset; - if (m_file_position >= tiofs && m_file_position < tiofs + m_async_bufsize) break; - } - if (x == m_pending.GetSize()) - { - m_async_readpos=m_file_position; - } - } - - errcnt+=RunReads(); - - if (maxlen > 0 && m_pending.GetSize() && !m_full.GetSize()) - { - WDL_FileRead__ReadEnt *ent=m_pending.Get(0); - m_pending.Delete(0); - - if (ent->m_size) m_full.Add(ent); - else - { -// WaitForSingleObject(ent->m_ol.hEvent,INFINITE); - - DWORD s=0; - if (GetOverlappedResult(m_fh,&ent->m_ol,&s,TRUE) && s) - { - ent->m_size=s; - m_full.Add(ent); - } - else // failed read, set the error flag - { - errcnt++; - ent->m_size=0; - m_empties.Add(ent); - } - } - } - } - while (maxlen > 0 && (m_pending.GetSize()||m_full.GetSize()) && !errcnt); - if (!errcnt) RunReads(); - else m_async_hashaderr=true; - - return lenout; - } - -#endif - - void *GetMappedView(int offs, int *len) - { - if (!m_mmap_view && !m_mmap_totalbufmode) return 0; - - int maxl=(int) (m_fsize-(WDL_FILEREAD_POSTYPE)offs); - if (*len > maxl) *len=maxl; - if (m_mmap_view) - return (char *)m_mmap_view + offs; - else - return (char *)m_mmap_totalbufmode + offs; - } - - int Read(void *buf, int len) - { - if (m_mmap_view||m_mmap_totalbufmode) - { - int maxl=(int) (m_fsize-m_file_position); - if (maxl > len) maxl=len; - if (maxl < 0) maxl=0; - if (maxl>0) - { - if (m_mmap_view) - memcpy(buf,(char *)m_mmap_view + (int)m_file_position,maxl); - else - memcpy(buf,(char *)m_mmap_totalbufmode + (int)m_file_position,maxl); - - } - m_file_position+=maxl; - return maxl; - } - - if (m_fsize_maychange) GetSize(); // update m_fsize - -#ifdef WDL_WIN32_NATIVE_READ - if (m_fh == INVALID_HANDLE_VALUE||len<1) return 0; - - if (m_async>0) - { - return AsyncRead((char *)buf,len); - } -#elif defined(WDL_POSIX_NATIVE_READ) - if (m_filedes<0 || len<1) return 0; - -#else - if (!m_fp || len<1) return 0; - -#endif - - if (m_bufspace.GetSize()>=WDL_UNBUF_ALIGN*2-1) - { - int rdout=0; - int sz=m_bufspace.GetSize()-(WDL_UNBUF_ALIGN-1); - char *srcbuf=(char *)m_bufspace.Get(); // read size - if (((int)(INT_PTR)srcbuf)&(WDL_UNBUF_ALIGN-1)) srcbuf += WDL_UNBUF_ALIGN-(((int)(INT_PTR)srcbuf)&(WDL_UNBUF_ALIGN-1)); - while (len > rdout) - { - int a=m_sync_bufmode_used-m_sync_bufmode_pos; - if (a>(len-rdout)) a=(len-rdout); - if (a>0) - { - memcpy((char*)buf+rdout,srcbuf+m_sync_bufmode_pos,a); - rdout+=a; - m_sync_bufmode_pos+=a; - m_file_position+=a; - } - - if (len > rdout) - { - m_sync_bufmode_used=0; - m_sync_bufmode_pos=0; - - int thissz=sz; - if (m_syncrd_firstbuf) // this is a scheduling mechanism to avoid having reads on various files always happening at the same time -- not needed in async modes, only in sync with large buffers - { - m_syncrd_firstbuf=false; - int a= thissz/WDL_UNBUF_ALIGN; - if (a > 1) - { - static int rrs; // may not be ideal on multithread, but having it incorrect isnt a big deal. - if (a>7) thissz >>= (rrs++)&3; - else thissz>>= (rrs++)&1; - } - } - - #ifdef WDL_WIN32_NATIVE_READ - DWORD o; - if (m_async==-1) - { - if (m_file_position&(WDL_UNBUF_ALIGN-1)) - { - int offs = (int)(m_file_position&(WDL_UNBUF_ALIGN-1)); - LONG high=(LONG) ((m_file_position-offs)>>32); - SetFilePointer(m_fh,(LONG)((m_file_position-offs)&((WDL_FILEREAD_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN); - m_sync_bufmode_pos=offs; - } - } - if (!ReadFile(m_fh,srcbuf,thissz,&o,NULL) || o<1 || m_sync_bufmode_pos>=(int)o) - { - break; - } - #elif defined(WDL_POSIX_NATIVE_READ) - int o; - o=pread(m_filedes,srcbuf,thissz,m_filedes_rdpos); - if (o>0) m_filedes_rdpos+=o; - if (o<1 || m_sync_bufmode_pos>=o) break; - - #else - int o; - o=fread(srcbuf,1,thissz,m_fp); - if (o<1 || m_sync_bufmode_pos>=o) break; - #endif - m_sync_bufmode_used=o; - } - - } - return rdout; - } - else - { - #ifdef WDL_WIN32_NATIVE_READ - DWORD dw=0; - ReadFile(m_fh,buf,len,&dw,NULL); - m_file_position+=dw; - return dw; - #elif defined(WDL_POSIX_NATIVE_READ) - - int ret=pread(m_filedes,buf,len,m_filedes_rdpos); - if (ret>0) m_filedes_rdpos+=ret; - m_file_position+=ret; - return ret; - #else - int ret=fread(buf,1,len,m_fp); - m_file_position+=ret; - return ret; - #endif - } - - } - - WDL_FILEREAD_POSTYPE GetSize() - { -#ifdef WDL_WIN32_NATIVE_READ - if (m_fh == INVALID_HANDLE_VALUE) return 0; -#elif defined(WDL_POSIX_NATIVE_READ) - if (m_filedes<0) return -1; - -#else - if (!m_fp) return -1; -#endif - - if (m_fsize_maychange) - { -#ifdef WDL_WIN32_NATIVE_READ - DWORD h=0; - DWORD l=GetFileSize(m_fh,&h); - m_fsize=(((WDL_FILEREAD_POSTYPE)h)<<32)|l; -#elif defined(WDL_POSIX_NATIVE_READ) - struct stat st; - if (!fstat(m_filedes,&st)) m_fsize = st.st_size; - -#endif - } - - return m_fsize; - } - - WDL_FILEREAD_POSTYPE GetPosition() - { -#ifdef WDL_WIN32_NATIVE_READ - if (m_fh == INVALID_HANDLE_VALUE) return -1; -#elif defined(WDL_POSIX_NATIVE_READ) - if (m_filedes<0) return -1; -#else - if (!m_fp) return -1; -#endif - return m_file_position; - } - - bool SetPosition(WDL_FILEREAD_POSTYPE pos) // returns 0 on success - { - m_async_hashaderr=false; - -#ifdef WDL_WIN32_NATIVE_READ - if (m_fh == INVALID_HANDLE_VALUE) return true; -#elif defined(WDL_POSIX_NATIVE_READ) - if (m_filedes<0) return true; -#else - if (!m_fp) return true; -#endif - - if (m_fsize_maychange) GetSize(); - - if (pos < 0) pos=0; - if (pos > m_fsize) pos=m_fsize; - WDL_FILEREAD_POSTYPE oldpos=m_file_position; - if (m_file_position!=pos) m_file_position=pos; - else return false; - - if (m_mmap_view||m_mmap_totalbufmode) return false; - -#ifdef WDL_WIN32_NATIVE_READ - if (m_async>0) - { - WDL_FileRead__ReadEnt *ent; - - if (pos > m_async_readpos || !(ent=m_full.Get(0)) || pos < *(WDL_FILEREAD_POSTYPE *)&ent->m_ol.Offset) - { - m_async_readpos=pos; - } - - return FALSE; - } -#endif - - - if (m_bufspace.GetSize()>=WDL_UNBUF_ALIGN*2-1) - { - if (pos >= oldpos-m_sync_bufmode_pos && pos < oldpos-m_sync_bufmode_pos + m_sync_bufmode_used) - { - int diff=(int) (pos-oldpos); - m_sync_bufmode_pos+=diff; - - return 0; - } - m_sync_bufmode_pos=m_sync_bufmode_used=0; - } - - m_syncrd_firstbuf=true; -#ifdef WDL_WIN32_NATIVE_READ - LONG high=(LONG) (m_file_position>>32); - return SetFilePointer(m_fh,(LONG)(m_file_position&((WDL_FILEREAD_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN)==0xFFFFFFFF && GetLastError() != NO_ERROR; -#elif defined(WDL_POSIX_NATIVE_READ) - m_filedes_rdpos = m_file_position; - return false; -#else - return !!fseek(m_fp,m_file_position,SEEK_SET); -#endif - } - - WDL_HeapBuf m_bufspace; - int m_sync_bufmode_used, m_sync_bufmode_pos; - - WDL_FILEREAD_POSTYPE m_file_position,m_async_readpos; - WDL_FILEREAD_POSTYPE m_fsize; - - void *m_mmap_view; - void *m_mmap_totalbufmode; - -#ifdef WDL_WIN32_NATIVE_READ - HANDLE GetHandle() { return m_fh; } - HANDLE m_fh; - HANDLE m_mmap_fmap; - int m_mmap_size; - int m_async; // 1=nobuf, 2=buffered async, -1=unbuffered sync - - int m_async_bufsize; - WDL_PtrList m_empties; - WDL_PtrList m_pending; - WDL_PtrList m_full; - -#elif defined(WDL_POSIX_NATIVE_READ) - WDL_FILEREAD_POSTYPE m_filedes_rdpos; - int m_filedes; - bool m_filedes_locked; - - int GetHandle() { return m_filedes; } -#else - FILE *m_fp; - - int GetHandle() { return fileno(m_fp); } -#endif - - bool m_fsize_maychange; - bool m_syncrd_firstbuf; - bool m_async_hashaderr; - -} WDL_FIXALIGN; - - - - - - -#endif diff --git a/WDL/filewrite.h b/WDL/filewrite.h deleted file mode 100644 index 10233f18..00000000 --- a/WDL/filewrite.h +++ /dev/null @@ -1,642 +0,0 @@ -/* - WDL - filewrite.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides the WDL_FileWrite object, which can be used to create/write files. - On windows systems it supports writing synchronously, asynchronously, and asynchronously without buffering. - On windows systems it supports files larger than 4gb. - On non-windows systems it acts as a wrapper for fopen()/etc. - - -*/ - - -#ifndef _WDL_FILEWRITE_H_ -#define _WDL_FILEWRITE_H_ - - - - -#include "ptrlist.h" - - - -#if defined(_WIN32) && !defined(WDL_NO_WIN32_FILEWRITE) - #ifndef WDL_WIN32_NATIVE_WRITE - #define WDL_WIN32_NATIVE_WRITE - #endif -#else - #ifdef WDL_WIN32_NATIVE_WRITE - #undef WDL_WIN32_NATIVE_WRITE - #endif - #if !defined(WDL_NO_POSIX_FILEWRITE) - #include - #include - #include - #define WDL_POSIX_NATIVE_WRITE - #endif -#endif - - - -#ifdef _MSC_VER -#define WDL_FILEWRITE_POSTYPE __int64 -#else -#define WDL_FILEWRITE_POSTYPE long long -#endif - -//#define WIN32_ASYNC_NOBUF_WRITE // this doesnt seem to give much perf increase (writethrough with buffering is fine, since ultimately writes get deferred anyway) - -class WDL_FileWrite -{ -#ifdef WDL_WIN32_NATIVE_WRITE - -class WDL_FileWrite__WriteEnt -{ -public: - WDL_FileWrite__WriteEnt(int sz) - { - m_last_writepos=0; - m_bufused=0; - m_bufsz=sz; - m_bufptr = (char *)__buf.Resize(sz+4095); - int a=((int)(INT_PTR)m_bufptr)&4095; - if (a) m_bufptr += 4096-a; - - memset(&m_ol,0,sizeof(m_ol)); - m_ol.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL); - } - ~WDL_FileWrite__WriteEnt() - { - CloseHandle(m_ol.hEvent); - } - - WDL_FILEWRITE_POSTYPE m_last_writepos; - - int m_bufused,m_bufsz; - OVERLAPPED m_ol; - char *m_bufptr; - WDL_TypedBuf __buf; -}; - -#endif - -#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) - BOOL HasUTF8(const char *_str) - { - const unsigned char *str = (const unsigned char *)_str; - if (!str) return FALSE; - while (*str) - { - unsigned char c = *str; - if (c >= 0xC2) - { - if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; - else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - } - str++; - } - return FALSE; - } -#endif - - -public: - WDL_FileWrite(const char *filename, int allow_async=1, int bufsize=8192, int minbufs=16, int maxbufs=16, bool wantAppendTo=false, bool noFileLocking=false) // async==2 is unbuffered - { - m_file_position=0; - m_file_max_position=0; - if(!filename) - { -#ifdef WDL_WIN32_NATIVE_WRITE - m_fh = INVALID_HANDLE_VALUE; - m_async = 0; -#elif defined(WDL_POSIX_NATIVE_WRITE) - m_filedes_locked=false; - m_filedes=-1; - m_bufspace_used=0; -#else - m_fp = NULL; -#endif - return; - } - -#ifdef WDL_WIN32_NATIVE_WRITE - bool isNT = (GetVersion()<0x80000000); - m_async = allow_async && isNT; -#ifdef WIN32_ASYNC_NOBUF_WRITE - bufsize = (bufsize+4095)&~4095; - if (bufsize<4096) bufsize=4096; -#endif - - int rwflag = GENERIC_WRITE; - int createFlag= wantAppendTo?OPEN_ALWAYS:CREATE_ALWAYS; - int shareFlag = noFileLocking ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : FILE_SHARE_READ; - int flag = FILE_ATTRIBUTE_NORMAL; - - if (m_async) - { - rwflag |= GENERIC_READ; -#ifdef WIN32_ASYNC_NOBUF_WRITE - flag |= FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH; -#else - flag |= FILE_FLAG_OVERLAPPED|(allow_async>1 ? FILE_FLAG_WRITE_THROUGH: 0); -#endif - } - - { -#ifndef WDL_NO_SUPPORT_UTF8 - m_fh=INVALID_HANDLE_VALUE; - if (isNT && HasUTF8(filename)) - { - int szreq=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,NULL,0); - if (szreq > 1000) - { - WDL_TypedBuf wfilename; - wfilename.Resize(szreq+10); - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename.Get(),wfilename.GetSize())) - m_fh = CreateFileW(wfilename.Get(),rwflag,shareFlag,NULL,createFlag,flag,NULL); - } - else - { - WCHAR wfilename[1024]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename,1024)) - m_fh = CreateFileW(wfilename,rwflag,shareFlag,NULL,createFlag,flag,NULL); - } - } - - if (m_fh == INVALID_HANDLE_VALUE) -#endif - m_fh = CreateFileA(filename,rwflag,shareFlag,NULL,createFlag,flag,NULL); - } - - if (m_async && m_fh != INVALID_HANDLE_VALUE) - { - m_async_bufsize=bufsize; - m_async_maxbufs=maxbufs; - m_async_minbufs=minbufs; - int x; - for (x = 0; x < m_async_minbufs; x ++) - { - WDL_FileWrite__WriteEnt *t=new WDL_FileWrite__WriteEnt(m_async_bufsize); - m_empties.Add(t); - } - } - - if (m_fh != INVALID_HANDLE_VALUE && wantAppendTo) - SetPosition(GetSize()); - -#elif defined(WDL_POSIX_NATIVE_WRITE) - m_bufspace_used=0; - m_filedes_locked=false; - m_filedes=open(filename,O_WRONLY|O_CREAT,0644); - if (m_filedes>=0) - { - - if (!noFileLocking) - { - m_filedes_locked = !flock(m_filedes,LOCK_EX|LOCK_NB); - if (!m_filedes_locked) - { - // this check might not be necessary, it might be sufficient to just fail and close if no exclusive lock possible - if (errno == EWOULDBLOCK) - { - // FAILED exclusive locking because someone else has a lock - close(m_filedes); - m_filedes=-1; - } - else // failed for some other reason, try to keep a shared lock at least - { - m_filedes_locked = !flock(m_filedes,LOCK_SH|LOCK_NB); - } - } - } - - if (m_filedes>=0) - { - if (!wantAppendTo) ftruncate(m_filedes,0); - else - { - struct stat st; - if (!fstat(m_filedes,&st)) SetPosition(st.st_size); - } - } - - -#ifdef __APPLE__ - if (m_filedes >= 0 && allow_async>1) fcntl(m_filedes,F_NOCACHE,1); -#endif - } - if (minbufs * bufsize >= 16384) m_bufspace.Resize((minbufs*bufsize+4095)&~4095); -#else - m_fp=fopen(filename,wantAppendTo ? "a+b" : "wb"); - if (wantAppendTo && m_fp) - fseek(m_fp,0,SEEK_END); -#endif - } - - ~WDL_FileWrite() - { -#ifdef WDL_WIN32_NATIVE_WRITE - // todo, async close stuff? - if (m_fh != INVALID_HANDLE_VALUE && m_async) - { - SyncOutput(true); - } - - m_empties.Empty(true); - m_pending.Empty(true); - - if (m_fh != INVALID_HANDLE_VALUE) CloseHandle(m_fh); - m_fh=INVALID_HANDLE_VALUE; -#elif defined(WDL_POSIX_NATIVE_WRITE) - if (m_filedes >= 0) - { - if (m_bufspace.GetSize() > 0 && m_bufspace_used>0) - { - int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); - if (v>0) m_file_position+=v; - if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; - m_bufspace_used=0; - } - if (m_filedes_locked) flock(m_filedes,LOCK_UN); - close(m_filedes); - } - m_filedes=-1; - -#else - if (m_fp) fclose(m_fp); - m_fp=0; -#endif - - } - - bool IsOpen() - { -#ifdef WDL_WIN32_NATIVE_WRITE - return (m_fh != INVALID_HANDLE_VALUE); -#elif defined(WDL_POSIX_NATIVE_WRITE) - return m_filedes >= 0; -#else - return m_fp != NULL; -#endif - } - - - int Write(const void *buf, int len) - { -#ifdef WDL_WIN32_NATIVE_WRITE - if (m_fh == INVALID_HANDLE_VALUE) return 0; - - if (m_async) - { - char *pbuf=(char *)buf; - - while (len > 0) - { - if (!m_empties.GetSize()) - { - WDL_FileWrite__WriteEnt *ent=m_pending.Get(0); - DWORD s=0; - if (ent) - { - bool wasabort=false; - if (GetOverlappedResult(m_fh,&ent->m_ol,&s,FALSE)|| - (wasabort=(GetLastError()==ERROR_OPERATION_ABORTED))) - { - m_pending.Delete(0); - - if (wasabort) - { - if (!RunAsyncWrite(ent,false)) m_empties.Add(ent); - } - else - { - m_empties.Add(ent); - ent->m_bufused=0; - } - } - } - } - - - WDL_FileWrite__WriteEnt *ent=m_empties.Get(0); - if (!ent) - { - if (m_pending.GetSize()>=m_async_maxbufs) - { - SyncOutput(false); - } - - if (!(ent=m_empties.Get(0))) - m_empties.Add(ent = new WDL_FileWrite__WriteEnt(m_async_bufsize)); // new buffer - - - } - - int ml=ent->m_bufsz-ent->m_bufused; - if (ml>len) ml=len; - memcpy(ent->m_bufptr+ent->m_bufused,pbuf,ml); - - ent->m_bufused+=ml; - len-=ml; - pbuf+=ml; - - if (ent->m_bufused >= ent->m_bufsz) - { - if (RunAsyncWrite(ent,true)) m_empties.Delete(0); // if queued remove from list - } - } - return pbuf - (char *)buf; - } - else - { - DWORD dw=0; - WriteFile(m_fh,buf,len,&dw,NULL); - m_file_position+=dw; - if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; - return dw; - } -#elif defined(WDL_POSIX_NATIVE_WRITE) - if (m_bufspace.GetSize()>0) - { - char *rdptr = (char *)buf; - int rdlen = len; - while (rdlen>0) - { - int amt = m_bufspace.GetSize() - m_bufspace_used; - if (amt>0) - { - if (amt>rdlen) amt=rdlen; - memcpy((char *)m_bufspace.Get()+m_bufspace_used,rdptr,amt); - m_bufspace_used += amt; - rdptr+=amt; - rdlen -= amt; - - if (m_file_position+m_bufspace_used > m_file_max_position) m_file_max_position=m_file_position + m_bufspace_used; - } - if (m_bufspace_used >= m_bufspace.GetSize()) - { - int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); - if (v>0) m_file_position+=v; - m_bufspace_used=0; - } - } - return len; - } - else - { - int v=pwrite(m_filedes,buf,len,m_file_position); - if (v>0) m_file_position+=v; - if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; - return v; - } -#else - return fwrite(buf,1,len,m_fp); -#endif - - - } - - WDL_FILEWRITE_POSTYPE GetSize() - { -#ifdef WDL_WIN32_NATIVE_WRITE - if (m_fh == INVALID_HANDLE_VALUE) return 0; - DWORD h=0; - DWORD l=GetFileSize(m_fh,&h); - WDL_FILEWRITE_POSTYPE tmp=(((WDL_FILEWRITE_POSTYPE)h)<<32)|l; - WDL_FILEWRITE_POSTYPE tmp2=GetPosition(); - if (tmpm_bufused; - } - return pos; -#elif defined(WDL_POSIX_NATIVE_WRITE) - if (m_filedes < 0) return -1; - return m_file_position + m_bufspace_used; -#else - if (!m_fp) return -1; - return ftell(m_fp); - -#endif - } - -#ifdef WDL_WIN32_NATIVE_WRITE - - bool RunAsyncWrite(WDL_FileWrite__WriteEnt *ent, bool updatePosition) // returns true if ent is added to pending - { - if (ent && ent->m_bufused>0) - { - if (updatePosition) - { - ent->m_last_writepos = m_file_position; - m_file_position += ent->m_bufused; - if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; - } - -#ifdef WIN32_ASYNC_NOBUF_WRITE - if (ent->m_bufused&4095) - { - int offs=(ent->m_bufused&4095); - char tmp[4096]; - memset(tmp,0,4096); - - *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = ent->m_last_writepos + ent->m_bufused - offs; - ResetEvent(ent->m_ol.hEvent); - - DWORD dw=0; - if (!ReadFile(m_fh,tmp,4096,&dw,&ent->m_ol)) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(ent->m_ol.hEvent,INFINITE); - } - memcpy(ent->m_bufptr+ent->m_bufused,tmp+offs,4096-offs); - - ent->m_bufused += 4096-offs; - } -#endif - DWORD d=0; - - *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = ent->m_last_writepos; - - ResetEvent(ent->m_ol.hEvent); - - if (!WriteFile(m_fh,ent->m_bufptr,ent->m_bufused,&d,&ent->m_ol)) - { - if (GetLastError()==ERROR_IO_PENDING) - { - m_pending.Add(ent); - return true; - } - } - ent->m_bufused=0; - } - return false; - } - - void SyncOutput(bool syncall) - { - if (syncall) - { - if (RunAsyncWrite(m_empties.Get(0),true)) m_empties.Delete(0); - } - for (;;) - { - WDL_FileWrite__WriteEnt *ent=m_pending.Get(0); - if (!ent) break; - DWORD s=0; - m_pending.Delete(0); - if (!GetOverlappedResult(m_fh,&ent->m_ol,&s,TRUE) && GetLastError()==ERROR_OPERATION_ABORTED) - { - // rewrite this one - if (!RunAsyncWrite(ent,false)) m_empties.Add(ent); - } - else - { - m_empties.Add(ent); - ent->m_bufused=0; - if (!syncall) break; - } - } - } - -#endif - - - bool SetPosition(WDL_FILEWRITE_POSTYPE pos) // returns 0 on success - { -#ifdef WDL_WIN32_NATIVE_WRITE - if (m_fh == INVALID_HANDLE_VALUE) return true; - if (m_async) - { - SyncOutput(true); - m_file_position=pos; - if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; - -#ifdef WIN32_ASYNC_NOBUF_WRITE - if (m_file_position&4095) - { - WDL_FileWrite__WriteEnt *ent=m_empties.Get(0); - if (ent) - { - int psz=(int) (m_file_position&4095); - - m_file_position -= psz; - *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = m_file_position; - ResetEvent(ent->m_ol.hEvent); - - DWORD dwo=0; - if (!ReadFile(m_fh,ent->m_bufptr,4096,&dwo,&ent->m_ol)) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(ent->m_ol.hEvent,INFINITE); - } - ent->m_bufused=(int)psz; - } - } -#endif - return false; - } - - m_file_position=pos; - if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; - - LONG high=(LONG) (m_file_position>>32); - return SetFilePointer(m_fh,(LONG)(m_file_position&((WDL_FILEWRITE_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN)==0xFFFFFFFF && GetLastError() != NO_ERROR; -#elif defined(WDL_POSIX_NATIVE_WRITE) - - if (m_filedes < 0) return true; - if (m_bufspace.GetSize() > 0 && m_bufspace_used>0) - { - int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); - if (v>0) m_file_position+=v; - if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; - m_bufspace_used=0; - } - - m_file_position = pos; // seek! - if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; - return false; -#else - if (!m_fp) return true; - return !!fseek(m_fp,pos,SEEK_SET); -#endif - } - - WDL_FILEWRITE_POSTYPE m_file_position, m_file_max_position; - -#ifdef WDL_WIN32_NATIVE_WRITE - HANDLE GetHandle() { return m_fh; } - HANDLE m_fh; - bool m_async; - - int m_async_bufsize, m_async_minbufs, m_async_maxbufs; - - WDL_PtrList m_empties; - WDL_PtrList m_pending; - -#elif defined(WDL_POSIX_NATIVE_WRITE) - int GetHandle() { return m_filedes; } - - WDL_HeapBuf m_bufspace; - int m_bufspace_used; - int m_filedes; - - bool m_filedes_locked; - -#else - int GetHandle() { return fileno(m_fp); } - - FILE *m_fp; -#endif -} WDL_FIXALIGN; - - - - - - -#endif diff --git a/WDL/giflib/AUTHORS b/WDL/giflib/AUTHORS deleted file mode 100644 index 43dee904..00000000 --- a/WDL/giflib/AUTHORS +++ /dev/null @@ -1,36 +0,0 @@ -Lennie Araki - Windows code providing a nicer interface and example program - -Michael Brown - callbacks to write data via user defined function - -Daniel Eisenbud - Fixes for crashes with invalid gif files and double freeing of - colormaps - -Gershon Elber - original giflib code - -Marc Ewing - spec file (for rpms) updates - -Toshio Kuratomi - uncompressed gif writing code - autoconf/automake process - current maintainer - -marek - Gif initialization fix - windows build code - -Peter Mehlitz - callbacks to read data from arbitrary sources (like libjpeg/libpng) - -Dick Porter - int/pointer fixes for Alpha - -Eric Raymond - long time maintainer of giflib code - -Georg Schwarz - IRIX fixes diff --git a/WDL/giflib/COPYING b/WDL/giflib/COPYING deleted file mode 100644 index da543574..00000000 --- a/WDL/giflib/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/WDL/giflib/ChangeLog b/WDL/giflib/ChangeLog deleted file mode 100644 index 4186f255..00000000 --- a/WDL/giflib/ChangeLog +++ /dev/null @@ -1,549 +0,0 @@ -2005-10-09 Toshio Kuratomi - r94 - * Sync with libungif r93. - * ChangeLog: Update to r92. - * NEWS: Update with combined libungif/giflib changes. - -2005-10-09 Toshio Kuratomi - r92 - * lib/gif_lib.h: Change GifPrefixType to unsigned. - -2005-10-09 Toshio Kuratomi - r91 - * ChangeLog: Update to r90. - * NEWS: Update on GBA and Windows fixes. - -2005-10-06 Toshio Kuratomi - r90 - Changes from Lennie Araki: - * gba/giftest.mak: Prefix the names of defines for the GBA build with _GBA. - * lib/dgif_lib.c, lib/gif_lib_private.h, lib/gif_err.c: - - When Compiling for Game Boy Advance, file functions are not needed so - exclude DGifOpenFileName(), DGifOpenFileHandle(), DGifSlurp(), and - PrintGifError(). - - On Game Boy Advance we need to reduce memory usage. Change values to - short int where appropriate. - * lib/gif_lib.h: - - Handle te GBA changes by defining GifPrefixType and GifWord to int - unless compiling on GBA. Then use unsigned short and short - respectively. - - Fix a problem with the API on _WIN32. DrawText conflicts with the - Windows API. Call it DrawGifText instead. - -2005-09-27 Toshio Kuratomi - r86 - * Sync with libungif r85. - -2005-09-27 Toshio Kuratomi - r82 - * AUTHORS: Add Daniel Eisenbud. Obscure email addresses. - * libungif.spec: Bump to version 4.1.4. - * configure.ac: Bump to 4.1.4. No longer check for ranlib. - * doc/lzgif.txt: Change dos line encoding to UNIX. - * lib/dgif_lib.c: (eisenbud) - - Set GifFile's ColorMaps to NULL when we free a colormap object. - - Detect some cases of corrupted GIFs which were crashing the library. - * lib/egif_lib.c: Set ColorMaps to NULL when we free a colormap object. - * lib/gifalloc.c: Set ColorMaps to NULL when we free a colormap object. - * lib/dev2gif.c: Fix redefinition problem on IRIX. - * NEWS: Update to 4.1.4 - * util/gifcomb.c: Set a olorMap to NULL. - -2004-07-11 Toshio Kuratomi - r79 - * gif2iris.c: Fixes from Georg Schwarz . - - stdlib.h is available and needs to be included on IRIX. - - ColorMapSize was being set from non-existent variables. - -2004-05-29 Toshio Kuratomi - r76 - * Sync with libungif-4.1.3. - -2004-05-29 Toshio Kuratomi - r74 - * ChangeLog, prop=lastlog: Sync with the subversion logs. - -2004-05-29 Toshio Kuratomi - r73 - * test-unx: Add a test of extension code. - * lib/egif_lib.c: Remove a debugging statement - -2004-05-29 Toshio Kuratomi - r72 - * Makefile.am, doc/Makefile.am, pic/Makefile.am: Change wildcarded entries - into explicit filenames so make distcheck will succeed. - -2004-05-29 Toshio Kuratomi - r71 - * ChangeLog, prop=lastlog: Sync the ChangeLog for the release. - -2004-05-29 Toshio Kuratomi - r70 - * AUTHORS: Add Lennie Araki to the list of contributers. - * windows: The windows subdirectory and all files under it are contributions - from Lennie Araki to provide a nice interface on MS Windows. - * README: Redundancy fix. - * doc/gif_lib.html: Add EGifPutExtension{First,Next,Last} to the documentation - so people know they should use it instead of EGifPutExtension. - * Makefile.am: Mark the windows files to be distributed. - * NEWS: Complete the NEWS item for 4.1.3. - -2004-05-29 Toshio Kuratomi - r69 - * libungif.spec: Some updates from the latest RedHat spec. - * configure.ac: Bump version to 4.1.3. - * lib/gifalloc.c: Add to my comments on ESR's note about Extension blocks. - * lib/egif_lib.c: - - EGifPutComment(): reimplemented using EGifPutExtensionFirst, Next, and - Last so that it won't break on unusually long comments. - - EGifPutExtension{First,Next,Last}: Changed fwrites to WRITE so any - user defined write function will get called properly. - - EGifPutExtensionLast: if the Extension block is empty (Zero length) - then don't attempt to output a last extension block, just output the - block terminator. - - EGifPutExtension: Comment that this function does not work when there - are multiple subblocks in an Extension block. Use the functions - EGifPutExtension{First,Next,Last} instead. - - EGifSpew: Reimplement to use EGifPutExtension{First,Next,Last} so we - don't output broken GIFs when there are multiple sub-blocks on an - extension. - * lib/Makefile.am: Bump version to 4.1.3. - * NEWS: Begin writing an entry for 4.1.3. - * util/icon2gif.c: Few casting fixes to make gcc -Wall happy. - * util/gif2ps.c: printf format string corrections. - -2004-05-26 Toshio Kuratomi - r67 - * Clean up some typos. - -2004-05-25 Toshio Kuratomi - r66 - * Sync with libungif-4.1.2. - -2004-03-03 Toshio Kuratomi - r64 - Last minute updates to the release notes in various files. - -2004-03-03 Toshio Kuratomi - r63 - * Set property lastlog to remind me when I last synced the ChangeLog - -2004-03-03 Toshio Kuratomi - r62 - * ChangeLog: Update - -2004-03-03 Toshio Kuratomi - r61 - * configure.ac: Bump version to 4.1.2 - -2004-02-22 Toshio Kuratomi - r59 - * configure.ac, lib/Makefile.am: Bump version. Forgot to do this for 4.1.1... - -2004-02-22 Toshio Kuratomi - r58 - * TODO: Take out -Wall as that's all ready now. - -2004-02-22 Toshio Kuratomi - r57 - Merge changes to the code from branch indent-audit r55 - * README: MakeExtension deprecation note. - * TODO: Bunch of things I need to fix or check that I saw while doing the - indentation of the code. - * lib/getarg.h: indent changes - * lib/dgif_lib.c: indent changes - - Move stdlib.h out of #ifdef's as it's included on all platforms. - - Add checks to be sure malloc and MakeMapObject succeed. - * lib/quantize.c: indent changes - - Move stdlib.h out of #ifdef's as it's included on all platforms. - - _GifError already pulled in through gif_lib_private.h. Remove decl. - - Make Count in NewColorMapType be unsigned. - - Separated mallocs from conditionals in a few places. Easier reading. - * lib/gifalloc.c: indent changes - - Added four FIXME's where I think the code might not be doing what we - want. Need to do more research to figure out. - - Add note to MakeExtension that I think it needs to be deprecated. - - Separated mallocs from conditionals in a few places. Easier reading. - - FreeLastSavedImage: New private function to free the last image in a - GifFile structure. Used to back out when unable to completely - allocate a new SavedImage structure. - - check for NULL values before deallocating in Free* functions and make - sure all Free* functions set the pointer to NULL after they deallocate - the memory. - * lib/egif_lib.c: indent changes - - EGifPutScreenDesc: If we have no colormap, output a default value for - its size instead of trying to reference its unallocated BitsPerPixel - field. (Fixes bug noted in r46) - * lib/gif_lib.h: indent changes - - Condense the #else #if VARARGS to #elif VARARGS check. - * lib/qprintf.c: indent changes - - Condense the #else #if VARARGS to #elif VARARGS check. - * lib/dev2gif.c: indent changes - * lib/getarg.c: indent changes - * lib/gif_lib_private.h: indent changes - * lib/gif_font.c: indent changes - * lib/gif_err.c: indent changes - -2004-02-22 Toshio Kuratomi - r56 - * lib/Makefile.am, util/Makefile.am: Add -Wall to the compilation flags so - we can keep the code from acquiring too much bad style. - -2004-02-20 Toshio Kuratomi - r46 - * egif_lib.c: Note for a bug fix (Can wait until after indent because - there's no patch.) - * gif_lib.h, dev2gif.c: Change int type to explicit long type in - DumpScreen2Gif. - * util/gifinto.c: Give the fprintf back its %d format. - GifFile->ImageCount is used as the Image number. - -2004-02-20 Toshio Kuratomi - r45 - * README: add varargs to the deprecation list - -2004-02-20 Toshio Kuratomi - r44 - * test-unx: Quote the program names. - * lib/dgif_lib.c: - - Make sure memory was allocated for the colormap - - Some reformatting of code but no syntactic changes. - * lib/gif_lib.h: - - C++ extern "C" fix - - Fix typo with EGifOpen - * lib/qprintf.c, lib/getarg.c: Update the varargs code. Some users reported - that not all systems can handle the hybridized varargs parameter lists - we had. Need to use old-style declarations instead. - -2004-02-20 Toshio Kuratomi - r43 - * NEWS: Note bugfixes and deprecations - * README: Deprecation list is now being compiled in this file. - * TODO: Notes about interlace bug, -Wall status, merging of old bug status - -2004-02-19 Toshio Kuratomi - r42 - * Makefile.am: Disable testing for now because gif2x11 is broken so none - of the tests _appear_ to complete successfully. - -2004-02-19 Toshio Kuratomi - r38 - Merge -Wall fixes from branches/Wall-audit r29 - * configure.ac: - - Make the stdarg vs varargs check simpler by relying on - AC_CHECK_HEADERS() magic. - - Check for unistd.h - * dgif_lib.c, gif_lib.h, egif_lib.c, gifalloc.c, quantize.c, dev2gif.c, - getarg.c, gif_lib_private.h, gif_font.c gif_err.c, gifinto.c, icon2gif.c, - raw2gif.c, gifcolor.c, gifasm.c, gif2epsn.c, gif2iris.c, gifrotat.c, - gifovly.c, gif2x11.c, rle2gif.c, gif2rle.c, text2gif.c, gifspnge.c, - gifclrmp.c, giffiltr.c, giftext.c, gifinfo.c, rgb2gif.c, gif2rgb.c, gif2ps.c - - Changes to get rid of -Wall compile warnings. - + Casting of types - + New header includes for unistd.h and fcntl.h - + Explicit declaration of many types to unsigned - + Removed unused variables and functions - + Removed VersionStr from every library file. Instead include it via - gif_lib_private.h - * gif_lib.h, gif_lib_private.h: Moved the VersionStr into gif_lib_private.h - and made it a #define instead of a static char *. - -2004-02-19 Toshio Kuratomi - r37 - Deprecation notes - -2004-02-19 Toshio Kuratomi - r36 - Add notes about security things to do and giflib syncing - -2004-02-18 Toshio Kuratomi - r32 - * TODO: Add notes about how to go about syncing Wall-audit and indent changes - into giflib. It won't be pretty. - * svn:ignore: Change the tarball names from libungif to giflib - -2004-02-18 Toshio Kuratomi - r31 - Add config.h include to gif_hash.c - -2004-02-17 Toshio Kuratomi - r30 - Sync up with libungif 4.1.1 - -2004-02-17 Toshio Kuratomi - r26 - Updated ChangeLog - -2004-02-17 Toshio Kuratomi - * Updated libungif.spec to look more like fedora core spec - * Updated version numbers in all files - -2004-02-17 Toshio Kuratomi - * Add the libungif*.tar.bz2 distribution tarball to the ignored files - * configure.ac, lib/getarg.c, lib/getarg.h, lib/gif_lib.h, lib/qprintf.c: - Prefer stdarg.h over vararg.h - * TODO: Add information about functions that will go away in 5.0 - (In reality, I don't think new software uses libungif, so there may never - be a 5.0 release.) - * lib/gif_lib.h: Change version from 4.0 to 4.1 - * NEWS: add deprecation warning for the qprintf stuff: GifQuietPrint var and - GifQprintf function. - -2004-02-16 Toshio Kuratomi - * util/gif2iris.c, util/gif2rle.c, util/gifinfo.c: Fix problems with fprintf error statements in the utils - -2004-02-16 Toshio Kuratomi - Add DEVELOPERS file to the distribution. - -2004-02-16 Toshio Kuratomi - * AUTHORS, libungif.spec, libungif.lsm, README, BUGS, NEWS: - Lots of changes to my email address and the website/download. (libungif is - moving to sourceforge.) - * TODO: Few notes on cleanups that need to happen. State what needs to be done - for 4.1.1 to be released. - -2004-02-15 Toshio Kuratomi - Changes imported from last cvs checkout - * TODO: note to check return of malloc everywhere - * lib/dgif_lib.c, lib/egif_lib.c: Fix some deallocation bugs - * lib/gifalloc.c: Fix a colormap allocation problem - * lib/gif_font.c: Fix to drawing text - -2004-02-15 Toshio Kuratomi - Added libgetarg.a to the ignore list. - -2004-02-15 Toshio Kuratomi - Changes to the build infrastructure to build under current libtool, automake, - and libtool. - * configure.in: renamed to configure.ac - * acconfig.h: deleted. Functionality moved into the configure.ac - * autogen.sh: now runs libtoolize --automake - * lib/Makefile.am, util/Makefile.am: CFLAGS=>AM_CFLAGS; INCLUDES=>AM_CPPFLAGS - * configure.ac: - - initialization macros for automake and autoconf have changed - - removed checks for C++ compiler and Awk - - acconfig.h functionality moved here. - - add other X11 libraries to the X11_LIB define - -2004-02-15 Toshio Kuratomi - * Remove INSTALL file as it's autogenerated.\n* Add stamp-h1 to ignored files - -2004-02-15 Toshio Kuratomi - Additional adds and deletes to make version 4.1.0b1 - -2004-02-15 Toshio Kuratomi - Import of version 4.1.0b1 - -2004-02-15 Toshio Kuratomi - r10 - Import giflib 4.1.0 - -2004-02-15 Toshio Kuratomi - r9 - Copy the 4.1.0 libungif release to be the base of the 4.1.0 giflib release. - -2004-02-15 Toshio Kuratomi - r7 - Release 4.1.0 - -2004-02-15 Toshio Kuratomi - r6 - Import of version 4.1.0 - -2004-02-15 Toshio Kuratomi - r5 - Set ignore patterns on the project directories. - -2004-02-15 Toshio Kuratomi - r3 - Remove a Makefile.in that was left in in the first commit. - -2004-02-14 Toshio Kuratomi - r2 - Commit revision 3.1.0 to subversion - -2004-02-14 Toshio Kuratomi - r1 - Initial SVN Repository Layout - -2000 6 Feb Toshio Kuratomi - * configure.in: Change to using config.h - - Every .c file: Change to using config.h. - * configure.in: added check for varargs header. - * lib/getarg.c: Changed the ifdef USE_VARARGS to ifdef HAVE_VARARGS_H. - - lib/getarg.h: Ditto. - - lib/gif_lib.h: Ditto. - - lib/qprintf.h: Ditto. - -2000 6 Feb Toshio Kuratomi - * lib/getarg.h: Prepend an underscore to the header file define. - * lib/gif_lib.h: Ditto - * lib/gif_lib_private.h: Ditto - * lib/getarg.c: ifdef'd MyMalloc so it actually won't define if it already - is. - -2000 3 Feb Toshio Kuratomi - * A new cvs repository based my private tree from home. It now goes back - to giflib-3.0. - * Updated the cvs repository to make multiple developers possible. - * Merge all of Michael's patches into the distribution. - * DEVELOPER: Updated to reflect the new versions of - autoconf/automake/libtool we're using. - * libungif.spec: Updated a few things from the latest redhat spec file. - -1999 5 Dec Toshio Kuratomi - * Update links to the web pages as I have reorganized them somewhat. - * Add the welcome2.gif to the pic directory and a test that utilizes - it to test-unx. - -1999 17 Nov Toshio Kuratomi - * New cvs Repository. Hopefully I've got everything that was in the - old one. This one is available on anonymous cvs. - * Update to libtool 1.3.3, automake 1.4, and autoconf 2.13 - -1999 23 May Michael R Brown - * Lots of 'const' qualifiers added, thanks Alexis - Wilke for finding these. - -1999 22 Mar Michael R Brown - * util/gif2x11.c: Patch by (who?) to fix lots of memory leeks. - * util/*.c: - lib/dgif_lib.c: - Makefile.in: - Patch by David Kaelbling to compile on IRIX 6.x. Basically fixing - lots of bad/missing parameter passing to printf, scanf and similar. - * Added pics/welcome2.gif, from Peter Merz which provokes a bug prior - to patch 19990224 to do with colour map management. There is still - a problem with util/gifspnge processing this image, so it will not - be added to test-unx yet. - -1999 05 Mar Michael R Brown - * lib/getarg.c: Lines 107 and 189 - Added ifdef's to use stdarg when available. On dec-alpha the - default code was causing programs to crash, probably because - it assumes a stack that grows-up. - -1999 24 Feb Michael R Brown - * lib/dgif_lib.c: Lines 363 and 367 - Bug reported by Steve Sanders, where &'s where causing the - memcpy to overwrite the pointers. Fixed by removing the &'s - so that memcpy overwrote the memory pointed to. - -1999 09 Feb Toshio Kuratomi - * Release 4.1.0 - -1999 09 Feb Toshio Kuratomi - * Merge libungif changes into the giflib tree: - - upgrade to libtool 1.2b - - util/Makefile.am: Minor change to allow compilation outside the - source_dir. - - lib/egif_lib.c: FILE_STATE_WRITE, FILE_STATE_SCREEN, - FILE_STATE_IMAGE, IS_WRITEABLE are now in gif_lib_private.h - - lib/dgif_lib.c: FILE_STATE_READ and IS_READABLE are now in - gif_lib_private.h - - lib/gif_lib_private.h: Above mentioned constants and macros are now - here. FILE_STATE_READ is now 0x08 instead of 0x00. - - configure.in: Update version to 4.1.0 - - lib/Makefile.am: Update libtool version to 5:0:1 (libtool) - - giflib.spec: Update for version 4.1.0 (Add libungif-4.1 - compatibility stuff and change version.) - - giflib.lsm: Update for version 4.1.0 - - lib/egif_lib.c: (WRITE) change from a function to a macro. - - lib/dgif_lib.c: (DGifOpenFileName) close FileHandle on error. - - lib/dgif_lib.c: (DGifOpenFileHandle) make sure the FILE stream is - closed if we hit an error. - - lib/dev2gif.c, lib/quantize.c, lib/gif_err.c, lib/gif_lib_private.h: - Reflect Eric's copyright notice rather than Gershon's - -1999 14 Jan Michael R Brown - * lib/gif_lib.h: Add OutputFunc type - * lib/gif_lib.h: Add EGifOpen for user supplied output function - * lib/egif_lib.c: (EGifOpenFileName) Fixed wasted memory when an - error occurs in EGifOpenFileHandle - * lib/egif_lib.c: Add EGifOpen, WRITE, and lots of changes to - support user supplied output function. Basically changing - all fwrite's to WRITE, and then all of the knock on effects. - -1998 17 Dec Toshio Kuratomi - * configure.in: Change references to libungif to giflib. - * libungif.lsm: Rename to giflib.lsm and change to reflect giflib - rather than libungif. - * libungif.spec: Rename to giflib.spec and change to reflect giflib - rather than libungif. - * UNCOMPRESSED_GIF: Removed from this branch. - * PATENT_PROBLEMS: Add file explaining Unisys's patent claims. - * Makefile.am: Replace libungif with giflib. - * README: Adapted language to giflib. - * lib/Makefile.am: Changed references to libungif to libgif. - * util/Makefile.am: Changed references to libungif to libgif. - -1998 17 Dec Toshio Kuratomi - * lib/egif_lib.c: Merge LZW stuff into this branch of the library. - This includes numerous changes to initialize the hash table as well - as the code forthe encoder. - * lib/gif_hash.c: Functions needed for the LZW encoder. - * lib/gif_hash.h: Functions needed for the LZW encoder. - * lib/Makefile.am: Add gif_hash.c gif_hash.h to the list of sources. - -1998 15 Dec Toshio Kuratomi - * lib/dgif_lib.c: (DGifSlurp) Fix a Seg Fault when an image contains - no extension blocks. - -1998 14 Dec Toshio Kuratomi - * configure.in: Update version to 4.0 - * lib/Makefile.am: Update libtool version to 4:0:0 (libtool) - * libungif.spec: Update for version 4.0 (not binary compatible with - giflib, change version.) - * lib/gif_lib_private.h: (PrivateType) New header for common stuff - private to the library. Currently, this is only the Private struct. - * lib/dgif_lib.c: (PrivateType) Extract the Private struct to - gif_lib_private.h - * lib/egif_lib.c: (PrivateType) Extract the Private struct to - gif_lib_private.h - * lib/Makefile.am: Add gif_lib_private.h to the list of source files. - * lib/gif_lib.h: (ExtensionBlock) Add a Function entry to the - ExtensionBlock record. Note that this is not entirely correct: - the GifLib ExtensionBlock structure is actually a data sub-block - record. By adding the function entry here, we are pushing the - ExtensionBlockType in with the DataSubBlock. - Sometime in the future, we need to change the API to have true - ExtensionBlocks which have DataSubBlocks belonging to them. - * lib/gif_lib.h: (ExtensionBlock) Deprecate the use of Function in - the SavedImage struct. Use ExtensionBlock's Function instead. - * lib/egif_lib.c: (EGifSpew) Changes to use the new Function variable. - * lib/dgif_lib.c: (DGifSlurp) Changes to put data into the new - Function variable. - -1998 3 Dec Toshio Kuratomi - * lib/dgif_lib.c: (DGifSlurp) Three changes: - - No longer allocate SaveImage in this function. All allocations - of SaveImage take place in DGifGetImageDesc. - - Extension blocks are now associated with the Image Block that is - read in subsequent to them, not before. This should now be - conformant to the gif89a specification. - - Fix an off-by-one error when copying extension data from structure - to structure. - * lib/dgif_lib.c: (DGifGetImageDesc) Change the function to do its own - allocation of space for the SavedImage structure no matter what. - * lib/egif_lib.c: (EGifSpew) The function now spits out - ExtensionBlocks before the associated Image Block to conform with - the gif89a specification. - * lib/egif_lib.c: (EGifOpenFileHandle) Move the write of the - GifVersion (gif87a or gif89a) from this function into - EGifPutScreenDesc so that it can be controlled by EGifSpew. Note - that this is still a hack as the GifVersion write doesn't really - belong in either of these functions. - * lib/egif_lib.c: (EGifPutScreenDesc) Moved writing the version - (gif87a or gif89a) into the file into this function from - EGifOpenFileHandle. - * test-unx: Now test the extension code. - * pic/x-trans.gif: New image with Comments and transparency to test - the extension code with. - -1998 29 Nov Toshio Kuratomi - * lib/dgif_lib.c: (DGifSlurp) Fix a few of the minor bugs plaguing - this function. At this point, the function should no longer cause - a Seg Fault. It is now losing all extension data however. I know - how to hack a fix in, but I need to commit these changes first. - * lib/dgif_lib.c: (DGifGetImageDesc) Fix my bug fix: the colormap is - now only copied if it exists :-). - -1998 10 Nov Toshio Kuratomi - * test-unx: Add a test for DGifSlurp and EGifSpew - -1998 14 Oct Toshio Kuratomi - * lib/dgif_lib.c: (DGifGetImageDesc) Fix a bug where the Colormap for - the image description and the SaveImage were pointers to the same - structure, causing a SegV when DGifClosing the file. - -1998 9 Oct Toshio Kuratomi - * lib/dgif_lib.c: (DGifSlurp) memory for the extensions was not being - allocated. Now I call AddExtensionBlock when I add an extension to - the structure. Additionally, fix a memory leak here. - * configure.in, NEWS, lib/Makefile.am: Update to version 3.1.1 - * ltmain.sh, ltconfig: removed from the cvs repository - * BUGS: add the BUGS file to list unresolved BUGS. - -1998 9 Sep Toshio Kuratomi - * libungif.spec: Fix wrong version in %files and %install section. - -1998 8 Sep Toshio Kuratomi - * lib/gif_hash.c, lib/gif_hash.h: Removed these because a hash table - is not needed to create uncompressed gifs. - * lib/egif_lib.c: Remove all references to the hash functions. - * lib/Makefile.am: Remove gif_hash.c gif_hash.h from the source files. - * libungif.lsm: added this file - -1998 7 Sep Toshio Kuratomi - * lib/dgif_lib.c, lib/gif_lib.h: (DGifOpen) Add callback to read gif - image through user supplied function (Peter Mehlitz). - -1998 6 Sep Toshio Kuratomi - * util/*.{gif.rle}: removed files that were left by my testing - process and shouldn't have been in the distribution. - * UNCOMPRESSED_GIF: add section on why software that can decode - LZW compressed gifs (but not write them) is legal. - * .cvsignore: added .cvsignore files to ignore Makefiles and other - generated files in my cvs repository. - * Makefile.am's: Fixes to allow the dist* family of targets to work - correctly. Preliminary support for make check as well. - * configure.in: Update version to 3.1.0 - * lib/Makefile.am: Update libtool version to 4:0:1 libtool) - * libungif-3.0.spec: Update from Marc Ewing. - * Add int/pointer Alpha fixes from Dick Porter to many source files. diff --git a/WDL/giflib/DEVELOPERS b/WDL/giflib/DEVELOPERS deleted file mode 100644 index 2d3f6deb..00000000 --- a/WDL/giflib/DEVELOPERS +++ /dev/null @@ -1,29 +0,0 @@ -Things to tell developers of libungif.... - -======= -Build Tools: -libungif presently uses autoconf, automake, and libtool in order to build -shared libraries for a wide variety of platforms. The distributed tarball has -files prebuilt from these tools. The cvs repository does not. If you want to -build libungif you will need to have these tools available. I currently run -with the following versions: -autoconf 2.57 -automake 1.7.8 -libtool 1.5 - -(P.S. I use the autogen.sh script in the top level directory to generate -configure, Makefile.in, etc using these tools.) - -======= -cvs: -I currently do my work in a subversion repository. Since sourceforge is still -using cvs and not subversion, there's nothing in the sourceforge tree. - -If someone else wants to do development we can definitely talk about the best -way to share version control access. - -======= -I create the distribution tar ball by using the `make dist` command.... After -hacking all I want, I check my sources into cvs, checkout a clean tree, run -./autogen.sh; make dist and then attempt to compile from the libungif-*.tar.gz -file that is generated. diff --git a/WDL/giflib/README b/WDL/giflib/README deleted file mode 100644 index 90e8dbf6..00000000 --- a/WDL/giflib/README +++ /dev/null @@ -1,69 +0,0 @@ -This is giflib version 4.1.2, a library for manipulating gif files. It is based -on Eric S. Raymond's giflib-3.0 with bugfixes and changes generated for the -libungif library. - -PLEASE BE AWARE OF POSSIBLE LEGAL PROBLEMS WITH USING THIS LIBRARY: READ -THE PATENT_PROBLEMS FILE NOW! - -======= -Latest versions of giflib, as well as a library which does not have the -mentioned patent problems (libungif), are available from: - http://sourceforge.net/projects/libungif - -==== -Building this package should be as simple as: - - ./configure - gmake - gmake install - -==== -Deprecation list. Will be removed in giflib 5.0: -* GIF_ERROR and GIF_MESSAGE are on the deprecation list as they are also - utility helper functions rather than essential to the functioning of the - library. -* The qprintf methods of the library are now deprecated. Do not use - GifQuietPrint or GifQprintf. These should have been pushed out into the - utility helper library instead of sitting around in the library proper at - the same time as the getarg functions were moved out. Getting rid of these - will let us get rid of our dependence on stdarg.h/varargs.h (Which a Gif - reading library has no business requiring.) -* In the SavedImage struct: int Function will be removed. Use - SavedImage.ExtensionBlocks[x].Function instead. -* In gifalloc.c: MakeExtension is deprecated as well. Use AddExtensionBlock - instead. (This and the previous int Function were deprecated because they - only handle one Extension per image. The new code handles multiple - extensions.) -* varargs style interface in qprintf and getarg: It's a mistake to have two - different interfaces that depend on compile time choices between varargs - and stdargs. The future is to get rid of varargs style altogether. - (Also: these are probably going strictly into the utility functions so - the library won't have to worry about them at all.) -==== - -I have found that automake currently generates Makefile's containing some -GNUmake specific syntax. If you're having troubles building with your -system provided make, please install GNU make and try rebuilding. - -==== -This package uses autoconf, automake, and libtool to create the configure -script, so if you need to edit the configure.ac or change a makefile target -you should read the DEVELOPER file for hints on recreating the distribution -using these tools. - -Good luck! --Toshio Kuratomi - -==== READ.ME file for giflib version 3.0: - - READ ME for GIFLIB - -For complete documentation on the package, point a web browser at -doc/index.html. See the file INSTALL for instructions on how to -install and test the package. - -GIFLIB has a home page at http://www.ccil.org/~esr/giflib. - - Eric S. Raymond - esr@snark.thyrsus.com. - (http://www.ccil.org/~esr) diff --git a/WDL/giflib/config.h b/WDL/giflib/config.h deleted file mode 100644 index 4eadf6c0..00000000 --- a/WDL/giflib/config.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ -#ifdef _WIN32 -#include -#include -#define _OPEN_BINARY -#else -typedef unsigned int UINT32; -#endif -#include -#endif \ No newline at end of file diff --git a/WDL/giflib/dgif_lib.c b/WDL/giflib/dgif_lib.c deleted file mode 100644 index e8580bcd..00000000 --- a/WDL/giflib/dgif_lib.c +++ /dev/null @@ -1,1088 +0,0 @@ -/****************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 - ****************************************************************************** - * The kernel of the GIF Decoding process can be found here. - ****************************************************************************** - * History: - * 16 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). - *****************************************************************************/ - -#include "config.h" - -#include -#if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__) -#include -#include -#include -#else -#include -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#include -#include -#include "gif_lib.h" -#include "gif_lib_private.h" - -#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for - comment. */ - -/* avoid extra function call in case we use fread (TVT) */ -#define READ(_gif,_buf,_len) \ - (((GifFilePrivateType*)_gif->Private)->Read ? \ - ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ - fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File)) - -static int DGifGetWord(GifFileType *GifFile, GifWord *Word); -static int DGifSetupDecompress(GifFileType *GifFile); -static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, - int LineLen); -static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode); -static int DGifDecompressInput(GifFileType *GifFile, int *Code); -static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, - GifByteType *NextByte); -#ifndef _GBA_NO_FILEIO - -/****************************************************************************** - * Open a new gif file for read, given by its name. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ -GifFileType * -DGifOpenFileName(const char *FileName) { - int FileHandle; - GifFileType *GifFile; - - if ((FileHandle = open(FileName, O_RDONLY -#if defined(__MSDOS__) || defined(_OPEN_BINARY) - | O_BINARY -#endif /* __MSDOS__ || _OPEN_BINARY */ - )) == -1) { - _GifError = D_GIF_ERR_OPEN_FAILED; - return NULL; - } - - GifFile = DGifOpenFileHandle(FileHandle); - if (GifFile == (GifFileType *)NULL) - close(FileHandle); - return GifFile; -} - -/****************************************************************************** - * Update a new gif file, given its file handle. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ -GifFileType * -DGifOpenFileHandle(int FileHandle) { - - unsigned char Buf[GIF_STAMP_LEN + 1]; - GifFileType *GifFile; - GifFilePrivateType *Private; - FILE *f; - - GifFile = (GifFileType *)malloc(sizeof(GifFileType)); - if (GifFile == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - memset(GifFile, '\0', sizeof(GifFileType)); - - Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); - if (Private == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - free((char *)GifFile); - return NULL; - } -#ifdef __MSDOS__ - setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ -#endif /* __MSDOS__ */ - - f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ - -#ifdef __MSDOS__ - setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream - buffer. */ -#endif /* __MSDOS__ */ - - GifFile->Private = (VoidPtr)Private; - Private->FileHandle = FileHandle; - Private->File = f; - Private->FileState = FILE_STATE_READ; - Private->Read = 0; /* don't use alternate input method (TVT) */ - GifFile->UserData = 0; /* TVT */ - - /* Lets see if this is a GIF file: */ - if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - _GifError = D_GIF_ERR_READ_FAILED; - fclose(f); - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - /* The GIF Version number is ignored at this time. Maybe we should do - * something more useful with it. */ - Buf[GIF_STAMP_LEN] = 0; - if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - _GifError = D_GIF_ERR_NOT_GIF_FILE; - fclose(f); - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - fclose(f); - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - _GifError = 0; - - return GifFile; -} - -#endif /* _GBA_NO_FILEIO */ - -/****************************************************************************** - * GifFileType constructor with user supplied input function (TVT) - *****************************************************************************/ -GifFileType * -DGifOpen(void *userData, - InputFunc readFunc) { - - unsigned char Buf[GIF_STAMP_LEN + 1]; - GifFileType *GifFile; - GifFilePrivateType *Private; - - GifFile = (GifFileType *)malloc(sizeof(GifFileType)); - if (GifFile == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - memset(GifFile, '\0', sizeof(GifFileType)); - - Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); - if (!Private) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - free((char *)GifFile); - return NULL; - } - - GifFile->Private = (VoidPtr)Private; - Private->FileHandle = 0; - Private->File = 0; - Private->FileState = FILE_STATE_READ; - - Private->Read = readFunc; /* TVT */ - GifFile->UserData = userData; /* TVT */ - - /* Lets see if this is a GIF file: */ - if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - _GifError = D_GIF_ERR_READ_FAILED; - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - /* The GIF Version number is ignored at this time. Maybe we should do - * something more useful with it. */ - Buf[GIF_STAMP_LEN] = 0; - if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - _GifError = D_GIF_ERR_NOT_GIF_FILE; - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - free((char *)Private); - free((char *)GifFile); - return NULL; - } - - _GifError = 0; - - return GifFile; -} - -/****************************************************************************** - * This routine should be called before any other DGif calls. Note that - * this routine is called automatically from DGif file open routines. - *****************************************************************************/ -int -DGifGetScreenDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - /* Put the screen descriptor into the file: */ - if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) - return GIF_ERROR; - - if (READ(GifFile, Buf, 3) != 3) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; - BitsPerPixel = (Buf[0] & 0x07) + 1; - GifFile->SBackGroundColor = Buf[1]; - if (Buf[0] & 0x80) { /* Do we have global color map? */ - - GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); - if (GifFile->SColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - - /* Get the global color map: */ - for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { - if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - GifFile->SColorMap->Colors[i].Red = Buf[0]; - GifFile->SColorMap->Colors[i].Green = Buf[1]; - GifFile->SColorMap->Colors[i].Blue = Buf[2]; - } - } else { - GifFile->SColorMap = NULL; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called before any attempt to read an image. - *****************************************************************************/ -int -DGifGetRecordType(GifFileType * GifFile, - GifRecordType * Type) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - - switch (Buf) { - case ',': - *Type = IMAGE_DESC_RECORD_TYPE; - break; - case '!': - *Type = EXTENSION_RECORD_TYPE; - break; - case ';': - *Type = TERMINATE_RECORD_TYPE; - break; - default: - *Type = UNDEFINED_RECORD_TYPE; - _GifError = D_GIF_ERR_WRONG_RECORD; - return GIF_ERROR; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called before any attempt to read an image. - * Note it is assumed the Image desc. header (',') has been read. - *****************************************************************************/ -int -DGifGetImageDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - SavedImage *sp; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) - return GIF_ERROR; - if (READ(GifFile, Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - BitsPerPixel = (Buf[0] & 0x07) + 1; - GifFile->Image.Interlace = (Buf[0] & 0x40); - if (Buf[0] & 0x80) { /* Does this image have local color map? */ - - /*** FIXME: Why do we check both of these in order to do this? - * Why do we have both Image and SavedImages? */ - if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL) - FreeMapObject(GifFile->Image.ColorMap); - - GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); - if (GifFile->Image.ColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - - /* Get the image local color map: */ - for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { - if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->Image.ColorMap); - _GifError = D_GIF_ERR_READ_FAILED; - GifFile->Image.ColorMap = NULL; - return GIF_ERROR; - } - GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; - GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; - GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; - } - } else if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - - if (GifFile->SavedImages) { - if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, - sizeof(SavedImage) * - (GifFile->ImageCount + 1))) == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } else { - if ((GifFile->SavedImages = - (SavedImage *) malloc(sizeof(SavedImage))) == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } - - sp = &GifFile->SavedImages[GifFile->ImageCount]; - memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); - if (GifFile->Image.ColorMap != NULL) { - sp->ImageDesc.ColorMap = MakeMapObject( - GifFile->Image.ColorMap->ColorCount, - GifFile->Image.ColorMap->Colors); - if (sp->ImageDesc.ColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } - sp->RasterBits = (unsigned char *)NULL; - sp->ExtensionBlockCount = 0; - sp->ExtensionBlocks = (ExtensionBlock *) NULL; - - GifFile->ImageCount++; - - Private->PixelCount = (long)GifFile->Image.Width * - (long)GifFile->Image.Height; - - DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ - - return GIF_OK; -} - -/****************************************************************************** - * Get one full scanned line (Line) of length LineLen from GIF file. - *****************************************************************************/ -int -DGifGetLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - GifByteType *Dummy; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - if (!LineLen) - LineLen = GifFile->Image.Width; - -#if defined(__MSDOS__) || defined(__GNUC__) - if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { -#else - if ((Private->PixelCount -= LineLen) > 0xffff0000) { -#endif /* __MSDOS__ */ - _GifError = D_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - - if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { - if (Private->PixelCount == 0) { - /* We probably would not be called any more, so lets clean - * everything before we return: need to flush out all rest of - * image until empty block (size 0) detected. We use GetCodeNext. */ - do - if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) - return GIF_ERROR; - while (Dummy != NULL) ; - } - return GIF_OK; - } else - return GIF_ERROR; -} - -/****************************************************************************** - * Put one pixel (Pixel) into GIF file. - *****************************************************************************/ -int -DGifGetPixel(GifFileType * GifFile, - GifPixelType Pixel) { - - GifByteType *Dummy; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } -#if defined(__MSDOS__) || defined(__GNUC__) - if (--Private->PixelCount > 0xffff0000UL) -#else - if (--Private->PixelCount > 0xffff0000) -#endif /* __MSDOS__ */ - { - _GifError = D_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - - if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { - if (Private->PixelCount == 0) { - /* We probably would not be called any more, so lets clean - * everything before we return: need to flush out all rest of - * image until empty block (size 0) detected. We use GetCodeNext. */ - do - if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) - return GIF_ERROR; - while (Dummy != NULL) ; - } - return GIF_OK; - } else - return GIF_ERROR; -} - -/****************************************************************************** - * Get an extension block (see GIF manual) from gif file. This routine only - * returns the first data block, and DGifGetExtensionNext should be called - * after this one until NULL extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - * Note it is assumed the Extension desc. header ('!') has been read. - *****************************************************************************/ -int -DGifGetExtension(GifFileType * GifFile, - int *ExtCode, - GifByteType ** Extension) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - *ExtCode = Buf; - - return DGifGetExtensionNext(GifFile, Extension); -} - -/****************************************************************************** - * Get a following extension block (see GIF manual) from gif file. This - * routine should be called until NULL Extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -int -DGifGetExtensionNext(GifFileType * GifFile, - GifByteType ** Extension) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - if (Buf > 0) { - *Extension = Private->Buf; /* Use private unused buffer. */ - (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ - if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - } else - *Extension = NULL; - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called last, to close the GIF file. - *****************************************************************************/ -int -DGifCloseFile(GifFileType * GifFile) { - - GifFilePrivateType *Private; - FILE *File; - - if (GifFile == NULL) - return GIF_ERROR; - - Private = (GifFilePrivateType *) GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - File = Private->File; - - if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - - if (GifFile->SColorMap) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - } - - if (Private) { - free((char *)Private); - Private = NULL; - } - - if (GifFile->SavedImages) { - FreeSavedImages(GifFile); - GifFile->SavedImages = NULL; - } - - free(GifFile); - - if (File && (fclose(File) != 0)) { - _GifError = D_GIF_ERR_CLOSE_FAILED; - return GIF_ERROR; - } - return GIF_OK; -} - -/****************************************************************************** - * Get 2 bytes (word) from the given file: - *****************************************************************************/ -static int -DGifGetWord(GifFileType * GifFile, - GifWord *Word) { - - unsigned char c[2]; - - if (READ(GifFile, c, 2) != 2) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - - *Word = (((unsigned int)c[1]) << 8) + c[0]; - return GIF_OK; -} - -/****************************************************************************** - * Get the image code in compressed form. This routine can be called if the - * information needed to be piped out as is. Obviously this is much faster - * than decoding and encoding again. This routine should be followed by calls - * to DGifGetCodeNext, until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -int -DGifGetCode(GifFileType * GifFile, - int *CodeSize, - GifByteType ** CodeBlock) { - - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - *CodeSize = Private->BitsPerPixel; - - return DGifGetCodeNext(GifFile, CodeBlock); -} - -/****************************************************************************** - * Continue to get the image code in compressed form. This routine should be - * called until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -int -DGifGetCodeNext(GifFileType * GifFile, - GifByteType ** CodeBlock) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - - if (Buf > 0) { - *CodeBlock = Private->Buf; /* Use private unused buffer. */ - (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ - if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - } else { - *CodeBlock = NULL; - Private->Buf[0] = 0; /* Make sure the buffer is empty! */ - Private->PixelCount = 0; /* And local info. indicate image read. */ - } - - return GIF_OK; -} - -/****************************************************************************** - * Setup the LZ decompression for this image: - *****************************************************************************/ -static int -DGifSetupDecompress(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType CodeSize; - GifPrefixType *Prefix; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - READ(GifFile, &CodeSize, 1); /* Read Code size from file. */ - BitsPerPixel = CodeSize; - - Private->Buf[0] = 0; /* Input Buffer empty. */ - Private->BitsPerPixel = BitsPerPixel; - Private->ClearCode = (1 << BitsPerPixel); - Private->EOFCode = Private->ClearCode + 1; - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ - Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ - Private->StackPtr = 0; /* No pixels on the pixel stack. */ - Private->LastCode = NO_SUCH_CODE; - Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ - Private->CrntShiftDWord = 0; - - Prefix = Private->Prefix; - for (i = 0; i <= LZ_MAX_CODE; i++) - Prefix[i] = NO_SUCH_CODE; - - return GIF_OK; -} - -/****************************************************************************** - * The LZ decompression routine: - * This version decompress the given gif file into Line of length LineLen. - * This routine can be called few times (one per scan line, for example), in - * order the complete the whole image. - *****************************************************************************/ -static int -DGifDecompressLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - int i = 0; - int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; - GifByteType *Stack, *Suffix; - GifPrefixType *Prefix; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - StackPtr = Private->StackPtr; - Prefix = Private->Prefix; - Suffix = Private->Suffix; - Stack = Private->Stack; - EOFCode = Private->EOFCode; - ClearCode = Private->ClearCode; - LastCode = Private->LastCode; - - if (StackPtr != 0) { - /* Let pop the stack off before continueing to read the gif file: */ - while (StackPtr != 0 && i < LineLen) - Line[i++] = Stack[--StackPtr]; - } - - while (i < LineLen) { /* Decode LineLen items. */ - if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) - return GIF_ERROR; - - if (CrntCode == EOFCode) { - /* Note however that usually we will not be here as we will stop - * decoding as soon as we got all the pixel, or EOF code will - * not be read at all, and DGifGetLine/Pixel clean everything. */ - if (i != LineLen - 1 || Private->PixelCount != 0) { - _GifError = D_GIF_ERR_EOF_TOO_SOON; - return GIF_ERROR; - } - i++; - } else if (CrntCode == ClearCode) { - /* We need to start over again: */ - for (j = 0; j <= LZ_MAX_CODE; j++) - Prefix[j] = NO_SUCH_CODE; - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = Private->BitsPerPixel + 1; - Private->MaxCode1 = 1 << Private->RunningBits; - LastCode = Private->LastCode = NO_SUCH_CODE; - } else { - /* Its regular code - if in pixel range simply add it to output - * stream, otherwise trace to codes linked list until the prefix - * is in pixel range: */ - if (CrntCode < ClearCode) { - /* This is simple - its pixel scalar, so add it to output: */ - Line[i++] = CrntCode; - } else { - /* Its a code to needed to be traced: trace the linked list - * until the prefix is a pixel, while pushing the suffix - * pixels on our stack. If we done, pop the stack in reverse - * (thats what stack is good for!) order to output. */ - if (Prefix[CrntCode] == NO_SUCH_CODE) { - /* Only allowed if CrntCode is exactly the running code: - * In that case CrntCode = XXXCode, CrntCode or the - * prefix code is last code and the suffix char is - * exactly the prefix of last code! */ - if (CrntCode == Private->RunningCode - 2) { - CrntPrefix = LastCode; - Suffix[Private->RunningCode - 2] = - Stack[StackPtr++] = DGifGetPrefixChar(Prefix, - LastCode, - ClearCode); - } else { - _GifError = D_GIF_ERR_IMAGE_DEFECT; - return GIF_ERROR; - } - } else - CrntPrefix = CrntCode; - - /* Now (if image is O.K.) we should not get an NO_SUCH_CODE - * During the trace. As we might loop forever, in case of - * defective image, we count the number of loops we trace - * and stop if we got LZ_MAX_CODE. obviously we can not - * loop more than that. */ - j = 0; - while (j++ <= LZ_MAX_CODE && - CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { - Stack[StackPtr++] = Suffix[CrntPrefix]; - CrntPrefix = Prefix[CrntPrefix]; - } - if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; - return GIF_ERROR; - } - /* Push the last character on stack: */ - Stack[StackPtr++] = CrntPrefix; - - /* Now lets pop all the stack into output: */ - while (StackPtr != 0 && i < LineLen) - Line[i++] = Stack[--StackPtr]; - } - if (LastCode != NO_SUCH_CODE) { - Prefix[Private->RunningCode - 2] = LastCode; - - if (CrntCode == Private->RunningCode - 2) { - /* Only allowed if CrntCode is exactly the running code: - * In that case CrntCode = XXXCode, CrntCode or the - * prefix code is last code and the suffix char is - * exactly the prefix of last code! */ - Suffix[Private->RunningCode - 2] = - DGifGetPrefixChar(Prefix, LastCode, ClearCode); - } else { - Suffix[Private->RunningCode - 2] = - DGifGetPrefixChar(Prefix, CrntCode, ClearCode); - } - } - LastCode = CrntCode; - } - } - - Private->LastCode = LastCode; - Private->StackPtr = StackPtr; - - return GIF_OK; -} - -/****************************************************************************** - * Routine to trace the Prefixes linked list until we get a prefix which is - * not code, but a pixel value (less than ClearCode). Returns that pixel value. - * If image is defective, we might loop here forever, so we limit the loops to - * the maximum possible if image O.k. - LZ_MAX_CODE times. - *****************************************************************************/ -static int -DGifGetPrefixChar(GifPrefixType *Prefix, - int Code, - int ClearCode) { - - int i = 0; - - while (Code > ClearCode && i++ <= LZ_MAX_CODE) - Code = Prefix[Code]; - return Code; -} - -/****************************************************************************** - * Interface for accessing the LZ codes directly. Set Code to the real code - * (12bits), or to -1 if EOF code is returned. - *****************************************************************************/ -int -DGifGetLZCodes(GifFileType * GifFile, - int *Code) { - - GifByteType *CodeBlock; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_READABLE(Private)) { - /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; - return GIF_ERROR; - } - - if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) - return GIF_ERROR; - - if (*Code == Private->EOFCode) { - /* Skip rest of codes (hopefully only NULL terminating block): */ - do { - if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) - return GIF_ERROR; - } while (CodeBlock != NULL) ; - - *Code = -1; - } else if (*Code == Private->ClearCode) { - /* We need to start over again: */ - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = Private->BitsPerPixel + 1; - Private->MaxCode1 = 1 << Private->RunningBits; - } - - return GIF_OK; -} - -/****************************************************************************** - * The LZ decompression input routine: - * This routine is responsable for the decompression of the bit stream from - * 8 bits (bytes) packets, into the real codes. - * Returns GIF_OK if read succesfully. - *****************************************************************************/ -static int -DGifDecompressInput(GifFileType * GifFile, - int *Code) { - - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - GifByteType NextByte; - static unsigned short CodeMasks[] = { - 0x0000, 0x0001, 0x0003, 0x0007, - 0x000f, 0x001f, 0x003f, 0x007f, - 0x00ff, 0x01ff, 0x03ff, 0x07ff, - 0x0fff - }; - /* The image can't contain more than LZ_BITS per code. */ - if (Private->RunningBits > LZ_BITS) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; - return GIF_ERROR; - } - - while (Private->CrntShiftState < Private->RunningBits) { - /* Needs to get more bytes from input stream for next code: */ - if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { - return GIF_ERROR; - } - Private->CrntShiftDWord |= - ((unsigned long)NextByte) << Private->CrntShiftState; - Private->CrntShiftState += 8; - } - *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; - - Private->CrntShiftDWord >>= Private->RunningBits; - Private->CrntShiftState -= Private->RunningBits; - - /* If code cannot fit into RunningBits bits, must raise its size. Note - * however that codes above 4095 are used for special signaling. - * If we're using LZ_BITS bits already and we're at the max code, just - * keep using the table as it is, don't increment Private->RunningCode. - */ - if (Private->RunningCode < LZ_MAX_CODE + 2 && - ++Private->RunningCode > Private->MaxCode1 && - Private->RunningBits < LZ_BITS) { - Private->MaxCode1 <<= 1; - Private->RunningBits++; - } - return GIF_OK; -} - -/****************************************************************************** - * This routines read one gif data block at a time and buffers it internally - * so that the decompression routine could access it. - * The routine returns the next byte from its internal buffer (or read next - * block in if buffer empty) and returns GIF_OK if succesful. - *****************************************************************************/ -static int -DGifBufferedInput(GifFileType * GifFile, - GifByteType * Buf, - GifByteType * NextByte) { - - if (Buf[0] == 0) { - /* Needs to read the next buffer - this one is empty: */ - if (READ(GifFile, Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - /* There shouldn't be any empty data blocks here as the LZW spec - * says the LZW termination code should come first. Therefore we - * shouldn't be inside this routine at that point. - */ - if (Buf[0] == 0) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; - return GIF_ERROR; - } - if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) { - _GifError = D_GIF_ERR_READ_FAILED; - return GIF_ERROR; - } - *NextByte = Buf[1]; - Buf[1] = 2; /* We use now the second place as last char read! */ - Buf[0]--; - } else { - *NextByte = Buf[Buf[1]++]; - Buf[0]--; - } - - return GIF_OK; -} -#ifndef _GBA_NO_FILEIO - -/****************************************************************************** - * This routine reads an entire GIF into core, hanging all its state info off - * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() - * first to initialize I/O. Its inverse is EGifSpew(). - ******************************************************************************/ -int -DGifSlurp(GifFileType * GifFile) { - - int ImageSize; - GifRecordType RecordType; - SavedImage *sp; - GifByteType *ExtData; - SavedImage temp_save; - - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; - - do { - if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) - return (GIF_ERROR); - - switch (RecordType) { - case IMAGE_DESC_RECORD_TYPE: - if (DGifGetImageDesc(GifFile) == GIF_ERROR) - return (GIF_ERROR); - - sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; - ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; - - sp->RasterBits = (unsigned char *)malloc(ImageSize * - sizeof(GifPixelType)); - if (sp->RasterBits == NULL) { - return GIF_ERROR; - } - if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == - GIF_ERROR) - return (GIF_ERROR); - if (temp_save.ExtensionBlocks) { - sp->ExtensionBlocks = temp_save.ExtensionBlocks; - sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; - - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; - - /* FIXME: The following is wrong. It is left in only for - * backwards compatibility. Someday it should go away. Use - * the sp->ExtensionBlocks->Function variable instead. */ - sp->Function = sp->ExtensionBlocks[0].Function; - } - break; - - case EXTENSION_RECORD_TYPE: - if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) == - GIF_ERROR) - return (GIF_ERROR); - while (ExtData != NULL) { - - /* Create an extension block with our data */ - if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) - == GIF_ERROR) - return (GIF_ERROR); - - if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) - return (GIF_ERROR); - temp_save.Function = 0; - } - break; - - case TERMINATE_RECORD_TYPE: - break; - - default: /* Should be trapped by DGifGetRecordType */ - break; - } - } while (RecordType != TERMINATE_RECORD_TYPE); - - /* Just in case the Gif has an extension block without an associated - * image... (Should we save this into a savefile structure with no image - * instead? Have to check if the present writing code can handle that as - * well.... */ - if (temp_save.ExtensionBlocks) - FreeExtension(&temp_save); - - return (GIF_OK); -} -#endif /* _GBA_NO_FILEIO */ diff --git a/WDL/giflib/egif_lib.c b/WDL/giflib/egif_lib.c deleted file mode 100644 index 91eae003..00000000 --- a/WDL/giflib/egif_lib.c +++ /dev/null @@ -1,1103 +0,0 @@ -/****************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber Ver 1.1, Aug. 1990 - ****************************************************************************** - * The kernel of the GIF Encoding process can be found here. - ****************************************************************************** - * History: - * 14 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). - * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) - *****************************************************************************/ - -#include "config.h" - -/* Find a thirty-two bit int type */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif - -#ifdef __MSDOS__ -#include -#include -#include -#else -#include -#include -#ifdef R6000 - -/* FIXME: What is sys/mode.h? Can we substitute a check for this file rather - * than a check based on machine type? - */ -#include -#endif -#endif /* __MSDOS__ */ - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#include -#include -#include -#include "gif_lib.h" -#include "gif_lib_private.h" - -/* #define DEBUG_NO_PREFIX Dump only compressed data. */ - -/* Masks given codes to BitsPerPixel, to make sure all codes are in range: */ -static GifPixelType CodeMask[] = { - 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff -}; - -static char GifVersionPrefix[GIF_STAMP_LEN + 1] = GIF87_STAMP; - -#define WRITE(_gif,_buf,_len) \ - (((GifFilePrivateType*)_gif->Private)->Write ? \ - ((GifFilePrivateType*)_gif->Private)->Write(_gif,_buf,_len) : \ - fwrite(_buf, 1, _len, ((GifFilePrivateType*)_gif->Private)->File)) - -static int EGifPutWord(int Word, GifFileType * GifFile); -static int EGifSetupCompress(GifFileType * GifFile); -static int EGifCompressLine(GifFileType * GifFile, GifPixelType * Line, - int LineLen); -static int EGifCompressOutput(GifFileType * GifFile, int Code); -static int EGifBufferedOutput(GifFileType * GifFile, GifByteType * Buf, - int c); - -/****************************************************************************** - * Open a new gif file for write, given by its name. If TestExistance then - * if the file exists this routines fails (returns NULL). - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ -GifFileType * -EGifOpenFileName(const char *FileName, - int TestExistance) { - - int FileHandle; - GifFileType *GifFile; - - if (TestExistance) - FileHandle = open(FileName, O_WRONLY | O_CREAT | O_EXCL -#if defined(__MSDOS__) || defined(_WIN32) - | O_BINARY -#endif /* __MSDOS__ */ - , 0644 ); - else - FileHandle = open(FileName, O_WRONLY | O_CREAT | O_TRUNC -#if defined(__MSDOS__) || defined(_WIN32) - | O_BINARY -#endif /* __MSDOS__ */ - , 0644 ); - - if (FileHandle == -1) { - _GifError = E_GIF_ERR_OPEN_FAILED; - return NULL; - } - GifFile = EGifOpenFileHandle(FileHandle); - if (GifFile == (GifFileType *) NULL) - close(FileHandle); - return GifFile; -} - -/****************************************************************************** - * Update a new gif file, given its file handle, which must be opened for - * write in binary mode. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ -GifFileType * -EGifOpenFileHandle(int FileHandle) { - - GifFileType *GifFile; - GifFilePrivateType *Private; - FILE *f; - - GifFile = (GifFileType *) malloc(sizeof(GifFileType)); - if (GifFile == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - memset(GifFile, '\0', sizeof(GifFileType)); - - Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); - if (Private == NULL) { - free(GifFile); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - if ((Private->HashTable = _InitHashTable()) == NULL) { - free(GifFile); - free(Private); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - -#ifdef __MSDOS__ - setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ -#endif /* __MSDOS__ */ - - f = fdopen(FileHandle, "wb"); /* Make it into a stream: */ - -#ifdef __MSDOS__ - setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream - * buffer. */ -#endif /* __MSDOS__ */ - - GifFile->Private = (VoidPtr)Private; - Private->FileHandle = FileHandle; - Private->File = f; - Private->FileState = FILE_STATE_WRITE; - - Private->Write = (OutputFunc) 0; /* No user write routine (MRB) */ - GifFile->UserData = (VoidPtr) 0; /* No user write handle (MRB) */ - - _GifError = 0; - - return GifFile; -} - -/****************************************************************************** - * Output constructor that takes user supplied output function. - * Basically just a copy of EGifOpenFileHandle. (MRB) - *****************************************************************************/ -GifFileType * -EGifOpen(void *userData, - OutputFunc writeFunc) { - - GifFileType *GifFile; - GifFilePrivateType *Private; - - GifFile = (GifFileType *)malloc(sizeof(GifFileType)); - if (GifFile == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - memset(GifFile, '\0', sizeof(GifFileType)); - - Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); - if (Private == NULL) { - free(GifFile); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - Private->HashTable = _InitHashTable(); - if (Private->HashTable == NULL) { - free (GifFile); - free (Private); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return NULL; - } - - GifFile->Private = (VoidPtr) Private; - Private->FileHandle = 0; - Private->File = (FILE *) 0; - Private->FileState = FILE_STATE_WRITE; - - Private->Write = writeFunc; /* User write routine (MRB) */ - GifFile->UserData = userData; /* User write handle (MRB) */ - - _GifError = 0; - - return GifFile; -} - -/****************************************************************************** - * Routine to set current GIF version. All files open for write will be - * using this version until next call to this routine. Version consists of - * 3 characters as "87a" or "89a". No test is made to validate the version. - *****************************************************************************/ -void -EGifSetGifVersion(const char *Version) { - strncpy(GifVersionPrefix + GIF_VERSION_POS, Version, 3); -} - -/****************************************************************************** - * This routine should be called before any other EGif calls, immediately - * follows the GIF file openning. - *****************************************************************************/ -int -EGifPutScreenDesc(GifFileType * GifFile, - int Width, - int Height, - int ColorRes, - int BackGround, - const ColorMapObject * ColorMap) { - - int i; - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - if (Private->FileState & FILE_STATE_SCREEN) { - /* If already has screen descriptor - something is wrong! */ - _GifError = E_GIF_ERR_HAS_SCRN_DSCR; - return GIF_ERROR; - } - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - -/* First write the version prefix into the file. */ -#ifndef DEBUG_NO_PREFIX - if (WRITE(GifFile, (unsigned char *)GifVersionPrefix, - strlen(GifVersionPrefix)) != strlen(GifVersionPrefix)) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } -#endif /* DEBUG_NO_PREFIX */ - - GifFile->SWidth = Width; - GifFile->SHeight = Height; - GifFile->SColorResolution = ColorRes; - GifFile->SBackGroundColor = BackGround; - if (ColorMap) { - GifFile->SColorMap = MakeMapObject(ColorMap->ColorCount, - ColorMap->Colors); - if (GifFile->SColorMap == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } else - GifFile->SColorMap = NULL; - - /* - * Put the logical screen descriptor into the file: - */ - /* Logical Screen Descriptor: Dimensions */ - EGifPutWord(Width, GifFile); - EGifPutWord(Height, GifFile); - - /* Logical Screen Descriptor: Packed Fields */ - /* Note: We have actual size of the color table default to the largest - * possible size (7+1 == 8 bits) because the decoder can use it to decide - * how to display the files. - */ - Buf[0] = (ColorMap ? 0x80 : 0x00) | /* Yes/no global colormap */ - ((ColorRes - 1) << 4) | /* Bits allocated to each primary color */ - (ColorMap ? ColorMap->BitsPerPixel - 1 : 0x07 ); /* Actual size of the - color table. */ - Buf[1] = BackGround; /* Index into the ColorTable for background color */ - Buf[2] = 0; /* Pixel Aspect Ratio */ -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 3); -#endif /* DEBUG_NO_PREFIX */ - - /* If we have Global color map - dump it also: */ -#ifndef DEBUG_NO_PREFIX - if (ColorMap != NULL) - for (i = 0; i < ColorMap->ColorCount; i++) { - /* Put the ColorMap out also: */ - Buf[0] = ColorMap->Colors[i].Red; - Buf[1] = ColorMap->Colors[i].Green; - Buf[2] = ColorMap->Colors[i].Blue; - if (WRITE(GifFile, Buf, 3) != 3) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - } -#endif /* DEBUG_NO_PREFIX */ - - /* Mark this file as has screen descriptor, and no pixel written yet: */ - Private->FileState |= FILE_STATE_SCREEN; - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called before any attempt to dump an image - any - * call to any of the pixel dump routines. - *****************************************************************************/ -int -EGifPutImageDesc(GifFileType * GifFile, - int Left, - int Top, - int Width, - int Height, - int Interlace, - const ColorMapObject * ColorMap) { - - int i; - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (Private->FileState & FILE_STATE_IMAGE && -#if defined(__MSDOS__) || defined(__GNUC__) - Private->PixelCount > 0xffff0000UL) { -#else - Private->PixelCount > 0xffff0000) { -#endif /* __MSDOS__ */ - /* If already has active image descriptor - something is wrong! */ - _GifError = E_GIF_ERR_HAS_IMAG_DSCR; - return GIF_ERROR; - } - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - GifFile->Image.Left = Left; - GifFile->Image.Top = Top; - GifFile->Image.Width = Width; - GifFile->Image.Height = Height; - GifFile->Image.Interlace = Interlace; - if (ColorMap) { - GifFile->Image.ColorMap = MakeMapObject(ColorMap->ColorCount, - ColorMap->Colors); - if (GifFile->Image.ColorMap == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } else { - GifFile->Image.ColorMap = NULL; - } - - /* Put the image descriptor into the file: */ - Buf[0] = ','; /* Image seperator character. */ -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 1); -#endif /* DEBUG_NO_PREFIX */ - EGifPutWord(Left, GifFile); - EGifPutWord(Top, GifFile); - EGifPutWord(Width, GifFile); - EGifPutWord(Height, GifFile); - Buf[0] = (ColorMap ? 0x80 : 0x00) | - (Interlace ? 0x40 : 0x00) | - (ColorMap ? ColorMap->BitsPerPixel - 1 : 0); -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 1); -#endif /* DEBUG_NO_PREFIX */ - - /* If we have Global color map - dump it also: */ -#ifndef DEBUG_NO_PREFIX - if (ColorMap != NULL) - for (i = 0; i < ColorMap->ColorCount; i++) { - /* Put the ColorMap out also: */ - Buf[0] = ColorMap->Colors[i].Red; - Buf[1] = ColorMap->Colors[i].Green; - Buf[2] = ColorMap->Colors[i].Blue; - if (WRITE(GifFile, Buf, 3) != 3) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - } -#endif /* DEBUG_NO_PREFIX */ - if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) { - _GifError = E_GIF_ERR_NO_COLOR_MAP; - return GIF_ERROR; - } - - /* Mark this file as has screen descriptor: */ - Private->FileState |= FILE_STATE_IMAGE; - Private->PixelCount = (long)Width *(long)Height; - - EGifSetupCompress(GifFile); /* Reset compress algorithm parameters. */ - - return GIF_OK; -} - -/****************************************************************************** - * Put one full scanned line (Line) of length LineLen into GIF file. - *****************************************************************************/ -int -EGifPutLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - int i; - GifPixelType Mask; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - if (!LineLen) - LineLen = GifFile->Image.Width; - if (Private->PixelCount < (unsigned)LineLen) { - _GifError = E_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - Private->PixelCount -= LineLen; - - /* Make sure the codes are not out of bit range, as we might generate - * wrong code (because of overflow when we combine them) in this case: */ - Mask = CodeMask[Private->BitsPerPixel]; - for (i = 0; i < LineLen; i++) - Line[i] &= Mask; - - return EGifCompressLine(GifFile, Line, LineLen); -} - -/****************************************************************************** - * Put one pixel (Pixel) into GIF file. - *****************************************************************************/ -int -EGifPutPixel(GifFileType * GifFile, - GifPixelType Pixel) { - - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - if (Private->PixelCount == 0) { - _GifError = E_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - --Private->PixelCount; - - /* Make sure the code is not out of bit range, as we might generate - * wrong code (because of overflow when we combine them) in this case: */ - Pixel &= CodeMask[Private->BitsPerPixel]; - - return EGifCompressLine(GifFile, &Pixel, 1); -} - -/****************************************************************************** - * Put a comment into GIF file using the GIF89 comment extension block. - *****************************************************************************/ -int -EGifPutComment(GifFileType * GifFile, - const char *Comment) { - - unsigned int length = strlen(Comment); - char *buf; - - length = strlen(Comment); - if (length <= 255) { - return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE, - length, Comment); - } else { - buf = (char *)Comment; - if (EGifPutExtensionFirst(GifFile, COMMENT_EXT_FUNC_CODE, 255, buf) - == GIF_ERROR) { - return GIF_ERROR; - } - length -= 255; - buf = buf + 255; - - /* Break the comment into 255 byte sub blocks */ - while (length > 255) { - if (EGifPutExtensionNext(GifFile, 0, 255, buf) == GIF_ERROR) { - return GIF_ERROR; - } - buf = buf + 255; - length -= 255; - } - /* Output any partial block and the clear code. */ - if (length > 0) { - if (EGifPutExtensionLast(GifFile, 0, length, buf) == GIF_ERROR) { - return GIF_ERROR; - } - } else { - if (EGifPutExtensionLast(GifFile, 0, 0, NULL) == GIF_ERROR) { - return GIF_ERROR; - } - } - } - return GIF_OK; -} - -/****************************************************************************** - * Put a first extension block (see GIF manual) into gif file. Here more - * extensions can be dumped using EGifPutExtensionNext until - * EGifPutExtensionLast is invoked. - *****************************************************************************/ -int -EGifPutExtensionFirst(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - if (ExtCode == 0) { - WRITE(GifFile, (GifByteType *)&ExtLen, 1); - } else { - Buf[0] = '!'; - Buf[1] = ExtCode; - Buf[2] = ExtLen; - WRITE(GifFile, Buf, 3); - } - - WRITE(GifFile, Extension, ExtLen); - - return GIF_OK; -} - -/****************************************************************************** - * Put a middle extension block (see GIF manual) into gif file. - *****************************************************************************/ -int -EGifPutExtensionNext(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - Buf = ExtLen; - WRITE(GifFile, &Buf, 1); - WRITE(GifFile, Extension, ExtLen); - - return GIF_OK; -} - -/****************************************************************************** - * Put a last extension block (see GIF manual) into gif file. - *****************************************************************************/ -int -EGifPutExtensionLast(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - /* If we are given an extension sub-block output it now. */ - if (ExtLen > 0) { - Buf = ExtLen; - WRITE(GifFile, &Buf, 1); - WRITE(GifFile, Extension, ExtLen); - } - - /* Write the block terminator */ - Buf = 0; - WRITE(GifFile, &Buf, 1); - - return GIF_OK; -} - -/****************************************************************************** - * Put an extension block (see GIF manual) into gif file. - * Warning: This function is only useful for Extension blocks that have at - * most one subblock. Extensions with more than one subblock need to use the - * EGifPutExtension{First,Next,Last} functions instead. - *****************************************************************************/ -int -EGifPutExtension(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - - GifByteType Buf[3]; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - if (ExtCode == 0) - WRITE(GifFile, (GifByteType *)&ExtLen, 1); - else { - Buf[0] = '!'; /* Extension Introducer 0x21 */ - Buf[1] = ExtCode; /* Extension Label */ - Buf[2] = ExtLen; /* Extension length */ - WRITE(GifFile, Buf, ExtCode==0xff ? 2 : 3); - } - WRITE(GifFile, Extension, ExtLen); - Buf[0] = 0; - WRITE(GifFile, Buf, 1); - - return GIF_OK; -} - -/****************************************************************************** - * Put the image code in compressed form. This routine can be called if the - * information needed to be piped out as is. Obviously this is much faster - * than decoding and encoding again. This routine should be followed by calls - * to EGifPutCodeNext, until NULL block is given. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -int -EGifPutCode(GifFileType * GifFile, - int CodeSize, - const GifByteType * CodeBlock) { - - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - /* No need to dump code size as Compression set up does any for us: */ - /* - * Buf = CodeSize; - * if (WRITE(GifFile, &Buf, 1) != 1) { - * _GifError = E_GIF_ERR_WRITE_FAILED; - * return GIF_ERROR; - * } - */ - - return EGifPutCodeNext(GifFile, CodeBlock); -} - -/****************************************************************************** - * Continue to put the image code in compressed form. This routine should be - * called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If - * given buffer pointer is NULL, empty block is written to mark end of code. - *****************************************************************************/ -int -EGifPutCodeNext(GifFileType * GifFile, - const GifByteType * CodeBlock) { - - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - - if (CodeBlock != NULL) { - if (WRITE(GifFile, CodeBlock, CodeBlock[0] + 1) - != (unsigned)(CodeBlock[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - } else { - Buf = 0; - if (WRITE(GifFile, &Buf, 1) != 1) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - Private->PixelCount = 0; /* And local info. indicate image read. */ - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called last, to close GIF file. - *****************************************************************************/ -int -EGifCloseFile(GifFileType * GifFile) { - - GifByteType Buf; - GifFilePrivateType *Private; - FILE *File; - - if (GifFile == NULL) - return GIF_ERROR; - - Private = (GifFilePrivateType *) GifFile->Private; - if (!IS_WRITEABLE(Private)) { - /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; - return GIF_ERROR; - } - - File = Private->File; - - Buf = ';'; - WRITE(GifFile, &Buf, 1); - - if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - if (GifFile->SColorMap) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - } - if (Private) { - if (Private->HashTable) { - free((char *) Private->HashTable); - } - free((char *) Private); - } - free(GifFile); - - if (File && fclose(File) != 0) { - _GifError = E_GIF_ERR_CLOSE_FAILED; - return GIF_ERROR; - } - return GIF_OK; -} - -/****************************************************************************** - * Put 2 bytes (word) into the given file: - *****************************************************************************/ -static int -EGifPutWord(int Word, - GifFileType * GifFile) { - - unsigned char c[2]; - - c[0] = Word & 0xff; - c[1] = (Word >> 8) & 0xff; -#ifndef DEBUG_NO_PREFIX - if (WRITE(GifFile, c, 2) == 2) - return GIF_OK; - else - return GIF_ERROR; -#else - return GIF_OK; -#endif /* DEBUG_NO_PREFIX */ -} - -/****************************************************************************** - * Setup the LZ compression for this image: - *****************************************************************************/ -static int -EGifSetupCompress(GifFileType * GifFile) { - - int BitsPerPixel; - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - /* Test and see what color map to use, and from it # bits per pixel: */ - if (GifFile->Image.ColorMap) - BitsPerPixel = GifFile->Image.ColorMap->BitsPerPixel; - else if (GifFile->SColorMap) - BitsPerPixel = GifFile->SColorMap->BitsPerPixel; - else { - _GifError = E_GIF_ERR_NO_COLOR_MAP; - return GIF_ERROR; - } - - Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel); - WRITE(GifFile, &Buf, 1); /* Write the Code size to file. */ - - Private->Buf[0] = 0; /* Nothing was output yet. */ - Private->BitsPerPixel = BitsPerPixel; - Private->ClearCode = (1 << BitsPerPixel); - Private->EOFCode = Private->ClearCode + 1; - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ - Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ - Private->CrntCode = FIRST_CODE; /* Signal that this is first one! */ - Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ - Private->CrntShiftDWord = 0; - - /* Clear hash table and send Clear to make sure the decoder do the same. */ - _ClearHashTable(Private->HashTable); - - if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - return GIF_OK; -} - -/****************************************************************************** - * The LZ compression routine: - * This version compresses the given buffer Line of length LineLen. - * This routine can be called a few times (one per scan line, for example), in - * order to complete the whole image. -******************************************************************************/ -static int -EGifCompressLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - int i = 0, CrntCode, NewCode; - unsigned long NewKey; - GifPixelType Pixel; - GifHashTableType *HashTable; - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - - HashTable = Private->HashTable; - - if (Private->CrntCode == FIRST_CODE) /* Its first time! */ - CrntCode = Line[i++]; - else - CrntCode = Private->CrntCode; /* Get last code in compression. */ - - while (i < LineLen) { /* Decode LineLen items. */ - Pixel = Line[i++]; /* Get next pixel from stream. */ - /* Form a new unique key to search hash table for the code combines - * CrntCode as Prefix string with Pixel as postfix char. - */ - NewKey = (((UINT32) CrntCode) << 8) + Pixel; - if ((NewCode = _ExistsHashTable(HashTable, NewKey)) >= 0) { - /* This Key is already there, or the string is old one, so - * simple take new code as our CrntCode: - */ - CrntCode = NewCode; - } else { - /* Put it in hash table, output the prefix code, and make our - * CrntCode equal to Pixel. - */ - if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - CrntCode = Pixel; - - /* If however the HashTable if full, we send a clear first and - * Clear the hash table. - */ - if (Private->RunningCode >= LZ_MAX_CODE) { - /* Time to do some clearance: */ - if (EGifCompressOutput(GifFile, Private->ClearCode) - == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = Private->BitsPerPixel + 1; - Private->MaxCode1 = 1 << Private->RunningBits; - _ClearHashTable(HashTable); - } else { - /* Put this unique key with its relative Code in hash table: */ - _InsertHashTable(HashTable, NewKey, Private->RunningCode++); - } - } - - } - - /* Preserve the current state of the compression algorithm: */ - Private->CrntCode = CrntCode; - - if (Private->PixelCount == 0) { - /* We are done - output last Code and flush output buffers: */ - if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; - return GIF_ERROR; - } - } - - return GIF_OK; -} - -/****************************************************************************** - * The LZ compression output routine: - * This routine is responsible for the compression of the bit stream into - * 8 bits (bytes) packets. - * Returns GIF_OK if written succesfully. - *****************************************************************************/ -static int -EGifCompressOutput(GifFileType * GifFile, - int Code) { - - GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - int retval = GIF_OK; - - if (Code == FLUSH_OUTPUT) { - while (Private->CrntShiftState > 0) { - /* Get Rid of what is left in DWord, and flush it. */ - if (EGifBufferedOutput(GifFile, Private->Buf, - Private->CrntShiftDWord & 0xff) == GIF_ERROR) - retval = GIF_ERROR; - Private->CrntShiftDWord >>= 8; - Private->CrntShiftState -= 8; - } - Private->CrntShiftState = 0; /* For next time. */ - if (EGifBufferedOutput(GifFile, Private->Buf, - FLUSH_OUTPUT) == GIF_ERROR) - retval = GIF_ERROR; - } else { - Private->CrntShiftDWord |= ((long)Code) << Private->CrntShiftState; - Private->CrntShiftState += Private->RunningBits; - while (Private->CrntShiftState >= 8) { - /* Dump out full bytes: */ - if (EGifBufferedOutput(GifFile, Private->Buf, - Private->CrntShiftDWord & 0xff) == GIF_ERROR) - retval = GIF_ERROR; - Private->CrntShiftDWord >>= 8; - Private->CrntShiftState -= 8; - } - } - - /* If code cannt fit into RunningBits bits, must raise its size. Note */ - /* however that codes above 4095 are used for special signaling. */ - if (Private->RunningCode >= Private->MaxCode1 && Code <= 4095) { - Private->MaxCode1 = 1 << ++Private->RunningBits; - } - - return retval; -} - -/****************************************************************************** - * This routines buffers the given characters until 255 characters are ready - * to be output. If Code is equal to -1 the buffer is flushed (EOF). - * The buffer is Dumped with first byte as its size, as GIF format requires. - * Returns GIF_OK if written succesfully. - *****************************************************************************/ -static int -EGifBufferedOutput(GifFileType * GifFile, - GifByteType * Buf, - int c) { - - if (c == FLUSH_OUTPUT) { - /* Flush everything out. */ - if (Buf[0] != 0 - && WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - /* Mark end of compressed data, by an empty block (see GIF doc): */ - Buf[0] = 0; - if (WRITE(GifFile, Buf, 1) != 1) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - } else { - if (Buf[0] == 255) { - /* Dump out this buffer - it is full: */ - if (WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; - return GIF_ERROR; - } - Buf[0] = 0; - } - Buf[++Buf[0]] = c; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine writes to disk an in-core representation of a GIF previously - * created by DGifSlurp(). - *****************************************************************************/ -int -EGifSpew(GifFileType * GifFileOut) { - - int i, j, gif89 = FALSE; - int bOff; /* Block Offset for adding sub blocks in Extensions */ - char SavedStamp[GIF_STAMP_LEN + 1]; - - for (i = 0; i < GifFileOut->ImageCount; i++) { - for (j = 0; j < GifFileOut->SavedImages[i].ExtensionBlockCount; j++) { - int function = - GifFileOut->SavedImages[i].ExtensionBlocks[j].Function; - - if (function == COMMENT_EXT_FUNC_CODE - || function == GRAPHICS_EXT_FUNC_CODE - || function == PLAINTEXT_EXT_FUNC_CODE - || function == APPLICATION_EXT_FUNC_CODE) - gif89 = TRUE; - } - } - - strncpy(SavedStamp, GifVersionPrefix, GIF_STAMP_LEN); - if (gif89) { - strncpy(GifVersionPrefix, GIF89_STAMP, GIF_STAMP_LEN); - } else { - strncpy(GifVersionPrefix, GIF87_STAMP, GIF_STAMP_LEN); - } - if (EGifPutScreenDesc(GifFileOut, - GifFileOut->SWidth, - GifFileOut->SHeight, - GifFileOut->SColorResolution, - GifFileOut->SBackGroundColor, - GifFileOut->SColorMap) == GIF_ERROR) { - strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); - return (GIF_ERROR); - } - strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); - - for (i = 0; i < GifFileOut->ImageCount; i++) { - SavedImage *sp = &GifFileOut->SavedImages[i]; - int SavedHeight = sp->ImageDesc.Height; - int SavedWidth = sp->ImageDesc.Width; - ExtensionBlock *ep; - - /* this allows us to delete images by nuking their rasters */ - if (sp->RasterBits == NULL) - continue; - - if (sp->ExtensionBlocks) { - for (j = 0; j < sp->ExtensionBlockCount; j++) { - ep = &sp->ExtensionBlocks[j]; - if (j == sp->ExtensionBlockCount - 1 || (ep+1)->Function != 0) { - /*** FIXME: Must check whether outputting - * is ever valid or if we should just - * drop anything with a 0 for the Function. (And whether - * we should drop here or in EGifPutExtension) - */ - if (EGifPutExtension(GifFileOut, - (ep->Function != 0) ? ep->Function : '\0', - ep->ByteCount, - ep->Bytes) == GIF_ERROR) { - return (GIF_ERROR); - } - } else { - EGifPutExtensionFirst(GifFileOut, ep->Function, ep->ByteCount, ep->Bytes); - for (bOff = j+1; bOff < sp->ExtensionBlockCount; bOff++) { - ep = &sp->ExtensionBlocks[bOff]; - if (ep->Function != 0) { - break; - } - EGifPutExtensionNext(GifFileOut, 0, - ep->ByteCount, ep->Bytes); - } - EGifPutExtensionLast(GifFileOut, 0, 0, NULL); - j = bOff-1; - } - } - } - - if (EGifPutImageDesc(GifFileOut, - sp->ImageDesc.Left, - sp->ImageDesc.Top, - SavedWidth, - SavedHeight, - sp->ImageDesc.Interlace, - sp->ImageDesc.ColorMap) == GIF_ERROR) - return (GIF_ERROR); - - for (j = 0; j < SavedHeight; j++) { - if (EGifPutLine(GifFileOut, - sp->RasterBits + j * SavedWidth, - SavedWidth) == GIF_ERROR) - return (GIF_ERROR); - } - } - - if (EGifCloseFile(GifFileOut) == GIF_ERROR) - return (GIF_ERROR); - - return (GIF_OK); -} diff --git a/WDL/giflib/gif_hash.c b/WDL/giflib/gif_hash.c deleted file mode 100644 index 82073723..00000000 --- a/WDL/giflib/gif_hash.c +++ /dev/null @@ -1,152 +0,0 @@ -/***************************************************************************** -* "Gif-Lib" - Yet another gif library. * -* * -* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * -****************************************************************************** -* Module to support the following operations: * -* * -* 1. InitHashTable - initialize hash table. * -* 2. ClearHashTable - clear the hash table to an empty state. * -* 2. InsertHashTable - insert one item into data structure. * -* 3. ExistsHashTable - test if item exists in data structure. * -* * -* This module is used to hash the GIF codes during encoding. * -****************************************************************************** -* History: * -* 14 Jun 89 - Version 1.0 by Gershon Elber. * -*****************************************************************************/ - -#include "config.h" - -/* Find a thirty-two bit int type */ -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef __MSDOS__ -#include -#include -#include -#else -#include -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#include -#include -#include "gif_lib.h" -#include "gif_hash.h" -#include "gif_lib_private.h" - -/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */ - -#ifdef DEBUG_HIT_RATE -static long NumberOfTests = 0, - NumberOfMisses = 0; -#endif /* DEBUG_HIT_RATE */ - -static int KeyItem(UINT32 Item); - -/****************************************************************************** -* Initialize HashTable - allocate the memory needed and clear it. * -******************************************************************************/ -GifHashTableType *_InitHashTable(void) -{ - GifHashTableType *HashTable; - - if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType))) - == NULL) - return NULL; - - _ClearHashTable(HashTable); - - return HashTable; -} - -/****************************************************************************** -* Routine to clear the HashTable to an empty state. * -* This part is a little machine depended. Use the commented part otherwise. * -******************************************************************************/ -void _ClearHashTable(GifHashTableType *HashTable) -{ - memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(UINT32)); -} - -/****************************************************************************** -* Routine to insert a new Item into the HashTable. The data is assumed to be * -* new one. * -******************************************************************************/ -void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code) -{ - int HKey = KeyItem(Key); - UINT32 *HTable = HashTable -> HTable; - -#ifdef DEBUG_HIT_RATE - NumberOfTests++; - NumberOfMisses++; -#endif /* DEBUG_HIT_RATE */ - - while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { -#ifdef DEBUG_HIT_RATE - NumberOfMisses++; -#endif /* DEBUG_HIT_RATE */ - HKey = (HKey + 1) & HT_KEY_MASK; - } - HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code); -} - -/****************************************************************************** -* Routine to test if given Key exists in HashTable and if so returns its code * -* Returns the Code if key was found, -1 if not. * -******************************************************************************/ -int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key) -{ - int HKey = KeyItem(Key); - UINT32 *HTable = HashTable -> HTable, HTKey; - -#ifdef DEBUG_HIT_RATE - NumberOfTests++; - NumberOfMisses++; -#endif /* DEBUG_HIT_RATE */ - - while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { -#ifdef DEBUG_HIT_RATE - NumberOfMisses++; -#endif /* DEBUG_HIT_RATE */ - if (Key == HTKey) return HT_GET_CODE(HTable[HKey]); - HKey = (HKey + 1) & HT_KEY_MASK; - } - - return -1; -} - -/****************************************************************************** -* Routine to generate an HKey for the hashtable out of the given unique key. * -* The given Key is assumed to be 20 bits as follows: lower 8 bits are the * -* new postfix character, while the upper 12 bits are the prefix code. * -* Because the average hit ratio is only 2 (2 hash references per entry), * -* evaluating more complex keys (such as twin prime keys) does not worth it! * -******************************************************************************/ -static int KeyItem(UINT32 Item) -{ - return ((Item >> 12) ^ Item) & HT_KEY_MASK; -} - -#ifdef DEBUG_HIT_RATE -/****************************************************************************** -* Debugging routine to print the hit ratio - number of times the hash table * -* was tested per operation. This routine was used to test the KeyItem routine * -******************************************************************************/ -void HashTablePrintHitRatio(void) -{ - printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", - NumberOfMisses, NumberOfTests, - NumberOfMisses * 100 / NumberOfTests); -} -#endif /* DEBUG_HIT_RATE */ diff --git a/WDL/giflib/gif_hash.h b/WDL/giflib/gif_hash.h deleted file mode 100644 index f45e34d8..00000000 --- a/WDL/giflib/gif_hash.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** -* Declarations, global to other of the GIF-HASH.C module. * -* * -* Written by Gershon Elber, Jun 1989 * -******************************************************************************* -* History: * -* 14 Jun 89 - Version 1.0 by Gershon Elber. * -******************************************************************************/ - -#ifndef _GIF_HASH_H_ -#define _GIF_HASH_H_ - -#include "config.h" - -/* Find a thirty-two bit int type */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_BASETSD_H -#include -#endif - -#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ -#define HT_KEY_MASK 0x1FFF /* 13bits keys */ -#define HT_KEY_NUM_BITS 13 /* 13bits keys */ -#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ -#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ - -/* The 32 bits of the long are divided into two parts for the key & code: */ -/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ -/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ -/* The key is the upper 20 bits. The code is the lower 12. */ -#define HT_GET_KEY(l) (l >> 12) -#define HT_GET_CODE(l) (l & 0x0FFF) -#define HT_PUT_KEY(l) (l << 12) -#define HT_PUT_CODE(l) (l & 0x0FFF) - -typedef struct GifHashTableType { - UINT32 HTable[HT_SIZE]; -} GifHashTableType; - -GifHashTableType *_InitHashTable(void); -void _ClearHashTable(GifHashTableType *HashTable); -void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code); -int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key); - -#endif /* _GIF_HASH_H_ */ diff --git a/WDL/giflib/gif_lib.h b/WDL/giflib/gif_lib.h deleted file mode 100644 index be644ae0..00000000 --- a/WDL/giflib/gif_lib.h +++ /dev/null @@ -1,336 +0,0 @@ -/****************************************************************************** - * In order to make life a little bit easier when using the GIF file format, - * this library was written, and which does all the dirty work... - * - * Written by Gershon Elber, Jun. 1989 - * Hacks by Eric S. Raymond, Sep. 1992 - ****************************************************************************** - * History: - * 14 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names) - * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp) - * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) - * 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code) - *****************************************************************************/ - -#ifndef _GIF_LIB_H_ -#define _GIF_LIB_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define GIF_LIB_VERSION " Version 4.1, " - -#define GIF_ERROR 0 -#define GIF_OK 1 - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -#ifndef NULL -#define NULL 0 -#endif /* NULL */ - -#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ -#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 -#define GIF_VERSION_POS 3 /* Version first character in stamp. */ -#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */ -#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */ - -#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */ - -typedef int GifBooleanType; -typedef unsigned char GifPixelType; -typedef unsigned char *GifRowType; -typedef unsigned char GifByteType; -#ifdef _GBA_OPTMEM - typedef unsigned short GifPrefixType; - typedef short GifWord; -#else - typedef unsigned int GifPrefixType; - typedef int GifWord; -#endif - -#define GIF_MESSAGE(Msg) -#define GIF_EXIT(Msg) - -#ifdef SYSV -#define VoidPtr char * -#else -#define VoidPtr void * -#endif /* SYSV */ - -typedef struct GifColorType { - GifByteType Red, Green, Blue; -} GifColorType; - -typedef struct ColorMapObject { - int ColorCount; - int BitsPerPixel; - GifColorType *Colors; /* on malloc(3) heap */ -} ColorMapObject; - -typedef struct GifImageDesc { - GifWord Left, Top, Width, Height, /* Current image dimensions. */ - Interlace; /* Sequential/Interlaced lines. */ - ColorMapObject *ColorMap; /* The local color map */ -} GifImageDesc; - -typedef struct GifFileType { - GifWord SWidth, SHeight, /* Screen dimensions. */ - SColorResolution, /* How many colors can we generate? */ - SBackGroundColor; /* I hope you understand this one... */ - ColorMapObject *SColorMap; /* NULL if not exists. */ - int ImageCount; /* Number of current image */ - GifImageDesc Image; /* Block describing current image */ - struct SavedImage *SavedImages; /* Use this to accumulate file state */ - VoidPtr UserData; /* hook to attach user data (TVT) */ - VoidPtr Private; /* Don't mess with this! */ -} GifFileType; - -typedef enum { - UNDEFINED_RECORD_TYPE, - SCREEN_DESC_RECORD_TYPE, - IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */ - EXTENSION_RECORD_TYPE, /* Begin with '!' */ - TERMINATE_RECORD_TYPE /* Begin with ';' */ -} GifRecordType; - -/* DumpScreen2Gif routine constants identify type of window/screen to dump. - * Note all values below 1000 are reserved for the IBMPC different display - * devices (it has many!) and are compatible with the numbering TC2.0 - * (Turbo C 2.0 compiler for IBM PC) gives to these devices. - */ -typedef enum { - GIF_DUMP_SGI_WINDOW = 1000, - GIF_DUMP_X_WINDOW = 1001 -} GifScreenDumpType; - -/* func type to read gif data from arbitrary sources (TVT) */ -typedef int (*InputFunc) (GifFileType *, GifByteType *, int); - -/* func type to write gif data ro arbitrary targets. - * Returns count of bytes written. (MRB) - */ -typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int); - -/****************************************************************************** - * GIF89 extension function codes -******************************************************************************/ - -#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ -#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */ -#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ -#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ - -/****************************************************************************** - * O.K., here are the routines one can access in order to encode GIF file: - * (GIF_LIB file EGIF_LIB.C). -******************************************************************************/ - -GifFileType *EGifOpenFileName(const char *GifFileName, - int GifTestExistance); -GifFileType *EGifOpenFileHandle(int GifFileHandle); -GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc); - -int EGifSpew(GifFileType * GifFile); -void EGifSetGifVersion(const char *Version); -int EGifPutScreenDesc(GifFileType * GifFile, - int GifWidth, int GifHeight, int GifColorRes, - int GifBackGround, - const ColorMapObject * GifColorMap); -int EGifPutImageDesc(GifFileType * GifFile, int GifLeft, int GifTop, - int Width, int GifHeight, int GifInterlace, - const ColorMapObject * GifColorMap); -int EGifPutLine(GifFileType * GifFile, GifPixelType * GifLine, - int GifLineLen); -int EGifPutPixel(GifFileType * GifFile, GifPixelType GifPixel); -int EGifPutComment(GifFileType * GifFile, const char *GifComment); -int EGifPutExtensionFirst(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtensionNext(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtensionLast(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtension(GifFileType * GifFile, int GifExtCode, int GifExtLen, - const VoidPtr GifExtension); -int EGifPutCode(GifFileType * GifFile, int GifCodeSize, - const GifByteType * GifCodeBlock); -int EGifPutCodeNext(GifFileType * GifFile, - const GifByteType * GifCodeBlock); -int EGifCloseFile(GifFileType * GifFile); - -#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */ -#define E_GIF_ERR_WRITE_FAILED 2 -#define E_GIF_ERR_HAS_SCRN_DSCR 3 -#define E_GIF_ERR_HAS_IMAG_DSCR 4 -#define E_GIF_ERR_NO_COLOR_MAP 5 -#define E_GIF_ERR_DATA_TOO_BIG 6 -#define E_GIF_ERR_NOT_ENOUGH_MEM 7 -#define E_GIF_ERR_DISK_IS_FULL 8 -#define E_GIF_ERR_CLOSE_FAILED 9 -#define E_GIF_ERR_NOT_WRITEABLE 10 - -/****************************************************************************** - * O.K., here are the routines one can access in order to decode GIF file: - * (GIF_LIB file DGIF_LIB.C). - *****************************************************************************/ -#ifndef _GBA_NO_FILEIO -GifFileType *DGifOpenFileName(const char *GifFileName); -GifFileType *DGifOpenFileHandle(int GifFileHandle); -int DGifSlurp(GifFileType * GifFile); -#endif /* _GBA_NO_FILEIO */ -GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); /* new one - * (TVT) */ -int DGifGetScreenDesc(GifFileType * GifFile); -int DGifGetRecordType(GifFileType * GifFile, GifRecordType * GifType); -int DGifGetImageDesc(GifFileType * GifFile); -int DGifGetLine(GifFileType * GifFile, GifPixelType * GifLine, int GifLineLen); -int DGifGetPixel(GifFileType * GifFile, GifPixelType GifPixel); -int DGifGetComment(GifFileType * GifFile, char *GifComment); -int DGifGetExtension(GifFileType * GifFile, int *GifExtCode, - GifByteType ** GifExtension); -int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension); -int DGifGetCode(GifFileType * GifFile, int *GifCodeSize, - GifByteType ** GifCodeBlock); -int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock); -int DGifGetLZCodes(GifFileType * GifFile, int *GifCode); -int DGifCloseFile(GifFileType * GifFile); - -#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ -#define D_GIF_ERR_READ_FAILED 102 -#define D_GIF_ERR_NOT_GIF_FILE 103 -#define D_GIF_ERR_NO_SCRN_DSCR 104 -#define D_GIF_ERR_NO_IMAG_DSCR 105 -#define D_GIF_ERR_NO_COLOR_MAP 106 -#define D_GIF_ERR_WRONG_RECORD 107 -#define D_GIF_ERR_DATA_TOO_BIG 108 -#define D_GIF_ERR_NOT_ENOUGH_MEM 109 -#define D_GIF_ERR_CLOSE_FAILED 110 -#define D_GIF_ERR_NOT_READABLE 111 -#define D_GIF_ERR_IMAGE_DEFECT 112 -#define D_GIF_ERR_EOF_TOO_SOON 113 - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file QUANTIZE.C. -******************************************************************************/ -int QuantizeBuffer(unsigned int Width, unsigned int Height, - int *ColorMapSize, GifByteType * RedInput, - GifByteType * GreenInput, GifByteType * BlueInput, - GifByteType * OutputBuffer, - GifColorType * OutputColorMap); - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file QPRINTF.C. -******************************************************************************/ -extern int GifQuietPrint; - -#ifdef HAVE_STDARG_H - extern void GifQprintf(char *Format, ...); -#elif defined (HAVE_VARARGS_H) - extern void GifQprintf(); -#endif /* HAVE_STDARG_H */ - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file GIF_ERR.C. -******************************************************************************/ -#ifndef _GBA_NO_FILEIO -extern void PrintGifError(void); -#endif /* _GBA_NO_FILEIO */ -extern int GifLastError(void); - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file DEV2GIF.C. -******************************************************************************/ -extern int DumpScreen2Gif(const char *FileName, - int ReqGraphDriver, - long ReqGraphMode1, - long ReqGraphMode2, - long ReqGraphMode3); - -/***************************************************************************** - * - * Everything below this point is new after version 1.2, supporting `slurp - * mode' for doing I/O in two big belts with all the image-bashing in core. - * - *****************************************************************************/ - -/****************************************************************************** - * Color Map handling from ALLOCGIF.C - *****************************************************************************/ - -extern ColorMapObject *MakeMapObject(int ColorCount, - const GifColorType * ColorMap); -extern void FreeMapObject(ColorMapObject * Object); -extern ColorMapObject *UnionColorMap(const ColorMapObject * ColorIn1, - const ColorMapObject * ColorIn2, - GifPixelType ColorTransIn2[]); -extern int BitSize(int n); - -/****************************************************************************** - * Support for the in-core structures allocation (slurp mode). - *****************************************************************************/ - -/* This is the in-core version of an extension record */ -typedef struct { - int ByteCount; - char *Bytes; /* on malloc(3) heap */ - int Function; /* Holds the type of the Extension block. */ -} ExtensionBlock; - -/* This holds an image header, its unpacked raster bits, and extensions */ -typedef struct SavedImage { - GifImageDesc ImageDesc; - unsigned char *RasterBits; /* on malloc(3) heap */ - int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */ - int ExtensionBlockCount; - ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */ -} SavedImage; - -extern void ApplyTranslation(SavedImage * Image, GifPixelType Translation[]); -extern void MakeExtension(SavedImage * New, int Function); -extern int AddExtensionBlock(SavedImage * New, int Len, - unsigned char ExtData[]); -extern void FreeExtension(SavedImage * Image); -extern SavedImage *MakeSavedImage(GifFileType * GifFile, - const SavedImage * CopyFrom); -extern void FreeSavedImages(GifFileType * GifFile); - -/****************************************************************************** - * The library's internal utility font - *****************************************************************************/ - -#define GIF_FONT_WIDTH 8 -#define GIF_FONT_HEIGHT 8 -extern unsigned char AsciiTable[][GIF_FONT_WIDTH]; - -#ifdef _WIN32 - extern void DrawGifText(SavedImage * Image, -#else - extern void DrawText(SavedImage * Image, -#endif - const int x, const int y, - const char *legend, const int color); - -extern void DrawBox(SavedImage * Image, - const int x, const int y, - const int w, const int d, const int color); - -void DrawRectangle(SavedImage * Image, - const int x, const int y, - const int w, const int d, const int color); - -extern void DrawBoxedText(SavedImage * Image, - const int x, const int y, - const char *legend, - const int border, const int bg, const int fg); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _GIF_LIB_H */ diff --git a/WDL/giflib/gif_lib_private.h b/WDL/giflib/gif_lib_private.h deleted file mode 100644 index 9261e3bb..00000000 --- a/WDL/giflib/gif_lib_private.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _GIF_LIB_PRIVATE_H -#define _GIF_LIB_PRIVATE_H - -#include "gif_lib.h" -#include "gif_hash.h" - -#define PROGRAM_NAME "GIFLIB" - -#ifdef SYSV -#define VersionStr "Gif library module,\t\tEric S. Raymond\n\ - (C) Copyright 1997 Eric S. Raymond\n" -#else -#define VersionStr PROGRAM_NAME " IBMPC " GIF_LIB_VERSION \ - " Eric S. Raymond, " __DATE__ ", " \ - __TIME__ "\n" "(C) Copyright 1997 Eric S. Raymond\n" -#endif /* SYSV */ - -#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ -#define LZ_BITS 12 - -#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */ -#define FIRST_CODE 4097 /* Impossible code, to signal first. */ -#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */ - -#define FILE_STATE_WRITE 0x01 -#define FILE_STATE_SCREEN 0x02 -#define FILE_STATE_IMAGE 0x04 -#define FILE_STATE_READ 0x08 - -#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ) -#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE) - -typedef struct GifFilePrivateType { - GifWord FileState, FileHandle, /* Where all this data goes to! */ - BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */ - ClearCode, /* The CLEAR LZ code. */ - EOFCode, /* The EOF LZ code. */ - RunningCode, /* The next code algorithm can generate. */ - RunningBits, /* The number of bits required to represent RunningCode. */ - MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */ - LastCode, /* The code before the current code. */ - CrntCode, /* Current algorithm code. */ - StackPtr, /* For character stack (see below). */ - CrntShiftState; /* Number of bits in CrntShiftDWord. */ - unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */ - unsigned long PixelCount; /* Number of pixels in image. */ - FILE *File; /* File as stream. */ - InputFunc Read; /* function to read gif input (TVT) */ - OutputFunc Write; /* function to write gif output (MRB) */ - GifByteType Buf[256]; /* Compressed input is buffered here. */ - GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */ - GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */ - GifPrefixType Prefix[LZ_MAX_CODE + 1]; - GifHashTableType *HashTable; -} GifFilePrivateType; - -extern int _GifError; - -#endif /* _GIF_LIB_PRIVATE_H */ diff --git a/WDL/giflib/gifalloc.c b/WDL/giflib/gifalloc.c deleted file mode 100644 index f48bbfb4..00000000 --- a/WDL/giflib/gifalloc.c +++ /dev/null @@ -1,441 +0,0 @@ -/***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber Ver 0.1, Jun. 1989 - * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 - ***************************************************************************** - * GIF construction tools - ***************************************************************************** - * History: - * 15 Sep 92 - Version 1.0 by Eric Raymond. - ****************************************************************************/ - -#include "config.h" - -#include -#include -#include -#include "gif_lib.h" - -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) - -/****************************************************************************** - * Miscellaneous utility functions - *****************************************************************************/ - -/* return smallest bitfield size n will fit in */ -int -BitSize(int n) { - - register int i; - - for (i = 1; i <= 8; i++) - if ((1 << i) >= n) - break; - return (i); -} - -/****************************************************************************** - * Color map object functions - *****************************************************************************/ - -/* - * Allocate a color map of given size; initialize with contents of - * ColorMap if that pointer is non-NULL. - */ -ColorMapObject * -MakeMapObject(int ColorCount, - const GifColorType * ColorMap) { - - ColorMapObject *Object; - - /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to - * make the user know that or should we automatically round up instead? */ - if (ColorCount != (1 << BitSize(ColorCount))) { - return ((ColorMapObject *) NULL); - } - - Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); - if (Object == (ColorMapObject *) NULL) { - return ((ColorMapObject *) NULL); - } - - Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType)); - if (Object->Colors == (GifColorType *) NULL) { - return ((ColorMapObject *) NULL); - } - - Object->ColorCount = ColorCount; - Object->BitsPerPixel = BitSize(ColorCount); - - if (ColorMap) { - memcpy((char *)Object->Colors, - (char *)ColorMap, ColorCount * sizeof(GifColorType)); - } - - return (Object); -} - -/* - * Free a color map object - */ -void -FreeMapObject(ColorMapObject * Object) { - - if (Object != NULL) { - free(Object->Colors); - free(Object); - /*** FIXME: - * When we are willing to break API we need to make this function - * FreeMapObject(ColorMapObject **Object) - * and do this assignment to NULL here: - * *Object = NULL; - */ - } -} - -#ifdef DEBUG -void -DumpColorMap(ColorMapObject * Object, - FILE * fp) { - - if (Object) { - int i, j, Len = Object->ColorCount; - - for (i = 0; i < Len; i += 4) { - for (j = 0; j < 4 && j < Len; j++) { - fprintf(fp, "%3d: %02x %02x %02x ", i + j, - Object->Colors[i + j].Red, - Object->Colors[i + j].Green, - Object->Colors[i + j].Blue); - } - fprintf(fp, "\n"); - } - } -} -#endif /* DEBUG */ - -/* - * Compute the union of two given color maps and return it. If result can't - * fit into 256 colors, NULL is returned, the allocated union otherwise. - * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are - * copied iff they didn't exist before. ColorTransIn2 maps the old - * ColorIn2 into ColorUnion color map table. - */ -ColorMapObject * -UnionColorMap(const ColorMapObject * ColorIn1, - const ColorMapObject * ColorIn2, - GifPixelType ColorTransIn2[]) { - - int i, j, CrntSlot, RoundUpTo, NewBitSize; - ColorMapObject *ColorUnion; - - /* - * Allocate table which will hold the result for sure. - */ - ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount, - ColorIn2->ColorCount) * 2, NULL); - - if (ColorUnion == NULL) - return (NULL); - - /* Copy ColorIn1 to ColorUnionSize; */ - /*** FIXME: What if there are duplicate entries into the colormap to begin - * with? */ - for (i = 0; i < ColorIn1->ColorCount; i++) - ColorUnion->Colors[i] = ColorIn1->Colors[i]; - CrntSlot = ColorIn1->ColorCount; - - /* - * Potentially obnoxious hack: - * - * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end - * of table 1. This is very useful if your display is limited to - * 16 colors. - */ - while (ColorIn1->Colors[CrntSlot - 1].Red == 0 - && ColorIn1->Colors[CrntSlot - 1].Green == 0 - && ColorIn1->Colors[CrntSlot - 1].Blue == 0) - CrntSlot--; - - /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */ - for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) { - /* Let's see if this color already exists: */ - /*** FIXME: Will it ever occur that ColorIn2 will contain duplicate - * entries? So we should search from 0 to CrntSlot rather than - * ColorIn1->ColorCount? - */ - for (j = 0; j < ColorIn1->ColorCount; j++) - if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], - sizeof(GifColorType)) == 0) - break; - - if (j < ColorIn1->ColorCount) - ColorTransIn2[i] = j; /* color exists in Color1 */ - else { - /* Color is new - copy it to a new slot: */ - ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i]; - ColorTransIn2[i] = CrntSlot++; - } - } - - if (CrntSlot > 256) { - FreeMapObject(ColorUnion); - return ((ColorMapObject *) NULL); - } - - NewBitSize = BitSize(CrntSlot); - RoundUpTo = (1 << NewBitSize); - - if (RoundUpTo != ColorUnion->ColorCount) { - register GifColorType *Map = ColorUnion->Colors; - - /* - * Zero out slots up to next power of 2. - * We know these slots exist because of the way ColorUnion's - * start dimension was computed. - */ - for (j = CrntSlot; j < RoundUpTo; j++) - Map[j].Red = Map[j].Green = Map[j].Blue = 0; - - /* perhaps we can shrink the map? */ - if (RoundUpTo < ColorUnion->ColorCount) - ColorUnion->Colors = (GifColorType *)realloc(Map, - sizeof(GifColorType) * RoundUpTo); - } - - ColorUnion->ColorCount = RoundUpTo; - ColorUnion->BitsPerPixel = NewBitSize; - - return (ColorUnion); -} - -/* - * Apply a given color translation to the raster bits of an image - */ -void -ApplyTranslation(SavedImage * Image, - GifPixelType Translation[]) { - - register int i; - register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; - - for (i = 0; i < RasterSize; i++) - Image->RasterBits[i] = Translation[Image->RasterBits[i]]; -} - -/****************************************************************************** - * Extension record functions - *****************************************************************************/ - -void -MakeExtension(SavedImage * New, - int Function) { - - New->Function = Function; - /*** FIXME: - * Someday we might have to deal with multiple extensions. - * ??? Was this a note from Gershon or from me? Does the multiple - * extension blocks solve this or do we need multiple Functions? Or is - * this an obsolete function? (People should use AddExtensionBlock - * instead?) - * Looks like AddExtensionBlock needs to take the int Function argument - * then it can take the place of this function. Right now people have to - * use both. Fix AddExtensionBlock and add this to the deprecation list. - */ -} - -int -AddExtensionBlock(SavedImage * New, - int Len, - unsigned char ExtData[]) { - - ExtensionBlock *ep; - - if (New->ExtensionBlocks == NULL) - New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); - else - New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks, - sizeof(ExtensionBlock) * - (New->ExtensionBlockCount + 1)); - - if (New->ExtensionBlocks == NULL) - return (GIF_ERROR); - - ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; - - ep->ByteCount=Len; - ep->Bytes = (char *)malloc(ep->ByteCount); - if (ep->Bytes == NULL) - return (GIF_ERROR); - - if (ExtData) { - memcpy(ep->Bytes, ExtData, Len); - ep->Function = New->Function; - } - - return (GIF_OK); -} - -void -FreeExtension(SavedImage * Image) -{ - ExtensionBlock *ep; - - if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) { - return; - } - for (ep = Image->ExtensionBlocks; - ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++) - (void)free((char *)ep->Bytes); - free((char *)Image->ExtensionBlocks); - Image->ExtensionBlocks = NULL; -} - -/****************************************************************************** - * Image block allocation functions -******************************************************************************/ - -/* Private Function: - * Frees the last image in the GifFile->SavedImages array - */ -void -FreeLastSavedImage(GifFileType *GifFile) { - - SavedImage *sp; - - if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) - return; - - /* Remove one SavedImage from the GifFile */ - GifFile->ImageCount--; - sp = &GifFile->SavedImages[GifFile->ImageCount]; - - /* Deallocate its Colormap */ - if (sp->ImageDesc.ColorMap) { - FreeMapObject(sp->ImageDesc.ColorMap); - sp->ImageDesc.ColorMap = NULL; - } - - /* Deallocate the image data */ - if (sp->RasterBits) - free((char *)sp->RasterBits); - - /* Deallocate any extensions */ - if (sp->ExtensionBlocks) - FreeExtension(sp); - - /*** FIXME: We could realloc the GifFile->SavedImages structure but is - * there a point to it? Saves some memory but we'd have to do it every - * time. If this is used in FreeSavedImages then it would be inefficient - * (The whole array is going to be deallocated.) If we just use it when - * we want to free the last Image it's convenient to do it here. - */ -} - -/* - * Append an image block to the SavedImages array - */ -SavedImage * -MakeSavedImage(GifFileType * GifFile, - const SavedImage * CopyFrom) { - - SavedImage *sp; - - if (GifFile->SavedImages == NULL) - GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); - else - GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, - sizeof(SavedImage) * (GifFile->ImageCount + 1)); - - if (GifFile->SavedImages == NULL) - return ((SavedImage *)NULL); - else { - sp = &GifFile->SavedImages[GifFile->ImageCount++]; - memset((char *)sp, '\0', sizeof(SavedImage)); - - if (CopyFrom) { - memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); - - /* - * Make our own allocated copies of the heap fields in the - * copied record. This guards against potential aliasing - * problems. - */ - - /* first, the local color map */ - if (sp->ImageDesc.ColorMap) { - sp->ImageDesc.ColorMap = MakeMapObject( - CopyFrom->ImageDesc.ColorMap->ColorCount, - CopyFrom->ImageDesc.ColorMap->Colors); - if (sp->ImageDesc.ColorMap == NULL) { - FreeLastSavedImage(GifFile); - return (SavedImage *)(NULL); - } - } - - /* next, the raster */ - sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) * - CopyFrom->ImageDesc.Height * - CopyFrom->ImageDesc.Width); - if (sp->RasterBits == NULL) { - FreeLastSavedImage(GifFile); - return (SavedImage *)(NULL); - } - memcpy(sp->RasterBits, CopyFrom->RasterBits, - sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * - CopyFrom->ImageDesc.Width); - - /* finally, the extension blocks */ - if (sp->ExtensionBlocks) { - sp->ExtensionBlocks = (ExtensionBlock *)malloc( - sizeof(ExtensionBlock) * - CopyFrom->ExtensionBlockCount); - if (sp->ExtensionBlocks == NULL) { - FreeLastSavedImage(GifFile); - return (SavedImage *)(NULL); - } - memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, - sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); - - /* - * For the moment, the actual blocks can take their - * chances with free(). We'll fix this later. - *** FIXME: [Better check this out... Toshio] - * 2004 May 27: Looks like this was an ESR note. - * It means the blocks are shallow copied from InFile to - * OutFile. However, I don't see that in this code.... - * Did ESR fix it but never remove this note (And other notes - * in gifspnge?) - */ - } - } - - return (sp); - } -} - -void -FreeSavedImages(GifFileType * GifFile) { - - SavedImage *sp; - - if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { - return; - } - for (sp = GifFile->SavedImages; - sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { - if (sp->ImageDesc.ColorMap) { - FreeMapObject(sp->ImageDesc.ColorMap); - sp->ImageDesc.ColorMap = NULL; - } - - if (sp->RasterBits) - free((char *)sp->RasterBits); - - if (sp->ExtensionBlocks) - FreeExtension(sp); - } - free((char *)GifFile->SavedImages); - GifFile->SavedImages=NULL; -} diff --git a/WDL/gpu/gpu.cpp b/WDL/gpu/gpu.cpp deleted file mode 100644 index 290e1e8d..00000000 --- a/WDL/gpu/gpu.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - WDL - gpu.cpp - Copyright (C) 2007 Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -#include "gpu.h" - -static int static_disableOpenGl = 0; - -WDL_GPU::WDL_GPU() -{ - m_glDll = NULL; - m_rc = NULL; -} - -WDL_GPU::~WDL_GPU() -{ - release(); -} - -void WDL_GPU::release() -{ - if(m_glDll) - { - if(m_rc) - { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(m_rc); - } - FreeLibrary(m_glDll); - m_glDll = NULL; - } -} - -int WDL_GPU::init(HWND hwnd) -{ - m_hwnd = hwnd; - - if(static_disableOpenGl) return 0; - - m_glDll = LoadLibrary("opengl32.dll"); - if(!m_glDll) return 0; - - *((int *)&wglCreateContext) = (int)GetProcAddress(m_glDll, "wglCreateContext"); - *((int *)&wglDeleteContext) = (int)GetProcAddress(m_glDll, "wglDeleteContext"); - *((int *)&wglMakeCurrent) = (int)GetProcAddress(m_glDll, "wglMakeCurrent"); - *((int *)&wglGetProcAddress) = (int)GetProcAddress(m_glDll, "wglGetProcAddress"); - *((int *)&glClearColor) = (int)GetProcAddress(m_glDll, "glClearColor"); - *((int *)&glClear) = (int)GetProcAddress(m_glDll, "glClear"); - *((int *)&glEnable) = (int)GetProcAddress(m_glDll, "glEnable"); - *((int *)&glDisable) = (int)GetProcAddress(m_glDll, "glDisable"); - *((int *)&glBlendFunc) = (int)GetProcAddress(m_glDll, "glBlendFunc"); - *((int *)&glLineWidth) = (int)GetProcAddress(m_glDll, "glLineWidth"); - *((int *)&glColor3f) = (int)GetProcAddress(m_glDll, "glColor3f"); - *((int *)&glBegin) = (int)GetProcAddress(m_glDll, "glBegin"); - *((int *)&glEnd) = (int)GetProcAddress(m_glDll, "glEnd"); - *((int *)&glFlush) = (int)GetProcAddress(m_glDll, "glFlush"); - *((int *)&glVertex2f) = (int)GetProcAddress(m_glDll, "glVertex2f"); - *((int *)&glFinish) = (int)GetProcAddress(m_glDll, "glFinish"); - *((int *)&glGetString) = (int)GetProcAddress(m_glDll, "glGetString"); - *((int *)&glReadPixels) = (int)GetProcAddress(m_glDll, "glReadPixels"); - - if(!wglGetProcAddress) - { - FreeLibrary(m_glDll); - m_glDll = NULL; - return 0; - } - - HDC pdc = GetDC(m_hwnd); - - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory( &pfd, sizeof( pfd ) ); - pfd.nSize = sizeof( pfd ); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cDepthBits = 16; - pfd.iLayerType = PFD_MAIN_PLANE; - int format = ChoosePixelFormat( pdc, &pfd ); - SetPixelFormat( pdc, format, &pfd ); - - m_rc = wglCreateContext(pdc); - - if(!m_rc) - { - ReleaseDC(m_hwnd, pdc); - FreeLibrary(m_glDll); - m_glDll = NULL; - return 0; - } - wglMakeCurrent(pdc, m_rc); - - char *rend = (char *)glGetString(GL_RENDERER); - if(!rend || (rend && strstr(rend, "GDI"))) goto ret; //opengl software rendering is slooooow - - wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); - - if(!wglGetExtensionsStringARB) - { -ret: - ReleaseDC(m_hwnd, pdc); - wglMakeCurrent(NULL, NULL); - wglDeleteContext(m_rc); - FreeLibrary(m_glDll); - m_glDll = NULL; - return 0; - } - - char *ext = NULL; - ext = (char*)wglGetExtensionsStringARB( pdc ); - if(!strstr( ext, "WGL_ARB_pbuffer" )) goto ret; - - wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB"); - wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB"); - wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB"); - wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB"); - wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB"); - if( !wglCreatePbufferARB || !wglGetPbufferDCARB || !wglReleasePbufferDCARB || !wglDestroyPbufferARB || !wglQueryPbufferARB ) goto ret; - - wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); - wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB"); - wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - - if( !wglGetExtensionsStringARB || !wglCreatePbufferARB || !wglGetPbufferDCARB ) goto ret; - - ReleaseDC(m_hwnd, pdc); - - return 1; -} - -WDL_GPU_Surface *WDL_GPU::createSurface(WDL_WinMemBitmap *bm, int w, int h) -{ - if(!isInited()) return 0; - return new WDL_GPU_Surface(this, bm, w, h); -} - -static LRESULT CALLBACK staticWndProc( - HWND hwnd, // handle to window - UINT uMsg, // message identifier - WPARAM wParam, // first message parameter - LPARAM lParam // second message parameter -) -{ - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -WDL_GPU_Surface::WDL_GPU_Surface(WDL_GPU *parent, WDL_WinMemBitmap *bm, int w, int h) -{ - m_parent = parent; - m_bm = bm; - m_hPBuffer = NULL; - m_hDC = NULL; - m_hRC = NULL; - - //m_w = ((w+15)/16)*16; m_h = ((h+15)/16)*16; - m_w = w; m_h = h; - - BITMAPINFO m_bmi; - memset(&m_bmi, 0, sizeof(BITMAPINFO)); - m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - m_bmi.bmiHeader.biWidth = m_w; - m_bmi.bmiHeader.biHeight = m_h; - m_bmi.bmiHeader.biPlanes = 1; - m_bmi.bmiHeader.biBitCount = 32; - m_bmi.bmiHeader.biCompression = BI_RGB; - m_bmi.bmiHeader.biSizeImage = m_w * m_h * 4; - m_bmp = CreateDIBSection(m_bm->GetDC(), &m_bmi, DIB_RGB_COLORS, &m_bits, NULL, 0); - m_oldbm = (HBITMAP)SelectObject(m_bm->GetDC(), m_bmp); - - //create pbuffer for offscreen rendering - int pf_attr[] = - { - WGL_SUPPORT_OPENGL_ARB, TRUE, // P-buffer will be used with OpenGL - WGL_DRAW_TO_PBUFFER_ARB, TRUE, // Enable render to p-buffer - WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // some cards need that in order not to crash in wglCreatePbufferARB - WGL_RED_BITS_ARB, 8, // At least 8 bits for RED channel - WGL_GREEN_BITS_ARB, 8, // At least 8 bits for GREEN channel - WGL_BLUE_BITS_ARB, 8, // At least 8 bits for BLUE channel - WGL_ALPHA_BITS_ARB, 8, // At least 8 bits for ALPHA channel - WGL_DEPTH_BITS_ARB, 16, // At least 16 bits for depth buffer - WGL_DOUBLE_BUFFER_ARB, FALSE, // We don't require double buffering - 0 // Zero terminates the list - }; - - HDC pdc = GetDC(m_parent->m_hwnd); - - try - { - unsigned int count = 0; - int pixelFormat; - m_parent->wglChoosePixelFormatARB( pdc,(const int*)pf_attr, NULL, 1, &pixelFormat, &count); - if(!count) - { - ReleaseDC(m_parent->m_hwnd, pdc); - m_parent->release(); - return; - } - - m_hPBuffer = m_parent->wglCreatePbufferARB( pdc, pixelFormat, m_w, m_h, NULL ); - if(!m_hPBuffer) - { - ReleaseDC(m_parent->m_hwnd, pdc); - m_parent->release(); - return; - } - } - catch(...) - { - //stupid opengl driver crashing, lets make sure we don't retry to reinitialize the whole thing - static_disableOpenGl = 1; - ReleaseDC(m_parent->m_hwnd, pdc); - m_parent->release(); - return; - } - - m_hDC = m_parent->wglGetPbufferDCARB( m_hPBuffer ); - m_hRC = m_parent->wglCreateContext( m_hDC ); - - ReleaseDC(m_parent->m_hwnd, pdc); -} - -WDL_GPU_Surface::~WDL_GPU_Surface() -{ - if(m_hRC) - { - m_parent->wglMakeCurrent(m_hDC, m_hRC); - m_parent->wglDeleteContext(m_hRC); - m_parent->wglReleasePbufferDCARB( m_hPBuffer, m_hDC ); - m_parent->wglDestroyPbufferARB( m_hPBuffer ); - ReleaseDC( m_parent->m_hwnd, m_hDC ); - } - if(m_parent->isInited()) m_parent->wglMakeCurrent(NULL, NULL); - SelectObject(m_bm->GetDC(), m_oldbm); - DeleteObject(m_bmp); -} - -void WDL_GPU_Surface::clear(float cr, float cg, float cb) -{ - m_parent->glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - m_parent->glClear( GL_COLOR_BUFFER_BIT ); -} - -void WDL_GPU_Surface::beginScene() -{ - if(!m_hRC) return; - m_parent->wglMakeCurrent(m_hDC, m_hRC); -} - -void WDL_GPU_Surface::setLineAA(int on) -{ - if(on) - { - m_parent->glEnable(GL_LINE_SMOOTH); - m_parent->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - m_parent->glEnable(GL_BLEND); - } - else - { - m_parent->glDisable(GL_LINE_SMOOTH); - } -} - -void WDL_GPU_Surface::beginLine(float cr, float cg, float cb) -{ - m_parent->glLineWidth (1); - m_parent->glBegin (GL_LINES); - m_parent->glColor3f (cb, cg, cr); -} - -void WDL_GPU_Surface::end() -{ - m_parent->glEnd (); - m_parent->glFinish(); -} - -void WDL_GPU_Surface::drawLine(int x1, int y1, int x2, int y2) -{ - float w = (float)m_w; - float h = (float)m_h; - float fx1 = ((float)x1/(w/2))-1; - float fy1 = -((float)y1/(h/2))+1; - float fx2 = ((float)x2/(w/2))-1; - float fy2 = -((float)y2/(h/2))+1; - m_parent->glVertex2f(fx1,fy1); - m_parent->glVertex2f(fx2,fy2); -} - -void WDL_GPU_Surface::flush() -{ - m_parent->glFlush(); -} - -void WDL_GPU_Surface::blit() -{ - if(!m_hRC) return; - m_parent->glReadPixels( 0, 0, m_w, m_h, GL_RGBA, GL_UNSIGNED_BYTE, m_bits); -} diff --git a/WDL/gpu/gpu.h b/WDL/gpu/gpu.h deleted file mode 100644 index 50bce940..00000000 --- a/WDL/gpu/gpu.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - WDL - gpu.h - Copyright (C) 2007 Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -#ifndef _WDL_GPU_H -#define _WDL_GPU_H - -#ifdef _WIN32 - -#include -#include -#include "wglext.h" - -#include "../wingui/membitmap.h" - -class WDL_GPU_Surface; - -class WDL_GPU -{ -public: - WDL_GPU(); - ~WDL_GPU(); - - int init(HWND hwnd); - void release(); - int isInited() { return m_glDll != NULL; } - - WDL_GPU_Surface *createSurface(WDL_WinMemBitmap *bm, int w, int h); - - HGLRC (WINAPI *wglCreateContext)(HDC dc); - BOOL (WINAPI *wglMakeCurrent)(HDC dc, HGLRC rc); - BOOL (WINAPI *wglDeleteContext)(HGLRC rc); - PROC (WINAPI *wglGetProcAddress)(LPCSTR name); - - void (WINAPI *glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - void (WINAPI *glClear)(GLbitfield mask); - void (WINAPI *glEnable)(GLenum cap); - void (WINAPI *glDisable)(GLenum cap); - void (WINAPI *glBlendFunc)(GLenum sfactor, GLenum dfactor); - void (WINAPI *glLineWidth)(GLfloat width); - void (WINAPI *glColor3f)(GLfloat red, GLfloat green, GLfloat blue); - void (WINAPI *glBegin)(GLenum mode); - void (WINAPI *glEnd)(); - void (WINAPI *glVertex2f)(GLfloat x, GLfloat y); - void (WINAPI *glFlush)(); - void (WINAPI *glFinish)(); - const GLubyte *(WINAPI *glGetString)(GLenum name); - void (WINAPI *glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); - - // WGL_ARB_extensions_string - PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; - - // WGL_ARB_pbuffer - PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB; - PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB; - PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB; - PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB; - PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB; - - // WGL_ARB_pixel_format - PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB; - PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB; - PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; - - HINSTANCE m_glDll; - HWND m_hwnd; - HGLRC m_rc; -}; - -class WDL_GPU_Surface -{ -public: - WDL_GPU_Surface(WDL_GPU *parent, WDL_WinMemBitmap *bm, int w, int h); - ~WDL_GPU_Surface(); - - void clear(float cr, float cg, float cb); - void beginScene(); - void setLineAA(int on); - void beginLine(float cr, float cg, float cb); - void end(); - void drawLine(int x1, int y1, int x2, int y2); - void flush(); - void blit(); - -private: - WDL_GPU *m_parent; - WDL_WinMemBitmap *m_bm; - HBITMAP m_oldbm, m_bmp; - int m_w, m_h; - - HPBUFFERARB m_hPBuffer; - HDC m_hDC; - HGLRC m_hRC; - void *m_bits; -}; - -#else - -//todo - -#endif - -#endif \ No newline at end of file diff --git a/WDL/gpu/wglext.h b/WDL/gpu/wglext.h deleted file mode 100644 index f424adcf..00000000 --- a/WDL/gpu/wglext.h +++ /dev/null @@ -1,611 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: This software was created using the -** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has -** not been independently verified as being compliant with the OpenGL(R) -** version 1.2.1 Specification. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number */ -/* wglext.h last updated 2002/03/22 */ -/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ -#define WGL_WGLEXT_VERSION 4 - -#ifndef WGL_ARB_buffer_region -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -#endif - -#ifndef WGL_ARB_multisample -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif - -#ifndef WGL_ARB_extensions_string -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -#endif - -#ifndef WGL_EXT_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -#endif - -#ifndef WGL_I3D_gamma -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -#endif - -#ifndef WGL_I3D_genlock -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -#endif - -#ifndef WGL_I3D_swap_frame_lock -#endif - -#ifndef WGL_NV_render_depth_texture -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif - -#ifndef WGL_NV_float_buffer -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif - - -/*************************************************************/ - -#ifndef WGL_ARB_pbuffer -DECLARE_HANDLE(HPBUFFERARB); -#endif -#ifndef WGL_EXT_pbuffer -DECLARE_HANDLE(HPBUFFEREXT); -#endif - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); -extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); -extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); -extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#endif - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringARB (HDC); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCARB (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); -extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); -extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); -extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); -extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); -extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); -extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); -extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); -extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#endif - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#endif - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); -extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); -extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); -extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglSwapIntervalEXT (int); -extern int WINAPI wglGetSwapIntervalEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#endif - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); -extern void WINAPI wglFreeMemoryNV (void *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#endif - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); -extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); -extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); -extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); -extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); -extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); -extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#endif - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); -extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); -extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); -extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableGenlockI3D (HDC); -extern BOOL WINAPI wglDisableGenlockI3D (HDC); -extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); -extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); -extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); -extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); -extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); -extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#endif - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableFrameLockI3D (void); -extern BOOL WINAPI wglDisableFrameLockI3D (void); -extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); -extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#endif - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetFrameUsageI3D (float *); -extern BOOL WINAPI wglBeginFrameTrackingI3D (void); -extern BOOL WINAPI wglEndFrameTrackingI3D (void); -extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/WDL/heapbuf.h b/WDL/heapbuf.h deleted file mode 100644 index c5e6b499..00000000 --- a/WDL/heapbuf.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - WDL - heapbuf.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides the interface and implementation for WDL_HeapBuf, a simple - malloc() wrapper for resizeable blocks. - - Also in this file is WDL_TypedBuf which is a templated version WDL_HeapBuf - that manages type and type-size. - -*/ - -#ifndef _WDL_HEAPBUF_H_ -#define _WDL_HEAPBUF_H_ - -#ifndef WDL_HEAPBUF_IMPL_ONLY - -#ifdef WDL_HEAPBUF_TRACE -#include -#define WDL_HEAPBUF_TRACEPARM(x) ,(x) -#else -#define WDL_HEAPBUF_TRACEPARM(x) -#endif - -#include "wdltypes.h" - -class WDL_HeapBuf -{ - public: - // interface -#ifdef WDL_HEAPBUF_INTF_ONLY - void *Resize(int newsize, bool resizedown=true); - void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false); -#endif - void *Get() const { return m_size?m_buf:NULL; } - int GetSize() const { return m_size; } - void *GetAligned(int align) const { return (void *)(((UINT_PTR)Get() + (align-1)) & ~(UINT_PTR)(align-1)); } - - void SetGranul(int granul) { m_granul = granul; } - - void SetMinAllocSize(int mas) { m_mas=mas; } - - - WDL_HeapBuf(const WDL_HeapBuf &cp) - { - m_buf=0; - CopyFrom(&cp,true); - } - WDL_HeapBuf &operator=(const WDL_HeapBuf &cp) - { - CopyFrom(&cp,true); - return *this; - } - - - - #ifndef WDL_HEAPBUF_TRACE - explicit WDL_HeapBuf(int granul=4096) : m_alloc(0), m_size(0), m_mas(0) - { - SetGranul(granul); - m_buf=0; - } - ~WDL_HeapBuf() - { - free(m_buf); - } - #else - explicit WDL_HeapBuf(int granul=4096, const char *tracetype="WDL_HeapBuf" - ) : m_alloc(0), m_size(0), m_mas(0) - { - SetGranul(granul); - m_buf=0; - - m_tracetype = tracetype; - char tmp[512]; - wsprintf(tmp,"WDL_HeapBuf: created type: %s granul=%d\n",tracetype,granul); - OutputDebugString(tmp); - } - ~WDL_HeapBuf() - { - char tmp[512]; - wsprintf(tmp,"WDL_HeapBuf: destroying type: %s (alloc=%d, size=%d)\n",m_tracetype,m_alloc,m_size); - OutputDebugString(tmp); - free(m_buf); - } - #endif - -#endif // !WDL_HEAPBUF_IMPL_ONLY - - // implementation bits -#ifndef WDL_HEAPBUF_INTF_ONLY - #ifdef WDL_HEAPBUF_IMPL_ONLY - void *WDL_HeapBuf::Resize(int newsize, bool resizedown) - #else - void *Resize(int newsize, bool resizedown=true) - #endif - { - #ifdef DEBUG_TIGHT_ALLOC // horribly slow, do not use for release builds - if (newsize == m_size) return m_buf; - - int a = newsize; - if (a > m_size) a=m_size; - void *newbuf = newsize ? malloc(newsize) : 0; - if (!newbuf && newsize) - { - #ifdef WDL_HEAPBUF_ONMALLOCFAIL - WDL_HEAPBUF_ONMALLOCFAIL(newsize) - #endif - return m_buf; - } - if (newbuf&&m_buf) memcpy(newbuf,m_buf,a); - m_size=m_alloc=newsize; - free(m_buf); - return m_buf=newbuf; - #endif - - //#define WDL_HEAPBUF_DYNAMIC - #ifdef WDL_HEAPBUF_DYNAMIC - // ignoring m_granul and m_mas - - if (newsize!=m_size) - { - if ((newsize > m_size && newsize <= m_alloc) || (newsize < m_size && !resizedown)) - { - m_size = newsize; - return m_buf; - } - - // next highest power of 2 - int n = newsize; - if (n) - { - if (n < 64) - { - n = 64; - } - else - { - --n; - n = (n>>1)|n; - n = (n>>2)|n; - n = (n>>4)|n; - n = (n>>8)|n; - n = (n>>16)|n; - ++n; - } - } - - if (n == m_alloc) - { - m_size = newsize; - return m_buf; - } - - void* newbuf = realloc(m_buf, n); // realloc==free when size==0 - #ifdef WDL_HEAPBUF_ONMALLOCFAIL - if (!newbuf && n) { WDL_HEAPBUF_ONMALLOCFAIL(n) } ; - #endif - if (newbuf || !newsize) - { - m_alloc = n; - m_buf = newbuf; - m_size = newsize; - } - } - - return (m_size ? m_buf : 0); - #else // WDL_HEAPBUF_DYNAMIC - if (newsize!=m_size) - { - // if we are not using m_smallbuf or we need to not use it - // and if if growing or resizing down - if ( - (newsize > m_alloc || - (resizedown && newsize < m_size && - newsize < m_alloc/2 && - newsize < m_alloc - (m_granul<<2)))) - { - int granul=newsize/2; - int newalloc; - if (granul < m_granul) granul=m_granul; - - if (m_granul<4096) newalloc=newsize+granul; - else - { - granul &= ~4095; - if (granul< 4096) granul=4096; - else if (granul>4*1024*1024) granul=4*1024*1024; - newalloc = ((newsize + granul + 96)&~4095)-96; - } - - if (newalloc < m_mas) newalloc=m_mas; - - if (newalloc != m_alloc) - { - #ifdef WDL_HEAPBUF_TRACE - char tmp[512]; - wsprintf(tmp,"WDL_HeapBuf: type %s realloc(%d) from %d\n",m_tracetype,newalloc,m_alloc); - OutputDebugString(tmp); - #endif - void *nbuf= realloc(m_buf,newalloc); - if (!nbuf && newalloc) - { - if (!(nbuf=malloc(newalloc))) - { - #ifdef WDL_HEAPBUF_ONMALLOCFAIL - WDL_HEAPBUF_ONMALLOCFAIL(newalloc); - #endif - return m_size?m_buf:0; // failed, do not resize - } - - if (m_buf) - { - int sz=newsize0) memcpy(nbuf,m_buf,sz); - free(m_buf); - } - } - - m_buf=nbuf; - m_alloc=newalloc; - } // alloc size change - } // need size up or down - m_size=newsize; - } // size change - return m_size?m_buf:0; - #endif // WDL_HEAPBUF_DYNAMIC - } - - #ifdef WDL_HEAPBUF_IMPL_ONLY - void WDL_HeapBuf::CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig) - #else - void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false) - #endif - { - if (exactCopyOfConfig) // copy all settings - { - free(m_buf); - - #ifdef WDL_HEAPBUF_TRACE - m_tracetype = hb->m_tracetype; - #endif - m_granul = hb->m_granul; - m_mas = hb->m_mas; - - m_size=m_alloc=0; - m_buf=hb->m_buf && hb->m_alloc>0 ? malloc(m_alloc = hb->m_alloc) : NULL; - #ifdef WDL_HEAPBUF_ONMALLOCFAIL - if (!m_buf && m_alloc) { WDL_HEAPBUF_ONMALLOCFAIL(m_alloc) } ; - #endif - if (m_buf) memcpy(m_buf,hb->m_buf,m_size = hb->m_size); - else m_alloc=0; - } - else // copy just the data + size - { - int newsz=hb->GetSize(); - Resize(newsz); - if (GetSize()!=newsz) Resize(0); - else memcpy(Get(),hb->Get(),newsz); - } - } - -#endif // ! WDL_HEAPBUF_INTF_ONLY - -#ifndef WDL_HEAPBUF_IMPL_ONLY - - private: - void *m_buf; - #if !defined(_WIN64) && !defined(__LP64__) - int ___pad; // keep this 8 byte aligned on osx32 - #endif - int m_granul; - int m_alloc; - int m_size; - int m_mas; - - #ifdef WDL_HEAPBUF_TRACE - const char *m_tracetype; - #endif - -}; - -template class WDL_TypedBuf -{ - public: - PTRTYPE *Get() const { return (PTRTYPE *) m_hb.Get(); } - int GetSize() const { return m_hb.GetSize()/sizeof(PTRTYPE); } - - PTRTYPE *Resize(int newsize, bool resizedown=true) { return (PTRTYPE *)m_hb.Resize(newsize*sizeof(PTRTYPE),resizedown); } - - PTRTYPE *GetAligned(int align) const { return (PTRTYPE *) m_hb.GetAligned(align); } - - PTRTYPE *Add(PTRTYPE val) - { - int sz=GetSize(); - PTRTYPE *p=Resize(sz+1); - if (p && GetSize() == sz+1) { p[sz]=val; return p+sz; } - return 0; - } - - void SetGranul(int gran) { m_hb.SetGranul(gran); } - - int Find(PTRTYPE val) const - { - PTRTYPE* p=Get(); - int i; - for (i=0; i < GetSize(); ++i) if (p[i] == val) return i; - return -1; - } - -#ifndef WDL_HEAPBUF_TRACE - explicit WDL_TypedBuf(int granul=4096) : m_hb(granul) { } -#else - explicit WDL_TypedBuf(int granul=4096, const char *tracetype="WDL_TypedBuf") : m_hb(granul WDL_HEAPBUF_TRACEPARM(tracetype)) { } -#endif - ~WDL_TypedBuf() - { - } - - private: - WDL_HeapBuf m_hb; -}; - -#endif // ! WDL_HEAPBUF_IMPL_ONLY - -#endif // _WDL_HEAPBUF_H_ diff --git a/WDL/history.txt b/WDL/history.txt deleted file mode 100644 index f17b4aa5..00000000 --- a/WDL/history.txt +++ /dev/null @@ -1,470 +0,0 @@ -FFMPEG: added WDL_VideoDecode class to grab video frames - -2010-08-16: -Now available via Git! The zipped distributions may go away someday? -EEL2: optional eel1 compat (allows you to build AVS using EEL2 and support old presets) -LICE: FillTriangle/Polygon/Bezier coordinates are now cleanly inclusive -LineParse: when parsing small lines, no heap use (requires an extra 2k of stack space per parser) -PtrList: do not pass NULLs to deletion functions -Scrollbar: improved zoom button sizing -sc_bounce: fixed a session ID handling bug -SWELL: no WM_CTLCOLOR* on text fields -SWELL: rendering glitch fix when destroying small subviews -SWELL: font and combo box sizes are more consistent -SWELL: emulate WM_NC/HTCAPTION on OSX for double-click in titlebar -SWELL: API for setting relative raise amounts for owned windows -Virtwnd: VirtualStaticText: added GetCharFromCoord() -Virtwnd: fixed scaled blit clipping on right/bottom, various other clip problems -Virtwnd: bgcache handles differing images automatically - - -2010-07-14: -SWELL: better TrackPopupMenu() behavior when using TPM_RETURNCMD -SWELL: resource script generation improved, faster, simpler use: mac_resgen.php file.rc [file2.rc ...] -SWELL: more accurate MoveToEx()/LineTo() -SWELL: fixes to no-maninmiddle-cocoa mode -SWELL: WM_ERASEBKGND fixes -SWELL: added GetPrivateProfileSection()/WritePrivateProfileSection() (untested) -EEL: tan() optimized and fixed on osx/i386 -EEL: fix for broken fmod() on VC2005/2008 x64 -Pitch shifter: bugfixes, latency compensation -LCF: fixed broken encoding on widths non multiples of 4 -LICE: better drawing of non-UTF8 8-bit text -LineParser: gettoken_str() now returns const char ptr -FileWrite: append support, option for no exclusive locking -Scrollbar: fixes for scaling, nonstandard scrollbar sizes, better image caching -String: allow SetLen() to shrink buffers -WIN32-UTF8: ShellExecute() UTF8 support -WndSizer: added set_orig_rect() -Virtwnd: more controls support disabling state -Virtwnd: static text controls support drawing text vertically - -2010-06-07: -File Browsing: fixed single file select on multifile open on Win2k/98 (windows bug) -File Browsing: UTF8 fixes -LICE: bitmaps are now forced to 64 byte alignment, backing stores are (by default) row aligned -IPlug: fixed OSX compiling (SWELL changes had made it not compile) -IPlug: VST_SDK path is now normalized, put VST_SDK/ at the same level as WDL/ -IPlug: image files for sample are now in the correct place (and not zipped) -Mutex: WDL_SharedMutex (for shared/exclusive locks) -Scrollbar: obey LICE rowspan on image loading -SWELL: CreateBitmap() optimizations -SWELL: Much faster INI file read/write -SWELL: Experimental mode to bypass OS X's default compositing code for SWELL views. This can be disabled by defining SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN to 0. -SWELL: hugely optimized BitBlt() (no longer floods kernel messages) -SWELL: removed BitBltAlpha*(), added flag for BitBlt(), SRCCOPY_USEALPHA -SWELL: added SWELL_FlushWindow(), ReleaseDC() no longer implies window flush -SWELL: dialog background drawing improvements/optimizations - -2010-06-01: -DirScan: GetCurrentFileSize() support for OSx/Linux -FileRead: detect when no shared lock acquired, update file size on demand since it can change -IPlug: tweaks from Tale -LCF: added LCF read/write (Lice Capture Format, a good high quality lossless screencapture codec) -LICE: moved warning pragma into lice_combine.h from lice.h, to prevent app warnings from being supressed -LICE: less dependent on SWELL -LICE: added octree palette generation/mapping -LICE: better .gif support, animated .gif writing -LICE: LICE_bitmapcmp() improvements (can give bounding rect of difference) -LICE: lice_arc simplification -Resampler: fixed crash on mode switches -SHM_msgreply: fixed issue with colliding named pipe names on OSX/Linux -SWELL: menu shortcuts fixed support for various keys, control modifier -SWELL: fixed GetDC()/ReleaseDC() updating window -SWELL: organized swell.h into swell-types.h, swell-functions.h -SWELL: stronger typing for various handles -SWELL: listview scrolling fixes -SWELL: fixed swell prefix support (for app-specific objC class name prefixes) -SWELL: ES_CENTER, ES_RIGHT support -SWELL: avoiding excessive WM_SIZE coming from top level window updates (destroying, focus change, etc) -SWELL: greatly optimized .ini file access functions (use assocarray, for bsearching of contents) -Virtwnd: rendered bg image cache support -Virtwnd: better support for 0px wide/tall windows (not drawing) -Virtwnd: better margin support in static text, button controls -Virtwnd: static text controls now can have children, autodisable border if background image set -Virtwnd: added GetPositionInTopVWnd() -Virtwnd: buttons can now force text along with their images, can ignore double click -Virtwnd: IAccessible wrapper layer, support for setting per-virtwnd description strings - - -2010-04-19: -SWELL: support for control key (as FLWIN, windows key) -iPlug: less dependent on SWELL for OSX (just swell-gdi) -iPlug: fixed projects to compile - -2010-04-15: -Added: Denormal.h denormal fixing functions and other FP utilities -Added: pooled string class -Added: basic unzip functions to zlib -Added: filebrowse.h for file browsing abstraction -Added: resample.h, low-decent-high quality samplerate conversion -assocarray: fixed leak on Clear(), added reverse lookup, changekey, deletebyindex -ConvoEngine: fixed quality when switching between silent/mono/stereo -convoEngine: optimizations -dirscan: better UTF8 fixes -EEL2: support for OS X x86_64, linux x86_64, fixes for Windows x64 -FileRead: open for read even when files are also opened for writes -HeapBuf: fixed leak on operator=() -iPlug: better cocoa view detection -iPlug: control+drag for slow control -LAME support: force newer APIs for x64, dynamic loading on linux, other fixes -Linux: better support for linux and linux/64 throughout much of WDL -LICE: arc drawing clipping fix -LICE: trapezoid drawing clipping fix (used by polygon drawing) -LICE: bezier clipping fix -LICE: added LICE_LoadPNGFromMemory() -Projectcontext: zlib mem support (ifdef'd out) -PtrList: WDL_PtrList_DeleteOnDestroy class for autodeletion of items -Scrollbar: prevent invalid draws with overlapping windows -SHM_msgreply/connection: support for OSX/linux -SWELL: generic target, with optional GDK support (in progress) -SWELL: clipboard improvements (CF_TEXT support, etc) -SWELL: more cursor images -SWELL: assorted OSX fixes/improvements/corrections -SWELL: text alignment support for listview columns/headers -SWELL: internal organization improvements -SWELL: stronger typing for HMENU -SWELL: GDI pooling optimizations, fixes for shutdown cleanup with pooled objects -SWELL: x86_64 support -SWELL: multitouch, hoirz mousewheel support -SWELL: OSX text drawing improvements -SWELL: LoadLibrary()/GetProcAddress() improvements, support for bundle loading, DllMain() -SWELL: CreateSocketEvent(), WaitForMultipleSocketObjects (or something) -SWELL: SWELL_CreateProcess() -SWELL: WM_SETFONT support for text boxes -SWELL: SetTimer() with callback support -SWELL: Carbon text field processing improvements -SWELL: better .cur loading (10.4 compat), hotspot detection -SWELL: AU Cocoa UI code fixed for certain bundle filanames -Timing: improvements -VerbEngine: fixed PPC denorm support -WDLTypes: WDL_FIXALIGN for forcing 8 byte alignment on struct members -WDLTypes: added WDL_bool (for 1 byte bools) -win32_utf8: fixes, added fopenUTF8() -wndsize: safer NULL pointer checking - -2009-11-30: -DirScan: handle scanning / on posix correctly -EEL: fixed x64 bugs on certain functions -FileRead: no longer use F_NOCACHE on OSX on remote filesystems -IPlug: OSX updates, project updates -JNetLib: added outgoing interface option for connections -LAME: fixed calling of LAME on win32 (correct tag writing, etc) -LAME: fixed VBR modes on linux/OSX, correct end of encode flushing -LICE: DrawText supports LICE_DT_NEEDALPHA for forcing setting of alphachannel -LICE: LICE_ProcessRect() for per pixel transformations -LICE: HSV adjust blend mode now has S and V adjusting full range rather than 0.5. -LICE: ++ Existing code using LICE_BLIT_MODE_HSVADJ may need to be adjusted. -SWELL: Sample SWELL application -SWELL: Main application framework (with instructions on creating new applications) -SWELL: Submenu fixes -SWELL: listview imagelist separate small/state support -SWELL: Added API to initiate a drag and drop operation -SWELL: Greatly improved keyboard handling for dialogs -SWELL: Tweaks to positioning of group and tab controls -SWELL: More listview/listbox APIs implemented (thanks sws), WM_CONTEXTMENU fixes -SWELL: SetWindowPos Z ordering enabled -SWELL: Added SetCurrentDirectory() -SWELL: Fixes for browseforfile etc -SWELL: GL support for swell HWNDs -SWELL: Fixed WritePrivateProfileString section deletion -SWELL: Fixed errors when GWL_STYLE changed in WM_CREATE/WM_INITDIALOG -SWELL: TrackPopupMenu() fixed when initiated from non-mouse-event -SWELL: preliminary support for targetting 64-bit on 10.6+ -virtwnd: buttons can own their image resources -virtwnd: handy utility dialog-derived class for win32 (handles paint correctly) -virtwnd: nested children fixes, vwnds automatically reset parent pointers of children on removal -virtwnd: cursor, tooltip processing infrastructure -virtwnd: fixed WDL_VirtualWnd_PreprocessBGConfig() on certain images -wdltypes: defined GCLP_HICONSM on VC6 -Added scrollbar emulation for SWELL, skinned scrollbar support for win32 (thanks to J Brown / Cool Scrollbar Library) -Added ProjectContext utility functions - -2009-10-10: -HeapBuf: optional WDL_HEAPBUF_DYNAMIC setting, for simpler and less configurable allocation management -HeapBuf/etc now handle failures better, added CopyFrom() -IPlug: OS X updates -LICE: line drawing optimizations, AA gamma correction -LICE: bezier-fill improvements -LICE: size optimizations, options to favor size over speed throughout LICE -LICE: scaledblit() no longer processes source-clipped pixels -LICE: scaledblit() now properly supports negative width source/dest rects (flips) -LICE: blit() fix for negative coordinates -LICE: Optimized copy/multiply blend modes to not require clamping (big gains in alpha-blended and filtered blits) -LICE: Optimized alpha blending (half the multiplies) -Virtwnd: buttons now have constant icon alpha parameter -Virtwnd: sliders no longer send excess scroll messages -Virtwnd: theme background drawing has flag to not draw left/right sides -SHM: fixed/optimized datapipe class, added low-latency threadsafe SHM message/reply class -SWELL: fixes to GetPrivateProfileString() with NULL second parameter -SWELL: added SWELL_GetAudioUnitCocoaView -SWELL: support for EndDialog() in modal WM_INITDIALOG -SWELL: SetMenuItemModifier() cleanups -SWELL: File browse dialogs now set default menu -SWELL: ScrollWindow() now properly invalidates the window -SWELL: EM_SCROLL, EM_SETSEL, EM_GETSEL support for edit fields -SWELL: OPAQUE text bk mode suport -SWELL: drag/drop source handling -SWELL: GetMenuItemInfo() MIIM_ID support -SWELL: Added SWELL_GetDefaultButtonID(), SWELL_KeyToASCII -scsrc: support for HTTP POST-ing chunks of encoded data to URL -scsrc: simplified data reprocessor api -scsrc: added sc_bounce/*.php (PHP data streaming server for scsrc) -WDL_PtrList::FindSorted() fixed -AssocArray fixes -win32_utf8 fixes -FileRead/FileWrite: better async file reading error handling, Win32 and OS X locking improvements -Added FFMPEG wrapper for encoding video files (with optional audio) -RFB client support (LICE--jnetlib) - -2009-07-04: - -WDL_SharedPool optimizations -SWELL: Fixes to carbon window hosting -SWELL: drop list tweaks -WDL_PtrList: fixed FindSorted() compilation on VC2008 -Added VC2010 projects for LICE etc - -2009-07-02: - -SWELL: mouse positioning updates (with synergy2 detection) -SWELL: WM_CTLCOLOR*, WM_DISPLAYCHANGE support -SWELL: BS_LEFTTEXT support for checkboxes -SWELL: Fixed menu item updating for top level submenus -SWELL: Implemented TreeView_HitTest -SWELL: Exposed API for SetOpaque -SWELL: nifty child window debug/diagnostic mode -SWELL: (default) options to use non-round buttons etc -SWELL: Fixed BitBltAlpha() for LICE sysbitmaps -SWELL: Carbon hosted window updates (no menu, activation fixes for BFD2, etc) -LICE: 8-bit PNG loading, JPG load from resource support -LICE: optimized source alpha w/ constalpha=1.0, other cases -virtwnd: listbox text drawing updates -LICE: LICE_CachedFont fixes when using both cached fonts and OS rendering -WDL_FileRead: support for synchronous unbuffered reads -WDL_FileRead/Write: OS X native open()/pread/mmap support (large files and unbuffered reads etc) -WDL_String: safer Get() for empty strings (returns read-write pointer) -WDL_PtrList: FindSorted / InsertSorted, EmptySafe() -WDL_Queue: optimized Compact() to autodetect pointless compacts -WDL_MergeSort: optimized for in-order data (stays in place) -EEL: safer locking of RAM -IPlug: better bitmap caching, jpg loading, x64 support, OS X udpates -AudioBufferContainer: supports wet/dry -UTF8 support fixes -Added WDL_AssocArray - - - -2009-04-08: - -UTF-8 support, win32_utf8.cpp for Win32 support (SWELL gets it automatically) -LICE: line and circle updates for fractional coordinates -LICE: preliminary SVG stuff -LICE: CachedFont updates (can render natively if possible and desired, better owned font support) -LICE: scaled blitting downsizing uses special filtering -LICE: disabled experimental GL extensions by default -LICE: better bezier stuff -IPlug: OSX URL update, VST parameter index validation, other updates -virtwnd: listbox improvements (horizontal mode etc) -SWELL: preliminary WM_CTLCOLORDLG support, dialog background updates -SWELL: better default button sizing -PtrList: InsertSorted() and FindSorted() methods -wndsize: margin querying api -LAME support handles mono signals better, better search paths -added basic blowfish implementation -added basic IRC line parsing/formatting functions -added incomplete non-working SHM datapipe class -convolution engine updates - - -2009-01-16: restored LICE bitmap ABI for compatability with older WDL versions -2009-01-15: Convolution engine optimizations and bugfixes, slightly updated impulse API -2009-01-13: simple reusable pitch shifter/time stretcher added -2009-01-11: WDL_Queue autocompact optimizations -2009-01-10: ADPCM decoder (IMA + MSADPCM + cADPCM), IMA/cADPCM encoder -2009-01-08: virtwnd comboboxes support SUB tags -2009-01-07: Vorbis encoder supports multichannel encoding -2009-01-01: Added LICE_DashedLine -2009-01-01: LICE_LoadPNGFromNamedResource() for OSX -2008-12-29: iPlug: added images for example -2008-12-27: LICE: Preliminary work for allowing LICE operations to be GL accelerated -2008-12-20: LICE: added effect names to test application -2008-12-20: LICE: added preliminary SVG support -2008-12-13: SWELL: Imagelists no longer free their bitmaps (to match win) -2008-12-13: WDL_WndSizer: reduced chance of HDWP leaks when invalid windows are stored -2008-12-09: Virtwnd: grayed state for buttons -2008-12-07: SWELL fixes for BitBlt/StretchBlt() with certain coordinates -2008-12-06: LICE HSV combining blend modes -2008-12-05: Plush2 multitexture fixes, fixed source-alpha modes -2008-12-04: Virtwnd: improved ordering of notification calls to allow deleting a vwnd from a command message -2008-11-24: WDL_String optimizations for empty strings -2008-11-22: LICE: line drawing improvements (changed signature of LICE_Line to use integers) -2008-11-20: SWELL: start on GTK implementations, far away from useful though -2008-11-19: EEL2 fixes for recent GCC versions on Linux, constness -2008-11-18: Added WDL_HeapBuf copy constructors -2008-11-18: LICE: RGB/HSV colorspace conversions -2008-11-17: LICE: overlay blend modes -2008-11-16: LICE: Better bezier drawing -2008-11-16: LICE: improved circle/arc drawing routes -2008-11-15: LICE JPEG loading fixes, JPEG writing, PNG writing byteorder fixes -2008-11-14: LICE_FillCircle() (needs optimizing) -2008-11-11: LICE_LoadImage, LICE_GetImageExtensoinList(),and LICE_CmpBitmap() -2008-11-08: LICE test app has new "fly" demo -2008-11-06: LICE: fixed bug in LICE_SubBitmap -2008-11-06: JNetLib: optional interface modes so you can easily reuse jnetlib across modules -2008-11-06: LICE: bitmaps no longer flipped on OS X, made isFlipped() non-virtual to enable better compile-time optimization -2008-11-05: LICE: reduced image resize heap thrashing -2008-11-05: virtwnd detects at load whether backgrounds have alphachannel info in each section -2008-11-04: virtwnd backgrounds disable filtering when not stretching -2008-11-03: LICE: optimizations for 50/50 fills, fast unfiltered stretchblt, etc -2008-11-03: virtwnd overhauls (removing HICON use) -2008-11-03: LICE: .ico loading overhaul, support for OS X -2008-11-01: SWELL: faster BitBlt() support -2008-11-01: LICE_CachedText OS X fixes -2008-10-31: LICE: LICE_LoadBMP() OS X support -2008-10-31: SWELL: GetObject() API subset -2008-10-31: LICE_MultiplyAddRect updated documentation and internals -2008-10-31: LICE_IFonts can own/destroy HFONTs -2008-10-30: LICE: Fixed a lot of small accuracy bugs -2008-10-30: LICE: PCX reading support -2008-10-30: Plush2: fixed singletexture mode when only multitexture compiled in -2008-10-30: Plush2: fixed repeating textures in bilinear mode -2008-10-30: Wndsizer: margin support -2008-10-30: Virtwnd: now uses LICE almost exclusively to draw controls -2008-10-30: Added Plush2: a port of the old 8bpp 3D rendering engine to a C++, 24 bit, LICE-combining multitexture capable colored lighting rendering engine -2008-10-27: Added LICE_FillTriangle(), LICE_HalveBlitAA(), fixed bug in LICE_StretchedBlit() -2008-10-26: Added iplug, a VST/AU plug-in framework -2008-10-26: LICE: LICE_SubBitmap for easy clipped rendering -2008-10-21: LICE: Added LICE_DrawRect(), LICE_DrawGlyph(), fast tiny circle drawing (glyph based), optimizations to internals -2008-10-20: LICE: Added LICE_IFont and LICE_CachedFont() for quick drawing and drawing to non-sysbitmaps. Also has certain useful other effects. -2008-10-20: LICE: Added LICE_DrawBezier -2008-10-20: Virtwnd: item backgrounds can now specify (with 255,255,0,255) outside-areas for some controls -2008-10-13: Added mergesort.h -2008-10-10: Added fast sinewave genereator (sinewavegen.h) -2008-10-10: SWELL: Keyboard fixes -2008-10-09: SWELL: Changed the way ScrollWindow() is implemented (scrolls children) -2008-10-09: Virtwnd: fixes for large canvas drawing -2008-10-05: Tweaks all around to reduce memory use (WDL_String gets WDL_HeapBuf granularity options etc in constructor) -2008-09-29: SWELL: Fixed MK_* VK_* bugs -2008-09-22: Win32_Curses updates, better OS X compatability, block cursor -2008-09-20: SWELL: ShowWindow(SW_HIDE) DestroyWindow() deal with focus better now -2008-09-17: Virtwnd: support for querying painter info, etc -2008-09-08: audiobuffercontainer fixes, optimizations -2008-09-06: Virtwnd sliders can optionally always send notifications on first click -2008-08-31: Overhauled pooling classes to be more general and reusable -2008-08-30: SWELL: Improved EndDialog() processing -2008-08-29: SWELL: Default menu for windows, modal windows -2008-08-28: SWELL: made GDI pooling threadsafe (Rosetta on 10.5 requires it) -2008-08-28: SWELL: fixed shift+mousewheel being sent correctly -2008-08-15: Fixed issues with Vorbis encoding-EOF-ness for NINJAM, added Vorbis comment support -2008-07-30: Cleaned up WDL_Queue's endian-converting functions -2008-07-28: Fixed WDL_String::Ellipsize() -2008-07-28: Added EEL2, a fast expression evaluator/code compiler that supports x86, x64 and PPC, MSVC and GCC. -2008-07-27: SWELL: fixed an issue with OS X hanging on fractional window positions -2008-07-22: Added WDL_String::Ellipsize() -2008-07-20: Win64 compatability, wdl_types.h has GetClassLongPtr() etc defines for MSVC6/OSX -2008-07-19: SWELL: GDI object pooling to reduce heap thrashing -2008-07-19: wndsize: fixed window positioning bug when used in SWELL. -2008-07-19: SWELL: LVNI_SELECTED support -2008-07-19: SWELL: better support for 64 bit OS X 10.5. -2008-07-17: VirtWnd slider mousewheel fixes -2008-07-15: SWELL: Treeview API improvements -2008-07-14: Added WDL_DLGRET for DLGPROC return type to ease compiler differences (use instead of BOOL CALLBACK or UINT_PTR CALLBACK) -2008-07-11: added win32_curses super-basic curses emulation for windows GUI -2008-07-10: LICE bitmap allocation changes (safer failures) -2008-07-10: SWELL: fixed GetCursorPos()/SetCursorPos() relationships -2008-07-10: SWELL: WM_MBUTTON* support -2008-07-08: Heapbuf can have optional small pre-allocations, heapbuf trace mode (to monitor heap use) -2008-06-30: LICE: Better bezierness -2008-06-30: SWELL: BitBltAlpha() and BitBltAlphaFromMem() -2008-06-24: WDL_FileWrite: fixed GetSize() at eof before flushing -2008-06-02: SWELL: many more bugfixes, initial work on 64 bit support, more -2008-05-21: Virtwnd: userdata for all virtwnd support -2008-05-05: SWELL: huge updates (too much to list) -2008-04-28: LICE: schwa's updated lice_bezier with support for quadratic nurbs -2008-04-27: SWELL: updates to EndDialog, added rc2cpp_dlg.php -2008-04-0x: fileread improvements for errors in async mode -2008-03-01: SWELL: ImageList_Destroy support -2008-02-09: lineparser improvements -2008-02-09: slightly faster drawtext, text cleanups -2008-02-09: virtwnd buttons only refresh on changes of button images -2008-02-09: virtwnd buttons support overlay outlines -2008-02-09: SWELL: php converter for menus: .rc to cpp -2008-02-09: SWELL: cursor hiding support -2008-02-09: wndsize: fix for when no window set -2008-02-09: lice: png write support (thanks cryptomail) -2008-02-09: shoutcast source: better encoder reinitialization, IRC channel support -2008-02-09: FFT: more define options -2008-02-09: convolution engine: fixed some bugs, added test app, _Div mode which allows high-cpu ZL operation -2008-01-25: LICE: flipped surface support for arcs -2007-12-17: SWELL: BM_SETCHECK support for buttons, basic FindWindowEx() emulation, better control font size selection -2007-12-13: SWELL: Basic ScrollWindow() emulation -2007-12-13: LICE: Updated LICE_IBitmap to include getDC() -2007-12-12: SWELL: GetDC(), GetWindowDC() improvements, GetSystemMetrics() -2007-12-12: SWELL: better WM_MOUSEWHEEL, WM_CONTEXTMENU message propagation -2007-12-11: SWELL: WM_NCCALCSIZE, WM_NCHITTEST etc support -2007-12-10: SWELL: basic _controlfp() support for rounding control (on x86) -2007-12-06: LICE: better bitmapped font -2007-12-05: LICE: schwa's faster/smaller lice_line -2007-12-04: SWELL: updated documentation in swell.h, GlobalAlloc supports GMEM_FIXED -2007-12-03: SWELL: added time.h inclusion for 10.5, fixed DrawText() when no font selected -2007-12-02: SWELL: GetProp API support, GetDC/GetWindowDC now usable during WM_PAINT/NCPAINT (they get the same HDC as BeginPaint) -2007-12-02: SWELL: dialogs can now have their window procedures subclassed, WM_NCPAINT support -2007-11-29: SWELL: fixed EnumClipboardFormats sometimes getting in an infinite loop -2007-11-29: SWELL: big DrawText overhaul (now uses NSAttributedString to draw) -2007-11-29: SWELL: added a bunch more compatibility defines to swell.h -2007-11-24: SWELL: support for having the application automatically provide the SWELL API to children -2007-11-24: SWELL: fixed some issues with name collisions to old deprecated Mac APIs -2007-11-24: SWELL: added opaque flag for dialogs (implicit on resourceless child windows) -2007-11-24: SWELL: basic GetDC()/ReleaseDC() support -2007-11-24: LICE: made OS X test app use opaque view (huge speedup) -2007-11-24: LICE: test app shows framerate -2007-11-23: SWELL: tons of menu fixes, dialog fixes, API extensions, more. too much to list. -2007-11-23: LICE: LICE_line supports flipped surfaces -2007-11-13: SWELL: Owned window support, tons of updates -2007-11-13: Virtwnd: support for controls eating mousedowns without capturing -2007-11-09: Fixed distribution making to include more docs/etc -2007-11-09: LICE: Test app now uses SWELL to run on OS X, included OS X example test project -2007-11-09: SWELL: Extensive updates for child dialogs, modal/modeless dialogs (mouse messages, painting, etc etc) -2007-11-09: SWELL: Modal/Modeless windows now support having their own menus (via GetMenu/SetMenu) -2007-11-09: SWELL: Added user-defined control classes for dialog template loading -2007-11-09: Updated GIFlib config.h for OS X support -2007-10-30: LICE: GIF, JPEG loading (included JPEG library and GifLib) -2007-10-30: LICE: Added bezier functions (Schwa) -2000-10-28: FileRead: better use of asynchronous buffer space, application level buffered synchronous reading support -2007-10-26: SWELL: WM_PAINT/BeginPaint/EndPaint emulation for child dialogs -2007-10-26: SWELL: SendMessage for windows that support it, made virtwnd use sendmessage -2007-10-26: SWELL: 3-state checkboxes, SetWindowLong improvements, fake *Capture, more -2007-10-24: SWELL: DialogBox/CreateDialog emulation, timer fixes, tons more -2007-10-23: LICE: scwha added LICE_ClipLine() -2007-10-19: LAMEEnc preliminary linux/OSX support (needs a lot of work though) -2007-09-17: virtual window system cleanups, sliders have mouse-hiding ctrl+ modifier mode -2007-09-17: virtual window system listbox custom drawing -2007-09-17: virtual window system, other improvements -2007-09-17: filewrite recovers from asynchronous failures from threads quitting -2007-09-12: pcmfmtcvt: corrected non-standard pcm format conversion -2007-09-14: LICE: fixed circle drawing with vc6 (template bug) -2007-09-01: LICE: faster rotating blit (fixed point) -2007-08-31: virtwnd: sliders can have centerline color defined in their skininfo -2007-08-27: LICE: faster more-fixed-point mode for LICE_ScaledBlit -2007-08-26: LICE: LICE_ScaledBlit properly obeys using a subimage source (and wont filter from outside) -2007-08-26: added db2val.h for easy dB<-->linear scale conversion -2007-08-25: virtwnd: stuff to let control bgs and window bg images have pink lines to define unstretched edges -2007-08-23: virtwnd: added listbox control -2007-08-22: LICE: defines for disabling Dodge, Add blend modes -2007-08-22: LICE: updated deltablit, added transformblit -2007-08-22: LICE: made LICE_FillRect support LICE_MODE_USE_ALPHA -2007-08-21: LICE: added LICE_BLIT_MODE_DODGE (thx schwa) -2007-08-21: LICE: added LICE_Blur, overloaded LICE_Blit() with better parameters -2007-08-16: LICE: added LICE_FillRect() -2007-08-15: filewrite: fixed GetSize() after flushed and unflushed writes in async mode -2007-08-04: virtwnd: made static text labels not refresh if text did not change -2007-08-04: started more detailed changelog -2007-07-23: added basic freeverb based reverb engine (verbengine.h) -2007-07-09: schwa fixes the FFT library's reordering API -2007-07-07: virtwnd fully uses LICE, support for advanced UI features -2007-07-01: lineparse.h now supports reading floats that use a , instead of . -2007-06-20: fileread.h has been asynchronous reading behavior -2007-06-20: virtwnd uses LICE for rendering gradients and general composition -2007-06-17: renamed string.h to wdlstring.h for if WDL is added to include paths -2007-05-09: first WDL release diff --git a/WDL/jnetlib/Makefile b/WDL/jnetlib/Makefile deleted file mode 100644 index 58cab477..00000000 --- a/WDL/jnetlib/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# freebsd3 makefile -default: jnl.a - -LDFLAGS = -pthread -CFLAGS = -s -O2 -Wall -DTHREAD_SAFE -D_THREAD_SAFE -D_REENTRANT -CC = gcc -CPP = g++ -CXX = g++ - -OBJS = asyncdns.o connection.o httpget.o httpserv.o listen.o util.o sercon.o - -jnl.a: ${OBJS} - -rm -f jnl.a - ar rcs jnl.a ${OBJS} - -test: ${OBJS} test.o - $(CC) ${CFLAGS} -o test test.o ${OBJS} ${LDFLAGS} - -clean: - -rm -f ${OBJS} test jnl.a test.o diff --git a/WDL/jnetlib/asyncdns.cpp b/WDL/jnetlib/asyncdns.cpp deleted file mode 100644 index 1b50139b..00000000 --- a/WDL/jnetlib/asyncdns.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: asyncdns.cpp - JNL portable asynchronous DNS implementation -** License: see jnetlib.h -*/ - -#include "netinc.h" -#include "util.h" -#include "asyncdns.h" -#ifdef _WIN32 -#include -#endif - -JNL_AsyncDNS::JNL_AsyncDNS(int max_cache_entries) -{ - m_thread_kill=1; - m_thread=0; - m_cache_size=max_cache_entries; - m_cache=(cache_entry *)::malloc(sizeof(cache_entry)*m_cache_size); - memset(m_cache,0,sizeof(cache_entry)*m_cache_size); -} - -JNL_AsyncDNS::~JNL_AsyncDNS() -{ -#ifndef NO_DNS_SUPPORT - m_thread_kill=1; - -#ifdef _WIN32 - if (m_thread) - { - WaitForSingleObject(m_thread,INFINITE); - CloseHandle(m_thread); - } -#else - if (m_thread) - { - void *p; - pthread_join(m_thread,&p); - } -#endif//!_WIN32 -#endif//NO_DNS_SUPPORT - free(m_cache); -} - -#ifdef _WIN32 -unsigned WINAPI JNL_AsyncDNS::_threadfunc(void *_d) -#else -unsigned int JNL_AsyncDNS::_threadfunc(void *_d) -#endif -{ -#ifndef NO_DNS_SUPPORT - int nowinsock=JNL::open_socketlib(); - JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d; - int x; - for (x = 0; x < _this->m_cache_size && !_this->m_thread_kill; x ++) - { - if (_this->m_cache[x].last_used && !_this->m_cache[x].resolved) - { - if (!nowinsock) - { - if (_this->m_cache[x].mode==0) - { - struct hostent *hostentry; - hostentry=::gethostbyname(_this->m_cache[x].hostname); - if (hostentry) - { - _this->m_cache[x].addr=*((int*)hostentry->h_addr); - } - else - _this->m_cache[x].addr=INADDR_NONE; - } - else if (_this->m_cache[x].mode==1) - { - struct hostent *ent; - ent=::gethostbyaddr((const char *)&_this->m_cache[x].addr,4,AF_INET); - if (ent) - { - strncpy(_this->m_cache[x].hostname,ent->h_name,255); - _this->m_cache[x].hostname[255]=0; - } - else - { - _this->m_cache[x].hostname[0]=0; - } - } - _this->m_cache[x].resolved=1; - } - else - { - if (_this->m_cache[x].mode==0) - { - _this->m_cache[x].addr=INADDR_NONE; - _this->m_cache[x].resolved=1; - } - else if (_this->m_cache[x].mode==1) - { - _this->m_cache[x].hostname[0]=0; - _this->m_cache[x].resolved=1; - } - } - } - } - if (!nowinsock) JNL::close_socketlib(); - _this->m_thread_kill=1; -#endif // NO_DNS_SUPPORT - - return 0; -} - -int JNL_AsyncDNS::resolve(const char *hostname, unsigned int *addr) -{ - // return 0 on success, 1 on wait, -1 on unresolvable - int x; - unsigned int ip=inet_addr(hostname); - if (ip != INADDR_NONE) - { - *addr=ip; - return 0; - } -#ifndef NO_DNS_SUPPORT - - for (x = 0; x < m_cache_size; x ++) - { - if (!strcasecmp(m_cache[x].hostname,hostname) && m_cache[x].mode==0) - { - m_cache[x].last_used=time(NULL); - if (m_cache[x].resolved) - { - if (m_cache[x].addr == INADDR_NONE) - { - return -1; - } - struct in_addr in; - in.s_addr=m_cache[x].addr; - *addr=m_cache[x].addr; - return 0; - } - makesurethreadisrunning(); - return 1; - } - } - // add to resolve list - int oi=-1; - for (x = 0; x < m_cache_size; x ++) - { - if (!m_cache[x].last_used) - { - oi=x; - break; - } - if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved) - { - oi=x; - } - } - if (oi == -1) - { - return -1; - } - strcpy(m_cache[oi].hostname,hostname); - m_cache[oi].mode=0; - m_cache[oi].addr=INADDR_NONE; - m_cache[oi].resolved=0; - m_cache[oi].last_used=time(NULL); - - makesurethreadisrunning(); - return 1; -#else - return -1; -#endif -} - -int JNL_AsyncDNS::reverse(unsigned int addr, char *hostname) -{ - // return 0 on success, 1 on wait, -1 on unresolvable - int x; - if (addr == INADDR_NONE) - { - return -1; - } -#ifndef NO_DNS_SUPPORT - for (x = 0; x < m_cache_size; x ++) - { - if (m_cache[x].addr==addr && m_cache[x].mode==1) - { - m_cache[x].last_used=time(NULL); - if (m_cache[x].resolved) - { - if (!m_cache[x].hostname[0]) - { - return -1; - } - strncpy(hostname,m_cache[x].hostname,255); - hostname[255]=0; - return 0; - } - makesurethreadisrunning(); - return 1; - } - } - // add to resolve list - int oi=-1; - for (x = 0; x < m_cache_size; x ++) - { - if (!m_cache[x].last_used) - { - oi=x; - break; - } - if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved) - { - oi=x; - } - } - if (oi == -1) - { - return -1; - } - m_cache[oi].addr=addr; - m_cache[oi].hostname[0]=0; - m_cache[oi].resolved=0; - m_cache[oi].mode=1; - m_cache[oi].last_used=time(NULL); - - makesurethreadisrunning(); - return 1; -#else - return -1; -#endif -} - - -void JNL_AsyncDNS::makesurethreadisrunning(void) -{ -#ifndef NO_DNS_SUPPORT - if (m_thread_kill) - { - #ifdef _WIN32 - if (m_thread) - { - WaitForSingleObject(m_thread,INFINITE); - CloseHandle(m_thread); - } - unsigned id; - m_thread_kill=0; - m_thread=(HANDLE)_beginthreadex(NULL,0,_threadfunc,(void *)this,0,&id); - if (!m_thread) - { - #else - if (m_thread) - { - void *p; - pthread_join(m_thread,&p); - } - m_thread_kill=0; - if (pthread_create(&m_thread,NULL,(void *(*) (void *))_threadfunc,(void*)this) != 0) - { - #endif - m_thread_kill=1; - } - } -#endif//NO_DNS_SUPPORT -} diff --git a/WDL/jnetlib/asyncdns.h b/WDL/jnetlib/asyncdns.h deleted file mode 100644 index 172c2a94..00000000 --- a/WDL/jnetlib/asyncdns.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: asyncdns.h - JNL portable asynchronous DNS interface -** License: see jnetlib.h -** -** Usage: -** 1. Create JNL_AsyncDNS object, optionally with the number of cache entries. -** 2. call resolve() to resolve a hostname into an address. The return value of -** resolve is 0 on success (host successfully resolved), 1 on wait (meaning -** try calling resolve() with the same hostname in a few hundred milliseconds -** or so), or -1 on error (i.e. the host can't resolve). -** 3. call reverse() to do reverse dns (ala resolve()). -** 4. enjoy. -*/ - -#ifndef _ASYNCDNS_H_ -#define _ASYNCDNS_H_ - -#ifndef JNL_NO_DEFINE_INTERFACES -class JNL_IAsyncDNS -{ -public: - virtual ~JNL_IAsyncDNS() { } - virtual int resolve(const char *hostname, unsigned int *addr)=0; // return 0 on success, 1 on wait, -1 on unresolvable - virtual int reverse(unsigned int addr, char *hostname)=0; // return 0 on success, 1 on wait, -1 on unresolvable. hostname must be at least 256 bytes. -}; -#define JNL_AsyncDNS_PARENTDEF : public JNL_IAsyncDNS -#else -#define JNL_IAsyncDNS JNL_AsyncDNS -#define JNL_AsyncDNS_PARENTDEF -#endif - - -#ifndef JNL_NO_IMPLEMENTATION - -class JNL_AsyncDNS JNL_AsyncDNS_PARENTDEF -{ -public: - JNL_AsyncDNS(int max_cache_entries=64); - ~JNL_AsyncDNS(); - - int resolve(const char *hostname, unsigned int *addr); // return 0 on success, 1 on wait, -1 on unresolvable - int reverse(unsigned int addr, char *hostname); // return 0 on success, 1 on wait, -1 on unresolvable. hostname must be at least 256 bytes. - -private: - typedef struct - { - int last_used; // timestamp. - char resolved; - char mode; // 1=reverse - char hostname[256]; - unsigned int addr; - } - cache_entry; - - cache_entry *m_cache; - int m_cache_size; - volatile int m_thread_kill; -#ifdef _WIN32 - HANDLE m_thread; - static unsigned WINAPI _threadfunc(void *_d); -#else - pthread_t m_thread; - static unsigned int _threadfunc(void *_d); -#endif - void makesurethreadisrunning(void); - -}; -#endif // !JNL_NO_IMPLEMENTATION - -#endif //_ASYNCDNS_H_ diff --git a/WDL/jnetlib/connection.cpp b/WDL/jnetlib/connection.cpp deleted file mode 100644 index 43c2e1c8..00000000 --- a/WDL/jnetlib/connection.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: connection.cpp - JNL TCP connection implementation -** License: see jnetlib.h -*/ - -#include "netinc.h" -#include "util.h" -#include "connection.h" - - -JNL_Connection::JNL_Connection(JNL_IAsyncDNS *dns, int sendbufsize, int recvbufsize) -{ - m_errorstr=""; - if (dns == JNL_CONNECTION_AUTODNS) - { - m_dns=new JNL_AsyncDNS(); - m_dns_owned=1; - } - else - { - m_dns=dns; - m_dns_owned=0; - } - m_recv_buffer_len=recvbufsize; - m_send_buffer_len=sendbufsize; - m_recv_buffer=(char*)malloc(m_recv_buffer_len); - m_send_buffer=(char*)malloc(m_send_buffer_len); - m_socket=-1; - memset(m_recv_buffer,0,recvbufsize); - memset(m_send_buffer,0,sendbufsize); - m_remote_port=0; - m_state=STATE_NOCONNECTION; - m_localinterfacereq=INADDR_ANY; - m_recv_len=m_recv_pos=0; - m_send_len=m_send_pos=0; - m_host[0]=0; - m_saddr = new struct sockaddr_in; - memset(m_saddr,0,sizeof(struct sockaddr_in)); -} - -void JNL_Connection::connect(int s, struct sockaddr_in *loc) -{ - close(1); - m_socket=s; - m_remote_port=0; - m_dns=NULL; - if (loc) *m_saddr=*loc; - else memset(m_saddr,0,sizeof(struct sockaddr_in)); - if (m_socket != -1) - { - SET_SOCK_BLOCK(m_socket,0); - m_state=STATE_CONNECTED; - } - else - { - m_errorstr="invalid socket passed to connect"; - m_state=STATE_ERROR; - } -} - -void JNL_Connection::connect(char *hostname, int port) -{ - close(1); - m_remote_port=(short)port; - m_socket=::socket(AF_INET,SOCK_STREAM,0); - if (m_socket==-1) - { - m_errorstr="creating socket"; - m_state=STATE_ERROR; - } - else - { - if (m_localinterfacereq != INADDR_ANY) - { - sockaddr_in sa={0,}; - sa.sin_family=AF_INET; - sa.sin_addr.s_addr=m_localinterfacereq; - bind(m_socket,(struct sockaddr *)&sa,16); - } - SET_SOCK_BLOCK(m_socket,0); - strncpy(m_host,hostname,sizeof(m_host)-1); - m_host[sizeof(m_host)-1]=0; - memset(m_saddr,0,sizeof(struct sockaddr_in)); - if (!m_host[0]) - { - m_errorstr="empty hostname"; - m_state=STATE_ERROR; - } - else - { - m_state=STATE_RESOLVING; - m_saddr->sin_family=AF_INET; - m_saddr->sin_port=htons((unsigned short)port); - m_saddr->sin_addr.s_addr=inet_addr(hostname); - } - } -} - -JNL_Connection::~JNL_Connection() -{ - if (m_socket >= 0) - { - ::shutdown(m_socket, SHUT_RDWR); - ::closesocket(m_socket); - m_socket=-1; - } - free(m_recv_buffer); - free(m_send_buffer); - if (m_dns_owned) - { - delete m_dns; - } - delete m_saddr; -} - -void JNL_Connection::run(int max_send_bytes, int max_recv_bytes, int *bytes_sent, int *bytes_rcvd) -{ - int bytes_allowed_to_send=(max_send_bytes<0)?m_send_buffer_len:max_send_bytes; - int bytes_allowed_to_recv=(max_recv_bytes<0)?m_recv_buffer_len:max_recv_bytes; - - if (bytes_sent) *bytes_sent=0; - if (bytes_rcvd) *bytes_rcvd=0; - - switch (m_state) - { - case STATE_RESOLVING: - if (m_saddr->sin_addr.s_addr == INADDR_NONE) - { - int a=m_dns?m_dns->resolve(m_host,(unsigned int *)&m_saddr->sin_addr.s_addr):-1; - if (!a) { m_state=STATE_CONNECTING; } - else if (a == 1) - { - m_state=STATE_RESOLVING; - break; - } - else - { - m_errorstr="resolving hostname"; - m_state=STATE_ERROR; - return; - } - } - if (!::connect(m_socket,(struct sockaddr *)m_saddr,16)) - { - m_state=STATE_CONNECTED; - } - else if (ERRNO!=EINPROGRESS) - { - m_errorstr="connecting to host"; - m_state=STATE_ERROR; - } - else { m_state=STATE_CONNECTING; } - break; - case STATE_CONNECTING: - { - fd_set f[3]; - FD_ZERO(&f[0]); - FD_ZERO(&f[1]); - FD_ZERO(&f[2]); - FD_SET(m_socket,&f[0]); - FD_SET(m_socket,&f[1]); - FD_SET(m_socket,&f[2]); - struct timeval tv; - memset(&tv,0,sizeof(tv)); - if (select(m_socket+1,&f[0],&f[1],&f[2],&tv)==-1) - { - m_errorstr="connecting to host (calling select())"; - m_state=STATE_ERROR; - } - else if (FD_ISSET(m_socket,&f[1])) - { - m_state=STATE_CONNECTED; - } - else if (FD_ISSET(m_socket,&f[2])) - { - m_errorstr="connecting to host"; - m_state=STATE_ERROR; - } - } - break; - case STATE_CONNECTED: - case STATE_CLOSING: - if (m_send_len>0 && bytes_allowed_to_send>0) - { - int len=m_send_buffer_len-m_send_pos; - if (len > m_send_len) len=m_send_len; - if (len > bytes_allowed_to_send) len=bytes_allowed_to_send; - if (len > 0) - { - int res=::send(m_socket,m_send_buffer+m_send_pos,len,0); - if (res==-1 && ERRNO != EWOULDBLOCK) - { -// m_state=STATE_CLOSED; -// return; - } - if (res>0) - { - bytes_allowed_to_send-=res; - if (bytes_sent) *bytes_sent+=res; - m_send_pos+=res; - m_send_len-=res; - } - } - if (m_send_pos>=m_send_buffer_len) - { - m_send_pos=0; - if (m_send_len>0) - { - len=m_send_buffer_len-m_send_pos; - if (len > m_send_len) len=m_send_len; - if (len > bytes_allowed_to_send) len=bytes_allowed_to_send; - int res=::send(m_socket,m_send_buffer+m_send_pos,len,0); - if (res==-1 && ERRNO != EWOULDBLOCK) - { -// m_state=STATE_CLOSED; - } - if (res>0) - { - bytes_allowed_to_send-=res; - if (bytes_sent) *bytes_sent+=res; - m_send_pos+=res; - m_send_len-=res; - } - } - } - } - if (m_recv_len m_recv_buffer_len-m_recv_len) len=m_recv_buffer_len-m_recv_len; - if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv; - if (len>0) - { - int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0); - if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK)) - { - m_state=STATE_CLOSED; - break; - } - if (res > 0) - { - bytes_allowed_to_recv-=res; - if (bytes_rcvd) *bytes_rcvd+=res; - m_recv_pos+=res; - m_recv_len+=res; - } - } - if (m_recv_pos >= m_recv_buffer_len) - { - m_recv_pos=0; - if (m_recv_len < m_recv_buffer_len) - { - len=m_recv_buffer_len-m_recv_len; - if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv; - if (len > 0) - { - int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0); - if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK)) - { - m_state=STATE_CLOSED; - break; - } - if (res > 0) - { - bytes_allowed_to_recv-=res; - if (bytes_rcvd) *bytes_rcvd+=res; - m_recv_pos+=res; - m_recv_len+=res; - } - } - } - } - } - if (m_state == STATE_CLOSING) - { - if (m_send_len < 1) m_state = STATE_CLOSED; - } - break; - default: break; - } -} - -void JNL_Connection::close(int quick) -{ - if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING) - { - m_state=STATE_CLOSED; - if (m_socket >= 0) - { - ::shutdown(m_socket, SHUT_RDWR); - ::closesocket(m_socket); - } - m_socket=-1; - memset(m_recv_buffer,0,m_recv_buffer_len); - memset(m_send_buffer,0,m_send_buffer_len); - m_remote_port=0; - m_recv_len=m_recv_pos=0; - m_send_len=m_send_pos=0; - m_host[0]=0; - memset(m_saddr,0,sizeof(struct sockaddr_in)); - } - else - { - if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING; - } -} - -int JNL_Connection::send_bytes_in_queue(void) -{ - return m_send_len; -} - -int JNL_Connection::send_bytes_available(void) -{ - return m_send_buffer_len-m_send_len; -} - -int JNL_Connection::send(const void *_data, int length) -{ - const char *data = static_cast(_data); - if (length > send_bytes_available()) - { - return -1; - } - - int write_pos=m_send_pos+m_send_len; - if (write_pos >= m_send_buffer_len) - { - write_pos-=m_send_buffer_len; - } - - int len=m_send_buffer_len-write_pos; - if (len > length) - { - len=length; - } - - memcpy(m_send_buffer+write_pos,data,len); - if (length > len) - { - memcpy(m_send_buffer,data+len,length-len); - } - m_send_len+=length; - return 0; -} - -int JNL_Connection::send_string(const char *line) -{ - return send(line,strlen(line)); -} - -int JNL_Connection::recv_bytes_available(void) -{ - return m_recv_len; -} - -int JNL_Connection::peek_bytes(void *_data, int maxlength) -{ - char *data = static_cast(_data); - if (maxlength > m_recv_len) - { - maxlength=m_recv_len; - } - int read_pos=m_recv_pos-m_recv_len; - if (read_pos < 0) - { - read_pos += m_recv_buffer_len; - } - int len=m_recv_buffer_len-read_pos; - if (len > maxlength) - { - len=maxlength; - } - if (data != NULL) { - memcpy(data,m_recv_buffer+read_pos,len); - if (len < maxlength) - { - memcpy(data+len,m_recv_buffer,maxlength-len); - } - } - - return maxlength; -} - -int JNL_Connection::recv_bytes(void *_data, int maxlength) -{ - char *data = static_cast(_data); - - int ml=peek_bytes(data,maxlength); - m_recv_len-=ml; - return ml; -} - -int JNL_Connection::getbfromrecv(int pos, int remove) -{ - int read_pos=m_recv_pos-m_recv_len + pos; - if (pos < 0 || pos > m_recv_len) return -1; - if (read_pos < 0) - { - read_pos += m_recv_buffer_len; - } - if (read_pos >= m_recv_buffer_len) - { - read_pos-=m_recv_buffer_len; - } - if (remove) m_recv_len--; - return m_recv_buffer[read_pos]; -} - -int JNL_Connection::recv_lines_available(void) -{ - int l=recv_bytes_available(); - int lcount=0; - int lastch=0; - int pos; - for (pos=0; pos < l; pos ++) - { - int t=getbfromrecv(pos,0); - if (t == -1) return lcount; - if ((t=='\r' || t=='\n') &&( - (lastch != '\r' && lastch != '\n') || lastch==t - )) lcount++; - lastch=t; - } - return lcount; -} - -int JNL_Connection::recv_line(char *line, int maxlength) -{ - if (maxlength > m_recv_len) maxlength=m_recv_len; - while (maxlength--) - { - int t=getbfromrecv(0,1); - if (t == -1) - { - *line=0; - return 0; - } - if (t == '\r' || t == '\n') - { - int r=getbfromrecv(0,0); - if ((r == '\r' || r == '\n') && r != t) getbfromrecv(0,1); - *line=0; - return 0; - } - *line++=(char)t; - } - return 1; -} - -void JNL_Connection::set_interface(int useInterface) // call before connect if needed -{ - m_localinterfacereq = useInterface; -} - - -unsigned int JNL_Connection::get_interface(void) -{ - if (m_socket==-1) return 0; - struct sockaddr_in sin; - memset(&sin,0,sizeof(sin)); - socklen_t len=16; - if (::getsockname(m_socket,(struct sockaddr *)&sin,&len)) return 0; - return (unsigned int) sin.sin_addr.s_addr; -} - -unsigned int JNL_Connection::get_remote() -{ - return m_saddr->sin_addr.s_addr; -} - -short JNL_Connection::get_remote_port() -{ - return m_remote_port; -} diff --git a/WDL/jnetlib/connection.h b/WDL/jnetlib/connection.h deleted file mode 100644 index 1ae140ac..00000000 --- a/WDL/jnetlib/connection.h +++ /dev/null @@ -1,188 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: connection.h - JNL TCP connection interface -** License: see jnetlib.h -** -** Usage: -** 1. Create a JNL_Connection object, optionally specifying a JNL_IAsyncDNS -** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto), -** and the send and receive buffer sizes. -** 2. Call connect() to have it connect to a host/port (the hostname will be -** resolved if possible). -** 3. call run() with the maximum send/recv amounts, and optionally parameters -** so you can tell how much has been send/received. You want to do this a lot, while: -** 4. check get_state() to check the state of the connection. The states are: -** JNL_Connection::STATE_ERROR -** - an error has occured on the connection. the connection has closed, -** and you can no longer write to the socket (there still might be -** data in the receive buffer - use recv_bytes_available()). -** JNL_Connection::STATE_NOCONNECTION -** - no connection has been made yet. call connect() already! :) -** JNL_Connection::STATE_RESOLVING -** - the connection is still waiting for a JNL_AsycnDNS to resolve the -** host. -** JNL_Connection::STATE_CONNECTING -** - the asynchronous call to connect() is still running. -** JNL_Connection::STATE_CONNECTED -** - the connection has connected, all is well. -** JNL_Connection::STATE_CLOSING -** - the connection is closing. This happens after a call to close, -** without the quick parameter set. This means that the connection -** will close once the data in the send buffer is sent (data could -** still be being received when it would be closed). After it is -** closed, the state will transition to: -** JNL_Connection::STATE_CLOSED -** - the connection has closed, generally without error. There still -** might be data in the receieve buffer, use recv_bytes_available(). -** 5. Use send() and send_string() to send data. You can use -** send_bytes_in_queue() to see how much has yet to go out, or -** send_bytes_available() to see how much you can write. If you use send() -** or send_string() and not enough room is available, both functions will -** return error ( < 0) -** 6. Use recv() and recv_line() to get data. If you want to see how much data -** there is, use recv_bytes_available() and recv_lines_available(). If you -** call recv() and not enough data is available, recv() will return how much -** data was actually read. See comments at the function defs. -** -** 7. To close, call close(1) for a quick close, or close() for a close that will -** make the socket close after sending all the data sent. -** -** 8. delete ye' ol' object. -*/ - -#ifndef _CONNECTION_H_ -#define _CONNECTION_H_ - -#include "asyncdns.h" - -#define JNL_CONNECTION_AUTODNS ((JNL_IAsyncDNS*)-1) - -struct sockaddr_in; - -#ifndef JNL_NO_DEFINE_INTERFACES -class JNL_IConnection -{ - public: - virtual ~JNL_IConnection() { } - virtual void connect(char *hostname, int port)=0; - virtual void connect(int sock, struct sockaddr_in *loc=NULL)=0; // used by the listen object, usually not needed by users. - - virtual void run(int max_send_bytes=-1, int max_recv_bytes=-1, int *bytes_sent=NULL, int *bytes_rcvd=NULL)=0; - virtual int get_state()=0; - virtual const char *get_errstr()=0; - - virtual void close(int quick=0)=0; - virtual void flush_send(void)=0; - - virtual int send_bytes_in_queue(void)=0; - virtual int send_bytes_available(void)=0; - virtual int send(const void *data, int length)=0; // returns -1 if not enough room - virtual int send_bytes(const void *data, int length)=0; - virtual int send_string(const char *line)=0; // returns -1 if not enough room - - virtual int recv_bytes_available(void)=0; - virtual int recv_bytes(void *data, int maxlength)=0; // returns actual bytes read - virtual int recv_lines_available(void)=0; - virtual int recv_line(char *line, int maxlength)=0; // returns 0 if the line was terminated with a \r or \n, 1 if not. - // (i.e. if you specify maxlength=10, and the line is 12 bytes long - // it will return 1. or if there is no \r or \n and that's all the data - // the connection has.) - virtual int peek_bytes(void *data, int maxlength)=0; // returns bytes peeked - - virtual unsigned int get_interface(void)=0; // this returns the interface the connection is on - virtual unsigned int get_remote(void)=0; // remote host ip. - virtual short get_remote_port(void)=0; // this returns the remote port of connection - - virtual void set_interface(int useInterface)=0; // call before connect if needed - }; - - #define JNL_Connection_PARENTDEF : public JNL_IConnection -#else - #define JNL_IConnection JNL_Connection - #define JNL_Connection_PARENTDEF -#endif - -#ifndef JNL_NO_IMPLEMENTATION - -class JNL_Connection JNL_Connection_PARENTDEF -{ - public: - typedef enum - { - STATE_ERROR, - STATE_NOCONNECTION, - STATE_RESOLVING, - STATE_CONNECTING, - STATE_CONNECTED, - STATE_CLOSING, - STATE_CLOSED - } state; - - JNL_Connection(JNL_IAsyncDNS *dns=JNL_CONNECTION_AUTODNS, int sendbufsize=8192, int recvbufsize=8192); - ~JNL_Connection(); - - void connect(char *hostname, int port); - void connect(int sock, struct sockaddr_in *loc=NULL); // used by the listen object, usually not needed by users. - - void run(int max_send_bytes=-1, int max_recv_bytes=-1, int *bytes_sent=NULL, int *bytes_rcvd=NULL); - int get_state() { return m_state; } - const char *get_errstr() { return m_errorstr; } - - void close(int quick=0); - void flush_send(void) { m_send_len=m_send_pos=0; } - - int send_bytes_in_queue(void); - int send_bytes_available(void); - int send(const void *data, int length); // returns -1 if not enough room - inline int send_bytes(const void *data, int length) { return send(data, length); } - int send_string(const char *line); // returns -1 if not enough room - - - int recv_bytes_available(void); - int recv_bytes(void *data, int maxlength); // returns actual bytes read - int recv_lines_available(void); - int recv_line(char *line, int maxlength); // returns 0 if the line was terminated with a \r or \n, 1 if not. - // (i.e. if you specify maxlength=10, and the line is 12 bytes long - // it will return 1. or if there is no \r or \n and that's all the data - // the connection has.) - int peek_bytes(void *data, int maxlength); // returns bytes peeked - - unsigned int get_interface(void); // this returns the interface the connection is on - unsigned int get_remote(void); // remote host ip. - short get_remote_port(void); // this returns the remote port of connection - - void set_interface(int useInterface); // call before connect if needed - - protected: - int m_socket; - short m_remote_port; - char *m_recv_buffer; - char *m_send_buffer; - int m_recv_buffer_len; - int m_send_buffer_len; - - int m_recv_pos; - int m_recv_len; - int m_send_pos; - int m_send_len; - - int m_localinterfacereq; - struct sockaddr_in *m_saddr; - char m_host[256]; - - JNL_IAsyncDNS *m_dns; - int m_dns_owned; - - state m_state; - const char *m_errorstr; - - int getbfromrecv(int pos, int remove); // used by recv_line* - -}; - -#endif - -#endif // _Connection_H_ diff --git a/WDL/jnetlib/httpget.cpp b/WDL/jnetlib/httpget.cpp deleted file mode 100644 index ba0cbaca..00000000 --- a/WDL/jnetlib/httpget.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: httpget.cpp - JNL HTTP GET implementation -** License: see jnetlib.h -*/ - -#include "netinc.h" -#include "util.h" -#include "httpget.h" - - -JNL_HTTPGet::JNL_HTTPGet(JNL_IAsyncDNS *dns, int recvbufsize, char *proxy) -{ - m_recvbufsize=recvbufsize; - m_dns=dns; - m_con=NULL; - m_http_proxylpinfo=0; - m_http_proxyhost=0; - m_http_proxyport=0; - if (proxy && *proxy) - { - char *p=(char*)malloc(strlen(proxy)+1); - if (p) - { - char *r=NULL; - strcpy(p,proxy); - do_parse_url(p,&m_http_proxyhost,&m_http_proxyport,&r,&m_http_proxylpinfo); - free(r); - free(p); - } - } - m_sendheaders=NULL; - reinit(); -} - -void JNL_HTTPGet::reinit() -{ - m_errstr=0; - m_recvheaders=NULL; - m_recvheaders_size=0; - m_http_state=0; - m_http_port=0; - m_http_url=0; - m_reply=0; - m_http_host=m_http_lpinfo=m_http_request=NULL; -} - -void JNL_HTTPGet::deinit() -{ - delete m_con; m_con = NULL; - free(m_recvheaders); - - free(m_http_url); - free(m_http_host); - free(m_http_lpinfo); - free(m_http_request); - free(m_errstr); - free(m_reply); - reinit(); -} - -JNL_HTTPGet::~JNL_HTTPGet() -{ - deinit(); - free(m_sendheaders); - free(m_http_proxylpinfo); - free(m_http_proxyhost); - -} - - -void JNL_HTTPGet::addheader(const char *header) -{ - if (strstr(header,"\r") || strstr(header,"\n")) return; - if (!m_sendheaders) - { - m_sendheaders=(char*)malloc(strlen(header)+3); - if (m_sendheaders) - { - strcpy(m_sendheaders,header); - strcat(m_sendheaders,"\r\n"); - } - } - else - { - char *t=(char*)malloc(strlen(header)+strlen(m_sendheaders)+1+2); - if (t) - { - strcpy(t,m_sendheaders); - strcat(t,header); - strcat(t,"\r\n"); - free(m_sendheaders); - m_sendheaders=t; - } - } -} - -void JNL_HTTPGet::do_encode_mimestr(char *in, char *out) -{ - char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int shift = 0; - int accum = 0; - - while (*in) - { - if (*in) - { - accum <<= 8; - shift += 8; - accum |= *in++; - } - while ( shift >= 6 ) - { - shift -= 6; - *out++ = alphabet[(accum >> shift) & 0x3F]; - } - } - if (shift == 4) - { - *out++ = alphabet[(accum & 0xF)<<2]; - *out++='='; - } - else if (shift == 2) - { - *out++ = alphabet[(accum & 0x3)<<4]; - *out++='='; - *out++='='; - } - - *out++=0; -} - - -void JNL_HTTPGet::connect(const char *url, int ver, const char *requestmethod) -{ - deinit(); - m_http_url=(char*)malloc(strlen(url)+1); - strcpy(m_http_url,url); - do_parse_url(m_http_url,&m_http_host,&m_http_port,&m_http_request, &m_http_lpinfo); - strcpy(m_http_url,url); - if (!m_http_host || !m_http_host[0] || !m_http_port) - { - m_http_state=-1; - seterrstr("invalid URL"); - return; - } - - int sendbufferlen=0; - - if (!m_http_proxyhost || !m_http_proxyhost[0]) - { - sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_request) + 9 /* HTTP/1.0 */ + 2; - } - else - { - sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_url) + 9 /* HTTP/1.0 */ + 2; - if (m_http_proxylpinfo&&m_http_proxylpinfo[0]) - { - sendbufferlen+=58+strlen(m_http_proxylpinfo)*2; // being safe here - } - } - sendbufferlen += 5 /* Host: */ + strlen(m_http_host) + 2; - - if (m_http_lpinfo&&m_http_lpinfo[0]) - { - sendbufferlen+=46+strlen(m_http_lpinfo)*2; // being safe here - } - - if (m_sendheaders) sendbufferlen+=strlen(m_sendheaders); - - char *str=(char*)malloc(sendbufferlen+1024); - if (!str) - { - seterrstr("error allocating memory"); - m_http_state=-1; - } - - if (!m_http_proxyhost || !m_http_proxyhost[0]) - { - wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod,m_http_request,ver%10); - } - else - { - wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod, m_http_url,ver%10); - } - - wsprintf(str+strlen(str),"Host:%s\r\n",m_http_host); - - if (m_http_lpinfo&&m_http_lpinfo[0]) - { - strcat(str,"Authorization: Basic "); - do_encode_mimestr(m_http_lpinfo,str+strlen(str)); - strcat(str,"\r\n"); - } - if (m_http_proxylpinfo&&m_http_proxylpinfo[0]) - { - strcat(str,"Proxy-Authorization: Basic "); - do_encode_mimestr(m_http_proxylpinfo,str+strlen(str)); - strcat(str,"\r\n"); - } - - if (m_sendheaders) strcat(str,m_sendheaders); - strcat(str,"\r\n"); - - int a=m_recvbufsize; - if (a < 4096) a=4096; - m_con=new JNL_Connection(m_dns,strlen(str)+4,a); - if (m_con) - { - if (!m_http_proxyhost || !m_http_proxyhost[0]) - { - m_con->connect(m_http_host,m_http_port); - } - else - { - m_con->connect(m_http_proxyhost,m_http_proxyport); - } - m_con->send_string(str); - } - else - { - m_http_state=-1; - seterrstr("could not create connection object"); - } - free(str); - -} - -void JNL_HTTPGet::do_parse_url(char *url, char **host, int *port, char **req, char **lp) -{ - char *p,*np; - free(*host); *host=0; - free(*req); *req=0; - free(*lp); *lp=0; - - if (strstr(url,"://")) np=p=strstr(url,"://")+3; - else np=p=url; - while (*np != '/' && *np) np++; - if (*np) - { - *req=(char*)malloc(strlen(np)+1); - if (*req) strcpy(*req,np); - *np++=0; - } - else - { - *req=(char*)malloc(2); - if (*req) strcpy(*req,"/"); - } - - np=p; - while (*np != '@' && *np) np++; - if (*np) - { - *np++=0; - *lp=(char*)malloc(strlen(p)+1); - if (*lp) strcpy(*lp,p); - p=np; - } - else - { - *lp=(char*)malloc(1); - if (*lp) strcpy(*lp,""); - } - np=p; - while (*np != ':' && *np) np++; - if (*np) - { - *np++=0; - *port=atoi(np); - } else *port=80; - *host=(char*)malloc(strlen(p)+1); - if (*host) strcpy(*host,p); -} - - -const char *JNL_HTTPGet::getallheaders() -{ // double null terminated, null delimited list - if (m_recvheaders) return m_recvheaders; - else return "\0\0"; -} - -const char *JNL_HTTPGet::getheader(const char *headername) -{ - char *ret=NULL; - if (strlen(headername)<1||!m_recvheaders) return NULL; - char *buf=(char*)malloc(strlen(headername)+2); - strcpy(buf,headername); - if (buf[strlen(buf)-1]!=':') strcat(buf,":"); - char *p=m_recvheaders; - while (*p) - { - if (!strnicmp(buf,p,strlen(buf))) - { - ret=p+strlen(buf); - while (*ret == ' ') ret++; - break; - } - p+=strlen(p)+1; - } - free(buf); - return ret; -} - -int JNL_HTTPGet::run() -{ - int cnt=0; - if (m_http_state==-1||!m_con) return -1; // error - - -run_again: - m_con->run(); - - if (m_con->get_state()==JNL_Connection::STATE_ERROR) - { - seterrstr(m_con->get_errstr()); - return -1; - } - if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1; - - if (m_http_state==0) // connected, waiting for reply - { - if (m_con->recv_lines_available()>0) - { - char buf[4096]; - m_con->recv_line(buf,4095); - buf[4095]=0; - m_reply=(char*)malloc(strlen(buf)+1); - strcpy(m_reply,buf); - - int code=getreplycode(); - if (code == 200 || code==206) m_http_state=2; // proceed to read headers normally - else if (code == 301 || code==302) - { - m_http_state=1; // redirect city - } - else - { - seterrstr(buf); - m_http_state=-1; - return -1; - } - cnt=0; - } - else if (!cnt++) goto run_again; - } - if (m_http_state == 1) // redirect - { - while (m_con->recv_lines_available() > 0) - { - char buf[4096]; - m_con->recv_line(buf,4096); - if (!buf[0]) - { - m_http_state=-1; - return -1; - } - if (!strnicmp(buf,"Location:",9)) - { - const char *p=buf+9; while (*p== ' ') p++; - if (*p) - { - connect(p); - return 0; - } - } - } - } - if (m_http_state==2) - { - if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again; - while (m_con->recv_lines_available() > 0) - { - char buf[4096]; - m_con->recv_line(buf,4096); - if (!buf[0]) { m_http_state=3; break; } - if (!m_recvheaders) - { - m_recvheaders_size=strlen(buf)+1; - m_recvheaders=(char*)malloc(m_recvheaders_size+1); - if (m_recvheaders) - { - strcpy(m_recvheaders,buf); - m_recvheaders[m_recvheaders_size]=0; - } - } - else - { - int oldsize=m_recvheaders_size; - m_recvheaders_size+=strlen(buf)+1; - char *n=(char*)malloc(m_recvheaders_size+1); - if (n) - { - memcpy(n,m_recvheaders,oldsize); - strcpy(n+oldsize,buf); - n[m_recvheaders_size]=0; - free(m_recvheaders); - m_recvheaders=n; - } - } - } - } - if (m_http_state==3) - { - } - return 0; -} - -int JNL_HTTPGet::get_status() // returns 0 if connecting, 1 if reading headers, - // 2 if reading content, -1 if error. -{ - if (m_http_state < 0) return -1; - if (m_http_state < 2) return 0; - if (m_http_state == 2) return 1; - if (m_http_state == 3) return 2; - return -1; -} - -int JNL_HTTPGet::getreplycode()// returns 0 if none yet, otherwise returns http reply code. -{ - if (!m_reply) return 0; - char *p=m_reply; - while (*p && *p != ' ') p++; // skip over HTTP/x.x - if (!*p) return 0; - return atoi(++p); -} - -int JNL_HTTPGet::bytes_available() -{ - if (m_con && m_http_state==3) return m_con->recv_bytes_available(); - return 0; -} -int JNL_HTTPGet::get_bytes(char *buf, int len) -{ - if (m_con && m_http_state==3) return m_con->recv_bytes(buf,len); - return 0; -} -int JNL_HTTPGet::peek_bytes(char *buf, int len) -{ - if (m_con && m_http_state==3) return m_con->peek_bytes(buf,len); - return 0; -} diff --git a/WDL/jnetlib/httpget.h b/WDL/jnetlib/httpget.h deleted file mode 100644 index aebed13c..00000000 --- a/WDL/jnetlib/httpget.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: httpget.h - JNL interface for doing HTTP GETs. -** License: see jnetlib.h -** -** Usage: -** 1. Create a JNL_HTTPGet object, optionally specifying a JNL_AsyncDNS -** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto), -** and the receive buffer size, and a string specifying proxy (or NULL -** for none). See note on proxy string below. -** 2. call addheader() to add whatever headers you want. It is recommended to -** add at least the following two: -** addheader("User-Agent:MyApp (Mozilla)"); -*/// addheader("Accept:*/*"); -/* ( the comment weirdness is there so I Can do the star-slash :) -** 3. Call connect() with the URL you wish to GET (see URL string note below) -** 4. Call run() once in a while, checking to see if it returns -1 -** (if it does return -1, call geterrorstr() to see what the error is). -** (if it returns 1, no big deal, the connection has closed). -** 5. While you're at it, you can call bytes_available() to see if any data -** from the http stream is available, or getheader() to see if any headers -** are available, or getreply() to see the HTTP reply, or getallheaders() -** to get a double null terminated, null delimited list of headers returned. -** 6. If you want to read from the stream, call get_bytes (which returns how much -** was actually read). -** 7. content_length() is a helper function that uses getheader() to check the -** content-length header. -** 8. Delete ye' ol' object when done. -** -** Proxy String: -** should be in the format of host:port, or user@host:port, or -** user:password@host:port. if port is not specified, 80 is assumed. -** URL String: -** should be in the format of http://user:pass@host:port/requestwhatever -** note that user, pass, port, and /requestwhatever are all optional :) -** note that also, http:// is really not important. if you do poo:// -** or even leave out the http:// altogether, it will still work. -*/ - -#ifndef _HTTPGET_H_ -#define _HTTPGET_H_ - -#include "connection.h" - -#ifndef JNL_NO_DEFINE_INTERFACES - class JNL_IHTTPGet - { - public: - - virtual ~JNL_IHTTPGet() { } - - virtual void addheader(const char *header)=0; - - virtual void connect(const char *url, int ver=0, const char *requestmethod="GET")=0; - - virtual int run()=0; // returns: 0 if all is OK. -1 if error (call geterrorstr()). 1 if connection closed. - - virtual int get_status()=0; // returns 0 if connecting, 1 if reading headers, - // 2 if reading content, -1 if error. - - virtual const char *getallheaders()=0; // double null terminated, null delimited list - virtual const char *getheader(const char *headername)=0; - virtual const char *getreply()=0; - virtual int getreplycode()=0; // returns 0 if none yet, otherwise returns http reply code. - - virtual const char *geterrorstr()=0; - - virtual int bytes_available()=0; - virtual int get_bytes(char *buf, int len)=0; - virtual int peek_bytes(char *buf, int len)=0; - - virtual int content_length()=0; - - virtual JNL_IConnection *get_con()=0; - }; - #define JNL_HTTPGet_PARENTDEF : public JNL_IHTTPGet -#else - #define JNL_IHTTPGet JNL_HTTPGet - #define JNL_HTTPGet_PARENTDEF -#endif - -#ifndef JNL_NO_IMPLEMENTATION - -class JNL_HTTPGet JNL_HTTPGet_PARENTDEF -{ - public: - JNL_HTTPGet(JNL_IAsyncDNS *dns=JNL_CONNECTION_AUTODNS, int recvbufsize=16384, char *proxy=NULL); - ~JNL_HTTPGet(); - - void addheader(const char *header); - - void connect(const char *url, int ver=0, const char *requestmethod="GET"); - - int run(); // returns: 0 if all is OK. -1 if error (call geterrorstr()). 1 if connection closed. - - int get_status(); // returns 0 if connecting, 1 if reading headers, - // 2 if reading content, -1 if error. - - const char *getallheaders(); // double null terminated, null delimited list - const char *getheader(const char *headername); - const char *getreply() { return m_reply; } - int getreplycode(); // returns 0 if none yet, otherwise returns http reply code. - - const char *geterrorstr() { return m_errstr;} - - int bytes_available(); - int get_bytes(char *buf, int len); - int peek_bytes(char *buf, int len); - - int content_length() { const char *p=getheader("content-length"); if (p) return atoi(p); return 0; } - - JNL_IConnection *get_con() { return m_con; } - - - - static void do_parse_url(char *url, char **host, int *port, char **req, char **lp); // url gets thrashed, and host/req/lp are freed/allocated - static void do_encode_mimestr(char *in, char *out); - - protected: - void reinit(); - void deinit(); - void seterrstr(const char *str) { if (m_errstr) free(m_errstr); m_errstr=(char*)malloc(strlen(str)+1); strcpy(m_errstr,str); } - - JNL_IAsyncDNS *m_dns; - JNL_IConnection *m_con; - int m_recvbufsize; - - int m_http_state; - - int m_http_port; - char *m_http_url; - char *m_http_host; - char *m_http_lpinfo; - char *m_http_request; - - char *m_http_proxylpinfo; - char *m_http_proxyhost; - int m_http_proxyport; - - char *m_sendheaders; - char *m_recvheaders; - int m_recvheaders_size; - char *m_reply; - - char *m_errstr; -}; -#endif - -#endif // _HTTPGET_H_ diff --git a/WDL/jnetlib/httpserv.cpp b/WDL/jnetlib/httpserv.cpp deleted file mode 100644 index 721bee63..00000000 --- a/WDL/jnetlib/httpserv.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: httpserv.cpp - JNL HTTP GET/POST serving implementation -** License: see jnetlib.h -** -** This class just manages the http reply/sending, not where the data -** comes from, etc. -*/ - -#include "netinc.h" -#include "util.h" - -#include "httpserv.h" - -/* - States for m_state: - -1 error (connection closed, etc) - 0 not read request yet. - 1 reading headers - 2 headers read, have not sent reply - 3 sent reply - 4 closed -*/ - -JNL_HTTPServ::JNL_HTTPServ(JNL_IConnection *con) -{ - m_keepalive=true; - m_con=con; - m_state=0; - m_reply_headers=0; - m_reply_string=0; - m_recvheaders=0; - m_recv_request=0; - m_recvheaders_size=0; - m_errstr=0; - m_reply_ready=0; -} - -JNL_HTTPServ::~JNL_HTTPServ() -{ - free(m_recv_request); - free(m_recvheaders); - free(m_reply_string); - free(m_reply_headers); - free(m_errstr); - delete m_con; -} - -int JNL_HTTPServ::run() -{ // returns: < 0 on error, 0 on connection close, 1 if reading request, 2 if reply not sent, 3 if reply sent, sending data. - int cnt=0; -run_again: - m_con->run(); - if (m_con->get_state()==JNL_Connection::STATE_ERROR) - { - seterrstr(m_con->get_errstr()); - return -1; - } - if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 4; - - if (m_state == 0) - { - if (m_con->recv_lines_available()>0) - { - char *buf=(char*)malloc(m_con->recv_bytes_available()-1); - m_con->recv_line(buf,m_con->recv_bytes_available()-1); - free(m_recv_request); - m_recv_request=(char*)malloc(strlen(buf)+2); - strcpy(m_recv_request,buf); - m_recv_request[strlen(m_recv_request)+1]=0; - free(buf); - buf=m_recv_request; - while (*buf) buf++; - while (buf >= m_recv_request && *buf != ' ') buf--; - if (strncmp(buf+1,"HTTP",4) || strncmp(m_recv_request,"GET ",3)) - { - seterrstr("malformed HTTP request"); - m_state=-1; - } - else - { - if (buf[strlen(buf)-1]=='0') m_keepalive=false; // old http 1.0 - m_state=1; - cnt=0; - if (buf >= m_recv_request) buf[0]=buf[1]=0; - - buf=strstr(m_recv_request,"?"); - if (buf) - { - *buf++=0; // change &'s into 0s now. - char *t=buf; - int stat=1; - while (*t) - { - if (*t == '&' && !stat) { stat=1; *t=0; } - else stat=0; - t++; - } - } - } - } - else if (!cnt++) goto run_again; - } - if (m_state == 1) - { - if (!cnt++ && m_con->recv_lines_available()<1) goto run_again; - while (m_con->recv_lines_available()>0) - { - char buf[4096]; - buf[0]=0; - m_con->recv_line(buf,4096); - if (!buf[0]) { m_state=2; break; } - - if (!strnicmp(buf,"Connection:",11)) - { - const char *p=buf+11; - while (*p && strnicmp(p,"close",5)) p++; - if (*p) m_keepalive=false; - } - - if (!m_recvheaders) - { - m_recvheaders_size=strlen(buf)+1; - m_recvheaders=(char*)malloc(m_recvheaders_size+1); - if (m_recvheaders) - { - strcpy(m_recvheaders,buf); - m_recvheaders[m_recvheaders_size]=0; - } - } - else - { - int oldsize=m_recvheaders_size; - m_recvheaders_size+=strlen(buf)+1; - char *n=(char*)malloc(m_recvheaders_size+1); - if (n) - { - memcpy(n,m_recvheaders,oldsize); - strcpy(n+oldsize,buf); - n[m_recvheaders_size]=0; - free(m_recvheaders); - m_recvheaders=n; - } - } - } - } - if (m_state == 2) - { - if (m_reply_ready) - { - // send reply - m_con->send_string((char*)(m_reply_string?m_reply_string:"HTTP/1.1 200 OK")); - m_con->send_string("\r\n"); - if (m_reply_headers) m_con->send_string(m_reply_headers); - m_con->send_string("\r\n"); - m_state=3; - } - } - if (m_state == 3) - { - // nothing. - } - - return m_state; -} - -const char *JNL_HTTPServ::get_request_file() -{ - // file portion of http request - if (!m_recv_request) return NULL; - char *t=m_recv_request; - while (*t != ' ' && *t) t++; - if (!*t) return NULL; - while (*t == ' ') t++; - return t; -} - -const char *JNL_HTTPServ::get_request_parm(const char *parmname) // parameter portion (after ?) -{ - const char *t=m_recv_request; - while (*t) t++; - t++; - while (*t) - { - while (*t == '&') t++; - if (!strnicmp(t,parmname,strlen(parmname)) && t[strlen(parmname)] == '=') - { - return t+strlen(parmname)+1; - } - t+=strlen(t)+1; - } - return NULL; -} - -const char *JNL_HTTPServ::getheader(const char *headername) -{ - const char *ret=NULL; - if (strlen(headername)<1||!m_recvheaders) return NULL; - char *buf=(char*)malloc(strlen(headername)+2); - strcpy(buf,headername); - if (buf[strlen(buf)-1]!=':') strcat(buf,":"); - const char *p=m_recvheaders; - while (*p) - { - if (!strnicmp(buf,p,strlen(buf))) - { - ret=p+strlen(buf); - while (*ret == ' ') ret++; - break; - } - p+=strlen(p)+1; - } - free(buf); - return ret; -} - -void JNL_HTTPServ::set_reply_string(const char *reply_string) // should be HTTP/1.1 OK or the like -{ - free(m_reply_string); - m_reply_string=(char*)malloc(strlen(reply_string)+1); - strcpy(m_reply_string,reply_string); -} - -void JNL_HTTPServ::set_reply_size(int sz) // if set, size will also add keep-alive etc -{ - if (sz>=0) - { - char buf[512]; - sprintf(buf,"Content-length: %d",sz); - set_reply_header(buf); - if (m_keepalive) set_reply_header("Connection: keep-alive"); - } -} -void JNL_HTTPServ::set_reply_header(const char *header) // "Connection: close" for example -{ - if (m_reply_headers) - { - char *tmp=(char*)malloc(strlen(m_reply_headers)+strlen(header)+3); - strcpy(tmp,m_reply_headers); - strcat(tmp,header); - strcat(tmp,"\r\n"); - free(m_reply_headers); - m_reply_headers=tmp; - } - else - { - m_reply_headers=(char*)malloc(strlen(header)+3); - strcpy(m_reply_headers,header); - strcat(m_reply_headers,"\r\n"); - } -} diff --git a/WDL/jnetlib/httpserv.h b/WDL/jnetlib/httpserv.h deleted file mode 100644 index bd433696..00000000 --- a/WDL/jnetlib/httpserv.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: httpserv.h - JNL interface for doing HTTP GET/POST serving. -** License: see jnetlib.h -** This class just manages the http reply/sending, not where the data -** comes from, etc. -** for a mini-web server see webserver.h -*/ - -#ifndef _HTTPSERV_H_ -#define _HTTPSERV_H_ - -#include "connection.h" - -#ifndef JNL_NO_DEFINE_INTERFACES -class JNL_IHTTPServ -{ - public: - - virtual ~JNL_IHTTPServ() { } - - virtual int run()=0; // returns: < 0 on error, 0 on request not read yet, 1 if reading headers, 2 if reply not sent, 3 if reply sent, sending data. 4 on connection closed. - - virtual const char *geterrorstr()=0; - - // use these when state returned by run() is 2 - virtual const char *get_request_file()=0; // file portion of http request - virtual const char *get_request_parm(const char *parmname)=0; // parameter portion (after ?) - virtual const char *getallheaders()=0; - virtual const char *getheader(const char *headername)=0; - - virtual void set_reply_string(const char *reply_string)=0; // should be HTTP/1.1 OK or the like - virtual void set_reply_header(const char *header)=0; // i.e. "content-size: 12345" - virtual void set_reply_size(int sz)=0; // if set, size will also add keep-alive etc - - virtual void send_reply()=0; - - ////////// sending data /////////////// - virtual int bytes_inqueue()=0; - virtual int bytes_cansend()=0; - virtual void write_bytes(char *bytes, int length)=0; - - virtual void close(int quick)=0; - - virtual JNL_IConnection *get_con()=0; - virtual JNL_IConnection *steal_con()=0; - - virtual bool canKeepAlive()=0; -}; - #define JNL_HTTPServ_PARENTDEF : public JNL_IHTTPServ -#else - #define JNL_IHTTPServ JNL_HTTPServ - #define JNL_HTTPServ_PARENTDEF -#endif - - -#ifndef JNL_NO_IMPLEMENTATION - -class JNL_HTTPServ JNL_HTTPServ_PARENTDEF -{ - public: - JNL_HTTPServ(JNL_IConnection *con); - ~JNL_HTTPServ(); - - int run(); // returns: < 0 on error, 0 on request not read yet, 1 if reading headers, 2 if reply not sent, 3 if reply sent, sending data. 4 on connection closed. - - const char *geterrorstr() { return m_errstr;} - - // use these when state returned by run() is 2 - const char *get_request_file(); // file portion of http request - const char *get_request_parm(const char *parmname); // parameter portion (after ?) - const char *getallheaders() { return m_recvheaders; } // double null terminated, null delimited list - const char *getheader(const char *headername); - - void set_reply_string(const char *reply_string); // should be HTTP/1.1 OK or the like - void set_reply_header(const char *header); // i.e. "content-size: 12345" - void set_reply_size(int sz); // if set, size will also add keep-alive etc - - void send_reply() { m_reply_ready=1; } // send reply, state will advance to 3. - - ////////// sending data /////////////// - int bytes_inqueue() { if (m_state == 3 || m_state == -1 || m_state ==4) return m_con->send_bytes_in_queue(); else return 0; } - int bytes_cansend() { if (m_state == 3) return m_con->send_bytes_available(); else return 0; } - void write_bytes(char *bytes, int length) { m_con->send(bytes,length); } - - void close(int quick) { m_con->close(quick); m_state=4; } - - JNL_IConnection *get_con() { return m_con; } - JNL_IConnection *steal_con() { JNL_IConnection *ret= m_con; m_con=0; return ret; } - - bool canKeepAlive() { return m_keepalive; } - - protected: - void seterrstr(const char *str) { if (m_errstr) free(m_errstr); m_errstr=(char*)malloc(strlen(str)+1); strcpy(m_errstr,str); } - - int m_reply_ready; - int m_state; - bool m_keepalive; - - char *m_errstr; - char *m_reply_headers; - char *m_reply_string; - char *m_recvheaders; - int m_recvheaders_size; - char *m_recv_request; // either double-null terminated, or may contain parameters after first null. - JNL_IConnection *m_con; -}; - -#endif - -#endif // _HTTPSERV_H_ diff --git a/WDL/jnetlib/irc_util.h b/WDL/jnetlib/irc_util.h deleted file mode 100644 index 4b85fc94..00000000 --- a/WDL/jnetlib/irc_util.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _WDL_JNL_IRC_UTIL_H_ -#define _WDL_JNL_IRC_UTIL_H_ - -#include "netinc.h" - -static void FormatIRCMessage(char *bufout, const char *fmt, ...) // bufout should be 1024 bytes to be safe -{ - va_list arglist; - va_start(arglist, fmt); - #ifdef _WIN32 - int written = _vsnprintf(bufout, 1024-16, fmt, arglist); - #else - int written = vsnprintf(bufout, 1024-16, fmt, arglist); - #endif - if (written < 0) written = 0; - else if (written > 510) written=510; - bufout[written]=0; - va_end(arglist); - - strcat(bufout,"\r\n"); -} - - -static void ParseIRCMessage(char *buf, char **prefix, char *tokens[16], int *tokensvalid, bool *lastHadColon) // destroys buf -{ - if (lastHadColon) *lastHadColon=false; - *tokensvalid=0; - if (prefix) *prefix=NULL; - if (*buf==':') - { - if (prefix) *prefix=buf; - while (*buf && *buf != ' ') buf++; - if (*buf==' ') - { - *buf++=0; - while (*buf== ' ') buf++; - } - } - - while (*buf && *tokensvalid < 16) - { - tokens[(*tokensvalid)++] = buf[0] == ':' ? buf+1 : buf; - if (buf[0] == ':' || *tokensvalid == 16) - { - if (buf[0] == ':' && lastHadColon) *lastHadColon=true; - break; - } - - // skip over parameter - while (*buf && *buf != ' ') buf++; - if (*buf == ' ') - { - *buf++=0; - while (*buf== ' ') buf++; - } - - } -} -#endif \ No newline at end of file diff --git a/WDL/jnetlib/jnetlib.h b/WDL/jnetlib/jnetlib.h deleted file mode 100644 index e4c73a08..00000000 --- a/WDL/jnetlib/jnetlib.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2003 Nullsoft, Inc. -** Author: Justin Frankel -** File: jnetlib.h - JNL main include file (not really necessary). -** -** For documentation, look at the following files: -** Generic network initialization: netinc.h -** DNS: asyncdns.h -** TCP connections: connection.h -** HTTP GET connections: httpget.h -** TCP listen: listen.h -** -** license: -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#ifndef _JNETLIB_H_ -#define _JNETLIB_H_ - -#include "netinc.h" -#include "util.h" - -#include "asyncdns.h" -#include "connection.h" -#include "httpget.h" -#include "httpserv.h" -#include "listen.h" - -#endif//_JNETLIB_H_ diff --git a/WDL/jnetlib/listen.cpp b/WDL/jnetlib/listen.cpp deleted file mode 100644 index e7578e19..00000000 --- a/WDL/jnetlib/listen.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: listen.cpp - JNL TCP listen implementation -** License: see jnetlib.h -*/ - -#include "netinc.h" -#include "util.h" -#include "listen.h" - -JNL_Listen::JNL_Listen(short port, unsigned int which_interface) -{ - m_port=port; - m_socket = ::socket(AF_INET,SOCK_STREAM,0); - if (m_socket < 0) - { - } - else - { - struct sockaddr_in sin; - SET_SOCK_BLOCK(m_socket,0); -#ifndef _WIN32 - int bflag = 1; - setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag)); -#endif - memset((char *) &sin, 0,sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons( (short) port ); - sin.sin_addr.s_addr = which_interface?which_interface:INADDR_ANY; - if (::bind(m_socket,(struct sockaddr *)&sin,sizeof(sin))) - { - closesocket(m_socket); - m_socket=-1; - } - else - { - if (::listen(m_socket,8)==-1) - { - closesocket(m_socket); - m_socket=-1; - } - } - } -} - -JNL_Listen::~JNL_Listen() -{ - if (m_socket>=0) - { - closesocket(m_socket); - } -} - -JNL_IConnection *JNL_Listen::get_connect(int sendbufsize, int recvbufsize) -{ - if (m_socket < 0) - { - return NULL; - } - struct sockaddr_in saddr; - socklen_t length = sizeof(struct sockaddr_in); - int s = accept(m_socket, (struct sockaddr *) &saddr, &length); - if (s != -1) - { - JNL_IConnection *c=new JNL_Connection(NULL,sendbufsize, recvbufsize); - c->connect(s,&saddr); - return c; - } - return NULL; -} diff --git a/WDL/jnetlib/listen.h b/WDL/jnetlib/listen.h deleted file mode 100644 index d51edc66..00000000 --- a/WDL/jnetlib/listen.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: listen.h - JNL interface for opening a TCP listen -** License: see jnetlib.h -** -** Usage: -** 1. create a JNL_Listen object with the port and (optionally) the interface -** to listen on. -** 2. call get_connect() to get any new connections (optionally specifying what -** buffer sizes the connection should be created with) -** 3. check is_error() to see if an error has occured -** 4. call port() if you forget what port the listener is on. -** -*/ - -#ifndef _LISTEN_H_ -#define _LISTEN_H_ -#include "connection.h" - -#ifndef JNL_NO_DEFINE_INTERFACES - - class JNL_IListen - { - public: - - virtual ~JNL_IListen() { } - - virtual JNL_IConnection *get_connect(int sendbufsize=8192, int recvbufsize=8192)=0; - virtual short port(void)=0; - virtual int is_error(void)=0; - }; - - #define JNL_Listen_PARENTDEF : public JNL_IListen -#else - #define JNL_IListen JNL_Listen - #define JNL_Listen_PARENTDEF -#endif - -#ifndef JNL_NO_IMPLEMENTATION - - -class JNL_Listen JNL_Listen_PARENTDEF -{ - public: - JNL_Listen(short port, unsigned int which_interface=0); - ~JNL_Listen(); - - JNL_IConnection *get_connect(int sendbufsize=8192, int recvbufsize=8192); - short port(void) { return m_port; } - int is_error(void) { return (m_socket<0); } - - protected: - int m_socket; - short m_port; -}; - -#endif - -#endif //_LISTEN_H_ diff --git a/WDL/jnetlib/netinc.h b/WDL/jnetlib/netinc.h deleted file mode 100644 index 6bb94986..00000000 --- a/WDL/jnetlib/netinc.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: netinc.h - network includes and portability defines (used internally) -** License: see jnetlib.h -*/ - -#ifndef _NETINC_H_ -#define _NETINC_H_ - -#ifdef _WIN32 - -#include -#include -#include -#define strcasecmp(x,y) stricmp(x,y) -#define ERRNO (WSAGetLastError()) -#define SET_SOCK_BLOCK(s,block) { unsigned long __i=block?0:1; ioctlsocket(s,FIONBIO,&__i); } -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EINPROGRESS WSAEWOULDBLOCK -typedef int socklen_t; - -#else - -#ifndef THREAD_SAFE -#define THREAD_SAFE -#endif -#ifndef _REENTRANT -#define _REENTRANT -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ERRNO errno -#define closesocket(s) close(s) -#define SET_SOCK_BLOCK(s,block) { int __flags; if ((__flags = fcntl(s, F_GETFL, 0)) != -1) { if (!block) __flags |= O_NONBLOCK; else __flags &= ~O_NONBLOCK; fcntl(s, F_SETFL, __flags); } } - -#define stricmp(x,y) strcasecmp(x,y) -#define strnicmp(x,y,z) strncasecmp(x,y,z) -#define wsprintf sprintf - -#ifdef MACOSX -typedef int socklen_t; -#endif - -#endif // !_WIN32 - -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif - -#ifndef INADDR_ANY -#define INADDR_ANY 0 -#endif - -#ifndef SHUT_RDWR -#define SHUT_RDWR 2 -#endif - -#endif //_NETINC_H_ diff --git a/WDL/jnetlib/test.cpp b/WDL/jnetlib/test.cpp deleted file mode 100644 index 0d24f78b..00000000 --- a/WDL/jnetlib/test.cpp +++ /dev/null @@ -1,555 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: test.cpp - JNL test code -** License: see jnetlib.h -*/ - -#ifdef _WIN32 -#include -#else -#define Sleep(x) usleep((x)*1000) -#endif -#include -#include "jnetlib.h" - - -#define TEST_ASYNCDNS 0 -#define TEST_CONNECTION 0 -#define TEST_LISTEN 0 -#define TEST_TELNET_GATEWAY 0 -#define TEST_HTTPGET 0 -#define TEST_WEBSERVER 1 - -#define TEST_UDP 0 //udp is not done yet tho :) - - - -#if (TEST_WEBSERVER) -#include "webserver.h" - - -class MemPageGenerator : public IPageGenerator -{ - public: - virtual ~MemPageGenerator() { free(m_buf); } - MemPageGenerator(char *buf, int buf_len=-1) { m_buf=buf; if (buf_len >= 0) m_buf_size=buf_len; else m_buf_size=strlen(buf); m_buf_pos=0; } - virtual int GetData(char *buf, int size) // return 0 when done - { - int a=m_buf_size-m_buf_pos; - if (a < size) size=a; - memcpy(buf,m_buf+m_buf_pos,size); - m_buf_pos+=size; - return size; - } - - private: - char *m_buf; - int m_buf_size; - int m_buf_pos; -}; - -class wwwServer : public WebServerBaseClass -{ -public: - wwwServer() { } - virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port) - { - serv->set_reply_header("Server:jnetlib_test/0.0"); - if (!strcmp(serv->get_request_file(),"/")) - { - serv->set_reply_string("HTTP/1.1 200 OK"); - serv->set_reply_header("Content-Type:text/html"); - serv->send_reply(); - - return new MemPageGenerator(strdup("Test Web Server v0.0")); - } - else - { - serv->set_reply_string("HTTP/1.1 404 NOT FOUND"); - serv->send_reply(); - return 0; // no data - } - } -}; - - -int main(int argc, char **argv) -{ - JNL::open_socketlib(); - { - wwwServer foo; - foo.addListenPort(8080); - while (1) - { - foo.run(); - Sleep(10); - } - } - JNL::close_socketlib(); - return 0; -} - -#endif - - -#if (TEST_HTTPGET) -int main(int argc, char **argv) -{ - - if (argc != 3) - { - printf("usage: httpget \n"); - exit(0); - } - - JNL_HTTPGet get; - JNL::open_socketlib(); - - get.addheader("User-Agent:PooHead (Mozilla)"); - get.addheader("Accept:*/*"); - get.connect(argv[1]); - - FILE *fp=fopen(argv[2],"wb"); - int headerstate=0; - int has_printed_headers=0; - int has_printed_reply=0; - while (1) - { - int st=get.run(); - if (st<0) - { - printf("HTTPGet error: %s\n",get.geterrorstr()); - break; - } - if (get.get_status()>0) - { - if (!has_printed_reply) - { - has_printed_reply=1; - printf("reply: %s (code:%d)\n",get.getreply(),get.getreplycode()); - } - if (get.get_status()==2) - { - int len; - if (!has_printed_headers) - { - has_printed_headers=1; - printf("headers:\n"); - char *p=get.getallheaders(); - while (p&&*p) - { - printf("%s\n",p); - p+=strlen(p)+1; - } - } - while ((len=get.bytes_available()) > 0) - { - char buf[4096]; - if (len > 4096) len=4096; - len=get.get_bytes(buf,len); - if (len>0)fwrite(buf,len,1,fp); - } - } - } - if (st==1) // 1 means connection closed - { - printf("HTTPGet done!\n"); - break; - } - } - if (fp) fclose(fp); - JNL::close_socketlib(); - return 0; -} - -#endif - - -#if (TEST_TELNET_GATEWAY) - -int main() -{ - JNL_Connection *cons[32]={0,}; - JNL_Connection *outcons[32]={0,}; - char textpos[32][256]; - int n_cons=0; - int states[32]={0,}; - - JNL::open_socketlib(); - JNL_AsyncDNS dns; - JNL_Listen l(23); - while (!l.is_error()) - { - Sleep(30); - if (n_cons<32) - { - JNL_Connection *con=l.get_connect(); - if (con) - { - int x; - for (x = 0; x < 32; x ++) - { - if (!cons[x]) - { - cons[x]=con; - outcons[x]=0; - states[x]=0; - n_cons++; - break; - } - } - } - } - int x; - for (x = 0; x < 32; x ++) - { - if (cons[x]) - { - cons[x]->run(); - if (outcons[x]) outcons[x]->run(); - - if (cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED || - (outcons[x] && (cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED))) - { - delete cons[x]; - if (outcons[x]) delete outcons[x]; - outcons[x]=0; - cons[x]=0; - states[x]=0; - n_cons--; - } - else - { - if (states[x]==0) - { - cons[x]->send_string("\r\nwelcome "); - states[x]++; - } - if (states[x]==1) - { - char hoststr[256]; - int ret=dns.reverse(cons[x]->get_remote(),hoststr); - if (ret==0) - { - cons[x]->send_string(hoststr); - cons[x]->send_string(". host: "); - states[x]++; - textpos[x][0]=0; - } - if (ret==-1) - { - JNL::addr_to_ipstr(cons[x]->get_remote(),hoststr,256); - cons[x]->send_string(hoststr); - cons[x]->send_string(". host: "); - states[x]++; - textpos[x][0]=0; - } - } - if (states[x]==2) - { - char b; - while (cons[x]->recv_bytes(&b,1) && states[x]==2) - { - if (b == '\r' || b == '\n') - { - if (strlen(textpos[x])) - { - char *p=strstr(textpos[x],":"); - int port=23; - if (p) - { - *p++=0; - if (atoi(p)) port=atoi(p); - } - outcons[x]=new JNL_Connection(&dns); - outcons[x]->connect(textpos[x],port); - - char str[512]; - sprintf(str,"\r\nconnecting to port %d of %s\r\n",port,textpos[x]); - cons[x]->send_string(str); - states[x]++; - } - else states[x]=0; - } - else if (b == '\b') - { - if (textpos[x][0]) - { - textpos[x][strlen(textpos[x])-1]=0; - cons[x]->send_string("\b \b"); - } - } - else - { - textpos[x][strlen(textpos[x])+1]=0; - textpos[x][strlen(textpos[x])]=b; - cons[x]->send(&b,1); - } - } - } - if (states[x]==3) - { - char buf[1024]; - outcons[x]->run(); - int l=cons[x]->recv_bytes(buf,1024); - if (l) outcons[x]->send(buf,l); - l=outcons[x]->recv_bytes(buf,1024); - if (l) cons[x]->send(buf,l); - } - } - } - } - } - JNL::close_socketlib(); - return 0; -} - - -#endif - -#if (TEST_LISTEN) - -int main() -{ - JNL_HTTPServ *cons[32]={0,}; - char *contents[32]={0,}; - int n_cons=0; - - JNL::open_socketlib(); - JNL_AsyncDNS dns; - JNL_Listen l(8000); - while (!l.is_error()) - { - Sleep(100); - if (n_cons<32) - { - JNL_Connection *con=l.get_connect(); - if (con) - { - int x; - for (x = 0; x < 32; x ++) - { - if (!cons[x]) - { - cons[x]=new JNL_HTTPServ(con); - n_cons++; - break; - } - } - } - } - int x; - for (x = 0; x < 32; x ++) - { - if (cons[x]) - { - int r=cons[x]->run(); - if (r == -1 || r == 4) - { - if (r == -1) printf("error:%s\n",cons[x]->geterrorstr()); - delete cons[x]; - cons[x]=0; - free(contents[x]); - contents[x]=0; - n_cons--; - } - if (r == 2) - { - cons[x]->set_reply_string("HTTP/1.1 200 OK"); - cons[x]->set_reply_header("Content-type:text/plain"); - cons[x]->set_reply_header("Server:JNLTest"); - contents[x]=(char*)malloc(32768); - char *poop=cons[x]->get_request_parm("poop"); - sprintf(contents[x],"test, sucka\r\n%s\r\n\r\n",poop?poop:"no poop"); - cons[x]->send_reply(); - } - if (r == 3) - { - if (contents[x] && cons[x]->bytes_cansend()>strlen(contents[x])) - { - cons[x]->write_bytes(contents[x],strlen(contents[x])); - cons[x]->close(0); - free(contents[x]); - contents[x]=0; - } - } - } - } - } - JNL::close_socketlib(); - return 0; -} - -#endif - -#if (TEST_CONNECTION) -int main() -{ - JNL::open_socketlib(); - { - JNL_AsyncDNS dns; - JNL_Connection con(&dns); - con.connect("localhost",80); - FILE *fp=fopen("c:\\hi.raw","wb"); - while (1) - { - con.run(); - if (con.get_state()==JNL_Connection::STATE_ERROR) - { - printf("error %s\n",con.get_errstr()); - } - if (con.get_state()==JNL_Connection::STATE_CLOSED) - { - } - while (con.recv_bytes_available()>0) - { - char buf[1024]; - int a=con.recv_bytes_available(); - if (a > 1024) a=1024; - con.recv_bytes(buf,a); - fwrite(buf,a,1,fp); - } - } - if (fp) fclose(fp); - } - JNL::close_socketlib(); - return 0; -} -#endif - -#if (TEST_ASYNCDNS) -int main() -{ - JNL_AsyncDNS dns; - char *hosts[]= - { - "www.firehose.net", - "gnutella.com", - "207.48.52.200", - "www.slashdot.org", - "www.google.com", - "www.winamp.com", - "www.genekan.com", - }; - char *reverses[]= - { - "64.0.160.98", - "205.188.245.120", - "207.48.52.222", - "207.48.52.200", - }; - int n=0; - int pass=0; - while (n\n"); - printf("mode: 0 for client, 1 for server\n"); - exit(0); - } - int mode=atoi(argv[1]); - - JNL::open_socketlib(); - - switch(mode) - { - case 0: // client mode - { - JNL_AsyncDNS dns; - JNL_UDPConnection con(0,&dns); // 0 chooses a random port - con.setpeer("localhost",80); - printf("Sending message...\n"); - con.send("blah",5); - while (1) - { - con.run(); - if (con.get_state()==JNL_UDPConnection::STATE_ERROR) - { - printf("error %s\n",con.get_errstr()); - } - while (con.recv_bytes_available()>0) - { - char buf[1024]; - int s=min(con.recv_bytes_available(), sizeof(buf)); - con.recv_bytes(buf,s); - printf("received message: %s\n", buf); - } - } - } - break; - case 1: // server (listening) mode - { - JNL_UDPConnection con(80); - printf("Waiting for messages...\n"); - while(1) - { - con.run(); - if (con.get_state()==JNL_UDPConnection::STATE_ERROR) - { - printf("error %s\n",con.get_errstr()); - } - while (con.recv_bytes_available()>0) - { - char buf[1024]; - int s=min(con.recv_bytes_available(), sizeof(buf)); - con.recv_bytes(buf,s); - printf("message received: %s. Replying...\n", buf); - // reply on the addr:port from sender - struct sockaddr from; - con.get_last_recv_msg_addr(&from); - con.setpeer(&from); - con.send("blorp",6); - } - } - } - break; - } - - JNL::close_socketlib(); - return 0; -} -#endif diff --git a/WDL/jnetlib/test.dsp b/WDL/jnetlib/test.dsp deleted file mode 100644 index 36f90a7c..00000000 --- a/WDL/jnetlib/test.dsp +++ /dev/null @@ -1,166 +0,0 @@ -# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=test - 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 "test.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 "test.mak" CFG="test - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/jnetlib", NTGAAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "test - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "test - Win32 Release" -# Name "test - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\asyncdns.cpp -# End Source File -# Begin Source File - -SOURCE=.\connection.cpp -# End Source File -# Begin Source File - -SOURCE=.\httpget.cpp -# End Source File -# Begin Source File - -SOURCE=.\httpserv.cpp -# End Source File -# Begin Source File - -SOURCE=.\listen.cpp -# End Source File -# Begin Source File - -SOURCE=.\test.cpp -# End Source File -# Begin Source File - -SOURCE=.\util.cpp -# End Source File -# Begin Source File - -SOURCE=.\webserver.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\asyncdns.h -# End Source File -# Begin Source File - -SOURCE=.\connection.h -# End Source File -# Begin Source File - -SOURCE=.\httpget.h -# End Source File -# Begin Source File - -SOURCE=.\httpserv.h -# End Source File -# Begin Source File - -SOURCE=.\jnetlib.h -# End Source File -# Begin Source File - -SOURCE=.\listen.h -# End Source File -# Begin Source File - -SOURCE=.\netinc.h -# End Source File -# Begin Source File - -SOURCE=.\util.h -# End Source File -# Begin Source File - -SOURCE=.\webserver.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/WDL/jnetlib/test.dsw b/WDL/jnetlib/test.dsw deleted file mode 100644 index e25096d1..00000000 --- a/WDL/jnetlib/test.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "test"=.\test.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/WDL/jnetlib/testbnc.cpp b/WDL/jnetlib/testbnc.cpp deleted file mode 100644 index 5c3bca20..00000000 --- a/WDL/jnetlib/testbnc.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: testbnc.cpp - JNL network bounce test code -** License: see jnetlib.h -*/ - -#ifdef _WIN32 -#include -#else -#define Sleep(x) usleep((x)*1000) -#endif -#include -#include "jnetlib.h" - - -int main(int argc, char *argv[]) -{ - JNL_Connection *cons[32]={0,}; - JNL_Connection *outcons[32]={0,}; - int n_cons=0; - - if (argc != 4 || !atoi(argv[1]) || !atoi(argv[3]) || !argv[2][0]) - { - printf("usage: redir localport host remoteport\n"); - exit(1); - } - - JNL::open_socketlib(); - JNL_AsyncDNS dns; - JNL_Listen l((short)atoi(argv[1])); - printf("running...\n"); - while (!l.is_error()) - { - Sleep(10); - if (n_cons<32) - { - JNL_Connection *con=l.get_connect(); - if (con) - { - int x; - for (x = 0; x < 32; x ++) - { - if (!cons[x]) - { - outcons[x]=new JNL_Connection(); - outcons[x]->connect(argv[2],atoi(argv[3])); - cons[x]=con; - char host[256]; - JNL::addr_to_ipstr(cons[x]->get_remote(),host,sizeof(host)); - n_cons++; - printf("Connection %d (%s) opened (%d).\n",x,host,n_cons); - break; - } - } - } - } - int x; - for (x = 0; x < 32; x ++) - { - if (cons[x]) - { - cons[x]->run(); - outcons[x]->run(); - - int cerr=(cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED); - int oerr=(outcons[x]->get_state() == JNL_Connection::STATE_ERROR || outcons[x]->get_state()==JNL_Connection::STATE_CLOSED); - - if ((!outcons[x]->send_bytes_in_queue() && !cons[x]->recv_bytes_available() && cerr) || - (!cons[x]->send_bytes_in_queue() && !outcons[x]->recv_bytes_available() && oerr) || - (cerr && oerr)) - { - char host[256]; - JNL::addr_to_ipstr(cons[x]->get_remote(),host,sizeof(host)); - delete cons[x]; - delete outcons[x]; - outcons[x]=0; - cons[x]=0; - n_cons--; - printf("Connection %d (%s) closed (%d)\n",x,host,n_cons); - } - else - { - char buf[4096]; - int l; - l=outcons[x]->send_bytes_available(); - if (l > 4096) l=4096; - if (l) l=cons[x]->recv_bytes(buf,l); - if (l) outcons[x]->send(buf,l); - - l=cons[x]->send_bytes_available(); - if (l > 4096) l=4096; - if (l) l=outcons[x]->recv_bytes(buf,l); - if (l) cons[x]->send(buf,l); - } - } - } - } - JNL::close_socketlib(); - return 0; -} diff --git a/WDL/jnetlib/util.cpp b/WDL/jnetlib/util.cpp deleted file mode 100644 index c97a2869..00000000 --- a/WDL/jnetlib/util.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: util.cpp - JNL implementation of basic network utilities -** License: see jnetlib.h -*/ - -#include "netinc.h" - -#include "util.h" - -int JNL::open_socketlib() -{ -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return 1; -#endif - return 0; -} -void JNL::close_socketlib() -{ -#ifdef _WIN32 - WSACleanup(); -#endif -} -unsigned int JNL::ipstr_to_addr(const char *cp) -{ - return ::inet_addr(cp); -} - -void JNL::addr_to_ipstr(unsigned int addr, char *host, int maxhostlen) -{ - struct in_addr a; a.s_addr=addr; - char *p=::inet_ntoa(a); strncpy(host,p?p:"",maxhostlen); -} diff --git a/WDL/jnetlib/util.h b/WDL/jnetlib/util.h deleted file mode 100644 index 7179ddc9..00000000 --- a/WDL/jnetlib/util.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2001 Nullsoft, Inc. -** Author: Justin Frankel -** File: util.h - JNL interface for basic network utilities -** License: see jnetlib.h -** -** routines you may be interested in: -** JNL::open_socketlib(); -** opens the socket library. Call this once before using any network -** code. If you create a new thread, call this again. Only really an -** issue for Win32 support, but use it anyway for portability/ -** -** JNL::close_Socketlib(); -** closes the socketlib. Call this when you're done with the network, -** after all your JNetLib objects have been destroyed. -** -** unsigned int JNL::ipstr_to_addr(const char *cp); -** gives you the integer representation of a ip address in dotted -** decimal form. -** -** JNL::addr_to_ipstr(unsigned int addr, char *host, int maxhostlen); -** gives you the dotted decimal notation of an integer ip address. -** -*/ - -#ifndef _UTIL_H_ -#define _UTIL_H_ - -class JNL -{ - public: - static int open_socketlib(); - static void close_socketlib(); - static unsigned int ipstr_to_addr(const char *cp); - static void addr_to_ipstr(unsigned int addr, char *host, int maxhostlen); -}; - -#endif //_UTIL_H_ diff --git a/WDL/jnetlib/webserver.cpp b/WDL/jnetlib/webserver.cpp deleted file mode 100644 index 6037db31..00000000 --- a/WDL/jnetlib/webserver.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2000-2003 Nullsoft, Inc. -** Author: Justin Frankel -** File: webserver.cpp - Generic simple webserver baseclass -** License: see jnetlib.h -** see test.cpp for an example of how to use this class -*/ - -#ifdef _WIN32 -#include -#endif -#include "jnetlib.h" -#include "webserver.h" - -class WS_ItemList -{ - public: - WS_ItemList() { m_size=0; m_list=0; } - ~WS_ItemList() { ::free(m_list); } - - void *Add(void *i); - void *Get(int w); - void Del(int idx); - int GetSize(void) { return m_size; } - protected: - void **m_list; - int m_size; -}; - -class WS_conInst -{ -public: - WS_conInst(JNL_IConnection *c, int which_port); - ~WS_conInst(); - - // these will be used by WebServerBaseClass::onConnection yay - JNL_HTTPServ m_serv; - IPageGenerator *m_pagegen; - - - int m_port; // port this came in on - time_t m_connect_time; -}; - - - -void *WS_ItemList::Add(void *i) -{ - if (!m_list || !(m_size&31)) - { - m_list=(void**)::realloc(m_list,sizeof(void*)*(m_size+32)); - } - m_list[m_size++]=i; - return i; -} -void *WS_ItemList::Get(int w) { if (w >= 0 && w < m_size) return m_list[w]; return NULL; } - -void WS_ItemList::Del(int idx) -{ - if (m_list && idx >= 0 && idx < m_size) - { - m_size--; - if (idx != m_size) ::memcpy(m_list+idx,m_list+idx+1,sizeof(void *)*(m_size-idx)); - if (!(m_size&31)&&m_size) // resize down - { - m_list=(void**)::realloc(m_list,sizeof(void*)*m_size); - } - } -} - - -WS_conInst::WS_conInst(JNL_IConnection *c, int which_port) : m_serv(c), m_port(which_port) -{ - m_pagegen=0; - time(&m_connect_time); -} - -WS_conInst::~WS_conInst() -{ - delete m_pagegen; -} - -WebServerBaseClass::~WebServerBaseClass() -{ - int x; - for (x = 0; x < m_connections->GetSize(); x ++) - { - delete (WS_conInst *)m_connections->Get(x); - } - delete m_connections; - for (x = 0; x < m_listeners->GetSize(); x ++) - { - delete (JNL_Listen *)m_listeners->Get(x); - } - delete m_listeners; -} - -WebServerBaseClass::WebServerBaseClass() -{ - m_connections=new WS_ItemList; - m_listeners=new WS_ItemList; - m_listener_rot=0; - m_timeout_s=30; - m_max_con=100; -} - - -void WebServerBaseClass::setMaxConnections(int max_con) -{ - m_max_con=max_con; -} - -void WebServerBaseClass::setRequestTimeout(int timeout_s) -{ - m_timeout_s=timeout_s; -} - -int WebServerBaseClass::addListenPort(int port, unsigned int which_interface) -{ - removeListenPort(port); - - JNL_Listen *p=new JNL_Listen(port,which_interface); - m_listeners->Add((void *)p); - if (p->is_error()) return -1; - return 0; -} - -void WebServerBaseClass::removeListenPort(int port) -{ - int x; - for (x = 0; x < m_listeners->GetSize(); x ++) - { - JNL_Listen *p=(JNL_Listen *)m_listeners->Get(x); - if (p->port()==port) - { - delete p; - m_listeners->Del(x); - break; - } - } -} - -void WebServerBaseClass::removeListenIdx(int idx) -{ - if (idx >= 0 && idx < m_listeners->GetSize()) - { - JNL_Listen *p=(JNL_Listen *)m_listeners->Get(idx); - delete p; - m_listeners->Del(idx); - } -} - -int WebServerBaseClass::getListenPort(int idx, int *err) -{ - JNL_Listen *p=(JNL_Listen *)m_listeners->Get(idx); - if (p) - { - if (err) *err=p->is_error(); - return p->port(); - } - return 0; -} - -void WebServerBaseClass::attachConnection(JNL_IConnection *con, int port) -{ - m_connections->Add((void*)new WS_conInst(con,port)); -} - -void WebServerBaseClass::run(void) -{ - int nl; - if (m_connections->GetSize() < m_max_con && (nl=m_listeners->GetSize())) - { - JNL_Listen *l=(JNL_Listen *)m_listeners->Get(m_listener_rot++ % nl); - JNL_IConnection *c=l->get_connect(); - if (c) - { -// char buf[512]; -// sprintf(buf,"got new connection at %.3f",GetTickCount()/1000.0); -// OutputDebugString(buf); - attachConnection(c,l->port()); - } - } - int x; - for (x = 0; x < m_connections->GetSize(); x ++) - { - WS_conInst *ci = (WS_conInst *)m_connections->Get(x); - int rv = run_connection(ci); - - if (rv<0) - { - JNL_IConnection *c=ci->m_serv.steal_con(); - if (c) - { - if (c->get_state() == JNL_Connection::STATE_CONNECTED) - attachConnection(c,ci->m_port); - else delete c; - } - } - - if (rv) - { - delete ci; - m_connections->Del(x--); - } - } -} - -int WebServerBaseClass::run_connection(WS_conInst *con) -{ - int s=con->m_serv.run(); - if (s < 0) - { - // m_serv.geterrorstr() - return 1; - } - if (s < 2) - { - // return 1 if we timed out - return time(NULL)-con->m_connect_time > m_timeout_s; - } - if (s < 3) - { - con->m_pagegen=onConnection(&con->m_serv,con->m_port); - return 0; - } - if (s < 4) - { - if (!con->m_pagegen) - { - if (con->m_serv.canKeepAlive()) return -1; - - return !con->m_serv.bytes_inqueue(); - } - char buf[16384]; - int l=con->m_serv.bytes_cansend(); - if (l > 0) - { - if (l > sizeof(buf))l=sizeof(buf); - l=con->m_pagegen->GetData(buf,l); - if (l < (con->m_pagegen->IsNonBlocking() ? 0 : 1)) // if nonblocking, this is l < 0, otherwise it's l<1 - { - if (con->m_serv.canKeepAlive()) return -1; - return !con->m_serv.bytes_inqueue(); - } - if (l>0) - con->m_serv.write_bytes(buf,l); - } - return 0; - } - if (con->m_serv.canKeepAlive()) return -1; - return 1; // we're done by this point -} - - - -void WebServerBaseClass::url_encode(const char *in, char *out, int max_out) -{ - while (*in && max_out > 4) - { - if ((*in >= 'A' && *in <= 'Z')|| - (*in >= 'a' && *in <= 'z')|| - (*in >= '0' && *in <= '9')|| *in == '.' || *in == '_' || *in == '-') - { - *out++=*in++; - max_out--; - } - else - { - int i=*in++; - *out++ = '%'; - int b=(i>>4)&15; - if (b < 10) *out++='0'+b; - else *out++='A'+b-10; - b=i&15; - if (b < 10) *out++='0'+b; - else *out++='A'+b-10; - max_out-=3; - } - } - *out=0; -} - - -void WebServerBaseClass::url_decode(const char *in, char *out, int maxlen) -{ - while (*in && maxlen>1) - { - if (*in == '+') - { - in++; - *out++=' '; - } - else if (*in == '%' && in[1] != '%' && in[1]) - { - int a=0; - int b=0; - for ( b = 0; b < 2; b ++) - { - int r=in[1+b]; - if (r>='0'&&r<='9') r-='0'; - else if (r>='a'&&r<='z') r-='a'-10; - else if (r>='A'&&r<='Z') r-='A'-10; - else break; - a*=16; - a+=r; - } - if (b < 2) *out++=*in++; - else { *out++=a; in += 3;} - } - else *out++=*in++; - maxlen--; - } - *out=0; -} - - - - - -void WebServerBaseClass::base64decode(const char *src, char *dest, int destsize) -{ - int accum=0; - int nbits=0; - while (*src) - { - int x=0; - char c=*src++; - if (c >= 'A' && c <= 'Z') x=c-'A'; - else if (c >= 'a' && c <= 'z') x=c-'a' + 26; - else if (c >= '0' && c <= '9') x=c-'0' + 52; - else if (c == '+') x=62; - else if (c == '/') x=63; - else break; - - accum <<= 6; - accum |= x; - nbits += 6; - - while (nbits >= 8) - { - if (--destsize<=0) break; - nbits-=8; - *dest++ = (char)((accum>>nbits)&0xff); - } - - } - *dest=0; -} - -void WebServerBaseClass::base64encode(const char *in, char *out) -{ - char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int shift = 0; - int accum = 0; - - while (*in) - { - if (*in) - { - accum <<= 8; - shift += 8; - accum |= *in++; - } - while ( shift >= 6 ) - { - shift -= 6; - *out++ = alphabet[(accum >> shift) & 0x3F]; - } - } - if (shift == 4) - { - *out++ = alphabet[(accum & 0xF)<<2]; - *out++='='; - } - else if (shift == 2) - { - *out++ = alphabet[(accum & 0x3)<<4]; - *out++='='; - *out++='='; - } - - *out++=0; -} - -int WebServerBaseClass::parseAuth(const char *auth_header, char *out, int out_len)//returns 0 on unknown auth, 1 on basic -{ - const char *authstr=auth_header; - *out=0; - if (!auth_header || !*auth_header) return 0; - while (*authstr == ' ') authstr++; - if (strnicmp(authstr,"basic ",6)) return 0; - authstr+=6; - while (*authstr == ' ') authstr++; - base64decode(authstr,out,out_len); - return 1; -} diff --git a/WDL/jnetlib/webserver.h b/WDL/jnetlib/webserver.h deleted file mode 100644 index 0701d375..00000000 --- a/WDL/jnetlib/webserver.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -** JNetLib -** Copyright (C) 2008 Cockos Inc -** Copyright (C) 2003 Nullsoft, Inc. -** Author: Justin Frankel -** File: webserver.h - Generic simple webserver baseclass -** License: see jnetlib.h -** -** You can derive your object from WebServerBaseClass to do simple web serving. Example: - - class wwwServer : public WebServerBaseClass - { - public: - wwwServer() { } - virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port) - { - serv->set_reply_header("Server:jnetlib_test/0.0"); - if (!strcmp(serv->get_request_file(),"/")) - { - serv->set_reply_string("HTTP/1.1 200 OK"); - serv->set_reply_header("Content-Type:text/html"); - serv->send_reply(); - - return new MemPageGenerator(strdup("Test Web Server v0.0")); - } - else - { - serv->set_reply_string("HTTP/1.1 404 NOT FOUND"); - serv->send_reply(); - return 0; // no data - } - } - }; - - - wwwServer foo; - foo.addListenPort(8080); - while (1) - { - foo.run(); - Sleep(10); - } - - You will also need to derive from the IPageGenerator interface to provide a data stream, here is an - example of MemPageGenerator: - - class MemPageGenerator : public IPageGenerator - { - public: - virtual ~MemPageGenerator() { free(m_buf); } - MemPageGenerator(char *buf, int buf_len=-1) { m_buf=buf; if (buf_len >= 0) m_buf_size=buf_len; else m_buf_size=strlen(buf); m_buf_pos=0; } - virtual int GetData(char *buf, int size) // return 0 when done - { - int a=m_buf_size-m_buf_pos; - if (a < size) size=a; - memcpy(buf,m_buf+m_buf_pos,size); - m_buf_pos+=size; - return size; - } - - private: - char *m_buf; - int m_buf_size; - int m_buf_pos; - }; - - -** -*/ - - -#ifndef _JNL_WEBSERVER_H_ -#define _JNL_WEBSERVER_H_ - -#include "httpserv.h" -#include "../wdlcstring.h" - -class IPageGenerator -{ -public: - virtual ~IPageGenerator() { }; - virtual int IsNonBlocking() { return 0; } // override this and return 1 if GetData should be allowed to return 0 - virtual int GetData(char *buf, int size)=0; // return < 0 when done (or 0 if IsNonBlocking() is 1) -}; - - - -class WS_ItemList; -class WS_conInst; - -class WebServerBaseClass -{ -protected: // never create one of these directly, always derive - WebServerBaseClass(); - -public: - virtual ~WebServerBaseClass(); - - // stuff for setting limits/timeouts - void setMaxConnections(int max_con); - void setRequestTimeout(int timeout_s); - - // stuff for setting listener port - int addListenPort(int port, unsigned int which_interface=0); - int getListenPort(int idx, int *err=0); - void removeListenPort(int port); - void removeListenIdx(int idx); - - // call this a lot :) - void run(void); - - // if you want to manually attach a connection, use this: - // you need to specify the port it came in on so the web server can build - // links - void attachConnection(JNL_IConnection *con, int port); - - // derived classes need to override this one =) - virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port)=0; - - // stats getting functions - - // these can be used externally, as well as are used by the web server - static void url_encode(const char *in, char *out, int max_out); - static void url_decode(const char *in, char *out, int maxlen); - static void base64decode(const char *src, char *dest, int destsize); - static void base64encode(const char *in, char *out); - - static int parseAuth(const char *auth_header, char *out, int out_len);//returns 0 on unknown auth, 1 on basic - - -private: - int run_connection(WS_conInst *con); - - int m_timeout_s; - int m_max_con; - - JNL_AsyncDNS m_dns; - - WS_ItemList *m_listeners; - int m_listener_rot; - WS_ItemList *m_connections; -}; - - - -#ifdef JNETLIB_WEBSERVER_WANT_UTILS - -#include "../fileread.h" -#include "../wdlstring.h" - -class JNL_FilePageGenerator : public IPageGenerator -{ - public: - JNL_FilePageGenerator(WDL_FileRead *fr) { m_file = fr; } - virtual ~JNL_FilePageGenerator() { delete m_file; } - virtual int GetData(char *buf, int size) { return m_file ? m_file->Read(buf,size) : -1; } - - private: - - WDL_FileRead *m_file; -}; -class JNL_StringPageGenerator : public IPageGenerator -{ - public: - JNL_StringPageGenerator() { m_pos=0; m_len=-1; } - virtual ~JNL_StringPageGenerator() { } - virtual int GetData(char *buf, int size) - { - if (m_len<0) m_len=strlen(str.Get()); - if (size > m_len - m_pos) size=m_len-m_pos; - if (size>0) - { - memcpy(buf,str.Get()+m_pos,size); - m_pos+=size; - } - return size; - } - - WDL_String str; // set this before sending it off - - private: - int m_len; - int m_pos; -}; - -static void JNL_get_mime_type_for_file(const char *fn, char *strout, int stroutsz) -{ - const char *ext = fn; - while (*ext) ext++; - while (ext > fn && *ext != '.' && *ext != '/' && *ext != '\\') ext--; - - const char *type = "application/octet-stream"; - - if (!stricmp(ext,".jpg")) type = "image/jpeg"; - else if (!stricmp(ext,".png")) type = "image/png"; - else if (!stricmp(ext,".gif")) type = "image/gif"; - else if (!stricmp(ext,".html")) type = "text/html"; - else if (!stricmp(ext,".txt")) type = "text/plain"; - else if (!stricmp(ext,".js")) type = "application/x-javascript"; - - lstrcpyn_safe(strout,type,stroutsz); -} - -static void JNL_Format_RFC1123(time_t t, char *buf) -{ - - buf[0]=0; - static const char days[] = { "SunMonTueWedThuFriSat" }; - static const char mons[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" }; - - struct tm *tm = gmtime(&t); - if (!tm) return; - memcpy(buf, days + (tm->tm_wday%7)*3, 3); - strcpy(buf+3,", "); - char *p=buf+5; - strftime(p, 64, "%d xxx %Y %H:%M:%S GMT", tm); - while (*p && *p != 'x') p++; - if (*p) memcpy(p, mons + (tm->tm_mon%12)*3, 3); -} - -#endif //JNETLIB_WEBSERVER_WANT_UTILS - - -#endif//_JNL_WEBSERVER_H_ diff --git a/WDL/jpeglib/README b/WDL/jpeglib/README deleted file mode 100644 index 911d0e84..00000000 --- a/WDL/jpeglib/README +++ /dev/null @@ -1,385 +0,0 @@ -The Independent JPEG Group's JPEG software -========================================== - -README for release 6b of 27-Mar-1998 -==================================== - -This distribution contains the sixth public release of the Independent JPEG -Group's free JPEG software. You are welcome to redistribute this software and -to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. - -Serious users of this software (particularly those incorporating it into -larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to -our electronic mailing list. Mailing list members are notified of updates -and have a chance to participate in technical discussions, etc. - -This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, -Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, -Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG -Group. - -IJG is not affiliated with the official ISO JPEG standards committee. - - -DOCUMENTATION ROADMAP -===================== - -This file contains the following sections: - -OVERVIEW General description of JPEG and the IJG software. -LEGAL ISSUES Copyright, lack of warranty, terms of distribution. -REFERENCES Where to learn more about JPEG. -ARCHIVE LOCATIONS Where to find newer versions of this software. -RELATED SOFTWARE Other stuff you should get. -FILE FORMAT WARS Software *not* to get. -TO DO Plans for future IJG releases. - -Other documentation files in the distribution are: - -User documentation: - install.doc How to configure and install the IJG software. - usage.doc Usage instructions for cjpeg, djpeg, jpegtran, - rdjpgcom, and wrjpgcom. - *.1 Unix-style man pages for programs (same info as usage.doc). - wizard.doc Advanced usage instructions for JPEG wizards only. - change.log Version-to-version change highlights. -Programmer and internal documentation: - libjpeg.doc How to use the JPEG library in your own programs. - example.c Sample code for calling the JPEG library. - structure.doc Overview of the JPEG library's internal structure. - filelist.doc Road map of IJG files. - coderules.doc Coding style rules --- please read if you contribute code. - -Please read at least the files install.doc and usage.doc. Useful information -can also be found in the JPEG FAQ (Frequently Asked Questions) article. See -ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. - -If you want to understand how the JPEG code works, we suggest reading one or -more of the REFERENCES, then looking at the documentation files (in roughly -the order listed) before diving into the code. - - -OVERVIEW -======== - -This package contains C software to implement JPEG image compression and -decompression. JPEG (pronounced "jay-peg") is a standardized compression -method for full-color and gray-scale images. JPEG is intended for compressing -"real-world" scenes; line drawings, cartoons and other non-realistic images -are not its strong suit. JPEG is lossy, meaning that the output image is not -exactly identical to the input image. Hence you must not use JPEG if you -have to have identical output bits. However, on typical photographic images, -very good compression levels can be obtained with no visible change, and -remarkably high compression levels are possible if you can tolerate a -low-quality image. For more details, see the references, or just experiment -with various compression settings. - -This software implements JPEG baseline, extended-sequential, and progressive -compression processes. Provision is made for supporting all variants of these -processes, although some uncommon parameter settings aren't implemented yet. -For legal reasons, we are not distributing code for the arithmetic-coding -variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting -the hierarchical or lossless processes defined in the standard. - -We provide a set of library routines for reading and writing JPEG image files, -plus two sample applications "cjpeg" and "djpeg", which use the library to -perform conversion between JPEG and some other popular image file formats. -The library is intended to be reused in other applications. - -In order to support file conversion and viewing software, we have included -considerable functionality beyond the bare JPEG coding/decoding capability; -for example, the color quantization modules are not strictly part of JPEG -decoding, but they are essential for output to colormapped file formats or -colormapped displays. These extra functions can be compiled out of the -library if not required for a particular application. We have also included -"jpegtran", a utility for lossless transcoding between different JPEG -processes, and "rdjpgcom" and "wrjpgcom", two simple applications for -inserting and extracting textual comments in JFIF files. - -The emphasis in designing this software has been on achieving portability and -flexibility, while also making it fast enough to be useful. In particular, -the software is not intended to be read as a tutorial on JPEG. (See the -REFERENCES section for introductory material.) Rather, it is intended to -be reliable, portable, industrial-strength code. We do not claim to have -achieved that goal in every aspect of the software, but we strive for it. - -We welcome the use of this software as a component of commercial products. -No royalty is required, but we do ask for an acknowledgement in product -documentation, as described under LEGAL ISSUES. - - -LEGAL ISSUES -============ - -In plain English: - -1. We don't promise that this software works. (But if you find any bugs, - please let us know!) -2. You can use this software for whatever you want. You don't have to pay us. -3. You may not pretend that you wrote this software. If you use it in a - program, you must acknowledge somewhere in your documentation that - you've used the IJG code. - -In legalese: - -The authors make NO WARRANTY or representation, either express or implied, -with respect to this software, its quality, accuracy, merchantability, or -fitness for a particular purpose. This software is provided "AS IS", and you, -its user, assume the entire risk as to its quality and accuracy. - -This software is copyright (C) 1991-1998, Thomas G. Lane. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this -software (or portions thereof) for any purpose, without fee, subject to these -conditions: -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice -unaltered; and any additions, deletions, or changes to the original files -must be clearly indicated in accompanying documentation. -(2) If only executable code is distributed, then the accompanying -documentation must state that "this software is based in part on the work of -the Independent JPEG Group". -(3) Permission for use of this software is granted only if the user accepts -full responsibility for any undesirable consequences; the authors accept -NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, -not just to the unmodified library. If you use our work, you ought to -acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name -in advertising or publicity relating to this software or products derived from -it. This software may be referred to only as "the Independent JPEG Group's -software". - -We specifically permit and encourage the use of this software as the basis of -commercial products, provided that all warranty or liability claims are -assumed by the product vendor. - - -ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, -sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. -ansi2knr.c is NOT covered by the above copyright and conditions, but instead -by the usual distribution terms of the Free Software Foundation; principally, -that you must include source code if you redistribute it. (See the file -ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part -of any program generated from the IJG code, this does not limit you more than -the foregoing paragraphs do. - -The Unix configuration script "configure" was produced with GNU Autoconf. -It is copyright by the Free Software Foundation but is freely distributable. -The same holds for its supporting scripts (config.guess, config.sub, -ltconfig, ltmain.sh). Another support script, install-sh, is copyright -by M.I.T. but is also freely distributable. - -It appears that the arithmetic coding option of the JPEG spec is covered by -patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot -legally be used without obtaining one or more licenses. For this reason, -support for arithmetic coding has been removed from the free JPEG software. -(Since arithmetic coding provides only a marginal gain over the unpatented -Huffman mode, it is unlikely that very many implementations will support it.) -So far as we are aware, there are no patent restrictions on the remaining -code. - -The IJG distribution formerly included code to read and write GIF files. -To avoid entanglement with the Unisys LZW patent, GIF reading support has -been removed altogether, and the GIF writer has been simplified to produce -"uncompressed GIFs". This technique does not use the LZW algorithm; the -resulting GIF files are larger than usual, but are readable by all standard -GIF decoders. - -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." - - -REFERENCES -========== - -We highly recommend reading one or more of these references before trying to -understand the innards of the JPEG software. - -The best short technical introduction to the JPEG compression algorithm is - Wallace, Gregory K. "The JPEG Still Picture Compression Standard", - Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. -(Adjacent articles in that issue discuss MPEG motion picture compression, -applications of JPEG, and related topics.) If you don't have the CACM issue -handy, a PostScript file containing a revised version of Wallace's article is -available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually -a preprint for an article that appeared in IEEE Trans. Consumer Electronics) -omits the sample images that appeared in CACM, but it includes corrections -and some added material. Note: the Wallace article is copyright ACM and IEEE, -and it may not be used for commercial purposes. - -A somewhat less technical, more leisurely introduction to JPEG can be found in -"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by -M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides -good explanations and example C code for a multitude of compression methods -including JPEG. It is an excellent source if you are comfortable reading C -code but don't know much about data compression in general. The book's JPEG -sample code is far from industrial-strength, but when you are ready to look -at a full implementation, you've got one here... - -The best full description of JPEG is the textbook "JPEG Still Image Data -Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published -by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. -The book includes the complete text of the ISO JPEG standards (DIS 10918-1 -and draft DIS 10918-2). This is by far the most complete exposition of JPEG -in existence, and we highly recommend it. - -The JPEG standard itself is not available electronically; you must order a -paper copy through ISO or ITU. (Unless you feel a need to own a certified -official copy, we recommend buying the Pennebaker and Mitchell book instead; -it's much cheaper and includes a great deal of useful explanatory material.) -In the USA, copies of the standard may be ordered from ANSI Sales at (212) -642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI -doesn't take credit card orders, but Global does.) It's not cheap: as of -1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% -shipping/handling. The standard is divided into two parts, Part 1 being the -actual specification, while Part 2 covers compliance testing methods. Part 1 -is titled "Digital Compression and Coding of Continuous-tone Still Images, -Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS -10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of -Continuous-tone Still Images, Part 2: Compliance testing" and has document -numbers ISO/IEC IS 10918-2, ITU-T T.83. - -Some extensions to the original JPEG standard are defined in JPEG Part 3, -a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG -currently does not support any Part 3 extensions. - -The JPEG standard does not specify all details of an interchangeable file -format. For the omitted details we follow the "JFIF" conventions, revision -1.02. A copy of the JFIF spec is available from: - Literature Department - C-Cube Microsystems, Inc. - 1778 McCarthy Blvd. - Milpitas, CA 95035 - phone (408) 944-6300, fax (408) 944-6314 -A PostScript version of this document is available by FTP at -ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text -version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing -the figures. - -The TIFF 6.0 file format specification can be obtained by FTP from -ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme -found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. -IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). -Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 -(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or -from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision -of the TIFF spec will replace the 6.0 JPEG design with the Note's design. -Although IJG's own code does not support TIFF/JPEG, the free libtiff library -uses our library to implement TIFF/JPEG per the Note. libtiff is available -from ftp://ftp.sgi.com/graphics/tiff/. - - -ARCHIVE LOCATIONS -================= - -The "official" archive site for this software is ftp.uu.net (Internet -address 192.48.96.9). The most recent released version can always be found -there in directory graphics/jpeg. This particular version will be archived -as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have -direct Internet access, UUNET's archives are also available via UUCP; contact -help@uunet.uu.net for information on retrieving files that way. - -Numerous Internet sites maintain copies of the UUNET files. However, only -ftp.uu.net is guaranteed to have the latest official version. - -You can also obtain this software in DOS-compatible "zip" archive format from -the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or -on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 -"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net -release. - -The JPEG FAQ (Frequently Asked Questions) article is a useful source of -general information about JPEG. It is updated constantly and therefore is -not included in this distribution. The FAQ is posted every two weeks to -Usenet newsgroups comp.graphics.misc, news.answers, and other groups. -It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ -and other news.answers archive sites, including the official news.answers -archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. -If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu -with body - send usenet/news.answers/jpeg-faq/part1 - send usenet/news.answers/jpeg-faq/part2 - - -RELATED SOFTWARE -================ - -Numerous viewing and image manipulation programs now support JPEG. (Quite a -few of them use this library to do so.) The JPEG FAQ described above lists -some of the more popular free and shareware viewers, and tells where to -obtain them on Internet. - -If you are on a Unix machine, we highly recommend Jef Poskanzer's free -PBMPLUS software, which provides many useful operations on PPM-format image -files. In particular, it can convert PPM images to and from a wide range of -other formats, thus making cjpeg/djpeg considerably more useful. The latest -version is distributed by the NetPBM group, and is available from numerous -sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. -Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; -you are likely to have difficulty making it work on any non-Unix machine. - -A different free JPEG implementation, written by the PVRG group at Stanford, -is available from ftp://havefun.stanford.edu/pub/jpeg/. This program -is designed for research and experimentation rather than production use; -it is slower, harder to use, and less portable than the IJG code, but it -is easier to read and modify. Also, the PVRG code supports lossless JPEG, -which we do not. (On the other hand, it doesn't do progressive JPEG.) - - -FILE FORMAT WARS -================ - -Some JPEG programs produce files that are not compatible with our library. -The root of the problem is that the ISO JPEG committee failed to specify a -concrete file format. Some vendors "filled in the blanks" on their own, -creating proprietary formats that no one else could read. (For example, none -of the early commercial JPEG implementations for the Macintosh were able to -exchange compressed files.) - -The file format we have adopted is called JFIF (see REFERENCES). This format -has been agreed to by a number of major commercial JPEG vendors, and it has -become the de facto standard. JFIF is a minimal or "low end" representation. -We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF -Technical Note #2) for "high end" applications that need to record a lot of -additional data about an image. TIFF/JPEG is fairly new and not yet widely -supported, unfortunately. - -The upcoming JPEG Part 3 standard defines a file format called SPIFF. -SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should -be able to read the most common variant of SPIFF. SPIFF has some technical -advantages over JFIF, but its major claim to fame is simply that it is an -official standard rather than an informal one. At this point it is unclear -whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto -standard. IJG intends to support SPIFF once the standard is frozen, but we -have not decided whether it should become our default output format or not. -(In any case, our decoder will remain capable of reading JFIF indefinitely.) - -Various proprietary file formats incorporating JPEG compression also exist. -We have little or no sympathy for the existence of these formats. Indeed, -one of the original reasons for developing this free software was to help -force convergence on common, open format standards for JPEG files. Don't -use a proprietary file format! - - -TO DO -===== - -The major thrust for v7 will probably be improvement of visual quality. -The current method for scaling the quantization tables is known not to be -very good at low Q values. We also intend to investigate block boundary -smoothing, "poor man's variable quantization", and other means of improving -quality-vs-file-size performance without sacrificing compatibility. - -In future versions, we are considering supporting some of the upcoming JPEG -Part 3 extensions --- principally, variable quantization and the SPIFF file -format. - -As always, speeding things up is of great interest. - -Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/WDL/jpeglib/example.c b/WDL/jpeglib/example.c deleted file mode 100644 index 9dcbd7d9..00000000 --- a/WDL/jpeglib/example.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * 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/WDL/jpeglib/jcapimin.c b/WDL/jpeglib/jcapimin.c deleted file mode 100644 index 493af5c3..00000000 --- a/WDL/jpeglib/jcapimin.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * 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/WDL/jpeglib/jcapistd.c b/WDL/jpeglib/jcapistd.c deleted file mode 100644 index fed66caf..00000000 --- a/WDL/jpeglib/jcapistd.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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/WDL/jpeglib/jccoefct.c b/WDL/jpeglib/jccoefct.c deleted file mode 100644 index c713b858..00000000 --- a/WDL/jpeglib/jccoefct.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * 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/WDL/jpeglib/jccolor.c b/WDL/jpeglib/jccolor.c deleted file mode 100644 index 26637245..00000000 --- a/WDL/jpeglib/jccolor.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * 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/WDL/jpeglib/jcdctmgr.c b/WDL/jpeglib/jcdctmgr.c deleted file mode 100644 index e3f90dc3..00000000 --- a/WDL/jpeglib/jcdctmgr.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * 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/WDL/jpeglib/jchuff.c b/WDL/jpeglib/jchuff.c deleted file mode 100644 index 16d9366a..00000000 --- a/WDL/jpeglib/jchuff.c +++ /dev/null @@ -1,909 +0,0 @@ -/* - * 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/WDL/jpeglib/jchuff.h b/WDL/jpeglib/jchuff.h deleted file mode 100644 index 8c02c09a..00000000 --- a/WDL/jpeglib/jchuff.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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/WDL/jpeglib/jcinit.c b/WDL/jpeglib/jcinit.c deleted file mode 100644 index 19de8d0e..00000000 --- a/WDL/jpeglib/jcinit.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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/WDL/jpeglib/jcmainct.c b/WDL/jpeglib/jcmainct.c deleted file mode 100644 index 14aa4c75..00000000 --- a/WDL/jpeglib/jcmainct.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * 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/WDL/jpeglib/jcmarker.c b/WDL/jpeglib/jcmarker.c deleted file mode 100644 index 0d3ca5e5..00000000 --- a/WDL/jpeglib/jcmarker.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * 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/WDL/jpeglib/jcmaster.c b/WDL/jpeglib/jcmaster.c deleted file mode 100644 index e61138b1..00000000 --- a/WDL/jpeglib/jcmaster.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * 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/WDL/jpeglib/jcomapi.c b/WDL/jpeglib/jcomapi.c deleted file mode 100644 index 1b1a340c..00000000 --- a/WDL/jpeglib/jcomapi.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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/WDL/jpeglib/jconfig.h b/WDL/jpeglib/jconfig.h deleted file mode 100644 index 4d40a57d..00000000 --- a/WDL/jpeglib/jconfig.h +++ /dev/null @@ -1,15 +0,0 @@ -#define HAVE_PROTOTYPES -#define HAVE_STDLIB_H -#define HAVE_UNSIGNED_SHORT -#define HAVE_UNSIGNED_CHAR -#ifndef _WIN32 -#define NEED_SYS_TYPES_H -#define HAVE_STDDEF_H -#else -#include -#define XMD_H -#undef FAR -#define HAVE_BOOLEAN -typedef short INT16; -#endif - diff --git a/WDL/jpeglib/jcparam.c b/WDL/jpeglib/jcparam.c deleted file mode 100644 index bbd175c8..00000000 --- a/WDL/jpeglib/jcparam.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * 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/WDL/jpeglib/jcphuff.c b/WDL/jpeglib/jcphuff.c deleted file mode 100644 index a4ee850e..00000000 --- a/WDL/jpeglib/jcphuff.c +++ /dev/null @@ -1,833 +0,0 @@ -/* - * 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/WDL/jpeglib/jcprepct.c b/WDL/jpeglib/jcprepct.c deleted file mode 100644 index fdc4bc2d..00000000 --- a/WDL/jpeglib/jcprepct.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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/WDL/jpeglib/jcsample.c b/WDL/jpeglib/jcsample.c deleted file mode 100644 index fe29fcab..00000000 --- a/WDL/jpeglib/jcsample.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * 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/WDL/jpeglib/jctrans.c b/WDL/jpeglib/jctrans.c deleted file mode 100644 index 8b36e363..00000000 --- a/WDL/jpeglib/jctrans.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * 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/WDL/jpeglib/jdapimin.c b/WDL/jpeglib/jdapimin.c deleted file mode 100644 index bd1df927..00000000 --- a/WDL/jpeglib/jdapimin.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * 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" - - -/* - * 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; - - /* 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; -} diff --git a/WDL/jpeglib/jdapistd.c b/WDL/jpeglib/jdapistd.c deleted file mode 100644 index f6c7fffe..00000000 --- a/WDL/jpeglib/jdapistd.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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/WDL/jpeglib/jdatadst.c b/WDL/jpeglib/jdatadst.c deleted file mode 100644 index 2ece4e95..00000000 --- a/WDL/jpeglib/jdatadst.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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/WDL/jpeglib/jdatasrc.c b/WDL/jpeglib/jdatasrc.c deleted file mode 100644 index 29b69832..00000000 --- a/WDL/jpeglib/jdatasrc.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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/WDL/jpeglib/jdcoefct.c b/WDL/jpeglib/jdcoefct.c deleted file mode 100644 index 992bd105..00000000 --- a/WDL/jpeglib/jdcoefct.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - * 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/WDL/jpeglib/jdcolor.c b/WDL/jpeglib/jdcolor.c deleted file mode 100644 index fd7b1388..00000000 --- a/WDL/jpeglib/jdcolor.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * 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/WDL/jpeglib/jdct.h b/WDL/jpeglib/jdct.h deleted file mode 100644 index b664cab0..00000000 --- a/WDL/jpeglib/jdct.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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/WDL/jpeglib/jddctmgr.c b/WDL/jpeglib/jddctmgr.c deleted file mode 100644 index 0e44eb14..00000000 --- a/WDL/jpeglib/jddctmgr.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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 */ - - -/* - * 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 - - -/* - * 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: - method_ptr = jpeg_idct_islow; - method = JDCT_ISLOW; - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - method_ptr = jpeg_idct_ifast; - method = JDCT_IFAST; - 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/WDL/jpeglib/jdhuff.c b/WDL/jpeglib/jdhuff.c deleted file mode 100644 index b2ad66d4..00000000 --- a/WDL/jpeglib/jdhuff.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * 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/WDL/jpeglib/jdhuff.h b/WDL/jpeglib/jdhuff.h deleted file mode 100644 index 12c07477..00000000 --- a/WDL/jpeglib/jdhuff.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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/WDL/jpeglib/jdinput.c b/WDL/jpeglib/jdinput.c deleted file mode 100644 index 2d5c7470..00000000 --- a/WDL/jpeglib/jdinput.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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/WDL/jpeglib/jdmainct.c b/WDL/jpeglib/jdmainct.c deleted file mode 100644 index 6b0f06f5..00000000 --- a/WDL/jpeglib/jdmainct.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * 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/WDL/jpeglib/jdmarker.c b/WDL/jpeglib/jdmarker.c deleted file mode 100644 index 9811761d..00000000 --- a/WDL/jpeglib/jdmarker.c +++ /dev/null @@ -1,1360 +0,0 @@ -/* - * 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/WDL/jpeglib/jdmaster.c b/WDL/jpeglib/jdmaster.c deleted file mode 100644 index eda4b3fa..00000000 --- a/WDL/jpeglib/jdmaster.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * 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/WDL/jpeglib/jdmerge.c b/WDL/jpeglib/jdmerge.c deleted file mode 100644 index 9e3a595d..00000000 --- a/WDL/jpeglib/jdmerge.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * 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 - - -/* 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. - */ - -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]; - } -} - - -/* - * 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/WDL/jpeglib/jdphuff.c b/WDL/jpeglib/jdphuff.c deleted file mode 100644 index 24047432..00000000 --- a/WDL/jpeglib/jdphuff.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * 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/WDL/jpeglib/jdpostct.c b/WDL/jpeglib/jdpostct.c deleted file mode 100644 index 7ba9eed5..00000000 --- a/WDL/jpeglib/jdpostct.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 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/WDL/jpeglib/jdsample.c b/WDL/jpeglib/jdsample.c deleted file mode 100644 index e0d9040a..00000000 --- a/WDL/jpeglib/jdsample.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * 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/WDL/jpeglib/jdtrans.c b/WDL/jpeglib/jdtrans.c deleted file mode 100644 index 12c193c8..00000000 --- a/WDL/jpeglib/jdtrans.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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/WDL/jpeglib/jerror.c b/WDL/jpeglib/jerror.c deleted file mode 100644 index c98aed76..00000000 --- a/WDL/jpeglib/jerror.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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" - -#ifdef USE_WINDOWS_MESSAGEBOX -#include -#endif - -#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/WDL/jpeglib/jerror.h b/WDL/jpeglib/jerror.h deleted file mode 100644 index 79084f2e..00000000 --- a/WDL/jpeglib/jerror.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * jerror.h - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the error and message codes for the JPEG library. - * Edit this file to add new codes, or to translate the message strings to - * some other language. - * A set of error-reporting macros are defined too. Some applications using - * the JPEG library may wish to include this file to get the error codes - * and/or the macros. - */ - -/* - * To define the enum list of message codes, include this file without - * defining macro JMESSAGE. To create a message string table, include it - * again with a suitable JMESSAGE definition (see jerror.c for an example). - */ -#ifndef JMESSAGE -#ifndef JERROR_H -/* First time through, define the enum list */ -#define JMAKE_ENUM_LIST -#else -/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ -#define JMESSAGE(code,string) -#endif /* JERROR_H */ -#endif /* JMESSAGE */ - -#ifdef JMAKE_ENUM_LIST - -typedef enum { - -#define JMESSAGE(code,string) code , - -#endif /* JMAKE_ENUM_LIST */ - -JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ - -/* For maintenance convenience, list is alphabetical by message code name */ -JMESSAGE(JERR_ARITH_NOTIMPL, - "Sorry, there are legal restrictions on arithmetic coding") -JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") -JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") -JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") -JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") -JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") -JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") -JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") -JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") -JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") -JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") -JMESSAGE(JERR_BAD_LIB_VERSION, - "Wrong JPEG library version: library is %d, caller expects %d") -JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") -JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") -JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") -JMESSAGE(JERR_BAD_PROGRESSION, - "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") -JMESSAGE(JERR_BAD_PROG_SCRIPT, - "Invalid progressive parameters at scan script entry %d") -JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") -JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") -JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") -JMESSAGE(JERR_BAD_STRUCT_SIZE, - "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") -JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") -JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") -JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") -JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") -JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") -JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") -JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") -JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") -JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") -JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") -JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") -JMESSAGE(JERR_EMS_READ, "Read from EMS failed") -JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") -JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") -JMESSAGE(JERR_FILE_READ, "Input file read error") -JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") -JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") -JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") -JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") -JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") -JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") -JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") -JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, - "Cannot transcode due to multiple use of quantization table %d") -JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") -JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") -JMESSAGE(JERR_NOTIMPL, "Not implemented yet") -JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") -JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") -JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") -JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") -JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") -JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") -JMESSAGE(JERR_QUANT_COMPONENTS, - "Cannot quantize more than %d color components") -JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") -JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") -JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") -JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") -JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") -JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") -JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") -JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") -JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") -JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") -JMESSAGE(JERR_TFILE_WRITE, - "Write failed on temporary file --- out of disk space?") -JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") -JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") -JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") -JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") -JMESSAGE(JERR_XMS_READ, "Read from XMS failed") -JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") -JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) -JMESSAGE(JMSG_VERSION, JVERSION) -JMESSAGE(JTRC_16BIT_TABLES, - "Caution: quantization tables are too coarse for baseline JPEG") -JMESSAGE(JTRC_ADOBE, - "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") -JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") -JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") -JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") -JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") -JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") -JMESSAGE(JTRC_DRI, "Define Restart Interval %u") -JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") -JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") -JMESSAGE(JTRC_EOI, "End Of Image") -JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") -JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") -JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, - "Warning: thumbnail image size does not match data length %u") -JMESSAGE(JTRC_JFIF_EXTENSION, - "JFIF extension marker: type 0x%02x, length %u") -JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") -JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") -JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") -JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") -JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") -JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") -JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") -JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") -JMESSAGE(JTRC_RST, "RST%d") -JMESSAGE(JTRC_SMOOTH_NOTIMPL, - "Smoothing not supported with nonstandard sampling ratios") -JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") -JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") -JMESSAGE(JTRC_SOI, "Start of Image") -JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") -JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") -JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") -JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") -JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") -JMESSAGE(JTRC_THUMB_JPEG, - "JFIF extension marker: JPEG-compressed thumbnail image, length %u") -JMESSAGE(JTRC_THUMB_PALETTE, - "JFIF extension marker: palette thumbnail image, length %u") -JMESSAGE(JTRC_THUMB_RGB, - "JFIF extension marker: RGB thumbnail image, length %u") -JMESSAGE(JTRC_UNKNOWN_IDS, - "Unrecognized component IDs %d %d %d, assuming YCbCr") -JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") -JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") -JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") -JMESSAGE(JWRN_BOGUS_PROGRESSION, - "Inconsistent progression sequence for component %d coefficient %d") -JMESSAGE(JWRN_EXTRANEOUS_DATA, - "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") -JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") -JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") -JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") -JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") -JMESSAGE(JWRN_MUST_RESYNC, - "Corrupt JPEG data: found marker 0x%02x instead of RST%d") -JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") -JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") - -#ifdef JMAKE_ENUM_LIST - - JMSG_LASTMSGCODE -} J_MESSAGE_CODE; - -#undef JMAKE_ENUM_LIST -#endif /* JMAKE_ENUM_LIST */ - -/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ -#undef JMESSAGE - - -#ifndef JERROR_H -#define JERROR_H - -/* Macros to simplify using the error and trace message stuff */ -/* The first parameter is either type of cinfo pointer */ - -/* Fatal errors (print message and exit) */ -#define ERREXIT(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT3(cinfo,code,p1,p2,p3) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (cinfo)->err->msg_parm.i[3] = (p4), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXITS(cinfo,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) - -#define MAKESTMT(stuff) do { stuff } while (0) - -/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ -#define WARNMS(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) - -/* Informational/debugging messages */ -#define TRACEMS(cinfo,lvl,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS1(cinfo,lvl,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS2(cinfo,lvl,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMSS(cinfo,lvl,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) - -#endif /* JERROR_H */ diff --git a/WDL/jpeglib/jfdctflt.c b/WDL/jpeglib/jfdctflt.c deleted file mode 100644 index 7ccfb380..00000000 --- a/WDL/jpeglib/jfdctflt.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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/WDL/jpeglib/jfdctfst.c b/WDL/jpeglib/jfdctfst.c deleted file mode 100644 index 005a74fe..00000000 --- a/WDL/jpeglib/jfdctfst.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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/WDL/jpeglib/jfdctint.c b/WDL/jpeglib/jfdctint.c deleted file mode 100644 index d6269274..00000000 --- a/WDL/jpeglib/jfdctint.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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/WDL/jpeglib/jidctflt.c b/WDL/jpeglib/jidctflt.c deleted file mode 100644 index 5fea54c2..00000000 --- a/WDL/jpeglib/jidctflt.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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/WDL/jpeglib/jidctfst.c b/WDL/jpeglib/jidctfst.c deleted file mode 100644 index 078b8c44..00000000 --- a/WDL/jpeglib/jidctfst.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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 - - -/* - * 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 /* DCT_IFAST_SUPPORTED */ diff --git a/WDL/jpeglib/jidctint.c b/WDL/jpeglib/jidctint.c deleted file mode 100644 index 4f47fe83..00000000 --- a/WDL/jpeglib/jidctint.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * 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 */ - } -} - -#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/WDL/jpeglib/jidctred.c b/WDL/jpeglib/jidctred.c deleted file mode 100644 index 911899b8..00000000 --- a/WDL/jpeglib/jidctred.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * 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/WDL/jpeglib/jinclude.h b/WDL/jpeglib/jinclude.h deleted file mode 100644 index 5ff60fed..00000000 --- a/WDL/jpeglib/jinclude.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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/WDL/jpeglib/jmemmgr.c b/WDL/jpeglib/jmemmgr.c deleted file mode 100644 index b636f1be..00000000 --- a/WDL/jpeglib/jmemmgr.c +++ /dev/null @@ -1,1118 +0,0 @@ -/* - * 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/WDL/jpeglib/jmemnobs.c b/WDL/jpeglib/jmemnobs.c deleted file mode 100644 index 6aa1e929..00000000 --- a/WDL/jpeglib/jmemnobs.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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/WDL/jpeglib/jmemsys.h b/WDL/jpeglib/jmemsys.h deleted file mode 100644 index 2a879611..00000000 --- a/WDL/jpeglib/jmemsys.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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/WDL/jpeglib/jmorecfg.h b/WDL/jpeglib/jmorecfg.h deleted file mode 100644 index c856e226..00000000 --- a/WDL/jpeglib/jmorecfg.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * jmorecfg.h - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains additional configuration options that customize the - * JPEG software for special applications or support machine-dependent - * optimizations. Most users will not need to touch this file. - */ - - -/* - * Define BITS_IN_JSAMPLE as either - * 8 for 8-bit sample values (the usual setting) - * 12 for 12-bit sample values - * Only 8 and 12 are legal data precisions for lossy JPEG according to the - * JPEG standard, and the IJG code does not support anything else! - * We do not support run-time selection of data precision, sorry. - */ - -#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ - - -/* - * Maximum number of components (color channels) allowed in JPEG image. - * To meet the letter of the JPEG spec, set this to 255. However, darn - * few applications need more than 4 channels (maybe 5 for CMYK + alpha - * mask). We recommend 10 as a reasonable compromise; use 4 if you are - * really short on memory. (Each allowed component costs a hundred or so - * bytes of storage, whether actually used in an image or not.) - */ - -#define MAX_COMPONENTS 10 /* maximum number of image components */ - - -/* - * Basic data types. - * You may need to change these if you have a machine with unusual data - * type sizes; for example, "char" not 8 bits, "short" not 16 bits, - * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, - * but it had better be at least 16. - */ - -/* Representation of a single sample (pixel element value). - * We frequently allocate large arrays of these, so it's important to keep - * them small. But if you have memory to burn and access to char or short - * arrays is very slow on your hardware, you might want to change these. - */ - -#if BITS_IN_JSAMPLE == 8 -/* JSAMPLE should be the smallest type that will hold the values 0..255. - * You can use a signed char by having GETJSAMPLE mask it with 0xFF. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JSAMPLE; -#ifdef CHAR_IS_UNSIGNED -#define GETJSAMPLE(value) ((int) (value)) -#else -#define GETJSAMPLE(value) ((int) (value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - -#define MAXJSAMPLE 255 -#define CENTERJSAMPLE 128 - -#endif /* BITS_IN_JSAMPLE == 8 */ - - -#if BITS_IN_JSAMPLE == 12 -/* JSAMPLE should be the smallest type that will hold the values 0..4095. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 4095 -#define CENTERJSAMPLE 2048 - -#endif /* BITS_IN_JSAMPLE == 12 */ - - -/* Representation of a DCT frequency coefficient. - * This should be a signed value of at least 16 bits; "short" is usually OK. - * Again, we allocate large arrays of these, but you can change to int - * if you have memory to burn and "short" is really slow. - */ - -typedef short JCOEF; - - -/* Compressed datastreams are represented as arrays of JOCTET. - * These must be EXACTLY 8 bits wide, at least once they are written to - * external storage. Note that when using the stdio data source/destination - * managers, this is also the data type passed to fread/fwrite. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JOCTET; -#define GETJOCTET(value) (value) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JOCTET; -#ifdef CHAR_IS_UNSIGNED -#define GETJOCTET(value) (value) -#else -#define GETJOCTET(value) ((value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - - -/* These typedefs are used for various table entries and so forth. - * They must be at least as wide as specified; but making them too big - * won't cost a huge amount of memory, so we don't provide special - * extraction code like we did for JSAMPLE. (In other words, these - * typedefs live at a different point on the speed/space tradeoff curve.) - */ - -/* UINT8 must hold at least the values 0..255. */ - -#ifdef HAVE_UNSIGNED_CHAR -typedef unsigned char UINT8; -#else /* not HAVE_UNSIGNED_CHAR */ -#ifdef CHAR_IS_UNSIGNED -typedef char UINT8; -#else /* not CHAR_IS_UNSIGNED */ -typedef short UINT8; -#endif /* CHAR_IS_UNSIGNED */ -#endif /* HAVE_UNSIGNED_CHAR */ - -/* UINT16 must hold at least the values 0..65535. */ - -#ifdef HAVE_UNSIGNED_SHORT -typedef unsigned short UINT16; -#else /* not HAVE_UNSIGNED_SHORT */ -typedef unsigned int UINT16; -#endif /* HAVE_UNSIGNED_SHORT */ - -/* INT16 must hold at least the values -32768..32767. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ -typedef short INT16; -#endif - -/* INT32 must hold at least signed 32-bit values. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ -typedef long INT32; -#endif - -/* Datatype used for image dimensions. The JPEG standard only supports - * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore - * "unsigned int" is sufficient on all machines. However, if you need to - * handle larger images and you don't mind deviating from the spec, you - * can change this datatype. - */ - -typedef unsigned int JDIMENSION; - -#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ - - -/* These macros are used in all function definitions and extern declarations. - * You could modify them if you need to change function linkage conventions; - * in particular, you'll need to do that to make the library a Windows DLL. - * Another application is to make all functions global for use with debuggers - * or code profilers that require it. - */ - -/* a function called through method pointers: */ -#define METHODDEF(type) static type -/* a function used only in its module: */ -#define LOCAL(type) static type -/* a function referenced thru EXTERNs: */ -#define GLOBAL(type) type -/* a reference to a GLOBAL function: */ -#define EXTERN(type) extern type - - -/* This macro is used to declare a "method", that is, a function pointer. - * We want to supply prototype parameters if the compiler can cope. - * Note that the arglist parameter must be parenthesized! - * Again, you can customize this if you need special linkage keywords. - */ - -#ifdef HAVE_PROTOTYPES -#define JMETHOD(type,methodname,arglist) type (*methodname) arglist -#else -#define JMETHOD(type,methodname,arglist) type (*methodname) () -#endif - - -/* Here is the pseudo-keyword for declaring pointers that must be "far" - * on 80x86 machines. Most of the specialized coding for 80x86 is handled - * by just saying "FAR *" where such a pointer is needed. In a few places - * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. - */ - -#ifdef NEED_FAR_POINTERS -#define FAR far -#else -#define FAR -#endif - - -/* - * On a few systems, type boolean and/or its values FALSE, TRUE may appear - * in standard header files. Or you may have conflicts with application- - * specific header files that you want to include together with these files. - * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. - */ - -#ifndef HAVE_BOOLEAN -typedef int boolean; -#endif -#ifndef FALSE /* in case these macros already exist */ -#define FALSE 0 /* values of boolean */ -#endif -#ifndef TRUE -#define TRUE 1 -#endif - - -/* - * The remaining options affect code selection within the JPEG library, - * but they don't need to be visible to most applications using the library. - * To minimize application namespace pollution, the symbols won't be - * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. - */ - -#ifdef JPEG_INTERNALS -#define JPEG_INTERNAL_OPTIONS -#endif - -#ifdef JPEG_INTERNAL_OPTIONS - - -/* - * These defines indicate whether to include various optional functions. - * Undefining some of these symbols will produce a smaller but less capable - * library. Note that you can leave certain source files out of the - * compilation/linking process if you've #undef'd the corresponding symbols. - * (You may HAVE to do that if your compiler doesn't like null source files.) - */ - -/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ - -/* Capability options common to encoder and decoder: */ - -#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ -#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ -#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ - -/* Encoder capability options: */ - -#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ -/* Note: if you selected 12-bit data precision, it is dangerous to turn off - * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit - * precision, so jchuff.c normally uses entropy optimization to compute - * usable tables for higher precision. If you don't want to do optimization, - * you'll have to supply different default Huffman tables. - * The exact same statements apply for progressive JPEG: the default tables - * don't work for progressive mode. (This may get fixed, however.) - */ -#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ - -/* Decoder capability options: */ - -#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ -#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ -#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ -#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ -#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ -#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ - -/* more capability options later, no doubt */ - - -/* - * Ordering of RGB data in scanlines passed to or from the application. - * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. - * RESTRICTIONS: - * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. - * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not - * useful if you are using JPEG color spaces other than YCbCr or grayscale. - * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. - */ - -#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ -#define RGB_GREEN 1 /* Offset of Green */ -#define RGB_BLUE 2 /* Offset of Blue */ -#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ - - -/* Definitions for speed-related optimizations. */ - - -/* If your compiler supports inline functions, define INLINE - * as the inline keyword; otherwise define it as empty. - */ - -#ifndef INLINE -#ifdef __GNUC__ /* for instance, GNU C knows about inline */ -#define INLINE __inline__ -#endif -#ifndef INLINE -#define INLINE /* default is to define it as empty */ -#endif -#endif - - -/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying - * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER - * as short on such a machine. MULTIPLIER must be at least 16 bits wide. - */ - -#ifndef MULTIPLIER -#define MULTIPLIER int /* type for fastest integer multiply */ -#endif - - -/* FAST_FLOAT should be either float or double, whichever is done faster - * by your compiler. (Note that this type is only used in the floating point - * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) - * Typically, float is faster in ANSI C compilers, while double is faster in - * pre-ANSI compilers (because they insist on converting to double anyway). - * The code below therefore chooses float if we have ANSI-style prototypes. - */ - -#ifndef FAST_FLOAT -#ifdef HAVE_PROTOTYPES -#define FAST_FLOAT float -#else -#define FAST_FLOAT double -#endif -#endif - -#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/WDL/jpeglib/jpegint.h b/WDL/jpeglib/jpegint.h deleted file mode 100644 index 685a3610..00000000 --- a/WDL/jpeglib/jpegint.h +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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/WDL/jpeglib/jpeglib.h b/WDL/jpeglib/jpeglib.h deleted file mode 100644 index b9356f39..00000000 --- a/WDL/jpeglib/jpeglib.h +++ /dev/null @@ -1,1096 +0,0 @@ -/* - * jpeglib.h - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the application interface for the JPEG library. - * Most applications using the library need only include this file, - * and perhaps jerror.h if they want to know the exact error codes. - */ - -#ifndef JPEGLIB_H -#define JPEGLIB_H - -/* - * First we include the configuration files that record how this - * installation of the JPEG library is set up. jconfig.h can be - * generated automatically for many systems. jmorecfg.h contains - * manual configuration options that most people need not worry about. - */ - -#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ -#include "jconfig.h" /* widely used configuration options */ -#endif -#include "jmorecfg.h" /* seldom changed options */ - - -/* Version ID for the JPEG library. - * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". - */ - -#define JPEG_LIB_VERSION 62 /* Version 6b */ - - -/* Various constants determining the sizes of things. - * All of these are specified by the JPEG standard, so don't change them - * if you want to be compatible. - */ - -#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ -#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ -#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ -#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ -#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ -#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ -#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ -/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; - * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. - * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU - * to handle it. We even let you do this from the jconfig.h file. However, - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe - * sometimes emits noncompliant files doesn't mean you should too. - */ -#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ -#ifndef D_MAX_BLOCKS_IN_MCU -#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ -#endif - - -/* Data structures for images (arrays of samples and of DCT coefficients). - * On 80x86 machines, the image arrays are too big for near pointers, - * but the pointer arrays can fit in near memory. - */ - -typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ -typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ -typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ - -typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ -typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ -typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ -typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ - -typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ - - -/* Types for JPEG compression parameters and working tables. */ - - -/* DCT coefficient quantization tables. */ - -typedef struct { - /* This array gives the coefficient quantizers in natural array order - * (not the zigzag order in which they are stored in a JPEG DQT marker). - * CAUTION: IJG versions prior to v6a kept this array in zigzag order. - */ - UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JQUANT_TBL; - - -/* Huffman coding tables. */ - -typedef struct { - /* These two fields directly represent the contents of a JPEG DHT marker */ - UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ - /* length k bits; bits[0] is unused */ - UINT8 huffval[256]; /* The symbols, in order of incr code length */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JHUFF_TBL; - - -/* Basic info about one component (color channel). */ - -typedef struct { - /* These values are fixed over the whole image. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOF marker. */ - int component_id; /* identifier for this component (0..255) */ - int component_index; /* its index in SOF or cinfo->comp_info[] */ - int h_samp_factor; /* horizontal sampling factor (1..4) */ - int v_samp_factor; /* vertical sampling factor (1..4) */ - int quant_tbl_no; /* quantization table selector (0..3) */ - /* These values may vary between scans. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOS marker. */ - /* The decompressor output side may not use these variables. */ - int dc_tbl_no; /* DC entropy table selector (0..3) */ - int ac_tbl_no; /* AC entropy table selector (0..3) */ - - /* Remaining fields should be treated as private by applications. */ - - /* These values are computed during compression or decompression startup: */ - /* Component's size in DCT blocks. - * Any dummy blocks added to complete an MCU are not counted; therefore - * these values do not depend on whether a scan is interleaved or not. - */ - JDIMENSION width_in_blocks; - JDIMENSION height_in_blocks; - /* Size of a DCT block in samples. Always DCTSIZE for compression. - * For decompression this is the size of the output from one DCT block, - * reflecting any scaling we choose to apply during the IDCT step. - * Values of 1,2,4,8 are likely to be supported. Note that different - * components may receive different IDCT scalings. - */ - int DCT_scaled_size; - /* The downsampled dimensions are the component's actual, unpadded number - * of samples at the main buffer (preprocessing/compression interface), thus - * downsampled_width = ceil(image_width * Hi/Hmax) - * and similarly for height. For decompression, IDCT scaling is included, so - * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) - */ - JDIMENSION downsampled_width; /* actual width in samples */ - JDIMENSION downsampled_height; /* actual height in samples */ - /* This flag is used only for decompression. In cases where some of the - * components will be ignored (eg grayscale output from YCbCr image), - * we can skip most computations for the unused components. - */ - boolean component_needed; /* do we need the value of this component? */ - - /* These values are computed before starting a scan of the component. */ - /* The decompressor output side may not use these variables. */ - int MCU_width; /* number of blocks per MCU, horizontally */ - int MCU_height; /* number of blocks per MCU, vertically */ - int MCU_blocks; /* MCU_width * MCU_height */ - int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ - int last_col_width; /* # of non-dummy blocks across in last MCU */ - int last_row_height; /* # of non-dummy blocks down in last MCU */ - - /* Saved quantization table for component; NULL if none yet saved. - * See jdinput.c comments about the need for this information. - * This field is currently used only for decompression. - */ - JQUANT_TBL * quant_table; - - /* Private per-component storage for DCT or IDCT subsystem. */ - void * dct_table; -} jpeg_component_info; - - -/* The script for encoding a multiple-scan file is an array of these: */ - -typedef struct { - int comps_in_scan; /* number of components encoded in this scan */ - int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ - int Ss, Se; /* progressive JPEG spectral selection parms */ - int Ah, Al; /* progressive JPEG successive approx. parms */ -} jpeg_scan_info; - -/* The decompressor can save APPn and COM markers in a list of these: */ - -typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; - -struct jpeg_marker_struct { - jpeg_saved_marker_ptr next; /* next in list, or NULL */ - UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ - unsigned int original_length; /* # bytes of data in the file */ - unsigned int data_length; /* # bytes of data saved at data[] */ - JOCTET FAR * data; /* the data contained in the marker */ - /* the marker length word is not counted in data_length or original_length */ -}; - -/* Known color spaces. */ - -typedef enum { - JCS_UNKNOWN, /* error/unspecified */ - JCS_GRAYSCALE, /* monochrome */ - JCS_RGB, /* red/green/blue */ - JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ - JCS_CMYK, /* C/M/Y/K */ - JCS_YCCK /* Y/Cb/Cr/K */ -} J_COLOR_SPACE; - -/* DCT/IDCT algorithm options. */ - -typedef enum { - JDCT_ISLOW, /* slow but accurate integer algorithm */ - JDCT_IFAST, /* faster, less accurate integer method */ - JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ -} J_DCT_METHOD; - -#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ -#define JDCT_DEFAULT JDCT_ISLOW -#endif -#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ -#define JDCT_FASTEST JDCT_IFAST -#endif - -/* Dithering options for decompression. */ - -typedef enum { - JDITHER_NONE, /* no dithering */ - JDITHER_ORDERED, /* simple ordered dither */ - JDITHER_FS /* Floyd-Steinberg error diffusion dither */ -} J_DITHER_MODE; - - -/* Common fields between JPEG compression and decompression master structs. */ - -#define jpeg_common_fields \ - struct jpeg_error_mgr * err; /* Error handler module */\ - struct jpeg_memory_mgr * mem; /* Memory manager module */\ - struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ - void * client_data; /* Available for use by application */\ - boolean is_decompressor; /* So common code can tell which is which */\ - int global_state /* For checking call sequence validity */ - -/* Routines that are to be used by both halves of the library are declared - * to receive a pointer to this structure. There are no actual instances of - * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. - */ -struct jpeg_common_struct { - jpeg_common_fields; /* Fields common to both master struct types */ - /* Additional fields follow in an actual jpeg_compress_struct or - * jpeg_decompress_struct. All three structs must agree on these - * initial fields! (This would be a lot cleaner in C++.) - */ -}; - -typedef struct jpeg_common_struct * j_common_ptr; -typedef struct jpeg_compress_struct * j_compress_ptr; -typedef struct jpeg_decompress_struct * j_decompress_ptr; - - -/* Master record for a compression instance */ - -struct jpeg_compress_struct { - jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ - - /* Destination for compressed data */ - struct jpeg_destination_mgr * dest; - - /* Description of source image --- these fields must be filled in by - * outer application before starting compression. in_color_space must - * be correct before you can even call jpeg_set_defaults(). - */ - - JDIMENSION image_width; /* input image width */ - JDIMENSION image_height; /* input image height */ - int input_components; /* # of color components in input image */ - J_COLOR_SPACE in_color_space; /* colorspace of input image */ - - double input_gamma; /* image gamma of input image */ - - /* Compression parameters --- these fields must be set before calling - * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to - * initialize everything to reasonable defaults, then changing anything - * the application specifically wants to change. That way you won't get - * burnt when new parameters are added. Also note that there are several - * helper routines to simplify changing parameters. - */ - - int data_precision; /* bits of precision in image data */ - - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - int num_scans; /* # of entries in scan_info array */ - const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ - /* The default value of scan_info is NULL, which causes a single-scan - * sequential JPEG file to be emitted. To create a multi-scan file, - * set num_scans and scan_info to point to an array of scan definitions. - */ - - boolean raw_data_in; /* TRUE=caller supplies downsampled data */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - int smoothing_factor; /* 1..100, or 0 for no input smoothing */ - J_DCT_METHOD dct_method; /* DCT algorithm selector */ - - /* The restart interval can be specified in absolute MCUs by setting - * restart_interval, or in MCU rows by setting restart_in_rows - * (in which case the correct restart_interval will be figured - * for each scan). - */ - unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ - int restart_in_rows; /* if > 0, MCU rows per restart interval */ - - /* Parameters controlling emission of special markers. */ - - boolean write_JFIF_header; /* should a JFIF marker be written? */ - UINT8 JFIF_major_version; /* What to write for the JFIF version number */ - UINT8 JFIF_minor_version; - /* These three values are not used by the JPEG code, merely copied */ - /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ - /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ - /* ratio is defined by X_density/Y_density even when density_unit=0. */ - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean write_Adobe_marker; /* should an Adobe marker be written? */ - - /* State variable: index of next scanline to be written to - * jpeg_write_scanlines(). Application may use this to control its - * processing loop, e.g., "while (next_scanline < image_height)". - */ - - JDIMENSION next_scanline; /* 0 .. image_height-1 */ - - /* Remaining fields are known throughout compressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during compression startup - */ - boolean progressive_mode; /* TRUE if scan script uses progressive mode */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ - /* The coefficient controller receives data in units of MCU rows as defined - * for fully interleaved scans (whether the JPEG file is interleaved or not). - * There are v_samp_factor * DCTSIZE sample rows of each component in an - * "iMCU" (interleaved MCU) row. - */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[C_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* - * Links to compression subobjects (methods and private variables of modules) - */ - struct jpeg_comp_master * master; - struct jpeg_c_main_controller * main; - struct jpeg_c_prep_controller * prep; - struct jpeg_c_coef_controller * coef; - struct jpeg_marker_writer * marker; - struct jpeg_color_converter * cconvert; - struct jpeg_downsampler * downsample; - struct jpeg_forward_dct * fdct; - struct jpeg_entropy_encoder * entropy; - jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ - int script_space_size; -}; - - -/* Master record for a decompression instance */ - -struct jpeg_decompress_struct { - jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ - - /* Source of compressed data */ - struct jpeg_source_mgr * src; - - /* Basic description of image --- filled in by jpeg_read_header(). */ - /* Application may inspect these values to decide how to process image. */ - - JDIMENSION image_width; /* nominal image width (from SOF marker) */ - JDIMENSION image_height; /* nominal image height */ - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - /* Decompression processing parameters --- these fields must be set before - * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes - * them to default values. - */ - - J_COLOR_SPACE out_color_space; /* colorspace for output */ - - unsigned int scale_num, scale_denom; /* fraction by which to scale image */ - - double output_gamma; /* image gamma wanted in output */ - - boolean buffered_image; /* TRUE=multiple output passes */ - boolean raw_data_out; /* TRUE=downsampled data wanted */ - - J_DCT_METHOD dct_method; /* IDCT algorithm selector */ - boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ - boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ - - boolean quantize_colors; /* TRUE=colormapped output wanted */ - /* the following are ignored if not quantize_colors: */ - J_DITHER_MODE dither_mode; /* type of color dithering to use */ - boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ - int desired_number_of_colors; /* max # colors to use in created colormap */ - /* these are significant only in buffered-image mode: */ - boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ - boolean enable_external_quant;/* enable future use of external colormap */ - boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ - - /* Description of actual output image that will be returned to application. - * These fields are computed by jpeg_start_decompress(). - * You can also use jpeg_calc_output_dimensions() to determine these values - * in advance of calling jpeg_start_decompress(). - */ - - JDIMENSION output_width; /* scaled image width */ - JDIMENSION output_height; /* scaled image height */ - int out_color_components; /* # of color components in out_color_space */ - int output_components; /* # of color components returned */ - /* output_components is 1 (a colormap index) when quantizing colors; - * otherwise it equals out_color_components. - */ - int rec_outbuf_height; /* min recommended height of scanline buffer */ - /* If the buffer passed to jpeg_read_scanlines() is less than this many rows - * high, space and time will be wasted due to unnecessary data copying. - * Usually rec_outbuf_height will be 1 or 2, at most 4. - */ - - /* When quantizing colors, the output colormap is described by these fields. - * The application can supply a colormap by setting colormap non-NULL before - * calling jpeg_start_decompress; otherwise a colormap is created during - * jpeg_start_decompress or jpeg_start_output. - * The map has out_color_components rows and actual_number_of_colors columns. - */ - int actual_number_of_colors; /* number of entries in use */ - JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ - - /* State variables: these variables indicate the progress of decompression. - * The application may examine these but must not modify them. - */ - - /* Row index of next scanline to be read from jpeg_read_scanlines(). - * Application may use this to control its processing loop, e.g., - * "while (output_scanline < output_height)". - */ - JDIMENSION output_scanline; /* 0 .. output_height-1 */ - - /* Current input scan number and number of iMCU rows completed in scan. - * These indicate the progress of the decompressor input side. - */ - int input_scan_number; /* Number of SOS markers seen so far */ - JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ - - /* The "output scan number" is the notional scan being displayed by the - * output side. The decompressor will not allow output scan/row number - * to get ahead of input scan/row, but it can fall arbitrarily far behind. - */ - int output_scan_number; /* Nominal scan number being displayed */ - JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ - - /* Current progression status. coef_bits[c][i] indicates the precision - * with which component c's DCT coefficient i (in zigzag order) is known. - * It is -1 when no data has yet been received, otherwise it is the point - * transform (shift) value for the most recent scan of the coefficient - * (thus, 0 at completion of the progression). - * This pointer is NULL when reading a non-progressive file. - */ - int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ - - /* Internal JPEG parameters --- the application usually need not look at - * these fields. Note that the decompressor output side may not use - * any parameters that can change between scans. - */ - - /* Quantization and Huffman tables are carried forward across input - * datastreams when processing abbreviated JPEG datastreams. - */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - /* These parameters are never carried across datastreams, since they - * are given in SOF/SOS markers or defined to be reset by SOI. - */ - - int data_precision; /* bits of precision in image data */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ - - /* These fields record data obtained from optional markers recognized by - * the JPEG library. - */ - boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ - /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ - UINT8 JFIF_major_version; /* JFIF version number */ - UINT8 JFIF_minor_version; - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ - UINT8 Adobe_transform; /* Color transform code from Adobe marker */ - - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - - /* Aside from the specific data retained from APPn markers known to the - * library, the uninterpreted contents of any or all APPn and COM markers - * can be saved in a list for examination by the application. - */ - jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ - - /* Remaining fields are known throughout decompressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during decompression startup - */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ - /* The coefficient controller's input and output progress is measured in - * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows - * in fully interleaved JPEG scans, but are used whether the scan is - * interleaved or not. We define an iMCU row as v_samp_factor DCT block - * rows of each component. Therefore, the IDCT output contains - * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. - */ - - JSAMPLE * sample_range_limit; /* table for fast range-limiting */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - * Note that the decompressor output side must not use these fields. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[D_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* This field is shared between entropy decoder and marker parser. - * It is either zero or the code of a JPEG marker that has been - * read from the data source, but has not yet been processed. - */ - int unread_marker; - - /* - * Links to decompression subobjects (methods, private variables of modules) - */ - struct jpeg_decomp_master * master; - struct jpeg_d_main_controller * main; - struct jpeg_d_coef_controller * coef; - struct jpeg_d_post_controller * post; - struct jpeg_input_controller * inputctl; - struct jpeg_marker_reader * marker; - struct jpeg_entropy_decoder * entropy; - struct jpeg_inverse_dct * idct; - struct jpeg_upsampler * upsample; - struct jpeg_color_deconverter * cconvert; - struct jpeg_color_quantizer * cquantize; -}; - - -/* "Object" declarations for JPEG modules that may be supplied or called - * directly by the surrounding application. - * As with all objects in the JPEG library, these structs only define the - * publicly visible methods and state variables of a module. Additional - * private fields may exist after the public ones. - */ - - -/* Error handler object */ - -struct jpeg_error_mgr { - /* Error exit handler: does not return to caller */ - JMETHOD(void, error_exit, (j_common_ptr cinfo)); - /* Conditionally emit a trace or warning message */ - JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); - /* Routine that actually outputs a trace or error message */ - JMETHOD(void, output_message, (j_common_ptr cinfo)); - /* Format a message string for the most recent JPEG error or message */ - JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); -#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ - /* Reset error state variables at start of a new image */ - JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); - - /* The message ID code and any parameters are saved here. - * A message can have one string parameter or up to 8 int parameters. - */ - int msg_code; -#define JMSG_STR_PARM_MAX 80 - union { - int i[8]; - char s[JMSG_STR_PARM_MAX]; - } msg_parm; - - /* Standard state variables for error facility */ - - int trace_level; /* max msg_level that will be displayed */ - - /* For recoverable corrupt-data errors, we emit a warning message, - * but keep going unless emit_message chooses to abort. emit_message - * should count warnings in num_warnings. The surrounding application - * can check for bad data by seeing if num_warnings is nonzero at the - * end of processing. - */ - long num_warnings; /* number of corrupt-data warnings */ - - /* These fields point to the table(s) of error message strings. - * An application can change the table pointer to switch to a different - * message list (typically, to change the language in which errors are - * reported). Some applications may wish to add additional error codes - * that will be handled by the JPEG library error mechanism; the second - * table pointer is used for this purpose. - * - * First table includes all errors generated by JPEG library itself. - * Error code 0 is reserved for a "no such error string" message. - */ - const char * const * jpeg_message_table; /* Library errors */ - int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ - /* Second table can be added by application (see cjpeg/djpeg for example). - * It contains strings numbered first_addon_message..last_addon_message. - */ - const char * const * addon_message_table; /* Non-library errors */ - int first_addon_message; /* code for first string in addon table */ - int last_addon_message; /* code for last string in addon table */ -}; - - -/* Progress monitor object */ - -struct jpeg_progress_mgr { - JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); - - long pass_counter; /* work units completed in this pass */ - long pass_limit; /* total number of work units in this pass */ - int completed_passes; /* passes completed so far */ - int total_passes; /* total number of passes expected */ -}; - - -/* Data destination object for compression */ - -struct jpeg_destination_mgr { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - - JMETHOD(void, init_destination, (j_compress_ptr cinfo)); - JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); - JMETHOD(void, term_destination, (j_compress_ptr cinfo)); -}; - - -/* Data source object for decompression */ - -struct jpeg_source_mgr { - const JOCTET * next_input_byte; /* => next byte to read from buffer */ - size_t bytes_in_buffer; /* # of bytes remaining in buffer */ - - JMETHOD(void, init_source, (j_decompress_ptr cinfo)); - JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); - JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); - JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); - JMETHOD(void, term_source, (j_decompress_ptr cinfo)); -}; - - -/* Memory manager object. - * Allocates "small" objects (a few K total), "large" objects (tens of K), - * and "really big" objects (virtual arrays with backing store if needed). - * The memory manager does not allow individual objects to be freed; rather, - * each created object is assigned to a pool, and whole pools can be freed - * at once. This is faster and more convenient than remembering exactly what - * to free, especially where malloc()/free() are not too speedy. - * NB: alloc routines never return NULL. They exit to error_exit if not - * successful. - */ - -#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ -#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ -#define JPOOL_NUMPOOLS 2 - -typedef struct jvirt_sarray_control * jvirt_sarray_ptr; -typedef struct jvirt_barray_control * jvirt_barray_ptr; - - -struct jpeg_memory_mgr { - /* Method pointers */ - JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows)); - JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, - JDIMENSION numrows)); - JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION samplesperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION blocksperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); - JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, - jvirt_sarray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, - jvirt_barray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); - JMETHOD(void, self_destruct, (j_common_ptr cinfo)); - - /* Limit on memory allocation for this JPEG object. (Note that this is - * merely advisory, not a guaranteed maximum; it only affects the space - * used for virtual-array buffers.) May be changed by outer application - * after creating the JPEG object. - */ - long max_memory_to_use; - - /* Maximum allocation request accepted by alloc_large. */ - long max_alloc_chunk; -}; - - -/* Routine signature for application-supplied marker processing methods. - * Need not pass marker code since it is stored in cinfo->unread_marker. - */ -typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); - - -/* Declarations for routines called by application. - * The JPP macro hides prototype parameters from compilers that can't cope. - * Note JPP requires double parentheses. - */ - -#ifdef HAVE_PROTOTYPES -#define JPP(arglist) arglist -#else -#define JPP(arglist) () -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. - * We shorten external names to be unique in the first six letters, which - * is good enough for all known systems. - * (If your compiler itself needs names to be unique in less than 15 - * characters, you are out of luck. Get a better compiler.) - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_error jStdError -#define jpeg_CreateCompress jCreaCompress -#define jpeg_CreateDecompress jCreaDecompress -#define jpeg_destroy_compress jDestCompress -#define jpeg_destroy_decompress jDestDecompress -#define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc -#define jpeg_set_defaults jSetDefaults -#define jpeg_set_colorspace jSetColorspace -#define jpeg_default_colorspace jDefColorspace -#define jpeg_set_quality jSetQuality -#define jpeg_set_linear_quality jSetLQuality -#define jpeg_add_quant_table jAddQuantTable -#define jpeg_quality_scaling jQualityScaling -#define jpeg_simple_progression jSimProgress -#define jpeg_suppress_tables jSuppressTables -#define jpeg_alloc_quant_table jAlcQTable -#define jpeg_alloc_huff_table jAlcHTable -#define jpeg_start_compress jStrtCompress -#define jpeg_write_scanlines jWrtScanlines -#define jpeg_finish_compress jFinCompress -#define jpeg_write_raw_data jWrtRawData -#define jpeg_write_marker jWrtMarker -#define jpeg_write_m_header jWrtMHeader -#define jpeg_write_m_byte jWrtMByte -#define jpeg_write_tables jWrtTables -#define jpeg_read_header jReadHeader -#define jpeg_start_decompress jStrtDecompress -#define jpeg_read_scanlines jReadScanlines -#define jpeg_finish_decompress jFinDecompress -#define jpeg_read_raw_data jReadRawData -#define jpeg_has_multiple_scans jHasMultScn -#define jpeg_start_output jStrtOutput -#define jpeg_finish_output jFinOutput -#define jpeg_input_complete jInComplete -#define jpeg_new_colormap jNewCMap -#define jpeg_consume_input jConsumeInput -#define jpeg_calc_output_dimensions jCalcDimensions -#define jpeg_save_markers jSaveMarkers -#define jpeg_set_marker_processor jSetMarker -#define jpeg_read_coefficients jReadCoefs -#define jpeg_write_coefficients jWrtCoefs -#define jpeg_copy_critical_parameters jCopyCrit -#define jpeg_abort_compress jAbrtCompress -#define jpeg_abort_decompress jAbrtDecompress -#define jpeg_abort jAbort -#define jpeg_destroy jDestroy -#define jpeg_resync_to_restart jResyncRestart -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Default error-management setup */ -EXTERN(struct jpeg_error_mgr *) jpeg_std_error - JPP((struct jpeg_error_mgr * err)); - -/* Initialization of JPEG compression objects. - * jpeg_create_compress() and jpeg_create_decompress() are the exported - * names that applications should call. These expand to calls on - * jpeg_CreateCompress and jpeg_CreateDecompress with additional information - * passed for version mismatch checking. - * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. - */ -#define jpeg_create_compress(cinfo) \ - jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_compress_struct)) -#define jpeg_create_decompress(cinfo) \ - jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_decompress_struct)) -EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, - int version, size_t structsize)); -EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, - int version, size_t structsize)); -/* Destruction of JPEG compression objects */ -EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); - -/* Standard data source and destination managers: stdio streams. */ -/* Caller is responsible for opening the file before and closing after. */ -EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); - -/* Default parameter setup for compression */ -EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); -/* Compression parameter setup aids */ -EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); -EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); -EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); -EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); -EXTERN(int) jpeg_quality_scaling JPP((int quality)); -EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); -EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); -EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); - -/* Main entry points for compression */ -EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); -EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); -EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); - -/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); - -/* Write a special marker. See libjpeg.doc concerning safe usage. */ -EXTERN(void) jpeg_write_marker - JPP((j_compress_ptr cinfo, int marker, - const JOCTET * dataptr, unsigned int datalen)); -/* Same, but piecemeal. */ -EXTERN(void) jpeg_write_m_header - JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); -EXTERN(void) jpeg_write_m_byte - JPP((j_compress_ptr cinfo, int val)); - -/* Alternate compression function: just write an abbreviated table file */ -EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); - -/* Decompression startup: read start of JPEG datastream to see what's there */ -EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); -/* Return value is one of: */ -#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ -#define JPEG_HEADER_OK 1 /* Found valid image datastream */ -#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ -/* If you pass require_image = TRUE (normal case), you need not check for - * a TABLES_ONLY return code; an abbreviated file will cause an error exit. - * JPEG_SUSPENDED is only possible if you use a data source module that can - * give a suspension return (the stdio source module doesn't). - */ - -/* Main entry points for decompression */ -EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); -EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); - -/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); - -/* Additional entry points for buffered-image mode. */ -EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); -EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); -EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); -/* Return value is one of: */ -/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ -#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ -#define JPEG_REACHED_EOI 2 /* Reached end of image */ -#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ -#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ - -/* Precalculate output dimensions for current decompression parameters. */ -EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); - -/* Control saving of COM and APPn markers into marker_list. */ -EXTERN(void) jpeg_save_markers - JPP((j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit)); - -/* Install a special processing method for COM or APPn markers. */ -EXTERN(void) jpeg_set_marker_processor - JPP((j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine)); - -/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ -EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); -EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); - -/* If you choose to abort compression or decompression before completing - * jpeg_finish_(de)compress, then you need to clean up to release memory, - * temporary files, etc. You can just call jpeg_destroy_(de)compress - * if you're done with the JPEG object, but if you want to clean it up and - * reuse it, call this: - */ -EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); - -/* Generic versions of jpeg_abort and jpeg_destroy that work on either - * flavor of JPEG object. These may be more convenient in some places. - */ -EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); -EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); - -/* Default restart-marker-resync procedure for use by data source modules */ -EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); - - -/* These marker codes are exported since applications and data source modules - * are likely to want to use them. - */ - -#define JPEG_RST0 0xD0 /* RST0 marker code */ -#define JPEG_EOI 0xD9 /* EOI marker code */ -#define JPEG_APP0 0xE0 /* APP0 marker code */ -#define JPEG_COM 0xFE /* COM marker code */ - - -/* If we have a brain-damaged compiler that emits warnings (or worse, errors) - * for structure definitions that are never filled in, keep it quiet by - * supplying dummy definitions for the various substructures. - */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -struct jpeg_comp_master { long dummy; }; -struct jpeg_c_main_controller { long dummy; }; -struct jpeg_c_prep_controller { long dummy; }; -struct jpeg_c_coef_controller { long dummy; }; -struct jpeg_marker_writer { long dummy; }; -struct jpeg_color_converter { long dummy; }; -struct jpeg_downsampler { long dummy; }; -struct jpeg_forward_dct { long dummy; }; -struct jpeg_entropy_encoder { long dummy; }; -struct jpeg_decomp_master { long dummy; }; -struct jpeg_d_main_controller { long dummy; }; -struct jpeg_d_coef_controller { long dummy; }; -struct jpeg_d_post_controller { long dummy; }; -struct jpeg_input_controller { long dummy; }; -struct jpeg_marker_reader { long dummy; }; -struct jpeg_entropy_decoder { long dummy; }; -struct jpeg_inverse_dct { long dummy; }; -struct jpeg_upsampler { long dummy; }; -struct jpeg_color_deconverter { long dummy; }; -struct jpeg_color_quantizer { long dummy; }; -#endif /* JPEG_INTERNALS */ -#endif /* INCOMPLETE_TYPES_BROKEN */ - - -/* - * The JPEG library modules define JPEG_INTERNALS before including this file. - * The internal structure declarations are read only when that is true. - * Applications using the library should not include jpegint.h, but may wish - * to include jerror.h. - */ - -#ifdef JPEG_INTERNALS -#include "jpegint.h" /* fetch private declarations */ -#include "jerror.h" /* fetch error codes too */ -#endif - -#endif /* JPEGLIB_H */ diff --git a/WDL/jpeglib/jquant1.c b/WDL/jpeglib/jquant1.c deleted file mode 100644 index aaa34a18..00000000 --- a/WDL/jpeglib/jquant1.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * 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/WDL/jpeglib/jquant2.c b/WDL/jpeglib/jquant2.c deleted file mode 100644 index 87a3920b..00000000 --- a/WDL/jpeglib/jquant2.c +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * 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/WDL/jpeglib/jutils.c b/WDL/jpeglib/jutils.c deleted file mode 100644 index 286cda20..00000000 --- a/WDL/jpeglib/jutils.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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/WDL/jpeglib/jversion.h b/WDL/jpeglib/jversion.h deleted file mode 100644 index dadd453a..00000000 --- a/WDL/jpeglib/jversion.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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/WDL/lameencdec.cpp b/WDL/lameencdec.cpp deleted file mode 100644 index 702b4799..00000000 --- a/WDL/lameencdec.cpp +++ /dev/null @@ -1,1004 +0,0 @@ -/* - WDL - lameencdec.cpp - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - -*/ - - - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include -#include -#include - -#include "wdlcstring.h" -#include "lameencdec.h" - - -#ifdef USE_LAME_BLADE_API - -#pragma pack(push) -#pragma pack(1) - -#ifdef __cplusplus -extern "C" { -#endif - -/* encoding formats */ - -#define BE_CONFIG_MP3 0 -#define BE_CONFIG_LAME 256 - -/* type definitions */ - -typedef UINT_PTR HBE_STREAM; -typedef HBE_STREAM *PHBE_STREAM; -typedef unsigned long BE_ERR; - -/* error codes */ - -#define BE_ERR_SUCCESSFUL 0x00000000 -#define BE_ERR_INVALID_FORMAT 0x00000001 -#define BE_ERR_INVALID_FORMAT_PARAMETERS 0x00000002 -#define BE_ERR_NO_MORE_HANDLES 0x00000003 -#define BE_ERR_INVALID_HANDLE 0x00000004 -#define BE_ERR_BUFFER_TOO_SMALL 0x00000005 - -/* other constants */ - -#define BE_MAX_HOMEPAGE 128 - -/* format specific variables */ - -#define BE_MP3_MODE_STEREO 0 -#define BE_MP3_MODE_JSTEREO 1 -#define BE_MP3_MODE_DUALCHANNEL 2 -#define BE_MP3_MODE_MONO 3 - - - -#define MPEG1 1 -#define MPEG2 0 - -#ifdef _BLADEDLL -#undef FLOAT - #include -#endif - -#define CURRENT_STRUCT_VERSION 1 -#define CURRENT_STRUCT_SIZE sizeof(BE_CONFIG) // is currently 331 bytes - -/* OBSOLETE, VALUES STILL WORK -typedef enum -{ - NORMAL_QUALITY=0, - LOW_QUALITY, - HIGH_QUALITY, - VOICE_QUALITY -} LAME_QUALTIY_PRESET; - -*/ - - -typedef enum -{ - VBR_METHOD_NONE = -1, - VBR_METHOD_DEFAULT = 0, - VBR_METHOD_OLD = 1, - VBR_METHOD_NEW = 2, - VBR_METHOD_MTRH = 3, - VBR_METHOD_ABR = 4 -} VBRMETHOD; - -typedef enum -{ - LQP_NOPRESET=-1, - - // QUALITY PRESETS - LQP_NORMAL_QUALITY=0, - LQP_LOW_QUALITY, - LQP_HIGH_QUALITY, - LQP_VOICE_QUALITY, - LQP_R3MIX_QUALITY, - LQP_VERYHIGH_QUALITY, - - // NEW PRESET VALUES - LQP_PHONE =1000, - LQP_SW =2000, - LQP_AM =3000, - LQP_FM =4000, - LQP_VOICE =5000, - LQP_RADIO =6000, - LQP_TAPE =7000, - LQP_HIFI =8000, - LQP_CD =9000, - LQP_STUDIO =10000 - -} LAME_QUALTIY_PRESET; - - - -typedef struct { - DWORD dwConfig; // BE_CONFIG_XXXXX - // Currently only BE_CONFIG_MP3 is supported - union { - - struct { - - DWORD dwSampleRate; // 48000, 44100 and 32000 allowed. RG note: also seems to support 16000, 22050, 24000. - BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO - WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed. RG note: also seems to support 8,16,24. - BOOL bPrivate; - BOOL bCRC; - BOOL bCopyright; - BOOL bOriginal; - - } mp3; // BE_CONFIG_MP3 - - struct - { - // STRUCTURE INFORMATION - DWORD dwStructVersion; - DWORD dwStructSize; - - // BASIC ENCODER SETTINGS - DWORD dwSampleRate; // SAMPLERATE OF INPUT FILE - DWORD dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES - LONG nMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO - DWORD dwBitrate; // CBR bitrate, VBR min bitrate - DWORD dwMaxBitrate; // CBR ignored, VBR Max bitrate - LONG nPreset; // Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum - DWORD dwMpegVersion; // FUTURE USE, MPEG-1 OR MPEG-2 - DWORD dwPsyModel; // FUTURE USE, SET TO 0 - DWORD dwEmphasis; // FUTURE USE, SET TO 0 - - // BIT STREAM SETTINGS - BOOL bPrivate; // Set Private Bit (TRUE/FALSE) - BOOL bCRC; // Insert CRC (TRUE/FALSE) - BOOL bCopyright; // Set Copyright Bit (TRUE/FALSE) - BOOL bOriginal; // Set Original Bit (TRUE/FALSE) - - // VBR STUFF - BOOL bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE) - BOOL bEnableVBR; // USE VBR ENCODING (TRUE/FALSE) - INT nVBRQuality; // VBR QUALITY 0..9 - DWORD dwVbrAbr_bps; // Use ABR in stead of nVBRQuality - VBRMETHOD nVbrMethod; - BOOL bNoRes; // Disable Bit resorvoir - - BYTE btReserved[255-3*sizeof(DWORD)]; // FUTURE USE, SET TO 0 - - } LHV1; // LAME header version 1 - - struct { - - DWORD dwSampleRate; - BYTE byMode; - WORD wBitrate; - BYTE byEncodingMethod; - - } aac; - - } format; - -} BE_CONFIG, *PBE_CONFIG; - - -typedef struct { - - // BladeEnc DLL Version number - - BYTE byDLLMajorVersion; - BYTE byDLLMinorVersion; - - // BladeEnc Engine Version Number - - BYTE byMajorVersion; - BYTE byMinorVersion; - - // DLL Release date - - BYTE byDay; - BYTE byMonth; - WORD wYear; - - // BladeEnc Homepage URL - - CHAR zHomepage[BE_MAX_HOMEPAGE + 1]; - - BYTE byAlphaLevel; - BYTE byBetaLevel; - BYTE byMMXEnabled; - - BYTE btReserved[125]; - - -} BE_VERSION, *PBE_VERSION; - -typedef BE_ERR (*BEINITSTREAM) (PBE_CONFIG, PDWORD, PDWORD, PHBE_STREAM); -typedef BE_ERR (*BEENCODECHUNK) (HBE_STREAM, DWORD, PSHORT, PBYTE, PDWORD); -// added for floating point audio -- DSPguru, jd -typedef BE_ERR (*BEENCODECHUNKFLOATS16NI) (HBE_STREAM, DWORD, PFLOAT, PFLOAT, PBYTE, PDWORD); -typedef BE_ERR (*BEDEINITSTREAM) (HBE_STREAM, PBYTE, PDWORD); -typedef BE_ERR (*BECLOSESTREAM) (HBE_STREAM); -typedef VOID (*BEVERSION) (PBE_VERSION); - - - -#define MP3_ERR -1 -#define MP3_OK 0 -#define MP3_NEED_MORE 1 - -// void *InitMP3_Create(); -// void ExitMP3_Delete(void *); - -// int decodeMP3_unclipped(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); -// always uses all of inmemory, returns MP3_NEED_MORE if it needs more, and done is the output size. -// it appears outmemory is interleaved. outmemory is doubles, too. ick. -// is 'done' bytes or samples? inmemsize should be 1152*2*sizeof(double) - -// void get_decode_info(void *,int *nch, int *srate);//JF> added for querying the decode stats -// void remove_buf(void *); - - - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -static HINSTANCE hlamedll; -static BEINITSTREAM beInitStream; -static BECLOSESTREAM beCloseStream; -static BEENCODECHUNKFLOATS16NI beEncodeChunkFloatS16NI; -static BEDEINITSTREAM beDeinitStream; -static BE_ERR (*beWriteInfoTag)(HBE_STREAM, const char *); -static BEVERSION beVersion; -static void *(*InitMP3_Create)(); -static void (*ExitMP3_Delete)(void *); -static int (*decodeMP3_unclipped)(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); -static void (*get_decode_info)(void *,int *nch, int *srate);//JF> added for querying the decode stats -static void (*remove_buf)(void *); - - - -#endif // USE_LAME_BLADE_API - - -#ifdef DYNAMIC_LAME - #ifdef __APPLE__ - #include - #endif - #ifndef _WIN32 - #include - #endif - - -typedef enum MPEG_mode_e { - STEREO = 0, - JOINT_STEREO, - DUAL_CHANNEL, /* LAME doesn't supports this! */ - MONO, - NOT_SET, - MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ -} MPEG_mode; - - -static int (*lame_close)(lame_t); -static lame_t (*lame_init)(); -static int (*lame_set_in_samplerate)(lame_t, int); -static int (*lame_set_num_channels)(lame_t,int); -static int (*lame_set_out_samplerate)(lame_t,int); -static int (*lame_set_quality)(lame_t,int); -static int (*lame_set_mode)(lame_t,MPEG_mode); -static int (*lame_set_brate)(lame_t, int); -static int (*lame_init_params)(lame_t); -static int (*lame_get_framesize)(lame_t); -static int (*lame_set_VBR)(lame_t, int); -static int (*lame_set_VBR_q)(lame_t, int); -static int (*lame_set_VBR_mean_bitrate_kbps)(lame_t, int); -static int (*lame_set_VBR_min_bitrate_kbps)(lame_t, int); -static int (*lame_set_VBR_max_bitrate_kbps)(lame_t, int); - -static size_t (*lame_get_lametag_frame)(lame_t, unsigned char *, size_t); -static int (*lame_encode_buffer_float)(lame_t, - const float buffer_l [], /* PCM data for left channel */ - const float buffer_r [], /* PCM data for right channel */ - const int nsamples, /* number of samples per channel */ - unsigned char* mp3buf, /* pointer to encoded MP3 stream */ - const int mp3buf_size ); -static int (*lame_encode_flush)(lame_t,unsigned char* mp3buf, int size); - -#endif - - -void LameEncoder::InitDLL(const char *extrapath) -{ -#ifdef USE_LAME_BLADE_API - if (!hlamedll) - { -#ifdef _WIN64 - const char *dllName = "lame_enc64.dll"; -#else - const char *dllName = "lame_enc.dll"; -#endif - char me[1024]; - GetModuleFileName(NULL,me,sizeof(me)-64); - - char *p=me; - while (*p) p++; - while(p>=me && *p!='\\') p--; - - strcpy(++p,dllName); - - hlamedll=LoadLibrary(me); - if (extrapath && !hlamedll) - { - lstrcpyn_safe(me,extrapath,sizeof(me)-64); - lstrcatn(me,"\\",sizeof(me)); - lstrcatn(me,dllName,sizeof(me)); - hlamedll=LoadLibrary(me); - } - - if (!hlamedll) hlamedll=LoadLibrary(dllName); - - if (hlamedll) - { - *((void**)&beInitStream) = (void *) GetProcAddress(hlamedll, "beInitStream"); - *((void**)&beCloseStream) = (void *) GetProcAddress(hlamedll, "beCloseStream"); - *((void**)&beEncodeChunkFloatS16NI) = (void *) GetProcAddress(hlamedll, "beEncodeChunkFloatS16NI"); - *((void**)&beDeinitStream) = (void *) GetProcAddress(hlamedll, "beDeinitStream"); - *((void**)&beVersion) = (void *) GetProcAddress(hlamedll, "beVersion"); - *((void**)&beWriteInfoTag) = (void*) GetProcAddress(hlamedll, "beWriteInfoTag"); - *((void**)&InitMP3_Create) = (void *) GetProcAddress(hlamedll,"InitMP3_Create"); - *((void**)&ExitMP3_Delete) = (void *) GetProcAddress(hlamedll,"ExitMP3_Delete"); - *((void**)&decodeMP3_unclipped) = (void *) GetProcAddress(hlamedll,"decodeMP3_unclipped"); - *((void**)&get_decode_info) = (void *) GetProcAddress(hlamedll,"get_decode_info"); - *((void**)&remove_buf) = (void *) GetProcAddress(hlamedll,"remove_buf"); - } - - } -#elif defined(DYNAMIC_LAME) - static int a; - static void *dll; - if (!dll&& (a<100 || extrapath)) // try a bunch of times before giving up - { - a++; -#ifdef _WIN32 - const char *dllname = "libmp3lame.dll"; - #ifdef _WIN64 - const char *dllName2 = "lame_enc64.dll"; - #else - const char *dllName2 = "lame_enc.dll"; - #endif - char me[1024]; - - if (extrapath) - { - lstrcpyn_safe(me,extrapath,sizeof(me)-64); - lstrcatn(me,"\\",sizeof(me)); - lstrcatn(me,dllname,sizeof(me)); - dll=LoadLibrary(me); - if (!dll) - { - lstrcpyn_safe(me,extrapath,sizeof(me)-64); - lstrcatn(me,"\\",sizeof(me)); - lstrcatn(me,dllName2,sizeof(me)); - dll=LoadLibrary(me); - } - } - - if (!dll) - { - GetModuleFileName(NULL,me,sizeof(me)-64); - - char *p=me; - while (*p) p++; - while(p>=me && *p!='\\') p--; - - strcpy(++p,dllname); - - dll=(void*)LoadLibrary(me); - if (!dll) - { - strcpy(p,dllName2); - dll=(void*)LoadLibrary(me); - } - } - if (!dll) dll=LoadLibrary(dllname); - if (!dll) dll=LoadLibrary(dllName2); - -#elif defined(__APPLE__) - if (!dll && extrapath) - { - char me[1024]; - lstrcpyn_safe(me,extrapath,sizeof(me)-64); - lstrcatn(me,"/libmp3lame.dylib",sizeof(me)); - dll = dlopen(me, RTLD_NOW|RTLD_LOCAL); - } - if (!dll) dll = dlopen("/Library/Application Support/libmp3lame.dylib", RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("/usr/lib/libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); - - if (!dll) dll=dlopen("libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); - - if (!dll) - { - CFBundleRef bund=CFBundleGetMainBundle(); - if (bund) - { - CFURLRef url=CFBundleCopyBundleURL(bund); - if (url) - { - char buf[8192]; - if (CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf)-128)) - { - char *p=buf; - while (*p) p++; - while (p>=buf && *p != '/') p--; - if (p>=buf) - { - strcat(buf,"/Contents/Plugins/libmp3lame.dylib"); - if (!dll) dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); - - if (!dll) - { - strcpy(p,"/libmp3lame.dylib"); - dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); - } - if (!dll) - { - strcpy(p,"/Plugins/libmp3lame.dylib"); - if (!dll) dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); - } - } - } - CFRelease(url); - } - } - } -#else // linux default to .so - if (!dll && extrapath) - { - char me[1024]; - lstrcpyn_safe(me,extrapath,sizeof(me)-64); - lstrcatn(me,"/libmp3lame.so",sizeof(me)); - dll = dlopen(me, RTLD_NOW|RTLD_LOCAL); - } - if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.so",RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("/usr/lib/libmp3lame.so",RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("libmp3lame.so",RTLD_NOW|RTLD_LOCAL); - - if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("/usr/lib/libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); - if (!dll) dll=dlopen("libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); - if (!dll) - { - char tmp[64]; - sprintf(tmp,"/proc/%d/exe",getpid()); - char buf[1024]; - buf[0]=0; - if (readlink(tmp,buf,sizeof(buf)-128)>0 && buf[0]) - { - char *p = buf; - while (*p) p++; - while (p>buf && *p != '/') p--; - if (p>buf) - { - strcpy(p,"/Plugins/libmp3lame.so"); - dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); - if (!dll) - { - strcpy(p,"/libmp3lame.so"); - dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); - } - } - } - } -#endif - - if (dll) - { - #ifdef _WIN32 - #define TURD(x) *(void **)&x = GetProcAddress((HINSTANCE)dll,#x); - #else - #define TURD(x) *(void **)&x = dlsym(dll,#x); - #endif - TURD(lame_get_lametag_frame) - TURD(lame_close) - TURD(lame_init) - TURD(lame_set_in_samplerate) - TURD(lame_set_num_channels) - TURD(lame_set_out_samplerate) - TURD(lame_set_quality) - TURD(lame_set_mode) - TURD(lame_set_brate) - TURD(lame_init_params) - TURD(lame_get_framesize) - TURD(lame_encode_buffer_float) - TURD(lame_encode_flush) - TURD(lame_set_VBR) - TURD(lame_set_VBR_q) - TURD(lame_set_VBR_mean_bitrate_kbps) - TURD(lame_set_VBR_min_bitrate_kbps) - TURD(lame_set_VBR_max_bitrate_kbps) - #undef TURD - } - } -#endif -} - -bool LameEncoder::CheckDLL() // returns true if dll is present -{ - InitDLL(); -#ifdef USE_LAME_BLADE_API - if (!beInitStream||!beCloseStream||!beEncodeChunkFloatS16NI||!beDeinitStream||!beVersion) return false; -#elif defined(DYNAMIC_LAME) - if (!lame_close||!lame_init||!lame_set_in_samplerate||!lame_set_num_channels||!lame_set_out_samplerate||!lame_set_quality||!lame_set_mode - ||!lame_set_brate||!lame_init_params||!lame_get_framesize||!lame_encode_buffer_float||!lame_encode_flush) return false; -#endif - return true; -} - -LameEncoder::LameEncoder(int srate, int nch, int bitrate, int stereomode, int quality, int vbrmethod, int vbrquality, int vbrmax, int abr) -{ - errorstat=0; - InitDLL(); -#ifdef USE_LAME_BLADE_API - hbeStream=0; - if (!CheckDLL()) - { - errorstat=1; - return; - } -#else - m_lamestate=0; - if (!CheckDLL()) - { - errorstat=1; - return; - } - m_lamestate=lame_init(); - if (!m_lamestate) - { - errorstat=1; - return; - } -#endif - m_nch=nch; - - -#ifdef USE_LAME_BLADE_API - - m_encoder_nch = stereomode == BE_MP3_MODE_MONO ? 1 : nch; - - BE_CONFIG beConfig; - memset(&beConfig,0,sizeof(beConfig)); - beConfig.dwConfig = BE_CONFIG_LAME; - - beConfig.format.LHV1.dwStructVersion = 1; - beConfig.format.LHV1.dwStructSize = sizeof(beConfig); - beConfig.format.LHV1.dwSampleRate = srate; - if (m_encoder_nch == 1) beConfig.format.LHV1.nMode = BE_MP3_MODE_MONO; - else beConfig.format.LHV1.nMode = stereomode; //bitrate >= 192 ? BE_MP3_MODE_STEREO : BE_MP3_MODE_JSTEREO; - - beConfig.format.LHV1.dwBitrate=bitrate; - beConfig.format.LHV1.dwMaxBitrate=(vbrmethod!=-1?vbrmax:bitrate); - beConfig.format.LHV1.dwReSampleRate = srate; - - // if mpeg 1, and bitrate is less than 32kbps per channel, switch to mpeg 2 - if (beConfig.format.LHV1.dwReSampleRate >= 32000 && beConfig.format.LHV1.dwMaxBitrate/m_encoder_nch <= 32) - { - beConfig.format.LHV1.dwReSampleRate/=2; - } - beConfig.format.LHV1.dwMpegVersion = (beConfig.format.LHV1.dwReSampleRate < 32000 ? MPEG2 : MPEG1); - - beConfig.format.LHV1.nPreset=quality; - - beConfig.format.LHV1.bNoRes = 0;//1; - - beConfig.format.LHV1.bWriteVBRHeader= 1; - beConfig.format.LHV1.bEnableVBR= vbrmethod!=-1; - beConfig.format.LHV1.nVBRQuality= vbrquality; - beConfig.format.LHV1.dwVbrAbr_bps = (vbrmethod!=-1?1000*abr:0); - beConfig.format.LHV1.nVbrMethod=(VBRMETHOD)vbrmethod; - - -/* LAME sets unwise bit if: - if (gfp->short_blocks == short_block_forced || gfp->short_blocks == short_block_dispensed || ((gfp->lowpassfreq == -1) && (gfp->highpassfreq == -1)) || // "-k" - (gfp->scale_left < gfp->scale_right) || - (gfp->scale_left > gfp->scale_right) || - (gfp->disable_reservoir && gfp->brate < 320) || - gfp->noATH || gfp->ATHonly || (nAthType == 0) || gfp->in_samplerate <= 32000) -*/ - - int out_size_bytes=0; - hbeStream=0; - - if (beInitStream(&beConfig, (DWORD*)&in_size_samples, (DWORD*)&out_size_bytes, (PHBE_STREAM) &hbeStream) != BE_ERR_SUCCESSFUL) - { - errorstat=2; - return; - } - in_size_samples/=m_encoder_nch; -#else - m_encoder_nch = stereomode == 3 ? 1 : m_nch; - - lame_set_in_samplerate(m_lamestate, srate); - lame_set_num_channels(m_lamestate,m_encoder_nch); - int outrate=srate; - - int maxbr = (vbrmethod != -1 ? vbrmax : bitrate); - if (outrate>=32000 && maxbr <= 32*m_encoder_nch) outrate/=2; - - lame_set_out_samplerate(m_lamestate,outrate); - lame_set_quality(m_lamestate,(quality>9 ||quality<0) ? 0 : quality); - lame_set_mode(m_lamestate,(MPEG_mode) (m_encoder_nch==1?3 :stereomode )); - lame_set_brate(m_lamestate,bitrate); - - //int vbrmethod (-1 no vbr), int vbrquality (nVBRQuality), int vbrmax, int abr - if (vbrmethod != -1 && lame_set_VBR) - { - int vm=4; // mtrh - if (vbrmethod == 4) vm = 3; //ABR - lame_set_VBR(m_lamestate,vm); - - if (lame_set_VBR_q) lame_set_VBR_q(m_lamestate,vbrquality); - - if (vbrmethod == 4&&lame_set_VBR_mean_bitrate_kbps) - { - lame_set_VBR_mean_bitrate_kbps(m_lamestate,abr); - } - if (lame_set_VBR_max_bitrate_kbps) - { - lame_set_VBR_max_bitrate_kbps(m_lamestate,vbrmax); - } - if (lame_set_VBR_min_bitrate_kbps) - { - lame_set_VBR_min_bitrate_kbps(m_lamestate,bitrate); - } - } - lame_init_params(m_lamestate); - in_size_samples=lame_get_framesize(m_lamestate); - int out_size_bytes=65536; -#endif - - outtmp.Resize(out_size_bytes); - -} - -void LameEncoder::Encode(float *in, int in_spls, int spacing) -{ - - if (errorstat) return; - - if (in_spls > 0) - { - if (m_nch > 1 && m_encoder_nch==1) - { - // downmix - int x; - int pos=0; - int adv=2*spacing; - for (x = 0; x < in_spls; x ++) - { - float f=in[pos]+in[pos+1]; - f*=16383.5f; - spltmp[0].Add(&f,sizeof(float)); - pos+=adv; - } - } - else if (m_encoder_nch > 1) // deinterleave - { - int x; - int pos=0; - int adv=2*spacing; - for (x = 0; x < in_spls; x ++) - { - float f=in[pos]; - f*=32767.0f; - spltmp[0].Add(&f,sizeof(float)); - - f=in[pos+1]; - f*=32767.0f; - spltmp[1].Add(&f,sizeof(float)); - - pos+=adv; - } - } - else - { - int x; - int pos=0; - for (x = 0; x < in_spls; x ++) - { - float f=in[pos]; - f*=32767.0f; - spltmp[0].Add(&f,sizeof(float)); - - pos+=spacing; - } - } - } - for (;;) - { - int a = spltmp[0].Available()/sizeof(float); - if (a >= in_size_samples) a = in_size_samples; - else if (a<1 || in_spls>0) break; // not enough samples available, and not flushing - -#ifdef USE_LAME_BLADE_API - DWORD dwo=0; - if (beEncodeChunkFloatS16NI(hbeStream, a, (float*)spltmp[0].Get(), (float*)spltmp[m_encoder_nch > 1].Get(), - (unsigned char*)outtmp.Get(), &dwo) != BE_ERR_SUCCESSFUL) - { - errorstat=3; - return; - } -// printf("encoded to %d bytes (%d) %d\n",dwo, outtmp.GetSize(),in_size_samples); -#else - int dwo=lame_encode_buffer_float(m_lamestate,(float *)spltmp[0].Get(),(float*)spltmp[m_encoder_nch>1].Get(), - a,(unsigned char *)outtmp.Get(),outtmp.GetSize()); - //printf("encoded %d to %d\n",in_size_samples,dwo); -#endif - outqueue.Add(outtmp.Get(),dwo); - spltmp[0].Advance(a*sizeof(float)); - if (m_encoder_nch > 1) spltmp[1].Advance(a*sizeof(float)); - } - - if (in_spls<1) - { -#ifdef USE_LAME_BLADE_API - DWORD dwo=0; - if (beDeinitStream(hbeStream, (unsigned char *)outtmp.Get(), &dwo) == BE_ERR_SUCCESSFUL && dwo>0) - outqueue.Add(outtmp.Get(),dwo); - -#else - int a=lame_encode_flush(m_lamestate,(unsigned char *)outtmp.Get(),outtmp.GetSize()); - if (a>0) outqueue.Add(outtmp.Get(),a); -#endif - } - - - - spltmp[0].Compact(); - spltmp[1].Compact(); - -} - -#ifdef _WIN32 - -static BOOL HasUTF8(const char *_str) -{ - const unsigned char *str = (const unsigned char *)_str; - if (!str) return FALSE; - while (*str) - { - unsigned char c = *str; - if (c >= 0xC2) // discard overlongs - { - if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; - else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - } - str++; - } - return FALSE; -} -#endif - -LameEncoder::~LameEncoder() -{ -#ifdef USE_LAME_BLADE_API - if (hbeStream) - { - if (m_vbrfile.Get()[0] && beWriteInfoTag) - { - // support UTF-8 filenames - if (HasUTF8(m_vbrfile.Get()) && GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,m_vbrfile.Get(),-1,wf,2048)) - { - FILE *fp = _wfopen(wf,L"r+b"); - if (fp) - { - char tmpspace[1024],tmpfn[2048]; - GetTempPath(sizeof(tmpspace),tmpspace); - GetTempFileName(tmpspace,"lameenc",0,tmpfn); - FILE *tmpfp = fopen(tmpfn,"wb"); - if (tmpfp) - { - fseek(fp,0,SEEK_SET); - int x=32; // 32kb - while(x--) - { - int a =fread(tmpspace,1,sizeof(tmpspace),fp); - if (a<1) break; - fwrite(tmpspace,1,a,tmpfp); - } - - fclose(tmpfp); - - beWriteInfoTag(hbeStream,tmpfn); - hbeStream=0; - - tmpfp = fopen(tmpfn,"r+b"); - if (tmpfp) - { - fseek(tmpfp,0,SEEK_SET); - fseek(fp,0,SEEK_SET); - - x=32; // 32kb - while(x--) - { - int a = fread(tmpspace,1,sizeof(tmpspace),tmpfp); - if (a<1) break; - fwrite(tmpspace,1,a,fp); - } - - fclose(tmpfp); - } - - DeleteFile(tmpfn); - } - fclose(fp); - - } - } - } - - - if (hbeStream) beWriteInfoTag(hbeStream,m_vbrfile.Get()); - } - else beCloseStream(hbeStream); - hbeStream=0; - } -#else - if (m_lamestate) - { - if (m_vbrfile.Get()[0] && lame_get_lametag_frame) - { - unsigned char buf[16384]; - int a=lame_get_lametag_frame(m_lamestate,buf,sizeof(buf)); - if (a>0 && a<=sizeof(buf)) - { - FILE *fp=NULL; -#ifdef _WIN32 - if (HasUTF8(m_vbrfile.Get()) && GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,m_vbrfile.Get(),-1,wf,2048)) - { - fp = _wfopen(wf,L"r+b"); - } - } -#endif - if (!fp) fp = fopen(m_vbrfile.Get(),"r+b"); - if (fp) - { - fseek(fp,0,SEEK_SET); - fwrite(buf,1,a,fp); - fclose(fp); - } - } - } - lame_close(m_lamestate); - m_lamestate=0; - } -#endif -} - -#ifdef USE_LAME_BLADE_API // todo: lame decoding on nonwin32 - -LameDecoder::LameDecoder() -{ - m_samples_remove=1152*2; - m_samplesdec=0; - decinst=0; - errorstat=0; - m_samples_used=0; - m_srate=m_nch=0; - LameEncoder::InitDLL(); - if (!InitMP3_Create||!ExitMP3_Delete||!decodeMP3_unclipped||!get_decode_info||!remove_buf) - { - errorstat=1; - return; - } - - decinst=InitMP3_Create(); - -} - -void LameDecoder::DecodeWrote(int srclen) -{ - if (errorstat||!decinst) return; - - for (;;) - { - double buf[1152*2]; - int bout; - //decodeMP3_unclipped(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); - int ret=decodeMP3_unclipped(decinst,(unsigned char *)srctmp.Get(),srclen,(char *)buf,sizeof(buf),&bout); - if (ret == MP3_ERR) { errorstat=1; break; } - if (ret == MP3_NEED_MORE) { break; } - - if (ret == MP3_OK) - { - if (!m_srate || !m_nch) get_decode_info(decinst,&m_nch,&m_srate); - bout /= sizeof(double); - - int bout_pairs=bout/m_nch; - double *bufptr=buf; - - - if (bout > 0) - { - int x; - int newsize=(m_samples_used+bout+4096)*sizeof(float); - if (m_samples.GetSize() < newsize) m_samples.Resize(newsize); - - float *fbuf=(float *)m_samples.Get(); - fbuf += m_samples_used; - - m_samplesdec += bout_pairs; - m_samples_used+=bout; - - for (x = 0; x < bout; x ++) - { - fbuf[x]=(float)(bufptr[x] * (1.0/32767.0)); - } - } - } - - srclen=0; - } -} - -void LameDecoder::Reset() -{ - m_samples_remove=1152*2; - m_samples_used=0; - m_samplesdec=0; - - //if (decinst) remove_buf(decinst); -/* - if (decinst) - { - ExitMP3_Delete(decinst); - } - decinst=InitMP3_Create(); - */ -} - -LameDecoder::~LameDecoder() -{ - if (decinst) - { - ExitMP3_Delete(decinst); - } -} -#endif diff --git a/WDL/lameencdec.h b/WDL/lameencdec.h deleted file mode 100644 index f7778f36..00000000 --- a/WDL/lameencdec.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - WDL - lameencdec.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides a simple interface for using lame_enc.dll on Windows for MP3 encoding and decoding. - -*/ - - -#ifndef _LAMEENCDEC_H_ -#define _LAMEENCDEC_H_ - -#include "queue.h" -#include "wdlstring.h" - -#ifdef _WIN32 - #ifndef _WIN64 - #define USE_LAME_BLADE_API - #endif -#endif - -#ifndef USE_LAME_BLADE_API - #define DYNAMIC_LAME - - #ifdef DYNAMIC_LAME - typedef void *lame_t; - #else - #include - #endif -#endif - - - -class LameEncoder -{ - public: - - LameEncoder(int srate, int nch, int bitrate, int stereomode = 1, int quality = 0, int vbrmethod = -1, int vbrquality = 2, int vbrmax = 320, int abr = 128); - ~LameEncoder(); - - int Status() { return errorstat; } // 1=no dll, 2=error - - void Encode(float *in, int in_spls, int spacing=1); - - WDL_Queue outqueue; - - void reinit() - { - spltmp[0].Advance(spltmp[0].Available()); - spltmp[0].Compact(); - spltmp[1].Advance(spltmp[1].Available()); - spltmp[1].Compact(); - } - - static bool CheckDLL(); // returns true if dll is present - static void InitDLL(const char *extrapath=NULL); // call with extrapath != NULL if you want to try loading from another path - - void SetVBRFilename(const char *fn) - { - m_vbrfile.Set(fn); - } - - int GetNumChannels() { return m_encoder_nch; } - - private: - int m_nch,m_encoder_nch; - WDL_Queue spltmp[2]; - WDL_HeapBuf outtmp; - WDL_String m_vbrfile; - int errorstat; - int in_size_samples; -#ifdef USE_LAME_BLADE_API - UINT_PTR hbeStream; -#else - lame_t m_lamestate; -#endif -}; - -class LameDecoder -{ - public: - LameDecoder(); - ~LameDecoder(); - - int GetSampleRate() { return m_srate?m_srate:48000; } - int GetNumChannels() { return m_nch?m_nch:1; } - - WDL_HeapBuf m_samples; // we let the size get as big as it needs to, so we don't worry about tons of mallocs/etc - int m_samples_used; - - void *DecodeGetSrcBuffer(int srclen) - { - if (srctmp.GetSize() < srclen) srctmp.Resize(srclen); - return srctmp.Get(); - } - void DecodeWrote(int srclen); - - int GetError() { return errorstat; } - - void Reset(); - - int m_samplesdec; - - private: - WDL_HeapBuf srctmp; - int errorstat; - int m_srate,m_nch; - int m_samples_remove; - -#ifdef USE_LAME_BLADE_API - void *decinst; -#else - lame_t *decinst; -#endif -}; - - - -#endif diff --git a/WDL/libpng/LICENSE b/WDL/libpng/LICENSE deleted file mode 100644 index 00787509..00000000 --- a/WDL/libpng/LICENSE +++ /dev/null @@ -1,111 +0,0 @@ - -This copy of the libpng notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail. - -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - -If you modify libpng you may insert additional notices immediately following -this sentence. - -This code is released under the libpng license. - -libpng versions 1.2.6, August 15, 2004, through 1.5.8, February 1, 2012, are -Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.2.5 -with the following individual added to the list of Contributing Authors - - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are -Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6 -with the following individuals added to the list of Contributing Authors - - Simon-Pierre Cadieux - Eric S. Raymond - Gilles Vollant - -and with the following additions to the disclaimer: - - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. - -libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-0.96, -with the following individuals added to the list of Contributing Authors: - - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik - -libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88, -with the following individuals added to the list of Contributing Authors: - - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner - -libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. - -For the purposes of this copyright and license, "Contributing Authors" -is defined as the following set of individuals: - - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. - -Permission is hereby granted to use, copy, modify, and distribute this -source code, or portions hereof, for any purpose, without fee, subject -to the following restrictions: - -1. The origin of this source code must not be misrepresented. - -2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. - -3. This Copyright notice may not be removed or altered from any - source or altered source distribution. - -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. - - -A "png_get_copyright" function is available, for convenient use in "about" -boxes and the like: - - printf("%s",png_get_copyright(NULL)); - -Also, the PNG logo (in PNG format, of course) is supplied in the -files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a -certification mark of the Open Source Initiative. - -Glenn Randers-Pehrson -glennrp at users.sourceforge.net -February 1, 2012 diff --git a/WDL/libpng/README b/WDL/libpng/README deleted file mode 100644 index c9dc29ef..00000000 --- a/WDL/libpng/README +++ /dev/null @@ -1,202 +0,0 @@ -README for libpng version 1.5.8 - February 1, 2012 (shared library 15.0) -See the note about version numbers near the top of png.h - -See INSTALL for instructions on how to install libpng. - -Libpng comes in several distribution formats. Get libpng-*.tar.gz, -libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings -in the text files, or lpng*.zip if you want DOS-style line endings. - -Version 0.89 was the first official release of libpng. Don't let the -fact that it's the first release fool you. The libpng library has been in -extensive use and testing since mid-1995. By late 1997 it had -finally gotten to the stage where there hadn't been significant -changes to the API in some time, and people have a bad feeling about -libraries with versions < 1.0. Version 1.0.0 was released in -March 1998. - -**** -Note that some of the changes to the png_info structure render this -version of the library binary incompatible with libpng-0.89 or -earlier versions if you are using a shared library. The type of the -"filler" parameter for png_set_filler() has changed from png_byte to -png_uint_32, which will affect shared-library applications that use -this function. - -To avoid problems with changes to the internals of png_info_struct, -new APIs have been made available in 0.95 to avoid direct application -access to info_ptr. These functions are the png_set_ and -png_get_ functions. These functions should be used when -accessing/storing the info_struct data, rather than manipulating it -directly, to avoid such problems in the future. - -It is important to note that the APIs do not make current programs -that access the info struct directly incompatible with the new -library. However, it is strongly suggested that new programs use -the new APIs (as shown in example.c and pngtest.c), and older programs -be converted to the new format, to facilitate upgrades in the future. -**** - -Additions since 0.90 include the ability to compile libpng as a -Windows DLL, and new APIs for accessing data in the info struct. -Experimental functions include the ability to set weighting and cost -factors for row filter selection, direct reads of integers from buffers -on big-endian processors that support misaligned data access, faster -methods of doing alpha composition, and more accurate 16->8 bit color -conversion. - -The additions since 0.89 include the ability to read from a PNG stream -which has had some (or all) of the signature bytes read by the calling -application. This also allows the reading of embedded PNG streams that -do not have the PNG file signature. As well, it is now possible to set -the library action on the detection of chunk CRC errors. It is possible -to set different actions based on whether the CRC error occurred in a -critical or an ancillary chunk. - -The changes made to the library, and bugs fixed are based on discussions -on the PNG-implement mailing list and not on material submitted -privately to Guy, Andreas, or Glenn. They will forward any good -suggestions to the list. - -For a detailed description on using libpng, read libpng-manual.txt. For -examples of libpng in a program, see example.c and pngtest.c. For usage -information and restrictions (what little they are) on libpng, see -png.h. For a description on using zlib (the compression library used by -libpng) and zlib's restrictions, see zlib.h - -I have included a general makefile, as well as several machine and -compiler specific ones, but you may have to modify one for your own needs. - -You should use zlib 1.0.4 or later to run this, but it MAY work with -versions as old as zlib 0.95. Even so, there are bugs in older zlib -versions which can cause the output of invalid compression streams for -some images. You will definitely need zlib 1.0.4 or later if you are -taking advantage of the MS-DOS "far" structure allocation for the small -and medium memory models. You should also note that zlib is a -compression library that is useful for more things than just PNG files. -You can use zlib as a drop-in replacement for fread() and fwrite() if -you are so inclined. - -zlib should be available at the same place that libpng is, or at. -ftp://ftp.info-zip.org/pub/infozip/zlib - -You may also want a copy of the PNG specification. It is available -as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find -these at http://www.libpng.org/pub/png/documents/ - -This code is currently being archived at libpng.sf.net in the -[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) -at GO GRAPHSUP. If you can't find it in any of those places, -e-mail me, and I'll help you find it. - -If you have any code changes, requests, problems, etc., please e-mail -them to me. Also, I'd appreciate any make files or project files, -and any modifications you needed to make to get libpng to compile, -along with a #define variable to tell what compiler/system you are on. -If you needed to add transformations to libpng, or wish libpng would -provide the image in a different way, drop me a note (and code, if -possible), so I can consider supporting the transformation. -Finally, if you get any warning messages when compiling libpng -(note: not zlib), and they are easy to fix, I'd appreciate the -fix. Please mention "libpng" somewhere in the subject line. Thanks. - -This release was created and will be supported by myself (of course -based in a large way on Guy's and Andreas' earlier work), and the PNG -development group. - -Send comments/corrections/commendations to png-mng-implement at -lists.sourceforge.net (subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) or to glennrp at users.sourceforge.net - -You can't reach Guy, the original libpng author, at the addresses -given in previous versions of this document. He and Andreas will -read mail addressed to the png-implement list, however. - -Please do not send general questions about PNG. Send them to -png-mng-misc at lists.sf.net (subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-misc to -subscribe). If you have a question about something -in the PNG specification that is related to using libpng, send it -to me. Send me any questions that start with "I was using libpng, -and ...". If in doubt, send questions to me. I'll bounce them -to others, if necessary. - -Please do not send suggestions on how to change PNG. We have -been discussing PNG for sixteen years now, and it is official and -finished. If you have suggestions for libpng, however, I'll -gladly listen. Even if your suggestion is not used immediately, -it may be used later. - -Files in this distribution: - - ANNOUNCE => Announcement of this version, with recent changes - CHANGES => Description of changes between libpng versions - KNOWNBUG => List of known bugs and deficiencies - LICENSE => License to use and redistribute libpng - README => This file - TODO => Things not implemented in the current library - Y2KINFO => Statement of Y2K compliance - example.c => Example code for using libpng functions - libpng.3 => manual page for libpng (includes libpng-manual.txt) - libpng-manual.txt => Description of libpng and its functions - libpngpf.3 => manual page for libpng's private functions - png.5 => manual page for the PNG format - png.c => Basic interface functions common to library - png.h => Library function and interface declarations (public) - pngpriv.h => Library function and interface declarations (private) - pngconf.h => System specific library configuration (public) - pngstruct.h => png_struct declaration (private) - pnginfo.h => png_info struct declaration (private) - pngdebug.h => debugging macros (private) - pngerror.c => Error/warning message I/O functions - pngget.c => Functions for retrieving info from struct - pngmem.c => Memory handling functions - pngbar.png => PNG logo, 88x31 - pngnow.png => PNG logo, 98x31 - pngpread.c => Progressive reading functions - pngread.c => Read data/helper high-level functions - pngrio.c => Lowest-level data read I/O functions - pngrtran.c => Read data transformation functions - pngrutil.c => Read data utility functions - pngset.c => Functions for storing data into the info_struct - pngtest.c => Library test program - pngtest.png => Library test sample image - pngtrans.c => Common data transformation functions - pngwio.c => Lowest-level write I/O functions - pngwrite.c => High-level write functions - pngwtran.c => Write data transformations - pngwutil.c => Write utility functions - contrib => Contributions - gregbook => source code for PNG reading and writing, from - Greg Roelofs' "PNG: The Definitive Guide", - O'Reilly, 1999 - msvctest => Builds and runs pngtest using a MSVC workspace - pngminus => Simple pnm2png and png2pnm programs - pngsuite => Test images - visupng => Contains a MSVC workspace for VisualPng - projects => Contains project files and workspaces for - building a DLL - cbuilder5 => Contains a Borland workspace for building - libpng and zlib - visualc6 => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib - visualc71 => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib - xcode => Contains an Apple xcode - workspace for building libpng and zlib - scripts => Directory containing scripts for building libpng: - (see scripts/README.txt for the list of scripts) - -Good luck, and happy coding. - --Glenn Randers-Pehrson (current maintainer, since 1998) - Internet: glennrp at users.sourceforge.net - --Andreas Eric Dilger (former maintainer, 1996-1997) - Internet: adilger at enel.ucalgary.ca - Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ - --Guy Eric Schalnat (original author and former maintainer, 1995-1996) - (formerly of Group 42, Inc) - Internet: gschal at infinet.com diff --git a/WDL/libpng/png.c b/WDL/libpng/png.c deleted file mode 100644 index 80e90a8b..00000000 --- a/WDL/libpng/png.c +++ /dev/null @@ -1,2870 +0,0 @@ - -/* png.c - location for general purpose libpng functions - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_5_8 Your_png_h_is_not_version_1_5_8; - -/* Tells libpng that we have already handled the first "num_bytes" bytes - * of the PNG file signature. If the PNG data is embedded into another - * stream we can set num_bytes = 8 so that libpng will not attempt to read - * or write any of the magic bytes before it starts on the IHDR. - */ - -#ifdef PNG_READ_SUPPORTED -void PNGAPI -png_set_sig_bytes(png_structp png_ptr, int num_bytes) -{ - png_debug(1, "in png_set_sig_bytes"); - - if (png_ptr == NULL) - return; - - if (num_bytes > 8) - png_error(png_ptr, "Too many bytes for PNG signature"); - - png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); -} - -/* Checks whether the supplied bytes match the PNG signature. We allow - * checking less than the full 8-byte signature so that those apps that - * already read the first few bytes of a file to determine the file type - * can simply check the remaining bytes for extra assurance. Returns - * an integer less than, equal to, or greater than zero if sig is found, - * respectively, to be less than, to match, or be greater than the correct - * PNG signature (this is the same behavior as strcmp, memcmp, etc). - */ -int PNGAPI -png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - - if (num_to_check > 8) - num_to_check = 8; - - else if (num_to_check < 1) - return (-1); - - if (start > 7) - return (-1); - - if (start + num_to_check > 8) - num_to_check = 8 - start; - - return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); -} - -#endif /* PNG_READ_SUPPORTED */ - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Function to allocate memory for zlib */ -PNG_FUNCTION(voidpf /* PRIVATE */, -png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) -{ - png_voidp ptr; - png_structp p=(png_structp)png_ptr; - png_uint_32 save_flags=p->flags; - png_alloc_size_t num_bytes; - - if (png_ptr == NULL) - return (NULL); - - if (items > PNG_UINT_32_MAX/size) - { - png_warning (p, "Potential overflow in png_zalloc()"); - return (NULL); - } - num_bytes = (png_alloc_size_t)items * size; - - p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; - ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); - p->flags=save_flags; - - return ((voidpf)ptr); -} - -/* Function to free memory for zlib */ -void /* PRIVATE */ -png_zfree(voidpf png_ptr, voidpf ptr) -{ - png_free((png_structp)png_ptr, (png_voidp)ptr); -} - -/* Reset the CRC variable to 32 bits of 1's. Care must be taken - * in case CRC is > 32 bits to leave the top bits 0. - */ -void /* PRIVATE */ -png_reset_crc(png_structp png_ptr) -{ - /* The cast is safe because the crc is a 32 bit value. */ - png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); -} - -/* Calculate the CRC over a section of data. We can only pass as - * much data to this routine as the largest single buffer size. We - * also check that this data will actually be used before going to the - * trouble of calculating it. - */ -void /* PRIVATE */ -png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) -{ - int need_crc = 1; - - if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) - need_crc = 0; - } - - /* 'uLong' is defined as unsigned long, this means that on some systems it is - * a 64 bit value. crc32, however, returns 32 bits so the following cast is - * safe. 'uInt' may be no more than 16 bits, so it is necessary to perform a - * loop here. - */ - if (need_crc && length > 0) - { - uLong crc = png_ptr->crc; /* Should never issue a warning */ - - do - { - uInt safeLength = (uInt)length; - if (safeLength == 0) - safeLength = (uInt)-1; /* evil, but safe */ - - crc = crc32(crc, ptr, safeLength); - - /* The following should never issue compiler warnings, if they do the - * target system has characteristics that will probably violate other - * assumptions within the libpng code. - */ - ptr += safeLength; - length -= safeLength; - } - while (length > 0); - - /* And the following is always safe because the crc is only 32 bits. */ - png_ptr->crc = (png_uint_32)crc; - } -} - -/* Check a user supplied version number, called from both read and write - * functions that create a png_struct - */ -int -png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver) -{ - if (user_png_ver) - { - int i = 0; - - do - { - if (user_png_ver[i] != png_libpng_ver[i]) - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - } while (png_libpng_ver[i++]); - } - - else - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - - if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) - { - /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so - * we must recompile any applications that use any older library version. - * For versions after libpng 1.0, we will be compatible, so we need - * only check the first digit. - */ - if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || - (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || - (user_png_ver[0] == '0' && user_png_ver[2] < '9')) - { -#ifdef PNG_WARNINGS_SUPPORTED - size_t pos = 0; - char m[128]; - - pos = png_safecat(m, sizeof m, pos, "Application built with libpng-"); - pos = png_safecat(m, sizeof m, pos, user_png_ver); - pos = png_safecat(m, sizeof m, pos, " but running with "); - pos = png_safecat(m, sizeof m, pos, png_libpng_ver); - - png_warning(png_ptr, m); -#endif - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags = 0; -#endif - - return 0; - } - } - - /* Success return. */ - return 1; -} - -/* Allocate the memory for an info_struct for the application. We don't - * really need the png_ptr, but it could potentially be useful in the - * future. This should be used in favour of malloc(png_sizeof(png_info)) - * and png_info_init() so that applications that want to use a shared - * libpng don't have to be recompiled if png_info changes size. - */ -PNG_FUNCTION(png_infop,PNGAPI -png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) -{ - png_infop info_ptr; - - png_debug(1, "in png_create_info_struct"); - - if (png_ptr == NULL) - return (NULL); - -#ifdef PNG_USER_MEM_SUPPORTED - info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, - png_ptr->malloc_fn, png_ptr->mem_ptr); -#else - info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); -#endif - if (info_ptr != NULL) - png_info_init_3(&info_ptr, png_sizeof(png_info)); - - return (info_ptr); -} - -/* This function frees the memory associated with a single info struct. - * Normally, one would use either png_destroy_read_struct() or - * png_destroy_write_struct() to free an info struct, but this may be - * useful for some applications. - */ -void PNGAPI -png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) -{ - png_infop info_ptr = NULL; - - png_debug(1, "in png_destroy_info_struct"); - - if (png_ptr == NULL) - return; - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - png_info_destroy(png_ptr, info_ptr); - -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, - png_ptr->mem_ptr); -#else - png_destroy_struct((png_voidp)info_ptr); -#endif - *info_ptr_ptr = NULL; - } -} - -/* Initialize the info structure. This is now an internal function (0.89) - * and applications using it are urged to use png_create_info_struct() - * instead. - */ - -void PNGAPI -png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) -{ - png_infop info_ptr = *ptr_ptr; - - png_debug(1, "in png_info_init_3"); - - if (info_ptr == NULL) - return; - - if (png_sizeof(png_info) > png_info_struct_size) - { - png_destroy_struct(info_ptr); - info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); - *ptr_ptr = info_ptr; - } - - /* Set everything to 0 */ - png_memset(info_ptr, 0, png_sizeof(png_info)); -} - -void PNGAPI -png_data_freer(png_structp png_ptr, png_infop info_ptr, - int freer, png_uint_32 mask) -{ - png_debug(1, "in png_data_freer"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (freer == PNG_DESTROY_WILL_FREE_DATA) - info_ptr->free_me |= mask; - - else if (freer == PNG_USER_WILL_FREE_DATA) - info_ptr->free_me &= ~mask; - - else - png_warning(png_ptr, - "Unknown freer parameter in png_data_freer"); -} - -void PNGAPI -png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, - int num) -{ - png_debug(1, "in png_free_data"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -#ifdef PNG_TEXT_SUPPORTED - /* Free text item num or (if num == -1) all text items */ - if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) - { - if (num != -1) - { - if (info_ptr->text && info_ptr->text[num].key) - { - png_free(png_ptr, info_ptr->text[num].key); - info_ptr->text[num].key = NULL; - } - } - - else - { - int i; - for (i = 0; i < info_ptr->num_text; i++) - png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - info_ptr->num_text=0; - } - } -#endif - -#ifdef PNG_tRNS_SUPPORTED - /* Free any tRNS entry */ - if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) - { - png_free(png_ptr, info_ptr->trans_alpha); - info_ptr->trans_alpha = NULL; - info_ptr->valid &= ~PNG_INFO_tRNS; - } -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* Free any sCAL entry */ - if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) - { - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); - info_ptr->scal_s_width = NULL; - info_ptr->scal_s_height = NULL; - info_ptr->valid &= ~PNG_INFO_sCAL; - } -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* Free any pCAL entry */ - if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) - { - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; - if (info_ptr->pcal_params != NULL) - { - int i; - for (i = 0; i < (int)info_ptr->pcal_nparams; i++) - { - png_free(png_ptr, info_ptr->pcal_params[i]); - info_ptr->pcal_params[i] = NULL; - } - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } - info_ptr->valid &= ~PNG_INFO_pCAL; - } -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* Free any iCCP entry */ - if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) - { - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); - info_ptr->iccp_name = NULL; - info_ptr->iccp_profile = NULL; - info_ptr->valid &= ~PNG_INFO_iCCP; - } -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ - if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) - { - if (num != -1) - { - if (info_ptr->splt_palettes) - { - png_free(png_ptr, info_ptr->splt_palettes[num].name); - png_free(png_ptr, info_ptr->splt_palettes[num].entries); - info_ptr->splt_palettes[num].name = NULL; - info_ptr->splt_palettes[num].entries = NULL; - } - } - - else - { - if (info_ptr->splt_palettes_num) - { - int i; - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; - info_ptr->splt_palettes_num = 0; - } - info_ptr->valid &= ~PNG_INFO_sPLT; - } - } -#endif - -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - if (png_ptr->unknown_chunk.data) - { - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - - if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) - { - if (num != -1) - { - if (info_ptr->unknown_chunks) - { - png_free(png_ptr, info_ptr->unknown_chunks[num].data); - info_ptr->unknown_chunks[num].data = NULL; - } - } - - else - { - int i; - - if (info_ptr->unknown_chunks_num) - { - for (i = 0; i < info_ptr->unknown_chunks_num; i++) - png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; - info_ptr->unknown_chunks_num = 0; - } - } - } -#endif - -#ifdef PNG_hIST_SUPPORTED - /* Free any hIST entry */ - if ((mask & PNG_FREE_HIST) & info_ptr->free_me) - { - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; - info_ptr->valid &= ~PNG_INFO_hIST; - } -#endif - - /* Free any PLTE entry that was internally allocated */ - if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) - { - png_zfree(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= ~PNG_INFO_PLTE; - info_ptr->num_palette = 0; - } - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Free any image bits attached to the info structure */ - if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) - { - if (info_ptr->row_pointers) - { - int row; - for (row = 0; row < (int)info_ptr->height; row++) - { - png_free(png_ptr, info_ptr->row_pointers[row]); - info_ptr->row_pointers[row] = NULL; - } - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers = NULL; - } - info_ptr->valid &= ~PNG_INFO_IDAT; - } -#endif - - if (num != -1) - mask &= ~PNG_FREE_MUL; - - info_ptr->free_me &= ~mask; -} - -/* This is an internal routine to free any memory that the info struct is - * pointing to before re-using it or freeing the struct itself. Recall - * that png_free() checks for NULL pointers for us. - */ -void /* PRIVATE */ -png_info_destroy(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_info_destroy"); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; - png_ptr->num_chunk_list = 0; - } -#endif - - png_info_init_3(&info_ptr, png_sizeof(png_info)); -} -#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ - -/* This function returns a pointer to the io_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy() or png_read_destroy() are called. - */ -png_voidp PNGAPI -png_get_io_ptr(png_structp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return (png_ptr->io_ptr); -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -# ifdef PNG_STDIO_SUPPORTED -/* Initialize the default input/output functions for the PNG file. If you - * use your own read or write routines, you can call either png_set_read_fn() - * or png_set_write_fn() instead of png_init_io(). If you have defined - * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a - * function of your own because "FILE *" isn't necessarily available. - */ -void PNGAPI -png_init_io(png_structp png_ptr, png_FILE_p fp) -{ - png_debug(1, "in png_init_io"); - - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = (png_voidp)fp; -} -# endif - -# ifdef PNG_TIME_RFC1123_SUPPORTED -/* Convert the supplied time into an RFC 1123 string suitable for use in - * a "Creation Time" or other text-based time string. - */ -png_const_charp PNGAPI -png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) -{ - static PNG_CONST char short_months[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - if (png_ptr == NULL) - return (NULL); - - if (ptime->year > 9999 /* RFC1123 limitation */ || - ptime->month == 0 || ptime->month > 12 || - ptime->day == 0 || ptime->day > 31 || - ptime->hour > 23 || ptime->minute > 59 || - ptime->second > 60) - { - png_warning(png_ptr, "Ignoring invalid time value"); - return (NULL); - } - - { - size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ - -# define APPEND_STRING(string)\ - pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\ - pos, (string)) -# define APPEND_NUMBER(format, value)\ - APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) -# define APPEND(ch)\ - if (pos < (sizeof png_ptr->time_buffer)-1)\ - png_ptr->time_buffer[pos++] = (ch) - - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); - APPEND(' '); - APPEND_STRING(short_months[(ptime->month - 1)]); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); - APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ - -# undef APPEND -# undef APPEND_NUMBER -# undef APPEND_STRING - } - - return png_ptr->time_buffer; -} -# endif /* PNG_TIME_RFC1123_SUPPORTED */ - -#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ - -png_const_charp PNGAPI -png_get_copyright(png_const_structp png_ptr) -{ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef PNG_STRING_COPYRIGHT - return PNG_STRING_COPYRIGHT -#else -# ifdef __STDC__ - return PNG_STRING_NEWLINE \ - "libpng version 1.5.8 - February 1, 2012" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; -# else - return "libpng version 1.5.8 - February 1, 2012\ - Copyright (c) 1998-2011 Glenn Randers-Pehrson\ - Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; -# endif -#endif -} - -/* The following return the library version as a short string in the - * format 1.0.0 through 99.99.99zz. To get the version of *.h files - * used with your application, print out PNG_LIBPNG_VER_STRING, which - * is defined in png.h. - * Note: now there is no difference between png_get_libpng_ver() and - * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, - * it is guaranteed that png.c uses the correct version of png.h. - */ -png_const_charp PNGAPI -png_get_libpng_ver(png_const_structp png_ptr) -{ - /* Version of *.c files used when building libpng */ - return png_get_header_ver(png_ptr); -} - -png_const_charp PNGAPI -png_get_header_ver(png_const_structp png_ptr) -{ - /* Version of *.h files used when building libpng */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ - return PNG_LIBPNG_VER_STRING; -} - -png_const_charp PNGAPI -png_get_header_version(png_const_structp png_ptr) -{ - /* Returns longer string containing both version and date */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef __STDC__ - return PNG_HEADER_VERSION_STRING -# ifndef PNG_READ_SUPPORTED - " (NO READ SUPPORT)" -# endif - PNG_STRING_NEWLINE; -#else - return PNG_HEADER_VERSION_STRING; -#endif -} - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -int PNGAPI -png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) -{ - /* Check chunk_name and return "keep" value if it's on the list, else 0 */ - png_const_bytep p, p_end; - - if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0) - return PNG_HANDLE_CHUNK_AS_DEFAULT; - - p_end = png_ptr->chunk_list; - p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ - - /* The code is the fifth byte after each four byte string. Historically this - * code was always searched from the end of the list, so it should continue - * to do so in case there are duplicated entries. - */ - do /* num_chunk_list > 0, so at least one */ - { - p -= 5; - if (!png_memcmp(chunk_name, p, 4)) - return p[4]; - } - while (p > p_end); - - return PNG_HANDLE_CHUNK_AS_DEFAULT; -} - -int /* PRIVATE */ -png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name) -{ - png_byte chunk_string[5]; - - PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); - return png_handle_as_unknown(png_ptr, chunk_string); -} -#endif - -#ifdef PNG_READ_SUPPORTED -/* This function, added to libpng-1.0.6g, is untested. */ -int PNGAPI -png_reset_zstream(png_structp png_ptr) -{ - if (png_ptr == NULL) - return Z_STREAM_ERROR; - - return (inflateReset(&png_ptr->zstream)); -} -#endif /* PNG_READ_SUPPORTED */ - -/* This function was added to libpng-1.0.7 */ -png_uint_32 PNGAPI -png_access_version_number(void) -{ - /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); -} - - - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* png_convert_size: a PNGAPI but no longer in png.h, so deleted - * at libpng 1.5.5! - */ - -/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -# ifdef PNG_CHECK_cHRM_SUPPORTED - -int /* PRIVATE */ -png_check_cHRM_fixed(png_structp png_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) -{ - int ret = 1; - unsigned long xy_hi,xy_lo,yx_hi,yx_lo; - - png_debug(1, "in function png_check_cHRM_fixed"); - - if (png_ptr == NULL) - return 0; - - /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white - * y must also be greater than 0. To test for the upper limit calculate - * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression - * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is - * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it - * pointless (and it produces compiler warnings!) - */ - if (white_x < 0 || white_y <= 0 || - red_x < 0 || red_y < 0 || - green_x < 0 || green_y < 0 || - blue_x < 0 || blue_y < 0) - { - png_warning(png_ptr, - "Ignoring attempt to set negative chromaticity value"); - ret = 0; - } - /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ - if (white_x > PNG_FP_1 - white_y) - { - png_warning(png_ptr, "Invalid cHRM white point"); - ret = 0; - } - - if (red_x > PNG_FP_1 - red_y) - { - png_warning(png_ptr, "Invalid cHRM red point"); - ret = 0; - } - - if (green_x > PNG_FP_1 - green_y) - { - png_warning(png_ptr, "Invalid cHRM green point"); - ret = 0; - } - - if (blue_x > PNG_FP_1 - blue_y) - { - png_warning(png_ptr, "Invalid cHRM blue point"); - ret = 0; - } - - png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); - png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); - - if (xy_hi == yx_hi && xy_lo == yx_lo) - { - png_warning(png_ptr, - "Ignoring attempt to set cHRM RGB triangle with zero area"); - ret = 0; - } - - return ret; -} -# endif /* PNG_CHECK_cHRM_SUPPORTED */ - -#ifdef PNG_cHRM_SUPPORTED -/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for - * cHRM, as opposed to using chromaticities. These internal APIs return - * non-zero on a parameter error. The X, Y and Z values are required to be - * positive and less than 1.0. - */ -int png_xy_from_XYZ(png_xy *xy, png_XYZ XYZ) -{ - png_int_32 d, dwhite, whiteX, whiteY; - - d = XYZ.redX + XYZ.redY + XYZ.redZ; - if (!png_muldiv(&xy->redx, XYZ.redX, PNG_FP_1, d)) return 1; - if (!png_muldiv(&xy->redy, XYZ.redY, PNG_FP_1, d)) return 1; - dwhite = d; - whiteX = XYZ.redX; - whiteY = XYZ.redY; - - d = XYZ.greenX + XYZ.greenY + XYZ.greenZ; - if (!png_muldiv(&xy->greenx, XYZ.greenX, PNG_FP_1, d)) return 1; - if (!png_muldiv(&xy->greeny, XYZ.greenY, PNG_FP_1, d)) return 1; - dwhite += d; - whiteX += XYZ.greenX; - whiteY += XYZ.greenY; - - d = XYZ.blueX + XYZ.blueY + XYZ.blueZ; - if (!png_muldiv(&xy->bluex, XYZ.blueX, PNG_FP_1, d)) return 1; - if (!png_muldiv(&xy->bluey, XYZ.blueY, PNG_FP_1, d)) return 1; - dwhite += d; - whiteX += XYZ.blueX; - whiteY += XYZ.blueY; - - /* The reference white is simply the same of the end-point (X,Y,Z) vectors, - * thus: - */ - if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1; - if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1; - - return 0; -} - -int png_XYZ_from_xy(png_XYZ *XYZ, png_xy xy) -{ - png_fixed_point red_inverse, green_inverse, blue_scale; - png_fixed_point left, right, denominator; - - /* Check xy and, implicitly, z. Note that wide gamut color spaces typically - * have end points with 0 tristimulus values (these are impossible end - * points, but they are used to cover the possible colors.) - */ - if (xy.redx < 0 || xy.redx > PNG_FP_1) return 1; - if (xy.redy < 0 || xy.redy > PNG_FP_1-xy.redx) return 1; - if (xy.greenx < 0 || xy.greenx > PNG_FP_1) return 1; - if (xy.greeny < 0 || xy.greeny > PNG_FP_1-xy.greenx) return 1; - if (xy.bluex < 0 || xy.bluex > PNG_FP_1) return 1; - if (xy.bluey < 0 || xy.bluey > PNG_FP_1-xy.bluex) return 1; - if (xy.whitex < 0 || xy.whitex > PNG_FP_1) return 1; - if (xy.whitey < 0 || xy.whitey > PNG_FP_1-xy.whitex) return 1; - - /* The reverse calculation is more difficult because the original tristimulus - * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 - * derived values were recorded in the cHRM chunk; - * (red,green,blue,white)x(x,y). This loses one degree of freedom and - * therefore an arbitrary ninth value has to be introduced to undo the - * original transformations. - * - * Think of the original end-points as points in (X,Y,Z) space. The - * chromaticity values (c) have the property: - * - * C - * c = --------- - * X + Y + Z - * - * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the - * three chromaticity values (x,y,z) for each end-point obey the - * relationship: - * - * x + y + z = 1 - * - * This describes the plane in (X,Y,Z) space that intersects each axis at the - * value 1.0; call this the chromaticity plane. Thus the chromaticity - * calculation has scaled each end-point so that it is on the x+y+z=1 plane - * and chromaticity is the intersection of the vector from the origin to the - * (X,Y,Z) value with the chromaticity plane. - * - * To fully invert the chromaticity calculation we would need the three - * end-point scale factors, (red-scale, green-scale, blue-scale), but these - * were not recorded. Instead we calculated the reference white (X,Y,Z) and - * recorded the chromaticity of this. The reference white (X,Y,Z) would have - * given all three of the scale factors since: - * - * color-C = color-c * color-scale - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * But cHRM records only white-x and white-y, so we have lost the white scale - * factor: - * - * white-C = white-c*white-scale - * - * To handle this the inverse transformation makes an arbitrary assumption - * about white-scale: - * - * Assume: white-Y = 1.0 - * Hence: white-scale = 1/white-y - * Or: red-Y + green-Y + blue-Y = 1.0 - * - * Notice the last statement of the assumption gives an equation in three of - * the nine values we want to calculate. 8 more equations come from the - * above routine as summarised at the top above (the chromaticity - * calculation): - * - * Given: color-x = color-X / (color-X + color-Y + color-Z) - * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 - * - * This is 9 simultaneous equations in the 9 variables "color-C" and can be - * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix - * determinants, however this is not as bad as it seems because only 28 of - * the total of 90 terms in the various matrices are non-zero. Nevertheless - * Cramer's rule is notoriously numerically unstable because the determinant - * calculation involves the difference of large, but similar, numbers. It is - * difficult to be sure that the calculation is stable for real world values - * and it is certain that it becomes unstable where the end points are close - * together. - * - * So this code uses the perhaps slighly less optimal but more understandable - * and totally obvious approach of calculating color-scale. - * - * This algorithm depends on the precision in white-scale and that is - * (1/white-y), so we can immediately see that as white-y approaches 0 the - * accuracy inherent in the cHRM chunk drops off substantially. - * - * libpng arithmetic: a simple invertion of the above equations - * ------------------------------------------------------------ - * - * white_scale = 1/white-y - * white-X = white-x * white-scale - * white-Y = 1.0 - * white-Z = (1 - white-x - white-y) * white_scale - * - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * This gives us three equations in (red-scale,green-scale,blue-scale) where - * all the coefficients are now known: - * - * red-x*red-scale + green-x*green-scale + blue-x*blue-scale - * = white-x/white-y - * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 - * red-z*red-scale + green-z*green-scale + blue-z*blue-scale - * = (1 - white-x - white-y)/white-y - * - * In the last equation color-z is (1 - color-x - color-y) so we can add all - * three equations together to get an alternative third: - * - * red-scale + green-scale + blue-scale = 1/white-y = white-scale - * - * So now we have a Cramer's rule solution where the determinants are just - * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve - * multiplication of three coefficients so we can't guarantee to avoid - * overflow in the libpng fixed point representation. Using Cramer's rule in - * floating point is probably a good choice here, but it's not an option for - * fixed point. Instead proceed to simplify the first two equations by - * eliminating what is likely to be the largest value, blue-scale: - * - * blue-scale = white-scale - red-scale - green-scale - * - * Hence: - * - * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = - * (white-x - blue-x)*white-scale - * - * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = - * 1 - blue-y*white-scale - * - * And now we can trivially solve for (red-scale,green-scale): - * - * green-scale = - * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale - * ----------------------------------------------------------- - * green-x - blue-x - * - * red-scale = - * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale - * --------------------------------------------------------- - * red-y - blue-y - * - * Hence: - * - * red-scale = - * ( (green-x - blue-x) * (white-y - blue-y) - - * (green-y - blue-y) * (white-x - blue-x) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * green-scale = - * ( (red-y - blue-y) * (white-x - blue-x) - - * (red-x - blue-x) * (white-y - blue-y) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * Accuracy: - * The input values have 5 decimal digits of accuracy. The values are all in - * the range 0 < value < 1, so simple products are in the same range but may - * need up to 10 decimal digits to preserve the original precision and avoid - * underflow. Because we are using a 32-bit signed representation we cannot - * match this; the best is a little over 9 decimal digits, less than 10. - * - * The approach used here is to preserve the maximum precision within the - * signed representation. Because the red-scale calculation above uses the - * difference between two products of values that must be in the range -1..+1 - * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The - * factor is irrelevant in the calculation because it is applied to both - * numerator and denominator. - * - * Note that the values of the differences of the products of the - * chromaticities in the above equations tend to be small, for example for - * the sRGB chromaticities they are: - * - * red numerator: -0.04751 - * green numerator: -0.08788 - * denominator: -0.2241 (without white-y multiplication) - * - * The resultant Y coefficients from the chromaticities of some widely used - * color space definitions are (to 15 decimal places): - * - * sRGB - * 0.212639005871510 0.715168678767756 0.072192315360734 - * Kodak ProPhoto - * 0.288071128229293 0.711843217810102 0.000085653960605 - * Adobe RGB - * 0.297344975250536 0.627363566255466 0.075291458493998 - * Adobe Wide Gamut RGB - * 0.258728243040113 0.724682314948566 0.016589442011321 - */ - /* By the argument, above overflow should be impossible here. The return - * value of 2 indicates an internal error to the caller. - */ - if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.redy - xy.bluey, 7)) return 2; - if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.redx - xy.bluex, 7)) return 2; - denominator = left - right; - - /* Now find the red numerator. */ - if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; - if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; - - /* Overflow is possible here and it indicates an extreme set of PNG cHRM - * chunk values. This calculation actually returns the reciprocal of the - * scale value because this allows us to delay the multiplication of white-y - * into the denominator, which tends to produce a small number. - */ - if (!png_muldiv(&red_inverse, xy.whitey, denominator, left-right) || - red_inverse <= xy.whitey /* r+g+b scales = white scale */) - return 1; - - /* Similarly for green_inverse: */ - if (!png_muldiv(&left, xy.redy-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; - if (!png_muldiv(&right, xy.redx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; - if (!png_muldiv(&green_inverse, xy.whitey, denominator, left-right) || - green_inverse <= xy.whitey) - return 1; - - /* And the blue scale, the checks above guarantee this can't overflow but it - * can still produce 0 for extreme cHRM values. - */ - blue_scale = png_reciprocal(xy.whitey) - png_reciprocal(red_inverse) - - png_reciprocal(green_inverse); - if (blue_scale <= 0) return 1; - - - /* And fill in the png_XYZ: */ - if (!png_muldiv(&XYZ->redX, xy.redx, PNG_FP_1, red_inverse)) return 1; - if (!png_muldiv(&XYZ->redY, xy.redy, PNG_FP_1, red_inverse)) return 1; - if (!png_muldiv(&XYZ->redZ, PNG_FP_1 - xy.redx - xy.redy, PNG_FP_1, - red_inverse)) - return 1; - - if (!png_muldiv(&XYZ->greenX, xy.greenx, PNG_FP_1, green_inverse)) return 1; - if (!png_muldiv(&XYZ->greenY, xy.greeny, PNG_FP_1, green_inverse)) return 1; - if (!png_muldiv(&XYZ->greenZ, PNG_FP_1 - xy.greenx - xy.greeny, PNG_FP_1, - green_inverse)) - return 1; - - if (!png_muldiv(&XYZ->blueX, xy.bluex, blue_scale, PNG_FP_1)) return 1; - if (!png_muldiv(&XYZ->blueY, xy.bluey, blue_scale, PNG_FP_1)) return 1; - if (!png_muldiv(&XYZ->blueZ, PNG_FP_1 - xy.bluex - xy.bluey, blue_scale, - PNG_FP_1)) - return 1; - - return 0; /*success*/ -} - -int png_XYZ_from_xy_checked(png_structp png_ptr, png_XYZ *XYZ, png_xy xy) -{ - switch (png_XYZ_from_xy(XYZ, xy)) - { - case 0: /* success */ - return 1; - - case 1: - /* The chunk may be technically valid, but we got png_fixed_point - * overflow while trying to get XYZ values out of it. This is - * entirely benign - the cHRM chunk is pretty extreme. - */ - png_warning(png_ptr, - "extreme cHRM chunk cannot be converted to tristimulus values"); - break; - - default: - /* libpng is broken; this should be a warning but if it happens we - * want error reports so for the moment it is an error. - */ - png_error(png_ptr, "internal error in png_XYZ_from_xy"); - break; - } - - /* ERROR RETURN */ - return 0; -} -#endif - -void /* PRIVATE */ -png_check_IHDR(png_structp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - int error = 0; - - /* Check for width and height valid values */ - if (width == 0) - { - png_warning(png_ptr, "Image width is zero in IHDR"); - error = 1; - } - - if (height == 0) - { - png_warning(png_ptr, "Image height is zero in IHDR"); - error = 1; - } - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (width > png_ptr->user_width_max) - -# else - if (width > PNG_USER_WIDTH_MAX) -# endif - { - png_warning(png_ptr, "Image width exceeds user limit in IHDR"); - error = 1; - } - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (height > png_ptr->user_height_max) -# else - if (height > PNG_USER_HEIGHT_MAX) -# endif - { - png_warning(png_ptr, "Image height exceeds user limit in IHDR"); - error = 1; - } - - if (width > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image width in IHDR"); - error = 1; - } - - if (height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } - - if (width > (PNG_UINT_32_MAX - >> 3) /* 8-byte RGBA pixels */ - - 48 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ - png_warning(png_ptr, "Width is too large for libpng to process pixels"); - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) - { - png_warning(png_ptr, "Invalid bit depth in IHDR"); - error = 1; - } - - if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) - { - png_warning(png_ptr, "Invalid color type in IHDR"); - error = 1; - } - - if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || - ((color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) - { - png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); - error = 1; - } - - if (interlace_type >= PNG_INTERLACE_LAST) - { - png_warning(png_ptr, "Unknown interlace method in IHDR"); - error = 1; - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Unknown compression method in IHDR"); - error = 1; - } - -# ifdef PNG_MNG_FEATURES_SUPPORTED - /* Accept filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not read a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && - png_ptr->mng_features_permitted) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - - if (filter_type != PNG_FILTER_TYPE_BASE) - { - if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } - - if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; - } - } - -# else - if (filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } -# endif - - if (error == 1) - png_error(png_ptr, "Invalid IHDR data"); -} - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* ASCII to fp functions */ -/* Check an ASCII formated floating point value, see the more detailed - * comments in pngpriv.h - */ -/* The following is used internally to preserve the sticky flags */ -#define png_fp_add(state, flags) ((state) |= (flags)) -#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) - -int /* PRIVATE */ -png_check_fp_number(png_const_charp string, png_size_t size, int *statep, - png_size_tp whereami) -{ - int state = *statep; - png_size_t i = *whereami; - - while (i < size) - { - int type; - /* First find the type of the next character */ - switch (string[i]) - { - case 43: type = PNG_FP_SAW_SIGN; break; - case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; - case 46: type = PNG_FP_SAW_DOT; break; - case 48: type = PNG_FP_SAW_DIGIT; break; - case 49: case 50: case 51: case 52: - case 53: case 54: case 55: case 56: - case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; - case 69: - case 101: type = PNG_FP_SAW_E; break; - default: goto PNG_FP_End; - } - - /* Now deal with this type according to the current - * state, the type is arranged to not overlap the - * bits of the PNG_FP_STATE. - */ - switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) - { - case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: - if (state & PNG_FP_SAW_ANY) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, type); - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DOT: - /* Ok as trailer, ok as lead of fraction. */ - if (state & PNG_FP_SAW_DOT) /* two dots */ - goto PNG_FP_End; - - else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ - png_fp_add(state, type); - - else - png_fp_set(state, PNG_FP_FRACTION | type); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: - if (state & PNG_FP_SAW_DOT) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - - png_fp_add(state, type | PNG_FP_WAS_VALID); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_E: - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: - goto PNG_FP_End; ** no sign in fraction */ - - /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: - goto PNG_FP_End; ** Because SAW_DOT is always set */ - - case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: - png_fp_add(state, type | PNG_FP_WAS_VALID); - break; - - case PNG_FP_FRACTION + PNG_FP_SAW_E: - /* This is correct because the trailing '.' on an - * integer is handled above - so we can only get here - * with the sequence ".E" (with no preceding digits). - */ - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: - if (state & PNG_FP_SAW_ANY) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, PNG_FP_SAW_SIGN); - - break; - - /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: - goto PNG_FP_End; */ - - case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); - - break; - - /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: - goto PNG_FP_End; */ - - default: goto PNG_FP_End; /* I.e. break 2 */ - } - - /* The character seems ok, continue. */ - ++i; - } - -PNG_FP_End: - /* Here at the end, update the state and return the correct - * return code. - */ - *statep = state; - *whereami = i; - - return (state & PNG_FP_SAW_DIGIT) != 0; -} - - -/* The same but for a complete string. */ -int -png_check_fp_string(png_const_charp string, png_size_t size) -{ - int state=0; - png_size_t char_index=0; - - if (png_check_fp_number(string, size, &state, &char_index) && - (char_index == size || string[char_index] == 0)) - return state /* must be non-zero - see above */; - - return 0; /* i.e. fail */ -} -#endif /* pCAL or sCAL */ - -#ifdef PNG_READ_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -/* Utility used below - a simple accurate power of ten from an integral - * exponent. - */ -static double -png_pow10(int power) -{ - int recip = 0; - double d = 1; - - /* Handle negative exponent with a reciprocal at the end because - * 10 is exact whereas .1 is inexact in base 2 - */ - if (power < 0) - { - if (power < DBL_MIN_10_EXP) return 0; - recip = 1, power = -power; - } - - if (power > 0) - { - /* Decompose power bitwise. */ - double mult = 10; - do - { - if (power & 1) d *= mult; - mult *= mult; - power >>= 1; - } - while (power > 0); - - if (recip) d = 1/d; - } - /* else power is 0 and d is 1 */ - - return d; -} - -/* Function to format a floating point value in ASCII with a given - * precision. - */ -void /* PRIVATE */ -png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, - double fp, unsigned int precision) -{ - /* We use standard functions from math.h, but not printf because - * that would require stdio. The caller must supply a buffer of - * sufficient size or we will png_error. The tests on size and - * the space in ascii[] consumed are indicated below. - */ - if (precision < 1) - precision = DBL_DIG; - - /* Enforce the limit of the implementation precision too. */ - if (precision > DBL_DIG+1) - precision = DBL_DIG+1; - - /* Basic sanity checks */ - if (size >= precision+5) /* See the requirements below. */ - { - if (fp < 0) - { - fp = -fp; - *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ - --size; - } - - if (fp >= DBL_MIN && fp <= DBL_MAX) - { - int exp_b10; /* A base 10 exponent */ - double base; /* 10^exp_b10 */ - - /* First extract a base 10 exponent of the number, - * the calculation below rounds down when converting - * from base 2 to base 10 (multiply by log10(2) - - * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to - * be increased. Note that the arithmetic shift - * performs a floor() unlike C arithmetic - using a - * C multiply would break the following for negative - * exponents. - */ - (void)frexp(fp, &exp_b10); /* exponent to base 2 */ - - exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ - - /* Avoid underflow here. */ - base = png_pow10(exp_b10); /* May underflow */ - - while (base < DBL_MIN || base < fp) - { - /* And this may overflow. */ - double test = png_pow10(exp_b10+1); - - if (test <= DBL_MAX) - ++exp_b10, base = test; - - else - break; - } - - /* Normalize fp and correct exp_b10, after this fp is in the - * range [.1,1) and exp_b10 is both the exponent and the digit - * *before* which the decimal point should be inserted - * (starting with 0 for the first digit). Note that this - * works even if 10^exp_b10 is out of range because of the - * test on DBL_MAX above. - */ - fp /= base; - while (fp >= 1) fp /= 10, ++exp_b10; - - /* Because of the code above fp may, at this point, be - * less than .1, this is ok because the code below can - * handle the leading zeros this generates, so no attempt - * is made to correct that here. - */ - - { - int czero, clead, cdigits; - char exponent[10]; - - /* Allow up to two leading zeros - this will not lengthen - * the number compared to using E-n. - */ - if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ - { - czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ - exp_b10 = 0; /* Dot added below before first output. */ - } - else - czero = 0; /* No zeros to add */ - - /* Generate the digit list, stripping trailing zeros and - * inserting a '.' before a digit if the exponent is 0. - */ - clead = czero; /* Count of leading zeros */ - cdigits = 0; /* Count of digits in list. */ - - do - { - double d; - - fp *= 10; - /* Use modf here, not floor and subtract, so that - * the separation is done in one step. At the end - * of the loop don't break the number into parts so - * that the final digit is rounded. - */ - if (cdigits+czero-clead+1 < (int)precision) - fp = modf(fp, &d); - - else - { - d = floor(fp + .5); - - if (d > 9) - { - /* Rounding up to 10, handle that here. */ - if (czero > 0) - { - --czero, d = 1; - if (cdigits == 0) --clead; - } - else - { - while (cdigits > 0 && d > 9) - { - int ch = *--ascii; - - if (exp_b10 != (-1)) - ++exp_b10; - - else if (ch == 46) - { - ch = *--ascii, ++size; - /* Advance exp_b10 to '1', so that the - * decimal point happens after the - * previous digit. - */ - exp_b10 = 1; - } - - --cdigits; - d = ch - 47; /* I.e. 1+(ch-48) */ - } - - /* Did we reach the beginning? If so adjust the - * exponent but take into account the leading - * decimal point. - */ - if (d > 9) /* cdigits == 0 */ - { - if (exp_b10 == (-1)) - { - /* Leading decimal point (plus zeros?), if - * we lose the decimal point here it must - * be reentered below. - */ - int ch = *--ascii; - - if (ch == 46) - ++size, exp_b10 = 1; - - /* Else lost a leading zero, so 'exp_b10' is - * still ok at (-1) - */ - } - else - ++exp_b10; - - /* In all cases we output a '1' */ - d = 1; - } - } - } - fp = 0; /* Guarantees termination below. */ - } - - if (d == 0) - { - ++czero; - if (cdigits == 0) ++clead; - } - else - { - /* Included embedded zeros in the digit count. */ - cdigits += czero - clead; - clead = 0; - - while (czero > 0) - { - /* exp_b10 == (-1) means we just output the decimal - * place - after the DP don't adjust 'exp_b10' any - * more! - */ - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) *ascii++ = 46, --size; - /* PLUS 1: TOTAL 4 */ - --exp_b10; - } - *ascii++ = 48, --czero; - } - - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) *ascii++ = 46, --size; /* counted - above */ - --exp_b10; - } - *ascii++ = (char)(48 + (int)d), ++cdigits; - } - } - while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); - - /* The total output count (max) is now 4+precision */ - - /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At - * this point exp_b10==(-1) is effectively if flag - it got - * to '-1' because of the decrement after outputing - * the decimal point above (the exponent required is - * *not* -1!) - */ - if (exp_b10 >= (-1) && exp_b10 <= 2) - { - /* The following only happens if we didn't output the - * leading zeros above for negative exponent, so this - * doest add to the digit requirement. Note that the - * two zeros here can only be output if the two leading - * zeros were *not* output, so this doesn't increase - * the output count. - */ - while (--exp_b10 >= 0) *ascii++ = 48; - - *ascii = 0; - - /* Total buffer requirement (including the '\0') is - * 5+precision - see check at the start. - */ - return; - } - - /* Here if an exponent is required, adjust size for - * the digits we output but did not count. The total - * digit output here so far is at most 1+precision - no - * decimal point and no leading or trailing zeros have - * been output. - */ - size -= cdigits; - - *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ - - /* The following use of an unsigned temporary avoids ambiguities in - * the signed arithmetic on exp_b10 and permits GCC at least to do - * better optimization. - */ - { - unsigned int uexp_b10; - - if (exp_b10 < 0) - { - *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ - uexp_b10 = -exp_b10; - } - - else - uexp_b10 = exp_b10; - - cdigits = 0; - - while (uexp_b10 > 0) - { - exponent[cdigits++] = (char)(48 + uexp_b10 % 10); - uexp_b10 /= 10; - } - } - - /* Need another size check here for the exponent digits, so - * this need not be considered above. - */ - if ((int)size > cdigits) - { - while (cdigits > 0) *ascii++ = exponent[--cdigits]; - - *ascii = 0; - - return; - } - } - } - else if (!(fp >= DBL_MIN)) - { - *ascii++ = 48; /* '0' */ - *ascii = 0; - return; - } - else - { - *ascii++ = 105; /* 'i' */ - *ascii++ = 110; /* 'n' */ - *ascii++ = 102; /* 'f' */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} - -# endif /* FLOATING_POINT */ - -# ifdef PNG_FIXED_POINT_SUPPORTED -/* Function to format a fixed point value in ASCII. - */ -void /* PRIVATE */ -png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, - png_fixed_point fp) -{ - /* Require space for 10 decimal digits, a decimal point, a minus sign and a - * trailing \0, 13 characters: - */ - if (size > 12) - { - png_uint_32 num; - - /* Avoid overflow here on the minimum integer. */ - if (fp < 0) - *ascii++ = 45, --size, num = -fp; - else - num = fp; - - if (num <= 0x80000000) /* else overflowed */ - { - unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; - - while (num) - { - /* Split the low digit off num: */ - unsigned int tmp = num/10; - num -= tmp*10; - digits[ndigits++] = (char)(48 + num); - /* Record the first non-zero digit, note that this is a number - * starting at 1, it's not actually the array index. - */ - if (first == 16 && num > 0) - first = ndigits; - num = tmp; - } - - if (ndigits > 0) - { - while (ndigits > 5) *ascii++ = digits[--ndigits]; - /* The remaining digits are fractional digits, ndigits is '5' or - * smaller at this point. It is certainly not zero. Check for a - * non-zero fractional digit: - */ - if (first <= 5) - { - unsigned int i; - *ascii++ = 46; /* decimal point */ - /* ndigits may be <5 for small numbers, output leading zeros - * then ndigits digits to first: - */ - i = 5; - while (ndigits < i) *ascii++ = 48, --i; - while (ndigits >= first) *ascii++ = digits[--ndigits]; - /* Don't output the trailing zeros! */ - } - } - else - *ascii++ = 48; - - /* And null terminate the string: */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -# endif /* FIXED_POINT */ -#endif /* READ_SCAL */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) -png_fixed_point -png_fixed(png_structp png_ptr, double fp, png_const_charp text) -{ - double r = floor(100000 * fp + .5); - - if (r > 2147483647. || r < -2147483648.) - png_fixed_error(png_ptr, text); - - return (png_fixed_point)r; -} -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || \ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) -/* muldiv functions */ -/* This API takes signed arguments and rounds the result to the nearest - * integer (or, for a fixed point number - the standard argument - to - * the nearest .00001). Overflow and divide by zero are signalled in - * the result, a boolean - true on success, false on overflow. - */ -int -png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - /* Return a * times / divisor, rounded. */ - if (divisor != 0) - { - if (a == 0 || times == 0) - { - *res = 0; - return 1; - } - else - { -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a; - r *= times; - r /= divisor; - r = floor(r+.5); - - /* A png_fixed_point is a 32-bit integer. */ - if (r <= 2147483647. && r >= -2147483648.) - { - *res = (png_fixed_point)r; - return 1; - } -#else - int negative = 0; - png_uint_32 A, T, D; - png_uint_32 s16, s32, s00; - - if (a < 0) - negative = 1, A = -a; - else - A = a; - - if (times < 0) - negative = !negative, T = -times; - else - T = times; - - if (divisor < 0) - negative = !negative, D = -divisor; - else - D = divisor; - - /* Following can't overflow because the arguments only - * have 31 bits each, however the result may be 32 bits. - */ - s16 = (A >> 16) * (T & 0xffff) + - (A & 0xffff) * (T >> 16); - /* Can't overflow because the a*times bit is only 30 - * bits at most. - */ - s32 = (A >> 16) * (T >> 16) + (s16 >> 16); - s00 = (A & 0xffff) * (T & 0xffff); - - s16 = (s16 & 0xffff) << 16; - s00 += s16; - - if (s00 < s16) - ++s32; /* carry */ - - if (s32 < D) /* else overflow */ - { - /* s32.s00 is now the 64-bit product, do a standard - * division, we know that s32 < D, so the maximum - * required shift is 31. - */ - int bitshift = 32; - png_fixed_point result = 0; /* NOTE: signed */ - - while (--bitshift >= 0) - { - png_uint_32 d32, d00; - - if (bitshift > 0) - d32 = D >> (32-bitshift), d00 = D << bitshift; - - else - d32 = 0, d00 = D; - - if (s32 > d32) - { - if (s00 < d00) --s32; /* carry */ - s32 -= d32, s00 -= d00, result += 1<= d00) - s32 = 0, s00 -= d00, result += 1<= (D >> 1)) - ++result; - - if (negative) - result = -result; - - /* Check for overflow. */ - if ((negative && result <= 0) || (!negative && result >= 0)) - { - *res = result; - return 1; - } - } -#endif - } - } - - return 0; -} -#endif /* READ_GAMMA || INCH_CONVERSIONS */ - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* The following is for when the caller doesn't much care about the - * result. - */ -png_fixed_point -png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - png_fixed_point result; - - if (png_muldiv(&result, a, times, divisor)) - return result; - - png_warning(png_ptr, "fixed point overflow ignored"); - return 0; -} -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ -/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ -png_fixed_point -png_reciprocal(png_fixed_point a) -{ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(1E10/a+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, 100000, 100000, a)) - return res; -#endif - - return 0; /* error/overflow */ -} - -/* A local convenience routine. */ -static png_fixed_point -png_product2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a * 1E-5; - r *= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, a, b, 100000)) - return res; -#endif - - return 0; /* overflow */ -} - -/* The inverse of the above. */ -png_fixed_point -png_reciprocal2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = 1E15/a; - r /= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - /* This may overflow because the range of png_fixed_point isn't symmetric, - * but this API is only used for the product of file and screen gamma so it - * doesn't matter that the smallest number it can produce is 1/21474, not - * 1/100000 - */ - png_fixed_point res = png_product2(a, b); - - if (res != 0) - return png_reciprocal(res); -#endif - - return 0; /* overflow */ -} -#endif /* READ_GAMMA */ - -#ifdef PNG_CHECK_cHRM_SUPPORTED -/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, - * 2010: moved from pngset.c) */ -/* - * Multiply two 32-bit numbers, V1 and V2, using 32-bit - * arithmetic, to produce a 64-bit result in the HI/LO words. - * - * A B - * x C D - * ------ - * AD || BD - * AC || CB || 0 - * - * where A and B are the high and low 16-bit words of V1, - * C and D are the 16-bit words of V2, AD is the product of - * A and D, and X || Y is (X << 16) + Y. -*/ - -void /* PRIVATE */ -png_64bit_product (long v1, long v2, unsigned long *hi_product, - unsigned long *lo_product) -{ - int a, b, c, d; - long lo, hi, x, y; - - a = (v1 >> 16) & 0xffff; - b = v1 & 0xffff; - c = (v2 >> 16) & 0xffff; - d = v2 & 0xffff; - - lo = b * d; /* BD */ - x = a * d + c * b; /* AD + CB */ - y = ((lo >> 16) & 0xffff) + x; - - lo = (lo & 0xffff) | ((y & 0xffff) << 16); - hi = (y >> 16) & 0xffff; - - hi += a * c; /* AC */ - - *hi_product = (unsigned long)hi; - *lo_product = (unsigned long)lo; -} -#endif /* CHECK_cHRM */ - -#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ -#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* Fixed point gamma. - * - * To calculate gamma this code implements fast log() and exp() calls using only - * fixed point arithmetic. This code has sufficient precision for either 8-bit - * or 16-bit sample values. - * - * The tables used here were calculated using simple 'bc' programs, but C double - * precision floating point arithmetic would work fine. The programs are given - * at the head of each table. - * - * 8-bit log table - * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to - * 255, so it's the base 2 logarithm of a normalized 8-bit floating point - * mantissa. The numbers are 32-bit fractions. - */ -static png_uint_32 -png_8bit_l2[128] = -{ -# ifdef PNG_DO_BC - for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } -# else - 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, - 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, - 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, - 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, - 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, - 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, - 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, - 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, - 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, - 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, - 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, - 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, - 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, - 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, - 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, - 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, - 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, - 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, - 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, - 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, - 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, - 24347096U, 0U -# endif - -#if 0 - /* The following are the values for 16-bit tables - these work fine for the - * 8-bit conversions but produce very slightly larger errors in the 16-bit - * log (about 1.2 as opposed to 0.7 absolute error in the final value). To - * use these all the shifts below must be adjusted appropriately. - */ - 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, - 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, - 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, - 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, - 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, - 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, - 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, - 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, - 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, - 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, - 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, - 1119, 744, 372 -#endif -}; - -PNG_STATIC png_int_32 -png_log8bit(unsigned int x) -{ - unsigned int lg2 = 0; - /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, - * because the log is actually negate that means adding 1. The final - * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 - * input), return 7.99998 for the overflow (log 0) case - so the result is - * always at most 19 bits. - */ - if ((x &= 0xff) == 0) - return 0xffffffff; - - if ((x & 0xf0) == 0) - lg2 = 4, x <<= 4; - - if ((x & 0xc0) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x80) == 0) - lg2 += 1, x <<= 1; - - /* result is at most 19 bits, so this cast is safe: */ - return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); -} - -/* The above gives exact (to 16 binary places) log2 values for 8-bit images, - * for 16-bit images we use the most significant 8 bits of the 16-bit value to - * get an approximation then multiply the approximation by a correction factor - * determined by the remaining up to 8 bits. This requires an additional step - * in the 16-bit case. - * - * We want log2(value/65535), we have log2(v'/255), where: - * - * value = v' * 256 + v'' - * = v' * f - * - * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 - * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less - * than 258. The final factor also needs to correct for the fact that our 8-bit - * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. - * - * This gives a final formula using a calculated value 'x' which is value/v' and - * scaling by 65536 to match the above table: - * - * log2(x/257) * 65536 - * - * Since these numbers are so close to '1' we can use simple linear - * interpolation between the two end values 256/257 (result -368.61) and 258/257 - * (result 367.179). The values used below are scaled by a further 64 to give - * 16-bit precision in the interpolation: - * - * Start (256): -23591 - * Zero (257): 0 - * End (258): 23499 - */ -PNG_STATIC png_int_32 -png_log16bit(png_uint_32 x) -{ - unsigned int lg2 = 0; - - /* As above, but now the input has 16 bits. */ - if ((x &= 0xffff) == 0) - return 0xffffffff; - - if ((x & 0xff00) == 0) - lg2 = 8, x <<= 8; - - if ((x & 0xf000) == 0) - lg2 += 4, x <<= 4; - - if ((x & 0xc000) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x8000) == 0) - lg2 += 1, x <<= 1; - - /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional - * value. - */ - lg2 <<= 28; - lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; - - /* Now we need to interpolate the factor, this requires a division by the top - * 8 bits. Do this with maximum precision. - */ - x = ((x << 16) + (x >> 9)) / (x >> 8); - - /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, - * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly - * 16 bits to interpolate to get the low bits of the result. Round the - * answer. Note that the end point values are scaled by 64 to retain overall - * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust - * the overall scaling by 6-12. Round at every step. - */ - x -= 1U << 24; - - if (x <= 65536U) /* <= '257' */ - lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); - - else - lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); - - /* Safe, because the result can't have more than 20 bits: */ - return (png_int_32)((lg2 + 2048) >> 12); -} - -/* The 'exp()' case must invert the above, taking a 20-bit fixed point - * logarithmic value and returning a 16 or 8-bit number as appropriate. In - * each case only the low 16 bits are relevant - the fraction - since the - * integer bits (the top 4) simply determine a shift. - * - * The worst case is the 16-bit distinction between 65535 and 65534, this - * requires perhaps spurious accuracy in the decoding of the logarithm to - * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance - * of getting this accuracy in practice. - * - * To deal with this the following exp() function works out the exponent of the - * frational part of the logarithm by using an accurate 32-bit value from the - * top four fractional bits then multiplying in the remaining bits. - */ -static png_uint_32 -png_32bit_exp[16] = -{ -# ifdef PNG_DO_BC - for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } -# else - /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ - 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, - 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, - 2553802834U, 2445529972U, 2341847524U, 2242560872U -# endif -}; - -/* Adjustment table; provided to explain the numbers in the code below. */ -#ifdef PNG_DO_BC -for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} - 11 44937.64284865548751208448 - 10 45180.98734845585101160448 - 9 45303.31936980687359311872 - 8 45364.65110595323018870784 - 7 45395.35850361789624614912 - 6 45410.72259715102037508096 - 5 45418.40724413220722311168 - 4 45422.25021786898173001728 - 3 45424.17186732298419044352 - 2 45425.13273269940811464704 - 1 45425.61317555035558641664 - 0 45425.85339951654943850496 -#endif - -PNG_STATIC png_uint_32 -png_exp(png_fixed_point x) -{ - if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ - { - /* Obtain a 4-bit approximation */ - png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; - - /* Incorporate the low 12 bits - these decrease the returned value by - * multiplying by a number less than 1 if the bit is set. The multiplier - * is determined by the above table and the shift. Notice that the values - * converge on 45426 and this is used to allow linear interpolation of the - * low bits. - */ - if (x & 0x800) - e -= (((e >> 16) * 44938U) + 16U) >> 5; - - if (x & 0x400) - e -= (((e >> 16) * 45181U) + 32U) >> 6; - - if (x & 0x200) - e -= (((e >> 16) * 45303U) + 64U) >> 7; - - if (x & 0x100) - e -= (((e >> 16) * 45365U) + 128U) >> 8; - - if (x & 0x080) - e -= (((e >> 16) * 45395U) + 256U) >> 9; - - if (x & 0x040) - e -= (((e >> 16) * 45410U) + 512U) >> 10; - - /* And handle the low 6 bits in a single block. */ - e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; - - /* Handle the upper bits of x. */ - e >>= x >> 16; - return e; - } - - /* Check for overflow */ - if (x <= 0) - return png_32bit_exp[0]; - - /* Else underflow */ - return 0; -} - -PNG_STATIC png_byte -png_exp8bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the - * second, rounding, step can't overflow because of the first, subtraction, - * step. - */ - x -= x >> 8; - return (png_byte)((x + 0x7fffffU) >> 24); -} - -PNG_STATIC png_uint_16 -png_exp16bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ - x -= x >> 16; - return (png_uint_16)((x + 32767U) >> 16); -} -#endif /* FLOATING_ARITHMETIC */ - -png_byte -png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 255) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); - return (png_byte)r; -# else - png_int_32 lg2 = png_log8bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) - return png_exp8bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_byte)value; -} - -png_uint_16 -png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 65535) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); - return (png_uint_16)r; -# else - png_int_32 lg2 = png_log16bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) - return png_exp16bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_uint_16)value; -} - -/* This does the right thing based on the bit_depth field of the - * png_struct, interpreting values as 8-bit or 16-bit. While the result - * is nominally a 16-bit value if bit depth is 8 then the result is - * 8-bit (as are the arguments.) - */ -png_uint_16 /* PRIVATE */ -png_gamma_correct(png_structp png_ptr, unsigned int value, - png_fixed_point gamma_val) -{ - if (png_ptr->bit_depth == 8) - return png_gamma_8bit_correct(value, gamma_val); - - else - return png_gamma_16bit_correct(value, gamma_val); -} - -/* This is the shared test on whether a gamma value is 'significant' - whether - * it is worth doing gamma correction. - */ -int /* PRIVATE */ -png_gamma_significant(png_fixed_point gamma_val) -{ - return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || - gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; -} - -/* Internal function to build a single 16-bit table - the table consists of - * 'num' 256-entry subtables, where 'num' is determined by 'shift' - the amount - * to shift the input values right (or 16-number_of_signifiant_bits). - * - * The caller is responsible for ensuring that the table gets cleaned up on - * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument - * should be somewhere that will be cleaned. - */ -static void -png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) -{ - /* Various values derived from 'shift': */ - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); - unsigned int i; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); - - for (i = 0; i < num; i++) - { - png_uint_16p sub_table = table[i] = - (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); - - /* The 'threshold' test is repeated here because it can arise for one of - * the 16-bit tables even if the others don't hit it. - */ - if (png_gamma_significant(gamma_val)) - { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an - * arithmetic error. This code follows the spec exactly; ig is - * the recovered input sample, it always has 8-16 bits. - * - * We want input * 65535/max, rounded, the arithmetic fits in 32 - * bits (unsigned) so long as max <= 32767. - */ - unsigned int j; - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ - double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); - sub_table[j] = (png_uint_16)d; -# else - if (shift) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); -# endif - } - } - else - { - /* We must still build a table, but do it the fast way. */ - unsigned int j; - - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; - - if (shift) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = (png_uint_16)ig; - } - } - } -} - -/* NOTE: this function expects the *inverse* of the overall gamma transformation - * required. - */ -static void -png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) -{ - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - unsigned int i; - png_uint_32 last; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); - - /* 'num' is the number of tables and also the number of low bits of the - * input 16-bit value used to select a table. Each table is itself indexed - * by the high 8 bits of the value. - */ - for (i = 0; i < num; i++) - table[i] = (png_uint_16p)png_malloc(png_ptr, - 256 * png_sizeof(png_uint_16)); - - /* 'gamma_val' is set to the reciprocal of the value calculated above, so - * pow(out,g) is an *input* value. 'last' is the last input value set. - * - * In the loop 'i' is used to find output values. Since the output is - * 8-bit there are only 256 possible values. The tables are set up to - * select the closest possible output value for each input by finding - * the input value at the boundary between each pair of output values - * and filling the table up to that boundary with the lower output - * value. - * - * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit - * values the code below uses a 16-bit value in i; the values start at - * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last - * entries are filled with 255). Start i at 128 and fill all 'last' - * table entries <= 'max' - */ - last = 0; - for (i = 0; i < 255; ++i) /* 8-bit output value */ - { - /* Find the corresponding maximum input value */ - png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ - - /* Find the boundary value in 16 bits: */ - png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); - - /* Adjust (round) to (16-shift) bits: */ - bound = (bound * max + 32768U)/65535U + 1U; - - while (last < bound) - { - table[last & (0xffU >> shift)][last >> (8U - shift)] = out; - last++; - } - } - - /* And fill in the final entries. */ - while (last < (num << 8)) - { - table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; - last++; - } -} - -/* Build a single 8-bit table: same as the 16-bit case but much simpler (and - * typically much faster). Note that libpng currently does no sBIT processing - * (apparently contrary to the spec) so a 256-entry table is always generated. - */ -static void -png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) -{ - unsigned int i; - png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); - - if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) - table[i] = png_gamma_8bit_correct(i, gamma_val); - - else for (i=0; i<256; ++i) - table[i] = (png_byte)i; -} - -/* Used from png_read_destroy and below to release the memory used by the gamma - * tables. - */ -void /* PRIVATE */ -png_destroy_gamma_table(png_structp png_ptr) -{ - png_free(png_ptr, png_ptr->gamma_table); - png_ptr->gamma_table = NULL; - - if (png_ptr->gamma_16_table != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_table[i]); - } - png_free(png_ptr, png_ptr->gamma_16_table); - png_ptr->gamma_16_table = NULL; - } - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_free(png_ptr, png_ptr->gamma_from_1); - png_ptr->gamma_from_1 = NULL; - png_free(png_ptr, png_ptr->gamma_to_1); - png_ptr->gamma_to_1 = NULL; - - if (png_ptr->gamma_16_from_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_from_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_from_1); - png_ptr->gamma_16_from_1 = NULL; - } - if (png_ptr->gamma_16_to_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_to_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_to_1); - png_ptr->gamma_16_to_1 = NULL; - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -} - -/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit - * tables, we don't make a full table if we are reducing to 8-bit in - * the future. Note also how the gamma_16 tables are segmented so that - * we don't need to allocate > 64K chunks for a full 16-bit table. - */ -void /* PRIVATE */ -png_build_gamma_table(png_structp png_ptr, int bit_depth) -{ - png_debug(1, "in png_build_gamma_table"); - - /* Remove any existing table; this copes with multiple calls to - * png_read_update_info. The warning is because building the gamma tables - * multiple times is a performance hit - it's harmless but the ability to call - * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible - * to warn if the app introduces such a hit. - */ - if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) - { - png_warning(png_ptr, "gamma table being rebuilt"); - png_destroy_gamma_table(png_ptr); - } - - if (bit_depth <= 8) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->gamma)); - - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } - else - { - png_byte shift, sig_bit; - - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { - sig_bit = png_ptr->sig_bit.red; - - if (png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; - - if (png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - sig_bit = png_ptr->sig_bit.gray; - - /* 16-bit gamma code uses this equation: - * - * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] - * - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * - * Thus the gamma table consists of up to 256 256-entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits of - * the color value then indexed by the upper 8 bits: - * - * table[low bits][high 8 bits] - * - * So the table 'n' corresponds to all those 'iv' of: - * - * ..<(n+1 << gamma_shift)-1> - * - */ - if (sig_bit > 0 && sig_bit < 16U) - shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ - - else - shift = 0; /* keep all 16 bits */ - - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) - { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. - */ - if (shift < (16U - PNG_MAX_GAMMA_8)) - shift = (16U - PNG_MAX_GAMMA_8); - } - - if (shift > 8U) - shift = 8U; /* Guarantees at least one table! */ - - png_ptr->gamma_shift = shift; - -#ifdef PNG_16BIT_SUPPORTED - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be reduced - * to 8 bits. - */ - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) -#endif - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#ifdef PNG_16BIT_SUPPORTED - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) - { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->gamma)); - - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, so it can't be. - * TODO: fix this. - */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -} -#endif /* READ_GAMMA */ -#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/WDL/libpng/png.h b/WDL/libpng/png.h deleted file mode 100644 index 98bb8a9d..00000000 --- a/WDL/libpng/png.h +++ /dev/null @@ -1,2654 +0,0 @@ - -/* png.h - header file for PNG reference library - * - * libpng version 1.5.8 - February 1, 2012 - * Copyright (c) 1998-2012 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license (See LICENSE, below) - * - * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.5.8 - February 1, 2012: Glenn - * See also "Contributing Authors", below. - * - * Note about libpng version numbers: - * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: - * - * source png.h png.h shared-lib - * version string int version - * ------- ------ ----- ---------- - * 0.89c "1.0 beta 3" 0.89 89 1.0.89 - * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] - * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] - * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] - * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] - * 0.97c 0.97 97 2.0.97 - * 0.98 0.98 98 2.0.98 - * 0.99 0.99 98 2.0.99 - * 0.99a-m 0.99 99 2.0.99 - * 1.00 1.00 100 2.1.0 [100 should be 10000] - * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] - * 1.0.1 png.h string is 10001 2.1.0 - * 1.0.1a-e identical to the 10002 from here on, the shared library - * 1.0.2 source version) 10002 is 2.V where V is the source code - * 1.0.2a-b 10003 version, except as noted. - * 1.0.3 10003 - * 1.0.3a-d 10004 - * 1.0.4 10004 - * 1.0.4a-f 10005 - * 1.0.5 (+ 2 patches) 10005 - * 1.0.5a-d 10006 - * 1.0.5e-r 10100 (not source compatible) - * 1.0.5s-v 10006 (not binary compatible) - * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) - * 1.0.6d-f 10007 (still binary incompatible) - * 1.0.6g 10007 - * 1.0.6h 10007 10.6h (testing xy.z so-numbering) - * 1.0.6i 10007 10.6i - * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) - * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) - * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) - * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) - * 1.0.7 1 10007 (still compatible) - * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 - * 1.0.8rc1 1 10008 2.1.0.8rc1 - * 1.0.8 1 10008 2.1.0.8 - * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 - * 1.0.9rc1 1 10009 2.1.0.9rc1 - * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 - * 1.0.9rc2 1 10009 2.1.0.9rc2 - * 1.0.9 1 10009 2.1.0.9 - * 1.0.10beta1 1 10010 2.1.0.10beta1 - * 1.0.10rc1 1 10010 2.1.0.10rc1 - * 1.0.10 1 10010 2.1.0.10 - * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 - * 1.0.11rc1 1 10011 2.1.0.11rc1 - * 1.0.11 1 10011 2.1.0.11 - * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 - * 1.0.12rc1 2 10012 2.1.0.12rc1 - * 1.0.12 2 10012 2.1.0.12 - * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) - * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 - * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 - * 1.2.0rc1 3 10200 3.1.2.0rc1 - * 1.2.0 3 10200 3.1.2.0 - * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 - * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 - * 1.2.1 3 10201 3.1.2.1 - * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 - * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 - * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 - * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 - * 1.0.13 10 10013 10.so.0.1.0.13 - * 1.2.2 12 10202 12.so.0.1.2.2 - * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 - * 1.2.3 12 10203 12.so.0.1.2.3 - * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 - * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 - * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 - * 1.0.14 10 10014 10.so.0.1.0.14 - * 1.2.4 13 10204 12.so.0.1.2.4 - * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 - * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 - * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 - * 1.0.15 10 10015 10.so.0.1.0.15 - * 1.2.5 13 10205 12.so.0.1.2.5 - * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 - * 1.0.16 10 10016 10.so.0.1.0.16 - * 1.2.6 13 10206 12.so.0.1.2.6 - * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 - * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 - * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 - * 1.0.17 10 10017 12.so.0.1.0.17 - * 1.2.7 13 10207 12.so.0.1.2.7 - * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 - * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 - * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 - * 1.0.18 10 10018 12.so.0.1.0.18 - * 1.2.8 13 10208 12.so.0.1.2.8 - * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 - * 1.2.9beta4-11 13 10209 12.so.0.9[.0] - * 1.2.9rc1 13 10209 12.so.0.9[.0] - * 1.2.9 13 10209 12.so.0.9[.0] - * 1.2.10beta1-7 13 10210 12.so.0.10[.0] - * 1.2.10rc1-2 13 10210 12.so.0.10[.0] - * 1.2.10 13 10210 12.so.0.10[.0] - * 1.4.0beta1-5 14 10400 14.so.0.0[.0] - * 1.2.11beta1-4 13 10211 12.so.0.11[.0] - * 1.4.0beta7-8 14 10400 14.so.0.0[.0] - * 1.2.11 13 10211 12.so.0.11[.0] - * 1.2.12 13 10212 12.so.0.12[.0] - * 1.4.0beta9-14 14 10400 14.so.0.0[.0] - * 1.2.13 13 10213 12.so.0.13[.0] - * 1.4.0beta15-36 14 10400 14.so.0.0[.0] - * 1.4.0beta37-87 14 10400 14.so.14.0[.0] - * 1.4.0rc01 14 10400 14.so.14.0[.0] - * 1.4.0beta88-109 14 10400 14.so.14.0[.0] - * 1.4.0rc02-08 14 10400 14.so.14.0[.0] - * 1.4.0 14 10400 14.so.14.0[.0] - * 1.4.1beta01-03 14 10401 14.so.14.1[.0] - * 1.4.1rc01 14 10401 14.so.14.1[.0] - * 1.4.1beta04-12 14 10401 14.so.14.1[.0] - * 1.4.1 14 10401 14.so.14.1[.0] - * 1.4.2 14 10402 14.so.14.2[.0] - * 1.4.3 14 10403 14.so.14.3[.0] - * 1.4.4 14 10404 14.so.14.4[.0] - * 1.5.0beta01-58 15 10500 15.so.15.0[.0] - * 1.5.0rc01-07 15 10500 15.so.15.0[.0] - * 1.5.0 15 10500 15.so.15.0[.0] - * 1.5.1beta01-11 15 10501 15.so.15.1[.0] - * 1.5.1rc01-02 15 10501 15.so.15.1[.0] - * 1.5.1 15 10501 15.so.15.1[.0] - * 1.5.2beta01-03 15 10502 15.so.15.2[.0] - * 1.5.2rc01-03 15 10502 15.so.15.2[.0] - * 1.5.2 15 10502 15.so.15.2[.0] - * 1.5.3beta01-10 15 10503 15.so.15.3[.0] - * 1.5.3rc01-02 15 10503 15.so.15.3[.0] - * 1.5.3beta11 15 10503 15.so.15.3[.0] - * 1.5.3 [omitted] - * 1.5.4beta01-08 15 10504 15.so.15.4[.0] - * 1.5.4rc01 15 10504 15.so.15.4[.0] - * 1.5.4 15 10504 15.so.15.4[.0] - * 1.5.5beta01-08 15 10505 15.so.15.5[.0] - * 1.5.5rc01 15 10505 15.so.15.5[.0] - * 1.5.5 15 10505 15.so.15.5[.0] - * 1.5.6beta01-07 15 10506 15.so.15.6[.0] - * 1.5.6rc01-03 15 10506 15.so.15.6[.0] - * 1.5.6 15 10506 15.so.15.6[.0] - * 1.5.7beta01-05 15 10507 15.so.15.7[.0] - * 1.5.7rc01-03 15 10507 15.so.15.7[.0] - * 1.5.7 15 10507 15.so.15.7[.0] - * 1.5.8beta01 15 10508 15.so.15.8[.0] - * 1.5.8rc01 15 10508 15.so.15.8[.0] - * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcN". - * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. - * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * - * See libpng-manual.txt or libpng.3 for more information. The PNG - * specification is available as a W3C Recommendation and as an ISO - * Specification, -# endif - - /* Need the time information for converting tIME chunks, it - * defines struct tm: - */ -# ifdef PNG_CONVERT_tIME_SUPPORTED - /* "time.h" functions are not supported on all operating systems */ -# include -# endif -# endif - -/* Machine specific configuration. */ -# include "pngconf.h" -#endif - -/* - * Added at libpng-1.2.8 - * - * Ref MSDN: Private as priority over Special - * VS_FF_PRIVATEBUILD File *was not* built using standard release - * procedures. If this value is given, the StringFileInfo block must - * contain a PrivateBuild string. - * - * VS_FF_SPECIALBUILD File *was* built by the original company using - * standard release procedures but is a variation of the standard - * file of the same version number. If this value is given, the - * StringFileInfo block must contain a SpecialBuild string. - */ - -#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) -#else -# ifdef PNG_LIBPNG_SPECIALBUILD -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) -# else -# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) -# endif -#endif - -#ifndef PNG_VERSION_INFO_ONLY - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Version information for C files, stored in png.c. This had better match - * the version above. - */ -#define png_libpng_ver png_get_header_ver(NULL) - -/* This file is arranged in several sections: - * - * 1. Any configuration options that can be specified by for the application - * code when it is built. (Build time configuration is in pnglibconf.h) - * 2. Type definitions (base types are defined in pngconf.h), structure - * definitions. - * 3. Exported library functions. - * - * The library source code has additional files (principally pngpriv.h) that - * allow configuration of the library. - */ -/* Section 1: run time configuration - * See pnglibconf.h for build time configuration - * - * Run time configuration allows the application to choose between - * implementations of certain arithmetic APIs. The default is set - * at build time and recorded in pnglibconf.h, but it is safe to - * override these (and only these) settings. Note that this won't - * change what the library does, only application code, and the - * settings can (and probably should) be made on a per-file basis - * by setting the #defines before including png.h - * - * Use macros to read integers from PNG data or use the exported - * functions? - * PNG_USE_READ_MACROS: use the macros (see below) Note that - * the macros evaluate their argument multiple times. - * PNG_NO_USE_READ_MACROS: call the relevant library function. - * - * Use the alternative algorithm for compositing alpha samples that - * does not use division? - * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' - * algorithm. - * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. - * - * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is - * false? - * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error - * APIs to png_warning. - * Otherwise the calls are mapped to png_error. - */ - -/* Section 2: type definitions, including structures and compile time - * constants. - * See pngconf.h for base types that vary by machine/system - */ - -/* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ -typedef char* png_libpng_version_1_5_8; - -/* Three color definitions. The order of the red, green, and blue, (and the - * exact size) is not important, although the size of the fields need to - * be png_byte or png_uint_16 (as defined below). - */ -typedef struct png_color_struct -{ - png_byte red; - png_byte green; - png_byte blue; -} png_color; -typedef png_color FAR * png_colorp; -typedef PNG_CONST png_color FAR * png_const_colorp; -typedef png_color FAR * FAR * png_colorpp; - -typedef struct png_color_16_struct -{ - png_byte index; /* used for palette files */ - png_uint_16 red; /* for use in red green blue files */ - png_uint_16 green; - png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ -} png_color_16; -typedef png_color_16 FAR * png_color_16p; -typedef PNG_CONST png_color_16 FAR * png_const_color_16p; -typedef png_color_16 FAR * FAR * png_color_16pp; - -typedef struct png_color_8_struct -{ - png_byte red; /* for use in red green blue files */ - png_byte green; - png_byte blue; - png_byte gray; /* for use in grayscale files */ - png_byte alpha; /* for alpha channel files */ -} png_color_8; -typedef png_color_8 FAR * png_color_8p; -typedef PNG_CONST png_color_8 FAR * png_const_color_8p; -typedef png_color_8 FAR * FAR * png_color_8pp; - -/* - * The following two structures are used for the in-core representation - * of sPLT chunks. - */ -typedef struct png_sPLT_entry_struct -{ - png_uint_16 red; - png_uint_16 green; - png_uint_16 blue; - png_uint_16 alpha; - png_uint_16 frequency; -} png_sPLT_entry; -typedef png_sPLT_entry FAR * png_sPLT_entryp; -typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp; -typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; - -/* When the depth of the sPLT palette is 8 bits, the color and alpha samples - * occupy the LSB of their respective members, and the MSB of each member - * is zero-filled. The frequency member always occupies the full 16 bits. - */ - -typedef struct png_sPLT_struct -{ - png_charp name; /* palette name */ - png_byte depth; /* depth of palette samples */ - png_sPLT_entryp entries; /* palette entries */ - png_int_32 nentries; /* number of palette entries */ -} png_sPLT_t; -typedef png_sPLT_t FAR * png_sPLT_tp; -typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp; -typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; - -#ifdef PNG_TEXT_SUPPORTED -/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, - * and whether that contents is compressed or not. The "key" field - * points to a regular zero-terminated C string. The "text" fields can be a - * regular C string, an empty string, or a NULL pointer. - * However, the structure returned by png_get_text() will always contain - * the "text" field as a regular zero-terminated C string (possibly - * empty), never a NULL pointer, so it can be safely used in printf() and - * other string-handling functions. Note that the "itxt_length", "lang", and - * "lang_key" members of the structure only exist when the library is built - * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by - * default without iTXt support. Also note that when iTXt *is* supported, - * the "lang" and "lang_key" fields contain NULL pointers when the - * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or - * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the - * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" - * which is always 0 or 1, or its "compression method" which is always 0. - */ -typedef struct png_text_struct -{ - int compression; /* compression value: - -1: tEXt, none - 0: zTXt, deflate - 1: iTXt, none - 2: iTXt, deflate */ - png_charp key; /* keyword, 1-79 character description of "text" */ - png_charp text; /* comment, may be an empty string (ie "") - or a NULL pointer */ - png_size_t text_length; /* length of the text string */ - png_size_t itxt_length; /* length of the itxt string */ - png_charp lang; /* language code, 0-79 characters - or a NULL pointer */ - png_charp lang_key; /* keyword translated UTF-8 string, 0 or more - chars or a NULL pointer */ -} png_text; -typedef png_text FAR * png_textp; -typedef PNG_CONST png_text FAR * png_const_textp; -typedef png_text FAR * FAR * png_textpp; -#endif - -/* Supported compression types for text in PNG files (tEXt, and zTXt). - * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ -#define PNG_TEXT_COMPRESSION_NONE_WR -3 -#define PNG_TEXT_COMPRESSION_zTXt_WR -2 -#define PNG_TEXT_COMPRESSION_NONE -1 -#define PNG_TEXT_COMPRESSION_zTXt 0 -#define PNG_ITXT_COMPRESSION_NONE 1 -#define PNG_ITXT_COMPRESSION_zTXt 2 -#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ - -/* png_time is a way to hold the time in an machine independent way. - * Two conversions are provided, both from time_t and struct tm. There - * is no portable way to convert to either of these structures, as far - * as I know. If you know of a portable way, send it to me. As a side - * note - PNG has always been Year 2000 compliant! - */ -typedef struct png_time_struct -{ - png_uint_16 year; /* full year, as in, 1995 */ - png_byte month; /* month of year, 1 - 12 */ - png_byte day; /* day of month, 1 - 31 */ - png_byte hour; /* hour of day, 0 - 23 */ - png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ -} png_time; -typedef png_time FAR * png_timep; -typedef PNG_CONST png_time FAR * png_const_timep; -typedef png_time FAR * FAR * png_timepp; - -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -/* png_unknown_chunk is a structure to hold queued chunks for which there is - * no specific support. The idea is that we can use this to queue - * up private chunks for output even though the library doesn't actually - * know about their semantics. - */ -typedef struct png_unknown_chunk_t -{ - png_byte name[5]; - png_byte *data; - png_size_t size; - - /* libpng-using applications should NOT directly modify this byte. */ - png_byte location; /* mode of operation at read time */ -} - - -png_unknown_chunk; -typedef png_unknown_chunk FAR * png_unknown_chunkp; -typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; -typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; -#endif - -/* Values for the unknown chunk location byte */ - -#define PNG_HAVE_IHDR 0x01 -#define PNG_HAVE_PLTE 0x02 -#define PNG_AFTER_IDAT 0x08 - -/* The complete definition of png_info has, as of libpng-1.5.0, - * been moved into a separate header file that is not accessible to - * applications. Read libpng-manual.txt or libpng.3 for more info. - */ -typedef struct png_info_def png_info; -typedef png_info FAR * png_infop; -typedef PNG_CONST png_info FAR * png_const_infop; -typedef png_info FAR * FAR * png_infopp; - -/* Maximum positive integer used in PNG is (2^31)-1 */ -#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) -#define PNG_UINT_32_MAX ((png_uint_32)(-1)) -#define PNG_SIZE_MAX ((png_size_t)(-1)) - -/* These are constants for fixed point values encoded in the - * PNG specification manner (x100000) - */ -#define PNG_FP_1 100000 -#define PNG_FP_HALF 50000 -#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) -#define PNG_FP_MIN (-PNG_FP_MAX) - -/* These describe the color_type field in png_info. */ -/* color type masks */ -#define PNG_COLOR_MASK_PALETTE 1 -#define PNG_COLOR_MASK_COLOR 2 -#define PNG_COLOR_MASK_ALPHA 4 - -/* color types. Note that not all combinations are legal */ -#define PNG_COLOR_TYPE_GRAY 0 -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) -/* aliases */ -#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA -#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA - -/* This is for compression type. PNG 1.0-1.2 only define the single type. */ -#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ -#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE - -/* This is for filter type. PNG 1.0-1.2 only define the single type. */ -#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ -#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ -#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE - -/* These are for the interlacing type. These values should NOT be changed. */ -#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ -#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ -#define PNG_INTERLACE_LAST 2 /* Not a valid value */ - -/* These are for the oFFs chunk. These values should NOT be changed. */ -#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ -#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ -#define PNG_OFFSET_LAST 2 /* Not a valid value */ - -/* These are for the pCAL chunk. These values should NOT be changed. */ -#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ -#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ -#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ -#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ -#define PNG_EQUATION_LAST 4 /* Not a valid value */ - -/* These are for the sCAL chunk. These values should NOT be changed. */ -#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ -#define PNG_SCALE_METER 1 /* meters per pixel */ -#define PNG_SCALE_RADIAN 2 /* radians per pixel */ -#define PNG_SCALE_LAST 3 /* Not a valid value */ - -/* These are for the pHYs chunk. These values should NOT be changed. */ -#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ -#define PNG_RESOLUTION_METER 1 /* pixels/meter */ -#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ - -/* These are for the sRGB chunk. These values should NOT be changed. */ -#define PNG_sRGB_INTENT_PERCEPTUAL 0 -#define PNG_sRGB_INTENT_RELATIVE 1 -#define PNG_sRGB_INTENT_SATURATION 2 -#define PNG_sRGB_INTENT_ABSOLUTE 3 -#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ - -/* This is for text chunks */ -#define PNG_KEYWORD_MAX_LENGTH 79 - -/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ -#define PNG_MAX_PALETTE_LENGTH 256 - -/* These determine if an ancillary chunk's data has been successfully read - * from the PNG header, or if the application has filled in the corresponding - * data in the info_struct to be written into the output file. The values - * of the PNG_INFO_ defines should NOT be changed. - */ -#define PNG_INFO_gAMA 0x0001 -#define PNG_INFO_sBIT 0x0002 -#define PNG_INFO_cHRM 0x0004 -#define PNG_INFO_PLTE 0x0008 -#define PNG_INFO_tRNS 0x0010 -#define PNG_INFO_bKGD 0x0020 -#define PNG_INFO_hIST 0x0040 -#define PNG_INFO_pHYs 0x0080 -#define PNG_INFO_oFFs 0x0100 -#define PNG_INFO_tIME 0x0200 -#define PNG_INFO_pCAL 0x0400 -#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ -#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ -#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ -#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ -#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ - -/* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using - * the routines for other purposes. - */ -typedef struct png_row_info_struct -{ - png_uint_32 width; /* width of row */ - png_size_t rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ -} png_row_info; - -typedef png_row_info FAR * png_row_infop; -typedef png_row_info FAR * FAR * png_row_infopp; - -/* The complete definition of png_struct has, as of libpng-1.5.0, - * been moved into a separate header file that is not accessible to - * applications. Read libpng-manual.txt or libpng.3 for more info. - */ -typedef struct png_struct_def png_struct; -typedef PNG_CONST png_struct FAR * png_const_structp; -typedef png_struct FAR * png_structp; - -/* These are the function types for the I/O functions and for the functions - * that allow the user to override the default I/O functions with his or her - * own. The png_error_ptr type should match that of user-supplied warning - * and error functions, while the png_rw_ptr type should match that of the - * user read/write data functions. Note that the 'write' function must not - * modify the buffer it is passed. The 'read' function, on the other hand, is - * expected to return the read data in the buffer. - */ -typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); -typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); -typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); -typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, - int)); -typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, - int)); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); -typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); - -/* The following callback receives png_uint_32 row_number, int pass for the - * png_bytep data of the row. When transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, - png_uint_32, int)); -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, - png_bytep)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, - png_unknown_chunkp)); -#endif -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This must match the function definition in , and the application - * must include this before png.h to obtain the definition of jmp_buf. The - * function is required to be PNG_NORETURN, but this is not checked. If the - * function does return the application will crash via an abort() or similar - * system level call. - * - * If you get a warning here while building the library you may need to make - * changes to ensure that pnglibconf.h records the calling convention used by - * your compiler. This may be very difficult - try using a different compiler - * to build the library! - */ -PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); -#endif - -/* Transform masks for the high-level interface */ -#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ -#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ -#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ -#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ -#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ -#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ -#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ -#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ -#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ -#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ -#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ -#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ -#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ -/* Added to libpng-1.2.34 */ -#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER -#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ -/* Added to libpng-1.4.0 */ -#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ -/* Added to libpng-1.5.4 */ -#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ - -/* Flags for MNG supported features */ -#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 -#define PNG_FLAG_MNG_FILTER_64 0x04 -#define PNG_ALL_MNG_FEATURES 0x05 - -/* NOTE: prior to 1.5 these functions had no 'API' style declaration, - * this allowed the zlib default functions to be used on Windows - * platforms. In 1.5 the zlib default malloc (which just calls malloc and - * ignores the first argument) should be completely compatible with the - * following. - */ -typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, - png_alloc_size_t)); -typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); - -typedef png_struct FAR * FAR * png_structpp; - -/* Section 3: exported functions - * Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng-manual.txt for the - * full explanation, see example.c for the summary. This just provides - * a simple one line description of the use of each function. - * - * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in - * pngconf.h and in the *.dfn files in the scripts directory. - * - * PNG_EXPORT(ordinal, type, name, (args)); - * - * ordinal: ordinal that is used while building - * *.def files. The ordinal value is only - * relevant when preprocessing png.h with - * the *.dfn files for building symbol table - * entries, and are removed by pngconf.h. - * type: return type of the function - * name: function name - * args: function arguments, with types - * - * When we wish to append attributes to a function prototype we use - * the PNG_EXPORTA() macro instead. - * - * PNG_EXPORTA(ordinal, type, name, (args), attributes); - * - * ordinal, type, name, and args: same as in PNG_EXPORT(). - * attributes: function attributes - */ - -/* Returns the version number of the library */ -PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); - -/* Tell lib we have already handled the first magic bytes. - * Handling more than 8 bytes from the beginning of the file is an error. - */ -PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes)); - -/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a - * PNG file. Returns zero if the supplied bytes match the 8-byte PNG - * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). - */ -PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, - png_size_t num_to_check)); - -/* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). - */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) - -/* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORTA(4, png_structp, png_create_read_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn), - PNG_ALLOCATED); - -/* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORTA(5, png_structp, png_create_write_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn), - PNG_ALLOCATED); - -PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, - (png_const_structp png_ptr)); - -PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, - png_size_t size)); - -/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp - * match up. - */ -#ifdef PNG_SETJMP_SUPPORTED -/* This function returns the jmp_buf built in to *png_ptr. It must be - * supplied with an appropriate 'longjmp' function to use on that jmp_buf - * unless the default error function is overridden in which case NULL is - * acceptable. The size of the jmp_buf is checked against the actual size - * allocated by the library - the call will return NULL on a mismatch - * indicating an ABI mismatch. - */ -PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, - png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); -# define png_jmpbuf(png_ptr) \ - (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) -#else -# define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) -#endif -/* This function should be used by libpng applications in place of - * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it - * will use it; otherwise it will call PNG_ABORT(). This function was - * added in libpng-1.5.0. - */ -PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), - PNG_NORETURN); - -#ifdef PNG_READ_SUPPORTED -/* Reset the compression stream */ -PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); -#endif - -/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(11, png_structp, png_create_read_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -PNG_EXPORTA(12, png_structp, png_create_write_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -#endif - -/* Write the PNG file signature. */ -PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); - -/* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep - chunk_name, png_const_bytep data, png_size_t length)); - -/* Write the start of a PNG chunk - length and chunk name. */ -PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, - png_const_bytep chunk_name, png_uint_32 length)); - -/* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, - png_const_bytep data, png_size_t length)); - -/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ -PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); - -/* Allocate and initialize the info structure */ -PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), - PNG_ALLOCATED); - -PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, - png_size_t png_info_struct_size)); - -/* Writes all the PNG information before the image. */ -PNG_EXPORT(20, void, png_write_info_before_PLTE, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(21, void, png_write_info, - (png_structp png_ptr, png_infop info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. */ -PNG_EXPORT(22, void, png_read_info, - (png_structp png_ptr, png_infop info_ptr)); -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED -PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, - (png_structp png_ptr, - png_const_timep ptime)); -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED -/* Convert from a struct tm to png_time */ -PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, - PNG_CONST struct tm FAR * ttime)); - -/* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(25, void, png_convert_from_time_t, - (png_timep ptime, time_t ttime)); -#endif /* PNG_CONVERT_tIME_SUPPORTED */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ -PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); -PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); -PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); -PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion - * of a tRNS chunk if present. - */ -PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Use blue, green, red order for pixels. */ -PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand the grayscale to 24-bit RGB if necessary. */ -PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB to grayscale. */ -#define PNG_ERROR_ACTION_NONE 1 -#define PNG_ERROR_ACTION_WARN 2 -#define PNG_ERROR_ACTION_ERROR 3 -#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ - -PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, - int error_action, double red, double green)); -PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, - int error_action, png_fixed_point red, png_fixed_point green)); - -PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp - png_ptr)); -#endif - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, - png_colorp palette)); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* How the alpha channel is interpreted - this affects how the color channels of - * a PNG file are returned when an alpha channel, or tRNS chunk in a palette - * file, is present. - * - * This has no effect on the way pixels are written into a PNG output - * datastream. The color samples in a PNG datastream are never premultiplied - * with the alpha samples. - * - * The default is to return data according to the PNG specification: the alpha - * channel is a linear measure of the contribution of the pixel to the - * corresponding composited pixel. The gamma encoded color channels must be - * scaled according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and reencode - * the values. This is the 'PNG' mode. - * - * The alternative is to 'associate' the alpha with the color information by - * storing color channel values that have been scaled by the alpha. The - * advantage is that the color channels can be resampled (the image can be - * scaled) in this form. The disadvantage is that normal practice is to store - * linear, not (gamma) encoded, values and this requires 16-bit channels for - * still images rather than the 8-bit channels that are just about sufficient if - * gamma encoding is used. In addition all non-transparent pixel values, - * including completely opaque ones, must be gamma encoded to produce the final - * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the - * latter being the two common names for associated alpha color channels.) - * - * Since it is not necessary to perform arithmetic on opaque color values so - * long as they are not to be resampled and are in the final color space it is - * possible to optimize the handling of alpha by storing the opaque pixels in - * the PNG format (adjusted for the output color space) while storing partially - * opaque pixels in the standard, linear, format. The accuracy required for - * standard alpha composition is relatively low, because the pixels are - * isolated, therefore typically the accuracy loss in storing 8-bit linear - * values is acceptable. (This is not true if the alpha channel is used to - * simulate transparency over large areas - use 16 bits or the PNG mode in - * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is - * treated as opaque only if the alpha value is equal to the maximum value. - * - * The final choice is to gamma encode the alpha channel as well. This is - * broken because, in practice, no implementation that uses this choice - * correctly undoes the encoding before handling alpha composition. Use this - * choice only if other serious errors in the software or hardware you use - * mandate it; the typical serious error is for dark halos to appear around - * opaque areas of the composited PNG image because of arithmetic overflow. - * - * The API function png_set_alpha_mode specifies which of these choices to use - * with an enumerated 'mode' value and the gamma of the required output: - */ -#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ -#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ -#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ -#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ -#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ -#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ - -PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode, - double output_gamma)); -PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr, - int mode, png_fixed_point output_gamma)); -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* The output_gamma value is a screen gamma in libpng terminology: it expresses - * how to decode the output values, not how they are encoded. The values used - * correspond to the normal numbers used to describe the overall gamma of a - * computer display system; for example 2.2 for an sRGB conformant system. The - * values are scaled by 100000 in the _fixed version of the API (so 220000 for - * sRGB.) - * - * The inverse of the value is always used to provide a default for the PNG file - * encoding if it has no gAMA chunk and if png_set_gamma() has not been called - * to override the PNG gamma information. - * - * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode - * opaque pixels however pixels with lower alpha values are not encoded, - * regardless of the output gamma setting. - * - * When the standard Porter Duff handling is requested with mode 1 the output - * encoding is set to be linear and the output_gamma value is only relevant - * as a default for input data that has no gamma information. The linear output - * encoding will be overridden if png_set_gamma() is called - the results may be - * highly unexpected! - * - * The following numbers are derived from the sRGB standard and the research - * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of - * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing - * correction required to take account of any differences in the color - * environment of the original scene and the intended display environment; the - * value expresses how to *decode* the image for display, not how the original - * data was *encoded*. - * - * sRGB provides a peg for the PNG standard by defining a viewing environment. - * sRGB itself, and earlier TV standards, actually use a more complex transform - * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is - * limited to simple power laws.) By saying that an image for direct display on - * an sRGB conformant system should be stored with a gAMA chunk value of 45455 - * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification - * makes it possible to derive values for other display systems and - * environments. - * - * The Mac value is deduced from the sRGB based on an assumption that the actual - * extra viewing correction used in early Mac display systems was implemented as - * a power 1.45 lookup table. - * - * Any system where a programmable lookup table is used or where the behavior of - * the final display device characteristics can be changed requires system - * specific code to obtain the current characteristic. However this can be - * difficult and most PNG gamma correction only requires an approximate value. - * - * By default, if png_set_alpha_mode() is not called, libpng assumes that all - * values are unencoded, linear, values and that the output device also has a - * linear characteristic. This is only very rarely correct - it is invariably - * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the - * default if you don't know what the right answer is! - * - * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS - * 10.6) which used a correction table to implement a somewhat lower gamma on an - * otherwise sRGB system. - * - * Both these values are reserved (not simple gamma values) in order to allow - * more precise correction internally in the future. - * - * NOTE: the following values can be passed to either the fixed or floating - * point APIs, but the floating point API will also accept floating point - * values. - */ -#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ -#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ -#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ -#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ -#endif - -/* The following are examples of calls to png_set_alpha_mode to achieve the - * required overall gamma correction and, where necessary, alpha - * premultiplication. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * This is the default libpng handling of the alpha channel - it is not - * pre-multiplied into the color components. In addition the call states - * that the output is for a sRGB system and causes all PNG files without gAMA - * chunks to be assumed to be encoded using sRGB. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * In this case the output is assumed to be something like an sRGB conformant - * display preceeded by a power-law lookup table of power 1.45. This is how - * early Mac systems behaved. - * - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); - * This is the classic Jim Blinn approach and will work in academic - * environments where everything is done by the book. It has the shortcoming - * of assuming that input PNG data with no gamma information is linear - this - * is unlikely to be correct unless the PNG files where generated locally. - * Most of the time the output precision will be so low as to show - * significant banding in dark areas of the image. - * - * png_set_expand_16(pp); - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); - * This is a somewhat more realistic Jim Blinn inspired approach. PNG files - * are assumed to have the sRGB encoding if not marked with a gamma value and - * the output is always 16 bits per component. This permits accurate scaling - * and processing of the data. If you know that your input PNG files were - * generated locally you might need to replace PNG_DEFAULT_sRGB with the - * correct value for your system. - * - * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); - * If you just need to composite the PNG image onto an existing background - * and if you control the code that does this you can use the optimization - * setting. In this case you just copy completely opaque pixels to the - * output. For pixels that are not completely transparent (you just skip - * those) you do the composition math using png_composite or png_composite_16 - * below then encode the resultant 8-bit or 16-bit values to match the output - * encoding. - * - * Other cases - * If neither the PNG nor the standard linear encoding work for you because - * of the software or hardware you use then you have a big problem. The PNG - * case will probably result in halos around the image. The linear encoding - * will probably result in a washed out, too bright, image (it's actually too - * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably - * substantially reduce the halos. Alternatively try: - * - * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); - * This option will also reduce the halos, but there will be slight dark - * halos round the opaque parts of the image where the background is light. - * In the OPTIMIZED mode the halos will be light halos where the background - * is dark. Take your pick - the halos are unavoidable unless you can get - * your hardware/software fixed! (The OPTIMIZED approach is slightly - * faster.) - * - * When the default gamma of PNG files doesn't match the output gamma. - * If you have PNG files with no gamma information png_set_alpha_mode allows - * you to provide a default gamma, but it also sets the ouput gamma to the - * matching value. If you know your PNG files have a gamma that doesn't - * match the output you can take advantage of the fact that - * png_set_alpha_mode always sets the output gamma but only sets the PNG - * default if it is not already set: - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * The first call sets both the default and the output gamma values, the - * second call overrides the output gamma without changing the default. This - * is easier than achieving the same effect with png_set_gamma. You must use - * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will - * fire if more than one call to png_set_alpha_mode and png_set_background is - * made in the same read operation, however multiple calls with PNG_ALPHA_PNG - * are ignored. - */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(39, void, png_set_filler, (png_structp png_ptr, png_uint_32 filler, - int flags)); -/* The values of the PNG_FILLER_ defines should NOT be changed */ -# define PNG_FILLER_BEFORE 0 -# define PNG_FILLER_AFTER 1 -/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(40, void, png_set_add_alpha, - (png_structp png_ptr, png_uint_32 filler, - int flags)); -#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swap bytes in 16-bit depth files. */ -PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ -PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Swap packing order of pixels in bytes. */ -PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -/* Converts files to legal bit depths. */ -PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p - true_bits)); -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. - * MUST be called before png_read_update_info or png_start_read_image, - * otherwise it will not have the desired effect. Note that it is still - * necessary to call png_read_row or png_read_rows png_get_image_height - * times for each pass. -*/ -PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -/* Invert monochrome files */ -PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS by replacing with a background color. Prior to - * libpng-1.5.4 this API must not be called before the PNG file header has been - * read. Doing so will result in unexpected behavior and possible warnings or - * errors if the PNG file contains a bKGD chunk. - */ -PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma)); -PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma)); -#endif -#ifdef PNG_READ_BACKGROUND_SUPPORTED -# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -# define PNG_BACKGROUND_GAMMA_SCREEN 1 -# define PNG_BACKGROUND_GAMMA_FILE 2 -# define PNG_BACKGROUND_GAMMA_UNIQUE 3 -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale a 16-bit depth file down to 8-bit, accurately. */ -PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ -/* Strip the second byte of information from a 16-bit depth file. */ -PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Turn on quantizing, and reduce the palette to the number of colors - * available. - */ -PNG_EXPORT(49, void, png_set_quantize, - (png_structp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The threshold on gamma processing is configurable but hard-wired into the - * library. The following is the floating point variant. - */ -#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) - -/* Handle gamma correction. Screen_gamma=(display_exponent). - * NOTE: this API simply sets the screen and file gamma values. It will - * therefore override the value for gamma in a PNG file if it is called after - * the file header has been read - use with care - call before reading the PNG - * file for best results! - * - * These routines accept the same gamma values as png_set_alpha_mode (described - * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either - * API (floating point or fixed.) Notice, however, that the 'file_gamma' value - * is the inverse of a 'screen gamma' value. - */ -PNG_FP_EXPORT(50, void, png_set_gamma, - (png_structp png_ptr, double screen_gamma, - double override_file_gamma)); -PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, - png_fixed_point screen_gamma, png_fixed_point override_file_gamma)); -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set how many lines between output flushes - 0 for no flushing */ -PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); -/* Flush the current PNG output buffer */ -PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); -#endif - -/* Optional update palette with requested transformations */ -PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); - -/* Optional call to update the users info structure */ -PNG_EXPORT(54, void, png_read_update_info, - (png_structp png_ptr, png_infop info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. */ -PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read a row of data. */ -PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, - png_bytep display_row)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the whole image into memory at once. */ -PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); -#endif - -/* Write a row of image data */ -PNG_EXPORT(58, void, png_write_row, - (png_structp png_ptr, png_const_bytep row)); - -/* Write a few rows of image data: (*row) is not written; however, the type - * is declared as writeable to maintain compatibility with previous versions - * of libpng and to allow the 'display_row' array from read_rows to be passed - * unchanged to write_rows. - */ -PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, - png_uint_32 num_rows)); - -/* Write the image data */ -PNG_EXPORT(60, void, png_write_image, - (png_structp png_ptr, png_bytepp image)); - -/* Write the end of the PNG file. */ -PNG_EXPORT(61, void, png_write_end, - (png_structp png_ptr, png_infop info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. */ -PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); -#endif - -/* Free any memory associated with the png_info_struct */ -PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, - png_infopp info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr)); - -/* Set the libpng method of handling chunk CRC errors */ -PNG_EXPORT(66, void, png_set_crc_action, - (png_structp png_ptr, int crit_action, int ancil_action)); - -/* Values for png_set_crc_action() say how to handle CRC errors in - * ancillary and critical chunks, and whether to use the data contained - * therein. Note that it is impossible to "discard" data in a critical - * chunk. For versions prior to 0.90, the action was always error/quit, - * whereas in version 0.90 and later, the action for CRC errors in ancillary - * chunks is warn/discard. These values should NOT be changed. - * - * value action:critical action:ancillary - */ -#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ -#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ -#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ -#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ -#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ -#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ - -/* These functions give the user control over the scan-line filtering in - * libpng and the compression methods used by zlib. These functions are - * mainly useful for testing, as the defaults should work with most users. - * Those users who are tight on memory or want faster performance at the - * expense of compression can modify them. See the compression library - * header file (zlib.h) for an explination of the compression functions. - */ - -/* Set the filtering method(s) used by libpng. Currently, the only valid - * value for "method" is 0. - */ -PNG_EXPORT(67, void, png_set_filter, - (png_structp png_ptr, int method, int filters)); - -/* Flags for png_set_filter() to say which filters to use. The flags - * are chosen so that they don't conflict with real filter types - * below, in case they are supplied instead of the #defined constants. - * These values should NOT be changed. - */ -#define PNG_NO_FILTERS 0x00 -#define PNG_FILTER_NONE 0x08 -#define PNG_FILTER_SUB 0x10 -#define PNG_FILTER_UP 0x20 -#define PNG_FILTER_AVG 0x40 -#define PNG_FILTER_PAETH 0x80 -#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ - PNG_FILTER_AVG | PNG_FILTER_PAETH) - -/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. - * These defines should NOT be changed. - */ -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 -#define PNG_FILTER_VALUE_LAST 5 - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ -/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ - * defines, either the default (minimum-sum-of-absolute-differences), or - * the experimental method (weighted-minimum-sum-of-absolute-differences). - * - * Weights are factors >= 1.0, indicating how important it is to keep the - * filter type consistent between rows. Larger numbers mean the current - * filter is that many times as likely to be the same as the "num_weights" - * previous filters. This is cumulative for each previous row with a weight. - * There needs to be "num_weights" values in "filter_weights", or it can be - * NULL if the weights aren't being specified. Weights have no influence on - * the selection of the first row filter. Well chosen weights can (in theory) - * improve the compression for a given image. - * - * Costs are factors >= 1.0 indicating the relative decoding costs of a - * filter type. Higher costs indicate more decoding expense, and are - * therefore less likely to be selected over a filter with lower computational - * costs. There needs to be a value in "filter_costs" for each valid filter - * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't - * setting the costs. Costs try to improve the speed of decompression without - * unduly increasing the compressed image size. - * - * A negative weight or cost indicates the default value is to be used, and - * values in the range [0.0, 1.0) indicate the value is to remain unchanged. - * The default values for both weights and costs are currently 1.0, but may - * change if good general weighting/cost heuristics can be found. If both - * the weights and costs are set to 1.0, this degenerates the WEIGHTED method - * to the UNWEIGHTED method, but with added encoding time/computation. - */ -PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, - int heuristic_method, int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs)); -PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, - (png_structp png_ptr, - int heuristic_method, int num_weights, png_const_fixed_point_p - filter_weights, png_const_fixed_point_p filter_costs)); -#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ - -/* Heuristic used for row filter selection. These defines should NOT be - * changed. - */ -#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ -#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ -#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ -#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ - -#ifdef PNG_WRITE_SUPPORTED -/* Set the library compression level. Currently, valid values range from - * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 - * (0 - no compression, 9 - "maximal" compression). Note that tests have - * shown that zlib compression levels 3-6 usually perform as well as level 9 - * for PNG images, and do considerably fewer caclulations. In the future, - * these values may not correspond directly to the zlib compression levels. - */ -PNG_EXPORT(69, void, png_set_compression_level, - (png_structp png_ptr, int level)); - -PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, - int mem_level)); - -PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, - int window_bits)); - -PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, - int method)); -#endif - -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -/* Also set zlib parameters for compressing non-IDAT chunks */ -PNG_EXPORT(222, void, png_set_text_compression_level, - (png_structp png_ptr, int level)); - -PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr, - int mem_level)); - -PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp - png_ptr, int window_bits)); - -PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr, - int method)); -#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ - -/* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, - * and call standard C I/O routines such as fread(), fwrite(), and - * fprintf(). These functions can be made to use other I/O routines - * at run time for those applications that need to handle I/O in a - * different manner by calling png_set_???_fn(). See libpng-manual.txt for - * more information. - */ - -#ifdef PNG_STDIO_SUPPORTED -/* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp)); -#endif - -/* Replace the (error and abort), and warning functions with user - * supplied functions. If no messages are to be printed you must still - * write and use replacement functions. The replacement error_fn should - * still do a longjmp to the last setjmp location if you are using this - * method of error handling. If error_fn or warning_fn is NULL, the - * default function will be used. - */ - -PNG_EXPORT(75, void, png_set_error_fn, - (png_structp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn)); - -/* Return the user pointer associated with the error functions */ -PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structp png_ptr)); - -/* Replace the default data output functions with a user supplied one(s). - * If buffered output is not used, then output_flush_fn can be set to NULL. - * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time - * output_flush_fn will be ignored (and thus can be NULL). - * It is probably a mistake to use NULL for output_flush_fn if - * write_data_fn is not also NULL unless you have built libpng with - * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's - * default flush function, which uses the standard *FILE structure, will - * be used. - */ -PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - -/* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn)); - -/* Return the user pointer associated with the I/O functions */ -PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); - -PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, - png_read_status_ptr read_row_fn)); - -PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr, - png_write_status_ptr write_row_fn)); - -#ifdef PNG_USER_MEM_SUPPORTED -/* Replace the default memory allocation functions with user supplied one(s). */ -PNG_EXPORT(82, void, png_set_mem_fn, (png_structp png_ptr, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)); -/* Return the user pointer associated with the memory functions */ -PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr)); -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, - png_user_transform_ptr read_user_transform_fn)); -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, - png_user_transform_ptr write_user_transform_fn)); -#endif - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr, - png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); -/* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, - (png_const_structp png_ptr)); -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -/* Return information about the row currently being processed. Note that these - * APIs do not fail but will return unexpected results if called outside a user - * transform callback. Also note that when transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp)); -PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, - png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structp png_ptr)); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* Sets the function callbacks for the push reader, and a pointer to a - * user-defined structure available to the callback functions. - */ -PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr, - png_voidp progressive_ptr, png_progressive_info_ptr info_fn, - png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); - -/* Returns the user pointer associated with the push read functions */ -PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr)); - -/* Function to be called when data becomes available */ -PNG_EXPORT(92, void, png_process_data, - (png_structp png_ptr, png_infop info_ptr, - png_bytep buffer, png_size_t buffer_size)); - -/* A function which may be called *only* within png_process_data to stop the - * processing of any more data. The function returns the number of bytes - * remaining, excluding any that libpng has cached internally. A subsequent - * call to png_process_data must supply these bytes again. If the argument - * 'save' is set to true the routine will first save all the pending data and - * will always return 0. - */ -PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save)); - -/* A function which may be called *only* outside (after) a call to - * png_process_data. It returns the number of bytes of data to skip in the - * input. Normally it will return 0, but if it returns a non-zero value the - * application must skip than number of bytes of input data and pass the - * following data to the next call to png_process_data. - */ -PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); - -#ifdef PNG_READ_INTERLACING_SUPPORTED -/* Function that combines rows. 'new_row' is a flag that should come from - * the callback and be non-NULL if anything needs to be done; the library - * stores its own version of the new data internally and ignores the passed - * in value. - */ -PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, - png_bytep old_row, png_const_bytep new_row)); -#endif /* PNG_READ_INTERLACING_SUPPORTED */ -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - -PNG_EXPORTA(94, png_voidp, png_malloc, - (png_structp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED); -/* Added at libpng version 1.4.0 */ -PNG_EXPORTA(95, png_voidp, png_calloc, - (png_structp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED); - -/* Added at libpng version 1.2.4 */ -PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Frees a pointer allocated by png_malloc() */ -PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); - -/* Free data that was allocated internally */ -PNG_EXPORT(98, void, png_free_data, - (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); - -/* Reassign responsibility for freeing existing data, whether allocated - * by libpng or by the application */ -PNG_EXPORT(99, void, png_data_freer, - (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); - -/* Assignments for png_data_freer */ -#define PNG_DESTROY_WILL_FREE_DATA 1 -#define PNG_SET_WILL_FREE_DATA 1 -#define PNG_USER_WILL_FREE_DATA 2 -/* Flags for png_ptr->free_me and info_ptr->free_me */ -#define PNG_FREE_HIST 0x0008 -#define PNG_FREE_ICCP 0x0010 -#define PNG_FREE_SPLT 0x0020 -#define PNG_FREE_ROWS 0x0040 -#define PNG_FREE_PCAL 0x0080 -#define PNG_FREE_SCAL 0x0100 -#define PNG_FREE_UNKN 0x0200 -#define PNG_FREE_LIST 0x0400 -#define PNG_FREE_PLTE 0x1000 -#define PNG_FREE_TRNS 0x2000 -#define PNG_FREE_TEXT 0x4000 -#define PNG_FREE_ALL 0x7fff -#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ - -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); -PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); -#endif - -#ifdef PNG_ERROR_TEXT_SUPPORTED -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(102, void, png_error, - (png_structp png_ptr, png_const_charp error_message), - PNG_NORETURN); - -/* The same, but the chunk name is prepended to the error string. */ -PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, - png_const_charp error_message), PNG_NORETURN); - -#else -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* Non-fatal error in libpng. Can continue, but may have a problem. */ -PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, - png_const_charp warning_message)); - -/* Non-fatal error in libpng, chunk name is prepended to message. */ -PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, - png_const_charp warning_message)); -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Benign error in libpng. Can continue, but may have a problem. - * User can choose whether to handle as a fatal error or as a warning. */ -# undef png_benign_error -PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, - png_const_charp warning_message)); - -/* Same, chunk name is prepended to message. */ -# undef png_chunk_benign_error -PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, - png_const_charp warning_message)); - -PNG_EXPORT(109, void, png_set_benign_errors, - (png_structp png_ptr, int allowed)); -#else -# ifdef PNG_ALLOW_BENIGN_ERRORS -# define png_benign_error png_warning -# define png_chunk_benign_error png_chunk_warning -# else -# define png_benign_error png_error -# define png_chunk_benign_error png_chunk_error -# endif -#endif - -/* The png_set_ functions are for storing values in the png_info_struct. - * Similarly, the png_get_ calls are used to read values from the - * png_info_struct, either storing the parameters in the passed variables, or - * setting pointers into the png_info_struct where the data is stored. The - * png_get_ functions return a non-zero value if the data was available - * in info_ptr, or return zero and do not change any of the parameters if the - * data was not available. - * - * These functions should be used instead of directly accessing png_info - * to avoid problems with future changes in the size and internal layout of - * png_info_struct. - */ -/* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(110, png_uint_32, png_get_valid, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_32 flag)); - -/* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* Returns row_pointers, which is an array of pointers to scanlines that was - * returned from png_read_png(). - */ -PNG_EXPORT(112, png_bytepp, png_get_rows, - (png_const_structp png_ptr, png_const_infop info_ptr)); -/* Set row_pointers, which is an array of pointers to scanlines for use - * by png_write_png(). - */ -PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, - png_infop info_ptr, png_bytepp row_pointers)); -#endif - -/* Returns number of color channels in image. */ -PNG_EXPORT(114, png_byte, png_get_channels, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Returns image width in pixels. */ -PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image height in pixels. */ -PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image bit_depth. */ -PNG_EXPORT(117, png_byte, png_get_bit_depth, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -/* Returns image color_type. */ -PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image filter_type. */ -PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image interlace_type. */ -PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image compression_type. */ -PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr, - png_const_infop info_ptr)); - -/* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -/* Returns pixel aspect ratio, computed from pHYs chunk data. */ -PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, - (png_const_structp png_ptr, png_const_infop info_ptr)); -PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -#endif /* PNG_EASY_ACCESS_SUPPORTED */ - -/* Returns pointer to signature string read from PNG header */ -PNG_EXPORT(130, png_const_bytep, png_get_signature, - (png_const_structp png_ptr, png_infop info_ptr)); - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(131, png_uint_32, png_get_bKGD, - (png_const_structp png_ptr, png_infop info_ptr, - png_color_16p *background)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, - png_const_color_16p background)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr, - png_const_infop info_ptr, double *white_x, double *white_y, double *red_x, - double *red_y, double *green_x, double *green_y, double *blue_x, - double *blue_y)); -PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_structp png_ptr, - png_const_infop info_ptr, double *red_X, double *red_Y, double *red_Z, - double *green_X, double *green_Y, double *green_Z, double *blue_X, - double *blue_Y, double *blue_Z)); -#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ -PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, - (png_const_structp png_ptr, - png_const_infop info_ptr, png_fixed_point *int_white_x, - png_fixed_point *int_white_y, png_fixed_point *int_red_x, - png_fixed_point *int_red_y, png_fixed_point *int_green_x, - png_fixed_point *int_green_y, png_fixed_point *int_blue_x, - png_fixed_point *int_blue_y)); -#endif -PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, - (png_structp png_ptr, png_const_infop info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(135, void, png_set_cHRM, - (png_structp png_ptr, png_infop info_ptr, - double white_x, double white_y, double red_x, double red_y, double green_x, - double green_y, double blue_x, double blue_y)); -PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_structp png_ptr, - png_infop info_ptr, double red_X, double red_Y, double red_Z, - double green_X, double green_Y, double green_Z, double blue_X, - double blue_Y, double blue_Z)); -PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr, - png_infop info_ptr, png_fixed_point int_white_x, - png_fixed_point int_white_y, png_fixed_point int_red_x, - png_fixed_point int_red_y, png_fixed_point int_green_x, - png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); -PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_structp png_ptr, - png_infop info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z)); -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, - (png_const_structp png_ptr, png_const_infop info_ptr, - double *file_gamma)); -PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_fixed_point *int_file_gamma)); -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, - png_infop info_ptr, double file_gamma)); -PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, - png_infop info_ptr, png_fixed_point int_file_gamma)); -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(141, png_uint_32, png_get_hIST, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_16p *hist)); -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, - png_infop info_ptr, png_const_uint_16p hist)); -#endif - -PNG_EXPORT(143, png_uint_32, png_get_IHDR, - (png_structp png_ptr, png_infop info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, - int *interlace_method, int *compression_method, int *filter_method)); - -PNG_EXPORT(144, void, png_set_IHDR, - (png_structp png_ptr, png_infop info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, - int interlace_method, int compression_method, int filter_method)); - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(145, png_uint_32, png_get_oFFs, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); -#endif - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(146, void, png_set_oFFs, - (png_structp png_ptr, png_infop info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(147, png_uint_32, png_get_pCAL, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, - int *nparams, - png_charp *units, png_charpp *params)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, - png_infop info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(149, png_uint_32, png_get_pHYs, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(150, void, png_set_pHYs, - (png_structp png_ptr, png_infop info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -#endif - -PNG_EXPORT(151, png_uint_32, png_get_PLTE, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_colorp *palette, int *num_palette)); - -PNG_EXPORT(152, void, png_set_PLTE, - (png_structp png_ptr, png_infop info_ptr, - png_const_colorp palette, int num_palette)); - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(153, png_uint_32, png_get_sBIT, - (png_const_structp png_ptr, png_infop info_ptr, - png_color_8p *sig_bit)); -#endif - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(154, void, png_set_sBIT, - (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr, - png_const_infop info_ptr, int *file_srgb_intent)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(156, void, png_set_sRGB, - (png_structp png_ptr, png_infop info_ptr, int srgb_intent)); -PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, - png_infop info_ptr, int srgb_intent)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(158, png_uint_32, png_get_iCCP, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_charpp name, int *compression_type, png_bytepp profile, - png_uint_32 *proflen)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(159, void, png_set_iCCP, - (png_structp png_ptr, png_infop info_ptr, - png_const_charp name, int compression_type, png_const_bytep profile, - png_uint_32 proflen)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(160, png_uint_32, png_get_sPLT, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_sPLT_tpp entries)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(161, void, png_set_sPLT, - (png_structp png_ptr, png_infop info_ptr, - png_const_sPLT_tp entries, int nentries)); -#endif - -#ifdef PNG_TEXT_SUPPORTED -/* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(162, png_uint_32, png_get_text, - (png_const_structp png_ptr, png_const_infop info_ptr, - png_textp *text_ptr, int *num_text)); -#endif - -/* Note while png_set_text() will accept a structure whose text, - * language, and translated keywords are NULL pointers, the structure - * returned by png_get_text will always contain regular - * zero-terminated C strings. They might be empty strings but - * they will never be NULL pointers. - */ - -#ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(163, void, png_set_text, - (png_structp png_ptr, png_infop info_ptr, - png_const_textp text_ptr, int num_text)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(164, png_uint_32, png_get_tIME, - (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(165, void, png_set_tIME, - (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(166, png_uint_32, png_get_tRNS, - (png_const_structp png_ptr, png_infop info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(167, void, png_set_tRNS, - (png_structp png_ptr, png_infop info_ptr, - png_const_bytep trans_alpha, int num_trans, - png_const_color_16p trans_color)); -#endif - -#ifdef PNG_sCAL_SUPPORTED -PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, - (png_const_structp png_ptr, png_const_infop info_ptr, - int *unit, double *width, double *height)); -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* NOTE: this API is currently implemented using floating point arithmetic, - * consequently it can only be used on systems with floating point support. - * In any case the range of values supported by png_fixed_point is small and it - * is highly recommended that png_get_sCAL_s be used instead. - */ -PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, - (png_structp png_ptr, png_const_infop info_ptr, int *unit, - png_fixed_point *width, - png_fixed_point *height)); -#endif -PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, - (png_const_structp png_ptr, png_const_infop info_ptr, - int *unit, png_charpp swidth, png_charpp sheight)); - -PNG_FP_EXPORT(170, void, png_set_sCAL, - (png_structp png_ptr, png_infop info_ptr, - int unit, double width, double height)); -PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, - png_infop info_ptr, int unit, png_fixed_point width, - png_fixed_point height)); -PNG_EXPORT(171, void, png_set_sCAL_s, - (png_structp png_ptr, png_infop info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight)); -#endif /* PNG_sCAL_SUPPORTED */ - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -/* Provide a list of chunks and how they are to be handled, if the built-in - handling or default unknown chunk handling is not desired. Any chunks not - listed will be handled in the default manner. The IHDR and IEND chunks - must not be listed. Because this turns off the default handling for chunks - that would otherwise be recognized the behavior of libpng transformations may - well become incorrect! - keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior - = 1: PNG_HANDLE_CHUNK_NEVER: do not keep - = 2: PNG_HANDLE_CHUNK_IF_SAFE: keep only if safe-to-copy - = 3: PNG_HANDLE_CHUNK_ALWAYS: keep even if unsafe-to-copy -*/ -PNG_EXPORT(172, void, png_set_keep_unknown_chunks, - (png_structp png_ptr, int keep, - png_const_bytep chunk_list, int num_chunks)); - -/* The handling code is returned; the result is therefore true (non-zero) if - * special handling is required, false for the default handling. - */ -PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, - png_const_bytep chunk_name)); -#endif -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, - png_infop info_ptr, png_const_unknown_chunkp unknowns, - int num_unknowns)); -PNG_EXPORT(175, void, png_set_unknown_chunk_location, - (png_structp png_ptr, png_infop info_ptr, int chunk, int location)); -PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr, - png_const_infop info_ptr, png_unknown_chunkpp entries)); -#endif - -/* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, - * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); - */ -PNG_EXPORT(177, void, png_set_invalid, - (png_structp png_ptr, png_infop info_ptr, int mask)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* The "params" pointer is currently not used and is for future expansion. */ -PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, - int transforms, png_voidp params)); -PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, - int transforms, png_voidp params)); -#endif - -PNG_EXPORT(180, png_const_charp, png_get_copyright, - (png_const_structp png_ptr)); -PNG_EXPORT(181, png_const_charp, png_get_header_ver, - (png_const_structp png_ptr)); -PNG_EXPORT(182, png_const_charp, png_get_header_version, - (png_const_structp png_ptr)); -PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, - (png_const_structp png_ptr)); - -#ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr, - png_uint_32 mng_features_permitted)); -#endif - -/* For use in png_set_keep_unknown, added to version 1.2.6 */ -#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 -#define PNG_HANDLE_CHUNK_NEVER 1 -#define PNG_HANDLE_CHUNK_IF_SAFE 2 -#define PNG_HANDLE_CHUNK_ALWAYS 3 - -/* Strip the prepended error numbers ("#nnn ") from error and warning - * messages before passing them to the error or warning handler. - */ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -PNG_EXPORT(185, void, png_set_strip_error_numbers, - (png_structp png_ptr, - png_uint_32 strip_mode)); -#endif - -/* Added in libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, - png_uint_32 user_width_max, png_uint_32 user_height_max)); -PNG_EXPORT(187, png_uint_32, png_get_user_width_max, - (png_const_structp png_ptr)); -PNG_EXPORT(188, png_uint_32, png_get_user_height_max, - (png_const_structp png_ptr)); -/* Added in libpng-1.4.0 */ -PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, - png_uint_32 user_chunk_cache_max)); -PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, - (png_const_structp png_ptr)); -/* Added in libpng-1.4.1 */ -PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, - png_alloc_size_t user_chunk_cache_max)); -PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, - (png_const_structp png_ptr)); -#endif - -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) -PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, - (png_const_structp png_ptr, png_const_infop info_ptr)); - -PNG_FP_EXPORT(196, float, png_get_x_offset_inches, - (png_const_structp png_ptr, png_const_infop info_ptr)); -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, - (png_structp png_ptr, png_const_infop info_ptr)); -#endif - -PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr, - png_const_infop info_ptr)); -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, - (png_structp png_ptr, png_const_infop info_ptr)); -#endif - -# ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr, - png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -# endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ - -/* Added in libpng-1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); - -PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name, - (png_structp png_ptr), PNG_DEPRECATED); -PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, - (png_const_structp png_ptr)); - -/* The flags returned by png_get_io_state() are the following: */ -# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ -# define PNG_IO_READING 0x0001 /* currently reading */ -# define PNG_IO_WRITING 0x0002 /* currently writing */ -# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ -# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ -# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ -# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ -# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ -# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ -#endif /* ?PNG_IO_STATE_SUPPORTED */ - -/* Interlace support. The following macros are always defined so that if - * libpng interlace handling is turned off the macros may be used to handle - * interlaced images within the application. - */ -#define PNG_INTERLACE_ADAM7_PASSES 7 - -/* Two macros to return the first row and first column of the original, - * full, image which appears in a given pass. 'pass' is in the range 0 - * to 6 and the result is in the range 0 to 7. - */ -#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) -#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) - -/* A macro to return the offset between pixels in the output row for a pair of - * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that - * follows. Note that ROW_OFFSET is the offset from one row to the next whereas - * COL_OFFSET is from one column to the next, within a row. - */ -#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) -#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) - -/* Two macros to help evaluate the number of rows or columns in each - * pass. This is expressed as a shift - effectively log2 of the number or - * rows or columns in each 8x8 tile of the original image. - */ -#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) -#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) - -/* Hence two macros to determine the number of rows or columns in a given - * pass of an image given its height or width. In fact these macros may - * return non-zero even though the sub-image is empty, because the other - * dimension may be empty for a small image. - */ -#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) -#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) - -/* For the reader row callbacks (both progressive and sequential) it is - * necessary to find the row in the output image given a row in an interlaced - * image, so two more macros: - */ -#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ - (((yIn)<>(((7-(off))-(pass))<<2)) & 0xF) | \ - ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) - -#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ - ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) -#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ - ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) - -#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED -/* With these routines we avoid an integer divide, which will be slower on - * most machines. However, it does take more operations than the corresponding - * divide method, so it may be slower on a few RISC systems. There are two - * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. - * - * Note that the rounding factors are NOT supposed to be the same! 128 and - * 32768 are correct for the NODIV code; 127 and 32767 are correct for the - * standard method. - * - * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] - */ - - /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ - -# define png_composite(composite, fg, alpha, bg) \ - { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ - - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } - -# define png_composite_16(composite, fg, alpha, bg) \ - { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ - + (png_uint_32)(bg)*(65535 \ - - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } - -#else /* Standard method using integer division */ - -# define png_composite(composite, fg, alpha, bg) \ - (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - 127) / 255) - -# define png_composite_16(composite, fg, alpha, bg) \ - (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ - 32767) / 65535) -#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); -PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); -PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); -#endif - -PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, - png_const_bytep buf)); -/* No png_get_int_16 -- may be added if there's a real need for it. */ - -/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); -#endif -#ifdef PNG_SAVE_INT_32_SUPPORTED -PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); -#endif - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); -/* No png_save_int_16 -- may be added if there's a real need for it. */ -#endif - -#ifdef PNG_USE_READ_MACROS -/* Inline macros to do direct reads of bytes from the input buffer. - * The png_get_int_32() routine assumes we are using two's complement - * format for negative values, which is almost certainly true. - */ -# define png_get_uint_32(buf) \ - (((png_uint_32)(*(buf)) << 24) + \ - ((png_uint_32)(*((buf) + 1)) << 16) + \ - ((png_uint_32)(*((buf) + 2)) << 8) + \ - ((png_uint_32)(*((buf) + 3)))) - - /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the - * function) incorrectly returned a value of type png_uint_32. - */ -# define png_get_uint_16(buf) \ - ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) - -# define png_get_int_32(buf) \ - ((png_int_32)((*(buf) & 0x80) \ - ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ - : (png_int_32)png_get_uint_32(buf))) -#endif - -/* Maintainer: Put new public prototypes here ^, in libpng.3, and project - * defs - */ - -/* The last ordinal number (this is the *last* one already used; the next - * one to use is one more than this.) Maintainer, remember to add an entry to - * scripts/symbols.def as well. - */ -#ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(233); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -/* Do not put anything past this line */ -#endif /* PNG_H */ diff --git a/WDL/libpng/pngconf.h b/WDL/libpng/pngconf.h deleted file mode 100644 index f68c8d7c..00000000 --- a/WDL/libpng/pngconf.h +++ /dev/null @@ -1,596 +0,0 @@ - -/* pngconf.h - machine configurable file for libpng - * - * libpng version 1.5.8 - February 1, 2012 - * - * Copyright (c) 1998-2012 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - */ - -/* Any machine specific code is near the front of this file, so if you - * are configuring libpng for a machine, you may want to read the section - * starting here down to where it starts to typedef png_color, png_text, - * and png_info. - */ - -#ifndef PNGCONF_H -#define PNGCONF_H - -#ifndef PNG_BUILDING_SYMBOL_TABLE -/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C - * definition file for machine specific limits, this may impact the - * correctness of the definitons below (see uses of INT_MAX). - */ -# ifndef PNG_NO_LIMITS_H -# include -# endif - -/* For the memory copy APIs (i.e. the standard definitions of these), - * because this file defines png_memcpy and so on the base APIs must - * be defined here. - */ -# ifdef BSD -# include -# else -# include -# endif - -/* For png_FILE_p - this provides the standard definition of a - * FILE - */ -# ifdef PNG_STDIO_SUPPORTED -# include -# endif -#endif - -/* This controls optimization of the reading of 16 and 32 bit values - * from PNG files. It can be set on a per-app-file basis - it - * just changes whether a macro is used to the function is called. - * The library builder sets the default, if read functions are not - * built into the library the macro implementation is forced on. - */ -#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED -# define PNG_USE_READ_MACROS -#endif -#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) -# if PNG_DEFAULT_READ_MACROS -# define PNG_USE_READ_MACROS -# endif -#endif - -/* COMPILER SPECIFIC OPTIONS. - * - * These options are provided so that a variety of difficult compilers - * can be used. Some are fixed at build time (e.g. PNG_API_RULE - * below) but still have compiler specific implementations, others - * may be changed on a per-file basis when compiling against libpng. - */ - -/* The PNGARG macro protects us against machines that don't have function - * prototypes (ie K&R style headers). If your compiler does not handle - * function prototypes, define this macro and use the included ansi2knr. - * I've always been able to use _NO_PROTO as the indicator, but you may - * need to drag the empty declaration out in front of here, or change the - * ifdef to suit your own needs. - */ -#ifndef PNGARG - -# ifdef OF /* zlib prototype munger */ -# define PNGARG(arglist) OF(arglist) -# else - -# ifdef _NO_PROTO -# define PNGARG(arglist) () -# else -# define PNGARG(arglist) arglist -# endif /* _NO_PROTO */ - -# endif /* OF */ - -#endif /* PNGARG */ - -/* Function calling conventions. - * ============================= - * Normally it is not necessary to specify to the compiler how to call - * a function - it just does it - however on x86 systems derived from - * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems - * and some others) there are multiple ways to call a function and the - * default can be changed on the compiler command line. For this reason - * libpng specifies the calling convention of every exported function and - * every function called via a user supplied function pointer. This is - * done in this file by defining the following macros: - * - * PNGAPI Calling convention for exported functions. - * PNGCBAPI Calling convention for user provided (callback) functions. - * PNGCAPI Calling convention used by the ANSI-C library (required - * for longjmp callbacks and sometimes used internally to - * specify the calling convention for zlib). - * - * These macros should never be overridden. If it is necessary to - * change calling convention in a private build this can be done - * by setting PNG_API_RULE (which defaults to 0) to one of the values - * below to select the correct 'API' variants. - * - * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. - * This is correct in every known environment. - * PNG_API_RULE=1 Use the operating system convention for PNGAPI and - * the 'C' calling convention (from PNGCAPI) for - * callbacks (PNGCBAPI). This is no longer required - * in any known environment - if it has to be used - * please post an explanation of the problem to the - * libpng mailing list. - * - * These cases only differ if the operating system does not use the C - * calling convention, at present this just means the above cases - * (x86 DOS/Windows sytems) and, even then, this does not apply to - * Cygwin running on those systems. - * - * Note that the value must be defined in pnglibconf.h so that what - * the application uses to call the library matches the conventions - * set when building the library. - */ - -/* Symbol export - * ============= - * When building a shared library it is almost always necessary to tell - * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' - * is used to mark the symbols. On some systems these symbols can be - * extracted at link time and need no special processing by the compiler, - * on other systems the symbols are flagged by the compiler and just - * the declaration requires a special tag applied (unfortunately) in a - * compiler dependent way. Some systems can do either. - * - * A small number of older systems also require a symbol from a DLL to - * be flagged to the program that calls it. This is a problem because - * we do not know in the header file included by application code that - * the symbol will come from a shared library, as opposed to a statically - * linked one. For this reason the application must tell us by setting - * the magic flag PNG_USE_DLL to turn on the special processing before - * it includes png.h. - * - * Four additional macros are used to make this happen: - * - * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from - * the build or imported if PNG_USE_DLL is set - compiler - * and system specific. - * - * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to - * 'type', compiler specific. - * - * PNG_DLL_EXPORT Set to the magic to use during a libpng build to - * make a symbol exported from the DLL. Not used in the - * public header files; see pngpriv.h for how it is used - * in the libpng build. - * - * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come - * from a DLL - used to define PNG_IMPEXP when - * PNG_USE_DLL is set. - */ - -/* System specific discovery. - * ========================== - * This code is used at build time to find PNG_IMPEXP, the API settings - * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL - * import processing is possible. On Windows/x86 systems it also sets - * compiler-specific macros to the values required to change the calling - * conventions of the various functions. - */ -#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ - defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ - ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ - defined(_M_X64) || defined(_M_IA64) ) - /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes - * builds under Cygwin or MinGW. Also includes Watcom builds but these need - * special treatment because they are not compatible with GCC or Visual C - * because of different calling conventions. - */ -# if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not - * understood or because of a redefine just below you cannot use *this* - * build of the library with the compiler you are using. *This* build was - * build using Watcom and applications must also be built using Watcom! - */ -# define PNGCAPI __watcall -# endif - -# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) -# define PNGCAPI __cdecl -# if PNG_API_RULE == 1 -# define PNGAPI __stdcall -# endif -# else - /* An older compiler, or one not detected (erroneously) above, - * if necessary override on the command line to get the correct - * variants for the compiler. - */ -# ifndef PNGCAPI -# define PNGCAPI _cdecl -# endif -# if PNG_API_RULE == 1 && !defined(PNGAPI) -# define PNGAPI _stdcall -# endif -# endif /* compiler/api */ - /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ - -# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) - ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed -# endif - -# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ - (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ -# ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP -# endif -# define PNG_DLL_EXPORT __export -# else /* newer compiler */ -# define PNG_DLL_EXPORT __declspec(dllexport) -# ifndef PNG_DLL_IMPORT -# define PNG_DLL_IMPORT __declspec(dllimport) -# endif -# endif /* compiler */ - -#else /* !Windows/x86 */ -# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) -# define PNGAPI _System -# else /* !Windows/x86 && !OS/2 */ - /* Use the defaults, or define PNG*API on the command line (but - * this will have to be done for every compile!) - */ -# endif /* other system, !OS/2 */ -#endif /* !Windows/x86 */ - -/* Now do all the defaulting . */ -#ifndef PNGCAPI -# define PNGCAPI -#endif -#ifndef PNGCBAPI -# define PNGCBAPI PNGCAPI -#endif -#ifndef PNGAPI -# define PNGAPI PNGCAPI -#endif - -/* PNG_IMPEXP may be set on the compilation system command line or (if not set) - * then in an internal header file when building the library, otherwise (when - * using the library) it is set here. - */ -#ifndef PNG_IMPEXP -# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) - /* This forces use of a DLL, disallowing static linking */ -# define PNG_IMPEXP PNG_DLL_IMPORT -# endif - -# ifndef PNG_IMPEXP -# define PNG_IMPEXP -# endif -#endif - -/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat - * 'attributes' as a storage class - the attributes go at the start of the - * function definition, and attributes are always appended regardless of the - * compiler. This considerably simplifies these macros but may cause problems - * if any compilers both need function attributes and fail to handle them as - * a storage class (this is unlikely.) - */ -#ifndef PNG_FUNCTION -# define PNG_FUNCTION(type, name, args, attributes) attributes type name args -#endif - -#ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type -#endif - - /* The ordinal value is only relevant when preprocessing png.h for symbol - * table entries, so we discard it here. See the .dfn files in the - * scripts directory. - */ -#ifndef PNG_EXPORTA - -# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ - PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ - extern attributes) -#endif - -/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, - * so make something non-empty to satisfy the requirement: - */ -#define PNG_EMPTY /*empty list*/ - -#define PNG_EXPORT(ordinal, type, name, args)\ - PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) - -/* Use PNG_REMOVED to comment out a removed interface. */ -#ifndef PNG_REMOVED -# define PNG_REMOVED(ordinal, type, name, args, attributes) -#endif - -#ifndef PNG_CALLBACK -# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) -#endif - -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. - * - * Added at libpng-1.2.41. - */ - -#ifndef PNG_NO_PEDANTIC_WARNINGS -# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED -# define PNG_PEDANTIC_WARNINGS_SUPPORTED -# endif -#endif - -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. - */ -# if defined(__GNUC__) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif -# endif /* __GNUC__ */ - -# if defined(_MSC_VER) && (_MSC_VER >= 1300) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* not supported */ -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __declspec(noreturn) -# endif -# ifndef PNG_ALLOCATED -# if (_MSC_VER >= 1400) -# define PNG_ALLOCATED __declspec(restrict) -# endif -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __declspec(deprecated) -# endif -# ifndef PNG_PRIVATE -# define PNG_PRIVATE __declspec(deprecated) -# endif -# endif /* _MSC_VER */ -#endif /* PNG_PEDANTIC_WARNINGS */ - -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ -#endif -#ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ -#endif -#ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ -#endif -#ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ -#endif -#ifndef PNG_FP_EXPORT /* A floating point API. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args) -# else /* No floating point APIs */ -# define PNG_FP_EXPORT(ordinal, type, name, args) -# endif -#endif -#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ -# ifdef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args) -# else /* No fixed point APIs */ -# define PNG_FIXED_EXPORT(ordinal, type, name, args) -# endif -#endif - -/* The following uses const char * instead of char * for error - * and warning message functions, so some compilers won't complain. - * If you do not want to use const, define PNG_NO_CONST here. - * - * This should not change how the APIs are called, so it can be done - * on a per-file basis in the application. - */ -#ifndef PNG_CONST -# ifndef PNG_NO_CONST -# define PNG_CONST const -# else -# define PNG_CONST -# endif -#endif - -/* Some typedefs to get us started. These should be safe on most of the - * common platforms. The typedefs should be at least as large as the - * numbers suggest (a png_uint_32 must be at least 32 bits long), but they - * don't have to be exactly that size. Some compilers dislike passing - * unsigned shorts as function parameters, so you may be better off using - * unsigned int for png_uint_16. - */ - -#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL) -typedef unsigned int png_uint_32; -typedef int png_int_32; -#else -typedef unsigned long png_uint_32; -typedef long png_int_32; -#endif -typedef unsigned short png_uint_16; -typedef short png_int_16; -typedef unsigned char png_byte; - -#ifdef PNG_NO_SIZE_T -typedef unsigned int png_size_t; -#else -typedef size_t png_size_t; -#endif -#define png_sizeof(x) (sizeof (x)) - -/* The following is needed for medium model support. It cannot be in the - * pngpriv.h header. Needs modification for other compilers besides - * MSC. Model independent support declares all arrays and pointers to be - * large using the far keyword. The zlib version used must also support - * model independent data. As of version zlib 1.0.4, the necessary changes - * have been made in zlib. The USE_FAR_KEYWORD define triggers other - * changes that are needed. (Tim Wegner) - */ - -/* Separate compiler dependencies (problem here is that zlib.h always - * defines FAR. (SJT) - */ -#ifdef __BORLANDC__ -# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) -# define LDATA 1 -# else -# define LDATA 0 -# endif - /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ -# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) -# define PNG_MAX_MALLOC_64K /* only used in build */ -# if (LDATA != 1) -# ifndef FAR -# define FAR __far -# endif -# define USE_FAR_KEYWORD -# endif /* LDATA != 1 */ - /* Possibly useful for moving data out of default segment. - * Uncomment it if you want. Could also define FARDATA as - * const if your compiler supports it. (SJT) -# define FARDATA FAR - */ -# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ -#endif /* __BORLANDC__ */ - - -/* Suggest testing for specific compiler first before testing for - * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, - * making reliance oncertain keywords suspect. (SJT) - */ - -/* MSC Medium model */ -#ifdef FAR -# ifdef M_I86MM -# define USE_FAR_KEYWORD -# define FARDATA FAR -# include -# endif -#endif - -/* SJT: default case */ -#ifndef FAR -# define FAR -#endif - -/* At this point FAR is always defined */ -#ifndef FARDATA -# define FARDATA -#endif - -/* Typedef for floating-point numbers that are converted - * to fixed-point with a multiple of 100,000, e.g., gamma - */ -typedef png_int_32 png_fixed_point; - -/* Add typedefs for pointers */ -typedef void FAR * png_voidp; -typedef PNG_CONST void FAR * png_const_voidp; -typedef png_byte FAR * png_bytep; -typedef PNG_CONST png_byte FAR * png_const_bytep; -typedef png_uint_32 FAR * png_uint_32p; -typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; -typedef png_int_32 FAR * png_int_32p; -typedef PNG_CONST png_int_32 FAR * png_const_int_32p; -typedef png_uint_16 FAR * png_uint_16p; -typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; -typedef png_int_16 FAR * png_int_16p; -typedef PNG_CONST png_int_16 FAR * png_const_int_16p; -typedef char FAR * png_charp; -typedef PNG_CONST char FAR * png_const_charp; -typedef png_fixed_point FAR * png_fixed_point_p; -typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; -typedef png_size_t FAR * png_size_tp; -typedef PNG_CONST png_size_t FAR * png_const_size_tp; - -#ifdef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double FAR * png_doublep; -typedef PNG_CONST double FAR * png_const_doublep; -#endif - -/* Pointers to pointers; i.e. arrays */ -typedef png_byte FAR * FAR * png_bytepp; -typedef png_uint_32 FAR * FAR * png_uint_32pp; -typedef png_int_32 FAR * FAR * png_int_32pp; -typedef png_uint_16 FAR * FAR * png_uint_16pp; -typedef png_int_16 FAR * FAR * png_int_16pp; -typedef PNG_CONST char FAR * FAR * png_const_charpp; -typedef char FAR * FAR * png_charpp; -typedef png_fixed_point FAR * FAR * png_fixed_point_pp; -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double FAR * FAR * png_doublepp; -#endif - -/* Pointers to pointers to pointers; i.e., pointer to array */ -typedef char FAR * FAR * FAR * png_charppp; - -/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, - * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 - * to png_alloc_size_t are not necessary; in fact, it is recommended - * not to use them at all so that the compiler can complain when something - * turns out to be problematic. - * Casts in the other direction (from png_alloc_size_t to png_size_t or - * png_uint_32) should be explicitly applied; however, we do not expect - * to encounter practical situations that require such conversions. - */ -#if defined(__TURBOC__) && !defined(__FLAT__) - typedef unsigned long png_alloc_size_t; -#else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - typedef unsigned long png_alloc_size_t; -# else - /* This is an attempt to detect an old Windows system where (int) is - * actually 16 bits, in that case png_malloc must have an argument with a - * bigger size to accomodate the requirements of the library. - */ -# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \ - (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL) - typedef DWORD png_alloc_size_t; -# else - typedef png_size_t png_alloc_size_t; -# endif -# endif -#endif - -#endif /* PNGCONF_H */ diff --git a/WDL/libpng/pngdebug.h b/WDL/libpng/pngdebug.h deleted file mode 100644 index 96c1ea42..00000000 --- a/WDL/libpng/pngdebug.h +++ /dev/null @@ -1,157 +0,0 @@ - -/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c - * - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * Last changed in libpng 1.5.0 [January 6, 2011] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* Define PNG_DEBUG at compile time for debugging information. Higher - * numbers for PNG_DEBUG mean more debugging information. This has - * only been added since version 0.95 so it is not implemented throughout - * libpng yet, but more support will be added as needed. - * - * png_debug[1-2]?(level, message ,arg{0-2}) - * Expands to a statement (either a simple expression or a compound - * do..while(0) statement) that outputs a message with parameter - * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG - * is undefined, 0 or 1 every png_debug expands to a simple expression - * (actually ((void)0)). - * - * level: level of detail of message, starting at 0. A level 'n' - * message is preceded by 'n' tab characters (not implemented - * on Microsoft compilers unless PNG_DEBUG_FILE is also - * defined, to allow debug DLL compilation with no standard IO). - * message: a printf(3) style text string. A trailing '\n' is added - * to the message. - * arg: 0 to 2 arguments for printf(3) style substitution in message. - */ -#ifndef PNGDEBUG_H -#define PNGDEBUG_H -/* These settings control the formatting of messages in png.c and pngerror.c */ -/* Moved to pngdebug.h at 1.5.0 */ -# ifndef PNG_LITERAL_SHARP -# define PNG_LITERAL_SHARP 0x23 -# endif -# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET -# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b -# endif -# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET -# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d -# endif -# ifndef PNG_STRING_NEWLINE -# define PNG_STRING_NEWLINE "\n" -# endif - -#ifdef PNG_DEBUG -# if (PNG_DEBUG > 0) -# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) -# include -# if (PNG_DEBUG > 1) -# ifndef _DEBUG -# define _DEBUG -# endif -# ifndef png_debug -# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) -# endif -# endif -# else /* PNG_DEBUG_FILE || !_MSC_VER */ -# ifndef PNG_STDIO_SUPPORTED -# include /* not included yet */ -# endif -# ifndef PNG_DEBUG_FILE -# define PNG_DEBUG_FILE stderr -# endif /* PNG_DEBUG_FILE */ - -# if (PNG_DEBUG > 1) -/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on - * non-ISO compilers - */ -# ifdef __STDC__ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ - } while (0) -# endif -# else /* __STDC __ */ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1,p2); \ - } while (0) -# endif -# endif /* __STDC __ */ -# endif /* (PNG_DEBUG > 1) */ - -# endif /* _MSC_VER */ -# endif /* (PNG_DEBUG > 0) */ -#endif /* PNG_DEBUG */ -#ifndef png_debug -# define png_debug(l, m) ((void)0) -#endif -#ifndef png_debug1 -# define png_debug1(l, m, p1) ((void)0) -#endif -#ifndef png_debug2 -# define png_debug2(l, m, p1, p2) ((void)0) -#endif -#endif /* PNGDEBUG_H */ diff --git a/WDL/libpng/pngerror.c b/WDL/libpng/pngerror.c deleted file mode 100644 index f3154071..00000000 --- a/WDL/libpng/pngerror.c +++ /dev/null @@ -1,685 +0,0 @@ - -/* pngerror.c - stub functions for i/o and memory allocation - * - * Last changed in libpng 1.5.7 [February 1, 2012] - * Copyright (c) 1998-2012 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all error handling. Users who - * need special error handling are expected to write replacement functions - * and use png_set_error_fn() to use those functions. See the instructions - * at each function. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, - png_const_charp error_message)),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -static void /* PRIVATE */ -png_default_warning PNGARG((png_structp png_ptr, - png_const_charp warning_message)); -#endif /* PNG_WARNINGS_SUPPORTED */ - -/* This function is called whenever there is a fatal error. This function - * should not be changed. If there is a need to handle errors differently, - * you should supply a replacement error function and use png_set_error_fn() - * to replace the error function at run-time. - */ -#ifdef PNG_ERROR_TEXT_SUPPORTED -PNG_FUNCTION(void,PNGAPI -png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) -{ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - char msg[16]; - if (png_ptr != NULL) - { - if (png_ptr->flags& - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) - { - if (*error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - for (offset = 1; offset<15; offset++) - if (error_message[offset] == ' ') - break; - - if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) - { - int i; - for (i = 0; i < offset - 1; i++) - msg[i] = error_message[i + 1]; - msg[i - 1] = '\0'; - error_message = msg; - } - - else - error_message += offset; - } - - else - { - if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; - } - } - } - } -#endif - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_ptr, error_message); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, error_message); -} -#else -PNG_FUNCTION(void,PNGAPI -png_err,(png_structp png_ptr),PNG_NORETURN) -{ - /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed - * erroneously as '\0', instead of the empty string "". This was - * apparently an error, introduced in libpng-1.2.20, and png_default_error - * will crash in this case. - */ - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_ptr, ""); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, ""); -} -#endif /* PNG_ERROR_TEXT_SUPPORTED */ - -/* Utility to safely appends strings to a buffer. This never errors out so - * error checking is not required in the caller. - */ -size_t -png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string) -{ - if (buffer != NULL && pos < bufsize) - { - if (string != NULL) - while (*string != '\0' && pos < bufsize-1) - buffer[pos++] = *string++; - - buffer[pos] = '\0'; - } - - return pos; -} - -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. - */ -png_charp -png_format_number(png_const_charp start, png_charp end, int format, - png_alloc_size_t number) -{ - int count = 0; /* number of digits output */ - int mincount = 1; /* minimum number required */ - int output = 0; /* digit output (for the fixed point format) */ - - *--end = '\0'; - - /* This is written so that the loop always runs at least once, even with - * number zero. - */ - while (end > start && (number != 0 || count < mincount)) - { - - static const char digits[] = "0123456789ABCDEF"; - - switch (format) - { - case PNG_NUMBER_FORMAT_fixed: - /* Needs five digits (the fraction) */ - mincount = 5; - if (output || number % 10 != 0) - { - *--end = digits[number % 10]; - output = 1; - } - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02u: - /* Expects at least 2 digits. */ - mincount = 2; - /* fall through */ - - case PNG_NUMBER_FORMAT_u: - *--end = digits[number % 10]; - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02x: - /* This format expects at least two digits */ - mincount = 2; - /* fall through */ - - case PNG_NUMBER_FORMAT_x: - *--end = digits[number & 0xf]; - number >>= 4; - break; - - default: /* an error */ - number = 0; - break; - } - - /* Keep track of the number of digits added */ - ++count; - - /* Float a fixed number here: */ - if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start) - { - /* End of the fraction, but maybe nothing was output? In that case - * drop the decimal point. If the number is a true zero handle that - * here. - */ - if (output) - *--end = '.'; - else if (number == 0) /* and !output */ - *--end = '0'; - } - } - - return end; -} -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called whenever there is a non-fatal error. This function - * should not be changed. If there is a need to handle warnings differently, - * you should supply a replacement warning function and use - * png_set_error_fn() to replace the warning function at run-time. - */ -void PNGAPI -png_warning(png_structp png_ptr, png_const_charp warning_message) -{ - int offset = 0; - if (png_ptr != NULL) - { -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (png_ptr->flags& - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) -#endif - { - if (*warning_message == PNG_LITERAL_SHARP) - { - for (offset = 1; offset < 15; offset++) - if (warning_message[offset] == ' ') - break; - } - } - } - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); - else - png_default_warning(png_ptr, warning_message + offset); -} - -/* These functions support 'formatted' warning messages with up to - * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter - * is introduced by @, where 'number' starts at 1. This follows the - * standard established by X/Open for internationalizable error messages. - */ -void -png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string) -{ - if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) - (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); -} - -void -png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, - png_alloc_size_t value) -{ - char buffer[PNG_NUMBER_BUFFER_SIZE]; - png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); -} - -void -png_warning_parameter_signed(png_warning_parameters p, int number, int format, - png_int_32 value) -{ - png_alloc_size_t u; - png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; - - /* Avoid overflow by doing the negate in a png_alloc_size_t: */ - u = (png_alloc_size_t)value; - if (value < 0) - u = ~u + 1; - - str = PNG_FORMAT_NUMBER(buffer, format, u); - - if (value < 0 && str > buffer) - *--str = '-'; - - png_warning_parameter(p, number, str); -} - -void -png_formatted_warning(png_structp png_ptr, png_warning_parameters p, - png_const_charp message) -{ - /* The internal buffer is just 192 bytes - enough for all our messages, - * overflow doesn't happen because this code checks! If someone figures - * out how to send us a message longer than 192 bytes, all that will - * happen is that the message will be truncated appropriately. - */ - size_t i = 0; /* Index in the msg[] buffer: */ - char msg[192]; - - /* Each iteration through the following loop writes at most one character - * to msg[i++] then returns here to validate that there is still space for - * the trailing '\0'. It may (in the case of a parameter) read more than - * one character from message[]; it must check for '\0' and continue to the - * test if it finds the end of string. - */ - while (i<(sizeof msg)-1 && *message != '\0') - { - /* '@' at end of string is now just printed (previously it was skipped); - * it is an error in the calling code to terminate the string with @. - */ - if (p != NULL && *message == '@' && message[1] != '\0') - { - int parameter_char = *++message; /* Consume the '@' */ - static const char valid_parameters[] = "123456789"; - int parameter = 0; - - /* Search for the parameter digit, the index in the string is the - * parameter to use. - */ - while (valid_parameters[parameter] != parameter_char && - valid_parameters[parameter] != '\0') - ++parameter; - - /* If the parameter digit is out of range it will just get printed. */ - if (parameter < PNG_WARNING_PARAMETER_COUNT) - { - /* Append this parameter */ - png_const_charp parm = p[parameter]; - png_const_charp pend = p[parameter] + (sizeof p[parameter]); - - /* No need to copy the trailing '\0' here, but there is no guarantee - * that parm[] has been initialized, so there is no guarantee of a - * trailing '\0': - */ - while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) - msg[i++] = *parm++; - - /* Consume the parameter digit too: */ - ++message; - continue; - } - - /* else not a parameter and there is a character after the @ sign; just - * copy that. This is known not to be '\0' because of the test above. - */ - } - - /* At this point *message can't be '\0', even in the bad parameter case - * above where there is a lone '@' at the end of the message string. - */ - msg[i++] = *message++; - } - - /* i is always less than (sizeof msg), so: */ - msg[i] = '\0'; - - /* And this is the formatted message, it may be larger than - * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are - * not (currently) formatted. - */ - png_warning(png_ptr, msg); -} -#endif /* PNG_WARNINGS_SUPPORTED */ - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_benign_error(png_structp png_ptr, png_const_charp error_message) -{ - if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); -} -#endif - -/* These utilities are used internally to build an error message that relates - * to the current chunk. The chunk name comes from png_ptr->chunk_name, - * this is used to prefix the message. The message is limited in length - * to 63 bytes, the name characters are output as hex digits wrapped in [] - * if the character is invalid. - */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static PNG_CONST char png_digit[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' -}; - -#define PNG_MAX_ERROR_TEXT 64 -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) -static void /* PRIVATE */ -png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp - error_message) -{ - png_uint_32 chunk_name = png_ptr->chunk_name; - int iout = 0, ishift = 24; - - while (ishift >= 0) - { - int c = (int)(chunk_name >> ishift) & 0xff; - - ishift -= 8; - if (isnonalpha(c)) - { - buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; - buffer[iout++] = png_digit[(c & 0xf0) >> 4]; - buffer[iout++] = png_digit[c & 0x0f]; - buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; - } - - else - { - buffer[iout++] = (char)c; - } - } - - if (error_message == NULL) - buffer[iout] = '\0'; - - else - { - int iin = 0; - - buffer[iout++] = ':'; - buffer[iout++] = ' '; - - while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') - buffer[iout++] = error_message[iin++]; - - /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ - buffer[iout] = '\0'; - } -} -#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ - -#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_FUNCTION(void,PNGAPI -png_chunk_error,(png_structp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_error(png_ptr, error_message); - - else - { - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); - } -} -#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ - -#ifdef PNG_WARNINGS_SUPPORTED -void PNGAPI -png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_warning(png_ptr, warning_message); - - else - { - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); - } -} -#endif /* PNG_WARNINGS_SUPPORTED */ - -#ifdef PNG_READ_SUPPORTED -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) -{ - if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) - png_chunk_warning(png_ptr, error_message); - - else - png_chunk_error(png_ptr, error_message); -} -#endif -#endif /* PNG_READ_SUPPORTED */ - -#ifdef PNG_ERROR_TEXT_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_FUNCTION(void, -png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) -{ -# define fixed_message "fixed point overflow in " -# define fixed_message_ln ((sizeof fixed_message)-1) - int iin; - char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; - png_memcpy(msg, fixed_message, fixed_message_ln); - iin = 0; - if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) - { - msg[fixed_message_ln + iin] = name[iin]; - ++iin; - } - msg[fixed_message_ln + iin] = 0; - png_error(png_ptr, msg); -} -#endif -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This API only exists if ANSI-C style error handling is used, - * otherwise it is necessary for png_default_error to be overridden. - */ -jmp_buf* PNGAPI -png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, - size_t jmp_buf_size) -{ - if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf)) - return NULL; - - png_ptr->longjmp_fn = longjmp_fn; - return &png_ptr->longjmp_buffer; -} -#endif - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_structp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - /* Check on NULL only added in 1.5.4 */ - if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - char error_number[16]; - for (offset = 0; offset<15; offset++) - { - error_number[offset] = error_message[offset + 1]; - if (error_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - error_number[offset - 1] = '\0'; - fprintf(stderr, "libpng error no. %s: %s", - error_number, error_message + offset + 1); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng error: %s, offset=%d", - error_message, offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -#endif - { - fprintf(stderr, "libpng error: %s", error_message ? error_message : - "undefined"); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(error_message) /* Make compiler happy */ -#endif - png_longjmp(png_ptr, 1); -} - -PNG_FUNCTION(void,PNGAPI -png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) -{ -#ifdef PNG_SETJMP_SUPPORTED - if (png_ptr && png_ptr->longjmp_fn) - { -# ifdef USE_FAR_KEYWORD - { - jmp_buf tmp_jmpbuf; - png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); - png_ptr->longjmp_fn(tmp_jmpbuf, val); - } - -# else - png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val); -# endif - } -#endif - /* Here if not setjmp support or if png_ptr is null. */ - PNG_ABORT(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want them to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -static void /* PRIVATE */ -png_default_warning(png_structp png_ptr, png_const_charp warning_message) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*warning_message == PNG_LITERAL_SHARP) - { - int offset; - char warning_number[16]; - for (offset = 0; offset < 15; offset++) - { - warning_number[offset] = warning_message[offset + 1]; - if (warning_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - warning_number[offset + 1] = '\0'; - fprintf(stderr, "libpng warning no. %s: %s", - warning_number, warning_message + offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng warning: %s", - warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -# endif - - { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(warning_message) /* Make compiler happy */ -#endif - PNG_UNUSED(png_ptr) /* Make compiler happy */ -} -#endif /* PNG_WARNINGS_SUPPORTED */ - -/* This function is called when the application wants to use another method - * of handling errors and warnings. Note that the error function MUST NOT - * return to the calling routine or serious problems will occur. The return - * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1) - */ -void PNGAPI -png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->error_ptr = error_ptr; - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#else - PNG_UNUSED(warning_fn) -#endif -} - - -/* This function returns a pointer to the error_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_error_ptr(png_const_structp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return ((png_voidp)png_ptr->error_ptr); -} - - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -void PNGAPI -png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) -{ - if (png_ptr != NULL) - { - png_ptr->flags &= - ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | - PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); - } -} -#endif -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngget.c b/WDL/libpng/pngget.c deleted file mode 100644 index 1889e990..00000000 --- a/WDL/libpng/pngget.c +++ /dev/null @@ -1,1124 +0,0 @@ - -/* pngget.c - retrieval of values from info struct - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -png_uint_32 PNGAPI -png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_32 flag) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->valid & flag); - - return(0); -} - -png_size_t PNGAPI -png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); - - return(0); -} - -#ifdef PNG_INFO_IMAGE_SUPPORTED -png_bytepp PNGAPI -png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); - - return(0); -} -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Easy access to info, added in libpng-0.99 */ -png_uint_32 PNGAPI -png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->width; - - return (0); -} - -png_uint_32 PNGAPI -png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->height; - - return (0); -} - -png_byte PNGAPI -png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->bit_depth; - - return (0); -} - -png_byte PNGAPI -png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->color_type; - - return (0); -} - -png_byte PNGAPI -png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->filter_type; - - return (0); -} - -png_byte PNGAPI -png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->interlace_type; - - return (0); -} - -png_byte PNGAPI -png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->compression_type; - - return (0); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); - } -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && - info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); - } -#endif - - return (0); -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); - } -#endif - - return ((float)0.0); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr, - png_const_infop info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) - && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 - && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX - && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) - { - png_fixed_point res; - - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - - /* The following casts work because a PNG 4 byte integer only has a valid - * range of 0..2^31-1; otherwise the cast might overflow. - */ - if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, - (png_int_32)info_ptr->x_pixels_per_unit)) - return res; - } -#endif - - return 0; -} -#endif - -png_int_32 PNGAPI -png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); - } -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); - } -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); - } -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); - } -#endif - - return (0); -} - -#ifdef PNG_INCH_CONVERSIONS_SUPPORTED -static png_uint_32 -ppi_from_ppm(png_uint_32 ppm) -{ -#if 0 - /* The conversion is *(2.54/100), in binary (32 digits): - * .00000110100000001001110101001001 - */ - png_uint_32 t1001, t1101; - ppm >>= 1; /* .1 */ - t1001 = ppm + (ppm >> 3); /* .1001 */ - t1101 = t1001 + (ppm >> 1); /* .1101 */ - ppm >>= 20; /* .000000000000000000001 */ - t1101 += t1101 >> 15; /* .1101000000000001101 */ - t1001 >>= 11; /* .000000000001001 */ - t1001 += t1001 >> 12; /* .000000000001001000000001001 */ - ppm += t1001; /* .000000000001001000001001001 */ - ppm += t1101; /* .110100000001001110101001001 */ - return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ -#else - /* The argument is a PNG unsigned integer, so it is not permitted - * to be bigger than 2^31. - */ - png_fixed_point result; - if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, - 5000)) - return result; - - /* Overflow. */ - return 0; -#endif -} - -png_uint_32 PNGAPI -png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -{ - return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -{ - return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -{ - return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); -} - -#ifdef PNG_FIXED_POINT_SUPPORTED -static png_fixed_point -png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) -{ - /* Convert from metres * 1,000,000 to inches * 100,000, meters to - * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. - * Notice that this can overflow - a warning is output and 0 is - * returned. - */ - return png_muldiv_warn(png_ptr, microns, 500, 127); -} - -png_fixed_point PNGAPI -png_get_x_offset_inches_fixed(png_structp png_ptr, - png_const_infop info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_x_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_y_offset_inches_fixed(png_structp png_ptr, - png_const_infop info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_y_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - - if (*unit_type == 1) - { - if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); - if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); - } - } - } - - return (retval); -} -#endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ - -/* png_get_channels really belongs in here, too, but it's been around longer */ - -#endif /* PNG_EASY_ACCESS_SUPPORTED */ - -png_byte PNGAPI -png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); - - return (0); -} - -png_const_bytep PNGAPI -png_get_signature(png_const_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); - - return (NULL); -} - -#ifdef PNG_bKGD_SUPPORTED -png_uint_32 PNGAPI -png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr, - png_color_16p *background) -{ - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) - && background != NULL) - { - png_debug1(1, "in %s retrieval function", "bKGD"); - - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); - } - - return (0); -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the - * same time to correct the rgb grayscale coefficient defaults obtained from the - * cHRM chunk in 1.5.4 - */ -png_uint_32 PNGFAPI -png_get_cHRM_XYZ_fixed(png_structp png_ptr, png_const_infop info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z) -{ - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - { - png_xy xy; - png_XYZ XYZ; - - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - - xy.whitex = info_ptr->x_white; - xy.whitey = info_ptr->y_white; - xy.redx = info_ptr->x_red; - xy.redy = info_ptr->y_red; - xy.greenx = info_ptr->x_green; - xy.greeny = info_ptr->y_green; - xy.bluex = info_ptr->x_blue; - xy.bluey = info_ptr->y_blue; - - /* The *_checked function handles error reporting, so just return 0 if - * there is a failure here. - */ - if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) - { - if (int_red_X != NULL) - *int_red_X = XYZ.redX; - if (int_red_Y != NULL) - *int_red_Y = XYZ.redY; - if (int_red_Z != NULL) - *int_red_Z = XYZ.redZ; - if (int_green_X != NULL) - *int_green_X = XYZ.greenX; - if (int_green_Y != NULL) - *int_green_Y = XYZ.greenY; - if (int_green_Z != NULL) - *int_green_Z = XYZ.greenZ; - if (int_blue_X != NULL) - *int_blue_X = XYZ.blueX; - if (int_blue_Y != NULL) - *int_blue_Y = XYZ.blueY; - if (int_blue_Z != NULL) - *int_blue_Z = XYZ.blueZ; - - return (PNG_INFO_cHRM); - } - } - - return (0); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) -{ - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - { - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (white_x != NULL) - *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); - if (white_y != NULL) - *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); - if (red_x != NULL) - *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); - if (red_y != NULL) - *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); - if (green_x != NULL) - *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); - if (green_y != NULL) - *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); - if (blue_x != NULL) - *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); - if (blue_y != NULL) - *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); - return (PNG_INFO_cHRM); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_cHRM_XYZ(png_structp png_ptr, png_const_infop info_ptr, - double *red_X, double *red_Y, double *red_Z, double *green_X, - double *green_Y, double *green_Z, double *blue_X, double *blue_Y, - double *blue_Z) -{ - png_XYZ XYZ; - - if (png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, - &XYZ.redX, &XYZ.redY, &XYZ.redZ, &XYZ.greenX, &XYZ.greenY, &XYZ.greenZ, - &XYZ.blueX, &XYZ.blueY, &XYZ.blueZ) & PNG_INFO_cHRM) - { - if (red_X != NULL) - *red_X = png_float(png_ptr, XYZ.redX, "cHRM red X"); - if (red_Y != NULL) - *red_Y = png_float(png_ptr, XYZ.redY, "cHRM red Y"); - if (red_Z != NULL) - *red_Z = png_float(png_ptr, XYZ.redZ, "cHRM red Z"); - if (green_X != NULL) - *green_X = png_float(png_ptr, XYZ.greenX, "cHRM green X"); - if (green_Y != NULL) - *green_Y = png_float(png_ptr, XYZ.greenY, "cHRM green Y"); - if (green_Z != NULL) - *green_Z = png_float(png_ptr, XYZ.greenZ, "cHRM green Z"); - if (blue_X != NULL) - *blue_X = png_float(png_ptr, XYZ.blueX, "cHRM blue X"); - if (blue_Y != NULL) - *blue_Y = png_float(png_ptr, XYZ.blueY, "cHRM blue Y"); - if (blue_Z != NULL) - *blue_Z = png_float(png_ptr, XYZ.blueZ, "cHRM blue Z"); - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM_fixed(png_const_structp png_ptr, png_const_infop info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) -{ - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - { - if (white_x != NULL) - *white_x = info_ptr->x_white; - if (white_y != NULL) - *white_y = info_ptr->y_white; - if (red_x != NULL) - *red_x = info_ptr->x_red; - if (red_y != NULL) - *red_y = info_ptr->y_red; - if (green_x != NULL) - *green_x = info_ptr->x_green; - if (green_y != NULL) - *green_y = info_ptr->y_green; - if (blue_x != NULL) - *blue_x = info_ptr->x_blue; - if (blue_y != NULL) - *blue_y = info_ptr->y_blue; - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif -#endif - -#ifdef PNG_gAMA_SUPPORTED -png_uint_32 PNGFAPI -png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr, - png_fixed_point *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) - && file_gamma != NULL) - { - *file_gamma = info_ptr->gamma; - return (PNG_INFO_gAMA); - } - - return (0); -} -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, - double *file_gamma) -{ - png_fixed_point igamma; - png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); - - if (ok) - *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); - - return ok; -} - -# endif -#endif - -#ifdef PNG_sRGB_SUPPORTED -png_uint_32 PNGAPI -png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, - int *file_srgb_intent) -{ - png_debug1(1, "in %s retrieval function", "sRGB"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) - && file_srgb_intent != NULL) - { - *file_srgb_intent = (int)info_ptr->srgb_intent; - return (PNG_INFO_sRGB); - } - - return (0); -} -#endif - -#ifdef PNG_iCCP_SUPPORTED -png_uint_32 PNGAPI -png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr, - png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen) -{ - png_debug1(1, "in %s retrieval function", "iCCP"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) - && name != NULL && compression_type != NULL && profile != NULL && - proflen != NULL) - { - *name = info_ptr->iccp_name; - *profile = info_ptr->iccp_profile; - /* Compression_type is a dummy so the API won't have to change - * if we introduce multiple compression types later. - */ - *proflen = info_ptr->iccp_proflen; - *compression_type = info_ptr->iccp_compression; - return (PNG_INFO_iCCP); - } - - return (0); -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -png_uint_32 PNGAPI -png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr, - png_sPLT_tpp spalettes) -{ - if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) - { - *spalettes = info_ptr->splt_palettes; - return ((png_uint_32)info_ptr->splt_palettes_num); - } - - return (0); -} -#endif - -#ifdef PNG_hIST_SUPPORTED -png_uint_32 PNGAPI -png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_16p *hist) -{ - png_debug1(1, "in %s retrieval function", "hIST"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) - && hist != NULL) - { - *hist = info_ptr->hist; - return (PNG_INFO_hIST); - } - - return (0); -} -#endif - -png_uint_32 PNGAPI -png_get_IHDR(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) - -{ - png_debug1(1, "in %s retrieval function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL || width == NULL || - height == NULL || bit_depth == NULL || color_type == NULL) - return (0); - - *width = info_ptr->width; - *height = info_ptr->height; - *bit_depth = info_ptr->bit_depth; - *color_type = info_ptr->color_type; - - if (compression_type != NULL) - *compression_type = info_ptr->compression_type; - - if (filter_type != NULL) - *filter_type = info_ptr->filter_type; - - if (interlace_type != NULL) - *interlace_type = info_ptr->interlace_type; - - /* This is redundant if we can be sure that the info_ptr values were all - * assigned in png_set_IHDR(). We do the check anyhow in case an - * application has ignored our advice not to mess with the members - * of info_ptr directly. - */ - png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - return (1); -} - -#ifdef PNG_oFFs_SUPPORTED -png_uint_32 PNGAPI -png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) -{ - png_debug1(1, "in %s retrieval function", "oFFs"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) - && offset_x != NULL && offset_y != NULL && unit_type != NULL) - { - *offset_x = info_ptr->x_offset; - *offset_y = info_ptr->y_offset; - *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); - } - - return (0); -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -png_uint_32 PNGAPI -png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, - png_charp *units, png_charpp *params) -{ - png_debug1(1, "in %s retrieval function", "pCAL"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) - && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) - { - *purpose = info_ptr->pcal_purpose; - *X0 = info_ptr->pcal_X0; - *X1 = info_ptr->pcal_X1; - *type = (int)info_ptr->pcal_type; - *nparams = (int)info_ptr->pcal_nparams; - *units = info_ptr->pcal_units; - *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); - } - - return (0); -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr, - int *unit, png_fixed_point *width, png_fixed_point *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) - { - *unit = info_ptr->scal_unit; - /*TODO: make this work without FP support */ - *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); - *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FLOATING_ARITHMETIC */ -# endif /* FIXED_POINT */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr, - int *unit, double *width, double *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) - { - *unit = info_ptr->scal_unit; - *width = atof(info_ptr->scal_s_width); - *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FLOATING POINT */ -png_uint_32 PNGAPI -png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr, - int *unit, png_charpp width, png_charpp height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; - *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); - } - - return(0); -} -#endif /* sCAL */ - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs)) - { - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - } - } - - return (retval); -} -#endif /* pHYs */ - -png_uint_32 PNGAPI -png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, - png_colorp *palette, int *num_palette) -{ - png_debug1(1, "in %s retrieval function", "PLTE"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) - && palette != NULL) - { - *palette = info_ptr->palette; - *num_palette = info_ptr->num_palette; - png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); - } - - return (0); -} - -#ifdef PNG_sBIT_SUPPORTED -png_uint_32 PNGAPI -png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, - png_color_8p *sig_bit) -{ - png_debug1(1, "in %s retrieval function", "sBIT"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) - && sig_bit != NULL) - { - *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); - } - - return (0); -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -png_uint_32 PNGAPI -png_get_text(png_const_structp png_ptr, png_const_infop info_ptr, - png_textp *text_ptr, int *num_text) -{ - if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) - { - png_debug1(1, "in 0x%lx retrieval function", - (unsigned long)png_ptr->chunk_name); - - if (text_ptr != NULL) - *text_ptr = info_ptr->text; - - if (num_text != NULL) - *num_text = info_ptr->num_text; - - return ((png_uint_32)info_ptr->num_text); - } - - if (num_text != NULL) - *num_text = 0; - - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -png_uint_32 PNGAPI -png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time) -{ - png_debug1(1, "in %s retrieval function", "tIME"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) - && mod_time != NULL) - { - *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); - } - - return (0); -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -png_uint_32 PNGAPI -png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) -{ - png_uint_32 retval = 0; - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) - { - png_debug1(1, "in %s retrieval function", "tRNS"); - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (trans_alpha != NULL) - { - *trans_alpha = info_ptr->trans_alpha; - retval |= PNG_INFO_tRNS; - } - - if (trans_color != NULL) - *trans_color = &(info_ptr->trans_color); - } - - else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ - { - if (trans_color != NULL) - { - *trans_color = &(info_ptr->trans_color); - retval |= PNG_INFO_tRNS; - } - - if (trans_alpha != NULL) - *trans_alpha = NULL; - } - - if (num_trans != NULL) - { - *num_trans = info_ptr->num_trans; - retval |= PNG_INFO_tRNS; - } - } - - return (retval); -} -#endif - -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr, - png_unknown_chunkpp unknowns) -{ - if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) - { - *unknowns = info_ptr->unknown_chunks; - return info_ptr->unknown_chunks_num; - } - - return (0); -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -png_byte PNGAPI -png_get_rgb_to_gray_status (png_const_structp png_ptr) -{ - return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); -} -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -png_voidp PNGAPI -png_get_user_chunk_ptr(png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_ptr : NULL); -} -#endif - -png_size_t PNGAPI -png_get_compression_buffer_size(png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->zbuf_size : 0); -} - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* These functions were added to libpng 1.2.6 and were enabled - * by default in libpng-1.4.0 */ -png_uint_32 PNGAPI -png_get_user_width_max (png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->user_width_max : 0); -} - -png_uint_32 PNGAPI -png_get_user_height_max (png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->user_height_max : 0); -} - -/* This function was added to libpng 1.4.0 */ -png_uint_32 PNGAPI -png_get_chunk_cache_max (png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_cache_max : 0); -} - -/* This function was added to libpng 1.4.1 */ -png_alloc_size_t PNGAPI -png_get_chunk_malloc_max (png_const_structp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); -} -#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ - -/* These functions were added to libpng 1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -png_uint_32 PNGAPI -png_get_io_state (png_structp png_ptr) -{ - return png_ptr->io_state; -} - -png_uint_32 PNGAPI -png_get_io_chunk_type (png_const_structp png_ptr) -{ - return png_ptr->chunk_name; -} - -png_const_bytep PNGAPI -png_get_io_chunk_name (png_structp png_ptr) -{ - PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name); - return png_ptr->io_chunk_string; -} -#endif /* ?PNG_IO_STATE_SUPPORTED */ - -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pnginfo.h b/WDL/libpng/pnginfo.h deleted file mode 100644 index bbfb105a..00000000 --- a/WDL/libpng/pnginfo.h +++ /dev/null @@ -1,269 +0,0 @@ - -/* pnginfo.h - header file for PNG reference library - * - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * Last changed in libpng 1.5.0 [January 6, 2011] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - - /* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, using png_set_*() functions, then - * call png_write_info(). - * - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. - * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. In libpng-1.5.0 this was moved into a separate private - * file that is not visible to applications. - * - * The following members may have allocated storage attached that should be - * cleaned up before the structure is discarded: palette, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). The png_set_* functions do not depend on being - * able to point info structure members to any of the storage they are - * passed (they make their own copies), EXCEPT that the png_set_text - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. - */ -#ifndef PNGINFO_H -#define PNGINFO_H - -struct png_info_def -{ - /* the following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ - png_size_t rowbytes; /* bytes needed to hold an untransformed row */ - png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ - png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ - png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ - png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ - png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ - /* The following three should have been named *_method not *_type */ - png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ - png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ - png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - - /* The following is informational only on read, and not used on writes. */ - png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte spare_byte; /* to align the data, and for future use */ - png_byte signature[8]; /* magic bytes read by libpng from start of file */ - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you - * are writing, set the valid field to those chunks you want written, - * and initialize the appropriate fields below. - */ - -#if defined(PNG_gAMA_SUPPORTED) - /* The gAMA chunk describes the gamma characteristics of the system - * on which the image was created, normally in the range [1.0, 2.5]. - * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. - */ - png_fixed_point gamma; -#endif - -#ifdef PNG_sRGB_SUPPORTED - /* GR-P, 0.96a */ - /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ - png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ -#endif - -#ifdef PNG_TEXT_SUPPORTED - /* The tEXt, and zTXt chunks contain human-readable textual data in - * uncompressed, compressed, and optionally compressed forms, respectively. - * The data in "text" is an array of pointers to uncompressed, - * null-terminated C strings. Each chunk has a keyword that describes the - * textual data contained in that chunk. Keywords are not required to be - * unique, and the text string may be empty. Any number of text chunks may - * be in an image. - */ - int num_text; /* number of comments read or comments to write */ - int max_text; /* current size of text array */ - png_textp text; /* array of comments read or comments to write */ -#endif /* PNG_TEXT_SUPPORTED */ - -#ifdef PNG_tIME_SUPPORTED - /* The tIME chunk holds the last time the displayed image data was - * modified. See the png_time struct for the contents of this struct. - */ - png_time mod_time; -#endif - -#ifdef PNG_sBIT_SUPPORTED - /* The sBIT chunk specifies the number of significant high-order bits - * in the pixel data. Values are in the range [1, bit_depth], and are - * only specified for the channels in the pixel data. The contents of - * the low-order bits is not specified. Data is valid if - * (valid & PNG_INFO_sBIT) is non-zero. - */ - png_color_8 sig_bit; /* significant bits in color channels */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ -defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The tRNS chunk supplies transparency data for paletted images and - * other image types that don't need a full alpha channel. There are - * "num_trans" transparency values for a paletted image, stored in the - * same order as the palette colors, starting from index 0. Values - * for the data are in the range [0, 255], ranging from fully transparent - * to fully opaque, respectively. For non-paletted images, there is a - * single color specified that should be treated as fully transparent. - * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. - */ - png_bytep trans_alpha; /* alpha values for paletted image */ - png_color_16 trans_color; /* transparent color for non-palette image */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The bKGD chunk gives the suggested image background color if the - * display program does not have its own background color and the image - * is needs to composited onto a background before display. The colors - * in "background" are normally in the same color space/depth as the - * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. - */ - png_color_16 background; -#endif - -#ifdef PNG_oFFs_SUPPORTED - /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards - * and downwards from the top-left corner of the display, page, or other - * application-specific co-ordinate space. See the PNG_OFFSET_ defines - * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. - */ - png_int_32 x_offset; /* x offset on page */ - png_int_32 y_offset; /* y offset on page */ - png_byte offset_unit_type; /* offset units type */ -#endif - -#ifdef PNG_pHYs_SUPPORTED - /* The pHYs chunk gives the physical pixel density of the image for - * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ - * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. - */ - png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ - png_uint_32 y_pixels_per_unit; /* vertical pixel density */ - png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ -#endif - -#ifdef PNG_hIST_SUPPORTED - /* The hIST chunk contains the relative frequency or importance of the - * various palette entries, so that a viewer can intelligently select a - * reduced-color palette, if required. Data is an array of "num_palette" - * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) - * is non-zero. - */ - png_uint_16p hist; -#endif - -#ifdef PNG_cHRM_SUPPORTED - /* The cHRM chunk describes the CIE color characteristics of the monitor - * on which the PNG was created. This data allows the viewer to do gamut - * mapping of the input image to ensure that the viewer sees the same - * colors in the image as the creator. Values are in the range - * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. - */ - png_fixed_point x_white; - png_fixed_point y_white; - png_fixed_point x_red; - png_fixed_point y_red; - png_fixed_point x_green; - png_fixed_point y_green; - png_fixed_point x_blue; - png_fixed_point y_blue; -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * values and original physical data values used to create the image. - * The integer range [0, 2^bit_depth - 1] maps to the floating-point - * range given by [pcal_X0, pcal_X1], and are further transformed by a - * (possibly non-linear) transformation function given by "pcal_type" - * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ - * defines below, and the PNG-Group's PNG extensions document for a - * complete description of the transformations and how they should be - * implemented, and for a description of the ASCII parameter strings. - * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. - */ - png_charp pcal_purpose; /* pCAL chunk description string */ - png_int_32 pcal_X0; /* minimum value */ - png_int_32 pcal_X1; /* maximum value */ - png_charp pcal_units; /* Latin-1 string giving physical units */ - png_charpp pcal_params; /* ASCII strings containing parameter values */ - png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ - png_byte pcal_nparams; /* number of parameters given in pcal_params */ -#endif - -/* New members added in libpng-1.0.6 */ - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks; - int unknown_chunks_num; -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* iCCP chunk data. */ - png_charp iccp_name; /* profile name */ - png_bytep iccp_profile; /* International Color Consortium profile data */ - png_uint_32 iccp_proflen; /* ICC profile data length */ - png_byte iccp_compression; /* Always zero */ -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes; - png_uint_32 splt_palettes_num; -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* The sCAL chunk describes the actual physical dimensions of the - * subject matter of the graphic. The chunk contains a unit specification - * a byte value, and two ASCII strings representing floating-point - * values. The values are width and height corresponsing to one pixel - * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is - * non-zero. - */ - png_byte scal_unit; /* unit of physical scale */ - png_charp scal_s_width; /* string containing height */ - png_charp scal_s_height; /* string containing width */ -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) - non-zero */ - /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ - png_bytepp row_pointers; /* the image bits */ -#endif - -}; -#endif /* PNGINFO_H */ diff --git a/WDL/libpng/pnglibconf.h b/WDL/libpng/pnglibconf.h deleted file mode 100644 index 06d6cdeb..00000000 --- a/WDL/libpng/pnglibconf.h +++ /dev/null @@ -1,189 +0,0 @@ - -/* libpng STANDARD API DEFINITION */ - -/* pnglibconf.h - library build configuration */ - -/* Libpng 1.5.8 - February 1, 2012 */ - -/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */ - -/* This code is released under the libpng license. */ -/* For conditions of distribution and use, see the disclaimer */ -/* and license in png.h */ - -/* pnglibconf.h */ -/* Derived from: scripts/pnglibconf.dfa */ -/* If you edit this file by hand you must obey the rules expressed in */ -/* pnglibconf.dfa with respect to the dependencies between the following */ -/* symbols. It is much better to generate a new file using */ -/* scripts/libpngconf.mak */ - -#ifndef PNGLCONF_H -#define PNGLCONF_H -/* settings */ -#define PNG_API_RULE 0 -#define PNG_CALLOC_SUPPORTED -#define PNG_COST_SHIFT 3 -#define PNG_DEFAULT_READ_MACROS 1 -#define PNG_GAMMA_THRESHOLD_FIXED 5000 -#define PNG_MAX_GAMMA_8 11 -#define PNG_QUANTIZE_BLUE_BITS 5 -#define PNG_QUANTIZE_GREEN_BITS 5 -#define PNG_QUANTIZE_RED_BITS 5 -#define PNG_sCAL_PRECISION 5 -#define PNG_USER_CHUNK_CACHE_MAX 0 -#define PNG_USER_CHUNK_MALLOC_MAX 0 -#define PNG_USER_HEIGHT_MAX 1000000 -#define PNG_USER_WIDTH_MAX 1000000 -#define PNG_WEIGHT_SHIFT 8 -#define PNG_ZBUF_SIZE 8192 -/* end of settings */ -/* options */ -#define PNG_16BIT_SUPPORTED -#define PNG_ALIGN_MEMORY_SUPPORTED -#define PNG_BENIGN_ERRORS_SUPPORTED -#define PNG_bKGD_SUPPORTED -#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -#define PNG_CHECK_cHRM_SUPPORTED -#define PNG_cHRM_SUPPORTED -#define PNG_CONSOLE_IO_SUPPORTED -#define PNG_CONVERT_tIME_SUPPORTED -#define PNG_EASY_ACCESS_SUPPORTED -/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ -#define PNG_ERROR_TEXT_SUPPORTED -#define PNG_FIXED_POINT_SUPPORTED -#define PNG_FLOATING_ARITHMETIC_SUPPORTED -#define PNG_FLOATING_POINT_SUPPORTED -#define PNG_FORMAT_AFIRST_SUPPORTED -#define PNG_FORMAT_BGR_SUPPORTED -#define PNG_gAMA_SUPPORTED -#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -#define PNG_hIST_SUPPORTED -#define PNG_iCCP_SUPPORTED -#define PNG_INCH_CONVERSIONS_SUPPORTED -#define PNG_INFO_IMAGE_SUPPORTED -#define PNG_IO_STATE_SUPPORTED -#define PNG_iTXt_SUPPORTED -#define PNG_MNG_FEATURES_SUPPORTED -#define PNG_oFFs_SUPPORTED -#define PNG_pCAL_SUPPORTED -#define PNG_pHYs_SUPPORTED -#define PNG_POINTER_INDEXING_SUPPORTED -#define PNG_PROGRESSIVE_READ_SUPPORTED -#define PNG_READ_16BIT_SUPPORTED -#define PNG_READ_ALPHA_MODE_SUPPORTED -#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_READ_BACKGROUND_SUPPORTED -#define PNG_READ_BGR_SUPPORTED -#define PNG_READ_bKGD_SUPPORTED -#define PNG_READ_cHRM_SUPPORTED -#define PNG_READ_COMPOSITE_NODIV_SUPPORTED -#define PNG_READ_COMPRESSED_TEXT_SUPPORTED -#define PNG_READ_EXPAND_16_SUPPORTED -#define PNG_READ_EXPAND_SUPPORTED -#define PNG_READ_FILLER_SUPPORTED -#define PNG_READ_gAMA_SUPPORTED -#define PNG_READ_GAMMA_SUPPORTED -#define PNG_READ_GRAY_TO_RGB_SUPPORTED -#define PNG_READ_hIST_SUPPORTED -#define PNG_READ_iCCP_SUPPORTED -#define PNG_READ_INTERLACING_SUPPORTED -#define PNG_READ_INT_FUNCTIONS_SUPPORTED -#define PNG_READ_INVERT_ALPHA_SUPPORTED -#define PNG_READ_INVERT_SUPPORTED -#define PNG_READ_iTXt_SUPPORTED -#define PNG_READ_oFFs_SUPPORTED -#define PNG_READ_OPT_PLTE_SUPPORTED -#define PNG_READ_PACK_SUPPORTED -#define PNG_READ_PACKSWAP_SUPPORTED -#define PNG_READ_pCAL_SUPPORTED -#define PNG_READ_pHYs_SUPPORTED -#define PNG_READ_QUANTIZE_SUPPORTED -#define PNG_READ_RGB_TO_GRAY_SUPPORTED -#define PNG_READ_sBIT_SUPPORTED -#define PNG_READ_SCALE_16_TO_8_SUPPORTED -#define PNG_READ_sCAL_SUPPORTED -#define PNG_READ_SHIFT_SUPPORTED -#define PNG_READ_sPLT_SUPPORTED -#define PNG_READ_sRGB_SUPPORTED -#define PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_STRIP_ALPHA_SUPPORTED -#define PNG_READ_SUPPORTED -#define PNG_READ_SWAP_ALPHA_SUPPORTED -#define PNG_READ_SWAP_SUPPORTED -#define PNG_READ_tEXt_SUPPORTED -#define PNG_READ_TEXT_SUPPORTED -#define PNG_READ_tIME_SUPPORTED -#define PNG_READ_TRANSFORMS_SUPPORTED -#define PNG_READ_tRNS_SUPPORTED -#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_READ_USER_CHUNKS_SUPPORTED -#define PNG_READ_USER_TRANSFORM_SUPPORTED -#define PNG_READ_zTXt_SUPPORTED -#define PNG_SAVE_INT_32_SUPPORTED -#define PNG_sBIT_SUPPORTED -#define PNG_sCAL_SUPPORTED -#define PNG_SEQUENTIAL_READ_SUPPORTED -#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED -#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -#define PNG_SETJMP_SUPPORTED -#define PNG_SET_USER_LIMITS_SUPPORTED -#define PNG_sPLT_SUPPORTED -#define PNG_sRGB_SUPPORTED -#define PNG_STDIO_SUPPORTED -#define PNG_tEXt_SUPPORTED -#define PNG_TEXT_SUPPORTED -#define PNG_TIME_RFC1123_SUPPORTED -#define PNG_tIME_SUPPORTED -#define PNG_tRNS_SUPPORTED -#define PNG_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_USER_CHUNKS_SUPPORTED -#define PNG_USER_LIMITS_SUPPORTED -#define PNG_USER_MEM_SUPPORTED -#define PNG_USER_TRANSFORM_INFO_SUPPORTED -#define PNG_USER_TRANSFORM_PTR_SUPPORTED -#define PNG_WARNINGS_SUPPORTED -#define PNG_WRITE_16BIT_SUPPORTED -#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_WRITE_BGR_SUPPORTED -#define PNG_WRITE_bKGD_SUPPORTED -#define PNG_WRITE_cHRM_SUPPORTED -#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -#define PNG_WRITE_FILLER_SUPPORTED -#define PNG_WRITE_FILTER_SUPPORTED -#define PNG_WRITE_FLUSH_SUPPORTED -#define PNG_WRITE_gAMA_SUPPORTED -#define PNG_WRITE_hIST_SUPPORTED -#define PNG_WRITE_iCCP_SUPPORTED -#define PNG_WRITE_INTERLACING_SUPPORTED -#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED -#define PNG_WRITE_INVERT_ALPHA_SUPPORTED -#define PNG_WRITE_INVERT_SUPPORTED -#define PNG_WRITE_iTXt_SUPPORTED -#define PNG_WRITE_oFFs_SUPPORTED -#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -#define PNG_WRITE_PACK_SUPPORTED -#define PNG_WRITE_PACKSWAP_SUPPORTED -#define PNG_WRITE_pCAL_SUPPORTED -#define PNG_WRITE_pHYs_SUPPORTED -#define PNG_WRITE_sBIT_SUPPORTED -#define PNG_WRITE_sCAL_SUPPORTED -#define PNG_WRITE_SHIFT_SUPPORTED -#define PNG_WRITE_sPLT_SUPPORTED -#define PNG_WRITE_sRGB_SUPPORTED -#define PNG_WRITE_SUPPORTED -#define PNG_WRITE_SWAP_ALPHA_SUPPORTED -#define PNG_WRITE_SWAP_SUPPORTED -#define PNG_WRITE_tEXt_SUPPORTED -#define PNG_WRITE_TEXT_SUPPORTED -#define PNG_WRITE_tIME_SUPPORTED -#define PNG_WRITE_TRANSFORMS_SUPPORTED -#define PNG_WRITE_tRNS_SUPPORTED -#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_WRITE_USER_TRANSFORM_SUPPORTED -#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -#define PNG_WRITE_zTXt_SUPPORTED -#define PNG_zTXt_SUPPORTED -/* end of options */ -#endif /* PNGLCONF_H */ diff --git a/WDL/libpng/pngmem.c b/WDL/libpng/pngmem.c deleted file mode 100644 index 25b5c735..00000000 --- a/WDL/libpng/pngmem.c +++ /dev/null @@ -1,667 +0,0 @@ - -/* pngmem.c - stub functions for memory allocation - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all memory allocation. Users who - * need special memory handling are expected to supply replacement - * functions for png_malloc() and png_free(), and to use - * png_create_read_struct_2() and png_create_write_struct_2() to - * identify the replacement functions. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -/* Borland DOS special memory handler */ -#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) -/* If you change this, be sure to change the one in png.h also */ - -/* Allocate memory for a png_struct. The malloc and memset can be replaced - by a single call to calloc() if this is thought to improve performance. */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_create_struct,(int type),PNG_ALLOCATED) -{ -# ifdef PNG_USER_MEM_SUPPORTED - return (png_create_struct_2(type, NULL, NULL)); -} - -/* Alternate version of png_create_struct, for use with user-defined malloc. */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), - PNG_ALLOCATED) -{ -# endif /* PNG_USER_MEM_SUPPORTED */ - png_size_t size; - png_voidp struct_ptr; - - if (type == PNG_STRUCT_INFO) - size = png_sizeof(png_info); - - else if (type == PNG_STRUCT_PNG) - size = png_sizeof(png_struct); - - else - return (png_get_copyright(NULL)); - -# ifdef PNG_USER_MEM_SUPPORTED - if (malloc_fn != NULL) - { - png_struct dummy_struct; - memset(&dummy_struct, 0, sizeof dummy_struct); - dummy_struct.mem_ptr=mem_ptr; - struct_ptr = (*(malloc_fn))(&dummy_struct, (png_alloc_size_t)size); - } - - else -# endif /* PNG_USER_MEM_SUPPORTED */ - struct_ptr = (png_voidp)farmalloc(size); - if (struct_ptr != NULL) - png_memset(struct_ptr, 0, size); - - return (struct_ptr); -} - -/* Free memory allocated by a png_create_struct() call */ -void /* PRIVATE */ -png_destroy_struct(png_voidp struct_ptr) -{ -# ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2(struct_ptr, NULL, NULL); -} - -/* Free memory allocated by a png_create_struct() call */ -void /* PRIVATE */ -png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, - png_voidp mem_ptr) -{ -# endif - if (struct_ptr != NULL) - { -# ifdef PNG_USER_MEM_SUPPORTED - if (free_fn != NULL) - { - png_struct dummy_struct; - memset(&dummy_struct, 0, sizeof dummy_struct); - dummy_struct.mem_ptr=mem_ptr; - (*(free_fn))(&dummy_struct, struct_ptr); - return; - } - -# endif /* PNG_USER_MEM_SUPPORTED */ - farfree (struct_ptr); - } -} - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more then 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - * - * Borland seems to have a problem in DOS mode for exactly 64K. - * It gives you a segment with an offset of 8 (perhaps to store its - * memory stuff). zlib doesn't like this at all, so we have to - * detect and deal with it. This code should not be needed in - * Windows or OS/2 modes, and only in 16 bit mode. This code has - * been updated by Alexander Lehmann for version 0.89 to waste less - * memory. - * - * Note that we can't use png_size_t for the "size" declaration, - * since on some systems a png_size_t is a 16-bit quantity, and as a - * result, we would be truncating potentially larger memory requests - * (which should cause a fatal error) and introducing major problems. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - ret = (png_malloc(png_ptr, size)); - - if (ret != NULL) - png_memset(ret,0,(png_size_t)size); - - return (ret); -} - -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - if (png_ptr == NULL || size == 0) - return (NULL); - -# ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->malloc_fn != NULL) - ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size)); - - else - ret = (png_malloc_default(png_ptr, size)); - - if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out of memory"); - - return (ret); -} - -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; -# endif /* PNG_USER_MEM_SUPPORTED */ - - if (png_ptr == NULL || size == 0) - return (NULL); - -# ifdef PNG_MAX_MALLOC_64K - if (size > (png_uint_32)65536L) - { - png_warning(png_ptr, "Cannot Allocate > 64K"); - ret = NULL; - } - - else -# endif - - if (size != (size_t)size) - ret = NULL; - - else if (size == (png_uint_32)65536L) - { - if (png_ptr->offset_table == NULL) - { - /* Try to see if we need to do any of this fancy stuff */ - ret = farmalloc(size); - if (ret == NULL || ((png_size_t)ret & 0xffff)) - { - int num_blocks; - png_uint_32 total_size; - png_bytep table; - int i, mem_level, window_bits; - png_byte huge * hptr; - int window_bits - - if (ret != NULL) - { - farfree(ret); - ret = NULL; - } - - window_bits = - png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ? - png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits; - - if (window_bits > 14) - num_blocks = (int)(1 << (window_bits - 14)); - - else - num_blocks = 1; - - mem_level = - png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ? - png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level; - - if (mem_level >= 7) - num_blocks += (int)(1 << (mem_level - 7)); - - else - num_blocks++; - - total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; - - table = farmalloc(total_size); - - if (table == NULL) - { -# ifndef PNG_USER_MEM_SUPPORTED - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ - - else - png_warning(png_ptr, "Out Of Memory"); -# endif - return (NULL); - } - - if ((png_size_t)table & 0xfff0) - { -# ifndef PNG_USER_MEM_SUPPORTED - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, - "Farmalloc didn't return normalized pointer"); - - else - png_warning(png_ptr, - "Farmalloc didn't return normalized pointer"); -# endif - return (NULL); - } - - png_ptr->offset_table = table; - png_ptr->offset_table_ptr = farmalloc(num_blocks * - png_sizeof(png_bytep)); - - if (png_ptr->offset_table_ptr == NULL) - { -# ifndef PNG_USER_MEM_SUPPORTED - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ - - else - png_warning(png_ptr, "Out Of memory"); -# endif - return (NULL); - } - - hptr = (png_byte huge *)table; - if ((png_size_t)hptr & 0xf) - { - hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); - hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ - } - - for (i = 0; i < num_blocks; i++) - { - png_ptr->offset_table_ptr[i] = (png_bytep)hptr; - hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ - } - - png_ptr->offset_table_number = num_blocks; - png_ptr->offset_table_count = 0; - png_ptr->offset_table_count_free = 0; - } - } - - if (png_ptr->offset_table_count >= png_ptr->offset_table_number) - { -# ifndef PNG_USER_MEM_SUPPORTED - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */ - - else - png_warning(png_ptr, "Out of Memory"); -# endif - return (NULL); - } - - ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; - } - - else - ret = farmalloc(size); - -# ifndef PNG_USER_MEM_SUPPORTED - if (ret == NULL) - { - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ - - else - png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ - } -# endif - - return (ret); -} - -/* Free a pointer allocated by png_malloc(). In the default - * configuration, png_ptr is not used, but is passed in case it - * is needed. If ptr is NULL, return without taking any action. - */ -void PNGAPI -png_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -# ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) - { - (*(png_ptr->free_fn))(png_ptr, ptr); - return; - } - - else - png_free_default(png_ptr, ptr); -} - -void PNGAPI -png_free_default(png_structp png_ptr, png_voidp ptr) -{ -# endif /* PNG_USER_MEM_SUPPORTED */ - - if (png_ptr == NULL || ptr == NULL) - return; - - if (png_ptr->offset_table != NULL) - { - int i; - - for (i = 0; i < png_ptr->offset_table_count; i++) - { - if (ptr == png_ptr->offset_table_ptr[i]) - { - ptr = NULL; - png_ptr->offset_table_count_free++; - break; - } - } - if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) - { - farfree(png_ptr->offset_table); - farfree(png_ptr->offset_table_ptr); - png_ptr->offset_table = NULL; - png_ptr->offset_table_ptr = NULL; - } - } - - if (ptr != NULL) - farfree(ptr); -} - -#else /* Not the Borland DOS special memory handler */ - -/* Allocate memory for a png_struct or a png_info. The malloc and - memset can be replaced by a single call to calloc() if this is thought - to improve performance noticably. */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_create_struct,(int type),PNG_ALLOCATED) -{ -# ifdef PNG_USER_MEM_SUPPORTED - return (png_create_struct_2(type, NULL, NULL)); -} - -/* Allocate memory for a png_struct or a png_info. The malloc and - memset can be replaced by a single call to calloc() if this is thought - to improve performance noticably. */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), - PNG_ALLOCATED) -{ -# endif /* PNG_USER_MEM_SUPPORTED */ - png_size_t size; - png_voidp struct_ptr; - - if (type == PNG_STRUCT_INFO) - size = png_sizeof(png_info); - - else if (type == PNG_STRUCT_PNG) - size = png_sizeof(png_struct); - - else - return (NULL); - -# ifdef PNG_USER_MEM_SUPPORTED - if (malloc_fn != NULL) - { - png_struct dummy_struct; - png_structp png_ptr = &dummy_struct; - png_ptr->mem_ptr=mem_ptr; - struct_ptr = (*(malloc_fn))(png_ptr, size); - - if (struct_ptr != NULL) - png_memset(struct_ptr, 0, size); - - return (struct_ptr); - } -# endif /* PNG_USER_MEM_SUPPORTED */ - -# if defined(__TURBOC__) && !defined(__FLAT__) - struct_ptr = (png_voidp)farmalloc(size); -# else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - struct_ptr = (png_voidp)halloc(size, 1); -# else - struct_ptr = (png_voidp)malloc(size); -# endif -# endif - - if (struct_ptr != NULL) - png_memset(struct_ptr, 0, size); - - return (struct_ptr); -} - - -/* Free memory allocated by a png_create_struct() call */ -void /* PRIVATE */ -png_destroy_struct(png_voidp struct_ptr) -{ -# ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2(struct_ptr, NULL, NULL); -} - -/* Free memory allocated by a png_create_struct() call */ -void /* PRIVATE */ -png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, - png_voidp mem_ptr) -{ -# endif /* PNG_USER_MEM_SUPPORTED */ - if (struct_ptr != NULL) - { -# ifdef PNG_USER_MEM_SUPPORTED - if (free_fn != NULL) - { - png_struct dummy_struct; - png_structp png_ptr = &dummy_struct; - png_ptr->mem_ptr=mem_ptr; - (*(free_fn))(png_ptr, struct_ptr); - return; - } -# endif /* PNG_USER_MEM_SUPPORTED */ -# if defined(__TURBOC__) && !defined(__FLAT__) - farfree(struct_ptr); - -# else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - hfree(struct_ptr); - -# else - free(struct_ptr); - -# endif -# endif - } -} - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more then 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - */ - -PNG_FUNCTION(png_voidp,PNGAPI -png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - ret = (png_malloc(png_ptr, size)); - - if (ret != NULL) - png_memset(ret,0,(png_size_t)size); - - return (ret); -} - -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - -# ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr == NULL || size == 0) - return (NULL); - - if (png_ptr->malloc_fn != NULL) - ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); - - else - ret = (png_malloc_default(png_ptr, size)); - - if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out of Memory"); - - return (ret); -} - -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; -# endif /* PNG_USER_MEM_SUPPORTED */ - - if (png_ptr == NULL || size == 0) - return (NULL); - -# ifdef PNG_MAX_MALLOC_64K - if (size > (png_uint_32)65536L) - { -# ifndef PNG_USER_MEM_SUPPORTED - if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Cannot Allocate > 64K"); - - else -# endif - return NULL; - } -# endif - - /* Check for overflow */ -# if defined(__TURBOC__) && !defined(__FLAT__) - - if (size != (unsigned long)size) - ret = NULL; - - else - ret = farmalloc(size); - -# else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - if (size != (unsigned long)size) - ret = NULL; - - else - ret = halloc(size, 1); - -# else - if (size != (size_t)size) - ret = NULL; - - else - ret = malloc((size_t)size); -# endif -# endif - -# ifndef PNG_USER_MEM_SUPPORTED - if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) - png_error(png_ptr, "Out of Memory"); -# endif - - return (ret); -} - -/* Free a pointer allocated by png_malloc(). If ptr is NULL, return - * without taking any action. - */ -void PNGAPI -png_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -# ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) - { - (*(png_ptr->free_fn))(png_ptr, ptr); - return; - } - - else - png_free_default(png_ptr, ptr); -} - -void PNGAPI -png_free_default(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -# endif /* PNG_USER_MEM_SUPPORTED */ - -# if defined(__TURBOC__) && !defined(__FLAT__) - farfree(ptr); - -# else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - hfree(ptr); - -# else - free(ptr); - -# endif -# endif -} -#endif /* Not Borland DOS special memory handler */ - -/* This function was added at libpng version 1.2.3. The png_malloc_warn() - * function will set up png_malloc() to issue a png_warning and return NULL - * instead of issuing a png_error, if it fails to allocate the requested - * memory. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ptr; - png_uint_32 save_flags; - if (png_ptr == NULL) - return (NULL); - - save_flags = png_ptr->flags; - png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; - ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); - png_ptr->flags=save_flags; - return(ptr); -} - - -#ifdef PNG_USER_MEM_SUPPORTED -/* This function is called when the application wants to use another method - * of allocating and freeing memory. - */ -void PNGAPI -png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr - malloc_fn, png_free_ptr free_fn) -{ - if (png_ptr != NULL) - { - png_ptr->mem_ptr = mem_ptr; - png_ptr->malloc_fn = malloc_fn; - png_ptr->free_fn = free_fn; - } -} - -/* This function returns a pointer to the mem_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_mem_ptr(png_const_structp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return ((png_voidp)png_ptr->mem_ptr); -} -#endif /* PNG_USER_MEM_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngpread.c b/WDL/libpng/pngpread.c deleted file mode 100644 index ca7607a6..00000000 --- a/WDL/libpng/pngpread.c +++ /dev/null @@ -1,1846 +0,0 @@ - -/* pngpread.c - read a png file in push mode - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - -/* Push model modes */ -#define PNG_READ_SIG_MODE 0 -#define PNG_READ_CHUNK_MODE 1 -#define PNG_READ_IDAT_MODE 2 -#define PNG_SKIP_MODE 3 -#define PNG_READ_tEXt_MODE 4 -#define PNG_READ_zTXt_MODE 5 -#define PNG_READ_DONE_MODE 6 -#define PNG_READ_iTXt_MODE 7 -#define PNG_ERROR_MODE 8 - -void PNGAPI -png_process_data(png_structp png_ptr, png_infop info_ptr, - png_bytep buffer, png_size_t buffer_size) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_push_restore_buffer(png_ptr, buffer, buffer_size); - - while (png_ptr->buffer_size) - { - png_process_some_data(png_ptr, info_ptr); - } -} - -png_size_t PNGAPI -png_process_data_pause(png_structp png_ptr, int save) -{ - if (png_ptr != NULL) - { - /* It's easiest for the caller if we do the save, then the caller doesn't - * have to supply the same data again: - */ - if (save) - png_push_save_buffer(png_ptr); - else - { - /* This includes any pending saved bytes: */ - png_size_t remaining = png_ptr->buffer_size; - png_ptr->buffer_size = 0; - - /* So subtract the saved buffer size, unless all the data - * is actually 'saved', in which case we just return 0 - */ - if (png_ptr->save_buffer_size < remaining) - return remaining - png_ptr->save_buffer_size; - } - } - - return 0; -} - -png_uint_32 PNGAPI -png_process_data_skip(png_structp png_ptr) -{ - png_uint_32 remaining = 0; - - if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && - png_ptr->skip_length > 0) - { - /* At the end of png_process_data the buffer size must be 0 (see the loop - * above) so we can detect a broken call here: - */ - if (png_ptr->buffer_size != 0) - png_error(png_ptr, - "png_process_data_skip called inside png_process_data"); - - /* If is impossible for there to be a saved buffer at this point - - * otherwise we could not be in SKIP mode. This will also happen if - * png_process_skip is called inside png_process_data (but only very - * rarely.) - */ - if (png_ptr->save_buffer_size != 0) - png_error(png_ptr, "png_process_data_skip called with saved data"); - - remaining = png_ptr->skip_length; - png_ptr->skip_length = 0; - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } - - return remaining; -} - -/* What we do with the incoming data depends on what we were previously - * doing before we ran out of data... - */ -void /* PRIVATE */ -png_process_some_data(png_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr == NULL) - return; - - switch (png_ptr->process_mode) - { - case PNG_READ_SIG_MODE: - { - png_push_read_sig(png_ptr, info_ptr); - break; - } - - case PNG_READ_CHUNK_MODE: - { - png_push_read_chunk(png_ptr, info_ptr); - break; - } - - case PNG_READ_IDAT_MODE: - { - png_push_read_IDAT(png_ptr); - break; - } - -#ifdef PNG_READ_tEXt_SUPPORTED - case PNG_READ_tEXt_MODE: - { - png_push_read_tEXt(png_ptr, info_ptr); - break; - } - -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - case PNG_READ_zTXt_MODE: - { - png_push_read_zTXt(png_ptr, info_ptr); - break; - } - -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - case PNG_READ_iTXt_MODE: - { - png_push_read_iTXt(png_ptr, info_ptr); - break; - } - -#endif - case PNG_SKIP_MODE: - { - png_push_crc_finish(png_ptr); - break; - } - - default: - { - png_ptr->buffer_size = 0; - break; - } - } -} - -/* Read any remaining signature bytes from the stream and compare them with - * the correct PNG signature. It is possible that this routine is called - * with bytes already read from the signature, either because they have been - * checked by the calling application, or because of multiple calls to this - * routine. - */ -void /* PRIVATE */ -png_push_read_sig(png_structp png_ptr, png_infop info_ptr) -{ - png_size_t num_checked = png_ptr->sig_bytes, - num_to_check = 8 - num_checked; - - if (png_ptr->buffer_size < num_to_check) - { - num_to_check = png_ptr->buffer_size; - } - - png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); - png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - else - { - if (png_ptr->sig_bytes >= 8) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } - } -} - -void /* PRIVATE */ -png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) -{ - png_uint_32 chunk_name; - - /* First we make sure we have enough data for the 4 byte chunk name - * and the 4 byte chunk length before proceeding with decoding the - * chunk data. To fully decode each of these chunks, we also make - * sure we have enough data in the buffer for the 4 byte CRC at the - * end of every chunk (except IDAT, which is handled separately). - */ - if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - if (png_ptr->buffer_size < 8) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } - - chunk_name = png_ptr->chunk_name; - - if (chunk_name == png_IDAT) - { - /* This is here above the if/else case statement below because if the - * unknown handling marks 'IDAT' as unknown then the IDAT handling case is - * completely skipped. - * - * TODO: there must be a better way of doing this. - */ - if (png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - } - - if (chunk_name == png_IHDR) - { - if (png_ptr->push_length != 13) - png_error(png_ptr, "Invalid IHDR length"); - - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IEND) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); - - png_ptr->process_mode = PNG_READ_DONE_MODE; - png_push_have_end(png_ptr, info_ptr); - } - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_chunk_unknown_handling(png_ptr, chunk_name)) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - if (chunk_name == png_IDAT) - png_ptr->mode |= PNG_HAVE_IDAT; - - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - - else if (chunk_name == png_IDAT) - { - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - } - } - -#endif - else if (chunk_name == png_PLTE) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IDAT) - { - /* If we reach an IDAT chunk, this means we have read all of the - * header chunks, and we can start reading the image (or if this - * is called after the image has been read - we have an error). - */ - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - - if (png_ptr->mode & PNG_HAVE_IDAT) - { - if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) - if (png_ptr->push_length == 0) - return; - - if (png_ptr->mode & PNG_AFTER_IDAT) - png_benign_error(png_ptr, "Too many IDATs found"); - } - - png_ptr->idat_size = png_ptr->push_length; - png_ptr->mode |= PNG_HAVE_IDAT; - png_ptr->process_mode = PNG_READ_IDAT_MODE; - png_push_have_info(png_ptr, info_ptr); - png_ptr->zstream.avail_out = - (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; - png_ptr->zstream.next_out = png_ptr->row_buf; - return; - } - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (png_ptr->chunk_name == png_gAMA) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - else if (png_ptr->chunk_name == png_sBIT) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - else if (png_ptr->chunk_name == png_cHRM) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - else if (png_ptr->chunk_name == png_iCCP) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif - else - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) - { - png_push_save_buffer(png_ptr); - return; - } - png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); - } - - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -} - -void /* PRIVATE */ -png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) -{ - png_ptr->process_mode = PNG_SKIP_MODE; - png_ptr->skip_length = skip; -} - -void /* PRIVATE */ -png_push_crc_finish(png_structp png_ptr) -{ - if (png_ptr->skip_length && png_ptr->save_buffer_size) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; - - /* We want the smaller of 'skip_length' and 'save_buffer_size', but - * they are of different types and we don't know which variable has the - * fewest bits. Carefully select the smaller and cast it to the type of - * the larger - this cannot overflow. Do not cast in the following test - * - it will break on either 16 or 64 bit platforms. - */ - if (skip_length < save_size) - save_size = (png_size_t)skip_length; - - else - skip_length = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->skip_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - if (png_ptr->skip_length && png_ptr->current_buffer_size) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; - - /* We want the smaller of 'skip_length' and 'current_buffer_size', here, - * the same problem exists as above and the same solution. - */ - if (skip_length < save_size) - save_size = (png_size_t)skip_length; - - else - skip_length = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->skip_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - if (!png_ptr->skip_length) - { - if (png_ptr->buffer_size < 4) - { - png_push_save_buffer(png_ptr); - return; - } - - png_crc_finish(png_ptr, 0); - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } -} - -void PNGCBAPI -png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) -{ - png_bytep ptr; - - if (png_ptr == NULL) - return; - - ptr = buffer; - if (png_ptr->save_buffer_size) - { - png_size_t save_size; - - if (length < png_ptr->save_buffer_size) - save_size = length; - - else - save_size = png_ptr->save_buffer_size; - - png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); - length -= save_size; - ptr += save_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - if (length && png_ptr->current_buffer_size) - { - png_size_t save_size; - - if (length < png_ptr->current_buffer_size) - save_size = length; - - else - save_size = png_ptr->current_buffer_size; - - png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -} - -void /* PRIVATE */ -png_push_save_buffer(png_structp png_ptr) -{ - if (png_ptr->save_buffer_size) - { - if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) - { - png_size_t i, istop; - png_bytep sp; - png_bytep dp; - - istop = png_ptr->save_buffer_size; - for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; - i < istop; i++, sp++, dp++) - { - *dp = *sp; - } - } - } - if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > - png_ptr->save_buffer_max) - { - png_size_t new_max; - png_bytep old_buffer; - - if (png_ptr->save_buffer_size > PNG_SIZE_MAX - - (png_ptr->current_buffer_size + 256)) - { - png_error(png_ptr, "Potential overflow of save_buffer"); - } - - new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; - old_buffer = png_ptr->save_buffer; - png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)new_max); - - if (png_ptr->save_buffer == NULL) - { - png_free(png_ptr, old_buffer); - png_error(png_ptr, "Insufficient memory for save_buffer"); - } - - png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); - png_free(png_ptr, old_buffer); - png_ptr->save_buffer_max = new_max; - } - if (png_ptr->current_buffer_size) - { - png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, - png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); - png_ptr->save_buffer_size += png_ptr->current_buffer_size; - png_ptr->current_buffer_size = 0; - } - png_ptr->save_buffer_ptr = png_ptr->save_buffer; - png_ptr->buffer_size = 0; -} - -void /* PRIVATE */ -png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, - png_size_t buffer_length) -{ - png_ptr->current_buffer = buffer; - png_ptr->current_buffer_size = buffer_length; - png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; - png_ptr->current_buffer_ptr = png_ptr->current_buffer; -} - -void /* PRIVATE */ -png_push_read_IDAT(png_structp png_ptr) -{ - if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - /* TODO: this code can be commoned up with the same code in push_read */ - if (png_ptr->buffer_size < 8) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - - if (png_ptr->chunk_name != png_IDAT) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - png_error(png_ptr, "Not enough compressed data"); - - return; - } - - png_ptr->idat_size = png_ptr->push_length; - } - - if (png_ptr->idat_size && png_ptr->save_buffer_size) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. Do not cast in the following test - it - * will break on either 16 or 64 bit platforms. - */ - if (idat_size < save_size) - save_size = (png_size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - - if (png_ptr->idat_size && png_ptr->current_buffer_size) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. - */ - if (idat_size < save_size) - save_size = (png_size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - if (!png_ptr->idat_size) - { - if (png_ptr->buffer_size < 4) - { - png_push_save_buffer(png_ptr); - return; - } - - png_crc_finish(png_ptr, 0); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - png_ptr->mode |= PNG_AFTER_IDAT; - } -} - -void /* PRIVATE */ -png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, - png_size_t buffer_length) -{ - /* The caller checks for a non-zero buffer length. */ - if (!(buffer_length > 0) || buffer == NULL) - png_error(png_ptr, "No IDAT data (internal error)"); - - /* This routine must process all the data it has been given - * before returning, calling the row callback as required to - * handle the uncompressed results. - */ - png_ptr->zstream.next_in = buffer; - png_ptr->zstream.avail_in = (uInt)buffer_length; - - /* Keep going until the decompressed data is all processed - * or the stream marked as finished. - */ - while (png_ptr->zstream.avail_in > 0 && - !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - { - int ret; - - /* We have data for zlib, but we must check that zlib - * has someplace to put the results. It doesn't matter - * if we don't expect any results -- it may be the input - * data is just the LZ end code. - */ - if (!(png_ptr->zstream.avail_out > 0)) - { - png_ptr->zstream.avail_out = - (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; - - png_ptr->zstream.next_out = png_ptr->row_buf; - } - - /* Using Z_SYNC_FLUSH here means that an unterminated - * LZ stream (a stream with a missing end code) can still - * be handled, otherwise (Z_NO_FLUSH) a future zlib - * implementation might defer output and therefore - * change the current behavior (see comments in inflate.c - * for why this doesn't happen at present with zlib 1.2.5). - */ - ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); - - /* Check for any failure before proceeding. */ - if (ret != Z_OK && ret != Z_STREAM_END) - { - /* Terminate the decompression. */ - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - - /* This may be a truncated stream (missing or - * damaged end code). Treat that as a warning. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - png_warning(png_ptr, "Truncated compressed data in IDAT"); - - else - png_error(png_ptr, "Decompression error in IDAT"); - - /* Skip the check on unprocessed input */ - return; - } - - /* Did inflate output any data? */ - if (png_ptr->zstream.next_out != png_ptr->row_buf) - { - /* Is this unexpected data after the last row? - * If it is, artificially terminate the LZ output - * here. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - { - /* Extra data. */ - png_warning(png_ptr, "Extra compressed data in IDAT"); - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - - /* Do no more processing; skip the unprocessed - * input check below. - */ - return; - } - - /* Do we have a complete row? */ - if (png_ptr->zstream.avail_out == 0) - png_push_process_row(png_ptr); - } - - /* And check for the end of the stream. */ - if (ret == Z_STREAM_END) - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - } - - /* All the data should have been processed, if anything - * is left at this point we have bytes of IDAT data - * after the zlib end code. - */ - if (png_ptr->zstream.avail_in > 0) - png_warning(png_ptr, "Extra compression data in IDAT"); -} - -void /* PRIVATE */ -png_push_process_row(png_structp png_ptr) -{ - /* 1.5.6: row_info moved out of png_struct to a local here. */ - png_row_info row_info; - - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced row count: - */ - png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "progressive row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal progressive row size calculation error"); - - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Blow up interlaced rows to full size */ - if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - switch (png_ptr->pass) - { - case 0: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 0; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ - } - - if (png_ptr->pass == 2) /* Pass 1 might be empty */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 4 && png_ptr->height <= 4) - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 6 && png_ptr->height <= 4) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 1: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 1; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 2) /* Skip top 4 generated rows */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 2: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Pass 3 might be empty */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 3: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 3; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Skip top two generated rows */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 4: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Pass 5 might be empty */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 5: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 5; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Skip top generated row */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - default: - case 6: - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - - if (png_ptr->pass != 6) - break; - - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - } - else -#endif - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } -} - -void /* PRIVATE */ -png_read_push_finish_row(png_structp png_ptr) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - /* Height of interlace block. This is not currently used - if you need - * it, uncomment it here and in png.h - static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; - */ - - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) - { - png_ptr->row_number = 0; - png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - if ((png_ptr->pass == 1 && png_ptr->width < 5) || - (png_ptr->pass == 3 && png_ptr->width < 3) || - (png_ptr->pass == 5 && png_ptr->width < 2)) - png_ptr->pass++; - - if (png_ptr->pass > 7) - png_ptr->pass--; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if (png_ptr->transformations & PNG_INTERLACE) - break; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); - } -#endif /* PNG_READ_INTERLACING_SUPPORTED */ -} - -#ifdef PNG_READ_tEXt_SUPPORTED -void /* PRIVATE */ -png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) -{ - if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ - png_error(png_ptr, "Out of place tEXt"); - /* NOT REACHED */ - } - -#ifdef PNG_MAX_MALLOC_64K - png_ptr->skip_length = 0; /* This may not be necessary */ - - if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ - { - png_warning(png_ptr, "tEXt chunk too large to fit in memory"); - png_ptr->skip_length = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); - png_ptr->current_text[length] = '\0'; - png_ptr->current_text_ptr = png_ptr->current_text; - png_ptr->current_text_size = (png_size_t)length; - png_ptr->current_text_left = (png_size_t)length; - png_ptr->process_mode = PNG_READ_tEXt_MODE; -} - -void /* PRIVATE */ -png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr->buffer_size && png_ptr->current_text_left) - { - png_size_t text_size; - - if (png_ptr->buffer_size < png_ptr->current_text_left) - text_size = png_ptr->buffer_size; - - else - text_size = png_ptr->current_text_left; - - png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); - png_ptr->current_text_left -= text_size; - png_ptr->current_text_ptr += text_size; - } - if (!(png_ptr->current_text_left)) - { - png_textp text_ptr; - png_charp text; - png_charp key; - int ret; - - if (png_ptr->buffer_size < 4) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_crc_finish(png_ptr); - -#ifdef PNG_MAX_MALLOC_64K - if (png_ptr->skip_length) - return; -#endif - - key = png_ptr->current_text; - - for (text = key; *text; text++) - /* Empty loop */ ; - - if (text < key + png_ptr->current_text_size) - text++; - - text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); - text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; - text_ptr->key = key; - text_ptr->itxt_length = 0; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->text = text; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, key); - png_free(png_ptr, text_ptr); - png_ptr->current_text = NULL; - - if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk"); - } -} -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -void /* PRIVATE */ -png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) -{ - if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ - png_error(png_ptr, "Out of place zTXt"); - /* NOT REACHED */ - } - -#ifdef PNG_MAX_MALLOC_64K - /* We can't handle zTXt chunks > 64K, since we don't have enough space - * to be able to store the uncompressed data. Actually, the threshold - * is probably around 32K, but it isn't as definite as 64K is. - */ - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "zTXt chunk too large to fit in memory"); - png_push_crc_skip(png_ptr, length); - return; - } -#endif - - png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); - png_ptr->current_text[length] = '\0'; - png_ptr->current_text_ptr = png_ptr->current_text; - png_ptr->current_text_size = (png_size_t)length; - png_ptr->current_text_left = (png_size_t)length; - png_ptr->process_mode = PNG_READ_zTXt_MODE; -} - -void /* PRIVATE */ -png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr->buffer_size && png_ptr->current_text_left) - { - png_size_t text_size; - - if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) - text_size = png_ptr->buffer_size; - - else - text_size = png_ptr->current_text_left; - - png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); - png_ptr->current_text_left -= text_size; - png_ptr->current_text_ptr += text_size; - } - if (!(png_ptr->current_text_left)) - { - png_textp text_ptr; - png_charp text; - png_charp key; - int ret; - png_size_t text_size, key_size; - - if (png_ptr->buffer_size < 4) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_crc_finish(png_ptr); - - key = png_ptr->current_text; - - for (text = key; *text; text++) - /* Empty loop */ ; - - /* zTXt can't have zero text */ - if (text >= key + png_ptr->current_text_size) - { - png_ptr->current_text = NULL; - png_free(png_ptr, key); - return; - } - - text++; - - if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ - { - png_ptr->current_text = NULL; - png_free(png_ptr, key); - return; - } - - text++; - - png_ptr->zstream.next_in = (png_bytep)text; - png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - - (text - key)); - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - - key_size = text - key; - text_size = 0; - text = NULL; - ret = Z_STREAM_END; - - while (png_ptr->zstream.avail_in) - { - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - if (ret != Z_OK && ret != Z_STREAM_END) - { - inflateReset(&png_ptr->zstream); - png_ptr->zstream.avail_in = 0; - png_ptr->current_text = NULL; - png_free(png_ptr, key); - png_free(png_ptr, text); - return; - } - - if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) - { - if (text == NULL) - { - text = (png_charp)png_malloc(png_ptr, - (png_ptr->zbuf_size - - png_ptr->zstream.avail_out + key_size + 1)); - - png_memcpy(text + key_size, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); - - png_memcpy(text, key, key_size); - - text_size = key_size + png_ptr->zbuf_size - - png_ptr->zstream.avail_out; - - *(text + text_size) = '\0'; - } - - else - { - png_charp tmp; - - tmp = text; - text = (png_charp)png_malloc(png_ptr, text_size + - (png_ptr->zbuf_size - - png_ptr->zstream.avail_out + 1)); - - png_memcpy(text, tmp, text_size); - png_free(png_ptr, tmp); - - png_memcpy(text + text_size, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); - - text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; - *(text + text_size) = '\0'; - } - - if (ret != Z_STREAM_END) - { - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - } - } - else - { - break; - } - - if (ret == Z_STREAM_END) - break; - } - - inflateReset(&png_ptr->zstream); - png_ptr->zstream.avail_in = 0; - - if (ret != Z_STREAM_END) - { - png_ptr->current_text = NULL; - png_free(png_ptr, key); - png_free(png_ptr, text); - return; - } - - png_ptr->current_text = NULL; - png_free(png_ptr, key); - key = text; - text += key_size; - - text_ptr = (png_textp)png_malloc(png_ptr, - png_sizeof(png_text)); - text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; - text_ptr->key = key; - text_ptr->itxt_length = 0; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->text = text; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, key); - png_free(png_ptr, text_ptr); - - if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk"); - } -} -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED -void /* PRIVATE */ -png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) -{ - if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ - png_error(png_ptr, "Out of place iTXt"); - /* NOT REACHED */ - } - -#ifdef PNG_MAX_MALLOC_64K - png_ptr->skip_length = 0; /* This may not be necessary */ - - if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ - { - png_warning(png_ptr, "iTXt chunk too large to fit in memory"); - png_ptr->skip_length = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); - png_ptr->current_text[length] = '\0'; - png_ptr->current_text_ptr = png_ptr->current_text; - png_ptr->current_text_size = (png_size_t)length; - png_ptr->current_text_left = (png_size_t)length; - png_ptr->process_mode = PNG_READ_iTXt_MODE; -} - -void /* PRIVATE */ -png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) -{ - - if (png_ptr->buffer_size && png_ptr->current_text_left) - { - png_size_t text_size; - - if (png_ptr->buffer_size < png_ptr->current_text_left) - text_size = png_ptr->buffer_size; - - else - text_size = png_ptr->current_text_left; - - png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); - png_ptr->current_text_left -= text_size; - png_ptr->current_text_ptr += text_size; - } - - if (!(png_ptr->current_text_left)) - { - png_textp text_ptr; - png_charp key; - int comp_flag; - png_charp lang; - png_charp lang_key; - png_charp text; - int ret; - - if (png_ptr->buffer_size < 4) - { - png_push_save_buffer(png_ptr); - return; - } - - png_push_crc_finish(png_ptr); - -#ifdef PNG_MAX_MALLOC_64K - if (png_ptr->skip_length) - return; -#endif - - key = png_ptr->current_text; - - for (lang = key; *lang; lang++) - /* Empty loop */ ; - - if (lang < key + png_ptr->current_text_size - 3) - lang++; - - comp_flag = *lang++; - lang++; /* Skip comp_type, always zero */ - - for (lang_key = lang; *lang_key; lang_key++) - /* Empty loop */ ; - - lang_key++; /* Skip NUL separator */ - - text=lang_key; - - if (lang_key < key + png_ptr->current_text_size - 1) - { - for (; *text; text++) - /* Empty loop */ ; - } - - if (text < key + png_ptr->current_text_size) - text++; - - text_ptr = (png_textp)png_malloc(png_ptr, - png_sizeof(png_text)); - - text_ptr->compression = comp_flag + 2; - text_ptr->key = key; - text_ptr->lang = lang; - text_ptr->lang_key = lang_key; - text_ptr->text = text; - text_ptr->text_length = 0; - text_ptr->itxt_length = png_strlen(text); - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_ptr->current_text = NULL; - - png_free(png_ptr, text_ptr); - if (ret) - png_warning(png_ptr, "Insufficient memory to store iTXt chunk"); - } -} -#endif - -/* This function is called when we haven't found a handler for this - * chunk. If there isn't a problem with the chunk itself (ie a bad chunk - * name or a critical chunk), the chunk is (currently) silently ignored. - */ -void /* PRIVATE */ -png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) -{ - png_uint_32 skip = 0; - png_uint_32 chunk_name = png_ptr->chunk_name; - - if (PNG_CHUNK_CRITICAL(chunk_name)) - { -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - if (png_chunk_unknown_handling(png_ptr, chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - && png_ptr->read_user_chunk_fn == NULL -#endif - ) -#endif - png_chunk_error(png_ptr, "unknown critical chunk"); - - PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ - } - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* TODO: the code below is apparently just using the - * png_struct::unknown_chunk member as a temporarily variable, it should be - * possible to eliminate both it and the temporary buffer. - */ - if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) - { -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535) - { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - 65535; - length = 65535; - } -#endif - /* This is just a record for the user; libpng doesn't use the character - * form of the name. - */ - PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); - - /* The following cast should be safe because of the check above. */ - png_ptr->unknown_chunk.size = (png_size_t)length; - - if (length == 0) - png_ptr->unknown_chunk.data = NULL; - - else - { - png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, - png_ptr->unknown_chunk.size); - png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, - png_ptr->unknown_chunk.size); - } - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - { - /* Callback to user unknown chunk handler */ - int ret; - ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); - - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - if (ret == 0) - { - if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - if (png_chunk_unknown_handling(png_ptr, chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) - png_chunk_error(png_ptr, "unknown critical chunk"); - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - } - } - - else -#endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - - else -#endif - skip=length; - png_push_crc_skip(png_ptr, skip); -} - -void /* PRIVATE */ -png_push_have_info(png_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr->info_fn != NULL) - (*(png_ptr->info_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_end(png_structp png_ptr, png_infop info_ptr) -{ - if (png_ptr->end_fn != NULL) - (*(png_ptr->end_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_row(png_structp png_ptr, png_bytep row) -{ - if (png_ptr->row_fn != NULL) - (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, - (int)png_ptr->pass); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void PNGAPI -png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, - png_const_bytep new_row) -{ - if (png_ptr == NULL) - return; - - /* new_row is a flag here - if it is NULL then the app callback was called - * from an empty row (see the calls to png_struct::row_fn below), otherwise - * it must be png_ptr->row_buf+1 - */ - if (new_row != NULL) - png_combine_row(png_ptr, old_row, 1/*display*/); -} -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - -void PNGAPI -png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->info_fn = info_fn; - png_ptr->row_fn = row_fn; - png_ptr->end_fn = end_fn; - - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); -} - -png_voidp PNGAPI -png_get_progressive_ptr(png_const_structp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return png_ptr->io_ptr; -} -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/WDL/libpng/pngpriv.h b/WDL/libpng/pngpriv.h deleted file mode 100644 index 5f751de2..00000000 --- a/WDL/libpng/pngpriv.h +++ /dev/null @@ -1,1629 +0,0 @@ - -/* pngpriv.h - private declarations for use inside libpng - * - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The symbols declared in this file (including the functions declared - * as PNG_EXTERN) are PRIVATE. They are not part of the libpng public - * interface, and are not recommended for use by regular applications. - * Some of them may become public in the future; others may stay private, - * change in an incompatible way, or even disappear. - * Although the libpng users are not forbidden to include this header, - * they should be well aware of the issues that may arise from doing so. - */ - -#ifndef PNGPRIV_H -#define PNGPRIV_H - -/* Feature Test Macros. The following are defined here to ensure that correctly - * implemented libraries reveal the APIs libpng needs to build and hide those - * that are not needed and potentially damaging to the compilation. - * - * Feature Test Macros must be defined before any system header is included (see - * POSIX 1003.1 2.8.2 "POSIX Symbols." - * - * These macros only have an effect if the operating system supports either - * POSIX 1003.1 or C99, or both. On other operating systems (particularly - * Windows/Visual Studio) there is no effect; the OS specific tests below are - * still required (as of 2011-05-02.) - */ -#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ - -/* This is required for the definition of abort(), used as a last ditch - * error handler when all else fails. - */ -#include - -/* This is used to find 'offsetof', used below for alignment tests. */ -#include - -#define PNGLIB_BUILD /*libpng is being built, not used*/ - -#ifdef PNG_USER_CONFIG -# include "pngusr.h" - /* These should have been defined in pngusr.h */ -# ifndef PNG_USER_PRIVATEBUILD -# define PNG_USER_PRIVATEBUILD "Custom libpng build" -# endif -# ifndef PNG_USER_DLLFNAME_POSTFIX -# define PNG_USER_DLLFNAME_POSTFIX "Cb" -# endif -#endif - -/* Is this a build of a DLL where compilation of the object modules requires - * different preprocessor settings to those required for a simple library? If - * so PNG_BUILD_DLL must be set. - * - * If libpng is used inside a DLL but that DLL does not export the libpng APIs - * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a - * static library of libpng then link the DLL against that. - */ -#ifndef PNG_BUILD_DLL -# ifdef DLL_EXPORT - /* This is set by libtool when files are compiled for a DLL; libtool - * always compiles twice, even on systems where it isn't necessary. Set - * PNG_BUILD_DLL in case it is necessary: - */ -# define PNG_BUILD_DLL -# else -# ifdef _WINDLL - /* This is set by the Microsoft Visual Studio IDE in projects that - * build a DLL. It can't easily be removed from those projects (it - * isn't visible in the Visual Studio UI) so it is a fairly reliable - * indication that PNG_IMPEXP needs to be set to the DLL export - * attributes. - */ -# define PNG_BUILD_DLL -# else -# ifdef __DLL__ - /* This is set by the Borland C system when compiling for a DLL - * (as above.) - */ -# define PNG_BUILD_DLL -# else - /* Add additional compiler cases here. */ -# endif -# endif -# endif -#endif /* Setting PNG_BUILD_DLL if required */ - -/* See pngconf.h for more details: the builder of the library may set this on - * the command line to the right thing for the specific compilation system or it - * may be automagically set above (at present we know of no system where it does - * need to be set on the command line.) - * - * PNG_IMPEXP must be set here when building the library to prevent pngconf.h - * setting it to the "import" setting for a DLL build. - */ -#ifndef PNG_IMPEXP -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP PNG_DLL_EXPORT -# else - /* Not building a DLL, or the DLL doesn't require specific export - * definitions. - */ -# define PNG_IMPEXP -# endif -#endif - -/* No warnings for private or deprecated functions in the build: */ -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE -#endif - -#include "png.h" -#include "pnginfo.h" -#include "pngstruct.h" - -/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ -#ifndef PNG_DLL_EXPORT -# define PNG_DLL_EXPORT -#endif - -/* This is used for 16 bit gamma tables - only the top level pointers are const, - * this could be changed: - */ -typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; - -/* Added at libpng-1.2.9 */ -/* Moved to pngpriv.h at libpng-1.5.0 */ - -/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" - * script. We may need it here to get the correct configuration on things - * like limits. - */ -#ifdef PNG_CONFIGURE_LIBPNG -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif -#endif - -/* Moved to pngpriv.h at libpng-1.5.0 */ -/* NOTE: some of these may have been used in external applications as - * these definitions were exposed in pngconf.h prior to 1.5. - */ - -/* If you are running on a machine where you cannot allocate more - * than 64K of memory at once, uncomment this. While libpng will not - * normally need that much memory in a chunk (unless you load up a very - * large file), zlib needs to know how big of a chunk it can use, and - * libpng thus makes sure to check any memory allocation to verify it - * will fit into memory. - * - * zlib provides 'MAXSEG_64K' which, if defined, indicates the - * same limit and pngconf.h (already included) sets the limit - * if certain operating systems are detected. - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) -# define PNG_MAX_MALLOC_64K -#endif - -#ifndef PNG_UNUSED -/* Unused formal parameter warnings are silenced using the following macro - * which is expected to have no bad effects on performance (optimizing - * compilers will probably remove it entirely). Note that if you replace - * it with something other than whitespace, you must include the terminating - * semicolon. - */ -# define PNG_UNUSED(param) (void)param; -#endif - -/* Just a little check that someone hasn't tried to define something - * contradictory. - */ -#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 65536L -#endif - -/* PNG_STATIC is used to mark internal file scope functions if they need to be - * accessed for implementation tests (see the code in tests/?*). - */ -#ifndef PNG_STATIC -# define PNG_STATIC static -#endif - -/* C99 restrict is used where possible, to do this 'restrict' is defined as - * empty if we can't be sure it is supported. configure builds have already - * done this work. - */ -#ifdef PNG_CONFIGURE_LIBPNG -# define PNG_RESTRICT restrict -#else - /* Modern compilers support restrict, but assume not for anything not - * recognized here: - */ -# if defined __GNUC__ || defined _MSC_VER || defined __WATCOMC__ -# define PNG_RESTRICT restrict -# else -# define PNG_RESTRICT -# endif -#endif - -/* If warnings or errors are turned off the code is disabled or redirected here. - * From 1.5.4 functions have been added to allow very limited formatting of - * error and warning messages - this code will also be disabled here. - */ -#ifdef PNG_WARNINGS_SUPPORTED -# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; -#else -# define png_warning(s1,s2) ((void)(s1)) -# define png_chunk_warning(s1,s2) ((void)(s1)) -# define png_warning_parameter(p,number,string) ((void)0) -# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) -# define png_warning_parameter_signed(p,number,format,value) ((void)0) -# define png_formatted_warning(pp,p,message) ((void)(pp)) -# define PNG_WARNING_PARAMETERS(p) -#endif -#ifndef PNG_ERROR_TEXT_SUPPORTED -# define png_error(s1,s2) png_err(s1) -# define png_chunk_error(s1,s2) png_err(s1) -# define png_fixed_error(s1,s2) png_err(s1) -#endif - -/* C allows up-casts from (void*) to any pointer and (const void*) to any - * pointer to a const object. C++ regards this as a type error and requires an - * explicit, static, cast and provides the static_cast<> rune to ensure that - * const is not cast away. - */ -#ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -#else -# define png_voidcast(type, value) (value) -#endif /* __cplusplus */ - -#ifndef PNG_EXTERN -/* The functions exported by PNG_EXTERN are internal functions, which - * aren't usually used outside the library (as far as I know), so it is - * debatable if they should be exported at all. In the future, when it - * is possible to have run-time registry of chunk-handling functions, - * some of these might be made available again. - * - * 1.5.7: turned the use of 'extern' back on, since it is localized to pngpriv.h - * it should be safe now (it is unclear why it was turned off.) - */ -# define PNG_EXTERN extern -#endif - -/* Some fixed point APIs are still required even if not exported because - * they get used by the corresponding floating point APIs. This magic - * deals with this: - */ -#ifdef PNG_FIXED_POINT_SUPPORTED -# define PNGFAPI PNGAPI -#else -# define PNGFAPI /* PRIVATE */ -#endif - -/* Other defines specific to compilers can go here. Try to keep - * them inside an appropriate ifdef/endif pair for portability. - */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - /* png.c requires the following ANSI-C constants if the conversion of - * floating point to ASCII is implemented therein: - * - * DBL_DIG Maximum number of decimal digits (can be set to any constant) - * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) - * DBL_MAX Maximum floating point number (can be set to an arbitrary value) - */ -# include - -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ -# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) -# include -# endif -# else -# include -# endif -# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) - /* Amiga SAS/C: We must include builtin FPU functions when compiling using - * MATH=68881 - */ -# include -# endif -#endif - -/* This provides the non-ANSI (far) memory allocation routines. */ -#if defined(__TURBOC__) && defined(__MSDOS__) -# include -# include -#endif - -#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ - defined(_WIN32) || defined(__WIN32__) -# include /* defines _WINDOWS_ macro */ -#endif - -/* Moved here around 1.5.0beta36 from pngconf.h */ -/* Users may want to use these so they are not private. Any library - * functions that are passed far data must be model-independent. - */ - -/* Memory model/platform independent fns */ -#ifndef PNG_ABORT -# ifdef _WINDOWS_ -# define PNG_ABORT() ExitProcess(0) -# else -# define PNG_ABORT() abort() -# endif -#endif - -#ifdef USE_FAR_KEYWORD -/* Use this to make far-to-near assignments */ -# define CHECK 1 -# define NOCHECK 0 -# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) -# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) -# define png_strlen _fstrlen -# define png_memcmp _fmemcmp /* SJT: added */ -# define png_memcpy _fmemcpy -# define png_memset _fmemset -#else -# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strlen lstrlenA -# define png_memcmp memcmp -# define png_memcpy CopyMemory -# define png_memset memset -# else -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strlen strlen -# define png_memcmp memcmp /* SJT: added */ -# define png_memcpy memcpy -# define png_memset memset -# endif -#endif - -/* These macros may need to be architecture dependent. */ -#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ -#ifdef offsetof -# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ -#else -# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ -#endif -#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ - -#ifndef PNG_ALIGN_TYPE - /* Default to using aligned access optimizations and requiring alignment to a - * multiple of the data type size. Override in a compiler specific fashion - * if necessary by inserting tests here: - */ -# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE -#endif - -#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE - /* This is used because in some compiler implementations non-aligned - * structure members are supported, so the offsetof approach below fails. - * Set PNG_ALIGN_TO_SIZE=0 for compiler combinations where unaligned access - * is good for performance. Do not do this unless you have tested the result - * and understand it. - */ -# define png_alignof(type) (sizeof (type)) -#else -# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -# define png_alignof(type) offsetof(struct{char c; type t;}, t) -# else -# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -# define png_alignof(type) (1) -# endif - /* Else leave png_alignof undefined to prevent use thereof */ -# endif -#endif - -/* This implicitly assumes alignment is always to a power of 2. */ -#ifdef png_alignof -# define png_isaligned(ptr, type)\ - ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) -#else -# define png_isaligned(ptr, type) 0 -#endif - -/* End of memory model/platform independent support */ -/* End of 1.5.0beta36 move from pngconf.h */ - -/* CONSTANTS and UTILITY MACROS - * These are used internally by libpng and not exposed in the API - */ - -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. Three of these - * are defined in png.h because they need to be visible to applications - * that call png_set_unknown_chunk(). - */ -/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */ -/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */ -#define PNG_HAVE_IDAT 0x04 -/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ -#define PNG_HAVE_IEND 0x10 -#define PNG_HAVE_gAMA 0x20 -#define PNG_HAVE_cHRM 0x40 -#define PNG_HAVE_sRGB 0x80 -#define PNG_HAVE_CHUNK_HEADER 0x100 -#define PNG_WROTE_tIME 0x200 -#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 -#define PNG_BACKGROUND_IS_GRAY 0x800 -#define PNG_HAVE_PNG_SIGNATURE 0x1000 -#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ - -/* Flags for the transformations the PNG library does on the image data */ -#define PNG_BGR 0x0001 -#define PNG_INTERLACE 0x0002 -#define PNG_PACK 0x0004 -#define PNG_SHIFT 0x0008 -#define PNG_SWAP_BYTES 0x0010 -#define PNG_INVERT_MONO 0x0020 -#define PNG_QUANTIZE 0x0040 -#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ -#define PNG_BACKGROUND_EXPAND 0x0100 -#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ -#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ -#define PNG_RGBA 0x0800 -#define PNG_EXPAND 0x1000 -#define PNG_GAMMA 0x2000 -#define PNG_GRAY_TO_RGB 0x4000 -#define PNG_FILLER 0x8000 -#define PNG_PACKSWAP 0x10000 -#define PNG_SWAP_ALPHA 0x20000 -#define PNG_STRIP_ALPHA 0x40000 -#define PNG_INVERT_ALPHA 0x80000 -#define PNG_USER_TRANSFORM 0x100000 -#define PNG_RGB_TO_GRAY_ERR 0x200000 -#define PNG_RGB_TO_GRAY_WARN 0x400000 -#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ -#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ -#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ -#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ -#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ - /* 0x8000000 unused */ - /* 0x10000000 unused */ - /* 0x20000000 unused */ - /* 0x40000000 unused */ -/* Flags for png_create_struct */ -#define PNG_STRUCT_PNG 0x0001 -#define PNG_STRUCT_INFO 0x0002 - -/* Scaling factor for filter heuristic weighting calculations */ -#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) -#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) - -/* Flags for the png_ptr->flags rather than declaring a byte for each one */ -#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 -#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 -#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 -#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 -#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 -#define PNG_FLAG_ZLIB_FINISHED 0x0020 -#define PNG_FLAG_ROW_INIT 0x0040 -#define PNG_FLAG_FILLER_AFTER 0x0080 -#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 -#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 -#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 -#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 -#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ -#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ -#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ -#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 -#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 -#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 -#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 -#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 -#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000 - /* 0x200000 unused */ - /* 0x400000 unused */ -#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000 /* Added to libpng-1.4.0 */ -#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000 /* 5 lines added */ -#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000 /* to libpng-1.5.4 */ -#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000 -#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000 -#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000 - /* 0x20000000 unused */ - /* 0x40000000 unused */ - -#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ - PNG_FLAG_CRC_ANCILLARY_NOWARN) - -#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ - PNG_FLAG_CRC_CRITICAL_IGNORE) - -#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ - PNG_FLAG_CRC_CRITICAL_MASK) - -/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib - * can handle at once. This type need be no larger than 16 bits (so maximum of - * 65535), this define allows us to discover how big it is, but limited by the - * maximuum for png_size_t. The value can be overriden in a library build - * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably - * lower value (e.g. 255 works). A lower value may help memory usage (slightly) - * and may even improve performance on some systems (and degrade it on others.) - */ -#ifndef ZLIB_IO_MAX -# define ZLIB_IO_MAX ((uInt)-1) -#endif - -/* Save typing and make code easier to understand */ - -#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ - abs((int)((c1).green) - (int)((c2).green)) + \ - abs((int)((c1).blue) - (int)((c2).blue))) - -/* Added to libpng-1.2.6 JB */ -#define PNG_ROWBYTES(pixel_bits, width) \ - ((pixel_bits) >= 8 ? \ - ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ - (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) ) - -/* PNG_OUT_OF_RANGE returns true if value is outside the range - * ideal-delta..ideal+delta. Each argument is evaluated twice. - * "ideal" and "delta" should be constants, normally simple - * integers, "value" a variable. Added to libpng-1.2.6 JB - */ -#define PNG_OUT_OF_RANGE(value, ideal, delta) \ - ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) - -/* Conversions between fixed and floating point, only defined if - * required (to make sure the code doesn't accidentally use float - * when it is supposedly disabled.) - */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* The floating point conversion can't overflow, though it can and - * does lose accuracy relative to the original fixed point value. - * In practice this doesn't matter because png_fixed_point only - * stores numbers with very low precision. The png_ptr and s - * arguments are unused by default but are there in case error - * checking becomes a requirement. - */ -#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) - -/* The fixed point conversion performs range checking and evaluates - * its argument multiple times, so must be used with care. The - * range checking uses the PNG specification values for a signed - * 32 bit fixed point value except that the values are deliberately - * rounded-to-zero to an integral value - 21474 (21474.83 is roughly - * (2^31-1) * 100000). 's' is a string that describes the value being - * converted. - * - * NOTE: this macro will raise a png_error if the range check fails, - * therefore it is normally only appropriate to use this on values - * that come from API calls or other sources where an out of range - * error indicates a programming error, not a data error! - * - * NOTE: by default this is off - the macro is not used - because the - * function call saves a lot of code. - */ -#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED -#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ - ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) -#else -PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, - png_const_charp text)); -#endif -#endif - -/* Constants for known chunk types. If you need to add a chunk, define the name - * here. For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. - * - * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values - * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string - * to be generated if required. - * - * PNG_32b correctly produces a value shifted by up to 24 bits, even on - * architectures where (int) is only 16 bits. - */ -#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) -#define PNG_CHUNK(b1,b2,b3,b4) \ - (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) - -#define png_IHDR PNG_CHUNK( 73, 72, 68, 82) -#define png_IDAT PNG_CHUNK( 73, 68, 65, 84) -#define png_IEND PNG_CHUNK( 73, 69, 78, 68) -#define png_PLTE PNG_CHUNK( 80, 76, 84, 69) -#define png_bKGD PNG_CHUNK( 98, 75, 71, 68) -#define png_cHRM PNG_CHUNK( 99, 72, 82, 77) -#define png_gAMA PNG_CHUNK(103, 65, 77, 65) -#define png_hIST PNG_CHUNK(104, 73, 83, 84) -#define png_iCCP PNG_CHUNK(105, 67, 67, 80) -#define png_iTXt PNG_CHUNK(105, 84, 88, 116) -#define png_oFFs PNG_CHUNK(111, 70, 70, 115) -#define png_pCAL PNG_CHUNK(112, 67, 65, 76) -#define png_sCAL PNG_CHUNK(115, 67, 65, 76) -#define png_pHYs PNG_CHUNK(112, 72, 89, 115) -#define png_sBIT PNG_CHUNK(115, 66, 73, 84) -#define png_sPLT PNG_CHUNK(115, 80, 76, 84) -#define png_sRGB PNG_CHUNK(115, 82, 71, 66) -#define png_sTER PNG_CHUNK(115, 84, 69, 82) -#define png_tEXt PNG_CHUNK(116, 69, 88, 116) -#define png_tIME PNG_CHUNK(116, 73, 77, 69) -#define png_tRNS PNG_CHUNK(116, 82, 78, 83) -#define png_zTXt PNG_CHUNK(122, 84, 88, 116) - -/* The following will work on (signed char*) strings, whereas the get_uint_32 - * macro will fail on top-bit-set values because of the sign extension. - */ -#define PNG_CHUNK_FROM_STRING(s)\ - PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) - -/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is - * signed and the argument is a (char[]) This macro will fail miserably on - * systems where (char) is more than 8 bits. - */ -#define PNG_STRING_FROM_CHUNK(s,c)\ - (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ - ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) - -/* Do the same but terminate with a null character. */ -#define PNG_CSTRING_FROM_CHUNK(s,c)\ - (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) - -/* Test on flag values as defined in the spec (section 5.4): */ -#define PNG_CHUNK_ANCILLIARY(c) (1 & ((c) >> 29)) -#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLIARY(c)) -#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) -#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) -#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) - -/* Gamma values (new at libpng-1.5.4): */ -#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ -#define PNG_GAMMA_MAC_INVERSE 65909 -#define PNG_GAMMA_sRGB_INVERSE 45455 - - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* These functions are used internally in the code. They generally - * shouldn't be used unless you are writing code to add or replace some - * functionality in libpng. More information about most functions can - * be found in the files where the functions are located. - */ - -/* Check the user version string for compatibility, returns false if the version - * numbers aren't compatible. - */ -PNG_EXTERN int png_user_version_check(png_structp png_ptr, - png_const_charp user_png_ver); - -/* Allocate memory for an internal libpng struct */ -PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), - PNG_ALLOCATED); - -/* Free memory from internal libpng struct */ -PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); - -PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, - PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), - PNG_ALLOCATED); -PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, - png_free_ptr free_fn, png_voidp mem_ptr)); - -/* Free any memory that info_ptr points to and reset struct. */ -PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, - png_infop info_ptr)); - -/* Function to allocate memory for zlib. PNGAPI is disallowed. */ -PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, - uInt size)),PNG_ALLOCATED); - -/* Function to free memory for zlib. PNGAPI is disallowed. */ -PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); - -/* Next four functions are used internally as callbacks. PNGCBAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to - * PNGCBAPI at 1.5.0 - */ - -PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, - png_bytep data, png_size_t length)); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t length)); -#endif - -PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, - png_bytep data, png_size_t length)); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED -PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); -# endif -#endif - -/* Reset the CRC variable */ -PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); - -/* Write the "data" buffer to whatever output you are using */ -PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, - png_const_bytep data, png_size_t length)); - -/* Read and check the PNG file signature */ -PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); - -/* Read the chunk header (length + type name) */ -PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); - -/* Read data from whatever input you are using into the "data" buffer */ -PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, - png_size_t length)); - -/* Read bytes into buf, and update png_ptr->crc */ -PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, - png_size_t length)); - -/* Decompress data in a chunk that uses compression */ -#if defined(PNG_READ_COMPRESSED_TEXT_SUPPORTED) -PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, - int comp_type, png_size_t chunklength, png_size_t prefix_length, - png_size_t *data_length)); -#endif - -/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ -PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); - -/* Read the CRC from the file and compare it to the libpng calculated CRC */ -PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); - -/* Calculate the CRC over a section of data. Note that we are only - * passing a maximum of 64K on systems that have this as a memory limit, - * since this is the maximum buffer size we can specify. - */ -PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, - png_const_bytep ptr, png_size_t length)); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); -#endif - -/* Write various chunks */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. - */ -PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, - png_uint_32 height, - int bit_depth, int color_type, int compression_method, int filter_method, - int interlace_method)); - -PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, - png_const_colorp palette, png_uint_32 num_pal)); - -PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, - png_size_t length)); - -PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); - -#ifdef PNG_WRITE_gAMA_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, - png_fixed_point file_gamma)); -# endif -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, - png_const_color_8p sbit, int color_type)); -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, - double white_x, double white_y, - double red_x, double red_y, double green_x, double green_y, - double blue_x, double blue_y)); -# endif -PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, - png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point - int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, - int intent)); -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, - png_const_charp name, int compression_type, - png_const_charp profile, int proflen)); - /* Note to maintainer: profile should be png_bytep */ -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, - png_const_sPLT_tp palette)); -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, - png_const_bytep trans, png_const_color_16p values, int number, - int color_type)); -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, - png_const_color_16p values, int color_type)); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, - png_const_uint_16p hist, int num_hist)); -#endif - -/* Chunks that have keywords */ -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ - defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, - png_const_charp key, png_charpp new_key)); -#endif - -#ifdef PNG_WRITE_tEXt_SUPPORTED -PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, - png_const_charp text, png_size_t text_len)); -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, - png_const_charp text, png_size_t text_len, int compression)); -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, - int compression, png_const_charp key, png_const_charp lang, - png_const_charp lang_key, png_const_charp text)); -#endif - -#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ -PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, - png_infop info_ptr, png_const_textp text_ptr, int num_text)); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, - png_int_32 x_offset, png_int_32 y_offset, int unit_type)); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED -PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, - png_int_32 X0, png_int_32 X1, int type, int nparams, - png_const_charp units, png_charpp params)); -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, - int unit_type)); -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, - png_const_timep mod_time)); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, - int unit, png_const_charp width, png_const_charp height)); -#endif - -/* Called when finished processing a row of data */ -PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); - -/* Internal use only. Called before first row of data */ -PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); - -/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an - * array of png_ptr->width pixels. If the image is not interlaced or this - * is the final pass this just does a png_memcpy, otherwise the "display" flag - * is used to determine whether to copy pixels that are not in the current pass. - * - * Because 'png_do_read_interlace' (below) replicates pixels this allows this - * function to achieve the documented 'blocky' appearance during interlaced read - * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' - * are not changed if they are not in the current pass, when display is 0. - * - * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. - * - * The API always reads from the png_struct row buffer and always assumes that - * it is full width (png_do_read_interlace has already been called.) - * - * This function is only ever used to write to row buffers provided by the - * caller of the relevant libpng API and the row must have already been - * transformed by the read transformations. - * - * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed - * bitmasks for use within the code, otherwise runtime generated masks are used. - * The default is compile time masks. - */ -#ifndef PNG_USE_COMPILE_TIME_MASKS -# define PNG_USE_COMPILE_TIME_MASKS 1 -#endif -PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, - int display)); - -#ifdef PNG_READ_INTERLACING_SUPPORTED -/* Expand an interlaced row: the 'row_info' describes the pass data that has - * been read in and must correspond to the pixels in 'row', the pixels are - * expanded (moved apart) in 'row' to match the final layout, when doing this - * the pixels are *replicated* to the intervening space. This is essential for - * the correct operation of png_combine_row, above. - */ -PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, - png_bytep row, int pass, png_uint_32 transformations)); -#endif - -/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Grab pixels out of a row for an interlaced pass */ -PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, - png_bytep row, int pass)); -#endif - -/* Unfilter a row: check the filter value before calling this, there is no point - * calling it for PNG_FILTER_VALUE_NONE. - */ -PNG_EXTERN void png_read_filter_row PNGARG((png_structp pp, png_row_infop row_info, - png_bytep row, png_const_bytep prev_row, int filter)); - -PNG_EXTERN void png_read_filter_row_up_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_sub3_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_sub4_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_avg3_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_avg4_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_paeth3_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); -PNG_EXTERN void png_read_filter_row_paeth4_neon PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep prev_row)); - -/* Choose the best filter to use and filter the row data */ -PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, - png_row_infop row_info)); - -/* Finish a row while reading, dealing with interlacing passes, etc. */ -PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); - -/* Initialize the row buffers, etc. */ -PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Optional call to update the users info structure */ -PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, - png_infop info_ptr)); -#endif - -/* These are the functions that do the transformations */ -#ifdef PNG_READ_FILLER_SUPPORTED -PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, - png_bytep row, png_uint_32 filler, png_uint_32 flags)); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info, - png_bytep row, int at_start)); -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, - png_bytep row)); -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, - png_row_infop row_info, png_bytep row)); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED -PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED -PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, - png_bytep row, png_const_color_8p sig_bits)); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, - png_bytep row, png_const_bytep palette_lookup, - png_const_bytep quantize_lookup)); - -# ifdef PNG_CORRECT_PALETTE_SUPPORTED -PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, - png_colorp palette, int num_palette)); -# endif -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED -PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, - png_bytep row, png_uint_32 bit_depth)); -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED -PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, - png_bytep row, png_const_color_8p bit_depth)); -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) -PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info, - png_bytep row, png_structp png_ptr)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, - png_bytep row, png_structp png_ptr)); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info, - png_bytep row, png_structp png_ptr)); -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED -PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, - png_bytep row, png_const_colorp palette, png_const_bytep trans, - int num_trans)); -PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, - png_bytep row, png_const_color_16p trans_color)); -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -/* The following decodes the appropriate chunks, and does error correction, - * then calls the appropriate callback for the chunk if it is valid. - */ - -/* Decode the IHDR chunk */ -PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); - -#ifdef PNG_READ_bKGD_SUPPORTED -PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED -PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif /* PNG_READ_iCCP_SUPPORTED */ - -#ifdef PNG_READ_iTXt_SUPPORTED -PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED -PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif /* PNG_READ_sPLT_SUPPORTED */ - -#ifdef PNG_READ_sRGB_SUPPORTED -PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED -PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); -#endif - -PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, - png_uint_32 chunk_name)); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk - * name, not a string. - */ -PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr, - png_uint_32 chunk_name)); -#endif - -/* Handle the transformations for reading and writing */ -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr, - png_row_infop row_info)); -#endif -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr, - png_row_infop row_info)); -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, - png_uint_32 length)); -PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t buffer_length)); -PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t buffer_length)); -PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); -PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); -PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); -# ifdef PNG_READ_tEXt_SUPPORTED -PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); -PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -# endif -# ifdef PNG_READ_zTXt_SUPPORTED -PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); -PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -# endif -# ifdef PNG_READ_iTXt_SUPPORTED -PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); -PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -# endif - -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, - png_bytep row)); -PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, - png_bytep row)); -#endif - -/* Added at libpng version 1.4.0 */ -#ifdef PNG_CHECK_cHRM_SUPPORTED -PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, - png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point - int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); -#endif - -#ifdef PNG_CHECK_cHRM_SUPPORTED -/* Added at libpng version 1.2.34 and 1.4.0 */ -/* Currently only used by png_check_cHRM_fixed */ -PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, - unsigned long *hi_product, unsigned long *lo_product)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -/* Added at libpng version 1.5.5 */ -typedef struct png_xy -{ - png_fixed_point redx, redy; - png_fixed_point greenx, greeny; - png_fixed_point bluex, bluey; - png_fixed_point whitex, whitey; -} png_xy; - -typedef struct png_XYZ -{ - png_fixed_point redX, redY, redZ; - png_fixed_point greenX, greenY, greenZ; - png_fixed_point blueX, blueY, blueZ; -} png_XYZ; - -/* The conversion APIs return 0 on success, non-zero on a parameter error. They - * allow conversion between the above representations of a color encoding. When - * converting from XYZ end points to chromaticities the absolute magnitude of - * the end points is lost, when converting back the sum of the Y values of the - * three end points will be 1.0 - */ -PNG_EXTERN int png_xy_from_XYZ PNGARG((png_xy *xy, png_XYZ XYZ)); -PNG_EXTERN int png_XYZ_from_xy PNGARG((png_XYZ *XYZ, png_xy xy)); -PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr, - png_XYZ *XYZ, png_xy xy)); -#endif - -/* Added at libpng version 1.4.0 */ -PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type)); - -/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ -PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, - png_infop info_ptr, png_infop end_info_ptr)); - -/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ -PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); - -#ifdef USE_FAR_KEYWORD /* memory model conversion function */ -PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, - int check)); -#endif /* USE_FAR_KEYWORD */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, - png_const_charp name),PNG_NORETURN); -#endif - -/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite - * the end. Always leaves the buffer nul terminated. Never errors out (and - * there is no error code.) - */ -PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string); - -/* Various internal functions to handle formatted warning messages, currently - * only implemented for warnings. - */ -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. This utility only - * does unsigned values. - */ -PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end, - int format, png_alloc_size_t number); - -/* Convenience macro that takes an array: */ -#define PNG_FORMAT_NUMBER(buffer,format,number) \ - png_format_number(buffer, buffer + (sizeof buffer), format, number) - -/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ -#define PNG_NUMBER_BUFFER_SIZE 24 - -/* These are the integer formats currently supported, the name is formed from - * the standard printf(3) format string. - */ -#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ -#define PNG_NUMBER_FORMAT_02u 2 -#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ -#define PNG_NUMBER_FORMAT_02d 2 -#define PNG_NUMBER_FORMAT_x 3 -#define PNG_NUMBER_FORMAT_02x 4 -#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* New defines and members adding in libpng-1.5.4 */ -# define PNG_WARNING_PARAMETER_SIZE 32 -# define PNG_WARNING_PARAMETER_COUNT 8 - -/* An l-value of this type has to be passed to the APIs below to cache the - * values of the parameters to a formatted warning message. - */ -typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ - PNG_WARNING_PARAMETER_SIZE]; - -PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string); - /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, - * including the trailing '\0'. - */ -PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p, - int number, int format, png_alloc_size_t value); - /* Use png_alloc_size_t because it is an unsigned type as big as any we - * need to output. Use the following for a signed value. - */ -PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p, - int number, int format, png_int_32 value); - -PNG_EXTERN void png_formatted_warning(png_structp png_ptr, - png_warning_parameters p, png_const_charp message); - /* 'message' follows the X/Open approach of using @1, @2 to insert - * parameters previously supplied using the above functions. Errors in - * specifying the paramters will simple result in garbage substitutions. - */ -#endif - -/* ASCII to FP interfaces, currently only implemented if sCAL - * support is required. - */ -#if defined(PNG_READ_sCAL_SUPPORTED) -/* MAX_DIGITS is actually the maximum number of characters in an sCAL - * width or height, derived from the precision (number of significant - * digits - a build time settable option) and assumpitions about the - * maximum ridiculous exponent. - */ -#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) - -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, - png_size_t size, double fp, unsigned int precision)); -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, - png_charp ascii, png_size_t size, png_fixed_point fp)); -#endif /* FIXED_POINT */ -#endif /* READ_sCAL */ - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* An internal API to validate the format of a floating point number. - * The result is the index of the next character. If the number is - * not valid it will be the index of a character in the supposed number. - * - * The format of a number is defined in the PNG extensions specification - * and this API is strictly conformant to that spec, not anyone elses! - * - * The format as a regular expression is: - * - * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? - * - * or: - * - * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? - * - * The complexity is that either integer or fraction must be present and the - * fraction is permitted to have no digits only if the integer is present. - * - * NOTE: The dangling E problem. - * There is a PNG valid floating point number in the following: - * - * PNG floating point numb1.ers are not greedy. - * - * Working this out requires *TWO* character lookahead (because of the - * sign), the parser does not do this - it will fail at the 'r' - this - * doesn't matter for PNG sCAL chunk values, but it requires more care - * if the value were ever to be embedded in something more complex. Use - * ANSI-C strtod if you need the lookahead. - */ -/* State table for the parser. */ -#define PNG_FP_INTEGER 0 /* before or in integer */ -#define PNG_FP_FRACTION 1 /* before or in fraction */ -#define PNG_FP_EXPONENT 2 /* before or in exponent */ -#define PNG_FP_STATE 3 /* mask for the above */ -#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ -#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ -#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ -#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ -#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ - -/* These three values don't affect the parser. They are set but not used. - */ -#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ -#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ -#define PNG_FP_NONZERO 256 /* A non-zero value */ -#define PNG_FP_STICKY 448 /* The above three flags */ - -/* This is available for the caller to store in 'state' if required. Do not - * call the parser after setting it (the parser sometimes clears it.) - */ -#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ - -/* Result codes for the parser (boolean - true meants ok, false means - * not ok yet.) - */ -#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ -#define PNG_FP_OK 1 /* The number is valid */ - -/* Tests on the sticky non-zero and negative flags. To pass these checks - * the state must also indicate that the whole number is valid - this is - * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this - * is equivalent to PNG_FP_OK above.) - */ -#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) - /* NZ_MASK: the string is valid and a non-zero negative value */ -#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) - /* Z MASK: the string is valid and a non-zero value. */ - /* PNG_FP_SAW_DIGIT: the string is valid. */ -#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) -#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) -#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) - -/* The actual parser. This can be called repeatedly, it updates - * the index into the string and the state variable (which must - * be initialzed to 0). It returns a result code, as above. There - * is no point calling the parser any more if it fails to advance to - * the end of the string - it is stuck on an invalid character (or - * terminated by '\0'). - * - * Note that the pointer will consume an E or even an E+ then leave - * a 'maybe' state even though a preceding integer.fraction is valid. - * The PNG_FP_WAS_VALID flag indicates that a preceding substring was - * a valid number. It's possible to recover from this by calling - * the parser again (from the start, with state 0) but with a string - * that omits the last character (i.e. set the size to the index of - * the problem character.) This has not been tested within libpng. - */ -PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, - png_size_t size, int *statep, png_size_tp whereami)); - -/* This is the same but it checks a complete string and returns true - * only if it just contains a floating point number. As of 1.5.4 this - * function also returns the state at the end of parsing the number if - * it was valid (otherwise it returns 0.) This can be used for testing - * for negative or zero values using the sticky flag. - */ -PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, - png_size_t size)); -#endif /* pCAL || sCAL */ - -#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* Added at libpng version 1.5.0 */ -/* This is a utility to provide a*times/div (rounded) and indicate - * if there is an overflow. The result is a boolean - false (0) - * for overflow, true (1) if no overflow, in which case *res - * holds the result. - */ -PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, - png_int_32 multiplied_by, png_int_32 divided_by)); -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* Same deal, but issue a warning on overflow and return 0. */ -PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, - png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Calculate a reciprocal - used for gamma values. This returns - * 0 if the argument is 0 in order to maintain an undefined value, - * there are no warnings. - */ -PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); - -/* The same but gives a reciprocal of the product of two fixed point - * values. Accuracy is suitable for gamma calculations but this is - * not exact - use png_muldiv for that. - */ -PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, - png_fixed_point b)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Internal fixed point gamma correction. These APIs are called as - * required to convert single values - they don't need to be fast, - * they are not used when processing image pixel values. - * - * While the input is an 'unsigned' value it must actually be the - * correct bit value - 0..255 or 0..65535 as required. - */ -PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, - unsigned int value, png_fixed_point gamma_value)); -PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value)); -PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, - png_fixed_point gamma_value)); -PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, - png_fixed_point gamma_value)); -PNG_EXTERN void png_destroy_gamma_table(png_structp png_ptr); -PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, - int bit_depth)); -#endif - -/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ - -#include "pngdebug.h" - -#ifdef __cplusplus -} -#endif - -#endif /* PNGPRIV_H */ diff --git a/WDL/libpng/pngread.c b/WDL/libpng/pngread.c deleted file mode 100644 index e2641d54..00000000 --- a/WDL/libpng/pngread.c +++ /dev/null @@ -1,1308 +0,0 @@ - -/* pngread.c - read a PNG file - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that an application calls directly to - * read a PNG file or stream. - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* Create a PNG structure for reading, and allocate any memory needed. */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ - -#ifdef PNG_USER_MEM_SUPPORTED - return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL)); -} - -/* Alternate create PNG structure for reading, and allocate any memory - * needed. - */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ -#endif /* PNG_USER_MEM_SUPPORTED */ - -#ifdef PNG_SETJMP_SUPPORTED - volatile -#endif - png_structp png_ptr; - volatile int png_cleanup_needed = 0; - -#ifdef PNG_SETJMP_SUPPORTED -#ifdef USE_FAR_KEYWORD - jmp_buf tmp_jmpbuf; -#endif -#endif - - png_debug(1, "in png_create_read_struct"); - -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - malloc_fn, mem_ptr); -#else - png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); -#endif - if (png_ptr == NULL) - return (NULL); - - /* Added at libpng-1.2.6 */ -#ifdef PNG_USER_LIMITS_SUPPORTED - png_ptr->user_width_max = PNG_USER_WIDTH_MAX; - png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; - -# ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ - png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -# endif - -# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1 */ - png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; -# endif -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* Applications that neglect to set up their own setjmp() and then - * encounter a png_error() will longjmp here. Since the jmpbuf is - * then meaningless we abort instead of returning. - */ -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else - if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ -#endif - PNG_ABORT(); -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif -#endif /* PNG_SETJMP_SUPPORTED */ - -#ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); -#endif - - png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); - - /* Call the general version checker (shared with read and write code): */ - if (!png_user_version_check(png_ptr, user_png_ver)) - png_cleanup_needed = 1; - - if (!png_cleanup_needed) - { - /* Initialize zbuf - compression buffer */ - png_ptr->zbuf_size = PNG_ZBUF_SIZE; - png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); - - if (png_ptr->zbuf == NULL) - png_cleanup_needed = 1; - } - - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; - png_ptr->zstream.opaque = (voidpf)png_ptr; - - if (!png_cleanup_needed) - { - switch (inflateInit(&png_ptr->zstream)) - { - case Z_OK: - break; /* Do nothing */ - - case Z_MEM_ERROR: - png_warning(png_ptr, "zlib memory error"); - png_cleanup_needed = 1; - break; - - case Z_STREAM_ERROR: - png_warning(png_ptr, "zlib stream error"); - png_cleanup_needed = 1; - break; - - case Z_VERSION_ERROR: - png_warning(png_ptr, "zlib version error"); - png_cleanup_needed = 1; - break; - - default: png_warning(png_ptr, "Unknown zlib error"); - png_cleanup_needed = 1; - } - } - - if (png_cleanup_needed) - { - /* Clean up PNG structure and deallocate any memory. */ - png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, - (png_free_ptr)free_fn, (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - return (NULL); - } - - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - - png_set_read_fn(png_ptr, NULL, NULL); - - - return (png_ptr); -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. This has been - * changed in v0.90 to allow reading a file that already has the magic - * bytes read from the stream. You can tell libpng how many bytes have - * been read from the beginning of the stream (up to the maximum of 8) - * via png_set_sig_bytes(), and we will only check the remaining bytes - * here. The application can then have access to the signature bytes we - * read if it is determined that this isn't a valid PNG file. - */ -void PNGAPI -png_read_info(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_read_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Read and check the PNG file signature. */ - png_read_sig(png_ptr, info_ptr); - - for (;;) - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - /* This should be a binary subdivision search or a hash for - * matching the chunk name rather than a linear search. - */ - if (chunk_name == png_IDAT) - if (png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - - if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_chunk_unknown_handling(png_ptr, chunk_name) != - PNG_HANDLE_CHUNK_AS_DEFAULT) - { - if (chunk_name == png_IDAT) - png_ptr->mode |= PNG_HAVE_IDAT; - - png_handle_unknown(png_ptr, info_ptr, length); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - - else if (chunk_name == png_IDAT) - { - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - - break; - } - } -#endif - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - - else if (chunk_name == png_IDAT) - { - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - - png_ptr->idat_size = length; - png_ptr->mode |= PNG_HAVE_IDAT; - break; - } - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length); - } -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -/* Optional call to update the users info_ptr structure */ -void PNGAPI -png_read_update_info(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_read_update_info"); - - if (png_ptr == NULL) - return; - - png_read_start_row(png_ptr); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_read_transform_info(png_ptr, info_ptr); -#else - PNG_UNUSED(info_ptr) -#endif -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Initialize palette, background, etc, after transformations - * are set, but before any reading takes place. This allows - * the user to obtain a gamma-corrected palette, for example. - * If the user doesn't call this, we will do it ourselves. - */ -void PNGAPI -png_start_read_image(png_structp png_ptr) -{ - png_debug(1, "in png_start_read_image"); - - if (png_ptr != NULL) - png_read_start_row(png_ptr); -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -void PNGAPI -png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) -{ - int ret; - - png_row_info row_info; - - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long)png_ptr->row_number, png_ptr->pass); - - /* png_read_start_row sets the information (in particular iwidth) for this - * interlace pass. - */ - if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) - png_read_start_row(png_ptr); - - /* 1.5.6: row_info moved out of png_struct to a local here. */ - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Check for transforms that have been set but were defined out */ -#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) - if (png_ptr->transformations & PNG_INVERT_MONO) - png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) - if (png_ptr->transformations & PNG_FILLER) - png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - !defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) - if (png_ptr->transformations & PNG_PACK) - png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) - if (png_ptr->transformations & PNG_SHIFT) - png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) - if (png_ptr->transformations & PNG_BGR) - png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); -#endif - } - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* If interlaced and we do not need a new row, combine row and return. - * Notice that the pixels we have from previous rows have been transformed - * already; we can only combine like with like (transformed or - * untransformed) and, because of the libpng API for interlaced images, this - * means we must transform before de-interlacing. - */ - if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) - { - switch (png_ptr->pass) - { - case 0: - if (png_ptr->row_number & 0x07) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - png_read_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - if (dsp_row != NULL && (png_ptr->row_number & 4)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 3) || png_ptr->width < 3) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 3) != 2) - { - if (dsp_row != NULL && (png_ptr->row_number & 2)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - case 5: - if ((png_ptr->row_number & 1) || png_ptr->width < 2) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - default: - case 6: - if (!(png_ptr->row_number & 1)) - { - png_read_finish_row(png_ptr); - return; - } - break; - } - } -#endif - - if (!(png_ptr->mode & PNG_HAVE_IDAT)) - png_error(png_ptr, "Invalid attempt to read row data"); - - png_ptr->zstream.next_out = png_ptr->row_buf; - png_ptr->zstream.avail_out = - (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1); - - do - { - if (!(png_ptr->zstream.avail_in)) - { - while (!png_ptr->idat_size) - { - png_crc_finish(png_ptr, 0); - - png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_in = png_ptr->zbuf; - if (png_ptr->zbuf_size > png_ptr->idat_size) - png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; - png_crc_read(png_ptr, png_ptr->zbuf, - (png_size_t)png_ptr->zstream.avail_in); - png_ptr->idat_size -= png_ptr->zstream.avail_in; - } - - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - - if (ret == Z_STREAM_END) - { - if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || - png_ptr->idat_size) - png_benign_error(png_ptr, "Extra compressed data"); - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - - if (ret != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : - "Decompression error"); - - } while (png_ptr->zstream.avail_out); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced count: - */ - png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "sequential row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal sequential row size calculation error"); - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Blow up interlaced rows to full size */ - if (png_ptr->interlaced && - (png_ptr->transformations & PNG_INTERLACE)) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - if (row != NULL) - png_combine_row(png_ptr, row, 0/*row*/); - } - - else -#endif - { - if (row != NULL) - png_combine_row(png_ptr, row, -1/*ignored*/); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, -1/*ignored*/); - } - png_read_finish_row(png_ptr); - - if (png_ptr->read_row_fn != NULL) - (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. If the image is interlaced, - * and png_set_interlace_handling() has been called, the rows need to - * contain the contents of the rows from the previous pass. If the - * image has alpha or transparency, and png_handle_alpha()[*] has been - * called, the rows contents must be initialized to the contents of the - * screen. - * - * "row" holds the actual image, and pixels are placed in it - * as they arrive. If the image is displayed after each pass, it will - * appear to "sparkle" in. "display_row" can be used to display a - * "chunky" progressive image, with finer detail added as it becomes - * available. If you do not want this "chunky" display, you may pass - * NULL for display_row. If you do not want the sparkle display, and - * you have not called png_handle_alpha(), you may pass NULL for rows. - * If you have called png_handle_alpha(), and the image has either an - * alpha channel or a transparency chunk, you must provide a buffer for - * rows. In this case, you do not have to provide a display_row buffer - * also, but you may. If the image is not interlaced, or if you have - * not called png_set_interlace_handling(), the display_row buffer will - * be ignored, so pass NULL to it. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ - -void PNGAPI -png_read_rows(png_structp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) -{ - png_uint_32 i; - png_bytepp rp; - png_bytepp dp; - - png_debug(1, "in png_read_rows"); - - if (png_ptr == NULL) - return; - - rp = row; - dp = display_row; - if (rp != NULL && dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp++; - png_bytep dptr = *dp++; - - png_read_row(png_ptr, rptr, dptr); - } - - else if (rp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp; - png_read_row(png_ptr, rptr, NULL); - rp++; - } - - else if (dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep dptr = *dp; - png_read_row(png_ptr, NULL, dptr); - dp++; - } -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the entire image. If the image has an alpha channel or a tRNS - * chunk, and you have called png_handle_alpha()[*], you will need to - * initialize the image to the current image that PNG will be overlaying. - * We set the num_rows again here, in case it was incorrectly set in - * png_read_start_row() by a call to png_read_update_info() or - * png_start_read_image() if png_set_interlace_handling() wasn't called - * prior to either of these functions like it should have been. You can - * only call this function once. If you desire to have an image for - * each pass of a interlaced image, use png_read_rows() instead. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ -void PNGAPI -png_read_image(png_structp png_ptr, png_bytepp image) -{ - png_uint_32 i, image_height; - int pass, j; - png_bytepp rp; - - png_debug(1, "in png_read_image"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) - { - pass = png_set_interlace_handling(png_ptr); - /* And make sure transforms are initialized. */ - png_start_read_image(png_ptr); - } - else - { - if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) - { - /* Caller called png_start_read_image or png_read_update_info without - * first turning on the PNG_INTERLACE transform. We can fix this here, - * but the caller should do it! - */ - png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); - /* Make sure this is set correctly */ - png_ptr->num_rows = png_ptr->height; - } - - /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in - * the above error case. - */ - pass = png_set_interlace_handling(png_ptr); - } -#else - if (png_ptr->interlaced) - png_error(png_ptr, - "Cannot read interlaced image -- interlace handler disabled"); - - pass = 1; -#endif - - image_height=png_ptr->height; - - for (j = 0; j < pass; j++) - { - rp = image; - for (i = 0; i < image_height; i++) - { - png_read_row(png_ptr, *rp, NULL); - rp++; - } - } -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. Will not read past the end of the - * file, will verify the end is accurate, and will read any comments - * or time information at the end of the file, if info is not NULL. - */ -void PNGAPI -png_read_end(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_read_end"); - - if (png_ptr == NULL) - return; - - png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ - - do - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_chunk_unknown_handling(png_ptr, chunk_name) != - PNG_HANDLE_CHUNK_AS_DEFAULT) - { - if (chunk_name == png_IDAT) - { - if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) - png_benign_error(png_ptr, "Too many IDATs found"); - } - png_handle_unknown(png_ptr, info_ptr, length); - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } -#endif - - else if (chunk_name == png_IDAT) - { - /* Zero length IDATs are legal after the last IDAT has been - * read, but not after other chunks have been read. - */ - if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) - png_benign_error(png_ptr, "Too many IDATs found"); - - png_crc_finish(png_ptr, length); - } - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length); - } while (!(png_ptr->mode & PNG_HAVE_IEND)); -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -/* Free all memory used by the read */ -void PNGAPI -png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) -{ - png_structp png_ptr = NULL; - png_infop info_ptr = NULL, end_info_ptr = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn = NULL; - png_voidp mem_ptr = NULL; -#endif - - png_debug(1, "in png_destroy_read_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; - if (png_ptr == NULL) - return; - -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; -#endif - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (end_info_ptr_ptr != NULL) - end_info_ptr = *end_info_ptr_ptr; - - png_read_destroy(png_ptr, info_ptr, end_info_ptr); - - if (info_ptr != NULL) - { -#ifdef PNG_TEXT_SUPPORTED - png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); -#endif - -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)info_ptr); -#endif - *info_ptr_ptr = NULL; - } - - if (end_info_ptr != NULL) - { -#ifdef PNG_READ_TEXT_SUPPORTED - png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); -#endif -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)end_info_ptr); -#endif - *end_info_ptr_ptr = NULL; - } - - if (png_ptr != NULL) - { -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - *png_ptr_ptr = NULL; - } -} - -/* Free all memory used by the read (old method) */ -void /* PRIVATE */ -png_read_destroy(png_structp png_ptr, png_infop info_ptr, - png_infop end_info_ptr) -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf tmp_jmp; -#endif - png_error_ptr error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; -#endif - png_voidp error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn; -#endif - - png_debug(1, "in png_read_destroy"); - - if (info_ptr != NULL) - png_info_destroy(png_ptr, info_ptr); - - if (end_info_ptr != NULL) - png_info_destroy(png_ptr, end_info_ptr); - -#ifdef PNG_READ_GAMMA_SUPPORTED - png_destroy_gamma_table(png_ptr); -#endif - - png_free(png_ptr, png_ptr->zbuf); - png_free(png_ptr, png_ptr->big_row_buf); - png_free(png_ptr, png_ptr->big_prev_row); - png_free(png_ptr, png_ptr->chunkdata); - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_free(png_ptr, png_ptr->palette_lookup); - png_free(png_ptr, png_ptr->quantize_index); -#endif - - if (png_ptr->free_me & PNG_FREE_PLTE) - png_zfree(png_ptr, png_ptr->palette); - png_ptr->free_me &= ~PNG_FREE_PLTE; - -#if defined(PNG_tRNS_SUPPORTED) || \ - defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->free_me & PNG_FREE_TRNS) - png_free(png_ptr, png_ptr->trans_alpha); - png_ptr->free_me &= ~PNG_FREE_TRNS; -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - if (png_ptr->free_me & PNG_FREE_HIST) - png_free(png_ptr, png_ptr->hist); - png_ptr->free_me &= ~PNG_FREE_HIST; -#endif - - inflateEnd(&png_ptr->zstream); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_free(png_ptr, png_ptr->save_buffer); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -#ifdef PNG_TEXT_SUPPORTED - png_free(png_ptr, png_ptr->current_text); -#endif /* PNG_TEXT_SUPPORTED */ -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - - /* Save the important info out of the png_struct, in case it is - * being used again. - */ -#ifdef PNG_SETJMP_SUPPORTED - png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); -#endif - - error_fn = png_ptr->error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - warning_fn = png_ptr->warning_fn; -#endif - error_ptr = png_ptr->error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; -#endif - - png_memset(png_ptr, 0, png_sizeof(png_struct)); - - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#endif - png_ptr->error_ptr = error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr->free_fn = free_fn; -#endif - -#ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); -#endif - -} - -void PNGAPI -png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->read_row_fn = read_row_fn; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_read_png(png_structp png_ptr, png_infop info_ptr, - int transforms, - voidp params) -{ - int row; - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). - */ - png_read_info(png_ptr, info_ptr); - if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) - png_error(png_ptr, "Image is too high to process with png_read_png()"); - - /* -------------- image transformations start here ------------------- */ - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - /* Tell libpng to strip 16-bit/color files down to 8 bits per color. - */ - if (transforms & PNG_TRANSFORM_SCALE_16) - { - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ - png_set_scale_16(png_ptr); - } -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* If both SCALE and STRIP are required pngrtran will effectively cancel the - * latter by doing SCALE first. This is ok and allows apps not to check for - * which is supported to get the right answer. - */ - if (transforms & PNG_TRANSFORM_STRIP_16) - png_set_strip_16(png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - /* Strip alpha bytes from the input data without combining with - * the background (not recommended). - */ - if (transforms & PNG_TRANSFORM_STRIP_ALPHA) - png_set_strip_alpha(png_ptr); -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) - /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ - if (transforms & PNG_TRANSFORM_PACKING) - png_set_packing(png_ptr); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - /* Change the order of packed pixels to least significant bit first - * (not useful if you are using png_set_packing). - */ - if (transforms & PNG_TRANSFORM_PACKSWAP) - png_set_packswap(png_ptr); -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED - /* Expand paletted colors into true RGB triplets - * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel - * Expand paletted or RGB images with transparency to full alpha - * channels so the data will be available as RGBA quartets. - */ - if (transforms & PNG_TRANSFORM_EXPAND) - if ((png_ptr->bit_depth < 8) || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || - (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) - png_set_expand(png_ptr); -#endif - - /* We don't handle background color or gamma transformation or quantizing. - */ - -#ifdef PNG_READ_INVERT_SUPPORTED - /* Invert monochrome files to have 0 as white and 1 as black - */ - if (transforms & PNG_TRANSFORM_INVERT_MONO) - png_set_invert_mono(png_ptr); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - /* If you want to shift the pixel values from the range [0,255] or - * [0,65535] to the original [0,7] or [0,31], or whatever range the - * colors were originally in: - */ - if ((transforms & PNG_TRANSFORM_SHIFT) - && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) - { - png_color_8p sig_bit; - - png_get_sBIT(png_ptr, info_ptr, &sig_bit); - png_set_shift(png_ptr, sig_bit); - } -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ - if (transforms & PNG_TRANSFORM_BGR) - png_set_bgr(png_ptr); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ - if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); -#endif - -#ifdef PNG_READ_SWAP_SUPPORTED - /* Swap bytes of 16-bit files to least significant byte first */ - if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) - png_set_swap(png_ptr); -#endif - -/* Added at libpng-1.2.41 */ -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel from opacity to transparency */ - if (transforms & PNG_TRANSFORM_INVERT_ALPHA) - png_set_invert_alpha(png_ptr); -#endif - -/* Added at libpng-1.2.41 */ -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* Expand grayscale image to RGB */ - if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) - png_set_gray_to_rgb(png_ptr); -#endif - -/* Added at libpng-1.5.4 */ -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if (transforms & PNG_TRANSFORM_EXPAND_16) - png_set_expand_16(png_ptr); -#endif - - /* We don't handle adding filler bytes */ - - /* We use png_read_image and rely on that for interlace handling, but we also - * call png_read_update_info therefore must turn on interlace handling now: - */ - (void)png_set_interlace_handling(png_ptr); - - /* Optional call to gamma correct and add the background to the palette - * and update info structure. REQUIRED if you are expecting libpng to - * update the palette for you (i.e., you selected such a transform above). - */ - png_read_update_info(png_ptr, info_ptr); - - /* -------------- image transformations end here ------------------- */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - if (info_ptr->row_pointers == NULL) - { - png_uint_32 iptr; - - info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, - info_ptr->height * png_sizeof(png_bytep)); - for (iptr=0; iptrheight; iptr++) - info_ptr->row_pointers[iptr] = NULL; - - info_ptr->free_me |= PNG_FREE_ROWS; - - for (row = 0; row < (int)info_ptr->height; row++) - info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, - png_get_rowbytes(png_ptr, info_ptr)); - } - - png_read_image(png_ptr, info_ptr->row_pointers); - info_ptr->valid |= PNG_INFO_IDAT; - - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - PNG_UNUSED(transforms) /* Quiet compiler warnings */ - PNG_UNUSED(params) - -} -#endif /* PNG_INFO_IMAGE_SUPPORTED */ -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrio.c b/WDL/libpng/pngrio.c deleted file mode 100644 index d0d9d8a7..00000000 --- a/WDL/libpng/pngrio.c +++ /dev/null @@ -1,176 +0,0 @@ - -/* pngrio.c - functions for data input - * - * Last changed in libpng 1.5.0 [January 6, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all input. Users who need - * special handling are expected to write a function that has the same - * arguments as this and performs a similar function, but that possibly - * has a different input method. Note that you shouldn't change this - * function, but rather write a replacement function and then make - * libpng use it at run time with png_set_read_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* Read the data from whatever input you are using. The default routine - * reads from a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered reads. This should never be asked - * to read more then 64K on a 16 bit machine. - */ -void /* PRIVATE */ -png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_debug1(4, "reading %d bytes", (int)length); - - if (png_ptr->read_data_fn != NULL) - (*(png_ptr->read_data_fn))(png_ptr, data, length); - - else - png_error(png_ptr, "Call to NULL read function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ -# ifndef USE_FAR_KEYWORD -void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - if (png_ptr == NULL) - return; - - /* fread() returns 0 on error, so it is OK to store this in a png_size_t - * instead of an int, which is what fread() actually returns. - */ - check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr); - - if (check != length) - png_error(png_ptr, "Read Error"); -} -# else -/* This is the model-independent version. Since the standard I/O library - can't handle far buffers in the medium and small models, we have to copy - the data. -*/ - -#define NEAR_BUF_SIZE 1024 -#define MIN(a,b) (a <= b ? a : b) - -static void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - png_byte *n_data; - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - /* Check if data really is near. If so, use usual code. */ - n_data = (png_byte *)CVT_PTR_NOCHECK(data); - io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); - - if ((png_bytep)n_data == data) - { - check = fread(n_data, 1, length, io_ptr); - } - - else - { - png_byte buf[NEAR_BUF_SIZE]; - png_size_t read, remaining, err; - check = 0; - remaining = length; - - do - { - read = MIN(NEAR_BUF_SIZE, remaining); - err = fread(buf, 1, read, io_ptr); - png_memcpy(data, buf, read); /* copy far buffer to near buffer */ - - if (err != read) - break; - - else - check += err; - - data += read; - remaining -= read; - } - while (remaining != 0); - } - - if ((png_uint_32)check != (png_uint_32)length) - png_error(png_ptr, "read Error"); -} -# endif -#endif - -/* This function allows the application to supply a new input function - * for libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * - * png_ptr - pointer to a png input data structure - * - * io_ptr - pointer to user supplied structure containing info about - * the input functions. May be NULL. - * - * read_data_fn - pointer to a new input function that takes as its - * arguments a pointer to a png_struct, a pointer to - * a location where input data can be stored, and a 32-bit - * unsigned int that is the number of bytes to be read. - * To exit and output any fatal error messages the new write - * function should call png_error(png_ptr, "Error msg"). - * May be NULL, in which case libpng's default function will - * be used. - */ -void PNGAPI -png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (read_data_fn != NULL) - png_ptr->read_data_fn = read_data_fn; - - else - png_ptr->read_data_fn = png_default_read_data; -#else - png_ptr->read_data_fn = read_data_fn; -#endif - - /* It is an error to write to a read device */ - if (png_ptr->write_data_fn != NULL) - { - png_ptr->write_data_fn = NULL; - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->output_flush_fn = NULL; -#endif -} -#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrtran.c b/WDL/libpng/pngrtran.c deleted file mode 100644 index 26083a0d..00000000 --- a/WDL/libpng/pngrtran.c +++ /dev/null @@ -1,5023 +0,0 @@ - -/* pngrtran.c - transforms the data in a row for PNG readers - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains functions optionally called by an application - * in order to tell libpng how to handle data when reading a PNG. - * Transformations that are used in both reading and writing are - * in pngtrans.c. - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* Set the action on getting a CRC error for an ancillary or critical chunk. */ -void PNGAPI -png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) -{ - png_debug(1, "in png_set_crc_action"); - - if (png_ptr == NULL) - return; - - /* Tell libpng how we react to CRC errors in critical chunks */ - switch (crit_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | - PNG_FLAG_CRC_CRITICAL_IGNORE; - break; - - case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ - png_warning(png_ptr, - "Can't discard critical data on CRC error"); - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - break; - } - - /* Tell libpng how we react to CRC errors in ancillary chunks */ - switch (ancil_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | - PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - break; - } -} - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS via a background color */ -void PNGFAPI -png_set_background_fixed(png_structp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma) -{ - png_debug(1, "in png_set_background_fixed"); - - if (png_ptr == NULL) - return; - - if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) - { - png_warning(png_ptr, "Application must supply a known background gamma"); - return; - } - - png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - png_memcpy(&(png_ptr->background), background_color, - png_sizeof(png_color_16)); - png_ptr->background_gamma = background_gamma; - png_ptr->background_gamma_type = (png_byte)(background_gamma_code); - if (need_expand) - png_ptr->transformations |= PNG_BACKGROUND_EXPAND; - else - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_background(png_structp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) -{ - png_set_background_fixed(png_ptr, background_color, background_gamma_code, - need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); -} -# endif /* FLOATING_POINT */ -#endif /* READ_BACKGROUND */ - -/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the - * one that pngrtran does first (scale) happens. This is necessary to allow the - * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -void PNGAPI -png_set_scale_16(png_structp png_ptr) -{ - png_debug(1, "in png_set_scale_16"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SCALE_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -/* Chop 16-bit depth files to 8-bit depth */ -void PNGAPI -png_set_strip_16(png_structp png_ptr) -{ - png_debug(1, "in png_set_strip_16"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -void PNGAPI -png_set_strip_alpha(png_structp png_ptr) -{ - png_debug(1, "in png_set_strip_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_STRIP_ALPHA; -} -#endif - -#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) -static png_fixed_point -translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, - int is_screen) -{ - /* Check for flag values. The main reason for having the old Mac value as a - * flag is that it is pretty near impossible to work out what the correct - * value is from Apple documentation - a working Mac system is needed to - * discover the value! - */ - if (output_gamma == PNG_DEFAULT_sRGB || - output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) - { - /* If there is no sRGB support this just sets the gamma to the standard - * sRGB value. (This is a side effect of using this function!) - */ -# ifdef PNG_READ_sRGB_SUPPORTED - png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; -# endif - if (is_screen) - output_gamma = PNG_GAMMA_sRGB; - else - output_gamma = PNG_GAMMA_sRGB_INVERSE; - } - - else if (output_gamma == PNG_GAMMA_MAC_18 || - output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) - { - if (is_screen) - output_gamma = PNG_GAMMA_MAC_OLD; - else - output_gamma = PNG_GAMMA_MAC_INVERSE; - } - - return output_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -static png_fixed_point -convert_gamma_value(png_structp png_ptr, double output_gamma) -{ - /* The following silently ignores cases where fixed point (times 100,000) - * gamma values are passed to the floating point API. This is safe and it - * means the fixed point constants work just fine with the floating point - * API. The alternative would just lead to undetected errors and spurious - * bug reports. Negative values fail inside the _fixed API unless they - * correspond to the flag values. - */ - if (output_gamma > 0 && output_gamma < 128) - output_gamma *= PNG_FP_1; - - /* This preserves -1 and -2 exactly: */ - output_gamma = floor(output_gamma + .5); - - if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) - png_fixed_error(png_ptr, "gamma value"); - - return (png_fixed_point)output_gamma; -} -# endif -#endif /* READ_ALPHA_MODE || READ_GAMMA */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -void PNGFAPI -png_set_alpha_mode_fixed(png_structp png_ptr, int mode, - png_fixed_point output_gamma) -{ - int compose = 0; - png_fixed_point file_gamma; - - png_debug(1, "in png_set_alpha_mode"); - - if (png_ptr == NULL) - return; - - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - - /* Validate the value to ensure it is in a reasonable range. The value - * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out users of this API - * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed. - */ - if (output_gamma < 70000 || output_gamma > 300000) - png_error(png_ptr, "output gamma out of expected range"); - - /* The default file gamma is the inverse of the output gamma; the output - * gamma may be changed below so get the file value first: - */ - file_gamma = png_reciprocal(output_gamma); - - /* There are really 8 possibilities here, composed of any combination - * of: - * - * premultiply the color channels - * do not encode non-opaque pixels - * encode the alpha as well as the color channels - * - * The differences disappear if the input/output ('screen') gamma is 1.0, - * because then the encoding is a no-op and there is only the choice of - * premultiplying the color channels or not. - * - * png_set_alpha_mode and png_set_background interact because both use - * png_compose to do the work. Calling both is only useful when - * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along - * with a default gamma value. Otherwise PNG_COMPOSE must not be set. - */ - switch (mode) - { - case PNG_ALPHA_PNG: /* default: png standard */ - /* No compose, but it may be set by png_set_background! */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - /* The output is linear: */ - output_gamma = PNG_FP_1; - break; - - case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; - /* output_gamma records the encoding of opaque pixels! */ - break; - - case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ - compose = 1; - png_ptr->transformations |= PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - default: - png_error(png_ptr, "invalid alpha mode"); - } - - /* Only set the default gamma if the file gamma has not been set (this has - * the side effect that the gamma in a second call to png_set_alpha_mode will - * be ignored.) - */ - if (png_ptr->gamma == 0) - png_ptr->gamma = file_gamma; - - /* But always set the output gamma: */ - png_ptr->screen_gamma = output_gamma; - - /* Finally, if pre-multiplying, set the background fields to achieve the - * desired result. - */ - if (compose) - { - /* And obtain alpha pre-multiplication by composing on black: */ - png_memset(&png_ptr->background, 0, sizeof png_ptr->background); - png_ptr->background_gamma = png_ptr->gamma; /* just in case */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; - - if (png_ptr->transformations & PNG_COMPOSE) - png_error(png_ptr, - "conflicting calls to set alpha mode and background"); - - png_ptr->transformations |= PNG_COMPOSE; - } - - /* New API, make sure apps call the correct initializers: */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) -{ - png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); -} -# endif -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Dither file to 8-bit. Supply a palette, the current number - * of elements in the palette, the maximum number of elements - * allowed, and a histogram if possible. If the current number - * of colors is greater then the maximum number, the palette will be - * modified to fit in the maximum number. "full_quantize" indicates - * whether we need a quantizing cube set up for RGB images, or if we - * simply are reducing the number of colors in a paletted image. - */ - -typedef struct png_dsort_struct -{ - struct png_dsort_struct FAR * next; - png_byte left; - png_byte right; -} png_dsort; -typedef png_dsort FAR * png_dsortp; -typedef png_dsort FAR * FAR * png_dsortpp; - -void PNGAPI -png_set_quantize(png_structp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize) -{ - png_debug(1, "in png_set_quantize"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_QUANTIZE; - - if (!full_quantize) - { - int i; - - png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); - for (i = 0; i < num_palette; i++) - png_ptr->quantize_index[i] = (png_byte)i; - } - - if (num_palette > maximum_colors) - { - if (histogram != NULL) - { - /* This is easy enough, just throw out the least used colors. - * Perhaps not the best solution, but good enough. - */ - - int i; - - /* Initialize an array to sort colors */ - png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); - - /* Initialize the quantize_sort array */ - for (i = 0; i < num_palette; i++) - png_ptr->quantize_sort[i] = (png_byte)i; - - /* Find the least used palette entries by starting a - * bubble sort, and running it until we have sorted - * out enough colors. Note that we don't care about - * sorting all the colors, just finding which are - * least used. - */ - - for (i = num_palette - 1; i >= maximum_colors; i--) - { - int done; /* To stop early if the list is pre-sorted */ - int j; - - done = 1; - for (j = 0; j < i; j++) - { - if (histogram[png_ptr->quantize_sort[j]] - < histogram[png_ptr->quantize_sort[j + 1]]) - { - png_byte t; - - t = png_ptr->quantize_sort[j]; - png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; - png_ptr->quantize_sort[j + 1] = t; - done = 0; - } - } - - if (done) - break; - } - - /* Swap the palette around, and set up a table, if necessary */ - if (full_quantize) - { - int j = num_palette; - - /* Put all the useful colors within the max, but don't - * move the others. - */ - for (i = 0; i < maximum_colors; i++) - { - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - palette[i] = palette[j]; - } - } - } - else - { - int j = num_palette; - - /* Move all the used colors inside the max limit, and - * develop a translation table. - */ - for (i = 0; i < maximum_colors; i++) - { - /* Only move the colors we need to */ - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - png_color tmp_color; - - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - tmp_color = palette[j]; - palette[j] = palette[i]; - palette[i] = tmp_color; - /* Indicate where the color went */ - png_ptr->quantize_index[j] = (png_byte)i; - png_ptr->quantize_index[i] = (png_byte)j; - } - } - - /* Find closest color for those colors we are not using */ - for (i = 0; i < num_palette; i++) - { - if ((int)png_ptr->quantize_index[i] >= maximum_colors) - { - int min_d, k, min_k, d_index; - - /* Find the closest color to one we threw out */ - d_index = png_ptr->quantize_index[i]; - min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); - for (k = 1, min_k = 0; k < maximum_colors; k++) - { - int d; - - d = PNG_COLOR_DIST(palette[d_index], palette[k]); - - if (d < min_d) - { - min_d = d; - min_k = k; - } - } - /* Point to closest color */ - png_ptr->quantize_index[i] = (png_byte)min_k; - } - } - } - png_free(png_ptr, png_ptr->quantize_sort); - png_ptr->quantize_sort = NULL; - } - else - { - /* This is much harder to do simply (and quickly). Perhaps - * we need to go through a median cut routine, but those - * don't always behave themselves with only a few colors - * as input. So we will just find the closest two colors, - * and throw out one of them (chosen somewhat randomly). - * [We don't understand this at all, so if someone wants to - * work on improving it, be our guest - AED, GRP] - */ - int i; - int max_d; - int num_new_palette; - png_dsortp t; - png_dsortpp hash; - - t = NULL; - - /* Initialize palette index arrays */ - png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); - png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); - - /* Initialize the sort array */ - for (i = 0; i < num_palette; i++) - { - png_ptr->index_to_palette[i] = (png_byte)i; - png_ptr->palette_to_index[i] = (png_byte)i; - } - - hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * - png_sizeof(png_dsortp))); - - num_new_palette = num_palette; - - /* Initial wild guess at how far apart the farthest pixel - * pair we will be eliminating will be. Larger - * numbers mean more areas will be allocated, Smaller - * numbers run the risk of not saving enough data, and - * having to do this all over again. - * - * I have not done extensive checking on this number. - */ - max_d = 96; - - while (num_new_palette > maximum_colors) - { - for (i = 0; i < num_new_palette - 1; i++) - { - int j; - - for (j = i + 1; j < num_new_palette; j++) - { - int d; - - d = PNG_COLOR_DIST(palette[i], palette[j]); - - if (d <= max_d) - { - - t = (png_dsortp)png_malloc_warn(png_ptr, - (png_uint_32)(png_sizeof(png_dsort))); - - if (t == NULL) - break; - - t->next = hash[d]; - t->left = (png_byte)i; - t->right = (png_byte)j; - hash[d] = t; - } - } - if (t == NULL) - break; - } - - if (t != NULL) - for (i = 0; i <= max_d; i++) - { - if (hash[i] != NULL) - { - png_dsortp p; - - for (p = hash[i]; p; p = p->next) - { - if ((int)png_ptr->index_to_palette[p->left] - < num_new_palette && - (int)png_ptr->index_to_palette[p->right] - < num_new_palette) - { - int j, next_j; - - if (num_new_palette & 0x01) - { - j = p->left; - next_j = p->right; - } - else - { - j = p->right; - next_j = p->left; - } - - num_new_palette--; - palette[png_ptr->index_to_palette[j]] - = palette[num_new_palette]; - if (!full_quantize) - { - int k; - - for (k = 0; k < num_palette; k++) - { - if (png_ptr->quantize_index[k] == - png_ptr->index_to_palette[j]) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[next_j]; - - if ((int)png_ptr->quantize_index[k] == - num_new_palette) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[j]; - } - } - - png_ptr->index_to_palette[png_ptr->palette_to_index - [num_new_palette]] = png_ptr->index_to_palette[j]; - - png_ptr->palette_to_index[png_ptr->index_to_palette[j]] - = png_ptr->palette_to_index[num_new_palette]; - - png_ptr->index_to_palette[j] = - (png_byte)num_new_palette; - - png_ptr->palette_to_index[num_new_palette] = - (png_byte)j; - } - if (num_new_palette <= maximum_colors) - break; - } - if (num_new_palette <= maximum_colors) - break; - } - } - - for (i = 0; i < 769; i++) - { - if (hash[i] != NULL) - { - png_dsortp p = hash[i]; - while (p) - { - t = p->next; - png_free(png_ptr, p); - p = t; - } - } - hash[i] = 0; - } - max_d += 96; - } - png_free(png_ptr, hash); - png_free(png_ptr, png_ptr->palette_to_index); - png_free(png_ptr, png_ptr->index_to_palette); - png_ptr->palette_to_index = NULL; - png_ptr->index_to_palette = NULL; - } - num_palette = maximum_colors; - } - if (png_ptr->palette == NULL) - { - png_ptr->palette = palette; - } - png_ptr->num_palette = (png_uint_16)num_palette; - - if (full_quantize) - { - int i; - png_bytep distance; - int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + - PNG_QUANTIZE_BLUE_BITS; - int num_red = (1 << PNG_QUANTIZE_RED_BITS); - int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); - int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); - png_size_t num_entries = ((png_size_t)1 << total_bits); - - png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_uint_32)(num_entries * png_sizeof(png_byte))); - - distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * - png_sizeof(png_byte))); - - png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); - - for (i = 0; i < num_palette; i++) - { - int ir, ig, ib; - int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); - int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); - int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); - - for (ir = 0; ir < num_red; ir++) - { - /* int dr = abs(ir - r); */ - int dr = ((ir > r) ? ir - r : r - ir); - int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + - PNG_QUANTIZE_GREEN_BITS)); - - for (ig = 0; ig < num_green; ig++) - { - /* int dg = abs(ig - g); */ - int dg = ((ig > g) ? ig - g : g - ig); - int dt = dr + dg; - int dm = ((dr > dg) ? dr : dg); - int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); - - for (ib = 0; ib < num_blue; ib++) - { - int d_index = index_g | ib; - /* int db = abs(ib - b); */ - int db = ((ib > b) ? ib - b : b - ib); - int dmax = ((dm > db) ? dm : db); - int d = dmax + dt + db; - - if (d < (int)distance[d_index]) - { - distance[d_index] = (png_byte)d; - png_ptr->palette_lookup[d_index] = (png_byte)i; - } - } - } - } - } - - png_free(png_ptr, distance); - } -} -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -void PNGFAPI -png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) -{ - png_debug(1, "in png_set_gamma_fixed"); - - if (png_ptr == NULL) - return; - - /* New in libpng-1.5.4 - reserve particular negative values as flags. */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); - -#if PNG_LIBPNG_VER >= 10600 - /* Checking the gamma values for being >0 was added in 1.5.4 along with the - * premultiplied alpha support; this actually hides an undocumented feature - * of the previous implementation which allowed gamma processing to be - * disabled in background handling. There is no evidence (so far) that this - * was being used; however, png_set_background itself accepted and must still - * accept '0' for the gamma value it takes, because it isn't always used. - * - * Since this is an API change (albeit a very minor one that removes an - * undocumented API feature) it will not be made until libpng-1.6.0. - */ - if (file_gamma <= 0) - png_error(png_ptr, "invalid file gamma in png_set_gamma"); - - if (scrn_gamma <= 0) - png_error(png_ptr, "invalid screen gamma in png_set_gamma"); -#endif - - /* Set the gamma values unconditionally - this overrides the value in the PNG - * file if a gAMA chunk was present. png_set_alpha_mode provides a - * different, easier, way to default the file gamma. - */ - png_ptr->gamma = file_gamma; - png_ptr->screen_gamma = scrn_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) -{ - png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); -} -# endif /* FLOATING_POINT_SUPPORTED */ -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand paletted images to RGB, expand grayscale images of - * less than 8-bit depth to 8-bit depth, and expand tRNS chunks - * to alpha channels. - */ -void PNGAPI -png_set_expand(png_structp png_ptr) -{ - png_debug(1, "in png_set_expand"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -} - -/* GRR 19990627: the following three functions currently are identical - * to png_set_expand(). However, it is entirely reasonable that someone - * might wish to expand an indexed image to RGB but *not* expand a single, - * fully transparent palette entry to a full alpha channel--perhaps instead - * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace - * the transparent color with a particular RGB value, or drop tRNS entirely. - * IOW, a future version of the library may make the transformations flag - * a bit more fine-grained, with separate bits for each of these three - * functions. - * - * More to the point, these functions make it obvious what libpng will be - * doing, whereas "expand" can (and does) mean any number of things. - * - * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified - * to expand only the sample depth but not to expand the tRNS to alpha - * and its name was changed to png_set_expand_gray_1_2_4_to_8(). - */ - -/* Expand paletted images to RGB. */ -void PNGAPI -png_set_palette_to_rgb(png_structp png_ptr) -{ - png_debug(1, "in png_set_palette_to_rgb"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -} - -/* Expand grayscale images of less than 8-bit depth to 8 bits. */ -void PNGAPI -png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) -{ - png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_EXPAND; - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -} - - - -/* Expand tRNS chunks to alpha channels. */ -void PNGAPI -png_set_tRNS_to_alpha(png_structp png_ptr) -{ - png_debug(1, "in png_set_tRNS_to_alpha"); - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -} -#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise - * it may not work correctly.) - */ -void PNGAPI -png_set_expand_16(png_structp png_ptr) -{ - png_debug(1, "in png_set_expand_16"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - - /* New API, make sure apps call the correct initializers: */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -void PNGAPI -png_set_gray_to_rgb(png_structp png_ptr) -{ - png_debug(1, "in png_set_gray_to_rgb"); - - if (png_ptr != NULL) - { - /* Because rgb must be 8 bits or more: */ - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_ptr->transformations |= PNG_GRAY_TO_RGB; - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void PNGFAPI -png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) -{ - png_debug(1, "in png_set_rgb_to_gray"); - - if (png_ptr == NULL) - return; - - switch(error_action) - { - case PNG_ERROR_ACTION_NONE: - png_ptr->transformations |= PNG_RGB_TO_GRAY; - break; - - case PNG_ERROR_ACTION_WARN: - png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; - break; - - case PNG_ERROR_ACTION_ERROR: - png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; - break; - - default: - png_error(png_ptr, "invalid error action to rgb_to_gray"); - break; - } - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_ptr->transformations |= PNG_EXPAND; -#else - { - png_warning(png_ptr, - "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); - - png_ptr->transformations &= ~PNG_RGB_TO_GRAY; - } -#endif - { - if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) - { - png_uint_16 red_int, green_int; - - /* NOTE: this calculation does not round, but this behavior is retained - * for consistency, the inaccuracy is very small. The code here always - * overwrites the coefficients, regardless of whether they have been - * defaulted or set already. - */ - red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); - green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); - - png_ptr->rgb_to_gray_red_coeff = red_int; - png_ptr->rgb_to_gray_green_coeff = green_int; - png_ptr->rgb_to_gray_coefficients_set = 1; - } - - else - { - if (red >= 0 && green >= 0) - png_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); - - /* Use the defaults, from the cHRM chunk if set, else the historical - * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See - * png_do_rgb_to_gray for more discussion of the values. In this case - * the coefficients are not marked as 'set' and are not overwritten if - * something has already provided a default. - */ - if (png_ptr->rgb_to_gray_red_coeff == 0 && - png_ptr->rgb_to_gray_green_coeff == 0) - { - png_ptr->rgb_to_gray_red_coeff = 6968; - png_ptr->rgb_to_gray_green_coeff = 23434; - /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ - } - } - } -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* Convert a RGB image to a grayscale of the same width. This allows us, - * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. - */ - -void PNGAPI -png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, - double green) -{ - if (png_ptr == NULL) - return; - - png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), - png_fixed(png_ptr, green, "rgb to gray green coefficient")); -} -#endif /* FLOATING POINT */ - -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -void PNGAPI -png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr - read_user_transform_fn) -{ - png_debug(1, "in png_set_read_user_transform_fn"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->read_user_transform_fn = read_user_transform_fn; -#endif -} -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -/* In the case of gamma transformations only do transformations on images where - * the [file] gamma and screen_gamma are not close reciprocals, otherwise it - * slows things down slightly, and also needlessly introduces small errors. - */ -static int /* PRIVATE */ -png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) -{ - /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma - * correction as a difference of the overall transform from 1.0 - * - * We want to compare the threshold with s*f - 1, if we get - * overflow here it is because of wacky gamma values so we - * turn on processing anyway. - */ - png_fixed_point gtest; - return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || - png_gamma_significant(gtest); -} -#endif - -/* Initialize everything needed for the read. This includes modifying - * the palette. - */ - -/*For the moment 'png_init_palette_transformations' and - * 'png_init_rgb_transformations' only do some flag canceling optimizations. - * The intent is that these two routines should have palette or rgb operations - * extracted from 'png_init_read_transformations'. - */ -static void /* PRIVATE */ -png_init_palette_transformations(png_structp png_ptr) -{ - /* Called to handle the (input) palette case. In png_do_read_transformations - * the first step is to expand the palette if requested, so this code must - * take care to only make changes that are invariant with respect to the - * palette expansion, or only do them if there is no expansion. - * - * STRIP_ALPHA has already been handled in the caller (by setting num_trans - * to 0.) - */ - int input_has_alpha = 0; - int input_has_transparency = 0; - - if (png_ptr->num_trans > 0) - { - int i; - - /* Ignore if all the entries are opaque (unlikely!) */ - for (i=0; inum_trans; ++i) - if (png_ptr->trans_alpha[i] == 255) - continue; - else if (png_ptr->trans_alpha[i] == 0) - input_has_transparency = 1; - else - input_has_alpha = 1; - } - - /* If no alpha we can optimize. */ - if (!input_has_alpha) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - if (!input_has_transparency) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND)) - { - { - png_ptr->background.red = - png_ptr->palette[png_ptr->background.index].red; - png_ptr->background.green = - png_ptr->palette[png_ptr->background.index].green; - png_ptr->background.blue = - png_ptr->palette[png_ptr->background.index].blue; - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - { - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ - int i, istop = png_ptr->num_trans; - - for (i=0; itrans_alpha[i] = (png_byte)(255 - - png_ptr->trans_alpha[i]); - } - } -#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ - } - } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ -} - -static void /* PRIVATE */ -png_init_rgb_transformations(png_structp png_ptr) -{ - /* Added to libpng-1.5.4: check the color type to determine whether there - * is any alpha or transparency in the image and simply cancel the - * background and alpha mode stuff if there isn't. - */ - int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; - int input_has_transparency = png_ptr->num_trans > 0; - - /* If no alpha we can optimize. */ - if (!input_has_alpha) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ -# ifdef PNG_READ_ALPHA_MODE_SUPPORTED - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; -# endif - - if (!input_has_transparency) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND) && - !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) - /* i.e., GRAY or GRAY_ALPHA */ - { - { - /* Expand background and tRNS chunks */ - int gray = png_ptr->background.gray; - int trans_gray = png_ptr->trans_color.gray; - - switch (png_ptr->bit_depth) - { - case 1: - gray *= 0xff; - trans_gray *= 0xff; - break; - - case 2: - gray *= 0x55; - trans_gray *= 0x55; - break; - - case 4: - gray *= 0x11; - trans_gray *= 0x11; - break; - - default: - - case 8: - /* Already 8 bits, fall through */ - - case 16: - /* Already a full 16 bits */ - break; - } - - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = (png_uint_16)gray; - - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - png_ptr->trans_color.red = png_ptr->trans_color.green = - png_ptr->trans_color.blue = (png_uint_16)trans_gray; - } - } - } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ -} - -void /* PRIVATE */ -png_init_read_transformations(png_structp png_ptr) -{ - png_debug(1, "in png_init_read_transformations"); - - /* This internal function is called from png_read_start_row in pngrutil.c - * and it is called before the 'rowbytes' calculation is done, so the code - * in here can change or update the transformations flags. - * - * First do updates that do not depend on the details of the PNG image data - * being processed. - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds - * png_set_alpha_mode and this is another source for a default file gamma so - * the test needs to be performed later - here. In addition prior to 1.5.4 - * the tests were repeated for the PALETTE color type here - this is no - * longer necessary (and doesn't seem to have been necessary before.) - */ - { - /* The following temporary indicates if overall gamma correction is - * required. - */ - int gamma_correction = 0; - - if (png_ptr->gamma != 0) /* has been set */ - { - if (png_ptr->screen_gamma != 0) /* screen set too */ - gamma_correction = png_gamma_threshold(png_ptr->gamma, - png_ptr->screen_gamma); - - else - /* Assume the output matches the input; a long time default behavior - * of libpng, although the standard has nothing to say about this. - */ - png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); - } - - else if (png_ptr->screen_gamma != 0) - /* The converse - assume the file matches the screen, note that this - * perhaps undesireable default can (from 1.5.4) be changed by calling - * png_set_alpha_mode (even if the alpha handling mode isn't required - * or isn't changed from the default.) - */ - png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); - - else /* neither are set */ - /* Just in case the following prevents any processing - file and screen - * are both assumed to be linear and there is no way to introduce a - * third gamma value other than png_set_background with 'UNIQUE', and, - * prior to 1.5.4 - */ - png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; - - /* Now turn the gamma transformation on or off as appropriate. Notice - * that PNG_GAMMA just refers to the file->screen correction. Alpha - * composition may independently cause gamma correction because it needs - * linear data (e.g. if the file has a gAMA chunk but the screen gamma - * hasn't been specified.) In any case this flag may get turned off in - * the code immediately below if the transform can be handled outside the - * row loop. - */ - if (gamma_correction) - png_ptr->transformations |= PNG_GAMMA; - - else - png_ptr->transformations &= ~PNG_GAMMA; - } -#endif - - /* Certain transformations have the effect of preventing other - * transformations that happen afterward in png_do_read_transformations, - * resolve the interdependencies here. From the code of - * png_do_read_transformations the order is: - * - * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) - * 2) PNG_STRIP_ALPHA (if no compose) - * 3) PNG_RGB_TO_GRAY - * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY - * 5) PNG_COMPOSE - * 6) PNG_GAMMA - * 7) PNG_STRIP_ALPHA (if compose) - * 8) PNG_ENCODE_ALPHA - * 9) PNG_SCALE_16_TO_8 - * 10) PNG_16_TO_8 - * 11) PNG_QUANTIZE (converts to palette) - * 12) PNG_EXPAND_16 - * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY - * 14) PNG_INVERT_MONO - * 15) PNG_SHIFT - * 16) PNG_PACK - * 17) PNG_BGR - * 18) PNG_PACKSWAP - * 19) PNG_FILLER (includes PNG_ADD_ALPHA) - * 20) PNG_INVERT_ALPHA - * 21) PNG_SWAP_ALPHA - * 22) PNG_SWAP_BYTES - * 23) PNG_USER_TRANSFORM [must be last] - */ -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE)) - { - /* Stripping the alpha channel happens immediately after the 'expand' - * transformations, before all other transformation, so it cancels out - * the alpha handling. It has the side effect negating the effect of - * PNG_EXPAND_tRNS too: - */ - png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | - PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen - * so transparency information would remain just so long as it wasn't - * expanded. This produces unexpected API changes if the set of things - * that do PNG_EXPAND_tRNS changes (perfectly possible given the - * documentation - which says ask for what you want, accept what you - * get.) This makes the behavior consistent from 1.5.4: - */ - png_ptr->num_trans = 0; - } -#endif /* STRIP_ALPHA supported, no COMPOSE */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA - * settings will have no effect. - */ - if (!png_gamma_significant(png_ptr->screen_gamma)) - { - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - } -#endif - -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) - /* Detect gray background and attempt to enable optimization for - * gray --> RGB case. - * - * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or - * RGB_ALPHA (in which case need_expand is superfluous anyway), the - * background color might actually be gray yet not be flagged as such. - * This is not a problem for the current code, which uses - * PNG_BACKGROUND_IS_GRAY only to decide when to do the - * png_do_gray_to_rgb() transformation. - * - * TODO: this code needs to be revised to avoid the complexity and - * interdependencies. The color type of the background should be recorded in - * png_set_background, along with the bit depth, then the code has a record - * of exactly what color space the background is currently in. - */ - if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) - { - /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if - * the file was grayscale the background value is gray. - */ - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } - - else if (png_ptr->transformations & PNG_COMPOSE) - { - /* PNG_COMPOSE: png_set_background was called with need_expand false, - * so the color is in the color space of the output or png_set_alpha_mode - * was called and the color is black. Ignore RGB_TO_GRAY because that - * happens before GRAY_TO_RGB. - */ - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - { - if (png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) - { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - png_ptr->background.gray = png_ptr->background.red; - } - } - } -#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ - - /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations - * can be performed directly on the palette, and some (such as rgb to gray) - * can be optimized inside the palette. This is particularly true of the - * composite (background and alpha) stuff, which can be pretty much all done - * in the palette even if the result is expanded to RGB or gray afterward. - * - * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and - * earlier and the palette stuff is actually handled on the first row. This - * leads to the reported bug that the palette returned by png_get_PLTE is not - * updated. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_init_palette_transformations(png_ptr); - - else - png_init_rgb_transformations(png_ptr); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth != 16) - { - /* TODO: fix this. Because the expand_16 operation is after the compose - * handling the background color must be 8, not 16, bits deep, but the - * application will supply a 16-bit value so reduce it here. - * - * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at - * present, so that case is ok (until do_expand_16 is moved.) - * - * NOTE: this discards the low 16 bits of the user supplied background - * color, but until expand_16 works properly there is no choice! - */ -# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) - CHOP(png_ptr->background.red); - CHOP(png_ptr->background.green); - CHOP(png_ptr->background.blue); - CHOP(png_ptr->background.gray); -# undef CHOP - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ - defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) - if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth == 16) - { - /* On the other hand, if a 16-bit file is to be reduced to 8-bits per - * component this will also happen after PNG_COMPOSE and so the background - * color must be pre-expanded here. - * - * TODO: fix this too. - */ - png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); - png_ptr->background.green = - (png_uint_16)(png_ptr->background.green * 257); - png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); - png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); - } -#endif - - /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the - * background support (see the comments in scripts/pnglibconf.dfa), this - * allows pre-multiplication of the alpha channel to be implemented as - * compositing on black. This is probably sub-optimal and has been done in - * 1.5.4 betas simply to enable external critique and testing (i.e. to - * implement the new API quickly, without lots of internal changes.) - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -# ifdef PNG_READ_BACKGROUND_SUPPORTED - /* Includes ALPHA_MODE */ - png_ptr->background_1 = png_ptr->background; -# endif - - /* This needs to change - in the palette image case a whole set of tables are - * built when it would be quicker to just calculate the correct value for - * each palette entry directly. Also, the test is too tricky - why check - * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that - * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the - * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction - * the gamma tables will not be built even if composition is required on a - * gamma encoded value. - * - * In 1.5.4 this is addressed below by an additional check on the individual - * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the - * tables. - */ - if ((png_ptr->transformations & PNG_GAMMA) - || ((png_ptr->transformations & PNG_RGB_TO_GRAY) - && (png_gamma_significant(png_ptr->gamma) || - png_gamma_significant(png_ptr->screen_gamma))) - || ((png_ptr->transformations & PNG_COMPOSE) - && (png_gamma_significant(png_ptr->gamma) - || png_gamma_significant(png_ptr->screen_gamma) -# ifdef PNG_READ_BACKGROUND_SUPPORTED - || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE - && png_gamma_significant(png_ptr->background_gamma)) -# endif - )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) - && png_gamma_significant(png_ptr->screen_gamma)) - ) - { - png_build_gamma_table(png_ptr, png_ptr->bit_depth); - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - if (png_ptr->transformations & PNG_COMPOSE) - { - /* Issue a warning about this combination: because RGB_TO_GRAY is - * optimized to do the gamma transform if present yet do_background has - * to do the same thing if both options are set a - * double-gamma-correction happens. This is true in all versions of - * libpng to date. - */ - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - png_warning(png_ptr, - "libpng does not support gamma+background+rgb_to_gray"); - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - /* We don't get to here unless there is a tRNS chunk with non-opaque - * entries - see the checking code at the start of this function. - */ - png_color back, back_1; - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) - { - - back.red = png_ptr->gamma_table[png_ptr->background.red]; - back.green = png_ptr->gamma_table[png_ptr->background.green]; - back.blue = png_ptr->gamma_table[png_ptr->background.blue]; - - back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; - back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; - back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; - } - else - { - png_fixed_point g, gs; - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = PNG_FP_1; - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - default: - g = PNG_FP_1; /* back_1 */ - gs = PNG_FP_1; /* back */ - break; - } - - if (png_gamma_significant(gs)) - { - back.red = png_gamma_8bit_correct(png_ptr->background.red, - gs); - back.green = png_gamma_8bit_correct(png_ptr->background.green, - gs); - back.blue = png_gamma_8bit_correct(png_ptr->background.blue, - gs); - } - - else - { - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - } - - if (png_gamma_significant(g)) - { - back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); - back_1.green = png_gamma_8bit_correct( - png_ptr->background.green, g); - back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, - g); - } - - else - { - back_1.red = (png_byte)png_ptr->background.red; - back_1.green = (png_byte)png_ptr->background.green; - back_1.blue = (png_byte)png_ptr->background.blue; - } - } - - for (i = 0; i < num_palette; i++) - { - if (i < (int)png_ptr->num_trans && - png_ptr->trans_alpha[i] != 0xff) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - else /* if (png_ptr->trans_alpha[i] != 0xff) */ - { - png_byte v, w; - - v = png_ptr->gamma_to_1[palette[i].red]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); - palette[i].red = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].green]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); - palette[i].green = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].blue]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); - palette[i].blue = png_ptr->gamma_from_1[w]; - } - } - else - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - } - - /* Prevent the transformations being done again. - * - * NOTE: this is highly dubious; it removes the transformations in - * place. This seems inconsistent with the general treatment of the - * transformations elsewhere. - */ - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); - } /* color_type == PNG_COLOR_TYPE_PALETTE */ - - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ - else /* color_type != PNG_COLOR_TYPE_PALETTE */ - { - int gs_sig, g_sig; - png_fixed_point g = PNG_FP_1; /* Correction to linear */ - png_fixed_point gs = PNG_FP_1; /* Correction to screen */ - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = png_ptr->screen_gamma; - /* gs = PNG_FP_1; */ - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - - default: - png_error(png_ptr, "invalid background gamma type"); - } - - g_sig = png_gamma_significant(g); - gs_sig = png_gamma_significant(gs); - - if (g_sig) - png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); - - if (gs_sig) - png_ptr->background.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, gs); - - if ((png_ptr->background.red != png_ptr->background.green) || - (png_ptr->background.red != png_ptr->background.blue) || - (png_ptr->background.red != png_ptr->background.gray)) - { - /* RGB or RGBA with color background */ - if (g_sig) - { - png_ptr->background_1.red = png_gamma_correct(png_ptr, - png_ptr->background.red, g); - - png_ptr->background_1.green = png_gamma_correct(png_ptr, - png_ptr->background.green, g); - - png_ptr->background_1.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, g); - } - - if (gs_sig) - { - png_ptr->background.red = png_gamma_correct(png_ptr, - png_ptr->background.red, gs); - - png_ptr->background.green = png_gamma_correct(png_ptr, - png_ptr->background.green, gs); - - png_ptr->background.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, gs); - } - } - - else - { - /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ - png_ptr->background_1.red = png_ptr->background_1.green - = png_ptr->background_1.blue = png_ptr->background_1.gray; - - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - } - - /* The background is now in screen gamma: */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; - } /* color_type != PNG_COLOR_TYPE_PALETTE */ - }/* png_ptr->transformations & PNG_BACKGROUND */ - - else - /* Transformation does not include PNG_BACKGROUND */ -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ - && ((png_ptr->transformations & PNG_EXPAND) == 0 || - (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -#endif - ) - { - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - - /*NOTE: there are other transformations that should probably be in here - * too. - */ - for (i = 0; i < num_palette; i++) - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - - /* Done the gamma correction. */ - png_ptr->transformations &= ~PNG_GAMMA; - } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ - } -#ifdef PNG_READ_BACKGROUND_SUPPORTED - else -#endif -#endif /* PNG_READ_GAMMA_SUPPORTED */ - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - /* No GAMMA transformation (see the hanging else 4 lines above) */ - if ((png_ptr->transformations & PNG_COMPOSE) && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = (int)png_ptr->num_trans; - png_color back; - png_colorp palette = png_ptr->palette; - - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - - for (i = 0; i < istop; i++) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - - else if (png_ptr->trans_alpha[i] != 0xff) - { - /* The png_composite() macro is defined in png.h */ - png_composite(palette[i].red, palette[i].red, - png_ptr->trans_alpha[i], back.red); - - png_composite(palette[i].green, palette[i].green, - png_ptr->trans_alpha[i], back.green); - - png_composite(palette[i].blue, palette[i].blue, - png_ptr->trans_alpha[i], back.blue); - } - } - - png_ptr->transformations &= ~PNG_COMPOSE; - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ - -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = png_ptr->num_palette; - int shift = 8 - png_ptr->sig_bit.red; - - /* significant bits can be in the range 1 to 7 for a meaninful result, if - * the number of significant bits is 0 then no shift is done (this is an - * error condition which is silently ignored.) - */ - if (shift > 0 && shift < 8) for (i=0; ipalette[i].red; - - component >>= shift; - png_ptr->palette[i].red = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.green; - if (shift > 0 && shift < 8) for (i=0; ipalette[i].green; - - component >>= shift; - png_ptr->palette[i].green = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.blue; - if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue; - - component >>= shift; - png_ptr->palette[i].blue = (png_byte)component; - } - } -#endif /* PNG_READ_SHIFT_SUPPORTED */ -} - -/* Modify the info structure to reflect the transformations. The - * info should be updated so a PNG file could be written with it, - * assuming the transformations result in valid PNG data. - */ -void /* PRIVATE */ -png_read_transform_info(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_read_transform_info"); - -#ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - /* This check must match what actually happens in - * png_do_expand_palette; if it ever checks the tRNS chunk to see if - * it is all opaque we must do the same (at present it does not.) - */ - if (png_ptr->num_trans > 0) - info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - - else - info_ptr->color_type = PNG_COLOR_TYPE_RGB; - - info_ptr->bit_depth = 8; - info_ptr->num_trans = 0; - } - else - { - if (png_ptr->num_trans) - { - if (png_ptr->transformations & PNG_EXPAND_tRNS) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } - if (info_ptr->bit_depth < 8) - info_ptr->bit_depth = 8; - - info_ptr->num_trans = 0; - } - } -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* The following is almost certainly wrong unless the background value is in - * the screen space! - */ - if (png_ptr->transformations & PNG_COMPOSE) - info_ptr->background = png_ptr->background; -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), - * however it seems that the code in png_init_read_transformations, which has - * been called before this from png_read_update_info->png_read_start_row - * sometimes does the gamma transform and cancels the flag. - */ - info_ptr->gamma = png_ptr->gamma; -#endif - - if (info_ptr->bit_depth == 16) - { -# ifdef PNG_READ_16BIT_SUPPORTED -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) - info_ptr->bit_depth = 8; -# endif - -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_16_TO_8) - info_ptr->bit_depth = 8; -# endif - -# else - /* No 16 bit support: force chopping 16-bit input down to 8, in this case - * the app program can chose if both APIs are available by setting the - * correct scaling to use. - */ -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* For compatibility with previous versions use the strip method by - * default. This code works because if PNG_SCALE_16_TO_8 is already - * set the code below will do that in preference to the chop. - */ - png_ptr->transformations |= PNG_16_TO_8; - info_ptr->bit_depth = 8; -# else - -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_ptr->transformations |= PNG_SCALE_16_TO_8; - info_ptr->bit_depth = 8; -# else - - CONFIGURATION ERROR: you must enable at least one 16 to 8 method -# endif -# endif -#endif /* !READ_16BIT_SUPPORTED */ - } - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - info_ptr->color_type = (png_byte)(info_ptr->color_type | - PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) - { - if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup && info_ptr->bit_depth == 8) - { - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && - info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - info_ptr->bit_depth = 16; - } -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) - info_ptr->bit_depth = 8; -#endif - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_STRIP_ALPHA) - { - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_ALPHA); - info_ptr->num_trans = 0; - } -#endif - - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) - info_ptr->channels++; - -#ifdef PNG_READ_FILLER_SUPPORTED - /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ - if ((png_ptr->transformations & PNG_FILLER) && - ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) - { - info_ptr->channels++; - /* If adding a true alpha channel not just filler */ - if (png_ptr->transformations & PNG_ADD_ALPHA) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } -#endif - -#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ -defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - if (info_ptr->bit_depth < png_ptr->user_transform_depth) - info_ptr->bit_depth = png_ptr->user_transform_depth; - - if (info_ptr->channels < png_ptr->user_transform_channels) - info_ptr->channels = png_ptr->user_transform_channels; - } -#endif - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * - info_ptr->bit_depth); - - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); - - /* Adding in 1.5.4: cache the above value in png_struct so that we can later - * check in png_rowbytes that the user buffer won't get overwritten. Note - * that the field is not always set - if png_read_update_info isn't called - * the application has to either not do any transforms or get the calculation - * right itself. - */ - png_ptr->info_rowbytes = info_ptr->rowbytes; - -#ifndef PNG_READ_EXPAND_SUPPORTED - if (png_ptr) - return; -#endif -} - -/* Transform the row. The order of transformations is significant, - * and is very touchy. If you add a transformation, take care to - * decide how it fits in with the other transformations here. - */ -void /* PRIVATE */ -png_do_read_transformations(png_structp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_read_transformations"); - - if (png_ptr->row_buf == NULL) - { - /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this - * error is incredibly rare and incredibly easy to debug without this - * information. - */ - png_error(png_ptr, "NULL row buffer"); - } - - /* The following is debugging; prior to 1.5.4 the code was never compiled in; - * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro - * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for - * selected new APIs to ensure that there is no API change. - */ - if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && - !(png_ptr->flags & PNG_FLAG_ROW_INIT)) - { - /* Application has failed to call either png_read_start_image() or - * png_read_update_info() after setting transforms that expand pixels. - * This check added to libpng-1.2.19 (but not enabled until 1.5.4). - */ - png_error(png_ptr, "Uninitialized row"); - } - -#ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) - { - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_do_expand_palette(row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } - - else - { - if (png_ptr->num_trans && - (png_ptr->transformations & PNG_EXPAND_tRNS)) - png_do_expand(row_info, png_ptr->row_buf + 1, - &(png_ptr->trans_color)); - - else - png_do_expand(row_info, png_ptr->row_buf + 1, - NULL); - } - } -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE) && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - { - int rgb_error = - png_do_rgb_to_gray(png_ptr, row_info, - png_ptr->row_buf + 1); - - if (rgb_error) - { - png_ptr->rgb_to_gray_status=1; - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_WARN) - png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_ERR) - png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - } - } -#endif - -/* From Andreas Dilger e-mail to png-implement, 26 March 1998: - * - * In most cases, the "simple transparency" should be done prior to doing - * gray-to-RGB, or you will have to test 3x as many bytes to check if a - * pixel is transparent. You would also need to make sure that the - * transparency information is upgraded to RGB. - * - * To summarize, the current flow is: - * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - * with background "in place" if transparent, - * convert to RGB if necessary - * - Gray + alpha -> composite with gray background and remove alpha bytes, - * convert to RGB if necessary - * - * To support RGB backgrounds for gray images we need: - * - Gray + simple transparency -> convert to RGB + simple transparency, - * compare 3 or 6 bytes and composite with - * background "in place" if transparent - * (3x compare/pixel compared to doing - * composite with gray bkgrnd) - * - Gray + alpha -> convert to RGB + alpha, composite with background and - * remove alpha bytes (3x float - * operations/pixel compared with composite - * on gray background) - * - * Greg's change will do this. The reason it wasn't done before is for - * performance, as this increases the per-pixel operations. If we would check - * in advance if the background was gray or RGB, and position the gray-to-RGB - * transform appropriately, then it would save a lot of work/time. - */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* If gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - if (png_ptr->transformations & PNG_COMPOSE) - png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->transformations & PNG_GAMMA) && -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Because RGB_TO_GRAY does the gamma transform. */ - !(png_ptr->transformations & PNG_RGB_TO_GRAY) && -#endif -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - /* Because PNG_COMPOSE does the gamma transform if there is something to - * do (if there is an alpha channel or transparency.) - */ - !((png_ptr->transformations & PNG_COMPOSE) && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && -#endif - /* Because png_init_read_transformations transforms the palette, unless - * RGB_TO_GRAY will do the transform. - */ - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - (png_ptr->transformations & PNG_COMPOSE) && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && - (row_info->color_type & PNG_COLOR_MASK_ALPHA)) - png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) - png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* There is no harm in doing both of these because only one has any effect, - * by putting the 'scale' option first if the app asks for scale (either by - * calling the API or in a TRANSFORM flag) this is what happens. - */ - if (png_ptr->transformations & PNG_16_TO_8) - png_do_chop(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) - { - png_do_quantize(row_info, png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - - if (row_info->rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Do the expansion now, after all the arithmetic has been done. Notice - * that previous transformations can handle the PNG_EXPAND_16 flag if this - * is efficient (particularly true in the case of gamma correction, where - * better accuracy results faster!) - */ - if (png_ptr->transformations & PNG_EXPAND_16) - png_do_expand_16(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /*NOTE: moved here in 1.5.4 (from much later in this list.) */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - if (png_ptr->transformations & PNG_SHIFT) - png_do_unshift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if (png_ptr->transformations & PNG_PACK) - png_do_unpack(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - if (png_ptr->transformations & PNG_BGR) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if (png_ptr->transformations & PNG_FILLER) - png_do_read_filler(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_16BIT_SUPPORTED -#ifdef PNG_READ_SWAP_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(row_info, png_ptr->row_buf + 1); -#endif -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - if (png_ptr->read_user_transform_fn != NULL) - (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (png_ptr->user_transform_depth) - row_info->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels) - row_info->channels = png_ptr->user_transform_channels; -#endif - row_info->pixel_depth = (png_byte)(row_info->bit_depth * - row_info->channels); - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); - } -#endif -} - -#ifdef PNG_READ_PACK_SUPPORTED -/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with - * a bit depth of 1, you would end up with bytes that only contained - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_do_shift() after this. - */ -void /* PRIVATE */ -png_do_unpack(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_unpack"); - - if (row_info->bit_depth < 8) - { - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - switch (row_info->bit_depth) - { - case 1: - { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x01); - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - - png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x03); - - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x0f); - - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED -/* Reverse the effects of png_do_shift. This routine merely shifts the - * pixels back to their significant bits values. Thus, if you have - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ -void /* PRIVATE */ -png_do_unshift(png_row_infop row_info, png_bytep row, - png_const_color_8p sig_bits) -{ - int color_type; - - png_debug(1, "in png_do_unshift"); - - /* The palette case has already been handled in the _init routine. */ - color_type = row_info->color_type; - - if (color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift[4]; - int channels = 0; - int bit_depth = row_info->bit_depth; - - if (color_type & PNG_COLOR_MASK_COLOR) - { - shift[channels++] = bit_depth - sig_bits->red; - shift[channels++] = bit_depth - sig_bits->green; - shift[channels++] = bit_depth - sig_bits->blue; - } - - else - { - shift[channels++] = bit_depth - sig_bits->gray; - } - - if (color_type & PNG_COLOR_MASK_ALPHA) - { - shift[channels++] = bit_depth - sig_bits->alpha; - } - - { - int c, have_shift; - - for (c = have_shift = 0; c < channels; ++c) - { - /* A shift of more than the bit depth is an error condition but it - * gets ignored here. - */ - if (shift[c] <= 0 || shift[c] >= bit_depth) - shift[c] = 0; - - else - have_shift = 1; - } - - if (!have_shift) - return; - } - - switch (bit_depth) - { - default: - /* Must be 1bpp gray: should not be here! */ - /* NOTREACHED */ - break; - - case 2: - /* Must be 2bpp gray */ - /* assert(channels == 1 && shift[0] == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - - while (bp < bp_end) - { - int b = (*bp >> 1) & 0x55; - *bp++ = (png_byte)b; - } - break; - } - - case 4: - /* Must be 4bpp gray */ - /* assert(channels == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int gray_shift = shift[0]; - int mask = 0xf >> gray_shift; - - mask |= mask << 4; - - while (bp < bp_end) - { - int b = (*bp >> gray_shift) & mask; - *bp++ = (png_byte)b; - } - break; - } - - case 8: - /* Single byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int b = *bp >> shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)b; - } - break; - } - -#ifdef PNG_READ_16BIT_SUPPORTED - case 16: - /* Double byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int value = (bp[0] << 8) + bp[1]; - - value >>= shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)(value & 0xff); - } - break; - } -#endif - } - } -} -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale rows of bit depth 16 down to 8 accurately */ -void /* PRIVATE */ -png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_scale_16_to_8"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - /* The input is an array of 16 bit components, these must be scaled to - * 8 bits each. For a 16 bit value V the required value (from the PNG - * specification) is: - * - * (V * 255) / 65535 - * - * This reduces to round(V / 257), or floor((V + 128.5)/257) - * - * Represent V as the two byte value vhi.vlo. Make a guess that the - * result is the top byte of V, vhi, then the correction to this value - * is: - * - * error = floor(((V-vhi.vhi) + 128.5) / 257) - * = floor(((vlo-vhi) + 128.5) / 257) - * - * This can be approximated using integer arithmetic (and a signed - * shift): - * - * error = (vlo-vhi+128) >> 8; - * - * The approximate differs from the exact answer only when (vlo-vhi) is - * 128; it then gives a correction of +1 when the exact correction is - * 0. This gives 128 errors. The exact answer (correct for all 16 bit - * input values) is: - * - * error = (vlo-vhi+128)*65535 >> 24; - * - * An alternative arithmetic calculation which also gives no errors is: - * - * (V * 255 + 32895) >> 16 - */ - - png_int_32 tmp = *sp++; /* must be signed! */ - tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; - *dp++ = (png_byte)tmp; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -void /* PRIVATE */ -/* Simply discard the low byte. This was the default behavior prior - * to libpng-1.5.4. - */ -png_do_chop(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_chop"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - *dp++ = *sp; - sp += 2; /* skip low byte */ - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -void /* PRIVATE */ -png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_read_swap_alpha"); - - { - png_uint_32 row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - /* This converts from RGBA to ARGB */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from RRGGBBAA to AARRGGBB */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - /* This converts from GA to AG */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from GGAA to AAGG */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } - } -} -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -void /* PRIVATE */ -png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_uint_32 row_width; - png_debug(1, "in png_do_read_invert_alpha"); - - row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=3; - dp=sp; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This inverts the alpha channel in RRGGBBAA */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=6; - dp=sp; - } - } -#endif - } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = *(--sp); - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); -/* - *(--dp) = *(--sp); - *(--dp) = *(--sp); -*/ - sp-=2; - dp=sp; - } - } -#endif - } -} -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED -/* Add filler channel if we have RGB color */ -void /* PRIVATE */ -png_do_read_filler(png_row_infop row_info, png_bytep row, - png_uint_32 filler, png_uint_32 flags) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - -#ifdef PNG_READ_16BIT_SUPPORTED - png_byte hi_filler = (png_byte)((filler>>8) & 0xff); -#endif - png_byte lo_filler = (png_byte)(filler & 0xff); - - png_debug(1, "in png_do_read_filler"); - - if ( - row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - if (flags & PNG_FLAG_FILLER_AFTER) - { - /* This changes the data from G to GX */ - png_bytep sp = row + (png_size_t)row_width; - png_bytep dp = sp + (png_size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - - else - { - /* This changes the data from G to XG */ - png_bytep sp = row + (png_size_t)row_width; - png_bytep dp = sp + (png_size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if (flags & PNG_FLAG_FILLER_AFTER) - { - /* This changes the data from GG to GGXX */ - png_bytep sp = row + (png_size_t)row_width * 2; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = hi_filler; - *(--dp) = lo_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = hi_filler; - *(--dp) = lo_filler; - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from GG to XXGG */ - png_bytep sp = row + (png_size_t)row_width * 2; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = hi_filler; - *(--dp) = lo_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } -#endif - } /* COLOR_TYPE == GRAY */ - else if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - if (row_info->bit_depth == 8) - { - if (flags & PNG_FLAG_FILLER_AFTER) - { - /* This changes the data from RGB to RGBX */ - png_bytep sp = row + (png_size_t)row_width * 3; - png_bytep dp = sp + (png_size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from RGB to XRGB */ - png_bytep sp = row + (png_size_t)row_width * 3; - png_bytep dp = sp + (png_size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if (flags & PNG_FLAG_FILLER_AFTER) - { - /* This changes the data from RRGGBB to RRGGBBXX */ - png_bytep sp = row + (png_size_t)row_width * 6; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = hi_filler; - *(--dp) = lo_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = hi_filler; - *(--dp) = lo_filler; - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - - else - { - /* This changes the data from RRGGBB to XXRRGGBB */ - png_bytep sp = row + (png_size_t)row_width * 6; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = hi_filler; - *(--dp) = lo_filler; - } - - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - } -#endif - } /* COLOR_TYPE == RGB */ -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand grayscale files to RGB, with or without alpha */ -void /* PRIVATE */ -png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_gray_to_rgb"); - - if (row_info->bit_depth >= 8 && - !(row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - /* This changes G to RGB */ - png_bytep sp = row + (png_size_t)row_width - 1; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GG to RRGGBB */ - png_bytep sp = row + (png_size_t)row_width * 2 - 1; - png_bytep dp = sp + (png_size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This changes GA to RGBA */ - png_bytep sp = row + (png_size_t)row_width * 2 - 1; - png_bytep dp = sp + (png_size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GGAA to RRGGBBAA */ - png_bytep sp = row + (png_size_t)row_width * 4 - 1; - png_bytep dp = sp + (png_size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - row_info->channels = (png_byte)(row_info->channels + 2); - row_info->color_type |= PNG_COLOR_MASK_COLOR; - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB files to grayscale, with or without alpha - * using the equation given in Poynton's ColorFAQ of 1998-01-04 at - * (THIS LINK IS DEAD June 2008 but - * versions dated 1998 through November 2002 have been archived at - * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ - * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) - * Charles Poynton poynton at poynton.com - * - * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B - * - * which can be expressed with integers as - * - * Y = (6969 * R + 23434 * G + 2365 * B)/32768 - * - * Poynton's current link (as of January 2003 through July 2011): - * - * has changed the numbers slightly: - * - * Y = 0.2126*R + 0.7152*G + 0.0722*B - * - * which can be expressed with integers as - * - * Y = (6966 * R + 23436 * G + 2366 * B)/32768 - * - * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 - * end point chromaticities and the D65 white point. Depending on the - * precision used for the D65 white point this produces a variety of different - * numbers, however if the four decimal place value used in ITU-R Rec 709 is - * used (0.3127,0.3290) the Y calculation would be: - * - * Y = (6968 * R + 23435 * G + 2366 * B)/32768 - * - * While this is correct the rounding results in an overflow for white, because - * the sum of the rounded coefficients is 32769, not 32768. Consequently - * libpng uses, instead, the closest non-overflowing approximation: - * - * Y = (6968 * R + 23434 * G + 2366 * B)/32768 - * - * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk - * (including an sRGB chunk) then the chromaticities are used to calculate the - * coefficients. See the chunk handling in pngrutil.c for more information. - * - * In all cases the calculation is to be done in a linear colorspace. If no - * gamma information is available to correct the encoding of the original RGB - * values this results in an implicit assumption that the original PNG RGB - * values were linear. - * - * Other integer coefficents can be used via png_set_rgb_to_gray(). Because - * the API takes just red and green coefficients the blue coefficient is - * calculated to make the sum 32768. This will result in different rounding - * to that used above. - */ -int /* PRIVATE */ -png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) - -{ - int rgb_error = 0; - - png_debug(1, "in png_do_rgb_to_gray"); - - if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && - (row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - PNG_CONST png_uint_32 bc = 32768 - rc - gc; - PNG_CONST png_uint_32 row_width = row_info->width; - PNG_CONST int have_alpha = - (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; - - if (row_info->bit_depth == 8) - { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - /* Notice that gamma to/from 1 are not necessarily inverses (if - * there is an overall gamma correction). Prior to 1.5.5 this code - * checked the linearized values for equality; this doesn't match - * the documentation, the original values must be checked. - */ - if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - red = png_ptr->gamma_to_1[red]; - green = png_ptr->gamma_to_1[green]; - blue = png_ptr->gamma_to_1[blue]; - - rgb_error |= 1; - *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue + 16384)>>15]; - } - - else - { - /* If there is no overall correction the table will not be - * set. - */ - if (png_ptr->gamma_table != NULL) - red = png_ptr->gamma_table[red]; - - *(dp++) = red; - } - - if (have_alpha) - *(dp++) = *(sp++); - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - rgb_error |= 1; - /*NOTE: this is the historical approach which simply - * truncates the results. - */ - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); - } - - else - *(dp++) = red; - - if (have_alpha) - *(dp++) = *(sp++); - } - } - } - - else /* RGB bit_depth == 16 */ - { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, w; - - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - - if (red == green && red == blue) - { - if (png_ptr->gamma_16_table != NULL) - w = png_ptr->gamma_16_table[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; - - else - w = red; - } - - else - { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green&0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) - >> png_ptr->gamma_shift][blue>>8]; - png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 - + bc*blue_1 + 16384)>>15); - w = png_ptr->gamma_16_from_1[(gray16&0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; - rgb_error |= 1; - } - - *(dp++) = (png_byte)((w>>8) & 0xff); - *(dp++) = (png_byte)(w & 0xff); - - if (have_alpha) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, gray16; - - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - - if (red != green || red != blue) - rgb_error |= 1; - - /* From 1.5.5 in the 16 bit case do the accurate conversion even - * in the 'fast' case - this is because this is where the code - * ends up when handling linear 16 bit data. - */ - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> - 15); - *(dp++) = (png_byte)((gray16>>8) & 0xff); - *(dp++) = (png_byte)(gray16 & 0xff); - - if (have_alpha) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - } - - row_info->channels = (png_byte)(row_info->channels - 2); - row_info->color_type = (png_byte)(row_info->color_type & - ~PNG_COLOR_MASK_COLOR); - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - return rgb_error; -} -#endif -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - int color_inc; - int i; - int v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; i++, v += color_inc) - { - palette[i].red = (png_byte)v; - palette[i].green = (png_byte)v; - palette[i].blue = (png_byte)v; - } -} -#endif - - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) -/* Replace any alpha or transparency with the supplied background color. - * "background" is already in the screen gamma, while "background_1" is - * at a gamma of 1.0. Paletted files have already been taken care of. - */ -void /* PRIVATE */ -png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) -{ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; - png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; - png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; - png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; - png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; - int gamma_shift = png_ptr->gamma_shift; -#endif - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; - int shift; - - png_debug(1, "in png_do_compose"); - - { - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_GRAY: - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row; - shift = 7; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x01) - == png_ptr->trans_color.gray) - { - *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); - } - - if (!shift) - { - shift = 7; - sp++; - } - - else - shift--; - } - break; - } - - case 2: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); - } - - else - { - png_byte p = (png_byte)((*sp >> shift) & 0x03); - png_byte g = (png_byte)((gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03); - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); - } - - if (!shift) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - - else -#endif - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); - } - - if (!shift) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - break; - } - - case 4: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); - } - - else - { - png_byte p = (png_byte)((*sp >> shift) & 0x0f); - png_byte g = (png_byte)((gamma_table[p | - (p << 4)] >> 4) & 0x0f); - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); - } - - if (!shift) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - - else -#endif - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); - } - - if (!shift) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - break; - } - - case 8: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - - else - *sp = gamma_table[*sp]; - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - } - } - break; - } - - case 16: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else - { - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - } - } - break; - } - - default: - break; - } - break; - } - - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 a = *(sp + 1); - - if (a == 0xff) - *sp = gamma_table[*sp]; - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.gray; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); - if (!optimize) - w = gamma_from_1[w]; - *sp = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_byte a = *(sp + 1); - - if (a == 0) - *sp = (png_byte)png_ptr->background.gray; - - else if (a < 0xff) - png_composite(*sp, *sp, a, png_ptr->background_1.gray); - } - } - } - else /* if (png_ptr->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else - { - png_uint_16 g, v, w; - - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize) - w = v; - else - w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 g, v; - - g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_composite_16(v, g, a, png_ptr->background_1.gray); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0xff) - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); - if (!optimize) w = gamma_from_1[w]; - *sp = w; - - v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); - if (!optimize) w = gamma_from_1[w]; - *(sp + 1) = w; - - v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); - if (!optimize) w = gamma_from_1[w]; - *(sp + 2) = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else if (a < 0xff) - { - png_composite(*sp, *sp, a, png_ptr->background.red); - - png_composite(*(sp + 1), *(sp + 1), a, - png_ptr->background.green); - - png_composite(*(sp + 2), *(sp + 2), a, - png_ptr->background.blue); - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v, w; - - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, png_ptr->background_1.red); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, png_ptr->background_1.green); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; - - *(sp + 2) = (png_byte)((w >> 8) & 0xff); - *(sp + 3) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, png_ptr->background_1.blue); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; - - *(sp + 4) = (png_byte)((w >> 8) & 0xff); - *(sp + 5) = (png_byte)(w & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 v; - - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - png_composite_16(v, r, a, png_ptr->background.red); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - png_composite_16(v, g, a, png_ptr->background.green); - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - png_composite_16(v, b, a, png_ptr->background.blue); - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - default: - break; - } - } -} -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Gamma correct the image, avoiding the alpha channel. Make sure - * you do this after you deal with the transparency issue on grayscale - * or RGB images. If your bit depth is 8, use gamma_table, if it - * is 16, use gamma_16_table and gamma_shift. Build these with - * build_gamma_table(). - */ -void /* PRIVATE */ -png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) -{ - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; - int gamma_shift = png_ptr->gamma_shift; - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_gamma"); - - if (((row_info->bit_depth <= 8 && gamma_table != NULL) || - (row_info->bit_depth == 16 && gamma_16_table != NULL))) - { - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp += 2; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY: - { - if (row_info->bit_depth == 2) - { - sp = row; - for (i = 0; i < row_width; i += 4) - { - int a = *sp & 0xc0; - int b = *sp & 0x30; - int c = *sp & 0x0c; - int d = *sp & 0x03; - - *sp = (png_byte)( - ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| - ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| - ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| - ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); - sp++; - } - } - - if (row_info->bit_depth == 4) - { - sp = row; - for (i = 0; i < row_width; i += 2) - { - int msb = *sp & 0xf0; - int lsb = *sp & 0x0f; - - *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) - | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); - sp++; - } - } - - else if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - } - } - - else if (row_info->bit_depth == 16) - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - default: - break; - } - } -} -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* Encode the alpha channel to the output gamma (the input channel is always - * linear.) Called only with color types that have an alpha channel. Needs the - * from_1 tables. - */ -void /* PRIVATE */ -png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) -{ - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_encode_alpha"); - - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) - { - if (row_info->bit_depth == 8) - { - PNG_CONST png_bytep table = png_ptr->gamma_from_1; - - if (table != NULL) - { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; - - /* The alpha channel is the last component: */ - row += step - 1; - - for (; row_width > 0; --row_width, row += step) - *row = table[*row]; - - return; - } - } - - else if (row_info->bit_depth == 16) - { - PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; - PNG_CONST int gamma_shift = png_ptr->gamma_shift; - - if (table != NULL) - { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; - - /* The alpha channel is the last component: */ - row += step - 2; - - for (; row_width > 0; --row_width, row += step) - { - png_uint_16 v; - - v = table[*(row + 1) >> gamma_shift][*row]; - *row = (png_byte)((v >> 8) & 0xff); - *(row + 1) = (png_byte)(v & 0xff); - } - - return; - } - } - } - - /* Only get to here if called with a weird row_info; no harm has been done, - * so just issue a warning. - */ - png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); -} -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expands a palette row to an RGB or RGBA row depending - * upon whether you supply trans and num_trans. - */ -void /* PRIVATE */ -png_do_expand_palette(png_row_infop row_info, png_bytep row, - png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand_palette"); - - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row + (png_size_t)((row_width - 1) >> 3); - dp = row + (png_size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 1; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - sp = row + (png_size_t)((row_width - 1) >> 2); - dp = row + (png_size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)value; - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - sp = row + (png_size_t)((row_width - 1) >> 1); - dp = row + (png_size_t)row_width - 1; - shift = (int)((row_width & 0x01) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)value; - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift += 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (row_info->bit_depth == 8) - { - { - if (num_trans > 0) - { - sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width << 2) - 1; - - for (i = 0; i < row_width; i++) - { - if ((int)(*sp) >= num_trans) - *dp-- = 0xff; - - else - *dp-- = trans_alpha[*sp]; - - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - row_info->color_type = 6; - row_info->channels = 4; - } - - else - { - sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width * 3) - 1; - - for (i = 0; i < row_width; i++) - { - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 24; - row_info->rowbytes = row_width * 3; - row_info->color_type = 2; - row_info->channels = 3; - } - } - } - } -} - -/* If the bit depth < 8, it is expanded to 8. Also, if the already - * expanded transparency value is supplied, an alpha channel is built. - */ -void /* PRIVATE */ -png_do_expand(png_row_infop row_info, png_bytep row, - png_const_color_16p trans_color) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); - - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - gray = (png_uint_16)((gray & 0x01) * 0xff); - sp = row + (png_size_t)((row_width - 1) >> 3); - dp = row + (png_size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 0xff; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - gray = (png_uint_16)((gray & 0x03) * 0x55); - sp = row + (png_size_t)((row_width - 1) >> 2); - dp = row + (png_size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)(value | (value << 2) | (value << 4) | - (value << 6)); - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - gray = (png_uint_16)((gray & 0x0f) * 0x11); - sp = row + (png_size_t)((row_width - 1) >> 1); - dp = row + (png_size_t)row_width - 1; - shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)(value | (value << 4)); - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - gray = gray & 0xff; - sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width << 1) - 1; - - for (i = 0; i < row_width; i++) - { - if (*sp == gray) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - } - } - - else if (row_info->bit_depth == 16) - { - png_byte gray_high = (png_byte)((gray >> 8) & 0xff); - png_byte gray_low = (png_byte)(gray & 0xff); - sp = row + row_info->rowbytes - 1; - dp = row + (row_info->rowbytes << 1) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 1) == gray_high && *(sp) == gray_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - } - } - - row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - row_info->channels = 2; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_width); - } - } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) - { - if (row_info->bit_depth == 8) - { - png_byte red = (png_byte)(trans_color->red & 0xff); - png_byte green = (png_byte)(trans_color->green & 0xff); - png_byte blue = (png_byte)(trans_color->blue & 0xff); - sp = row + (png_size_t)row_info->rowbytes - 1; - dp = row + (png_size_t)(row_width << 2) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - else if (row_info->bit_depth == 16) - { - png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); - png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); - png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); - png_byte red_low = (png_byte)(trans_color->red & 0xff); - png_byte green_low = (png_byte)(trans_color->green & 0xff); - png_byte blue_low = (png_byte)(trans_color->blue & 0xff); - sp = row + row_info->rowbytes - 1; - dp = row + (png_size_t)(row_width << 3) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 5) == red_high && - *(sp - 4) == red_low && - *(sp - 3) == green_high && - *(sp - 2) == green_low && - *(sp - 1) == blue_high && - *(sp ) == blue_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - row_info->channels = 4; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - } -} -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* If the bit depth is 8 and the color type is not a palette type expand the - * whole row to 16 bits. Has no effect otherwise. - */ -void /* PRIVATE */ -png_do_expand_16(png_row_infop row_info, png_bytep row) -{ - if (row_info->bit_depth == 8 && - row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - /* The row have a sequence of bytes containing [0..255] and we need - * to turn it into another row containing [0..65535], to do this we - * calculate: - * - * (input / 255) * 65535 - * - * Which happens to be exactly input * 257 and this can be achieved - * simply by byte replication in place (copying backwards). - */ - png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ - png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ - while (dp > sp) - dp[-2] = dp[-1] = *--sp, dp -= 2; - - row_info->rowbytes *= 2; - row_info->bit_depth = 16; - row_info->pixel_depth = (png_byte)(row_info->channels * 16); - } -} -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -void /* PRIVATE */ -png_do_quantize(png_row_infop row_info, png_bytep row, - png_const_bytep palette_lookup, png_const_bytep quantize_lookup) -{ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_quantize"); - - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - - /* This looks real messy, but the compiler will reduce - * it down to a reasonable formula. For example, with - * 5 bits per color, we get: - * p = (((r >> 3) & 0x1f) << 10) | - * (((g >> 3) & 0x1f) << 5) | - * ((b >> 3) & 0x1f); - */ - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - palette_lookup != NULL) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - sp++; - - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - quantize_lookup) - { - sp = row; - - for (i = 0; i < row_width; i++, sp++) - { - *sp = quantize_lookup[*sp]; - } - } - } -} -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing */ -void /* PRIVATE */ -png_do_read_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_read_intrapixel"); - - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); - *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); - } - } - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (s0 + s1 + 65536) & 0xffff; - png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } - } - } -} -#endif /* PNG_MNG_FEATURES_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrutil.c b/WDL/libpng/pngrutil.c deleted file mode 100644 index 62e96322..00000000 --- a/WDL/libpng/pngrutil.c +++ /dev/null @@ -1,4160 +0,0 @@ - -/* pngrutil.c - utilities to read a PNG file - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that are only called from within - * libpng itself during the course of reading an image. - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -#define png_strtod(p,a,b) strtod(a,b) - -png_uint_32 PNGAPI -png_get_uint_31(png_structp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range"); - - return (uval); -} - -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) -/* The following is a variation on the above for use with the fixed - * point values used for gAMA and cHRM. Instead of png_error it - * issues a warning and returns (-1) - an invalid value because both - * gAMA and cHRM use *unsigned* integers for fixed point values. - */ -#define PNG_FIXED_ERROR (-1) - -static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval <= PNG_UINT_31_MAX) - return (png_fixed_point)uval; /* known to be in range */ - - /* The caller can turn off the warning by passing NULL. */ - if (png_ptr != NULL) - png_warning(png_ptr, "PNG fixed point integer out of range"); - - return PNG_FIXED_ERROR; -} -#endif - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -/* NOTE: the read macros will obscure these definitions, so that if - * PNG_USE_READ_MACROS is set the library will not use them internally, - * but the APIs will still be available externally. - * - * The parentheses around "PNGAPI function_name" in the following three - * functions are necessary because they allow the macros to co-exist with - * these (unused but exported) functions. - */ - -/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ -png_uint_32 (PNGAPI -png_get_uint_32)(png_const_bytep buf) -{ - png_uint_32 uval = - ((png_uint_32)(*(buf )) << 24) + - ((png_uint_32)(*(buf + 1)) << 16) + - ((png_uint_32)(*(buf + 2)) << 8) + - ((png_uint_32)(*(buf + 3)) ) ; - - return uval; -} - -/* Grab a signed 32-bit integer from a buffer in big-endian format. The - * data is stored in the PNG file in two's complement format and there - * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore - * the following code does a two's complement to native conversion. - */ -png_int_32 (PNGAPI -png_get_int_32)(png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - if ((uval & 0x80000000) == 0) /* non-negative */ - return uval; - - uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ - return -(png_int_32)uval; -} - -/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ -png_uint_16 (PNGAPI -png_get_uint_16)(png_const_bytep buf) -{ - /* ANSI-C requires an int value to accomodate at least 16 bits so this - * works and allows the compiler not to worry about possible narrowing - * on 32 bit systems. (Pre-ANSI systems did not make integers smaller - * than 16 bits either.) - */ - unsigned int val = - ((unsigned int)(*buf) << 8) + - ((unsigned int)(*(buf + 1))); - - return (png_uint_16)val; -} - -#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ - -/* Read and check the PNG file signature */ -void /* PRIVATE */ -png_read_sig(png_structp png_ptr, png_infop info_ptr) -{ - png_size_t num_checked, num_to_check; - - /* Exit if the user application does not expect a signature. */ - if (png_ptr->sig_bytes >= 8) - return; - - num_checked = png_ptr->sig_bytes; - num_to_check = 8 - num_checked; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; -#endif - - /* The signature must be serialized in a single I/O call. */ - png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); - png_ptr->sig_bytes = 8; - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - if (num_checked < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Read the chunk header (length + type name). - * Put the type name into png_ptr->chunk_name, and return the length. - */ -png_uint_32 /* PRIVATE */ -png_read_chunk_header(png_structp png_ptr) -{ - png_byte buf[8]; - png_uint_32 length; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; -#endif - - /* Read the length and the chunk name. - * This must be performed in a single I/O call. - */ - png_read_data(png_ptr, buf, 8); - length = png_get_uint_31(png_ptr, buf); - - /* Put the chunk name into png_ptr->chunk_name. */ - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - - png_debug2(0, "Reading %lx chunk, length = %lu", - (unsigned long)png_ptr->chunk_name, (unsigned long)length); - - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, buf + 4, 4); - - /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; -#endif - - return length; -} - -/* Read data, and (optionally) run it through the CRC. */ -void /* PRIVATE */ -png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) -{ - if (png_ptr == NULL) - return; - - png_read_data(png_ptr, buf, length); - png_calculate_crc(png_ptr, buf, length); -} - -/* Optionally skip data and then check the CRC. Depending on whether we - * are reading a ancillary or critical chunk, and how the program has set - * things up, we may calculate the CRC on the data and print a message. - * Returns '1' if there was a CRC error, '0' otherwise. - */ -int /* PRIVATE */ -png_crc_finish(png_structp png_ptr, png_uint_32 skip) -{ - png_size_t i; - png_size_t istop = png_ptr->zbuf_size; - - for (i = (png_size_t)skip; i > istop; i -= istop) - { - png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - } - - if (i) - { - png_crc_read(png_ptr, png_ptr->zbuf, i); - } - - if (png_crc_error(png_ptr)) - { - if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ? - !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : - (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) - { - png_chunk_warning(png_ptr, "CRC error"); - } - - else - { - png_chunk_benign_error(png_ptr, "CRC error"); - return (0); - } - - return (1); - } - - return (0); -} - -/* Compare the CRC stored in the PNG file with that calculated by libpng from - * the data it has read thus far. - */ -int /* PRIVATE */ -png_crc_error(png_structp png_ptr) -{ - png_byte crc_bytes[4]; - png_uint_32 crc; - int need_crc = 1; - - if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) - need_crc = 0; - } - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; -#endif - - /* The chunk CRC must be serialized in a single I/O call. */ - png_read_data(png_ptr, crc_bytes, 4); - - if (need_crc) - { - crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); - } - - else - return (0); -} - -#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED -static png_size_t -png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, - png_bytep output, png_size_t output_size) -{ - png_size_t count = 0; - - /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't - * even necessarily handle 65536 bytes) because the type uInt is "16 bits or - * more". Consequently it is necessary to chunk the input to zlib. This - * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value - * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a - * lower value in pngpriv.h and this may sometimes have a performance - * advantage, because it forces access of the input data to be separated from - * at least some of the use by some period of time. - */ - png_ptr->zstream.next_in = data; - /* avail_in is set below from 'size' */ - png_ptr->zstream.avail_in = 0; - - while (1) - { - int ret, avail; - - /* The setting of 'avail_in' used to be outside the loop; by setting it - * inside it is possible to chunk the input to zlib and simply rely on - * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o - * data to be passed through zlib at the unavoidable cost of requiring a - * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX - * input bytes. - */ - if (png_ptr->zstream.avail_in == 0 && size > 0) - { - if (size <= ZLIB_IO_MAX) - { - /* The value is less than ZLIB_IO_MAX so the cast is safe: */ - png_ptr->zstream.avail_in = (uInt)size; - size = 0; - } - - else - { - png_ptr->zstream.avail_in = ZLIB_IO_MAX; - size -= ZLIB_IO_MAX; - } - } - - /* Reset the output buffer each time round - we empty it - * after every inflate call. - */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = png_ptr->zbuf_size; - - ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); - avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; - - /* First copy/count any new output - but only if we didn't - * get an error code. - */ - if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) - { - png_size_t space = avail; /* > 0, see above */ - - if (output != 0 && output_size > count) - { - png_size_t copy = output_size - count; - - if (space < copy) - copy = space; - - png_memcpy(output + count, png_ptr->zbuf, copy); - } - count += space; - } - - if (ret == Z_OK) - continue; - - /* Termination conditions - always reset the zstream, it - * must be left in inflateInit state. - */ - png_ptr->zstream.avail_in = 0; - inflateReset(&png_ptr->zstream); - - if (ret == Z_STREAM_END) - return count; /* NOTE: may be zero. */ - - /* Now handle the error codes - the API always returns 0 - * and the error message is dumped into the uncompressed - * buffer if available. - */ -# ifdef PNG_WARNINGS_SUPPORTED - { - png_const_charp msg; - - if (png_ptr->zstream.msg != 0) - msg = png_ptr->zstream.msg; - - else switch (ret) - { - case Z_BUF_ERROR: - msg = "Buffer error in compressed datastream"; - break; - - case Z_DATA_ERROR: - msg = "Data error in compressed datastream"; - break; - - default: - msg = "Incomplete compressed datastream"; - break; - } - - png_chunk_warning(png_ptr, msg); - } -# endif - - /* 0 means an error - notice that this code simply ignores - * zero length compressed chunks as a result. - */ - return 0; - } -} - -/* - * Decompress trailing data in a chunk. The assumption is that chunkdata - * points at an allocated area holding the contents of a chunk with a - * trailing compressed part. What we get back is an allocated area - * holding the original prefix part and an uncompressed version of the - * trailing part (the malloc area passed in is freed). - */ -void /* PRIVATE */ -png_decompress_chunk(png_structp png_ptr, int comp_type, - png_size_t chunklength, - png_size_t prefix_size, png_size_t *newlength) -{ - /* The caller should guarantee this */ - if (prefix_size > chunklength) - { - /* The recovery is to delete the chunk. */ - png_warning(png_ptr, "invalid chunklength"); - prefix_size = 0; /* To delete everything */ - } - - else if (comp_type == PNG_COMPRESSION_TYPE_BASE) - { - png_size_t expanded_size = png_inflate(png_ptr, - (png_bytep)(png_ptr->chunkdata + prefix_size), - chunklength - prefix_size, - 0, /* output */ - 0); /* output size */ - - /* Now check the limits on this chunk - if the limit fails the - * compressed data will be removed, the prefix will remain. - */ -#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED - if (png_ptr->user_chunk_malloc_max && - (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) -#else -# ifdef PNG_USER_CHUNK_MALLOC_MAX - if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && - prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) -# endif -#endif - png_warning(png_ptr, "Exceeded size limit while expanding chunk"); - - /* If the size is zero either there was an error and a message - * has already been output (warning) or the size really is zero - * and we have nothing to do - the code will exit through the - * error case below. - */ -#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ - defined(PNG_USER_CHUNK_MALLOC_MAX) - else if (expanded_size > 0) -#else - if (expanded_size > 0) -#endif - { - /* Success (maybe) - really uncompress the chunk. */ - png_size_t new_size = 0; - png_charp text = (png_charp)png_malloc_warn(png_ptr, - prefix_size + expanded_size + 1); - - if (text != NULL) - { - png_memcpy(text, png_ptr->chunkdata, prefix_size); - new_size = png_inflate(png_ptr, - (png_bytep)(png_ptr->chunkdata + prefix_size), - chunklength - prefix_size, - (png_bytep)(text + prefix_size), expanded_size); - text[prefix_size + expanded_size] = 0; /* just in case */ - - if (new_size == expanded_size) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = text; - *newlength = prefix_size + expanded_size; - return; /* The success return! */ - } - - png_warning(png_ptr, "png_inflate logic error"); - png_free(png_ptr, text); - } - - else - png_warning(png_ptr, "Not enough memory to decompress chunk"); - } - } - - else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ - { - PNG_WARNING_PARAMETERS(p) - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); - png_formatted_warning(png_ptr, p, "Unknown compression type @1"); - - /* The recovery is to simply drop the data. */ - } - - /* Generic error return - leave the prefix, delete the compressed - * data, reallocate the chunkdata to remove the potentially large - * amount of compressed data. - */ - { - png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1); - - if (text != NULL) - { - if (prefix_size > 0) - png_memcpy(text, png_ptr->chunkdata, prefix_size); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = text; - - /* This is an extra zero in the 'uncompressed' part. */ - *(png_ptr->chunkdata + prefix_size) = 0x00; - } - /* Ignore a malloc error here - it is safe. */ - } - - *newlength = prefix_size; -} -#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ - -/* Read and check the IDHR chunk */ -void /* PRIVATE */ -png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte buf[13]; - png_uint_32 width, height; - int bit_depth, color_type, compression_type, filter_type; - int interlace_type; - - png_debug(1, "in png_handle_IHDR"); - - if (png_ptr->mode & PNG_HAVE_IHDR) - png_error(png_ptr, "Out of place IHDR"); - - /* Check the length */ - if (length != 13) - png_error(png_ptr, "Invalid IHDR chunk"); - - png_ptr->mode |= PNG_HAVE_IHDR; - - png_crc_read(png_ptr, buf, 13); - png_crc_finish(png_ptr, 0); - - width = png_get_uint_31(png_ptr, buf); - height = png_get_uint_31(png_ptr, buf + 4); - bit_depth = buf[8]; - color_type = buf[9]; - compression_type = buf[10]; - filter_type = buf[11]; - interlace_type = buf[12]; - - /* Set internal variables */ - png_ptr->width = width; - png_ptr->height = height; - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->interlaced = (png_byte)interlace_type; - png_ptr->color_type = (png_byte)color_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - - /* Find number of channels */ - switch (png_ptr->color_type) - { - default: /* invalid, png_set_IHDR calls png_error */ - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_PALETTE: - png_ptr->channels = 1; - break; - - case PNG_COLOR_TYPE_RGB: - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - png_ptr->channels = 4; - break; - } - - /* Set up other useful info */ - png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * - png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); - png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); - png_debug1(3, "channels = %d", png_ptr->channels); - png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); - png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); -} - -/* Read and check the palette */ -void /* PRIVATE */ -png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_color palette[PNG_MAX_PALETTE_LENGTH]; - int num, i; -#ifdef PNG_POINTER_INDEXING_SUPPORTED - png_colorp pal_ptr; -#endif - - png_debug(1, "in png_handle_PLTE"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before PLTE"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid PLTE after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - png_error(png_ptr, "Duplicate PLTE chunk"); - - png_ptr->mode |= PNG_HAVE_PLTE; - - if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) - { - png_warning(png_ptr, - "Ignoring PLTE chunk in grayscale PNG"); - png_crc_finish(png_ptr, length); - return; - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_crc_finish(png_ptr, length); - return; - } -#endif - - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) - { - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_warning(png_ptr, "Invalid palette chunk"); - png_crc_finish(png_ptr, length); - return; - } - - else - { - png_error(png_ptr, "Invalid palette chunk"); - } - } - - num = (int)length / 3; - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - pal_ptr->red = buf[0]; - pal_ptr->green = buf[1]; - pal_ptr->blue = buf[2]; - } -#else - for (i = 0; i < num; i++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - /* Don't depend upon png_color being any order */ - palette[i].red = buf[0]; - palette[i].green = buf[1]; - palette[i].blue = buf[2]; - } -#endif - - /* If we actually need the PLTE chunk (ie for a paletted image), we do - * whatever the normal CRC configuration tells us. However, if we - * have an RGB image, the PLTE can be considered ancillary, so - * we will act as though it is. - */ -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#endif - { - png_crc_finish(png_ptr, 0); - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ - { - /* If we don't want to use the data from an ancillary chunk, - * we have two options: an error abort, or a warning and we - * ignore the data in this chunk (which should be OK, since - * it's considered ancillary for a RGB or RGBA image). - */ - if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) - { - if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) - { - png_chunk_benign_error(png_ptr, "CRC error"); - } - - else - { - png_chunk_warning(png_ptr, "CRC error"); - return; - } - } - - /* Otherwise, we (optionally) emit a warning and use the chunk. */ - else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) - { - png_chunk_warning(png_ptr, "CRC error"); - } - } -#endif - - png_set_PLTE(png_ptr, info_ptr, palette, num); - -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) - { - if (png_ptr->num_trans > (png_uint_16)num) - { - png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); - png_ptr->num_trans = (png_uint_16)num; - } - - if (info_ptr->num_trans > (png_uint_16)num) - { - png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); - info_ptr->num_trans = (png_uint_16)num; - } - } - } -#endif - -} - -void /* PRIVATE */ -png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_debug(1, "in png_handle_IEND"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) - { - png_error(png_ptr, "No image in file"); - } - - png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - - if (length != 0) - { - png_warning(png_ptr, "Incorrect IEND chunk length"); - } - - png_crc_finish(png_ptr, length); - - PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ -} - -#ifdef PNG_READ_gAMA_SUPPORTED -void /* PRIVATE */ -png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_fixed_point igamma; - png_byte buf[4]; - - png_debug(1, "in png_handle_gAMA"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before gAMA"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid gAMA after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place gAMA chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) -#ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) -#endif - ) - { - png_warning(png_ptr, "Duplicate gAMA chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (length != 4) - { - png_warning(png_ptr, "Incorrect gAMA chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 4); - - if (png_crc_finish(png_ptr, 0)) - return; - - igamma = png_get_fixed_point(NULL, buf); - - /* Check for zero gamma or an error. */ - if (igamma <= 0) - { - png_warning(png_ptr, - "Ignoring gAMA chunk with out of range gamma"); - - return; - } - -# ifdef PNG_READ_sRGB_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) - { - if (PNG_OUT_OF_RANGE(igamma, 45500, 500)) - { - PNG_WARNING_PARAMETERS(p) - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); - png_formatted_warning(png_ptr, p, - "Ignoring incorrect gAMA value @1 when sRGB is also present"); - return; - } - } -# endif /* PNG_READ_sRGB_SUPPORTED */ - -# ifdef PNG_READ_GAMMA_SUPPORTED - /* Gamma correction on read is supported. */ - png_ptr->gamma = igamma; -# endif - /* And set the 'info' structure members. */ - png_set_gAMA_fixed(png_ptr, info_ptr, igamma); -} -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -void /* PRIVATE */ -png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_size_t truelen; - png_byte buf[4]; - - png_debug(1, "in png_handle_sBIT"); - - buf[0] = buf[1] = buf[2] = buf[3] = 0; - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sBIT"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid sBIT after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - { - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place sBIT chunk"); - } - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) - { - png_warning(png_ptr, "Duplicate sBIT chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - truelen = 3; - - else - truelen = (png_size_t)png_ptr->channels; - - if (length != truelen || length > 4) - { - png_warning(png_ptr, "Incorrect sBIT chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0)) - return; - - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[1]; - png_ptr->sig_bit.blue = buf[2]; - png_ptr->sig_bit.alpha = buf[3]; - } - - else - { - png_ptr->sig_bit.gray = buf[0]; - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[0]; - png_ptr->sig_bit.blue = buf[0]; - png_ptr->sig_bit.alpha = buf[1]; - } - - png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); -} -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -void /* PRIVATE */ -png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte buf[32]; - png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, - y_blue; - - png_debug(1, "in png_handle_cHRM"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before cHRM"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid cHRM after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place cHRM chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) -# ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) -# endif - ) - { - png_warning(png_ptr, "Duplicate cHRM chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (length != 32) - { - png_warning(png_ptr, "Incorrect cHRM chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 32); - - if (png_crc_finish(png_ptr, 0)) - return; - - x_white = png_get_fixed_point(NULL, buf); - y_white = png_get_fixed_point(NULL, buf + 4); - x_red = png_get_fixed_point(NULL, buf + 8); - y_red = png_get_fixed_point(NULL, buf + 12); - x_green = png_get_fixed_point(NULL, buf + 16); - y_green = png_get_fixed_point(NULL, buf + 20); - x_blue = png_get_fixed_point(NULL, buf + 24); - y_blue = png_get_fixed_point(NULL, buf + 28); - - if (x_white == PNG_FIXED_ERROR || - y_white == PNG_FIXED_ERROR || - x_red == PNG_FIXED_ERROR || - y_red == PNG_FIXED_ERROR || - x_green == PNG_FIXED_ERROR || - y_green == PNG_FIXED_ERROR || - x_blue == PNG_FIXED_ERROR || - y_blue == PNG_FIXED_ERROR) - { - png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); - return; - } - -#ifdef PNG_READ_sRGB_SUPPORTED - if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) - { - if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(x_red, 64000, 1000) || - PNG_OUT_OF_RANGE(y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(y_green, 60000, 1000) || - PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); - png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); - png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); - png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); - png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); - png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); - png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); - - png_formatted_warning(png_ptr, p, - "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " - "when sRGB is also present"); - } - return; - } -#endif /* PNG_READ_sRGB_SUPPORTED */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Store the _white values as default coefficients for the rgb to gray - * operation if it is supported. Check if the transform is already set to - * avoid destroying the transform values. - */ - if (!png_ptr->rgb_to_gray_coefficients_set) - { - /* png_set_background has not been called and we haven't seen an sRGB - * chunk yet. Find the XYZ of the three end points. - */ - png_XYZ XYZ; - png_xy xy; - - xy.redx = x_red; - xy.redy = y_red; - xy.greenx = x_green; - xy.greeny = y_green; - xy.bluex = x_blue; - xy.bluey = y_blue; - xy.whitex = x_white; - xy.whitey = y_white; - - if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) - { - /* The success case, because XYZ_from_xy normalises to a reference - * white Y of 1.0 we just need to scale the numbers. This should - * always work just fine. It is an internal error if this overflows. - */ - { - png_fixed_point r, g, b; - if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) && - r >= 0 && r <= 32768 && - png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) && - g >= 0 && g <= 32768 && - png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) && - b >= 0 && b <= 32768 && - r+g+b <= 32769) - { - /* We allow 0 coefficients here. r+g+b may be 32769 if two or - * all of the coefficients were rounded up. Handle this by - * reducing the *largest* coefficient by 1; this matches the - * approach used for the default coefficients in pngrtran.c - */ - int add = 0; - - if (r+g+b > 32768) - add = -1; - else if (r+g+b < 32768) - add = 1; - - if (add != 0) - { - if (g >= r && g >= b) - g += add; - else if (r >= g && r >= b) - r += add; - else - b += add; - } - - /* Check for an internal error. */ - if (r+g+b != 32768) - png_error(png_ptr, - "internal error handling cHRM coefficients"); - - png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; - png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; - } - - /* This is a png_error at present even though it could be ignored - - * it should never happen, but it is important that if it does, the - * bug is fixed. - */ - else - png_error(png_ptr, "internal error handling cHRM->XYZ"); - } - } - } -#endif - - png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, - x_green, y_green, x_blue, y_blue); -} -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED -void /* PRIVATE */ -png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - int intent; - png_byte buf[1]; - - png_debug(1, "in png_handle_sRGB"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sRGB"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid sRGB after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place sRGB chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) - { - png_warning(png_ptr, "Duplicate sRGB chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (length != 1) - { - png_warning(png_ptr, "Incorrect sRGB chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 1); - - if (png_crc_finish(png_ptr, 0)) - return; - - intent = buf[0]; - - /* Check for bad intent */ - if (intent >= PNG_sRGB_INTENT_LAST) - { - png_warning(png_ptr, "Unknown sRGB intent"); - return; - } - -#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) - { - if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, - info_ptr->gamma); - - png_formatted_warning(png_ptr, p, - "Ignoring incorrect gAMA value @1 when sRGB is also present"); - } - } -#endif /* PNG_READ_gAMA_SUPPORTED */ - -#ifdef PNG_READ_cHRM_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) - { - png_warning(png_ptr, - "Ignoring incorrect cHRM value when sRGB is also present"); - } -#endif /* PNG_READ_cHRM_SUPPORTED */ - - /* This is recorded for use when handling the cHRM chunk above. An sRGB - * chunk unconditionally overwrites the coefficients for grayscale conversion - * too. - */ - png_ptr->is_sRGB = 1; - -# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Don't overwrite user supplied values: */ - if (!png_ptr->rgb_to_gray_coefficients_set) - { - /* These numbers come from the sRGB specification (or, since one has to - * pay much money to get a copy, the wikipedia sRGB page) the - * chromaticity values quoted have been inverted to get the reverse - * transformation from RGB to XYZ and the 'Y' coefficients scaled by - * 32768 (then rounded). - * - * sRGB and ITU Rec-709 both truncate the values for the D65 white - * point to four digits and, even though it actually stores five - * digits, the PNG spec gives the truncated value. - * - * This means that when the chromaticities are converted back to XYZ - * end points we end up with (6968,23435,2366), which, as described in - * pngrtran.c, would overflow. If the five digit precision and up is - * used we get, instead: - * - * 6968*R + 23435*G + 2365*B - * - * (Notice that this rounds the blue coefficient down, rather than the - * choice used in pngrtran.c which is to round the green one down.) - */ - png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */ - png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */ - /* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */ - - /* The following keeps the cHRM chunk from destroying the - * coefficients again in the event that it follows the sRGB chunk. - */ - png_ptr->rgb_to_gray_coefficients_set = 1; - } -# endif - - png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); -} -#endif /* PNG_READ_sRGB_SUPPORTED */ - -#ifdef PNG_READ_iCCP_SUPPORTED -void /* PRIVATE */ -png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ -{ - png_byte compression_type; - png_bytep pC; - png_charp profile; - png_uint_32 skip = 0; - png_uint_32 profile_size; - png_alloc_size_t profile_length; - png_size_t slength, prefix_length, data_length; - - png_debug(1, "in png_handle_iCCP"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before iCCP"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid iCCP after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place iCCP chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) - { - png_warning(png_ptr, "Duplicate iCCP chunk"); - png_crc_finish(png_ptr, length); - return; - } - -#ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "iCCP chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; - - for (profile = png_ptr->chunkdata; *profile; profile++) - /* Empty loop to find end of name */ ; - - ++profile; - - /* There should be at least one zero (the compression type byte) - * following the separator, and we should be on it - */ - if (profile >= png_ptr->chunkdata + slength - 1) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Malformed iCCP chunk"); - return; - } - - /* Compression_type should always be zero */ - compression_type = *profile++; - - if (compression_type) - { - png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); - compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 - wrote nonzero) */ - } - - prefix_length = profile - png_ptr->chunkdata; - png_decompress_chunk(png_ptr, compression_type, - slength, prefix_length, &data_length); - - profile_length = data_length - prefix_length; - - if (prefix_length > data_length || profile_length < 4) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Profile size field missing from iCCP chunk"); - return; - } - - /* Check the profile_size recorded in the first 32 bits of the ICC profile */ - pC = (png_bytep)(png_ptr->chunkdata + prefix_length); - profile_size = ((*(pC )) << 24) | - ((*(pC + 1)) << 16) | - ((*(pC + 2)) << 8) | - ((*(pC + 3)) ); - - /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, - * because profile_size is a 32 bit value. - */ - if (profile_size < profile_length) - profile_length = profile_size; - - /* And the following guarantees that profile_size == profile_length. */ - if (profile_size > profile_length) - { - PNG_WARNING_PARAMETERS(p) - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); - png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); - png_formatted_warning(png_ptr, p, - "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); - return; - } - - png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, - compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, - profile_size); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -} -#endif /* PNG_READ_iCCP_SUPPORTED */ - -#ifdef PNG_READ_sPLT_SUPPORTED -void /* PRIVATE */ -png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ -{ - png_bytep entry_start; - png_sPLT_t new_palette; - png_sPLT_entryp pp; - png_uint_32 data_length; - int entry_size, i; - png_uint_32 skip = 0; - png_size_t slength; - png_uint_32 dl; - png_size_t max_dl; - - png_debug(1, "in png_handle_sPLT"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for sPLT"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sPLT"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid sPLT after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - -#ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "sPLT chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); - - /* WARNING: this may break if size_t is less than 32 bits; it is assumed - * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a - * potential breakage point if the types in pngconf.h aren't exactly right. - */ - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; - - for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; - entry_start++) - /* Empty loop to find end of name */ ; - - ++entry_start; - - /* A sample depth should follow the separator, and we should be on it */ - if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "malformed sPLT chunk"); - return; - } - - new_palette.depth = *entry_start++; - entry_size = (new_palette.depth == 8 ? 6 : 10); - /* This must fit in a png_uint_32 because it is derived from the original - * chunk data length (and use 'length', not 'slength' here for clarity - - * they are guaranteed to be the same, see the tests above.) - */ - data_length = length - (png_uint_32)(entry_start - - (png_bytep)png_ptr->chunkdata); - - /* Integrity-check the data length */ - if (data_length % entry_size) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "sPLT chunk has bad length"); - return; - } - - dl = (png_int_32)(data_length / entry_size); - max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); - - if (dl > max_dl) - { - png_warning(png_ptr, "sPLT chunk too long"); - return; - } - - new_palette.nentries = (png_int_32)(data_length / entry_size); - - new_palette.entries = (png_sPLT_entryp)png_malloc_warn( - png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); - - if (new_palette.entries == NULL) - { - png_warning(png_ptr, "sPLT chunk requires too much memory"); - return; - } - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0; i < new_palette.nentries; i++) - { - pp = new_palette.entries + i; - - if (new_palette.depth == 8) - { - pp->red = *entry_start++; - pp->green = *entry_start++; - pp->blue = *entry_start++; - pp->alpha = *entry_start++; - } - - else - { - pp->red = png_get_uint_16(entry_start); entry_start += 2; - pp->green = png_get_uint_16(entry_start); entry_start += 2; - pp->blue = png_get_uint_16(entry_start); entry_start += 2; - pp->alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp->frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#else - pp = new_palette.entries; - - for (i = 0; i < new_palette.nentries; i++) - { - - if (new_palette.depth == 8) - { - pp[i].red = *entry_start++; - pp[i].green = *entry_start++; - pp[i].blue = *entry_start++; - pp[i].alpha = *entry_start++; - } - - else - { - pp[i].red = png_get_uint_16(entry_start); entry_start += 2; - pp[i].green = png_get_uint_16(entry_start); entry_start += 2; - pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; - pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#endif - - /* Discard all chunk data except the name and stash that */ - new_palette.name = png_ptr->chunkdata; - - png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, new_palette.entries); -} -#endif /* PNG_READ_sPLT_SUPPORTED */ - -#ifdef PNG_READ_tRNS_SUPPORTED -void /* PRIVATE */ -png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_tRNS"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before tRNS"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid tRNS after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) - { - png_warning(png_ptr, "Duplicate tRNS chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - png_byte buf[2]; - - if (length != 2) - { - png_warning(png_ptr, "Incorrect tRNS chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 2); - png_ptr->num_trans = 1; - png_ptr->trans_color.gray = png_get_uint_16(buf); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_byte buf[6]; - - if (length != 6) - { - png_warning(png_ptr, "Incorrect tRNS chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, (png_size_t)length); - png_ptr->num_trans = 1; - png_ptr->trans_color.red = png_get_uint_16(buf); - png_ptr->trans_color.green = png_get_uint_16(buf + 2); - png_ptr->trans_color.blue = png_get_uint_16(buf + 4); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (!(png_ptr->mode & PNG_HAVE_PLTE)) - { - /* Should be an error, but we can cope with it. */ - png_warning(png_ptr, "Missing PLTE before tRNS"); - } - - if (length > (png_uint_32)png_ptr->num_palette || - length > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, "Incorrect tRNS chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - if (length == 0) - { - png_warning(png_ptr, "Zero length tRNS chunk"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, readbuf, (png_size_t)length); - png_ptr->num_trans = (png_uint_16)length; - } - - else - { - png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); - png_crc_finish(png_ptr, length); - return; - } - - if (png_crc_finish(png_ptr, 0)) - { - png_ptr->num_trans = 0; - return; - } - - png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_color)); -} -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED -void /* PRIVATE */ -png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_size_t truelen; - png_byte buf[6]; - png_color_16 background; - - png_debug(1, "in png_handle_bKGD"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before bKGD"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid bKGD after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - { - png_warning(png_ptr, "Missing PLTE before bKGD"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) - { - png_warning(png_ptr, "Duplicate bKGD chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - truelen = 1; - - else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - truelen = 6; - - else - truelen = 2; - - if (length != truelen) - { - png_warning(png_ptr, "Incorrect bKGD chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0)) - return; - - /* We convert the index value into RGB components so that we can allow - * arbitrary RGB values for background when we have transparency, and - * so it is easy to determine the RGB values of the background color - * from the info_ptr struct. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - background.index = buf[0]; - - if (info_ptr && info_ptr->num_palette) - { - if (buf[0] >= info_ptr->num_palette) - { - png_warning(png_ptr, "Incorrect bKGD chunk index value"); - return; - } - - background.red = (png_uint_16)png_ptr->palette[buf[0]].red; - background.green = (png_uint_16)png_ptr->palette[buf[0]].green; - background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; - } - - else - background.red = background.green = background.blue = 0; - - background.gray = 0; - } - - else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ - { - background.index = 0; - background.red = - background.green = - background.blue = - background.gray = png_get_uint_16(buf); - } - - else - { - background.index = 0; - background.red = png_get_uint_16(buf); - background.green = png_get_uint_16(buf + 2); - background.blue = png_get_uint_16(buf + 4); - background.gray = 0; - } - - png_set_bKGD(png_ptr, info_ptr, &background); -} -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -void /* PRIVATE */ -png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - unsigned int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_hIST"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before hIST"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid hIST after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (!(png_ptr->mode & PNG_HAVE_PLTE)) - { - png_warning(png_ptr, "Missing PLTE before hIST"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) - { - png_warning(png_ptr, "Duplicate hIST chunk"); - png_crc_finish(png_ptr, length); - return; - } - - num = length / 2 ; - - if (num != (unsigned int)png_ptr->num_palette || num > - (unsigned int)PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, "Incorrect hIST chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - for (i = 0; i < num; i++) - { - png_byte buf[2]; - - png_crc_read(png_ptr, buf, 2); - readbuf[i] = png_get_uint_16(buf); - } - - if (png_crc_finish(png_ptr, 0)) - return; - - png_set_hIST(png_ptr, info_ptr, readbuf); -} -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -void /* PRIVATE */ -png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_uint_32 res_x, res_y; - int unit_type; - - png_debug(1, "in png_handle_pHYs"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before pHYs"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid pHYs after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) - { - png_warning(png_ptr, "Duplicate pHYs chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (length != 9) - { - png_warning(png_ptr, "Incorrect pHYs chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0)) - return; - - res_x = png_get_uint_32(buf); - res_y = png_get_uint_32(buf + 4); - unit_type = buf[8]; - png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); -} -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -void /* PRIVATE */ -png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_int_32 offset_x, offset_y; - int unit_type; - - png_debug(1, "in png_handle_oFFs"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before oFFs"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid oFFs after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) - { - png_warning(png_ptr, "Duplicate oFFs chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (length != 9) - { - png_warning(png_ptr, "Incorrect oFFs chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0)) - return; - - offset_x = png_get_int_32(buf); - offset_y = png_get_int_32(buf + 4); - unit_type = buf[8]; - png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); -} -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -/* Read the pCAL chunk (described in the PNG Extensions document) */ -void /* PRIVATE */ -png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_int_32 X0, X1; - png_byte type, nparams; - png_charp buf, units, endptr; - png_charpp params; - png_size_t slength; - int i; - - png_debug(1, "in png_handle_pCAL"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before pCAL"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid pCAL after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) - { - png_warning(png_ptr, "Duplicate pCAL chunk"); - png_crc_finish(png_ptr, length); - return; - } - - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", - length + 1); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "No memory for pCAL purpose"); - return; - } - - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - - png_debug(3, "Finding end of pCAL purpose string"); - for (buf = png_ptr->chunkdata; *buf; buf++) - /* Empty loop */ ; - - endptr = png_ptr->chunkdata + slength; - - /* We need to have at least 12 bytes after the purpose string - * in order to get the parameter information. - */ - if (endptr <= buf + 12) - { - png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); - X0 = png_get_int_32((png_bytep)buf+1); - X1 = png_get_int_32((png_bytep)buf+5); - type = buf[9]; - nparams = buf[10]; - units = buf + 11; - - png_debug(3, "Checking pCAL equation type and number of parameters"); - /* Check that we have the right number of parameters for known - * equation types. - */ - if ((type == PNG_EQUATION_LINEAR && nparams != 2) || - (type == PNG_EQUATION_BASE_E && nparams != 3) || - (type == PNG_EQUATION_ARBITRARY && nparams != 3) || - (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) - { - png_warning(png_ptr, "Invalid pCAL parameters for equation type"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - else if (type >= PNG_EQUATION_LAST) - { - png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); - } - - for (buf = units; *buf; buf++) - /* Empty loop to move past the units string. */ ; - - png_debug(3, "Allocating pCAL parameters array"); - - params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)(nparams * png_sizeof(png_charp))); - - if (params == NULL) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "No memory for pCAL params"); - return; - } - - /* Get pointers to the start of each parameter string. */ - for (i = 0; i < (int)nparams; i++) - { - buf++; /* Skip the null string terminator from previous parameter. */ - - png_debug1(3, "Reading pCAL parameter %d", i); - - for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) - /* Empty loop to move past each parameter string */ ; - - /* Make sure we haven't run out of data yet */ - if (buf > endptr) - { - png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, params); - return; - } - } - - png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, - units, params); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, params); -} -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -/* Read the sCAL chunk */ -void /* PRIVATE */ -png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_size_t slength, i; - int state; - - png_debug(1, "in png_handle_sCAL"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sCAL"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) - { - png_warning(png_ptr, "Invalid sCAL after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) - { - png_warning(png_ptr, "Duplicate sCAL chunk"); - png_crc_finish(png_ptr, length); - return; - } - - /* Need unit type, width, \0, height: minimum 4 bytes */ - else if (length < 4) - { - png_warning(png_ptr, "sCAL chunk too short"); - png_crc_finish(png_ptr, length); - return; - } - - png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", - length + 1); - - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk"); - png_crc_finish(png_ptr, length); - return; - } - - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - /* Validate the unit. */ - if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) - { - png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - /* Validate the ASCII numbers, need two ASCII numbers separated by - * a '\0' and they need to fit exactly in the chunk data. - */ - i = 1; - state = 0; - - if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || - i >= slength || png_ptr->chunkdata[i++] != 0) - png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); - - else if (!PNG_FP_IS_POSITIVE(state)) - png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); - - else - { - png_size_t heighti = i; - - state = 0; - if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || - i != slength) - png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); - - else if (!PNG_FP_IS_POSITIVE(state)) - png_warning(png_ptr, - "Invalid sCAL chunk ignored: non-positive height"); - - else - /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], - png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); - } - - /* Clean up - just free the temporarily allocated buffer. */ - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -} -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -void /* PRIVATE */ -png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte buf[7]; - png_time mod_time; - - png_debug(1, "in png_handle_tIME"); - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Out of place tIME chunk"); - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) - { - png_warning(png_ptr, "Duplicate tIME chunk"); - png_crc_finish(png_ptr, length); - return; - } - - if (png_ptr->mode & PNG_HAVE_IDAT) - png_ptr->mode |= PNG_AFTER_IDAT; - - if (length != 7) - { - png_warning(png_ptr, "Incorrect tIME chunk length"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buf, 7); - - if (png_crc_finish(png_ptr, 0)) - return; - - mod_time.second = buf[6]; - mod_time.minute = buf[5]; - mod_time.hour = buf[4]; - mod_time.day = buf[3]; - mod_time.month = buf[2]; - mod_time.year = png_get_uint_16(buf); - - png_set_tIME(png_ptr, info_ptr, &mod_time); -} -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -/* Note: this does not properly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_textp text_ptr; - png_charp key; - png_charp text; - png_uint_32 skip = 0; - png_size_t slength; - int ret; - - png_debug(1, "in png_handle_tEXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for tEXt"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before tEXt"); - - if (png_ptr->mode & PNG_HAVE_IDAT) - png_ptr->mode |= PNG_AFTER_IDAT; - -#ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "tEXt chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "No memory to process text chunk"); - return; - } - - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - key = png_ptr->chunkdata; - - key[slength] = 0x00; - - for (text = key; *text; text++) - /* Empty loop to find end of key */ ; - - if (text != key + slength) - text++; - - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); - - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process text chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; - text_ptr->key = key; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->itxt_length = 0; - text_ptr->text = text; - text_ptr->text_length = png_strlen(text); - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, text_ptr); - - if (ret) - png_warning(png_ptr, "Insufficient memory to process text chunk"); -} -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_textp text_ptr; - png_charp text; - int comp_type; - int ret; - png_size_t slength, prefix_len, data_len; - - png_debug(1, "in png_handle_zTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for zTXt"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before zTXt"); - - if (png_ptr->mode & PNG_HAVE_IDAT) - png_ptr->mode |= PNG_AFTER_IDAT; - -#ifdef PNG_MAX_MALLOC_64K - /* We will no doubt have problems with chunks even half this size, but - * there is no hard and fast rule to tell us where to stop. - */ - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "zTXt chunk too large to fit in memory"); - png_crc_finish(png_ptr, length); - return; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "Out of memory processing zTXt chunk"); - return; - } - - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; - - for (text = png_ptr->chunkdata; *text; text++) - /* Empty loop */ ; - - /* zTXt must have some text after the chunkdataword */ - if (text >= png_ptr->chunkdata + slength - 2) - { - png_warning(png_ptr, "Truncated zTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - else - { - comp_type = *(++text); - - if (comp_type != PNG_TEXT_COMPRESSION_zTXt) - { - png_warning(png_ptr, "Unknown compression type in zTXt chunk"); - comp_type = PNG_TEXT_COMPRESSION_zTXt; - } - - text++; /* Skip the compression_method byte */ - } - - prefix_len = text - png_ptr->chunkdata; - - png_decompress_chunk(png_ptr, comp_type, - (png_size_t)length, prefix_len, &data_len); - - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); - - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process zTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = comp_type; - text_ptr->key = png_ptr->chunkdata; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->itxt_length = 0; - text_ptr->text = png_ptr->chunkdata + prefix_len; - text_ptr->text_length = data_len; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, text_ptr); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - if (ret) - png_error(png_ptr, "Insufficient memory to store zTXt chunk"); -} -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_textp text_ptr; - png_charp key, lang, text, lang_key; - int comp_flag; - int comp_type = 0; - int ret; - png_size_t slength, prefix_len, data_len; - - png_debug(1, "in png_handle_iTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for iTXt"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before iTXt"); - - if (png_ptr->mode & PNG_HAVE_IDAT) - png_ptr->mode |= PNG_AFTER_IDAT; - -#ifdef PNG_MAX_MALLOC_64K - /* We will no doubt have problems with chunks even half this size, but - * there is no hard and fast rule to tell us where to stop. - */ - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "iTXt chunk too large to fit in memory"); - png_crc_finish(png_ptr, length); - return; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "No memory to process iTXt chunk"); - return; - } - - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; - - for (lang = png_ptr->chunkdata; *lang; lang++) - /* Empty loop */ ; - - lang++; /* Skip NUL separator */ - - /* iTXt must have a language tag (possibly empty), two compression bytes, - * translated keyword (possibly empty), and possibly some text after the - * keyword - */ - - if (lang >= png_ptr->chunkdata + slength - 3) - { - png_warning(png_ptr, "Truncated iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - else - { - comp_flag = *lang++; - comp_type = *lang++; - } - - if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt)) - { - png_warning(png_ptr, "Unknown iTXt compression type or method"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - for (lang_key = lang; *lang_key; lang_key++) - /* Empty loop */ ; - - lang_key++; /* Skip NUL separator */ - - if (lang_key >= png_ptr->chunkdata + slength) - { - png_warning(png_ptr, "Truncated iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - for (text = lang_key; *text; text++) - /* Empty loop */ ; - - text++; /* Skip NUL separator */ - - if (text >= png_ptr->chunkdata + slength) - { - png_warning(png_ptr, "Malformed iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - prefix_len = text - png_ptr->chunkdata; - - key=png_ptr->chunkdata; - - if (comp_flag) - png_decompress_chunk(png_ptr, comp_type, - (size_t)length, prefix_len, &data_len); - - else - data_len = png_strlen(png_ptr->chunkdata + prefix_len); - - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); - - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = (int)comp_flag + 1; - text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); - text_ptr->lang = png_ptr->chunkdata + (lang - key); - text_ptr->itxt_length = data_len; - text_ptr->text_length = 0; - text_ptr->key = png_ptr->chunkdata; - text_ptr->text = png_ptr->chunkdata + prefix_len; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, text_ptr); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - if (ret) - png_error(png_ptr, "Insufficient memory to store iTXt chunk"); -} -#endif - -/* This function is called when we haven't found a handler for a - * chunk. If there isn't a problem with the chunk itself (ie bad - * chunk name, CRC, or a critical chunk), the chunk is silently ignored - * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which - * case it will be saved away to be written out later. - */ -void /* PRIVATE */ -png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_uint_32 skip = 0; - - png_debug(1, "in png_handle_unknown"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for unknown chunk"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (png_ptr->mode & PNG_HAVE_IDAT) - { - if (png_ptr->chunk_name != png_IDAT) - png_ptr->mode |= PNG_AFTER_IDAT; - } - - if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - { -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - && png_ptr->read_user_chunk_fn == NULL -#endif - ) -#endif - png_chunk_error(png_ptr, "unknown critical chunk"); - } - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - || (png_ptr->read_user_chunk_fn != NULL) -#endif - ) - { -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535) - { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - 65535; - length = 65535; - } -#endif - - /* TODO: this code is very close to the unknown handling in pngpread.c, - * maybe it can be put into a common utility routine? - * png_struct::unknown_chunk is just used as a temporary variable, along - * with the data into which the chunk is read. These can be eliminated. - */ - PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); - png_ptr->unknown_chunk.size = (png_size_t)length; - - if (length == 0) - png_ptr->unknown_chunk.data = NULL; - - else - { - png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); - png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); - } - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - { - /* Callback to user unknown chunk handler */ - int ret; - - ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); - - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - if (ret == 0) - { - if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - { -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) -#endif - png_chunk_error(png_ptr, "unknown critical chunk"); - } - - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - } - } - - else -#endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); - - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - - else -#endif - skip = length; - - png_crc_finish(png_ptr, skip); - -#ifndef PNG_READ_USER_CHUNKS_SUPPORTED - PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ -#endif -} - -/* This function is called to verify that a chunk name is valid. - * This function can't have the "critical chunk check" incorporated - * into it, since in the future we will need to be able to call user - * functions to handle unknown critical chunks after we check that - * the chunk name itself is valid. - */ - -/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: - * - * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - */ - -void /* PRIVATE */ -png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) -{ - int i; - - png_debug(1, "in png_check_chunk_name"); - - for (i=1; i<=4; ++i) - { - int c = chunk_name & 0xff; - - if (c < 65 || c > 122 || (c > 90 && c < 97)) - png_chunk_error(png_ptr, "invalid chunk type"); - - chunk_name >>= 8; - } -} - -/* Combines the row recently read in with the existing pixels in the row. This - * routine takes care of alpha and transparency if requested. This routine also - * handles the two methods of progressive display of interlaced images, - * depending on the 'display' value; if 'display' is true then the whole row - * (dp) is filled from the start by replicating the available pixels. If - * 'display' is false only those pixels present in the pass are filled in. - */ -void /* PRIVATE */ -png_combine_row(png_structp png_ptr, png_bytep dp, int display) -{ - unsigned int pixel_depth = png_ptr->transformed_pixel_depth; - png_const_bytep sp = png_ptr->row_buf + 1; - png_uint_32 row_width = png_ptr->width; - unsigned int pass = png_ptr->pass; - png_bytep end_ptr = 0; - png_byte end_byte = 0; - unsigned int end_mask; - - png_debug(1, "in png_combine_row"); - - /* Added in 1.5.6: it should not be possible to enter this routine until at - * least one row has been read from the PNG data and transformed. - */ - if (pixel_depth == 0) - png_error(png_ptr, "internal row logic error"); - - /* Added in 1.5.4: the pixel depth should match the information returned by - * any call to png_read_update_info at this point. Do not continue if we got - * this wrong. - */ - if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != - PNG_ROWBYTES(pixel_depth, row_width)) - png_error(png_ptr, "internal row size calculation error"); - - /* Don't expect this to ever happen: */ - if (row_width == 0) - png_error(png_ptr, "internal row width error"); - - /* Preserve the last byte in cases where only part of it will be overwritten, - * the multiply below may overflow, we don't care because ANSI-C guarantees - * we get the low bits. - */ - end_mask = (pixel_depth * row_width) & 7; - if (end_mask != 0) - { - /* end_ptr == NULL is a flag to say do nothing */ - end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; - end_byte = *end_ptr; -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */ - end_mask = 0xff << end_mask; - - else /* big-endian byte */ -# endif - end_mask = 0xff >> end_mask; - /* end_mask is now the bits to *keep* from the destination row */ - } - - /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy() - * will also happen if interlacing isn't supported or if the application - * does not call png_set_interlace_handling(). In the latter cases the - * caller just gets a sequence of the unexpanded rows from each interlace - * pass. - */ -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) && - pass < 6 && (display == 0 || - /* The following copies everything for 'display' on passes 0, 2 and 4. */ - (display == 1 && (pass & 1) != 0))) - { - /* Narrow images may have no bits in a pass; the caller should handle - * this, but this test is cheap: - */ - if (row_width <= PNG_PASS_START_COL(pass)) - return; - - if (pixel_depth < 8) - { - /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit - * into 32 bits, then a single loop over the bytes using the four byte - * values in the 32-bit mask can be used. For the 'display' option the - * expanded mask may also not require any masking within a byte. To - * make this work the PACKSWAP option must be taken into account - it - * simply requires the pixels to be reversed in each byte. - * - * The 'regular' case requires a mask for each of the first 6 passes, - * the 'display' case does a copy for the even passes in the range - * 0..6. This has already been handled in the test above. - * - * The masks are arranged as four bytes with the first byte to use in - * the lowest bits (little-endian) regardless of the order (PACKSWAP or - * not) of the pixels in each byte. - * - * NOTE: the whole of this logic depends on the caller of this function - * only calling it on rows appropriate to the pass. This function only - * understands the 'x' logic; the 'y' logic is handled by the caller. - * - * The following defines allow generation of compile time constant bit - * masks for each pixel depth and each possibility of swapped or not - * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, - * is in the range 0..7; and the result is 1 if the pixel is to be - * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' - * for the block method. - * - * With some compilers a compile time expression of the general form: - * - * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) - * - * Produces warnings with values of 'shift' in the range 33 to 63 - * because the right hand side of the ?: expression is evaluated by - * the compiler even though it isn't used. Microsoft Visual C (various - * versions) and the Intel C compiler are known to do this. To avoid - * this the following macros are used in 1.5.6. This is a temporary - * solution to avoid destabilizing the code during the release process. - */ -# if PNG_USE_COMPILE_TIME_MASKS -# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) -# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) -# else -# define PNG_LSR(x,s) ((x)>>(s)) -# define PNG_LSL(x,s) ((x)<<(s)) -# endif -# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) -# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) - - /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is - * little endian - the first pixel is at bit 0 - however the extra - * parameter 's' can be set to cause the mask position to be swapped - * within each byte, to match the PNG format. This is done by XOR of - * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. - */ -# define PIXEL_MASK(p,x,d,s) \ - (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) - - /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. - */ -# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) -# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) - - /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp - * cases the result needs replicating, for the 4-bpp case the above - * generates a full 32 bits. - */ -# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) - -# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ - S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ - S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) - -# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ - B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ - B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) - -#if PNG_USE_COMPILE_TIME_MASKS - /* Utility macros to construct all the masks for a depth/swap - * combination. The 's' parameter says whether the format is PNG - * (big endian bytes) or not. Only the three odd-numbered passes are - * required for the display/block algorithm. - */ -# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ - S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } - -# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) } - -# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) - - /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and - * then pass: - */ - static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = - { - /* Little-endian byte masks for PACKSWAP */ - { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } - }; - - /* display_mask has only three entries for the odd passes, so index by - * pass>>1. - */ - static PNG_CONST png_uint_32 display_mask[2][3][3] = - { - /* Little-endian byte masks for PACKSWAP */ - { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } - }; - -# define MASK(pass,depth,display,png)\ - ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ - row_mask[png][DEPTH_INDEX(depth)][pass]) - -#else /* !PNG_USE_COMPILE_TIME_MASKS */ - /* This is the runtime alternative: it seems unlikely that this will - * ever be either smaller or faster than the compile time approach. - */ -# define MASK(pass,depth,display,png)\ - ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) -#endif /* !PNG_USE_COMPILE_TIME_MASKS */ - - /* Use the appropriate mask to copy the required bits. In some cases - * the byte mask will be 0 or 0xff, optimize these cases. row_width is - * the number of pixels, but the code copies bytes, so it is necessary - * to special case the end. - */ - png_uint_32 pixels_per_byte = 8 / pixel_depth; - png_uint_32 mask; - -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - mask = MASK(pass, pixel_depth, display, 0); - - else -# endif - mask = MASK(pass, pixel_depth, display, 1); - - for (;;) - { - png_uint_32 m; - - /* It doesn't matter in the following if png_uint_32 has more than - * 32 bits because the high bits always match those in m<<24; it is, - * however, essential to use OR here, not +, because of this. - */ - m = mask; - mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ - m &= 0xff; - - if (m != 0) /* something to copy */ - { - if (m != 0xff) - *dp = (png_byte)((*dp & ~m) | (*sp & m)); - else - *dp = *sp; - } - - /* NOTE: this may overwrite the last byte with garbage if the image - * is not an exact number of bytes wide; libpng has always done - * this. - */ - if (row_width <= pixels_per_byte) - break; /* May need to restore part of the last byte */ - - row_width -= pixels_per_byte; - ++dp; - ++sp; - } - } - - else /* pixel_depth >= 8 */ - { - unsigned int bytes_to_copy, bytes_to_jump; - - /* Validate the depth - it must be a multiple of 8 */ - if (pixel_depth & 7) - png_error(png_ptr, "invalid user transform pixel depth"); - - pixel_depth >>= 3; /* now in bytes */ - row_width *= pixel_depth; - - /* Regardless of pass number the Adam 7 interlace always results in a - * fixed number of pixels to copy then to skip. There may be a - * different number of pixels to skip at the start though. - */ - { - unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; - - row_width -= offset; - dp += offset; - sp += offset; - } - - /* Work out the bytes to copy. */ - if (display) - { - /* When doing the 'block' algorithm the pixel in the pass gets - * replicated to adjacent pixels. This is why the even (0,2,4,6) - * passes are skipped above - the entire expanded row is copied. - */ - bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; - - /* But don't allow this number to exceed the actual row width. */ - if (bytes_to_copy > row_width) - bytes_to_copy = row_width; - } - - else /* normal row; Adam7 only ever gives us one pixel to copy. */ - bytes_to_copy = pixel_depth; - - /* In Adam7 there is a constant offset between where the pixels go. */ - bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; - - /* And simply copy these bytes. Some optimization is possible here, - * depending on the value of 'bytes_to_copy'. Special case the low - * byte counts, which we know to be frequent. - * - * Notice that these cases all 'return' rather than 'break' - this - * avoids an unnecessary test on whether to restore the last byte - * below. - */ - switch (bytes_to_copy) - { - case 1: - for (;;) - { - *dp = *sp; - - if (row_width <= bytes_to_jump) - return; - - dp += bytes_to_jump; - sp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - case 2: - /* There is a possibility of a partial copy at the end here; this - * slows the code down somewhat. - */ - do - { - dp[0] = sp[0], dp[1] = sp[1]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - while (row_width > 1); - - /* And there can only be one byte left at this point: */ - *dp = *sp; - return; - - case 3: - /* This can only be the RGB case, so each copy is exactly one - * pixel and it is not necessary to check for a partial copy. - */ - for(;;) - { - dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - default: -#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE - /* Check for double byte alignment and, if possible, use a - * 16-bit copy. Don't attempt this for narrow images - ones that - * are less than an interlace panel wide. Don't attempt it for - * wide bytes_to_copy either - use the png_memcpy there. - */ - if (bytes_to_copy < 16 /*else use png_memcpy*/ && - png_isaligned(dp, png_uint_16) && - png_isaligned(sp, png_uint_16) && - bytes_to_copy % sizeof (png_uint_16) == 0 && - bytes_to_jump % sizeof (png_uint_16) == 0) - { - /* Everything is aligned for png_uint_16 copies, but try for - * png_uint_32 first. - */ - if (png_isaligned(dp, png_uint_32) && - png_isaligned(sp, png_uint_32) && - bytes_to_copy % sizeof (png_uint_32) == 0 && - bytes_to_jump % sizeof (png_uint_32) == 0) - { - png_uint_32p dp32 = (png_uint_32p)dp; - png_const_uint_32p sp32 = (png_const_uint_32p)sp; - unsigned int skip = (bytes_to_jump-bytes_to_copy) / - sizeof (png_uint_32); - - do - { - size_t c = bytes_to_copy; - do - { - *dp32++ = *sp32++; - c -= sizeof (png_uint_32); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp32 += skip; - sp32 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* Get to here when the row_width truncates the final copy. - * There will be 1-3 bytes left to copy, so don't try the - * 16-bit loop below. - */ - dp = (png_bytep)dp32; - sp = (png_const_bytep)sp32; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - - /* Else do it in 16-bit quantities, but only if the size is - * not too large. - */ - else - { - png_uint_16p dp16 = (png_uint_16p)dp; - png_const_uint_16p sp16 = (png_const_uint_16p)sp; - unsigned int skip = (bytes_to_jump-bytes_to_copy) / - sizeof (png_uint_16); - - do - { - size_t c = bytes_to_copy; - do - { - *dp16++ = *sp16++; - c -= sizeof (png_uint_16); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp16 += skip; - sp16 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* End of row - 1 byte left, bytes_to_copy > row_width: */ - dp = (png_bytep)dp16; - sp = (png_const_bytep)sp16; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - } -#endif /* PNG_ALIGN_ code */ - - /* The true default - use a png_memcpy: */ - for (;;) - { - png_memcpy(dp, sp, bytes_to_copy); - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - if (bytes_to_copy > row_width) - bytes_to_copy = row_width; - } - } - - /* NOT REACHED*/ - } /* pixel_depth >= 8 */ - - /* Here if pixel_depth < 8 to check 'end_ptr' below. */ - } - else -#endif - - /* If here then the switch above wasn't used so just png_memcpy the whole row - * from the temporary row buffer (notice that this overwrites the end of the - * destination row if it is a partial byte.) - */ - png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); - - /* Restore the overwritten bits from the last byte if necessary. */ - if (end_ptr != NULL) - *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void /* PRIVATE */ -png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, - png_uint_32 transformations /* Because these may affect the byte layout */) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* Offset to next interlace block */ - static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_read_interlace"); - if (row != NULL && row_info != NULL) - { - png_uint_32 final_width; - - final_width = row_info->width * png_pass_inc[pass]; - - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); - png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); - int sshift, dshift; - int s_start, s_end, s_inc; - int jstop = png_pass_inc[pass]; - png_byte v; - png_uint_32 i; - int j; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) - { - sshift = (int)((row_info->width + 7) & 0x07); - dshift = (int)((final_width + 7) & 0x07); - s_start = 7; - s_end = 0; - s_inc = -1; - } - - else -#endif - { - sshift = 7 - (int)((row_info->width + 7) & 0x07); - dshift = 7 - (int)((final_width + 7) & 0x07); - s_start = 0; - s_end = 7; - s_inc = 1; - } - - for (i = 0; i < row_info->width; i++) - { - v = (png_byte)((*sp >> sshift) & 0x01); - for (j = 0; j < jstop; j++) - { - *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift += s_inc; - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift += s_inc; - } - break; - } - - case 2: - { - png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); - png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); - int sshift, dshift; - int s_start, s_end, s_inc; - int jstop = png_pass_inc[pass]; - png_uint_32 i; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) - { - sshift = (int)(((row_info->width + 3) & 0x03) << 1); - dshift = (int)(((final_width + 3) & 0x03) << 1); - s_start = 6; - s_end = 0; - s_inc = -2; - } - - else -#endif - { - sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); - dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); - s_start = 0; - s_end = 6; - s_inc = 2; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0x03); - for (j = 0; j < jstop; j++) - { - *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift += s_inc; - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift += s_inc; - } - break; - } - - case 4: - { - png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); - png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); - int sshift, dshift; - int s_start, s_end, s_inc; - png_uint_32 i; - int jstop = png_pass_inc[pass]; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) - { - sshift = (int)(((row_info->width + 1) & 0x01) << 2); - dshift = (int)(((final_width + 1) & 0x01) << 2); - s_start = 4; - s_end = 0; - s_inc = -4; - } - - else -#endif - { - sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); - dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); - s_start = 0; - s_end = 4; - s_inc = 4; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v = (png_byte)((*sp >> sshift) & 0x0f); - int j; - - for (j = 0; j < jstop; j++) - { - *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift += s_inc; - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift += s_inc; - } - break; - } - - default: - { - png_size_t pixel_bytes = (row_info->pixel_depth >> 3); - - png_bytep sp = row + (png_size_t)(row_info->width - 1) - * pixel_bytes; - - png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; - - int jstop = png_pass_inc[pass]; - png_uint_32 i; - - for (i = 0; i < row_info->width; i++) - { - png_byte v[8]; - int j; - - png_memcpy(v, sp, pixel_bytes); - - for (j = 0; j < jstop; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - - sp -= pixel_bytes; - } - break; - } - } - - row_info->width = final_width; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); - } -#ifndef PNG_READ_PACKSWAP_SUPPORTED - PNG_UNUSED(transformations) /* Silence compiler warning */ -#endif -} -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - -static void -png_read_filter_row_sub(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_size_t i; - png_size_t istop = row_info->rowbytes; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - - PNG_UNUSED(prev_row) - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_up(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_size_t i; - png_size_t istop = row_info->rowbytes; - png_bytep rp = row; - png_const_bytep pp = prev_row; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_avg(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_size_t i; - png_bytep rp = row; - png_const_bytep pp = prev_row; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_size_t istop = row_info->rowbytes - bpp; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) / 2 )) & 0xff); - - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); - - rp++; - } -} - -static void -png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp_end = row + row_info->rowbytes; - int a, c; - - /* First pixel/byte */ - c = *prev_row++; - a = *row + c; - *row++ = (png_byte)a; - - /* Remainder */ - while (row < rp_end) - { - int b, pa, pb, pc, p; - - a &= 0xff; /* From previous iteration or start */ - b = *prev_row++; - - p = b - c; - pc = a - c; - -# ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -# else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -# endif - - /* Find the best predictor, the least of pa, pb, pc favoring the earlier - * ones in the case of a tie. - */ - if (pb < pa) pa = pb, a = b; - if (pc < pa) a = c; - - /* Calculate the current pixel in a, and move the previous row pixel to c - * for the next time round the loop - */ - c = b; - a += *row; - *row++ = (png_byte)a; - } -} - -static void -png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp_end = row + bpp; - - /* Process the first pixel in the row completely (this is the same as 'up' - * because there is only one candidate predictor for the first row). - */ - while (row < rp_end) - { - int a = *row + *prev_row++; - *row++ = (png_byte)a; - } - - /* Remainder */ - rp_end += row_info->rowbytes - bpp; - - while (row < rp_end) - { - int a, b, c, pa, pb, pc, p; - - c = *(prev_row - bpp); - a = *(row - bpp); - b = *prev_row++; - - p = b - c; - pc = a - c; - -# ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -# else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -# endif - - if (pb < pa) pa = pb, a = b; - if (pc < pa) a = c; - - c = b; - a += *row; - *row++ = (png_byte)a; - } -} - -#ifdef PNG_ARM_NEON - -#ifdef __linux__ -#include -#include -#include - -static int png_have_hwcap(unsigned cap) -{ - FILE *f = fopen("/proc/self/auxv", "r"); - Elf32_auxv_t aux; - int have_cap = 0; - - if (!f) - return 0; - - while (fread(&aux, sizeof(aux), 1, f) > 0) - { - if (aux.a_type == AT_HWCAP && - aux.a_un.a_val & cap) - { - have_cap = 1; - break; - } - } - - fclose(f); - - return have_cap; -} -#endif /* __linux__ */ - -static void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) -{ -#ifdef __linux__ - if (!png_have_hwcap(HWCAP_NEON)) - return; -#endif - - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; - - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_neon; - } - - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_neon; - } -} -#endif /* PNG_ARM_NEON */ - -static void -png_init_filter_functions(png_structp pp) -{ - unsigned int bpp = (pp->pixel_depth + 7) >> 3; - - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; - if (bpp == 1) - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_1byte_pixel; - else - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_multibyte_pixel; - -#ifdef PNG_ARM_NEON - png_init_filter_functions_neon(pp, bpp); -#endif -} - -void /* PRIVATE */ -png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) -{ - if (pp->read_filter[0] == NULL) - png_init_filter_functions(pp); - if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) - pp->read_filter[filter-1](row_info, row, prev_row); -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -void /* PRIVATE */ -png_read_finish_row(png_structp png_ptr) -{ -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - - png_debug(1, "in png_read_finish_row"); - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) - { - png_ptr->row_number = 0; - - /* TO DO: don't do this if prev_row isn't needed (requires - * read-ahead of the next row's filter byte. - */ - png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if (!(png_ptr->transformations & PNG_INTERLACE)) - { - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - } - - else /* if (png_ptr->transformations & PNG_INTERLACE) */ - break; /* libpng deinterlacing sees every row */ - - } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); - - if (png_ptr->pass < 7) - return; - } -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - { - char extra; - int ret; - - png_ptr->zstream.next_out = (Byte *)&extra; - png_ptr->zstream.avail_out = (uInt)1; - - for (;;) - { - if (!(png_ptr->zstream.avail_in)) - { - while (!png_ptr->idat_size) - { - png_crc_finish(png_ptr, 0); - png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - - png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_in = png_ptr->zbuf; - - if (png_ptr->zbuf_size > png_ptr->idat_size) - png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; - - png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); - png_ptr->idat_size -= png_ptr->zstream.avail_in; - } - - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - - if (ret == Z_STREAM_END) - { - if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || - png_ptr->idat_size) - png_warning(png_ptr, "Extra compressed data"); - - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - - if (ret != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : - "Decompression Error"); - - if (!(png_ptr->zstream.avail_out)) - { - png_warning(png_ptr, "Extra compressed data"); - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - - } - png_ptr->zstream.avail_out = 0; - } - - if (png_ptr->idat_size || png_ptr->zstream.avail_in) - png_warning(png_ptr, "Extra compression data"); - - inflateReset(&png_ptr->zstream); - - png_ptr->mode |= PNG_AFTER_IDAT; -} -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ - -void /* PRIVATE */ -png_read_start_row(png_structp png_ptr) -{ -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - int max_pixel_depth; - png_size_t row_bytes; - - png_debug(1, "in png_read_start_row"); - png_ptr->zstream.avail_in = 0; -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_init_read_transformations(png_ptr); -#endif -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) - { - if (!(png_ptr->transformations & PNG_INTERLACE)) - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - else - png_ptr->num_rows = png_ptr->height; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - } - - else -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - { - png_ptr->num_rows = png_ptr->height; - png_ptr->iwidth = png_ptr->width; - } - - max_pixel_depth = png_ptr->pixel_depth; - - /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of - * calculations to calculate the final pixel depth, then - * png_do_read_transforms actually does the transforms. This means that the - * code which effectively calculates this value is actually repeated in three - * separate places. They must all match. Innocent changes to the order of - * transformations can and will break libpng in a way that causes memory - * overwrites. - * - * TODO: fix this. - */ -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) - max_pixel_depth = 8; -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (png_ptr->num_trans) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth < 8) - max_pixel_depth = 8; - - if (png_ptr->num_trans) - max_pixel_depth *= 2; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - if (png_ptr->num_trans) - { - max_pixel_depth *= 4; - max_pixel_depth /= 3; - } - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND_16) - { -# ifdef PNG_READ_EXPAND_SUPPORTED - /* In fact it is an error if it isn't supported, but checking is - * the safe way. - */ - if (png_ptr->transformations & PNG_EXPAND) - { - if (png_ptr->bit_depth < 16) - max_pixel_depth *= 2; - } - else -# endif - png_ptr->transformations &= ~PNG_EXPAND_16; - } -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if (png_ptr->transformations & (PNG_FILLER)) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth <= 8) - max_pixel_depth = 16; - - else - max_pixel_depth = 32; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (max_pixel_depth <= 32) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - } -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - { - if ( -#ifdef PNG_READ_EXPAND_SUPPORTED - (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || -#endif -#ifdef PNG_READ_FILLER_SUPPORTED - (png_ptr->transformations & (PNG_FILLER)) || -#endif - png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (max_pixel_depth <= 16) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - - else - { - if (max_pixel_depth <= 8) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 64; - - else - max_pixel_depth = 48; - } - } -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ -defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - int user_pixel_depth = png_ptr->user_transform_depth * - png_ptr->user_transform_channels; - - if (user_pixel_depth > max_pixel_depth) - max_pixel_depth = user_pixel_depth; - } -#endif - - /* This value is stored in png_struct and double checked in the row read - * code. - */ - png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; - png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ - - /* Align the width on the next larger 8 pixels. Mainly used - * for interlacing - */ - row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); - /* Calculate the maximum bytes needed, adding a byte and a pixel - * for safety's sake - */ - row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + - 1 + ((max_pixel_depth + 7) >> 3); - -#ifdef PNG_MAX_MALLOC_64K - if (row_bytes > (png_uint_32)65536L) - png_error(png_ptr, "This image requires a row greater than 64KB"); -#endif - - if (row_bytes + 48 > png_ptr->old_big_row_buf_size) - { - png_free(png_ptr, png_ptr->big_row_buf); - png_free(png_ptr, png_ptr->big_prev_row); - - if (png_ptr->interlaced) - png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, - row_bytes + 48); - - else - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - - png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - -#ifdef PNG_ALIGNED_MEMORY_SUPPORTED - /* Use 16-byte aligned memory for row_buf with at least 16 bytes - * of padding before and after row_buf; treat prev_row similarly. - * NOTE: the alignment is to the start of the pixels, one beyond the start - * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this - * was incorrect; the filter byte was aligned, which had the exact - * opposite effect of that intended. - */ - { - png_bytep temp = png_ptr->big_row_buf + 32; - int extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->row_buf = temp - extra - 1/*filter byte*/; - - temp = png_ptr->big_prev_row + 32; - extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->prev_row = temp - extra - 1/*filter byte*/; - } - -#else - /* Use 31 bytes of padding before and 17 bytes after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 31; - png_ptr->prev_row = png_ptr->big_prev_row + 31; -#endif - png_ptr->old_big_row_buf_size = row_bytes + 48; - } - -#ifdef PNG_MAX_MALLOC_64K - if (png_ptr->rowbytes > 65535) - png_error(png_ptr, "This image requires a row greater than 64KB"); - -#endif - if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) - png_error(png_ptr, "Row has too many bytes to allocate in memory"); - - png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - png_debug1(3, "width = %u,", png_ptr->width); - png_debug1(3, "height = %u,", png_ptr->height); - png_debug1(3, "iwidth = %u,", png_ptr->iwidth); - png_debug1(3, "num_rows = %u,", png_ptr->num_rows); - png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); - png_debug1(3, "irowbytes = %lu", - (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); - - png_ptr->flags |= PNG_FLAG_ROW_INIT; -} -#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngset.c b/WDL/libpng/pngset.c deleted file mode 100644 index e753ca88..00000000 --- a/WDL/libpng/pngset.c +++ /dev/null @@ -1,1284 +0,0 @@ - -/* pngset.c - storage of image information into info struct - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * The functions here are used during reads to store data from the file - * into the info struct, and during writes to store application data - * into the info struct for writing into the file. This abstracts the - * info struct and allows us to change the structure in the future. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#ifdef PNG_bKGD_SUPPORTED -void PNGAPI -png_set_bKGD(png_structp png_ptr, png_infop info_ptr, - png_const_color_16p background) -{ - png_debug1(1, "in %s storage function", "bKGD"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); - info_ptr->valid |= PNG_INFO_bKGD; -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -void PNGFAPI -png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) -{ - png_debug1(1, "in %s storage function", "cHRM fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -# ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) -# endif - { - info_ptr->x_white = white_x; - info_ptr->y_white = white_y; - info_ptr->x_red = red_x; - info_ptr->y_red = red_y; - info_ptr->x_green = green_x; - info_ptr->y_green = green_y; - info_ptr->x_blue = blue_x; - info_ptr->y_blue = blue_y; - info_ptr->valid |= PNG_INFO_cHRM; - } -} - -void PNGFAPI -png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z) -{ - png_XYZ XYZ; - png_xy xy; - - png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - XYZ.redX = int_red_X; - XYZ.redY = int_red_Y; - XYZ.redZ = int_red_Z; - XYZ.greenX = int_green_X; - XYZ.greenY = int_green_Y; - XYZ.greenZ = int_green_Z; - XYZ.blueX = int_blue_X; - XYZ.blueY = int_blue_Y; - XYZ.blueZ = int_blue_Z; - - if (png_xy_from_XYZ(&xy, XYZ)) - png_error(png_ptr, "XYZ values out of representable range"); - - png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy, - xy.greenx, xy.greeny, xy.bluex, xy.bluey); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(png_structp png_ptr, png_infop info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) -{ - png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); -} - -void PNGAPI -png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X, - double red_Y, double red_Z, double green_X, double green_Y, double green_Z, - double blue_X, double blue_Y, double blue_Z) -{ - png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Red X"), - png_fixed(png_ptr, green_Y, "cHRM Red Y"), - png_fixed(png_ptr, green_Z, "cHRM Red Z"), - png_fixed(png_ptr, blue_X, "cHRM Red X"), - png_fixed(png_ptr, blue_Y, "cHRM Red Y"), - png_fixed(png_ptr, blue_Z, "cHRM Red Z")); -} -# endif /* PNG_FLOATING_POINT_SUPPORTED */ - -#endif /* PNG_cHRM_SUPPORTED */ - -#ifdef PNG_gAMA_SUPPORTED -void PNGFAPI -png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point - file_gamma) -{ - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is assymetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truly ridiculous gammma values (and will produce - * displays that are all black or all white.) - */ - if (file_gamma < 16 || file_gamma > 625000000) - png_warning(png_ptr, "Out of range gamma value ignored"); - - else - { - info_ptr->gamma = file_gamma; - info_ptr->valid |= PNG_INFO_gAMA; - } -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) -{ - png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, - "png_set_gAMA")); -} -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED -void PNGAPI -png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) -{ - int i; - - png_debug1(1, "in %s storage function", "hIST"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->num_palette == 0 || info_ptr->num_palette - > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, - "Invalid palette size, hIST allocation skipped"); - - return; - } - - png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); - - /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in - * version 1.2.1 - */ - png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); - - if (png_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - return; - } - - for (i = 0; i < info_ptr->num_palette; i++) - png_ptr->hist[i] = hist[i]; - - info_ptr->hist = png_ptr->hist; - info_ptr->valid |= PNG_INFO_hIST; - info_ptr->free_me |= PNG_FREE_HIST; -} -#endif - -void PNGAPI -png_set_IHDR(png_structp png_ptr, png_infop info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - png_debug1(1, "in %s storage function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->width = width; - info_ptr->height = height; - info_ptr->bit_depth = (png_byte)bit_depth; - info_ptr->color_type = (png_byte)color_type; - info_ptr->compression_type = (png_byte)compression_type; - info_ptr->filter_type = (png_byte)filter_type; - info_ptr->interlace_type = (png_byte)interlace_type; - - png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) - info_ptr->channels++; - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - - /* Check for potential overflow */ - if (width > - (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ - - 48 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ - info_ptr->rowbytes = 0; - else - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); -} - -#ifdef PNG_oFFs_SUPPORTED -void PNGAPI -png_set_oFFs(png_structp png_ptr, png_infop info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "oFFs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_offset = offset_x; - info_ptr->y_offset = offset_y; - info_ptr->offset_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_oFFs; -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -void PNGAPI -png_set_pCAL(png_structp png_ptr, png_infop info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params) -{ - png_size_t length; - int i; - - png_debug1(1, "in %s storage function", "pCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - length = png_strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); - - /* TODO: validate format of calibration name and unit name */ - - /* Check that the type matches the specification. */ - if (type < 0 || type > 3) - png_error(png_ptr, "Invalid pCAL equation type"); - - /* Validate params[nparams] */ - for (i=0; ipcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_purpose == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL purpose"); - return; - } - - png_memcpy(info_ptr->pcal_purpose, purpose, length); - - png_debug(3, "storing X0, X1, type, and nparams in info"); - info_ptr->pcal_X0 = X0; - info_ptr->pcal_X1 = X1; - info_ptr->pcal_type = (png_byte)type; - info_ptr->pcal_nparams = (png_byte)nparams; - - length = png_strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); - - info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_units == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL units"); - return; - } - - png_memcpy(info_ptr->pcal_units, units, length); - - info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * png_sizeof(png_charp))); - - if (info_ptr->pcal_params == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL params"); - return; - } - - png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); - - for (i = 0; i < nparams; i++) - { - length = png_strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); - - info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_params[i] == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL parameter"); - return; - } - - png_memcpy(info_ptr->pcal_params[i], params[i], length); - } - - info_ptr->valid |= PNG_INFO_pCAL; - info_ptr->free_me |= PNG_FREE_PCAL; -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -void PNGAPI -png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight) -{ - png_size_t lengthw = 0, lengthh = 0; - - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Double check the unit (should never get here with an invalid - * unit unless this is an API call.) - */ - if (unit != 1 && unit != 2) - png_error(png_ptr, "Invalid sCAL unit"); - - if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || - swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) - png_error(png_ptr, "Invalid sCAL width"); - - if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || - sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) - png_error(png_ptr, "Invalid sCAL height"); - - info_ptr->scal_unit = (png_byte)unit; - - ++lengthw; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - - info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); - - if (info_ptr->scal_s_width == NULL) - { - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - return; - } - - png_memcpy(info_ptr->scal_s_width, swidth, lengthw); - - ++lengthh; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - - info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); - - if (info_ptr->scal_s_height == NULL) - { - png_free (png_ptr, info_ptr->scal_s_width); - info_ptr->scal_s_width = NULL; - - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - return; - } - - png_memcpy(info_ptr->scal_s_height, sheight, lengthh); - - info_ptr->valid |= PNG_INFO_sCAL; - info_ptr->free_me |= PNG_FREE_SCAL; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, - double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, - PNG_sCAL_PRECISION); - png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, - PNG_sCAL_PRECISION); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, - png_fixed_point width, png_fixed_point height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); - png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif -#endif - -#ifdef PNG_pHYs_SUPPORTED -void PNGAPI -png_set_pHYs(png_structp png_ptr, png_infop info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "pHYs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_pixels_per_unit = res_x; - info_ptr->y_pixels_per_unit = res_y; - info_ptr->phys_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_pHYs; -} -#endif - -void PNGAPI -png_set_PLTE(png_structp png_ptr, png_infop info_ptr, - png_const_colorp palette, int num_palette) -{ - - png_debug1(1, "in %s storage function", "PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Invalid palette length"); - - else - { - png_warning(png_ptr, "Invalid palette length"); - return; - } - } - - /* It may not actually be necessary to set png_ptr->palette here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - */ - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - - /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead - * of num_palette entries, in case of an invalid PNG file that has - * too-large sample values. - */ - png_ptr->palette = (png_colorp)png_calloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); - - png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); - info_ptr->palette = png_ptr->palette; - info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; - - info_ptr->free_me |= PNG_FREE_PLTE; - - info_ptr->valid |= PNG_INFO_PLTE; -} - -#ifdef PNG_sBIT_SUPPORTED -void PNGAPI -png_set_sBIT(png_structp png_ptr, png_infop info_ptr, - png_const_color_8p sig_bit) -{ - png_debug1(1, "in %s storage function", "sBIT"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); - info_ptr->valid |= PNG_INFO_sBIT; -} -#endif - -#ifdef PNG_sRGB_SUPPORTED -void PNGAPI -png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->srgb_intent = (png_byte)srgb_intent; - info_ptr->valid |= PNG_INFO_sRGB; -} - -void PNGAPI -png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, - int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_set_sRGB(png_ptr, info_ptr, srgb_intent); - -# ifdef PNG_gAMA_SUPPORTED - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); -# endif - -# ifdef PNG_cHRM_SUPPORTED - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 - ); -# endif /* cHRM */ -} -#endif /* sRGB */ - - -#ifdef PNG_iCCP_SUPPORTED -void PNGAPI -png_set_iCCP(png_structp png_ptr, png_infop info_ptr, - png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen) -{ - png_charp new_iccp_name; - png_bytep new_iccp_profile; - png_size_t length; - - png_debug1(1, "in %s storage function", "iCCP"); - - if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) - return; - - length = png_strlen(name)+1; - new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); - - if (new_iccp_name == NULL) - { - png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); - return; - } - - png_memcpy(new_iccp_name, name, length); - new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); - - if (new_iccp_profile == NULL) - { - png_free (png_ptr, new_iccp_name); - png_warning(png_ptr, - "Insufficient memory to process iCCP profile"); - return; - } - - png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); - - info_ptr->iccp_proflen = proflen; - info_ptr->iccp_name = new_iccp_name; - info_ptr->iccp_profile = new_iccp_profile; - /* Compression is always zero but is here so the API and info structure - * does not have to change if we introduce multiple compression types - */ - info_ptr->iccp_compression = (png_byte)compression_type; - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -void PNGAPI -png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, - int num_text) -{ - int ret; - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - - if (ret) - png_error(png_ptr, "Insufficient memory to store text"); -} - -int /* PRIVATE */ -png_set_text_2(png_structp png_ptr, png_infop info_ptr, - png_const_textp text_ptr, int num_text) -{ - int i; - - png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : - (unsigned long)png_ptr->chunk_name); - - if (png_ptr == NULL || info_ptr == NULL || num_text == 0) - return(0); - - /* Make sure we have enough space in the "text" array in info_struct - * to hold all of the incoming text_ptr objects. - */ - if (info_ptr->num_text + num_text > info_ptr->max_text) - { - if (info_ptr->text != NULL) - { - png_textp old_text; - int old_max; - - old_max = info_ptr->max_text; - info_ptr->max_text = info_ptr->num_text + num_text + 8; - old_text = info_ptr->text; - info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); - - if (info_ptr->text == NULL) - { - png_free(png_ptr, old_text); - return(1); - } - - png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * - png_sizeof(png_text))); - png_free(png_ptr, old_text); - } - - else - { - info_ptr->max_text = num_text + 8; - info_ptr->num_text = 0; - info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); - if (info_ptr->text == NULL) - return(1); - info_ptr->free_me |= PNG_FREE_TEXT; - } - - png_debug1(3, "allocated %d entries for info_ptr->text", - info_ptr->max_text); - } - for (i = 0; i < num_text; i++) - { - png_size_t text_length, key_len; - png_size_t lang_len, lang_key_len; - png_textp textp = &(info_ptr->text[info_ptr->num_text]); - - if (text_ptr[i].key == NULL) - continue; - - if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || - text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) - { - png_warning(png_ptr, "text compression mode is out of range"); - continue; - } - - key_len = png_strlen(text_ptr[i].key); - - if (text_ptr[i].compression <= 0) - { - lang_len = 0; - lang_key_len = 0; - } - - else -# ifdef PNG_iTXt_SUPPORTED - { - /* Set iTXt data */ - - if (text_ptr[i].lang != NULL) - lang_len = png_strlen(text_ptr[i].lang); - - else - lang_len = 0; - - if (text_ptr[i].lang_key != NULL) - lang_key_len = png_strlen(text_ptr[i].lang_key); - - else - lang_key_len = 0; - } -# else /* PNG_iTXt_SUPPORTED */ - { - png_warning(png_ptr, "iTXt chunk not supported"); - continue; - } -# endif - - if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') - { - text_length = 0; -# ifdef PNG_iTXt_SUPPORTED - if (text_ptr[i].compression > 0) - textp->compression = PNG_ITXT_COMPRESSION_NONE; - - else -# endif - textp->compression = PNG_TEXT_COMPRESSION_NONE; - } - - else - { - text_length = png_strlen(text_ptr[i].text); - textp->compression = text_ptr[i].compression; - } - - textp->key = (png_charp)png_malloc_warn(png_ptr, - (png_size_t) - (key_len + text_length + lang_len + lang_key_len + 4)); - - if (textp->key == NULL) - return(1); - - png_debug2(2, "Allocated %lu bytes at %p in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - textp->key); - - png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); - *(textp->key + key_len) = '\0'; - - if (text_ptr[i].compression > 0) - { - textp->lang = textp->key + key_len + 1; - png_memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang + lang_len) = '\0'; - textp->lang_key = textp->lang + lang_len + 1; - png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key + lang_key_len) = '\0'; - textp->text = textp->lang_key + lang_key_len + 1; - } - - else - { - textp->lang=NULL; - textp->lang_key=NULL; - textp->text = textp->key + key_len + 1; - } - - if (text_length) - png_memcpy(textp->text, text_ptr[i].text, - (png_size_t)(text_length)); - - *(textp->text + text_length) = '\0'; - -# ifdef PNG_iTXt_SUPPORTED - if (textp->compression > 0) - { - textp->text_length = 0; - textp->itxt_length = text_length; - } - - else -# endif - { - textp->text_length = text_length; - textp->itxt_length = 0; - } - - info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d", info_ptr->num_text); - } - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -void PNGAPI -png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) -{ - png_debug1(1, "in %s storage function", "tIME"); - - if (png_ptr == NULL || info_ptr == NULL || - (png_ptr->mode & PNG_WROTE_tIME)) - return; - - if (mod_time->month == 0 || mod_time->month > 12 || - mod_time->day == 0 || mod_time->day > 31 || - mod_time->hour > 23 || mod_time->minute > 59 || - mod_time->second > 60) - { - png_warning(png_ptr, "Ignoring invalid time value"); - return; - } - - png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); - info_ptr->valid |= PNG_INFO_tIME; -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -void PNGAPI -png_set_tRNS(png_structp png_ptr, png_infop info_ptr, - png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) -{ - png_debug1(1, "in %s storage function", "tRNS"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (trans_alpha != NULL) - { - /* It may not actually be necessary to set png_ptr->trans_alpha here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = - (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); - - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) - png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); - } - - if (trans_color != NULL) - { - int sample_max = (1 << info_ptr->bit_depth); - - if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && - (int)trans_color->gray > sample_max) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max))) - png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); - - png_memcpy(&(info_ptr->trans_color), trans_color, - png_sizeof(png_color_16)); - - if (num_trans == 0) - num_trans = 1; - } - - info_ptr->num_trans = (png_uint_16)num_trans; - - if (num_trans != 0) - { - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->free_me |= PNG_FREE_TRNS; - } -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -void PNGAPI -png_set_sPLT(png_structp png_ptr, - png_infop info_ptr, png_const_sPLT_tp entries, int nentries) -/* - * entries - array of png_sPLT_t structures - * to be added to the list of palettes - * in the info structure. - * - * nentries - number of palette structures to be - * added. - */ -{ - png_sPLT_tp np; - int i; - - if (png_ptr == NULL || info_ptr == NULL) - return; - - np = (png_sPLT_tp)png_malloc_warn(png_ptr, - (info_ptr->splt_palettes_num + nentries) * - (png_size_t)png_sizeof(png_sPLT_t)); - - if (np == NULL) - { - png_warning(png_ptr, "No memory for sPLT palettes"); - return; - } - - png_memcpy(np, info_ptr->splt_palettes, - info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes=NULL; - - for (i = 0; i < nentries; i++) - { - png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; - png_const_sPLT_tp from = entries + i; - png_size_t length; - - length = png_strlen(from->name) + 1; - to->name = (png_charp)png_malloc_warn(png_ptr, length); - - if (to->name == NULL) - { - png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); - continue; - } - - png_memcpy(to->name, from->name, length); - to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, - from->nentries * png_sizeof(png_sPLT_entry)); - - if (to->entries == NULL) - { - png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); - png_free(png_ptr, to->name); - to->name = NULL; - continue; - } - - png_memcpy(to->entries, from->entries, - from->nentries * png_sizeof(png_sPLT_entry)); - - to->nentries = from->nentries; - to->depth = from->depth; - } - - info_ptr->splt_palettes = np; - info_ptr->splt_palettes_num += nentries; - info_ptr->valid |= PNG_INFO_sPLT; - info_ptr->free_me |= PNG_FREE_SPLT; -} -#endif /* PNG_sPLT_SUPPORTED */ - -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -void PNGAPI -png_set_unknown_chunks(png_structp png_ptr, - png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) -{ - png_unknown_chunkp np; - int i; - - if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) - return; - - np = (png_unknown_chunkp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * - png_sizeof(png_unknown_chunk)); - - if (np == NULL) - { - png_warning(png_ptr, - "Out of memory while processing unknown chunk"); - return; - } - - png_memcpy(np, info_ptr->unknown_chunks, - (png_size_t)info_ptr->unknown_chunks_num * - png_sizeof(png_unknown_chunk)); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; - - for (i = 0; i < num_unknowns; i++) - { - png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; - png_const_unknown_chunkp from = unknowns + i; - - png_memcpy(to->name, from->name, png_sizeof(from->name)); - to->name[png_sizeof(to->name)-1] = '\0'; - to->size = from->size; - - /* Note our location in the read or write sequence */ - to->location = (png_byte)(png_ptr->mode & 0xff); - - if (from->size == 0) - to->data=NULL; - - else - { - to->data = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)from->size); - - if (to->data == NULL) - { - png_warning(png_ptr, - "Out of memory while processing unknown chunk"); - to->size = 0; - } - - else - png_memcpy(to->data, from->data, from->size); - } - } - - info_ptr->unknown_chunks = np; - info_ptr->unknown_chunks_num += num_unknowns; - info_ptr->free_me |= PNG_FREE_UNKN; -} - -void PNGAPI -png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, - int chunk, int location) -{ - if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < - info_ptr->unknown_chunks_num) - info_ptr->unknown_chunks[chunk].location = (png_byte)location; -} -#endif - - -#ifdef PNG_MNG_FEATURES_SUPPORTED -png_uint_32 PNGAPI -png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) -{ - png_debug(1, "in png_permit_mng_features"); - - if (png_ptr == NULL) - return (png_uint_32)0; - - png_ptr->mng_features_permitted = - (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); - - return (png_uint_32)png_ptr->mng_features_permitted; -} -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -void PNGAPI -png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep - chunk_list, int num_chunks) -{ - png_bytep new_list, p; - int i, old_num_chunks; - if (png_ptr == NULL) - return; - - if (num_chunks == 0) - { - if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) - png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; - - else - png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS) - png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; - - else - png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; - - return; - } - - if (chunk_list == NULL) - return; - - old_num_chunks = png_ptr->num_chunk_list; - new_list=(png_bytep)png_malloc(png_ptr, - (png_size_t)(5*(num_chunks + old_num_chunks))); - - if (png_ptr->chunk_list != NULL) - { - png_memcpy(new_list, png_ptr->chunk_list, - (png_size_t)(5*old_num_chunks)); - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list=NULL; - } - - png_memcpy(new_list + 5*old_num_chunks, chunk_list, - (png_size_t)(5*num_chunks)); - - for (p = new_list + 5*old_num_chunks + 4, i = 0; inum_chunk_list = old_num_chunks + num_chunks; - png_ptr->chunk_list = new_list; - png_ptr->free_me |= PNG_FREE_LIST; -} -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -void PNGAPI -png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) -{ - png_debug(1, "in png_set_read_user_chunk_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->read_user_chunk_fn = read_user_chunk_fn; - png_ptr->user_chunk_ptr = user_chunk_ptr; -} -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) -{ - png_debug1(1, "in %s storage function", "rows"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - - info_ptr->row_pointers = row_pointers; - - if (row_pointers) - info_ptr->valid |= PNG_INFO_IDAT; -} -#endif - -void PNGAPI -png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) -{ - if (png_ptr == NULL) - return; - - png_free(png_ptr, png_ptr->zbuf); - - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); - png_ptr->zbuf_size = ZLIB_IO_MAX; - size = ZLIB_IO_MAX; /* must fit */ - } - - else - png_ptr->zbuf_size = (uInt)size; - - png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); - - /* The following ensures a relatively safe failure if this gets called while - * the buffer is actually in use. - */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = 0; - png_ptr->zstream.avail_in = 0; -} - -void PNGAPI -png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) -{ - if (png_ptr && info_ptr) - info_ptr->valid &= ~mask; -} - - - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* This function was added to libpng 1.2.6 */ -void PNGAPI -png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, - png_uint_32 user_height_max) -{ - /* Images with dimensions larger than these limits will be - * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7ffffffL. - */ - if (png_ptr == NULL) - return; - - png_ptr->user_width_max = user_width_max; - png_ptr->user_height_max = user_height_max; -} - -/* This function was added to libpng 1.4.0 */ -void PNGAPI -png_set_chunk_cache_max (png_structp png_ptr, - png_uint_32 user_chunk_cache_max) -{ - if (png_ptr) - png_ptr->user_chunk_cache_max = user_chunk_cache_max; -} - -/* This function was added to libpng 1.4.1 */ -void PNGAPI -png_set_chunk_malloc_max (png_structp png_ptr, - png_alloc_size_t user_chunk_malloc_max) -{ - if (png_ptr) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; -} -#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ - - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_set_benign_errors(png_structp png_ptr, int allowed) -{ - png_debug(1, "in png_set_benign_errors"); - - if (allowed) - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; - - else - png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; -} -#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngstruct.h b/WDL/libpng/pngstruct.h deleted file mode 100644 index bea7afe4..00000000 --- a/WDL/libpng/pngstruct.h +++ /dev/null @@ -1,360 +0,0 @@ - -/* pngstruct.h - header file for PNG reference library - * - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * Last changed in libpng 1.5.5 [September 22, 2011] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application. - */ - -#ifndef PNGSTRUCT_H -#define PNGSTRUCT_H -/* zlib.h defines the structure z_stream, an instance of which is included - * in this structure and is required for decompressing the LZ compressed - * data in PNG files. - */ -#include "../zlib/zlib.h" - -struct png_struct_def -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf longjmp_buffer; /* used in png_error */ - png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ -#endif - png_error_ptr error_fn; /* function for printing errors and aborting */ -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; /* function for printing warnings */ -#endif - png_voidp error_ptr; /* user supplied struct for error functions */ - png_rw_ptr write_data_fn; /* function for writing output data */ - png_rw_ptr read_data_fn; /* function for reading input data */ - png_voidp io_ptr; /* ptr to application struct for I/O functions */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr read_user_transform_fn; /* user read transform */ -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr write_user_transform_fn; /* user write transform */ -#endif - -/* These were added in libpng-1.0.2 */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - png_voidp user_transform_ptr; /* user supplied struct for user transform */ - png_byte user_transform_depth; /* bit depth of user transformed pixels */ - png_byte user_transform_channels; /* channels in user transformed pixels */ -#endif -#endif - - png_uint_32 mode; /* tells us where we are in the PNG file */ - png_uint_32 flags; /* flags indicating various things to libpng */ - png_uint_32 transformations; /* which transformations to perform */ - - z_stream zstream; /* pointer to decompression structure (below) */ - png_bytep zbuf; /* buffer for zlib */ - uInt zbuf_size; /* size of zbuf (typically 65536) */ -#ifdef PNG_WRITE_SUPPORTED - -/* Added in 1.5.4: state to keep track of whether the zstream has been - * initialized and if so whether it is for IDAT or some other chunk. - */ -#define PNG_ZLIB_UNINITIALIZED 0 -#define PNG_ZLIB_FOR_IDAT 1 -#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ -#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ -#define PNG_ZLIB_IN_USE 4 /* a flag value */ - - png_uint_32 zlib_state; /* State of zlib initialization */ -/* End of material added at libpng 1.5.4 */ - - int zlib_level; /* holds zlib compression level */ - int zlib_method; /* holds zlib compression method */ - int zlib_window_bits; /* holds zlib compression window bits */ - int zlib_mem_level; /* holds zlib compression memory level */ - int zlib_strategy; /* holds zlib compression strategy */ -#endif -/* Added at libpng 1.5.4 */ -#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ - defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) - int zlib_text_level; /* holds zlib compression level */ - int zlib_text_method; /* holds zlib compression method */ - int zlib_text_window_bits; /* holds zlib compression window bits */ - int zlib_text_mem_level; /* holds zlib compression memory level */ - int zlib_text_strategy; /* holds zlib compression strategy */ -#endif -/* End of material added at libpng 1.5.4 */ - - png_uint_32 width; /* width of image in pixels */ - png_uint_32 height; /* height of image in pixels */ - png_uint_32 num_rows; /* number of rows in current pass */ - png_uint_32 usr_width; /* width of row at start of write */ - png_size_t rowbytes; /* size of row in bytes */ - png_uint_32 iwidth; /* width of current interlaced row in pixels */ - png_uint_32 row_number; /* current row in interlace pass */ - png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ - png_bytep prev_row; /* buffer to save previous (unfiltered) row. - * This is a pointer into big_prev_row - */ - png_bytep row_buf; /* buffer to save current (unfiltered) row. - * This is a pointer into big_row_buf - */ - png_bytep sub_row; /* buffer to save "sub" row when filtering */ - png_bytep up_row; /* buffer to save "up" row when filtering */ - png_bytep avg_row; /* buffer to save "avg" row when filtering */ - png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ - png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ - - png_uint_32 idat_size; /* current IDAT size for read */ - png_uint_32 crc; /* current chunk CRC value */ - png_colorp palette; /* palette from the input file */ - png_uint_16 num_palette; /* number of color entries in palette */ - png_uint_16 num_trans; /* number of transparency values */ - png_byte compression; /* file compression type (always 0) */ - png_byte filter; /* file filter type (always 0) */ - png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - png_byte pass; /* current interlace pass (0 - 6) */ - png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ - png_byte color_type; /* color type of file */ - png_byte bit_depth; /* bit depth of file */ - png_byte usr_bit_depth; /* bit depth of users row: write only */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte channels; /* number of channels in file */ - png_byte usr_channels; /* channels at start of write: write only */ - png_byte sig_bytes; /* magic bytes read/written from start of file */ - png_byte maximum_pixel_depth; - /* pixel depth used for the row buffers */ - png_byte transformed_pixel_depth; - /* pixel depth after read/write transforms */ - png_byte io_chunk_string[5]; - /* string name of chunk */ - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler; /* filler bytes for pixel expansion */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - png_byte background_gamma_type; - png_fixed_point background_gamma; - png_color_16 background; /* background color in screen gamma space */ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1; /* background normalized to gamma 1.0 */ -#endif -#endif /* PNG_bKGD_SUPPORTED */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ - png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point gamma; /* file gamma value */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ - - png_bytep gamma_table; /* gamma table for 8-bit depth files */ - png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_bytep gamma_from_1; /* converts from 1.0 to screen */ - png_bytep gamma_to_1; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits in each available channel */ -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift; /* shift for significant bit tranformation */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ - || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep trans_alpha; /* alpha values for paletted files */ - png_color_16 trans_color; /* transparent color for non-paletted files */ -#endif - - png_read_status_ptr read_row_fn; /* called after each row is decoded */ - png_write_status_ptr write_row_fn; /* called after each row is encoded */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_info_ptr info_fn; /* called after header data fully read */ - png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ - png_progressive_end_ptr end_fn; /* called after image is complete */ - png_bytep save_buffer_ptr; /* current location in save_buffer */ - png_bytep save_buffer; /* buffer for previously read data */ - png_bytep current_buffer_ptr; /* current location in current_buffer */ - png_bytep current_buffer; /* buffer for recently used data */ - png_uint_32 push_length; /* size of current input chunk */ - png_uint_32 skip_length; /* bytes to skip in input data */ - png_size_t save_buffer_size; /* amount of data now in save_buffer */ - png_size_t save_buffer_max; /* total size of save_buffer */ - png_size_t buffer_size; /* total amount of available input data */ - png_size_t current_buffer_size; /* amount of data now in current_buffer */ - int process_mode; /* what push library is currently doing */ - int cur_palette; /* current push library palette index */ - -# ifdef PNG_TEXT_SUPPORTED - png_size_t current_text_size; /* current size of text input data */ - png_size_t current_text_left; /* how much text left to read in input */ - png_charp current_text; /* current text chunk buffer */ - png_charp current_text_ptr; /* current location in current_text */ -# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ - -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - -#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) -/* For the Borland special 64K segment handler */ - png_bytepp offset_table_ptr; - png_bytep offset_table; - png_uint_16 offset_table_number; - png_uint_16 offset_table_count; - png_uint_16 offset_table_count_free; -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_bytep palette_lookup; /* lookup table for quantizing */ - png_bytep quantize_index; /* index translation for palette files */ -#endif - -#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) - png_uint_16p hist; /* histogram */ -#endif - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_byte heuristic_method; /* heuristic for row filter selection */ - png_byte num_prev_filters; /* number of weights for previous rows */ - png_bytep prev_filters; /* filter type(s) of previous row(s) */ - png_uint_16p filter_weights; /* weight(s) for previous line(s) */ - png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ - png_uint_16p filter_costs; /* relative filter calculation cost */ - png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED - char time_buffer[29]; /* String to hold RFC 1123 time text */ -#endif - -/* New members added in libpng-1.0.6 */ - - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp user_chunk_ptr; - png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int num_chunk_list; - png_bytep chunk_list; -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - /* Added in 1.5.5 to record an sRGB chunk in the png. */ - png_byte is_sRGB; -#endif - -/* New members added in libpng-1.0.3 */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status; - /* Added in libpng 1.5.5 to record setting of coefficients: */ - png_byte rgb_to_gray_coefficients_set; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff; - png_uint_16 rgb_to_gray_green_coeff; - /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ -#endif - -/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ - defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ - defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) -/* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted; -#endif - -/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_byte filter_type; -#endif - -/* New members added in libpng-1.2.0 */ - -/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ -#ifdef PNG_USER_MEM_SUPPORTED - png_voidp mem_ptr; /* user supplied struct for mem functions */ - png_malloc_ptr malloc_fn; /* function for allocating memory */ - png_free_ptr free_fn; /* function for freeing memory */ -#endif - -/* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort; /* working sort array */ - png_bytep index_to_palette; /* where the original index currently is - in the palette */ - png_bytep palette_to_index; /* which original index points to this - palette color */ -#endif - -/* New members added in libpng-1.0.16 and 1.2.6 */ - png_byte compression_type; - -#ifdef PNG_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max; - png_uint_32 user_height_max; - - /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown - * chunks that can be stored (0 means unlimited). - */ - png_uint_32 user_chunk_cache_max; - - /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. - */ - png_alloc_size_t user_chunk_malloc_max; -#endif - -/* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunk that the library doesn't recognize. */ - png_unknown_chunk unknown_chunk; -#endif - -/* New member added in libpng-1.2.26 */ - png_size_t old_big_row_buf_size; - -/* New member added in libpng-1.2.30 */ - png_charp chunkdata; /* buffer for reading chunk data */ - -#ifdef PNG_IO_STATE_SUPPORTED -/* New member added in libpng-1.4.0 */ - png_uint_32 io_state; -#endif - -/* New member added in libpng-1.5.6 */ - png_bytep big_prev_row; - - void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row); -}; -#endif /* PNGSTRUCT_H */ diff --git a/WDL/libpng/pngtest.c b/WDL/libpng/pngtest.c deleted file mode 100644 index 0b29c60f..00000000 --- a/WDL/libpng/pngtest.c +++ /dev/null @@ -1,1820 +0,0 @@ - -/* pngtest.c - a simple test program to test libpng - * - * Last changed in libpng 1.5.6 [November 3, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This program reads in a PNG image, writes it out again, and then - * compares the two files. If the files are identical, this shows that - * the basic chunk handling, filtering, and (de)compression code is working - * properly. It does not currently test all of the transforms, although - * it probably should. - * - * The program will report "FAIL" in certain legitimate cases: - * 1) when the compression level or filter selection method is changed. - * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. - * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks - * exist in the input file. - * 4) others not listed here... - * In these cases, it is best to check with another tool such as "pngcheck" - * to see what the differences between the two files are. - * - * If a filename is given on the command-line, then this file is used - * for the input, rather than the default "pngtest.png". This allows - * testing a wide variety of files easily. You can also test a number - * of files at once by typing "pngtest -m file1.png file2.png ..." - */ - -#define _POSIX_SOURCE 1 - -#include "zlib.h" -#include "png.h" -/* Copied from pngpriv.h but only used in error messages below. */ -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 -#endif -# include -# include -# include -# define FCLOSE(file) fclose(file) - -#ifndef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -/* Makes pngtest verbose so we can find problems. */ -#ifndef PNG_DEBUG -# define PNG_DEBUG 0 -#endif - -#if PNG_DEBUG > 1 -# define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) -# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1)) -# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2)) -#else -# define pngtest_debug(m) ((void)0) -# define pngtest_debug1(m,p1) ((void)0) -# define pngtest_debug2(m,p1,p2) ((void)0) -#endif - -#if !PNG_DEBUG -# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ -#endif - -/* The code uses memcmp and memcpy on large objects (typically row pointers) so - * it is necessary to do soemthing special on certain architectures, note that - * the actual support for this was effectively removed in 1.4, so only the - * memory remains in this program: - */ -#define CVT_PTR(ptr) (ptr) -#define CVT_PTR_NOCHECK(ptr) (ptr) -#define png_memcmp memcmp -#define png_memcpy memcpy -#define png_memset memset - -/* Turn on CPU timing -#define PNGTEST_TIMING -*/ - -#ifndef PNG_FLOATING_POINT_SUPPORTED -#undef PNGTEST_TIMING -#endif - -#ifdef PNGTEST_TIMING -static float t_start, t_stop, t_decode, t_encode, t_misc; -#include -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED -#define PNG_tIME_STRING_LENGTH 29 -static int tIME_chunk_present = 0; -static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; -#endif - -static int verbose = 0; -static int strict = 0; - -int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); - -#ifdef __TURBOC__ -#include -#endif - -/* Defined so I can write to a file on gui/windowing platforms */ -/* #define STDERR stderr */ -#define STDERR stdout /* For DOS */ - -/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ -#ifndef png_jmpbuf -# define png_jmpbuf(png_ptr) png_ptr->jmpbuf -#endif - -/* Example of using row callbacks to make a simple progress meter */ -static int status_pass = 1; -static int status_dots_requested = 0; -static int status_dots = 1; - -void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); -void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) - return; - - if (status_pass != pass) - { - fprintf(stdout, "\n Pass %d: ", pass); - status_pass = pass; - status_dots = 31; - } - - status_dots--; - - if (status_dots == 0) - { - fprintf(stdout, "\n "); - status_dots=30; - } - - fprintf(stdout, "r"); -} - -void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); -void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) - return; - - fprintf(stdout, "w"); -} - - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely examine the row filters. We set this to 256 rather than - * 5 in case illegal filter values are present.) - */ -static png_uint_32 filters_used[256]; -void PNGCBAPI -count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); -void PNGCBAPI -count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - if (png_ptr != NULL && row_info != NULL) - ++filters_used[*(data - 1)]; -} -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely count the zero samples) - */ - -static png_uint_32 zero_samples; - -void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); -void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - png_bytep dp = data; - if (png_ptr == NULL) - return; - - /* Contents of row_info: - * png_uint_32 width width of row - * png_uint_32 rowbytes number of bytes in row - * png_byte color_type color type of pixels - * png_byte bit_depth bit depth of samples - * png_byte channels number of channels (1-4) - * png_byte pixel_depth bits per pixel (depth*channels) - */ - - /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - - if (row_info->color_type == 0 || row_info->color_type == 3) - { - int pos = 0; - png_uint_32 n, nstop; - - for (n = 0, nstop=row_info->width; nbit_depth == 1) - { - if (((*dp << pos++ ) & 0x80) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 2) - { - if (((*dp << (pos+=2)) & 0xc0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 4) - { - if (((*dp << (pos+=4)) & 0xf0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - dp+=2; - } - } - } - else /* Other color types */ - { - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; - if (row_info->color_type > 3)color_channels--; - - for (n = 0, nstop=row_info->width; nbit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - - dp+=2; - } - } - if (row_info->color_type > 3) - { - dp++; - if (row_info->bit_depth == 16) - dp++; - } - } - } -} -#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ - -static int wrote_question = 0; - -#ifndef PNG_STDIO_SUPPORTED -/* START of code to validate stdio-free compilation */ -/* These copies of the default read/write functions come from pngrio.c and - * pngwio.c. They allow "don't include stdio" testing of the library. - * This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ - -#ifdef PNG_IO_STATE_SUPPORTED -void -pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op); -void -pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op) -{ - png_uint_32 io_state = png_get_io_state(png_ptr); - int err = 0; - - /* Check if the current operation (reading / writing) is as expected. */ - if ((io_state & PNG_IO_MASK_OP) != io_op) - png_error(png_ptr, "Incorrect operation in I/O state"); - - /* Check if the buffer size specific to the current location - * (file signature / header / data / crc) is as expected. - */ - switch (io_state & PNG_IO_MASK_LOC) - { - case PNG_IO_SIGNATURE: - if (data_length > 8) - err = 1; - break; - case PNG_IO_CHUNK_HDR: - if (data_length != 8) - err = 1; - break; - case PNG_IO_CHUNK_DATA: - break; /* no restrictions here */ - case PNG_IO_CHUNK_CRC: - if (data_length != 4) - err = 1; - break; - default: - err = 1; /* uninitialized */ - } - if (err) - png_error(png_ptr, "Bad I/O state or buffer size"); -} -#endif - -#ifndef USE_FAR_KEYWORD -static void PNGCBAPI -pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check = 0; - png_voidp io_ptr; - - /* fread() returns 0 on error, so it is OK to store this in a png_size_t - * instead of an int, which is what fread() actually returns. - */ - io_ptr = png_get_io_ptr(png_ptr); - if (io_ptr != NULL) - { - check = fread(data, 1, length, (png_FILE_p)io_ptr); - } - - if (check != length) - { - png_error(png_ptr, "Read Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); -#endif -} -#else -/* This is the model-independent version. Since the standard I/O library - can't handle far buffers in the medium and small models, we have to copy - the data. -*/ - -#define NEAR_BUF_SIZE 1024 -#define MIN(a,b) (a <= b ? a : b) - -static void PNGCBAPI -pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - png_byte *n_data; - png_FILE_p io_ptr; - - /* Check if data really is near. If so, use usual code. */ - n_data = (png_byte *)CVT_PTR_NOCHECK(data); - io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); - if ((png_bytep)n_data == data) - { - check = fread(n_data, 1, length, io_ptr); - } - else - { - png_byte buf[NEAR_BUF_SIZE]; - png_size_t read, remaining, err; - check = 0; - remaining = length; - - do - { - read = MIN(NEAR_BUF_SIZE, remaining); - err = fread(buf, 1, 1, io_ptr); - png_memcpy(data, buf, read); /* Copy far buffer to near buffer */ - if (err != read) - break; - else - check += err; - data += read; - remaining -= read; - } - while (remaining != 0); - } - - if (check != length) - png_error(png_ptr, "Read Error"); - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); -#endif -} -#endif /* USE_FAR_KEYWORD */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -static void PNGCBAPI -pngtest_flush(png_structp png_ptr) -{ - /* Do nothing; fflush() is said to be just a waste of energy. */ - PNG_UNUSED(png_ptr) /* Stifle compiler warning */ -} -#endif - -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -#ifndef USE_FAR_KEYWORD -static void PNGCBAPI -pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); - - if (check != length) - { - png_error(png_ptr, "Write Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); -#endif -} -#else -/* This is the model-independent version. Since the standard I/O library - can't handle far buffers in the medium and small models, we have to copy - the data. -*/ - -#define NEAR_BUF_SIZE 1024 -#define MIN(a,b) (a <= b ? a : b) - -static void PNGCBAPI -pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ - png_FILE_p io_ptr; - - /* Check if data really is near. If so, use usual code. */ - near_data = (png_byte *)CVT_PTR_NOCHECK(data); - io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); - - if ((png_bytep)near_data == data) - { - check = fwrite(near_data, 1, length, io_ptr); - } - - else - { - png_byte buf[NEAR_BUF_SIZE]; - png_size_t written, remaining, err; - check = 0; - remaining = length; - - do - { - written = MIN(NEAR_BUF_SIZE, remaining); - png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ - err = fwrite(buf, 1, written, io_ptr); - if (err != written) - break; - else - check += err; - data += written; - remaining -= written; - } - while (remaining != 0); - } - - if (check != length) - { - png_error(png_ptr, "Write Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); -#endif -} -#endif /* USE_FAR_KEYWORD */ - -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -static void PNGCBAPI -pngtest_warning(png_structp png_ptr, png_const_charp message) -{ - PNG_CONST char *name = "UNKNOWN (ERROR!)"; - char *test; - test = png_get_error_ptr(png_ptr); - - if (test == NULL) - fprintf(STDERR, "%s: libpng warning: %s\n", name, message); - - else - fprintf(STDERR, "%s: libpng warning: %s\n", test, message); -} - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static void PNGCBAPI -pngtest_error(png_structp png_ptr, png_const_charp message) -{ - pngtest_warning(png_ptr, message); - /* We can return because png_error calls the default handler, which is - * actually OK in this case. - */ -} -#endif /* !PNG_STDIO_SUPPORTED */ -/* END of code to validate stdio-free compilation */ - -/* START of code to validate memory allocation and deallocation */ -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more then 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - * - * This piece of code can be compiled to validate max 64K allocations - * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. - */ -typedef struct memory_information -{ - png_alloc_size_t size; - png_voidp pointer; - struct memory_information FAR *next; -} memory_information; -typedef memory_information FAR *memory_infop; - -static memory_infop pinformation = NULL; -static int current_allocation = 0; -static int maximum_allocation = 0; -static int total_allocation = 0; -static int num_allocations = 0; - -png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr, - png_alloc_size_t size)); -void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); - -png_voidp -PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) -{ - - /* png_malloc has already tested for NULL; png_create_struct calls - * png_debug_malloc directly, with png_ptr == NULL which is OK - */ - - if (size == 0) - return (NULL); - - /* This calls the library allocator twice, once to get the requested - buffer and once to get a new free list entry. */ - { - /* Disable malloc_fn and free_fn */ - memory_infop pinfo; - png_set_mem_fn(png_ptr, NULL, NULL, NULL); - pinfo = (memory_infop)png_malloc(png_ptr, - png_sizeof(*pinfo)); - pinfo->size = size; - current_allocation += size; - total_allocation += size; - num_allocations ++; - - if (current_allocation > maximum_allocation) - maximum_allocation = current_allocation; - - pinfo->pointer = png_malloc(png_ptr, size); - /* Restore malloc_fn and free_fn */ - - png_set_mem_fn(png_ptr, - NULL, png_debug_malloc, png_debug_free); - - if (size != 0 && pinfo->pointer == NULL) - { - current_allocation -= size; - total_allocation -= size; - png_error(png_ptr, - "out of memory in pngtest->png_debug_malloc"); - } - - pinfo->next = pinformation; - pinformation = pinfo; - /* Make sure the caller isn't assuming zeroed memory. */ - png_memset(pinfo->pointer, 0xdd, pinfo->size); - - if (verbose) - printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); - - return (png_voidp)(pinfo->pointer); - } -} - -/* Free a pointer. It is removed from the list at the same time. */ -void PNGCBAPI -png_debug_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL) - fprintf(STDERR, "NULL pointer to png_debug_free.\n"); - - if (ptr == 0) - { -#if 0 /* This happens all the time. */ - fprintf(STDERR, "WARNING: freeing NULL pointer\n"); -#endif - return; - } - - /* Unlink the element from the list. */ - { - memory_infop FAR *ppinfo = &pinformation; - - for (;;) - { - memory_infop pinfo = *ppinfo; - - if (pinfo->pointer == ptr) - { - *ppinfo = pinfo->next; - current_allocation -= pinfo->size; - if (current_allocation < 0) - fprintf(STDERR, "Duplicate free of memory\n"); - /* We must free the list element too, but first kill - the memory that is to be freed. */ - png_memset(ptr, 0x55, pinfo->size); - png_free_default(png_ptr, pinfo); - pinfo = NULL; - break; - } - - if (pinfo->next == NULL) - { - fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); - break; - } - - ppinfo = &pinfo->next; - } - } - - /* Finally free the data. */ - if (verbose) - printf("Freeing %p\n", ptr); - - png_free_default(png_ptr, ptr); - ptr = NULL; -} -#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ -/* END of code to test memory allocation/deallocation */ - - -/* Demonstration of user chunk support of the sTER and vpAg chunks */ -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - -/* (sTER is a public chunk not yet known by libpng. vpAg is a private -chunk used in ImageMagick to store "virtual page" size). */ - -static png_uint_32 user_chunk_data[4]; - - /* 0: sTER mode + 1 - * 1: vpAg width - * 2: vpAg height - * 3: vpAg units - */ - -static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, - png_unknown_chunkp chunk) -{ - png_uint_32 - *my_user_chunk_data; - - /* Return one of the following: - * return (-n); chunk had an error - * return (0); did not recognize - * return (n); success - * - * The unknown chunk structure contains the chunk data: - * png_byte name[5]; - * png_byte *data; - * png_size_t size; - * - * Note that libpng has already taken care of the CRC handling. - */ - - if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ - chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ - { - /* Found sTER chunk */ - if (chunk->size != 1) - return (-1); /* Error return */ - - if (chunk->data[0] != 0 && chunk->data[0] != 1) - return (-1); /* Invalid mode */ - - my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); - my_user_chunk_data[0]=chunk->data[0]+1; - return (1); - } - - if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ - chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ - return (0); /* Did not recognize */ - - /* Found ImageMagick vpAg chunk */ - - if (chunk->size != 9) - return (-1); /* Error return */ - - my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); - - my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); - my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); - my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; - - return (1); - -} -#endif -/* END of code to demonstrate user chunk support */ - -/* Test one file */ -int -test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) -{ - static png_FILE_p fpin; - static png_FILE_p fpout; /* "static" prevents setjmp corruption */ - png_structp read_ptr; - png_infop read_info_ptr, end_info_ptr; -#ifdef PNG_WRITE_SUPPORTED - png_structp write_ptr; - png_infop write_info_ptr; - png_infop write_end_info_ptr; -#else - png_structp write_ptr = NULL; - png_infop write_info_ptr = NULL; - png_infop write_end_info_ptr = NULL; -#endif - png_bytep row_buf; - png_uint_32 y; - png_uint_32 width, height; - int num_pass, pass; - int bit_depth, color_type; -#ifdef PNG_SETJMP_SUPPORTED -#ifdef USE_FAR_KEYWORD - jmp_buf tmp_jmpbuf; -#endif -#endif - - char inbuf[256], outbuf[256]; - - row_buf = NULL; - - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find input file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "wb")) == NULL) - { - fprintf(STDERR, "Could not open output file %s\n", outname); - FCLOSE(fpin); - return (1); - } - - pngtest_debug("Allocating read and write structures"); -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - read_ptr = - png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif -#ifndef PNG_STDIO_SUPPORTED - png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, - pngtest_warning); -#endif - -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - user_chunk_data[0] = 0; - user_chunk_data[1] = 0; - user_chunk_data[2] = 0; - user_chunk_data[3] = 0; - png_set_read_user_chunk_fn(read_ptr, user_chunk_data, - read_user_chunk_callback); - -#endif -#ifdef PNG_WRITE_SUPPORTED -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = - png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif -#ifndef PNG_STDIO_SUPPORTED - png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, - pngtest_warning); -#endif -#endif - pngtest_debug("Allocating read_info, write_info and end_info structures"); - read_info_ptr = png_create_info_struct(read_ptr); - end_info_ptr = png_create_info_struct(read_ptr); -#ifdef PNG_WRITE_SUPPORTED - write_info_ptr = png_create_info_struct(write_ptr); - write_end_info_ptr = png_create_info_struct(write_ptr); -#endif - -#ifdef PNG_SETJMP_SUPPORTED - pngtest_debug("Setting jmpbuf for read struct"); -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else - if (setjmp(png_jmpbuf(read_ptr))) -#endif - { - fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Setting jmpbuf for write struct"); -#ifdef USE_FAR_KEYWORD - - if (setjmp(tmp_jmpbuf)) -#else - if (setjmp(png_jmpbuf(write_ptr))) -#endif - { - fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } - -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif -#endif -#endif - - pngtest_debug("Initializing input and output streams"); -#ifdef PNG_STDIO_SUPPORTED - png_init_io(read_ptr, fpin); -# ifdef PNG_WRITE_SUPPORTED - png_init_io(write_ptr, fpout); -# endif -#else - png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); -# ifdef PNG_WRITE_SUPPORTED - png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, -# ifdef PNG_WRITE_FLUSH_SUPPORTED - pngtest_flush); -# else - NULL); -# endif -# endif -#endif - -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - /* Normally one would use Z_DEFAULT_STRATEGY for text compression. - * This is here just to make pngtest replicate the results from libpng - * versions prior to 1.5.4, and to test this new API. - */ - png_set_text_compression_strategy(write_ptr, Z_FILTERED); -#endif - - if (status_dots_requested == 1) - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, write_row_callback); -#endif - png_set_read_status_fn(read_ptr, read_row_callback); - } - - else - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, NULL); -#endif - png_set_read_status_fn(read_ptr, NULL); - } - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - { - int i; - - for (i = 0; i<256; i++) - filters_used[i] = 0; - - png_set_read_user_transform_fn(read_ptr, count_filters); - } -#endif -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - zero_samples = 0; - png_set_write_user_transform_fn(write_ptr, count_zero_samples); -#endif - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -# ifndef PNG_HANDLE_CHUNK_ALWAYS -# define PNG_HANDLE_CHUNK_ALWAYS 3 -# endif - png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -# ifndef PNG_HANDLE_CHUNK_IF_SAFE -# define PNG_HANDLE_CHUNK_IF_SAFE 2 -# endif - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, - NULL, 0); -#endif - - pngtest_debug("Reading info struct"); - png_read_info(read_ptr, read_info_ptr); - - pngtest_debug("Transferring info struct"); - { - int interlace_type, compression_type, filter_type; - - if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type)) - { - png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - color_type, interlace_type, compression_type, filter_type); -#else - color_type, PNG_INTERLACE_NONE, compression_type, filter_type); -#endif - } - } -#ifdef PNG_FIXED_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) - { - png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - png_fixed_point gamma; - - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) - png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } -#endif -#else /* Use floating point versions */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y)) - { - png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - double gamma; - - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) - png_set_gAMA(write_ptr, write_info_ptr, gamma); - } -#endif -#endif /* Floating point */ -#endif /* Fixed point */ -#ifdef PNG_iCCP_SUPPORTED - { - png_charp name; - png_bytep profile; - png_uint_32 proflen; - int compression_type; - - if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen)) - { - png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); - } - } -#endif -#ifdef PNG_sRGB_SUPPORTED - { - int intent; - - if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) - png_set_sRGB(write_ptr, write_info_ptr, intent); - } -#endif - { - png_colorp palette; - int num_palette; - - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) - png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } -#ifdef PNG_bKGD_SUPPORTED - { - png_color_16p background; - - if (png_get_bKGD(read_ptr, read_info_ptr, &background)) - { - png_set_bKGD(write_ptr, write_info_ptr, background); - } - } -#endif -#ifdef PNG_hIST_SUPPORTED - { - png_uint_16p hist; - - if (png_get_hIST(read_ptr, read_info_ptr, &hist)) - png_set_hIST(write_ptr, write_info_ptr, hist); - } -#endif -#ifdef PNG_oFFs_SUPPORTED - { - png_int_32 offset_x, offset_y; - int unit_type; - - if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type)) - { - png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); - } - } -#endif -#ifdef PNG_pCAL_SUPPORTED - { - png_charp purpose, units; - png_charpp params; - png_int_32 X0, X1; - int type, nparams; - - if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms)) - { - png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); - } - } -#endif -#ifdef PNG_pHYs_SUPPORTED - { - png_uint_32 res_x, res_y; - int unit_type; - - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) - png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } -#endif -#ifdef PNG_sBIT_SUPPORTED - { - png_color_8p sig_bit; - - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) - png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } -#endif -#ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - { - int unit; - double scal_width, scal_height; - - if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) - { - png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); - } - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - { - int unit; - png_charp scal_width, scal_height; - - if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) - { - png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, - scal_height); - } - } -#endif -#endif -#endif -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - if (verbose) - printf("\nText compression=%d\n", text_ptr->compression); - - png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); - } - } -#endif -#ifdef PNG_tIME_SUPPORTED - { - png_timep mod_time; - - if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) - { - png_set_tIME(write_ptr, write_info_ptr, mod_time); -#ifdef PNG_TIME_RFC1123_SUPPORTED - /* We have to use png_memcpy instead of "=" because the string - * pointed to by png_convert_to_rfc1123() gets free'ed before - * we use it. - */ - png_memcpy(tIME_string, - png_convert_to_rfc1123(read_ptr, mod_time), - png_sizeof(tIME_string)); - - tIME_string[png_sizeof(tIME_string) - 1] = '\0'; - tIME_chunk_present++; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ - } - } -#endif -#ifdef PNG_tRNS_SUPPORTED - { - png_bytep trans_alpha; - int num_trans; - png_color_16p trans_color; - - if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, - &trans_color)) - { - int sample_max = (1 << bit_depth); - /* libpng doesn't reject a tRNS chunk with out-of-range samples */ - if (!((color_type == PNG_COLOR_TYPE_GRAY && - (int)trans_color->gray > sample_max) || - (color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max)))) - png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, - trans_color); - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, - &unknowns); - - if (num_unknowns) - { - int i; - png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, - num_unknowns); - /* Copy the locations from the read_info_ptr. The automatically - * generated locations in write_info_ptr are wrong because we - * haven't written anything yet. - */ - for (i = 0; i < num_unknowns; i++) - png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, - unknowns[i].location); - } - } -#endif - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Writing info struct"); - -/* If we wanted, we could write info in two steps: - * png_write_info_before_PLTE(write_ptr, write_info_ptr); - */ - png_write_info(write_ptr, write_info_ptr); - -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - if (user_chunk_data[0] != 0) - { - png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}; - - unsigned char - ster_chunk_data[1]; - - if (verbose) - fprintf(STDERR, "\n stereo mode = %lu\n", - (unsigned long)(user_chunk_data[0] - 1)); - - ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1); - png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1); - } - - if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0) - { - png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'}; - - unsigned char - vpag_chunk_data[9]; - - if (verbose) - fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n", - (unsigned long)user_chunk_data[1], - (unsigned long)user_chunk_data[2], - (unsigned long)user_chunk_data[3]); - - png_save_uint_32(vpag_chunk_data, user_chunk_data[1]); - png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]); - vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff); - png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9); - } - -#endif -#endif - -#ifdef SINGLE_ROWBUF_ALLOC - pngtest_debug("Allocating row buffer..."); - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug1("\t0x%08lx", (unsigned long)row_buf); -#endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("Writing row data"); - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) - num_pass = png_set_interlace_handling(read_ptr); -# ifdef PNG_WRITE_SUPPORTED - png_set_interlace_handling(write_ptr); -# endif -#else - num_pass = 1; -#endif - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; -#endif - for (pass = 0; pass < num_pass; pass++) - { - pngtest_debug1("Writing row data for pass %d", pass); - for (y = 0; y < height; y++) - { -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf, - png_get_rowbytes(read_ptr, read_info_ptr)); - -#endif /* !SINGLE_ROWBUF_ALLOC */ - png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_decode += (t_stop - t_start); - t_start = t_stop; -#endif - png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_encode += (t_stop - t_start); - t_start = t_stop; -#endif -#endif /* PNG_WRITE_SUPPORTED */ - -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); - png_free(read_ptr, row_buf); - row_buf = NULL; -#endif /* !SINGLE_ROWBUF_ALLOC */ - } - } - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -#endif - - pngtest_debug("Reading and writing end_info data"); - - png_read_end(read_ptr, end_info_ptr); -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); - } - } -#endif -#ifdef PNG_tIME_SUPPORTED - { - png_timep mod_time; - - if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) - { - png_set_tIME(write_ptr, write_end_info_ptr, mod_time); -#ifdef PNG_TIME_RFC1123_SUPPORTED - /* We have to use png_memcpy instead of "=" because the string - pointed to by png_convert_to_rfc1123() gets free'ed before - we use it */ - png_memcpy(tIME_string, - png_convert_to_rfc1123(read_ptr, mod_time), - png_sizeof(tIME_string)); - - tIME_string[png_sizeof(tIME_string) - 1] = '\0'; - tIME_chunk_present++; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, - &unknowns); - - if (num_unknowns) - { - int i; - png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, - num_unknowns); - /* Copy the locations from the read_info_ptr. The automatically - * generated locations in write_end_info_ptr are wrong because we - * haven't written the end_info yet. - */ - for (i = 0; i < num_unknowns; i++) - png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, - unknowns[i].location); - } - } -#endif -#ifdef PNG_WRITE_SUPPORTED - png_write_end(write_ptr, write_end_info_ptr); -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED - if (verbose) - { - png_uint_32 iwidth, iheight; - iwidth = png_get_image_width(write_ptr, write_info_ptr); - iheight = png_get_image_height(write_ptr, write_info_ptr); - fprintf(STDERR, "\n Image width = %lu, height = %lu\n", - (unsigned long)iwidth, (unsigned long)iheight); - } -#endif - - pngtest_debug("Destroying data structs"); -#ifdef SINGLE_ROWBUF_ALLOC - pngtest_debug("destroying row_buf for read_ptr"); - png_free(read_ptr, row_buf); - row_buf = NULL; -#endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("destroying write_end_info_ptr"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - pngtest_debug("destroying write_ptr, write_info_ptr"); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - pngtest_debug("Destruction complete."); - - FCLOSE(fpin); - FCLOSE(fpout); - - pngtest_debug("Opening files for comparison"); - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", outname); - FCLOSE(fpin); - return (1); - } - - for (;;) - { - png_size_t num_in, num_out; - - num_in = fread(inbuf, 1, 1, fpin); - num_out = fread(outbuf, 1, 1, fpout); - - if (num_in != num_out) - { - fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); - - if (wrote_question == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - if (strict != 0) - return (1); - - else - return (0); - } - - if (!num_in) - break; - - if (png_memcmp(inbuf, outbuf, num_in)) - { - fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); - - if (wrote_question == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - if (strict != 0) - return (1); - - else - return (0); - } - } - - FCLOSE(fpin); - FCLOSE(fpout); - - return (0); -} - -/* Input and output filenames */ -#ifdef RISCOS -static PNG_CONST char *inname = "pngtest/png"; -static PNG_CONST char *outname = "pngout/png"; -#else -static PNG_CONST char *inname = "pngtest.png"; -static PNG_CONST char *outname = "pngout.png"; -#endif - -int -main(int argc, char *argv[]) -{ - int multiple = 0; - int ierror = 0; - - fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); - fprintf(STDERR, "%s", png_get_copyright(NULL)); - /* Show the version of libpng used in building the library */ - fprintf(STDERR, " library (%lu):%s", - (unsigned long)png_access_version_number(), - png_get_header_version(NULL)); - - /* Show the version of libpng used in building the application */ - fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, - PNG_HEADER_VERSION_STRING); - - /* Do some consistency checking on the memory allocation settings, I'm - * not sure this matters, but it is nice to know, the first of these - * tests should be impossible because of the way the macros are set - * in pngconf.h - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); -#endif - /* I think the following can happen. */ -#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); -#endif - - if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) - { - fprintf(STDERR, - "Warning: versions are different between png.h and png.c\n"); - fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); - ++ierror; - } - - if (argc > 1) - { - if (strcmp(argv[1], "-m") == 0) - { - multiple = 1; - status_dots_requested = 0; - } - - else if (strcmp(argv[1], "-mv") == 0 || - strcmp(argv[1], "-vm") == 0 ) - { - multiple = 1; - verbose = 1; - status_dots_requested = 1; - } - - else if (strcmp(argv[1], "-v") == 0) - { - verbose = 1; - status_dots_requested = 1; - inname = argv[2]; - } - - else if (strcmp(argv[1], "--strict") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict++; - } - - else - { - inname = argv[1]; - status_dots_requested = 0; - } - } - - if (!multiple && argc == 3 + verbose) - outname = argv[2 + verbose]; - - if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) - { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", - argv[0], argv[0]); - fprintf(STDERR, - " reads/writes one PNG file (without -m) or multiple files (-m)\n"); - fprintf(STDERR, - " with -m %s is used as a temporary file\n", outname); - exit(1); - } - - if (multiple) - { - int i; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - for (i=2; isize, - (unsigned int)pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - - else - { - int i; - for (i = 0; i<3; ++i) - { - int kerror; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - if (i == 1) - status_dots_requested = 1; - - else if (verbose == 0) - status_dots_requested = 0; - - if (i == 0 || verbose == 1 || ierror != 0) - fprintf(STDERR, "\n Testing %s:", inname); - - kerror = test_one_file(inname, outname); - - if (kerror == 0) - { - if (verbose == 1 || i == 2) - { -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - int k; -#endif -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - for (k = 0; k<256; k++) - if (filters_used[k]) - fprintf(STDERR, " Filter %d was used %lu times\n", - k, (unsigned long)filters_used[k]); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ - } - } - - else - { - if (verbose == 0 && i != 2) - fprintf(STDERR, "\n Testing %s:", inname); - - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %x\n", - (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; - fprintf(STDERR, " CPU time used = %.3f seconds", - (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " (decoding %.3f,\n", - t_decode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " encoding %.3f ,", - t_encode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " other %.3f seconds)\n\n", - t_misc/(float)CLOCKS_PER_SEC); -#endif - - if (ierror == 0) - fprintf(STDERR, " libpng passes test\n"); - - else - fprintf(STDERR, " libpng FAILS test\n"); - - return (int)(ierror != 0); -} - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_5_8 Your_png_h_is_not_version_1_5_8; diff --git a/WDL/libpng/pngtrans.c b/WDL/libpng/pngtrans.c deleted file mode 100644 index 53d9a25b..00000000 --- a/WDL/libpng/pngtrans.c +++ /dev/null @@ -1,678 +0,0 @@ - -/* pngtrans.c - transforms the data in a row (used by both readers and writers) - * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Turn on BGR-to-RGB mapping */ -void PNGAPI -png_set_bgr(png_structp png_ptr) -{ - png_debug(1, "in png_set_bgr"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_BGR; -} -#endif - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Turn on 16 bit byte swapping */ -void PNGAPI -png_set_swap(png_structp png_ptr) -{ - png_debug(1, "in png_set_swap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth == 16) - png_ptr->transformations |= PNG_SWAP_BYTES; -} -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Turn on pixel packing */ -void PNGAPI -png_set_packing(png_structp png_ptr) -{ - png_debug(1, "in png_set_packing"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - { - png_ptr->transformations |= PNG_PACK; - png_ptr->usr_bit_depth = 8; - } -} -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Turn on packed pixel swapping */ -void PNGAPI -png_set_packswap(png_structp png_ptr) -{ - png_debug(1, "in png_set_packswap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - png_ptr->transformations |= PNG_PACKSWAP; -} -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -void PNGAPI -png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) -{ - png_debug(1, "in png_set_shift"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SHIFT; - png_ptr->shift = *true_bits; -} -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -int PNGAPI -png_set_interlace_handling(png_structp png_ptr) -{ - png_debug(1, "in png_set_interlace handling"); - - if (png_ptr && png_ptr->interlaced) - { - png_ptr->transformations |= PNG_INTERLACE; - return (7); - } - - return (1); -} -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte on read, or remove a filler or alpha byte on write. - * The filler type has changed in v0.95 to allow future 2-byte fillers - * for 48-bit input data, as well as to avoid problems with some compilers - * that don't like bytes as parameters. - */ -void PNGAPI -png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_filler"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_FILLER; - png_ptr->filler = (png_uint_16)filler; - - if (filler_loc == PNG_FILLER_AFTER) - png_ptr->flags |= PNG_FLAG_FILLER_AFTER; - - else - png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; - - /* This should probably go in the "do_read_filler" routine. - * I attempted to do that in libpng-1.0.1a but that caused problems - * so I restored it in libpng-1.0.2a - */ - - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_ptr->usr_channels = 4; - } - - /* Also I added this in libpng-1.0.2a (what happens when we expand - * a less-than-8-bit grayscale to GA?) */ - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) - { - png_ptr->usr_channels = 2; - } -} - -/* Added to libpng-1.2.7 */ -void PNGAPI -png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_add_alpha"); - - if (png_ptr == NULL) - return; - - png_set_filler(png_ptr, filler, filler_loc); - png_ptr->transformations |= PNG_ADD_ALPHA; -} - -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -void PNGAPI -png_set_swap_alpha(png_structp png_ptr) -{ - png_debug(1, "in png_set_swap_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SWAP_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -void PNGAPI -png_set_invert_alpha(png_structp png_ptr) -{ - png_debug(1, "in png_set_invert_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -void PNGAPI -png_set_invert_mono(png_structp png_ptr) -{ - png_debug(1, "in png_set_invert_mono"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_MONO; -} - -/* Invert monochrome grayscale data */ -void /* PRIVATE */ -png_do_invert(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_invert"); - - /* This test removed from libpng version 1.0.13 and 1.2.0: - * if (row_info->bit_depth == 1 && - */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(~(*rp)); - rp++; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 8) - { - png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 2) - { - *rp = (png_byte)(~(*rp)); - rp += 2; - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 16) - { - png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 4) - { - *rp = (png_byte)(~(*rp)); - *(rp + 1) = (png_byte)(~(*(rp + 1))); - rp += 4; - } - } -#endif -} -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swaps byte order on 16 bit depth images */ -void /* PRIVATE */ -png_do_swap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_swap"); - - if (row_info->bit_depth == 16) - { - png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop= row_info->width * row_info->channels; - - for (i = 0; i < istop; i++, rp += 2) - { - png_byte t = *rp; - *rp = *(rp + 1); - *(rp + 1) = t; - } - } -} -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static PNG_CONST png_byte onebppswaptable[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 PNG_CONST png_byte twobppswaptable[256] = { - 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, - 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, - 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, - 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, - 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, - 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, - 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, - 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, - 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, - 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, - 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, - 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, - 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, - 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, - 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, - 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, - 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, - 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, - 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, - 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, - 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, - 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, - 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, - 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, - 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, - 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, - 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, - 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, - 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, - 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, - 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, - 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF -}; - -static PNG_CONST png_byte fourbppswaptable[256] = { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, - 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, - 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, - 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, - 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, - 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, - 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, - 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, - 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, - 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, - 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, - 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, - 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, - 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, - 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, - 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, - 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, - 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, - 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, - 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, - 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, - 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, - 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, - 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, - 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, - 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, - 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, - 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, - 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, - 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, - 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF -}; - -/* Swaps pixel packing order within bytes */ -void /* PRIVATE */ -png_do_packswap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_packswap"); - - if (row_info->bit_depth < 8) - { - png_bytep rp; - png_const_bytep end, table; - - end = row + row_info->rowbytes; - - if (row_info->bit_depth == 1) - table = onebppswaptable; - - else if (row_info->bit_depth == 2) - table = twobppswaptable; - - else if (row_info->bit_depth == 4) - table = fourbppswaptable; - - else - return; - - for (rp = row; rp < end; rp++) - *rp = table[*rp]; - } -} -#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ - -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -/* Remove a channel - this used to be 'png_do_strip_filler' but it used a - * somewhat weird combination of flags to determine what to do. All the calls - * to png_do_strip_filler are changed in 1.5.2 to call this instead with the - * correct arguments. - * - * The routine isn't general - the channel must be the channel at the start or - * end (not in the middle) of each pixel. - */ -void /* PRIVATE */ -png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) -{ - png_bytep sp = row; /* source pointer */ - png_bytep dp = row; /* destination pointer */ - png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ - - /* At the start sp will point to the first byte to copy and dp to where - * it is copied to. ep always points just beyond the end of the row, so - * the loop simply copies (channels-1) channels until sp reaches ep. - * - * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. - * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. - */ - - /* GA, GX, XG cases */ - if (row_info->channels == 2) - { - if (row_info->bit_depth == 8) - { - if (at_start) /* Skip initial filler */ - ++sp; - else /* Skip initial channel and, for sp, the filler */ - sp += 2, ++dp; - - /* For a 1 pixel wide image there is nothing to do */ - while (sp < ep) - *dp++ = *sp, sp += 2; - - row_info->pixel_depth = 8; - } - - else if (row_info->bit_depth == 16) - { - if (at_start) /* Skip initial filler */ - sp += 2; - else /* Skip initial channel and, for sp, the filler */ - sp += 4, dp += 2; - - while (sp < ep) - *dp++ = *sp++, *dp++ = *sp, sp += 3; - - row_info->pixel_depth = 16; - } - - else - return; /* bad bit depth */ - - row_info->channels = 1; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_GRAY; - } - - /* RGBA, RGBX, XRGB cases */ - else if (row_info->channels == 4) - { - if (row_info->bit_depth == 8) - { - if (at_start) /* Skip initial filler */ - ++sp; - else /* Skip initial channels and, for sp, the filler */ - sp += 4, dp += 3; - - /* Note that the loop adds 3 to dp and 4 to sp each time. */ - while (sp < ep) - *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; - - row_info->pixel_depth = 24; - } - - else if (row_info->bit_depth == 16) - { - if (at_start) /* Skip initial filler */ - sp += 2; - else /* Skip initial channels and, for sp, the filler */ - sp += 8, dp += 6; - - while (sp < ep) - { - /* Copy 6 bytes, skip 2 */ - *dp++ = *sp++, *dp++ = *sp++; - *dp++ = *sp++, *dp++ = *sp++; - *dp++ = *sp++, *dp++ = *sp, sp += 3; - } - - row_info->pixel_depth = 48; - } - - else - return; /* bad bit depth */ - - row_info->channels = 3; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_RGB; - } - - else - return; /* The filler channel has gone already */ - - /* Fix the rowbytes value. */ - row_info->rowbytes = dp-row; -} -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Swaps red and blue bytes within a pixel */ -void /* PRIVATE */ -png_do_bgr(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_bgr"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 3) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 4) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 6) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 8) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - } -#endif - } -} -#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -void PNGAPI -png_set_user_transform_info(png_structp png_ptr, png_voidp - user_transform_ptr, int user_transform_depth, int user_transform_channels) -{ - png_debug(1, "in png_set_user_transform_info"); - - if (png_ptr == NULL) - return; - png_ptr->user_transform_ptr = user_transform_ptr; - png_ptr->user_transform_depth = (png_byte)user_transform_depth; - png_ptr->user_transform_channels = (png_byte)user_transform_channels; -} -#endif - -/* This function returns a pointer to the user_transform_ptr associated with - * the user transform functions. The application should free any memory - * associated with this pointer before png_write_destroy and png_read_destroy - * are called. - */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -png_voidp PNGAPI -png_get_user_transform_ptr(png_const_structp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return ((png_voidp)png_ptr->user_transform_ptr); -} -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -png_uint_32 PNGAPI -png_get_current_row_number(png_const_structp png_ptr) -{ - /* See the comments in png.h - this is the sub-image row when reading and - * interlaced image. - */ - if (png_ptr != NULL) - return png_ptr->row_number; - - return PNG_UINT_32_MAX; /* help the app not to fail silently */ -} - -png_byte PNGAPI -png_get_current_pass_number(png_const_structp png_ptr) -{ - if (png_ptr != NULL) - return png_ptr->pass; - return 8; /* invalid */ -} -#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ -#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || - PNG_WRITE_USER_TRANSFORM_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwio.c b/WDL/libpng/pngwio.c deleted file mode 100644 index 8eacf9f6..00000000 --- a/WDL/libpng/pngwio.c +++ /dev/null @@ -1,254 +0,0 @@ - -/* pngwio.c - functions for data output - * - * Last changed in libpng 1.5.0 [January 6, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all output. Users who need - * special handling are expected to write functions that have the same - * arguments as these and perform similar functions, but that possibly - * use different output methods. Note that you shouldn't change these - * functions, but rather write replacement functions and then change - * them at run time with png_set_write_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -/* Write the data to whatever output you are using. The default routine - * writes to a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered writes. This should never be asked - * to write more than 64K on a 16 bit machine. - */ - -void /* PRIVATE */ -png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) -{ - /* NOTE: write_data_fn must not change the buffer! */ - if (png_ptr->write_data_fn != NULL ) - (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); - - else - png_error(png_ptr, "Call to NULL write function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -#ifndef USE_FAR_KEYWORD -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_size_t check; - - if (png_ptr == NULL) - return; - - check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Write Error"); -} -#else -/* This is the model-independent version. Since the standard I/O library - * can't handle far buffers in the medium and small models, we have to copy - * the data. - */ - -#define NEAR_BUF_SIZE 1024 -#define MIN(a,b) (a <= b ? a : b) - -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_uint_32 check; - png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - /* Check if data really is near. If so, use usual code. */ - near_data = (png_byte *)CVT_PTR_NOCHECK(data); - io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); - - if ((png_bytep)near_data == data) - { - check = fwrite(near_data, 1, length, io_ptr); - } - - else - { - png_byte buf[NEAR_BUF_SIZE]; - png_size_t written, remaining, err; - check = 0; - remaining = length; - - do - { - written = MIN(NEAR_BUF_SIZE, remaining); - png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ - err = fwrite(buf, 1, written, io_ptr); - - if (err != written) - break; - - else - check += err; - - data += written; - remaining -= written; - } - while (remaining != 0); - } - - if (check != length) - png_error(png_ptr, "Write Error"); -} - -#endif -#endif - -/* This function is called to output any data pending writing (normally - * to disk). After png_flush is called, there should be no data pending - * writing in any buffers. - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -void /* PRIVATE */ -png_flush(png_structp png_ptr) -{ - if (png_ptr->output_flush_fn != NULL) - (*(png_ptr->output_flush_fn))(png_ptr); -} - -# ifdef PNG_STDIO_SUPPORTED -void PNGCBAPI -png_default_flush(png_structp png_ptr) -{ - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); - fflush(io_ptr); -} -# endif -#endif - -/* This function allows the application to supply new output functions for - * libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * png_ptr - pointer to a png output data structure - * io_ptr - pointer to user supplied structure containing info about - * the output functions. May be NULL. - * write_data_fn - pointer to a new output function that takes as its - * arguments a pointer to a png_struct, a pointer to - * data to be written, and a 32-bit unsigned int that is - * the number of bytes to be written. The new write - * function should call png_error(png_ptr, "Error msg") - * to exit and output any fatal error messages. May be - * NULL, in which case libpng's default function will - * be used. - * flush_data_fn - pointer to a new flush function that takes as its - * arguments a pointer to a png_struct. After a call to - * the flush function, there should be no data in any buffers - * or pending transmission. If the output method doesn't do - * any buffering of output, a function prototype must still be - * supplied although it doesn't have to do anything. If - * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile - * time, output_flush_fn will be ignored, although it must be - * supplied for compatibility. May be NULL, in which case - * libpng's default function will be used, if - * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not - * a good idea if io_ptr does not point to a standard - * *FILE structure. - */ -void PNGAPI -png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (write_data_fn != NULL) - png_ptr->write_data_fn = write_data_fn; - - else - png_ptr->write_data_fn = png_default_write_data; -#else - png_ptr->write_data_fn = write_data_fn; -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED - - if (output_flush_fn != NULL) - png_ptr->output_flush_fn = output_flush_fn; - - else - png_ptr->output_flush_fn = png_default_flush; - -# else - png_ptr->output_flush_fn = output_flush_fn; -# endif -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ - - /* It is an error to read while writing a png file */ - if (png_ptr->read_data_fn != NULL) - { - png_ptr->read_data_fn = NULL; - - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -} - -#ifdef USE_FAR_KEYWORD -# ifdef _MSC_VER -void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) -{ - void *near_ptr; - void FAR *far_ptr; - FP_OFF(near_ptr) = FP_OFF(ptr); - far_ptr = (void FAR *)near_ptr; - - if (check != 0) - if (FP_SEG(ptr) != FP_SEG(far_ptr)) - png_error(png_ptr, "segment lost in conversion"); - - return(near_ptr); -} -# else -void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) -{ - void *near_ptr; - void FAR *far_ptr; - near_ptr = (void FAR *)ptr; - far_ptr = (void FAR *)near_ptr; - - if (check != 0) - if (far_ptr != ptr) - png_error(png_ptr, "segment lost in conversion"); - - return(near_ptr); -} -# endif -#endif -#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwrite.c b/WDL/libpng/pngwrite.c deleted file mode 100644 index dc12a204..00000000 --- a/WDL/libpng/pngwrite.c +++ /dev/null @@ -1,1655 +0,0 @@ - -/* pngwrite.c - general routines to write a PNG file - * - * Last changed in libpng 1.5.7 [December 15, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -/* Writes all the PNG information. This is the suggested way to use the - * library. If you have a new chunk to add, make a function to write it, - * and put it in the correct location here. If you want the chunk written - * after the image data, put it in png_write_end(). I strongly encourage - * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing - * the chunk, as that will keep the code from breaking if you want to just - * write a plain PNG file. If you have long comments, I suggest writing - * them in png_write_end(), and compressing them. - */ -void PNGAPI -png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_write_info_before_PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) - { - /* Write PNG signature */ - png_write_sig(png_ptr); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ - (png_ptr->mng_features_permitted)) - { - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - png_ptr->mng_features_permitted = 0; - } -#endif - - /* Write IHDR information. */ - png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type); -#else - 0); -#endif - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. - */ -#ifdef PNG_WRITE_gAMA_SUPPORTED - if (info_ptr->valid & PNG_INFO_gAMA) - png_write_gAMA_fixed(png_ptr, info_ptr->gamma); -#endif -#ifdef PNG_WRITE_sRGB_SUPPORTED - if (info_ptr->valid & PNG_INFO_sRGB) - png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED - if (info_ptr->valid & PNG_INFO_iCCP) - png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, - (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); -#endif -#ifdef PNG_WRITE_sBIT_SUPPORTED - if (info_ptr->valid & PNG_INFO_sBIT) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); -#endif -#ifdef PNG_WRITE_cHRM_SUPPORTED - if (info_ptr->valid & PNG_INFO_cHRM) - png_write_cHRM_fixed(png_ptr, - info_ptr->x_white, info_ptr->y_white, - info_ptr->x_red, info_ptr->y_red, - info_ptr->x_green, info_ptr->y_green, - info_ptr->x_blue, info_ptr->y_blue); -#endif - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - !(up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - !(up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - if (up->size == 0) - png_warning(png_ptr, "Writing zero-length unknown chunk"); - - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } -#endif - png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; - } -} - -void PNGAPI -png_write_info(png_structp png_ptr, png_infop info_ptr) -{ -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) - int i; -#endif - - png_debug(1, "in png_write_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_write_info_before_PLTE(png_ptr, info_ptr); - - if (info_ptr->valid & PNG_INFO_PLTE) - png_write_PLTE(png_ptr, info_ptr->palette, - (png_uint_32)info_ptr->num_palette); - - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Valid palette required for paletted images"); - -#ifdef PNG_WRITE_tRNS_SUPPORTED - if (info_ptr->valid & PNG_INFO_tRNS) - { -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel (in tRNS) */ - if ((png_ptr->transformations & PNG_INVERT_ALPHA) && - info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - int j; - for (j = 0; j<(int)info_ptr->num_trans; j++) - info_ptr->trans_alpha[j] = - (png_byte)(255 - info_ptr->trans_alpha[j]); - } -#endif - png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), - info_ptr->num_trans, info_ptr->color_type); - } -#endif -#ifdef PNG_WRITE_bKGD_SUPPORTED - if (info_ptr->valid & PNG_INFO_bKGD) - png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED - if (info_ptr->valid & PNG_INFO_hIST) - png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED - if (info_ptr->valid & PNG_INFO_oFFs) - png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_pCAL) - png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_sCAL) - png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_s_width, info_ptr->scal_s_height); -#endif /* sCAL */ - -#ifdef PNG_WRITE_pHYs_SUPPORTED - if (info_ptr->valid & PNG_INFO_pHYs) - png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); -#endif /* pHYs */ - -#ifdef PNG_WRITE_tIME_SUPPORTED - if (info_ptr->valid & PNG_INFO_tIME) - { - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - png_ptr->mode |= PNG_WROTE_tIME; - } -#endif /* tIME */ - -#ifdef PNG_WRITE_sPLT_SUPPORTED - if (info_ptr->valid & PNG_INFO_sPLT) - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); -#endif /* sPLT */ - -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Check to see if we need to write text chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing header text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - - /* If we want a compressed text chunk */ - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, - 0); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -#else - /* Can't get here */ - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - } - } -#endif /* tEXt */ - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - (up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - !(up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } -#endif -} - -/* Writes the end of the PNG file. If you don't want to write comments or - * time information, you can pass NULL for info. If you already wrote these - * in png_write_info(), do not write them again here. If you have long - * comments, I suggest writing them here, and compressing them. - */ -void PNGAPI -png_write_end(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_write_end"); - - if (png_ptr == NULL) - return; - - if (!(png_ptr->mode & PNG_HAVE_IDAT)) - png_error(png_ptr, "No IDATs written into file"); - - /* See if user wants us to write information chunks */ - if (info_ptr != NULL) - { -#ifdef PNG_WRITE_TEXT_SUPPORTED - int i; /* local index variable */ -#endif -#ifdef PNG_WRITE_tIME_SUPPORTED - /* Check to see if user has supplied a time chunk */ - if ((info_ptr->valid & PNG_INFO_tIME) && - !(png_ptr->mode & PNG_WROTE_tIME)) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - -#endif -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Loop through comment chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing trailer text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - - else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); -#else - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - (up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } -#endif - } - - png_ptr->mode |= PNG_AFTER_IDAT; - - /* Write end of PNG file */ - png_write_IEND(png_ptr); - /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, - * and restored again in libpng-1.2.30, may cause some applications that - * do not set png_ptr->output_flush_fn to crash. If your application - * experiences a problem, please try building libpng with - * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to - * png-mng-implement at lists.sf.net . - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED - png_flush(png_ptr); -# endif -#endif -} - -#ifdef PNG_CONVERT_tIME_SUPPORTED -/* "tm" structure is not supported on WindowsCE */ -void PNGAPI -png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) -{ - png_debug(1, "in png_convert_from_struct_tm"); - - ptime->year = (png_uint_16)(1900 + ttime->tm_year); - ptime->month = (png_byte)(ttime->tm_mon + 1); - ptime->day = (png_byte)ttime->tm_mday; - ptime->hour = (png_byte)ttime->tm_hour; - ptime->minute = (png_byte)ttime->tm_min; - ptime->second = (png_byte)ttime->tm_sec; -} - -void PNGAPI -png_convert_from_time_t(png_timep ptime, time_t ttime) -{ - struct tm *tbuf; - - png_debug(1, "in png_convert_from_time_t"); - - tbuf = gmtime(&ttime); - png_convert_from_struct_tm(ptime, tbuf); -} -#endif - -/* Initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifdef PNG_USER_MEM_SUPPORTED - return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL)); -} - -/* Alternate initialize png_ptr structure, and allocate any memory needed */ -static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ - -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ -#endif /* PNG_USER_MEM_SUPPORTED */ - volatile int png_cleanup_needed = 0; -#ifdef PNG_SETJMP_SUPPORTED - volatile -#endif - png_structp png_ptr; -#ifdef PNG_SETJMP_SUPPORTED -#ifdef USE_FAR_KEYWORD - jmp_buf tmp_jmpbuf; -#endif -#endif - - png_debug(1, "in png_create_write_struct"); - -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); -#else - png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); -#endif /* PNG_USER_MEM_SUPPORTED */ - if (png_ptr == NULL) - return (NULL); - - /* Added at libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - png_ptr->user_width_max = PNG_USER_WIDTH_MAX; - png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* Applications that neglect to set up their own setjmp() and then - * encounter a png_error() will longjmp here. Since the jmpbuf is - * then meaningless we abort instead of returning. - */ -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else - if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ -#endif -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif - PNG_ABORT(); -#endif - -#ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); -#endif /* PNG_USER_MEM_SUPPORTED */ - png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); - - if (!png_user_version_check(png_ptr, user_png_ver)) - png_cleanup_needed = 1; - - /* Initialize zbuf - compression buffer */ - png_ptr->zbuf_size = PNG_ZBUF_SIZE; - - if (!png_cleanup_needed) - { - png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, - png_ptr->zbuf_size); - if (png_ptr->zbuf == NULL) - png_cleanup_needed = 1; - } - - if (png_cleanup_needed) - { - /* Clean up PNG structure and deallocate any memory. */ - png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, - (png_free_ptr)free_fn, (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - return (NULL); - } - - png_set_write_fn(png_ptr, NULL, NULL, NULL); - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_reset_filter_heuristics(png_ptr); -#endif - - return (png_ptr); -} - - -/* Write a few rows of image data. If the image is interlaced, - * either you will have to write the 7 sub images, or, if you - * have called png_set_interlace_handling(), you will have to - * "write" the image seven times. - */ -void PNGAPI -png_write_rows(png_structp png_ptr, png_bytepp row, - png_uint_32 num_rows) -{ - png_uint_32 i; /* row counter */ - png_bytepp rp; /* row pointer */ - - png_debug(1, "in png_write_rows"); - - if (png_ptr == NULL) - return; - - /* Loop through the rows */ - for (i = 0, rp = row; i < num_rows; i++, rp++) - { - png_write_row(png_ptr, *rp); - } -} - -/* Write the image. You only need to call this function once, even - * if you are writing an interlaced image. - */ -void PNGAPI -png_write_image(png_structp png_ptr, png_bytepp image) -{ - png_uint_32 i; /* row index */ - int pass, num_pass; /* pass variables */ - png_bytepp rp; /* points to current row */ - - if (png_ptr == NULL) - return; - - png_debug(1, "in png_write_image"); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Initialize interlace handling. If image is not interlaced, - * this will set pass to 1 - */ - num_pass = png_set_interlace_handling(png_ptr); -#else - num_pass = 1; -#endif - /* Loop through passes */ - for (pass = 0; pass < num_pass; pass++) - { - /* Loop through image */ - for (i = 0, rp = image; i < png_ptr->height; i++, rp++) - { - png_write_row(png_ptr, *rp); - } - } -} - -/* Called by user to write a row of image data */ -void PNGAPI -png_write_row(png_structp png_ptr, png_const_bytep row) -{ - /* 1.5.6: moved from png_struct to be a local structure: */ - png_row_info row_info; - - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_write_row (row %u, pass %d)", - png_ptr->row_number, png_ptr->pass); - - /* Initialize transformations and other stuff if first time */ - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Make sure we wrote the header info */ - if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) - png_error(png_ptr, - "png_write_info was never called before png_write_row"); - - /* Check for transforms that have been set but were defined out */ -#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) - if (png_ptr->transformations & PNG_INVERT_MONO) - png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) - if (png_ptr->transformations & PNG_FILLER) - png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); -#endif -#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - png_warning(png_ptr, - "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) - if (png_ptr->transformations & PNG_PACK) - png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) - if (png_ptr->transformations & PNG_SHIFT) - png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) - if (png_ptr->transformations & PNG_BGR) - png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); -#endif - - png_write_start_row(png_ptr); - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced and not interested in row, return */ - if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) - { - switch (png_ptr->pass) - { - case 0: - if (png_ptr->row_number & 0x07) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 0x03) != 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 5: - if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 6: - if (!(png_ptr->row_number & 0x01)) - { - png_write_finish_row(png_ptr); - return; - } - break; - - default: /* error: ignore it */ - break; - } - } -#endif - - /* Set up row info for transformations */ - row_info.color_type = png_ptr->color_type; - row_info.width = png_ptr->usr_width; - row_info.channels = png_ptr->usr_channels; - row_info.bit_depth = png_ptr->usr_bit_depth; - row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - png_debug1(3, "row_info->color_type = %d", row_info.color_type); - png_debug1(3, "row_info->width = %u", row_info.width); - png_debug1(3, "row_info->channels = %d", row_info.channels); - png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); - - /* Copy user's row into buffer, leaving room for filter byte. */ - png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Handle interlacing */ - if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE)) - { - png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); - /* This should always get caught above, but still ... */ - if (!(row_info.width)) - { - png_write_finish_row(png_ptr); - return; - } - } -#endif - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* Handle other transformations */ - if (png_ptr->transformations) - png_do_write_transformations(png_ptr, &row_info); -#endif - - /* At this point the row_info pixel depth must match the 'transformed' depth, - * which is also the output depth. - */ - if (row_info.pixel_depth != png_ptr->pixel_depth || - row_info.pixel_depth != png_ptr->transformed_pixel_depth) - png_error(png_ptr, "internal write transform logic error"); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - - /* Find a filter if necessary, filter the row and write it out. */ - png_write_find_filter(png_ptr, &row_info); - - if (png_ptr->write_row_fn != NULL) - (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set the automatic flush interval or 0 to turn flushing off */ -void PNGAPI -png_set_flush(png_structp png_ptr, int nrows) -{ - png_debug(1, "in png_set_flush"); - - if (png_ptr == NULL) - return; - - png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); -} - -/* Flush the current output buffers now */ -void PNGAPI -png_write_flush(png_structp png_ptr) -{ - int wrote_IDAT; - - png_debug(1, "in png_write_flush"); - - if (png_ptr == NULL) - return; - - /* We have already written out all of the data */ - if (png_ptr->row_number >= png_ptr->num_rows) - return; - - do - { - int ret; - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); - wrote_IDAT = 0; - - /* Check for compression errors */ - if (ret != Z_OK) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - - if (!(png_ptr->zstream.avail_out)) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - wrote_IDAT = 1; - } - } while (wrote_IDAT == 1); - - /* If there is any data left to be output, write it into a new IDAT */ - if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); - } - png_ptr->flush_rows = 0; - png_flush(png_ptr); -} -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ - -/* Free all memory used by the write */ -void PNGAPI -png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) -{ - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn = NULL; - png_voidp mem_ptr = NULL; -#endif - - png_debug(1, "in png_destroy_write_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr != NULL) - { - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; - } -#endif - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - if (png_ptr != NULL) - { - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->num_chunk_list = 0; - } -#endif - } - -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)info_ptr); -#endif - *info_ptr_ptr = NULL; - } - - if (png_ptr != NULL) - { - png_write_destroy(png_ptr); -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - *png_ptr_ptr = NULL; - } -} - - -/* Free any memory used in png_ptr struct (old method) */ -void /* PRIVATE */ -png_write_destroy(png_structp png_ptr) -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf tmp_jmp; /* Save jump buffer */ -#endif - png_error_ptr error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; -#endif - png_voidp error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn; -#endif - - png_debug(1, "in png_write_destroy"); - - /* Free any memory zlib uses */ - if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) - deflateEnd(&png_ptr->zstream); - - /* Free our memory. png_free checks NULL for us. */ - png_free(png_ptr, png_ptr->zbuf); - png_free(png_ptr, png_ptr->row_buf); -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->sub_row); - png_free(png_ptr, png_ptr->up_row); - png_free(png_ptr, png_ptr->avg_row); - png_free(png_ptr, png_ptr->paeth_row); -#endif - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* Use this to save a little code space, it doesn't free the filter_costs */ - png_reset_filter_heuristics(png_ptr); - png_free(png_ptr, png_ptr->filter_costs); - png_free(png_ptr, png_ptr->inv_filter_costs); -#endif - -#ifdef PNG_SETJMP_SUPPORTED - /* Reset structure */ - png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); -#endif - - error_fn = png_ptr->error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - warning_fn = png_ptr->warning_fn; -#endif - error_ptr = png_ptr->error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; -#endif - - png_memset(png_ptr, 0, png_sizeof(png_struct)); - - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#endif - png_ptr->error_ptr = error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr->free_fn = free_fn; -#endif - -#ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); -#endif -} - -/* Allow the application to select one or more row filters to use. */ -void PNGAPI -png_set_filter(png_structp png_ptr, int method, int filters) -{ - png_debug(1, "in png_set_filter"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (method == PNG_INTRAPIXEL_DIFFERENCING)) - method = PNG_FILTER_TYPE_BASE; - -#endif - if (method == PNG_FILTER_TYPE_BASE) - { - switch (filters & (PNG_ALL_FILTERS | 0x07)) - { -#ifdef PNG_WRITE_FILTER_SUPPORTED - case 5: - case 6: - case 7: png_warning(png_ptr, "Unknown row filter for method 0"); -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - case PNG_FILTER_VALUE_SUB: - png_ptr->do_filter = PNG_FILTER_SUB; break; - - case PNG_FILTER_VALUE_UP: - png_ptr->do_filter = PNG_FILTER_UP; break; - - case PNG_FILTER_VALUE_AVG: - png_ptr->do_filter = PNG_FILTER_AVG; break; - - case PNG_FILTER_VALUE_PAETH: - png_ptr->do_filter = PNG_FILTER_PAETH; break; - - default: - png_ptr->do_filter = (png_byte)filters; break; -#else - default: - png_warning(png_ptr, "Unknown row filter for method 0"); -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - } - - /* If we have allocated the row_buf, this means we have already started - * with the image and we should have allocated all of the filter buffers - * that have been selected. If prev_row isn't already allocated, then - * it is too late to start using the filters that need it, since we - * will be missing the data in the previous row. If an application - * wants to start and stop using particular filters during compression, - * it should start out with all of the filters, and then add and - * remove them after the start of compression. - */ - if (png_ptr->row_buf != NULL) - { -#ifdef PNG_WRITE_FILTER_SUPPORTED - if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; - } - - if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Up filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_UP); - } - - else - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } - } - - if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Average filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_AVG); - } - - else - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - } - - if ((png_ptr->do_filter & PNG_FILTER_PAETH) && - png_ptr->paeth_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Paeth filter after starting"); - png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); - } - - else - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } - - if (png_ptr->do_filter == PNG_NO_FILTERS) -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - png_ptr->do_filter = PNG_FILTER_NONE; - } - } - else - png_error(png_ptr, "Unknown custom filter method"); -} - -/* This allows us to influence the way in which libpng chooses the "best" - * filter for the current scanline. While the "minimum-sum-of-absolute- - * differences metric is relatively fast and effective, there is some - * question as to whether it can be improved upon by trying to keep the - * filtered data going to zlib more consistent, hopefully resulting in - * better compression. - */ -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ -/* Convenience reset API. */ -static void -png_reset_filter_heuristics(png_structp png_ptr) -{ - /* Clear out any old values in the 'weights' - this must be done because if - * the app calls set_filter_heuristics multiple times with different - * 'num_weights' values we would otherwise potentially have wrong sized - * arrays. - */ - png_ptr->num_prev_filters = 0; - png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; - if (png_ptr->prev_filters != NULL) - { - png_bytep old = png_ptr->prev_filters; - png_ptr->prev_filters = NULL; - png_free(png_ptr, old); - } - if (png_ptr->filter_weights != NULL) - { - png_uint_16p old = png_ptr->filter_weights; - png_ptr->filter_weights = NULL; - png_free(png_ptr, old); - } - - if (png_ptr->inv_filter_weights != NULL) - { - png_uint_16p old = png_ptr->inv_filter_weights; - png_ptr->inv_filter_weights = NULL; - png_free(png_ptr, old); - } - - /* Leave the filter_costs - this array is fixed size. */ -} - -static int -png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, - int num_weights) -{ - if (png_ptr == NULL) - return 0; - - /* Clear out the arrays */ - png_reset_filter_heuristics(png_ptr); - - /* Check arguments; the 'reset' function makes the correct settings for the - * unweighted case, but we must handle the weight case by initializing the - * arrays for the caller. - */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - - if (num_weights > 0) - { - png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_byte) * num_weights)); - - /* To make sure that the weighting starts out fairly */ - for (i = 0; i < num_weights; i++) - { - png_ptr->prev_filters[i] = 255; - } - - png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); - - png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); - - for (i = 0; i < num_weights; i++) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - /* Safe to set this now */ - png_ptr->num_prev_filters = (png_byte)num_weights; - } - - /* If, in the future, there are other filter methods, this would - * need to be based on png_ptr->filter. - */ - if (png_ptr->filter_costs == NULL) - { - png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - - png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - } - - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) - { - png_ptr->inv_filter_costs[i] = - png_ptr->filter_costs[i] = PNG_COST_FACTOR; - } - - /* All the arrays are inited, safe to set this: */ - png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; - - /* Return the 'ok' code. */ - return 1; - } - else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || - heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) - { - return 1; - } - else - { - png_warning(png_ptr, "Unknown filter heuristic method"); - return 0; - } -} - -/* Provide floating and fixed point APIs */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, - int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs) -{ - png_debug(1, "in png_set_filter_heuristics"); - - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ - if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) - return; - - /* If using the weighted method copy in the weights. */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - for (i = 0; i < num_weights; i++) - { - if (filter_weights[i] <= 0.0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - else - { - png_ptr->inv_filter_weights[i] = - (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); - - png_ptr->filter_weights[i] = - (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); - } - } - - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) - { - png_ptr->inv_filter_costs[i] = - (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); - - png_ptr->filter_costs[i] = - (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); - } - } -} -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, - int num_weights, png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs) -{ - png_debug(1, "in png_set_filter_heuristics_fixed"); - - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ - if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) - return; - - /* If using the weighted method copy in the weights. */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - for (i = 0; i < num_weights; i++) - { - if (filter_weights[i] <= 0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - else - { - png_ptr->inv_filter_weights[i] = (png_uint_16) - ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); - - png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* - PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); - } - } - - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) - if (filter_costs[i] >= PNG_FP_1) - { - png_uint_32 tmp; - - /* Use a 32 bit unsigned temporary here because otherwise the - * intermediate value will be a 32 bit *signed* integer (ANSI rules) - * and this will get the wrong answer on division. - */ - tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); - tmp /= filter_costs[i]; - - png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; - - tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; - tmp /= PNG_FP_1; - - png_ptr->filter_costs[i] = (png_uint_16)tmp; - } - } -} -#endif /* FIXED_POINT */ -#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ - -void PNGAPI -png_set_compression_level(png_structp png_ptr, int level) -{ - png_debug(1, "in png_set_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; - png_ptr->zlib_level = level; -} - -void PNGAPI -png_set_compression_mem_level(png_structp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; - png_ptr->zlib_mem_level = mem_level; -} - -void PNGAPI -png_set_compression_strategy(png_structp png_ptr, int strategy) -{ - png_debug(1, "in png_set_compression_strategy"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; - png_ptr->zlib_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_compression_window_bits(png_structp png_ptr, int window_bits) -{ - if (png_ptr == NULL) - return; - - if (window_bits > 15) - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - - else if (window_bits < 8) - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - -#ifndef WBITS_8_OK - /* Avoid libpng bug with 256-byte windows */ - if (window_bits == 8) - { - png_warning(png_ptr, "Compression window is being reset to 512"); - window_bits = 9; - } - -#endif - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; - png_ptr->zlib_window_bits = window_bits; -} - -void PNGAPI -png_set_compression_method(png_structp png_ptr, int method) -{ - png_debug(1, "in png_set_compression_method"); - - if (png_ptr == NULL) - return; - - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; - png_ptr->zlib_method = method; -} - -/* The following were added to libpng-1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -void PNGAPI -png_set_text_compression_level(png_structp png_ptr, int level) -{ - png_debug(1, "in png_set_text_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; - png_ptr->zlib_text_level = level; -} - -void PNGAPI -png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_text_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; - png_ptr->zlib_text_mem_level = mem_level; -} - -void PNGAPI -png_set_text_compression_strategy(png_structp png_ptr, int strategy) -{ - png_debug(1, "in png_set_text_compression_strategy"); - - if (png_ptr == NULL) - return; - - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; - png_ptr->zlib_text_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) -{ - if (png_ptr == NULL) - return; - - if (window_bits > 15) - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - - else if (window_bits < 8) - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - -#ifndef WBITS_8_OK - /* Avoid libpng bug with 256-byte windows */ - if (window_bits == 8) - { - png_warning(png_ptr, "Text compression window is being reset to 512"); - window_bits = 9; - } - -#endif - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; - png_ptr->zlib_text_window_bits = window_bits; -} - -void PNGAPI -png_set_text_compression_method(png_structp png_ptr, int method) -{ - png_debug(1, "in png_set_text_compression_method"); - - if (png_ptr == NULL) - return; - - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; - png_ptr->zlib_text_method = method; -} -#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ -/* end of API added to libpng-1.5.4 */ - -void PNGAPI -png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->write_row_fn = write_row_fn; -} - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -void PNGAPI -png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr - write_user_transform_fn) -{ - png_debug(1, "in png_set_write_user_transform_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->write_user_transform_fn = write_user_transform_fn; -} -#endif - - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_write_png(png_structp png_ptr, png_infop info_ptr, - int transforms, voidp params) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Write the file header information. */ - png_write_info(png_ptr, info_ptr); - - /* ------ these transformations don't touch the info structure ------- */ - -#ifdef PNG_WRITE_INVERT_SUPPORTED - /* Invert monochrome pixels */ - if (transforms & PNG_TRANSFORM_INVERT_MONO) - png_set_invert_mono(png_ptr); -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ - if ((transforms & PNG_TRANSFORM_SHIFT) - && (info_ptr->valid & PNG_INFO_sBIT)) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED - /* Pack pixels into bytes */ - if (transforms & PNG_TRANSFORM_PACKING) - png_set_packing(png_ptr); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - /* Swap location of alpha bytes from ARGB to RGBA */ - if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); -#endif - -#ifdef PNG_WRITE_FILLER_SUPPORTED - /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ - if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) - png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - - else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -#endif - -#ifdef PNG_WRITE_BGR_SUPPORTED - /* Flip BGR pixels to RGB */ - if (transforms & PNG_TRANSFORM_BGR) - png_set_bgr(png_ptr); -#endif - -#ifdef PNG_WRITE_SWAP_SUPPORTED - /* Swap bytes of 16-bit files to most significant byte first */ - if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) - png_set_swap(png_ptr); -#endif - -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - /* Swap bits of 1, 2, 4 bit packed pixel formats */ - if (transforms & PNG_TRANSFORM_PACKSWAP) - png_set_packswap(png_ptr); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel from opacity to transparency */ - if (transforms & PNG_TRANSFORM_INVERT_ALPHA) - png_set_invert_alpha(png_ptr); -#endif - - /* ----------------------- end of transformations ------------------- */ - - /* Write the bits */ - if (info_ptr->valid & PNG_INFO_IDAT) - png_write_image(png_ptr, info_ptr->row_pointers); - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - - PNG_UNUSED(transforms) /* Quiet compiler warnings */ - PNG_UNUSED(params) -} -#endif -#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwtran.c b/WDL/libpng/pngwtran.c deleted file mode 100644 index b598149a..00000000 --- a/WDL/libpng/pngwtran.c +++ /dev/null @@ -1,633 +0,0 @@ - -/* pngwtran.c - transforms the data in a row for PNG writers - * - * Last changed in libpng 1.5.6 [November 3, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -/* Transform the data according to the user's wishes. The order of - * transformations is significant. - */ -void /* PRIVATE */ -png_do_write_transformations(png_structp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_write_transformations"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - if (png_ptr->transformations & PNG_USER_TRANSFORM) - if (png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* User write transform - function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#endif - -#ifdef PNG_WRITE_FILLER_SUPPORTED - if (png_ptr->transformations & PNG_FILLER) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); -#endif - -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED - if (png_ptr->transformations & PNG_PACK) - png_do_pack(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->bit_depth); -#endif - -#ifdef PNG_WRITE_SWAP_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if (png_ptr->transformations & PNG_SHIFT) - png_do_shift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_BGR_SUPPORTED - if (png_ptr->transformations & PNG_BGR) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif -} - -#ifdef PNG_WRITE_PACK_SUPPORTED -/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The - * row_info bit depth should be 8 (one pixel per byte). The channels - * should be 1 (this only happens on grayscale and paletted images). - */ -void /* PRIVATE */ -png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) -{ - png_debug(1, "in png_do_pack"); - - if (row_info->bit_depth == 8 && - row_info->channels == 1) - { - switch ((int)bit_depth) - { - case 1: - { - png_bytep sp, dp; - int mask, v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - mask = 0x80; - v = 0; - - for (i = 0; i < row_width; i++) - { - if (*sp != 0) - v |= mask; - - sp++; - - if (mask > 1) - mask >>= 1; - - else - { - mask = 0x80; - *dp = (png_byte)v; - dp++; - v = 0; - } - } - - if (mask != 0x80) - *dp = (png_byte)v; - - break; - } - - case 2: - { - png_bytep sp, dp; - int shift, v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 6; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x03); - v |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 2; - - sp++; - } - - if (shift != 6) - *dp = (png_byte)v; - - break; - } - - case 4: - { - png_bytep sp, dp; - int shift, v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 4; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x0f); - v |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 4; - - sp++; - } - - if (shift != 4) - *dp = (png_byte)v; - - break; - } - - default: - break; - } - - row_info->bit_depth = (png_byte)bit_depth; - row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED -/* Shift pixel values to take advantage of whole range. Pass the - * true number of bits in bit_depth. The row should be packed - * according to row_info->bit_depth. Thus, if you had a row of - * bit depth 4, but the pixels only had values from 0 to 7, you - * would pass 3 as bit_depth, and this routine would translate the - * data to 0 to 15. - */ -void /* PRIVATE */ -png_do_shift(png_row_infop row_info, png_bytep row, - png_const_color_8p bit_depth) -{ - png_debug(1, "in png_do_shift"); - - if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift_start[4], shift_dec[4]; - int channels = 0; - - if (row_info->color_type & PNG_COLOR_MASK_COLOR) - { - shift_start[channels] = row_info->bit_depth - bit_depth->red; - shift_dec[channels] = bit_depth->red; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->green; - shift_dec[channels] = bit_depth->green; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->blue; - shift_dec[channels] = bit_depth->blue; - channels++; - } - - else - { - shift_start[channels] = row_info->bit_depth - bit_depth->gray; - shift_dec[channels] = bit_depth->gray; - channels++; - } - - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) - { - shift_start[channels] = row_info->bit_depth - bit_depth->alpha; - shift_dec[channels] = bit_depth->alpha; - channels++; - } - - /* With low row depths, could only be grayscale, so one channel */ - if (row_info->bit_depth < 8) - { - png_bytep bp = row; - png_size_t i; - png_byte mask; - png_size_t row_bytes = row_info->rowbytes; - - if (bit_depth->gray == 1 && row_info->bit_depth == 2) - mask = 0x55; - - else if (row_info->bit_depth == 4 && bit_depth->gray == 3) - mask = 0x11; - - else - mask = 0xff; - - for (i = 0; i < row_bytes; i++, bp++) - { - png_uint_16 v; - int j; - - v = *bp; - *bp = 0; - - for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) - { - if (j > 0) - *bp |= (png_byte)((v << j) & 0xff); - - else - *bp |= (png_byte)((v >> (-j)) & mask); - } - } - } - - else if (row_info->bit_depth == 8) - { - png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (i = 0; i < istop; i++, bp++) - { - - png_uint_16 v; - int j; - int c = (int)(i%channels); - - v = *bp; - *bp = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - *bp |= (png_byte)((v << j) & 0xff); - - else - *bp |= (png_byte)((v >> (-j)) & 0xff); - } - } - } - - else - { - png_bytep bp; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (bp = row, i = 0; i < istop; i++) - { - int c = (int)(i%channels); - png_uint_16 value, v; - int j; - - v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); - value = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); - - else - value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); - } - *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)(value & 0xff); - } - } - } -} -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -void /* PRIVATE */ -png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_swap_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from ARGB to RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AARRGGBB to RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from AG to GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AAGG to GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } - } -} -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -void /* PRIVATE */ -png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_invert_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=3; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=6; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *(dp++) = (png_byte)(255 - *(sp++)); - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - *(dp++) = *(sp++); - *(dp++) = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=2; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *(dp++) = (png_byte)(255 - *(sp++)); - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } - } -} -#endif -#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing */ -void /* PRIVATE */ -png_do_write_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_intrapixel"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); - *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } -} -#endif /* PNG_MNG_FEATURES_SUPPORTED */ -#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwutil.c b/WDL/libpng/pngwutil.c deleted file mode 100644 index 64888f7c..00000000 --- a/WDL/libpng/pngwutil.c +++ /dev/null @@ -1,3180 +0,0 @@ - -/* pngwutil.c - utilities to write a PNG file - * - * Last changed in libpng 1.5.6 [November 3, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -/* Place a 32-bit number into a buffer in PNG byte order. We work - * with unsigned numbers for convenience, although one supported - * ancillary chunk uses signed (two's complement) numbers. - */ -void PNGAPI -png_save_uint_32(png_bytep buf, png_uint_32 i) -{ - buf[0] = (png_byte)((i >> 24) & 0xff); - buf[1] = (png_byte)((i >> 16) & 0xff); - buf[2] = (png_byte)((i >> 8) & 0xff); - buf[3] = (png_byte)(i & 0xff); -} - -#ifdef PNG_SAVE_INT_32_SUPPORTED -/* The png_save_int_32 function assumes integers are stored in two's - * complement format. If this isn't the case, then this routine needs to - * be modified to write data in two's complement format. Note that, - * the following works correctly even if png_int_32 has more than 32 bits - * (compare the more complex code required on read for sign extention.) - */ -void PNGAPI -png_save_int_32(png_bytep buf, png_int_32 i) -{ - buf[0] = (png_byte)((i >> 24) & 0xff); - buf[1] = (png_byte)((i >> 16) & 0xff); - buf[2] = (png_byte)((i >> 8) & 0xff); - buf[3] = (png_byte)(i & 0xff); -} -#endif - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -void PNGAPI -png_save_uint_16(png_bytep buf, unsigned int i) -{ - buf[0] = (png_byte)((i >> 8) & 0xff); - buf[1] = (png_byte)(i & 0xff); -} -#endif - -/* Simple function to write the signature. If we have already written - * the magic bytes of the signature, or more likely, the PNG stream is - * being embedded into another stream and doesn't need its own signature, - * we should call png_set_sig_bytes() to tell libpng how many of the - * bytes have already been written. - */ -void PNGAPI -png_write_sig(png_structp png_ptr) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the signature is being written */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; -#endif - - /* Write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (png_size_t)(8 - png_ptr->sig_bytes)); - - if (png_ptr->sig_bytes < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Write the start of a PNG chunk. The type is the chunk type. - * The total_length is the sum of the lengths of all the data you will be - * passing in png_write_chunk_data(). - */ -static void -png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, - png_uint_32 length) -{ - png_byte buf[8]; - -#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) - PNG_CSTRING_FROM_CHUNK(buf, chunk_name); - png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); -#endif - - if (png_ptr == NULL) - return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk header is being written. - * PNG_IO_CHUNK_HDR requires a single I/O call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; -#endif - - /* Write the length and the chunk name */ - png_save_uint_32(buf, length); - png_save_uint_32(buf + 4, chunk_name); - png_write_data(png_ptr, buf, 8); - - /* Put the chunk name into png_ptr->chunk_name */ - png_ptr->chunk_name = chunk_name; - - /* Reset the crc and run it over the chunk name */ - png_reset_crc(png_ptr); - - png_calculate_crc(png_ptr, buf + 4, 4); - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that chunk data will (possibly) be written. - * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; -#endif -} - -void PNGAPI -png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, - png_uint_32 length) -{ - png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); -} - -/* Write the data of a PNG chunk started with png_write_chunk_header(). - * Note that multiple calls to this function are allowed, and that the - * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_header(). - */ -void PNGAPI -png_write_chunk_data(png_structp png_ptr, png_const_bytep data, - png_size_t length) -{ - /* Write the data, and run the CRC over it */ - if (png_ptr == NULL) - return; - - if (data != NULL && length > 0) - { - png_write_data(png_ptr, data, length); - - /* Update the CRC after writing the data, - * in case that the user I/O routine alters it. - */ - png_calculate_crc(png_ptr, data, length); - } -} - -/* Finish a chunk started with png_write_chunk_header(). */ -void PNGAPI -png_write_chunk_end(png_structp png_ptr) -{ - png_byte buf[4]; - - if (png_ptr == NULL) return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk CRC is being written. - * PNG_IO_CHUNK_CRC requires a single I/O function call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -#endif - - /* Write the crc in a single operation */ - png_save_uint_32(buf, png_ptr->crc); - - png_write_data(png_ptr, buf, (png_size_t)4); -} - -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -static void -png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, png_size_t length) -{ - if (png_ptr == NULL) - return; - - /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ - if (length > PNG_UINT_32_MAX) - png_error(png_ptr, "length exceeds PNG maxima"); - - png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); - png_write_chunk_data(png_ptr, data, length); - png_write_chunk_end(png_ptr); -} - -/* This is the API that calls the internal function above. */ -void PNGAPI -png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, - png_const_bytep data, png_size_t length) -{ - png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, - length); -} - -/* Initialize the compressor for the appropriate type of compression. */ -static void -png_zlib_claim(png_structp png_ptr, png_uint_32 state) -{ - if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) - { - /* If already initialized for 'state' do not re-init. */ - if (png_ptr->zlib_state != state) - { - int ret = Z_OK; - png_const_charp who = "-"; - - /* If actually initialized for another state do a deflateEnd. */ - if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) - { - ret = deflateEnd(&png_ptr->zstream); - who = "end"; - png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; - } - - /* zlib itself detects an incomplete state on deflateEnd */ - if (ret == Z_OK) switch (state) - { -# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - case PNG_ZLIB_FOR_TEXT: - ret = deflateInit2(&png_ptr->zstream, - png_ptr->zlib_text_level, png_ptr->zlib_text_method, - png_ptr->zlib_text_window_bits, - png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); - who = "text"; - break; -# endif - - case PNG_ZLIB_FOR_IDAT: - ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, - png_ptr->zlib_method, png_ptr->zlib_window_bits, - png_ptr->zlib_mem_level, png_ptr->zlib_strategy); - who = "IDAT"; - break; - - default: - png_error(png_ptr, "invalid zlib state"); - } - - if (ret == Z_OK) - png_ptr->zlib_state = state; - - else /* an error in deflateEnd or deflateInit2 */ - { - size_t pos = 0; - char msg[64]; - - pos = png_safecat(msg, sizeof msg, pos, - "zlib failed to initialize compressor ("); - pos = png_safecat(msg, sizeof msg, pos, who); - - switch (ret) - { - case Z_VERSION_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") version error"); - break; - - case Z_STREAM_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") stream error"); - break; - - case Z_MEM_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") memory error"); - break; - - default: - pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); - break; - } - - png_error(png_ptr, msg); - } - } - - /* Here on success, claim the zstream: */ - png_ptr->zlib_state |= PNG_ZLIB_IN_USE; - } - - else - png_error(png_ptr, "zstream already in use (internal error)"); -} - -/* The opposite: release the stream. It is also reset, this API will warn on - * error but will not fail. - */ -static void -png_zlib_release(png_structp png_ptr) -{ - if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) - { - int ret = deflateReset(&png_ptr->zstream); - - png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; - - if (ret != Z_OK) - { - png_const_charp err; - PNG_WARNING_PARAMETERS(p) - - switch (ret) - { - case Z_VERSION_ERROR: - err = "version"; - break; - - case Z_STREAM_ERROR: - err = "stream"; - break; - - case Z_MEM_ERROR: - err = "memory"; - break; - - default: - err = "unknown"; - break; - } - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); - png_warning_parameter(p, 2, err); - - if (png_ptr->zstream.msg) - err = png_ptr->zstream.msg; - else - err = "[no zlib message]"; - - png_warning_parameter(p, 3, err); - - png_formatted_warning(png_ptr, p, - "zlib failed to reset compressor: @1(@2): @3"); - } - } - - else - png_warning(png_ptr, "zstream not in use (internal error)"); -} - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -/* This pair of functions encapsulates the operation of (a) compressing a - * text string, and (b) issuing it later as a series of chunk data writes. - * The compression_state structure is shared context for these functions - * set up by the caller in order to make the whole mess thread-safe. - */ - -typedef struct -{ - png_const_bytep input; /* The uncompressed input data */ - png_size_t input_len; /* Its length */ - int num_output_ptr; /* Number of output pointers used */ - int max_output_ptr; /* Size of output_ptr */ - png_bytep *output_ptr; /* Array of pointers to output */ -} compression_state; - -/* Compress given text into storage in the png_ptr structure */ -static int /* PRIVATE */ -png_text_compress(png_structp png_ptr, - png_const_charp text, png_size_t text_len, int compression, - compression_state *comp) -{ - int ret; - - comp->num_output_ptr = 0; - comp->max_output_ptr = 0; - comp->output_ptr = NULL; - comp->input = NULL; - comp->input_len = text_len; - - /* We may just want to pass the text right through */ - if (compression == PNG_TEXT_COMPRESSION_NONE) - { - comp->input = (png_const_bytep)text; - return((int)text_len); - } - - if (compression >= PNG_TEXT_COMPRESSION_LAST) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, - compression); - png_formatted_warning(png_ptr, p, "Unknown compression type @1"); - } - - /* We can't write the chunk until we find out how much data we have, - * which means we need to run the compressor first and save the - * output. This shouldn't be a problem, as the vast majority of - * comments should be reasonable, but we will set up an array of - * malloc'd pointers to be sure. - * - * If we knew the application was well behaved, we could simplify this - * greatly by assuming we can always malloc an output buffer large - * enough to hold the compressed text ((1001 * text_len / 1000) + 12) - * and malloc this directly. The only time this would be a bad idea is - * if we can't malloc more than 64K and we have 64K of random input - * data, or if the input string is incredibly large (although this - * wouldn't cause a failure, just a slowdown due to swapping). - */ - png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); - - /* Set up the compression buffers */ - /* TODO: the following cast hides a potential overflow problem. */ - png_ptr->zstream.avail_in = (uInt)text_len; - - /* NOTE: assume zlib doesn't overwrite the input */ - png_ptr->zstream.next_in = (Bytef *)text; - png_ptr->zstream.avail_out = png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - - /* This is the same compression loop as in png_write_row() */ - do - { - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); - - if (ret != Z_OK) - { - /* Error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - /* Make sure the output array has room */ - if (comp->num_output_ptr >= comp->max_output_ptr) - { - int old_max; - - old_max = comp->max_output_ptr; - comp->max_output_ptr = comp->num_output_ptr + 4; - if (comp->output_ptr != NULL) - { - png_bytepp old_ptr; - - old_ptr = comp->output_ptr; - - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charpp))); - - png_memcpy(comp->output_ptr, old_ptr, old_max - * png_sizeof(png_charp)); - - png_free(png_ptr, old_ptr); - } - else - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charp))); - } - - /* Save the data */ - comp->output_ptr[comp->num_output_ptr] = - (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); - - png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - - comp->num_output_ptr++; - - /* and reset the buffer */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - } - /* Continue until we don't have any more to compress */ - } while (png_ptr->zstream.avail_in); - - /* Finish the compression */ - do - { - /* Tell zlib we are finished */ - ret = deflate(&png_ptr->zstream, Z_FINISH); - - if (ret == Z_OK) - { - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - /* Check to make sure our output array has room */ - if (comp->num_output_ptr >= comp->max_output_ptr) - { - int old_max; - - old_max = comp->max_output_ptr; - comp->max_output_ptr = comp->num_output_ptr + 4; - if (comp->output_ptr != NULL) - { - png_bytepp old_ptr; - - old_ptr = comp->output_ptr; - - /* This could be optimized to realloc() */ - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); - - png_memcpy(comp->output_ptr, old_ptr, - old_max * png_sizeof(png_charp)); - - png_free(png_ptr, old_ptr); - } - - else - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); - } - - /* Save the data */ - comp->output_ptr[comp->num_output_ptr] = - (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); - - png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - - comp->num_output_ptr++; - - /* and reset the buffer pointers */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - } - } - else if (ret != Z_STREAM_END) - { - /* We got an error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - } while (ret != Z_STREAM_END); - - /* Text length is number of buffers plus last buffer */ - text_len = png_ptr->zbuf_size * comp->num_output_ptr; - - if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) - text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; - - return((int)text_len); -} - -/* Ship the compressed text out via chunk writes */ -static void /* PRIVATE */ -png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) -{ - int i; - - /* Handle the no-compression case */ - if (comp->input) - { - png_write_chunk_data(png_ptr, comp->input, comp->input_len); - - return; - } - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - /* The zbuf_size test is because the code below doesn't work if zbuf_size is - * '1'; simply skip it to avoid memory overwrite. - */ - if (comp->input_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1) - { - unsigned int z_cmf; /* zlib compression method and flags */ - - /* Optimize the CMF field in the zlib stream. This hack of the zlib - * stream is compliant to the stream specification. - */ - - if (comp->num_output_ptr) - z_cmf = comp->output_ptr[0][0]; - else - z_cmf = png_ptr->zbuf[0]; - - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) - { - unsigned int z_cinfo; - unsigned int half_z_window_size; - png_size_t uncompressed_text_size = comp->input_len; - - z_cinfo = z_cmf >> 4; - half_z_window_size = 1 << (z_cinfo + 7); - - while (uncompressed_text_size <= half_z_window_size && - half_z_window_size >= 256) - { - z_cinfo--; - half_z_window_size >>= 1; - } - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - if (comp->num_output_ptr) - { - - if (comp->output_ptr[0][0] != z_cmf) - { - int tmp; - - comp->output_ptr[0][0] = (png_byte)z_cmf; - tmp = comp->output_ptr[0][1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - comp->output_ptr[0][1] = (png_byte)tmp; - } - } - else - { - int tmp; - - png_ptr->zbuf[0] = (png_byte)z_cmf; - tmp = png_ptr->zbuf[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - png_ptr->zbuf[1] = (png_byte)tmp; - } - } - - else - png_error(png_ptr, - "Invalid zlib compression method or flags in non-IDAT chunk"); - } -#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ - - /* Write saved output buffers, if any */ - for (i = 0; i < comp->num_output_ptr; i++) - { - png_write_chunk_data(png_ptr, comp->output_ptr[i], - (png_size_t)png_ptr->zbuf_size); - - png_free(png_ptr, comp->output_ptr[i]); - } - - if (comp->max_output_ptr != 0) - png_free(png_ptr, comp->output_ptr); - - /* Write anything left in zbuf */ - if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) - png_write_chunk_data(png_ptr, png_ptr->zbuf, - (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); - - /* Reset zlib for another zTXt/iTXt or image data */ - png_zlib_release(png_ptr); -} -#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. Note that the rest of this code depends upon this - * information being correct. - */ -void /* PRIVATE */ -png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_type, - int interlace_type) -{ - png_byte buf[13]; /* Buffer to store the IHDR info */ - - png_debug(1, "in png_write_IHDR"); - - /* Check that we have valid input data from the application info */ - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: -#ifdef PNG_WRITE_16BIT_SUPPORTED - case 16: -#endif - png_ptr->channels = 1; break; - - default: - png_error(png_ptr, - "Invalid bit depth for grayscale image"); - } - break; - - case PNG_COLOR_TYPE_RGB: -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) -#endif - png_error(png_ptr, "Invalid bit depth for RGB image"); - - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_PALETTE: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: - png_ptr->channels = 1; - break; - - default: - png_error(png_ptr, "Invalid bit depth for paletted image"); - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - if (bit_depth != 8 && bit_depth != 16) - png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); - - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) -#endif - png_error(png_ptr, "Invalid bit depth for RGBA image"); - - png_ptr->channels = 4; - break; - - default: - png_error(png_ptr, "Invalid image color type specified"); - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Invalid compression type specified"); - compression_type = PNG_COMPRESSION_TYPE_BASE; - } - - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && -#endif - filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Invalid filter type specified"); - filter_type = PNG_FILTER_TYPE_BASE; - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - if (interlace_type != PNG_INTERLACE_NONE && - interlace_type != PNG_INTERLACE_ADAM7) - { - png_warning(png_ptr, "Invalid interlace type specified"); - interlace_type = PNG_INTERLACE_ADAM7; - } -#else - interlace_type=PNG_INTERLACE_NONE; -#endif - - /* Save the relevent information */ - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->color_type = (png_byte)color_type; - png_ptr->interlaced = (png_byte)interlace_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - png_ptr->width = width; - png_ptr->height = height; - - png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); - /* Set the usr info, so any transformations can modify it */ - png_ptr->usr_width = png_ptr->width; - png_ptr->usr_bit_depth = png_ptr->bit_depth; - png_ptr->usr_channels = png_ptr->channels; - - /* Pack the header information into the buffer */ - png_save_uint_32(buf, width); - png_save_uint_32(buf + 4, height); - buf[8] = (png_byte)bit_depth; - buf[9] = (png_byte)color_type; - buf[10] = (png_byte)compression_type; - buf[11] = (png_byte)filter_type; - buf[12] = (png_byte)interlace_type; - - /* Write the chunk */ - png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); - - /* Initialize zlib with PNG info */ - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; - png_ptr->zstream.opaque = (voidpf)png_ptr; - - if (!(png_ptr->do_filter)) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8) - png_ptr->do_filter = PNG_FILTER_NONE; - - else - png_ptr->do_filter = PNG_ALL_FILTERS; - } - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) - { - if (png_ptr->do_filter != PNG_FILTER_NONE) - png_ptr->zlib_strategy = Z_FILTERED; - - else - png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; - } - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) - png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) - png_ptr->zlib_mem_level = 8; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) - png_ptr->zlib_window_bits = 15; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) - png_ptr->zlib_method = 8; - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) - png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) - png_ptr->zlib_text_level = png_ptr->zlib_level; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) - png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) - png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) - png_ptr->zlib_text_method = png_ptr->zlib_method; -#else - png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; - png_ptr->zlib_text_level = png_ptr->zlib_level; - png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; - png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; - png_ptr->zlib_text_method = png_ptr->zlib_method; -#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ -#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ - - /* Record that the compressor has not yet been initialized. */ - png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; - - png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ -} - -/* Write the palette. We are careful not to trust png_color to be in the - * correct order for PNG, so people can redefine it to any convenient - * structure. - */ -void /* PRIVATE */ -png_write_PLTE(png_structp png_ptr, png_const_colorp palette, - png_uint_32 num_pal) -{ - png_uint_32 i; - png_const_colorp pal_ptr; - png_byte buf[3]; - - png_debug(1, "in png_write_PLTE"); - - if (( -#ifdef PNG_MNG_FEATURES_SUPPORTED - !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && -#endif - num_pal == 0) || num_pal > 256) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_error(png_ptr, "Invalid number of colors in palette"); - } - - else - { - png_warning(png_ptr, "Invalid number of colors in palette"); - return; - } - } - - if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) - { - png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); - - return; - } - - png_ptr->num_palette = (png_uint_16)num_pal; - png_debug1(3, "num_palette = %d", png_ptr->num_palette); - - png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); -#ifdef PNG_POINTER_INDEXING_SUPPORTED - - for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) - { - buf[0] = pal_ptr->red; - buf[1] = pal_ptr->green; - buf[2] = pal_ptr->blue; - png_write_chunk_data(png_ptr, buf, (png_size_t)3); - } - -#else - /* This is a little slower but some buggy compilers need to do this - * instead - */ - pal_ptr=palette; - - for (i = 0; i < num_pal; i++) - { - buf[0] = pal_ptr[i].red; - buf[1] = pal_ptr[i].green; - buf[2] = pal_ptr[i].blue; - png_write_chunk_data(png_ptr, buf, (png_size_t)3); - } - -#endif - png_write_chunk_end(png_ptr); - png_ptr->mode |= PNG_HAVE_PLTE; -} - -/* Write an IDAT chunk */ -void /* PRIVATE */ -png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_debug(1, "in png_write_IDAT"); - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if (!(png_ptr->mode & PNG_HAVE_IDAT) && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) - { - /* Optimize the CMF field in the zlib stream. This hack of the zlib - * stream is compliant to the stream specification. - */ - unsigned int z_cmf = data[0]; /* zlib compression method and flags */ - - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) - { - /* Avoid memory underflows and multiplication overflows. - * - * The conditions below are practically always satisfied; - * however, they still must be checked. - */ - if (length >= 2 && - png_ptr->height < 16384 && png_ptr->width < 16384) - { - /* Compute the maximum possible length of the datastream */ - - /* Number of pixels, plus for each row a filter byte - * and possibly a padding byte, so increase the maximum - * size to account for these. - */ - unsigned int z_cinfo; - unsigned int half_z_window_size; - png_uint_32 uncompressed_idat_size = png_ptr->height * - ((png_ptr->width * - png_ptr->channels * png_ptr->bit_depth + 15) >> 3); - - /* If it's interlaced, each block of 8 rows is sent as up to - * 14 rows, i.e., 6 additional rows, each with a filter byte - * and possibly a padding byte - */ - if (png_ptr->interlaced) - uncompressed_idat_size += ((png_ptr->height + 7)/8) * - (png_ptr->bit_depth < 8 ? 12 : 6); - - z_cinfo = z_cmf >> 4; - half_z_window_size = 1 << (z_cinfo + 7); - - while (uncompressed_idat_size <= half_z_window_size && - half_z_window_size >= 256) - { - z_cinfo--; - half_z_window_size >>= 1; - } - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - if (data[0] != z_cmf) - { - int tmp; - data[0] = (png_byte)z_cmf; - tmp = data[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - data[1] = (png_byte)tmp; - } - } - } - - else - png_error(png_ptr, - "Invalid zlib compression method or flags in IDAT"); - } -#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ - - png_write_complete_chunk(png_ptr, png_IDAT, data, length); - png_ptr->mode |= PNG_HAVE_IDAT; - - /* Prior to 1.5.4 this code was replicated in every caller (except at the - * end, where it isn't technically necessary). Since this function has - * flushed the data we can safely reset the zlib output buffer here. - */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -} - -/* Write an IEND chunk */ -void /* PRIVATE */ -png_write_IEND(png_structp png_ptr) -{ - png_debug(1, "in png_write_IEND"); - - png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); - png_ptr->mode |= PNG_HAVE_IEND; -} - -#ifdef PNG_WRITE_gAMA_SUPPORTED -/* Write a gAMA chunk */ -void /* PRIVATE */ -png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) -{ - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); -} -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -/* Write a sRGB chunk */ -void /* PRIVATE */ -png_write_sRGB(png_structp png_ptr, int srgb_intent) -{ - png_byte buf[1]; - - png_debug(1, "in png_write_sRGB"); - - if (srgb_intent >= PNG_sRGB_INTENT_LAST) - png_warning(png_ptr, - "Invalid sRGB rendering intent specified"); - - buf[0]=(png_byte)srgb_intent; - png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); -} -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -/* Write an iCCP chunk */ -void /* PRIVATE */ -png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, - png_const_charp profile, int profile_len) -{ - png_size_t name_len; - png_charp new_name; - compression_state comp; - int embedded_profile_len = 0; - - png_debug(1, "in png_write_iCCP"); - - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; - comp.input_len = 0; - - if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) - return; - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_warning(png_ptr, "Unknown compression type in iCCP chunk"); - - if (profile == NULL) - profile_len = 0; - - if (profile_len > 3) - embedded_profile_len = - ((*( (png_const_bytep)profile ))<<24) | - ((*( (png_const_bytep)profile + 1))<<16) | - ((*( (png_const_bytep)profile + 2))<< 8) | - ((*( (png_const_bytep)profile + 3)) ); - - if (embedded_profile_len < 0) - { - png_warning(png_ptr, - "Embedded profile length in iCCP chunk is negative"); - - png_free(png_ptr, new_name); - return; - } - - if (profile_len < embedded_profile_len) - { - png_warning(png_ptr, - "Embedded profile length too large in iCCP chunk"); - - png_free(png_ptr, new_name); - return; - } - - if (profile_len > embedded_profile_len) - { - png_warning(png_ptr, - "Truncating profile to actual length in iCCP chunk"); - - profile_len = embedded_profile_len; - } - - if (profile_len) - profile_len = png_text_compress(png_ptr, profile, - (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); - - /* Make sure we include the NULL after the name and the compression type */ - png_write_chunk_header(png_ptr, png_iCCP, - (png_uint_32)(name_len + profile_len + 2)); - - new_name[name_len + 1] = 0x00; - - png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 2)); - - if (profile_len) - { - comp.input_len = profile_len; - png_write_compressed_data_out(png_ptr, &comp); - } - - png_write_chunk_end(png_ptr); - png_free(png_ptr, new_name); -} -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -/* Write a sPLT chunk */ -void /* PRIVATE */ -png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) -{ - png_size_t name_len; - png_charp new_name; - png_byte entrybuf[10]; - png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); - png_size_t palette_size = entry_size * spalette->nentries; - png_sPLT_entryp ep; -#ifndef PNG_POINTER_INDEXING_SUPPORTED - int i; -#endif - - png_debug(1, "in png_write_sPLT"); - - if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) - return; - - /* Make sure we include the NULL after the name */ - png_write_chunk_header(png_ptr, png_sPLT, - (png_uint_32)(name_len + 2 + palette_size)); - - png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 1)); - - png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); - - /* Loop through each palette entry, writing appropriately */ -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (ep = spalette->entries; epentries + spalette->nentries; ep++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep->red; - entrybuf[1] = (png_byte)ep->green; - entrybuf[2] = (png_byte)ep->blue; - entrybuf[3] = (png_byte)ep->alpha; - png_save_uint_16(entrybuf + 4, ep->frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep->red); - png_save_uint_16(entrybuf + 2, ep->green); - png_save_uint_16(entrybuf + 4, ep->blue); - png_save_uint_16(entrybuf + 6, ep->alpha); - png_save_uint_16(entrybuf + 8, ep->frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); - } -#else - ep=spalette->entries; - for (i = 0; i>spalette->nentries; i++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep[i].red; - entrybuf[1] = (png_byte)ep[i].green; - entrybuf[2] = (png_byte)ep[i].blue; - entrybuf[3] = (png_byte)ep[i].alpha; - png_save_uint_16(entrybuf + 4, ep[i].frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep[i].red); - png_save_uint_16(entrybuf + 2, ep[i].green); - png_save_uint_16(entrybuf + 4, ep[i].blue); - png_save_uint_16(entrybuf + 6, ep[i].alpha); - png_save_uint_16(entrybuf + 8, ep[i].frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); - } -#endif - - png_write_chunk_end(png_ptr); - png_free(png_ptr, new_name); -} -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -/* Write the sBIT chunk */ -void /* PRIVATE */ -png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) -{ - png_byte buf[4]; - png_size_t size; - - png_debug(1, "in png_write_sBIT"); - - /* Make sure we don't depend upon the order of PNG_COLOR_8 */ - if (color_type & PNG_COLOR_MASK_COLOR) - { - png_byte maxbits; - - maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : - png_ptr->usr_bit_depth); - - if (sbit->red == 0 || sbit->red > maxbits || - sbit->green == 0 || sbit->green > maxbits || - sbit->blue == 0 || sbit->blue > maxbits) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->red; - buf[1] = sbit->green; - buf[2] = sbit->blue; - size = 3; - } - - else - { - if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->gray; - size = 1; - } - - if (color_type & PNG_COLOR_MASK_ALPHA) - { - if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[size++] = sbit->alpha; - } - - png_write_complete_chunk(png_ptr, png_sBIT, buf, size); -} -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -/* Write the cHRM chunk */ -void /* PRIVATE */ -png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, - png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, - png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, - png_fixed_point blue_y) -{ - png_byte buf[32]; - - png_debug(1, "in png_write_cHRM"); - - /* Each value is saved in 1/100,000ths */ -#ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, - green_x, green_y, blue_x, blue_y)) -#endif - { - png_save_uint_32(buf, (png_uint_32)white_x); - png_save_uint_32(buf + 4, (png_uint_32)white_y); - - png_save_uint_32(buf + 8, (png_uint_32)red_x); - png_save_uint_32(buf + 12, (png_uint_32)red_y); - - png_save_uint_32(buf + 16, (png_uint_32)green_x); - png_save_uint_32(buf + 20, (png_uint_32)green_y); - - png_save_uint_32(buf + 24, (png_uint_32)blue_x); - png_save_uint_32(buf + 28, (png_uint_32)blue_y); - - png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); - } -} -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -/* Write the tRNS chunk */ -void /* PRIVATE */ -png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, - png_const_color_16p tran, int num_trans, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_tRNS"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) - { - png_warning(png_ptr, "Invalid number of transparent colors specified"); - return; - } - - /* Write the chunk out as it is */ - png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); - } - - else if (color_type == PNG_COLOR_TYPE_GRAY) - { - /* One 16 bit value */ - if (tran->gray >= (1 << png_ptr->bit_depth)) - { - png_warning(png_ptr, - "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, tran->gray); - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); - } - - else if (color_type == PNG_COLOR_TYPE_RGB) - { - /* Three 16 bit values */ - png_save_uint_16(buf, tran->red); - png_save_uint_16(buf + 2, tran->green); - png_save_uint_16(buf + 4, tran->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) -#else - if (buf[0] | buf[2] | buf[4]) -#endif - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); - return; - } - - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); - } - - else - { - png_warning(png_ptr, "Can't write tRNS with an alpha channel"); - } -} -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -/* Write the background chunk */ -void /* PRIVATE */ -png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_bKGD"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->num_palette || - (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && -#endif - back->index >= png_ptr->num_palette) - { - png_warning(png_ptr, "Invalid background palette index"); - return; - } - - buf[0] = back->index; - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); - } - - else if (color_type & PNG_COLOR_MASK_COLOR) - { - png_save_uint_16(buf, back->red); - png_save_uint_16(buf + 2, back->green); - png_save_uint_16(buf + 4, back->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) -#else - if (buf[0] | buf[2] | buf[4]) -#endif - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); - - return; - } - - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); - } - - else - { - if (back->gray >= (1 << png_ptr->bit_depth)) - { - png_warning(png_ptr, - "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, back->gray); - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); - } -} -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -/* Write the histogram */ -void /* PRIVATE */ -png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) -{ - int i; - png_byte buf[3]; - - png_debug(1, "in png_write_hIST"); - - if (num_hist > (int)png_ptr->num_palette) - { - png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, - png_ptr->num_palette); - - png_warning(png_ptr, "Invalid number of histogram entries specified"); - return; - } - - png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); - - for (i = 0; i < num_hist; i++) - { - png_save_uint_16(buf, hist[i]); - png_write_chunk_data(png_ptr, buf, (png_size_t)2); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ - defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The new_key is allocated to hold the corrected keyword and must be freed - * by the calling routine. This avoids problems with trying to write to - * static keywords without having to have duplicate copies of the strings. - */ -png_size_t /* PRIVATE */ -png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) -{ - png_size_t key_len; - png_const_charp ikp; - png_charp kp, dp; - int kflag; - int kwarn=0; - - png_debug(1, "in png_check_keyword"); - - *new_key = NULL; - - if (key == NULL || (key_len = png_strlen(key)) == 0) - { - png_warning(png_ptr, "zero length keyword"); - return ((png_size_t)0); - } - - png_debug1(2, "Keyword to be checked is '%s'", key); - - *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); - - if (*new_key == NULL) - { - png_warning(png_ptr, "Out of memory while procesing keyword"); - return ((png_size_t)0); - } - - /* Replace non-printing characters with a blank and print a warning */ - for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) - { - if ((png_byte)*ikp < 0x20 || - ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, - (png_byte)*ikp); - png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); - *dp = ' '; - } - - else - { - *dp = *ikp; - } - } - *dp = '\0'; - - /* Remove any trailing white space. */ - kp = *new_key + key_len - 1; - if (*kp == ' ') - { - png_warning(png_ptr, "trailing spaces removed from keyword"); - - while (*kp == ' ') - { - *(kp--) = '\0'; - key_len--; - } - } - - /* Remove any leading white space. */ - kp = *new_key; - if (*kp == ' ') - { - png_warning(png_ptr, "leading spaces removed from keyword"); - - while (*kp == ' ') - { - kp++; - key_len--; - } - } - - png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); - - /* Remove multiple internal spaces. */ - for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) - { - if (*kp == ' ' && kflag == 0) - { - *(dp++) = *kp; - kflag = 1; - } - - else if (*kp == ' ') - { - key_len--; - kwarn = 1; - } - - else - { - *(dp++) = *kp; - kflag = 0; - } - } - *dp = '\0'; - if (kwarn) - png_warning(png_ptr, "extra interior spaces removed from keyword"); - - if (key_len == 0) - { - png_free(png_ptr, *new_key); - png_warning(png_ptr, "Zero length keyword"); - } - - if (key_len > 79) - { - png_warning(png_ptr, "keyword length must be 1 - 79 characters"); - (*new_key)[79] = '\0'; - key_len = 79; - } - - return (key_len); -} -#endif - -#ifdef PNG_WRITE_tEXt_SUPPORTED -/* Write a tEXt chunk */ -void /* PRIVATE */ -png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len) -{ - png_size_t key_len; - png_charp new_key; - - png_debug(1, "in png_write_tEXt"); - - if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) - return; - - if (text == NULL || *text == '\0') - text_len = 0; - - else - text_len = png_strlen(text); - - /* Make sure we include the 0 after the key */ - png_write_chunk_header(png_ptr, png_tEXt, - (png_uint_32)(key_len + text_len + 1)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, - (png_size_t)(key_len + 1)); - - if (text_len) - png_write_chunk_data(png_ptr, (png_const_bytep)text, - (png_size_t)text_len); - - png_write_chunk_end(png_ptr); - png_free(png_ptr, new_key); -} -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -/* Write a compressed text chunk */ -void /* PRIVATE */ -png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len, int compression) -{ - png_size_t key_len; - png_byte buf; - png_charp new_key; - compression_state comp; - - png_debug(1, "in png_write_zTXt"); - - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; - comp.input_len = 0; - - if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) - { - png_free(png_ptr, new_key); - return; - } - - if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) - { - png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); - png_free(png_ptr, new_key); - return; - } - - text_len = png_strlen(text); - - /* Compute the compressed data; do it now for the length */ - text_len = png_text_compress(png_ptr, text, text_len, compression, - &comp); - - /* Write start of chunk */ - png_write_chunk_header(png_ptr, png_zTXt, - (png_uint_32)(key_len+text_len + 2)); - - /* Write key */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, - (png_size_t)(key_len + 1)); - - png_free(png_ptr, new_key); - - buf = (png_byte)compression; - - /* Write compression */ - png_write_chunk_data(png_ptr, &buf, (png_size_t)1); - - /* Write the compressed data */ - comp.input_len = text_len; - png_write_compressed_data_out(png_ptr, &comp); - - /* Close the chunk */ - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -/* Write an iTXt chunk */ -void /* PRIVATE */ -png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, - png_const_charp lang, png_const_charp lang_key, png_const_charp text) -{ - png_size_t lang_len, key_len, lang_key_len, text_len; - png_charp new_lang; - png_charp new_key = NULL; - png_byte cbuf[2]; - compression_state comp; - - png_debug(1, "in png_write_iTXt"); - - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; - - if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) - return; - - if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) - { - png_warning(png_ptr, "Empty language field in iTXt chunk"); - new_lang = NULL; - lang_len = 0; - } - - if (lang_key == NULL) - lang_key_len = 0; - - else - lang_key_len = png_strlen(lang_key); - - if (text == NULL) - text_len = 0; - - else - text_len = png_strlen(text); - - /* Compute the compressed data; do it now for the length */ - text_len = png_text_compress(png_ptr, text, text_len, compression - 2, - &comp); - - - /* Make sure we include the compression flag, the compression byte, - * and the NULs after the key, lang, and lang_key parts - */ - - png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)( - 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ - + key_len - + lang_len - + lang_key_len - + text_len)); - - /* We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); - - /* Set the compression flag */ - if (compression == PNG_ITXT_COMPRESSION_NONE || - compression == PNG_TEXT_COMPRESSION_NONE) - cbuf[0] = 0; - - else /* compression == PNG_ITXT_COMPRESSION_zTXt */ - cbuf[0] = 1; - - /* Set the compression method */ - cbuf[1] = 0; - - png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); - - cbuf[0] = 0; - png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), - (png_size_t)(lang_len + 1)); - - png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), - (png_size_t)(lang_key_len + 1)); - - png_write_compressed_data_out(png_ptr, &comp); - - png_write_chunk_end(png_ptr); - - png_free(png_ptr, new_key); - png_free(png_ptr, new_lang); -} -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -/* Write the oFFs chunk */ -void /* PRIVATE */ -png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_oFFs"); - - if (unit_type >= PNG_OFFSET_LAST) - png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); - - png_save_int_32(buf, x_offset); - png_save_int_32(buf + 4, y_offset); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); -} -#endif -#ifdef PNG_WRITE_pCAL_SUPPORTED -/* Write the pCAL chunk (described in the PNG extensions document) */ -void /* PRIVATE */ -png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, - png_int_32 X1, int type, int nparams, png_const_charp units, - png_charpp params) -{ - png_size_t purpose_len, units_len, total_len; - png_size_tp params_len; - png_byte buf[10]; - png_charp new_purpose; - int i; - - png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); - - if (type >= PNG_EQUATION_LAST) - png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); - - purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; - png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); - units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d", (int)units_len); - total_len = purpose_len + units_len + 10; - - params_len = (png_size_tp)png_malloc(png_ptr, - (png_alloc_size_t)(nparams * png_sizeof(png_size_t))); - - /* Find the length of each parameter, making sure we don't count the - * null terminator for the last parameter. - */ - for (i = 0; i < nparams; i++) - { - params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); - png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long)params_len[i]); - total_len += params_len[i]; - } - - png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); - png_save_int_32(buf, X0); - png_save_int_32(buf + 4, X1); - buf[8] = (png_byte)type; - buf[9] = (png_byte)nparams; - png_write_chunk_data(png_ptr, buf, (png_size_t)10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); - - png_free(png_ptr, new_purpose); - - for (i = 0; i < nparams; i++) - { - png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); - } - - png_free(png_ptr, params_len); - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -/* Write the sCAL chunk */ -void /* PRIVATE */ -png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, - png_const_charp height) -{ - png_byte buf[64]; - png_size_t wlen, hlen, total_len; - - png_debug(1, "in png_write_sCAL_s"); - - wlen = png_strlen(width); - hlen = png_strlen(height); - total_len = wlen + hlen + 2; - - if (total_len > 64) - { - png_warning(png_ptr, "Can't write sCAL (buffer too small)"); - return; - } - - buf[0] = (png_byte)unit; - png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ - png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); -} -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -/* Write the pHYs chunk */ -void /* PRIVATE */ -png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_pHYs"); - - if (unit_type >= PNG_RESOLUTION_LAST) - png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); - - png_save_uint_32(buf, x_pixels_per_unit); - png_save_uint_32(buf + 4, y_pixels_per_unit); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); -} -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -/* Write the tIME chunk. Use either png_convert_from_struct_tm() - * or png_convert_from_time_t(), or fill in the structure yourself. - */ -void /* PRIVATE */ -png_write_tIME(png_structp png_ptr, png_const_timep mod_time) -{ - png_byte buf[7]; - - png_debug(1, "in png_write_tIME"); - - if (mod_time->month > 12 || mod_time->month < 1 || - mod_time->day > 31 || mod_time->day < 1 || - mod_time->hour > 23 || mod_time->second > 60) - { - png_warning(png_ptr, "Invalid time specified for tIME chunk"); - return; - } - - png_save_uint_16(buf, mod_time->year); - buf[2] = mod_time->month; - buf[3] = mod_time->day; - buf[4] = mod_time->hour; - buf[5] = mod_time->minute; - buf[6] = mod_time->second; - - png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); -} -#endif - -/* Initializes the row writing capability of libpng */ -void /* PRIVATE */ -png_write_start_row(png_structp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - png_alloc_size_t buf_size; - int usr_pixel_depth; - - png_debug(1, "in png_write_start_row"); - - usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; - buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; - - /* 1.5.6: added to allow checking in the row write code. */ - png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; - png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; - - /* Set up row buffer */ - png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); - - png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - /* Set up filtering buffer, if using this filter */ - if (png_ptr->do_filter & PNG_FILTER_SUB) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); - - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; - } - - /* We only need to keep the previous row if we are using one of these. */ - if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) - { - /* Set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); - - if (png_ptr->do_filter & PNG_FILTER_UP) - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } - - if (png_ptr->do_filter & PNG_FILTER_AVG) - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - - if (png_ptr->do_filter & PNG_FILTER_PAETH) - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, we need to set up width and height of pass */ - if (png_ptr->interlaced) - { - if (!(png_ptr->transformations & PNG_INTERLACE)) - { - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - - png_pass_start[0]) / png_pass_inc[0]; - } - - else - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } - } - - else -#endif - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } - - png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; -} - -/* Internal use only. Called when finished processing a row of data. */ -void /* PRIVATE */ -png_write_finish_row(png_structp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - int ret; - - png_debug(1, "in png_write_finish_row"); - - /* Next row */ - png_ptr->row_number++; - - /* See if we are done */ - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, go to next pass */ - if (png_ptr->interlaced) - { - png_ptr->row_number = 0; - if (png_ptr->transformations & PNG_INTERLACE) - { - png_ptr->pass++; - } - - else - { - /* Loop until we find a non-zero width or height pass */ - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->usr_width = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - if (png_ptr->transformations & PNG_INTERLACE) - break; - - } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); - - } - - /* Reset the row above the image for the next pass */ - if (png_ptr->pass < 7) - { - if (png_ptr->prev_row != NULL) - png_memset(png_ptr->prev_row, 0, - (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* - png_ptr->usr_bit_depth, png_ptr->width)) + 1); - - return; - } - } -#endif - - /* If we get here, we've just written the last row, so we need - to flush the compressor */ - do - { - /* Tell the compressor we are done */ - ret = deflate(&png_ptr->zstream, Z_FINISH); - - /* Check for an error */ - if (ret == Z_OK) - { - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - } - } - - else if (ret != Z_STREAM_END) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - } while (ret != Z_STREAM_END); - - /* Write any extra space */ - if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) - { - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - - png_ptr->zstream.avail_out); - } - - png_zlib_release(png_ptr); - png_ptr->zstream.data_type = Z_BINARY; -} - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Pick out the correct pixels for the interlace pass. - * The basic idea here is to go through the row with a source - * pointer and a destination pointer (sp and dp), and copy the - * correct pixels for the pass. As the row gets compacted, - * sp will always be >= dp, so we should never overwrite anything. - * See the default: case for the easiest code to understand. - */ -void /* PRIVATE */ -png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_write_interlace"); - - /* We don't have to do anything on the last pass (6) */ - if (pass < 6) - { - /* Each pixel depth is handled separately */ - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp; - png_bytep dp; - int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - d = 0; - shift = 7; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (png_size_t)(i >> 3); - value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; - d |= (value << shift); - - if (shift == 0) - { - shift = 7; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift--; - - } - if (shift != 7) - *dp = (png_byte)d; - - break; - } - - case 2: - { - png_bytep sp; - png_bytep dp; - int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 6; - d = 0; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (png_size_t)(i >> 2); - value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; - d |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 2; - } - if (shift != 6) - *dp = (png_byte)d; - - break; - } - - case 4: - { - png_bytep sp; - png_bytep dp; - int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 4; - d = 0; - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (png_size_t)(i >> 1); - value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; - d |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 4; - } - if (shift != 4) - *dp = (png_byte)d; - - break; - } - - default: - { - png_bytep sp; - png_bytep dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - png_size_t pixel_bytes; - - /* Start at the beginning */ - dp = row; - - /* Find out how many bytes each pixel takes up */ - pixel_bytes = (row_info->pixel_depth >> 3); - - /* Loop through the row, only looking at the pixels that matter */ - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - /* Find out where the original pixel is */ - sp = row + (png_size_t)i * pixel_bytes; - - /* Move the pixel */ - if (dp != sp) - png_memcpy(dp, sp, pixel_bytes); - - /* Next pixel */ - dp += pixel_bytes; - } - break; - } - } - /* Set new row width */ - row_info->width = (row_info->width + - png_pass_inc[pass] - 1 - - png_pass_start[pass]) / - png_pass_inc[pass]; - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - -/* This filters the row, chooses which filter to use, if it has not already - * been specified by the application, and then writes the row out with the - * chosen filter. - */ -static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, - png_size_t row_bytes); - -#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) -#define PNG_HISHIFT 10 -#define PNG_LOMASK ((png_uint_32)0xffffL) -#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) -void /* PRIVATE */ -png_write_find_filter(png_structp png_ptr, png_row_infop row_info) -{ - png_bytep best_row; -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_bytep prev_row, row_buf; - png_uint_32 mins, bpp; - png_byte filter_to_do = png_ptr->do_filter; - png_size_t row_bytes = row_info->rowbytes; -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - int num_p_filters = png_ptr->num_prev_filters; -#endif - - png_debug(1, "in png_write_find_filter"); - -#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) - { - /* These will never be selected so we need not test them. */ - filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); - } -#endif - - /* Find out how many bytes offset each pixel is */ - bpp = (row_info->pixel_depth + 7) >> 3; - - prev_row = png_ptr->prev_row; -#endif - best_row = png_ptr->row_buf; -#ifdef PNG_WRITE_FILTER_SUPPORTED - row_buf = best_row; - mins = PNG_MAXSUM; - - /* The prediction method we use is to find which method provides the - * smallest value when summing the absolute values of the distances - * from zero, using anything >= 128 as negative numbers. This is known - * as the "minimum sum of absolute differences" heuristic. Other - * heuristics are the "weighted minimum sum of absolute differences" - * (experimental and can in theory improve compression), and the "zlib - * predictive" method (not implemented yet), which does test compressions - * of lines using different filter methods, and then chooses the - * (series of) filter(s) that give minimum compressed data size (VERY - * computationally expensive). - * - * GRR 980525: consider also - * - * (1) minimum sum of absolute differences from running average (i.e., - * keep running sum of non-absolute differences & count of bytes) - * [track dispersion, too? restart average if dispersion too large?] - * - * (1b) minimum sum of absolute differences from sliding average, probably - * with window size <= deflate window (usually 32K) - * - * (2) minimum sum of squared differences from zero or running average - * (i.e., ~ root-mean-square approach) - */ - - - /* We don't need to test the 'no filter' case if this is the only filter - * that has been chosen, as it doesn't actually do anything to the data. - */ - if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) - { - png_bytep rp; - png_uint_32 sum = 0; - png_size_t i; - int v; - - for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) - { - v = *rp; - sum += (v < 128) ? v : 256 - v; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - png_uint_32 sumhi, sumlo; - int j; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ - - /* Reduce the sum if we match any of the previous rows */ - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - /* Factor in the cost of this filter (this is here for completeness, - * but it makes no sense to have a "cost" for the NONE filter, as - * it has the minimum possible computational cost - none). - */ - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif - mins = sum; - } - - /* Sub filter */ - if (filter_to_do == PNG_FILTER_SUB) - /* It's the only filter so no testing is needed */ - { - png_bytep rp, lp, dp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; - i++, rp++, dp++) - { - *dp = *rp; - } - - for (lp = row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); - } - - best_row = png_ptr->sub_row; - } - - else if (filter_to_do & PNG_FILTER_SUB) - { - png_bytep rp, dp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* We temporarily increase the "minimum sum" by the factor we - * would reduce the sum of this filter, so that we can do the - * early exit comparison without scaling the sum each time. - */ - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; - i++, rp++, dp++) - { - v = *dp = *rp; - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) - { - sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->sub_row; - } - } - - /* Up filter */ - if (filter_to_do == PNG_FILTER_UP) - { - png_bytep rp, dp, pp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); - } - - best_row = png_ptr->up_row; - } - - else if (filter_to_do & PNG_FILTER_UP) - { - png_bytep rp, dp, pp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; - - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->up_row; - } - } - - /* Avg filter */ - if (filter_to_do == PNG_FILTER_AVG) - { - png_bytep rp, dp, pp, lp; - png_uint_32 i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - } - - for (lp = row_buf + 1; i < row_bytes; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) - & 0xff); - } - best_row = png_ptr->avg_row; - } - - else if (filter_to_do & PNG_FILTER_AVG) - { - png_bytep rp, dp, pp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1; i < row_bytes; i++) - { - v = *dp++ = - (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->avg_row; - } - } - - /* Paeth filter */ - if (filter_to_do == PNG_FILTER_PAETH) - { - png_bytep rp, dp, pp, cp, lp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - } - - for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - } - best_row = png_ptr->paeth_row; - } - - else if (filter_to_do & PNG_FILTER_PAETH) - { - png_bytep rp, dp, pp, cp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - -#ifndef PNG_SLOW_PAETH - p = b - c; - pc = a - c; -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; -#else /* PNG_SLOW_PAETH */ - p = a + b - c; - pa = abs(p - a); - pb = abs(p - b); - pc = abs(p - c); - - if (pa <= pb && pa <= pc) - p = a; - - else if (pb <= pc) - p = b; - - else - p = c; -#endif /* PNG_SLOW_PAETH */ - - v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif - - if (sum < mins) - { - best_row = png_ptr->paeth_row; - } - } -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - - /* Do the actual writing of the filtered row data from the chosen filter. */ - png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); - -#ifdef PNG_WRITE_FILTER_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* Save the type of filter we picked this time for future calculations */ - if (png_ptr->num_prev_filters > 0) - { - int j; - - for (j = 1; j < num_p_filters; j++) - { - png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; - } - - png_ptr->prev_filters[j] = best_row[0]; - } -#endif -#endif /* PNG_WRITE_FILTER_SUPPORTED */ -} - - -/* Do the actual writing of a previously filtered row. */ -static void -png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, - png_size_t avail/*includes filter byte*/) -{ - png_debug(1, "in png_write_filtered_row"); - - png_debug1(2, "filter = %d", filtered_row[0]); - /* Set up the zlib input buffer */ - - png_ptr->zstream.next_in = filtered_row; - png_ptr->zstream.avail_in = 0; - /* Repeat until we have compressed all the data */ - do - { - int ret; /* Return of zlib */ - - /* Record the number of bytes available - zlib supports at least 65535 - * bytes at one step, depending on the size of the zlib type 'uInt', the - * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). - * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. - * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a - * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called - * with smaller chunks of data. - */ - if (png_ptr->zstream.avail_in == 0) - { - if (avail > ZLIB_IO_MAX) - { - png_ptr->zstream.avail_in = ZLIB_IO_MAX; - avail -= ZLIB_IO_MAX; - } - - else - { - /* So this will fit in the available uInt space: */ - png_ptr->zstream.avail_in = (uInt)avail; - avail = 0; - } - } - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); - - /* Check for compression errors */ - if (ret != Z_OK) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - - /* See if it is time to write another IDAT */ - if (!(png_ptr->zstream.avail_out)) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - } - /* Repeat until all data has been compressed */ - } while (avail > 0 || png_ptr->zstream.avail_in > 0); - - /* Swap the current and previous rows */ - if (png_ptr->prev_row != NULL) - { - png_bytep tptr; - - tptr = png_ptr->prev_row; - png_ptr->prev_row = png_ptr->row_buf; - png_ptr->row_buf = tptr; - } - - /* Finish row - updates counters and flushes zlib if last row */ - png_write_finish_row(png_ptr); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->flush_rows++; - - if (png_ptr->flush_dist > 0 && - png_ptr->flush_rows >= png_ptr->flush_dist) - { - png_write_flush(png_ptr); - } -#endif -} -#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/lice/Makefile b/WDL/lice/Makefile deleted file mode 100644 index 19c3ff10..00000000 --- a/WDL/lice/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -CFLAGS=-O2 -s -D_LICE_NO_SYSBITMAPS_ -CC=gcc -CXX=g++ -WDL_PATH=.. - -CXXFLAGS=$(CFLAGS) - -vpath %.c $(WDL_PATH)/zlib $(WDL_PATH)/libpng $(WDL_PATH)/jpeglib $(WDL_PATH)/giflib -vpath %.cpp test/ - -ZLIB_OBJS = compress.o adler32.o crc32.o deflate.o gzio.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o unzip.o ioapi.o zip.o unzip.o - -PNGLIB_OBJS = png.o pngerror.o pngget.o pngmem.o pngpread.o pngread.o pngrio.o pngrtran.o pngrutil.o pngset.o pngtrans.o - -JPEGLIB_OBJS = jcomapi.o jdapimin.o jdapistd.o jdatadst.o jdatasrc.o jdcoefct.o jdcolor.o jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o \ - jdmaster.o jdmerge.o jdphuff.o jdpostct.o jdsample.o jerror.o jfdctflt.o jfdctfst.o jfdctint.o jidctflt.o jidctfst.o jidctint.o \ - jidctred.o jmemmgr.o jmemnobs.o jquant1.o jquant2.o jutils.o - -GIFLIB_OBJS = dgif_lib.o egif_lib.o gifalloc.o gif_hash.o - -LICEOBJS = lice.o lice_gif.o lice_gif_write.o lice_image.o lice_jpg.o lice_png.o lice_palette.o - -imgs2gif: $(LICEOBJS) $(JPEGLIB_OBJS) $(PNGLIB_OBJS) $(ZLIB_OBJS) $(GIFLIB_OBJS) imgs2gif.o - $(CXX) $(CFLAGS) -o $@ $^ diff --git a/WDL/lice/glew/include/GL/WGLEXT.H b/WDL/lice/glew/include/GL/WGLEXT.H deleted file mode 100644 index 989d86a2..00000000 --- a/WDL/lice/glew/include/GL/WGLEXT.H +++ /dev/null @@ -1,631 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: This software was created using the -** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has -** not been independently verified as being compliant with the OpenGL(R) -** version 1.2.1 Specification. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number */ -/* wglext.h last updated 2005/01/07 */ -/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ -#define WGL_WGLEXT_VERSION 6 - -#ifndef WGL_ARB_buffer_region -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -#endif - -#ifndef WGL_ARB_multisample -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif - -#ifndef WGL_ARB_extensions_string -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -#endif - -#ifndef WGL_ARB_pixel_format_float -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 -#endif - -#ifndef WGL_EXT_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -#endif - -#ifndef WGL_I3D_gamma -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -#endif - -#ifndef WGL_I3D_genlock -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -#endif - -#ifndef WGL_I3D_swap_frame_lock -#endif - -#ifndef WGL_NV_render_depth_texture -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif - -#ifndef WGL_ATI_pixel_format_float -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#endif - -#ifndef WGL_NV_float_buffer -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif - - -/*************************************************************/ - -#ifndef WGL_ARB_pbuffer -DECLARE_HANDLE(HPBUFFERARB); -#endif -#ifndef WGL_EXT_pbuffer -DECLARE_HANDLE(HPBUFFEREXT); -#endif - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); -extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); -extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); -extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#endif - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringARB (HDC); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCARB (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); -extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); -extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); -extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); -extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); -extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 -#endif - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); -extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); -extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); -extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#endif - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#endif - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); -extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); -extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); -extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglSwapIntervalEXT (int); -extern int WINAPI wglGetSwapIntervalEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#endif - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); -extern void WINAPI wglFreeMemoryNV (void *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#endif - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); -extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); -extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); -extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); -extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); -extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); -extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#endif - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); -extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); -extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); -extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableGenlockI3D (HDC); -extern BOOL WINAPI wglDisableGenlockI3D (HDC); -extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); -extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); -extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); -extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); -extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); -extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); -extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); -extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#endif - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableFrameLockI3D (void); -extern BOOL WINAPI wglDisableFrameLockI3D (void); -extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); -extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#endif - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetFrameUsageI3D (float *); -extern BOOL WINAPI wglBeginFrameTrackingI3D (void); -extern BOOL WINAPI wglEndFrameTrackingI3D (void); -extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 -#endif - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/WDL/lice/glew/include/GL/glew.h b/WDL/lice/glew/include/GL/glew.h deleted file mode 100644 index 0de2efc3..00000000 --- a/WDL/lice/glew/include/GL/glew.h +++ /dev/null @@ -1,12262 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __glew_h__ -#define __glew_h__ -#define __GLEW_H__ - -#if defined(__gl_h_) || defined(__GL_H__) -#error gl.h included before glew.h -#endif -#if defined(__glext_h_) || defined(__GLEXT_H_) -#error glext.h included before glew.h -#endif -#if defined(__gl_ATI_h_) -#error glATI.h included before glew.h -#endif - -#define __gl_h_ -#define __GL_H__ -#define __glext_h_ -#define __GLEXT_H_ -#define __gl_ATI_h_ - -#if defined(_WIN32) - -/* - * GLEW does not include to avoid name space pollution. - * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t - * defined properly. - */ -/* */ -#ifndef APIENTRY -#define GLEW_APIENTRY_DEFINED -# if defined(__MINGW32__) -# define APIENTRY __stdcall -# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) -# define APIENTRY __stdcall -# else -# define APIENTRY -# endif -#endif -#ifndef GLAPI -# if defined(__MINGW32__) -# define GLAPI extern -# endif -#endif -/* */ -#ifndef CALLBACK -#define GLEW_CALLBACK_DEFINED -# if defined(__MINGW32__) -# define CALLBACK __attribute__ ((__stdcall__)) -# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) -# define CALLBACK __stdcall -# else -# define CALLBACK -# endif -#endif -/* and */ -#ifndef WINGDIAPI -#define GLEW_WINGDIAPI_DEFINED -#define WINGDIAPI __declspec(dllimport) -#endif -/* */ -#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) -typedef unsigned short wchar_t; -# define _WCHAR_T_DEFINED -#endif -/* */ -#if !defined(_W64) -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif -#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) -# ifdef _WIN64 -typedef __int64 ptrdiff_t; -# else -typedef _W64 int ptrdiff_t; -# endif -# define _PTRDIFF_T_DEFINED -# define _PTRDIFF_T_ -#endif - -#ifndef GLAPI -# if defined(__MINGW32__) -# define GLAPI extern -# else -# define GLAPI WINGDIAPI -# endif -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY APIENTRY -#endif - -/* - * GLEW_STATIC needs to be set when using the static version. - * GLEW_BUILD is set when building the DLL version. - */ -#ifdef GLEW_STATIC -# define GLEWAPI extern -#else -# ifdef GLEW_BUILD -# define GLEWAPI extern __declspec(dllexport) -# else -# define GLEWAPI extern __declspec(dllimport) -# endif -#endif - -#else /* _UNIX */ - -/* - * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO - * C. On my system, this amounts to _3 lines_ of included code, all of - * them pretty much harmless. If you know of a way of detecting 32 vs - * 64 _targets_ at compile time you are free to replace this with - * something that's portable. For now, _this_ is the portable solution. - * (mem, 2004-01-04) - */ - -#include -#include - -#define GLEW_APIENTRY_DEFINED -#define APIENTRY -#define GLEWAPI extern - -/* */ -#ifndef GLAPI -#define GLAPI extern -#endif -#ifndef GLAPIENTRY -#define GLAPIENTRY -#endif - -#endif /* _WIN32 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ - -#ifndef GL_VERSION_1_1 -#define GL_VERSION_1_1 1 - -typedef unsigned int GLenum; -typedef unsigned int GLbitfield; -typedef unsigned int GLuint; -typedef int GLint; -typedef int GLsizei; -typedef unsigned char GLboolean; -typedef signed char GLbyte; -typedef short GLshort; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; -typedef unsigned long GLulong; -typedef float GLfloat; -typedef float GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void GLvoid; -#if defined(_MSC_VER) -# if _MSC_VER < 1400 -typedef __int64 GLint64EXT; -typedef unsigned __int64 GLuint64EXT; -# else -typedef signed long long GLint64EXT; -typedef unsigned long long GLuint64EXT; -# endif -#else -# if defined(__MINGW32__) -#include -# endif -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif - -#define GL_ACCUM 0x0100 -#define GL_LOAD 0x0101 -#define GL_RETURN 0x0102 -#define GL_MULT 0x0103 -#define GL_ADD 0x0104 -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_CURRENT_BIT 0x00000001 -#define GL_POINT_BIT 0x00000002 -#define GL_LINE_BIT 0x00000004 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_HINT_BIT 0x00008000 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0x000fffff -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON 0x0009 -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_TRUE 1 -#define GL_FALSE 0 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_DOUBLE 0x140A -#define GL_NONE 0 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LIST_MODE 0x0B30 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_SHADE_MODEL 0x0B54 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_FOG 0x0B60 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_COLOR 0x0B66 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_NORMALIZE 0x0BA1 -#define GL_VIEWPORT 0x0BA2 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_DITHER 0x0BD0 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND 0x0BE2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_READ_BUFFER 0x0C02 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_INDEX_MODE 0x0C30 -#define GL_RGBA_MODE 0x0C31 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_RENDER_MODE 0x0C40 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_FOG_HINT 0x0C54 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_INDEX_BITS 0x0D51 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_CLEAR 0x1500 -#define GL_AND 0x1501 -#define GL_AND_REVERSE 0x1502 -#define GL_COPY 0x1503 -#define GL_AND_INVERTED 0x1504 -#define GL_NOOP 0x1505 -#define GL_XOR 0x1506 -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_EQUIV 0x1509 -#define GL_INVERT 0x150A -#define GL_OR_REVERSE 0x150B -#define GL_COPY_INVERTED 0x150C -#define GL_OR_INVERTED 0x150D -#define GL_NAND 0x150E -#define GL_SET 0x150F -#define GL_EMISSION 0x1600 -#define GL_SHININESS 0x1601 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_TEXTURE 0x1702 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_COLOR_INDEX 0x1900 -#define GL_STENCIL_INDEX 0x1901 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_BITMAP 0x1A00 -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_RENDER 0x1C00 -#define GL_FEEDBACK 0x1C01 -#define GL_SELECT 0x1C02 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_S 0x2000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_MODULATE 0x2100 -#define GL_DECAL 0x2101 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV 0x2300 -#define GL_EYE_LINEAR 0x2400 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_SPHERE_MAP 0x2402 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_PLANE 0x2502 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_CLAMP 0x2900 -#define GL_REPEAT 0x2901 -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_R3_G3_B2 0x2A10 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D -#define GL_LOGIC_OP GL_INDEX_LOGIC_OP -#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 - -GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); -GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); -GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI void GLAPIENTRY glArrayElement (GLint i); -GLAPI void GLAPIENTRY glBegin (GLenum mode); -GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); -GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); -GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GLAPI void GLAPIENTRY glCallList (GLuint list); -GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); -GLAPI void GLAPIENTRY glClear (GLbitfield mask); -GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); -GLAPI void GLAPIENTRY glClearIndex (GLfloat c); -GLAPI void GLAPIENTRY glClearStencil (GLint s); -GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); -GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); -GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); -GLAPI void GLAPIENTRY glColor3iv (const GLint *v); -GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); -GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); -GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); -GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); -GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); -GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); -GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); -GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); -GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); -GLAPI void GLAPIENTRY glColor4iv (const GLint *v); -GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); -GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); -GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); -GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); -GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); -GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); -GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); -GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); -GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void GLAPIENTRY glCullFace (GLenum mode); -GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); -GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); -GLAPI void GLAPIENTRY glDepthFunc (GLenum func); -GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); -GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); -GLAPI void GLAPIENTRY glDisable (GLenum cap); -GLAPI void GLAPIENTRY glDisableClientState (GLenum array); -GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); -GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); -GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); -GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); -GLAPI void GLAPIENTRY glEnable (GLenum cap); -GLAPI void GLAPIENTRY glEnableClientState (GLenum array); -GLAPI void GLAPIENTRY glEnd (void); -GLAPI void GLAPIENTRY glEndList (void); -GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); -GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); -GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); -GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); -GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); -GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); -GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); -GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); -GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); -GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); -GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); -GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); -GLAPI void GLAPIENTRY glFinish (void); -GLAPI void GLAPIENTRY glFlush (void); -GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glFrontFace (GLenum mode); -GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); -GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); -GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); -GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); -GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); -GLAPI GLenum GLAPIENTRY glGetError (void); -GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); -GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); -GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); -GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); -GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); -GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); -GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); -GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); -GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); -GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); -GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); -GLAPI void GLAPIENTRY glIndexMask (GLuint mask); -GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glIndexd (GLdouble c); -GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); -GLAPI void GLAPIENTRY glIndexf (GLfloat c); -GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); -GLAPI void GLAPIENTRY glIndexi (GLint c); -GLAPI void GLAPIENTRY glIndexiv (const GLint *c); -GLAPI void GLAPIENTRY glIndexs (GLshort c); -GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); -GLAPI void GLAPIENTRY glIndexub (GLubyte c); -GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); -GLAPI void GLAPIENTRY glInitNames (void); -GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); -GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); -GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); -GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); -GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); -GLAPI void GLAPIENTRY glLineWidth (GLfloat width); -GLAPI void GLAPIENTRY glListBase (GLuint base); -GLAPI void GLAPIENTRY glLoadIdentity (void); -GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); -GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); -GLAPI void GLAPIENTRY glLoadName (GLuint name); -GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); -GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); -GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); -GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); -GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); -GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); -GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); -GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); -GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); -GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); -GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); -GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); -GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void GLAPIENTRY glPassThrough (GLfloat token); -GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); -GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); -GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); -GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); -GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); -GLAPI void GLAPIENTRY glPointSize (GLfloat size); -GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); -GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); -GLAPI void GLAPIENTRY glPopAttrib (void); -GLAPI void GLAPIENTRY glPopClientAttrib (void); -GLAPI void GLAPIENTRY glPopMatrix (void); -GLAPI void GLAPIENTRY glPopName (void); -GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); -GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); -GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); -GLAPI void GLAPIENTRY glPushMatrix (void); -GLAPI void GLAPIENTRY glPushName (GLuint name); -GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); -GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); -GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); -GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); -GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); -GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); -GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); -GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); -GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); -GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); -GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); -GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); -GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); -GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); -GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); -GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); -GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); -GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); -GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); -GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); -GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); -GLAPI void GLAPIENTRY glShadeModel (GLenum mode); -GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GLAPI void GLAPIENTRY glStencilMask (GLuint mask); -GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); -GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); -GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord1i (GLint s); -GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); -GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); -GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); -GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); -GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); -GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); -GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); -GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); -GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); -GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); -GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); -GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); -GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); -GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); -GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); -GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); -GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); -GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); -GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); -GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); -GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); -GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); -GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); -GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); -GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); -GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - -#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) - -#endif /* GL_VERSION_1_1 */ - -/* ---------------------------------- GLU ---------------------------------- */ - -/* this is where we can safely include GLU */ -#if defined(__APPLE__) && defined(__MACH__) -#include -#else -#include -#endif - -/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 - -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_RESCALE_NORMAL 0x803A -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E - -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); - -#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) -#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) -#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) -#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) - -#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) - -#endif /* GL_VERSION_1_2 */ - -/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 - -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_SUBTRACT 0x84E7 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_MULTISAMPLE_BIT 0x20000000 - -typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); - -#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) -#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) -#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) -#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) -#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) -#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) -#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) -#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) -#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) -#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) -#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) -#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) -#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) -#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) -#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) -#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) -#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) -#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) -#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) -#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) -#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) -#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) -#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) -#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) -#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) -#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) -#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) -#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) -#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) -#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) -#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) -#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) -#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) -#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) -#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) -#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) -#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) -#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) -#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) -#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) -#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) -#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) -#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) -#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) -#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) -#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) - -#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) - -#endif /* GL_VERSION_1_3 */ - -/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 - -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_COMPARE_R_TO_TEXTURE 0x884E - -typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); - -#define glBlendColor GLEW_GET_FUN(__glewBlendColor) -#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) -#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) -#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) -#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) -#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) -#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) -#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) -#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) -#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) -#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) -#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) -#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) -#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) -#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) -#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) -#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) -#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) -#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) -#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) -#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) -#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) -#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) -#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) -#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) -#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) -#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) -#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) -#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) -#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) -#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) -#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) -#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) -#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) -#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) -#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) -#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) -#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) -#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) -#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) -#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) -#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) -#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) -#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) -#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) -#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) -#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) - -#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) - -#endif /* GL_VERSION_1_4 */ - -/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 - -#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE -#define GL_FOG_COORD GL_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY -#define GL_SRC0_RGB GL_SOURCE0_RGB -#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA -#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA -#define GL_SRC1_RGB GL_SOURCE1_RGB -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA -#define GL_SRC2_RGB GL_SOURCE2_RGB -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 - -typedef ptrdiff_t GLsizeiptr; -typedef ptrdiff_t GLintptr; - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); -typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); - -#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) -#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) -#define glBufferData GLEW_GET_FUN(__glewBufferData) -#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) -#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) -#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) -#define glEndQuery GLEW_GET_FUN(__glewEndQuery) -#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) -#define glGenQueries GLEW_GET_FUN(__glewGenQueries) -#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) -#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) -#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) -#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) -#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) -#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) -#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) -#define glIsQuery GLEW_GET_FUN(__glewIsQuery) -#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) -#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) - -#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) - -#endif /* GL_VERSION_1_5 */ - -/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 - -#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 - -typedef char GLchar; - -typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); -typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); -typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); -typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); -typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source); -typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid*); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); -typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); -typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); -typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); - -#define glAttachShader GLEW_GET_FUN(__glewAttachShader) -#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) -#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) -#define glCompileShader GLEW_GET_FUN(__glewCompileShader) -#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) -#define glCreateShader GLEW_GET_FUN(__glewCreateShader) -#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) -#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) -#define glDetachShader GLEW_GET_FUN(__glewDetachShader) -#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) -#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) -#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) -#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) -#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) -#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) -#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) -#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) -#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) -#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) -#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) -#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) -#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) -#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) -#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) -#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) -#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) -#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) -#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) -#define glIsProgram GLEW_GET_FUN(__glewIsProgram) -#define glIsShader GLEW_GET_FUN(__glewIsShader) -#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) -#define glShaderSource GLEW_GET_FUN(__glewShaderSource) -#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) -#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) -#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) -#define glUniform1f GLEW_GET_FUN(__glewUniform1f) -#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) -#define glUniform1i GLEW_GET_FUN(__glewUniform1i) -#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) -#define glUniform2f GLEW_GET_FUN(__glewUniform2f) -#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) -#define glUniform2i GLEW_GET_FUN(__glewUniform2i) -#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) -#define glUniform3f GLEW_GET_FUN(__glewUniform3f) -#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) -#define glUniform3i GLEW_GET_FUN(__glewUniform3i) -#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) -#define glUniform4f GLEW_GET_FUN(__glewUniform4f) -#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) -#define glUniform4i GLEW_GET_FUN(__glewUniform4i) -#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) -#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) -#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) -#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) -#define glUseProgram GLEW_GET_FUN(__glewUseProgram) -#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) -#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) -#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) -#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) -#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) -#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) -#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) -#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) -#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) -#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) -#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) -#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) -#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) -#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) -#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) -#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) -#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) -#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) -#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) -#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) -#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) -#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) -#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) -#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) -#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) -#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) -#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) -#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) -#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) -#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) -#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) -#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) -#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) -#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) -#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) -#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) -#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) -#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) - -#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) - -#endif /* GL_VERSION_2_0 */ - -/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 - -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B - -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - -#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) -#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) -#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) -#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) -#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) -#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) - -#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) - -#endif /* GL_VERSION_2_1 */ - -/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 - -#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES -#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 -#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 -#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 -#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB -#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 -#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 -#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 -#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_DEPTH_BUFFER 0x8223 -#define GL_STENCIL_BUFFER 0x8224 -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_ALPHA_INTEGER 0x8D97 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 - -typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum); -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*); -typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*); -typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*); -typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); -typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint); -typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint); -typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*); -typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum, GLuint, GLint*); -typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLint*); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLint*, GLenum); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*); - -#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) -#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) -#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) -#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) -#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) -#define glClampColor GLEW_GET_FUN(__glewClampColor) -#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) -#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) -#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) -#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) -#define glColorMaski GLEW_GET_FUN(__glewColorMaski) -#define glDisablei GLEW_GET_FUN(__glewDisablei) -#define glEnablei GLEW_GET_FUN(__glewEnablei) -#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) -#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) -#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) -#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) -#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) -#define glGetStringi GLEW_GET_FUN(__glewGetStringi) -#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) -#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) -#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) -#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) -#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) -#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) -#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) -#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) -#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) -#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) -#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) -#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) -#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) -#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) -#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) -#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) -#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) -#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) -#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) -#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) -#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) -#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) -#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) -#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) -#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) -#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) -#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) -#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) -#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) -#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) -#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) -#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) -#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) -#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) -#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) -#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) -#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) -#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) -#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) - -#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) - -#endif /* GL_VERSION_3_0 */ - -/* -------------------------- GL_3DFX_multisample -------------------------- */ - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 - -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 - -#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) - -#endif /* GL_3DFX_multisample */ - -/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 - -typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); - -#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) - -#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) - -#endif /* GL_3DFX_tbuffer */ - -/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 - -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 - -#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) - -#endif /* GL_3DFX_texture_compression_FXT1 */ - -/* ------------------------ GL_APPLE_client_storage ------------------------ */ - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 - -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 - -#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) - -#endif /* GL_APPLE_client_storage */ - -/* ------------------------- GL_APPLE_element_array ------------------------ */ - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 - -#define GL_ELEMENT_ARRAY_APPLE 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); - -#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) -#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) -#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) -#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) -#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) - -#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) - -#endif /* GL_APPLE_element_array */ - -/* ----------------------------- GL_APPLE_fence ---------------------------- */ - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 - -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B - -typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); -typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); -typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); - -#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) -#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) -#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) -#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) -#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) -#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) -#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) -#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) - -#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) - -#endif /* GL_APPLE_fence */ - -/* ------------------------- GL_APPLE_float_pixels ------------------------- */ - -#ifndef GL_APPLE_float_pixels -#define GL_APPLE_float_pixels 1 - -#define GL_HALF_APPLE 0x140B -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_COLOR_FLOAT_APPLE 0x8A0F - -#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) - -#endif /* GL_APPLE_float_pixels */ - -/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 - -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 - -typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); - -#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) -#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) - -#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) - -#endif /* GL_APPLE_flush_buffer_range */ - -/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ - -#ifndef GL_APPLE_pixel_buffer -#define GL_APPLE_pixel_buffer 1 - -#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 - -#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) - -#endif /* GL_APPLE_pixel_buffer */ - -/* ------------------------ GL_APPLE_specular_vector ----------------------- */ - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 - -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 - -#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) - -#endif /* GL_APPLE_specular_vector */ - -/* ------------------------- GL_APPLE_texture_range ------------------------ */ - -#ifndef GL_APPLE_texture_range -#define GL_APPLE_texture_range 1 - -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF - -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); -typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); - -#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) -#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) - -#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) - -#endif /* GL_APPLE_texture_range */ - -/* ------------------------ GL_APPLE_transform_hint ------------------------ */ - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 - -#define GL_TRANSFORM_HINT_APPLE 0x85B1 - -#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) - -#endif /* GL_APPLE_transform_hint */ - -/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 - -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); - -#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) -#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) -#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) -#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) - -#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) - -#endif /* GL_APPLE_vertex_array_object */ - -/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 - -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF - -typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); - -#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) -#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) -#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) - -#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) - -#endif /* GL_APPLE_vertex_array_range */ - -/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 - -#define GL_YCBCR_422_APPLE 0x85B9 -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB - -#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) - -#endif /* GL_APPLE_ycbcr_422 */ - -/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 - -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D - -typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); - -#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) - -#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) - -#endif /* GL_ARB_color_buffer_float */ - -/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 - -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD - -#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) - -#endif /* GL_ARB_depth_buffer_float */ - -/* -------------------------- GL_ARB_depth_texture ------------------------- */ - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 - -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B - -#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) - -#endif /* GL_ARB_depth_texture */ - -/* -------------------------- GL_ARB_draw_buffers -------------------------- */ - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) - -#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) - -#endif /* GL_ARB_draw_buffers */ - -/* ------------------------- GL_ARB_draw_instanced ------------------------- */ - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); - -#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) -#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) - -#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) - -#endif /* GL_ARB_draw_instanced */ - -/* ------------------------ GL_ARB_fragment_program ------------------------ */ - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 - -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 - -#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) - -#endif /* GL_ARB_fragment_program */ - -/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 - -#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) - -#endif /* GL_ARB_fragment_program_shadow */ - -/* ------------------------- GL_ARB_fragment_shader ------------------------ */ - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 - -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B - -#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) - -#endif /* GL_ARB_fragment_shader */ - -/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_INDEX 0x8222 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_SRGB 0x8C40 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 - -typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURLAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) -#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) -#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) -#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) -#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) -#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) -#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) -#define glFramebufferTexturLayer GLEW_GET_FUN(__glewFramebufferTexturLayer) -#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) -#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) -#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) -#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) -#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) -#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) -#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) -#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) -#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) -#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) -#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) -#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) - -#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) - -#endif /* GL_ARB_framebuffer_object */ - -/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 - -#define GL_FRAMEBUFFER_SRGB 0x8DB9 - -#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) - -#endif /* GL_ARB_framebuffer_sRGB */ - -/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 - -#define GL_LINES_ADJACENCY_ARB 0xA -#define GL_LINE_STRIP_ADJACENCY_ARB 0xB -#define GL_TRIANGLES_ADJACENCY_ARB 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); - -#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) -#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) -#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) -#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) - -#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) - -#endif /* GL_ARB_geometry_shader4 */ - -/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 - -#define GL_HALF_FLOAT_ARB 0x140B - -#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) - -#endif /* GL_ARB_half_float_pixel */ - -/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 - -#define GL_HALF_FLOAT 0x140B - -#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) - -#endif /* GL_ARB_half_float_vertex */ - -/* ----------------------------- GL_ARB_imaging ---------------------------- */ - -#ifndef GL_ARB_imaging -#define GL_ARB_imaging 1 - -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_FUNC_ADD 0x8006 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BLEND_EQUATION 0x8009 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_IGNORE_BORDER 0x8150 -#define GL_CONSTANT_BORDER 0x8151 -#define GL_WRAP_BORDER 0x8152 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 - -typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); - -#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) -#define glColorTable GLEW_GET_FUN(__glewColorTable) -#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) -#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) -#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) -#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) -#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) -#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) -#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) -#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) -#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) -#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) -#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) -#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) -#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) -#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) -#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) -#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) -#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) -#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) -#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) -#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) -#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) -#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) -#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) -#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) -#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) -#define glHistogram GLEW_GET_FUN(__glewHistogram) -#define glMinmax GLEW_GET_FUN(__glewMinmax) -#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) -#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) -#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) - -#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) - -#endif /* GL_ARB_imaging */ - -/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 - -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE - -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); - -#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) - -#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) - -#endif /* GL_ARB_instanced_arrays */ - -/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 - -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 - -typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); - -#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) -#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) - -#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) - -#endif /* GL_ARB_map_buffer_range */ - -/* ------------------------- GL_ARB_matrix_palette ------------------------- */ - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 - -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 - -typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); -typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); - -#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) -#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) -#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) -#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) -#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) - -#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) - -#endif /* GL_ARB_matrix_palette */ - -/* --------------------------- GL_ARB_multisample -------------------------- */ - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 - -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 - -typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); - -#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) - -#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) - -#endif /* GL_ARB_multisample */ - -/* -------------------------- GL_ARB_multitexture -------------------------- */ - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 - -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 - -typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); - -#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) -#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) -#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) -#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) -#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) -#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) -#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) -#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) -#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) -#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) -#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) -#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) -#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) -#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) -#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) -#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) -#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) -#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) -#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) -#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) -#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) -#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) -#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) -#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) -#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) -#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) -#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) -#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) -#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) -#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) -#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) -#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) -#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) -#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) - -#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) - -#endif /* GL_ARB_multitexture */ - -/* ------------------------- GL_ARB_occlusion_query ------------------------ */ - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 - -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 - -typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); - -#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) -#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) -#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) -#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) -#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) -#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) -#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) -#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) - -#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) - -#endif /* GL_ARB_occlusion_query */ - -/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 - -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF - -#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) - -#endif /* GL_ARB_pixel_buffer_object */ - -/* ------------------------ GL_ARB_point_parameters ------------------------ */ - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 - -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat* params); - -#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) -#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) - -#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) - -#endif /* GL_ARB_point_parameters */ - -/* -------------------------- GL_ARB_point_sprite -------------------------- */ - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 - -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 - -#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) - -#endif /* GL_ARB_point_sprite */ - -/* ------------------------- GL_ARB_shader_objects ------------------------- */ - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 - -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 - -typedef char GLcharARB; -typedef unsigned int GLhandleARB; - -typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); -typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); -typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); -typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); - -#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) -#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) -#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) -#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) -#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) -#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) -#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) -#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) -#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) -#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) -#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) -#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) -#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) -#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) -#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) -#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) -#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) -#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) -#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) -#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) -#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) -#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) -#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) -#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) -#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) -#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) -#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) -#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) -#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) -#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) -#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) -#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) -#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) -#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) -#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) -#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) -#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) -#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) -#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) - -#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) - -#endif /* GL_ARB_shader_objects */ - -/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 - -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C - -#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) - -#endif /* GL_ARB_shading_language_100 */ - -/* ----------------------------- GL_ARB_shadow ----------------------------- */ - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 - -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E - -#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) - -#endif /* GL_ARB_shadow */ - -/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 - -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF - -#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) - -#endif /* GL_ARB_shadow_ambient */ - -/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 - -#define GL_CLAMP_TO_BORDER_ARB 0x812D - -#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) - -#endif /* GL_ARB_texture_border_clamp */ - -/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 - -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E - -typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); - -#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) - -#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) - -#endif /* GL_ARB_texture_buffer_object */ - -/* ----------------------- GL_ARB_texture_compression ---------------------- */ - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 - -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 - -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); - -#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) -#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) -#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) -#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) -#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) -#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) -#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) - -#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) - -#endif /* GL_ARB_texture_compression */ - -/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 - -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE - -#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) - -#endif /* GL_ARB_texture_compression_rgtc */ - -/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 - -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C - -#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) - -#endif /* GL_ARB_texture_cube_map */ - -/* ------------------------- GL_ARB_texture_env_add ------------------------ */ - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 - -#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) - -#endif /* GL_ARB_texture_env_add */ - -/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 - -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A - -#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) - -#endif /* GL_ARB_texture_env_combine */ - -/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 - -#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) - -#endif /* GL_ARB_texture_env_crossbar */ - -/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 - -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF - -#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) - -#endif /* GL_ARB_texture_env_dot3 */ - -/* -------------------------- GL_ARB_texture_float ------------------------- */ - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 - -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 - -#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) - -#endif /* GL_ARB_texture_float */ - -/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 - -#define GL_MIRRORED_REPEAT_ARB 0x8370 - -#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) - -#endif /* GL_ARB_texture_mirrored_repeat */ - -/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 - -#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) - -#endif /* GL_ARB_texture_non_power_of_two */ - -/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 - -#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) - -#endif /* GL_ARB_texture_rectangle */ - -/* --------------------------- GL_ARB_texture_rg --------------------------- */ - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 - -#define GL_RED 0x1903 -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C - -#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) - -#endif /* GL_ARB_texture_rg */ - -/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 - -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 - -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); -typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); - -#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) -#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) -#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) -#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) - -#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) - -#endif /* GL_ARB_transpose_matrix */ - -/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 - -#define GL_VERTEX_ARRAY_BINDING 0x85B5 - -typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); -typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); -typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); - -#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) -#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) -#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) -#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) - -#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) - -#endif /* GL_ARB_vertex_array_object */ - -/* -------------------------- GL_ARB_vertex_blend -------------------------- */ - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 - -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F - -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); -typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); -typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); -typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); - -#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) -#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) -#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) -#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) -#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) -#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) -#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) -#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) -#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) -#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) - -#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) - -#endif /* GL_ARB_vertex_blend */ - -/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 - -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA - -typedef ptrdiff_t GLsizeiptrARB; -typedef ptrdiff_t GLintptrARB; - -typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); -typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); -typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); - -#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) -#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) -#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) -#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) -#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) -#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) -#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) -#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) -#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) -#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) -#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) - -#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) - -#endif /* GL_ARB_vertex_buffer_object */ - -/* ------------------------- GL_ARB_vertex_program ------------------------- */ - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 - -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF - -typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); -typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); - -#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) -#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) -#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) -#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) -#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) -#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) -#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) -#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) -#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) -#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) -#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) -#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) -#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) -#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) -#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) -#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) -#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) -#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) -#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) -#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) -#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) -#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) -#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) -#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) -#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) -#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) -#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) -#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) -#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) -#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) -#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) -#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) -#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) -#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) -#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) -#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) -#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) -#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) -#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) -#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) -#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) -#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) -#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) -#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) -#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) -#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) -#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) -#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) -#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) -#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) -#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) -#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) -#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) -#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) -#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) -#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) -#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) -#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) -#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) -#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) -#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) -#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) - -#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) - -#endif /* GL_ARB_vertex_program */ - -/* -------------------------- GL_ARB_vertex_shader ------------------------- */ - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 - -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A - -typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); -typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); - -#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) -#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) -#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) - -#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) - -#endif /* GL_ARB_vertex_shader */ - -/* --------------------------- GL_ARB_window_pos --------------------------- */ - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 - -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); - -#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) -#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) -#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) -#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) -#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) -#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) -#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) -#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) -#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) -#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) -#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) -#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) -#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) -#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) -#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) -#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) - -#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) - -#endif /* GL_ARB_window_pos */ - -/* ------------------------- GL_ATIX_point_sprites ------------------------- */ - -#ifndef GL_ATIX_point_sprites -#define GL_ATIX_point_sprites 1 - -#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 -#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 -#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 -#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 -#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 -#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 - -#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) - -#endif /* GL_ATIX_point_sprites */ - -/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ - -#ifndef GL_ATIX_texture_env_combine3 -#define GL_ATIX_texture_env_combine3 1 - -#define GL_MODULATE_ADD_ATIX 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 -#define GL_MODULATE_SUBTRACT_ATIX 0x8746 - -#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) - -#endif /* GL_ATIX_texture_env_combine3 */ - -/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ - -#ifndef GL_ATIX_texture_env_route -#define GL_ATIX_texture_env_route 1 - -#define GL_SECONDARY_COLOR_ATIX 0x8747 -#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 -#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 - -#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) - -#endif /* GL_ATIX_texture_env_route */ - -/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ - -#ifndef GL_ATIX_vertex_shader_output_point_size -#define GL_ATIX_vertex_shader_output_point_size 1 - -#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E - -#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) - -#endif /* GL_ATIX_vertex_shader_output_point_size */ - -/* -------------------------- GL_ATI_draw_buffers -------------------------- */ - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 - -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 - -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); - -#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) - -#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) - -#endif /* GL_ATI_draw_buffers */ - -/* -------------------------- GL_ATI_element_array ------------------------- */ - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 - -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A - -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); - -#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) -#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) -#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) - -#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) - -#endif /* GL_ATI_element_array */ - -/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 - -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C - -typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); - -#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) -#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) -#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) -#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) - -#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) - -#endif /* GL_ATI_envmap_bumpmap */ - -/* ------------------------- GL_ATI_fragment_shader ------------------------ */ - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 - -#define GL_RED_BIT_ATI 0x00000001 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B - -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); - -#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) -#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) -#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) -#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) -#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) -#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) -#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) -#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) -#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) -#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) -#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) -#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) -#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) -#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) - -#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) - -#endif /* GL_ATI_fragment_shader */ - -/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 - -typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); - -#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) -#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) - -#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) - -#endif /* GL_ATI_map_object_buffer */ - -/* -------------------------- GL_ATI_pn_triangles -------------------------- */ - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 - -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 - -typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); - -#define glPNTrianglesfATI GLEW_GET_FUN(__glPNTrianglewesfATI) -#define glPNTrianglesiATI GLEW_GET_FUN(__glPNTrianglewesiATI) - -#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) - -#endif /* GL_ATI_pn_triangles */ - -/* ------------------------ GL_ATI_separate_stencil ------------------------ */ - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 - -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 - -typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); - -#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) -#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) - -#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) - -#endif /* GL_ATI_separate_stencil */ - -/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ - -#ifndef GL_ATI_shader_texture_lod -#define GL_ATI_shader_texture_lod 1 - -#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) - -#endif /* GL_ATI_shader_texture_lod */ - -/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 - -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 - -#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) - -#endif /* GL_ATI_text_fragment_shader */ - -/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ - -#ifndef GL_ATI_texture_compression_3dc -#define GL_ATI_texture_compression_3dc 1 - -#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 - -#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) - -#endif /* GL_ATI_texture_compression_3dc */ - -/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 - -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 - -#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) - -#endif /* GL_ATI_texture_env_combine3 */ - -/* -------------------------- GL_ATI_texture_float ------------------------- */ - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 - -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F - -#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) - -#endif /* GL_ATI_texture_float */ - -/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 - -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 - -#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) - -#endif /* GL_ATI_texture_mirror_once */ - -/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 - -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 - -typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); -typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); -typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); - -#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) -#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) -#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) -#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) -#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) -#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) -#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) -#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) -#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) -#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) -#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) -#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) - -#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) - -#endif /* GL_ATI_vertex_array_object */ - -/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 - -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); - -#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) -#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) -#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) - -#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) - -#endif /* GL_ATI_vertex_attrib_array_object */ - -/* ------------------------- GL_ATI_vertex_streams ------------------------- */ - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 - -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_SOURCE_ATI 0x876C -#define GL_VERTEX_STREAM0_ATI 0x876D -#define GL_VERTEX_STREAM1_ATI 0x876E -#define GL_VERTEX_STREAM2_ATI 0x876F -#define GL_VERTEX_STREAM3_ATI 0x8770 -#define GL_VERTEX_STREAM4_ATI 0x8771 -#define GL_VERTEX_STREAM5_ATI 0x8772 -#define GL_VERTEX_STREAM6_ATI 0x8773 -#define GL_VERTEX_STREAM7_ATI 0x8774 - -typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); - -#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) -#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) -#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) -#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) -#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) -#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) -#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) -#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) -#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) -#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) -#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) -#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) -#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) -#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) -#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) -#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) -#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) -#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) -#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) -#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) -#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) -#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) -#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) -#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) -#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) -#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) -#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) -#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) -#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) -#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) -#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) -#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) -#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) -#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) -#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) -#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) -#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) - -#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) - -#endif /* GL_ATI_vertex_streams */ - -/* --------------------------- GL_EXT_422_pixels --------------------------- */ - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 - -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF - -#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) - -#endif /* GL_EXT_422_pixels */ - -/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ - -#ifndef GL_EXT_Cg_shader -#define GL_EXT_Cg_shader 1 - -#define GL_CG_VERTEX_SHADER_EXT 0x890E -#define GL_CG_FRAGMENT_SHADER_EXT 0x890F - -#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) - -#endif /* GL_EXT_Cg_shader */ - -/* ------------------------------ GL_EXT_abgr ------------------------------ */ - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 - -#define GL_ABGR_EXT 0x8000 - -#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) - -#endif /* GL_EXT_abgr */ - -/* ------------------------------ GL_EXT_bgra ------------------------------ */ - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 - -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 - -#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) - -#endif /* GL_EXT_bgra */ - -/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 - -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF - -typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); - -#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) -#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) -#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) - -#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) - -#endif /* GL_EXT_bindable_uniform */ - -/* --------------------------- GL_EXT_blend_color -------------------------- */ - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 - -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 - -typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - -#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) - -#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) - -#endif /* GL_EXT_blend_color */ - -/* --------------------- GL_EXT_blend_equation_separate -------------------- */ - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 - -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); - -#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) - -#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) - -#endif /* GL_EXT_blend_equation_separate */ - -/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 - -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB - -typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - -#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) - -#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) - -#endif /* GL_EXT_blend_func_separate */ - -/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 - -#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) - -#endif /* GL_EXT_blend_logic_op */ - -/* -------------------------- GL_EXT_blend_minmax -------------------------- */ - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 - -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_BLEND_EQUATION_EXT 0x8009 - -typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); - -#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) - -#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) - -#endif /* GL_EXT_blend_minmax */ - -/* ------------------------- GL_EXT_blend_subtract ------------------------- */ - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 - -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B - -#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) - -#endif /* GL_EXT_blend_subtract */ - -/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 - -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 - -#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) - -#endif /* GL_EXT_clip_volume_hint */ - -/* ------------------------------ GL_EXT_cmyka ----------------------------- */ - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 - -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F - -#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) - -#endif /* GL_EXT_cmyka */ - -/* ------------------------- GL_EXT_color_subtable ------------------------- */ - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 - -typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); - -#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) -#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) - -#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) - -#endif /* GL_EXT_color_subtable */ - -/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 - -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 - -typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); - -#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) -#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) - -#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) - -#endif /* GL_EXT_compiled_vertex_array */ - -/* --------------------------- GL_EXT_convolution -------------------------- */ - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 - -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 - -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); -typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); - -#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) -#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) -#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) -#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) -#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) -#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) -#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) -#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) -#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) -#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) -#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) -#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) -#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) - -#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) - -#endif /* GL_EXT_convolution */ - -/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 - -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 - -typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); -typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); - -#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) -#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) - -#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) - -#endif /* GL_EXT_coordinate_frame */ - -/* -------------------------- GL_EXT_copy_texture -------------------------- */ - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 - -typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - -#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) -#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) -#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) -#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) -#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) - -#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) - -#endif /* GL_EXT_copy_texture */ - -/* --------------------------- GL_EXT_cull_vertex -------------------------- */ - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 - -typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); - -#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) -#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) - -#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) - -#endif /* GL_EXT_cull_vertex */ - -/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 - -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 - -typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); - -#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) - -#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) - -#endif /* GL_EXT_depth_bounds_test */ - -/* ----------------------- GL_EXT_direct_state_access ---------------------- */ - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 - -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F - -typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img); -typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img); -typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void* data); -typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string); -typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLvoid** params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); -typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); -typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); -typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); -typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); -typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void* pointer); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); -typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage); -typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void* string); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); -typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); -typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); - -#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) -#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) -#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) -#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) -#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) -#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) -#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) -#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) -#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) -#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) -#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) -#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) -#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) -#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) -#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) -#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) -#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) -#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) -#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) -#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) -#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) -#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) -#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) -#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) -#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) -#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) -#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) -#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) -#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) -#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) -#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) -#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) -#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) -#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) -#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) -#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) -#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) -#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) -#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) -#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) -#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) -#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) -#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) -#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) -#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) -#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) -#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) -#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) -#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) -#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) -#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) -#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) -#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) -#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) -#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) -#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) -#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) -#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) -#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) -#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) -#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) -#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) -#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) -#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) -#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) -#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) -#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) -#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) -#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) -#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) -#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) -#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) -#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) -#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) -#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) -#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) -#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) -#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) -#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) -#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) -#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) -#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) -#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) -#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) -#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) -#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) -#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) -#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) -#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) -#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) -#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) -#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) -#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) -#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) -#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) -#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) -#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) -#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) -#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) -#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) -#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) -#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) -#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) -#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) -#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) -#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) -#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) -#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) -#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) -#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) -#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) -#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) -#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) -#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) -#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) -#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) -#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) -#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) -#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) -#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) -#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) -#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) -#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) -#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) -#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) -#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) -#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) -#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) -#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) -#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) -#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) -#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) -#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) -#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) -#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) -#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) -#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) -#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) -#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) -#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) -#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) -#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) -#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) -#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) -#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) -#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) -#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) -#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) -#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) -#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) -#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) -#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) -#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) -#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) -#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) -#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) -#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) -#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) -#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) -#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) -#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) -#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) -#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) -#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) -#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) -#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) -#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) -#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) -#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) -#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) -#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) -#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) -#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) -#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) -#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) -#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) -#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) -#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) -#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) -#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) -#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) -#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) -#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) -#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) -#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) -#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) - -#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) - -#endif /* GL_EXT_direct_state_access */ - -/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 - -typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); -typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); -typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); - -#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) -#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) -#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) -#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) -#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) -#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) - -#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) - -#endif /* GL_EXT_draw_buffers2 */ - -/* ------------------------- GL_EXT_draw_instanced ------------------------- */ - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 - -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); - -#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) -#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) - -#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) - -#endif /* GL_EXT_draw_instanced */ - -/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 - -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 - -typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); - -#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) - -#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) - -#endif /* GL_EXT_draw_range_elements */ - -/* ---------------------------- GL_EXT_fog_coord --------------------------- */ - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 - -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 - -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); - -#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) -#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) -#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) -#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) -#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) - -#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) - -#endif /* GL_EXT_fog_coord */ - -/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ - -#ifndef GL_EXT_fragment_lighting -#define GL_EXT_fragment_lighting 1 - -#define GL_FRAGMENT_LIGHTING_EXT 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 -#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 -#define GL_LIGHT_ENV_MODE_EXT 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B -#define GL_FRAGMENT_LIGHT0_EXT 0x840C -#define GL_FRAGMENT_LIGHT7_EXT 0x8413 - -typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); - -#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) -#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) -#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) -#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) -#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) -#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) -#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) -#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) -#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) -#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) -#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) -#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) -#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) -#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) -#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) -#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) -#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) -#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) - -#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) - -#endif /* GL_EXT_fragment_lighting */ - -/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 - -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA - -typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - -#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) - -#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) - -#endif /* GL_EXT_framebuffer_blit */ - -/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 - -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) - -#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) - -#endif /* GL_EXT_framebuffer_multisample */ - -/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 - -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 - -typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); -typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); -typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - -#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) -#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) -#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) -#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) -#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) -#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) -#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) -#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) -#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) -#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) -#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) -#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) -#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) -#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) -#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) -#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) -#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) - -#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) - -#endif /* GL_EXT_framebuffer_object */ - -/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 - -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA - -#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) - -#endif /* GL_EXT_framebuffer_sRGB */ - -/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 - -#define GL_LINES_ADJACENCY_EXT 0xA -#define GL_LINE_STRIP_ADJACENCY_EXT 0xB -#define GL_TRIANGLES_ADJACENCY_EXT 0xC -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 - -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); - -#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) -#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) -#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) -#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) - -#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) - -#endif /* GL_EXT_geometry_shader4 */ - -/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 - -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); - -#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) -#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) - -#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) - -#endif /* GL_EXT_gpu_program_parameters */ - -/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 - -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 - -typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - -#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) -#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) -#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) -#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) -#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) -#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) -#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) -#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) -#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) -#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) -#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) -#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) -#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) -#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) -#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) -#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) -#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) -#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) -#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) -#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) -#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) -#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) -#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) -#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) -#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) -#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) -#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) -#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) -#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) -#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) -#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) -#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) -#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) -#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) - -#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) - -#endif /* GL_EXT_gpu_shader4 */ - -/* ---------------------------- GL_EXT_histogram --------------------------- */ - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 - -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 - -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); - -#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) -#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) -#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) -#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) -#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) -#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) -#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) -#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) -#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) -#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) - -#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) - -#endif /* GL_EXT_histogram */ - -/* ----------------------- GL_EXT_index_array_formats ---------------------- */ - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 - -#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) - -#endif /* GL_EXT_index_array_formats */ - -/* --------------------------- GL_EXT_index_func --------------------------- */ - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 - -typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); - -#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) - -#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) - -#endif /* GL_EXT_index_func */ - -/* ------------------------- GL_EXT_index_material ------------------------- */ - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 - -typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); - -#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) - -#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) - -#endif /* GL_EXT_index_material */ - -/* -------------------------- GL_EXT_index_texture ------------------------- */ - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 - -#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) - -#endif /* GL_EXT_index_texture */ - -/* -------------------------- GL_EXT_light_texture ------------------------- */ - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 - -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 - -typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); - -#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) -#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) -#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) - -#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) - -#endif /* GL_EXT_light_texture */ - -/* ------------------------- GL_EXT_misc_attribute ------------------------- */ - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 - -#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) - -#endif /* GL_EXT_misc_attribute */ - -/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 - -typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint* first, GLsizei *count, GLsizei primcount); -typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); - -#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) -#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) - -#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) - -#endif /* GL_EXT_multi_draw_arrays */ - -/* --------------------------- GL_EXT_multisample -------------------------- */ - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 - -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 - -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); - -#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) -#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) - -#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) - -#endif /* GL_EXT_multisample */ - -/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 - -#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) - -#endif /* GL_EXT_packed_depth_stencil */ - -/* -------------------------- GL_EXT_packed_float -------------------------- */ - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 - -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C - -#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) - -#endif /* GL_EXT_packed_float */ - -/* -------------------------- GL_EXT_packed_pixels ------------------------- */ - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 - -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 - -#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) - -#endif /* GL_EXT_packed_pixels */ - -/* ------------------------ GL_EXT_paletted_texture ------------------------ */ - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 - -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 -#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B - -typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); - -#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) -#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) -#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) -#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) - -#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) - -#endif /* GL_EXT_paletted_texture */ - -/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 - -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF - -#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) - -#endif /* GL_EXT_pixel_buffer_object */ - -/* ------------------------- GL_EXT_pixel_transform ------------------------ */ - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 - -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 - -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) -#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) -#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) -#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) -#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) -#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) - -#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) - -#endif /* GL_EXT_pixel_transform */ - -/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 - -#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) - -#endif /* GL_EXT_pixel_transform_color_table */ - -/* ------------------------ GL_EXT_point_parameters ------------------------ */ - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 - -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); - -#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) -#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) - -#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) - -#endif /* GL_EXT_point_parameters */ - -/* ------------------------- GL_EXT_polygon_offset ------------------------- */ - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 - -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 - -typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); - -#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) - -#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) - -#endif /* GL_EXT_polygon_offset */ - -/* ------------------------- GL_EXT_rescale_normal ------------------------- */ - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 - -#define GL_RESCALE_NORMAL_EXT 0x803A - -#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) - -#endif /* GL_EXT_rescale_normal */ - -/* -------------------------- GL_EXT_scene_marker -------------------------- */ - -#ifndef GL_EXT_scene_marker -#define GL_EXT_scene_marker 1 - -typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); - -#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) -#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) - -#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) - -#endif /* GL_EXT_scene_marker */ - -/* ------------------------- GL_EXT_secondary_color ------------------------ */ - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 - -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E - -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); - -#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) -#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) -#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) -#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) -#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) -#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) -#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) -#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) -#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) -#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) -#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) -#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) -#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) -#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) -#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) -#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) -#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) - -#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) - -#endif /* GL_EXT_secondary_color */ - -/* --------------------- GL_EXT_separate_specular_color -------------------- */ - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 - -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA - -#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) - -#endif /* GL_EXT_separate_specular_color */ - -/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 - -#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) - -#endif /* GL_EXT_shadow_funcs */ - -/* --------------------- GL_EXT_shared_texture_palette --------------------- */ - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 - -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB - -#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) - -#endif /* GL_EXT_shared_texture_palette */ - -/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 - -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 - -#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) - -#endif /* GL_EXT_stencil_clear_tag */ - -/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 - -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 - -typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); - -#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) - -#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) - -#endif /* GL_EXT_stencil_two_side */ - -/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 - -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 - -#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) - -#endif /* GL_EXT_stencil_wrap */ - -/* --------------------------- GL_EXT_subtexture --------------------------- */ - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 - -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); - -#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) -#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) -#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) - -#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) - -#endif /* GL_EXT_subtexture */ - -/* ----------------------------- GL_EXT_texture ---------------------------- */ - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 - -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 - -#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) - -#endif /* GL_EXT_texture */ - -/* ---------------------------- GL_EXT_texture3D --------------------------- */ - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 - -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 - -typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); - -#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) - -#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) - -#endif /* GL_EXT_texture3D */ - -/* -------------------------- GL_EXT_texture_array ------------------------- */ - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 - -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D - -#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) - -#endif /* GL_EXT_texture_array */ - -/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 - -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E - -typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); - -#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) - -#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) - -#endif /* GL_EXT_texture_buffer_object */ - -/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ - -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_EXT_texture_compression_dxt1 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 - -#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) - -#endif /* GL_EXT_texture_compression_dxt1 */ - -/* -------------------- GL_EXT_texture_compression_latc -------------------- */ - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 - -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 - -#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) - -#endif /* GL_EXT_texture_compression_latc */ - -/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 - -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE - -#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) - -#endif /* GL_EXT_texture_compression_rgtc */ - -/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_EXT_texture_compression_s3tc 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - -#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) - -#endif /* GL_EXT_texture_compression_s3tc */ - -/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ - -#ifndef GL_EXT_texture_cube_map -#define GL_EXT_texture_cube_map 1 - -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C - -#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) - -#endif /* GL_EXT_texture_cube_map */ - -/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ - -#ifndef GL_EXT_texture_edge_clamp -#define GL_EXT_texture_edge_clamp 1 - -#define GL_CLAMP_TO_EDGE_EXT 0x812F - -#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) - -#endif /* GL_EXT_texture_edge_clamp */ - -/* --------------------------- GL_EXT_texture_env -------------------------- */ - -#ifndef GL_EXT_texture_env -#define GL_EXT_texture_env 1 - -#define GL_TEXTURE_ENV0_EXT 0 -#define GL_ENV_BLEND_EXT 0 -#define GL_TEXTURE_ENV_SHIFT_EXT 0 -#define GL_ENV_REPLACE_EXT 0 -#define GL_ENV_ADD_EXT 0 -#define GL_ENV_SUBTRACT_EXT 0 -#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 -#define GL_ENV_REVERSE_SUBTRACT_EXT 0 -#define GL_ENV_REVERSE_BLEND_EXT 0 -#define GL_ENV_COPY_EXT 0 -#define GL_ENV_MODULATE_EXT 0 - -#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) - -#endif /* GL_EXT_texture_env */ - -/* ------------------------- GL_EXT_texture_env_add ------------------------ */ - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 - -#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) - -#endif /* GL_EXT_texture_env_add */ - -/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 - -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A - -#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) - -#endif /* GL_EXT_texture_env_combine */ - -/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 - -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 - -#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) - -#endif /* GL_EXT_texture_env_dot3 */ - -/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 - -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF - -#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) - -#endif /* GL_EXT_texture_filter_anisotropic */ - -/* ------------------------- GL_EXT_texture_integer ------------------------ */ - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 - -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E - -typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); - -#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) -#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) -#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) -#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) -#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) -#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) - -#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) - -#endif /* GL_EXT_texture_integer */ - -/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 - -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 - -#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) - -#endif /* GL_EXT_texture_lod_bias */ - -/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 - -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 - -#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) - -#endif /* GL_EXT_texture_mirror_clamp */ - -/* ------------------------- GL_EXT_texture_object ------------------------- */ - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 - -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A - -typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); -typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); -typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); -typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); - -#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) -#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) -#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) -#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) -#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) -#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) - -#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) - -#endif /* GL_EXT_texture_object */ - -/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 - -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF - -typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); - -#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) - -#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) - -#endif /* GL_EXT_texture_perturb_normal */ - -/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ - -#ifndef GL_EXT_texture_rectangle -#define GL_EXT_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 - -#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) - -#endif /* GL_EXT_texture_rectangle */ - -/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 - -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F - -#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) - -#endif /* GL_EXT_texture_sRGB */ - -/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 - -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F - -#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) - -#endif /* GL_EXT_texture_shared_exponent */ - -/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ - -#ifndef GL_EXT_texture_swizzle -#define GL_EXT_texture_swizzle 1 - -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 - -#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) - -#endif /* GL_EXT_texture_swizzle */ - -/* --------------------------- GL_EXT_timer_query -------------------------- */ - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 - -#define GL_TIME_ELAPSED_EXT 0x88BF - -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); -typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); - -#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) -#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) - -#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) - -#endif /* GL_EXT_timer_query */ - -/* ----------------------- GL_EXT_transform_feedback ----------------------- */ - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 - -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F - -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, char *name); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); - -#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) -#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) -#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) -#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) -#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) -#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) -#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) - -#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) - -#endif /* GL_EXT_transform_feedback */ - -/* -------------------------- GL_EXT_vertex_array -------------------------- */ - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 - -#define GL_DOUBLE_EXT 0x140A -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 - -typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); -typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); -typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void** params); -typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); - -#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) -#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) -#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) -#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) -#define glGetPointervEXT GLEW_GET_FUN(__glewGetPointervEXT) -#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) -#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) -#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) -#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) - -#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) - -#endif /* GL_EXT_vertex_array */ - -/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 - -#define GL_BGRA 0x80E1 - -#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) - -#endif /* GL_EXT_vertex_array_bgra */ - -/* -------------------------- GL_EXT_vertex_shader ------------------------- */ - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 - -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED - -typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); -typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); -typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); -typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); -typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); -typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); -typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); - -#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) -#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) -#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) -#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) -#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) -#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) -#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) -#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) -#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) -#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) -#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) -#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) -#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) -#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) -#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) -#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) -#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) -#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) -#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) -#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) -#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) -#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) -#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) -#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) -#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) -#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) -#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) -#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) -#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) -#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) -#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) -#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) -#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) -#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) -#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) -#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) -#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) -#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) -#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) -#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) -#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) -#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) - -#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) - -#endif /* GL_EXT_vertex_shader */ - -/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 - -#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 -#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 -#define GL_MODELVIEW0_EXT 0x1700 -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 - -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); - -#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) -#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) -#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) - -#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) - -#endif /* GL_EXT_vertex_weighting */ - -/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 - -typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); - -#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) - -#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) - -#endif /* GL_GREMEDY_frame_terminator */ - -/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 - -typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); - -#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) - -#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) - -#endif /* GL_GREMEDY_string_marker */ - -/* --------------------- GL_HP_convolution_border_modes -------------------- */ - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 - -#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) - -#endif /* GL_HP_convolution_border_modes */ - -/* ------------------------- GL_HP_image_transform ------------------------- */ - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 - -typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) -#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) -#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) -#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) -#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) -#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) - -#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) - -#endif /* GL_HP_image_transform */ - -/* -------------------------- GL_HP_occlusion_test ------------------------- */ - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 - -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 - -#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) - -#endif /* GL_HP_occlusion_test */ - -/* ------------------------- GL_HP_texture_lighting ------------------------ */ - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 - -#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) - -#endif /* GL_HP_texture_lighting */ - -/* --------------------------- GL_IBM_cull_vertex -------------------------- */ - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 - -#define GL_CULL_VERTEX_IBM 103050 - -#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) - -#endif /* GL_IBM_cull_vertex */ - -/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 - -typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); - -#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) -#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) - -#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) - -#endif /* GL_IBM_multimode_draw_arrays */ - -/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 - -#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 - -#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) - -#endif /* GL_IBM_rasterpos_clip */ - -/* --------------------------- GL_IBM_static_data -------------------------- */ - -#ifndef GL_IBM_static_data -#define GL_IBM_static_data 1 - -#define GL_ALL_STATIC_DATA_IBM 103060 -#define GL_STATIC_VERTEX_ARRAY_IBM 103061 - -#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) - -#endif /* GL_IBM_static_data */ - -/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_IBM_texture_mirrored_repeat 1 - -#define GL_MIRRORED_REPEAT_IBM 0x8370 - -#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) - -#endif /* GL_IBM_texture_mirrored_repeat */ - -/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 - -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 - -typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); - -#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) -#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) -#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) -#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) -#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) -#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) -#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) -#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) - -#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) - -#endif /* GL_IBM_vertex_array_lists */ - -/* -------------------------- GL_INGR_color_clamp -------------------------- */ - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 - -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 - -#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) - -#endif /* GL_INGR_color_clamp */ - -/* ------------------------- GL_INGR_interlace_read ------------------------ */ - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 - -#define GL_INTERLACE_READ_INGR 0x8568 - -#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) - -#endif /* GL_INGR_interlace_read */ - -/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 - -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 - -typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); - -#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) -#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) -#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) -#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) - -#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) - -#endif /* GL_INTEL_parallel_arrays */ - -/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ - -#ifndef GL_INTEL_texture_scissor -#define GL_INTEL_texture_scissor 1 - -typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); -typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); - -#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) -#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) - -#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) - -#endif /* GL_INTEL_texture_scissor */ - -/* -------------------------- GL_KTX_buffer_region ------------------------- */ - -#ifndef GL_KTX_buffer_region -#define GL_KTX_buffer_region 1 - -#define GL_KTX_FRONT_REGION 0x0 -#define GL_KTX_BACK_REGION 0x1 -#define GL_KTX_Z_REGION 0x2 -#define GL_KTX_STENCIL_REGION 0x3 - -typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); -typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); -typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); -typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); -typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); - -#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) -#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) -#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) -#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) -#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) - -#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) - -#endif /* GL_KTX_buffer_region */ - -/* ------------------------- GL_MESAX_texture_stack ------------------------ */ - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 - -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E - -#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) - -#endif /* GL_MESAX_texture_stack */ - -/* -------------------------- GL_MESA_pack_invert -------------------------- */ - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 - -#define GL_PACK_INVERT_MESA 0x8758 - -#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) - -#endif /* GL_MESA_pack_invert */ - -/* ------------------------- GL_MESA_resize_buffers ------------------------ */ - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 - -typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); - -#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) - -#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) - -#endif /* GL_MESA_resize_buffers */ - -/* --------------------------- GL_MESA_window_pos -------------------------- */ - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 - -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); - -#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) -#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) -#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) -#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) -#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) -#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) -#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) -#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) -#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) -#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) -#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) -#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) -#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) -#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) -#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) -#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) -#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) -#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) -#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) -#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) -#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) -#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) -#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) -#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) - -#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) - -#endif /* GL_MESA_window_pos */ - -/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 - -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 - -#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) - -#endif /* GL_MESA_ycbcr_texture */ - -/* --------------------------- GL_NV_blend_square -------------------------- */ - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 - -#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) - -#endif /* GL_NV_blend_square */ - -/* ------------------------ GL_NV_conditional_render ----------------------- */ - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 - -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 - -typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); - -#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) -#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) - -#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) - -#endif /* GL_NV_conditional_render */ - -/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 - -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F - -#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) - -#endif /* GL_NV_copy_depth_to_color */ - -/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 - -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF - -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); - -#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) -#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) -#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) - -#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) - -#endif /* GL_NV_depth_buffer_float */ - -/* --------------------------- GL_NV_depth_clamp --------------------------- */ - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 - -#define GL_DEPTH_CLAMP_NV 0x864F - -#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) - -#endif /* GL_NV_depth_clamp */ - -/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ - -#ifndef GL_NV_depth_range_unclamped -#define GL_NV_depth_range_unclamped 1 - -#define GL_SAMPLE_COUNT_BITS_NV 0x8864 -#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 -#define GL_QUERY_RESULT_NV 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 -#define GL_SAMPLE_COUNT_NV 0x8914 - -#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) - -#endif /* GL_NV_depth_range_unclamped */ - -/* ---------------------------- GL_NV_evaluators --------------------------- */ - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 - -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 - -typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); -typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); -typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); - -#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) -#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) -#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) -#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) -#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) -#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) -#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) -#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) -#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) - -#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) - -#endif /* GL_NV_evaluators */ - -/* ----------------------- GL_NV_explicit_multisample ---------------------- */ - -#ifndef GL_NV_explicit_multisample -#define GL_NV_explicit_multisample 1 - -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 - -typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); -typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); - -#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) -#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) -#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) - -#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) - -#endif /* GL_NV_explicit_multisample */ - -/* ------------------------------ GL_NV_fence ------------------------------ */ - -#ifndef GL_NV_fence -#define GL_NV_fence 1 - -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 - -typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); -typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); -typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); -typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); - -#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) -#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) -#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) -#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) -#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) -#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) -#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) - -#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) - -#endif /* GL_NV_fence */ - -/* --------------------------- GL_NV_float_buffer -------------------------- */ - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 - -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E - -#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) - -#endif /* GL_NV_float_buffer */ - -/* --------------------------- GL_NV_fog_distance -------------------------- */ - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 - -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C - -#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) - -#endif /* GL_NV_fog_distance */ - -/* ------------------------- GL_NV_fragment_program ------------------------ */ - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 - -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 - -typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); - -#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) -#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) -#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) -#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) -#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) -#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) - -#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) - -#endif /* GL_NV_fragment_program */ - -/* ------------------------ GL_NV_fragment_program2 ------------------------ */ - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 - -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 - -#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) - -#endif /* GL_NV_fragment_program2 */ - -/* ------------------------ GL_NV_fragment_program4 ------------------------ */ - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 - -#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) - -#endif /* GL_NV_fragment_program4 */ - -/* --------------------- GL_NV_fragment_program_option --------------------- */ - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 - -#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) - -#endif /* GL_NV_fragment_program_option */ - -/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 - -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 - -typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); - -#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) - -#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) - -#endif /* GL_NV_framebuffer_multisample_coverage */ - -/* ------------------------ GL_NV_geometry_program4 ------------------------ */ - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 - -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 - -typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); - -#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) - -#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) - -#endif /* GL_NV_geometry_program4 */ - -/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 - -#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) - -#endif /* GL_NV_geometry_shader4 */ - -/* --------------------------- GL_NV_gpu_program4 -------------------------- */ - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 - -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 - -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); - -#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) -#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) -#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) -#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) -#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) -#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) -#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) -#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) -#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) -#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) -#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) -#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) - -#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) - -#endif /* GL_NV_gpu_program4 */ - -/* ---------------------------- GL_NV_half_float --------------------------- */ - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 - -#define GL_HALF_FLOAT_NV 0x140B - -typedef unsigned short GLhalf; - -typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); -typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); -typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); -typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); -typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); -typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); -typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); -typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); -typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); -typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); -typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); -typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); -typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); - -#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) -#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) -#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) -#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) -#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) -#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) -#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) -#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) -#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) -#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) -#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) -#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) -#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) -#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) -#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) -#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) -#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) -#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) -#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) -#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) -#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) -#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) -#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) -#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) -#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) -#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) -#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) -#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) -#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) -#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) -#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) -#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) -#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) -#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) -#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) -#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) -#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) -#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) -#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) -#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) -#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) -#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) -#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) -#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) -#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) -#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) - -#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) - -#endif /* GL_NV_half_float */ - -/* ------------------------ GL_NV_light_max_exponent ----------------------- */ - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 - -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 - -#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) - -#endif /* GL_NV_light_max_exponent */ - -/* --------------------- GL_NV_multisample_filter_hint --------------------- */ - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 - -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 - -#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) - -#endif /* GL_NV_multisample_filter_hint */ - -/* ------------------------- GL_NV_occlusion_query ------------------------- */ - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 - -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 - -typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); - -#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) -#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) -#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) -#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) -#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) -#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) -#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) - -#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) - -#endif /* GL_NV_occlusion_query */ - -/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA - -#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) - -#endif /* GL_NV_packed_depth_stencil */ - -/* --------------------- GL_NV_parameter_buffer_object --------------------- */ - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 - -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 - -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); - -#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) -#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) -#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) - -#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) - -#endif /* GL_NV_parameter_buffer_object */ - -/* ------------------------- GL_NV_pixel_data_range ------------------------ */ - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 - -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D - -typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); - -#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) -#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) - -#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) - -#endif /* GL_NV_pixel_data_range */ - -/* --------------------------- GL_NV_point_sprite -------------------------- */ - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 - -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 - -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); - -#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) -#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) - -#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) - -#endif /* GL_NV_point_sprite */ - -/* -------------------------- GL_NV_present_video -------------------------- */ - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 - -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B - -typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); -typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); -typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -typedef void (GLAPIENTRY * PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint* params); - -#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) -#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) -#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) -#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) -#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) -#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) -#define glVideoParameterivNV GLEW_GET_FUN(__glewVideoParameterivNV) - -#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) - -#endif /* GL_NV_present_video */ - -/* ------------------------ GL_NV_primitive_restart ------------------------ */ - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 - -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 - -typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); - -#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) -#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) - -#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) - -#endif /* GL_NV_primitive_restart */ - -/* ------------------------ GL_NV_register_combiners ----------------------- */ - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 - -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 - -typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); - -#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) -#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) -#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) -#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) -#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) -#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) -#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) -#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) -#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) -#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) -#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) -#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) -#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) - -#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) - -#endif /* GL_NV_register_combiners */ - -/* ----------------------- GL_NV_register_combiners2 ----------------------- */ - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 - -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 - -typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); - -#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) -#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) - -#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) - -#endif /* GL_NV_register_combiners2 */ - -/* -------------------------- GL_NV_texgen_emboss -------------------------- */ - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 - -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F - -#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) - -#endif /* GL_NV_texgen_emboss */ - -/* ------------------------ GL_NV_texgen_reflection ------------------------ */ - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 - -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 - -#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) - -#endif /* GL_NV_texgen_reflection */ - -/* --------------------- GL_NV_texture_compression_vtc --------------------- */ - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 - -#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) - -#endif /* GL_NV_texture_compression_vtc */ - -/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 - -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B - -#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) - -#endif /* GL_NV_texture_env_combine4 */ - -/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 - -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F - -#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) - -#endif /* GL_NV_texture_expand_normal */ - -/* ------------------------ GL_NV_texture_rectangle ------------------------ */ - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 - -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 - -#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) - -#endif /* GL_NV_texture_rectangle */ - -/* -------------------------- GL_NV_texture_shader ------------------------- */ - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 - -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F - -#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) - -#endif /* GL_NV_texture_shader */ - -/* ------------------------- GL_NV_texture_shader2 ------------------------- */ - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 - -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D - -#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) - -#endif /* GL_NV_texture_shader2 */ - -/* ------------------------- GL_NV_texture_shader3 ------------------------- */ - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 - -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 - -#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) - -#endif /* GL_NV_texture_shader3 */ - -/* ------------------------ GL_NV_transform_feedback ----------------------- */ - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 - -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F - -typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); -typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); - -#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) -#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) -#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) -#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) -#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) -#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) -#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) -#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) -#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) -#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) -#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) - -#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) - -#endif /* GL_NV_transform_feedback */ - -/* ------------------------ GL_NV_vertex_array_range ----------------------- */ - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 - -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 - -typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); - -#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) -#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) - -#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) - -#endif /* GL_NV_vertex_array_range */ - -/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 - -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 - -#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) - -#endif /* GL_NV_vertex_array_range2 */ - -/* -------------------------- GL_NV_vertex_program ------------------------- */ - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 - -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F - -typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); -typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); -typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); -typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); -typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint num, const GLdouble* params); -typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint num, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); -typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); -typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); - -#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) -#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) -#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) -#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) -#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) -#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) -#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) -#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) -#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) -#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) -#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) -#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) -#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) -#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) -#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) -#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) -#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) -#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) -#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) -#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) -#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) -#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) -#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) -#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) -#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) -#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) -#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) -#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) -#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) -#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) -#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) -#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) -#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) -#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) -#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) -#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) -#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) -#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) -#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) -#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) -#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) -#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) -#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) -#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) -#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) -#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) -#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) -#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) -#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) -#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) -#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) -#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) -#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) -#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) -#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) -#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) -#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) -#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) -#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) -#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) -#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) -#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) -#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) -#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) - -#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) - -#endif /* GL_NV_vertex_program */ - -/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 - -#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) - -#endif /* GL_NV_vertex_program1_1 */ - -/* ------------------------- GL_NV_vertex_program2 ------------------------- */ - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 - -#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) - -#endif /* GL_NV_vertex_program2 */ - -/* ---------------------- GL_NV_vertex_program2_option --------------------- */ - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 - -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 - -#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) - -#endif /* GL_NV_vertex_program2_option */ - -/* ------------------------- GL_NV_vertex_program3 ------------------------- */ - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 - -#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C - -#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) - -#endif /* GL_NV_vertex_program3 */ - -/* ------------------------- GL_NV_vertex_program4 ------------------------- */ - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 - -#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) - -#endif /* GL_NV_vertex_program4 */ - -/* ------------------------ GL_OES_byte_coordinates ------------------------ */ - -#ifndef GL_OES_byte_coordinates -#define GL_OES_byte_coordinates 1 - -#define GL_BYTE 0x1400 - -#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) - -#endif /* GL_OES_byte_coordinates */ - -/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ - -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 - -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 - -#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) - -#endif /* GL_OES_compressed_paletted_texture */ - -/* --------------------------- GL_OES_read_format -------------------------- */ - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 - -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B - -#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) - -#endif /* GL_OES_read_format */ - -/* ------------------------ GL_OES_single_precision ------------------------ */ - -#ifndef GL_OES_single_precision -#define GL_OES_single_precision 1 - -typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth); -typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); -typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); -typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); -typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); -typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); - -#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) -#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) -#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) -#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) -#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) -#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) - -#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) - -#endif /* GL_OES_single_precision */ - -/* ---------------------------- GL_OML_interlace --------------------------- */ - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 - -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 - -#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) - -#endif /* GL_OML_interlace */ - -/* ---------------------------- GL_OML_resample ---------------------------- */ - -#ifndef GL_OML_resample -#define GL_OML_resample 1 - -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 - -#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) - -#endif /* GL_OML_resample */ - -/* ---------------------------- GL_OML_subsample --------------------------- */ - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 - -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 - -#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) - -#endif /* GL_OML_subsample */ - -/* --------------------------- GL_PGI_misc_hints --------------------------- */ - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 - -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 -#define GL_CONSERVE_MEMORY_HINT_PGI 107005 -#define GL_RECLAIM_MEMORY_HINT_PGI 107006 -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 -#define GL_ALWAYS_FAST_HINT_PGI 107020 -#define GL_ALWAYS_SOFT_HINT_PGI 107021 -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 -#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 -#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 -#define GL_STRICT_LIGHTING_HINT_PGI 107031 -#define GL_STRICT_SCISSOR_HINT_PGI 107032 -#define GL_FULL_STIPPLE_HINT_PGI 107033 -#define GL_CLIP_NEAR_HINT_PGI 107040 -#define GL_CLIP_FAR_HINT_PGI 107041 -#define GL_WIDE_LINE_HINT_PGI 107042 -#define GL_BACK_NORMALS_HINT_PGI 107043 - -#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) - -#endif /* GL_PGI_misc_hints */ - -/* -------------------------- GL_PGI_vertex_hints -------------------------- */ - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 - -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_VERTEX_DATA_HINT_PGI 107050 -#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 -#define GL_MATERIAL_SIDE_HINT_PGI 107052 -#define GL_MAX_VERTEX_HINT_PGI 107053 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 - -#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) - -#endif /* GL_PGI_vertex_hints */ - -/* ----------------------- GL_REND_screen_coordinates ---------------------- */ - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 - -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 - -#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) - -#endif /* GL_REND_screen_coordinates */ - -/* ------------------------------- GL_S3_s3tc ------------------------------ */ - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 - -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#define GL_RGBA_DXT5_S3TC 0x83A4 -#define GL_RGBA4_DXT5_S3TC 0x83A5 - -#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) - -#endif /* GL_S3_s3tc */ - -/* -------------------------- GL_SGIS_color_range -------------------------- */ - -#ifndef GL_SGIS_color_range -#define GL_SGIS_color_range 1 - -#define GL_EXTENDED_RANGE_SGIS 0x85A5 -#define GL_MIN_RED_SGIS 0x85A6 -#define GL_MAX_RED_SGIS 0x85A7 -#define GL_MIN_GREEN_SGIS 0x85A8 -#define GL_MAX_GREEN_SGIS 0x85A9 -#define GL_MIN_BLUE_SGIS 0x85AA -#define GL_MAX_BLUE_SGIS 0x85AB -#define GL_MIN_ALPHA_SGIS 0x85AC -#define GL_MAX_ALPHA_SGIS 0x85AD - -#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) - -#endif /* GL_SGIS_color_range */ - -/* ------------------------- GL_SGIS_detail_texture ------------------------ */ - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 - -typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); - -#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) -#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) - -#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) - -#endif /* GL_SGIS_detail_texture */ - -/* -------------------------- GL_SGIS_fog_function ------------------------- */ - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 - -typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); -typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); - -#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) -#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) - -#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) - -#endif /* GL_SGIS_fog_function */ - -/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 - -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 - -#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) - -#endif /* GL_SGIS_generate_mipmap */ - -/* -------------------------- GL_SGIS_multisample -------------------------- */ - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 - -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 - -typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); - -#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) -#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) - -#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) - -#endif /* GL_SGIS_multisample */ - -/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 - -#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) - -#endif /* GL_SGIS_pixel_texture */ - -/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 - -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 - -#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) - -#endif /* GL_SGIS_point_line_texgen */ - -/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 - -typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); -typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); - -#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) -#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) - -#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) - -#endif /* GL_SGIS_sharpen_texture */ - -/* --------------------------- GL_SGIS_texture4D --------------------------- */ - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 - -typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); -typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); - -#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) -#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) - -#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) - -#endif /* GL_SGIS_texture4D */ - -/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 - -#define GL_CLAMP_TO_BORDER_SGIS 0x812D - -#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) - -#endif /* GL_SGIS_texture_border_clamp */ - -/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 - -#define GL_CLAMP_TO_EDGE_SGIS 0x812F - -#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) - -#endif /* GL_SGIS_texture_edge_clamp */ - -/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 - -typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); -typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); - -#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) -#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) - -#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) - -#endif /* GL_SGIS_texture_filter4 */ - -/* -------------------------- GL_SGIS_texture_lod -------------------------- */ - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 - -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D - -#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) - -#endif /* GL_SGIS_texture_lod */ - -/* ------------------------- GL_SGIS_texture_select ------------------------ */ - -#ifndef GL_SGIS_texture_select -#define GL_SGIS_texture_select 1 - -#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) - -#endif /* GL_SGIS_texture_select */ - -/* ----------------------------- GL_SGIX_async ----------------------------- */ - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 - -#define GL_ASYNC_MARKER_SGIX 0x8329 - -typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); -typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); - -#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) -#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) -#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) -#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) -#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) -#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) - -#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) - -#endif /* GL_SGIX_async */ - -/* ------------------------ GL_SGIX_async_histogram ------------------------ */ - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 - -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D - -#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) - -#endif /* GL_SGIX_async_histogram */ - -/* -------------------------- GL_SGIX_async_pixel -------------------------- */ - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 - -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 - -#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) - -#endif /* GL_SGIX_async_pixel */ - -/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 - -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 - -#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) - -#endif /* GL_SGIX_blend_alpha_minmax */ - -/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 - -#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) - -#endif /* GL_SGIX_clipmap */ - -/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 - -#define GL_CONVOLUTION_HINT_SGIX 0x8316 - -#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) - -#endif /* GL_SGIX_convolution_accuracy */ - -/* ------------------------- GL_SGIX_depth_texture ------------------------- */ - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 - -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 - -#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) - -#endif /* GL_SGIX_depth_texture */ - -/* -------------------------- GL_SGIX_flush_raster ------------------------- */ - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 - -typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); - -#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) - -#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) - -#endif /* GL_SGIX_flush_raster */ - -/* --------------------------- GL_SGIX_fog_offset -------------------------- */ - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 - -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 - -#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) - -#endif /* GL_SGIX_fog_offset */ - -/* -------------------------- GL_SGIX_fog_texture -------------------------- */ - -#ifndef GL_SGIX_fog_texture -#define GL_SGIX_fog_texture 1 - -#define GL_TEXTURE_FOG_SGIX 0 -#define GL_FOG_PATCHY_FACTOR_SGIX 0 -#define GL_FRAGMENT_FOG_SGIX 0 - -typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); - -#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) - -#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) - -#endif /* GL_SGIX_fog_texture */ - -/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ - -#ifndef GL_SGIX_fragment_specular_lighting -#define GL_SGIX_fragment_specular_lighting 1 - -typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); -typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); -typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); - -#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) -#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) -#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) -#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) -#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) -#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) -#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) -#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) -#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) -#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) -#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) -#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) -#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) -#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) -#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) -#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) -#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) - -#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) - -#endif /* GL_SGIX_fragment_specular_lighting */ - -/* --------------------------- GL_SGIX_framezoom --------------------------- */ - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 - -typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); - -#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) - -#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) - -#endif /* GL_SGIX_framezoom */ - -/* --------------------------- GL_SGIX_interlace --------------------------- */ - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 - -#define GL_INTERLACE_SGIX 0x8094 - -#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) - -#endif /* GL_SGIX_interlace */ - -/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 - -#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) - -#endif /* GL_SGIX_ir_instrument1 */ - -/* ------------------------- GL_SGIX_list_priority ------------------------- */ - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 - -#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) - -#endif /* GL_SGIX_list_priority */ - -/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 - -typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); - -#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) - -#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) - -#endif /* GL_SGIX_pixel_texture */ - -/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ - -#ifndef GL_SGIX_pixel_texture_bits -#define GL_SGIX_pixel_texture_bits 1 - -#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) - -#endif /* GL_SGIX_pixel_texture_bits */ - -/* ------------------------ GL_SGIX_reference_plane ------------------------ */ - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 - -typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); - -#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) - -#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) - -#endif /* GL_SGIX_reference_plane */ - -/* ---------------------------- GL_SGIX_resample --------------------------- */ - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 - -#define GL_PACK_RESAMPLE_SGIX 0x842E -#define GL_UNPACK_RESAMPLE_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 - -#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) - -#endif /* GL_SGIX_resample */ - -/* ----------------------------- GL_SGIX_shadow ---------------------------- */ - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 - -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D - -#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) - -#endif /* GL_SGIX_shadow */ - -/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 - -#define GL_SHADOW_AMBIENT_SGIX 0x80BF - -#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) - -#endif /* GL_SGIX_shadow_ambient */ - -/* ----------------------------- GL_SGIX_sprite ---------------------------- */ - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 - -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); - -#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) -#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) -#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) -#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) - -#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) - -#endif /* GL_SGIX_sprite */ - -/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 - -typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); - -#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) - -#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) - -#endif /* GL_SGIX_tag_sample_buffer */ - -/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 - -#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) - -#endif /* GL_SGIX_texture_add_env */ - -/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 - -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B - -#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) - -#endif /* GL_SGIX_texture_coordinate_clamp */ - -/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 - -#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) - -#endif /* GL_SGIX_texture_lod_bias */ - -/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 - -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E - -#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) - -#endif /* GL_SGIX_texture_multi_buffer */ - -/* ------------------------- GL_SGIX_texture_range ------------------------- */ - -#ifndef GL_SGIX_texture_range -#define GL_SGIX_texture_range 1 - -#define GL_RGB_SIGNED_SGIX 0x85E0 -#define GL_RGBA_SIGNED_SGIX 0x85E1 -#define GL_ALPHA_SIGNED_SGIX 0x85E2 -#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 -#define GL_INTENSITY_SIGNED_SGIX 0x85E4 -#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 -#define GL_RGB16_SIGNED_SGIX 0x85E6 -#define GL_RGBA16_SIGNED_SGIX 0x85E7 -#define GL_ALPHA16_SIGNED_SGIX 0x85E8 -#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 -#define GL_INTENSITY16_SIGNED_SGIX 0x85EA -#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB -#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC -#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED -#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE -#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF -#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 -#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 -#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 -#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 -#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 -#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 -#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 -#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 -#define GL_MIN_LUMINANCE_SGIS 0x85F8 -#define GL_MAX_LUMINANCE_SGIS 0x85F9 -#define GL_MIN_INTENSITY_SGIS 0x85FA -#define GL_MAX_INTENSITY_SGIS 0x85FB - -#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) - -#endif /* GL_SGIX_texture_range */ - -/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 - -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C - -#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) - -#endif /* GL_SGIX_texture_scale_bias */ - -/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 - -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF - -#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) - -#endif /* GL_SGIX_vertex_preclip */ - -/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ - -#ifndef GL_SGIX_vertex_preclip_hint -#define GL_SGIX_vertex_preclip_hint 1 - -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF - -#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) - -#endif /* GL_SGIX_vertex_preclip_hint */ - -/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 - -#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) - -#endif /* GL_SGIX_ycrcb */ - -/* -------------------------- GL_SGI_color_matrix -------------------------- */ - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 - -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB - -#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) - -#endif /* GL_SGI_color_matrix */ - -/* --------------------------- GL_SGI_color_table -------------------------- */ - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 - -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF - -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); -typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); -typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); -typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); - -#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) -#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) -#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) -#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) -#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) -#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) -#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) - -#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) - -#endif /* GL_SGI_color_table */ - -/* ----------------------- GL_SGI_texture_color_table ---------------------- */ - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 - -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD - -#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) - -#endif /* GL_SGI_texture_color_table */ - -/* ------------------------- GL_SUNX_constant_data ------------------------- */ - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 - -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 - -typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); - -#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) - -#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) - -#endif /* GL_SUNX_constant_data */ - -/* -------------------- GL_SUN_convolution_border_modes -------------------- */ - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 - -#define GL_WRAP_BORDER_SUN 0x81D4 - -#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) - -#endif /* GL_SUN_convolution_border_modes */ - -/* -------------------------- GL_SUN_global_alpha -------------------------- */ - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 - -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA - -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); - -#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) -#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) -#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) -#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) -#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) -#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) -#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) -#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) - -#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) - -#endif /* GL_SUN_global_alpha */ - -/* --------------------------- GL_SUN_mesh_array --------------------------- */ - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 - -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 - -#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) - -#endif /* GL_SUN_mesh_array */ - -/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ - -#ifndef GL_SUN_read_video_pixels -#define GL_SUN_read_video_pixels 1 - -typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); - -#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) - -#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) - -#endif /* GL_SUN_read_video_pixels */ - -/* --------------------------- GL_SUN_slice_accum -------------------------- */ - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 - -#define GL_SLICE_ACCUM_SUN 0x85CC - -#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) - -#endif /* GL_SUN_slice_accum */ - -/* -------------------------- GL_SUN_triangle_list ------------------------- */ - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 - -#define GL_RESTART_SUN 0x01 -#define GL_REPLACE_MIDDLE_SUN 0x02 -#define GL_REPLACE_OLDEST_SUN 0x03 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB - -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); - -#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) -#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) -#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) -#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) -#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) -#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) -#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) - -#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) - -#endif /* GL_SUN_triangle_list */ - -/* ----------------------------- GL_SUN_vertex ----------------------------- */ - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 - -typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); - -#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) -#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) -#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) -#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) -#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) -#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) -#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) -#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) -#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) -#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) -#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) -#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) -#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) -#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) -#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) -#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) -#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) -#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) -#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) -#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) -#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) -#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) -#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) -#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) -#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) -#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) -#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) -#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) -#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) -#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) -#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) -#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) -#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) -#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) -#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) -#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) - -#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) - -#endif /* GL_SUN_vertex */ - -/* -------------------------- GL_WIN_phong_shading ------------------------- */ - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 - -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB - -#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) - -#endif /* GL_WIN_phong_shading */ - -/* -------------------------- GL_WIN_specular_fog -------------------------- */ - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 - -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC - -#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) - -#endif /* GL_WIN_specular_fog */ - -/* ---------------------------- GL_WIN_swap_hint --------------------------- */ - -#ifndef GL_WIN_swap_hint -#define GL_WIN_swap_hint 1 - -typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); - -#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) - -#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) - -#endif /* GL_WIN_swap_hint */ - -/* ------------------------------------------------------------------------- */ - -#if defined(GLEW_MX) && defined(_WIN32) -#define GLEW_FUN_EXPORT -#else -#define GLEW_FUN_EXPORT GLEWAPI -#endif /* GLEW_MX */ - -#if defined(GLEW_MX) -#define GLEW_VAR_EXPORT -#else -#define GLEW_VAR_EXPORT GLEWAPI -#endif /* GLEW_MX */ - -#if defined(GLEW_MX) && defined(_WIN32) -struct GLEWContextStruct -{ -#endif /* GLEW_MX */ - -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; - -GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; -GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; -GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; - -GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; -GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; -GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; -GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; -GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; -GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; -GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; -GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; -GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; -GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; -GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; -GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; -GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; -GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; -GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; -GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; -GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; -GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; - -GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; -GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; -GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; -GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; -GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; -GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; -GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; -GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; -GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; -GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; -GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; -GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; -GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; -GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; -GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; -GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; -GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; -GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; -GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; -GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; -GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; -GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; -GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; -GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; -GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; -GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; -GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; -GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; -GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; -GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; -GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; -GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; -GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; -GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; -GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; -GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; -GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; -GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; -GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; -GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; -GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; -GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; - -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; - -GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; -GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; -GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; -GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; -GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; -GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; -GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; -GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; -GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; -GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; -GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; -GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; - -GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; -GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; - -GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; -GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; -GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; -GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; -GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; -GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; -GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; -GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; - -GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; -GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; - -GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; - -GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; - -GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; -GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; -GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; -GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; -GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; -GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; -GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; -GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; -GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; -GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; -GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; - -GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; -GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; -GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; -GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; -GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; -GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; -GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; -GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; -GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; -GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; - -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; - -GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; -GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; - -GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; -GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; - -GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; - -GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; -GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; - -GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; -GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; -GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; -GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; -GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; -GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; - -GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; -GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; -GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; -GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; -GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; -GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; -GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; -GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; -GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; -GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; -GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; -GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; -GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; -GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; -GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; -GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; -GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; -GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; -GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; - -GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; - -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; - -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; -GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; -GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; - -GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; -GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; -GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; - -GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; -GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; -GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; -GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; -GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; - -GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; -GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; -GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; -GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; -GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; -GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; -GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; -GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; - -GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; -GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; -GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; -GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; -GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; -GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; - -GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; -GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; -GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; - -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; - -GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; - -GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; -GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; - -GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; -GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; -GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; -GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; - -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; -GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; -GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; -GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; -GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; -GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; -GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; -GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; -GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; - -GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; -GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; - -GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI; -GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI; - -GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; -GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; - -GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; -GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; -GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; -GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; -GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; -GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; -GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; -GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; - -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; - -GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; -GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; -GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; -GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; -GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; - -GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; -GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; -GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; - -GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; - -GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; - -GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; - -GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; -GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; - -GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; -GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; - -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; -GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; -GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; - -GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; -GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; - -GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; - -GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; -GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; - -GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; - -GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; -GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; -GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; -GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; -GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; -GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; -GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; -GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; -GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; -GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; -GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; -GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; -GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; -GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; -GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; -GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; -GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; -GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; -GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; -GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; -GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; -GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; -GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; -GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; -GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; -GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; -GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; - -GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; -GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; -GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; -GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; -GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; -GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; - -GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; -GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; - -GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; - -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; -GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; - -GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; -GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; - -GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; -GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; -GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; -GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; -GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; -GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; -GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; -GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; -GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; -GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; - -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; - -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; - -GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; -GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; -GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; -GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; - -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; -GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; -GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; -GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; -GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; - -GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; - -GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; - -GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; -GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; -GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; - -GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; -GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; - -GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; -GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; - -GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; - -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; -GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; -GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; - -GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; - -GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; -GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; - -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; - -GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; - -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; - -GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; - -GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; - -GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; -GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; -GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; - -GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; -GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; -GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; -GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; -GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; - -GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; - -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; -GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; - -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; - -GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; -GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; -GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; -GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; -GLEW_FUN_EXPORT PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT; -GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; -GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; - -GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; -GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; -GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; -GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; -GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; -GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; -GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; -GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; -GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; -GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; -GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; -GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; -GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; -GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; -GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; -GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; -GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; -GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; -GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; -GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; -GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; - -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; - -GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; - -GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; - -GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; -GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; -GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; - -GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; -GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; - -GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; -GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; -GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; -GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; -GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; - -GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; -GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; -GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; -GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; - -GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; -GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; - -GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; -GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; -GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; -GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; -GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; - -GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; - -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; -GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; - -GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; -GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; - -GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; -GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; - -GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; -GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; -GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; -GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; -GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; -GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; -GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; - -GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; -GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; -GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; - -GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; -GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; -GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; -GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; -GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; -GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; -GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; - -GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; -GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; - -GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; - -GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; -GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; -GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; -GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; -GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; -GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; -GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; -GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; -GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; -GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; -GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; -GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; -GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; -GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; -GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; - -GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; -GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; -GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; -GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; -GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; -GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; -GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; - -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; -GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; - -GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; -GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; - -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; -GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; - -GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; -GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; -GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; -GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; -GLEW_FUN_EXPORT PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV; - -GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; -GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; - -GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; -GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; -GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; -GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; -GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; - -GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; - -GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; -GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; -GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; -GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; -GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; -GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; -GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; -GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; - -GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; -GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; - -GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; -GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; -GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; -GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; -GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; -GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; -GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; -GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; -GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; -GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; -GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; -GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; -GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; -GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; - -GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; -GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; -GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; -GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; -GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; -GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; - -GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; -GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; - -GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; -GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; - -GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; -GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; - -GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; -GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; - -GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; -GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; - -GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; -GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; - -GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; -GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; -GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; -GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; -GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; -GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; - -GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; - -GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; - -GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; -GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; -GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; - -GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; - -GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; - -GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; - -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; -GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; - -GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; - -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; -GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; -GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; -GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; -GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; - -GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; - -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; -GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; - -GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; - -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; - -GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; -GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; -GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; - -GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; - -#if defined(GLEW_MX) && !defined(_WIN32) -struct GLEWContextStruct -{ -#endif /* GLEW_MX */ - -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; -GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; -GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; -GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; -GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; -GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; -GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; -GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; -GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; -GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; -GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; -GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; -GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; -GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; -GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; -GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; -GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; -GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; -GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; -GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; -GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; -GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; -GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; -GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; -GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; -GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; - -#ifdef GLEW_MX -}; /* GLEWContextStruct */ -#endif /* GLEW_MX */ - -/* ------------------------------------------------------------------------- */ - -/* error codes */ -#define GLEW_OK 0 -#define GLEW_NO_ERROR 0 -#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ -#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* GL 1.1 and up are not supported */ -#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* GLX 1.2 and up are not supported */ - -/* string codes */ -#define GLEW_VERSION 1 -#define GLEW_VERSION_MAJOR 2 -#define GLEW_VERSION_MINOR 3 -#define GLEW_VERSION_MICRO 4 - -/* API */ -#ifdef GLEW_MX - -typedef struct GLEWContextStruct GLEWContext; -GLEWAPI GLenum glewContextInit (GLEWContext* ctx); -GLEWAPI GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name); - -#define glewInit() glewContextInit(glewGetContext()) -#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) -#define glewIsExtensionSupported(x) glewIsSupported(x) - -#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x)) -#ifdef _WIN32 -# define GLEW_GET_FUN(x) glewGetContext()->x -#else -# define GLEW_GET_FUN(x) x -#endif - -#else /* GLEW_MX */ - -GLEWAPI GLenum glewInit (); -GLEWAPI GLboolean glewIsSupported (const char* name); -#define glewIsExtensionSupported(x) glewIsSupported(x) - -#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) -#define GLEW_GET_FUN(x) x - -#endif /* GLEW_MX */ - -GLEWAPI GLboolean glewExperimental; -GLEWAPI GLboolean glewGetExtension (const char* name); -GLEWAPI const GLubyte* glewGetErrorString (GLenum error); -GLEWAPI const GLubyte* glewGetString (GLenum name); - -#ifdef __cplusplus -} -#endif - -#ifdef GLEW_APIENTRY_DEFINED -#undef GLEW_APIENTRY_DEFINED -#undef APIENTRY -#undef GLAPIENTRY -#endif - -#ifdef GLEW_CALLBACK_DEFINED -#undef GLEW_CALLBACK_DEFINED -#undef CALLBACK -#endif - -#ifdef GLEW_WINGDIAPI_DEFINED -#undef GLEW_WINGDIAPI_DEFINED -#undef WINGDIAPI -#endif - -#undef GLAPI -/* #undef GLEWAPI */ - -#endif /* __glew_h__ */ diff --git a/WDL/lice/glew/include/GL/glxew.h b/WDL/lice/glew/include/GL/glxew.h deleted file mode 100644 index eeb4b280..00000000 --- a/WDL/lice/glew/include/GL/glxew.h +++ /dev/null @@ -1,1397 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __glxew_h__ -#define __glxew_h__ -#define __GLXEW_H__ - -#ifdef __glxext_h_ -#error glxext.h included before glxew.h -#endif -#ifdef GLX_H -#error glx.h included before glxew.h -#endif - -#define __glxext_h_ -#define __GLX_glx_h__ -#define GLX_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ - -#ifndef GLX_VERSION_1_0 -#define GLX_VERSION_1_0 1 - -#define GLX_USE_GL 1 -#define GLX_BUFFER_SIZE 2 -#define GLX_LEVEL 3 -#define GLX_RGBA 4 -#define GLX_DOUBLEBUFFER 5 -#define GLX_STEREO 6 -#define GLX_AUX_BUFFERS 7 -#define GLX_RED_SIZE 8 -#define GLX_GREEN_SIZE 9 -#define GLX_BLUE_SIZE 10 -#define GLX_ALPHA_SIZE 11 -#define GLX_DEPTH_SIZE 12 -#define GLX_STENCIL_SIZE 13 -#define GLX_ACCUM_RED_SIZE 14 -#define GLX_ACCUM_GREEN_SIZE 15 -#define GLX_ACCUM_BLUE_SIZE 16 -#define GLX_ACCUM_ALPHA_SIZE 17 -#define GLX_BAD_SCREEN 1 -#define GLX_BAD_ATTRIBUTE 2 -#define GLX_NO_EXTENSION 3 -#define GLX_BAD_VISUAL 4 -#define GLX_BAD_CONTEXT 5 -#define GLX_BAD_VALUE 6 -#define GLX_BAD_ENUM 7 - -typedef XID GLXDrawable; -typedef XID GLXPixmap; -#ifdef __sun -typedef struct __glXContextRec *GLXContext; -#else -typedef struct __GLXcontextRec *GLXContext; -#endif - -typedef unsigned int GLXVideoDeviceNV; - -extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); -extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); -extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); -extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); -extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); -extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); -extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); -extern void glXDestroyContext (Display *dpy, GLXContext ctx); -extern Bool glXIsDirect (Display *dpy, GLXContext ctx); -extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); -extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); -extern GLXContext glXGetCurrentContext (void); -extern GLXDrawable glXGetCurrentDrawable (void); -extern void glXWaitGL (void); -extern void glXWaitX (void); -extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); -extern void glXUseXFont (Font font, int first, int count, int listBase); - -#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) - -#endif /* GLX_VERSION_1_0 */ - -/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ - -#ifndef GLX_VERSION_1_1 -#define GLX_VERSION_1_1 - -#define GLX_VENDOR 0x1 -#define GLX_VERSION 0x2 -#define GLX_EXTENSIONS 0x3 - -extern const char* glXQueryExtensionsString (Display *dpy, int screen); -extern const char* glXGetClientString (Display *dpy, int name); -extern const char* glXQueryServerString (Display *dpy, int screen, int name); - -#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) - -#endif /* GLX_VERSION_1_1 */ - -/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ - -#ifndef GLX_VERSION_1_2 -#define GLX_VERSION_1_2 1 - -typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); - -#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) - -#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) - -#endif /* GLX_VERSION_1_2 */ - -/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ - -#ifndef GLX_VERSION_1_3 -#define GLX_VERSION_1_3 1 - -#define GLX_RGBA_BIT 0x00000001 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 -#define GLX_DONT_CARE 0xFFFFFFFF - -typedef XID GLXFBConfigID; -typedef XID GLXWindow; -typedef XID GLXPbuffer; -typedef struct __GLXFBConfigRec *GLXFBConfig; - -typedef struct { - int event_type; - int draw_type; - unsigned long serial; - Bool send_event; - Display *display; - GLXDrawable drawable; - unsigned int buffer_mask; - unsigned int aux_buffer; - int x, y; - int width, height; - int count; -} GLXPbufferClobberEvent; -typedef union __GLXEvent { - GLXPbufferClobberEvent glxpbufferclobber; - long pad[24]; -} GLXEvent; - -typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); -typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); -typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); -typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); -typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); -typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); -typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); -typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); -typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); -typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); -typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); -typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); -typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); -typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); - -#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) -#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) -#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) -#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) -#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) -#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) -#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) -#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) -#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) -#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) -#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) -#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) -#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) -#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) -#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) -#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) -#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) - -#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) - -#endif /* GLX_VERSION_1_3 */ - -/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ - -#ifndef GLX_VERSION_1_4 -#define GLX_VERSION_1_4 1 - -#define GLX_SAMPLE_BUFFERS 100000 -#define GLX_SAMPLES 100001 - -extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); - -#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) - -#endif /* GLX_VERSION_1_4 */ - -/* -------------------------- GLX_3DFX_multisample ------------------------- */ - -#ifndef GLX_3DFX_multisample -#define GLX_3DFX_multisample 1 - -#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 -#define GLX_SAMPLES_3DFX 0x8051 - -#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) - -#endif /* GLX_3DFX_multisample */ - -/* ------------------------- GLX_ARB_create_context ------------------------ */ - -#ifndef GLX_ARB_create_context -#define GLX_ARB_create_context 1 - -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 -#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define GLX_CONTEXT_FLAGS_ARB 0x2094 - -typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); - -#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) - -#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) - -#endif /* GLX_ARB_create_context */ - -/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ - -#ifndef GLX_ARB_fbconfig_float -#define GLX_ARB_fbconfig_float 1 - -#define GLX_RGBA_FLOAT_BIT 0x00000004 -#define GLX_RGBA_FLOAT_TYPE 0x20B9 - -#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) - -#endif /* GLX_ARB_fbconfig_float */ - -/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ - -#ifndef GLX_ARB_framebuffer_sRGB -#define GLX_ARB_framebuffer_sRGB 1 - -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 - -#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) - -#endif /* GLX_ARB_framebuffer_sRGB */ - -/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ - -#ifndef GLX_ARB_get_proc_address -#define GLX_ARB_get_proc_address 1 - -extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); - -#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) - -#endif /* GLX_ARB_get_proc_address */ - -/* -------------------------- GLX_ARB_multisample -------------------------- */ - -#ifndef GLX_ARB_multisample -#define GLX_ARB_multisample 1 - -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 - -#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) - -#endif /* GLX_ARB_multisample */ - -/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ - -#ifndef GLX_ATI_pixel_format_float -#define GLX_ATI_pixel_format_float 1 - -#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 - -#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) - -#endif /* GLX_ATI_pixel_format_float */ - -/* ------------------------- GLX_ATI_render_texture ------------------------ */ - -#ifndef GLX_ATI_render_texture -#define GLX_ATI_render_texture 1 - -#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 -#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 -#define GLX_TEXTURE_FORMAT_ATI 0x9802 -#define GLX_TEXTURE_TARGET_ATI 0x9803 -#define GLX_MIPMAP_TEXTURE_ATI 0x9804 -#define GLX_TEXTURE_RGB_ATI 0x9805 -#define GLX_TEXTURE_RGBA_ATI 0x9806 -#define GLX_NO_TEXTURE_ATI 0x9807 -#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 -#define GLX_TEXTURE_1D_ATI 0x9809 -#define GLX_TEXTURE_2D_ATI 0x980A -#define GLX_MIPMAP_LEVEL_ATI 0x980B -#define GLX_CUBE_MAP_FACE_ATI 0x980C -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 -#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 -#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 -#define GLX_FRONT_LEFT_ATI 0x9813 -#define GLX_FRONT_RIGHT_ATI 0x9814 -#define GLX_BACK_LEFT_ATI 0x9815 -#define GLX_BACK_RIGHT_ATI 0x9816 -#define GLX_AUX0_ATI 0x9817 -#define GLX_AUX1_ATI 0x9818 -#define GLX_AUX2_ATI 0x9819 -#define GLX_AUX3_ATI 0x981A -#define GLX_AUX4_ATI 0x981B -#define GLX_AUX5_ATI 0x981C -#define GLX_AUX6_ATI 0x981D -#define GLX_AUX7_ATI 0x981E -#define GLX_AUX8_ATI 0x981F -#define GLX_AUX9_ATI 0x9820 -#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 -#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 - -typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); -typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); -typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); - -#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) -#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) -#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) - -#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) - -#endif /* GLX_ATI_render_texture */ - -/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_EXT_fbconfig_packed_float 1 - -#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 -#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 - -#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) - -#endif /* GLX_EXT_fbconfig_packed_float */ - -/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_EXT_framebuffer_sRGB 1 - -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 - -#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) - -#endif /* GLX_EXT_framebuffer_sRGB */ - -/* ------------------------- GLX_EXT_import_context ------------------------ */ - -#ifndef GLX_EXT_import_context -#define GLX_EXT_import_context 1 - -#define GLX_SHARE_CONTEXT_EXT 0x800A -#define GLX_VISUAL_ID_EXT 0x800B -#define GLX_SCREEN_EXT 0x800C - -typedef XID GLXContextID; - -typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); -typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); -typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); -typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); - -#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) -#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) -#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) -#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) - -#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) - -#endif /* GLX_EXT_import_context */ - -/* -------------------------- GLX_EXT_scene_marker ------------------------- */ - -#ifndef GLX_EXT_scene_marker -#define GLX_EXT_scene_marker 1 - -#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) - -#endif /* GLX_EXT_scene_marker */ - -/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_EXT_texture_from_pixmap 1 - -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB - -typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list); -typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer); - -#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) -#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) - -#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) - -#endif /* GLX_EXT_texture_from_pixmap */ - -/* -------------------------- GLX_EXT_visual_info -------------------------- */ - -#ifndef GLX_EXT_visual_info -#define GLX_EXT_visual_info 1 - -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_TRANSPARENT_TYPE_EXT 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 -#define GLX_NONE_EXT 0x8000 -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 - -#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) - -#endif /* GLX_EXT_visual_info */ - -/* ------------------------- GLX_EXT_visual_rating ------------------------- */ - -#ifndef GLX_EXT_visual_rating -#define GLX_EXT_visual_rating 1 - -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D - -#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) - -#endif /* GLX_EXT_visual_rating */ - -/* -------------------------- GLX_MESA_agp_offset -------------------------- */ - -#ifndef GLX_MESA_agp_offset -#define GLX_MESA_agp_offset 1 - -typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); - -#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) - -#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) - -#endif /* GLX_MESA_agp_offset */ - -/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ - -#ifndef GLX_MESA_copy_sub_buffer -#define GLX_MESA_copy_sub_buffer 1 - -typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); - -#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) - -#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) - -#endif /* GLX_MESA_copy_sub_buffer */ - -/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ - -#ifndef GLX_MESA_pixmap_colormap -#define GLX_MESA_pixmap_colormap 1 - -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); - -#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) - -#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) - -#endif /* GLX_MESA_pixmap_colormap */ - -/* ------------------------ GLX_MESA_release_buffers ----------------------- */ - -#ifndef GLX_MESA_release_buffers -#define GLX_MESA_release_buffers 1 - -typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); - -#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) - -#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) - -#endif /* GLX_MESA_release_buffers */ - -/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_MESA_set_3dfx_mode 1 - -#define GLX_3DFX_WINDOW_MODE_MESA 0x1 -#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 - -typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); - -#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) - -#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) - -#endif /* GLX_MESA_set_3dfx_mode */ - -/* -------------------------- GLX_NV_float_buffer -------------------------- */ - -#ifndef GLX_NV_float_buffer -#define GLX_NV_float_buffer 1 - -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 - -#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) - -#endif /* GLX_NV_float_buffer */ - -/* -------------------------- GLX_NV_present_video ------------------------- */ - -#ifndef GLX_NV_present_video -#define GLX_NV_present_video 1 - -#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 - -typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); -typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); - -#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) -#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) - -#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) - -#endif /* GLX_NV_present_video */ - -/* --------------------------- GLX_NV_swap_group --------------------------- */ - -#ifndef GLX_NV_swap_group -#define GLX_NV_swap_group 1 - -typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); -typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); -typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count); -typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); -typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); -typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); - -#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) -#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) -#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) -#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) -#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) -#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) - -#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) - -#endif /* GLX_NV_swap_group */ - -/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ - -#ifndef GLX_NV_vertex_array_range -#define GLX_NV_vertex_array_range 1 - -typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); -typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); - -#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) -#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) - -#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) - -#endif /* GLX_NV_vertex_array_range */ - -/* -------------------------- GLX_NV_video_output -------------------------- */ - -#ifndef GLX_NV_video_output -#define GLX_NV_video_output 1 - -#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 -#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 -#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 -#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 -#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 -#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA -#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB -#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC - -typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); -typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); -typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); -typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); -typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); - -#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) -#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) -#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) -#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) -#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) -#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) - -#define GLXEW_NV_video_output GLXEW_GET_VAR(__GLXEW_NV_video_output) - -#endif /* GLX_NV_video_output */ - -/* -------------------------- GLX_OML_swap_method -------------------------- */ - -#ifndef GLX_OML_swap_method -#define GLX_OML_swap_method 1 - -#define GLX_SWAP_METHOD_OML 0x8060 -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 - -#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) - -#endif /* GLX_OML_swap_method */ - -/* -------------------------- GLX_OML_sync_control ------------------------- */ - -#if !defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#include -#define GLX_OML_sync_control 1 - -typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); -typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); -typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); -typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); - -#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) -#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) -#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) -#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) -#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) - -#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) - -#endif /* GLX_OML_sync_control */ - -/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ - -#ifndef GLX_SGIS_blended_overlay -#define GLX_SGIS_blended_overlay 1 - -#define GLX_BLENDED_RGBA_SGIS 0x8025 - -#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) - -#endif /* GLX_SGIS_blended_overlay */ - -/* -------------------------- GLX_SGIS_color_range ------------------------- */ - -#ifndef GLX_SGIS_color_range -#define GLX_SGIS_color_range 1 - -#define GLX_MIN_RED_SGIS 0 -#define GLX_MAX_GREEN_SGIS 0 -#define GLX_MIN_BLUE_SGIS 0 -#define GLX_MAX_ALPHA_SGIS 0 -#define GLX_MIN_GREEN_SGIS 0 -#define GLX_MIN_ALPHA_SGIS 0 -#define GLX_MAX_RED_SGIS 0 -#define GLX_EXTENDED_RANGE_SGIS 0 -#define GLX_MAX_BLUE_SGIS 0 - -#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) - -#endif /* GLX_SGIS_color_range */ - -/* -------------------------- GLX_SGIS_multisample ------------------------- */ - -#ifndef GLX_SGIS_multisample -#define GLX_SGIS_multisample 1 - -#define GLX_SAMPLE_BUFFERS_SGIS 100000 -#define GLX_SAMPLES_SGIS 100001 - -#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) - -#endif /* GLX_SGIS_multisample */ - -/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ - -#ifndef GLX_SGIS_shared_multisample -#define GLX_SGIS_shared_multisample 1 - -#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 -#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 - -#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) - -#endif /* GLX_SGIS_shared_multisample */ - -/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ - -#ifndef GLX_SGIX_fbconfig -#define GLX_SGIX_fbconfig 1 - -#define GLX_WINDOW_BIT_SGIX 0x00000001 -#define GLX_RGBA_BIT_SGIX 0x00000001 -#define GLX_PIXMAP_BIT_SGIX 0x00000002 -#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 -#define GLX_SCREEN_EXT 0x800C -#define GLX_DRAWABLE_TYPE_SGIX 0x8010 -#define GLX_RENDER_TYPE_SGIX 0x8011 -#define GLX_X_RENDERABLE_SGIX 0x8012 -#define GLX_FBCONFIG_ID_SGIX 0x8013 -#define GLX_RGBA_TYPE_SGIX 0x8014 -#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 - -typedef XID GLXFBConfigIDSGIX; -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; - -typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); -typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); -typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); -typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); -typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); - -#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) -#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) -#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) -#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) -#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) -#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) - -#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) - -#endif /* GLX_SGIX_fbconfig */ - -/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ - -#ifndef GLX_SGIX_hyperpipe -#define GLX_SGIX_hyperpipe 1 - -#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 -#define GLX_PIPE_RECT_SGIX 0x00000001 -#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 -#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 -#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 -#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 -#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 -#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 -#define GLX_BAD_HYPERPIPE_SGIX 92 -#define GLX_HYPERPIPE_ID_SGIX 0x8030 - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int networkId; -} GLXHyperpipeNetworkSGIX; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int XOrigin; - int YOrigin; - int maxHeight; - int maxWidth; -} GLXPipeRectLimits; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int channel; - unsigned int participationType; - int timeSlice; -} GLXHyperpipeConfigSGIX; -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int srcXOrigin; - int srcYOrigin; - int srcWidth; - int srcHeight; - int destXOrigin; - int destYOrigin; - int destWidth; - int destHeight; -} GLXPipeRect; - -typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); -typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); -typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); -typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); -typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); -typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); - -#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) -#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) -#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) -#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) -#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) -#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) -#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) -#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) - -#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) - -#endif /* GLX_SGIX_hyperpipe */ - -/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ - -#ifndef GLX_SGIX_pbuffer -#define GLX_SGIX_pbuffer 1 - -#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 -#define GLX_PBUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 -#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 -#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 -#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 -#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 -#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 -#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 -#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 -#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 -#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A -#define GLX_PRESERVED_CONTENTS_SGIX 0x801B -#define GLX_LARGEST_PBUFFER_SGIX 0x801C -#define GLX_WIDTH_SGIX 0x801D -#define GLX_HEIGHT_SGIX 0x801E -#define GLX_EVENT_MASK_SGIX 0x801F -#define GLX_DAMAGED_SGIX 0x8020 -#define GLX_SAVED_SGIX 0x8021 -#define GLX_WINDOW_SGIX 0x8022 -#define GLX_PBUFFER_SGIX 0x8023 -#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 - -typedef XID GLXPbufferSGIX; -typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; - -typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); -typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); -typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); -typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); -typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); - -#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) -#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) -#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) -#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) -#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) - -#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) - -#endif /* GLX_SGIX_pbuffer */ - -/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ - -#ifndef GLX_SGIX_swap_barrier -#define GLX_SGIX_swap_barrier 1 - -typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); -typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); - -#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) -#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) - -#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) - -#endif /* GLX_SGIX_swap_barrier */ - -/* -------------------------- GLX_SGIX_swap_group -------------------------- */ - -#ifndef GLX_SGIX_swap_group -#define GLX_SGIX_swap_group 1 - -typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); - -#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) - -#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) - -#endif /* GLX_SGIX_swap_group */ - -/* ------------------------- GLX_SGIX_video_resize ------------------------- */ - -#ifndef GLX_SGIX_video_resize -#define GLX_SGIX_video_resize 1 - -#define GLX_SYNC_FRAME_SGIX 0x00000000 -#define GLX_SYNC_SWAP_SGIX 0x00000001 - -typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); -typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); -typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); -typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); -typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); - -#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) -#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) -#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) -#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) -#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) - -#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) - -#endif /* GLX_SGIX_video_resize */ - -/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ - -#ifndef GLX_SGIX_visual_select_group -#define GLX_SGIX_visual_select_group 1 - -#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 - -#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) - -#endif /* GLX_SGIX_visual_select_group */ - -/* ---------------------------- GLX_SGI_cushion ---------------------------- */ - -#ifndef GLX_SGI_cushion -#define GLX_SGI_cushion 1 - -typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); - -#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) - -#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) - -#endif /* GLX_SGI_cushion */ - -/* ----------------------- GLX_SGI_make_current_read ----------------------- */ - -#ifndef GLX_SGI_make_current_read -#define GLX_SGI_make_current_read 1 - -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); -typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - -#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) -#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) - -#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) - -#endif /* GLX_SGI_make_current_read */ - -/* -------------------------- GLX_SGI_swap_control ------------------------- */ - -#ifndef GLX_SGI_swap_control -#define GLX_SGI_swap_control 1 - -typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); - -#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) - -#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) - -#endif /* GLX_SGI_swap_control */ - -/* --------------------------- GLX_SGI_video_sync -------------------------- */ - -#ifndef GLX_SGI_video_sync -#define GLX_SGI_video_sync 1 - -typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (uint* count); -typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); - -#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) -#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) - -#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) - -#endif /* GLX_SGI_video_sync */ - -/* --------------------- GLX_SUN_get_transparent_index --------------------- */ - -#ifndef GLX_SUN_get_transparent_index -#define GLX_SUN_get_transparent_index 1 - -typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); - -#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) - -#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) - -#endif /* GLX_SUN_get_transparent_index */ - -/* -------------------------- GLX_SUN_video_resize ------------------------- */ - -#ifndef GLX_SUN_video_resize -#define GLX_SUN_video_resize 1 - -#define GLX_VIDEO_RESIZE_SUN 0x8171 -#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD - -typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); -typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); - -#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) -#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) - -#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) - -#endif /* GLX_SUN_video_resize */ - -/* ------------------------------------------------------------------------- */ - -#ifdef GLEW_MX -#define GLXEW_EXPORT -#else -#define GLXEW_EXPORT extern -#endif /* GLEW_MX */ - -extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; - -extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; -extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; -extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; -extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; -extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; -extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; -extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; -extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; -extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; -extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; -extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; -extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; -extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; -extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; -extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; -extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; -extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; - -extern PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; - -extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; -extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; -extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; - -extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; -extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; -extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; -extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; - -extern PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; -extern PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; - -extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; - -extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; - -extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; - -extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; - -extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; - -extern PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; -extern PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; - -extern PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; -extern PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; -extern PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; -extern PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; -extern PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; -extern PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; - -extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; -extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; - -extern PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; -extern PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; -extern PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; -extern PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; -extern PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; -extern PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; - -#ifdef GLX_OML_sync_control -extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; -extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; -extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; -extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; -extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; -#endif - -extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; -extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; -extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; -extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; -extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; -extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; - -extern PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; -extern PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; -extern PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; -extern PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; -extern PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; -extern PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; -extern PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; -extern PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; - -extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; -extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; -extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; -extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; -extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; - -extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; -extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; - -extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; - -extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; -extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; -extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; -extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; -extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; - -extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; - -extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; -extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; - -extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; - -extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; -extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; - -extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; - -extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; -extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; - -#if defined(GLEW_MX) -struct GLXEWContextStruct -{ -#endif /* GLEW_MX */ - -GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; -GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; -GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; -GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; -GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; -GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; -GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context; -GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; -GLXEW_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; -GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; -GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; -GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; -GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; -GLXEW_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; -GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; -GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; -GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; -GLXEW_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; -GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; -GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; -GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; -GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; -GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; -GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; -GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; -GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; -GLXEW_EXPORT GLboolean __GLXEW_NV_present_video; -GLXEW_EXPORT GLboolean __GLXEW_NV_swap_group; -GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; -GLXEW_EXPORT GLboolean __GLXEW_NV_video_output; -GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; -GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; -GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; -GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; -GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; -GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; -GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; -GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; -GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; -GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; -GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; -GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; -GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; - -#ifdef GLEW_MX -}; /* GLXEWContextStruct */ -#endif /* GLEW_MX */ - -/* ------------------------------------------------------------------------ */ - -#ifdef GLEW_MX - -typedef struct GLXEWContextStruct GLXEWContext; -extern GLenum glxewContextInit (GLXEWContext* ctx); -extern GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name); - -#define glxewInit() glxewContextInit(glxewGetContext()) -#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) - -#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x)) -#define GLXEW_GET_FUN(x) x - -#else /* GLEW_MX */ - -#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) -#define GLXEW_GET_FUN(x) x - -extern GLboolean glxewIsSupported (const char* name); - -#endif /* GLEW_MX */ - -extern GLboolean glxewGetExtension (const char* name); - -#ifdef __cplusplus -} -#endif - -#endif /* __glxew_h__ */ diff --git a/WDL/lice/glew/include/GL/wglew.h b/WDL/lice/glew/include/GL/wglew.h deleted file mode 100644 index d9dd3f25..00000000 --- a/WDL/lice/glew/include/GL/wglew.h +++ /dev/null @@ -1,1165 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __wglew_h__ -#define __wglew_h__ -#define __WGLEW_H__ - -#ifdef __wglext_h_ -#error wglext.h included before wglew.h -#endif - -#define __wglext_h_ - -#if !defined(APIENTRY) && !defined(__CYGWIN__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -#include -#endif - -/* - * GLEW_STATIC needs to be set when using the static version. - * GLEW_BUILD is set when building the DLL version. - */ -#ifdef GLEW_STATIC -# define GLEWAPI extern -#else -# ifdef GLEW_BUILD -# define GLEWAPI extern __declspec(dllexport) -# else -# define GLEWAPI extern __declspec(dllimport) -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* -------------------------- WGL_3DFX_multisample ------------------------- */ - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 - -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 - -#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) - -#endif /* WGL_3DFX_multisample */ - -/* ------------------------- WGL_3DL_stereo_control ------------------------ */ - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 - -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 - -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); - -#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) - -#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) - -#endif /* WGL_3DL_stereo_control */ - -/* ------------------------- WGL_ARB_buffer_region ------------------------- */ - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 - -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 - -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); - -#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) -#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) -#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) -#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) - -#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) - -#endif /* WGL_ARB_buffer_region */ - -/* ------------------------- WGL_ARB_create_context ------------------------ */ - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 - -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 - -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); - -#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) - -#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) - -#endif /* WGL_ARB_create_context */ - -/* ----------------------- WGL_ARB_extensions_string ----------------------- */ - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 - -typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); - -#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) - -#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) - -#endif /* WGL_ARB_extensions_string */ - -/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 - -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 - -#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) - -#endif /* WGL_ARB_framebuffer_sRGB */ - -/* ----------------------- WGL_ARB_make_current_read ----------------------- */ - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 - -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 - -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - -#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) -#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) - -#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) - -#endif /* WGL_ARB_make_current_read */ - -/* -------------------------- WGL_ARB_multisample -------------------------- */ - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 - -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 - -#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) - -#endif /* WGL_ARB_multisample */ - -/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 - -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 - -DECLARE_HANDLE(HPBUFFERARB); - -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); - -#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) -#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) -#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) -#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) -#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) - -#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) - -#endif /* WGL_ARB_pbuffer */ - -/* -------------------------- WGL_ARB_pixel_format ------------------------- */ - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 - -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B - -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); - -#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) -#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) -#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) - -#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) - -#endif /* WGL_ARB_pixel_format */ - -/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 - -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 - -#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) - -#endif /* WGL_ARB_pixel_format_float */ - -/* ------------------------- WGL_ARB_render_texture ------------------------ */ - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 - -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 - -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); - -#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) -#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) -#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) - -#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) - -#endif /* WGL_ARB_render_texture */ - -/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 - -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#define GL_RGBA_FLOAT_MODE_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 - -#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) - -#endif /* WGL_ATI_pixel_format_float */ - -/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ - -#ifndef WGL_ATI_render_texture_rectangle -#define WGL_ATI_render_texture_rectangle 1 - -#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 - -#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) - -#endif /* WGL_ATI_render_texture_rectangle */ - -/* -------------------------- WGL_EXT_depth_float -------------------------- */ - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 - -#define WGL_DEPTH_FLOAT_EXT 0x2040 - -#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) - -#endif /* WGL_EXT_depth_float */ - -/* ---------------------- WGL_EXT_display_color_table ---------------------- */ - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 - -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); - -#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) -#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) -#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) -#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) - -#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) - -#endif /* WGL_EXT_display_color_table */ - -/* ----------------------- WGL_EXT_extensions_string ----------------------- */ - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 - -typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); - -#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) - -#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) - -#endif /* WGL_EXT_extensions_string */ - -/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 - -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 - -#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) - -#endif /* WGL_EXT_framebuffer_sRGB */ - -/* ----------------------- WGL_EXT_make_current_read ----------------------- */ - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 - -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 - -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - -#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) -#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) - -#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) - -#endif /* WGL_EXT_make_current_read */ - -/* -------------------------- WGL_EXT_multisample -------------------------- */ - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 - -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 - -#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) - -#endif /* WGL_EXT_multisample */ - -/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 - -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 - -DECLARE_HANDLE(HPBUFFEREXT); - -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); - -#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) -#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) -#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) -#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) -#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) - -#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) - -#endif /* WGL_EXT_pbuffer */ - -/* -------------------------- WGL_EXT_pixel_format ------------------------- */ - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 - -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C - -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); - -#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) -#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) -#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) - -#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) - -#endif /* WGL_EXT_pixel_format */ - -/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 - -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 - -#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) - -#endif /* WGL_EXT_pixel_format_packed_float */ - -/* -------------------------- WGL_EXT_swap_control ------------------------- */ - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 - -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - -#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) -#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) - -#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) - -#endif /* WGL_EXT_swap_control */ - -/* --------------------- WGL_I3D_digital_video_control --------------------- */ - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 - -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 - -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); - -#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) -#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) - -#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) - -#endif /* WGL_I3D_digital_video_control */ - -/* ----------------------------- WGL_I3D_gamma ----------------------------- */ - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 - -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F - -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); - -#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) -#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) -#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) -#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) - -#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) - -#endif /* WGL_I3D_gamma */ - -/* ---------------------------- WGL_I3D_genlock ---------------------------- */ - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 - -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C - -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); - -#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) -#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) -#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) -#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) -#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) -#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) -#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) -#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) -#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) -#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) -#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) -#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) - -#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) - -#endif /* WGL_I3D_genlock */ - -/* -------------------------- WGL_I3D_image_buffer ------------------------- */ - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 - -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 - -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); - -#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) -#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) -#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) -#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) - -#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) - -#endif /* WGL_I3D_image_buffer */ - -/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 - -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); - -#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) -#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) -#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) -#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) - -#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) - -#endif /* WGL_I3D_swap_frame_lock */ - -/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 - -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); - -#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) -#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) -#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) -#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) - -#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) - -#endif /* WGL_I3D_swap_frame_usage */ - -/* -------------------------- WGL_NV_float_buffer -------------------------- */ - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 - -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 - -#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) - -#endif /* WGL_NV_float_buffer */ - -/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 - -#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 - -DECLARE_HANDLE(HGPUNV); -typedef struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -} GPU_DEVICE, *PGPU_DEVICE; - -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); - -#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) -#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) -#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) -#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) -#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) - -#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) - -#endif /* WGL_NV_gpu_affinity */ - -/* -------------------------- WGL_NV_present_video ------------------------- */ - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 - -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 - -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); - -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); - -#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) -#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) -#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) - -#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) - -#endif /* WGL_NV_present_video */ - -/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ - -#ifndef WGL_NV_render_depth_texture -#define WGL_NV_render_depth_texture 1 - -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 - -#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) - -#endif /* WGL_NV_render_depth_texture */ - -/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_NV_render_texture_rectangle 1 - -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 - -#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) - -#endif /* WGL_NV_render_texture_rectangle */ - -/* --------------------------- WGL_NV_swap_group --------------------------- */ - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 - -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); - -#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) -#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) -#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) -#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) -#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) -#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) - -#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) - -#endif /* WGL_NV_swap_group */ - -/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 - -typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); - -#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) -#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) - -#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) - -#endif /* WGL_NV_vertex_array_range */ - -/* -------------------------- WGL_NV_video_output -------------------------- */ - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 - -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC - -DECLARE_HANDLE(HPVIDEODEV); - -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); - -#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) -#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) -#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) -#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) -#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) -#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) - -#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) - -#endif /* WGL_NV_video_output */ - -/* -------------------------- WGL_OML_sync_control ------------------------- */ - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 - -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); - -#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) -#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) -#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) -#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) -#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) -#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) - -#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) - -#endif /* WGL_OML_sync_control */ - -/* ------------------------------------------------------------------------- */ - -#ifdef GLEW_MX -#define WGLEW_EXPORT -#else -#define WGLEW_EXPORT GLEWAPI -#endif /* GLEW_MX */ - -#ifdef GLEW_MX -struct WGLEWContextStruct -{ -#endif /* GLEW_MX */ - -WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; - -WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; -WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; -WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; -WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; - -WGLEW_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; - -WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; - -WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; -WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; - -WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; -WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; -WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; -WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; -WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; - -WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; -WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; -WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; - -WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; -WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; -WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; - -WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; -WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; -WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; -WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; - -WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; - -WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; -WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; - -WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; -WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; -WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; -WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; -WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; - -WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; -WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; -WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; - -WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; -WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; - -WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; -WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; - -WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; -WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; -WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; -WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; - -WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; -WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; -WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; -WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; -WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; -WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; -WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; -WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; -WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; -WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; -WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; -WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; - -WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; -WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; -WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; -WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; - -WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; -WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; -WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; -WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; - -WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; -WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; -WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; -WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; - -WGLEW_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; -WGLEW_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; -WGLEW_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; -WGLEW_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; -WGLEW_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; - -WGLEW_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; -WGLEW_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; -WGLEW_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; - -WGLEW_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; -WGLEW_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; -WGLEW_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; -WGLEW_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; -WGLEW_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; -WGLEW_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; - -WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; -WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; - -WGLEW_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; -WGLEW_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; -WGLEW_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; -WGLEW_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; -WGLEW_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; -WGLEW_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; - -WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; -WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; -WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; -WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; -WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; -WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; -WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; -WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; -WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; -WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context; -WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; -WGLEW_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; -WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; -WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; -WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; -WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; -WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; -WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; -WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; -WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; -WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; -WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; -WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; -WGLEW_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; -WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; -WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; -WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; -WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; -WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; -WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; -WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; -WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; -WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; -WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; -WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; -WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; -WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; -WGLEW_EXPORT GLboolean __WGLEW_NV_gpu_affinity; -WGLEW_EXPORT GLboolean __WGLEW_NV_present_video; -WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; -WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; -WGLEW_EXPORT GLboolean __WGLEW_NV_swap_group; -WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; -WGLEW_EXPORT GLboolean __WGLEW_NV_video_output; -WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; - -#ifdef GLEW_MX -}; /* WGLEWContextStruct */ -#endif /* GLEW_MX */ - -/* ------------------------------------------------------------------------- */ - -#ifdef GLEW_MX - -typedef struct WGLEWContextStruct WGLEWContext; -GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); -GLEWAPI GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name); - -#define wglewInit() wglewContextInit(wglewGetContext()) -#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) - -#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x)) -#define WGLEW_GET_FUN(x) wglewGetContext()->x - -#else /* GLEW_MX */ - -#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) -#define WGLEW_GET_FUN(x) x - -GLEWAPI GLboolean wglewIsSupported (const char* name); - -#endif /* GLEW_MX */ - -GLEWAPI GLboolean wglewGetExtension (const char* name); - -#ifdef __cplusplus -} -#endif - -#undef GLEWAPI - -#endif /* __wglew_h__ */ diff --git a/WDL/lice/glew/src/glew.c b/WDL/lice/glew/src/glew.c deleted file mode 100644 index 8767b580..00000000 --- a/WDL/lice/glew/src/glew.c +++ /dev/null @@ -1,12180 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "../include/GL/glew.h" -#if defined(_WIN32) -# include "../include/GL/wglew.h" -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -# include "../include/GL/glxew.h" -#endif - -/* - * Define glewGetContext and related helper macros. - */ -#ifdef GLEW_MX -# define glewGetContext() ctx -# ifdef _WIN32 -# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx -# define GLEW_CONTEXT_ARG_VAR_INIT ctx -# define wglewGetContext() ctx -# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx -# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx -# else /* _WIN32 */ -# define GLEW_CONTEXT_ARG_DEF_INIT void -# define GLEW_CONTEXT_ARG_VAR_INIT -# define glxewGetContext() ctx -# define GLXEW_CONTEXT_ARG_DEF_INIT void -# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx -# endif /* _WIN32 */ -# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx -#else /* GLEW_MX */ -# define GLEW_CONTEXT_ARG_DEF_INIT void -# define GLEW_CONTEXT_ARG_VAR_INIT -# define GLEW_CONTEXT_ARG_DEF_LIST void -# define WGLEW_CONTEXT_ARG_DEF_INIT void -# define WGLEW_CONTEXT_ARG_DEF_LIST void -# define GLXEW_CONTEXT_ARG_DEF_INIT void -# define GLXEW_CONTEXT_ARG_DEF_LIST void -#endif /* GLEW_MX */ - -#if defined(__APPLE__) -#include -#include -#include - -void* NSGLGetProcAddress (const GLubyte *name) -{ - static const struct mach_header* image = NULL; - NSSymbol symbol; - char* symbolName; - if (NULL == image) - { - image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); - } - /* prepend a '_' for the Unix C symbol mangling convention */ - symbolName = malloc(strlen((const char*)name) + 2); - strcpy(symbolName+1, (const char*)name); - symbolName[0] = '_'; - symbol = NULL; - /* if (NSIsSymbolNameDefined(symbolName)) - symbol = NSLookupAndBindSymbol(symbolName); */ - symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; - free(symbolName); - return symbol ? NSAddressOfSymbol(symbol) : NULL; -} -#endif /* __APPLE__ */ - -#if defined(__sgi) || defined (__sun) -#include -#include -#include - -void* dlGetProcAddress (const GLubyte* name) -{ - static void* h = NULL; - static void* gpa; - - if (h == NULL) - { - if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL; - gpa = dlsym(h, "glXGetProcAddress"); - } - - if (gpa != NULL) - return ((void*(*)(const GLubyte*))gpa)(name); - else - return dlsym(h, (const char*)name); -} -#endif /* __sgi || __sun */ - -/* - * Define glewGetProcAddress. - */ -#if defined(_WIN32) -# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) -#else -# if defined(__APPLE__) -# define glewGetProcAddress(name) NSGLGetProcAddress(name) -# else -# if defined(__sgi) || defined(__sun) -# define glewGetProcAddress(name) dlGetProcAddress(name) -# else /* __linux */ -# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) -# endif -# endif -#endif - -/* - * Define GLboolean const cast. - */ -#define CONST_CAST(x) (*(GLboolean*)&x) - -/* - * GLEW, just like OpenGL or GLU, does not rely on the standard C library. - * These functions implement the functionality required in this file. - */ -static GLuint _glewStrLen (const GLubyte* s) -{ - GLuint i=0; - if (s == NULL) return 0; - while (s[i] != '\0') i++; - return i; -} - -static GLuint _glewStrCLen (const GLubyte* s, GLubyte c) -{ - GLuint i=0; - if (s == NULL) return 0; - while (s[i] != '\0' && s[i] != c) i++; - return (s[i] == '\0' || s[i] == c) ? i : 0; -} - -static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) -{ - GLuint i=0; - if(a == NULL || b == NULL) - return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; - while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; - return i == n ? GL_TRUE : GL_FALSE; -} - -static GLboolean _glewStrSame1 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) -{ - while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t')) - { - (*a)++; - (*na)--; - } - if(*na >= nb) - { - GLuint i=0; - while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; - if(i == nb) - { - *a = *a + nb; - *na = *na - nb; - return GL_TRUE; - } - } - return GL_FALSE; -} - -static GLboolean _glewStrSame2 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) -{ - if(*na >= nb) - { - GLuint i=0; - while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; - if(i == nb) - { - *a = *a + nb; - *na = *na - nb; - return GL_TRUE; - } - } - return GL_FALSE; -} - -static GLboolean _glewStrSame3 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) -{ - if(*na >= nb) - { - GLuint i=0; - while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; - if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t')) - { - *a = *a + nb; - *na = *na - nb; - return GL_TRUE; - } - } - return GL_FALSE; -} - -#if !defined(_WIN32) || !defined(GLEW_MX) - -PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL; -PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL; -PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL; -PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL; - -PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL; -PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL; -PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL; -PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL; -PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL; -PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL; -PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL; -PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL; -PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL; -PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL; -PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL; -PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL; -PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL; -PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL; -PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL; -PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL; -PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL; -PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL; -PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL; -PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL; -PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL; -PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL; -PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL; -PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL; -PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL; -PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL; -PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL; -PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL; -PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL; -PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL; -PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL; -PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL; -PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL; -PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL; -PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL; -PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL; -PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL; -PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL; -PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL; - -PFNGLBLENDCOLORPROC __glewBlendColor = NULL; -PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL; -PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL; -PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL; -PFNGLFOGCOORDDPROC __glewFogCoordd = NULL; -PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL; -PFNGLFOGCOORDFPROC __glewFogCoordf = NULL; -PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL; -PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL; -PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL; -PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL; -PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL; -PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL; -PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL; -PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL; -PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL; -PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL; -PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL; -PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL; -PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL; -PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL; -PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL; -PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL; -PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL; -PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL; -PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL; -PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL; -PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL; -PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL; -PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL; -PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL; -PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL; -PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL; -PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL; -PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL; -PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL; -PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL; -PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL; -PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL; -PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL; -PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL; -PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL; -PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL; - -PFNGLBEGINQUERYPROC __glewBeginQuery = NULL; -PFNGLBINDBUFFERPROC __glewBindBuffer = NULL; -PFNGLBUFFERDATAPROC __glewBufferData = NULL; -PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL; -PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL; -PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL; -PFNGLENDQUERYPROC __glewEndQuery = NULL; -PFNGLGENBUFFERSPROC __glewGenBuffers = NULL; -PFNGLGENQUERIESPROC __glewGenQueries = NULL; -PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL; -PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL; -PFNGLISBUFFERPROC __glewIsBuffer = NULL; -PFNGLISQUERYPROC __glewIsQuery = NULL; -PFNGLMAPBUFFERPROC __glewMapBuffer = NULL; -PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL; - -PFNGLATTACHSHADERPROC __glewAttachShader = NULL; -PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL; -PFNGLCOMPILESHADERPROC __glewCompileShader = NULL; -PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL; -PFNGLCREATESHADERPROC __glewCreateShader = NULL; -PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL; -PFNGLDELETESHADERPROC __glewDeleteShader = NULL; -PFNGLDETACHSHADERPROC __glewDetachShader = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL; -PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL; -PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL; -PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL; -PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL; -PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL; -PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL; -PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL; -PFNGLISPROGRAMPROC __glewIsProgram = NULL; -PFNGLISSHADERPROC __glewIsShader = NULL; -PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL; -PFNGLSHADERSOURCEPROC __glewShaderSource = NULL; -PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL; -PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL; -PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL; -PFNGLUNIFORM1FPROC __glewUniform1f = NULL; -PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL; -PFNGLUNIFORM1IPROC __glewUniform1i = NULL; -PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL; -PFNGLUNIFORM2FPROC __glewUniform2f = NULL; -PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL; -PFNGLUNIFORM2IPROC __glewUniform2i = NULL; -PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL; -PFNGLUNIFORM3FPROC __glewUniform3f = NULL; -PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL; -PFNGLUNIFORM3IPROC __glewUniform3i = NULL; -PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL; -PFNGLUNIFORM4FPROC __glewUniform4f = NULL; -PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL; -PFNGLUNIFORM4IPROC __glewUniform4i = NULL; -PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL; -PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL; -PFNGLUSEPROGRAMPROC __glewUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL; -PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL; - -PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL; - -PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL; -PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL; -PFNGLCLAMPCOLORPROC __glewClampColor = NULL; -PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL; -PFNGLCOLORMASKIPROC __glewColorMaski = NULL; -PFNGLDISABLEIPROC __glewDisablei = NULL; -PFNGLENABLEIPROC __glewEnablei = NULL; -PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL; -PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL; -PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL; -PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL; -PFNGLGETSTRINGIPROC __glewGetStringi = NULL; -PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL; -PFNGLISENABLEDIPROC __glewIsEnabledi = NULL; -PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL; -PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL; -PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL; -PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL; -PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL; -PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL; - -PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; - -PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL; -PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL; -PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL; -PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL; -PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL; - -PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL; -PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL; -PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL; -PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL; -PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL; -PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL; -PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL; -PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL; - -PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL; - -PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL; -PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL; - -PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL; -PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL; -PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL; -PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL; - -PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL; -PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL; -PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL; - -PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; - -PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; - -PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL; -PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL; - -PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL; -PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; -PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; -PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; -PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL; -PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL; -PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL; -PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL; -PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL; -PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL; - -PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL; -PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL; -PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL; - -PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL; -PFNGLCOLORTABLEPROC __glewColorTable = NULL; -PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL; -PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL; -PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL; -PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL; -PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL; -PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL; -PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL; -PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL; -PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL; -PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL; -PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL; -PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL; -PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL; -PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL; -PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL; -PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL; -PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL; -PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL; -PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL; -PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL; -PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL; -PFNGLGETMINMAXPROC __glewGetMinmax = NULL; -PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL; -PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL; -PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL; -PFNGLHISTOGRAMPROC __glewHistogram = NULL; -PFNGLMINMAXPROC __glewMinmax = NULL; -PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL; -PFNGLRESETMINMAXPROC __glewResetMinmax = NULL; -PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL; - -PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL; - -PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL; -PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL; - -PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; -PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; -PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; -PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; -PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; - -PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL; - -PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL; -PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL; -PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL; -PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL; -PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL; -PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL; -PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL; -PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL; -PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL; -PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL; -PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL; -PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL; -PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL; -PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL; -PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL; -PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL; -PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL; -PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL; -PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL; -PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL; -PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL; -PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL; -PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL; -PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL; -PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL; -PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL; -PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL; -PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL; -PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL; -PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL; -PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL; -PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL; -PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL; -PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL; - -PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL; -PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL; -PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL; -PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL; -PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL; -PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL; -PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL; -PFNGLISQUERYARBPROC __glewIsQueryARB = NULL; - -PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL; -PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL; - -PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL; -PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL; -PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL; -PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL; -PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL; -PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL; -PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL; -PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL; -PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL; -PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL; -PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL; -PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL; -PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL; -PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL; -PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL; -PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL; -PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL; -PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL; -PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL; -PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL; -PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL; -PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL; -PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL; -PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL; -PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL; -PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL; -PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL; -PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL; -PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL; -PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL; -PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL; -PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL; -PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL; -PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL; -PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL; -PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL; -PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL; -PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL; -PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL; - -PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL; - -PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; - -PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; -PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; -PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; -PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; - -PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL; -PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL; -PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL; -PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL; - -PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL; -PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL; -PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL; -PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL; -PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL; -PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL; -PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL; -PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL; -PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL; -PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL; - -PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL; -PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL; -PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL; -PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL; -PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL; -PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL; -PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL; -PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL; -PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL; -PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL; -PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL; - -PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL; -PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL; -PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL; -PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL; -PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL; -PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL; -PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL; -PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL; -PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL; -PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL; -PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL; -PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL; -PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL; -PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL; -PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL; -PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL; -PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL; -PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL; -PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL; -PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL; -PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL; -PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL; -PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL; -PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL; -PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL; -PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL; -PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL; -PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL; -PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL; -PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL; -PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL; -PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL; -PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL; -PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL; -PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL; -PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL; -PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL; -PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL; -PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL; -PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL; -PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL; -PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL; -PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL; -PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL; -PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL; -PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL; -PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL; -PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL; -PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL; -PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL; -PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL; -PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL; -PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL; -PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL; -PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL; -PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL; -PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL; -PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL; -PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL; -PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL; -PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL; - -PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL; -PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL; -PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL; - -PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL; -PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL; -PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL; -PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL; -PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL; -PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL; -PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL; -PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL; -PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL; -PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL; -PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL; -PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL; -PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL; -PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL; -PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL; -PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL; - -PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL; - -PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL; -PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL; -PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL; - -PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL; -PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL; -PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL; -PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL; - -PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL; -PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL; -PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL; -PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL; -PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL; -PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL; -PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL; -PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL; -PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL; -PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL; -PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL; -PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL; -PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL; -PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL; - -PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL; -PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL; - -PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI = NULL; -PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI = NULL; - -PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL; -PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL; - -PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL; -PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL; -PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL; -PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL; -PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL; -PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL; -PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL; -PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL; -PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL; -PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL; -PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL; -PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL; - -PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL; -PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL; -PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL; - -PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL; -PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL; -PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL; -PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL; -PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL; -PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL; -PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL; -PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL; -PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL; -PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL; -PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL; -PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL; -PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL; -PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL; -PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL; -PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL; -PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL; -PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL; -PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL; -PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL; -PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL; -PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL; -PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL; -PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL; -PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL; -PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL; -PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL; -PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL; -PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL; -PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL; -PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL; -PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL; -PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL; -PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL; -PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL; -PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL; -PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL; - -PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL; -PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL; -PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL; - -PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL; - -PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL; - -PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL; - -PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL; - -PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL; -PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL; - -PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL; -PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL; - -PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL; -PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL; -PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL; -PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL; -PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL; -PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL; -PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL; -PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL; -PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL; -PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL; -PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL; -PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL; -PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL; - -PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL; -PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL; - -PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL; -PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL; -PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL; -PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL; -PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL; - -PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL; -PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL; - -PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL; - -PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL; -PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL; -PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL; -PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL; -PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL; -PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL; -PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL; -PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL; -PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL; -PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL; -PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL; -PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL; -PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL; -PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL; -PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL; -PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL; -PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL; -PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL; -PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL; -PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL; -PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL; -PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL; -PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL; -PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL; -PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL; -PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL; -PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL; -PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL; -PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL; -PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL; -PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL; -PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL; -PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL; -PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL; -PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL; -PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL; -PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL; -PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL; -PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL; -PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL; -PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL; -PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL; -PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL; -PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL; -PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL; -PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL; -PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL; -PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL; -PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL; -PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL; -PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL; -PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL; -PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL; -PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL; -PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL; -PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL; -PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL; -PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL; -PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL; -PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL; -PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL; -PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL; -PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL; -PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL; -PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL; -PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL; -PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL; -PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL; -PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL; -PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL; -PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL; -PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL; -PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL; -PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL; -PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL; -PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL; -PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL; -PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL; -PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL; -PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL; -PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL; -PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL; -PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL; -PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL; -PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL; -PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL; -PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL; -PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL; -PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL; -PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL; -PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL; -PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL; -PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL; -PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL; -PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL; -PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL; -PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL; -PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL; -PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL; -PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL; -PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL; -PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL; -PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL; -PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL; -PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL; -PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL; -PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL; -PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL; -PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL; -PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL; -PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL; -PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL; -PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL; -PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL; -PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL; -PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL; -PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL; -PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL; -PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL; -PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL; -PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL; -PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL; -PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL; -PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL; -PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL; -PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL; -PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL; -PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL; -PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL; -PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL; -PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL; -PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL; -PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL; -PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL; -PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL; -PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL; -PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL; -PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL; -PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL; -PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL; -PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL; -PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL; -PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL; -PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL; -PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL; -PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL; -PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL; -PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL; -PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL; - -PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL; -PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL; -PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL; -PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL; -PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL; -PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL; - -PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL; -PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL; - -PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL; - -PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL; -PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL; -PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL; -PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL; -PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL; - -PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL; -PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL; -PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL; -PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL; -PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL; -PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL; -PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL; -PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL; -PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL; -PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL; -PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL; -PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL; -PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL; -PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL; -PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL; -PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL; -PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL; -PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL; - -PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL; - -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL; - -PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL; -PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL; -PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL; -PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL; -PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL; -PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL; -PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL; -PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL; -PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL; -PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL; - -PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL; -PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL; -PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL; -PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL; - -PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL; -PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL; - -PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL; -PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL; -PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL; -PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL; -PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL; -PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL; -PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL; -PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL; -PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL; -PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL; -PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL; -PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL; -PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL; -PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL; -PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL; -PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL; -PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL; -PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL; -PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL; -PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL; -PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL; -PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL; -PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL; -PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL; -PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL; -PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL; -PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL; -PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL; -PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL; -PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL; -PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL; -PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL; -PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL; -PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL; - -PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL; -PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL; -PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL; -PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL; -PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL; -PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL; -PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL; -PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL; -PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL; -PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL; - -PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL; - -PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL; - -PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL; -PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL; -PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL; - -PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL; -PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL; - -PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL; -PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL; - -PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL; -PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL; -PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL; -PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL; - -PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL; -PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL; -PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL; -PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL; -PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL; -PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL; - -PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL; -PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL; - -PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL; - -PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL; -PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL; - -PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL; -PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL; -PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL; -PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL; -PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL; -PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL; -PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL; -PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL; -PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL; -PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL; -PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL; -PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL; -PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL; -PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL; -PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL; -PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL; -PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL; - -PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; - -PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; -PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; -PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; - -PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; - -PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL; - -PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL; -PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL; -PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL; -PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL; -PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL; -PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL; - -PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL; -PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL; -PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL; -PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL; -PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL; -PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL; - -PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL; - -PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL; -PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL; - -PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL; -PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL; -PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL; -PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL; -PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL; - -PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL; -PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL; -PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL; -PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL; -PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT = NULL; -PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; -PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; -PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; -PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; - -PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL; -PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL; -PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL; -PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL; -PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL; -PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL; -PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL; -PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL; -PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL; -PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL; -PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL; -PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL; -PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL; -PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL; -PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL; -PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL; -PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL; -PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL; -PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL; -PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL; -PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL; -PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL; -PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL; -PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL; -PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL; -PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL; -PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL; -PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL; -PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL; -PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL; -PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL; -PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL; -PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL; -PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL; -PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL; -PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL; -PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL; -PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL; -PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL; -PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL; -PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL; -PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL; - -PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL; -PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL; -PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL; - -PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL; - -PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL; - -PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL; -PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL; -PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL; -PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL; -PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL; -PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL; - -PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL; -PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL; - -PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL; -PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL; -PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL; -PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL; -PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL; -PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL; -PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL; -PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL; - -PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; -PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; -PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; -PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; - -PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; -PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; - -PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT = NULL; -PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT = NULL; -PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT = NULL; -PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT = NULL; -PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT = NULL; - -PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL; - -PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL; -PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL; -PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL; -PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL; -PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL; -PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL; -PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL; -PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL; -PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL; -PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL; -PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL; -PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL; -PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL; -PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL; -PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL; -PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL; -PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL; -PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL; -PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL; -PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL; -PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL; -PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL; -PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL; -PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL; - -PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL; -PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL; - -PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL; -PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL; -PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL; - -PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL; -PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL; -PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL; -PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL; -PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL; -PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL; -PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL; -PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL; -PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL; - -PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL; -PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL; -PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL; - -PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL; -PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL; -PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL; -PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL; -PFNGLISFENCENVPROC __glewIsFenceNV = NULL; -PFNGLSETFENCENVPROC __glewSetFenceNV = NULL; -PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL; - -PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL; -PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL; -PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL; -PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL; -PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL; -PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL; - -PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL; - -PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL; - -PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL; -PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL; -PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL; -PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL; -PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL; -PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL; -PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL; -PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL; -PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL; -PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL; -PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL; -PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL; - -PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL; -PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL; -PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL; -PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL; -PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL; -PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL; -PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL; -PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL; -PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL; -PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL; -PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL; -PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL; -PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL; -PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL; -PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL; -PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL; -PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL; -PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL; -PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL; -PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL; -PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL; -PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL; -PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL; -PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL; -PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL; -PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL; -PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL; -PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL; -PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL; -PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL; -PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL; -PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL; -PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL; -PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL; -PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL; -PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL; -PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL; -PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL; -PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL; -PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL; -PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL; -PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL; -PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL; -PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL; -PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL; -PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL; - -PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL; -PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL; -PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL; -PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL; -PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL; -PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL; -PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL; - -PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL; -PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL; -PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL; - -PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL; -PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL; - -PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL; -PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL; - -PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL; -PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL; -PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL; -PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL; -PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL; -PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL; -PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV = NULL; - -PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL; -PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL; - -PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL; -PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL; -PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL; -PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL; -PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL; -PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL; -PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL; -PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL; -PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL; -PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL; -PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL; -PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL; -PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL; - -PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL; -PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL; - -PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL; -PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL; -PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL; -PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL; -PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL; -PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL; -PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL; -PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL; -PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL; - -PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; -PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; - -PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL; -PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL; -PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL; -PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL; -PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL; -PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL; -PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL; -PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL; -PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL; -PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL; -PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL; -PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL; -PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL; -PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL; -PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL; -PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL; -PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL; -PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL; -PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL; -PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL; -PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL; -PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL; -PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL; -PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL; -PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL; -PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL; -PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL; -PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL; -PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL; -PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL; -PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL; -PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL; -PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL; -PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL; -PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL; -PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL; -PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL; -PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL; -PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL; -PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL; -PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL; -PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL; -PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL; -PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL; -PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL; -PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL; -PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL; -PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL; -PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL; -PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL; -PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL; -PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL; -PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL; -PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL; -PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL; -PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL; -PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL; -PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL; -PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL; -PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL; -PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL; -PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL; -PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL; -PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL; - -PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL; -PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL; -PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL; -PFNGLFRUSTUMFOESPROC __glewFrustumfOES = NULL; -PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES = NULL; -PFNGLORTHOFOESPROC __glewOrthofOES = NULL; - -PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL; -PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL; - -PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL; -PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL; - -PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL; -PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL; - -PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL; -PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL; - -PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL; -PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL; - -PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL; -PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL; - -PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL; -PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL; -PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL; -PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL; -PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL; -PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL; - -PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL; - -PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL; - -PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL; -PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL; -PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL; -PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL; -PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL; -PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL; -PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL; -PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL; -PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL; -PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL; -PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL; -PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL; -PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL; -PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL; -PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL; -PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL; -PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL; - -PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL; - -PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL; - -PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL; - -PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL; -PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL; -PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL; -PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL; - -PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL; - -PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL; -PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL; -PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL; -PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL; -PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL; -PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL; -PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL; - -PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL; - -PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL; -PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL; -PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL; -PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL; -PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL; -PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL; -PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL; -PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL; - -PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL; - -PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL; -PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL; -PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL; -PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL; -PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL; -PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL; -PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL; - -PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL; -PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL; -PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL; -PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL; -PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL; -PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL; -PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL; -PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL; -PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL; -PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; -PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL; -PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL; -PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL; -PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL; -PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL; -PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; -PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL; -PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL; -PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL; -PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL; -PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL; -PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL; -PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL; -PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; -PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL; -PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL; - -PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL; - -#endif /* !WIN32 || !GLEW_MX */ - -#if !defined(GLEW_MX) - -GLboolean __GLEW_VERSION_1_1 = GL_FALSE; -GLboolean __GLEW_VERSION_1_2 = GL_FALSE; -GLboolean __GLEW_VERSION_1_3 = GL_FALSE; -GLboolean __GLEW_VERSION_1_4 = GL_FALSE; -GLboolean __GLEW_VERSION_1_5 = GL_FALSE; -GLboolean __GLEW_VERSION_2_0 = GL_FALSE; -GLboolean __GLEW_VERSION_2_1 = GL_FALSE; -GLboolean __GLEW_VERSION_3_0 = GL_FALSE; -GLboolean __GLEW_3DFX_multisample = GL_FALSE; -GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; -GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; -GLboolean __GLEW_APPLE_client_storage = GL_FALSE; -GLboolean __GLEW_APPLE_element_array = GL_FALSE; -GLboolean __GLEW_APPLE_fence = GL_FALSE; -GLboolean __GLEW_APPLE_float_pixels = GL_FALSE; -GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE; -GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; -GLboolean __GLEW_APPLE_specular_vector = GL_FALSE; -GLboolean __GLEW_APPLE_texture_range = GL_FALSE; -GLboolean __GLEW_APPLE_transform_hint = GL_FALSE; -GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE; -GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE; -GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; -GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; -GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE; -GLboolean __GLEW_ARB_depth_texture = GL_FALSE; -GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; -GLboolean __GLEW_ARB_draw_instanced = GL_FALSE; -GLboolean __GLEW_ARB_fragment_program = GL_FALSE; -GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE; -GLboolean __GLEW_ARB_fragment_shader = GL_FALSE; -GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE; -GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE; -GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE; -GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE; -GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE; -GLboolean __GLEW_ARB_imaging = GL_FALSE; -GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE; -GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE; -GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; -GLboolean __GLEW_ARB_multisample = GL_FALSE; -GLboolean __GLEW_ARB_multitexture = GL_FALSE; -GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; -GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE; -GLboolean __GLEW_ARB_point_parameters = GL_FALSE; -GLboolean __GLEW_ARB_point_sprite = GL_FALSE; -GLboolean __GLEW_ARB_shader_objects = GL_FALSE; -GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; -GLboolean __GLEW_ARB_shadow = GL_FALSE; -GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; -GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; -GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE; -GLboolean __GLEW_ARB_texture_compression = GL_FALSE; -GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE; -GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; -GLboolean __GLEW_ARB_texture_env_add = GL_FALSE; -GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE; -GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE; -GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE; -GLboolean __GLEW_ARB_texture_float = GL_FALSE; -GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; -GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; -GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; -GLboolean __GLEW_ARB_texture_rg = GL_FALSE; -GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; -GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE; -GLboolean __GLEW_ARB_vertex_blend = GL_FALSE; -GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE; -GLboolean __GLEW_ARB_vertex_program = GL_FALSE; -GLboolean __GLEW_ARB_vertex_shader = GL_FALSE; -GLboolean __GLEW_ARB_window_pos = GL_FALSE; -GLboolean __GLEW_ATIX_point_sprites = GL_FALSE; -GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE; -GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE; -GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE; -GLboolean __GLEW_ATI_draw_buffers = GL_FALSE; -GLboolean __GLEW_ATI_element_array = GL_FALSE; -GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE; -GLboolean __GLEW_ATI_fragment_shader = GL_FALSE; -GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE; -GLboolean __GLEW_ATI_pn_triangles = GL_FALSE; -GLboolean __GLEW_ATI_separate_stencil = GL_FALSE; -GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE; -GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE; -GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE; -GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE; -GLboolean __GLEW_ATI_texture_float = GL_FALSE; -GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE; -GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE; -GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE; -GLboolean __GLEW_ATI_vertex_streams = GL_FALSE; -GLboolean __GLEW_EXT_422_pixels = GL_FALSE; -GLboolean __GLEW_EXT_Cg_shader = GL_FALSE; -GLboolean __GLEW_EXT_abgr = GL_FALSE; -GLboolean __GLEW_EXT_bgra = GL_FALSE; -GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE; -GLboolean __GLEW_EXT_blend_color = GL_FALSE; -GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE; -GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE; -GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE; -GLboolean __GLEW_EXT_blend_minmax = GL_FALSE; -GLboolean __GLEW_EXT_blend_subtract = GL_FALSE; -GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE; -GLboolean __GLEW_EXT_cmyka = GL_FALSE; -GLboolean __GLEW_EXT_color_subtable = GL_FALSE; -GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE; -GLboolean __GLEW_EXT_convolution = GL_FALSE; -GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE; -GLboolean __GLEW_EXT_copy_texture = GL_FALSE; -GLboolean __GLEW_EXT_cull_vertex = GL_FALSE; -GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE; -GLboolean __GLEW_EXT_direct_state_access = GL_FALSE; -GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE; -GLboolean __GLEW_EXT_draw_instanced = GL_FALSE; -GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE; -GLboolean __GLEW_EXT_fog_coord = GL_FALSE; -GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE; -GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE; -GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE; -GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE; -GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE; -GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE; -GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE; -GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE; -GLboolean __GLEW_EXT_histogram = GL_FALSE; -GLboolean __GLEW_EXT_index_array_formats = GL_FALSE; -GLboolean __GLEW_EXT_index_func = GL_FALSE; -GLboolean __GLEW_EXT_index_material = GL_FALSE; -GLboolean __GLEW_EXT_index_texture = GL_FALSE; -GLboolean __GLEW_EXT_light_texture = GL_FALSE; -GLboolean __GLEW_EXT_misc_attribute = GL_FALSE; -GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE; -GLboolean __GLEW_EXT_multisample = GL_FALSE; -GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE; -GLboolean __GLEW_EXT_packed_float = GL_FALSE; -GLboolean __GLEW_EXT_packed_pixels = GL_FALSE; -GLboolean __GLEW_EXT_paletted_texture = GL_FALSE; -GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE; -GLboolean __GLEW_EXT_pixel_transform = GL_FALSE; -GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE; -GLboolean __GLEW_EXT_point_parameters = GL_FALSE; -GLboolean __GLEW_EXT_polygon_offset = GL_FALSE; -GLboolean __GLEW_EXT_rescale_normal = GL_FALSE; -GLboolean __GLEW_EXT_scene_marker = GL_FALSE; -GLboolean __GLEW_EXT_secondary_color = GL_FALSE; -GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; -GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE; -GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE; -GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE; -GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE; -GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE; -GLboolean __GLEW_EXT_subtexture = GL_FALSE; -GLboolean __GLEW_EXT_texture = GL_FALSE; -GLboolean __GLEW_EXT_texture3D = GL_FALSE; -GLboolean __GLEW_EXT_texture_array = GL_FALSE; -GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE; -GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE; -GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE; -GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE; -GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE; -GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE; -GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE; -GLboolean __GLEW_EXT_texture_env = GL_FALSE; -GLboolean __GLEW_EXT_texture_env_add = GL_FALSE; -GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE; -GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE; -GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE; -GLboolean __GLEW_EXT_texture_integer = GL_FALSE; -GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE; -GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE; -GLboolean __GLEW_EXT_texture_object = GL_FALSE; -GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE; -GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE; -GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE; -GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE; -GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE; -GLboolean __GLEW_EXT_timer_query = GL_FALSE; -GLboolean __GLEW_EXT_transform_feedback = GL_FALSE; -GLboolean __GLEW_EXT_vertex_array = GL_FALSE; -GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE; -GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; -GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; -GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE; -GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE; -GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE; -GLboolean __GLEW_HP_image_transform = GL_FALSE; -GLboolean __GLEW_HP_occlusion_test = GL_FALSE; -GLboolean __GLEW_HP_texture_lighting = GL_FALSE; -GLboolean __GLEW_IBM_cull_vertex = GL_FALSE; -GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE; -GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE; -GLboolean __GLEW_IBM_static_data = GL_FALSE; -GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE; -GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE; -GLboolean __GLEW_INGR_color_clamp = GL_FALSE; -GLboolean __GLEW_INGR_interlace_read = GL_FALSE; -GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; -GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; -GLboolean __GLEW_KTX_buffer_region = GL_FALSE; -GLboolean __GLEW_MESAX_texture_stack = GL_FALSE; -GLboolean __GLEW_MESA_pack_invert = GL_FALSE; -GLboolean __GLEW_MESA_resize_buffers = GL_FALSE; -GLboolean __GLEW_MESA_window_pos = GL_FALSE; -GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE; -GLboolean __GLEW_NV_blend_square = GL_FALSE; -GLboolean __GLEW_NV_conditional_render = GL_FALSE; -GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; -GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE; -GLboolean __GLEW_NV_depth_clamp = GL_FALSE; -GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE; -GLboolean __GLEW_NV_evaluators = GL_FALSE; -GLboolean __GLEW_NV_explicit_multisample = GL_FALSE; -GLboolean __GLEW_NV_fence = GL_FALSE; -GLboolean __GLEW_NV_float_buffer = GL_FALSE; -GLboolean __GLEW_NV_fog_distance = GL_FALSE; -GLboolean __GLEW_NV_fragment_program = GL_FALSE; -GLboolean __GLEW_NV_fragment_program2 = GL_FALSE; -GLboolean __GLEW_NV_fragment_program4 = GL_FALSE; -GLboolean __GLEW_NV_fragment_program_option = GL_FALSE; -GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE; -GLboolean __GLEW_NV_geometry_program4 = GL_FALSE; -GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE; -GLboolean __GLEW_NV_gpu_program4 = GL_FALSE; -GLboolean __GLEW_NV_half_float = GL_FALSE; -GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; -GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE; -GLboolean __GLEW_NV_occlusion_query = GL_FALSE; -GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE; -GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE; -GLboolean __GLEW_NV_pixel_data_range = GL_FALSE; -GLboolean __GLEW_NV_point_sprite = GL_FALSE; -GLboolean __GLEW_NV_present_video = GL_FALSE; -GLboolean __GLEW_NV_primitive_restart = GL_FALSE; -GLboolean __GLEW_NV_register_combiners = GL_FALSE; -GLboolean __GLEW_NV_register_combiners2 = GL_FALSE; -GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; -GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; -GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE; -GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE; -GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE; -GLboolean __GLEW_NV_texture_rectangle = GL_FALSE; -GLboolean __GLEW_NV_texture_shader = GL_FALSE; -GLboolean __GLEW_NV_texture_shader2 = GL_FALSE; -GLboolean __GLEW_NV_texture_shader3 = GL_FALSE; -GLboolean __GLEW_NV_transform_feedback = GL_FALSE; -GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; -GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; -GLboolean __GLEW_NV_vertex_program = GL_FALSE; -GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE; -GLboolean __GLEW_NV_vertex_program2 = GL_FALSE; -GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE; -GLboolean __GLEW_NV_vertex_program3 = GL_FALSE; -GLboolean __GLEW_NV_vertex_program4 = GL_FALSE; -GLboolean __GLEW_OES_byte_coordinates = GL_FALSE; -GLboolean __GLEW_OES_compressed_paletted_texture = GL_FALSE; -GLboolean __GLEW_OES_read_format = GL_FALSE; -GLboolean __GLEW_OES_single_precision = GL_FALSE; -GLboolean __GLEW_OML_interlace = GL_FALSE; -GLboolean __GLEW_OML_resample = GL_FALSE; -GLboolean __GLEW_OML_subsample = GL_FALSE; -GLboolean __GLEW_PGI_misc_hints = GL_FALSE; -GLboolean __GLEW_PGI_vertex_hints = GL_FALSE; -GLboolean __GLEW_REND_screen_coordinates = GL_FALSE; -GLboolean __GLEW_S3_s3tc = GL_FALSE; -GLboolean __GLEW_SGIS_color_range = GL_FALSE; -GLboolean __GLEW_SGIS_detail_texture = GL_FALSE; -GLboolean __GLEW_SGIS_fog_function = GL_FALSE; -GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE; -GLboolean __GLEW_SGIS_multisample = GL_FALSE; -GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE; -GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE; -GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE; -GLboolean __GLEW_SGIS_texture4D = GL_FALSE; -GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE; -GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE; -GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE; -GLboolean __GLEW_SGIS_texture_lod = GL_FALSE; -GLboolean __GLEW_SGIS_texture_select = GL_FALSE; -GLboolean __GLEW_SGIX_async = GL_FALSE; -GLboolean __GLEW_SGIX_async_histogram = GL_FALSE; -GLboolean __GLEW_SGIX_async_pixel = GL_FALSE; -GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE; -GLboolean __GLEW_SGIX_clipmap = GL_FALSE; -GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE; -GLboolean __GLEW_SGIX_depth_texture = GL_FALSE; -GLboolean __GLEW_SGIX_flush_raster = GL_FALSE; -GLboolean __GLEW_SGIX_fog_offset = GL_FALSE; -GLboolean __GLEW_SGIX_fog_texture = GL_FALSE; -GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE; -GLboolean __GLEW_SGIX_framezoom = GL_FALSE; -GLboolean __GLEW_SGIX_interlace = GL_FALSE; -GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE; -GLboolean __GLEW_SGIX_list_priority = GL_FALSE; -GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE; -GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE; -GLboolean __GLEW_SGIX_reference_plane = GL_FALSE; -GLboolean __GLEW_SGIX_resample = GL_FALSE; -GLboolean __GLEW_SGIX_shadow = GL_FALSE; -GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE; -GLboolean __GLEW_SGIX_sprite = GL_FALSE; -GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE; -GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE; -GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE; -GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE; -GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE; -GLboolean __GLEW_SGIX_texture_range = GL_FALSE; -GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE; -GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE; -GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE; -GLboolean __GLEW_SGIX_ycrcb = GL_FALSE; -GLboolean __GLEW_SGI_color_matrix = GL_FALSE; -GLboolean __GLEW_SGI_color_table = GL_FALSE; -GLboolean __GLEW_SGI_texture_color_table = GL_FALSE; -GLboolean __GLEW_SUNX_constant_data = GL_FALSE; -GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE; -GLboolean __GLEW_SUN_global_alpha = GL_FALSE; -GLboolean __GLEW_SUN_mesh_array = GL_FALSE; -GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE; -GLboolean __GLEW_SUN_slice_accum = GL_FALSE; -GLboolean __GLEW_SUN_triangle_list = GL_FALSE; -GLboolean __GLEW_SUN_vertex = GL_FALSE; -GLboolean __GLEW_WIN_phong_shading = GL_FALSE; -GLboolean __GLEW_WIN_specular_fog = GL_FALSE; -GLboolean __GLEW_WIN_swap_hint = GL_FALSE; - -#endif /* !GLEW_MX */ - -#ifdef GL_VERSION_1_2 - -static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r; - r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r; - r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r; - r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_1_2 */ - -#ifdef GL_VERSION_1_3 - -static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r; - r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r; - r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r; - r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r; - r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r; - r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r; - r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r; - r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r; - r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r; - r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r; - r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r; - r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r; - r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r; - r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r; - r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r; - r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r; - r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r; - r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r; - r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r; - r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r; - r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r; - r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r; - r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r; - r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r; - r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r; - r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r; - r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r; - r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r; - r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r; - r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r; - r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r; - r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r; - r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r; - r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r; - r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r; - r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r; - r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r; - r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r; - r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r; - r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r; - r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r; - r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r; - r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r; - r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r; - r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r; - r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_1_3 */ - -#ifdef GL_VERSION_1_4 - -static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r; - r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; - r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r; - r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r; - r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r; - r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r; - r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r; - r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r; - r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r; - r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r; - r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r; - r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r; - r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r; - r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r; - r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r; - r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r; - r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r; - r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r; - r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r; - r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r; - r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r; - r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r; - r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r; - r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r; - r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r; - r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r; - r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r; - r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r; - r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r; - r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r; - r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r; - r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r; - r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r; - r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r; - r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r; - r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r; - r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r; - r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r; - r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r; - r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r; - r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r; - r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r; - r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r; - r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r; - r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r; - r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r; - r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_1_4 */ - -#ifdef GL_VERSION_1_5 - -static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r; - r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r; - r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r; - r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r; - r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r; - r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r; - r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r; - r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r; - r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r; - r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r; - r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r; - r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r; - r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r; - r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r; - r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r; - r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r; - r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r; - r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r; - r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_1_5 */ - -#ifdef GL_VERSION_2_0 - -static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r; - r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r; - r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r; - r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r; - r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r; - r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r; - r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r; - r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r; - r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r; - r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r; - r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r; - r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r; - r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r; - r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r; - r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r; - r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r; - r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r; - r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r; - r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r; - r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r; - r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r; - r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r; - r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r; - r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r; - r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r; - r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r; - r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r; - r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r; - r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r; - r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r; - r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r; - r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r; - r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r; - r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r; - r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r; - r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r; - r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r; - r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r; - r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r; - r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r; - r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r; - r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r; - r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r; - r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r; - r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r; - r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r; - r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r; - r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r; - r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r; - r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r; - r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r; - r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r; - r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r; - r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r; - r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r; - r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r; - r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r; - r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r; - r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r; - r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r; - r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r; - r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r; - r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r; - r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r; - r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r; - r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r; - r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r; - r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r; - r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r; - r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r; - r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r; - r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r; - r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r; - r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r; - r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r; - r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r; - r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r; - r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r; - r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r; - r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r; - r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r; - r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r; - r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r; - r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r; - r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r; - r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r; - r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r; - r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r; - r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r; - r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r; - r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r; - r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r; - r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_2_0 */ - -#ifdef GL_VERSION_2_1 - -static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r; - r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r; - r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r; - r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r; - r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r; - r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_2_1 */ - -#ifdef GL_VERSION_3_0 - -static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r; - r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r; - r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r; - r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r; - r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r; - r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r; - r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r; - r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r; - r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r; - r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r; - r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r; - r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r; - r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r; - r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r; - r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r; - r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r; - r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r; - r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r; - r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r; - r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r; - r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r; - r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r; - r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r; - r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r; - r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r; - r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r; - r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r; - r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r; - r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r; - r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r; - r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r; - r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r; - r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r; - r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r; - r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r; - r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r; - r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r; - r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r; - r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r; - r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r; - r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r; - r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r; - r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r; - r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r; - r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r; - r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r; - r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r; - r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r; - r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r; - r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r; - r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r; - r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r; - r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r; - r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r; - r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r; - r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r; - r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r; - r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r; - - return r; -} - -#endif /* GL_VERSION_3_0 */ - -#ifdef GL_3DFX_multisample - -#endif /* GL_3DFX_multisample */ - -#ifdef GL_3DFX_tbuffer - -static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r; - - return r; -} - -#endif /* GL_3DFX_tbuffer */ - -#ifdef GL_3DFX_texture_compression_FXT1 - -#endif /* GL_3DFX_texture_compression_FXT1 */ - -#ifdef GL_APPLE_client_storage - -#endif /* GL_APPLE_client_storage */ - -#ifdef GL_APPLE_element_array - -static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r; - r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r; - r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r; - r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r; - r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_element_array */ - -#ifdef GL_APPLE_fence - -static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r; - r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r; - r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r; - r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r; - r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r; - r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r; - r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r; - r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_fence */ - -#ifdef GL_APPLE_float_pixels - -#endif /* GL_APPLE_float_pixels */ - -#ifdef GL_APPLE_flush_buffer_range - -static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r; - r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_flush_buffer_range */ - -#ifdef GL_APPLE_pixel_buffer - -#endif /* GL_APPLE_pixel_buffer */ - -#ifdef GL_APPLE_specular_vector - -#endif /* GL_APPLE_specular_vector */ - -#ifdef GL_APPLE_texture_range - -static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r; - r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_texture_range */ - -#ifdef GL_APPLE_transform_hint - -#endif /* GL_APPLE_transform_hint */ - -#ifdef GL_APPLE_vertex_array_object - -static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r; - r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r; - r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r; - r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_vertex_array_object */ - -#ifdef GL_APPLE_vertex_array_range - -static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r; - r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r; - r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r; - - return r; -} - -#endif /* GL_APPLE_vertex_array_range */ - -#ifdef GL_APPLE_ycbcr_422 - -#endif /* GL_APPLE_ycbcr_422 */ - -#ifdef GL_ARB_color_buffer_float - -static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_color_buffer_float */ - -#ifdef GL_ARB_depth_buffer_float - -#endif /* GL_ARB_depth_buffer_float */ - -#ifdef GL_ARB_depth_texture - -#endif /* GL_ARB_depth_texture */ - -#ifdef GL_ARB_draw_buffers - -static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_draw_buffers */ - -#ifdef GL_ARB_draw_instanced - -static GLboolean _glewInit_GL_ARB_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r; - r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_draw_instanced */ - -#ifdef GL_ARB_fragment_program - -#endif /* GL_ARB_fragment_program */ - -#ifdef GL_ARB_fragment_program_shadow - -#endif /* GL_ARB_fragment_program_shadow */ - -#ifdef GL_ARB_fragment_shader - -#endif /* GL_ARB_fragment_shader */ - -#ifdef GL_ARB_framebuffer_object - -static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r; - r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r; - r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r; - r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r; - r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r; - r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r; - r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r; - r = ((glFramebufferTexturLayer = (PFNGLFRAMEBUFFERTEXTURLAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexturLayer")) == NULL) || r; - r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r; - r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r; - r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r; - r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r; - r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r; - r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r; - r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r; - r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r; - r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r; - r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r; - r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r; - r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_framebuffer_object */ - -#ifdef GL_ARB_framebuffer_sRGB - -#endif /* GL_ARB_framebuffer_sRGB */ - -#ifdef GL_ARB_geometry_shader4 - -static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r; - r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r; - r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r; - r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_geometry_shader4 */ - -#ifdef GL_ARB_half_float_pixel - -#endif /* GL_ARB_half_float_pixel */ - -#ifdef GL_ARB_half_float_vertex - -#endif /* GL_ARB_half_float_vertex */ - -#ifdef GL_ARB_imaging - -static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; - r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r; - r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r; - r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r; - r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r; - r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r; - r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r; - r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r; - r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r; - r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r; - r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r; - r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r; - r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r; - r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r; - r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r; - r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r; - r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r; - r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r; - r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r; - r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r; - r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r; - r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r; - r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r; - r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r; - r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r; - r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r; - r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r; - r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r; - r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r; - r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r; - r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r; - r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r; - r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_imaging */ - -#ifdef GL_ARB_instanced_arrays - -static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_instanced_arrays */ - -#ifdef GL_ARB_map_buffer_range - -static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r; - r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_map_buffer_range */ - -#ifdef GL_ARB_matrix_palette - -static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r; - r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r; - r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r; - r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r; - r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_matrix_palette */ - -#ifdef GL_ARB_multisample - -static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_multisample */ - -#ifdef GL_ARB_multitexture - -static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r; - r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r; - r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r; - r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r; - r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r; - r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r; - r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r; - r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r; - r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r; - r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r; - r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r; - r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r; - r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r; - r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r; - r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r; - r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r; - r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r; - r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r; - r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r; - r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r; - r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r; - r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r; - r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r; - r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r; - r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r; - r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r; - r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r; - r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r; - r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r; - r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r; - r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r; - r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r; - r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r; - r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_multitexture */ - -#ifdef GL_ARB_occlusion_query - -static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r; - r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r; - r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r; - r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r; - r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r; - r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r; - r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r; - r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_occlusion_query */ - -#ifdef GL_ARB_pixel_buffer_object - -#endif /* GL_ARB_pixel_buffer_object */ - -#ifdef GL_ARB_point_parameters - -static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r; - r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_point_parameters */ - -#ifdef GL_ARB_point_sprite - -#endif /* GL_ARB_point_sprite */ - -#ifdef GL_ARB_shader_objects - -static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r; - r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r; - r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r; - r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r; - r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r; - r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r; - r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r; - r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r; - r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r; - r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r; - r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r; - r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r; - r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r; - r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r; - r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r; - r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r; - r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r; - r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r; - r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r; - r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r; - r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r; - r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r; - r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r; - r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r; - r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r; - r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r; - r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r; - r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r; - r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r; - r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r; - r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r; - r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r; - r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r; - r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r; - r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r; - r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r; - r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r; - r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r; - r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_shader_objects */ - -#ifdef GL_ARB_shading_language_100 - -#endif /* GL_ARB_shading_language_100 */ - -#ifdef GL_ARB_shadow - -#endif /* GL_ARB_shadow */ - -#ifdef GL_ARB_shadow_ambient - -#endif /* GL_ARB_shadow_ambient */ - -#ifdef GL_ARB_texture_border_clamp - -#endif /* GL_ARB_texture_border_clamp */ - -#ifdef GL_ARB_texture_buffer_object - -static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_texture_buffer_object */ - -#ifdef GL_ARB_texture_compression - -static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r; - r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r; - r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r; - r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r; - r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r; - r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r; - r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_texture_compression */ - -#ifdef GL_ARB_texture_compression_rgtc - -#endif /* GL_ARB_texture_compression_rgtc */ - -#ifdef GL_ARB_texture_cube_map - -#endif /* GL_ARB_texture_cube_map */ - -#ifdef GL_ARB_texture_env_add - -#endif /* GL_ARB_texture_env_add */ - -#ifdef GL_ARB_texture_env_combine - -#endif /* GL_ARB_texture_env_combine */ - -#ifdef GL_ARB_texture_env_crossbar - -#endif /* GL_ARB_texture_env_crossbar */ - -#ifdef GL_ARB_texture_env_dot3 - -#endif /* GL_ARB_texture_env_dot3 */ - -#ifdef GL_ARB_texture_float - -#endif /* GL_ARB_texture_float */ - -#ifdef GL_ARB_texture_mirrored_repeat - -#endif /* GL_ARB_texture_mirrored_repeat */ - -#ifdef GL_ARB_texture_non_power_of_two - -#endif /* GL_ARB_texture_non_power_of_two */ - -#ifdef GL_ARB_texture_rectangle - -#endif /* GL_ARB_texture_rectangle */ - -#ifdef GL_ARB_texture_rg - -#endif /* GL_ARB_texture_rg */ - -#ifdef GL_ARB_transpose_matrix - -static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r; - r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r; - r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r; - r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_transpose_matrix */ - -#ifdef GL_ARB_vertex_array_object - -static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r; - r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r; - r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r; - r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_vertex_array_object */ - -#ifdef GL_ARB_vertex_blend - -static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r; - r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r; - r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r; - r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r; - r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r; - r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r; - r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r; - r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r; - r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r; - r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_vertex_blend */ - -#ifdef GL_ARB_vertex_buffer_object - -static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r; - r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r; - r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r; - r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r; - r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r; - r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r; - r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r; - r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r; - r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r; - r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r; - r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_vertex_buffer_object */ - -#ifdef GL_ARB_vertex_program - -static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r; - r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r; - r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r; - r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r; - r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r; - r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r; - r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r; - r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r; - r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r; - r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r; - r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r; - r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r; - r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r; - r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r; - r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r; - r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r; - r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r; - r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r; - r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r; - r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r; - r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r; - r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r; - r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r; - r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r; - r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r; - r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r; - r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r; - r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r; - r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r; - r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r; - r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r; - r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r; - r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r; - r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r; - r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r; - r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r; - r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r; - r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r; - r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r; - r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r; - r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r; - r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r; - r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r; - r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r; - r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r; - r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r; - r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r; - r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r; - r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r; - r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r; - r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r; - r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r; - r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r; - r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r; - r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r; - r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r; - r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r; - r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r; - r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r; - r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r; - r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r; - r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_vertex_program */ - -#ifdef GL_ARB_vertex_shader - -static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r; - r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r; - r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_vertex_shader */ - -#ifdef GL_ARB_window_pos - -static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r; - r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r; - r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r; - r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r; - r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r; - r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r; - r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r; - r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r; - r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r; - r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r; - r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r; - r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r; - r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r; - r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r; - r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r; - r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r; - - return r; -} - -#endif /* GL_ARB_window_pos */ - -#ifdef GL_ATIX_point_sprites - -#endif /* GL_ATIX_point_sprites */ - -#ifdef GL_ATIX_texture_env_combine3 - -#endif /* GL_ATIX_texture_env_combine3 */ - -#ifdef GL_ATIX_texture_env_route - -#endif /* GL_ATIX_texture_env_route */ - -#ifdef GL_ATIX_vertex_shader_output_point_size - -#endif /* GL_ATIX_vertex_shader_output_point_size */ - -#ifdef GL_ATI_draw_buffers - -static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_draw_buffers */ - -#ifdef GL_ATI_element_array - -static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r; - r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r; - r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_element_array */ - -#ifdef GL_ATI_envmap_bumpmap - -static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r; - r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r; - r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r; - r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_envmap_bumpmap */ - -#ifdef GL_ATI_fragment_shader - -static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r; - r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r; - r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r; - r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r; - r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r; - r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r; - r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r; - r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r; - r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r; - r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r; - r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r; - r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r; - r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r; - r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_fragment_shader */ - -#ifdef GL_ATI_map_object_buffer - -static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r; - r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_map_object_buffer */ - -#ifdef GL_ATI_pn_triangles - -static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r; - r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_pn_triangles */ - -#ifdef GL_ATI_separate_stencil - -static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r; - r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_separate_stencil */ - -#ifdef GL_ATI_shader_texture_lod - -#endif /* GL_ATI_shader_texture_lod */ - -#ifdef GL_ATI_text_fragment_shader - -#endif /* GL_ATI_text_fragment_shader */ - -#ifdef GL_ATI_texture_compression_3dc - -#endif /* GL_ATI_texture_compression_3dc */ - -#ifdef GL_ATI_texture_env_combine3 - -#endif /* GL_ATI_texture_env_combine3 */ - -#ifdef GL_ATI_texture_float - -#endif /* GL_ATI_texture_float */ - -#ifdef GL_ATI_texture_mirror_once - -#endif /* GL_ATI_texture_mirror_once */ - -#ifdef GL_ATI_vertex_array_object - -static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r; - r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r; - r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r; - r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r; - r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r; - r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r; - r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r; - r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r; - r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r; - r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r; - r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r; - r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_vertex_array_object */ - -#ifdef GL_ATI_vertex_attrib_array_object - -static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r; - r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r; - r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_vertex_attrib_array_object */ - -#ifdef GL_ATI_vertex_streams - -static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r; - r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r; - r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r; - r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r; - r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r; - r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r; - r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r; - r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r; - r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r; - r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r; - r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r; - r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r; - r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r; - r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r; - r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r; - r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r; - r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r; - r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r; - r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r; - r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r; - r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r; - r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r; - r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r; - r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r; - r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r; - r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r; - r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r; - r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r; - r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r; - r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r; - r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r; - r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r; - r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r; - r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r; - r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r; - r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r; - r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r; - - return r; -} - -#endif /* GL_ATI_vertex_streams */ - -#ifdef GL_EXT_422_pixels - -#endif /* GL_EXT_422_pixels */ - -#ifdef GL_EXT_Cg_shader - -#endif /* GL_EXT_Cg_shader */ - -#ifdef GL_EXT_abgr - -#endif /* GL_EXT_abgr */ - -#ifdef GL_EXT_bgra - -#endif /* GL_EXT_bgra */ - -#ifdef GL_EXT_bindable_uniform - -static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r; - r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r; - r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_bindable_uniform */ - -#ifdef GL_EXT_blend_color - -static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_blend_color */ - -#ifdef GL_EXT_blend_equation_separate - -static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_blend_equation_separate */ - -#ifdef GL_EXT_blend_func_separate - -static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_blend_func_separate */ - -#ifdef GL_EXT_blend_logic_op - -#endif /* GL_EXT_blend_logic_op */ - -#ifdef GL_EXT_blend_minmax - -static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_blend_minmax */ - -#ifdef GL_EXT_blend_subtract - -#endif /* GL_EXT_blend_subtract */ - -#ifdef GL_EXT_clip_volume_hint - -#endif /* GL_EXT_clip_volume_hint */ - -#ifdef GL_EXT_cmyka - -#endif /* GL_EXT_cmyka */ - -#ifdef GL_EXT_color_subtable - -static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r; - r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_color_subtable */ - -#ifdef GL_EXT_compiled_vertex_array - -static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r; - r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_compiled_vertex_array */ - -#ifdef GL_EXT_convolution - -static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r; - r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r; - r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r; - r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r; - r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r; - r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r; - r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r; - r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r; - r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r; - r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r; - r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r; - r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r; - r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_convolution */ - -#ifdef GL_EXT_coordinate_frame - -static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r; - r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_coordinate_frame */ - -#ifdef GL_EXT_copy_texture - -static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r; - r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r; - r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r; - r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r; - r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_copy_texture */ - -#ifdef GL_EXT_cull_vertex - -static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r; - r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_cull_vertex */ - -#ifdef GL_EXT_depth_bounds_test - -static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_depth_bounds_test */ - -#ifdef GL_EXT_direct_state_access - -static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r; - r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r; - r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r; - r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r; - r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r; - r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r; - r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r; - r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r; - r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r; - r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r; - r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r; - r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r; - r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r; - r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r; - r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r; - r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r; - r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r; - r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r; - r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r; - r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r; - r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r; - r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r; - r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r; - r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r; - r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r; - r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r; - r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r; - r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r; - r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r; - r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r; - r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r; - r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r; - r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r; - r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r; - r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r; - r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r; - r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r; - r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r; - r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r; - r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r; - r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r; - r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r; - r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r; - r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r; - r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r; - r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r; - r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r; - r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r; - r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r; - r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r; - r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r; - r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r; - r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r; - r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r; - r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r; - r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r; - r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r; - r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r; - r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r; - r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r; - r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r; - r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r; - r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r; - r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r; - r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r; - r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r; - r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r; - r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r; - r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r; - r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r; - r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r; - r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r; - r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r; - r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r; - r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r; - r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r; - r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r; - r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r; - r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r; - r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r; - r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r; - r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r; - r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r; - r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r; - r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r; - r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r; - r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r; - r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r; - r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r; - r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r; - r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r; - r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r; - r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r; - r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r; - r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r; - r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r; - r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r; - r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r; - r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r; - r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r; - r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r; - r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r; - r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r; - r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r; - r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r; - r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r; - r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r; - r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r; - r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r; - r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r; - r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r; - r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r; - r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r; - r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r; - r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r; - r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r; - r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r; - r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r; - r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r; - r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r; - r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r; - r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r; - r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r; - r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r; - r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r; - r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r; - r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r; - r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r; - r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r; - r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r; - r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r; - r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r; - r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r; - r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r; - r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r; - r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r; - r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r; - r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r; - r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r; - r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r; - r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r; - r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r; - r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r; - r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r; - r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r; - r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r; - r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r; - r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r; - r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r; - r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r; - r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r; - r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r; - r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r; - r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r; - r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r; - r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r; - r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r; - r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r; - r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r; - r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r; - r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r; - r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r; - r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r; - r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r; - r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r; - r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r; - r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r; - r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r; - r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r; - r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r; - r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_direct_state_access */ - -#ifdef GL_EXT_draw_buffers2 - -static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r; - r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r; - r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r; - r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r; - r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r; - r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_draw_buffers2 */ - -#ifdef GL_EXT_draw_instanced - -static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r; - r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_draw_instanced */ - -#ifdef GL_EXT_draw_range_elements - -static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_draw_range_elements */ - -#ifdef GL_EXT_fog_coord - -static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r; - r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r; - r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r; - r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r; - r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_fog_coord */ - -#ifdef GL_EXT_fragment_lighting - -static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r; - r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r; - r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r; - r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r; - r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r; - r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r; - r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r; - r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r; - r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r; - r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r; - r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r; - r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r; - r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r; - r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r; - r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r; - r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r; - r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r; - r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_fragment_lighting */ - -#ifdef GL_EXT_framebuffer_blit - -static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_framebuffer_blit */ - -#ifdef GL_EXT_framebuffer_multisample - -static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_framebuffer_multisample */ - -#ifdef GL_EXT_framebuffer_object - -static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r; - r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r; - r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r; - r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r; - r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r; - r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r; - r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r; - r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r; - r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r; - r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r; - r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r; - r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r; - r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r; - r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r; - r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r; - r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r; - r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_framebuffer_object */ - -#ifdef GL_EXT_framebuffer_sRGB - -#endif /* GL_EXT_framebuffer_sRGB */ - -#ifdef GL_EXT_geometry_shader4 - -static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r; - r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r; - r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r; - r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_geometry_shader4 */ - -#ifdef GL_EXT_gpu_program_parameters - -static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r; - r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_gpu_program_parameters */ - -#ifdef GL_EXT_gpu_shader4 - -static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r; - r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r; - r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r; - r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r; - r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r; - r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r; - r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r; - r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r; - r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r; - r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r; - r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r; - r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r; - r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r; - r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r; - r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r; - r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r; - r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r; - r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r; - r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r; - r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r; - r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r; - r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r; - r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r; - r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r; - r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r; - r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r; - r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r; - r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r; - r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r; - r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r; - r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r; - r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r; - r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r; - r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_gpu_shader4 */ - -#ifdef GL_EXT_histogram - -static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r; - r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r; - r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r; - r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r; - r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r; - r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r; - r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r; - r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r; - r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r; - r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_histogram */ - -#ifdef GL_EXT_index_array_formats - -#endif /* GL_EXT_index_array_formats */ - -#ifdef GL_EXT_index_func - -static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_index_func */ - -#ifdef GL_EXT_index_material - -static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_index_material */ - -#ifdef GL_EXT_index_texture - -#endif /* GL_EXT_index_texture */ - -#ifdef GL_EXT_light_texture - -static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r; - r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r; - r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_light_texture */ - -#ifdef GL_EXT_misc_attribute - -#endif /* GL_EXT_misc_attribute */ - -#ifdef GL_EXT_multi_draw_arrays - -static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r; - r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_multi_draw_arrays */ - -#ifdef GL_EXT_multisample - -static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r; - r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_multisample */ - -#ifdef GL_EXT_packed_depth_stencil - -#endif /* GL_EXT_packed_depth_stencil */ - -#ifdef GL_EXT_packed_float - -#endif /* GL_EXT_packed_float */ - -#ifdef GL_EXT_packed_pixels - -#endif /* GL_EXT_packed_pixels */ - -#ifdef GL_EXT_paletted_texture - -static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r; - r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r; - r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r; - r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_paletted_texture */ - -#ifdef GL_EXT_pixel_buffer_object - -#endif /* GL_EXT_pixel_buffer_object */ - -#ifdef GL_EXT_pixel_transform - -static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r; - r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r; - r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r; - r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r; - r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r; - r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_pixel_transform */ - -#ifdef GL_EXT_pixel_transform_color_table - -#endif /* GL_EXT_pixel_transform_color_table */ - -#ifdef GL_EXT_point_parameters - -static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r; - r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_point_parameters */ - -#ifdef GL_EXT_polygon_offset - -static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_polygon_offset */ - -#ifdef GL_EXT_rescale_normal - -#endif /* GL_EXT_rescale_normal */ - -#ifdef GL_EXT_scene_marker - -static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r; - r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_scene_marker */ - -#ifdef GL_EXT_secondary_color - -static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r; - r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r; - r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r; - r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r; - r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r; - r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r; - r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r; - r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r; - r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r; - r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r; - r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r; - r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r; - r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r; - r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r; - r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r; - r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r; - r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_secondary_color */ - -#ifdef GL_EXT_separate_specular_color - -#endif /* GL_EXT_separate_specular_color */ - -#ifdef GL_EXT_shadow_funcs - -#endif /* GL_EXT_shadow_funcs */ - -#ifdef GL_EXT_shared_texture_palette - -#endif /* GL_EXT_shared_texture_palette */ - -#ifdef GL_EXT_stencil_clear_tag - -#endif /* GL_EXT_stencil_clear_tag */ - -#ifdef GL_EXT_stencil_two_side - -static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_stencil_two_side */ - -#ifdef GL_EXT_stencil_wrap - -#endif /* GL_EXT_stencil_wrap */ - -#ifdef GL_EXT_subtexture - -static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r; - r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r; - r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_subtexture */ - -#ifdef GL_EXT_texture - -#endif /* GL_EXT_texture */ - -#ifdef GL_EXT_texture3D - -static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_texture3D */ - -#ifdef GL_EXT_texture_array - -#endif /* GL_EXT_texture_array */ - -#ifdef GL_EXT_texture_buffer_object - -static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_texture_buffer_object */ - -#ifdef GL_EXT_texture_compression_dxt1 - -#endif /* GL_EXT_texture_compression_dxt1 */ - -#ifdef GL_EXT_texture_compression_latc - -#endif /* GL_EXT_texture_compression_latc */ - -#ifdef GL_EXT_texture_compression_rgtc - -#endif /* GL_EXT_texture_compression_rgtc */ - -#ifdef GL_EXT_texture_compression_s3tc - -#endif /* GL_EXT_texture_compression_s3tc */ - -#ifdef GL_EXT_texture_cube_map - -#endif /* GL_EXT_texture_cube_map */ - -#ifdef GL_EXT_texture_edge_clamp - -#endif /* GL_EXT_texture_edge_clamp */ - -#ifdef GL_EXT_texture_env - -#endif /* GL_EXT_texture_env */ - -#ifdef GL_EXT_texture_env_add - -#endif /* GL_EXT_texture_env_add */ - -#ifdef GL_EXT_texture_env_combine - -#endif /* GL_EXT_texture_env_combine */ - -#ifdef GL_EXT_texture_env_dot3 - -#endif /* GL_EXT_texture_env_dot3 */ - -#ifdef GL_EXT_texture_filter_anisotropic - -#endif /* GL_EXT_texture_filter_anisotropic */ - -#ifdef GL_EXT_texture_integer - -static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r; - r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r; - r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r; - r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r; - r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r; - r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_texture_integer */ - -#ifdef GL_EXT_texture_lod_bias - -#endif /* GL_EXT_texture_lod_bias */ - -#ifdef GL_EXT_texture_mirror_clamp - -#endif /* GL_EXT_texture_mirror_clamp */ - -#ifdef GL_EXT_texture_object - -static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r; - r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r; - r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r; - r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r; - r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r; - r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_texture_object */ - -#ifdef GL_EXT_texture_perturb_normal - -static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_texture_perturb_normal */ - -#ifdef GL_EXT_texture_rectangle - -#endif /* GL_EXT_texture_rectangle */ - -#ifdef GL_EXT_texture_sRGB - -#endif /* GL_EXT_texture_sRGB */ - -#ifdef GL_EXT_texture_shared_exponent - -#endif /* GL_EXT_texture_shared_exponent */ - -#ifdef GL_EXT_texture_swizzle - -#endif /* GL_EXT_texture_swizzle */ - -#ifdef GL_EXT_timer_query - -static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r; - r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_timer_query */ - -#ifdef GL_EXT_transform_feedback - -static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r; - r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r; - r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r; - r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r; - r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r; - r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r; - r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_transform_feedback */ - -#ifdef GL_EXT_vertex_array - -static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r; - r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r; - r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r; - r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r; - r = ((glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointervEXT")) == NULL) || r; - r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r; - r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r; - r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r; - r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_vertex_array */ - -#ifdef GL_EXT_vertex_array_bgra - -#endif /* GL_EXT_vertex_array_bgra */ - -#ifdef GL_EXT_vertex_shader - -static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r; - r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r; - r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r; - r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r; - r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r; - r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r; - r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r; - r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r; - r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r; - r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r; - r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r; - r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r; - r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r; - r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r; - r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r; - r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r; - r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r; - r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r; - r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r; - r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r; - r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r; - r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r; - r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r; - r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r; - r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r; - r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r; - r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r; - r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r; - r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r; - r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r; - r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r; - r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r; - r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r; - r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r; - r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r; - r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r; - r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r; - r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r; - r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r; - r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r; - r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r; - r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_vertex_shader */ - -#ifdef GL_EXT_vertex_weighting - -static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r; - r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r; - r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_EXT_vertex_weighting */ - -#ifdef GL_GREMEDY_frame_terminator - -static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r; - - return r; -} - -#endif /* GL_GREMEDY_frame_terminator */ - -#ifdef GL_GREMEDY_string_marker - -static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r; - - return r; -} - -#endif /* GL_GREMEDY_string_marker */ - -#ifdef GL_HP_convolution_border_modes - -#endif /* GL_HP_convolution_border_modes */ - -#ifdef GL_HP_image_transform - -static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r; - r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r; - r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r; - r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r; - r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r; - r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r; - - return r; -} - -#endif /* GL_HP_image_transform */ - -#ifdef GL_HP_occlusion_test - -#endif /* GL_HP_occlusion_test */ - -#ifdef GL_HP_texture_lighting - -#endif /* GL_HP_texture_lighting */ - -#ifdef GL_IBM_cull_vertex - -#endif /* GL_IBM_cull_vertex */ - -#ifdef GL_IBM_multimode_draw_arrays - -static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r; - r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r; - - return r; -} - -#endif /* GL_IBM_multimode_draw_arrays */ - -#ifdef GL_IBM_rasterpos_clip - -#endif /* GL_IBM_rasterpos_clip */ - -#ifdef GL_IBM_static_data - -#endif /* GL_IBM_static_data */ - -#ifdef GL_IBM_texture_mirrored_repeat - -#endif /* GL_IBM_texture_mirrored_repeat */ - -#ifdef GL_IBM_vertex_array_lists - -static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r; - r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r; - r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r; - r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r; - r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r; - r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r; - r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r; - r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r; - - return r; -} - -#endif /* GL_IBM_vertex_array_lists */ - -#ifdef GL_INGR_color_clamp - -#endif /* GL_INGR_color_clamp */ - -#ifdef GL_INGR_interlace_read - -#endif /* GL_INGR_interlace_read */ - -#ifdef GL_INTEL_parallel_arrays - -static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r; - r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r; - r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r; - r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r; - - return r; -} - -#endif /* GL_INTEL_parallel_arrays */ - -#ifdef GL_INTEL_texture_scissor - -static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r; - r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r; - - return r; -} - -#endif /* GL_INTEL_texture_scissor */ - -#ifdef GL_KTX_buffer_region - -static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBufferRegionEnabledEXT = (PFNGLBUFFERREGIONENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabledEXT")) == NULL) || r; - r = ((glDeleteBufferRegionEXT = (PFNGLDELETEBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegionEXT")) == NULL) || r; - r = ((glDrawBufferRegionEXT = (PFNGLDRAWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegionEXT")) == NULL) || r; - r = ((glNewBufferRegionEXT = (PFNGLNEWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegionEXT")) == NULL) || r; - r = ((glReadBufferRegionEXT = (PFNGLREADBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegionEXT")) == NULL) || r; - - return r; -} - -#endif /* GL_KTX_buffer_region */ - -#ifdef GL_MESAX_texture_stack - -#endif /* GL_MESAX_texture_stack */ - -#ifdef GL_MESA_pack_invert - -#endif /* GL_MESA_pack_invert */ - -#ifdef GL_MESA_resize_buffers - -static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r; - - return r; -} - -#endif /* GL_MESA_resize_buffers */ - -#ifdef GL_MESA_window_pos - -static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r; - r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r; - r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r; - r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r; - r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r; - r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r; - r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r; - r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r; - r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r; - r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r; - r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r; - r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r; - r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r; - r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r; - r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r; - r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r; - r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r; - r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r; - r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r; - r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r; - r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r; - r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r; - r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r; - r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r; - - return r; -} - -#endif /* GL_MESA_window_pos */ - -#ifdef GL_MESA_ycbcr_texture - -#endif /* GL_MESA_ycbcr_texture */ - -#ifdef GL_NV_blend_square - -#endif /* GL_NV_blend_square */ - -#ifdef GL_NV_conditional_render - -static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r; - r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_conditional_render */ - -#ifdef GL_NV_copy_depth_to_color - -#endif /* GL_NV_copy_depth_to_color */ - -#ifdef GL_NV_depth_buffer_float - -static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r; - r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r; - r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_depth_buffer_float */ - -#ifdef GL_NV_depth_clamp - -#endif /* GL_NV_depth_clamp */ - -#ifdef GL_NV_depth_range_unclamped - -#endif /* GL_NV_depth_range_unclamped */ - -#ifdef GL_NV_evaluators - -static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r; - r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r; - r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r; - r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r; - r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r; - r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r; - r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r; - r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r; - r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_evaluators */ - -#ifdef GL_NV_explicit_multisample - -static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r; - r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r; - r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_explicit_multisample */ - -#ifdef GL_NV_fence - -static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r; - r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r; - r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r; - r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r; - r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r; - r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r; - r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_fence */ - -#ifdef GL_NV_float_buffer - -#endif /* GL_NV_float_buffer */ - -#ifdef GL_NV_fog_distance - -#endif /* GL_NV_fog_distance */ - -#ifdef GL_NV_fragment_program - -static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r; - r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r; - r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r; - r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r; - r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r; - r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_fragment_program */ - -#ifdef GL_NV_fragment_program2 - -#endif /* GL_NV_fragment_program2 */ - -#ifdef GL_NV_fragment_program4 - -#endif /* GL_NV_fragment_program4 */ - -#ifdef GL_NV_fragment_program_option - -#endif /* GL_NV_fragment_program_option */ - -#ifdef GL_NV_framebuffer_multisample_coverage - -static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_framebuffer_multisample_coverage */ - -#ifdef GL_NV_geometry_program4 - -static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_geometry_program4 */ - -#ifdef GL_NV_geometry_shader4 - -#endif /* GL_NV_geometry_shader4 */ - -#ifdef GL_NV_gpu_program4 - -static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r; - r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r; - r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r; - r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r; - r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r; - r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r; - r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r; - r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r; - r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r; - r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r; - r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r; - r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_gpu_program4 */ - -#ifdef GL_NV_half_float - -static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r; - r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r; - r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r; - r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r; - r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r; - r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r; - r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r; - r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r; - r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r; - r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r; - r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r; - r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r; - r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r; - r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r; - r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r; - r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r; - r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r; - r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r; - r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r; - r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r; - r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r; - r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r; - r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r; - r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r; - r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r; - r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r; - r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r; - r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r; - r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r; - r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r; - r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r; - r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r; - r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r; - r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r; - r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r; - r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r; - r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r; - r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r; - r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r; - r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r; - r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r; - r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r; - r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r; - r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r; - r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r; - r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_half_float */ - -#ifdef GL_NV_light_max_exponent - -#endif /* GL_NV_light_max_exponent */ - -#ifdef GL_NV_multisample_filter_hint - -#endif /* GL_NV_multisample_filter_hint */ - -#ifdef GL_NV_occlusion_query - -static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r; - r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r; - r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r; - r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r; - r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r; - r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r; - r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_occlusion_query */ - -#ifdef GL_NV_packed_depth_stencil - -#endif /* GL_NV_packed_depth_stencil */ - -#ifdef GL_NV_parameter_buffer_object - -static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r; - r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r; - r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_parameter_buffer_object */ - -#ifdef GL_NV_pixel_data_range - -static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r; - r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_pixel_data_range */ - -#ifdef GL_NV_point_sprite - -static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r; - r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_point_sprite */ - -#ifdef GL_NV_present_video - -static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r; - r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r; - r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r; - r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r; - r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r; - r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r; - r = ((glVideoParameterivNV = (PFNGLVIDEOPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoParameterivNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_present_video */ - -#ifdef GL_NV_primitive_restart - -static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r; - r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_primitive_restart */ - -#ifdef GL_NV_register_combiners - -static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r; - r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r; - r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r; - r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r; - r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r; - r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r; - r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r; - r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r; - r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r; - r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r; - r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r; - r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r; - r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_register_combiners */ - -#ifdef GL_NV_register_combiners2 - -static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r; - r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_register_combiners2 */ - -#ifdef GL_NV_texgen_emboss - -#endif /* GL_NV_texgen_emboss */ - -#ifdef GL_NV_texgen_reflection - -#endif /* GL_NV_texgen_reflection */ - -#ifdef GL_NV_texture_compression_vtc - -#endif /* GL_NV_texture_compression_vtc */ - -#ifdef GL_NV_texture_env_combine4 - -#endif /* GL_NV_texture_env_combine4 */ - -#ifdef GL_NV_texture_expand_normal - -#endif /* GL_NV_texture_expand_normal */ - -#ifdef GL_NV_texture_rectangle - -#endif /* GL_NV_texture_rectangle */ - -#ifdef GL_NV_texture_shader - -#endif /* GL_NV_texture_shader */ - -#ifdef GL_NV_texture_shader2 - -#endif /* GL_NV_texture_shader2 */ - -#ifdef GL_NV_texture_shader3 - -#endif /* GL_NV_texture_shader3 */ - -#ifdef GL_NV_transform_feedback - -static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r; - r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r; - r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r; - r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r; - r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r; - r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r; - r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r; - r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r; - r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r; - r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r; - r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_transform_feedback */ - -#ifdef GL_NV_vertex_array_range - -static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r; - r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_vertex_array_range */ - -#ifdef GL_NV_vertex_array_range2 - -#endif /* GL_NV_vertex_array_range2 */ - -#ifdef GL_NV_vertex_program - -static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r; - r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r; - r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r; - r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r; - r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r; - r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r; - r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r; - r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r; - r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r; - r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r; - r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r; - r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r; - r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r; - r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r; - r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r; - r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r; - r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r; - r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r; - r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r; - r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r; - r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r; - r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r; - r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r; - r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r; - r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r; - r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r; - r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r; - r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r; - r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r; - r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r; - r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r; - r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r; - r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r; - r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r; - r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r; - r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r; - r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r; - r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r; - r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r; - r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r; - r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r; - r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r; - r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r; - r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r; - r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r; - r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r; - r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r; - r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r; - r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r; - r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r; - r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r; - r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r; - r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r; - r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r; - r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r; - r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r; - r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r; - r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r; - r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r; - r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r; - r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r; - r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r; - r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r; - r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r; - - return r; -} - -#endif /* GL_NV_vertex_program */ - -#ifdef GL_NV_vertex_program1_1 - -#endif /* GL_NV_vertex_program1_1 */ - -#ifdef GL_NV_vertex_program2 - -#endif /* GL_NV_vertex_program2 */ - -#ifdef GL_NV_vertex_program2_option - -#endif /* GL_NV_vertex_program2_option */ - -#ifdef GL_NV_vertex_program3 - -#endif /* GL_NV_vertex_program3 */ - -#ifdef GL_NV_vertex_program4 - -#endif /* GL_NV_vertex_program4 */ - -#ifdef GL_OES_byte_coordinates - -#endif /* GL_OES_byte_coordinates */ - -#ifdef GL_OES_compressed_paletted_texture - -#endif /* GL_OES_compressed_paletted_texture */ - -#ifdef GL_OES_read_format - -#endif /* GL_OES_read_format */ - -#ifdef GL_OES_single_precision - -static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC)glewGetProcAddress((const GLubyte*)"glClearDepthfOES")) == NULL) || r; - r = ((glClipPlanefOES = (PFNGLCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glClipPlanefOES")) == NULL) || r; - r = ((glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC)glewGetProcAddress((const GLubyte*)"glDepthRangefOES")) == NULL) || r; - r = ((glFrustumfOES = (PFNGLFRUSTUMFOESPROC)glewGetProcAddress((const GLubyte*)"glFrustumfOES")) == NULL) || r; - r = ((glGetClipPlanefOES = (PFNGLGETCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanefOES")) == NULL) || r; - r = ((glOrthofOES = (PFNGLORTHOFOESPROC)glewGetProcAddress((const GLubyte*)"glOrthofOES")) == NULL) || r; - - return r; -} - -#endif /* GL_OES_single_precision */ - -#ifdef GL_OML_interlace - -#endif /* GL_OML_interlace */ - -#ifdef GL_OML_resample - -#endif /* GL_OML_resample */ - -#ifdef GL_OML_subsample - -#endif /* GL_OML_subsample */ - -#ifdef GL_PGI_misc_hints - -#endif /* GL_PGI_misc_hints */ - -#ifdef GL_PGI_vertex_hints - -#endif /* GL_PGI_vertex_hints */ - -#ifdef GL_REND_screen_coordinates - -#endif /* GL_REND_screen_coordinates */ - -#ifdef GL_S3_s3tc - -#endif /* GL_S3_s3tc */ - -#ifdef GL_SGIS_color_range - -#endif /* GL_SGIS_color_range */ - -#ifdef GL_SGIS_detail_texture - -static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r; - r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_detail_texture */ - -#ifdef GL_SGIS_fog_function - -static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r; - r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_fog_function */ - -#ifdef GL_SGIS_generate_mipmap - -#endif /* GL_SGIS_generate_mipmap */ - -#ifdef GL_SGIS_multisample - -static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r; - r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_multisample */ - -#ifdef GL_SGIS_pixel_texture - -#endif /* GL_SGIS_pixel_texture */ - -#ifdef GL_SGIS_point_line_texgen - -#endif /* GL_SGIS_point_line_texgen */ - -#ifdef GL_SGIS_sharpen_texture - -static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r; - r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_sharpen_texture */ - -#ifdef GL_SGIS_texture4D - -static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r; - r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_texture4D */ - -#ifdef GL_SGIS_texture_border_clamp - -#endif /* GL_SGIS_texture_border_clamp */ - -#ifdef GL_SGIS_texture_edge_clamp - -#endif /* GL_SGIS_texture_edge_clamp */ - -#ifdef GL_SGIS_texture_filter4 - -static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r; - r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIS_texture_filter4 */ - -#ifdef GL_SGIS_texture_lod - -#endif /* GL_SGIS_texture_lod */ - -#ifdef GL_SGIS_texture_select - -#endif /* GL_SGIS_texture_select */ - -#ifdef GL_SGIX_async - -static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r; - r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r; - r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r; - r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r; - r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r; - r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_async */ - -#ifdef GL_SGIX_async_histogram - -#endif /* GL_SGIX_async_histogram */ - -#ifdef GL_SGIX_async_pixel - -#endif /* GL_SGIX_async_pixel */ - -#ifdef GL_SGIX_blend_alpha_minmax - -#endif /* GL_SGIX_blend_alpha_minmax */ - -#ifdef GL_SGIX_clipmap - -#endif /* GL_SGIX_clipmap */ - -#ifdef GL_SGIX_convolution_accuracy - -#endif /* GL_SGIX_convolution_accuracy */ - -#ifdef GL_SGIX_depth_texture - -#endif /* GL_SGIX_depth_texture */ - -#ifdef GL_SGIX_flush_raster - -static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_flush_raster */ - -#ifdef GL_SGIX_fog_offset - -#endif /* GL_SGIX_fog_offset */ - -#ifdef GL_SGIX_fog_texture - -static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_fog_texture */ - -#ifdef GL_SGIX_fragment_specular_lighting - -static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r; - r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r; - r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r; - r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r; - r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r; - r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r; - r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r; - r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r; - r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r; - r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r; - r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r; - r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r; - r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r; - r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r; - r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r; - r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r; - r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_fragment_specular_lighting */ - -#ifdef GL_SGIX_framezoom - -static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_framezoom */ - -#ifdef GL_SGIX_interlace - -#endif /* GL_SGIX_interlace */ - -#ifdef GL_SGIX_ir_instrument1 - -#endif /* GL_SGIX_ir_instrument1 */ - -#ifdef GL_SGIX_list_priority - -#endif /* GL_SGIX_list_priority */ - -#ifdef GL_SGIX_pixel_texture - -static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_pixel_texture */ - -#ifdef GL_SGIX_pixel_texture_bits - -#endif /* GL_SGIX_pixel_texture_bits */ - -#ifdef GL_SGIX_reference_plane - -static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_reference_plane */ - -#ifdef GL_SGIX_resample - -#endif /* GL_SGIX_resample */ - -#ifdef GL_SGIX_shadow - -#endif /* GL_SGIX_shadow */ - -#ifdef GL_SGIX_shadow_ambient - -#endif /* GL_SGIX_shadow_ambient */ - -#ifdef GL_SGIX_sprite - -static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r; - r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r; - r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r; - r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_sprite */ - -#ifdef GL_SGIX_tag_sample_buffer - -static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r; - - return r; -} - -#endif /* GL_SGIX_tag_sample_buffer */ - -#ifdef GL_SGIX_texture_add_env - -#endif /* GL_SGIX_texture_add_env */ - -#ifdef GL_SGIX_texture_coordinate_clamp - -#endif /* GL_SGIX_texture_coordinate_clamp */ - -#ifdef GL_SGIX_texture_lod_bias - -#endif /* GL_SGIX_texture_lod_bias */ - -#ifdef GL_SGIX_texture_multi_buffer - -#endif /* GL_SGIX_texture_multi_buffer */ - -#ifdef GL_SGIX_texture_range - -#endif /* GL_SGIX_texture_range */ - -#ifdef GL_SGIX_texture_scale_bias - -#endif /* GL_SGIX_texture_scale_bias */ - -#ifdef GL_SGIX_vertex_preclip - -#endif /* GL_SGIX_vertex_preclip */ - -#ifdef GL_SGIX_vertex_preclip_hint - -#endif /* GL_SGIX_vertex_preclip_hint */ - -#ifdef GL_SGIX_ycrcb - -#endif /* GL_SGIX_ycrcb */ - -#ifdef GL_SGI_color_matrix - -#endif /* GL_SGI_color_matrix */ - -#ifdef GL_SGI_color_table - -static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r; - r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r; - r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r; - r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r; - r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r; - r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r; - r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r; - - return r; -} - -#endif /* GL_SGI_color_table */ - -#ifdef GL_SGI_texture_color_table - -#endif /* GL_SGI_texture_color_table */ - -#ifdef GL_SUNX_constant_data - -static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r; - - return r; -} - -#endif /* GL_SUNX_constant_data */ - -#ifdef GL_SUN_convolution_border_modes - -#endif /* GL_SUN_convolution_border_modes */ - -#ifdef GL_SUN_global_alpha - -static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r; - r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r; - r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r; - r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r; - r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r; - r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r; - r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r; - r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r; - - return r; -} - -#endif /* GL_SUN_global_alpha */ - -#ifdef GL_SUN_mesh_array - -#endif /* GL_SUN_mesh_array */ - -#ifdef GL_SUN_read_video_pixels - -static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r; - - return r; -} - -#endif /* GL_SUN_read_video_pixels */ - -#ifdef GL_SUN_slice_accum - -#endif /* GL_SUN_slice_accum */ - -#ifdef GL_SUN_triangle_list - -static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r; - r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r; - r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r; - r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r; - r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r; - r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r; - r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r; - - return r; -} - -#endif /* GL_SUN_triangle_list */ - -#ifdef GL_SUN_vertex - -static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r; - r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r; - r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r; - r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r; - r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r; - r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r; - r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r; - r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r; - r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r; - r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r; - r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r; - r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; - r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r; - r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r; - r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r; - r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r; - r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r; - r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r; - - return r; -} - -#endif /* GL_SUN_vertex */ - -#ifdef GL_WIN_phong_shading - -#endif /* GL_WIN_phong_shading */ - -#ifdef GL_WIN_specular_fog - -#endif /* GL_WIN_specular_fog */ - -#ifdef GL_WIN_swap_hint - -static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r; - - return r; -} - -#endif /* GL_WIN_swap_hint */ - -/* ------------------------------------------------------------------------- */ - -/* - * Search for name in the extensions string. Use of strstr() - * is not sufficient because extension names can be prefixes of - * other extension names. Could use strtok() but the constant - * string returned by glGetString might be in read-only memory. - */ -GLboolean glewGetExtension (const char* name) -{ - GLubyte* p; - GLubyte* end; - GLuint len = _glewStrLen((const GLubyte*)name); - p = (GLubyte*)glGetString(GL_EXTENSIONS); - if (0 == p) return GL_FALSE; - end = p + _glewStrLen(p); - while (p < end) - { - GLuint n = _glewStrCLen(p, ' '); - if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; - p += n+1; - } - return GL_FALSE; -} - -/* ------------------------------------------------------------------------- */ - -#ifndef GLEW_MX -static -#endif -GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) -{ - const GLubyte* s; - GLuint dot, major, minor; - /* query opengl version */ - s = glGetString(GL_VERSION); - dot = _glewStrCLen(s, '.'); - major = dot-1; - minor = dot+1; - if (dot == 0 || s[minor] == '\0') - return GLEW_ERROR_NO_GL_VERSION; - if (s[major] == '1' && s[minor] == '0') - { - return GLEW_ERROR_GL_VERSION_10_ONLY; - } - else - { - CONST_CAST(GLEW_VERSION_1_1) = GL_TRUE; - if (s[major] >= '2') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; - CONST_CAST(GLEW_VERSION_2_0) = GL_TRUE; - if (s[minor] >= '1') - { - CONST_CAST(GLEW_VERSION_2_1) = GL_TRUE; - } - } - else - { - if (s[minor] >= '5') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; - CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; - } - if (s[minor] == '4') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; - } - if (s[minor] == '3') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; - } - if (s[minor] == '2') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; - } - if (s[minor] < '2') - { - CONST_CAST(GLEW_VERSION_1_2) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; - CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; - CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; - } - } - } - /* initialize extensions */ -#ifdef GL_VERSION_1_2 - if (glewExperimental || GLEW_VERSION_1_2) CONST_CAST(GLEW_VERSION_1_2) = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_1_2 */ -#ifdef GL_VERSION_1_3 - if (glewExperimental || GLEW_VERSION_1_3) CONST_CAST(GLEW_VERSION_1_3) = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_1_3 */ -#ifdef GL_VERSION_1_4 - if (glewExperimental || GLEW_VERSION_1_4) CONST_CAST(GLEW_VERSION_1_4) = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_1_4 */ -#ifdef GL_VERSION_1_5 - if (glewExperimental || GLEW_VERSION_1_5) CONST_CAST(GLEW_VERSION_1_5) = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_1_5 */ -#ifdef GL_VERSION_2_0 - if (glewExperimental || GLEW_VERSION_2_0) CONST_CAST(GLEW_VERSION_2_0) = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_2_0 */ -#ifdef GL_VERSION_2_1 - if (glewExperimental || GLEW_VERSION_2_1) CONST_CAST(GLEW_VERSION_2_1) = !_glewInit_GL_VERSION_2_1(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_2_1 */ -#ifdef GL_VERSION_3_0 - if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_VERSION_3_0 */ -#ifdef GL_3DFX_multisample - CONST_CAST(GLEW_3DFX_multisample) = glewGetExtension("GL_3DFX_multisample"); -#endif /* GL_3DFX_multisample */ -#ifdef GL_3DFX_tbuffer - CONST_CAST(GLEW_3DFX_tbuffer) = glewGetExtension("GL_3DFX_tbuffer"); - if (glewExperimental || GLEW_3DFX_tbuffer) CONST_CAST(GLEW_3DFX_tbuffer) = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_3DFX_tbuffer */ -#ifdef GL_3DFX_texture_compression_FXT1 - CONST_CAST(GLEW_3DFX_texture_compression_FXT1) = glewGetExtension("GL_3DFX_texture_compression_FXT1"); -#endif /* GL_3DFX_texture_compression_FXT1 */ -#ifdef GL_APPLE_client_storage - CONST_CAST(GLEW_APPLE_client_storage) = glewGetExtension("GL_APPLE_client_storage"); -#endif /* GL_APPLE_client_storage */ -#ifdef GL_APPLE_element_array - CONST_CAST(GLEW_APPLE_element_array) = glewGetExtension("GL_APPLE_element_array"); - if (glewExperimental || GLEW_APPLE_element_array) CONST_CAST(GLEW_APPLE_element_array) = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_element_array */ -#ifdef GL_APPLE_fence - CONST_CAST(GLEW_APPLE_fence) = glewGetExtension("GL_APPLE_fence"); - if (glewExperimental || GLEW_APPLE_fence) CONST_CAST(GLEW_APPLE_fence) = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_fence */ -#ifdef GL_APPLE_float_pixels - CONST_CAST(GLEW_APPLE_float_pixels) = glewGetExtension("GL_APPLE_float_pixels"); -#endif /* GL_APPLE_float_pixels */ -#ifdef GL_APPLE_flush_buffer_range - CONST_CAST(GLEW_APPLE_flush_buffer_range) = glewGetExtension("GL_APPLE_flush_buffer_range"); - if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_flush_buffer_range */ -#ifdef GL_APPLE_pixel_buffer - CONST_CAST(GLEW_APPLE_pixel_buffer) = glewGetExtension("GL_APPLE_pixel_buffer"); -#endif /* GL_APPLE_pixel_buffer */ -#ifdef GL_APPLE_specular_vector - CONST_CAST(GLEW_APPLE_specular_vector) = glewGetExtension("GL_APPLE_specular_vector"); -#endif /* GL_APPLE_specular_vector */ -#ifdef GL_APPLE_texture_range - CONST_CAST(GLEW_APPLE_texture_range) = glewGetExtension("GL_APPLE_texture_range"); - if (glewExperimental || GLEW_APPLE_texture_range) CONST_CAST(GLEW_APPLE_texture_range) = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_texture_range */ -#ifdef GL_APPLE_transform_hint - CONST_CAST(GLEW_APPLE_transform_hint) = glewGetExtension("GL_APPLE_transform_hint"); -#endif /* GL_APPLE_transform_hint */ -#ifdef GL_APPLE_vertex_array_object - CONST_CAST(GLEW_APPLE_vertex_array_object) = glewGetExtension("GL_APPLE_vertex_array_object"); - if (glewExperimental || GLEW_APPLE_vertex_array_object) CONST_CAST(GLEW_APPLE_vertex_array_object) = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_vertex_array_object */ -#ifdef GL_APPLE_vertex_array_range - CONST_CAST(GLEW_APPLE_vertex_array_range) = glewGetExtension("GL_APPLE_vertex_array_range"); - if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_APPLE_vertex_array_range */ -#ifdef GL_APPLE_ycbcr_422 - CONST_CAST(GLEW_APPLE_ycbcr_422) = glewGetExtension("GL_APPLE_ycbcr_422"); -#endif /* GL_APPLE_ycbcr_422 */ -#ifdef GL_ARB_color_buffer_float - CONST_CAST(GLEW_ARB_color_buffer_float) = glewGetExtension("GL_ARB_color_buffer_float"); - if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_color_buffer_float */ -#ifdef GL_ARB_depth_buffer_float - CONST_CAST(GLEW_ARB_depth_buffer_float) = glewGetExtension("GL_ARB_depth_buffer_float"); -#endif /* GL_ARB_depth_buffer_float */ -#ifdef GL_ARB_depth_texture - CONST_CAST(GLEW_ARB_depth_texture) = glewGetExtension("GL_ARB_depth_texture"); -#endif /* GL_ARB_depth_texture */ -#ifdef GL_ARB_draw_buffers - CONST_CAST(GLEW_ARB_draw_buffers) = glewGetExtension("GL_ARB_draw_buffers"); - if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_draw_buffers */ -#ifdef GL_ARB_draw_instanced - CONST_CAST(GLEW_ARB_draw_instanced) = glewGetExtension("GL_ARB_draw_instanced"); - if (glewExperimental || GLEW_ARB_draw_instanced) CONST_CAST(GLEW_ARB_draw_instanced) = !_glewInit_GL_ARB_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_draw_instanced */ -#ifdef GL_ARB_fragment_program - CONST_CAST(GLEW_ARB_fragment_program) = glewGetExtension("GL_ARB_fragment_program"); -#endif /* GL_ARB_fragment_program */ -#ifdef GL_ARB_fragment_program_shadow - CONST_CAST(GLEW_ARB_fragment_program_shadow) = glewGetExtension("GL_ARB_fragment_program_shadow"); -#endif /* GL_ARB_fragment_program_shadow */ -#ifdef GL_ARB_fragment_shader - CONST_CAST(GLEW_ARB_fragment_shader) = glewGetExtension("GL_ARB_fragment_shader"); -#endif /* GL_ARB_fragment_shader */ -#ifdef GL_ARB_framebuffer_object - CONST_CAST(GLEW_ARB_framebuffer_object) = glewGetExtension("GL_ARB_framebuffer_object"); - if (glewExperimental || GLEW_ARB_framebuffer_object) CONST_CAST(GLEW_ARB_framebuffer_object) = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_framebuffer_object */ -#ifdef GL_ARB_framebuffer_sRGB - CONST_CAST(GLEW_ARB_framebuffer_sRGB) = glewGetExtension("GL_ARB_framebuffer_sRGB"); -#endif /* GL_ARB_framebuffer_sRGB */ -#ifdef GL_ARB_geometry_shader4 - CONST_CAST(GLEW_ARB_geometry_shader4) = glewGetExtension("GL_ARB_geometry_shader4"); - if (glewExperimental || GLEW_ARB_geometry_shader4) CONST_CAST(GLEW_ARB_geometry_shader4) = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_geometry_shader4 */ -#ifdef GL_ARB_half_float_pixel - CONST_CAST(GLEW_ARB_half_float_pixel) = glewGetExtension("GL_ARB_half_float_pixel"); -#endif /* GL_ARB_half_float_pixel */ -#ifdef GL_ARB_half_float_vertex - CONST_CAST(GLEW_ARB_half_float_vertex) = glewGetExtension("GL_ARB_half_float_vertex"); -#endif /* GL_ARB_half_float_vertex */ -#ifdef GL_ARB_imaging - CONST_CAST(GLEW_ARB_imaging) = glewGetExtension("GL_ARB_imaging"); - if (glewExperimental || GLEW_ARB_imaging) CONST_CAST(GLEW_ARB_imaging) = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_imaging */ -#ifdef GL_ARB_instanced_arrays - CONST_CAST(GLEW_ARB_instanced_arrays) = glewGetExtension("GL_ARB_instanced_arrays"); - if (glewExperimental || GLEW_ARB_instanced_arrays) CONST_CAST(GLEW_ARB_instanced_arrays) = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_instanced_arrays */ -#ifdef GL_ARB_map_buffer_range - CONST_CAST(GLEW_ARB_map_buffer_range) = glewGetExtension("GL_ARB_map_buffer_range"); - if (glewExperimental || GLEW_ARB_map_buffer_range) CONST_CAST(GLEW_ARB_map_buffer_range) = !_glewInit_GL_ARB_map_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_map_buffer_range */ -#ifdef GL_ARB_matrix_palette - CONST_CAST(GLEW_ARB_matrix_palette) = glewGetExtension("GL_ARB_matrix_palette"); - if (glewExperimental || GLEW_ARB_matrix_palette) CONST_CAST(GLEW_ARB_matrix_palette) = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_matrix_palette */ -#ifdef GL_ARB_multisample - CONST_CAST(GLEW_ARB_multisample) = glewGetExtension("GL_ARB_multisample"); - if (glewExperimental || GLEW_ARB_multisample) CONST_CAST(GLEW_ARB_multisample) = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_multisample */ -#ifdef GL_ARB_multitexture - CONST_CAST(GLEW_ARB_multitexture) = glewGetExtension("GL_ARB_multitexture"); - if (glewExperimental || GLEW_ARB_multitexture) CONST_CAST(GLEW_ARB_multitexture) = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_multitexture */ -#ifdef GL_ARB_occlusion_query - CONST_CAST(GLEW_ARB_occlusion_query) = glewGetExtension("GL_ARB_occlusion_query"); - if (glewExperimental || GLEW_ARB_occlusion_query) CONST_CAST(GLEW_ARB_occlusion_query) = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_occlusion_query */ -#ifdef GL_ARB_pixel_buffer_object - CONST_CAST(GLEW_ARB_pixel_buffer_object) = glewGetExtension("GL_ARB_pixel_buffer_object"); -#endif /* GL_ARB_pixel_buffer_object */ -#ifdef GL_ARB_point_parameters - CONST_CAST(GLEW_ARB_point_parameters) = glewGetExtension("GL_ARB_point_parameters"); - if (glewExperimental || GLEW_ARB_point_parameters) CONST_CAST(GLEW_ARB_point_parameters) = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_point_parameters */ -#ifdef GL_ARB_point_sprite - CONST_CAST(GLEW_ARB_point_sprite) = glewGetExtension("GL_ARB_point_sprite"); -#endif /* GL_ARB_point_sprite */ -#ifdef GL_ARB_shader_objects - CONST_CAST(GLEW_ARB_shader_objects) = glewGetExtension("GL_ARB_shader_objects"); - if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_shader_objects */ -#ifdef GL_ARB_shading_language_100 - CONST_CAST(GLEW_ARB_shading_language_100) = glewGetExtension("GL_ARB_shading_language_100"); -#endif /* GL_ARB_shading_language_100 */ -#ifdef GL_ARB_shadow - CONST_CAST(GLEW_ARB_shadow) = glewGetExtension("GL_ARB_shadow"); -#endif /* GL_ARB_shadow */ -#ifdef GL_ARB_shadow_ambient - CONST_CAST(GLEW_ARB_shadow_ambient) = glewGetExtension("GL_ARB_shadow_ambient"); -#endif /* GL_ARB_shadow_ambient */ -#ifdef GL_ARB_texture_border_clamp - CONST_CAST(GLEW_ARB_texture_border_clamp) = glewGetExtension("GL_ARB_texture_border_clamp"); -#endif /* GL_ARB_texture_border_clamp */ -#ifdef GL_ARB_texture_buffer_object - CONST_CAST(GLEW_ARB_texture_buffer_object) = glewGetExtension("GL_ARB_texture_buffer_object"); - if (glewExperimental || GLEW_ARB_texture_buffer_object) CONST_CAST(GLEW_ARB_texture_buffer_object) = !_glewInit_GL_ARB_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_texture_buffer_object */ -#ifdef GL_ARB_texture_compression - CONST_CAST(GLEW_ARB_texture_compression) = glewGetExtension("GL_ARB_texture_compression"); - if (glewExperimental || GLEW_ARB_texture_compression) CONST_CAST(GLEW_ARB_texture_compression) = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_texture_compression */ -#ifdef GL_ARB_texture_compression_rgtc - CONST_CAST(GLEW_ARB_texture_compression_rgtc) = glewGetExtension("GL_ARB_texture_compression_rgtc"); -#endif /* GL_ARB_texture_compression_rgtc */ -#ifdef GL_ARB_texture_cube_map - CONST_CAST(GLEW_ARB_texture_cube_map) = glewGetExtension("GL_ARB_texture_cube_map"); -#endif /* GL_ARB_texture_cube_map */ -#ifdef GL_ARB_texture_env_add - CONST_CAST(GLEW_ARB_texture_env_add) = glewGetExtension("GL_ARB_texture_env_add"); -#endif /* GL_ARB_texture_env_add */ -#ifdef GL_ARB_texture_env_combine - CONST_CAST(GLEW_ARB_texture_env_combine) = glewGetExtension("GL_ARB_texture_env_combine"); -#endif /* GL_ARB_texture_env_combine */ -#ifdef GL_ARB_texture_env_crossbar - CONST_CAST(GLEW_ARB_texture_env_crossbar) = glewGetExtension("GL_ARB_texture_env_crossbar"); -#endif /* GL_ARB_texture_env_crossbar */ -#ifdef GL_ARB_texture_env_dot3 - CONST_CAST(GLEW_ARB_texture_env_dot3) = glewGetExtension("GL_ARB_texture_env_dot3"); -#endif /* GL_ARB_texture_env_dot3 */ -#ifdef GL_ARB_texture_float - CONST_CAST(GLEW_ARB_texture_float) = glewGetExtension("GL_ARB_texture_float"); -#endif /* GL_ARB_texture_float */ -#ifdef GL_ARB_texture_mirrored_repeat - CONST_CAST(GLEW_ARB_texture_mirrored_repeat) = glewGetExtension("GL_ARB_texture_mirrored_repeat"); -#endif /* GL_ARB_texture_mirrored_repeat */ -#ifdef GL_ARB_texture_non_power_of_two - CONST_CAST(GLEW_ARB_texture_non_power_of_two) = glewGetExtension("GL_ARB_texture_non_power_of_two"); -#endif /* GL_ARB_texture_non_power_of_two */ -#ifdef GL_ARB_texture_rectangle - CONST_CAST(GLEW_ARB_texture_rectangle) = glewGetExtension("GL_ARB_texture_rectangle"); -#endif /* GL_ARB_texture_rectangle */ -#ifdef GL_ARB_texture_rg - CONST_CAST(GLEW_ARB_texture_rg) = glewGetExtension("GL_ARB_texture_rg"); -#endif /* GL_ARB_texture_rg */ -#ifdef GL_ARB_transpose_matrix - CONST_CAST(GLEW_ARB_transpose_matrix) = glewGetExtension("GL_ARB_transpose_matrix"); - if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_transpose_matrix */ -#ifdef GL_ARB_vertex_array_object - CONST_CAST(GLEW_ARB_vertex_array_object) = glewGetExtension("GL_ARB_vertex_array_object"); - if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_vertex_array_object */ -#ifdef GL_ARB_vertex_blend - CONST_CAST(GLEW_ARB_vertex_blend) = glewGetExtension("GL_ARB_vertex_blend"); - if (glewExperimental || GLEW_ARB_vertex_blend) CONST_CAST(GLEW_ARB_vertex_blend) = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_vertex_blend */ -#ifdef GL_ARB_vertex_buffer_object - CONST_CAST(GLEW_ARB_vertex_buffer_object) = glewGetExtension("GL_ARB_vertex_buffer_object"); - if (glewExperimental || GLEW_ARB_vertex_buffer_object) CONST_CAST(GLEW_ARB_vertex_buffer_object) = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_vertex_buffer_object */ -#ifdef GL_ARB_vertex_program - CONST_CAST(GLEW_ARB_vertex_program) = glewGetExtension("GL_ARB_vertex_program"); - if (glewExperimental || GLEW_ARB_vertex_program) CONST_CAST(GLEW_ARB_vertex_program) = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_vertex_program */ -#ifdef GL_ARB_vertex_shader - CONST_CAST(GLEW_ARB_vertex_shader) = glewGetExtension("GL_ARB_vertex_shader"); - if (glewExperimental || GLEW_ARB_vertex_shader) CONST_CAST(GLEW_ARB_vertex_shader) = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_vertex_shader */ -#ifdef GL_ARB_window_pos - CONST_CAST(GLEW_ARB_window_pos) = glewGetExtension("GL_ARB_window_pos"); - if (glewExperimental || GLEW_ARB_window_pos) CONST_CAST(GLEW_ARB_window_pos) = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_window_pos */ -#ifdef GL_ATIX_point_sprites - CONST_CAST(GLEW_ATIX_point_sprites) = glewGetExtension("GL_ATIX_point_sprites"); -#endif /* GL_ATIX_point_sprites */ -#ifdef GL_ATIX_texture_env_combine3 - CONST_CAST(GLEW_ATIX_texture_env_combine3) = glewGetExtension("GL_ATIX_texture_env_combine3"); -#endif /* GL_ATIX_texture_env_combine3 */ -#ifdef GL_ATIX_texture_env_route - CONST_CAST(GLEW_ATIX_texture_env_route) = glewGetExtension("GL_ATIX_texture_env_route"); -#endif /* GL_ATIX_texture_env_route */ -#ifdef GL_ATIX_vertex_shader_output_point_size - CONST_CAST(GLEW_ATIX_vertex_shader_output_point_size) = glewGetExtension("GL_ATIX_vertex_shader_output_point_size"); -#endif /* GL_ATIX_vertex_shader_output_point_size */ -#ifdef GL_ATI_draw_buffers - CONST_CAST(GLEW_ATI_draw_buffers) = glewGetExtension("GL_ATI_draw_buffers"); - if (glewExperimental || GLEW_ATI_draw_buffers) CONST_CAST(GLEW_ATI_draw_buffers) = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_draw_buffers */ -#ifdef GL_ATI_element_array - CONST_CAST(GLEW_ATI_element_array) = glewGetExtension("GL_ATI_element_array"); - if (glewExperimental || GLEW_ATI_element_array) CONST_CAST(GLEW_ATI_element_array) = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_element_array */ -#ifdef GL_ATI_envmap_bumpmap - CONST_CAST(GLEW_ATI_envmap_bumpmap) = glewGetExtension("GL_ATI_envmap_bumpmap"); - if (glewExperimental || GLEW_ATI_envmap_bumpmap) CONST_CAST(GLEW_ATI_envmap_bumpmap) = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_envmap_bumpmap */ -#ifdef GL_ATI_fragment_shader - CONST_CAST(GLEW_ATI_fragment_shader) = glewGetExtension("GL_ATI_fragment_shader"); - if (glewExperimental || GLEW_ATI_fragment_shader) CONST_CAST(GLEW_ATI_fragment_shader) = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_fragment_shader */ -#ifdef GL_ATI_map_object_buffer - CONST_CAST(GLEW_ATI_map_object_buffer) = glewGetExtension("GL_ATI_map_object_buffer"); - if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_map_object_buffer */ -#ifdef GL_ATI_pn_triangles - CONST_CAST(GLEW_ATI_pn_triangles) = glewGetExtension("GL_ATI_pn_triangles"); - if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_pn_triangles */ -#ifdef GL_ATI_separate_stencil - CONST_CAST(GLEW_ATI_separate_stencil) = glewGetExtension("GL_ATI_separate_stencil"); - if (glewExperimental || GLEW_ATI_separate_stencil) CONST_CAST(GLEW_ATI_separate_stencil) = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_separate_stencil */ -#ifdef GL_ATI_shader_texture_lod - CONST_CAST(GLEW_ATI_shader_texture_lod) = glewGetExtension("GL_ATI_shader_texture_lod"); -#endif /* GL_ATI_shader_texture_lod */ -#ifdef GL_ATI_text_fragment_shader - CONST_CAST(GLEW_ATI_text_fragment_shader) = glewGetExtension("GL_ATI_text_fragment_shader"); -#endif /* GL_ATI_text_fragment_shader */ -#ifdef GL_ATI_texture_compression_3dc - CONST_CAST(GLEW_ATI_texture_compression_3dc) = glewGetExtension("GL_ATI_texture_compression_3dc"); -#endif /* GL_ATI_texture_compression_3dc */ -#ifdef GL_ATI_texture_env_combine3 - CONST_CAST(GLEW_ATI_texture_env_combine3) = glewGetExtension("GL_ATI_texture_env_combine3"); -#endif /* GL_ATI_texture_env_combine3 */ -#ifdef GL_ATI_texture_float - CONST_CAST(GLEW_ATI_texture_float) = glewGetExtension("GL_ATI_texture_float"); -#endif /* GL_ATI_texture_float */ -#ifdef GL_ATI_texture_mirror_once - CONST_CAST(GLEW_ATI_texture_mirror_once) = glewGetExtension("GL_ATI_texture_mirror_once"); -#endif /* GL_ATI_texture_mirror_once */ -#ifdef GL_ATI_vertex_array_object - CONST_CAST(GLEW_ATI_vertex_array_object) = glewGetExtension("GL_ATI_vertex_array_object"); - if (glewExperimental || GLEW_ATI_vertex_array_object) CONST_CAST(GLEW_ATI_vertex_array_object) = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_vertex_array_object */ -#ifdef GL_ATI_vertex_attrib_array_object - CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = glewGetExtension("GL_ATI_vertex_attrib_array_object"); - if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_vertex_attrib_array_object */ -#ifdef GL_ATI_vertex_streams - CONST_CAST(GLEW_ATI_vertex_streams) = glewGetExtension("GL_ATI_vertex_streams"); - if (glewExperimental || GLEW_ATI_vertex_streams) CONST_CAST(GLEW_ATI_vertex_streams) = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ATI_vertex_streams */ -#ifdef GL_EXT_422_pixels - CONST_CAST(GLEW_EXT_422_pixels) = glewGetExtension("GL_EXT_422_pixels"); -#endif /* GL_EXT_422_pixels */ -#ifdef GL_EXT_Cg_shader - CONST_CAST(GLEW_EXT_Cg_shader) = glewGetExtension("GL_EXT_Cg_shader"); -#endif /* GL_EXT_Cg_shader */ -#ifdef GL_EXT_abgr - CONST_CAST(GLEW_EXT_abgr) = glewGetExtension("GL_EXT_abgr"); -#endif /* GL_EXT_abgr */ -#ifdef GL_EXT_bgra - CONST_CAST(GLEW_EXT_bgra) = glewGetExtension("GL_EXT_bgra"); -#endif /* GL_EXT_bgra */ -#ifdef GL_EXT_bindable_uniform - CONST_CAST(GLEW_EXT_bindable_uniform) = glewGetExtension("GL_EXT_bindable_uniform"); - if (glewExperimental || GLEW_EXT_bindable_uniform) CONST_CAST(GLEW_EXT_bindable_uniform) = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_bindable_uniform */ -#ifdef GL_EXT_blend_color - CONST_CAST(GLEW_EXT_blend_color) = glewGetExtension("GL_EXT_blend_color"); - if (glewExperimental || GLEW_EXT_blend_color) CONST_CAST(GLEW_EXT_blend_color) = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_blend_color */ -#ifdef GL_EXT_blend_equation_separate - CONST_CAST(GLEW_EXT_blend_equation_separate) = glewGetExtension("GL_EXT_blend_equation_separate"); - if (glewExperimental || GLEW_EXT_blend_equation_separate) CONST_CAST(GLEW_EXT_blend_equation_separate) = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_blend_equation_separate */ -#ifdef GL_EXT_blend_func_separate - CONST_CAST(GLEW_EXT_blend_func_separate) = glewGetExtension("GL_EXT_blend_func_separate"); - if (glewExperimental || GLEW_EXT_blend_func_separate) CONST_CAST(GLEW_EXT_blend_func_separate) = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_blend_func_separate */ -#ifdef GL_EXT_blend_logic_op - CONST_CAST(GLEW_EXT_blend_logic_op) = glewGetExtension("GL_EXT_blend_logic_op"); -#endif /* GL_EXT_blend_logic_op */ -#ifdef GL_EXT_blend_minmax - CONST_CAST(GLEW_EXT_blend_minmax) = glewGetExtension("GL_EXT_blend_minmax"); - if (glewExperimental || GLEW_EXT_blend_minmax) CONST_CAST(GLEW_EXT_blend_minmax) = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_blend_minmax */ -#ifdef GL_EXT_blend_subtract - CONST_CAST(GLEW_EXT_blend_subtract) = glewGetExtension("GL_EXT_blend_subtract"); -#endif /* GL_EXT_blend_subtract */ -#ifdef GL_EXT_clip_volume_hint - CONST_CAST(GLEW_EXT_clip_volume_hint) = glewGetExtension("GL_EXT_clip_volume_hint"); -#endif /* GL_EXT_clip_volume_hint */ -#ifdef GL_EXT_cmyka - CONST_CAST(GLEW_EXT_cmyka) = glewGetExtension("GL_EXT_cmyka"); -#endif /* GL_EXT_cmyka */ -#ifdef GL_EXT_color_subtable - CONST_CAST(GLEW_EXT_color_subtable) = glewGetExtension("GL_EXT_color_subtable"); - if (glewExperimental || GLEW_EXT_color_subtable) CONST_CAST(GLEW_EXT_color_subtable) = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_color_subtable */ -#ifdef GL_EXT_compiled_vertex_array - CONST_CAST(GLEW_EXT_compiled_vertex_array) = glewGetExtension("GL_EXT_compiled_vertex_array"); - if (glewExperimental || GLEW_EXT_compiled_vertex_array) CONST_CAST(GLEW_EXT_compiled_vertex_array) = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_compiled_vertex_array */ -#ifdef GL_EXT_convolution - CONST_CAST(GLEW_EXT_convolution) = glewGetExtension("GL_EXT_convolution"); - if (glewExperimental || GLEW_EXT_convolution) CONST_CAST(GLEW_EXT_convolution) = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_convolution */ -#ifdef GL_EXT_coordinate_frame - CONST_CAST(GLEW_EXT_coordinate_frame) = glewGetExtension("GL_EXT_coordinate_frame"); - if (glewExperimental || GLEW_EXT_coordinate_frame) CONST_CAST(GLEW_EXT_coordinate_frame) = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_coordinate_frame */ -#ifdef GL_EXT_copy_texture - CONST_CAST(GLEW_EXT_copy_texture) = glewGetExtension("GL_EXT_copy_texture"); - if (glewExperimental || GLEW_EXT_copy_texture) CONST_CAST(GLEW_EXT_copy_texture) = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_copy_texture */ -#ifdef GL_EXT_cull_vertex - CONST_CAST(GLEW_EXT_cull_vertex) = glewGetExtension("GL_EXT_cull_vertex"); - if (glewExperimental || GLEW_EXT_cull_vertex) CONST_CAST(GLEW_EXT_cull_vertex) = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_cull_vertex */ -#ifdef GL_EXT_depth_bounds_test - CONST_CAST(GLEW_EXT_depth_bounds_test) = glewGetExtension("GL_EXT_depth_bounds_test"); - if (glewExperimental || GLEW_EXT_depth_bounds_test) CONST_CAST(GLEW_EXT_depth_bounds_test) = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_depth_bounds_test */ -#ifdef GL_EXT_direct_state_access - CONST_CAST(GLEW_EXT_direct_state_access) = glewGetExtension("GL_EXT_direct_state_access"); - if (glewExperimental || GLEW_EXT_direct_state_access) CONST_CAST(GLEW_EXT_direct_state_access) = !_glewInit_GL_EXT_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_direct_state_access */ -#ifdef GL_EXT_draw_buffers2 - CONST_CAST(GLEW_EXT_draw_buffers2) = glewGetExtension("GL_EXT_draw_buffers2"); - if (glewExperimental || GLEW_EXT_draw_buffers2) CONST_CAST(GLEW_EXT_draw_buffers2) = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_draw_buffers2 */ -#ifdef GL_EXT_draw_instanced - CONST_CAST(GLEW_EXT_draw_instanced) = glewGetExtension("GL_EXT_draw_instanced"); - if (glewExperimental || GLEW_EXT_draw_instanced) CONST_CAST(GLEW_EXT_draw_instanced) = !_glewInit_GL_EXT_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_draw_instanced */ -#ifdef GL_EXT_draw_range_elements - CONST_CAST(GLEW_EXT_draw_range_elements) = glewGetExtension("GL_EXT_draw_range_elements"); - if (glewExperimental || GLEW_EXT_draw_range_elements) CONST_CAST(GLEW_EXT_draw_range_elements) = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_draw_range_elements */ -#ifdef GL_EXT_fog_coord - CONST_CAST(GLEW_EXT_fog_coord) = glewGetExtension("GL_EXT_fog_coord"); - if (glewExperimental || GLEW_EXT_fog_coord) CONST_CAST(GLEW_EXT_fog_coord) = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_fog_coord */ -#ifdef GL_EXT_fragment_lighting - CONST_CAST(GLEW_EXT_fragment_lighting) = glewGetExtension("GL_EXT_fragment_lighting"); - if (glewExperimental || GLEW_EXT_fragment_lighting) CONST_CAST(GLEW_EXT_fragment_lighting) = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_fragment_lighting */ -#ifdef GL_EXT_framebuffer_blit - CONST_CAST(GLEW_EXT_framebuffer_blit) = glewGetExtension("GL_EXT_framebuffer_blit"); - if (glewExperimental || GLEW_EXT_framebuffer_blit) CONST_CAST(GLEW_EXT_framebuffer_blit) = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_framebuffer_blit */ -#ifdef GL_EXT_framebuffer_multisample - CONST_CAST(GLEW_EXT_framebuffer_multisample) = glewGetExtension("GL_EXT_framebuffer_multisample"); - if (glewExperimental || GLEW_EXT_framebuffer_multisample) CONST_CAST(GLEW_EXT_framebuffer_multisample) = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_framebuffer_multisample */ -#ifdef GL_EXT_framebuffer_object - CONST_CAST(GLEW_EXT_framebuffer_object) = glewGetExtension("GL_EXT_framebuffer_object"); - if (glewExperimental || GLEW_EXT_framebuffer_object) CONST_CAST(GLEW_EXT_framebuffer_object) = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_framebuffer_object */ -#ifdef GL_EXT_framebuffer_sRGB - CONST_CAST(GLEW_EXT_framebuffer_sRGB) = glewGetExtension("GL_EXT_framebuffer_sRGB"); -#endif /* GL_EXT_framebuffer_sRGB */ -#ifdef GL_EXT_geometry_shader4 - CONST_CAST(GLEW_EXT_geometry_shader4) = glewGetExtension("GL_EXT_geometry_shader4"); - if (glewExperimental || GLEW_EXT_geometry_shader4) CONST_CAST(GLEW_EXT_geometry_shader4) = !_glewInit_GL_EXT_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_geometry_shader4 */ -#ifdef GL_EXT_gpu_program_parameters - CONST_CAST(GLEW_EXT_gpu_program_parameters) = glewGetExtension("GL_EXT_gpu_program_parameters"); - if (glewExperimental || GLEW_EXT_gpu_program_parameters) CONST_CAST(GLEW_EXT_gpu_program_parameters) = !_glewInit_GL_EXT_gpu_program_parameters(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_gpu_program_parameters */ -#ifdef GL_EXT_gpu_shader4 - CONST_CAST(GLEW_EXT_gpu_shader4) = glewGetExtension("GL_EXT_gpu_shader4"); - if (glewExperimental || GLEW_EXT_gpu_shader4) CONST_CAST(GLEW_EXT_gpu_shader4) = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_gpu_shader4 */ -#ifdef GL_EXT_histogram - CONST_CAST(GLEW_EXT_histogram) = glewGetExtension("GL_EXT_histogram"); - if (glewExperimental || GLEW_EXT_histogram) CONST_CAST(GLEW_EXT_histogram) = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_histogram */ -#ifdef GL_EXT_index_array_formats - CONST_CAST(GLEW_EXT_index_array_formats) = glewGetExtension("GL_EXT_index_array_formats"); -#endif /* GL_EXT_index_array_formats */ -#ifdef GL_EXT_index_func - CONST_CAST(GLEW_EXT_index_func) = glewGetExtension("GL_EXT_index_func"); - if (glewExperimental || GLEW_EXT_index_func) CONST_CAST(GLEW_EXT_index_func) = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_index_func */ -#ifdef GL_EXT_index_material - CONST_CAST(GLEW_EXT_index_material) = glewGetExtension("GL_EXT_index_material"); - if (glewExperimental || GLEW_EXT_index_material) CONST_CAST(GLEW_EXT_index_material) = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_index_material */ -#ifdef GL_EXT_index_texture - CONST_CAST(GLEW_EXT_index_texture) = glewGetExtension("GL_EXT_index_texture"); -#endif /* GL_EXT_index_texture */ -#ifdef GL_EXT_light_texture - CONST_CAST(GLEW_EXT_light_texture) = glewGetExtension("GL_EXT_light_texture"); - if (glewExperimental || GLEW_EXT_light_texture) CONST_CAST(GLEW_EXT_light_texture) = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_light_texture */ -#ifdef GL_EXT_misc_attribute - CONST_CAST(GLEW_EXT_misc_attribute) = glewGetExtension("GL_EXT_misc_attribute"); -#endif /* GL_EXT_misc_attribute */ -#ifdef GL_EXT_multi_draw_arrays - CONST_CAST(GLEW_EXT_multi_draw_arrays) = glewGetExtension("GL_EXT_multi_draw_arrays"); - if (glewExperimental || GLEW_EXT_multi_draw_arrays) CONST_CAST(GLEW_EXT_multi_draw_arrays) = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_multi_draw_arrays */ -#ifdef GL_EXT_multisample - CONST_CAST(GLEW_EXT_multisample) = glewGetExtension("GL_EXT_multisample"); - if (glewExperimental || GLEW_EXT_multisample) CONST_CAST(GLEW_EXT_multisample) = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_multisample */ -#ifdef GL_EXT_packed_depth_stencil - CONST_CAST(GLEW_EXT_packed_depth_stencil) = glewGetExtension("GL_EXT_packed_depth_stencil"); -#endif /* GL_EXT_packed_depth_stencil */ -#ifdef GL_EXT_packed_float - CONST_CAST(GLEW_EXT_packed_float) = glewGetExtension("GL_EXT_packed_float"); -#endif /* GL_EXT_packed_float */ -#ifdef GL_EXT_packed_pixels - CONST_CAST(GLEW_EXT_packed_pixels) = glewGetExtension("GL_EXT_packed_pixels"); -#endif /* GL_EXT_packed_pixels */ -#ifdef GL_EXT_paletted_texture - CONST_CAST(GLEW_EXT_paletted_texture) = glewGetExtension("GL_EXT_paletted_texture"); - if (glewExperimental || GLEW_EXT_paletted_texture) CONST_CAST(GLEW_EXT_paletted_texture) = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_paletted_texture */ -#ifdef GL_EXT_pixel_buffer_object - CONST_CAST(GLEW_EXT_pixel_buffer_object) = glewGetExtension("GL_EXT_pixel_buffer_object"); -#endif /* GL_EXT_pixel_buffer_object */ -#ifdef GL_EXT_pixel_transform - CONST_CAST(GLEW_EXT_pixel_transform) = glewGetExtension("GL_EXT_pixel_transform"); - if (glewExperimental || GLEW_EXT_pixel_transform) CONST_CAST(GLEW_EXT_pixel_transform) = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_pixel_transform */ -#ifdef GL_EXT_pixel_transform_color_table - CONST_CAST(GLEW_EXT_pixel_transform_color_table) = glewGetExtension("GL_EXT_pixel_transform_color_table"); -#endif /* GL_EXT_pixel_transform_color_table */ -#ifdef GL_EXT_point_parameters - CONST_CAST(GLEW_EXT_point_parameters) = glewGetExtension("GL_EXT_point_parameters"); - if (glewExperimental || GLEW_EXT_point_parameters) CONST_CAST(GLEW_EXT_point_parameters) = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_point_parameters */ -#ifdef GL_EXT_polygon_offset - CONST_CAST(GLEW_EXT_polygon_offset) = glewGetExtension("GL_EXT_polygon_offset"); - if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_polygon_offset */ -#ifdef GL_EXT_rescale_normal - CONST_CAST(GLEW_EXT_rescale_normal) = glewGetExtension("GL_EXT_rescale_normal"); -#endif /* GL_EXT_rescale_normal */ -#ifdef GL_EXT_scene_marker - CONST_CAST(GLEW_EXT_scene_marker) = glewGetExtension("GL_EXT_scene_marker"); - if (glewExperimental || GLEW_EXT_scene_marker) CONST_CAST(GLEW_EXT_scene_marker) = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_scene_marker */ -#ifdef GL_EXT_secondary_color - CONST_CAST(GLEW_EXT_secondary_color) = glewGetExtension("GL_EXT_secondary_color"); - if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_secondary_color */ -#ifdef GL_EXT_separate_specular_color - CONST_CAST(GLEW_EXT_separate_specular_color) = glewGetExtension("GL_EXT_separate_specular_color"); -#endif /* GL_EXT_separate_specular_color */ -#ifdef GL_EXT_shadow_funcs - CONST_CAST(GLEW_EXT_shadow_funcs) = glewGetExtension("GL_EXT_shadow_funcs"); -#endif /* GL_EXT_shadow_funcs */ -#ifdef GL_EXT_shared_texture_palette - CONST_CAST(GLEW_EXT_shared_texture_palette) = glewGetExtension("GL_EXT_shared_texture_palette"); -#endif /* GL_EXT_shared_texture_palette */ -#ifdef GL_EXT_stencil_clear_tag - CONST_CAST(GLEW_EXT_stencil_clear_tag) = glewGetExtension("GL_EXT_stencil_clear_tag"); -#endif /* GL_EXT_stencil_clear_tag */ -#ifdef GL_EXT_stencil_two_side - CONST_CAST(GLEW_EXT_stencil_two_side) = glewGetExtension("GL_EXT_stencil_two_side"); - if (glewExperimental || GLEW_EXT_stencil_two_side) CONST_CAST(GLEW_EXT_stencil_two_side) = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_stencil_two_side */ -#ifdef GL_EXT_stencil_wrap - CONST_CAST(GLEW_EXT_stencil_wrap) = glewGetExtension("GL_EXT_stencil_wrap"); -#endif /* GL_EXT_stencil_wrap */ -#ifdef GL_EXT_subtexture - CONST_CAST(GLEW_EXT_subtexture) = glewGetExtension("GL_EXT_subtexture"); - if (glewExperimental || GLEW_EXT_subtexture) CONST_CAST(GLEW_EXT_subtexture) = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_subtexture */ -#ifdef GL_EXT_texture - CONST_CAST(GLEW_EXT_texture) = glewGetExtension("GL_EXT_texture"); -#endif /* GL_EXT_texture */ -#ifdef GL_EXT_texture3D - CONST_CAST(GLEW_EXT_texture3D) = glewGetExtension("GL_EXT_texture3D"); - if (glewExperimental || GLEW_EXT_texture3D) CONST_CAST(GLEW_EXT_texture3D) = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_texture3D */ -#ifdef GL_EXT_texture_array - CONST_CAST(GLEW_EXT_texture_array) = glewGetExtension("GL_EXT_texture_array"); -#endif /* GL_EXT_texture_array */ -#ifdef GL_EXT_texture_buffer_object - CONST_CAST(GLEW_EXT_texture_buffer_object) = glewGetExtension("GL_EXT_texture_buffer_object"); - if (glewExperimental || GLEW_EXT_texture_buffer_object) CONST_CAST(GLEW_EXT_texture_buffer_object) = !_glewInit_GL_EXT_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_texture_buffer_object */ -#ifdef GL_EXT_texture_compression_dxt1 - CONST_CAST(GLEW_EXT_texture_compression_dxt1) = glewGetExtension("GL_EXT_texture_compression_dxt1"); -#endif /* GL_EXT_texture_compression_dxt1 */ -#ifdef GL_EXT_texture_compression_latc - CONST_CAST(GLEW_EXT_texture_compression_latc) = glewGetExtension("GL_EXT_texture_compression_latc"); -#endif /* GL_EXT_texture_compression_latc */ -#ifdef GL_EXT_texture_compression_rgtc - CONST_CAST(GLEW_EXT_texture_compression_rgtc) = glewGetExtension("GL_EXT_texture_compression_rgtc"); -#endif /* GL_EXT_texture_compression_rgtc */ -#ifdef GL_EXT_texture_compression_s3tc - CONST_CAST(GLEW_EXT_texture_compression_s3tc) = glewGetExtension("GL_EXT_texture_compression_s3tc"); -#endif /* GL_EXT_texture_compression_s3tc */ -#ifdef GL_EXT_texture_cube_map - CONST_CAST(GLEW_EXT_texture_cube_map) = glewGetExtension("GL_EXT_texture_cube_map"); -#endif /* GL_EXT_texture_cube_map */ -#ifdef GL_EXT_texture_edge_clamp - CONST_CAST(GLEW_EXT_texture_edge_clamp) = glewGetExtension("GL_EXT_texture_edge_clamp"); -#endif /* GL_EXT_texture_edge_clamp */ -#ifdef GL_EXT_texture_env - CONST_CAST(GLEW_EXT_texture_env) = glewGetExtension("GL_EXT_texture_env"); -#endif /* GL_EXT_texture_env */ -#ifdef GL_EXT_texture_env_add - CONST_CAST(GLEW_EXT_texture_env_add) = glewGetExtension("GL_EXT_texture_env_add"); -#endif /* GL_EXT_texture_env_add */ -#ifdef GL_EXT_texture_env_combine - CONST_CAST(GLEW_EXT_texture_env_combine) = glewGetExtension("GL_EXT_texture_env_combine"); -#endif /* GL_EXT_texture_env_combine */ -#ifdef GL_EXT_texture_env_dot3 - CONST_CAST(GLEW_EXT_texture_env_dot3) = glewGetExtension("GL_EXT_texture_env_dot3"); -#endif /* GL_EXT_texture_env_dot3 */ -#ifdef GL_EXT_texture_filter_anisotropic - CONST_CAST(GLEW_EXT_texture_filter_anisotropic) = glewGetExtension("GL_EXT_texture_filter_anisotropic"); -#endif /* GL_EXT_texture_filter_anisotropic */ -#ifdef GL_EXT_texture_integer - CONST_CAST(GLEW_EXT_texture_integer) = glewGetExtension("GL_EXT_texture_integer"); - if (glewExperimental || GLEW_EXT_texture_integer) CONST_CAST(GLEW_EXT_texture_integer) = !_glewInit_GL_EXT_texture_integer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_texture_integer */ -#ifdef GL_EXT_texture_lod_bias - CONST_CAST(GLEW_EXT_texture_lod_bias) = glewGetExtension("GL_EXT_texture_lod_bias"); -#endif /* GL_EXT_texture_lod_bias */ -#ifdef GL_EXT_texture_mirror_clamp - CONST_CAST(GLEW_EXT_texture_mirror_clamp) = glewGetExtension("GL_EXT_texture_mirror_clamp"); -#endif /* GL_EXT_texture_mirror_clamp */ -#ifdef GL_EXT_texture_object - CONST_CAST(GLEW_EXT_texture_object) = glewGetExtension("GL_EXT_texture_object"); - if (glewExperimental || GLEW_EXT_texture_object) CONST_CAST(GLEW_EXT_texture_object) = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_texture_object */ -#ifdef GL_EXT_texture_perturb_normal - CONST_CAST(GLEW_EXT_texture_perturb_normal) = glewGetExtension("GL_EXT_texture_perturb_normal"); - if (glewExperimental || GLEW_EXT_texture_perturb_normal) CONST_CAST(GLEW_EXT_texture_perturb_normal) = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_texture_perturb_normal */ -#ifdef GL_EXT_texture_rectangle - CONST_CAST(GLEW_EXT_texture_rectangle) = glewGetExtension("GL_EXT_texture_rectangle"); -#endif /* GL_EXT_texture_rectangle */ -#ifdef GL_EXT_texture_sRGB - CONST_CAST(GLEW_EXT_texture_sRGB) = glewGetExtension("GL_EXT_texture_sRGB"); -#endif /* GL_EXT_texture_sRGB */ -#ifdef GL_EXT_texture_shared_exponent - CONST_CAST(GLEW_EXT_texture_shared_exponent) = glewGetExtension("GL_EXT_texture_shared_exponent"); -#endif /* GL_EXT_texture_shared_exponent */ -#ifdef GL_EXT_texture_swizzle - CONST_CAST(GLEW_EXT_texture_swizzle) = glewGetExtension("GL_EXT_texture_swizzle"); -#endif /* GL_EXT_texture_swizzle */ -#ifdef GL_EXT_timer_query - CONST_CAST(GLEW_EXT_timer_query) = glewGetExtension("GL_EXT_timer_query"); - if (glewExperimental || GLEW_EXT_timer_query) CONST_CAST(GLEW_EXT_timer_query) = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_timer_query */ -#ifdef GL_EXT_transform_feedback - CONST_CAST(GLEW_EXT_transform_feedback) = glewGetExtension("GL_EXT_transform_feedback"); - if (glewExperimental || GLEW_EXT_transform_feedback) CONST_CAST(GLEW_EXT_transform_feedback) = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_transform_feedback */ -#ifdef GL_EXT_vertex_array - CONST_CAST(GLEW_EXT_vertex_array) = glewGetExtension("GL_EXT_vertex_array"); - if (glewExperimental || GLEW_EXT_vertex_array) CONST_CAST(GLEW_EXT_vertex_array) = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_vertex_array */ -#ifdef GL_EXT_vertex_array_bgra - CONST_CAST(GLEW_EXT_vertex_array_bgra) = glewGetExtension("GL_EXT_vertex_array_bgra"); -#endif /* GL_EXT_vertex_array_bgra */ -#ifdef GL_EXT_vertex_shader - CONST_CAST(GLEW_EXT_vertex_shader) = glewGetExtension("GL_EXT_vertex_shader"); - if (glewExperimental || GLEW_EXT_vertex_shader) CONST_CAST(GLEW_EXT_vertex_shader) = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_vertex_shader */ -#ifdef GL_EXT_vertex_weighting - CONST_CAST(GLEW_EXT_vertex_weighting) = glewGetExtension("GL_EXT_vertex_weighting"); - if (glewExperimental || GLEW_EXT_vertex_weighting) CONST_CAST(GLEW_EXT_vertex_weighting) = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_vertex_weighting */ -#ifdef GL_GREMEDY_frame_terminator - CONST_CAST(GLEW_GREMEDY_frame_terminator) = glewGetExtension("GL_GREMEDY_frame_terminator"); - if (glewExperimental || GLEW_GREMEDY_frame_terminator) CONST_CAST(GLEW_GREMEDY_frame_terminator) = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_GREMEDY_frame_terminator */ -#ifdef GL_GREMEDY_string_marker - CONST_CAST(GLEW_GREMEDY_string_marker) = glewGetExtension("GL_GREMEDY_string_marker"); - if (glewExperimental || GLEW_GREMEDY_string_marker) CONST_CAST(GLEW_GREMEDY_string_marker) = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_GREMEDY_string_marker */ -#ifdef GL_HP_convolution_border_modes - CONST_CAST(GLEW_HP_convolution_border_modes) = glewGetExtension("GL_HP_convolution_border_modes"); -#endif /* GL_HP_convolution_border_modes */ -#ifdef GL_HP_image_transform - CONST_CAST(GLEW_HP_image_transform) = glewGetExtension("GL_HP_image_transform"); - if (glewExperimental || GLEW_HP_image_transform) CONST_CAST(GLEW_HP_image_transform) = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_HP_image_transform */ -#ifdef GL_HP_occlusion_test - CONST_CAST(GLEW_HP_occlusion_test) = glewGetExtension("GL_HP_occlusion_test"); -#endif /* GL_HP_occlusion_test */ -#ifdef GL_HP_texture_lighting - CONST_CAST(GLEW_HP_texture_lighting) = glewGetExtension("GL_HP_texture_lighting"); -#endif /* GL_HP_texture_lighting */ -#ifdef GL_IBM_cull_vertex - CONST_CAST(GLEW_IBM_cull_vertex) = glewGetExtension("GL_IBM_cull_vertex"); -#endif /* GL_IBM_cull_vertex */ -#ifdef GL_IBM_multimode_draw_arrays - CONST_CAST(GLEW_IBM_multimode_draw_arrays) = glewGetExtension("GL_IBM_multimode_draw_arrays"); - if (glewExperimental || GLEW_IBM_multimode_draw_arrays) CONST_CAST(GLEW_IBM_multimode_draw_arrays) = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_IBM_multimode_draw_arrays */ -#ifdef GL_IBM_rasterpos_clip - CONST_CAST(GLEW_IBM_rasterpos_clip) = glewGetExtension("GL_IBM_rasterpos_clip"); -#endif /* GL_IBM_rasterpos_clip */ -#ifdef GL_IBM_static_data - CONST_CAST(GLEW_IBM_static_data) = glewGetExtension("GL_IBM_static_data"); -#endif /* GL_IBM_static_data */ -#ifdef GL_IBM_texture_mirrored_repeat - CONST_CAST(GLEW_IBM_texture_mirrored_repeat) = glewGetExtension("GL_IBM_texture_mirrored_repeat"); -#endif /* GL_IBM_texture_mirrored_repeat */ -#ifdef GL_IBM_vertex_array_lists - CONST_CAST(GLEW_IBM_vertex_array_lists) = glewGetExtension("GL_IBM_vertex_array_lists"); - if (glewExperimental || GLEW_IBM_vertex_array_lists) CONST_CAST(GLEW_IBM_vertex_array_lists) = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_IBM_vertex_array_lists */ -#ifdef GL_INGR_color_clamp - CONST_CAST(GLEW_INGR_color_clamp) = glewGetExtension("GL_INGR_color_clamp"); -#endif /* GL_INGR_color_clamp */ -#ifdef GL_INGR_interlace_read - CONST_CAST(GLEW_INGR_interlace_read) = glewGetExtension("GL_INGR_interlace_read"); -#endif /* GL_INGR_interlace_read */ -#ifdef GL_INTEL_parallel_arrays - CONST_CAST(GLEW_INTEL_parallel_arrays) = glewGetExtension("GL_INTEL_parallel_arrays"); - if (glewExperimental || GLEW_INTEL_parallel_arrays) CONST_CAST(GLEW_INTEL_parallel_arrays) = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_INTEL_parallel_arrays */ -#ifdef GL_INTEL_texture_scissor - CONST_CAST(GLEW_INTEL_texture_scissor) = glewGetExtension("GL_INTEL_texture_scissor"); - if (glewExperimental || GLEW_INTEL_texture_scissor) CONST_CAST(GLEW_INTEL_texture_scissor) = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_INTEL_texture_scissor */ -#ifdef GL_KTX_buffer_region - CONST_CAST(GLEW_KTX_buffer_region) = glewGetExtension("GL_KTX_buffer_region"); - if (glewExperimental || GLEW_KTX_buffer_region) CONST_CAST(GLEW_KTX_buffer_region) = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_KTX_buffer_region */ -#ifdef GL_MESAX_texture_stack - CONST_CAST(GLEW_MESAX_texture_stack) = glewGetExtension("GL_MESAX_texture_stack"); -#endif /* GL_MESAX_texture_stack */ -#ifdef GL_MESA_pack_invert - CONST_CAST(GLEW_MESA_pack_invert) = glewGetExtension("GL_MESA_pack_invert"); -#endif /* GL_MESA_pack_invert */ -#ifdef GL_MESA_resize_buffers - CONST_CAST(GLEW_MESA_resize_buffers) = glewGetExtension("GL_MESA_resize_buffers"); - if (glewExperimental || GLEW_MESA_resize_buffers) CONST_CAST(GLEW_MESA_resize_buffers) = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_MESA_resize_buffers */ -#ifdef GL_MESA_window_pos - CONST_CAST(GLEW_MESA_window_pos) = glewGetExtension("GL_MESA_window_pos"); - if (glewExperimental || GLEW_MESA_window_pos) CONST_CAST(GLEW_MESA_window_pos) = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_MESA_window_pos */ -#ifdef GL_MESA_ycbcr_texture - CONST_CAST(GLEW_MESA_ycbcr_texture) = glewGetExtension("GL_MESA_ycbcr_texture"); -#endif /* GL_MESA_ycbcr_texture */ -#ifdef GL_NV_blend_square - CONST_CAST(GLEW_NV_blend_square) = glewGetExtension("GL_NV_blend_square"); -#endif /* GL_NV_blend_square */ -#ifdef GL_NV_conditional_render - CONST_CAST(GLEW_NV_conditional_render) = glewGetExtension("GL_NV_conditional_render"); - if (glewExperimental || GLEW_NV_conditional_render) CONST_CAST(GLEW_NV_conditional_render) = !_glewInit_GL_NV_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_conditional_render */ -#ifdef GL_NV_copy_depth_to_color - CONST_CAST(GLEW_NV_copy_depth_to_color) = glewGetExtension("GL_NV_copy_depth_to_color"); -#endif /* GL_NV_copy_depth_to_color */ -#ifdef GL_NV_depth_buffer_float - CONST_CAST(GLEW_NV_depth_buffer_float) = glewGetExtension("GL_NV_depth_buffer_float"); - if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_depth_buffer_float */ -#ifdef GL_NV_depth_clamp - CONST_CAST(GLEW_NV_depth_clamp) = glewGetExtension("GL_NV_depth_clamp"); -#endif /* GL_NV_depth_clamp */ -#ifdef GL_NV_depth_range_unclamped - CONST_CAST(GLEW_NV_depth_range_unclamped) = glewGetExtension("GL_NV_depth_range_unclamped"); -#endif /* GL_NV_depth_range_unclamped */ -#ifdef GL_NV_evaluators - CONST_CAST(GLEW_NV_evaluators) = glewGetExtension("GL_NV_evaluators"); - if (glewExperimental || GLEW_NV_evaluators) CONST_CAST(GLEW_NV_evaluators) = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_evaluators */ -#ifdef GL_NV_explicit_multisample - CONST_CAST(GLEW_NV_explicit_multisample) = glewGetExtension("GL_NV_explicit_multisample"); - if (glewExperimental || GLEW_NV_explicit_multisample) CONST_CAST(GLEW_NV_explicit_multisample) = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_explicit_multisample */ -#ifdef GL_NV_fence - CONST_CAST(GLEW_NV_fence) = glewGetExtension("GL_NV_fence"); - if (glewExperimental || GLEW_NV_fence) CONST_CAST(GLEW_NV_fence) = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_fence */ -#ifdef GL_NV_float_buffer - CONST_CAST(GLEW_NV_float_buffer) = glewGetExtension("GL_NV_float_buffer"); -#endif /* GL_NV_float_buffer */ -#ifdef GL_NV_fog_distance - CONST_CAST(GLEW_NV_fog_distance) = glewGetExtension("GL_NV_fog_distance"); -#endif /* GL_NV_fog_distance */ -#ifdef GL_NV_fragment_program - CONST_CAST(GLEW_NV_fragment_program) = glewGetExtension("GL_NV_fragment_program"); - if (glewExperimental || GLEW_NV_fragment_program) CONST_CAST(GLEW_NV_fragment_program) = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_fragment_program */ -#ifdef GL_NV_fragment_program2 - CONST_CAST(GLEW_NV_fragment_program2) = glewGetExtension("GL_NV_fragment_program2"); -#endif /* GL_NV_fragment_program2 */ -#ifdef GL_NV_fragment_program4 - CONST_CAST(GLEW_NV_fragment_program4) = glewGetExtension("GL_NV_fragment_program4"); -#endif /* GL_NV_fragment_program4 */ -#ifdef GL_NV_fragment_program_option - CONST_CAST(GLEW_NV_fragment_program_option) = glewGetExtension("GL_NV_fragment_program_option"); -#endif /* GL_NV_fragment_program_option */ -#ifdef GL_NV_framebuffer_multisample_coverage - CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = glewGetExtension("GL_NV_framebuffer_multisample_coverage"); - if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = !_glewInit_GL_NV_framebuffer_multisample_coverage(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_framebuffer_multisample_coverage */ -#ifdef GL_NV_geometry_program4 - CONST_CAST(GLEW_NV_geometry_program4) = glewGetExtension("GL_NV_geometry_program4"); - if (glewExperimental || GLEW_NV_geometry_program4) CONST_CAST(GLEW_NV_geometry_program4) = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_geometry_program4 */ -#ifdef GL_NV_geometry_shader4 - CONST_CAST(GLEW_NV_geometry_shader4) = glewGetExtension("GL_NV_geometry_shader4"); -#endif /* GL_NV_geometry_shader4 */ -#ifdef GL_NV_gpu_program4 - CONST_CAST(GLEW_NV_gpu_program4) = glewGetExtension("GL_NV_gpu_program4"); - if (glewExperimental || GLEW_NV_gpu_program4) CONST_CAST(GLEW_NV_gpu_program4) = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_gpu_program4 */ -#ifdef GL_NV_half_float - CONST_CAST(GLEW_NV_half_float) = glewGetExtension("GL_NV_half_float"); - if (glewExperimental || GLEW_NV_half_float) CONST_CAST(GLEW_NV_half_float) = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_half_float */ -#ifdef GL_NV_light_max_exponent - CONST_CAST(GLEW_NV_light_max_exponent) = glewGetExtension("GL_NV_light_max_exponent"); -#endif /* GL_NV_light_max_exponent */ -#ifdef GL_NV_multisample_filter_hint - CONST_CAST(GLEW_NV_multisample_filter_hint) = glewGetExtension("GL_NV_multisample_filter_hint"); -#endif /* GL_NV_multisample_filter_hint */ -#ifdef GL_NV_occlusion_query - CONST_CAST(GLEW_NV_occlusion_query) = glewGetExtension("GL_NV_occlusion_query"); - if (glewExperimental || GLEW_NV_occlusion_query) CONST_CAST(GLEW_NV_occlusion_query) = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_occlusion_query */ -#ifdef GL_NV_packed_depth_stencil - CONST_CAST(GLEW_NV_packed_depth_stencil) = glewGetExtension("GL_NV_packed_depth_stencil"); -#endif /* GL_NV_packed_depth_stencil */ -#ifdef GL_NV_parameter_buffer_object - CONST_CAST(GLEW_NV_parameter_buffer_object) = glewGetExtension("GL_NV_parameter_buffer_object"); - if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_parameter_buffer_object */ -#ifdef GL_NV_pixel_data_range - CONST_CAST(GLEW_NV_pixel_data_range) = glewGetExtension("GL_NV_pixel_data_range"); - if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_pixel_data_range */ -#ifdef GL_NV_point_sprite - CONST_CAST(GLEW_NV_point_sprite) = glewGetExtension("GL_NV_point_sprite"); - if (glewExperimental || GLEW_NV_point_sprite) CONST_CAST(GLEW_NV_point_sprite) = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_point_sprite */ -#ifdef GL_NV_present_video - CONST_CAST(GLEW_NV_present_video) = glewGetExtension("GL_NV_present_video"); - if (glewExperimental || GLEW_NV_present_video) CONST_CAST(GLEW_NV_present_video) = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_present_video */ -#ifdef GL_NV_primitive_restart - CONST_CAST(GLEW_NV_primitive_restart) = glewGetExtension("GL_NV_primitive_restart"); - if (glewExperimental || GLEW_NV_primitive_restart) CONST_CAST(GLEW_NV_primitive_restart) = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_primitive_restart */ -#ifdef GL_NV_register_combiners - CONST_CAST(GLEW_NV_register_combiners) = glewGetExtension("GL_NV_register_combiners"); - if (glewExperimental || GLEW_NV_register_combiners) CONST_CAST(GLEW_NV_register_combiners) = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_register_combiners */ -#ifdef GL_NV_register_combiners2 - CONST_CAST(GLEW_NV_register_combiners2) = glewGetExtension("GL_NV_register_combiners2"); - if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_register_combiners2 */ -#ifdef GL_NV_texgen_emboss - CONST_CAST(GLEW_NV_texgen_emboss) = glewGetExtension("GL_NV_texgen_emboss"); -#endif /* GL_NV_texgen_emboss */ -#ifdef GL_NV_texgen_reflection - CONST_CAST(GLEW_NV_texgen_reflection) = glewGetExtension("GL_NV_texgen_reflection"); -#endif /* GL_NV_texgen_reflection */ -#ifdef GL_NV_texture_compression_vtc - CONST_CAST(GLEW_NV_texture_compression_vtc) = glewGetExtension("GL_NV_texture_compression_vtc"); -#endif /* GL_NV_texture_compression_vtc */ -#ifdef GL_NV_texture_env_combine4 - CONST_CAST(GLEW_NV_texture_env_combine4) = glewGetExtension("GL_NV_texture_env_combine4"); -#endif /* GL_NV_texture_env_combine4 */ -#ifdef GL_NV_texture_expand_normal - CONST_CAST(GLEW_NV_texture_expand_normal) = glewGetExtension("GL_NV_texture_expand_normal"); -#endif /* GL_NV_texture_expand_normal */ -#ifdef GL_NV_texture_rectangle - CONST_CAST(GLEW_NV_texture_rectangle) = glewGetExtension("GL_NV_texture_rectangle"); -#endif /* GL_NV_texture_rectangle */ -#ifdef GL_NV_texture_shader - CONST_CAST(GLEW_NV_texture_shader) = glewGetExtension("GL_NV_texture_shader"); -#endif /* GL_NV_texture_shader */ -#ifdef GL_NV_texture_shader2 - CONST_CAST(GLEW_NV_texture_shader2) = glewGetExtension("GL_NV_texture_shader2"); -#endif /* GL_NV_texture_shader2 */ -#ifdef GL_NV_texture_shader3 - CONST_CAST(GLEW_NV_texture_shader3) = glewGetExtension("GL_NV_texture_shader3"); -#endif /* GL_NV_texture_shader3 */ -#ifdef GL_NV_transform_feedback - CONST_CAST(GLEW_NV_transform_feedback) = glewGetExtension("GL_NV_transform_feedback"); - if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_transform_feedback */ -#ifdef GL_NV_vertex_array_range - CONST_CAST(GLEW_NV_vertex_array_range) = glewGetExtension("GL_NV_vertex_array_range"); - if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_vertex_array_range */ -#ifdef GL_NV_vertex_array_range2 - CONST_CAST(GLEW_NV_vertex_array_range2) = glewGetExtension("GL_NV_vertex_array_range2"); -#endif /* GL_NV_vertex_array_range2 */ -#ifdef GL_NV_vertex_program - CONST_CAST(GLEW_NV_vertex_program) = glewGetExtension("GL_NV_vertex_program"); - if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_NV_vertex_program */ -#ifdef GL_NV_vertex_program1_1 - CONST_CAST(GLEW_NV_vertex_program1_1) = glewGetExtension("GL_NV_vertex_program1_1"); -#endif /* GL_NV_vertex_program1_1 */ -#ifdef GL_NV_vertex_program2 - CONST_CAST(GLEW_NV_vertex_program2) = glewGetExtension("GL_NV_vertex_program2"); -#endif /* GL_NV_vertex_program2 */ -#ifdef GL_NV_vertex_program2_option - CONST_CAST(GLEW_NV_vertex_program2_option) = glewGetExtension("GL_NV_vertex_program2_option"); -#endif /* GL_NV_vertex_program2_option */ -#ifdef GL_NV_vertex_program3 - CONST_CAST(GLEW_NV_vertex_program3) = glewGetExtension("GL_NV_vertex_program3"); -#endif /* GL_NV_vertex_program3 */ -#ifdef GL_NV_vertex_program4 - CONST_CAST(GLEW_NV_vertex_program4) = glewGetExtension("GL_NV_vertex_program4"); -#endif /* GL_NV_vertex_program4 */ -#ifdef GL_OES_byte_coordinates - CONST_CAST(GLEW_OES_byte_coordinates) = glewGetExtension("GL_OES_byte_coordinates"); -#endif /* GL_OES_byte_coordinates */ -#ifdef GL_OES_compressed_paletted_texture - CONST_CAST(GLEW_OES_compressed_paletted_texture) = glewGetExtension("GL_OES_compressed_paletted_texture"); -#endif /* GL_OES_compressed_paletted_texture */ -#ifdef GL_OES_read_format - CONST_CAST(GLEW_OES_read_format) = glewGetExtension("GL_OES_read_format"); -#endif /* GL_OES_read_format */ -#ifdef GL_OES_single_precision - CONST_CAST(GLEW_OES_single_precision) = glewGetExtension("GL_OES_single_precision"); - if (glewExperimental || GLEW_OES_single_precision) CONST_CAST(GLEW_OES_single_precision) = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_OES_single_precision */ -#ifdef GL_OML_interlace - CONST_CAST(GLEW_OML_interlace) = glewGetExtension("GL_OML_interlace"); -#endif /* GL_OML_interlace */ -#ifdef GL_OML_resample - CONST_CAST(GLEW_OML_resample) = glewGetExtension("GL_OML_resample"); -#endif /* GL_OML_resample */ -#ifdef GL_OML_subsample - CONST_CAST(GLEW_OML_subsample) = glewGetExtension("GL_OML_subsample"); -#endif /* GL_OML_subsample */ -#ifdef GL_PGI_misc_hints - CONST_CAST(GLEW_PGI_misc_hints) = glewGetExtension("GL_PGI_misc_hints"); -#endif /* GL_PGI_misc_hints */ -#ifdef GL_PGI_vertex_hints - CONST_CAST(GLEW_PGI_vertex_hints) = glewGetExtension("GL_PGI_vertex_hints"); -#endif /* GL_PGI_vertex_hints */ -#ifdef GL_REND_screen_coordinates - CONST_CAST(GLEW_REND_screen_coordinates) = glewGetExtension("GL_REND_screen_coordinates"); -#endif /* GL_REND_screen_coordinates */ -#ifdef GL_S3_s3tc - CONST_CAST(GLEW_S3_s3tc) = glewGetExtension("GL_S3_s3tc"); -#endif /* GL_S3_s3tc */ -#ifdef GL_SGIS_color_range - CONST_CAST(GLEW_SGIS_color_range) = glewGetExtension("GL_SGIS_color_range"); -#endif /* GL_SGIS_color_range */ -#ifdef GL_SGIS_detail_texture - CONST_CAST(GLEW_SGIS_detail_texture) = glewGetExtension("GL_SGIS_detail_texture"); - if (glewExperimental || GLEW_SGIS_detail_texture) CONST_CAST(GLEW_SGIS_detail_texture) = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_detail_texture */ -#ifdef GL_SGIS_fog_function - CONST_CAST(GLEW_SGIS_fog_function) = glewGetExtension("GL_SGIS_fog_function"); - if (glewExperimental || GLEW_SGIS_fog_function) CONST_CAST(GLEW_SGIS_fog_function) = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_fog_function */ -#ifdef GL_SGIS_generate_mipmap - CONST_CAST(GLEW_SGIS_generate_mipmap) = glewGetExtension("GL_SGIS_generate_mipmap"); -#endif /* GL_SGIS_generate_mipmap */ -#ifdef GL_SGIS_multisample - CONST_CAST(GLEW_SGIS_multisample) = glewGetExtension("GL_SGIS_multisample"); - if (glewExperimental || GLEW_SGIS_multisample) CONST_CAST(GLEW_SGIS_multisample) = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_multisample */ -#ifdef GL_SGIS_pixel_texture - CONST_CAST(GLEW_SGIS_pixel_texture) = glewGetExtension("GL_SGIS_pixel_texture"); -#endif /* GL_SGIS_pixel_texture */ -#ifdef GL_SGIS_point_line_texgen - CONST_CAST(GLEW_SGIS_point_line_texgen) = glewGetExtension("GL_SGIS_point_line_texgen"); -#endif /* GL_SGIS_point_line_texgen */ -#ifdef GL_SGIS_sharpen_texture - CONST_CAST(GLEW_SGIS_sharpen_texture) = glewGetExtension("GL_SGIS_sharpen_texture"); - if (glewExperimental || GLEW_SGIS_sharpen_texture) CONST_CAST(GLEW_SGIS_sharpen_texture) = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_sharpen_texture */ -#ifdef GL_SGIS_texture4D - CONST_CAST(GLEW_SGIS_texture4D) = glewGetExtension("GL_SGIS_texture4D"); - if (glewExperimental || GLEW_SGIS_texture4D) CONST_CAST(GLEW_SGIS_texture4D) = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_texture4D */ -#ifdef GL_SGIS_texture_border_clamp - CONST_CAST(GLEW_SGIS_texture_border_clamp) = glewGetExtension("GL_SGIS_texture_border_clamp"); -#endif /* GL_SGIS_texture_border_clamp */ -#ifdef GL_SGIS_texture_edge_clamp - CONST_CAST(GLEW_SGIS_texture_edge_clamp) = glewGetExtension("GL_SGIS_texture_edge_clamp"); -#endif /* GL_SGIS_texture_edge_clamp */ -#ifdef GL_SGIS_texture_filter4 - CONST_CAST(GLEW_SGIS_texture_filter4) = glewGetExtension("GL_SGIS_texture_filter4"); - if (glewExperimental || GLEW_SGIS_texture_filter4) CONST_CAST(GLEW_SGIS_texture_filter4) = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIS_texture_filter4 */ -#ifdef GL_SGIS_texture_lod - CONST_CAST(GLEW_SGIS_texture_lod) = glewGetExtension("GL_SGIS_texture_lod"); -#endif /* GL_SGIS_texture_lod */ -#ifdef GL_SGIS_texture_select - CONST_CAST(GLEW_SGIS_texture_select) = glewGetExtension("GL_SGIS_texture_select"); -#endif /* GL_SGIS_texture_select */ -#ifdef GL_SGIX_async - CONST_CAST(GLEW_SGIX_async) = glewGetExtension("GL_SGIX_async"); - if (glewExperimental || GLEW_SGIX_async) CONST_CAST(GLEW_SGIX_async) = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_async */ -#ifdef GL_SGIX_async_histogram - CONST_CAST(GLEW_SGIX_async_histogram) = glewGetExtension("GL_SGIX_async_histogram"); -#endif /* GL_SGIX_async_histogram */ -#ifdef GL_SGIX_async_pixel - CONST_CAST(GLEW_SGIX_async_pixel) = glewGetExtension("GL_SGIX_async_pixel"); -#endif /* GL_SGIX_async_pixel */ -#ifdef GL_SGIX_blend_alpha_minmax - CONST_CAST(GLEW_SGIX_blend_alpha_minmax) = glewGetExtension("GL_SGIX_blend_alpha_minmax"); -#endif /* GL_SGIX_blend_alpha_minmax */ -#ifdef GL_SGIX_clipmap - CONST_CAST(GLEW_SGIX_clipmap) = glewGetExtension("GL_SGIX_clipmap"); -#endif /* GL_SGIX_clipmap */ -#ifdef GL_SGIX_convolution_accuracy - CONST_CAST(GLEW_SGIX_convolution_accuracy) = glewGetExtension("GL_SGIX_convolution_accuracy"); -#endif /* GL_SGIX_convolution_accuracy */ -#ifdef GL_SGIX_depth_texture - CONST_CAST(GLEW_SGIX_depth_texture) = glewGetExtension("GL_SGIX_depth_texture"); -#endif /* GL_SGIX_depth_texture */ -#ifdef GL_SGIX_flush_raster - CONST_CAST(GLEW_SGIX_flush_raster) = glewGetExtension("GL_SGIX_flush_raster"); - if (glewExperimental || GLEW_SGIX_flush_raster) CONST_CAST(GLEW_SGIX_flush_raster) = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_flush_raster */ -#ifdef GL_SGIX_fog_offset - CONST_CAST(GLEW_SGIX_fog_offset) = glewGetExtension("GL_SGIX_fog_offset"); -#endif /* GL_SGIX_fog_offset */ -#ifdef GL_SGIX_fog_texture - CONST_CAST(GLEW_SGIX_fog_texture) = glewGetExtension("GL_SGIX_fog_texture"); - if (glewExperimental || GLEW_SGIX_fog_texture) CONST_CAST(GLEW_SGIX_fog_texture) = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_fog_texture */ -#ifdef GL_SGIX_fragment_specular_lighting - CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = glewGetExtension("GL_SGIX_fragment_specular_lighting"); - if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_fragment_specular_lighting */ -#ifdef GL_SGIX_framezoom - CONST_CAST(GLEW_SGIX_framezoom) = glewGetExtension("GL_SGIX_framezoom"); - if (glewExperimental || GLEW_SGIX_framezoom) CONST_CAST(GLEW_SGIX_framezoom) = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_framezoom */ -#ifdef GL_SGIX_interlace - CONST_CAST(GLEW_SGIX_interlace) = glewGetExtension("GL_SGIX_interlace"); -#endif /* GL_SGIX_interlace */ -#ifdef GL_SGIX_ir_instrument1 - CONST_CAST(GLEW_SGIX_ir_instrument1) = glewGetExtension("GL_SGIX_ir_instrument1"); -#endif /* GL_SGIX_ir_instrument1 */ -#ifdef GL_SGIX_list_priority - CONST_CAST(GLEW_SGIX_list_priority) = glewGetExtension("GL_SGIX_list_priority"); -#endif /* GL_SGIX_list_priority */ -#ifdef GL_SGIX_pixel_texture - CONST_CAST(GLEW_SGIX_pixel_texture) = glewGetExtension("GL_SGIX_pixel_texture"); - if (glewExperimental || GLEW_SGIX_pixel_texture) CONST_CAST(GLEW_SGIX_pixel_texture) = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_pixel_texture */ -#ifdef GL_SGIX_pixel_texture_bits - CONST_CAST(GLEW_SGIX_pixel_texture_bits) = glewGetExtension("GL_SGIX_pixel_texture_bits"); -#endif /* GL_SGIX_pixel_texture_bits */ -#ifdef GL_SGIX_reference_plane - CONST_CAST(GLEW_SGIX_reference_plane) = glewGetExtension("GL_SGIX_reference_plane"); - if (glewExperimental || GLEW_SGIX_reference_plane) CONST_CAST(GLEW_SGIX_reference_plane) = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_reference_plane */ -#ifdef GL_SGIX_resample - CONST_CAST(GLEW_SGIX_resample) = glewGetExtension("GL_SGIX_resample"); -#endif /* GL_SGIX_resample */ -#ifdef GL_SGIX_shadow - CONST_CAST(GLEW_SGIX_shadow) = glewGetExtension("GL_SGIX_shadow"); -#endif /* GL_SGIX_shadow */ -#ifdef GL_SGIX_shadow_ambient - CONST_CAST(GLEW_SGIX_shadow_ambient) = glewGetExtension("GL_SGIX_shadow_ambient"); -#endif /* GL_SGIX_shadow_ambient */ -#ifdef GL_SGIX_sprite - CONST_CAST(GLEW_SGIX_sprite) = glewGetExtension("GL_SGIX_sprite"); - if (glewExperimental || GLEW_SGIX_sprite) CONST_CAST(GLEW_SGIX_sprite) = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_sprite */ -#ifdef GL_SGIX_tag_sample_buffer - CONST_CAST(GLEW_SGIX_tag_sample_buffer) = glewGetExtension("GL_SGIX_tag_sample_buffer"); - if (glewExperimental || GLEW_SGIX_tag_sample_buffer) CONST_CAST(GLEW_SGIX_tag_sample_buffer) = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGIX_tag_sample_buffer */ -#ifdef GL_SGIX_texture_add_env - CONST_CAST(GLEW_SGIX_texture_add_env) = glewGetExtension("GL_SGIX_texture_add_env"); -#endif /* GL_SGIX_texture_add_env */ -#ifdef GL_SGIX_texture_coordinate_clamp - CONST_CAST(GLEW_SGIX_texture_coordinate_clamp) = glewGetExtension("GL_SGIX_texture_coordinate_clamp"); -#endif /* GL_SGIX_texture_coordinate_clamp */ -#ifdef GL_SGIX_texture_lod_bias - CONST_CAST(GLEW_SGIX_texture_lod_bias) = glewGetExtension("GL_SGIX_texture_lod_bias"); -#endif /* GL_SGIX_texture_lod_bias */ -#ifdef GL_SGIX_texture_multi_buffer - CONST_CAST(GLEW_SGIX_texture_multi_buffer) = glewGetExtension("GL_SGIX_texture_multi_buffer"); -#endif /* GL_SGIX_texture_multi_buffer */ -#ifdef GL_SGIX_texture_range - CONST_CAST(GLEW_SGIX_texture_range) = glewGetExtension("GL_SGIX_texture_range"); -#endif /* GL_SGIX_texture_range */ -#ifdef GL_SGIX_texture_scale_bias - CONST_CAST(GLEW_SGIX_texture_scale_bias) = glewGetExtension("GL_SGIX_texture_scale_bias"); -#endif /* GL_SGIX_texture_scale_bias */ -#ifdef GL_SGIX_vertex_preclip - CONST_CAST(GLEW_SGIX_vertex_preclip) = glewGetExtension("GL_SGIX_vertex_preclip"); -#endif /* GL_SGIX_vertex_preclip */ -#ifdef GL_SGIX_vertex_preclip_hint - CONST_CAST(GLEW_SGIX_vertex_preclip_hint) = glewGetExtension("GL_SGIX_vertex_preclip_hint"); -#endif /* GL_SGIX_vertex_preclip_hint */ -#ifdef GL_SGIX_ycrcb - CONST_CAST(GLEW_SGIX_ycrcb) = glewGetExtension("GL_SGIX_ycrcb"); -#endif /* GL_SGIX_ycrcb */ -#ifdef GL_SGI_color_matrix - CONST_CAST(GLEW_SGI_color_matrix) = glewGetExtension("GL_SGI_color_matrix"); -#endif /* GL_SGI_color_matrix */ -#ifdef GL_SGI_color_table - CONST_CAST(GLEW_SGI_color_table) = glewGetExtension("GL_SGI_color_table"); - if (glewExperimental || GLEW_SGI_color_table) CONST_CAST(GLEW_SGI_color_table) = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SGI_color_table */ -#ifdef GL_SGI_texture_color_table - CONST_CAST(GLEW_SGI_texture_color_table) = glewGetExtension("GL_SGI_texture_color_table"); -#endif /* GL_SGI_texture_color_table */ -#ifdef GL_SUNX_constant_data - CONST_CAST(GLEW_SUNX_constant_data) = glewGetExtension("GL_SUNX_constant_data"); - if (glewExperimental || GLEW_SUNX_constant_data) CONST_CAST(GLEW_SUNX_constant_data) = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SUNX_constant_data */ -#ifdef GL_SUN_convolution_border_modes - CONST_CAST(GLEW_SUN_convolution_border_modes) = glewGetExtension("GL_SUN_convolution_border_modes"); -#endif /* GL_SUN_convolution_border_modes */ -#ifdef GL_SUN_global_alpha - CONST_CAST(GLEW_SUN_global_alpha) = glewGetExtension("GL_SUN_global_alpha"); - if (glewExperimental || GLEW_SUN_global_alpha) CONST_CAST(GLEW_SUN_global_alpha) = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SUN_global_alpha */ -#ifdef GL_SUN_mesh_array - CONST_CAST(GLEW_SUN_mesh_array) = glewGetExtension("GL_SUN_mesh_array"); -#endif /* GL_SUN_mesh_array */ -#ifdef GL_SUN_read_video_pixels - CONST_CAST(GLEW_SUN_read_video_pixels) = glewGetExtension("GL_SUN_read_video_pixels"); - if (glewExperimental || GLEW_SUN_read_video_pixels) CONST_CAST(GLEW_SUN_read_video_pixels) = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SUN_read_video_pixels */ -#ifdef GL_SUN_slice_accum - CONST_CAST(GLEW_SUN_slice_accum) = glewGetExtension("GL_SUN_slice_accum"); -#endif /* GL_SUN_slice_accum */ -#ifdef GL_SUN_triangle_list - CONST_CAST(GLEW_SUN_triangle_list) = glewGetExtension("GL_SUN_triangle_list"); - if (glewExperimental || GLEW_SUN_triangle_list) CONST_CAST(GLEW_SUN_triangle_list) = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SUN_triangle_list */ -#ifdef GL_SUN_vertex - CONST_CAST(GLEW_SUN_vertex) = glewGetExtension("GL_SUN_vertex"); - if (glewExperimental || GLEW_SUN_vertex) CONST_CAST(GLEW_SUN_vertex) = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_SUN_vertex */ -#ifdef GL_WIN_phong_shading - CONST_CAST(GLEW_WIN_phong_shading) = glewGetExtension("GL_WIN_phong_shading"); -#endif /* GL_WIN_phong_shading */ -#ifdef GL_WIN_specular_fog - CONST_CAST(GLEW_WIN_specular_fog) = glewGetExtension("GL_WIN_specular_fog"); -#endif /* GL_WIN_specular_fog */ -#ifdef GL_WIN_swap_hint - CONST_CAST(GLEW_WIN_swap_hint) = glewGetExtension("GL_WIN_swap_hint"); - if (glewExperimental || GLEW_WIN_swap_hint) CONST_CAST(GLEW_WIN_swap_hint) = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_WIN_swap_hint */ - - return GLEW_OK; -} - - -#if defined(_WIN32) - -#if !defined(GLEW_MX) - -PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL; - -PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL; -PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL; -PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL; -PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL; - -PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB = NULL; - -PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL; - -PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL; -PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL; - -PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL; -PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL; -PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL; -PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL; -PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL; - -PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL; -PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL; -PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL; - -PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL; -PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL; -PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL; - -PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL; -PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL; -PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL; -PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL; - -PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL; - -PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL; -PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL; - -PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL; -PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL; -PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL; -PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL; -PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL; - -PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL; -PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL; -PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL; - -PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL; -PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL; - -PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL; -PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL; - -PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL; -PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL; -PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL; -PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL; - -PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL; -PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL; -PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL; -PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL; -PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL; -PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL; -PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL; -PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL; -PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL; -PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL; -PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL; -PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL; - -PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL; -PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL; -PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL; -PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL; - -PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL; -PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL; -PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL; -PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL; - -PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL; -PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL; -PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL; -PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL; - -PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL; -PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL; -PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL; -PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV = NULL; -PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV = NULL; - -PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV = NULL; -PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV = NULL; -PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV = NULL; - -PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV = NULL; -PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV = NULL; -PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV = NULL; -PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV = NULL; -PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV = NULL; -PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV = NULL; - -PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL; -PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL; - -PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV = NULL; -PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV = NULL; -PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV = NULL; -PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV = NULL; -PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV = NULL; -PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV = NULL; - -PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL; -PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL; -PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL; -PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL; -PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL; -PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL; -GLboolean __WGLEW_3DFX_multisample = GL_FALSE; -GLboolean __WGLEW_3DL_stereo_control = GL_FALSE; -GLboolean __WGLEW_ARB_buffer_region = GL_FALSE; -GLboolean __WGLEW_ARB_create_context = GL_FALSE; -GLboolean __WGLEW_ARB_extensions_string = GL_FALSE; -GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE; -GLboolean __WGLEW_ARB_make_current_read = GL_FALSE; -GLboolean __WGLEW_ARB_multisample = GL_FALSE; -GLboolean __WGLEW_ARB_pbuffer = GL_FALSE; -GLboolean __WGLEW_ARB_pixel_format = GL_FALSE; -GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE; -GLboolean __WGLEW_ARB_render_texture = GL_FALSE; -GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE; -GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE; -GLboolean __WGLEW_EXT_depth_float = GL_FALSE; -GLboolean __WGLEW_EXT_display_color_table = GL_FALSE; -GLboolean __WGLEW_EXT_extensions_string = GL_FALSE; -GLboolean __WGLEW_EXT_framebuffer_sRGB = GL_FALSE; -GLboolean __WGLEW_EXT_make_current_read = GL_FALSE; -GLboolean __WGLEW_EXT_multisample = GL_FALSE; -GLboolean __WGLEW_EXT_pbuffer = GL_FALSE; -GLboolean __WGLEW_EXT_pixel_format = GL_FALSE; -GLboolean __WGLEW_EXT_pixel_format_packed_float = GL_FALSE; -GLboolean __WGLEW_EXT_swap_control = GL_FALSE; -GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE; -GLboolean __WGLEW_I3D_gamma = GL_FALSE; -GLboolean __WGLEW_I3D_genlock = GL_FALSE; -GLboolean __WGLEW_I3D_image_buffer = GL_FALSE; -GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE; -GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE; -GLboolean __WGLEW_NV_float_buffer = GL_FALSE; -GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE; -GLboolean __WGLEW_NV_present_video = GL_FALSE; -GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE; -GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE; -GLboolean __WGLEW_NV_swap_group = GL_FALSE; -GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE; -GLboolean __WGLEW_NV_video_output = GL_FALSE; -GLboolean __WGLEW_OML_sync_control = GL_FALSE; - -#endif /* !GLEW_MX */ - -#ifdef WGL_3DFX_multisample - -#endif /* WGL_3DFX_multisample */ - -#ifdef WGL_3DL_stereo_control - -static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r; - - return r; -} - -#endif /* WGL_3DL_stereo_control */ - -#ifdef WGL_ARB_buffer_region - -static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r; - r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r; - r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r; - r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_buffer_region */ - -#ifdef WGL_ARB_create_context - -static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateContextAttribsARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_create_context */ - -#ifdef WGL_ARB_extensions_string - -static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_extensions_string */ - -#ifdef WGL_ARB_framebuffer_sRGB - -#endif /* WGL_ARB_framebuffer_sRGB */ - -#ifdef WGL_ARB_make_current_read - -static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r; - r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_make_current_read */ - -#ifdef WGL_ARB_multisample - -#endif /* WGL_ARB_multisample */ - -#ifdef WGL_ARB_pbuffer - -static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r; - r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r; - r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r; - r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r; - r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_pbuffer */ - -#ifdef WGL_ARB_pixel_format - -static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r; - r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r; - r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_pixel_format */ - -#ifdef WGL_ARB_pixel_format_float - -#endif /* WGL_ARB_pixel_format_float */ - -#ifdef WGL_ARB_render_texture - -static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r; - r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r; - r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r; - - return r; -} - -#endif /* WGL_ARB_render_texture */ - -#ifdef WGL_ATI_pixel_format_float - -#endif /* WGL_ATI_pixel_format_float */ - -#ifdef WGL_ATI_render_texture_rectangle - -#endif /* WGL_ATI_render_texture_rectangle */ - -#ifdef WGL_EXT_depth_float - -#endif /* WGL_EXT_depth_float */ - -#ifdef WGL_EXT_display_color_table - -static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r; - r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r; - r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r; - r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_display_color_table */ - -#ifdef WGL_EXT_extensions_string - -static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_extensions_string */ - -#ifdef WGL_EXT_framebuffer_sRGB - -#endif /* WGL_EXT_framebuffer_sRGB */ - -#ifdef WGL_EXT_make_current_read - -static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r; - r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_make_current_read */ - -#ifdef WGL_EXT_multisample - -#endif /* WGL_EXT_multisample */ - -#ifdef WGL_EXT_pbuffer - -static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r; - r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r; - r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r; - r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r; - r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_pbuffer */ - -#ifdef WGL_EXT_pixel_format - -static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r; - r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r; - r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_pixel_format */ - -#ifdef WGL_EXT_pixel_format_packed_float - -#endif /* WGL_EXT_pixel_format_packed_float */ - -#ifdef WGL_EXT_swap_control - -static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r; - r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r; - - return r; -} - -#endif /* WGL_EXT_swap_control */ - -#ifdef WGL_I3D_digital_video_control - -static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r; - r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_digital_video_control */ - -#ifdef WGL_I3D_gamma - -static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r; - r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r; - r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r; - r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_gamma */ - -#ifdef WGL_I3D_genlock - -static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r; - r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r; - r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r; - r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r; - r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r; - r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r; - r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r; - r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r; - r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r; - r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r; - r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r; - r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_genlock */ - -#ifdef WGL_I3D_image_buffer - -static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r; - r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r; - r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r; - r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_image_buffer */ - -#ifdef WGL_I3D_swap_frame_lock - -static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r; - r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r; - r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r; - r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_swap_frame_lock */ - -#ifdef WGL_I3D_swap_frame_usage - -static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r; - r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r; - r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r; - r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r; - - return r; -} - -#endif /* WGL_I3D_swap_frame_usage */ - -#ifdef WGL_NV_float_buffer - -#endif /* WGL_NV_float_buffer */ - -#ifdef WGL_NV_gpu_affinity - -static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglCreateAffinityDCNV")) == NULL) || r; - r = ((wglDeleteDCNV = (PFNWGLDELETEDCNVPROC)glewGetProcAddress((const GLubyte*)"wglDeleteDCNV")) == NULL) || r; - r = ((wglEnumGpuDevicesNV = (PFNWGLENUMGPUDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpuDevicesNV")) == NULL) || r; - r = ((wglEnumGpusFromAffinityDCNV = (PFNWGLENUMGPUSFROMAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusFromAffinityDCNV")) == NULL) || r; - r = ((wglEnumGpusNV = (PFNWGLENUMGPUSNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusNV")) == NULL) || r; - - return r; -} - -#endif /* WGL_NV_gpu_affinity */ - -#ifdef WGL_NV_present_video - -static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBindVideoDeviceNV = (PFNWGLBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoDeviceNV")) == NULL) || r; - r = ((wglEnumerateVideoDevicesNV = (PFNWGLENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoDevicesNV")) == NULL) || r; - r = ((wglQueryCurrentContextNV = (PFNWGLQUERYCURRENTCONTEXTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryCurrentContextNV")) == NULL) || r; - - return r; -} - -#endif /* WGL_NV_present_video */ - -#ifdef WGL_NV_render_depth_texture - -#endif /* WGL_NV_render_depth_texture */ - -#ifdef WGL_NV_render_texture_rectangle - -#endif /* WGL_NV_render_texture_rectangle */ - -#ifdef WGL_NV_swap_group - -static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"wglBindSwapBarrierNV")) == NULL) || r; - r = ((wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglJoinSwapGroupNV")) == NULL) || r; - r = ((wglQueryFrameCountNV = (PFNWGLQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameCountNV")) == NULL) || r; - r = ((wglQueryMaxSwapGroupsNV = (PFNWGLQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryMaxSwapGroupsNV")) == NULL) || r; - r = ((wglQuerySwapGroupNV = (PFNWGLQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglQuerySwapGroupNV")) == NULL) || r; - r = ((wglResetFrameCountNV = (PFNWGLRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglResetFrameCountNV")) == NULL) || r; - - return r; -} - -#endif /* WGL_NV_swap_group */ - -#ifdef WGL_NV_vertex_array_range - -static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r; - r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r; - - return r; -} - -#endif /* WGL_NV_vertex_array_range */ - -#ifdef WGL_NV_video_output - -static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglBindVideoImageNV = (PFNWGLBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoImageNV")) == NULL) || r; - r = ((wglGetVideoDeviceNV = (PFNWGLGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoDeviceNV")) == NULL) || r; - r = ((wglGetVideoInfoNV = (PFNWGLGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoInfoNV")) == NULL) || r; - r = ((wglReleaseVideoDeviceNV = (PFNWGLRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoDeviceNV")) == NULL) || r; - r = ((wglReleaseVideoImageNV = (PFNWGLRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoImageNV")) == NULL) || r; - r = ((wglSendPbufferToVideoNV = (PFNWGLSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"wglSendPbufferToVideoNV")) == NULL) || r; - - return r; -} - -#endif /* WGL_NV_video_output */ - -#ifdef WGL_OML_sync_control - -static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r; - r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r; - r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r; - r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r; - r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r; - r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r; - - return r; -} - -#endif /* WGL_OML_sync_control */ - -/* ------------------------------------------------------------------------- */ - -static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL; -static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL; - -GLboolean wglewGetExtension (const char* name) -{ - GLubyte* p; - GLubyte* end; - GLuint len = _glewStrLen((const GLubyte*)name); - if (_wglewGetExtensionsStringARB == NULL) - if (_wglewGetExtensionsStringEXT == NULL) - return GL_FALSE; - else - p = (GLubyte*)_wglewGetExtensionsStringEXT(); - else - p = (GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); - if (0 == p) return GL_FALSE; - end = p + _glewStrLen(p); - while (p < end) - { - GLuint n = _glewStrCLen(p, ' '); - if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; - p += n+1; - } - return GL_FALSE; -} - -GLenum wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) -{ - GLboolean crippled; - /* find wgl extension string query functions */ - _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); - _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); - /* initialize extensions */ - crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; -#ifdef WGL_3DFX_multisample - CONST_CAST(WGLEW_3DFX_multisample) = wglewGetExtension("WGL_3DFX_multisample"); -#endif /* WGL_3DFX_multisample */ -#ifdef WGL_3DL_stereo_control - CONST_CAST(WGLEW_3DL_stereo_control) = wglewGetExtension("WGL_3DL_stereo_control"); - if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) CONST_CAST(WGLEW_3DL_stereo_control)= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_3DL_stereo_control */ -#ifdef WGL_ARB_buffer_region - CONST_CAST(WGLEW_ARB_buffer_region) = wglewGetExtension("WGL_ARB_buffer_region"); - if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) CONST_CAST(WGLEW_ARB_buffer_region)= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_buffer_region */ -#ifdef WGL_ARB_create_context - CONST_CAST(WGLEW_ARB_create_context) = wglewGetExtension("WGL_ARB_create_context"); - if (glewExperimental || WGLEW_ARB_create_context|| crippled) CONST_CAST(WGLEW_ARB_create_context)= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_create_context */ -#ifdef WGL_ARB_extensions_string - CONST_CAST(WGLEW_ARB_extensions_string) = wglewGetExtension("WGL_ARB_extensions_string"); - if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) CONST_CAST(WGLEW_ARB_extensions_string)= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_extensions_string */ -#ifdef WGL_ARB_framebuffer_sRGB - CONST_CAST(WGLEW_ARB_framebuffer_sRGB) = wglewGetExtension("WGL_ARB_framebuffer_sRGB"); -#endif /* WGL_ARB_framebuffer_sRGB */ -#ifdef WGL_ARB_make_current_read - CONST_CAST(WGLEW_ARB_make_current_read) = wglewGetExtension("WGL_ARB_make_current_read"); - if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) CONST_CAST(WGLEW_ARB_make_current_read)= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_make_current_read */ -#ifdef WGL_ARB_multisample - CONST_CAST(WGLEW_ARB_multisample) = wglewGetExtension("WGL_ARB_multisample"); -#endif /* WGL_ARB_multisample */ -#ifdef WGL_ARB_pbuffer - CONST_CAST(WGLEW_ARB_pbuffer) = wglewGetExtension("WGL_ARB_pbuffer"); - if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) CONST_CAST(WGLEW_ARB_pbuffer)= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_pbuffer */ -#ifdef WGL_ARB_pixel_format - CONST_CAST(WGLEW_ARB_pixel_format) = wglewGetExtension("WGL_ARB_pixel_format"); - if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) CONST_CAST(WGLEW_ARB_pixel_format)= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_pixel_format */ -#ifdef WGL_ARB_pixel_format_float - CONST_CAST(WGLEW_ARB_pixel_format_float) = wglewGetExtension("WGL_ARB_pixel_format_float"); -#endif /* WGL_ARB_pixel_format_float */ -#ifdef WGL_ARB_render_texture - CONST_CAST(WGLEW_ARB_render_texture) = wglewGetExtension("WGL_ARB_render_texture"); - if (glewExperimental || WGLEW_ARB_render_texture|| crippled) CONST_CAST(WGLEW_ARB_render_texture)= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_ARB_render_texture */ -#ifdef WGL_ATI_pixel_format_float - CONST_CAST(WGLEW_ATI_pixel_format_float) = wglewGetExtension("WGL_ATI_pixel_format_float"); -#endif /* WGL_ATI_pixel_format_float */ -#ifdef WGL_ATI_render_texture_rectangle - CONST_CAST(WGLEW_ATI_render_texture_rectangle) = wglewGetExtension("WGL_ATI_render_texture_rectangle"); -#endif /* WGL_ATI_render_texture_rectangle */ -#ifdef WGL_EXT_depth_float - CONST_CAST(WGLEW_EXT_depth_float) = wglewGetExtension("WGL_EXT_depth_float"); -#endif /* WGL_EXT_depth_float */ -#ifdef WGL_EXT_display_color_table - CONST_CAST(WGLEW_EXT_display_color_table) = wglewGetExtension("WGL_EXT_display_color_table"); - if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) CONST_CAST(WGLEW_EXT_display_color_table)= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_display_color_table */ -#ifdef WGL_EXT_extensions_string - CONST_CAST(WGLEW_EXT_extensions_string) = wglewGetExtension("WGL_EXT_extensions_string"); - if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) CONST_CAST(WGLEW_EXT_extensions_string)= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_extensions_string */ -#ifdef WGL_EXT_framebuffer_sRGB - CONST_CAST(WGLEW_EXT_framebuffer_sRGB) = wglewGetExtension("WGL_EXT_framebuffer_sRGB"); -#endif /* WGL_EXT_framebuffer_sRGB */ -#ifdef WGL_EXT_make_current_read - CONST_CAST(WGLEW_EXT_make_current_read) = wglewGetExtension("WGL_EXT_make_current_read"); - if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) CONST_CAST(WGLEW_EXT_make_current_read)= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_make_current_read */ -#ifdef WGL_EXT_multisample - CONST_CAST(WGLEW_EXT_multisample) = wglewGetExtension("WGL_EXT_multisample"); -#endif /* WGL_EXT_multisample */ -#ifdef WGL_EXT_pbuffer - CONST_CAST(WGLEW_EXT_pbuffer) = wglewGetExtension("WGL_EXT_pbuffer"); - if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) CONST_CAST(WGLEW_EXT_pbuffer)= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_pbuffer */ -#ifdef WGL_EXT_pixel_format - CONST_CAST(WGLEW_EXT_pixel_format) = wglewGetExtension("WGL_EXT_pixel_format"); - if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) CONST_CAST(WGLEW_EXT_pixel_format)= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_pixel_format */ -#ifdef WGL_EXT_pixel_format_packed_float - CONST_CAST(WGLEW_EXT_pixel_format_packed_float) = wglewGetExtension("WGL_EXT_pixel_format_packed_float"); -#endif /* WGL_EXT_pixel_format_packed_float */ -#ifdef WGL_EXT_swap_control - CONST_CAST(WGLEW_EXT_swap_control) = wglewGetExtension("WGL_EXT_swap_control"); - if (glewExperimental || WGLEW_EXT_swap_control|| crippled) CONST_CAST(WGLEW_EXT_swap_control)= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_EXT_swap_control */ -#ifdef WGL_I3D_digital_video_control - CONST_CAST(WGLEW_I3D_digital_video_control) = wglewGetExtension("WGL_I3D_digital_video_control"); - if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) CONST_CAST(WGLEW_I3D_digital_video_control)= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_digital_video_control */ -#ifdef WGL_I3D_gamma - CONST_CAST(WGLEW_I3D_gamma) = wglewGetExtension("WGL_I3D_gamma"); - if (glewExperimental || WGLEW_I3D_gamma|| crippled) CONST_CAST(WGLEW_I3D_gamma)= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_gamma */ -#ifdef WGL_I3D_genlock - CONST_CAST(WGLEW_I3D_genlock) = wglewGetExtension("WGL_I3D_genlock"); - if (glewExperimental || WGLEW_I3D_genlock|| crippled) CONST_CAST(WGLEW_I3D_genlock)= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_genlock */ -#ifdef WGL_I3D_image_buffer - CONST_CAST(WGLEW_I3D_image_buffer) = wglewGetExtension("WGL_I3D_image_buffer"); - if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) CONST_CAST(WGLEW_I3D_image_buffer)= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_image_buffer */ -#ifdef WGL_I3D_swap_frame_lock - CONST_CAST(WGLEW_I3D_swap_frame_lock) = wglewGetExtension("WGL_I3D_swap_frame_lock"); - if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_lock)= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_swap_frame_lock */ -#ifdef WGL_I3D_swap_frame_usage - CONST_CAST(WGLEW_I3D_swap_frame_usage) = wglewGetExtension("WGL_I3D_swap_frame_usage"); - if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_usage)= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_I3D_swap_frame_usage */ -#ifdef WGL_NV_float_buffer - CONST_CAST(WGLEW_NV_float_buffer) = wglewGetExtension("WGL_NV_float_buffer"); -#endif /* WGL_NV_float_buffer */ -#ifdef WGL_NV_gpu_affinity - CONST_CAST(WGLEW_NV_gpu_affinity) = wglewGetExtension("WGL_NV_gpu_affinity"); - if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) CONST_CAST(WGLEW_NV_gpu_affinity)= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_NV_gpu_affinity */ -#ifdef WGL_NV_present_video - CONST_CAST(WGLEW_NV_present_video) = wglewGetExtension("WGL_NV_present_video"); - if (glewExperimental || WGLEW_NV_present_video|| crippled) CONST_CAST(WGLEW_NV_present_video)= !_glewInit_WGL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_NV_present_video */ -#ifdef WGL_NV_render_depth_texture - CONST_CAST(WGLEW_NV_render_depth_texture) = wglewGetExtension("WGL_NV_render_depth_texture"); -#endif /* WGL_NV_render_depth_texture */ -#ifdef WGL_NV_render_texture_rectangle - CONST_CAST(WGLEW_NV_render_texture_rectangle) = wglewGetExtension("WGL_NV_render_texture_rectangle"); -#endif /* WGL_NV_render_texture_rectangle */ -#ifdef WGL_NV_swap_group - CONST_CAST(WGLEW_NV_swap_group) = wglewGetExtension("WGL_NV_swap_group"); - if (glewExperimental || WGLEW_NV_swap_group|| crippled) CONST_CAST(WGLEW_NV_swap_group)= !_glewInit_WGL_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_NV_swap_group */ -#ifdef WGL_NV_vertex_array_range - CONST_CAST(WGLEW_NV_vertex_array_range) = wglewGetExtension("WGL_NV_vertex_array_range"); - if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) CONST_CAST(WGLEW_NV_vertex_array_range)= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_NV_vertex_array_range */ -#ifdef WGL_NV_video_output - CONST_CAST(WGLEW_NV_video_output) = wglewGetExtension("WGL_NV_video_output"); - if (glewExperimental || WGLEW_NV_video_output|| crippled) CONST_CAST(WGLEW_NV_video_output)= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_NV_video_output */ -#ifdef WGL_OML_sync_control - CONST_CAST(WGLEW_OML_sync_control) = wglewGetExtension("WGL_OML_sync_control"); - if (glewExperimental || WGLEW_OML_sync_control|| crippled) CONST_CAST(WGLEW_OML_sync_control)= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* WGL_OML_sync_control */ - - return GLEW_OK; -} - -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - -PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL; - -PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL; -PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL; -PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL; -PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL; -PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL; -PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL; -PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL; -PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL; -PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL; -PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL; -PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL; -PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL; -PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL; -PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL; -PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL; -PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL; -PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL; - -PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB = NULL; - -PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL; -PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL; -PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL; - -PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL; -PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL; -PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL; -PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL; - -PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL; -PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL; - -PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL; - -PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL; - -PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL; - -PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL; - -PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL; - -PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL; -PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL; - -PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV = NULL; -PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV = NULL; -PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV = NULL; -PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV = NULL; -PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV = NULL; -PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV = NULL; - -PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL; -PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL; - -PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL; -PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL; -PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL; -PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL; -PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL; -PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL; - -#ifdef GLX_OML_sync_control -PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL; -PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL; -PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL; -PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL; -PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL; -#endif - -PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL; -PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL; -PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL; -PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL; -PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL; -PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL; - -PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX = NULL; -PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX = NULL; -PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX = NULL; -PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX = NULL; -PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX = NULL; -PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX = NULL; -PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX = NULL; -PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX = NULL; - -PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL; -PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL; -PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL; -PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL; -PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL; - -PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL; -PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL; - -PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL; - -PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL; -PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL; -PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL; -PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL; -PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL; - -PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL; - -PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL; -PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL; - -PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL; - -PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL; -PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL; - -PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL; - -PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL; -PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL; - -#if !defined(GLEW_MX) - -GLboolean __GLXEW_VERSION_1_0 = GL_FALSE; -GLboolean __GLXEW_VERSION_1_1 = GL_FALSE; -GLboolean __GLXEW_VERSION_1_2 = GL_FALSE; -GLboolean __GLXEW_VERSION_1_3 = GL_FALSE; -GLboolean __GLXEW_VERSION_1_4 = GL_FALSE; -GLboolean __GLXEW_3DFX_multisample = GL_FALSE; -GLboolean __GLXEW_ARB_create_context = GL_FALSE; -GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE; -GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE; -GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE; -GLboolean __GLXEW_ARB_multisample = GL_FALSE; -GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE; -GLboolean __GLXEW_ATI_render_texture = GL_FALSE; -GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE; -GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE; -GLboolean __GLXEW_EXT_import_context = GL_FALSE; -GLboolean __GLXEW_EXT_scene_marker = GL_FALSE; -GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE; -GLboolean __GLXEW_EXT_visual_info = GL_FALSE; -GLboolean __GLXEW_EXT_visual_rating = GL_FALSE; -GLboolean __GLXEW_MESA_agp_offset = GL_FALSE; -GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE; -GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE; -GLboolean __GLXEW_MESA_release_buffers = GL_FALSE; -GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE; -GLboolean __GLXEW_NV_float_buffer = GL_FALSE; -GLboolean __GLXEW_NV_present_video = GL_FALSE; -GLboolean __GLXEW_NV_swap_group = GL_FALSE; -GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE; -GLboolean __GLXEW_NV_video_output = GL_FALSE; -GLboolean __GLXEW_OML_swap_method = GL_FALSE; -#ifdef GLX_OML_sync_control -GLboolean __GLXEW_OML_sync_control = GL_FALSE; -#endif -GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE; -GLboolean __GLXEW_SGIS_color_range = GL_FALSE; -GLboolean __GLXEW_SGIS_multisample = GL_FALSE; -GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE; -GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE; -GLboolean __GLXEW_SGIX_hyperpipe = GL_FALSE; -GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE; -GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE; -GLboolean __GLXEW_SGIX_swap_group = GL_FALSE; -GLboolean __GLXEW_SGIX_video_resize = GL_FALSE; -GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE; -GLboolean __GLXEW_SGI_cushion = GL_FALSE; -GLboolean __GLXEW_SGI_make_current_read = GL_FALSE; -GLboolean __GLXEW_SGI_swap_control = GL_FALSE; -GLboolean __GLXEW_SGI_video_sync = GL_FALSE; -GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE; -GLboolean __GLXEW_SUN_video_resize = GL_FALSE; - -#endif /* !GLEW_MX */ - -#ifdef GLX_VERSION_1_2 - -static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r; - - return r; -} - -#endif /* GLX_VERSION_1_2 */ - -#ifdef GLX_VERSION_1_3 - -static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r; - r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r; - r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r; - r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r; - r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r; - r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r; - r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r; - r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r; - r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r; - r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r; - r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r; - r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r; - r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r; - r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r; - r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r; - r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r; - r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r; - - return r; -} - -#endif /* GLX_VERSION_1_3 */ - -#ifdef GLX_VERSION_1_4 - -#endif /* GLX_VERSION_1_4 */ - -#ifdef GLX_3DFX_multisample - -#endif /* GLX_3DFX_multisample */ - -#ifdef GLX_ARB_create_context - -static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB")) == NULL) || r; - - return r; -} - -#endif /* GLX_ARB_create_context */ - -#ifdef GLX_ARB_fbconfig_float - -#endif /* GLX_ARB_fbconfig_float */ - -#ifdef GLX_ARB_framebuffer_sRGB - -#endif /* GLX_ARB_framebuffer_sRGB */ - -#ifdef GLX_ARB_get_proc_address - -#endif /* GLX_ARB_get_proc_address */ - -#ifdef GLX_ARB_multisample - -#endif /* GLX_ARB_multisample */ - -#ifdef GLX_ATI_pixel_format_float - -#endif /* GLX_ATI_pixel_format_float */ - -#ifdef GLX_ATI_render_texture - -static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r; - r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r; - r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r; - - return r; -} - -#endif /* GLX_ATI_render_texture */ - -#ifdef GLX_EXT_fbconfig_packed_float - -#endif /* GLX_EXT_fbconfig_packed_float */ - -#ifdef GLX_EXT_framebuffer_sRGB - -#endif /* GLX_EXT_framebuffer_sRGB */ - -#ifdef GLX_EXT_import_context - -static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r; - r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r; - r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r; - r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r; - - return r; -} - -#endif /* GLX_EXT_import_context */ - -#ifdef GLX_EXT_scene_marker - -#endif /* GLX_EXT_scene_marker */ - -#ifdef GLX_EXT_texture_from_pixmap - -static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageEXT")) == NULL) || r; - r = ((glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageEXT")) == NULL) || r; - - return r; -} - -#endif /* GLX_EXT_texture_from_pixmap */ - -#ifdef GLX_EXT_visual_info - -#endif /* GLX_EXT_visual_info */ - -#ifdef GLX_EXT_visual_rating - -#endif /* GLX_EXT_visual_rating */ - -#ifdef GLX_MESA_agp_offset - -static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r; - - return r; -} - -#endif /* GLX_MESA_agp_offset */ - -#ifdef GLX_MESA_copy_sub_buffer - -static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r; - - return r; -} - -#endif /* GLX_MESA_copy_sub_buffer */ - -#ifdef GLX_MESA_pixmap_colormap - -static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r; - - return r; -} - -#endif /* GLX_MESA_pixmap_colormap */ - -#ifdef GLX_MESA_release_buffers - -static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r; - - return r; -} - -#endif /* GLX_MESA_release_buffers */ - -#ifdef GLX_MESA_set_3dfx_mode - -static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r; - - return r; -} - -#endif /* GLX_MESA_set_3dfx_mode */ - -#ifdef GLX_NV_float_buffer - -#endif /* GLX_NV_float_buffer */ - -#ifdef GLX_NV_present_video - -static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoDeviceNV")) == NULL) || r; - r = ((glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoDevicesNV")) == NULL) || r; - - return r; -} - -#endif /* GLX_NV_present_video */ - -#ifdef GLX_NV_swap_group - -static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierNV")) == NULL) || r; - r = ((glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupNV")) == NULL) || r; - r = ((glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryFrameCountNV")) == NULL) || r; - r = ((glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapGroupsNV")) == NULL) || r; - r = ((glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXQuerySwapGroupNV")) == NULL) || r; - r = ((glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXResetFrameCountNV")) == NULL) || r; - - return r; -} - -#endif /* GLX_NV_swap_group */ - -#ifdef GLX_NV_vertex_array_range - -static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r; - r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r; - - return r; -} - -#endif /* GLX_NV_vertex_array_range */ - -#ifdef GLX_NV_video_output - -static GLboolean _glewInit_GLX_NV_video_output (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoImageNV")) == NULL) || r; - r = ((glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoDeviceNV")) == NULL) || r; - r = ((glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoInfoNV")) == NULL) || r; - r = ((glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoDeviceNV")) == NULL) || r; - r = ((glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoImageNV")) == NULL) || r; - r = ((glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"glXSendPbufferToVideoNV")) == NULL) || r; - - return r; -} - -#endif /* GLX_NV_video_output */ - -#ifdef GLX_OML_swap_method - -#endif /* GLX_OML_swap_method */ - -#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#include - -static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r; - r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r; - r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r; - r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r; - r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r; - - return r; -} - -#endif /* GLX_OML_sync_control */ - -#ifdef GLX_SGIS_blended_overlay - -#endif /* GLX_SGIS_blended_overlay */ - -#ifdef GLX_SGIS_color_range - -#endif /* GLX_SGIS_color_range */ - -#ifdef GLX_SGIS_multisample - -#endif /* GLX_SGIS_multisample */ - -#ifdef GLX_SGIS_shared_multisample - -#endif /* GLX_SGIS_shared_multisample */ - -#ifdef GLX_SGIX_fbconfig - -static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r; - r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r; - r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r; - r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r; - r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r; - r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_fbconfig */ - -#ifdef GLX_SGIX_hyperpipe - -static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindHyperpipeSGIX")) == NULL) || r; - r = ((glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyHyperpipeConfigSGIX")) == NULL) || r; - r = ((glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeAttribSGIX")) == NULL) || r; - r = ((glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeConfigSGIX")) == NULL) || r; - r = ((glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeAttribSGIX")) == NULL) || r; - r = ((glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeBestAttribSGIX")) == NULL) || r; - r = ((glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeConfigSGIX")) == NULL) || r; - r = ((glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeNetworkSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_hyperpipe */ - -#ifdef GLX_SGIX_pbuffer - -static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r; - r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r; - r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r; - r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r; - r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_pbuffer */ - -#ifdef GLX_SGIX_swap_barrier - -static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r; - r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_swap_barrier */ - -#ifdef GLX_SGIX_swap_group - -static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_swap_group */ - -#ifdef GLX_SGIX_video_resize - -static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r; - r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r; - r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r; - r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r; - r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGIX_video_resize */ - -#ifdef GLX_SGIX_visual_select_group - -#endif /* GLX_SGIX_visual_select_group */ - -#ifdef GLX_SGI_cushion - -static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGI_cushion */ - -#ifdef GLX_SGI_make_current_read - -static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r; - r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGI_make_current_read */ - -#ifdef GLX_SGI_swap_control - -static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGI_swap_control */ - -#ifdef GLX_SGI_video_sync - -static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r; - r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r; - - return r; -} - -#endif /* GLX_SGI_video_sync */ - -#ifdef GLX_SUN_get_transparent_index - -static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r; - - return r; -} - -#endif /* GLX_SUN_get_transparent_index */ - -#ifdef GLX_SUN_video_resize - -static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) -{ - GLboolean r = GL_FALSE; - - r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r; - r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r; - - return r; -} - -#endif /* GLX_SUN_video_resize */ - -/* ------------------------------------------------------------------------ */ - -GLboolean glxewGetExtension (const char* name) -{ - GLubyte* p; - GLubyte* end; - GLuint len = _glewStrLen((const GLubyte*)name); -/* if (glXQueryExtensionsString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; */ -/* p = (GLubyte*)glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay())); */ - if (glXGetClientString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; - p = (GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); - if (0 == p) return GL_FALSE; - end = p + _glewStrLen(p); - while (p < end) - { - GLuint n = _glewStrCLen(p, ' '); - if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; - p += n+1; - } - return GL_FALSE; -} - -GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) -{ - int major, minor; - /* initialize core GLX 1.2 */ - if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY; - /* initialize flags */ - CONST_CAST(GLXEW_VERSION_1_0) = GL_TRUE; - CONST_CAST(GLXEW_VERSION_1_1) = GL_TRUE; - CONST_CAST(GLXEW_VERSION_1_2) = GL_TRUE; - CONST_CAST(GLXEW_VERSION_1_3) = GL_TRUE; - CONST_CAST(GLXEW_VERSION_1_4) = GL_TRUE; - /* query GLX version */ - glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); - if (major == 1 && minor <= 3) - { - switch (minor) - { - case 3: - CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; - break; - case 2: - CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; - CONST_CAST(GLXEW_VERSION_1_3) = GL_FALSE; - break; - default: - return GLEW_ERROR_GLX_VERSION_11_ONLY; - break; - } - } - /* initialize extensions */ -#ifdef GLX_VERSION_1_3 - if (glewExperimental || GLXEW_VERSION_1_3) CONST_CAST(GLXEW_VERSION_1_3) = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_VERSION_1_3 */ -#ifdef GLX_3DFX_multisample - CONST_CAST(GLXEW_3DFX_multisample) = glxewGetExtension("GLX_3DFX_multisample"); -#endif /* GLX_3DFX_multisample */ -#ifdef GLX_ARB_create_context - CONST_CAST(GLXEW_ARB_create_context) = glxewGetExtension("GLX_ARB_create_context"); - if (glewExperimental || GLXEW_ARB_create_context) CONST_CAST(GLXEW_ARB_create_context) = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_ARB_create_context */ -#ifdef GLX_ARB_fbconfig_float - CONST_CAST(GLXEW_ARB_fbconfig_float) = glxewGetExtension("GLX_ARB_fbconfig_float"); -#endif /* GLX_ARB_fbconfig_float */ -#ifdef GLX_ARB_framebuffer_sRGB - CONST_CAST(GLXEW_ARB_framebuffer_sRGB) = glxewGetExtension("GLX_ARB_framebuffer_sRGB"); -#endif /* GLX_ARB_framebuffer_sRGB */ -#ifdef GLX_ARB_get_proc_address - CONST_CAST(GLXEW_ARB_get_proc_address) = glxewGetExtension("GLX_ARB_get_proc_address"); -#endif /* GLX_ARB_get_proc_address */ -#ifdef GLX_ARB_multisample - CONST_CAST(GLXEW_ARB_multisample) = glxewGetExtension("GLX_ARB_multisample"); -#endif /* GLX_ARB_multisample */ -#ifdef GLX_ATI_pixel_format_float - CONST_CAST(GLXEW_ATI_pixel_format_float) = glxewGetExtension("GLX_ATI_pixel_format_float"); -#endif /* GLX_ATI_pixel_format_float */ -#ifdef GLX_ATI_render_texture - CONST_CAST(GLXEW_ATI_render_texture) = glxewGetExtension("GLX_ATI_render_texture"); - if (glewExperimental || GLXEW_ATI_render_texture) CONST_CAST(GLXEW_ATI_render_texture) = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_ATI_render_texture */ -#ifdef GLX_EXT_fbconfig_packed_float - CONST_CAST(GLXEW_EXT_fbconfig_packed_float) = glxewGetExtension("GLX_EXT_fbconfig_packed_float"); -#endif /* GLX_EXT_fbconfig_packed_float */ -#ifdef GLX_EXT_framebuffer_sRGB - CONST_CAST(GLXEW_EXT_framebuffer_sRGB) = glxewGetExtension("GLX_EXT_framebuffer_sRGB"); -#endif /* GLX_EXT_framebuffer_sRGB */ -#ifdef GLX_EXT_import_context - CONST_CAST(GLXEW_EXT_import_context) = glxewGetExtension("GLX_EXT_import_context"); - if (glewExperimental || GLXEW_EXT_import_context) CONST_CAST(GLXEW_EXT_import_context) = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_EXT_import_context */ -#ifdef GLX_EXT_scene_marker - CONST_CAST(GLXEW_EXT_scene_marker) = glxewGetExtension("GLX_EXT_scene_marker"); -#endif /* GLX_EXT_scene_marker */ -#ifdef GLX_EXT_texture_from_pixmap - CONST_CAST(GLXEW_EXT_texture_from_pixmap) = glxewGetExtension("GLX_EXT_texture_from_pixmap"); - if (glewExperimental || GLXEW_EXT_texture_from_pixmap) CONST_CAST(GLXEW_EXT_texture_from_pixmap) = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_EXT_texture_from_pixmap */ -#ifdef GLX_EXT_visual_info - CONST_CAST(GLXEW_EXT_visual_info) = glxewGetExtension("GLX_EXT_visual_info"); -#endif /* GLX_EXT_visual_info */ -#ifdef GLX_EXT_visual_rating - CONST_CAST(GLXEW_EXT_visual_rating) = glxewGetExtension("GLX_EXT_visual_rating"); -#endif /* GLX_EXT_visual_rating */ -#ifdef GLX_MESA_agp_offset - CONST_CAST(GLXEW_MESA_agp_offset) = glxewGetExtension("GLX_MESA_agp_offset"); - if (glewExperimental || GLXEW_MESA_agp_offset) CONST_CAST(GLXEW_MESA_agp_offset) = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_MESA_agp_offset */ -#ifdef GLX_MESA_copy_sub_buffer - CONST_CAST(GLXEW_MESA_copy_sub_buffer) = glxewGetExtension("GLX_MESA_copy_sub_buffer"); - if (glewExperimental || GLXEW_MESA_copy_sub_buffer) CONST_CAST(GLXEW_MESA_copy_sub_buffer) = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_MESA_copy_sub_buffer */ -#ifdef GLX_MESA_pixmap_colormap - CONST_CAST(GLXEW_MESA_pixmap_colormap) = glxewGetExtension("GLX_MESA_pixmap_colormap"); - if (glewExperimental || GLXEW_MESA_pixmap_colormap) CONST_CAST(GLXEW_MESA_pixmap_colormap) = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_MESA_pixmap_colormap */ -#ifdef GLX_MESA_release_buffers - CONST_CAST(GLXEW_MESA_release_buffers) = glxewGetExtension("GLX_MESA_release_buffers"); - if (glewExperimental || GLXEW_MESA_release_buffers) CONST_CAST(GLXEW_MESA_release_buffers) = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_MESA_release_buffers */ -#ifdef GLX_MESA_set_3dfx_mode - CONST_CAST(GLXEW_MESA_set_3dfx_mode) = glxewGetExtension("GLX_MESA_set_3dfx_mode"); - if (glewExperimental || GLXEW_MESA_set_3dfx_mode) CONST_CAST(GLXEW_MESA_set_3dfx_mode) = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_MESA_set_3dfx_mode */ -#ifdef GLX_NV_float_buffer - CONST_CAST(GLXEW_NV_float_buffer) = glxewGetExtension("GLX_NV_float_buffer"); -#endif /* GLX_NV_float_buffer */ -#ifdef GLX_NV_present_video - CONST_CAST(GLXEW_NV_present_video) = glxewGetExtension("GLX_NV_present_video"); - if (glewExperimental || GLXEW_NV_present_video) CONST_CAST(GLXEW_NV_present_video) = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_NV_present_video */ -#ifdef GLX_NV_swap_group - CONST_CAST(GLXEW_NV_swap_group) = glxewGetExtension("GLX_NV_swap_group"); - if (glewExperimental || GLXEW_NV_swap_group) CONST_CAST(GLXEW_NV_swap_group) = !_glewInit_GLX_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_NV_swap_group */ -#ifdef GLX_NV_vertex_array_range - CONST_CAST(GLXEW_NV_vertex_array_range) = glxewGetExtension("GLX_NV_vertex_array_range"); - if (glewExperimental || GLXEW_NV_vertex_array_range) CONST_CAST(GLXEW_NV_vertex_array_range) = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_NV_vertex_array_range */ -#ifdef GLX_NV_video_output - CONST_CAST(GLXEW_NV_video_output) = glxewGetExtension("GLX_NV_video_output"); - if (glewExperimental || GLXEW_NV_video_output) CONST_CAST(GLXEW_NV_video_output) = !_glewInit_GLX_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_NV_video_output */ -#ifdef GLX_OML_swap_method - CONST_CAST(GLXEW_OML_swap_method) = glxewGetExtension("GLX_OML_swap_method"); -#endif /* GLX_OML_swap_method */ -#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#include - CONST_CAST(GLXEW_OML_sync_control) = glxewGetExtension("GLX_OML_sync_control"); - if (glewExperimental || GLXEW_OML_sync_control) CONST_CAST(GLXEW_OML_sync_control) = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_OML_sync_control */ -#ifdef GLX_SGIS_blended_overlay - CONST_CAST(GLXEW_SGIS_blended_overlay) = glxewGetExtension("GLX_SGIS_blended_overlay"); -#endif /* GLX_SGIS_blended_overlay */ -#ifdef GLX_SGIS_color_range - CONST_CAST(GLXEW_SGIS_color_range) = glxewGetExtension("GLX_SGIS_color_range"); -#endif /* GLX_SGIS_color_range */ -#ifdef GLX_SGIS_multisample - CONST_CAST(GLXEW_SGIS_multisample) = glxewGetExtension("GLX_SGIS_multisample"); -#endif /* GLX_SGIS_multisample */ -#ifdef GLX_SGIS_shared_multisample - CONST_CAST(GLXEW_SGIS_shared_multisample) = glxewGetExtension("GLX_SGIS_shared_multisample"); -#endif /* GLX_SGIS_shared_multisample */ -#ifdef GLX_SGIX_fbconfig - CONST_CAST(GLXEW_SGIX_fbconfig) = glxewGetExtension("GLX_SGIX_fbconfig"); - if (glewExperimental || GLXEW_SGIX_fbconfig) CONST_CAST(GLXEW_SGIX_fbconfig) = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_fbconfig */ -#ifdef GLX_SGIX_hyperpipe - CONST_CAST(GLXEW_SGIX_hyperpipe) = glxewGetExtension("GLX_SGIX_hyperpipe"); - if (glewExperimental || GLXEW_SGIX_hyperpipe) CONST_CAST(GLXEW_SGIX_hyperpipe) = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_hyperpipe */ -#ifdef GLX_SGIX_pbuffer - CONST_CAST(GLXEW_SGIX_pbuffer) = glxewGetExtension("GLX_SGIX_pbuffer"); - if (glewExperimental || GLXEW_SGIX_pbuffer) CONST_CAST(GLXEW_SGIX_pbuffer) = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_pbuffer */ -#ifdef GLX_SGIX_swap_barrier - CONST_CAST(GLXEW_SGIX_swap_barrier) = glxewGetExtension("GLX_SGIX_swap_barrier"); - if (glewExperimental || GLXEW_SGIX_swap_barrier) CONST_CAST(GLXEW_SGIX_swap_barrier) = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_swap_barrier */ -#ifdef GLX_SGIX_swap_group - CONST_CAST(GLXEW_SGIX_swap_group) = glxewGetExtension("GLX_SGIX_swap_group"); - if (glewExperimental || GLXEW_SGIX_swap_group) CONST_CAST(GLXEW_SGIX_swap_group) = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_swap_group */ -#ifdef GLX_SGIX_video_resize - CONST_CAST(GLXEW_SGIX_video_resize) = glxewGetExtension("GLX_SGIX_video_resize"); - if (glewExperimental || GLXEW_SGIX_video_resize) CONST_CAST(GLXEW_SGIX_video_resize) = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGIX_video_resize */ -#ifdef GLX_SGIX_visual_select_group - CONST_CAST(GLXEW_SGIX_visual_select_group) = glxewGetExtension("GLX_SGIX_visual_select_group"); -#endif /* GLX_SGIX_visual_select_group */ -#ifdef GLX_SGI_cushion - CONST_CAST(GLXEW_SGI_cushion) = glxewGetExtension("GLX_SGI_cushion"); - if (glewExperimental || GLXEW_SGI_cushion) CONST_CAST(GLXEW_SGI_cushion) = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGI_cushion */ -#ifdef GLX_SGI_make_current_read - CONST_CAST(GLXEW_SGI_make_current_read) = glxewGetExtension("GLX_SGI_make_current_read"); - if (glewExperimental || GLXEW_SGI_make_current_read) CONST_CAST(GLXEW_SGI_make_current_read) = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGI_make_current_read */ -#ifdef GLX_SGI_swap_control - CONST_CAST(GLXEW_SGI_swap_control) = glxewGetExtension("GLX_SGI_swap_control"); - if (glewExperimental || GLXEW_SGI_swap_control) CONST_CAST(GLXEW_SGI_swap_control) = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGI_swap_control */ -#ifdef GLX_SGI_video_sync - CONST_CAST(GLXEW_SGI_video_sync) = glxewGetExtension("GLX_SGI_video_sync"); - if (glewExperimental || GLXEW_SGI_video_sync) CONST_CAST(GLXEW_SGI_video_sync) = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SGI_video_sync */ -#ifdef GLX_SUN_get_transparent_index - CONST_CAST(GLXEW_SUN_get_transparent_index) = glxewGetExtension("GLX_SUN_get_transparent_index"); - if (glewExperimental || GLXEW_SUN_get_transparent_index) CONST_CAST(GLXEW_SUN_get_transparent_index) = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SUN_get_transparent_index */ -#ifdef GLX_SUN_video_resize - CONST_CAST(GLXEW_SUN_video_resize) = glxewGetExtension("GLX_SUN_video_resize"); - if (glewExperimental || GLXEW_SUN_video_resize) CONST_CAST(GLXEW_SUN_video_resize) = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GLX_SUN_video_resize */ - - return GLEW_OK; -} - -#endif /* !__APPLE__ || GLEW_APPLE_GLX */ - -/* ------------------------------------------------------------------------ */ - -const GLubyte* glewGetErrorString (GLenum error) -{ - static const GLubyte* _glewErrorString[] = - { - (const GLubyte*)"No error", - (const GLubyte*)"Missing GL version", - (const GLubyte*)"GL 1.1 and up are not supported", - (const GLubyte*)"GLX 1.2 and up are not supported", - (const GLubyte*)"Unknown error" - }; - const int max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; - return _glewErrorString[(int)error > max_error ? max_error : (int)error]; -} - -const GLubyte* glewGetString (GLenum name) -{ - static const GLubyte* _glewString[] = - { - (const GLubyte*)NULL, - (const GLubyte*)"1.5.1", - (const GLubyte*)"1", - (const GLubyte*)"5", - (const GLubyte*)"1" - }; - const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; - return _glewString[(int)name > max_string ? 0 : (int)name]; -} - -/* ------------------------------------------------------------------------ */ - -GLboolean glewExperimental = GL_FALSE; - -#if !defined(GLEW_MX) - -#if defined(_WIN32) -extern GLenum wglewContextInit (void); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ -extern GLenum glxewContextInit (void); -#endif /* _WIN32 */ - -GLenum glewInit () -{ - GLenum r; - if ( (r = glewContextInit()) ) return r; -#if defined(_WIN32) - return wglewContextInit(); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ - return glxewContextInit(); -#else - return r; -#endif /* _WIN32 */ -} - -#endif /* !GLEW_MX */ -#ifdef GLEW_MX -GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name) -#else -GLboolean glewIsSupported (const char* name) -#endif -{ - GLubyte* pos = (GLubyte*)name; - GLuint len = _glewStrLen(pos); - GLboolean ret = GL_TRUE; - while (ret && len > 0) - { - if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3)) - { - if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) - { -#ifdef GL_VERSION_1_2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) - { - ret = GLEW_VERSION_1_2; - continue; - } -#endif -#ifdef GL_VERSION_1_3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) - { - ret = GLEW_VERSION_1_3; - continue; - } -#endif -#ifdef GL_VERSION_1_4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) - { - ret = GLEW_VERSION_1_4; - continue; - } -#endif -#ifdef GL_VERSION_1_5 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3)) - { - ret = GLEW_VERSION_1_5; - continue; - } -#endif -#ifdef GL_VERSION_2_0 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3)) - { - ret = GLEW_VERSION_2_0; - continue; - } -#endif -#ifdef GL_VERSION_2_1 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3)) - { - ret = GLEW_VERSION_2_1; - continue; - } -#endif -#ifdef GL_VERSION_3_0 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3)) - { - ret = GLEW_VERSION_3_0; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) - { -#ifdef GL_3DFX_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLEW_3DFX_multisample; - continue; - } -#endif -#ifdef GL_3DFX_tbuffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7)) - { - ret = GLEW_3DFX_tbuffer; - continue; - } -#endif -#ifdef GL_3DFX_texture_compression_FXT1 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24)) - { - ret = GLEW_3DFX_texture_compression_FXT1; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) - { -#ifdef GL_APPLE_client_storage - if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14)) - { - ret = GLEW_APPLE_client_storage; - continue; - } -#endif -#ifdef GL_APPLE_element_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) - { - ret = GLEW_APPLE_element_array; - continue; - } -#endif -#ifdef GL_APPLE_fence - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) - { - ret = GLEW_APPLE_fence; - continue; - } -#endif -#ifdef GL_APPLE_float_pixels - if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12)) - { - ret = GLEW_APPLE_float_pixels; - continue; - } -#endif -#ifdef GL_APPLE_flush_buffer_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18)) - { - ret = GLEW_APPLE_flush_buffer_range; - continue; - } -#endif -#ifdef GL_APPLE_pixel_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12)) - { - ret = GLEW_APPLE_pixel_buffer; - continue; - } -#endif -#ifdef GL_APPLE_specular_vector - if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15)) - { - ret = GLEW_APPLE_specular_vector; - continue; - } -#endif -#ifdef GL_APPLE_texture_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) - { - ret = GLEW_APPLE_texture_range; - continue; - } -#endif -#ifdef GL_APPLE_transform_hint - if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14)) - { - ret = GLEW_APPLE_transform_hint; - continue; - } -#endif -#ifdef GL_APPLE_vertex_array_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) - { - ret = GLEW_APPLE_vertex_array_object; - continue; - } -#endif -#ifdef GL_APPLE_vertex_array_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) - { - ret = GLEW_APPLE_vertex_array_range; - continue; - } -#endif -#ifdef GL_APPLE_ycbcr_422 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9)) - { - ret = GLEW_APPLE_ycbcr_422; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) - { -#ifdef GL_ARB_color_buffer_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) - { - ret = GLEW_ARB_color_buffer_float; - continue; - } -#endif -#ifdef GL_ARB_depth_buffer_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) - { - ret = GLEW_ARB_depth_buffer_float; - continue; - } -#endif -#ifdef GL_ARB_depth_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) - { - ret = GLEW_ARB_depth_texture; - continue; - } -#endif -#ifdef GL_ARB_draw_buffers - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) - { - ret = GLEW_ARB_draw_buffers; - continue; - } -#endif -#ifdef GL_ARB_draw_instanced - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) - { - ret = GLEW_ARB_draw_instanced; - continue; - } -#endif -#ifdef GL_ARB_fragment_program - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) - { - ret = GLEW_ARB_fragment_program; - continue; - } -#endif -#ifdef GL_ARB_fragment_program_shadow - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23)) - { - ret = GLEW_ARB_fragment_program_shadow; - continue; - } -#endif -#ifdef GL_ARB_fragment_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) - { - ret = GLEW_ARB_fragment_shader; - continue; - } -#endif -#ifdef GL_ARB_framebuffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) - { - ret = GLEW_ARB_framebuffer_object; - continue; - } -#endif -#ifdef GL_ARB_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = GLEW_ARB_framebuffer_sRGB; - continue; - } -#endif -#ifdef GL_ARB_geometry_shader4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) - { - ret = GLEW_ARB_geometry_shader4; - continue; - } -#endif -#ifdef GL_ARB_half_float_pixel - if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16)) - { - ret = GLEW_ARB_half_float_pixel; - continue; - } -#endif -#ifdef GL_ARB_half_float_vertex - if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17)) - { - ret = GLEW_ARB_half_float_vertex; - continue; - } -#endif -#ifdef GL_ARB_imaging - if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7)) - { - ret = GLEW_ARB_imaging; - continue; - } -#endif -#ifdef GL_ARB_instanced_arrays - if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) - { - ret = GLEW_ARB_instanced_arrays; - continue; - } -#endif -#ifdef GL_ARB_map_buffer_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16)) - { - ret = GLEW_ARB_map_buffer_range; - continue; - } -#endif -#ifdef GL_ARB_matrix_palette - if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14)) - { - ret = GLEW_ARB_matrix_palette; - continue; - } -#endif -#ifdef GL_ARB_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLEW_ARB_multisample; - continue; - } -#endif -#ifdef GL_ARB_multitexture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) - { - ret = GLEW_ARB_multitexture; - continue; - } -#endif -#ifdef GL_ARB_occlusion_query - if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) - { - ret = GLEW_ARB_occlusion_query; - continue; - } -#endif -#ifdef GL_ARB_pixel_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) - { - ret = GLEW_ARB_pixel_buffer_object; - continue; - } -#endif -#ifdef GL_ARB_point_parameters - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) - { - ret = GLEW_ARB_point_parameters; - continue; - } -#endif -#ifdef GL_ARB_point_sprite - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) - { - ret = GLEW_ARB_point_sprite; - continue; - } -#endif -#ifdef GL_ARB_shader_objects - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14)) - { - ret = GLEW_ARB_shader_objects; - continue; - } -#endif -#ifdef GL_ARB_shading_language_100 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20)) - { - ret = GLEW_ARB_shading_language_100; - continue; - } -#endif -#ifdef GL_ARB_shadow - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) - { - ret = GLEW_ARB_shadow; - continue; - } -#endif -#ifdef GL_ARB_shadow_ambient - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) - { - ret = GLEW_ARB_shadow_ambient; - continue; - } -#endif -#ifdef GL_ARB_texture_border_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) - { - ret = GLEW_ARB_texture_border_clamp; - continue; - } -#endif -#ifdef GL_ARB_texture_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) - { - ret = GLEW_ARB_texture_buffer_object; - continue; - } -#endif -#ifdef GL_ARB_texture_compression - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19)) - { - ret = GLEW_ARB_texture_compression; - continue; - } -#endif -#ifdef GL_ARB_texture_compression_rgtc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) - { - ret = GLEW_ARB_texture_compression_rgtc; - continue; - } -#endif -#ifdef GL_ARB_texture_cube_map - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) - { - ret = GLEW_ARB_texture_cube_map; - continue; - } -#endif -#ifdef GL_ARB_texture_env_add - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) - { - ret = GLEW_ARB_texture_env_add; - continue; - } -#endif -#ifdef GL_ARB_texture_env_combine - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) - { - ret = GLEW_ARB_texture_env_combine; - continue; - } -#endif -#ifdef GL_ARB_texture_env_crossbar - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20)) - { - ret = GLEW_ARB_texture_env_crossbar; - continue; - } -#endif -#ifdef GL_ARB_texture_env_dot3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) - { - ret = GLEW_ARB_texture_env_dot3; - continue; - } -#endif -#ifdef GL_ARB_texture_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) - { - ret = GLEW_ARB_texture_float; - continue; - } -#endif -#ifdef GL_ARB_texture_mirrored_repeat - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) - { - ret = GLEW_ARB_texture_mirrored_repeat; - continue; - } -#endif -#ifdef GL_ARB_texture_non_power_of_two - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24)) - { - ret = GLEW_ARB_texture_non_power_of_two; - continue; - } -#endif -#ifdef GL_ARB_texture_rectangle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) - { - ret = GLEW_ARB_texture_rectangle; - continue; - } -#endif -#ifdef GL_ARB_texture_rg - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10)) - { - ret = GLEW_ARB_texture_rg; - continue; - } -#endif -#ifdef GL_ARB_transpose_matrix - if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16)) - { - ret = GLEW_ARB_transpose_matrix; - continue; - } -#endif -#ifdef GL_ARB_vertex_array_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) - { - ret = GLEW_ARB_vertex_array_object; - continue; - } -#endif -#ifdef GL_ARB_vertex_blend - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12)) - { - ret = GLEW_ARB_vertex_blend; - continue; - } -#endif -#ifdef GL_ARB_vertex_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) - { - ret = GLEW_ARB_vertex_buffer_object; - continue; - } -#endif -#ifdef GL_ARB_vertex_program - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) - { - ret = GLEW_ARB_vertex_program; - continue; - } -#endif -#ifdef GL_ARB_vertex_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) - { - ret = GLEW_ARB_vertex_shader; - continue; - } -#endif -#ifdef GL_ARB_window_pos - if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) - { - ret = GLEW_ARB_window_pos; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5)) - { -#ifdef GL_ATIX_point_sprites - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13)) - { - ret = GLEW_ATIX_point_sprites; - continue; - } -#endif -#ifdef GL_ATIX_texture_env_combine3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) - { - ret = GLEW_ATIX_texture_env_combine3; - continue; - } -#endif -#ifdef GL_ATIX_texture_env_route - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17)) - { - ret = GLEW_ATIX_texture_env_route; - continue; - } -#endif -#ifdef GL_ATIX_vertex_shader_output_point_size - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31)) - { - ret = GLEW_ATIX_vertex_shader_output_point_size; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) - { -#ifdef GL_ATI_draw_buffers - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) - { - ret = GLEW_ATI_draw_buffers; - continue; - } -#endif -#ifdef GL_ATI_element_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) - { - ret = GLEW_ATI_element_array; - continue; - } -#endif -#ifdef GL_ATI_envmap_bumpmap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14)) - { - ret = GLEW_ATI_envmap_bumpmap; - continue; - } -#endif -#ifdef GL_ATI_fragment_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) - { - ret = GLEW_ATI_fragment_shader; - continue; - } -#endif -#ifdef GL_ATI_map_object_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17)) - { - ret = GLEW_ATI_map_object_buffer; - continue; - } -#endif -#ifdef GL_ATI_pn_triangles - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12)) - { - ret = GLEW_ATI_pn_triangles; - continue; - } -#endif -#ifdef GL_ATI_separate_stencil - if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16)) - { - ret = GLEW_ATI_separate_stencil; - continue; - } -#endif -#ifdef GL_ATI_shader_texture_lod - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) - { - ret = GLEW_ATI_shader_texture_lod; - continue; - } -#endif -#ifdef GL_ATI_text_fragment_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20)) - { - ret = GLEW_ATI_text_fragment_shader; - continue; - } -#endif -#ifdef GL_ATI_texture_compression_3dc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23)) - { - ret = GLEW_ATI_texture_compression_3dc; - continue; - } -#endif -#ifdef GL_ATI_texture_env_combine3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) - { - ret = GLEW_ATI_texture_env_combine3; - continue; - } -#endif -#ifdef GL_ATI_texture_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) - { - ret = GLEW_ATI_texture_float; - continue; - } -#endif -#ifdef GL_ATI_texture_mirror_once - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19)) - { - ret = GLEW_ATI_texture_mirror_once; - continue; - } -#endif -#ifdef GL_ATI_vertex_array_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) - { - ret = GLEW_ATI_vertex_array_object; - continue; - } -#endif -#ifdef GL_ATI_vertex_attrib_array_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26)) - { - ret = GLEW_ATI_vertex_attrib_array_object; - continue; - } -#endif -#ifdef GL_ATI_vertex_streams - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14)) - { - ret = GLEW_ATI_vertex_streams; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) - { -#ifdef GL_EXT_422_pixels - if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10)) - { - ret = GLEW_EXT_422_pixels; - continue; - } -#endif -#ifdef GL_EXT_Cg_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9)) - { - ret = GLEW_EXT_Cg_shader; - continue; - } -#endif -#ifdef GL_EXT_abgr - if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4)) - { - ret = GLEW_EXT_abgr; - continue; - } -#endif -#ifdef GL_EXT_bgra - if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4)) - { - ret = GLEW_EXT_bgra; - continue; - } -#endif -#ifdef GL_EXT_bindable_uniform - if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16)) - { - ret = GLEW_EXT_bindable_uniform; - continue; - } -#endif -#ifdef GL_EXT_blend_color - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11)) - { - ret = GLEW_EXT_blend_color; - continue; - } -#endif -#ifdef GL_EXT_blend_equation_separate - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23)) - { - ret = GLEW_EXT_blend_equation_separate; - continue; - } -#endif -#ifdef GL_EXT_blend_func_separate - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19)) - { - ret = GLEW_EXT_blend_func_separate; - continue; - } -#endif -#ifdef GL_EXT_blend_logic_op - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14)) - { - ret = GLEW_EXT_blend_logic_op; - continue; - } -#endif -#ifdef GL_EXT_blend_minmax - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12)) - { - ret = GLEW_EXT_blend_minmax; - continue; - } -#endif -#ifdef GL_EXT_blend_subtract - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14)) - { - ret = GLEW_EXT_blend_subtract; - continue; - } -#endif -#ifdef GL_EXT_clip_volume_hint - if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16)) - { - ret = GLEW_EXT_clip_volume_hint; - continue; - } -#endif -#ifdef GL_EXT_cmyka - if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5)) - { - ret = GLEW_EXT_cmyka; - continue; - } -#endif -#ifdef GL_EXT_color_subtable - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14)) - { - ret = GLEW_EXT_color_subtable; - continue; - } -#endif -#ifdef GL_EXT_compiled_vertex_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21)) - { - ret = GLEW_EXT_compiled_vertex_array; - continue; - } -#endif -#ifdef GL_EXT_convolution - if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11)) - { - ret = GLEW_EXT_convolution; - continue; - } -#endif -#ifdef GL_EXT_coordinate_frame - if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16)) - { - ret = GLEW_EXT_coordinate_frame; - continue; - } -#endif -#ifdef GL_EXT_copy_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12)) - { - ret = GLEW_EXT_copy_texture; - continue; - } -#endif -#ifdef GL_EXT_cull_vertex - if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) - { - ret = GLEW_EXT_cull_vertex; - continue; - } -#endif -#ifdef GL_EXT_depth_bounds_test - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17)) - { - ret = GLEW_EXT_depth_bounds_test; - continue; - } -#endif -#ifdef GL_EXT_direct_state_access - if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19)) - { - ret = GLEW_EXT_direct_state_access; - continue; - } -#endif -#ifdef GL_EXT_draw_buffers2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13)) - { - ret = GLEW_EXT_draw_buffers2; - continue; - } -#endif -#ifdef GL_EXT_draw_instanced - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) - { - ret = GLEW_EXT_draw_instanced; - continue; - } -#endif -#ifdef GL_EXT_draw_range_elements - if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19)) - { - ret = GLEW_EXT_draw_range_elements; - continue; - } -#endif -#ifdef GL_EXT_fog_coord - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9)) - { - ret = GLEW_EXT_fog_coord; - continue; - } -#endif -#ifdef GL_EXT_fragment_lighting - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17)) - { - ret = GLEW_EXT_fragment_lighting; - continue; - } -#endif -#ifdef GL_EXT_framebuffer_blit - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) - { - ret = GLEW_EXT_framebuffer_blit; - continue; - } -#endif -#ifdef GL_EXT_framebuffer_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) - { - ret = GLEW_EXT_framebuffer_multisample; - continue; - } -#endif -#ifdef GL_EXT_framebuffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) - { - ret = GLEW_EXT_framebuffer_object; - continue; - } -#endif -#ifdef GL_EXT_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = GLEW_EXT_framebuffer_sRGB; - continue; - } -#endif -#ifdef GL_EXT_geometry_shader4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) - { - ret = GLEW_EXT_geometry_shader4; - continue; - } -#endif -#ifdef GL_EXT_gpu_program_parameters - if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22)) - { - ret = GLEW_EXT_gpu_program_parameters; - continue; - } -#endif -#ifdef GL_EXT_gpu_shader4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11)) - { - ret = GLEW_EXT_gpu_shader4; - continue; - } -#endif -#ifdef GL_EXT_histogram - if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9)) - { - ret = GLEW_EXT_histogram; - continue; - } -#endif -#ifdef GL_EXT_index_array_formats - if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19)) - { - ret = GLEW_EXT_index_array_formats; - continue; - } -#endif -#ifdef GL_EXT_index_func - if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10)) - { - ret = GLEW_EXT_index_func; - continue; - } -#endif -#ifdef GL_EXT_index_material - if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14)) - { - ret = GLEW_EXT_index_material; - continue; - } -#endif -#ifdef GL_EXT_index_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13)) - { - ret = GLEW_EXT_index_texture; - continue; - } -#endif -#ifdef GL_EXT_light_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13)) - { - ret = GLEW_EXT_light_texture; - continue; - } -#endif -#ifdef GL_EXT_misc_attribute - if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14)) - { - ret = GLEW_EXT_misc_attribute; - continue; - } -#endif -#ifdef GL_EXT_multi_draw_arrays - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17)) - { - ret = GLEW_EXT_multi_draw_arrays; - continue; - } -#endif -#ifdef GL_EXT_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLEW_EXT_multisample; - continue; - } -#endif -#ifdef GL_EXT_packed_depth_stencil - if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) - { - ret = GLEW_EXT_packed_depth_stencil; - continue; - } -#endif -#ifdef GL_EXT_packed_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12)) - { - ret = GLEW_EXT_packed_float; - continue; - } -#endif -#ifdef GL_EXT_packed_pixels - if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13)) - { - ret = GLEW_EXT_packed_pixels; - continue; - } -#endif -#ifdef GL_EXT_paletted_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16)) - { - ret = GLEW_EXT_paletted_texture; - continue; - } -#endif -#ifdef GL_EXT_pixel_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) - { - ret = GLEW_EXT_pixel_buffer_object; - continue; - } -#endif -#ifdef GL_EXT_pixel_transform - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15)) - { - ret = GLEW_EXT_pixel_transform; - continue; - } -#endif -#ifdef GL_EXT_pixel_transform_color_table - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27)) - { - ret = GLEW_EXT_pixel_transform_color_table; - continue; - } -#endif -#ifdef GL_EXT_point_parameters - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) - { - ret = GLEW_EXT_point_parameters; - continue; - } -#endif -#ifdef GL_EXT_polygon_offset - if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14)) - { - ret = GLEW_EXT_polygon_offset; - continue; - } -#endif -#ifdef GL_EXT_rescale_normal - if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14)) - { - ret = GLEW_EXT_rescale_normal; - continue; - } -#endif -#ifdef GL_EXT_scene_marker - if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) - { - ret = GLEW_EXT_scene_marker; - continue; - } -#endif -#ifdef GL_EXT_secondary_color - if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15)) - { - ret = GLEW_EXT_secondary_color; - continue; - } -#endif -#ifdef GL_EXT_separate_specular_color - if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23)) - { - ret = GLEW_EXT_separate_specular_color; - continue; - } -#endif -#ifdef GL_EXT_shadow_funcs - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12)) - { - ret = GLEW_EXT_shadow_funcs; - continue; - } -#endif -#ifdef GL_EXT_shared_texture_palette - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22)) - { - ret = GLEW_EXT_shared_texture_palette; - continue; - } -#endif -#ifdef GL_EXT_stencil_clear_tag - if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17)) - { - ret = GLEW_EXT_stencil_clear_tag; - continue; - } -#endif -#ifdef GL_EXT_stencil_two_side - if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16)) - { - ret = GLEW_EXT_stencil_two_side; - continue; - } -#endif -#ifdef GL_EXT_stencil_wrap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12)) - { - ret = GLEW_EXT_stencil_wrap; - continue; - } -#endif -#ifdef GL_EXT_subtexture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10)) - { - ret = GLEW_EXT_subtexture; - continue; - } -#endif -#ifdef GL_EXT_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7)) - { - ret = GLEW_EXT_texture; - continue; - } -#endif -#ifdef GL_EXT_texture3D - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9)) - { - ret = GLEW_EXT_texture3D; - continue; - } -#endif -#ifdef GL_EXT_texture_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13)) - { - ret = GLEW_EXT_texture_array; - continue; - } -#endif -#ifdef GL_EXT_texture_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) - { - ret = GLEW_EXT_texture_buffer_object; - continue; - } -#endif -#ifdef GL_EXT_texture_compression_dxt1 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) - { - ret = GLEW_EXT_texture_compression_dxt1; - continue; - } -#endif -#ifdef GL_EXT_texture_compression_latc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24)) - { - ret = GLEW_EXT_texture_compression_latc; - continue; - } -#endif -#ifdef GL_EXT_texture_compression_rgtc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) - { - ret = GLEW_EXT_texture_compression_rgtc; - continue; - } -#endif -#ifdef GL_EXT_texture_compression_s3tc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) - { - ret = GLEW_EXT_texture_compression_s3tc; - continue; - } -#endif -#ifdef GL_EXT_texture_cube_map - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) - { - ret = GLEW_EXT_texture_cube_map; - continue; - } -#endif -#ifdef GL_EXT_texture_edge_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) - { - ret = GLEW_EXT_texture_edge_clamp; - continue; - } -#endif -#ifdef GL_EXT_texture_env - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11)) - { - ret = GLEW_EXT_texture_env; - continue; - } -#endif -#ifdef GL_EXT_texture_env_add - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) - { - ret = GLEW_EXT_texture_env_add; - continue; - } -#endif -#ifdef GL_EXT_texture_env_combine - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) - { - ret = GLEW_EXT_texture_env_combine; - continue; - } -#endif -#ifdef GL_EXT_texture_env_dot3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) - { - ret = GLEW_EXT_texture_env_dot3; - continue; - } -#endif -#ifdef GL_EXT_texture_filter_anisotropic - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) - { - ret = GLEW_EXT_texture_filter_anisotropic; - continue; - } -#endif -#ifdef GL_EXT_texture_integer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15)) - { - ret = GLEW_EXT_texture_integer; - continue; - } -#endif -#ifdef GL_EXT_texture_lod_bias - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) - { - ret = GLEW_EXT_texture_lod_bias; - continue; - } -#endif -#ifdef GL_EXT_texture_mirror_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20)) - { - ret = GLEW_EXT_texture_mirror_clamp; - continue; - } -#endif -#ifdef GL_EXT_texture_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14)) - { - ret = GLEW_EXT_texture_object; - continue; - } -#endif -#ifdef GL_EXT_texture_perturb_normal - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22)) - { - ret = GLEW_EXT_texture_perturb_normal; - continue; - } -#endif -#ifdef GL_EXT_texture_rectangle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) - { - ret = GLEW_EXT_texture_rectangle; - continue; - } -#endif -#ifdef GL_EXT_texture_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12)) - { - ret = GLEW_EXT_texture_sRGB; - continue; - } -#endif -#ifdef GL_EXT_texture_shared_exponent - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23)) - { - ret = GLEW_EXT_texture_shared_exponent; - continue; - } -#endif -#ifdef GL_EXT_texture_swizzle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) - { - ret = GLEW_EXT_texture_swizzle; - continue; - } -#endif -#ifdef GL_EXT_timer_query - if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) - { - ret = GLEW_EXT_timer_query; - continue; - } -#endif -#ifdef GL_EXT_transform_feedback - if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) - { - ret = GLEW_EXT_transform_feedback; - continue; - } -#endif -#ifdef GL_EXT_vertex_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12)) - { - ret = GLEW_EXT_vertex_array; - continue; - } -#endif -#ifdef GL_EXT_vertex_array_bgra - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) - { - ret = GLEW_EXT_vertex_array_bgra; - continue; - } -#endif -#ifdef GL_EXT_vertex_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) - { - ret = GLEW_EXT_vertex_shader; - continue; - } -#endif -#ifdef GL_EXT_vertex_weighting - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16)) - { - ret = GLEW_EXT_vertex_weighting; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8)) - { -#ifdef GL_GREMEDY_frame_terminator - if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16)) - { - ret = GLEW_GREMEDY_frame_terminator; - continue; - } -#endif -#ifdef GL_GREMEDY_string_marker - if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13)) - { - ret = GLEW_GREMEDY_string_marker; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3)) - { -#ifdef GL_HP_convolution_border_modes - if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) - { - ret = GLEW_HP_convolution_border_modes; - continue; - } -#endif -#ifdef GL_HP_image_transform - if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15)) - { - ret = GLEW_HP_image_transform; - continue; - } -#endif -#ifdef GL_HP_occlusion_test - if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14)) - { - ret = GLEW_HP_occlusion_test; - continue; - } -#endif -#ifdef GL_HP_texture_lighting - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16)) - { - ret = GLEW_HP_texture_lighting; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4)) - { -#ifdef GL_IBM_cull_vertex - if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) - { - ret = GLEW_IBM_cull_vertex; - continue; - } -#endif -#ifdef GL_IBM_multimode_draw_arrays - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21)) - { - ret = GLEW_IBM_multimode_draw_arrays; - continue; - } -#endif -#ifdef GL_IBM_rasterpos_clip - if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14)) - { - ret = GLEW_IBM_rasterpos_clip; - continue; - } -#endif -#ifdef GL_IBM_static_data - if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11)) - { - ret = GLEW_IBM_static_data; - continue; - } -#endif -#ifdef GL_IBM_texture_mirrored_repeat - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) - { - ret = GLEW_IBM_texture_mirrored_repeat; - continue; - } -#endif -#ifdef GL_IBM_vertex_array_lists - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18)) - { - ret = GLEW_IBM_vertex_array_lists; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5)) - { -#ifdef GL_INGR_color_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11)) - { - ret = GLEW_INGR_color_clamp; - continue; - } -#endif -#ifdef GL_INGR_interlace_read - if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14)) - { - ret = GLEW_INGR_interlace_read; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6)) - { -#ifdef GL_INTEL_parallel_arrays - if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) - { - ret = GLEW_INTEL_parallel_arrays; - continue; - } -#endif -#ifdef GL_INTEL_texture_scissor - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15)) - { - ret = GLEW_INTEL_texture_scissor; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4)) - { -#ifdef GL_KTX_buffer_region - if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) - { - ret = GLEW_KTX_buffer_region; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6)) - { -#ifdef GL_MESAX_texture_stack - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13)) - { - ret = GLEW_MESAX_texture_stack; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) - { -#ifdef GL_MESA_pack_invert - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11)) - { - ret = GLEW_MESA_pack_invert; - continue; - } -#endif -#ifdef GL_MESA_resize_buffers - if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14)) - { - ret = GLEW_MESA_resize_buffers; - continue; - } -#endif -#ifdef GL_MESA_window_pos - if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) - { - ret = GLEW_MESA_window_pos; - continue; - } -#endif -#ifdef GL_MESA_ycbcr_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13)) - { - ret = GLEW_MESA_ycbcr_texture; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) - { -#ifdef GL_NV_blend_square - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) - { - ret = GLEW_NV_blend_square; - continue; - } -#endif -#ifdef GL_NV_conditional_render - if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) - { - ret = GLEW_NV_conditional_render; - continue; - } -#endif -#ifdef GL_NV_copy_depth_to_color - if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19)) - { - ret = GLEW_NV_copy_depth_to_color; - continue; - } -#endif -#ifdef GL_NV_depth_buffer_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) - { - ret = GLEW_NV_depth_buffer_float; - continue; - } -#endif -#ifdef GL_NV_depth_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) - { - ret = GLEW_NV_depth_clamp; - continue; - } -#endif -#ifdef GL_NV_depth_range_unclamped - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21)) - { - ret = GLEW_NV_depth_range_unclamped; - continue; - } -#endif -#ifdef GL_NV_evaluators - if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10)) - { - ret = GLEW_NV_evaluators; - continue; - } -#endif -#ifdef GL_NV_explicit_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20)) - { - ret = GLEW_NV_explicit_multisample; - continue; - } -#endif -#ifdef GL_NV_fence - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) - { - ret = GLEW_NV_fence; - continue; - } -#endif -#ifdef GL_NV_float_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) - { - ret = GLEW_NV_float_buffer; - continue; - } -#endif -#ifdef GL_NV_fog_distance - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12)) - { - ret = GLEW_NV_fog_distance; - continue; - } -#endif -#ifdef GL_NV_fragment_program - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) - { - ret = GLEW_NV_fragment_program; - continue; - } -#endif -#ifdef GL_NV_fragment_program2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17)) - { - ret = GLEW_NV_fragment_program2; - continue; - } -#endif -#ifdef GL_NV_fragment_program4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17)) - { - ret = GLEW_NV_fragment_program4; - continue; - } -#endif -#ifdef GL_NV_fragment_program_option - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23)) - { - ret = GLEW_NV_fragment_program_option; - continue; - } -#endif -#ifdef GL_NV_framebuffer_multisample_coverage - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32)) - { - ret = GLEW_NV_framebuffer_multisample_coverage; - continue; - } -#endif -#ifdef GL_NV_geometry_program4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17)) - { - ret = GLEW_NV_geometry_program4; - continue; - } -#endif -#ifdef GL_NV_geometry_shader4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) - { - ret = GLEW_NV_geometry_shader4; - continue; - } -#endif -#ifdef GL_NV_gpu_program4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12)) - { - ret = GLEW_NV_gpu_program4; - continue; - } -#endif -#ifdef GL_NV_half_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10)) - { - ret = GLEW_NV_half_float; - continue; - } -#endif -#ifdef GL_NV_light_max_exponent - if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18)) - { - ret = GLEW_NV_light_max_exponent; - continue; - } -#endif -#ifdef GL_NV_multisample_filter_hint - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23)) - { - ret = GLEW_NV_multisample_filter_hint; - continue; - } -#endif -#ifdef GL_NV_occlusion_query - if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) - { - ret = GLEW_NV_occlusion_query; - continue; - } -#endif -#ifdef GL_NV_packed_depth_stencil - if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) - { - ret = GLEW_NV_packed_depth_stencil; - continue; - } -#endif -#ifdef GL_NV_parameter_buffer_object - if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23)) - { - ret = GLEW_NV_parameter_buffer_object; - continue; - } -#endif -#ifdef GL_NV_pixel_data_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16)) - { - ret = GLEW_NV_pixel_data_range; - continue; - } -#endif -#ifdef GL_NV_point_sprite - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) - { - ret = GLEW_NV_point_sprite; - continue; - } -#endif -#ifdef GL_NV_present_video - if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) - { - ret = GLEW_NV_present_video; - continue; - } -#endif -#ifdef GL_NV_primitive_restart - if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17)) - { - ret = GLEW_NV_primitive_restart; - continue; - } -#endif -#ifdef GL_NV_register_combiners - if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18)) - { - ret = GLEW_NV_register_combiners; - continue; - } -#endif -#ifdef GL_NV_register_combiners2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19)) - { - ret = GLEW_NV_register_combiners2; - continue; - } -#endif -#ifdef GL_NV_texgen_emboss - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13)) - { - ret = GLEW_NV_texgen_emboss; - continue; - } -#endif -#ifdef GL_NV_texgen_reflection - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17)) - { - ret = GLEW_NV_texgen_reflection; - continue; - } -#endif -#ifdef GL_NV_texture_compression_vtc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23)) - { - ret = GLEW_NV_texture_compression_vtc; - continue; - } -#endif -#ifdef GL_NV_texture_env_combine4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20)) - { - ret = GLEW_NV_texture_env_combine4; - continue; - } -#endif -#ifdef GL_NV_texture_expand_normal - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21)) - { - ret = GLEW_NV_texture_expand_normal; - continue; - } -#endif -#ifdef GL_NV_texture_rectangle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) - { - ret = GLEW_NV_texture_rectangle; - continue; - } -#endif -#ifdef GL_NV_texture_shader - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14)) - { - ret = GLEW_NV_texture_shader; - continue; - } -#endif -#ifdef GL_NV_texture_shader2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15)) - { - ret = GLEW_NV_texture_shader2; - continue; - } -#endif -#ifdef GL_NV_texture_shader3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15)) - { - ret = GLEW_NV_texture_shader3; - continue; - } -#endif -#ifdef GL_NV_transform_feedback - if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) - { - ret = GLEW_NV_transform_feedback; - continue; - } -#endif -#ifdef GL_NV_vertex_array_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) - { - ret = GLEW_NV_vertex_array_range; - continue; - } -#endif -#ifdef GL_NV_vertex_array_range2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19)) - { - ret = GLEW_NV_vertex_array_range2; - continue; - } -#endif -#ifdef GL_NV_vertex_program - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) - { - ret = GLEW_NV_vertex_program; - continue; - } -#endif -#ifdef GL_NV_vertex_program1_1 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17)) - { - ret = GLEW_NV_vertex_program1_1; - continue; - } -#endif -#ifdef GL_NV_vertex_program2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15)) - { - ret = GLEW_NV_vertex_program2; - continue; - } -#endif -#ifdef GL_NV_vertex_program2_option - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22)) - { - ret = GLEW_NV_vertex_program2_option; - continue; - } -#endif -#ifdef GL_NV_vertex_program3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15)) - { - ret = GLEW_NV_vertex_program3; - continue; - } -#endif -#ifdef GL_NV_vertex_program4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15)) - { - ret = GLEW_NV_vertex_program4; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4)) - { -#ifdef GL_OES_byte_coordinates - if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16)) - { - ret = GLEW_OES_byte_coordinates; - continue; - } -#endif -#ifdef GL_OES_compressed_paletted_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_paletted_texture", 27)) - { - ret = GLEW_OES_compressed_paletted_texture; - continue; - } -#endif -#ifdef GL_OES_read_format - if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format", 11)) - { - ret = GLEW_OES_read_format; - continue; - } -#endif -#ifdef GL_OES_single_precision - if (_glewStrSame3(&pos, &len, (const GLubyte*)"single_precision", 16)) - { - ret = GLEW_OES_single_precision; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) - { -#ifdef GL_OML_interlace - if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) - { - ret = GLEW_OML_interlace; - continue; - } -#endif -#ifdef GL_OML_resample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) - { - ret = GLEW_OML_resample; - continue; - } -#endif -#ifdef GL_OML_subsample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) - { - ret = GLEW_OML_subsample; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4)) - { -#ifdef GL_PGI_misc_hints - if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10)) - { - ret = GLEW_PGI_misc_hints; - continue; - } -#endif -#ifdef GL_PGI_vertex_hints - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12)) - { - ret = GLEW_PGI_vertex_hints; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5)) - { -#ifdef GL_REND_screen_coordinates - if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18)) - { - ret = GLEW_REND_screen_coordinates; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3)) - { -#ifdef GL_S3_s3tc - if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4)) - { - ret = GLEW_S3_s3tc; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) - { -#ifdef GL_SGIS_color_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) - { - ret = GLEW_SGIS_color_range; - continue; - } -#endif -#ifdef GL_SGIS_detail_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14)) - { - ret = GLEW_SGIS_detail_texture; - continue; - } -#endif -#ifdef GL_SGIS_fog_function - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12)) - { - ret = GLEW_SGIS_fog_function; - continue; - } -#endif -#ifdef GL_SGIS_generate_mipmap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15)) - { - ret = GLEW_SGIS_generate_mipmap; - continue; - } -#endif -#ifdef GL_SGIS_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLEW_SGIS_multisample; - continue; - } -#endif -#ifdef GL_SGIS_pixel_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) - { - ret = GLEW_SGIS_pixel_texture; - continue; - } -#endif -#ifdef GL_SGIS_point_line_texgen - if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17)) - { - ret = GLEW_SGIS_point_line_texgen; - continue; - } -#endif -#ifdef GL_SGIS_sharpen_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15)) - { - ret = GLEW_SGIS_sharpen_texture; - continue; - } -#endif -#ifdef GL_SGIS_texture4D - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9)) - { - ret = GLEW_SGIS_texture4D; - continue; - } -#endif -#ifdef GL_SGIS_texture_border_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) - { - ret = GLEW_SGIS_texture_border_clamp; - continue; - } -#endif -#ifdef GL_SGIS_texture_edge_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) - { - ret = GLEW_SGIS_texture_edge_clamp; - continue; - } -#endif -#ifdef GL_SGIS_texture_filter4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15)) - { - ret = GLEW_SGIS_texture_filter4; - continue; - } -#endif -#ifdef GL_SGIS_texture_lod - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11)) - { - ret = GLEW_SGIS_texture_lod; - continue; - } -#endif -#ifdef GL_SGIS_texture_select - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14)) - { - ret = GLEW_SGIS_texture_select; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) - { -#ifdef GL_SGIX_async - if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5)) - { - ret = GLEW_SGIX_async; - continue; - } -#endif -#ifdef GL_SGIX_async_histogram - if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15)) - { - ret = GLEW_SGIX_async_histogram; - continue; - } -#endif -#ifdef GL_SGIX_async_pixel - if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11)) - { - ret = GLEW_SGIX_async_pixel; - continue; - } -#endif -#ifdef GL_SGIX_blend_alpha_minmax - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18)) - { - ret = GLEW_SGIX_blend_alpha_minmax; - continue; - } -#endif -#ifdef GL_SGIX_clipmap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7)) - { - ret = GLEW_SGIX_clipmap; - continue; - } -#endif -#ifdef GL_SGIX_convolution_accuracy - if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20)) - { - ret = GLEW_SGIX_convolution_accuracy; - continue; - } -#endif -#ifdef GL_SGIX_depth_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) - { - ret = GLEW_SGIX_depth_texture; - continue; - } -#endif -#ifdef GL_SGIX_flush_raster - if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12)) - { - ret = GLEW_SGIX_flush_raster; - continue; - } -#endif -#ifdef GL_SGIX_fog_offset - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10)) - { - ret = GLEW_SGIX_fog_offset; - continue; - } -#endif -#ifdef GL_SGIX_fog_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11)) - { - ret = GLEW_SGIX_fog_texture; - continue; - } -#endif -#ifdef GL_SGIX_fragment_specular_lighting - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26)) - { - ret = GLEW_SGIX_fragment_specular_lighting; - continue; - } -#endif -#ifdef GL_SGIX_framezoom - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9)) - { - ret = GLEW_SGIX_framezoom; - continue; - } -#endif -#ifdef GL_SGIX_interlace - if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) - { - ret = GLEW_SGIX_interlace; - continue; - } -#endif -#ifdef GL_SGIX_ir_instrument1 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14)) - { - ret = GLEW_SGIX_ir_instrument1; - continue; - } -#endif -#ifdef GL_SGIX_list_priority - if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13)) - { - ret = GLEW_SGIX_list_priority; - continue; - } -#endif -#ifdef GL_SGIX_pixel_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) - { - ret = GLEW_SGIX_pixel_texture; - continue; - } -#endif -#ifdef GL_SGIX_pixel_texture_bits - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18)) - { - ret = GLEW_SGIX_pixel_texture_bits; - continue; - } -#endif -#ifdef GL_SGIX_reference_plane - if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15)) - { - ret = GLEW_SGIX_reference_plane; - continue; - } -#endif -#ifdef GL_SGIX_resample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) - { - ret = GLEW_SGIX_resample; - continue; - } -#endif -#ifdef GL_SGIX_shadow - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) - { - ret = GLEW_SGIX_shadow; - continue; - } -#endif -#ifdef GL_SGIX_shadow_ambient - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) - { - ret = GLEW_SGIX_shadow_ambient; - continue; - } -#endif -#ifdef GL_SGIX_sprite - if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6)) - { - ret = GLEW_SGIX_sprite; - continue; - } -#endif -#ifdef GL_SGIX_tag_sample_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17)) - { - ret = GLEW_SGIX_tag_sample_buffer; - continue; - } -#endif -#ifdef GL_SGIX_texture_add_env - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15)) - { - ret = GLEW_SGIX_texture_add_env; - continue; - } -#endif -#ifdef GL_SGIX_texture_coordinate_clamp - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24)) - { - ret = GLEW_SGIX_texture_coordinate_clamp; - continue; - } -#endif -#ifdef GL_SGIX_texture_lod_bias - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) - { - ret = GLEW_SGIX_texture_lod_bias; - continue; - } -#endif -#ifdef GL_SGIX_texture_multi_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20)) - { - ret = GLEW_SGIX_texture_multi_buffer; - continue; - } -#endif -#ifdef GL_SGIX_texture_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) - { - ret = GLEW_SGIX_texture_range; - continue; - } -#endif -#ifdef GL_SGIX_texture_scale_bias - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18)) - { - ret = GLEW_SGIX_texture_scale_bias; - continue; - } -#endif -#ifdef GL_SGIX_vertex_preclip - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14)) - { - ret = GLEW_SGIX_vertex_preclip; - continue; - } -#endif -#ifdef GL_SGIX_vertex_preclip_hint - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19)) - { - ret = GLEW_SGIX_vertex_preclip_hint; - continue; - } -#endif -#ifdef GL_SGIX_ycrcb - if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5)) - { - ret = GLEW_SGIX_ycrcb; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) - { -#ifdef GL_SGI_color_matrix - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12)) - { - ret = GLEW_SGI_color_matrix; - continue; - } -#endif -#ifdef GL_SGI_color_table - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11)) - { - ret = GLEW_SGI_color_table; - continue; - } -#endif -#ifdef GL_SGI_texture_color_table - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19)) - { - ret = GLEW_SGI_texture_color_table; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5)) - { -#ifdef GL_SUNX_constant_data - if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13)) - { - ret = GLEW_SUNX_constant_data; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) - { -#ifdef GL_SUN_convolution_border_modes - if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) - { - ret = GLEW_SUN_convolution_border_modes; - continue; - } -#endif -#ifdef GL_SUN_global_alpha - if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12)) - { - ret = GLEW_SUN_global_alpha; - continue; - } -#endif -#ifdef GL_SUN_mesh_array - if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10)) - { - ret = GLEW_SUN_mesh_array; - continue; - } -#endif -#ifdef GL_SUN_read_video_pixels - if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17)) - { - ret = GLEW_SUN_read_video_pixels; - continue; - } -#endif -#ifdef GL_SUN_slice_accum - if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11)) - { - ret = GLEW_SUN_slice_accum; - continue; - } -#endif -#ifdef GL_SUN_triangle_list - if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13)) - { - ret = GLEW_SUN_triangle_list; - continue; - } -#endif -#ifdef GL_SUN_vertex - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6)) - { - ret = GLEW_SUN_vertex; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4)) - { -#ifdef GL_WIN_phong_shading - if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13)) - { - ret = GLEW_WIN_phong_shading; - continue; - } -#endif -#ifdef GL_WIN_specular_fog - if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12)) - { - ret = GLEW_WIN_specular_fog; - continue; - } -#endif -#ifdef GL_WIN_swap_hint - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9)) - { - ret = GLEW_WIN_swap_hint; - continue; - } -#endif - } - } - ret = (len == 0); - } - return ret; -} - -#if defined(_WIN32) - -#if defined(GLEW_MX) -GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name) -#else -GLboolean wglewIsSupported (const char* name) -#endif -{ - GLubyte* pos = (GLubyte*)name; - GLuint len = _glewStrLen(pos); - GLboolean ret = GL_TRUE; - while (ret && len > 0) - { - if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4)) - { - if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) - { -#ifdef WGL_3DFX_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = WGLEW_3DFX_multisample; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4)) - { -#ifdef WGL_3DL_stereo_control - if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14)) - { - ret = WGLEW_3DL_stereo_control; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) - { -#ifdef WGL_ARB_buffer_region - if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) - { - ret = WGLEW_ARB_buffer_region; - continue; - } -#endif -#ifdef WGL_ARB_create_context - if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) - { - ret = WGLEW_ARB_create_context; - continue; - } -#endif -#ifdef WGL_ARB_extensions_string - if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) - { - ret = WGLEW_ARB_extensions_string; - continue; - } -#endif -#ifdef WGL_ARB_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = WGLEW_ARB_framebuffer_sRGB; - continue; - } -#endif -#ifdef WGL_ARB_make_current_read - if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) - { - ret = WGLEW_ARB_make_current_read; - continue; - } -#endif -#ifdef WGL_ARB_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = WGLEW_ARB_multisample; - continue; - } -#endif -#ifdef WGL_ARB_pbuffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) - { - ret = WGLEW_ARB_pbuffer; - continue; - } -#endif -#ifdef WGL_ARB_pixel_format - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) - { - ret = WGLEW_ARB_pixel_format; - continue; - } -#endif -#ifdef WGL_ARB_pixel_format_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) - { - ret = WGLEW_ARB_pixel_format_float; - continue; - } -#endif -#ifdef WGL_ARB_render_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) - { - ret = WGLEW_ARB_render_texture; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) - { -#ifdef WGL_ATI_pixel_format_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) - { - ret = WGLEW_ATI_pixel_format_float; - continue; - } -#endif -#ifdef WGL_ATI_render_texture_rectangle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) - { - ret = WGLEW_ATI_render_texture_rectangle; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) - { -#ifdef WGL_EXT_depth_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11)) - { - ret = WGLEW_EXT_depth_float; - continue; - } -#endif -#ifdef WGL_EXT_display_color_table - if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19)) - { - ret = WGLEW_EXT_display_color_table; - continue; - } -#endif -#ifdef WGL_EXT_extensions_string - if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) - { - ret = WGLEW_EXT_extensions_string; - continue; - } -#endif -#ifdef WGL_EXT_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = WGLEW_EXT_framebuffer_sRGB; - continue; - } -#endif -#ifdef WGL_EXT_make_current_read - if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) - { - ret = WGLEW_EXT_make_current_read; - continue; - } -#endif -#ifdef WGL_EXT_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = WGLEW_EXT_multisample; - continue; - } -#endif -#ifdef WGL_EXT_pbuffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) - { - ret = WGLEW_EXT_pbuffer; - continue; - } -#endif -#ifdef WGL_EXT_pixel_format - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) - { - ret = WGLEW_EXT_pixel_format; - continue; - } -#endif -#ifdef WGL_EXT_pixel_format_packed_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_packed_float", 25)) - { - ret = WGLEW_EXT_pixel_format_packed_float; - continue; - } -#endif -#ifdef WGL_EXT_swap_control - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) - { - ret = WGLEW_EXT_swap_control; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4)) - { -#ifdef WGL_I3D_digital_video_control - if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21)) - { - ret = WGLEW_I3D_digital_video_control; - continue; - } -#endif -#ifdef WGL_I3D_gamma - if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5)) - { - ret = WGLEW_I3D_gamma; - continue; - } -#endif -#ifdef WGL_I3D_genlock - if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7)) - { - ret = WGLEW_I3D_genlock; - continue; - } -#endif -#ifdef WGL_I3D_image_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12)) - { - ret = WGLEW_I3D_image_buffer; - continue; - } -#endif -#ifdef WGL_I3D_swap_frame_lock - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15)) - { - ret = WGLEW_I3D_swap_frame_lock; - continue; - } -#endif -#ifdef WGL_I3D_swap_frame_usage - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16)) - { - ret = WGLEW_I3D_swap_frame_usage; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) - { -#ifdef WGL_NV_float_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) - { - ret = WGLEW_NV_float_buffer; - continue; - } -#endif -#ifdef WGL_NV_gpu_affinity - if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_affinity", 12)) - { - ret = WGLEW_NV_gpu_affinity; - continue; - } -#endif -#ifdef WGL_NV_present_video - if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) - { - ret = WGLEW_NV_present_video; - continue; - } -#endif -#ifdef WGL_NV_render_depth_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20)) - { - ret = WGLEW_NV_render_depth_texture; - continue; - } -#endif -#ifdef WGL_NV_render_texture_rectangle - if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) - { - ret = WGLEW_NV_render_texture_rectangle; - continue; - } -#endif -#ifdef WGL_NV_swap_group - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) - { - ret = WGLEW_NV_swap_group; - continue; - } -#endif -#ifdef WGL_NV_vertex_array_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) - { - ret = WGLEW_NV_vertex_array_range; - continue; - } -#endif -#ifdef WGL_NV_video_output - if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) - { - ret = WGLEW_NV_video_output; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) - { -#ifdef WGL_OML_sync_control - if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) - { - ret = WGLEW_OML_sync_control; - continue; - } -#endif - } - } - ret = (len == 0); - } - return ret; -} - -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - -#if defined(GLEW_MX) -GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name) -#else -GLboolean glxewIsSupported (const char* name) -#endif -{ - GLubyte* pos = (GLubyte*)name; - GLuint len = _glewStrLen(pos); - GLboolean ret = GL_TRUE; - while (ret && len > 0) - { - if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4)) - { - if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) - { -#ifdef GLX_VERSION_1_2 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) - { - ret = GLXEW_VERSION_1_2; - continue; - } -#endif -#ifdef GLX_VERSION_1_3 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) - { - ret = GLXEW_VERSION_1_3; - continue; - } -#endif -#ifdef GLX_VERSION_1_4 - if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) - { - ret = GLXEW_VERSION_1_4; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) - { -#ifdef GLX_3DFX_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLXEW_3DFX_multisample; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) - { -#ifdef GLX_ARB_create_context - if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) - { - ret = GLXEW_ARB_create_context; - continue; - } -#endif -#ifdef GLX_ARB_fbconfig_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14)) - { - ret = GLXEW_ARB_fbconfig_float; - continue; - } -#endif -#ifdef GLX_ARB_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = GLXEW_ARB_framebuffer_sRGB; - continue; - } -#endif -#ifdef GLX_ARB_get_proc_address - if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16)) - { - ret = GLXEW_ARB_get_proc_address; - continue; - } -#endif -#ifdef GLX_ARB_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLXEW_ARB_multisample; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) - { -#ifdef GLX_ATI_pixel_format_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) - { - ret = GLXEW_ATI_pixel_format_float; - continue; - } -#endif -#ifdef GLX_ATI_render_texture - if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) - { - ret = GLXEW_ATI_render_texture; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) - { -#ifdef GLX_EXT_fbconfig_packed_float - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_packed_float", 21)) - { - ret = GLXEW_EXT_fbconfig_packed_float; - continue; - } -#endif -#ifdef GLX_EXT_framebuffer_sRGB - if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) - { - ret = GLXEW_EXT_framebuffer_sRGB; - continue; - } -#endif -#ifdef GLX_EXT_import_context - if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14)) - { - ret = GLXEW_EXT_import_context; - continue; - } -#endif -#ifdef GLX_EXT_scene_marker - if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) - { - ret = GLXEW_EXT_scene_marker; - continue; - } -#endif -#ifdef GLX_EXT_texture_from_pixmap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19)) - { - ret = GLXEW_EXT_texture_from_pixmap; - continue; - } -#endif -#ifdef GLX_EXT_visual_info - if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11)) - { - ret = GLXEW_EXT_visual_info; - continue; - } -#endif -#ifdef GLX_EXT_visual_rating - if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13)) - { - ret = GLXEW_EXT_visual_rating; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) - { -#ifdef GLX_MESA_agp_offset - if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10)) - { - ret = GLXEW_MESA_agp_offset; - continue; - } -#endif -#ifdef GLX_MESA_copy_sub_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15)) - { - ret = GLXEW_MESA_copy_sub_buffer; - continue; - } -#endif -#ifdef GLX_MESA_pixmap_colormap - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15)) - { - ret = GLXEW_MESA_pixmap_colormap; - continue; - } -#endif -#ifdef GLX_MESA_release_buffers - if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15)) - { - ret = GLXEW_MESA_release_buffers; - continue; - } -#endif -#ifdef GLX_MESA_set_3dfx_mode - if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13)) - { - ret = GLXEW_MESA_set_3dfx_mode; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) - { -#ifdef GLX_NV_float_buffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) - { - ret = GLXEW_NV_float_buffer; - continue; - } -#endif -#ifdef GLX_NV_present_video - if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) - { - ret = GLXEW_NV_present_video; - continue; - } -#endif -#ifdef GLX_NV_swap_group - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) - { - ret = GLXEW_NV_swap_group; - continue; - } -#endif -#ifdef GLX_NV_vertex_array_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) - { - ret = GLXEW_NV_vertex_array_range; - continue; - } -#endif -#ifdef GLX_NV_video_output - if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) - { - ret = GLXEW_NV_video_output; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) - { -#ifdef GLX_OML_swap_method - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11)) - { - ret = GLXEW_OML_swap_method; - continue; - } -#endif -#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#include - if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) - { - ret = GLXEW_OML_sync_control; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) - { -#ifdef GLX_SGIS_blended_overlay - if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15)) - { - ret = GLXEW_SGIS_blended_overlay; - continue; - } -#endif -#ifdef GLX_SGIS_color_range - if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) - { - ret = GLXEW_SGIS_color_range; - continue; - } -#endif -#ifdef GLX_SGIS_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) - { - ret = GLXEW_SGIS_multisample; - continue; - } -#endif -#ifdef GLX_SGIS_shared_multisample - if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18)) - { - ret = GLXEW_SGIS_shared_multisample; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) - { -#ifdef GLX_SGIX_fbconfig - if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8)) - { - ret = GLXEW_SGIX_fbconfig; - continue; - } -#endif -#ifdef GLX_SGIX_hyperpipe - if (_glewStrSame3(&pos, &len, (const GLubyte*)"hyperpipe", 9)) - { - ret = GLXEW_SGIX_hyperpipe; - continue; - } -#endif -#ifdef GLX_SGIX_pbuffer - if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) - { - ret = GLXEW_SGIX_pbuffer; - continue; - } -#endif -#ifdef GLX_SGIX_swap_barrier - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12)) - { - ret = GLXEW_SGIX_swap_barrier; - continue; - } -#endif -#ifdef GLX_SGIX_swap_group - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) - { - ret = GLXEW_SGIX_swap_group; - continue; - } -#endif -#ifdef GLX_SGIX_video_resize - if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) - { - ret = GLXEW_SGIX_video_resize; - continue; - } -#endif -#ifdef GLX_SGIX_visual_select_group - if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19)) - { - ret = GLXEW_SGIX_visual_select_group; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) - { -#ifdef GLX_SGI_cushion - if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7)) - { - ret = GLXEW_SGI_cushion; - continue; - } -#endif -#ifdef GLX_SGI_make_current_read - if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) - { - ret = GLXEW_SGI_make_current_read; - continue; - } -#endif -#ifdef GLX_SGI_swap_control - if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) - { - ret = GLXEW_SGI_swap_control; - continue; - } -#endif -#ifdef GLX_SGI_video_sync - if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10)) - { - ret = GLXEW_SGI_video_sync; - continue; - } -#endif - } - if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) - { -#ifdef GLX_SUN_get_transparent_index - if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21)) - { - ret = GLXEW_SUN_get_transparent_index; - continue; - } -#endif -#ifdef GLX_SUN_video_resize - if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) - { - ret = GLXEW_SUN_video_resize; - continue; - } -#endif - } - } - ret = (len == 0); - } - return ret; -} - -#endif /* _WIN32 */ diff --git a/WDL/lice/glew/src/glewinfo.c b/WDL/lice/glew/src/glewinfo.c deleted file mode 100644 index 42e7173b..00000000 --- a/WDL/lice/glew/src/glewinfo.c +++ /dev/null @@ -1,7180 +0,0 @@ -/* -** The OpenGL Extension Wrangler Library -** Copyright (C) 2002-2008, Milan Ikits -** Copyright (C) 2002-2008, Marcelo E. Magallon -** Copyright (C) 2002, Lev Povalahev -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** * The name of the author may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -** THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#if defined(_WIN32) -#include -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -#include -#endif - -static FILE* f; - -#ifdef GLEW_MX -GLEWContext _glewctx; -#define glewGetContext() (&_glewctx) -#ifdef _WIN32 -WGLEWContext _wglewctx; -#define wglewGetContext() (&_wglewctx) -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -GLXEWContext _glxewctx; -#define glxewGetContext() (&_glxewctx) -#endif -#endif - -#if defined(_WIN32) -GLboolean glewCreateContext (int* pixelformat); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -GLboolean glewCreateContext (const char* display, int* visual); -#else -GLboolean glewCreateContext (); -#endif - -#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -GLboolean glewParseArgs (int argc, char** argv, char** display, int* visual); -#endif - -void glewDestroyContext (); - -/* ------------------------------------------------------------------------- */ - -static void glewPrintExt (const char* name, GLboolean def1, GLboolean def2, GLboolean def3) -{ - unsigned int i; - fprintf(f, "\n%s:", name); - for (i=0; i<62-strlen(name); i++) fprintf(f, " "); - fprintf(f, "%s ", def1 ? "OK" : "MISSING"); - if (def1 != def2) - fprintf(f, "[%s] ", def2 ? "OK" : "MISSING"); - if (def1 != def3) - fprintf(f, "[%s]\n", def3 ? "OK" : "MISSING"); - else - fprintf(f, "\n"); - for (i=0; i= 199901L) -#include - -static void _glewInfo_GLX_OML_sync_control (void) -{ - glewPrintExt("GLX_OML_sync_control", GLXEW_OML_sync_control, glxewIsSupported("GLX_OML_sync_control"), glxewGetExtension("GLX_OML_sync_control")); - - glewInfoFunc("glXGetMscRateOML", glXGetMscRateOML == NULL); - glewInfoFunc("glXGetSyncValuesOML", glXGetSyncValuesOML == NULL); - glewInfoFunc("glXSwapBuffersMscOML", glXSwapBuffersMscOML == NULL); - glewInfoFunc("glXWaitForMscOML", glXWaitForMscOML == NULL); - glewInfoFunc("glXWaitForSbcOML", glXWaitForSbcOML == NULL); -} - -#endif /* GLX_OML_sync_control */ - -#ifdef GLX_SGIS_blended_overlay - -static void _glewInfo_GLX_SGIS_blended_overlay (void) -{ - glewPrintExt("GLX_SGIS_blended_overlay", GLXEW_SGIS_blended_overlay, glxewIsSupported("GLX_SGIS_blended_overlay"), glxewGetExtension("GLX_SGIS_blended_overlay")); -} - -#endif /* GLX_SGIS_blended_overlay */ - -#ifdef GLX_SGIS_color_range - -static void _glewInfo_GLX_SGIS_color_range (void) -{ - glewPrintExt("GLX_SGIS_color_range", GLXEW_SGIS_color_range, glxewIsSupported("GLX_SGIS_color_range"), glxewGetExtension("GLX_SGIS_color_range")); -} - -#endif /* GLX_SGIS_color_range */ - -#ifdef GLX_SGIS_multisample - -static void _glewInfo_GLX_SGIS_multisample (void) -{ - glewPrintExt("GLX_SGIS_multisample", GLXEW_SGIS_multisample, glxewIsSupported("GLX_SGIS_multisample"), glxewGetExtension("GLX_SGIS_multisample")); -} - -#endif /* GLX_SGIS_multisample */ - -#ifdef GLX_SGIS_shared_multisample - -static void _glewInfo_GLX_SGIS_shared_multisample (void) -{ - glewPrintExt("GLX_SGIS_shared_multisample", GLXEW_SGIS_shared_multisample, glxewIsSupported("GLX_SGIS_shared_multisample"), glxewGetExtension("GLX_SGIS_shared_multisample")); -} - -#endif /* GLX_SGIS_shared_multisample */ - -#ifdef GLX_SGIX_fbconfig - -static void _glewInfo_GLX_SGIX_fbconfig (void) -{ - glewPrintExt("GLX_SGIX_fbconfig", GLXEW_SGIX_fbconfig, glxewIsSupported("GLX_SGIX_fbconfig"), glxewGetExtension("GLX_SGIX_fbconfig")); - - glewInfoFunc("glXChooseFBConfigSGIX", glXChooseFBConfigSGIX == NULL); - glewInfoFunc("glXCreateContextWithConfigSGIX", glXCreateContextWithConfigSGIX == NULL); - glewInfoFunc("glXCreateGLXPixmapWithConfigSGIX", glXCreateGLXPixmapWithConfigSGIX == NULL); - glewInfoFunc("glXGetFBConfigAttribSGIX", glXGetFBConfigAttribSGIX == NULL); - glewInfoFunc("glXGetFBConfigFromVisualSGIX", glXGetFBConfigFromVisualSGIX == NULL); - glewInfoFunc("glXGetVisualFromFBConfigSGIX", glXGetVisualFromFBConfigSGIX == NULL); -} - -#endif /* GLX_SGIX_fbconfig */ - -#ifdef GLX_SGIX_hyperpipe - -static void _glewInfo_GLX_SGIX_hyperpipe (void) -{ - glewPrintExt("GLX_SGIX_hyperpipe", GLXEW_SGIX_hyperpipe, glxewIsSupported("GLX_SGIX_hyperpipe"), glxewGetExtension("GLX_SGIX_hyperpipe")); - - glewInfoFunc("glXBindHyperpipeSGIX", glXBindHyperpipeSGIX == NULL); - glewInfoFunc("glXDestroyHyperpipeConfigSGIX", glXDestroyHyperpipeConfigSGIX == NULL); - glewInfoFunc("glXHyperpipeAttribSGIX", glXHyperpipeAttribSGIX == NULL); - glewInfoFunc("glXHyperpipeConfigSGIX", glXHyperpipeConfigSGIX == NULL); - glewInfoFunc("glXQueryHyperpipeAttribSGIX", glXQueryHyperpipeAttribSGIX == NULL); - glewInfoFunc("glXQueryHyperpipeBestAttribSGIX", glXQueryHyperpipeBestAttribSGIX == NULL); - glewInfoFunc("glXQueryHyperpipeConfigSGIX", glXQueryHyperpipeConfigSGIX == NULL); - glewInfoFunc("glXQueryHyperpipeNetworkSGIX", glXQueryHyperpipeNetworkSGIX == NULL); -} - -#endif /* GLX_SGIX_hyperpipe */ - -#ifdef GLX_SGIX_pbuffer - -static void _glewInfo_GLX_SGIX_pbuffer (void) -{ - glewPrintExt("GLX_SGIX_pbuffer", GLXEW_SGIX_pbuffer, glxewIsSupported("GLX_SGIX_pbuffer"), glxewGetExtension("GLX_SGIX_pbuffer")); - - glewInfoFunc("glXCreateGLXPbufferSGIX", glXCreateGLXPbufferSGIX == NULL); - glewInfoFunc("glXDestroyGLXPbufferSGIX", glXDestroyGLXPbufferSGIX == NULL); - glewInfoFunc("glXGetSelectedEventSGIX", glXGetSelectedEventSGIX == NULL); - glewInfoFunc("glXQueryGLXPbufferSGIX", glXQueryGLXPbufferSGIX == NULL); - glewInfoFunc("glXSelectEventSGIX", glXSelectEventSGIX == NULL); -} - -#endif /* GLX_SGIX_pbuffer */ - -#ifdef GLX_SGIX_swap_barrier - -static void _glewInfo_GLX_SGIX_swap_barrier (void) -{ - glewPrintExt("GLX_SGIX_swap_barrier", GLXEW_SGIX_swap_barrier, glxewIsSupported("GLX_SGIX_swap_barrier"), glxewGetExtension("GLX_SGIX_swap_barrier")); - - glewInfoFunc("glXBindSwapBarrierSGIX", glXBindSwapBarrierSGIX == NULL); - glewInfoFunc("glXQueryMaxSwapBarriersSGIX", glXQueryMaxSwapBarriersSGIX == NULL); -} - -#endif /* GLX_SGIX_swap_barrier */ - -#ifdef GLX_SGIX_swap_group - -static void _glewInfo_GLX_SGIX_swap_group (void) -{ - glewPrintExt("GLX_SGIX_swap_group", GLXEW_SGIX_swap_group, glxewIsSupported("GLX_SGIX_swap_group"), glxewGetExtension("GLX_SGIX_swap_group")); - - glewInfoFunc("glXJoinSwapGroupSGIX", glXJoinSwapGroupSGIX == NULL); -} - -#endif /* GLX_SGIX_swap_group */ - -#ifdef GLX_SGIX_video_resize - -static void _glewInfo_GLX_SGIX_video_resize (void) -{ - glewPrintExt("GLX_SGIX_video_resize", GLXEW_SGIX_video_resize, glxewIsSupported("GLX_SGIX_video_resize"), glxewGetExtension("GLX_SGIX_video_resize")); - - glewInfoFunc("glXBindChannelToWindowSGIX", glXBindChannelToWindowSGIX == NULL); - glewInfoFunc("glXChannelRectSGIX", glXChannelRectSGIX == NULL); - glewInfoFunc("glXChannelRectSyncSGIX", glXChannelRectSyncSGIX == NULL); - glewInfoFunc("glXQueryChannelDeltasSGIX", glXQueryChannelDeltasSGIX == NULL); - glewInfoFunc("glXQueryChannelRectSGIX", glXQueryChannelRectSGIX == NULL); -} - -#endif /* GLX_SGIX_video_resize */ - -#ifdef GLX_SGIX_visual_select_group - -static void _glewInfo_GLX_SGIX_visual_select_group (void) -{ - glewPrintExt("GLX_SGIX_visual_select_group", GLXEW_SGIX_visual_select_group, glxewIsSupported("GLX_SGIX_visual_select_group"), glxewGetExtension("GLX_SGIX_visual_select_group")); -} - -#endif /* GLX_SGIX_visual_select_group */ - -#ifdef GLX_SGI_cushion - -static void _glewInfo_GLX_SGI_cushion (void) -{ - glewPrintExt("GLX_SGI_cushion", GLXEW_SGI_cushion, glxewIsSupported("GLX_SGI_cushion"), glxewGetExtension("GLX_SGI_cushion")); - - glewInfoFunc("glXCushionSGI", glXCushionSGI == NULL); -} - -#endif /* GLX_SGI_cushion */ - -#ifdef GLX_SGI_make_current_read - -static void _glewInfo_GLX_SGI_make_current_read (void) -{ - glewPrintExt("GLX_SGI_make_current_read", GLXEW_SGI_make_current_read, glxewIsSupported("GLX_SGI_make_current_read"), glxewGetExtension("GLX_SGI_make_current_read")); - - glewInfoFunc("glXGetCurrentReadDrawableSGI", glXGetCurrentReadDrawableSGI == NULL); - glewInfoFunc("glXMakeCurrentReadSGI", glXMakeCurrentReadSGI == NULL); -} - -#endif /* GLX_SGI_make_current_read */ - -#ifdef GLX_SGI_swap_control - -static void _glewInfo_GLX_SGI_swap_control (void) -{ - glewPrintExt("GLX_SGI_swap_control", GLXEW_SGI_swap_control, glxewIsSupported("GLX_SGI_swap_control"), glxewGetExtension("GLX_SGI_swap_control")); - - glewInfoFunc("glXSwapIntervalSGI", glXSwapIntervalSGI == NULL); -} - -#endif /* GLX_SGI_swap_control */ - -#ifdef GLX_SGI_video_sync - -static void _glewInfo_GLX_SGI_video_sync (void) -{ - glewPrintExt("GLX_SGI_video_sync", GLXEW_SGI_video_sync, glxewIsSupported("GLX_SGI_video_sync"), glxewGetExtension("GLX_SGI_video_sync")); - - glewInfoFunc("glXGetVideoSyncSGI", glXGetVideoSyncSGI == NULL); - glewInfoFunc("glXWaitVideoSyncSGI", glXWaitVideoSyncSGI == NULL); -} - -#endif /* GLX_SGI_video_sync */ - -#ifdef GLX_SUN_get_transparent_index - -static void _glewInfo_GLX_SUN_get_transparent_index (void) -{ - glewPrintExt("GLX_SUN_get_transparent_index", GLXEW_SUN_get_transparent_index, glxewIsSupported("GLX_SUN_get_transparent_index"), glxewGetExtension("GLX_SUN_get_transparent_index")); - - glewInfoFunc("glXGetTransparentIndexSUN", glXGetTransparentIndexSUN == NULL); -} - -#endif /* GLX_SUN_get_transparent_index */ - -#ifdef GLX_SUN_video_resize - -static void _glewInfo_GLX_SUN_video_resize (void) -{ - glewPrintExt("GLX_SUN_video_resize", GLXEW_SUN_video_resize, glxewIsSupported("GLX_SUN_video_resize"), glxewGetExtension("GLX_SUN_video_resize")); - - glewInfoFunc("glXGetVideoResizeSUN", glXGetVideoResizeSUN == NULL); - glewInfoFunc("glXVideoResizeSUN", glXVideoResizeSUN == NULL); -} - -#endif /* GLX_SUN_video_resize */ - -#endif /* _WIN32 */ - -/* ------------------------------------------------------------------------ */ - -static void glewInfo (void) -{ -#ifdef GL_VERSION_1_1 - _glewInfo_GL_VERSION_1_1(); -#endif /* GL_VERSION_1_1 */ -#ifdef GL_VERSION_1_2 - _glewInfo_GL_VERSION_1_2(); -#endif /* GL_VERSION_1_2 */ -#ifdef GL_VERSION_1_3 - _glewInfo_GL_VERSION_1_3(); -#endif /* GL_VERSION_1_3 */ -#ifdef GL_VERSION_1_4 - _glewInfo_GL_VERSION_1_4(); -#endif /* GL_VERSION_1_4 */ -#ifdef GL_VERSION_1_5 - _glewInfo_GL_VERSION_1_5(); -#endif /* GL_VERSION_1_5 */ -#ifdef GL_VERSION_2_0 - _glewInfo_GL_VERSION_2_0(); -#endif /* GL_VERSION_2_0 */ -#ifdef GL_VERSION_2_1 - _glewInfo_GL_VERSION_2_1(); -#endif /* GL_VERSION_2_1 */ -#ifdef GL_VERSION_3_0 - _glewInfo_GL_VERSION_3_0(); -#endif /* GL_VERSION_3_0 */ -#ifdef GL_3DFX_multisample - _glewInfo_GL_3DFX_multisample(); -#endif /* GL_3DFX_multisample */ -#ifdef GL_3DFX_tbuffer - _glewInfo_GL_3DFX_tbuffer(); -#endif /* GL_3DFX_tbuffer */ -#ifdef GL_3DFX_texture_compression_FXT1 - _glewInfo_GL_3DFX_texture_compression_FXT1(); -#endif /* GL_3DFX_texture_compression_FXT1 */ -#ifdef GL_APPLE_client_storage - _glewInfo_GL_APPLE_client_storage(); -#endif /* GL_APPLE_client_storage */ -#ifdef GL_APPLE_element_array - _glewInfo_GL_APPLE_element_array(); -#endif /* GL_APPLE_element_array */ -#ifdef GL_APPLE_fence - _glewInfo_GL_APPLE_fence(); -#endif /* GL_APPLE_fence */ -#ifdef GL_APPLE_float_pixels - _glewInfo_GL_APPLE_float_pixels(); -#endif /* GL_APPLE_float_pixels */ -#ifdef GL_APPLE_flush_buffer_range - _glewInfo_GL_APPLE_flush_buffer_range(); -#endif /* GL_APPLE_flush_buffer_range */ -#ifdef GL_APPLE_pixel_buffer - _glewInfo_GL_APPLE_pixel_buffer(); -#endif /* GL_APPLE_pixel_buffer */ -#ifdef GL_APPLE_specular_vector - _glewInfo_GL_APPLE_specular_vector(); -#endif /* GL_APPLE_specular_vector */ -#ifdef GL_APPLE_texture_range - _glewInfo_GL_APPLE_texture_range(); -#endif /* GL_APPLE_texture_range */ -#ifdef GL_APPLE_transform_hint - _glewInfo_GL_APPLE_transform_hint(); -#endif /* GL_APPLE_transform_hint */ -#ifdef GL_APPLE_vertex_array_object - _glewInfo_GL_APPLE_vertex_array_object(); -#endif /* GL_APPLE_vertex_array_object */ -#ifdef GL_APPLE_vertex_array_range - _glewInfo_GL_APPLE_vertex_array_range(); -#endif /* GL_APPLE_vertex_array_range */ -#ifdef GL_APPLE_ycbcr_422 - _glewInfo_GL_APPLE_ycbcr_422(); -#endif /* GL_APPLE_ycbcr_422 */ -#ifdef GL_ARB_color_buffer_float - _glewInfo_GL_ARB_color_buffer_float(); -#endif /* GL_ARB_color_buffer_float */ -#ifdef GL_ARB_depth_buffer_float - _glewInfo_GL_ARB_depth_buffer_float(); -#endif /* GL_ARB_depth_buffer_float */ -#ifdef GL_ARB_depth_texture - _glewInfo_GL_ARB_depth_texture(); -#endif /* GL_ARB_depth_texture */ -#ifdef GL_ARB_draw_buffers - _glewInfo_GL_ARB_draw_buffers(); -#endif /* GL_ARB_draw_buffers */ -#ifdef GL_ARB_draw_instanced - _glewInfo_GL_ARB_draw_instanced(); -#endif /* GL_ARB_draw_instanced */ -#ifdef GL_ARB_fragment_program - _glewInfo_GL_ARB_fragment_program(); -#endif /* GL_ARB_fragment_program */ -#ifdef GL_ARB_fragment_program_shadow - _glewInfo_GL_ARB_fragment_program_shadow(); -#endif /* GL_ARB_fragment_program_shadow */ -#ifdef GL_ARB_fragment_shader - _glewInfo_GL_ARB_fragment_shader(); -#endif /* GL_ARB_fragment_shader */ -#ifdef GL_ARB_framebuffer_object - _glewInfo_GL_ARB_framebuffer_object(); -#endif /* GL_ARB_framebuffer_object */ -#ifdef GL_ARB_framebuffer_sRGB - _glewInfo_GL_ARB_framebuffer_sRGB(); -#endif /* GL_ARB_framebuffer_sRGB */ -#ifdef GL_ARB_geometry_shader4 - _glewInfo_GL_ARB_geometry_shader4(); -#endif /* GL_ARB_geometry_shader4 */ -#ifdef GL_ARB_half_float_pixel - _glewInfo_GL_ARB_half_float_pixel(); -#endif /* GL_ARB_half_float_pixel */ -#ifdef GL_ARB_half_float_vertex - _glewInfo_GL_ARB_half_float_vertex(); -#endif /* GL_ARB_half_float_vertex */ -#ifdef GL_ARB_imaging - _glewInfo_GL_ARB_imaging(); -#endif /* GL_ARB_imaging */ -#ifdef GL_ARB_instanced_arrays - _glewInfo_GL_ARB_instanced_arrays(); -#endif /* GL_ARB_instanced_arrays */ -#ifdef GL_ARB_map_buffer_range - _glewInfo_GL_ARB_map_buffer_range(); -#endif /* GL_ARB_map_buffer_range */ -#ifdef GL_ARB_matrix_palette - _glewInfo_GL_ARB_matrix_palette(); -#endif /* GL_ARB_matrix_palette */ -#ifdef GL_ARB_multisample - _glewInfo_GL_ARB_multisample(); -#endif /* GL_ARB_multisample */ -#ifdef GL_ARB_multitexture - _glewInfo_GL_ARB_multitexture(); -#endif /* GL_ARB_multitexture */ -#ifdef GL_ARB_occlusion_query - _glewInfo_GL_ARB_occlusion_query(); -#endif /* GL_ARB_occlusion_query */ -#ifdef GL_ARB_pixel_buffer_object - _glewInfo_GL_ARB_pixel_buffer_object(); -#endif /* GL_ARB_pixel_buffer_object */ -#ifdef GL_ARB_point_parameters - _glewInfo_GL_ARB_point_parameters(); -#endif /* GL_ARB_point_parameters */ -#ifdef GL_ARB_point_sprite - _glewInfo_GL_ARB_point_sprite(); -#endif /* GL_ARB_point_sprite */ -#ifdef GL_ARB_shader_objects - _glewInfo_GL_ARB_shader_objects(); -#endif /* GL_ARB_shader_objects */ -#ifdef GL_ARB_shading_language_100 - _glewInfo_GL_ARB_shading_language_100(); -#endif /* GL_ARB_shading_language_100 */ -#ifdef GL_ARB_shadow - _glewInfo_GL_ARB_shadow(); -#endif /* GL_ARB_shadow */ -#ifdef GL_ARB_shadow_ambient - _glewInfo_GL_ARB_shadow_ambient(); -#endif /* GL_ARB_shadow_ambient */ -#ifdef GL_ARB_texture_border_clamp - _glewInfo_GL_ARB_texture_border_clamp(); -#endif /* GL_ARB_texture_border_clamp */ -#ifdef GL_ARB_texture_buffer_object - _glewInfo_GL_ARB_texture_buffer_object(); -#endif /* GL_ARB_texture_buffer_object */ -#ifdef GL_ARB_texture_compression - _glewInfo_GL_ARB_texture_compression(); -#endif /* GL_ARB_texture_compression */ -#ifdef GL_ARB_texture_compression_rgtc - _glewInfo_GL_ARB_texture_compression_rgtc(); -#endif /* GL_ARB_texture_compression_rgtc */ -#ifdef GL_ARB_texture_cube_map - _glewInfo_GL_ARB_texture_cube_map(); -#endif /* GL_ARB_texture_cube_map */ -#ifdef GL_ARB_texture_env_add - _glewInfo_GL_ARB_texture_env_add(); -#endif /* GL_ARB_texture_env_add */ -#ifdef GL_ARB_texture_env_combine - _glewInfo_GL_ARB_texture_env_combine(); -#endif /* GL_ARB_texture_env_combine */ -#ifdef GL_ARB_texture_env_crossbar - _glewInfo_GL_ARB_texture_env_crossbar(); -#endif /* GL_ARB_texture_env_crossbar */ -#ifdef GL_ARB_texture_env_dot3 - _glewInfo_GL_ARB_texture_env_dot3(); -#endif /* GL_ARB_texture_env_dot3 */ -#ifdef GL_ARB_texture_float - _glewInfo_GL_ARB_texture_float(); -#endif /* GL_ARB_texture_float */ -#ifdef GL_ARB_texture_mirrored_repeat - _glewInfo_GL_ARB_texture_mirrored_repeat(); -#endif /* GL_ARB_texture_mirrored_repeat */ -#ifdef GL_ARB_texture_non_power_of_two - _glewInfo_GL_ARB_texture_non_power_of_two(); -#endif /* GL_ARB_texture_non_power_of_two */ -#ifdef GL_ARB_texture_rectangle - _glewInfo_GL_ARB_texture_rectangle(); -#endif /* GL_ARB_texture_rectangle */ -#ifdef GL_ARB_texture_rg - _glewInfo_GL_ARB_texture_rg(); -#endif /* GL_ARB_texture_rg */ -#ifdef GL_ARB_transpose_matrix - _glewInfo_GL_ARB_transpose_matrix(); -#endif /* GL_ARB_transpose_matrix */ -#ifdef GL_ARB_vertex_array_object - _glewInfo_GL_ARB_vertex_array_object(); -#endif /* GL_ARB_vertex_array_object */ -#ifdef GL_ARB_vertex_blend - _glewInfo_GL_ARB_vertex_blend(); -#endif /* GL_ARB_vertex_blend */ -#ifdef GL_ARB_vertex_buffer_object - _glewInfo_GL_ARB_vertex_buffer_object(); -#endif /* GL_ARB_vertex_buffer_object */ -#ifdef GL_ARB_vertex_program - _glewInfo_GL_ARB_vertex_program(); -#endif /* GL_ARB_vertex_program */ -#ifdef GL_ARB_vertex_shader - _glewInfo_GL_ARB_vertex_shader(); -#endif /* GL_ARB_vertex_shader */ -#ifdef GL_ARB_window_pos - _glewInfo_GL_ARB_window_pos(); -#endif /* GL_ARB_window_pos */ -#ifdef GL_ATIX_point_sprites - _glewInfo_GL_ATIX_point_sprites(); -#endif /* GL_ATIX_point_sprites */ -#ifdef GL_ATIX_texture_env_combine3 - _glewInfo_GL_ATIX_texture_env_combine3(); -#endif /* GL_ATIX_texture_env_combine3 */ -#ifdef GL_ATIX_texture_env_route - _glewInfo_GL_ATIX_texture_env_route(); -#endif /* GL_ATIX_texture_env_route */ -#ifdef GL_ATIX_vertex_shader_output_point_size - _glewInfo_GL_ATIX_vertex_shader_output_point_size(); -#endif /* GL_ATIX_vertex_shader_output_point_size */ -#ifdef GL_ATI_draw_buffers - _glewInfo_GL_ATI_draw_buffers(); -#endif /* GL_ATI_draw_buffers */ -#ifdef GL_ATI_element_array - _glewInfo_GL_ATI_element_array(); -#endif /* GL_ATI_element_array */ -#ifdef GL_ATI_envmap_bumpmap - _glewInfo_GL_ATI_envmap_bumpmap(); -#endif /* GL_ATI_envmap_bumpmap */ -#ifdef GL_ATI_fragment_shader - _glewInfo_GL_ATI_fragment_shader(); -#endif /* GL_ATI_fragment_shader */ -#ifdef GL_ATI_map_object_buffer - _glewInfo_GL_ATI_map_object_buffer(); -#endif /* GL_ATI_map_object_buffer */ -#ifdef GL_ATI_pn_triangles - _glewInfo_GL_ATI_pn_triangles(); -#endif /* GL_ATI_pn_triangles */ -#ifdef GL_ATI_separate_stencil - _glewInfo_GL_ATI_separate_stencil(); -#endif /* GL_ATI_separate_stencil */ -#ifdef GL_ATI_shader_texture_lod - _glewInfo_GL_ATI_shader_texture_lod(); -#endif /* GL_ATI_shader_texture_lod */ -#ifdef GL_ATI_text_fragment_shader - _glewInfo_GL_ATI_text_fragment_shader(); -#endif /* GL_ATI_text_fragment_shader */ -#ifdef GL_ATI_texture_compression_3dc - _glewInfo_GL_ATI_texture_compression_3dc(); -#endif /* GL_ATI_texture_compression_3dc */ -#ifdef GL_ATI_texture_env_combine3 - _glewInfo_GL_ATI_texture_env_combine3(); -#endif /* GL_ATI_texture_env_combine3 */ -#ifdef GL_ATI_texture_float - _glewInfo_GL_ATI_texture_float(); -#endif /* GL_ATI_texture_float */ -#ifdef GL_ATI_texture_mirror_once - _glewInfo_GL_ATI_texture_mirror_once(); -#endif /* GL_ATI_texture_mirror_once */ -#ifdef GL_ATI_vertex_array_object - _glewInfo_GL_ATI_vertex_array_object(); -#endif /* GL_ATI_vertex_array_object */ -#ifdef GL_ATI_vertex_attrib_array_object - _glewInfo_GL_ATI_vertex_attrib_array_object(); -#endif /* GL_ATI_vertex_attrib_array_object */ -#ifdef GL_ATI_vertex_streams - _glewInfo_GL_ATI_vertex_streams(); -#endif /* GL_ATI_vertex_streams */ -#ifdef GL_EXT_422_pixels - _glewInfo_GL_EXT_422_pixels(); -#endif /* GL_EXT_422_pixels */ -#ifdef GL_EXT_Cg_shader - _glewInfo_GL_EXT_Cg_shader(); -#endif /* GL_EXT_Cg_shader */ -#ifdef GL_EXT_abgr - _glewInfo_GL_EXT_abgr(); -#endif /* GL_EXT_abgr */ -#ifdef GL_EXT_bgra - _glewInfo_GL_EXT_bgra(); -#endif /* GL_EXT_bgra */ -#ifdef GL_EXT_bindable_uniform - _glewInfo_GL_EXT_bindable_uniform(); -#endif /* GL_EXT_bindable_uniform */ -#ifdef GL_EXT_blend_color - _glewInfo_GL_EXT_blend_color(); -#endif /* GL_EXT_blend_color */ -#ifdef GL_EXT_blend_equation_separate - _glewInfo_GL_EXT_blend_equation_separate(); -#endif /* GL_EXT_blend_equation_separate */ -#ifdef GL_EXT_blend_func_separate - _glewInfo_GL_EXT_blend_func_separate(); -#endif /* GL_EXT_blend_func_separate */ -#ifdef GL_EXT_blend_logic_op - _glewInfo_GL_EXT_blend_logic_op(); -#endif /* GL_EXT_blend_logic_op */ -#ifdef GL_EXT_blend_minmax - _glewInfo_GL_EXT_blend_minmax(); -#endif /* GL_EXT_blend_minmax */ -#ifdef GL_EXT_blend_subtract - _glewInfo_GL_EXT_blend_subtract(); -#endif /* GL_EXT_blend_subtract */ -#ifdef GL_EXT_clip_volume_hint - _glewInfo_GL_EXT_clip_volume_hint(); -#endif /* GL_EXT_clip_volume_hint */ -#ifdef GL_EXT_cmyka - _glewInfo_GL_EXT_cmyka(); -#endif /* GL_EXT_cmyka */ -#ifdef GL_EXT_color_subtable - _glewInfo_GL_EXT_color_subtable(); -#endif /* GL_EXT_color_subtable */ -#ifdef GL_EXT_compiled_vertex_array - _glewInfo_GL_EXT_compiled_vertex_array(); -#endif /* GL_EXT_compiled_vertex_array */ -#ifdef GL_EXT_convolution - _glewInfo_GL_EXT_convolution(); -#endif /* GL_EXT_convolution */ -#ifdef GL_EXT_coordinate_frame - _glewInfo_GL_EXT_coordinate_frame(); -#endif /* GL_EXT_coordinate_frame */ -#ifdef GL_EXT_copy_texture - _glewInfo_GL_EXT_copy_texture(); -#endif /* GL_EXT_copy_texture */ -#ifdef GL_EXT_cull_vertex - _glewInfo_GL_EXT_cull_vertex(); -#endif /* GL_EXT_cull_vertex */ -#ifdef GL_EXT_depth_bounds_test - _glewInfo_GL_EXT_depth_bounds_test(); -#endif /* GL_EXT_depth_bounds_test */ -#ifdef GL_EXT_direct_state_access - _glewInfo_GL_EXT_direct_state_access(); -#endif /* GL_EXT_direct_state_access */ -#ifdef GL_EXT_draw_buffers2 - _glewInfo_GL_EXT_draw_buffers2(); -#endif /* GL_EXT_draw_buffers2 */ -#ifdef GL_EXT_draw_instanced - _glewInfo_GL_EXT_draw_instanced(); -#endif /* GL_EXT_draw_instanced */ -#ifdef GL_EXT_draw_range_elements - _glewInfo_GL_EXT_draw_range_elements(); -#endif /* GL_EXT_draw_range_elements */ -#ifdef GL_EXT_fog_coord - _glewInfo_GL_EXT_fog_coord(); -#endif /* GL_EXT_fog_coord */ -#ifdef GL_EXT_fragment_lighting - _glewInfo_GL_EXT_fragment_lighting(); -#endif /* GL_EXT_fragment_lighting */ -#ifdef GL_EXT_framebuffer_blit - _glewInfo_GL_EXT_framebuffer_blit(); -#endif /* GL_EXT_framebuffer_blit */ -#ifdef GL_EXT_framebuffer_multisample - _glewInfo_GL_EXT_framebuffer_multisample(); -#endif /* GL_EXT_framebuffer_multisample */ -#ifdef GL_EXT_framebuffer_object - _glewInfo_GL_EXT_framebuffer_object(); -#endif /* GL_EXT_framebuffer_object */ -#ifdef GL_EXT_framebuffer_sRGB - _glewInfo_GL_EXT_framebuffer_sRGB(); -#endif /* GL_EXT_framebuffer_sRGB */ -#ifdef GL_EXT_geometry_shader4 - _glewInfo_GL_EXT_geometry_shader4(); -#endif /* GL_EXT_geometry_shader4 */ -#ifdef GL_EXT_gpu_program_parameters - _glewInfo_GL_EXT_gpu_program_parameters(); -#endif /* GL_EXT_gpu_program_parameters */ -#ifdef GL_EXT_gpu_shader4 - _glewInfo_GL_EXT_gpu_shader4(); -#endif /* GL_EXT_gpu_shader4 */ -#ifdef GL_EXT_histogram - _glewInfo_GL_EXT_histogram(); -#endif /* GL_EXT_histogram */ -#ifdef GL_EXT_index_array_formats - _glewInfo_GL_EXT_index_array_formats(); -#endif /* GL_EXT_index_array_formats */ -#ifdef GL_EXT_index_func - _glewInfo_GL_EXT_index_func(); -#endif /* GL_EXT_index_func */ -#ifdef GL_EXT_index_material - _glewInfo_GL_EXT_index_material(); -#endif /* GL_EXT_index_material */ -#ifdef GL_EXT_index_texture - _glewInfo_GL_EXT_index_texture(); -#endif /* GL_EXT_index_texture */ -#ifdef GL_EXT_light_texture - _glewInfo_GL_EXT_light_texture(); -#endif /* GL_EXT_light_texture */ -#ifdef GL_EXT_misc_attribute - _glewInfo_GL_EXT_misc_attribute(); -#endif /* GL_EXT_misc_attribute */ -#ifdef GL_EXT_multi_draw_arrays - _glewInfo_GL_EXT_multi_draw_arrays(); -#endif /* GL_EXT_multi_draw_arrays */ -#ifdef GL_EXT_multisample - _glewInfo_GL_EXT_multisample(); -#endif /* GL_EXT_multisample */ -#ifdef GL_EXT_packed_depth_stencil - _glewInfo_GL_EXT_packed_depth_stencil(); -#endif /* GL_EXT_packed_depth_stencil */ -#ifdef GL_EXT_packed_float - _glewInfo_GL_EXT_packed_float(); -#endif /* GL_EXT_packed_float */ -#ifdef GL_EXT_packed_pixels - _glewInfo_GL_EXT_packed_pixels(); -#endif /* GL_EXT_packed_pixels */ -#ifdef GL_EXT_paletted_texture - _glewInfo_GL_EXT_paletted_texture(); -#endif /* GL_EXT_paletted_texture */ -#ifdef GL_EXT_pixel_buffer_object - _glewInfo_GL_EXT_pixel_buffer_object(); -#endif /* GL_EXT_pixel_buffer_object */ -#ifdef GL_EXT_pixel_transform - _glewInfo_GL_EXT_pixel_transform(); -#endif /* GL_EXT_pixel_transform */ -#ifdef GL_EXT_pixel_transform_color_table - _glewInfo_GL_EXT_pixel_transform_color_table(); -#endif /* GL_EXT_pixel_transform_color_table */ -#ifdef GL_EXT_point_parameters - _glewInfo_GL_EXT_point_parameters(); -#endif /* GL_EXT_point_parameters */ -#ifdef GL_EXT_polygon_offset - _glewInfo_GL_EXT_polygon_offset(); -#endif /* GL_EXT_polygon_offset */ -#ifdef GL_EXT_rescale_normal - _glewInfo_GL_EXT_rescale_normal(); -#endif /* GL_EXT_rescale_normal */ -#ifdef GL_EXT_scene_marker - _glewInfo_GL_EXT_scene_marker(); -#endif /* GL_EXT_scene_marker */ -#ifdef GL_EXT_secondary_color - _glewInfo_GL_EXT_secondary_color(); -#endif /* GL_EXT_secondary_color */ -#ifdef GL_EXT_separate_specular_color - _glewInfo_GL_EXT_separate_specular_color(); -#endif /* GL_EXT_separate_specular_color */ -#ifdef GL_EXT_shadow_funcs - _glewInfo_GL_EXT_shadow_funcs(); -#endif /* GL_EXT_shadow_funcs */ -#ifdef GL_EXT_shared_texture_palette - _glewInfo_GL_EXT_shared_texture_palette(); -#endif /* GL_EXT_shared_texture_palette */ -#ifdef GL_EXT_stencil_clear_tag - _glewInfo_GL_EXT_stencil_clear_tag(); -#endif /* GL_EXT_stencil_clear_tag */ -#ifdef GL_EXT_stencil_two_side - _glewInfo_GL_EXT_stencil_two_side(); -#endif /* GL_EXT_stencil_two_side */ -#ifdef GL_EXT_stencil_wrap - _glewInfo_GL_EXT_stencil_wrap(); -#endif /* GL_EXT_stencil_wrap */ -#ifdef GL_EXT_subtexture - _glewInfo_GL_EXT_subtexture(); -#endif /* GL_EXT_subtexture */ -#ifdef GL_EXT_texture - _glewInfo_GL_EXT_texture(); -#endif /* GL_EXT_texture */ -#ifdef GL_EXT_texture3D - _glewInfo_GL_EXT_texture3D(); -#endif /* GL_EXT_texture3D */ -#ifdef GL_EXT_texture_array - _glewInfo_GL_EXT_texture_array(); -#endif /* GL_EXT_texture_array */ -#ifdef GL_EXT_texture_buffer_object - _glewInfo_GL_EXT_texture_buffer_object(); -#endif /* GL_EXT_texture_buffer_object */ -#ifdef GL_EXT_texture_compression_dxt1 - _glewInfo_GL_EXT_texture_compression_dxt1(); -#endif /* GL_EXT_texture_compression_dxt1 */ -#ifdef GL_EXT_texture_compression_latc - _glewInfo_GL_EXT_texture_compression_latc(); -#endif /* GL_EXT_texture_compression_latc */ -#ifdef GL_EXT_texture_compression_rgtc - _glewInfo_GL_EXT_texture_compression_rgtc(); -#endif /* GL_EXT_texture_compression_rgtc */ -#ifdef GL_EXT_texture_compression_s3tc - _glewInfo_GL_EXT_texture_compression_s3tc(); -#endif /* GL_EXT_texture_compression_s3tc */ -#ifdef GL_EXT_texture_cube_map - _glewInfo_GL_EXT_texture_cube_map(); -#endif /* GL_EXT_texture_cube_map */ -#ifdef GL_EXT_texture_edge_clamp - _glewInfo_GL_EXT_texture_edge_clamp(); -#endif /* GL_EXT_texture_edge_clamp */ -#ifdef GL_EXT_texture_env - _glewInfo_GL_EXT_texture_env(); -#endif /* GL_EXT_texture_env */ -#ifdef GL_EXT_texture_env_add - _glewInfo_GL_EXT_texture_env_add(); -#endif /* GL_EXT_texture_env_add */ -#ifdef GL_EXT_texture_env_combine - _glewInfo_GL_EXT_texture_env_combine(); -#endif /* GL_EXT_texture_env_combine */ -#ifdef GL_EXT_texture_env_dot3 - _glewInfo_GL_EXT_texture_env_dot3(); -#endif /* GL_EXT_texture_env_dot3 */ -#ifdef GL_EXT_texture_filter_anisotropic - _glewInfo_GL_EXT_texture_filter_anisotropic(); -#endif /* GL_EXT_texture_filter_anisotropic */ -#ifdef GL_EXT_texture_integer - _glewInfo_GL_EXT_texture_integer(); -#endif /* GL_EXT_texture_integer */ -#ifdef GL_EXT_texture_lod_bias - _glewInfo_GL_EXT_texture_lod_bias(); -#endif /* GL_EXT_texture_lod_bias */ -#ifdef GL_EXT_texture_mirror_clamp - _glewInfo_GL_EXT_texture_mirror_clamp(); -#endif /* GL_EXT_texture_mirror_clamp */ -#ifdef GL_EXT_texture_object - _glewInfo_GL_EXT_texture_object(); -#endif /* GL_EXT_texture_object */ -#ifdef GL_EXT_texture_perturb_normal - _glewInfo_GL_EXT_texture_perturb_normal(); -#endif /* GL_EXT_texture_perturb_normal */ -#ifdef GL_EXT_texture_rectangle - _glewInfo_GL_EXT_texture_rectangle(); -#endif /* GL_EXT_texture_rectangle */ -#ifdef GL_EXT_texture_sRGB - _glewInfo_GL_EXT_texture_sRGB(); -#endif /* GL_EXT_texture_sRGB */ -#ifdef GL_EXT_texture_shared_exponent - _glewInfo_GL_EXT_texture_shared_exponent(); -#endif /* GL_EXT_texture_shared_exponent */ -#ifdef GL_EXT_texture_swizzle - _glewInfo_GL_EXT_texture_swizzle(); -#endif /* GL_EXT_texture_swizzle */ -#ifdef GL_EXT_timer_query - _glewInfo_GL_EXT_timer_query(); -#endif /* GL_EXT_timer_query */ -#ifdef GL_EXT_transform_feedback - _glewInfo_GL_EXT_transform_feedback(); -#endif /* GL_EXT_transform_feedback */ -#ifdef GL_EXT_vertex_array - _glewInfo_GL_EXT_vertex_array(); -#endif /* GL_EXT_vertex_array */ -#ifdef GL_EXT_vertex_array_bgra - _glewInfo_GL_EXT_vertex_array_bgra(); -#endif /* GL_EXT_vertex_array_bgra */ -#ifdef GL_EXT_vertex_shader - _glewInfo_GL_EXT_vertex_shader(); -#endif /* GL_EXT_vertex_shader */ -#ifdef GL_EXT_vertex_weighting - _glewInfo_GL_EXT_vertex_weighting(); -#endif /* GL_EXT_vertex_weighting */ -#ifdef GL_GREMEDY_frame_terminator - _glewInfo_GL_GREMEDY_frame_terminator(); -#endif /* GL_GREMEDY_frame_terminator */ -#ifdef GL_GREMEDY_string_marker - _glewInfo_GL_GREMEDY_string_marker(); -#endif /* GL_GREMEDY_string_marker */ -#ifdef GL_HP_convolution_border_modes - _glewInfo_GL_HP_convolution_border_modes(); -#endif /* GL_HP_convolution_border_modes */ -#ifdef GL_HP_image_transform - _glewInfo_GL_HP_image_transform(); -#endif /* GL_HP_image_transform */ -#ifdef GL_HP_occlusion_test - _glewInfo_GL_HP_occlusion_test(); -#endif /* GL_HP_occlusion_test */ -#ifdef GL_HP_texture_lighting - _glewInfo_GL_HP_texture_lighting(); -#endif /* GL_HP_texture_lighting */ -#ifdef GL_IBM_cull_vertex - _glewInfo_GL_IBM_cull_vertex(); -#endif /* GL_IBM_cull_vertex */ -#ifdef GL_IBM_multimode_draw_arrays - _glewInfo_GL_IBM_multimode_draw_arrays(); -#endif /* GL_IBM_multimode_draw_arrays */ -#ifdef GL_IBM_rasterpos_clip - _glewInfo_GL_IBM_rasterpos_clip(); -#endif /* GL_IBM_rasterpos_clip */ -#ifdef GL_IBM_static_data - _glewInfo_GL_IBM_static_data(); -#endif /* GL_IBM_static_data */ -#ifdef GL_IBM_texture_mirrored_repeat - _glewInfo_GL_IBM_texture_mirrored_repeat(); -#endif /* GL_IBM_texture_mirrored_repeat */ -#ifdef GL_IBM_vertex_array_lists - _glewInfo_GL_IBM_vertex_array_lists(); -#endif /* GL_IBM_vertex_array_lists */ -#ifdef GL_INGR_color_clamp - _glewInfo_GL_INGR_color_clamp(); -#endif /* GL_INGR_color_clamp */ -#ifdef GL_INGR_interlace_read - _glewInfo_GL_INGR_interlace_read(); -#endif /* GL_INGR_interlace_read */ -#ifdef GL_INTEL_parallel_arrays - _glewInfo_GL_INTEL_parallel_arrays(); -#endif /* GL_INTEL_parallel_arrays */ -#ifdef GL_INTEL_texture_scissor - _glewInfo_GL_INTEL_texture_scissor(); -#endif /* GL_INTEL_texture_scissor */ -#ifdef GL_KTX_buffer_region - _glewInfo_GL_KTX_buffer_region(); -#endif /* GL_KTX_buffer_region */ -#ifdef GL_MESAX_texture_stack - _glewInfo_GL_MESAX_texture_stack(); -#endif /* GL_MESAX_texture_stack */ -#ifdef GL_MESA_pack_invert - _glewInfo_GL_MESA_pack_invert(); -#endif /* GL_MESA_pack_invert */ -#ifdef GL_MESA_resize_buffers - _glewInfo_GL_MESA_resize_buffers(); -#endif /* GL_MESA_resize_buffers */ -#ifdef GL_MESA_window_pos - _glewInfo_GL_MESA_window_pos(); -#endif /* GL_MESA_window_pos */ -#ifdef GL_MESA_ycbcr_texture - _glewInfo_GL_MESA_ycbcr_texture(); -#endif /* GL_MESA_ycbcr_texture */ -#ifdef GL_NV_blend_square - _glewInfo_GL_NV_blend_square(); -#endif /* GL_NV_blend_square */ -#ifdef GL_NV_conditional_render - _glewInfo_GL_NV_conditional_render(); -#endif /* GL_NV_conditional_render */ -#ifdef GL_NV_copy_depth_to_color - _glewInfo_GL_NV_copy_depth_to_color(); -#endif /* GL_NV_copy_depth_to_color */ -#ifdef GL_NV_depth_buffer_float - _glewInfo_GL_NV_depth_buffer_float(); -#endif /* GL_NV_depth_buffer_float */ -#ifdef GL_NV_depth_clamp - _glewInfo_GL_NV_depth_clamp(); -#endif /* GL_NV_depth_clamp */ -#ifdef GL_NV_depth_range_unclamped - _glewInfo_GL_NV_depth_range_unclamped(); -#endif /* GL_NV_depth_range_unclamped */ -#ifdef GL_NV_evaluators - _glewInfo_GL_NV_evaluators(); -#endif /* GL_NV_evaluators */ -#ifdef GL_NV_explicit_multisample - _glewInfo_GL_NV_explicit_multisample(); -#endif /* GL_NV_explicit_multisample */ -#ifdef GL_NV_fence - _glewInfo_GL_NV_fence(); -#endif /* GL_NV_fence */ -#ifdef GL_NV_float_buffer - _glewInfo_GL_NV_float_buffer(); -#endif /* GL_NV_float_buffer */ -#ifdef GL_NV_fog_distance - _glewInfo_GL_NV_fog_distance(); -#endif /* GL_NV_fog_distance */ -#ifdef GL_NV_fragment_program - _glewInfo_GL_NV_fragment_program(); -#endif /* GL_NV_fragment_program */ -#ifdef GL_NV_fragment_program2 - _glewInfo_GL_NV_fragment_program2(); -#endif /* GL_NV_fragment_program2 */ -#ifdef GL_NV_fragment_program4 - _glewInfo_GL_NV_fragment_program4(); -#endif /* GL_NV_fragment_program4 */ -#ifdef GL_NV_fragment_program_option - _glewInfo_GL_NV_fragment_program_option(); -#endif /* GL_NV_fragment_program_option */ -#ifdef GL_NV_framebuffer_multisample_coverage - _glewInfo_GL_NV_framebuffer_multisample_coverage(); -#endif /* GL_NV_framebuffer_multisample_coverage */ -#ifdef GL_NV_geometry_program4 - _glewInfo_GL_NV_geometry_program4(); -#endif /* GL_NV_geometry_program4 */ -#ifdef GL_NV_geometry_shader4 - _glewInfo_GL_NV_geometry_shader4(); -#endif /* GL_NV_geometry_shader4 */ -#ifdef GL_NV_gpu_program4 - _glewInfo_GL_NV_gpu_program4(); -#endif /* GL_NV_gpu_program4 */ -#ifdef GL_NV_half_float - _glewInfo_GL_NV_half_float(); -#endif /* GL_NV_half_float */ -#ifdef GL_NV_light_max_exponent - _glewInfo_GL_NV_light_max_exponent(); -#endif /* GL_NV_light_max_exponent */ -#ifdef GL_NV_multisample_filter_hint - _glewInfo_GL_NV_multisample_filter_hint(); -#endif /* GL_NV_multisample_filter_hint */ -#ifdef GL_NV_occlusion_query - _glewInfo_GL_NV_occlusion_query(); -#endif /* GL_NV_occlusion_query */ -#ifdef GL_NV_packed_depth_stencil - _glewInfo_GL_NV_packed_depth_stencil(); -#endif /* GL_NV_packed_depth_stencil */ -#ifdef GL_NV_parameter_buffer_object - _glewInfo_GL_NV_parameter_buffer_object(); -#endif /* GL_NV_parameter_buffer_object */ -#ifdef GL_NV_pixel_data_range - _glewInfo_GL_NV_pixel_data_range(); -#endif /* GL_NV_pixel_data_range */ -#ifdef GL_NV_point_sprite - _glewInfo_GL_NV_point_sprite(); -#endif /* GL_NV_point_sprite */ -#ifdef GL_NV_present_video - _glewInfo_GL_NV_present_video(); -#endif /* GL_NV_present_video */ -#ifdef GL_NV_primitive_restart - _glewInfo_GL_NV_primitive_restart(); -#endif /* GL_NV_primitive_restart */ -#ifdef GL_NV_register_combiners - _glewInfo_GL_NV_register_combiners(); -#endif /* GL_NV_register_combiners */ -#ifdef GL_NV_register_combiners2 - _glewInfo_GL_NV_register_combiners2(); -#endif /* GL_NV_register_combiners2 */ -#ifdef GL_NV_texgen_emboss - _glewInfo_GL_NV_texgen_emboss(); -#endif /* GL_NV_texgen_emboss */ -#ifdef GL_NV_texgen_reflection - _glewInfo_GL_NV_texgen_reflection(); -#endif /* GL_NV_texgen_reflection */ -#ifdef GL_NV_texture_compression_vtc - _glewInfo_GL_NV_texture_compression_vtc(); -#endif /* GL_NV_texture_compression_vtc */ -#ifdef GL_NV_texture_env_combine4 - _glewInfo_GL_NV_texture_env_combine4(); -#endif /* GL_NV_texture_env_combine4 */ -#ifdef GL_NV_texture_expand_normal - _glewInfo_GL_NV_texture_expand_normal(); -#endif /* GL_NV_texture_expand_normal */ -#ifdef GL_NV_texture_rectangle - _glewInfo_GL_NV_texture_rectangle(); -#endif /* GL_NV_texture_rectangle */ -#ifdef GL_NV_texture_shader - _glewInfo_GL_NV_texture_shader(); -#endif /* GL_NV_texture_shader */ -#ifdef GL_NV_texture_shader2 - _glewInfo_GL_NV_texture_shader2(); -#endif /* GL_NV_texture_shader2 */ -#ifdef GL_NV_texture_shader3 - _glewInfo_GL_NV_texture_shader3(); -#endif /* GL_NV_texture_shader3 */ -#ifdef GL_NV_transform_feedback - _glewInfo_GL_NV_transform_feedback(); -#endif /* GL_NV_transform_feedback */ -#ifdef GL_NV_vertex_array_range - _glewInfo_GL_NV_vertex_array_range(); -#endif /* GL_NV_vertex_array_range */ -#ifdef GL_NV_vertex_array_range2 - _glewInfo_GL_NV_vertex_array_range2(); -#endif /* GL_NV_vertex_array_range2 */ -#ifdef GL_NV_vertex_program - _glewInfo_GL_NV_vertex_program(); -#endif /* GL_NV_vertex_program */ -#ifdef GL_NV_vertex_program1_1 - _glewInfo_GL_NV_vertex_program1_1(); -#endif /* GL_NV_vertex_program1_1 */ -#ifdef GL_NV_vertex_program2 - _glewInfo_GL_NV_vertex_program2(); -#endif /* GL_NV_vertex_program2 */ -#ifdef GL_NV_vertex_program2_option - _glewInfo_GL_NV_vertex_program2_option(); -#endif /* GL_NV_vertex_program2_option */ -#ifdef GL_NV_vertex_program3 - _glewInfo_GL_NV_vertex_program3(); -#endif /* GL_NV_vertex_program3 */ -#ifdef GL_NV_vertex_program4 - _glewInfo_GL_NV_vertex_program4(); -#endif /* GL_NV_vertex_program4 */ -#ifdef GL_OES_byte_coordinates - _glewInfo_GL_OES_byte_coordinates(); -#endif /* GL_OES_byte_coordinates */ -#ifdef GL_OES_compressed_paletted_texture - _glewInfo_GL_OES_compressed_paletted_texture(); -#endif /* GL_OES_compressed_paletted_texture */ -#ifdef GL_OES_read_format - _glewInfo_GL_OES_read_format(); -#endif /* GL_OES_read_format */ -#ifdef GL_OES_single_precision - _glewInfo_GL_OES_single_precision(); -#endif /* GL_OES_single_precision */ -#ifdef GL_OML_interlace - _glewInfo_GL_OML_interlace(); -#endif /* GL_OML_interlace */ -#ifdef GL_OML_resample - _glewInfo_GL_OML_resample(); -#endif /* GL_OML_resample */ -#ifdef GL_OML_subsample - _glewInfo_GL_OML_subsample(); -#endif /* GL_OML_subsample */ -#ifdef GL_PGI_misc_hints - _glewInfo_GL_PGI_misc_hints(); -#endif /* GL_PGI_misc_hints */ -#ifdef GL_PGI_vertex_hints - _glewInfo_GL_PGI_vertex_hints(); -#endif /* GL_PGI_vertex_hints */ -#ifdef GL_REND_screen_coordinates - _glewInfo_GL_REND_screen_coordinates(); -#endif /* GL_REND_screen_coordinates */ -#ifdef GL_S3_s3tc - _glewInfo_GL_S3_s3tc(); -#endif /* GL_S3_s3tc */ -#ifdef GL_SGIS_color_range - _glewInfo_GL_SGIS_color_range(); -#endif /* GL_SGIS_color_range */ -#ifdef GL_SGIS_detail_texture - _glewInfo_GL_SGIS_detail_texture(); -#endif /* GL_SGIS_detail_texture */ -#ifdef GL_SGIS_fog_function - _glewInfo_GL_SGIS_fog_function(); -#endif /* GL_SGIS_fog_function */ -#ifdef GL_SGIS_generate_mipmap - _glewInfo_GL_SGIS_generate_mipmap(); -#endif /* GL_SGIS_generate_mipmap */ -#ifdef GL_SGIS_multisample - _glewInfo_GL_SGIS_multisample(); -#endif /* GL_SGIS_multisample */ -#ifdef GL_SGIS_pixel_texture - _glewInfo_GL_SGIS_pixel_texture(); -#endif /* GL_SGIS_pixel_texture */ -#ifdef GL_SGIS_point_line_texgen - _glewInfo_GL_SGIS_point_line_texgen(); -#endif /* GL_SGIS_point_line_texgen */ -#ifdef GL_SGIS_sharpen_texture - _glewInfo_GL_SGIS_sharpen_texture(); -#endif /* GL_SGIS_sharpen_texture */ -#ifdef GL_SGIS_texture4D - _glewInfo_GL_SGIS_texture4D(); -#endif /* GL_SGIS_texture4D */ -#ifdef GL_SGIS_texture_border_clamp - _glewInfo_GL_SGIS_texture_border_clamp(); -#endif /* GL_SGIS_texture_border_clamp */ -#ifdef GL_SGIS_texture_edge_clamp - _glewInfo_GL_SGIS_texture_edge_clamp(); -#endif /* GL_SGIS_texture_edge_clamp */ -#ifdef GL_SGIS_texture_filter4 - _glewInfo_GL_SGIS_texture_filter4(); -#endif /* GL_SGIS_texture_filter4 */ -#ifdef GL_SGIS_texture_lod - _glewInfo_GL_SGIS_texture_lod(); -#endif /* GL_SGIS_texture_lod */ -#ifdef GL_SGIS_texture_select - _glewInfo_GL_SGIS_texture_select(); -#endif /* GL_SGIS_texture_select */ -#ifdef GL_SGIX_async - _glewInfo_GL_SGIX_async(); -#endif /* GL_SGIX_async */ -#ifdef GL_SGIX_async_histogram - _glewInfo_GL_SGIX_async_histogram(); -#endif /* GL_SGIX_async_histogram */ -#ifdef GL_SGIX_async_pixel - _glewInfo_GL_SGIX_async_pixel(); -#endif /* GL_SGIX_async_pixel */ -#ifdef GL_SGIX_blend_alpha_minmax - _glewInfo_GL_SGIX_blend_alpha_minmax(); -#endif /* GL_SGIX_blend_alpha_minmax */ -#ifdef GL_SGIX_clipmap - _glewInfo_GL_SGIX_clipmap(); -#endif /* GL_SGIX_clipmap */ -#ifdef GL_SGIX_convolution_accuracy - _glewInfo_GL_SGIX_convolution_accuracy(); -#endif /* GL_SGIX_convolution_accuracy */ -#ifdef GL_SGIX_depth_texture - _glewInfo_GL_SGIX_depth_texture(); -#endif /* GL_SGIX_depth_texture */ -#ifdef GL_SGIX_flush_raster - _glewInfo_GL_SGIX_flush_raster(); -#endif /* GL_SGIX_flush_raster */ -#ifdef GL_SGIX_fog_offset - _glewInfo_GL_SGIX_fog_offset(); -#endif /* GL_SGIX_fog_offset */ -#ifdef GL_SGIX_fog_texture - _glewInfo_GL_SGIX_fog_texture(); -#endif /* GL_SGIX_fog_texture */ -#ifdef GL_SGIX_fragment_specular_lighting - _glewInfo_GL_SGIX_fragment_specular_lighting(); -#endif /* GL_SGIX_fragment_specular_lighting */ -#ifdef GL_SGIX_framezoom - _glewInfo_GL_SGIX_framezoom(); -#endif /* GL_SGIX_framezoom */ -#ifdef GL_SGIX_interlace - _glewInfo_GL_SGIX_interlace(); -#endif /* GL_SGIX_interlace */ -#ifdef GL_SGIX_ir_instrument1 - _glewInfo_GL_SGIX_ir_instrument1(); -#endif /* GL_SGIX_ir_instrument1 */ -#ifdef GL_SGIX_list_priority - _glewInfo_GL_SGIX_list_priority(); -#endif /* GL_SGIX_list_priority */ -#ifdef GL_SGIX_pixel_texture - _glewInfo_GL_SGIX_pixel_texture(); -#endif /* GL_SGIX_pixel_texture */ -#ifdef GL_SGIX_pixel_texture_bits - _glewInfo_GL_SGIX_pixel_texture_bits(); -#endif /* GL_SGIX_pixel_texture_bits */ -#ifdef GL_SGIX_reference_plane - _glewInfo_GL_SGIX_reference_plane(); -#endif /* GL_SGIX_reference_plane */ -#ifdef GL_SGIX_resample - _glewInfo_GL_SGIX_resample(); -#endif /* GL_SGIX_resample */ -#ifdef GL_SGIX_shadow - _glewInfo_GL_SGIX_shadow(); -#endif /* GL_SGIX_shadow */ -#ifdef GL_SGIX_shadow_ambient - _glewInfo_GL_SGIX_shadow_ambient(); -#endif /* GL_SGIX_shadow_ambient */ -#ifdef GL_SGIX_sprite - _glewInfo_GL_SGIX_sprite(); -#endif /* GL_SGIX_sprite */ -#ifdef GL_SGIX_tag_sample_buffer - _glewInfo_GL_SGIX_tag_sample_buffer(); -#endif /* GL_SGIX_tag_sample_buffer */ -#ifdef GL_SGIX_texture_add_env - _glewInfo_GL_SGIX_texture_add_env(); -#endif /* GL_SGIX_texture_add_env */ -#ifdef GL_SGIX_texture_coordinate_clamp - _glewInfo_GL_SGIX_texture_coordinate_clamp(); -#endif /* GL_SGIX_texture_coordinate_clamp */ -#ifdef GL_SGIX_texture_lod_bias - _glewInfo_GL_SGIX_texture_lod_bias(); -#endif /* GL_SGIX_texture_lod_bias */ -#ifdef GL_SGIX_texture_multi_buffer - _glewInfo_GL_SGIX_texture_multi_buffer(); -#endif /* GL_SGIX_texture_multi_buffer */ -#ifdef GL_SGIX_texture_range - _glewInfo_GL_SGIX_texture_range(); -#endif /* GL_SGIX_texture_range */ -#ifdef GL_SGIX_texture_scale_bias - _glewInfo_GL_SGIX_texture_scale_bias(); -#endif /* GL_SGIX_texture_scale_bias */ -#ifdef GL_SGIX_vertex_preclip - _glewInfo_GL_SGIX_vertex_preclip(); -#endif /* GL_SGIX_vertex_preclip */ -#ifdef GL_SGIX_vertex_preclip_hint - _glewInfo_GL_SGIX_vertex_preclip_hint(); -#endif /* GL_SGIX_vertex_preclip_hint */ -#ifdef GL_SGIX_ycrcb - _glewInfo_GL_SGIX_ycrcb(); -#endif /* GL_SGIX_ycrcb */ -#ifdef GL_SGI_color_matrix - _glewInfo_GL_SGI_color_matrix(); -#endif /* GL_SGI_color_matrix */ -#ifdef GL_SGI_color_table - _glewInfo_GL_SGI_color_table(); -#endif /* GL_SGI_color_table */ -#ifdef GL_SGI_texture_color_table - _glewInfo_GL_SGI_texture_color_table(); -#endif /* GL_SGI_texture_color_table */ -#ifdef GL_SUNX_constant_data - _glewInfo_GL_SUNX_constant_data(); -#endif /* GL_SUNX_constant_data */ -#ifdef GL_SUN_convolution_border_modes - _glewInfo_GL_SUN_convolution_border_modes(); -#endif /* GL_SUN_convolution_border_modes */ -#ifdef GL_SUN_global_alpha - _glewInfo_GL_SUN_global_alpha(); -#endif /* GL_SUN_global_alpha */ -#ifdef GL_SUN_mesh_array - _glewInfo_GL_SUN_mesh_array(); -#endif /* GL_SUN_mesh_array */ -#ifdef GL_SUN_read_video_pixels - _glewInfo_GL_SUN_read_video_pixels(); -#endif /* GL_SUN_read_video_pixels */ -#ifdef GL_SUN_slice_accum - _glewInfo_GL_SUN_slice_accum(); -#endif /* GL_SUN_slice_accum */ -#ifdef GL_SUN_triangle_list - _glewInfo_GL_SUN_triangle_list(); -#endif /* GL_SUN_triangle_list */ -#ifdef GL_SUN_vertex - _glewInfo_GL_SUN_vertex(); -#endif /* GL_SUN_vertex */ -#ifdef GL_WIN_phong_shading - _glewInfo_GL_WIN_phong_shading(); -#endif /* GL_WIN_phong_shading */ -#ifdef GL_WIN_specular_fog - _glewInfo_GL_WIN_specular_fog(); -#endif /* GL_WIN_specular_fog */ -#ifdef GL_WIN_swap_hint - _glewInfo_GL_WIN_swap_hint(); -#endif /* GL_WIN_swap_hint */ -} - -/* ------------------------------------------------------------------------ */ - -#ifdef _WIN32 - -static void wglewInfo () -{ -#ifdef WGL_3DFX_multisample - _glewInfo_WGL_3DFX_multisample(); -#endif /* WGL_3DFX_multisample */ -#ifdef WGL_3DL_stereo_control - _glewInfo_WGL_3DL_stereo_control(); -#endif /* WGL_3DL_stereo_control */ -#ifdef WGL_ARB_buffer_region - _glewInfo_WGL_ARB_buffer_region(); -#endif /* WGL_ARB_buffer_region */ -#ifdef WGL_ARB_create_context - _glewInfo_WGL_ARB_create_context(); -#endif /* WGL_ARB_create_context */ -#ifdef WGL_ARB_extensions_string - _glewInfo_WGL_ARB_extensions_string(); -#endif /* WGL_ARB_extensions_string */ -#ifdef WGL_ARB_framebuffer_sRGB - _glewInfo_WGL_ARB_framebuffer_sRGB(); -#endif /* WGL_ARB_framebuffer_sRGB */ -#ifdef WGL_ARB_make_current_read - _glewInfo_WGL_ARB_make_current_read(); -#endif /* WGL_ARB_make_current_read */ -#ifdef WGL_ARB_multisample - _glewInfo_WGL_ARB_multisample(); -#endif /* WGL_ARB_multisample */ -#ifdef WGL_ARB_pbuffer - _glewInfo_WGL_ARB_pbuffer(); -#endif /* WGL_ARB_pbuffer */ -#ifdef WGL_ARB_pixel_format - _glewInfo_WGL_ARB_pixel_format(); -#endif /* WGL_ARB_pixel_format */ -#ifdef WGL_ARB_pixel_format_float - _glewInfo_WGL_ARB_pixel_format_float(); -#endif /* WGL_ARB_pixel_format_float */ -#ifdef WGL_ARB_render_texture - _glewInfo_WGL_ARB_render_texture(); -#endif /* WGL_ARB_render_texture */ -#ifdef WGL_ATI_pixel_format_float - _glewInfo_WGL_ATI_pixel_format_float(); -#endif /* WGL_ATI_pixel_format_float */ -#ifdef WGL_ATI_render_texture_rectangle - _glewInfo_WGL_ATI_render_texture_rectangle(); -#endif /* WGL_ATI_render_texture_rectangle */ -#ifdef WGL_EXT_depth_float - _glewInfo_WGL_EXT_depth_float(); -#endif /* WGL_EXT_depth_float */ -#ifdef WGL_EXT_display_color_table - _glewInfo_WGL_EXT_display_color_table(); -#endif /* WGL_EXT_display_color_table */ -#ifdef WGL_EXT_extensions_string - _glewInfo_WGL_EXT_extensions_string(); -#endif /* WGL_EXT_extensions_string */ -#ifdef WGL_EXT_framebuffer_sRGB - _glewInfo_WGL_EXT_framebuffer_sRGB(); -#endif /* WGL_EXT_framebuffer_sRGB */ -#ifdef WGL_EXT_make_current_read - _glewInfo_WGL_EXT_make_current_read(); -#endif /* WGL_EXT_make_current_read */ -#ifdef WGL_EXT_multisample - _glewInfo_WGL_EXT_multisample(); -#endif /* WGL_EXT_multisample */ -#ifdef WGL_EXT_pbuffer - _glewInfo_WGL_EXT_pbuffer(); -#endif /* WGL_EXT_pbuffer */ -#ifdef WGL_EXT_pixel_format - _glewInfo_WGL_EXT_pixel_format(); -#endif /* WGL_EXT_pixel_format */ -#ifdef WGL_EXT_pixel_format_packed_float - _glewInfo_WGL_EXT_pixel_format_packed_float(); -#endif /* WGL_EXT_pixel_format_packed_float */ -#ifdef WGL_EXT_swap_control - _glewInfo_WGL_EXT_swap_control(); -#endif /* WGL_EXT_swap_control */ -#ifdef WGL_I3D_digital_video_control - _glewInfo_WGL_I3D_digital_video_control(); -#endif /* WGL_I3D_digital_video_control */ -#ifdef WGL_I3D_gamma - _glewInfo_WGL_I3D_gamma(); -#endif /* WGL_I3D_gamma */ -#ifdef WGL_I3D_genlock - _glewInfo_WGL_I3D_genlock(); -#endif /* WGL_I3D_genlock */ -#ifdef WGL_I3D_image_buffer - _glewInfo_WGL_I3D_image_buffer(); -#endif /* WGL_I3D_image_buffer */ -#ifdef WGL_I3D_swap_frame_lock - _glewInfo_WGL_I3D_swap_frame_lock(); -#endif /* WGL_I3D_swap_frame_lock */ -#ifdef WGL_I3D_swap_frame_usage - _glewInfo_WGL_I3D_swap_frame_usage(); -#endif /* WGL_I3D_swap_frame_usage */ -#ifdef WGL_NV_float_buffer - _glewInfo_WGL_NV_float_buffer(); -#endif /* WGL_NV_float_buffer */ -#ifdef WGL_NV_gpu_affinity - _glewInfo_WGL_NV_gpu_affinity(); -#endif /* WGL_NV_gpu_affinity */ -#ifdef WGL_NV_present_video - _glewInfo_WGL_NV_present_video(); -#endif /* WGL_NV_present_video */ -#ifdef WGL_NV_render_depth_texture - _glewInfo_WGL_NV_render_depth_texture(); -#endif /* WGL_NV_render_depth_texture */ -#ifdef WGL_NV_render_texture_rectangle - _glewInfo_WGL_NV_render_texture_rectangle(); -#endif /* WGL_NV_render_texture_rectangle */ -#ifdef WGL_NV_swap_group - _glewInfo_WGL_NV_swap_group(); -#endif /* WGL_NV_swap_group */ -#ifdef WGL_NV_vertex_array_range - _glewInfo_WGL_NV_vertex_array_range(); -#endif /* WGL_NV_vertex_array_range */ -#ifdef WGL_NV_video_output - _glewInfo_WGL_NV_video_output(); -#endif /* WGL_NV_video_output */ -#ifdef WGL_OML_sync_control - _glewInfo_WGL_OML_sync_control(); -#endif /* WGL_OML_sync_control */ -} - -#else /* _UNIX */ - -static void glxewInfo () -{ -#ifdef GLX_VERSION_1_2 - _glewInfo_GLX_VERSION_1_2(); -#endif /* GLX_VERSION_1_2 */ -#ifdef GLX_VERSION_1_3 - _glewInfo_GLX_VERSION_1_3(); -#endif /* GLX_VERSION_1_3 */ -#ifdef GLX_VERSION_1_4 - _glewInfo_GLX_VERSION_1_4(); -#endif /* GLX_VERSION_1_4 */ -#ifdef GLX_3DFX_multisample - _glewInfo_GLX_3DFX_multisample(); -#endif /* GLX_3DFX_multisample */ -#ifdef GLX_ARB_create_context - _glewInfo_GLX_ARB_create_context(); -#endif /* GLX_ARB_create_context */ -#ifdef GLX_ARB_fbconfig_float - _glewInfo_GLX_ARB_fbconfig_float(); -#endif /* GLX_ARB_fbconfig_float */ -#ifdef GLX_ARB_framebuffer_sRGB - _glewInfo_GLX_ARB_framebuffer_sRGB(); -#endif /* GLX_ARB_framebuffer_sRGB */ -#ifdef GLX_ARB_get_proc_address - _glewInfo_GLX_ARB_get_proc_address(); -#endif /* GLX_ARB_get_proc_address */ -#ifdef GLX_ARB_multisample - _glewInfo_GLX_ARB_multisample(); -#endif /* GLX_ARB_multisample */ -#ifdef GLX_ATI_pixel_format_float - _glewInfo_GLX_ATI_pixel_format_float(); -#endif /* GLX_ATI_pixel_format_float */ -#ifdef GLX_ATI_render_texture - _glewInfo_GLX_ATI_render_texture(); -#endif /* GLX_ATI_render_texture */ -#ifdef GLX_EXT_fbconfig_packed_float - _glewInfo_GLX_EXT_fbconfig_packed_float(); -#endif /* GLX_EXT_fbconfig_packed_float */ -#ifdef GLX_EXT_framebuffer_sRGB - _glewInfo_GLX_EXT_framebuffer_sRGB(); -#endif /* GLX_EXT_framebuffer_sRGB */ -#ifdef GLX_EXT_import_context - _glewInfo_GLX_EXT_import_context(); -#endif /* GLX_EXT_import_context */ -#ifdef GLX_EXT_scene_marker - _glewInfo_GLX_EXT_scene_marker(); -#endif /* GLX_EXT_scene_marker */ -#ifdef GLX_EXT_texture_from_pixmap - _glewInfo_GLX_EXT_texture_from_pixmap(); -#endif /* GLX_EXT_texture_from_pixmap */ -#ifdef GLX_EXT_visual_info - _glewInfo_GLX_EXT_visual_info(); -#endif /* GLX_EXT_visual_info */ -#ifdef GLX_EXT_visual_rating - _glewInfo_GLX_EXT_visual_rating(); -#endif /* GLX_EXT_visual_rating */ -#ifdef GLX_MESA_agp_offset - _glewInfo_GLX_MESA_agp_offset(); -#endif /* GLX_MESA_agp_offset */ -#ifdef GLX_MESA_copy_sub_buffer - _glewInfo_GLX_MESA_copy_sub_buffer(); -#endif /* GLX_MESA_copy_sub_buffer */ -#ifdef GLX_MESA_pixmap_colormap - _glewInfo_GLX_MESA_pixmap_colormap(); -#endif /* GLX_MESA_pixmap_colormap */ -#ifdef GLX_MESA_release_buffers - _glewInfo_GLX_MESA_release_buffers(); -#endif /* GLX_MESA_release_buffers */ -#ifdef GLX_MESA_set_3dfx_mode - _glewInfo_GLX_MESA_set_3dfx_mode(); -#endif /* GLX_MESA_set_3dfx_mode */ -#ifdef GLX_NV_float_buffer - _glewInfo_GLX_NV_float_buffer(); -#endif /* GLX_NV_float_buffer */ -#ifdef GLX_NV_present_video - _glewInfo_GLX_NV_present_video(); -#endif /* GLX_NV_present_video */ -#ifdef GLX_NV_swap_group - _glewInfo_GLX_NV_swap_group(); -#endif /* GLX_NV_swap_group */ -#ifdef GLX_NV_vertex_array_range - _glewInfo_GLX_NV_vertex_array_range(); -#endif /* GLX_NV_vertex_array_range */ -#ifdef GLX_NV_video_output - _glewInfo_GLX_NV_video_output(); -#endif /* GLX_NV_video_output */ -#ifdef GLX_OML_swap_method - _glewInfo_GLX_OML_swap_method(); -#endif /* GLX_OML_swap_method */ -#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#include - _glewInfo_GLX_OML_sync_control(); -#endif /* GLX_OML_sync_control */ -#ifdef GLX_SGIS_blended_overlay - _glewInfo_GLX_SGIS_blended_overlay(); -#endif /* GLX_SGIS_blended_overlay */ -#ifdef GLX_SGIS_color_range - _glewInfo_GLX_SGIS_color_range(); -#endif /* GLX_SGIS_color_range */ -#ifdef GLX_SGIS_multisample - _glewInfo_GLX_SGIS_multisample(); -#endif /* GLX_SGIS_multisample */ -#ifdef GLX_SGIS_shared_multisample - _glewInfo_GLX_SGIS_shared_multisample(); -#endif /* GLX_SGIS_shared_multisample */ -#ifdef GLX_SGIX_fbconfig - _glewInfo_GLX_SGIX_fbconfig(); -#endif /* GLX_SGIX_fbconfig */ -#ifdef GLX_SGIX_hyperpipe - _glewInfo_GLX_SGIX_hyperpipe(); -#endif /* GLX_SGIX_hyperpipe */ -#ifdef GLX_SGIX_pbuffer - _glewInfo_GLX_SGIX_pbuffer(); -#endif /* GLX_SGIX_pbuffer */ -#ifdef GLX_SGIX_swap_barrier - _glewInfo_GLX_SGIX_swap_barrier(); -#endif /* GLX_SGIX_swap_barrier */ -#ifdef GLX_SGIX_swap_group - _glewInfo_GLX_SGIX_swap_group(); -#endif /* GLX_SGIX_swap_group */ -#ifdef GLX_SGIX_video_resize - _glewInfo_GLX_SGIX_video_resize(); -#endif /* GLX_SGIX_video_resize */ -#ifdef GLX_SGIX_visual_select_group - _glewInfo_GLX_SGIX_visual_select_group(); -#endif /* GLX_SGIX_visual_select_group */ -#ifdef GLX_SGI_cushion - _glewInfo_GLX_SGI_cushion(); -#endif /* GLX_SGI_cushion */ -#ifdef GLX_SGI_make_current_read - _glewInfo_GLX_SGI_make_current_read(); -#endif /* GLX_SGI_make_current_read */ -#ifdef GLX_SGI_swap_control - _glewInfo_GLX_SGI_swap_control(); -#endif /* GLX_SGI_swap_control */ -#ifdef GLX_SGI_video_sync - _glewInfo_GLX_SGI_video_sync(); -#endif /* GLX_SGI_video_sync */ -#ifdef GLX_SUN_get_transparent_index - _glewInfo_GLX_SUN_get_transparent_index(); -#endif /* GLX_SUN_get_transparent_index */ -#ifdef GLX_SUN_video_resize - _glewInfo_GLX_SUN_video_resize(); -#endif /* GLX_SUN_video_resize */ -} - -#endif /* _WIN32 */ - -/* ------------------------------------------------------------------------ */ - -#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -int main (int argc, char** argv) -#else -int main (void) -#endif -{ - GLuint err; - -#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - char* display = NULL; - int visual = -1; - - if (glewParseArgs(argc-1, argv+1, &display, &visual)) - { -#if defined(_WIN32) - fprintf(stderr, "Usage: glewinfo [-pf ]\n"); -#else - fprintf(stderr, "Usage: glewinfo [-display ] [-visual ]\n"); -#endif - return 1; - } -#endif - -#if defined(_WIN32) - if (GL_TRUE == glewCreateContext(&visual)) -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - if (GL_TRUE == glewCreateContext()) -#else - if (GL_TRUE == glewCreateContext(display, &visual)) -#endif - { - fprintf(stderr, "Error: glewCreateContext failed\n"); - glewDestroyContext(); - return 1; - } - glewExperimental = GL_TRUE; -#ifdef GLEW_MX - err = glewContextInit(glewGetContext()); -#ifdef _WIN32 - err = err || wglewContextInit(wglewGetContext()); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - err = err || glxewContextInit(glxewGetContext()); -#endif - -#else - err = glewInit(); -#endif - if (GLEW_OK != err) - { - fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); - glewDestroyContext(); - return 1; - } -#if defined(_WIN32) - f = fopen("glewinfo.txt", "w"); - if (f == NULL) f = stdout; -#else - f = stdout; -#endif - fprintf(f, "---------------------------\n"); - fprintf(f, " GLEW Extension Info\n"); - fprintf(f, "---------------------------\n\n"); - fprintf(f, "GLEW version %s\n", glewGetString(GLEW_VERSION)); -#if defined(_WIN32) - fprintf(f, "Reporting capabilities of pixelformat %d\n", visual); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - fprintf(f, "Reporting capabilities of display %s, visual 0x%x\n", - display == NULL ? getenv("DISPLAY") : display, visual); -#endif - fprintf(f, "Running on a %s from %s\n", - glGetString(GL_RENDERER), glGetString(GL_VENDOR)); - fprintf(f, "OpenGL version %s is supported\n", glGetString(GL_VERSION)); - glewInfo(); -#if defined(_WIN32) - wglewInfo(); -#else - glxewInfo(); -#endif - if (f != stdout) fclose(f); - glewDestroyContext(); - return 0; -} - -/* ------------------------------------------------------------------------ */ - -#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -GLboolean glewParseArgs (int argc, char** argv, char** display, int* visual) -{ - int p = 0; - while (p < argc) - { -#if defined(_WIN32) - if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) - { - if (++p >= argc) return GL_TRUE; - *display = 0; - *visual = strtol(argv[p++], NULL, 0); - } - else - return GL_TRUE; -#else - if (!strcmp(argv[p], "-display")) - { - if (++p >= argc) return GL_TRUE; - *display = argv[p++]; - } - else if (!strcmp(argv[p], "-visual")) - { - if (++p >= argc) return GL_TRUE; - *visual = (int)strtol(argv[p++], NULL, 0); - } - else - return GL_TRUE; -#endif - } - return GL_FALSE; -} -#endif - -/* ------------------------------------------------------------------------ */ - -#if defined(_WIN32) - -HWND wnd = NULL; -HDC dc = NULL; -HGLRC rc = NULL; - -GLboolean glewCreateContext (int* pixelformat) -{ - WNDCLASS wc; - PIXELFORMATDESCRIPTOR pfd; - /* register window class */ - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.hInstance = GetModuleHandle(NULL); - wc.lpfnWndProc = DefWindowProc; - wc.lpszClassName = "GLEW"; - if (0 == RegisterClass(&wc)) return GL_TRUE; - /* create window */ - wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL); - if (NULL == wnd) return GL_TRUE; - /* get the device context */ - dc = GetDC(wnd); - if (NULL == dc) return GL_TRUE; - /* find pixel format */ - ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); - if (*pixelformat == -1) /* find default */ - { - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - *pixelformat = ChoosePixelFormat(dc, &pfd); - if (*pixelformat == 0) return GL_TRUE; - } - /* set the pixel format for the dc */ - if (FALSE == SetPixelFormat(dc, *pixelformat, &pfd)) return GL_TRUE; - /* create rendering context */ - rc = wglCreateContext(dc); - if (NULL == rc) return GL_TRUE; - if (FALSE == wglMakeCurrent(dc, rc)) return GL_TRUE; - return GL_FALSE; -} - -void glewDestroyContext () -{ - if (NULL != rc) wglMakeCurrent(NULL, NULL); - if (NULL != rc) wglDeleteContext(wglGetCurrentContext()); - if (NULL != wnd && NULL != dc) ReleaseDC(wnd, dc); - if (NULL != wnd) DestroyWindow(wnd); - UnregisterClass("GLEW", GetModuleHandle(NULL)); -} - -/* ------------------------------------------------------------------------ */ - -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - -#include - -AGLContext ctx, octx; - -GLboolean glewCreateContext () -{ - int attrib[] = { AGL_RGBA, AGL_NONE }; - AGLPixelFormat pf; - /*int major, minor; - SetPortWindowPort(wnd); - aglGetVersion(&major, &minor); - fprintf(stderr, "GL %d.%d\n", major, minor);*/ - pf = aglChoosePixelFormat(NULL, 0, attrib); - if (NULL == pf) return GL_TRUE; - ctx = aglCreateContext(pf, NULL); - if (NULL == ctx || AGL_NO_ERROR != aglGetError()) return GL_TRUE; - aglDestroyPixelFormat(pf); - /*aglSetDrawable(ctx, GetWindowPort(wnd));*/ - octx = aglGetCurrentContext(); - if (NULL == aglSetCurrentContext(ctx)) return GL_TRUE; - return GL_FALSE; -} - -void glewDestroyContext () -{ - aglSetCurrentContext(octx); - if (NULL != ctx) aglDestroyContext(ctx); -} - -/* ------------------------------------------------------------------------ */ - -#else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ - -Display* dpy = NULL; -XVisualInfo* vi = NULL; -XVisualInfo* vis = NULL; -GLXContext ctx = NULL; -Window wnd = 0; -Colormap cmap = 0; - -GLboolean glewCreateContext (const char* display, int* visual) -{ - int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; - int erb, evb; - XSetWindowAttributes swa; - /* open display */ - dpy = XOpenDisplay(display); - if (NULL == dpy) return GL_TRUE; - /* query for glx */ - if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE; - /* choose visual */ - if (*visual == -1) - { - vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib); - if (NULL == vi) return GL_TRUE; - *visual = (int)XVisualIDFromVisual(vi->visual); - } - else - { - int n_vis, i; - vis = XGetVisualInfo(dpy, 0, NULL, &n_vis); - for (i=0; iscreen), 0, 0, 1, 1, 1, 0, 0);*/ - cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); - swa.border_pixel = 0; - swa.colormap = cmap; - wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen), - 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap, &swa); - /* make context current */ - if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; - return GL_FALSE; -} - -void glewDestroyContext () -{ - if (NULL != dpy && NULL != ctx) glXDestroyContext(dpy, ctx); - if (NULL != dpy && 0 != wnd) XDestroyWindow(dpy, wnd); - if (NULL != dpy && 0 != cmap) XFreeColormap(dpy, cmap); - if (NULL != vis) - XFree(vis); - else if (NULL != vi) - XFree(vi); - if (NULL != dpy) XCloseDisplay(dpy); -} - -#endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ diff --git a/WDL/lice/glew/src/visualinfo.c b/WDL/lice/glew/src/visualinfo.c deleted file mode 100644 index 98c391c0..00000000 --- a/WDL/lice/glew/src/visualinfo.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* -** visualinfo.c -** -** Copyright (C) Nate Robins, 1997 -** Michael Wimmer, 1999 -** Milan Ikits, 2002-2008 -** -** visualinfo is a small utility that displays all available visuals, -** aka. pixelformats, in an OpenGL system along with renderer version -** information. It shows a table of all the visuals that support OpenGL -** along with their capabilities. The format of the table is similar to -** that of glxinfo on Unix systems: -** -** visual ~= pixel format descriptor -** id = visual id (integer from 1 - max visuals) -** tp = type (wn: window, pb: pbuffer, wp: window & pbuffer, bm: bitmap) -** ac = acceleration (ge: generic, fu: full, no: none) -** fm = format (i: integer, f: float, c: color index) -** db = double buffer (y = yes) -** sw = swap method (x: exchange, c: copy, u: undefined) -** st = stereo (y = yes) -** sz = total # bits -** r = # bits of red -** g = # bits of green -** b = # bits of blue -** a = # bits of alpha -** axbf = # aux buffers -** dpth = # bits of depth -** stcl = # bits of stencil -*/ - -#include -#include -#include -#include -#if defined(_WIN32) -#include -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) -#include -#else -#include -#endif - -#ifdef GLEW_MX -GLEWContext _glewctx; -# define glewGetContext() (&_glewctx) -# ifdef _WIN32 -WGLEWContext _wglewctx; -# define wglewGetContext() (&_wglewctx) -# elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) -GLXEWContext _glxewctx; -# define glxewGetContext() (&_glxewctx) -# endif -#endif /* GLEW_MX */ - -typedef struct GLContextStruct -{ -#ifdef _WIN32 - HWND wnd; - HDC dc; - HGLRC rc; -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - AGLContext ctx, octx; -#else - Display* dpy; - XVisualInfo* vi; - GLXContext ctx; - Window wnd; - Colormap cmap; -#endif -} GLContext; - -void InitContext (GLContext* ctx); -GLboolean CreateContext (GLContext* ctx); -void DestroyContext (GLContext* ctx); -void VisualInfo (GLContext* ctx); -void PrintExtensions (const char* s); -GLboolean ParseArgs (int argc, char** argv); - -int showall = 0; -int displaystdout = 0; -int verbose = 0; -int drawableonly = 0; - -char* display = NULL; -int visual = -1; - -FILE* file = 0; -GLContext ctx; - -int -main (int argc, char** argv) -{ - GLenum err; - - /* ---------------------------------------------------------------------- */ - /* parse arguments */ - if (GL_TRUE == ParseArgs(argc-1, argv+1)) - { -#if defined(_WIN32) - fprintf(stderr, "Usage: visualinfo [-a] [-s] [-h] [-pf ]\n"); - fprintf(stderr, " -a: show all visuals\n"); - fprintf(stderr, " -s: display to stdout instead of visualinfo.txt\n"); - fprintf(stderr, " -pf : use given pixelformat\n"); - fprintf(stderr, " -h: this screen\n"); -#else - fprintf(stderr, "Usage: visualinfo [-h] [-display ] [-visual ]\n"); - fprintf(stderr, " -h: this screen\n"); - fprintf(stderr, " -display : use given display\n"); - fprintf(stderr, " -visual : use given visual\n"); -#endif - return 1; - } - - /* ---------------------------------------------------------------------- */ - /* create OpenGL rendering context */ - InitContext(&ctx); - if (GL_TRUE == CreateContext(&ctx)) - { - fprintf(stderr, "Error: CreateContext failed\n"); - DestroyContext(&ctx); - return 1; - } - - /* ---------------------------------------------------------------------- */ - /* initialize GLEW */ - glewExperimental = GL_TRUE; -#ifdef GLEW_MX - err = glewContextInit(glewGetContext()); -# ifdef _WIN32 - err = err || wglewContextInit(wglewGetContext()); -# elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) - err = err || glxewContextInit(glxewGetContext()); -# endif -#else - err = glewInit(); -#endif - if (GLEW_OK != err) - { - fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); - DestroyContext(&ctx); - return 1; - } - - /* ---------------------------------------------------------------------- */ - /* open file */ -#if defined(_WIN32) - if (!displaystdout) - file = fopen("visualinfo.txt", "w"); - if (file == NULL) - file = stdout; -#else - file = stdout; -#endif - - /* ---------------------------------------------------------------------- */ - /* output header information */ - /* OpenGL extensions */ - fprintf(file, "OpenGL vendor string: %s\n", glGetString(GL_VENDOR)); - fprintf(file, "OpenGL renderer string: %s\n", glGetString(GL_RENDERER)); - fprintf(file, "OpenGL version string: %s\n", glGetString(GL_VERSION)); - fprintf(file, "OpenGL extensions (GL_): \n"); - PrintExtensions((char*)glGetString(GL_EXTENSIONS)); - /* GLU extensions */ - fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION)); - fprintf(file, "GLU extensions (GLU_): \n"); - PrintExtensions((char*)gluGetString(GLU_EXTENSIONS)); - - /* ---------------------------------------------------------------------- */ - /* extensions string */ -#if defined(_WIN32) - /* WGL extensions */ - if (WGLEW_ARB_extensions_string || WGLEW_EXT_extensions_string) - { - fprintf(file, "WGL extensions (WGL_): \n"); - PrintExtensions(wglGetExtensionsStringARB ? - (char*)wglGetExtensionsStringARB(ctx.dc) : - (char*)wglGetExtensionsStringEXT()); - } -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - -#else - /* GLX extensions */ - fprintf(file, "GLX extensions (GLX_): \n"); - PrintExtensions(glXQueryExtensionsString(glXGetCurrentDisplay(), - DefaultScreen(glXGetCurrentDisplay()))); -#endif - - /* ---------------------------------------------------------------------- */ - /* enumerate all the formats */ - VisualInfo(&ctx); - - /* ---------------------------------------------------------------------- */ - /* release resources */ - DestroyContext(&ctx); - if (file != stdout) - fclose(file); - return 0; -} - -/* do the magic to separate all extensions with comma's, except - for the last one that _may_ terminate in a space. */ -void PrintExtensions (const char* s) -{ - char t[80]; - int i=0; - char* p=0; - - t[79] = '\0'; - while (*s) - { - t[i++] = *s; - if(*s == ' ') - { - if (*(s+1) != '\0') { - t[i-1] = ','; - t[i] = ' '; - p = &t[i++]; - } - else /* zoinks! last one terminated in a space! */ - { - t[i-1] = '\0'; - } - } - if(i > 80 - 5) - { - *p = t[i] = '\0'; - fprintf(file, " %s\n", t); - p++; - i = (int)strlen(p); - strcpy(t, p); - } - s++; - } - t[i] = '\0'; - fprintf(file, " %s.\n", t); -} - -/* ---------------------------------------------------------------------- */ - -#if defined(_WIN32) - -void -VisualInfoARB (GLContext* ctx) -{ - int attrib[32], value[32], n_attrib, n_pbuffer=0, n_float=0; - int i, pf, maxpf; - unsigned int c; - - /* to get pbuffer capable pixel formats */ - attrib[0] = WGL_DRAW_TO_PBUFFER_ARB; - attrib[1] = GL_TRUE; - attrib[2] = 0; - wglChoosePixelFormatARB(ctx->dc, attrib, 0, 1, &pf, &c); - /* query number of pixel formats */ - attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; - wglGetPixelFormatAttribivARB(ctx->dc, 0, 0, 1, attrib, value); - maxpf = value[0]; - for (i=0; i<32; i++) - value[i] = 0; - - attrib[0] = WGL_SUPPORT_OPENGL_ARB; - attrib[1] = WGL_DRAW_TO_WINDOW_ARB; - attrib[2] = WGL_DRAW_TO_BITMAP_ARB; - attrib[3] = WGL_ACCELERATION_ARB; - /* WGL_NO_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB */ - attrib[4] = WGL_SWAP_METHOD_ARB; - /* WGL_SWAP_EXCHANGE_ARB, WGL_SWAP_COPY_ARB, WGL_SWAP_UNDEFINED_ARB */ - attrib[5] = WGL_DOUBLE_BUFFER_ARB; - attrib[6] = WGL_STEREO_ARB; - attrib[7] = WGL_PIXEL_TYPE_ARB; - /* WGL_TYPE_RGBA_ARB, WGL_TYPE_COLORINDEX_ARB, - WGL_TYPE_RGBA_FLOAT_ATI (WGL_ATI_pixel_format_float) */ - /* Color buffer information */ - attrib[8] = WGL_COLOR_BITS_ARB; - attrib[9] = WGL_RED_BITS_ARB; - attrib[10] = WGL_GREEN_BITS_ARB; - attrib[11] = WGL_BLUE_BITS_ARB; - attrib[12] = WGL_ALPHA_BITS_ARB; - /* Accumulation buffer information */ - attrib[13] = WGL_ACCUM_BITS_ARB; - attrib[14] = WGL_ACCUM_RED_BITS_ARB; - attrib[15] = WGL_ACCUM_GREEN_BITS_ARB; - attrib[16] = WGL_ACCUM_BLUE_BITS_ARB; - attrib[17] = WGL_ACCUM_ALPHA_BITS_ARB; - /* Depth, stencil, and aux buffer information */ - attrib[18] = WGL_DEPTH_BITS_ARB; - attrib[19] = WGL_STENCIL_BITS_ARB; - attrib[20] = WGL_AUX_BUFFERS_ARB; - /* Layer information */ - attrib[21] = WGL_NUMBER_OVERLAYS_ARB; - attrib[22] = WGL_NUMBER_UNDERLAYS_ARB; - attrib[23] = WGL_SWAP_LAYER_BUFFERS_ARB; - attrib[24] = WGL_SAMPLES_ARB; - attrib[25] = WGL_SUPPORT_GDI_ARB; - n_attrib = 26; - if (WGLEW_ARB_pbuffer) - { - attrib[n_attrib] = WGL_DRAW_TO_PBUFFER_ARB; - n_pbuffer = n_attrib; - n_attrib++; - } - if (WGLEW_NV_float_buffer) - { - attrib[n_attrib] = WGL_FLOAT_COMPONENTS_NV; - n_float = n_attrib; - n_attrib++; - } - - if (!verbose) - { - /* print table header */ - fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); - fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); - fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); - fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); - /* loop through all the pixel formats */ - for(i = 1; i <= maxpf; i++) - { - wglGetPixelFormatAttribivARB(ctx->dc, i, 0, n_attrib, attrib, value); - /* only describe this format if it supports OpenGL */ - if (!value[0]) continue; - /* by default show only fully accelerated window or pbuffer capable visuals */ - if (!showall - && ((value[2] && !value[1]) - || (!WGLEW_ARB_pbuffer || !value[n_pbuffer]) - || (value[3] != WGL_FULL_ACCELERATION_ARB))) continue; - /* print out the information for this visual */ - /* visual id */ - fprintf(file, " |% 4d | ", i); - /* visual type */ - if (value[1]) - { - if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "wp "); - else fprintf(file, "wn "); - } - else - { - if (value[2]) fprintf(file, "bm "); - else if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "pb "); - } - /* acceleration */ - fprintf(file, "%s ", value[3] == WGL_FULL_ACCELERATION_ARB ? "fu" : - value[3] == WGL_GENERIC_ACCELERATION_ARB ? "ge" : - value[3] == WGL_NO_ACCELERATION_ARB ? "no" : ". "); - /* gdi support */ - fprintf(file, " %c ", value[25] ? 'y' : '.'); - /* format */ - if (WGLEW_NV_float_buffer && value[n_float]) fprintf(file, " f "); - else if (WGLEW_ATI_pixel_format_float && value[7] == WGL_TYPE_RGBA_FLOAT_ATI) fprintf(file, " f "); - else if (value[7] == WGL_TYPE_RGBA_ARB) fprintf(file, " i "); - else if (value[7] == WGL_TYPE_COLORINDEX_ARB) fprintf(file, " c "); - /* double buffer */ - fprintf(file, " %c ", value[5] ? 'y' : '.'); - /* swap method */ - if (value[4] == WGL_SWAP_EXCHANGE_ARB) fprintf(file, " x "); - else if (value[4] == WGL_SWAP_COPY_ARB) fprintf(file, " c "); - else if (value[4] == WGL_SWAP_UNDEFINED_ARB) fprintf(file, " . "); - else fprintf(file, " . "); - /* stereo */ - fprintf(file, " %c ", value[6] ? 'y' : '.'); - /* multisample */ - if (value[24] > 0) - fprintf(file, "%2d | ", value[24]); - else - fprintf(file, " . | "); - /* color size */ - if (value[8]) fprintf(file, "%3d ", value[8]); - else fprintf(file, " . "); - /* red */ - if (value[9]) fprintf(file, "%2d ", value[9]); - else fprintf(file, " . "); - /* green */ - if (value[10]) fprintf(file, "%2d ", value[10]); - else fprintf(file, " . "); - /* blue */ - if (value[11]) fprintf(file, "%2d ", value[11]); - else fprintf(file, " . "); - /* alpha */ - if (value[12]) fprintf(file, "%2d | ", value[12]); - else fprintf(file, " . | "); - /* aux buffers */ - if (value[20]) fprintf(file, "%2d ", value[20]); - else fprintf(file, " . "); - /* depth */ - if (value[18]) fprintf(file, "%2d ", value[18]); - else fprintf(file, " . "); - /* stencil */ - if (value[19]) fprintf(file, "%2d | ", value[19]); - else fprintf(file, " . | "); - /* accum size */ - if (value[13]) fprintf(file, "%3d ", value[13]); - else fprintf(file, " . "); - /* accum red */ - if (value[14]) fprintf(file, "%2d ", value[14]); - else fprintf(file, " . "); - /* accum green */ - if (value[15]) fprintf(file, "%2d ", value[15]); - else fprintf(file, " . "); - /* accum blue */ - if (value[16]) fprintf(file, "%2d ", value[16]); - else fprintf(file, " . "); - /* accum alpha */ - if (value[17]) fprintf(file, "%2d | ", value[17]); - else fprintf(file, " . | "); - /* overlay */ - if (value[21]) fprintf(file, "%2d ", value[21]); - else fprintf(file, " . "); - /* underlay */ - if (value[22]) fprintf(file, "%2d ", value[22]); - else fprintf(file, " . "); - /* layer swap */ - if (value[23]) fprintf(file, "y "); - else fprintf(file, " . "); - fprintf(file, "|\n"); - } - /* print table footer */ - fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); - fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); - fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); - fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); - } - else /* verbose */ - { -#if 0 - fprintf(file, "\n"); - /* loop through all the pixel formats */ - for(i = 1; i <= maxpf; i++) - { - DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - /* only describe this format if it supports OpenGL */ - if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) - || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; - fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, - pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); - fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); - fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); - fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); - fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); - fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); - fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); - fprintf(file, " Opaque.\n"); - } -#endif - } -} - -void -VisualInfoGDI (GLContext* ctx) -{ - int i, maxpf; - PIXELFORMATDESCRIPTOR pfd; - - /* calling DescribePixelFormat() with NULL pfd (!!!) return maximum - number of pixel formats */ - maxpf = DescribePixelFormat(ctx->dc, 1, 0, NULL); - - if (!verbose) - { - fprintf(file, "-----------------------------------------------------------------------------\n"); - fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); - fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); - fprintf(file, "-----------------------------------------------------------------------------\n"); - - /* loop through all the pixel formats */ - for(i = 1; i <= maxpf; i++) - { - DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - /* only describe this format if it supports OpenGL */ - if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) - || (drawableonly && (pfd.dwFlags & PFD_DRAW_TO_BITMAP))) continue; - /* other criteria could be tested here for actual pixel format - choosing in an application: - - for (...each pixel format...) { - if (pfd.dwFlags & PFD_SUPPORT_OPENGL && - pfd.dwFlags & PFD_DOUBLEBUFFER && - pfd.cDepthBits >= 24 && - pfd.cColorBits >= 24) - { - goto found; - } - } - ... not found so exit ... - found: - ... found so use it ... - */ - /* print out the information for this pixel format */ - fprintf(file, "0x%02x ", i); - fprintf(file, "%3d ", pfd.cColorBits); - if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) fprintf(file, "wn "); - else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) fprintf(file, "bm "); - else fprintf(file, "pb "); - /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ - fprintf(file, " . "); - fprintf(file, "%3d ", pfd.cColorBits); - /* bReserved field indicates number of over/underlays */ - if(pfd.bReserved) fprintf(file, " %d ", pfd.bReserved); - else fprintf(file, " . "); - fprintf(file, " %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); - fprintf(file, "%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); - fprintf(file, " %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.'); - /* added: */ - fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_FORMAT ? 'y' : '.'); - fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_ACCELERATED ? 'y' : '.'); - if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) - fprintf(file, "%2d ", pfd.cRedBits); - else fprintf(file, " . "); - if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) - fprintf(file, "%2d ", pfd.cGreenBits); - else fprintf(file, " . "); - if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) - fprintf(file, "%2d ", pfd.cBlueBits); - else fprintf(file, " . "); - if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) - fprintf(file, "%2d ", pfd.cAlphaBits); - else fprintf(file, " . "); - if(pfd.cAuxBuffers) fprintf(file, "%2d ", pfd.cAuxBuffers); - else fprintf(file, " . "); - if(pfd.cDepthBits) fprintf(file, "%2d ", pfd.cDepthBits); - else fprintf(file, " . "); - if(pfd.cStencilBits) fprintf(file, "%2d ", pfd.cStencilBits); - else fprintf(file, " . "); - if(pfd.cAccumBits) fprintf(file, "%3d ", pfd.cAccumBits); - else fprintf(file, " . "); - if(pfd.cAccumRedBits) fprintf(file, "%2d ", pfd.cAccumRedBits); - else fprintf(file, " . "); - if(pfd.cAccumGreenBits) fprintf(file, "%2d ", pfd.cAccumGreenBits); - else fprintf(file, " . "); - if(pfd.cAccumBlueBits) fprintf(file, "%2d ", pfd.cAccumBlueBits); - else fprintf(file, " . "); - if(pfd.cAccumAlphaBits) fprintf(file, "%2d ", pfd.cAccumAlphaBits); - else fprintf(file, " . "); - /* no multisample in win32 */ - fprintf(file, " . .\n"); - } - /* print table footer */ - fprintf(file, "-----------------------------------------------------------------------------\n"); - fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); - fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); - fprintf(file, "-----------------------------------------------------------------------------\n"); - } - else /* verbose */ - { - fprintf(file, "\n"); - /* loop through all the pixel formats */ - for(i = 1; i <= maxpf; i++) - { - DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - /* only describe this format if it supports OpenGL */ - if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) - || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; - fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, - pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); - fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%ld stereo=%ld\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); - fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); - fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); - fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); - fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); - fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); - fprintf(file, " Opaque.\n"); - } - } -} - -void -VisualInfo (GLContext* ctx) -{ - if (WGLEW_ARB_pixel_format) - VisualInfoARB(ctx); - else - VisualInfoGDI(ctx); -} - -/* ---------------------------------------------------------------------- */ - -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - -void -VisualInfo (GLContext* ctx) -{ -/* - int attrib[] = { AGL_RGBA, AGL_NONE }; - AGLPixelFormat pf; - GLint value; - pf = aglChoosePixelFormat(NULL, 0, attrib); - while (pf != NULL) - { - aglDescribePixelFormat(pf, GL_RGBA, &value); - fprintf(stderr, "%d\n", value); - pf = aglNextPixelFormat(pf); - } -*/ -} - -#else /* GLX */ - -void -VisualInfo (GLContext* ctx) -{ - int n_fbc; - GLXFBConfig* fbc; - int value, ret, i; - - fbc = glXGetFBConfigs(ctx->dpy, DefaultScreen(ctx->dpy), &n_fbc); - - if (fbc) - { - if (!verbose) - { - /* print table header */ - fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); - fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); - fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); - fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); - /* loop through all the fbcs */ - for (i=0; idpy, fbc[i], GLX_FBCONFIG_ID, &value); - if (ret != Success) - { - fprintf(file, "| ? |"); - } - else - { - fprintf(file, " |% 4d | ", value); - } - /* visual type */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DRAWABLE_TYPE, &value); - if (ret != Success) - { - fprintf(file, " ? "); - } - else - { - if (value & GLX_WINDOW_BIT) - { - if (value & GLX_PBUFFER_BIT) - { - fprintf(file, "wp "); - } - else - { - fprintf(file, "wn "); - } - } - else - { - if (value & GLX_PBUFFER_BIT) - { - fprintf(file, "pb "); - } - else if (value & GLX_PIXMAP_BIT) - { - fprintf(file, "pm "); - } - else - { - fprintf(file, " ? "); - } - } - } - /* x renderable */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_RENDERABLE, &value); - if (ret != Success) - { - fprintf(file, " ? "); - } - else - { - fprintf(file, value ? " y " : " n "); - } - /* class */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_VISUAL_TYPE, &value); - if (ret != Success) - { - fprintf(file, " ? "); - } - else - { - if (GLX_TRUE_COLOR == value) - fprintf(file, "tc "); - else if (GLX_DIRECT_COLOR == value) - fprintf(file, "dc "); - else if (GLX_PSEUDO_COLOR == value) - fprintf(file, "pc "); - else if (GLX_STATIC_COLOR == value) - fprintf(file, "sc "); - else if (GLX_GRAY_SCALE == value) - fprintf(file, "gs "); - else if (GLX_STATIC_GRAY == value) - fprintf(file, "sg "); - else if (GLX_X_VISUAL_TYPE == value) - fprintf(file, " . "); - else - fprintf(file, " ? "); - } - /* format */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RENDER_TYPE, &value); - if (ret != Success) - { - fprintf(file, " ? "); - } - else - { - if (GLXEW_NV_float_buffer) - { - int ret2, value2; - ret2 = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_FLOAT_COMPONENTS_NV, &value2); - if (Success == ret2 && GL_TRUE == value2) - { - fprintf(file, " f "); - } - else if (value & GLX_RGBA_BIT) - fprintf(file, " i "); - else if (value & GLX_COLOR_INDEX_BIT) - fprintf(file, " c "); - else - fprintf(file, " ? "); - } - else - { - if (value & GLX_RGBA_FLOAT_ATI_BIT) - fprintf(file, " f "); - else if (value & GLX_RGBA_BIT) - fprintf(file, " i "); - else if (value & GLX_COLOR_INDEX_BIT) - fprintf(file, " c "); - else - fprintf(file, " ? "); - } - } - /* double buffer */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DOUBLEBUFFER, &value); - fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); - /* stereo */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STEREO, &value); - fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); - /* level */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_LEVEL, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - fprintf(file, "%2d ", value); - } - /* transparency */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_TRANSPARENT_TYPE, &value); - if (Success != ret) - { - fprintf(file, " ? | "); - } - else - { - if (GLX_TRANSPARENT_RGB == value) - fprintf(file, " r | "); - else if (GLX_TRANSPARENT_INDEX == value) - fprintf(file, " i | "); - else if (GLX_NONE == value) - fprintf(file, " . | "); - else - fprintf(file, " ? | "); - } - /* color size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BUFFER_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%3d ", value); - else - fprintf(file, " . "); - } - /* red size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RED_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* green size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_GREEN_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* blue size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BLUE_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* alpha size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ALPHA_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? | "); - } - else - { - if (value) - fprintf(file, "%2d | ", value); - else - fprintf(file, " . | "); - } - /* aux buffers */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_AUX_BUFFERS, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* depth size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DEPTH_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* stencil size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STENCIL_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? | "); - } - else - { - if (value) - fprintf(file, "%2d | ", value); - else - fprintf(file, " . | "); - } - /* accum red size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_RED_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* accum green size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_GREEN_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* accum blue size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_BLUE_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - if (value) - fprintf(file, "%2d ", value); - else - fprintf(file, " . "); - } - /* accum alpha size */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_ALPHA_SIZE, &value); - if (Success != ret) - { - fprintf(file, " ? | "); - } - else - { - if (value) - fprintf(file, "%2d | ", value); - else - fprintf(file, " . | "); - } - /* multisample */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLES, &value); - if (Success != ret) - { - fprintf(file, " ? "); - } - else - { - fprintf(file, "%2d ", value); - } - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLE_BUFFERS, &value); - if (Success != ret) - { - fprintf(file, " ? | "); - } - else - { - fprintf(file, "%2d | ", value); - } - /* caveat */ - ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_CONFIG_CAVEAT, &value); - if (Success != ret) - { - fprintf(file, "???? |"); - } - else - { - if (GLX_NONE == value) - fprintf(file, "none |\n"); - else if (GLX_SLOW_CONFIG == value) - fprintf(file, "slow |\n"); - else if (GLX_NON_CONFORMANT_CONFIG == value) - fprintf(file, "ncft |\n"); - else - fprintf(file, "???? |\n"); - } - } - /* print table footer */ - fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); - fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); - fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); - fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); - } - } -} - -#endif - -/* ------------------------------------------------------------------------ */ - -#if defined(_WIN32) - -void InitContext (GLContext* ctx) -{ - ctx->wnd = NULL; - ctx->dc = NULL; - ctx->rc = NULL; -} - -GLboolean CreateContext (GLContext* ctx) -{ - WNDCLASS wc; - PIXELFORMATDESCRIPTOR pfd; - /* check for input */ - if (NULL == ctx) return GL_TRUE; - /* register window class */ - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.hInstance = GetModuleHandle(NULL); - wc.lpfnWndProc = DefWindowProc; - wc.lpszClassName = "GLEW"; - if (0 == RegisterClass(&wc)) return GL_TRUE; - /* create window */ - ctx->wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, - GetModuleHandle(NULL), NULL); - if (NULL == ctx->wnd) return GL_TRUE; - /* get the device context */ - ctx->dc = GetDC(ctx->wnd); - if (NULL == ctx->dc) return GL_TRUE; - /* find pixel format */ - ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); - if (visual == -1) /* find default */ - { - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - visual = ChoosePixelFormat(ctx->dc, &pfd); - if (0 == visual) return GL_TRUE; - } - /* set the pixel format for the dc */ - if (FALSE == SetPixelFormat(ctx->dc, visual, &pfd)) return GL_TRUE; - /* create rendering context */ - ctx->rc = wglCreateContext(ctx->dc); - if (NULL == ctx->rc) return GL_TRUE; - if (FALSE == wglMakeCurrent(ctx->dc, ctx->rc)) return GL_TRUE; - return GL_FALSE; -} - -void DestroyContext (GLContext* ctx) -{ - if (NULL == ctx) return; - if (NULL != ctx->rc) wglMakeCurrent(NULL, NULL); - if (NULL != ctx->rc) wglDeleteContext(wglGetCurrentContext()); - if (NULL != ctx->wnd && NULL != ctx->dc) ReleaseDC(ctx->wnd, ctx->dc); - if (NULL != ctx->wnd) DestroyWindow(ctx->wnd); - UnregisterClass("GLEW", GetModuleHandle(NULL)); -} - -/* ------------------------------------------------------------------------ */ - -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) - -void InitContext (GLContext* ctx) -{ - ctx->ctx = NULL; - ctx->octx = NULL; -} - -GLboolean CreateContext (GLContext* ctx) -{ - int attrib[] = { AGL_RGBA, AGL_NONE }; - AGLPixelFormat pf; - /* check input */ - if (NULL == ctx) return GL_TRUE; - /*int major, minor; - SetPortWindowPort(wnd); - aglGetVersion(&major, &minor); - fprintf(stderr, "GL %d.%d\n", major, minor);*/ - pf = aglChoosePixelFormat(NULL, 0, attrib); - if (NULL == pf) return GL_TRUE; - ctx->ctx = aglCreateContext(pf, NULL); - if (NULL == ctx->ctx || AGL_NO_ERROR != aglGetError()) return GL_TRUE; - aglDestroyPixelFormat(pf); - /*aglSetDrawable(ctx, GetWindowPort(wnd));*/ - ctx->octx = aglGetCurrentContext(); - if (NULL == aglSetCurrentContext(ctx->ctx)) return GL_TRUE; - return GL_FALSE; -} - -void DestroyContext (GLContext* ctx) -{ - if (NULL == ctx) return; - aglSetCurrentContext(ctx->octx); - if (NULL != ctx->ctx) aglDestroyContext(ctx->ctx); -} - -/* ------------------------------------------------------------------------ */ - -#else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ - -void InitContext (GLContext* ctx) -{ - ctx->dpy = NULL; - ctx->vi = NULL; - ctx->ctx = NULL; - ctx->wnd = 0; - ctx->cmap = 0; -} - -GLboolean CreateContext (GLContext* ctx) -{ - int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; - int erb, evb; - XSetWindowAttributes swa; - /* check input */ - if (NULL == ctx) return GL_TRUE; - /* open display */ - ctx->dpy = XOpenDisplay(display); - if (NULL == ctx->dpy) return GL_TRUE; - /* query for glx */ - if (!glXQueryExtension(ctx->dpy, &erb, &evb)) return GL_TRUE; - /* choose visual */ - ctx->vi = glXChooseVisual(ctx->dpy, DefaultScreen(ctx->dpy), attrib); - if (NULL == ctx->vi) return GL_TRUE; - /* create context */ - ctx->ctx = glXCreateContext(ctx->dpy, ctx->vi, None, True); - if (NULL == ctx->ctx) return GL_TRUE; - /* create window */ - /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ - ctx->cmap = XCreateColormap(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), - ctx->vi->visual, AllocNone); - swa.border_pixel = 0; - swa.colormap = ctx->cmap; - ctx->wnd = XCreateWindow(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), - 0, 0, 1, 1, 0, ctx->vi->depth, InputOutput, ctx->vi->visual, - CWBorderPixel | CWColormap, &swa); - /* make context current */ - if (!glXMakeCurrent(ctx->dpy, ctx->wnd, ctx->ctx)) return GL_TRUE; - return GL_FALSE; -} - -void DestroyContext (GLContext* ctx) -{ - if (NULL != ctx->dpy && NULL != ctx->ctx) glXDestroyContext(ctx->dpy, ctx->ctx); - if (NULL != ctx->dpy && 0 != ctx->wnd) XDestroyWindow(ctx->dpy, ctx->wnd); - if (NULL != ctx->dpy && 0 != ctx->cmap) XFreeColormap(ctx->dpy, ctx->cmap); - if (NULL != ctx->vi) XFree(ctx->vi); - if (NULL != ctx->dpy) XCloseDisplay(ctx->dpy); -} - -#endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ - -GLboolean ParseArgs (int argc, char** argv) -{ - int p = 0; - while (p < argc) - { -#if defined(_WIN32) - if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) - { - if (++p >= argc) return GL_TRUE; - display = NULL; - visual = strtol(argv[p], NULL, 0); - } - else if (!strcmp(argv[p], "-a")) - { - showall = 1; - } - else if (!strcmp(argv[p], "-s")) - { - displaystdout = 1; - } - else if (!strcmp(argv[p], "-h")) - { - return GL_TRUE; - } - else - return GL_TRUE; -#else - if (!strcmp(argv[p], "-display")) - { - if (++p >= argc) return GL_TRUE; - display = argv[p]; - } - else if (!strcmp(argv[p], "-visual")) - { - if (++p >= argc) return GL_TRUE; - visual = (int)strtol(argv[p], NULL, 0); - } - else if (!strcmp(argv[p], "-h")) - { - return GL_TRUE; - } - else - return GL_TRUE; -#endif - p++; - } - return GL_FALSE; -} diff --git a/WDL/lice/lice.cpp b/WDL/lice/lice.cpp deleted file mode 100644 index 839a7ef5..00000000 --- a/WDL/lice/lice.cpp +++ /dev/null @@ -1,2173 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice.cpp (LICE core processing) - See lice.h for license and other information -*/ - - -#ifndef __LICE_CPP_IMPLEMENTED__ -#define __LICE_CPP_IMPLEMENTED__ - -#include "lice.h" -#include -#include // only included in case we need to debug with sprintf etc - -#include "lice_combine.h" -#include "lice_extended.h" - -#ifndef _WIN32 -#include "../swell/swell.h" -#endif - -_LICE_ImageLoader_rec *LICE_ImageLoader_list; - -LICE_pixel LICE_CombinePixels(LICE_pixel dest, LICE_pixel src, float alpha, int mode) -{ - int r = LICE_GETR(src); - int g = LICE_GETG(src); - int b = LICE_GETB(src); - int a = LICE_GETA(src); - int al = (int)(alpha*256.0f); - -#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)&dest,r, g, b, a, al) - __LICE_ACTION_SRCALPHA(mode, al,false); -#undef __LICE__ACTION - - return dest; -} - - -void LICE_CombinePixels2(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode) -{ -#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia) - __LICE_ACTION_SRCALPHA(mode, ia, false); -#undef __LICE__ACTION -} -void LICE_CombinePixels2Clamp(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode) -{ -#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia) - __LICE_ACTION_SRCALPHA(mode, ia, true); -#undef __LICE__ACTION -} - - -LICE_MemBitmap::LICE_MemBitmap(int w, int h, unsigned int linealign) -{ - m_allocsize=0; - m_fb=0; - m_width=0; - m_height=0; - m_linealign = linealign > 1 ? ((linealign & ~(linealign-1))-1) : 0; // force to be contiguous bits - if (m_linealign>16) m_linealign=16; - if (w||h) resize(w,h); -} - -LICE_MemBitmap::~LICE_MemBitmap() { free(m_fb); } - -bool LICE_MemBitmap::resize(int w, int h) -{ - if (w!=m_width||h!=m_height) - { -#ifdef DEBUG_TIGHT_ALLOC // dont enable for anything you want to be even remotely fast - free(m_fb); - m_fb = (LICE_pixel *)malloc((m_allocsize = ((w+m_linealign)&~m_linealign)*h*sizeof(LICE_pixel)) + LICE_MEMBITMAP_ALIGNAMT); - m_width=m_fb?w:0; - m_height=m_fb?h:0; - return true; -#endif - int sz=(((m_width=w)+m_linealign)&~m_linealign)*(m_height=h)*sizeof(LICE_pixel); - - if (sz<=0) { free(m_fb); m_fb=0; m_allocsize=0; } - else if (!m_fb) m_fb=(LICE_pixel*)malloc((m_allocsize=sz) + LICE_MEMBITMAP_ALIGNAMT); - else - { - if (sz>m_allocsize) - { - void *op=m_fb; - if (!(m_fb=(LICE_pixel*)realloc(m_fb,(m_allocsize=sz+sz/4)+LICE_MEMBITMAP_ALIGNAMT))) - { - free(op); - m_fb=(LICE_pixel*)malloc((m_allocsize=sz)+LICE_MEMBITMAP_ALIGNAMT); - } - } - } - if (!m_fb) {m_width=m_height=0; } - - return true; - } - return false; -} - - - -#ifndef _LICE_NO_SYSBITMAPS_ - -LICE_SysBitmap::LICE_SysBitmap(int w, int h) -{ - m_allocw=m_alloch=0; -#ifdef _WIN32 - m_dc = CreateCompatibleDC(NULL); - m_bitmap = 0; - m_oldbitmap = 0; -#else - m_dc=0; -#endif - m_bits=0; - m_width=m_height=0; - - resize(w,h); -} - - -LICE_SysBitmap::~LICE_SysBitmap() -{ -#ifdef _WIN32 - if (m_oldbitmap && m_dc) SelectObject(m_dc,m_oldbitmap); - if (m_bitmap) DeleteObject(m_bitmap); - if (m_dc) DeleteDC(m_dc); -#else - if (m_dc) - SWELL_DeleteGfxContext(m_dc); -#endif -} - -bool LICE_SysBitmap::resize(int w, int h) -{ -#ifdef _WIN32 - if (!m_dc) { m_width=m_height=0; m_bits=0; return false; } -#endif - - if (m_width==w && m_height == h) return false; - - m_width=w; - m_height=h; - -#ifndef DEBUG_TIGHT_ALLOC - // dont resize down bitmaps - if (w && h && w <= m_allocw && h <= m_alloch && m_bits) - { -#ifndef _WIN32 - if (isFlipped()) - { - m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc); - m_bits += (m_alloch-h)*m_allocw; - } -#endif - return true; - } -#endif//!DEBUG_TIGHT_ALLOC - - w = (w+3)&~3; // always keep backing store a multiple of 4px wide - - - m_allocw=w; - m_alloch=h; - -#ifdef _WIN32 - if (m_oldbitmap) - { - SelectObject(m_dc,m_oldbitmap); - m_oldbitmap=0; - } - if (m_bitmap) DeleteObject(m_bitmap); - m_bitmap=0; - m_bits=0; - - - if (!w || !h) return false; - - BITMAPINFO pbmInfo = {0,}; - pbmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmInfo.bmiHeader.biWidth = w; - pbmInfo.bmiHeader.biHeight = isFlipped()?h:-h; - pbmInfo.bmiHeader.biPlanes = 1; - pbmInfo.bmiHeader.biBitCount = sizeof(LICE_pixel)*8; - pbmInfo.bmiHeader.biCompression = BI_RGB; - m_bitmap = CreateDIBSection( NULL, &pbmInfo, DIB_RGB_COLORS, (void **)&m_bits, NULL, 0); - - if (m_bitmap) m_oldbitmap=SelectObject(m_dc, m_bitmap); - else { m_width=m_height=0; m_bits=0; } -#else - if (m_dc) SWELL_DeleteGfxContext(m_dc); - m_dc=0; - m_bits=0; - - if (!w || !h) return false; - - m_dc=SWELL_CreateMemContext(0,w,h); - if (!m_dc) { m_width=m_height=0; m_bits=0; } - else m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc); -#endif - - return true; -} - -#endif // _LICE_NO_SYSBITMAPS_ - - - -#ifndef LICE_NO_BLIT_SUPPORT -void LICE_Copy(LICE_IBitmap *dest, LICE_IBitmap *src) // resizes dest -{ - if (src&&dest) - { - dest->resize(src->getWidth(),src->getHeight()); - LICE_Blit(dest,src,0,0,NULL,1.0,LICE_BLIT_MODE_COPY); - } -} -#endif - -template class _LICE_Template_Blit0 // these always templated -{ - public: - static void solidBlitFAST(LICE_pixel *dest, int w, int h, - LICE_pixel color, - int dest_span) - { - while (h--) - { - LICE_pixel *pout=dest; - int n=w; - while (n--) - { - COMBFUNC::doPixFAST(pout,color); - ++pout; - } - dest+=dest_span; - } - } - - - - static void scaleBlitFAST(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, - int icurx, int icury, int idx, int idy, int clipright, int clipbottom, - int src_span, int dest_span) - { - LICE_pixel* destpx = (LICE_pixel*) dest; - int destpxspan = dest_span*sizeof(LICE_pixel_chan)/sizeof(LICE_pixel); - - //LICE_pixel* srcpx = (LICE_pixel*) src; - //int srcpxspan = src_span*sizeof(LICE_pixel_chan)/sizeof(LICE_pixel); - // todo cast inptr back to LICE_pixel - - while (h--) - { - int cury = icury/65536; - if (cury >= 0 && cury < clipbottom) - { - int curx=icurx; - LICE_pixel_chan *inptr=src + cury * src_span; - LICE_pixel* pout = destpx; - int n=w; - while (n--) - { - int offs=curx/65536; - if (offs>=0 && offs -#endif -class _LICE_Template_Blit1 // these controlled by LICE_FAVOR_SIZE_EXTREME -{ -#ifdef LICE_FAVOR_SIZE_EXTREME - #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); -#else - #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); -#endif - public: - static void solidBlit(LICE_pixel_chan *dest, int w, int h, - int ir, int ig, int ib, int ia, - int dest_span -#ifdef LICE_FAVOR_SIZE_EXTREME - , LICE_COMBINEFUNC combFunc -#endif - ) - { - while (h--) - { - LICE_pixel_chan *pout=dest; - int n=w; - while (n--) - { - DOPIX(pout,ir,ig,ib,ia,ia); - pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - } - dest+=dest_span; - } - } - static void gradBlit(LICE_pixel_chan *dest, int w, int h, - int ir, int ig, int ib, int ia, - int drdx, int dgdx, int dbdx, int dadx, - int drdy, int dgdy, int dbdy, int dady, - int dest_span -#ifdef LICE_FAVOR_SIZE_EXTREME - , LICE_COMBINEFUNC combFunc -#endif - ) - { - while (h--) - { - int r=ir,g=ig,b=ib,a=ia; - ir+=drdy; ig+=dgdy; ib+=dbdy; ia+=dady; - LICE_pixel_chan *pout=dest; - int n=w; - while (n--) - { - int ia=a/65536; - DOPIX(pout,r/65536,g/65536,b/65536,ia,ia); - pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - r+=drdx; g+=dgdx; b+=dbdx; a+=dadx; - } - dest+=dest_span; - } - } - -#undef DOPIX -}; - - -#ifndef LICE_FAVOR_SIZE -template -#endif -class _LICE_Template_Blit2 // these controlled by LICE_FAVOR_SIZE -{ -#ifdef LICE_FAVOR_SIZE - #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); -#else - #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); -#endif - - public: - - static void blit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, int src_span, int dest_span, int ia -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - ) - { - while (h-->0) - { - int n=w; - LICE_pixel_chan *pin=src; - LICE_pixel_chan *pout=dest; - while (n--) - { - - DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia); - - pin += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - } - dest+=dest_span; - src += src_span; - } - } - - // this is only designed for filtering down an image approx 2:1 to 4:1 or so.. it'll work (poortly) for higher, and for less it's crap too. - // probably need to redo it using linear interpolation of the filter coefficients, but bleh I'm gonna go play some call of duty - static void scaleBlitFilterDown(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, - int icurx, int icury, int idx, int idy, int clipright, int clipbottom, - int src_span, int dest_span, int ia, int *filter, int filt_start, int filtsz -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - - ) - { - - while (h--) - { - int cury = icury/65536; - int curx=icurx; - int n=w; - if (cury >= 0 && cury < clipbottom) - { - LICE_pixel_chan *inptr=src + (cury+filt_start) * src_span; - LICE_pixel_chan *pout=dest; - while (n--) - { - int offs=curx/65536; - if (offs>=0 && offs= clipbottom) break; - - if (ypos >= 0) - { - int xpos=offs + filt_start; - LICE_pixel_chan *pin = rdptr; - int fx=filtsz; - while (fx--) - { - int tsc = *scaletab++; - if (xpos >= 0 && xpos < clipright) - { - r+=pin[LICE_PIXEL_R]*tsc; - g+=pin[LICE_PIXEL_G]*tsc; - b+=pin[LICE_PIXEL_B]*tsc; - a+=pin[LICE_PIXEL_A]*tsc; - sc+=tsc; - } - xpos++; - pin+=sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - } - } - else scaletab += filtsz; - - ypos++; - rdptr+=src_span; - } - if (sc>0) - { - DOPIX(pout,r/sc,g/sc,b/sc,a/sc,ia); - } - } - - pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - curx+=idx; - } - } - dest+=dest_span; - icury+=idy; - } - } - static void scaleBlit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, - int icurx, int icury, int idx, int idy, int clipright, int clipbottom, - int src_span, int dest_span, int ia, int filtermode -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - - ) - { - - if (filtermode == LICE_BLIT_FILTER_BILINEAR) - { - while (h--) - { - int cury = icury/65536; - int yfrac=icury&65535; - int curx=icurx; - LICE_pixel_chan *inptr=src + cury * src_span; - LICE_pixel_chan *pout=dest; - int n=w; - if (cury >= 0 && cury < clipbottom-1) - { - while (n--) - { - int offs=curx/65536; - LICE_pixel_chan *pin = inptr + offs*sizeof(LICE_pixel); - if (offs>=0 && offs=0 && offs= 0 && cury < clipbottom) - { - int curx=icurx; - LICE_pixel_chan *inptr=src + cury * src_span; - LICE_pixel_chan *pout=dest; - int n=w; - while (n--) - { - int offs=curx/65536; - if (offs>=0 && offs -#endif -class _LICE_Template_Blit3 // stuff controlled by LICE_FAVOR_SPEED -{ -#ifndef LICE_FAVOR_SPEED - #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); -#else - #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); -#endif - - public: - - static void deltaBlit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, - int isrcx, int isrcy, int idsdx, int idtdx, int idsdy, int idtdy, - int idsdxdy, int idtdxdy, - int src_left, int src_top, int src_right, int src_bottom, - int src_span, int dest_span, int ia, int filtermode -#ifndef LICE_FAVOR_SPEED - , LICE_COMBINEFUNC combFunc -#endif - ) - { - if (filtermode == LICE_BLIT_FILTER_BILINEAR) - { - while (h--) - { - int thisx=isrcx; - int thisy=isrcy; - LICE_pixel_chan *pout=dest; - int n=w; - while (n--) - { - int cury = thisy/65536; - int curx = thisx/65536; - if (cury >= src_top && cury < src_bottom-1) - { - if (curx >= src_left && curx < src_right-1) - { - LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); - int r,g,b,a; - - __LICE_BilinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisx&65535,thisy&65535); - - DOPIX(pout,r,g,b,a,ia); - } - else if (curx==src_right-1) - { - - LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); - int r,g,b,a; - - __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisy&65535); - DOPIX(pout,r,g,b,a,ia); - } - } - else if (cury==src_bottom-1) - { - if (curx>=src_left && curx= src_top && cury < src_bottom && curx >= src_left && curx < src_right) - { - - LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); - - DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia); - } - - pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); - thisx+=idsdx; - thisy+=idtdx; - } - idsdx+=idsdxdy; - idtdx+=idtdxdy; - isrcx+=idsdy; - isrcy+=idtdy; - dest+=dest_span; - } - } - } - -#undef DOPIX -}; - -#ifndef LICE_NO_GRADIENT_SUPPORT - -void LICE_GradRect(LICE_IBitmap *dest, int dstx, int dsty, int dstw, int dsth, - float ir, float ig, float ib, float ia, - float drdx, float dgdx, float dbdx, float dadx, - float drdy, float dgdy, float dbdy, float dady, - int mode) -{ - if (!dest) return; - - ir*=255.0; ig*=255.0; ib*=255.0; ia*=256.0; - drdx*=255.0; dgdx*=255.0; dbdx*=255.0; dadx*=256.0; - drdy*=255.0; dgdy*=255.0; dbdy*=255.0; dady*=256.0; - // dont scale alpha - - // clip to output - if (dstx < 0) { ir-=dstx*drdx; ig-=dstx*dgdx; ib-=dstx*dbdx; ia-=dstx*dadx; dstw+=dstx; dstx=0; } - if (dsty < 0) - { - ir -= dsty*drdy; ig-=dsty*dgdy; ib -= dsty*dbdy; ia -= dsty*dady; - dsth += dsty; - dsty=0; - } - if (dstx+dstw > dest->getWidth()) dstw =(dest->getWidth()-dstx); - if (dsty+dsth > dest->getHeight()) dsth = (dest->getHeight()-dsty); - - if (dstw<1 || dsth<1) return; - - int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); - LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); - if (!pdest) return; - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else - { - pdest += dsty*dest_span; - } - pdest+=dstx*sizeof(LICE_pixel); -#define TOFIX(a) ((int)((a)*65536.0)) - - int iir=TOFIX(ir), iig=TOFIX(ig), iib=TOFIX(ib), iia=TOFIX(ia), idrdx=TOFIX(drdx),idgdx=TOFIX(dgdx),idbdx=TOFIX(dbdx),idadx=TOFIX(dadx), - idrdy=TOFIX(drdy), idgdy=TOFIX(dgdy), idbdy=TOFIX(dbdy), idady=TOFIX(dady); - - -#ifdef LICE_FAVOR_SIZE_EXTREME - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; -#else - - #define __LICE__ACTION(comb) _LICE_Template_Blit1::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span) -#endif - - // todo: could predict whether or not the colors will ever go out of 0.255 range and optimize - - if ((mode & LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY && iia==65536 && idady==0 && idadx == 0) - { - __LICE__ACTION(_LICE_CombinePixelsClobberClamp); - } - else - { - __LICE_ACTION_NOSRCALPHA(mode,256,true); - } - #undef __LICE__ACTION - -#ifdef LICE_FAVOR_SIZE_EXTREME - if (blitfunc) _LICE_Template_Blit1::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span,blitfunc); -#endif - -#undef TOFIX -} - -#endif - - -#ifndef LICE_NO_BLIT_SUPPORT -void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch, float alpha, int mode) -{ - RECT r={srcx,srcy,srcx+srcw,srcy+srch}; - LICE_Blit(dest,src,dstx,dsty,&r,alpha,mode); -} - -void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, RECT *srcrect, float alpha, int mode) -{ - if (!dest || !src || !alpha) return; - - RECT sr={0,0,src->getWidth(),src->getHeight()}; - if (srcrect) - { - sr=*srcrect; - if (sr.left < 0) { dstx-=sr.left; sr.left=0; } - if (sr.top < 0) { dsty-=sr.top; sr.top=0; } - if (sr.right > src->getWidth()) sr.right=src->getWidth(); - if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight(); - } - - // clip to output - if (dstx < 0) { sr.left -= dstx; dstx=0; } - if (dsty < 0) { sr.top -= dsty; dsty=0; } - if (dstx+sr.right-sr.left > dest->getWidth()) sr.right = sr.left + (dest->getWidth()-dstx); - if (dsty+sr.bottom-sr.top > dest->getHeight()) sr.bottom = sr.top + (dest->getHeight()-dsty); - - // ignore blits that are 0 - if (sr.right <= sr.left || sr.bottom <= sr.top) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_BLIT_ACCEL)) - { - LICE_Ext_Blit_acceldata data(src, dstx, dsty, - sr.left, sr.top, - sr.right-sr.left, sr.bottom-sr.top, - alpha, mode); - if (dest->Extended(LICE_EXT_BLIT_ACCEL, &data)) return; - } -#endif - - - int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); - int src_span=src->getRowSpan()*sizeof(LICE_pixel); - LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); - LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); - if (!psrc || !pdest) return; - - if (src->isFlipped()) - { - psrc += (src->getHeight()-sr.top - 1)*src_span; - src_span=-src_span; - } - else psrc += sr.top*src_span; - psrc += sr.left*sizeof(LICE_pixel); - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else pdest += dsty*dest_span; - pdest+=dstx*sizeof(LICE_pixel); - - int i=sr.bottom-sr.top; - int cpsize=sr.right-sr.left; - - if ((mode&LICE_BLIT_MODE_MASK) >= LICE_BLIT_MODE_CHANCOPY && (mode&LICE_BLIT_MODE_MASK) < LICE_BLIT_MODE_CHANCOPY+0x10) - { - while (i-->0) - { - LICE_pixel_chan *o=pdest+((mode>>2)&3); - LICE_pixel_chan *in=psrc+(mode&3); - int a=cpsize; - while (a--) - { - *o=*in; - o+=sizeof(LICE_pixel); - in+=sizeof(LICE_pixel); - } - pdest+=dest_span; - psrc += src_span; - } - } - // special fast case for copy with no source alpha and alpha=1.0 or 0.5 - else if ((mode&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (alpha==1.0||alpha==0.5)) - { - if (alpha==0.5) - { - while (i-->0) - { - int a=cpsize; - LICE_pixel *rd = (LICE_pixel *)psrc; - LICE_pixel *wr = (LICE_pixel *)pdest; - while (a-->0) - { - *wr = ((*wr>>1)&0x7f7f7f7f)+((*rd++>>1)&0x7f7f7f7f); - wr++; - } - - pdest+=dest_span; - psrc += src_span; - } - } - else - { - while (i-->0) - { - memcpy(pdest,psrc,cpsize*sizeof(LICE_pixel)); - pdest+=dest_span; - psrc += src_span; - } - } - } - else - { - int ia=(int)(alpha*256.0); - #ifdef LICE_FAVOR_SIZE - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - #else - #define __LICE__ACTION(comb) _LICE_Template_Blit2::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia) - #endif - - __LICE_ACTION_SRCALPHA(mode,ia,false); - - #undef __LICE__ACTION - - #ifdef LICE_FAVOR_SIZE - if (blitfunc) _LICE_Template_Blit2::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia,blitfunc); - #endif - } -} - -#endif - -#ifndef LICE_NO_BLUR_SUPPORT - -void LICE_Blur(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch) // src and dest can overlap, however it may look fudgy if they do -{ - if (!dest || !src) return; - - RECT sr={srcx,srcy,srcx+srcw,srcy+srch}; - if (sr.left < 0) sr.left=0; - if (sr.top < 0) sr.top=0; - if (sr.right > src->getWidth()) sr.right=src->getWidth(); - if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight(); - - // clip to output - if (dstx < 0) { sr.left -= dstx; dstx=0; } - if (dsty < 0) { sr.top -= dsty; dsty=0; } - if (dstx+sr.right-sr.left > dest->getWidth()) sr.right = sr.left + (dest->getWidth()-dstx); - if (dsty+sr.bottom-sr.top > dest->getHeight()) sr.bottom = sr.top + (dest->getHeight()-dsty); - - // ignore blits that are smaller than 2x2 - if (sr.right <= sr.left+1 || sr.bottom <= sr.top+1) return; - - int dest_span=dest->getRowSpan(); - int src_span=src->getRowSpan(); - LICE_pixel *psrc = (LICE_pixel *)src->getBits(); - LICE_pixel *pdest = (LICE_pixel *)dest->getBits(); - if (!psrc || !pdest) return; - - if (src->isFlipped()) - { - psrc += (src->getHeight()-sr.top - 1)*src_span; - src_span=-src_span; - } - else psrc += sr.top*src_span; - psrc += sr.left; - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else pdest += dsty*dest_span; - pdest+=dstx; - - LICE_pixel *tmpbuf=NULL; - int w=sr.right-sr.left; - - // buffer to save the last unprocessed lines for the cases where blurring from a bitmap to itself - LICE_pixel turdbuf[2048]; - if (src==dest) - { - if (w <= sizeof(turdbuf)/sizeof(turdbuf[0])/2) tmpbuf=turdbuf; - else tmpbuf=(LICE_pixel*)malloc(w*2*sizeof(LICE_pixel)); - } - - int i; - for (i = sr.top; i < sr.bottom; i ++) - { - if (tmpbuf) - memcpy(tmpbuf+((i&1)?w:0),psrc,w*sizeof(LICE_pixel)); - - if (i==sr.top || i==sr.bottom-1) - { - LICE_pixel *psrc2=psrc+(i==sr.top ? src_span : -src_span); - - LICE_pixel lp; - - pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) + - LICE_PIXEL_QUARTER(psrc[1]) + - LICE_PIXEL_QUARTER(psrc2[0]); - int x; - for (x = 1; x < w-1; x ++) - { - LICE_pixel tp; - pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) + - LICE_PIXEL_QUARTER(psrc2[x]) + - LICE_PIXEL_EIGHTH(psrc[x+1]) + - LICE_PIXEL_EIGHTH(lp); - lp=tp; - } - pdest[x] = LICE_PIXEL_HALF(psrc[x]) + - LICE_PIXEL_QUARTER(lp) + - LICE_PIXEL_QUARTER(psrc2[x]); - } - else - { - LICE_pixel *psrc2=psrc-src_span; - LICE_pixel *psrc3=psrc+src_span; - if (tmpbuf) - psrc2=tmpbuf + ((i&1) ? 0 : w); - - LICE_pixel lp; - pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) + - LICE_PIXEL_QUARTER(psrc[1]) + - LICE_PIXEL_EIGHTH(psrc2[0]) + - LICE_PIXEL_EIGHTH(psrc3[0]); - int x; - for (x = 1; x < w-1; x ++) - { - LICE_pixel tp; - pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) + - LICE_PIXEL_EIGHTH(psrc[x+1]) + - LICE_PIXEL_EIGHTH(lp) + - LICE_PIXEL_EIGHTH(psrc2[x]) + - LICE_PIXEL_EIGHTH(psrc3[x]); - lp=tp; - } - pdest[x] = LICE_PIXEL_HALF(psrc[x]) + - LICE_PIXEL_QUARTER(lp) + - LICE_PIXEL_EIGHTH(psrc2[x]) + - LICE_PIXEL_EIGHTH(psrc3[x]); - } - pdest+=dest_span; - psrc += src_span; - } - if (tmpbuf && tmpbuf != turdbuf) - free(tmpbuf); -} - -#endif - -#ifndef LICE_NO_BLIT_SUPPORT -void LICE_ScaledBlit(LICE_IBitmap *dest, LICE_IBitmap *src, - int dstx, int dsty, int dstw, int dsth, - float srcx, float srcy, float srcw, float srch, - float alpha, int mode) -{ - if (!dest || !src || !dstw || !dsth || !alpha) return; - - // non-scaling optimized omde - if (fabs(srcw-dstw)<0.001 && fabs(srch-dsth)<0.001) - { - // and if not bilinear filtering, or - // the source coordinates are near their integer counterparts - if ((mode&LICE_BLIT_FILTER_MASK)!=LICE_BLIT_FILTER_BILINEAR || - (fabs(srcx-floor(srcx+0.5f))<0.03 && fabs(srcy-floor(srcy+0.5f))<0.03)) - { - RECT sr={(int)(srcx+0.5f),(int)(srcy+0.5f),}; - sr.right=sr.left+dstw; - sr.bottom=sr.top+dsth; - LICE_Blit(dest,src,dstx,dsty,&sr,alpha,mode); - return; - } - } - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_SCALEDBLIT_ACCEL)) - { - LICE_Ext_ScaledBlit_acceldata data(src, dstx, dsty, dstw, dsth, srcx, srcy, srcw, srch, alpha, mode); - if (dest->Extended(LICE_EXT_SCALEDBLIT_ACCEL, &data)) return; - } -#endif - - if (dstw<0) - { - dstw=-dstw; - dstx-=dstw; - srcx+=srcw; - srcw=-srcw; - } - if (dsth<0) - { - dsth=-dsth; - dsty-=dsth; - srcy+=srch; - srch=-srch; - } - - double xadvance = srcw / dstw; - double yadvance = srch / dsth; - - if (dstx < 0) { srcx -= (float) (dstx*xadvance); dstw+=dstx; dstx=0; } - if (dsty < 0) { srcy -= (float) (dsty*yadvance); dsth+=dsty; dsty=0; } - if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; - if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; - - if (dstw<1 || dsth<1) return; // check before the below calcs since they arent necessary / will fuck up if these area small - - int idx=(int)(xadvance*65536.0); - int idy=(int)(yadvance*65536.0); - int icurx=(int) (srcx*65536.0); - int icury=(int) (srcy*65536.0); - - -#if 1 - // the clip area calculations need to be done fixed point so the results match runtime - - if (idx>0) - { - if (icurx < 0) // increase dstx, decrease dstw - { - int n = (idx-1-icurx)/idx; - dstw-=n; - dstx+=n; - icurx+=idx*n; - } - if ((icurx + idx*(dstw-1))/65536 >= src->getWidth()) - { - int neww = ((src->getWidth()-1)*65536 - icurx)/idx; - if (neww < dstw) dstw=neww; - } - } - else if (idx<0) - { - // todo: optimize source-clipping with reversed X axis - } - - if (idy > 0) - { - if (icury < 0) // increase dsty, decrease dsth - { - int n = (idy-1-icury)/idy; - dsth-=n; - dsty+=n; - icury+=idy*n; - } - if ((icury + idy*(dsth-1))/65536 >= src->getHeight()) - { - int newh = ((src->getHeight()-1)*65536 - icury)/idy; - if (newh < dsth) dsth=newh; - } - } - else if (idy<0) - { - // todo: optimize source-clipping with reversed Y axis (check icury against src->getHeight(), etc) - } - if (dstw<1 || dsth<1) return; -#endif - - - int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); - int src_span=src->getRowSpan()*sizeof(LICE_pixel); - - LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); - LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); - if (!psrc || !pdest) return; - - - if (src->isFlipped()) - { - psrc += (src->getHeight()-1)*src_span; - src_span=-src_span; - } - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else pdest += dsty*dest_span; - pdest+=dstx*sizeof(LICE_pixel); - - int clip_r=(int)(srcx+max(srcw,0)+0.999999); - int clip_b=(int)(srcy+max(srch,0)+0.999999); - if (clip_r>src->getWidth()) clip_r=src->getWidth(); - if (clip_b>src->getHeight()) clip_b=src->getHeight(); - - if (clip_r<1||clip_b<1) return; - - int ia=(int)(alpha*256.0); - - if ((mode&(LICE_BLIT_FILTER_MASK|LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (ia==128 || ia==256)) - { - if (ia==128) - { - _LICE_Template_Blit0<_LICE_CombinePixelsHalfMixFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span); - } - else - { - _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span); - } - } - else - { - if (xadvance>=1.7 && yadvance >=1.7 && (mode&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR) - { - int msc = max(idx,idy); - const int filtsz=msc>(3<<16) ? 5 : 3; - const int filt_start = - (filtsz/2); - - int filter[25]; // 5x5 max - { - int y; - // char buf[4096]; - // sprintf(buf,"filter, msc=%f: ",msc); - int *p=filter; - for(y=0;y1.0) *p++=65536; - else *p++=(int)(v*65536.0); - } - } - } -// OutputDebugString(buf); - } - - #ifdef LICE_FAVOR_SIZE - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - #else - #define __LICE__ACTION(comb) _LICE_Template_Blit2::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz) - #endif - __LICE_ACTION_SRCALPHA(mode,ia,false); - #undef __LICE__ACTION - - #ifdef LICE_FAVOR_SIZE - if (blitfunc) _LICE_Template_Blit2::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz,blitfunc); - #endif - - } - else - { - #ifdef LICE_FAVOR_SIZE - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - #else - #define __LICE__ACTION(comb) _LICE_Template_Blit2::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) - #endif - __LICE_ACTION_SRCALPHA(mode,ia,false); - #undef __LICE__ACTION - #ifdef LICE_FAVOR_SIZE - if (blitfunc) _LICE_Template_Blit2::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); - #endif - } - } -} - -void LICE_DeltaBlit(LICE_IBitmap *dest, LICE_IBitmap *src, - int dstx, int dsty, int dstw, int dsth, - float srcx, float srcy, float srcw, float srch, - double dsdx, double dtdx, double dsdy, double dtdy, - double dsdxdy, double dtdxdy, - bool cliptosourcerect, float alpha, int mode) -{ - if (!dest || !src || !dstw || !dsth) return; - - double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight(); - - if (cliptosourcerect) - { - if (srcx > src_left) src_left=srcx; - if (srcy > src_top) src_top=srcy; - if (srcx+srcw < src_right) src_right=srcx+srcw; - if (srcy+srch < src_bottom) src_bottom=srcy+srch; - } - - if (dstw<0) - { - dstw=-dstw; - dstx-=dstw; - srcx+=srcw; - srcw=-srcw; - } - if (dsth<0) - { - dsth=-dsth; - dsty-=dsth; - srcy+=srch; - srch=-srch; - } - - - if (dstx < 0) - { - srcx -= (float) (dstx*dsdx); - srcy -= (float) (dstx*dtdx); - dstw+=dstx; - dstx=0; - } - if (dsty < 0) - { - srcy -= (float) (dsty*dtdy); - srcx -= (float) (dsty*dsdy); - dsth+=dsty; - dsty=0; - } - if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; - if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; - - if (dstw<1 || dsth<1) return; - - - int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); - int src_span=src->getRowSpan()*sizeof(LICE_pixel); - - LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); - LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); - if (!psrc || !pdest) return; - - if (src->isFlipped()) - { - psrc += (src->getHeight()-1)*src_span; - src_span=-src_span; - } - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else pdest += dsty*dest_span; - pdest+=dstx*sizeof(LICE_pixel); - - int sl=(int)(src_left); - int sr=(int)(src_right); - int st=(int)(src_top); - int sb=(int)(src_bottom); - - int ia=(int)(alpha*256.0); - int isrcx=(int)(srcx*65536.0); - int isrcy=(int)(srcy*65536.0); - int idsdx=(int)(dsdx*65536.0); - int idtdx=(int)(dtdx*65536.0); - int idsdy=(int)(dsdy*65536.0); - int idtdy=(int)(dtdy*65536.0); - int idsdxdy=(int)(dsdxdy*65536.0); - int idtdxdy=(int)(dtdxdy*65536.0); - -#ifndef LICE_FAVOR_SPEED - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc = comb::doPix; -#else - #define __LICE__ACTION(comb) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) -#endif - __LICE_ACTION_SRCALPHA(mode,ia,false); - #undef __LICE__ACTION - -#ifndef LICE_FAVOR_SPEED - if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); -#endif - -} - - - -void LICE_RotatedBlit(LICE_IBitmap *dest, LICE_IBitmap *src, - int dstx, int dsty, int dstw, int dsth, - float srcx, float srcy, float srcw, float srch, - float angle, - bool cliptosourcerect, float alpha, int mode, float rotxcent, float rotycent) -{ - if (!dest || !src || !dstw || !dsth) return; - - double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight(); - - if (cliptosourcerect) - { - if (srcx > src_left) src_left=srcx; - if (srcy > src_top) src_top=srcy; - if (srcx+srcw < src_right) src_right=srcx+srcw; - if (srcy+srch < src_bottom) src_bottom=srcy+srch; - } - - if (dstw<0) - { - dstw=-dstw; - dstx-=dstw; - srcx+=srcw; - srcw=-srcw; - } - if (dsth<0) - { - dsth=-dsth; - dsty-=dsth; - srcy+=srch; - srch=-srch; - } - - double cosa=cos(angle); - double sina=sin(angle); - - double xsc=srcw / dstw; - double ysc=srch / dsth; - - double dsdx = xsc * cosa; - double dtdy = ysc * cosa; - double dsdy = xsc * sina; - double dtdx = ysc * -sina; - - srcx -= (float) (0.5 * (dstw*dsdx + dsth*dsdy - srcw) - rotxcent); - srcy -= (float) (0.5 * (dsth*dtdy + dstw*dtdx - srch) - rotycent); - - if (dstx < 0) - { - srcx -= (float) (dstx*dsdx); - srcy -= (float) (dstx*dtdx); - dstw+=dstx; - dstx=0; - } - if (dsty < 0) - { - srcy -= (float) (dsty*dtdy); - srcx -= (float) (dsty*dsdy); - dsth+=dsty; - dsty=0; - } - if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; - if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; - - if (dstw<1 || dsth<1) return; - - - int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); - int src_span=src->getRowSpan()*sizeof(LICE_pixel); - - LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); - LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); - if (!psrc || !pdest) return; - - if (src->isFlipped()) - { - psrc += (src->getHeight()-1)*src_span; - src_span=-src_span; - } - - if (dest->isFlipped()) - { - pdest += (dest->getHeight()-dsty - 1)*dest_span; - dest_span=-dest_span; - } - else pdest += dsty*dest_span; - pdest+=dstx*sizeof(LICE_pixel); - - int sl=(int)(src_left); - int sr=(int)(src_right); - int st=(int)(src_top); - int sb=(int)(src_bottom); - - int ia=(int)(alpha*256.0); - int isrcx=(int)(srcx*65536.0); - int isrcy=(int)(srcy*65536.0); - int idsdx=(int)(dsdx*65536.0); - int idtdx=(int)(dtdx*65536.0); - int idsdy=(int)(dsdy*65536.0); - int idtdy=(int)(dtdy*65536.0); - -#ifndef LICE_FAVOR_SPEED - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc = comb::doPix; -#else - #define __LICE__ACTION(comb) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) -#endif - __LICE_ACTION_SRCALPHA(mode,ia,false); - #undef __LICE__ACTION - -#ifndef LICE_FAVOR_SPEED - if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); -#endif -} - -#endif - - -void LICE_Clear(LICE_IBitmap *dest, LICE_pixel color) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_CLEAR_ACCEL)) - { - if (dest->Extended(LICE_EXT_CLEAR_ACCEL, &color)) return; - } -#endif - - LICE_pixel *p=dest->getBits(); - int h=dest->getHeight(); - int w=dest->getWidth(); - int sp=dest->getRowSpan(); - if (!p || w<1 || h<1 || sp<1) return; - - while (h-->0) - { - int n=w; - while (n--) *p++ = color; - p+=sp-w; - } -} - - - - -void LICE_MultiplyAddRect(LICE_IBitmap *dest, int x, int y, int w, int h, - float rsc, float gsc, float bsc, float asc, - float radd, float gadd, float badd, float aadd) -{ - if (!dest) return; - LICE_pixel *p=dest->getBits(); - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w>dest->getWidth()) w=dest->getWidth()-x; - if (y+h>dest->getHeight()) h=dest->getHeight()-y; - - int sp=dest->getRowSpan(); - if (!p || w<1 || h<1 || sp<1) return; - - if (dest->isFlipped()) - { - p+=(dest->getHeight() - y - h)*sp; - } - else p+=sp*y; - - p += x; - - int ir=(int)(rsc*256.0); - int ig=(int)(gsc*256.0); - int ib=(int)(bsc*256.0); - int ia=(int)(asc*256.0); - int ir2=(int)(radd*256.0); - int ig2=(int)(gadd*256.0); - int ib2=(int)(badd*256.0); - int ia2=(int)(aadd*256.0); - - while (h-->0) - { - int n=w; - while (n--) - { - LICE_pixel_chan *ptr=(LICE_pixel_chan *)p++; - _LICE_MakePixelClamp(ptr,(ptr[LICE_PIXEL_R]*ir+ir2)>>8, - (ptr[LICE_PIXEL_G]*ig+ig2)>>8, - (ptr[LICE_PIXEL_B]*ib+ib2)>>8, - (ptr[LICE_PIXEL_A]*ia+ia2)>>8); - } - p+=sp-w; - } -} - -void LICE_ProcessRect(LICE_IBitmap *dest, int x, int y, int w, int h, void (*procFunc)(LICE_pixel *p, void *parm), void *parm) -{ - if (!dest||!procFunc) return; - LICE_pixel *p=dest->getBits(); - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w>dest->getWidth()) w=dest->getWidth()-x; - if (y+h>dest->getHeight()) h=dest->getHeight()-y; - - int sp=dest->getRowSpan(); - if (!p || w<1 || h<1 || sp<1) return; - - if (dest->isFlipped()) - { - p+=(dest->getHeight() - y - h)*sp; - } - else p+=sp*y; - - p += x; - - while (h--) - { - LICE_pixel *pout=p; - int n=w; - while (n--) procFunc(pout++,parm); - p+=sp; - } - - -} - -void LICE_FillRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_FILLRECT_ACCEL)) - { - LICE_Ext_FillRect_acceldata data(x, y, w, h, color, alpha, mode); - if (dest->Extended(LICE_EXT_FILLRECT_ACCEL, &data)) return; - } -#endif - - if (mode & LICE_BLIT_USE_ALPHA) alpha *= LICE_GETA(color)/255.0f; - LICE_pixel *p=dest->getBits(); - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w>dest->getWidth()) w=dest->getWidth()-x; - if (y+h>dest->getHeight()) h=dest->getHeight()-y; - - int sp=dest->getRowSpan(); - if (!alpha || !p || w<1 || h<1 || sp<1) return; - - if (dest->isFlipped()) - { - p+=(dest->getHeight() - y - h)*sp; - } - else p+=sp*y; - - p += x; - - int ia=(int)(alpha*256.0); - // copy, alpha=1, alpha=0.5, 0.25, 0.75 optimizations - if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) - { - if (ia==256) - { - _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::solidBlitFAST(p,w,h,color,sp); - return; - } - if (ia==128) - { - // we use _LICE_CombinePixelsHalfMix2 because we pre-halve color here - _LICE_Template_Blit0<_LICE_CombinePixelsHalfMix2FAST>::solidBlitFAST(p,w,h,(color>>1)&0x7f7f7f7f,sp); - return; - } - if (ia==64) - { - _LICE_Template_Blit0<_LICE_CombinePixelsQuarterMix2FAST>::solidBlitFAST(p,w,h,(color>>2)&0x3f3f3f3f,sp); - return; - } - if (ia==192) - { - _LICE_Template_Blit0<_LICE_CombinePixelsThreeQuarterMix2FAST>::solidBlitFAST(p,w,h, - ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f),sp); - return; - } - } - -#ifdef LICE_FAVOR_SIZE_EXTREME - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; -#else - #define __LICE__ACTION(comb) _LICE_Template_Blit1::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel)) -#endif - - // we use __LICE_ACTION_NOSRCALPHA even though __LICE_ACTION_CONSTANTALPHA - // is valid, sinc we optimized the 1.0f/0.5f cases above - __LICE_ACTION_NOSRCALPHA(mode,ia,false); - #undef __LICE__ACTION - -#ifdef LICE_FAVOR_SIZE_EXTREME - if (blitfunc) _LICE_Template_Blit1::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel),blitfunc); -#endif -} - -void LICE_ClearRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel mask, LICE_pixel orbits) -{ - if (!dest) return; - LICE_pixel *p=dest->getBits(); - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w>dest->getWidth()) w=dest->getWidth()-x; - if (y+h>dest->getHeight()) h=dest->getHeight()-y; - - int sp=dest->getRowSpan(); - if (!p || w<1 || h<1 || sp<1) return; - - if (dest->isFlipped()) - { - p+=(dest->getHeight() - y - h)*sp; - } - else p+=sp*y; - - p += x; - while (h-->0) - { - int n=w; - while (n--) - { - *p = (*p&mask)|orbits; - p++; - } - p+=sp-w; - } -} - - -LICE_pixel LICE_GetPixel(LICE_IBitmap *bm, int x, int y) -{ - if (!bm) return 0; - -#ifndef DISABLE_LICE_EXTENSIONS - if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_GETPIXEL_ACCEL)) - { - LICE_Ext_GetPixel_acceldata data(x, y); - if (bm->Extended(LICE_EXT_GETPIXEL_ACCEL, &data)) return data.px; - } -#endif - - LICE_pixel *px; - if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return 0; - if (bm->isFlipped()) return px[(bm->getHeight()-1-y) * bm->getRowSpan() + x]; - return px[y * bm->getRowSpan() + x]; -} - -void LICE_PutPixel(LICE_IBitmap *bm, int x, int y, LICE_pixel color, float alpha, int mode) -{ - if (!bm) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_PUTPIXEL_ACCEL)) - { - LICE_Ext_PutPixel_acceldata data(x, y, color, alpha, mode); - if (bm->Extended(LICE_EXT_PUTPIXEL_ACCEL, &data)) return; - } -#endif - - LICE_pixel *px; - if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return; - - if (bm->isFlipped()) px+=x+(bm->getHeight()-1-y)*bm->getRowSpan(); - else px+=x+y*bm->getRowSpan(); - - int ia = (int)(alpha * 256.0f); - if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) - { - if (ia==256) - { - *px = color; - return; - } - if (ia==128) - { - *px = ((*px>>1)&0x7f7f7f7f) + ((color>>1)&0x7f7f7f7f); - return; - } - if (ia==64) - { - *px = ((*px>>1)&0x7f7f7f7f) + ((*px>>2)&0x3f3f3f3f) + ((color>>2)&0x3f3f3f3f); - return; - } - if (ia==192) - { - *px = ((*px>>2)&0x3f3f3f3f) + ((color>>1)&0x7f7f7f7f) + ((color>>2)&0x3f3f3f3f); - return; - } - } -#define __LICE__ACTION(comb) comb::doPix((LICE_pixel_chan *)px, LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),LICE_GETA(color), ia) - __LICE_ACTION_NOSRCALPHA(mode,ia,false); -#undef __LICE__ACTION -} - - -#ifndef LICE_NO_BLIT_SUPPORT -void LICE_TransformBlit(LICE_IBitmap *dest, LICE_IBitmap *src, - int dstx, int dsty, int dstw, int dsth, - float *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates - float alpha, int mode) -{ - if (!dest || !src || dstw<1 || dsth<1 || div_w<2 || div_h<2) return; - - int cypos=dsty; - double ypos=dsty; - double dxpos=dstw/(float)(div_w-1); - double dypos=dsth/(float)(div_h-1); - int y; - float *curpoints=srcpoints; - for (y = 0; y < div_h-1; y ++) - { - int nypos=(int)(ypos+=dypos); - int x; - double xpos=dstx; - int cxpos=dstx; - - if (nypos != cypos) - { - double iy=1.0/(double)(nypos-cypos); - for (x = 0; x < div_w-1; x ++) - { - int nxpos=(int) (xpos+=dxpos); - if (nxpos != cxpos) - { - int offs=x*2; - double sx=curpoints[offs]; - double sy=curpoints[offs+1]; - double sw=curpoints[offs+2]-sx; - double sh=curpoints[offs+3]-sy; - - offs+=div_w*2; - double sxdiff=curpoints[offs]-sx; - double sydiff=curpoints[offs+1]-sy; - double sw3=curpoints[offs+2]-curpoints[offs]; - double sh3=curpoints[offs+3]-curpoints[offs+1]; - - double ix=1.0/(double)(nxpos-cxpos); - double dsdx=sw*ix; - double dtdx=sh*ix; - double dsdx2=sw3*ix; - double dtdx2=sh3*ix; - double dsdy=sxdiff*iy; - double dtdy=sydiff*iy; - double dsdxdy = (dsdx2-dsdx)*iy; - double dtdxdy = (dtdx2-dtdx)*iy; - - LICE_DeltaBlit(dest,src,cxpos,cypos,nxpos-cxpos,nypos-cypos, - (float)sx,(float)sy,(float)sw,(float)sh, - dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy,false,alpha,mode); - } - - cxpos=nxpos; - } - } - curpoints+=div_w*2; - cypos=nypos; - } - -} - - - -#endif - -#ifndef LICE_NO_MISC_SUPPORT - -void LICE_SetAlphaFromColorMask(LICE_IBitmap *dest, LICE_pixel color) -{ - if (!dest) return; - LICE_pixel *p=dest->getBits(); - int h=dest->getHeight(); - int w=dest->getWidth(); - int sp=dest->getRowSpan(); - if (!p || w<1 || h<1 || sp<1) return; - - while (h-->0) - { - int n=w; - while (n--) - { - if ((*p&LICE_RGBA(255,255,255,0)) == color) *p&=LICE_RGBA(255,255,255,0); - else *p|=LICE_RGBA(0,0,0,255); - p++; - } - p+=sp-w; - } -} - - -void LICE_SimpleFill(LICE_IBitmap *dest, int x, int y, LICE_pixel newcolor, - LICE_pixel comparemask, - LICE_pixel keepmask) -{ - if (!dest) return; - int dw=dest->getWidth(); - int dh=dest->getHeight(); - int rowsize=dest->getRowSpan(); - if (x<0||x>=dw||y<0||y>=dh) return; - LICE_pixel *ptr=dest->getBits(); - if (!ptr) return; - ptr += rowsize*y; - - LICE_pixel compval=ptr[x]&comparemask; - int ay; - for (ay=y;ay=0) - { - if ((ptr[ax]&comparemask)!=compval) break; - ptr[ax]=(ptr[ax]&keepmask)|newcolor; - } - - ptr+=rowsize; - } - ptr =dest->getBits()+rowsize*y; - - ay=y; - while (--ay>=0) - { - ptr-=rowsize; - if ((ptr[x]&comparemask)!=compval) break; - ptr[x]=(ptr[x]&keepmask)|newcolor; - - int ax; - for(ax=x+1;ax=0) - { - if ((ptr[ax]&comparemask)!=compval) break; - ptr[ax]=(ptr[ax]&keepmask)|newcolor; - } - } -} - -// stupid ass VS6 instantiates this wrong as a template function, needs to be a template class -template class GlyphDrawImpl -{ -public: - static void DrawGlyph(const LICE_pixel_chan* srcalpha, LICE_pixel* destpx, int src_w, int src_h, LICE_pixel color, int span, int src_span, int aa) - { - - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - int xi, yi; - for (yi = 0; yi < src_h; ++yi, srcalpha += src_span, destpx += span) { - const LICE_pixel_chan* tsrc = srcalpha; - LICE_pixel* tdest = destpx; - for (xi = 0; xi < src_w; ++xi, ++tsrc, ++tdest) { - if (*tsrc) { // glyphs should be expected to have a lot of "holes" - COMBFUNC::doPix((LICE_pixel_chan*) tdest, r, g, b, a, *tsrc*aa/256); - } - } - } - } -}; - -void LICE_DrawGlyphEx(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_span, int glyph_h, float alpha, int mode) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWGLYPH_ACCEL) && glyph_w == glyph_span) - { - LICE_Ext_DrawGlyph_acceldata data(x, y, color, alphas, glyph_w, glyph_h, alpha, mode); - if (dest->Extended(LICE_EXT_DRAWGLYPH_ACCEL, &data)) return; - } -#endif - - int ia= (int)(alpha*256.0f); - - int src_x = 0, src_y = 0, src_w = glyph_w, src_h = glyph_h; - if (x < 0) { - src_x -= x; - src_w += x; - x = 0; - } - if (x+src_w >= dest->getWidth()) { - src_w = dest->getWidth()-x; - } - if (y < 0) { - src_y -= y; - src_h += y; - y = 0; - } - if (y+src_h >= dest->getHeight()) { - src_h = dest->getHeight()-y; - } - - - LICE_pixel* destpx = dest->getBits(); - int span = dest->getRowSpan(); - if (dest->isFlipped()) { - destpx += (dest->getHeight()-y-1)*span+x; - span = -span; - } - else { - destpx += y*dest->getRowSpan()+x; - } - - const LICE_pixel_chan* srcalpha = alphas+src_y*glyph_span+src_x; - -#define __LICE__ACTION(COMBFUNC) GlyphDrawImpl::DrawGlyph(srcalpha,destpx, src_w, src_h, color,span,glyph_span,ia) - __LICE_ACTION_NOSRCALPHA(mode, ia, false); -#undef __LICE__ACTION -} - -void LICE_DrawGlyph(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_h, float alpha, int mode) -{ - LICE_DrawGlyphEx(dest,x,y,color,alphas,glyph_w,glyph_w,glyph_h,alpha,mode); -} - -void LICE_HalveBlitAA(LICE_IBitmap *dest, LICE_IBitmap *src) -{ - if (!dest||!src) return; - int w = dest->getWidth(); - if (w > src->getWidth()/2) w=src->getWidth()/2; - int h = dest->getHeight(); - if (h > src->getHeight()/2) h=src->getHeight()/2; - int src_span = src->getRowSpan(); - int dest_span = dest->getRowSpan(); - LICE_pixel *srcptr = src->getBits(); - LICE_pixel *destptr = dest->getBits(); - - while (h--) - { - LICE_pixel *sp = srcptr; - LICE_pixel *sp2 = srcptr+src_span; - LICE_pixel *dp = destptr; - int x=w/2; - // perhaps we should use more precision rather than chopping each src pixel to 6 bits, but oh well - while (x--) // unroll 2px at a time, about 5% faster on core2 and ICC - { - int r1=((sp[0]>>2)&0x3f3f3f3f); - int r2=((sp[2]>>2)&0x3f3f3f3f); - r1 += ((sp[1]>>2)&0x3f3f3f3f); - r2 += ((sp[3]>>2)&0x3f3f3f3f); - dp[0] = r1 + - ((sp2[0]>>2)&0x3f3f3f3f) + - ((sp2[1]>>2)&0x3f3f3f3f); - dp[1] = r2 + - ((sp2[2]>>2)&0x3f3f3f3f) + - ((sp2[3]>>2)&0x3f3f3f3f); - sp+=4; - sp2+=4; - dp+=2; - } - if (w&1) - { - *dp = - ((sp[0]>>2)&0x3f3f3f3f) + - ((sp[1]>>2)&0x3f3f3f3f) + - ((sp2[0]>>2)&0x3f3f3f3f) + - ((sp2[1]>>2)&0x3f3f3f3f); - } - srcptr+=src_span*2; - destptr+=dest_span; - } -} - -#endif // LICE_NO_MISC_SUPPORT - -int LICE_BitmapCmp(LICE_IBitmap* a, LICE_IBitmap* b, int *coordsOut) -{ - if (!a || !b) { - if (!a && b) return -1; - if (a && !b) return 1; - return 0; - } - - int aw = a->getWidth(), bw = b->getWidth(); - if (aw != bw) return bw-aw; - int ah = a->getHeight(), bh = b->getHeight(); - if (ah != bh) return bh-ah; - - //coordsOut - LICE_pixel *px1 = a->getBits(); - LICE_pixel *px2 = b->getBits(); - int span1 = a->getRowSpan(); - int span2 = b->getRowSpan(); - if (a->isFlipped()) - { - px1+=span1*(ah-1); - span1=-span1; - } - if (b->isFlipped()) - { - px2+=span2*(ah-1); - span2=-span2; - } - - int y; - if (!coordsOut) - { - for (y=0; y < ah; y ++) - { - int a = memcmp(px1,px2,aw*sizeof(LICE_pixel)); - if (a) return a; - px1+=span1; - px2+=span2; - } - } - else - { - int x; - - // find first row that differs - for (y=0; y < ah; y ++) - { - // check left side - for (x=0;x=ah) - { - memset(coordsOut,0,4*sizeof(int)); - return 0; // no differences - } - - int miny=y; - int minx=x; - // scan right edge of top differing row - for (x=aw-1;x>minx && px1[x]==px2[x];x--); - int maxx=x; - - // find last row that differs - px1+=span1 * (ah-1-y); - px2+=span2 * (ah-1-y); - for (y = ah-1; y > miny; y --) - { - int x; - // check left side - for (x=0;x miny) - { - if (x < minx) minx=x; - // scan right edge of bottom row that differs - for (x=aw-1;x>maxx && px1[x]==px2[x];x--); - maxx=x; - } - - - // find min/max x that differ - px1+=span1 * (miny+1-y); - px2+=span2 * (miny+1-y); - for (y=miny+1;y0 || maxxmaxx && px1[x]==px2[x];x--); - maxx=x; - - px1+=span1; - px2+=span2; - } - - coordsOut[0]=minx; - coordsOut[1]=miny; - coordsOut[2]=maxx-minx+1; - coordsOut[3]=maxy-miny+1; - - return 1; - } - - return 0; -} - -unsigned short _LICE_RGB2HSV_invtab[256]={ // 65536/idx - 1 - 0, 0xffff, 0x7fff, 0x5554, 0x3fff, 0x3332, 0x2aa9, 0x2491, - 0x1fff, 0x1c70, 0x1998, 0x1744, 0x1554, 0x13b0, 0x1248, 0x1110, - 0x0fff, 0x0f0e, 0x0e37, 0x0d78, 0x0ccb, 0x0c2f, 0x0ba1, 0x0b20, - 0x0aa9, 0x0a3c, 0x09d7, 0x097a, 0x0923, 0x08d2, 0x0887, 0x0841, - 0x07ff, 0x07c0, 0x0786, 0x074f, 0x071b, 0x06ea, 0x06bb, 0x068f, - 0x0665, 0x063d, 0x0617, 0x05f3, 0x05d0, 0x05af, 0x058f, 0x0571, - 0x0554, 0x0538, 0x051d, 0x0504, 0x04eb, 0x04d3, 0x04bc, 0x04a6, - 0x0491, 0x047c, 0x0468, 0x0455, 0x0443, 0x0431, 0x0420, 0x040f, - 0x03ff, 0x03ef, 0x03df, 0x03d1, 0x03c2, 0x03b4, 0x03a7, 0x039a, - 0x038d, 0x0380, 0x0374, 0x0368, 0x035d, 0x0352, 0x0347, 0x033c, - 0x0332, 0x0328, 0x031e, 0x0314, 0x030b, 0x0302, 0x02f9, 0x02f0, - 0x02e7, 0x02df, 0x02d7, 0x02cf, 0x02c7, 0x02bf, 0x02b8, 0x02b0, - 0x02a9, 0x02a2, 0x029b, 0x0294, 0x028e, 0x0287, 0x0281, 0x027b, - 0x0275, 0x026f, 0x0269, 0x0263, 0x025d, 0x0258, 0x0252, 0x024d, - 0x0248, 0x0242, 0x023d, 0x0238, 0x0233, 0x022f, 0x022a, 0x0225, - 0x0221, 0x021c, 0x0218, 0x0213, 0x020f, 0x020b, 0x0207, 0x0203, - 0x01ff, 0x01fb, 0x01f7, 0x01f3, 0x01ef, 0x01eb, 0x01e8, 0x01e4, - 0x01e0, 0x01dd, 0x01d9, 0x01d6, 0x01d3, 0x01cf, 0x01cc, 0x01c9, - 0x01c6, 0x01c2, 0x01bf, 0x01bc, 0x01b9, 0x01b6, 0x01b3, 0x01b1, - 0x01ae, 0x01ab, 0x01a8, 0x01a5, 0x01a3, 0x01a0, 0x019d, 0x019b, - 0x0198, 0x0196, 0x0193, 0x0191, 0x018e, 0x018c, 0x0189, 0x0187, - 0x0185, 0x0182, 0x0180, 0x017e, 0x017c, 0x0179, 0x0177, 0x0175, - 0x0173, 0x0171, 0x016f, 0x016d, 0x016b, 0x0169, 0x0167, 0x0165, - 0x0163, 0x0161, 0x015f, 0x015d, 0x015b, 0x0159, 0x0157, 0x0156, - 0x0154, 0x0152, 0x0150, 0x014f, 0x014d, 0x014b, 0x0149, 0x0148, - 0x0146, 0x0145, 0x0143, 0x0141, 0x0140, 0x013e, 0x013d, 0x013b, - 0x013a, 0x0138, 0x0137, 0x0135, 0x0134, 0x0132, 0x0131, 0x012f, - 0x012e, 0x012d, 0x012b, 0x012a, 0x0128, 0x0127, 0x0126, 0x0124, - 0x0123, 0x0122, 0x0120, 0x011f, 0x011e, 0x011d, 0x011b, 0x011a, - 0x0119, 0x0118, 0x0117, 0x0115, 0x0114, 0x0113, 0x0112, 0x0111, - 0x0110, 0x010e, 0x010d, 0x010c, 0x010b, 0x010a, 0x0109, 0x0108, - 0x0107, 0x0106, 0x0105, 0x0104, 0x0103, 0x0102, 0x0101, 0x0100, -}; - - -#endif//__LICE_CPP_IMPLEMENTED__ diff --git a/WDL/lice/lice.dsp b/WDL/lice/lice.dsp deleted file mode 100644 index 302bb1a9..00000000 --- a/WDL/lice/lice.dsp +++ /dev/null @@ -1,942 +0,0 @@ -# Microsoft Developer Studio Project File - Name="lice" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=lice - 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 "lice.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 "lice.mak" CFG="lice - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "lice - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "lice - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE "lice - Win32 Release Profile" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "lice - 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 /MD /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /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)" == "lice - 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 /W3 /Gm /GX /ZI /Od /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_DEBUG" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /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 - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "lice___Win32_Release_Profile" -# PROP BASE Intermediate_Dir "lice___Win32_Release_Profile" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_Profile" -# PROP Intermediate_Dir "Release_Profile" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /D "PNG_WRITE_SUPPORTED" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /D "PNG_WRITE_SUPPORTED" /FR /FD /c -# SUBTRACT CPP /YX -# 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 - -!ENDIF - -# Begin Target - -# Name "lice - Win32 Release" -# Name "lice - Win32 Debug" -# Name "lice - Win32 Release Profile" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "libpng" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\libpng\png.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\png.h -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngconf.h -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngerror.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngget.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngmem.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngpread.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngread.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngrio.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngrtran.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngrutil.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngset.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngtest.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngtrans.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngwio.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngwrite.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngwtran.c -# End Source File -# Begin Source File - -SOURCE=..\libpng\pngwutil.c -# End Source File -# End Group -# Begin Group "zlib" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\zlib\adler32.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\compress.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\crc32.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\crc32.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\deflate.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\infback.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\inffast.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\inffast.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\inffixed.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\inflate.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\inflate.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\inftrees.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\inftrees.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\trees.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\trees.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\uncompr.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\zconf.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\zlib.h -# End Source File -# Begin Source File - -SOURCE=..\zlib\zutil.c -# End Source File -# Begin Source File - -SOURCE=..\zlib\zutil.h -# End Source File -# End Group -# Begin Group "jpeglib" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\jpeglib\jcapimin.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcapistd.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jccoefct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jccolor.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcdctmgr.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jchuff.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcinit.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcmainct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcmarker.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcmaster.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcomapi.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcparam.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcphuff.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcprepct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jcsample.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jctrans.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdapimin.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdapistd.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdatadst.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdatasrc.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdcoefct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdcolor.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jddctmgr.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdhuff.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdinput.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdmainct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdmarker.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdmaster.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdmerge.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdphuff.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdpostct.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdsample.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jdtrans.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jerror.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jfdctflt.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jfdctfst.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jfdctint.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jidctflt.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jidctfst.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jidctint.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jidctred.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jmemmgr.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jmemnobs.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jquant1.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jquant2.c -# End Source File -# Begin Source File - -SOURCE=..\jpeglib\jutils.c -# End Source File -# End Group -# Begin Group "giflib" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\giflib\dgif_lib.c - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\giflib\egif_lib.c - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\giflib\gif_hash.c - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\giflib\gif_hash.h -# End Source File -# Begin Source File - -SOURCE=..\giflib\gif_lib.h -# End Source File -# Begin Source File - -SOURCE=..\giflib\gif_lib_private.h -# End Source File -# Begin Source File - -SOURCE=..\giflib\gifalloc.c - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" -# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" - -!ENDIF - -# End Source File -# End Group -# Begin Group "tinyxml" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\tinyxml\svgtiny_colors.c -# End Source File -# Begin Source File - -SOURCE=..\tinyxml\tinystr.cpp -# End Source File -# Begin Source File - -SOURCE=..\tinyxml\tinyxml.cpp -# End Source File -# Begin Source File - -SOURCE=..\tinyxml\tinyxml.h -# End Source File -# Begin Source File - -SOURCE=..\tinyxml\tinyxmlerror.cpp -# End Source File -# Begin Source File - -SOURCE=..\tinyxml\tinyxmlparser.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\lice.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_arc.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_bmp.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_colorspace.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_gif.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_gl_ctx.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_glbitmap.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_ico.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_jpg.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_jpg_write.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_line.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_palette.cpp -# End Source File -# Begin Source File - -SOURCE=.\lice_pcx.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_png.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_png_write.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_svg.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_texgen.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_text.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\lice_textnew.cpp - -!IF "$(CFG)" == "lice - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "lice - Win32 Debug" - -!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" - -# ADD BASE CPP /D "USE_ICC" -# ADD CPP /D "USE_ICC" - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\lice.h -# End Source File -# Begin Source File - -SOURCE=.\lice_combine.h -# End Source File -# Begin Source File - -SOURCE=.\lice_extended.h -# End Source File -# Begin Source File - -SOURCE=.\lice_gl_ctx.h -# End Source File -# Begin Source File - -SOURCE=.\lice_glbitmap.h -# End Source File -# Begin Source File - -SOURCE=.\lice_text.h -# End Source File -# End Group -# End Target -# End Project diff --git a/WDL/lice/lice.dsw b/WDL/lice/lice.dsw deleted file mode 100644 index a057da40..00000000 --- a/WDL/lice/lice.dsw +++ /dev/null @@ -1,59 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "lice"=.\lice.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "plush2"=..\plush2\plush2.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "test"=.\test\test.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name lice - End Project Dependency - Begin Project Dependency - Project_Dep_Name plush2 - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/WDL/lice/lice.h b/WDL/lice/lice.h deleted file mode 100644 index fed9f279..00000000 --- a/WDL/lice/lice.h +++ /dev/null @@ -1,554 +0,0 @@ -#ifndef _LICE_H -#define _LICE_H - -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - - Copyright (C) 2007 and later, Cockos Incorporated - Portions Copyright (C) 2007 "schwa" - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -#ifdef _WIN32 -#include -#else -#include "../swell/swell-types.h" // use SWELL on other systems -#endif - - -// one of these can be defined in your project if you choose: -//#define LICE_FAVOR_SPEED // optimizes some stuff that doesnt seem to benefit much (like LICE_DeltaBlit/LICE_RotatedBlit/LICE_TransformBlit) -// (nothing) default probably good overall -//#define LICE_FAVOR_SIZE // reduces code size of normal/scaled blit functions -//#define LICE_FAVOR_SIZE_EXTREME // same as LICE_FAVOR_SIZE w/ smaller gains with bigger perf penalties (solid fills etc) - -#ifdef LICE_FAVOR_SPEED - #ifdef LICE_FAVOR_SIZE_EXTREME - #undef LICE_FAVOR_SIZE_EXTREME - #endif - #ifdef LICE_FAVOR_SIZE - #undef LICE_FAVOR_SIZE - #endif -#endif -#if defined(LICE_FAVOR_SIZE_EXTREME) && !defined(LICE_FAVOR_SIZE) -#define LICE_FAVOR_SIZE -#endif - - -typedef unsigned int LICE_pixel; -typedef unsigned char LICE_pixel_chan; - -#ifdef _WIN32 - -#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) -#define LICE_GETB(v) ((v)&0xff) -#define LICE_GETG(v) (((v)>>8)&0xff) -#define LICE_GETR(v) (((v)>>16)&0xff) -#define LICE_GETA(v) (((v)>>24)&0xff) - - -#define LICE_PIXEL_B 0 -#define LICE_PIXEL_G 1 -#define LICE_PIXEL_R 2 -#define LICE_PIXEL_A 3 - -#elif defined(__APPLE__) -// start apple -#define LICE_PIXEL_A 0 -#define LICE_PIXEL_R 1 -#define LICE_PIXEL_G 2 -#define LICE_PIXEL_B 3 - -#ifdef __ppc__ // same memory format, different endian - -#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) -#define LICE_GETB(v) ((v)&0xff) -#define LICE_GETG(v) (((v)>>8)&0xff) -#define LICE_GETR(v) (((v)>>16)&0xff) -#define LICE_GETA(v) (((v)>>24)&0xff) - -#else - -#define LICE_RGBA(r,g,b,a) (((a)&0xff)|(((r)&0xff)<<8)|(((g)&0xff)<<16)|(((b)&0xff)<<24)) -#define LICE_GETA(v) ((v)&0xff) -#define LICE_GETR(v) (((v)>>8)&0xff) -#define LICE_GETG(v) (((v)>>16)&0xff) -#define LICE_GETB(v) (((v)>>24)&0xff) - -#endif - -// end apple -#else - -//GDK etc (tested on linux 386/x86_64) -#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) -#define LICE_GETB(v) ((v)&0xff) -#define LICE_GETG(v) (((v)>>8)&0xff) -#define LICE_GETR(v) (((v)>>16)&0xff) -#define LICE_GETA(v) (((v)>>24)&0xff) - - -#define LICE_PIXEL_B 0 -#define LICE_PIXEL_G 1 -#define LICE_PIXEL_R 2 -#define LICE_PIXEL_A 3 - -#endif - - -static inline LICE_pixel LICE_RGBA_FROMNATIVE(LICE_pixel col, int alpha=0) -{ - return LICE_RGBA(GetRValue(col),GetGValue(col),GetBValue(col),alpha); -} - -// bitmap interface, and some built-in types (memory bitmap and system bitmap) - -class LICE_IBitmap -{ -public: - virtual ~LICE_IBitmap() { } - - virtual LICE_pixel *getBits()=0; - virtual int getWidth()=0; - virtual int getHeight()=0; - virtual int getRowSpan()=0; // includes any off-bitmap data - virtual bool isFlipped() { return false; } - virtual bool resize(int w, int h)=0; - - virtual HDC getDC() { return 0; } // only sysbitmaps have to implement this - - - virtual INT_PTR Extended(int id, void* data) { return 0; } -}; - - -#define LICE_MEMBITMAP_ALIGNAMT 63 - -class LICE_MemBitmap : public LICE_IBitmap -{ -public: - LICE_MemBitmap(int w=0, int h=0, unsigned int linealign=4); - virtual ~LICE_MemBitmap(); - - - // LICE_IBitmap interface - virtual LICE_pixel *getBits() - { - const UINT_PTR extra=LICE_MEMBITMAP_ALIGNAMT; - return (LICE_pixel *) (((UINT_PTR)m_fb + extra)&~extra); - } - virtual int getWidth() { return m_width; } - virtual int getHeight() { return m_height; } - virtual int getRowSpan() { return (m_width+m_linealign)&~m_linealign; } - virtual bool resize(int w, int h); // returns TRUE if a resize occurred - -private: - LICE_pixel *m_fb; - int m_width, m_height; - int m_allocsize; - unsigned int m_linealign; -}; - -class LICE_SysBitmap : public LICE_IBitmap -{ -public: - LICE_SysBitmap(int w=0, int h=0); - virtual ~LICE_SysBitmap(); - - // LICE_IBitmap interface - virtual LICE_pixel *getBits() { return m_bits; } - virtual int getWidth() { return m_width; } - virtual int getHeight() { return m_height; } - virtual int getRowSpan() { return m_allocw; }; - virtual bool resize(int w, int h); // returns TRUE if a resize occurred - - // sysbitmap specific calls - virtual HDC getDC() { return m_dc; } - - -private: - int m_width, m_height; - - HDC m_dc; - LICE_pixel *m_bits; - int m_allocw, m_alloch; -#ifdef _WIN32 - HBITMAP m_bitmap; - HGDIOBJ m_oldbitmap; -#endif -}; - -class LICE_WrapperBitmap : public LICE_IBitmap -{ - public: - LICE_WrapperBitmap(LICE_pixel *buf, int w, int h, int span, bool flipped) - { - m_buf=buf; - m_w=w; - m_h=h; - m_span=span; - m_flipped=flipped; - } - virtual ~LICE_WrapperBitmap() {} - - virtual bool resize(int w, int h) { return false; } - virtual LICE_pixel *getBits() { return m_buf; } - virtual int getWidth() { return m_w; } - virtual int getHeight() { return m_h; } - virtual int getRowSpan() { return m_span; } - - virtual HDC getDC() { return NULL; } - virtual bool isFlipped() { return m_flipped; } - - - LICE_pixel *m_buf; - int m_w,m_h,m_span; - bool m_flipped; -}; - - -class LICE_SubBitmap : public LICE_IBitmap // note: you should only keep these around as long as they are needed, and don't resize the parent while this is allocated -{ - public: - LICE_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h) - { - m_parent=parent; - if(x<0)x=0; - if(y<0)y=0; - m_x=x;m_y=y; - resize(w,h); - } - virtual ~LICE_SubBitmap() { } - - virtual bool resize(int w, int h) - { - m_w=0;m_h=0; - if (m_parent) - { - if(m_x+w>m_parent->getWidth()) w=m_parent->getWidth()-m_x; - if (w<0)w=0; - - if (m_y+h>m_parent->getHeight()) h=m_parent->getHeight()-m_y; - if (h<0)h=0; - - m_w=w; - m_h=h; - } - - return true; - } - - virtual bool isFlipped() { return m_parent && m_parent->isFlipped(); } - - virtual LICE_pixel *getBits() - { - if (!m_parent) return 0; - - LICE_pixel* parentptr=m_parent->getBits(); - if (m_parent->isFlipped()) parentptr += (m_parent->getHeight() - (m_y+m_h))*m_parent->getRowSpan()+m_x; - else parentptr += m_y*m_parent->getRowSpan()+m_x; - - return parentptr; - } - - virtual INT_PTR Extended(int id, void* data) - { - if (!m_parent) return 0; - return m_parent->Extended(id, data); - } - - virtual int getWidth() { return m_w; } - virtual int getHeight() { return m_h; } - virtual int getRowSpan() { return m_parent ? m_parent->getRowSpan() : 0; } - - virtual HDC getDC() { return NULL; } - - int m_w,m_h,m_x,m_y; - LICE_IBitmap *m_parent; - //LICE_pixel *m_parentptr; -}; - - -// flags that most blit functions can take - -#define LICE_BLIT_MODE_MASK 0xff -#define LICE_BLIT_MODE_COPY 0 -#define LICE_BLIT_MODE_ADD 1 -#define LICE_BLIT_MODE_DODGE 2 -#define LICE_BLIT_MODE_MUL 3 -#define LICE_BLIT_MODE_OVERLAY 4 -#define LICE_BLIT_MODE_HSVADJ 5 - -#define LICE_BLIT_MODE_CHANCOPY 0xf0 // in this mode, only available for LICE_Blit(), the low nibble is 2 bits of source channel (low 2), 2 bits of dest channel (high 2) - -#define LICE_BLIT_FILTER_MASK 0xff00 -#define LICE_BLIT_FILTER_NONE 0 -#define LICE_BLIT_FILTER_BILINEAR 0x100 // currently pretty slow! ack - - -#define LICE_BLIT_USE_ALPHA 0x10000 // use source's alpha channel - - -// Reaper exports most LICE functions, so the function declarations below -// will collide with reaper_plugin.h -#ifndef LICE_PROVIDED_BY_APP - - -// bitmap loaders - -// dispatch to a linked loader implementation based on file extension -LICE_IBitmap* LICE_LoadImage(const char* filename, LICE_IBitmap* bmp=NULL, bool tryIgnoreExtension=false); -char *LICE_GetImageExtensionList(bool wantAllSup=true, bool wantAllFiles=true); // returns doublenull terminated GetOpenFileName() style list -- free() when done. -bool LICE_ImageIsSupported(const char *filename); // must be a filename that ends in .jpg, etc. if you want to check the extension, pass .ext - - -// pass a bmp if you wish to load it into that bitmap. note that if it fails bmp will not be deleted. -LICE_IBitmap *LICE_LoadPNG(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitmap *bmp=NULL); -LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -#ifndef _WIN32 -LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -#endif - -LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success - -LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success - -LICE_IBitmap *LICE_LoadJPG(const char *filename, LICE_IBitmap *bmp=NULL); -LICE_IBitmap* LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap* bmp = 0); - -LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp=NULL, int *nframes=NULL); // if nframes set, will be set to number of images (stacked vertically), otherwise first frame used - -LICE_IBitmap *LICE_LoadPCX(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success - -LICE_IBitmap *LICE_LoadSVG(const char *filename, LICE_IBitmap *bmp=NULL); - -// bitmap saving -bool LICE_WritePNG(const char *filename, LICE_IBitmap *bmp, bool wantalpha=true); -bool LICE_WriteJPG(const char *filename, LICE_IBitmap *bmp, int quality=95, bool force_baseline=true); -bool LICE_WriteGIF(const char *filename, LICE_IBitmap *bmp, int transparent_alpha=0, bool dither=true); // if alpha - - - Debug - Win32 - - - Debug - X64 - - - Release - Win32 - - - Release - X64 - - - - {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC} - - - - StaticLibrary - false - MultiByte - - - StaticLibrary - false - MultiByte - false - - - StaticLibrary - - - StaticLibrary - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.20506.1 - $(Platform)/$(Configuration)/ - $(Platform)/$(Configuration)/ - lice - .lib - $(Platform)/$(Configuration)/ - $(Platform)/$(Configuration)/ - lice - .lib - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - - - - Disabled - ../zlib;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;PNG_USE_PNGVCRD;PNG_DEBUG;PNG_LIBPNG_SPECIALBUILD;__MMX__;PNG_HAVE_MMX_COMBINE_ROW;PNG_HAVE_MMX_READ_INTERLACE;PNG_HAVE_MMX_READ_FILTER_ROW;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/lice.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - true - .\Debug/lice.bsc - - - - - MaxSpeed - AnySuitable - true - Speed - false - ../zlib;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;__MMX__;PNG_HAVE_MMX_COMBINE_ROW;PNG_HAVE_MMX_READ_INTERLACE;PNG_HAVE_MMX_READ_FILTER_ROW;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - Default - false - false - StreamingSIMDExtensions2 - Fast - false - .\Release/lice.pch - .\Release/ - .\Release/ - .\Release/ - - - Level3 - true - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - true - .\Release/lice.bsc - - - - - StreamingSIMDExtensions2 - Fast - true - Speed - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/WDL/lice/lice_arc.cpp b/WDL/lice/lice_arc.cpp deleted file mode 100644 index 3be69e61..00000000 --- a/WDL/lice/lice_arc.cpp +++ /dev/null @@ -1,496 +0,0 @@ -#include "lice.h" -#include "lice_combine.h" -#include - -#define _PI 3.141592653589793238f - -template inline void _SWAP(T& a, T& b) { T tmp = a; a = b; b = tmp; } - -#define A(x) ((LICE_pixel_chan)((x)*255.0+0.5)) - -static bool CachedCircle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) -{ - // fast draw for some small circles - if (r == 1.5f) - { - if (aa) - { - LICE_pixel_chan alphas[25] = - { - A(0.31), A(1.00), A(1.00), A(0.31), - A(1.00), A(0.06), A(0.06), A(1.00), - A(1.00), A(0.06), A(0.06), A(1.00), - A(0.31), A(1.00), A(1.00), A(0.31), - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 4, 4, alpha, mode); - } - else - { - LICE_pixel_chan alphas[25] = - { - A(0.00), A(1.00), A(1.00), A(0.00), - A(1.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(1.00), - A(0.00), A(1.00), A(1.00), A(0.00), - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 4, 4, alpha, mode); - } - return true; - } - else if (r == 2.0f) - { - if (aa) - { - LICE_pixel_chan alphas[25] = - { - A(0.06), A(0.75), A(1.00), A(0.75), A(0.06), - A(0.75), A(0.82), A(0.31), A(0.82), A(0.75), - A(1.00), A(0.31), A(0.00), A(0.31), A(1.00), - A(0.75), A(0.82), A(0.31), A(0.82), A(0.75), - A(0.06), A(0.75), A(1.00), A(0.75), A(0.06) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 5, 5, alpha, mode); - } - else - { - LICE_pixel_chan alphas[25] = - { - A(0.00), A(0.00), A(1.00), A(0.00), A(0.00), - A(0.00), A(1.00), A(0.00), A(1.00), A(0.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(0.00), A(1.00), A(0.00), A(1.00), A(0.00), - A(0.00), A(0.00), A(1.00), A(0.00), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 5, 5, alpha, mode); - } - return true; - } - else if (r == 2.5f) { - if (aa) { - LICE_pixel_chan alphas[36] = { - A(0.06), A(0.75), A(1.00), A(1.00), A(0.75), A(0.06), - A(0.75), A(0.82), A(0.31), A(0.31), A(0.82), A(0.75), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.31), A(1.00), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.31), A(1.00), - A(0.75), A(0.82), A(0.31), A(0.31), A(0.82), A(0.75), - A(0.06), A(0.75), A(1.00), A(1.00), A(0.75), A(0.06) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 6, 6, alpha, mode); - } - else { - LICE_pixel_chan alphas[36] = { - A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), - A(0.00), A(1.00), A(0.00), A(0.00), A(1.00), A(0.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(0.00), A(1.00), A(0.00), A(0.00), A(1.00), A(0.00), - A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 6, 6, alpha, mode); - } - return true; - } - else if (r == 3.0f) { - if (aa) { - LICE_pixel_chan alphas[49] = { - A(0.00), A(0.56), A(1.00), A(1.00), A(1.00), A(0.56), A(0.00), - A(0.56), A(1.00), A(0.38), A(0.25), A(0.38), A(1.00), A(0.56), - A(1.00), A(0.44), A(0.00), A(0.00), A(0.00), A(0.44), A(1.00), - A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), - A(1.00), A(0.44), A(0.00), A(0.00), A(0.00), A(0.44), A(1.00), - A(0.56), A(1.00), A(0.38), A(0.25), A(0.38), A(1.00), A(0.56), - A(0.00), A(0.56), A(1.00), A(1.00), A(1.00), A(0.56), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 7, 7, alpha, mode); - } - else { - LICE_pixel_chan alphas[49] = { - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), - A(0.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(0.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(0.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(0.00), - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 7, 7, alpha, mode); - } - return true; - } - else if (r == 3.5f) { - if (aa) { - LICE_pixel_chan alphas[64] = { - A(0.00), A(0.31), A(0.87), A(1.00), A(1.00), A(0.87), A(0.31), A(0.00), - A(0.31), A(1.00), A(0.69), A(0.25), A(0.25), A(0.69), A(1.00), A(0.31), - A(0.87), A(0.69), A(0.00), A(0.00), A(0.00), A(0.00), A(0.69), A(0.87), - A(1.00), A(0.25), A(0.00), A(0.00), A(0.00), A(0.00), A(0.25), A(1.00), - A(1.00), A(0.25), A(0.00), A(0.00), A(0.00), A(0.00), A(0.25), A(1.00), - A(0.87), A(0.69), A(0.00), A(0.00), A(0.00), A(0.00), A(0.69), A(0.87), - A(0.31), A(1.00), A(0.69), A(0.25), A(0.25), A(0.69), A(1.00), A(0.31), - A(0.00), A(0.31), A(0.87), A(1.00), A(1.00), A(0.87), A(0.31), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 8, 8, alpha, mode); - } - else { - LICE_pixel_chan alphas[64] = { - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), - A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), - A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), - A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 8, 8, alpha, mode); - } - return true; - } - else if (r == 4.0f) { - if (aa) { - LICE_pixel_chan alphas[81] = { - A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00), - A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), - A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), - A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), - A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), - A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), - A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 9, 9, alpha, mode); - } - else { - LICE_pixel_chan alphas[81] = { - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), - A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), - A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), - A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), - A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), - A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) - }; - LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 9, 9, alpha, mode); - } - return true; - } - - return false; -} - - -template class _LICE_CircleDrawer -{ -public: - - static void DrawClippedPt(LICE_IBitmap* dest, int x, int y, int clip[], - int r, int g, int b, int a, int alpha, bool doclip) - { - if (doclip && (x < clip[0] || x >= clip[2] || y < clip[1] || y >= clip[3])) return; - LICE_pixel* px = dest->getBits()+y*dest->getRowSpan()+x; - COMBFUNC::doPix((LICE_pixel_chan*)px, r, g, b, a, alpha); - } - - static void DrawClippedHorzLine(LICE_IBitmap* dest, int y, int xlo, int xhi, int clip[], - int r, int g, int b, int a, int alpha, bool doclip) - { - if (doclip) { - if (y < clip[1] || y >= clip[3]) return; - xlo = max(xlo, clip[0]); - xhi = min(xhi, clip[2]-1); - } - LICE_pixel* px = dest->getBits()+y*dest->getRowSpan()+xlo; - while (xlo <= xhi) { - COMBFUNC::doPix((LICE_pixel_chan*)px, r, g, b, a, alpha); - ++px; - ++xlo; - } - } - - static void DrawClippedCircleAA(LICE_IBitmap* dest, float cx, float cy, float rad, - int clip[], LICE_pixel color, int ai, bool filled, bool doclip) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - float r2 = rad*rad; - float x = 0.0f; - float y = rad; - while (x < y+1.0f) - { - float w = y-floor(y); - - if (w == 0.0f) - { - DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, ai, doclip); - } - else - { - int wa = (int)(ai*w); - int iwa = ai-wa; - - DrawClippedPt(dest, cx+x, cy+y+1, clip, r, g, b, a, wa, doclip); - DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, iwa, doclip); - - DrawClippedPt(dest, cx+x, cy-y+1, clip, r, g, b, a, iwa, doclip); - DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, wa, doclip); - - DrawClippedPt(dest, cx-x, cy+y+1, clip, r, g, b, a, wa, doclip); - DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, iwa, doclip); - - DrawClippedPt(dest, cx-x, cy-y+1, clip, r, g, b, a, iwa, doclip); - DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, wa, doclip); - - DrawClippedPt(dest, cx+y+1, cy+x, clip, r, g, b, a, wa, doclip); - DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, iwa, doclip); - - DrawClippedPt(dest, cx+y+1, cy-x, clip, r, g, b, a, wa, doclip); - DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, iwa, doclip); - - DrawClippedPt(dest, cx-y+1, cy+x, clip, r, g, b, a, iwa, doclip); - DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, wa, doclip); - - DrawClippedPt(dest, cx-y+1, cy-x, clip, r, g, b, a, iwa, doclip); - DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, wa, doclip); - } - - if (filled) - { - DrawClippedHorzLine(dest, cy-y+1, cx-x, cx+x, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy+y, cx-x, cx+x, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy-x, cx-y+1, cx+y, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy+x, cx-y+1, cx+y, clip, r, g, b, a, ai, doclip); - } - - x += 1; - y = sqrt(r2-x*x); - } - } - - static void DrawClippedCircle(LICE_IBitmap* dest, float cx, float cy, float rad, - int clip[], LICE_pixel color, int ai, bool filled, bool doclip) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - float x = 0.0; - float y = rad; - float p = (5.0-rad*4.0)/4.0; - - DrawClippedPt(dest, cx, cy+rad, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx, cy-rad, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+rad, cy, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-rad, cy, clip, r, g, b, a, ai, doclip); - - if (filled) { - DrawClippedHorzLine(dest, cy, cx-rad+1, cx+rad-1, clip, r, g, b, a, ai, doclip); - } - - while (x < y) { - x += 1.0f; - - if (p < 0) { - p += 2.0f*x+1.0f; - } - else { - y -= 1.0f; - p += 2.0*(x-y)+1.0f; - } - - DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, ai, doclip); - DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, ai, doclip); - - if (filled) { - DrawClippedHorzLine(dest, cy-y, cx-x+1, cx+x-1, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy+y, cx-x+1, cx+x-1, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy-x, cx-y+1, cx+y-1, clip, r, g, b, a, ai, doclip); - DrawClippedHorzLine(dest, cy+x, cx-y+1, cx+y-1, clip, r, g, b, a, ai, doclip); - } - } - } - - -}; - - -static void __DrawCircleClipped(LICE_IBitmap* dest, float cx, float cy, float rad, - LICE_pixel color, int ia, bool aa, bool filled, int mode, int *clip, bool doclip) -{ - // todo: more clipped/filled versions (to optimize constants out?) - if (aa) - { - #define __LICE__ACTION(COMBFUNC) _LICE_CircleDrawer::DrawClippedCircleAA(dest, cx, cy, rad, clip, color, ia, filled, doclip) - __LICE_ACTION_NOSRCALPHA(mode, ia,false) - #undef __LICE__ACTION - } - else - { - #define __LICE__ACTION(COMBFUNC) _LICE_CircleDrawer::DrawClippedCircle(dest, cx, cy, rad, clip, color, ia, filled, doclip) - __LICE_ACTION_CONSTANTALPHA(mode,ia,false) - #undef __LICE__ACTION - } -} - - -static void __DrawArc(int w, int h, LICE_IBitmap* dest, float cx, float cy, float rad, float anglo, float anghi, - LICE_pixel color, int ialpha, bool aa, int mode) -{ - // -2PI <= anglo <= anghi <= 2PI - - if (anglo < -_PI && anghi > -_PI) - { - __DrawArc(w,h,dest, cx, cy, rad, anglo, -_PI, color, ialpha, aa,mode); - anglo=-_PI; - } - - if (anglo < 0.0f && anghi > 0.0f) - { - __DrawArc(w,h,dest, cx, cy, rad, anglo+2.0f*_PI, 2.0f*_PI, color, ialpha, aa,mode); - anglo=0.0f; - } - - if (anglo < _PI && anghi > _PI) - { - __DrawArc(w,h,dest, cx, cy, rad, anglo, _PI, color, ialpha, aa,mode); - anglo=_PI; - } - - int ylo = (int) (cy-rad*cos(anglo)+0.5); - int yhi = (int) (cy-rad*cos(anghi)+0.5); - - if (yhi < ylo) { int tmp = ylo; ylo = yhi; yhi=tmp; } - - int clip[4]={0,max(0, ylo),w,min(h, yhi+1)}; - - if (anglo < -_PI || (anglo >= 0.0f && anglo < _PI)) - { - if (cx>0) clip[0]=cx; - } - else - { - if (cxisFlipped()) { cy=dest->getHeight()-1-cy; minAngle=_PI-minAngle; maxAngle=_PI-maxAngle; } - - if (maxAngle < minAngle) - { - float tmp=maxAngle; - maxAngle=minAngle; - minAngle=tmp; - } - - if (maxAngle - minAngle >= 2.0f*_PI) - { - LICE_Circle(dest,cx,cy,r,color,alpha,mode,aa); - return; - } - - if (maxAngle >= 2.0f*_PI) - { - float tmp = fmod(maxAngle,2.0f*_PI); - minAngle -= maxAngle - tmp; // reduce by factors of 2PI - maxAngle = tmp; - } - else if (minAngle <= -2.0f*_PI) - { - float tmp = fmod(minAngle,2.0f*_PI); - maxAngle -= minAngle - tmp; // toward zero by factors of 2pi - minAngle = tmp; - } - - // -2PI <= minAngle <= maxAngle <= 2PI - - int ia = (int) (alpha*256.0f); - if (!ia) return; - - __DrawArc(dest->getWidth(),dest->getHeight(),dest,cx,cy,r,minAngle,maxAngle,color,ia,aa,mode); -} - - - - -void LICE_Circle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) -{ - if (!dest) return; - if (CachedCircle(dest, cx, cy, r, color, alpha, mode, aa)) return; - - if (dest->isFlipped()) cy=dest->getHeight()-1-cy; - - int ia = (int) (alpha*256.0f); - if (!ia) return; - - int w = dest->getWidth(), h = dest->getHeight(); - int clip[4] = { 0, 0, w, h }; - - bool doclip = (cx-r-1 < 0 || cy-r-1 < 0 || cx+r+1 >= w || cy+r+1 >= h); - - __DrawCircleClipped(dest,cx,cy,r,color,ia,aa,false,mode,clip,doclip); -} - -void LICE_FillCircle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) -{ - if (!dest) return; - if (dest->isFlipped()) cy=dest->getHeight()-1-cy; - - int ia = (int) (alpha*256.0f); - if (!ia) return; - int w = dest->getWidth(), h = dest->getHeight(); - int clip[4] = { 0, 0, w, h }; - - bool doclip = (cx-r-1 < 0 || cy-r-1 < 0 || cx+r+1 >= w || cy+r+1 >= h); - __DrawCircleClipped(dest,cx,cy,r,color,ia,aa,true,mode,clip,doclip); -} - - -void LICE_RoundRect(LICE_IBitmap *drawbm, float xpos, float ypos, float w, float h, int cornerradius, - LICE_pixel col, float alpha, int mode, bool aa) -{ - if (cornerradius>0) - { - float cr=cornerradius; - if (cr > w*0.5) cr=w*0.5; - if (cr > h*0.5) cr=h*0.5; - cr=floor(cr); - if (cr>=2) - { - LICE_Line(drawbm,xpos+cr,ypos,xpos+w-cr,ypos,col,alpha,mode,aa); - LICE_Line(drawbm,xpos+cr-1,ypos+h,xpos+w-cr,ypos+h,col,alpha,mode,aa); - LICE_Line(drawbm,xpos+w,ypos+cr,xpos+w,ypos+h-cr,col,alpha,mode,aa); - LICE_Line(drawbm,xpos,ypos+cr-1,xpos,ypos+h-cr,col,alpha,mode,aa); - - - LICE_Arc(drawbm,xpos+cr,ypos+cr,cr,-_PI*0.5f,0,col,alpha,mode,aa); - LICE_Arc(drawbm,xpos+w-cr,ypos+cr,cr,0,_PI*0.5f,col,alpha,mode,aa); - LICE_Arc(drawbm,xpos+w-cr,ypos+h-cr,cr,_PI*0.5f,_PI,col,alpha,mode,aa); - LICE_Arc(drawbm,xpos+cr,ypos+h-cr,cr,_PI,_PI*1.5f,col,alpha,mode,aa); - - return; - } - } - - LICE_DrawRect(drawbm, xpos, ypos, w, h, col, alpha, mode); -} - diff --git a/WDL/lice/lice_bezier.h b/WDL/lice/lice_bezier.h deleted file mode 100644 index d10381d1..00000000 --- a/WDL/lice/lice_bezier.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef _LICE_BEZIER_ -#define _LICE_BEZIER_ - -#include "lice.h" -#include - -// Returns quadratic bezier x, y for a given t in [0,1]. -template -void LICE_Bezier(T ctrl_x1, T ctrl_x2, T ctrl_x3, - T ctrl_y1, T ctrl_y2, T ctrl_y3, double t, T* pX, T* pY) -{ - double it = 1.0 - t; - double a = it * it; - double b = 2.0 * it * t; - double c = t * t; - *pX = (T) (a * (double) ctrl_x1 + b * (double) ctrl_x2 + c * (double) ctrl_x3); - *pY = (T) (a * (double) ctrl_y1 + b * (double) ctrl_y2 + c * (double) ctrl_y3); -} - -template -void LICE_CBezier_GetCoeffs(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, - T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, - double* pAX, double* pBX, double* pCX, - double* pAY, double* pBY, double* pCY) -{ - double cx = *pCX = 3.0 * (double) (ctrl_x2 - ctrl_x1); - double bx = *pBX = 3.0 * (double) (ctrl_x3 - ctrl_x2) - cx; - *pAX = (double) (ctrl_x4 - ctrl_x1) - cx - bx; - double cy = *pCY = 3.0 * (double) (ctrl_y2 - ctrl_y1); - double by = *pBY = 3.0 * (double) (ctrl_y3 - ctrl_y2) - cy; - *pAY = (double) (ctrl_y4 - ctrl_y1) - cy - by; -} - -// Returns cubic bezier x, y for a given t in [0,1]. -template -void LICE_CBezier(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, - T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, double t, T* pX, T* pY) -{ - double ax, bx, cx, ay, by, cy; - LICE_CBezier_GetCoeffs(ctrl_x1, ctrl_x2, ctrl_x3, ctrl_x4, - ctrl_y1, ctrl_y2, ctrl_y3, ctrl_y4, - &ax, &bx, &cx, &ay, &by, &cy); - - double t2 = t * t; - double t3 = t * t2; - *pX = (T) (ax * t3 + bx * t2 + cx * t) + ctrl_x1; - *pY = (T) (ay * t3 + by * t2 + cy * t) + ctrl_y1; -} - -// Returns quadratic bezier y for a given x in [x1, x3] (for rasterizing). -// ctrl_x1 < ctrl_x3 required. -template -T LICE_Bezier_GetY(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_y1, T ctrl_y2, T ctrl_y3, T x, double* pt=0) -{ - if (x <= ctrl_x1) - { - if (pt) *pt = 0.0; - return ctrl_y1; - } - if (x >= ctrl_x3) - { - if (pt) *pt = 1.0; - return ctrl_y3; - } - - double a = (double) ctrl_x1 - (double) (2 * ctrl_x2) + (double) ctrl_x3; - if (a == 0.0) // linear - { - T y = ctrl_y1; - double t = 0.0; - if (ctrl_x1 != ctrl_x3) - { - t = (x-ctrl_x1)/(ctrl_x3-ctrl_x1); - y += t*(ctrl_y3-ctrl_y1); - } - if (pt) *pt = t; - return y; - } - - double b = (double) (2 * (ctrl_x2 - ctrl_x1)); - double c = (double) (ctrl_x1 - x); - double t = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a); - double it = 1.0 - t; - - a = it * it; - b = 2.0 * it * t; - c = t * t; - - if (pt) *pt = t; - return (T) (a * (double) ctrl_y1 + b * (double) ctrl_y2 + c * (double) ctrl_y3); -} - -// Special case for x = y = [0,1] -template -void LICE_Bezier_Norm(T ctrl_x2, T ctrl_y2, double t, T* pX, T* pY) -{ - double b = 2.0 * (1.0 - t) * t; - double c = t * t; - *pX = (T) (b * (double) ctrl_x2 + c); - *pY = (T) (b * (double) ctrl_y2 + c); -} - -// special case for x = y = [0,1]. -template -T LICE_Bezier_GetY_Norm(T ctrl_x2, T ctrl_y2, T x) -{ - if (x < (T) 0.0) { - return (T) 0.0; - } - if (x >= (T) 1.0) { - return (T) 1.0; - } - if (ctrl_x2 == (T) 0.5) { // linear - return x; - } - - double b = (double) (2 * ctrl_x2); - double a = 1.0 - b; - double c = (double) -x; - double t = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a); - - b = 2.0 * (1.0 - t) * t; - c = t * t; - return (T) (b * (double) ctrl_y2 + c); -} - -// Finds the cardinal bezier control points surrounding x2. -// Cubic bezier over (x1,x1b,x2a,x2), (y1,y1b,y2a,y2) or -// quadratic bezier over (x1,x1b,mid(x1b,x2a)), (y1,y1b,mid(y1b,y2a)) -// will smoothly interpolate between (x1,y1) and (x2,y2) while preserving all existing values. -// The lower alpha is, the more tame the bezier curve will be (0.25 = subtle). -template -void LICE_Bezier_FindCardinalCtlPts(double alpha, T x1, T x2, T x3, T y1, T y2, T y3, - T* ctrl_x2a, T* ctrl_x2b, T* ctrl_y2a, T* ctrl_y2b) -{ - double dxa = alpha * (double) (x2 - x1); - double dxb = alpha * (double) (x3 - x2); - if (ctrl_x2a) *ctrl_x2a = x2 - (T) dxa; - if (ctrl_x2b) *ctrl_x2b = x2 + (T) dxb; - - if (x1 == x3) - { - if (ctrl_y2a) *ctrl_y2a = y2; - if (ctrl_y2b) *ctrl_y2b = y2; - } - else - { - double m = (double) (y3 - y1) / (double) (x3 - x1); - if (ctrl_y2a) *ctrl_y2a = y2 - (T) (m * dxa); - if (ctrl_y2b) *ctrl_y2b = y2 + (T) (m * dxb); - } -} - -// Basic quadratic nurbs. Given a set of n (x,y) pairs, -// populate pDest with the unit-spaced nurbs curve. -// pDest must be passed in with size (int) (*(pX+n-1) - *pX). -// pX must be monotonically increasing and no duplicates. -template -inline void LICE_QNurbs(T* pDest, T* pX, T* pY, int n) -{ - double x1 = (double) *pX++, x2 = (double) *pX++; - double y1 = (double) *pY++, y2 = (double) *pY++; - double xm1, xm2 = 0.5 * (x1 + x2); - double ym1, ym2 = 0.5 * (y1 + y2); - - double m = (y2 - y1) / (x2 - x1); - double xi = x1, yi = y1; - for (/* */; xi < xm2; xi += 1.0, yi += m, ++pDest) - { - *pDest = (T) yi; - } - - for (int i = 2; i < n; ++i, ++pX, ++pY) - { - x1 = x2; - x2 = (double) *pX; - y1 = y2; - y2 = (double) *pY; - - xm1 = xm2; - xm2 = 0.5 * (x1 + x2); - ym1 = ym2; - ym2 = 0.5 * (y1 + y2); - - if (ym1 == ym2) - { - for (/* */; xi < xm2; xi += 1.0, ++pDest) - { - *pDest = (T) y1; - } - } - else - { - for (/* */; xi < xm2; xi += 1.0, ++pDest) - { - *pDest = (T) LICE_Bezier_GetY(xm1, x1, xm2, ym1, y1, ym2, xi); - } - } - } - - m = (y2 - y1) / (x2 - x1); - yi = ym2; - for (/* */; xi < x2; xi += 1.0, yi += m, ++pDest) - { - *pDest = (T) yi; - } -} - -#define CBEZ_ITERS 8 - -#define EVAL_CBEZ(tx,a,b,c,d,t) \ -{ \ - double _t2=t*t; \ - tx=(a*t*_t2+b*_t2+c*t+d); \ -} - -#define EVAL_CBEZXY(tx, ty, ax, bx, cx, dx, ay, by, cy, dy, t) \ -{ \ - double _t2=t*t; \ - double _t3=t*_t2; \ - tx=ax*_t3+bx*_t2+cx*t+dx; \ - ty=ay*_t3+by*_t2+cy*t+dy; \ -} - -template -T LICE_CBezier_GetY(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, - T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, T x, - T* pNextX = 0, T* pdYdX = 0, double* ptLo = 0, double* ptHi = 0) -{ - if (x < ctrl_x1) - { - if (pNextX) *pNextX = ctrl_x1; - if (pdYdX) *pdYdX = (T) 0.0; - return ctrl_y1; - } - if (x >= ctrl_x4) - { - if (pNextX) *pNextX = ctrl_x4; - if (pdYdX) *pdYdX = (T) 0.0; - return ctrl_y4; - } - - double ax, bx, cx, ay, by, cy; - LICE_CBezier_GetCoeffs(ctrl_x1, ctrl_x2, ctrl_x3, ctrl_x4, - ctrl_y1, ctrl_y2, ctrl_y3, ctrl_y4, - &ax, &bx, &cx, &ay, &by, &cy); - - double tx, t, tLo = 0.0, tHi = 1.0; - double xLo, xHi, yLo, yHi; - int i; - for (i = 0; i < CBEZ_ITERS; ++i) - { - t = 0.5 * (tLo + tHi); - EVAL_CBEZ(tx, ax, bx, cx, (double) ctrl_x1, t); - if (tx < (double) x) - { - tLo = t; - xLo = tx; - } - else if (tx > (double) x) - { - tHi = t; - xHi = tx; - } - else - { - tLo = t; - xLo = tx; - tHi = t + 1.0/pow(2.0,CBEZ_ITERS); - if (tHi > 1.0) tHi = 1.0; // floating point error - EVAL_CBEZ(xHi, ax, bx, cx, (double) ctrl_x1, tHi); - break; - } - } - - if (tLo == 0.0) EVAL_CBEZ(xLo, ax, bx, cx, (double) ctrl_x1, 0.0); - if (tHi == 1.0) EVAL_CBEZ(xHi, ax, bx, cx, (double) ctrl_x1, 1.0); - - EVAL_CBEZ(yLo, ay, by, cy, (double) ctrl_y1, tLo); - EVAL_CBEZ(yHi, ay, by, cy, (double) ctrl_y1, tHi); - - double dYdX = (xLo == xHi ? 0.0 : (yHi - yLo) / (xHi - xLo)); - double y = yLo + ((double) x - xLo) * dYdX; - - if (pNextX) *pNextX = (T) xHi; - if (pdYdX) *pdYdX = (T) dYdX; - - if (ptLo) *ptLo = tLo; - if (ptHi) *ptHi = tHi; - - return (T) y; -} - -#endif - diff --git a/WDL/lice/lice_bmp.cpp b/WDL/lice/lice_bmp.cpp deleted file mode 100644 index fab3d98b..00000000 --- a/WDL/lice/lice_bmp.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_bmp.cpp (BMP loading for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" -#ifndef _WIN32 -#include "../swell/swell.h" -#endif - -static LICE_IBitmap *hbmToBit(HBITMAP hbm, LICE_IBitmap *bmp) -{ - BITMAP bm; - GetObject(hbm, sizeof(BITMAP), (LPSTR)&bm); - - LICE_SysBitmap sysbitmap(bm.bmWidth,bm.bmHeight); - -#ifdef _WIN32 - HDC hdc=CreateCompatibleDC(NULL); - HGDIOBJ oldBM=SelectObject(hdc,hbm); - - BitBlt(sysbitmap.getDC(),0,0,bm.bmWidth,bm.bmHeight,hdc,0,0,SRCCOPY); - GdiFlush(); - - if (!bmp) bmp=new LICE_MemBitmap(bm.bmWidth,bm.bmHeight); - LICE_Copy(bmp,&sysbitmap); - - SelectObject(hdc,oldBM); - DeleteDC(hdc); - #else - LICE_Clear(&sysbitmap,0); - RECT r={0,0,bm.bmWidth,bm.bmHeight}; - DrawImageInRect(sysbitmap.getDC(),hbm,&r); - if (!bmp) bmp=new LICE_MemBitmap(bm.bmWidth,bm.bmHeight); - LICE_Copy(bmp,&sysbitmap); - #endif - - LICE_FillRect(bmp,0,0,bmp->getWidth(),bmp->getHeight(),LICE_RGBA(0,0,0,255),1.0f,LICE_BLIT_MODE_ADD); - - return bmp; -} - - -LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success -{ - HBITMAP bm=NULL; -#ifdef _WIN32 - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - bm = (HBITMAP) LoadImageW(NULL,wf,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); - } - - if (!bm) bm=(HBITMAP) LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); -#else - bm=(HBITMAP) LoadNamedImage(filename,false); -#endif - if (!bm) return 0; - - LICE_IBitmap *ret=hbmToBit(bm,bmp); - - DeleteObject(bm); - return ret; -} - -#ifdef _WIN32 -LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success -{ - HBITMAP bm=(HBITMAP) LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); - if (!bm) return 0; - - LICE_IBitmap *ret=hbmToBit(bm,bmp); - - DeleteObject(bm); - return ret; -} -#endif - - - -class LICE_BMPLoader -{ -public: - _LICE_ImageLoader_rec rec; - LICE_BMPLoader() - { - rec.loadfunc = loadfunc; - rec.get_extlist = get_extlist; - rec._next = LICE_ImageLoader_list; - LICE_ImageLoader_list = &rec; - } - - static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) - { - if (checkFileName) - { - const char *p=filename; - while (*p)p++; - while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".bmp")) return 0; - } - return LICE_LoadBMP(filename,bmpbase); - } - static const char *get_extlist() - { - return "BMP files (*.BMP)\0*.BMP\0"; - } - -}; - -LICE_BMPLoader LICE_bmpldr; \ No newline at end of file diff --git a/WDL/lice/lice_colorspace.cpp b/WDL/lice/lice_colorspace.cpp deleted file mode 100644 index 433cfc94..00000000 --- a/WDL/lice/lice_colorspace.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "lice.h" -#include - -#define LICE_COMBINE_IMPLEMENT_HSV -#include "lice_combine.h" - - -LICE_pixel LICE_AlterColorHSV_int(LICE_pixel color, int dH, int dS, int dV) // H is rolled over [0,384), S and V are clamped [0,255) -{ - int h, s, v; - LICE_RGB2HSV(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), &h, &s, &v); - - h += dH; - s += dS; - v += dV; - - if (h < 0) h += 384; - else if (h >= 384) h -= 384; - - if (s & ~255) - { - if (s<0) s = 0; - else s = 255; - } - - if (v&~255) - { - if (v < 0) v = 0.; - else v = 255; - } - - return LICE_HSV2Pix(h, s, v, LICE_GETA(color)); -} - -LICE_pixel LICE_AlterColorHSV(LICE_pixel color, float dH, float dS, float dV) // H is rolled over, S and V are clamped, all [0,1) -{ - int dHi = (int)(dH*384.0f); - int dSi = (int)(dS*255.0f); - int dVi = (int)(dV*255.0f); - return LICE_AlterColorHSV_int(color, dHi, dSi, dVi); -} - -void LICE_AlterBitmapHSV(LICE_IBitmap* src, float dH, float dS, float dV) // H is rolled over, S and V are clamped -{ - if (src) LICE_AlterRectHSV(src,0,0,src->getWidth(),src->getHeight(),dH,dS,dV); -} - -void LICE_AlterRectHSV(LICE_IBitmap* src, int x, int y, int w, int h, float dH, float dS, float dV) // H is rolled over, S and V are clamped -{ - if (!src) return; - - if (x < 0) { - w += x; - x = 0; - } - if (y < 0) { - h += y; - y = 0; - } - if (x+w > src->getWidth()) { - w = src->getWidth()-x; - } - if (y+h > src->getHeight()) { - h = src->getHeight()-y; - } - - int span = src->getRowSpan(); - LICE_pixel* px = src->getBits()+y*span+x; - - int dHi = (int)(dH*384.0f); - int dSi = (int)(dS*255.0f); - int dVi = (int)(dV*255.0f); - if (dHi > 383) dHi=383; - else if (dHi < -383) dHi=-383; - - - if (!dHi && !dSi && !dVi) return; // no mod - - if (w*h > 8192) - { - // generate a table of HSV translations with clip/clamp - unsigned char stab[256], vtab[256]; - short htab[384]; - int x; - for(x=0;x<256;x++) - { - int a=x+dSi; - if(a<0)a=0; else if (a>255)a=255; - stab[x]=a; - - a=x+dVi; - if(a<0)a=0; else if (a>255)a=255; - vtab[x]=a; - - a=x+dHi; - if(a<0)a+=384; else if (a>=384)a-=384; - htab[x]=a; - } - for(;x<384;x++) - { - int a=x+dHi; - if(a<0)a+=384; else if (a>=384)a-=384; - htab[x]=a; - } - - while (h-->0) - { - LICE_pixel* tpx = px; - px+=span; - int xi=w; - while (xi-->0) - { - LICE_pixel color = *tpx; - int h,s,v; - LICE_RGB2HSV(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), &h, &s, &v); - *tpx++ = LICE_HSV2Pix(htab[h],stab[s],vtab[v],LICE_GETA(color)); - } - } - } - else - { - while (h-->0) - { - LICE_pixel* tpx = px; - px+=span; - int xi=w; - while (xi-->0) - { - *tpx = LICE_AlterColorHSV_int(*tpx, dHi, dSi, dVi); - tpx++; - } - } - } -} diff --git a/WDL/lice/lice_combine.h b/WDL/lice/lice_combine.h deleted file mode 100644 index 1613e520..00000000 --- a/WDL/lice/lice_combine.h +++ /dev/null @@ -1,831 +0,0 @@ -#ifndef _LICE_COMBINE_H_ -#define _LICE_COMBINE_H_ - -#if defined(_MSC_VER) -#pragma warning(disable:4244) // float-to-int -#endif - -#define __LICE_BOUND(x,lo,hi) ((x)<(lo)?(lo):((x)>(hi)?(hi):(x))) - - - -#define LICE_PIXEL_HALF(x) (((x)>>1)&0x7F7F7F7F) -#define LICE_PIXEL_QUARTER(x) (((x)>>2)&0x3F3F3F3F) -#define LICE_PIXEL_EIGHTH(x) (((x)>>3)&0x1F1F1F1F) - - - -#if defined(_MSC_VER) && !defined(_WIN64) -static inline int __LICE_TOINT(double x) // don't use this _everywhere_ since it doesnt round the same as (int) -{ - int tmp; - __asm - { - fld x - fistp tmp - }; - return tmp; -} -#else -#define __LICE_TOINT(x) ((int)(x)) -#endif - - -static inline void __LICE_BilinearFilterI(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int xfrac, int yfrac) -{ - int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; - int f3=yfrac-f4; // (1.0-xfrac)*yfrac; - int f2=xfrac-f4; // xfrac*(1.0-yfrac); - int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); - #define DOCHAN(output, inchan) \ - (output)=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)/65536; - DOCHAN(*r,LICE_PIXEL_R) - DOCHAN(*g,LICE_PIXEL_G) - DOCHAN(*b,LICE_PIXEL_B) - DOCHAN(*a,LICE_PIXEL_A) - #undef DOCHAN -} - -static inline void __LICE_BilinearFilterIPixOut(LICE_pixel_chan *out, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int xfrac, int yfrac) -{ - int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; - int f3=yfrac-f4; // (1.0-xfrac)*yfrac; - int f2=xfrac-f4; // xfrac*(1.0-yfrac); - int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); - #define DOCHAN(inchan) \ - (out[inchan])=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)/65536; - DOCHAN(LICE_PIXEL_R) - DOCHAN(LICE_PIXEL_G) - DOCHAN(LICE_PIXEL_B) - DOCHAN(LICE_PIXEL_A) - #undef DOCHAN -} - - -static inline void __LICE_BilinearFilterI_2(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int npoffs, int xfrac, int yfrac) -{ - int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; - int f3=yfrac-f4; // (1.0-xfrac)*yfrac; - int f2=xfrac-f4; // xfrac*(1.0-yfrac); - int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); - npoffs*=4; - *r=(pin[LICE_PIXEL_R]*f1 + pin[npoffs+LICE_PIXEL_R]*f2 + pinnext[LICE_PIXEL_R]*f3 + pinnext[npoffs+LICE_PIXEL_R]*f4)/65536; - *g=(pin[LICE_PIXEL_G]*f1 + pin[npoffs+LICE_PIXEL_G]*f2 + pinnext[LICE_PIXEL_G]*f3 + pinnext[npoffs+LICE_PIXEL_G]*f4)/65536; - *b=(pin[LICE_PIXEL_B]*f1 + pin[npoffs+LICE_PIXEL_B]*f2 + pinnext[LICE_PIXEL_B]*f3 + pinnext[npoffs+LICE_PIXEL_B]*f4)/65536; - *a=(pin[LICE_PIXEL_A]*f1 + pin[npoffs+LICE_PIXEL_A]*f2 + pinnext[LICE_PIXEL_A]*f3 + pinnext[npoffs+LICE_PIXEL_A]*f4)/65536; -} - - -static inline void __LICE_LinearFilterI(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int frac) -{ - int f=65536-frac; - *r=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)/65536; - *g=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)/65536; - *b=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)/65536; - *a=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)/65536; -} -static inline void __LICE_LinearFilterIPixOut(LICE_pixel_chan *out, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int frac) -{ - int f=65536-frac; - out[LICE_PIXEL_R]=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)/65536; - out[LICE_PIXEL_G]=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)/65536; - out[LICE_PIXEL_B]=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)/65536; - out[LICE_PIXEL_A]=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)/65536; -} - -static void inline _LICE_MakePixelClamp(LICE_pixel_chan *out, int r, int g, int b, int a) -{ -#define LICE_PIX_MAKECHAN(a,b) out[a] = (b&~0xff) ? (b<0?0:255) : b; - LICE_PIX_MAKECHAN(LICE_PIXEL_B,b) - LICE_PIX_MAKECHAN(LICE_PIXEL_G,g) - LICE_PIX_MAKECHAN(LICE_PIXEL_R,r) - LICE_PIX_MAKECHAN(LICE_PIXEL_A,a) -#undef LICE_PIX_MAKECHAN -} - -static void inline _LICE_MakePixelNoClamp(LICE_pixel_chan *out, LICE_pixel_chan r, LICE_pixel_chan g, LICE_pixel_chan b, LICE_pixel_chan a) -{ -#define LICE_PIX_MAKECHAN(a,b) out[a] = b; - LICE_PIX_MAKECHAN(LICE_PIXEL_B,b) - LICE_PIX_MAKECHAN(LICE_PIXEL_G,g) - LICE_PIX_MAKECHAN(LICE_PIXEL_R,r) - LICE_PIX_MAKECHAN(LICE_PIXEL_A,a) -#undef LICE_PIX_MAKECHAN -} - - - -#define HSV_P v*(256-s)/256 -#define HSV_Q(hval) v*(16384-(hval)*s)/16384 -#define HSV_T(hval) v*(16384-(64-(hval))*s)/16384 -#define HSV_X v -extern unsigned short _LICE_RGB2HSV_invtab[256]; // 65536/idx - 1 - -#ifdef LICE_COMBINE_IMPLEMENT_HSV - LICE_pixel LICE_HSV2Pix(int h, int s, int v, int alpha) - #define __LICE_HSV2Pix LICE_HSV2Pix -#else - static inline LICE_pixel __LICE_HSV2Pix(int h, int s, int v, int alpha) -#endif -{ - if (h<192) - { - if (h<64) return LICE_RGBA(HSV_X,HSV_T(h),HSV_P,alpha); - if (h<128) return LICE_RGBA(HSV_Q(h-64),HSV_X,HSV_P,alpha); - return LICE_RGBA(HSV_P,HSV_X,HSV_T(h-128),alpha); - } - if (h < 256) return LICE_RGBA(HSV_P,HSV_Q(h-192),HSV_X,alpha); - if (h < 320) return LICE_RGBA(HSV_T(h-256),HSV_P,HSV_X,alpha); - return LICE_RGBA(HSV_X,HSV_P,HSV_Q(h-320),alpha); -} - -#ifdef LICE_COMBINE_IMPLEMENT_HSV -void LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b) -#define __LICE_HSV2RGB LICE_HSV2RGB -#else -static inline void __LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b) -#endif -{ - if (h<192) - { - if (h<64) - { - *r = HSV_X; *g = HSV_T(h); *b = HSV_P; - } - else if (h<128) - { - *r = HSV_Q(h-64); *g = HSV_X; *b = HSV_P; - } - else - { - *r = HSV_P; *g = HSV_X; *b = HSV_T(h-128); - } - } - else - { - if (h < 256) - { - *r = HSV_P; *g = HSV_Q(h-192); *b = HSV_X; - } - else if (h < 320) - { - *r = HSV_T(h-256); *g = HSV_P; *b = HSV_X; - } - else - { - *r = HSV_X; *g = HSV_P; *b = HSV_Q(h-320); - } - } -} - - -#define LICE_RGB2HSV_USE_TABLE -// h = [0,384), s and v = [0,256) - -#ifdef LICE_COMBINE_IMPLEMENT_HSV - void LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v) - #define __LICE_RGB2HSV LICE_RGB2HSV -#else - static inline void __LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v) -#endif -{ - - // this makes it just 3 conditional branches per call - int df,d,maxrgb; - int degoffs; - if (g > r) - { - if (g>b) // green max - { - maxrgb=g; - degoffs=128; - df = maxrgb - min(b,r); - d=b-r; - } - else // blue max - { - maxrgb=b; - degoffs=256; - df = maxrgb - min(g,r); - d=r-g; - } - } - else // r >= g - { - if (r > b) // red max - { - maxrgb=r; - - if (g>1) &0x7f7f7f7f) + ((src>>1)&0x7f7f7f7f); - } -}; - -class _LICE_CombinePixelsHalfMixClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - _LICE_MakePixelClamp(dest, - (dest[LICE_PIXEL_R]+r)/2, - (dest[LICE_PIXEL_G]+g)/2, - (dest[LICE_PIXEL_B]+b)/2, - (dest[LICE_PIXEL_A]+a)/2); - } - -}; - - -class _LICE_CombinePixelsHalfMix2FAST -{ -public: - static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-halfed and masked - { - *dest = ((*dest>>1) &0x7f7f7f7f) + src; - } -}; - -class _LICE_CombinePixelsQuarterMix2FAST -{ -public: - static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-quartered and masked - { - LICE_pixel tmp = *dest; - *dest = ((tmp>>1) &0x7f7f7f7f) + ((tmp>>2) &0x3f3f3f3f) + src; - } -}; - - -class _LICE_CombinePixelsThreeQuarterMix2FAST -{ -public: - static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-quartered and masked - { - *dest = ((*dest>>2) &0x3f3f3f3f) + src; - } -}; - -class _LICE_CombinePixelsCopyNoClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - int sc=(256-alpha); - - // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) - _LICE_MakePixelNoClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - a + ((dest[LICE_PIXEL_A]-a)*sc)/256); - } -}; - -class _LICE_CombinePixelsCopyClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - int sc=(256-alpha); - - // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) - _LICE_MakePixelClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - a + ((dest[LICE_PIXEL_A]-a)*sc)/256); - } -}; - -class _LICE_CombinePixelsCopySourceAlphaNoClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - int sc2=(alpha*(a+1))/256; - int sc = 256 - sc2; - - _LICE_MakePixelNoClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - min(255,sc2 + dest[LICE_PIXEL_A])); - } - } -}; - -class _LICE_CombinePixelsCopySourceAlphaClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - int sc2=(alpha*(a+1))/256; - int sc = 256 - sc2; - - _LICE_MakePixelClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - sc2 + dest[LICE_PIXEL_A]); - } - } -}; -class _LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmNoClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - if (a==255) - { - _LICE_MakePixelNoClamp(dest,r,g,b,a); - } - else - { - int sc=(255-a); - - _LICE_MakePixelNoClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - min(255,a + dest[LICE_PIXEL_A])); - } - } - } -}; -class _LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - if (a==255) - { - _LICE_MakePixelClamp(dest,r,g,b,a); - } - else - { - int sc=(255-a); - - _LICE_MakePixelClamp(dest, - r + ((dest[LICE_PIXEL_R]-r)*sc)/256, - g + ((dest[LICE_PIXEL_G]-g)*sc)/256, - b + ((dest[LICE_PIXEL_B]-b)*sc)/256, - a + dest[LICE_PIXEL_A]); - } - } - } -}; - -#ifndef LICE_DISABLE_BLEND_ADD - -class _LICE_CombinePixelsAdd -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) - - _LICE_MakePixelClamp(dest, - dest[LICE_PIXEL_R]+(r*alpha)/256, - dest[LICE_PIXEL_G]+(g*alpha)/256, - dest[LICE_PIXEL_B]+(b*alpha)/256, - dest[LICE_PIXEL_A]+(a*alpha)/256); - - } -}; -class _LICE_CombinePixelsAddSourceAlpha -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - alpha=(alpha*(a+1))/256; - _LICE_MakePixelClamp(dest, - dest[LICE_PIXEL_R]+(r*alpha)/256, - dest[LICE_PIXEL_G]+(g*alpha)/256, - dest[LICE_PIXEL_B]+(b*alpha)/256, - dest[LICE_PIXEL_A]+(a*alpha)/256); - } - } -}; - -#else // !LICE_DISABLE_BLEND_ADD -#define _LICE_CombinePixelsAddSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp -#define _LICE_CombinePixelsAdd _LICE_CombinePixelsCopyClamp -#endif - -#ifndef LICE_DISABLE_BLEND_DODGE - -class _LICE_CombinePixelsColorDodge -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - int src_r = 256-r*alpha/256; - int src_g = 256-g*alpha/256; - int src_b = 256-b*alpha/256; - int src_a = 256-a*alpha/256; - - _LICE_MakePixelClamp(dest, - src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R], - src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G], - src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B], - src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]); - } -}; - -class _LICE_CombinePixelsColorDodgeSourceAlpha -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - alpha=(alpha*(a+1))/256; - int src_r = 256-r*alpha/256; - int src_g = 256-g*alpha/256; - int src_b = 256-b*alpha/256; - int src_a = 256-a*alpha/256; - - _LICE_MakePixelClamp(dest, - src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R], - src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G], - src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B], - src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]); - } -}; - -#else // !LICE_DISABLE_BLEND_DODGE -#define _LICE_CombinePixelsColorDodgeSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp -#define _LICE_CombinePixelsColorDodge _LICE_CombinePixelsCopyClamp -#endif - - -#ifndef LICE_DISABLE_BLEND_MUL - -class _LICE_CombinePixelsMulNoClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) - - int da=(256-alpha)*256; - _LICE_MakePixelNoClamp(dest, - (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, - (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, - (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, - (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); - - } -}; -class _LICE_CombinePixelsMulClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) - - int da=(256-alpha)*256; - _LICE_MakePixelClamp(dest, - (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, - (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, - (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, - (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); - - } -}; -class _LICE_CombinePixelsMulSourceAlphaNoClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - alpha=(alpha*(a+1))/256; - int da=(256-alpha)*256; - _LICE_MakePixelNoClamp(dest, - (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, - (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, - (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, - (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); - - } - } -}; -class _LICE_CombinePixelsMulSourceAlphaClamp -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - if (a) - { - alpha=(alpha*(a+1))/256; - int da=(256-alpha)*256; - _LICE_MakePixelClamp(dest, - (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, - (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, - (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, - (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); - - } - } -}; - -#else // !LICE_DISABLE_BLEND_MUL -#define _LICE_CombinePixelsMulSourceAlphaNoClamp _LICE_CombinePixelsCopySourceAlphaNoClamp -#define _LICE_CombinePixelsMulSourceAlphaClamp _LICE_CombinePixelsCopySourceAlphaClamp -#define _LICE_CombinePixelsMulNoClamp _LICE_CombinePixelsCopyNoClamp -#define _LICE_CombinePixelsMulClamp _LICE_CombinePixelsCopyClamp -#endif - -//#define LICE_DISABLE_BLEND_OVERLAY -#ifndef LICE_DISABLE_BLEND_OVERLAY - -class _LICE_CombinePixelsOverlay -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) - - int destr = dest[LICE_PIXEL_R], destg = dest[LICE_PIXEL_G], destb = dest[LICE_PIXEL_B], desta = dest[LICE_PIXEL_A]; - -#if 0 - int srcr = r*alpha, srcg = g*alpha, srcb = b*alpha, srca = a*alpha; - int da=(256-alpha)*256; - int mr = (destr*(da+srcr))/65536; - int mg = (destg*(da+srcg))/65536; - int mb = (destb*(da+srcb))/65536; - int ma = (desta*(da+srca))/65536; - int sr = 256-(65536-srcr)*(256-destr)/65536; - int sg = 256-(65536-srcg)*(256-destg)/65536; - int sb = 256-(65536-srcb)*(256-destb)/65536; - int sa = 256-(65536-srca)*(256-desta)/65536; - - destr = (destr*sr+(256-destr)*mr)/256; - destg = (destg*sg+(256-destg)*mg)/256; - destb = (destb*sb+(256-destb)*mb)/256; - desta = (desta*sa+(256-desta)*ma)/256; -#else - // can produce slightly diff (+-1) results from above due to rounding - int da=(256-alpha)*128; - int srcr = r*alpha+da, srcg = g*alpha+da, srcb = b*alpha+da, srca = a*alpha + da; - destr = ( destr*( (destr*(32768-srcr))/256 + srcr ) )/32768; - destg = ( destg*( (destg*(32768-srcg))/256 + srcg ) )/32768; - destb = ( destb*( (destb*(32768-srcb))/256 + srcb ) )/32768; - desta = ( desta*( (desta*(32768-srca))/256 + srca ) )/32768; - -#endif - - _LICE_MakePixelClamp(dest, destr, destg, destb, desta); - } -}; - -class _LICE_CombinePixelsOverlaySourceAlpha -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - _LICE_CombinePixelsOverlay::doPix(dest, r, g, b, a, (alpha*(a+1))/256); - } -}; - -#else // !LICE_DISABLE_BLEND_OVERLAY -#define _LICE_CombinePixelsOverlaySourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp -#define _LICE_CombinePixelsOverlay _LICE_CombinePixelsCopyClamp -#endif - - -//#define LICE_DISABLE_BLEND_HSVADJ -#ifndef LICE_DISABLE_BLEND_HSVADJ - -class _LICE_CombinePixelsHSVAdjust -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - int h,s,v; - __LICE_RGB2HSV(dest[LICE_PIXEL_R],dest[LICE_PIXEL_G],dest[LICE_PIXEL_B],&h,&s,&v); - h+=(((r+r/2) - 192) * alpha)/256; - if (h<0)h+=384; - else if (h>=384) h-=384; - s+=((g-128)*alpha)/128; - if (s&~0xff) - { - if (s<0)s=0; - else s=255; - } - v+=((b-128)*alpha)/128; - if (v&~0xff) - { - if (v<0)v=0; - else v=255; - } - - *(LICE_pixel *)dest = __LICE_HSV2Pix(h,s,v,a); - } -}; - -class _LICE_CombinePixelsHSVAdjustSourceAlpha -{ -public: - static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) - { - _LICE_CombinePixelsHSVAdjust::doPix(dest, r, g, b, a, (alpha*(a+1))/256); - } -}; - -#else // !LICE_DISABLE_BLEND_HSVADJ -#define _LICE_CombinePixelsHSVAdjustSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp -#define _LICE_CombinePixelsHSVAdjust _LICE_CombinePixelsCopyClamp -#endif - -// note: the "clamp" parameter would generally be false, unless you're working with -// input colors that need to be clamped (i.e. if you have a r value of >255 or <0, etc. -// if your input is LICE_pixel only then use false, and it will clamp as needed depending -// on the blend mode.. - -//#define __LICE__ACTION(comb) templateclass::function(parameters) -//__LICE_ACTION_SRCALPHA(mode,alpha,clamp); -//#undef __LICE__ACTION - - -// use this for paths that support LICE_BLIT_USE_ALPHA (source-alpha combining), but -// otherwise have constant alpha -#define __LICE_ACTION_SRCALPHA(mode,ia,clamp) \ - if ((ia)!=0) switch ((mode)&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA)) { \ - case LICE_BLIT_MODE_COPY: if ((ia)>0) { \ - if (clamp) { \ - if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } \ - else { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } \ - } else { \ - if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } \ - else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } \ - } \ - } \ - break; \ - case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ - case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ - case LICE_BLIT_MODE_MUL: \ - if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } \ - else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } \ - break; \ - case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ - case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ - case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA: \ - if (clamp) { \ - if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmClamp);} \ - else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaClamp); } \ - } else { \ - if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmNoClamp); } \ - else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaNoClamp); } \ - } \ - break; \ - case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA: \ - __LICE__ACTION(_LICE_CombinePixelsAddSourceAlpha); \ - break; \ - case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA: \ - __LICE__ACTION(_LICE_CombinePixelsColorDodgeSourceAlpha); \ - break; \ - case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA: \ - if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaClamp); } \ - else { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaNoClamp); } \ - break; \ - case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA: \ - __LICE__ACTION(_LICE_CombinePixelsOverlaySourceAlpha); \ - break; \ - case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA: \ - __LICE__ACTION(_LICE_CombinePixelsHSVAdjustSourceAlpha); \ - break; \ - } - - -// use this for paths that can have per pixel alpha, but calculate it themselves -#define __LICE_ACTION_NOSRCALPHA(mode, ia,clamp) \ - if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \ - case LICE_BLIT_MODE_COPY: if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } break; \ - case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ - case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ - case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \ - case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ - case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ - } - -// For drawing where there is constant alpha and no per-pixel alpha. -#define __LICE_ACTION_CONSTANTALPHA(mode,ia,clamp) \ - if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \ - case LICE_BLIT_MODE_COPY: \ - if ((ia)==256) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } else { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } } \ - else if ((ia)==128) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsHalfMixClamp); } else { __LICE__ACTION(_LICE_CombinePixelsHalfMixNoClamp); } } \ - else if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } \ - break; \ - case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ - case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ - case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \ - case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ - case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ - } - -typedef void (*LICE_COMBINEFUNC)(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha); - -#endif // _LICE_COMBINE_H_ diff --git a/WDL/lice/lice_extended.h b/WDL/lice/lice_extended.h deleted file mode 100644 index fb7ff937..00000000 --- a/WDL/lice/lice_extended.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef _LICE_EXTENDED_ -#define _LICE_EXTENDED_ - -#include "lice.h" - -#define DISABLE_LICE_EXTENSIONS - -// stuff to pass to LICE_IBitmap::Extended - -enum // IDs -{ - LICE_EXT_SUPPORTS_ID, // data = ID, returns 1 if that extension ID is supported - LICE_EXT_CLEAR_ACCEL, - LICE_EXT_LINE_ACCEL, - LICE_EXT_FILLRECT_ACCEL, - LICE_EXT_DRAWCBEZIER_ACCEL, - LICE_EXT_DRAWGLYPH_ACCEL, - LICE_EXT_BLIT_ACCEL, - LICE_EXT_SCALEDBLIT_ACCEL, - LICE_EXT_GETFBOTEX_ACCEL, // if the bitmap is implemented as an openGL framebuffer object, get its texture backing store - LICE_EXT_DASHEDLINE_ACCEL, - LICE_EXT_GETPIXEL_ACCEL, - LICE_EXT_PUTPIXEL_ACCEL, - LICE_EXT_SETCLIP, // data == 0 to clear clip - LICE_EXT_WINDOW_BLIT, - LICE_EXT_FORGET, // optimizations can sometimes happen if a bitmap can be told it doesn't need to retain data after it's accessed - LICE_EXT_DRAWTRIANGLE_ACCEL, -}; - -struct LICE_Ext_Line_acceldata -{ - float x1, y1, x2, y2; - LICE_pixel color; - float alpha; - int mode; - bool aa; - - LICE_Ext_Line_acceldata(float _x1, float _y1, float _x2, float _y2, LICE_pixel _color, float _alpha, int _mode, bool _aa) - : x1(_x1), y1(_y1), x2(_x2), y2(_y2), color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} -}; - -struct LICE_Ext_FillRect_acceldata -{ - int x, y, w, h; - LICE_pixel color; - float alpha; - int mode; - - LICE_Ext_FillRect_acceldata(int _x, int _y, int _w, int _h, LICE_pixel _color, float _alpha, int _mode) - : x(_x), y(_y), w(_w), h(_h), color(_color), alpha(_alpha), mode(_mode) {} -}; - -struct LICE_Ext_DrawCBezier_acceldata -{ - float xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend; - LICE_pixel color; - float alpha; - int mode; - bool aa; - - LICE_Ext_DrawCBezier_acceldata(float _xstart, float _ystart, float _xctl1, float _yctl1, float _xctl2, float _yctl2, float _xend, float _yend, - LICE_pixel _color, float _alpha, int _mode, bool _aa) - : xstart(_xstart), ystart(_ystart), xctl1(_xctl1), yctl1(_yctl1), xctl2(_xctl2), yctl2(_yctl2), xend(_xend), yend(_yend), - color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} -}; - -struct LICE_Ext_DrawGlyph_acceldata -{ - int x; - int y; - LICE_pixel color; - const LICE_pixel_chan* alphas; - int glyph_w, glyph_h; - float alpha; - int mode; - - LICE_Ext_DrawGlyph_acceldata(int _x, int _y, LICE_pixel _color, LICE_pixel_chan* _alphas, int _glyph_w, int _glyph_h, float _alpha, int _mode) - : x(_x), y(_y), color(_color), alphas(_alphas), glyph_w(_glyph_w), glyph_h(_glyph_h), alpha(_alpha), mode(_mode) {} -}; - -struct LICE_Ext_Blit_acceldata -{ - LICE_IBitmap* src; - int dstx, dsty, srcx, srcy, srcw, srch; - float alpha; - int mode; - - LICE_Ext_Blit_acceldata(LICE_IBitmap* _src, int _dstx, int _dsty, int _srcx, int _srcy, int _srcw, int _srch, float _alpha, int _mode) - : src(_src), dstx(_dstx), dsty(_dsty), srcx(_srcx), srcy(_srcy), srcw(_srcw), srch(_srch), alpha(_alpha), mode(_mode) {} -}; - -struct LICE_Ext_ScaledBlit_acceldata -{ - LICE_IBitmap* src; - int dstx, dsty, dstw, dsth; - float srcx, srcy, srcw, srch; - float alpha; - int mode; - - LICE_Ext_ScaledBlit_acceldata(LICE_IBitmap* _src, int _dstx, int _dsty, int _dstw, int _dsth, float _srcx, float _srcy, float _srcw, float _srch, float _alpha, int _mode) - : src(_src), dstx(_dstx), dsty(_dsty), dstw(_dstw), dsth(_dsth), srcx(_srcx), srcy(_srcy), srcw(_srcw), srch(_srch), alpha(_alpha), mode(_mode) {} -}; - -struct LICE_Ext_DashedLine_acceldata -{ - float x1, y1, x2, y2; - int pxon, pxoff; - LICE_pixel color; - float alpha; - int mode; - bool aa; - - LICE_Ext_DashedLine_acceldata(float _x1, float _y1, float _x2, float _y2, int _pxon, int _pxoff, LICE_pixel _color, float _alpha, int _mode, bool _aa) - : x1(_x1), y1(_y1), x2(_x2), y2(_y2), pxon(_pxon), pxoff(_pxoff), color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} -}; - -struct LICE_Ext_GetPixel_acceldata -{ - int x, y; - LICE_pixel px; // return - - LICE_Ext_GetPixel_acceldata(int _x, int _y) - : x(_x), y(_y), px(0) {} -}; - -struct LICE_Ext_PutPixel_acceldata -{ - int x, y; - LICE_pixel color; - float alpha; - int mode; - - LICE_Ext_PutPixel_acceldata(int _x, int _y, LICE_pixel _color, float _alpha, int _mode) - : x(_x), y(_y), color(_color), alpha(_alpha), mode(_mode) {} -}; - -struct LICE_Ext_SetClip_data -{ - int x, y, w, h; - - LICE_Ext_SetClip_data(int _x, int _y, int _w, int _h) - : x(_x), y(_y), w(_w), h(_h) {} -}; - -class pl_Mat; - -struct LICE_Ext_DrawTriangle_acceldata -{ - pl_Mat *mat; // will need to include plush.h to access this - double VertexShades[3][3]; // for solid element - float scrx[3], scry[3], scrz[3]; // scrz = 1/Zdist - double mapping_coords[2][3][2]; // [texture or texture2][vertex][uv] -}; - -struct LICE_Ext_WindowBlit_data -{ - HWND hwnd; - int destx, desty, srcx, srcy, w, h; - - LICE_Ext_WindowBlit_data(HWND _hwnd, int _destx, int _desty, int _srcx, int _srcy, int _w, int _h) - : hwnd(_hwnd), destx(_destx), desty(_desty), srcx(_srcx), srcy(_srcy), w(_w), h(_h) {} -}; - -#endif diff --git a/WDL/lice/lice_gif.cpp b/WDL/lice/lice_gif.cpp deleted file mode 100644 index b68ea0cf..00000000 --- a/WDL/lice/lice_gif.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_gif.cpp (GIF loading for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" - -extern "C" { - -#include "../giflib/gif_lib.h" -int _GifError; -}; - - -LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp, int *nframes) -{ - GifFileType *fp=DGifOpenFileName(filename); - if (!fp) - return 0; - - - GifRecordType RecordType; - GifByteType *Extension; - int ExtCode; - do - { - if (DGifGetRecordType(fp, &RecordType) == GIF_ERROR) - { - DGifCloseFile(fp); - return 0; - } - switch (RecordType) - { - case IMAGE_DESC_RECORD_TYPE: - if (DGifGetImageDesc(fp) == GIF_ERROR) - { - DGifCloseFile(fp); - return 0; - } - - // todo: support transparency - // todo: have it buffer all frames and output frame count - if (nframes) *nframes=1; // placeholder - - { - int width=fp->Image.Width,height=fp->Image.Height; - if (bmp) - { - bmp->resize(width,height); - if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) - { - DGifCloseFile(fp); - return 0; - } - } - else bmp=new LICE_MemBitmap(width,height); - - LICE_pixel *bmpptr = bmp->getBits(); - int dbmpptr=bmp->getRowSpan(); - if (bmp->isFlipped()) - { - bmpptr += dbmpptr*(bmp->getHeight()-1); - dbmpptr=-dbmpptr; - } - GifPixelType *linebuf=(GifPixelType*)malloc(width*sizeof(GifPixelType)); - int y; - int cmap[256]; - for (y=0;y<256;y++) - { - if (fp->SColorMap&&ySColorMap->ColorCount&&fp->SColorMap->Colors) - { - GifColorType *ct=fp->SColorMap->Colors+y; - cmap[y]=LICE_RGBA(ct->Red,ct->Green,ct->Blue,255); - } - else cmap[y]=0; - } - - for (y=0; y < height; y ++) - { - if (DGifGetLine(fp,linebuf,width)==GIF_ERROR) break; - - int x; - for (x = 0; x < width; x ++) - { - bmpptr[x]=cmap[linebuf[x]&0xff]; - } - bmpptr += dbmpptr; - } - - - - free(linebuf); - DGifCloseFile(fp); - return bmp; - } - break; - case EXTENSION_RECORD_TYPE: - if (DGifGetExtension(fp, &ExtCode, &Extension) == GIF_ERROR) - { - DGifCloseFile(fp); - return 0; - } - while (Extension != NULL) - { - if (DGifGetExtensionNext(fp, &Extension) == GIF_ERROR) - { - DGifCloseFile(fp); - return 0; - } - } - break; - case TERMINATE_RECORD_TYPE: - break; - default: /* Should be traps by DGifGetRecordType. */ - break; - } - } - while (RecordType != TERMINATE_RECORD_TYPE); - - DGifCloseFile(fp); - return 0; - -} - - - -class LICE_GIFLoader -{ -public: - _LICE_ImageLoader_rec rec; - LICE_GIFLoader() - { - rec.loadfunc = loadfunc; - rec.get_extlist = get_extlist; - rec._next = LICE_ImageLoader_list; - LICE_ImageLoader_list = &rec; - } - - static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) - { - if (checkFileName) - { - const char *p=filename; - while (*p)p++; - while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".gif")) return 0; - } - return LICE_LoadGIF(filename,bmpbase,NULL); - } - static const char *get_extlist() - { - return "GIF files (*.GIF)\0*.GIF\0"; - } - -}; - -LICE_GIFLoader LICE_gifldr; \ No newline at end of file diff --git a/WDL/lice/lice_gif_write.cpp b/WDL/lice/lice_gif_write.cpp deleted file mode 100644 index d9eceb36..00000000 --- a/WDL/lice/lice_gif_write.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_gif.cpp (GIF loading for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" - -extern "C" { - -#include "../giflib/gif_lib.h" -//int _GifError; -}; - - -struct liceGifWriteRec -{ - GifFileType *f; - ColorMapObject *cmap; - unsigned char from15to8bit[32][32][32];//r,g,b - GifPixelType *linebuf; - int transalpha; - int w,h; - bool dither; - bool has_had_frame; - bool has_global_cmap; - LICE_IBitmap *prevframe; // used when multiframe, transalpha<0 -}; - -static inline GifPixelType QuantPixel(LICE_pixel p, liceGifWriteRec *wr) -{ - return wr->from15to8bit[LICE_GETR(p)>>3][LICE_GETG(p)>>3][LICE_GETB(p)>>3]; -} - - -int LICE_SetGIFColorMapFromOctree(void *ww, void *octree, int numcolors) -{ - liceGifWriteRec *wr = (liceGifWriteRec *)ww; - if (!octree||!ww) return 0; - - ColorMapObject *cmap = wr->cmap; - - int palette_sz=0; - - // store palette - { - LICE_pixel* palette=0; - LICE_pixel tpalette[256]; - if (numcolors <= 256) palette = tpalette; - else palette = (LICE_pixel*)malloc(numcolors*sizeof(LICE_pixel)); - - palette_sz = LICE_ExtractOctreePalette(octree, palette); - - int i; - for (i = 0; i < palette_sz; ++i) - { - cmap->Colors[i].Red = LICE_GETR(palette[i]); - cmap->Colors[i].Green = LICE_GETG(palette[i]); - cmap->Colors[i].Blue = LICE_GETB(palette[i]); - } - for (i = palette_sz; i < numcolors; ++i) - { - cmap->Colors[i].Red = cmap->Colors[i].Green = cmap->Colors[i].Blue = 0; - } - - if (palette != tpalette) free(palette); - } - - // map palette to 16 bit - GifColorType *ct = cmap->Colors; - unsigned char r,g,b; - for(r=0;r<32;r++) - { - unsigned char cr = r<<3; - for (g=0;g<32;g++) - { - unsigned char cg = g<<3; - for (b=0;b<32;b++) - { - unsigned char cb = b<<3; - LICE_pixel col = LICE_RGBA(cr,cg,cb,0); - wr->from15to8bit[r][g][b] = LICE_FindInOctree(octree, col); - } - } - } - - wr->has_global_cmap=true; - - return palette_sz; -} - - -bool LICE_WriteGIFFrame(void *handle, LICE_IBitmap *frame, int xpos, int ypos, bool perImageColorMap, int frame_delay, int nreps) -{ - liceGifWriteRec *wr = (liceGifWriteRec*)handle; - if (!wr) return false; - - bool isFirst=false; - if (!wr->has_had_frame) - { - wr->has_had_frame=true; - isFirst=true; - - if (!perImageColorMap && !wr->has_global_cmap) - { - int ccnt = wr->cmap->ColorCount; - if (wr->transalpha && ccnt>255) ccnt=255; - void* octree = LICE_CreateOctree(ccnt); - if (octree) - { - LICE_BuildOctree(octree, frame); - // sets has_global_cmap - LICE_SetGIFColorMapFromOctree(wr, octree, ccnt); - LICE_DestroyOctree(octree); - } - } - - EGifPutScreenDesc(wr->f,wr->w,wr->h,8,0,wr->has_global_cmap ? wr->cmap : 0); - - } - - int usew=frame->getWidth(), useh=frame->getHeight(); - if (xpos+usew > wr->w) usew = wr->w-xpos; - if (ypos+useh > wr->h) useh = wr->h-ypos; - if (usew<1||useh<1) return false; - - unsigned char gce[4] = { 0, }; - if (wr->transalpha) - { - gce[0] |= 1; - gce[3] = 255; - } - - int a = frame_delay/10; - if(a<1&&frame_delay)a=1; - else if (a>60000) a=60000; - gce[1]=(a)&255; - gce[2]=(a)>>8; - - if (isFirst && frame_delay && nreps!=1) - { - int nr = nreps > 1 && nreps <= 65536 ? nreps-1 : 0; - unsigned char ext[]={0xB, 'N','E','T','S','C','A','P','E','2','.','0',3,1,(nr&0xff),(nr>>8)&0xff}; - EGifPutExtension(wr->f,0xFF, sizeof(ext),ext); - } - - if (gce[0]||gce[1]||gce[2]) - EGifPutExtension(wr->f, 0xF9, sizeof(gce), gce); - - - if (perImageColorMap && !wr->has_global_cmap) - { - int ccnt = wr->cmap->ColorCount; - if (wr->transalpha && ccnt>255) ccnt=255; - void* octree = LICE_CreateOctree(ccnt); - if (octree) - { - LICE_BuildOctree(octree, frame); - // sets has_global_cmap (clear below) - LICE_SetGIFColorMapFromOctree(wr, octree, ccnt); - LICE_DestroyOctree(octree); - wr->has_global_cmap=false; - } - } - - EGifPutImageDesc(wr->f, xpos, ypos, usew,useh, 0, wr->has_global_cmap ? NULL : wr->cmap); - - GifPixelType *linebuf = wr->linebuf; - int y; - int ta=wr->transalpha>0; - - if ((!isFirst || frame_delay) && wr->transalpha<0) - { - bool ignFr=false; - if (!wr->prevframe) - { - ignFr=true; - wr->prevframe = new LICE_MemBitmap(wr->w,wr->h); - LICE_Clear(wr->prevframe,0); - } - - LICE_SubBitmap tmp(wr->prevframe,xpos,ypos,usew,useh); - - for(y=0;yisFlipped()) rdy = frame->getHeight()-1-y; - if (tmp.isFlipped()) rdy2 = tmp.getHeight()-1-y; - LICE_pixel *in = frame->getBits() + rdy*frame->getRowSpan(); - LICE_pixel *in2 = tmp.getBits() + rdy2*tmp.getRowSpan(); - int x; - for(x=0;xf, linebuf, usew); - } - - - LICE_Blit(&tmp,frame,0,0,0,0,usew,useh,1.0f,LICE_BLIT_MODE_COPY); - - } - else for(y=0;yisFlipped()) rdy = frame->getHeight()-1-y; - LICE_pixel *in = frame->getBits() + rdy*frame->getRowSpan(); - int x; - for(x=0;xf, linebuf, usew); - } - - return true; -} - -void *LICE_WriteGIFBeginNoFrame(const char *filename, int w, int h, int transparent_alpha, bool dither) -{ - - EGifSetGifVersion("89a"); - - GifFileType *f = EGifOpenFileName(filename,0); - if (!f) return NULL; - - liceGifWriteRec *wr = (liceGifWriteRec*)calloc(sizeof(liceGifWriteRec),1); - wr->f = f; - wr->dither = dither; - wr->w=w; - wr->h=h; - wr->cmap = (ColorMapObject*)calloc(sizeof(ColorMapObject)+256*sizeof(GifColorType),1); - wr->cmap->Colors = (GifColorType*)(wr->cmap+1); - wr->cmap->ColorCount=256; - wr->cmap->BitsPerPixel=8; - wr->has_had_frame=false; - wr->has_global_cmap=false; - - wr->linebuf = (GifPixelType*)malloc(wr->w*sizeof(GifPixelType)); - wr->transalpha = transparent_alpha; - - return wr; -} -void *LICE_WriteGIFBegin(const char *filename, LICE_IBitmap *firstframe, int transparent_alpha, int frame_delay, bool dither, int nreps) -{ - if (!firstframe) return NULL; - - void *wr=LICE_WriteGIFBeginNoFrame(filename,firstframe->getWidth(),firstframe->getHeight(),transparent_alpha,dither); - if (wr) LICE_WriteGIFFrame(wr,firstframe,0,0,true,frame_delay,nreps); - - return wr; -} - - - -bool LICE_WriteGIFEnd(void *handle) -{ - liceGifWriteRec *wr = (liceGifWriteRec*)handle; - if (!wr) return false; - - int ret = EGifCloseFile(wr->f); - - free(wr->linebuf); - free(wr->cmap); - - delete wr->prevframe; - - free(wr); - - return ret!=GIF_ERROR; -} - - -bool LICE_WriteGIF(const char *filename, LICE_IBitmap *bmp, int transparent_alpha, bool dither) -{ - // todo: alpha? - if (!bmp) return false; - - int has_transparent = 0; - if (transparent_alpha>0) - { - int y=bmp->getHeight(); - LICE_pixel *p = bmp->getBits(); - int w = bmp->getWidth(); - while (y--&&!has_transparent) - { - int x=w; - while(x--) - { - if (LICE_GETA(*p) < transparent_alpha) - { - has_transparent=1; - break; - } - p++; - } - p+=bmp->getRowSpan()-w; - } - } - - - void *wr=LICE_WriteGIFBeginNoFrame(filename,bmp->getWidth(),bmp->getHeight(),has_transparent?transparent_alpha:0,dither); - if (!wr) return false; - - LICE_WriteGIFFrame(wr,bmp,0,0,false,0); - - return LICE_WriteGIFEnd(wr); -} diff --git a/WDL/lice/lice_gl_ctx.cpp b/WDL/lice/lice_gl_ctx.cpp deleted file mode 100644 index 1a91f5f6..00000000 --- a/WDL/lice/lice_gl_ctx.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "lice_gl_ctx.h" - -#define MAX_CACHED_GLYPHS 4096 - -// create one hidden window per process to hold the openGL state, -// its GL render context stays current for the life of the process, -// we serve all framebuffers from the same render context - -class LICE_GL_ctx -{ -public: - - LICE_GL_ctx(); - ~LICE_GL_ctx(); - - bool IsValid(); - HWND GetWindow() { return m_hwnd; } - void Close(); - - GLUnurbsObj* GetNurbsObj(int linetol=8); // linetol = maximum number of straight-line pixels - - int GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h); - void ClearTex(); - - struct GlyphCache - { - unsigned int tex; - unsigned char* glyph; // lives on the heap - int glyph_w, glyph_h; - }; - -private: - - bool Init(); - - bool m_init_tried; - HINSTANCE m_gldll; - HWND m_hwnd; - HGLRC m_glrc; - - GLUnurbsObj* m_nurbs; // keep this here for easy reuse - - GlyphCache m_glyphCache[MAX_CACHED_GLYPHS]; - int m_nCachedGlyphs; -}; - -LICE_GL_ctx::LICE_GL_ctx() -{ - m_init_tried = false; - m_gldll = 0; - m_hwnd = 0; - m_glrc = 0; - m_nurbs = 0; - memset(m_glyphCache, 0, MAX_CACHED_GLYPHS*sizeof(GlyphCache)); - m_nCachedGlyphs = 0; -} - -LICE_GL_ctx::~LICE_GL_ctx() -{ - Close(); -} - -bool LICE_GL_ctx::Init() -{ - m_init_tried = true; - - m_gldll = LoadLibrary("opengl32.dll"); - if (!m_gldll) - { - Close(); - return false; - } - - // create a minimal GL render context to serve FBOs out of - WNDCLASS wc; - memset(&wc, 0, sizeof(WNDCLASS)); - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = DefWindowProc; - wc.lpszClassName = "LICE_GL_ctx"; - RegisterClass(&wc); - m_hwnd = CreateWindow("LICE_GL_ctx", "LICE_GL_ctx", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); - HDC dc = GetDC(m_hwnd); - if (!dc) - { - Close(); - return false; - } - - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cAlphaBits = 8; - int pxfmt = ChoosePixelFormat(dc, &pfd); - if (!SetPixelFormat(dc, pxfmt, &pfd)) - { - Close(); - return false; - } - - m_glrc = wglCreateContext(dc); - if (!wglMakeCurrent(dc, m_glrc)) // render context should stay current throughout - { - Close(); - return false; - } - - char *rendstr = (char*) glGetString(GL_RENDERER); - if (!rendstr || strstr(rendstr, "GDI")) - { - Close(); - return false; - } - - // check now for all the extension functions we will ever need - if (glewInit() != GLEW_OK || - !glewIsSupported("GL_EXT_framebuffer_object") || - !glewIsSupported("GL_ARB_texture_rectangle")) - { - Close(); - return false; - } - - // any one-time initialization goes here - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - ReleaseDC(m_hwnd, dc); - - return true; -} - -bool LICE_GL_ctx::IsValid() -{ - if (m_gldll && m_glrc) return true; - if (!m_init_tried) return Init(); - return false; -} - -void LICE_GL_ctx::Close() -{ - ClearTex(); - if (m_nurbs) - { - gluDeleteNurbsRenderer(m_nurbs); - m_nurbs = 0; - } - if (m_glrc) - { - wglMakeCurrent(0, 0); - wglDeleteContext(m_glrc); - m_glrc = 0; - } - if (m_hwnd) - { - DestroyWindow(m_hwnd); - m_hwnd = 0; - } - if (m_gldll) - { - FreeLibrary(m_gldll); - m_gldll = 0; - } -} - -GLUnurbsObj* LICE_GL_ctx::GetNurbsObj(int linetol) -{ - if (!IsValid()) return 0; - if (!m_nurbs) m_nurbs = gluNewNurbsRenderer(); - if (m_nurbs) gluNurbsProperty(m_nurbs, GLU_SAMPLING_TOLERANCE, (float)linetol); - return m_nurbs; -} - -void LICE_GL_ctx::ClearTex() -{ - int i; - for (i = 0; i < m_nCachedGlyphs; ++i) - { - glDeleteTextures(1, &m_glyphCache[i].tex); - free(m_glyphCache[i].glyph); - memset(&m_glyphCache[i], 0, sizeof(GlyphCache)); - } - m_nCachedGlyphs = 0; -} - -static int _glyphcmp(const void* p1, const void* p2) -{ - LICE_GL_ctx::GlyphCache* gc1 = (LICE_GL_ctx::GlyphCache*) p1; - LICE_GL_ctx::GlyphCache* gc2 = (LICE_GL_ctx::GlyphCache*) p2; - - if (gc1->glyph_w < gc2->glyph_w) return -1; - if (gc1->glyph_w > gc2->glyph_w) return 1; - if (gc1->glyph_h < gc2->glyph_h) return -1; - if (gc1->glyph_h > gc2->glyph_h) return 1; - return memcmp(gc1->glyph, gc2->glyph, gc1->glyph_w*gc1->glyph_h); -} - -int LICE_GL_ctx::GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h) -{ - if (!IsValid()) return false; - - GlyphCache gc; - gc.tex = 0; - gc.glyph = (unsigned char *)glyph; - gc.glyph_w = glyph_w; - gc.glyph_h = glyph_h; - - GlyphCache* p = (GlyphCache*) bsearch(&gc, m_glyphCache, m_nCachedGlyphs, sizeof(GlyphCache), _glyphcmp); - if (p) return p->tex; - - glGenTextures(1, &gc.tex); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, gc.tex); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA8, glyph_w, glyph_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, glyph); - - if (m_nCachedGlyphs >= MAX_CACHED_GLYPHS) ClearTex(); // quick & dirty - - gc.glyph = (unsigned char*) malloc(glyph_w*glyph_h); - memcpy(gc.glyph, glyph, glyph_w*glyph_h); - m_glyphCache[m_nCachedGlyphs++] = gc; // copy - qsort(m_glyphCache, m_nCachedGlyphs, sizeof(GlyphCache), _glyphcmp); - - return gc.tex; -} - -//////// - -static LICE_GL_ctx s_glctx; // one static opengl context object per process - - -bool LICE_GL_IsValid() -{ - return s_glctx.IsValid(); -} - -HWND LICE_GL_GetWindow() -{ - if (s_glctx.IsValid()) return s_glctx.GetWindow(); - return 0; -} - -void LICE_GL_CloseCtx() -{ - s_glctx.Close(); -} - -GLUnurbsObj* LICE_GL_GetNurbsObj(int linetol) // linetol = maximum number of straight-line pixels -{ - return s_glctx.GetNurbsObj(linetol); -} - -GLuint LICE_GL_GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h) -{ - return s_glctx.GetTexFromGlyph(glyph, glyph_w, glyph_h); -} - -void LICE_GL_ClearTex() -{ - s_glctx.ClearTex(); -} - diff --git a/WDL/lice/lice_gl_ctx.h b/WDL/lice/lice_gl_ctx.h deleted file mode 100644 index 26ec4292..00000000 --- a/WDL/lice/lice_gl_ctx.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _GL_CTX_ -#define _GL_CTX_ - -#include "lice.h" - -#define GLEW_STATIC -#include "glew/include/gl/glew.h" -#include "glew/include/gl/wglew.h" -#include "glew/include/gl/wglext.h" - -// GL context functions -// opening and managing GL context is handled behind the scenes - - -bool LICE_GL_IsValid(); // GL context is initialized (will be lazy initialized on first call) and valid - -HWND LICE_GL_GetWindow(); // Get the window that owns the GL context (one per process) - -void LICE_GL_CloseCtx(); // Something failed, turn off GL context forever so we don't keep failing - -GLUnurbsObj* LICE_GL_GetNurbsObj(int linetol=8); // linetol = maximum number of straight-line pixels - -// facility for associating a glyph with a texture -GLuint LICE_GL_GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h); -void LICE_GL_ClearTex(); - -#endif diff --git a/WDL/lice/lice_glbitmap.cpp b/WDL/lice/lice_glbitmap.cpp deleted file mode 100644 index 31a59a4b..00000000 --- a/WDL/lice/lice_glbitmap.cpp +++ /dev/null @@ -1,708 +0,0 @@ -#include "lice_glbitmap.h" -#include "lice_gl_ctx.h" - -#include "../plush2/plush.h" - -LICE_GLBitmap::LICE_GLBitmap() -{ - m_bmp = 0; - m_fbo = 0; - m_tex = 0; - m_bufloc = EMPTY; -} - -// This is separate from the constructor for initialization order reasons -void LICE_GLBitmap::Init(LICE_IBitmap* bmp, int w, int h) -{ - m_bmp = bmp; - if (w > 0 && h > 0) CreateFBO(w, h); -} - -bool LICE_GLBitmap::CreateFBO(int w, int h) -{ - if (LICE_GL_IsValid()) - { - if (m_fbo) ReleaseFBO(); - glGenFramebuffersEXT(1, &m_fbo); // create a new empty FBO - if (m_fbo) - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // bind this FBO so it is the rendering target - glEnable(GL_TEXTURE_RECTANGLE_ARB); // enable texturing - glGenTextures(1, &m_tex); // create a new texture to be the backing store - if (m_tex) - { - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); // bind this texture so it is the texturing target - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // we won't be scaling it for this purpose - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_tex, 0); // attach the texture as the backing store for the FBO - } - glDisable(GL_TEXTURE_RECTANGLE_ARB); // done texturing - } - - return BindFBO(); // this tests the FBO for validity - } - return false; -} - -LICE_GL_SysBitmap::LICE_GL_SysBitmap(int w, int h) -: m_sysbmp(w, h) -{ - Init(&m_sysbmp, w, h); -} - -LICE_GL_MemBitmap::LICE_GL_MemBitmap(int w, int h) -: m_membmp(w, h) -{ - Init(&m_membmp, w, h); -} - -HDC LICE_GL_SysBitmap::getDC() -{ - // no known way to get a DC directly from an offscreen openGL render context, sadly - FramebufferFromGPU(); - OutputDebugString("GL to screen"); - return m_sysbmp.getDC(); -} - - -LICE_GL_SubBitmap::LICE_GL_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h) -{ - m_parent = parent; - m_x = x; - m_y = y; - m_w = w; - m_h = h; -} - -LICE_pixel* LICE_GL_SubBitmap::getBits() -{ - if (!m_parent) return 0; - return m_parent->getBits()+m_y*m_parent->getRowSpan()+m_x; -} - -bool LICE_GL_SubBitmap::resize(int w, int h) -{ - if (w == m_w && h == m_h) return false; - m_w = w; - m_h = h; - return true; -} - -INT_PTR LICE_GL_SubBitmap::Extended(int id, void* data) -{ - if (!m_parent) return 0; - - if (id == LICE_EXT_SUPPORTS_ID) return m_parent->Extended(id, data); - - LICE_Ext_SetClip_data clipdata(m_x, m_y, m_w, m_h); - if (!m_parent->Extended(LICE_EXT_SETCLIP, &clipdata)) return 0; - INT_PTR ret = m_parent->Extended(id, data); - m_parent->Extended(LICE_EXT_SETCLIP, 0); - - return ret; -} - -bool LICE_GLBitmap::SetClip_ext(LICE_Ext_SetClip_data* p) -{ - if (!FramebufferToGPU()) return false; - - if (p) - { - GLdouble c0[4] = { 1.0, 0.0, 0.0, -p->x }; - GLdouble c1[4] = { -1.0, 0.0, 0.0, p->x+p->w }; - GLdouble c2[4] = { 0.0, 1.0, 0.0, -p->y}; - GLdouble c3[4] = { 0.0, -1.0, 0.0, p->y+p->h }; - glClipPlane(GL_CLIP_PLANE0, c0); - glClipPlane(GL_CLIP_PLANE1, c1); - glClipPlane(GL_CLIP_PLANE2, c2); - glClipPlane(GL_CLIP_PLANE3, c3); - glEnable(GL_CLIP_PLANE0); - glEnable(GL_CLIP_PLANE1); - glEnable(GL_CLIP_PLANE2); - glEnable(GL_CLIP_PLANE3); - } - else - { - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - } - - return true; -} - -LICE_GLBitmap::~LICE_GLBitmap() -{ - ReleaseFBO(); -} - -int LICE_GLBitmap::getWidth() -{ - return m_bmp->getWidth(); -} - -int LICE_GLBitmap::getHeight() -{ - return m_bmp->getHeight(); -} - -int LICE_GLBitmap::getRowSpan() -{ - return m_bmp->getRowSpan(); -} - -LICE_pixel* LICE_GLBitmap::getBits() -{ - FramebufferFromGPU(); - return m_bmp->getBits(); -} - -bool LICE_GLBitmap::resize(int w, int h) -{ - int oldw = getWidth(); - int oldh = getHeight(); - if (w == oldw && h == oldh) return false; - - if (oldw == 0 && oldh == 0 && w > 0 && h > 0) - { - m_bmp->resize(w, h); - CreateFBO(w, h); - return true; - } - - if (!m_fbo || !m_tex) return m_bmp->resize(w, h); - - OutputDebugString("GL resizing"); - - // the framebuffer/GPU transfer overhead is per-call, so it's important to be able - // to move the entire bitmap back and forth in one call, which means keeping m_sysbmp width == rowspan - - int oldloc = m_bufloc; - - FramebufferFromGPU(); // copy out the GPU data (this binds the FBO so it is the rendering target) - - glEnable(GL_TEXTURE_RECTANGLE_ARB); // enable texturing - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); // bind this texture so it is the texturing target - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // we won't be scaling it for this purpose - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_tex, 0); // attach the texture as the backing store for the FBO - glDisable(GL_TEXTURE_RECTANGLE_ARB); // done texturing - - if (!BindFBO()) return m_bmp->resize(w, h); // this tests the FBO for validity - - static LICE_MemBitmap tmpbmp; - tmpbmp.resize(w, h); - LICE_Blit(&tmpbmp, m_bmp, 0, 0, 0, 0, oldw, oldh, 1.0f, LICE_BLIT_MODE_COPY); - m_bmp->resize(0, 0); // force it to resize down - LICE_Copy(m_bmp, &tmpbmp); - - if (oldloc == EMPTY) m_bufloc = EMPTY; // else bufloc remains INMEM - - return true; -} - -bool LICE_GLBitmap::BindFBO() -{ - bool valid = false; - if (m_fbo) - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // bind this FBO so it is the rendering target - valid = (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); - if (valid) - { - int w = getWidth(); - int h = getHeight(); - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, w, 0.0, h); - } - else - { - ReleaseFBO(); - LICE_GL_CloseCtx(); // if we fail once we're done with GL - } - } - return valid; -} - -void LICE_GLBitmap::ReleaseFBO() -{ - if (m_fbo) - { - glDeleteFramebuffersEXT(1, &m_fbo); - m_fbo = 0; - } - if (m_tex) - { - glDeleteTextures(1, &m_tex); - m_tex = 0; - } -} - -bool LICE_GLBitmap::FramebufferToGPU() -{ - if (BindFBO()) - { - if (m_bufloc == INMEM) - { - OutputDebugString("GL to GPU"); - glDisable(GL_BLEND); - glRasterPos2i(0, 0); - glDrawPixels(getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_bmp->getBits()); - } - m_bufloc = INGPU; - } - return (m_bufloc == INGPU); -} - -void LICE_GLBitmap::FramebufferFromGPU() -{ - if (m_bufloc == INGPU && BindFBO()) - { - OutputDebugString("GL to mem"); - glFinish(); - glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_bmp->getBits()); - } - m_bufloc = INMEM; -} - -INT_PTR LICE_GLBitmap::Extended(int id, void* data) -{ - if (id == LICE_EXT_SUPPORTS_ID) - { - int extid = (int) data; - if (extid == LICE_EXT_LINE_ACCEL) return 1; - if (extid == LICE_EXT_FILLRECT_ACCEL) return 1; - if (extid == LICE_EXT_DRAWCBEZIER_ACCEL) return 1; - if (extid == LICE_EXT_DRAWGLYPH_ACCEL) return 1; - if (extid == LICE_EXT_BLIT_ACCEL) return 1; - if (extid == LICE_EXT_SCALEDBLIT_ACCEL) return 1; - if (extid == LICE_EXT_GETFBOTEX_ACCEL) return 1; - if (extid == LICE_EXT_CLEAR_ACCEL) return 1; - if (extid == LICE_EXT_DASHEDLINE_ACCEL) return 1; - if (extid == LICE_EXT_GETPIXEL_ACCEL) return 1; - if (extid == LICE_EXT_PUTPIXEL_ACCEL) return 1; - if (extid == LICE_EXT_SETCLIP) return 1; - if (extid == LICE_EXT_WINDOW_BLIT) return 1; - if (extid == LICE_EXT_FORGET) return 1; - if (extid == LICE_EXT_DRAWTRIANGLE_ACCEL) return 1; - return 0; - } - - if (id == LICE_EXT_CLEAR_ACCEL) return Clear_accel((LICE_pixel*)data); - if (id == LICE_EXT_LINE_ACCEL) return Line_accel((LICE_Ext_Line_acceldata*)data); - if (id == LICE_EXT_FILLRECT_ACCEL) return FillRect_accel((LICE_Ext_FillRect_acceldata*) data); - if (id == LICE_EXT_DRAWCBEZIER_ACCEL) return DrawCBezier_accel((LICE_Ext_DrawCBezier_acceldata*)data); - if (id == LICE_EXT_DRAWGLYPH_ACCEL) return DrawGlyph_accel((LICE_Ext_DrawGlyph_acceldata*)data); - if (id == LICE_EXT_BLIT_ACCEL) return Blit_accel((LICE_Ext_Blit_acceldata*)data); - if (id == LICE_EXT_SCALEDBLIT_ACCEL) return ScaledBlit_accel((LICE_Ext_ScaledBlit_acceldata*)data); - if (id == LICE_EXT_DASHEDLINE_ACCEL) return DashedLine_accel((LICE_Ext_DashedLine_acceldata*)data); - if (id == LICE_EXT_GETPIXEL_ACCEL) return GetPixel_accel((LICE_Ext_GetPixel_acceldata*)data); - if (id == LICE_EXT_PUTPIXEL_ACCEL) return PutPixel_accel((LICE_Ext_PutPixel_acceldata*)data); - if (id == LICE_EXT_SETCLIP) return SetClip_ext((LICE_Ext_SetClip_data*)data); - if (id == LICE_EXT_DRAWTRIANGLE_ACCEL) return DrawTriangle_accel((LICE_Ext_DrawTriangle_acceldata*)data); - if (id == LICE_EXT_WINDOW_BLIT) return WindowBlit((LICE_Ext_WindowBlit_data*)data); - - if (id == LICE_EXT_FORGET) - { - m_bufloc = EMPTY; - return 1; - } - - if (id == LICE_EXT_GETFBOTEX_ACCEL) - { - if (FramebufferToGPU()) return m_tex; - return 0; - } - - return 0; -} - -static void SetGLAliasing(bool aa) -{ - if (aa) - { - glEnable(GL_LINE_SMOOTH); - } - else - { - glDisable(GL_LINE_SMOOTH); - } -} - -static void SetGLColor(LICE_pixel color, float alpha, int licemode) -{ - int a = 255; - if (licemode&LICE_BLIT_USE_ALPHA) a = LICE_GETA(color); - a = (float)a*alpha; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glColor4ub(LICE_GETB(color), LICE_GETG(color), LICE_GETR(color), a); - //glColor4ub(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), a); -} - -bool LICE_GLBitmap::Clear_accel(LICE_pixel* color) -{ - if (!color) return false; - LICE_pixel col = *color; - - if (!FramebufferToGPU()) return false; - - float r = (float)LICE_GETR(col)/255.0f; - float g = (float)LICE_GETG(col)/255.0f; - float b = (float)LICE_GETB(col)/255.0f; - float a = (float)LICE_GETA(col)/255.0f; - glClearColor(b, g, r, a); - //glClearColor(r, g, b, a); - glClear(GL_COLOR_BUFFER_BIT); - - return true; -} - -bool LICE_GLBitmap::Line_accel(LICE_Ext_Line_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - SetGLColor(p->color, p->alpha, p->mode); - SetGLAliasing(p->aa); - - glBegin(GL_LINES); - - glVertex2f(p->x1, p->y1); - glVertex2f(p->x2, p->y2); - - glEnd(); - - return true; -} - -bool LICE_GLBitmap::DashedLine_accel(LICE_Ext_DashedLine_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - SetGLColor(p->color, p->alpha, p->mode); - SetGLAliasing(p->aa); - - glEnable(GL_LINE_STIPPLE); - int n = (p->pxon+p->pxoff)/2; // todo properly when pxon != pxoff - glLineStipple(n, 0xAAAA); - - glBegin(GL_LINES); - - glVertex2f(p->x1, p->y1); - glVertex2f(p->x2, p->y2); - - glEnd(); - - glLineStipple(1, 65535); - glDisable(GL_LINE_STIPPLE); - - return true; -} - - -bool LICE_GLBitmap::FillRect_accel(LICE_Ext_FillRect_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - SetGLColor(p->color, p->alpha, p->mode); - - glBegin(GL_POLYGON); - - glVertex2i(p->x, p->y); - glVertex2i(p->x+p->w, p->y); - glVertex2i(p->x+p->w, p->y+p->h); - glVertex2i(p->x, p->y+p->h); - - glEnd(); - - return true; -} - -bool LICE_GLBitmap::DrawCBezier_accel(LICE_Ext_DrawCBezier_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - GLUnurbsObj* nurbs = LICE_GL_GetNurbsObj(); - if (!nurbs) return false; - -p->color = LICE_RGBA(255,255,255,255); // temp for easy ID of GL rendering - - SetGLColor(p->color, p->alpha, p->mode); - SetGLAliasing(p->aa); - - float ctlpts[] = - { - p->xstart, p->ystart, 0.0f, - p->xctl1, p->yctl1, 0.0f, - p->xctl2, p->yctl2, 0.0f, - p->xend, p->yend, 0.0f - }; - float knots[] = { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; - - gluBeginCurve(nurbs); - gluNurbsCurve(nurbs, 8, knots, 3, ctlpts, 4, GL_MAP1_VERTEX_3); - gluEndCurve(nurbs); - - return true; -} - -bool LICE_GLBitmap::DrawGlyph_accel(LICE_Ext_DrawGlyph_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - glEnable(GL_TEXTURE_RECTANGLE_ARB); - - int texID = LICE_GL_GetTexFromGlyph(p->alphas, p->glyph_w, p->glyph_h); - if (!texID) return false; - - SetGLColor(p->color, p->alpha, p->mode); - - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID); - glBegin(GL_POLYGON); - - glTexCoord2i(0, 0); - glVertex2i(p->x, p->y); - glTexCoord2i(p->glyph_w, 0); - glVertex2i(p->x+p->glyph_w, p->y); - glTexCoord2i(p->glyph_w, p->glyph_h); - glVertex2i(p->x+p->glyph_w, p->y+p->glyph_h); - glTexCoord2i(0, p->glyph_h); - glVertex2i(p->x, p->y+p->glyph_h); - - glEnd(); - - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - return true; -} - -bool LICE_GLBitmap::Blit_accel(LICE_Ext_Blit_acceldata* p) -{ - if (!p || !p->src) return false; - if (!FramebufferToGPU()) return false; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - GLuint src_tex = p->src->Extended(LICE_EXT_GETFBOTEX_ACCEL, 0); // this binds the src's FBO - if (src_tex) - { - if (!BindFBO()) return false; // re-bind dest FBO - - glEnable(GL_TEXTURE_RECTANGLE_ARB); - - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); - glBegin(GL_POLYGON); - - glTexCoord2i(p->srcx, p->srcy); - glVertex2i(p->dstx, p->dsty); - glTexCoord2i(p->srcx+p->srcw, p->srcy); - glVertex2i(p->dstx+p->srcw, p->dsty); - glTexCoord2i(p->srcx+p->srcw, p->srcy+p->srch); - glVertex2i(p->dstx+p->srcw, p->dsty+p->srch); - glTexCoord2i(p->srcx, p->srcy+p->srch); - glVertex2i(p->dstx, p->dsty+p->srch); - - glEnd(); - - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - return true; - } - - int srcspan = p->src->getRowSpan(); - if (p->srcx == 0 && p->srcy == 0 && p->srcw == srcspan) - { - glRasterPos2i(p->dstx, p->dsty); - glDrawPixels(p->srcw, p->srch, GL_RGBA, GL_UNSIGNED_BYTE, p->src->getBits()); - return true; - } - - LICE_pixel* srcrow = p->src->getBits()+p->srcy*srcspan+p->srcx; - int y; - for (y = 0; y < p->srch; ++y, srcrow += srcspan) - { - glRasterPos2i(p->dstx, p->dsty+y); - glDrawPixels(p->srcw, 1, GL_RGBA, GL_UNSIGNED_BYTE, srcrow); - } - return true; -} - -bool LICE_GLBitmap::ScaledBlit_accel(LICE_Ext_ScaledBlit_acceldata* p) -{ - if (!p || !p->src) return false; - if (!FramebufferToGPU()) return false; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glEnable(GL_TEXTURE_RECTANGLE_ARB); - - GLuint src_tex = p->src->Extended(LICE_EXT_GETFBOTEX_ACCEL, 0); // this binds the src's FBO - bool src_has_tex = (src_tex > 0); - if (src_has_tex) - { - if (!BindFBO()) return false; // re-bind dest FBO - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); - } - else - { - // create texture from src bits - glGenTextures(1, &src_tex); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); - - int srcspan = p->src->getRowSpan(); - if (p->srcx == 0 && p->srcy == 0 && srcspan == p->srcw) - { - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, p->srcw, p->srch, 0, GL_RGBA, GL_UNSIGNED_BYTE, p->src->getBits()); - } - else - { - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, p->srcw, p->srch, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture - LICE_pixel* srcrow = p->src->getBits()+(int)p->srcy*srcspan+(int)p->srcx; - int y; - for (y = 0; y < p->srch; ++y, srcrow += srcspan) - { - glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, y, p->srcw, 1, GL_RGBA, GL_UNSIGNED_BYTE, srcrow); - } - } - } - - if (!src_tex) return false; - - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // filter - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glBegin(GL_POLYGON); - - glTexCoord2i(p->srcx, p->srcy); - glVertex2i(p->dstx, p->dsty); - glTexCoord2i(p->srcx+p->srcw, p->srcy); - glVertex2i(p->dstx+p->dstw, p->dsty); - glTexCoord2i(p->srcx+p->srcw, p->srcy+p->srch); - glVertex2i(p->dstx+p->dstw, p->dsty+p->dsth); - glTexCoord2i(p->srcx, p->srcy+p->srch); - glVertex2i(p->dstx, p->dsty+p->dsth); - - glEnd(); - - if (!src_has_tex) glDeleteTextures(1, &src_tex); - - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - return true; -} - -bool LICE_GLBitmap::GetPixel_accel(LICE_Ext_GetPixel_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - p->px = 0; - glReadPixels(p->x, p->y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &p->px); - - return true; -} - -bool LICE_GLBitmap::PutPixel_accel(LICE_Ext_PutPixel_acceldata* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - SetGLColor(p->color, p->alpha, p->mode); - - glBegin(GL_POINTS); - glVertex2i(p->x, p->y); - glEnd(); - - return true; -} - -bool LICE_GLBitmap::DrawTriangle_accel(LICE_Ext_DrawTriangle_acceldata *p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - // todo: finish implementing zbuffering, (multi)texture mapping, alpha, etc - glColor4f(p->VertexShades[0][0], - p->VertexShades[0][1], - p->VertexShades[0][2], - p->mat->SolidOpacity); - - glBegin(GL_TRIANGLES); - - int x; - for(x=0;x<3;x++) - { - glVertex2i(p->scrx[x], p->scry[x]); - } - - glEnd(); - - return true; -} - -bool LICE_GLBitmap::WindowBlit(LICE_Ext_WindowBlit_data* p) -{ - if (!p) return false; - if (!FramebufferToGPU()) return false; - - HWND hwnd = p->hwnd; - if (hwnd != LICE_GL_GetWindow()) return 0; - - glFinish(); - - //HDC dc = GetDC(hwnd); - //HGLRC rc = wglCreateContext(dc); - //wglMakeCurrent(dc, rc); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - -/* - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, w, 0.0, h); -*/ - glEnable(GL_TEXTURE_RECTANGLE_ARB); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); - - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - // the src image is upside down - // todo positioning - glBegin(GL_POLYGON); - glTexCoord2i(0, p->h); - glVertex2i(0, 0); - glTexCoord2i(p->w, p->h); - glVertex2i(p->w, 0); - glTexCoord2i(p->w, 0); - glVertex2i(p->w-1, p->h); - glTexCoord2i(0, 0); - glVertex2i(0, p->h); - glEnd(); - glDisable(GL_TEXTURE_RECTANGLE_ARB); - -//wglMakeCurrent(0, 0); -//wglDeleteContext(rc); - -// ReleaseDC(hwnd, dc); - - return true; -} diff --git a/WDL/lice/lice_glbitmap.h b/WDL/lice/lice_glbitmap.h deleted file mode 100644 index 0b3ca61c..00000000 --- a/WDL/lice/lice_glbitmap.h +++ /dev/null @@ -1,110 +0,0 @@ -#include "lice.h" -#include "lice_extended.h" - -// interface class for LICE_GL_SysBitmap and LICE_GL_MemBitmap -class LICE_GLBitmap : public LICE_IBitmap -{ -public: - - LICE_GLBitmap(); - ~LICE_GLBitmap(); - - LICE_pixel* getBits(); - - int getWidth(); - int getHeight(); - int getRowSpan(); - - bool resize(int w, int h); - - virtual HDC getDC() = 0; // re-virtualize this to prevent instantiating LICE_GLBitmap directly - - INT_PTR Extended(int id, void* data); - -private: - - bool Clear_accel(LICE_pixel* color); - bool Line_accel(LICE_Ext_Line_acceldata* p); - bool FillRect_accel(LICE_Ext_FillRect_acceldata* p); - bool DrawCBezier_accel(LICE_Ext_DrawCBezier_acceldata* p); - bool DrawGlyph_accel(LICE_Ext_DrawGlyph_acceldata* p); - bool Blit_accel(LICE_Ext_Blit_acceldata* p); - bool ScaledBlit_accel(LICE_Ext_ScaledBlit_acceldata* p); - bool DashedLine_accel(LICE_Ext_DashedLine_acceldata* p); - bool GetPixel_accel(LICE_Ext_GetPixel_acceldata* p); - bool PutPixel_accel(LICE_Ext_PutPixel_acceldata* p); - bool SetClip_ext(LICE_Ext_SetClip_data* p); - bool DrawTriangle_accel(LICE_Ext_DrawTriangle_acceldata *p); - // etc - - bool WindowBlit(LICE_Ext_WindowBlit_data* p); - - bool CreateFBO(int w, int h); - bool BindFBO(); // bind this FBO so it is the current rendering target, and test for validity - void ReleaseFBO(); - - unsigned int m_fbo; // framebuffer object: rendering target for drawing on this glbitmap - unsigned int m_tex; // texture object: backing store for this framebuffer object - - enum { EMPTY, INGPU, INMEM }; - int m_bufloc; // where is the current framebuffer? - LICE_IBitmap* m_bmp; - -protected: - - void Init(LICE_IBitmap* bmp, int w, int h); - bool FramebufferToGPU(); - void FramebufferFromGPU(); -}; - -class LICE_GL_SysBitmap : public LICE_GLBitmap -{ -public: - - LICE_GL_SysBitmap(int w=0, int h=0); - - HDC getDC(); - -private: - - LICE_SysBitmap m_sysbmp; -}; - - -class LICE_GL_MemBitmap : public LICE_GLBitmap -{ -public: - - LICE_GL_MemBitmap(int w=0, int h=0); - - HDC getDC() { return 0; } - -private: - - LICE_MemBitmap m_membmp; -}; - - -class LICE_GL_SubBitmap : public LICE_IBitmap -{ -public: - - LICE_GL_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h); - - LICE_pixel* getBits(); - - int getWidth() { return m_w; } - int getHeight() { return m_h; } - int getRowSpan() { return (m_parent ? m_parent->getRowSpan() : 0); } - - bool resize(int w, int h); - - HDC getDC() { return (m_parent ? m_parent->getDC() : 0); } - - INT_PTR Extended(int id, void* data); - -private: - - LICE_IBitmap* m_parent; - int m_x, m_y, m_w, m_h; -}; diff --git a/WDL/lice/lice_ico.cpp b/WDL/lice/lice_ico.cpp deleted file mode 100644 index 5f3f7ea7..00000000 --- a/WDL/lice/lice_ico.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_ico.cpp (ICO icon file loading for LICE) - See lice.h for license and other information - - This file contains some code from Microsoft's MSDN ICO loading sample - see: http://msdn2.microsoft.com/en-us/library/ms997538.aspx -*/ - -#include "lice.h" -#ifndef _WIN32 -#include "../swell/swell.h" -#endif - -static LICE_IBitmap *icoToBitmap(HICON icon, LICE_IBitmap *bmpOut) -{ - int icon_w = 16, icon_h=16; - -#ifdef _WIN32 - ICONINFO ii={0,}; - if (GetIconInfo(icon,&ii)) - { - bool blah=false; - if (ii.hbmColor) - { - BITMAP bm={0,}; - if (GetObject(ii.hbmColor,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) - { - icon_w=bm.bmWidth; - icon_h=bm.bmHeight; - blah=true; - } - DeleteObject(ii.hbmColor); - } - if (ii.hbmMask) - { - BITMAP bm={0,}; - if (!blah && GetObject(ii.hbmMask,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) - { - icon_w=bm.bmWidth; - icon_h=bm.bmHeight; - } - DeleteObject(ii.hbmMask); - } - } -#else - BITMAP bm={0,}; - if (GetObject(icon,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) // SWELL's GetObject() works on icons - { - icon_w=bm.bmWidth; - icon_h=bm.bmHeight; - } - -#endif - - LICE_SysBitmap tempbm(icon_w*2,icon_h); - LICE_FillRect(&tempbm,0,0,icon_w,icon_h,LICE_RGBA(0,0,0,255),1.0f,LICE_BLIT_MODE_COPY); -#ifdef _WIN32 - DrawIconEx(tempbm.getDC(),0,0,icon,icon_w,icon_h,0,NULL,DI_NORMAL); -#else - { - RECT r={0,0,icon_w,icon_h}; - DrawImageInRect(tempbm.getDC(),icon,&r); - } -#endif - - LICE_FillRect(&tempbm,icon_w,0,icon_w,icon_h,LICE_RGBA(255,255,255,255),1.0f,LICE_BLIT_MODE_COPY); -#ifdef _WIN32 - DrawIconEx(tempbm.getDC(),icon_w,0,icon,icon_w,icon_h,0,NULL,DI_NORMAL); -#else - { - RECT r={icon_w,0,icon_w+icon_w,icon_h}; - DrawImageInRect(tempbm.getDC(),icon,&r); - } -#endif - - if (!bmpOut) bmpOut = new LICE_MemBitmap(icon_w,icon_h); - else bmpOut->resize(icon_w,icon_h); - - int y; // since we have the image drawn on white and on black, we can calculate the alpha channel... - for(y=0;y=255) alpha=255; - else if (alpha>0) - { - r1 = (r1*255)/alpha; // LICE stores its alpha channel non-premultiplied, so we need to scale these up. - g1 = (g1*255)/alpha; - b1 = (b1*255)/alpha; - if (r1>255)r1=255; - if (g1>255)g1=255; - if (b1>255)b1=255; - } - else alpha=0; - LICE_PutPixel(bmpOut,x,y,LICE_RGBA(r1,g1,b1,alpha),1.0f,LICE_BLIT_MODE_COPY); - } - } - - return bmpOut; -} - -LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success -{ - if (reqiconsz<1) reqiconsz=16; - HICON icon = NULL; -#ifdef _WIN32 - - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - icon = (HICON)LoadImageW(NULL,wf,IMAGE_ICON,reqiconsz,reqiconsz,LR_LOADFROMFILE); - } - - if (!icon) icon = (HICON)LoadImage(NULL,filename,IMAGE_ICON,reqiconsz,reqiconsz,LR_LOADFROMFILE); - -#else - icon = (HICON)LoadNamedImage(filename,false); -#endif - if (!icon) return 0; - - LICE_IBitmap *ret=icoToBitmap(icon,bmp); - DestroyIcon(icon); - return ret; -} - -LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success -{ -#ifdef _WIN32 - if (reqiconsz<1) reqiconsz=16; - HICON icon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_ICON,reqiconsz,reqiconsz,0); - if (!icon) return 0; - - LICE_IBitmap *ret=icoToBitmap(icon,bmp); - DestroyIcon(icon); - return ret; -#else - return 0; -#endif -} - - - - -class LICE_ICOLoader -{ -public: - _LICE_ImageLoader_rec rec; - LICE_ICOLoader() - { - rec.loadfunc = loadfunc; - rec.get_extlist = get_extlist; - rec._next = LICE_ImageLoader_list; - LICE_ImageLoader_list = &rec; - } - - static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) - { - if (checkFileName) - { - const char *p=filename; - while (*p)p++; - while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".ico")) return 0; - } - return LICE_LoadIcon(filename,16,bmpbase); - } - static const char *get_extlist() - { - return "ICO files (*.ICO)\0*.ICO\0"; - } - -}; - -LICE_ICOLoader LICE_icoldr; \ No newline at end of file diff --git a/WDL/lice/lice_image.cpp b/WDL/lice/lice_image.cpp deleted file mode 100644 index 49e9a699..00000000 --- a/WDL/lice/lice_image.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "lice.h" - - - -LICE_IBitmap* LICE_LoadImage(const char* filename, LICE_IBitmap* bmp, bool tryIgnoreExtension) -{ - _LICE_ImageLoader_rec *hdr = LICE_ImageLoader_list; - while (hdr) - { - LICE_IBitmap *ret = hdr->loadfunc(filename,true,bmp); - if (ret) return ret; - hdr=hdr->_next; - } - if (tryIgnoreExtension) - { - hdr = LICE_ImageLoader_list; - while (hdr) - { - LICE_IBitmap *ret = hdr->loadfunc(filename,false,bmp); - if (ret) return ret; - hdr=hdr->_next; - } - } - - return 0; -} - - -static bool grow_buf(char **buf, int *bufsz, int *wrpos, const char *rd, int len) -{ - if (*wrpos + len > *bufsz) - { - char *nbuf=(char*)realloc(*buf,*bufsz = *wrpos+len+4096); - if (!nbuf) return true; // ugh - *buf = nbuf; - } - memcpy(*buf+*wrpos,rd,len); - *wrpos+=len; - return false; -} - -char *LICE_GetImageExtensionList(bool wantAllSup, bool wantAllFiles) -{ - _LICE_ImageLoader_rec *hdr = LICE_ImageLoader_list; - int bufsz=4096; - int wrpos=0; - char *buf=(char *)malloc(bufsz); - buf[0]=buf[1]=buf[2]=0; - - if (wantAllSup) - { - static const char af[]="All supported images"; - if (grow_buf(&buf,&bufsz,&wrpos,af,sizeof(af))) { free(buf); return NULL; } // fail - - int cnt=0; - while (hdr) - { - const char *rd = hdr->get_extlist(); - if (rd && *rd) - { - bool st=false; - const char *p=rd; - while (*p) - { - if (st) - { - if (cnt++) - if (grow_buf(&buf,&bufsz,&wrpos,";",1)) { free(buf); return NULL; } // fail - if (grow_buf(&buf,&bufsz,&wrpos,p,strlen(p)+1)) { free(buf); return NULL; } // fail - wrpos--; - } - while (*p) p++; - p++; - st=!st; - } - } - hdr=hdr->_next; - } - - if (!cnt) - { - wrpos=0; // reset if nothing meaningful added - buf[0]=buf[1]=buf[2]=0; - } - else wrpos++; - - hdr = LICE_ImageLoader_list; - } - - while (hdr) - { - const char *rd = hdr->get_extlist(); - if (rd && *rd) - { - const char *p=rd; - while (p[0] || p[1]) p++; // doublenull terminated list - - int len = p + 2 - rd; - if (len>2) - { - if (grow_buf(&buf,&bufsz,&wrpos,rd,len)) return buf; // fail - wrpos--; // remove doublenull on next round - } - } - hdr=hdr->_next; - } - if (wantAllFiles) - { - static const char af[]="All files (*.*)\0*.*\0"; - if (grow_buf(&buf,&bufsz,&wrpos,af,sizeof(af))) return buf; // fail - wrpos--; - } - - return buf; -} - -bool LICE_ImageIsSupported(const char *filename) -{ - const char *extension = filename; - while (*extension)extension++; - while (extension>=filename && *extension != '/' && *extension != '.' && *extension != '\\') extension--; - if (extensionget_extlist(); - if (el) - { - while (*el) el++; // skip desc - ++el; - - // scan rest of buffer - while (*el) - { - if (!strnicmp(el,extension,extlen)) - { - if (el[extlen] == 0|| el[extlen] == ';') return true; - } - el++; - } - } - hdr=hdr->_next; - } - return false; -} diff --git a/WDL/lice/lice_jpg.cpp b/WDL/lice/lice_jpg.cpp deleted file mode 100644 index 212a55c1..00000000 --- a/WDL/lice/lice_jpg.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_jpg.cpp (JPG loading for LICE) - See lice.h for license and other information -*/ - -#include -#include "lice.h" -#include - -extern "C" { -#include "../jpeglib/jpeglib.h" -}; - -struct my_error_mgr { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; -static void LICEJPEG_Error(j_common_ptr cinfo) -{ - longjmp(((my_error_mgr*)cinfo->err)->setjmp_buffer,1); -} -static void LICEJPEG_EmitMsg(j_common_ptr cinfo, int msg_level) { } -static void LICEJPEG_FmtMsg(j_common_ptr cinfo, char *) { } -static void LICEJPEG_OutMsg(j_common_ptr cinfo) { } -static void LICEJPEG_reset_error_mgr(j_common_ptr cinfo) -{ - cinfo->err->num_warnings = 0; - cinfo->err->msg_code = 0; -} - -static void LICEJPEG_init_source(j_decompress_ptr cinfo) {} -static unsigned char EOI_data[2] = { 0xFF, 0xD9 }; -static boolean LICEJPEG_fill_input_buffer(j_decompress_ptr cinfo) -{ - cinfo->src->next_input_byte = EOI_data; - cinfo->src->bytes_in_buffer = 2; - return TRUE; -} -static void LICEJPEG_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - if (num_bytes > 0) - { - if (num_bytes > (long) cinfo->src->bytes_in_buffer) - { - num_bytes = (long) cinfo->src->bytes_in_buffer; - } - cinfo->src->next_input_byte += (size_t) num_bytes; - cinfo->src->bytes_in_buffer -= (size_t) num_bytes; - } -} -static void LICEJPEG_term_source(j_decompress_ptr cinfo) {} - - -LICE_IBitmap *LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) -{ -#ifdef _WIN32 - HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "JPG"); - if(!hResource) return NULL; - - DWORD imageSize = SizeofResource(hInst, hResource); - if(imageSize < 8) return NULL; - - HGLOBAL res = LoadResource(hInst, hResource); - const void* pResourceData = LockResource(res); - if(!pResourceData) return NULL; - - unsigned char *data = (unsigned char *)pResourceData; - - struct jpeg_decompress_struct cinfo; - struct my_error_mgr jerr={0,}; - JSAMPARRAY buffer; - int row_stride; - - jerr.pub.error_exit = LICEJPEG_Error; - jerr.pub.emit_message = LICEJPEG_EmitMsg; - jerr.pub.output_message = LICEJPEG_OutMsg; - jerr.pub.format_message = LICEJPEG_FmtMsg; - jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; - - cinfo.err = &jerr.pub; - - if (setjmp(jerr.setjmp_buffer)) - { - jpeg_destroy_decompress(&cinfo); - DeleteObject(res); - return 0; - } - jpeg_create_decompress(&cinfo); - - cinfo.src = (struct jpeg_source_mgr *) (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, sizeof (struct jpeg_source_mgr)); - - cinfo.src->init_source = LICEJPEG_init_source; - cinfo.src->fill_input_buffer = LICEJPEG_fill_input_buffer; - cinfo.src->skip_input_data = LICEJPEG_skip_input_data; - cinfo.src->resync_to_restart = jpeg_resync_to_restart; - cinfo.src->term_source = LICEJPEG_term_source; - - cinfo.src->next_input_byte = data; - cinfo.src->bytes_in_buffer = imageSize; - - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - row_stride = cinfo.output_width * cinfo.output_components; - - buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - if (bmp) - { - bmp->resize(cinfo.output_width,cinfo.output_height); - if (bmp->getWidth() != (int)cinfo.output_width || bmp->getHeight() != (int)cinfo.output_height) - { - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - DeleteObject(res); - return 0; - } - } - else bmp=new LICE_MemBitmap(cinfo.output_width,cinfo.output_height); - - LICE_pixel *bmpptr = bmp->getBits(); - int dbmpptr=bmp->getRowSpan(); - if (bmp->isFlipped()) - { - bmpptr += dbmpptr*(bmp->getHeight()-1); - dbmpptr=-dbmpptr; - } - - 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. - */ - jpeg_read_scanlines(&cinfo, buffer, 1); - /* Assume put_scanline_someplace wants a pointer and sample count. */ -// put_scanline_someplace(buffer[0], row_stride); - if (cinfo.output_components==3) - { - int x; - for (x = 0; x < (int)cinfo.output_width; x++) - { - bmpptr[x]=LICE_RGBA(buffer[0][x*3],buffer[0][x*3+1],buffer[0][x*3+2],255); - } - } - else if (cinfo.output_components==1) - { - int x; - for (x = 0; x < (int)cinfo.output_width; x++) - { - int v=buffer[0][x]; - bmpptr[x]=LICE_RGBA(v,v,v,255); - } - } - else - { - memset(bmpptr,0,4*cinfo.output_width); - } - bmpptr+=dbmpptr; - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); // we created cinfo.src with some special alloc so I think it gets collected - DeleteObject(res); - - return bmp; - -#else - return 0; -#endif -} - - -LICE_IBitmap *LICE_LoadJPG(const char *filename, LICE_IBitmap *bmp) -{ - struct jpeg_decompress_struct cinfo; - struct my_error_mgr jerr={{0},}; - JSAMPARRAY buffer; - int row_stride; - - FILE *fp=NULL; -#ifdef _WIN32 - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - fp = _wfopen(wf,L"rb"); - } -#endif - if (!fp) fp = fopen(filename,"rb"); - - if (!fp) return 0; - - jerr.pub.error_exit = LICEJPEG_Error; - jerr.pub.emit_message = LICEJPEG_EmitMsg; - jerr.pub.output_message = LICEJPEG_OutMsg; - jerr.pub.format_message = LICEJPEG_FmtMsg; - jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; - - cinfo.err = &jerr.pub; - - if (setjmp(jerr.setjmp_buffer)) - { - jpeg_destroy_decompress(&cinfo); - fclose(fp); - return 0; - } - jpeg_create_decompress(&cinfo); - - jpeg_stdio_src(&cinfo, fp); - jpeg_read_header(&cinfo, TRUE); - jpeg_start_decompress(&cinfo); - - row_stride = cinfo.output_width * cinfo.output_components; - - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - if (bmp) - { - bmp->resize(cinfo.output_width,cinfo.output_height); - if (bmp->getWidth() != (int)cinfo.output_width || bmp->getHeight() != (int)cinfo.output_height) - { - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(fp); - return 0; - } - } - else bmp=new LICE_MemBitmap(cinfo.output_width,cinfo.output_height); - - LICE_pixel *bmpptr = bmp->getBits(); - int dbmpptr=bmp->getRowSpan(); - if (bmp->isFlipped()) - { - bmpptr += dbmpptr*(bmp->getHeight()-1); - dbmpptr=-dbmpptr; - } - - 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. - */ - jpeg_read_scanlines(&cinfo, buffer, 1); - /* Assume put_scanline_someplace wants a pointer and sample count. */ -// put_scanline_someplace(buffer[0], row_stride); - if (cinfo.output_components==3) - { - int x; - for (x = 0; x < (int)cinfo.output_width; x++) - { - bmpptr[x]=LICE_RGBA(buffer[0][x*3],buffer[0][x*3+1],buffer[0][x*3+2],255); - } - } - else if (cinfo.output_components==1) - { - int x; - for (x = 0; x < (int)cinfo.output_width; x++) - { - int v=buffer[0][x]; - bmpptr[x]=LICE_RGBA(v,v,v,255); - } - } - else - memset(bmpptr,0,4*cinfo.output_width); - bmpptr+=dbmpptr; - } - - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(fp); - - return bmp; -} - - -class LICE_JPGLoader -{ -public: - _LICE_ImageLoader_rec rec; - LICE_JPGLoader() - { - rec.loadfunc = loadfunc; - rec.get_extlist = get_extlist; - rec._next = LICE_ImageLoader_list; - LICE_ImageLoader_list = &rec; - } - - static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) - { - if (checkFileName) - { - const char *p=filename; - while (*p)p++; - while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".jpg")&&stricmp(p,".jpeg")&&stricmp(p,".jfif")) return 0; - } - return LICE_LoadJPG(filename,bmpbase); - } - static const char *get_extlist() - { - return "JPEG files (*.JPG;*.JPEG;*.JFIF)\0*.JPG;*.JPEG;*.JFIF\0"; - } - -}; - -LICE_JPGLoader LICE_jgpldr; diff --git a/WDL/lice/lice_jpg_write.cpp b/WDL/lice/lice_jpg_write.cpp deleted file mode 100644 index 3f425854..00000000 --- a/WDL/lice/lice_jpg_write.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_jpg_write.cpp (JPG writing for LICE) - See lice.h for license and other information -*/ - -#include -#include "lice.h" -#include - -extern "C" { -#include "../jpeglib/jpeglib.h" -}; - -struct my_error_mgr { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; -static void LICEJPEG_Error(j_common_ptr cinfo) -{ - longjmp(((my_error_mgr*)cinfo->err)->setjmp_buffer,1); -} -static void LICEJPEG_EmitMsg(j_common_ptr cinfo, int msg_level) { } -static void LICEJPEG_FmtMsg(j_common_ptr cinfo, char *) { } -static void LICEJPEG_OutMsg(j_common_ptr cinfo) { } -static void LICEJPEG_reset_error_mgr(j_common_ptr cinfo) -{ - cinfo->err->num_warnings = 0; - cinfo->err->msg_code = 0; -} - -bool LICE_WriteJPG(const char *filename, LICE_IBitmap *bmp, int quality, bool force_baseline) -{ - if (!bmp || !filename) return false; - - FILE *fp=NULL; -#ifdef _WIN32 - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - fp = _wfopen(wf,L"wb"); - } -#endif - if (!fp) fp = fopen(filename,"wb"); - - if (!fp) return false; - - struct jpeg_compress_struct cinfo; - struct my_error_mgr jerr={0,}; - jerr.pub.error_exit = LICEJPEG_Error; - jerr.pub.emit_message = LICEJPEG_EmitMsg; - jerr.pub.output_message = LICEJPEG_OutMsg; - jerr.pub.format_message = LICEJPEG_FmtMsg; - jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; - - cinfo.err = &jerr.pub; - unsigned char *buf = NULL; - - if (setjmp(jerr.setjmp_buffer)) - { - jpeg_destroy_compress(&cinfo); - if (fp) fclose(fp); - free(buf); - return false; - } - jpeg_create_compress(&cinfo); - - jpeg_stdio_dest(&cinfo, fp); - - cinfo.image_width = bmp->getWidth(); /* image width and height, in pixels */ - cinfo.image_height = bmp->getHeight(); - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, !!force_baseline); - jpeg_start_compress(&cinfo, TRUE); - - buf = (unsigned char *)malloc(cinfo.image_width * 3); - LICE_pixel_chan *rd = (LICE_pixel_chan *)bmp->getBits(); - int rowspan = bmp->getRowSpan()*4; - if (bmp->isFlipped()) - { - rd += rowspan*(bmp->getHeight()-1); - rowspan=-rowspan; - } - while (cinfo.next_scanline < cinfo.image_height) - { - unsigned char *outp=buf; - LICE_pixel_chan *rdp = rd; - int x=cinfo.image_width; - while(x--) - { - outp[0] = rdp[LICE_PIXEL_R]; - outp[1] = rdp[LICE_PIXEL_G]; - outp[2] = rdp[LICE_PIXEL_B]; - outp+=3; - rdp+=4; - } - jpeg_write_scanlines(&cinfo, &buf, 1); - - rd+=rowspan; - } - free(buf); - buf=0; - - jpeg_finish_compress(&cinfo); - - if (fp) fclose(fp); - fp=0; - - jpeg_destroy_compress(&cinfo); - - return true; -} \ No newline at end of file diff --git a/WDL/lice/lice_lcf.cpp b/WDL/lice/lice_lcf.cpp deleted file mode 100644 index 4e0bc95e..00000000 --- a/WDL/lice/lice_lcf.cpp +++ /dev/null @@ -1,663 +0,0 @@ -#include -#include - -#include "lice_lcf.h" - -#include "../filewrite.h" -#include "../fileread.h" - - -#define LCF_VERSION 0x11CEb001 - -LICECaptureCompressor::LICECaptureCompressor(const char *outfn, int w, int h, int interval, int bsize_w, int bsize_h) -{ - m_inframes = m_outframes=0; - m_file = new WDL_FileWrite(outfn,1,512*1024); - if (!m_file->IsOpen()) { delete m_file; m_file=0; } - - memset(&m_compstream,0,sizeof(m_compstream)); - if (m_file) - { - if (deflateInit(&m_compstream,9)!=Z_OK) - { - delete m_file; - m_file=0; - } - } - - m_inbytes=0; - m_outsize=0; - m_w=w; - m_h=h; - m_interval=interval; - m_bsize_w=bsize_w; - m_bsize_h=bsize_h; - m_state=0; - m_which=0; - m_outchunkpos=0; - m_numcols = (m_w+bsize_w-1) / (bsize_w>0?bsize_w:1); - if (m_numcols<1) m_numcols=1; - m_numrows = (m_h+bsize_h-1)/ (bsize_h>0?bsize_h:1); - - m_current_block_srcsize=0; -} - -void LICECaptureCompressor::OnFrame(LICE_IBitmap *fr, int delta_t_ms) -{ - if (fr) - { - if (fr->getWidth()!=m_w || fr->getHeight()!=m_h) return; - - frameRec *rec = m_framelists[m_which].Get(m_state); - if (!rec) - { - rec = new frameRec(m_w*m_h); - m_framelists[m_which].Add(rec); - } - rec->delta_t_ms=delta_t_ms; - BitmapToFrameRec(fr,rec); - m_state++; - m_inframes++; - } - - - bool isLastBlock = m_state >= m_interval || !fr; - - if (m_framelists[!m_which].GetSize()) - { - int compressTo; - if (isLastBlock) compressTo = m_numcols*m_numrows; - else compressTo = (m_state * m_numcols*m_numrows) / m_interval; - - frameRec **list = m_framelists[!m_which].GetList(); - int list_size = m_framelists[!m_which].GetSize(); - - // compress some data - int chunkpos = m_outchunkpos; - while (chunkpos < compressTo) - { - int xpos = (chunkpos%m_numcols) * m_bsize_w; - int ypos = (chunkpos/m_numcols) * m_bsize_h; - - int wid = m_w-xpos; - int hei = m_h-ypos; - if (wid > m_bsize_w) wid=m_bsize_w; - if (hei > m_bsize_h) hei=m_bsize_h; - - int i; - int rdoffs = xpos + ypos*m_w; - int rdspan = m_w; - - int repeat_cnt=0; - - for(i=0;idata + rdoffs; - if (i&&repeat_cnt<256) - { - unsigned short *rd1=rd; - unsigned short *rd2=list[i-1]->data+rdoffs; - int a=hei; - while(a--) - { - if (memcmp(rd1,rd2,wid*sizeof(short))) break; - rd1+=rdspan; - rd2+=rdspan; - } - if (a<0) - { - repeat_cnt++; - continue; - } - } - - if (i || repeat_cnt) - { - unsigned char c = (unsigned char)repeat_cnt; - DeflateBlock(&c,1,false); - repeat_cnt=0; - } - int a=hei; - while (a--) - { - DeflateBlock(rd,wid*sizeof(short),false); - rd+=rdspan; - } - } - if (repeat_cnt) - { - unsigned char c = (unsigned char)repeat_cnt; - DeflateBlock(&c,1,false); - } - - chunkpos++; - } - m_outchunkpos=chunkpos; - } - - if (isLastBlock) - { - if (m_framelists[!m_which].GetSize()) - { - m_outframes += m_framelists[!m_which].GetSize(); - - DeflateBlock(NULL,0,true); - - deflateReset(&m_compstream); - - m_hdrqueue.Clear(); - AddHdrInt(LCF_VERSION); - AddHdrInt(16); - AddHdrInt(m_w); - AddHdrInt(m_h); - AddHdrInt(m_bsize_w); - AddHdrInt(m_bsize_h); - int nf = m_framelists[!m_which].GetSize(); - AddHdrInt(nf); - int sz = m_current_block.Available(); - AddHdrInt(sz); - - int uncomp_sz = m_current_block_srcsize; - AddHdrInt(uncomp_sz); - - { - int x; - for(x=0;xdelta_t_ms); - } - } - - - m_file->Write(m_hdrqueue.Get(),m_hdrqueue.Available()); - m_outsize += m_hdrqueue.Available(); - m_file->Write(m_current_block.Get(),sz); - m_outsize += sz; - - m_current_block.Clear(); - m_current_block_srcsize=0; - } - - - int old_state=m_state; - m_state=0; - m_outchunkpos=0; - m_which=!m_which; - - - if (old_state>0 && !fr) - { - while (m_framelists[!m_which].GetSize() > old_state) - m_framelists[!m_which].Delete(m_framelists[!m_which].GetSize()-1,true); - - OnFrame(NULL,0); - } - - if (!fr) - { - m_framelists[0].Empty(true); - m_framelists[1].Empty(true); - } - } -} - -void LICECaptureCompressor::BitmapToFrameRec(LICE_IBitmap *fr, frameRec *dest) -{ - unsigned short *outptr = dest->data; - const LICE_pixel *p = fr->getBits(); - int span = fr->getRowSpan(); - if (fr->isFlipped()) - { - p+=(fr->getHeight()-1)*span; - span=-span; - } - int h = fr->getHeight(),w=fr->getWidth(); - while (h--) - { - int x=w; - const LICE_pixel *sp = p; - while (x--) - { - LICE_pixel pix = *sp++; - *outptr++ = (((int)LICE_GETR(pix)&0xF8)>>3) | (((int)LICE_GETG(pix)&0xFC)<<3) | (((int)LICE_GETB(pix)&0xF8)<<8); - } - p += span; - } -} - -void LICECaptureCompressor::DeflateBlock(void *data, int data_size, bool flush) -{ - m_current_block_srcsize += data_size; - m_inbytes += data_size; - int bytesout=0; - - m_compstream.next_in = (unsigned char *)data; - m_compstream.avail_in = data_size; - - for (;;) - { - int add_sz = data_size+32768; - m_compstream.next_out = (unsigned char *)m_current_block.Add(NULL,add_sz); - m_compstream.avail_out = add_sz; - - int e = deflate(&m_compstream,flush?Z_FULL_FLUSH:Z_NO_FLUSH); - - m_current_block.Add(NULL,-(int)m_compstream.avail_out); - - bytesout+=add_sz-m_compstream.avail_out; - - - if (e != Z_OK) - { - break; - } - - if (!m_compstream.avail_in && (!flush || add_sz==(int)m_compstream.avail_out)) break; - } - m_outsize += bytesout; - -} - - - -LICECaptureCompressor::~LICECaptureCompressor() -{ - // process any pending frames - if (m_file) - { - OnFrame(NULL,0); - deflateEnd(&m_compstream); - } - - delete m_file; - m_framelists[0].Empty(true); - m_framelists[1].Empty(true); -} - - - - - - - - - - - - - - -////////////////////////////////////////// -///////DECOMPRESS -////////////////////////////////////////// - - -LICECaptureDecompressor::LICECaptureDecompressor(const char *fn, bool want_seekable) : m_workbm(0,0,1) -{ - m_file_length_ms=0; - m_rd_which=0; - m_frameidx=0; - memset(&m_compstream,0,sizeof(m_compstream)); - memset(&m_curhdr,0,sizeof(m_curhdr)); - m_file = new WDL_FileRead(fn,2,1024*1024); - if (m_file->IsOpen()) - { - if (inflateInit(&m_compstream)!=Z_OK) - { - delete m_file; - m_file=0; - } - if (m_file) - { - m_file_frame_info.Clear(); - m_file_length_ms=0; - if (want_seekable) - { - unsigned int lastpos = 0; - while (ReadHdr(0)) - { - m_file_frame_info.Add(&lastpos,1); - unsigned int mst = m_file_length_ms; - if (m_frame_deltas[0].GetSize()) mst += m_frame_deltas[0].Get()[0]; // TOC is by time of first frames, ignore first delay when seeking - m_file_frame_info.Add(&mst,1); - - int x; - for(x=0;xSetPosition(lastpos = (unsigned int)(m_file->GetPosition() + m_curhdr[0].cdata_left)); - } - } - - Seek(0); - } - } - - if (m_curhdr[m_rd_which].bpp!=16) - { - delete m_file; - m_file=0; - } - -} - -LICECaptureDecompressor::~LICECaptureDecompressor() -{ - inflateEnd(&m_compstream); - delete m_file; -} - -bool LICECaptureDecompressor::NextFrame() // TRUE if out of frames -{ - if (++m_frameidx >= m_frame_deltas[m_rd_which].GetSize()) - { - m_rd_which=!m_rd_which; - - DecompressBlock(m_rd_which,1.0); - if (!ReadHdr(!m_rd_which)) - memset(&m_curhdr[!m_rd_which],0,sizeof(m_curhdr[!m_rd_which])); - m_frameidx=0; - if (!m_curhdr[m_rd_which].bpp) return false; - DecodeSlices(); - } - else - DecompressBlock(!m_rd_which,m_frameidx/(double)m_frame_deltas[m_rd_which].GetSize()); - return false; -} - -int LICECaptureDecompressor::Seek(unsigned int offset_ms) -{ - - memset(m_curhdr,0,sizeof(m_curhdr)); - if (!m_file) return -1; - - int rval=0; - - unsigned int seekpos=0; - m_frameidx=0; - if (offset_ms>0&&m_file_frame_info.GetSize()) - { - int x; - for(x=0;x0) rval=-1; - offset_ms=0; - } - - m_rd_which=0; - m_file->SetPosition(seekpos); - if (!ReadHdr(m_rd_which)||!DecompressBlock(m_rd_which,1.0)) - { - rval=-1; - memset(&m_curhdr,0,sizeof(m_curhdr)); - } - else - { - if (offset_ms>0 && rval==0) - { - int x; - for (x = 1; x < m_frame_deltas[m_rd_which].GetSize(); x++) - { - if (offset_ms < m_frame_deltas[m_rd_which].Get()[x]) - { - rval = offset_ms; - break; - } - offset_ms -= m_frame_deltas[m_rd_which].Get()[x]; - } - m_frameidx=x-1; - } - if (!ReadHdr(!m_rd_which)) - memset(&m_curhdr[!m_rd_which],0,sizeof(m_curhdr[!m_rd_which])); - - DecodeSlices(); - } - - return rval; -} - - -bool LICECaptureDecompressor::ReadHdr(int whdr) // todo: eventually make this read/decompress the next header as it goes -{ - m_tmp.Clear(); - int hdr_sz = (4*9); - if (m_file->Read(m_tmp.Add(NULL,hdr_sz),hdr_sz)!=hdr_sz) return false; - int ver; - m_tmp.GetTFromLE(&ver); - if (ver !=LCF_VERSION) return false; - m_tmp.GetTFromLE(&m_curhdr[whdr].bpp); - m_tmp.GetTFromLE(&m_curhdr[whdr].w); - m_tmp.GetTFromLE(&m_curhdr[whdr].h); - m_tmp.GetTFromLE(&m_curhdr[whdr].bsize_w); - m_tmp.GetTFromLE(&m_curhdr[whdr].bsize_h); - int nf; - m_tmp.GetTFromLE(&nf); - int csize; - m_tmp.GetTFromLE(&csize); - - int dsize; - m_tmp.GetTFromLE(&dsize); - - if (nf<1 || nf > 1024) return false; - - m_frame_deltas[whdr].Resize(nf); - - if (m_frame_deltas[whdr].GetSize()!=nf) return false; - - if (m_file->Read(m_frame_deltas[whdr].Get(),nf*4)!=nf*4) return false; - int x; - for(x=0;xpercent) break; - } - unsigned char buf[16384]; - m_compstream.next_in = buf; - m_compstream.avail_in = m_curhdr[whdr].cdata_left; - if (m_compstream.avail_in > (int)sizeof(buf)) m_compstream.avail_in=(int)sizeof(buf); - - m_compstream.avail_in = m_file->Read(buf,m_compstream.avail_in); - m_curhdr[whdr].cdata_left -= m_compstream.avail_in; - - int e = inflate(&m_compstream,0); - if (e != Z_OK&&e!=Z_STREAM_END) - { -// printf("inflate error: %d (%d/%d)\n",e,m_compstream.avail_in, m_curhdr[whdr].cdata_left); - return !m_compstream.avail_out; - } - if (!m_compstream.avail_out && !m_compstream.avail_in) break; - } - } - - return true; -} - -int LICECaptureDecompressor::GetTimeToNextFrame() -{ - int nf = m_frame_deltas[m_rd_which].GetSize(); - int fidx = m_frameidx; - - if (fidx<0&& nf) return m_frame_deltas[m_rd_which].Get()[0]; - - if (fidx+1 < nf) return m_frame_deltas[m_rd_which].Get()[fidx+1]; - - if (m_curhdr[!m_rd_which].bpp && m_frame_deltas[!m_rd_which].GetSize()) - return m_frame_deltas[!m_rd_which].Get()[0]; - - return 100; -} - -void LICECaptureDecompressor::DecodeSlices() -{ - int nf = m_frame_deltas[m_rd_which].GetSize(); - unsigned char *sp = (unsigned char *)m_decompdata[m_rd_which].Get(); - int sp_left = m_decompdata[m_rd_which].GetSize(); - hdrType *hdr = m_curhdr+m_rd_which; - int ns_x = (hdr->w + hdr->bsize_w-1)/hdr->bsize_w; - int ns_y = (hdr->h + hdr->bsize_h-1)/hdr->bsize_h; - - int ns_frame = ns_x*ns_y; - void **slicelist = m_slices.Resize(nf * ns_frame); - - // format of sp is: - // nf slices - // each slice is : - // initial value - // repeat cnt - // frame - // repeat cnt - // .. - - int ypos, - toth=hdr->h, - totw=hdr->w; - - int bytespersample = (hdr->bpp+7)/8; - - for (ypos = 0; ypos < toth; ypos+=hdr->bsize_h) - { - int hei = toth-ypos; - if (hei>hdr->bsize_h) hei=hdr->bsize_h; - int xpos; - for (xpos=0; xposbsize_w) - { - int wid = totw-xpos; - if (wid>hdr->bsize_w) wid=hdr->bsize_w; - - int sz1=wid*hei*bytespersample; - - int slicewritepos = 0,i = 0; - void *lvalid = NULL; - while (i0) - { - if (lvalid) - { - unsigned char c = *sp++; - sp_left--; - while (c-->0 && i++ < nf) - { - // repeat last slice - slicelist[slicewritepos] = lvalid; - slicewritepos += ns_frame; - } - } - if (i=0 && fidx < nf && m_slices.GetSize() && hdr->bsize_w && hdr->bsize_h) - { - int ns_x = (hdr->w + hdr->bsize_w-1)/hdr->bsize_w; - int ns_y = (hdr->h + hdr->bsize_h-1)/hdr->bsize_h; - - int ns_frame = ns_x*ns_y; - - if (m_slices.GetSize() != ns_frame*nf) - return NULL; // invalid slices - - if (hdr->bpp == 16) - { - m_workbm.resize(hdr->w,hdr->h); - //unsigned short * - // format of m_decompdata is: - // nf frames of slice1, nf frames of slice2, etc - - LICE_pixel *pout = m_workbm.getBits(); - int span = m_workbm.getRowSpan(); - - int ypos, - toth=hdr->h, - totw=hdr->w; - void **sliceptr = m_slices.Get() + ns_frame * fidx; - - for (ypos = 0; ypos < toth; ypos+=hdr->bsize_h) - { - int hei = toth-ypos; - if (hei>hdr->bsize_h) hei=hdr->bsize_h; - int xpos; - for (xpos=0; xposbsize_w) - { - int wid = totw-xpos; - if (wid>hdr->bsize_w) wid=hdr->bsize_w; - - int sz1=wid*hei; - - unsigned short *rdptr = (unsigned short *)*sliceptr; - - sliceptr++; - - LICE_pixel *dest = pout + xpos + ypos*span; - int y; - for (y=0;y>3)&0xFC,(px>>8)&0xF8,255); - } - dest+=span; - } - } - } - - - return &m_workbm; - } - } - return NULL; -} \ No newline at end of file diff --git a/WDL/lice/lice_lcf.h b/WDL/lice/lice_lcf.h deleted file mode 100644 index b60801e0..00000000 --- a/WDL/lice/lice_lcf.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _LICE_LCF_H_ -#define _LICE_LCF_H_ - -#include "../zlib/zlib.h" -#include "lice.h" - -#include "../ptrlist.h" -#include "../queue.h" -class WDL_FileWrite; -class WDL_FileRead; - -class LICECaptureCompressor -{ -public: - LICECaptureCompressor(const char *outfn, int w, int h, int interval=20, int bsize_w=128, int bsize_h=16); - - ~LICECaptureCompressor(); - - bool IsOpen() { return !!m_file; } - void OnFrame(LICE_IBitmap *fr, int delta_t_ms); - - WDL_INT64 GetOutSize() { return m_outsize; } - WDL_INT64 GetInSize() { return m_inbytes; } - - -private: - WDL_FileWrite *m_file; - WDL_INT64 m_outsize,m_inbytes; - int m_inframes, m_outframes; - - int m_w,m_h,m_interval,m_bsize_w,m_bsize_h; - - - struct frameRec - { - frameRec(int sz) { data=(unsigned short *)malloc(sz*sizeof(short)); delta_t_ms=0; } - ~frameRec() { free(data); } - unsigned short *data; // shorts - int delta_t_ms; // time (ms) since last frame - }; - WDL_PtrList m_framelists[2]; - WDL_Queue m_current_block; - WDL_Queue m_hdrqueue; - - int m_state, m_which,m_outchunkpos,m_numrows,m_numcols; - int m_current_block_srcsize; - - z_stream m_compstream; - - void BitmapToFrameRec(LICE_IBitmap *fr, frameRec *dest); - void DeflateBlock(void *data, int data_size, bool flush); - void AddHdrInt(int a) { m_hdrqueue.AddToLE(&a); } - - -}; - - -class LICECaptureDecompressor -{ -public: - LICECaptureDecompressor(const char *fn, bool want_seekable=false); - ~LICECaptureDecompressor(); - - - bool IsOpen() { return !!m_file; } - - // only supported if want_seekable=true - int GetLength() { return m_file_length_ms; } // length in ms - int Seek(unsigned int offset_ms); // return -1 on fail (out of range), or >0 to tell you how far into the frame you seeked (0=exact hit) - - bool NextFrame(); // TRUE if out of frames - LICE_IBitmap *GetCurrentFrame(); // can return NULL if error - int GetTimeToNextFrame(); // delta in ms - - int GetWidth(){ return m_curhdr[m_rd_which].w; } - int GetHeight(){ return m_curhdr[m_rd_which].h; } - -private: - LICE_MemBitmap m_workbm; - - struct hdrType - { - int bpp; - int w, h; - int bsize_w, bsize_h; - int cdata_left; - } m_curhdr[2]; - - int m_rd_which; - int m_frameidx; - - bool ReadHdr(int whdr); - bool DecompressBlock(int whdr, double percent=1.0); - - z_stream m_compstream; - WDL_Queue m_tmp; - - WDL_FileRead *m_file; - - unsigned int m_file_length_ms; - WDL_TypedQueue m_file_frame_info; //pairs of offset_bytes, offset_ms - - WDL_TypedBuf m_frame_deltas[2]; - WDL_HeapBuf m_decompdata[2]; - WDL_TypedBuf m_slices; // indexed by [frame][slice] - - void DecodeSlices(); -}; - -#endif diff --git a/WDL/lice/lice_line.cpp b/WDL/lice/lice_line.cpp deleted file mode 100644 index 71eef6bb..00000000 --- a/WDL/lice/lice_line.cpp +++ /dev/null @@ -1,1612 +0,0 @@ -#include "lice.h" -#include "lice_combine.h" -#include "lice_extended.h" -#include -#include -//#include - -template inline void SWAP(T& a, T& b) { T tmp = a; a = b; b = tmp; } - -enum { eOK = 0, eXLo = 1, eXHi = 2, eYLo = 4, eYHi = 8 }; - -static int OffscreenTest(int x, int y, int nX, int nY) -{ - int e = eOK; - if (x < 0) e |= eXLo; - else if (x >= nX) e |= eXHi; - if (y < 0) e |= eYLo; - else if (y >= nY) e |= eYHi; - return e; -} - -// Cohen-Sutherland. Returns false if the line is entirely offscreen. -static bool ClipLine(int* pX1, int* pY1, int* pX2, int* pY2, int nX, int nY) -{ - int x1 = *pX1, y1 = *pY1, x2 = *pX2, y2 = *pY2; - int e1 = OffscreenTest(x1, y1, nX, nY); - int e2 = OffscreenTest(x2, y2, nX, nY); - - bool accept = false, done = false; - do - { - if (!(e1 | e2)) { - accept = done = true; - } - else - if (e1 & e2) { - done = true; // Line is entirely offscreen. - } - else { - int x, y; - int eOut = e1 ? e1 : e2; - if (eOut & eYHi) { - x = x1 + (int) ((double) (x2 - x1) * (double) (nY - y1) / (double) (y2 - y1)); - y = nY - 1; - } - else - if (eOut & eYLo) { - x = x1 + (int) ((double) (x2 - x1) * (double) -y1 / (double) (y2 - y1)); - y = 0; - } - else - if (eOut & eXHi) { - y = y1 + (int) ((double) (y2 - y1) * (double) (nX - x1) / (double) (x2 - x1)); - x = nX - 1; - } - else { - y = y1 + (int) ((double) (y2 - y1) * (double) -x1 / (double) (x2 - x1)); - x = 0; - } - - if (eOut == e1) { - x1 = x; - y1 = y; - e1 = OffscreenTest(x1, y1, nX, nY); - } - else { - x2 = x; - y2 = y; - e2 = OffscreenTest(x2, y2, nX, nY); - } - } - } - while (!done); - - *pX1 = x1; - *pY1 = y1; - *pX2 = x2; - *pY2 = y2; - return accept; -} - -static int OffscreenFTest(float x, float y, float w, float h) -{ - int e = eOK; - if (x < 0.0f) e |= eXLo; - else if (x >= w) e |= eXHi; - if (y < 0.0f) e |= eYLo; - else if (y >= h) e |= eYHi; - return e; -} - -static bool ClipFLine(float* x1, float* y1, float* x2, float*y2, int w, int h) -{ - float tx1 = *x1, ty1 = *y1, tx2 = *x2, ty2 = *y2; - float tw = (float)(w-1), th = (float)(h-1); - - int e1 = OffscreenFTest(tx1, ty1, tw, th); - int e2 = OffscreenFTest(tx2, ty2, tw, th); - - bool accept = false, done = false; - do - { - if (!(e1|e2)) - { - accept = done = true; - } - else - if (e1&e2) - { - done = true; // Line is entirely offscreen. - } - else - { - float x, y; - int eOut = (e1 ? e1 : e2); - if (eOut&eYHi) - { - x = tx1+(tx2-tx1)*(th-ty1)/(ty2-ty1); - y = th-1.0f; - } - else if (eOut&eYLo) - { - x = tx1+(tx2-tx1)*ty1/(ty1-ty2); - y = 0.0f; - } - else if (eOut&eXHi) - { - y = ty1+(ty2-ty1)*(tw-tx1)/(tx2-tx1); - x = tw-1.0f; - } - else - { - y = ty1+(ty2-ty1)*tx1/(tx1-tx2); - x = 0.0f; - } - - if (eOut == e1) - { - tx1 = x; - ty1 = y; - e1 = OffscreenFTest(tx1, ty1, tw, th); - } - else - { - tx2 = x; - ty2 = y; - e2 = OffscreenFTest(tx2, ty2, tw, th); - } - } - } - while (!done); - - *x1 = tx1; - *y1 = ty1; - *x2 = tx2; - *y2 = ty2; - return accept; -} - - -inline static void LICE_DiagLineFAST(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, bool aa) -{ - int step = xstep+ystep; - if (aa) - { - LICE_pixel color75 = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); - LICE_pixel color25 = (color>>2)&0x3f3f3f3f; - while (n--) - { - _LICE_CombinePixelsThreeQuarterMix2FAST::doPixFAST(px, color75); - _LICE_CombinePixelsQuarterMix2FAST::doPixFAST(px+xstep, color25); - _LICE_CombinePixelsQuarterMix2FAST::doPixFAST(px+ystep, color25); - px += step; - } - _LICE_CombinePixelsThreeQuarterMix2FAST::doPixFAST(px, color75); - } - else - { - ++n; - while (n--) - { - *px = color; - px += step; - } - } -} - -inline static void LICE_DottedVertLineFAST(LICE_IBitmap* dest, int x, int y1, int y2, LICE_pixel color) -{ - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span+x; - - int n = (y2-y1+1)/2; - while (n--) - { - *px = color; - px += 2*span; - } -} - -// this is the white-color table, doing this properly requires correcting the destination color specifically -#define DO_AA_GAMMA_CORRECT 0 -static unsigned char AA_GAMMA_CORRECT[256] = -{ - // 1.8 gamma - 0,11,17,21,25,28,31,34,37,39,42,44,46,48,50,52,54,56,58,60,61,63,65,67,68,70,71,73,74,76,77,79,80,81,83,84,85,87,88,89,91,92,93,94,96,97,98,99,100,101,103,104,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,132,133,134,135,136,137,138,139,140,141,142,142,143,144,145,146,147,148,149,149,150,151,152,153,154,154,155,156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,170,170,171,172,173,173,174,175,176,176,177,178,179,179,180,181,182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,203,204,204,205,206,206,207,208,208,209,210,210,211,212,212,213,214,214,215,215,216,217,217,218,219,219,220,220,221,222,222,223,224,224,225,225,226,227,227,228,228,229,230,230,231,231,232,233,233,234,234,235,236,236,237,237,238,239,239,240,240,241,241,242,243,243,244,244,245,245,246,247,247,248,248,249,249,250,251,251,252,252,253,253,254,255 - - // 2.0 gamma - //0,15,22,27,31,35,39,42,45,47,50,52,55,57,59,61,63,65,67,69,71,73,74,76,78,79,81,82,84,85,87,88,90,91,93,94,95,97,98,99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,141,142,143,144,145,146,147,148,148,149,150,151,152,153,153,154,155,156,157,158,158,159,160,161,162,162,163,164,165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,177,177,178,179,179,180,181,182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,201,202,203,203,204,205,205,206,206,207,208,208,209,210,210,211,211,212,213,213,214,214,215,216,216,217,217,218,218,219,220,220,221,221,222,222,223,224,224,225,225,226,226,227,228,228,229,229,230,230,231,231,232,233,233,234,234,235,235,236,236,237,237,238,238,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,255 - - // 2.2 gamma - //0,20,28,33,38,42,46,49,52,55,58,61,63,65,68,70,72,74,76,78,80,81,83,85,87,88,90,91,93,94,96,97,99,100,102,103,104,106,107,108,109,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,136,137,138,139,140,141,142,143,144,145,146,147,147,148,149,150,151,152,153,153,154,155,156,157,158,158,159,160,161,162,162,163,164,165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,178,179,180,181,181,182,183,183,184,185,185,186,187,187,188,189,189,190,190,191,192,192,193,194,194,195,196,196,197,197,198,199,199,200,200,201,202,202,203,203,204,205,205,206,206,207,208,208,209,209,210,210,211,212,212,213,213,214,214,215,216,216,217,217,218,218,219,219,220,220,221,222,222,223,223,224,224,225,225,226,226,227,227,228,228,229,229,230,230,231,231,232,232,233,233,234,234,235,235,236,236,237,237,238,238,239,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,249,250,250,251,251,252,252,253,253,254,254,255 - - // 2.6 gamma - //0,30,39,46,51,56,60,63,67,70,73,76,78,81,83,85,87,89,91,93,95,97,99,101,102,104,105,107,109,110,111,113,114,116,117,118,120,121,122,123,125,126,127,128,129,130,131,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,148,149,150,151,152,153,154,155,155,156,157,158,159,160,160,161,162,163,164,164,165,166,167,167,168,169,170,170,171,172,173,173,174,175,175,176,177,177,178,179,179,180,181,181,182,183,183,184,185,185,186,187,187,188,188,189,190,190,191,192,192,193,193,194,195,195,196,196,197,197,198,199,199,200,200,201,201,202,203,203,204,204,205,205,206,206,207,207,208,208,209,210,210,211,211,212,212,213,213,214,214,215,215,216,216,217,217,218,218,219,219,220,220,221,221,222,222,223,223,223,224,224,225,225,226,226,227,227,228,228,229,229,230,230,230,231,231,232,232,233,233,234,234,234,235,235,236,236,237,237,237,238,238,239,239,240,240,240,241,241,242,242,243,243,243,244,244,245,245,245,246,246,247,247,247,248,248,249,249,249,250,250,251,251,251,252,252,253,253,253,254,254,255 -}; - -static void GetAAPxWeight(int err, int alpha, int* wt, int* iwt) -{ - int i = err/256; - int w = 255-i; - -#if DO_AA_GAMMA_CORRECT - w = AA_GAMMA_CORRECT[w]; - i = AA_GAMMA_CORRECT[i]; -#endif - - w = alpha*w/256; - i = alpha*i/256; - *wt = w; - *iwt = i; -} - -static void GetAAPxWeightFAST(int err, int* wt, int* iwt) -{ - int i = err/256; - int w = 255-i; - -#if DO_AA_GAMMA_CORRECT - w = AA_GAMMA_CORRECT[w]; - i = AA_GAMMA_CORRECT[i]; -#endif - - *wt = w; - *iwt = i; -} -template class __LICE_LineClassSimple -{ -public: - static void LICE_VertLineFAST(LICE_pixel *px, int span, int len, LICE_pixel color) - { - while (len--) - { - COMBFUNC::doPixFAST(px, color); - px+=span; - } - } - - static void LICE_HorizLineFAST(LICE_pixel *px, int n, LICE_pixel color) - { - while (n--) - { - COMBFUNC::doPixFAST(px, color); - px++; - } - } - static void LICE_VertLine(LICE_pixel *px, int span, int len, int color, int aw) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - while (len--) - { - COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); - px+=span; - } - } - - static void LICE_HorizLine(LICE_pixel *px, int n, LICE_pixel color, int aw) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - while (n--) - { - COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); - px++; - } - } - static void LICE_DiagLine(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, int aw) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - int step = xstep+ystep; - - for (int i = 0; i <= n; ++i, px += step) - { - COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); - } - } - static void LICE_DiagLineAA(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, int aw) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - int step = xstep+ystep; - -#if DO_AA_GAMMA_CORRECT - int iw = aw*AA_GAMMA_CORRECT[256*3/4]/256; - int dw = aw*AA_GAMMA_CORRECT[256/4]/256; -#else - int iw = aw*3/4; - int dw = aw/4; -#endif - for (int i = 0; i < n; ++i, px += step) - { - COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, iw); - COMBFUNC::doPix((LICE_pixel_chan*) (px+xstep), r, g, b, a, dw); - COMBFUNC::doPix((LICE_pixel_chan*) (px+ystep), r, g, b, a, dw); - } - COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, iw); - } -}; - - -#ifndef LICE_FAVOR_SIZE -template -#endif -class __LICE_LineClass -{ -public: - -#ifdef LICE_FAVOR_SIZE - #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); -#else - #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); -#endif - - static void DashedLine(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int pxon, int pxoff, LICE_pixel color, int aw -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - ) - { - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span+x1; - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - if (x1 == x2) - { - int i, y; - for (y = y1; y < y2-pxon; y += pxon+pxoff) - { - for (i = 0; i < pxon; ++i, px += span) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) - px += pxoff*span; - } - for (i = 0; i < min(pxon, y2-y); px += span) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) - } - else if (y1 == y2) - { - int i, x; - for (x = x1; x < x2-pxon; x += pxon+pxoff) - { - for (i = 0; i < pxon; ++i, ++px) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) - px += pxoff; - } - for (i = 0; i < min(pxon, x2-x); ++px) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) - } - } - - - - - static void LICE_LineImpl(LICE_pixel *px, LICE_pixel *px2, int derr, int astep, int da, int bstep, LICE_pixel color, int aw, bool aa -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - ) - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - int err = 0; - int i; - int n = (da+1)/2; - - if (aa) - { - DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) - DOPIX((LICE_pixel_chan*) px2, r, g, b, a, aw) - px += astep; - px2 -= astep; - err = derr; - - if (aw == 256) - { - for (i = 1; i < n; ++i) - { - int wt, iwt; - GetAAPxWeightFAST(err, &wt, &iwt); - DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) - DOPIX((LICE_pixel_chan*)px2, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px2-bstep), r, g, b, a, iwt) - - err += derr; - if (err >= 65536) - { - px += bstep; - px2 -= bstep; - err -= 65536; - } - px += astep; - px2 -= astep; - } - } - else // alpha<256 - { - for (i = 1; i < n; ++i) - { - int wt, iwt; - GetAAPxWeight(err, aw, &wt, &iwt); - DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) - DOPIX((LICE_pixel_chan*)px2, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px2-bstep), r, g, b, a, iwt) - - err += derr; - if (err >= 65536) - { - px += bstep; - px2 -= bstep; - err -= 65536; - } - px += astep; - px2 -= astep; - } - } - if (!(da%2)) - { - int wt, iwt; - if (aw == 256) GetAAPxWeightFAST(err, &wt, &iwt); - else GetAAPxWeight(err, aw, &wt, &iwt); - DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) - } - } - else // not aa - { - for (i = 0; i < n; ++i) - { - DOPIX((LICE_pixel_chan*)px, r, g, b, a, aw) - DOPIX((LICE_pixel_chan*)px2, r, g, b, a, aw) - err += derr; - if (err >= 65536/2) - { - px += bstep; - px2 -= bstep; - err -= 65536; - } - - px += astep; - px2 -= astep; - } - if (!(da%2)) - { - DOPIX((LICE_pixel_chan*)px, r, g, b, a, aw) - } - } - } - - static void LICE_FLineImpl(LICE_pixel *px, int n , int err, int derr, int astep, int bstep, LICE_pixel color, int aw -#ifdef LICE_FAVOR_SIZE - , LICE_COMBINEFUNC combFunc -#endif - - ) // only does AA - { - int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); - - - int wt, iwt; - int i; - - if (aw == 256) - { - for (i = 0; i <= n; ++i) - { - GetAAPxWeightFAST(err, &wt, &iwt); - DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) - - err += derr; - if (err >= 65536) - { - px += bstep; - err -= 65536; - } - px += astep; - } - } - else // alpha != 256 - { - for (i = 0; i <= n; ++i) - { - GetAAPxWeight(err, aw, &wt, &iwt); - DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) - DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) - - err += derr; - if (err >= 65536) - { - px += bstep; - err -= 65536; - } - px += astep; - } - } - } -#undef DOPIX -}; - - -void LICE_Line(LICE_IBitmap *dest, int x1, int y1, int x2, int y2, LICE_pixel color, float alpha, int mode, bool aa) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_LINE_ACCEL)) - { - LICE_Ext_Line_acceldata data(x1, y1, x2, y2, color, alpha, mode, aa); - if (dest->Extended(LICE_EXT_LINE_ACCEL, &data)) return; - } -#endif - - int w = dest->getWidth(); - int h = dest->getHeight(); - if (dest->isFlipped()) - { - y1 = h-1-y1; - y2 = h-1-y2; - } - - if (ClipLine(&x1, &y1, &x2, &y2, w, h)) - { - int xdiff = x2-x1; - if (y1 == y2) // horizontal line optimizations - { - if (x1 > x2) SWAP(x1, x2); - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span+x1; - int n=x2-x1+1; - - if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) - { - __LICE_LineClassSimple<_LICE_CombinePixelsClobberFAST>::LICE_HorizLineFAST(px, n, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.5f) - { - color = (color>>1)&0x7f7f7f7f; - __LICE_LineClassSimple<_LICE_CombinePixelsHalfMix2FAST>::LICE_HorizLineFAST(px, n, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.25f) - { - color = (color>>2)&0x3f3f3f3f; - __LICE_LineClassSimple<_LICE_CombinePixelsQuarterMix2FAST>::LICE_HorizLineFAST(px, n, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.75f) - { - color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); - __LICE_LineClassSimple<_LICE_CombinePixelsThreeQuarterMix2FAST>::LICE_HorizLineFAST(px, n, color); - } - else - { - int aw = (int)(256.0f*alpha); -#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_HorizLine(px, n, color, aw) - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); -#undef __LICE__ACTION - } - } - else if (!xdiff) // vertical line optimizations - { - if (y1 > y2) SWAP(y1, y2); - int len=y2+1-y1; - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span+x1; - int aw = (int)(256.0f*alpha); - if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) - { - __LICE_LineClassSimple<_LICE_CombinePixelsClobberFAST>::LICE_VertLineFAST(px, span, len, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.5f) - { - color = (color>>1)&0x7f7f7f7f; - __LICE_LineClassSimple<_LICE_CombinePixelsHalfMix2FAST>::LICE_VertLineFAST(px, span, len, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.25f) - { - color = (color>>2)&0x3f3f3f3f; - __LICE_LineClassSimple<_LICE_CombinePixelsQuarterMix2FAST>::LICE_VertLineFAST(px, span, len, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.75f) - { - color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); - __LICE_LineClassSimple<_LICE_CombinePixelsThreeQuarterMix2FAST>::LICE_VertLineFAST(px, span, len, color); - } - else - { -#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_VertLine(px, span, len, color,aw) - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); -#undef __LICE__ACTION - } - } - else if ((xdiff=abs(xdiff)) == abs(y2-y1)) // diagonal line optimizations - { - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span+x1; - int aw = (int)(256.0f*alpha); - int xstep = (x2 > x1 ? 1 : -1); - int ystep = (y2 > y1 ? span : -span); - if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) - { - LICE_DiagLineFAST(px,span, xdiff, xstep, ystep, color, aa); - } - else - { - if (aa) - { -#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_DiagLineAA(px,span, xdiff, xstep, ystep, color, aw) - __LICE_ACTION_NOSRCALPHA(mode, aw, false); -#undef __LICE__ACTION - } - else - { -#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_DiagLine(px,span, xdiff, xstep, ystep, color, aw) - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); -#undef __LICE__ACTION - } - } - } - else - { - - // common set-up for normal line draws - - int span = dest->getRowSpan(); - int aw = (int)(256.0f*alpha); - LICE_pixel* px = dest->getBits()+y1*span+x1; - LICE_pixel* px2 = dest->getBits()+y2*span+x2; - - int da, db; - int astep, bstep; - int dx = x2-x1; - int dy = y2-y1; - - if (abs(dx) > abs(dy)) - { - da = dx; - db = dy; - astep = 1; - bstep = span; - } - else - { - da = dy; - db = dx; - astep = span; - bstep = 1; - } - - if (da < 0) - { - da = -da; - db = -db; - SWAP(px, px2); - } - if (db < 0) - { - db = -db; - bstep = -bstep; - } - - double dbda = (double)db/(double)da; - - int derr = (int)(dbda*65536.0); - -#ifdef LICE_FAVOR_SIZE - - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - -#else - #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::LICE_LineImpl(px,px2, derr, astep, da, bstep, color, aw, aa) -#endif - if (aa) - { - __LICE_ACTION_NOSRCALPHA(mode, aw, false); - } - else - { - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); - } - - #undef __LICE__ACTION - -#ifdef LICE_FAVOR_SIZE - if (blitfunc) __LICE_LineClass::LICE_LineImpl(px,px2, derr, astep, da, bstep, color, aw, aa, blitfunc); -#endif - } - } -} - -void LICE_FLine(LICE_IBitmap* dest, float x1, float y1, float x2, float y2, LICE_pixel color, float alpha, int mode, bool aa) -{ - if (!dest) return; - if (!aa) - { - LICE_Line(dest,(int)x1,(int)y1,(int)x2,(int)y2,color,alpha,mode,false); - return; - } - - int w = dest->getWidth(); - int h = dest->getHeight(); - if (dest->isFlipped()) - { - y1 = (float)(h-1)-y1; - y2 = (float)(h-1)-y2; - } - - if (ClipFLine(&x1, &y1, &x2, &y2, w, h)) - { - if (x1 != x2 || y1 != y2) - { - int span = dest->getRowSpan(); - int aw = (int)(256.0f*alpha); - - float a1, a2, b1, b2, da, db; - int astep, bstep; - float dx = x2-x1; - float dy = y2-y1; - - if (fabs(dx) > fabs(dy)) - { - a1 = x1; - a2 = x2; - b1 = y1; - b2 = y2; - da = dx; - db = dy; - astep = 1; - bstep = span; - } - else - { - a1 = y1; - a2 = y2; - b1 = x1; - b2 = x2; - da = dy; - db = dx; - astep = span; - bstep = 1; - } - - if (da < 0.0f) - { - da = -da; - db = -db; - SWAP(a1, a2); - SWAP(b1, b2); - } - if (db < 0.0f) - { - bstep = -bstep; - } - - int n = (int)(floor(a2)-ceil(a1)); - float dbda = db/da; - - float ta = ceil(a1); - float tb = b1+(ta-a1)*dbda; - float bf = tb-floor(tb); - int err = (int)(bf*65536.0f); - if (bstep < 0) err = 65535-err; - int derr = (int)(fabs(dbda)*65536.0f); - - LICE_pixel* px = dest->getBits()+(int)ta*astep+(int)tb*abs(bstep); - - if (bstep < 0) px -= bstep; - -#ifdef LICE_FAVOR_SIZE - - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - -#else - - #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::LICE_FLineImpl(px,n,err,derr,astep,bstep, color, aw) -#endif - - __LICE_ACTION_NOSRCALPHA(mode, aw, false); - -#ifdef LICE_FAVOR_SIZE - if (blitfunc) __LICE_LineClass::LICE_FLineImpl(px,n,err,derr,astep,bstep, color, aw, blitfunc); -#endif - - #undef __LICE__ACTION - } - } -} - -void LICE_DashedLine(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int pxon, int pxoff, LICE_pixel color, float alpha, int mode, bool aa) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DASHEDLINE_ACCEL)) - { - LICE_Ext_DashedLine_acceldata data(x1, y1, x2, y2, pxon, pxoff, color, alpha, mode, aa); - if (dest->Extended(LICE_EXT_DASHEDLINE_ACCEL, &data)) return; - } -#endif - - int w = dest->getWidth(); - int h = dest->getHeight(); - if (ClipLine(&x1, &y1, &x2, &y2, w, h)) - { - if (y1 > y2) SWAP(y1, y2); - if (pxon == 1 && pxoff == 1 && x1 == x2 && (mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) - { - LICE_DottedVertLineFAST(dest, x1, y1, y2, color); - } - else - { - int aw = (int)(256.0f*alpha); - if (x1 > x2) SWAP(x1, x2); - -#ifdef LICE_FAVOR_SIZE - - LICE_COMBINEFUNC blitfunc=NULL; - #define __LICE__ACTION(comb) blitfunc=comb::doPix; - -#else - - #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::DashedLine(dest, x1, y1, x2, y2, pxon, pxoff, color, aw); -#endif - - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); - -#ifdef LICE_FAVOR_SIZE - if (blitfunc) __LICE_LineClass::DashedLine(dest, x1, y1, x2, y2, pxon, pxoff, color, aw, blitfunc); -#endif - -#undef __LICE__ACTION - } - } -} - -bool LICE_ClipLine(int* pX1, int* pY1, int* pX2, int* pY2, int xLo, int yLo, int xHi, int yHi) -{ - int x1 = *pX1-xLo; - int y1 = *pY1-yLo; - int x2 = *pX2-xLo; - int y2 = *pY2-yLo; - bool onscreen = ClipLine(&x1, &y1, &x2, &y2, xHi-xLo, yHi-yLo); - *pX1 = x1+xLo; - *pY1 = y1+yLo; - *pX2 = x2+xLo; - *pY2 = y2+yLo; - return onscreen; -} - -bool LICE_ClipFLine(float* px1, float* py1, float* px2, float* py2, float xlo, float ylo, float xhi, float yhi) -{ - float x1 = *px1-xlo; - float y1 = *py1-ylo; - float x2 = *px2-xlo; - float y2 = *py2-ylo; - bool onscreen = ClipFLine(&x1, &y1, &x2, &y2, xhi-xlo, yhi-ylo); - *px1 = x1+xlo; - *py1 = y1+ylo; - *px2 = x2+xlo; - *py2 = y2+ylo; - return onscreen; -} - - -#include "lice_bezier.h" - -static void DoBezierFillSegment(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int yfill, LICE_pixel color, float alpha, int mode) -{ - if (x2 < x1) return; - if (x2 == x1) - { - int ylo = min(y1,yfill); - int yhi = max(y2,yfill); - if (yhi != yfill) --yhi; - LICE_Line(dest, x1, ylo, x1, yhi, color, alpha, mode, false); - return; - } - - if ((y1 < yfill) == (y2 < yfill)) - { - if (y1 < yfill) ++yfill; - int x[4] = { x1, x1, x2, x2 }; - int y[4] = { y1, yfill, y2, yfill }; - LICE_FillConvexPolygon(dest, x, y, 4, color, alpha, mode); - } - else - { - int x = x1+(int)((double)(yfill-y1)*(double)(x2-x1)/(double)(y2-y1)); - int yf = yfill; - if (y1 < yfill) ++yf; - LICE_FillTriangle(dest, x1, y1, x1, yf, x, yf, color, alpha, mode); - yf = yfill; - if (y2 < yfill) ++yf; - LICE_FillTriangle(dest, x, yf, x2, yf, x2, y2, color, alpha, mode); - } -} - -static void DoBezierFillSegmentX(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int xfill, LICE_pixel color, float alpha, int mode) -{ - if (y2 < y1) return; - if (y2 == y1) - { - int xlo = min(x1,xfill); - int xhi = max(x2,xfill); - if (xhi != xfill) --xhi; - LICE_Line(dest, xlo, y1, xhi, y1, color, alpha, mode, false); - return; - } - - if ((x1 < xfill) == (x2 < xfill)) - { - if (x1 < xfill) ++xfill; - int x[4] = { x1, xfill, x2, xfill }; - int y[4] = { y1, y1, y2+1, y2+1 }; - LICE_FillConvexPolygon(dest, x, y, 4, color, alpha, mode); - } - else - { - int y = y1+(int)((double)(xfill-x1)*(double)(y2-y1)/(double)(x2-x1)); - int xf = xfill; - if (x1 < xfill) ++xf; - LICE_FillTriangle(dest, x1, y1, xf, y1, xf, y, color, alpha, mode); - xf = xfill; - if (x2 < xfill) ++xf; - LICE_FillTriangle(dest, xf, y, xf, y2, x2, y2, color, alpha, mode); - } -} - - -// quadratic bezier ... NOT TESTED YET -// attempt to draw segments no longer than tol px -void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl, float yctl, float xend, float yend, - LICE_pixel color, float alpha, int mode, bool aa, float tol) -{ - if (!dest) return; - - int w = dest->getWidth(); - - if (xstart > xend) - { - SWAP(xstart, xend); - SWAP(ystart, yend); - } - - double len = sqrt((xctl-xstart)*(xctl-xstart)+(yctl-ystart)*(yctl-ystart)); - len += sqrt((xend-xctl)*(xend-xctl)+(yend-yctl)*(yend-yctl)); - - float xlo = xstart; - float xhi = xend; - float ylo = ystart; - float yhi = yend; - double tlo = 0.0; - double thi = 1.0; - - if (xlo < 0.0f) - { - xlo = 0.0f; - ylo = LICE_Bezier_GetY(xstart, xctl, xend, ystart, yctl, yend, xlo, &tlo); - } - if (xhi >= (float)w) - { - xhi = (float)(w-1); - yhi = LICE_Bezier_GetY(xstart, xctl, xend, ystart, yctl, yend, xhi, &thi); - } - if (xlo > xhi) return; - - len *= (thi-tlo); - if (tol <= 0.0f) tol = 1.0f; - int nsteps = (int)(len/tol); - if (nsteps <= 0) nsteps = 1; - - double dt = (thi-tlo)/(double)nsteps; - double t = tlo+dt; - - float lastx = xlo; - float lasty = ylo; - float x, y; - int i; - for (i = 1; i < nsteps; ++i) - { - LICE_Bezier(xstart, xctl, xend, ystart, yctl, yend, t, &x, &y); - LICE_FLine(dest, lastx, lasty, x, y, color, alpha, mode, aa); - lastx = x; - lasty = y; - t += dt; - } - LICE_FLine(dest, lastx, lasty, xhi, yhi, color, alpha, mode, aa); - -} - -static int CBezPrep(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, float tol, bool xbasis, - double* ax, double* bx, double* cx, double* dx, double* ay, double* by, double* cy, double* dy, - float* xlo, float* xhi, float* ylo, float* yhi, double* tlo, double* thi) -{ - if (!dest) return 0; - - int w = dest->getWidth(); - - if ((xbasis && xstart > xend) || (!xbasis && ystart > yend)) - { - SWAP(xstart, xend); - SWAP(xctl1, xctl2); - SWAP(ystart, yend); - SWAP(yctl1, yctl2); - } - - double len = sqrt((xctl1-xstart)*(xctl1-xstart)+(yctl1-ystart)*(yctl1-ystart)); - len += sqrt((xctl2-xctl1)*(xctl2-xctl1)+(yctl2-yctl1)*(yctl2-yctl1)); - len += sqrt((xend-xctl2)*(xend-xctl2)+(yend-yctl2)*(yend-yctl2)); - - LICE_CBezier_GetCoeffs(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, ax, bx, cx, ay, by, cy); - *dx = xstart; - *dy = ystart; - - *xlo = xstart; - *xhi = xend; - *ylo = ystart; - *yhi = yend; - *tlo = 0.0; - *thi = 1.0; - - if (*xlo < 0.0f) - { - *xlo = 0.0f; - *ylo = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xlo, (float*)0, (float*)0, (double*)0, tlo); - } - if (*xhi > (float)w) - { - *xhi = (float)(w); - *yhi = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xhi, (float*)0, (float*)0, thi, (double*)0); - } - if ((xbasis && *xlo > *xhi) || (!xbasis && *ylo > *yhi)) - { - return 0; - } - - len *= (*thi-*tlo); - if (tol <= 0.0f) tol = 1.0f; - int nsteps = (int)(len/tol); - if (nsteps <= 0) nsteps = 1; - return nsteps; -} - -void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, LICE_pixel color, float alpha, int mode, bool aa, float tol) -{ - if (!dest) return; - -#ifndef DISABLE_LICE_EXTENSIONS - if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWCBEZIER_ACCEL)) - { - LICE_Ext_DrawCBezier_acceldata data(xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, color, alpha, mode, aa); - if (dest->Extended(LICE_EXT_DRAWCBEZIER_ACCEL, &data)) return; - } -#endif - - double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; - double tlo, thi; - int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, - &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); - if (!nsteps) return; - - double dt = (thi-tlo)/(double)nsteps; - double t = tlo+dt; - - float lastx = xlo; - float lasty = ylo; - float x, y; - int i; - for (i = 1; i < nsteps-1; ++i) - { - EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); - LICE_FLine(dest, lastx, lasty, x, y, color, alpha, mode, aa); - lastx = x; - lasty = y; - t += dt; - } - LICE_FLine(dest, lastx, lasty, xhi, yhi, color, alpha, mode, aa); -} - -void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int yfill, LICE_pixel color, float alpha, int mode, float tol) -{ - if (!dest) return; - - double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; - double tlo, thi; - int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, - &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); - if (!nsteps) return; - - double dt = (thi-tlo)/(double)nsteps; - double t = tlo+dt; - - int lastfillx = (int)xlo; - int lastfilly = (int)(ylo+0.5f); - float x, y; - int i; - for (i = 1; i < nsteps-1; ++i) - { - EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); - if ((int)x >= lastfillx) - { - int xi = (int)x; - int yi = (int)(y+0.5f); - DoBezierFillSegment(dest, lastfillx, lastfilly, xi, yi, yfill, color, alpha, mode); - lastfillx = xi+1; - lastfilly = yi; - } - t += dt; - } - if ((int)(xhi-1.0f) >= lastfillx) - { - DoBezierFillSegment(dest, lastfillx, lastfilly, (int)(xhi-1.0f),(int)(yhi+0.5f), yfill, color, alpha, mode); - } -} - -void LICE_FillCBezierX(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int xfill, LICE_pixel color, float alpha, int mode, float tol) -{ - if (!dest) return; - - double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; - double tlo, thi; - int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, false, - &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); - if (!nsteps) return; - - double dt = (thi-tlo)/(double)nsteps; - double t = tlo+dt; - - int lastfillx = (int)(xlo+0.5f); - int lastfilly = (int)ylo; - float x, y; - int i; - for (i = 1; i < nsteps-1; ++i) - { - EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); - if ((int)y >= lastfilly) - { - int xi = (int)(x+0.5f); - int yi = (int)y; - DoBezierFillSegmentX(dest, lastfillx, lastfilly, xi, yi, xfill, color, alpha, mode); - lastfillx = xi; - lastfilly = yi+1; - } - t += dt; - } - if ((int)(yhi-1.0f) >= lastfilly) - { - DoBezierFillSegmentX(dest, lastfillx, lastfilly, (int)(xhi+0.5),(int)(yhi-1.0f), xfill, color, alpha, mode); - } -} - - -void LICE_DrawRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode) -{ - LICE_Line(dest, x, y, x+w, y, color, alpha, mode, false); - LICE_Line(dest, x+w, y, x+w, y+h, color, alpha, mode, false); - LICE_Line(dest, x+w, y+h, x, y+h, color, alpha, mode, false); - LICE_Line(dest, x, y+h, x, y, color, alpha, mode, false); -} - -void LICE_BorderedRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel bgcolor, LICE_pixel fgcolor, float alpha, int mode) -{ - LICE_FillRect(dest, x+1, y+1, w-1, h-1, bgcolor, alpha, mode); - LICE_DrawRect(dest, x, y, w, h, fgcolor, alpha, mode); -} - - -#ifndef LICE_FAVOR_SIZE_EXTREME -template -#endif -class _LICE_Fill -{ - -#ifdef LICE_FAVOR_SIZE_EXTREME - #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); -#else - #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); -#endif - -public: - - // da, db are [0..65536] - static void FillClippedTrapezoid(int wid, int span, LICE_pixel *px, int y, int xa, int xb, int da, int db, int a, int b, int astep, int bstep, int cr, int cg, int cb, int ca, int aw -#ifdef LICE_FAVOR_SIZE_EXTREME - , LICE_COMBINEFUNC combFunc -#endif - ) - { - if (!da && !db) - { - while (y-->0) - { - LICE_pixel* xpx = px; - int x=xb; - while (x--) - { - DOPIX((LICE_pixel_chan*)xpx, cr, cg, cb, ca, aw) - ++xpx; - } - px += span; - } - return; - } - - - while (y-->0) - { - int x1=max(xa,0); - int x2=min(xb,wid); - LICE_pixel* xpx = px + x1; - int cnt=x2-x1; - while (cnt-->0) - { - DOPIX((LICE_pixel_chan*)xpx, cr, cg, cb, ca, aw) - ++xpx; - } - - a += da; - b += db; - if (a >= 65536) - { - int na = a/65536; - a %= 65536; - if (astep<0)na=-na; - xa += na; - } - if (b >= 65536) - { - int nb = b/65536; - b %= 65536; - if (bstep<0)nb=-nb; - xb += nb; - } - px += span; - } - } -}; - - -template class _LICE_FillFast -{ -public: - - // da, db are [0..65536] - static void FillClippedTrapezoidFAST(int wid, int span, LICE_pixel *px, int y, int xa, int xb, int da, int db, int a, int b, int astep, int bstep, LICE_pixel color) - { - if (!da && !db) - { - while (y-->0) - { - LICE_pixel* xpx = px; - int x=xb; - while (x--) - { - COMBFUNC::doPixFAST(xpx, color); - ++xpx; - } - px += span; - } - return; - } - - - while (y-->0) - { - int x1=max(xa,0); - int x2=min(xb,wid); - LICE_pixel* xpx = px + x1; - int cnt=x2-x1; - while (cnt-->0) - { - COMBFUNC::doPixFAST(xpx, color); - ++xpx; - } - - a += da; - b += db; - if (a >= 65536) - { - int na = a/65536; - a %= 65536; - if (astep<0)na=-na; - xa += na; - } - if (b >= 65536) - { - int nb = b/65536; - b %= 65536; - if (bstep<0)nb=-nb; - xb += nb; - } - px += span; - } - } -}; - -static int FindXOnSegment(int x1, int y1, int x2, int y2, int ty) -{ - if (y1 > y2) - { - SWAP(x1, x2); - SWAP(y1, y2); - } - if (ty <= y1) return x1; - if (ty >= y2) return x2; - float dxdy = (float)(x2-x1)/(float)(y2-y1); - return x1+(int)((float)(ty-y1)*dxdy); -} - -static int FindYOnSegment(int x1, int y1, int x2, int y2, int tx) -{ - if (x1 > x2) - { - SWAP(x1, x2); - SWAP(y1, y2); - } - if (tx <= x1) return y1; - if (tx >= x2) return y2; - float dydx = (float)(y2-y1)/(float)(x2-x1); - return y1+(int)((float)(tx-x1)*dydx); -} - -void LICE_FillTrapezoid(LICE_IBitmap* dest, int x1a, int x1b, int y1, int x2a, int x2b, int y2, LICE_pixel color, float alpha, int mode) -{ - if (!dest) return; - if (y1 > y2) - { - SWAP(y1, y2); - SWAP(x1a, x2a); - SWAP(x1b, x2b); - } - if (x1a > x1b) SWAP(x1a, x1b); - if (x2a > x2b) SWAP(x2a, x2b); - - int w = dest->getWidth(); - int h = dest->getHeight(); - - if (x1b < 0 && x2b < 0) return; - if (x1a >= w && x2a >= w) return; - - if (x1a <= 0 && x2a <= 0) x1a = x2a = 0; - if (x1b >= w-1 && x2b >= w-1) x1b = x2b = w-1; - - if (y2 < 0 || y1 >= h) return; - - - int aw = (int)(alpha*256.0f); - - double idy = y2==y1 ? 0.0 : (65536.0/(y2-y1)); - - - const double maxv=(double)(1<<29); - double tmp = (x2a-x1a)*idy; - if (tmp > maxv) tmp=maxv; - else if (tmp < -maxv) tmp=-maxv; - int dxady = (int)tmp; - - tmp = ((x2b-x1b)*idy); - if (tmp > maxv) tmp=maxv; - else if (tmp < -maxv) tmp=-maxv; - int dxbdy = (int)tmp; - - int a = 0; - int b = 0; - int astep = 1; - int bstep = 1; - if (dxady < 0) - { - dxady = -dxady; - astep = -1; - } - if (dxbdy < 0) - { - dxbdy = -dxbdy; - bstep = -1; - } - - if (y1<0) - { - a -= dxady*y1; - b -= dxbdy*y1; - y1=0; - if (a >= 65536) - { - int na = a/65536; - a %= 65536; - if (astep<0)na=-na; - x1a += na; - } - if (b >= 65536) - { - int nb = b/65536; - b %= 65536; - if (bstep<0)nb=-nb; - x1b += nb; - } - } - if (y2 > h-1) y2 = h-1; - - int wid = dest->getWidth(); - int span = dest->getRowSpan(); - LICE_pixel* px = dest->getBits()+y1*span; - int y = y2-y1 + 1; - - x1b++; // from now on draw [x1a,x1b) - - if (!dxady && !dxbdy) - { - if (x1a<0)x1a=0; - x1b = min(x1b,wid)-x1a; - px+=x1a; - if (x1b<1) return; - } - - if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==256) - { - _LICE_FillFast<_LICE_CombinePixelsClobberFAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==128) - { - color = (color>>1)&0x7f7f7f7f; - _LICE_FillFast<_LICE_CombinePixelsHalfMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==64) - { - color = (color>>2)&0x3f3f3f3f; - _LICE_FillFast<_LICE_CombinePixelsQuarterMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); - } - else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==192) - { - color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); - _LICE_FillFast<_LICE_CombinePixelsThreeQuarterMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy,a,b, astep,bstep, color); - } - else - { - int cr = LICE_GETR(color), cg = LICE_GETG(color), cb = LICE_GETB(color), ca = LICE_GETA(color); -#ifdef LICE_FAVOR_SIZE_EXTREME - - LICE_COMBINEFUNC blitfunc=NULL; -#define __LICE__ACTION(comb) blitfunc=comb::doPix; -#else -#define __LICE__ACTION(COMBFUNC) _LICE_Fill::FillClippedTrapezoid(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, cr,cg,cb,ca, aw); -#endif - - __LICE_ACTION_CONSTANTALPHA(mode, aw, false); - -#ifdef LICE_FAVOR_SIZE_EXTREME - if (blitfunc) _LICE_Fill::FillClippedTrapezoid(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, cr,cg,cb,ca, aw, blitfunc); -#endif - -#undef __LICE__ACTION - } -} - - -static int _ysort(const void* a, const void* b) -{ - int* xya = (int*)a; - int* xyb = (int*)b; - if (xya[1] < xyb[1]) return -1; - if (xya[1] > xyb[1]) return 1; - if (xya[0] < xyb[0]) return -1; - if (xya[0] > xyb[0]) return 1; - return 0; -} - -#define _X(i) xy[2*(i)] -#define _Y(i) xy[2*(i)+1] - -static int FindNextEdgeVertex(int* xy, int a, int n, int dir) -{ - bool init = false; - float dxdy_best; - int i, ilo = a; - - for (i = a+1; i < n; ++i) - { - if (_Y(i) == _Y(a)) continue; - float dxdy = (float)(_X(i)-_X(a))/(float)(_Y(i)-_Y(a)); - if (!init || dxdy == dxdy_best || (dir < 0 && dxdy < dxdy_best) || (dir > 0 && dxdy > dxdy_best)) - { - init = true; - ilo = i; - dxdy_best = dxdy; - } - } - return ilo; -} - -void LICE_FillConvexPolygon(LICE_IBitmap* dest, const int* x, const int* y, int npoints, LICE_pixel color, float alpha, int mode) -{ - if (!dest) return; - if (npoints < 3) return; - - int* xy = 0; - int xyt[1024]; // use stack space if small - bool usestack = (npoints <= sizeof(xyt)/sizeof(int)/2); - if (usestack) xy = xyt; - else xy = (int*)malloc(npoints*sizeof(int)*2); - - int i; - { - int min_x=dest->getWidth(),max_x=0; - for (i = 0; i < npoints; ++i) - { - int tx = x[i]; - if (tx < min_x) min_x=tx; - if (tx > max_x) max_x=tx; - _X(i) = tx; - _Y(i) = y[i]; - if (dest->isFlipped()) _Y(i) = dest->getHeight()-_Y(i)-1; - } - qsort(xy, npoints, 2*sizeof(int), _ysort); // sorts by y, at same y sorts by x - - - int ty=_Y(0); - if (ty == _Y(npoints-1)) - { - // special case 1px high polygon - if (ty >= 0 && ty < dest->getHeight() && min_x <= max_x) - { - LICE_FillTrapezoid(dest,min_x,max_x,ty,min_x,max_x,ty,color,alpha,mode); - } - if (!usestack) free(xy); - - return; - } - } - - int a1, b1; // index of previous vertex L and R - int a2, b2; // index of next vertex L and R - int y1; // top and bottom of current trapezoid - - a1 = b1 = 0; - y1 = _Y(0); - - for (i = 1; i < npoints && _Y(i) == y1; ++i) - { - if (_X(i) == _X(0)) a1 = i; - b1 = i; - } - - a2 = FindNextEdgeVertex(xy, a1, npoints, -1); - b2 = FindNextEdgeVertex(xy, b1, npoints, 1); - - while (a1 != a2 || b1 != b2) - { - int y_a2 = _Y(a2); - int y_b2 = _Y(b2); - - int y2 = min(y_a2, y_b2); - int x1a = FindXOnSegment(_X(a1), _Y(a1), _X(a2), y_a2, y1); - int x1b = FindXOnSegment(_X(b1), _Y(b1), _X(b2), y_b2, y1); - int x2a = FindXOnSegment(_X(a1), _Y(a1), _X(a2), y_a2, y2); - int x2b = FindXOnSegment(_X(b1), _Y(b1), _X(b2), y_b2, y2); - - LICE_FillTrapezoid(dest, x1a, x1b, y1, x2a, x2b, y2, color, alpha, mode); - - bool dir = y1<=y2; // should always be true - - y1 = y2; - if (y_a2 == y1) - { - a1 = a2; - a2 = FindNextEdgeVertex(xy, a2, npoints, -1); - } - if (y_b2 == y1) - { - b1 = b2; - b2 = FindNextEdgeVertex(xy, b2, npoints, 1); - } - - if (dir) y1++; - else y1--; - } - - if (!usestack) free(xy); -} - -#undef _X -#undef _Y - - -void LICE_FillTriangle(LICE_IBitmap *dest, int x1, int y1, int x2, int y2, int x3, int y3, LICE_pixel color, float alpha, int mode) -{ - int x[3] = { x1, x2, x3 }; - int y[3] = { y1, y2, y3 }; - LICE_FillConvexPolygon(dest, x, y, 3, color, alpha, mode); -} diff --git a/WDL/lice/lice_lvg.cpp b/WDL/lice/lice_lvg.cpp deleted file mode 100644 index 08a0c453..00000000 --- a/WDL/lice/lice_lvg.cpp +++ /dev/null @@ -1,620 +0,0 @@ -#include "lice.h" -#include -#include -#include "../projectcontext.h" -#include "../lineparse.h" -#include "../ptrlist.h" -#include "../assocarray.h" - -#define PI 3.1415926535897932384626433832795 - -static inline int chartohex(char c) -{ - if (c >= '0' && c<='9') return c-'0'; - else if (c>='A' && c<='F') return 10 + c - 'A'; - else if (c>='a' && c<='f') return 10 + c - 'a'; - return -1; -} -static int __boolval(const char *p, int defval) -{ - if (!stricmp(p,"yes") || - !stricmp(p,"true") || - !stricmp(p,"on") || - atoi(p)>0) return 1; - if (!stricmp(p,"no") || - !stricmp(p,"false") || - !stricmp(p,"off") || - !stricmp(p,"0")) return 0; - return defval; -} - -static LICE_pixel __colorval(const char *p, LICE_pixel def) -{ - int lp = strlen(p); - if (lp == 3) - { - int r = chartohex(p[0]); - int g = chartohex(p[1]); - int b = chartohex(p[2]); - if (r>=0&&g>=0&&b>=0) - def = LICE_RGBA(r+(r<<4),g+(g<<4),b+(b<<4),255); - } - else if (lp == 6||lp==8) - { - int r = chartohex(p[0]), r2 = chartohex(p[1]); - int g = chartohex(p[2]), g2 = chartohex(p[3]); - int b = chartohex(p[4]), b2 = chartohex(p[5]); - int a = 0xf, a2=0xf; - if (lp==8) { a=chartohex(p[6]); a2=chartohex(p[7]); } - if (r>=0&&g>=0&&b>=0&&r2>=0&&g2>=0&&b2>=0&&a>=0&&a2>=0) - def = LICE_RGBA((r<<4)+r2,(g<<4)+g2,(b<<4)+b2,(a<<4)+a2); - } - return def; -} - -class lvgRenderState -{ -public: - lvgRenderState() - { - m_color=LICE_RGBA(255,255,255,255); - m_alpha=1.0f; - m_blend = LICE_BLIT_MODE_COPY; - m_aa = false; - } - ~lvgRenderState() { } - - LICE_pixel m_color; - float m_alpha; - int m_blend; - bool m_aa; - - WDL_TypedBuf m_aa_stack; - WDL_TypedBuf m_alpha_stack; - WDL_TypedBuf m_color_stack; - WDL_TypedBuf m_blend_stack; - -///////// - - void parsealpha(const char *p) - { - int idx=0; - if (*p == '-') idx++; - if (p[idx] == '.' || (p[idx] >= '0' && p[idx] <= '9')) - m_alpha = (float)atof(p); - } - - void parseaa(const char *p) - { - int a = __boolval(p,-1); - if (a>=0) m_aa = !!a; - } - - void parseblend(const char *p) - { - if (!stricmp(p,"copy")) m_blend = LICE_BLIT_MODE_COPY; - else if (!stricmp(p,"add")) m_blend = LICE_BLIT_MODE_ADD; - else if (!stricmp(p,"dodge")) m_blend = LICE_BLIT_MODE_DODGE; - else if (!stricmp(p,"mul")||!stricmp(p,"multiply")) m_blend = LICE_BLIT_MODE_MUL; - else if (!stricmp(p,"overlay")) m_blend = LICE_BLIT_MODE_MUL; - else if (!stricmp(p,"hsvadj")) m_blend = LICE_BLIT_MODE_HSVADJ; - } - - void parsecolor(const char *p) - { - m_color = __colorval(p,m_color); - } - -#define DEF_PUSHPOP(name,defpopval) \ - void push##name() { int sz=m_##name##_stack.GetSize(); m_##name##_stack.Resize(sz+1,false)[sz] = m_##name; } \ - void pop##name() { int sz = m_##name##_stack.GetSize()-1; m_##name = sz>=0 ? m_##name##_stack.Get()[sz] : defpopval; m_##name##_stack.Resize(sz,false); } - DEF_PUSHPOP(color,LICE_RGBA(0,0,0,255)) - DEF_PUSHPOP(alpha,1.0f) - DEF_PUSHPOP(aa,false) - DEF_PUSHPOP(blend,LICE_BLIT_MODE_COPY) -#undef DEF_PUSHPOP - - bool processAttributeLine(LineParser *lp) - { - int i,numtok=lp->getnumtokens(); - switch (lp->gettoken_enum(0,"color\0" - "alpha\0" - "aa\0" - "blend\0" - "\0")) - { -#define PROCTYPE(v,name) \ - case v: for (i=1;igettoken_str(i); \ - if (!stricmp(p,"push")) push##name(); \ - else if (!stricmp(p,"pop")) pop##name(); \ - else parse##name(p); \ - } \ - return true; - - PROCTYPE(0,color) - PROCTYPE(1,alpha) - PROCTYPE(2,aa) - PROCTYPE(3,blend) -#undef PROCTYPE - - } - return false; - } - - -}; - -class lvgImageCtx -{ -public: - lvgImageCtx(lvgImageCtx *par) : m_images(true,deleteThis) - { - m_in_render=false; - m_par=par; - m_cachedImage=0; - m_base_w=0; - m_base_h=0; - } - ~lvgImageCtx() - { - delete m_cachedImage; - m_lines.Empty(true,free); - } - - WDL_PtrList m_lines; - LICE_IBitmap *m_cachedImage; - - lvgImageCtx *m_par; - WDL_StringKeyedArray m_images; - - int m_base_w,m_base_h; - bool m_in_render; - - void render(lvgRenderState *rstate, int wantw, int wanth); - -private: - static void deleteThis(lvgImageCtx *t) { delete t; } - - double parsecoord(const char *p, double scale, bool round) - { - if (!*p) return 0; - if (p[0] == 'a' && p[1]) return atoi(p+1); - if (p[0] == 'w') - { - scale = m_cachedImage ? m_cachedImage->getWidth() : 0.0; - p++; - } - else if (p[0] == 'h') - { - scale = m_cachedImage ? m_cachedImage->getHeight() : 0.0; - p++; - } - return atof(p) * scale + (round ? 0.5 : 0.0); - } - void processLvgLine(LineParser *lp, lvgRenderState *state, LICE_IBitmap *bm, double xscale, double yscale); - -}; - -#define DECL_OPT(type, cfunc) \ - static type getoption_##type(LineParser *lp, int startidx, const char *name, type def) { \ - int namelen = strlen(name); \ - for(;startidxgetnumtokens();startidx++) { \ - const char *p=lp->gettoken_str(startidx); \ - if (!strnicmp(name,p,namelen) && p[namelen]=='=') return cfunc(p+namelen+1,def); \ - } \ - return def; \ - } - -static int __intval(const char *p, int def) { return atoi(p); } -static double __dblval(const char *p, double def) { return atof(p); } - -DECL_OPT(bool,!!__boolval) -DECL_OPT(int,__intval) -DECL_OPT(double,__dblval) -DECL_OPT(LICE_pixel,__colorval) - -#undef DECL_OPT - -void lvgImageCtx::processLvgLine(LineParser *lp, lvgRenderState *state, LICE_IBitmap *bm, double xscale, double yscale) -{ - if (state->processAttributeLine(lp)) return; - - int numtok = lp->getnumtokens(); - const char *tok = lp->gettoken_str(0); - if (!stricmp(tok,"line")) - { - int i; - float lx,ly; - for (i = 1; i < numtok-1; i+= 2) - { - const char *p=lp->gettoken_str(i); - if (strstr(p,"=")) break; - float x=(float)parsecoord(p,xscale,false); - p=lp->gettoken_str(i+1); - if (strstr(p,"=")) break; - float y=(float)parsecoord(p,yscale,false); - - if (i!=1) LICE_FLine(bm,lx,ly,x,y,state->m_color,state->m_alpha,state->m_blend,state->m_aa); - - lx=x; - ly=y; - } - } - else if (!stricmp(tok,"circle")) - { - if (numtok>=4) - { - float x=(float)parsecoord(lp->gettoken_str(1),xscale,false); - float y=(float)parsecoord(lp->gettoken_str(2),yscale,false); - float r=(float)(atof(lp->gettoken_str(3))*min(xscale,yscale)); - if (getoption_bool(lp,1,"fill",false)) - { - LICE_FillCircle(bm,x,y,r,state->m_color,state->m_alpha,state->m_blend,state->m_aa); - } - else - LICE_Circle(bm,x,y,r,state->m_color,state->m_alpha,state->m_blend,state->m_aa); - } - } - else if (!stricmp(tok,"arc")) - { - if (numtok>=6) - { - float x=(float)parsecoord(lp->gettoken_str(1),xscale,false); - float y=(float)parsecoord(lp->gettoken_str(2),yscale,false); - float r=(float)(atof(lp->gettoken_str(3))*min(xscale,yscale)); - float a1=(float)(atof(lp->gettoken_str(4))*PI/180.0); - float a2=(float)(atof(lp->gettoken_str(5))*PI/180.0); - LICE_Arc(bm,x,y,r,a1,a2,state->m_color,state->m_alpha,state->m_blend,state->m_aa); - } - } - else if (!stricmp(tok,"fill")) - { - if (numtok>=3) // fill x y [cmask=xxxxxx kmask=xxxxxxx] - { - LICE_pixel cmask = getoption_LICE_pixel(lp,1,"cmask",LICE_RGBA(255,255,255,0)); - LICE_pixel kmask = getoption_LICE_pixel(lp,1,"kmask",LICE_RGBA(0,0,0,0)); - int x = (int)parsecoord(lp->gettoken_str(1),xscale,true); - int y = (int)parsecoord(lp->gettoken_str(2),yscale,true); - - LICE_SimpleFill(bm,x,y,state->m_color,cmask,kmask); - } - } - else if (!stricmp(tok,"rect")) - { - if (numtok>=5) // rect x y w h [dcdx=xxxxxxxx dcdy=xxxxxxxxx dcdxscale=1.0 dcdyscale=1.0] - { - LICE_pixel dcdx = getoption_LICE_pixel(lp,1,"dcdx",LICE_RGBA(0x80,0x80,0x80,0x80)); - LICE_pixel dcdy = getoption_LICE_pixel(lp,1,"dcdy",LICE_RGBA(0x80,0x80,0x80,0x80)); - double dcdxsc = getoption_double(lp,1,"dcdxscale",1.0); - double dcdysc = getoption_double(lp,1,"dcdyscale",1.0); - - // todo: any options? - int x = (int)parsecoord(lp->gettoken_str(1),xscale,true); - int y = (int)parsecoord(lp->gettoken_str(2),yscale,true); - int w = (int)parsecoord(lp->gettoken_str(3),xscale,true); - int h = (int)parsecoord(lp->gettoken_str(4),yscale,true); - if (w>0 && h>0) - { - if (dcdx!=LICE_RGBA(0x80,0x80,0x80,0x80) || - dcdy!=LICE_RGBA(0x80,0x80,0x80,0x80)) - { - LICE_pixel sc = state->m_color; - dcdxsc /= w*128.0; - dcdysc /= h*128.0; - LICE_GradRect(bm,x,y,w,h, - (float)(LICE_GETR(sc)/255.0), - (float)(LICE_GETG(sc)/255.0), - (float)(LICE_GETB(sc)/255.0), - (float)(LICE_GETA(sc)/255.0*state->m_alpha), - (float)(((int)LICE_GETR(dcdx)-0x80)*dcdxsc), - (float)(((int)LICE_GETG(dcdx)-0x80)*dcdxsc), - (float)(((int)LICE_GETB(dcdx)-0x80)*dcdxsc), - (float)(((int)LICE_GETA(dcdx)-0x80)*dcdxsc), - (float)(((int)LICE_GETR(dcdy)-0x80)*dcdysc), - (float)(((int)LICE_GETG(dcdy)-0x80)*dcdysc), - (float)(((int)LICE_GETB(dcdy)-0x80)*dcdysc), - (float)(((int)LICE_GETA(dcdy)-0x80)*dcdysc), - state->m_blend); - } - else - LICE_FillRect(bm,x,y,w,h,state->m_color,state->m_alpha,state->m_blend); - } - } - } - else if (!stricmp(tok,"rerender")) - { - if (numtok>=2) - { - int forcew=getoption_int(lp,1,"w",0),forceh=getoption_int(lp,1,"h",0); - bool useState=getoption_bool(lp,1,"usestate",false); - - lvgImageCtx *scan = this; - while (scan) - { - lvgImageCtx *p = scan->m_images.Get(lp->gettoken_str(1)); - if (p) - { - if (!p->m_in_render) - { - p->m_in_render=true; - p->render(useState ? state : NULL,forcew,forceh); - p->m_in_render=false; - } - break; - } - scan=scan->m_par; - } - } - } - else if (!stricmp(tok,"blit")) - { - if (numtok>=3) // blit image x y [options] - { - LICE_IBitmap *src=NULL; - lvgImageCtx *scan = this; - const char *rd = lp->gettoken_str(1); - - while (!strnicmp(rd,"parent:",7)) { scan = scan ? scan->m_par : NULL; rd += 7; } - - if (!stricmp(rd,"parent")) - { - if (scan) scan=scan->m_par; - if (scan) src=scan->m_cachedImage; - } - else if (!stricmp(rd,"self")) - { - if (scan) src=scan->m_cachedImage; - } - else while (scan&&!src) - { - lvgImageCtx *p = scan->m_images.Get(rd); - if (p) - { - if (!p->m_cachedImage && !p->m_in_render) - { - p->m_in_render=true; - p->render(NULL,0,0); - p->m_in_render=false; - } - src = p->m_cachedImage; - break; - } - scan=scan->m_par; - } - if (src) - { - int x = (int)parsecoord(lp->gettoken_str(2),xscale,true); - int y = (int)parsecoord(lp->gettoken_str(3),yscale,true); - - // these will be options filter= srcalpha= w= h= scale= - bool filter=getoption_bool(lp,1,"filter",true); - bool usesrcalpha = getoption_bool(lp,1,"srcalpha",true); - int w = getoption_int(lp,1,"w",src->getWidth()); - int h = getoption_int(lp,1,"h",src->getHeight()); - double sc = getoption_double(lp,1,"scale",1.0f); - if (fabs(sc-1.0)>0.0000000001) - { - w = (int)(w*sc+0.5); - h = (int)(h*sc+0.5); - } -// double ang = getoption_double(lp,1,"rotate",0.0) * PI / 180.0; - float sx=(float)getoption_double(lp,1,"srcx",0.0); - float sy=(float)getoption_double(lp,1,"srcy",0.0); - float sw=(float)getoption_double(lp,1,"srcw",src->getWidth()); - float sh=(float)getoption_double(lp,1,"srch",src->getHeight()); -// if (fabs(ang)>0.0001) LICE_RotatedBlit(bm,src,x,y,w,h,sx,sy,sw,sh,ang,true,state->m_alpha,state->m_blend,0,0); - //else - LICE_ScaledBlit(bm,src,x,y,w,h,sx,sy,sw,sh, - state->m_alpha,state->m_blend|(filter ? LICE_BLIT_FILTER_BILINEAR : 0)|(usesrcalpha ? LICE_BLIT_USE_ALPHA : 0)); - } - } - } -} - -void lvgImageCtx::render(lvgRenderState *rstate, int wantw, int wanth) -{ - if (wantw<1) wantw = m_base_w; - if (wanth<1) wanth = m_base_h; - - if (wantw<1||wanth<1) - { - if (m_cachedImage) m_cachedImage->resize(0,0); - return; - } - - if (!m_cachedImage) m_cachedImage = new LICE_MemBitmap(wantw,wanth); - else m_cachedImage->resize(wantw,wanth); - - LICE_Clear(m_cachedImage,LICE_RGBA(0,0,0,0)); - - lvgRenderState rs; - if (rstate) rs = *rstate; - - double xscale = wantw / max(m_base_w,1); - double yscale = wanth / max(m_base_h,1); - int x; - bool comment_state=false; - LineParser lp(comment_state); - for (x=0;x0) - processLvgLine(&lp,&rs,m_cachedImage,xscale,yscale); - } -} - -void *LICE_GetSubLVG(void *lvg, const char *subname) -{ - if (!lvg||!subname||!*subname) return NULL; - lvgImageCtx *t = (lvgImageCtx *)lvg; - return t->m_images.Get(subname); -} - -LICE_IBitmap *LICE_RenderLVG(void *lvg, int reqw, int reqh, LICE_IBitmap *bmOut) -{ - lvgImageCtx *t = (lvgImageCtx *)lvg; - if (!t || !t->m_lines.GetSize() || t->m_in_render) return NULL; - - if (bmOut) - { - delete t->m_cachedImage; - t->m_cachedImage = bmOut; - } - else if (!t->m_cachedImage) t->m_cachedImage = new LICE_MemBitmap; - - t->m_in_render=true; - t->render(NULL,reqw,reqh); - t->m_in_render=false; - - LICE_IBitmap *ret = t->m_cachedImage; - - t->m_cachedImage=NULL; - - return ret; -} - -void LICE_DestroyLVG(void *lvg) -{ - lvgImageCtx *t = (lvgImageCtx *)lvg; - if (t && !t->m_par) delete t; -} - -class lvgRdContext : public ProjectStateContext -{ -public: - lvgRdContext(FILE *fp) { m_fp=fp; } - virtual ~lvgRdContext() { } - - virtual void AddLine(const char *fmt, ...) {}; - virtual int GetLine(char *buf, int buflen) // returns -1 on eof - { - if (!m_fp) return -1; - for (;;) - { - buf[0]=0; - fgets(buf,buflen,m_fp); - if (!buf[0]) return -1; - - char *p=buf; - while (*p) p++; - while (p>buf && (p[-1] == '\r' || p[-1]=='\n')) p--; - *p=0; - if (*buf) return 0; - } - } - - virtual WDL_INT64 GetOutputSize() { return 0; } - virtual int GetTempFlag() { return 0; } - virtual void SetTempFlag(int flag) {} - - FILE *m_fp; -}; - -void *LICE_LoadLVGFromContext(ProjectStateContext *ctx, const char *nameInfo, int defw, int defh) -{ - if (!ctx) return NULL; - - bool err=false; - int ignoreBlockCnt=0; - - lvgImageCtx *retimg = new lvgImageCtx(NULL); - lvgImageCtx *curimg = NULL; - - if (nameInfo) - { - curimg = retimg; - curimg->m_base_w = defw; - curimg->m_base_h = defh; - } - - while (!err) - { - char line[4096]; - line[0]=0; - if (ctx->GetLine(line,sizeof(line))) break; - - char *p=line; - while (*p == ' ' || *p == '\t') p++; - if (!*p) continue; - - if (ignoreBlockCnt>0) - { - if (*p == '<') ignoreBlockCnt++; - else if (*p == '>') ignoreBlockCnt--; - } - else - { - if (*p == '<') - { - bool comment_state=false; - LineParser lp(comment_state); - if (!lp.parse(p)&&lp.getnumtokens()>=2 && !strcmp(lp.gettoken_str(0),"m_images.Insert(lp.gettoken_str(1),p); - curimg = p; - } - curimg->m_base_w = lp.gettoken_int(2); - curimg->m_base_h = lp.gettoken_int(3); - } - else ignoreBlockCnt++; - } - else if (curimg) - { - if (*p == '>') - { - curimg = curimg->m_par; - if (!curimg) break; // success! - } - else - { - curimg->m_lines.Add(strdup(p)); - } - } - - if (!curimg) err=true; // 24-bit RGB) - -struct ONode -{ - WDL_INT64 colorcount; // number of color instances at or below this node - WDL_INT64 sumrgb[3]; - int childflag; // 0=leaf, >0=index of single child, <0=branch - int leafidx; // populated at the end - ONode* next; // for OTree::branches - ONode* children[8]; -}; - -struct OTree -{ - int maxcolors; - int leafcount; - ONode* trunk; - ONode* branches[OCTREE_DEPTH]; // linked lists of branches for each level of the tree - LICE_pixel* palette; // populated at the end -}; - - - -int LICE_BuildPalette(LICE_IBitmap* bmp, LICE_pixel* palette, int maxcolors) -{ - void* tree = LICE_CreateOctree(maxcolors); - LICE_BuildOctree(tree, bmp); - int sz = LICE_ExtractOctreePalette(tree, palette); - LICE_DestroyOctree(tree); - return sz; -} - - -static void AddColorToTree(OTree*, unsigned char rgb[]); -static int FindColorInTree(OTree*, unsigned char rgb[]); -static int PruneTree(OTree*); -static void DeleteNode(OTree*, ONode*); -static int CollectLeaves(OTree*); -static int CollectNodeLeaves(ONode* node, LICE_pixel* palette, int colorcount); - - -void* LICE_CreateOctree(int maxcolors) -{ - OTree* tree = new OTree; - memset(tree, 0, sizeof(OTree)); - tree->maxcolors = maxcolors; - tree->trunk = new ONode; - memset(tree->trunk, 0, sizeof(ONode)); - return tree; -} - - -void LICE_DestroyOctree(void* octree) -{ - OTree* tree = (OTree*)octree; - DeleteNode(tree, tree->trunk); - free(tree->palette); - delete tree; -} - - -int LICE_BuildOctree(void* octree, LICE_IBitmap* bmp) -{ - OTree* tree = (OTree*)octree; - if (!tree) return 0; - - if (tree->palette) - { - free(tree->palette); - tree->palette=0; - } - - int x, y; - for (y = 0; y < bmp->getHeight(); ++y) - { - LICE_pixel* px = bmp->getBits()+y*bmp->getRowSpan(); - for (x = 0; x < bmp->getWidth(); ++x) - { - unsigned char rgb[3] = { LICE_GETR(px[x]), LICE_GETG(px[x]), LICE_GETB(px[x]) }; - AddColorToTree(tree, rgb); - if (tree->leafcount > tree->maxcolors) PruneTree(tree); - } - } - - return tree->leafcount; -} - - -int LICE_FindInOctree(void* octree, LICE_pixel color) -{ - OTree* tree = (OTree*)octree; - if (!tree) return 0; - - if (!tree->palette) CollectLeaves(tree); - - unsigned char rgb[3] = { LICE_GETR(color), LICE_GETG(color), LICE_GETB(color) }; - return FindColorInTree(tree, rgb); -} - - -int LICE_ExtractOctreePalette(void* octree, LICE_pixel* palette) -{ - OTree* tree = (OTree*)octree; - if (!tree || !palette) return 0; - - if (!tree->palette) CollectLeaves(tree); - - memcpy(palette, tree->palette, tree->maxcolors*sizeof(LICE_pixel)); - return tree->leafcount; -} - - - -void LICE_TestPalette(LICE_IBitmap* bmp, LICE_pixel* palette, int numcolors) -{ - int x, y; - for (y = 0; y < bmp->getHeight(); ++y) - { - LICE_pixel* px = bmp->getBits()+y*bmp->getRowSpan(); - for (x = 0; x < bmp->getWidth(); ++x) - { - unsigned char rgb[3] = { LICE_GETR(px[x]), LICE_GETG(px[x]), LICE_GETB(px[x]) }; - - int minerr; - int bestcol=-1; - int i; - for (i = 0; i < numcolors; ++i) - { - LICE_pixel palcol = palette[i]; - int rerr[3] = { rgb[0]-LICE_GETR(palcol), rgb[1]-LICE_GETG(palcol), rgb[2]-LICE_GETB(palcol) }; - int err = rerr[0]*rerr[0]+rerr[1]*rerr[1]+rerr[2]*rerr[2]; - if (bestcol < 0 || err < minerr) - { - bestcol=i; - minerr=err; - } - } - px[x] = palette[bestcol]; - } - } -} - - -void AddColorToTree(OTree* tree, unsigned char rgb[3]) -{ - ONode* p = tree->trunk; - p->colorcount++; - - int i; - for (i = OCTREE_DEPTH-1; i >= 0; --i) - { - int j = i+8-OCTREE_DEPTH; - unsigned char idx = (((rgb[0]>>(j-2))&4))|(((rgb[1]>>(j-1))&2))|((rgb[2]>>j)&1); - - ONode* np = p->children[idx]; - bool isleaf = false; - - if (np) - { - isleaf = !np->childflag; - } - else // add node - { - if (!p->childflag) // first time down this path - { - p->childflag=idx+1; - } - else if (p->childflag > 0) // creating a new branch - { - p->childflag = -1; - p->next = tree->branches[i]; - tree->branches[i] = p; - } - // else multiple branch, which we don't care about - - np = p->children[idx] = new ONode; - memset(np, 0, sizeof(ONode)); - } - - np->sumrgb[0] += rgb[0]; - np->sumrgb[1] += rgb[1]; - np->sumrgb[2] += rgb[2]; - np->colorcount++; - - if (isleaf) return; - - p=np; // continue downward - } - - // p is a new leaf at the bottom - tree->leafcount++; -} - -int FindColorInTree(OTree* tree, unsigned char rgb[3]) -{ - ONode* p = tree->trunk; - - int i; - for (i = OCTREE_DEPTH-1; i >= 0; --i) - { - if (!p->childflag) break; - - int j = i+8-OCTREE_DEPTH; - unsigned char idx = (((rgb[0]>>(j-2))&4))|(((rgb[1]>>(j-1))&2))|((rgb[2]>>j)&1); - - ONode* np = p->children[idx]; - if (!np) break; - - p = np; - } - - return p->leafidx; -} - - -int PruneTree(OTree* tree) -{ - ONode* branch=0; - int i; - for (i = 0; i < OCTREE_DEPTH; ++i) // prune at the furthest level from the trunk - { - branch = tree->branches[i]; - if (branch) - { - tree->branches[i] = branch->next; - branch->next=0; - break; - } - } - - if (branch) - { - int i; - for (i = 0; i < 8; ++i) - { - if (branch->children[i]) - { - DeleteNode(tree, branch->children[i]); - branch->children[i]=0; - } - } - branch->childflag=0; // now it's a leaf - tree->leafcount++; - } - - return tree->leafcount; -} - -int CollectLeaves(OTree* tree) -{ - if (tree->palette) free(tree->palette); - tree->palette = (LICE_pixel*)malloc(tree->maxcolors*sizeof(LICE_pixel)); - - int sz = CollectNodeLeaves(tree->trunk, tree->palette, 0); - memset(tree->palette+sz, 0, (tree->maxcolors-sz)*sizeof(LICE_pixel)); - - return sz; -} - -int CollectNodeLeaves(ONode* p, LICE_pixel* palette, int colorcount) -{ - if (!p->childflag) - { - p->leafidx = colorcount; - int r = (int)((double)p->sumrgb[0]/(double)p->colorcount); - int g = (int)((double)p->sumrgb[1]/(double)p->colorcount); - int b = (int)((double)p->sumrgb[2]/(double)p->colorcount); - palette[colorcount++] = LICE_RGBA(r, g, b, 255); - } - else - { - if (p->childflag > 0) - { - colorcount = CollectNodeLeaves(p->children[p->childflag-1], palette, colorcount); - } - else - { - int i; - for (i = 0; i < 8; ++i) - { - if (p->children[i]) - { - colorcount = CollectNodeLeaves(p->children[i], palette, colorcount); - } - } - } - // this is a branch or passthrough node, record the index - // of any downtree leaf here so that we can return it for - // color lookups that want to diverge off this node - p->leafidx = colorcount-1; - } - - // colorcount should == leafcount - return colorcount; -} - - -void DeleteNode(OTree* tree, ONode* p) -{ - if (!p->childflag) - { - tree->leafcount--; - } - else if (p->childflag > 0) - { - DeleteNode(tree, p->children[p->childflag-1]); - } - else - { - int i; - for (i = 0; i < 8; ++i) - { - if (p->children[i]) - { - DeleteNode(tree, p->children[i]); - } - } - } - - delete p; -} - diff --git a/WDL/lice/lice_pcx.cpp b/WDL/lice/lice_pcx.cpp deleted file mode 100644 index f14b4a66..00000000 --- a/WDL/lice/lice_pcx.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_pcx.cpp (PCX loading for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" - - -#include - -// note: you'd never really want to use PCX files, but in case you do... - -LICE_IBitmap *LICE_LoadPCX(const char *filename, LICE_IBitmap *_bmp) -{ - FILE *fp = fopen(filename,"rb"); - if(!fp) return 0; - - fgetc(fp); - if (fgetc(fp) != 5) { fclose(fp); return NULL; } - if (fgetc(fp) != 1) { fclose(fp); return NULL; } - if (fgetc(fp) != 8) { fclose(fp); return NULL; } - - int sx = fgetc(fp); sx += fgetc(fp)<<8; - int sy = fgetc(fp); sy += fgetc(fp)<<8; - int ex = fgetc(fp); ex += fgetc(fp)<<8; - int ey = fgetc(fp); ey += fgetc(fp)<<8; - - - unsigned char pal[768]; - fseek(fp,-769,SEEK_END); - if (fgetc(fp) != 12) { fclose(fp); return NULL; } - fread(pal,1,768,fp); - if (feof(fp)) { fclose(fp); return NULL; } - - - LICE_IBitmap *usebmp = NULL; - if (_bmp) (usebmp=_bmp)->resize(ex-sx+1,ey-sy+1); - else usebmp = new LICE_MemBitmap(ex-sx+1,ey-sy+1); - - fseek(fp,128,SEEK_SET); - - LICE_Clear(usebmp,0); - int y = usebmp->getHeight(); - int w = usebmp->getWidth(); - int rowspan = usebmp->getRowSpan(); - LICE_pixel *pout = usebmp->getBits(); - if (usebmp->isFlipped()) - { - pout += rowspan*(y-1); - rowspan=-rowspan; - } - while (y--) - { - int xpos = 0; - while (xpos < w) - { - int c = fgetc(fp); - if (c&~255) break; - if ((c & 192) == 192) - { - int oc = (fgetc(fp))&255; - LICE_pixel t=LICE_RGBA(pal[oc*3],pal[oc*3+1],pal[oc*3+2],255); - - c&=63; - while (c-- && xposfilename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".pcx")) return 0; - } - return LICE_LoadPCX(filename,bmpbase); - } - static const char *get_extlist() - { - return "PCX files (*.PCX)\0*.PCX\0"; - } - -}; - -LICE_PCXLoader LICE_pcxldr; \ No newline at end of file diff --git a/WDL/lice/lice_png.cpp b/WDL/lice/lice_png.cpp deleted file mode 100644 index 16916531..00000000 --- a/WDL/lice/lice_png.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_png.cpp (PNG loading for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" - - -#include -#include "../libpng/png.h" - -#ifdef __APPLE__ -#include // for loading images from embedded resource -#endif - - -LICE_IBitmap *LICE_LoadPNG(const char *filename, LICE_IBitmap *bmp) -{ - FILE *fp = NULL; -#ifdef _WIN32 - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - fp = _wfopen(wf,L"rb"); - } -#endif - - if (!fp) fp = fopen(filename,"rb"); - if(!fp) return 0; - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if(!png_ptr) - { - fclose(fp); - return 0; - } - - png_infop info_ptr = png_create_info_struct(png_ptr); - if(!info_ptr) - { - png_destroy_read_struct(&png_ptr, NULL, NULL); - fclose(fp); - return 0; - } - - if (setjmp(png_jmpbuf(png_ptr))) - { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - fclose(fp); - return 0; - } - - png_init_io(png_ptr, fp); - - png_read_info(png_ptr, info_ptr); - - unsigned int width, height; - int bit_depth, color_type, interlace_type, compression_type, filter_method; - png_get_IHDR(png_ptr, info_ptr, &width, &height, - &bit_depth, &color_type, &interlace_type, - &compression_type, &filter_method); - - //convert whatever it is to RGBA - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png_ptr); - - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand_gray_1_2_4_to_8(png_ptr); - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - { - png_set_tRNS_to_alpha(png_ptr); - color_type |= PNG_COLOR_MASK_ALPHA; - } - - if (bit_depth == 16) - png_set_strip_16(png_ptr); - - if (bit_depth < 8) - png_set_packing(png_ptr); - - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png_ptr); - - if (color_type & PNG_COLOR_MASK_ALPHA) - png_set_swap_alpha(png_ptr); - else - png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); - - //get the bits - if (bmp) - { - bmp->resize(width,height); - if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) - { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(fp); - return 0; - } - } - else bmp=new LICE_MemBitmap(width,height); - - unsigned char **row_pointers=(unsigned char **)malloc(height*sizeof(unsigned char *));; - LICE_pixel *bmpptr = bmp->getBits(); - int dbmpptr=bmp->getRowSpan(); - if (bmp->isFlipped()) - { - bmpptr += dbmpptr*(bmp->getHeight()-1); - dbmpptr=-dbmpptr; - } - unsigned int i; - for(i=0;i0) - { - unsigned char a = bmpptr[0]; - unsigned char r = bmpptr[1]; - unsigned char g = bmpptr[2]; - unsigned char b = bmpptr[3]; - ((LICE_pixel*)bmpptr)[0] = LICE_RGBA(r,g,b,a); - bmpptr+=4; - } - } - #endif - free(row_pointers); - - return bmp; -} - -typedef struct -{ - unsigned char *data; - int len; -} pngReadStruct; - -static void staticPngReadFunc(png_structp png_ptr, png_bytep data, png_size_t length) -{ - pngReadStruct *readStruct = (pngReadStruct *)png_get_io_ptr(png_ptr); - memset(data, 0, length); - - int l = min((int)length, readStruct->len); - memcpy(data, readStruct->data, l); - readStruct->data += l; - readStruct->len -= l; -} - -#ifndef _WIN32 -LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success -{ - char buf[2048]; - buf[0]=0; - if (strlen(name)>400) return NULL; // max name for this is 400 chars - -#ifdef __APPLE__ - CFBundleRef bund = CFBundleGetMainBundle(); - if (bund) - { - CFURLRef url=CFBundleCopyBundleURL(bund); - if (url) - { - CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf)-512); - CFRelease(url); - } - } - if (!buf[0]) return 0; - strcat(buf,"/Contents/Resources/"); -#else - char tmp[64]; - sprintf(tmp,"/proc/%d/exe",getpid()); - int sz = readlink(tmp, buf, sizeof(buf)-512); - if (sz<0) sz=0; - else if (sz >= sizeof(buf)-512) sz = sizeof(buf)-512-1; - buf[sz]=0; - char *p = buf; - while (*p) p++; - while (p > buf && *p != '/') p--; - *p=0; - strcat(buf,"/Resources/"); -#endif // !__APPLE__ - - strcat(buf,name); - return LICE_LoadPNG(buf,bmp); -} -#endif - -LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitmap *bmp) -{ - if (buflen<8) return NULL; - unsigned char *data = (unsigned char *)(void*)data_in; - if(png_sig_cmp(data, 0, 8)) return NULL; - - pngReadStruct readStruct = {data, buflen}; - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if(!png_ptr) - { - return 0; - } - - png_infop info_ptr = png_create_info_struct(png_ptr); - if(!info_ptr) - { - png_destroy_read_struct(&png_ptr, NULL, NULL); - return 0; - } - - if (setjmp(png_jmpbuf(png_ptr))) - { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return 0; - } - - png_set_read_fn(png_ptr, &readStruct, staticPngReadFunc); - - png_read_info(png_ptr, info_ptr); - - unsigned int width, height; - int bit_depth, color_type, interlace_type, compression_type, filter_method; - png_get_IHDR(png_ptr, info_ptr, &width, &height, - &bit_depth, &color_type, &interlace_type, - &compression_type, &filter_method); - - //convert whatever it is to RGBA - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png_ptr); - - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand_gray_1_2_4_to_8(png_ptr); - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - { - png_set_tRNS_to_alpha(png_ptr); - color_type |= PNG_COLOR_MASK_ALPHA; - } - - if (bit_depth == 16) - png_set_strip_16(png_ptr); - - if (bit_depth < 8) - png_set_packing(png_ptr); - - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png_ptr); - - if (color_type & PNG_COLOR_MASK_ALPHA) - png_set_swap_alpha(png_ptr); - else - png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); - - //get the bits - if (bmp) - { - bmp->resize(width,height); - if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) - { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - return 0; - } - } - else bmp=new LICE_MemBitmap(width,height); - - unsigned char **row_pointers=(unsigned char **)malloc(height*sizeof(unsigned char *));; - LICE_pixel *bmpptr = bmp->getBits(); - int dbmpptr=bmp->getRowSpan(); - unsigned int i; - for(i=0;i0) - { - unsigned char a = bmpptr[0]; - unsigned char r = bmpptr[1]; - unsigned char g = bmpptr[2]; - unsigned char b = bmpptr[3]; - ((LICE_pixel*)bmpptr)[0] = LICE_RGBA(r,g,b,a); - bmpptr+=4; - } - } - #endif - free(row_pointers); - return bmp; -} -LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) -{ -#ifdef _WIN32 - HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "PNG"); - if(!hResource) return NULL; - - DWORD imageSize = SizeofResource(hInst, hResource); - if(imageSize < 8) return NULL; - - HGLOBAL res = LoadResource(hInst, hResource); - const void* pResourceData = LockResource(res); - if(!pResourceData) return NULL; - - LICE_IBitmap * ret = LICE_LoadPNGFromMemory(pResourceData,imageSize,bmp); - - // todo : cleanup res?? - - return ret; -#else - return 0; -#endif -} - - -class LICE_PNGLoader -{ -public: - _LICE_ImageLoader_rec rec; - LICE_PNGLoader() - { - rec.loadfunc = loadfunc; - rec.get_extlist = get_extlist; - rec._next = LICE_ImageLoader_list; - LICE_ImageLoader_list = &rec; - } - - static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) - { - if (checkFileName) - { - const char *p=filename; - while (*p)p++; - while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; - if (stricmp(p,".png")) return 0; - } - return LICE_LoadPNG(filename,bmpbase); - } - static const char *get_extlist() - { - return "PNG files (*.PNG)\0*.PNG\0"; - } - -}; - -LICE_PNGLoader LICE_pngldr; diff --git a/WDL/lice/lice_png_write.cpp b/WDL/lice/lice_png_write.cpp deleted file mode 100644 index bb4e2af1..00000000 --- a/WDL/lice/lice_png_write.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_png_write.cpp (PNG saving for LICE) - See lice.h for license and other information -*/ - -#include "lice.h" - - -#include -#include "../libpng/png.h" - - -bool LICE_WritePNG(const char *filename, LICE_IBitmap *bmp, bool wantalpha /*=true*/) -{ - if (!bmp || !filename) return false; - /* - ** Joshua Teitelbaum 1/1/2008 - ** Gifted to cockos for toe nail clippings. - ** - ** JF> tweaked some - */ - png_structp png_ptr=NULL; - png_infop info_ptr=NULL; - unsigned char *rowbuf=NULL; - - FILE *fp=NULL; -#ifdef _WIN32 - if (GetVersion()<0x80000000) - { - WCHAR wf[2048]; - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) - fp = _wfopen(wf,L"wb"); - } -#endif - if (!fp) fp = fopen(filename,"wb"); - - if (fp == NULL) return false; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL); - - if (png_ptr == NULL) { - fclose(fp); - return false; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - fclose(fp); - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - return false; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - /* If we get here, we had a problem reading the file */ - if (fp) fclose(fp); - fp=0; - free(rowbuf); - rowbuf=0; - png_destroy_write_struct(&png_ptr, &info_ptr); - return false; - } - - - png_init_io(png_ptr, fp); - int width=bmp->getWidth(); - int height = bmp->getHeight(); - -#define BITDEPTH 8 - png_set_IHDR(png_ptr, info_ptr, width, height, BITDEPTH, wantalpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_write_info(png_ptr, info_ptr); - - png_set_bgr(png_ptr); - - // kill alpha channel bytes if not wanted - if (!wantalpha) png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - - LICE_pixel *ptr=(LICE_pixel *)bmp->getBits(); - int rowspan=bmp->getRowSpan(); - if (bmp->isFlipped()) - { - ptr+=rowspan*(bmp->getHeight()-1); - rowspan=-rowspan; - } - - - if (LICE_PIXEL_B != 0 || LICE_PIXEL_G != 1 || LICE_PIXEL_R != 2 || LICE_PIXEL_A != 3) - { - rowbuf=(unsigned char *)malloc(width*4); - int k; - for (k = 0; k < height; k++) - { - int x; - unsigned char *bout = rowbuf; - LICE_pixel_chan *bin = (LICE_pixel_chan *) ptr; - for(x=0;x -#include -#include - -#include "../tinyxml/tinyxml.h" -#include "../wdlcstring.h" - -extern "C" int LICE_RGBA_from_SVG(const char* s, int len); - - -const double SVG_ID_MAT[6] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 }; // acebdf -const int SVG_MAT_SZ = sizeof(SVG_ID_MAT); - -#define SVGINT(x) ((int)(x+0.5)) - -static void SVGMSet(double m[], double a, double b, double c, double d, double e, double f) -{ - m[0] = a; - m[3] = b; - m[1] = c; - m[4] = d; - m[2] = e; - m[5] = f; -} - -static void SVGMMult(double m[], double a, double b, double c, double d, double e, double f) -{ - SVGMSet(m, - m[0]*a+m[1]*b, // 0 - m[3]*a+m[4]*b, // 3 - m[0]*c+m[1]*d, // 1 - m[3]*c+m[4]*d, // 4 - m[0]*e+m[1]*f+m[2], // 2 - m[3]*e+m[4]*f+m[5]); // 5 -} - -static void SVGMTransform(double m[], double* x, double* y) -{ - if (memcmp(m, SVG_ID_MAT, SVG_MAT_SZ)) - { - double tx = *x; - double ty = *y; - *x = tx*m[0]+ty*m[1]+m[2]; - *y = tx*m[3]+ty*m[4]+m[5]; - } -} - -static void SVGMScale(double m[], double* w, double* h) -{ - if (memcmp(m, SVG_ID_MAT, SVG_MAT_SZ)) - { - *w *= m[0]; - *h *= m[4]; - } -} - -static void SVGDrawLine(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, LICE_pixel color, float alpha, bool aa, int linewid=1) -{ - int i; - for (i = 0; i < linewid; ++i) - { - LICE_FLine(bmp, x1, y1, x2, y2, color, alpha, LICE_BLIT_MODE_COPY, aa); - - if (fabs(y2-y1) > fabs(x2-x1)) - { - x1 += 1.0; - x2 += 1.0; - } - else - { - y1 += 1.0; - y2 += 1.0; - } - } -} - -static void SVGDrawRect(LICE_IBitmap* bmp, double x, double y, int w, int h, LICE_pixel color, float alpha, int linewid=1) -{ - int xi = SVGINT(x), yi = SVGINT(y); - int wi = SVGINT(w), hi = SVGINT(h); - - int i; - for (i = 0; i < linewid; ++i) - { - LICE_DrawRect(bmp, xi, yi, wi, hi, color, alpha, LICE_BLIT_MODE_COPY); - ++xi; - ++yi; - } -} - -static void SVGDrawCircle(LICE_IBitmap* bmp, double cx, double cy, double r, LICE_pixel color, float alpha, bool aa, int linewid=1) -{ - int i; - for (i = 0; i < linewid; ++i) - { - LICE_Circle(bmp, cx, cy, r, color, alpha, LICE_BLIT_MODE_COPY, aa); - r += 1.0f; - } -} - -static void SVGDrawQBezier(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, double x3, double y3, - LICE_pixel color, float alpha, bool aa, int linewid=1) -{ - int i; - for (i = 0; i < linewid; ++i) - { - LICE_DrawQBezier(bmp, x1, y1, x2, y2, x3, y3, color, alpha, LICE_BLIT_MODE_COPY, aa); - - if (fabs(y3-y1) > fabs(x3-x1)) - { - x1 += 1.0; - x2 += 1.0; - x3 += 1.0; - } - else - { - y1 += 1.0; - y2 += 1.0; - y3 += 1.0; - } - } -} - -static void SVGDrawCBezier(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, - LICE_pixel color, float alpha, bool aa, int linewid=1) -{ - int i; - for (i = 0; i < linewid; ++i) - { - LICE_DrawCBezier(bmp, x1, y1, x2, y2, x3, y3, x4, y4, color, alpha, LICE_BLIT_MODE_COPY, aa); - - if (fabs(y4-y1) > fabs(x4-x1)) - { - x1 += 1.0; - x2 += 1.0; - x3 += 1.0; - x4 += 1.0; - } - else - { - y1 += 1.0; - y2 += 1.0; - y3 += 1.0; - y4 += 1.0; - } - } -} - -class LICE_SVGState -{ -public: - - LICE_IBitmap* m_bmp; - LICE_IBitmap* m_tmpbmp; - double m_x, m_y; - - LICE_pixel m_strokecolor; - float m_strokealpha; - int m_strokewidth; - - LICE_pixel m_fillcolor; - float m_fillalpha; - - LICE_CachedFont* m_font; - LOGFONT m_logfont; - bool m_fontdirty; - int m_textflags; - - double m_ctm[6]; // current transform matrix - - LICE_SVGState(LICE_IBitmap* bmp); - ~LICE_SVGState(); - - void SetXY(double x, double y); - - void DrawText(LICE_IBitmap* bmp, const char* str); - - bool ParseNode(TiXmlNode* xmlnode); - bool ParseLine(TiXmlElement* xmlelem); - bool ParseRect(TiXmlElement* xmlelem); - bool ParseCircle(TiXmlElement* xmlelem); - bool ParsePolyline(TiXmlElement* xmlelem, bool close); - bool ParseText(TiXmlElement* xmlelem); - - bool ParsePosition(TiXmlElement* xmlelem); - bool ParseTransform(TiXmlElement* xmlelem, double prevctm[]); - bool ParseColor(TiXmlElement* xmlelem); - bool ParseFont(TiXmlElement* xmlelem); - - bool ParsePath(TiXmlElement* xmlelem); -}; - - -LICE_SVGState::LICE_SVGState(LICE_IBitmap* bmp) -{ - m_bmp = bmp; - m_tmpbmp = 0; - - m_x = 0.0; - m_y = 0.0; - - m_strokecolor = 0; - m_strokealpha = 1.0f; - m_strokewidth = 1; - - m_fillcolor = 0; - m_fillalpha = 1.0f; - - m_font = 0; - memset(&m_logfont, 0, sizeof(LOGFONT)); - m_fontdirty = true; - m_textflags = 0; - - memcpy(m_ctm, SVG_ID_MAT, SVG_MAT_SZ); -} - -LICE_SVGState::~LICE_SVGState() -{ - delete(m_tmpbmp); - delete(m_font); -} - -void LICE_SVGState::SetXY(double x, double y) -{ - m_x = x; - m_y = y; -} - -void LICE_SVGState::DrawText(LICE_IBitmap* bmp, const char* str) -{ - if (!m_font) m_font = new LICE_CachedFont; - - if (m_fontdirty) - { - m_fontdirty = false; - HFONT hf = CreateFontIndirect(&m_logfont); - m_font->SetFromHFont(hf, LICE_FONT_FLAG_OWNS_HFONT); - } - m_font->SetTextColor(m_fillcolor); - - RECT r = { SVGINT(m_x), SVGINT(m_y), SVGINT(m_x), SVGINT(m_y) }; - m_font->DrawText(m_bmp, str, -1, &r, m_textflags|DT_NOCLIP); -} - -static const char* GetSVGStyleStr(const char* str, const char* name, int* len) -{ - const char* s = strstr(str, name); - if (s) - { - s += strlen(name); - while (*s == ' ') ++s; - int i; - const int MAXLEN = 256; - for (i = 0; i < MAXLEN && s[i] && s[i] != ';'; ++i) - { - // run through - } - if (i && i < MAXLEN) *len = i; - else s = 0; - } - return s; -} - -bool LICE_SVGState::ParseTransform(TiXmlElement* xmlelem, double prevctm[]) -{ - const char* str = xmlelem->Attribute("transform"); - while (str && *str == ' ') ++str; - - int ntrans = 0; - while (str && *str) - { - double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0; - int n = 0; - - bool ok = (sscanf(str, "matrix(%lf,%lf,%lf,%lf,%lf,%lf) %n", &a, &b, &c, &d, &e, &f, &n) == 6); - if (!ok) ok = (sscanf(str, "translate(%lf,%lf) %n", &e, &f, &n) == 2); - if (!ok) ok = (sscanf(str, "scale(%lf,%lf) %n", &a, &d, &n) == 2); - // todo rotate, skew - if (!ok || !n) break; - - if (!ntrans++) memcpy(prevctm, m_ctm, SVG_MAT_SZ); - SVGMMult(m_ctm, a, b, c, d, e, f); - str += n; - while (*str == ' ') ++str; - } - - return !!ntrans; -} - -bool LICE_SVGState::ParsePosition(TiXmlElement* xmlelem) -{ - double xf; - double yf; - if (xmlelem->Attribute("x", &xf) && xmlelem->Attribute("y", &yf)) - { - SVGMTransform(m_ctm, &xf, &yf); - SetXY(xf, yf); - } - return true; -} - -bool LICE_SVGState::ParseColor(TiXmlElement* xmlelem) -{ - const char* s; - int len; - - const char* str = xmlelem->Attribute("style"); - if (str) - { - s = GetSVGStyleStr(str, "fill:", &len); - if (s) m_fillcolor = LICE_RGBA_from_SVG(s, len); - else m_fillcolor = 0; - - s = GetSVGStyleStr(str, "stroke:", &len); - if (s) m_strokecolor = LICE_RGBA_from_SVG(s, len); - else m_strokecolor = 0; - - s = GetSVGStyleStr(str, "stroke-width:", &len); - if (s && *s >= '0' && *s <= '9') m_strokewidth = *s-'0'; - else m_strokewidth = 1; - } - return true; -} - -bool LICE_SVGState::ParseFont(TiXmlElement* xmlelem) -{ - const char* s; - int len; - - m_textflags = DT_LEFT|DT_TOP; - - const char* str = xmlelem->Attribute("style"); - if (str) - { - s = GetSVGStyleStr(str, "font-family:", &len); - if (s) - { - lstrcpyn_safe(m_logfont.lfFaceName, s, len); - m_fontdirty = true; - } - - s = GetSVGStyleStr(str, "font-size:", &len); - if (s) - { - double sz = atof(s); - if (sz > 0.0) - { - double xsz = sz, ysz = sz; - SVGMScale(m_ctm, &xsz, &ysz); - sz = max(xsz, ysz); - m_logfont.lfHeight = -abs((int)sz); - m_fontdirty = true; - } - } - - s = GetSVGStyleStr(str, "text-align:", &len); - if (s) - { - if (!strnicmp(s, "center", len)) - { - m_textflags &= ~(DT_LEFT|DT_TOP); - m_textflags |= (DT_CENTER|DT_VCENTER); - } - else if (!strnicmp(s, "start", len)) - { - m_textflags &= ~DT_TOP; - m_textflags |= DT_BOTTOM; - } - } - } - - return true; -} - -bool LICE_SVGState::ParseText(TiXmlElement* xmlelem) -{ - bool ok = true; - - ParseFont(xmlelem); - - const char* str = xmlelem->GetText(); - if (str && *str) DrawText(m_bmp, str); - - TiXmlElement* xmlchild; - for (xmlchild = xmlelem->FirstChildElement("tspan"); xmlchild; xmlchild = xmlchild->NextSiblingElement("tspan")) - { - // no transform for tspan - ParsePosition(xmlchild); - ParseColor(xmlchild); - if (!ParseText(xmlchild)) ok = false; - } - - return ok; -} - -bool LICE_SVGState::ParseRect(TiXmlElement* xmlelem) -{ - bool ok = false; - double w, h; - - double rx = 0.0, ry = 0.0; - xmlelem->Attribute("rx", &rx); - xmlelem->Attribute("ry", &ry); - - ok = (xmlelem->Attribute("width", &w) && xmlelem->Attribute("height", &h)); - - if (ok) - { - SVGMScale(m_ctm, &w, &h); - SVGMScale(m_ctm, &rx, &ry); - - if (m_fillcolor && m_fillalpha > 0.0f) - { - LICE_FillRect(m_bmp, SVGINT(m_x), SVGINT(m_y), SVGINT(w), SVGINT(h), m_fillcolor, m_fillalpha, LICE_BLIT_MODE_COPY); - } - if (m_strokecolor && m_strokealpha > 0.0f) - { - if (rx > 0.0) - { - LICE_RoundRect(m_bmp, SVGINT(m_x), SVGINT(m_y), SVGINT(w), SVGINT(h), (int) rx, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); - } - else - { - SVGDrawRect(m_bmp, m_x, m_y, w, h, m_strokecolor, m_strokealpha, m_strokewidth); - } - } - } - - return ok; -} - -bool LICE_SVGState::ParseCircle(TiXmlElement* xmlelem) -{ - bool ok = false; - - double cx, cy, r = 0.0; - ok = !!xmlelem->Attribute("cx", &cx); - if (ok) ok = !!xmlelem->Attribute("cy", &cy); - if (ok) ok = (!!xmlelem->Attribute("r", &r) && r > 0.0); - - if (ok) - { - SVGMTransform(m_ctm, &cx, &cy); - r = 0.5*floor(r*2.0+0.5); - - if (m_fillcolor && m_fillalpha > 0.0f) - { - LICE_FillCircle(m_bmp, cx, cy, r, m_fillcolor, m_fillalpha, LICE_BLIT_MODE_COPY, true); - } - if (m_strokecolor && m_strokealpha > 0.0f) - { - //LICE_Circle(m_bmp, cx, cy, r, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); - SVGDrawCircle(m_bmp, cx, cy, r, m_strokecolor, m_strokealpha, true, m_strokewidth); - } - } - - return ok; -} - -bool LICE_SVGState::ParseLine(TiXmlElement* xmlelem) -{ - bool ok = false; - double x1, y1, x2, y2; - - ok = (xmlelem->Attribute("x1", &x1) && xmlelem->Attribute("y1", &y1) - && xmlelem->Attribute("x2", &x2) && xmlelem->Attribute("y2", &y2)); - - if (ok) - { - SVGMTransform(m_ctm, &x1, &y1); - SVGMTransform(m_ctm, &x2, &y2); - //LICE_FLine(m_bmp, x1, y1, x2, y2, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); - SVGDrawLine(m_bmp, x1, y1, x2, y2, m_strokecolor, m_strokealpha, true, m_strokewidth); - SetXY(x2, y2); - } - - return ok; -} - -bool LICE_SVGState::ParsePolyline(TiXmlElement* xmlelem, bool close) -{ - bool ok = false; - - double firstx = m_x; - double firsty = m_y; - int npts = 0; - - const char* str = xmlelem->Attribute("points"); - while (str && *str == ' ') ++str; - - while (str && *str) - { - double x, y; - int n = 0; - - ok = (sscanf(str, "%lf,%lf %n", &x, &y, &n) == 2); - if (ok) - { - SVGMTransform(m_ctm, &x, &y); - if (!npts++) - { - firstx = x; - firsty = y; - } - else - { - //LICE_FLine(m_bmp, m_x, m_y, x, y, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); - SVGDrawLine(m_bmp, m_x, m_y, x, y, m_strokecolor, m_strokealpha, true, m_strokewidth); - } - SetXY(x, y); - } - - if (!ok || !n) break; - str += n; - while (*str == ' ') ++str; - } - - if (close && npts) - { - //LICE_FLine(m_bmp, m_x, m_y, firstx, firsty, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); - SVGDrawLine(m_bmp, m_x, m_y, firstx, firsty, m_strokecolor, m_strokealpha, true, m_strokewidth); - SetXY(firstx, firsty); - } - - return ok; -} - -static void AdjRelXY(double* lastx, double* lasty, double* x, double* y, double m[], bool isrel, RECT* r) -{ - if (isrel) - { - *x += *lastx; - *y += *lasty; - } - *lastx = *x; - *lasty = *y; - SVGMTransform(m, x, y); - - if (r) - { - if (r->left < 0 || *x < r->left) r->left = *x-2; - if (r->right < 0 || *x >= r->right) r->right = *x+3; - if (r->top < 0 || *y < r->top) r->top = *y-2; - if (r->bottom < 0 || *y >= r->bottom) r->bottom = *y+3; - } -} - -static bool RenderSVGPath(const char* str, double m[], RECT* r, - LICE_IBitmap* bmp=0, LICE_pixel color=0xFFFFFFFF, float alpha=1.0f, bool aa=false, int strokewid=1, - double* lastx=0, double* lasty=0) -{ - bool allok = true; - - double firstx, firsty; // first point on subpath, global coords - double prevx, prevy; // previous point, local coords - double x0, y0; // point at end of previous move, global coords - - while (str && *str) - { - double x1, y1, x2, y2, x3, y3; - int n = 0; - bool ok = false; - - char c = str[0]; - bool isrel = (c == tolower(c)); - ++str; - while (*str == ' ') ++str; - - switch (toupper(c)) - { - case 'M': - case 'L': - ok = (sscanf(str, "%lf,%lf %n", &x1, &y1, &n) == 2); - if (ok) - { - AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); - if (c == 'M') - { - firstx = x1; - firsty = y1; - } - else if (bmp) - { - //LICE_FLine(bmp, x0, y0, x1, y1, color, alpha, LICE_BLIT_MODE_COPY, aa); - SVGDrawLine(bmp, x0, y0, x1, y1, color, alpha, aa, strokewid); - } - x0 = x1; - y0 = y1; - } - break; - - case 'Z': - ok = true; - --str; - n = 1; - if (ok) - { - if (bmp && x0 != firstx && y0 != firsty) - { - //LICE_FLine(bmp, x0, y0, firstx, firsty, color, alpha, LICE_BLIT_MODE_COPY, aa); - SVGDrawLine(bmp, x0, y0, firstx, firsty, color, alpha, aa, strokewid); - x0 = firstx; - y0 = firsty; - } - } - break; - - case 'Q': - ok = (sscanf(str, "%lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &n) == 4); - if (ok) - { - AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); - AdjRelXY(&prevx, &prevy, &x2, &y2, m, isrel, r); - if (bmp) - { - //LICE_DrawQBezier(bmp, x0, y0, x1, y1, x2, y2, color, alpha, LICE_BLIT_MODE_COPY, aa); - SVGDrawQBezier(bmp, x0, y1, x1, y1, x2, y2, color, alpha, aa, strokewid); - x0 = x2; - y0 = y2; - } - } - break; - - case 'C': - ok = (sscanf(str, "%lf,%lf %lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &x3, &y3, &n) == 6); - if (ok) - { - AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); - AdjRelXY(&prevx, &prevy, &x2, &y2, m, isrel, r); - AdjRelXY(&prevx, &prevy, &x3, &y3, m, isrel, r); - if (bmp) - { - //LICE_DrawCBezier(bmp, x0, y0, x1, y1, x2, y2, x3, y3, color, alpha, LICE_BLIT_MODE_COPY, aa); - SVGDrawCBezier(bmp, x0, y0, x1, y1, x2, y2, x3, y3, color, alpha, aa, strokewid); - x0 = x3; - y0 = y3; - } - } - break; - } - - if (!ok) allok = false; - if (!ok || !n) break; - str += n; - while (*str == ' ') ++str; - } - - if (lastx) *lastx = x0; - if (lasty) *lasty = y0; - return allok; -} - -static bool FillSVGScanLine(LICE_IBitmap* dest, LICE_pixel* rowpx, LICE_pixel col, float alpha, RECT* r, int y, int dir) -{ - bool prevon = false; - bool dofill = false; - - int i, x, xstart; - int w = r->right-r->left; - for (i = 0; i < w; ++i) - { - x = (dir < 0 ? w-i-1 : i); - bool curon = !!rowpx[x]; - if (curon != prevon) - { - if (!curon) - { - xstart = x; - } - else - { - if (dofill) - { - LICE_Line(dest, r->left+xstart/*+dir*/, y, r->left+x/*-dir*/, y, col, alpha, LICE_BLIT_MODE_COPY, false); - } - dofill = !dofill; - } - prevon = curon; - } - } - - return !dofill; // if we ended before hitting the end of a fill, we nicked an edge -} - -static bool FillSVGShape(LICE_IBitmap* dest, LICE_IBitmap* src, LICE_pixel col, float alpha, RECT *r) -{ - bool ok = true; - - LICE_pixel* rowpx = src->getBits(); - int span = src->getRowSpan(); - - int y; - for (y = r->top; y < r->bottom; ++y, rowpx += span) - { - if (!FillSVGScanLine(dest, rowpx, col, alpha, r, y, 1) && - !FillSVGScanLine(dest, rowpx, col, alpha, r, y, -1)) - { - ok = false; - } - } - - return ok; -} - -bool LICE_SVGState::ParsePath(TiXmlElement* xmlelem) -{ - bool ok = true; - - const char* str = xmlelem->Attribute("d"); - while (str && *str == ' ') ++str; - - if (m_fillcolor && m_fillalpha > 0.0f) // fill - { - RECT r = { -1, -1, -1, -1 }; // bounding box - if (ok) ok = RenderSVGPath(str, m_ctm, &r); // measure - - double m[6]; - SVGMSet(m, 1.0, 0.0, 0.0, 1.0, -(double)r.left, -(double)r.top); // translate to tmpbmp on matrix LHS - SVGMMult(m, m_ctm[0], m_ctm[3], m_ctm[1], m_ctm[4], m_ctm[2], m_ctm[5]); - - if (!m_tmpbmp) m_tmpbmp = new LICE_MemBitmap; - m_tmpbmp->resize(r.right-r.left, r.bottom-r.top); - LICE_Clear(m_tmpbmp, 0); - - if (ok) ok = RenderSVGPath(str, m, 0, m_tmpbmp); // outline to tmpbmp - // debug LICE_Blit(m_bmp, m_tmpbmp, r.left, r.top, 0, 0, r.right-r.left, r.bottom-r.top, 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - if (ok) ok = FillSVGShape(m_bmp, m_tmpbmp, m_fillcolor, m_fillalpha, &r); // raytrace to dest - } - - if (m_strokecolor && m_strokealpha > 0.0f) // outline - { - if (ok) ok = RenderSVGPath(str, m_ctm, 0, m_bmp, m_strokecolor, m_strokealpha, true, m_strokewidth, &m_x, &m_y); - } - - return ok; -} - -bool LICE_SVGState::ParseNode(TiXmlNode* xmlnode) -{ - bool allok = true; - - TiXmlNode* xmlchild; - for (xmlchild = xmlnode->FirstChild(); xmlchild; xmlchild = xmlchild->NextSibling()) - { - if (xmlchild->Type() == TiXmlElement::ELEMENT) - { - bool ok = true; - - const char* name = xmlchild->Value(); - TiXmlElement* xmlelem = xmlchild->ToElement(); - - double prevctm[6]; - bool transform = ParseTransform(xmlelem, prevctm); - - ParsePosition(xmlelem); - ParseColor(xmlelem); - - if (!stricmp(name, "svg") || !stricmp(name, "g")) ok = ParseNode(xmlelem); - else if (!stricmp(name, "rect")) ok = ParseRect(xmlelem); - else if (!stricmp(name, "circle")) ok = ParseCircle(xmlelem); - else if (!stricmp(name, "line")) ok = ParseLine(xmlelem); - else if (!stricmp(name, "polyline")) ok = ParsePolyline(xmlelem, false); - else if (!stricmp(name, "polygon")) ok = ParsePolyline(xmlelem, true); - else if (!stricmp(name, "path")) ok = ParsePath(xmlelem); - else if (!stricmp(name, "text") || !stricmp(name, "tspan")) ok = ParseText(xmlelem); - // it's not an error not to recognize a tag - - if (!ok) - { - allok = false; - // log error and continue - } - - if (transform) memcpy(m_ctm, prevctm, SVG_MAT_SZ); - } - } - - return true; //allok; -} - -static LICE_IBitmap *LICE_RenderSVG(TiXmlDocument* xmldoc, LICE_IBitmap *bmp) -{ - if (!xmldoc) return 0; - - TiXmlElement* xmlroot = xmldoc->RootElement(); - if (!xmlroot || stricmp(xmlroot->Value(), "svg")) return 0; - - int srcw = 0; - int srch = 0; - if (!xmlroot->Attribute("width", &srcw) || !xmlroot->Attribute("height", &srch)) return 0; - if (!srcw || !srch) return 0; - - bool ourbmp = !bmp; - if (ourbmp) bmp = new LICE_MemBitmap; - LICE_SVGState svgstate(bmp); - -/* - int destw = bmp->getWidth(); - int desth = bmp->getHeight(); - - if (destw && desth) - { - double xscale = (double)destw/(double)srcw; - double yscale = (double)desth/(double)srch; - SVGMSet(svgstate.m_ctm, xscale, 0.0, 0.0, yscale, 0.0, 0.0); - } - else -*/ - { - bmp->resize(srcw, srch); - } - LICE_Clear(bmp, 0); - - if (!svgstate.ParseNode(xmlroot) && ourbmp) - { - delete(bmp); - bmp = 0; - } - return bmp; -} - -LICE_IBitmap* LICE_LoadSVG(const char* filename, LICE_IBitmap* bmp) -{ - TiXmlDocument xmldoc; - xmldoc.SetCondenseWhiteSpace(false); - if (!xmldoc.LoadFile(filename) || xmldoc.Error()) return 0; - return LICE_RenderSVG(&xmldoc, bmp); -} - -LICE_IBitmap* LICE_LoadSVGFromBuffer(const char* buffer, int buflen, LICE_IBitmap* bmp) -{ - TiXmlDocument xmldoc; - xmldoc.SetCondenseWhiteSpace(false); - if (!xmldoc.Parse(buffer) || xmldoc.Error()) return 0; - return LICE_RenderSVG(&xmldoc, bmp); -} - diff --git a/WDL/lice/lice_texgen.cpp b/WDL/lice/lice_texgen.cpp deleted file mode 100644 index fe6e5ffd..00000000 --- a/WDL/lice/lice_texgen.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: lice_texgen.cpp (LICE texture generator routines) - See lice.h for license and other information -*/ - - -#include "lice.h" -#include - -void LICE_TexGen_Marble(LICE_IBitmap *dest, RECT *rect, float rv, float gv, float bv, float intensity) -{ - int span=dest->getRowSpan(); - int w = dest->getWidth(); - int h = dest->getHeight(); - int x = 0; - int y = 0; - if(rect) - { - x = rect->left; - y = rect->top; - w = rect->right - rect->left; - h = rect->bottom - rect->top; - } - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w > dest->getWidth()) w=dest->getWidth()-x; - if (y+h > dest->getHeight()) h=dest->getHeight()-y; - - if (w<1 || h<1) return; - - LICE_pixel *startp = dest->getBits(); - if (dest->isFlipped()) - { - startp += x + (dest->getHeight()-1-y)*span; - span=-span; - } - else startp += x + y*span; - - //simple 16bit marble noise generator - -#define ROL(x,y) ((x<<(y))|(((unsigned short)x)>>(16-(y)))) -#define ROR(x,y) ((((unsigned short)x)>>(y))|(x<<(16-(y)))) - - intensity/=1024.0f; - int maxc = 0; - { - LICE_pixel *p = startp; - short n1 = 0, n2 = 0; - for(int i=0;i0) - { - c = p[j-span]; - if(j==0) - c2 = p[(w-1)-span]; - else - c2 = p[(j-1)-span]; - } - - int pix = (((c + c2)/2) + val); - if(pix>maxc) maxc = pix; - p[j] = pix; - } - p+=span; - } - } - - //normalize values and apply gamma - { - LICE_pixel *p = startp; - float sc=255.0f/maxc; - - for(int i=0;igetRowSpan(); - int w = dest->getWidth(); - int h = dest->getHeight(); - int x = 0; - int y = 0; - if(rect) - { - x = rect->left; - y = rect->top; - w = rect->right - rect->left; - h = rect->bottom - rect->top; - } - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w > dest->getWidth()) w=dest->getWidth()-x; - if (y+h > dest->getHeight()) h=dest->getHeight()-y; - - if (w<1 || h<1) return; - - LICE_pixel *startp = dest->getBits(); - if (dest->isFlipped()) - { - startp += x + (dest->getHeight()-1-y)*span; - span=-span; - } - else startp += x + y*span; - - { - LICE_pixel *p = startp; - for(int i=0;i=1) - { - switch(mode) - { - case NOISE_MODE_NORMAL: val += noise(x/size, y/size)*size; break; - case NOISE_MODE_WOOD: val += (float)cos( x/size + noise(x/size,y/size) )*size/2; break; - } - size /= 2; - } - float col = (float)fabs(val/smooth)*255; - if(col>255) col=255; - - p[j] = LICE_RGBA((int)(col*rv),(int)(col*gv),(int)(col*bv),255); - } - p+=span; - } - } -} - -float turbulence(float x, float y, float size) -{ - float value = 0.0, initialSize = size; - while(size >= 1) - { - value += noise(x / size, y / size) * size; - size /= 2.0; - } - return(128.0f * value / initialSize); -} - -void LICE_TexGen_CircNoise(LICE_IBitmap *dest, RECT *rect, float rv, float gv, float bv, float nrings, float power, int size) -{ - initNoise(); - - int span=dest->getRowSpan(); - int w = dest->getWidth(); - int h = dest->getHeight(); - int x = 0; - int y = 0; - if(rect) - { - x = rect->left; - y = rect->top; - w = rect->right - rect->left; - h = rect->bottom - rect->top; - } - - if (x<0) { w+=x; x=0; } - if (y<0) { h+=y; y=0; } - if (x+w > dest->getWidth()) w=dest->getWidth()-x; - if (y+h > dest->getHeight()) h=dest->getHeight()-y; - - if (w<1 || h<1) return; - - LICE_pixel *startp = dest->getBits(); - if (dest->isFlipped()) - { - startp += x + (dest->getHeight()-1-y)*span; - span=-span; - } - else startp += x + y*span; - - float xyPeriod = nrings; - float turbPower = power; - float turbSize = (float)size; - - { - LICE_pixel *p = startp; - for(int i=0;i' */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - - /* 63 0x3f '?' */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* 64 0x40 '@' */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xc0, /* 11000000 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 65 0x41 'A' */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 66 0x42 'B' */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - - /* 67 0x43 'C' */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 68 0x44 'D' */ - 0xf8, /* 11111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - - /* 69 0x45 'E' */ - 0xfe, /* 11111110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x62, /* 01100010 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* 70 0x46 'F' */ - 0xfe, /* 11111110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 71 0x47 'G' */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xce, /* 11001110 */ - 0x66, /* 01100110 */ - 0x3a, /* 00111010 */ - 0x00, /* 00000000 */ - - /* 72 0x48 'H' */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 73 0x49 'I' */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 74 0x4a 'J' */ - 0x1e, /* 00011110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 75 0x4b 'K' */ - 0xe6, /* 11100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* 76 0x4c 'L' */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* 77 0x4d 'M' */ - 0xc6, /* 11000110 */ - 0xee, /* 11101110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 78 0x4e 'N' */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 79 0x4f 'O' */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* 80 0x50 'P' */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 81 0x51 'Q' */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xce, /* 11001110 */ - 0x7c, /* 01111100 */ - 0x0e, /* 00001110 */ - - /* 82 0x52 'R' */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* 83 0x53 'S' */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 84 0x54 'T' */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x5a, /* 01011010 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 85 0x55 'U' */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* 86 0x56 'V' */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* 87 0x57 'W' */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* 88 0x58 'X' */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 89 0x59 'Y' */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 90 0x5a 'Z' */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x8c, /* 10001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* 91 0x5b '[' */ - 0x3c, /* 00111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 92 0x5c '\' */ - 0xc0, /* 11000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - - /* 93 0x5d ']' */ - 0x3c, /* 00111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 94 0x5e '^' */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 95 0x5f '_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - - /* 96 0x60 '`' */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 97 0x61 'a' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* 98 0x62 'b' */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - - /* 99 0x63 'c' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* 100 0x64 'd' */ - 0x1c, /* 00011100 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* 101 0x65 'e' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* 102 0x66 'f' */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x60, /* 01100000 */ - 0xf8, /* 11111000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 103 0x67 'g' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0xf8, /* 11111000 */ - - /* 104 0x68 'h' */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x6c, /* 01101100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* 105 0x69 'i' */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 106 0x6a 'j' */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - - /* 107 0x6b 'k' */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* 108 0x6c 'l' */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 109 0x6d 'm' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0x00, /* 00000000 */ - - /* 110 0x6e 'n' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - - /* 111 0x6f 'o' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* 112 0x70 'p' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - - /* 113 0x71 'q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - - /* 114 0x72 'r' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 115 0x73 's' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x06, /* 00000110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - - /* 116 0x74 't' */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0xfc, /* 11111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x36, /* 00110110 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - - /* 117 0x75 'u' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* 118 0x76 'v' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* 119 0x77 'w' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* 120 0x78 'x' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* 121 0x79 'y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0xfc, /* 11111100 */ - - /* 122 0x7a 'z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x4c, /* 01001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* 123 0x7b '{' */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - - /* 124 0x7c '|' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* 125 0x7d '}' */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - - /* 126 0x7e '~' */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - - /* 127 0x7f '' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ -}; - - -void LICE_DrawChar(LICE_IBitmap *bm, int x, int y, char c, - LICE_pixel color, float alpha, int mode) -{ - LICE_pixel *fb; - if (c<1 || !bm || !(fb=bm->getBits()))return; - unsigned char *font = LICE_deffont + ((c-1)*LICE_FONT_HEIGHT); - int len = LICE_FONT_HEIGHT; - if (y < 0) - { - font -= y; - len += y; - y = 0; - } - if (y+LICE_FONT_HEIGHT >= bm->getHeight()) len = bm->getHeight()-y; - if (len<1) return; - - int smask=128; - int xlen=8; - if (x<0) - { - smask >>= -x; - xlen+=x; - x=0; - } - int ml=bm->getWidth()-x; - if (xlen>ml)xlen=ml; - - if (ml<1) return; - - int rs=bm->getRowSpan(); - if (bm->isFlipped()) - { - fb += x+((bm->getHeight()-1-y)*rs); - rs=-rs; - } - else - fb += x+(y*rs); - - int red=LICE_GETR(color), green=LICE_GETG(color), blue=LICE_GETB(color), alp=LICE_GETA(color), ialpha=(int) (alpha * 256.0f); - - while (len-->0) - { - LICE_pixel *outmem = fb; - fb+=rs; - unsigned char ch = *font++; - int a=smask; - int xleft = xlen; - while (a && xleft--) - { - if (ch & a) - { - #define __LICE__ACTION(comb) comb::doPix((LICE_pixel_chan *)outmem, red,green,blue,alp,ialpha) - __LICE_ACTION_NOSRCALPHA(mode,ialpha, false); - #undef __LICE__ACTION - } - outmem++; - a >>= 1; - } - } -} - -void LICE_DrawText(LICE_IBitmap *bm, int x, int y, const char *string, - LICE_pixel color, float alpha, int mode) -{ - if (!bm) return; - int w=bm->getWidth(); - int h=bm->getHeight(); - int xx = x; - while (*string) - { - switch (*string) - { - case '\n': y += LICE_FONT_HEIGHT; xx = x; break; - case ' ': xx += 8; break; - case '\r': break; - case '\t': xx += 8*5; break; - default: - if (xx>=-8 && xx= -LICE_FONT_HEIGHT && y < h) - LICE_DrawChar(bm,xx,y,*string, color,alpha,mode); - xx += 8; - break; - } - string++; - } -} - -void LICE_MeasureText(const char *string, int *w, int *h) -{ - if (w) *w=0; - if (h) *h=0; - int x=0,y=LICE_FONT_HEIGHT; - while (*string) - { - switch (*string) - { - case '\n': y += LICE_FONT_HEIGHT; x = 0; break; - case '\r': break; - case '\t': x += 8*4; - default: - x += 8; - if (w && x > *w) *w=x; - if (h && y > *h) *h=y; - break; - } - string++; - } -} - diff --git a/WDL/lice/lice_text.h b/WDL/lice/lice_text.h deleted file mode 100644 index 165eaf02..00000000 --- a/WDL/lice/lice_text.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _LICE_TEXT_H_ -#define _LICE_TEXT_H_ - -#include "lice.h" - -#include "../heapbuf.h" - -#define LICE_FONT_FLAG_VERTICAL 1 // rotate text to vertical (do not set the windows font to vertical though) -#define LICE_FONT_FLAG_VERTICAL_BOTTOMUP 2 - -#define LICE_FONT_FLAG_PRECALCALL 4 -//#define LICE_FONT_FLAG_ALLOW_NATIVE 8 -#define LICE_FONT_FLAG_FORCE_NATIVE 1024 - -#define LICE_FONT_FLAG_FX_BLUR 16 -#define LICE_FONT_FLAG_FX_INVERT 32 -#define LICE_FONT_FLAG_FX_MONO 64 // faster but no AA/etc - -#define LICE_FONT_FLAG_FX_SHADOW 128 // these imply MONO -#define LICE_FONT_FLAG_FX_OUTLINE 256 - -#define LICE_FONT_FLAG_OWNS_HFONT 512 - -// could do a mask for these flags -#define LICE_FONT_FLAGS_HAS_FX(flag) \ - (flag&(LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP| \ - LICE_FONT_FLAG_FX_BLUR|LICE_FONT_FLAG_FX_INVERT|LICE_FONT_FLAG_FX_MONO| \ - LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) - -#define LICE_DT_NEEDALPHA 0x80000000 // include in DrawText() if the output alpha channel is important -#define LICE_DT_USEFGALPHA 0x40000000 // uses alpha channel in fg color - -class LICE_IFont -{ - public: - virtual ~LICE_IFont() {} - - virtual void SetFromHFont(HFONT font, int flags=0)=0; // hfont must REMAIN valid, unless LICE_FONT_FLAG_PRECALCALL or LICE_FONT_FLAG_OWNS_HFONT set (OWNS means LICE_IFont will clean up hfont on font change or exit) - - virtual LICE_pixel SetTextColor(LICE_pixel color)=0; - virtual LICE_pixel SetBkColor(LICE_pixel color)=0; - virtual LICE_pixel SetEffectColor(LICE_pixel color)=0; - virtual int SetBkMode(int bkmode)=0; - virtual void SetCombineMode(int combine, float alpha=1.0f)=0; - - virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags)=0; - - virtual LICE_pixel GetTextColor()=0; - virtual HFONT GetHFont()=0; -}; - - -class LICE_CachedFont : public LICE_IFont -{ - public: - LICE_CachedFont(); - virtual ~LICE_CachedFont(); - - virtual void SetFromHFont(HFONT font, int flags=0); - - virtual LICE_pixel SetTextColor(LICE_pixel color) { LICE_pixel ret=m_fg; m_fg=color; return ret; } - virtual LICE_pixel SetBkColor(LICE_pixel color) { LICE_pixel ret=m_bg; m_bg=color; return ret; } - virtual LICE_pixel SetEffectColor(LICE_pixel color) { LICE_pixel ret=m_effectcol; m_effectcol=color; return ret; } - virtual int SetBkMode(int bkmode) { int bk = m_bgmode; m_bgmode=bkmode; return bk; } - virtual void SetCombineMode(int combine, float alpha=1.0f) { m_comb=combine; m_alpha=alpha; } - - virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags) - { - return DrawTextImpl(bm,str,strcnt,rect,dtFlags); - } - - virtual LICE_pixel GetTextColor() { return m_fg; } - virtual HFONT GetHFont() { return m_font; } - - void SetLineSpacingAdjust(int amt) { m_lsadj=amt; } - - private: - - int DrawTextImpl(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags); // cause swell defines DrawText to SWELL_DrawText etc - - bool DrawGlyph(LICE_IBitmap *bm, unsigned short c, int xpos, int ypos, RECT *clipR); - bool RenderGlyph(unsigned short idx); - - LICE_pixel m_fg,m_bg,m_effectcol; - int m_bgmode; - int m_comb; - float m_alpha; - int m_flags; - - int m_line_height,m_lsadj; - struct charEnt - { - int base_offset; // offset in m_cachestore+1, so 1=offset0, 0=unset, -1=failed to render - int width, height; - int advance; - int charid; // used by m_extracharlist - }; - charEnt *findChar(unsigned short c); - - charEnt m_lowchars[128]; // first 128 chars cached here - WDL_TypedBuf m_extracharlist; - WDL_TypedBuf m_cachestore; - - static int _charSortFunc(const void *a, const void *b); - - HFONT m_font; - -}; - -#endif//_LICE_TEXT_H_ diff --git a/WDL/lice/lice_textnew.cpp b/WDL/lice/lice_textnew.cpp deleted file mode 100644 index eec87968..00000000 --- a/WDL/lice/lice_textnew.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -#include "lice_text.h" -#include - - -#ifndef _WIN32 -#include "../swell/swell.h" -#endif - - -#include "lice_combine.h" -#include "lice_extended.h" - -#ifdef _WIN32 -static char __1ifNT2if98=0; // 2 for iswin98 -#endif - - -static int utf8makechar(char *ptrout, unsigned short charIn) -{ - unsigned char *pout = (unsigned char *)ptrout; - if (charIn < 128) { *pout = (unsigned char)charIn; return 1; } - if (charIn < 2048) { pout[0] = 0xC0 + (charIn>>6); pout[1] = 0x80 + (charIn&0x3f); return 2; } - pout[0] = 0xE0 + (charIn>>12); - pout[1] = 0x80 + ((charIn>>6)&0x3f); - pout[2] = 0x80 + (charIn&0x3f); - return 3; -} - -static int utf8char(const char *ptr, unsigned short *charOut) // returns char length -{ - const unsigned char *p = (const unsigned char *)ptr; - unsigned char tc = *p; - - if (tc < 128) - { - if (charOut) *charOut = (unsigned short) tc; - return 1; - } - else if (tc < 0xC2) // invalid chars (subsequent in sequence, or overlong which we disable for) - { - } - else if (tc < 0xE0) // 2 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0) - { - if (charOut) *charOut = ((tc&0x1f)<<6) | (p[1]&0x3f); - return 2; - } - } - else if (tc < 0xF0) // 3 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0) - { - if (charOut) *charOut = ((tc&0xf)<<12) | ((p[1]&0x3f)<<6) | ((p[2]&0x3f)); - return 3; - } - } - else if (tc < 0xF5) // 4 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0 && p[3] >= 0x80 && p[3] <= 0xC0) - { - if (charOut) *charOut = (unsigned short)' '; // dont support 4 byte sequences yet(ever?) - return 4; - } - } - if (charOut) *charOut = (unsigned short) tc; - return 1; -} - - - -//not threadsafe ---- -static LICE_SysBitmap s_tempbitmap; // keep a sysbitmap around for rendering fonts - - -int LICE_CachedFont::_charSortFunc(const void *a, const void *b) -{ - charEnt *aa = (charEnt *)a; - charEnt *bb = (charEnt *)b; - return aa->charid - bb->charid; -} - -LICE_CachedFont::LICE_CachedFont() : m_cachestore(65536) -{ - m_fg=0; - m_effectcol=m_bg=LICE_RGBA(255,255,255,255); - m_comb=0; - m_alpha=1.0f; - m_bgmode = TRANSPARENT; - m_flags=0; - m_line_height=0; - m_lsadj=0; - m_font=0; - memset(m_lowchars,0,sizeof(m_lowchars)); -} - -LICE_CachedFont::~LICE_CachedFont() -{ - if ((m_flags&LICE_FONT_FLAG_OWNS_HFONT) && m_font) { - DeleteObject(m_font); - } -} - -void LICE_CachedFont::SetFromHFont(HFONT font, int flags) -{ - if ((m_flags&LICE_FONT_FLAG_OWNS_HFONT) && m_font && m_font != font) - { - DeleteObject(m_font); - } - - m_flags=flags; - m_font=font; - if (font) - { - if (s_tempbitmap.getWidth() < 256 || s_tempbitmap.getHeight() < 256) - { - s_tempbitmap.resize(256,256); - ::SetTextColor(s_tempbitmap.getDC(),RGB(255,255,255)); - ::SetBkMode(s_tempbitmap.getDC(),OPAQUE); - ::SetBkColor(s_tempbitmap.getDC(),RGB(0,0,0)); - } - - TEXTMETRIC tm; - HGDIOBJ oldFont = 0; - if (font) oldFont = SelectObject(s_tempbitmap.getDC(),font); - GetTextMetrics(s_tempbitmap.getDC(),&tm); - if (oldFont) SelectObject(s_tempbitmap.getDC(),oldFont); - - m_line_height = tm.tmHeight; - } - - memset(m_lowchars,0,sizeof(m_lowchars)); - m_extracharlist.Resize(0,false); - m_cachestore.Resize(0); - if (flags&LICE_FONT_FLAG_PRECALCALL) - { - int x; - for(x=0;x<128;x++) - RenderGlyph(x); - } -} - -bool LICE_CachedFont::RenderGlyph(unsigned short idx) // return TRUE if ok -{ - bool needSort=false; - charEnt *ent; - if (idx>=128) - { -#ifdef _WIN32 - if (!__1ifNT2if98) __1ifNT2if98 = GetVersion()<0x80000000 ? 1 : 2; - - if (__1ifNT2if98==2) return false; -#endif - ent=findChar(idx); - if (!ent) - { - if (m_flags & LICE_FONT_FLAG_PRECALCALL) return false; - - int oldsz=m_extracharlist.GetSize(); - ent = m_extracharlist.Resize(oldsz+1) + oldsz; - memset(ent,0,sizeof(*ent)); - ent->charid = idx; - - needSort=true; - } - } - else ent = m_lowchars+idx; - - int bmsz=m_line_height; - if (bmsz<1) bmsz=1; - if (s_tempbitmap.getWidth() < bmsz || s_tempbitmap.getHeight() < bmsz) - { - s_tempbitmap.resize(bmsz,bmsz); - ::SetTextColor(s_tempbitmap.getDC(),RGB(255,255,255)); - ::SetBkMode(s_tempbitmap.getDC(),OPAQUE); - ::SetBkColor(s_tempbitmap.getDC(),RGB(0,0,0)); - } - - LICE_Clear(&s_tempbitmap,0); - - HGDIOBJ oldFont=0; - if (m_font) oldFont = SelectObject(s_tempbitmap.getDC(),m_font); - RECT r={0,0,0,0,}; - int advance; - -#ifdef _WIN32 - if (__1ifNT2if98==1) - { - WCHAR tmpstr[2]={(WCHAR)idx,0}; - ::DrawTextW(s_tempbitmap.getDC(),tmpstr,1,&r,DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); - advance=r.right; - if (idx>='A' && idx<='Z') r.right+=2; // extra space for A-Z - ::DrawTextW(s_tempbitmap.getDC(),tmpstr,1,&r,DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); - } - else -#endif - { - - char tmpstr[6]={(char)idx,0}; -#ifndef _WIN32 - if (idx>=128) utf8makechar(tmpstr,idx); -#endif - ::DrawText(s_tempbitmap.getDC(),tmpstr,-1,&r,DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); - advance=r.right; - if (idx>='A' && idx<='Z') r.right+=2; // extra space for A-Z - ::DrawText(s_tempbitmap.getDC(),tmpstr,-1,&r,DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); - } - - if (oldFont) SelectObject(s_tempbitmap.getDC(),oldFont); - - if (r.right < 1 || r.bottom < 1) - { - ent->base_offset=-1; - ent->advance=ent->width=ent->height=0; - } - else - { - ent->advance=advance; - int flags=m_flags; - if (flags&LICE_FONT_FLAG_FX_BLUR) - { - LICE_Blur(&s_tempbitmap,&s_tempbitmap,0,0,0,0,r.right,r.bottom); - } - LICE_pixel *srcbuf = s_tempbitmap.getBits(); - int span=s_tempbitmap.getRowSpan(); - - ent->base_offset=m_cachestore.GetSize()+1; - unsigned char *destbuf = m_cachestore.Resize(ent->base_offset-1+r.right*r.bottom) + ent->base_offset-1; - if (s_tempbitmap.isFlipped()) - { - srcbuf += (s_tempbitmap.getHeight()-1)*span; - span=-span; - } - int x,y; - for(y=0;y130 ? 255:0; - destbuf++; - } - - destbuf -= r.right*r.bottom; - } - if (flags&(LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) - { - for(y=0;y130 ? 255:0; - destbuf++; - } - - destbuf -= r.right*r.bottom; - if (flags&LICE_FONT_FLAG_FX_SHADOW) - { - for(y=0;y0) - { - if (destbuf[-1]==255) *destbuf=128; - else if (y>0 && destbuf[-r.right-1]==255) *destbuf=128; - } - if (y>0 && destbuf[-r.right]==255) *destbuf=128; - } - destbuf++; - } - } - else - { - for(y=0;y0 && destbuf[-r.right]==255) *destbuf=128; - else if (y0) - { - if (destbuf[-1]==255) *destbuf=128; - // else if (y>0 && destbuf[-r.right-1]==255) *destbuf=128; - // else if (y0 && destbuf[-r.right+1]==255) *destbuf=128; - // else if (ywidth = r.right; - ent->height = r.bottom; - } - if (needSort&&m_extracharlist.GetSize()>1) qsort(m_extracharlist.Get(),m_extracharlist.GetSize(),sizeof(charEnt),_charSortFunc); - - return true; -} - -template class GlyphRenderer -{ -public: - static void Normal(unsigned char *gsrc, LICE_pixel *pout, - int src_span, int dest_span, int width, int height, - int red, int green, int blue, int a256) - { - int y; - if (a256==256) - { - for(y=0;y256)a=256; - T::doPix((unsigned char *)(pout+x),red,green,blue,255,a); - } - } - gsrc += src_span; - pout += dest_span; - } - } - } - static void Mono(unsigned char *gsrc, LICE_pixel *pout, - int src_span, int dest_span, int width, int height, - int red, int green, int blue, int alpha) - { - int y; - for(y=0;ywidth <= clipR->left || xpos >= clipR->right || - ypos+ch->height <= clipR->top || ypos >= clipR->bottom) return false; - - unsigned char *gsrc = m_cachestore.Get() + ch->base_offset-1; - int src_span = ch->width; - int width = ch->width; - int height = ch->height; - -#ifndef DISABLE_LICE_EXTENSIONS - if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWGLYPH_ACCEL)) - { - LICE_Ext_DrawGlyph_acceldata data(xpos, ypos, m_fg, gsrc, width, height, m_alpha, m_comb); - if (bm->Extended(LICE_EXT_DRAWGLYPH_ACCEL, &data)) return true; - } -#endif - - if (xpos < clipR->left) - { - width += (xpos-clipR->left); - gsrc += clipR->left-xpos; - xpos=clipR->left; - } - if (ypos < clipR->top) - { - gsrc += src_span*(clipR->top-ypos); - height += (ypos-clipR->top); - ypos=clipR->top; - } - int dest_span = bm->getRowSpan(); - LICE_pixel *pout = bm->getBits(); - - if (bm->isFlipped()) - { - pout += (bm->getHeight()-1)*dest_span; - dest_span=-dest_span; - } - - pout += xpos + ypos * dest_span; - - if (xpos+width >= clipR->right) width = clipR->right-xpos; - - if (ypos+height >= clipR->bottom) height = clipR->bottom-ypos; - - int mode=m_comb&~LICE_BLIT_USE_ALPHA; - float alpha=m_alpha; - - if (m_bgmode==OPAQUE) - LICE_FillRect(bm,xpos,ypos,width,height,m_bg,alpha,mode); - - int red=LICE_GETR(m_fg); - int green=LICE_GETG(m_fg); - int blue=LICE_GETB(m_fg); - - if (m_flags&LICE_FONT_FLAG_FX_MONO) - { - if (alpha==1.0 && (mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) // fast simple - { - LICE_pixel col=m_fg; - int y; - for(y=0;y256)avalint=256; - - #define __LICE__ACTION(comb) GlyphRenderer::Mono(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint) - __LICE_ACTION_NOSRCALPHA(mode,avalint, false); - #undef __LICE__ACTION - } - } - else if (m_flags&(LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) - { - LICE_pixel col=m_fg; - LICE_pixel bkcol=m_effectcol; - - if (alpha==1.0 && (mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) - { - int y; - for(y=0;y256)avalint=256; - int r2=LICE_GETR(bkcol); - int g2=LICE_GETG(bkcol); - int b2=LICE_GETB(bkcol); - #define __LICE__ACTION(comb) GlyphRenderer::Effect(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint,r2,g2,b2) - __LICE_ACTION_NOSRCALPHA(mode,avalint, false); - #undef __LICE__ACTION - } - } - else - { - int avalint = (int) (alpha*256.0); - #define __LICE__ACTION(comb) GlyphRenderer::Normal(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint) - __LICE_ACTION_NOSRCALPHA(mode,avalint, false); - #undef __LICE__ACTION - } - - return true; // drew glyph at all (for updating max extents) -} - - -static int LICE_Text_IsWine() -{ - static int isWine=-1; -#ifdef _WIN32 - if (isWine<0) - { - HKEY hk; - if (RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Wine",&hk)==ERROR_SUCCESS) - { - isWine=1; - RegCloseKey(hk); - } - else isWine=0; - } -#endif - return isWine>0; -} - -#ifdef _WIN32 -static BOOL LICE_Text_HasUTF8(const char *_str) -{ - const unsigned char *str = (const unsigned char *)_str; - if (!str) return FALSE; - while (*str) - { - unsigned char c = *str; - if (c >= 0xC2) // fuck overlongs - { - if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; - else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; - } - str++; - } - return FALSE; -} -#endif - - -int LICE_CachedFont::DrawTextImpl(LICE_IBitmap *bm, const char *str, int strcnt, - RECT *rect, UINT dtFlags) -{ - if (!bm && !(dtFlags&DT_CALCRECT)) return 0; - - bool forceWantAlpha=false; - - if (dtFlags & LICE_DT_NEEDALPHA) - { - forceWantAlpha=true; - dtFlags &= ~LICE_DT_NEEDALPHA; - } - -#if 0 - if ((m_flags&LICE_FONT_FLAG_ALLOW_NATIVE) && - !(m_flags&LICE_FONT_FLAG_PRECALCALL)) - { - HDC hdc = (bm ? bm->getDC() : 0); - if (hdc) - { - ::SetTextColor(hdc,RGB(LICE_GETR(m_fg),LICE_GETG(m_fg),LICE_GETB(m_fg))); - ::SetBkMode(hdc,m_bgmode); - if (m_bgmode==OPAQUE) - ::SetBkColor(hdc,RGB(LICE_GETR(m_bg),LICE_GETG(m_bg),LICE_GETB(m_bg))); - - return ::DrawText(hdc,str,strcnt,rect,dtFlags|DT_NOPREFIX); - } - } -#endif - - // if using line-spacing adjustments (m_lsadj), don't allow native rendering - // todo: split rendering up into invidual lines and DrawText calls - if ((m_flags&LICE_FONT_FLAG_FORCE_NATIVE) && m_font && !forceWantAlpha &&!LICE_Text_IsWine() && - !(dtFlags & LICE_DT_USEFGALPHA) && - !(m_flags&LICE_FONT_FLAG_PRECALCALL) && !LICE_FONT_FLAGS_HAS_FX(m_flags) && - (!m_lsadj || (dtFlags&DT_SINGLELINE))) - { - - // on Win2000+, use wide versions if needed for UTF -#ifdef _WIN32 - WCHAR wtmpbuf[1024]; - WCHAR *wtmp=NULL; - static int win9x; - if (!win9x) win9x = GetVersion() < 0x80000000 ? -1 : 1; //>0 if win9x - if (win9x<0 && LICE_Text_HasUTF8(str)) - { - int req = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,NULL,0); - if (req < 1000) - { - int cnt=0; - if ((cnt=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,wtmpbuf,1024))) - { - wtmp=wtmpbuf; - wtmp[cnt]=0; - } - } - else - { - wtmp = (WCHAR *)malloc((req + 32)*sizeof(WCHAR)); - int cnt=-1; - if (wtmp && !(cnt=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,wtmp,req+1))) - free(wtmp); - else if (cnt>0) wtmp[cnt]=0; - } - } -#endif - - HDC hdc = (bm ? bm->getDC() : 0); - int w = rect->right-rect->left; - int h = rect->bottom-rect->top; - HGDIOBJ oldfont = 0; - RECT srcr={0,}; - bool isTmp=false; - POINT blitPos={0,}; - - static LICE_SysBitmap s_nativerender_tempbitmap; - - if (!hdc) // use temp buffer - { - isTmp=true; - if (w<1)w=1; - if (h<1)h=1; - if (s_nativerender_tempbitmap.getWidth() < w || - s_nativerender_tempbitmap.getHeight() < h) - s_nativerender_tempbitmap.resize(w, h); - - - hdc = s_nativerender_tempbitmap.getDC(); - - oldfont = SelectObject(hdc, m_font); - - RECT blit_r = {0,0}; - int rv= -#ifdef _WIN32 - wtmp ? - ::DrawTextW(hdc,wtmp,-1,&blit_r,(dtFlags&~(DT_CENTER|DT_VCENTER|DT_TOP|DT_BOTTOM|DT_LEFT|DT_RIGHT))|DT_CALCRECT|DT_NOPREFIX) - : -#endif - ::DrawText(hdc,str,strcnt,&blit_r,(dtFlags&~(DT_CENTER|DT_VCENTER|DT_TOP|DT_BOTTOM|DT_LEFT|DT_RIGHT))|DT_CALCRECT|DT_NOPREFIX); - if (dtFlags & DT_CALCRECT) - { - SelectObject(hdc,oldfont); - rect->right = rect->left + blit_r.right - blit_r.left; - rect->bottom = rect->top + blit_r.bottom - blit_r.top; - -#ifdef _WIN32 - if (wtmp!=wtmpbuf)free(wtmp); -#endif - return rv; - } - - if (!bm) return 0; - - // if noclip, resize up - if (dtFlags&DT_NOCLIP) - { - w=blit_r.right-blit_r.left; - h=blit_r.bottom-blit_r.top; - } - - // set new width/height (if shrinking down) - if (blit_r.right-blit_r.left < w) - { - if (dtFlags & DT_RIGHT) blitPos.x = w-(blit_r.right-blit_r.left); - else if (dtFlags & DT_CENTER) blitPos.x=(w-(blit_r.right-blit_r.left))/2; - - w=blit_r.right-blit_r.left; - } - if (blit_r.bottom-blit_r.top < h) - { - if (dtFlags & DT_BOTTOM) blitPos.y = h-(blit_r.bottom-blit_r.top); - else if (dtFlags & DT_VCENTER) blitPos.y=(h-(blit_r.bottom-blit_r.top))/2; - - h=blit_r.bottom-blit_r.top; - } - - if (w > s_nativerender_tempbitmap.getWidth() || - h > s_nativerender_tempbitmap.getHeight()) - { - SelectObject(hdc,oldfont); - s_nativerender_tempbitmap.resize(w, h); - hdc = s_nativerender_tempbitmap.getDC(); - oldfont = SelectObject(hdc, m_font); - } - - blit_r.left=rect->left + blitPos.x; - blit_r.top = rect->top + blitPos.y; - blit_r.right = blit_r.left+w; - blit_r.bottom = blit_r.top+h; - LICE_Blit(&s_nativerender_tempbitmap, bm, 0, 0, &blit_r, 1.0f, LICE_BLIT_MODE_COPY); - srcr.right=w; - srcr.bottom=h; - } - else - { - oldfont = SelectObject(hdc, m_font); - srcr = *rect; - } - - ::SetTextColor(hdc,RGB(LICE_GETR(m_fg),LICE_GETG(m_fg),LICE_GETB(m_fg))); - ::SetBkMode(hdc,m_bgmode); - if (m_bgmode==OPAQUE) ::SetBkColor(hdc,RGB(LICE_GETR(m_bg),LICE_GETG(m_bg),LICE_GETB(m_bg))); - - int ret = -#ifdef _WIN32 - wtmp ? - ::DrawTextW(hdc,wtmp,-1,&srcr,dtFlags|DT_NOPREFIX) - : -#endif - ::DrawText(hdc,str,strcnt,&srcr,dtFlags|DT_NOPREFIX); - - if (isTmp) LICE_Blit(bm, &s_nativerender_tempbitmap, rect->left+blitPos.x, rect->top+blitPos.y, &srcr, m_alpha, LICE_BLIT_MODE_COPY); - else if (dtFlags & DT_CALCRECT) *rect = srcr; - - - SelectObject(hdc, oldfont); -#ifdef _WIN32 - if (wtmp!=wtmpbuf) free(wtmp); -#endif - return ret; - } - - - if (dtFlags & DT_CALCRECT) - { - int xpos=0; - int ypos=0; - int max_xpos=0; - int max_ypos=0; - while (*str && strcnt) - { - unsigned short c=' '; - int charlen = utf8char(str,&c); - str += charlen; - if (strcnt>0) - { - strcnt -= charlen; - if (strcnt<0) strcnt=0; - } - - if (c == '\r') continue; - if (c == '\n') - { - if (dtFlags & DT_SINGLELINE) c=' '; - else - { - if (m_flags&LICE_FONT_FLAG_VERTICAL) - { - xpos+=m_line_height+m_lsadj; - ypos=0; - } - else - { - ypos+=m_line_height+m_lsadj; - xpos=0; - } - continue; - } - } - - charEnt *ent = findChar(c); - if (!ent) - { - int os=m_extracharlist.GetSize(); - RenderGlyph(c); - if (m_extracharlist.GetSize()!=os) - ent = findChar(c); - } - - if (ent && ent->base_offset>=0) - { - if (ent->base_offset == 0) RenderGlyph(c); - - if (ent->base_offset > 0) - { - if (m_flags&LICE_FONT_FLAG_VERTICAL) - { - ypos += ent->advance; - if (xpos+ent->width>max_xpos) max_xpos=xpos+ent->width; - if (ypos>max_ypos) max_ypos=ypos; - } - else - { - xpos += ent->advance; - if (ypos+ent->height>max_ypos) max_ypos=ypos+ent->height; - if (xpos>max_xpos) max_xpos=xpos; - } - } - } - } - - rect->right = rect->left+max_xpos; - rect->bottom = rect->top+max_ypos; - - - return (m_flags&LICE_FONT_FLAG_VERTICAL) ? max_xpos : max_ypos; - } - float alphaSave = m_alpha; - - if (dtFlags & LICE_DT_USEFGALPHA) - { - m_alpha *= LICE_GETA(m_fg)/255.0; - } - - if (m_alpha==0.0) - { - m_alpha=alphaSave; - return 0; - } - - - RECT use_rect=*rect; - int xpos=use_rect.left; - int ypos=use_rect.top; - - bool isVertRev = false; - if ((m_flags&(LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP)) == (LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP)) - isVertRev=true; - - if (dtFlags & (DT_CENTER|DT_VCENTER|DT_RIGHT|DT_BOTTOM)) - { - RECT tr={0,}; - DrawTextImpl(bm,str,strcnt,&tr,DT_CALCRECT|(dtFlags & DT_SINGLELINE)|(forceWantAlpha?LICE_DT_NEEDALPHA:0)); - if (dtFlags & DT_CENTER) - { - xpos += (use_rect.right-use_rect.left-tr.right)/2; - } - else if (dtFlags & DT_RIGHT) - { - xpos = use_rect.right - tr.right; - } - - if (dtFlags & DT_VCENTER) - { - ypos += (use_rect.bottom-use_rect.top-tr.bottom)/2; - } - else if (dtFlags & DT_BOTTOM) - { - ypos = use_rect.bottom - tr.bottom; - } - if (isVertRev) - ypos += tr.bottom; - } - else if (isVertRev) - { - RECT tr={0,}; - DrawTextImpl(bm,str,strcnt,&tr,DT_CALCRECT|(dtFlags & DT_SINGLELINE)|(forceWantAlpha?LICE_DT_NEEDALPHA:0)); - ypos += tr.bottom; - } - - - int start_y=ypos; - int start_x=xpos; - int max_ypos=ypos; - int max_xpos=xpos; - - if (!(dtFlags & DT_NOCLIP)) - { - if (use_rect.left<0)use_rect.left=0; - if (use_rect.top<0) use_rect.top=0; - if (use_rect.right > bm->getWidth()) use_rect.right = bm->getWidth(); - if (use_rect.bottom > bm->getHeight()) use_rect.bottom = bm->getHeight(); - if (use_rect.right <= use_rect.left || use_rect.bottom <= use_rect.top) - { - m_alpha=alphaSave; - return 0; - } - } - else - { - use_rect.left=use_rect.top=0; - use_rect.right = bm->getWidth(); - use_rect.bottom = bm->getHeight(); - } - - - // todo: handle DT_END_ELLIPSIS etc - // thought: calculate length of "...", then when pos+length+widthofnextchar >= right, switch - // might need to precalc size to make sure it's needed, though - - while (*str && strcnt) - { - unsigned short c=' '; - int charlen = utf8char(str,&c); - str += charlen; - if (strcnt>0) - { - strcnt -= charlen; - if (strcnt<0) strcnt=0; - } - if (c == '\r') continue; - if (c == '\n') - { - if (dtFlags & DT_SINGLELINE) c=' '; - else - { - if (m_flags&LICE_FONT_FLAG_VERTICAL) - { - xpos+=m_line_height+m_lsadj; - ypos=start_y; - } - else - { - ypos+=m_line_height+m_lsadj; - xpos=start_x; - } - continue; - } - } - - charEnt *ent = findChar(c); - if (!ent) - { - int os=m_extracharlist.GetSize(); - RenderGlyph(c); - if (m_extracharlist.GetSize()!=os) - ent = findChar(c); - } - - if (ent && ent->base_offset>=0) - { - if (ent->base_offset==0) RenderGlyph(c); - - if (ent->base_offset > 0 && ent->base_offset < m_cachestore.GetSize()) - { - if (isVertRev) ypos -= ent->height; - - bool drawn = DrawGlyph(bm,c,xpos,ypos,&use_rect); - - if (m_flags&LICE_FONT_FLAG_VERTICAL) - { - if (!isVertRev) - { - ypos += ent->advance; - } - else ypos += ent->height - ent->advance; - if (drawn && xpos+ent->width > max_xpos) max_xpos=xpos; - } - else - { - xpos += ent->advance; - if (drawn && ypos+ent->height>max_ypos) max_ypos=ypos+ent->height; - } - } - } - } - - m_alpha=alphaSave; - return (m_flags&LICE_FONT_FLAG_VERTICAL) ? max_xpos - start_x : max_ypos - start_y; -} diff --git a/WDL/lice/makedist.bat b/WDL/lice/makedist.bat deleted file mode 100644 index 124c3cc7..00000000 --- a/WDL/lice/makedist.bat +++ /dev/null @@ -1,2 +0,0 @@ -del lice001.zip -zip -X9r lice001.zip . -i *.cpp *.c *.h *.rc *.ds? *.bmp *.png diff --git a/WDL/lice/test/Controller.h b/WDL/lice/test/Controller.h deleted file mode 100644 index 1256c094..00000000 --- a/WDL/lice/test/Controller.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Controller */ - -#import - -@interface Controller : NSObject -{ -} --(void)awakeFromNib; -@end diff --git a/WDL/lice/test/Controller.mm b/WDL/lice/test/Controller.mm deleted file mode 100644 index 84c418e0..00000000 --- a/WDL/lice/test/Controller.mm +++ /dev/null @@ -1,40 +0,0 @@ -#import "Controller.h" - -#include "../../SWELL/swell.h" -#include "../../SWELL/swell-dlggen.h" - -#include "main.cpp" // this would otherwise conflict in object name with main.m, which xcode made us. - -static HWND ccontrolCreator(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h) -{ - if (!stricmp(classname,"TestRenderingClass")) - { - HWND hw=CreateDialog(NULL,0,parent,(DLGPROC)testRenderDialogProc); - SetWindowLong(hw,GWL_ID,idx); - SetWindowPos(hw,HWND_TOP,x,y,w,h,SWP_NOZORDER|SWP_NOACTIVATE); - ShowWindow(hw,SW_SHOWNA); - return hw; - } - return 0; -} - -@implementation Controller --(void)awakeFromNib -{ - SWELL_RegisterCustomControlCreator(ccontrolCreator); - HWND h=CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,dlgProc); - ShowWindow(h,SW_SHOW); -} -@end - - -// define our dialog box resource! - -SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG1,SWELL_DLG_WS_RESIZABLE|SWELL_DLG_WS_FLIPPED,"LICE Test",400,300,1.8) -BEGIN -CONTROL "",IDC_RECT,"TestRenderingClass",0,7,23,384,239 // we arae creating a custom control here because it will be opaque and therefor a LOT faster drawing -COMBOBOX IDC_COMBO1,7,7,181,170,CBS_DROPDOWNLIST | WS_VSCROLL | -WS_TABSTOP - -END -SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG1) \ No newline at end of file diff --git a/WDL/lice/test/English.lproj/InfoPlist.strings b/WDL/lice/test/English.lproj/InfoPlist.strings deleted file mode 100644 index 997688e2fd53fd8d44166a1895730ea43ed42f47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202 zcmW-ZOAf&R6h+V2DjLH^R7?!S$b{#$5lbf^EkLAW3{7RTh oDE+A9pSg65nVdc!``%jXwyDfqOK2p - - - - IBDocumentLocation - 110 86 356 240 0 0 1440 878 - IBEditorPositions - - 29 - 109 299 338 44 0 0 1440 878 - - IBFramework Version - 446.1 - IBOpenObjects - - 29 - - IBSystem Version - 8R2232 - - diff --git a/WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib b/WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib deleted file mode 100644 index 21c91cb50aaa0a1ae9a0d9aa67cc97b7694c8b95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13648 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 I@6gQu0ZEVR#sB~S diff --git a/WDL/lice/test/Info.plist b/WDL/lice/test/Info.plist deleted file mode 100644 index abca571a..00000000 --- a/WDL/lice/test/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.yourcompany.test - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/WDL/lice/test/fly.cpp b/WDL/lice/test/fly.cpp deleted file mode 100644 index 93f8e4e3..00000000 --- a/WDL/lice/test/fly.cpp +++ /dev/null @@ -1,286 +0,0 @@ -#include "../lice.h" -#include "../../plush2/plush.h" - -#ifndef _WIN32 -#include "../../swell/swell.h" -#endif - - -/* Physical size of land */ -#define LAND_SIZE 65000 -/* Number of divisions of the land. Higher number == more polygons */ -#define LAND_DIV 32 - - // These are the amount the mouse has moved since the last frame - // mouse_b = button status, mouse_avail is whether or not mouse is - // available, mouse_buttons is number of buttons -static float mouse_sens = 8192.0/32768.0; - -static int draw_sky = 1; // do we draw the sky? -static int wait_vsync = 0; // do we wait for vsync? -static pl_Mat *mat[3+1]; // our materials, we have 1 extra for null - // termination for plMatMakeOptPal2() -static pl_Cam *cam; // our camera -static pl_Obj *land; // the land object -static pl_Obj *sky, *sky2; // the two skies -static pl_Light lights[16]; - -static void setup_materials(pl_Mat **mat); - // Sets up the landscape and skies -static pl_Obj *setup_landscape(pl_Mat *m, pl_Mat *sm, pl_Mat *sm2); - -void doFlyEffect(LICE_IBitmap *fb, HWND hwnd) -{ - static int initted; - if (!initted) - { - initted=1; - cam = new pl_Cam; - cam->Fov=90.0; - cam->WantZBuffer=true; - if (cam->WantZBuffer) cam->Sort = -1; - cam->Y = 800; // move the camera up from the ground - cam->Pitch = 180.0; - - setup_materials(mat); // intialize materials and palette - - land = setup_landscape(mat[0],mat[1],mat[2]); // create landscape - sky = land->Children.Get(0); // unhierarchicalize the sky from the land - land->Children.Delete(0); - sky2 = land->Children.Get(0); - land->Children.Delete(0); - - int x; - for(x=0;xBegin(fb); - - int x; - for(x=0;xRenderLight(&lights[x]); - - // lots of rendering special casing - if (draw_sky) { // if we're drawing the sky - if (cam->Y > 2000) { // if above the sky, only render the skies, with - // no far clip plane - - cam->RenderObject(sky); - cam->RenderObject(sky2); - } else { // otherwise, render the sky (but not the second sky), - // and the land, with a far clip plane - - - cam->RenderObject(sky); - cam->RenderObject(land); - } - } else { // not drawing sky, just render the land - - cam->RenderObject(land); - } - cam->End(); // finish rendering - - static POINT lpos; - POINT p; - GetCursorPos(&p); - int mouse_x = 0; - int mouse_y = 0; - int mouse_b=0; - - if (hwnd) - { - mouse_x = p.x-lpos.x; - mouse_y = p.y-lpos.y; - if (GetAsyncKeyState(VK_RBUTTON)&0x8000) mouse_b|=2; - - RECT r; - GetWindowRect(hwnd,&r); - p.x=(r.right+r.left)/2; - p.y=(r.bottom+r.top)/2; - SetCursorPos(p.x,p.y); - } - lpos=p; - // We calculate the amount of time in thousanths of seconds this frame took - double prevtime = 10; //((uclock() / (float) UCLOCKS_PER_SEC) - prevtime)*1000.0; - - if (mouse_b & 2) { // if right button hit, we go forward quickly - cam->X -= - prevtime*4*sin(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); - cam->Z += - prevtime*4*cos(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); - cam->Y += - prevtime*4*sin(cam->Pitch*PL_PI/180.0); - } else if (mouse_b & 1) { // if left button hit, we go forward slowly - cam->X -= - prevtime*2*sin(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); - cam->Z += - prevtime*2*cos(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); - cam->Y += - prevtime*2*sin(cam->Pitch*PL_PI/180.0); - } - cam->Pitch += (mouse_y*mouse_sens); // update pitch and pan of ship - cam->Pan += (mouse_x*mouse_sens)*(-cos(cam->Pitch*PL_PI/180.0)); - - if (cam->X > LAND_SIZE/2) cam->X = LAND_SIZE/2; // make sure we don't go - if (cam->X < -LAND_SIZE/2) cam->X = -LAND_SIZE/2; // too far away - if (cam->Z > LAND_SIZE/2) cam->Z = LAND_SIZE/2; - if (cam->Z < -LAND_SIZE/2) cam->Z = -LAND_SIZE/2; - if (cam->Y < 0) cam->Y = 0; - if (cam->Y > 8999) cam->Y = 8999; -#if 0 - - while (kbhit()) switch(getch()) { // handle keystrokes - case 27: done++; break; // ESC == quit - // + is for zooming in. - case '=': case '+': cam->Fov -= 1.0; if (cam->Fov < 1.0) cam->Fov = 1.0; - sprintf(lastmessage,"FOV: %2.f",cam->Fov); - break; - // - is for zooming out - case '-': cam->Fov += 1.0; if (cam->Fov > 179.0) cam->Fov = 179.0; - sprintf(lastmessage,"FOV: %2.f",cam->Fov); - break; - // [ decreases mouse sensitivity - case '[': mouse_sens /= 1.1; - sprintf(lastmessage,"MouseSens: %.3f",mouse_sens); - break; - // ] increases mouse sensitivity - case ']': mouse_sens *= 1.1; - sprintf(lastmessage,"MouseSens: %.3f",mouse_sens); - break; - // v toggles vsync - case 'v': wait_vsync ^= 1; - sprintf(lastmessage,"VSync %s",wait_vsync ? "on" : "off"); - break; - // s toggles sky - case 's': draw_sky ^= 1; - sprintf(lastmessage,"Sky %s",draw_sky ? "on" : "off"); - break; - } -#endif - - //LICE_ScaledBlit(fb,mat[2]->Texture,0,0,fb->getWidth(),fb->getHeight(),0,0,mat[2]->Texture->getWidth(),mat[2]->Texture->getHeight(),1.0f,0); -} - - - - -static void setup_materials(pl_Mat **mat) { - // create our 3 materials, make the fourth null so that plMatMakeOptPal2() - // knows where to stop - mat[0] = new pl_Mat; - mat[1] = new pl_Mat; - mat[2] = new pl_Mat; - mat[3] = 0; - - extern LICE_IBitmap *bmp; - // set up material 0 (the ground) - mat[0]->Smoothing = true; - mat[0]->Lightable=true; - mat[0]->Ambient[0] = 0.0; // these calculations are to get the - mat[0]->Ambient[1] = 0.0; // distance shading to work right - mat[0]->Ambient[2] = 0.0; - mat[0]->Diffuse[0] = 1.0; - mat[0]->Diffuse[1] = 1.0; - mat[0]->Diffuse[2] = 1.0; - mat[0]->FadeDist = 10000.0; - mat[0]->Texture2 = LICE_LoadPCX("c:\\ground.pcx"); - if (!mat[0]->Texture2) - { - mat[0]->Texture2 = new LICE_MemBitmap(400,400); -// LICE_TexGen_Marble(mat[0]->Texture2,NULL,1.0,0.8,0.8,1.0f); - LICE_TexGen_Noise(mat[0]->Texture2,NULL,1.0,1.0,1.0,1.0f,NOISE_MODE_WOOD,8); - } - - mat[0]->Texture=mat[0]->Texture2; - mat[0]->Texture2=bmp; - mat[0]->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; - mat[0]->Tex2CombineMode=LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR; - mat[0]->Tex2Scaling[1]= - mat[0]->Tex2Scaling[0] = 40.0*LAND_SIZE/50000; - mat[0]->TexScaling[1]= - mat[0]->TexScaling[0] = 40.0*LAND_SIZE/50000; - mat[0]->Tex2MapIdx=0; - mat[0]->PerspectiveCorrect = 16; - mat[0]->BackfaceIllumination=1.0; - - // set up material 1 (the sky) - mat[1]->Lightable=true; - mat[1]->Ambient[0] = 0.4; // these calculations are to get the - mat[1]->Ambient[1] = 0.4; // distance shading to work right - mat[1]->Ambient[2] = 0.4; - mat[1]->Diffuse[0] = 1.0; - mat[1]->Diffuse[1] = 1.0; - mat[1]->Diffuse[2] = 1.0; - mat[1]->FadeDist = 10000.0; - mat[1]->Texture = LICE_LoadPCX("c:\\sky.pcx"); - mat[1]->TexCombineMode=LICE_BLIT_MODE_MUL; - mat[1]->TexScaling[1] = mat[1]->TexScaling[0] = 45.0*LAND_SIZE/50000; - mat[1]->PerspectiveCorrect = 32; - mat[1]->BackfaceCull=false; - mat[1]->BackfaceIllumination=1.0; - - if (!mat[1]->Texture) - { - mat[1]->Texture = new LICE_MemBitmap(400,400); - LICE_TexGen_Noise(mat[1]->Texture,NULL,0.0,0.0,1.0,1.0f,NOISE_MODE_WOOD,8); - } - mat[1]->Texture2=bmp; - mat[1]->Tex2CombineMode= LICE_BLIT_MODE_HSVADJ|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA; - mat[1]->Tex2Scaling[1] = mat[1]->Tex2Scaling[0] = 45.0*LAND_SIZE/50000*0.37; - mat[1]->Tex2MapIdx=0; - - // set up material 2 (the second sky) - mat[2]->Lightable=true; - mat[2]->Smoothing=false; - mat[2]->Ambient[0] = 0.2; // these calculations are to get the - mat[2]->Ambient[1] = 0.2; // distance shading to work right - mat[2]->Ambient[2] = 0.2; - mat[2]->Diffuse[0] = 0.0; - mat[2]->Diffuse[1] = 0.0; - mat[2]->Diffuse[2] = 0.0; - mat[2]->Texture = LICE_LoadPCX("c:\\sky2.pcx"); - if (!mat[2]->Texture) - { - mat[2]->Texture = new LICE_MemBitmap(400,400); - LICE_TexGen_Marble(mat[2]->Texture,NULL,0.3,0,0.4,0.4); - } - mat[2]->TexScaling[0] = mat[2]->TexScaling[1] = 10.0; //200.0*LAND_SIZE/50000; - mat[2]->TexCombineMode=LICE_BLIT_MODE_COPY; - mat[2]->PerspectiveCorrect = 16; - - mat[2]->Texture2=bmp; - mat[2]->Tex2CombineMode= LICE_BLIT_MODE_HSVADJ|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA; - mat[2]->Tex2Scaling[1] = mat[1]->Tex2Scaling[0] = 45.0*LAND_SIZE/50000*3.37; - mat[2]->Tex2MapIdx=0; - -} - -pl_Obj *setup_landscape(pl_Mat *m, pl_Mat *sm, pl_Mat *sm2) { - int i; - // make our root object the land - pl_Obj *o = plMakePlane(LAND_SIZE,LAND_SIZE,LAND_DIV-1,m); - // give it a nice random bumpy effect - for (i = 0; i < o->Vertices.GetSize(); i ++) - o->Vertices.Get()[i].y += (float) (rand()%1400)-700; - // gotta recalculate normals for backface culling to work right - o->CalculateNormals(); - - // Make our first child the first sky - o->Children.Add(plMakePlane(LAND_SIZE,LAND_SIZE,30,sm)); - o->Children.Get(0)->Yp = 2000; - - // and the second the second sky - o->Children.Add(plMakeSphere(LAND_SIZE,10,10,sm2)); - o->Children.Get(1)->Yp = 2000; - o->Children.Get(1)->FlipNormals(); - - return (o); -} - diff --git a/WDL/lice/test/image.png b/WDL/lice/test/image.png deleted file mode 100644 index ae855918e8c8a4f00eaf76e31df45bdfc43976fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4910 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 diff --git a/WDL/lice/test/imgs2gif.cpp b/WDL/lice/test/imgs2gif.cpp deleted file mode 100644 index 4d270a0b..00000000 --- a/WDL/lice/test/imgs2gif.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include - -#include "../lice.h" - -void usage(const char *a, const char *b) -{ - if (a||b) printf("%s: %s\n",a,b); - printf("Usage: imgs2gif [-w width] [-h height] [-d ms] [-skipempty] [-leaddelay ms] output.gif file1.jpg [file2.png ...]\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - int delay=10; - int size_w=0,size_h=0; - int i; - int rv=0; - int leaddelay=0; - bool skipempty=false; - void *gifOut=NULL; - const char *fn=NULL; - - LICE_MemBitmap lastfr, fr,fr2; - int accum_lat=0; - - for (i=1;i= argc) usage("Missing parameter",argv[i-1]); - size_w = atoi(argv[i]); - } - else if (!strcmp(argv[i],"-h")) - { - if (++i >= argc) usage("Missing parameter",argv[i-1]); - size_h = atoi(argv[i]); - } - else if (!strcmp(argv[i],"-d")) - { - if (++i >= argc) usage("Missing parameter",argv[i-1]); - delay = atoi(argv[i]); - } - else if (!strcmp(argv[i],"-skipempty")) skipempty=true; - else if (!strcmp(argv[i],"-leaddelay")) - { - if (++i >= argc) usage("Missing parameter",argv[i-1]); - leaddelay=atoi(argv[i]); - } - else usage("Unknown option",argv[i]); - } - else if (!fn) fn=argv[i]; - else - { - printf("Loading %s\n",argv[i]); - if (!LICE_LoadImage(argv[i],&fr) || !fr.getWidth() || !fr.getHeight()) - { - printf("Error loading image: %s\n",argv[i]); - continue; - } - - if (!size_w) size_w=fr.getWidth(); - if (!size_h) size_h=fr.getHeight(); - LICE_MemBitmap *usefr = &fr; - if (fr.getWidth() != size_w || fr.getHeight() != size_h) - { - fr2.resize(size_w,size_h); - LICE_ScaledBlit(usefr=&fr2,&fr,0,0,size_w,size_h,0,0,fr.getWidth(),fr.getHeight(),1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - - if (!gifOut) - { - gifOut=LICE_WriteGIFBegin(fn,usefr,0,leaddelay?leaddelay:delay,false); - if (!gifOut) usage("Error writing to file",fn); - } - else - { - accum_lat += delay; - int diffcoords[4]={0,0,size_w,size_h}; - if (LICE_BitmapCmp(usefr,&lastfr,diffcoords)) - { - LICE_SubBitmap bm(usefr,diffcoords[0],diffcoords[1], diffcoords[2],diffcoords[3]); - LICE_WriteGIFFrame(gifOut,&bm,diffcoords[0],diffcoords[1], true, accum_lat); - accum_lat=0; - } - if (skipempty) accum_lat=0; - } - - LICE_Copy(&lastfr,usefr); - } - } - printf("finishing up\n"); - if (gifOut) LICE_WriteGIFEnd(gifOut); - - return rv; -} diff --git a/WDL/lice/test/main.cpp b/WDL/lice/test/main.cpp deleted file mode 100644 index 8e48bee0..00000000 --- a/WDL/lice/test/main.cpp +++ /dev/null @@ -1,1026 +0,0 @@ -/* - Cockos WDL - LICE - Lightweight Image Compositing Engine - Copyright (C) 2007 and later, Cockos Incorporated - File: main.cpp (example use of LICE) - See lice.h for license and other information -*/ - -#include "../lice.h" -#include "../../plush2/plush.h" -#include "../../MersenneTwister.h" -#include -#include - -#include "../lice_text.h" - -#include "../lice_glbitmap.h" -//#define GLEW_STATIC -//#include "../glew/include/gl/glew.h" -//#include "../glew/include/gl/wglew.h" - -//uncomment this to enable the ffmpeg video output in test 1 -//#define FFMPEG_TEST - -//#define TIMING -#include "../../timing.c" - -#ifdef FFMPEG_TEST -//ffmpeg encoding test -#include "../../ffmpeg.h" -#pragma comment(lib, "../../../sdks/ffmpeg/lib/avcodec.lib") -#pragma comment(lib, "../../../sdks/ffmpeg/lib/avformat.lib") -#pragma comment(lib, "../../../sdks/ffmpeg/lib/avutil.lib") -#pragma comment(lib, "../../../sdks/ffmpeg/lib/swscale.lib") -static WDL_VideoEncode *m_encoder; -static WDL_VideoDecode *m_decoder; -#endif - -#include "resource.h" - -#define NUM_EFFECTS 25 - -char *effect_names[NUM_EFFECTS] = -{ - "Rotated + Scaled blit", - "Simple alpha blit", - "Rotated blit", - "Scaled blit", - "GradRect", - "Marble generator", - "Wood generator", - "Noise generator", - "Circular noise generator", - "GradRect + text + rotated blit", - "PutPixel", - "Line", - "DrawText", - "Icon loading", - "Circles, Arc", - "Rotated + Multiply add blit", - "Transform blit", - "Plush 3D", - "3D Fly (use mouse)", - "SVG loading (C:\\test.svg)", - "GL acceleration (disabled)", - "Bezier curves", - "Convex polygon fill", - "Palette generator (C:\\test.png)", - "Triangle test", -}; - -HINSTANCE g_hInstance; -LICE_IBitmap *jpg; -LICE_IBitmap *bmp; -LICE_IBitmap *icon; -LICE_IBitmap *framebuffer; -static int m_effect = NUM_EFFECTS-1; -static int m_doeff = 0; - -static LICE_IBitmap* tmpbmp = 0; - -static DWORD m_start_time, m_frame_cnt; -bool m_cap; - - -static void DoPaint(HWND hwndDlg) -{ - PAINTSTRUCT ps; - - HDC dc = BeginPaint(hwndDlg, &ps); - RECT r; - GetClientRect(hwndDlg, &r); - -#ifdef _WIN32 - r.top+=40; - if (r.top >= r.bottom) r.top=r.bottom-1; -#endif - - if (framebuffer->resize(r.right-r.left,r.bottom-r.top)) - { - m_doeff=1; - // memset(framebuffer->getBits(),0,framebuffer->getWidth()*framebuffer->getHeight()*4); - } - - int x=rand()%(r.right+300)-150; - int y=rand()%(r.bottom+300)-150; - - static int s_preveff = -1; - if (m_effect != s_preveff) - { - s_preveff = m_effect; - LICE_Clear(framebuffer, 0); - } - - static MTRand s_rng; - - switch(m_effect) - { - case 23: - { - const int palnumcols=256; - - static int init=0; - static LICE_IBitmap* srcbmp=0; - static LICE_IBitmap* palbmp=0; - static LICE_pixel palette[palnumcols] = { 0 }; - - if (!init) - { - init=-1; - srcbmp = LICE_LoadPNG("C:\\test.png"); - if (srcbmp) - { - int n = LICE_BuildPalette(srcbmp, palette, palnumcols); - palbmp = new LICE_MemBitmap; - LICE_Copy(palbmp, srcbmp); - void LICE_TestPalette(LICE_IBitmap*, LICE_pixel*, int); - LICE_TestPalette(palbmp, palette, n); - init=1; - } - } - - if (init > 0) - { - static int lastw=0; - static int lasth=0; - if (lastw != framebuffer->getWidth() || lasth != framebuffer->getHeight()) - { - lastw = framebuffer->getWidth(); - lasth = framebuffer->getHeight(); - int y = framebuffer->getHeight()*3/4; - LICE_ScaledBlit(framebuffer, srcbmp, 0, 0, lastw/2, y, 0, 0, srcbmp->getWidth(), srcbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(framebuffer, palbmp, lastw/2, 0, lastw/2, y, 0, 0, palbmp->getWidth(), palbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - - int dy = (lasth-y)/4; - int dx = lastw/(palnumcols/4); - int i, j, k=0; - for (i = 0; i < 4; ++i) - { - for (j = 0; j < palnumcols/4; ++j) - { - LICE_FillRect(framebuffer, j*dx, y+i*dy, dx, dy, palette[k++], 1.0f, LICE_BLIT_MODE_COPY); - } - } - } - } - } - break; - case 24: - { - LICE_MemBitmap bm(128,128); - LICE_Clear(framebuffer,0); - LICE_Clear(&bm,0); - - static POINT sp; - POINT p; - if (!sp.x&&!sp.y) GetCursorPos(&sp); - GetCursorPos(&p); - p.x-=sp.x; - p.y-=sp.y; - int th=p.y+16; - bool flip = th < 0; - if (flip) th=-th; - int tw=p.x+16; - int cx=(tw+1)/2; - int x=1,y=1; - LICE_pixel lc=LICE_RGBA(255,0,255,255); - LICE_Line(&bm,x,y,x+tw,y,lc,1.0f,LICE_BLIT_MODE_COPY); - LICE_Line(&bm,x,y+th,x+tw,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); - LICE_Line(&bm,x+tw,y,x+tw,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); - LICE_Line(&bm,x,y,x,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); - - LICE_FillTriangle(&bm,x+tw,y+(flip?th:0)/*+th/4*/,x+cx,y+(flip?0:th),x,y+(flip?th:0),LICE_RGBA(255,255,255,255),0.75f,LICE_BLIT_MODE_COPY); - - int sc=16; - LICE_ScaledBlit(framebuffer,&bm,0,0,bm.getWidth()*sc,bm.getHeight()*sc,0,0,bm.getWidth(),bm.getHeight(),1.0,LICE_BLIT_MODE_COPY); - for (y=0;ygetWidth(); - int h = framebuffer->getHeight(); - - static bool init = false; - if (!init) - { - init = true; - for (i = 0; i < 16; ++i) - { - x[i] = s_rng.randInt(w-1); - y[i] = s_rng.randInt(h-1); - } - } - - for (i = 0; i < 16; ++i) - { - x[i] += s_rng.randNorm(0.0, 1.0)+0.5; - y[i] += s_rng.randNorm(0.0, 1.0)+0.5; - if (x[i] < 0) x[i] = 0; - else if (x[i] >= w) x[i] = w-1; - if (y[i] < 0) y[i] = 0; - else if (y[i] >= h) y[i] = h-1; - } - - LICE_Clear(framebuffer, 0); - LICE_FillConvexPolygon(framebuffer, x, y, 16, LICE_RGBA(96,96,96,255), 0.5f, LICE_BLIT_MODE_ADD); - - for (i = 0; i < 16; ++i) - { - LICE_Line(framebuffer, x[i]-1, y[i], x[i]+1, y[i], LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY); - LICE_Line(framebuffer, x[i], y[i]-1, x[i], y[i]+1, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY); - } - } - break; - - case 21: - { - int w = framebuffer->getWidth(); - int h = framebuffer->getHeight(); - - int x0, y0, x1, y1, x2, y2, x3, y3; - - bool aa = true; - float maxsegmentpx = 0.0f; - - x0 = w*rand()/RAND_MAX; - y0 = h*rand()/RAND_MAX; - x1 = w*rand()/RAND_MAX; - y1 = h*rand()/RAND_MAX; - x2 = w*rand()/RAND_MAX; - y2 = h*rand()/RAND_MAX; - LICE_DrawQBezier(framebuffer, x0, y0, x1, y1, x2, y2, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY, aa, maxsegmentpx); - - x0 = w*rand()/RAND_MAX; - y0 = h*rand()/RAND_MAX; - x1 = w*rand()/RAND_MAX; - y1 = h*rand()/RAND_MAX; - x2 = w*rand()/RAND_MAX; - y2 = h*rand()/RAND_MAX; - x3 = w*rand()/RAND_MAX; - y3 = h*rand()/RAND_MAX; - LICE_DrawCBezier(framebuffer, x0, y0, x1, y1, x2, y2, x3, y3, LICE_RGBA(0,255,0,255), 1.0f, LICE_BLIT_MODE_COPY, aa, maxsegmentpx); - } - break; - -#ifndef DISABLE_LICE_EXTENSIONS - case 20: // GL acceleration - { - int w = framebuffer->getWidth(); - int h = framebuffer->getHeight(); - - int x, y, tw, th; - - static LICE_IBitmap* glbmp = 0; - if (!glbmp) - { - glbmp = new LICE_GL_SysBitmap(0, 0); - glbmp->resize(w, h); - - glbmp = new LICE_GL_SubBitmap(glbmp, 20, 80, 50, 20); - - framebuffer = glbmp; - } - - if (!tmpbmp) - { - tmpbmp = new LICE_GL_MemBitmap(0, 0); - tmpbmp->resize(20, 20); - //tmpbmp = new LICE_MemBitmap(20, 20); - } - - LICE_Clear(tmpbmp, LICE_RGBA(255,0,0,255)); - LICE_Line(tmpbmp, 0, 0, 20, 20, LICE_RGBA(255,255,255,255), 1.0f, LICE_BLIT_MODE_COPY, true); - - static int _n = 0; - - //if (_n < 3) - { - //LICE_Clear(glbmp, LICE_RGBA(0,0,0,0)); - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - LICE_Blit(glbmp, tmpbmp, x, y, 0, 0, 20, 20, 1.0f, LICE_BLIT_MODE_COPY); // blit one GL bitmap to another - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - LICE_ScaledBlit(glbmp, tmpbmp, x, y, 40, 40, 0, 0, 20, 20, 1.0f, LICE_BLIT_MODE_COPY); // blit one GL bitmap to another - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - tw = (w-x)*rand()/RAND_MAX; - th = (h-y)*rand()/RAND_MAX; - int color = (_n%2 ? LICE_RGBA(63,63,63,255) : LICE_RGBA(0,0,0,255)); - LICE_FillRect(glbmp, x, y, tw, th, color, 1.0f, LICE_BLIT_MODE_COPY); - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - tw = (w-x)*rand()/RAND_MAX; - th = (h-y)*rand()/RAND_MAX; - LICE_Line(glbmp, x, y, x+tw, y+th, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY, true); - - int x0 = w*rand()/RAND_MAX; - int y0 = h*rand()/RAND_MAX; - int x1 = w*rand()/RAND_MAX; - int y1 = h*rand()/RAND_MAX; - int x2 = w*rand()/RAND_MAX; - int y2 = h*rand()/RAND_MAX; - int x3 = w*rand()/RAND_MAX; - int y3 = h*rand()/RAND_MAX; - LICE_DrawCBezier(glbmp, x0, y0, x1, y1, x2, y2, x3, y3, LICE_RGBA(0,255,0,255), 1.0f, LICE_BLIT_MODE_COPY, true); - - #define A(x) ((LICE_pixel_chan)((x)*255.0+0.5)) - - LICE_pixel_chan alphas[81] = - { - A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00), - A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), - A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), - A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), - A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), - A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), - A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), - A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00) - }; - int gw = 9; - int gh = 9; - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - LICE_DrawGlyph(glbmp, x, y, LICE_RGBA(255,255,0,255), alphas, gw, gh, 1.0f, LICE_BLIT_MODE_COPY); - - static LICE_CachedFont* font = 0; - if (!font) - { - font = new LICE_CachedFont; - LOGFONT lf={ 12, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial"}; - HFONT hf = CreateFontIndirect(&lf); - font->SetFromHFont(hf, 0); - font->SetTextColor(LICE_RGBA(255,255,0,255)); - } - - x = w*rand()/RAND_MAX; - y = h*rand()/RAND_MAX; - RECT r = { x, y, x+40, y+10 }; - font->DrawText(glbmp, "foo bar", -1, &r, 0); - - } - ++_n; - } - break; -#endif - - case 18: - { - void doFlyEffect(LICE_IBitmap *fb,HWND); - doFlyEffect(framebuffer,m_cap ? hwndDlg : NULL); - } - break; - - case 17: - { - static pl_Obj *obj=NULL,*obj2=NULL; - if (!obj) - { - pl_Mat *mat = new pl_Mat; - pl_Mat *mat2 = new pl_Mat; - - mat2->Smoothing=false; - mat2->Ambient[0]=mat2->Ambient[1]=mat2->Ambient[2]=0.0; - mat2->Diffuse[0]=mat2->Diffuse[1]=0.6; - mat2->Diffuse[2]=1.0; - - mat->Ambient[0]=mat->Ambient[1]=mat->Ambient[2]=0.0; - mat->Diffuse[0]=mat->Diffuse[1]=1.9; - mat->Diffuse[2]=0.4; - - mat->PerspectiveCorrect=16; - mat->SolidCombineMode=LICE_BLIT_MODE_COPY; - mat->SolidOpacity=1.0; - mat->Smoothing=true; - mat->Lightable=true; - //mat->FadeDist = 300.0; - - mat2->Texture=bmp; - mat2->TexOpacity=0.5; - mat2->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; - mat2->SolidOpacity=0.4; - mat2->BackfaceCull=false; - mat2->BackfaceIllumination=1.0; - - mat->Texture=bmp; - LICE_TexGen_Marble(mat->Texture = new LICE_MemBitmap(r.right,r.bottom),NULL,0.3,0.4,0.0,1.0f); - - mat->TexOpacity=0.5; - mat->TexScaling[0]=mat->TexScaling[1]=3.0; - mat->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; - - LICE_TexGen_Noise(mat->Texture2 = new LICE_MemBitmap(r.right,r.bottom),NULL,0.3,0.4,0.0,1.0f); - // mat->Texture2=icon; - mat->Tex2MapIdx=-1; - mat->Tex2CombineMode=LICE_BLIT_MODE_ADD|LICE_BLIT_FILTER_BILINEAR; - mat->Tex2Opacity=0.8; - mat->Tex2Scaling[0]=2.0; - mat->Tex2Scaling[1]=-2.0; - - mat->BackfaceCull=true; - mat->BackfaceIllumination=0.0; - - obj=plMakeTorus(100.0,80.0,40,40,mat); - - int x; - if (0)for(x=1;x<3;x++) - { - pl_Obj *no = obj->Clone(); - no->Translate(0,40.0,-x*35.0); - obj->Children.Add(no); - no->Xa += 50.35*x; - no->Ya -= 30.13*x; - } - obj2=plMakeBox(130,130,130,mat2); - - /*pl_Obj *o = plRead3DSObj("c:\\temp\\suzanne.3ds",mat); - if (o) - { - o->Scale(30.0); - o->Translate(150.0,0,0); - obj->Children.Add(o); - } - */ - } - obj2->Xa+=0.3; - obj2->Ya+=-0.1; - obj->Ya+=0.1; - obj->Xa+=0.1; - obj->Za+=0.1; - obj->GenMatrix=true; - - if (1) LICE_Clear(framebuffer,0); - else { - double a=GetTickCount()/1000.0; - - double scale=(1.1+sin(a)*0.3); - - LICE_RotatedBlit(framebuffer,framebuffer,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,254/255.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - static pl_Cam cam; - LICE_SubBitmap tmpbm(framebuffer,10,10,framebuffer->getWidth()-20,framebuffer->getHeight()-20); - //cam.CenterX = (tmpbm.getWidth()/2+80); - //cam.CenterY = (tmpbm.getHeight()/2+80); - cam.AspectRatio = 1.0;//cam.frameBuffer->getWidth()* 3.0/4.0 / (double)cam.frameBuffer->getHeight(); - cam.X = cam.Y = 0.0; - cam.Z = -200.0; - cam.WantZBuffer=true; - cam.SetTarget(0,0,0); - - - - static pl_Light light; - light.Set(PL_LIGHT_POINT,500.0,0,-900.0,1.3f,0.5f,0.5f,1000.0); - static pl_Light light2; - light2.Set(PL_LIGHT_POINT,-500.0,0,-700.0,0.0f,1.0f,0.5f,1000.0); - cam.ClipBack=220.0; - - cam.Begin(&tmpbm); - cam.RenderLight(&light); - cam.RenderLight(&light2); - cam.RenderObject(obj); - cam.SortToCurrent(); - cam.RenderObject(obj2); - cam.End(); - - char buf[512]; - sprintf(buf,"tri: %d->%d->%d, pix=%.0f", - cam.RenderTrisIn, - cam.RenderTrisCulled, - cam.RenderTrisOut,cam.RenderPixelsOut); - LICE_DrawText(framebuffer,0,10,buf,LICE_RGBA(255,255,255,255),1.0f,0); - - } - break; - case 15: - case 0: - { - double a=.51;//GetTickCount()/1000.0; - - double scale=(1.1+sin(a)*0.3); - - if (0) // weirdness - { - LICE_RotatedBlit(framebuffer,framebuffer,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,254/255.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - else // artifact-free mode - { - LICE_MemBitmap framebuffer_back; - - LICE_Copy(&framebuffer_back,framebuffer); - LICE_RotatedBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - timingEnter(0); - LICE_ScaledBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,-200,-200,3000,3000,0.1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - timingLeave(0); - timingEnter(1); - LICE_ScaledBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,0,0,r.right/2,r.bottom/2,0.1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - timingLeave(1); - } - //LICE_Clear(framebuffer,0); - if (bmp) LICE_RotatedBlit(framebuffer,bmp,r.right*scale,r.bottom*scale,r.right*(1.0-scale*2.0),r.bottom*(1.0-scale*2.0),0,0,bmp->getWidth(),bmp->getHeight(),cos(a*0.3)*13.0,false,0.3,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR); - - if (m_effect==15) - { - LICE_MultiplyAddRect(framebuffer,0,0,framebuffer->getWidth(),framebuffer->getHeight(),0.9,0.9,-0.3,1, - 3,2,200,0); - } - - -#ifdef FFMPEG_TEST - -#if 0 - //ffmpeg encoding test - if(!m_encoder) m_encoder = new WDL_VideoEncode("flv", framebuffer->getWidth(),framebuffer->getHeight(), 25, 1256, NULL, 44100, 1, 128); - if(m_encoder->isInited()) - { - //set the alpha bit to 0xff - //LICE_FillRect(framebuffer, 0, 0, framebuffer->getWidth(), framebuffer->getHeight(), LICE_RGBA(0,0,0,255), 1.0f, LICE_BLIT_MODE_ADD); - m_encoder->encodeVideo(framebuffer->getBits()); - - static short audiodata[2000]={0,}; - static int initaudio=0; - if(!initaudio) - { - float t = 0; - for(int j=0;j<2000;j++) - { - audiodata[j] = (int)(sin(t) * 10000); - t += 2 * M_PI * 440.0 / 44100; - } - initaudio = 1; - } - m_encoder->encodeAudio(audiodata, 44100/25); - - static WDL_HeapBuf h; - h.Resize(256*1024); - unsigned char *p = (unsigned char *)h.Get(); - int s = m_encoder->getBytes(p, 256*1024); - if(s) - { - FILE *fh = fopen("c:\\temp\\out.flv", "ab"); - fwrite(p, s, 1, fh); - fclose(fh); - } - } -#else - //ffmpeg decoding test - if(!m_decoder) m_decoder = new WDL_VideoDecode("c:\\test.avi"); - if(m_decoder->isInited()) - { - static LICE_IBitmap *m_tmpframe; - static double t = 0; - if(!m_tmpframe) - { - m_tmpframe = new LICE_MemBitmap(framebuffer->getWidth(), framebuffer->getHeight()); - } - m_decoder->GetVideoFrameAtTime(m_tmpframe, t, NULL, &t, true); - t+=0.0001; - LICE_Blit(framebuffer, m_tmpframe, 0, 0, 0, 0, m_tmpframe->getWidth(), m_tmpframe->getHeight(), 1.0f, 0); - } -#endif - -#endif - - - } - break; - case 1: - if (rand()%6==0) - LICE_Blit(framebuffer,bmp,x,y,NULL,-1.4,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA); - else - LICE_Blit(framebuffer,bmp,x,y,NULL,0.6,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - break; - case 2: - { - LICE_Clear(framebuffer,0); - double a=GetTickCount()/1000.0; - - double scale=(1.1+sin(a)*0.3); - if (bmp) LICE_RotatedBlit(framebuffer,bmp,r.right*scale,r.bottom*scale,r.right*(1.0-scale*2.0),r.bottom*(1.0-scale*2.0),0,0,bmp->getWidth(),bmp->getHeight(),cos(a*0.3)*13.0,false,1.0,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR,0.0,-bmp->getHeight()/2); - } - break; - case 3: - { - LICE_Clear(framebuffer,LICE_RGBA(128,128,128,128)); - static double a; - a+=0.003; - int xsize=sin(a*1.1)*r.right*10.5; - int ysize=sin(a*1.7)*r.bottom*10.5; - int xp = sin(a*0.3+1515851)*r.right*0.5; - int yp = sin(a*0.3+15853)*r.bottom*0.5; - - if (bmp) - { -// if (rand()%3==0) - // LICE_ScaledBlit(framebuffer,bmp,r.right/2-xsize/2,r.bottom/2-ysize/2,xsize,ysize,0.0,0.0,bmp->getWidth(),bmp->getHeight(),-0.7,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_ADD|LICE_BLIT_FILTER_BILINEAR); - /// else - LICE_ScaledBlit(framebuffer,bmp,xp + r.right/2-xsize/2,yp + r.bottom/2-ysize/2,xsize,ysize,-300,-300,600+bmp->getWidth(),600+bmp->getHeight(),1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - } - break; - case 4: - case 9: - - { - static double a; - a+=0.003; - - LICE_GradRect(framebuffer,0,0,framebuffer->getWidth(),framebuffer->getHeight(), - 0.5*sin(a*14.0),0.5*cos(a*2.0+1.3),0.5*sin(a*4.0),1.0, - (cos(a*37.0))/framebuffer->getWidth()*0.5,(sin(a*17.0))/framebuffer->getWidth()*0.5,(cos(a*7.0))/framebuffer->getWidth()*0.5,0, - (sin(a*12.0))/framebuffer->getHeight()*0.5,(cos(a*4.0))/framebuffer->getHeight()*0.5,(cos(a*3.0))/framebuffer->getHeight()*0.5,0, - LICE_BLIT_MODE_COPY); - - - if (m_effect==9) - { - /* LOGFONT lf={ - 140,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, - OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, - "Times New Roman" - }; - HFONT font=CreateFontIndirect(&lf); - - */ - - - LICE_SysBitmap bm(60,60); - LICE_Clear(&bm,LICE_RGBA(0,0,0,0)); - SetTextColor(bm.getDC(),RGB(255,255,255)); - SetBkMode(bm.getDC(),TRANSPARENT); - // HGDIOBJ of=SelectObject(bm.getDC(),font); - RECT r={0,0,bm.getWidth(),bm.getHeight()}; - DrawText(bm.getDC(),"LICE",-1,&r,DT_LEFT|DT_TOP|DT_SINGLELINE); - // SelectObject(bm.getDC(),of); - // DeleteObject(font); - - LICE_Blit(&bm,&bm,0,0,NULL,1.0,LICE_BLIT_MODE_CHANCOPY|LICE_PIXEL_R|(LICE_PIXEL_A<<2)); - - int bmw=bm.getWidth(); - int bmh=bm.getHeight(); - LICE_FillRect(framebuffer,framebuffer->getWidth()/2,framebuffer->getHeight()/2,bmh,bmw,0,0.5,LICE_BLIT_MODE_COPY); - LICE_RotatedBlit(framebuffer,&bm, - framebuffer->getWidth()/2,framebuffer->getHeight()/2, - bmh,bmw,0,0,bmw,bmh, - 3.14159*0.5,false,.4,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR,-bm.getWidth()/4,-bm.getHeight()/4); - } - - break; - } - case 5: - if(m_doeff) - { - LICE_TexGen_Marble(framebuffer, NULL, 1, 1, 1, 1); - } - break; - case 6: - if(m_doeff) - { - LICE_TexGen_Noise(framebuffer, NULL, 0.9, 0.3, 0.6, 6.0f, NOISE_MODE_WOOD, 2); - } - break; - case 7: - if(m_doeff) - { - LICE_TexGen_Noise(framebuffer, NULL, 1,1,1, 8.0f, NOISE_MODE_NORMAL, 8); - } - break; - case 8: - if(m_doeff) - { - LICE_TexGen_CircNoise(framebuffer, NULL, 0.5f,0.5f,0.5f, 12.0f, 0.1f, 32); - } - break; - case 10: - { - int x; - static double a; - double sc=sin(a)*0.024; - a+=0.03; - for (x = 0; x < 10000; x ++) - LICE_PutPixel(framebuffer,rand()%framebuffer->getWidth(),rand()%framebuffer->getHeight(),LICE_RGBA(255,255,255,255),sc,LICE_BLIT_MODE_ADD); - } - break; - case 11: - //line test - { - - LICE_pixel goodCol=LICE_RGBA(192,0,192,64); - LICE_Clear(framebuffer,goodCol); - int subx=30,suby=30,subw=300,subh=300; - LICE_SubBitmap bm(framebuffer,subx,suby,subw,subh); - LICE_Clear(&bm,LICE_RGBA(80,80,80,255)); - - int n; - int w = framebuffer->getWidth(), h = framebuffer->getHeight(); - for(n=0;n<10000;n++) - { - LICE_FLine(&bm, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); - } - int y; - for(y=0;y=subx+subw||y>=suby+subh) - { - if (LICE_GetPixel(framebuffer,x,y)!=goodCol) - { - LICE_Clear(framebuffer,LICE_RGBA(255,255,255,255)); - y=h; - break; - } - } - } - } - - // LICE_Line(framebuffer, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); - } - break; - case 12: - //lice draw text test - { - static double a; - a+=0.001; - LICE_DrawText(framebuffer,0.5*(1+sin(a))*(framebuffer->getWidth()-30),0.5*(1+sin(a*7.0+1.3))*(framebuffer->getHeight()-16),"LICE RULEZ",LICE_RGBA(255,0,0,0),sin(a*0.7),LICE_BLIT_MODE_ADD); - } - break; - case 13: - //icon loading test - { - LICE_Clear(framebuffer, LICE_RGBA(255,255,255,255)); - LICE_Blit(framebuffer,icon,0,0,NULL,1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - } - break; - case 14: - // circles/arcs - { - int w = framebuffer->getWidth(), h = framebuffer->getHeight(); - const double _PI = acos(-1.0); - static int m_init, m_x, m_y; - if (!m_init) { - m_init = true; - m_x = w/2; m_y = h/2; - } - int r = rand()%w; - float alpha = 1.0f; //(float) r / (float) w; - float aLo = 2*_PI*rand()/RAND_MAX; - float aHi = 2*_PI*rand()/RAND_MAX; - - //LICE_Clear(framebuffer, LICE_RGBA(0,0,0,0)); - LICE_Arc(framebuffer, m_x, m_y, r, aLo, aHi, LICE_RGBA(rand()%255,rand()%255,rand()%255,255),alpha); - //LICE_Circle(framebuffer, m_x, m_y, r, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); - } - break; - case 16: - { - int sw=framebuffer->getWidth(); - int sh=framebuffer->getHeight(); - - LICE_MemBitmap framebuffer_back; - { - static double a; - a+=0.003; - - static int turd; - if ((turd++&511) < 12) - LICE_GradRect(framebuffer,sw/4,sh/4,sw/2,sh/2, - 0.5*sin(a*14.0),0.5*cos(a*2.0+1.3),0.5*sin(a*4.0),0.1, - (cos(a*37.0))/framebuffer->getWidth()*0.5,(sin(a*17.0))/framebuffer->getWidth()*0.5,(cos(a*7.0))/framebuffer->getWidth()*0.5,0, - (sin(a*12.0))/framebuffer->getHeight()*0.5,(cos(a*4.0))/framebuffer->getHeight()*0.5,(cos(a*3.0))/framebuffer->getHeight()*0.5,0, - LICE_BLIT_MODE_ADD); - } - //LICE_TexGen_Marble(framebuffer, NULL, 1, 1, 1, 1); - LICE_Copy(&framebuffer_back,framebuffer); - - - const int divw=10; - const int divh=5; - float pts[2*divw*divh]; - static float angs[2*divw*divh]; - static float dangs[2*divw*divh]; - static int turd; - if (!turd) - { - turd++; - int a; - for (a = 0; a < 2*divw*divh; a ++) - { - dangs[a]=((rand()%1000)-500)*0.0001; - angs[a]=((rand()%1000)-500)*0.1; - } - } - int x,y; - for (y=0;ygetWidth(), - framebuffer->getHeight(),pts,divw,divh,0.8,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - - break; - case 19: - //SVG loading - { - static LICE_IBitmap* svgbmp = 0; - - if (!svgbmp) svgbmp = LICE_LoadSVG("c:\\test.svg", 0); - if (svgbmp) LICE_Blit(framebuffer, svgbmp, 0, 0, 0, 0, svgbmp->getWidth(), svgbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY); - } - break; - } - - if(jpg) - { - LICE_ScaledBlit(framebuffer,jpg,0,0,framebuffer->getWidth(),framebuffer->getHeight(),0,0,jpg->getWidth(),jpg->getHeight(),0.5,LICE_BLIT_MODE_COPY); - } - - m_frame_cnt++; - - double sec=(GetTickCount()-m_start_time)*0.001; - //if (sec>0.0001) - if (false) - { - char buf[512]; - sprintf(buf,"%dx%d @ %.2ffps",framebuffer->getWidth(),framebuffer->getHeight(),m_frame_cnt / (double)sec); - LICE_DrawText(framebuffer,1,1,buf,LICE_RGBA(0,0,0,0),1,LICE_BLIT_MODE_COPY); - LICE_DrawText(framebuffer,0,0,buf,LICE_RGBA(255,255,255,0),1,LICE_BLIT_MODE_COPY); - } - - m_doeff = 0; - -#ifndef _WIN32 - SWELL_SyncCtxFrameBuffer(framebuffer->getDC()); // flush required on OS X -#endif - BitBlt(dc,r.left,r.top,framebuffer->getWidth(),framebuffer->getHeight(),framebuffer->getDC(),0,0,SRCCOPY); - // bmp->blitToDC(dc, NULL, 0, 0); - - -#if 0 - if (GetAsyncKeyState(VK_SHIFT)&0x8000) - if (GetAsyncKeyState(VK_MENU)&0x8000) - if (GetAsyncKeyState(VK_CONTROL)&0x8000) - { - LICE_WritePNG("/tmp/blah.png",framebuffer,false); - LICE_WriteJPG("/tmp/blah.jpg",framebuffer); - } -#endif - - EndPaint(hwndDlg, &ps); -} - - -// this is only used on OS X since it's way faster there -LRESULT WINAPI testRenderDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg==WM_PAINT) - { - DoPaint(hwndDlg); - return 0; - } - if (uMsg == WM_LBUTTONDOWN) - { - m_cap=true; - SetCapture(hwndDlg); - ShowCursor(FALSE); - } - else if (uMsg == WM_LBUTTONUP||uMsg==WM_CAPTURECHANGED) - { - m_cap=false; - ShowCursor(TRUE); - if (uMsg==WM_LBUTTONUP)ReleaseCapture(); - } - - return DefWindowProc(hwndDlg,uMsg,wParam,lParam); -} - -WDL_DLGRET WINAPI dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg == WM_LBUTTONDOWN) - { - m_cap=true; - SetCapture(hwndDlg); - ShowCursor(FALSE); - } - else if (uMsg == WM_LBUTTONUP||uMsg==WM_CAPTURECHANGED) - { - m_cap=false; - ShowCursor(TRUE); - if (uMsg==WM_LBUTTONUP)ReleaseCapture(); - } - - switch(uMsg) - { - case WM_INITDIALOG: - - framebuffer = new LICE_SysBitmap(0,0); - - //jpg=LICE_LoadJPG("C:/turds.jpg"); - -#ifdef _WIN32 - bmp = LICE_LoadPNGFromResource(g_hInstance, IDC_PNG1); - icon = LICE_LoadIconFromResource(g_hInstance, IDI_MAIN, 0); -#endif - - SetTimer(hwndDlg,1,3,NULL); - { - int x; - for (x = 0; x < NUM_EFFECTS; x ++) - { - char buf[512]; - wsprintf(buf,"Effect %d - %s",x+1,effect_names[x]); - SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)buf); - } - SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,m_effect,0); - - m_start_time=GetTickCount(); - m_frame_cnt=0; - } - return 0; - case WM_DESTROY: - - - delete icon; - delete bmp; - delete framebuffer; - return 0; - -#ifdef _WIN32 - case WM_TIMER: - InvalidateRect(hwndDlg,NULL,FALSE); - return 0; - case WM_PAINT: - DoPaint(hwndDlg); - break; -#else - case WM_SIZE: - { - RECT r; - GetClientRect(hwndDlg,&r); - r.top+=40; - SetWindowPos(GetDlgItem(hwndDlg,IDC_RECT),NULL,r.left,r.top,r.right-r.left,r.bottom-r.top,SWP_NOZORDER|SWP_NOACTIVATE); - } - return 0; - case WM_TIMER: - InvalidateRect(GetDlgItem(hwndDlg,IDC_RECT),NULL,FALSE); - return 0; -#endif - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDC_COMBO1: - m_effect = SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0); - m_doeff=1; - m_start_time=GetTickCount(); - m_frame_cnt=0; - break; - case IDCANCEL: -#ifdef _WIN32 - EndDialog(hwndDlg, 0); -#else - DestroyWindow(hwndDlg); // on mac we run modeless -#endif - break; - } - break; - } - return 0; -} - -#ifdef _WIN32 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd) -{ - - timingInit(); - g_hInstance=hInstance; - DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, dlgProc); - - timingPrint(); - - return 0; -} -#endif \ No newline at end of file diff --git a/WDL/lice/test/main.ico b/WDL/lice/test/main.ico deleted file mode 100644 index 78c2e614c9a03ee5f7c2e010b2a6a5a5b316ae26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24942 zcmeHPcX*Y>(jPorflC)es(^xmQYCaS1W=KH5UHW}9w3y^IiZ&TA#@0k&_nONB(zH> zbm@tp*d^ABS9HGLZ_nA2lMqnvz286I^S#eAXW#R_yEC)9Gh1e6Uy*c@LCTdAq!}e9 zn@EU=6e;5VpHbxH>>@dGxc>L}o5(+25_kS05>s5HOd*>e|B>%nZIQfrnZJlk&LlFr zi7j75dZZV5zO6_J&;Uv403h9GU0JhclYIH}Oa4MHOOaQLNzr1(rPyn)OR?8W$ZI9v zkP?J9OUWCh%SfrR<)w7F@>1@t3R13ukCd-iNqj0*mP%EsN|kEWrAm#OQq#AV)U4$v zZ`ZCXwQAQ9zdCiLcHMWR?z`{FJMYz#y7lTyz54aVzhOgZ_(3D7|3PDE*r>4tG-)aU zO`A#67A>S%iDEm;cIzRXdi0hqJ$p;1o_(ZCuOR6j)K7Z#=_7rDc;8=o0Q&UnFTMK@kbeF9OV8jz z5;S12^a~j#0|pL~;6a0AP)LXbo&-;4Vz`{+O@KN<0jd-aigr?yj9k0*)D6g?~+Yhw#vqxdt}qzgR*t&R@t(1 zm+acLOLiYPB>VR5lY@s2$)4CFvhVOwIT&|X_8d7b2LQW|o|L`EPf6_A3lbL>CviuQ z%kkrYlPBfy*?2j1>a?6Xdrr=sJ1564UX}O@7vK|5^3nC{a^copxdOO&J3+49z9Tno+>l$hZp+Qvx8=^= zyK?DvqFlZEv3!(xU+#Q-UvAv{L~eibncRKwxg;hgO5*)bP`?6ad});TMfnd=zB9^)p!{T%Uzk&6b$OK?0V+p=RpKL5Zf{lj>SA*Fj3}QC zE@p{*O=JNfU!%;N(Ra$p7 z(mOJAfqJ^r%jih|v;xRp z;OKc=Cp!AHt~~SvZ_n>5@U#Mcz<&4?u9zylqNAfbRf*xBQ-|}XT>veUZ~swTtIAA3 z_UPydKEwI<=>B|;^nOp)A-5yr5;8rm(kzobI(l}~R;CtP@;b6S(Mm-fj;YZ3{i7=_ zHrbo;x6=pf@ND1Ij1J6DDXt0*N6XEdH*c9=dFgtSzo_{gPz6ZYMUy{z!25W-di8s$s!-ICVNN8j%CmNCU%!G`^SJUycM9P1$lQ*c z$=JmY+{~LdFS5aiojbN~T*<6C-1(#H_r#ldLmUn-*?Y;6KP)V4PEg?P-8*({Pnmyq zh2eM?R?d+;hXQ>^NLX0q4SRNzKnncPV=GhooX;m$`6Wl*apT5K^`E|Xk0HSP&s%vbbyD5AH|ds(t9-9zy^PG{M#v#b&=b1aG^0YEaCPIV2=xqTkFz2VDeE zfr_=0@uS=DKBS24v@DMDefsp7ST8Qt5{RDloJ)pWg=Uw+`#yCXSW4g`JKehVYcb^r z^1BE`S9Eo+rP1`mZn*yDD8>9G9GTj;Z$Gij@naqWW5gRhYEuC@+81(`8=y2h?nf%i(}3qq^X2a*fj`T?E!<$`rM8M=AniYqA2_ zC_|8Z)P27HnNuzT1v4!}C#NDXp#mEympeZiH`4#Ci$L*oYfUGoBrv-SdmuOSgCBI> z!ne;E0>LuH)d$(J8fv(cx?;6}9>!$JBf- zdGJr~XouC$wzs#so5&-k8{Li6s|nuE8SQYmhPgtH-1FzpU%0x$7TX7IG2QMOS_V`I z!~6Lq?GOP1jWA@aURPnR?PRy2ZN%6zyLHWZ98vmv^h+@MjKiQ5bGU{7A}d8MOBteuaqqyQ7BwavOxA<&4wbvF;fu|YFFG_ECXfP+ zi1YDpKm$a{DbNAo1urB37c-0}FgXQt^M{}#%8&qz&qyf^7H z@FfC`Hy@Ti!#DV~{M-83`r7(?+Q+t=ZBGp~?aXyS5kM`#AMI1KWX&ph^F3{!`lf4- zTBD_5R<0ryxi{s$)UUSLlh&>GKK7m;V9)8=d-{LaOd2+6E{&SCl*Ub) z%ZDvn%ZGt&%-*v(_MU<5J4s-N&eEnsCuwE&o?WGV*B;Wba~J8-wX4~8cErB3EB2jT zdIw>T*-!fP?Q8a$z55T8zSwJ;edfRrv(FraedQppJ*C-CI>(wl+a%H0Gp@qEaOIj9S+j1v*%!vdtd+GJHVMWj*M4x{A=$QVn{3~) zLw4=nBYXGmm3;>en*H9s6KBkR52J}3JN^&s^-jsDGiT(?*|TP!cP{>d+1p*XbXhK6 zy^6iuRkKICckjMDz#i=3!-tZT^qu_hX5G4#EEYmu3QM7GQjiC-&{bQG#~DW~Z5@}hSFL_Y}@{W3x{X{+eZ7n959 zM)_Azz8uQGjq(jq9=MWvqWrL&qEpL@E(s9b94vY`0ywvdetI#vJk}G9u_)^QJj%oF zvITQxJXUQuSEInD1Qj$ zPoO+#M%+gEPfS*Cu&hBg20$XY2y4!nM`Y18_zHfU2l z-`h=_Hq7S8oZ@{BN4BPc^^3I)3JPjcpnS8yrrA=E$m7T!*zTPYUGcg`Q0EeFwr&@g z*^9~2jtq@EHZ!k-N(KdWEm5Xp$Ho~Po@!=xRPNTkaA%Yb3d#fMTEeGWx5^$C3ORE1 z?)`cj^ExOilg zs|5$=b|J{&Xg1K#jXkKO8&Bt#dJb&n$bm+v_5n5m4jhJb2ya4X3j#>sKj# zrokbvQZj-9-YS_j>&qp{W!Dn@oC6%`DP?(pAh^8Az)a@qTB4KFS=^C_LRKlgBhVRK zx*ny+eSP=_UI#idx`gy~2Qq{-FI~Nf${$(?z)Urx>pqbgL26o5wK~-p2`aCY$WYAod@>4b4 zSLXbw-kL1si{{CdHEXUsMa#R(FwvyKs)-p?L$OT5N(<`@CzcWfU#vk2b9q5X#A<~Q zhgA|G6w8V~12%sm$`TK8nxzUzlP=dO6yqX*KU$}xPoG|L=gw{H=`X+hGVJIjrFe;w zQmPb2VA##e`&5*wHGQRK&6-l(7j|;2ON?#2UOjoozoER}pn)`iUA)nUA4)(#fHZF2 zQd$JIl9sJnNo&}>Y4h&cv!`@}ExTWEumlenD8aN{4;vv)*q}#_$9loNZkRk}ip&U~ zDU)W-hHZI{L_{u?1y~;}f$ezlnsu^f%^F#|ZXM?QEwX0YF4=bIupB&nUe3qI%ZV%3 z%^XhKZ2V2wS7DdEbSF`+!M=Lq-lvlIncIf?&A0OH_dm#YKe_CrkN)*9dHmaNm?$yX z&ct$l3%WVJ7ADI2l2cntdCcztI!S_ciA3l&*{Y}Hq9)IC&y^KP-xz+3{uq>Iiu`?x zNalEvY)NQ;eL-qsozNQVgkiw50PBRESSMWZS|{X2`Bxgl|IuHh=1h?WTSNj;zI&3$ zP|Yb*QGPMXZ$kMvl)r@XpLmsj4drV!7HQRAWYA2J8CyiwqWqC00iQYlf1UFG>y&5P z(@VZy@CC2sN$G5vUM!r$@iK-EUS+anDPOUQPhq#g;0^rsdAo8|pVwSdeXdO9eSCa# z*YNQvO8ZqY$D2MCe0ekD{(sXU#T_MZQ$0iGYJ8j}PZ0-_DsQE$ z#lJpDUIT|dWedPnX|8-O4?uSQdE^T<$6aCukvJ45 zgr;+WD|gCYzGEKdXE~0uRAS5*iS5vor}SRolJ_lv0ndfomkfLOnxn|q)7`s7D8}SiM*6KOP1Hb(=p3$$u~=B z>o#o_K3RqD)TBLo_R@Fjz3=G{=6xxDfiRW_17P{hi+k=C3IYn{%$2Jic)v$}UM>Eb_UzSLmoH!bRDe%c->&87sYkv71^j*P!@sXf zqoNd6!#@Q>h7L1jSe7_)zL3kGINi9}Hf$r-gZ;vKP(~>Olm+Sy<-_~pfA$mmjD5#G zB=2koZ{CaG|103Vq2>K;KR-Ql=8RsucI__#Y#I7i#Y(0xh%5I?c?ScxcO7hBc-Mh# zn^r&kY5pNI{+9PT@4Tz`@88#?q@*Vx{=x-4dhEC|P3t|Mu`F@09|$kLly?yLWB;-b z(&C?ekQV=xANGrtdo!lsKjohNNL&TL`+FYV-+fQN{q|dh|2qYI_uY3IGGdfAY}!I$ zOH==Vrsn^x+jmmr^DY|1} zclq8yL7qC~$(KI}Jh1IJc6iJF(|AWV&t-L)dD$PCv*pNH5WIg(-VsBii64J#+Mexi zVe9rC+6p{(?Ab><_wK9hyZ6#Iox5qv_MNn8>vr0>MJt7UQ%8*%r=NWCiKm<`&$I`| zFDpwg<)KOWcj{{Tq)Dr``T^vsd!K%aIFA%~EWU0%dYC$Z=0l9Hc6;M?iqy`;hiqlh2zz{ltZ#LsApwjFhH_$(bUZjuff>D2y1M`)ixL$pW#LHc%` zceG=VKH9cR4~5NGo44(t0qBdSfo+U_d*kE%l`B`2W171k;*nDJ|E&vUecgC;X2dK- zoQwx<-MXb#X67u8(%F$q6){LUeB4A0agNo2BSve#A;Yy|)oR+k-vI3bnd;EJH)N{2 z2Db04?29I-!=czX4^E38@jZ%tuB}7(zr#H14M-sWO`0`R>^VJf`SN9rJA6c8d)H+# z>opp%X!$CgHg|y{wn|4$oT9_VPSC-l$C!D!Z^$t1H2^ZzH&{FO3exu7Trx%dW*ttS zKJCG6>8x0}((=y~tJ%MHp^THfb8d}|jWu%==PAPZ^YPjWdKtZDog&Uk*KFRV%hqnt zxl5Mmq?vPc+_ahMoIFiOPMEBP3K!8qqe9)fF%-HnNV^90hi>$NZuG!-)m}Sw@2N+Q z9!)`mbh`EEY3q;xUjDQkA#Y*wP8c^~g2J}%0feq-(11a@XxU2LcjTDvIB-Ze?b@p` zTej8QLosJ~)8Re* z44!occya#O9zfnG@{U-;6zdtpq$y(NbnKKcJ%0Y8#+^EYIvhtGVs+E*eTw)uoxOCK zBF0Xq&0DCGXU)^{K9zLL)ESVesXBbDOE(6%b))yd5ThF$Z#hpa1n$&pDA-|4JAxms z&Hu0ukjK;ZGs43aad#d#1Uc%`tB;<#a7oWzzNRPQS%$$7f^~8nC zdiczFJ#hS_ZrXc5mv7pt@U1C)aYlaUEL{$nTI$w~c{%}e#n`YJI(kwV#@k6c#0lLP z;naSZH#ko(Ub4hP*YfaYnX#9p) zAX6)2T)MG18Zxz5!!Tb^H^yP!3!UN`Z-+uR8Z{5pxpU`w=#v-3rC9!%7EWCUJfrNG zJR?Vr(%IPS5#W2(uo*LTpyx z9xN~Lh1)vxON0ML#FKV63et_WuU|e)O3??@h1;Jz(3{W)#M(DAk_zJ8bn|FPu1S@RZ(C_oP&rdzk~-m6JJ{-od7 zKKKTDKskaQBs@r#qtlT8*Rk&M!@PI;+6|36e@S7(*S#ms=q~8>wnImB^S(p6e)oQj z*}hv>Zr*P6WC_RHl^AcMSLiIaZgB0#eVI2eytgurw5)d>@ZXG^L4Et`lqpjTAl5)9 zhfUXOH*V?=KmSvce)v%lQ*HX-!PnpDeXGlmqw^R?UoTnG0LRmdw-WT&rE7ZR!WE4@ zcTo?VI;VS%pVpm+kL%WhhcV6`gl_Eh=my8z#aMqVSOJ-eT5i@)Jt4Q27n_zX|CX(T zZz}%H^D$$_C}JrLAU<9P4I81q{Oeam%y-HC)Ui{#Bkq`Pp>9B?)?y84bz|vT=my4H&fl#eLzWkt zR>peV-3KXj*!BwosMG?YdUY`7M#QNMj0tE|VF1}^P(_8nU%XU0MADqV=P5x~iOg$h|)Qtnw4a$^TH#Si> zINomGWptxm=dK=JEKk*H)O;rYh`aIF|IC^P>srLLq*;fRtJj!u@<7~SJ#p^58IN#I z!ORKQIUc#?=+xC43Lo4P^{~3JpSnSra_a`iTaHbLL-O!q?UFU#_O<+{mY)R5(0Ghf zcFnPU`*vNhc!^%ReC3HceD=kcnmv1V4Q$m)@7}ww*|KHVPF=g1eqbGJA5e}iVQwS; z-gU73!S?2y=Fttv6m?@N_7Ki7<2<}rp1jsUsr5IO{0H^zr<*oy^1y+EhZJ#9IHIAh zI-oBeBP?&<{{5!yTeWVjg$fli_mD@_Bb)XcFi_*63ph98=>zyZJ#}C`I2Sj=95o#K zOsgAaymjja_y3V-J8xcaz`(XW)559b-%0-KH)yCkckc86?InmEQ^ZHP>fo*i{HnTs z!v?cXEnT{_hkw?=0?une2Rms`tj7?GhCO^AMeLitlrO)&|3PCT`>AzG=4t8#*GL>w&tXi$c_#y@>%sNtXvn>#ZPN|tYumm^Q_Q`#E_mLad1!OsKJ?_t zlO9NbZHaP}W*tx))`NQCnd^S~Ss!A){_5d(X3fWa!yT--sS}*ra6apaI&g15S@WiA z?{Rj|@*ivYO)CZe39JM60JJrD!^ijT8Cx>PB&!dej&RrEH`L=-^u<3-UtrCFzTn!G zYj5ry60qjGi8+F6J)9#`j;%PaX6!2?oMTeZv$UhJmm*JY@J)+v`wV$}ZQkiK!i_zT zHa!bCW2PHn@9Y5E&E~D!pIQ&YBCd^e$|<-uUf3Vo$VYty;F-shintJO5FNyqj4E+MMTNO+;I5 zYM>n)@uwOKTjJaWi?DAEHhRwbARgAhiq$c?eDxX)3y;vA{eraz>?Gl{=ICkI*I51@ zWHL2g{%0Q`p2zb35WJ+RvrnrB>k5cv9S8#k4SvFQZf)L7zx?t`Qy2PQaAp$xoz+vP z&*(|mHcy;7trsp{Qk-klufF<9DTCf+Q{S&%v&OWWoAzJk-Mdb}5oPOu^TE1!=~BZ7 zdHHX{rOTJKb=!8f&6&mn{!+Vp^KS2fqY;4ZU~v0jE{a~ZToJ#lKm72+e+&mOue5FN zv5#2(!$I#)%e&?EX(@35oB&TfUdOthbKS~StBpV9U(nM(3vrkqhr`Z+n0m{vO=Cgh zKW_6sQI7=Bu{2Fu32TK9;VT%0eRtUO=}$n%&YiXHd+((vO*<}_H#Vo zX?#8HIs0)lpgrKfCMRj}`DdPy2Y@fY=?3x^>jn0CBRu=B$p_EjnDaPf66b6lF~xbB zIHou^6Ur3lT1=Yy9E?5hf_y*&FLUxa9WJ7IUdNteK@4c}xgD?bI)FTR)rH^EyaPy-*)pKU;4N1;2^~VI0_Iii(-@PG}Hc{&$~~ zVw_eHKrO(35T`|dK7GuL51}m6=btOri!av7TcF@X_;R-sa6f_1@Xk9XgFbSWeOhb` zUOjO!FKN*?&lm&7OS}Sj6Hwv#=QGqrd=X_=(*p2u_V1aqG(z5TfRX@~Wo!*&ZOA`y zvrefmK4T0CX%+^&4xlbn0@MV&lR0bFKB(&tq|5QSd5f0DZb;i9@A-`Hm5PkT*S#XDFR@7Fy_Se4cmo%%es?K`sb?xY9Xd4)V6hpjvbBt zoi=#dQ#j8IA2nKM&YbCa9x`Nz;`=0qk34zv?fcvF&-(*U6~J2nwkv6{4cOkK&x>tf zc_@JUR{?Kk%bp|9wmI#Wv|AF!j)yOxSxXbk!uSuyD2$&t$@6~tj2T+N9YX|}xB*;@ zqR2?aw`xo~0H?1PnKW;ihqSp@rk|6x z#_3q&({@0ABlqEB!e$sBJmVqoeH*2}mvJeKgJAnGz9|?!L6#*u$wMGECYQz^iR`vG*@lXkuO{wD6>6v}l%ybyh_F|d8oeoGrP{jc;P)1Oa2IQ=q= zs~8ABKK;gQE5=e#N4D+QX>if5=8pY%2pVa&0iK(>uS1==*PDqpm_o82;zQef-{rc;#HDb;@-4l0IFTlQd=A)a6@8ako z*bw&|J8A52^woUWvK8W1`ndW8J{tOxr_O$;v{(OgBp4B0NU&q zv;SlKTG-54N?S9|bHG-9$M8U#|6$n2*%q`T7kT9sT?hXi{YCWM(T_^M9et=%X3sNm zLnFpdGO>QN(Gc(Q6`uH+a7!O_%aZno@Z-^@f9wQ&{`(HVmhnJoC%$;=uCa~LZ*meg z*4>C}c%^u8$lVm0iLNj*Op#F(>r7acqcz9fY{K2PZ8+ychlUd`3Ox zwRZhRO}PJwvAfg%cNumq+IjK)A>%*8_o!eeZDf2m^gq!TNZTm=fb_{yPiVWIw``@+ zSH^yM+d1*AEW?8reWy45$feOr+YWt_^rg~1h;JI1e(-M;p!FLyHtj$gEqyQagV85R z9~gZ{)RR?PcNkkVee~m?8%dzN z?vHYYnk=Mm?4E8OE+hVvevDlQ4jDh{TC}a<0rF^gaJPeP3-$@eNBUprUk!s!&Yrix zlGil)zcBm1F4k7OXft#9R#a)X#F=T$2A@j7g311fh5=1<8penNi1V>L(D%?6x=#PY z2E;8{*}yq4#W`z(`^uH8M)p82*4CdX{>PJtf@EP0UmtTL? zAD|ob7c*w!E@CApo3z=Q@xkpAqy3zIyEgFE(H6rCXUi>Zj&(-%Eq$hVmOvh2V0+|6 z9_B5K)Nf%6w3n5OfBy1|@mtfDPa8P>i`M?l{$Q+F57@kk!(QxP;s-dr>DqfdH{+l; z51+#(7qxsPY>sR7#?4#$2>xbXwomZgF=GQ}49vAV3A!BPaO;j;P1||f!oAwvGwxZs z-YICeCw+p|N75r7OP8%MAEUrtupR;&AJUb19s0oh(8=U%Bh>TrL(;LE5WaA`-6Pgi~3=~yN&I8(xpBVha3JBZOaSF6b8iF^3++jA;(C3 zm%x%qky5wtJq5*gA1qC#tVf#tZD~C#MOj}!6u=v&xhGF{EKB2k0-iYmf7ss7qHo_3 z51>6D3J?p>RFL3)?nLTq%l%PGvq2&(GNE4a*u3X6*iZ@scy2cX0nZ$SI2WWtnl3aM z1os5bvpC!n5?$pC4&sAN!xsaWlcox8HuD0wVgC>86ew-v))#e;a<@Y)(s00ktNn>f zOP4FBA7K9Xt5ZkuEl$NV%2z+bz`yZB{s5Z++9EJe@huS#gocJ{eg6ieL5KqUrMfUb zAfEg2p@_A__bhd4SeOpP95oncg=jnAGoFuf@7d%33Jv7l%yRhJnJcDl(IVZ4d7plF zu7RA`4@{XFX5KN+U!eiqPJj*@K3o?rT&U4lw{q=E+yw5)n1*AmOPezDjKR4y#?_)+ z)U&z*?|q58Yq#zih4WRb5l?g&dkl-)8$a)(5yLbMK11fEeS>8I?Vm;i?-KBhRb^ZO zzS)A<$BQX&6KB1KjZ!@0d^Ha-i7Z1o0FH-%C;FRo0jTdHv(Jw^eHQaQ<7iy%V(X9^ zKcA1sI&|H-btd-YRo9-}nYs?ZoxpfLd|y-<|H8eG_d1h!*tfR*Ej^};1LNGpvfa9y z^ByVc0NiECJL5KK8@PD$j)?A;M{E62=}ppt#Ll&=uy3S=dOuS zd2x^P0P7a|-CrwF0=AvWt~H!{J)Ih_ z{Xb*jVuNG(iWRBxKV+N;&;0#}xERJ>kVe<;-E}zD0^G}*zTiI6-5(aGcNzg*AP&yu zsrZj=-ZD^c-@a|m-f<0f7H3+j*Qf!TNqw#J?z_78$T725J>}l3+BlTii=&L)f^-%| zEi*XW?VsS)KK)3KwCO|S9w-4m^}et@mMK$)?P!4h(r&$j;NS0U*4&KQ;o6`3586hq zqCC$4y3a9&d*RQ{{vJ3u#Q1vYXC)0@tjpK!RTek1ewVO8U@|bnH1N&O8XIYPp zdk^T|0|!mnP>glt6;RmXXNv#r`FttHD*Djrcm4%yWqXkh;};lz!8I#mosZ(o#dg?L zu6^{8DZ{dE+)i)Y_8#w|_ z*RH(h`j_wA5QQ{Fd#A?vwErmA2;c<7rUE|WyC=qaZ(KS?{qRL#zsKV1_ecr@vil_g z5+wt`;TLBhonNT@F)%O7u{?39IQ_T|%K<0?_^azMe6M68#+sk;trKIv!}m@eOrAQm z8BqPRe0;@c`(&ZnZ{J1U6x8KL;bilRL*77mJh76P1!InT2AMvJjI;5#U0jA0BH z@el{T$#N?#9I*36dY5Gx#`5r-8TYgNk8iRV95{cOf{!_K=T^hFUw$Xgv~}2+F??S| z@jVz5&t#vCg#8VC{ElyxSF?QJn=iM>8*Nm~N8M)1^7tN2it>EU_CU;vsmHkS;|tMW z&S#c}O&QOF@7g?3o^(i$Jm6b1k-W!uW>S>Lw_+6EzfpYi#>9wPoHk_};~O`TI5!o` z^7c7XW1~b&5WcIU+z)%dv-j)|-`aIzQC*TJ@=g9 zoA-=wB~H$rytm~oeSCLkBKgO6bj-ZX^)~v&0NbutuU@7P*$+K%W|eb0ap1c?l;mLm?viSZrt&?X6*zuNvEIcjt>*y4X@oh*NpUCNyW`<#5@ zTSULZ7n4GtLdTA41|Qe2lmp7Cw;WoUv^(M3M!zCvFGX3)2UC2jC=%a1dcZbG1rO2Q oDde8{9~EBgmy~_6Ut)&EesPY)exd1HAhH;K#wWqPXI_^3A05{C_5c6? diff --git a/WDL/lice/test/main.m b/WDL/lice/test/main.m deleted file mode 100644 index a4476ab4..00000000 --- a/WDL/lice/test/main.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.m -// test -// -// Created by Justin Frankel on 11/9/07. -// Copyright __MyCompanyName__ 2007. All rights reserved. -// - -#import - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/WDL/lice/test/resource.h b/WDL/lice/test/resource.h deleted file mode 100644 index 15d67f48..00000000 --- a/WDL/lice/test/resource.h +++ /dev/null @@ -1,27 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by test.rc -// -#define IDD_DIALOG1 101 -#define IDC_PNG1 102 -#define IDI_MAIN 103 -#define IDC_BUTTON1 1000 -#define IDC_RECT 1001 -#define IDC_BUTTON2 1002 -#define IDC_COMBO1 1002 -#define IDC_BUTTON3 1003 -#define IDC_BUTTON4 1004 -#define IDC_BUTTON5 1005 -#define IDC_BUTTON6 1006 -#define IDC_BUTTON7 1007 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/WDL/lice/test/test.dsp b/WDL/lice/test/test.dsp deleted file mode 100644 index ddfad7e5..00000000 --- a/WDL/lice/test/test.dsp +++ /dev/null @@ -1,120 +0,0 @@ -# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=test - 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 "test.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 "test.mak" CFG="test - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "test - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98 -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "test - Win32 Release" -# Name "test - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\fly.cpp -# End Source File -# Begin Source File - -SOURCE=.\main.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\image.png -# End Source File -# Begin Source File - -SOURCE=.\test.rc -# End Source File -# End Group -# End Target -# End Project diff --git a/WDL/lice/test/test.rc b/WDL/lice/test/test.rc deleted file mode 100644 index f5371bcc..00000000 --- a/WDL/lice/test/test.rc +++ /dev/null @@ -1,107 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 398, 270 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "LICE Test App" -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "",IDC_RECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | - WS_DISABLED,7,23,384,239 - COMBOBOX IDC_COMBO1,7,7,181,170,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP -END - - -///////////////////////////////////////////////////////////////////////////// -// -// PNG -// - -IDC_PNG1 PNG DISCARDABLE "image.png" -IDI_MAIN ICON DISCARDABLE "main.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_DIALOG1, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 391 - TOPMARGIN, 7 - BOTTOMMARGIN, 263 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/WDL/lice/test/test.xcodeproj/project.pbxproj b/WDL/lice/test/test.xcodeproj/project.pbxproj deleted file mode 100644 index 9351adc8..00000000 --- a/WDL/lice/test/test.xcodeproj/project.pbxproj +++ /dev/null @@ -1,918 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 33343C070CE4DB5D00FF8CE6 /* swell-dlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */; }; - 33343C130CE4DB7000FF8CE6 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */; }; - 33343C140CE4DB7000FF8CE6 /* swell-ini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */; }; - 33343C150CE4DB7000FF8CE6 /* swell-kb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */; }; - 33343C160CE4DB7000FF8CE6 /* swell-menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */; }; - 33343C170CE4DB7000FF8CE6 /* swell-miscdlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */; }; - 33343C180CE4DB7000FF8CE6 /* swell-wnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */; }; - 33343C190CE4DB7000FF8CE6 /* swell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C110CE4DB7000FF8CE6 /* swell.cpp */; }; - 33343C210CE4DB9E00FF8CE6 /* lice_arc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */; }; - 33343C2D0CE4DBBB00FF8CE6 /* lice_gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */; }; - 33343C2E0CE4DBBB00FF8CE6 /* lice_jpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */; }; - 33343C2F0CE4DBBB00FF8CE6 /* lice_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */; }; - 33343C300CE4DBBB00FF8CE6 /* lice_png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */; }; - 33343C310CE4DBBB00FF8CE6 /* lice_texgen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */; }; - 33343C320CE4DBBB00FF8CE6 /* lice_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */; }; - 33343C330CE4DBBB00FF8CE6 /* lice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */; }; - 33343C3C0CE4DBD200FF8CE6 /* dgif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; - 33343C3D0CE4DBD200FF8CE6 /* egif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C360CE4DBD200FF8CE6 /* egif_lib.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; - 33343C3E0CE4DBD200FF8CE6 /* gif_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C370CE4DBD200FF8CE6 /* gif_hash.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; - 33343C3F0CE4DBD200FF8CE6 /* gifalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; - 33343C790CE4DBE200FF8CE6 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C400CE4DBE200FF8CE6 /* jcapimin.c */; }; - 33343C7A0CE4DBE200FF8CE6 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C410CE4DBE200FF8CE6 /* jcapistd.c */; }; - 33343C7B0CE4DBE200FF8CE6 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C420CE4DBE200FF8CE6 /* jccoefct.c */; }; - 33343C7C0CE4DBE200FF8CE6 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C430CE4DBE200FF8CE6 /* jccolor.c */; }; - 33343C7D0CE4DBE200FF8CE6 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */; }; - 33343C7E0CE4DBE200FF8CE6 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C450CE4DBE200FF8CE6 /* jchuff.c */; }; - 33343C7F0CE4DBE200FF8CE6 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C470CE4DBE200FF8CE6 /* jcinit.c */; }; - 33343C800CE4DBE200FF8CE6 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C480CE4DBE200FF8CE6 /* jcmainct.c */; }; - 33343C810CE4DBE200FF8CE6 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C490CE4DBE200FF8CE6 /* jcmarker.c */; }; - 33343C820CE4DBE200FF8CE6 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */; }; - 33343C830CE4DBE200FF8CE6 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */; }; - 33343C840CE4DBE200FF8CE6 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */; }; - 33343C850CE4DBE200FF8CE6 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */; }; - 33343C860CE4DBE200FF8CE6 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */; }; - 33343C870CE4DBE200FF8CE6 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C500CE4DBE200FF8CE6 /* jcsample.c */; }; - 33343C880CE4DBE200FF8CE6 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C510CE4DBE200FF8CE6 /* jctrans.c */; }; - 33343C890CE4DBE200FF8CE6 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C520CE4DBE200FF8CE6 /* jdapimin.c */; }; - 33343C8A0CE4DBE200FF8CE6 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C530CE4DBE200FF8CE6 /* jdapistd.c */; }; - 33343C8B0CE4DBE200FF8CE6 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C540CE4DBE200FF8CE6 /* jdatadst.c */; }; - 33343C8C0CE4DBE200FF8CE6 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */; }; - 33343C8D0CE4DBE200FF8CE6 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */; }; - 33343C8E0CE4DBE200FF8CE6 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C570CE4DBE200FF8CE6 /* jdcolor.c */; }; - 33343C8F0CE4DBE200FF8CE6 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */; }; - 33343C900CE4DBE200FF8CE6 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */; }; - 33343C910CE4DBE200FF8CE6 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */; }; - 33343C920CE4DBE200FF8CE6 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */; }; - 33343C930CE4DBE200FF8CE6 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */; }; - 33343C940CE4DBE200FF8CE6 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */; }; - 33343C950CE4DBE200FF8CE6 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C600CE4DBE200FF8CE6 /* jdmerge.c */; }; - 33343C960CE4DBE200FF8CE6 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C610CE4DBE200FF8CE6 /* jdphuff.c */; }; - 33343C970CE4DBE200FF8CE6 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C620CE4DBE200FF8CE6 /* jdpostct.c */; }; - 33343C980CE4DBE200FF8CE6 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C630CE4DBE200FF8CE6 /* jdsample.c */; }; - 33343C990CE4DBE200FF8CE6 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C640CE4DBE200FF8CE6 /* jdtrans.c */; }; - 33343C9A0CE4DBE200FF8CE6 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C650CE4DBE200FF8CE6 /* jerror.c */; }; - 33343C9B0CE4DBE200FF8CE6 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */; }; - 33343C9C0CE4DBE200FF8CE6 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */; }; - 33343C9D0CE4DBE200FF8CE6 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C690CE4DBE200FF8CE6 /* jfdctint.c */; }; - 33343C9E0CE4DBE200FF8CE6 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */; }; - 33343C9F0CE4DBE200FF8CE6 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */; }; - 33343CA00CE4DBE200FF8CE6 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */; }; - 33343CA10CE4DBE200FF8CE6 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */; }; - 33343CA20CE4DBE200FF8CE6 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */; }; - 33343CA30CE4DBE200FF8CE6 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */; }; - 33343CA40CE4DBE200FF8CE6 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C750CE4DBE200FF8CE6 /* jquant1.c */; }; - 33343CA50CE4DBE200FF8CE6 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C760CE4DBE200FF8CE6 /* jquant2.c */; }; - 33343CA60CE4DBE200FF8CE6 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C770CE4DBE200FF8CE6 /* jutils.c */; }; - 33343CFE0CE4DCFB00FF8CE6 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE50CE4DCFB00FF8CE6 /* adler32.c */; }; - 33343CFF0CE4DCFB00FF8CE6 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE60CE4DCFB00FF8CE6 /* compress.c */; }; - 33343D000CE4DCFB00FF8CE6 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE70CE4DCFB00FF8CE6 /* crc32.c */; }; - 33343D010CE4DCFB00FF8CE6 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE90CE4DCFB00FF8CE6 /* deflate.c */; }; - 33343D030CE4DCFB00FF8CE6 /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */; }; - 33343D040CE4DCFB00FF8CE6 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CED0CE4DCFB00FF8CE6 /* infback.c */; }; - 33343D050CE4DCFB00FF8CE6 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */; }; - 33343D060CE4DCFB00FF8CE6 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF10CE4DCFB00FF8CE6 /* inflate.c */; }; - 33343D070CE4DCFB00FF8CE6 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */; }; - 33343D090CE4DCFB00FF8CE6 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF60CE4DCFB00FF8CE6 /* trees.c */; }; - 33343D0A0CE4DCFB00FF8CE6 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */; }; - 33343D0B0CE4DCFB00FF8CE6 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */; }; - 33343D210CE4DD1F00FF8CE6 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D0D0CE4DD1F00FF8CE6 /* png.c */; }; - 33343D220CE4DD1F00FF8CE6 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D100CE4DD1F00FF8CE6 /* pngerror.c */; }; - 33343D240CE4DD1F00FF8CE6 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D120CE4DD1F00FF8CE6 /* pngget.c */; }; - 33343D250CE4DD1F00FF8CE6 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D130CE4DD1F00FF8CE6 /* pngmem.c */; }; - 33343D260CE4DD1F00FF8CE6 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D140CE4DD1F00FF8CE6 /* pngpread.c */; }; - 33343D270CE4DD1F00FF8CE6 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D150CE4DD1F00FF8CE6 /* pngread.c */; }; - 33343D280CE4DD1F00FF8CE6 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D160CE4DD1F00FF8CE6 /* pngrio.c */; }; - 33343D290CE4DD1F00FF8CE6 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */; }; - 33343D2A0CE4DD1F00FF8CE6 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */; }; - 33343D2B0CE4DD1F00FF8CE6 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D190CE4DD1F00FF8CE6 /* pngset.c */; }; - 33343D2D0CE4DD1F00FF8CE6 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */; }; - 33343D2F0CE4DD1F00FF8CE6 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */; }; - 33343D300CE4DD1F00FF8CE6 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */; }; - 33343D310CE4DD1F00FF8CE6 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */; }; - 33343D320CE4DD1F00FF8CE6 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */; }; - 334560580CE4E727004D76AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 334560570CE4E727004D76AE /* Carbon.framework */; }; - 3350A9D2146B63B500702E1F /* lice_lvg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3350A9D0146B63B500702E1F /* lice_lvg.cpp */; }; - 3350A9D3146B63B500702E1F /* lice_palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3350A9D1146B63B500702E1F /* lice_palette.cpp */; }; - 33651CDE10B766A6005FF751 /* swell-misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33651CDD10B766A6005FF751 /* swell-misc.mm */; }; - 33651CE010B766B2005FF751 /* lice_svg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CDF10B766B2005FF751 /* lice_svg.cpp */; }; - 33651CEC10B766E1005FF751 /* libxml_tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */; }; - 33651CED10B766E1005FF751 /* svgtiny_colors.c in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE510B766E1005FF751 /* svgtiny_colors.c */; }; - 33651CEE10B766E1005FF751 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE610B766E1005FF751 /* tinystr.cpp */; }; - 33651CEF10B766E1005FF751 /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE810B766E1005FF751 /* tinyxml.cpp */; }; - 33651CF010B766E1005FF751 /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */; }; - 33651CF110B766E1005FF751 /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */; }; - 33BD26B70ECF7811000A367A /* pl_cam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AC0ECF7811000A367A /* pl_cam.cpp */; }; - 33BD26B80ECF7811000A367A /* pl_make.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AD0ECF7811000A367A /* pl_make.cpp */; }; - 33BD26B90ECF7811000A367A /* pl_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AE0ECF7811000A367A /* pl_math.cpp */; }; - 33BD26BA0ECF7811000A367A /* pl_obj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AF0ECF7811000A367A /* pl_obj.cpp */; }; - 33BD26BB0ECF7811000A367A /* pl_putface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B10ECF7811000A367A /* pl_putface.cpp */; }; - 33BD26BC0ECF7811000A367A /* pl_read_3ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */; }; - 33BD26BD0ECF7811000A367A /* pl_read_cob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */; }; - 33BD26BE0ECF7811000A367A /* pl_read_jaw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */; }; - 33BD26BF0ECF7811000A367A /* pl_spline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B50ECF7811000A367A /* pl_spline.cpp */; }; - 33BD26C90ECF7830000A367A /* lice_bmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C10ECF7830000A367A /* lice_bmp.cpp */; }; - 33BD26CA0ECF7830000A367A /* lice_ico.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C20ECF7830000A367A /* lice_ico.cpp */; }; - 33BD26CB0ECF7830000A367A /* lice_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C30ECF7830000A367A /* lice_image.cpp */; }; - 33BD26CC0ECF7830000A367A /* lice_jpg_write.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */; }; - 33BD26CD0ECF7830000A367A /* lice_pcx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C50ECF7830000A367A /* lice_pcx.cpp */; }; - 33BD26CE0ECF7830000A367A /* lice_png_write.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C60ECF7830000A367A /* lice_png_write.cpp */; }; - 33BD26CF0ECF7830000A367A /* lice_textnew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C80ECF7830000A367A /* lice_textnew.cpp */; }; - 33BD26DF0ECF78C3000A367A /* fly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26DE0ECF78C3000A367A /* fly.cpp */; }; - 33E075650CE4DDD3005DDE14 /* Controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33E075640CE4DDD3005DDE14 /* Controller.mm */; }; - 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-dlg.mm"; path = "../../swell/swell-dlg.mm"; sourceTree = SOURCE_ROOT; }; - 33343C080CE4DB7000FF8CE6 /* swell-dlggen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "swell-dlggen.h"; path = "../../swell/swell-dlggen.h"; sourceTree = SOURCE_ROOT; }; - 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../../swell/swell-gdi.mm"; sourceTree = SOURCE_ROOT; }; - 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "swell-ini.cpp"; path = "../../swell/swell-ini.cpp"; sourceTree = SOURCE_ROOT; }; - 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-kb.mm"; path = "../../swell/swell-kb.mm"; sourceTree = SOURCE_ROOT; }; - 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-menu.mm"; path = "../../swell/swell-menu.mm"; sourceTree = SOURCE_ROOT; }; - 33343C0E0CE4DB7000FF8CE6 /* swell-menugen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "swell-menugen.h"; path = "../../swell/swell-menugen.h"; sourceTree = SOURCE_ROOT; }; - 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-miscdlg.mm"; path = "../../swell/swell-miscdlg.mm"; sourceTree = SOURCE_ROOT; }; - 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-wnd.mm"; path = "../../swell/swell-wnd.mm"; sourceTree = SOURCE_ROOT; }; - 33343C110CE4DB7000FF8CE6 /* swell.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = swell.cpp; path = ../../swell/swell.cpp; sourceTree = SOURCE_ROOT; }; - 33343C120CE4DB7000FF8CE6 /* swell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = swell.h; path = ../../swell/swell.h; sourceTree = SOURCE_ROOT; }; - 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_arc.cpp; path = ../lice_arc.cpp; sourceTree = SOURCE_ROOT; }; - 33343C230CE4DBBB00FF8CE6 /* lice_combine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lice_combine.h; path = ../lice_combine.h; sourceTree = SOURCE_ROOT; }; - 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_gif.cpp; path = ../lice_gif.cpp; sourceTree = SOURCE_ROOT; }; - 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg.cpp; path = ../lice_jpg.cpp; sourceTree = SOURCE_ROOT; }; - 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_line.cpp; path = ../lice_line.cpp; sourceTree = SOURCE_ROOT; }; - 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png.cpp; path = ../lice_png.cpp; sourceTree = SOURCE_ROOT; }; - 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_texgen.cpp; path = ../lice_texgen.cpp; sourceTree = SOURCE_ROOT; }; - 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_text.cpp; path = ../lice_text.cpp; sourceTree = SOURCE_ROOT; }; - 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice.cpp; path = ../lice.cpp; sourceTree = SOURCE_ROOT; }; - 33343C2B0CE4DBBB00FF8CE6 /* lice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lice.h; path = ../lice.h; sourceTree = SOURCE_ROOT; }; - 33343C340CE4DBD200FF8CE6 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../../giflib/config.h; sourceTree = SOURCE_ROOT; }; - 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dgif_lib.c; path = ../../giflib/dgif_lib.c; sourceTree = SOURCE_ROOT; }; - 33343C360CE4DBD200FF8CE6 /* egif_lib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = egif_lib.c; path = ../../giflib/egif_lib.c; sourceTree = SOURCE_ROOT; }; - 33343C370CE4DBD200FF8CE6 /* gif_hash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gif_hash.c; path = ../../giflib/gif_hash.c; sourceTree = SOURCE_ROOT; }; - 33343C380CE4DBD200FF8CE6 /* gif_hash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_hash.h; path = ../../giflib/gif_hash.h; sourceTree = SOURCE_ROOT; }; - 33343C390CE4DBD200FF8CE6 /* gif_lib_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib_private.h; path = ../../giflib/gif_lib_private.h; sourceTree = SOURCE_ROOT; }; - 33343C3A0CE4DBD200FF8CE6 /* gif_lib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib.h; path = ../../giflib/gif_lib.h; sourceTree = SOURCE_ROOT; }; - 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gifalloc.c; path = ../../giflib/gifalloc.c; sourceTree = SOURCE_ROOT; }; - 33343C400CE4DBE200FF8CE6 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../../jpeglib/jcapimin.c; sourceTree = SOURCE_ROOT; }; - 33343C410CE4DBE200FF8CE6 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../../jpeglib/jcapistd.c; sourceTree = SOURCE_ROOT; }; - 33343C420CE4DBE200FF8CE6 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../../jpeglib/jccoefct.c; sourceTree = SOURCE_ROOT; }; - 33343C430CE4DBE200FF8CE6 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../../jpeglib/jccolor.c; sourceTree = SOURCE_ROOT; }; - 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../../jpeglib/jcdctmgr.c; sourceTree = SOURCE_ROOT; }; - 33343C450CE4DBE200FF8CE6 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../../jpeglib/jchuff.c; sourceTree = SOURCE_ROOT; }; - 33343C460CE4DBE200FF8CE6 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../../jpeglib/jchuff.h; sourceTree = SOURCE_ROOT; }; - 33343C470CE4DBE200FF8CE6 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../../jpeglib/jcinit.c; sourceTree = SOURCE_ROOT; }; - 33343C480CE4DBE200FF8CE6 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../../jpeglib/jcmainct.c; sourceTree = SOURCE_ROOT; }; - 33343C490CE4DBE200FF8CE6 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../../jpeglib/jcmarker.c; sourceTree = SOURCE_ROOT; }; - 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../../jpeglib/jcmaster.c; sourceTree = SOURCE_ROOT; }; - 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../../jpeglib/jcomapi.c; sourceTree = SOURCE_ROOT; }; - 33343C4C0CE4DBE200FF8CE6 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../../jpeglib/jconfig.h; sourceTree = SOURCE_ROOT; }; - 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../../jpeglib/jcparam.c; sourceTree = SOURCE_ROOT; }; - 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../../jpeglib/jcphuff.c; sourceTree = SOURCE_ROOT; }; - 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../../jpeglib/jcprepct.c; sourceTree = SOURCE_ROOT; }; - 33343C500CE4DBE200FF8CE6 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../../jpeglib/jcsample.c; sourceTree = SOURCE_ROOT; }; - 33343C510CE4DBE200FF8CE6 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../../jpeglib/jctrans.c; sourceTree = SOURCE_ROOT; }; - 33343C520CE4DBE200FF8CE6 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../../jpeglib/jdapimin.c; sourceTree = SOURCE_ROOT; }; - 33343C530CE4DBE200FF8CE6 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../../jpeglib/jdapistd.c; sourceTree = SOURCE_ROOT; }; - 33343C540CE4DBE200FF8CE6 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../../jpeglib/jdatadst.c; sourceTree = SOURCE_ROOT; }; - 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../../jpeglib/jdatasrc.c; sourceTree = SOURCE_ROOT; }; - 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../../jpeglib/jdcoefct.c; sourceTree = SOURCE_ROOT; }; - 33343C570CE4DBE200FF8CE6 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../../jpeglib/jdcolor.c; sourceTree = SOURCE_ROOT; }; - 33343C580CE4DBE200FF8CE6 /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdct.h; path = ../../jpeglib/jdct.h; sourceTree = SOURCE_ROOT; }; - 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../../jpeglib/jddctmgr.c; sourceTree = SOURCE_ROOT; }; - 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../../jpeglib/jdhuff.c; sourceTree = SOURCE_ROOT; }; - 33343C5B0CE4DBE200FF8CE6 /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdhuff.h; path = ../../jpeglib/jdhuff.h; sourceTree = SOURCE_ROOT; }; - 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../../jpeglib/jdinput.c; sourceTree = SOURCE_ROOT; }; - 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../../jpeglib/jdmainct.c; sourceTree = SOURCE_ROOT; }; - 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../../jpeglib/jdmarker.c; sourceTree = SOURCE_ROOT; }; - 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../../jpeglib/jdmaster.c; sourceTree = SOURCE_ROOT; }; - 33343C600CE4DBE200FF8CE6 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../../jpeglib/jdmerge.c; sourceTree = SOURCE_ROOT; }; - 33343C610CE4DBE200FF8CE6 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../../jpeglib/jdphuff.c; sourceTree = SOURCE_ROOT; }; - 33343C620CE4DBE200FF8CE6 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../../jpeglib/jdpostct.c; sourceTree = SOURCE_ROOT; }; - 33343C630CE4DBE200FF8CE6 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../../jpeglib/jdsample.c; sourceTree = SOURCE_ROOT; }; - 33343C640CE4DBE200FF8CE6 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../../jpeglib/jdtrans.c; sourceTree = SOURCE_ROOT; }; - 33343C650CE4DBE200FF8CE6 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../../jpeglib/jerror.c; sourceTree = SOURCE_ROOT; }; - 33343C660CE4DBE200FF8CE6 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../../jpeglib/jerror.h; sourceTree = SOURCE_ROOT; }; - 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../../jpeglib/jfdctflt.c; sourceTree = SOURCE_ROOT; }; - 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../../jpeglib/jfdctfst.c; sourceTree = SOURCE_ROOT; }; - 33343C690CE4DBE200FF8CE6 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../../jpeglib/jfdctint.c; sourceTree = SOURCE_ROOT; }; - 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../../jpeglib/jidctflt.c; sourceTree = SOURCE_ROOT; }; - 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../../jpeglib/jidctfst.c; sourceTree = SOURCE_ROOT; }; - 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../../jpeglib/jidctint.c; sourceTree = SOURCE_ROOT; }; - 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../../jpeglib/jidctred.c; sourceTree = SOURCE_ROOT; }; - 33343C6E0CE4DBE200FF8CE6 /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jinclude.h; path = ../../jpeglib/jinclude.h; sourceTree = SOURCE_ROOT; }; - 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../../jpeglib/jmemmgr.c; sourceTree = SOURCE_ROOT; }; - 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../../jpeglib/jmemnobs.c; sourceTree = SOURCE_ROOT; }; - 33343C710CE4DBE200FF8CE6 /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmemsys.h; path = ../../jpeglib/jmemsys.h; sourceTree = SOURCE_ROOT; }; - 33343C720CE4DBE200FF8CE6 /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmorecfg.h; path = ../../jpeglib/jmorecfg.h; sourceTree = SOURCE_ROOT; }; - 33343C730CE4DBE200FF8CE6 /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpegint.h; path = ../../jpeglib/jpegint.h; sourceTree = SOURCE_ROOT; }; - 33343C740CE4DBE200FF8CE6 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../../jpeglib/jpeglib.h; sourceTree = SOURCE_ROOT; }; - 33343C750CE4DBE200FF8CE6 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../../jpeglib/jquant1.c; sourceTree = SOURCE_ROOT; }; - 33343C760CE4DBE200FF8CE6 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../../jpeglib/jquant2.c; sourceTree = SOURCE_ROOT; }; - 33343C770CE4DBE200FF8CE6 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../jpeglib/jutils.c; sourceTree = SOURCE_ROOT; }; - 33343C780CE4DBE200FF8CE6 /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jversion.h; path = ../../jpeglib/jversion.h; sourceTree = SOURCE_ROOT; }; - 33343CE50CE4DCFB00FF8CE6 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ../../zlib/adler32.c; sourceTree = SOURCE_ROOT; }; - 33343CE60CE4DCFB00FF8CE6 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ../../zlib/compress.c; sourceTree = SOURCE_ROOT; }; - 33343CE70CE4DCFB00FF8CE6 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ../../zlib/crc32.c; sourceTree = SOURCE_ROOT; }; - 33343CE80CE4DCFB00FF8CE6 /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = ../../zlib/crc32.h; sourceTree = SOURCE_ROOT; }; - 33343CE90CE4DCFB00FF8CE6 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ../../zlib/deflate.c; sourceTree = SOURCE_ROOT; }; - 33343CEA0CE4DCFB00FF8CE6 /* deflate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = deflate.h; path = ../../zlib/deflate.h; sourceTree = SOURCE_ROOT; }; - 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gzio.c; path = ../../zlib/gzio.c; sourceTree = SOURCE_ROOT; }; - 33343CED0CE4DCFB00FF8CE6 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ../../zlib/infback.c; sourceTree = SOURCE_ROOT; }; - 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../../zlib/inffast.c; sourceTree = SOURCE_ROOT; }; - 33343CEF0CE4DCFB00FF8CE6 /* inffast.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inffast.h; path = ../../zlib/inffast.h; sourceTree = SOURCE_ROOT; }; - 33343CF00CE4DCFB00FF8CE6 /* inffixed.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inffixed.h; path = ../../zlib/inffixed.h; sourceTree = SOURCE_ROOT; }; - 33343CF10CE4DCFB00FF8CE6 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ../../zlib/inflate.c; sourceTree = SOURCE_ROOT; }; - 33343CF20CE4DCFB00FF8CE6 /* inflate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inflate.h; path = ../../zlib/inflate.h; sourceTree = SOURCE_ROOT; }; - 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ../../zlib/inftrees.c; sourceTree = SOURCE_ROOT; }; - 33343CF40CE4DCFB00FF8CE6 /* inftrees.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inftrees.h; path = ../../zlib/inftrees.h; sourceTree = SOURCE_ROOT; }; - 33343CF60CE4DCFB00FF8CE6 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ../../zlib/trees.c; sourceTree = SOURCE_ROOT; }; - 33343CF70CE4DCFB00FF8CE6 /* trees.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = trees.h; path = ../../zlib/trees.h; sourceTree = SOURCE_ROOT; }; - 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ../../zlib/uncompr.c; sourceTree = SOURCE_ROOT; }; - 33343CF90CE4DCFB00FF8CE6 /* zconf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zconf.h; path = ../../zlib/zconf.h; sourceTree = SOURCE_ROOT; }; - 33343CFA0CE4DCFB00FF8CE6 /* zconf.in.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zconf.in.h; path = ../../zlib/zconf.in.h; sourceTree = SOURCE_ROOT; }; - 33343CFB0CE4DCFB00FF8CE6 /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = ../../zlib/zlib.h; sourceTree = SOURCE_ROOT; }; - 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ../../zlib/zutil.c; sourceTree = SOURCE_ROOT; }; - 33343CFD0CE4DCFB00FF8CE6 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = ../../zlib/zutil.h; sourceTree = SOURCE_ROOT; }; - 33343D0D0CE4DD1F00FF8CE6 /* png.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../../libpng/png.c; sourceTree = SOURCE_ROOT; }; - 33343D0E0CE4DD1F00FF8CE6 /* png.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = png.h; path = ../../libpng/png.h; sourceTree = SOURCE_ROOT; }; - 33343D0F0CE4DD1F00FF8CE6 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = ../../libpng/pngconf.h; sourceTree = SOURCE_ROOT; }; - 33343D100CE4DD1F00FF8CE6 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../../libpng/pngerror.c; sourceTree = SOURCE_ROOT; }; - 33343D120CE4DD1F00FF8CE6 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../../libpng/pngget.c; sourceTree = SOURCE_ROOT; }; - 33343D130CE4DD1F00FF8CE6 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../../libpng/pngmem.c; sourceTree = SOURCE_ROOT; }; - 33343D140CE4DD1F00FF8CE6 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../../libpng/pngpread.c; sourceTree = SOURCE_ROOT; }; - 33343D150CE4DD1F00FF8CE6 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../../libpng/pngread.c; sourceTree = SOURCE_ROOT; }; - 33343D160CE4DD1F00FF8CE6 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../../libpng/pngrio.c; sourceTree = SOURCE_ROOT; }; - 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; }; - 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; }; - 33343D190CE4DD1F00FF8CE6 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../../libpng/pngset.c; sourceTree = SOURCE_ROOT; }; - 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; }; - 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../../libpng/pngwio.c; sourceTree = SOURCE_ROOT; }; - 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = ../../libpng/pngwrite.c; sourceTree = SOURCE_ROOT; }; - 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; }; - 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; }; - 334560570CE4E727004D76AE /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 3350A9D0146B63B500702E1F /* lice_lvg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_lvg.cpp; path = ../lice_lvg.cpp; sourceTree = SOURCE_ROOT; }; - 3350A9D1146B63B500702E1F /* lice_palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_palette.cpp; path = ../lice_palette.cpp; sourceTree = SOURCE_ROOT; }; - 33651CDD10B766A6005FF751 /* swell-misc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-misc.mm"; path = "../../swell/swell-misc.mm"; sourceTree = SOURCE_ROOT; }; - 33651CDF10B766B2005FF751 /* lice_svg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_svg.cpp; path = ../lice_svg.cpp; sourceTree = SOURCE_ROOT; }; - 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = libxml_tinyxml.cpp; path = ../../tinyxml/libxml_tinyxml.cpp; sourceTree = SOURCE_ROOT; }; - 33651CE410B766E1005FF751 /* libxml_tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libxml_tinyxml.h; path = ../../tinyxml/libxml_tinyxml.h; sourceTree = SOURCE_ROOT; }; - 33651CE510B766E1005FF751 /* svgtiny_colors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = svgtiny_colors.c; path = ../../tinyxml/svgtiny_colors.c; sourceTree = SOURCE_ROOT; }; - 33651CE610B766E1005FF751 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinystr.cpp; path = ../../tinyxml/tinystr.cpp; sourceTree = SOURCE_ROOT; }; - 33651CE710B766E1005FF751 /* tinystr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinystr.h; path = ../../tinyxml/tinystr.h; sourceTree = SOURCE_ROOT; }; - 33651CE810B766E1005FF751 /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml.cpp; path = ../../tinyxml/tinyxml.cpp; sourceTree = SOURCE_ROOT; }; - 33651CE910B766E1005FF751 /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml.h; path = ../../tinyxml/tinyxml.h; sourceTree = SOURCE_ROOT; }; - 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlerror.cpp; path = ../../tinyxml/tinyxmlerror.cpp; sourceTree = SOURCE_ROOT; }; - 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlparser.cpp; path = ../../tinyxml/tinyxmlparser.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26AC0ECF7811000A367A /* pl_cam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_cam.cpp; path = ../../plush2/pl_cam.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26AD0ECF7811000A367A /* pl_make.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_make.cpp; path = ../../plush2/pl_make.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26AE0ECF7811000A367A /* pl_math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_math.cpp; path = ../../plush2/pl_math.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26AF0ECF7811000A367A /* pl_obj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_obj.cpp; path = ../../plush2/pl_obj.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B00ECF7811000A367A /* pl_pf_tex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pl_pf_tex.h; path = ../../plush2/pl_pf_tex.h; sourceTree = SOURCE_ROOT; }; - 33BD26B10ECF7811000A367A /* pl_putface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_putface.cpp; path = ../../plush2/pl_putface.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_3ds.cpp; path = ../../plush2/pl_read_3ds.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_cob.cpp; path = ../../plush2/pl_read_cob.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_jaw.cpp; path = ../../plush2/pl_read_jaw.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B50ECF7811000A367A /* pl_spline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_spline.cpp; path = ../../plush2/pl_spline.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26B60ECF7811000A367A /* plush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plush.h; path = ../../plush2/plush.h; sourceTree = SOURCE_ROOT; }; - 33BD26C00ECF7830000A367A /* lice_bezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_bezier.h; path = ../lice_bezier.h; sourceTree = SOURCE_ROOT; }; - 33BD26C10ECF7830000A367A /* lice_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_bmp.cpp; path = ../lice_bmp.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C20ECF7830000A367A /* lice_ico.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_ico.cpp; path = ../lice_ico.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C30ECF7830000A367A /* lice_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_image.cpp; path = ../lice_image.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg_write.cpp; path = ../lice_jpg_write.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C50ECF7830000A367A /* lice_pcx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_pcx.cpp; path = ../lice_pcx.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C60ECF7830000A367A /* lice_png_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png_write.cpp; path = ../lice_png_write.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26C70ECF7830000A367A /* lice_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_text.h; path = ../lice_text.h; sourceTree = SOURCE_ROOT; }; - 33BD26C80ECF7830000A367A /* lice_textnew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_textnew.cpp; path = ../lice_textnew.cpp; sourceTree = SOURCE_ROOT; }; - 33BD26DE0ECF78C3000A367A /* fly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fly.cpp; sourceTree = ""; }; - 33E075630CE4DDD3005DDE14 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; - 33E075640CE4DDD3005DDE14 /* Controller.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = Controller.mm; sourceTree = ""; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - 334560580CE4E727004D76AE /* Carbon.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { - isa = PBXGroup; - children = ( - 33E075630CE4DDD3005DDE14 /* Controller.h */, - 33E075640CE4DDD3005DDE14 /* Controller.mm */, - ); - name = Classes; - sourceTree = ""; - }; - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 334560570CE4E727004D76AE /* Carbon.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* test.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* test */ = { - isa = PBXGroup; - children = ( - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = test; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 33BD26DE0ECF78C3000A367A /* fly.cpp */, - 33BD26AA0ECF77F9000A367A /* plush2 */, - 33343C1B0CE4DB7B00FF8CE6 /* LICE */, - 33343C050CE4DB4A00FF8CE6 /* SWELL */, - 29B97316FDCFA39411CA2CEA /* main.m */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 8D1107310486CEB800E47090 /* Info.plist */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 33343C050CE4DB4A00FF8CE6 /* SWELL */ = { - isa = PBXGroup; - children = ( - 33651CDD10B766A6005FF751 /* swell-misc.mm */, - 33343C080CE4DB7000FF8CE6 /* swell-dlggen.h */, - 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */, - 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */, - 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */, - 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */, - 33343C0E0CE4DB7000FF8CE6 /* swell-menugen.h */, - 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */, - 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */, - 33343C110CE4DB7000FF8CE6 /* swell.cpp */, - 33343C120CE4DB7000FF8CE6 /* swell.h */, - 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */, - ); - name = SWELL; - sourceTree = ""; - }; - 33343C1B0CE4DB7B00FF8CE6 /* LICE */ = { - isa = PBXGroup; - children = ( - 3350A9D0146B63B500702E1F /* lice_lvg.cpp */, - 3350A9D1146B63B500702E1F /* lice_palette.cpp */, - 33651CE110B766B6005FF751 /* tinyxml */, - 33651CDF10B766B2005FF751 /* lice_svg.cpp */, - 33BD26C00ECF7830000A367A /* lice_bezier.h */, - 33BD26C10ECF7830000A367A /* lice_bmp.cpp */, - 33BD26C20ECF7830000A367A /* lice_ico.cpp */, - 33BD26C30ECF7830000A367A /* lice_image.cpp */, - 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */, - 33BD26C50ECF7830000A367A /* lice_pcx.cpp */, - 33BD26C60ECF7830000A367A /* lice_png_write.cpp */, - 33BD26C70ECF7830000A367A /* lice_text.h */, - 33BD26C80ECF7830000A367A /* lice_textnew.cpp */, - 33343C230CE4DBBB00FF8CE6 /* lice_combine.h */, - 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */, - 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */, - 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */, - 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */, - 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */, - 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */, - 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */, - 33343C2B0CE4DBBB00FF8CE6 /* lice.h */, - 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */, - 33343C1F0CE4DB9200FF8CE6 /* giflib */, - 33343C1E0CE4DB8E00FF8CE6 /* JPeglib */, - 33343C1D0CE4DB8A00FF8CE6 /* Zlib */, - 33343C1C0CE4DB8100FF8CE6 /* PNGlib */, - ); - name = LICE; - sourceTree = ""; - }; - 33343C1C0CE4DB8100FF8CE6 /* PNGlib */ = { - isa = PBXGroup; - children = ( - 33343D0D0CE4DD1F00FF8CE6 /* png.c */, - 33343D0E0CE4DD1F00FF8CE6 /* png.h */, - 33343D0F0CE4DD1F00FF8CE6 /* pngconf.h */, - 33343D100CE4DD1F00FF8CE6 /* pngerror.c */, - 33343D120CE4DD1F00FF8CE6 /* pngget.c */, - 33343D130CE4DD1F00FF8CE6 /* pngmem.c */, - 33343D140CE4DD1F00FF8CE6 /* pngpread.c */, - 33343D150CE4DD1F00FF8CE6 /* pngread.c */, - 33343D160CE4DD1F00FF8CE6 /* pngrio.c */, - 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */, - 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */, - 33343D190CE4DD1F00FF8CE6 /* pngset.c */, - 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */, - 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */, - 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */, - 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */, - 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */, - ); - name = PNGlib; - sourceTree = ""; - }; - 33343C1D0CE4DB8A00FF8CE6 /* Zlib */ = { - isa = PBXGroup; - children = ( - 33343CE50CE4DCFB00FF8CE6 /* adler32.c */, - 33343CE60CE4DCFB00FF8CE6 /* compress.c */, - 33343CE70CE4DCFB00FF8CE6 /* crc32.c */, - 33343CE80CE4DCFB00FF8CE6 /* crc32.h */, - 33343CE90CE4DCFB00FF8CE6 /* deflate.c */, - 33343CEA0CE4DCFB00FF8CE6 /* deflate.h */, - 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */, - 33343CED0CE4DCFB00FF8CE6 /* infback.c */, - 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */, - 33343CEF0CE4DCFB00FF8CE6 /* inffast.h */, - 33343CF00CE4DCFB00FF8CE6 /* inffixed.h */, - 33343CF10CE4DCFB00FF8CE6 /* inflate.c */, - 33343CF20CE4DCFB00FF8CE6 /* inflate.h */, - 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */, - 33343CF40CE4DCFB00FF8CE6 /* inftrees.h */, - 33343CF60CE4DCFB00FF8CE6 /* trees.c */, - 33343CF70CE4DCFB00FF8CE6 /* trees.h */, - 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */, - 33343CF90CE4DCFB00FF8CE6 /* zconf.h */, - 33343CFA0CE4DCFB00FF8CE6 /* zconf.in.h */, - 33343CFB0CE4DCFB00FF8CE6 /* zlib.h */, - 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */, - 33343CFD0CE4DCFB00FF8CE6 /* zutil.h */, - ); - name = Zlib; - sourceTree = ""; - }; - 33343C1E0CE4DB8E00FF8CE6 /* JPeglib */ = { - isa = PBXGroup; - children = ( - 33343C400CE4DBE200FF8CE6 /* jcapimin.c */, - 33343C410CE4DBE200FF8CE6 /* jcapistd.c */, - 33343C420CE4DBE200FF8CE6 /* jccoefct.c */, - 33343C430CE4DBE200FF8CE6 /* jccolor.c */, - 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */, - 33343C450CE4DBE200FF8CE6 /* jchuff.c */, - 33343C460CE4DBE200FF8CE6 /* jchuff.h */, - 33343C470CE4DBE200FF8CE6 /* jcinit.c */, - 33343C480CE4DBE200FF8CE6 /* jcmainct.c */, - 33343C490CE4DBE200FF8CE6 /* jcmarker.c */, - 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */, - 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */, - 33343C4C0CE4DBE200FF8CE6 /* jconfig.h */, - 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */, - 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */, - 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */, - 33343C500CE4DBE200FF8CE6 /* jcsample.c */, - 33343C510CE4DBE200FF8CE6 /* jctrans.c */, - 33343C520CE4DBE200FF8CE6 /* jdapimin.c */, - 33343C530CE4DBE200FF8CE6 /* jdapistd.c */, - 33343C540CE4DBE200FF8CE6 /* jdatadst.c */, - 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */, - 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */, - 33343C570CE4DBE200FF8CE6 /* jdcolor.c */, - 33343C580CE4DBE200FF8CE6 /* jdct.h */, - 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */, - 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */, - 33343C5B0CE4DBE200FF8CE6 /* jdhuff.h */, - 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */, - 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */, - 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */, - 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */, - 33343C600CE4DBE200FF8CE6 /* jdmerge.c */, - 33343C610CE4DBE200FF8CE6 /* jdphuff.c */, - 33343C620CE4DBE200FF8CE6 /* jdpostct.c */, - 33343C630CE4DBE200FF8CE6 /* jdsample.c */, - 33343C640CE4DBE200FF8CE6 /* jdtrans.c */, - 33343C650CE4DBE200FF8CE6 /* jerror.c */, - 33343C660CE4DBE200FF8CE6 /* jerror.h */, - 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */, - 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */, - 33343C690CE4DBE200FF8CE6 /* jfdctint.c */, - 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */, - 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */, - 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */, - 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */, - 33343C6E0CE4DBE200FF8CE6 /* jinclude.h */, - 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */, - 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */, - 33343C710CE4DBE200FF8CE6 /* jmemsys.h */, - 33343C720CE4DBE200FF8CE6 /* jmorecfg.h */, - 33343C730CE4DBE200FF8CE6 /* jpegint.h */, - 33343C740CE4DBE200FF8CE6 /* jpeglib.h */, - 33343C750CE4DBE200FF8CE6 /* jquant1.c */, - 33343C760CE4DBE200FF8CE6 /* jquant2.c */, - 33343C770CE4DBE200FF8CE6 /* jutils.c */, - 33343C780CE4DBE200FF8CE6 /* jversion.h */, - ); - name = JPeglib; - sourceTree = ""; - }; - 33343C1F0CE4DB9200FF8CE6 /* giflib */ = { - isa = PBXGroup; - children = ( - 33343C340CE4DBD200FF8CE6 /* config.h */, - 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */, - 33343C360CE4DBD200FF8CE6 /* egif_lib.c */, - 33343C370CE4DBD200FF8CE6 /* gif_hash.c */, - 33343C380CE4DBD200FF8CE6 /* gif_hash.h */, - 33343C390CE4DBD200FF8CE6 /* gif_lib_private.h */, - 33343C3A0CE4DBD200FF8CE6 /* gif_lib.h */, - 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */, - ); - name = giflib; - sourceTree = ""; - }; - 33651CE110B766B6005FF751 /* tinyxml */ = { - isa = PBXGroup; - children = ( - 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */, - 33651CE410B766E1005FF751 /* libxml_tinyxml.h */, - 33651CE510B766E1005FF751 /* svgtiny_colors.c */, - 33651CE610B766E1005FF751 /* tinystr.cpp */, - 33651CE710B766E1005FF751 /* tinystr.h */, - 33651CE810B766E1005FF751 /* tinyxml.cpp */, - 33651CE910B766E1005FF751 /* tinyxml.h */, - 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */, - 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */, - ); - name = tinyxml; - sourceTree = ""; - }; - 33BD26AA0ECF77F9000A367A /* plush2 */ = { - isa = PBXGroup; - children = ( - 33BD26AC0ECF7811000A367A /* pl_cam.cpp */, - 33BD26AD0ECF7811000A367A /* pl_make.cpp */, - 33BD26AE0ECF7811000A367A /* pl_math.cpp */, - 33BD26AF0ECF7811000A367A /* pl_obj.cpp */, - 33BD26B00ECF7811000A367A /* pl_pf_tex.h */, - 33BD26B10ECF7811000A367A /* pl_putface.cpp */, - 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */, - 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */, - 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */, - 33BD26B50ECF7811000A367A /* pl_spline.cpp */, - 33BD26B60ECF7811000A367A /* plush.h */, - ); - name = plush2; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8D1107260486CEB800E47090 /* test */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */; - buildPhases = ( - 8D1107290486CEB800E47090 /* Resources */, - 8D11072C0486CEB800E47090 /* Sources */, - 8D11072E0486CEB800E47090 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = test; - productInstallPath = "$(HOME)/Applications"; - productName = test; - productReference = 8D1107320486CEB800E47090 /* test.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */; - compatibilityVersion = "Xcode 2.4"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* test */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8D1107260486CEB800E47090 /* test */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072D0486CEB800E47090 /* main.m in Sources */, - 33343C070CE4DB5D00FF8CE6 /* swell-dlg.mm in Sources */, - 33343C130CE4DB7000FF8CE6 /* swell-gdi.mm in Sources */, - 33343C140CE4DB7000FF8CE6 /* swell-ini.cpp in Sources */, - 33343C150CE4DB7000FF8CE6 /* swell-kb.mm in Sources */, - 33343C160CE4DB7000FF8CE6 /* swell-menu.mm in Sources */, - 33343C170CE4DB7000FF8CE6 /* swell-miscdlg.mm in Sources */, - 33343C180CE4DB7000FF8CE6 /* swell-wnd.mm in Sources */, - 33343C190CE4DB7000FF8CE6 /* swell.cpp in Sources */, - 33343C210CE4DB9E00FF8CE6 /* lice_arc.cpp in Sources */, - 33343C2D0CE4DBBB00FF8CE6 /* lice_gif.cpp in Sources */, - 33343C2E0CE4DBBB00FF8CE6 /* lice_jpg.cpp in Sources */, - 33343C2F0CE4DBBB00FF8CE6 /* lice_line.cpp in Sources */, - 33343C300CE4DBBB00FF8CE6 /* lice_png.cpp in Sources */, - 33343C310CE4DBBB00FF8CE6 /* lice_texgen.cpp in Sources */, - 33343C320CE4DBBB00FF8CE6 /* lice_text.cpp in Sources */, - 33343C330CE4DBBB00FF8CE6 /* lice.cpp in Sources */, - 33343C3C0CE4DBD200FF8CE6 /* dgif_lib.c in Sources */, - 33343C3D0CE4DBD200FF8CE6 /* egif_lib.c in Sources */, - 33343C3E0CE4DBD200FF8CE6 /* gif_hash.c in Sources */, - 33343C3F0CE4DBD200FF8CE6 /* gifalloc.c in Sources */, - 33343C790CE4DBE200FF8CE6 /* jcapimin.c in Sources */, - 33343C7A0CE4DBE200FF8CE6 /* jcapistd.c in Sources */, - 33343C7B0CE4DBE200FF8CE6 /* jccoefct.c in Sources */, - 33343C7C0CE4DBE200FF8CE6 /* jccolor.c in Sources */, - 33343C7D0CE4DBE200FF8CE6 /* jcdctmgr.c in Sources */, - 33343C7E0CE4DBE200FF8CE6 /* jchuff.c in Sources */, - 33343C7F0CE4DBE200FF8CE6 /* jcinit.c in Sources */, - 33343C800CE4DBE200FF8CE6 /* jcmainct.c in Sources */, - 33343C810CE4DBE200FF8CE6 /* jcmarker.c in Sources */, - 33343C820CE4DBE200FF8CE6 /* jcmaster.c in Sources */, - 33343C830CE4DBE200FF8CE6 /* jcomapi.c in Sources */, - 33343C840CE4DBE200FF8CE6 /* jcparam.c in Sources */, - 33343C850CE4DBE200FF8CE6 /* jcphuff.c in Sources */, - 33343C860CE4DBE200FF8CE6 /* jcprepct.c in Sources */, - 33343C870CE4DBE200FF8CE6 /* jcsample.c in Sources */, - 33343C880CE4DBE200FF8CE6 /* jctrans.c in Sources */, - 33343C890CE4DBE200FF8CE6 /* jdapimin.c in Sources */, - 33343C8A0CE4DBE200FF8CE6 /* jdapistd.c in Sources */, - 33343C8B0CE4DBE200FF8CE6 /* jdatadst.c in Sources */, - 33343C8C0CE4DBE200FF8CE6 /* jdatasrc.c in Sources */, - 33343C8D0CE4DBE200FF8CE6 /* jdcoefct.c in Sources */, - 33343C8E0CE4DBE200FF8CE6 /* jdcolor.c in Sources */, - 33343C8F0CE4DBE200FF8CE6 /* jddctmgr.c in Sources */, - 33343C900CE4DBE200FF8CE6 /* jdhuff.c in Sources */, - 33343C910CE4DBE200FF8CE6 /* jdinput.c in Sources */, - 33343C920CE4DBE200FF8CE6 /* jdmainct.c in Sources */, - 33343C930CE4DBE200FF8CE6 /* jdmarker.c in Sources */, - 33343C940CE4DBE200FF8CE6 /* jdmaster.c in Sources */, - 33343C950CE4DBE200FF8CE6 /* jdmerge.c in Sources */, - 33343C960CE4DBE200FF8CE6 /* jdphuff.c in Sources */, - 33343C970CE4DBE200FF8CE6 /* jdpostct.c in Sources */, - 33343C980CE4DBE200FF8CE6 /* jdsample.c in Sources */, - 33343C990CE4DBE200FF8CE6 /* jdtrans.c in Sources */, - 33343C9A0CE4DBE200FF8CE6 /* jerror.c in Sources */, - 33343C9B0CE4DBE200FF8CE6 /* jfdctflt.c in Sources */, - 33343C9C0CE4DBE200FF8CE6 /* jfdctfst.c in Sources */, - 33343C9D0CE4DBE200FF8CE6 /* jfdctint.c in Sources */, - 33343C9E0CE4DBE200FF8CE6 /* jidctflt.c in Sources */, - 33343C9F0CE4DBE200FF8CE6 /* jidctfst.c in Sources */, - 33343CA00CE4DBE200FF8CE6 /* jidctint.c in Sources */, - 33343CA10CE4DBE200FF8CE6 /* jidctred.c in Sources */, - 33343CA20CE4DBE200FF8CE6 /* jmemmgr.c in Sources */, - 33343CA30CE4DBE200FF8CE6 /* jmemnobs.c in Sources */, - 33343CA40CE4DBE200FF8CE6 /* jquant1.c in Sources */, - 33343CA50CE4DBE200FF8CE6 /* jquant2.c in Sources */, - 33343CA60CE4DBE200FF8CE6 /* jutils.c in Sources */, - 33343CFE0CE4DCFB00FF8CE6 /* adler32.c in Sources */, - 33343CFF0CE4DCFB00FF8CE6 /* compress.c in Sources */, - 33343D000CE4DCFB00FF8CE6 /* crc32.c in Sources */, - 33343D010CE4DCFB00FF8CE6 /* deflate.c in Sources */, - 33343D030CE4DCFB00FF8CE6 /* gzio.c in Sources */, - 33343D040CE4DCFB00FF8CE6 /* infback.c in Sources */, - 33343D050CE4DCFB00FF8CE6 /* inffast.c in Sources */, - 33343D060CE4DCFB00FF8CE6 /* inflate.c in Sources */, - 33343D070CE4DCFB00FF8CE6 /* inftrees.c in Sources */, - 33343D090CE4DCFB00FF8CE6 /* trees.c in Sources */, - 33343D0A0CE4DCFB00FF8CE6 /* uncompr.c in Sources */, - 33343D0B0CE4DCFB00FF8CE6 /* zutil.c in Sources */, - 33343D210CE4DD1F00FF8CE6 /* png.c in Sources */, - 33343D220CE4DD1F00FF8CE6 /* pngerror.c in Sources */, - 33343D240CE4DD1F00FF8CE6 /* pngget.c in Sources */, - 33343D250CE4DD1F00FF8CE6 /* pngmem.c in Sources */, - 33343D260CE4DD1F00FF8CE6 /* pngpread.c in Sources */, - 33343D270CE4DD1F00FF8CE6 /* pngread.c in Sources */, - 33343D280CE4DD1F00FF8CE6 /* pngrio.c in Sources */, - 33343D290CE4DD1F00FF8CE6 /* pngrtran.c in Sources */, - 33343D2A0CE4DD1F00FF8CE6 /* pngrutil.c in Sources */, - 33343D2B0CE4DD1F00FF8CE6 /* pngset.c in Sources */, - 33343D2D0CE4DD1F00FF8CE6 /* pngtrans.c in Sources */, - 33343D2F0CE4DD1F00FF8CE6 /* pngwio.c in Sources */, - 33343D300CE4DD1F00FF8CE6 /* pngwrite.c in Sources */, - 33343D310CE4DD1F00FF8CE6 /* pngwtran.c in Sources */, - 33343D320CE4DD1F00FF8CE6 /* pngwutil.c in Sources */, - 33E075650CE4DDD3005DDE14 /* Controller.mm in Sources */, - 33BD26B70ECF7811000A367A /* pl_cam.cpp in Sources */, - 33BD26B80ECF7811000A367A /* pl_make.cpp in Sources */, - 33BD26B90ECF7811000A367A /* pl_math.cpp in Sources */, - 33BD26BA0ECF7811000A367A /* pl_obj.cpp in Sources */, - 33BD26BB0ECF7811000A367A /* pl_putface.cpp in Sources */, - 33BD26BC0ECF7811000A367A /* pl_read_3ds.cpp in Sources */, - 33BD26BD0ECF7811000A367A /* pl_read_cob.cpp in Sources */, - 33BD26BE0ECF7811000A367A /* pl_read_jaw.cpp in Sources */, - 33BD26BF0ECF7811000A367A /* pl_spline.cpp in Sources */, - 33BD26C90ECF7830000A367A /* lice_bmp.cpp in Sources */, - 33BD26CA0ECF7830000A367A /* lice_ico.cpp in Sources */, - 33BD26CB0ECF7830000A367A /* lice_image.cpp in Sources */, - 33BD26CC0ECF7830000A367A /* lice_jpg_write.cpp in Sources */, - 33BD26CD0ECF7830000A367A /* lice_pcx.cpp in Sources */, - 33BD26CE0ECF7830000A367A /* lice_png_write.cpp in Sources */, - 33BD26CF0ECF7830000A367A /* lice_textnew.cpp in Sources */, - 33BD26DF0ECF78C3000A367A /* fly.cpp in Sources */, - 33651CDE10B766A6005FF751 /* swell-misc.mm in Sources */, - 33651CE010B766B2005FF751 /* lice_svg.cpp in Sources */, - 33651CEC10B766E1005FF751 /* libxml_tinyxml.cpp in Sources */, - 33651CED10B766E1005FF751 /* svgtiny_colors.c in Sources */, - 33651CEE10B766E1005FF751 /* tinystr.cpp in Sources */, - 33651CEF10B766E1005FF751 /* tinyxml.cpp in Sources */, - 33651CF010B766E1005FF751 /* tinyxmlerror.cpp in Sources */, - 33651CF110B766E1005FF751 /* tinyxmlparser.cpp in Sources */, - 3350A9D2146B63B500702E1F /* lice_lvg.cpp in Sources */, - 3350A9D3146B63B500702E1F /* lice_palette.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C165DFE840E0CC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { - isa = PBXVariantGroup; - children = ( - 29B97319FDCFA39411CA2CEA /* English */, - ); - name = MainMenu.nib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = test; - WRAPPER_EXTENSION = app; - ZERO_LINK = YES; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G5; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = test; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; - GCC_PREPROCESSOR_DEFINITIONS = PNG_WRITE_SUPPORTED; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; - GCC_PREPROCESSOR_DEFINITIONS = PNG_WRITE_SUPPORTED; - GCC_VERSION = 4.0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/WDL/lineparse.h b/WDL/lineparse.h deleted file mode 100644 index a0164a4f..00000000 --- a/WDL/lineparse.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - WDL - lineparse.h - Copyright (C) 2005 Cockos Incorporated - Copyright (C) 1999-2004 Nullsoft, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple line parsing class. This class is also used in NSIS, - http://nsis.sf.net. In particular, it allows for multiple space delimited tokens - on a line, with a choice of three quotes (`bla`, 'bla', or "bla") to contain any - items that may have spaces. - - For a bigger reference on the format, you can refer to NSIS's documentation. - -*/ - -#ifndef WDL_LINEPARSE_H_ -#define WDL_LINEPARSE_H_ - - -#ifndef WDL_LINEPARSE_IMPL_ONLY -class LineParser -{ - public: - int getnumtokens() const { return (m_nt-m_eat)>=0 ? (m_nt-m_eat) : 0; } - #ifdef WDL_LINEPARSE_INTF_ONLY - int parse(const char *line, int ignore_escaping=1); //-1 on error - - double gettoken_float(int token, int *success=NULL) const; - int gettoken_int(int token, int *success=NULL) const; - unsigned int gettoken_uint(int token, int *success=NULL) const; - const char *gettoken_str(int token) const; - int gettoken_enum(int token, const char *strlist) const; // null seperated list - - void set_one_token(const char *ptr); - #endif - - void eattoken() { m_eat++; } - bool InCommentBlock() const { return m_bCommentBlock; } - - - LineParser(bool bCommentBlock=false) - { - m_bCommentBlock=bCommentBlock; - m_nt=m_eat=0; - m_tokens=0; - m_tmpbuf_used=0; - } - - ~LineParser() - { - freetokens(); - } - -#endif // !WDL_LINEPARSE_IMPL_ONLY - - - -#ifndef WDL_LINEPARSE_INTF_ONLY - #ifdef WDL_LINEPARSE_IMPL_ONLY - #define WDL_LINEPARSE_PREFIX LineParser:: - #define WDL_LINEPARSE_DEFPARM(x) - #else - #define WDL_LINEPARSE_PREFIX - #define WDL_LINEPARSE_DEFPARM(x) =(x) - #endif - - int WDL_LINEPARSE_PREFIX parse(const char *line, int ignore_escaping WDL_LINEPARSE_DEFPARM(1)) - { - freetokens(); - bool bPrevCB=m_bCommentBlock; - int n=doline(line, ignore_escaping); - if (n) { m_nt=0; return n; } - if (m_nt) - { - m_bCommentBlock=bPrevCB; - m_tokens=(char**)tmpbufalloc(sizeof(char*)*m_nt); - if (m_tokens) memset(m_tokens,0,m_nt * sizeof(char*)); - n=doline(line, ignore_escaping); - if (n) - { - freetokens(); - return -1; - } - } - return 0; - } - void WDL_LINEPARSE_PREFIX set_one_token(const char *ptr) - { - freetokens(); - m_eat=0; - m_nt=1; - m_tokens=(char **)tmpbufalloc(sizeof(char *)); - m_tokens[0]=tmpbufalloc(strlen(ptr)+1); - if (m_tokens[0]) strcpy(m_tokens[0],ptr); - } - - double WDL_LINEPARSE_PREFIX gettoken_float(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const - { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token]) - { - if (success) *success=0; - return 0.0; - } - char *t=m_tokens[token]; - if (success) - *success=*t?1:0; - - char buf[512]; - char *ot=buf; - while (*t&&(ot-buf)<500) - { - char c=*t++; - if (success && (c < '0' || c > '9')&&c != '.'&&c!=',') *success=0; - *ot++=c==','?'.':c; - } - *ot=0; - return atof(buf); - } - - int WDL_LINEPARSE_PREFIX gettoken_int(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const - { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0]) - { - if (success) *success=0; - return 0; - } - char *tmp; - int l; - if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0); - else l=(int)strtoul(m_tokens[token],&tmp,0); - if (success) *success=! (int)(*tmp); - return l; - } - - unsigned int WDL_LINEPARSE_PREFIX gettoken_uint(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const - { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0]) - { - if (success) *success=0; - return 0; - } - char *tmp; - const char* p=m_tokens[token]; - if (p[0] == '-') ++p; - unsigned int val=(int)strtoul(p, &tmp, 0); - if (success) *success=! (int)(*tmp); - return val; - } - - const char * WDL_LINEPARSE_PREFIX gettoken_str(int token) const - { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token]) return ""; - return m_tokens[token]; - } - - int WDL_LINEPARSE_PREFIX gettoken_enum(int token, const char *strlist) const // null seperated list - { - int x=0; - const char *tt=gettoken_str(token); - if (tt && *tt) while (*strlist) - { -#ifdef _WIN32 - if (!stricmp(tt,strlist)) return x; -#else - if (!strcasecmp(tt,strlist)) return x; -#endif - strlist+=strlen(strlist)+1; - x++; - } - return -1; - } - -#ifndef WDL_LINEPARSE_IMPL_ONLY - private: -#endif - - void WDL_LINEPARSE_PREFIX freetokens() - { - if (m_tokens) - { - int x; - for (x = 0; x < m_nt; x ++) tmpbuffree(m_tokens[x]); - tmpbuffree((char*)m_tokens); - } - m_tmpbuf_used=0; - m_tokens=0; - m_nt=0; - } - - int WDL_LINEPARSE_PREFIX doline(const char *line, int ignore_escaping) - { - m_nt=0; - if ( m_bCommentBlock ) - { - while ( *line ) - { - if ( *line == '*' && *(line+1) == '/' ) - { - m_bCommentBlock=false; // Found end of comment block - line+=2; - break; - } - line++; - } - } - while (*line == ' ' || *line == '\t') line++; - while (*line) - { - int lstate=0; // 1=", 2=`, 4=' - if (*line == ';' || *line == '#') break; - if (*line == '/' && *(line+1) == '*') - { - m_bCommentBlock = true; - line+=2; - return doline(line, ignore_escaping); - } - if (*line == '\"') lstate=1; - else if (*line == '\'') lstate=2; - else if (*line == '`') lstate=4; - if (lstate) line++; - int nc=0; - const char *p = line; - while (*line) - { - if (line[0] == '$' && line[1] == '\\') { - switch (line[2]) { - case '"': - case '\'': - case '`': - nc += ignore_escaping ? 3 : 1; - line += 3; - continue; - } - } - if (lstate==1 && *line =='\"') break; - if (lstate==2 && *line =='\'') break; - if (lstate==4 && *line =='`') break; - if (!lstate && (*line == ' ' || *line == '\t')) break; - line++; - nc++; - } - if (m_tokens) - { - int i; - m_tokens[m_nt]=tmpbufalloc(nc+1); - for (i = 0; p < line; i++, p++) { - if (!ignore_escaping && p[0] == '$' && p[1] == '\\') { - switch (p[2]) { - case '"': - case '\'': - case '`': - p += 2; - } - } - m_tokens[m_nt][i] = *p; - } - m_tokens[m_nt][nc]=0; - } - m_nt++; - if (lstate) - { - if (*line) line++; - else return -2; - } - while (*line == ' ' || *line == '\t') line++; - } - return 0; - } - - char * WDL_LINEPARSE_PREFIX tmpbufalloc(int sz) - { - if (sz<1)sz=1; - if (sz+m_tmpbuf_used <= (int)sizeof(m_tmpbuf)) - { - m_tmpbuf_used+=sz; - return m_tmpbuf + m_tmpbuf_used - sz; - } - return (char *)malloc(sz); - } - void WDL_LINEPARSE_PREFIX tmpbuffree(char *p) - { - if (p < m_tmpbuf || p >= m_tmpbuf + sizeof(m_tmpbuf)) free(p); - } - - #undef WDL_LINEPARSE_PREFIX - #undef WDL_LINEPARSE_DEFPARM -#endif // ! WDL_LINEPARSE_INTF_ONLY - -#ifndef WDL_LINEPARSE_IMPL_ONLY - private: - -#ifdef WDL_LINEPARSE_INTF_ONLY - void freetokens(); - int doline(const char *line, int ignore_escaping); - char *tmpbufalloc(int sz); - void tmpbuffree(char *p); -#endif - - int m_eat; - int m_nt; - int m_tmpbuf_used; - bool m_bCommentBlock; - char **m_tokens; - char m_tmpbuf[2048]; -}; -#endif//!WDL_LINEPARSE_IMPL_ONLY -#endif//WDL_LINEPARSE_H_ - diff --git a/WDL/makedist.bat b/WDL/makedist.bat deleted file mode 100644 index 7cae1745..00000000 --- a/WDL/makedist.bat +++ /dev/null @@ -1,13 +0,0 @@ -del wdl.zip -cd.. -zip -X9r wdl\wdl.zip wdl -i *.c *.cpp *.cc *.h *.m *.mm *.png *.ico *.txt *.bat *.rc *.plist *.dsp *.dsw *.pbxproj *.strings *.nib *.php *.exp *.vcproj *.vcxproj *_prefix.pch *.r *.xib *.sln *.icns - -zip -X9r wdl\wdl.zip wdl\eel2\asm-nseel-x64-macho.o - -zip -X9r wdl\wdl.zip wdl\iplug\example\img.zip - -zip -X9r wdl\wdl.zip wdl\jnetlib\makefile -zip -X9r wdl\wdl.zip wdl\jpeglib\readme -zip -X9r wdl\wdl.zip wdl\giflib\authors wdl\giflib\changelog wdl\giflib\copying wdl\giflib\developers wdl\giflib\readme - -cd wdl diff --git a/WDL/mergesort.h b/WDL/mergesort.h deleted file mode 100644 index 549eebf4..00000000 --- a/WDL/mergesort.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _WDL_MERGESORT_H_ -#define _WDL_MERGESORT_H_ - - -static void WDL_mergesort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *), char *tmpspace) -{ - char *b1,*b2; - size_t n1, n2; - - if (nmemb < 2) return; - - n1 = nmemb / 2; - b1 = (char *) base; - n2 = nmemb - n1; - b2 = b1 + (n1 * size); - - if (nmemb>2) - { - WDL_mergesort(b1, n1, size, compar, tmpspace); - WDL_mergesort(b2, n2, size, compar, tmpspace); - } - - - do - { - if (compar(b1, b2) > 0) // out of order, go to full merge - { - int sofar = b1-(char*)base; - memcpy(tmpspace,base,sofar); - memcpy(tmpspace+sofar, b2, size); - b2 += size; - n2--; - - char *writeptr=tmpspace+sofar+size; - while (n1 > 0 && n2 > 0) - { - if (compar(b1, b2) > 0) - { - memcpy(writeptr, b2, size); - b2 += size; - n2--; - } - else - { - memcpy(writeptr, b1, size); - b1 += size; - n1--; - } - writeptr += size; - } - - if (n1 > 0) memcpy(writeptr, b1, n1 * size); - memcpy(base, tmpspace, (nmemb - n2) * size); - - break; - } - - // in order, just advance - b1 += size; - n1--; - } - while (n1 > 0 && n2 > 0); -} - -#endif//_WDL_MERGESORT_H_ \ No newline at end of file diff --git a/WDL/mp3write.h b/WDL/mp3write.h deleted file mode 100644 index 1dc97fbc..00000000 --- a/WDL/mp3write.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - WDL - mp3write.h - Copyright (C) 2005 Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple class for writing MP3 files (using lameencdec.h) - -*/ - - -#ifndef _MP3WRITE_H_ -#define _MP3WRITE_H_ - - -#include -#include "lameencdec.h" - -class mp3Writer -{ - public: - // appending doesnt check sample types - mp3Writer() - { - m_enc=0; - m_fp=0; - m_srate=0; - m_nch=0; - } - - mp3Writer(char *filename, int nch, int srate, int bitrate, int allow_append=1) - { - m_enc=0; - m_fp=0; - m_srate=0; - m_nch=0; - Open(filename,nch,srate,bitrate,allow_append); - - } - - int Open(char *filename, int nch, int srate, int bitrate, int allow_append=1) - { - m_fp=0; - if (allow_append) - { - m_fp=fopen(filename,"r+b"); - if (m_fp) - { - fseek(m_fp,0,SEEK_END); - } - } - if (!m_fp) - { - m_fp=fopen(filename,"wb"); - } - m_nch=nch>1?2:1; - m_srate=srate; - m_enc = new LameEncoder(srate,nch,bitrate); - if (m_enc->Status()) - { - delete m_enc; - m_enc=0; - } - return m_fp && m_enc; - } - - ~mp3Writer() - { - if (m_fp) - { - if (m_enc) - { - m_enc->Encode(NULL,0); - if (m_enc->outqueue.Available()) - { - fwrite(m_enc->outqueue.Get(),1,m_enc->outqueue.GetSize(),m_fp); - fflush(m_fp); - m_enc->outqueue.Advance(m_enc->outqueue.GetSize()); - m_enc->outqueue.Compact(); - } - } - - fclose(m_fp); - m_fp=0; - } - if (m_enc) - { - delete m_enc; - m_enc=0; - } - } - - int Status() { return m_enc && m_fp; } - - void WriteFloats(float *samples, int nsamples) - { - if (!m_fp || !m_enc) return; - - m_enc->Encode(samples,nsamples/m_nch); - if (m_enc->outqueue.Available()) - { - fwrite(m_enc->outqueue.Get(),1,m_enc->outqueue.GetSize(),m_fp); - fflush(m_fp); - m_enc->outqueue.Advance(m_enc->outqueue.GetSize()); - m_enc->outqueue.Compact(); - } - - } - - int get_nch() { return m_nch; } - int get_srate() { return m_srate; } - - private: - FILE *m_fp; - int m_nch,m_srate; - LameEncoder *m_enc; -}; - - -#endif//_MP3WRITE_H_ \ No newline at end of file diff --git a/WDL/mutex.h b/WDL/mutex.h deleted file mode 100644 index 6420986c..00000000 --- a/WDL/mutex.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - WDL - mutex.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - - This file provides a simple class that abstracts a mutex or critical section object. - On Windows it uses CRITICAL_SECTION, on everything else it uses pthread's mutex library. - It simulates the Critical Section behavior on non-Windows, as well (meaning a thread can - safely Enter the mutex multiple times, provided it Leaves the same number of times) - -*/ - -#ifndef _WDL_MUTEX_H_ -#define _WDL_MUTEX_H_ - -#ifdef _WIN32 -#include -#else - -#include -// define this if you wish to use carbon critical sections on OS X -// #define WDL_MAC_USE_CARBON_CRITSEC - -#ifdef WDL_MAC_USE_CARBON_CRITSEC -#include -#else -#include -#endif - -#ifdef __APPLE__ -#include -#endif - -#endif - -#include "wdltypes.h" - -class WDL_Mutex { - public: - WDL_Mutex() - { -#ifdef _DEBUG - _debug_cnt=0; -#endif - -#ifdef _WIN32 - InitializeCriticalSection(&m_cs); -#else -#ifdef WDL_MAC_USE_CARBON_CRITSEC - MPCreateCriticalRegion(&m_cr); -#else - m_ownerthread=0; - m_lockcnt=0; - pthread_mutex_init(&m_mutex,NULL); -#endif -#endif - } - ~WDL_Mutex() - { -#ifdef _WIN32 - DeleteCriticalSection(&m_cs); -#else -#ifdef WDL_MAC_USE_CARBON_CRITSEC - MPDeleteCriticalRegion(m_cr); -#else - pthread_mutex_destroy(&m_mutex); -#endif -#endif - } - - void Enter() - { -#ifdef _DEBUG - _debug_cnt++; -#endif - -#ifdef _WIN32 - EnterCriticalSection(&m_cs); -#else -#ifdef WDL_MAC_USE_CARBON_CRITSEC - MPEnterCriticalRegion(m_cr,kDurationForever); -#else - pthread_t tt=pthread_self(); - if (m_ownerthread==tt) m_lockcnt++; - else - { - pthread_mutex_lock(&m_mutex); - m_ownerthread=tt; - m_lockcnt=0; - } -#endif -#endif - } - - void Leave() - { -#ifdef _DEBUG - _debug_cnt--; -#endif -#ifdef _WIN32 - LeaveCriticalSection(&m_cs); -#else -#ifdef WDL_MAC_USE_CARBON_CRITSEC - MPExitCriticalRegion(m_cr); -#else - if (--m_lockcnt < 0) - { - m_ownerthread=0; - pthread_mutex_unlock(&m_mutex); - } -#endif -#endif - } - -#ifdef _DEBUG - int _debug_cnt; -#endif - - private: -#ifdef _WIN32 - CRITICAL_SECTION m_cs; -#else -#ifdef WDL_MAC_USE_CARBON_CRITSEC - MPCriticalRegionID m_cr; -#else - pthread_mutex_t m_mutex; - pthread_t m_ownerthread; - int m_lockcnt; -#endif -#endif - -} WDL_FIXALIGN; - -class WDL_MutexLock { -public: - WDL_MutexLock(WDL_Mutex *m) : m_m(m) { if (m) m->Enter(); } - ~WDL_MutexLock() { if (m_m) m_m->Leave(); } -private: - WDL_Mutex *m_m; -} WDL_FIXALIGN; - -class WDL_SharedMutex -{ - public: - WDL_SharedMutex() { m_sharedcnt=0; } - ~WDL_SharedMutex() { } - - void LockExclusive() // note: the calling thread must NOT have any shared locks, or deadlock WILL occur - { - m_mutex.Enter(); -#ifdef _WIN32 - while (m_sharedcnt>0) Sleep(1); -#else - while (m_sharedcnt>0) usleep(100); -#endif - } - void UnlockExclusive() { m_mutex.Leave(); } - - void LockShared() - { - m_mutex.Enter(); -#ifdef _WIN32 - InterlockedIncrement(&m_sharedcnt); -#elif defined (__APPLE__) - OSAtomicIncrement32(&m_sharedcnt); -#else - m_cntmutex.Enter(); - m_sharedcnt++; - m_cntmutex.Leave(); -#endif - - m_mutex.Leave(); - } - void UnlockShared() - { -#ifdef _WIN32 - InterlockedDecrement(&m_sharedcnt); -#elif defined(__APPLE__) - OSAtomicDecrement32(&m_sharedcnt); -#else - m_cntmutex.Enter(); - m_sharedcnt--; - m_cntmutex.Leave(); -#endif - } - - private: - WDL_Mutex m_mutex; -#ifdef _WIN32 - LONG m_sharedcnt; -#elif defined(__APPLE__) - int32_t m_sharedcnt; -#else - WDL_Mutex m_cntmutex; - int m_sharedcnt; -#endif -} WDL_FIXALIGN; - - - -class WDL_MutexLockShared { - public: - WDL_MutexLockShared(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockShared(); } - ~WDL_MutexLockShared() { if (m_m) m_m->UnlockShared(); } - private: - WDL_SharedMutex *m_m; -} WDL_FIXALIGN; - -class WDL_MutexLockExclusive { - public: - WDL_MutexLockExclusive(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockExclusive(); } - ~WDL_MutexLockExclusive() { if (m_m) m_m->UnlockExclusive(); } - private: - WDL_SharedMutex *m_m; -} WDL_FIXALIGN; - - -#endif diff --git a/WDL/nsv/nsvbs.h b/WDL/nsv/nsvbs.h deleted file mode 100644 index fcb0009a..00000000 --- a/WDL/nsv/nsvbs.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - LICENSE - ------- -Copyright 2005 Nullsoft, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of Nullsoft nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ -/* -** nsvbs.h - NSV basic inline bitstream classes -** -** -** Note: these bitstream classes encode/decode everything in LSB. -** bits are stored from the lowest bit to the highest bit. -** putbits(4,0xE) will result in getbits(1)=0, getbits(1)=1, -** getbits(1)=1, getbits(1)=1 -** or of course, getbits(4) == 0xE :) -*/ - -#ifndef _NSVBS_H_ -#define _NSVBS_H_ - -#include -#include - -class nsv_GrowBuf -{ - public: - nsv_GrowBuf() { m_alloc=m_used=0; m_s=NULL; } - ~nsv_GrowBuf() { if (m_s) free(m_s); m_s=0; } - - int add(void *data, int len) - { - if (len<=0) return 0; - resize(m_used+len); - if (m_s) memcpy((char*)m_s+m_used-len,data,len); - return m_used-len; - } - - void set(void *data, int len) - { - resize(len); - if (m_s) memcpy((char*)m_s,data,len); - } - - void resize(int newlen) - { - m_used=newlen; - if (newlen > m_alloc) - { - void *ne; - m_alloc = newlen*2; - if (m_alloc < 1024) m_alloc =1024; - ne = realloc(m_s, m_alloc); - if (!ne) - { - ne=malloc(m_alloc); - if (ne) memcpy(ne,m_s,m_used); - free(m_s); - } - m_s=ne; - } - } - - int getlen() { return m_used; } - void *get() { return m_s; } - - private: - void *m_s; - int m_alloc; - int m_used; - -}; - - -class nsv_OutBS -{ -public: - nsv_OutBS() { m_used = 0; m_curb=0; } - ~nsv_OutBS() { } - - void putbits(int nbits, unsigned int value) - { - while (nbits-- > 0) - { - m_curb|=(value&1)<<(m_used&7); - if (!((++m_used)&7)) - { - m_bits.add(&m_curb,1); - m_curb=0; - } - value>>=1; - } - } - - // lets you put in any amount of data, but does not preserve endianness. - void putdata(int nbits, void *data) - { - unsigned char *c=(unsigned char *)data; - if (!(m_used&7) && nbits >= 8) - { - m_bits.add(c,nbits/8); - c+=nbits/8; - m_used+=nbits&~7; - nbits&=7; - } - while (nbits > 0) - { - int tb=nbits; - if (tb > 8) tb=8; - putbits(tb,*c++); - nbits-=tb; - } - } - - int getlen() { return m_used; } // in bits - - void *get(int *len) // len is in bytes, forces to byte aligned. - { - if (m_used&7) - { - m_bits.add(&m_curb,1); - m_used=(m_used+7)&~7; - m_curb=0; - } - *len=m_used/8; - return m_bits.get(); - } - - void clear() - { - m_used=0; - m_curb=0; - m_bits.resize(0); - } - -private: - nsv_GrowBuf m_bits; - int m_used; // bits - unsigned char m_curb; -}; - -class nsv_InBS { -public: - nsv_InBS() { m_bitpos=0; m_eof=0; } - ~nsv_InBS() { } - - void clear() - { - m_eof=0; - m_bitpos=0; - m_bits.resize(0); - } - - void add(void *data, int len) - { - m_bits.add(data,len); - m_eof=0; - } - - void addbyte(unsigned char byte) - { - add(&byte,1); - } - - void addint(unsigned int dword) - { - addbyte(dword&0xff); - addbyte((dword>>8)&0xff); - addbyte((dword>>16)&0xff); - addbyte((dword>>24)&0xff); - } - - void compact() - { - int bytepos=m_bitpos/8; - if (bytepos) - { - unsigned char *t=(unsigned char *)m_bits.get(); - int l=m_bits.getlen()-bytepos; - if (t) memcpy(t,t+bytepos,l); - m_bits.resize(l); - m_bitpos&=7; - } - m_eof=0; - } - - - void seek(int nbits) { m_bitpos+=nbits; if (m_bitpos < 0) m_bitpos=0; m_eof=m_bits.getlen()*8 < m_bitpos; } - void rewind() { m_bitpos=0; m_eof=0; } - int eof() { return m_eof; } - int avail() { if (m_eof) return 0; return m_bits.getlen()*8 - m_bitpos; } - - unsigned int getbits(int nbits) - { - unsigned int ret=0; - if (nbits <= 0) return ret; - unsigned char *t=(unsigned char *)m_bits.get(); - - if (!t || m_bits.getlen()*8 < m_bitpos+nbits) m_eof=1; - else - { - int sh=0; - t+=m_bitpos/8; - for (sh = 0; sh < nbits; sh ++) - { - ret|=((*t>>(m_bitpos&7))&1) << sh; - if (!((++m_bitpos)&7)) t++; - } - } - return ret; - } - - int getdata(int nbits, void *data) - { - unsigned char *t=(unsigned char *)data; - if (m_bits.getlen()*8 < m_bitpos+nbits) return 1; - if (!(m_bitpos&7) && nbits >= 8) - { - char *bitptr=(char*)m_bits.get(); - bitptr+=(m_bitpos/8); - if (bitptr) memcpy(t,bitptr,nbits/8); - m_bitpos+=nbits&~7; - - t+=nbits/8; - nbits&=7; - } - while (nbits > 0) - { - int nb=nbits; - if (nb > 8) nb=8; - *t++=getbits(nb); - nbits-=nb; - } - return 0; - } - - void *getcurbyteptr() - { - char *t=(char*)m_bits.get(); - if (t) return (void *)(t+(m_bitpos/8)); - return 0; - } - -private: - nsv_GrowBuf m_bits; - int m_bitpos; - int m_eof; -}; - -#endif//_NSVBS_H_ diff --git a/WDL/nsv/nsvlib.cpp b/WDL/nsv/nsvlib.cpp deleted file mode 100644 index 2f81d2de..00000000 --- a/WDL/nsv/nsvlib.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/* - LICENSE - ------- -Copyright 2005 Nullsoft, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of Nullsoft nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ -/* -** nsvlib.cpp - NSV file/bitstream reading/writing code -** -*/ - -#include -#include -#include - -#include "nsvlib.h" - -#define NSV_HDR_DWORD (NSV_MAKETYPE('N','S','V','f')) - -#define NSV_SYNC_HEADERLEN_BITS 192 -#define NSV_SYNC_DWORD (NSV_MAKETYPE('N','S','V','s')) -#define NSV_NONSYNC_HEADERLEN_BITS 56 -#define NSV_NONSYNC_WORD 0xBEEF - -#define NSV_INVALID_SYNC_OFFSET 0x80000000 - -/* - NSV sync packet header - 32 bits: NSV_SYNC_DWORD - 32 bits: video format - 32 bits: audio format - 16 bits: width - 16 bits: height - 8 bits: framerate (see getfrate/setfrate) - - - 16 bits: audio/video sync offset - -or - - NSV nonsync packet header - 16 bits: NSV_NONSYNC_WORD - -then - -4 bits: # aux data channels present (max 15) -20 bits: video data + aux channels length -16 bits: audio data length - --------------------------------- -sync: - 192 bit header, - 136 bits are invariant -nonsync: - 56 bit header - 16 bits are invariant - -*/ - - - - -static int is_type_char_valid(int c) -{ - c&=0xff; - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == ' ' || c == '-' || - c == '.' || c == '_'; -} - -static int is_type_valid(unsigned int t) -{ - return (t&0xff) != ' ' && - is_type_char_valid(t>>24) && - is_type_char_valid(t>>16) && - is_type_char_valid(t>>8) && - is_type_char_valid(t); -} - - -void nsv_type_to_string(unsigned int t, char *out) -{ - if (is_type_valid(t)) - { - out[0]=(t)&0xff; - out[1]=(t>>8)&0xff; - out[2]=(t>>16)&0xff; - out[3]=(t>>24)&0xff; - out[4]=0; - int x=3; - while (out[x]==' ' && x > 0) out[x--]=0; - } - else *out=0; -} - -unsigned int nsv_string_to_type(char *in) -{ - int n; - unsigned int ret=*in; - if (*in == ' ' || !is_type_char_valid(*in)) return 0; - in++; - for (n = 0; n < 3; n ++) - { - if (!is_type_char_valid(*in)) break; - ret|=(*in<<(8+8*n)); - in++; - } - if (*in) return 0; - return ret; -} - -// frate is specified -// XYYYYYZZ -// if !X, framerate is YYYYYZZ (1-127) -// otherwise: -// ZZ indexes base -// YYYYY is scale (0-32). -// if YYYYY < 16, then scale = 1/(YYYY+1) -// otherwise scale = YYYYY-15 - - -static double frate2double(unsigned char fr) -{ - static double fratetab[]= - { - 30.0, - 30.0*1000.0/1001.0, - 25.0, - 24.0*1000.0/1001.0, - }; - if (!(fr&0x80)) return (double)fr; - - double sc; - int d=(fr&0x7f)>>2; - if (d < 16) sc=1.0/(double)(d+1); - else sc=d-15; - - return fratetab[fr&3]*sc; -} - - - -static unsigned char double2frate(double fr) -{ - int best=0; - double best_v=1000000.0; - int x; - for (x = 0; x < 256; x ++) - { - double this_v=(fr-frate2double(x)); - - if (this_v<0) this_v=-this_v; - if (this_v < best_v) - { - best_v=this_v; - best=x; - } - } - return (unsigned char) best; -} - - - -nsv_Packeter::nsv_Packeter() -{ - vidfmt=audfmt=0; - width=height=0; - framerate_idx=0; - framerate=0.0; - syncoffset_cur=0; - video=NULL; - audio=NULL; - video_len=0; - audio_len=0; - aux_used=0; -} - -void nsv_Packeter::setVidFmt(unsigned int vfmt, unsigned int w, unsigned int h, double frt) -{ - vidfmt=vfmt; - width=w; - height=h; - framerate=frt; - framerate_idx=double2frate(frt); -} - -nsv_Packeter::~nsv_Packeter() -{ -} - -int nsv_Packeter::packet(nsv_OutBS &bs) -{ - int total_auxlen=0; - int x; - if (width >= (1<<16) || height >= (1<<16) || - !framerate_idx || framerate_idx > 255 || - !is_type_valid(audfmt) || - !is_type_valid(vidfmt) || - video_len > NSV_MAX_VIDEO_LEN || - audio_len > NSV_MAX_AUDIO_LEN || - aux_used > NSV_MAX_AUXSTREAMS || - aux_used < 0 - ) return -1; - - for (x = 0; x < aux_used; x ++) - { - if (aux_len[x] > NSV_MAX_AUX_LEN) return -1; - total_auxlen+=aux_len[x]+6; - } - - if (is_sync_frame) - { - bs.putbits(32,NSV_SYNC_DWORD); - bs.putbits(32,vidfmt); - bs.putbits(32,audfmt); - bs.putbits(16,width); - bs.putbits(16,height); - bs.putbits(8 ,framerate_idx); - bs.putbits(16,syncoffset_cur); - } - else - { - bs.putbits(16,NSV_NONSYNC_WORD); - } - - bs.putbits(4,aux_used); // no aux data channels for our streams yet - bs.putbits(20,video_len+total_auxlen); - bs.putbits(16,audio_len); - - for (x = 0; x < aux_used; x ++) - { - bs.putbits(16,aux_len[x]); // length of 0 for aux channels - bs.putbits(32,aux_types[x]); - if (aux_len[x]) bs.putdata(aux_len[x]*8,aux[x]); - } - - if (video_len) bs.putdata(video_len*8,video); - if (audio_len) bs.putdata(audio_len*8,audio); - - return 0; -} - - -void nsv_Unpacketer::reset(int full) -{ - synched=0; - is_sync_frame=0; - syncoffset_cur=0; - syncoffset=NSV_INVALID_SYNC_OFFSET; - - if (full) - { - m_auxbs=NULL; - m_audiobs=NULL; - m_videobs=NULL; - m_eof=0; - vidfmt=0; - audfmt=0; - valid=0; - width=0; - height=0; - framerate=0.0; - framerate_idx=0; - } -} - - -// returns 0 on success, >0 on needs (at least X bytes) more data, -// -1 on error (no header found in block) -int nsv_Unpacketer::unpacket(nsv_InBS &bs) -{ - int gotframe=0; - unsigned int num_aux=0; - unsigned int vl=0; - unsigned int al=0; - - while (bs.avail()>=NSV_NONSYNC_HEADERLEN_BITS) - { - if (valid && synched) - { - if (bs.avail() < NSV_NONSYNC_HEADERLEN_BITS) - return m_eof?-1:(NSV_NONSYNC_HEADERLEN_BITS-bs.avail())/8; - - unsigned int d=bs.getbits(16); - if (d == NSV_NONSYNC_WORD) - { - num_aux=bs.getbits(4); - vl=bs.getbits(20); - al=bs.getbits(16); - if (al >= NSV_MAX_AUDIO_LEN || - vl >= (NSV_MAX_VIDEO_LEN+num_aux*(NSV_MAX_AUX_LEN+6))) - { - bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); - } - else - { - if ((unsigned int)bs.avail() < 8*(vl+al)+(m_eof?0:32)) - { - int l=(al+vl+32/8)-bs.avail()/8; - bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); - return m_eof?-1:l; - } - - if ((unsigned int)bs.avail() >= 8*(vl+al)+32) - { - bs.seek(8*(vl+al)); - unsigned int a32=bs.getbits(32); - bs.seek(-32); - unsigned int a16=bs.getbits(16); - bs.seek(-16); - bs.seek(-8*(vl+al)); - if (a16 != NSV_NONSYNC_WORD && a32 != NSV_SYNC_DWORD) - { - bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); - } - else gotframe=NSV_NONSYNC_HEADERLEN_BITS; - } - else gotframe=NSV_NONSYNC_HEADERLEN_BITS; - } - } - else bs.seek(-16); - } // inf.valid && inf.synched - - // gotframe is set if we successfully got a nonsync frame, otherwise - // let's see if we can't interpret this as a sync frame - - if (!gotframe) - { - if (bs.avail() < NSV_SYNC_HEADERLEN_BITS) - return m_eof?-1:(NSV_SYNC_HEADERLEN_BITS-bs.avail())/8; - unsigned int d=bs.getbits(32); - if (d != NSV_SYNC_DWORD) - { - bs.seek(8-32); // seek back 3 bytes - synched=0; - continue; - } - unsigned int vfmt=bs.getbits(32); - unsigned int afmt=bs.getbits(32); - unsigned int w=bs.getbits(16); - unsigned int h=bs.getbits(16); - unsigned char frt=bs.getbits(8); - unsigned int so=bs.getbits(16); - - num_aux=bs.getbits(4); - vl=bs.getbits(20); - al=bs.getbits(16); - - if (al >= NSV_MAX_AUDIO_LEN || - vl >= (NSV_MAX_VIDEO_LEN+num_aux*(NSV_MAX_AUX_LEN+6)) || - !frt || !is_type_valid(vfmt) || !is_type_valid(afmt) || - (valid && - (width != w || height != h || - vidfmt != vfmt || audfmt != afmt || framerate_idx != frt))) - { // frame is definately not valid - bs.seek(8-NSV_SYNC_HEADERLEN_BITS); // seek back what we just read - synched=0; - continue; - } - - if ((unsigned int)bs.avail() < (al+vl)*8+((m_eof||(valid&&synched))?0:32)) - { - int l=(al+vl)*8+NSV_SYNC_HEADERLEN_BITS-bs.avail(); - bs.seek(-NSV_SYNC_HEADERLEN_BITS); - return m_eof?-1:(l/8); - } - - if (valid && synched) - { - gotframe=NSV_SYNC_HEADERLEN_BITS; - } - else // we need to do more robust sync - { - int sk=(al+vl)*8; - bs.seek(sk); - unsigned int a16=bs.getbits(16); - bs.seek(-16); - unsigned int a32=bs.getbits(32); - bs.seek(-32); - if (a16 == NSV_NONSYNC_WORD) - { - sk+=16+4+20+16; - bs.seek(16+4); //skip hdr + aux bits - unsigned int _vl=bs.getbits(20); - unsigned int _al=bs.getbits(16); - if ((unsigned int)bs.avail() < (_vl+_al)*8 + 32) - { - int l=(_al+_vl+32)-bs.avail()/8; - bs.seek(-NSV_SYNC_HEADERLEN_BITS-sk); - return m_eof?-1:l; - } - bs.seek((_vl+_al)*8); - sk+=(_vl+_al)*8; - unsigned int a16=bs.getbits(16); - bs.seek(-16); - unsigned int a32=bs.getbits(32); - bs.seek(-32); - bs.seek(-sk); - if (a16 == NSV_NONSYNC_WORD || a32 == NSV_SYNC_DWORD) - gotframe=NSV_SYNC_HEADERLEN_BITS; - } - else if (a32 == NSV_SYNC_DWORD) - { - - sk+=32+32+32+16+16+8; - - bs.seek(32); - unsigned int _vfmt=bs.getbits(32); - unsigned int _afmt=bs.getbits(32); - unsigned int _w=bs.getbits(16); - unsigned int _h=bs.getbits(16); - unsigned char _frt=bs.getbits(8); - bs.seek(-sk); - - if (_vfmt==vfmt && _afmt==afmt && _w==w && _h==h && _frt==frt) // matches - { - gotframe=NSV_SYNC_HEADERLEN_BITS; - } - } - } - if (!gotframe) - { - synched=0; - bs.seek(8-NSV_SYNC_HEADERLEN_BITS); - } - else - { - if (so & 0x8000) so|=0xFFFF0000; - syncoffset_cur=so; - if (!valid || (unsigned int)syncoffset == NSV_INVALID_SYNC_OFFSET) syncoffset=so; - if (!valid) framerate=frate2double(frt); - framerate_idx=frt; - width=w; - height=h; - audfmt=afmt; - vidfmt=vfmt; - valid=1; - synched=1; - } - } - - if (gotframe) - { - is_sync_frame = (gotframe == NSV_SYNC_HEADERLEN_BITS); - // read aux channels - int rd=gotframe; - unsigned int x; - for (x = 0; x < num_aux; x ++) - { - unsigned int l=bs.getbits(16); - unsigned int fmt=bs.getbits(32); - vl -= 4+2; - rd += 16+32; - - if (l > NSV_MAX_AUX_LEN) break; - - if (m_auxbs) - { - m_auxbs->addint(l); - m_auxbs->addint(fmt); - m_auxbs->add(bs.getcurbyteptr(),l); - } - bs.seek(l*8); // toss aux - - vl-=l; - rd+=l*8; - - if (vl<0) break; // invalid frame (aux channels add up to more than video) - } - if (x < num_aux) // oh shit, invalid frame - { - synched=0; - bs.seek(8-rd); - gotframe=0; - continue; - } - - if (m_videobs) - { - m_videobs->addint(vl); - m_videobs->add(bs.getcurbyteptr(),vl); - } - bs.seek(vl*8); - - if (m_audiobs) - { - m_audiobs->addint(al); - m_audiobs->add(bs.getcurbyteptr(),al); - } - bs.seek(al*8); - - return 0; - } - } // while - return m_eof?-1:(NSV_NONSYNC_HEADERLEN_BITS-bs.avail())/8; -} - - - - - - - - - -/* NSV file header -4: NSV_HDR_DWORD -4: length of header in bytes - -- may not be 0 or 0xFFFFFFFF. :) -4: length of file, in bytes (including header - if this is 0 we are invalid) - -- can be 0xFFFFFFFF which means unknown length -4: length of file, in milliseconds (max file length, 24 days or so) - -- can be 0xFFFFFFFF which means unknown length -4: metadata length -4: number of TOC entries allocated -4: number of TOC entries used -mdlen: metadata -TOC_alloc*4:offset in file at time t. -*/ - -void nsv_writeheader(nsv_OutBS &bs, nsv_fileHeader *hdr, unsigned int padto) -{ - if (hdr->toc_alloc < hdr->toc_size) - hdr->toc_alloc=hdr->toc_size; - - if (hdr->toc_ex && hdr->toc_alloc <= hdr->toc_size*2) - hdr->toc_alloc=hdr->toc_size*2+1; - - hdr->header_size = 4+4+4+4+4+hdr->metadata_len+4+4+4*hdr->toc_alloc; - - bs.putbits(32,NSV_HDR_DWORD); - bs.putbits(32,hdr->header_size>padto?hdr->header_size:padto); - if (hdr->file_lenbytes == 0xFFFFFFFF) bs.putbits(32,hdr->file_lenbytes); - else bs.putbits(32,hdr->file_lenbytes+(hdr->header_size>padto?hdr->header_size:padto)); - bs.putbits(32,hdr->file_lenms); - bs.putbits(32,hdr->metadata_len); - bs.putbits(32,hdr->toc_alloc); - bs.putbits(32,hdr->toc_size); - bs.putdata(hdr->metadata_len*8,hdr->metadata); - - unsigned int numtoc=hdr->toc_alloc; - unsigned int numtocused=hdr->toc_size; - unsigned int *toc=hdr->toc; - unsigned int *toc_ex=hdr->toc_ex; - unsigned int numtocused2=(toc_ex && hdr->toc_alloc > hdr->toc_size*2) ? (hdr->toc_size + 1): 0; - - while (numtoc--) - { - if (!numtocused) - { - if (numtocused2) - { - if (--numtocused2 == hdr->toc_size) // signal extended TOC :) - bs.putbits(32,NSV_MAKETYPE('T','O','C','2')); - else - bs.putbits(32,*toc_ex++); - } - else // extra (unused by this implementation but could be used someday so we fill it with 0xFF) space - bs.putbits(32,~0); - } - else if (toc) - { - bs.putbits(32,*toc++); - numtocused--; - } - else bs.putbits(32,0); - } - - unsigned int x; - for (x = hdr->header_size; x < padto; x ++) bs.putbits(8,0); -} - - -int nsv_readheader(nsv_InBS &bs, nsv_fileHeader *hdr) -{ - int s=0; - hdr->metadata=(void*)NULL; - hdr->toc=(unsigned int *)NULL; - hdr->toc_ex=(unsigned int *)NULL; - hdr->header_size=0; - hdr->file_lenbytes=~0; - hdr->file_lenms=~0; - hdr->toc_alloc=0; - hdr->toc_size=0; - hdr->metadata_len=0; - - if (bs.avail()<64) { - return 8-bs.avail()/8; - } - s+=32; - if (bs.getbits(32) != NSV_HDR_DWORD) - { - bs.seek(-s); - return -1; - } - s+=32; - unsigned int headersize=bs.getbits(32); - - if ((unsigned int)bs.avail() < (headersize-4)*8) - { - int l=headersize-4-bs.avail()/8; - bs.seek(-s); - return l; - } - - s+=32; - unsigned int lenbytes=bs.getbits(32); - s+=32; - unsigned int lenms=bs.getbits(32); - s+=32; - unsigned int metadatalen=bs.getbits(32); - s+=32; - unsigned int tocalloc=bs.getbits(32); - s+=32; - unsigned int tocsize=bs.getbits(32); - - if (tocalloc < tocsize || lenbytes < headersize || tocalloc + metadatalen + s/8 > headersize) - { - bs.seek(-s); - return -1; - } - - void *metadata=NULL; - - if (metadatalen) - { - metadata=malloc(metadatalen+1); - if (!metadata) - { - bs.seek(-s); - return -1; - } - s+=metadatalen*8; - bs.getdata(metadatalen*8,metadata); - ((char*)metadata)[metadatalen]=0; - } - - unsigned int *toc=NULL; - unsigned int *toc_ex=NULL; - - if (tocalloc) - { - toc=(unsigned int *)malloc(tocsize * 4 * 2); - if (!toc) - { - free(metadata); - bs.seek(-s); - return -1; - } - unsigned int x; - int bitsread=0; - for (x = 0; x < tocsize; x ++) { toc[x] = bs.getbits(32); bitsread += 32; } - - if (tocalloc > tocsize*2) - { - bitsread += 32; - if (bs.getbits(32) == NSV_MAKETYPE('T','O','C','2')) - { - toc_ex=toc + tocsize; - for (x = 0; x < tocsize; x ++) { toc_ex[x] = bs.getbits(32); bitsread += 32; } - } - } - bs.seek((tocalloc-tocsize)*32 - bitsread); - s+=tocalloc*32; - } - - hdr->header_size=headersize; - if (lenbytes == 0xFFFFFFFF) hdr->file_lenbytes=lenbytes; - else hdr->file_lenbytes=lenbytes-headersize; - hdr->file_lenms=lenms; - hdr->metadata=metadata; - hdr->metadata_len=metadatalen; - hdr->toc=toc; - hdr->toc_ex=toc_ex; - hdr->toc_alloc=tocalloc; - hdr->toc_size=tocsize; - - return 0; -} - -char *nsv_getmetadata(void *metadata, char *name) -{ - if (!metadata) return NULL; - char *p=(char*)metadata; - int ln=strlen(name); - for (;;) - { - while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; - if (!*p) break; - if (!strnicmp(p,name,ln) && p[ln]=='=' && p[ln+1] && p[ln+2]) - { - int cnt=0; - char *np=p+ln+1; - char c=*np++; - while (np[cnt] && np[cnt] != c) cnt++; - - char *s=(char*)malloc(cnt+1); - if (!s) return NULL; - memcpy(s,np,cnt); - s[cnt]=0; - return s; - } - - // advance to next item - while (*p && *p != '=') p++; - if (!*p++) break; - if (!*p) break; - char c=*p++; - while (*p && *p != c) p++; - if (*p) p++; - } - return NULL; -} diff --git a/WDL/nsv/nsvlib.h b/WDL/nsv/nsvlib.h deleted file mode 100644 index f8dd5b0c..00000000 --- a/WDL/nsv/nsvlib.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - LICENSE - ------- -Copyright 2005 Nullsoft, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of Nullsoft nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ -/* -** nsvlib.h - NSV file/bitstream reading/writing interface -** -*/ - -#ifndef _NSVLIB_H_ -#define _NSVLIB_H_ - -/********************************************************************* -** bitstream classes -*/ - -#include "nsvbs.h" - - -/********************************************************************* -** NSV packeting limits -*/ -#define NSV_MAX_AUDIO_LEN 0x8000 // 32kb -#define NSV_MAX_VIDEO_LEN 0x80000 // 512kb -#define NSV_MAX_AUX_LEN 0x8000 // 32kb for each aux stream -#define NSV_MAX_AUXSTREAMS 15 // 15 aux streams maximum - - -/********************************************************************* -** Constants for setting certain metadata items using addHdrMetaData() -*/ -#define METADATANAME_AUTHOR "Author" -#define METADATANAME_TITLE "Title" -#define METADATANAME_COPYRIGHT "Copyright" -#define METADATANAME_COMMENT "Comment" -#define METADATANAME_PROFILE "Profile" -#define METADATANAME_FILEID "File ID" - -/********************************************************************* -** NSV type utility functions/macros -*/ - -/* -** Use NSV_MAKETYPE() to quickly make NSV audio/video/aux types. -** ex: NSV_MAKETYPE('R','G','B','A') -*/ -#define NSV_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24)) - -/* -** These functions convert types to and from strings. -*/ - -/* nsv_type_to_string() converts an NSV type to a string. - * out must be at least 5 bytes long. If 't' is not a valid type, - * then out will be set to an empty string - * ex: - * char out[5]; - * nsv_type_to_string(NSV_MAKETYPE('R','G','B','A'),out); - * strcmp(out,"RGBA") == 0 - */ -void nsv_type_to_string(unsigned int t, char *out); - -/* nsv_string_to_type() converts a string to an NSV type. - * Returns 0 if the type is not valid. - * ex: nsv_string_to_type("RGBA") == NSV_MAKETYPE('R','G','B','A') - */ -unsigned int nsv_string_to_type(char *in); - - -/********************************************************************* -** NSV bitstream packeting/unpacketing classes -*/ - - -/* nsv_Packeter is used to packet audio/video/auxiliary data into - * a bitstream. - * - * ex: - * nsv_Packeter p; - * nsv_OutBS bs; - * p.setVidFmt(NSV_MAKETYPE('R','G','B','A'),320,240,30.0); - * p.setAudFmt(NSV_MAKETYPE('P','C','M',' ')); - * for (;;) { - * doEncodeAudioAndVideo(); - * p.setSyncFrame(is_keyframe); - * p.setSyncOffset(av_sync_offset); - * p.setAudio(audio_data,audio_len); - * p.setVideo(video_data,video_len); - * p.clearAuxChannels(); // you can add aux channels if you want - * if (p.packet(bs)) error(); - * int outbuflen; - * void *outbuf=bs.get(&outbuflen); - * fwrite(outbuf,outbuflen,1,fp); // write output - * bs.clear(); // clear bitstream - * } - * - */ - -class nsv_Packeter { - public: - nsv_Packeter(); - ~nsv_Packeter(); - - // init (per file) calls - void setVidFmt(unsigned int vfmt, unsigned int w, unsigned int h, double frt); - void setAudFmt(unsigned int afmt) { audfmt=afmt; } - - // per frame calls - void setSyncFrame(int is_syncframe) { is_sync_frame=is_syncframe; } - void setSyncOffset(int syncoffs) { syncoffset_cur=syncoffs; } - void setAudio(void *a, int a_len) { audio=a; audio_len=a_len; } - void setVideo(void *v, int v_len) { video=v; video_len=v_len; } - int addAuxChannel(unsigned int fmt, void *data, int data_len) // 0 on success - { - if (aux_used >= NSV_MAX_AUXSTREAMS) return -1; - aux[aux_used]=data; - aux_len[aux_used]=data_len; - aux_types[aux_used]=fmt; - aux_used++; - return 0; - } - void clearAuxChannels() { aux_used=0; } - - int packet(nsv_OutBS &bs); // returns 0 on success - - // some utility getting functions - unsigned int getAudFmt() { return audfmt; } - unsigned int getVidFmt() { return vidfmt; } - unsigned int getWidth() { return width; } - unsigned int getHeight() { return height; } - double getFrameRate() { return framerate; } - - private: - unsigned char framerate_idx; - unsigned int vidfmt; - unsigned int audfmt; - unsigned int width; - unsigned int height; - double framerate; - int syncoffset_cur; - - int aux_used; - void *aux[NSV_MAX_AUXSTREAMS]; - int aux_len[NSV_MAX_AUXSTREAMS]; - unsigned int aux_types[NSV_MAX_AUXSTREAMS]; - int is_sync_frame; - void *audio; - int audio_len; - void *video; - int video_len; -}; - - -/* nsv_Unpacketer is used to unpacket a bitstream into audio/video/auxiliary data - * to decode, use an nsv_InBS object with data, and call unpacket(). - * ex: - * nsv_Unpacketer up; - * nsv_InBS in; - * nsv_InBS videoout, audioout; - * up.setVideoOut(&videoout); - * up.setAudioOut(&audioout); - * for (;;) { - * int ret=up.unpacket(in); - * if (ret < 0) break; // eof - * if (ret > 0) add_data_to_bitstream(&in,ret); - * if (!ret) { // got frame - * int vl=videoout.getbits(32); - * int al=videoout.getbits(32); - * char *vd=(char*)videoout.getcurbyteptr(); - * char *ad=(char*)audioout.getcurbyteptr(); - * doDecode(vd,vl,ad,al); - * videoout.seek(vl*8); - * audioout.seek(al*8); - * videoout.compact(); // free memory up - * audioout.compact(); // free memory up - * in.compact(); // free memory up - * } - * } - */ - -class nsv_Unpacketer { - public: - nsv_Unpacketer() { reset(); } - ~nsv_Unpacketer() { } - - void reset(int full=1); // if full, full reset is done. - // if not, then it is a partial reset (ie for seeking) - - // when EOF is set, the unpacketer will fail instead of requesting more data at the - // end; it will also not require that the next frame be available for sync - // (normally it looks ahead to verify data) - void setEof(int eof=1) { m_eof=eof; } - int getEof() { return m_eof; } - - // use these to set where the unpacketer writes the output of each stream - // set to NULL to ignore output of that stream - - void setAudioOut(nsv_InBS *output=NULL) { m_audiobs=output; } - // the format of the audio data written to the output is: - // 32 bits: length of frame - // ? bytes: audio data - // (to read): - // int l=output->getbits(32); - // decode_audio(output->getcurbyteptr(),l); - // output->seek(l*8); - - - void setVideoOut(nsv_InBS *output=NULL) { m_videobs=output; } - // the format of the video data written to the output is: - // 32 bits: length of frame - // ? bytes: video data - // (to read): - // int l=output->getbits(32); - // decode_video(output->getcurbyteptr(),l); - // output->seek(l*8); - - void setAuxOut(nsv_InBS *output=NULL) { m_auxbs=output; } - // the format of the aux data written to the output is: - // 32 bits: length of frame - // 32 bits: type of aux data - // ? bytes: aux data - // (to read): - // int l=output->getbits(32); - // int type=output->getbits(32); - // decode_aux(output->getcurbyteptr(),l); - // output->seek(l*8); - // aux is different than audio/video in that it includes a 32 bit - // type value that is not included in the length. - - - // returns 0 on success, >0 on needs (at least X bytes) more data, - // -1 on error (eof and no header found) - int unpacket(nsv_InBS &bs); - - - // do we have enough sync to determine formats/widths/heights/framerates - int isValid() { return valid; } - - // are we fully synched? - int isSynched() { return synched; } - - // get sync offset from when we first synched up - signed int getSyncOffset() { return (signed int) syncoffset; } - - // get sync offset from current frame (not usually used) - signed int getCurSyncOffset() { return (signed int) syncoffset_cur; } - - // get video, audio, width, height, framerate formats. - unsigned int getVidFmt() { return vidfmt; } - unsigned int getAudFmt() { return audfmt; } - unsigned int getWidth() { return width; } - unsigned int getHeight() { return height; } - double getFrameRate() { return framerate; } - unsigned char getFrameRateIdx() { return framerate_idx; } - - // is current frame a sync frame? - int isSynchFrame() { return is_sync_frame; } - - private: - nsv_InBS *m_audiobs, *m_videobs, *m_auxbs; - int valid; // contents of stream info are valid for syncing - int synched; // turns off anal packet checking - unsigned int vidfmt; - unsigned int audfmt; - unsigned int width; - unsigned int height; - double framerate; - int is_sync_frame; - unsigned char framerate_idx; - int syncoffset; - int syncoffset_cur; - - int m_eof; -}; - - -/********************************************************************* -** NSV file header reading/writing functions -*/ - - -typedef struct { - // header_size is the size of NSV header. nsv_writeheader() and nsv_readheader() - // will set this automatically - unsigned int header_size; - - // file_lenbytes is the size of the NSV bitstream (not including the header size) - // this can be 0xFFFFFFFF to signify unknown length - unsigned int file_lenbytes; - - // file_lenms is the length of the NSV bitstream in milliseconds. - // this can be 0xFFFFFFFF to signify unknown length - unsigned int file_lenms; - - // metadata_len describes the length of the metadata. - unsigned int metadata_len; - - // toc_alloc describes the allocated length of the TOC (in entries). - // set this to zero to use toc_size (recommended). - unsigned int toc_alloc; - - // toc_size describes the used size of the TOC (in entries) - // set this to zero to disable the TOC. When using toc_ex, - // this must be < toc_alloc/2 (if using nsv_writeheader, and - // toc_size is too big, toc_alloc will be grown automatically. - unsigned int toc_size; - - // buffer which contains the TOC. this will be automatically - // allocated when using nsv_readheader(), but you should allocate - // this yourself when using nsv_writeheader() - unsigned int *toc; - - // if used, contains time pairs (in frames) for the offset. this will be - // automatically allocated when using nsv_readheader(), but you should allocate - // this yourself when using nsv_writeheader() - // DO NOT FREE THIS VALUE IF IT WAS ALLOCATED FROM NSV_READHEADER. :) - // (it is just an extension of toc, which should be freed with free()) - unsigned int *toc_ex; - - // buffer which contains metadata. allocated when using nsv_readheader(), - // but you should allocate this yourself when using nsv_writeheader() - // note that nsv_readheader() will NULL terminate this buffer. - void *metadata; - -} nsv_fileHeader; - -// nsv_writeheader() writes the NSV file header to the bitstream bs. -// the NSV file header will be at LEAST padto bytes long (usually -// you will leave padto to 0) -void nsv_writeheader(nsv_OutBS &bs, nsv_fileHeader *hdr, unsigned int padto); - -// nsv_readheader() reads an NSV file header from a bitstream bs. -// if the return value is less than zero, then there is no NSV -// file header in bs. if the return value is zero, the NSV file -// header was succesfully read. if the return value is positive, -// then at least that many more bytes are needed to decode the -// header. -// ex: -// nsv_InBS bs; -// nsv_fileHeader hdr; -// for (;;) { -// int ret=nsv_readheader(bs,&hdr); -// if (ret<=0) break; -// addBytesToBs(bs,ret); -// } -// if (hdr.header_size) { we_got_valid_header(&hdr); } -// - -int nsv_readheader(nsv_InBS &bs, nsv_fileHeader *hdr); - - -// nsv_getmetadata() retrieves a metadata item from the metadata -// block. if that item is not found, NULL is returned. -// Note that the value returned by nsv_getmetadata() has been -// malloc()'d, and you must free() it when you are done. -// ex: -// char *v=nsv_getmetadata(hdr.metadata,"TITLE"); -// if (v) printf("title=%s\n",v); -// free(v); -// - -char *nsv_getmetadata(void *metadata, char *name); - - -#endif//_NSVLIB_H_ diff --git a/WDL/pcmfmtcvt.h b/WDL/pcmfmtcvt.h deleted file mode 100644 index d498865f..00000000 --- a/WDL/pcmfmtcvt.h +++ /dev/null @@ -1,528 +0,0 @@ -/* - WDL - pcmfmtcvt.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides some simple functions for dealing with PCM audio. - Specifically: - + convert between 16/24/32 bit integer samples and flaots (only really tested on little-endian (i.e. x86) systems) - + mix (and optionally resample, using low quality linear interpolation) a block of floats to another. - -*/ - -#ifndef _PCMFMTCVT_H_ -#define _PCMFMTCVT_H_ - - -#include "wdltypes.h" - -#ifndef PCMFMTCVT_DBL_TYPE -#define PCMFMTCVT_DBL_TYPE double -#endif - -static inline int float2int(PCMFMTCVT_DBL_TYPE d) -{ - return (int) d; -// int tmp; - // __asm__ __volatile__ ("fistpl %0" : "=m" (tmp) : "t" (d) : "st") ; - // return tmp; -} - - -#define float_TO_INT16(out,in) \ - if ((in)<0.0) { if ((in) <= -1.0) (out) = -32768; else (out) = (short) (float2int(((in) * 32768.0)-0.5)); } \ - else { if ((in) >= (32766.5f/32768.0f)) (out) = 32767; else (out) = (short) float2int((in) * 32768.0 + 0.5); } - -#define INT16_TO_float(out,in) { (out) = (float)(((double)in)/32768.0); } - -#define double_TO_INT16(out,in) \ - if ((in)<0.0) { if ((in) <= -1.0) (out) = -32768; else (out) = (short) (float2int(((in) * 32768.0)-0.5)); } \ - else { if ((in) >= (32766.5/32768.0)) (out) = 32767; else (out) = (short) float2int((in) * 32768.0 + 0.5); } - -#define INT16_TO_double(out,in) { (out) = (((PCMFMTCVT_DBL_TYPE)in)/32768.0); } - - -static inline void i32_to_float(int i32, float *p) -{ - *p = (float) ((((double) i32)) * (1.0 / (2147483648.0))); -} - -static inline void float_to_i32(float *vv, int *i32) -{ - float v = *vv; - if (v < 0.0) - { - if (v < -1.0) *i32 = 0x80000000; - else *i32=float2int(v*2147483648.0-0.5); - } - else - { - if (v >= (2147483646.5f/2147483648.0f)) *i32 = 0x7FFFFFFF; - else *i32=float2int(v*2147483648.0+0.5); - } -} - - -static inline void i32_to_double(int i32, PCMFMTCVT_DBL_TYPE *p) -{ - *p = ((((PCMFMTCVT_DBL_TYPE) i32)) * (1.0 / (2147483648.0))); -} - -static inline void double_to_i32(PCMFMTCVT_DBL_TYPE *vv, int *i32) -{ - PCMFMTCVT_DBL_TYPE v = *vv; - if (v < 0.0) - { - if (v < -1.0) *i32 = 0x80000000; - else *i32=float2int(v*2147483648.0-0.5); - } - else - { - if (v >= (2147483646.5/2147483648.0)) *i32 = 0x7FFFFFFF; - else *i32=float2int(v*2147483648.0+0.5); - } -} - - - -static inline void i24_to_float(unsigned char *i24, float *p) -{ - int val=(i24[0]) | (i24[1]<<8) | (i24[2]<<16); - if (val&0x800000) - { - val|=0xFF000000; - *p = (float) ((((double) val)) * (1.0 / (8388608.0))); - } - else - { - val&=0xFFFFFF; - *p = (float) ((((double) val)) * (1.0 / (8388608.0))); - } - -} - -static inline void float_to_i24(float *vv, unsigned char *i24) -{ - float v = *vv; - if (v < 0.0) - { - if (v < -1.0) - { - i24[0]=i24[1]=0x00; - i24[2]=0x80; - } - else - { - int i=float2int(v*8388608.0-0.5); - i24[0]=(i)&0xff; - i24[1]=(i>>8)&0xff; - i24[2]=(i>>16)&0xff; - } - } - else - { - if (v >= (8388606.5f/8388608.0f)) - { - i24[0]=i24[1]=0xff; - i24[2]=0x7f; - } - else - { - - int i=float2int(v*8388608.0+0.5); - i24[0]=(i)&0xff; - i24[1]=(i>>8)&0xff; - i24[2]=(i>>16)&0xff; - } - } -} - - -static inline void i24_to_double(unsigned char *i24, PCMFMTCVT_DBL_TYPE *p) -{ - int val=(i24[0]) | (i24[1]<<8) | (i24[2]<<16); - if (val&0x800000) - { - val|=0xFF000000; - *p = ((((PCMFMTCVT_DBL_TYPE) val)) * (1.0 / (8388608.0))); - } - else - { - val&=0xFFFFFF; - *p = ((((PCMFMTCVT_DBL_TYPE) val)) * (1.0 / (8388608.0))); - } - -} - -static inline void double_to_i24(PCMFMTCVT_DBL_TYPE *vv, unsigned char *i24) -{ - PCMFMTCVT_DBL_TYPE v = *vv; - if (v < 0.0) - { - if (v < -1.0) - { - i24[0]=i24[1]=0x00; - i24[2]=0x80; - } - else - { - int i=float2int(v*8388608.0-0.5); - i24[0]=(i)&0xff; - i24[1]=(i>>8)&0xff; - i24[2]=(i>>16)&0xff; - } - } - else - { - if (v >= (8388606.5/8388608.0)) - { - i24[0]=i24[1]=0xff; - i24[2]=0x7f; - } - else - { - - int i=float2int(v*8388608.0+0.5); - i24[0]=(i)&0xff; - i24[1]=(i>>8)&0xff; - i24[2]=(i>>16)&0xff; - } - } -} - -static void pcmToFloats(void *src, int items, int bps, int src_spacing, float *dest, int dest_spacing) -{ - if (bps == 32) - { - int *i1=(int *)src; - while (items--) - { - i32_to_float(*i1,dest); - i1+=src_spacing; - dest+=dest_spacing; - } - } - else if (bps == 24) - { - unsigned char *i1=(unsigned char *)src; - int adv=3*src_spacing; - while (items--) - { - i24_to_float(i1,dest); - dest+=dest_spacing; - i1+=adv; - } - } - else if (bps == 16) - { - short *i1=(short *)src; - while (items--) - { - INT16_TO_float(*dest,*i1); - i1+=src_spacing; - dest+=dest_spacing; - } - } -} - -static void floatsToPcm(float *src, int src_spacing, int items, void *dest, int bps, int dest_spacing) -{ - if (bps==32) - { - int *o1=(int*)dest; - while (items--) - { - float_to_i32(src,o1); - src+=src_spacing; - o1+=dest_spacing; - } - } - else if (bps == 24) - { - unsigned char *o1=(unsigned char*)dest; - int adv=dest_spacing*3; - while (items--) - { - float_to_i24(src,o1); - src+=src_spacing; - o1+=adv; - } - } - else if (bps==16) - { - short *o1=(short*)dest; - while (items--) - { - float_TO_INT16(*o1,*src); - src+=src_spacing; - o1+=dest_spacing; - } - } -} - - -static void pcmToDoubles(void *src, int items, int bps, int src_spacing, PCMFMTCVT_DBL_TYPE *dest, int dest_spacing, int byteadvancefor24=0) -{ - if (bps == 32) - { - int *i1=(int *)src; - while (items--) - { - i32_to_double(*i1,dest); - i1+=src_spacing; - dest+=dest_spacing; - } - } - else if (bps == 24) - { - unsigned char *i1=(unsigned char *)src; - int adv=3*src_spacing+byteadvancefor24; - while (items--) - { - i24_to_double(i1,dest); - dest+=dest_spacing; - i1+=adv; - } - } - else if (bps == 16) - { - short *i1=(short *)src; - while (items--) - { - INT16_TO_double(*dest,*i1); - i1+=src_spacing; - dest+=dest_spacing; - } - } -} - -static void doublesToPcm(PCMFMTCVT_DBL_TYPE *src, int src_spacing, int items, void *dest, int bps, int dest_spacing, int byteadvancefor24=0) -{ - if (bps==32) - { - int *o1=(int*)dest; - while (items--) - { - double_to_i32(src,o1); - src+=src_spacing; - o1+=dest_spacing; - } - } - else if (bps == 24) - { - unsigned char *o1=(unsigned char*)dest; - int adv=dest_spacing*3+byteadvancefor24; - while (items--) - { - double_to_i24(src,o1); - src+=src_spacing; - o1+=adv; - } - } - else if (bps==16) - { - short *o1=(short*)dest; - while (items--) - { - double_TO_INT16(*o1,*src); - src+=src_spacing; - o1+=dest_spacing; - } - } -} - -static int resampleLengthNeeded(int src_srate, int dest_srate, int dest_len, double *state) -{ - // safety - if (!src_srate) src_srate=48000; - if (!dest_srate) dest_srate=48000; - if (src_srate == dest_srate) return dest_len; - return (int) (((double)src_srate*(double)dest_len/(double)dest_srate)+*state); - -} - -static void mixFloats(float *src, int src_srate, int src_nch, // lengths are sample pairs - float *dest, int dest_srate, int dest_nch, - int dest_len, float vol, float pan, double *state) -{ - // fucko: better resampling, this is shite - int x; - if (pan < -1.0f) pan=-1.0f; - else if (pan > 1.0f) pan=1.0f; - if (vol > 4.0f) vol=4.0f; - if (vol < 0.0f) vol=0.0f; - - if (!src_srate) src_srate=48000; - if (!dest_srate) dest_srate=48000; - - double vol1=vol,vol2=vol; - if (dest_nch == 2) - { - if (pan < 0.0f) vol2 *= 1.0f+pan; - else if (pan > 0.0f) vol1 *= 1.0f-pan; - } - - double rspos=*state; - double drspos = (double)src_srate/(double)dest_srate; - - for (x = 0; x < dest_len; x ++) - { - - double ls; - double rs; - if (src_srate != dest_srate) - { - int ipos = (int)rspos; - double fracpos=rspos-ipos; - if (src_nch == 2) - { - ipos+=ipos; - ls=src[ipos]*(1.0-fracpos) + src[ipos+2]*fracpos; - rs=src[ipos+1]*(1.0-fracpos) + src[ipos+3]*fracpos; - } - else - { - rs=ls=src[ipos]*(1.0-fracpos) + src[ipos+1]*fracpos; - } - } - else - { - if (src_nch == 2) - { - int t=x+x; - ls=src[t]; - rs=src[t+1]; - } - else - { - rs=ls=src[x]; - } - } - - rspos+=drspos; - - ls *= vol1; - if (ls > 1.0) ls=1.0; - else if (ls<-1.0) ls=-1.0; - - if (dest_nch == 2) - { - rs *= vol2; - if (rs > 1.0) rs=1.0; - else if (rs<-1.0) rs=-1.0; - - dest[0]+=(float) ls; - dest[1]+=(float) rs; - dest+=2; - } - else - { - dest[0]+=(float) ls; - dest++; - } - } - *state = rspos - (int)rspos; -} - -static void mixFloatsNIOutput(float *src, int src_srate, int src_nch, // lengths are sample pairs. input is interleaved samples, output not - float **dest, int dest_srate, int dest_nch, - int dest_len, float vol, float pan, double *state) -{ - // fucko: better resampling, this is shite - int x; - if (pan < -1.0f) pan=-1.0f; - else if (pan > 1.0f) pan=1.0f; - if (vol > 4.0f) vol=4.0f; - if (vol < 0.0f) vol=0.0f; - - if (!src_srate) src_srate=48000; - if (!dest_srate) dest_srate=48000; - - double vol1=vol,vol2=vol; - float *dest1=dest[0]; - float *dest2=NULL; - if (dest_nch > 1) - { - dest2=dest[1]; - if (pan < 0.0f) vol2 *= 1.0f+pan; - else if (pan > 0.0f) vol1 *= 1.0f-pan; - } - - - double rspos=*state; - double drspos = 1.0; - if (src_srate != dest_srate) drspos=(double)src_srate/(double)dest_srate; - - for (x = 0; x < dest_len; x ++) - { - double ls,rs; - if (src_srate != dest_srate) - { - int ipos = (int)rspos; - double fracpos=rspos-ipos; - if (src_nch == 2) - { - ipos+=ipos; - ls=src[ipos]*(1.0-fracpos) + src[ipos+2]*fracpos; - rs=src[ipos+1]*(1.0-fracpos) + src[ipos+3]*fracpos; - } - else - { - rs=ls=src[ipos]*(1.0-fracpos) + src[ipos+1]*fracpos; - } - rspos+=drspos; - - } - else - { - if (src_nch == 2) - { - int t=x+x; - ls=src[t]; - rs=src[t+1]; - } - else - { - rs=ls=src[x]; - } - } - - ls *= vol1; - if (ls > 1.0) ls=1.0; - else if (ls<-1.0) ls=-1.0; - - *dest1++ +=(float) ls; - - if (dest_nch > 1) - { - rs *= vol2; - if (rs > 1.0) rs=1.0; - else if (rs<-1.0) rs=-1.0; - - *dest2++ += (float) rs; - } - } - *state = rspos - (int)rspos; -} - - -#endif //_PCMFMTCVT_H_ \ No newline at end of file diff --git a/WDL/plush2/pl_cam.cpp b/WDL/plush2/pl_cam.cpp deleted file mode 100644 index 45996077..00000000 --- a/WDL/plush2/pl_cam.cpp +++ /dev/null @@ -1,748 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -cam.c -Camera and Rendering -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - - -#include "../lice/lice_extended.h" - -#include "../mergesort.h" - -#define MACRO_plMatrixApply(m,x,y,z,outx,outy,outz) \ - ( outx ) = ( x )*( m )[0] + ( y )*( m )[1] + ( z )*( m )[2] + ( m )[3];\ - ( outy ) = ( x )*( m )[4] + ( y )*( m )[5] + ( z )*( m )[6] + ( m )[7];\ - ( outz ) = ( x )*( m )[8] + ( y )*( m )[9] + ( z )*( m )[10] + ( m )[11] - -#define MACRO_plDotProduct(x1,y1,z1,x2,y2,z2) \ - ((( x1 )*( x2 ))+(( y1 )*( y2 ))+(( z1 )*( z2 ))) - -#define MACRO_plNormalizeVector(x,y,z) { \ - double length; \ - length = ( x )*( x )+( y )*( y )+( z )*( z ); \ - if (length > 0.0000000001) { \ - double __l = 1.0/sqrt(length); \ - ( x ) *= __l; \ - ( y ) *= __l; \ - ( z ) *= __l; \ - } \ -} - - -static void _FindNormal(double x2, double x3,double y2, double y3, - double zv, double *res) { - res[0] = zv*(y2-y3); - res[1] = zv*(x3-x2); - res[2] = x2*y3 - y2*x3; -} - - -void pl_Cam::SetTarget(pl_Float x, pl_Float y, pl_Float z) { - double dx, dy, dz; - dx = x - X; - dy = y - Y; - dz = z - Z; - Roll = 0; - if (dz > 0.0001f) { - Pan = (pl_Float) (-atan(dx/dz)*(180.0/PL_PI)); - dz /= cos(Pan*(PL_PI/180.0)); - Pitch = (pl_Float) (atan(dy/dz)*(180.0/PL_PI)); - } else if (dz < -0.0001f) { - Pan = (pl_Float) (180.0-atan(dx/dz)*(180.0/PL_PI)); - dz /= cos((Pan-180.0f)*(PL_PI/180.0)); - Pitch = (pl_Float) (-atan(dy/dz)*(180.0/PL_PI)); - } else { - Pan = 0.0f; - Pitch = -90.0f; - } -} - -void pl_Cam::RecalcFrustum() -{ - int fbw=frameBuffer->getWidth(); - int fbh=frameBuffer->getHeight(); - int cx = CenterX + fbw/2; - int cy = CenterY + fbh/2; - - m_adj_asp = 1.0 / AspectRatio; - m_fovfactor = fbw/tan(plMin(plMax(Fov,1.0),179.0)*(PL_PI/360.0)); - memset(m_clipPlanes,0,sizeof(m_clipPlanes)); - - /* Back */ - m_clipPlanes[0][2] = -1.0; - m_clipPlanes[0][3] = -ClipBack; - - /* Left */ - m_clipPlanes[1][3] = 0.00000001; - if (cx == 0) m_clipPlanes[1][0] = 1.0; - else - { - _FindNormal(-100,-100, - 100, -100, - m_fovfactor*100.0/cx, - m_clipPlanes[1]); - if (cx < 0) - { - m_clipPlanes[1][0] = -m_clipPlanes[1][0]; - m_clipPlanes[1][1] = -m_clipPlanes[1][1]; - m_clipPlanes[1][2] = -m_clipPlanes[1][2]; - } - } - - /* Right */ - m_clipPlanes[2][3] = 0.00000001; - if (fbw == cx) m_clipPlanes[2][0] = -1.0; - else - { - _FindNormal(100,100, - -100, 100, - m_fovfactor*100.0/(fbw-cx), - m_clipPlanes[2]); - if (cx > fbw) - { - m_clipPlanes[2][0] = -m_clipPlanes[2][0]; - m_clipPlanes[2][1] = -m_clipPlanes[2][1]; - m_clipPlanes[2][2] = -m_clipPlanes[2][2]; - } - } - - /* Top */ - m_clipPlanes[3][3] = 0.00000001; - if (cy == 0) m_clipPlanes[3][1] = 1.0; - else - { - _FindNormal(100, -100, - 100, 100, - m_fovfactor*m_adj_asp*-100.0/(cy), - m_clipPlanes[3]); - if (cy < 0) - { - m_clipPlanes[3][0] = -m_clipPlanes[3][0]; - m_clipPlanes[3][1] = -m_clipPlanes[3][1]; - m_clipPlanes[3][2] = -m_clipPlanes[3][2]; - } - } - - /* Bottom */ - m_clipPlanes[4][3] = 0.00000001; - if (cy == fbh) m_clipPlanes[4][1] = -1.0; - else - { - _FindNormal(-100, 100, - -100, -100, - m_fovfactor*m_adj_asp*100.0/(cy-fbh), - m_clipPlanes[4]); - if (cy > fbh) - { - m_clipPlanes[4][0] = -m_clipPlanes[4][0]; - m_clipPlanes[4][1] = -m_clipPlanes[4][1]; - m_clipPlanes[4][2] = -m_clipPlanes[4][2]; - } - } - -} - - - /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ -pl_uInt pl_Cam::_ClipToPlane(pl_uInt numVerts, pl_Float *plane) -{ - pl_uInt i, nextvert, curin, nextin; - double curdot, nextdot, scale; - pl_uInt invert, outvert; - invert = 0; - outvert = 0; - curdot = m_cl[0].newVertices[0].xformedx*plane[0] + - m_cl[0].newVertices[0].xformedy*plane[1] + - m_cl[0].newVertices[0].xformedz*plane[2]; - curin = (curdot >= plane[3]); - - for (i=0 ; i < numVerts; i++) { - nextvert = (i + 1) % numVerts; - if (curin) { - memcpy(&m_cl[1].ShadeInfos[outvert][0],&m_cl[0].ShadeInfos[invert][0],3*sizeof(pl_Float)); - int a; - for(a=0;a= plane[3]); - if (curin != nextin) { - scale = (plane[3] - curdot) / (nextdot - curdot); - m_cl[1].newVertices[outvert].xformedx = (pl_Float) (m_cl[0].newVertices[invert].xformedx + - (m_cl[0].newVertices[nextvert].xformedx - m_cl[0].newVertices[invert].xformedx) - * scale); - m_cl[1].newVertices[outvert].xformedy = (pl_Float) (m_cl[0].newVertices[invert].xformedy + - (m_cl[0].newVertices[nextvert].xformedy - m_cl[0].newVertices[invert].xformedy) - * scale); - m_cl[1].newVertices[outvert].xformedz = (pl_Float) (m_cl[0].newVertices[invert].xformedz + - (m_cl[0].newVertices[nextvert].xformedz - m_cl[0].newVertices[invert].xformedz) - * scale); - - m_cl[1].ShadeInfos[outvert][0] = m_cl[0].ShadeInfos[invert][0] + (m_cl[0].ShadeInfos[nextvert][0] - m_cl[0].ShadeInfos[invert][0]) * scale; - m_cl[1].ShadeInfos[outvert][1] = m_cl[0].ShadeInfos[invert][1] + (m_cl[0].ShadeInfos[nextvert][1] - m_cl[0].ShadeInfos[invert][1]) * scale; - m_cl[1].ShadeInfos[outvert][2] = m_cl[0].ShadeInfos[invert][2] + (m_cl[0].ShadeInfos[nextvert][2] - m_cl[0].ShadeInfos[invert][2]) * scale; - - int a; - for(a=0;agetWidth())/2; - int cy = CenterY + (frameBuffer->getHeight())/2; - - { - pl_Vertex *vlist=obj->Vertices.Get(); - int a; - for (a = 0; a < 3; a ++) { - m_cl[0].newVertices[a] = vlist[face->VertexIndices[a]]; - - memcpy(&m_cl[0].ShadeInfos[a][0],&face->Shades[a][0],3*sizeof(pl_Float)); - int b; - for(b=0;bMappingU[b][a]; - m_cl[0].MappingV[b][a] = face->MappingV[b][a]; - } - } - } - - pl_uInt numVerts = 3; - { - int a = (m_clipPlanes[0][3] < 0.0 ? 0 : 1); - while (a < PL_NUM_CLIP_PLANES && numVerts > 2) - { - numVerts = _ClipToPlane(numVerts, m_clipPlanes[a]); - memcpy(&m_cl[0],&m_cl[1],sizeof(m_cl[0])); - a++; - } - } - if (numVerts > 2) { - pl_Face newface; - memcpy(&newface,face,sizeof(pl_Face)); - int k; - for (k = 2; k < (int)numVerts; k ++) { - int a; - for (a = 0; a < 3; a ++) { - int w; - if (a == 0) w = 0; - else w = a+(k-2); ; - pl_Vertex *thisv=m_cl[0].newVertices+w; - newface.Shades[a][0] = m_cl[0].ShadeInfos[w][0]; - newface.Shades[a][1] = m_cl[0].ShadeInfos[w][1]; - newface.Shades[a][2] = m_cl[0].ShadeInfos[w][2]; - int b; - for(b=0;bxformedz; - double ytmp = m_fovfactor * newface.Scrz[a]; - double xtmp = ytmp*thisv->xformedx; - ytmp *= thisv->xformedy*m_adj_asp; - newface.Scrx[a] = xtmp+cx; - newface.Scry[a] = ytmp+cy; - } - RenderTrisOut++; - - // quick approx of triangle area - RenderPixelsOut += 0.5*fabs( - (newface.Scrx[1] - newface.Scrx[0]) * - (newface.Scry[2] - newface.Scry[0]) - - (newface.Scrx[2] - newface.Scrx[0]) * - (newface.Scry[1] - newface.Scry[0]) ); - - if (frameBuffer->Extended(LICE_EXT_SUPPORTS_ID,(void*)(INT_PTR)LICE_EXT_DRAWTRIANGLE_ACCEL)) - { - LICE_Ext_DrawTriangle_acceldata ac; - ac.mat = newface.Material; - int x,y; - for(x=0;x<3;x++) for(y=0;y<3;y++) ac.VertexShades[x][y]=newface.Shades[x][y]; - for(x=0;x<3;x++) - { - ac.scrx[x]=newface.Scrx[x]; - ac.scry[x]=newface.Scry[x]; - ac.scrz[x]=newface.Scrz[x]; - } - for(x=0;x<2;x++) - { - int tidx=x?newface.Material->TexMapIdx : newface.Material->Tex2MapIdx; - if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; - for(y=0;y<3;y++) - { - ac.mapping_coords[x][y][0]=newface.MappingU[tidx][y]; - ac.mapping_coords[x][y][1]=newface.MappingV[tidx][y]; - } - } - - frameBuffer->Extended(LICE_EXT_DRAWTRIANGLE_ACCEL,&ac); - } - else PutFace(&newface); - } - } -} - -pl_sInt pl_Cam::ClipNeeded(pl_Face *face, pl_Obj *obj) { - double dr,dl,db,dt; - double f; - int fbw=(frameBuffer->getWidth()); - int fbh=(frameBuffer->getHeight()); - int cx = CenterX + fbw/2; - int cy = CenterY + fbh/2; - dr = (fbw-cx); - dl = (-cx); - db = (fbh-cy); - dt = (-cy); - f = m_fovfactor*m_adj_asp; - pl_Vertex *vlist=obj->Vertices.Get(); - pl_Vertex *v0=vlist+face->VertexIndices[0]; - pl_Vertex *v1=vlist+face->VertexIndices[1]; - pl_Vertex *v2=vlist+face->VertexIndices[2]; - - return ((ClipBack <= 0.0 || - v0->xformedz <= ClipBack || - v1->xformedz <= ClipBack || - v2->xformedz <= ClipBack) && - (v0->xformedz >= 0 || - v1->xformedz >= 0 || - v2->xformedz >= 0) && - (v0->xformedx*m_fovfactor<=dr*v0->xformedz || - v1->xformedx*m_fovfactor<=dr*v1->xformedz || - v2->xformedx*m_fovfactor<=dr*v2->xformedz) && - (v0->xformedx*m_fovfactor>=dl*v0->xformedz || - v1->xformedx*m_fovfactor>=dl*v1->xformedz || - v2->xformedx*m_fovfactor>=dl*v2->xformedz) && - (v0->xformedy*f<=db*v0->xformedz || - v1->xformedy*f<=db*v1->xformedz || - v2->xformedy*f<=db*v2->xformedz) && - (v0->xformedy*f>=dt*v0->xformedz || - v1->xformedy*f>=dt*v1->xformedz || - v2->xformedy*f>=dt*v2->xformedz)); -} - - - - - - -void pl_Cam::Begin(LICE_IBitmap *fb, bool want_zbclear, pl_ZBuffer zbclear) { - if (frameBuffer||!fb) return; - - if (WantZBuffer) - { - int zbsz=fb->getWidth()*fb->getHeight(); - pl_ZBuffer *zb=zBuffer.Resize(zbsz); - if (want_zbclear) - { - if (!zbclear) memset(zb,0,zbsz*sizeof(pl_ZBuffer)); - else - { - int i=zbsz; - while(i--) *zb++=zbclear; - } - } - } - else zBuffer.Resize(0); - pl_Float tempMatrix[16]; - _numlights = 0; - _numfaces = _numfaces_sorted = 0; - frameBuffer = fb; - plMatrixRotate(_cMatrix,2,-Pan); - plMatrixRotate(tempMatrix,1,-Pitch); - plMatrixMultiply(_cMatrix,tempMatrix); - plMatrixRotate(tempMatrix,3,-Roll); - plMatrixMultiply(_cMatrix,tempMatrix); - - RecalcFrustum(); - - RenderTrisIn=RenderTrisCulled=RenderTrisOut=0; - RenderPixelsOut=0.0; - -} - -void pl_Cam::RenderLight(pl_Light *light) { - if (!light||!frameBuffer) return; - - pl_Float *pl, xp, yp, zp; - if (light->Type == PL_LIGHT_NONE) return; - if (_lights.GetSize()<=_numlights) _lights.Resize(_numlights+1); - pl = _lights.Get()[_numlights].l; - if (light->Type == PL_LIGHT_VECTOR) { - xp = light->Xp; - yp = light->Yp; - zp = light->Zp; - MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); - } else if (light->Type & PL_LIGHT_POINT) { - xp = light->Xp-X; - yp = light->Yp-Y; - zp = light->Zp-Z; - MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); - } - _lights.Get()[_numlights++].light = light; -} - -void pl_Cam::RenderObject(pl_Obj *obj, pl_Float *bmatrix, pl_Float *bnmatrix) { - if (!obj||!frameBuffer) return; - - pl_Float oMatrix[16], nMatrix[16], tempMatrix[16]; - - if (obj->GenMatrix) { - plMatrixRotate(nMatrix,1,obj->Xa); - plMatrixRotate(tempMatrix,2,obj->Ya); - plMatrixMultiply(nMatrix,tempMatrix); - plMatrixRotate(tempMatrix,3,obj->Za); - plMatrixMultiply(nMatrix,tempMatrix); - memcpy(oMatrix,nMatrix,sizeof(pl_Float)*16); - } else memcpy(nMatrix,obj->RotMatrix,sizeof(pl_Float)*16); - - if (bnmatrix) plMatrixMultiply(nMatrix,bnmatrix); - - if (obj->GenMatrix) { - plMatrixTranslate(tempMatrix, obj->Xp, obj->Yp, obj->Zp); - plMatrixMultiply(oMatrix,tempMatrix); - } else memcpy(oMatrix,obj->Matrix,sizeof(pl_Float)*16); - if (bmatrix) plMatrixMultiply(oMatrix,bmatrix); - - { - int i; - for (i = 0; i < obj->Children.GetSize(); i ++) - if (obj->Children.Get(i)) RenderObject(obj->Children.Get(i),oMatrix,nMatrix); - } - if (!obj->Faces.GetSize() || !obj->Vertices.GetSize()) return; - - plMatrixTranslate(tempMatrix, -X, -Y, -Z); - plMatrixMultiply(oMatrix,tempMatrix); - plMatrixMultiply(oMatrix,_cMatrix); - plMatrixMultiply(nMatrix,_cMatrix); - - { - pl_Vertex *vertex = obj->Vertices.Get(); - int i = obj->Vertices.GetSize(); - - while (i--) - { - MACRO_plMatrixApply(oMatrix,vertex->x,vertex->y,vertex->z, - vertex->xformedx, vertex->xformedy, vertex->xformedz); - MACRO_plMatrixApply(nMatrix,vertex->nx,vertex->ny,vertex->nz, - vertex->xformednx,vertex->xformedny,vertex->xformednz); - vertex++; - } - } - - if (_faces.GetSize() < _numfaces + obj->Faces.GetSize()) _faces.Resize(_numfaces + obj->Faces.GetSize()); - - - _faceInfo *facelistout = _faces.Get() + _numfaces; - - pl_Face *face = obj->Faces.Get(); - int facecnt = obj->Faces.GetSize(); - - RenderTrisIn += facecnt; - _numfaces += facecnt; - pl_Vertex *vlist = obj->Vertices.Get(); - - while (facecnt--) - { - double nx,ny,nz; - pl_Mat *mat=face->Material; - if (mat->BackfaceCull || (mat->Lightable && !mat->Smoothing)) - { - MACRO_plMatrixApply(nMatrix,face->nx,face->ny,face->nz,nx,ny,nz); - } - pl_Vertex *v0=vlist+face->VertexIndices[0]; - pl_Vertex *v1=vlist+face->VertexIndices[1]; - pl_Vertex *v2=vlist+face->VertexIndices[2]; - - if (!mat->BackfaceCull || (MACRO_plDotProduct(nx,ny,nz, v0->xformedx, v0->xformedy, v0->xformedz) < 0.0000001)) { - if (ClipNeeded(face,obj)) { - if (!mat->Smoothing && (mat->Lightable||mat->FadeDist)) { - pl_Float val[3]; - memcpy(val,face->sLighting,3*sizeof(pl_Float)); - if (mat->Lightable) { - _lightInfo *inf = _lights.Get(); - int i=_numlights; - while (i--) - { - pl_Light *light = inf->light; - double lightsc=0.0; - if (light->Type & PL_LIGHT_POINT_ANGLE) { - double nx2 = inf->l[0] - v0->xformedx; - double ny2 = inf->l[1] - v0->xformedy; - double nz2 = inf->l[2] - v0->xformedz; - MACRO_plNormalizeVector(nx2,ny2,nz2); - lightsc = MACRO_plDotProduct(nx,ny,nz,nx2,ny2,nz2); - } - if (light->Type & PL_LIGHT_POINT_DISTANCE) { - double nx2 = inf->l[0] - v0->xformedx; - double ny2 = inf->l[1] - v0->xformedy; - double nz2 = inf->l[2] - v0->xformedz; - if (light->Type & PL_LIGHT_POINT_ANGLE) { - nx2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ - light->HalfDistSquared)); - lightsc *= plMax(0,plMin(1.0,nx2)); - } else { - lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ - light->HalfDistSquared)); - lightsc = plMax(0,plMin(1.0,lightsc)); - } - } - if (light->Type == PL_LIGHT_VECTOR) - lightsc = MACRO_plDotProduct(nx,ny,nz,inf->l[0],inf->l[1],inf->l[2]); - - if (lightsc>0.0) - { - val[0] += light->Intensity[0]*lightsc; - val[1] += light->Intensity[1]*lightsc; - val[2] += light->Intensity[2]*lightsc; - } - else if (mat->BackfaceIllumination) - { - val[0] -= light->Intensity[0]*lightsc*mat->BackfaceIllumination; - val[1] -= light->Intensity[1]*lightsc*mat->BackfaceIllumination; - val[2] -= light->Intensity[2]*lightsc*mat->BackfaceIllumination; - } - inf++; - } /* End of light loop */ - } /* End of flat shading if */ - - if (mat->FadeDist) - { - double lightsc = 1.0 - (v0->xformedz+v1->xformedz+v2->xformedz) / (mat->FadeDist*3.0); - if (lightsc<0.0) lightsc=0.0; - else if (lightsc>1.0)lightsc=1.0; - if (mat->Lightable) - { - val[0] *= lightsc; - val[1] *= lightsc; - val[2] *= lightsc; - } - else - { - val[0]+=lightsc; - val[1]+=lightsc; - val[2]+=lightsc; - } - } - face->Shades[0][0]=mat->Ambient[0] + mat->Diffuse[0]*val[0]; - face->Shades[0][1]=mat->Ambient[1] + mat->Diffuse[1]*val[1]; - face->Shades[0][2]=mat->Ambient[2] + mat->Diffuse[2]*val[2]; - } - else memcpy(face->Shades,mat->Ambient,sizeof(mat->Ambient)); // flat shading - - if ((mat->Texture && mat->TexMapIdx<0)||(mat->Texture2 && mat->Tex2MapIdx<0)) { - face->MappingU[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 + (v0->xformednx); - face->MappingV[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 - (v0->xformedny); - face->MappingU[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 + (v1->xformednx); - face->MappingV[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 - (v1->xformedny); - face->MappingU[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 + (v2->xformednx); - face->MappingV[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 - (v2->xformedny); - } - - if (mat->Smoothing && (mat->Lightable || mat->FadeDist)) - { - int a; - for (a = 0; a < 3; a ++) { - pl_Float val[3]; - memcpy(val,face->vsLighting[a],sizeof(val)); - pl_Vertex *thisvert = obj->Vertices.Get()+face->VertexIndices[a]; - - if (mat->Lightable) - { - int i=_numlights; - _lightInfo *inf = _lights.Get(); - while (i--) - { - double lightsc = 0.0; - pl_Light *light = inf->light; - if (light->Type & PL_LIGHT_POINT_ANGLE) { - double nx2 = inf->l[0] - thisvert->xformedx; - double ny2 = inf->l[1] - thisvert->xformedy; - double nz2 = inf->l[2] - thisvert->xformedz; - MACRO_plNormalizeVector(nx2,ny2,nz2); - lightsc = MACRO_plDotProduct(thisvert->xformednx, - thisvert->xformedny, - thisvert->xformednz, - nx2,ny2,nz2); - } - if (light->Type & PL_LIGHT_POINT_DISTANCE) { - double nx2 = inf->l[0] - thisvert->xformedx; - double ny2 = inf->l[1] - thisvert->xformedy; - double nz2 = inf->l[2] - thisvert->xformedz; - if (light->Type & PL_LIGHT_POINT_ANGLE) { - double t= (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); - lightsc *= plMax(0,plMin(1.0,t)); - } else { - lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); - lightsc = plMax(0,plMin(1.0,lightsc)); - } - } - - if (light->Type == PL_LIGHT_VECTOR) - lightsc = MACRO_plDotProduct(thisvert->xformednx, - thisvert->xformedny, - thisvert->xformednz, - inf->l[0],inf->l[1],inf->l[2]); - if (lightsc > 0.0) - { - val[0] += lightsc * light->Intensity[0]; - val[1] += lightsc * light->Intensity[1]; - val[2] += lightsc * light->Intensity[2]; - } - else if (mat->BackfaceIllumination) - { - val[0] -= lightsc * light->Intensity[0]*mat->BackfaceIllumination; - val[1] -= lightsc * light->Intensity[1]*mat->BackfaceIllumination; - val[2] -= lightsc * light->Intensity[2]*mat->BackfaceIllumination; - } - inf++; - } /* End of light loop */ - } /* End of gouraud shading if */ - if (mat->FadeDist) - { - double lightsc = 1.0-thisvert->xformedz/mat->FadeDist; - if (lightsc<0.0) lightsc=0.0; - else if (lightsc>1.0)lightsc=1.0; - if (mat->Lightable) - { - val[0] *= lightsc; - val[1] *= lightsc; - val[2] *= lightsc; - } - else - { - val[0] += lightsc; - val[1] += lightsc; - val[2] += lightsc; - } - } - face->Shades[a][0] = mat->Ambient[0] + mat->Diffuse[0]*val[0]; - face->Shades[a][1] = mat->Ambient[1] + mat->Diffuse[1]*val[1]; - face->Shades[a][2] = mat->Ambient[2] + mat->Diffuse[2]*val[2]; - } /* End of vertex loop for */ - } /* End of gouraud shading mask if */ - else // flat modes, shade all vertices - { - memcpy(&face->Shades[1][0],&face->Shades[0][0],sizeof(pl_Float)*3); - memcpy(&face->Shades[2][0],&face->Shades[0][0],sizeof(pl_Float)*3); - } - - facelistout->zd = v0->xformedz+v1->xformedz+v2->xformedz; - facelistout->obj=obj; - facelistout->face = face; - facelistout++; - - - RenderTrisCulled++; - - } /* Is it in our area Check */ - } /* Backface Check */ - face++; - } - _numfaces = facelistout-_faces.Get(); -} -void pl_Cam::SortToCurrent() -{ - if (Sort && _numfaces > _numfaces_sorted+1) - { - WDL_mergesort(_faces.Get()+_numfaces_sorted, - _numfaces-_numfaces_sorted,sizeof(_faceInfo), - Sort > 0 ? sortFwdFunc : sortRevFunc, - (char*)_sort_tmpspace.Resize((_numfaces-_numfaces_sorted)*sizeof(_faceInfo),false)); - } - _numfaces_sorted=_numfaces; -} - -int pl_Cam::sortRevFunc(const void *a, const void *b) -{ - _faceInfo *aa = (_faceInfo*)a; - _faceInfo *bb = (_faceInfo*)b; - - if (aa->zd < bb->zd) return -1; - if (aa->zd > bb->zd) return 1; - return 0; -} - -int pl_Cam::sortFwdFunc(const void *a, const void *b) -{ - _faceInfo *aa = (_faceInfo*)a; - _faceInfo *bb = (_faceInfo*)b; - - if (aa->zd < bb->zd) return 1; - if (aa->zd > bb->zd) return -1; - return 0; -} - -void pl_Cam::End() { - if (!frameBuffer) return; - - SortToCurrent(); - - _faceInfo *f = _faces.Get(); - int n=_numfaces; - while (n-->0) - { - if (f->face->Material) - { - ClipRenderFace(f->face,f->obj); - } - f++; - } - frameBuffer=0; - _numfaces=0; - _numlights = 0; -} - - - - -void pl_Light::Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist) { - pl_Float m[16], m2[16]; - Type = mode; - Intensity[0] = intensity_r; - Intensity[1] = intensity_g; - Intensity[2] = intensity_b; - HalfDistSquared = halfDist*halfDist; - switch (mode) { - case PL_LIGHT_VECTOR: - plMatrixRotate(m,1,x); - plMatrixRotate(m2,2,y); - plMatrixMultiply(m,m2); - plMatrixRotate(m2,3,z); - plMatrixMultiply(m,m2); - plMatrixApply(m,0.0,0.0,-1.0,&Xp, &Yp, &Zp); - break; - case PL_LIGHT_POINT_ANGLE: - case PL_LIGHT_POINT_DISTANCE: - case PL_LIGHT_POINT: - Xp = x; - Yp = y; - Zp = z; - break; - } -} \ No newline at end of file diff --git a/WDL/plush2/pl_make.cpp b/WDL/plush2/pl_make.cpp deleted file mode 100644 index 4147a49e..00000000 --- a/WDL/plush2/pl_make.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -make.c -Object Primitives -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************* - Notes: - Most of these routines are highly unoptimized. - They could all use some work, such as more capable divisions (Box is - most notable), etc... The mapping coordinates are all set up nicely, - though. -******************************************************************************/ - -#include "plush.h" - -pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, pl_uInt divrad, - pl_Mat *m) { - pl_Obj *o; - pl_Vertex *v; - pl_Face *f; - pl_uInt x, y; - double ravg, rt, a, da, al, dal; - pl_Float U,V,dU,dV; - if (divrot < 3) divrot = 3; - if (divrad < 3) divrad = 3; - ravg = (r1+r2)*0.5; - rt = (r2-r1)*0.5; - o = new pl_Obj(divrad*divrot,divrad*divrot*2); - if (!o) return 0; - v = o->Vertices.Get(); - a = 0.0; - da = 2*PL_PI/divrot; - for (y = 0; y < divrot; y ++) { - al = 0.0; - dal = 2*PL_PI/divrad; - for (x = 0; x < divrad; x ++) { - v->x = (pl_Float) (cos((double) a)*(ravg + cos((double) al)*rt)); - v->z = (pl_Float) (sin((double) a)*(ravg + cos((double) al)*rt)); - v->y = (pl_Float) (sin((double) al)*rt); - v++; - al += dal; - } - a += da; - } - v = o->Vertices.Get(); - f = o->Faces.Get(); - dV = 1.0/divrad; - dU = 1.0/divrot; - U = 0; - for (y = 0; y < divrot; y ++) { - V = -0.5; - for (x = 0; x < divrad; x ++) { - f->VertexIndices[0] = v+x+y*divrad - o->Vertices.Get(); - f->MappingU[0][0] = U; - f->MappingV[0][0] = V; - f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get(); - f->MappingU[0][1] = U; - f->MappingV[0][1] = V+dV; - f->VertexIndices[2] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); - f->MappingU[0][2] = U+dU; - f->MappingV[0][2] = V; - f->Material = m; - f++; - f->VertexIndices[0] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); - f->MappingU[0][0] = U+dU; - f->MappingV[0][0] = V; - f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get(); - f->MappingU[0][1] = U; - f->MappingV[0][1] = V+dV; - f->VertexIndices[2] = v+(x+1==divrad?0:x+1)+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); - f->MappingU[0][2] = U+dU; - f->MappingV[0][2] = V+dV; - f->Material = m; - f++; - V += dV; - } - U += dU; - } - o->CalculateNormals(); - return (o); -} - -pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m) { - pl_Obj *o; - pl_Vertex *v; - pl_Face *f; - pl_uInt x, y; - double a, da, yp, ya, yda, yf; - pl_Float U,V,dU,dV; - if (divh < 3) divh = 3; - if (divr < 3) divr = 3; - o = new pl_Obj(2+(divh-2)*(divr),2*divr+(divh-3)*divr*2); - if (!o) return 0; - v = o->Vertices.Get(); - v->x = v->z = 0.0; v->y = r; v++; - v->x = v->z = 0.0; v->y = -r; v++; - ya = 0.0; - yda = PL_PI/(divh-1); - da = (PL_PI*2.0)/divr; - for (y = 0; y < divh - 2; y ++) { - ya += yda; - yp = cos((double) ya)*r; - yf = sin((double) ya)*r; - a = 0.0; - for (x = 0; x < divr; x ++) { - v->y = (pl_Float) yp; - v->x = (pl_Float) (cos((double) a)*yf); - v->z = (pl_Float) (sin((double) a)*yf); - v++; - a += da; - } - } - f = o->Faces.Get(); - v = o->Vertices.Get() + 2; - a = 0.0; - U = 0; - dU = 1.0/divr; - dV = V = 1.0/divh; - for (x = 0; x < divr; x ++) { - f->VertexIndices[0] = 0; - f->VertexIndices[1] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get(); - f->VertexIndices[2] = v + x - o->Vertices.Get(); - f->MappingU[0][0] = U; - f->MappingV[0][0] = 0; - f->MappingU[0][1] = U+dU; - f->MappingV[0][1] = V; - f->MappingU[0][2] = U; - f->MappingV[0][2] = V; - f->Material = m; - f++; - U += dU; - } - da = 1.0/(divr+1); - v = o->Vertices.Get() + 2; - for (x = 0; x < (divh-3); x ++) { - U = 0; - for (y = 0; y < divr; y ++) { - f->VertexIndices[0] = v+y - o->Vertices.Get(); - f->VertexIndices[1] = v+divr+(y+1==divr?0:y+1) - o->Vertices.Get(); - f->VertexIndices[2] = v+y+divr - o->Vertices.Get(); - f->MappingU[0][0] = U; - f->MappingV[0][0] = V; - f->MappingU[0][1] = U+dU; - f->MappingV[0][1] = V+dV; - f->MappingU[0][2] = U; - f->MappingV[0][2] = V+dV; - f->Material = m; f++; - f->VertexIndices[0] = v+y - o->Vertices.Get(); - f->VertexIndices[1] = v+(y+1==divr?0:y+1) - o->Vertices.Get(); - f->VertexIndices[2] = v+(y+1==divr?0:y+1)+divr - o->Vertices.Get(); - f->MappingU[0][0] = U; - f->MappingV[0][0] = V; - f->MappingU[0][1] = U+dU; - f->MappingV[0][1] = V; - f->MappingU[0][2] = U+dU; - f->MappingV[0][2] = V+dV; - f->Material = m; f++; - U += dU; - } - V += dV; - v += divr; - } - v = o->Vertices.Get() + o->Vertices.GetSize() - divr; - U = 0; - for (x = 0; x < divr; x ++) { - f->VertexIndices[0] = 1; - f->VertexIndices[1] = v + x - o->Vertices.Get(); - f->VertexIndices[2] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get(); - f->MappingU[0][0] = U; - f->MappingV[0][0] = 1.0; - f->MappingU[0][1] = U; - f->MappingV[0][1] = V; - f->MappingU[0][2] = U+dU; - f->MappingV[0][2] = V; - f->Material = m; - f++; - U += dU; - } - o->CalculateNormals(); - return (o); -} - -pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, - pl_Bool capbottom, pl_Mat *m) { - pl_Obj *o; - pl_Vertex *v, *topverts, *bottomverts, *topcapvert=0, *bottomcapvert=0; - pl_Face *f; - pl_uInt32 i; - double a, da; - if (divr < 3) divr = 3; - o = new pl_Obj(divr*2+((divr==3)?0:(captop?1:0)+(capbottom?1:0)), - divr*2+(divr==3 ? (captop ? 1 : 0) + (capbottom ? 1 : 0) : - (captop ? divr : 0) + (capbottom ? divr : 0))); - if (!o) return 0; - a = 0.0; - da = (2.0*PL_PI)/divr; - v = o->Vertices.Get(); - topverts = v; - for (i = 0; i < divr; i ++) { - v->y = h/2.0f; - v->x = (pl_Float) (r*cos((double) a)); - v->z = (pl_Float)(r*sin(a)); - v->xformedx = (0.5 + (0.5*cos((double) a))); // temp - v->xformedy = (0.5 + (0.5*sin((double) a))); // use xf - v++; - a += da; - } - bottomverts = v; - a = 0.0; - for (i = 0; i < divr; i ++) { - v->y = -h/2.0f; - v->x = (pl_Float) (r*cos((double) a)); - v->z = (pl_Float) (r*sin(a)); - v->xformedx = (0.5 + (0.5*cos((double) a))); - v->xformedy = (0.5 + (0.5*sin((double) a))); - v++; a += da; - } - if (captop && divr != 3) { - topcapvert = v; - v->y = h / 2.0f; - v->x = v->z = 0.0f; - v++; - } - if (capbottom && divr != 3) { - bottomcapvert = v; - v->y = -h / 2.0f; - v->x = v->z = 0.0f; - v++; - } - f = o->Faces.Get(); - for (i = 0; i < divr; i ++) { - f->VertexIndices[0] = bottomverts + i - o->Vertices.Get(); - f->VertexIndices[1] = topverts + i - o->Vertices.Get(); - f->VertexIndices[2] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); - f->MappingV[0][0] = f->MappingV[0][2] = 1.0; f->MappingV[0][1] = 0; - f->MappingU[0][0] = f->MappingU[0][1] = i/(double)divr; - f->MappingU[0][2] = ((i+1))/(double)divr; - f->Material = m; f++; - f->VertexIndices[0] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); - f->VertexIndices[1] = topverts + i - o->Vertices.Get(); - f->VertexIndices[2] = topverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); - f->MappingV[0][1] = f->MappingV[0][2] = 0; f->MappingV[0][0] = 1.0; - f->MappingU[0][0] = f->MappingU[0][2] = ((i+1))/(double)divr; - f->MappingU[0][1] = (i)/(double)divr; - f->Material = m; f++; - } - if (captop) { - if (divr == 3) { - f->VertexIndices[0] = topverts + 0 - o->Vertices.Get(); - f->VertexIndices[1] = topverts + 2 - o->Vertices.Get(); - f->VertexIndices[2] = topverts + 1 - o->Vertices.Get(); - f->MappingU[0][0] = topverts[0].xformedx; - f->MappingV[0][0] = topverts[0].xformedy; - f->MappingU[0][1] = topverts[1].xformedx; - f->MappingV[0][1] = topverts[1].xformedy; - f->MappingU[0][2] = topverts[2].xformedx; - f->MappingV[0][2] = topverts[2].xformedy; - f->Material = m; f++; - } else { - for (i = 0; i < divr; i ++) { - f->VertexIndices[0] = topverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get(); - f->VertexIndices[1] = topverts + i - o->Vertices.Get(); - f->VertexIndices[2] = topcapvert - o->Vertices.Get(); - f->MappingU[0][0] = topverts[(i==divr-1?0:i+1)].xformedx; - f->MappingV[0][0] = topverts[(i==divr-1?0:i+1)].xformedy; - f->MappingU[0][1] = topverts[i].xformedx; - f->MappingV[0][1] = topverts[i].xformedy; - f->MappingU[0][2] = f->MappingV[0][2] = 0.5; - f->Material = m; f++; - } - } - } - if (capbottom) { - if (divr == 3) { - f->VertexIndices[0] = bottomverts + 0 - o->Vertices.Get(); - f->VertexIndices[1] = bottomverts + 1 - o->Vertices.Get(); - f->VertexIndices[2] = bottomverts + 2 - o->Vertices.Get(); - f->MappingU[0][0] = bottomverts[0].xformedx; - f->MappingV[0][0] = bottomverts[0].xformedy; - f->MappingU[0][1] = bottomverts[1].xformedx; - f->MappingV[0][1] = bottomverts[1].xformedy; - f->MappingU[0][2] = bottomverts[2].xformedx; - f->MappingV[0][2] = bottomverts[2].xformedy; - f->Material = m; f++; - } else { - for (i = 0; i < divr; i ++) { - f->VertexIndices[0] = bottomverts + i - o->Vertices.Get(); - f->VertexIndices[1] = bottomverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get(); - f->VertexIndices[2] = bottomcapvert - o->Vertices.Get(); - f->MappingU[0][0] = bottomverts[i].xformedx; - f->MappingV[0][0] = bottomverts[i].xformedy; - f->MappingU[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedx; - f->MappingV[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedy; - f->MappingU[0][2] = f->MappingV[0][2] = 0.5; - f->Material = m; f++; - } - } - } - o->CalculateNormals(); - return (o); -} - -pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, - pl_Bool cap, pl_Mat *m) { - pl_Obj *o; - pl_Vertex *v; - pl_Face *f; - pl_uInt32 i; - double a, da; - if (div < 3) div = 3; - o = new pl_Obj(div + (div == 3 ? 1 : (cap ? 2 : 1)), - div + (div == 3 ? 1 : (cap ? div : 0))); - if (!o) return 0; - v = o->Vertices.Get(); - v->x = v->z = 0; v->y = h/2; - v->xformedx = 0.5; - v->xformedy = 0.5; - v++; - a = 0.0; - da = (2.0*PL_PI)/div; - for (i = 1; i <= div; i ++) { - v->y = h/-2.0f; - v->x = (pl_Float) (r*cos((double) a)); - v->z = (pl_Float) (r*sin((double) a)); - v->xformedx = (0.5 + (cos((double) a)*0.5)); - v->xformedy = (0.5 + (sin((double) a)*0.5)); - a += da; - v++; - } - if (cap && div != 3) { - v->y = h / -2.0f; - v->x = v->z = 0.0f; - v->xformedx = 0.5; - v->xformedy = 0.5; - v++; - } - f = o->Faces.Get(); - for (i = 1; i <= div; i ++) { - f->VertexIndices[0] = 0; - f->VertexIndices[1] = o->Vertices.Get() + (i == div ? 1 : i + 1) - o->Vertices.Get(); - f->VertexIndices[2] = o->Vertices.Get() + i - o->Vertices.Get(); - f->MappingU[0][0] = o->Vertices.Get()[0].xformedx; - f->MappingV[0][0] = o->Vertices.Get()[0].xformedy; - f->MappingU[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedx; - f->MappingV[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedy; - f->MappingU[0][2] = o->Vertices.Get()[i].xformedx; - f->MappingV[0][2] = o->Vertices.Get()[i].xformedy; - f->Material = m; - f++; - } - if (cap) { - if (div == 3) { - f->VertexIndices[0] = 1; - f->VertexIndices[1] = 2; - f->VertexIndices[2] = 3; - f->MappingU[0][0] = o->Vertices.Get()[1].xformedx; - f->MappingV[0][0] = o->Vertices.Get()[1].xformedy; - f->MappingU[0][1] = o->Vertices.Get()[2].xformedx; - f->MappingV[0][1] = o->Vertices.Get()[2].xformedy; - f->MappingU[0][2] = o->Vertices.Get()[3].xformedx; - f->MappingV[0][2] = o->Vertices.Get()[3].xformedy; - f->Material = m; - f++; - } else { - for (i = 1; i <= div; i ++) { - f->VertexIndices[0] = div + 1; - f->VertexIndices[1] = i; - f->VertexIndices[2] = (i==div ? 1 : i+1); - f->MappingU[0][0] = o->Vertices.Get()[div+1].xformedx; - f->MappingV[0][0] = o->Vertices.Get()[div+1].xformedy; - f->MappingU[0][1] = o->Vertices.Get()[i].xformedx; - f->MappingV[0][1] = o->Vertices.Get()[i].xformedy; - f->MappingU[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedx; - f->MappingV[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedy; - f->Material = m; - f++; - } - } - } - o->CalculateNormals(); - return (o); -} - -static pl_uChar verts[6*6] = { - 0,4,1, 1,4,5, 0,1,2, 3,2,1, 2,3,6, 3,7,6, - 6,7,4, 4,7,5, 1,7,3, 7,1,5, 2,6,0, 4,0,6 -}; -static pl_uChar map[24*2*3] = { - 1,0, 1,1, 0,0, 0,0, 1,1, 0,1, - 0,0, 1,0, 0,1, 1,1, 0,1, 1,0, - 0,0, 1,0, 0,1, 1,0, 1,1, 0,1, - 0,0, 1,0, 0,1, 0,1, 1,0, 1,1, - 1,0, 0,1, 0,0, 0,1, 1,0, 1,1, - 1,0, 1,1, 0,0, 0,1, 0,0, 1,1 -}; - - -pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m) { - pl_uChar *mm = map; - pl_uChar *vv = verts; - pl_Obj *o; - pl_Vertex *v; - pl_Face *f; - pl_uInt x; - o = new pl_Obj(8,12); - if (!o) return 0; - v = o->Vertices.Get(); - v->x = -w/2; v->y = h/2; v->z = d/2; v++; - v->x = w/2; v->y = h/2; v->z = d/2; v++; - v->x = -w/2; v->y = h/2; v->z = -d/2; v++; - v->x = w/2; v->y = h/2; v->z = -d/2; v++; - v->x = -w/2; v->y = -h/2; v->z = d/2; v++; - v->x = w/2; v->y = -h/2; v->z = d/2; v++; - v->x = -w/2; v->y = -h/2; v->z = -d/2; v++; - v->x = w/2; v->y = -h/2; v->z = -d/2; v++; - f = o->Faces.Get(); - for (x = 0; x < 12; x ++) { - f->VertexIndices[0] = *vv++; - f->VertexIndices[1] = *vv++; - f->VertexIndices[2] = *vv++; - f->MappingU[0][0] = (pl_Float) *mm++; - f->MappingV[0][0] = (pl_Float) *mm++; - f->MappingU[0][1] = (pl_Float) *mm++; - f->MappingV[0][1] = (pl_Float) *mm++; - f->MappingU[0][2] = (pl_Float) *mm++; - f->MappingV[0][2] = (pl_Float) *mm++; - f->Material = m; - f++; - } - - o->CalculateNormals(); - return (o); -} - -pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m) { - pl_Obj *o; - pl_Vertex *v; - pl_Face *f; - pl_uInt x, y; - o = new pl_Obj((res+1)*(res+1),res*res*2); - if (!o) return 0; - v = o->Vertices.Get(); - for (y = 0; y <= res; y ++) { - for (x = 0; x <= res; x ++) { - v->y = 0; - v->x = ((x*w)/res) - w/2; - v->z = ((y*d)/res) - d/2; - v++; - } - } - f = o->Faces.Get(); - for (y = 0; y < res; y ++) { - for (x = 0; x < res; x ++) { - f->VertexIndices[0] = x+(y*(res+1)); - f->MappingU[0][0] = (x)/(double)res; - f->MappingV[0][0] = (y)/(double)res; - f->VertexIndices[2] = x+1+(y*(res+1)); - f->MappingU[0][2] = ((x+1))/(double)res; - f->MappingV[0][2] = (y)/(double)res; - f->VertexIndices[1] = x+((y+1)*(res+1)); - f->MappingU[0][1] = (x)/(double)res; - f->MappingV[0][1] = ((y+1))/(double)res; - f->Material = m; - f++; - f->VertexIndices[0] = x+((y+1)*(res+1)); - f->MappingU[0][0] = (x)/(double)res; - f->MappingV[0][0] = ((y+1))/(double)res; - f->VertexIndices[2] = x+1+(y*(res+1)); - f->MappingU[0][2] = ((x+1))/(double)res; - f->MappingV[0][2] = (y)/(double)res; - f->VertexIndices[1] = x+1+((y+1)*(res+1)); - f->MappingU[0][1] = ((x+1))/(double)res; - f->MappingV[0][1] = ((y+1))/(double)res; - f->Material = m; - f++; - } - } - o->CalculateNormals(); - return (o); -} diff --git a/WDL/plush2/pl_math.cpp b/WDL/plush2/pl_math.cpp deleted file mode 100644 index dcedf6a2..00000000 --- a/WDL/plush2/pl_math.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -math.c -Math and Matrix Control -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - -void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg) { - pl_uChar m1, m2; - double c,s; - double d= Deg * PL_PI / 180.0; - memset(matrix,0,sizeof(pl_Float)*16); - matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0; - m1 = (m % 3); - m2 = ((m1+1) % 3); - c = cos(d); s = sin(d); - matrix[(m1<<2)+m1]=(pl_Float)c; matrix[(m1<<2)+m2]=(pl_Float)s; - matrix[(m2<<2)+m2]=(pl_Float)c; matrix[(m2<<2)+m1]=(pl_Float)-s; -} - -void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z) { - memset(m,0,sizeof(pl_Float)*16); - m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0; - m[0+3] = x; m[4+3] = y; m[8+3] = z; -} - -void plMatrixMultiply(pl_Float *dest, pl_Float src[]) { - pl_Float temp[16]; - pl_uInt i; - memcpy(temp,dest,sizeof(pl_Float)*16); - for (i = 0; i < 16; i += 4) { - *dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+ - src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0]; - *dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+ - src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1]; - *dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+ - src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2]; - *dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+ - src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3]; - } -} - -void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, - pl_Float *outx, pl_Float *outy, pl_Float *outz) { - *outx = x*m[0] + y*m[1] + z*m[2] + m[3]; - *outy = x*m[4] + y*m[5] + z*m[6] + m[7]; - *outz = x*m[8] + y*m[9] + z*m[10] + m[11]; -} - -pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, - pl_Float x2, pl_Float y2, pl_Float z2) { - return ((x1*x2)+(y1*y2)+(z1*z2)); -} - -void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z) { - double length; - length = (*x)*(*x)+(*y)*(*y)+(*z)*(*z); - if (length > 0.0000000001) { - pl_Float t = (pl_Float)sqrt(length); - *x /= t; - *y /= t; - *z /= t; - } else *x = *y = *z = 0.0; -} - diff --git a/WDL/plush2/pl_obj.cpp b/WDL/plush2/pl_obj.cpp deleted file mode 100644 index ca366f99..00000000 --- a/WDL/plush2/pl_obj.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -obj.c -Object control -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - -void pl_Obj::Scale(pl_Float s) { - int i = Vertices.GetSize(); - pl_Vertex *v = Vertices.Get(); - while (i--) { - v->x *= s; v->y *= s; v->z *= s; v++; - } - for (i = 0; i < Children.GetSize(); i ++) - if (Children.Get(i)) Children.Get(i)->Scale(s); -} - -void pl_Obj::Stretch(pl_Float x, pl_Float y, pl_Float z) { - int i = Vertices.GetSize(); - pl_Vertex *v = Vertices.Get(); - while (i--) { - v->x *= x; v->y *= y; v->z *= z; v++; - } - for (i = 0; i < Children.GetSize(); i ++) - if (Children.Get(i)) Children.Get(i)->Stretch(x,y,z); -} - -void pl_Obj::Translate(pl_Float x, pl_Float y, pl_Float z) { - int i = Vertices.GetSize(); - pl_Vertex *v = Vertices.Get(); - while (i--) { - v->x += x; v->y += y; v->z += z; v++; - } - for (i = 0; i < Children.GetSize(); i ++) - if (Children.Get(i)) Children.Get(i)->Translate(x,y,z); -} - -void pl_Obj::FlipNormals() { - int i = Vertices.GetSize(); - pl_Vertex *v = Vertices.Get(); - pl_Face *f = Faces.Get(); - while (i--) { - v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++; - } - i = Faces.GetSize(); - while (i--) { - f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz; - f++; - } - for (i = 0; i < Children.GetSize(); i ++) - if (Children.Get(i)) Children.Get(i)->FlipNormals(); -} - - -pl_Obj *pl_Obj::Clone() { - int i; - pl_Obj *out; - if (!(out = new pl_Obj(Vertices.GetSize(),Faces.GetSize()))) return 0; - for (i = 0; i < Children.GetSize(); i ++) - out->Children.Add(Children.Get(i) ? Children.Get(i)->Clone() : NULL); - - out->Xa = Xa; out->Ya = Ya; out->Za = Za; - out->Xp = Xp; out->Yp = Yp; out->Zp = Zp; - out->GenMatrix = GenMatrix; - memcpy(out->Vertices.Get(), Vertices.Get(), sizeof(pl_Vertex) * Vertices.GetSize()); - memcpy(out->Faces.Get(),Faces.Get(),sizeof(pl_Face) * Faces.GetSize()); - return out; -} - -void pl_Obj::SetMaterial(pl_Mat *m, pl_Bool th) { - pl_sInt32 i = Faces.GetSize(); - pl_Face *f = Faces.Get(); - while (i--) (f++)->Material = m; - if (th) for (i = 0; i < Children.GetSize(); i++) - if (Children.Get(i)) Children.Get(i)->SetMaterial(m,true); -} - -void pl_Obj::CalculateNormals() { - int i; - pl_Vertex *v = Vertices.Get(); - pl_Face *f = Faces.Get(); - double x1, x2, y1, y2, z1, z2; - i = Vertices.GetSize(); - while (i--) { - v->nx = 0.0; v->ny = 0.0; v->nz = 0.0; - v++; - } - i = Faces.GetSize(); - while (i--) { - pl_Vertex *vp=Vertices.Get(); - pl_Vertex *fVertices[3] = { - vp+f->VertexIndices[0], - vp+f->VertexIndices[1], - vp+f->VertexIndices[2], - }; - x1 = fVertices[0]->x-fVertices[1]->x; - x2 = fVertices[0]->x-fVertices[2]->x; - y1 = fVertices[0]->y-fVertices[1]->y; - y2 = fVertices[0]->y-fVertices[2]->y; - z1 = fVertices[0]->z-fVertices[1]->z; - z2 = fVertices[0]->z-fVertices[2]->z; - f->nx = (pl_Float) (y1*z2 - z1*y2); - f->ny = (pl_Float) (z1*x2 - x1*z2); - f->nz = (pl_Float) (x1*y2 - y1*x2); - plNormalizeVector(&f->nx, &f->ny, &f->nz); - fVertices[0]->nx += f->nx; - fVertices[0]->ny += f->ny; - fVertices[0]->nz += f->nz; - fVertices[1]->nx += f->nx; - fVertices[1]->ny += f->ny; - fVertices[1]->nz += f->nz; - fVertices[2]->nx += f->nx; - fVertices[2]->ny += f->ny; - fVertices[2]->nz += f->nz; - f++; - } - v = Vertices.Get(); - i = Vertices.GetSize(); - do { - plNormalizeVector(&v->nx, &v->ny, &v->nz); - v++; - } while (--i); - - for (i = 0; i < Children.GetSize(); i ++) - if (Children.Get(i)) Children.Get(i)->CalculateNormals(); -} diff --git a/WDL/plush2/pl_pf_tex.h b/WDL/plush2/pl_pf_tex.h deleted file mode 100644 index e8075813..00000000 --- a/WDL/plush2/pl_pf_tex.h +++ /dev/null @@ -1,442 +0,0 @@ - -static void -#ifdef PL_PF_MULTITEX -PLMTexTri -#else -PLTexTri -#endif -(LICE_pixel *gmem, int swidth, pl_Face *TriFace, pl_ZBuffer *zbuf, int zfb_width, - int solidalpha, int solidcomb, LICE_IBitmap *tex, pl_Float *texscales, int texalpha, int texcomb, int texmap -#ifdef PL_PF_MULTITEX - , LICE_IBitmap *tex2, int tex2alpha, int tex2comb, int texmap2 -#endif - - ) -{ - pl_sInt32 C1[3], C3[3], C2[3], dC2[3]={0}, dCL[3]={0},dC1[3]={0}, dX2=0, dX1=0; - pl_Float dZ2=0, dZL=0,dZ1=0; - - PUTFACE_SORT(); - - - solidcomb&=LICE_BLIT_MODE_MASK; - if (solidcomb == 0 && solidalpha == 256) solidcomb=-1; - else if (solidalpha==0) solidcomb=-2; // ignore - int solidalpha2=(256-solidalpha)*256; - - - pl_Float dU2=0,dV2=0,dUL=0,dVL=0; - pl_Float dU1=0, dV1=0; - bool bilinear = (texcomb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR; - texcomb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA; - if (texcomb==LICE_BLIT_MODE_COPY && texalpha==256) texcomb=-1; - else if (texalpha==0) texcomb=-2; - int texalpha2=(256-texalpha); - - int tex_rowspan=0; - LICE_pixel *texture=NULL; - int tex_w=16,tex_h=16; - -#if defined(PLUSH_NO_SOLIDGOURAUD) || defined(PLUSH_NO_TEXTURE) - if (tex) -#endif - { - texture=tex->getBits(); - tex_rowspan = tex->getRowSpan(); - if (tex->isFlipped()) - { - texture += tex_rowspan*(tex->getHeight()-1); - tex_rowspan=-tex_rowspan; - } - tex_w=tex->getWidth(); - tex_h=tex->getHeight(); - } - pl_sInt32 MappingU_Max=tex_w<<16, MappingV_Max=tex_h<<16; - texscales[0]*=MappingU_Max; - texscales[1]*=MappingV_Max; - -#ifdef PL_PF_MULTITEX - - pl_Float dU2_2=0,dV2_2=0,dUL_2=0,dVL_2=0; - pl_Float dU1_2=0, dV1_2=0; - int tex_w_2=16,tex_h_2=16; - bool bilinear2 = (tex2comb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR; - tex2comb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA; - if (tex2comb==LICE_BLIT_MODE_COPY && tex2alpha==256) tex2comb=-1; - else if (tex2alpha==0) tex2comb=-2; - int tex2alpha2=(256-tex2alpha); - LICE_pixel *texture_2=NULL; - int tex_rowspan_2 = 0; - pl_sInt32 MappingU_Max_2, MappingV_Max_2; - -#ifdef PLUSH_NO_TEXTURE - if (tex2) -#endif - { - tex_w_2=tex2->getWidth(); - tex_h_2=tex2->getHeight(); - texture_2=tex2->getBits(); - tex_rowspan_2 = tex2->getRowSpan(); - if (tex2->isFlipped()) - { - texture_2 += tex_rowspan_2*(tex2->getHeight()-1); - tex_rowspan_2=-tex_rowspan_2; - } - } - MappingU_Max_2=tex_w_2<<16; - MappingV_Max_2=tex_h_2<<16; - texscales[2]*=MappingU_Max_2; - texscales[3]*=MappingV_Max_2; -#endif - - - pl_uChar nm = TriFace->Material->PerspectiveCorrect; - pl_uChar nmb = 0; while (nm) { nmb++; nm >>= 1; } - nmb = plMin(6,nmb); - nm = 1<Scrz[i0]; - pl_Float Z2 = TriFace->Scrz[i1]; - pl_Float Z3 = TriFace->Scrz[i2]; - - pl_Float MappingU1=TriFace->MappingU[texmap][i0]*texscales[0]*Z1; - pl_Float MappingV1=TriFace->MappingV[texmap][i0]*texscales[1]*Z1; - pl_Float MappingU2=TriFace->MappingU[texmap][i1]*texscales[0]*Z2; - pl_Float MappingV2=TriFace->MappingV[texmap][i1]*texscales[1]*Z2; - pl_Float MappingU3=TriFace->MappingU[texmap][i2]*texscales[0]*Z3; - pl_Float MappingV3=TriFace->MappingV[texmap][i2]*texscales[1]*Z3; - -#ifdef PL_PF_MULTITEX - pl_Float MappingU1_2=TriFace->MappingU[texmap2][i0]*texscales[2]*Z1; - pl_Float MappingV1_2=TriFace->MappingV[texmap2][i0]*texscales[3]*Z1; - pl_Float MappingU2_2=TriFace->MappingU[texmap2][i1]*texscales[2]*Z2; - pl_Float MappingV2_2=TriFace->MappingV[texmap2][i1]*texscales[3]*Z2; - pl_Float MappingU3_2=TriFace->MappingU[texmap2][i2]*texscales[2]*Z3; - pl_Float MappingV3_2=TriFace->MappingV[texmap2][i2]*texscales[3]*Z3; -#endif - - int a; - for(a=0;a<3;a++) - { - C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24)); - C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24)); - C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24)); - } - - pl_Float U1, U2; - U1 = U2 = MappingU1; - pl_Float V1,V2; - V1 = V2 = MappingV1; -#ifdef PL_PF_MULTITEX - pl_Float U1_2, U2_2; - U1_2 = U2_2 = MappingU1_2; - pl_Float V1_2, V2_2; - V1_2 = V2_2 = MappingV1_2; -#endif - - pl_sInt32 X2,X1; - X2 = X1 = Scrx[i0]; - pl_sInt32 Y0 = Scry[i0]; - pl_sInt32 Y1 = Scry[i1]; - pl_sInt32 Y2 = Scry[i2]; - - - { - pl_sInt32 dY = Y2-Y0; - if (dY) { - dX2 = (Scrx[i2] - X1) / dY; - - pl_Float v = 1.0/dY; - for(a=0;a<3;a++) dC2[a] = (pl_sInt32) ((C3[a] - C1[a]) * v); - dZ2 = (Z3 - Z1) * v; - dU2 = (MappingU3 - U1) * v; - dV2 = (MappingV3 - V1) * v; - #ifdef PL_PF_MULTITEX - dU2_2 = (MappingU3_2 - U1_2) * v; - dV2_2 = (MappingV3_2 - V1_2) * v; - #endif - } - dY = Y1-Y0; - if (dY) { - dX1 = (Scrx[i1] - X1) / dY; - pl_Float v=1.0/dY; - dZ1 = (Z2 - Z1) * v; - for(a=0;a<3;a++) dC1[a] = (pl_sInt32) ((C2[a] - C1[a]) * v); - dU1 = (MappingU2 - U1) * v; - dV1 = (MappingV2 - V1) * v; - #ifdef PL_PF_MULTITEX - dU1_2 = (MappingU2_2 - U1_2) * v; - dV1_2 = (MappingV2_2 - V1_2) * v; - #endif - if (dX2 < dX1) { - SWAP(dX1,dX2,pl_sInt32); - SWAP(dU1,dU2,pl_Float); - SWAP(dV1,dV2,pl_Float); - #ifdef PL_PF_MULTITEX - SWAP(dU1_2,dU2_2,pl_Float); - SWAP(dV1_2,dV2_2,pl_Float); - #endif - SWAP(dZ1,dZ2,pl_Float); - for(a=0;a<3;a++) - SWAP(dC1[a],dC2[a],pl_sInt32); - stat = 2; - } else stat = 1; - Z2 = Z1; - C2[0] = C1[0]; - C2[1] = C1[1]; - C2[2] = C1[2]; - - } else { - if (Scrx[i1] > X1) { - X2 = Scrx[i1]; - U2 = MappingU2; - V2 = MappingV2; - #ifdef PL_PF_MULTITEX - U2_2 = MappingU2_2; - V2_2 = MappingV2_2; - #endif - stat = 2|4; - } else { - X1 = Scrx[i1]; - SWAP(Z1,Z2,pl_Float) - for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32); - U1 = MappingU2; - V1 = MappingV2; - #ifdef PL_PF_MULTITEX - U1_2 = MappingU2_2; - V1_2 = MappingV2_2; - #endif - stat = 1|8; - } - } - pl_sInt32 tmp = (dX1-dX2)*dY; - if (tmp) { - pl_Float v=(1<>XPOS_BITS; - pl_sInt32 Xlen = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; - if (Xlen > 0) { - pl_sInt32 iUL, iVL, idUL, idVL, iULnext, iVLnext; - pl_Float UL = U1; - pl_Float VL = V1; -#ifdef PL_PF_MULTITEX - pl_sInt32 iUL_2, iVL_2, idUL_2, idVL_2, iULnext_2, iVLnext_2; - pl_Float UL_2 = U1_2; - pl_Float VL_2 = V1_2; -#endif - pl_sInt32 CL[3] = {C1[0],C1[1], C1[2]}; - pl_Float pZL,ZL; - pl_Float t = 1.0f / (pZL = ZL = Z1); - gmem += XL1; - zbuf += XL1; - - XL1 += Xlen; // update to new line end pos so we can adjust gmem/zbuf later - iULnext = ((pl_sInt32) (UL*t)); - iVLnext = ((pl_sInt32) (VL*t)); -#ifdef PL_PF_MULTITEX - iULnext_2 = ((pl_sInt32) (UL_2*t)); - iVLnext_2 = ((pl_sInt32) (VL_2*t)); -#endif - do { - UL += dUL; - VL += dVL; - iUL = iULnext; - iVL = iVLnext; - pZL += pdZL; - t = 1.0f/pZL; - iULnext = ((pl_sInt32) (UL*t)); - iVLnext = ((pl_sInt32) (VL*t)); - idUL = (iULnext - iUL)>>nmb; - idVL = (iVLnext - iVL)>>nmb; - if (idUL>MappingU_Max) idUL=MappingU_Max; - else if (idUL<-MappingU_Max) idUL=-MappingU_Max; - if (idVL>MappingV_Max) idVL=MappingV_Max; - else if (idVL<-MappingV_Max) idVL=-MappingV_Max; - - // todo: this is slow as shit, should we force textures to be powers of two? hehe - if (iUL<0) do iUL+=MappingU_Max; while (iUL<0); - else while (iUL >= MappingU_Max) iUL-=MappingU_Max; - if (iVL<0) do iVL+=MappingV_Max; while (iVL<0); - else while (iVL >= MappingV_Max) iVL-=MappingV_Max; - -#ifdef PL_PF_MULTITEX - UL_2 += dUL_2; - VL_2 += dVL_2; - iUL_2 = iULnext_2; - iVL_2 = iVLnext_2; - iULnext_2 = ((pl_sInt32) (UL_2*t)); - iVLnext_2 = ((pl_sInt32) (VL_2*t)); - idUL_2 = (iULnext_2 - iUL_2)>>nmb; - idVL_2 = (iVLnext_2 - iVL_2)>>nmb; - if (idUL_2>MappingU_Max_2) idUL_2=MappingU_Max_2; - else if (idUL_2<-MappingU_Max_2) idUL_2=-MappingU_Max_2; - if (idVL_2>MappingV_Max_2) idVL_2=MappingV_Max_2; - else if (idVL_2<-MappingV_Max_2) idVL_2=-MappingV_Max_2; - - // todo: this is slow as shit, should we force textures to be powers of two? hehe - if (iUL_2<0) do iUL_2+=MappingU_Max_2; while (iUL_2<0); - else while (iUL_2 >= MappingU_Max_2) iUL_2-=MappingU_Max_2; - if (iVL_2<0) do iVL_2+=MappingV_Max_2; while (iVL_2<0); - else while (iVL_2 >= MappingV_Max_2) iVL_2-=MappingV_Max_2; - -#endif - - pl_uInt n = nm; - Xlen -= n; - if (Xlen < 0) n += Xlen; - if (zfb_width) do { - if (*zbuf < ZL) { - *zbuf = (pl_ZBuffer) ZL; - - #ifdef PL_PF_MULTITEX - TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, - iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2, - bilinear2, iUL_2,iVL_2, - tex_w_2,tex_h_2, - texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2); - #else - TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL, - tex_w,tex_h, - texture,tex_rowspan,texcomb,texalpha,texalpha2); - #endif - - } - zbuf++; - gmem++; - ZL += dZL; - CL[0] += dCL[0]; - CL[1] += dCL[1]; - CL[2] += dCL[2]; - iUL += idUL; - iVL += idVL; - - if (iUL<0) iUL+=MappingU_Max; - else if (iUL >= MappingU_Max) iUL -= MappingU_Max; - if (iVL<0) iVL+=MappingV_Max; - else if (iVL >= MappingV_Max) iVL -= MappingV_Max; -#ifdef PL_PF_MULTITEX - iUL_2 += idUL_2; - iVL_2 += idVL_2; - - if (iUL_2<0) iUL_2+=MappingU_Max_2; - else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2; - if (iVL_2<0) iVL_2+=MappingV_Max_2; - else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2; -#endif - } while (--n); - else do { - - #ifdef PL_PF_MULTITEX - TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, - iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2, - bilinear2, iUL_2,iVL_2, - tex_w_2,tex_h_2, - texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2); - #else - TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL, - tex_w,tex_h, - texture,tex_rowspan,texcomb,texalpha,texalpha2); - #endif - - - gmem++; - CL[0] += dCL[0]; - CL[1] += dCL[1]; - CL[2] += dCL[2]; - iUL += idUL; - iVL += idVL; - - if (iUL<0) iUL+=MappingU_Max; - else if (iUL >= MappingU_Max) iUL -= MappingU_Max; - if (iVL<0) iVL+=MappingV_Max; - else if (iVL >= MappingV_Max) iVL -= MappingV_Max; - -#ifdef PL_PF_MULTITEX - iUL_2 += idUL_2; - iVL_2 += idVL_2; - - if (iUL_2<0) iUL_2+=MappingU_Max_2; - else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2; - if (iVL_2<0) iVL_2+=MappingV_Max_2; - else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2; -#endif - - } while (--n); - } while (Xlen > 0); - gmem += swidth-XL1; - zbuf += zfb_width-XL1; - } else { // xlen <=0 ,no drawing - gmem += swidth; - zbuf += zfb_width; - } - Z1 += dZ1; - U1 += dU1; - V1 += dV1; -#ifdef PL_PF_MULTITEX - U1_2 += dU1_2; - V1_2 += dV1_2; -#endif - X1 += dX1; - X2 += dX2; - C1[0] += dC1[0]; - C1[1] += dC1[1]; - C1[2] += dC1[2]; - } -} - - - diff --git a/WDL/plush2/pl_putface.cpp b/WDL/plush2/pl_putface.cpp deleted file mode 100644 index 259e82e4..00000000 --- a/WDL/plush2/pl_putface.cpp +++ /dev/null @@ -1,707 +0,0 @@ -#include "plush.h" -#include "../lice/lice_combine.h" - -//#define PLUSH_NO_SOLIDFLAT // make non-texturemapped flat shading optimized engine -//#define PLUSH_NO_SOLIDGOURAUD // disable non-texturemapped gouraud optimized engine -//#define PLUSH_NO_TEXTURE // disable single-texture optimized engine -//#define PLUSH_NO_MULTITEXTURE // disable multitexture (this can do any of em) -#define XPOS_BITS 19 // allows 2^13 max screen width, or 8192px - -#define SWAP(a,b,t) { t ____tmp=(a); (a)=(b); (b)=____tmp; } - -#define PUTFACE_SORT() \ - char i0 = 0; char i1 = 1; char i2 = 2; char stat; \ - if (TriFace->Scry[0] > TriFace->Scry[1]) { i0 = 1; i1 = 0; } \ - if (TriFace->Scry[i0] > TriFace->Scry[2]) { SWAP(i0,i2,char); } \ - if (TriFace->Scry[i1] > TriFace->Scry[i2]) { SWAP(i1,i2,char); } \ - int Scrx[3] = {(int)(TriFace->Scrx[0]*(1<Scrx[1]*(1<Scrx[2]*(1<Scry[0]+0.5), (int) (TriFace->Scry[1]+0.5), (int) (TriFace->Scry[2]+0.5)}; \ - -#define DO_STAT_XDELTAS \ - if (stat & 1) { \ - dX1 = (Scrx[i2]-(X1 = Scrx[i1]))/dY; \ - if (stat & 8) dX2 = (Scrx[i2]-(X2 = Scrx[i0]))/dY; \ - } \ - else if (stat & 2) { \ - dX2 = (Scrx[i2]-(X2 = Scrx[i1]))/dY; \ - if (stat & 4) dX1 = (Scrx[i2]-(X1 = Scrx[i0]))/dY; \ - } - - -static inline void OverlayBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int usea) -{ - int da=(256-usea)*128; - int srcr = r*usea+da, srcg = g*usea+da, srcb = b*usea+da, srca = usea*a + da; - red = ( red*( (red*(32768-srcr))/256 + srcr ) )/32768; - green = ( green*( (green*(32768-srcg))/256 + srcg ) )/32768; - blue = ( blue*( (blue*(32768-srcb))/256 + srcb ) )/32768; - alpha = ( alpha*( (alpha*(32768-srca))/256 + srca ) )/32768; -} - -static inline void MulBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta) -{ - int ta2=(256-ta)*256; - red = (r*ta*red + red*ta2)/65536; - green = (g*ta*green + green*ta2)/65536; - blue = (b*ta*blue + blue*ta2)/65536; - alpha = (a*ta*alpha + alpha*ta2)/65536; -} - - -static inline void AdjustHSV(int &red, int &green, int &blue, int r, int g, int b, int texalpha) -{ - int h,s,v; - __LICE_RGB2HSV(red,green,blue,&h,&s,&v); - h+=(((r+r/2) - 192) * texalpha)/256; - if (h<0)h+=384; - else if (h>=384) h-=384; - s+=((g-128)*texalpha)/256; - if (s&~0xff) - { - if (s<0)s=0; - else s=255; - } - v+=((b-128)*texalpha)/256; - if (v&~0xff) - { - if (v<0)v=0; - else v=255; - } - __LICE_HSV2RGB(h,s,v,&red,&green,&blue); -} - -static inline void DodgeBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta) -{ - int src_r = 256-r*ta/256; - int src_g = 256-g*ta/256; - int src_b = 256-b*ta/256; - int src_a = 256-(a*ta)/256; - - red = src_r > 1 ? 256*red / src_r : 256*red; - green = src_g > 1 ? 256*green / src_g : 256*green; - blue = src_b > 1 ? 256*blue / src_b : 256*blue; - alpha = src_a > 1 ? 256*alpha / src_a : 256*alpha; -} - - -static void inline DoTextureCombine(int texcomb, int r, int g, int b, int a, int &red, int &green, int &blue, int &alpha, int texalpha, int texalpha2) -{ - switch (texcomb) - { - case LICE_BLIT_MODE_COPY: - red = (r*texalpha + red*texalpha2)/256; - green = (g*texalpha + green*texalpha2)/256; - blue = (b*texalpha + blue*texalpha2)/256; - alpha = (a*texalpha + alpha*texalpha2)/256; - break; - case LICE_BLIT_MODE_ADD: - red += (r*texalpha)/256; - green += (g*texalpha)/256; - blue += (b*texalpha)/256; - alpha += (a*texalpha)/256; - break; - case LICE_BLIT_MODE_MUL: - MulBlend(red,green,blue,alpha,r,g,b,a,texalpha); - break; - case LICE_BLIT_MODE_DODGE: - DodgeBlend(red,green,blue,alpha,r,g,b,a,texalpha); - - break; - case LICE_BLIT_MODE_OVERLAY: - OverlayBlend(red,green,blue,alpha,r,g,b,a, texalpha); - break; - case LICE_BLIT_MODE_HSVADJ: - AdjustHSV(red,green,blue,r,g,b,texalpha); - break; - case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA: - { - int ta=(texalpha*(a+1)); - int ta2=(65536-ta); - red = (r*ta + red*ta2)/65536; - green = (g*ta + green*ta2)/65536; - blue = (b*ta + blue*ta2)/65536; - alpha = (a*ta + alpha*ta2)/65536; - } - break; - case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA: - { - int ta=(texalpha*(a+1)); - red += (r*ta)/65536; - green += (g*ta)/65536; - blue += (b*ta)/65536; - alpha += (a*ta)/65536; - } - break; - case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA: - { - int ta=(texalpha*(a+1))/256; - DodgeBlend(red,green,blue,alpha,r,g,b,a,ta); - } - break; - case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA: - MulBlend(red,green,blue,alpha,r,g,b,a,(texalpha*(a+1))/256); - break; - case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA: - OverlayBlend(red,green,blue,alpha,r,g,b,a, (texalpha*(a+1))/256); - break; - case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA: - AdjustHSV(red,green,blue,r,g,b,(texalpha*(a+1))/256); - break; - case -2: - break; - default: - red=r; green=g; blue=b; alpha=a; - break; - } -} - - -static void inline TextureMakePixelSolidCombine(int &red, int &green, int &blue, int &alpha, - pl_sInt32 *CL, int solidcomb, int solidalpha, - int solidalpha2, - LICE_pixel_chan *gmemptr) -{ - - switch (solidcomb) - { - case LICE_BLIT_MODE_COPY: - red = (CL[0]/256*solidalpha + gmemptr[LICE_PIXEL_R]*solidalpha2)/65536; - green = (CL[1]/256*solidalpha + gmemptr[LICE_PIXEL_G]*solidalpha2)/65536; - blue = (CL[2]/256*solidalpha + gmemptr[LICE_PIXEL_B]*solidalpha2)/65536; - alpha = solidalpha; - break; - case LICE_BLIT_MODE_ADD: - red = gmemptr[LICE_PIXEL_R] + (CL[0]/256*solidalpha)/65536; - green = gmemptr[LICE_PIXEL_G] + (CL[1]/256*solidalpha)/65536; - blue = gmemptr[LICE_PIXEL_B] + (CL[2]/256*solidalpha)/65536; - alpha = gmemptr[LICE_PIXEL_A] + solidalpha; - break; - case LICE_BLIT_MODE_DODGE: - red=gmemptr[LICE_PIXEL_R]; - green=gmemptr[LICE_PIXEL_G]; - blue=gmemptr[LICE_PIXEL_B]; - alpha=gmemptr[LICE_PIXEL_A]; - DodgeBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha,solidalpha); - break; - case LICE_BLIT_MODE_MUL: - red=gmemptr[LICE_PIXEL_R]; - green=gmemptr[LICE_PIXEL_G]; - blue=gmemptr[LICE_PIXEL_B]; - alpha=gmemptr[LICE_PIXEL_A]; - MulBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha,solidalpha); - break; - case LICE_BLIT_MODE_OVERLAY: - red=gmemptr[LICE_PIXEL_R]; - green=gmemptr[LICE_PIXEL_G]; - blue=gmemptr[LICE_PIXEL_B]; - alpha=gmemptr[LICE_PIXEL_A]; - OverlayBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha, solidalpha); - break; - case LICE_BLIT_MODE_HSVADJ: - red=gmemptr[LICE_PIXEL_R]; - green=gmemptr[LICE_PIXEL_G]; - blue=gmemptr[LICE_PIXEL_B]; - alpha=gmemptr[LICE_PIXEL_A]; - AdjustHSV(red,green,blue,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha); - break; - case -2: - red=gmemptr[LICE_PIXEL_R]; - green=gmemptr[LICE_PIXEL_G]; - blue=gmemptr[LICE_PIXEL_B]; - alpha=gmemptr[LICE_PIXEL_A]; - break; - default: - red=CL[0]/65536; - green=CL[1]/65536; - blue=CL[2]/65536; - alpha=solidalpha; - break; - } -} - - -static void inline TextureMakePixel2(LICE_pixel_chan *gmemptr, - int solidcomb, int solidalpha, int solidalpha2, - pl_sInt32 *CL, - bool bilinear, - pl_sInt32 iUL, pl_sInt32 iVL, - pl_sInt32 texwidth, pl_sInt32 texheight, - LICE_pixel *texture, int tex_rowspan, - int texcomb, - int texalpha, - int texalpha2, - bool bilinear2, - pl_sInt32 iUL_2, pl_sInt32 iVL_2, - pl_sInt32 texwidth_2, pl_sInt32 texheight_2, - LICE_pixel *texture2, int tex_rowspan_2, - int tex2comb, - int tex2alpha, - int tex2alpha2) -{ - - int red,green,blue,alpha; - - TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr); - - int r,g,b,a; - - int xpos=iUL>>16; - int ypos=iVL>>16; - LICE_pixel_chan *rd = (LICE_pixel_chan*)(texture + xpos+ypos*tex_rowspan); - -#if defined(PLUSH_NO_TEXTURE) - if (texture) -#endif - { - if (bilinear) - { - __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, - ypos < texheight - 1 ? (rd+tex_rowspan*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture+xpos), - xpos < texwidth - 1 ? 1 : 1-texwidth, - iUL&65535,iVL&65535); - } - else - { - r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; - } - - DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2); - } - -#ifdef PLUSH_NO_TEXTURE - if (texture2) -#endif - { - xpos=iUL_2>>16; - ypos=iVL_2>>16; - rd = (LICE_pixel_chan*)(texture2 + xpos+ypos*tex_rowspan_2); - - if (bilinear2) - { - __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, - ypos < texheight_2 - 1 ? (rd+tex_rowspan_2*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture2+xpos), - xpos < texwidth_2 - 1 ? 1 : 1-texwidth_2, - iUL_2&65535,iVL_2&65535); - } - else - { - r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; - } - - DoTextureCombine(tex2comb, r,g,b,a, red,green,blue,alpha,tex2alpha,tex2alpha2); - } - - _LICE_MakePixelClamp(gmemptr, red,green,blue,alpha); -} - -static void inline TextureMakePixel(LICE_pixel_chan *gmemptr, - int solidcomb, int solidalpha, int solidalpha2, - pl_sInt32 *CL, - bool bilinear, - pl_sInt32 iUL, pl_sInt32 iVL, - pl_sInt32 texwidth, pl_sInt32 texheight, - LICE_pixel *texture, int tex_rowspan, - int texcomb, - int texalpha, - int texalpha2) -{ - - int red,green,blue,alpha; - - if ( -#ifdef PLUSH_NO_SOLIDGOURAUD - !texture|| -#endif - texcomb!=-1) - TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr); - - - -#ifdef PLUSH_NO_SOLIDGOURAUD - if (texture) -#endif - { - int r,g,b,a; - int xpos=iUL>>16; - int ypos=iVL>>16; - LICE_pixel_chan *rd = (LICE_pixel_chan*)(texture + xpos+ypos*tex_rowspan); - - if (bilinear) - { - - __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, - ypos < texheight - 1 ? (rd+tex_rowspan*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture+xpos), - xpos < texwidth - 1 ? 1 : 1-texwidth, - iUL&65535,iVL&65535); - } - else - { - r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; - } - - DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2); - } - - _LICE_MakePixelClamp(gmemptr, red,green,blue,alpha); -} - - - -#ifndef PLUSH_NO_TEXTURE -#include "pl_pf_tex.h" -#endif - -#ifndef PLUSH_NO_MULTITEXTURE -#define PL_PF_MULTITEX -#include "pl_pf_tex.h" -#endif - - - - -template class PLSolidPutFace -{ - public: -#ifndef PLUSH_NO_SOLIDGOURAUD - static void SolidGouraud(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width) - { - pl_Float dZL=0, dZ1=0, dZ2=0; - pl_sInt32 dX1=0, dX2=0, C1[3], C2[3], dC1[3]={0}, dC2[3]={0}, dCL[3]={0}, C3[3]; - - PUTFACE_SORT(); - - - int a; - for(a=0;a<3;a++) - { - C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24)); - C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24)); - C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24)); - } - pl_sInt32 X2,X1; - X2 = X1 = Scrx[i0]; - pl_Float Z1 = TriFace->Scrz[i0]; - pl_Float Z2 = TriFace->Scrz[i1]; - pl_Float Z3 = TriFace->Scrz[i2]; - - pl_sInt32 Y0 = Scry[i0]; - pl_sInt32 Y1 = Scry[i1]; - pl_sInt32 Y2 = Scry[i2]; - - { - pl_sInt32 dY = Y2 - Y0; - if (dY) { - dX2 = (Scrx[i2] - X1) / dY; - for(a=0;a<3;a++) dC2[a] = (C3[a] - C1[a]) / dY; - dZ2 = (Z3 - Z1) / dY; - } - dY = Y1 - Y0; - if (dY) { - dX1 = (Scrx[i1] - X1) / dY; - for(a=0;a<3;a++) - dC1[a] = (C2[a] - C1[a]) / dY; - dZ1 = (Z2 - Z1) / dY; - if (dX2 < dX1) { - SWAP(dX2,dX1,pl_sInt32); - for(a=0;a<3;a++) SWAP(dC1[a],dC2[a],pl_sInt32); - SWAP(dZ1,dZ2,pl_Float); - stat = 2; - } else stat = 1; - Z2 = Z1; - C2[0] = C1[0]; - C2[1] = C1[1]; - C2[2] = C1[2]; - } else { - if (Scrx[i1] > X1) { - X2 = Scrx[i1]; - stat = 2|4; - } else { - for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32); - SWAP(Z1,Z2,pl_Float); - X1 = Scrx[i1]; - stat = 1|8; - } - } - - pl_sInt32 tmp = (dX1-dX2)*dY; - if (tmp) { - double v=(1<>XPOS_BITS; - pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; - if (XL2 > 0) { - gmem += XL1; - XL1 += XL2; - pl_sInt32 CL[3] = {C1[0],C1[1],C1[2]}; - if (zbuf) - { - pl_Float ZL = Z1; - zbuf += XL1-XL2; - do { - if (*zbuf < ZL) { - *zbuf = (pl_ZBuffer) ZL; - - Comb::doPix((LICE_pixel_chan *)gmem,CL[0]/65536,CL[1]/65536,CL[2]/65536,255,alpha); - } - gmem++; - zbuf++; - ZL += dZL; - CL[0] += dCL[0]; - CL[1] += dCL[1]; - CL[2] += dCL[2]; - } while (--XL2); - zbuf -= XL1; - } - else do { - Comb::doPix((LICE_pixel_chan *)gmem,CL[0]/65536,CL[1]/65536,CL[2]/65536,255,alpha); - gmem++; - CL[0] += dCL[0]; - CL[1] += dCL[1]; - CL[2] += dCL[2]; - } while (--XL2); - gmem -= XL1; - } - gmem += swidth; - zbuf += zfb_width; - X1 += dX1; - X2 += dX2; - C1[0] += dC1[0]; - C1[1] += dC1[1]; - C1[2] += dC1[2]; - Z1 += dZ1; - Y0++; - } - } -#endif - -#ifndef PLUSH_NO_SOLIDFLAT - static void Solid(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width) - { - pl_sInt32 dX1=0, dX2=0; - pl_Float dZL=0, dZ1=0, dZ2=0; - - PUTFACE_SORT(); - - int col0 = (int) (TriFace->Shades[0][0]*255.0); - int col1 = (int) (TriFace->Shades[0][1]*255.0); - int col2 = (int) (TriFace->Shades[0][2]*255.0); - - pl_sInt32 X1,X2; - X2 = X1 = Scrx[i0]; - pl_sInt32 Y0 = Scry[i0]; - pl_sInt32 Y1 = Scry[i1]; - pl_sInt32 Y2 = Scry[i2]; - - pl_Float Z1 = TriFace->Scrz[i0]; - pl_Float Z2 = TriFace->Scrz[i1]; - pl_Float Z3 = TriFace->Scrz[i2]; - - { - pl_sInt32 dY = Y2-Y0; - if (dY) { - dX2 = (Scrx[i2] - X1) / dY; - dZ2 = (Z3 - Z1) / dY; - } - dY = Y1-Y0; - if (dY) { - dX1 = (Scrx[i1] - X1) / dY; - dZ1 = (Z2 - Z1) / dY; - if (dX2 < dX1) { - SWAP(dX1,dX2,pl_sInt32); - SWAP(dZ1,dZ2,pl_Float); - stat = 2; - } else stat = 1; - Z2 = Z1; - } else { - if (Scrx[i1] > X1) { - X2 = Scrx[i1]; - stat = 2|4; - } else { - X1 = Scrx[i1]; - SWAP(Z1,Z2,pl_Float); - stat = 1|8; - } - } - - if (zbuf) - { - pl_sInt32 tmp=(dX1-dX2)*dY; - if (tmp) dZL = ((dZ1-dZ2)*dY)*(double)(1<>XPOS_BITS; - pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; - if (XL2 > 0) { - gmem += XL1; - XL1 += XL2; - if (zbuf) - { - pl_Float ZL = Z1; - zbuf += XL1-XL2; - do { - if (*zbuf < ZL) { - *zbuf = (pl_ZBuffer) ZL; - Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha); - } - gmem++; - zbuf++; - ZL += dZL; - } while (--XL2); - zbuf -= XL1; - } - else - { - do { - Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha); - gmem++; - } while (--XL2); - } - gmem -= XL1; - - } - gmem += swidth; - zbuf += zfb_width; - Z1 += dZ1; - X1 += dX1; - X2 += dX2; - Y0++; - } - } -#endif -}; - -void pl_Cam::PutFace(pl_Face *TriFace) -{ - LICE_pixel *gmem = frameBuffer->getBits(); - - int zfb_width = 0; - pl_ZBuffer *zb = NULL; - if (zBuffer.GetSize()&&TriFace->Material->zBufferable) - { - zfb_width = frameBuffer->getWidth(); - zb = zBuffer.Get(); - } - - int swidth = frameBuffer->getRowSpan(); - if (frameBuffer->isFlipped()) - { - gmem += swidth*(frameBuffer->getHeight()-1); - swidth=-swidth; - } - - pl_Mat *mat=TriFace->Material; - -#ifndef PLUSH_NO_MULTITEXTURE - - #ifndef PLUSH_NO_TEXTURE - if (mat->Texture&&mat->Texture2) - #else - #ifndef PLUSH_NO_SOLIDGOURAUD - if (mat->Texture||mat->Texture2) - #endif - #endif - { - pl_Float texsc[4]; - memcpy(texsc,mat->TexScaling,sizeof(mat->TexScaling)); - memcpy(texsc+2,mat->Tex2Scaling,sizeof(mat->Tex2Scaling)); - int tidx = mat->TexMapIdx; - if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; - int tidx2 = mat->Tex2MapIdx; - if (tidx2<0 || tidx2>=PLUSH_MAX_MAPCOORDS)tidx2=PLUSH_MAX_MAPCOORDS-1; - - PLMTexTri(gmem,swidth,TriFace,zb,zfb_width,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode, - mat->Texture,texsc,(int) (mat->TexOpacity*256.0),mat->TexCombineMode,tidx, - mat->Texture2,(int) (mat->Tex2Opacity*256.0),mat->Tex2CombineMode,tidx2 - ); - return; - } -#endif - - -#ifndef PLUSH_NO_TEXTURE - #ifndef PLUSH_NO_SOLIDGOURAUD - if (mat->Texture||mat->Texture2) - #endif - { - LICE_IBitmap *tex=mat->Texture ? mat->Texture : mat->Texture2; - int talpha = (int) (mat->Texture ? mat->TexOpacity*256.0 : mat->Tex2Opacity*256.0); - int tcomb = (int) (mat->Texture ? mat->TexCombineMode : mat->Tex2CombineMode); - int tidx = (mat->Texture ? mat->TexMapIdx: mat->Tex2MapIdx); - if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; - pl_Float texsc[2]; - memcpy(texsc,mat->Texture ? mat->TexScaling : mat->Tex2Scaling,sizeof(texsc)); - PLTexTri(gmem,swidth,TriFace,zb,zfb_width,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,tex,texsc,talpha,tcomb,tidx); - return; - } -#endif - - int alpha=(int) (mat->SolidOpacity*256.0); - if (!alpha) return; -#ifndef PLUSH_NO_SOLIDGOURAUD -#ifndef PLUSH_NO_SOLIDFLAT - if (mat->Smoothing) -#endif - { - #define __LICE__ACTION(comb) PLSolidPutFace::SolidGouraud(gmem,swidth,TriFace,alpha,zb,zfb_width); - __LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true); - #undef __LICE__ACTION - return; - } -#endif - -#ifndef PLUSH_NO_SOLIDFLAT - - #define __LICE__ACTION(comb) PLSolidPutFace::Solid(gmem,swidth,TriFace,alpha,zb,zfb_width); - __LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true); - #undef __LICE__ACTION - -#endif // PLUSH_NO_SOLIDFLAT -} - - diff --git a/WDL/plush2/pl_read_3ds.cpp b/WDL/plush2/pl_read_3ds.cpp deleted file mode 100644 index 11086346..00000000 --- a/WDL/plush2/pl_read_3ds.cpp +++ /dev/null @@ -1,347 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -read_3ds.c -3DS Object Reader -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - -typedef struct -{ - pl_uInt16 id; - void (*func)(pl_uChar *ptr, pl_uInt32 p); -} _pl_3DSChunk; - -static pl_Obj *obj; -static pl_Obj *bobj; -static pl_Obj *lobj; -static pl_sInt16 currentobj; -static pl_Mat *_m; - -static pl_Float _pl3DSReadFloat(pl_uChar **ptr); -static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr); -static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr); -static void _pl3DSChunkReader(pl_uChar *ptr, int len); -static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p); -static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p); -static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as); -static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p); -static void _pl3DSTriMeshReader(pl_uChar *f, pl_uInt32 p); -static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p); -static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p); -static void _pl3DSFaceMatReader(pl_uChar *f, pl_uInt32 p); -static void MapListReader(pl_uChar *f, pl_uInt32 p); -static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id); - -static _pl_3DSChunk _pl3DSChunkNames[] = { - {0x4D4D,NULL}, /* Main */ - {0x3D3D,NULL}, /* Object Mesh */ - {0x4000,_pl3DSObjBlockReader}, - {0x4100,_pl3DSTriMeshReader}, - {0x4110,_pl3DSVertListReader}, - {0x4120,_pl3DSFaceListReader}, - {0x4130,_pl3DSFaceMatReader}, - {0x4140,MapListReader}, - {0xAFFF,NULL}, /* Material */ - {0xA010,NULL}, /* Ambient */ - {0xA020,NULL}, /* Diff */ - {0xA030,NULL}, /* Specular */ - {0xA200,NULL}, /* Texture */ - {0x0010,_pl3DSRGBFReader}, - {0x0011,_pl3DSRGBBReader}, -}; - -pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m) -{ - FILE *f = fopen(fn, "rb"); - if (!f) return 0; - fseek(f, 0, 2); - pl_uInt32 p = ftell(f); - rewind(f); - - WDL_HeapBuf buf; - buf.Resize(p); - int s = fread(buf.Get(), 1, p, f); - fclose(f); - - if(!s) return 0; - - return plRead3DSObj(buf.Get(), s, m); -} - -pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m) -{ -#ifdef _WIN32 - HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "3DS"); - if(!hResource) return NULL; - - DWORD imageSize = SizeofResource(hInst, hResource); - if(imageSize < 6) return NULL; - - HGLOBAL res = LoadResource(hInst, hResource); - const void* pResourceData = LockResource(res); - if(!pResourceData) return NULL; - - unsigned char *data = (unsigned char *)pResourceData; - - pl_Obj *o = plRead3DSObj(data, imageSize, m); - - DeleteObject(res); - - return o; -#else - return 0; -#endif -} - -pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m) -{ - _m = m; - obj = bobj = lobj = 0; - currentobj = 0; - - _pl3DSChunkReader((pl_uChar *)ptr, size); - - return bobj; -} - -static pl_Float _pl3DSReadFloat(pl_uChar **ptr) { - pl_uInt32 *i; - pl_IEEEFloat32 c; - i = (pl_uInt32 *) &c; - *i = _pl3DSReadDWord(ptr); - return ((pl_Float) c); -} - -static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr) -{ - pl_uInt32 r; - pl_uChar *p = *ptr; - r = *p++; - r |= (*p++)<<8; - r |= (*p++)<<16; - r |= (*p++)<<24; - *ptr += 4; - return r; -} - -static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr) -{ - pl_uInt16 r; - pl_uChar *p = *ptr; - r = *p++; - r |= (*p++)<<8; - *ptr += 2; - return r; -} - -static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p) -{ - pl_Float c[3]; - if(p < 3*4) return; - c[0] = _pl3DSReadFloat(&f); - c[1] = _pl3DSReadFloat(&f); - c[2] = _pl3DSReadFloat(&f); -} - -static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p) -{ - unsigned char c[3]; - if(p < 3) return; - memcpy(c, f, sizeof(c)); -} - -static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as) -{ - int l = 0; - while (*ptr && p>0) - { - if(as) *as++ = *ptr; - ptr++; - l++; - p--; - } - if(as) *as = 0; - return l+1; -} - -static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p) -{ - int l = _pl3DSASCIIZReader(ptr, p, 0); - ptr += l; - p -= l; - _pl3DSChunkReader(ptr, p); -} - -static void _pl3DSTriMeshReader(pl_uChar *ptr, pl_uInt32 p) -{ - pl_uInt32 i; - pl_Face *face; - obj = new pl_Obj; - _pl3DSChunkReader(ptr, p); - i = obj->Faces.GetSize(); - face = obj->Faces.Get(); - while (i--) - { - pl_Vertex *vp=obj->Vertices.Get(); - pl_Vertex *fVertices[3] = { - vp+face->VertexIndices[0], - vp+face->VertexIndices[1], - vp+face->VertexIndices[2], - }; - face->MappingU[0][0] = fVertices[0]->xformedx; - face->MappingV[0][0] = fVertices[0]->xformedy; - face->MappingU[0][1] = fVertices[1]->xformedx; - face->MappingV[0][1] = fVertices[1]->xformedy; - face->MappingU[0][2] = fVertices[2]->xformedx; - face->MappingV[0][2] = fVertices[2]->xformedy; - face++; - } - obj->CalculateNormals(); - if (currentobj == 0) - { - currentobj = 1; - lobj = bobj = obj; - } - else - { - lobj->Children.Add(obj); - lobj = obj; - } -} - -static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p) -{ - pl_uInt16 nv; - pl_Vertex *v; - int len = (int)p; - nv = _pl3DSReadWord(&f); - len -= 2; - if(len <= 0) return; - obj->Vertices.Resize(nv); - v = obj->Vertices.Get(); - while (nv--) - { - memset(v,0,sizeof(pl_Vertex)); - v->x = _pl3DSReadFloat(&f); - v->y = _pl3DSReadFloat(&f); - v->z = _pl3DSReadFloat(&f); - len -= 3*4; - if(len < 0) return; - v++; - } -} - -static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p) -{ - pl_uInt16 nv; - pl_uInt16 c[3]; - pl_uInt16 flags; - pl_Face *face; - int len = (int)p; - - nv = _pl3DSReadWord(&f); - len -= 2; - if(len <= 0) return; - obj->Faces.Resize(nv); - face = obj->Faces.Get(); - while (nv--) - { - memset(face,0,sizeof(pl_Face)); - c[0] = _pl3DSReadWord(&f); - c[1] = _pl3DSReadWord(&f); - c[2] = _pl3DSReadWord(&f); - flags = _pl3DSReadWord(&f); - len -= 4*2; - if(len < 0) return; - - face->VertexIndices[0] = (c[0]&0x0000FFFF); - face->VertexIndices[1] = (c[1]&0x0000FFFF); - face->VertexIndices[2] = (c[2]&0x0000FFFF); - face->Material = _m; - face++; - } - if(len) _pl3DSChunkReader(f, len); -} - -static void _pl3DSFaceMatReader(pl_uChar *ptr, pl_uInt32 p) -{ - pl_uInt16 n, nf; - - int l = _pl3DSASCIIZReader(ptr, p, 0); - ptr += l; - p -= l; - - n = _pl3DSReadWord(&ptr); - while (n--) - { - nf = _pl3DSReadWord(&ptr); - } -} - -static void MapListReader(pl_uChar *f, pl_uInt32 p) -{ - pl_uInt16 nv; - pl_Float c[2]; - pl_Vertex *v; - int len = (int) p; - nv = _pl3DSReadWord(&f); - len -= 2; - v = obj->Vertices.Get(); - if (nv == obj->Vertices.GetSize()) while (nv--) - { - c[0] = _pl3DSReadFloat(&f); - c[1] = _pl3DSReadFloat(&f); - len -= 2*4; - if (len < 0) return; - v->xformedx = c[0]; - v->xformedy = c[1]; - v++; - } -} - -static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id) -{ - pl_sInt16 i; - for (i = 0; i < sizeof(_pl3DSChunkNames)/sizeof(_pl3DSChunkNames[0]); i++) - if (id == _pl3DSChunkNames[i].id) return i; - return -1; -} - -static void _pl3DSChunkReader(pl_uChar *ptr, int len) -{ - pl_uInt32 hlen; - pl_uInt16 hid; - pl_sInt16 n; - - while (len > 0) - { - hid = _pl3DSReadWord(&ptr); - len -= 2; - if(len <= 0) return; - hlen = _pl3DSReadDWord(&ptr); - len -= 4; - if(len <= 0) return; - if (hlen == 0) return; - hlen -= 6; - n = _pl3DSFindChunk(hid); - if (n < 0) - { - ptr += hlen; - len -= hlen; - } - else - { - pl_uChar *p = ptr; - if (_pl3DSChunkNames[n].func != NULL) - _pl3DSChunkNames[n].func(p, hlen); - else - _pl3DSChunkReader(p, hlen); - - ptr += hlen; - len -= hlen; - } - } -} - diff --git a/WDL/plush2/pl_read_cob.cpp b/WDL/plush2/pl_read_cob.cpp deleted file mode 100644 index 1ed8187c..00000000 --- a/WDL/plush2/pl_read_cob.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -read_cob.c -ASCII COB Object Reader -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - -#define PL_COB_MAX_LINELENGTH 1024 - -pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat) { - FILE *fp = fopen(fn,"rt"); - int p1,m1,p2,m2,p3,m3; - char temp_string[PL_COB_MAX_LINELENGTH]; - float TransMatrix[4][4]; - pl_Obj *obj; - pl_sInt32 x,i2; - int numVertices, numMappingVertices, numFaces, i; - pl_Float *MappingVertices = 0; - if (!fp) return 0; - - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - if (memcmp("Caligari",temp_string,8)) { fclose(fp); return 0; } - - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("Transform",temp_string,9)); - if (feof(fp)) { fclose(fp); return 0; } - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - sscanf(temp_string,"%f %f %f %f", - &TransMatrix[0][0],&TransMatrix[0][1],&TransMatrix[0][2],&TransMatrix[0][3]); - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - sscanf(temp_string,"%f %f %f %f", - &TransMatrix[1][0],&TransMatrix[1][1],&TransMatrix[1][2],&TransMatrix[1][3]); - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - sscanf(temp_string,"%f %f %f %f", - &TransMatrix[2][0],&TransMatrix[2][1],&TransMatrix[2][2],&TransMatrix[2][3]); - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - sscanf(temp_string,"%f %f %f %f", - &TransMatrix[3][0],&TransMatrix[3][1],&TransMatrix[3][2],&TransMatrix[3][3]); - - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); - if (feof(fp) || sscanf(temp_string,"World Vertices %d",&numVertices) != 1) - { fclose(fp); return 0; } - - rewind(fp); - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); - if (feof(fp) || - sscanf(temp_string,"Texture Vertices %d",&numMappingVertices) != 1) { - fclose(fp); return 0; - } - - rewind(fp); - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("Faces",temp_string,5)); - if (feof(fp) || sscanf(temp_string,"Faces %d",&numFaces) != 1) { - fclose(fp); return 0; - } - for (x = numFaces; x; x--) { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - if (feof(fp) || sscanf(temp_string+4," verts %d",&i) != 1 || i < 3) { - fclose(fp); - return 0; - } - numFaces += i-3; - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } - obj = new pl_Obj(numVertices,numFaces); - if (!obj) { fclose(fp); return 0; } - rewind(fp); - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); - if (feof(fp)) { delete obj; fclose(fp); return 0; } - for (x = 0; x < numVertices; x ++) { - float xp, yp, zp; - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - if (feof(fp) || - sscanf(temp_string,"%f %f %f", &xp, &yp, &zp) != 3) { - delete obj; fclose(fp); return 0; - } - obj->Vertices.Get()[x].x = (TransMatrix[0][0]*xp+TransMatrix[0][1]*yp+ - TransMatrix[0][2]*zp+TransMatrix[0][3]); - obj->Vertices.Get()[x].y = (TransMatrix[1][0]*xp+TransMatrix[1][1]*yp+ - TransMatrix[1][2]*zp+TransMatrix[1][3]); - obj->Vertices.Get()[x].z = (TransMatrix[2][0]*xp+TransMatrix[2][1]*yp+ - TransMatrix[2][2]*zp+TransMatrix[2][3]); - } - rewind(fp); - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); - if (!feof(fp)) { - MappingVertices = (pl_Float *) - malloc(sizeof(pl_Float ) * numMappingVertices * 2); - if (MappingVertices) { - for (x = 0; x < numMappingVertices; x ++) { - float p1, p2; - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - if (feof(fp) || sscanf(temp_string,"%f %f", &p1, &p2) != 2) { - free(MappingVertices); delete obj; fclose(fp); return 0; - } - MappingVertices[x*2] = p1; - MappingVertices[x*2+1] = p2; - } - } - } - rewind(fp); - do { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - } while (!feof(fp) && memcmp("Faces",temp_string,5)); - if (feof(fp)) { - if (MappingVertices) free(MappingVertices); - delete obj; fclose(fp); return 0; - } - for (x = 0; x < numFaces; x ++) { - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - sscanf(temp_string+4," verts %d",&i); - fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); - if (i == 3) { - if (feof(fp) || sscanf(temp_string,"<%d,%d> <%d,%d> <%d,%d>", - &p3,&m3,&p2,&m2,&p1,&m1) != 6) { - if (MappingVertices) free(MappingVertices); - delete obj; fclose(fp); return 0; - } - obj->Faces.Get()[x].VertexIndices[0] = p1; - obj->Faces.Get()[x].VertexIndices[1] = p2; - obj->Faces.Get()[x].VertexIndices[2] = p3; - if (MappingVertices) { - obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m1*2]; - obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m1*2+1]; - obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m2*2]; - obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m2*2+1]; - obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m3*2]; - obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m3*2+1]; - } - obj->Faces.Get()[x].Material = mat; - } else { - int p[16],m[16]; - if (feof(fp)) { - if (MappingVertices) free(MappingVertices); - delete obj; fclose(fp); return 0; - } - sscanf(temp_string, - "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " - "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " - "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " - "<%d,%d> <%d,%d> <%d,%d> <%d,%d> ", - p+0,m+0,p+1,m+1,p+2,m+2,p+3,m+3, - p+4,m+4,p+5,m+5,p+6,m+6,p+7,m+7, - p+8,m+8,p+9,m+9,p+10,m+10,p+11,m+11, - p+12,m+12,p+13,m+13,p+14,m+14,p+15,m+15); - for (i2 = 1; i2 < (i-1); i2 ++) { - obj->Faces.Get()[x].VertexIndices[0] = p[0]; - obj->Faces.Get()[x].VertexIndices[1] = p[i2+1]; - obj->Faces.Get()[x].VertexIndices[2] = p[i2]; - if (MappingVertices) { - obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m[0]*2]; - obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m[0]*2+1]; - obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m[i2+1]*2]; - obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m[i2+1]*2+1]; - obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m[i2]*2]; - obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m[i2]*2+1]; - } - obj->Faces.Get()[x].Material = mat; - x++; - } - x--; - } - } - if (MappingVertices) free(MappingVertices); - obj->CalculateNormals(); - fclose(fp); - return obj; -} diff --git a/WDL/plush2/pl_read_jaw.cpp b/WDL/plush2/pl_read_jaw.cpp deleted file mode 100644 index 942e5e0c..00000000 --- a/WDL/plush2/pl_read_jaw.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -read_jaw.c -Jaw3D Object Reader -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************* - Notes on .JAW files: - This is a file format created by Jawed Karim for Jaw3D - (http://jaw3d.home.ml.org). - -- updated 11/6/00 - www.jawed.com - It is very simple, and lets one easily create ones own models using only - a text editor. The format is pretty simple: - The first line must be "Light: (x,y,z)" where x,y, and z are the x y and - z components of the lightsource vector (I think ;) - A series of lines, numbered 0 to n, in the format of - "i: x y z", where i is the vertex number (which should be listed in - order, and x y and z are the coordinates of that vertex. - A series of lines, having the format "tri a, b, c" where a b and c are - the vertices that the face uses. It is unclear at this time which - way the vertices are listed (ccw or cw), so just make em consistent - and you can always use plFlipObjectNormals() on the loaded object. - That is it! (I told ya it was simple). -******************************************************************************/ - -#include "plush.h" - -pl_Obj *plReadJAWObj(char *filename, pl_Mat *m) { - FILE *jawfile; - pl_Obj *obj; - pl_uInt32 i; - pl_sInt crap; - char line[256]; - pl_uInt32 total_points = 0, total_polys = 0; - if ((jawfile = fopen(filename, "r")) == NULL) return 0; - fgets(line, 256, jawfile); /* Ignores lightsource info */ - while (fgets(line, 256, jawfile) != NULL) - if (strstr(line, ":") != NULL) total_points++; - - rewind(jawfile); fgets(line, 256, jawfile); - while (fgets(line, 256, jawfile) != NULL) - if (strstr(line, "tri") != NULL) total_polys++; - - rewind(jawfile); fgets(line, 256, jawfile); - obj = new pl_Obj(total_points,total_polys); - - i = 0; - while (fgets(line, 256, jawfile) != NULL) if (strstr(line, ":") != NULL) { - float x, y, z; - sscanf(line, "%d: %f %f %f",&crap,&x,&y,&z); - obj->Vertices.Get()[i].x = (pl_Float) x; - obj->Vertices.Get()[i].y = (pl_Float) y; - obj->Vertices.Get()[i].z = (pl_Float) z; - i++; - } - rewind(jawfile); fgets(line, 256, jawfile); - i = 0; - while (fgets(line, 256, jawfile) != NULL) if (strstr(line, "tri") != NULL) { - pl_uInt32 a,b,c; - sscanf(line, "tri %ld, %ld, %ld", &a, &b, &c); - obj->Faces.Get()[i].VertexIndices[0] = a; - obj->Faces.Get()[i].VertexIndices[1] = c; - obj->Faces.Get()[i].VertexIndices[2] = b; - obj->Faces.Get()[i].Material = m; - i++; - } - fclose(jawfile); - obj->CalculateNormals(); - return obj; -} diff --git a/WDL/plush2/pl_spline.cpp b/WDL/plush2/pl_spline.cpp deleted file mode 100644 index a4755eba..00000000 --- a/WDL/plush2/pl_spline.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** -Plush Version 1.2 -spline.c -n-th Dimensional Spline Interpolator -Copyright (c) 1996-2000, Justin Frankel -******************************************************************************/ - -#include "plush.h" - -void pl_Spline::GetPoint(pl_Float frame, pl_Float *out) { - pl_sInt32 i, i_1, i0, i1, i2; - pl_Float time1,time2,time3; - pl_Float t1,t2,t3,t4,u1,u2,u3,u4,v1,v2,v3; - pl_Float a,b,c,d; - - int numKeys=keys.GetSize(); - pl_Float *keyptrs = keys.Get(); - - a = (1-tens)*(1+cont)*(1+bias); - b = (1-tens)*(1-cont)*(1-bias); - c = (1-tens)*(1-cont)*(1+bias); - d = (1-tens)*(1+cont)*(1-bias); - v1 = t1 = -a / 2.0; u1 = a; - u2 = (-6-2*a+2*b+c)/2.0; v2 = (a-b)/2.0; t2 = (4+a-b-c) / 2.0; - t3 = (-4+b+c-d) / 2.0; - u3 = (6-2*b-c+d)/2.0; - v3 = b/2.0; - t4 = d/2.0; u4 = -t4; - - i0 = (pl_uInt) frame; - i_1 = i0 - 1; - while (i_1 < 0) i_1 += numKeys; - i1 = i0 + 1; - while (i1 >= numKeys) i1 -= numKeys; - i2 = i0 + 2; - while (i2 >= numKeys) i2 -= numKeys; - time1 = frame - (pl_Float) ((pl_uInt) frame); - time2 = time1*time1; - time3 = time2*time1; - i0 *= keyWidth; - i1 *= keyWidth; - i2 *= keyWidth; - i_1 *= keyWidth; - for (i = 0; i < keyWidth; i ++) { - a = t1*keyptrs[i+i_1]+t2*keyptrs[i+i0]+t3*keyptrs[i+i1]+t4*keyptrs[i+i2]; - b = u1*keyptrs[i+i_1]+u2*keyptrs[i+i0]+u3*keyptrs[i+i1]+u4*keyptrs[i+i2]; - c = v1*keyptrs[i+i_1]+v2*keyptrs[i+i0]+v3*keyptrs[i+i1]; - *out++ = a*time3 + b*time2 + c*time1 + keyptrs[i+i0]; - } -} diff --git a/WDL/plush2/plush.h b/WDL/plush2/plush.h deleted file mode 100644 index ac0ed30a..00000000 --- a/WDL/plush2/plush.h +++ /dev/null @@ -1,598 +0,0 @@ -/****************************************************************************** - plush.h - PLUSH 3D VERSION 2.0 MAIN HEADER - Copyright (c) 1996-2000 Justin Frankel - Copyright (c) 1998-2000 Nullsoft, Inc. - Copyright (c) 2008 Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -******************************************************************************/ - -#ifndef _PLUSH_H_ -#define _PLUSH_H_ - -#include -#include -#include -#include - -#include "../lice/lice.h" // using LICE for images -#include "../ptrlist.h" -#include "../wdltypes.h" - -typedef float pl_ZBuffer; /* z-buffer type (must be float) */ -typedef double pl_Float; /* General floating point */ -typedef float pl_IEEEFloat32; /* IEEE 32 bit floating point */ -typedef signed int pl_sInt32; /* signed 32 bit integer */ -typedef unsigned int pl_uInt32; /* unsigned 32 bit integer */ -typedef signed short int pl_sInt16; /* signed 16 bit integer */ -typedef unsigned short int pl_uInt16; /* unsigned 16 bit integer */ -typedef signed int pl_sInt; /* signed optimal integer */ -typedef unsigned int pl_uInt; /* unsigned optimal integer */ -typedef bool pl_Bool; /* boolean */ -typedef unsigned char pl_uChar; /* unsigned 8 bit integer */ -typedef signed char pl_sChar; /* signed 8 bit integer */ - - - -/* pi! */ -#define PL_PI 3.141592653589793238 - -/* Utility min() and max() functions */ -#define plMin(x,y) (( ( x ) > ( y ) ? ( y ) : ( x ))) -#define plMax(x,y) (( ( x ) < ( y ) ? ( y ) : ( x ))) - - - -/* -** Light modes. Used with plLight.Type or plLightSet(). -** Note that PL_LIGHT_POINT_ANGLE assumes no falloff and uses the angle between -** the light and the point, PL_LIGHT_POINT_DISTANCE has falloff with proportion -** to distance**2 (see plLightSet() for setting it), PL_LIGHT_POINT does both. -*/ -#define PL_LIGHT_NONE (0x0) -#define PL_LIGHT_VECTOR (0x1) -#define PL_LIGHT_POINT (0x2|0x4) -#define PL_LIGHT_POINT_DISTANCE (0x2) -#define PL_LIGHT_POINT_ANGLE (0x4) - - -#define PLUSH_MAX_MAPCOORDS 3 // 2 + envmap slot - - -class pl_Mat -{ -public: - pl_Mat() - { - memset(Ambient,0,sizeof(Ambient)); - Diffuse[0]=Diffuse[1]=Diffuse[2]=1.0; - SolidOpacity=1.0; - SolidCombineMode= LICE_BLIT_MODE_COPY; - - Texture=NULL; - TexCombineMode = LICE_BLIT_MODE_ADD; //LICE_BLIT_USE_SOURCE_ALPHA? - TexOpacity=1.0; - TexScaling[0]=TexScaling[1]=1.0; - TexMapIdx=0; - - Texture2=NULL; - Tex2CombineMode = LICE_BLIT_MODE_ADD; - Tex2Opacity=1.0; - Tex2Scaling[0]=Tex2Scaling[1]=1.0; - Tex2MapIdx=-1; - - FadeDist=0.0; - Smoothing=Lightable=true; - zBufferable=true; - PerspectiveCorrect=16; - BackfaceCull=true; - BackfaceIllumination=0.0; - - cachedTexture=cachedTexture2=0; - cachesInvalid=true; - } - - ~pl_Mat() - { - delete cachedTexture; - delete cachedTexture2; - } - - - pl_Bool Smoothing; // smoothing of lighting - pl_Bool Lightable; // affected by lights - pl_Bool zBufferable; /* Can this material be zbuffered? */ - pl_uChar PerspectiveCorrect; /* Correct texture perspective every n pixels */ - - pl_Float FadeDist WDL_FIXALIGN; /* For distance fading, distance at which intensity is 0. set to 0.0 for no distance shading */ - - pl_Bool BackfaceCull; /* Are backfacing polys drawn? */ - pl_Float BackfaceIllumination WDL_FIXALIGN; /* Illuminated by lights behind them, and by how much of a factor? */ - - // colors - pl_Float Ambient[3]; /* RGB of surface (0-1 is a good range) */ - pl_Float Diffuse[3]; /* RGB of diffuse (0-1 is a good range) */ - pl_Float SolidOpacity; - int SolidCombineMode; /* LICE combine mode for first pass (color), default should be replace (or add-black for transparent) */ - - // textures - LICE_IBitmap *Texture; /* Texture map (not owned by Material but a reference)*/ - pl_Float TexScaling[2] WDL_FIXALIGN; /* Texture map scaling */ - pl_Float TexOpacity; - int TexCombineMode; /* Texture combine mode (generally should be additive) */ - int TexMapIdx; // -1 for env - - LICE_IBitmap *Texture2; - pl_Float Tex2Scaling[2] WDL_FIXALIGN; - pl_Float Tex2Opacity; - int Tex2CombineMode; - int Tex2MapIdx; // -1 for env - - - void InvalidateTextureCaches() { cachesInvalid=true; } // call this if you change Texture or Texture2 after rendering - -private: - bool cachesInvalid; - LICE_IBitmap *cachedTexture,*cachedTexture2; // these may need to be LICE_GL_MemBitmaps etc - -} WDL_FIXALIGN; - - -class pl_Vertex { -public: - pl_Vertex() { } - ~pl_Vertex () { } - - pl_Float x, y, z; /* Vertex coordinate (objectspace) */ - pl_Float nx, ny, nz; /* Unit vertex normal (objectspace) */ - - pl_Float xformedx, xformedy, xformedz; /* Transformed vertex coordinate (cameraspace) */ - pl_Float xformednx, xformedny, xformednz; /* Transformed unit vertex normal (cameraspace) */ -}; - -class pl_Face { -public: - pl_Face() - { - } - ~pl_Face() - { - } - - pl_Mat *Material; /* Material of triangle */ - int VertexIndices[3]; /* Vertices of triangle */ - - pl_Float nx WDL_FIXALIGN; - pl_Float ny; - pl_Float nz; /* Normal of triangle (object space) */ - - pl_Float MappingU[PLUSH_MAX_MAPCOORDS][3], MappingV[PLUSH_MAX_MAPCOORDS][3]; /* Texture mapping coordinates */ - - pl_Float sLighting[3]; /* Face static lighting. Should usually be 0.0 */ - pl_Float vsLighting[3][3]; /* Vertex static lighting. Should usually be 0.0 */ - - - // calculated: - pl_Float Shades[3][3]; /* colors (first 3 used for flat, all for Gouraud) */ - pl_Float Scrx[3], Scry[3]; /* Projected screen coordinates */ - pl_Float Scrz[3]; /* Projected 1/Z coordinates */ - -}; - - -class pl_Obj { -public: - pl_Obj(int nv=0, int nf=0) - { - if (nv) memset(Vertices.Resize(nv),0,nv*sizeof(pl_Vertex)); - if (nf) memset(Faces.Resize(nf),0,nf*sizeof(pl_Face)); - - GenMatrix=true; - Xp=Yp=Zp=Xa=Ya=Za=0.0; - } - ~pl_Obj() { Children.Empty(true); } - - pl_Obj *Clone(); - void Scale(pl_Float sc); - void Stretch(pl_Float x, pl_Float y, pl_Float z); // scales but preserves normals - void Translate(pl_Float x, pl_Float y, pl_Float z); - void FlipNormals(); - - void SetMaterial(pl_Mat *m, pl_Bool recurse=true); - void CalculateNormals(); - - - WDL_TypedBuf Vertices; - WDL_TypedBuf Faces; - WDL_PtrList Children; - /* Children */ - pl_Bool GenMatrix; /* Generate Matrix from the following - if set */ - pl_Float Xp WDL_FIXALIGN; - pl_Float Yp, Zp, Xa, Ya, Za; /* Position and rotation of object: - Note: rotations are around - X then Y then Z. Measured in degrees */ - pl_Float Matrix[16]; /* Transformation matrix */ - pl_Float RotMatrix[16]; /* Rotation only matrix (for normals) */ -}; - - -class pl_Spline { -public: - pl_Spline() { cont=1.0; bias=0.3; tens=0.3; keyWidth=1; } - ~pl_Spline () { } - void GetPoint(pl_Float frame, pl_Float *out); - WDL_TypedBuf keys; /* Key data, keyWidth*numKeys */ - pl_sInt keyWidth; /* Number of floats per key */ - - pl_Float cont WDL_FIXALIGN; /* Continuity. Should be -1.0 -> 1.0 */ - pl_Float bias; /* Bias. -1.0 -> 1.0 */ - pl_Float tens; /* Tension. -1.0 -> 1.0 */ -}; - - -class pl_Light { -public: - pl_Light() { Type = PL_LIGHT_VECTOR; Xp=Yp=0.0; Zp=1.0; Intensity[0]=Intensity[1]=Intensity[2]=1.0; } - ~pl_Light() { } - -/* - Set() sets up a light: - mode: the mode of the light (PL_LIGHT_*) - x,y,z: either the position of the light (PL_LIGHT_POINT*) or the angle - in degrees of the light (PL_LIGHT_VECTOR) - intensity: the intensity of the light (0.0-1.0) - halfDist: the distance at which PL_LIGHT_POINT_DISTANCE is 1/2 intensity -*/ - void Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist); - - - // privatestuff - pl_uChar Type; /* Type of light: PL_LIGHT_* */ - pl_Float Xp WDL_FIXALIGN; - pl_Float Yp, Zp; /* If Type=PL_LIGHT_POINT*, - this is Position (PL_LIGHT_POINT_*), - otherwise if PL_LIGHT_VECTOR, - Unit vector */ - pl_Float Intensity[3]; /* Intensity. 0.0 is off, 1.0 is full */ - pl_Float HalfDistSquared; /* Distance squared at which - PL_LIGHT_POINT_DISTANCE is 50% */ -}; - - -class pl_Cam { -public: - pl_Cam() - { - frameBuffer=0; - Fov=90.0; - AspectRatio=1.0; - Sort=1; - ClipBack=-1.0; - CenterX=CenterY=0; - X=Y=Z=0.0; - WantZBuffer=false; - Pitch=Pan=Roll=0.0; - } - ~pl_Cam() - { - } - - - void SetTarget(pl_Float x, pl_Float y, pl_Float z); - - - pl_Float Fov; /* FOV in degrees valid range is 1-179 */ - pl_Float AspectRatio; /* Aspect ratio (usually 1.0) */ - pl_sChar Sort; /* Sort polygons, -1 f-t-b, 1 b-t-f, 0 no */ - pl_Float ClipBack WDL_FIXALIGN; /* Far clipping ( < 0.0 is none) */ - pl_sInt CenterX, CenterY; /* Offset center of screen from actual center by this much... */ - pl_Float X WDL_FIXALIGN; - pl_Float Y, Z; /* Camera position in worldspace */ - - pl_Float Pitch, Pan, Roll; /* Camera angle in degrees in worldspace */ - - bool WantZBuffer; - - void Begin(LICE_IBitmap *fb, bool want_zbclear=true, pl_ZBuffer zbclear=0.0); - void RenderLight(pl_Light *light); - void RenderObject(pl_Obj *obj, pl_Float *bmatrix=NULL, pl_Float *bnmatrix=NULL); - void SortToCurrent(); // sorts all faces added since Begin() or last SortToCurrent() call. useful for if you use zbuffering with transparent objects (draw them last) - - LICE_IBitmap *GetFrameBuffer() { return frameBuffer; } - WDL_TypedBuf zBuffer; /* Z Buffer (validate size before using)*/ - - void End(); - - int RenderTrisIn; - int RenderTrisCulled; - int RenderTrisOut; - - double RenderPixelsOut WDL_FIXALIGN; - - void PutFace(pl_Face *TriFace); - -private: - LICE_IBitmap *frameBuffer; /* Framebuffer - note this is owned by the camera if you set it */ - - // internal use - void ClipRenderFace(pl_Face *face, pl_Obj *obj); - int ClipNeeded(pl_Face *face, pl_Obj *obj); // 0=no draw, 1=drawing (possibly splitting) necessary - void RecalcFrustum(); - - - #define PL_NUM_CLIP_PLANES 5 - - struct _clipInfo - { - pl_Vertex newVertices[8]; - pl_Float ShadeInfos[8][3]; - pl_Float MappingU[PLUSH_MAX_MAPCOORDS][8]; - pl_Float MappingV[PLUSH_MAX_MAPCOORDS][8]; - }; - - _clipInfo m_cl[2] WDL_FIXALIGN; - pl_Float m_clipPlanes[PL_NUM_CLIP_PLANES][4]; - pl_Float m_fovfactor, m_adj_asp; // recalculated - - /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ - pl_uInt _ClipToPlane(pl_uInt numVerts, pl_Float *plane); - - - struct _faceInfo { - pl_Float zd; - pl_Face *face; - pl_Obj *obj; - } WDL_FIXALIGN; - - struct _lightInfo { - pl_Float l[3]; - pl_Light *light; - } WDL_FIXALIGN; - - static int sortRevFunc(const void *a, const void *b); - static int sortFwdFunc(const void *a, const void *b); - - int _numfaces,_numfaces_sorted; - WDL_TypedBuf<_faceInfo> _faces; - - pl_Float _cMatrix[16] WDL_FIXALIGN; - - int _numlights; - WDL_TypedBuf<_lightInfo> _lights; - - void _RenderObj(pl_Obj *, pl_Float *, pl_Float *); - - WDL_HeapBuf _sort_tmpspace; - -}; - - - - -/****************************************************************************** -** Object Primitives Code (pl_make.cpp) -******************************************************************************/ - -/* - plMakePlane() makes a plane centered at the origin facing up the y axis. - Parameters: - w: width of the plane (along the x axis) - d: depth of the plane (along the z axis) - res: resolution of plane, i.e. subdivisions - m: material to use - Returns: - pointer to object created. -*/ -pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m); - -/* - plMakeBox() makes a box centered at the origin - Parameters: - w: width of the box (x axis) - d: depth of the box (z axis) - h: height of the box (y axis) - Returns: - pointer to object created. -*/ -pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m); - -/* - plMakeCone() makes a cone centered at the origin - Parameters: - r: radius of the cone (x-z axis) - h: height of the cone (y axis) - div: division of cone (>=3) - cap: close the big end? - m: material to use - Returns: - pointer to object created. -*/ -pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, pl_Bool cap, pl_Mat *m); - -/* - plMakeCylinder() makes a cylinder centered at the origin - Parameters: - r: radius of the cylinder (x-z axis) - h: height of the cylinder (y axis) - divr: division of of cylinder (around the circle) (>=3) - captop: close the top - capbottom: close the bottom - m: material to use - Returns: - pointer to object created. -*/ -pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, - pl_Bool capbottom, pl_Mat *m); - -/* - plMakeSphere() makes a sphere centered at the origin. - Parameters: - r: radius of the sphere - divr: division of the sphere (around the y axis) (>=3) - divh: division of the sphere (around the x,z axis) (>=3) - m: material to use - Returns: - pointer to object created. -*/ -pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m); - -/* - plMakeTorus() makes a torus centered at the origin - Parameters: - r1: inner radius of the torus - r2: outer radius of the torus - divrot: division of the torus (around the y axis) (>=3) - divrad: division of the radius of the torus (x>=3) - m: material to use - Returns: - pointer to object created. -*/ -pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, - pl_uInt divrad, pl_Mat *m); - - -/****************************************************************************** -** File Readers (pl_read_*.cpp) -******************************************************************************/ - -/* - plRead3DSObj() reads a 3DS object - Parameters: - fn: filename of object to read - m: material to assign it - Returns: - pointer to object - Notes: - This reader organizes multiple objects like so: - 1) the first object is returned - 2) the second object is the first's first child - 3) the third object is the second's first child - 4) etc -*/ -pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m); -pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m); -pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m); - -/* - plReadCOBObj() reads an ascii .COB object - Parameters: - fn: filename of object to read - mat: material to assign it - Returns: - pointer to object - Notes: - This is Caligari's ASCII object format. - This reader doesn't handle multiple objects. It just reads the first one. - Polygons with lots of sides are not always tesselated correctly. Just - use the "Tesselate" button from within truespace to improve the results. -*/ -pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat); - -/* - plReadJAWObj() reads a .JAW object. - Parameters: - fn: filename of object to read - m: material to assign it - Returns: - pointer to object - Notes: - For information on the .JAW format, please see the jaw3D homepage, - http://www.tc.umn.edu/nlhome/g346/kari0022/jaw3d/ -*/ -pl_Obj *plReadJAWObj(char *fn, pl_Mat *m); - - - -/****************************************************************************** -** Math Code (pl_math.cpp) -******************************************************************************/ - -/* - plMatrixRotate() generates a rotation matrix - Parameters: - matrix: an array of 16 pl_Floats that is a 4x4 matrix - m: the axis to rotate around, 1=X, 2=Y, 3=Z. - Deg: the angle in degrees to rotate - Returns: - nothing -*/ -void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg); - -/* - plMatrixTranslate() generates a translation matrix - Parameters: - m: the matrix (see plMatrixRotate for more info) - x,y,z: the translation coordinates - Returns: - nothing -*/ -void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z); - -/* - plMatrixMultiply() multiplies two matrices - Parameters: - dest: destination matrix will be multipled by src - src: source matrix - Returns: - nothing - Notes: - this is the same as dest = dest*src (since the order *does* matter); -*/ -void plMatrixMultiply(pl_Float *dest, pl_Float src[]); - -/* - plMatrixApply() applies a matrix. - Parameters: - m: matrix to apply - x,y,z: input coordinate - outx,outy,outz: pointers to output coords. - Returns: - nothing - Notes: - applies the matrix to the 3d point to produce the transformed 3d point -*/ -void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, - pl_Float *outx, pl_Float *outy, pl_Float *outz); - -/* - plNormalizeVector() makes a vector a unit vector - Parameters: - x,y,z: pointers to the vector - Returns: - nothing -*/ -void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z); - -/* - plDotProduct() returns the dot product of two vectors - Parameters: - x1,y1,z1: the first vector - x2,y2,z2: the second vector - Returns: - the dot product of the two vectors -*/ -pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, - pl_Float x2, pl_Float y2, pl_Float z2); - - - - -#endif /* !_PLUSH_H_ */ diff --git a/WDL/plush2/plush2.dsp b/WDL/plush2/plush2.dsp deleted file mode 100644 index 215aa143..00000000 --- a/WDL/plush2/plush2.dsp +++ /dev/null @@ -1,217 +0,0 @@ -# Microsoft Developer Studio Project File - Name="plush2" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=plush2 - 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 "plush2.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 "plush2.mak" CFG="plush2 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "plush2 - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "plush2 - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "plush2 - 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 "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /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=xilink6.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "plush2 - 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 "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /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=xilink6.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "plush2 - Win32 Release" -# Name "plush2 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=pl_cam.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_make.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_math.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_obj.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_putface.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_read_3ds.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_read_cob.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_read_jaw.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=pl_spline.cpp - -!IF "$(CFG)" == "plush2 - Win32 Release" - -# ADD CPP /D "USE_ICC" - -!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=pl_pf_tex.h -# End Source File -# Begin Source File - -SOURCE=plush.h -# End Source File -# End Group -# End Target -# End Project diff --git a/WDL/poollist.h b/WDL/poollist.h deleted file mode 100644 index 4ad8129b..00000000 --- a/WDL/poollist.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - WDL - poollist.h - Copyright (C) 2006 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - - This file defines a template class for hosting lists of referenced count, string-identified objects. - - We mostly use it with WDL_ResourcePool, but any class like this can use it: - - - class SomeClass - { - public: - SomeClass(char *identstr) { WDL_POOLLIST_identstr=identstr; WDL_POOLLIST_refcnt=0; } - ~SomeClass() {} // do NOT free or delete WDL_POOLLIST_identstr - - - void Clear() {} // will be called if ReleasePool(x,false) is called and refcnt gets to 0 - int WDL_POOLLIST_refcnt; - char *WDL_POOLLIST_identstr; - }; - - - -*/ - - - -#ifndef _WDL_POOLLIST_H_ -#define _WDL_POOLLIST_H_ - -#include - -#include "mutex.h" - -template class WDL_PoolList -{ -public: - - WDL_PoolList() - { - } - ~WDL_PoolList() - { - int x; - for (x = 0; x < pool.GetSize(); x ++) - { - DATATYPE *p = pool.Get(x); - free(p->WDL_POOLLIST_identstr); - delete p; - } - } - - DATATYPE *Get(const char *filename) - { - WDL_MutexLock lock(&mutex); - - DATATYPE *t = Find(filename,false); - if (t) - { - t->WDL_POOLLIST_refcnt++; - return t; - } - - t = new DATATYPE(strdup(filename)); - t->WDL_POOLLIST_refcnt=1; - - int x; - for(x=0;xWDL_POOLLIST_identstr,filename)>0) break; - - pool.Insert(x,t); - - return t; - } - - DATATYPE *Find(const char *filename, bool lockMutex=true) // not threadsafe - { - if (lockMutex) mutex.Enter(); - DATATYPE **_tmp=NULL; - if (pool.GetSize()) - { - DATATYPE tmp((char *)filename),*t=&tmp; - _tmp = (DATATYPE**)bsearch(&t,pool.GetList(),pool.GetSize(),sizeof(void *),_sortfunc); - } - if (lockMutex) mutex.Leave(); - return _tmp ? *_tmp : NULL; - } - - int ReleaseByName(const char *filename, bool isFull=true) - { - WDL_MutexLock lock(&mutex); - return Release(Find(filename,false),isFull); - } - - int Release(DATATYPE *tp, bool isFull=true) - { - if (!tp) return -1; - WDL_MutexLock lock(&mutex); - - int refcnt; - if (!(refcnt=--tp->WDL_POOLLIST_refcnt)) - { - if (!isFull) - { - tp->Clear(); - } - else - { - int x; - for (x = 0; x < pool.GetSize() && pool.Get(x) != tp; x ++); - if (xWDL_POOLLIST_identstr); - delete tp; - } - // remove from list - } - return refcnt; - } - - WDL_Mutex mutex; - WDL_PtrList< DATATYPE > pool; - -private: - - static int _sortfunc(const void *a, const void *b) - { - DATATYPE *ta = *(DATATYPE **)a; - DATATYPE *tb = *(DATATYPE **)b; - - return stricmp(ta->WDL_POOLLIST_identstr,tb->WDL_POOLLIST_identstr); - } -}; - - -#endif \ No newline at end of file diff --git a/WDL/projectcontext.cpp b/WDL/projectcontext.cpp deleted file mode 100644 index 651672df..00000000 --- a/WDL/projectcontext.cpp +++ /dev/null @@ -1,678 +0,0 @@ -#ifdef _WIN32 -#include -#else -#include -#include -#include -#endif -#include -#include -#include - -#include "projectcontext.h" - -#include "fileread.h" -#include "filewrite.h" -#include "heapbuf.h" -#include "wdlstring.h" -#include "lineparse.h" - - -//#define WDL_MEMPROJECTCONTEXT_USE_ZLIB 1 - -#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - -#define WDL_MEMPROJECTCONTEXT_ZLIB_CHUNKSIZE 65536 -#include "zlib/zlib.h" - -#endif - - -class ProjectStateContext_Mem : public ProjectStateContext -{ -public: - - ProjectStateContext_Mem(WDL_HeapBuf *hb) - { - m_heapbuf=hb; - m_pos=0; - m_tmpflag=0; -#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - memset(&m_compstream,0,sizeof(m_compstream)); - m_usecomp=0; -#endif - } - - virtual ~ProjectStateContext_Mem() - { - #ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - if (m_usecomp==1) - { - FlushComp(true); - deflateEnd(&m_compstream); - } - else if (m_usecomp==2) - { - inflateEnd(&m_compstream); - } - #endif - }; - - virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...); - virtual int GetLine(char *buf, int buflen); // returns -1 on eof - - virtual WDL_INT64 GetOutputSize() { return m_heapbuf ? m_heapbuf->GetSize() : 0; } - - virtual int GetTempFlag() { return m_tmpflag; } - virtual void SetTempFlag(int flag) { m_tmpflag=flag; } - - int m_pos; - WDL_HeapBuf *m_heapbuf; - int m_tmpflag; - -#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - int DecompressData() - { - if (m_pos >= m_heapbuf->GetSize()) return 1; - - m_compstream.next_in = (unsigned char *)m_heapbuf->Get() + m_pos; - m_compstream.avail_in = m_heapbuf->GetSize()-m_pos; - m_compstream.total_in = 0; - - int outchunk = 65536; - m_compstream.next_out = (unsigned char *)m_compdatabuf.Add(NULL,outchunk); - m_compstream.avail_out = outchunk; - m_compstream.total_out = 0; - - int e = inflate(&m_compstream,Z_NO_FLUSH); - - m_pos += m_compstream.total_in; - m_compdatabuf.Add(NULL,m_compstream.total_out - outchunk); // rewind - - return e != Z_OK; - } - - void FlushComp(bool eof) - { - while (m_compdatabuf.Available()>=WDL_MEMPROJECTCONTEXT_ZLIB_CHUNKSIZE || eof) - { - if (!m_heapbuf->GetSize()) m_heapbuf->SetGranul(256*1024); - m_compstream.next_in = (unsigned char *)m_compdatabuf.Get(); - m_compstream.avail_in = m_compdatabuf.Available(); - m_compstream.total_in = 0; - - int osz = m_heapbuf->GetSize(); - - int newsz=osz + max(m_compstream.avail_in,8192) + 256; - m_compstream.next_out = (unsigned char *)m_heapbuf->Resize(newsz, false) + osz; - if (m_heapbuf->GetSize()!=newsz) return; // ERROR - m_compstream.avail_out = newsz-osz; - m_compstream.total_out=0; - - deflate(&m_compstream,eof?Z_SYNC_FLUSH:Z_NO_FLUSH); - - m_heapbuf->Resize(osz+m_compstream.total_out,false); - m_compdatabuf.Advance(m_compstream.total_in); - if (m_compstream.avail_out) break; // no need to process anymore - - } - m_compdatabuf.Compact(); - } - - // these will be used for either decompression or compression, fear - int m_usecomp; // 0=?, -1 = fail, 1=yes - WDL_Queue m_compdatabuf; - z_stream m_compstream; -#endif - -}; - -void ProjectStateContext_Mem::AddLine(const char *fmt, ...) -{ - if (!m_heapbuf) return; - - char buf[8192]; - va_list va; - va_start(va,fmt); - - buf[0]=0; -#if defined(_WIN32) && defined(_MSC_VER) - int l = _vsnprintf(buf,sizeof(buf),fmt,va); // _vsnprintf() does not always null terminate - if (l < 0 || l >= sizeof(buf)) - { - buf[sizeof(buf)-1]=0; - l = strlen(buf); - } -#else - // vsnprintf() on non-win32, always null terminates - int l = vsnprintf(buf,sizeof(buf),fmt,va); - if (l>sizeof(buf)-1) l=sizeof(buf)-1; -#endif - va_end(va); - - l++; // include NULL term - -#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - if (!m_usecomp) - { - if (deflateInit(&m_compstream,WDL_MEMPROJECTCONTEXT_USE_ZLIB)==Z_OK) m_usecomp=1; - else m_usecomp=-1; - } - - if (m_usecomp==1) - { - m_compdatabuf.Add(buf,l); - FlushComp(false); - return; - } -#endif - - - int sz=m_heapbuf->GetSize(); - if (!sz) - { - m_heapbuf->SetGranul(256*1024); - } - - int newsz = sz + l; - char *p = (char *)m_heapbuf->Resize(newsz); - if (m_heapbuf->GetSize() != newsz) - { - // ERROR, resize to 0 and return - m_heapbuf->Resize(0); - m_heapbuf=0; - return; - } - memcpy(p+sz,buf,l); -} - -int ProjectStateContext_Mem::GetLine(char *buf, int buflen) // returns -1 on eof -{ - if (!m_heapbuf) return -1; - - buf[0]=0; - - -#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB - if (!m_usecomp) - { - unsigned char hdr[]={0x78,0x01}; - if (m_heapbuf->GetSize()>2 && !memcmp(hdr,m_heapbuf->Get(),4) && inflateInit(&m_compstream)==Z_OK) m_usecomp=2; - else m_usecomp=-1; - } - if (m_usecomp==2) - { - int x=0; - for (;;) - { - const char *p = (const char*) m_compdatabuf.Get(); - for (x = 0; x < m_compdatabuf.Available() && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); - while (x >= m_compdatabuf.Available()) - { - int err = DecompressData(); - p = (const char *)m_compdatabuf.Get(); - for (; x < m_compdatabuf.Available() && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); - - if (err) break; - } - - if (x||!m_compdatabuf.Available()) break; - - m_compdatabuf.Advance(1); // skip over nul or newline char - } - - if (!x) return -1; - - if (buflen > 0 && buf) - { - int l = min(buflen-1,x); - memcpy(buf,m_compdatabuf.Get(),l); - buf[l]=0; - } - - m_compdatabuf.Advance(x+1); - m_compdatabuf.Compact(); - return 0; - } -#endif - - - int avail = m_heapbuf->GetSize() - m_pos; - const char *p=(const char *)m_heapbuf->Get() + m_pos; - while (avail > 0 && (p[0] =='\r'||p[0]=='\n'||!p[0]||p[0] == ' ' || p[0] == '\t')) - { - p++; - m_pos++; - avail--; - } - if (avail <= 0) return -1; - - int x; - for (x = 0; x < avail && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); - m_pos += x+1; - - if (buflen > 0&&buf) - { - int l = buflen-1; - if (l>x) l=x; - memcpy(buf,p,l); - buf[l]=0; - } - return 0; -} - -class ProjectStateContext_File : public ProjectStateContext -{ -public: - - ProjectStateContext_File(WDL_FileRead *rd, WDL_FileWrite *wr) - { - m_rd=rd; - m_wr=wr; - m_indent=0; - m_bytesOut=0; - m_errcnt=false; - m_tmpflag=0; - } - virtual ~ProjectStateContext_File(){ delete m_rd; delete m_wr; }; - - virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...); - virtual int GetLine(char *buf, int buflen); // returns -1 on eof - - virtual WDL_INT64 GetOutputSize() { return m_bytesOut; } - - virtual int GetTempFlag() { return m_tmpflag; } - virtual void SetTempFlag(int flag) { m_tmpflag=flag; } - - bool HasError() { return m_errcnt; } - - WDL_INT64 m_bytesOut WDL_FIXALIGN; - - WDL_FileRead *m_rd; - WDL_FileWrite *m_wr; - int m_indent; - int m_tmpflag; - bool m_errcnt; -}; - -int ProjectStateContext_File::GetLine(char *buf, int buflen) -{ - if (!m_rd||buflen<2) return -1; - - buf[0]=0; - for (;;) - { - buf[0]=0; - int i=0; - while (iRead(buf+i,1)) { if (!i) return -1; break; } - - if (buf[i] == '\r' || buf[i] == '\n') - { - if (!i) continue; // skip over leading newlines - break; - } - - if (!i && (buf[0] == ' ' || buf[0] == '\t')) continue; // skip leading blanks - - i++; - } - if (i<1) continue; - - buf[i]=0; - - if (buf[0]) return 0; - } - return -1; -} - -void ProjectStateContext_File::AddLine(const char *fmt, ...) -{ - if (m_wr && !m_errcnt) - { - int err=0; - - int a=m_indent; - if (fmt[0] == '<') m_indent+=2; - else if (fmt[0] == '>') a=(m_indent-=2); - - if (a>0) - { - m_bytesOut+=a; - char tb[32]; - memset(tb,' ',sizeof(tb)); - while (a>0) - { - int tl = a; - if (tl>32)tl=32; - a-=tl; - m_wr->Write(tb,tl); - } - } - - - char buf[8192]; - va_list va; - va_start(va,fmt); - - buf[0]=0; - #if defined(_WIN32) && defined(_MSC_VER) - int l = _vsnprintf(buf,sizeof(buf),fmt,va); // _vsnprintf() does not always null terminate - if (l < 0 || l >= sizeof(buf)) - { - buf[sizeof(buf)-1] = 0; - l = strlen(buf); - } - #else - // vsnprintf() on non-win32, always null terminates - int l = vsnprintf(buf,sizeof(buf),fmt,va); - if (l>sizeof(buf)-1) l=sizeof(buf)-1; - #endif - - va_end(va); - - err |= m_wr->Write(buf,l) != l; - err |= m_wr->Write("\r\n",2) != 2; - m_bytesOut += 2 + l; - - if (err) m_errcnt=true; - } -} - - - -ProjectStateContext *ProjectCreateFileRead(const char *fn) -{ - WDL_FileRead *rd = new WDL_FileRead(fn); - if (!rd || !rd->IsOpen()) - { - delete rd; - return NULL; - } - return new ProjectStateContext_File(rd,NULL); -} -ProjectStateContext *ProjectCreateFileWrite(const char *fn) -{ - WDL_FileWrite *wr = new WDL_FileWrite(fn); - if (!wr || !wr->IsOpen()) - { - delete wr; - return NULL; - } - return new ProjectStateContext_File(NULL,wr); -} - - -ProjectStateContext *ProjectCreateMemCtx(WDL_HeapBuf *hb) -{ - return new ProjectStateContext_Mem(hb); -} - -bool ProjectContext_GetNextLine(ProjectStateContext *ctx, LineParser *lpOut) -{ - for (;;) - { - char linebuf[4096]; - if (ctx->GetLine(linebuf,sizeof(linebuf))) - { - lpOut->parse(""); - return false; - } - - if (lpOut->parse(linebuf)||lpOut->getnumtokens()<=0) continue; - - return true; // success! - - } -} - - -bool ProjectContext_EatCurrentBlock(ProjectStateContext *ctx) -{ - int child_count=1; - if (ctx) for (;;) - { - char linebuf[4096]; - if (ctx->GetLine(linebuf,sizeof(linebuf))) break; - - bool comment_state=false; - LineParser lp(comment_state); - if (lp.parse(linebuf)||lp.getnumtokens()<=0) continue; - if (lp.gettoken_str(0)[0] == '>') if (--child_count < 1) return true; - if (lp.gettoken_str(0)[0] == '<') child_count++; - } - - return false; -} - - -static void pc_base64encode(const unsigned char *in, char *out, int len) -{ - char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int shift = 0; - int accum = 0; - - while (len>0) - { - len--; - accum <<= 8; - shift += 8; - accum |= *in++; - while ( shift >= 6 ) - { - shift -= 6; - *out++ = alphabet[(accum >> shift) & 0x3F]; - } - } - if (shift == 4) - { - *out++ = alphabet[(accum & 0xF)<<2]; - *out++='='; - } - else if (shift == 2) - { - *out++ = alphabet[(accum & 0x3)<<4]; - *out++='='; - *out++='='; - } - - *out++=0; -} - -static int pc_base64decode(const char *src, unsigned char *dest, int destsize) -{ - unsigned char *olddest=dest; - - int accum=0; - int nbits=0; - while (*src) - { - int x=0; - char c=*src++; - if (c >= 'A' && c <= 'Z') x=c-'A'; - else if (c >= 'a' && c <= 'z') x=c-'a' + 26; - else if (c >= '0' && c <= '9') x=c-'0' + 52; - else if (c == '+') x=62; - else if (c == '/') x=63; - else break; - - accum <<= 6; - accum |= x; - nbits += 6; - - while (nbits >= 8) - { - if (--destsize<0) break; - nbits-=8; - *dest++ = (char)((accum>>nbits)&0xff); - } - - } - return dest-olddest; -} - - -int cfg_decode_binary(ProjectStateContext *ctx, WDL_HeapBuf *hb) // 0 on success, doesnt clear hb -{ - int child_count=1; - bool comment_state=false; - for (;;) - { - char linebuf[4096]; - if (ctx->GetLine(linebuf,sizeof(linebuf))) break; - - LineParser lp(comment_state); - if (lp.parse(linebuf)||lp.getnumtokens()<=0) continue; - - if (lp.gettoken_str(0)[0] == '<') child_count++; - else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; } - else if (child_count == 1) - { - unsigned char buf[8192]; - int buf_l=pc_base64decode(lp.gettoken_str(0),buf,sizeof(buf)); - int os=hb->GetSize(); - hb->Resize(os+buf_l); - memcpy((char *)hb->Get()+os,buf,buf_l); - } - } - return -1; -} - -void cfg_encode_binary(ProjectStateContext *ctx, const void *ptr, int len) -{ - const unsigned char *p=(const unsigned char *)ptr; - while (len>0) - { - char buf[80]; - int thiss=len; - if (thiss > 40) thiss=40; - pc_base64encode(p,buf,thiss); - - ctx->AddLine("%s",buf); - p+=thiss; - len-=thiss; - } -} - - -int cfg_decode_textblock(ProjectStateContext *ctx, WDL_String *str) // 0 on success, appends to str -{ - int child_count=1; - bool comment_state=false; - for (;;) - { - char linebuf[4096]; - if (ctx->GetLine(linebuf,sizeof(linebuf))) break; - - if (!linebuf[0]) continue; - LineParser lp(comment_state); - if (!lp.parse(linebuf)&&lp.getnumtokens()>0) - { - if (lp.gettoken_str(0)[0] == '<') { child_count++; continue; } - else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; continue; } - } - if (child_count == 1) - { - char *p=linebuf; - while (*p == ' ' || *p == '\t') p++; - if (*p == '|') - { - if (str->Get()[0]) str->Append("\r\n"); - str->Append(++p); - } - } - } - return -1; -} - -int cfg_decode_textblock(ProjectStateContext *ctx, WDL_FastString *str) // 0 on success, appends to str -{ - int child_count=1; - bool comment_state=false; - for (;;) - { - char linebuf[4096]; - if (ctx->GetLine(linebuf,sizeof(linebuf))) break; - - if (!linebuf[0]) continue; - LineParser lp(comment_state); - if (!lp.parse(linebuf)&&lp.getnumtokens()>0) - { - if (lp.gettoken_str(0)[0] == '<') { child_count++; continue; } - else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; continue; } - } - if (child_count == 1) - { - char *p=linebuf; - while (*p == ' ' || *p == '\t') p++; - if (*p == '|') - { - if (str->Get()[0]) str->Append("\r\n"); - str->Append(++p); - } - } - } - return -1; -} - - -void cfg_encode_textblock(ProjectStateContext *ctx, const char *text) -{ - WDL_String tmpcopy(text); - char *txt=(char*)tmpcopy.Get(); - while (*txt) - { - char *ntext=txt; - while (*ntext && *ntext != '\r' && *ntext != '\n') ntext++; - if (ntext > txt || *ntext) - { - char ov=*ntext; - *ntext=0; - ctx->AddLine("|%s",txt); - *ntext=ov; - } - txt=ntext; - if (*txt == '\r') - { - if (*++txt== '\n') txt++; - } - else if (*txt == '\n') - { - if (*++txt == '\r') txt++; - } - } -} - - -void makeEscapedConfigString(const char *in, WDL_String *out) -{ - int flags=0; - const char *p=in; - while (*p && flags!=7) - { - char c=*p++; - if (c=='"') flags|=1; - else if (c=='\'') flags|=2; - else if (c=='`') flags|=4; - } - if (flags!=7) - { - const char *src=(flags&1)?((flags&2)?"`":"'"):"\""; - out->Set(src); - out->Append(in); - out->Append(src); - } - else // ick, change ` into ' - { - out->Set("`"); - out->Append(in); - out->Append("`"); - char *p=out->Get()+1; - while (*p && p[1]) - { - if (*p == '`') *p='\''; - p++; - } - } -} diff --git a/WDL/projectcontext.h b/WDL/projectcontext.h deleted file mode 100644 index f6a53e40..00000000 --- a/WDL/projectcontext.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _PROJECTCONTEXT_H_ -#define _PROJECTCONTEXT_H_ - -#include "wdltypes.h" - -class WDL_String; -class WDL_FastString; -class WDL_HeapBuf; - -#ifndef _REAPER_PLUGIN_PROJECTSTATECONTEXT_DEFINED_ -#define _WDL_PROJECTSTATECONTEXT_DEFINED_ - -class ProjectStateContext // this is also defined in reaper_plugin.h (keep them identical, thx) -{ -public: - virtual ~ProjectStateContext(){}; - - virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...) = 0; - virtual int GetLine(char *buf, int buflen)=0; // returns -1 on eof - - virtual WDL_INT64 GetOutputSize()=0; - - virtual int GetTempFlag()=0; - virtual void SetTempFlag(int flag)=0; -}; - -#endif - -ProjectStateContext *ProjectCreateFileRead(const char *fn); -ProjectStateContext *ProjectCreateFileWrite(const char *fn); -ProjectStateContext *ProjectCreateMemCtx(WDL_HeapBuf *hb); // read or write, be sure to delete it before accessing hb - - - -// helper functions -class LineParser; -bool ProjectContext_EatCurrentBlock(ProjectStateContext *ctx); // returns TRUE if got valid >, otherwise it means eof... -bool ProjectContext_GetNextLine(ProjectStateContext *ctx, LineParser *lpOut); // true if lpOut is valid - - -int cfg_decode_binary(ProjectStateContext *ctx, WDL_HeapBuf *hb); // 0 on success, doesnt clear hb -void cfg_encode_binary(ProjectStateContext *ctx, const void *ptr, int len); - -int cfg_decode_textblock(ProjectStateContext *ctx, WDL_String *str); // 0 on success, appends to str -int cfg_decode_textblock(ProjectStateContext *ctx, WDL_FastString *str); // 0 on success, appends to str -void cfg_encode_textblock(ProjectStateContext *ctx, const char *text); - -void makeEscapedConfigString(const char *in, WDL_String *out); - -#endif//_PROJECTCONTEXT_H_ diff --git a/WDL/ptrlist.h b/WDL/ptrlist.h deleted file mode 100644 index 2a62b6f1..00000000 --- a/WDL/ptrlist.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - WDL - ptrlist.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple templated class for a list of pointers. By default this list - doesn't free any of the pointers, but you can call Empty(true) or Delete(x,true) to delete the pointer, - or you can use Empty(true,free) etc to call free (or any other function). - - Note: on certain compilers, instantiating with WDL_PtrList bla; will give a warning, since - the template will create code for "delete (void *)x;" which isn't technically valid. Oh well. - -*/ - -#ifndef _WDL_PTRLIST_H_ -#define _WDL_PTRLIST_H_ - -#include "heapbuf.h" - -template class WDL_PtrList -{ - public: - explicit WDL_PtrList(int defgran=4096) : m_hb(defgran WDL_HEAPBUF_TRACEPARM("WDL_PtrList")) - { - } - - ~WDL_PtrList() - { - } - - PTRTYPE **GetList() const { return (PTRTYPE**)m_hb.Get(); } - PTRTYPE *Get(INT_PTR index) const { if (GetList() && index >= 0 && index < (INT_PTR)GetSize()) return GetList()[index]; return NULL; } - int GetSize(void) const { return m_hb.GetSize()/sizeof(PTRTYPE *); } - - int Find(PTRTYPE *p) const - { - if (p) - { - int x; - PTRTYPE **list=(PTRTYPE **)m_hb.Get(); - for (x = 0; x < GetSize(); x ++) if (list[x] == p) return x; - } - return -1; - } - - PTRTYPE *Add(PTRTYPE *item) - { - int s=GetSize(); - m_hb.Resize((s+1)*sizeof(PTRTYPE*),false); - return Set(s,item); - } - - PTRTYPE *Set(int index, PTRTYPE *item) - { - if (index >= 0 && index < GetSize() && GetList()) return GetList()[index]=item; - return NULL; - } - - PTRTYPE *Insert(int index, PTRTYPE *item) - { - int s=GetSize(); - m_hb.Resize((s+1)*sizeof(PTRTYPE*),false); - - if (index<0) index=0; - else if (index > s) index=s; - - int x; - PTRTYPE **list = GetList(); - for (x = s; x > index; x --) list[x]=list[x-1]; - return (list[x] = item); - } - int FindSorted(PTRTYPE *p, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) const - { - bool m; - int i = LowerBound(p,&m,compar); - return m ? i : -1; - } - PTRTYPE *InsertSorted(PTRTYPE *item, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) - { - bool m; - return Insert(LowerBound(item,&m,compar),item); - } - - void Delete(int index) - { - PTRTYPE **list=GetList(); - int size=GetSize(); - if (list && index >= 0 && index < size) - { - if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); - m_hb.Resize(size * sizeof(PTRTYPE*),false); - } - } - void Delete(int index, bool wantDelete, void (*delfunc)(void *)=NULL) - { - PTRTYPE **list=GetList(); - int size=GetSize(); - if (list && index >= 0 && index < size) - { - if (wantDelete) - { - if (delfunc) delfunc(Get(index)); - else delete Get(index); - } - if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); - m_hb.Resize(size * sizeof(PTRTYPE*),false); - } - } - void Delete(int index, void (*delfunc)(PTRTYPE *)) - { - PTRTYPE **list=GetList(); - int size=GetSize(); - if (list && index >= 0 && index < size) - { - if (delfunc) delfunc(Get(index)); - if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); - m_hb.Resize(size * sizeof(PTRTYPE*),false); - } - } - void Empty() - { - m_hb.Resize(0,false); - } - void Empty(bool wantDelete, void (*delfunc)(void *)=NULL) - { - if (wantDelete) - { - int x; - for (x = GetSize()-1; x >= 0; x --) - { - PTRTYPE* p = Get(x); - if (p) - { - if (delfunc) delfunc(p); - else delete p; - } - m_hb.Resize(x*sizeof(PTRTYPE *),false); - } - } - m_hb.Resize(0,false); - } - void Empty(void (*delfunc)(PTRTYPE *)) - { - int x; - for (x = GetSize()-1; x >= 0; x --) - { - PTRTYPE* p = Get(x); - if (delfunc && p) delfunc(p); - m_hb.Resize(x*sizeof(PTRTYPE *),false); - } - } - void EmptySafe(bool wantDelete=false,void (*delfunc)(void *)=NULL) - { - if (!wantDelete) Empty(); - else - { - WDL_PtrList tmp; - int x; - for(x=0;x 0) a = b+1; - else if (cmp < 0) c = b; - else - { - *ismatch = true; - return b; - } - } - *ismatch = false; - return a; - } - - private: - WDL_HeapBuf m_hb; - -}; - - -template class WDL_PtrList_DeleteOnDestroy : public WDL_PtrList -{ -public: - explicit WDL_PtrList_DeleteOnDestroy(void (*delfunc)(void *)=NULL, int defgran=4096) : WDL_PtrList(defgran), m_delfunc(delfunc) { } - ~WDL_PtrList_DeleteOnDestroy() - { - WDL_PtrList::EmptySafe(true,m_delfunc); - } -private: - void (*m_delfunc)(void *); -}; - -#endif - diff --git a/WDL/queue.h b/WDL/queue.h deleted file mode 100644 index cdbba334..00000000 --- a/WDL/queue.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - WDL - queue.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple class for a FIFO queue of bytes. It uses a simple buffer, - so should not generally be used for large quantities of data (it can advance the queue - pointer, but Compact() needs to be called regularly to keep memory usage down, and when - it is called, there's a memcpy() penalty for the remaining data. oh well, is what it is). - - You may also wish to look at fastqueue.h or circbuf.h if these limitations aren't acceptable. - -*/ - -#ifndef _WDL_QUEUE_H_ -#define _WDL_QUEUE_H_ - -#include "heapbuf.h" - - -class WDL_Queue -{ -public: - WDL_Queue() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { } - WDL_Queue(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { } - ~WDL_Queue() { } - - template void* AddT(T* buf) - { - return Add(buf, sizeof(T)); - } - - void *Add(const void *buf, int len) - { - int olen=m_hb.GetSize(); - if (m_pos >= olen) m_pos=olen=0; // if queue is empty then autoreset it - - void *obuf=m_hb.Resize(olen+len,false); - if (m_hb.GetSize() != olen+len) return NULL; - - char* newbuf = (char*) obuf + olen; - if (buf) memcpy(newbuf,buf,len); - return newbuf; - } - - template T* GetT(T* val=0) - { - T* p = (T*) Get(sizeof(T)); - if (val && p) *val = *p; - return p; - } - - void* Get(int size) - { - void* p = Get(); - if (p) Advance(size); - return p; - } - - void *Get() const - { - void *buf=m_hb.Get(); - if (buf && m_pos >= 0 && m_pos < m_hb.GetSize()) return (char *)buf+m_pos; - return NULL; - } - - void* Rewind() - { - m_pos = 0; - return m_hb.Get(); - } - - int GetSize() const - { - return m_hb.GetSize()-m_pos; - } - int Available() const { return GetSize(); } - - void Clear() - { - m_pos=0; - m_hb.Resize(0,false); - } - - void Advance(int bytecnt) - { - m_pos+=bytecnt; - if (m_pos<0)m_pos=0; - else if (m_pos > m_hb.GetSize()) m_pos=m_hb.GetSize(); - } - - void Compact(bool allocdown=false, bool force=false) - { - int olen=m_hb.GetSize(); - if (m_pos > (force ? 0 : olen/2)) - { - if (m_pos < olen) - { - void *a=m_hb.Get(); - if (a) memmove(a,(char*)a+m_pos,olen-m_pos); - m_hb.Resize(olen-m_pos,allocdown); - } - else m_hb.Resize(0,allocdown); - m_pos=0; - } - } - - void SetGranul(int granul) { m_hb.SetGranul(granul); } - - - - - // endian-management stuff - - static void WDL_Queue__bswap_buffer(void *buf, int len) - { - #ifdef __ppc__ - char *p=(char *)buf; - char *ep=p+len; - while ((len-=2) >= 0) - { - char tmp=*p; *p++=*--ep; *ep=tmp; - } - #endif - } - - // older API of static functions (that endedu p warning a bit anyway) -#define WDL_Queue__AddToLE(q, v) (q)->AddToLE(v) -#define WDL_Queue__AddDataToLE(q,d,ds,us) (q)->AddDataToLE(d,ds,us) -#define WDL_Queue__GetTFromLE(q,v) (q)->GetTFromLE(v) -#define WDL_Queue__GetDataFromLE(q,ds,us) (q)->GetDataFromLE(ds,us) - - template void AddToLE(T *val) - { - WDL_Queue__bswap_buffer(AddT(val),sizeof(T)); - } - void AddDataToLE(void *data, int datasize, int unitsize) - { - #ifdef __ppc__ - char *dout = (char *)Add(data,datasize); - while (datasize >= unitsize) - { - WDL_Queue__bswap_buffer(dout,unitsize); - dout+=unitsize; - datasize-=unitsize; - } - #else - Add(data,datasize); - #endif - } - - - // NOTE: these thrash the contents of the queue if on LE systems. So for example if you are going to rewind it later or use it elsewhere, - // then get ready to get unhappy. - template T *GetTFromLE(T* val=0) - { - T *p = GetT(val); - if (p) { - WDL_Queue__bswap_buffer(p,sizeof(T)); - if (val) *val = *p; - } - return p; - } - - void *GetDataFromLE(int datasize, int unitsize) - { - void *data=Get(datasize); - #ifdef __ppc__ - char *dout=(char *)data; - if (dout) while (datasize >= unitsize) - { - WDL_Queue__bswap_buffer(dout,unitsize); - dout+=unitsize; - datasize-=unitsize; - } - #endif - return data; - } - - -private: - WDL_HeapBuf m_hb; - int m_pos; - int __pad; // keep 8 byte aligned -}; - -template class WDL_TypedQueue -{ -public: - WDL_TypedQueue() : m_pos(0), m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_TypedQueue")) { } - ~WDL_TypedQueue() { } - - T *Add(const T *buf, int len) - { - int olen=m_hb.GetSize(); - if (m_pos >= olen) olen=m_pos=0; - len *= sizeof(T); - void *obuf=m_hb.Resize(olen+len,false); - if (!obuf||m_hb.GetSize()!=olen+len) return 0; - if (buf) memcpy((char*)obuf+olen,buf,len); - return (T*) ((char*)obuf+olen); - } - - T *Get() const - { - void *buf=m_hb.Get(); - if (buf && m_pos >= 0 && m_pos < m_hb.GetSize()) return (T*)((char *)buf+m_pos); - return NULL; - } - - int GetSize() const - { - return (m_hb.GetSize()-m_pos)/sizeof(T); - } - int Available() const { return GetSize(); } - - void Clear() - { - m_pos=0; - m_hb.Resize(0,false); - } - - void Advance(int cnt) - { - m_pos+=cnt*sizeof(T); - if (m_pos<0)m_pos=0; - else if (m_pos > m_hb.GetSize()) m_pos=m_hb.GetSize(); - } - - void Compact(bool allocdown=false, bool force=false) - { - int olen=m_hb.GetSize(); - if (m_pos > (force ? 0 : olen/2)) - { - if (m_pos < olen) - { - void *a=m_hb.Get(); - if (a) memmove(a,(char*)a+m_pos,olen-m_pos); - m_hb.Resize(olen-m_pos,allocdown); - } - else m_hb.Resize(0,allocdown); - m_pos=0; - } - } - - void SetGranul(int granul) { m_hb.SetGranul(granul); } - -private: - WDL_HeapBuf m_hb; - int m_pos; - int __pad; // keep 8 byte aligned -}; - -#endif diff --git a/WDL/reminder.h b/WDL/reminder.h deleted file mode 100644 index 4518c88b..00000000 --- a/WDL/reminder.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef REMINDER - - #define MAKE_QUOTE(str) #str - #define MAKE_STR(str) MAKE_QUOTE(str) - #if defined WIN32 - // This enables: #pragma REMINDER("change this line!") with click-through from VC++. - #define REMINDER(msg) message(__FILE__ "(" MAKE_STR(__LINE__) "): " msg) - #else - #define REMINDER(msg) // no-op - #endif - -#endif - diff --git a/WDL/resample.cpp b/WDL/resample.cpp deleted file mode 100644 index ec36285f..00000000 --- a/WDL/resample.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* -** Copyright (C) 2010 Cockos Incorporated -** LGPL -**/ -#include "resample.h" -#include - -#include "denormal.h" - -#ifndef min -#define min(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef PI -#define PI 3.1415926535897932384626433832795 -#endif - -class WDL_Resampler::WDL_Resampler_IIRFilter -{ -public: - WDL_Resampler_IIRFilter() - { - m_fpos=-1; - Reset(); - } - ~WDL_Resampler_IIRFilter() - { - } - - void Reset() - { - memset(m_hist,0,sizeof(m_hist)); - } - - void setParms(double fpos, double Q) - { - if (fabs(fpos-m_fpos)<0.000001) return; - m_fpos=fpos; - - double pos = fpos * PI; - double cpos=cos(pos); - double spos=sin(pos); - - double alpha=spos/(2.0*Q); - - double sc=1.0/( 1 + alpha); - m_b1 = (1-cpos) * sc; - m_b2 = m_b0 = m_b1*0.5; - m_a1 = -2 * cpos * sc; - m_a2 = (1-alpha)*sc; - - } - - void Apply(WDL_ResampleSample *in1, WDL_ResampleSample *out1, int ns, int span, int w) - { - double b0=m_b0,b1=m_b1,b2=m_b2,a1=m_a1,a2=m_a2; - double *hist=m_hist[w]; - while (ns--) - { - double in=*in1; - in1+=span; - double out = (double) ( in*b0 + hist[0]*b1 + hist[1]*b2 - hist[2]*a1 - hist[3]*a2); - hist[1]=hist[0]; hist[0]=in; - hist[3]=hist[2]; *out1 = hist[2]=denormal_filter_double(out); - - out1+=span; - } - } - -private: - double m_fpos; - double m_a1,m_a2; - double m_b0,m_b1,m_b2; - double m_hist[WDL_RESAMPLE_MAX_FILTERS*WDL_RESAMPLE_MAX_NCH][4]; -}; - - -void inline WDL_Resampler::SincSample(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, int nch, WDL_SincFilterSample *filter, int filtsz) -{ - int oversize=m_lp_oversize; - int x; - fracpos *= oversize; - int ifpos=(int)fracpos; - filter += oversize-1-ifpos; - fracpos -= ifpos; - - for (x = 0; x < nch; x ++) - { - double sum=0.0,sum2=0.0; - WDL_SincFilterSample *fptr=filter; - WDL_ResampleSample *iptr=inptr+x; - int i=filtsz; - while (i--) - { - sum += fptr[0]*iptr[0]; - sum2 += fptr[1]*iptr[0]; - iptr+=nch; - fptr += oversize; - } - outptr[x]=sum*fracpos + sum2*(1.0-fracpos); - } - -} - -void inline WDL_Resampler::SincSample1(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz) -{ - int oversize=m_lp_oversize; - fracpos *= oversize; - int ifpos=(int)fracpos; - filter += oversize-1-ifpos; - fracpos -= ifpos; - - double sum=0.0,sum2=0.0; - WDL_SincFilterSample *fptr=filter; - WDL_ResampleSample *iptr=inptr; - int i=filtsz; - while (i--) - { - sum += fptr[0]*iptr[0]; - sum2 += fptr[1]*iptr[0]; - iptr++; - fptr += oversize; - } - outptr[0]=sum*fracpos+sum2*(1.0-fracpos); - -} - -void inline WDL_Resampler::SincSample2(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz) -{ - int oversize=m_lp_oversize; - fracpos *= oversize; - int ifpos=(int)fracpos; - filter += oversize-1-ifpos; - fracpos -= ifpos; - - double sum=0.0; - double sum2=0.0; - double sumb=0.0; - double sum2b=0.0; - WDL_SincFilterSample *fptr=filter; - WDL_ResampleSample *iptr=inptr; - int i=filtsz/2; - while (i--) - { - sum += fptr[0]*iptr[0]; - sum2 += fptr[0]*iptr[1]; - sumb += fptr[1]*iptr[0]; - sum2b += fptr[1]*iptr[1]; - sum += fptr[oversize]*iptr[2]; - sum2 += fptr[oversize]*iptr[3]; - sumb += fptr[oversize+1]*iptr[2]; - sum2b += fptr[oversize+1]*iptr[3]; - iptr+=4; - fptr += oversize*2; - } - outptr[0]=sum*fracpos + sumb*(1.0-fracpos); - outptr[1]=sum2*fracpos + sum2b*(1.0-fracpos); - -} - - - -WDL_Resampler::WDL_Resampler() -{ - m_filterq=0.707f; - m_filterpos=0.693f; // .792 ? - - m_sincoversize=0; - m_lp_oversize=1; - m_sincsize=0; - m_filtercnt=1; - m_interp=true; - m_feedmode=false; - - m_filter_coeffs_size=0; - m_sratein=44100.0; - m_srateout=44100.0; - m_ratio=1.0; - m_filter_ratio=-1.0; - m_iirfilter=0; - - Reset(); -} - -WDL_Resampler::~WDL_Resampler() -{ - delete m_iirfilter; -} - -void WDL_Resampler::Reset(double fracpos) -{ - m_last_requested=0; - m_filtlatency=0; - m_fracpos=fracpos; - m_samples_in_rsinbuf=0; - if (m_iirfilter) m_iirfilter->Reset(); -} - -void WDL_Resampler::SetMode(bool interp, int filtercnt, bool sinc, int sinc_size, int sinc_interpsize) -{ - m_sincsize = sinc && sinc_size>= 4 ? sinc_size > 8192 ? 8192 : sinc_size : 0; - m_sincoversize = m_sincsize ? (sinc_interpsize<= 1 ? 1 : sinc_interpsize>=4096 ? 4096 : sinc_interpsize) : 1; - - m_filtercnt = m_sincsize ? 0 : (filtercnt<=0?0 : filtercnt >= WDL_RESAMPLE_MAX_FILTERS ? WDL_RESAMPLE_MAX_FILTERS : filtercnt); - m_interp=interp && !m_sincsize; -// char buf[512]; -// sprintf(buf,"setting interp=%d, filtercnt=%d, sinc=%d,%d\n",m_interp,m_filtercnt,m_sincsize,m_sincoversize); -// OutputDebugString(buf); - - if (!m_sincsize) - { - m_filter_coeffs.Resize(0); - m_filter_coeffs_size=0; - } - if (!m_filtercnt) - { - delete m_iirfilter; - m_iirfilter=0; - } -} - -void WDL_Resampler::SetRates(double rate_in, double rate_out) -{ - if (rate_in<1.0) rate_in=1.0; - if (rate_out<1.0) rate_out=1.0; - if (rate_in != m_sratein || rate_out != m_srateout) - { - m_sratein=rate_in; - m_srateout=rate_out; - m_ratio=m_sratein / m_srateout; - } -} - - -void WDL_Resampler::BuildLowPass(double filtpos) // only called in sinc modes -{ - int wantsize=m_sincsize; - int wantinterp=m_sincoversize; - - if (m_filter_ratio!=filtpos || - m_filter_coeffs_size != wantsize || - m_lp_oversize != wantinterp) - { - m_lp_oversize = wantinterp; - m_filter_ratio=filtpos; - - // build lowpass filter - int allocsize = (wantsize+1)*m_lp_oversize; - WDL_SincFilterSample *cfout=m_filter_coeffs.Resize(allocsize); - if (m_filter_coeffs.GetSize()==allocsize) - { - m_filter_coeffs_size=wantsize; - - int sz=wantsize*m_lp_oversize; - int hsz=sz/2; - double filtpower=0.0; - double windowpos = 0.0; - double dwindowpos = 2.0 * PI/(double)(sz); - double dsincpos = PI / m_lp_oversize * filtpos; // filtpos is outrate/inrate, i.e. 0.5 is going to half rate - double sincpos = dsincpos * (double)(-hsz); - - int x; - for (x = -hsz; x < hsz+m_lp_oversize; x ++) - { - double val = 0.35875 - 0.48829 * cos(windowpos) + 0.14128 * cos(2*windowpos) - 0.01168 * cos(6*windowpos); // blackman-harris - if (x) val *= sin(sincpos) / sincpos; - - windowpos+=dwindowpos; - sincpos += dsincpos; - - cfout[hsz+x] = (WDL_SincFilterSample)val; - if (x < hsz) filtpower += val; - } - filtpower = m_lp_oversize/filtpower; - for (x = 0; x < sz+m_lp_oversize; x ++) - { - cfout[x] = (WDL_SincFilterSample) (cfout[x]*filtpower); - } - } - else m_filter_coeffs_size=0; - - } -} - -double WDL_Resampler::GetCurrentLatency() -{ - double v=((double)m_samples_in_rsinbuf-m_filtlatency)/m_sratein; - - if (v<0.0)v=0.0; - return v; -} - -int WDL_Resampler::ResamplePrepare(int out_samples, int nch, WDL_ResampleSample **inbuffer) -{ - if (nch > WDL_RESAMPLE_MAX_NCH || nch < 1) return 0; - - int fsize=0; - if (m_sincsize>1) fsize = m_sincsize; - - int hfs=fsize/2; - if (hfs>1 && m_samples_in_rsinbuf0) - { - WDL_ResampleSample *p = m_rsinbuf.Resize(m_samples_in_rsinbuf*nch,false); - memset(p,0,sizeof(WDL_ResampleSample)*m_rsinbuf.GetSize()); - } - } - - int sreq = 0; - - if (!m_feedmode) sreq = (int)(m_ratio * out_samples) + 4 + fsize - m_samples_in_rsinbuf; - else sreq = out_samples; - - if (sreq<0)sreq=0; - -again: - m_rsinbuf.Resize((m_samples_in_rsinbuf+sreq)*nch,false); - - int sz = m_rsinbuf.GetSize()/(nch?nch:1) - m_samples_in_rsinbuf; - if (sz!=sreq) - { - if (sreq>4 && !sz) - { - sreq/=2; - goto again; // try again with half the size - } - // todo: notify of error? - sreq=sz; - } - - *inbuffer = m_rsinbuf.Get() + m_samples_in_rsinbuf*nch; - - m_last_requested=sreq; - return sreq; -} - - - -int WDL_Resampler::ResampleOut(WDL_ResampleSample *out, int nsamples_in, int nsamples_out, int nch) -{ - if (nch > WDL_RESAMPLE_MAX_NCH || nch < 1) return 0; - - if (m_filtercnt>0) - { - if (m_ratio > 1.0 && nsamples_in > 0) // filter input - { - if (!m_iirfilter) m_iirfilter = new WDL_Resampler_IIRFilter; - - int n=m_filtercnt; - m_iirfilter->setParms((1.0/m_ratio)*m_filterpos,m_filterq); - - WDL_ResampleSample *buf=(WDL_ResampleSample *)m_rsinbuf.Get() + m_samples_in_rsinbuf*nch; - int a,x; - int offs=0; - for (x=0; x < nch; x ++) - for (a = 0; a < n; a ++) - m_iirfilter->Apply(buf+x,buf+x,nsamples_in,nch,offs++); - } - } - - m_samples_in_rsinbuf += min(nsamples_in,m_last_requested); // prevent the user from corrupting the internal state - - - int rsinbuf_availtemp = m_samples_in_rsinbuf; - - if (nsamples_in < m_last_requested) // flush out to ensure we can deliver - { - int fsize=(m_last_requested-nsamples_in)*2 + m_sincsize*2; - - int alloc_size=(m_samples_in_rsinbuf+fsize)*nch; - WDL_ResampleSample *zb=m_rsinbuf.Resize(alloc_size,false); - if (m_rsinbuf.GetSize()==alloc_size) - { - memset(zb+m_samples_in_rsinbuf*nch,0,fsize*nch*sizeof(WDL_ResampleSample)); - rsinbuf_availtemp = m_samples_in_rsinbuf+fsize; - } - } - - int ret=0; - double srcpos=m_fracpos; - double drspos = m_ratio; - WDL_ResampleSample *localin = m_rsinbuf.Get(); - - WDL_ResampleSample *outptr=out; - - int ns=nsamples_out; - - int outlatadj=0; - - if (m_sincsize) // sinc interpolating - { - if (m_ratio > 1.0) BuildLowPass(1.0 / (m_ratio*1.03)); - else BuildLowPass(1.0); - - int filtsz=m_filter_coeffs_size; - int filtlen = rsinbuf_availtemp - filtsz; - outlatadj=filtsz/2-1; - WDL_SincFilterSample *filter=m_filter_coeffs.Get(); - - if (nch == 1) - { - while (ns--) - { - int ipos = (int)srcpos; - - if (ipos >= filtlen-1) break; // quit decoding, not enough input samples - - SincSample1(outptr,localin + ipos,srcpos-ipos,filter,filtsz); - outptr ++; - srcpos+=drspos; - ret++; - } - } - else if (nch==2) - { - while (ns--) - { - int ipos = (int)srcpos; - - if (ipos >= filtlen-1) break; // quit decoding, not enough input samples - - SincSample2(outptr,localin + ipos*2,srcpos-ipos,filter,filtsz); - outptr+=2; - srcpos+=drspos; - ret++; - } - } - else - { - while (ns--) - { - int ipos = (int)srcpos; - - if (ipos >= filtlen-1) break; // quit decoding, not enough input samples - - SincSample(outptr,localin + ipos*nch,srcpos-ipos,nch,filter,filtsz); - outptr += nch; - srcpos+=drspos; - ret++; - } - } - } - else if (!m_interp) // point sampling - { - if (nch == 1) - { - while (ns--) - { - int ipos = (int)srcpos; - if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples - - *outptr++ = localin[ipos]; - srcpos+=drspos; - ret++; - } - } - else if (nch == 2) - { - while (ns--) - { - int ipos = (int)srcpos; - if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples - - ipos+=ipos; - - outptr[0] = localin[ipos]; - outptr[1] = localin[ipos+1]; - outptr+=2; - srcpos+=drspos; - ret++; - } - } - else - while (ns--) - { - int ipos = (int)srcpos; - if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples - - memcpy(outptr,localin + ipos*nch,nch*sizeof(WDL_ResampleSample)); - outptr += nch; - srcpos+=drspos; - ret++; - } - } - else // linear interpolation - { - if (nch == 1) - { - while (ns--) - { - int ipos = (int)srcpos; - double fracpos=srcpos-ipos; - - if (ipos >= rsinbuf_availtemp-1) - { - break; // quit decoding, not enough input samples - } - - double ifracpos=1.0-fracpos; - WDL_ResampleSample *inptr = localin + ipos; - *outptr++ = inptr[0]*(ifracpos) + inptr[1]*(fracpos); - srcpos+=drspos; - ret++; - } - } - else if (nch == 2) - { - while (ns--) - { - int ipos = (int)srcpos; - double fracpos=srcpos-ipos; - - if (ipos >= rsinbuf_availtemp-1) - { - break; // quit decoding, not enough input samples - } - - double ifracpos=1.0-fracpos; - WDL_ResampleSample *inptr = localin + ipos*2; - outptr[0] = inptr[0]*(ifracpos) + inptr[2]*(fracpos); - outptr[1] = inptr[1]*(ifracpos) + inptr[3]*(fracpos); - outptr += 2; - srcpos+=drspos; - ret++; - } - } - else - { - while (ns--) - { - int ipos = (int)srcpos; - double fracpos=srcpos-ipos; - - if (ipos >= rsinbuf_availtemp-1) - { - break; // quit decoding, not enough input samples - } - - double ifracpos=1.0-fracpos; - int ch=nch; - WDL_ResampleSample *inptr = localin + ipos*nch; - while (ch--) - { - *outptr++ = inptr[0]*(ifracpos) + inptr[nch]*(fracpos); - inptr++; - } - srcpos+=drspos; - ret++; - } - } - } - - - if (m_filtercnt>0) - { - if (m_ratio < 1.0 && ret>0) // filter output - { - if (!m_iirfilter) m_iirfilter = new WDL_Resampler_IIRFilter; - int n=m_filtercnt; - m_iirfilter->setParms(m_ratio*m_filterpos,m_filterq); - - int x,a; - int offs=0; - for (x=0; x < nch; x ++) - for (a = 0; a < n; a ++) - m_iirfilter->Apply(out+x,out+x,ret,nch,offs++); - } - } - - - - if (ret>0 && rsinbuf_availtemp>m_samples_in_rsinbuf) // we had to pad!! - { - // check for the case where rsinbuf_availtemp>m_samples_in_rsinbuf, decrease ret down to actual valid samples - double adj=(srcpos-m_samples_in_rsinbuf + outlatadj) / drspos; - if (adj>0) - { - ret -= (int) (adj + 0.5); - if (ret<0)ret=0; - } - } - - int isrcpos=(int)srcpos; - m_fracpos = srcpos - isrcpos; - m_samples_in_rsinbuf -= isrcpos; - if (m_samples_in_rsinbuf <= 0) m_samples_in_rsinbuf=0; - else - memcpy(localin, localin + isrcpos*nch,m_samples_in_rsinbuf*sizeof(WDL_ResampleSample)*nch); - - - return ret; -} diff --git a/WDL/resample.h b/WDL/resample.h deleted file mode 100644 index 152ac8c5..00000000 --- a/WDL/resample.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -** Copyright (C) 2010 Cockos Incorporated -** LGPL -**/ - -#ifndef _WDL_RESAMPLE_H_ -#define _WDL_RESAMPLE_H_ - -#include -#include -#include "wdltypes.h" -#include "heapbuf.h" - -// default to floats for sinc filter ceofficients -#ifdef WDL_RESAMPLE_FULL_SINC_PRECISION -typedef double WDL_SincFilterSample; -#else -typedef float WDL_SincFilterSample; -#endif - -// default to doubles for audio samples -#ifdef WDL_RESAMPLE_TYPE -typedef WDL_RESAMPLE_TYPE WDL_ResampleSample; -#else -typedef double WDL_ResampleSample; -#endif - - -#ifndef WDL_RESAMPLE_MAX_FILTERS -#define WDL_RESAMPLE_MAX_FILTERS 4 -#endif - -#ifndef WDL_RESAMPLE_MAX_NCH -#define WDL_RESAMPLE_MAX_NCH 64 -#endif - - -class WDL_Resampler -{ -public: - WDL_Resampler(); - ~WDL_Resampler(); - // if sinc set, it overrides interp or filtercnt - void SetMode(bool interp, int filtercnt, bool sinc, int sinc_size=64, int sinc_interpsize=32); - - void SetFilterParms(float filterpos=0.693, float filterq=0.707) { m_filterpos=filterpos; m_filterq=filterq; } // used for filtercnt>0 but not sinc - void SetFeedMode(bool wantInputDriven) { m_feedmode=wantInputDriven; } // if true, that means the first parameter to ResamplePrepare will specify however much input you have, not how much you want - - void Reset(double fracpos=0.0); - void SetRates(double rate_in, double rate_out); - - double GetCurrentLatency(); // amount of input that has been received but not yet converted to output, in seconds - - // req_samples is output samples desired if !wantInputDriven, or if wantInputDriven is input samples that we have - // returns number of samples desired (put these into *inbuffer) - // note that it is safe to call ResamplePrepare without calling ResampleOut (the next call of ResamplePrepare will function as normal) - int ResamplePrepare(int req_samples, int nch, WDL_ResampleSample **inbuffer); - - - // if numsamples_in < the value return by ResamplePrepare(), then it will be flushed to produce all remaining valid samples - // do NOT call with nsamples_in greater than the value returned from resamplerprpare()! the extra samples will be ignored. - // returns number of samples successfully outputted to out - int ResampleOut(WDL_ResampleSample *out, int nsamples_in, int nsamples_out, int nch); - - - -private: - void BuildLowPass(double filtpos); - void inline SincSample(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, int nch, WDL_SincFilterSample *filter, int filtsz); - void inline SincSample1(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz); - void inline SincSample2(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz); - - double m_sratein WDL_FIXALIGN; - double m_srateout; - double m_fracpos; - double m_ratio; - double m_filter_ratio; - float m_filterq, m_filterpos; - WDL_TypedBuf m_rsinbuf; - WDL_TypedBuf m_filter_coeffs; - - class WDL_Resampler_IIRFilter; - WDL_Resampler_IIRFilter *m_iirfilter; - - int m_filter_coeffs_size; - int m_last_requested; - int m_filtlatency; - int m_samples_in_rsinbuf; - int m_lp_oversize; - - int m_sincsize; - int m_filtercnt; - int m_sincoversize; - bool m_interp; - bool m_feedmode; - -}; - - - -#endif diff --git a/WDL/rfb_client.cpp b/WDL/rfb_client.cpp deleted file mode 100644 index ce84bdc3..00000000 --- a/WDL/rfb_client.cpp +++ /dev/null @@ -1,443 +0,0 @@ -#include "rfb_client.h" -#include "lice/lice.h" - -#include "des.h" - -#define CONNECTION_TIMEOUT 30 -#define NORMAL_TIMEOUT 30 -#define OUR_VERSION_STRING "RFB 003.000\n" - - -//#define WANT_RRE // seems to be broken on many servers - -#define ENCODE_TYPE_RAW 0 -#define ENCODE_TYPE_SCREENSIZE -223 -#define ENCODE_TYPE_RRE 2 -//#define ENCODE_TYPE_CORRE 3 -//#define ENCODE_TYPE_HEXTILE 5 - - -WDL_RFB_Client::WDL_RFB_Client(JNL_IConnection *con, const char *password) -{ - m_skipdata=0; - m_req_x=m_req_y=m_req_w=m_req_h=m_needref=0; - m_errstr=0; - m_state=InitialState; - m_con=con; - m_password.Set(password?password:""); - m_screen_w=m_screen_h=0; - m_remote_ver=0; - instance_data=0; - DrawRectangleCallback=0; - time(&m_lastt); -} - -WDL_RFB_Client::~WDL_RFB_Client() -{ - delete m_con; -} - - -unsigned int WDL_RFB_Client::GetBE(int nb, int queueoffs, bool advance) -{ - unsigned char *buf=m_msg_buf.Get()+queueoffs; - - unsigned int a=0; - if (nb==4) a= (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; - else if (nb==3) a=(buf[0]<<16) | (buf[1]<<8) | buf[2]; - else if (nb==2) a=(buf[0]<<8) | (buf[1]); - else if (nb==1) a=(buf[0]); - - if (advance) m_msg_buf.Advance(queueoffs+nb); - - return a; -} - -int WDL_RFB_Client::Run() -{ - if (!m_con||m_state == ErrorState) return -1; - - int cnt=0; - - while (m_state != ErrorState) - { - int bytes_needed=1; - int old_avail = m_msg_buf.Available(); - - switch (m_state) - { - case InitialState: - if (m_msg_buf.Available()>=12) - { - unsigned char *buf = m_msg_buf.Get(); - - if (memcmp(buf,"RFB ",4) || buf[7] != '.'||buf[11] != '\n') - { - m_state=ErrorState; - m_errstr = "Server gave invalid line"; - } - else - { - buf[7]=0; - buf[11]=0; - m_remote_ver = atoi((char*)buf+4)*1000 + atoi((char*)buf+8); - if (m_remote_ver < 3000 || m_remote_ver >= 4000) - { - m_state=ErrorState; - m_errstr = "Server gave invalid version"; - } - else - { - m_con->send_bytes(OUR_VERSION_STRING,strlen(OUR_VERSION_STRING)); - m_state = AuthWaitState; - } - } - m_msg_buf.Advance(12); - } - else bytes_needed=12; - break; - case AuthWaitState: - if (m_msg_buf.Available()>=4) - { - unsigned int type = GetBE(4,0,false); - if (type==0) - { - m_state=ErrorState; - m_errstr = "Server permission denied"; - } - else if (type==1) - { - m_state=ServerInitState; - m_msg_buf.Advance(4); - - char c=1; // allow sharing - m_con->send_bytes(&c,1); - } - else if (type == 2) - { - if (m_msg_buf.Available() >= 4+16) - { - m_msg_buf.Advance(4); - unsigned char challenge[16]; - memcpy(challenge,m_msg_buf.Get(),16); - m_msg_buf.Advance(16); - - unsigned char buf[8]; - memset(buf,0,sizeof(buf)); - memcpy(buf,m_password.Get(),min(strlen(m_password.Get()),8)); - WDL_DES des; - des.SetKey(buf,true); - des.Process8(challenge); - des.Process8(challenge+8); - m_con->send_bytes(challenge,16); - m_state=AuthWaitState2; - } - else bytes_needed=4+16; - } - else - { - m_state=ErrorState; - m_errstr = "Unknown authentication method"; - } - } - else bytes_needed=4; - break; - case AuthWaitState2: - if (m_msg_buf.Available()>=4) - { - unsigned int type = GetBE(); - if (type==0) - { - m_state=ServerInitState; - - char c=1; // allow sharing - m_con->send_bytes(&c,1); - } - else - { - m_state=ErrorState; - m_errstr = type==1 ? "Auth failed" : type==2 ? "Too many connections" : "Auth failed (unknown reason)"; - } - } - else bytes_needed=4; - break; - case ServerInitState: - { - if (m_msg_buf.Available()>=2+2+16+4) - { - unsigned int nl = GetBE(4,2+2+16,false); - if (m_msg_buf.Available()>=2+2+16+4 + nl) - { - m_screen_w = GetBE(2); - m_screen_h = GetBE(2); - - m_msg_buf.Advance(16+4); // skip color map and length - - memcpy(m_namebuf.Resize(nl+1),m_msg_buf.Get(),nl); - m_msg_buf.Advance(nl); - m_namebuf.Get()[nl]=0; - - // request our pixel format - - { - unsigned char buf[20]={0,}; - buf[0] = 0; // request pixel format - // 3 bytes padding - buf[4] = 32; - buf[5] = 24; - buf[6] = 0; // always LE - buf[7] = 1; // true-color - - buf[8] = 0; buf[9]=255; // masks - buf[10] = 0; buf[11]=255; - buf[12] = 0; buf[13]=255; - - buf[14] = LICE_PIXEL_R*8; // shifts - buf[15] = LICE_PIXEL_G*8; - buf[16] = LICE_PIXEL_B*8; - - // 3 bytes padding - - m_con->send_bytes(buf,sizeof(buf)); - } - // request encodings - { - const int encs[]={ -#ifdef WANT_RRE - ENCODE_TYPE_RRE, -#endif - ENCODE_TYPE_RAW,ENCODE_TYPE_SCREENSIZE,}; - const int nencs = sizeof(encs)/sizeof(encs[0]); - - unsigned char buf[4+nencs*4]={0,}; - buf[0]=2; //encodings - buf[2] = (nencs>>8)&0xff; - buf[3] = nencs&0xff; - int x; - for(x=0;x>24)&0xff; - buf[4+x*4+1] = (encs[x]>>16)&0xff; - buf[4+x*4+2] = (encs[x]>>8)&0xff; - buf[4+x*4+3] = (encs[x])&0xff; - } - m_con->send_bytes(buf,sizeof(buf)); - } - - m_state=RunState; - m_needref=2; - } - else bytes_needed=2+2+16+4+nl; - } - else bytes_needed=2+2+16+4; - } - break; - case RunState: - - if (m_needref) - { - unsigned char buf[10]={0,}; - buf[0]=3; - buf[1]=(m_needref & 2)?false:true; - if (!m_req_w || !m_req_h) - { - buf[6]=(m_screen_w>>8)&0xff; - buf[7]=m_screen_w&0xff; - buf[8]=(m_screen_h>>8)&0xff; - buf[9]=m_screen_h&0xff; - } - else - { - buf[2]=(m_req_x>>8)&0xff; - buf[3]=m_req_x&0xff; - buf[4]=(m_req_x>>8)&0xff; - buf[5]=m_req_x&0xff; - buf[6]=(m_req_w>>8)&0xff; - buf[7]=m_req_w&0xff; - buf[8]=(m_req_h>>8)&0xff; - buf[9]=m_req_h&0xff; - } - m_needref=0; - m_con->send_bytes(buf,sizeof(buf)); - } - - if (m_skipdata>0) - { - int a= min(m_msg_buf.Available(),m_skipdata); - m_msg_buf.Advance(a); - m_skipdata-=a; - } - - if (m_msg_buf.Available()>0) - { - m_skipdata=0; - unsigned char msg = *(unsigned char *)m_msg_buf.Get(); - switch (msg) - { - case 0: // framebuffer update - if (m_msg_buf.Available() >= 4) - { - unsigned char *buf=m_msg_buf.Get(); - m_msg_buf.Advance(4); - - m_msg_state=(buf[2]<<8)+buf[3]; - if (m_msg_state>0) - { - m_state=RunState_GettingRects; - } - } - else bytes_needed=4; - break; - case 1: // color map crap - if (m_msg_buf.Available()>=6) - { - m_skipdata = GetBE(2,4)*6; // skip 4 bytes, read 2, then skip that - } - break; - case 2: // bell, skip - m_msg_buf.Advance(1); - break; - case 3: // copy text, skip - if (m_msg_buf.Available()>=8) - { - m_skipdata=GetBE(4,4); // skip 4 bytes, read 4 - } - break; - default: - m_state=ErrorState; - sprintf(tmperrbuf,"Got unknown message: %d",msg); - m_errstr=tmperrbuf; - break; - } - } - break; - case RunState_GettingRects: - if (m_msg_state>0) - { - if (m_msg_buf.GetSize()>=12) - { - int xpos = GetBE(2,0,false); - int ypos = GetBE(2,2,false); - int w=GetBE(2,4,false); - int h=GetBE(2,6,false); - int enc = GetBE(4,8,false); - - switch (enc) - { - case ENCODE_TYPE_SCREENSIZE: - { - if (w>m_screen_w || h>m_screen_h) m_needref=2; - m_screen_w = w; - m_screen_h = h; - m_msg_buf.Advance(12); - } - break; - case ENCODE_TYPE_RRE: - if (m_msg_buf.GetSize()>=12+8) - { - unsigned int nr = GetBE(4,12,false); - if (m_msg_buf.GetSize()>=12+8 + nr*12) - { - LICE_pixel bgc = GetBE(4,12+4); - if (DrawRectangleCallback) - { - m_bm.resize(w,h); - LICE_FillRect(&m_bm,0,0,w,h,bgc,1.0f,LICE_BLIT_MODE_COPY); - - while (nr-->0) - { - bgc=GetBE(); - int lx=GetBE(2); - int ly=GetBE(2); - int lw=GetBE(2); - int lh=GetBE(2); - LICE_FillRect(&m_bm,lx,ly,lw,lh,bgc,1.0f,LICE_BLIT_MODE_COPY); - } - - DrawRectangleCallback(this,&m_bm,xpos,ypos,w,h); - } - else m_msg_buf.Advance(nr*12); - - --m_msg_state; - } - else bytes_needed = 12+8 + nr*12; - } - else bytes_needed=12+8; - break; - case ENCODE_TYPE_RAW: // raw - if (m_msg_buf.GetSize()>=12+w*h*4) // we only support 32bpp for now - { - if (DrawRectangleCallback) - { - LICE_pixel *src = (LICE_pixel *)(m_msg_buf.Get()+12); - m_bm.resize(w,h); - LICE_pixel *out = m_bm.getBits(); - int rs = m_bm.getRowSpan(); - int a; - for (a=0;arun(); - - while (m_msg_buf.Available()recv_bytes_available(); - if (a>0) - { - m_con->recv_bytes(m_msg_buf.Add(NULL,a),a); - time(&m_lastt); - } - else break; - - m_con->run(); - } - - if (old_avail == m_msg_buf.Available()|| - m_msg_buf.Available() m_lastt+(m_state < RunState ? CONNECTION_TIMEOUT : NORMAL_TIMEOUT) || m_con->get_state()==JNL_Connection::STATE_CLOSED|| m_con->get_state()==JNL_Connection::STATE_ERROR) - { - m_state=ErrorState; - m_errstr = "Timed out"; - } - - return cnt>0; -} - diff --git a/WDL/rfb_client.h b/WDL/rfb_client.h deleted file mode 100644 index d69483cb..00000000 --- a/WDL/rfb_client.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _WDL_RFBCLIENT_H_ -#define _WDL_RFBCLIENT_H_ - -#include "wdlstring.h" -#include "queue.h" -#include "jnetlib/jnetlib.h" -#include "lice/lice.h" - -class WDL_RFB_Client -{ -public: - WDL_RFB_Client(JNL_IConnection *con, const char *password); - ~WDL_RFB_Client(); - - int GetScreenWidth() { return m_screen_w; } - int GetScreenHeight() { return m_screen_h; } - - int Run(); // <0 on disconnect, - const char *GetError() { return m_errstr; } - - void Invalidate() { m_needref=2; } // tell server to re-send - void SetUpdateRegion(int x, int y, int w, int h) // if w or h are 0 then whole screen is used - { - m_req_x=x; - m_req_y=y; - m_req_w=w; - m_req_h=h; - - } - void RequestUpdate() { m_needref|=1; } - - void *instance_data; - void (*DrawRectangleCallback)(WDL_RFB_Client *_this, LICE_IBitmap *drawimg, int dest_x, int dest_y, int dest_w, int dest_h); - - -private: - - enum { ErrorState=-1, InitialState=0, AuthWaitState, AuthWaitState2, ServerInitState, RunState, RunState_GettingRects}; - - int m_remote_ver; // xxxyyy - - int m_state; - time_t m_lastt; - const char *m_errstr; - - WDL_String m_password; - JNL_IConnection *m_con; - - int m_screen_w, m_screen_h; - - int m_req_x,m_req_y,m_req_w,m_req_h, m_needref; - - WDL_TypedBuf m_namebuf; - WDL_TypedQueue m_msg_buf; - - int m_skipdata; - - int m_msg_state; // state specific value / data - - unsigned int GetBE(int nb=4, int queueoffs=0, bool advance=true); - - LICE_MemBitmap m_bm; - - char tmperrbuf[128]; -}; - - - - -#endif//_WDL_RFBCLIENT_H_ \ No newline at end of file diff --git a/WDL/rng.cpp b/WDL/rng.cpp deleted file mode 100644 index 073abbd1..00000000 --- a/WDL/rng.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - WDL - rng.cpp - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides the implementation of a decent random number generator, - that internally uses a 256-bit state, and SHA-1 to iterate. - -*/ - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#ifndef min -#define min(x,y) ((x)<(y)?(x):(y)) -#endif -#endif - - -#include "rng.h" -#include "sha.h" - -static unsigned char state[32]; - -void WDL_RNG_addentropy(void *buf, int buflen) -{ - WDL_SHA1 tmp; - tmp.add(state,sizeof(state)); - tmp.result(state); - tmp.reset(); - tmp.add((unsigned char *)buf,buflen); - tmp.result(state+sizeof(state) - WDL_SHA1SIZE); -} - -static void rngcycle() -{ - int i; - for (i = 0; i < (int)sizeof(state) && state[i]++; i++); -} - -int WDL_RNG_int32() -{ - WDL_SHA1 tmp; - tmp.add(state,sizeof(state)); - rngcycle(); - union { - char buf[WDL_SHA1SIZE]; - int a; - } b; - tmp.result(b.buf); - return b.a; - -} - - -void WDL_RNG_bytes(void *buf, int buflen) -{ - char *b=(char *)buf; - while (buflen > 0) - { - char tb[WDL_SHA1SIZE]; - WDL_SHA1 tmp; - tmp.add(state,sizeof(state)); - rngcycle(); - - tmp.result(tb); - int l=min(buflen,WDL_SHA1SIZE); - memcpy(b,tb,l); - buflen-=l; - b+=l; - } -} - diff --git a/WDL/rng.h b/WDL/rng.h deleted file mode 100644 index 873486c7..00000000 --- a/WDL/rng.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - WDL - rng.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This header provides the interface to a decent random number generator, - that internally uses a 256-bit state, and SHA-1 to iterate. We wouldn't consider - this RNG to be cryptographically secure, but it may be decent. - -*/ - -#ifndef _WDL_RNG_H_ -#define _WDL_RNG_H_ - - -void WDL_RNG_addentropy(void *buf, int buflen); // add entropy to the RNG - -int WDL_RNG_int32(); // get a random integer -void WDL_RNG_bytes(void *buf, int buflen); // get a random string of bytes - - -#endif - diff --git a/WDL/rpool.h b/WDL/rpool.h deleted file mode 100644 index 47f05bee..00000000 --- a/WDL/rpool.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - WDL - rpool.h - Copyright (C) 2006 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file defines a template for a class that stores a list of objects, and allows the caller - to periodically get an object, do something with it, and add it back into the pool. - - When the caller does this, it can set ownership of the object, and an expiration for that ownership. - - - The PTYPE1 and PTYPE2entries for the template are there to store additional information (for use with poollist.h) - - - This is pretty esoteric. But we use it for some things. - -*/ - - -#ifndef _WDL_RPOOL_H_ -#define _WDL_RPOOL_H_ - -// resource pool (time based) - -#include "ptrlist.h" -#include "mutex.h" - -class WDL_ResourcePool_ResInfo // include in class RTYPE as WDL_ResourcePool_ResInfo m_rpoolinfo; -{ -public: - WDL_ResourcePool_ResInfo(){ m_owneduntil=0; m_ownerptr=0; next=0; } - ~WDL_ResourcePool_ResInfo() {} - - unsigned int m_owneduntil; - void *m_ownerptr; - - void *next; -} WDL_FIXALIGN; - - -template class WDL_ResourcePool -{ - public: - WDL_ResourcePool(char *identstr) - { - WDL_POOLLIST_refcnt=0; - WDL_POOLLIST_identstr=identstr; - m_rlist=NULL; - extraInfo=0; - m_hadres=false; - } - ~WDL_ResourcePool() - { - while (m_rlist) - { - RTYPE *tp=m_rlist; - m_rlist=(RTYPE *)m_rlist->m_rpoolinfo.next; - delete tp; - } - delete extraInfo; - } - void Clear() - { - m_mutex.Enter(); - while (m_rlist) - { - RTYPE *tp=m_rlist; - m_rlist=(RTYPE *)m_rlist->m_rpoolinfo.next; - delete tp; - } - m_hadres=false; - m_mutex.Leave(); - } - bool HasResources() - { - return m_hadres; - } - - void AddResource(RTYPE *item, void *own, unsigned int until) - { - item->m_rpoolinfo.m_ownerptr = own; - item->m_rpoolinfo.m_owneduntil = until; - - m_mutex.Enter(); - item->m_rpoolinfo.next = m_rlist; - m_rlist = item; - m_hadres=true; - m_mutex.Leave(); - } - - void ReleaseResources(void *own) - { - m_mutex.Enter(); - RTYPE *ent=m_rlist; - while (ent) - { - if (ent->m_rpoolinfo.m_ownerptr == own) - { - ent->m_rpoolinfo.m_ownerptr = 0; - ent->m_rpoolinfo.m_owneduntil=0; - } - ent=(RTYPE *)ent->m_rpoolinfo.next; - } - m_mutex.Leave(); - } - - RTYPE *GetResource(void *own, unsigned int now) - { - m_mutex.Enter(); - RTYPE *ent=m_rlist, *lastent=NULL, *bestent=NULL, *bestlastent=NULL; - bool bestnoown=false; - while (ent) - { - if (ent->m_rpoolinfo.m_ownerptr == own) - { - if (lastent) lastent->m_rpoolinfo.next = ent->m_rpoolinfo.next; - else m_rlist = (RTYPE *)ent->m_rpoolinfo.next; - m_mutex.Leave(); - return ent; - } - - if (!bestnoown && (!ent->m_rpoolinfo.m_ownerptr || ent->m_rpoolinfo.m_owneduntil < now)) - { - bestent=ent; - bestlastent=lastent; - if (!ent->m_rpoolinfo.m_ownerptr || !ent->m_rpoolinfo.m_owneduntil) bestnoown=true; - } - lastent=ent; - ent=(RTYPE *)ent->m_rpoolinfo.next; - } - - if (bestent) - { - if (bestlastent) bestlastent->m_rpoolinfo.next = bestent->m_rpoolinfo.next; - else m_rlist = (RTYPE *)bestent->m_rpoolinfo.next; - } - - m_mutex.Leave(); - return bestent; - } - - int WDL_POOLLIST_refcnt; - char *WDL_POOLLIST_identstr; - bool m_hadres; - - EXTRAINFOTYPE *extraInfo; - - RTYPE *PeekList() - { - return m_rlist; - } - void LockList() - { - m_mutex.Enter(); - } - void UnlockList() - { - m_mutex.Leave(); - } - -private: - - WDL_Mutex m_mutex; - RTYPE *m_rlist; - -} WDL_FIXALIGN; - - - -#endif diff --git a/WDL/sc_bounce/stream-config.php b/WDL/sc_bounce/stream-config.php deleted file mode 100644 index 5ec731e7..00000000 --- a/WDL/sc_bounce/stream-config.php +++ /dev/null @@ -1,21 +0,0 @@ - array("password" => "somePassword", "listen_password" => "",), - -); - - -// performance tweaks ( safe to leave these as is for now ) - -$config_num_files = 4; -$config_file_timeout = 30; - -?> diff --git a/WDL/sc_bounce/stream.php b/WDL/sc_bounce/stream.php deleted file mode 100644 index 7ce2e64b..00000000 --- a/WDL/sc_bounce/stream.php +++ /dev/null @@ -1,243 +0,0 @@ - $now-60)) && ($oldest_index<0 || $t < $oldest_time)) - { - $oldest_index = $x; - $oldest_time = $t; - } -} - - -if ($is_bc) -{ - if (trim($_POST['broadcast']) != $this_stream["password"]) - { - header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Password"); - die("invalid password"); - } - - if (!$_FILES || !($file = $_FILES["file"])) die("no file sent"); - - if (!is_dir($config_temp_dir)) @mkdir($config_temp_dir,0775); - - $sessinfo = read_session_file($sessfn); - - $last_sess = $sessinfo[0]; - $this_sess = filter_var($_REQUEST['session'],FILTER_SANITIZE_NUMBER_INT); - - if ($last_sess != $this_sess || - rtrim($_REQUEST['name']) != $sessinfo[1] || - rtrim($_REQUEST['title']) != $sessinfo[2] ) - write_session_file($sessfn,$this_sess,$_REQUEST['name'],$_REQUEST['title']); - - if ($last_sess != $this_sess) - { - for ($x = 0; $x < $config_num_files; $x ++) @unlink($fns[$x]); // clear out history - $oldest_index=0; - } - else if ($oldest_index<0) $oldest_index=0; - - @unlink($fns[$oldest_index]); - -// echo "suc maybe: '" . $file["tmp_name"] . "' to '" . $fns[$oldest_index] . "' '" . $file["size"] . "'\n"; - move_uploaded_file($file["tmp_name"], $fns[$oldest_index]); - die; -} - -// stream, validate password if set -if ($this_stream["listen_password"] != "" && - $this_stream["listen_password"] != trim($_REQUEST["password"])) -{ - header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream Password"); - die("invalid password"); -} - -// make sure stream is up - -// advance past old item since it'll likely get replaced soon -if ($oldest_index>=0) -{ - $oldest_index += 1; - if ($oldest_index >= $config_num_files) $oldest_index = 0; -} - -if ($oldest_index < 0 || !($fp = @fopen($fns[$oldest_index],"rb"))) -{ - header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive"); - die("stream inactive"); -} -$sessinfo = read_session_file($sessfn); -$sesstime = filemtime($sessfn); - -if ($_REQUEST['get'] == "title") die($sessinfo[2]); - -set_time_limit(3600*3); -header("Content-type: audio/x-mpeg"); -header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 -header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past -$streamname = trim($sessinfo[1]); -if ($streamname != "") header("icy-name: $streamname"); - -$want_title = rtrim($sessinfo[2]); - -$meta_block = ""; -$meta_int=$meta_pos=0; - -if ((int)$_SERVER['HTTP_ICY_METADATA'] > 0) -{ - $meta_int = 32000; - header("icy-metaint: $meta_int"); - if ($_SERVER["SERVER_PROTOCOL"] != "HTTP/1.0") - { - // VLC requires an invalid content-length to prevent chunked mode - if (strstr($_SERVER["HTTP_USER_AGENT"],"VLC")) header("Content-length:-1"); - } -} - -while (!connection_aborted()) -{ - if (!$fp) - { - clearstatcache(); - if ( ($t=@filemtime($fns[$oldest_index])) >= $oldest_time && - @filesize($fns[$oldest_index])>0 && - ($fp = @fopen($fns[$oldest_index],"rb"))) - { - $oldest_time = $t; - if ($meta_int > 0 && $want_title == "") - { - $t = filemtime($sessfn); - if ($t > $sesstime) - { - $oldtitle = rtrim($sessinfo[2]); - $sessinfo = read_session_file($sessfn); - $sesstime=$t; - if ($oldtitle != rtrim($sessinfo[2])) $want_title = rtrim($sessinfo[2]); - } - } - } - else - { - if (time() > $last_read_time + $config_file_timeout) - { - break; - } - usleep(250000); - } - } - else - { - $rdamt = 4096; - if ($meta_int > 0 && $rdamt > ($meta_int-$meta_pos)) $rdamt = ($meta_int - $meta_pos); - $buf = fread($fp,$rdamt); - if ($buf == '') - { - fclose($fp); - $fp = 0; - - $oldest_index += 1; - if ($oldest_index >= $config_num_files) $oldest_index = 0; - } - else - { - echo $buf; - $last_read_time = time(); - - if ($meta_int > 0) - { - $meta_pos += strlen($buf); - if ($meta_pos >= $meta_int) - { - $meta_pos=0; - if ($want_title != "") - { - $want_title = str_replace("'","",$want_title); - $want_title = "StreamTitle='$want_title';"; - $tb=(int) (((strlen($want_title) + 1 + 15)/16)); - echo chr($tb); - echo $want_title; - $tb = $tb*16 - strlen($want_title); - while ($tb-- > 0) echo chr(0); - $want_title=""; - } - else echo chr(0); - $meta_block = ""; - } - } - } - } -} - -if ($fp) fclose($fp); - - -?> diff --git a/WDL/scsrc.cpp b/WDL/scsrc.cpp deleted file mode 100644 index 3d9a7f35..00000000 --- a/WDL/scsrc.cpp +++ /dev/null @@ -1,700 +0,0 @@ -/* - WDL - scsrc.cpp - Copyright (C) 2007, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - - -*/ - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#include -#include -#include -typedef int DWORD; - -static void Sleep(int ms) -{ - usleep(ms?ms*1000:100); -} - -static unsigned int GetTickCount() -{ - struct timeval tm={0,}; - gettimeofday(&tm,NULL); - return tm.tv_sec*1000 + tm.tv_usec/1000; -} - -#endif // !_WIN32 - -#include - -#include "scsrc.h" -#include "jnetlib/jnetlib.h" -#include "wdlcstring.h" - -// maybe we need to do this better someday -#define POST_DIV_STRING "zzzASFIJAHFASJFHASLKFHZI8" -#define END_POST_BYTES "\r\n--" POST_DIV_STRING "--\r\n" - - -#define ERR_NOLAME -600 -#define ERR_CREATINGENCODER -599 - -#define ERR_TIMEOUT -4 -#define ERR_CONNECT -5 -#define ERR_AUTH -6 - -#define ST_OK 0 -#define ST_CONNECTING 1 -#define ERR_DISCONNECTED_AFTER_SUCCESS 32 -WDL_ShoutcastSource::WDL_ShoutcastSource(const char *host, const char *pass, const char *name, bool pub, - const char *genre, const char *url, - int nch, int srate, int kbps, const char *ircchan) -{ - m_post_postsleft=0; - m_postmode_session=GetTickCount(); - m_is_postmode = !!strstr(host,"/"); - - totalBitrate=0; - sendProcessor=0; - userData=0; - - JNL::open_socketlib(); - m_host.Set(host); - m_pass.Set(pass); - if (name) m_name.Set(name); - if (url) m_url.Set(url); - if (genre) m_genre.Set(genre); - if (ircchan) m_ircchan.Set(ircchan); - m_pub=pub; - m_br=kbps; - - m_state=ST_CONNECTING; // go to 0 when we - m_nch=nch==2?2:1; - m_bytesout=0; - m_srate=srate; - m_last_samples[0]=m_last_samples[1]=0.0; - m_rspos=0.0; - m_sendcon=0; - - m_needtitle=0; - m_title[0]=0; - m_titlecon=0; - m_titlecon_start=0; - m_encoder_splsin=0; - m_encoder=new LameEncoder(m_srate,m_nch,m_br); - int s=m_encoder->Status(); - if (s == 1) m_state=ERR_NOLAME; - else if (s) m_state=ERR_CREATINGENCODER; - - if (s) { delete m_encoder; m_encoder=0; } - - m_sendcon_start=time(NULL); - if (m_encoder) - { - if (m_is_postmode) - { - PostModeConnect(); - } - else - { - m_sendcon = new JNL_Connection(JNL_CONNECTION_AUTODNS,65536,65536); - WDL_String hb(m_host.Get()); - int port=8000; - char *p=strstr(hb.Get(),":"); - if (p) - { - *p++=0; - port = atoi(p); - if (!port) port=8000; - } - m_sendcon->connect(hb.Get(), port+1); - - m_sendcon->send_string(m_pass.Get()); - m_sendcon->send_string("\r\n"); - } - } - -} - -WDL_ShoutcastSource::~WDL_ShoutcastSource() -{ - delete m_titlecon; - delete m_sendcon; - delete m_encoder; -} - -int WDL_ShoutcastSource::GetStatus() // returns 0 if connected/connecting, >0 if disconnected, -1 if failed connect (or other error) from the start -{ - if (m_state= ERR_DISCONNECTED_AFTER_SUCCESS) return m_state; - return 0; -} - -void WDL_ShoutcastSource::GetStatusText(char *buf, int bufsz) // gets status text -{ - if (m_state == ST_OK) snprintf(buf,bufsz,"Connected. Sent %u bytes",m_bytesout); - else if (m_state == ST_CONNECTING) lstrcpyn_safe(buf,"Connecting...",bufsz); - else if (m_state == ERR_DISCONNECTED_AFTER_SUCCESS) snprintf(buf,bufsz,"Disconnected after sending %u bytes",m_bytesout); - else if (m_state == ERR_AUTH) lstrcpyn_safe(buf,"Error authenticating with server",bufsz); - else if (m_state == ERR_CONNECT) lstrcpyn_safe(buf,"Error connecting to server",bufsz); - else if (m_state == ERR_TIMEOUT) lstrcpyn_safe(buf,"Timed out connecting to server",bufsz); - else if (m_state == ERR_CREATINGENCODER) lstrcpyn_safe(buf,"Error creating encoder",bufsz); - else if (m_state == ERR_NOLAME) - #ifdef _WIN32 - lstrcpyn_safe(buf,"Error loading lame_enc.dll",bufsz); - #else - lstrcpyn_safe(buf,"Error loading libmp3lame.dylib",bufsz); - #endif - else lstrcpyn_safe(buf,"Error creating encoder",bufsz); - -} - -void WDL_ShoutcastSource::SetCurTitle(const char *title) -{ - m_titlemutex.Enter(); - lstrcpyn_safe(m_title,title,sizeof(m_title)); - m_needtitle=true; - m_titlemutex.Leave(); - -} - -void WDL_ShoutcastSource::OnSamples(float **samples, int nch, int chspread, int frames, double srate) -{ - m_samplemutex.Enter(); - - if (fabs(srate-m_srate)<1.0) - { - float *ob=m_rsbuf.Resize(frames*m_nch,false); - int x=frames; - int a=0; - if (nch < 2 && m_nch < 2) - { - while (x--) - { - *ob++ = samples[0][a]; - a+=chspread; - } - } - else if (nch < 2 && m_nch > 1) - { - while (x--) - { - ob[0] = ob[1] = samples[0][a]; - ob+=2; - a+=chspread; - } - } - else if (nch > 1 && m_nch > 1) - { - while (x--) - { - *ob++ = samples[0][a]; - *ob++ = samples[1][a]; - a+=chspread; - } - } - else - { - while (x--) - { - *ob++ = (samples[0][a]+samples[1][a])*0.5f; - a+=chspread; - } - } - if (m_samplequeue.Available() < (int)sizeof(float)*m_nch*96000*4 && - m_encoder && m_encoder->outqueue.Available() < 256*1024) - m_samplequeue.Add(m_rsbuf.Get(),frames*m_nch*sizeof(float)); - } - else - { - double rateratio = srate/m_srate; - - double fracpos=m_rspos; - int outlen=(int) ((frames+fracpos)/rateratio); - float *outptr=m_rsbuf.Resize(outlen*m_nch,false); - - int x; - int loffs=-1000; - double ls[2]={m_last_samples[0],m_last_samples[1]}; - for (x = 0; x < outlen; x ++) - { - int ioffs=(int)fracpos; - double fp=fracpos-ioffs; - - ioffs *= chspread; - - if (ioffs>0) - { - ls[0]=samples[0][ioffs-chspread]; - ls[1]=samples[nch-1][ioffs-chspread]; - } - - if (m_nch>1) - { - *outptr++ = (float) (samples[0][ioffs] * fp + ls[0]*(1-fp)); - if (nch>1) - *outptr++ = (float) (samples[1][ioffs] * fp + ls[1]*(1-fp)); - else - { - *outptr = outptr[-1]; - outptr++; - } - } - else - { - if (nch>1) - { - *outptr++ = (float) (((samples[0][ioffs]+samples[1][ioffs]) * fp + (ls[0]+ls[1])*(1-fp))*0.5); - } - else - *outptr++ = (float) (samples[0][ioffs] * fp + ls[0]*(1-fp)); - - } - - fracpos += rateratio; - } - m_last_samples[0]=samples[0][frames-1]; - m_last_samples[1]=samples[nch-1][frames-1]; - - if (m_samplequeue.Available() < (int)sizeof(float)*m_nch*96000*4 && - m_encoder && m_encoder->outqueue.Available() < 256*1024) - m_samplequeue.Add(m_rsbuf.Get(),outlen*m_nch*sizeof(float)); - - m_rspos=fracpos - floor(fracpos); - } - - m_samplemutex.Leave(); -} - - -static void url_encode(char *in, char *out, int max_out) -{ - while (*in && max_out > 4) - { - if ((*in >= 'A' && *in <= 'Z')|| - (*in >= 'a' && *in <= 'z')|| - (*in >= '0' && *in <= '9')|| *in == '.' || *in == '_' || *in == '-') - { - *out++=*in++; - max_out--; - } - else - { - int i=*in++; - *out++ = '%'; - int b=(i>>4)&15; - if (b < 10) *out++='0'+b; - else *out++='A'+b-10; - b=i&15; - if (b < 10) *out++='0'+b; - else *out++='A'+b-10; - max_out-=3; - } - } - *out=0; -} - -int WDL_ShoutcastSource::RunStuff() -{ - int ret=0; - // run connection - - if (m_sendcon) - { - if (m_encoder && m_encoder_splsin > 48000*60*60*3) // every 3 hours, reinit the mp3 encoder - { - m_encoder_splsin=0; - - WDL_Queue tmp; - if (m_encoder->outqueue.GetSize()) tmp.Add(m_encoder->outqueue.Get(),m_encoder->outqueue.GetSize()); - - delete m_encoder; - - int s=2; - m_encoder=new LameEncoder(m_srate,m_nch,m_br); - if (m_encoder && !(s=m_encoder->Status())) - { - // copy out queue from m_encoder to newnc - if (tmp.GetSize()) m_encoder->outqueue.Add(tmp.Get(),tmp.GetSize()); - } - else - { - if (s == 1) m_state=ERR_NOLAME; - else if (s) m_state=ERR_CREATINGENCODER; - delete m_encoder; - m_encoder=0; - } - - } - - if (m_encoder) - { - // encode data from m_samplequeue - int n=32; - int maxl=1152*2; - m_workbuf.Resize(maxl); - while (n--) - { - m_samplemutex.Enter(); - int d=m_samplequeue.Available()/sizeof(float); - if (d > 0) - { - if (d>maxl) d=maxl; - m_samplequeue.GetToBuf(0,m_workbuf.Get(),d*sizeof(float)); - m_samplequeue.Advance(d*sizeof(float)); - } - m_samplemutex.Leave(); - - if (!d) break; - - m_encoder_splsin+=d/m_nch; - m_encoder->Encode(m_workbuf.Get(),d/m_nch,1); - ret=1; - } - - if (m_encoder->outqueue.Available() > 128*1024) - { - m_encoder->outqueue.Advance(m_encoder->outqueue.Available()-64*1024); - } - - if (m_state==ST_OK) - { - WDL_Queue *srcq = &m_encoder->outqueue; - - if (sendProcessor) - { - sendProcessor(userData,&m_procdata,srcq); - srcq = &m_procdata; - } - - - int mb=srcq->Available(); - int mb2=m_sendcon->send_bytes_available(); - - if (mb>mb2) mb=mb2; - - if (m_is_postmode) - { - if (m_post_bytesleft<=0) PostModeConnect(); - - if (mb>m_post_bytesleft) mb = m_post_bytesleft; - } - - if (mb>0) - { - m_bytesout+=mb; - m_sendcon->send_bytes(srcq->Get(),mb); - if (m_is_postmode) m_post_bytesleft-=mb; - srcq->Advance(mb); - srcq->Compact(); - ret=1; - } - } - } - - m_sendcon->run(); - int s = m_sendcon->get_state(); - - if (m_state == ST_CONNECTING) - { - if (m_is_postmode) - { - m_state=ST_OK; - } - else if (m_sendcon->recv_lines_available()>0) - { - char buf[4096]; - m_sendcon->recv_line(buf, 4095); - if (strcmp(buf, "OK2")) - { - m_state=ERR_AUTH; - delete m_sendcon; - m_sendcon=0; - } - else - { - m_state=ST_OK; - m_sendcon->send_string("icy-name:"); - m_sendcon->send_string(m_name.Get()); - m_sendcon->send_string("\r\n"); - m_sendcon->send_string("icy-genre:"); - m_sendcon->send_string(m_genre.Get()); - m_sendcon->send_string("\r\n"); - m_sendcon->send_string("icy-pub:"); - m_sendcon->send_string(m_pub ? "1":"0"); - m_sendcon->send_string("\r\n"); - m_sendcon->send_string("icy-br:"); - char buf[64]; - snprintf(buf,sizeof(buf),"%d",totalBitrate ? totalBitrate : m_br); - m_sendcon->send_string(buf); - m_sendcon->send_string("\r\n"); - m_sendcon->send_string("icy-url:"); - m_sendcon->send_string(m_url.Get()); - m_sendcon->send_string("\r\n"); - if (m_ircchan.Get()[0]) - { - m_sendcon->send_string("icy-irc:"); - m_sendcon->send_string(m_ircchan.Get()); - m_sendcon->send_string("\r\n"); - } - m_sendcon->send_string("icy-genre:"); - m_sendcon->send_string(m_genre.Get()); - m_sendcon->send_string("\r\n"); - m_sendcon->send_string("icy-reset:1\r\n\r\n"); - } - } - } - if (!m_is_postmode) switch (s) - { - case JNL_Connection::STATE_ERROR: - case JNL_Connection::STATE_CLOSED: - if (m_state==ST_OK) m_state=ERR_DISCONNECTED_AFTER_SUCCESS; - else if (m_state>ST_OK && m_state < ERR_DISCONNECTED_AFTER_SUCCESS) m_state = ERR_CONNECT; - - delete m_sendcon; - m_sendcon=0; - break; - default: - if (m_state > ST_OK && m_state < ERR_DISCONNECTED_AFTER_SUCCESS && time(NULL) > m_sendcon_start+30) - { - m_state=ERR_TIMEOUT; - delete m_sendcon; - m_sendcon=0; - } - - break; - } - } - - if (m_titlecon) - { - if (m_titlecon->run() || time(NULL) > m_titlecon_start+30) - { - delete m_titlecon; - m_titlecon=0; - } - } - - if (m_needtitle && m_state==ST_OK && !m_is_postmode) - { - char title[512]; - m_titlemutex.Enter(); - url_encode(m_title,title,sizeof(title)-1); - m_needtitle=false; - m_titlemutex.Leave(); - - - WDL_String url; - url.Append("http://"); - url.Append(m_host.Get()); - url.Append("/admin.cgi?pass="); - url.Append(m_pass.Get()); - url.Append("&mode=updinfo&song="); - - url.Append(title); - - delete m_titlecon; - m_titlecon=new JNL_HTTPGet; - m_titlecon->addheader("User-Agent:Cockos WDL scsrc (Mozilla)"); - m_titlecon->addheader("Accept:*/*"); - m_titlecon->connect(url.Get()); - m_titlecon_start=time(NULL); - } - - return ret; -} - -static void AddTextField(WDL_String *s, const char *name, const char *value) -{ - s->AppendFormatted(4096,"--" POST_DIV_STRING "\r\n" - "Content-Disposition: form-data; name=\"%s\"\r\n" - "\r\n" - "%s\r\n", - name, - value); -} - -void WDL_ShoutcastSource::PostModeConnect() -{ - const char *hsrc = m_host.Get(); - if (!strnicmp(hsrc,"http://",7)) hsrc+=7; - WDL_String hb(hsrc); - int port=80; - char zb[32]={0,}; - char *req = zb, *parms=zb; - char *p=hb.Get(); - while (*p && *p != ':' && *p != '/' && *p != '?') p++; - if (*p == ':') - { - *p++=0; - port = atoi(p); - if (!port) port=80; - } - while (*p && *p != '/' && *p != '?') p++; - if (*p == '/') - { - *p++=0; - req = p; - } - while (*p && *p != '?') p++; - if (*p == '?') - { - *p++=0; - parms = p; - } - - bool allowReuse=false; - - if (m_sendcon) - { - m_sendcon->send_string(END_POST_BYTES); - m_sendcon->run(); - DWORD start=GetTickCount(); - bool done=false,hadResp=false; - while (GetTickCount() < start+1000 && !done) - { - Sleep(50); - m_sendcon->run(); - if (m_sendcon->get_state() == JNL_Connection::STATE_ERROR || - m_sendcon->get_state() > JNL_Connection::STATE_CONNECTED) break; - - while (m_sendcon->recv_lines_available()>0) - { - char buf[4096]; - m_sendcon->recv_line(buf, 4095); -// OutputDebugString(buf); - - if (!strnicmp(buf,"HTTP/",5)) hadResp=true; - if (!strnicmp(buf,"HTTP/1.1",8)) allowReuse=true; - - const char *con="Connection:"; - if (!strnicmp(buf,con,strlen(con))) - { - char *p=buf+strlen(con); - while (*p == ' ') p++; - if (!strnicmp(p,"close",5)) allowReuse=false; - else if (!strnicmp(p,"keep-alive",10)) allowReuse=true; - - done=true; - } - if (hadResp && (!buf[0] || buf[0] == '\r' || buf[0] == '\n')) - done=true; - - } - } - } - - if (m_sendcon) m_sendcon->run(); - - if (m_sendcon && - (!allowReuse || m_post_postsleft<=0 || - m_sendcon->get_state() == JNL_Connection::STATE_ERROR || - m_sendcon->get_state() > JNL_Connection::STATE_CONNECTED)) - - { - delete m_sendcon; - m_sendcon=0; - } - - if (!m_sendcon) - { -// OutputDebugString("new connection\n"); - m_sendcon = new JNL_Connection(JNL_CONNECTION_AUTODNS,65536,65536); - m_sendcon->connect(hb.Get(),port); - m_post_postsleft=16; // todo: some configurable amt? - } - - int csize = (totalBitrate ? totalBitrate*2 : m_br) * 2000 / 8 + 512; // 2s of audio plus pad - if (csize<16384) csize=16384; - - - WDL_String tmp; - tmp.SetFormatted(4096,"POST /%s HTTP/1.1\r\n" - "Connection: %s\r\n" - "Host: %s\r\n" - "User-Agent: WDLScSrc(Mozilla)\r\n" - "MIME-Version: 1.0\r\n" - "Content-type: multipart/form-data; boundary=" POST_DIV_STRING "\r\n" - "Content-length: %d\r\n" - "\r\n", - req, - --m_post_postsleft > 0 ? "Keep-Alive" : "close", - hb.Get(), - csize); - m_sendcon->send_string(tmp.Get()); - - m_post_bytesleft = csize - strlen(END_POST_BYTES); - - tmp.Set(""); - - p = parms; - while (*p) - { - char *eq = p; - while (*eq && *eq != '=') eq++; - if (!*eq) break; - *eq++=0; - char *np = eq; - while (*np && *np != '&') np++; - - AddTextField(&tmp,p,eq); - - - if (!*np) break; - p=np+1; - } - - AddTextField(&tmp,"broadcast",m_pass.Get()); - - if (m_title[0]) - { - m_titlemutex.Enter(); - if (m_title[0]) AddTextField(&tmp,"title",m_title); - m_titlemutex.Leave(); - } - - AddTextField(&tmp,"name",m_name.Get()); - - - { - char buf[512]; - sprintf(buf,"%u",m_postmode_session); - AddTextField(&tmp,"session",buf); - } - - tmp.AppendFormatted(4096,"--" POST_DIV_STRING "\r\n" - "Content-Disposition: form-data; name=\"file\"; filename=\"bla.dat\"\r\n" - "Content-Type: application/octet-stream\r\n" - "Content-transfer-encoding: binary\r\n" - ); - - - tmp.Append("\r\n"); - - m_sendcon->send_string(tmp.Get()); - m_post_bytesleft -= strlen(tmp.Get()); - -} \ No newline at end of file diff --git a/WDL/scsrc.h b/WDL/scsrc.h deleted file mode 100644 index 289fb9c4..00000000 --- a/WDL/scsrc.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - WDL - scsrc.h - Copyright (C) 2007, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides for an object to source a SHOUTcast (www.shoutcast.com) stream. - It uses the lameencdec.h interface (and lame_enc.dll) to encode, and JNetLib to send the data. - - - This object will not auto-reconnect on disconnect. If GetStatus() returns error, the callee needs to - delete the object and create a new one. - - -*/ - - -#ifndef _WDL_SCSRC_H_ -#define _WDL_SCSRC_H_ - -#include -#include "jnetlib/connection.h" -#include "jnetlib/httpget.h" -#include "lameencdec.h" -#include "wdlstring.h" -#include "fastqueue.h" -#include "queue.h" -#include "mutex.h" - -class WDL_ShoutcastSource -{ -public: - WDL_ShoutcastSource(const char *host, const char *pass, const char *name, bool pub=false, - const char *genre=NULL, const char *url=NULL, - - int nch=2, int srate=44100, int kbps=128, - const char *ircchan=NULL - ); - ~WDL_ShoutcastSource(); - - int GetStatus(); // returns 0 if connected/connecting, >0 if disconnected, -1 if failed connect (or other error) from the start - void GetStatusText(char *buf, int bufsz); // gets status text - - void SetCurTitle(const char *title); - - int GetSampleRate() { return m_srate; } - void OnSamples(float **samples, int nch, int chspread, int frames, double srate); - int RunStuff(); // returns nonzero if work done - - - void *userData; - int totalBitrate; // 0 for normal, otherwise if using NSV (below) set to kbps of total stream - // allows hooking to say, I dunno, package in some other format such as NSV? - void (*sendProcessor)(void *userData, WDL_Queue *dataout, WDL_Queue *data); - - int GetAudioBitrate() { return m_br*1000; } - -private: - - WDL_Queue m_procdata; - - LameEncoder *m_encoder; - int m_encoder_splsin; - - WDL_String m_host,m_pass,m_url,m_genre,m_name,m_ircchan; - int m_br; - bool m_pub; - - time_t m_titlecon_start,m_sendcon_start; - - unsigned int m_bytesout; - int m_state; - int m_nch,m_srate; - - double m_last_samples[2] WDL_FIXALIGN; - double m_rspos; // last resample fractional position - - WDL_FastQueue m_samplequeue; // interleaved samples (float) - - JNL_HTTPGet *m_titlecon; - JNL_Connection *m_sendcon; - - WDL_TypedBuf m_workbuf,m_rsbuf; - WDL_Mutex m_samplemutex; - WDL_Mutex m_titlemutex; - char m_title[512]; - bool m_needtitle; - - - bool m_is_postmode; - unsigned int m_postmode_session; - int m_post_bytesleft; - int m_post_postsleft; - - void PostModeConnect(); - -}; - -#endif // _WDL_SCSRC_H_ \ No newline at end of file diff --git a/WDL/sha.cpp b/WDL/sha.cpp deleted file mode 100644 index 07bfecaf..00000000 --- a/WDL/sha.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - WDL - sha.cpp - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides the implementation to the WDL_SHA1 object, which performs SHA-1 hashes - on data. - -*/ - -#include "sha.h" - -/// sha - -WDL_SHA1::WDL_SHA1() -{ - reset(); -} - -void WDL_SHA1::reset() -{ - lenW = 0; - size[0] = size[1] = 0; - H[0] = 0x67452301; - H[1] = 0xefcdab89; - H[2] = 0x98badcfe; - H[3] = 0x10325476; - H[4] = 0xc3d2e1f0; - int x; - for (x = 0; x < (int)(sizeof(W)/sizeof(W[0])); x ++) W[x]=0; -} - - -#define SHA_ROTL(X,n) ((((X)&0xffffffff) << (n)) | (((X)&0xffffffff) >> (32-(n)))) -#define SHUFFLE() E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP - -void WDL_SHA1::add(const void *data, int datalen) -{ - int i; - for (i = 0; i < datalen; i++) - { - W[lenW / 4] <<= 8; - W[lenW / 4] |= (unsigned int)((const unsigned char *)data)[i]; - if (!(++lenW & 63)) - { - int t; - - unsigned int A = H[0]; - unsigned int B = H[1]; - unsigned int C = H[2]; - unsigned int D = H[3]; - unsigned int E = H[4]; - - - for (t = 16; t < 80; t++) W[t] = SHA_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); - - for (t = 0; t < 20; t++) - { - unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x5a827999 + (((C^D)&B)^D); - SHUFFLE(); - } - for (; t < 40; t++) - { - unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x6ed9eba1 + (B^C^D); - SHUFFLE(); - } - for (; t < 60; t++) - { - unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x8f1bbcdc + ((B&C)|(D&(B|C))); - SHUFFLE(); - } - for (; t < 80; t++) - { - unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0xca62c1d6 + (B^C^D); - SHUFFLE(); - } - - H[0] += A; - H[1] += B; - H[2] += C; - H[3] += D; - H[4] += E; - - lenW = 0; - } - size[0] += 8; - if (size[0] < 8) size[1]++; - } -} - -void WDL_SHA1::result(void *out) -{ - unsigned char pad0x80 = 0x80; - unsigned char pad0x00 = 0x00; - unsigned char padlen[8]; - int i; - padlen[0] = (unsigned char)((size[1] >> 24) & 0xff); - padlen[1] = (unsigned char)((size[1] >> 16) & 0xff); - padlen[2] = (unsigned char)((size[1] >> 8) & 0xff); - padlen[3] = (unsigned char)((size[1]) & 0xff); - padlen[4] = (unsigned char)((size[0] >> 24) & 0xff); - padlen[5] = (unsigned char)((size[0] >> 16) & 0xff); - padlen[6] = (unsigned char)((size[0] >> 8) & 0xff); - padlen[7] = (unsigned char)((size[0]) & 0xff); - add(&pad0x80, 1); - while (lenW != 56) add(&pad0x00, 1); - add(padlen, 8); - for (i = 0; i < 20; i++) - { - ((unsigned char *)out)[i] = (unsigned char)(H[i / 4] >> 24); - H[i / 4] <<= 8; - } - reset(); -} diff --git a/WDL/sha.h b/WDL/sha.h deleted file mode 100644 index 581403bb..00000000 --- a/WDL/sha.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - WDL - sha.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This header provides an interface to the WDL_SHA1 object, which performs SHA-1 hashes - on data. -*/ - -#ifndef _WDL_SHA_H_ -#define _WDL_SHA_H_ - - -#define WDL_SHA1SIZE 20 - -// sha - -class WDL_SHA1 { - -public: - WDL_SHA1(); - void add(const void *data, int datalen); - void result(void *out); - void reset(); - -private: - - unsigned int H[5]; - unsigned int W[80]; - int lenW; - unsigned int size[2]; -}; - -#endif - diff --git a/WDL/sharedpool.h b/WDL/sharedpool.h deleted file mode 100644 index 60b208d5..00000000 --- a/WDL/sharedpool.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - WDL - sharedpool.h - Copyright (C) 2006 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - - This file defines a template for a simple object pool. - - Objects are keyed by string (filename, or otherwise). The caller can add or get an object, - increase or decrease its reference count (if it reaches zero the object is deleted). - - - If you delete the pool itself, all objects are deleted, regardless of their reference count. - -*/ - - -#ifndef _WDL_SHAREDPOOL_H_ -#define _WDL_SHAREDPOOL_H_ - -#include "ptrlist.h" - -template class WDL_SharedPool -{ - public: - WDL_SharedPool() { } - ~WDL_SharedPool() { m_listobjk.Empty(true); /* do not release m_list since it's redundant */ } - - void Add(OBJ *obj, const char *n) // no need to AddRef() after add, it defaults to a reference count of 1. - { - if (obj && n) - { - Ent *p = new Ent(obj,n); - m_list.InsertSorted(p,_sortfunc_name); - m_listobjk.InsertSorted(p,_sortfunc_obj); - } - } - - OBJ *Get(const char *s) - { - struct { void *obj; const char *name; } tmp = { NULL, s }; - Ent *t = m_list.Get(m_list.FindSorted((Ent *)&tmp,_sortfunc_name)); - - if (t && t->obj) - { - t->refcnt++; - return t->obj; - } - - return 0; - - } - - void AddRef(OBJ *obj) - { - Ent *ent = m_listobjk.Get(m_listobjk.FindSorted((Ent *)&obj,_sortfunc_obj)); - if (ent) ent->refcnt++; - } - - void Release(OBJ *obj) - { - int x = m_listobjk.FindSorted((Ent *)&obj,_sortfunc_obj); - Ent *ent = m_listobjk.Get(x); - if (ent && !--ent->refcnt) - { - m_list.Delete(m_list.FindSorted(ent,_sortfunc_name)); - m_listobjk.Delete(x,true); - } - } - - OBJ *EnumItems(int x) - { - Ent *e=m_list.Get(x); - return e?e->obj:NULL; - } - - private: - - class Ent - { - public: - OBJ *obj; // this order is used elsewhere for its own advantage - char *name; - - int refcnt; - - Ent(OBJ *o, const char *n) { obj=o; name=strdup(n); refcnt=1; } - ~Ent() { delete obj; free(name); } - - }; - - - - static int _sortfunc_name(const Ent **a, const Ent **b) - { - return stricmp((*a)->name,(*b)->name); - } - static int _sortfunc_obj(const Ent **a, const Ent **b) - { - if ((INT_PTR)(*a)->obj < (INT_PTR)(*b)->obj) return -1; - if ((INT_PTR)(*a)->obj > (INT_PTR)(*b)->obj) return 1; - return 0; - } - - WDL_PtrList m_list, // keyed by name - m_listobjk; // keyed by OBJ - - -}; - - -#endif//_WDL_SHAREDPOOL_H_ diff --git a/WDL/shm_connection.cpp b/WDL/shm_connection.cpp deleted file mode 100644 index ed76e243..00000000 --- a/WDL/shm_connection.cpp +++ /dev/null @@ -1,521 +0,0 @@ -#include "shm_connection.h" - -#ifdef _WIN32 -#define SHM_MINSIZE 64 -#define SHM_HDRSIZE (4+4*4+2) - // 4 bytes: buffer size (each channel) - // 4 bytes: read pointer chan 0 - // 4 bytes: write pointer chan 0 - // 4 bytes: read pointer chan 1 - // 4 bytes: write pointer chan 1 - // 2 bytes: chan 0 refresh, chan 1 refresh - // data follows (2x buffer size) - - -WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, - const char *uniquestring, // identify - int shmsize, // bytes, whoever opens first decides - int timeout_sec, - int extra_flags // unused on win32 - - ) -{ - m_timeout_cnt=0; - m_timeout_sec=timeout_sec; - m_last_recvt=time(NULL)+2; // grace period - { // make shmsize the next power of two - int a = shmsize; - shmsize=2; - while (shmsize < SHM_MINSIZE || shmsize0) - { - DWORD d; - int a = sz; - if (a>sizeof(buf))a=sizeof(buf); - WriteFile(m_file,buf,a,&d,NULL); - sz-=a; - *(int *)buf = 0; - } - } - - if (m_file!=INVALID_HANDLE_VALUE) - m_filemap=CreateFileMapping(m_file,NULL,PAGE_READWRITE,0,0,NULL); - - if (m_filemap) - { - m_mem=(unsigned char *)MapViewOfFile(m_filemap,FILE_MAP_WRITE,0,0,0); - - tmp.Get()[tmp_l]=0; - tmp.Append(".1"); - m_events[0]=CreateEvent(NULL,false,false,tmp.Get()); - tmp.Get()[strlen(tmp.Get())-1]++; - m_events[1]=CreateEvent(NULL,false,false,tmp.Get()); - } - - if (mutex) - { - ReleaseMutex(mutex); - CloseHandle(mutex); - } - -} - - -WDL_SHM_Connection::~WDL_SHM_Connection() -{ - if (m_mem) UnmapViewOfFile(m_mem); - if (m_filemap) CloseHandle(m_filemap); - if (m_file != INVALID_HANDLE_VALUE) CloseHandle(m_file); - DeleteFile(m_tempfn.Get()); - - if (m_events[0]) CloseHandle(m_events[0]); - if (m_events[1]) CloseHandle(m_events[1]); - if (m_lockmutex) - { - ReleaseMutex(m_lockmutex); - CloseHandle(m_lockmutex); - } -} - -bool WDL_SHM_Connection::WantSendKeepAlive() { return false; } - -int WDL_SHM_Connection::Run() -{ - if (!m_mem) return -1; - - int *hdr = (int *)m_mem; - - int shm_size = hdr[0]; - - // todo: check to see if we just opened, if so, have a grace period - if (shm_size < SHM_MINSIZE) return -1; - - m_mem[4*5 + !!m_whichChan] = 1; - if (m_timeout_sec > 0) - { - if (m_mem[4*5 + !m_whichChan]) - { - m_timeout_cnt=0; - m_last_recvt=time(NULL); - m_mem[4*5 + !m_whichChan]=0; - } - else - { - if (time(NULL) > m_timeout_sec+m_last_recvt) - { - if (m_timeout_cnt >= 4) return -1; - - m_timeout_cnt++; - m_last_recvt=time(NULL); - } - } - } - - int didStuff=0; - - // process writes - int send_avail=send_queue.Available(); - if (send_avail>0) - { - int wc = !m_whichChan; - unsigned char *data=m_mem+SHM_HDRSIZE+shm_size*wc; - int rdptr = hdr[1 + wc*2]; // hopefully atomic - int wrptr = hdr[1 + wc*2+1]; - int wrlen = shm_size - (wrptr-rdptr); - if (wrlen > 0) - { - if (wrlen > send_avail) wrlen=send_avail; - if (wrlen > shm_size) wrlen=shm_size; // should never happen ! - - int idx = wrptr & (shm_size-1); - int l = shm_size - idx; - if (l > wrlen) l = wrlen; - memcpy(data+idx,send_queue.Get(),l); - if (l < wrlen) memcpy(data,(char*)send_queue.Get() + l,wrlen-l); - - hdr[1 + wc*2+1] = wrptr + wrlen; // advance write pointer, hopefluly atomic - - didStuff|=1; - - send_queue.Advance(wrlen); - send_queue.Compact(); - - } - } - - // process reads - { - int wc = m_whichChan; - unsigned char *data=m_mem+SHM_HDRSIZE+shm_size*wc; - int rdptr = hdr[1 + wc*2]; - int wrptr = hdr[1 + wc*2+1]; // hopefully atomic - int rdlen = wrptr-rdptr; - if (rdlen > 0) - { - if (rdlen > shm_size) rdlen=shm_size; // should never happen ! - - int idx = rdptr & (shm_size-1); - int l = shm_size - idx; - if (l > rdlen) l = rdlen; - recv_queue.Add(data+idx,l); - if (l < rdlen) recv_queue.Add(data,rdlen-l); - - hdr[1 + wc*2] = wrptr; // hopefully atomic, bring read pointer up to write pointer - didStuff|=2; - } - } - - if (didStuff) - { - if (m_events[!m_whichChan]) SetEvent(m_events[!m_whichChan]); - return 1; - } - - - return 0; -} - - -#else - -#include -#include -#include -#include -#include -#include -#include -#ifndef __APPLE__ -#include -#endif -#include "swell/swell-internal.h" - -static void sigpipehandler(int sig) { } - -// socket version -WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, // first created must be whichChan=0 - const char *uniquestring, // identify - int shmsize, - int timeout_sec, - int extra_flags // set 1 for lockfile use on master - ) -{ - m_sockbufsize = shmsize; - if (m_sockbufsize<16384) m_sockbufsize=16384; - else if (m_sockbufsize>1024*1024) m_sockbufsize=1024*1024; - - m_rdbufsize = min(m_sockbufsize,65536); - m_rdbuf = (char *)malloc(m_rdbufsize); - - static bool hasSigHandler; - if (!hasSigHandler) - { - signal(SIGPIPE,sigpipehandler); - hasSigHandler=true; - } - m_timeout_cnt=0; - m_timeout_sec=timeout_sec; - m_last_recvt=time(NULL)+3; // grace period - m_next_keepalive = time(NULL)+1; - - m_tempfn.Set("/tmp/WDL_SHM."); - m_tempfn.Append(uniquestring); - m_tempfn.Append(".tmp"); - - - m_sockaddr=malloc(sizeof(struct sockaddr_un) + strlen(m_tempfn.Get())); - m_lockhandle=-1; - m_listen_socket=-1; - m_socket=-1; - m_waitevt=0; - m_whichChan = whichChan; - - struct sockaddr_un *addr = (struct sockaddr_un *)m_sockaddr; - addr->sun_family = AF_UNIX; - strcpy(addr->sun_path,m_tempfn.Get()); - #ifdef __APPLE__ - int l = SUN_LEN(addr)+1; - if (l>255)l=255; - addr->sun_len=l; - #endif - - if (!whichChan) - { - if (extra_flags & 1) - { - m_lockfn.Set(m_tempfn.Get()); - m_lockfn.Append(".lock"); - m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT,0666); - if (m_lockhandle < 0) return; // error getting lockfile, fail - if (flock(m_lockhandle,LOCK_NB|LOCK_EX) < 0) - { - close(m_lockhandle); - m_lockhandle=-1; - return; // could not lock - } - } - acquireListener(); - if (m_listen_socket<0) return; - } - else - { - struct stat sbuf; - if (stat(addr->sun_path,&sbuf)) - { - return; // fail - } - - int s = socket(AF_UNIX,SOCK_STREAM,0); - if (s<0) return; - - int bsz=m_sockbufsize; - setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&bsz,sizeof(bsz)); - bsz=m_sockbufsize; - setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&bsz,sizeof(bsz)); - - if (connect(s,(struct sockaddr*)addr,SUN_LEN(addr))) - { - close(s); - } - else - { - fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); - m_socket=s; - - // clean up the filesystem, our connection has been made - unlink(m_tempfn.Get()); - } - } - - if (m_socket>=0 || m_listen_socket>=0) - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)malloc(sizeof(SWELL_InternalObjectHeader_SocketEvent)); - memset(se,0,sizeof(SWELL_InternalObjectHeader_SocketEvent)); - se->hdr.type = INTERNAL_OBJECT_EXTERNALSOCKET; - se->hdr.count = 1; - se->socket[0]=m_socket>=0? m_socket : m_listen_socket; - m_waitevt = (HANDLE)se; - } -} - -WDL_SHM_Connection::~WDL_SHM_Connection() -{ - if (m_listen_socket>=0 || m_socket>=0) - { - if (m_socket>=0) close(m_socket); - if (m_listen_socket>=0) close(m_listen_socket); - - // only delete temp socket file if the master and successfully had something open - if (!m_whichChan && m_tempfn.Get()[0]) unlink(m_tempfn.Get()); - } - - free(m_waitevt); // don't CloseHandle(), since it's just referencing our socket - free(m_sockaddr); - free(m_rdbuf); - - if (m_lockhandle>=0) - { - flock(m_lockhandle,LOCK_UN); - close(m_lockhandle); - unlink(m_lockfn.Get()); - } -} - -bool WDL_SHM_Connection::WantSendKeepAlive() -{ - return !send_queue.GetSize() && time(NULL) >= m_next_keepalive; -} - - -int WDL_SHM_Connection::Run() -{ - if (m_socket < 0) - { - if (m_listen_socket < 0) return -1; - - struct sockaddr_un remote={0,}; - socklen_t t = sizeof(struct sockaddr_un); - int s = accept(m_listen_socket,(struct sockaddr *)&remote,&t); - if (s>=0) - { - close(m_listen_socket); - m_listen_socket=-1; - - fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); // nonblocking - - int bsz=m_sockbufsize; - setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&bsz,sizeof(bsz)); - bsz=m_sockbufsize; - setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&bsz,sizeof(bsz)); - - if (m_waitevt) - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)m_waitevt; - se->socket[0]=s; - } - m_socket=s; - } - else - { - if (m_timeout_sec>0 && time(NULL) > m_timeout_sec+m_last_recvt) - { - if (m_timeout_cnt >= 2) return -1; - m_timeout_cnt++; - m_last_recvt=time(NULL); - } - return 0; - } - } - - bool sendcnt=false; - bool recvcnt=false; - for (;;) - { - bool hadAct=false; - while (recv_queue.Available()<128*1024*1024) - { - int n=read(m_socket,m_rdbuf,m_rdbufsize); - if (n>0) - { - recv_queue.Add(m_rdbuf,n); - hadAct=true; - recvcnt=true; - } - else if (n<0&&errno!=EAGAIN) goto abortClose; - else break; - } - while (send_queue.Available()>0) - { - int n = send_queue.Available(); - if (n > m_rdbufsize) n=m_rdbufsize; - n = write(m_socket,send_queue.Get(),n); - if (n > 0) - { - hadAct=true; - sendcnt=true; - send_queue.Advance(n); - } - else if (n<0&&errno!=EAGAIN) goto abortClose; - else break; - } - if (!hadAct) break; - } - if (sendcnt) send_queue.Compact(); - - if (m_timeout_sec>0) - { - time_t now = time(NULL); - if (recvcnt) - { - m_last_recvt=now; - m_timeout_cnt=0; - } - else if (now > m_timeout_sec+m_last_recvt) - { - if (m_timeout_cnt >= 3) return -1; - m_timeout_cnt++; - m_last_recvt=now; - } - - if (sendcnt||send_queue.GetSize()) m_next_keepalive = now + (m_timeout_sec+1)/2; - } - - return sendcnt||recvcnt; - -abortClose: - if (m_whichChan) return -1; - - acquireListener(); - recv_queue.Clear(); - send_queue.Clear(); - if (m_waitevt) - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)m_waitevt; - se->socket[0]=m_listen_socket; - } - close(m_socket); - m_socket=-1; - - return m_listen_socket >= 0 ? 0 : -1; -} - -void WDL_SHM_Connection::acquireListener() -{ - // only ever called from whichChan==0 - if (m_listen_socket>=0) return; // no need to re-open - - unlink(m_tempfn.Get()); - - int s = socket(AF_UNIX,SOCK_STREAM,0); - if (s<0) return; - struct sockaddr_un *addr = (struct sockaddr_un *)m_sockaddr; - if (bind(s,(struct sockaddr*)addr,SUN_LEN(addr)) < 0 || listen(s,1) < 0) - { - close(s); - } - else - { - fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); - m_listen_socket = s; - } -} -#endif diff --git a/WDL/shm_connection.h b/WDL/shm_connection.h deleted file mode 100644 index ca012713..00000000 --- a/WDL/shm_connection.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _WDL_SHM_CONNECTION_H_ -#define _WDL_SHM_CONNECTION_H_ - -#ifdef _WIN32 -#include -#else -#include "swell/swell.h" -#include "swell/swell-internal.h" -#endif - -#include - -#include "wdlstring.h" -#include "wdltypes.h" -#include "queue.h" - -class WDL_SHM_Connection -{ -public: - WDL_SHM_Connection(bool whichChan, // a true con connects to a false con -- note on SHM false should be created FIRST. - const char *uniquestring, // identify - int shmsize=262144, // bytes, whoever opens first decides - int timeout_sec=0, - int extra_flags=0 // on posix, set 1 for the master to create a .lock file as well - ); - - ~WDL_SHM_Connection(); - - int Run(); // call as often as possible, returns <0 error, >0 if did something - - bool WantSendKeepAlive(); // called when it needs a keepalive to be sent (may be never, or whatever interval it decides) - - // wait for this if you want to see when data comes in - HANDLE GetWaitEvent() - { - #ifdef _WIN32 - return m_events[m_whichChan]; - #else - return m_waitevt; - #endif - } - - // receiving and sending data - WDL_Queue recv_queue; - WDL_Queue send_queue; - - -private: - - - int m_timeout_sec; - time_t m_last_recvt; - int m_timeout_cnt; - - WDL_String m_tempfn; - - int m_whichChan; // which channel we read from - -#ifdef _WIN32 - - HANDLE m_file, m_filemap; - HANDLE m_events[2]; // [m_whichChan] set when the other side did something useful - HANDLE m_lockmutex; - - unsigned char *m_mem; -#else - time_t m_next_keepalive; - - int m_sockbufsize; - - int m_rdbufsize; - char *m_rdbuf; // m_rdbufsize - - int m_listen_socket; - int m_socket; - - HANDLE m_waitevt; - void *m_sockaddr; - - void acquireListener(); - WDL_String m_lockfn; - int m_lockhandle; -#endif - -}; - -#endif diff --git a/WDL/shm_msgreply.cpp b/WDL/shm_msgreply.cpp deleted file mode 100644 index a99f1507..00000000 --- a/WDL/shm_msgreply.cpp +++ /dev/null @@ -1,346 +0,0 @@ -#include "shm_msgreply.h" -#include "wdlcstring.h" - -//#define VERIFY_MESSAGES // this is not endian-aware (so it'll fail if enabled and doing ppc<->x86 etc) -#ifdef VERIFY_MESSAGES -#define WDL_SHA1 WDL_SHA1_msgreplydef -#include "sha.cpp" -#endif - -SHM_MsgReplyConnection::SHM_MsgReplyConnection(int bufsize, int maxqueuesize, bool dir, const char *uniquestr, int timeout_sec, int extra_flags) -{ - m_maxqueuesize=maxqueuesize; - m_has_had_error=false; - userData=0; - OnRecv=0; - IdleProc=0; - m_lastmsgid=1; - m_shm = 0; - m_spares=0; - m_waiting_replies=0; - - if (uniquestr) lstrcpyn_safe(m_uniq,uniquestr,sizeof(m_uniq)); - else - { -#ifdef _WIN32 - WDL_INT64 pid = (WDL_INT64) GetCurrentProcessId(); -#else - WDL_INT64 pid = (WDL_INT64) getpid(); -#endif - WDL_INT64 thisptr = (WDL_INT64) (INT_PTR) this; - static int cnt=0xdeadf00d; - sprintf(m_uniq,"%08x%08x%08x%08x", - (int)(pid&0xffffffff), - (int)(pid>>32), - (int)(thisptr&0xffffffff) ^ GetTickCount(), - (int)(thisptr>>32)^(cnt++)); - } - - m_shm = new WDL_SHM_Connection(dir,m_uniq,bufsize,timeout_sec,extra_flags); - -} - -SHM_MsgReplyConnection::~SHM_MsgReplyConnection() -{ - delete m_shm; - WaitingMessage *tmp=m_waiting_replies; - while (tmp) - { - WaitingMessage *p=tmp; - tmp=tmp->_next; - delete p; - } - tmp=m_spares; - while (tmp) - { - WaitingMessage *p=tmp; - tmp=tmp->_next; - delete p; - } -} - -void SHM_MsgReplyConnection::Reply(int msgID, const void *msg, int msglen) -{ - if (msgID) Send(0,msg,msglen,NULL,0,&msgID); -} - - -int SHM_MsgReplyConnection::Send(int type, const void *msg, int msglen, - void *replybuf, int maxretbuflen, const int *forceMsgID, - const void *secondchunk, int secondchunklen, - WDL_HeapBuf *hbreplyout) -{ - if (!m_shm||m_has_had_error) return -1; - - if (secondchunk && secondchunklen>0) msglen+=secondchunklen; - else secondchunklen=0; - - int msgid; - { - WDL_MutexLock lock(&m_shmmutex); - m_shm->send_queue.AddDataToLE(&type,4,4); - - if (forceMsgID) msgid = *forceMsgID; - else - { - if (!replybuf&&!hbreplyout) msgid=0; - else if (!(msgid = ++m_lastmsgid)) msgid = ++m_lastmsgid; - } - - m_shm->send_queue.AddDataToLE(&msgid,4,4); - m_shm->send_queue.AddDataToLE(&msglen,4,4); - if (msglen>secondchunklen) m_shm->send_queue.Add(msg,msglen-secondchunklen); - if (secondchunklen>0) m_shm->send_queue.Add(secondchunk,secondchunklen); - -#ifdef VERIFY_MESSAGES - WDL_SHA1 t; - t.add(&type,4); - t.add(&msgid,4); - t.add(&msglen,4); - if (msglen>secondchunklen) t.add(msg,msglen-secondchunklen); - if (secondchunklen>0) t.add(secondchunk,secondchunklen); - - char tb[WDL_SHA1SIZE]; - t.result(tb); - m_shm->send_queue.Add(tb,sizeof(tb)); -#endif - - - if ((!replybuf && !hbreplyout) || !msgid) m_shm->Run(); // get this reply out ASAP - } - - if ((hbreplyout||replybuf) && msgid) - { - int wait_cnt=30; // dont run idleproc for first Xms or so - - while (!m_has_had_error) - { - if (wait_cnt<=0 && IdleProc && IdleProc(this)) - { - m_has_had_error=true; - break; - } - - WaitingMessage *msg=NULL; - bool r = RunInternal(msgid,&msg); - - if (msg) - { - int rv = msg->m_msgdata.GetSize(); - - if (hbreplyout) - { - memcpy(hbreplyout->Resize(rv,false),msg->m_msgdata.Get(),rv); - } - - if (replybuf) - { - if (rv > maxretbuflen) rv=maxretbuflen; - if (rv>0) memcpy(replybuf,msg->m_msgdata.Get(),rv); - } - - m_shmmutex.Enter(); - msg->_next = m_spares; - m_spares=msg; - m_shmmutex.Leave(); - return rv; - } - else if (r) break; - - - if (wait_cnt>0) wait_cnt--; - - HANDLE evt=m_shm->GetWaitEvent(); - if (evt) WaitForSingleObject(evt,1); - else Sleep(1); - - } - } - - if (hbreplyout) hbreplyout->Resize(0,false); - - return -1; -} - -void SHM_MsgReplyConnection::Wait(HANDLE extraEvt) -{ - HANDLE evt=m_shm ? m_shm->GetWaitEvent() : extraEvt; - if (evt && extraEvt && evt != extraEvt) - { - HANDLE hds[2] = {evt,extraEvt}; -#ifdef _WIN32 - WaitForMultipleObjects(2,hds,FALSE,1); -#else - WaitForAnySocketObject(2,hds,1); -#endif - } - else if (evt) WaitForSingleObject(evt,1); - else Sleep(1); -} - -void SHM_MsgReplyConnection::ReturnSpares(WaitingMessage *msglist) -{ - if (msglist) - { - WaitingMessage *msgtail = msglist; - while (msgtail && msgtail->_next) msgtail=msgtail->_next; - - m_shmmutex.Enter(); - msgtail->_next = m_spares; - m_spares=msglist; - m_shmmutex.Leave(); - } -} - -bool SHM_MsgReplyConnection::Run(bool runFull) -{ - if (m_has_had_error) return true; - - if (runFull) return RunInternal(); - - m_shmmutex.Enter(); - int s=m_shm->Run(); - if (m_shm->send_queue.Available() > m_maxqueuesize) s=-1; - m_shmmutex.Leave(); - - if (s<0) m_has_had_error=true; - else if (m_shm && m_shm->WantSendKeepAlive()) - { - int zer=0; - Send(0,NULL,0,NULL,0,&zer); - } - - return s<0; -} - -bool SHM_MsgReplyConnection::RunInternal(int checkForReplyID, WaitingMessage **replyPtr) -{ - if (!m_shm||m_has_had_error) return true; - - if (replyPtr) *replyPtr=0; - - int s=0; - - do - { - m_shmmutex.Enter(); - - // autocompact on first time through - if (!s) m_shm->recv_queue.Compact(); - - s = m_shm->Run(); - if (m_shm->send_queue.Available() > m_maxqueuesize) s=-1; - - while (m_shm->recv_queue.GetSize()>=12) - { - int datasz = *(int *)((char *)m_shm->recv_queue.Get()+8); - WDL_Queue::WDL_Queue__bswap_buffer(&datasz,4); // convert to LE if needed - - if (m_shm->recv_queue.GetSize() < 12 + datasz) break; - -#ifdef VERIFY_MESSAGES - if (m_shm->recv_queue.GetSize() < 12 + datasz + WDL_SHA1SIZE) break; -#endif - - int type = *(int *)((char *)m_shm->recv_queue.Get()); - WDL_Queue::WDL_Queue__bswap_buffer(&type,4); // convert to LE if needed - - WaitingMessage *msg = m_spares; - if (msg) m_spares = m_spares->_next; - else msg = new WaitingMessage; - - msg->m_msgid = *(int *)((char *)m_shm->recv_queue.Get() + 4); - WDL_Queue::WDL_Queue__bswap_buffer(&msg->m_msgid,4); // convert to LE if needed - - msg->m_msgtype = type; - memcpy(msg->m_msgdata.Resize(datasz,false),(char *)m_shm->recv_queue.Get()+12, datasz); - - m_shm->recv_queue.Advance(12+datasz); - -#ifdef VERIFY_MESSAGES - WDL_SHA1 t; - t.add(&type,4); - t.add(&msg->m_msgid,4); - t.add(&datasz,4); - t.add(msg->m_msgdata.Get(),msg->m_msgdata.GetSize()); - char tb[WDL_SHA1SIZE]; - t.result(tb); - if (memcmp(m_shm->recv_queue.Get(),tb,WDL_SHA1SIZE)) - MessageBox(NULL,"FAIL","A",0); - m_shm->recv_queue.Advance(WDL_SHA1SIZE); -#endif - - - if (type==0) - { - if (checkForReplyID && replyPtr && !*replyPtr && - checkForReplyID == msg->m_msgid) - { - *replyPtr = msg; - s=0; - break; // we're done! - } - else - { - msg->_next = m_waiting_replies; - m_waiting_replies = msg; - } - } - else - { - m_shmmutex.Leave(); - - WaitingMessage *msgtail=NULL; - - if (OnRecv) - { - msg->_next=0; - msgtail = msg = OnRecv(this,msg); - while (msgtail && msgtail->_next) msgtail=msgtail->_next; - } - else if (msg->m_msgid) Reply(msg->m_msgid,"",0); // send an empty reply - - m_shmmutex.Enter(); // get shm again - - if (msg) - { - (msgtail?msgtail:msg)->_next = m_spares; - m_spares=msg; - } - } - } // while queue has stuff - - if (checkForReplyID && replyPtr && !*replyPtr) - { - WaitingMessage *m=m_waiting_replies; - WaitingMessage *lp=NULL; - - while (m) - { - if (m->m_msgid == checkForReplyID) - { - if (lp) lp->_next = m->_next; - else m_waiting_replies=m->_next; - - *replyPtr = m; - s=0; // make sure we return ASAP - break; - } - lp = m; - m=m->_next; - } - } - - m_shmmutex.Leave(); - - } while (s>0); - - if (s<0) m_has_had_error=true; - else if (m_shm && m_shm->WantSendKeepAlive()) - { - int zer=0; - Send(0,NULL,0,NULL,0,&zer); - } - return s<0; -} - diff --git a/WDL/shm_msgreply.h b/WDL/shm_msgreply.h deleted file mode 100644 index f5d0ee3f..00000000 --- a/WDL/shm_msgreply.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _WDL_SHM_MSGREPLY_ -#define _WDL_SHM_MSGREPLY_ - -#include -#include "shm_connection.h" -#include "mutex.h" - - -/* - 4 byte message type - - 4 byte unique message ID (0 for no reply needed/wanted) - - 4 byte message length (following) - - - type: 0 reply - call specific return data - type: all others user defined - -*/ -// type is user defined, however type=0 is reserved for reply -class SHM_MsgReplyConnection -{ - -public: - - class WaitingMessage - { - public: - WaitingMessage() { } - ~WaitingMessage() { } - - WaitingMessage *_next; - - int m_msgid; - int m_msgtype; - - WDL_HeapBuf m_msgdata; - }; - - - SHM_MsgReplyConnection(int bufsize, int maxqueuesize, bool dir, const char *uniquestr=NULL, int timeout_sec=0, int extra_flags=0); - ~SHM_MsgReplyConnection(); - - // be sure to set these, and have OnRecv() Reply() to any nonzero msgID ! - void *userData; - WaitingMessage *(*OnRecv)(SHM_MsgReplyConnection *con, WaitingMessage *msg); - bool (*IdleProc)(SHM_MsgReplyConnection *con); // return TRUE to abort (this will set the m_has_had_error to true / kill the connection) - // can return NULL To temporarily buffer msg, can return a chain of msgs too to return them to the spare list - - // run as you wish, Send() will also run internally when waiting for reply - // note: the checkForReplyID etc are for INTERNAL USE ONLY :) - - bool Run(bool runFull=true); - - // returns <0 if no reply, otherwise lenght of replybuf used - // no retbuf = no wait for reply - int Send(int type, const void *msg, int msglen, - void *replybuf, int maxretbuflen, const int *forceMsgID=NULL, - const void *secondchunk=NULL, int secondchunklen=0, // allow sending two blocks as one message (for speed in certain instances) - WDL_HeapBuf *hbreplyout=NULL); // if hbreplyout is set it will get the full message (replybuf can be NULL then) - void Reply(int msgID, const void *msg, int msglen); - void Wait(HANDLE extraEvt=NULL); - - const char *GetUniqueString() { return m_uniq; } - - void ReturnSpares(WaitingMessage *msglist); - -private: - bool RunInternal(int checkForReplyID=0, WaitingMessage **replyPtr=0); // nonzero on error - - char m_uniq[256]; - WDL_Mutex m_shmmutex; - WDL_SHM_Connection *m_shm; - - - WaitingMessage *m_waiting_replies; - WaitingMessage *m_spares; - - int m_lastmsgid; - int m_maxqueuesize; - bool m_has_had_error; -}; - -#endif diff --git a/WDL/simple_pitchshift.h b/WDL/simple_pitchshift.h deleted file mode 100644 index 62db26f7..00000000 --- a/WDL/simple_pitchshift.h +++ /dev/null @@ -1,311 +0,0 @@ -#ifndef _WDL_SIMPLEPITCHSHIFT_H_ -#define _WDL_SIMPLEPITCHSHIFT_H_ - - -#include "queue.h" - -#ifndef WDL_SIMPLEPITCHSHIFT_SAMPLETYPE -#define WDL_SIMPLEPITCHSHIFT_SAMPLETYPE double -#endif - - -#ifdef WDL_SIMPLEPITCHSHIFT_PARENTCLASS -class WDL_SimplePitchShifter : public WDL_SIMPLEPITCHSHIFT_PARENTCLASS -#else -class WDL_SimplePitchShifter -#endif -{ -public: - WDL_SimplePitchShifter() - { - m_last_nch=1; - m_srate=44100.0; - m_last_tempo=1.0; - m_last_shift=1.0; - m_qual=0; - - Reset(); - } - ~WDL_SimplePitchShifter() { } - - void Reset() - { - m_hadinput=0; - m_pspos=0.0; - m_pswritepos=0; - m_latpos=0; - m_tempo_fracpos=0.0; - m_queue.Clear(); - m_rsbuf.Resize(0,false); - m_psbuf.Resize(0,false); - } - - bool IsReset() - { - return !m_queue.Available() && !m_hadinput; - } - - - - void set_srate(double srate) { m_srate=srate; } - void set_nch(int nch) { if (m_last_nch!=nch) { m_queue.Clear(); m_last_nch=nch; m_tempo_fracpos=0.0; } } - void set_shift(double shift) { m_last_shift=shift; } - void set_tempo(double tempo) { m_last_tempo=tempo; } - void set_formant_shift(double shift) - { - } - - WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *GetBuffer(int size) - { - return m_inbuf.Resize(size*m_last_nch); - } - void BufferDone(int input_filled); - void FlushSamples() {} - - static const char *enumQual(int q); - static bool GetSizes(int qv, int *ws, int *os); - - int GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer); - - - void SetQualityParameter(int parm) - { - m_qual=parm; - } - - -private: - void PitchShiftBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, double pitch, int bsize, int olsize, double srate); - - -private: - double m_pspos WDL_FIXALIGN; - double m_tempo_fracpos; - double m_srate,m_last_tempo,m_last_shift; - - WDL_TypedBuf m_psbuf; - WDL_Queue m_queue; - WDL_TypedBuf m_inbuf; - WDL_TypedBuf m_rsbuf; - - int m_pswritepos; - int m_last_nch; - int m_qual; - int m_hadinput; - - int m_latpos; - -}; - - -#ifdef WDL_SIMPLEPITCHSHIFT_IMPLEMENT -void WDL_SimplePitchShifter::BufferDone(int input_filled) -{ - // perform pitch shifting - if (input_filled>0) - { - m_hadinput=1; - int ws,os; - GetSizes(m_qual,&ws,&os); - - int bsize=(int) (ws * 0.001 * m_srate); - if (bsize<16) bsize=16; - else if (bsize>128*1024)bsize=128*1024; - - int olsize=(int) (os * 0.001 * m_srate); - if (olsize > bsize/2) olsize=bsize/2; - if (olsize<1)olsize=1; - if (m_psbuf.GetSize() != bsize*m_last_nch) - { - memset(m_psbuf.Resize(bsize*m_last_nch,false),0,sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*bsize*m_last_nch); - m_pspos=(double) (bsize/2); - m_pswritepos=0; - } - - if (fabs(m_last_tempo-1.0)<0.0000000001) - { - PitchShiftBlock(m_inbuf.Get(),(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,input_filled*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)),m_last_nch,input_filled,m_last_shift,bsize,olsize,m_srate); - } - else - { - int needclear=m_rsbuf.GetSize() input_filled) a=input_filled; - m_latpos+=a; - fp += a; - } - - int outlen = (int) (input_filled*itempo-fp) + 128; // upper bound on possible sample count - if (outlen<0) - { - outlen=0; - } - - WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *bufo = (WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,outlen*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); - // resample bufi to bufo - int i,nch=m_last_nch; - for (i = 0; i < outlen; i ++) - { - double rdpos=floor(fp); - int idx=((int)rdpos); - if (idx>=input_filled) - { - // un-add any missing samples - m_queue.Add(NULL,(i-outlen)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); - break; - } - rdpos = (fp-rdpos); - int a; - idx*=nch; - for (a = 0; a < nch; a ++) - { - *bufo++ = bufi[idx+a]*(1.0-rdpos)+bufi[idx+nch+a]*rdpos; - } - fp += tempo; - } - - memcpy(bufi,bufi+m_last_nch*input_filled,m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); // save last sample for interpolation later - // - m_tempo_fracpos=fp-floor(fp); - } - } -} - -const char *WDL_SimplePitchShifter::enumQual(int q) -{ - int ws,os; - if (!GetSizes(q,&ws,&os)) return NULL; - static char buf[128]; - sprintf(buf,"%dms window, %dms fade",ws,os); - return buf; -} - -bool WDL_SimplePitchShifter::GetSizes(int qv, int *ws, int *os) -{ - int windows[]={50,75,100,150,225,300,40,30,20,10,5,3}; - int divs[]={2,3,5,7}; - - int wd=qv/(sizeof(divs)/sizeof(divs[0])); - if (wd >= sizeof(windows)/sizeof(windows[0])) wd=-1; - - *ws=windows[wd>=0?wd:0]; - *os = *ws / divs[qv%(sizeof(divs)/sizeof(divs[0]))]; - if (*os<1) *os=1; - - return wd>=0; -} - -int WDL_SimplePitchShifter::GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer) -{ - if (!m_last_nch||requested_output<1) return 0; - - int l=m_queue.Available()/sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)/m_last_nch; - - if (requested_output>l) requested_output=l; - int sz=requested_output*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*m_last_nch; - memcpy(buffer,m_queue.Get(),sz); - m_queue.Advance(sz); - m_queue.Compact(); - return requested_output; -} - -void WDL_SimplePitchShifter::PitchShiftBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, double pitch, int bsize, int olsize, double srate) -{ - double iolsize=1.0/olsize; - - WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *psbuf=m_psbuf.Get(); - - double dpi=pitch; - - double pspos=m_pspos; - int writepos=m_pswritepos; - int writeposnch = writepos*nch; - int bsizench = bsize*nch; - int olsizench = olsize*nch; - - int i=length; - while (i--) - { - int ipos1=(int)pspos; - double frac0=pspos-ipos1; - - ipos1*=nch; - - int ipos2=ipos1+nch; - - if (ipos2 >= bsizench) ipos2=0; - - int a; - for(a=0;a= 1.0) - { - if (tv > writepos) tv-=bsize; - - if (tv >= writepos-olsize && tv < writepos) - { - double tfrac=(writepos-tv)*iolsize; - int tmp=ipos1+olsizench; - if (tmp>=bsizench) tmp-=bsizench; - int tmp2=tmp+nch; - if (tmp2 >= bsizench) tmp2=0; - - for(a=0;a= writepos) pspos+=olsize; - } - - } - else - { - if (tv= writepos && tv < writepos+olsize) - { - double tfrac=(tv-writepos)*iolsize; - int tmp=ipos1+olsizench; - if (tmp>=bsizench) tmp -= bsizench; - int tmp2= tmp+nch; - if (tmp2 >= bsizench) tmp2=0; - for(a=0;a= writepos+olsize) pspos += olsize; - } - } - - - if ((pspos+=pitch) >= bsize) pspos -= bsize; - - - memcpy(psbuf+writeposnch,inputs,nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); - - writeposnch += nch; - if (++writepos >= bsize) writeposnch = writepos=0; - - inputs += nch; - outputs += nch; - } // sample loop - m_pspos=pspos; - m_pswritepos=writepos; -} - -#endif - -#endif diff --git a/WDL/simple_pitchshift2.h b/WDL/simple_pitchshift2.h deleted file mode 100644 index 0d084256..00000000 --- a/WDL/simple_pitchshift2.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef _WDL_SIMPLEPITCHSHIFT_H_ -#define _WDL_SIMPLEPITCHSHIFT_H_ - - -#include "queue.h" - -#ifndef WDL_SIMPLEPITCHSHIFT_SAMPLETYPE -#define WDL_SIMPLEPITCHSHIFT_SAMPLETYPE double -#endif - - -// this one isnt done yet, but stretches, then (optionally) resamples - -#ifdef WDL_SIMPLEPITCHSHIFT_PARENTCLASS -class WDL_SimplePitchShifter2 : public WDL_SIMPLEPITCHSHIFT_PARENTCLASS -#else -class WDL_SimplePitchShifter2 -#endif -{ -public: - WDL_SimplePitchShifter2() - { - m_last_nch=1; - m_srate=44100.0; - m_last_tempo=1.0; - m_last_shift=1.0; - m_qual=0; - - Reset(); - } - ~WDL_SimplePitchShifter2() { } - - void Reset() - { - m_hadinput=0; - m_pspos=0.0; - m_pswritepos=0; - m_tempo_fracpos=0.0; - m_queue.Clear(); - m_rsbuf.Resize(0,false); - m_psbuf.Resize(0,false); - } - - bool IsReset() - { - return !m_queue.Available() && !m_hadinput; - } - - - - void set_srate(double srate) { m_srate=srate; } - void set_nch(int nch) { if (m_last_nch!=nch) { m_queue.Clear(); m_last_nch=nch; m_tempo_fracpos=0.0; } } - void set_shift(double shift) { m_last_shift=shift; } - void set_tempo(double tempo) { m_last_tempo=tempo; } - void set_formant_shift(double shift) - { - } - - WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *GetBuffer(int size) - { - return m_inbuf.Resize(size*m_last_nch); - } - void BufferDone(int input_filled); - void FlushSamples() {} - - static char *enumQual(int q); - static bool GetSizes(int qv, int *ws, int *os); - - int GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer); - - - void SetQualityParameter(int parm) - { - m_qual=parm; - } - - - int Stretch(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, double srate, int ws_ms, int os_ms); - -private: - int StretchBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, int bsize, int olsize, double srate); - - -private: - double m_pspos WDL_FIXALIGN; - double m_tempo_fracpos; - double m_srate,m_last_tempo,m_last_shift; - - WDL_TypedBuf m_psbuf; - WDL_Queue m_queue; - WDL_TypedBuf m_inbuf; - WDL_TypedBuf m_rsbuf; - - int m_pswritepos; - int m_last_nch; - int m_qual; - int m_hadinput; - -}; - - -#ifdef WDL_SIMPLEPITCHSHIFT_IMPLEMENT -void WDL_SimplePitchShifter2::BufferDone(int input_filled) -{ - if (input_filled>0) - { - m_hadinput=1; - int ws,os; - GetSizes(m_qual,&ws,&os); - int max_outputlen=(int) (input_filled * m_last_shift / m_last_tempo * 1.1f + 32.0f); - - if (fabs(m_last_shift-1.0)<0.0000000001) - { - int valid_amt = Stretch(m_inbuf.Get(),(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,max_outputlen*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)),m_last_nch, - input_filled,max_outputlen,1.0/m_last_tempo,m_srate,ws,os); - - if (valid_amt < max_outputlen) - m_queue.Add(NULL,(valid_amt-max_outputlen)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); - } - else - { - int needclear=m_rsbuf.GetSize()=valid_amt) - { - // un-add any missing samples - m_queue.Add(NULL,(i-out_max)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); - break; - } - rdpos = (fp-rdpos); - int a; - idx*=nch; - for (a = 0; a < nch; a ++) - { - *bufo++ = bufi[idx+a]*(1.0-rdpos)+bufi[idx+nch+a]*rdpos; - } - fp += adv; - } - - memcpy(bufi,bufi+m_last_nch*valid_amt,m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); // save last sample for interpolation later - // - m_tempo_fracpos=fp-floor(fp); - } - } -} - -char *WDL_SimplePitchShifter2::enumQual(int q) -{ - int ws,os; - if (!GetSizes(q,&ws,&os)) return NULL; - static char buf[128]; - sprintf(buf,"%dms window, %dms fade",ws,os); - return buf; -} - -bool WDL_SimplePitchShifter2::GetSizes(int qv, int *ws, int *os) -{ - int windows[]={50,75,100,150,225,300,40,30,20,10,5,3}; - int divs[]={2,3,5,7}; - - int wd=qv/(sizeof(divs)/sizeof(divs[0])); - if (wd >= sizeof(windows)/sizeof(windows[0])) wd=-1; - - *ws=windows[wd>=0?wd:0]; - *os = *ws / divs[qv%(sizeof(divs)/sizeof(divs[0]))]; - if (*os<1) *os=1; - - return wd>=0; -} - -int WDL_SimplePitchShifter2::GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer) -{ - if (!m_last_nch||requested_output<1) return 0; - - int l=m_queue.Available()/sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)/m_last_nch; - if (requested_output>l) requested_output=l; - int sz=requested_output*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*m_last_nch; - memcpy(buffer,m_queue.Get(),sz); - m_queue.Advance(sz); - m_queue.Compact(); - return requested_output; -} - -int WDL_SimplePitchShifter2::Stretch(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, double srate, int ws_ms, int os_ms) -{ - int bsize=(int) (ws_ms * 0.001 * srate); - if (bsize<16) bsize=16; - else if (bsize>128*1024)bsize=128*1024; - - int olsize=(int) (os_ms * 0.001 * srate); - if (olsize > bsize/2) olsize=bsize/2; - if (olsize<1)olsize=1; - if (m_psbuf.GetSize() != bsize*nch) - { - memset(m_psbuf.Resize(bsize*nch,false),0,sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*bsize*nch); - m_pspos=(double) (bsize/2); - m_pswritepos=0; - } - - return StretchBlock(inputs,outputs,nch,length,maxoutlen,stretch,bsize,olsize,srate); -} - -int WDL_SimplePitchShifter2::StretchBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, int bsize, int olsize, double srate) -{ - double iolsize=1.0/olsize; - - WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *psbuf=m_psbuf.Get(); - - double pspos=m_pspos; - int writepos=m_pswritepos; - int writeposnch = writepos*nch; - int bsizench = bsize*nch; - int olsizench = olsize*nch; - int output_used=0; - int i=length; - int chunksize = nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE); - while (i--) - { - int cnt = (int) (pspos + stretch) - (int) pspos; - double pspos_fracadd=stretch - cnt; - while (cnt-- > 0) - { - if (output_used>=maxoutlen) return maxoutlen; - int ipos1=(int)pspos; - - ipos1*=nch; - - memcpy(outputs,psbuf+ipos1,chunksize); - - double tv=pspos; - if (stretch >= 1.0) - { - if (tv > writepos) tv-=bsize; - - if (tv >= writepos-olsize && tv < writepos) - { - double tfrac=(writepos-tv)*iolsize; - int tmp=ipos1+olsizench; - if (tmp>=bsizench) tmp-=bsizench; - - int a; - for(a=0;a= writepos) - { - pspos+=olsize; - } - } - - } - else - { - if (tv= writepos && tv < writepos+olsize) - { - double tfrac=(tv-writepos)*iolsize; - int tmp=ipos1+olsizench; - if (tmp>=bsizench) tmp -= bsizench; - int a; - for(a=0;a= writepos+olsize) pspos += olsize; - } - } - - - if ((pspos+=1) >= bsize) pspos -= bsize; - outputs += nch; - output_used++; - } - pspos += pspos_fracadd; - if (pspos>=bsize) pspos-=bsize; - - - - memcpy(psbuf+writeposnch,inputs,chunksize); - - writeposnch += nch; - if (++writepos >= bsize) writeposnch = writepos=0; - - inputs += nch; - } // sample loop - m_pspos=pspos; - m_pswritepos=writepos; - return output_used; - -} - -#endif - -#endif \ No newline at end of file diff --git a/WDL/sinewavegen.h b/WDL/sinewavegen.h deleted file mode 100644 index 7e8739d5..00000000 --- a/WDL/sinewavegen.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _WDL_SINEWAVEGEN_H_ -#define _WDL_SINEWAVEGEN_H_ - - -// note: calling new WDL_SineWaveGenerator isnt strictly necessary, you can also do WDL_SineWaveGenerator *gens = (WDL_SineWaveGenerator *)malloc(512*sizeof(WDL_SineWaveGenerator)); -// as long as you call Reset() and SetFreq() it should be fine. - - -// note: won't really work for high frequencies... - -class WDL_SineWaveGenerator -{ - double m_lastfreq; - double m_mul1,m_mul2; - double m_pos,m_vel; - -public: - WDL_SineWaveGenerator() { Reset(); m_mul1=m_mul2=m_pos=m_vel=0.0; } - ~WDL_SineWaveGenerator() { } - - void Reset() { m_lastfreq=0.0; } // must call this before anything - - void SetFreq(double freq) // be sure to call this before calling Gen(), or on freq change, or after a Reset() - // freq is frequency/(samplerate*0.5) (so 0..1 is valid, though over 0.3 is probably not a good idea) - { - freq*=3.1415926535897932384626433832795; // scale to freq*PI - - if (m_lastfreq<=0.0) - { - m_pos=0.0; - m_vel = 1.0/freq; - } - else - { - if (freq==m_lastfreq) return; - m_vel *= m_lastfreq/freq; - } - m_lastfreq=freq; - - double tmp2 = 1.0/(1.0+(freq*=freq)); - m_mul1 = (1.0-freq)*tmp2; - m_mul2 = freq*2.0*tmp2; - } - - double Gen() // returns sine - { - double rv=m_pos; - m_vel -= rv + (m_pos = rv*m_mul1 + m_vel*m_mul2); - return rv; - } - - double GetNextCos() // call BEFORE Gen() if you want the cosine of the next value - { - return m_vel * m_lastfreq; - } - -}; - -#endif diff --git a/WDL/stringpool.h b/WDL/stringpool.h deleted file mode 100644 index f48fcafa..00000000 --- a/WDL/stringpool.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _WDL_STRINGPOOL_H_ -#define _WDL_STRINGPOOL_H_ - - -#include "wdlstring.h" -#include "assocarray.h" -#include "mutex.h" - -class WDL_StringPool -{ - friend class WDL_PooledString; -public: - WDL_StringPool(bool wantMutex) : m_strings(true) { m_mutex = wantMutex ? new WDL_Mutex : NULL; }; - ~WDL_StringPool() { delete m_mutex; } - -private: - WDL_StringKeyedArray m_strings; -protected: - WDL_Mutex *m_mutex; - -}; - -class WDL_PooledString -{ -public: - WDL_PooledString(WDL_StringPool *pool, const char *value=NULL) { m_pool = pool; m_val = ""; Set(value); } - ~WDL_PooledString() { Set(""); } - - const char *Get() { return m_val; } - - void Set(const char *value) - { - if (!value) value=""; - if (strcmp(value,m_val)) - { - WDL_MutexLock(m_pool->m_mutex); // may or may not actually be a mutex - - const char *oldval = m_val; - - if (*value) - { - // set to new value - const char *keyptr=NULL; - int * ref = m_pool->m_strings.GetPtr(value,&keyptr); - if (ref) - { - ++*ref; - m_val=keyptr; - } - else m_pool->m_strings.Insert(value,1,&m_val); - } - else m_val=""; - - if (oldval[0]) - { - int *oldref = m_pool->m_strings.GetPtr(oldval); - if (oldref && --*oldref<=0) m_pool->m_strings.Delete(oldval); - } - } - } - - // utility for compat with WDL_String - void Append(const char *value) - { - if (value&&*value) - { - WDL_String tmp(Get()); - tmp.Append(value); - Set(tmp.Get()); - } - } - void Insert(const char *value, int pos) - { - WDL_String tmp(Get()); - tmp.Insert(value,pos); - Set(tmp.Get()); - } - void DeleteSub(int pos, int len) - { - WDL_String tmp(Get()); - tmp.DeleteSub(pos,len); - Set(tmp.Get()); - } - -private: - const char *m_val; - WDL_StringPool *m_pool; - -}; - - -#endif _WDL_STRINGPOOL_H_ \ No newline at end of file diff --git a/WDL/swell/Makefile.libSwell b/WDL/swell/Makefile.libSwell deleted file mode 100644 index 5d611c07..00000000 --- a/WDL/swell/Makefile.libSwell +++ /dev/null @@ -1,65 +0,0 @@ -# use make -f Makefile.libSwell -# or make -f Makefile.libSwell NOGDK=1 -# or make -f Makefile.libSwell DEBUG=1 -# etc - -ARCH := $(shell uname -m) - -CFLAGS = -pipe -malign-double -fvisibility=hidden -fno-strict-aliasing -fno-math-errno -fPIC -DPIC -Wall - -ifdef DEBUG -CFLAGS += -O0 -g -else -CFLAGS += -O2 -s -endif - -LINKEXTRA = -lpthread -ldl - - -EXTRA_OBJS = - - - - -vpath %.cpp .. ../lice - -SWELL_OBJS = swell.o swell-ini.o swell-miscdlg-generic.o swell-wnd-generic.o swell-menu-generic.o swell-kb-generic.o swell-dlg-generic.o \ - swell-gdi-generic.o swell-misc-generic.o swell-appstub-generic.o swell-modstub-generic.o swell-gdi-lice.o - -LICE_OBJS = lice.o lice_arc.o lice_colorspace.o lice_image.o lice_jpg.o lice_line.o lice_pcx.o lice_png.o lice_texgen.o lice_text.o \ - lice_textnew.o lice_ico.o lice_bmp.o lice_lvg.o - -OBJS = $(SWELL_OBJS) - -ifndef NOGDK - ifdef GDK2 - CFLAGS += -DSWELL_TARGET_GDK=2 $(shell pkg-config --cflags gdk-2.0) - LINKEXTRA += $(shell pkg-config --libs gdk-2.0) - else - CFLAGS += -DSWELL_TARGET_GDK=3 $(shell pkg-config --cflags gdk-3.0) - LINKEXTRA += $(shell pkg-config --libs gdk-3.0) - endif - CFLAGS += -DSWELL_LICE_GDI - OBJS += $(LICE_OBJS) - - ifndef NOFREETYPE - CFLAGS += -DSWELL_FREETYPE $(shell freetype-config --cflags) - LINKEXTRA += $(shell freetype-config --libs) - endif -endif - -CXXFLAGS = $(CFLAGS) - -default: libSwell.so - -.PHONY: clean - -libSwell.so: $(OBJS) - $(CXX) -shared -o $@ $(CFLAGS) $(LFLAGS) $(LINKEXTRA) $^ - -test: $(OBJS) test.o - $(CXX) -o test $(CFLAGS) $(LFLAGS) $(LINKEXTRA) $^ - -clean: - -rm $(OBJS) libSwell.so - diff --git a/WDL/swell/commctrl.h b/WDL/swell/commctrl.h deleted file mode 100644 index 776a87ce..00000000 --- a/WDL/swell/commctrl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/WDL/swell/mac_resgen.php b/WDL/swell/mac_resgen.php deleted file mode 100755 index d9564c9d..00000000 --- a/WDL/swell/mac_resgen.php +++ /dev/null @@ -1,283 +0,0 @@ -#!/usr/bin/php -=2) - { - $dlg_contents .= $y . "\n"; - if ($y == "END") - { - if ($dlg_state==2) $dlg_styles.="|SWELL_DLG_WS_OPAQUE"; - $retstr .= "#ifndef SET_$dlg_name" . "_SCALE\n"; - $retstr .= "#define SET_$dlg_name" . "_SCALE SWELL_DLG_SCALE_AUTOGEN\n"; - $retstr .= "#endif\n"; - $retstr .= "#ifndef SET_$dlg_name" . "_STYLE\n"; - $retstr .= "#define SET_$dlg_name" . "_STYLE $dlg_styles\n"; - $retstr .= "#endif\n"; - $retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_BEGIN($dlg_name,SET_$dlg_name" . "_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h,SET_$dlg_name" . "_SCALE)\n"; - $dlg_contents=str_replace("NOT WS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); - $dlg_contents=str_replace("NOT\nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); - $dlg_contents=str_replace("NOT \nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); - $retstr .= $dlg_contents; - $retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END($dlg_name)\n\n\n"; - $dlg_state=0; - } - else if (strlen($y)>1) $dlg_state=3; - } - else - { - $parms = explode(" ", $y); - if (count($parms) > 0) - { - if ($dlg_state == 0) - { - // if (substr($parms[0],0,8) == "IDD_PREF") - if (count($parms)>4 && ($parms[1] == 'DIALOGEX'||$parms[1] == 'DIALOG')) - { - $dlg_name=$parms[0]; - $rdidx = 2; - if ($parms[$rdidx] == 'DISCARDABLE') $rdidx++; - while ($parms[$rdidx] == "" && $rdidx < count($parms)) $rdidx++; - $rdidx += 2; - $dlg_size_w = str_replace(",","",$parms[$rdidx++]); - $dlg_size_h = str_replace(",","",$parms[$rdidx++]); - if (count($parms) >= $rdidx && $dlg_size_w != "" && $dlg_size_h != "") - { - $dlg_title=""; - $dlg_styles="SWELL_DLG_FLAGS_AUTOGEN"; - $dlg_contents=""; - $dlg_state=1; - } - else $errstr .= "WARNING: corrupted $dlg_name resource\n"; - } - } - else if ($dlg_state == 1) - { - if ($parms[0] == "BEGIN") - { - $dlg_state=2; - $dlg_contents = $y ."\n"; - } - else - { - if ($parms[0] == "CAPTION") - { - $dlg_title = str_replace("\"","",trim(substr($y,8))); - } - else if ($parms[0] == "STYLE" || $parms[0] == "EXSTYLE") - { - $rep=0; - for (;;) - { - $next_line = fgets($fp,4096); - if (!($next_line )) { $next_line=""; break; } - if (substr($next_line,0,1)==" " || substr($next_line,0,1)=="\t") - { - $y .= " " . trim($next_line); - $rep++; - $next_line=""; - } - else break; - } - if ($rep) $parms = explode(" ", $y); - $opmode=0; - $rdidx=1; - while ($rdidx < count($parms)) - { - if ($parms[$rdidx] == '|') { $opmode=0; } - else if ($parms[$rdidx] == 'NOT') { $opmode=1; } - else if ($parms[$rdidx] == 'WS_CHILD') - { - if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_CHILD"; - } - else if ($parms[$rdidx] == 'WS_THICKFRAME') - { - if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_RESIZABLE"; - } - else if ($parms[$rdidx] == 'WS_EX_ACCEPTFILES') - { - if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_DROPTARGET"; - } - else $opmode=0; - $rdidx++; - } - } - } - } - } - } - } - if ($dlg_state != 0) - $errstr .= "WARNING: there may have been a truncated dialog resource ($dlg_name)\n"; - - $retstr .= "\n//EOF\n\n"; - $rv = array(); - $rv["data"] = $retstr; - $rv["error"] = $errstr; - return $rv; -} - -function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally ["error"] -{ - $retstr=""; - $errstr=""; - - fseek($fp,0,SEEK_SET); - - $menu_symbol=""; - $menu_depth=0; - while (($x=fgets($fp))) - { - $a=strpos($x, "\"\""); - if ($a) - { - $b=strpos($x, "\""); - $c=strpos($x, "\"", $a+1); - if ($b && $c && $b < $a && $c > $a) - { - $x=str_replace("\"\"", "\\\"", $x); - } - } - - $y=trim($x); - if ($menu_symbol == "") - { - $parms = explode(" ", $y); - $tok = "MENU"; - if (count($parms) >= 2 && $parms[1] == $tok) - { - $menu_symbol = $parms[0]; - $menu_depth=0; - $retstr .= "SWELL_DEFINE_MENU_RESOURCE_BEGIN($menu_symbol)\n"; - } - } - else - { - if ($y == "END") - { - $menu_depth-=1; - if ($menu_depth == 0) - { - $retstr .= "SWELL_DEFINE_MENU_RESOURCE_END($menu_symbol)\n\n\n"; - } - if ($menu_depth < 1) $menu_symbol=""; - } - if ($menu_depth>0) - { - if (substr($y,-strlen(", HELP")) == ", HELP") - { - $x=substr(rtrim($x),0,-strlen(", HELP")) . "\n"; - } - $retstr .= $x; - } - if ($y == "BEGIN") $menu_depth+=1; - } - } - - $retstr .= "\n//EOF\n\n"; - $rv = array(); - $rv["data"] = $retstr; - $rv["error"] = $errstr; - - return $rv; -} - -if (count($argv)<2) die("usage: mac_resgen.php [--force] file.rc ...\n"); - -$x=1; -$forcemode = 0; -if ($argv[$x] == "--force") { $forcemode=1; $x++; } - -$lp = dirname(__FILE__); -$proc=0; -$skipped=0; -$err=0; -for (; $x < count($argv); $x ++) -{ - $srcfn = $argv[$x]; - if (!stristr($srcfn,".rc") || !($fp = @fopen($srcfn,"r"))) - { - $err++; - echo "$srcfn: not valid or not found!\n"; - continue; - } - echo "$srcfn: "; - $ofnmenu = $srcfn . "_mac_menu"; - $ofndlg = $srcfn . "_mac_dlg"; - - $res = swell_rc2cpp_dialog($fp); - $res2 = swell_rc2cpp_menu($fp); - fclose($fp); - if ($res["error"] != "" || $res2["error"] != "") - { - $err++; - echo "error"; - if ($res["error"] != "") echo " dialog: " . $res["error"]; - if ($res2["error"] != "") echo " menu: " . $res2["error"]; - echo "\n"; - continue; - } - $f=""; - if ($forcemode || !file_exists($ofndlg) || file_get_contents($ofndlg) != $res["data"]) - { - $f .= "dlg updated"; - if (!file_put_contents($ofndlg,$res["data"],LOCK_EX)) { echo "error writing $ofndlg\n"; $err++; } - } - if ($forcemode || !file_exists($ofnmenu) || file_get_contents($ofnmenu) != $res2["data"]) - { - if ($f != "") $f .= ", "; - $f .= "menu updated"; - if (!file_put_contents($ofnmenu,$res2["data"],LOCK_EX)) { echo "error writing $ofnmenu\n"; $err++; } - } - - - if ($f) echo "$f\n"; - else echo "skipped\n"; - if ($f != "") $proc++; - else $skipped++; -} -echo "processed $proc, skipped $skipped, error $err\n"; - -?> diff --git a/WDL/swell/make-libSwells.sh b/WDL/swell/make-libSwells.sh deleted file mode 100644 index 764093c1..00000000 --- a/WDL/swell/make-libSwells.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -DESCSTR=libSwell-`uname -m`-`lsb_release -i -s | tr '[:upper:]' '[:lower:]'`-`lsb_release -c -s | tr '[:upper:]' '[:lower:]'` -make -f Makefile.libSwell NOGDK=1 clean -make -f Makefile.libSwell NOGDK=1 || exit 1 -tar cvJf $DESCSTR-headless.tar.xz libSwell.so || exit 1 - -make -f Makefile.libSwell clean -make -f Makefile.libSwell || exit 1 -tar cvJf $DESCSTR-gtk3.tar.xz libSwell.so || exit 1 - diff --git a/WDL/swell/sample_project/English.lproj/InfoPlist.strings b/WDL/swell/sample_project/English.lproj/InfoPlist.strings deleted file mode 100644 index 5e45963c382ba690b781b953a00585212b898ac5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92 zcmW-XQ3`+{5C!MkQ~2$No+IcIkqMDxWCV8j>LCj|yTg2Mz+o9F%uHlf9u}h9EuK`F a!Y*1dX%G66ZqL#C$|bw0ZoP5@jOGW1ArT7z diff --git a/WDL/swell/sample_project/English.lproj/MainMenu.xib b/WDL/swell/sample_project/English.lproj/MainMenu.xib deleted file mode 100644 index dc6f1700..00000000 --- a/WDL/swell/sample_project/English.lproj/MainMenu.xib +++ /dev/null @@ -1,520 +0,0 @@ - - - - 1050 - 9L30 - 677 - 949.54 - 353.00 - - YES - - - - YES - com.apple.InterfaceBuilderKit - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - NSApplication - - - FirstResponder - - - SWELLApplication - - - AMainMenu - - YES - - - SWELL Sample - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - SWELL Sample - - YES - - - About SWELL Sample - - 2147483647 - - - 40002 - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - UHJlZmVyZW5jZXPigKY - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - YES - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide SWELL Sample - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit SWELL Sample - q - 1048576 - 2147483647 - - - 40001 - - - _NSAppleMenu - - - - _NSMainMenu - - - NSFontManager - - - SWELLAppController - - - - - YES - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - terminate: - - - - 449 - - - - onSysMenuCommand: - - - - 451 - - - - - YES - - 0 - - YES - - - - - - -2 - - - RmlsZSdzIE93bmVyA - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - YES - - - - MainMenu - - - 56 - - - YES - - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - 1111 - - - 144 - - - - - 129 - - - 121 - - - 143 - - - - - 236 - - - - - 131 - - - YES - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 420 - - - - - 450 - - - Controller - - - - - YES - - YES - -1.IBPluginDependency - -2.IBPluginDependency - -3.IBPluginDependency - 129.IBPluginDependency - 129.ImportedFromIB2 - 130.IBPluginDependency - 130.ImportedFromIB2 - 130.editorWindowContentRectSynchronizationRect - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 143.IBPluginDependency - 143.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 29.WindowOrigin - 29.editorWindowContentRectSynchronizationRect - 420.IBPluginDependency - 450.IBPluginDependency - 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBEditorWindowLastContentRect - 57.IBPluginDependency - 57.ImportedFromIB2 - 57.editorWindowContentRectSynchronizationRect - 58.IBPluginDependency - 58.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilderKit - com.apple.InterfaceBuilderKit - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{436, 809}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{207, 285}, {144, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - {74, 862} - {{6, 978}, {478, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{219, 102}, {234, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{23, 794}, {245, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - YES - - - YES - - - - - YES - - YES - - - YES - - - - 451 - - - - YES - - SWELLAppController - NSObject - - onSysMenuCommand: - id - - - IBDocumentRelativeSource - ../../swellappmain.h - - - - SWELLApplication - NSApplication - - - - - 0 - ../sample_project.xcodeproj - 3 - - diff --git a/WDL/swell/sample_project/Info.plist b/WDL/swell/sample_project/Info.plist deleted file mode 100644 index 1fe7bf0a..00000000 --- a/WDL/swell/sample_project/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSMainNibFile - MainMenu - NSPrincipalClass - SWELLApplication - - diff --git a/WDL/swell/sample_project/app_main.cpp b/WDL/swell/sample_project/app_main.cpp deleted file mode 100644 index 5c49eb13..00000000 --- a/WDL/swell/sample_project/app_main.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "main.h" -#include "resource.h" - -/*** - How we created the xcode project that compiles this, too: - - New Project -> Mac OS X -> Application -> Cocoa Application - - Save as... - - Add to "Other sources/SWELL": (from swell path) swell-dlg.mm swell-gdi.mm swell-ini.cpp swell-kb.mm swell-menu.mm swell-misc.mm swell-miscdlg.mm swell-wnd.mm swell.cpp swell-appstub.mm swellappmain.mm - - Add app_main.cpp main_dialog.cpp to "Other sources" - - Go to Frameworks -> Linked Frameworks, add existing framework, Carbon.Framework - - go to terminal, to project dir, and run php /mac_resgen.php sample_project.rc - - Open mainmenu.xib in Interface Builder (doubleclick it in XCode) - - + Delete the default "Window" - + File->Read class files, find and select "swellappmain.h" - + Go to Library, Objects, scroll to "Object" , drag to "MainMenu.xib", rename to "Controller", then open its - properties (Cmd+Shift+I, go to class identity tab), choose for Class "SWELLAppController". - + Select "Application" in MainMenu.xib, go to (Cmd+Shift+I) application identity tab, select "SWELLApplication" for the class. - - + Customize the "NewApplication" menu. - + Properties on "About NewApplication": - + set the tag to 40002 (matching resource.h for about) - + on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand). - + Properties on "Quit NewApplication": - + set the tag to 40001 (matching resource.h for quit) - + on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand). - + Delete the file/edit/format/view/window/help menus, if you like (or keep some of them if you want) - - + Save and quit IB - - Go to Targets->sample_project, hit cmd+I, go to "Properties", and change Principal class to "SWELLApplication" - - - ...and then bleh you're done! :) - - */ - - - -HWND g_hwnd; // our main window (this corresponds to an NSView on OSX but we still use HWND) - -// these are not needed on OSX but defined anyway -HINSTANCE g_hInst; -UINT Scroll_Message; - - -#ifdef _WIN32 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd) -{ - g_hInst=hInstance; - // SWELLAPP_ONLOAD or so - - InitCommonControls(); - Scroll_Message = RegisterWindowMessage("MSWHEEL_ROLLMSG"); - - // create dialog (SWELLAPP_LOADED) - CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),MainDlgProc); - - for(;;) - { - MSG msg={0,}; - int vvv = GetMessage(&msg,NULL,0,0); - if (!vvv) break; - - if (vvv<0) - { - Sleep(10); - continue; - } - if (!msg.hwnd) - { - DispatchMessage(&msg); - continue; - } - - // if you want to hook any keyboard in here, the SWELL equiv is SWELLAPP_PROCESSMESSAGE - - - if (g_hwnd && IsDialogMessage(g_hwnd,&msg)) continue; - - // default processing for other dialogs - HWND hWndParent=NULL; - HWND temphwnd = msg.hwnd; - do - { - if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770) - { - hWndParent=temphwnd; - if (!(GetWindowLong(temphwnd,GWL_STYLE)&WS_CHILD)) break; // not a child, exit - } - } - while (temphwnd = GetParent(temphwnd)); - - if (hWndParent && IsDialogMessage(hWndParent,&msg)) continue; - - TranslateMessage(&msg); - DispatchMessage(&msg); - - } - - // in case g_hwnd didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly - if (g_hwnd) DestroyWindow(g_hwnd); - - return 0; -} -#else - -extern HMENU SWELL_app_stocksysmenu; -extern "C" { -INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) -{ - switch (msg) - { - case SWELLAPP_ONLOAD: - break; - case SWELLAPP_LOADED: - - if (SWELL_app_stocksysmenu) // set the SWELL default menu, using the .nib'd menu as the default settings - { - HMENU menu = CreatePopupMenu(); - HMENU nm=SWELL_DuplicateMenu(SWELL_app_stocksysmenu); - if (nm) - { - MENUITEMINFO mi={sizeof(mi),MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,0,0,nm,NULL,NULL,0,"SampleApp"}; - InsertMenuItem(menu,0,TRUE,&mi); - } - SWELL_SetDefaultModalWindowMenu(menu); - } - - { - HMENU menu = LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1)); - { - HMENU sm=GetSubMenu(menu,0); - DeleteMenu(sm,ID_QUIT,MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX - - // remove any trailing separators - int a= GetMenuItemCount(sm); - while (a > 0 && GetMenuItemID(sm,a-1)==0) DeleteMenu(sm,--a,MF_BYPOSITION); - } - // delete help menu from Windows menu (since we only use it for "About", which is in the system menu - DeleteMenu(menu,GetMenuItemCount(menu)-1,MF_BYPOSITION); - - if (SWELL_app_stocksysmenu) // insert the stock system menu - { - HMENU nm=SWELL_DuplicateMenu(SWELL_app_stocksysmenu); - if (nm) - { - MENUITEMINFO mi={sizeof(mi),MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,0,0,nm,NULL,NULL,0,"SampleApp"}; - InsertMenuItem(menu,0,TRUE,&mi); - } - } - - // if we want to set any default modifiers for items in the menus, we can use: - // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc. - - - HWND hwnd = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,MainDlgProc); - - SetMenu(hwnd,menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL - // we need to set it manually (and obviously we've edited the menu anyway) - } - break; - case SWELLAPP_ONCOMMAND: - // this is to catch commands coming from the system menu etc - if (g_hwnd && (parm1&0xffff)) SendMessage(g_hwnd,WM_COMMAND,parm1&0xffff,0); - break; - case SWELLAPP_DESTROY: - if (g_hwnd) DestroyWindow(g_hwnd); - break; - case SWELLAPP_PROCESSMESSAGE: - // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to - break; - } - return 0; -} -}; - -#endif - - - - -#ifndef _WIN32 // import the resources. Note: if you do not have these files, run "php ../mac_resgen.php sample_project.rc" from this directory - #include "../swell-dlggen.h" - - #include "sample_project.rc_mac_dlg" - - #include "../swell-menugen.h" - - #include "sample_project.rc_mac_menu" -#endif diff --git a/WDL/swell/sample_project/main.h b/WDL/swell/sample_project/main.h deleted file mode 100644 index 628f73ff..00000000 --- a/WDL/swell/sample_project/main.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _SAMPLEPROJECT_MAIN_H_ -#define _SAMPLEPROJECT_MAIN_H_ - - -#ifdef _WIN32 -#include -#include -#else -#include "../swell.h" -#endif - -#include "../../wdltypes.h" - -extern WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -extern HINSTANCE g_hInst; -extern HWND g_hwnd; -extern UINT Scroll_Message; - - - -#endif//_SAMPLEPROJECT_MAIN_H_ - diff --git a/WDL/swell/sample_project/main.m b/WDL/swell/sample_project/main.m deleted file mode 100644 index 4f4a95cd..00000000 --- a/WDL/swell/sample_project/main.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.m -// sample_project -// -// Created by Justin Frankel on 11/24/09. -// Copyright Cockos Incorporated 2009. All rights reserved. -// - -#import - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/WDL/swell/sample_project/main_dialog.cpp b/WDL/swell/sample_project/main_dialog.cpp deleted file mode 100644 index fb70346e..00000000 --- a/WDL/swell/sample_project/main_dialog.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "main.h" - -#include "resource.h" - - -WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - g_hwnd=hwndDlg; - - SetDlgItemText(hwndDlg,IDC_EDIT1,"Text yay"); - - ShowWindow(hwndDlg,SW_SHOW); - return 1; - case WM_DESTROY: - g_hwnd=NULL; - - #ifdef _WIN32 - PostQuitMessage(0); - #else - // this isnt just "PostQuitMessage", because the behaviors don't totally match -- i.e. - // it is relatively normal for the OS X app to get terminated without us calling this. Sooo, our exit handler - // code shouldn't rely on us having called this, etc... - SWELL_PostQuitMessage(hwndDlg); - #endif - - return 0; - case WM_CLOSE: - DestroyWindow(hwndDlg); - return 0; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case ID_QUIT: - DestroyWindow(hwndDlg); - return 0; - case ID_SOMETHING: - { - char buf[1024]; - if (GetDlgItemText(hwndDlg,IDC_EDIT1,buf,sizeof(buf))) - { - MessageBox(hwndDlg,buf,"The string!",MB_OK); - } - } - return 0; - case ID_ABOUT: - MessageBox(hwndDlg,"SWELL test app","Hooray",MB_OK); - return 0; - } - return 0; - } - return 0; -} diff --git a/WDL/swell/sample_project/resource.h b/WDL/swell/sample_project/resource.h deleted file mode 100644 index 376a461a..00000000 --- a/WDL/swell/sample_project/resource.h +++ /dev/null @@ -1,21 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by sample_project.rc -// -#define IDD_DIALOG1 101 -#define IDR_MENU1 102 -#define IDC_EDIT1 1001 -#define ID_QUIT 40001 -#define ID_ABOUT 40002 -#define ID_SOMETHING 40003 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 -#define _APS_NEXT_COMMAND_VALUE 40004 -#define _APS_NEXT_CONTROL_VALUE 1002 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/WDL/swell/sample_project/sample_project.dsp b/WDL/swell/sample_project/sample_project.dsp deleted file mode 100644 index 9708f07d..00000000 --- a/WDL/swell/sample_project/sample_project.dsp +++ /dev/null @@ -1,119 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sample_project" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=sample_project - 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 "sample_project.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 "sample_project.mak" CFG="sample_project - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sample_project - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "sample_project - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sample_project - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 - -!ELSEIF "$(CFG)" == "sample_project - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sample_project - Win32 Release" -# Name "sample_project - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\app_main.cpp -# End Source File -# Begin Source File - -SOURCE=.\main_dialog.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\main.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\sample_project.rc -# End Source File -# End Group -# End Target -# End Project diff --git a/WDL/swell/sample_project/sample_project.dsw b/WDL/swell/sample_project/sample_project.dsw deleted file mode 100644 index c74c29e1..00000000 --- a/WDL/swell/sample_project/sample_project.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "sample_project"=.\sample_project.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/WDL/swell/sample_project/sample_project.rc b/WDL/swell/sample_project/sample_project.rc deleted file mode 100644 index fb1c6264..00000000 --- a/WDL/swell/sample_project/sample_project.rc +++ /dev/null @@ -1,118 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 264, 117 -STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Sample app" -MENU IDR_MENU1 -FONT 8, "MS Sans Serif" -BEGIN - EDITTEXT IDC_EDIT1,59,50,145,14,ES_AUTOHSCROLL - LTEXT "Enter some text here:",IDC_STATIC,59,39,73,8 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_DIALOG1, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 257 - TOPMARGIN, 7 - BOTTOMMARGIN, 110 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU1 MENU DISCARDABLE -BEGIN - POPUP "&File" - BEGIN - MENUITEM "MessageBox the string", ID_SOMETHING - MENUITEM SEPARATOR - MENUITEM "&Quit", ID_QUIT - END - POPUP "&Help" - BEGIN - MENUITEM "&About", ID_ABOUT - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns b/WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns deleted file mode 100644 index 62cb7015e09d6ea3e65d7f7949c4c07f9246a908..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52318 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 WhsmLR^b3` -#endif diff --git a/WDL/swell/sample_project/version.plist b/WDL/swell/sample_project/version.plist deleted file mode 100644 index 5611992c..00000000 --- a/WDL/swell/sample_project/version.plist +++ /dev/null @@ -1,16 +0,0 @@ - - - - - BuildVersion - 3 - CFBundleVersion - 1.0 - ProductBuildVersion - 9M2729 - ProjectName - DevToolsWizardTemplates - SourceVersion - 11600000 - - diff --git a/WDL/swell/shlobj.h b/WDL/swell/shlobj.h deleted file mode 100644 index 776a87ce..00000000 --- a/WDL/swell/shlobj.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/WDL/swell/swell-appstub-generic.cpp b/WDL/swell/swell-appstub-generic.cpp deleted file mode 100644 index ad5caed2..00000000 --- a/WDL/swell/swell-appstub-generic.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "swell.h" - - -#ifndef SWELL_PROVIDED_BY_APP - -// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins -// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm - -#undef _WDL_SWELL_H_API_DEFINED_ -#undef SWELL_API_DEFINE -#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func }, -static struct api_ent -{ - const char *name; - void *func; -} -api_table[]= -{ -#include "swell.h" -}; - -static int compfunc(const void *a, const void *b) -{ - return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name); -} - -extern "C" { -__attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) -{ - if (!name) return (void *)0x100; // version - static int a; - if (!a) - { - a=1; - qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); - } - struct api_ent find={name,NULL}; - struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); - if (res) return res->func; - return NULL; -} -}; - -#endif diff --git a/WDL/swell/swell-appstub.mm b/WDL/swell/swell-appstub.mm deleted file mode 100644 index 2984c3f7..00000000 --- a/WDL/swell/swell-appstub.mm +++ /dev/null @@ -1,42 +0,0 @@ -#include "swell.h" - - -#ifndef SWELL_PROVIDED_BY_APP - -// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins -// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm - -#undef _WDL_SWELL_H_API_DEFINED_ -#undef SWELL_API_DEFINE -#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func }, -static struct api_ent -{ - const char *name; - void *func; -} -api_table[]= -{ -#include "swell-functions.h" -}; - -static int compfunc(const void *a, const void *b) -{ - return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name); -} - -void *SWELLAPI_GetFunc(const char *name) -{ - if (!name) return (void *)0x100; // version - static int a; - if (!a) - { - a=1; - qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); - } - struct api_ent find={name,NULL}; - struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); - if (res) return res->func; - return NULL; -} - -#endif diff --git a/WDL/swell/swell-dlg-generic.cpp b/WDL/swell/swell-dlg-generic.cpp deleted file mode 100644 index 63a30f08..00000000 --- a/WDL/swell/swell-dlg-generic.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-dlggen.h" - -#include "../ptrlist.h" - -static HMENU g_swell_defaultmenu,g_swell_defaultmenumodal; - -void (*SWELL_DDrop_onDragLeave)(); -void (*SWELL_DDrop_onDragOver)(POINT pt); -void (*SWELL_DDrop_onDragEnter)(void *hGlobal, POINT pt); -const char* (*SWELL_DDrop_getDroppedFileTargetPath)(const char* extension); - -bool SWELL_owned_windows_levelincrease=false; - -#include "swell-internal.h" - -static SWELL_DialogResourceIndex *resById(SWELL_DialogResourceIndex *reshead, const char *resid) -{ - SWELL_DialogResourceIndex *p=reshead; - while (p) - { - if (p->resid == resid) return p; - p=p->_next; - } - return 0; -} - -// keep list of modal dialogs -struct modalDlgRet { - HWND hwnd; - bool has_ret; - int ret; -}; - - -static WDL_PtrList s_modalDialogs; - -HWND DialogBoxIsActive() -{ - return s_modalDialogs.GetSize() ? s_modalDialogs.Get(s_modalDialogs.GetSize()-1)->hwnd : NULL; -} - -void EndDialog(HWND wnd, int ret) -{ - if (!wnd) return; - - int x; - for (x = 0; x < s_modalDialogs.GetSize(); x ++) - if (s_modalDialogs.Get(x)->hwnd == wnd) - { - s_modalDialogs.Get(x)->has_ret=true; - s_modalDialogs.Get(x)->ret = ret; - } - DestroyWindow(wnd); - // todo -} - -int SWELL_DialogBox(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) -{ - SWELL_DialogResourceIndex *p=resById(reshead,resid); - if (resid) // allow modal dialogs to be created without template - { - if (!p||(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) return -1; - } - - - int ret=-1; - HWND hwnd = SWELL_CreateDialog(reshead,resid,parent,dlgproc,param); - // create dialog - if (hwnd) - { - ReleaseCapture(); // force end of any captures - - WDL_PtrList enwnds; - extern HWND__ *SWELL_topwindows; - HWND a = SWELL_topwindows; - while (a) - { - if (a->m_enabled && a != hwnd) { EnableWindow(a,FALSE); enwnds.Add(a); } - a = a->m_next; - } - - modalDlgRet r = { hwnd,false, -1 }; - s_modalDialogs.Add(&r); - ShowWindow(hwnd,SW_SHOW); - while (s_modalDialogs.Find(&r)>=0 && !r.has_ret) - { - void SWELL_RunMessageLoop(); - SWELL_RunMessageLoop(); - Sleep(10); - } - ret=r.ret; - s_modalDialogs.Delete(s_modalDialogs.Find(&r)); - - a = SWELL_topwindows; - while (a) - { - if (!a->m_enabled && a != hwnd && enwnds.Find(a)>=0) EnableWindow(a,TRUE); - a = a->m_next; - } - } - // while in list, do something - return ret; -} - -HWND SWELL_CreateDialog(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) -{ - SWELL_DialogResourceIndex *p=resById(reshead,resid); - if (!p&&resid) return 0; - - RECT r={0,0,p?p->width : 300, p?p->height : 200}; - HWND owner=NULL; - - if ((!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD)) && parent) - { - } - else - { - owner = parent; - parent = NULL; // top level window - } - - HWND__ *h = new HWND__(parent,0,&r,NULL,false,NULL,NULL); - if (p && !(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) - { - if (p->windowTypeFlags&SWELL_DLG_WS_RESIZABLE) h->m_style |= WS_THICKFRAME|WS_CAPTION; - else h->m_style |= WS_CAPTION; - } - else if (!p && !parent) h->m_style |= WS_CAPTION; - else if (parent && (!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD))) h->m_style |= WS_CHILD; - - if (p) - { - p->createFunc(h,p->windowTypeFlags); - if (p->title) SetWindowText(h,p->title); - - h->m_dlgproc = dlgproc; - h->m_wndproc = SwellDialogDefaultWindowProc; - - //HWND hFoc=m_children; -// while (hFoc && !hFoc->m_wantfocus) hFoc=hFoc->m_next; - // if (!hFoc) hFoc=this; - // if (dlgproc(this,WM_INITDIALOG,(WPARAM)hFoc,0)&&hFoc) SetFocus(hFoc); - - h->m_dlgproc(h,WM_INITDIALOG,0,param); - } - else - { - h->m_wndproc = (WNDPROC)dlgproc; - h->m_wndproc(h,WM_CREATE,0,param); - } - - return h; -} - - -HMENU SWELL_GetDefaultWindowMenu() { return g_swell_defaultmenu; } -void SWELL_SetDefaultWindowMenu(HMENU menu) -{ - g_swell_defaultmenu=menu; -} -HMENU SWELL_GetDefaultModalWindowMenu() -{ - return g_swell_defaultmenumodal; -} -void SWELL_SetDefaultModalWindowMenu(HMENU menu) -{ - g_swell_defaultmenumodal=menu; -} - - - -SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; // this eventually will go into a per-module stub file - - -static char* s_dragdropsrcfn = 0; -static void (*s_dragdropsrccallback)(const char*) = 0; - -void SWELL_InitiateDragDrop(HWND hwnd, RECT* srcrect, const char* srcfn, void (*callback)(const char* dropfn)) -{ - SWELL_FinishDragDrop(); - - if (1) return; - - s_dragdropsrcfn = strdup(srcfn); - s_dragdropsrccallback = callback; - - char* p = s_dragdropsrcfn+strlen(s_dragdropsrcfn)-1; - while (p >= s_dragdropsrcfn && *p != '.') --p; - ++p; - -} - -// owner owns srclist, make copies here etc -void SWELL_InitiateDragDropOfFileList(HWND hwnd, RECT *srcrect, const char **srclist, int srccount, HICON icon) -{ - SWELL_FinishDragDrop(); - - if (1) return; - -} - -void SWELL_FinishDragDrop() -{ - free(s_dragdropsrcfn); - s_dragdropsrcfn = 0; - s_dragdropsrccallback = 0; -} - -#endif diff --git a/WDL/swell/swell-dlg.mm b/WDL/swell/swell-dlg.mm deleted file mode 100644 index d273bf7e..00000000 --- a/WDL/swell/swell-dlg.mm +++ /dev/null @@ -1,3214 +0,0 @@ -#ifndef SWELL_PROVIDED_BY_APP - - -#include "swell.h" -#include "swell-dlggen.h" - -#import -#include -#include - -#ifndef SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN -#define SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN 1 // 2 gives more performance, not correctly drawn window frames (try NSThemeFrame stuff? bleh) -#endif - -static HMENU g_swell_defaultmenu,g_swell_defaultmenumodal; - -void (*SWELL_DDrop_onDragLeave)(); -void (*SWELL_DDrop_onDragOver)(POINT pt); -void (*SWELL_DDrop_onDragEnter)(void *hGlobal, POINT pt); -const char* (*SWELL_DDrop_getDroppedFileTargetPath)(const char* extension); - -bool SWELL_owned_windows_levelincrease=false; - -#include "swell-internal.h" -#include "../wdlstring.h" - -#define NSColorFromCol(a) [NSColor colorWithCalibratedRed:GetRValue(a)/255.0f green:GetGValue(a)/255.0f blue:GetBValue(a)/255.0f alpha:1.0f] -extern int g_swell_terminating; - -static LRESULT sendSwellMessage(id obj, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (obj && [obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - return [(SWELL_hwndChild *)obj onSwellMessage:uMsg p1:wParam p2:lParam]; - return 0; -} - - -static BOOL useNoMiddleManCocoa() -{ - static char is105; - if (!is105) - { - SInt32 v=0x1040; - Gestalt(gestaltSystemVersion,&v); - is105 = v>=0x1050 ? 1 : -1; - } - return is105>0; -} - -void updateWindowCollection(NSWindow *w) -{ - static SInt32 ver; - if (!ver) - { - Gestalt(gestaltSystemVersion,&ver); - if (!ver) ver=0x1040; - } - if (ver>=0x1060) - { - const int NSWindowCollectionBehaviorParticipatesInCycle = 1 << 5; - const int NSWindowCollectionBehaviorManaged = 1 << 2; - [(SWELL_WindowExtensions*)w setCollectionBehavior:NSWindowCollectionBehaviorManaged|NSWindowCollectionBehaviorParticipatesInCycle]; - } -} - -static void DrawSwellViewRectImpl(SWELL_hwndChild *view, NSRect rect, HDC hdc); -static void swellRenderOptimizely(int passflags, SWELL_hwndChild *view, HDC hdc, BOOL doforce, WDL_PtrList *needdraws, const NSRect *rlist, int rlistcnt, int draw_xlate_x, int draw_xlate_y, bool iscv); - -static LRESULT SWELL_SendMouseMessage(NSView *slf, int msg, NSEvent *event); -static LRESULT SWELL_SendMouseMessageImpl(SWELL_hwndChild *slf, int msg, NSEvent *theEvent) -{ - - NSView *capv=(NSView *)GetCapture(); - if (capv && capv != slf && [capv window] == [slf window] && [capv isKindOfClass:[SWELL_hwndChild class]]) - return SWELL_SendMouseMessage((SWELL_hwndChild*)capv,msg,theEvent); - - if (slf->m_hashaddestroy||!slf->m_wndproc) return -1; - - NSPoint swellProcessMouseEvent(int msg, NSView *view, NSEvent *event); - - NSPoint p = swellProcessMouseEvent(msg,slf,theEvent); - unsigned short xpos=(int)floor(p.x); - unsigned short ypos=(int)floor(p.y); - - LRESULT htc=HTCLIENT; - if (msg != WM_MOUSEWHEEL && msg != WM_MOUSEHWHEEL && !capv) - { - DWORD p=GetMessagePos(); - htc=slf->m_wndproc((HWND)slf,WM_NCHITTEST,0,p); - if (slf->m_hashaddestroy||!slf->m_wndproc) return -1; // if somehow WM_NCHITTEST destroyed us, bail - - if (htc!=HTCLIENT) - { - if (msg==WM_MOUSEMOVE) return slf->m_wndproc((HWND)slf,WM_NCMOUSEMOVE,htc,p); - if (msg==WM_LBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONUP,htc,p); - if (msg==WM_LBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONDOWN,htc,p); - if (msg==WM_LBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONDBLCLK,htc,p); - if (msg==WM_RBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONUP,htc,p); - if (msg==WM_RBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONDOWN,htc,p); - if (msg==WM_RBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONDBLCLK,htc,p); - if (msg==WM_MBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONUP,htc,p); - if (msg==WM_MBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONDOWN,htc,p); - if (msg==WM_MBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONDBLCLK,htc,p); - } - } - - int l=0; - if (msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL) - { - float dw = (msg == WM_MOUSEWHEEL ? [theEvent deltaY] : [theEvent deltaX]); - //if (!dy) dy=[theEvent deltaX]; // shift+mousewheel sends deltaX instead of deltaY - l = (int)(dw*60.0); - l <<= 16; - - // put todo: modifiers into low word of l? - - POINT p; - GetCursorPos(&p); - return slf->m_wndproc((HWND)slf,msg,l,(p.x&0xffff) + (p.y<<16)); - } - - LRESULT ret=slf->m_wndproc((HWND)slf,msg,l,(xpos&0xffff) + (ypos<<16)); - - if (msg==WM_LBUTTONUP || msg==WM_RBUTTONUP || msg==WM_MOUSEMOVE || msg==WM_MBUTTONUP) { - if (!GetCapture() && (slf->m_hashaddestroy || !slf->m_wndproc || !slf->m_wndproc((HWND)slf,WM_SETCURSOR,(WPARAM)slf,htc | (msg<<16)))) { - NSCursor *arr= [NSCursor arrowCursor]; - if (GetCursor() != (HCURSOR)arr) SetCursor((HCURSOR)arr); - } - } - return ret; -} -static LRESULT SWELL_SendMouseMessage(NSView *slf, int msg, NSEvent *event) -{ - if (!slf) return 0; - [slf retain]; - LRESULT res=SWELL_SendMouseMessageImpl((SWELL_hwndChild*)slf,msg,event); - [slf release]; - return res; -} - -void SWELL_DoDialogColorUpdates(HWND hwnd, DLGPROC d, bool isUpdate) -{ - extern HDC__ *SWELL_GDP_CTX_NEW(); - NSArray *children = [(NSView *)hwnd subviews]; - - if (!d || !children || ![children count]) return; - - int had_flags=0; - - NSColor *staticFg=NULL; // had_flags&1, WM_CTLCOLORSTATIC - NSColor *editFg=NULL, *editBg=NULL; // had_flags&2, WM_CTLCOLOREDIT - NSColor *buttonFg=NULL; // had_flags&4, WM_CTLCOLORBTN - - int x; - for (x = 0; x < [children count]; x ++) - { - NSView *ch = [children objectAtIndex:x]; - if (ch) - { - if ([ch isKindOfClass:[NSButton class]] && [(NSButton *)ch image]) - { - if (!buttonFg && !(had_flags&4)) - { - had_flags|=4; - HDC__ *c = SWELL_GDP_CTX_NEW(); - if (c) - { - d(hwnd,WM_CTLCOLORBTN,(WPARAM)c,(LPARAM)ch); - if (c->curtextcol) buttonFg=NSColorFromCol(c->cur_text_color_int); - else if (isUpdate) buttonFg = [NSColor textColor]; // todo some other col? - if (buttonFg) [buttonFg retain]; - - SWELL_DeleteGfxContext((HDC)c); - } - } - if (buttonFg) [(NSTextField*)ch setTextColor:buttonFg]; // NSButton had this added below - } - else if ([ch isKindOfClass:[NSTextField class]] || [ch isKindOfClass:[NSBox class]]) - { - bool isbox = ([ch isKindOfClass:[NSBox class]]); - if (!isbox && [(NSTextField *)ch isEditable]) - { -#if 0 // no color overrides for editable text fields - if (!editFg && !editBg && !(had_flags&2)) - { - had_flags|=2; - HDC__ *c = SWELL_GDP_CTX_NEW(); - if (c) - { - d(hwnd,WM_CTLCOLOREDIT,(WPARAM)c,(LPARAM)ch); - if (c->curtextcol) - { - editFg=NSColorFromCol(c->cur_text_color_int); - editBg=[NSColor colorWithCalibratedRed:GetRValue(c->curbkcol)/255.0f green:GetGValue(c->curbkcol)/255.0f blue:GetBValue(c->curbkcol)/255.0f alpha:1.0f]; - } - else if (isUpdate) - { - editFg = [NSColor textColor]; - editBg = [NSColor textBackgroundColor]; - } - if (editFg) [editFg retain]; - if (editBg) [editBg retain]; - SWELL_DeleteGfxContext((HDC)c); - } - } - if (editFg) [(NSTextField*)ch setTextColor:editFg]; - if (editBg) [(NSTextField*)ch setBackgroundColor:editBg]; -#endif - } - else // isbox or noneditable - { - if (!staticFg && !(had_flags&1)) - { - had_flags|=1; - HDC__ *c = SWELL_GDP_CTX_NEW(); - if (c) - { - d(hwnd,WM_CTLCOLORSTATIC,(WPARAM)c,(LPARAM)ch); - if (c->curtextcol) staticFg=NSColorFromCol(c->cur_text_color_int); - else if (isUpdate) - { - staticFg = [NSColor textColor]; - } - if (staticFg) [staticFg retain]; - SWELL_DeleteGfxContext((HDC)c); - } - } - if (staticFg) - { - if (isbox) - { - [[(NSBox*)ch titleCell] setTextColor:staticFg]; - //[(NSBox*)ch setBorderColor:staticFg]; // see comment at SWELL_MakeGroupBox - } - else - { - [(NSTextField*)ch setTextColor:staticFg]; - } - } - } // noneditable - } //nstextfield - } // child - } // children - if (buttonFg) [buttonFg release]; - if (staticFg) [staticFg release]; - if (editFg) [editFg release]; - if (editBg) [editBg release]; -} - -static LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - DLGPROC d=(DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); - if (d) - { - if (uMsg == WM_PAINT) - { - if (!d(hwnd,WM_ERASEBKGND,0,0)) - { - bool nommc=useNoMiddleManCocoa(); - NSView *cv = [[(NSView *)hwnd window] contentView]; - bool isop = [(NSView *)hwnd isOpaque] || (nommc && [cv isOpaque]); - if (isop || cv == (NSView *)hwnd) - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r=ps.rcPaint; - if (!nommc && !(((SWELL_hwndChild*)hwnd)->m_isdirty&1)) - { - NSArray *ar = [(NSView *)hwnd subviews]; - int x,n=[ar count]; - for (x=0;x=n) r.right=r.left; // disable drawing - } - - if (r.right > r.left && r.bottom > r.top) - { - HBRUSH hbrush = (HBRUSH) d(hwnd,WM_CTLCOLORDLG,(WPARAM)ps.hdc,(LPARAM)hwnd); - if (hbrush && hbrush != (HBRUSH)1) - { - // char bf[512]; - // GetWindowText(hwnd,bf,sizeof(bf)); -// static int a; - // printf("%d filled custom bg, (%p %s) %d %d %d %d\n",a++,hwnd,bf,r.left,r.top,r.right-r.left,r.bottom-r.top); - FillRect(ps.hdc,&r,hbrush); - } - else if (isop) // no need to do this fill if it is a content view and is not opaque - { - // char bf[512]; - // GetWindowText(hwnd,bf,sizeof(bf)); - // static int a; - // printf("%d: filled stock bg, (%p %s) %d %d %d %d\n",a++,hwnd,bf,r.left,r.top,r.right-r.left,r.bottom-r.top); - SWELL_FillDialogBackground(ps.hdc,&r,3); - } - } - EndPaint(hwnd,&ps); - } - } - } - } - - LRESULT r=(LRESULT) d(hwnd,uMsg,wParam,lParam); - - if (r) return r; - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - -static SWELL_DialogResourceIndex *resById(SWELL_DialogResourceIndex *reshead, const char *resid) -{ - SWELL_DialogResourceIndex *p=reshead; - while (p) - { - if (p->resid == resid) return p; - p=p->_next; - } - return 0; -} - -static void DoPaintStuff(WNDPROC wndproc, HWND hwnd, HDC hdc, NSRect *modrect) -{ - RECT r,r2; - GetWindowRect(hwnd,&r); - if (r.top>r.bottom) { int tmp=r.top; r.top=r.bottom; r.bottom=tmp; } - r2=r; - wndproc(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&r); - wndproc(hwnd,WM_NCPAINT,(WPARAM)1,0); - modrect->origin.x += r.left-r2.left; - modrect->origin.y += r.top-r2.top; - - if (modrect->size.width >= 1 && modrect->size.height >= 1) - { - int a=0; - if (memcmp(&r,&r2,sizeof(r))) - { - RECT tr; - SWELL_PushClipRegion(hdc); - GetClientRect(hwnd,&tr); - SWELL_SetClipRegion(hdc,&tr); - a++; - } - wndproc(hwnd,WM_PAINT,(WPARAM)hdc,0); - if (a) SWELL_PopClipRegion(hdc); - } -} - - -static int DelegateMouseMove(NSView *view, NSEvent *theEvent) -{ - static int __nofwd; - if (__nofwd) return 0; - - NSWindow *w=[theEvent window]; - if (!w) return 0; - - NSPoint p=[theEvent locationInWindow]; - NSPoint screen_p=[w convertBaseToScreen:p]; - - NSWindow *bestwnd = w; - HWND cap = GetCapture(); - if (!cap) - { - // if not captured, find the window that should receive this event - - NSArray *windows=[NSApp orderedWindows]; - int x,cnt=windows ? [windows count] : 0; - NSWindow *kw = [NSApp keyWindow]; - if (kw && windows && [windows containsObject:kw]) kw=NULL; - // make sure the keywindow, if any, is checked, but not twice - - for (x = kw ? -1 : 0; x < cnt; x ++) - { - NSWindow *wnd = x < 0 ? kw : [windows objectAtIndex:x]; - if (wnd && [wnd isVisible]) - { - NSRect fr=[wnd frame]; - if (screen_p.x >= fr.origin.x && screen_p.x < fr.origin.x + fr.size.width && - screen_p.y >= fr.origin.y && screen_p.y < fr.origin.y + fr.size.height) - { - bestwnd=wnd; - break; - } - } - } - } - - if (bestwnd == w || [NSApp modalWindow]) - { - NSView *v=[[w contentView] hitTest:p]; - if (!v || v == view) return 0; // default processing if in view, or if in nonclient area - - __nofwd=1; - [v mouseMoved:theEvent]; - __nofwd=0; - return 1; - } - - // bestwnd != w - NSView *cv = [bestwnd contentView]; - if (cv && [cv isKindOfClass:[SWELL_hwndChild class]]) - { - p = [bestwnd convertScreenToBase:screen_p]; - NSView *v=[cv hitTest:p]; - if (v) - { - theEvent = [NSEvent mouseEventWithType:[theEvent type] - location:p - modifierFlags:[theEvent modifierFlags] - timestamp:[theEvent timestamp] - windowNumber:[bestwnd windowNumber] - context:[bestwnd graphicsContext] - eventNumber:[theEvent eventNumber] - clickCount:[theEvent clickCount] - pressure:[theEvent pressure]]; - __nofwd=1; - [v mouseMoved:theEvent]; - __nofwd=0; - return 1; - } - } - if (!cap) - { - // set default cursor, and eat message - NSCursor *arr= [NSCursor arrowCursor]; - if (GetCursor() != (HCURSOR)arr) SetCursor((HCURSOR)arr); - return 1; - } - return 0; -} - - - - -@implementation SWELL_hwndChild : NSView - --(void)viewDidHide -{ - SendMessage((HWND)self, WM_SHOWWINDOW, FALSE, 0); -} --(void) viewDidUnhide -{ - SendMessage((HWND)self, WM_SHOWWINDOW, TRUE, 0); -} - -- (void)SWELL_Timer:(id)sender -{ - extern HWND g_swell_only_timerhwnd; - if (g_swell_only_timerhwnd && (HWND)self != g_swell_only_timerhwnd) return; - - id uinfo=[sender userInfo]; - if ([uinfo respondsToSelector:@selector(getValue)]) - { - WPARAM idx=(WPARAM)[(SWELL_DataHold*)uinfo getValue]; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_TIMER,idx,0); - } -} - -- (int)swellCapChangeNotify { return YES; } - -- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam -{ - if (m_hashaddestroy) - { - if (m_hashaddestroy==2 || msg == WM_DESTROY || msg == WM_CAPTURECHANGED) return 0; - } - - - if (msg==WM_DESTROY) // only ever called once per window - { - m_hashaddestroy=1; - if (GetCapture()==(HWND)self) ReleaseCapture(); - SWELL_MessageQueue_Clear((HWND)self); - - LRESULT ret=m_wndproc ? m_wndproc((HWND)self,msg,wParam,lParam) : 0; - - if ([[self window] contentView] == self && [[self window] respondsToSelector:@selector(swellDestroyAllOwnedWindows)]) - [(SWELL_ModelessWindow*)[self window] swellDestroyAllOwnedWindows]; - - if (GetCapture()==(HWND)self) ReleaseCapture(); - SWELL_MessageQueue_Clear((HWND)self); - - if (m_menu) - { - if ((HMENU)[NSApp mainMenu] == m_menu && !g_swell_terminating) [NSApp setMainMenu:nil]; - SWELL_SetMenuDestination(m_menu,NULL); - [(NSMenu *)m_menu release]; - m_menu=0; - } - NSView *v=self; - NSArray *ar; - if (v && [v isKindOfClass:[NSView class]] && (ar=[v subviews]) && [ar count]>0) - { - int x; - for (x = 0; x < [ar count]; x ++) - { - NSView *sv=[ar objectAtIndex:x]; - sendSwellMessage(sv,WM_DESTROY,0,0); - } - } - KillTimer((HWND)self,~(UINT_PTR)0); - m_hashaddestroy=2; - - return ret; - } - - return m_wndproc ? m_wndproc((HWND)self,msg,wParam,lParam) : 0; -} - -- (void) setEnabled:(BOOL)en -{ - m_enabled=en; -} - -- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex -{ - if ([aTableView isKindOfClass:[SWELL_ListView class]]) - { - SWELL_ListView *f = (SWELL_ListView *)aTableView; - if (f->m_selColors&&[aTableView isRowSelected:rowIndex]) - { - int cnt = [f->m_selColors count]; - int offs = GetFocus() == (HWND)aTableView ? 0 : 2; - if (cnt>=offs+2) - { - if ([aCell respondsToSelector:@selector(setTextColor:)]) [aCell setTextColor:[f->m_selColors objectAtIndex:(offs+1)]]; - return; - } - } - - if (f->m_fgColor && [aCell respondsToSelector:@selector(setTextColor:)]) [aCell setTextColor:f->m_fgColor]; - } -} -- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item -{ - if ([outlineView isKindOfClass:[SWELL_TreeView class]]) - { - SWELL_TreeView *f = (SWELL_TreeView *)outlineView; - if (f->m_selColors) - { - HTREEITEM sel = TreeView_GetSelection((HWND)outlineView); - if (sel && sel->m_dh == item) - { - int cnt = [f->m_selColors count]; - int offs = GetFocus() == (HWND)outlineView ? 0 : 2; - if (cnt>=offs+2) - { - if ([cell respondsToSelector:@selector(setTextColor:)]) [cell setTextColor:[f->m_selColors objectAtIndex:(offs+1)]]; - return; - } - } - } - if (f->m_fgColor && [cell respondsToSelector:@selector(setTextColor:)]) [cell setTextColor:f->m_fgColor]; - } -} - - -//- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item - -- (void)comboBoxWillPopUp:(NSNotification*)notification -{ - id sender=[notification object]; - int code=CBN_DROPDOWN; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); -} - -- (void)comboBoxSelectionDidChange:(NSNotification *)notification -{ - id sender=[notification object]; - int code=CBN_SELCHANGE; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); -} - -- (void)textDidEndEditing:(NSNotification *)aNotification -{ - id sender=[aNotification object]; - int code=EN_CHANGE; - if ([sender isKindOfClass:[NSComboBox class]]) return; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); -} - -- (void)controlTextDidChange:(NSNotification *)aNotification -{ - id sender=[aNotification object]; - int code=EN_CHANGE; - if ([sender isKindOfClass:[NSComboBox class]]) code=CBN_EDITCHANGE; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); -} - -- (void)menuNeedsUpdate:(NSMenu *)menu -{ - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_INITMENUPOPUP,(WPARAM)menu,0); -} - --(void) swellOnControlDoubleClick:(id)sender -{ - if (!m_wndproc||m_hashaddestroy) return; - - if ([sender isKindOfClass:[NSTableView class]] && - [sender respondsToSelector:@selector(getSwellNotificationMode)]) - { - if ([(SWELL_ListView*)sender getSwellNotificationMode]) - m_wndproc((HWND)self,WM_COMMAND,(LBN_DBLCLK<<16)|[(NSControl*)sender tag],(LPARAM)sender); - else - { - SWELL_ListView* v = (SWELL_ListView*)sender; - NMLISTVIEW nmlv={{(HWND)sender,[(NSControl*)sender tag], NM_DBLCLK}, [v clickedRow], [sender clickedColumn], }; - SWELL_ListView_Row *row=v->m_items->Get(nmlv.iItem); - if (row) - nmlv.lParam = row->m_param; - m_wndproc((HWND)self,WM_NOTIFY,[(NSControl*)sender tag],(LPARAM)&nmlv); - } - } - else - { - NMCLICK nm={{(HWND)sender,[(NSControl*)sender tag],NM_DBLCLK}, }; - m_wndproc((HWND)self,WM_NOTIFY,[(NSControl*)sender tag],(LPARAM)&nm); - } -} - -- (void)outlineViewSelectionDidChange:(NSNotification *)notification -{ - NSOutlineView *sender=[notification object]; - NMTREEVIEW nmhdr={{(HWND)sender,(int)[sender tag],TVN_SELCHANGED},0,}; // todo: better treeview notifications - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); -} -- (void)tableViewSelectionDidChange:(NSNotification *)aNotification -{ - NSTableView *sender=[aNotification object]; - if ([sender respondsToSelector:@selector(getSwellNotificationMode)] && [(SWELL_ListView*)sender getSwellNotificationMode]) - { - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,(int)[sender tag] | (LBN_SELCHANGE<<16),(LPARAM)sender); - } - else - { - NMLISTVIEW nmhdr={{(HWND)sender,(int)[sender tag],LVN_ITEMCHANGED},(int)[sender selectedRow],0}; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); - - } -} - -- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn -{ - if ([tableView isKindOfClass:[SWELL_ListView class]] && - ((SWELL_ListView *)tableView)->m_cols && - !((SWELL_ListView *)tableView)->m_lbMode && - !(((SWELL_ListView *)tableView)->style & LVS_NOSORTHEADER) - ) - { - int col=((SWELL_ListView *)tableView)->m_cols->Find(tableColumn); - - NMLISTVIEW hdr={{(HWND)tableView,[tableView tag],LVN_COLUMNCLICK},-1,col}; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,[tableView tag], (LPARAM) &hdr); - } -} - --(void) onSwellCommand:(id)sender -{ - if (!m_wndproc || m_hashaddestroy) return; - - if ([sender isKindOfClass:[NSSlider class]]) - { - m_wndproc((HWND)self,WM_HSCROLL,0,(LPARAM)sender); - // WM_HSCROLL, WM_VSCROLL - } - else if ([sender isKindOfClass:[NSTableView class]]) - { - #if 0 - if ([sender isKindOfClass:[NSOutlineView class]]) - { -// NMTREEVIEW nmhdr={{(HWND)sender,(int)[sender tag],TVN_SELCHANGED},0,}; // todo: better treeview notifications - // m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); - } - else - { - - if ([sender respondsToSelector:@selector(getSwellNotificationMode)] && [(SWELL_ListView*)sender getSwellNotificationMode]) - { - m_wndproc((HWND)self,WM_COMMAND,(int)[sender tag] | (LBN_SELCHANGE<<16),(LPARAM)sender); - } - else - { - NMLISTVIEW nmhdr={{(HWND)sender,(int)[sender tag],LVN_ITEMCHANGED},(int)[sender clickedRow],0}; - m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); - } - } - #endif - } - else - { - int cw=0; - if ([sender isKindOfClass:[NSComboBox class]]) return; // combo boxes will use delegate messages - else if ([sender isKindOfClass:[NSPopUpButton class]]) - { - cw=CBN_SELCHANGE; - } - else if ([sender isKindOfClass:[SWELL_Button class]]) - { - int rf; - if ((rf=(int)[(SWELL_Button*)sender swellGetRadioFlags])) - { - NSView *par=(NSView *)GetParent((HWND)sender); - if (par && [par isKindOfClass:[NSWindow class]]) par=[(NSWindow *)par contentView]; - if (par && [par isKindOfClass:[NSView class]]) - { - NSArray *ar=[par subviews]; - if (ar) - { - NSInteger x=[ar indexOfObject:sender]; - if (x != NSNotFound) - { - int n=[ar count]; - int a=x; - if (!(rf&2)) while (--a >= 0) - { - NSView *item=[ar objectAtIndex:a]; - if (!item || ![item isKindOfClass:[SWELL_Button class]]) break; // we may want to allow other controls in there, but for now if it's non-button we're done - int bla=(int)[(SWELL_Button*)item swellGetRadioFlags]; - if (bla&1) if ([(NSButton *)item state]!=NSOffState) [(NSButton *)item setState:NSOffState]; - if (bla&2) break; - } - a=x; - while (++a < n) - { - NSView *item=[ar objectAtIndex:a]; - if (!item || ![item isKindOfClass:[SWELL_Button class]]) break; // we may want to allow other controls in there, but for now if it's non-button we're done - int bla=(int)[(SWELL_Button*)item swellGetRadioFlags]; - if (bla&2) break; - if (bla&1) if ([(NSButton *)item state]!=NSOffState) [(NSButton *)item setState:NSOffState]; - } - } - } - } - } - } - else if ([sender isKindOfClass:[NSControl class]]) - { - NSEvent *evt=[NSApp currentEvent]; - int ty=evt?[evt type]:0; - if (evt && (ty==NSLeftMouseDown || ty==NSLeftMouseUp) && [evt clickCount] > 1) cw=STN_DBLCLK; - } - else if ([sender isKindOfClass:[NSMenuItem class]]) - { -// [[sender menu] update]; - // wish we could force the top level menu to update here, meh - } - m_wndproc((HWND)self,WM_COMMAND,[sender tag]|(cw<<16),(LPARAM)sender); - } - -} --(void) dealloc -{ - - int x; - for (x=0;x=0&&idx=0&&idxhdc = m_paintctx_hdc; - ps->fErase=false; - ps->rcPaint.left = (int)m_paintctx_rect.origin.x; - ps->rcPaint.right = (int)ceil(m_paintctx_rect.origin.x+m_paintctx_rect.size.width); - ps->rcPaint.top = (int)m_paintctx_rect.origin.y; - ps->rcPaint.bottom = (int)ceil(m_paintctx_rect.origin.y+m_paintctx_rect.size.height); - } -} - --(bool)swellCanPostMessage { return !m_hashaddestroy; } --(int)swellEnumProps:(PROPENUMPROCEX)proc lp:(LPARAM)lParam -{ - WindowPropRec *p=m_props; - if (!p) return -1; - while (p) - { - WindowPropRec *ps=p; - p=p->_next; - if (!proc((HWND)self, ps->name, ps->data, lParam)) return 0; - } - return 1; -} - --(void *)swellGetProp:(const char *)name wantRemove:(BOOL)rem -{ - WindowPropRec *p=m_props, *lp=NULL; - while (p) - { - if (p->name < (void *)65536) - { - if (name==p->name) break; - } - else if (name >= (void *)65536) - { - if (!strcmp(name,p->name)) break; - } - lp=p; p=p->_next; - } - if (!p) return NULL; - void *ret=p->data; - if (rem) - { - if (lp) lp->_next=p->_next; else m_props=p->_next; - free(p); - } - return ret; -} - --(int)swellSetProp:(const char *)name value:(void *)val -{ - WindowPropRec *p=m_props; - while (p) - { - if (p->name < (void *)65536) - { - if (name==p->name) { p->data=val; return TRUE; }; - } - else if (name >= (void *)65536) - { - if (!strcmp(name,p->name)) { p->data=val; return TRUE; }; - } - p=p->_next; - } - p=(WindowPropRec*)malloc(sizeof(WindowPropRec)); - p->name = (name<(void*)65536) ? (char *)name : strdup(name); - p->data = val; p->_next=m_props; m_props=p; - return TRUE; -} - -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent -{ - if (m_enabled) - { - SendMessage((HWND)self, WM_MOUSEACTIVATE, 0, 0); - NSView* par=[self superview]; - if (par) SendMessage((HWND)par, WM_MOUSEACTIVATE, 0, 0); - return YES; - } - return NO; -} - --(HMENU)swellGetMenu { return m_menu; } --(BOOL)swellHasBeenDestroyed { return !!m_hashaddestroy; } --(void)swellSetMenu:(HMENU)menu { - if (m_menu) SWELL_SetMenuDestination(m_menu,NULL); // don't free m_menu, but at least make it not point to us anymore - m_menu=menu; - if (m_menu) SWELL_SetMenuDestination(m_menu,(HWND)self); -} - - -- (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par -{ - NSRect contentRect=NSMakeRect(0,0,resstate ? resstate->width : 300,resstate ? resstate->height : 200); - if (!(self = [super initWithFrame:contentRect])) return self; - - memset(m_access_cacheptrs,0,sizeof(m_access_cacheptrs)); - m_isdirty=3; - m_glctx=NULL; - m_enabled=TRUE; - m_lastTopLevelOwner=NULL; - m_dlgproc=NULL; - m_wndproc=NULL; - m_userdata=0; - memset(&m_extradata,0,sizeof(m_extradata)); - m_tag=0; - m_isfakerightmouse=0; - m_hashaddestroy=false; - m_menu=0; - m_flip=0; - m_supports_ddrop=0; - m_paintctx_used=0; - m_paintctx_hdc=0; - m_props=0; - - m_titlestr[0]=0; - - m_wndproc=SwellDialogDefaultWindowProc; - - m_isopaque = !resstate || (resstate->windowTypeFlags&SWELL_DLG_WS_OPAQUE); - m_flip = !resstate || (resstate->windowTypeFlags&SWELL_DLG_WS_FLIPPED); - m_supports_ddrop = resstate && (resstate->windowTypeFlags&SWELL_DLG_WS_DROPTARGET); - - [self setHidden:YES]; - -// BOOL wasHid=[self isHidden]; - //if (!wasHid) [self setHidden:YES]; - - bool isChild=false; - - if ([parent isKindOfClass:[NSSavePanel class]]||[parent isKindOfClass:[NSOpenPanel class]]) - { - [(NSSavePanel *)parent setAccessoryView:self]; - [self setHidden:NO]; - } - else if ([parent isKindOfClass:[NSColorPanel class]]) - { - [(NSColorPanel *)parent setAccessoryView:self]; - [self setHidden:NO]; - } - else if ([parent isKindOfClass:[NSFontPanel class]]) - { - [(NSFontPanel *)parent setAccessoryView:self]; - [self setHidden:NO]; - } - else if ([parent isKindOfClass:[NSWindow class]]) - { - [(NSWindow *)parent setContentView:self]; - } - else - { - isChild=[parent isKindOfClass:[NSView class]]; - [parent addSubview:self]; - } - if (resstate) resstate->createFunc((HWND)self,resstate->windowTypeFlags); - - if (resstate) m_dlgproc=dlgproc; - else if (dlgproc) m_wndproc=(WNDPROC)dlgproc; - - if (resstate && (resstate->windowTypeFlags&SWELL_DLG_WS_DROPTARGET)) - { - [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSFilesPromisePboardType, nil]]; - } - - if (!resstate) - m_wndproc((HWND)self,WM_CREATE,0,par); - - if (m_dlgproc) - { - HWND hFoc=0; - NSArray *ar=[self subviews]; - if (ar && [ar count]>0) - { - int x; - for (x = 0; x < [ar count] && !hFoc; x ++) - { - NSView *v=[ar objectAtIndex:x]; - if (v && [v isKindOfClass:[NSScrollView class]]) v=[(NSScrollView *)v documentView]; - if (v && [v acceptsFirstResponder]) hFoc=(HWND)v; - } - } - - INT_PTR a; - if ((a=m_dlgproc((HWND)self,WM_INITDIALOG,(WPARAM)hFoc,par))) - { - // set first responder to first item in window - if (a == 0xbeef) hFoc = (HWND)self; // ret 0xbeef overrides to make the window itself focused (argh, need a cleaner way) - if (hFoc) - { - id wnd = [self window]; - if (wnd && [wnd firstResponder] != (id)hFoc) [wnd makeFirstResponder:(id)hFoc]; - } - - - if (parent && [self window] == (NSWindow *)parent && [(id)parent isKindOfClass:[SWELL_ModelessWindow class]] && ![(NSWindow *)parent isVisible]) - { - // on win32, if you do CreateDialog(), WM_INITDIALOG(ret=1), then ShowWindow(SW_SHOWNA), you get the - // window brought to front. this simulates that, hackishly. - ((SWELL_ModelessWindow *)parent)->m_wantInitialKeyWindowOnShow = true; - } - } - else - { - // if top level dialog,always set default focus if it wasn't set - // if this causes problems, change NSWindow to be SWELL_ModalDialog, as that would - // only affect DialogBox() and not CreateDialog(), which might be preferable. - if (hFoc && parent && [self window] == (NSWindow *)parent && [(id)parent isKindOfClass:[NSWindow class]]) - { - id fr = [(NSWindow *)parent firstResponder]; - if (!fr || fr == self || fr == (id)parent) [(NSWindow *)parent makeFirstResponder:(id)hFoc]; - - } - } - - SWELL_DoDialogColorUpdates((HWND)self,m_dlgproc,false); - } - -// if (!wasHid) - // [self setHidden:NO]; - - return self; -} - --(void)setOpaque:(bool)isOpaque -{ - m_isopaque = isOpaque; -} - --(BOOL)isOpaque -{ - return m_isopaque; -} - -- (void)setFrame:(NSRect)frameRect -{ - [super setFrame:frameRect]; - if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_SIZE,0,0); - InvalidateRect(GetParent((HWND)self),NULL,FALSE); -} - -- (void)keyDown:(NSEvent *)theEvent -{ - int flag,code=SWELL_MacKeyToWindowsKey(theEvent,&flag); - if (!m_wndproc || m_hashaddestroy || m_wndproc((HWND)self,WM_KEYDOWN,code,flag)==69) - { - [super keyDown:theEvent]; - } -} - -- (void)keyUp:(NSEvent *)theEvent -{ - int flag,code=SWELL_MacKeyToWindowsKey(theEvent,&flag); - if (!m_wndproc || m_hashaddestroy || m_wndproc((HWND)self,WM_KEYUP,code,flag)==69) - { - [super keyUp:theEvent]; - } -} - -#if SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN > 0 // not done yet - -- (void)didAddSubview:(NSView *)subview -{ - m_isdirty|=2; - NSView *view = [self superview]; - while (view) - { - if ([view isKindOfClass:[SWELL_hwndChild class]]) - { - if (((SWELL_hwndChild *)view)->m_isdirty&2) break; - ((SWELL_hwndChild *)view)->m_isdirty|=2; - } - view = [view superview]; - } -} -- (void)willRemoveSubview:(NSView *)subview -{ - m_isdirty|=3; - [self setNeedsDisplay:YES]; - NSView *view = [self superview]; - while (view) - { - if ([view isKindOfClass:[SWELL_hwndChild class]]) - { - if ((((SWELL_hwndChild *)view)->m_isdirty&3)==3) break; - ((SWELL_hwndChild *)view)->m_isdirty|=3; - } - [view setNeedsDisplay:YES]; - view = [view superview]; - } -} - --(void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)vr rectIsVisibleRectForView:(NSView*)v topView:(NSView *)v2 -{ - - - - // once we figure out how to get other controls to notify their parents that the view is dirty, we can enable this for 10.4 - // 10.5+ has some nice property where it goes up the hierarchy - -// NSLog(@"r:%@ vr:%d v=%p tv=%p self=%p %p\n",NSStringFromRect(rect),vr,v,v2,self, [[self window] contentView]); - if (!useNoMiddleManCocoa() || ![self isOpaque] || [[self window] contentView] != self || [self isHiddenOrHasHiddenAncestor]) - { - [super _recursiveDisplayRectIfNeededIgnoringOpacity:rect isVisibleRect:vr rectIsVisibleRectForView:v topView:v2]; - return; - } - - if (!m_isdirty && ![self needsDisplay]) return; - - const NSRect *rlist=NULL; - NSInteger rlistcnt=0; - [self getRectsBeingDrawn:&rlist count:&rlistcnt]; - - - [self lockFocus]; - HDC hdc=SWELL_CreateGfxContext([NSGraphicsContext currentContext]); - - - const bool twoPassMode = false; // true makes it draw non-opaque items over all window backgrounds, but opaque children going last (so native controls over groups, etc) - // this is probably slower - - static WDL_PtrList ndlist; - int ndlist_oldsz=ndlist.GetSize(); - swellRenderOptimizely(twoPassMode?1:3,self,hdc,false,&ndlist,rlist,rlistcnt,0,0,true); - - while (ndlist.GetSize()>ndlist_oldsz+1) - { - NSView *v = (NSView *)ndlist.Get(ndlist.GetSize()-1); - ndlist.Delete(ndlist.GetSize()-1); - - int flag = (int)(INT_PTR) ndlist.Get(ndlist.GetSize()-1); - ndlist.Delete(ndlist.GetSize()-1); - - NSRect b = [v bounds]; - - if (rlistcnt && !(flag&1)) - { - int x; - for(x=0;x0 && r.size.height>0) - [v displayRectIgnoringOpacity:r]; - } - } - else - [v displayRectIgnoringOpacity:b]; - [v setNeedsDisplay:NO]; - [v release]; - } - - - if (twoPassMode) swellRenderOptimizely(2,self,hdc,false,&ndlist,rlist,rlistcnt,0,0,true); - SWELL_DeleteGfxContext(hdc); - [self unlockFocus]; - [self setNeedsDisplay:NO]; - -} -#endif - --(void) drawRect:(NSRect)rect -{ - HDC hdc=SWELL_CreateGfxContext([NSGraphicsContext currentContext]); - DrawSwellViewRectImpl(self,rect,hdc); - SWELL_DeleteGfxContext(hdc); - m_isdirty=0; - -} - -- (void)rightMouseDragged:(NSEvent *)theEvent -{ - if (!m_enabled) return; - [self mouseDragged:theEvent]; -} -- (void)otherMouseDragged:(NSEvent *)theEvent -{ - if (!m_enabled) return; - [self mouseDragged:theEvent]; -} - -- (void)mouseDragged:(NSEvent *)theEvent -{ - if (!m_enabled) return; - - SWELL_SendMouseMessage(self,WM_MOUSEMOVE,theEvent); - if (SWELL_GetLastSetCursor()!=GetCursor()) SetCursor(SWELL_GetLastSetCursor()); -} -- (void)mouseMoved:(NSEvent *)theEvent -{ - if (DelegateMouseMove(self,theEvent)) return; - - if (m_enabled) if (!GetCapture() || GetCapture()==(HWND)self) { - SWELL_SendMouseMessage(self,WM_MOUSEMOVE, theEvent); - } -// [super mouseMoved:theEvent]; -} -- (void)mouseUp:(NSEvent *)theEvent -{ - if (!m_enabled) return; - if (m_isfakerightmouse) [self rightMouseUp:theEvent]; - else SWELL_SendMouseMessage(self,WM_LBUTTONUP,theEvent); -} -- (void)scrollWheel:(NSEvent *)theEvent -{ - if (!m_enabled) return; - if ([theEvent deltaY] != 0.0f) - { - SWELL_SendMouseMessage(self,WM_MOUSEWHEEL,theEvent); - } - if ([theEvent deltaX] != 0.0f) - { - SWELL_SendMouseMessage(self,WM_MOUSEHWHEEL,theEvent); - } -} -- (void)mouseDown:(NSEvent *)theEvent -{ - SWELL_FinishDragDrop(); - if (!m_enabled) return; - - m_isfakerightmouse=0; - if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) - { - [self rightMouseDown:theEvent]; - if ([theEvent clickCount]<2) m_isfakerightmouse=1; - return; - } - - SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_LBUTTONDBLCLK : WM_LBUTTONDOWN) ,theEvent); -} -- (void)rightMouseUp:(NSEvent *)theEvent -{ - if (!m_enabled) return; - m_isfakerightmouse=0; - SWELL_SendMouseMessage(self,WM_RBUTTONUP,theEvent); -} -- (void)rightMouseDown:(NSEvent *)theEvent -{ - m_isfakerightmouse=0; - if ([NSApp keyWindow] != [self window]) - { - SetFocus((HWND)[self window]); - } - SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_RBUTTONDBLCLK : WM_RBUTTONDOWN),theEvent); -} -- (void)otherMouseUp:(NSEvent *)theEvent -{ - if (!m_enabled) return; - SWELL_SendMouseMessage(self,WM_MBUTTONUP,theEvent); -} -- (void)otherMouseDown:(NSEvent *)theEvent -{ - if ([NSApp keyWindow] != [self window]) - { - SetFocus((HWND)[self window]); - } - SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_MBUTTONDBLCLK : WM_MBUTTONDOWN),theEvent); -} - -// multitouch support - -static void MakeGestureInfo(NSEvent* evt, GESTUREINFO* gi, HWND hwnd, int type) -{ - memset(gi, 0, sizeof(GESTUREINFO)); - gi->cbSize = sizeof(GESTUREINFO); - - gi->hwndTarget = hwnd; - gi->dwID = type; - - NSWindow* wnd = [evt window]; - NSPoint pt = [evt locationInWindow]; - pt = [wnd convertBaseToScreen:pt]; - gi->ptsLocation.x = pt.x; - gi->ptsLocation.y = pt.y; -} - -- (void)magnifyWithEvent:(NSEvent*)evt -{ - GESTUREINFO gi; - MakeGestureInfo(evt, &gi, (HWND) self, GID_ZOOM); - - gi.dwFlags = GF_BEGIN; - gi.ullArguments = 1024; // arbitrary - SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); - - gi.dwFlags = GF_END; - float z = [evt deltaZ]; // should be the same as 10.6 [evt magnification] - int a = (int)(1024.0f*z+0.5); - if (!a) a = (z >= 0.0f ? 1 : -1); - a += 1024; - if (a < 512) a=512; - else if (a > 2048) a=2048; - gi.ullArguments = a; - SendMessage((HWND)self, WM_GESTURE, gi.ullArguments, (LPARAM)&gi); -} - -- (void)swipeWithEvent:(NSEvent*)evt -{ - GESTUREINFO gi; - MakeGestureInfo(evt, &gi, (HWND) self, GID_PAN); - - gi.dwFlags = GF_BEGIN; - gi.ullArguments = 0; // for this gesture we only care about ptsLocation - SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); - - gi.dwFlags = GF_END; - NSRect r = [self bounds]; - int dx=0; - int dy=0; - - // for swipe events, deltaX/Y is either -1 or +1, convert to "one page" - if ([evt deltaX] < 0.0f) dx = -r.size.width; - else if ([evt deltaX] > 0.0f) dx = r.size.width; - else if ([evt deltaY] < 0.0f) dy = r.size.height; - else if ([evt deltaY] > 0.0f) dy = -r.size.height; - - gi.ptsLocation.x += dx; - gi.ptsLocation.y += dy; - - SendMessage((HWND)self, WM_GESTURE, gi.ullArguments, (LPARAM)&gi); -} - --(void) rotateWithEvent:(NSEvent*)evt -{ - GESTUREINFO gi; - MakeGestureInfo(evt, &gi, (HWND) self, GID_ROTATE); - - gi.dwFlags = GF_BEGIN; - gi.ullArguments = 0; // Windows sends the absolute starting rotation as the first message, Mac doesn't - SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); - - gi.dwFlags = GF_END; - float z = [evt rotation]; - int i = (int)32767.0f*z/60.0f; - if (!i) i = (z >= 0.0f ? 1 : -1); - i += 32767; - if (i < 0) i=0; - else if (i > 65535) i=65535; - gi.ullArguments = i; - SendMessage((HWND)self, WM_GESTURE, i, (LPARAM)&gi); -} - - -- (const char *)onSwellGetText { return m_titlestr; } --(void)onSwellSetText:(const char *)buf { lstrcpyn(m_titlestr,buf,sizeof(m_titlestr)); } - - -// source-side drag/drop, only does something if source called SWELL_InitiateDragDrop while handling mouseDown -- (NSArray*) namesOfPromisedFilesDroppedAtDestination:(NSURL*) dropdestination -{ - NSArray* SWELL_DoDragDrop(NSURL*); - return SWELL_DoDragDrop(dropdestination); -} - - -/* -- (BOOL)becomeFirstResponder -{ - if (!m_enabled) return NO; - HWND foc=GetFocus(); - if (![super becomeFirstResponder]) return NO; - [self onSwellMessage:WM_ACTIVATE p1:WA_ACTIVE p2:(LPARAM)foc]; - return YES; -} - -- (BOOL)resignFirstResponder -{ - HWND foc=GetFocus(); - if (![super resignFirstResponder]) return NO; - [self onSwellMessage:WM_ACTIVATE p1:WA_INACTIVE p2:(LPARAM)foc]; - return YES; -} -*/ - -- (BOOL)acceptsFirstResponder -{ - if (m_enabled) - { - if (GetFocus() != (HWND)self) - { - SendMessage((HWND)self, WM_MOUSEACTIVATE, 0, 0); - } - return YES; - } - return NO; -} - --(void)swellSetExtendedStyle:(LONG)st -{ - if (st&WS_EX_ACCEPTFILES) m_supports_ddrop=true; - else m_supports_ddrop=false; -} --(LONG)swellGetExtendedStyle -{ - LONG ret=0; - if (m_supports_ddrop) ret|=WS_EX_ACCEPTFILES; - return ret; -} - -- (NSDragOperation)draggingEntered:(id )sender -{ - if (!m_supports_ddrop) return NSDragOperationNone; - - if (SWELL_DDrop_onDragEnter) - { - HANDLE h = (HANDLE)[self swellExtendedDragOp:sender retGlob:YES]; - if (h) - { - NSPoint p=[[self window] convertBaseToScreen:[sender draggingLocation]]; - POINT pt={(int)(p.x+0.5),(int)(p.y+0.5)}; - SWELL_DDrop_onDragEnter(h,pt); - GlobalFree(h); - } - } - - return NSDragOperationGeneric; -} -- (BOOL) wantsPeriodicDraggingUpdates -{ - return NO; -} -- (NSDragOperation)draggingUpdated:(id )sender -{ - if (!m_supports_ddrop) return NSDragOperationNone; - - if (SWELL_DDrop_onDragOver) - { - NSPoint p=[[self window] convertBaseToScreen:[sender draggingLocation]]; - POINT pt={(int)(p.x+0.5),(int)(p.y+0.5)}; - SWELL_DDrop_onDragOver(pt); - } - - return NSDragOperationGeneric; - -} -- (void)draggingExited:(id )sender -{ - if (m_supports_ddrop && SWELL_DDrop_onDragLeave) SWELL_DDrop_onDragLeave(); -} - --(HANDLE)swellExtendedDragOp:(id )sender retGlob:(BOOL)retG -{ - if (!m_supports_ddrop) return 0; - - NSPasteboard *pboard; - NSDragOperation sourceDragMask; - sourceDragMask = [sender draggingSourceOperationMask]; - pboard = [sender draggingPasteboard]; - - enum { PB_FILEREF=1, PB_FILEPROMISE }; - int pbtype = 0; - if ([[pboard types] containsObject:NSFilenamesPboardType]) pbtype |= PB_FILEREF; - if ([[pboard types] containsObject:NSFilesPromisePboardType]) pbtype |= PB_FILEPROMISE; - if (!pbtype) return 0; - - int sz=sizeof(DROPFILES); - - bool maketmpfn = false; - NSArray *files = 0; - if (pbtype&PB_FILEREF) - { - files = [pboard propertyListForType:NSFilenamesPboardType]; - } - else if (pbtype&PB_FILEPROMISE) - { - NSArray* exts = [pboard propertyListForType:NSFilesPromisePboardType]; // just the file extensions - if (retG) - { - files = exts; - maketmpfn = true; - } - else if (SWELL_DDrop_getDroppedFileTargetPath) - { - char ext[256]; - ext[0] = 0; - if ([exts objectAtIndex:0]) SWELL_CFStringToCString([exts objectAtIndex:0], ext, sizeof(ext)); - - const char* droppath = SWELL_DDrop_getDroppedFileTargetPath(ext); - if (!droppath || !droppath[0]) droppath = "/tmp/"; - NSString* pathstr = (NSString*)SWELL_CStringToCFString(droppath); - NSURL* dest = [NSURL fileURLWithPath:pathstr]; - - files = [sender namesOfPromisedFilesDroppedAtDestination:dest]; // tells the drag source to create the files - - if ([files count]) - { - NSMutableArray* paths=[NSMutableArray arrayWithCapacity:[files count]]; - int i; - for (i=0; i < [files count]; ++i) - { - NSString* fn=[files objectAtIndex:i]; - if (fn) - { - [paths addObject:[pathstr stringByAppendingPathComponent:fn]]; - } - } - files=paths; - } - - [pathstr release]; - } - } - if (!files) return 0; - - int x; - for (x = 0; x < [files count]; x ++) - { - NSString *sv=[files objectAtIndex:x]; - if (sv) - { - char text[4096]; - text[0]=0; - SWELL_CFStringToCString(sv,text,sizeof(text)); - sz+=strlen(text)+1; - if (maketmpfn) sz += strlen("tmp."); - } - } - - NSPoint tpt = [self convertPoint:[sender draggingLocation] fromView:nil]; - - HANDLE gobj=GlobalAlloc(0,sz+1); - DROPFILES *df=(DROPFILES*)gobj; - df->pFiles=sizeof(DROPFILES); - df->pt.x = (int)(tpt.x+0.5); - df->pt.y = (int)(tpt.y+0.5); - df->fNC = FALSE; - df->fWide = FALSE; - char *pout = (char *)(df+1); - for (x = 0; x < [files count]; x ++) - { - NSString *sv=[files objectAtIndex:x]; - if (sv) - { - char text[4096]; - text[0]=0; - SWELL_CFStringToCString(sv,text,sizeof(text)); - if (maketmpfn) - { - strcpy(pout, "tmp."); - pout += strlen("tmp."); - } - strcpy(pout,text); - pout+=strlen(pout)+1; - } - } - *pout=0; - - if (!retG) - { - [self onSwellMessage:WM_DROPFILES p1:(WPARAM)gobj p2:0]; - GlobalFree(gobj); - } - - return gobj; -} - -- (BOOL)performDragOperation:(id )sender -{ - if (m_supports_ddrop && SWELL_DDrop_onDragLeave) SWELL_DDrop_onDragLeave(); - - HWND cv = NULL; // view to disable "setwindowrepre()" for - - id dragsrc = [sender draggingSource]; - if ([dragsrc isKindOfClass:[NSView class]]) - { - if ([(NSView *)dragsrc window] == [self window]) // this means we're likely dragging from the titlebar, so we gotta disable setwindowrepre cause cocoa sucks - { - cv = (HWND) [[self window] contentView]; - } - } - - if (cv) SetProp(cv,"SWELL_DisableWindowRepre",(HANDLE)TRUE); - - NSView *v=[self hitTest:[[self superview] convertPoint:[sender draggingLocation] fromView:nil]]; - if (v && [v isDescendantOf:self]) - { - while (v && v!=self) - { - if ([v respondsToSelector:@selector(swellExtendedDragOp:retGlob:)]) - if ([(SWELL_hwndChild *)v swellExtendedDragOp:sender retGlob:NO]) - { - if (cv) RemoveProp(cv,"SWELL_DisableWindowRepre"); - return YES; - } - v=[v superview]; - } - } - - BOOL ret=!![self swellExtendedDragOp:sender retGlob:NO]; - if (cv) RemoveProp(cv,"SWELL_DisableWindowRepre"); - return ret; -} - --(unsigned int)swellCreateWindowFlags -{ - return m_create_windowflags; -} - - - - -// NSAccessibility - - -- (id)accessibilityHitTest:(NSPoint)point -{ - id ret = NULL; - id use_obj = NULL; - SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); - if (use_obj) - { - ret = [use_obj accessibilityHitTest:point]; - if (ret == use_obj && [ret accessibilityIsIgnored]) ret = NULL; - } - - if (!ret) ret = [super accessibilityHitTest:point]; - return ret; -} -- (id)accessibilityFocusedUIElement -{ - id use_obj = NULL, ret = NULL; - SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); - if (use_obj) - { - ret = [use_obj accessibilityFocusedUIElement]; - if (ret == use_obj) ret= NULL; - } - if (!ret) ret = [super accessibilityFocusedUIElement]; - return ret; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute -{ - id ret = [super accessibilityAttributeValue:attribute]; - int wo=0; - if ([attribute isEqual:NSAccessibilityChildrenAttribute] || (wo = !![attribute isEqual:NSAccessibilityVisibleChildrenAttribute])) - { - id *cp = wo ? m_access_cacheptrs+3 : m_access_cacheptrs; - id use_obj = NULL; - SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); - if (use_obj) - { - if (cp[0] && cp[1] && use_obj == cp[2] && (ret==cp[1] || [ret isEqualToArray:cp[1]])) return cp[0]; - - NSArray *ar=NULL; - if (ret && [ret count]) - { - ar = [NSMutableArray arrayWithArray:ret]; - [(NSMutableArray *)ar addObject:use_obj]; - } - else ar = [NSArray arrayWithObject:use_obj]; - - int x; - for (x=0;x<3;x++) if (cp[x]) { [cp[x] release]; cp[x]=0; } - - //cp[1]=ret; - //cp[2]=use_obj; - - ret = NSAccessibilityUnignoredChildren(ar); - //cp[0]=ret; - - for (x=0;x<3;x++) if (cp[x]) [cp[x] retain]; - - return ret; - } - int x; - for (x=0;x<3;x++) if (cp[x]) { [cp[x] release]; cp[x]=0; } - } - - return ret; -} -// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. -- (BOOL)accessibilityIsIgnored -{ - if (![[self subviews] count]) - { - id use_obj = NULL; - SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); - - if (use_obj) - { - return YES; - } - } - return [super accessibilityIsIgnored]; -} - - - - - - -@end - - - - - -static HWND last_key_window; - - -#define SWELLDIALOGCOMMONIMPLEMENTS_WND(ISMODAL) \ --(BOOL)acceptsFirstResponder { return m_enabled?YES:NO; } \ -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return m_enabled?YES:NO; } \ -- (void)setFrame:(NSRect)frameRect display:(BOOL)displayFlag \ -{ \ - [super setFrame:frameRect display:displayFlag]; \ - if((int)frameRect.size.width != (int)lastFrameSize.width || (int)frameRect.size.height != (int)lastFrameSize.height) { \ - SWELL_hwndChild *hc = (SWELL_hwndChild*)[self contentView]; \ - sendSwellMessage(hc,WM_SIZE,0,0); \ - if ([hc isOpaque]) InvalidateRect((HWND)hc,NULL,FALSE); \ - lastFrameSize=frameRect.size; \ - } \ -} \ -- (void)windowDidMove:(NSNotification *)aNotification { \ - NSRect f=[self frame]; \ - sendSwellMessage([self contentView], WM_MOVE,0, MAKELPARAM((int)f.origin.x,(int)f.origin.y)); \ -} \ -- (BOOL)accessibilityIsIgnored \ -{ \ - if (!([self styleMask] & NSTitledWindowMask) && ![[[self contentView] subviews] count]) return YES; \ - return [super accessibilityIsIgnored]; \ -} \ --(void)swellDoDestroyStuff \ -{ \ - if (last_key_window==(HWND)self) last_key_window=0; \ - OwnedWindowListRec *p=m_ownedwnds; m_ownedwnds=0; \ - while (p) \ - { \ - OwnedWindowListRec *next=p->_next; \ - DestroyWindow((HWND)p->hwnd); \ - free(p); p=next; \ - } \ - if (last_key_window==(HWND)self) last_key_window=0; \ - if (m_owner) { \ - [(SWELL_ModelessWindow*)m_owner swellRemoveOwnedWindow:self]; \ - if ([NSApp keyWindow] == self) [(SWELL_ModelessWindow*)m_owner makeKeyWindow]; \ - m_owner=0; \ - } \ -} \ --(void)dealloc \ -{ \ - [self swellDoDestroyStuff]; \ - [super dealloc]; \ -} \ -- (void)swellDestroyAllOwnedWindows \ -{ \ - OwnedWindowListRec *p=m_ownedwnds; m_ownedwnds=0; \ - while (p) \ - { \ - OwnedWindowListRec *next=p->_next; \ - DestroyWindow((HWND)p->hwnd); \ - free(p); p=next; \ - } \ -} \ -- (void)resignKeyWindow { \ - [super resignKeyWindow]; \ - if (g_swell_terminating) return; \ - sendSwellMessage([self contentView],WM_ACTIVATE,WA_INACTIVE,0); \ - last_key_window=(HWND)self; \ -} \ --(void)becomeKeyWindow \ -{ \ - [super becomeKeyWindow]; \ - if (g_swell_terminating) return; \ - NSView *foc=last_key_window && IsWindow(last_key_window) ? [(NSWindow *)last_key_window contentView] : 0; \ - HMENU menu=0; \ - if (foc && [foc respondsToSelector:@selector(swellHasBeenDestroyed)] && [(SWELL_hwndChild*)foc swellHasBeenDestroyed]) foc=NULL; \ - NSView *cv = [self contentView]; \ - if (!cv || ![cv respondsToSelector:@selector(swellHasBeenDestroyed)] || ![(SWELL_hwndChild*)cv swellHasBeenDestroyed]) { \ - if ([cv respondsToSelector:@selector(swellGetMenu)]) menu = [(SWELL_hwndChild*)cv swellGetMenu]; \ - if (!menu) menu=ISMODAL && g_swell_defaultmenumodal ? g_swell_defaultmenumodal : g_swell_defaultmenu; \ - if (menu && menu != (HMENU)[NSApp mainMenu] && !g_swell_terminating) [NSApp setMainMenu:(NSMenu *)menu]; \ - sendSwellMessage(cv,WM_ACTIVATE,WA_ACTIVE,(LPARAM)foc); \ - sendSwellMessage(cv,WM_MOUSEACTIVATE,0,0); \ - } \ -} \ --(BOOL)windowShouldClose:(id)sender \ -{ \ - NSView *v=[self contentView]; \ - if ([v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) \ - if (![(SWELL_hwndChild*)v onSwellMessage:WM_CLOSE p1:0 p2:0]) \ - [(SWELL_hwndChild*)v onSwellMessage:WM_COMMAND p1:IDCANCEL p2:0]; \ - return NO; \ -} \ -- (BOOL)canBecomeKeyWindow { return !!m_enabled && !g_swell_terminating; } \ -- (void **)swellGetOwnerWindowHead { return (void **)&m_ownedwnds; } \ -- (void)swellAddOwnedWindow:(NSWindow*)wnd \ -{ \ - OwnedWindowListRec *p=m_ownedwnds; \ - while (p) { \ - if (p->hwnd == wnd) return; \ - p=p->_next; \ - } \ - p=(OwnedWindowListRec*)malloc(sizeof(OwnedWindowListRec)); \ - p->hwnd=wnd; p->_next=m_ownedwnds; m_ownedwnds=p; \ - if ([wnd respondsToSelector:@selector(swellSetOwner:)]) [(SWELL_ModelessWindow*)wnd swellSetOwner:self]; \ - if (SWELL_owned_windows_levelincrease) if ([wnd isKindOfClass:[NSWindow class]]) \ - { \ - int extra = [wnd isKindOfClass:[SWELL_ModelessWindow class]] ? ((SWELL_ModelessWindow *)wnd)->m_wantraiseamt : 0; \ - if ([NSApp isActive]) [wnd setLevel:[self level]+1+extra]; \ - } \ -} \ -- (void)swellRemoveOwnedWindow:(NSWindow *)wnd \ -{ \ - OwnedWindowListRec *p=m_ownedwnds, *lp=NULL; \ - while (p) { \ - if (p->hwnd == wnd) { \ - if (lp) lp->_next=p->_next; \ - else m_ownedwnds=p->_next; \ - free(p); \ - return; \ - } \ - lp=p; \ - p=p->_next; \ - } \ -} \ -- (void)swellResetOwnedWindowLevels { \ - if (SWELL_owned_windows_levelincrease) { OwnedWindowListRec *p=m_ownedwnds; \ - bool active = [NSApp isActive]; \ - int l=[self level]+!!active; \ - while (p) { \ - if (p->hwnd) { \ - int extra = active && [(id)p->hwnd isKindOfClass:[SWELL_ModelessWindow class]] ? ((SWELL_ModelessWindow *)p->hwnd)->m_wantraiseamt : 0; \ - [(NSWindow *)p->hwnd setLevel:l+extra]; \ - if ([(id)p->hwnd respondsToSelector:@selector(swellResetOwnedWindowLevels)]) \ - [(id)p->hwnd swellResetOwnedWindowLevels]; \ - } \ - p=p->_next; \ - } \ - } \ -} \ -- (void)swellSetOwner:(id)owner { m_owner=owner; } \ -- (id)swellGetOwner { return m_owner; } \ -- (NSSize)minSize \ -{ \ - MINMAXINFO mmi={0}; \ - NSSize minsz=(NSSize)[super minSize]; \ - mmi.ptMinTrackSize.x=(int)minsz.width; mmi.ptMinTrackSize.y=(int)minsz.height; \ - sendSwellMessage([self contentView],WM_GETMINMAXINFO,0,(LPARAM)&mmi); \ - minsz.width=mmi.ptMinTrackSize.x; minsz.height=mmi.ptMinTrackSize.y; \ - return minsz; \ -} \ -- (NSSize)maxSize \ -{ \ - MINMAXINFO mmi={0}; \ - NSSize maxsz=(NSSize)[super maxSize]; NSSize tmp=maxsz;\ - if (tmp.width<1)tmp.width=1; else if (tmp.width > 1000000.0) tmp.width=1000000.0; \ - if (tmp.height<1)tmp.height=1; else if (tmp.height > 1000000.0) tmp.height=1000000.0; \ - mmi.ptMaxTrackSize.x=(int)tmp.width; mmi.ptMaxTrackSize.y=(int)tmp.height; \ - sendSwellMessage([self contentView], WM_GETMINMAXINFO, 0, (LPARAM)&mmi); \ - if (mmi.ptMaxTrackSize.x < 1000000) maxsz.width=mmi.ptMaxTrackSize.x; \ - if (mmi.ptMaxTrackSize.y < 1000000) maxsz.height=mmi.ptMaxTrackSize.y; \ - return maxsz; \ -} \ - - - -#define INIT_COMMON_VARS \ - m_enabled=TRUE; \ - m_owner=0; \ - m_ownedwnds=0; - - -#if 0 -#define DOWINDOWMINMAXSIZES(ch) \ -{ \ - MINMAXINFO mmi={0}; \ - NSSize minsz=(NSSize)[super contentMinSize]; \ - mmi.ptMinTrackSize.x=(int)minsz.width; mmi.ptMinTrackSize.y=(int)minsz.height; \ - sendSwellMessage(ch,WM_GETMINMAXINFO,0,(LPARAM)&mmi); \ - minsz.width=mmi.ptMinTrackSize.x; minsz.height=mmi.ptMinTrackSize.y; \ - [super setContentMinSize:minsz]; \ -} - -#endif - -static void GetInitialWndPos(HWND owner, int h, int* x, int* y) -{ - RECT r; - if (owner) GetWindowRect(owner, &r); - else SWELL_GetViewPort(&r, 0, false); - *x = r.left+50; - *y = r.bottom-h-100; -} - - -@implementation SWELL_ModelessWindow : NSWindow - -SWELLDIALOGCOMMONIMPLEMENTS_WND(0) - - -- (id)initModelessForChild:(HWND)child owner:(HWND)owner styleMask:(unsigned int)smask -{ - INIT_COMMON_VARS - m_wantInitialKeyWindowOnShow=0; - m_wantraiseamt=0; - lastFrameSize.width=lastFrameSize.height=0.0f; - - NSRect cr=[(NSView *)child bounds]; - - int wx, wy; - GetInitialWndPos(owner, cr.size.height, &wx, &wy); - NSRect contentRect=NSMakeRect(wx,wy,cr.size.width,cr.size.height); - if (!(self = [super initWithContentRect:contentRect styleMask:smask backing:NSBackingStoreBuffered defer:NO])) return self; - - [self setDelegate:(id)self]; - [self disableCursorRects]; - [self setAcceptsMouseMovedEvents:YES]; - [self setContentView:(NSView *)child]; - [self useOptimizedDrawing:YES]; - updateWindowCollection(self); - - if (owner && [(id)owner respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(id)owner swellAddOwnedWindow:self]; - } - else if (owner && [(id)owner isKindOfClass:[NSView class]]) - { - NSWindow *w=[(id)owner window]; - if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; - } - } - - [self display]; - return self; -} - -- (id)initModeless:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par outputHwnd:(HWND *)hwndOut forceStyles:(unsigned int)smask -{ - INIT_COMMON_VARS - m_wantInitialKeyWindowOnShow=0; - m_wantraiseamt=0; - - lastFrameSize.width=lastFrameSize.height=0.0f; - - int w = (resstate ? resstate->width : 10); - int h = (resstate ? resstate->height : 10); - - int wx, wy; - GetInitialWndPos(parent, h, &wx, &wy); - NSRect contentRect=NSMakeRect(wx,wy,w,h); - int sf=smask; - - if (resstate) - { - sf |= NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask; - if (resstate->windowTypeFlags&SWELL_DLG_WS_RESIZABLE) sf |= NSResizableWindowMask; - } - - if (!(self = [super initWithContentRect:contentRect styleMask:sf backing:NSBackingStoreBuffered defer:NO])) return self; - - [self disableCursorRects]; - [self setAcceptsMouseMovedEvents:YES]; - [self useOptimizedDrawing:YES]; - [self setDelegate:(id)self]; - updateWindowCollection(self); - - if (resstate&&resstate->title) SetWindowText((HWND)self, resstate->title); - - - if (parent && [(id)parent respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(id)parent swellAddOwnedWindow:self]; - } - else if (parent && [(id)parent isKindOfClass:[NSView class]]) - { - NSWindow *w=[(id)parent window]; - if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; - } - } - - [self retain]; // in case WM_INITDIALOG goes and releases us - - SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:resstate Parent:(NSView *)self dlgProc:dlgproc Param:par]; // create a new child view class - ch->m_create_windowflags=sf; - *hwndOut = (HWND)ch; - - [ch release]; - - [self display]; - [self release]; // matching retain above - - return self; -} --(NSInteger)level -{ - //if (SWELL_owned_windows_levelincrease) return NSNormalWindowLevel; - return [super level]; -} - -#if SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN > 1 --(void) displayIfNeeded -{ - if (![[self contentView] isOpaque]) - { - [super displayIfNeeded]; - } - else - { - // NSThemeFrame - if ([self viewsNeedDisplay]) - { - [[self contentView] _recursiveDisplayRectIfNeededIgnoringOpacity:NSMakeRect(0,0,0,0) isVisibleRect:YES rectIsVisibleRectForView:[self contentView] topView:[self contentView]]; - [self setViewsNeedDisplay:NO]; - [self flushWindow]; - } - - } -} -#endif - -@end - - - - -@implementation SWELL_ModalDialog : NSPanel - -SWELLDIALOGCOMMONIMPLEMENTS_WND(1) - - - -- (id)initDialogBox:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par -{ - m_rv=0; - m_hasrv=false; - INIT_COMMON_VARS - - NSRect contentRect=NSMakeRect(0,0,resstate->width,resstate->height); - unsigned int sf=(NSTitledWindowMask|NSClosableWindowMask|((resstate->windowTypeFlags&SWELL_DLG_WS_RESIZABLE)? NSResizableWindowMask : 0)); - if (!(self = [super initWithContentRect:contentRect styleMask:sf backing:NSBackingStoreBuffered defer:NO])) return self; - - [self setAcceptsMouseMovedEvents:YES]; - [self disableCursorRects]; - [self useOptimizedDrawing:YES]; - [self setDelegate:(id)self]; - updateWindowCollection(self); - - if (parent && [(id)parent respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(id)parent swellAddOwnedWindow:self]; - } - else if (parent && [(id)parent isKindOfClass:[NSView class]]) - { - NSWindow *w=[(id)parent window]; - if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) - { - [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; - } - } - if (resstate&&resstate->title) SetWindowText((HWND)self, resstate->title); - - SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:resstate Parent:(NSView *)self dlgProc:dlgproc Param:par]; // create a new child view class - ch->m_create_windowflags=sf; - [ch setHidden:NO]; -// DOWINDOWMINMAXSIZES(ch) - [ch release]; - - [self setHidesOnDeactivate:NO]; - [self display]; - - return self; -} - - --(void)swellSetModalRetVal:(int)r -{ - m_hasrv=true; - m_rv=r; -} --(int)swellGetModalRetVal -{ - return m_rv; -} --(bool)swellHasModalRetVal -{ - return m_hasrv; -} - -@end - -void EndDialog(HWND wnd, int ret) -{ - if (!wnd) return; - - NSWindow *nswnd=NULL; - NSView *nsview = NULL; - if ([(id)wnd isKindOfClass:[NSView class]]) - { - nsview = (NSView *)wnd; - nswnd = [nsview window]; - } - else if ([(id)wnd isKindOfClass:[NSWindow class]]) - { - nswnd = (NSWindow *)wnd; - nsview = [nswnd contentView]; - } - if (!nswnd) return; - - if ([nswnd respondsToSelector:@selector(swellSetModalRetVal:)]) - [(SWELL_ModalDialog*)nswnd swellSetModalRetVal:ret]; - - if ([NSApp modalWindow] == nswnd) - { - sendSwellMessage(nsview,WM_DESTROY,0,0); - - NSEvent *evt=[NSApp currentEvent]; - if (evt && [evt window] == nswnd) - { - [NSApp stopModal]; - } - - [NSApp abortModal]; // always call this, otherwise if running in runModalForWindow: it can often require another even tto come through before things continue - - [nswnd close]; - } -} - - -int SWELL_DialogBox(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) -{ - SWELL_DialogResourceIndex *p=resById(reshead,resid); - if (!p||(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) return -1; - SWELL_ModalDialog *box = [[SWELL_ModalDialog alloc] initDialogBox:p Parent:parent dlgProc:dlgproc Param:param]; - - if (!box) return -1; - - if ([box swellHasModalRetVal]) // detect EndDialog() in WM_INITDIALOG - { - int ret=[box swellGetModalRetVal]; - sendSwellMessage([box contentView],WM_DESTROY,0,0); - [box release]; - return ret; - } - - if (0 && ![NSApp isActive]) // using this enables better background processing (i.e. if the app isnt active it still runs) - { - [NSApp activateIgnoringOtherApps:YES]; - NSModalSession session = [NSApp beginModalSessionForWindow:box]; - for (;;) - { - if ([NSApp runModalSession:session] != NSRunContinuesResponse) break; - Sleep(1); - } - [NSApp endModalSession:session]; - } - else - { - [NSApp runModalForWindow:box]; - } - int ret=[box swellGetModalRetVal]; - [box release]; - return ret; -} - -HWND SWELL_CreateModelessFrameForWindow(HWND childW, HWND ownerW, unsigned int windowFlags) -{ - SWELL_ModelessWindow *ch=[[SWELL_ModelessWindow alloc] initModelessForChild:childW owner:ownerW styleMask:windowFlags]; - return (HWND)ch; -} - - -HWND SWELL_CreateDialog(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) -{ - unsigned int forceStyles=0; - if ((((INT_PTR)resid)&~0xf)==0x400000) - { - int a = (int)(INT_PTR)resid; - forceStyles = NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask; - if (a&1) forceStyles|=NSResizableWindowMask; - if (a&2) forceStyles&=~NSMiniaturizableWindowMask; - if (a&4) forceStyles&=~NSClosableWindowMask; - resid=NULL; - } - SWELL_DialogResourceIndex *p=resById(reshead,resid); - if (!p&&resid) return 0; - - NSView *parview=NULL; - if (parent && ([(id)parent isKindOfClass:[NSView class]] || - [(id)parent isKindOfClass:[NSSavePanel class]] || - [(id)parent isKindOfClass:[NSOpenPanel class]] || - [(id)parent isKindOfClass:[NSColorPanel class]] || - [(id)parent isKindOfClass:[NSFontPanel class]] - )) parview=(NSView *)parent; - else if (parent && [(id)parent isKindOfClass:[NSWindow class]]) parview=(NSView *)[(id)parent contentView]; - - if ((!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD)) && parview) - { - SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:p Parent:parview dlgProc:dlgproc Param:param]; // create a new child view class - ch->m_create_windowflags=(NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask); - [ch release]; - return (HWND)ch; - } - else - { - HWND h=NULL; - [[SWELL_ModelessWindow alloc] initModeless:p Parent:parent dlgProc:dlgproc Param:param outputHwnd:&h forceStyles:forceStyles]; - return h; - } - - return 0; -} - - -HMENU SWELL_GetDefaultWindowMenu() { return g_swell_defaultmenu; } -void SWELL_SetDefaultWindowMenu(HMENU menu) -{ - g_swell_defaultmenu=menu; -} -HMENU SWELL_GetDefaultModalWindowMenu() -{ - return g_swell_defaultmenumodal; -} -void SWELL_SetDefaultModalWindowMenu(HMENU menu) -{ - g_swell_defaultmenumodal=menu; -} - - - -SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; // this eventually will go into a per-module stub file - - -#import - - -#if 0 -static void PrintAllHIViews(HIViewRef f, const char *bla) -{ - char tmp[4096]; - sprintf(tmp,"%s:%08x",bla,f); - - HIRect r; - HIViewGetFrame(f,&r); - printf("%s beg %f %f %f %f\n",tmp,r.origin.x,r.origin.y,r.size.width, r.size.height); - HIViewRef a=HIViewGetFirstSubview(f); - while (a) - { - PrintAllHIViews(a,tmp); - a=HIViewGetNextView(a); - } - printf("%s end\n",tmp); -} -#endif - -#ifndef __LP64__ -// carbon event handler for carbon-in-cocoa -OSStatus CarbonEvtHandler(EventHandlerCallRef nextHandlerRef, EventRef event, void* userdata) -{ - SWELL_hwndCarbonHost* _this = (SWELL_hwndCarbonHost*)userdata; - UInt32 evtkind = GetEventKind(event); - - switch (evtkind) - { - case kEventWindowActivated: - if (!g_swell_terminating) [NSApp setMainMenu:nil]; - break; - - case kEventWindowGetClickActivation: - { - ClickActivationResult car = kActivateAndHandleClick; - SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult, sizeof(ClickActivationResult), &car); - } - break; - - case kEventWindowHandleDeactivate: - { - if (_this) - { - WindowRef wndref = (WindowRef)[_this->m_cwnd windowRef]; - if (wndref) ActivateWindow(wndref, true); - } - } - break; - - case kEventControlBoundsChanged: - { - if (_this && !_this->m_whileresizing) - { - Rect prevr, curr; - GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, 0, sizeof(Rect), 0, &prevr); - GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0, sizeof(Rect), 0, &curr); - - RECT parr; - GetWindowRect((HWND)_this, &parr); - parr.left += curr.left-prevr.left; - parr.top += curr.top-prevr.top; - parr.right += curr.right-prevr.right; - parr.bottom += curr.bottom-prevr.bottom; - _this->m_whileresizing = true; - SetWindowPos((HWND)_this, 0, parr.left, parr.right, parr.right-parr.left, parr.bottom-parr.top, SWP_NOZORDER|SWP_NOACTIVATE); - _this->m_whileresizing = false; - } - } - break; - - case kEventRawKeyDown: - case kEventRawKeyUp: - case kEventRawKeyModifiersChanged: - { - if (_this->m_wantallkeys) return eventNotHandledErr; - - WindowRef wndref = (WindowRef)[_this->m_cwnd windowRef]; - if (wndref) - { - ControlRef ctlref=0; - GetKeyboardFocus(wndref, &ctlref); - if (ctlref) - { - ControlKind ctlkind = { 0, 0 }; - GetControlKind(ctlref, &ctlkind); - if (ctlkind.kind == kControlKindEditText || - ctlkind.kind == kControlKindEditUnicodeText || - ctlkind.kind == kControlKindHITextView) - { - // ControlDefinitions.h, HITextViews.h, etc list control types, - // we may want to pass on some other types too - return eventNotHandledErr; - } - } - } - - UInt32 keycode; - UInt32 modifiers; - char c[2] = { 0, 0 }; - GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(UInt32), 0, &keycode); - GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &modifiers); - GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(char), 0, &c[0]); - - NSEventType type; - if (evtkind == kEventRawKeyDown) type = NSKeyDown; - else if (evtkind == kEventRawKeyUp) type = NSKeyUp; - else if (evtkind == kEventRawKeyModifiersChanged) type = NSFlagsChanged; - - NSString* str = (NSString*)SWELL_CStringToCFString(c); - NSTimeInterval ts = 0; // [[NSApp currentevent] timestamp]; - NSEvent* evt = [NSEvent keyEventWithType:type location:NSMakePoint(0,0) - modifierFlags:modifiers - timestamp:ts windowNumber:0 - context:[NSGraphicsContext currentContext] - characters:str charactersIgnoringModifiers:str - isARepeat:NO keyCode:keycode]; - [str release]; - if (evt) [NSApp sendEvent:evt]; - return noErr; - } - } - return noErr; -} - -void SWELL_CarbonWndHost_SetWantAllKeys(void* carbonhost, bool want) -{ - SWELL_hwndCarbonHost* h = (SWELL_hwndCarbonHost*)carbonhost; - if (h) h->m_wantallkeys = want; -} - -#endif // __LP - -@implementation SWELL_hwndCarbonHost - -- (id)initCarbonChild:(NSView *)parent rect:(Rect*)r composit:(bool)wantComp -{ - if (!(self = [super initChild:nil Parent:parent dlgProc:nil Param:nil])) return self; - - m_wantallkeys=false; - -#ifndef __LP64__ - WindowRef wndref=0; - CreateNewWindow (kPlainWindowClass, (wantComp ? kWindowCompositingAttribute : 0) | kWindowStandardHandlerAttribute|kWindowNoShadowAttribute, r, &wndref); - if (wndref) - { - // eventually we should set this and have the real NSWindow parent call ActivateWindow when activated/deactivated - // SetWindowActivationScope( m_wndref, kWindowActivationScopeNone); - - // adding a Carbon event handler to catch special stuff that NSWindow::initWithWindowRef - // doesn't automatically redirect to a standard Cocoa window method - - ControlRef ctl=0; - if (!wantComp) CreateRootControl(wndref, &ctl); // creating root control here so callers must use GetRootControl - - EventTypeSpec winevts[] = - { - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowGetClickActivation }, - { kEventClassWindow, kEventWindowHandleDeactivate }, - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - }; - int nwinevts = sizeof(winevts)/sizeof(EventTypeSpec); - - EventTypeSpec ctlevts[] = - { - //{ kEventClassControl, kEventControlInitialize }, - //{ kEventClassControl, kEventControlDraw }, - { kEventClassControl, kEventControlBoundsChanged }, - }; - int nctlevts = sizeof(ctlevts)/sizeof(EventTypeSpec); - - EventHandlerRef wndhandler=0, ctlhandler=0; - InstallWindowEventHandler(wndref, CarbonEvtHandler, nwinevts, winevts, self, &wndhandler); - if (!wantComp) InstallControlEventHandler(ctl, CarbonEvtHandler, nctlevts, ctlevts, self, &ctlhandler); - m_wndhandler = wndhandler; - m_ctlhandler = ctlhandler; - - // initWithWindowRef does not retain // MAKE SURE THIS IS NOT BAD TO DO - //CFRetain(wndref); - - m_cwnd = [[NSWindow alloc] initWithWindowRef:wndref]; - [m_cwnd setDelegate:self]; - - ShowWindow(wndref); - - //[[parent window] addChildWindow:m_cwnd ordered:NSWindowAbove]; - //[self swellDoRepos]; - SetTimer((HWND)self,1,10,NULL); - } -#endif - return self; -} - --(BOOL)swellIsCarbonHostingView { return YES; } - - --(void)close -{ - KillTimer((HWND)self,1); - -#ifndef __LP64__ - if (m_wndhandler) - { - EventHandlerRef wndhandler = (EventHandlerRef)m_wndhandler; - RemoveEventHandler(wndhandler); - m_wndhandler = 0; - } - if (m_ctlhandler) - { - EventHandlerRef ctlhandler = (EventHandlerRef)m_ctlhandler; - RemoveEventHandler(ctlhandler); - m_ctlhandler = 0; - } - - if (m_cwnd) - { - if ([m_cwnd parentWindow]) [[m_cwnd parentWindow] removeChildWindow:m_cwnd]; - [m_cwnd orderOut:self]; - [m_cwnd close]; // this disposes the owned wndref - m_cwnd=0; - } -#endif -} - --(void)dealloc -{ - [self close]; - [super dealloc]; // ?! -} - -- (void)SWELL_Timer:(id)sender -{ -#ifndef __LP64__ - id uinfo=[sender userInfo]; - if ([uinfo respondsToSelector:@selector(getValue)]) - { - int idx=(int)(INT_PTR)[(SWELL_DataHold*)uinfo getValue]; - if (idx==1) - { - if (![self superview] || [[self superview] isHiddenOrHasHiddenAncestor]) - { - NSWindow *oldw=[m_cwnd parentWindow]; - if (oldw) - { - [oldw removeChildWindow:(NSWindow *)m_cwnd]; - [m_cwnd orderOut:self]; - } - } - else - { - if (![m_cwnd parentWindow]) - { - NSWindow *par = [self window]; - if (par) - { - [par addChildWindow:m_cwnd ordered:NSWindowAbove]; - [self swellDoRepos]; - } - } - else - { - if (GetCurrentEventButtonState()&7) - { - if ([NSApp keyWindow] == [self window]) - { - POINT p; - GetCursorPos(&p); - RECT r; - GetWindowRect((HWND)self,&r); - if (r.top>r.bottom) - { - int a=r.top; - r.top=r.bottom; - r.bottom=a; - } - if (m_cwnd && p.x >=r.left &&p.x < r.right && p.y >= r.top && p.y < r.bottom) - { - [(NSWindow *)m_cwnd makeKeyWindow]; - } - } - } - } - } - return; - } - KillTimer((HWND)self,idx); - return; - } -#endif -} -- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam -{ - if (msg == WM_DESTROY) - { - if (m_cwnd) - { - if ([NSApp keyWindow] == m_cwnd) // restore focus to highest window that is not us! - { - NSArray *ar = [NSApp orderedWindows]; - int x; - for (x = 0; x < (ar ? [ar count] : 0); x ++) - { - NSWindow *w=[ar objectAtIndex:x]; - if (w && w != m_cwnd && [w isVisible]) { [w makeKeyWindow]; break; } - } - } - - [self close]; - } - } - return [super onSwellMessage:msg p1:wParam p2:lParam]; -} -- (void)windowDidResignKey:(NSNotification *)aNotification -{ -} -- (void)windowDidBecomeKey:(NSNotification *)aNotification -{ -} - - -- (void)viewDidMoveToWindow -{ - [super viewDidMoveToWindow]; - if (m_cwnd) - { - // reparent m_cwnd to new owner - NSWindow *neww=[self window]; - NSWindow *oldw=[m_cwnd parentWindow]; - if (neww != oldw) - { - if (oldw) [oldw removeChildWindow:m_cwnd]; - } - } -} --(void)swellDoRepos -{ -#ifndef __LP64__ - if (m_cwnd) - { - RECT r; - GetWindowRect((HWND)self,&r); - if (r.top>r.bottom) - { - int a=r.top; - r.top=r.bottom; - r.bottom=a; - } - - // [m_cwnd setFrameOrigin:NSMakePoint(r.left,r.top)]; - - { - Rect bounds; - bounds.left = r.left; - bounds.top = CGRectGetHeight(CGDisplayBounds(kCGDirectMainDisplay))-r.bottom; - // GetWindowBounds (m_wndref, kWindowContentRgn, &bounds); - bounds.right = bounds.left + (r.right-r.left); - bounds.bottom = bounds.top + (r.bottom-r.top); - - WindowRef wndref = (WindowRef)[m_cwnd windowRef]; - SetWindowBounds (wndref, kWindowContentRgn, &bounds); - - // might make sense to only do this on initial show, but doesnt seem to hurt to do it often - WindowAttributes wa=0; - GetWindowAttributes(wndref,&wa); - - if (wa&kWindowCompositingAttribute) - { -// [[m_cwnd contentView] setNeedsDisplay:YES]; - HIViewRef ref = HIViewGetRoot(wndref); - if (ref) - { - // PrintAllHIViews(ref,""); - - HIViewRef ref2=HIViewGetFirstSubview(ref); - while (ref2) - { - /* - HIRect r3=CGRectMake(0,0,bounds.right-bounds.left,bounds.bottom-bounds.top); - HIViewRef ref3=HIViewGetFirstSubview(ref2); - while (ref3) - { - HIViewSetVisible(ref3,true); - HIViewSetNeedsDisplay(ref3,true); - HIViewSetFrame(ref3,&r3); - ref3=HIViewGetNextView(ref3); - } - */ - - // HIViewSetVisible(ref2,true); - HIViewSetNeedsDisplay(ref2,true); - ref2=HIViewGetNextView(ref2); - } - //HIViewSetVisible(ref,true); - HIViewSetNeedsDisplay(ref,true); - HIViewRender(ref); - } - } - else - { - -#if 0 - ControlRef rc=NULL; - GetRootControl(m_wndref,&rc); - if (rc) - { - RgnHandle rgn=NewRgn(); - GetControlRegion(rc,kControlEntireControl,rgn); - UpdateControls(m_wndref,rgn); - CloseRgn(rgn); - } -#endif - // Rect r={0,0,bounds.bottom-bounds.top,bounds.right-bounds.left}; - // InvalWindowRect(m_wndref,&r); - - // or we could just do: - DrawControls(wndref); - } - } - } -#endif -} - -- (void)viewDidMoveToSuperview -{ - [super viewDidMoveToSuperview]; - [self swellDoRepos]; -} -- (void)setFrameSize:(NSSize)newSize -{ - [super setFrameSize:newSize]; - [self swellDoRepos]; -} -- (void)setFrame:(NSRect)frameRect -{ - [super setFrame:frameRect]; - [self swellDoRepos]; -} -- (void)setFrameOrigin:(NSPoint)newOrigin -{ - [super setFrameOrigin:newOrigin]; - [self swellDoRepos]; -} - - --(BOOL)isOpaque -{ - return NO; -} - -@end - -HWND SWELL_GetAudioUnitCocoaView(HWND parent, AudioUnit aunit, AudioUnitCocoaViewInfo* viewinfo, RECT* r) -{ - NSString* classname = (NSString*)(viewinfo->mCocoaAUViewClass[0]); - if (!classname) return 0; - - NSBundle* bundle=0; - if ([NSBundle respondsToSelector:@selector(bundleWithURL:)]) - { - bundle=[NSBundle bundleWithURL:(NSURL*)viewinfo->mCocoaAUViewBundleLocation]; - } - - if (!bundle) - { - NSString* path = (NSString*)(CFURLCopyFileSystemPath(viewinfo->mCocoaAUViewBundleLocation,kCFURLPOSIXPathStyle)); - if (path) - { - bundle = [NSBundle bundleWithPath:path]; - [path release]; - } - } - - if (!bundle) return 0; - - Class factoryclass = [bundle classNamed:classname]; - if (![factoryclass conformsToProtocol: @protocol(AUCocoaUIBase)]) return 0; - if (![factoryclass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) return 0; - id viewfactory = [[factoryclass alloc] init]; - if (!viewfactory) return 0; - NSView* view = [viewfactory uiViewForAudioUnit:aunit withSize:NSMakeSize(r->right-r->left, r->bottom-r->top)]; - if (!view) - { - [viewfactory release]; - return 0; - } - - [(NSView*)parent addSubview:view]; - NSRect bounds = [view bounds]; - r->left = r->top = 0; - r->right = bounds.size.width; - r->bottom = bounds.size.height; - [viewfactory release]; - - return (HWND)view; -} - - -HWND SWELL_CreateCarbonWindowView(HWND viewpar, void **wref, RECT* r, bool wantcomp) // window is created with a root control -{ - RECT wndr = *r; - ClientToScreen(viewpar, (POINT*)&wndr); - ClientToScreen(viewpar, (POINT*)&wndr+1); - //Rect r2 = { wndr.top, wndr.left, wndr.bottom, wndr.right }; - Rect r2 = { wndr.bottom, wndr.left, wndr.top, wndr.right }; - SWELL_hwndCarbonHost *w = [[SWELL_hwndCarbonHost alloc] initCarbonChild:(NSView*)viewpar rect:&r2 composit:wantcomp]; - if (w) *wref = [w->m_cwnd windowRef]; - return (HWND)w; -} - -void* SWELL_GetWindowFromCarbonWindowView(HWND cwv) -{ - SWELL_hwndCarbonHost* w = (SWELL_hwndCarbonHost*)cwv; - if (w) return [w->m_cwnd windowRef]; - return 0; -} - -void SWELL_AddCarbonPaneToView(HWND cwv, void* pane) // not currently used -{ -#ifndef __LP64__ - SWELL_hwndCarbonHost* w = (SWELL_hwndCarbonHost*)cwv; - if (w) - { - WindowRef wndref = (WindowRef)[w->m_cwnd windowRef]; - if (wndref) - { - EventTypeSpec ctlevts[] = - { - //{ kEventClassControl, kEventControlInitialize }, - //{ kEventClassControl, kEventControlDraw }, - { kEventClassControl, kEventControlBoundsChanged }, - }; - int nctlevts = sizeof(ctlevts)/sizeof(EventTypeSpec); - - EventHandlerRef ctlhandler = (EventHandlerRef)w->m_ctlhandler; - InstallControlEventHandler((ControlRef)pane, CarbonEvtHandler, nctlevts, ctlevts, w, &ctlhandler); - } - } -#endif -} - - -@interface NSButton (TextColor) - -- (NSColor *)textColor; -- (void)setTextColor:(NSColor *)textColor; - -@end - -@implementation NSButton (TextColor) - -- (NSColor *)textColor -{ - NSAttributedString *attrTitle = [self attributedTitle]; - int len = [attrTitle length]; - NSRange range = NSMakeRange(0, MIN(len, 1)); // take color from first char - NSDictionary *attrs = [attrTitle fontAttributesInRange:range]; - NSColor *textColor = [NSColor controlTextColor]; - if (attrs) { - textColor = [attrs objectForKey:NSForegroundColorAttributeName]; - } - return textColor; -} - -- (void)setTextColor:(NSColor *)textColor -{ - NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] - initWithAttributedString:[self attributedTitle]]; - int len = [attrTitle length]; - NSRange range = NSMakeRange(0, len); - [attrTitle addAttribute:NSForegroundColorAttributeName - value:textColor - range:range]; - [attrTitle fixAttributesInRange:range]; - [self setAttributedTitle:attrTitle]; - [attrTitle release]; -} - -@end - - -static char* s_dragdropsrcfn = 0; -static void (*s_dragdropsrccallback)(const char*) = 0; - -void SWELL_InitiateDragDrop(HWND hwnd, RECT* srcrect, const char* srcfn, void (*callback)(const char* dropfn)) -{ - SWELL_FinishDragDrop(); - - if (![(id)hwnd isKindOfClass:[SWELL_hwndChild class]]) return; - - s_dragdropsrcfn = strdup(srcfn); - s_dragdropsrccallback = callback; - - char* p = s_dragdropsrcfn+strlen(s_dragdropsrcfn)-1; - while (p >= s_dragdropsrcfn && *p != '.') --p; - ++p; - - NSString* str = (NSString*)SWELL_CStringToCFString(p); - NSRect r = NSMakeRect(srcrect->left, srcrect->top, srcrect->right-srcrect->left, srcrect->bottom-srcrect->top); - NSEvent* evt = [NSApp currentEvent]; - [(NSView*)hwnd dragPromisedFilesOfTypes:[NSArray arrayWithObject:str] fromRect:r source:(NSView*)hwnd slideBack:YES event:evt]; - [str release]; -} - -// owner owns srclist, make copies here etc -void SWELL_InitiateDragDropOfFileList(HWND hwnd, RECT *srcrect, const char **srclist, int srccount, HICON icon) -{ - SWELL_FinishDragDrop(); - - if (![(id)hwnd isKindOfClass:[SWELL_hwndChild class]]) return; - - NSMutableArray *ar = [[NSMutableArray alloc] initWithCapacity:srccount]; - int x; - - for(x=0;xleft,srcrect->top) offset:NSMakeSize(0,0) event:[NSApp currentEvent] pasteboard:pb source:(id)hwnd slideBack:YES]; - - [ar release]; -} - - -static bool _file_exists(const char* fn) -{ - struct stat sb= { 0 }; - return !stat(fn, &sb); -} - -NSArray* SWELL_DoDragDrop(NSURL* droplocation) -{ - NSArray* fnarr=0; - if (s_dragdropsrcfn && s_dragdropsrccallback && droplocation) - { - const char* srcpath=s_dragdropsrcfn; - - const char* fn = srcpath+strlen(srcpath)-1; - while (fn >= srcpath && *fn != '/') --fn; - ++fn; - - WDL_String destpath; - destpath.SetFormatted(4096, "%s/%s", [[droplocation path] UTF8String], fn); - - bool ok=!_file_exists(destpath.Get()); - if (!ok) - { - int ret=NSRunAlertPanel(@"Copy", - @"An item named \"%s\" already exists in this location. Do you want to replace it with the one you're moving?", - @"Keep Both Files", @"Stop", @"Replace", fn); - - if (ret == -1) // replace - { - ok=true; - } - else if (ret == 1) // keep both - { - WDL_String base(destpath.Get()); - char* p=base.Get(); - int len=strlen(p); - const char* ext=""; - int incr=0; - - const char* q=fn+strlen(fn)-1; - while (q > fn && *q != '.') --q; - if (*q == '.') - { - ext=q; - len -= strlen(ext); - p[len]=0; - } - - int digits=0; - int i; - for (i=0; i < 3 && len > i+1 && isdigit(p[len-i-1]); ++i) ++digits; - if (len > digits+1 && (p[len-digits-1] == ' ' || p[len-digits-1] == '-' || p[len-digits-1] == '_')) - { - incr=atoi(p+len-digits); - p[len-digits]=0; - } - else - { - base.Append(" "); - } - - WDL_String trypath; - while (!ok && ++incr < 1000) - { - trypath.SetFormatted(4096, "%s%03d%s", base.Get(), incr, ext); - ok=!_file_exists(trypath.Get()); - } - - if (ok) destpath.Set(trypath.Get()); - } - } - - if (ok) - { - s_dragdropsrccallback(destpath.Get()); - ok=_file_exists(destpath.Get()); - } - - if (ok) - { - fn=destpath.Get(); - fn += strlen(fn)-1; - while (fn >= destpath.Get() && *fn != '/') --fn; - ++fn; - - NSString* nfn=(NSString*)SWELL_CStringToCFString(fn); - fnarr=[NSArray arrayWithObject:nfn]; - [nfn release]; - } - } - - SWELL_FinishDragDrop(); - return fnarr; -} - -void SWELL_FinishDragDrop() -{ - free(s_dragdropsrcfn); - s_dragdropsrcfn = 0; - s_dragdropsrccallback = 0; -} - -bool SWELL_SetGLContextToView(HWND h) -{ - if (!h) [NSOpenGLContext clearCurrentContext]; - else if ([(id)h isKindOfClass:[SWELL_hwndChild class]]) - { - SWELL_hwndChild *hc = (SWELL_hwndChild*)h; - if (hc->m_glctx) - { - [hc->m_glctx makeCurrentContext]; - return true; - } - } - return false; -} - -void SWELL_SetViewGL(HWND h, bool wantGL) -{ - if (h && [(id)h isKindOfClass:[SWELL_hwndChild class]]) - { - SWELL_hwndChild *hc = (SWELL_hwndChild*)h; - if (wantGL != !!hc->m_glctx) - { - if (wantGL) - { - NSOpenGLPixelFormatAttribute atr[] = {(NSOpenGLPixelFormatAttribute)0}; // todo: optionally add any attributes before the 0 - NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:atr]; - - hc->m_glctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil]; - [fmt release]; - } - else - { - if ([NSOpenGLContext currentContext] == hc->m_glctx) [NSOpenGLContext clearCurrentContext]; - [hc->m_glctx release]; - hc->m_glctx=0; - } - } - - } -} - -bool SWELL_GetViewGL(HWND h) -{ - return h && [(id)h isKindOfClass:[SWELL_hwndChild class]] && ((SWELL_hwndChild*)h)->m_glctx; -} -void DrawSwellViewRectImpl(SWELL_hwndChild *view, NSRect rect, HDC hdc) -{ - if (view->m_hashaddestroy) - { - return; - } - view->m_paintctx_hdc=hdc; - if (view->m_paintctx_hdc && view->m_glctx) - { - view->m_paintctx_hdc->GLgfxctx = view->m_glctx; - - [view->m_glctx setView:view]; - [view->m_glctx makeCurrentContext]; - [view->m_glctx update]; - } - view->m_paintctx_rect=rect; - view->m_paintctx_used=false; - DoPaintStuff(view->m_wndproc,(HWND)view,view->m_paintctx_hdc,&view->m_paintctx_rect); - - if (view->m_paintctx_hdc && view->m_glctx && [NSOpenGLContext currentContext] == view->m_glctx) - { - [NSOpenGLContext clearCurrentContext]; - } - view->m_paintctx_hdc=0; - if (!view->m_paintctx_used) { - /*[super drawRect:rect];*/ - } - -#if 0 - // debug: show everything - static CGColorSpaceRef cspace; - if (!cspace) cspace=CGColorSpaceCreateDeviceRGB(); - float cols[4]={0.0f,1.0f,0.0f,0.8f}; - CGColorRef color=CGColorCreate(cspace,cols); - - CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextSetStrokeColorWithColor(ctx,color); - CGContextStrokeRectWithWidth(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height), 1); - - CGColorRelease(color); - - cols[0]=1.0f; - cols[1]=0.0f; - cols[2]=0.0f; - cols[3]=1.0f; - color=CGColorCreate(cspace,cols); - - NSRect rect2=[view bounds]; - CGContextSetStrokeColorWithColor(ctx,color); - CGContextStrokeRectWithWidth(ctx, CGRectMake(rect2.origin.x,rect2.origin.y,rect2.size.width,rect2.size.height), 1); - - - CGColorRelease(color); - - cols[0]=0.0f; - cols[1]=0.0f; - cols[2]=1.0f; - cols[3]=0.7f; - color=CGColorCreate(cspace,cols); - cols[3]=0.25; - cols[2]=0.5; - CGColorRef color2=CGColorCreate(cspace,cols); - - NSArray *ar = [view subviews]; - if (ar) - { - int x; - for(x=0;x<[ar count];x++) - { - NSView *v = [ar objectAtIndex:x]; - if (v && ![v isHidden]) - { - NSRect rect = [v frame]; - CGContextSetStrokeColorWithColor(ctx,color); - CGContextStrokeRectWithWidth(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height), 1); - CGContextSetFillColorWithColor(ctx,color2); - CGContextFillRect(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height)); - } - } - - // draw children - } - CGColorRelease(color); - CGColorRelease(color2); - -#endif - - - -} - -void swellRenderOptimizely(int passflags, SWELL_hwndChild *view, HDC hdc, BOOL doforce, WDL_PtrList *needdraws, const NSRect *rlist, int rlistcnt, int draw_xlate_x, int draw_xlate_y, bool iscv) -{ - if (view->m_isdirty&1) doforce=true; - NSArray *sv = [view subviews]; - if (doforce&&(passflags & ([sv count]?1:2))) - DrawSwellViewRectImpl(view,[view bounds], hdc); - - if (sv) - { - [sv retain]; - int x,n=[sv count]; - HBRUSH bgbr=0; - bool bgbr_valid=false; - for(x=0;xm_isdirty)|| [v needsDisplay]) - { - if (isSwellChild) - { - NSRect fr = [v frame]; - CGContextSaveGState(hdc->ctx); - CGContextClipToRect(hdc->ctx,CGRectMake(fr.origin.x,fr.origin.y,fr.size.width,fr.size.height)); - CGContextTranslateCTM(hdc->ctx, fr.origin.x,fr.origin.y); - swellRenderOptimizely(passflags,(SWELL_hwndChild*)v,hdc,doforce,needdraws,rlist,rlistcnt,draw_xlate_x-(int)fr.origin.x,draw_xlate_y-(int)fr.origin.y,false); - CGContextRestoreGState(hdc->ctx); - if (passflags&2) [v setNeedsDisplay:NO]; - bgbr_valid=false; // code in swellRenderOptimizely() may trigger WM_CTLCOLORDLG which may invalidate our brush, so clear the cached value here - } - else if (passflags&1) - { - if ([v isKindOfClass:[NSScrollView class]]) - { - NSView *sv = [(NSScrollView *)v contentView]; - if (sv) - { - [v retain]; - needdraws->Add((void*)(INT_PTR)(doforce?1:0)); - needdraws->Add(v); - v=sv; - } - } - [v retain]; - if (!doforce && ![v isOpaque]) - { - - NSRect fr= [v frame]; - - // we could recursively go up looking for WM_CTLCOLORDLG, but actually we just need to use the current window - if (!bgbr_valid) // note that any code in this loop that does anything that could trigger messages might invalidate bgbr, so it should clear bgbr_checked here - { - bgbr=(HGDIOBJ)SendMessage((HWND)view,WM_CTLCOLORDLG,(WPARAM)hdc,(LPARAM)view); - bgbr_valid=true; - } - - if (!iscv) fr = [view convertRect:fr toView:[[view window] contentView]]; - - int ri; - for(ri=0;ri0 && ff.size.height>0) - { - RECT r={(int)ff.origin.x,(int)ff.origin.y,(int)(ff.origin.x+ff.size.width),(int)(ff.origin.y+ff.size.height)}; - r.left+=draw_xlate_x; - r.right+=draw_xlate_x; - r.top+=draw_xlate_y; - r.bottom+=draw_xlate_y; - if (bgbr_valid && bgbr && bgbr != (HBRUSH)1) FillRect(hdc,&r,bgbr); - else SWELL_FillDialogBackground(hdc,&r,3); - } - } - } - needdraws->Add((void*)(INT_PTR)(doforce?1:0)); - needdraws->Add(v); - } - } - } - } - [sv release]; - } - if (passflags&2) - view->m_isdirty=0; -} - -#endif diff --git a/WDL/swell/swell-dlggen.h b/WDL/swell/swell-dlggen.h deleted file mode 100644 index 93c77ec9..00000000 --- a/WDL/swell/swell-dlggen.h +++ /dev/null @@ -1,280 +0,0 @@ - -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - DialogBox emulation is here. To declare the resource at a global level, use (in any source file that includes this file and resource.h): - - - #ifdef MAC - - - SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_SOMEDIALOG,0,"Dialog Box Title",222,55,1.8) // width, height, scale (1.8 is usually good) - - BEGIN - DEFPUSHBUTTON "OK",IDOK,117,33,47,14 - CONTROL "Expand MIDI tracks to new REAPER tracks ",IDC_CHECK1, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,7,214,10 - CONTROL "Merge MIDI tempo map to project tempo map at ", - IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,19, - 214,10 - PUSHBUTTON "Cancel",IDCANCEL,168,33,50,14 - END - - SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_SOMEDIALOG) - - - #endif - - - This file also provides functions to dynamically create controls in a view from a win32 resource script. - - - -*/ - - - - -#ifndef _SWELL_DLGGEN_H_ -#define _SWELL_DLGGEN_H_ - -#ifdef BEGIN -#undef BEGIN -#endif - -#ifdef END -#undef END -#endif - - -struct SWELL_DlgResourceEntry -{ - const char *str1; - int flag1; - const char *str2; - - int p1; // often used for ID - - // todo: see at runtime if some of these can be short instead of int (p2-p6 probably can, but not completely sure) -- i.e. do we use any - // big values in flags. note: it can't be unsigned short, because we want negative values. - int p2, p3, p4, p5, p6; // meaning is dependent on class -}; - - -#define BEGIN {NULL, -#define END }, - -#define PUSHBUTTON }, { "__SWELL_BUTTON", 0, -#define DEFPUSHBUTTON }, { "__SWELL_BUTTON", 1, -#define EDITTEXT }, { "__SWELL_EDIT", 0, "", -#define CTEXT }, { "__SWELL_LABEL", 0, -#define LTEXT }, { "__SWELL_LABEL", -1, -#define RTEXT }, { "__SWELL_LABEL", 1, -#define CONTROL }, { -#define COMBOBOX }, { "__SWELL_COMBO", 0, "", -#define GROUPBOX }, { "__SWELL_GROUP", 0, -#define CHECKBOX }, { "__SWELL_CHECKBOX", 0, -#define LISTBOX }, { "__SWELL_LISTBOX", 0, "", - -#define NOT - -// flags we may use -#define CBS_DROPDOWNLIST 0x0003L -#define CBS_DROPDOWN 0x0002L -#define CBS_SORT 0x0100L -#define ES_PASSWORD 0x0020L -#define ES_READONLY 0x0800L -#define ES_WANTRETURN 0x1000L -#define ES_NUMBER 0x2000L - -#define SS_LEFT 0 -#define SS_CENTER 0x1L -#define SS_BLACKRECT 0x4L -#define SS_BLACKFRAME (SS_BLACKRECT) -#define SS_LEFTNOWORDWRAP 0xCL -#define SS_TYPEMASK 0x1FL -#define SS_NOTIFY 0x0100L - -#define BS_CENTER 0x0300L -#define BS_LEFTTEXT 0x0020L -#define BS_GROUPBOX 0x20000000 -#define BS_DEFPUSHBUTTON 0x10000000 -#define BS_PUSHBUTTON 0x8000000 - -#define LVS_LIST 0 /* 0x0003 */ -#define LVS_NOCOLUMNHEADER 0x4000 -#define LVS_NOSORTHEADER 0x8000 -#define LVS_REPORT 0x0001 -#define LVS_TYPEMASK 0x0003 -#define LVS_SINGLESEL 0x0004 -#define LVS_OWNERDATA 0x1000 -#define LVS_SORTASCENDING 0x0010 -#define LVS_SORTDESCENDING 0x0020 - -#define LBS_SORT 0x0002L -#define LBS_OWNERDRAWFIXED 0x0010L -#define LBS_EXTENDEDSEL 0x0800L - -#define ES_LEFT 0 -#define ES_CENTER 1 -#define ES_RIGHT 2 - -// flags we ignore -#define LVS_SHOWSELALWAYS 0 -#define LVS_SHAREIMAGELISTS 0 -#define ES_AUTOHSCROLL 0 -#define ES_MULTILINE 0 -#define ES_AUTOVSCROLL 0 -#define GROUP 0 -#define PBS_SMOOTH 0 -#define CBS_AUTOHSCROLL 0 -#define TBS_NOTICKS 0 -#define TBS_TOP 0 -#define TBS_BOTH 0 -#define BS_BITMAP 0 -#define LBS_NOINTEGRALHEIGHT 0 -#define TVS_HASLINES 0 -#define TVS_SHOWSELALWAYS 0 -#define TVS_HASBUTTONS 0 -#define BS_FLAT 0 -#define TVS_DISABLEDRAGDROP 0 -#define TVS_TRACKSELECT 0 -#define TVS_NONEVENHEIGHT 0 -#define BS_LEFT 0 -#define SS_SUNKEN 0 -#define BS_RIGHT 0 -#define WS_EX_STATICEDGE 0 -#define WS_EX_RIGHT 0 -#define SS_CENTERIMAGE 0 -#define SS_NOPREFIX 0 - - -#ifndef IDC_STATIC -#define IDC_STATIC 0 -#endif - - - - -#define SWELL_DLG_WS_CHILD 1 -#define SWELL_DLG_WS_RESIZABLE 2 -#define SWELL_DLG_WS_FLIPPED 4 -#define SWELL_DLG_WS_NOAUTOSIZE 8 -#define SWELL_DLG_WS_OPAQUE 16 -#define SWELL_DLG_WS_DROPTARGET 32 - -typedef struct SWELL_DialogResourceIndex -{ - const char *resid; - const char *title; - int windowTypeFlags; - void (*createFunc)(HWND, int); - int width,height; - struct SWELL_DialogResourceIndex *_next; -} SWELL_DialogResourceIndex; - -typedef struct SWELL_CursorResourceIndex -{ - const char *resid; - const char *resname; - POINT hotspot; - HCURSOR cachedCursor; - struct SWELL_CursorResourceIndex *_next; -} SWELL_CursorResourceIndex; - - - -static inline HWND __SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags=0, int exstyle=0) -{ - return SWELL_MakeButton(def,label,idx,x,y,w,h,flags); -} -static inline HWND __SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags=0) -{ - return SWELL_MakeEditField(idx,x,y,w,h,flags); -} -static inline HWND __SWELL_MakeLabel(int align, const char *label, int idx, int x, int y, int w, int h, int flags=0, int exflags=0) -{ - return SWELL_MakeLabel(align,label,idx,x,y,w,h,flags); -} -static inline HWND __SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags=0) -{ - return SWELL_MakeCombo(idx,x,y,w,h,flags); -} -static inline HWND __SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles=0) -{ - return SWELL_MakeListBox(idx,x,y,w,h,styles); -} - -static inline HWND __SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle=0) -{ - return SWELL_MakeControl(cname,idx,classname,style,x,y,w,h,exstyle); -} - -static inline HWND __SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style=0) -{ - return SWELL_MakeGroupBox(name,idx,x,y,w,h,style); -} - -static void SWELL_Register_Cursor_Resource(const char *idx, const char *name, int hotspot_x, int hotspot_y) -{ - extern SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; - - SWELL_CursorResourceIndex *ri = (SWELL_CursorResourceIndex*)malloc(sizeof(SWELL_CursorResourceIndex)); - ri->hotspot.x = hotspot_x; - ri->hotspot.y = hotspot_y; - ri->resname=name; - ri->cachedCursor=0; - ri->resid = idx; - ri->_next = SWELL_curmodule_cursorresource_head; - SWELL_curmodule_cursorresource_head = ri; -} - - -class SWELL_DialogRegHelper { - public: - SWELL_DialogResourceIndex m_rec; - SWELL_DialogRegHelper(SWELL_DialogResourceIndex **h, void (*cf)(HWND,int), int recid, int flags, const char *titlestr, int wid, int hei, double scale) - { - if (recid) - { - m_rec.resid=MAKEINTRESOURCE(recid); - m_rec.title=titlestr; - m_rec.windowTypeFlags=flags; - m_rec.createFunc=cf; - m_rec.width=(int)((wid)*(scale)); - m_rec.height=(int)((hei)*(scale)); - m_rec._next=*h; - *h = &m_rec; - } - } -}; - -#define SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(recid, flags, titlestr, wid, hei, scale) \ - static void SWELL__dlg_cf__##recid(HWND view, int wflags); \ - static SWELL_DialogRegHelper __swell_dlg_helper_##recid(&SWELL_curmodule_dialogresource_head, SWELL__dlg_cf__##recid, recid,flags,titlestr,wid,hei,scale); \ - void SWELL__dlg_cf__##recid(HWND view, int wflags) { \ - SWELL_MakeSetCurParms(scale,scale,0,0,view,false,!(wflags&SWELL_DLG_WS_NOAUTOSIZE)); \ - static const SWELL_DlgResourceEntry list[]={ - - -#define SWELL_DEFINE_DIALOG_RESOURCE_END(recid ) }; SWELL_GenerateDialogFromList(list+1,sizeof(list)/sizeof(list[0])-1); } - - - -#endif diff --git a/WDL/swell/swell-functions.h b/WDL/swell/swell-functions.h deleted file mode 100644 index d574d263..00000000 --- a/WDL/swell/swell-functions.h +++ /dev/null @@ -1,1092 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) - Copyright (C) 2006-2010, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. - - */ - -#ifndef _WDL_SWELL_H_API_DEFINED_ -#define _WDL_SWELL_H_API_DEFINED_ - -//////////////////////////////////////////// -/////////// FUNCTIONS -//////////////////////////////////////////// - -#ifndef SWELL_API_DEFINE - - -#ifdef SWELL_PROVIDED_BY_APP - #ifdef __cplusplus - #define SWELL_API_DEFINE(ret,func,parms) extern "C" ret (*func)parms; - #else - #define SWELL_API_DEFINE(ret,func,parms) extern ret (*func)parms; - #endif -#else -#define SWELL_API_DEFINE(ret,func,parms) ret func parms ; -#endif -#endif - -// when adding APIs, add it using: -// SWELL_API_DEFINE(void, function_name, (int parm, int parm2)) -// rather than: -// void function_name(int parm, int parm2); - -/* -** lstrcpyn: this is provided because strncpy is braindead (filling with zeroes, and not -** NULL terminating if the destination buffer is too short? ASKING for trouble..) -** lstrpcyn always null terminates the string and doesnt fill anything extra. -*/ -SWELL_API_DEFINE(char *, lstrcpyn, (char *dest, const char *src, int l)) - - -/* -** MulDiv(): (parm1*parm2)/parm3 -** Implemented using long longs. -*/ -SWELL_API_DEFINE(int, MulDiv, (int, int, int)) - - -/* -** Sleep() sleeps for specified milliseconds. This maps to usleep, with a ms value of 0 -** usleeping for 100 microseconds. -*/ -SWELL_API_DEFINE(void, Sleep,(int ms)) - -/* -** GetTickCount() and timeGetTime() give you ms level timings via gettimeofday(). -** -** NOTE: This doesn't map to time since system start (like in win32), so a wrap around -** is slightly more likely (i.e. even if you booted your system an hour ago it could happen). -*/ -SWELL_API_DEFINE(DWORD, GetTickCount,()) -#ifndef timeGetTime -#define timeGetTime() GetTickCount() -#endif - -/* -** GetFileTime() gets the file time of a file (FILE *), and converts it to the Windows time. -** -** NOTE: while it returns a 64 bit time value, it is only accurate to the second since thats -** what fstat() returns. Takes an int filedes rather than a HANDLE. -*/ -SWELL_API_DEFINE(BOOL, GetFileTime,(int filedes, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime)) - -/* -** *PrivateProfileString/Int(): -** These are mostly thread-safe, mostly inter-process safe, and mostly module safe -** (i.e. writes from other modules) should be synchronized). -** -** NOTES: -** the filename used MUST be the full filename, unlike on Windows where files without paths go to -** C:/Windows, here they will be opened in the current directory. -** -** It's probably not a good idea to push your luck with simultaneous writes from multiple -** modules in different threads/processes, but in theory it should work. -*/ -SWELL_API_DEFINE(BOOL, WritePrivateProfileString, (const char *appname, const char *keyname, const char *val, const char *fn)) -SWELL_API_DEFINE(DWORD, GetPrivateProfileString, (const char *appname, const char *keyname, const char *def, char *ret, int retsize, const char *fn)) -SWELL_API_DEFINE(int, GetPrivateProfileInt,(const char *appname, const char *keyname, int def, const char *fn)) -SWELL_API_DEFINE(BOOL, GetPrivateProfileStruct,(const char *appname, const char *keyname, void *buf, int bufsz, const char *fn)) -SWELL_API_DEFINE(BOOL, WritePrivateProfileStruct,(const char *appname, const char *keyname, const void *buf, int bufsz, const char *fn)) -SWELL_API_DEFINE(BOOL, WritePrivateProfileSection, (const char *appname, const char *strings, const char *fn)) -SWELL_API_DEFINE(DWORD, GetPrivateProfileSection, (const char *appname, char *strout, DWORD strout_len, const char *fn)) - -/* -** GetModuleFileName() -** Can pass NULL (exe filename) or a hInstance from DllMain or LoadLibrary -*/ -SWELL_API_DEFINE(DWORD, GetModuleFileName,(HINSTANCE hInst, char *fn, DWORD nSize)) - -#ifdef SWELL_TARGET_OSX -/* -** SWELL_CStringToCFString(): Creates a CFString/NSString * from a C string. This is mostly -** used internally but you may wish to use it as well (though none of the SWELL APIs take -** CFString/NSString. -*/ -SWELL_API_DEFINE(void *,SWELL_CStringToCFString,(const char *str)) -SWELL_API_DEFINE(void, SWELL_CFStringToCString, (const void *str, char *buf, int buflen)) -#endif - - -/* -** PtInRect() should hopefully function just like it's win32 equivelent. -** there is #define funkiness because some Mac system headers define PtInRect as well. -*/ -#ifdef PtInRect -#undef PtInRect -#endif -#define PtInRect(r,p) SWELL_PtInRect(r,p) -SWELL_API_DEFINE(BOOL, SWELL_PtInRect,(RECT *r, POINT p)) - -/* -** ShellExecute(): -** NOTE: currently action is ignored, and it only works on content1 being a URL beginning with http://. -** TODO: finish implementation -*/ -SWELL_API_DEFINE(BOOL, ShellExecute,(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah)) - -/* -** MessageBox(). -*/ -SWELL_API_DEFINE(int, MessageBox,(HWND hwndParent, const char *text, const char *caption, int type)) - - -/* -** GetOpenFileName() / GetSaveFileName() -** These are a different API because we didnt feel like reeimplimenting the full API. -** Extlist is something similar you'd pass getopenfilename, -** initialdir and initialfile are optional (and NULL means not set). -*/ - -// free() the result of this, if non-NULL. -// if allowmul is set, the multiple files are specified the same way GetOpenFileName() returns. -SWELL_API_DEFINE(char *,BrowseForFiles,(const char *text, const char *initialdir, - const char *initialfile, bool allowmul, const char *extlist)) - -// returns TRUE if file was chosen. -SWELL_API_DEFINE(bool, BrowseForSaveFile,(const char *text, const char *initialdir, const char *initialfile, const char *extlist, - char *fn, int fnsize)) - -// returns TRUE if path was chosen. -SWELL_API_DEFINE(bool, BrowseForDirectory,(const char *text, const char *initialdir, char *fn, int fnsize)) - -// can use this before calling BrowseForFiles or BrowseForSaveFile to use a template dialog -SWELL_API_DEFINE(void,BrowseFile_SetTemplate,(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead)) - - -// Note that window functions are generally NOT threadsafe. -// all of these treat HWND as NSView and/or NSWindow (usually smartish about it) - - -/* -** GetDlgItem(hwnd,0) returns hwnd if hwnd is a NSView, or the contentview if hwnd is a NSWindow. -** Note that this GetDlgItem will actually search a view hierarchy for the tagged view, -** unlike Win32 where it will only look at immediate children. -*/ -SWELL_API_DEFINE(HWND, GetDlgItem,(HWND, int)) - -/* -** ShowWindow() works for hwnds that represent NSView and/or NSWindow. -** SW_SHOW, SW_SHOWNA, and SW_HIDE are defined, and some of the other common uses -** alias to these. -*/ -SWELL_API_DEFINE(void, ShowWindow,(HWND, int)) - - -/* -** DestroyWindow() works for both a NSWindow or NSView. -** Note that if the window is a fake window with a procedure -** (created via CreateDialog or DialogBox below) then WM_DESTROY -** will be called immediately, though the window/view may be freed -** sometime later via the autorelease pool. -*/ -SWELL_API_DEFINE(void, DestroyWindow,(HWND hwnd)) - -SWELL_API_DEFINE(BOOL, SWELL_GetGestureInfo, (LPARAM lParam, GESTUREINFO* gi)) - -SWELL_API_DEFINE(void, SWELL_HideApp,()) - -/* -** These should all work like their Win32 versions, though if idx=0 it gets/sets the -** value for the window. Note that SetDlgItemText() for an edit control does NOT send -** a WM_COMMAND notification like on win32, so you will have to do this yourself. -*/ -SWELL_API_DEFINE(BOOL, SetDlgItemText,(HWND, int idx, const char *text)) -SWELL_API_DEFINE(BOOL, SetDlgItemInt,(HWND, int idx, int val, int issigned)) -SWELL_API_DEFINE(int, GetDlgItemInt,(HWND, int idx, BOOL *translated, int issigned)) -SWELL_API_DEFINE(BOOL, GetDlgItemText,(HWND, int idx, char *text, int textlen)) - -#ifndef GetWindowText -#define GetWindowText(hwnd,text,textlen) GetDlgItemText(hwnd,0,text,textlen) -#define SetWindowText(hwnd,text) SetDlgItemText(hwnd,0,text) -#endif - - -SWELL_API_DEFINE(void, CheckDlgButton,(HWND hwnd, int idx, int check)) -SWELL_API_DEFINE(int, IsDlgButtonChecked,(HWND hwnd, int idx)) -SWELL_API_DEFINE(void, EnableWindow,(HWND hwnd, int enable)) -SWELL_API_DEFINE(void, SetFocus,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * -SWELL_API_DEFINE(HWND, GetFocus,()) -SWELL_API_DEFINE(void, SetForegroundWindow,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * -SWELL_API_DEFINE(HWND, GetForegroundWindow,()) -#ifndef GetActiveWindow -#define GetActiveWindow() GetForegroundWindow() -#endif -#ifndef SetActiveWindow -#define SetActiveWindow(x) SetForegroundWindow(x) -#endif - -/* -** GetCapture/SetCapture/ReleaseCapture are completely faked, with just an internal state. -** Mouse click+drag automatically captures the focus sending mouseDrag events in OSX, so -** these are as a porting aid. -** -** Updated: they actually send WM_CAPTURECHANGED messages now, if the window supports -** onSwellMessage:p1:p2: and swellCapChangeNotify (and swellCapChangeNotify returns YES). -** -** Note that any HWND that returns YES to swellCapChangeNotify should do the following on -** destroy or dealloc: if (GetCapture()==(HWND)self) ReleaseCapture(); Failure to do so -** can cause a dealloc'd window to get messages sent to it. -*/ -SWELL_API_DEFINE(HWND, SetCapture,(HWND hwnd)) -SWELL_API_DEFINE(HWND, GetCapture,()) -SWELL_API_DEFINE(void, ReleaseCapture,()) - -/* -** IsChild() -** Notes: hwndChild must be a NSView (if not then false is returned) -** hwndParent can be a NSWindow or NSView. -** NSWindow level ownership/children are not detected. -*/ -SWELL_API_DEFINE(int, IsChild,(HWND hwndParent, HWND hwndChild)) - - -/* -** GetParent() -** Notes: if hwnd is a NSView, then gets the parent view (or NSWindow -** if the parent view is the window's contentview). If hwnd is a NSWindow, -** then GetParent returns the owner window, if any. Note that the owner -** window system is not part of OSX, but rather part of SWELL. -*/ -SWELL_API_DEFINE(HWND, GetParent,(HWND hwnd)) - -/* -** SetParent() -** Notes: hwnd must be a NSView, newPar can be either NSView or NSWindow. -*/ -SWELL_API_DEFINE(HWND, SetParent,(HWND hwnd, HWND newPar)) - -/* -** GetWindow() -** Most of the standard GW_CHILD etc work. Does not do anything to prevent you from -** getting into infinite loops if you go changing the order on the fly etc. -*/ -SWELL_API_DEFINE(HWND, GetWindow,(HWND hwnd, int what)) - -SWELL_API_DEFINE(HWND,FindWindowEx,(HWND par, HWND lastw, const char *classname, const char *title)) - - -/* -** Notes: common win32 code like this: -** RECT r; -** GetWindowRect(hwnd,&r); -** ScreenToClient(otherhwnd,(LPPOINT)&r); -** ScreenToClient(otherhwnd,((LPPOINT)&r)+1); -** does work, however be aware that in certain instances r.bottom may be less -** than r.top, due to flipped coordinates. SetWindowPos and other functions -** handle negative heights gracefully, and you should too. -** -** Note: GetWindowContentViewRect gets the rectangle of the content view (pre-NCCALCSIZE etc) -*/ -SWELL_API_DEFINE(void, ClientToScreen,(HWND hwnd, POINT *p)) -SWELL_API_DEFINE(void, ScreenToClient,(HWND hwnd, POINT *p)) -SWELL_API_DEFINE(bool, GetWindowRect,(HWND hwnd, RECT *r)) -SWELL_API_DEFINE(void, GetWindowContentViewRect, (HWND hwnd, RECT *r)) -SWELL_API_DEFINE(void, GetClientRect,(HWND hwnd, RECT *r)) -SWELL_API_DEFINE(HWND, WindowFromPoint,(POINT p)) -SWELL_API_DEFINE(BOOL, WinOffsetRect, (LPRECT lprc, int dx, int dy)) -SWELL_API_DEFINE(BOOL, WinSetRect, (LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom)) -SWELL_API_DEFINE(void,WinUnionRect,(RECT *out, RECT *in1, RECT *in2)) -SWELL_API_DEFINE(int,WinIntersectRect,(RECT *out, RECT *in1, RECT *in2)) - - -/* -** SetWindowPos(): -** Notes: Z ordering stuff is ignored, as are most flags. -** SWP_NOMOVE and SWP_NOSIZE are the only flags used. -*/ -SWELL_API_DEFINE(void, SetWindowPos,(HWND hwnd, HWND unused, int x, int y, int cx, int cy, int flags)) - -SWELL_API_DEFINE(int, SWELL_SetWindowLevel, (HWND hwnd, int newlevel)) - -/* -** InvalidateRect() -** Notes: eraseBk is ignored, probably not threadsafe! hwnd can be NSWindow or NSView -*/ -SWELL_API_DEFINE(void,InvalidateRect,(HWND hwnd, RECT *r, int eraseBk)) - -/* -** UpdateWindow() -** Notes: not currently implemented but provided here in case someday it is necessary -*/ -SWELL_API_DEFINE(void,UpdateWindow,(HWND hwnd)) - - -/* -** GetWindowLong()/SetWindowLong() -** -** GWL_ID is supported for all objects that support the 'tag'/'setTag' methods, -** which would be controls and SWELL created windows/dialogs/controls. -** -** GWL_USERDATA is supported by SWELL created windows/dialogs/controls, using -** (int)getSwellUserData and setSwellUserData:(int). -** -** GWL_WNDPROC is supported by SWELL created windows/dialogs/controls, using -** (int)getSwellWindowProc and setSwellWindowProc:(int). -** -** DWL_DLGPROC is supported by SWELL created dialogs now (it might work in windows/controls but isnt recommended) -** -** GWL_STYLE is only supported for NSButton. Currently the only flags supported are -** BS_AUTO3STATE (BS_AUTOCHECKBOX is returned but also ignored). -** -** indices of >= 0 and < 128 (32 integers) are supported for SWELL created -** windows/dialogs/controls, via (int)getSwellExtraData:(int)idx and -** setSwellExtraData:(int)idx value:(int)val . -*/ -SWELL_API_DEFINE(LONG_PTR, GetWindowLong,(HWND hwnd, int idx)) -SWELL_API_DEFINE(LONG_PTR, SetWindowLong,(HWND hwnd, int idx, LONG_PTR val)) - - -SWELL_API_DEFINE(BOOL, ScrollWindow, (HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect)) - -/* -** GetProp() SetProp() RemoveProp() EnumPropsEx() -** These should work like in win32. Free your props otherwise they will leak. -** Restriction on what you can do in the PROPENUMPROCEX is similar to win32 -** (you can remove only the called prop, and can't add props within it). -** if the prop name is < (void *)65536 then it is treated as a short identifier. -*/ -SWELL_API_DEFINE(int, EnumPropsEx,(HWND, PROPENUMPROCEX, LPARAM)) -SWELL_API_DEFINE(HANDLE, GetProp, (HWND, const char *)) -SWELL_API_DEFINE(BOOL, SetProp, (HWND, const char *, HANDLE)) -SWELL_API_DEFINE(HANDLE, RemoveProp, (HWND, const char *)) - - -/* -** IsWindowVisible() -** if hwnd is a NSView, returns !isHiddenOrHasHiddenAncestor -** if hwnd is a NSWindow returns isVisible -** otherwise returns TRUE if non-null hwnd -*/ -SWELL_API_DEFINE(bool, IsWindowVisible,(HWND hwnd)) - -SWELL_API_DEFINE(bool, IsWindow, (HWND hwnd)) // very costly (compared to win32) -- enumerates all windows, searches for hwnd - - -/* -** SetTimer/KillTimer(): -** Notes: -** The timer API may be threadsafe though it is highly untested. -** Note also that the mechanism for sending timers is SWELL_Timer:(id). -** The fourth parameter to SetTimer() is not supported and will be ignored, so you must -** receive your timers via a WM_TIMER (or SWELL_Timer:(id)) -** -** You can kill all timers for a window using KillTimer(hwnd,-1); -** You MUST kill all timers for a window before destroying it. Note that SWELL created -** windows/dialogs/controls automatically do this, but if you use SetTimer() on a NSView * -** or NSWindow * directly, then you should kill all timers in -dealloc. -*/ -SWELL_API_DEFINE(UINT_PTR, SetTimer,(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc)) -SWELL_API_DEFINE(BOOL, KillTimer,(HWND hwnd, UINT_PTR timerid)) - -#ifdef SWELL_TARGET_OSX -/* -** These provide the interfaces for directly updating a combo box control. This is no longer -** required as SendMessage can now be used with CB_* etc. -** Combo boxes may be implemented using a NSComboBox or NSPopUpButton depending on the style. -** -** Notes: CB_SetItemData/CB_GetItemData only work for the non-user-editable version (using NSPopUpbutotn). -*/ -SWELL_API_DEFINE(int, SWELL_CB_AddString,(HWND hwnd, int idx, const char *str)) -SWELL_API_DEFINE(void, SWELL_CB_SetCurSel,(HWND hwnd, int idx, int sel)) -SWELL_API_DEFINE(int, SWELL_CB_GetCurSel,(HWND hwnd, int idx)) -SWELL_API_DEFINE(int, SWELL_CB_GetNumItems,(HWND hwnd, int idx)) -SWELL_API_DEFINE(void, SWELL_CB_SetItemData,(HWND hwnd, int idx, int item, LONG_PTR data)) // these two only work for the combo list version for now -SWELL_API_DEFINE(LONG_PTR, SWELL_CB_GetItemData,(HWND hwnd, int idx, int item)) -SWELL_API_DEFINE(void, SWELL_CB_Empty,(HWND hwnd, int idx)) -SWELL_API_DEFINE(int, SWELL_CB_InsertString,(HWND hwnd, int idx, int pos, const char *str)) -SWELL_API_DEFINE(int, SWELL_CB_GetItemText,(HWND hwnd, int idx, int item, char *buf, int bufsz)) -SWELL_API_DEFINE(void, SWELL_CB_DeleteString,(HWND hwnd, int idx, int wh)) -SWELL_API_DEFINE(int, SWELL_CB_FindString,(HWND hwnd, int idx, int startAfter, const char *str, bool exact)) - - -/* -** Trackbar API -** These provide the interfaces for directly updating a trackbar (implemented using NSSlider). -** Note that you can now use SendMessage with TBM_* instead. -*/ -SWELL_API_DEFINE(void, SWELL_TB_SetPos,(HWND hwnd, int idx, int pos)) -SWELL_API_DEFINE(void, SWELL_TB_SetRange,(HWND hwnd, int idx, int low, int hi)) -SWELL_API_DEFINE(int, SWELL_TB_GetPos,(HWND hwnd, int idx)) -SWELL_API_DEFINE(void, SWELL_TB_SetTic,(HWND hwnd, int idx, int pos)) - - -#endif - -/* -** ListView API. In owner data mode only LVN_GETDISPINFO is used (not ODFINDITEM etc). -** LVN_BEGINDRAG also should work as on windows. Imagelists state icons work as well. -*/ -SWELL_API_DEFINE(void, ListView_SetExtendedListViewStyleEx,(HWND h, int mask, int style)) -SWELL_API_DEFINE(void, ListView_InsertColumn,(HWND h, int pos, const LVCOLUMN *lvc)) -SWELL_API_DEFINE(bool, ListView_DeleteColumn,(HWND h, int pos)) -SWELL_API_DEFINE(void, ListView_SetColumn,(HWND h, int pos, const LVCOLUMN *lvc)) -SWELL_API_DEFINE(int, ListView_GetColumnWidth,(HWND h, int pos)) -SWELL_API_DEFINE(int, ListView_InsertItem,(HWND h, const LVITEM *item)) -SWELL_API_DEFINE(void, ListView_SetItemText,(HWND h, int ipos, int cpos, const char *txt)) -SWELL_API_DEFINE(bool, ListView_SetItem,(HWND h, LVITEM *item)) -SWELL_API_DEFINE(int, ListView_GetNextItem,(HWND h, int istart, int flags)) -SWELL_API_DEFINE(bool, ListView_GetItem,(HWND h, LVITEM *item)) -SWELL_API_DEFINE(int, ListView_GetItemState,(HWND h, int ipos, int mask)) -SWELL_API_DEFINE(void, ListView_DeleteItem,(HWND h, int ipos)) -SWELL_API_DEFINE(void, ListView_DeleteAllItems,(HWND h)) -SWELL_API_DEFINE(int, ListView_GetSelectedCount,(HWND h)) -SWELL_API_DEFINE(int, ListView_GetItemCount,(HWND h)) -SWELL_API_DEFINE(int, ListView_GetSelectionMark,(HWND h)) -SWELL_API_DEFINE(void, ListView_SetColumnWidth,(HWND h, int colpos, int wid)) -SWELL_API_DEFINE(bool, ListView_SetItemState,(HWND h, int item, int state, int statemask)) -SWELL_API_DEFINE(void, ListView_RedrawItems,(HWND h, int startitem, int enditem)) -SWELL_API_DEFINE(void, ListView_SetItemCount,(HWND h, int cnt)) -SWELL_API_DEFINE(void, ListView_EnsureVisible,(HWND h, int i, BOOL pok)) -SWELL_API_DEFINE(bool, ListView_GetSubItemRect,(HWND h, int item, int subitem, int code, RECT *r)) -SWELL_API_DEFINE(void, ListView_SetImageList,(HWND h, HIMAGELIST imagelist, int which)) -SWELL_API_DEFINE(int, ListView_HitTest,(HWND h, LVHITTESTINFO *pinf)) -SWELL_API_DEFINE(int, ListView_SubItemHitTest,(HWND h, LVHITTESTINFO *pinf)) -SWELL_API_DEFINE(void, ListView_GetItemText,(HWND hwnd, int item, int subitem, char *text, int textmax)) -SWELL_API_DEFINE(void, ListView_SortItems,(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm)) -SWELL_API_DEFINE(bool, ListView_GetItemRect,(HWND h, int item, RECT *r, int code)) -SWELL_API_DEFINE(bool, ListView_Scroll,(HWND h, int xscroll, int yscroll)) -SWELL_API_DEFINE(int, ListView_GetTopIndex,(HWND h)) -SWELL_API_DEFINE(int, ListView_GetCountPerPage,(HWND h)) -SWELL_API_DEFINE(BOOL, ListView_SetColumnOrderArray,(HWND h, int cnt, int* arr)) -SWELL_API_DEFINE(BOOL, ListView_GetColumnOrderArray,(HWND h, int cnt, int* arr)) -SWELL_API_DEFINE(HWND, ListView_GetHeader,(HWND h)) -SWELL_API_DEFINE(int, Header_GetItemCount,(HWND h)) -SWELL_API_DEFINE(BOOL, Header_GetItem,(HWND h, int col, HDITEM* hi)) -SWELL_API_DEFINE(BOOL, Header_SetItem,(HWND h, int col, HDITEM* hi)) - -SWELL_API_DEFINE(int, SWELL_GetListViewHeaderHeight, (HWND h)) - -#ifndef ImageList_Create -#define ImageList_Create(x,y,a,b,c) ImageList_CreateEx(); -#endif -SWELL_API_DEFINE(HIMAGELIST, ImageList_CreateEx,()) -SWELL_API_DEFINE(BOOL, ImageList_Remove, (HIMAGELIST list, int idx)) -SWELL_API_DEFINE(int, ImageList_ReplaceIcon,(HIMAGELIST list, int offset, HICON image)) -SWELL_API_DEFINE(void, ImageList_Destroy, (HIMAGELIST)) -/* -** TabCtrl api. -*/ -SWELL_API_DEFINE(int, TabCtrl_GetItemCount,(HWND hwnd)) -SWELL_API_DEFINE(BOOL, TabCtrl_DeleteItem,(HWND hwnd, int idx)) -SWELL_API_DEFINE(int, TabCtrl_InsertItem,(HWND hwnd, int idx, TCITEM *item)) -SWELL_API_DEFINE(int, TabCtrl_SetCurSel,(HWND hwnd, int idx)) -SWELL_API_DEFINE(int, TabCtrl_GetCurSel,(HWND hwnd)) -SWELL_API_DEFINE(BOOL, TabCtrl_AdjustRect, (HWND hwnd, BOOL fLarger, RECT *r)) - -/* -** TreeView -*/ - -SWELL_API_DEFINE(HTREEITEM, TreeView_InsertItem, (HWND hwnd, TV_INSERTSTRUCT *ins)) -SWELL_API_DEFINE(BOOL, TreeView_Expand,(HWND hwnd, HTREEITEM item, UINT flag)) -SWELL_API_DEFINE(HTREEITEM, TreeView_GetSelection,(HWND hwnd)) -SWELL_API_DEFINE(void, TreeView_DeleteItem,(HWND hwnd, HTREEITEM item)) -SWELL_API_DEFINE(void, TreeView_SelectItem,(HWND hwnd, HTREEITEM item)) -SWELL_API_DEFINE(BOOL, TreeView_GetItem,(HWND hwnd, LPTVITEM pitem)) -SWELL_API_DEFINE(BOOL, TreeView_SetItem,(HWND hwnd, LPTVITEM pitem)) -SWELL_API_DEFINE(HTREEITEM, TreeView_HitTest, (HWND hwnd, TVHITTESTINFO *hti)) -SWELL_API_DEFINE(BOOL, TreeView_SetIndent,(HWND hwnd, int indent)) - -SWELL_API_DEFINE(HTREEITEM, TreeView_GetChild, (HWND hwnd, HTREEITEM item)) -SWELL_API_DEFINE(HTREEITEM, TreeView_GetNextSibling, (HWND hwnd, HTREEITEM item)) -SWELL_API_DEFINE(HTREEITEM, TreeView_GetRoot, (HWND hwnd)) - -SWELL_API_DEFINE(void,TreeView_SetBkColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,TreeView_SetTextColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,ListView_SetBkColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,ListView_SetTextBkColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,ListView_SetTextColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,ListView_SetGridColor,(HWND hwnd, int color)) -SWELL_API_DEFINE(void,ListView_SetSelColors,(HWND hwnd, int *colors, int ncolors)) - -/* -** These are deprecated functions for launching a modal window but still running -** your own code. In general use DialogBox with a timer if needed instead. -*/ -SWELL_API_DEFINE(void *, SWELL_ModalWindowStart,(HWND hwnd)) -SWELL_API_DEFINE(bool, SWELL_ModalWindowRun,(void *ctx, int *ret)) // returns false and puts retval in *ret when done -SWELL_API_DEFINE(void, SWELL_ModalWindowEnd,(void *ctx)) -SWELL_API_DEFINE(void, SWELL_CloseWindow,(HWND hwnd)) - - -/* -** Menu functions -** HMENU is a NSMenu *. -*/ -SWELL_API_DEFINE(HMENU, CreatePopupMenu,()) -SWELL_API_DEFINE(HMENU, CreatePopupMenuEx,(const char *title)) -SWELL_API_DEFINE(void, DestroyMenu,(HMENU hMenu)) -SWELL_API_DEFINE(int, AddMenuItem,(HMENU hMenu, int pos, const char *name, int tagid)) -SWELL_API_DEFINE(HMENU, GetSubMenu,(HMENU hMenu, int pos)) -SWELL_API_DEFINE(int, GetMenuItemCount,(HMENU hMenu)) -SWELL_API_DEFINE(int, GetMenuItemID,(HMENU hMenu, int pos)) -SWELL_API_DEFINE(bool, SetMenuItemModifier,(HMENU hMenu, int idx, int flag, int code, unsigned int mask)) -SWELL_API_DEFINE(bool, SetMenuItemText,(HMENU hMenu, int idx, int flag, const char *text)) -SWELL_API_DEFINE(bool, EnableMenuItem,(HMENU hMenu, int idx, int en)) -SWELL_API_DEFINE(bool, DeleteMenu,(HMENU hMenu, int idx, int flag)) -SWELL_API_DEFINE(bool, CheckMenuItem,(HMENU hMenu, int idx, int chk)) -SWELL_API_DEFINE(void, InsertMenuItem,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) -SWELL_API_DEFINE(void,SWELL_InsertMenu,(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str)) -#ifdef InsertMenu -#undef InsertMenu -#endif -#define InsertMenu SWELL_InsertMenu - -SWELL_API_DEFINE(BOOL, GetMenuItemInfo,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) -SWELL_API_DEFINE(BOOL, SetMenuItemInfo,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) -SWELL_API_DEFINE(void, DrawMenuBar,(HWND)) - - - -/* -** LoadMenu() -** Loads a menu created with SWELL_DEFINE_MENU_RESOURCE_BEGIN(), see swell-menugen.h -** Notes: the hinst parameter is ignored, the menu must have been defined in the same -** APP or DYLIB as the LoadMenu call. If you wish to load a menu from another module, -** you should somehow get its SWELL_curmodule_menuresource_head and pass it to SWELL_LoadMenu -** directly. -*/ -#ifndef LoadMenu -#define LoadMenu(hinst,resid) SWELL_LoadMenu(SWELL_curmodule_menuresource_head,(resid)) -#endif -SWELL_API_DEFINE(HMENU, SWELL_LoadMenu,(struct SWELL_MenuResourceIndex *head, const char *resid)) - -/* -** TrackPopupMenu -** Notes: the rectangle and many flags are ignored, but TPM_NONOTIFY is used. -** It always returns the command selected, even if TPM_RETURNCMD is not specified. -*/ -SWELL_API_DEFINE(int, TrackPopupMenu,(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r)) - -/* -** SWELL_SetMenuDestination: set the action destination for all items in a menu -** Notes: -** TrackPopupMenu and SetMenu use this internally, but it may be useful. -*/ -SWELL_API_DEFINE(void, SWELL_SetMenuDestination,(HMENU menu, HWND hwnd)) - -/* -** SWELL_DuplicateMenu: -** Copies an entire menu. -*/ -SWELL_API_DEFINE(HMENU, SWELL_DuplicateMenu,(HMENU menu)) - -/* -** SetMenu()/GetMenu() -** Notes: These work on SWELL created NSWindows, or objective C objects that respond to -** swellSetMenu:(HMENU) and swellGetMenu. -** Setting these values doesnt mean anything, except that the SWELL windows will automatically -** set the application menu via NSApp setMainMenu: when activated. -** -*/ -SWELL_API_DEFINE(BOOL, SetMenu,(HWND hwnd, HMENU menu)) -SWELL_API_DEFINE(HMENU, GetMenu,(HWND hwnd)) - -/* -** SWELL_SetDefaultWindowMenu()/SWELL_GetDefaultWindowMenu() -** these set an internal flag for the default window menu, which will be set -** when switching to a window that has no menu set. Set this to your application's -** main menu. -*/ -SWELL_API_DEFINE(HMENU, SWELL_GetDefaultWindowMenu,()) -SWELL_API_DEFINE(void, SWELL_SetDefaultWindowMenu,(HMENU)) -SWELL_API_DEFINE(HMENU, SWELL_GetDefaultModalWindowMenu,()) -SWELL_API_DEFINE(void, SWELL_SetDefaultModalWindowMenu,(HMENU)) -SWELL_API_DEFINE(HMENU, SWELL_GetCurrentMenu,()) -SWELL_API_DEFINE(void, SWELL_SetCurrentMenu,(HMENU)) - - - -/* -** SWELL dialog box/control/window/child dialog/etc creation -** DialogBox(), DialogBoxParam(), CreateDialog(), and CreateDialogParam() -** -** Notes: -** hInstance parameters are ignored. If you wish to load a dialog resource from another -** module (DYLIB), you should get its SWELL_curmodule_dialogresource_head via your own -** mechanism and pass it as the first parameter of SWELL_DialogBox or whichever API. -** -** If you are using CreateDialog() and creating a child window, you can use a resource ID of -** 0, which creates an opaque child window. Instead of passing a DLGPROC, you should pass a -** routine that retuns LRESULT (and cast it to DLGPROC). -** -*/ - -#ifndef DialogBox -#define DialogBox(hinst, resid, par, dlgproc) SWELL_DialogBox(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,0) -#define DialogBoxParam(hinst, resid, par, dlgproc, param) SWELL_DialogBox(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,param) -#define CreateDialog(hinst,resid,par,dlgproc) SWELL_CreateDialog(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,0) -#define CreateDialogParam(hinst,resid,par,dlgproc,param) SWELL_CreateDialog(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,param) -#endif -SWELL_API_DEFINE(int, SWELL_DialogBox,(struct SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)) -SWELL_API_DEFINE(HWND, SWELL_CreateDialog,(struct SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)) - - -/* -** SWELL_RegisterCustomControlCreator(), SWELL_UnregisterCustomControlCreator() -** Notes: -** Pass these a callback function that can create custom controls based on classname. -** Todo: document. -*/ - -SWELL_API_DEFINE(void, SWELL_RegisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) -SWELL_API_DEFINE(void, SWELL_UnregisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) - -/* -** DefWindowProc(). -** Notes: Doesnt do much but call it anyway from any child windows created with CreateDialog -** and a 0 resource-id window proc. -*/ -SWELL_API_DEFINE(LRESULT, DefWindowProc,(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)) - -/* -** EndDialog(): -** Notes: _ONLY_ use on a dialog created with DialogBox(). Will do nothing on other dialogs. -*/ -SWELL_API_DEFINE(void, EndDialog,(HWND, int)) - - -SWELL_API_DEFINE(int,SWELL_GetDefaultButtonID,(HWND hwndDlg, bool onlyIfEnabled)) - - -/* -** SendMessage() -** Notes: -** LIMITATION - SendMessage should only be used from the same thread that the window/view -** was created in. Cross-thread use SHOULD BE AVOIDED. It may work, but it may blow up. -** PostMessage (below) can be used in certain instances for asynchronous notifications. -** -** If the hwnd supports onSwellMessage:p1:p2: then the message is sent via this. -** Alternatively, buttons created via the dialog interface support BM_GETIMAGE/BM_SETIMAGE -** NSPopUpButton and NSComboBox controls support CB_* -** NSSlider controls support TBM_* -** If the receiver is a view and none of these work, the message goes to the window's onSwellMessage, if any -** If the receiver is a window and none of these work, the message goes to the window's contentview's onSwellMessage, if any -** -*/ -SWELL_API_DEFINE(LRESULT, SendMessage,(HWND, UINT, WPARAM, LPARAM)) -#ifndef SendDlgItemMessage -#define SendDlgItemMessage(hwnd,idx,msg,wparam,lparam) SendMessage(GetDlgItem(hwnd,idx),msg,wparam,lparam) -#endif - -SWELL_API_DEFINE(void,SWELL_BroadcastMessage,(UINT, WPARAM, LPARAM)) - -/* -** PostMessage() -** Notes: -** Queues a message into the application message queue. Note that you should only ever -** send messages to destinations that were created from the main thread. They will be -** processed later from a timer (in the main thread). -** When a window is destroyed any outstanding messages will be discarded for it. -*/ -SWELL_API_DEFINE(BOOL, PostMessage,(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)) - -/* -** SWELL_MessageQueue_Flush(): -** Notes: -** Processes all messages in the message queue. ONLY call from the main thread. -*/ -SWELL_API_DEFINE(void, SWELL_MessageQueue_Flush,()) - -/* -** SWELL_MessageQueue_Clear(): -** Notes: -** Discards all messages from the message queue if h is NULL, otherwise discards all messages -** to h. -*/ -SWELL_API_DEFINE(void, SWELL_MessageQueue_Clear,(HWND h)) - - - -/* -** keyboard/mouse support -*/ - -/* -** SWELL_MacKeyToWindowsKey() -** Pass a keyboard NSEvent *, and it will return a windows VK_ keycode (or ascii), and set flags, -** including (possibly) FSHIFT, FCONTROL (apple key), FALT, and FVIRTKEY. The ctrl key is not checked, -** as SWELL generally encourages this to be used soley for a right mouse button (as modifier). -*/ -#ifdef SWELL_TARGET_OSX -SWELL_API_DEFINE(int, SWELL_MacKeyToWindowsKey,(void *nsevent, int *flags)) -#endif -SWELL_API_DEFINE(int,SWELL_KeyToASCII,(int wParam, int lParam, int *newflags)) - - -/* -** GetAsyncKeyState() -** Notes: only supports MK_LBUTTON, MK_RBUTTON, MK_MBUTTON, VK_SHIFT, VK_MENU, and VK_CONTROL (apple key) for now. -*/ -SWELL_API_DEFINE(WORD, GetAsyncKeyState,(int key)) - -/* -** GetCursorPos(), GetMessagePos() -** Notes: GetMessagePos() currently returns the same coordinates as GetCursorPos(), -** this needs to be fixed. -*/ -SWELL_API_DEFINE(void, GetCursorPos,(POINT *pt)) -SWELL_API_DEFINE(DWORD, GetMessagePos,()) - -/* -** LoadCursor(). -** Notes: hinstance parameter ignored, currently only supports loading some of the predefined values. -** (IDC_SIZEALL etc). If it succeeds value is a NSCursor * -*/ -SWELL_API_DEFINE(HCURSOR, SWELL_LoadCursor,(const char *idx)) -#ifndef LoadCursor -#define LoadCursor(a,x) SWELL_LoadCursor(x) -#endif - -/* -** SetCursor() -** Sets a cursor as active (can be HCURSOR or NSCursor * cast as such). -*/ -#ifdef SetCursor -#undef SetCursor -#endif -#define SetCursor(x) SWELL_SetCursor(x) -SWELL_API_DEFINE(void, SWELL_SetCursor,(HCURSOR curs)) - - -#ifdef GetCursor -#undef GetCursor -#endif -#define GetCursor SWELL_GetCursor - -#ifdef ShowCursor -#undef ShowCursor -#endif -#define ShowCursor SWELL_ShowCursor - -#ifdef SetCursorPos -#undef SetCursorPos -#endif -#define SetCursorPos SWELL_SetCursorPos - -#ifdef ScrollWindowEx -#undef ScrollWindowEx -#endif -#define ScrollWindowEx(a,b,c,d,e,f,g,h) ScrollWindow(a,b,c,d,e) - - -/* -** Globally enable or disable emulating mouse right-click using control+left-click -*/ -SWELL_API_DEFINE(void, SWELL_EnableRightClickEmulate, (BOOL enable)) - - -/* -** GetCursor() gets the actual system cursor, -** SWELL_GetLastSetCursor() gets the last cursor set via SWELL (if they differ than some other window must have changed the cursor) -*/ -SWELL_API_DEFINE(HCURSOR, SWELL_GetCursor,()) -SWELL_API_DEFINE(HCURSOR, SWELL_GetLastSetCursor,()) - -SWELL_API_DEFINE(bool, SWELL_IsCursorVisible, ()) -SWELL_API_DEFINE(int, SWELL_ShowCursor, (BOOL bShow)) -SWELL_API_DEFINE(BOOL, SWELL_SetCursorPos, (int X, int Y)) - -/* -** SWELL_GetViewPort -** Gets screen information, for the screen that contains sourcerect. if wantWork is set -** it excluses the menu bar etc. -*/ -SWELL_API_DEFINE(void, SWELL_GetViewPort,(RECT *r, RECT *sourcerect, bool wantWork)) - -/* -** Clipboard API emulation -** Notes: setting multiple types may not work right -** -*/ -SWELL_API_DEFINE(bool, OpenClipboard,(HWND hwndDlg)) -SWELL_API_DEFINE(void, CloseClipboard,()) -SWELL_API_DEFINE(HANDLE, GetClipboardData,(UINT type)) - -SWELL_API_DEFINE(void, EmptyClipboard,()) -SWELL_API_DEFINE(void, SetClipboardData,(UINT type, HANDLE h)) -SWELL_API_DEFINE(UINT, RegisterClipboardFormat,(const char *desc)) -SWELL_API_DEFINE(UINT, EnumClipboardFormats,(UINT lastfmt)) - -#ifndef CF_TEXT -#define CF_TEXT (RegisterClipboardFormat("SWELL__CF_TEXT")) -#endif - -/* -** GlobalAlloc*() -** These are only currently used by the clipboard system, -** but should work normally. -*/ - -SWELL_API_DEFINE(HANDLE, GlobalAlloc,(int flags, int sz)) -SWELL_API_DEFINE(void *, GlobalLock,(HANDLE h)) -SWELL_API_DEFINE(int, GlobalSize,(HANDLE h)) -SWELL_API_DEFINE(void, GlobalUnlock,(HANDLE h)) -SWELL_API_DEFINE(void, GlobalFree,(HANDLE h)) - - -SWELL_API_DEFINE(HANDLE,CreateThread,(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut)) -SWELL_API_DEFINE(HANDLE,CreateEvent,(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored)) -SWELL_API_DEFINE(HANDLE,CreateEventAsSocket,(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored)) - - -#ifdef _beginthreadex -#undef _beginthreadex -#endif -#define _beginthreadex(a,b,c,d,e,f) ((UINT_PTR)CreateThread(a,b,(unsigned (*)(LPVOID))(c),d,e,(DWORD*)(f))) - -SWELL_API_DEFINE(DWORD,GetCurrentThreadId,()) -SWELL_API_DEFINE(DWORD,WaitForSingleObject,(HANDLE hand, DWORD msTO)) -SWELL_API_DEFINE(DWORD,WaitForAnySocketObject,(int numObjs, HANDLE *objs, DWORD msTO)) // waits for any number of socket objects -SWELL_API_DEFINE(BOOL,CloseHandle,(HANDLE hand)) -SWELL_API_DEFINE(BOOL,SetThreadPriority,(HANDLE evt, int prio)) -SWELL_API_DEFINE(BOOL,SetEvent,(HANDLE evt)) -SWELL_API_DEFINE(BOOL,ResetEvent,(HANDLE evt)) - -#ifdef SWELL_TARGET_OSX -SWELL_API_DEFINE(void,SWELL_EnsureMultithreadedCocoa,()) -SWELL_API_DEFINE(void *, SWELL_InitAutoRelease,()) -SWELL_API_DEFINE(void, SWELL_QuitAutoRelease,(void *p)) -#endif - -SWELL_API_DEFINE(HANDLE,SWELL_CreateProcess,(const char *exe, int nparams, const char **params)) - - -SWELL_API_DEFINE(HINSTANCE,LoadLibraryGlobals,(const char *fileName, bool symbolsAsGlobals)) -SWELL_API_DEFINE(HINSTANCE,LoadLibrary,(const char *fileName)) -SWELL_API_DEFINE(void *,GetProcAddress,(HINSTANCE hInst, const char *procName)) -SWELL_API_DEFINE(BOOL,FreeLibrary,(HINSTANCE hInst)) - -/* -** GDI functions. -** Everything should be all hunky dory, your windows may get WM_PAINT, call -** GetDC()/ReleaseDC(), etc. -** -** Or, there are these helper functions: -*/ - - -/* -** SWELL_CreateMemContext() -** Creates a memory context (that you can get the bits for, below) -** hdc is currently ignored. -*/ -SWELL_API_DEFINE(HDC, SWELL_CreateMemContext,(HDC hdc, int w, int h)) - -/* -** SWELL_DeleteGfxContext() -** Deletes a context created with SWELL_CreateMemContext() (or the internal SWELL_CreateGfxContext) -*/ -SWELL_API_DEFINE(void, SWELL_DeleteGfxContext,(HDC)) - -/* -** SWELL_GetCtxGC() -** Returns the CGContextRef of a HDC -*/ -SWELL_API_DEFINE(void *, SWELL_GetCtxGC,(HDC ctx)) - - -/* -** SWELL_GetCtxFrameBuffer() -** Gets the framebuffer of a memory context. NULL if none available. -*/ -SWELL_API_DEFINE(void *, SWELL_GetCtxFrameBuffer,(HDC ctx)) - - - -/* -** Some utility functions for pushing, setting, and popping the clip region. -*/ -SWELL_API_DEFINE(void, SWELL_PushClipRegion,(HDC ctx)) -SWELL_API_DEFINE(void, SWELL_SetClipRegion,(HDC ctx, RECT *r)) -SWELL_API_DEFINE(void, SWELL_PopClipRegion,(HDC ctx)) - - - -/* -** GDI emulation functions -** todo: document -*/ - -SWELL_API_DEFINE(HFONT, CreateFontIndirect,(LOGFONT *)) -SWELL_API_DEFINE(HFONT, CreateFont,(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, - char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, - char lfQuality, char lfPitchAndFamily, const char *lfFaceName)) - -SWELL_API_DEFINE(HPEN, CreatePen,(int attr, int wid, int col)) -SWELL_API_DEFINE(HBRUSH, CreateSolidBrush,(int col)) -SWELL_API_DEFINE(HPEN, CreatePenAlpha,(int attr, int wid, int col, float alpha)) -SWELL_API_DEFINE(HBRUSH, CreateSolidBrushAlpha,(int col, float alpha)) -SWELL_API_DEFINE(HGDIOBJ, SelectObject,(HDC ctx, HGDIOBJ pen)) -SWELL_API_DEFINE(HGDIOBJ, GetStockObject,(int wh)) -SWELL_API_DEFINE(void, DeleteObject,(HGDIOBJ)) -#ifndef DestroyIcon -#define DestroyIcon(x) DeleteObject(x) -#endif - -#ifdef LineTo -#undef LineTo -#endif -#ifdef SetPixel -#undef SetPixel -#endif -#ifdef FillRect -#undef FillRect -#endif -#ifdef DrawText -#undef DrawText -#endif -#ifdef Polygon -#undef Polygon -#endif - -#define DrawText SWELL_DrawText -#define FillRect SWELL_FillRect -#define LineTo SWELL_LineTo -#define SetPixel SWELL_SetPixel -#define Polygon(a,b,c) SWELL_Polygon(a,b,c) - -SWELL_API_DEFINE(void, SWELL_FillRect,(HDC ctx, RECT *r, HBRUSH br)) -SWELL_API_DEFINE(void, Rectangle,(HDC ctx, int l, int t, int r, int b)) -SWELL_API_DEFINE(void, Ellipse,(HDC ctx, int l, int t, int r, int b)) -SWELL_API_DEFINE(void, SWELL_Polygon,(HDC ctx, POINT *pts, int npts)) -SWELL_API_DEFINE(void, MoveToEx,(HDC ctx, int x, int y, POINT *op)) -SWELL_API_DEFINE(void, LineTo,(HDC ctx, int x, int y)) -SWELL_API_DEFINE(void, SetPixel,(HDC ctx, int x, int y, int c)) -SWELL_API_DEFINE(void, PolyBezierTo,(HDC ctx, POINT *pts, int np)) -SWELL_API_DEFINE(int, SWELL_DrawText,(HDC ctx, const char *buf, int len, RECT *r, int align)) -SWELL_API_DEFINE(void, SetTextColor,(HDC ctx, int col)) -SWELL_API_DEFINE(int, GetTextColor,(HDC ctx)) -SWELL_API_DEFINE(void, SetBkColor,(HDC ctx, int col)) -SWELL_API_DEFINE(void, SetBkMode,(HDC ctx, int col)) - -SWELL_API_DEFINE(void, RoundRect,(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd)) -SWELL_API_DEFINE(void, PolyPolyline,(HDC ctx, POINT *pts, DWORD *cnts, int nseg)) -SWELL_API_DEFINE(BOOL, GetTextMetrics,(HDC ctx, TEXTMETRIC *tm)) -#ifdef SWELL_TARGET_OSX -SWELL_API_DEFINE(void *, GetNSImageFromHICON,(HICON)) -#endif -SWELL_API_DEFINE(BOOL, GetObject, (HICON icon, int bmsz, void *_bm)) -SWELL_API_DEFINE(HICON, CreateIconIndirect, (ICONINFO* iconinfo)) -SWELL_API_DEFINE(HICON, LoadNamedImage,(const char *name, bool alphaFromMask)) -SWELL_API_DEFINE(void, DrawImageInRect,(HDC ctx, HICON img, RECT *r)) -SWELL_API_DEFINE(void, BitBlt,(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode)) -SWELL_API_DEFINE(void, StretchBlt,(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode)) -SWELL_API_DEFINE(int, GetSysColor,(int idx)) -SWELL_API_DEFINE(HBITMAP, CreateBitmap,(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits)) - -SWELL_API_DEFINE(void, SetOpaque, (HWND h, bool isopaque)) -#ifdef SWELL_TARGET_OSX -SWELL_API_DEFINE(void, SWELL_SetViewGL, (HWND h, bool wantGL)) -SWELL_API_DEFINE(bool, SWELL_GetViewGL, (HWND h)) -SWELL_API_DEFINE(bool, SWELL_SetGLContextToView, (HWND h)) // sets GL context to that view, returns TRUE if successs (use NULL to clear GL context) -#endif - -SWELL_API_DEFINE(HDC, BeginPaint,(HWND, PAINTSTRUCT *)) -SWELL_API_DEFINE(BOOL, EndPaint,(HWND, PAINTSTRUCT *)) - -SWELL_API_DEFINE(HDC, GetDC,(HWND)) // use these sparingly! they kinda work but shouldnt be overused!! -SWELL_API_DEFINE(HDC, GetWindowDC,(HWND)) -SWELL_API_DEFINE(void, ReleaseDC,(HWND, HDC)) - -#ifdef __APPLE__ -SWELL_API_DEFINE(void, SWELL_FlushWindow,(HWND)) -#endif - -SWELL_API_DEFINE(void, SWELL_FillDialogBackground,(HDC hdc, RECT *r, int level)) - -SWELL_API_DEFINE(HGDIOBJ,SWELL_CloneGDIObject,(HGDIOBJ a)) - -SWELL_API_DEFINE(int, GetSystemMetrics, (int)) - -SWELL_API_DEFINE(BOOL, DragQueryPoint,(HDROP,LPPOINT)) -SWELL_API_DEFINE(void, DragFinish,(HDROP)) -SWELL_API_DEFINE(UINT, DragQueryFile,(HDROP,UINT,char *,UINT)) - -// source drag/drop - callback is source implementing "create dropped files at droppath" -SWELL_API_DEFINE(void, SWELL_InitiateDragDrop, (HWND, RECT* srcrect, const char* srcfn, void (*callback)(const char* droppath))) -SWELL_API_DEFINE(void,SWELL_InitiateDragDropOfFileList,(HWND, RECT *srcrect, const char **srclist, int srccount, HICON icon)) -SWELL_API_DEFINE(void, SWELL_FinishDragDrop, ()) // cancels any outstanding InitiateDragDrop - - - -// r=NULL to "free" handle -// otherwise r is in hwndPar coordinates -SWELL_API_DEFINE(void,SWELL_DrawFocusRect,(HWND hwndPar, RECT *rct, void **handle)) - - -#ifdef SWELL_TARGET_OSX -SWELL_API_DEFINE(void,SWELL_SetWindowRepre,(HWND hwnd, const char *fn, bool isDirty)) // sets the represented file and edited state -SWELL_API_DEFINE(void,SWELL_PostQuitMessage,(void *sender)) -#endif - -/* -** Functions used by swell-dlggen.h and swell-menugen.h -** No need to really dig into these unless you're working on swell or debugging.. -*/ - -SWELL_API_DEFINE(void, SWELL_MakeSetCurParms,(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit)) - -SWELL_API_DEFINE(HWND, SWELL_MakeButton,(int def, const char *label, int idx, int x, int y, int w, int h, int flags)) -SWELL_API_DEFINE(HWND, SWELL_MakeEditField,(int idx, int x, int y, int w, int h, int flags)) -SWELL_API_DEFINE(HWND, SWELL_MakeLabel,(int align, const char *label, int idx, int x, int y, int w, int h, int flags)) -SWELL_API_DEFINE(HWND, SWELL_MakeControl,(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle)) -SWELL_API_DEFINE(HWND, SWELL_MakeCombo,(int idx, int x, int y, int w, int h, int flags)) -SWELL_API_DEFINE(HWND, SWELL_MakeGroupBox,(const char *name, int idx, int x, int y, int w, int h, int style)) -SWELL_API_DEFINE(HWND, SWELL_MakeCheckBox,(const char *name, int idx, int x, int y, int w, int h, int flags)) -SWELL_API_DEFINE(HWND, SWELL_MakeListBox,(int idx, int x, int y, int w, int h, int styles)) - -SWELL_API_DEFINE(void, SWELL_Menu_AddMenuItem,(HMENU hMenu, const char *name, int idx, int flags)) -SWELL_API_DEFINE(int, SWELL_GenerateMenuFromList,(HMENU hMenu, const void *list, int listsz)) // list is SWELL_MenuGen_Entry - -SWELL_API_DEFINE(void, SWELL_GenerateDialogFromList, (const void *list, int listsz)) - - -SWELL_API_DEFINE(unsigned int, _controlfp,(unsigned int flag, unsigned int mask)) - -SWELL_API_DEFINE(void,SWELL_Internal_PostMessage_Init,()) - - -SWELL_API_DEFINE(HCURSOR,SWELL_LoadCursorFromFile,(const char *fn)) -SWELL_API_DEFINE(void,SWELL_SetWindowWantRaiseAmt,(HWND h, int amt)) - -SWELL_API_DEFINE(void,SWELL_SetListViewFastClickMask,(HWND hList, int mask)) - - -#ifndef __APPLE__ -SWELL_API_DEFINE(void,SWELL_initargs,(int *argc, char ***argv)) -SWELL_API_DEFINE(void,SWELL_RunMessageLoop,()) -#endif - -#ifdef __APPLE__ -SWELL_API_DEFINE(void,SWELL_GenerateGUID,(void *g)) -#endif - -SWELL_API_DEFINE(BOOL,EnumChildWindows,(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam)) - - -SWELL_API_DEFINE(BOOL,SWELL_IsGroupBox,(HWND)) -SWELL_API_DEFINE(BOOL,SWELL_IsButton,(HWND)) -SWELL_API_DEFINE(BOOL,SWELL_IsStaticText,(HWND)) -SWELL_API_DEFINE(void,SWELL_GetDesiredControlSize,(HWND hwnd, RECT *r)) - - -#endif // _WDL_SWELL_H_API_DEFINED_ diff --git a/WDL/swell/swell-gdi-generic.cpp b/WDL/swell/swell-gdi-generic.cpp deleted file mode 100644 index a46cd88a..00000000 --- a/WDL/swell/swell-gdi-generic.cpp +++ /dev/null @@ -1,676 +0,0 @@ - -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic win32 GDI-->lice? translation. - -*/ - -#ifndef SWELL_LICE_GDI -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-internal.h" - -#include "../lice/lice.h" -#include "../mutex.h" -#include "../ptrlist.h" - -#include "swell-gdi-internalpool.h" - - -HDC SWELL_CreateGfxContext(void *c) -{ - HDC__ *ctx=SWELL_GDP_CTX_NEW(); - - - return ctx; -} - -HDC SWELL_CreateMemContext(HDC hdc, int w, int h) -{ - // we could use CGLayer here, but it's 10.4+ and seems to be slower than this -// if (w&1) w++; - void *buf=calloc(w*4,h); - if (!buf) return 0; - - HDC__ *ctx=SWELL_GDP_CTX_NEW(); - ctx->ownedData=buf; - - SetTextColor(ctx,0); - return ctx; -} - - -void SWELL_DeleteGfxContext(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)) - { - if (ct->ownedData) - { - free(ct->ownedData); - } - SWELL_GDP_CTX_DELETE(ct); - } -} -HPEN CreatePen(int attr, int wid, int col) -{ - return CreatePenAlpha(attr,wid,col,1.0f); -} - -HBRUSH CreateSolidBrush(int col) -{ - return CreateSolidBrushAlpha(col,1.0f); -} - -HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) -{ - HGDIOBJ__ *pen=GDP_OBJECT_NEW(); - pen->type=TYPE_PEN; - pen->wid=wid<0?0:wid; -// pen->color=CreateColor(col,alpha); - return pen; -} -HBRUSH CreateSolidBrushAlpha(int col, float alpha) -{ - HGDIOBJ__ *brush=GDP_OBJECT_NEW(); - brush->type=TYPE_BRUSH; -// brush->color=CreateColor(col,alpha); - brush->wid=0; - return brush; -} - -#define FONTSCALE 0.9 -HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, - char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, - char lfQuality, char lfPitchAndFamily, const char *lfFaceName) -{ - HGDIOBJ__ *font=GDP_OBJECT_NEW(); - font->type=TYPE_FONT; - float fontwid=lfHeight; - - - if (!fontwid) fontwid=lfWidth; - if (fontwid<0)fontwid=-fontwid; - - if (fontwid < 2 || fontwid > 8192) fontwid=10; - - return font; -} - - -HFONT CreateFontIndirect(LOGFONT *lf) -{ - return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, - lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, - lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); -} - -void DeleteObject(HGDIOBJ pen) -{ - if (HGDIOBJ_VALID(pen)) - { - HGDIOBJ__ *p=(HGDIOBJ__ *)pen; - if (--p->additional_refcnt < 0) - { - if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) - { - if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) - if (p->wid<0) return; - - GDP_OBJECT_DELETE(p); - } - // JF> don't free unknown objects, this should never happen anyway: else free(p); - } - } -} - - -HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *p=(HGDIOBJ__ *) pen; - HGDIOBJ__ **mod=0; - if (!HDC_VALID(c)||!p) return 0; - - if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen; - else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush; - else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont; - - if (mod) - { - HGDIOBJ__ *np=*mod; - *mod=0; - return np?np:p; - } - - if (!HGDIOBJ_VALID(p)) return 0; - - if (p->type == TYPE_PEN) mod=&c->curpen; - else if (p->type == TYPE_BRUSH) mod=&c->curbrush; - else if (p->type == TYPE_FONT) mod=&c->curfont; - else return 0; - - HGDIOBJ__ *op=*mod; - if (!op) op=(HGDIOBJ__ *)p->type; - if (op != p) - { - *mod=p; - - if (p->type == TYPE_FONT) - { -// CGContextSelectFont(c->ctx,p->fontface,(float)p->wid,kCGEncodingMacRoman); - } - } - return op; -} - - - -void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *b=(HGDIOBJ__ *) br; - if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return; - - if (b->wid<0) return; - - -} - -void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) -{ - xrnd/=3; - yrnd/=3; - POINT pts[10]={ // todo: curves between edges - {x,y+yrnd}, - {x+xrnd,y}, - {x2-xrnd,y}, - {x2,y+yrnd}, - {x2,y2-yrnd}, - {x2-xrnd,y2}, - {x+xrnd,y2}, - {x,y2-yrnd}, - {x,y+yrnd}, - {x+xrnd,y}, -}; - - WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); -} - -void Ellipse(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - //CGRect rect=CGRectMake(l,t,r-l,b-t); - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) - { - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - } -} - -void Rectangle(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - //CGRect rect=CGRectMake(l,t,r-l,b-t); - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - } -} - -HGDIOBJ GetStockObject(int wh) -{ - switch (wh) - { - case NULL_BRUSH: - { - static HGDIOBJ__ br={0,}; - br.type=TYPE_BRUSH; - br.wid=-1; - return &br; - } - case NULL_PEN: - { - static HGDIOBJ__ pen={0,}; - pen.type=TYPE_PEN; - pen.wid=-1; - return &pen; - } - } - return 0; -} - -void Polygon(HDC ctx, POINT *pts, int npts) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && - (!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return; - -// CGContextBeginPath(c->ctx); - // CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); - int x; - for (x = 1; x < npts; x ++) - { - // CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); - } - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - // CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) - { -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); - // CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - } -// CGContextDrawPath(c->ctx,c->curpen && c->curpen->wid>=0 && c->curbrush && c->curbrush->wid>=0 ? kCGPathFillStroke : c->curpen && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); -} - -void MoveToEx(HDC ctx, int x, int y, POINT *op) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (op) - { - op->x = (int) (c->lastpos_x); - op->y = (int) (c->lastpos_y); - } - c->lastpos_x=(float)x; - c->lastpos_y=(float)y; -} - -void PolyBezierTo(HDC ctx, POINT *pts, int np) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); -// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); - int x; - float xp,yp; - for (x = 0; x < np-2; x += 3) - { -/* CGContextAddCurveToPoint(c->ctx, - (float)pts[x].x,(float)pts[x].y, - (float)pts[x+1].x,(float)pts[x+1].y, -*/ - xp=(float)pts[x+2].x; - yp=(float)pts[x+2].y; - } - c->lastpos_x=(float)xp; - c->lastpos_y=(float)yp; -// CGContextStrokePath(c->ctx); -} - - -void SWELL_LineTo(HDC ctx, int x, int y) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); -// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); - float fx=(float)x,fy=(float)y; - -// CGContextAddLineToPoint(c->ctx,fx,fy); - c->lastpos_x=fx; - c->lastpos_y=fy; -// CGContextStrokePath(c->ctx); -} - -void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); - - while (nseg-->0) - { - DWORD cnt=*cnts++; - if (!cnt) continue; - if (!--cnt) { pts++; continue; } - - // CGContextMoveToPoint(c->ctx,(float)pts->x,(float)pts->y); - pts++; - - while (cnt--) - { -// CGContextAddLineToPoint(c->ctx,(float)pts->x,(float)pts->y); - pts++; - } - } -// CGContextStrokePath(c->ctx); -} -void *SWELL_GetCtxGC(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return 0; - return NULL; -} - - -void SWELL_SetPixel(HDC ctx, int x, int y, int c) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - /* CGContextBeginPath(ct->ctx); - CGContextMoveToPoint(ct->ctx,(float)x,(float)y); - CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); - CGContextSetLineWidth(ct->ctx,(float)1.5); - CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); - CGContextStrokePath(ct->ctx); -*/ -} - - -BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) -{ - HDC__ *ct=(HDC__ *)ctx; - if (tm) // give some sane defaults - { - tm->tmInternalLeading=3; - tm->tmAscent=12; - tm->tmDescent=4; - tm->tmHeight=16; - tm->tmAveCharWidth = 10; - } - if (!HDC_VALID(ct)||!tm) return 0; - - return 1; -} - - -int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return 0; - if (r && (align&DT_CALCRECT)) - { - r->top=r->left=0; - r->bottom=10; - r->right = ( buflen < 0 ? strlen(buf) : buflen ) *8; - } - else printf("DrawText: %s\n",buf); - return 10; -} - -void SetBkColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkcol=col; -} - -void SetBkMode(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkmode=col; -} -int GetTextColor(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return -1; - return ct->cur_text_color_int; -} - -void SetTextColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->cur_text_color_int = col; - -} - -HICON LoadNamedImage(const char *name, bool alphaFromMask) -{ - return 0; // todo -} - -void DrawImageInRect(HDC ctx, HICON img, RECT *r) -{ - // todo -} - - -BOOL GetObject(HICON icon, int bmsz, void *_bm) -{ - memset(_bm,0,bmsz); - if (bmsz != sizeof(BITMAP)) return false; - BITMAP *bm=(BITMAP *)_bm; - HGDIOBJ__ *i = (HGDIOBJ__ *)icon; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; - - return false; -/* - NSImage *img = i->bitmapptr; - if (!img) return false; - bm->bmWidth = (int) ([img size].width+0.5); - bm->bmHeight = (int) ([img size].height+0.5); - return true; -*/ -} - - -#define ColorFromNSColor(a,b) (b) -int GetSysColor(int idx) -{ - // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor - switch (idx) - { - case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_3DFACE: - case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); - case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); - case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); - case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); - case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; - case COLOR_INFOBK: return RGB(255,240,200); - case COLOR_INFOTEXT: return RGB(0,0,0); - - } - return 0; -} - -void BitBltAlphaFromMem(HDC hdcOut, int x, int y, int w, int h, void *inbufptr, int inbuf_span, int inbuf_h, int xin, int yin, int mode, bool useAlphaChannel, float opacity) -{ -} - -void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity) -{ -} - -void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) -{ -} - -void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode) -{ -} - -void SWELL_PushClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextSaveGState(ct->ctx); -} - -void SWELL_SetClipRegion(HDC ctx, RECT *r) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); - -} - -void SWELL_PopClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextRestoreGState(ct->ctx); -} - -void *SWELL_GetCtxFrameBuffer(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)) return ct->ownedData; - return 0; -} - - -HDC GetDC(HWND h) -{ - return NULL; -} - -HDC GetWindowDC(HWND h) -{ - return NULL; -} - -void ReleaseDC(HWND h, HDC hdc) -{ -} - -void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) -{ -} - -HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) -{ - if (HGDIOBJ_VALID(a)) - { - a->additional_refcnt++; - return a; - } - return NULL; -} - -HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) -{ - if (!ps) return 0; - memset(ps,0,sizeof(PAINTSTRUCT)); - if (!hwnd) return 0; - - return NULL; -} - - -HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) -{ - return NULL; -} - -HICON CreateIconIndirect(ICONINFO* iconinfo) -{ - return NULL; -} -HIMAGELIST ImageList_CreateEx() -{ - return (HIMAGELIST)new WDL_PtrList; -} -BOOL ImageList_Remove(HIMAGELIST list, int idx) -{ - WDL_PtrList* imglist=(WDL_PtrList*)list; - if (imglist && idx < imglist->GetSize()) - { - if (idx < 0) - { - int x,n=imglist->GetSize(); - for (x=0;xGet(x); - if (a) DeleteObject(a); - } - imglist->Empty(); - } - else - { - HGDIOBJ__ *a = imglist->Get(idx); - imglist->Set(idx, NULL); - if (a) DeleteObject(a); - } - return TRUE; - } - - return FALSE; -} - -void ImageList_Destroy(HIMAGELIST list) -{ - if (!list) return; - WDL_PtrList *p=(WDL_PtrList*)list; - ImageList_Remove(list,-1); - delete p; -} - -int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) -{ - if (!image || !list) return -1; - WDL_PtrList *l=(WDL_PtrList *)list; - - HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; - if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; - - HGDIOBJ__* icon=GDP_OBJECT_NEW(); - icon->type=TYPE_BITMAP; - icon->wid=1; - // todo: copy underlying image - - image = (HICON) icon; - - if (offset<0||offset>=l->GetSize()) - { - l->Add(image); - offset=l->GetSize()-1; - } - else - { - HICON old=l->Get(offset); - l->Set(offset,image); - if (old) DeleteObject(old); - } - return offset; -} - - - - -#endif -#endif // !SWELL_LICE_GDI diff --git a/WDL/swell/swell-gdi-internalpool.h b/WDL/swell/swell-gdi-internalpool.h deleted file mode 100644 index df558d96..00000000 --- a/WDL/swell/swell-gdi-internalpool.h +++ /dev/null @@ -1,194 +0,0 @@ -// used for HDC/HGDIOBJ pooling (to avoid excess heap use), used by swell-gdi.mm and swell-gdi-generic.cpp - -#if defined(_DEBUG) - #define SWELL_GDI_DEBUG -#endif - -static WDL_Mutex *m_ctxpool_mutex; -#ifdef SWELL_GDI_DEBUG - #include - #include "../ptrlist.h" - static WDL_PtrList *m_ctxpool_debug; - static WDL_PtrList *m_objpool_debug; -#else - static HDC__ *m_ctxpool; - static int m_ctxpool_size; - static HGDIOBJ__ *m_objpool; - static int m_objpool_size; -#endif - - - -HDC__ *SWELL_GDP_CTX_NEW() -{ - if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; - - HDC__ *p=NULL; -#ifdef SWELL_GDI_DEBUG - m_ctxpool_mutex->Enter(); - if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList; - if (m_ctxpool_debug->GetSize() > 8192) - { - p = m_ctxpool_debug->Get(0); - m_ctxpool_debug->Delete(0); - memset(p,0,sizeof(*p)); - } - m_ctxpool_mutex->Leave(); -#else - if (m_ctxpool) - { - m_ctxpool_mutex->Enter(); - if ((p=m_ctxpool)) - { - m_ctxpool=p->_next; - m_ctxpool_size--; - memset(p,0,sizeof(*p)); - } - m_ctxpool_mutex->Leave(); - } -#endif - if (!p) - { -// printf("alloc ctx\n"); - p=(HDC__ *)calloc(sizeof(HDC__)+128,1); // extra space in case things want to use it (i.e. swell-gdi-lice does) - } - return p; -} -static void SWELL_GDP_CTX_DELETE(HDC__ *p) -{ - if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; - - if (!p) return; - - if (p->_infreelist) - { -#ifdef SWELL_GDI_DEBUG - assert(!p->_infreelist); -#endif - return; - } - - memset(p,0,sizeof(*p)); - -#ifdef SWELL_GDI_DEBUG - m_ctxpool_mutex->Enter(); - p->_infreelist=true; - if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList; - m_ctxpool_debug->Add(p); - m_ctxpool_mutex->Leave(); -#else - if (m_ctxpool_size<100) - { - m_ctxpool_mutex->Enter(); - p->_infreelist=true; - p->_next = m_ctxpool; - m_ctxpool = p; - m_ctxpool_size++; - m_ctxpool_mutex->Leave(); - } - else - { - // printf("free ctx\n"); - free(p); - } -#endif -} -static HGDIOBJ__ *GDP_OBJECT_NEW() -{ - if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; - HGDIOBJ__ *p=NULL; -#ifdef SWELL_GDI_DEBUG - m_ctxpool_mutex->Enter(); - if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList; - if (m_objpool_debug->GetSize()>8192) - { - p = m_objpool_debug->Get(0); - m_objpool_debug->Delete(0); - memset(p,0,sizeof(*p)); - } - m_ctxpool_mutex->Leave(); -#else - if (m_objpool) - { - m_ctxpool_mutex->Enter(); - if ((p=m_objpool)) - { - m_objpool = p->_next; - m_objpool_size--; - memset(p,0,sizeof(*p)); - } - m_ctxpool_mutex->Leave(); - } -#endif - if (!p) - { - // printf("alloc obj\n"); - p=(HGDIOBJ__ *)calloc(sizeof(HGDIOBJ__),1); - } - return p; -} -static void GDP_OBJECT_DELETE(HGDIOBJ__ *p) -{ - if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; - if (!p) return; - - if (p->_infreelist) - { -#ifdef SWELL_GDI_DEBUG - assert(!p->_infreelist); -#endif - return; - } - - memset(p,0,sizeof(*p)); -#ifdef SWELL_GDI_DEBUG - m_ctxpool_mutex->Enter(); - p->_infreelist = true; - if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList; - m_objpool_debug->Add(p); - m_ctxpool_mutex->Leave(); -#else - if (m_objpool_size<200) - { - m_ctxpool_mutex->Enter(); - p->_infreelist = true; - p->_next = m_objpool; - m_objpool = p; - m_objpool_size++; - m_ctxpool_mutex->Leave(); - } - else - { - // printf("free obj\n"); - free(p); - } -#endif -} - -static bool HGDIOBJ_VALID(HGDIOBJ__ *p, int reqType=0) -{ - if (p == (HGDIOBJ__*)TYPE_PEN || p == (HGDIOBJ__*)TYPE_BRUSH || - p == (HGDIOBJ__*)TYPE_FONT || p == (HGDIOBJ__*)TYPE_BITMAP) return false; -#ifdef SWELL_GDI_DEBUG - if (p) { assert(!p->_infreelist); } -#endif - // insert breakpoints in these parts for debugging - if (p && !p->_infreelist) - { -#ifdef SWELL_GDI_DEBUG - if (reqType) { assert(reqType == p->type); } -#endif - - return !reqType || reqType == p->type; - } - return false; -} - -static bool HDC_VALID(HDC__ *ct) -{ -#ifdef SWELL_GDI_DEBUG - if (ct) { assert(!ct->_infreelist); } -#endif - // insert breakpoints in these parts for debugging - return ct && !ct->_infreelist; -} diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp deleted file mode 100644 index 55382396..00000000 --- a/WDL/swell/swell-gdi-lice.cpp +++ /dev/null @@ -1,1284 +0,0 @@ - -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic win32 GDI-->lice translation. - -*/ - -#ifdef SWELL_LICE_GDI -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-internal.h" - -#include "../mutex.h" -#include "../ptrlist.h" - -#include "swell-gdi-internalpool.h" - - -#ifdef SWELL_FREETYPE -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H - -static bool s_freetype_failed; -static FT_Library s_freetype; // todo: TLS for multithread support? - -#include "../dirscan.h" - -static int utf8char(const char *ptr, unsigned short *charOut) // returns char length -{ - const unsigned char *p = (const unsigned char *)ptr; - unsigned char tc = *p; - - if (tc < 128) - { - if (charOut) *charOut = (unsigned short) tc; - return 1; - } - else if (tc < 0xC2) // invalid chars (subsequent in sequence, or overlong which we disable for) - { - } - else if (tc < 0xE0) // 2 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0) - { - if (charOut) *charOut = ((tc&0x1f)<<6) | (p[1]&0x3f); - return 2; - } - } - else if (tc < 0xF0) // 3 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0) - { - if (charOut) *charOut = ((tc&0xf)<<12) | ((p[1]&0x3f)<<6) | ((p[2]&0x3f)); - return 3; - } - } - else if (tc < 0xF5) // 4 char seq - { - if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0 && p[3] >= 0x80 && p[3] <= 0xC0) - { - if (charOut) *charOut = (unsigned short)' '; // dont support 4 byte sequences yet(ever?) - return 4; - } - } - if (charOut) *charOut = (unsigned short) tc; - return 1; -} - - - -#endif - -HDC SWELL_CreateMemContext(HDC hdc, int w, int h) -{ - LICE_MemBitmap * bm = new LICE_MemBitmap(w,h); - if (!bm) return 0; - - HDC__ *ctx=SWELL_GDP_CTX_NEW(); - ctx->surface = bm; - ctx->surface_offs.x=0; - ctx->surface_offs.y=0; - ctx->dirty_rect_valid=false; - - SetTextColor(ctx,0); - return ctx; -} - - -void SWELL_DeleteGfxContext(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)) - { - delete ct->surface; - ct->surface=0; - SWELL_GDP_CTX_DELETE(ct); - } -} - -HPEN CreatePen(int attr, int wid, int col) -{ - return CreatePenAlpha(attr,wid,col,1.0f); -} - -HBRUSH CreateSolidBrush(int col) -{ - return CreateSolidBrushAlpha(col,1.0f); -} - -HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) -{ - HGDIOBJ__ *pen=GDP_OBJECT_NEW(); - pen->type=TYPE_PEN; - pen->wid=wid<0?0:wid; - pen->color=LICE_RGBA_FROMNATIVE(col); - return pen; -} -HBRUSH CreateSolidBrushAlpha(int col, float alpha) -{ - HGDIOBJ__ *brush=GDP_OBJECT_NEW(); - brush->type=TYPE_BRUSH; - brush->color=LICE_RGBA_FROMNATIVE(col); - brush->wid=0; - return brush; -} - -void SetBkColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkcol=LICE_RGBA_FROMNATIVE(col,255); -} - -void SetBkMode(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkmode=col; -} - -HGDIOBJ GetStockObject(int wh) -{ - switch (wh) - { - case NULL_BRUSH: - { - static HGDIOBJ__ br={0,}; - br.type=TYPE_BRUSH; - br.wid=-1; - return &br; - } - case NULL_PEN: - { - static HGDIOBJ__ pen={0,}; - pen.type=TYPE_PEN; - pen.wid=-1; - return &pen; - } - } - return 0; -} - - -#define FONTSCALE 0.9 -HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, - char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, - char lfQuality, char lfPitchAndFamily, const char *lfFaceName) -{ - HGDIOBJ__ *font=NULL; -#ifdef SWELL_FREETYPE - FT_Face face=NULL; - if (!s_freetype_failed && !s_freetype) s_freetype_failed = !!FT_Init_FreeType(&s_freetype); - if (s_freetype) - { - if (!lfFaceName || !*lfFaceName) lfFaceName = "Arial"; - - int fn_len = strlen(lfFaceName); - - const char *leadpath = "/usr/share/fonts/truetype/msttcorefonts"; // todo: scan subdirs? - char tmp[1024]; - char bestmatch[512]; - bestmatch[0]=0; - snprintf(tmp,sizeof(tmp),"%s/%s.ttf",leadpath,lfFaceName); - FT_New_Face(s_freetype,tmp,0,&face); - if (!face) - { - WDL_DirScan ds; - if (!ds.First(leadpath)) do - { - if (!strnicmp(ds.GetCurrentFN(),lfFaceName,fn_len)) - { - if (!stricmp(ds.GetCurrentFN()+fn_len,".ttf")) - { - snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,ds.GetCurrentFN()); - FT_New_Face(s_freetype,tmp,0,&face); - } - else - { - // todo look for italic/bold/etc too - int sl = strlen(ds.GetCurrentFN()); - if (sl > 4 && !stricmp(ds.GetCurrentFN() + sl - 4, ".ttf") && (!bestmatch[0] || sl < strlen(bestmatch))) - { - lstrcpyn(bestmatch,ds.GetCurrentFN(),sizeof(bestmatch)); - } - } - } - } while (!face && !ds.Next()); - if (!face && bestmatch[0]) - { - snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,bestmatch); - FT_New_Face(s_freetype,tmp,0,&face); - } - } - if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/freefont/FreeSans.ttf",0,&face); - if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",0,&face); - } - - if (face) - { - font = GDP_OBJECT_NEW(); - font->type=TYPE_FONT; - font->fontface = face; - ////unsure here - if (lfWidth<0) lfWidth=-lfWidth; - if (lfHeight<0) lfHeight=-lfHeight; - FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi -// FT_Set_Pixel_Sizes(face,0,lfHeight); - } -#else - font->type=TYPE_FONT; -#endif - - return font; -} - - -HFONT CreateFontIndirect(LOGFONT *lf) -{ - return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, - lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, - lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); -} - -void DeleteObject(HGDIOBJ pen) -{ - if (HGDIOBJ_VALID(pen)) - { - HGDIOBJ__ *p=(HGDIOBJ__ *)pen; - if (--p->additional_refcnt < 0) - { - if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) - { - if (p->type == TYPE_FONT) - { -#ifdef SWELL_FREETYPE - if (p->fontface) - { - FT_Done_Face((FT_Face)p->fontface); - p->fontface = 0; - } -#endif - } - else if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) - { - if (p->wid<0) return; - } - - GDP_OBJECT_DELETE(p); - } - // JF> don't free unknown objects, this should never happen anyway: else free(p); - } - } -} - - -HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *p= pen; - HGDIOBJ__ **mod=0; - if (!HDC_VALID(c)||!p) return 0; - - if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen; - else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush; - else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont; - - if (mod) - { - HGDIOBJ__ *np=*mod; - *mod=0; - return np?np:p; - } - - if (!HGDIOBJ_VALID(p)) return 0; - - if (p->type == TYPE_PEN) mod=&c->curpen; - else if (p->type == TYPE_BRUSH) mod=&c->curbrush; - else if (p->type == TYPE_FONT) mod=&c->curfont; - else return 0; - - HGDIOBJ__ *op=*mod; - if (!op) op=(HGDIOBJ__ *)p->type; - if (op != p) - { - *mod=p; - } - return op; -} - - -static void swell_DirtyContext(HDC__ *out, int x1, int y1, int x2, int y2) -{ - if (x2surface_offs.x; - x2+=out->surface_offs.x; - y1+=out->surface_offs.y; - y2+=out->surface_offs.y; - - if (!out->dirty_rect_valid) - { - out->dirty_rect_valid=true; - out->dirty_rect.left = x1; - out->dirty_rect.top = y1; - out->dirty_rect.right = x2; - out->dirty_rect.bottom = y2; - } - else - { - if (out->dirty_rect.left > x1) out->dirty_rect.left=x1; - if (out->dirty_rect.top > y1) out->dirty_rect.top = y1; - if (out->dirty_rect.right < x2) out->dirty_rect.right = x2; - if (out->dirty_rect.bottom < y2) out->dirty_rect.bottom = y2; - } -} - - -void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *b=(HGDIOBJ__ *) br; - if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return; - if (!c->surface) return; - - if (b->wid<0) return; - LICE_FillRect(c->surface, - r->left+c->surface_offs.x, - r->top+c->surface_offs.y, - r->right-r->left,r->bottom-r->top,b->color,1.0f,LICE_BLIT_MODE_COPY); - -} - -void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) -{ - xrnd/=3; - yrnd/=3; - POINT pts[10]={ // todo: curves between edges - {x,y+yrnd}, - {x+xrnd,y}, - {x2-xrnd,y}, - {x2,y+yrnd}, - {x2,y2-yrnd}, - {x2-xrnd,y2}, - {x+xrnd,y2}, - {x,y2-yrnd}, - {x,y+yrnd}, - {x+xrnd,y}, -}; - - WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); -} - -void Ellipse(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - //CGRect rect=CGRectMake(l,t,r-l,b-t); - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) - { - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - } -} - -void Rectangle(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - //CGRect rect=CGRectMake(l,t,r-l,b-t); - - l += c->surface_offs.x; - t += c->surface_offs.y; - r += c->surface_offs.x; - b += c->surface_offs.y; - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - LICE_FillRect(c->surface,l,t,r-l,b-t,c->curbrush->color,1.0f,LICE_BLIT_MODE_COPY); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - LICE_DrawRect(c->surface,l,t,r-l,b-t,c->curpen->color,1.0f,LICE_BLIT_MODE_COPY); - } -} - -void Polygon(HDC ctx, POINT *pts, int npts) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && - (!HGDIOBJ_VALID(c->curpen,TYPE_PEN) ||c->curpen->wid<0)) || npts<2) return; - -// CGContextBeginPath(c->ctx); - // CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); - int x; - for (x = 1; x < npts; x ++) - { - // CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); - } - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - // CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) - { -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); - // CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - } -// CGContextDrawPath(c->ctx,c->curpen && c->curpen->wid>=0 && c->curbrush && c->curbrush->wid>=0 ? kCGPathFillStroke : c->curpen && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); -} - -void MoveToEx(HDC ctx, int x, int y, POINT *op) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (op) - { - op->x = (int) (c->lastpos_x); - op->y = (int) (c->lastpos_y); - } - c->lastpos_x=(float)x; - c->lastpos_y=(float)y; -} - -void PolyBezierTo(HDC ctx, POINT *pts, int np) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); -// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); - int x; - float xp,yp; - for (x = 0; x < np-2; x += 3) - { -/* CGContextAddCurveToPoint(c->ctx, - (float)pts[x].x,(float)pts[x].y, - (float)pts[x+1].x,(float)pts[x+1].y, -*/ - xp=(float)pts[x+2].x; - yp=(float)pts[x+2].y; - } - c->lastpos_x=(float)xp; - c->lastpos_y=(float)yp; -// CGContextStrokePath(c->ctx); -} - - -void SWELL_LineTo(HDC ctx, int x, int y) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); -// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); - float fx=(float)x,fy=(float)y; - - int dx=c->surface_offs.x; - int dy=c->surface_offs.y; - LICE_Line(c->surface,x+dx,y+dy,(int)c->lastpos_x+dx,(int)c->lastpos_y+dy,c->curpen->color,1.0f,LICE_BLIT_MODE_COPY,false); - -// CGContextAddLineToPoint(c->ctx,fx,fy); - c->lastpos_x=fx; - c->lastpos_y=fy; -// CGContextStrokePath(c->ctx); -} - -void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; - -// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); -// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - -// CGContextBeginPath(c->ctx); - - while (nseg-->0) - { - DWORD cnt=*cnts++; - if (!cnt) continue; - if (!--cnt) { pts++; continue; } - - // CGContextMoveToPoint(c->ctx,(float)pts->x,(float)pts->y); - pts++; - - while (cnt--) - { -// CGContextAddLineToPoint(c->ctx,(float)pts->x,(float)pts->y); - pts++; - } - } -// CGContextStrokePath(c->ctx); -} -void *SWELL_GetCtxGC(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return 0; - return NULL; -} - - -void SWELL_SetPixel(HDC ctx, int x, int y, int c) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - /* CGContextBeginPath(ct->ctx); - CGContextMoveToPoint(ct->ctx,(float)x,(float)y); - CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); - CGContextSetLineWidth(ct->ctx,(float)1.5); - CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); - CGContextStrokePath(ct->ctx); -*/ -} - -#ifdef SWELL_FREETYPE -HFONT SWELL_GetDefaultFont() -{ - static HFONT def; - if (!def) - { - def = CreateFont(12,0,0,0,0,0,0,0,0,0,0,0,0,"Arial"); // todo better defaults - } - return def; -} -#endif - -BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) -{ - HDC__ *ct=(HDC__ *)ctx; - if (tm) // give some sane defaults - { - tm->tmInternalLeading=0; - tm->tmAscent=8; - tm->tmDescent=0; - tm->tmHeight=8; - tm->tmAveCharWidth = 8; - } - if (!HDC_VALID(ct)||!tm) return 0; - -#ifdef SWELL_FREETYPE - HGDIOBJ__ *font = HGDIOBJ_VALID(ct->curfont,TYPE_FONT) ? ct->curfont : SWELL_GetDefaultFont(); - if (font && font->fontface) - { - FT_Face face=(FT_Face) font->fontface; - tm->tmAscent = face->size->metrics.ascender/64; - tm->tmDescent = face->size->metrics.descender/64; - tm->tmHeight = face->size->metrics.height/64; - tm->tmAveCharWidth = face->size->metrics.max_advance/64; - tm->tmInternalLeading=0; - } -#endif - - return 1; -} - - -int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) -{ - const char *obuf=buf; - HDC__ *ct=(HDC__ *)ctx; - if (!r) return 0; - - int lineh = 8; - int charw = 8; - - HGDIOBJ__ *font = NULL; -#ifdef SWELL_FREETYPE - int ascent=0; - font = HDC_VALID(ct) && HGDIOBJ_VALID(ct->curfont,TYPE_FONT) ? ct->curfont : SWELL_GetDefaultFont(); - FT_Face face = NULL; - if (font && font->fontface) - { - face=(FT_Face)font->fontface; - lineh = face->size->metrics.height/64; - ascent = face->size->metrics.ascender/64; - charw = face->size->metrics.max_advance/64; - } -#endif - - if (align&DT_CALCRECT) - { - if (!font && (align&DT_SINGLELINE)) - { - r->right = r->left + ( buflen < 0 ? strlen(buf) : buflen ) * charw; - int h = r->right ? lineh:0; - r->bottom = r->top+h; - return h; - } - - int xpos=0; - int ypos=0; - - r->bottom=r->top; - bool in_prefix=false; - while (buflen && *buf) // if buflen<0, go forever - { - unsigned short c=0; - int charlen = utf8char(buf,&c); - buf+=charlen; - if (buflen > 0) - { - buflen -= charlen; - if (buflen < 0) buflen=0; - } - if (!c) break; - - if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) - { - in_prefix = true; - continue; - } - in_prefix=false; - - if (c == '\n') { ypos += lineh; xpos=0; } - else if (c != '\r') - { - if (font) - { -#ifdef SWELL_FREETYPE - if (!FT_Load_Char(face, c, FT_LOAD_DEFAULT) && face->glyph) - { - // measure character - FT_GlyphSlot g = face->glyph; - int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; - if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; - if (r->left+rext > r->right) r->right = r->left+rext; - xpos += g->metrics.horiAdvance/64; - - int bext = r->top + ypos + ascent + (g->metrics.height - g->metrics.horiBearingY)/64; - if (bext > r->bottom) r->bottom = bext; - continue; - } - } -#endif - xpos += c=='\t' ? charw*5 : charw; - if (r->top + ypos + lineh > r->bottom) r->bottom = r->top+ypos+lineh; - if (r->left+xpos>r->right) r->right=r->left+xpos; - } - } - return r->bottom-r->top; - } - if (!HDC_VALID(ct)) return 0; - - RECT use_r = *r; - use_r.left += ct->surface_offs.x; - use_r.right += ct->surface_offs.x; - use_r.top += ct->surface_offs.y; - use_r.bottom += ct->surface_offs.y; - - int xpos = use_r.left; - int ypos = use_r.top; - if (align&(DT_CENTER|DT_VCENTER|DT_RIGHT|DT_BOTTOM)) - { - RECT tr={0,}; - DrawText(ctx,buf,buflen,&tr,align|DT_CALCRECT); - - if (align&DT_CENTER) - xpos -= ((tr.right-tr.left) - (use_r.right-use_r.left))/2; - else if (align&DT_RIGHT) - xpos = use_r.right - (tr.right-tr.left); - - if (align&DT_VCENTER) - ypos -= ((tr.bottom-tr.top) - (use_r.bottom-use_r.top))/2; - else if (align&DT_BOTTOM) - ypos = use_r.bottom - (tr.bottom-tr.top); - } - LICE_IBitmap *surface = ct->surface; - int fgcol = ct->cur_text_color_int; - int bgcol = ct->curbkcol; - int bgmode = ct->curbkmode; - - - int clip_x1=max(use_r.left,0), clip_y1 = max(use_r.top,0); - int clip_w=0, clip_h=0; - if (surface) - { - clip_w = min(use_r.right,surface->getWidth())-clip_x1; - clip_h = min(use_r.bottom,surface->getHeight())-clip_y1; - if (clip_w<0)clip_w=0; - if (clip_h<0)clip_h=0; - } - - LICE_SubBitmap clipbm(surface,clip_x1,clip_y1,clip_w,clip_h); - if (surface && !(align&DT_NOCLIP)) { surface = &clipbm; xpos-=clip_x1; ypos-=clip_y1; } - - int left_xpos = xpos,ysize=0,max_xpos=0; - int start_ypos = ypos; - bool in_prefix=false; - - while (buflen && *buf) - { - unsigned short c=0; - int charlen = utf8char(buf,&c); - if (buflen>0) - { - buflen -= charlen; - if (buflen<0) buflen=0; - } - buf+=charlen; - - bool doUl=in_prefix; - - if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) - { - in_prefix = true; - continue; - } - in_prefix=false; - - if (c=='\n' && !(align&DT_SINGLELINE)) { xpos=left_xpos; ypos+=lineh; } - else if (c=='\r') {} - else - { - bool needr=true; - if (font) - { -#ifdef SWELL_FREETYPE - if (!FT_Load_Char(face, c, FT_LOAD_RENDER) && face->glyph) - { - FT_GlyphSlot g = face->glyph; - if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,g->metrics.horiAdvance/64,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); - - LICE_DrawGlyphEx(surface,xpos+g->bitmap_left,ypos+ascent-g->bitmap_top,fgcol,(LICE_pixel_chan *)g->bitmap.buffer,g->bitmap.width,g->bitmap.pitch,g->bitmap.rows,1.0f,LICE_BLIT_MODE_COPY); - - int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; - if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; - if (rext > max_xpos) max_xpos=rext; - xpos += g->metrics.horiAdvance/64; - int bext = ypos + lineh + (g->metrics.height - g->metrics.horiBearingY)/64; - if (ysize < bext) ysize=bext; - needr=false; - } -#endif - } - - if (needr) - { - if (c=='\t') - { - if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw*5,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); - xpos+=charw*5; - if (ysize < ypos+lineh) ysize=ypos+lineh; - } - else - { - if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); - LICE_DrawChar(surface,xpos,ypos,c,fgcol,1.0f,LICE_BLIT_MODE_COPY); - if (doUl) LICE_Line(surface,xpos,ypos+lineh+1,xpos+charw,ypos+lineh+1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - - if (ysize < ypos+lineh+(doUl ? 2:1)) ysize=ypos+lineh+(doUl ? 2:1); - xpos+=charw; - } - } - } - if(xpos>max_xpos)max_xpos=xpos; - } - if (surface==&clipbm) - swell_DirtyContext(ct,clip_x1+left_xpos,clip_y1+start_ypos,clip_x1+max_xpos,clip_y1+start_ypos+ysize); - else - swell_DirtyContext(ct,left_xpos,start_ypos,max_xpos,start_ypos+ysize); - return ysize; -} - - -int GetTextColor(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return -1; - return ct->cur_text_color_int; -} -void SetTextColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->cur_text_color_int = LICE_RGBA_FROMNATIVE(col,255); - -} - - -////////// todo: some sort of HICON emul - -HICON LoadNamedImage(const char *name, bool alphaFromMask) -{ - return 0; // todo -} - -void DrawImageInRect(HDC ctx, HICON img, RECT *r) -{ - // todo -} - - -BOOL GetObject(HICON icon, int bmsz, void *_bm) -{ - memset(_bm,0,bmsz); - if (bmsz != sizeof(BITMAP)) return false; - BITMAP *bm=(BITMAP *)_bm; - HGDIOBJ__ *i = (HGDIOBJ__ *)icon; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; - - return false; -/* - NSImage *img = i->bitmapptr; - if (!img) return false; - bm->bmWidth = (int) ([img size].width+0.5); - bm->bmHeight = (int) ([img size].height+0.5); - return true; -*/ -} - - -//////////////////////////////////// - -#define ColorFromNSColor(a,b) (b) -int GetSysColor(int idx) -{ - // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor - switch (idx) - { - case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_3DFACE: - case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); - case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); - case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); - case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); - case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; - case COLOR_INFOBK: return RGB(255,240,200); - case COLOR_INFOTEXT: return RGB(0,0,0); - - } - return 0; -} - -void BitBltAlphaFromMem(HDC hdcOut, int x, int y, int w, int h, void *inbufptr, int inbuf_span, int inbuf_h, int xin, int yin, int mode, bool useAlphaChannel, float opacity) -{ - // todo: use LICE_WrapperBitmap? -} - -void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity) -{ - HDC__ *in = (HDC__ *)hdcIn; - HDC__ *out = (HDC__ *)hdcOut; - if (!HDC_VALID(out) || !HDC_VALID(in)) return; - if (!in->surface || !out->surface) return; - LICE_Blit(out->surface,in->surface, - x+out->surface_offs.x,y+out->surface_offs.y, - xin+in->surface_offs.x,yin+in->surface_offs.y,w,h, - opacity,LICE_BLIT_MODE_COPY|(useAlphaChannel?LICE_BLIT_USE_ALPHA:0)); - swell_DirtyContext(out,x,y,x+w,y+h); -} - -void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) -{ - HDC__ *in = (HDC__ *)hdcIn; - HDC__ *out = (HDC__ *)hdcOut; - if (!HDC_VALID(out) || !HDC_VALID(in)) return; - if (!in->surface || !out->surface) return; - LICE_Blit(out->surface,in->surface, - x+out->surface_offs.x,y+out->surface_offs.y, - xin+in->surface_offs.x,yin+in->surface_offs.y,w,h, - 1.0f,LICE_BLIT_MODE_COPY); - swell_DirtyContext(out,x,y,x+w,y+h); -} - -void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode) -{ -} - -void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) -{ -} - -HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) -{ - if (HGDIOBJ_VALID(a)) - { - a->additional_refcnt++; - return a; - } - return NULL; -} - -void SWELL_PushClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextSaveGState(ct->ctx); -} - -void SWELL_SetClipRegion(HDC ctx, RECT *r) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); - -} - -void SWELL_PopClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; -// if (ct && ct->ctx) CGContextRestoreGState(ct->ctx); -} - -void *SWELL_GetCtxFrameBuffer(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)&&ct->surface) return ct->surface->getBits(); - return 0; -} - - - -struct swell_gdpLocalContext -{ - HDC__ ctx; - RECT clipr; -}; - - - -HDC SWELL_internalGetWindowDC(HWND h, bool calcsize_on_first) -{ - if (!h) return NULL; - - int xoffs=0,yoffs=0; - int wndw = h->m_position.right-h->m_position.left; - int wndh = h->m_position.bottom-h->m_position.top; - - HWND starth = h; - while (h) - { - if ((calcsize_on_first || h!=starth) && h->m_wndproc) - { - RECT r,r2; - GetWindowContentViewRect(h,&r); - r2=r; - h->m_wndproc(h,WM_NCCALCSIZE,FALSE,(LPARAM)&r); - - // todo: handle left edges and adjust postions/etc accordingly - if (h==starth) // if initial window, adjust rects to client area (this implies calcsize_on_first being false) - { - wndw=r.right-r.left; - wndh=r.bottom-r.top; - } - yoffs += r.top-r2.top; - xoffs += r.left-r2.left; - } - if (h->m_backingstore) break; // found our target window - - xoffs += h->m_position.left; - yoffs += h->m_position.top; - h = h->m_parent; - } - if (!h) return NULL; - - swell_gdpLocalContext *p = (swell_gdpLocalContext*)SWELL_GDP_CTX_NEW(); - // todo: GDI defaults? - p->ctx.surface=new LICE_SubBitmap(h->m_backingstore,xoffs,yoffs,wndw,wndh); - if (xoffs<0) p->ctx.surface_offs.x = xoffs; - if (yoffs<0) p->ctx.surface_offs.y = yoffs; - p->clipr.left=xoffs; - p->clipr.top=yoffs; - p->clipr.right=xoffs + p->ctx.surface->getWidth(); - p->clipr.bottom=yoffs + p->ctx.surface->getHeight(); - - return (HDC)p; -} -HDC GetWindowDC(HWND h) -{ - return SWELL_internalGetWindowDC(h,0); -} - -HDC GetDC(HWND h) -{ - return SWELL_internalGetWindowDC(h,1); -} - -void ReleaseDC(HWND h, HDC hdc) -{ - if (!h || !HDC_VALID(hdc)) return; - swell_gdpLocalContext *p = (swell_gdpLocalContext*)hdc; - - - if (!h->m_paintctx) - { - // handle blitting? - HWND par = h; - while (par && !par->m_backingstore) par=par->m_parent; - void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect); - if (par) - { - if (p->ctx.dirty_rect_valid) - { - RECT r = p->clipr, dr=p->ctx.dirty_rect; - dr.left += r.left; - dr.top += r.top; - dr.right += r.left; - dr.bottom += r.top; -#if 1 - if (dr.left > r.left) r.left=dr.left; - if (dr.top > r.top) r.top=dr.top; - if (dr.right < r.right) r.right=dr.right; - if (dr.bottom < r.bottom) r.bottom=dr.bottom; -#endif - - if (r.topctx.surface; - SWELL_GDP_CTX_DELETE(hdc); -} - - - -HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) -{ - if (!ps) return 0; - memset(ps,0,sizeof(PAINTSTRUCT)); - if (!hwnd) return 0; - if (!hwnd->m_paintctx) return NULL; - - swell_gdpLocalContext *ctx = (swell_gdpLocalContext *)hwnd->m_paintctx; - ps->rcPaint = ctx->clipr; - ps->hdc = &ctx->ctx; - return &ctx->ctx; -} - - -// paint hwnd into bmout, where bmout points at bmout_xpos,bmout_ypos in window coordinates -void SWELL_internalLICEpaint(HWND hwnd, LICE_IBitmap *bmout, int bmout_xpos, int bmout_ypos, bool forceref) -{ - // todo: check to see if any children completely intersect clip region, if so then we don't need to render ourselves - // todo: opaque flag for windows? (to disable above behavior) - // todo: implement/use per-window backing store. - // we would want to only really use them for top level windows, and on those, only update windows (and children of windows) who had backingstore invalidated. - if (hwnd->m_invalidated) forceref=true; - - if (forceref || hwnd->m_child_invalidated) - { - swell_gdpLocalContext ctx={0,}; // todo set up gdi context defaults? - ctx.ctx.surface = bmout; - ctx.ctx.surface_offs.x = -bmout_xpos; - ctx.ctx.surface_offs.y = -bmout_ypos; - ctx.clipr.left = bmout_xpos; - ctx.clipr.top = bmout_ypos; - ctx.clipr.right = ctx.clipr.left + bmout->getWidth(); - ctx.clipr.bottom = ctx.clipr.top + bmout->getHeight(); - - void *oldpaintctx = hwnd->m_paintctx; - if (forceref) hwnd->m_paintctx = &ctx; - - LICE_SubBitmap tmpsub(NULL,0,0,0,0); - if (hwnd->m_wndproc) // this happens after m_paintctx is set -- that way GetWindowDC()/GetDC()/ReleaseDC() know to not actually update the screen - { - RECT r,r2; - GetWindowContentViewRect(hwnd,&r); - r.right-=r.left; r.bottom-=r.top; r.left=r.top=0; - r2=r; - hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&r); - if (forceref) hwnd->m_wndproc(hwnd,WM_NCPAINT,(WPARAM)1,0); - - if (r.left!=r2.left) {} // todo: adjust drawing offsets, clip rects, accordingly - if (r.top!=r2.top) {} // todo: adjust drawing offsets, clip rects, accordingly - int dx = r.left-r2.left,dy=r.top-r2.top; - // dx,dy is offset from the window's root of - bmout_xpos -= dx; - bmout_ypos -= dy; - - if (dx||dy) - { - tmpsub.m_parent = ctx.ctx.surface; - tmpsub.m_x = dx; - tmpsub.m_y = dy; - tmpsub.m_w = ctx.ctx.surface->getWidth()-dx; - tmpsub.m_h = ctx.ctx.surface->getHeight()-dy; - if (tmpsub.m_w<0) tmpsub.m_w=0; - if (tmpsub.m_h<0) tmpsub.m_h=0; - ctx.ctx.surface_offs.x += dx; - ctx.ctx.surface_offs.y += dy; - ctx.ctx.surface = &tmpsub; - - ctx.clipr.left-=dx; - ctx.clipr.top-=dy; - ctx.clipr.right-=dx; - ctx.clipr.bottom-=dy; - } - - // adjust clip rects for right/bottom extents - int newr = r.right-r.left; - if (ctx.clipr.right > newr) ctx.clipr.right=newr; - int newb = r.bottom-r.top; - if (ctx.clipr.bottom > newb) ctx.clipr.bottom=newb; - } - - // paint - if (forceref) - { - if (hwnd->m_wndproc && ctx.clipr.right > ctx.clipr.left && ctx.clipr.bottom > ctx.clipr.top) - { - hwnd->m_wndproc(hwnd,WM_PAINT,(WPARAM)&ctx,0); - } - - hwnd->m_paintctx = oldpaintctx; - - // it might be good to blit here on some OSes, rather than from the top level caller... - hwnd->m_invalidated=false; - } - } - - if (forceref || hwnd->m_child_invalidated) - { - HWND h = hwnd->m_children; - while (h && h->m_next) h=h->m_next; - while (h) // go through list backwards (first in list = top of Z order) - { - if (h->m_visible && (forceref || h->m_invalidated||h->m_child_invalidated)) - { - int width = h->m_position.right - h->m_position.left, height = h->m_position.bottom - h->m_position.top; // max width possible for this window - int xp = h->m_position.left - bmout_xpos, yp = h->m_position.top - bmout_ypos; - - // if xp/yp < 0, that means that the clip region starts inside the window, so we need to pass a positive render offset, and decrease the potential draw width - // if xp/yp > 0, then the clip region starts before the window, so we use the subbitmap and pass 0 for the offset parm - int subx = 0, suby=0; - if (xp<0) width+=xp; - else { subx=xp; xp=0; } - - if (yp<0) height+=yp; - else { suby=yp; yp=0; } - - LICE_SubBitmap subbm(bmout,subx,suby,width,height); // the right/bottom will automatically be clipped to the clip rect etc - if (subbm.getWidth()>0 && subbm.getHeight()>0) - SWELL_internalLICEpaint(h,&subbm,-xp,-yp,forceref); - } - h = h->m_prev; - } - } - hwnd->m_child_invalidated=false; -} - -HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) -{ - return NULL; -} - -HICON CreateIconIndirect(ICONINFO* iconinfo) -{ - if (!iconinfo || !iconinfo->fIcon) return 0; - HGDIOBJ__* i=iconinfo->hbmColor; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP) ) return 0; -/* - if (!i->bitmapptr) return 0; - HGDIOBJ__* icon=GDP_OBJECT_NEW(); - icon->type=TYPE_BITMAP; - icon->wid=1; - return icon; -*/ - return NULL; -} - -HIMAGELIST ImageList_CreateEx() -{ - return (HIMAGELIST)new WDL_PtrList; -} - -BOOL ImageList_Remove(HIMAGELIST list, int idx) -{ - WDL_PtrList* imglist=(WDL_PtrList*)list; - if (imglist && idx < imglist->GetSize()) - { - if (idx < 0) - { - int x,n=imglist->GetSize(); - for (x=0;xGet(x); - if (a) DeleteObject(a); - } - imglist->Empty(); - } - else - { - HGDIOBJ__ *a = imglist->Get(idx); - imglist->Set(idx, NULL); - if (a) DeleteObject(a); - } - return TRUE; - } - - return FALSE; -} - -void ImageList_Destroy(HIMAGELIST list) -{ - if (!list) return; - WDL_PtrList *p=(WDL_PtrList*)list; - ImageList_Remove(list,-1); - delete p; -} - -int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) -{ - if (!image || !list) return -1; - WDL_PtrList *l=(WDL_PtrList *)list; - - HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; - if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; - - HGDIOBJ__* icon=GDP_OBJECT_NEW(); - icon->type=TYPE_BITMAP; - icon->wid=1; - // todo: copy underlying image - - image = (HICON) icon; - - if (offset<0||offset>=l->GetSize()) - { - l->Add(image); - offset=l->GetSize()-1; - } - else - { - HICON old=l->Get(offset); - l->Set(offset,image); - if (old) DeleteObject(old); - } - return offset; -} - - - -#endif - -#endif // SWELL_LICE_GDI diff --git a/WDL/swell/swell-gdi.mm b/WDL/swell/swell-gdi.mm deleted file mode 100644 index 8ba5c863..00000000 --- a/WDL/swell/swell-gdi.mm +++ /dev/null @@ -1,1530 +0,0 @@ - -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic win32 GDI-->Quartz translation. It uses features that require OS X 10.4+ - -*/ - -#ifndef SWELL_PROVIDED_BY_APP - -#import -#import -#import -#import -#include "swell.h" -#include "swell-internal.h" - -#include "../mutex.h" - - -static bool IsCoreTextSupported() -{ -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - static char is105; - if (!is105) - { - SInt32 v=0x1040; - Gestalt(gestaltSystemVersion,&v); - is105 = v>=0x1050 ? 1 : -1; - } - - return is105 > 0 && CTFontCreateWithName && CTLineDraw && CTFramesetterCreateWithAttributedString && CTFramesetterCreateFrame && - CTFrameGetLines && CTLineGetTypographicBounds && CTLineCreateWithAttributedString; -#else - // targetting 10.5+, CT is always valid - return true; -#endif -} - -static CTFontRef GetCoreTextDefaultFont() -{ - static CTFontRef deffr; - static bool ok; - if (!ok) - { - ok=true; - if (IsCoreTextSupported()) - { - deffr=(CTFontRef) [[NSFont labelFontOfSize:10.0] retain]; - } - } - return deffr; -} - - -static NSString *CStringToNSString(const char *str) -{ - if (!str) str=""; - NSString *ret; - - ret=(NSString *)CFStringCreateWithCString(NULL,str,kCFStringEncodingUTF8); - if (ret) return ret; - ret=(NSString *)CFStringCreateWithCString(NULL,str,kCFStringEncodingASCII); - return ret; -} - - -static CGColorRef CreateColor(int col, float alpha=1.0f) -{ - static CGColorSpaceRef cspace; - - if (!cspace) cspace=CGColorSpaceCreateDeviceRGB(); - - CGFloat cols[4]={GetRValue(col)/255.0,GetGValue(col)/255.0,GetBValue(col)/255.0,alpha}; - CGColorRef color=CGColorCreate(cspace,cols); - return color; -} - - -#include "swell-gdi-internalpool.h" - - -HDC SWELL_CreateGfxContext(void *c) -{ - HDC__ *ctx=SWELL_GDP_CTX_NEW(); - NSGraphicsContext *nsc = (NSGraphicsContext *)c; -// if (![nsc isFlipped]) -// nsc = [NSGraphicsContext graphicsContextWithGraphicsPort:[nsc graphicsPort] flipped:YES]; - - ctx->ctx=(CGContextRef)[nsc graphicsPort]; -// CGAffineTransform f={1,0,0,-1,0,0}; - //CGContextSetTextMatrix(ctx->ctx,f); - //SetTextColor(ctx,0); - - // CGContextSelectFont(ctx->ctx,"Arial",12.0,kCGEncodingMacRoman); - return ctx; -} - -#define ALIGN_EXTRA 63 -static void *ALIGN_FBUF(void *inbuf) -{ - const UINT_PTR extra = ALIGN_EXTRA; - return (void *) (((UINT_PTR)inbuf+extra)&~extra); -} - -HDC SWELL_CreateMemContext(HDC hdc, int w, int h) -{ - void *buf=calloc(w*4*h+ALIGN_EXTRA,1); - if (!buf) return 0; - CGColorSpaceRef cs=CGColorSpaceCreateDeviceRGB(); - CGContextRef c=CGBitmapContextCreate(ALIGN_FBUF(buf),w,h,8,w*4,cs, kCGImageAlphaNoneSkipFirst); - CGColorSpaceRelease(cs); - if (!c) - { - free(buf); - return 0; - } - - - CGContextTranslateCTM(c,0.0,h); - CGContextScaleCTM(c,1.0,-1.0); - - - HDC__ *ctx=SWELL_GDP_CTX_NEW(); - ctx->ctx=(CGContextRef)c; - ctx->ownedData=buf; - // CGContextSelectFont(ctx->ctx,"Arial",12.0,kCGEncodingMacRoman); - - SetTextColor(ctx,0); - return ctx; -} - -void SWELL_DeleteGfxContext(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)) - { - if (ct->ownedData) - { - CGContextRelease(ct->ctx); - free(ct->ownedData); - } - if (ct->curtextcol) CFRelease(ct->curtextcol); - SWELL_GDP_CTX_DELETE(ct); - } -} -HPEN CreatePen(int attr, int wid, int col) -{ - return CreatePenAlpha(attr,wid,col,1.0f); -} - -HBRUSH CreateSolidBrush(int col) -{ - return CreateSolidBrushAlpha(col,1.0f); -} - - - -HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) -{ - HGDIOBJ__ *pen=GDP_OBJECT_NEW(); - pen->type=TYPE_PEN; - pen->wid=wid<0?0:wid; - pen->color=CreateColor(col,alpha); - return pen; -} -HBRUSH CreateSolidBrushAlpha(int col, float alpha) -{ - HGDIOBJ__ *brush=GDP_OBJECT_NEW(); - brush->type=TYPE_BRUSH; - brush->color=CreateColor(col,alpha); - brush->wid=0; - return brush; -} - - -HFONT CreateFontIndirect(LOGFONT *lf) -{ - return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, - lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, - lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); -} - -static HGDIOBJ__ global_objs[2]; - -void DeleteObject(HGDIOBJ pen) -{ - HGDIOBJ__ *p=(HGDIOBJ__ *)pen; - if (p >= global_objs && p < global_objs + sizeof(global_objs)/sizeof(global_objs[0])) return; - - if (HGDIOBJ_VALID(p)) - { - if (--p->additional_refcnt < 0) - { - if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) - { - if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) - if (p->wid<0) return; - if (p->color) CGColorRelease(p->color); - - if (p->ct_FontRef) CFRelease(p->ct_FontRef); - -#ifdef SWELL_ATSUI_TEXT_SUPPORT - if (p->atsui_font_style) ATSUDisposeStyle(p->atsui_font_style); -#endif - - if (p->wid && p->bitmapptr) [p->bitmapptr release]; - GDP_OBJECT_DELETE(p); - } - // JF> don't free unknown objects, this shouldn't ever happen anyway: else free(p); - } - } -} - - -HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *p=(HGDIOBJ__*) pen; - HGDIOBJ__ **mod=0; - if (!HDC_VALID(c)) return 0; - - if (p == (HGDIOBJ__*)TYPE_PEN) mod=&c->curpen; - else if (p == (HGDIOBJ__*)TYPE_BRUSH) mod=&c->curbrush; - else if (p == (HGDIOBJ__*)TYPE_FONT) mod=&c->curfont; - - if (mod) // clearing a particular thing - { - HGDIOBJ__ *np=*mod; - *mod=0; - return HGDIOBJ_VALID(np,(int)(INT_PTR)p)?np:p; - } - - if (!HGDIOBJ_VALID(p)) return 0; - - if (p->type == TYPE_PEN) mod=&c->curpen; - else if (p->type == TYPE_BRUSH) mod=&c->curbrush; - else if (p->type == TYPE_FONT) mod=&c->curfont; - - if (!mod) return 0; - - HGDIOBJ__ *op=*mod; - if (!HGDIOBJ_VALID(op,p->type)) op=(HGDIOBJ__*)p->type; - if (op != p) *mod=p; - return op; -} - - - -void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) -{ - HDC__ *c=(HDC__ *)ctx; - HGDIOBJ__ *b=(HGDIOBJ__*) br; - if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH) || b == (HGDIOBJ__*)TYPE_BRUSH || b->type != TYPE_BRUSH) return; - - if (b->wid<0) return; - - CGRect rect=CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top); - CGContextSetFillColorWithColor(c->ctx,b->color); - CGContextFillRect(c->ctx,rect); - -} - -void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) -{ - xrnd/=3; - yrnd/=3; - POINT pts[10]={ // todo: curves between edges - {x,y+yrnd}, - {x+xrnd,y}, - {x2-xrnd,y}, - {x2,y+yrnd}, - {x2,y2-yrnd}, - {x2-xrnd,y2}, - {x+xrnd,y2}, - {x,y2-yrnd}, - {x,y+yrnd}, - {x+xrnd,y}, -}; - - WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); -} - -void Ellipse(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - CGRect rect=CGRectMake(l,t,r-l,b-t); - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) - { - CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); - CGContextFillEllipseInRect(c->ctx,rect); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - CGContextStrokeEllipseInRect(c->ctx, rect); //, (float)max(1,c->curpen->wid)); - } -} - -void Rectangle(HDC ctx, int l, int t, int r, int b) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - - CGRect rect=CGRectMake(l,t,r-l,b-t); - - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); - CGContextFillRect(c->ctx,rect); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) - { - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - CGContextStrokeRectWithWidth(c->ctx, rect, (float)max(1,c->curpen->wid)); - } -} - - -HGDIOBJ GetStockObject(int wh) -{ - switch (wh) - { - case NULL_BRUSH: - { - HGDIOBJ__ *p = &global_objs[0]; - p->type=TYPE_BRUSH; - p->wid=-1; - return p; - } - case NULL_PEN: - { - HGDIOBJ__ *p = &global_objs[1]; - p->type=TYPE_PEN; - p->wid=-1; - return p; - } - } - return 0; -} - -void Polygon(HDC ctx, POINT *pts, int npts) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && (!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return; - - CGContextBeginPath(c->ctx); - CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); - int x; - for (x = 1; x < npts; x ++) - { - CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); - } - if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) - { - CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); - } - if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) - { - CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - } - CGContextDrawPath(c->ctx,HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0 && HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid>=0 ? kCGPathFillStroke : HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); -} - -void MoveToEx(HDC ctx, int x, int y, POINT *op) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)) return; - if (op) - { - op->x = (int) (c->lastpos_x); - op->y = (int) (c->lastpos_y); - } - c->lastpos_x=(float)x; - c->lastpos_y=(float)y; -} - -void PolyBezierTo(HDC ctx, POINT *pts, int np) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; - - CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - - CGContextBeginPath(c->ctx); - CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); - int x; - float xp,yp; - for (x = 0; x < np-2; x += 3) - { - CGContextAddCurveToPoint(c->ctx, - (float)pts[x].x,(float)pts[x].y, - (float)pts[x+1].x,(float)pts[x+1].y, - xp=(float)pts[x+2].x,yp=(float)pts[x+2].y); - } - c->lastpos_x=(float)xp; - c->lastpos_y=(float)yp; - CGContextStrokePath(c->ctx); -} - - -void SWELL_LineTo(HDC ctx, int x, int y) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; - - float w = (float)max(c->curpen->wid,1); - CGContextSetLineWidth(c->ctx,w); - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - - CGContextBeginPath(c->ctx); - CGContextMoveToPoint(c->ctx,c->lastpos_x + w * 0.5,c->lastpos_y + w*0.5); - float fx=(float)x,fy=(float)y; - - CGContextAddLineToPoint(c->ctx,fx+w*0.5,fy+w*0.5); - c->lastpos_x=fx; - c->lastpos_y=fy; - CGContextStrokePath(c->ctx); -} - -void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) -{ - HDC__ *c=(HDC__ *)ctx; - if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; - - float w = (float)max(c->curpen->wid,1); - CGContextSetLineWidth(c->ctx,w); - CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); - - CGContextBeginPath(c->ctx); - - while (nseg-->0) - { - DWORD cnt=*cnts++; - if (!cnt) continue; - if (!--cnt) { pts++; continue; } - - CGContextMoveToPoint(c->ctx,(float)pts->x+w*0.5,(float)pts->y+w*0.5); - pts++; - - while (cnt--) - { - CGContextAddLineToPoint(c->ctx,(float)pts->x+w*0.5,(float)pts->y+w*0.5); - pts++; - } - } - CGContextStrokePath(c->ctx); -} -void *SWELL_GetCtxGC(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return 0; - return ct->ctx; -} - - -void SWELL_SetPixel(HDC ctx, int x, int y, int c) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - CGContextBeginPath(ct->ctx); - CGContextMoveToPoint(ct->ctx,(float)x-0.5,(float)y-0.5); - CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); - CGContextSetLineWidth(ct->ctx,(float)1.0); - CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); - CGContextStrokePath(ct->ctx); -} - - -HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, - char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, - char lfQuality, char lfPitchAndFamily, const char *lfFaceName) -{ - HGDIOBJ__ *font=GDP_OBJECT_NEW(); - font->type=TYPE_FONT; - float fontwid=lfHeight; - - if (!fontwid) fontwid=lfWidth; - if (fontwid<0)fontwid=-fontwid; - - if (fontwid < 2 || fontwid > 8192) fontwid=10; - - font->font_rotation = lfOrientation/10.0; - - if (IsCoreTextSupported()) - { - char buf[1024]; - lstrcpyn(buf,lfFaceName,900); - if (lfWeight >= FW_BOLD) strcat(buf," Bold"); - if (lfItalic) strcat(buf," Italic"); - - NSString *str=CStringToNSString(buf); - font->ct_FontRef = (void*)CTFontCreateWithName((CFStringRef)str,fontwid,NULL); - [str release]; - if (!font->ct_FontRef) font->ct_FontRef = (void*)[[NSFont labelFontOfSize:fontwid] retain]; - - // might want to make this conditional (i.e. only return font if created successfully), but I think we'd rather fallback to a system font than use ATSUI - return font; - } - -#ifdef SWELL_ATSUI_TEXT_SUPPORT - ATSUFontID fontid=kATSUInvalidFontID; - if (lfFaceName && lfFaceName[0]) - { - ATSUFindFontFromName(lfFaceName,strlen(lfFaceName),kFontFullName /* kFontFamilyName? */ ,(FontPlatformCode)kFontNoPlatform,kFontNoScriptCode,kFontNoLanguageCode,&fontid); - // if (fontid==kATSUInvalidFontID) printf("looked up %s and got %d\n",lfFaceName,fontid); - } - - if (ATSUCreateStyle(&font->atsui_font_style) == noErr && font->atsui_font_style) - { - Fixed fsize=Long2Fix(fontwid); - - Boolean isBold=lfWeight >= FW_BOLD; - Boolean isItal=!!lfItalic; - Boolean isUnder=!!lfUnderline; - - ATSUAttributeTag theTags[] = { kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag,kATSUSizeTag,kATSUFontTag }; - ByteCount theSizes[] = { sizeof(Boolean),sizeof(Boolean),sizeof(Boolean), sizeof(Fixed),sizeof(ATSUFontID) }; - ATSUAttributeValuePtr theValues[] = {&isBold, &isItal, &isUnder, &fsize, &fontid } ; - - int attrcnt=sizeof(theTags)/sizeof(theTags[0]); - if (fontid == kATSUInvalidFontID) attrcnt--; - - if (ATSUSetAttributes (font->atsui_font_style, - attrcnt, - theTags, - theSizes, - theValues)!=noErr) - { - ATSUDisposeStyle(font->atsui_font_style); - font->atsui_font_style=0; - } - } - else - font->atsui_font_style=0; - -#endif - - - return font; -} - - - -BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) -{ - - HDC__ *ct=(HDC__ *)ctx; - if (tm) // give some sane defaults - { - tm->tmInternalLeading=3; - tm->tmAscent=12; - tm->tmDescent=4; - tm->tmHeight=16; - tm->tmAveCharWidth = 10; - } - if (!HDC_VALID(ct)||!tm) return 0; - - bool curfont_valid=HGDIOBJ_VALID(ct->curfont,TYPE_FONT); - -#ifdef SWELL_ATSUI_TEXT_SUPPORT - if (curfont_valid && ct->curfont->atsui_font_style) - { - ATSUTextMeasurement ascent=Long2Fix(10); - ATSUTextMeasurement descent=Long2Fix(3); - ATSUTextMeasurement sz=Long2Fix(0); - ATSUTextMeasurement width =Long2Fix(12); - ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUAscentTag, sizeof(ATSUTextMeasurement), &ascent,NULL); - ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUDescentTag, sizeof(ATSUTextMeasurement), &descent,NULL); - ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUSizeTag, sizeof(ATSUTextMeasurement), &sz,NULL); - ATSUGetAttribute(ct->curfont->atsui_font_style, kATSULineWidthTag, sizeof(ATSUTextMeasurement),&width,NULL); - - float asc=Fix2X(ascent); - float desc=Fix2X(descent); - float size = Fix2X(sz); - - if (size < (asc+desc)*0.2) size=asc+desc; - - tm->tmAscent = (int)ceil(asc); - tm->tmDescent = (int)ceil(desc); - tm->tmInternalLeading=(int)ceil(asc+desc-size); - if (tm->tmInternalLeading<0)tm->tmInternalLeading=0; - tm->tmHeight=(int) ceil(asc+desc); - tm->tmAveCharWidth = (int) (ceil(asc+desc)*0.65); // (int)ceil(Fix2X(width)); - - return 1; - } -#endif - - CTFontRef fr = curfont_valid ? (CTFontRef)ct->curfont->ct_FontRef : NULL; - if (!fr) fr=GetCoreTextDefaultFont(); - - if (fr) - { - tm->tmInternalLeading = CTFontGetLeading(fr); - tm->tmAscent = CTFontGetAscent(fr); - tm->tmDescent = CTFontGetDescent(fr); - tm->tmHeight = (tm->tmInternalLeading + tm->tmAscent + tm->tmDescent); - tm->tmAveCharWidth = tm->tmHeight*2/3; // todo - - if (tm->tmHeight) tm->tmHeight++; - - return 1; - } - - - return 1; -} - - - -#ifdef SWELL_ATSUI_TEXT_SUPPORT - -static int DrawTextATSUI(HDC ctx, CFStringRef strin, RECT *r, int align, bool *err) -{ - HDC__ *ct=(HDC__ *)ctx; - HGDIOBJ__ *font=ct->curfont; // caller must specify a valid font - - UniChar strbuf[4096]; - int strbuf_len; - - { - strbuf[0]=0; - CFRange r = {0,CFStringGetLength(strin)}; - if (r.length > 4095) r.length=4095; - strbuf_len=CFStringGetBytes(strin,r,kCFStringEncodingUTF16,' ',false,(UInt8*)strbuf,sizeof(strbuf)-2,NULL); - if (strbuf_len<0)strbuf_len=0; - else if (strbuf_len>4095) strbuf_len=4095; - strbuf[strbuf_len]=0; - } - - { - RGBColor tcolor={GetRValue(ct->cur_text_color_int)*256,GetGValue(ct->cur_text_color_int)*256,GetBValue(ct->cur_text_color_int)*256}; - ATSUAttributeTag theTags[] = { kATSUColorTag, }; - ByteCount theSizes[] = { sizeof(RGBColor), }; - ATSUAttributeValuePtr theValues[] = {&tcolor, } ; - - // error check this? we can live with the wrong color maybe? - ATSUSetAttributes(font->atsui_font_style, sizeof(theTags)/sizeof(theTags[0]), theTags, theSizes, theValues); - } - - UniCharCount runLengths[1]={kATSUToTextEnd}; - ATSUTextLayout layout; - if (ATSUCreateTextLayoutWithTextPtr(strbuf, kATSUFromTextBeginning, kATSUToTextEnd, strbuf_len, 1, runLengths, &font->atsui_font_style, &layout)!=noErr) - { - *err=true; - return 0; - } - - { - Fixed frot = X2Fix(font->font_rotation); - - ATSULineTruncation tv = (align & DT_END_ELLIPSIS) ? kATSUTruncateEnd : kATSUTruncateNone; - ATSUAttributeTag theTags[] = { kATSUCGContextTag, kATSULineTruncationTag, kATSULineRotationTag }; - ByteCount theSizes[] = { sizeof (CGContextRef), sizeof(ATSULineTruncation), sizeof(Fixed)}; - ATSUAttributeValuePtr theValues[] = { &ct->ctx, &tv, &frot } ; - - - if (ATSUSetLayoutControls (layout, - - sizeof(theTags)/sizeof(theTags[0]), - - theTags, - - theSizes, - - theValues)!=noErr) - { - *err=true; - ATSUDisposeTextLayout(layout); - return 0; - } - } - - - ATSUTextMeasurement leftFixed, rightFixed, ascentFixed, descentFixed; - - if (ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, kATSUToTextEnd, &leftFixed, &rightFixed, &ascentFixed, &descentFixed)!=noErr) - { - *err=true; - ATSUDisposeTextLayout(layout); - return 0; - } - - int w=Fix2Long(rightFixed); - int descent=Fix2Long(descentFixed); - int h=descent + Fix2Long(ascentFixed); - if (align&DT_CALCRECT) - { - ATSUDisposeTextLayout(layout); - r->right=r->left+w; - r->bottom=r->top+h; - return h; - } - CGContextSaveGState(ct->ctx); - - if (!(align & DT_NOCLIP)) - CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); - - int l=r->left, t=r->top; - - if (fabs(font->font_rotation)<45.0) - { - if (align & DT_RIGHT) l = r->right-w; - else if (align & DT_CENTER) l = (r->right+r->left)/2 - w/2; - } - else l+=Fix2Long(ascentFixed); // 90 degree special case (we should generalize this to be correct throughout the rotation range, but oh well) - - if (align & DT_BOTTOM) t = r->bottom-h; - else if (align & DT_VCENTER) t = (r->bottom+r->top)/2 - h/2; - - CGContextTranslateCTM(ct->ctx,0,t); - CGContextScaleCTM(ct->ctx,1,-1); - CGContextTranslateCTM(ct->ctx,0,-t-h); - - if (ct->curbkmode == OPAQUE) - { - CGRect bgr = CGRectMake(l, t, w, h); - static CGColorSpaceRef csr; - if (!csr) csr = CGColorSpaceCreateDeviceRGB(); - float col[] = { (float)GetRValue(ct->curbkcol)/255.0f, (float)GetGValue(ct->curbkcol)/255.0f, (float)GetBValue(ct->curbkcol)/255.0f, 1.0f }; - CGColorRef bgc = CGColorCreate(csr, col); - CGContextSetFillColorWithColor(ct->ctx, bgc); - CGContextFillRect(ct->ctx, bgr); - CGColorRelease(bgc); - } - - if (ATSUDrawText(layout,kATSUFromTextBeginning,kATSUToTextEnd,Long2Fix(l),Long2Fix(t+descent))!=noErr) - *err=true; - - CGContextRestoreGState(ct->ctx); - - ATSUDisposeTextLayout(layout); - - return h; -} - -#endif - -int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return 0; - - bool has_ml=false; - char tmp[4096]; - const char *p=buf; - char *op=tmp; - while (*p && (op-tmp)curfont,TYPE_FONT); -#ifdef SWELL_ATSUI_TEXT_SUPPORT - if (curfont_valid && ct->curfont->atsui_font_style) - { - bool err=false; - int ret = DrawTextATSUI(ctx,(CFStringRef)str,r,align,&err); - [str release]; - - if (!err) return ret; - return 0; - } -#endif - - CTFontRef fr = curfont_valid ? (CTFontRef)ct->curfont->ct_FontRef : NULL; - if (!fr) fr=GetCoreTextDefaultFont(); - if (fr) - { - // Initialize string, font, and context - CFStringRef keys[] = { kCTFontAttributeName,kCTForegroundColorAttributeName }; - CFTypeRef values[] = { fr,ct->curtextcol }; - - int nk= sizeof(keys) / sizeof(keys[0]); - if (!values[1]) nk--; - - CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, nk, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - CFAttributedStringRef attrString = - CFAttributedStringCreate(kCFAllocatorDefault, (CFStringRef)str, attributes); - CFRelease(attributes); - [str release]; - - - CTFrameRef frame = NULL; - CFArrayRef lines = NULL; - CTLineRef line = NULL; - CGFloat asc=0; - int line_w=0,line_h=0; - if (has_ml) - { - CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString); - if (framesetter) - { - CGMutablePathRef path=CGPathCreateMutable(); - CGPathAddRect(path,NULL,CGRectMake(0,0,100000,100000)); - frame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL); - CFRelease(framesetter); - CFRelease(path); - } - if (frame) - { - lines = CTFrameGetLines(frame); - int n=CFArrayGetCount(lines); - int x; - for(x=0;xright = r->left+line_w; - r->bottom = r->top+line_h; - if (line) CFRelease(line); - if (frame) CFRelease(frame); - return line_h; - } - - float xo=r->left,yo=r->top; - if (align & DT_RIGHT) xo += (r->right-r->left) - line_w; - else if (align & DT_CENTER) xo += (r->right-r->left)/2 - line_w/2; - - if (align & DT_BOTTOM) yo += (r->bottom-r->top) - line_h; - else if (align & DT_VCENTER) yo += (r->bottom-r->top)/2 - line_h/2; - - - CGContextSaveGState(ct->ctx); - - CGAffineTransform f={1,0,0,-1,0,0}; - CGContextSetTextMatrix(ct->ctx, f); - - if (!(align & DT_NOCLIP)) - { - CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); - } - - CGColorRef bgc = NULL; - if (ct->curbkmode == OPAQUE) - { - CGColorSpaceRef csr = CGColorSpaceCreateDeviceRGB(); - CGFloat col[] = { (float)GetRValue(ct->curbkcol)/255.0f, (float)GetGValue(ct->curbkcol)/255.0f, (float)GetBValue(ct->curbkcol)/255.0f, 1.0f }; - bgc = CGColorCreate(csr, col); - CGColorSpaceRelease(csr); - } - - if (line) - { - if (bgc) - { - CGContextSetFillColorWithColor(ct->ctx, bgc); - CGContextFillRect(ct->ctx, CGRectMake(xo,yo,line_w,line_h)); - } - CGContextSetTextPosition(ct->ctx, xo, yo + asc); - CTLineDraw(line,ct->ctx); - - } - if (lines) - { - int n=CFArrayGetCount(lines); - int x; - for(x=0;xctx, bgc); - CGContextFillRect(ct->ctx, CGRectMake(xo,yo,lw,asc+desc+lead)); - } - CGContextSetTextPosition(ct->ctx, xo, yo + asc); - CTLineDraw(l,ct->ctx); - - yo += floor(asc+desc+lead+0.5); - } - } - - } - - CGContextRestoreGState(ct->ctx); - if (bgc) CGColorRelease(bgc); - if (line) CFRelease(line); - if (frame) CFRelease(frame); - - return line_h; - } - - - [str release]; - return 0; -} - - - - - - -void SetBkColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkcol=col; -} - -void SetBkMode(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->curbkmode=col; -} - -int GetTextColor(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return -1; - return ct->cur_text_color_int; -} - -void SetTextColor(HDC ctx, int col) -{ - HDC__ *ct=(HDC__ *)ctx; - if (!HDC_VALID(ct)) return; - ct->cur_text_color_int = col; - - if (ct->curtextcol) CFRelease(ct->curtextcol); - - static CGColorSpaceRef csr; - if (!csr) csr = CGColorSpaceCreateDeviceRGB(); - CGFloat ccol[] = { GetRValue(col)/255.0f,GetGValue(col)/255.0f,GetBValue(col)/255.0f,1.0 }; - ct->curtextcol = csr ? CGColorCreate(csr, ccol) : NULL; -} - - -HICON CreateIconIndirect(ICONINFO* iconinfo) -{ - if (!iconinfo || !iconinfo->fIcon) return 0; - HGDIOBJ__* i=iconinfo->hbmColor; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP) || !i->bitmapptr) return 0; - NSImage* img=i->bitmapptr; - if (!img) return 0; - - HGDIOBJ__* icon=GDP_OBJECT_NEW(); - icon->type=TYPE_BITMAP; - icon->wid=1; - [img retain]; - icon->bitmapptr=img; - return icon; -} - -HICON LoadNamedImage(const char *name, bool alphaFromMask) -{ - int needfree=0; - NSImage *img=0; - NSString *str=CStringToNSString(name); - if (strstr(name,"/")) - { - img=[[NSImage alloc] initWithContentsOfFile:str]; - if (img) needfree=1; - } - if (!img) img=[NSImage imageNamed:str]; - [str release]; - if (!img) - { - return 0; - } - - if (alphaFromMask) - { - NSSize sz=[img size]; - NSImage *newImage=[[NSImage alloc] initWithSize:sz]; - [newImage lockFocus]; - - [img setFlipped:YES]; - [img drawInRect:NSMakeRect(0,0,sz.width,sz.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; - int y; - CGContextRef myContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; - for (y=0; y< sz.height; y ++) - { - int x; - for (x = 0; x < sz.width; x ++) - { - NSColor *col=NSReadPixel(NSMakePoint(x,y)); - if (col && [col numberOfComponents]<=4) - { - CGFloat comp[4]; - [col getComponents:comp]; // this relies on the format being RGB - if (comp[0] == 1.0 && comp[1] == 0.0 && comp[2] == 1.0 && comp[3]==1.0) - //fabs(comp[0]-1.0) < 0.0001 && fabs(comp[1]-.0) < 0.0001 && fabs(comp[2]-1.0) < 0.0001) - { - CGContextClearRect(myContext,CGRectMake(x,y,1,1)); - } - } - } - } - [newImage unlockFocus]; - - if (needfree) [img release]; - needfree=1; - img=newImage; - } - - HGDIOBJ__ *i=GDP_OBJECT_NEW(); - i->type=TYPE_BITMAP; - i->wid=needfree; - i->bitmapptr = img; - return i; -} - -void DrawImageInRect(HDC ctx, HICON img, RECT *r) -{ - HGDIOBJ__ *i = (HGDIOBJ__ *)img; - HDC__ *ct=(HDC__*)ctx; - if (!HDC_VALID(ct) || !HGDIOBJ_VALID(i,TYPE_BITMAP) || !i->bitmapptr) return; - //CGContextDrawImage(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top),(CGImage*)i->bitmapptr); - // probably a better way since this ignores the ctx - [NSGraphicsContext saveGraphicsState]; - NSGraphicsContext *gc=[NSGraphicsContext graphicsContextWithGraphicsPort:ct->ctx flipped:NO]; - [NSGraphicsContext setCurrentContext:gc]; - NSImage *nsi=i->bitmapptr; - NSRect rr=NSMakeRect(r->left,r->top,r->right-r->left,r->bottom-r->top); - [nsi setFlipped:YES]; - [nsi drawInRect:rr fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; - [nsi setFlipped:NO]; - [NSGraphicsContext restoreGraphicsState]; -// [gc release]; -} - - -BOOL GetObject(HICON icon, int bmsz, void *_bm) -{ - memset(_bm,0,bmsz); - if (bmsz != sizeof(BITMAP)) return false; - BITMAP *bm=(BITMAP *)_bm; - HGDIOBJ__ *i = (HGDIOBJ__ *)icon; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; - NSImage *img = i->bitmapptr; - if (!img) return false; - bm->bmWidth = (int) ([img size].width+0.5); - bm->bmHeight = (int) ([img size].height+0.5); - return true; -} - - -void *GetNSImageFromHICON(HICON ico) -{ - HGDIOBJ__ *i = (HGDIOBJ__ *)ico; - if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return 0; - return i->bitmapptr; -} - -#if 0 -static int ColorFromNSColor(NSColor *color, int valifnul) -{ - if (!color) return valifnul; - float r,g,b; - NSColor *color2=[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; - if (!color2) - { - NSLog(@"error converting colorspace from: %@\n",[color colorSpaceName]); - return valifnul; - } - - [color2 getRed:&r green:&g blue:&b alpha:NULL]; - return RGB((int)(r*255.0),(int)(g*255.0),(int)(b*255.0)); -} -#else -#define ColorFromNSColor(a,b) (b) -#endif -int GetSysColor(int idx) -{ - // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor - - switch (idx) - { - case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_3DFACE: - case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); - case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); - case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); - case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); - case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); - case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; - case COLOR_INFOBK: return RGB(255,240,200); - case COLOR_INFOTEXT: return RGB(0,0,0); - - } - return 0; -} - - -void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) -{ - StretchBlt(hdcOut,x,y,w,h,hdcIn,xin,yin,w,h,mode); -} - -void StretchBlt(HDC hdcOut, int x, int y, int destw, int desth, HDC hdcIn, int xin, int yin, int w, int h, int mode) -{ - if (!hdcOut || !hdcIn||w<1||h<1) return; - HDC__ *src=(HDC__*)hdcIn; - HDC__ *dest=(HDC__*)hdcOut; - if (!HDC_VALID(src) || !HDC_VALID(dest) || !src->ownedData || !src->ctx || !dest->ctx) return; - - if (w<1||h<1) return; - - int sw= CGBitmapContextGetWidth(src->ctx); - int sh= CGBitmapContextGetHeight(src->ctx); - - int preclip_w=w; - int preclip_h=h; - - if (xin<0) - { - x-=(xin*destw)/w; - w+=xin; - xin=0; - } - if (yin<0) - { - y-=(yin*desth)/h; - h+=yin; - yin=0; - } - if (xin+w > sw) w=sw-xin; - if (yin+h > sh) h=sh-yin; - - if (w<1||h<1) return; - - if (destw==preclip_w) destw=w; // no scaling, keep width the same - else if (w != preclip_w) destw = (w*destw)/preclip_w; - - if (desth == preclip_h) desth=h; - else if (h != preclip_h) desth = (h*desth)/preclip_h; - - CGImageRef img = NULL, subimg = NULL; - NSBitmapImageRep *rep = NULL; - - static char is105; - if (!is105) - { - SInt32 v=0x1040; - Gestalt(gestaltSystemVersion,&v); - is105 = v>=0x1050 ? 1 : -1; - } - - bool want_subimage=false; - - bool use_alphachannel = mode == SRCCOPY_USEALPHACHAN; - - if (is105>0) - { - // [NSBitmapImageRep CGImage] is not available pre-10.5 - unsigned char *p = (unsigned char *)ALIGN_FBUF(src->ownedData); - p += (xin + sw*yin)*4; - rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&p pixelsWide:w pixelsHigh:h - bitsPerSample:8 samplesPerPixel:(3+use_alphachannel) hasAlpha:use_alphachannel isPlanar:FALSE - colorSpaceName:NSDeviceRGBColorSpace bitmapFormat:(NSBitmapFormat)((use_alphachannel ? NSAlphaNonpremultipliedBitmapFormat : 0) |NSAlphaFirstBitmapFormat) bytesPerRow:sw*4 bitsPerPixel:32]; - img=(CGImageRef)objc_msgSend(rep,@selector(CGImage)); - if (img) CGImageRetain(img); - } - else - { - if (1) // this seems to be WAY better on 10.4 than the alternative (below) - { - static CGColorSpaceRef cs; - if (!cs) cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - unsigned char *p = (unsigned char *)ALIGN_FBUF(src->ownedData); - p += (xin + sw*yin)*4; - - CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,p,4*sw*h,NULL); - img = CGImageCreate(w,h,8,32,4*sw,cs,use_alphachannel?kCGImageAlphaFirst:kCGImageAlphaNoneSkipFirst,provider,NULL,NO,kCGRenderingIntentDefault); - // CGColorSpaceRelease(cs); - CGDataProviderRelease(provider); - } - else - { - // causes lots of kernel messages, so avoid if possible, also doesnt support alpha bleh - img = CGBitmapContextCreateImage(src->ctx); - want_subimage = true; - } - } - - if (!img) return; - - if (want_subimage && (w != sw || h != sh)) - { - subimg = CGImageCreateWithImageInRect(img,CGRectMake(xin,yin,w,h)); - if (!subimg) - { - CGImageRelease(img); - return; - } - } - - CGContextRef output = (CGContextRef)dest->ctx; - - - CGContextSaveGState(output); - CGContextScaleCTM(output,1.0,-1.0); - CGContextDrawImage(output,CGRectMake(x,-desth-y,destw,desth),subimg ? subimg : img); - CGContextRestoreGState(output); - - if (subimg) CGImageRelease(subimg); - CGImageRelease(img); - if (rep) [rep release]; - -} - -void SWELL_PushClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct) && ct->ctx) CGContextSaveGState(ct->ctx); -} - -void SWELL_SetClipRegion(HDC ctx, RECT *r) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct) && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); - -} - -void SWELL_PopClipRegion(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct) && ct->ctx) CGContextRestoreGState(ct->ctx); -} - -void *SWELL_GetCtxFrameBuffer(HDC ctx) -{ - HDC__ *ct=(HDC__ *)ctx; - if (HDC_VALID(ct)) return ALIGN_FBUF(ct->ownedData); - return 0; -} - - -HDC GetDC(HWND h) -{ - if (h && [(id)h isKindOfClass:[NSWindow class]]) - { - if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) - { - PAINTSTRUCT ps={0,}; - [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; - if (ps.hdc) - { - if ((ps.hdc)->ctx) CGContextSaveGState((ps.hdc)->ctx); - return ps.hdc; - } - } - h=(HWND)[(id)h contentView]; - } - - if (h && [(id)h isKindOfClass:[NSView class]]) - { - if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) - { - PAINTSTRUCT ps={0,}; - [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; - if (HDC_VALID((HDC__*)ps.hdc)) - { - if (((HDC__*)ps.hdc)->ctx) CGContextSaveGState((ps.hdc)->ctx); - return ps.hdc; - } - } - - if ([(NSView*)h lockFocusIfCanDraw]) - { - HDC ret= SWELL_CreateGfxContext([NSGraphicsContext currentContext]); - if (ret) - { - if ((ret)->ctx) CGContextSaveGState((ret)->ctx); - } - return ret; - } - } - return 0; -} - -HDC GetWindowDC(HWND h) -{ - HDC ret=GetDC(h); - if (ret) - { - NSView *v=NULL; - if ([(id)h isKindOfClass:[NSWindow class]]) v=[(id)h contentView]; - else if ([(id)h isKindOfClass:[NSView class]]) v=(NSView *)h; - - if (v) - { - NSRect b=[v bounds]; - float xsc=b.origin.x; - float ysc=b.origin.y; - if ((xsc || ysc) && (ret)->ctx) CGContextTranslateCTM((ret)->ctx,xsc,ysc); - } - } - return ret; -} - -void ReleaseDC(HWND h, HDC hdc) -{ - if (hdc) - { - if ((hdc)->ctx) CGContextRestoreGState((hdc)->ctx); - } - if (h && [(id)h isKindOfClass:[NSWindow class]]) - { - if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) - { - PAINTSTRUCT ps={0,}; - [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; - if (ps.hdc && ps.hdc==hdc) return; - } - h=(HWND)[(id)h contentView]; - } - bool isView=h && [(id)h isKindOfClass:[NSView class]]; - if (isView) - { - if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) - { - PAINTSTRUCT ps={0,}; - [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; - if (ps.hdc && ps.hdc==hdc) return; - } - } - - if (hdc) SWELL_DeleteGfxContext(hdc); - if (isView && hdc) - { - [(NSView *)h unlockFocus]; -// if ([(NSView *)h window]) [[(NSView *)h window] flushWindow]; - } -} - -void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) -{ - CGContextRef ctx=(CGContextRef)SWELL_GetCtxGC(hdc); - if (ctx) - { - // level 0 for now = this - HIThemeSetFill(kThemeBrushDialogBackgroundActive,NULL,ctx,kHIThemeOrientationNormal); - CGRect rect=CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top); - CGContextFillRect(ctx,rect); - } -} - -HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) -{ - if (HGDIOBJ_VALID(a)) - { - a->additional_refcnt++; - return a; - } - return NULL; -} - - -HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) -{ - int spp = bitsperpixel/8; - Boolean hasa = (bitsperpixel == 32); - Boolean hasp = (numplanes > 1); // won't actually work yet for planar data - NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 pixelsWide:width pixelsHigh:height - bitsPerSample:8 samplesPerPixel:spp - hasAlpha:hasa isPlanar:hasp - colorSpaceName:NSDeviceRGBColorSpace - bitmapFormat:NSAlphaFirstBitmapFormat - bytesPerRow:0 bitsPerPixel:0]; - if (!rep) return 0; - unsigned char* p = [rep bitmapData]; - int pspan = [rep bytesPerRow]; // might not be the same as width - - int y; - for (y=0;ytype = TYPE_BITMAP; - obj->wid = 1; // need free - obj->bitmapptr = img; - return obj; -} - - -HIMAGELIST ImageList_CreateEx() -{ - return (HIMAGELIST)new WDL_PtrList; -} - -BOOL ImageList_Remove(HIMAGELIST list, int idx) -{ - WDL_PtrList* imglist=(WDL_PtrList*)list; - if (imglist && idx < imglist->GetSize()) - { - if (idx < 0) - { - int x,n=imglist->GetSize(); - for (x=0;xGet(x); - if (a) DeleteObject(a); - } - imglist->Empty(); - } - else - { - HGDIOBJ__ *a = imglist->Get(idx); - imglist->Set(idx, NULL); - if (a) DeleteObject(a); - } - return TRUE; - } - - return FALSE; -} - -void ImageList_Destroy(HIMAGELIST list) -{ - if (!list) return; - ImageList_Remove(list, -1); - delete (WDL_PtrList*)list; -} - -int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) -{ - if (!image || !list) return -1; - WDL_PtrList *l=(WDL_PtrList *)list; - - HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; - if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; - - HGDIOBJ__* icon=GDP_OBJECT_NEW(); - icon->type=TYPE_BITMAP; - icon->wid=1; - icon->bitmapptr = imgsrc->bitmapptr; // no need to duplicate it, can just retain a copy - [icon->bitmapptr retain]; - image = (HICON) icon; - - if (offset<0||offset>=l->GetSize()) - { - l->Add(image); - offset=l->GetSize()-1; - } - else - { - HICON old=l->Get(offset); - l->Set(offset,image); - if (old) DeleteObject(old); - } - return offset; -} - - - -#endif diff --git a/WDL/swell/swell-ini.cpp b/WDL/swell/swell-ini.cpp deleted file mode 100644 index ca3ab701..00000000 --- a/WDL/swell/swell-ini.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - This file implements basic win32 GetPrivateProfileString / etc support. - It works by caching reads, but writing through on every write that is required (to ensure - that updates take, especially when being updated from multiple modules who have their own - cache of the .ini file). - - It is threadsafe, but in theory if two processes are trying to access the same ini, - results may go a bit unpredictable (but in general the file should NOT get corrupted, - we hope). - -*/ - -#ifndef SWELL_PROVIDED_BY_APP - - -#include "swell.h" -#include "../assocarray.h" -#include "../mutex.h" -#include "../queue.h" -#include -#include -#include - -static void deleteStringKeyedArray(WDL_StringKeyedArray *p) { delete p; } - -struct iniFileContext -{ - iniFileContext() : m_sections(false,deleteStringKeyedArray) - { - m_curfn=NULL; - m_lastaccesscnt=0; - m_curfn_time=0; - m_curfn_sz=0; - } - ~iniFileContext() { } - - WDL_UINT64 m_lastaccesscnt; - time_t m_curfn_time; - int m_curfn_sz; - char *m_curfn; - - WDL_StringKeyedArray< WDL_StringKeyedArray * > m_sections; - -}; - -#define NUM_OPEN_CONTEXTS 32 -static iniFileContext s_ctxs[NUM_OPEN_CONTEXTS]; -static WDL_Mutex m_mutex; - -static time_t getfileupdtimesize(const char *fn, int *szOut) -{ - struct stat st; - *szOut = 0; - if (!fn || !fn[0] || stat(fn,&st)) return 0; - *szOut = (int)st.st_size; - return st.st_mtime; -} - -static bool fgets_to_typedbuf(WDL_TypedBuf *buf, FILE *fp) -{ - int rdpos=0; - while (rdpos < 1024*1024*32) - { - if (buf->GetSize()Resize(rdpos+8192); - if (buf->GetSize()Get()+rdpos; - *p=0; - fgets(p,buf->GetSize()-rdpos,fp); - if (!*p) break; - while (*p) p++; - if (p[-1] == '\r' || p[-1] == '\n') break; - - rdpos = p - buf->Get(); - } - return buf->GetSize()>0 && buf->Get()[0]; -} - - -// return true on success -static iniFileContext *GetFileContext(const char *name) -{ - static WDL_UINT64 acc_cnt; - int best_z = 0; - { - int w; - WDL_UINT64 bestcnt = 0; - bestcnt--; - - for (w=0;wm_lastaccesscnt=++acc_cnt; - - int sz=0; - if (!ctx->m_curfn || stricmp(ctx->m_curfn,name) || ctx->m_curfn_time != getfileupdtimesize(ctx->m_curfn,&sz) || sz != ctx->m_curfn_sz) - { - ctx->m_sections.DeleteAll(); -// printf("reinitting to %s\n",name); - if (!ctx->m_curfn || stricmp(ctx->m_curfn,name)) - { - free(ctx->m_curfn); - ctx->m_curfn=strdup(name); - } - FILE *fp = fopen(name,"r"); - - if (!fp) - { - ctx->m_curfn_time=0; - ctx->m_curfn_sz=0; - return ctx; // allow to proceed (empty file) - } - - flock(fileno(fp),LOCK_SH); - - // parse .ini file - WDL_StringKeyedArray *cursec=NULL; - - int lcnt=0; - for (;;) - { - static WDL_TypedBuf _buf; - if (!fgets_to_typedbuf(&_buf,fp)) break; - - char *buf = _buf.Get(); - char *p=buf; - if (lcnt++ == 8 && !ctx->m_sections.GetSize()) break; // dont bother reading more than 8 lines if no section encountered - - while (*p) p++; - - if (p>buf) - { - p--; - while (p >= buf && (*p==' ' || *p == '\r' || *p == '\n' || *p == '\t')) p--; - p[1]=0; - } - p=buf; - while (*p == ' ' || *p == '\t') p++; - if (p[0] == '[') - { - char *p2=p; - while (*p2 && *p2 != ']') p2++; - if (*p2) - { - *p2=0; - if (cursec) cursec->Resort(); - - if (p[1]) - { - cursec = ctx->m_sections.Get(p+1); - if (!cursec) - { - cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); - ctx->m_sections.Insert(p+1,cursec); - } - else cursec->DeleteAll(); - } - else cursec=0; - } - } - else if (cursec) - { - char *t=strstr(p,"="); - if (t) - { - *t++=0; - if (*p) - cursec->AddUnsorted(p,strdup(t)); - } - } - } - ctx->m_curfn_time = getfileupdtimesize(name,&ctx->m_curfn_sz); - flock(fileno(fp),LOCK_UN); - fclose(fp); - - if (cursec) cursec->Resort(); - } - return ctx; -} - -static void WriteBackFile(iniFileContext *ctx) -{ - if (!ctx||!ctx->m_curfn) return; - char newfn[1024]; - lstrcpyn(newfn,ctx->m_curfn,sizeof(newfn)-8); - { - char *p=newfn; - while (*p) p++; - while (p>newfn && p[-1] != '/') p--; - char lc = '.'; - while (*p) - { - char c = *p; - *p++ = lc; - lc = c; - } - *p++ = lc; - strcpy(p,".new"); - } - - FILE *fp = fopen(newfn,"w"); - if (!fp) return; - - flock(fileno(fp),LOCK_EX); - - int x; - for (x = 0; ; x ++) - { - const char *secname=NULL; - WDL_StringKeyedArray * cursec = ctx->m_sections.Enumerate(x,&secname); - if (!cursec || !secname) break; - - fprintf(fp,"[%s]\n",secname); - int y; - for (y=0;;y++) - { - const char *keyname = NULL; - const char *keyvalue = cursec->Enumerate(y,&keyname); - if (!keyvalue || !keyname) break; - if (*keyname) fprintf(fp,"%s=%s\n",keyname,keyvalue); - } - fprintf(fp,"\n"); - } - - fflush(fp); - flock(fileno(fp),LOCK_UN); - fclose(fp); - - if (!rename(newfn,ctx->m_curfn)) - { - ctx->m_curfn_time = getfileupdtimesize(ctx->m_curfn,&ctx->m_curfn_sz); - } - else - { - // error updating, hmm how to handle this? - } -} - -BOOL WritePrivateProfileSection(const char *appname, const char *strings, const char *fn) -{ - if (!appname || !fn) return FALSE; - WDL_MutexLock lock(&m_mutex); - iniFileContext *ctx = GetFileContext(fn); - if (!ctx) return FALSE; - - WDL_StringKeyedArray * cursec = ctx->m_sections.Get(appname); - if (!cursec) - { - if (!*strings) return TRUE; - - cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); - ctx->m_sections.Insert(appname,cursec); - } - else cursec->DeleteAll(); - - if (*strings) - { - while (*strings) - { - char buf[8192]; - lstrcpyn(buf,strings,sizeof(buf)); - char *p = buf; - while (*p && *p != '=') p++; - if (*p) - { - *p++=0; - cursec->Insert(buf,strdup(strings + (p-buf))); - } - - strings += strlen(strings)+1; - } - } - WriteBackFile(ctx); - - return TRUE; -} - - -BOOL WritePrivateProfileString(const char *appname, const char *keyname, const char *val, const char *fn) -{ - if (!appname || (keyname && !*keyname)) return FALSE; -// printf("writing %s %s %s %s\n",appname,keyname,val,fn); - WDL_MutexLock lock(&m_mutex); - - iniFileContext *ctx = GetFileContext(fn); - if (!ctx) return FALSE; - - if (!keyname) - { - if (ctx->m_sections.Get(appname)) - { - ctx->m_sections.Delete(appname); - WriteBackFile(ctx); - } - } - else - { - WDL_StringKeyedArray * cursec = ctx->m_sections.Get(appname); - if (!val) - { - if (cursec && cursec->Get(keyname)) - { - cursec->Delete(keyname); - WriteBackFile(ctx); - } - } - else - { - const char *p; - if (!cursec || !(p=cursec->Get(keyname)) || strcmp(p,val)) - { - if (!cursec) - { - cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); - ctx->m_sections.Insert(appname,cursec); - } - cursec->Insert(keyname,strdup(val)); - WriteBackFile(ctx); - } - } - - } - - return TRUE; -} - -DWORD GetPrivateProfileSection(const char *appname, char *strout, DWORD strout_len, const char *fn) -{ - WDL_MutexLock lock(&m_mutex); - - if (!strout || strout_len<2) - { - if (strout && strout_len==1) *strout=0; - return 0; - } - iniFileContext *ctx= GetFileContext(fn); - int szOut=0; - WDL_StringKeyedArray *cursec = ctx ? ctx->m_sections.Get(appname) : NULL; - - if (ctx && cursec) - { - int x; - for(x=0;xGetSize();x++) - { - const char *kv = NULL; - const char *val = cursec->Enumerate(x,&kv); - if (val && kv) - { - int l; - -#define WRSTR(v) \ - l= strlen(v); \ - if (l > strout_len - szOut - 2) l = strout_len - 2 - szOut; \ - if (l>0) { memcpy(strout+szOut,v,l); szOut+=l; } - - WRSTR(kv) - WRSTR("=") - WRSTR(val) - -#undef WRSTR - - l=1; - if (l > strout_len - szOut - 1) l = strout_len - 1 - szOut; - if (l>0) { memset(strout+szOut,0,l); szOut+=l; } - if (szOut >= strout_len-1) - { - strout[strout_len-1]=0; - return strout_len-2; - } - } - } - } - strout[szOut]=0; - if (!szOut) strout[1]=0; - return szOut; -} - -DWORD GetPrivateProfileString(const char *appname, const char *keyname, const char *def, char *ret, int retsize, const char *fn) -{ - WDL_MutexLock lock(&m_mutex); - -// printf("getprivateprofilestring: %s\n",fn); - iniFileContext *ctx= GetFileContext(fn); - - if (ctx) - { - if (!appname||!keyname) - { - WDL_Queue tmpbuf; - if (!appname) - { - int x; - for (x = 0;; x ++) - { - const char *secname=NULL; - if (!ctx->m_sections.Enumerate(x,&secname) || !secname) break; - if (*secname) tmpbuf.Add(secname,strlen(secname)+1); - } - } - else - { - WDL_StringKeyedArray *cursec = ctx->m_sections.Get(appname); - if (cursec) - { - int y; - for (y = 0; ; y ++) - { - const char *keyname=NULL; - if (!cursec->Enumerate(y,&keyname)||!keyname) break; - if (*keyname) tmpbuf.Add(keyname,strlen(keyname)+1); - } - } - } - - int sz=tmpbuf.GetSize()-1; - if (sz<0) - { - ret[0]=ret[1]=0; - return 0; - } - if (sz > retsize-2) sz=retsize-2; - memcpy(ret,tmpbuf.Get(),sz); - ret[sz]=ret[sz+1]=0; - - return sz; - } - - WDL_StringKeyedArray *cursec = ctx->m_sections.Get(appname); - if (cursec) - { - const char *val = cursec->Get(keyname); - if (val) - { - lstrcpyn(ret,val,retsize); - return strlen(ret); - } - } - } -// printf("def %s %s %s %s\n",appname,keyname,def,fn); - lstrcpyn(ret,def?def:"",retsize); - return strlen(ret); -} - -int GetPrivateProfileInt(const char *appname, const char *keyname, int def, const char *fn) -{ - char buf[512]; - GetPrivateProfileString(appname,keyname,"",buf,sizeof(buf),fn); - if (buf[0]) - { - int a=atoi(buf); - if (a||buf[0]=='0') return a; - } - return def; -} - -static bool __readbyte(char *src, unsigned char *out) -{ - unsigned char cv=0; - int s=4; - while(s>=0) - { - if (*src >= '0' && *src <= '9') cv += (*src-'0')<= 'a' && *src <= 'f') cv += (*src-'a' + 10)<= 'A' && *src <= 'F') cv += (*src-'A' + 10)<0) - { - if (!__readbyte(src,&cv)) break; - *bufout++ = cv; - sum += cv; - src+=2; - } - ret = bufsz<0 && __readbyte(src,&cv) && cv==sum; - } - free(tmp); - //printf("getprivateprofilestruct returning %d\n",ret); - return ret; -} - -BOOL WritePrivateProfileStruct(const char *appname, const char *keyname, const void *buf, int bufsz, const char *fn) -{ - if (!keyname || !buf) return WritePrivateProfileString(appname,keyname,(const char *)buf,fn); - char *tmp=(char *)malloc((bufsz+1)*2+1); - if (!tmp) return 0; - char *p = tmp; - unsigned char sum=0; - unsigned char *src=(unsigned char *)buf; - while (bufsz-- > 0) - { - sprintf(p,"%02X",*src); - sum+=*src++; - p+=2; - } - sprintf(p,"%02X",sum); - - BOOL ret=WritePrivateProfileString(appname,keyname,tmp,fn); - free(tmp); - return ret; -} - -#endif diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h deleted file mode 100644 index dea3bcc6..00000000 --- a/WDL/swell/swell-internal.h +++ /dev/null @@ -1,758 +0,0 @@ -#ifndef _SWELL_INTERNAL_H_ -#define _SWELL_INTERNAL_H_ - -#include "../ptrlist.h" - -#ifdef SWELL_TARGET_OSX - -#if 0 - // at some point we should enable this and use it in most SWELL APIs that call Cocoa code... - #define SWELL_BEGIN_TRY @try { - #define SWELL_END_TRY(x) } @catch (NSException *ex) { NSLog(@"SWELL exception in %s:%d :: %@:%@\n",__FILE__,__LINE__,[ex name], [ex reason]); x } -#else - #define SWELL_BEGIN_TRY - #define SWELL_END_TRY(x) -#endif - -#define __SWELL_PREFIX_CLASSNAME3(a,b) a##b -#define __SWELL_PREFIX_CLASSNAME2(a,b) __SWELL_PREFIX_CLASSNAME3(a,b) -#define __SWELL_PREFIX_CLASSNAME(cname) __SWELL_PREFIX_CLASSNAME2(SWELL_APP_PREFIX,cname) - -// this defines interfaces to internal swell classes -#define SWELL_hwndChild __SWELL_PREFIX_CLASSNAME(_hwnd) -#define SWELL_hwndCarbonHost __SWELL_PREFIX_CLASSNAME(_hwndcarbonhost) - -#define SWELL_ModelessWindow __SWELL_PREFIX_CLASSNAME(_modelesswindow) -#define SWELL_ModalDialog __SWELL_PREFIX_CLASSNAME(_dialogbox) - -#define SWELL_TextField __SWELL_PREFIX_CLASSNAME(_textfield) -#define SWELL_ListView __SWELL_PREFIX_CLASSNAME(_listview) -#define SWELL_TreeView __SWELL_PREFIX_CLASSNAME(_treeview) -#define SWELL_TabView __SWELL_PREFIX_CLASSNAME(_tabview) -#define SWELL_ProgressView __SWELL_PREFIX_CLASSNAME(_progind) -#define SWELL_TextView __SWELL_PREFIX_CLASSNAME(_textview) -#define SWELL_BoxView __SWELL_PREFIX_CLASSNAME(_box) -#define SWELL_Button __SWELL_PREFIX_CLASSNAME(_button) -#define SWELL_PopUpButton __SWELL_PREFIX_CLASSNAME(_pub) -#define SWELL_ComboBox __SWELL_PREFIX_CLASSNAME(_cbox) - -#define SWELL_StatusCell __SWELL_PREFIX_CLASSNAME(_statuscell) -#define SWELL_ListViewCell __SWELL_PREFIX_CLASSNAME(_listviewcell) -#define SWELL_ODListViewCell __SWELL_PREFIX_CLASSNAME(_ODlistviewcell) -#define SWELL_ODButtonCell __SWELL_PREFIX_CLASSNAME(_ODbuttoncell) - -#define SWELL_FocusRectWnd __SWELL_PREFIX_CLASSNAME(_drawfocusrectwnd) - -#define SWELL_DataHold __SWELL_PREFIX_CLASSNAME(_sdh) -#define SWELL_ThreadTmp __SWELL_PREFIX_CLASSNAME(_thread) -#define SWELL_PopupMenuRecv __SWELL_PREFIX_CLASSNAME(_trackpopupmenurecv) - -#define SWELL_TimerFuncTarget __SWELL_PREFIX_CLASSNAME(_tft) - - -#define SWELL_Menu __SWELL_PREFIX_CLASSNAME(_menu) - -#ifdef __OBJC__ - - -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 -typedef int NSInteger; -typedef unsigned int NSUInteger; -#endif - -@interface SWELL_Menu : NSMenu -{ -} --(void)dealloc; -- (id)copyWithZone:(NSZone *)zone; -@end - -@interface SWELL_DataHold : NSObject -{ - void *m_data; -} --(id) initWithVal:(void *)val; --(void *) getValue; -@end - -@interface SWELL_TimerFuncTarget : NSObject -{ - TIMERPROC m_cb; - HWND m_hwnd; - UINT_PTR m_timerid; -} --(id) initWithId:(UINT_PTR)tid hwnd:(HWND)h callback:(TIMERPROC)cb; --(void)SWELL_Timer:(id)sender; -@end - -typedef struct OwnedWindowListRec -{ - NSWindow *hwnd; - struct OwnedWindowListRec *_next; -} OwnedWindowListRec; - -typedef struct WindowPropRec -{ - char *name; // either <64k or a strdup'd name - void *data; - struct WindowPropRec *_next; -} WindowPropRec; - - -class SWELL_ListView_Row -{ -public: - SWELL_ListView_Row(); - ~SWELL_ListView_Row(); - WDL_PtrList m_vals; - LPARAM m_param; - int m_imageidx; - - int m_tmp; -}; - - -struct HTREEITEM__ -{ - HTREEITEM__(); - ~HTREEITEM__(); - bool FindItem(HTREEITEM it, HTREEITEM__ **parOut, int *idxOut); - - SWELL_DataHold *m_dh; - - bool m_haschildren; - char *m_value; - WDL_PtrList m_children; // only used in tree mode - LPARAM m_param; -}; - - - -@interface SWELL_TextField : NSTextField -- (void)setNeedsDisplay:(BOOL)flag; -- (void)setNeedsDisplayInRect:(NSRect)rect; -@end - -@interface SWELL_TabView : NSTabView -{ - NSInteger m_tag; - id m_dest; -} -@end - -@interface SWELL_ProgressView : NSProgressIndicator -{ - NSInteger m_tag; -} -@end - -@interface SWELL_ListViewCell : NSTextFieldCell -{ -} -@end - -@interface SWELL_StatusCell : NSTextFieldCell -{ - NSImage *status; -} -@end - -@interface SWELL_TreeView : NSOutlineView -{ - @public - bool m_fakerightmouse; - LONG style; - WDL_PtrList *m_items; - NSColor *m_fgColor; - NSMutableArray *m_selColors; -} -@end - -@interface SWELL_ListView : NSTableView -{ - int m_leftmousemovecnt; - bool m_fakerightmouse; - @public - LONG style; - int ownermode_cnt; - int m_start_item; - int m_start_subitem; - int m_start_item_clickmode; - int m_lbMode; - WDL_PtrList *m_items; - WDL_PtrList *m_cols; - WDL_PtrList *m_status_imagelist; - int m_status_imagelist_type; - int m_fastClickMask; - NSColor *m_fgColor; - NSMutableArray *m_selColors; -} --(LONG)getSwellStyle; --(void)setSwellStyle:(LONG)st; --(int)getSwellNotificationMode; --(void)setSwellNotificationMode:(int)lbMode; --(int)columnAtPoint:(NSPoint)pt; --(int)getColumnPos:(int)idx; // get current position of column that was originally at idx --(int)getColumnIdx:(int)pos; // get original index of column that is currently at position -@end - -@interface SWELL_ODButtonCell : NSButtonCell -{ -} -@end - -@interface SWELL_ODListViewCell : NSCell -{ - SWELL_ListView *m_ownctl; - int m_lastidx; -} --(void)setOwnerControl:(SWELL_ListView *)t; --(void)setItemIdx:(int)idx; -@end - -@interface SWELL_Button : NSButton -{ - void *m_swellGDIimage; - LONG_PTR m_userdata; - int m_radioflags; -} --(int)swellGetRadioFlags; --(void)swellSetRadioFlags:(int)f; --(LONG_PTR)getSwellUserData; --(void)setSwellUserData:(LONG_PTR)val; --(void)setSwellGDIImage:(void *)par; --(void *)getSwellGDIImage; -@end - -@interface SWELL_TextView : NSTextView -{ - NSInteger m_tag; -} --(NSInteger) tag; --(void) setTag:(NSInteger)tag; -@end - -@interface SWELL_BoxView : NSBox -{ - NSInteger m_tag; -} --(NSInteger) tag; --(void) setTag:(NSInteger)tag; -@end - -@interface SWELL_FocusRectWnd : NSView -{ -} -@end - -@interface SWELL_ThreadTmp : NSObject -{ -@public - void *a, *b; -} --(void)bla:(id)obj; -@end - - - -@interface SWELL_hwndChild : NSView // -{ -@public - BOOL m_enabled; - DLGPROC m_dlgproc; - WNDPROC m_wndproc; - LONG_PTR m_userdata; - LONG_PTR m_extradata[32]; - NSInteger m_tag; - int m_isfakerightmouse; - char m_hashaddestroy; // 2 = WM_DESTROY has finished completely - HMENU m_menu; - BOOL m_flip; - bool m_supports_ddrop; - bool m_paintctx_used; - HDC m_paintctx_hdc; - WindowPropRec *m_props; - NSRect m_paintctx_rect; - BOOL m_isopaque; - char m_titlestr[1024]; - unsigned int m_create_windowflags; - NSOpenGLContext *m_glctx; - char m_isdirty; // &1=self needs redraw, &2=children may need redraw - id m_lastTopLevelOwner; // save a copy of the owner, if any - id m_access_cacheptrs[6]; -} -- (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par; -- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam; --(HANDLE)swellExtendedDragOp:(id )sender retGlob:(BOOL)retG; -- (const char *)onSwellGetText; --(void)onSwellSetText:(const char *)buf; --(LONG)swellGetExtendedStyle; --(void)swellSetExtendedStyle:(LONG)st; --(HMENU)swellGetMenu; --(BOOL)swellHasBeenDestroyed; --(void)swellSetMenu:(HMENU)menu; --(LONG_PTR)getSwellUserData; --(void)setSwellUserData:(LONG_PTR)val; --(void)setOpaque:(bool)isOpaque; --(LPARAM)getSwellExtraData:(int)idx; --(void)setSwellExtraData:(int)idx value:(LPARAM)val; --(void)setSwellWindowProc:(WNDPROC)val; --(WNDPROC)getSwellWindowProc; --(void)setSwellDialogProc:(DLGPROC)val; --(DLGPROC)getSwellDialogProc; - -- (NSArray*) namesOfPromisedFilesDroppedAtDestination:(NSURL*)droplocation; - --(void) getSwellPaintInfo:(PAINTSTRUCT *)ps; -- (int)swellCapChangeNotify; --(unsigned int)swellCreateWindowFlags; - --(bool)swellCanPostMessage; --(int)swellEnumProps:(PROPENUMPROCEX)proc lp:(LPARAM)lParam; --(void *)swellGetProp:(const char *)name wantRemove:(BOOL)rem; --(int)swellSetProp:(const char *)name value:(void *)val ; - - -// NSAccessibility - -// attribute methods -- (NSArray *)accessibilityAttributeNames; -- (id)accessibilityAttributeValue:(NSString *)attribute; -- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; -- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; - -// parameterized attribute methods -- (NSArray *)accessibilityParameterizedAttributeNames; -- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter; - -// action methods -- (NSArray *)accessibilityActionNames; -- (NSString *)accessibilityActionDescription:(NSString *)action; -- (void)accessibilityPerformAction:(NSString *)action; - -// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. -- (BOOL)accessibilityIsIgnored; - -// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. -- (id)accessibilityHitTest:(NSPoint)point; - -// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. -- (id)accessibilityFocusedUIElement; - - - - -@end - -@interface SWELL_ModelessWindow : NSWindow -{ -@public - NSSize lastFrameSize; - id m_owner; - OwnedWindowListRec *m_ownedwnds; - BOOL m_enabled; - int m_wantraiseamt; - bool m_wantInitialKeyWindowOnShow; -} -- (id)initModeless:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par outputHwnd:(HWND *)hwndOut forceStyles:(unsigned int)smask; -- (id)initModelessForChild:(HWND)child owner:(HWND)owner styleMask:(unsigned int)smask; -- (void)swellDestroyAllOwnedWindows; -- (void)swellRemoveOwnedWindow:(NSWindow *)wnd; -- (void)swellSetOwner:(id)owner; -- (id)swellGetOwner; -- (void **)swellGetOwnerWindowHead; --(void)swellDoDestroyStuff; --(void)swellResetOwnedWindowLevels; -@end - -@interface SWELL_ModalDialog : NSPanel -{ - NSSize lastFrameSize; - id m_owner; - OwnedWindowListRec *m_ownedwnds; - - int m_rv; - bool m_hasrv; - BOOL m_enabled; -} -- (id)initDialogBox:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par; -- (void)swellDestroyAllOwnedWindows; -- (void)swellRemoveOwnedWindow:(NSWindow *)wnd; -- (void)swellSetOwner:(id)owner; -- (id)swellGetOwner; -- (void **)swellGetOwnerWindowHead; --(void)swellDoDestroyStuff; - --(void)swellSetModalRetVal:(int)r; --(int)swellGetModalRetVal; --(bool)swellHasModalRetVal; -@end - - -@interface SWELL_hwndCarbonHost : SWELL_hwndChild -{ -@public - NSWindow *m_cwnd; - - bool m_whileresizing; - void* m_wndhandler; // won't compile if declared EventHandlerRef, wtf - void* m_ctlhandler; // not sure if these need to be separate but cant hurt - bool m_wantallkeys; -} --(BOOL)swellIsCarbonHostingView; --(void)swellDoRepos; -@end - - -@interface SWELL_PopupMenuRecv : NSObject -{ - int m_act; - HWND cbwnd; -} --(id) initWithWnd:(HWND)wnd; --(void) onSwellCommand:(id)sender; --(int) isCommand; -- (void)menuNeedsUpdate:(NSMenu *)menu; - -@end - -@interface SWELL_PopUpButton : NSPopUpButton -{ - LONG m_style; -} --(void)setSwellStyle:(LONG)style; --(LONG)getSwellStyle; -@end - -@interface SWELL_ComboBox : NSComboBox -{ -@public - LONG m_style; - WDL_PtrList *m_ids; -} --(id)init; --(void)dealloc; --(void)setSwellStyle:(LONG)style; --(LONG)getSwellStyle; -@end - - - -// GDI internals - - -// 10.4 doesn't support CoreText, so allow ATSUI if targetting 10.4 SDK -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -#ifndef __LP64__ -#define SWELL_ATSUI_TEXT_SUPPORT -#endif -#endif - -struct HGDIOBJ__ -{ - int type; - - int additional_refcnt; // refcnt of 0 means one owner (if >0, additional owners) - - // used by pen/brush - CGColorRef color; - int wid; - NSImage *bitmapptr; - - NSMutableDictionary *__old_fontdict; // unused, for ABI compat - // - // if ATSUI used, meaning IsCoreTextSupported() returned false - ATSUStyle atsui_font_style; - - float font_rotation; - - bool _infreelist; - struct HGDIOBJ__ *_next; - - // if using CoreText to draw text - void *ct_FontRef; -}; - -struct HDC__ { - CGContextRef ctx; - void *ownedData; // always use via SWELL_GetContextFrameBuffer() (which performs necessary alignment) - HGDIOBJ__ *curpen; - HGDIOBJ__ *curbrush; - HGDIOBJ__ *curfont; - - NSColor *__old_nstextcol; // provided for ABI compat, but unused - int cur_text_color_int; // text color as int - - int curbkcol; - int curbkmode; - float lastpos_x,lastpos_y; - - void *GLgfxctx; // optionally set - bool _infreelist; - struct HDC__ *_next; - - CGColorRef curtextcol; // text color as CGColor -}; - - - - - -// some extras so we can call functions available only on some OSX versions without warnings, and with the correct types -#define SWELL_DelegateExtensions __SWELL_PREFIX_CLASSNAME(_delext) -#define SWELL_ViewExtensions __SWELL_PREFIX_CLASSNAME(_viewext) -#define SWELL_AppExtensions __SWELL_PREFIX_CLASSNAME(_appext) -#define SWELL_WindowExtensions __SWELL_PREFIX_CLASSNAME(_wndext) -#define SWELL_TableColumnExtensions __SWELL_PREFIX_CLASSNAME(_tcolext) - -@interface SWELL_WindowExtensions : NSWindow --(void)setCollectionBehavior:(NSUInteger)a; -@end -@interface SWELL_ViewExtensions : NSView --(void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)vr rectIsVisibleRectForView:(NSView*)v topView:(NSView *)v2; -@end - -@interface SWELL_DelegateExtensions : NSObject --(bool)swellPostMessage:(HWND)dest msg:(int)message wp:(WPARAM)wParam lp:(LPARAM)lParam; --(void)swellPostMessageClearQ:(HWND)dest; --(void)swellPostMessageTick:(id)sender; -@end - -@interface SWELL_AppExtensions : NSApplication --(NSUInteger)presentationOptions; --(void)setPresentationOptions:(NSUInteger)o; -@end -@interface SWELL_TableColumnExtensions : NSTableColumn --(BOOL)isHidden; --(void)setHidden:(BOOL)h; -@end - - - - - -#endif // __OBJC__ - -// 10.4 sdk just uses "float" -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 -typedef float CGFloat; -#endif - - -#elif defined(SWELL_TARGET_GDK) - -#include -#include - -#else -// generic - -#endif // end generic - -#ifndef SWELL_TARGET_OSX - -#ifdef SWELL_LICE_GDI -#include "../lice/lice.h" -#endif -#include "../assocarray.h" - -LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -struct HWND__ -{ - HWND__(HWND par, int wID=0, RECT *wndr=NULL, const char *label=NULL, bool visible=false, WNDPROC wndproc=NULL, DLGPROC dlgproc=NULL); - ~HWND__(); // DO NOT USE!!! We would make this private but it breaks PtrList using it on gcc. - - // using this API prevents the HWND from being valid -- it'll still get its resources destroyed via DestroyWindow() though. - // DestroyWindow() does cleanup, then the final Release(). - void Retain() { m_refcnt++; } - void Release() { if (!--m_refcnt) delete this; } - - - - - const char *m_classname; - - -#ifdef SWELL_TARGET_GDK - GdkWindow *m_oswindow; -#endif - char *m_title; - - HWND__ *m_children, *m_parent, *m_next, *m_prev; - HWND__ *m_owner, *m_owned; - RECT m_position; - int m_id; - int m_style, m_exstyle; - INT_PTR m_userdata; - WNDPROC m_wndproc; - DLGPROC m_dlgproc; - INT_PTR m_extra[64]; - INT_PTR m_private_data; // used by internal controls - - bool m_visible; - bool m_hashaddestroy; - bool m_enabled; - bool m_wantfocus; - - int m_refcnt; - - HMENU m_menu; - - WDL_StringKeyedArray m_props; - -#ifdef SWELL_LICE_GDI - void *m_paintctx; // temporarily set for calls to WM_PAINT - -// todo: - bool m_child_invalidated; // if a child is invalidated - bool m_invalidated; // set to true on direct invalidate. todo RECT instead? - - LICE_IBitmap *m_backingstore; // if NULL, unused (probably only should use on top level windows, but support caching?) -#endif -}; - -struct HMENU__ -{ - HMENU__() { } - ~HMENU__() { items.Empty(true,freeMenuItem); } - - WDL_PtrList items; - - HMENU__ *Duplicate(); - static void freeMenuItem(void *p); - -}; - - -struct HGDIOBJ__ -{ - int type; - int additional_refcnt; // refcnt of 0 means one owner (if >0, additional owners) - - int color; - int wid; - - struct HGDIOBJ__ *_next; - bool _infreelist; -#ifdef SWELL_FREETYPE - void *fontface; // FT_Face -#endif - -}; - - -struct HDC__ { -#ifdef SWELL_LICE_GDI - LICE_IBitmap *surface; // owned by context. can be (and usually is, if clipping is desired) LICE_SubBitmap - POINT surface_offs; // offset drawing into surface by this amount - - RECT dirty_rect; // in surface coordinates, used for GetWindowDC()/GetDC()/etc - bool dirty_rect_valid; -#else - void *ownedData; // for mem contexts, support a null rendering -#endif - - HGDIOBJ__ *curpen; - HGDIOBJ__ *curbrush; - HGDIOBJ__ *curfont; - - int cur_text_color_int; // text color as int - - int curbkcol; - int curbkmode; - float lastpos_x,lastpos_y; - - struct HDC__ *_next; - bool _infreelist; -}; - -#endif // !OSX - -HDC SWELL_CreateGfxContext(void *); - -// GDP internals -#define TYPE_PEN 1 -#define TYPE_BRUSH 2 -#define TYPE_FONT 3 -#define TYPE_BITMAP 4 - -typedef struct -{ - void *instptr; - void *bundleinstptr; - int refcnt; - - int (*SWELL_dllMain)(HINSTANCE, DWORD,LPVOID); //last parm=SWELLAPI_GetFunc - BOOL (*dllMain)(HINSTANCE, DWORD, LPVOID); - void *lastSymbolRequested; -} SWELL_HINSTANCE; - - -enum -{ - INTERNAL_OBJECT_START= 0x1000001, - INTERNAL_OBJECT_THREAD, - INTERNAL_OBJECT_EVENT, - INTERNAL_OBJECT_FILE, - INTERNAL_OBJECT_EXTERNALSOCKET, // socket not owned by us - INTERNAL_OBJECT_SOCKETEVENT, - INTERNAL_OBJECT_NSTASK, - INTERNAL_OBJECT_END -}; - -typedef struct -{ - int type; // INTERNAL_OBJECT_* - int count; // reference count -} SWELL_InternalObjectHeader; - -typedef struct -{ - SWELL_InternalObjectHeader hdr; - DWORD (*threadProc)(LPVOID); - void *threadParm; - pthread_t pt; - DWORD retv; - bool done; -} SWELL_InternalObjectHeader_Thread; - -typedef struct -{ - SWELL_InternalObjectHeader hdr; - - pthread_mutex_t mutex; - pthread_cond_t cond; - - bool isSignal; - bool isManualReset; - -} SWELL_InternalObjectHeader_Event; - - -// used for both INTERNAL_OBJECT_EXTERNALSOCKET and INTERNAL_OBJECT_SOCKETEVENT. -// if EXTERNALSOCKET, socket[1] ignored and autoReset ignored. -typedef struct -{ - SWELL_InternalObjectHeader hdr; - int socket[2]; - bool autoReset; -} SWELL_InternalObjectHeader_SocketEvent; - -typedef struct -{ - SWELL_InternalObjectHeader hdr; - - FILE *fp; -} SWELL_InternalObjectHeader_File; - -typedef struct -{ - SWELL_InternalObjectHeader hdr; - void *task; -} SWELL_InternalObjectHeader_NSTask; - - -bool IsRightClickEmulateEnabled(); - -#endif diff --git a/WDL/swell/swell-kb-generic.cpp b/WDL/swell/swell-kb-generic.cpp deleted file mode 100644 index ecaaeab4..00000000 --- a/WDL/swell/swell-kb-generic.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux? - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic key and mouse cursor querying, as well as a key to windows key translation function. - - */ - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-dlggen.h" - -int SWELL_KeyToASCII(int wParam, int lParam, int *newflags) -{ - if (wParam >= '0' && wParam <= '9' && lParam == (FSHIFT|FVIRTKEY)) - { - // todo: some OS X API for this? - *newflags = lParam&~(FSHIFT|FVIRTKEY); - switch (wParam) - { - case '1': return '!'; - case '2': return '@'; - case '3': return '#'; - case '4': return '$'; - case '5': return '%'; - case '6': return '^'; - case '7': return '&'; - case '8': return '*'; - case '9': return '('; - case '0': return ')'; - } - } - return 0; -} - - -SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; - -HCURSOR SWELL_LoadCursor(const char *_idx) -{ - return NULL; -} - -static HCURSOR m_last_setcursor; - -void SWELL_SetCursor(HCURSOR curs) -{ - m_last_setcursor=curs; - // todo -} - -HCURSOR SWELL_GetCursor() -{ - return m_last_setcursor; -} -HCURSOR SWELL_GetLastSetCursor() -{ - return m_last_setcursor; -} - - - - -static int m_curvis_cnt; -bool SWELL_IsCursorVisible() -{ - return m_curvis_cnt>=0; -} -int SWELL_ShowCursor(BOOL bShow) -{ - m_curvis_cnt += (bShow?1:-1); - if (m_curvis_cnt==-1 && !bShow) - { - } - if (m_curvis_cnt==0 && bShow) - { - } - return m_curvis_cnt; -} - - -BOOL SWELL_SetCursorPos(int X, int Y) -{ - - return false; -} - -HCURSOR SWELL_LoadCursorFromFile(const char *fn) -{ - return NULL; -} - -#endif diff --git a/WDL/swell/swell-kb.mm b/WDL/swell/swell-kb.mm deleted file mode 100644 index bf494385..00000000 --- a/WDL/swell/swell-kb.mm +++ /dev/null @@ -1,601 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic key and mouse cursor querying, as well as a mac key to windows key translation function. - - */ - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-dlggen.h" -#import -#import - - - -static int MacKeyCodeToVK(int code) -{ - switch (code) - { - case 51: return VK_BACK; - case 65: return VK_DECIMAL; - case 67: return VK_MULTIPLY; - case 69: return VK_ADD; - case 71: return VK_NUMLOCK; - case 75: return VK_DIVIDE; - case 76: return VK_RETURN|0x8000; - case 78: return VK_SUBTRACT; - case 81: return VK_SEPARATOR; - case 82: return VK_NUMPAD0; - case 83: return VK_NUMPAD1; - case 84: return VK_NUMPAD2; - case 85: return VK_NUMPAD3; - case 86: return VK_NUMPAD4; - case 87: return VK_NUMPAD5; - case 88: return VK_NUMPAD6; - case 89: return VK_NUMPAD7; - case 91: return VK_NUMPAD8; - case 92: return VK_NUMPAD9; - case 96: return VK_F5; - case 97: return VK_F6; - case 98: return VK_F7; - case 99: return VK_F3; - case 100: return VK_F8; - case 101: return VK_F9; - case 109: return VK_F10; - case 103: return VK_F11; - case 105: return VK_SNAPSHOT; - case 111: return VK_F12; - case 114: return VK_INSERT; - case 115: return VK_HOME; - case 117: return VK_DELETE; - case 116: return VK_PRIOR; - case 118: return VK_F4; - case 119: return VK_END; - case 120: return VK_F2; - case 121: return VK_NEXT; - case 122: return VK_F1; - case 123: return VK_LEFT; - case 124: return VK_RIGHT; - case 125: return VK_DOWN; - case 126: return VK_UP; - } - return 0; -} - -bool IsRightClickEmulateEnabled(); - - -int SWELL_MacKeyToWindowsKey(void *nsevent, int *flags) -{ - NSEvent *theEvent = (NSEvent *)nsevent; - int mod=[theEvent modifierFlags];// & ( NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask); - // if ([theEvent isARepeat]) return; - - int flag=0; - if (mod & NSShiftKeyMask) flag|=FSHIFT; - if (mod & NSCommandKeyMask) flag|=FCONTROL; // todo: this should be command once we figure it out - if (mod & NSAlternateKeyMask) flag|=FALT; - if ((mod&NSControlKeyMask) && !IsRightClickEmulateEnabled()) flag|=FLWIN; - - int rawcode=[theEvent keyCode]; - - int code=MacKeyCodeToVK(rawcode); - if (!code) - { - NSString *str=[theEvent charactersIgnoringModifiers]; -// if (!str || ![str length]) str=[theEvent characters]; - - if (!str || ![str length]) - { - code = 1024+rawcode; // raw code - flag|=FVIRTKEY; - } - else - { - code=[str characterAtIndex:0]; - if (code >= 'a' && code <= 'z') code+='A'-'a'; - if (code == 25 && (flag&FSHIFT)) code=VK_TAB; - if (isalnum(code)||code==' ' || code == '\r' || code == '\n' || code ==27 || code == VK_TAB) flag|=FVIRTKEY; - } - } - else - { - flag|=FVIRTKEY; - if (code==8) code='\b'; - } - - if (!(flag&FVIRTKEY)) flag&=~FSHIFT; - - if (flags) *flags=flag; - return code; -} - -int SWELL_KeyToASCII(int wParam, int lParam, int *newflags) -{ - if (wParam >= '0' && wParam <= '9' && lParam == (FSHIFT|FVIRTKEY)) - { - *newflags = lParam&~(FSHIFT|FVIRTKEY); - if (!(lParam & (FCONTROL|FLWIN))) switch (wParam) - { - case '1': return '!'; - case '2': return '@'; - case '3': return '#'; - case '4': return '$'; - case '5': return '%'; - case '6': return '^'; - case '7': return '&'; - case '8': return '*'; - case '9': return '('; - case '0': return ')'; - } - } - return 0; -} - - -WORD GetAsyncKeyState(int key) -{ - int state=0; - if (key == VK_LBUTTON || key == VK_RBUTTON || key == VK_MBUTTON) - { - state=GetCurrentEventButtonState(); - } - else - { - state=CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState); - } - - if ((key == VK_LBUTTON && (state&1)) || - (key == VK_RBUTTON && (state&2)) || - (key == VK_MBUTTON && (state&4)) || - (key == VK_SHIFT && (state&kCGEventFlagMaskShift)) || - (key == VK_CONTROL && (state&kCGEventFlagMaskCommand)) || - (key == VK_MENU && (state&kCGEventFlagMaskAlternate)) || - (key == VK_LWIN && !IsRightClickEmulateEnabled() && (state&kCGEventFlagMaskControl))) - { - return 0x8000; - } - - return 0; -} - - -SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; - -static NSCursor* MakeCursorFromData(unsigned char* data, int hotspot_x, int hotspot_y) -{ - NSCursor *c=NULL; - NSBitmapImageRep* bmp = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:0 - pixelsWide:16 - pixelsHigh:16 - bitsPerSample:8 - samplesPerPixel:2 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedWhiteColorSpace - bytesPerRow:(16*2) - bitsPerPixel:16]; - - if (bmp) - { - unsigned char* p = [bmp bitmapData]; - if (p) - { - int i; - for (i = 0; i < 16*16; ++i) - { - // tried 4 bits per sample and memcpy, didn't work - p[2*i] = (data[i]&0xF0) | data[i]>>4; - p[2*i+1] = (data[i]<<4) | (data[i]&0xf); - } - - NSImage *img = [[NSImage alloc] init]; - if (img) - { - [img addRepresentation:bmp]; - NSPoint hs = { hotspot_x, hotspot_y }; - c = [[NSCursor alloc] initWithImage:img hotSpot:hs]; - [img release]; - } - } - [bmp release]; - } - return c; -} - -static NSCursor* MakeSWELLSystemCursor(const char *id) -{ - // bytemaps are (white<<4)|(alpha) - const unsigned char B = 0xF; - const unsigned char W = 0xFF; - const unsigned char G = 0xF8; - - static NSCursor* carr[3] = { 0, 0, 0 }; - - NSCursor** pc=0; - if (id == IDC_SIZEALL) pc = &carr[0]; - else if (id == IDC_SIZENWSE) pc = &carr[1]; - else if (id == IDC_SIZENESW) pc = &carr[2]; - else return 0; - - if (!(*pc)) - { - if (id == IDC_SIZEALL) - { - static unsigned char p[16*16] = - { - 0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0, - 0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0, - 0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0, - 0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0, - G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G, - W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W, - W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W, - G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G, - 0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0, - 0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0, - 0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0, - 0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0, - }; - *pc = MakeCursorFromData(p, 8, 8); - } - else if (id == IDC_SIZENWSE || id == IDC_SIZENESW) - { - static unsigned char p[16*16] = - { - W, W, W, W, W, W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - W, G, G, G, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - W, G, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - W, W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, - W, G, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, G, W, - 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W, W, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, G, W, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, G, G, G, W, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W, W, W, W, W, W, - }; - if (id == IDC_SIZENESW) - { - int x, y; - for (y = 0; y < 16; ++y) - { - for (x = 0; x < 8; ++x) - { - unsigned char tmp = p[16*y+x]; - p[16*y+x] = p[16*y+16-x-1]; - p[16*y+16-x-1] = tmp; - } - } - } - *pc = MakeCursorFromData(p, 8, 8); - if (id == IDC_SIZENESW) // swap back! - { - int x, y; - for (y = 0; y < 16; ++y) - { - for (x = 0; x < 8; ++x) - { - unsigned char tmp = p[16*y+x]; - p[16*y+x] = p[16*y+16-x-1]; - p[16*y+16-x-1] = tmp; - } - } - } - } - else if (id == IDC_NO) - { - static unsigned char p[16*16] = - { - 0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0, - 0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0, - 0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0, - 0, W, B, B, W, W, G, 0, 0, G, W, G, B, B, W, 0, - G, W, B, W, G, 0, 0, 0, 0, G, W, B, G, B, W, G, - W, B, B, W, 0, 0, 0, 0, G, W, B, W, W, B, B, W, - W, B, W, G, 0, 0, 0, G, W, B, W, G, G, W, B, W, - W, B, W, 0, 0, 0, G, W, B, W, G, 0, 0, W, B, W, - W, B, W, 0, 0, G, W, B, W, G, 0, 0, 0, W, B, W, - W, B, W, G, G, W, B, W, G, 0, 0, 0, G, W, B, W, - W, B, B, W, W, B, W, G, 0, 0, 0, 0, W, B, B, W, - G, W, B, G, B, W, G, 0, 0, 0, 0, G, W, B, W, G, - 0, W, B, B, G, W, G, 0, 0, G, W, W, B, B, W, 0, - 0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0, - 0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0, - 0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0, - }; - *pc = MakeCursorFromData(p, 8, 8); - } - } - - return *pc; -} - -static NSImage *swell_imageFromCursorString(const char *name, POINT *hotSpot) -{ - NSImage *img=NULL; - FILE *fp = NULL; - bool isFullFn=false; - - if (!strstr(name,"/") && strlen(name)<1024) - { - char tmpn[4096]; - GetModuleFileName(NULL,tmpn,sizeof(tmpn)-128-strlen(name)); - strcat(tmpn,"/Contents/Resources/"); - strcat(tmpn,name); - strcat(tmpn,".cur"); - fp = fopen(tmpn,"rb"); - } - else - { - isFullFn=true; - if (strlen(name)>4 && !stricmp(name+strlen(name)-4,".cur")) fp = fopen(name,"rb"); - } - - if (fp) - { - unsigned char buf[4096]; - if (fread(buf,1,6,fp)==6 && !buf[0] && !buf[1] && buf[2] == 2 && buf[3] == 0 && buf[4] == 1 && buf[5] == 0) - { - static char tempfn[512]; - if (!tempfn[0]) - { - const char *p = getenv("TEMP"); - if (!p || !*p) p="/tmp"; - sprintf(tempfn,"%.200s/swellcur%x%x.ico",p,timeGetTime(),(int)getpid()); - } - - FILE *outfp = fopen(tempfn,"wb"); - if (outfp) - { - bool wantLoad=false; - buf[2]=1; // change to .ico - fwrite(buf,1,6,outfp); - - fread(buf,1,16,fp); - int xHot = buf[4]|(buf[5]<<8); - int yHot = buf[6]|(buf[7]<<8); - - buf[4]=1; buf[5]=0; // 1 color plane - buf[6]=0; buf[7]=0; // 0 for pixel depth means "auto" - - if (!buf[3]) - { - fwrite(buf,1,16,outfp); - for (;;) - { - int a = fread(buf,1,sizeof(buf),fp); - if (a<1) break; - fwrite(buf,1,a,outfp); - } - wantLoad=true; - } - - fclose(outfp); - if (wantLoad) - { - NSString *str = (NSString *)SWELL_CStringToCFString(tempfn); - img = [[NSImage alloc] initWithContentsOfFile:str]; - [str release]; - if (img && hotSpot) - { - hotSpot->x = xHot; - hotSpot->y = yHot; - } - // printf("loaded converted ico for %s %s %d\n",tempfn,name,!!img); - } - unlink(tempfn); - } - - } - - fclose(fp); - } - - if (!img) // fall back - { - NSString *str = (NSString *)SWELL_CStringToCFString(name); - - if (isFullFn) img = [[NSImage alloc] initWithContentsOfFile:str]; - else - { - img = [NSImage imageNamed:str]; - if (img) [img retain]; - } - [str release]; - } - - return img; -} - - -HCURSOR SWELL_LoadCursorFromFile(const char *fn) -{ - POINT hotspot={0,}; - NSImage *img = swell_imageFromCursorString(fn,&hotspot); - if (img) - { - HCURSOR ret=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(hotspot.x,hotspot.y)]; - [img release]; - return ret; - } - return NULL; -} - -// todo: support for loading from file -HCURSOR SWELL_LoadCursor(const char *_idx) -{ - if (_idx == IDC_NO||_idx==IDC_SIZENWSE || _idx == IDC_SIZENESW || _idx == IDC_SIZEALL) return (HCURSOR) MakeSWELLSystemCursor(_idx); - if (_idx == IDC_SIZEWE) return (HCURSOR)[NSCursor resizeLeftRightCursor]; - if (_idx == IDC_SIZENS) return (HCURSOR)[NSCursor resizeUpDownCursor]; - if (_idx == IDC_ARROW) return (HCURSOR)[NSCursor arrowCursor]; - if (_idx == IDC_HAND) return (HCURSOR)[NSCursor openHandCursor]; - if (_idx == IDC_UPARROW) return (HCURSOR)[NSCursor resizeUpCursor]; - if (_idx == IDC_IBEAM) return (HCURSOR)[NSCursor IBeamCursor]; - - // search registered cursor list - SWELL_CursorResourceIndex *p = SWELL_curmodule_cursorresource_head; - while (p) - { - if (p->resid == _idx) - { - if (p->cachedCursor) return p->cachedCursor; - - NSImage *img = swell_imageFromCursorString(p->resname,&p->hotspot); - if (img) - { - p->cachedCursor=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(p->hotspot.x,p->hotspot.y)]; - [img release]; - return p->cachedCursor; - } - } - p=p->_next; - } - return 0; -} - -static HCURSOR m_last_setcursor; - -void SWELL_SetCursor(HCURSOR curs) -{ - if (curs && [(id) curs isKindOfClass:[NSCursor class]]) - { - m_last_setcursor=curs; - [(NSCursor *)curs set]; - } - else - { - m_last_setcursor=NULL; - [[NSCursor arrowCursor] set]; - } -} - -HCURSOR SWELL_GetCursor() -{ - return (HCURSOR)[NSCursor currentCursor]; -} -HCURSOR SWELL_GetLastSetCursor() -{ - return m_last_setcursor; -} - -static POINT g_swell_mouse_relmode_curpos; // stored in osx-native coordinates (y=0=top of screen) -static bool g_swell_mouse_relmode; - - - -void GetCursorPos(POINT *pt) -{ - if (g_swell_mouse_relmode) - { - *pt=g_swell_mouse_relmode_curpos; - return; - } - NSPoint localpt=[NSEvent mouseLocation]; - pt->x=(int)floor(localpt.x); - pt->y=-(int)floor(-localpt.y); // floor() is used with negative sign, effectively ceil(), because screen coordinates are flipped and everywhere else we use nonflipped rounding -} - -DWORD GetMessagePos() -{ - if (g_swell_mouse_relmode) - { - return MAKELONG((int)g_swell_mouse_relmode_curpos.x,(int)g_swell_mouse_relmode_curpos.y); - } - NSPoint localpt=[NSEvent mouseLocation]; - return MAKELONG((int)floor(localpt.x), -(int)floor(-localpt.y)); // floor() is used with negative sign, effectively ceil(), because screen coordinates are flipped and everywhere else we use nonflipped rounding -} - - -NSPoint swellProcessMouseEvent(int msg, NSView *view, NSEvent *event) -{ - if (g_swell_mouse_relmode && msg==WM_MOUSEMOVE) // event will have relative coordinates - { - int idx=(int)[event deltaX]; - int idy=(int)[event deltaY]; - g_swell_mouse_relmode_curpos.x += idx; - g_swell_mouse_relmode_curpos.y -= idy; - } - if (g_swell_mouse_relmode) - { - POINT p=g_swell_mouse_relmode_curpos; - ScreenToClient((HWND)view,&p); - return NSMakePoint(p.x,p.y); - } - NSPoint localpt=[event locationInWindow]; - return [view convertPoint:localpt fromView:nil]; -} - -static int m_curvis_cnt; -bool SWELL_IsCursorVisible() -{ - return m_curvis_cnt>=0; -} -int SWELL_ShowCursor(BOOL bShow) -{ - m_curvis_cnt += (bShow?1:-1); - if (m_curvis_cnt==-1 && !bShow) - { - GetCursorPos(&g_swell_mouse_relmode_curpos); - CGDisplayHideCursor(kCGDirectMainDisplay); - CGAssociateMouseAndMouseCursorPosition(false); - g_swell_mouse_relmode=true; - } - if (m_curvis_cnt==0 && bShow) - { - CGDisplayShowCursor(kCGDirectMainDisplay); - CGAssociateMouseAndMouseCursorPosition(true); - g_swell_mouse_relmode=false; - SetCursorPos(g_swell_mouse_relmode_curpos.x,g_swell_mouse_relmode_curpos.y); - } - return m_curvis_cnt; -} - - -BOOL SWELL_SetCursorPos(int X, int Y) -{ - if (g_swell_mouse_relmode) - { - g_swell_mouse_relmode_curpos.x=X; - g_swell_mouse_relmode_curpos.y=Y; - return TRUE; - } - - - int h=CGDisplayPixelsHigh(CGMainDisplayID()); - CGPoint pos=CGPointMake(X,h-Y); - return CGWarpMouseCursorPosition(pos)==kCGErrorSuccess; -} - - - -#endif diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp deleted file mode 100644 index 65dd4afc..00000000 --- a/WDL/swell/swell-menu-generic.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic windows menu API - - */ - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-menugen.h" - -#include "swell-internal.h" - -#include "../ptrlist.h" - -HMENU__ *HMENU__::Duplicate() -{ - HMENU__ *p = new HMENU__; - int x; - for (x = 0; x < items.GetSize(); x ++) - { - MENUITEMINFO *s = items.Get(x); - MENUITEMINFO *inf = (MENUITEMINFO*)calloc(sizeof(MENUITEMINFO),1); - - *inf = *s; - if (inf->dwTypeData) - { - // todo handle bitmap types - inf->dwTypeData=strdup(inf->dwTypeData); - } - if (inf->hSubMenu) inf->hSubMenu = inf->hSubMenu->Duplicate(); - - p->items.Add(inf); - } - return p; -} - -void HMENU__::freeMenuItem(void *p) -{ - MENUITEMINFO *inf = (MENUITEMINFO *)p; - if (!inf) return; - delete inf->hSubMenu; - free(inf->dwTypeData); // todo handle bitmap types - free(inf); -} - -static MENUITEMINFO *GetMenuItemByID(HMENU menu, int id, bool searchChildren=true) -{ - if (!menu) return 0; - int x; - for (x = 0; x < menu->items.GetSize(); x ++) - if (menu->items.Get(x)->wID == id) return menu->items.Get(x); - - if (searchChildren) for (x = 0; x < menu->items.GetSize(); x ++) - { - if (menu->items.Get(x)->hSubMenu) - { - MENUITEMINFO *ret = GetMenuItemByID(menu->items.Get(x)->hSubMenu,id,true); - if (ret) return ret; - } - } - - return 0; -} - -bool SetMenuItemText(HMENU hMenu, int idx, int flag, const char *text) -{ - MENUITEMINFO *item = hMenu ? ((flag & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; - if (!item) return false; - - item->fType = MFT_STRING; - free(item->dwTypeData); // todo handle bitmap types - item->dwTypeData=strdup(text?text:""); - - return true; -} - -bool EnableMenuItem(HMENU hMenu, int idx, int en) -{ - MENUITEMINFO *item = hMenu ? ((en & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; - if (!item) return false; - - int mask = MF_ENABLED|MF_DISABLED|MF_GRAYED; - item->fState &= ~mask; - item->fState |= en&mask; - - return true; -} - -bool CheckMenuItem(HMENU hMenu, int idx, int chk) -{ - MENUITEMINFO *item = hMenu ? ((chk & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; - if (!item) return false; - - int mask = MF_CHECKED; - item->fState &= ~mask; - item->fState |= chk&mask; - - return true; -} -HMENU SWELL_GetCurrentMenu() -{ - return NULL; // not osx -} -void SWELL_SetCurrentMenu(HMENU hmenu) -{ -} - -HMENU GetSubMenu(HMENU hMenu, int pos) -{ - MENUITEMINFO *item = hMenu ? hMenu->items.Get(pos) : NULL; - if (item) return item->hSubMenu; - return 0; -} - -int GetMenuItemCount(HMENU hMenu) -{ - if (hMenu) return hMenu->items.GetSize(); - return 0; -} - -int GetMenuItemID(HMENU hMenu, int pos) -{ - MENUITEMINFO *item = hMenu ? hMenu->items.Get(pos) : NULL; - if (!item || item->hSubMenu) return -1; - return item->wID; -} - -bool SetMenuItemModifier(HMENU hMenu, int idx, int flag, int code, unsigned int mask) -{ - return false; -} - -HMENU CreatePopupMenu() -{ - return new HMENU__; -} -HMENU CreatePopupMenuEx(const char *title) -{ - return CreatePopupMenu(); -} - -void DestroyMenu(HMENU hMenu) -{ - delete hMenu; -} - -int AddMenuItem(HMENU hMenu, int pos, const char *name, int tagid) -{ - if (!hMenu) return -1; - MENUITEMINFO *inf = (MENUITEMINFO*)calloc(1,sizeof(MENUITEMINFO)); - inf->wID = tagid; - inf->dwTypeData = strdup(name?name:""); - hMenu->items.Insert(pos,inf); - return 0; -} - -bool DeleteMenu(HMENU hMenu, int idx, int flag) -{ - if (!hMenu) return false; - if (flag&MF_BYPOSITION) - { - if (hMenu->items.Get(idx)) - { - hMenu->items.Delete(idx,true,HMENU__::freeMenuItem); - return true; - } - return false; - } - else - { - int x; - int cnt=0; - for (x=0;xitems.GetSize(); x ++) - { - if (!hMenu->items.Get(x)->hSubMenu && hMenu->items.Get(x)->wID == idx) - { - hMenu->items.Delete(x--,true,HMENU__::freeMenuItem); - cnt++; - } - } - if (!cnt) - { - for (x=0;xitems.GetSize(); x ++) - { - if (hMenu->items.Get(x)->hSubMenu) cnt += DeleteMenu(hMenu->items.Get(x)->hSubMenu,idx,flag)?1:0; - } - } - return !!cnt; - } -} - - -BOOL SetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) -{ - if (!hMenu) return 0; - MENUITEMINFO *item = byPos ? hMenu->items.Get(pos) : GetMenuItemByID(hMenu, pos, true); - if (!item) return 0; - - if ((mi->fMask & MIIM_SUBMENU) && mi->hSubMenu != item->hSubMenu) - { - delete item->hSubMenu; - item->hSubMenu = mi->hSubMenu; - } - if (mi->fMask & MIIM_TYPE) - { - free(item->dwTypeData); // todo handle bitmap types - item->dwTypeData=0; - if (mi->fType == MFT_STRING && mi->dwTypeData) - { - item->dwTypeData = strdup( mi->dwTypeData ); - } - item->fType = mi->fType; - } - - if (mi->fMask & MIIM_STATE) item->fState = mi->fState; - if (mi->fMask & MIIM_ID) item->wID = mi->wID; - if (mi->fMask & MIIM_DATA) item->dwItemData = mi->dwItemData; - - return true; -} - -BOOL GetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) -{ - if (!hMenu) return 0; - MENUITEMINFO *item = byPos ? hMenu->items.Get(pos) : GetMenuItemByID(hMenu, pos, true); - if (!item) return 0; - - if (mi->fMask & MIIM_TYPE) - { - mi->fType = item->fType; - if (item->fType == MFT_STRING && mi->dwTypeData && mi->cch) - { - lstrcpyn(mi->dwTypeData,item->dwTypeData?item->dwTypeData:"",mi->cch); - } - } - - if (mi->fMask & MIIM_DATA) mi->dwItemData = item->dwItemData; - if (mi->fMask & MIIM_STATE) mi->fState = item->fState; - if (mi->fMask & MIIM_ID) mi->wID = item->wID; - if (mi->fMask & MIIM_SUBMENU) mi->hSubMenu = item->hSubMenu; - - return 1; - -} - -void SWELL_InsertMenu(HMENU menu, int pos, int flag, int idx, const char *str) -{ - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - (flag & ~MF_BYPOSITION),idx,NULL,NULL,NULL,0,(char *)str}; - InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); -} - -void SWELL_InsertMenu(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str) -{ - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - (flag & ~MF_BYPOSITION),(flag&MF_POPUP) ? 0 : (int)idx,NULL,NULL,NULL,0,(char *)str}; - - if (flag&MF_POPUP) - { - mi.hSubMenu = (HMENU)idx; - mi.fMask |= MIIM_SUBMENU; - mi.fState &= ~MF_POPUP; - } - - if (flag&MF_SEPARATOR) - { - mi.fMask=MIIM_TYPE; - mi.fType=MFT_SEPARATOR; - mi.fState &= ~MF_SEPARATOR; - } - - InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); -} - -void InsertMenuItem(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) -{ - if (!hMenu) return; - int ni=hMenu->items.GetSize(); - - if (!byPos) - { - int x; - for (x=0;xitems.Get(x)->wID != pos; x++); - pos = x; - } - if (pos < 0 || pos > ni) pos=ni; - - MENUITEMINFO *inf = (MENUITEMINFO*)calloc(sizeof(MENUITEMINFO),1); - inf->fType = mi->fType; - if (mi->fType == MFT_STRING) - { - inf->dwTypeData = strdup(mi->dwTypeData?mi->dwTypeData:""); - } - else if (mi->fType == MFT_BITMAP) - { // todo handle bitmap types - } - else if (mi->fType == MFT_SEPARATOR) - { - } - if (mi->fMask&MIIM_SUBMENU) inf->hSubMenu = mi->hSubMenu; - if (mi->fMask & MIIM_STATE) inf->fState = mi->fState; - if (mi->fMask & MIIM_DATA) inf->dwItemData = mi->dwItemData; - if (mi->fMask & MIIM_ID) inf->wID = mi->wID; - - hMenu->items.Insert(pos,inf); -} - - -void SWELL_SetMenuDestination(HMENU menu, HWND hwnd) -{ - // only needed for Cocoa -} - -static POINT m_trackingPt; -static int m_trackingFlags,m_trackingRet; -static HWND m_trackingPar; -static WDL_PtrList m_trackingMenus; // each HWND as userdata = HMENU - -static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - const int itemheight = 12, lcol=12, rcol=12, mcol=10; - switch (uMsg) - { - case WM_CREATE: - m_trackingMenus.Add(hwnd); - SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); - - if (m_trackingPar && !(m_trackingFlags&TPM_NONOTIFY)) - SendMessage(m_trackingPar,WM_INITMENUPOPUP,(WPARAM)lParam,0); - - { - HDC hdc = GetDC(hwnd); - HMENU__ *menu = (HMENU__*)lParam; - int ht = menu->items.GetSize()*itemheight, wid=100,wid2=0; - int xpos=m_trackingPt.x; - int ypos=m_trackingPt.y; - int x; - for (x=0; x < menu->items.GetSize(); x++) - { - MENUITEMINFO *inf = menu->items.Get(x); - if (inf->fType == MFT_STRING && inf->dwTypeData) - { - RECT r={0,}; - const char *pt2 = strstr(inf->dwTypeData,"\t"); - DrawText(hdc,inf->dwTypeData,pt2 ? pt2-inf->dwTypeData : -1,&r,DT_CALCRECT|DT_SINGLELINE); - if (r.right > wid) wid=r.right; - if (pt2) - { - r.right=r.left; - DrawText(hdc,pt2+1,-1,&r,DT_CALCRECT|DT_SINGLELINE); - if (r.right > wid2) wid2=r.right; - } - } - } - wid+=lcol+rcol + (wid2?wid2+mcol:0); - ReleaseDC(hwnd,hdc); - RECT tr={xpos,ypos,xpos+wid,ypos+ht},vp; - SWELL_GetViewPort(&vp,&tr,true); - if (tr.bottom > vp.bottom) { tr.top += vp.bottom-tr.bottom; tr.bottom=vp.bottom; } - if (tr.right > vp.right) { tr.left += vp.right-tr.right; tr.right=vp.right; } - if (tr.left < vp.left) { tr.right += vp.left-tr.left; tr.left=vp.left; } - if (tr.top < vp.top) { tr.bottom += vp.top-tr.top; tr.top=vp.top; } - SetWindowPos(hwnd,NULL,tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top,SWP_NOZORDER); - } - SetWindowLong(hwnd,GWL_STYLE,GetWindowLong(hwnd,GWL_STYLE)&~WS_CAPTION); - ShowWindow(hwnd,SW_SHOW); - SetFocus(hwnd); - SetTimer(hwnd,1,250,NULL); - break; - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT cr; - GetClientRect(hwnd,&cr); - HBRUSH br=CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - HPEN pen=CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); - HGDIOBJ oldbr = SelectObject(ps.hdc,br); - HGDIOBJ oldpen = SelectObject(ps.hdc,pen); - Rectangle(ps.hdc,cr.left,cr.top,cr.right-1,cr.bottom-1); - SetBkMode(ps.hdc,TRANSPARENT); - int cols[2]={ GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_3DHILIGHT)}; - HMENU__ *menu = (HMENU__*)GetWindowLongPtr(hwnd,GWLP_USERDATA); - int x; - for (x=0; x < menu->items.GetSize(); x++) - { - MENUITEMINFO *inf = menu->items.Get(x); - RECT r={lcol,x*itemheight,cr.right,(x+1)*itemheight}; - bool dis = !!(inf->fState & MF_GRAYED); - SetTextColor(ps.hdc,cols[dis]); - if (inf->fType == MFT_STRING && inf->dwTypeData) - { - const char *pt2 = strstr(inf->dwTypeData,"\t"); - DrawText(ps.hdc,inf->dwTypeData,pt2 ? pt2-inf->dwTypeData : -1,&r,DT_VCENTER|DT_SINGLELINE); - if (pt2) - { - RECT tr=r; tr.right-=rcol; - DrawText(ps.hdc,pt2+1,-1,&tr,DT_VCENTER|DT_SINGLELINE|DT_RIGHT); - } - } - else - { - MoveToEx(ps.hdc,r.left - lcol/2,(r.top+r.bottom)/2,NULL); - LineTo(ps.hdc,r.right - rcol*3/2,(r.top+r.bottom)/2); - } - if (inf->hSubMenu) - { - RECT r2=r; r2.left = r2.right - rcol; - DrawText(ps.hdc,">",-1,&r2,DT_VCENTER|DT_RIGHT|DT_SINGLELINE); - } - if (inf->fState&MF_CHECKED) - { - RECT r2=r; r2.left = 0; r2.right=lcol; - DrawText(ps.hdc,"X",-1,&r2,DT_VCENTER|DT_CENTER|DT_SINGLELINE); - } - } - SelectObject(ps.hdc,oldbr); - SelectObject(ps.hdc,oldpen); - DeleteObject(br); - DeleteObject(pen); - EndPaint(hwnd,&ps); - } - } - break; - case WM_TIMER: - if (wParam==1) - { - HWND GetFocusIncludeMenus(); - HWND h = GetFocusIncludeMenus(); - if (h!=hwnd) - { - int a = h ? m_trackingMenus.Find(h) : -1; - if (a<0 || a < m_trackingMenus.Find(hwnd)) DestroyWindow(hwnd); - } - } - break; - case WM_DESTROY: - { - int a = m_trackingMenus.Find(hwnd); - m_trackingMenus.Delete(a); - if (m_trackingMenus.Get(a)) DestroyWindow(m_trackingMenus.Get(a)); - RemoveProp(hwnd,"SWELL_MenuOwner"); - } - break; - case WM_LBUTTONUP: - case WM_RBUTTONUP: - { - RECT r; - GetClientRect(hwnd,&r); - if (GET_X_LPARAM(lParam)>=r.left && GET_X_LPARAM(lParam)items.Get(which); - if (inf) - { - if (inf->fState&MF_GRAYED){ } - else if (inf->hSubMenu) - { - int a = m_trackingMenus.Find(hwnd); - HWND next = m_trackingMenus.Get(a+1); - if (next) DestroyWindow(next); - - m_trackingPt.x=r.right; - m_trackingPt.y=r.top + which*itemheight; - ClientToScreen(hwnd,&m_trackingPt); - HWND hh; - submenuWndProc(hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL),WM_CREATE,0,(LPARAM)inf->hSubMenu); - SetProp(hh,"SWELL_MenuOwner",GetProp(hh,"SWELL_MenuOwner")); - } - else if (inf->wID) m_trackingRet = inf->wID; - } - else DestroyWindow(hwnd); - } - else DestroyWindow(hwnd); - } - break; - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - -int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r) -{ - if (!hMenu || m_trackingMenus.GetSize()) return 0; - - ReleaseCapture(); - m_trackingPar=hwnd; - m_trackingFlags=flags; - m_trackingRet=-1; - m_trackingPt.x=xpos; - m_trackingPt.y=ypos; - -// HWND oldFoc = GetFocus(); - // bool oldFoc_child = oldFoc && (IsChild(hwnd,oldFoc) || oldFoc == hwnd || oldFoc==GetParent(hwnd)); - - HWND hh; - submenuWndProc(hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL),WM_CREATE,0,(LPARAM)hMenu); - SetProp(hh,"SWELL_MenuOwner",(HANDLE)hwnd); - - while (m_trackingRet<0 && m_trackingMenus.GetSize()) - { - void SWELL_RunMessageLoop(); - SWELL_RunMessageLoop(); - Sleep(10); - } - - int x=m_trackingMenus.GetSize()-1; - while (x>=0) - { - HWND h = m_trackingMenus.Get(x); - m_trackingMenus.Delete(x); - if (h) DestroyWindow(h); - x--; - } - -// if (oldFoc_child) SetFocus(oldFoc); - - if (!(flags&TPM_NONOTIFY) && m_trackingRet>0) - SendMessage(hwnd,WM_COMMAND,m_trackingRet,0); - - return m_trackingRet>0?m_trackingRet:0; -} - - - - -void SWELL_Menu_AddMenuItem(HMENU hMenu, const char *name, int idx, int flags) -{ - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - (flags)?MFS_GRAYED:0,idx,NULL,NULL,NULL,0,(char *)name}; - if (!name) - { - mi.fType = MFT_SEPARATOR; - mi.fMask&=~(MIIM_STATE|MIIM_ID); - } - InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); -} - - -SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; // todo: move to per-module thingy - -static SWELL_MenuResourceIndex *resById(SWELL_MenuResourceIndex *head, const char *resid) -{ - SWELL_MenuResourceIndex *p=head; - while (p) - { - if (p->resid == resid) return p; - p=p->_next; - } - return 0; -} - -HMENU SWELL_LoadMenu(SWELL_MenuResourceIndex *head, const char *resid) -{ - SWELL_MenuResourceIndex *p; - - if (!(p=resById(head,resid))) return 0; - HMENU hMenu=CreatePopupMenu(); - if (hMenu) p->createFunc(hMenu); - return hMenu; -} - -HMENU SWELL_DuplicateMenu(HMENU menu) -{ - if (!menu) return 0; - return menu->Duplicate(); -} - -BOOL SetMenu(HWND hwnd, HMENU menu) -{ - if (!hwnd) return 0; - hwnd->m_menu = menu; - - return TRUE; -} - -HMENU GetMenu(HWND hwnd) -{ - if (!hwnd) return 0; - return hwnd->m_menu; -} - -void DrawMenuBar(HWND hwnd) -{ - InvalidateRect(hwnd,NULL,FALSE); -} - - -// copied from swell-menu.mm, can have a common impl someday -int SWELL_GenerateMenuFromList(HMENU hMenu, const void *_list, int listsz) -{ - SWELL_MenuGen_Entry *list = (SWELL_MenuGen_Entry *)_list; - const int l1=strlen(SWELL_MENUGEN_POPUP_PREFIX); - while (listsz>0) - { - int cnt=1; - if (!list->name) SWELL_Menu_AddMenuItem(hMenu,NULL,-1,0); - else if (!strcmp(list->name,SWELL_MENUGEN_ENDPOPUP)) return list + 1 - (SWELL_MenuGen_Entry *)_list; - else if (!strncmp(list->name,SWELL_MENUGEN_POPUP_PREFIX,l1)) - { - MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_STATE|MIIM_TYPE,MFT_STRING,0,0,CreatePopupMenuEx(list->name+l1),NULL,NULL,0,(char *)list->name+l1}; - cnt += SWELL_GenerateMenuFromList(mi.hSubMenu,list+1,listsz-1); - InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); - } - else SWELL_Menu_AddMenuItem(hMenu,list->name,list->idx,list->flags); - - list+=cnt; - listsz -= cnt; - } -} -#endif diff --git a/WDL/swell/swell-menu.mm b/WDL/swell/swell-menu.mm deleted file mode 100644 index 89e22bcd..00000000 --- a/WDL/swell/swell-menu.mm +++ /dev/null @@ -1,919 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic windows menu API to interface an NSMenu - - */ - -#ifndef SWELL_PROVIDED_BY_APP - -#import - -#include "swell.h" -#include "swell-menugen.h" - -#include "swell-internal.h" - - -static void __filtnametobuf(char *out, const char *in, int outsz) -{ - while (*in && outsz>1) - { - if (*in == '\t') break; - if (*in == '&') - { - in++; - } - *out++=*in++; - outsz--; - } - *out=0; -} - - - -bool SetMenuItemText(HMENU hMenu, int idx, int flag, const char *text) -{ - NSMenu *menu=(NSMenu *)hMenu; - - NSMenuItem *item; - if (flag & MF_BYPOSITION) item=[menu itemAtIndex:idx]; - else item =[menu itemWithTag:idx]; - if (!item) - { - if (!(flag & MF_BYPOSITION)) - { - int x; - int n=[menu numberOfItems]; - for (x = 0; x < n; x ++) - { - item=[menu itemAtIndex:x]; - if (item && [item hasSubmenu]) - { - NSMenu *m=[item submenu]; - if (m && SetMenuItemText((HMENU)m,idx,flag,text)) return true; - } - } - } - return false; - } - char buf[1024]; - __filtnametobuf(buf,text?text:"",sizeof(buf)); - NSString *label=(NSString *)SWELL_CStringToCFString(buf); - - [item setTitle:label]; - if ([item hasSubmenu] && [item submenu]) [[item submenu] setTitle:label]; - - [label release]; - return true; -} - -bool EnableMenuItem(HMENU hMenu, int idx, int en) -{ - NSMenu *menu=(NSMenu *)hMenu; - - NSMenuItem *item; - if (en & MF_BYPOSITION) item=[menu itemAtIndex:idx]; - else item =[menu itemWithTag:idx]; - if (!item) - { - if (!(en & MF_BYPOSITION)) - { - int x; - int n=[menu numberOfItems]; - for (x = 0; x < n; x ++) - { - item=[menu itemAtIndex:x]; - if (item && [item hasSubmenu]) - { - NSMenu *m=[item submenu]; - if (m && EnableMenuItem((HMENU)m,idx,en)) return true; - } - } - } - return false; - } - [item setEnabled:((en&MF_GRAYED)?NO:YES)]; - return true; -} - -bool CheckMenuItem(HMENU hMenu, int idx, int chk) -{ - NSMenu *menu=(NSMenu *)hMenu; - if (!menu) return false; - - NSMenuItem *item; - if (chk & MF_BYPOSITION) item=[menu itemAtIndex:idx]; - else item =[menu itemWithTag:idx]; - if (!item) - { - if (!(chk & MF_BYPOSITION)) - { - int x; - int n=[menu numberOfItems]; - for (x = 0; x < n; x ++) - { - item=[menu itemAtIndex:x]; - if (item && [item hasSubmenu]) - { - NSMenu *m=[item submenu]; - if (m && CheckMenuItem((HMENU)m,idx,chk)) return true; - } - } - } - return false; - } - [item setState:((chk&MF_CHECKED)?NSOnState:NSOffState)]; - - return true; -} -HMENU SWELL_GetCurrentMenu() -{ - return (HMENU)[NSApp mainMenu]; -} - -extern int g_swell_terminating; - -void SWELL_SetCurrentMenu(HMENU hmenu) -{ - if (hmenu && [(id)hmenu isKindOfClass:[NSMenu class]]) - { - if (!g_swell_terminating) [NSApp setMainMenu:(NSMenu *)hmenu]; - } -} - -HMENU GetSubMenu(HMENU hMenu, int pos) -{ - NSMenu *menu=(NSMenu *)hMenu; - - NSMenuItem *item=menu && pos >=0 && pos < [menu numberOfItems] ? [menu itemAtIndex:pos] : 0; - if (item && [item hasSubmenu]) return (HMENU)[item submenu]; - return 0; -} - -int GetMenuItemCount(HMENU hMenu) -{ - NSMenu *menu=(NSMenu *)hMenu; - return [menu numberOfItems]; -} - -int GetMenuItemID(HMENU hMenu, int pos) -{ - NSMenu *menu=(NSMenu *)hMenu; - if (pos < 0 || pos >= [menu numberOfItems]) return 0; - - NSMenuItem *item=[menu itemAtIndex:pos]; - if (item) - { - if ([item hasSubmenu]) return -1; - return [item tag]; - } - return 0; -} - -bool SetMenuItemModifier(HMENU hMenu, int idx, int flag, int code, unsigned int mask) -{ - -#if 0 // enable this once we make SWELL_KeyToASCII decent - int n2=0; - int n1 = SWELL_KeyToASCII(code,flag,&n2); - if (n1) - { - code=n1; - flag=n2; - } -#endif - - NSMenu *menu=(NSMenu *)hMenu; - - NSMenuItem *item; - if (flag & MF_BYPOSITION) item=[menu itemAtIndex:idx]; - else item =[menu itemWithTag:idx]; - if (!item) - { - if (!(flag & MF_BYPOSITION)) - { - int x; - int n=[menu numberOfItems]; - for (x = 0; x < n; x ++) - { - item=[menu itemAtIndex:x]; - if (item && [item hasSubmenu]) - { - NSMenu *m=[item submenu]; - if (m && SetMenuItemModifier((HMENU)m,idx,flag,code,mask)) return true; - } - } - } - return false; - } - - bool suppressShift = false; - unichar arrowKey = 0; - int codelow = code&127; - if ((code>='A' && code <='Z') || - (code>='0' && code <= '9') || - ( !(mask&FVIRTKEY) && - ( - codelow == '\'' || - codelow == '/' || - codelow == '\\' || - codelow == '|' || - codelow == '"' || - codelow == ',' || - codelow == '.' || - codelow == '!' || - codelow == '?' || - codelow == '[' || - codelow == ']' - ))) - { - arrowKey=codelow; - if (!(mask & FSHIFT) && arrowKey < 256) arrowKey=tolower(arrowKey); - - if (code>='A' && code<='Z') suppressShift=true; - } - else if (code >= VK_F1 && code <= VK_F12) - { - arrowKey = NSF1FunctionKey + code - VK_F1; - } - else switch (code&0xff) - { - #define DEFKP(wink,mack) case wink: arrowKey = mack; break; - DEFKP(VK_UP,NSUpArrowFunctionKey) - DEFKP(VK_DOWN,NSDownArrowFunctionKey) - DEFKP(VK_LEFT,NSLeftArrowFunctionKey) - DEFKP(VK_RIGHT,NSRightArrowFunctionKey) - DEFKP(VK_INSERT,NSInsertFunctionKey) - DEFKP(VK_DELETE,NSDeleteCharacter) - DEFKP(VK_BACK,NSBackspaceCharacter) - DEFKP(VK_HOME,NSHomeFunctionKey) - DEFKP(VK_END,NSEndFunctionKey) - DEFKP(VK_NEXT,NSPageDownFunctionKey) - DEFKP(VK_PRIOR,NSPageUpFunctionKey) - DEFKP(VK_SUBTRACT,'-') - } - - unsigned int mask2=0; - if (mask&FALT) mask2|=NSAlternateKeyMask; - if (!suppressShift) if (mask&FSHIFT) mask2|=NSShiftKeyMask; - if (mask&FCONTROL) mask2|=NSCommandKeyMask; - if (mask&FLWIN) mask2|=NSControlKeyMask; - - [item setKeyEquivalentModifierMask:mask2]; - [item setKeyEquivalent:arrowKey?[NSString stringWithCharacters:&arrowKey length:1]:@""]; - return true; -} - -// #define SWELL_MENU_ACCOUNTING - -#ifdef SWELL_MENU_ACCOUNTING -struct menuTmp -{ - NSMenu *menu; - NSString *lbl; -}; - -WDL_PtrList allMenus; -#endif - -@implementation SWELL_Menu -- (id)copyWithZone:(NSZone *)zone -{ - id rv = [super copyWithZone:zone]; -#ifdef SWELL_MENU_ACCOUNTING - if (rv) - { - menuTmp *mt = new menuTmp; - mt->menu=(NSMenu *)rv; - NSString *lbl = [(SWELL_Menu *)rv title]; - mt->lbl = lbl; - [lbl retain]; - allMenus.Add(mt); - NSLog(@"copy menu, new count=%d lbl=%@\n",allMenus.GetSize(),lbl); - } -#endif - return rv; -} --(void)dealloc -{ -#ifdef SWELL_MENU_ACCOUNTING - int x; - bool f=false; - for(x=0;xmenu == self) - { - NSLog(@"dealloc menu, found self %@\n",allMenus.Get(x)->lbl); - allMenus.Delete(x); - f=true; - break; - } - } - - NSLog(@"dealloc menu, new count=%d %@\n",allMenus.GetSize(), [self title]); - if (!f) - { - NSLog(@"deleting unfound menu!!\n"); - } -#endif - [super dealloc]; -} -@end - -HMENU CreatePopupMenu() -{ - return CreatePopupMenuEx(NULL); -} -HMENU CreatePopupMenuEx(const char *title) -{ - SWELL_Menu *m; - if (title) - { - char buf[1024]; - __filtnametobuf(buf,title,sizeof(buf)); - NSString *lbl=(NSString *)SWELL_CStringToCFString(buf); - m=[[SWELL_Menu alloc] initWithTitle:lbl]; -#ifdef SWELL_MENU_ACCOUNTING - menuTmp *mt = new menuTmp; - mt->menu=m; - mt->lbl = lbl; - [lbl retain]; - allMenus.Add(mt); - NSLog(@"alloc menu, new count=%d lbl=%@\n",allMenus.GetSize(),lbl); -#endif - [lbl release]; - } - else - { - m=[[SWELL_Menu alloc] init]; -#ifdef SWELL_MENU_ACCOUNTING - menuTmp *mt = new menuTmp; - mt->menu=m; - mt->lbl = @""; - allMenus.Add(mt); - NSLog(@"alloc menu, new count=%d lbl=%@\n",allMenus.GetSize(),@""); -#endif - } - [m setAutoenablesItems:NO]; - - return (HMENU)m; -} - -void DestroyMenu(HMENU hMenu) -{ - if (hMenu) - { - SWELL_SetMenuDestination(hMenu,NULL); - NSMenu *m=(NSMenu *)hMenu; - [m release]; - } -} - - - -int AddMenuItem(HMENU hMenu, int pos, const char *name, int tagid) -{ - if (!hMenu) return -1; - NSMenu *m=(NSMenu *)hMenu; - NSString *label=(NSString *)SWELL_CStringToCFString(name); - NSMenuItem *item=[m insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; - [label release]; - [item setTag:tagid]; - [item setEnabled:YES]; - return 0; -} - -bool DeleteMenu(HMENU hMenu, int idx, int flag) -{ - if (!hMenu) return false; - NSMenu *m=(NSMenu *)hMenu; - NSMenuItem *item=NULL; - - if (flag&MF_BYPOSITION) - { - if (idx >=0 && idx < [m numberOfItems]) - item=[m itemAtIndex:idx]; - if (!item) return false; - } - else - { - item=[m itemWithTag:idx]; - if (!item) - { - int x,n=[m numberOfItems]; - for (x=0;xfMask & MIIM_SUBMENU) && mi->hSubMenu) // do this before MIIM_TYPE so we title the submenu properly - { - [m setSubmenu:(NSMenu*)mi->hSubMenu forItem:item]; - [((NSMenu*)mi->hSubMenu) release]; // let the parent menu free it - } - if (mi->fMask & MIIM_TYPE) - { - if (mi->fType == MFT_STRING && mi->dwTypeData) - { - char buf[1024]; - __filtnametobuf(buf,mi->dwTypeData?mi->dwTypeData:"(null)",sizeof(buf)); - NSString *label=(NSString *)SWELL_CStringToCFString(buf); - - [item setTitle:label]; - if ([item hasSubmenu] && [item submenu]) [[item submenu] setTitle:label]; - - [label release]; - } - } - if (mi->fMask & MIIM_STATE) - { - [item setState:((mi->fState&MFS_CHECKED)?NSOnState:NSOffState)]; - [item setEnabled:((mi->fState&MFS_GRAYED)?NO:YES)]; - } - if (mi->fMask & MIIM_ID) - { - [item setTag:mi->wID]; - } - if (mi->fMask & MIIM_DATA) - { - SWELL_DataHold* newh = [[SWELL_DataHold alloc] initWithVal:(void*)mi->dwItemData]; - [item setRepresentedObject:newh]; - [newh release]; - } - - return true; -} - -BOOL GetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) -{ - if (!hMenu) return 0; - NSMenu *m=(NSMenu *)hMenu; - NSMenuItem *item; - if (byPos) - { - item=[m itemAtIndex:pos]; - } - else item=[m itemWithTag:pos]; - - if (!item) - { - if (!byPos) - { - int x; - int n=[m numberOfItems]; - for (x = 0; x < n; x ++) - { - item=[m itemAtIndex:x]; - if (item && [item hasSubmenu]) - { - NSMenu *m1=[item submenu]; - if (m1 && GetMenuItemInfo((HMENU)m1,pos,byPos,mi)) return true; - } - } - } - return 0; - } - - if (mi->fMask & MIIM_TYPE) - { - if ([item isSeparatorItem]) mi->fType = MFT_SEPARATOR; - else - { - mi->fType = MFT_STRING; - if (mi->dwTypeData && mi->cch) - { - mi->dwTypeData[0]=0; - SWELL_CFStringToCString([item title], (char *)mi->dwTypeData, mi->cch); - } - } - } - - if (mi->fMask & MIIM_DATA) - { - SWELL_DataHold *h=[item representedObject]; - mi->dwItemData = (INT_PTR)(h && [h isKindOfClass:[SWELL_DataHold class]]? [h getValue] : 0); - } - - if (mi->fMask & MIIM_STATE) - { - mi->fState=0; - if ([item state]) mi->fState|=MFS_CHECKED; - if (![item isEnabled]) mi->fState|=MFS_GRAYED; - } - - if (mi->fMask & MIIM_ID) - { - mi->wID = [item tag]; - } - - if(mi->fMask & MIIM_SUBMENU) - { - if ([item hasSubmenu]) - { - mi->hSubMenu = (HMENU)[item submenu]; - } - } - - return 1; - -} - -void SWELL_InsertMenu(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str) -{ - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - (flag & ~MF_BYPOSITION),(flag&MF_POPUP) ? 0 : (int)idx,NULL,NULL,NULL,0,(char *)str}; - - if (flag&MF_POPUP) - { - mi.hSubMenu = (HMENU)idx; - mi.fMask |= MIIM_SUBMENU; - mi.fState &= ~MF_POPUP; - } - - if (flag&MF_SEPARATOR) - { - mi.fMask=MIIM_TYPE; - mi.fType=MFT_SEPARATOR; - mi.fState &= ~MF_SEPARATOR; - } - - if (flag&MF_BITMAP) - { - mi.fType=MFT_BITMAP; - mi.fState &= ~MF_BITMAP; - } - - InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); -} - - -void InsertMenuItem(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) -{ - if (!hMenu) return; - NSMenu *m=(NSMenu *)hMenu; - NSMenuItem *item; - int ni=[m numberOfItems]; - - if (!byPos) - { - pos = [m indexOfItemWithTag:pos]; - } - if (pos < 0 || pos > ni) pos=ni; - - NSString *label=0; - if (mi->fType == MFT_STRING) - { - char buf[1024]; - __filtnametobuf(buf,mi->dwTypeData?mi->dwTypeData:"(null)",sizeof(buf)); - label=(NSString *)SWELL_CStringToCFString(buf); - item=[m insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; - } - else if (mi->fType == MFT_BITMAP) - { - item=[m insertItemWithTitle:@"(no image)" action:NULL keyEquivalent:@"" atIndex:pos]; - if (mi->dwTypeData) - { - NSImage *i=(NSImage *)GetNSImageFromHICON((HICON)mi->dwTypeData); - if (i) - { - [item setImage:i]; - [item setTitle:@""]; - } - } - } - else - { - item = [NSMenuItem separatorItem]; - [m insertItem:item atIndex:pos]; - } - - if ((mi->fMask & MIIM_SUBMENU) && mi->hSubMenu) - { - if (label) [(NSMenu *)mi->hSubMenu setTitle:label]; - [m setSubmenu:(NSMenu *)mi->hSubMenu forItem:item]; - [((NSMenu *)mi->hSubMenu) release]; // let the parent menu free it - } - if (label) [label release]; - - if (!ni) [m setAutoenablesItems:NO]; - [item setEnabled:YES]; - - if (mi->fMask & MIIM_STATE) - { - if (mi->fState&MFS_GRAYED) - { - [item setEnabled:NO]; - } - if (mi->fState&MFS_CHECKED) - { - [item setState:NSOnState]; - } - } - - if (mi->fMask & MIIM_DATA) - { - SWELL_DataHold *h=[[SWELL_DataHold alloc] initWithVal:(void*)mi->dwItemData]; - [item setRepresentedObject:h]; - [h release]; - } - else - { - [item setRepresentedObject:nil]; - } - - if (mi->fMask & MIIM_ID) - { - [item setTag:mi->wID]; - } - - NSMenuItem *fi=[m itemAtIndex:0]; - if (fi && fi != item) - { - if ([fi action]) [item setAction:[fi action]]; - if ([fi target]) [item setTarget:[fi target]]; - } -} - - - -@implementation SWELL_PopupMenuRecv --(id) initWithWnd:(HWND)wnd -{ - if ((self = [super init])) - { - cbwnd=wnd; - m_act=0; - } - return self; -} - --(void) onSwellCommand:(id)sender -{ - int tag=[sender tag]; - if (tag) - m_act=tag; -} - --(int) isCommand -{ - return m_act; -} - -- (void)menuNeedsUpdate:(NSMenu *)menu -{ - if (cbwnd) - { - SendMessage(cbwnd,WM_INITMENUPOPUP,(WPARAM)menu,0); - SWELL_SetMenuDestination((HMENU)menu,(HWND)self); - } -} - -@end - -void SWELL_SetMenuDestination(HMENU menu, HWND hwnd) -{ - if (!menu || (hwnd && ![(id)hwnd respondsToSelector:@selector(onSwellCommand:)])) return; - - NSMenu *m=(NSMenu *)menu; - [m setDelegate:(id)hwnd]; - int x,n=[m numberOfItems]; - for (x = 0; x < n; x++) - { - NSMenuItem *item=[m itemAtIndex:x]; - if (item) - { - if ([item hasSubmenu]) - { - NSMenu *mm=[item submenu]; - if (mm) SWELL_SetMenuDestination((HMENU)mm,hwnd); - } - else - { - if ([item tag]) - { - [item setTarget:(id)hwnd]; - if (hwnd) [item setAction:@selector(onSwellCommand:)]; - } - } - } - } -} - -int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r) -{ - if (hMenu) - { - NSMenu *m=(NSMenu *)hMenu; - NSView *v=(NSView *)hwnd; - if (v && [v isKindOfClass:[NSWindow class]]) v=[(NSWindow *)v contentView]; - if (!v) v=[[NSApp mainWindow] contentView]; - if (!v) return 0; - - NSEvent *event = [NSApp currentEvent]; - - { - //create a new event at these coordinates, faking it - NSWindow *w = [v window]; - NSPoint pt = NSMakePoint(xpos, ypos); - pt=[w convertScreenToBase:pt]; - pt.y -= 4; - int wn = [w windowNumber]; // event ? [event windowNumber] : [w windowNumber]; - NSTimeInterval ts = event ? [event timestamp] : 0; - NSGraphicsContext *gctx = event ? [event context] : 0; - event = [NSEvent otherEventWithType:NSApplicationDefined location:pt modifierFlags:0 timestamp:ts windowNumber:wn context:gctx subtype:0 data1:0 data2:0]; - } - - SWELL_PopupMenuRecv *recv = [[SWELL_PopupMenuRecv alloc] initWithWnd:((flags & TPM_NONOTIFY) ? 0 : hwnd)]; - - SWELL_SetMenuDestination((HMENU)m,(HWND)recv); - - if (!(flags&TPM_NONOTIFY)&&hwnd) - { - SendMessage(hwnd,WM_INITMENUPOPUP,(WPARAM)m,0); - SWELL_SetMenuDestination((HMENU)m,(HWND)recv); - } - - [NSMenu popUpContextMenu:m withEvent:event forView:v]; - - int ret=[recv isCommand]; - SWELL_SetMenuDestination((HMENU)m,(HWND)NULL); - [recv release]; - - if (ret<=0) return 0; - - if (flags & TPM_RETURNCMD) return ret; - - if (hwnd) SendMessage(hwnd,WM_COMMAND,ret,0); - - return 1; - } - return 0; -} - - - - -void SWELL_Menu_AddMenuItem(HMENU hMenu, const char *name, int idx, int flags) -{ - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - (flags)?MFS_GRAYED:0,idx,NULL,NULL,NULL,0,(char *)name}; - if (!name) - { - mi.fType = MFT_SEPARATOR; - mi.fMask&=~(MIIM_STATE|MIIM_ID); - } - InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); -} - -int SWELL_GenerateMenuFromList(HMENU hMenu, const void *_list, int listsz) -{ - SWELL_MenuGen_Entry *list = (SWELL_MenuGen_Entry *)_list; - const int l1=strlen(SWELL_MENUGEN_POPUP_PREFIX); - while (listsz>0) - { - int cnt=1; - if (!list->name) SWELL_Menu_AddMenuItem(hMenu,NULL,-1,0); - else if (!strcmp(list->name,SWELL_MENUGEN_ENDPOPUP)) break; - else if (!strncmp(list->name,SWELL_MENUGEN_POPUP_PREFIX,l1)) - { - MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_STATE|MIIM_TYPE,MFT_STRING,0,0,CreatePopupMenuEx(list->name+l1),NULL,NULL,0,(char *)list->name+l1}; - cnt += SWELL_GenerateMenuFromList(mi.hSubMenu,list+1,listsz-1); - InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); - } - else SWELL_Menu_AddMenuItem(hMenu,list->name,list->idx,list->flags); - - list+=cnt; - listsz -= cnt; - } - return list + 1 - (SWELL_MenuGen_Entry *)_list; -} - - -SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; // todo: move to per-module thingy - -static SWELL_MenuResourceIndex *resById(SWELL_MenuResourceIndex *head, const char *resid) -{ - SWELL_MenuResourceIndex *p=head; - while (p) - { - if (p->resid == resid) return p; - p=p->_next; - } - return 0; -} - -HMENU SWELL_LoadMenu(SWELL_MenuResourceIndex *head, const char *resid) -{ - SWELL_MenuResourceIndex *p; - - if (!(p=resById(head,resid))) return 0; - HMENU hMenu=CreatePopupMenu(); - if (hMenu) p->createFunc(hMenu); - return hMenu; -} - -HMENU SWELL_DuplicateMenu(HMENU menu) -{ - if (!menu) return 0; - NSMenu *ret = (NSMenu *)[(NSMenu *)menu copy]; - return (HMENU)ret; -} - -BOOL SetMenu(HWND hwnd, HMENU menu) -{ - if (!hwnd||![(id)hwnd respondsToSelector:@selector(swellSetMenu:)]) return FALSE; - if (g_swell_terminating) return FALSE; - - [(id)hwnd swellSetMenu:(HMENU)menu]; - NSWindow *nswnd = (NSWindow *)hwnd; - if ([nswnd isKindOfClass:[NSWindow class]] || - ([nswnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)nswnd window]) && hwnd == (HWND)[nswnd contentView])) - { - if ([NSApp keyWindow]==nswnd && - [NSApp mainMenu] != (NSMenu *)menu) - { - [NSApp setMainMenu:(NSMenu *)menu]; - if (menu) SendMessage(hwnd,WM_INITMENUPOPUP,(WPARAM)menu,0); // find a better place for this! TODO !!! - } - } - - return TRUE; -} - -HMENU GetMenu(HWND hwnd) -{ - if (!hwnd) return NULL; - if ([(id)hwnd isKindOfClass:[NSWindow class]]) hwnd = (HWND)[(NSWindow *)hwnd contentView]; - if ([(id)hwnd respondsToSelector:@selector(swellGetMenu)]) return (HMENU) [(id)hwnd swellGetMenu]; - return NULL; -} - -void DrawMenuBar(HWND hwnd) -{ -} - - -#endif diff --git a/WDL/swell/swell-menugen.h b/WDL/swell/swell-menugen.h deleted file mode 100644 index 5bf1baf3..00000000 --- a/WDL/swell/swell-menugen.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _SWELL_MENUGEN_H_ -#define _SWELL_MENUGEN_H_ - - -/** - SWELL - (Simple Windows Emulation Layer Library) - Copyright (C) 2006 and later, Cockos Incorporated. - Dynamic menu generation - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Usage: - - See: mac_resgen.php etc - - */ - - -#include "swell.h" - - -#ifdef BEGIN -#undef BEGIN -#endif - -#ifdef END -#undef END -#endif - - -typedef struct SWELL_MenuResourceIndex -{ - const char *resid; - void (*createFunc)(HMENU hMenu); - struct SWELL_MenuResourceIndex *_next; -} SWELL_MenuResourceIndex; -extern SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; - - -#define SWELL_MENUGEN_POPUP_PREFIX "/.BO^O:" -#define SWELL_MENUGEN_ENDPOPUP "EN%%%^:" -struct SWELL_MenuGen_Entry -{ - const char *name; // will begin with SWELL_MENUGEN_POPUP_PREFIX on submenus, and will be SWELL_MENUGEN_ENDPOPUP at the end of a submenu - unsigned short idx; - unsigned short flags; -}; - -class SWELL_MenuGenHelper -{ - public: - SWELL_MenuResourceIndex m_rec; - SWELL_MenuGenHelper(SWELL_MenuResourceIndex **h, void (*cf)(HMENU), int recid) - { - m_rec.resid=MAKEINTRESOURCE(recid); - m_rec.createFunc=cf; - m_rec._next=*h; - *h = &m_rec; - } -}; - -#define SWELL_DEFINE_MENU_RESOURCE_BEGIN(recid) \ - static void __swell_menu_cf__##recid(HMENU hMenu); \ - static SWELL_MenuGenHelper __swell_menu_cf_helper__##recid(&SWELL_curmodule_menuresource_head, __swell_menu_cf__##recid, recid); \ - static void __swell_menu_cf__##recid(HMENU hMenu) { static const SWELL_MenuGen_Entry list[]={{NULL,0,0 - -#define SWELL_DEFINE_MENU_RESOURCE_END(recid) } }; SWELL_GenerateMenuFromList(hMenu,list+1,sizeof(list)/sizeof(list[0])-1); } - - -#define GRAYED 1 -#define INACTIVE 2 -#define POPUP }, { SWELL_MENUGEN_POPUP_PREFIX -#define MENUITEM }, { -#define SEPARATOR NULL, -1 -#define BEGIN -#define END }, { SWELL_MENUGEN_ENDPOPUP - -#endif//_SWELL_MENUGEN_H_ - diff --git a/WDL/swell/swell-misc-generic.cpp b/WDL/swell/swell-misc-generic.cpp deleted file mode 100644 index fb5fff1a..00000000 --- a/WDL/swell/swell-misc-generic.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-internal.h" - -HANDLE SWELL_CreateProcess(const char *exe, int nparams, const char **params) -{ - return 0; // todo -} -bool IsRightClickEmulateEnabled() -{ - return false; -} - -void SWELL_EnableRightClickEmulate(BOOL enable) -{ -} - - -#endif diff --git a/WDL/swell/swell-misc.mm b/WDL/swell/swell-misc.mm deleted file mode 100644 index 9c9aa4ba..00000000 --- a/WDL/swell/swell-misc.mm +++ /dev/null @@ -1,566 +0,0 @@ -#ifndef SWELL_PROVIDED_BY_APP - -//#import -#import -#include "swell.h" -#include "swell-internal.h" - -#include "../mutex.h" - -HWND g_swell_only_timerhwnd; - -@implementation SWELL_TimerFuncTarget - --(id) initWithId:(UINT_PTR)tid hwnd:(HWND)h callback:(TIMERPROC)cb -{ - if ((self = [super init])) - { - m_hwnd=h; - m_cb=cb; - m_timerid = tid; - } - return self; -} --(void)SWELL_Timer:(id)sender -{ - if (g_swell_only_timerhwnd && m_hwnd != g_swell_only_timerhwnd) return; - - m_cb(m_hwnd,WM_TIMER,m_timerid,GetTickCount()); -} -@end - -@implementation SWELL_DataHold --(id) initWithVal:(void *)val -{ - if ((self = [super init])) - { - m_data=val; - } - return self; -} --(void *) getValue -{ - return m_data; -} -@end - -void SWELL_CFStringToCString(const void *str, char *buf, int buflen) -{ - NSString *s = (NSString *)str; - if (buflen>0) *buf=0; - if (buflen <= 1 || !s || [s getCString:buf maxLength:buflen encoding:NSUTF8StringEncoding]) return; // should always work, I'd hope (ambiguous documentation ugh) - - NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; - if (!data) - { - [s getCString:buf maxLength:buflen-1]; - return; - } - int len = [data length]; - if (len > buflen-1) len=buflen-1; - [data getBytes:buf length:len]; - buf[len]=0; -} - -void *SWELL_CStringToCFString(const char *str) -{ - if (!str) str=""; - void *ret; - - ret=(void *)CFStringCreateWithCString(NULL,str,kCFStringEncodingUTF8); - if (ret) return ret; - ret=(void*)CFStringCreateWithCString(NULL,str,kCFStringEncodingASCII); - return ret; -} - -void SWELL_MakeProcessFront(HANDLE h) -{ - SWELL_InternalObjectHeader_NSTask *buf = (SWELL_InternalObjectHeader_NSTask*)h; - if (buf && buf->hdr.type == INTERNAL_OBJECT_NSTASK && buf->task) - { - ProcessSerialNumber psn; - - int pid=[(id)buf->task processIdentifier]; - // try for 1sec to get the PSN, if it fails - int n = 20; - while (GetProcessForPID(pid,&psn) != noErr && n-- > 0) - { - Sleep(50); - } - if (n>0) SetFrontProcess(&psn); - } -} - -void SWELL_ReleaseNSTask(void *p) -{ - NSTask *a =(NSTask*)p; - [a release]; -} -DWORD SWELL_WaitForNSTask(void *p, DWORD msTO) -{ - NSTask *a =(NSTask*)p; - DWORD t = msTO ? GetTickCount()+msTO : 0; - do - { - if (![a isRunning]) return WAIT_OBJECT_0; - if (t) Sleep(1); - } - while (GetTickCount()hdr.type = INTERNAL_OBJECT_NSTASK; - buf->hdr.count=1; - buf->task = tsk; - return buf; -} - - -@implementation SWELL_ThreadTmp --(void)bla:(id)obj -{ - if (a) - { - DWORD (*func)(void *); - *(void **)(&func) = a; - func(b); - } - [NSThread exit]; -} -@end - -void SWELL_EnsureMultithreadedCocoa() -{ - static int a; - if (!a) - { - a++; - if (![NSThread isMultiThreaded]) // force cocoa into multithreaded mode - { - SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init]; - t->a=0; - t->b=0; - [NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t]; - /// [t release]; - } - } -} - -void CreateThreadNS(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut) -{ - SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init]; - t->a=(void*)ThreadProc; - t->b=parm; - return [NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t]; -} - - -// used by swell.cpp (lazy these should go elsewhere) -void *SWELL_InitAutoRelease() -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - return (void *)pool; -} -void SWELL_QuitAutoRelease(void *p) -{ - if (p) - [(NSAutoreleasePool*)p release]; -} - -// timer stuff -typedef struct TimerInfoRec -{ - UINT_PTR timerid; - HWND hwnd; - NSTimer *timer; - struct TimerInfoRec *_next; -} TimerInfoRec; -static TimerInfoRec *m_timer_list; -static WDL_Mutex m_timermutex; -static pthread_t m_pmq_mainthread; -static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc); - -UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) -{ - if (!hwnd && !tProc) return 0; // must have either callback or hwnd - - if (hwnd && !timerid) return 0; - - if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) - { - SWELL_pmq_settimer(hwnd,timerid,(rate==(UINT)-1)?((UINT)-2):rate,tProc); - return timerid; - } - - - if (hwnd && ![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) - { - if (![(id)hwnd isKindOfClass:[NSWindow class]]) return 0; - hwnd=(HWND)[(id)hwnd contentView]; - if (![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) return 0; - } - - WDL_MutexLock lock(&m_timermutex); - TimerInfoRec *rec=NULL; - if (hwnd||timerid) - { - rec = m_timer_list; - while (rec) - { - if (rec->timerid == timerid && rec->hwnd == hwnd) // works for both kinds - break; - rec=rec->_next; - } - } - - bool recAdd=false; - if (!rec) - { - rec=(TimerInfoRec*)malloc(sizeof(TimerInfoRec)); - recAdd=true; - } - else - { - [rec->timer invalidate]; - rec->timer=0; - } - - rec->timerid=timerid; - rec->hwnd=hwnd; - - if (!hwnd || tProc) - { - // set timer to this unique ptr - if (!hwnd) timerid = rec->timerid = (UINT_PTR)rec; - - SWELL_TimerFuncTarget *t = [[SWELL_TimerFuncTarget alloc] initWithId:timerid hwnd:hwnd callback:tProc]; - rec->timer = [NSTimer scheduledTimerWithTimeInterval:(max(rate,1)*0.001) target:t selector:@selector(SWELL_Timer:) - userInfo:t repeats:YES]; - [t release]; - - } - else - { - SWELL_DataHold *t=[[SWELL_DataHold alloc] initWithVal:(void *)timerid]; - rec->timer = [NSTimer scheduledTimerWithTimeInterval:(max(rate,1)*0.001) target:(id)hwnd selector:@selector(SWELL_Timer:) - userInfo:t repeats:YES]; - - [t release]; - } - [[NSRunLoop currentRunLoop] addTimer:rec->timer forMode:(NSString*)kCFRunLoopCommonModes]; - - if (recAdd) - { - rec->_next=m_timer_list; - m_timer_list=rec; - } - - return timerid; -} -void SWELL_RunRunLoop(int ms) -{ - [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]]; -} -void SWELL_RunRunLoopEx(int ms, HWND hwndOnlyTimer) -{ - HWND h=g_swell_only_timerhwnd; - g_swell_only_timerhwnd = hwndOnlyTimer; - [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]]; - if (g_swell_only_timerhwnd == hwndOnlyTimer) g_swell_only_timerhwnd = h; -} - -BOOL KillTimer(HWND hwnd, UINT_PTR timerid) -{ - if (!hwnd && !timerid) return FALSE; - - WDL_MutexLock lock(&m_timermutex); - if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) - { - SWELL_pmq_settimer(hwnd,timerid,~(UINT)0,NULL); - return TRUE; - } - BOOL rv=FALSE; - - // don't allow removing all global timers - if (timerid!=~(UINT_PTR)0 || hwnd) - { - TimerInfoRec *rec = m_timer_list, *lrec=NULL; - while (rec) - { - - if (rec->hwnd == hwnd && (timerid==~(UINT_PTR)0 || rec->timerid == timerid)) - { - TimerInfoRec *nrec = rec->_next; - - // remove self from list - if (lrec) lrec->_next = nrec; - else m_timer_list = nrec; - - [rec->timer invalidate]; - free(rec); - - rv=TRUE; - if (timerid!=~(UINT_PTR)0) break; - - rec=nrec; - } - else - { - lrec=rec; - rec=rec->_next; - } - } - } - return rv; -} - - - -///////// PostMessage emulation - -BOOL PostMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - id del=[NSApp delegate]; - if (del && [del respondsToSelector:@selector(swellPostMessage:msg:wp:lp:)]) - return !![(SWELL_DelegateExtensions*)del swellPostMessage:hwnd msg:message wp:wParam lp:lParam]; - return FALSE; -} - -void SWELL_MessageQueue_Clear(HWND h) -{ - id del=[NSApp delegate]; - if (del && [del respondsToSelector:@selector(swellPostMessageClearQ:)]) - [(SWELL_DelegateExtensions*)del swellPostMessageClearQ:h]; -} - - - -// implementation of postmessage stuff - - - -typedef struct PMQ_rec -{ - HWND hwnd; - UINT msg; - WPARAM wParam; - LPARAM lParam; - - struct PMQ_rec *next; - bool is_special_timer; // if set, then msg=interval(-1 for kill),wParam=timer id, lParam = timerproc -} PMQ_rec; - -static WDL_Mutex *m_pmq_mutex; -static PMQ_rec *m_pmq, *m_pmq_empty, *m_pmq_tail; -static int m_pmq_size; -static id m_pmq_timer; -#define MAX_POSTMESSAGE_SIZE 1024 - -void SWELL_Internal_PostMessage_Init() -{ - if (m_pmq_mutex) return; - id del = [NSApp delegate]; - if (!del || ![del respondsToSelector:@selector(swellPostMessageTick:)]) return; - - m_pmq_mainthread=pthread_self(); - m_pmq_mutex = new WDL_Mutex; - - m_pmq_timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:(id)del selector:@selector(swellPostMessageTick:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:m_pmq_timer forMode:(NSString*)kCFRunLoopCommonModes]; - // [ release]; - // set a timer to the delegate -} - - -void SWELL_MessageQueue_Flush() -{ - if (!m_pmq_mutex) return; - - m_pmq_mutex->Enter(); - PMQ_rec *p=m_pmq, *startofchain=m_pmq; - m_pmq=m_pmq_tail=0; - m_pmq_mutex->Leave(); - - int cnt=0; - // process out queue - while (p) - { - if (p->is_special_timer) - { - if (p->msg == ~(UINT)0) KillTimer(p->hwnd,p->wParam); - else SetTimer(p->hwnd,p->wParam,p->msg,(TIMERPROC)p->lParam); - } - else - SendMessage(p->hwnd,p->msg,p->wParam,p->lParam); - - cnt ++; - if (!p->next) // add the chain back to empties - { - m_pmq_mutex->Enter(); - m_pmq_size-=cnt; - p->next=m_pmq_empty; - m_pmq_empty=startofchain; - m_pmq_mutex->Leave(); - break; - } - p=p->next; - } -} - -void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd) -{ - if (!m_pmq_mutex) return; - - m_pmq_mutex->Enter(); - PMQ_rec *p=m_pmq; - PMQ_rec *lastrec=NULL; - while (p) - { - if (hwnd && p->hwnd != hwnd) { lastrec=p; p=p->next; } - else - { - PMQ_rec *next=p->next; - - p->next=m_pmq_empty; // add p to empty list - m_pmq_empty=p; - m_pmq_size--; - - - if (p==m_pmq_tail) m_pmq_tail=lastrec; // update tail - - if (lastrec) p = lastrec->next = next; - else p = m_pmq = next; - } - } - m_pmq_mutex->Leave(); -} - -static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc) -{ - if (!h||!m_pmq_mutex) return; - WDL_MutexLock lock(m_pmq_mutex); - - PMQ_rec *rec=m_pmq; - while (rec) - { - if (rec->is_special_timer && rec->hwnd == h && rec->wParam == timerid) - { - rec->msg = rate; // adjust to new rate - rec->lParam = (LPARAM)tProc; - return; - } - rec=rec->next; - } - - rec=m_pmq_empty; - if (rec) m_pmq_empty=rec->next; - else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); - rec->next=0; - rec->hwnd=h; - rec->msg=rate; - rec->wParam=timerid; - rec->lParam=(LPARAM)tProc; - rec->is_special_timer=true; - - if (m_pmq_tail) m_pmq_tail->next=rec; - else - { - PMQ_rec *p=m_pmq; - while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety - if (p) p->next=rec; - else m_pmq=rec; - } - m_pmq_tail=rec; - m_pmq_size++; -} - -BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!hwnd||!m_pmq_mutex) return FALSE; - if (![(id)hwnd respondsToSelector:@selector(swellCanPostMessage)]) return FALSE; - - BOOL ret=FALSE; - m_pmq_mutex->Enter(); - - if ((m_pmq_empty||m_pmq_sizenext; - else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); - rec->next=0; - rec->hwnd=hwnd; - rec->msg=msg; - rec->wParam=wParam; - rec->lParam=lParam; - rec->is_special_timer=false; - - if (m_pmq_tail) m_pmq_tail->next=rec; - else - { - PMQ_rec *p=m_pmq; - while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety - if (p) p->next=rec; - else m_pmq=rec; - } - m_pmq_tail=rec; - m_pmq_size++; - - ret=TRUE; - } - - m_pmq_mutex->Leave(); - - return ret; -} - - -static bool s_rightclickemulate=true; - -bool IsRightClickEmulateEnabled() -{ - return s_rightclickemulate; -} - -void SWELL_EnableRightClickEmulate(BOOL enable) -{ - s_rightclickemulate=enable; -} - - -#endif diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp deleted file mode 100644 index 7c9374d5..00000000 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic APIs for browsing for files, directories, and messageboxes. - - These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. - - */ - - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-internal.h" -#include "swell-dlggen.h" - -static const char *BFSF_Templ_dlgid; -static DLGPROC BFSF_Templ_dlgproc; -static struct SWELL_DialogResourceIndex *BFSF_Templ_reshead; -void BrowseFile_SetTemplate(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) -{ - BFSF_Templ_reshead=reshead; - BFSF_Templ_dlgid=dlgid; - BFSF_Templ_dlgproc=dlgProc; -} - -// return true -bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, - char *fn, int fnsize) -{ - return false; -} - -bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) -{ - return false; -} - - -char *BrowseForFiles(const char *text, const char *initialdir, - const char *initialfile, bool allowmul, const char *extlist) -{ - return NULL; -} - - -static LRESULT WINAPI swellMessageBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_CREATE: - if (lParam) // swell-specific - { - SetWindowLong(hwnd,GWL_WNDPROC,(LPARAM)SwellDialogDefaultWindowProc); - SetWindowLong(hwnd,DWL_DLGPROC,(LPARAM)swellMessageBoxProc); - void **parms = (void **)lParam; - if (parms[1]) SetWindowText(hwnd,(const char*)parms[1]); - - - int nbuttons=1; - const char *buttons[3] = { "OK", "", "" }; - int button_ids[3] = {IDOK,0,0}; - int button_sizes[3]; - - int mode = ((int)(INT_PTR)parms[2]); - if (mode == MB_RETRYCANCEL) { buttons[0]="Retry"; button_ids[0]=IDRETRY; } - if (mode == MB_YESNO || mode == MB_YESNOCANCEL) { buttons[0]="Yes"; button_ids[0] = IDYES; buttons[nbuttons] = "No"; button_ids[nbuttons] = IDNO; nbuttons++; } - if (mode == MB_OKCANCEL || mode == MB_YESNOCANCEL || mode == MB_RETRYCANCEL) { buttons[nbuttons] = "Cancel"; button_ids[nbuttons] = IDCANCEL; nbuttons++; } - - SWELL_MakeSetCurParms(1,1,0,0,hwnd,false,false); - RECT labsize = {0,0,300,20}; - HWND lab = SWELL_MakeLabel(-1,parms[0] ? (const char *)parms[0] : "", 0, 0,0,10,10,SS_CENTER); //we'll resize this manually - HDC dc=GetDC(lab); - if (lab && parms[0]) - { - DrawText(dc,(const char *)parms[0],-1,&labsize,DT_CALCRECT);// if dc isnt valid yet, try anyway - } - labsize.top += 10; - labsize.bottom += 18; - - int x; - const int button_spacing = 8; - int button_height=0, button_total_w=0;; - for (x = 0; x < nbuttons; x ++) - { - RECT r={0,0,35,12}; - DrawText(dc,buttons[x],-1,&r,DT_CALCRECT|DT_SINGLELINE); - button_sizes[x] = r.right-r.left + 8; - button_total_w += button_sizes[x] + (x ? button_spacing : 0); - if (r.bottom-r.top+10 > button_height) button_height = r.bottom-r.top+10; - } - - if (labsize.right < button_total_w+16) labsize.right = button_total_w+16; - - int xpos = labsize.right/2 - button_total_w/2; - for (x = 0; x < nbuttons; x ++) - { - SWELL_MakeButton(0,buttons[x],button_ids[x],xpos,labsize.bottom,button_sizes[x],button_height,0); - xpos += button_sizes[x] + button_spacing; - } - - if (dc) ReleaseDC(lab,dc); - SWELL_MakeSetCurParms(1,1,0,0,NULL,false,false); - if (lab) SetWindowPos(lab,NULL,0,0,labsize.right,labsize.bottom,SWP_NOACTIVATE|SWP_NOZORDER); - SetWindowPos(hwnd,NULL,0,0,labsize.right,labsize.bottom + button_height + 8,SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); - } - break; - case WM_COMMAND: - if (LOWORD(wParam) && HIWORD(wParam) == BN_CLICKED ) EndDialog(hwnd,LOWORD(wParam)); - break; - case WM_CLOSE: - if (GetDlgItem(hwnd,IDCANCEL)) EndDialog(hwnd,IDCANCEL); - else if (GetDlgItem(hwnd,IDNO)) EndDialog(hwnd,IDNO); - else if (GetDlgItem(hwnd,IDYES)) EndDialog(hwnd,IDYES); - else EndDialog(hwnd,IDOK); - break; - } - return 0; -} - -int MessageBox(HWND hwndParent, const char *text, const char *caption, int type) -{ - printf("MessageBox: %s %s\n",text,caption); - const void *parms[3]= {text,caption,(void*)(INT_PTR)type} ; - return DialogBoxParam(NULL,NULL,NULL,swellMessageBoxProc,(LPARAM)parms); - -#if 0 - int ret=0; - - if (type == MB_OK) - { - // todo - ret=IDOK; - } - else if (type == MB_OKCANCEL) - { - ret = 1; // todo - if (ret) ret=IDOK; - else ret=IDCANCEL; - } - else if (type == MB_YESNO) - { - ret = 1 ; // todo - if (ret) ret=IDYES; - else ret=IDNO; - } - else if (type == MB_RETRYCANCEL) - { - ret = 1; // todo - - if (ret) ret=IDRETRY; - else ret=IDCANCEL; - } - else if (type == MB_YESNOCANCEL) - { - ret = 1; // todo - - if (ret == 1) ret=IDYES; - else if (ret==-1) ret=IDNO; - else ret=IDCANCEL; - } - - return ret; -#endif -} - -#endif diff --git a/WDL/swell/swell-miscdlg-gtk.cpp b/WDL/swell/swell-miscdlg-gtk.cpp deleted file mode 100644 index 523ac2c7..00000000 --- a/WDL/swell/swell-miscdlg-gtk.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux - Copyright (C) 2006-2008, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic APIs for browsing for files, directories, and messageboxes. - - These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. - - - (GTK version) - */ - - -#ifndef SWELL_PROVIDED_BY_APP - -#include - -#include "swell.h" - -void BrowseFile_SetTemplate(int dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) -{ -} - -// return true -bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, - char *fn, int fnsize) -{ - return false; -} - -bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) -{ - return false; -} - - - -char *BrowseForFiles(const char *text, const char *initialdir, - const char *initialfile, bool allowmul, const char *extlist) -{ - return NULL; -} - - -static void messagebox_callback( GtkWidget *widget, gpointer data ) -{ - if (data) *(char*)data=1; - gtk_main_quit (); -} - -int MessageBox(HWND hwndParent, const char *text, const char *caption, int type) -{ - char has_clicks[3]={0,}; - int ids[3]={0,}; - const char *lbls[3]={0,}; - if (type == MB_OKCANCEL) - { - ids[0]=IDOK; lbls[0]="OK"; - ids[1]=IDCANCEL; lbls[1]="Cancel"; - } - else if (type == MB_YESNO) - { - ids[0]=IDYES; lbls[0]="Yes"; - ids[1]=IDNO; lbls[1]="No"; - } - else if (type == MB_YESNOCANCEL) - { - ids[0]=IDYES; lbls[0]="Yes"; - ids[1]=IDNO; lbls[1]="No"; - ids[2]=IDCANCEL; lbls[2]="Cancel"; - } - else // MB_OK? - { - ids[0]=IDOK; lbls[0]="OK"; - } - - GtkWidget *window; - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_modal(GTK_WINDOW(window), true); - gtk_window_set_destroy_with_parent(GTK_WINDOW(window), true); - gtk_window_set_resizable(GTK_WINDOW(window), false); - gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); - gtk_window_set_title(GTK_WINDOW(window), caption); - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (messagebox_callback), NULL); - - gtk_container_set_border_width (GTK_CONTAINER (window), 10); - - GtkWidget *outer_container = gtk_vbox_new(false, 4); - { - GtkWidget *label = gtk_label_new(text); - gtk_container_add(GTK_CONTAINER(outer_container),label); - gtk_widget_show(label); - } - { - GtkWidget *con = gtk_hbutton_box_new(); - int x; - for(x=0;x<3&&ids[x];x++) - { - GtkWidget *but = gtk_button_new_with_label(lbls[x]); - g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(messagebox_callback), &has_clicks[x]); - gtk_container_add(GTK_CONTAINER(con), but); - gtk_widget_show(but); - } - gtk_container_add(GTK_CONTAINER(outer_container),con); - gtk_widget_show(con); - } - - - gtk_container_add(GTK_CONTAINER(window), outer_container); - gtk_widget_show(outer_container); - gtk_widget_show(window); - - gtk_main (); - - int x; - for(x=0;x<3 && ids[x]; x++) - { - if (has_clicks[x]) return ids[x]; - } - if (x>0) x--; - return ids[x]; -} - -#endif diff --git a/WDL/swell/swell-miscdlg.mm b/WDL/swell/swell-miscdlg.mm deleted file mode 100644 index e29637d6..00000000 --- a/WDL/swell/swell-miscdlg.mm +++ /dev/null @@ -1,354 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic APIs for browsing for files, directories, and messageboxes. - - These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. - - */ - - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#import -static NSMutableArray *extensionsFromList(const char *extlist) -{ - NSMutableArray *fileTypes = [[NSMutableArray alloc] initWithCapacity:30]; - while (*extlist) - { - extlist += strlen(extlist)+1; - if (!*extlist) break; - while (*extlist) - { - while (*extlist && *extlist != '.') extlist++; - if (!*extlist) break; - extlist++; - char tmp[32]; - lstrcpyn(tmp,extlist,sizeof(tmp)); - if (strstr(tmp,";")) strstr(tmp,";")[0]=0; - if (tmp[0] && tmp[0]!='*') - { - NSString *s=(NSString *)SWELL_CStringToCFString(tmp); - [fileTypes addObject:s]; - [s release]; - } - while (*extlist && *extlist != ';') extlist++; - if (*extlist == ';') extlist++; - } - extlist++; - } - - return fileTypes; -} - -static const char *BFSF_Templ_dlgid; -static DLGPROC BFSF_Templ_dlgproc; -static struct SWELL_DialogResourceIndex *BFSF_Templ_reshead; -void BrowseFile_SetTemplate(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) -{ - BFSF_Templ_reshead=reshead; - BFSF_Templ_dlgid=dlgid; - BFSF_Templ_dlgproc=dlgProc; -} - -// return true -bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, - char *fn, int fnsize) -{ - NSSavePanel *panel = [NSSavePanel savePanel]; - NSString *title=(NSString *)SWELL_CStringToCFString(text); - [panel setTitle:title]; - [panel setAccessoryView:nil]; - HWND oh=NULL; - if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel - { - oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); - BFSF_Templ_dlgproc=0; - BFSF_Templ_dlgid=0; - } - - NSMutableArray *fileTypes = extensionsFromList(extlist); - - [panel setAllowedFileTypes:fileTypes]; - NSString *ifn=0; - NSString *idir=0; - - if (initialfile && *initialfile) - { - char s[2048]; - lstrcpyn(s,initialfile,sizeof(s)); - char *p=s; - while (*p) p++; - while (p >= s && *p != '/') p--; - if (p>=s) - { - *p=0; - ifn=(NSString *)SWELL_CStringToCFString(p+1); - idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/"); - } - else - ifn=(NSString *)SWELL_CStringToCFString(s); - } - if (!idir && initialdir && *initialdir) - { - idir=(NSString *)SWELL_CStringToCFString(initialdir); - } - - HMENU hm=SWELL_GetDefaultModalWindowMenu(); - if (hm) hm=SWELL_DuplicateMenu(hm); - SWELL_SetCurrentMenu(hm); - int result = [panel runModalForDirectory:idir file:ifn]; - SWELL_SetCurrentMenu(GetMenu(GetFocus())); - if (hm) DestroyMenu(hm); - - if (oh) SendMessage(oh,WM_DESTROY,0,0); - [panel setAccessoryView:nil]; - [title release]; - [fileTypes release]; - - if (result == NSOKButton) - { - char buf[2048]; - buf[0]=0; - buf[sizeof(buf)-1]=0; - SWELL_CFStringToCString([panel filename],buf,(sizeof(buf)-1)); - if (buf[0]) - { - lstrcpyn(fn,buf,fnsize); - return true; - } - } - - return false; - -} - -bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) -{ - NSOpenPanel *panel = [NSOpenPanel openPanel]; - NSString *title=(NSString *)SWELL_CStringToCFString(text); - [panel setTitle:title]; - [panel setAllowsMultipleSelection:NO]; - [panel setCanChooseFiles:NO]; - [panel setCanCreateDirectories:YES]; - [panel setCanChooseDirectories:YES]; - [panel setResolvesAliases:YES]; - - HWND oh=NULL; - if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel - { - oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); - BFSF_Templ_dlgproc=0; - BFSF_Templ_dlgid=0; - } - - NSString *idir=0; - - if (initialdir && *initialdir) - { - idir=(NSString *)SWELL_CStringToCFString(initialdir); - } - - HMENU hm=SWELL_GetDefaultModalWindowMenu(); - if (hm) hm=SWELL_DuplicateMenu(hm); - SWELL_SetCurrentMenu(hm); - int result = [panel runModalForDirectory:idir file:nil types:nil]; - SWELL_SetCurrentMenu(GetMenu(GetFocus())); - if (hm) DestroyMenu(hm); - - if (oh) SendMessage(oh,WM_DESTROY,0,0); - [panel setAccessoryView:nil]; - - if (idir) [idir release]; - - [title release]; - - if (result != NSOKButton) return 0; - - NSArray *filesToOpen = [panel filenames]; - int count = [filesToOpen count]; - - if (!count) return 0; - - NSString *aFile = [filesToOpen objectAtIndex:0]; - if (!aFile) return 0; - SWELL_CFStringToCString(aFile,fn,(fnsize-1)); - fn[fnsize-1]=0; - return 1; -} - - -char *BrowseForFiles(const char *text, const char *initialdir, - const char *initialfile, bool allowmul, const char *extlist) -{ - NSOpenPanel *panel = [NSOpenPanel openPanel]; - NSString *title=(NSString *)SWELL_CStringToCFString(text); - HWND oh=NULL; - if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel - { - oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); - BFSF_Templ_dlgproc=0; - BFSF_Templ_dlgid=0; - } - - [panel setTitle:title]; - [panel setAllowsMultipleSelection:(allowmul?YES:NO)]; - [panel setCanChooseFiles:YES]; - [panel setCanChooseDirectories:NO]; - [panel setResolvesAliases:YES]; - - NSMutableArray *fileTypes = extensionsFromList(extlist); - - NSString *ifn=0; - NSString *idir=0; - - if (initialfile && *initialfile) - { - char s[2048]; - lstrcpyn(s,initialfile,sizeof(s)); - char *p=s; - while (*p) p++; - while (p >= s && *p != '/') p--; - if (p>=s) - { - *p=0; - ifn=(NSString *)SWELL_CStringToCFString(p+1); - idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/"); - } - else - ifn=(NSString *)SWELL_CStringToCFString(s); - - } - if (!idir && initialdir && *initialdir) - { - idir=(NSString *)SWELL_CStringToCFString(initialdir); - } - - HMENU hm=SWELL_GetDefaultModalWindowMenu(); - if (hm) hm=SWELL_DuplicateMenu(hm); - SWELL_SetCurrentMenu(hm); - - int result = [panel runModalForDirectory:idir file:ifn types:fileTypes]; - - SWELL_SetCurrentMenu(GetMenu(GetFocus())); - if (hm) DestroyMenu(hm); - - if (oh) SendMessage(oh,WM_DESTROY,0,0); - [panel setAccessoryView:nil]; - - if (ifn) [ifn release]; - if (idir) [idir release]; - - [fileTypes release]; - [title release]; - - if (result != NSOKButton) return 0; - - NSArray *filesToOpen = [panel filenames]; - int i, count = [filesToOpen count]; - - if (!count) return 0; - - if (count==1||!allowmul) - { - NSString *aFile = [filesToOpen objectAtIndex:0]; - if (!aFile) return 0; - char fn[2048]; - SWELL_CFStringToCString(aFile,fn,(sizeof(fn)-1)); - fn[sizeof(fn)-1]=0; - char *ret=(char *)malloc(strlen(fn)+2); - memcpy(ret,fn,strlen(fn)); - ret[strlen(fn)]=0; - ret[strlen(fn)+1]=0; - return ret; - } - - int rsize=1; - char *ret=0; - for (i=0; i=nSize)sz=nSize-1; - fn[sz]=0; - char *p=fn; - while (*p) p++; - while (p >= fn && *p != '/') p--; - strcpy(++p,"libSwell.so"); - - void *tmp = dlopen(fn,RTLD_LAZY); - if (!tmp) - { - printf("Error loading '%s'\n",fn); - perror("dlopen:"); - exit(2); - } -#else - void *tmp = dlopen(NULL,RTLD_LAZY); -#endif - - if (tmp) *(void **)&SWELLAPI_GetFunc = dlsym(tmp,"SWELLAPI_GetFunc"); - //printf("tmp=%08x, SWELLAPI_GetFunc=%08x\n",tmp,SWELLAPI_GetFunc); - - if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)!=(void*)0x100) SWELLAPI_GetFunc=0; - -#ifdef SWELL_LOAD_SWELL_DYLIB - __loaded_getfunc = SWELLAPI_GetFunc; -#endif - int x; - for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) - { - *api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0; - if (!*api_tab[x].func) - { - printf("SWELL API not found: %s\n",api_tab[x].name); -#ifdef SWELL_LOAD_SWELL_DYLIB - exit(1); -#endif - *api_tab[x].func = (void*)&dummyFunc; - } - } - } - ~SwellAPPInitializer() - { - } -}; - -SwellAPPInitializer m_swell_appAPIinit; - -#ifdef SWELL_LOAD_SWELL_DYLIB -extern "C" __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) -{ - if (__loaded_getfunc) return __loaded_getfunc(name); - return NULL; -} - -#endif - -extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc) -{ - // this returning 1 allows DllMain to be called, if available - return 1; -} - -#endif diff --git a/WDL/swell/swell-modstub.mm b/WDL/swell/swell-modstub.mm deleted file mode 100644 index cb5f88ff..00000000 --- a/WDL/swell/swell-modstub.mm +++ /dev/null @@ -1,70 +0,0 @@ -#ifdef SWELL_PROVIDED_BY_APP - -#import -#import -#define SWELL_API_DEFPARM(x) -#define SWELL_API_DEFINE(ret,func,parms) ret (*func) parms ; -#include "swell.h" - -// only include this file in projects that are linked to swell.dylib - -struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; -struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; -struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; - -// define the functions - -static struct -{ - const char *name; - void **func; -} api_tab[]={ - -#undef _WDL_SWELL_H_API_DEFINED_ -#undef SWELL_API_DEFINE -#define SWELL_API_DEFINE(ret, func, parms) {#func, (void **)&func }, - -#include "swell-functions.h" - -}; - -static int dummyFunc() { return 0; } - -class SwellAPPInitializer -{ -public: - SwellAPPInitializer() - { - void *(*SWELLAPI_GetFunc)(const char *name)=NULL; - - id del = [NSApp delegate]; - if (del && [del respondsToSelector:@selector(swellGetAPPAPIFunc)]) - *(void **)&SWELLAPI_GetFunc = (void *)objc_msgSend(del,@selector(swellGetAPPAPIFunc)); - - if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)!=(void*)0x100) SWELLAPI_GetFunc=0; - - int x; - for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) - { - *api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0; - if (!*api_tab[x].func) - { - printf("SWELL API not found: %s\n",api_tab[x].name); - *api_tab[x].func = (void*)&dummyFunc; - } - } - } - ~SwellAPPInitializer() - { - } -}; - -SwellAPPInitializer m_swell_appAPIinit; - -extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc) -{ - // this returning 1 allows DllMain to be called, if available - return 1; -} - -#endif diff --git a/WDL/swell/swell-types.h b/WDL/swell/swell-types.h deleted file mode 100644 index 96e33520..00000000 --- a/WDL/swell/swell-types.h +++ /dev/null @@ -1,1337 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) - Copyright (C) 2006-2010, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. - - */ - -#ifndef _WDL_SWELL_H_TYPES_DEFINED_ -#define _WDL_SWELL_H_TYPES_DEFINED_ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -typedef intptr_t INT_PTR, *PINT_PTR, LONG_PTR, *PLONG_PTR; -typedef uintptr_t UINT_PTR, *PUINT_PTR, ULONG_PTR, *PULONG_PTR, DWORD_PTR, *PDWORD_PTR; - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef max -#define max(x,y) ((x)<(y)?(y):(x)) -#define min(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef S_OK -#define S_OK 0 -#endif -#ifndef E_FAIL -#define E_FAIL (-1) -#endif - - -// the byte ordering of RGB() etc is different than on win32 -#define RGB(r,g,b) (((r)<<16)|((g)<<8)|(b)) -#define GetRValue(x) (((x)>>16)&0xff) -#define GetGValue(x) (((x)>>8)&0xff) -#define GetBValue(x) ((x)&0xff) - -// basic platform compat defines -#define stricmp(x,y) strcasecmp(x,y) -#define strnicmp(x,y,z) strncasecmp(x,y,z) - -#define DeleteFile(x) (!unlink(x)) -#define MoveFile(x,y) (!rename(x,y)) -#define GetCurrentDirectory(sz,buf) (!getcwd(buf,sz)) -#define SetCurrentDirectory(buf) (!chdir(buf)) -#define CreateDirectory(x,y) (!mkdir((x),0755)) -#define wsprintf sprintf - -#ifndef LOWORD -#define MAKEWORD(a, b) ((unsigned short)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) -#define MAKELONG(a, b) ((int)(((unsigned short)(a)) | ((DWORD)((unsigned short)(b))) << 16)) -#define MAKEWPARAM(l, h) (WPARAM)MAKELONG(l, h) -#define MAKELPARAM(l, h) (LPARAM)MAKELONG(l, h) -#define MAKELRESULT(l, h) (LRESULT)MAKELONG(l, h) -#define LOWORD(l) ((unsigned short)(l)) -#define HIWORD(l) ((unsigned short)(((unsigned int)(l) >> 16) & 0xFFFF)) -#define LOBYTE(w) ((BYTE)(w)) -#define HIBYTE(w) ((BYTE)(((unsigned short)(w) >> 8) & 0xFF)) -#endif - -#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) -#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) - -#define UNREFERENCED_PARAMETER(P) (P) -#define _T(T) T - -#define CallWindowProc(A,B,C,D,E) ((WNDPROC)A)(B,C,D,E) -#define OffsetRect WinOffsetRect //to avoid OSX's OffsetRect function -#define SetRect WinSetRect //to avoid OSX's SetRect function -#define UnionRect WinUnionRect -#define IntersectRect WinIntersectRect - - -#define MAX_PATH 1024 - - - -// SWELLAPP stuff (swellappmain.mm) -#ifdef __cplusplus -extern "C" { -#endif -INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2); // to be implemented by app (if using swellappmain.mm) -#ifdef __cplusplus -}; -#endif - -#define SWELLAPP_ONLOAD 0x0001 // initialization of app vars etc -#define SWELLAPP_LOADED 0x0002 // create dialogs etc -#define SWELLAPP_DESTROY 0x0003 // about to destroy (cleanup etc) -#define SWELLAPP_SHOULDDESTROY 0x0004 // return 0 to allow app to terminate, >0 to prevent - -#define SWELLAPP_OPENFILE 0x0050 // parm1= (const char *)string, return >0 if allowed -#define SWELLAPP_NEWFILE 0x0051 // new file, return >0 if allowed -#define SWELLAPP_SHOULDOPENNEWFILE 0x0052 // allow opening new file? >0 if allowed - -#define SWELLAPP_ONCOMMAND 0x0099 // parm1 = (int) command ID, parm2 = (id) sender -#define SWELLAPP_PROCESSMESSAGE 0x0100 // parm1=(MSG *)msg (loosely), parm2= (NSEvent *) the event . return >0 to eat - -#define SWELLAPP_ACTIVATE 0x1000 // parm1 = (bool) isactive. return nonzero to prevent WM_ACTIVATEAPP from being broadcasted -// - - - - -// basic types -typedef signed char BOOL; -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned int DWORD; -typedef DWORD COLORREF; -typedef unsigned int UINT; -typedef int INT; - -typedef ULONG_PTR WPARAM; -typedef LONG_PTR LPARAM; -typedef LONG_PTR LRESULT; - - -typedef void *LPVOID, *PVOID; - -#if defined(__APPLE__) && !defined(__LP64__) -typedef signed long HRESULT; -typedef signed long LONG; -typedef unsigned long ULONG; -#else -typedef signed int HRESULT; -typedef signed int LONG; -typedef unsigned int ULONG; -#endif - -typedef short SHORT; -typedef int *LPINT; -typedef char CHAR; -typedef char *LPSTR; -typedef const char *LPCSTR; - -#define __int64 long long // define rather than typedef, for unsigned __int64 support - -typedef unsigned __int64 ULONGLONG; - -typedef union { - unsigned long long QuadPart; - struct { - #ifdef __ppc__ - DWORD HighPart; - DWORD LowPart; - #else - DWORD LowPart; - DWORD HighPart; - #endif - }; -} ULARGE_INTEGER; - - -typedef struct HWND__ *HWND; -typedef struct HMENU__ *HMENU; -typedef void *HANDLE, *HINSTANCE, *HDROP; -typedef void *HGLOBAL; - -typedef void (*TIMERPROC)(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); - -typedef struct -{ - LONG x,y; -} POINT, *LPPOINT; - - -typedef struct -{ - SHORT x; - SHORT y; -} POINTS; - - -typedef struct -{ - LONG left,top, right, bottom; -} RECT, *LPRECT; - - -typedef struct { - unsigned char fVirt; - unsigned short key,cmd; -} ACCEL, *LPACCEL; - - -typedef struct { - DWORD dwLowDateTime; - DWORD dwHighDateTime; -} FILETIME; - -typedef struct _GUID { - unsigned int Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; - -typedef struct { - HWND hwnd; - UINT message; - WPARAM wParam; - LPARAM lParam; - DWORD time; - POINT pt; -} MSG, *LPMSG; - -typedef struct HDC__ *HDC; -typedef struct HCURSOR__ *HCURSOR; -typedef struct HRGN__ *HRGN; - -typedef struct HGDIOBJ__ *HBITMAP; -typedef struct HGDIOBJ__ *HICON; -typedef struct HGDIOBJ__ *HGDIOBJ; -typedef struct HGDIOBJ__ *HBRUSH; -typedef struct HGDIOBJ__ *HPEN; -typedef struct HGDIOBJ__ *HFONT; - - -typedef struct -{ - HWND hwndFrom; - UINT_PTR idFrom; - UINT code; -} NMHDR, *LPNMHDR; - - -typedef struct { - NMHDR hdr; - DWORD_PTR dwItemSpec; - DWORD_PTR dwItemData; - POINT pt; - DWORD dwHitInfo; -} NMMOUSE, *LPNMMOUSE; -typedef NMMOUSE NMCLICK; -typedef LPNMMOUSE LPNMCLICK; - -typedef struct -{ - int mask, fmt,cx; - char *pszText; - int cchTextMax, iSubItem; -} LVCOLUMN; -typedef struct -{ - int mask, iItem, iSubItem, state, stateMask; - char *pszText; - int cchTextMax, iImage; - LPARAM lParam; -} LVITEM; - -typedef int (*PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); - -typedef struct HIMAGELIST__ *HIMAGELIST; - -typedef struct -{ - POINT pt; - UINT flags; - int iItem; - int iSubItem; // this is was NOT in win95. valid only for LVM_SUBITEMHITTEST -} LVHITTESTINFO, *LPLVHITTESTINFO; - - -typedef struct -{ - NMHDR hdr; - int iItem; - int iSubItem; - UINT uNewState; - UINT uOldState; - UINT uChanged; - POINT ptAction; - LPARAM lParam; -} NMLISTVIEW, *LPNMLISTVIEW; - -typedef struct -{ - NMHDR hdr; - LVITEM item; -} NMLVDISPINFO, *LPNMLVDISPINFO; - -typedef struct -{ - UINT mask; - int cxy; - char* pszText; - HBITMAP hbm; - int cchTextMax; - int fmt; - LPARAM lParam; - int iImage; - int iOrder; - UINT type; - void *pvFilter; - UINT state; -} HDITEM, *LPHDITEM; - -typedef struct TCITEM -{ - UINT mask; - DWORD dwState; - DWORD dwStateMask; - char *pszText; - int cchTextMax; - int iImage; - - LPARAM lParam; -} TCITEM, *LPTCITEM; - -typedef struct tagDRAWITEMSTRUCT { - UINT CtlType; - UINT CtlID; - UINT itemID; - UINT itemAction; - UINT itemState; - HWND hwndItem; - HDC hDC; - RECT rcItem; - DWORD_PTR itemData; -} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT; - -typedef struct tagBITMAP { - LONG bmWidth; - LONG bmHeight; -} BITMAP, *PBITMAP, *LPBITMAP; -#define ODT_MENU 1 -#define ODT_LISTBOX 2 -#define ODT_COMBOBOX 3 -#define ODT_BUTTON 4 - -#define ODS_SELECTED 0x0001 - - - - -typedef struct -{ - DWORD cbSize; - HWND hWnd; - UINT uID; - UINT uFlags; - UINT uCallbackMessage; - HICON hIcon; - CHAR szTip[64]; -} NOTIFYICONDATA,*PNOTIFYICONDATA, *LPNOTIFYICONDATA; - - -#define NIM_ADD 0x00000000 -#define NIM_MODIFY 0x00000001 -#define NIM_DELETE 0x00000002 - -#define NIF_MESSAGE 0x00000001 -#define NIF_ICON 0x00000002 -#define NIF_TIP 0x00000004 - - - -typedef struct HTREEITEM__ *HTREEITEM; - -#define TVIF_TEXT 0x0001 -#define TVIF_IMAGE 0x0002 -#define TVIF_PARAM 0x0004 -#define TVIF_STATE 0x0008 -#define TVIF_HANDLE 0x0010 -#define TVIF_SELECTEDIMAGE 0x0020 -#define TVIF_CHILDREN 0x0040 - -#define TVIS_SELECTED 0x0002 -#define TVIS_DROPHILITED 0x0008 -#define TVIS_BOLD 0x0010 -#define TVIS_EXPANDED 0x0020 - -#define TVE_COLLAPSE 0x0001 -#define TVE_EXPAND 0x0002 -#define TVE_TOGGLE 0x0003 - -#define TVN_FIRST (0U-400U) // treeview -#define TVN_SELCHANGED (TVN_FIRST-2) - -#define TVI_ROOT ((HTREEITEM)0xFFFF0000) -#define TVI_FIRST ((HTREEITEM)0xFFFF0001) -#define TVI_LAST ((HTREEITEM)0xFFFF0002) -#define TVI_SORT ((HTREEITEM)0xFFFF0003) - -#define TVHT_NOWHERE 0x0001 -#define TVHT_ONITEMICON 0x0002 -#define TVHT_ONITEMLABEL 0x0004 -#define TVHT_ONITEM (TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMSTATEICON) -#define TVHT_ONITEMINDENT 0x0008 -#define TVHT_ONITEMBUTTON 0x0010 -#define TVHT_ONITEMRIGHT 0x0020 -#define TVHT_ONITEMSTATEICON 0x0040 - -#define TVHT_ABOVE 0x0100 -#define TVHT_BELOW 0x0200 -#define TVHT_TORIGHT 0x0400 -#define TVHT_TOLEFT 0x0800 - -typedef struct { - UINT mask; - HTREEITEM hItem; - UINT state; - UINT stateMask; - char *pszText; - int cchTextMax; - int iImage; - int iSelectedImage; - int cChildren; - LPARAM lParam; -} TVITEM, TV_ITEM, *LPTVITEM, *LPTV_ITEM; - -typedef struct { - HTREEITEM hParent; - HTREEITEM hInsertAfter; - TVITEM item; -} TVINSERTSTRUCT, *LPTVINSERTSTRUCT, TV_INSERTSTRUCT, *LPTV_INSERTSTRUCT; - -typedef struct { - POINT pt; - UINT flags; - HTREEITEM hItem; -} TVHITTESTINFO, *LPTVHITTESTINFO; - -typedef struct { - NMHDR hdr; - UINT action; - TVITEM itemOld; - TVITEM itemNew; - POINT ptDrag; -} NMTREEVIEW, *LPNMTREEVIEW; - - -typedef struct -{ - unsigned int cbSize, fMask, fType, fState, wID; - HMENU hSubMenu; - HICON hbmpChecked,hbmpUnchecked; - DWORD_PTR dwItemData; - char *dwTypeData; - int cch; -} MENUITEMINFO; - -#define SetMenuDefaultItem(a,b,c) (0) - -typedef struct { - POINT ptReserved, ptMaxSize, ptMaxPosition, ptMinTrackSize, ptMaxTrackSize; -} MINMAXINFO, *LPMINMAXINFO; - - -typedef struct -{ - int lfHeight, lfWidth, lfEscapement,lfOrientation, lfWeight; - char lfItalic, lfUnderline, lfStrikeOut, lfCharSet, lfOutPrecision, lfClipPrecision, - lfQuality, lfPitchAndFamily; - char lfFaceName[32]; -} LOGFONT; -typedef struct -{ - LONG tmHeight; - LONG tmAscent; - LONG tmDescent; - LONG tmInternalLeading; - LONG tmAveCharWidth; - // todo: implement rest -} TEXTMETRIC; - -typedef struct { - HDC hdc; - BOOL fErase; - RECT rcPaint; -} PAINTSTRUCT; - -typedef struct -{ - UINT cbSize; - UINT fMask; - int nMin; - int nMax; - UINT nPage; - int nPos; - int nTrackPos; -} SCROLLINFO, *LPSCROLLINFO; - -typedef struct -{ - DWORD styleOld; - DWORD styleNew; -} STYLESTRUCT, *LPSTYLESTRUCT; - -typedef struct _DROPFILES { - DWORD pFiles; // offset of file list - POINT pt; // drop point (client coords) - BOOL fNC; // is it on NonClient area - // and pt is in screen coords - BOOL fWide; // WIDE character switch -} DROPFILES, *LPDROPFILES; - - -typedef struct -{ - HWND hwnd; - HWND hwndInsertAfter; - int x; - int y; - int cx; - int cy; - UINT flags; -} WINDOWPOS, *LPWINDOWPOS, *PWINDOWPOS; - -typedef struct -{ - RECT rgrc[3]; - PWINDOWPOS lppos; -} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS; - - - -typedef INT_PTR (*DLGPROC)(HWND, UINT, WPARAM, LPARAM); -typedef LRESULT (*WNDPROC)(HWND, UINT, WPARAM, LPARAM); - - - -#define GF_BEGIN 1 -#define GF_INERTIA 2 -#define GF_END 4 - -#define GID_BEGIN 1 -#define GID_END 2 -#define GID_ZOOM 3 -#define GID_PAN 4 -#define GID_ROTATE 5 -#define GID_TWOFINGERTAP 6 -#define GID_ROLLOVER 7 - -typedef struct tagGESTUREINFO -{ - UINT cbSize; - DWORD dwFlags; - DWORD dwID; - HWND hwndTarget; - POINTS ptsLocation; - DWORD dwInstanceID; - DWORD dwSequenceID; - ULONGLONG ullArguments; - UINT cbExtraArgs; -} GESTUREINFO; - -// not using this stuff yet -#define GC_PAN 1 -#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 2 -#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 4 - -typedef struct tagGESTURECONFIG -{ - DWORD dwID; - DWORD dwWant; - DWORD dwBlock; -} GESTURECONFIG; - - - -#ifndef WINAPI -#define WINAPI -#endif - -#ifndef CALLBACK -#define CALLBACK -#endif - - -typedef BOOL (*PROPENUMPROCEX)(HWND hwnd, const char *lpszString, HANDLE hData, LPARAM lParam); - -// swell specific type -typedef HWND (*SWELL_ControlCreatorProc)(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h); - -#define DLL_PROCESS_DETACH 0 -#define DLL_PROCESS_ATTACH 1 - -// if the user implements this (and links with swell-modstub[-generic], this will get called for DLL_PROCESS_[AT|DE]TACH -#ifdef __cplusplus -extern "C" { -#endif -__attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved); -#ifdef __cplusplus -}; -#endif - -/* - ** win32 specific constants - */ -#define MB_OK 0 -#define MB_OKCANCEL 1 -#define MB_YESNOCANCEL 3 -#define MB_YESNO 4 -#define MB_RETRYCANCEL 5 - -#define MB_ICONERROR 0 -#define MB_ICONSTOP 0 -#define MB_ICONINFORMATION 0 - -#define IDOK 1 -#define IDCANCEL 2 -#define IDABORT 3 -#define IDRETRY 4 -#define IDIGNORE 5 -#define IDYES 6 -#define IDNO 7 - -#define GW_HWNDFIRST 0 -#define GW_HWNDLAST 1 -#define GW_HWNDNEXT 2 -#define GW_HWNDPREV 3 -#define GW_OWNER 4 -#define GW_CHILD 5 - -#define GWL_USERDATA (-21) -#define GWL_ID (-12) -#define GWL_STYLE (-16) // only supported for BS_ for now I think -#define GWL_EXSTYLE (-20) -#define GWL_WNDPROC (-4) -#define DWL_DLGPROC (-8) - -#define SWELL_NOT_WS_VISIBLE 0x80000000L -#define WS_CHILDWINDOW (WS_CHILD) -#define WS_CHILD 0x40000000L -#define WS_DISABLED 0x08000000L -#define WS_CAPTION 0x00C00000L -#define WS_VSCROLL 0x00200000L -#define WS_HSCROLL 0x00100000L -#define WS_SYSMENU 0x00080000L -#define WS_THICKFRAME 0x00040000L -#define WS_GROUP 0x00020000L -#define WS_TABSTOP 0x00010000L - -#define WS_BORDER 0 // ignored for now -#define WS_VISIBLE 0 - - -#define WM_CTLCOLORMSGBOX 0x0132 -#define WM_CTLCOLOREDIT 0x0133 -#define WM_CTLCOLORLISTBOX 0x0134 -#define WM_CTLCOLORBTN 0x0135 -#define WM_CTLCOLORDLG 0x0136 -#define WM_CTLCOLORSCROLLBAR 0x0137 -#define WM_CTLCOLORSTATIC 0x0138 - -#define CB_ADDSTRING 0x0143 -#define CB_DELETESTRING 0x0144 -#define CB_GETCOUNT 0x0146 -#define CB_GETCURSEL 0x0147 -#define CB_GETLBTEXT 0x0148 -#define CB_INSERTSTRING 0x014A -#define CB_RESETCONTENT 0x014B -#define CB_FINDSTRING 0x014C -#define CB_SETCURSEL 0x014E -#define CB_GETITEMDATA 0x0150 -#define CB_SETITEMDATA 0x0151 -#define CB_FINDSTRINGEXACT 0x0158 -#define CB_INITSTORAGE 0x0161 - -#define LB_ADDSTRING 0x0180 -#define LB_INSERTSTRING 0x0181 -#define LB_DELETESTRING 0x0182 -#define LB_GETTEXT 0x0183 -#define LB_RESETCONTENT 0x0184 -#define LB_SETSEL 0x0185 -#define LB_SETCURSEL 0x0186 -#define LB_GETSEL 0x0187 -#define LB_GETCURSEL 0x0188 -#define LB_GETCOUNT 0x018B -#define LB_GETSELCOUNT 0x0190 -#define LB_GETITEMDATA 0x0199 -#define LB_SETITEMDATA 0x019A - -#define TBM_GETPOS (WM_USER) -#define TBM_SETTIC (WM_USER+4) -#define TBM_SETPOS (WM_USER+5) -#define TBM_SETRANGE (WM_USER+6) -#define TBM_SETSEL (WM_USER+10) - -#define PBM_SETRANGE (WM_USER+1) -#define PBM_SETPOS (WM_USER+2) -#define PBM_DELTAPOS (WM_USER+3) - -#define BM_GETCHECK 0x00F0 -#define BM_SETCHECK 0x00F1 -#define BM_GETIMAGE 0x00F6 -#define BM_SETIMAGE 0x00F7 -#define IMAGE_BITMAP 0 -#define IMAGE_ICON 1 - -#define NM_FIRST (0U- 0U) // generic to all controls -#define NM_LAST (0U- 99U) -#define NM_CLICK (NM_FIRST-2) // uses NMCLICK struct -#define NM_DBLCLK (NM_FIRST-3) -#define NM_RCLICK (NM_FIRST-5) // uses NMCLICK struct - - -#define LVSIL_STATE 1 -#define LVSIL_SMALL 2 - -#define LVIR_BOUNDS 0 -#define LVIR_ICON 1 -#define LVIR_LABEL 2 -#define LVIR_SELECTBOUNDS 3 - - -#define LVHT_NOWHERE 0x0001 -#define LVHT_ONITEMICON 0x0002 -#define LVHT_ONITEMLABEL 0x0004 -#define LVHT_ONITEMSTATEICON 0x0008 -#define LVHT_ONITEM (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON) - -#define LVHT_ABOVE 0x0010 -#define LVHT_BELOW 0x0020 -#define LVHT_TORIGHT 0x0040 -#define LVHT_TOLEFT 0x0080 - -#define LVCF_FMT 1 -#define LVCF_WIDTH 2 -#define LVCF_TEXT 4 - -#define LVCFMT_LEFT 0 -#define LVCFMT_RIGHT 1 -#define LVCFMT_CENTER 2 - -#define LVIF_TEXT 1 -#define LVIF_IMAGE 2 -#define LVIF_PARAM 4 -#define LVIF_STATE 8 - -#define LVIS_SELECTED 1 -#define LVIS_FOCUSED 2 -#define LVNI_SELECTED 1 -#define LVNI_FOCUSED 2 -#define INDEXTOSTATEIMAGEMASK(x) ((x)<<16) -#define LVIS_STATEIMAGEMASK (255<<16) - -#define LVN_FIRST (0U-100U) // listview -#define LVN_LAST (0U-199U) -#define LVN_BEGINDRAG (LVN_FIRST-9) -#define LVN_COLUMNCLICK (LVN_FIRST-8) -#define LVN_ITEMCHANGED (LVN_FIRST-1) -#define LVN_ODFINDITEM (LVN_FIRST-52) -#define LVN_GETDISPINFO (LVN_FIRST-50) - -#define LVS_EX_GRIDLINES 0x01 -#define LVS_EX_HEADERDRAGDROP 0x10 -#define LVS_EX_FULLROWSELECT 0x20 // ignored for now (enabled by default on OSX) - -#define HDI_FORMAT 0x4 -#define HDF_SORTUP 0x0400 -#define HDF_SORTDOWN 0x0200 - -#define TCIF_TEXT 0x0001 -#define TCIF_IMAGE 0x0002 -#define TCIF_PARAM 0x0008 -//#define TCIF_STATE 0x0010 - - - -#define TCN_FIRST (0U-550U) // tab control -#define TCN_LAST (0U-580U) -#define TCN_SELCHANGE (TCN_FIRST - 1) - - -#define BS_AUTOCHECKBOX 0x00000003L -#define BS_AUTO3STATE 0x00000006L -#define BS_AUTORADIOBUTTON 0x00000009L -#define BS_OWNERDRAW 0x0000000BL - - - -#define BST_CHECKED 1 -#define BST_UNCHECKED 0 -#define BST_INDETERMINATE 2 - -// note: these differ in values from their win32 counterparts, because we got them -// wrong to begin with, and we'd like to keep backwards compatability for things compiled -// against an old swell.h (and using the SWELL API via an exported mechanism, i.e. third party -// plug-ins). -#define SW_HIDE 0 -#define SW_SHOWNA 1 // 8 on win32 -#define SW_SHOW 2 // 1 on win32 -#define SW_SHOWMINIMIZED 3 // 2 on win32 - -// aliases (todo implement these as needed) -#define SW_SHOWNOACTIVATE SW_SHOWNA -#define SW_NORMAL SW_SHOW -#define SW_SHOWNORMAL SW_SHOW -#define SW_SHOWMAXIMIZED SW_SHOW -#define SW_SHOWDEFAULT SW_SHOWNORMAL -#define SW_RESTORE SW_SHOWNA - -#define SWP_NOMOVE 1 -#define SWP_NOSIZE 2 -#define SWP_NOZORDER 4 -#define SWP_NOACTIVATE 8 -#define SWP_SHOWWINDOW 16 -#define SWP_FRAMECHANGED 32 -#define SWP_NOCOPYBITS 0 -#define HWND_TOP ((HWND)0) -#define HWND_BOTTOM ((HWND)1) -#define HWND_TOPMOST ((HWND)-1) -#define HWND_NOTOPMOST ((HWND)-2) - -// most of these are ignored, actually, but TPM_NONOTIFY and TPM_RETURNCMD are now used -#define TPM_LEFTBUTTON 0x0000L -#define TPM_RIGHTBUTTON 0x0002L -#define TPM_LEFTALIGN 0x0000L -#define TPM_CENTERALIGN 0x0004L -#define TPM_RIGHTALIGN 0x0008L -#define TPM_TOPALIGN 0x0000L -#define TPM_VCENTERALIGN 0x0010L -#define TPM_BOTTOMALIGN 0x0020L -#define TPM_HORIZONTAL 0x0000L /* Horz alignment matters more */ -#define TPM_VERTICAL 0x0040L /* Vert alignment matters more */ -#define TPM_NONOTIFY 0x0080L /* Don't send any notification msgs */ -#define TPM_RETURNCMD 0x0100L - -#define MIIM_ID 1 -#define MIIM_STATE 2 -#define MIIM_TYPE 4 -#define MIIM_SUBMENU 8 -#define MIIM_DATA 16 - -#define MF_ENABLED 0 -#define MF_GRAYED 1 -#define MF_DISABLED 2 -#define MF_STRING 0 -#define MF_BITMAP 4 -#define MF_UNCHECKED 0 -#define MF_CHECKED 8 -#define MF_POPUP 0x10 -#define MF_BYCOMMAND 0 -#define MF_BYPOSITION 0x400 -#define MF_SEPARATOR 0x800 - -#define MFT_STRING MF_STRING -#define MFT_BITMAP MF_BITMAP -#define MFT_SEPARATOR MF_SEPARATOR -#define MFT_RADIOCHECK 0x200 - -#define MFS_GRAYED (MF_GRAYED|MF_DISABLED) -#define MFS_DISABLED MFS_GRAYED -#define MFS_CHECKED MF_CHECKED -#define MFS_ENABLED MF_ENABLED -#define MFS_UNCHECKED MF_UNCHECKED - -#define EN_CHANGE 0x0300 -#define STN_CLICKED 0 -#define STN_DBLCLK 1 -#define WM_CREATE 0x0001 -#define WM_DESTROY 0x0002 -#define WM_MOVE 0x0003 -#define WM_SIZE 0x0005 -#define WM_ACTIVATE 0x0006 -#define WM_SETTEXT 0x000C // not implemented on OSX, used internally on Linux -#define WM_PAINT 0x000F -#define WM_CLOSE 0x0010 -#define WM_ERASEBKGND 0x0014 -#define WM_SHOWWINDOW 0x0018 -#define WM_ACTIVATEAPP 0x001C -#define WM_SETCURSOR 0x0020 -#define WM_MOUSEACTIVATE 0x0021 -#define WM_GETMINMAXINFO 0x0024 -#define WM_DRAWITEM 0x002B -#define WM_SETFONT 0x0030 -#define WM_GETFONT 0x0031 -#define WM_GETOBJECT 0x003D // implemented differently than win32 -- see virtwnd/virtwnd-nsaccessibility.mm -#define WM_NOTIFY 0x004E - -#define WM_CONTEXTMENU 0x007B -#define WM_STYLECHANGED 0x007D -#define WM_DISPLAYCHANGE 0x007E -#define WM_NCDESTROY 0x0082 -#define WM_NCCALCSIZE 0x0083 -#define WM_NCHITTEST 0x0084 -#define WM_NCPAINT 0x0085 -#define WM_NCMOUSEMOVE 0x00A0 -#define WM_NCLBUTTONDOWN 0x00A1 -#define WM_NCLBUTTONUP 0x00A2 -#define WM_NCLBUTTONDBLCLK 0x00A3 -#define WM_NCRBUTTONDOWN 0x00A4 -#define WM_NCRBUTTONUP 0x00A5 -#define WM_NCRBUTTONDBLCLK 0x00A6 -#define WM_NCMBUTTONDOWN 0x00A7 -#define WM_NCMBUTTONUP 0x00A8 -#define WM_NCMBUTTONDBLCLK 0x00A9 -#define WM_KEYFIRST 0x0100 -#define WM_KEYDOWN 0x0100 -#define WM_KEYUP 0x0101 -#define WM_CHAR 0x0102 -#define WM_DEADCHAR 0x0103 -#define WM_SYSKEYDOWN 0x0104 -#define WM_SYSKEYUP 0x0105 -#define WM_SYSCHAR 0x0106 -#define WM_SYSDEADCHAR 0x0107 -#define WM_KEYLAST 0x0108 -#define WM_INITDIALOG 0x0110 -#define WM_COMMAND 0x0111 -#define WM_SYSCOMMAND 0x0112 -#define SC_CLOSE 0xF060 -#define WM_TIMER 0x0113 -#define WM_HSCROLL 0x0114 -#define WM_VSCROLL 0x0115 -#define WM_INITMENUPOPUP 0x0117 -#define WM_GESTURE 0x0119 -#define WM_MOUSEFIRST 0x0200 -#define WM_MOUSEMOVE 0x0200 -#define WM_LBUTTONDOWN 0x0201 -#define WM_LBUTTONUP 0x0202 -#define WM_LBUTTONDBLCLK 0x0203 -#define WM_RBUTTONDOWN 0x0204 -#define WM_RBUTTONUP 0x0205 -#define WM_RBUTTONDBLCLK 0x0206 -#define WM_MBUTTONDOWN 0x0207 -#define WM_MBUTTONUP 0x0208 -#define WM_MBUTTONDBLCLK 0x0209 -#define WM_MOUSEWHEEL 0x020A -#define WM_MOUSEHWHEEL 0x020E -#define WM_MOUSELAST 0x020A -#define WM_CAPTURECHANGED 0x0215 -#define WM_DROPFILES 0x0233 -#define WM_USER 0x0400 - - -#define HTCAPTION 2 -#define HTBOTTOMRIGHT 17 - -#define WA_INACTIVE 0 -#define WA_ACTIVE 1 -#define WA_CLICKACTIVE 2 - -#define BN_CLICKED 0 - -#define LBN_SELCHANGE 1 -#define LBN_DBLCLK 2 -#define LB_ERR (-1) - -#define CBN_SELCHANGE 1 -#define CBN_EDITCHANGE 5 -#define CBN_DROPDOWN 7 -#define CB_ERR (-1) - -#define EM_GETSEL 0xF0B0 -#define EM_SETSEL 0xF0B1 -#define EM_SCROLL 0xF0B5 -#define EM_SETPASSWORDCHAR 0xF0CC - -#define SB_HORZ 0 -#define SB_VERT 1 -#define SB_CTL 2 -#define SB_BOTH 3 - -#define SB_LINEUP 0 -#define SB_LINELEFT 0 -#define SB_LINEDOWN 1 -#define SB_LINERIGHT 1 -#define SB_PAGEUP 2 -#define SB_PAGELEFT 2 -#define SB_PAGEDOWN 3 -#define SB_PAGERIGHT 3 -#define SB_THUMBPOSITION 4 -#define SB_THUMBTRACK 5 -#define SB_TOP 6 -#define SB_LEFT 6 -#define SB_BOTTOM 7 -#define SB_RIGHT 7 -#define SB_ENDSCROLL 8 - -#define DFCS_SCROLLUP 0x0000 -#define DFCS_SCROLLDOWN 0x0001 -#define DFCS_SCROLLLEFT 0x0002 -#define DFCS_SCROLLRIGHT 0x0003 -#define DFCS_SCROLLCOMBOBOX 0x0005 -#define DFCS_SCROLLSIZEGRIP 0x0008 -#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010 - -#define DFCS_INACTIVE 0x0100 -#define DFCS_PUSHED 0x0200 -#define DFCS_CHECKED 0x0400 -#define DFCS_FLAT 0x4000 - -#define DFCS_BUTTONPUSH 0x0010 - -#define DFC_SCROLL 3 -#define DFC_BUTTON 4 - -#define ESB_ENABLE_BOTH 0x0000 -#define ESB_DISABLE_BOTH 0x0003 - -#define ESB_DISABLE_LEFT 0x0001 -#define ESB_DISABLE_RIGHT 0x0002 - -#define ESB_DISABLE_UP 0x0001 -#define ESB_DISABLE_DOWN 0x0002 - -#define BDR_RAISEDOUTER 0x0001 -#define BDR_SUNKENOUTER 0x0002 -#define BDR_RAISEDINNER 0x0004 -#define BDR_SUNKENINNER 0x0008 - -#define BDR_OUTER 0x0003 -#define BDR_INNER 0x000c - -#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) -#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) -#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER) -#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER) - -#define BF_ADJUST 0x2000 -#define BF_FLAT 0x4000 -#define BF_LEFT 0x0001 -#define BF_TOP 0x0002 -#define BF_RIGHT 0x0004 -#define BF_BOTTOM 0x0008 -#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM) - -#define PATCOPY (DWORD)0x00F00021 - -#define HTHSCROLL 6 -#define HTVSCROLL 7 - -#define WS_EX_LEFTSCROLLBAR 0x00004000L -#define WS_EX_ACCEPTFILES 0x00000010L - -#define SIF_RANGE 0x0001 -#define SIF_PAGE 0x0002 -#define SIF_POS 0x0004 -#define SIF_DISABLENOSCROLL 0x0008 -#define SIF_TRACKPOS 0x0010 -#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) - -#define SIZE_RESTORED 0 -#define SIZE_MINIMIZED 1 -#define SIZE_MAXIMIZED 2 -#define SIZE_MAXSHOW 3 -#define SIZE_MAXHIDE 4 - - -#ifndef MAKEINTRESOURCE -#define MAKEINTRESOURCE(x) ((const char *)(UINT_PTR)(x)) -#endif - -#ifdef FSHIFT -#undef FSHIFT -#endif - -#define FVIRTKEY 1 -#define FSHIFT 0x04 -#define FCONTROL 0x08 -#define FALT 0x10 -#define FLWIN 0x20 - - -#define VK_LBUTTON 0x01 -#define VK_RBUTTON 0x02 -#define VK_MBUTTON 0x04 - -#define VK_BACK 0x08 -#define VK_TAB 0x09 - -#define VK_CLEAR 0x0C -#define VK_RETURN 0x0D - -#define VK_SHIFT 0x10 -#define VK_CONTROL 0x11 -#define VK_MENU 0x12 -#define VK_PAUSE 0x13 -#define VK_CAPITAL 0x14 - -#define VK_ESCAPE 0x1B - -#define VK_SPACE 0x20 -#define VK_PRIOR 0x21 -#define VK_NEXT 0x22 -#define VK_END 0x23 -#define VK_HOME 0x24 -#define VK_LEFT 0x25 -#define VK_UP 0x26 -#define VK_RIGHT 0x27 -#define VK_DOWN 0x28 -#define VK_SELECT 0x29 -#define VK_PRINT 0x2A -#define VK_SNAPSHOT 0x2C -#define VK_INSERT 0x2D -#define VK_DELETE 0x2E -#define VK_HELP 0x2F - -#define VK_LWIN 0x5B - -#define VK_NUMPAD0 0x60 -#define VK_NUMPAD1 0x61 -#define VK_NUMPAD2 0x62 -#define VK_NUMPAD3 0x63 -#define VK_NUMPAD4 0x64 -#define VK_NUMPAD5 0x65 -#define VK_NUMPAD6 0x66 -#define VK_NUMPAD7 0x67 -#define VK_NUMPAD8 0x68 -#define VK_NUMPAD9 0x69 -#define VK_MULTIPLY 0x6A -#define VK_ADD 0x6B -#define VK_SEPARATOR 0x6C -#define VK_SUBTRACT 0x6D -#define VK_DECIMAL 0x6E -#define VK_DIVIDE 0x6F -#define VK_F1 0x70 -#define VK_F2 0x71 -#define VK_F3 0x72 -#define VK_F4 0x73 -#define VK_F5 0x74 -#define VK_F6 0x75 -#define VK_F7 0x76 -#define VK_F8 0x77 -#define VK_F9 0x78 -#define VK_F10 0x79 -#define VK_F11 0x7A -#define VK_F12 0x7B -#define VK_NUMLOCK 0x90 -#define VK_SCROLL 0x91 - -#define MK_LBUTTON 0x01 -#define MK_RBUTTON 0x02 -#define MK_MBUTTON 0x10 - - -#define IDC_SIZENESW MAKEINTRESOURCE(-1007) -#define IDC_SIZENWSE MAKEINTRESOURCE(-1006) -#define IDC_IBEAM MAKEINTRESOURCE(-1005) -#define IDC_UPARROW MAKEINTRESOURCE(-1004) -#define IDC_NO MAKEINTRESOURCE(-1003) -#define IDC_SIZEALL MAKEINTRESOURCE(-1002) -#define IDC_SIZENS MAKEINTRESOURCE(-1001) -#define IDC_SIZEWE MAKEINTRESOURCE(-1000) -#define IDC_ARROW MAKEINTRESOURCE(-999) -#define IDC_HAND MAKEINTRESOURCE(32649) - - - - -#define COLOR_3DSHADOW 0 -#define COLOR_3DHILIGHT 1 -#define COLOR_3DFACE 2 -#define COLOR_BTNTEXT 3 -#define COLOR_WINDOW 4 -#define COLOR_SCROLLBAR 5 -#define COLOR_3DDKSHADOW 6 -#define COLOR_BTNFACE 7 -#define COLOR_INFOBK 8 -#define COLOR_INFOTEXT 9 - -#define SRCCOPY 0 -#define SRCCOPY_USEALPHACHAN 0xdeadbeef -#define PS_SOLID 0 -#define DT_CALCRECT 1 -#define DT_VCENTER 2 -#define DT_CENTER 4 -#define DT_END_ELLIPSIS 8 -#define DT_BOTTOM 16 -#define DT_RIGHT 32 -#define DT_SINGLELINE 64 -#define DT_NOPREFIX 128 -#define DT_NOCLIP 256 -#define DT_WORDBREAK 512 - -#define DT_TOP 0 -#define DT_LEFT 0 - -#define FW_DONTCARE 0 -#define FW_THIN 100 -#define FW_EXTRALIGHT 200 -#define FW_LIGHT 300 -#define FW_NORMAL 400 -#define FW_MEDIUM 500 -#define FW_SEMIBOLD 600 -#define FW_BOLD 700 -#define FW_EXTRABOLD 800 -#define FW_HEAVY 900 - -#define FW_ULTRALIGHT FW_EXTRALIGHT -#define FW_REGULAR FW_NORMAL -#define FW_DEMIBOLD FW_SEMIBOLD -#define FW_ULTRABOLD FW_EXTRABOLD -#define FW_BLACK FW_HEAVY - -#define OUT_DEFAULT_PRECIS 0 -#define CLIP_DEFAULT_PRECIS 0 -#define DEFAULT_QUALITY 0 -#define DRAFT_QUALITY 1 -#define PROOF_QUALITY 2 -#define NONANTIALIASED_QUALITY 3 -#define ANTIALIASED_QUALITY 4 -#define DEFAULT_PITCH 0 -#define DEFAULT_CHARSET 0 -#define ANSI_CHARSET 0 -#define TRANSPARENT 0 -#define OPAQUE 1 - -#define NULL_PEN 1 -#define NULL_BRUSH 2 - -#define GMEM_ZEROINIT 1 -#define GMEM_FIXED 0 -#define GMEM_MOVEABLE 0 -#define GMEM_DDESHARE 0 -#define GMEM_DISCARDABLE 0 -#define GMEM_SHARE 0 -#define GMEM_LOWER 0 -#define GHND (GMEM_MOVEABLE|GM_ZEROINIT) -#define GPTR (GMEM_FIXED|GMEM_ZEROINIT) - - -#define _MCW_RC 0x00000300 /* Rounding Control */ -#define _RC_NEAR 0x00000000 /* near */ -#define _RC_DOWN 0x00000100 /* down */ -#define _RC_UP 0x00000200 /* up */ -#define _RC_CHOP 0x00000300 /* chop */ - - -extern struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; -extern struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; -extern struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; - -#define HTNOWHERE 0 -#define HTCLIENT 1 -#define HTMENU 5 -#define HTHSCROLL 6 -#define HTVSCROLL 7 - -#define SM_CXSCREEN 0 -#define SM_CYSCREEN 1 -#define SM_CXVSCROLL 2 -#define SM_CYHSCROLL 3 -#define SM_CYVSCROLL 20 -#define SM_CXHSCROLL 21 - - -#if 0 // these are disabled until implemented - -#define SM_CYCAPTION 4 -#define SM_CXBORDER 5 -#define SM_CYBORDER 6 -#define SM_CXDLGFRAME 7 -#define SM_CYDLGFRAME 8 -#define SM_CYVTHUMB 9 -#define SM_CXHTHUMB 10 -#define SM_CXICON 11 -#define SM_CYICON 12 -#define SM_CXCURSOR 13 -#define SM_CYCURSOR 14 -#define SM_CYMENU 15 -#define SM_CXFULLSCREEN 16 -#define SM_CYFULLSCREEN 17 -#define SM_CYKANJIWINDOW 18 -#define SM_MOUSEPRESENT 19 -#define SM_DEBUG 22 -#define SM_SWAPBUTTON 23 -#define SM_CXMIN 28 -#define SM_CYMIN 29 -#define SM_CXSIZE 30 -#define SM_CYSIZE 31 -#define SM_CXFRAME 32 -#define SM_CYFRAME 33 -#define SM_CXMINTRACK 34 -#define SM_CYMINTRACK 35 -#define SM_CXDOUBLECLK 36 -#define SM_CYDOUBLECLK 37 -#define SM_CXICONSPACING 38 -#define SM_CYICONSPACING 39 - -#endif // unimplemented system metrics - - -#define THREAD_BASE_PRIORITY_LOWRT 15 -#define THREAD_BASE_PRIORITY_MAX 2 -#define THREAD_BASE_PRIORITY_MIN -2 -#define THREAD_BASE_PRIORITY_IDLE -15 -#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN -#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) -#define THREAD_PRIORITY_NORMAL 0 -#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX -#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) -#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT -#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE - - - -#define WAIT_OBJECT_0 (0 ) -#define WAIT_TIMEOUT (0x00000102L) -#define WAIT_FAILED (DWORD)0xFFFFFFFF -#define INFINITE 0xFFFFFFFF - - -typedef struct _ICONINFO -{ - BOOL fIcon; - DWORD xHotspot; - DWORD yHotspot; - HBITMAP hbmMask; - HBITMAP hbmColor; -} ICONINFO, *PICONINFO; - - -#endif //_WDL_SWELL_H_TYPES_DEFINED_ diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp deleted file mode 100644 index 4ca1dfae..00000000 --- a/WDL/swell/swell-wnd-generic.cpp +++ /dev/null @@ -1,3562 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) - Copyright (C) 2006-2008, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - */ - - -#ifndef SWELL_PROVIDED_BY_APP - -#include "swell.h" -#include "swell-internal.h" - -#include -#include "../mutex.h" -#include "../ptrlist.h" -#include "../queue.h" - -#include "swell-dlggen.h" - -int g_swell_want_nice_style = 1; //unused but here for compat - -HWND__ *SWELL_topwindows; - - -static HWND s_captured_window; -HWND SWELL_g_focuswnd; // update from focus-in-event / focus-out-event signals, have to enable the GDK_FOCUS_CHANGE_MASK bits for the gdkwindow -static DWORD s_lastMessagePos; - -#ifdef SWELL_TARGET_GDK - -static GdkWindow *SWELL_g_focus_oswindow; -static int SWELL_gdk_active; - -HWND ChildWindowFromPoint(HWND h, POINT p); -bool IsWindowEnabled(HWND hwnd); - -static void swell_gdkEventHandler(GdkEvent *event, gpointer data); -void SWELL_initargs(int *argc, char ***argv) -{ - if (!SWELL_gdk_active) - { - // maybe make the main app call this with real parms - SWELL_gdk_active = gdk_init_check(argc,argv) ? 1 : -1; - if (SWELL_gdk_active > 0) - gdk_event_handler_set(swell_gdkEventHandler,NULL,NULL); - } -} - -static bool swell_initwindowsys() -{ - if (!SWELL_gdk_active) - { - // maybe make the main app call this with real parms - int argc=1; - char buf[32]; - strcpy(buf,"blah"); - char *argv[2]; - argv[0] = buf; - argv[1] = buf; - char **pargv = argv; - SWELL_initargs(&argc,&pargv); - } - - return SWELL_gdk_active>0; -} - -static void swell_destroyOSwindow(HWND hwnd) -{ - if (hwnd && hwnd->m_oswindow) - { - if (SWELL_g_focus_oswindow == hwnd->m_oswindow) SWELL_g_focus_oswindow=NULL; - gdk_window_destroy(hwnd->m_oswindow); - hwnd->m_oswindow=NULL; -#ifdef SWELL_LICE_GDI - delete hwnd->m_backingstore; - hwnd->m_backingstore=0; -#endif - } -} -static void swell_setOSwindowtext(HWND hwnd) -{ - if (hwnd && hwnd->m_oswindow) - { - gdk_window_set_title(hwnd->m_oswindow, hwnd->m_title ? hwnd->m_title : (char*)""); - } -} -static void swell_manageOSwindow(HWND hwnd, bool wantfocus) -{ - if (!hwnd) return; - - bool isVis = !!hwnd->m_oswindow; - bool wantVis = !hwnd->m_parent && hwnd->m_visible; - - if (isVis != wantVis) - { - if (!wantVis) swell_destroyOSwindow(hwnd); - else - { - if (swell_initwindowsys()) - { - HWND owner = NULL; // hwnd->m_owner; -// parent windows dont seem to work the way we'd want, yet, in gdk... -/* while (owner && !owner->m_oswindow) - { - if (owner->m_parent) owner = owner->m_parent; - else if (owner->m_owner) owner = owner->m_owner; - } -*/ - - RECT r = hwnd->m_position; - GdkWindowAttr attr={0,}; - attr.title = ""; - attr.event_mask = GDK_ALL_EVENTS_MASK|GDK_EXPOSURE_MASK; - attr.x = r.left; - attr.y = r.top; - attr.width = r.right-r.left; - attr.height = r.bottom-r.top; - attr.wclass = GDK_INPUT_OUTPUT; - attr.window_type = GDK_WINDOW_TOPLEVEL; - hwnd->m_oswindow = gdk_window_new(owner ? owner->m_oswindow : NULL,&attr,GDK_WA_X|GDK_WA_Y); - - if (hwnd->m_oswindow) - { - gdk_window_set_user_data(hwnd->m_oswindow,hwnd); - gdk_window_move_resize(hwnd->m_oswindow,r.left,r.top,r.right-r.left,r.bottom-r.top); - if (!wantfocus) gdk_window_set_focus_on_map(hwnd->m_oswindow,false); - HWND DialogBoxIsActive(); - if (!(hwnd->m_style & WS_CAPTION)) - { - gdk_window_set_override_redirect(hwnd->m_oswindow,true); - } - else if (/*hwnd == DialogBoxIsActive() || */ !(hwnd->m_style&WS_THICKFRAME)) - gdk_window_set_type_hint(hwnd->m_oswindow,GDK_WINDOW_TYPE_HINT_DIALOG); // this is a better default behavior - - gdk_window_show(hwnd->m_oswindow); - } - } - } - } - if (wantVis) swell_setOSwindowtext(hwnd); - -// if (wantVis && isVis && wantfocus && hwnd && hwnd->m_oswindow) gdk_window_raise(hwnd->m_oswindow); -} - -void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect) -{ -#ifdef SWELL_LICE_GDI - if (hwnd && hwnd->m_backingstore && hwnd->m_oswindow) - { - LICE_SubBitmap tmpbm(hwnd->m_backingstore,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top); - cairo_t * crc = gdk_cairo_create (hwnd->m_oswindow); - cairo_surface_t *temp_surface = cairo_image_surface_create_for_data((guchar*)tmpbm.getBits(), CAIRO_FORMAT_RGB24, tmpbm.getWidth(),tmpbm.getHeight(), tmpbm.getRowSpan()*4); - cairo_set_source_surface(crc, temp_surface, rect->left, rect->top); - cairo_paint(crc); - cairo_surface_destroy(temp_surface); - cairo_destroy(crc); - } -#endif -} - -static int swell_gdkConvertKey(int key) -{ - //gdk key to VK_ conversion - switch(key) - { - case GDK_KEY_Home: key = VK_HOME; break; - case GDK_KEY_End: key = VK_END; break; - case GDK_KEY_Up: key = VK_UP; break; - case GDK_KEY_Down: key = VK_DOWN; break; - case GDK_KEY_Left: key = VK_LEFT; break; - case GDK_KEY_Right: key = VK_RIGHT; break; - case GDK_KEY_Page_Up: key = VK_PRIOR; break; - case GDK_KEY_Page_Down: key = VK_NEXT; break; - case GDK_KEY_Insert: key = VK_INSERT; break; - case GDK_KEY_Delete: key = VK_DELETE; break; - case GDK_KEY_Escape: key = VK_ESCAPE; break; - } - return key; -} - -static LRESULT SendMouseMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!hwnd || !hwnd->m_wndproc) return -1; - if (!IsWindowEnabled(hwnd)) - { - HWND DialogBoxIsActive(); - HWND h = DialogBoxIsActive(); - if (h) SetForegroundWindow(h); - return -1; - } - - LRESULT htc; - if (msg != WM_MOUSEWHEEL && !GetCapture()) - { - DWORD p=GetMessagePos(); - - htc=hwnd->m_wndproc(hwnd,WM_NCHITTEST,0,p); - if (hwnd->m_hashaddestroy||!hwnd->m_wndproc) - { - return -1; // if somehow WM_NCHITTEST destroyed us, bail - } - - if (htc!=HTCLIENT) - { - if (msg==WM_MOUSEMOVE) return hwnd->m_wndproc(hwnd,WM_NCMOUSEMOVE,htc,p); - if (msg==WM_LBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONUP,htc,p); - if (msg==WM_LBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONDOWN,htc,p); - if (msg==WM_LBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONDBLCLK,htc,p); - if (msg==WM_RBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONUP,htc,p); - if (msg==WM_RBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONDOWN,htc,p); - if (msg==WM_RBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONDBLCLK,htc,p); - if (msg==WM_MBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONUP,htc,p); - if (msg==WM_MBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONDOWN,htc,p); - if (msg==WM_MBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONDBLCLK,htc,p); - } - } - - - LRESULT ret=hwnd->m_wndproc(hwnd,msg,wParam,lParam); - - if (msg==WM_LBUTTONUP || msg==WM_RBUTTONUP || msg==WM_MOUSEMOVE || msg==WM_MBUTTONUP) - { - if (!GetCapture() && (hwnd->m_hashaddestroy || !hwnd->m_wndproc || !hwnd->m_wndproc(hwnd,WM_SETCURSOR,(WPARAM)hwnd,htc | (msg<<16)))) - { - // todo: set default cursor - } - } - - return ret; -} - -static void swell_gdkEventHandler(GdkEvent *evt, gpointer data) -{ - { - HWND hwnd = NULL; - if (((GdkEventAny*)evt)->window) gdk_window_get_user_data(((GdkEventAny*)evt)->window,(gpointer*)&hwnd); - - if (hwnd) // validate window (todo later have a window class that we check) - { - HWND a = SWELL_topwindows; - while (a && a != hwnd) a=a->m_next; - if (!a) hwnd=NULL; - } - - if (evt->type == GDK_FOCUS_CHANGE) - { - GdkEventFocus *fc = (GdkEventFocus *)evt; - if (fc->in) SWELL_g_focus_oswindow = hwnd ? fc->window : NULL; - } - - if (hwnd) switch (evt->type) - { - case GDK_DELETE: - if (IsWindowEnabled(hwnd) && !SendMessage(hwnd,WM_CLOSE,0,0)) - SendMessage(hwnd,WM_COMMAND,IDCANCEL,0); - break; - case GDK_EXPOSE: // paint! GdkEventExpose... - { - GdkEventExpose *exp = (GdkEventExpose*)evt; -#ifdef SWELL_LICE_GDI - // super slow - RECT r,cr; - - // don't use GetClientRect(),since we're getting it pre-NCCALCSIZE etc - - cr.right = gdk_window_get_width(hwnd->m_oswindow); - cr.bottom = gdk_window_get_height(hwnd->m_oswindow); - cr.left=cr.top=0; - - r.left = exp->area.x; - r.top=exp->area.y; - r.bottom=r.top+exp->area.height; - r.right=r.left+exp->area.width; - if (!hwnd->m_backingstore) - hwnd->m_backingstore = new LICE_MemBitmap; - - bool forceref = hwnd->m_backingstore->resize(cr.right-cr.left,cr.bottom-cr.top); - if (forceref) r = cr; - - LICE_SubBitmap tmpbm(hwnd->m_backingstore,r.left,r.top,r.right-r.left,r.bottom-r.top); - - if (tmpbm.getWidth()>0 && tmpbm.getHeight()>0) - { - void SWELL_internalLICEpaint(HWND hwnd, LICE_IBitmap *bmout, int bmout_xpos, int bmout_ypos, bool forceref); - SWELL_internalLICEpaint(hwnd, &tmpbm, r.left, r.top, forceref); - cairo_t *crc = gdk_cairo_create (exp->window); - cairo_surface_t *temp_surface = cairo_image_surface_create_for_data((guchar*)tmpbm.getBits(), CAIRO_FORMAT_RGB24, tmpbm.getWidth(),tmpbm.getHeight(), tmpbm.getRowSpan()*4); -// cairo_surface_t *sub_surface = cairo_surface_create_for_rectangle(hwnd->m_backingstore, 0, 0, cr.right, cr.bottom); - cairo_set_source_surface(crc, temp_surface, r.left, r.top); - cairo_paint(crc); - cairo_surface_destroy(temp_surface); - cairo_destroy(crc); - } -#endif - } - break; - case GDK_CONFIGURE: // size/move, GdkEventConfigure - { - GdkEventConfigure *cfg = (GdkEventConfigure*)evt; - int flag=0; - if (cfg->x != hwnd->m_position.left || cfg->y != hwnd->m_position.top) flag|=1; - if (cfg->width != hwnd->m_position.right-hwnd->m_position.left || cfg->height != hwnd->m_position.bottom - hwnd->m_position.top) flag|=2; - hwnd->m_position.left = cfg->x; - hwnd->m_position.top = cfg->y; - hwnd->m_position.right = cfg->x + cfg->width; - hwnd->m_position.bottom = cfg->y + cfg->height; - if (flag&1) SendMessage(hwnd,WM_MOVE,0,0); - if (flag&2) SendMessage(hwnd,WM_SIZE,0,0); - } - break; - case GDK_WINDOW_STATE: /// GdkEventWindowState for min/max - printf("minmax\n"); - break; - case GDK_GRAB_BROKEN: - { - GdkEventGrabBroken *bk = (GdkEventGrabBroken*)evt; - if (s_captured_window) - { - SendMessage(s_captured_window,WM_CAPTURECHANGED,0,0); - s_captured_window=0; - } - } - break; - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - { // todo: pass through app-specific default processing before sending to child window - GdkEventKey *k = (GdkEventKey *)evt; - //printf("key%s: %d %s\n", evt->type == GDK_KEY_PRESS ? "down" : "up", k->keyval, k->string); - int modifiers = FVIRTKEY; - if (k->state&GDK_SHIFT_MASK) modifiers|=FSHIFT; - if (k->state&GDK_CONTROL_MASK) modifiers|=FCONTROL; - if (k->state&GDK_MOD1_MASK) modifiers|=FALT; - - int kv = swell_gdkConvertKey(k->keyval); - kv=toupper(kv); - - HWND foc = GetFocus(); - if (foc && IsChild(hwnd,foc)) hwnd=foc; - MSG msg = { hwnd, evt->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP, kv, modifiers, }; - if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE,(INT_PTR)&msg,0)<=0) - SendMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam); - } - break; - case GDK_MOTION_NOTIFY: - { - GdkEventMotion *m = (GdkEventMotion *)evt; - s_lastMessagePos = MAKELONG(((int)m->x_root&0xffff),((int)m->y_root&0xffff)); -// printf("motion %d %d %d %d\n", (int)m->x, (int)m->y, (int)m->x_root, (int)m->y_root); - POINT p={m->x, m->y}; - HWND hwnd2 = GetCapture(); - if (!hwnd2) hwnd2=ChildWindowFromPoint(hwnd, p); -//char buf[1024]; -//GetWindowText(hwnd2,buf,sizeof(buf)); - // printf("%x %s\n", hwnd2,buf); - POINT p2={m->x_root, m->y_root}; - ScreenToClient(hwnd2, &p2); - //printf("%d %d\n", p2.x, p2.y); - if (hwnd2) hwnd2->Retain(); - SendMouseMessage(hwnd2, WM_MOUSEMOVE, 0, MAKELPARAM(p2.x, p2.y)); - if (hwnd2) hwnd2->Release(); - gdk_event_request_motions(m); - } - break; - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - { - GdkEventButton *b = (GdkEventButton *)evt; - s_lastMessagePos = MAKELONG(((int)b->x_root&0xffff),((int)b->y_root&0xffff)); -// printf("button %d %d %d %d %d\n", evt->type, (int)b->x, (int)b->y, (int)b->x_root, (int)b->y_root); - POINT p={b->x, b->y}; - HWND hwnd2 = GetCapture(); - if (!hwnd2) hwnd2=ChildWindowFromPoint(hwnd, p); -// printf("%x\n", hwnd2); - POINT p2={b->x_root, b->y_root}; - ScreenToClient(hwnd2, &p2); - //printf("%d %d\n", p2.x, p2.y); - int msg=WM_LBUTTONDOWN; - if (b->button==2) msg=WM_MBUTTONDOWN; - else if (b->button==3) msg=WM_RBUTTONDOWN; - - if (hwnd && hwnd->m_oswindow && - SWELL_g_focus_oswindow != hwnd->m_oswindow) - SWELL_g_focus_oswindow = hwnd->m_oswindow; - - if(evt->type == GDK_BUTTON_RELEASE) msg++; // move from down to up - else if(evt->type == GDK_2BUTTON_PRESS) msg+=2; // move from down to up - if (hwnd2) hwnd2->Retain(); - SendMouseMessage(hwnd2, msg, 0, MAKELPARAM(p2.x, p2.y)); - if (hwnd2) hwnd2->Release(); - } - break; - default: - //printf("msg: %d\n",evt->type); - break; - } - - } -} - -void swell_runOSevents() -{ - if (SWELL_gdk_active>0) - { -// static GMainLoop *loop; -// if (!loop) loop = g_main_loop_new(NULL,TRUE); - gdk_window_process_all_updates(); - - GdkEvent *evt; - while (gdk_events_pending() && (evt = gdk_event_get())) - { - swell_gdkEventHandler(evt,(gpointer)1); - gdk_event_free(evt); - } - } -} - -#else -void SWELL_initargs(int *argc, char ***argv) -{ -} -void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect) -{ -} -#define swell_initwindowsys() (0) -#define swell_destroyOSwindow(x) -#define swell_manageOSwindow(x,y) -#define swell_runOSevents() -#define swell_setOSwindowtext(x) { if (x) printf("SWELL: swt '%s'\n",(x)->m_title ? (x)->m_title : ""); } -#endif - -HWND__::HWND__(HWND par, int wID, RECT *wndr, const char *label, bool visible, WNDPROC wndproc, DLGPROC dlgproc) -{ - m_refcnt=1; - m_private_data=0; - - m_classname = "unknown"; - m_wndproc=wndproc?wndproc:dlgproc?(WNDPROC)SwellDialogDefaultWindowProc:(WNDPROC)DefWindowProc; - m_dlgproc=dlgproc; - m_userdata=0; - m_style=0; - m_exstyle=0; - m_id=wID; - m_owned=m_owner=0; - m_children=m_parent=m_next=m_prev=0; - if (wndr) m_position = *wndr; - else memset(&m_position,0,sizeof(m_position)); - memset(&m_extra,0,sizeof(m_extra)); - m_visible=visible; - m_hashaddestroy=false; - m_enabled=true; - m_wantfocus=true; - m_menu=NULL; -#ifdef SWELL_TARGET_GDK - m_oswindow = 0; -#endif - -#ifdef SWELL_LICE_GDI - m_paintctx=0; - m_invalidated=true; - m_child_invalidated=true; - m_backingstore=0; -#endif - - m_title=label ? strdup(label) : NULL; - SetParent(this, par); - -} - -HWND__::~HWND__() -{ -} - - - -HWND GetParent(HWND hwnd) -{ - return hwnd ? hwnd->m_parent : NULL; -} - -HWND GetDlgItem(HWND hwnd, int idx) -{ - if (!idx) return hwnd; - if (hwnd) hwnd=hwnd->m_children; - while (hwnd && hwnd->m_id != idx) hwnd=hwnd->m_next; - return hwnd; -} - - -LONG_PTR SetWindowLong(HWND hwnd, int idx, LONG_PTR val) -{ - if (!hwnd) return 0; - if (idx==GWL_STYLE) - { - // todo: special case for buttons - LONG ret = hwnd->m_style; - hwnd->m_style=val; - return ret; - } - if (idx==GWL_EXSTYLE) - { - LONG ret = hwnd->m_exstyle; - hwnd->m_exstyle=val; - return ret; - } - if (idx==GWL_USERDATA) - { - LONG_PTR ret = hwnd->m_userdata; - hwnd->m_userdata=val; - return ret; - } - if (idx==GWL_ID) - { - LONG ret = hwnd->m_id; - hwnd->m_id=val; - return ret; - } - - if (idx==GWL_WNDPROC) - { - LONG_PTR ret = (LONG_PTR)hwnd->m_wndproc; - hwnd->m_wndproc=(WNDPROC)val; - return ret; - } - if (idx==DWL_DLGPROC) - { - LONG_PTR ret = (LONG_PTR)hwnd->m_dlgproc; - hwnd->m_dlgproc=(DLGPROC)val; - return ret; - } - - if (idx>=0 && idx < 64*(int)sizeof(INT_PTR)) - { - INT_PTR ret = hwnd->m_extra[idx/sizeof(INT_PTR)]; - hwnd->m_extra[idx/sizeof(INT_PTR)]=val; - return (LONG_PTR)ret; - } - return 0; -} - -LONG_PTR GetWindowLong(HWND hwnd, int idx) -{ - if (!hwnd) return 0; - if (idx==GWL_STYLE) - { - // todo: special case for buttons - return hwnd->m_style; - } - if (idx==GWL_EXSTYLE) - { - return hwnd->m_exstyle; - } - if (idx==GWL_USERDATA) - { - return hwnd->m_userdata; - } - if (idx==GWL_ID) - { - return hwnd->m_id; - } - - if (idx==GWL_WNDPROC) - { - return (LONG_PTR)hwnd->m_wndproc; - } - if (idx==DWL_DLGPROC) - { - return (LONG_PTR)hwnd->m_dlgproc; - } - - if (idx>=0 && idx < 64*(int)sizeof(INT_PTR)) - { - return (LONG_PTR)hwnd->m_extra[idx/sizeof(INT_PTR)]; - } - return 0; -} - - -bool IsWindow(HWND hwnd) -{ - // todo: verify window is valid (somehow) - return !!hwnd; -} - -bool IsWindowVisible(HWND hwnd) -{ - if (!hwnd) return false; - while (hwnd->m_visible) - { - hwnd = hwnd->m_parent; - if (!hwnd) return true; - } - return false; -} - -LRESULT SendMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!hwnd) return 0; - WNDPROC wp = hwnd->m_wndproc; - - if (msg == WM_DESTROY) - { - if (hwnd->m_hashaddestroy) return 0;// todo: allow certain messages to pass? - hwnd->m_hashaddestroy=true; - if (GetCapture()==hwnd) ReleaseCapture(); - SWELL_MessageQueue_Clear(hwnd); - } - else if (msg==WM_CAPTURECHANGED && hwnd->m_hashaddestroy) return 0; - - int ret = wp ? wp(hwnd,msg,wParam,lParam) : 0; - - if (msg == WM_DESTROY) - { - if (GetCapture()==hwnd) ReleaseCapture(); - - SWELL_MessageQueue_Clear(hwnd); - // send WM_DESTROY to all children - HWND tmp=hwnd->m_children; - while (tmp) - { - SendMessage(tmp,WM_DESTROY,0,0); - tmp=tmp->m_next; - } - tmp=hwnd->m_owned; - while (tmp) - { - SendMessage(tmp,WM_DESTROY,0,0); - tmp=tmp->m_next; - } - KillTimer(hwnd,-1); - if (SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd=0; - } - return ret; -} - -static void swell_removeWindowFromNonChildren(HWND__ *hwnd) -{ - if (hwnd->m_next) hwnd->m_next->m_prev = hwnd->m_prev; - if (hwnd->m_prev) hwnd->m_prev->m_next = hwnd->m_next; - else - { - if (hwnd->m_parent && hwnd->m_parent->m_children == hwnd) hwnd->m_parent->m_children = hwnd->m_next; - if (hwnd->m_owner && hwnd->m_owner->m_owned == hwnd) hwnd->m_owner->m_owned = hwnd->m_next; - if (hwnd == SWELL_topwindows) SWELL_topwindows = hwnd->m_next; - } -} - -static void RecurseDestroyWindow(HWND hwnd) -{ - HWND tmp=hwnd->m_children; - while (tmp) - { - HWND old = tmp; - tmp=tmp->m_next; - RecurseDestroyWindow(old); - } - tmp=hwnd->m_owned; - while (tmp) - { - HWND old = tmp; - tmp=tmp->m_next; - RecurseDestroyWindow(old); - } - - if (s_captured_window == hwnd) s_captured_window=NULL; - if (SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd=NULL; - - swell_destroyOSwindow(hwnd); - - free(hwnd->m_title); - hwnd->m_title=0; - - if (hwnd->m_menu) DestroyMenu(hwnd->m_menu); - hwnd->m_menu=0; - -#ifdef SWELL_LICE_GDI - delete hwnd->m_backingstore; - hwnd->m_backingstore=0; -#endif - - hwnd->m_wndproc=NULL; - hwnd->Release(); -} - - -void DestroyWindow(HWND hwnd) -{ - if (!hwnd) return; - if (hwnd->m_hashaddestroy) return; - - // broadcast WM_DESTROY - SendMessage(hwnd,WM_DESTROY,0,0); - - // remove from parent/global lists - swell_removeWindowFromNonChildren(hwnd); - - // safe to delete this window and all children directly - RecurseDestroyWindow(hwnd); -} - - -bool IsWindowEnabled(HWND hwnd) -{ - if (!hwnd) return false; - while (hwnd && hwnd->m_enabled) - { - hwnd=hwnd->m_parent; - } - return !hwnd; -} - -void EnableWindow(HWND hwnd, int enable) -{ - if (!hwnd) return; - hwnd->m_enabled=!!enable; -#ifdef SWELL_TARGET_GDK - if (hwnd->m_oswindow) gdk_window_set_accept_focus(hwnd->m_oswindow,!!enable); -#endif - - if (!enable && SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd = 0; -} - - -void SetFocus(HWND hwnd) -{ - if (!hwnd) return; - - SWELL_g_focuswnd = hwnd; -#ifdef SWELL_TARGET_GDK - while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; - if (hwnd) gdk_window_raise(hwnd->m_oswindow); - if (hwnd && hwnd->m_oswindow != SWELL_g_focus_oswindow) - { - gdk_window_focus(SWELL_g_focus_oswindow = hwnd->m_oswindow,GDK_CURRENT_TIME); - } -#endif -} -void SetForegroundWindow(HWND hwnd) -{ - SetFocus(hwnd); -} - - -int IsChild(HWND hwndParent, HWND hwndChild) -{ - if (!hwndParent || !hwndChild || hwndParent == hwndChild) return 0; - - while (hwndChild && hwndChild != hwndParent) hwndChild = hwndChild->m_parent; - - return hwndChild == hwndParent; -} - - -HWND GetForegroundWindowIncludeMenus() -{ -#ifdef SWELL_TARGET_GDK - if (!SWELL_g_focus_oswindow) return 0; - HWND a = SWELL_topwindows; - while (a && a->m_oswindow != SWELL_g_focus_oswindow) a=a->m_next; - return a; -#else - HWND h = SWELL_g_focuswnd; - while (h && h->m_parent) h=h->m_parent; - return h; -#endif -} - -HWND GetFocusIncludeMenus() -{ -#ifdef SWELL_TARGET_GDK - if (!SWELL_g_focus_oswindow) return 0; - HWND a = SWELL_topwindows; - while (a && a->m_oswindow != SWELL_g_focus_oswindow) a=a->m_next; - return a && IsChild(a,SWELL_g_focuswnd) ? SWELL_g_focuswnd : a; -#else - return SWELL_g_focuswnd; -#endif -} - -HWND GetForegroundWindow() -{ - HWND h =GetForegroundWindowIncludeMenus(); - HWND ho; - while (h && (ho=(HWND)GetProp(h,"SWELL_MenuOwner"))) h=ho; - return h; -} - -HWND GetFocus() -{ - HWND h =GetFocusIncludeMenus(); - HWND ho; - while (h && (ho=(HWND)GetProp(h,"SWELL_MenuOwner"))) h=ho; - return h; -} - - -void SWELL_GetViewPort(RECT *r, RECT *sourcerect, bool wantWork) -{ -#ifdef SWELL_TARGET_GDK - if (swell_initwindowsys()) - { - GdkScreen *defscr = gdk_screen_get_default(); - if (!defscr) { r->left=r->top=0; r->right=r->bottom=1024; return; } - gint idx = sourcerect ? gdk_screen_get_monitor_at_point(defscr, - (sourcerect->left+sourcerect->right)/2, - (sourcerect->top+sourcerect->bottom)/2) : 0; - GdkRectangle rc={0,0,1024,1024}; - gdk_screen_get_monitor_geometry(defscr,idx,&rc); - r->left=rc.x; r->top = rc.y; - r->right=rc.x+rc.width; - r->bottom=rc.y+rc.height; - return; - } -#endif - r->left=r->top=0; - r->right=1024; - r->bottom=768; -} - - -void ScreenToClient(HWND hwnd, POINT *p) -{ - if (!hwnd) return; - - int x=p->x,y=p->y; - - HWND tmp=hwnd, ltmp=0; - while (tmp -#ifdef SWELL_TARGET_GDK - && !tmp->m_oswindow -#endif - ) // top level window's m_position left/top should always be 0 anyway - { - RECT tr=tmp->m_position; - if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); - - x -= tr.left; - y -= tr.top; - tmp = tmp->m_parent; - } - - if (tmp) - { - RECT tr=tmp->m_position; - if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); - x -= tr.left - tmp->m_position.left; - y -= tr.top - tmp->m_position.top; - } - -#ifdef SWELL_TARGET_GDK - if (tmp && tmp->m_oswindow) - { - GdkWindow *wnd = tmp->m_oswindow; - gint px=0,py=0; - gdk_window_get_origin(wnd,&px,&py); // this is probably unreliable but ugh (use get_geometry?) - x-=px; - y-=py; - } -#endif - - p->x=x; - p->y=y; -} - -void ClientToScreen(HWND hwnd, POINT *p) -{ - if (!hwnd) return; - - int x=p->x,y=p->y; - - HWND tmp=hwnd,ltmp=0; - while (tmp -#ifdef SWELL_TARGET_GDK - && !tmp->m_oswindow -#endif - ) // top level window's m_position left/top should always be 0 anyway - { - RECT tr=tmp->m_position; - if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); - x += tr.left; - y += tr.top; - tmp = tmp->m_parent; - } - if (tmp) - { - RECT tr=tmp->m_position; - if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); - x += tr.left - tmp->m_position.left; - y += tr.top - tmp->m_position.top; - } - -#ifdef SWELL_TARGET_GDK - if (tmp && tmp->m_oswindow) - { - GdkWindow *wnd = tmp->m_oswindow; - gint px=0,py=0; - gdk_window_get_origin(wnd,&px,&py); // this is probably unreliable but ugh (use get_geometry?) - x+=px; - y+=py; - } -#endif - - p->x=x; - p->y=y; -} - -bool GetWindowRect(HWND hwnd, RECT *r) -{ - if (!hwnd) return false; -#ifdef SWELL_TARGET_GDK - if (hwnd->m_oswindow) - { - GdkRectangle rc; - gdk_window_get_frame_extents(hwnd->m_oswindow,&rc); - r->left=rc.x; - r->top=rc.y; - r->right=rc.x+rc.width; - r->bottom = rc.y+rc.height; - return true; - } -#endif - - r->left=r->top=0; - ClientToScreen(hwnd,(LPPOINT)r); - r->right = r->left + hwnd->m_position.right - hwnd->m_position.left; - r->bottom = r->top + hwnd->m_position.bottom - hwnd->m_position.top; - return true; -} - -void GetWindowContentViewRect(HWND hwnd, RECT *r) -{ -#ifdef SWELL_TARGET_GDK - if (hwnd && hwnd->m_oswindow) - { - gint w=0,h=0,px=0,py=0; - gdk_window_get_position(hwnd->m_oswindow,&px,&py); - w = gdk_window_get_width(hwnd->m_oswindow); - h = gdk_window_get_height(hwnd->m_oswindow); - r->left=px; - r->top=py; - r->right = px+w; - r->bottom = py+h; - return; - } -#endif - GetWindowRect(hwnd,r); -} - -void GetClientRect(HWND hwnd, RECT *r) -{ - r->left=r->top=r->right=r->bottom=0; - if (!hwnd) return; - -#ifdef SWELL_TARGET_GDK - if (hwnd->m_oswindow) - { - r->right = gdk_window_get_width(hwnd->m_oswindow); - r->bottom = gdk_window_get_height(hwnd->m_oswindow); - - } - else -#endif - { - r->right = hwnd->m_position.right - hwnd->m_position.left; - r->bottom = hwnd->m_position.bottom - hwnd->m_position.top; - } - - RECT tr=*r; - SendMessage(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&tr); - r->right = r->left + (tr.right-tr.left); - r->bottom=r->top + (tr.bottom-tr.top); -} - - - -void SetWindowPos(HWND hwnd, HWND zorder, int x, int y, int cx, int cy, int flags) -{ - if (!hwnd) return; - // todo: handle SWP_SHOWWINDOW - RECT f = hwnd->m_position; - int reposflag = 0; - if (!(flags&SWP_NOZORDER)) - { - if (hwnd->m_parent && zorder != hwnd) - { - HWND tmp = hwnd->m_parent->m_children; - while (tmp && tmp != hwnd) tmp=tmp->m_next; - if (tmp) // we are in the list, so we can do a reorder - { - // take hwnd out of list - if (hwnd->m_prev) hwnd->m_prev->m_next = hwnd->m_next; - else hwnd->m_parent->m_children = hwnd->m_next; - if (hwnd->m_next) hwnd->m_next->m_prev = hwnd->m_prev; - hwnd->m_next=hwnd->m_prev=NULL;// leave hwnd->m_parent valid since it wont change - - // add back in - tmp = hwnd->m_parent->m_children; - if (zorder == HWND_TOP || !tmp || tmp == zorder) // no children, topmost, or zorder is at top already - { - if (tmp) tmp->m_prev=hwnd; - hwnd->m_next = tmp; - hwnd->m_parent->m_children = hwnd; - } - else if (zorder == HWND_BOTTOM) - { - while (tmp && tmp->m_next) tmp=tmp->m_next; - tmp->m_next=hwnd; - hwnd->m_prev=tmp; - } - else - { - HWND ltmp=NULL; - while (tmp && tmp != zorder) tmp=(ltmp=tmp)->m_next; - - hwnd->m_next = ltmp->m_next; - hwnd->m_prev = ltmp; - if (ltmp->m_next) ltmp->m_next->m_prev = hwnd; - ltmp->m_next = hwnd; - } - reposflag|=4; - } - } - } - if (!(flags&SWP_NOMOVE)) - { - int oldw = f.right-f.left; - int oldh = f.bottom-f.top; - f.left=x; - f.right=x+oldw; - f.top=y; - f.bottom=y+oldh; - reposflag|=1; - } - if (!(flags&SWP_NOSIZE)) - { - f.right = f.left + cx; - f.bottom = f.top + cy; - reposflag|=2; - } - if (reposflag) - { -#ifdef SWELL_TARGET_GDK - if (hwnd->m_oswindow) - { - //printf("repos %d,%d,%d,%d, %d\n",f.left,f.top,f.right,f.bottom,reposflag); - if ((reposflag&3)==3) gdk_window_move_resize(hwnd->m_oswindow,f.left,f.top,f.right-f.left,f.bottom-f.top); - else if (reposflag&2) gdk_window_resize(hwnd->m_oswindow,f.right-f.left,f.bottom-f.top); - else if (reposflag&1) gdk_window_move(hwnd->m_oswindow,f.left,f.top); - } - else // top level windows above get their position from gdk and cache it in m_position -#endif - { - if (reposflag&3) - { - hwnd->m_position = f; - SendMessage(hwnd,WM_SIZE,0,0); - } - InvalidateRect(hwnd->m_parent ? hwnd->m_parent : hwnd,NULL,FALSE); - } - } - -} - - - -HWND GetWindow(HWND hwnd, int what) -{ - if (!hwnd) return 0; - - if (what == GW_CHILD) return hwnd->m_children; - if (what == GW_OWNER) return hwnd->m_owner; - if (what == GW_HWNDNEXT) return hwnd->m_next; - if (what == GW_HWNDPREV) return hwnd->m_prev; - if (what == GW_HWNDFIRST) - { - while (hwnd->m_prev) hwnd = hwnd->m_prev; - return hwnd; - } - if (what == GW_HWNDLAST) - { - while (hwnd->m_next) hwnd = hwnd->m_next; - return hwnd; - } - return 0; -} - -HWND SetParent(HWND hwnd, HWND newPar) -{ - if (!hwnd) return NULL; - - swell_removeWindowFromNonChildren(hwnd); - - HWND oldPar = hwnd->m_parent; - hwnd->m_prev=0; - hwnd->m_next=0; - hwnd->m_parent = NULL; - hwnd->m_owner = NULL; // todo - - if (newPar) - { - hwnd->m_parent = newPar; - hwnd->m_next=newPar->m_children; - if (hwnd->m_next) hwnd->m_next->m_prev = hwnd; - newPar->m_children=hwnd; - } - else // add to top level windows - { - hwnd->m_next=SWELL_topwindows; - if (hwnd->m_next) hwnd->m_next->m_prev = hwnd; - SWELL_topwindows = hwnd; - } - - swell_manageOSwindow(hwnd,false); - return oldPar; -} - - - - -// timer stuff -typedef struct TimerInfoRec -{ - UINT_PTR timerid; - HWND hwnd; - UINT interval; - DWORD nextFire; - TIMERPROC tProc; - struct TimerInfoRec *_next; -} TimerInfoRec; - -static TimerInfoRec *m_timer_list; -static WDL_Mutex m_timermutex; -static pthread_t m_pmq_mainthread; - -void SWELL_RunMessageLoop() -{ - SWELL_MessageQueue_Flush(); - swell_runOSevents(); - - DWORD now = GetTickCount(); - WDL_MutexLock lock(&m_timermutex); - int x; - TimerInfoRec *rec = m_timer_list; - while (rec) - { - if (now > rec->nextFire || now < rec->nextFire - rec->interval*4) - { - rec->nextFire = now + rec->interval; - - HWND h = rec->hwnd; - TIMERPROC tProc = rec->tProc; - UINT_PTR tid = rec->timerid; - m_timermutex.Leave(); - - if (tProc) tProc(h,WM_TIMER,tid,now); - else if (h) SendMessage(h,WM_TIMER,tid,0); - - m_timermutex.Enter(); - TimerInfoRec *tr = m_timer_list; - while (tr && tr != rec) tr=tr->_next; - if (!tr) - { - rec = m_timer_list; // if no longer in the list, then abort - continue; - } - } - rec=rec->_next; - } -} - - -UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) -{ - if (!hwnd && !tProc) return 0; // must have either callback or hwnd - - if (hwnd && !timerid) return 0; - - WDL_MutexLock lock(&m_timermutex); - TimerInfoRec *rec=NULL; - if (hwnd||timerid) - { - rec = m_timer_list; - while (rec) - { - if (rec->timerid == timerid && rec->hwnd == hwnd) // works for both kinds - break; - rec=rec->_next; - } - } - - bool recAdd=false; - if (!rec) - { - rec=(TimerInfoRec*)malloc(sizeof(TimerInfoRec)); - recAdd=true; - } - - rec->tProc = tProc; - rec->timerid=timerid; - rec->hwnd=hwnd; - rec->interval = rate<1?1: rate; - rec->nextFire = GetTickCount() + rate; - - if (!hwnd) timerid = rec->timerid = (UINT_PTR)rec; - - if (recAdd) - { - rec->_next=m_timer_list; - m_timer_list=rec; - } - - return timerid; -} - -BOOL KillTimer(HWND hwnd, UINT_PTR timerid) -{ - if (!hwnd && !timerid) return FALSE; - - WDL_MutexLock lock(&m_timermutex); - BOOL rv=FALSE; - - // don't allow removing all global timers - if (timerid!=-1 || hwnd) - { - TimerInfoRec *rec = m_timer_list, *lrec=NULL; - while (rec) - { - if (rec->hwnd == hwnd && (timerid==-1 || rec->timerid == timerid)) - { - TimerInfoRec *nrec = rec->_next; - - // remove self from list - if (lrec) lrec->_next = nrec; - else m_timer_list = nrec; - - free(rec); - - rv=TRUE; - if (timerid!=-1) break; - - rec=nrec; - } - else - { - lrec=rec; - rec=rec->_next; - } - } - } - return rv; -} - -BOOL SetDlgItemText(HWND hwnd, int idx, const char *text) -{ - hwnd =(idx ? GetDlgItem(hwnd,idx) : hwnd); - if (!hwnd) return false; - - if (!text) text=""; - - - if (strcmp(hwnd->m_title ? hwnd->m_title : "", text)) - { - if (*text && hwnd->m_title && strlen(hwnd->m_title)>=strlen(text)) strcpy(hwnd->m_title,text); - else - { - free(hwnd->m_title); - hwnd->m_title = text[0] ? strdup(text) : NULL; - } - SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)text); - swell_setOSwindowtext(hwnd); - } - return true; -} - -BOOL GetDlgItemText(HWND hwnd, int idx, char *text, int textlen) -{ - *text=0; - hwnd = idx?GetDlgItem(hwnd,idx) : hwnd; - if (!hwnd) return false; - - // todo: sendmessage WM_GETTEXT etc? special casing for combo boxes etc - lstrcpyn(text,hwnd->m_title ? hwnd->m_title : "", textlen); - return true; -} - -void CheckDlgButton(HWND hwnd, int idx, int check) -{ - hwnd = GetDlgItem(hwnd,idx); - if (!hwnd) return; - SendMessage(hwnd,BM_SETCHECK,check,0); -} - - -int IsDlgButtonChecked(HWND hwnd, int idx) -{ - hwnd = GetDlgItem(hwnd,idx); - if (!hwnd) return 0; - return SendMessage(hwnd,BM_GETCHECK,0,0); -} - - -BOOL SetDlgItemInt(HWND hwnd, int idx, int val, int issigned) -{ - char buf[128]; - sprintf(buf,issigned?"%d":"%u",val); - return SetDlgItemText(hwnd,idx,buf); -} - -int GetDlgItemInt(HWND hwnd, int idx, BOOL *translated, int issigned) -{ - char buf[128]; - if (!GetDlgItemText(hwnd,idx,buf,sizeof(buf))) - { - if (translated) *translated=0; - return 0; - } - char *p=buf; - while (*p == ' ' || *p == '\t') p++; - int a=atoi(p); - if ((a<0 && !issigned) || (!a && p[0] != '0')) { if (translated) *translated=0; return 0; } - if (translated) *translated=1; - return a; -} - -void ShowWindow(HWND hwnd, int cmd) -{ - if (!hwnd) return; - - if (cmd==SW_SHOW||cmd==SW_SHOWNA) - { - hwnd->m_visible=true; - } - else if (cmd==SW_HIDE) hwnd->m_visible=false; - - swell_manageOSwindow(hwnd,cmd==SW_SHOW); - InvalidateRect(hwnd,NULL,FALSE); - -} - -void *SWELL_ModalWindowStart(HWND hwnd) -{ - return 0; -} - -bool SWELL_ModalWindowRun(void *ctx, int *ret) // returns false and puts retval in *ret when done -{ - return false; -} - -void SWELL_ModalWindowEnd(void *ctx) -{ - if (ctx) - { - } -} - -void SWELL_CloseWindow(HWND hwnd) -{ - DestroyWindow(hwnd); -} - - -#include "swell-dlggen.h" - -static HWND m_make_owner; -static RECT m_transform; -static bool m_doautoright; -static RECT m_lastdoauto; -static bool m_sizetofits; - -#define ACTIONTARGET (m_make_owner) - -void SWELL_MakeSetCurParms(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit) -{ - m_sizetofits=dosizetofit; - m_lastdoauto.left = 0; - m_lastdoauto.top = -100<<16; - m_lastdoauto.right = 0; - m_doautoright=doauto; - m_transform.left=(int)(xtrans*65536.0); - m_transform.top=(int)(ytrans*65536.0); - m_transform.right=(int)(xscale*65536.0); - m_transform.bottom=(int)(yscale*65536.0); - m_make_owner=parent; -} - -static void UpdateAutoCoords(RECT r) -{ - m_lastdoauto.right=r.left + r.right - m_lastdoauto.left; -} - - -static RECT MakeCoords(int x, int y, int w, int h, bool wantauto) -{ - if (w<0&&h<0) - { - RECT r = { -x, -y, -x-w, -y-h}; - return r; - } - - float ysc=m_transform.bottom/65536.0; - int newx=(int)((x+m_transform.left/65536.0)*m_transform.right/65536.0 + 0.5); - int newy=(int)(((((double)y+(double)m_transform.top/65536.0) )*ysc) + 0.5); - - RECT ret= { newx, - newy, - (int) (newx + w*(double)m_transform.right/65536.0+0.5), - (int) (newy + h*fabs(ysc)+0.5) - }; - - - RECT oret=ret; - if (wantauto && m_doautoright) - { - float dx = ret.left - m_lastdoauto.left; - if (fabs(dx)<32 && m_lastdoauto.top >= ret.top && m_lastdoauto.top < ret.bottom) - { - ret.left += (int) m_lastdoauto.right; - } - - m_lastdoauto.left = oret.right; - m_lastdoauto.top = (ret.top + ret.bottom)*0.5; - m_lastdoauto.right=0; - } - return ret; -} - -static const double minwidfontadjust=1.81; -#define TRANSFORMFONTSIZE ((m_transform.right/65536.0+1.0)*3.7) - - -#ifdef SWELL_LICE_GDI -//#define SWELL_ENABLE_VIRTWND_CONTROLS -#include "../wingui/virtwnd-controls.h" -#endif - -static LRESULT WINAPI virtwndWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ -#ifdef SWELL_ENABLE_VIRTWND_CONTROLS - WDL_VWnd *vwnd = (WDL_VWnd *) ( msg == WM_CREATE ? (void*)lParam : GetProp(hwnd,"WDL_control_vwnd") ); - if (vwnd) switch (msg) - { - case WM_CREATE: - { - SetProp(hwnd,"WDL_control_vwnd",vwnd); - RECT r; - GetClientRect(hwnd,&r); - vwnd->SetRealParent(hwnd); - vwnd->SetPosition(&r); - vwnd->SetID(0xf); - } - return 0; - case WM_SIZE: - { - RECT r; - GetClientRect(hwnd,&r); - vwnd->SetPosition(&r); - InvalidateRect(hwnd,NULL,FALSE); - } - break; - case WM_COMMAND: - if (LOWORD(wParam)==0xf) SendMessage(GetParent(hwnd),WM_COMMAND,(wParam&0xffff0000) | GetWindowLong(hwnd,GWL_ID),NULL); - break; - case WM_DESTROY: - RemoveProp(hwnd,"WDL_control_vwnd"); - delete vwnd; - vwnd=0; - return 0; - case WM_LBUTTONDOWN: - SetCapture(hwnd); - vwnd->OnMouseDown(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); - return 0; - case WM_MOUSEMOVE: - vwnd->OnMouseMove(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); - return 0; - case WM_LBUTTONUP: - ReleaseCapture(); - vwnd->OnMouseUp(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); - return 0; - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - - HDC hdc = ps.hdc; - if (hdc) - { - RECT tr = ps.rcPaint; // todo: offset by surface_offs.x/y - vwnd->OnPaint(hdc->surface,hdc->surface_offs.x,hdc->surface_offs.y,&tr); - vwnd->OnPaintOver(hdc->surface,hdc->surface_offs.x,hdc->surface_offs.y,&tr); - } - - EndPaint(hwnd,&ps); - } - } - return 0; - case WM_SETTEXT: - if (lParam) - { - if (!strcmp(vwnd->GetType(),"vwnd_iconbutton")) - { - WDL_VirtualIconButton *b = (WDL_VirtualIconButton *) vwnd; - b->SetTextLabel((const char *)lParam); - } - } - break; - case BM_SETCHECK: - case BM_GETCHECK: - if (!strcmp(vwnd->GetType(),"vwnd_iconbutton")) - { - WDL_VirtualIconButton *b = (WDL_VirtualIconButton *) vwnd; - if (msg == BM_GETCHECK) return b->GetCheckState(); - - b->SetCheckState(wParam); - } - return 0; - } -#endif - return DefWindowProc(hwnd,msg,wParam,lParam); -} - -#ifdef SWELL_ENABLE_VIRTWND_CONTROLS -static HWND swell_makeButton(HWND owner, int idx, RECT *tr, const char *label, bool vis, int style) -{ - WDL_VirtualIconButton *vwnd = new WDL_VirtualIconButton; - if (label) vwnd->SetTextLabel(label); - vwnd->SetForceBorder(true); - if (style & BS_AUTOCHECKBOX) vwnd->SetCheckState(0); - HWND hwnd = new HWND__(owner,idx,tr,label,vis,virtwndWindowProc); - hwnd->m_classname = "Button"; - hwnd->m_style = style|WS_CHILD; - hwnd->m_wndproc(hwnd,WM_CREATE,0,(LPARAM)vwnd); - return hwnd; -} - -#endif - - -#ifndef SWELL_ENABLE_VIRTWND_CONTROLS -static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_LBUTTONDOWN: - SetCapture(hwnd); - SendMessage(hwnd,WM_USER+100,0,0); // invalidate - return 0; - case WM_MOUSEMOVE: - return 0; - case WM_LBUTTONUP: - if (GetCapture()==hwnd) - { - ReleaseCapture(); // WM_CAPTURECHANGED will take care of the invalidate - RECT r; - GetClientRect(hwnd,&r); - POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; - if (PtInRect(&r,p) && hwnd->m_id && hwnd->m_parent) - { - int sf = (hwnd->m_style & 0xf); - if (sf == BS_AUTO3STATE) - { - int a = hwnd->m_private_data&3; - if (a==0) a=1; - else if (a==1) a=2; - else a=0; - hwnd->m_private_data = (a) | (hwnd->m_private_data&~3); - } - else if (sf == BS_AUTOCHECKBOX) - { - hwnd->m_private_data = (!(hwnd->m_private_data&3)) | (hwnd->m_private_data&~3); - } - else if (sf == BS_AUTORADIOBUTTON) - { - // todo: uncheck other nearby radios - } - SendMessage(hwnd->m_parent,WM_COMMAND,MAKEWPARAM(hwnd->m_id,BN_CLICKED),(LPARAM)hwnd); - } - } - return 0; - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - bool pressed = GetCapture()==hwnd; - - SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); - SetBkMode(ps.hdc,TRANSPARENT); - - int f=DT_VCENTER; - int sf = (hwnd->m_style & 0xf); - if (sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON) - { - const int chksz = 16; - RECT tr={r.left,(r.top+r.bottom)/2-chksz/2,r.left+chksz}; - tr.bottom = tr.top+chksz; - - HPEN pen=CreatePen(PS_SOLID,0,RGB(0,0,0)); - HGDIOBJ oldPen = SelectObject(ps.hdc,pen); - if (sf == BS_AUTOCHECKBOX || sf == BS_AUTO3STATE) - { - int st = (int)(hwnd->m_private_data&3); - if (st==3||(st==2 && (hwnd->m_style & 0xf) == BS_AUTOCHECKBOX)) st=1; - - HBRUSH br = CreateSolidBrush(st==2?RGB(192,192,192):RGB(255,255,255)); - FillRect(ps.hdc,&tr,br); - DeleteObject(br); - - if (st == 1||pressed) - { - RECT ar=tr; - ar.left+=2; - ar.right-=3; - ar.top+=2; - ar.bottom-=3; - if (pressed) - { - const int rsz=chksz/4; - ar.left+=rsz; - ar.top+=rsz; - ar.right-=rsz; - ar.bottom-=rsz; - } - MoveToEx(ps.hdc,ar.left,ar.top,NULL); - LineTo(ps.hdc,ar.right,ar.bottom); - MoveToEx(ps.hdc,ar.right,ar.top,NULL); - LineTo(ps.hdc,ar.left,ar.bottom); - } - } - else if (sf == BS_AUTORADIOBUTTON) - { - // todo radio circle - } - SelectObject(ps.hdc,oldPen); - DeleteObject(pen); - r.left += chksz + 4; - } - else - { - - HBRUSH br = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - FillRect(ps.hdc,&r,br); - DeleteObject(br); - - HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(pressed?COLOR_3DHILIGHT : COLOR_3DSHADOW)); - HPEN pen = CreatePen(PS_SOLID,0,GetSysColor((!pressed)?COLOR_3DHILIGHT : COLOR_3DSHADOW)); - HGDIOBJ oldpen = SelectObject(ps.hdc,pen); - MoveToEx(ps.hdc,r.left,r.bottom-1,NULL); - LineTo(ps.hdc,r.left,r.top); - LineTo(ps.hdc,r.right-1,r.top); - SelectObject(ps.hdc,pen2); - LineTo(ps.hdc,r.right-1,r.bottom-1); - LineTo(ps.hdc,r.left,r.bottom-1); - SelectObject(ps.hdc,oldpen); - DeleteObject(pen); - DeleteObject(pen2); - f|=DT_CENTER; - if (pressed) - { - r.left+=2; - r.top+=2; - } - } - - - char buf[512]; - buf[0]=0; - GetWindowText(hwnd,buf,sizeof(buf)); - if (buf[0]) DrawText(ps.hdc,buf,-1,&r,f); - - - EndPaint(hwnd,&ps); - } - } - return 0; - case BM_GETCHECK: - if (hwnd) - { - return (hwnd->m_private_data&3)==2 ? 1 : (hwnd->m_private_data&3); - } - return 0; - case BM_SETCHECK: - if (hwnd) - { - int check = (int)wParam; - INT_PTR op = hwnd->m_private_data; - hwnd->m_private_data=(check > 2 || check<0 ? 1 : (check&3)) | (hwnd->m_private_data&~3); - if (hwnd->m_private_data == op) break; - } - else - { - break; - } - // fall through (invalidating) - case WM_USER+100: - case WM_CAPTURECHANGED: - case WM_SETTEXT: - { - int sf = (hwnd->m_style & 0xf); - if (sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON) - { - InvalidateRect(hwnd,NULL,TRUE); - } - else InvalidateRect(hwnd,NULL,FALSE); - } - break; - } - return DefWindowProc(hwnd,msg,wParam,lParam); -} - -static HWND swell_makeButton(HWND owner, int idx, RECT *tr, const char *label, bool vis, int style) -{ - HWND hwnd = new HWND__(owner,idx,tr,label,vis,buttonWindowProc); - hwnd->m_classname = "Button"; - hwnd->m_style = style|WS_CHILD; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - return hwnd; -} -#endif - -static LRESULT WINAPI groupWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - int col = GetSysColor(COLOR_BTNTEXT); - - const char *buf = hwnd->m_title; - int th=20; - int tw=0; - int xp=0; - if (buf && buf[0]) - { - RECT tr={0,}; - DrawText(ps.hdc,buf,-1,&tr,DT_CALCRECT); - th=tr.bottom-tr.top; - tw=tr.right-tr.left; - } - if (hwnd->m_style & SS_CENTER) - { - xp = r.right/2 - tw/2; - } - if (xp<8)xp=8; - if (xp+tw > r.right-8) tw=r.right-8-xp; - - HPEN pen = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT)); - HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); - HGDIOBJ oldPen=SelectObject(ps.hdc,pen); - - MoveToEx(ps.hdc,xp - (tw?4:0) + 1,th/2+1,NULL); - LineTo(ps.hdc,1,th/2+1); - LineTo(ps.hdc,1,r.bottom-1); - LineTo(ps.hdc,r.right-1,r.bottom-1); - LineTo(ps.hdc,r.right-1,th/2+1); - LineTo(ps.hdc,xp+tw + (tw?4:0),th/2+1); - - SelectObject(ps.hdc,pen2); - - MoveToEx(ps.hdc,xp - (tw?4:0),th/2,NULL); - LineTo(ps.hdc,0,th/2); - LineTo(ps.hdc,0,r.bottom-2); - LineTo(ps.hdc,r.right-2,r.bottom-2); - LineTo(ps.hdc,r.right-2,th/2); - LineTo(ps.hdc,xp+tw + (tw?4:0),th/2); - - - SelectObject(ps.hdc,oldPen); - DeleteObject(pen); - DeleteObject(pen2); - - SetTextColor(ps.hdc,col); - SetBkMode(ps.hdc,TRANSPARENT); - r.left = xp; - r.right = xp+tw; - r.bottom = th; - if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,DT_LEFT|DT_TOP); - EndPaint(hwnd,&ps); - } - } - return 0; - case WM_SETTEXT: - InvalidateRect(hwnd,NULL,TRUE); - break; - } - return DefWindowProc(hwnd,msg,wParam,lParam); -} - -static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - HBRUSH br = CreateSolidBrush(RGB(255,255,255)); // todo edit colors - FillRect(ps.hdc,&r,br); - DeleteObject(br); - SetTextColor(ps.hdc,RGB(0,0,0)); // todo edit colors - SetBkMode(ps.hdc,TRANSPARENT); - const char *buf = hwnd->m_title; - if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,DT_VCENTER); - EndPaint(hwnd,&ps); - } - } - return 0; - case WM_SETTEXT: - InvalidateRect(hwnd,NULL,FALSE); - break; - } - return DefWindowProc(hwnd,msg,wParam,lParam); -} - -static LRESULT WINAPI labelWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - - SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); - SetBkMode(ps.hdc,TRANSPARENT); - const char *buf = hwnd->m_title; - if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,((hwnd->m_style & SS_CENTER) ? DT_CENTER:0)|DT_VCENTER); - EndPaint(hwnd,&ps); - } - } - return 0; - case WM_SETTEXT: - InvalidateRect(hwnd,NULL,TRUE); - break; - } - return DefWindowProc(hwnd,msg,wParam,lParam); -} - -struct __SWELL_ComboBoxInternalState_rec -{ - __SWELL_ComboBoxInternalState_rec(const char *_desc=NULL, LPARAM _parm=0) { desc=_desc?strdup(_desc):NULL; parm=_parm; } - ~__SWELL_ComboBoxInternalState_rec() { free(desc); } - char *desc; - LPARAM parm; - static int cmp(const __SWELL_ComboBoxInternalState_rec **a, const __SWELL_ComboBoxInternalState_rec **b) { return strcmp((*a)->desc, (*b)->desc); } -}; - -class __SWELL_ComboBoxInternalState -{ - public: - __SWELL_ComboBoxInternalState() { selidx=-1; } - ~__SWELL_ComboBoxInternalState() { } - - int selidx; - WDL_PtrList_DeleteOnDestroy<__SWELL_ComboBoxInternalState_rec> items; -}; - -static LRESULT WINAPI comboWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static const char *stateName = "__SWELL_COMBOBOXSTATE"; - if (msg >= CB_ADDSTRING && msg <= CB_INITSTORAGE) - { - __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); - if (!s) - { - s = new __SWELL_ComboBoxInternalState; - SetProp(hwnd,stateName,(HANDLE)s); - } - if (s) - { - switch (msg) - { - case CB_ADDSTRING: - - if (!(hwnd->m_style & CBS_SORT)) - { - s->items.Add(new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); - return s->items.GetSize() - 1; - } - else - { - __SWELL_ComboBoxInternalState_rec *r=new __SWELL_ComboBoxInternalState_rec((const char *)lParam); - // find position of insert for wParam - bool m; - int idx = s->items.LowerBound(r,&m,__SWELL_ComboBoxInternalState_rec::cmp); - s->items.Insert(idx,r); - return idx; - } - - case CB_INSERTSTRING: - if ((int)wParam == -1) - { - s->items.Add(new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); - return s->items.GetSize() - 1; - } - else - { - if (wParam > s->items.GetSize()) wParam=s->items.GetSize(); - s->items.Insert(wParam,new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); - return wParam; - } - return 0; - - case CB_DELETESTRING: - if (wParam >= s->items.GetSize()) return CB_ERR; - s->items.Delete(wParam,true); - return s->items.GetSize(); - - case CB_GETCOUNT: return s->items.GetSize(); - case CB_GETCURSEL: return s->selidx >=0 && s->selidx < s->items.GetSize() ? s->selidx : -1; - - case CB_GETLBTEXT: - if (wParam < s->items.GetSize()) - { - if (lParam) - { - char *ptr=s->items.Get(wParam)->desc; - int l = strlen(ptr); - memcpy((char *)lParam,ptr,l+1); - return l; - } - } - return CB_ERR; - case CB_RESETCONTENT: - s->selidx=-1; - s->items.Empty(true); - return 0; - case CB_SETCURSEL: - if ((int) wParam == -1 || wParam >= s->items.GetSize()) - { - if (s->selidx!=-1) - { - s->selidx = -1; - SetWindowText(hwnd,""); - InvalidateRect(hwnd,NULL,FALSE); - } - } - else - { - if (s->selidx != wParam) - { - s->selidx=wParam; - char *ptr=s->items.Get(wParam)->desc; - SetWindowText(hwnd,ptr); - InvalidateRect(hwnd,NULL,FALSE); - } - } - case CB_GETITEMDATA: - if (wParam < s->items.GetSize()) - { - return s->items.Get(wParam)->parm; - } - return CB_ERR; - case CB_SETITEMDATA: - if (wParam < s->items.GetSize()) - { - s->items.Get(wParam)->parm=lParam; - return 0; - } - return CB_ERR; - case CB_INITSTORAGE: - return 0; - - case CB_FINDSTRINGEXACT: - case CB_FINDSTRING: - return CB_ERR; - } - } - } - - switch (msg) - { - case WM_DESTROY: - { - __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); - if (s) - { - SetProp(hwnd,stateName,NULL); - delete s; - } - } - break; - - case WM_LBUTTONDOWN: - SetCapture(hwnd); - InvalidateRect(hwnd,NULL,FALSE); - return 0; - case WM_MOUSEMOVE: - return 0; - case WM_LBUTTONUP: - if (GetCapture()==hwnd) - { - ReleaseCapture(); - __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); - if (s && s->items.GetSize()) - { - int x; - HMENU menu = CreatePopupMenu(); - for (x=0;xitems.GetSize();x++) - { - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, - x == s->selidx?MFS_CHECKED:0,100+x,NULL,NULL,NULL,0,s->items.Get(x)->desc}; - InsertMenuItem(menu,x,TRUE,&mi); - } - RECT r; - GetWindowRect(hwnd,&r); - int a = TrackPopupMenu(menu,TPM_NONOTIFY|TPM_RETURNCMD|TPM_LEFTALIGN,r.left,r.bottom,0,hwnd,0); - DestroyMenu(menu); - if (a>=100 && a < s->items.GetSize()+100) - { - s->selidx = a-100; - char *ptr=s->items.Get(s->selidx)->desc; - SetWindowText(hwnd,ptr); - InvalidateRect(hwnd,NULL,FALSE); - SendMessage(GetParent(hwnd),WM_COMMAND,(GetWindowLong(hwnd,GWL_ID)&0xffff) | (CBN_SELCHANGE<<16),(LPARAM)hwnd); - } - } - } - return 0; - case WM_PAINT: - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - RECT r; - GetClientRect(hwnd,&r); - bool pressed = GetCapture()==hwnd; - - SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); - SetBkMode(ps.hdc,TRANSPARENT); - - int f=DT_VCENTER; - { - HBRUSH br = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - FillRect(ps.hdc,&r,br); - DeleteObject(br); - - HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(pressed?COLOR_3DHILIGHT : COLOR_3DSHADOW)); - HPEN pen = CreatePen(PS_SOLID,0,GetSysColor((!pressed)?COLOR_3DHILIGHT : COLOR_3DSHADOW)); - HGDIOBJ oldpen = SelectObject(ps.hdc,pen); - MoveToEx(ps.hdc,r.left,r.bottom-1,NULL); - LineTo(ps.hdc,r.left,r.top); - LineTo(ps.hdc,r.right-1,r.top); - SelectObject(ps.hdc,pen2); - LineTo(ps.hdc,r.right-1,r.bottom-1); - LineTo(ps.hdc,r.left,r.bottom-1); - - - const int dw = 8; - const int dh = 4; - const int cx = r.right-dw/2-4; - const int cy = (r.bottom+r.top)/2; - MoveToEx(ps.hdc,cx-dw/2,cy-dh/2,NULL); - LineTo(ps.hdc,cx,cy+dh/2); - LineTo(ps.hdc,cx+dw/2,cy-dh/2); - - - SelectObject(ps.hdc,oldpen); - DeleteObject(pen); - DeleteObject(pen2); - - - if (pressed) - { - r.left+=2; - r.top+=2; - } - } - - char buf[512]; - buf[0]=0; - GetWindowText(hwnd,buf,sizeof(buf)); - if (buf[0]) DrawText(ps.hdc,buf,-1,&r,f); - - EndPaint(hwnd,&ps); - } - } - return 0; - - case WM_CAPTURECHANGED: - case WM_SETTEXT: - InvalidateRect(hwnd,NULL,FALSE); - break; - } - return DefWindowProc(hwnd,msg,wParam,lParam); -} - - -/// these are for swell-dlggen.h -HWND SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags) -{ - UINT_PTR a=(UINT_PTR)label; - if (a < 65536) label = "ICONTEMP"; - - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = swell_makeButton(m_make_owner,idx,&tr,label,!(flags&SWELL_NOT_WS_VISIBLE),0); - - if (m_doautoright) UpdateAutoCoords(tr); - if (def) { } - return hwnd; -} - - -HWND SWELL_MakeLabel( int align, const char *label, int idx, int x, int y, int w, int h, int flags) -{ - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,label, !(flags&SWELL_NOT_WS_VISIBLE),labelWindowProc); - hwnd->m_classname = "static"; - hwnd->m_style = (flags & ~SWELL_NOT_WS_VISIBLE)|WS_CHILD; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; -} -HWND SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags) -{ - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(flags&SWELL_NOT_WS_VISIBLE),editWindowProc); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "Edit"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; -} - - -HWND SWELL_MakeCheckBox(const char *name, int idx, int x, int y, int w, int h, int flags=0) -{ - return SWELL_MakeControl(name,idx,"Button",BS_AUTOCHECKBOX|flags,x,y,w,h,0); -} - -HWND SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles) -{ - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(styles&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "ListBox"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; -} - -typedef struct ccprocrec -{ - SWELL_ControlCreatorProc proc; - int cnt; - struct ccprocrec *next; -} ccprocrec; - -static ccprocrec *m_ccprocs; - -void SWELL_RegisterCustomControlCreator(SWELL_ControlCreatorProc proc) -{ - if (!proc) return; - - ccprocrec *p=m_ccprocs; - while (p && p->next) - { - if (p->proc == proc) - { - p->cnt++; - return; - } - p=p->next; - } - ccprocrec *ent = (ccprocrec*)malloc(sizeof(ccprocrec)); - ent->proc=proc; - ent->cnt=1; - ent->next=0; - - if (p) p->next=ent; - else m_ccprocs=ent; -} - -void SWELL_UnregisterCustomControlCreator(SWELL_ControlCreatorProc proc) -{ - if (!proc) return; - - ccprocrec *lp=NULL; - ccprocrec *p=m_ccprocs; - while (p) - { - if (p->proc == proc) - { - if (--p->cnt <= 0) - { - if (lp) lp->next=p->next; - else m_ccprocs=p->next; - free(p); - } - return; - } - lp=p; - p=p->next; - } -} - - -HWND SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle) -{ - if (m_ccprocs) - { - RECT poo=MakeCoords(x,y,w,h,false); - ccprocrec *p=m_ccprocs; - while (p) - { - HWND hhh=p->proc((HWND)m_make_owner,cname,idx,classname,style,poo.left,poo.top,poo.right-poo.left,poo.bottom-poo.top); - if (hhh) - { - if (exstyle) SetWindowLong(hhh,GWL_EXSTYLE,exstyle); - return hhh; - } - p=p->next; - } - } - if (!stricmp(classname,"SysTabControl32")) - { - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "SysTabControl32"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - SetWindowPos(hwnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - return hwnd; - } - else if (!stricmp(classname, "SysListView32")||!stricmp(classname, "SysListView32_LB")) - { - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "SysListView32"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - return hwnd; - } - else if (!stricmp(classname, "SysTreeView32")) - { - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "SysTreeView32"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - return hwnd; - } - else if (!stricmp(classname, "msctls_progress32")) - { - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "msctls_progress32"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - return hwnd; - } - else if (!stricmp(classname,"Edit")) - { - return SWELL_MakeEditField(idx,x,y,w,h,style); - } - else if (!stricmp(classname, "static")) - { - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,cname, !(style&SWELL_NOT_WS_VISIBLE),labelWindowProc); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "static"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; - } - else if (!stricmp(classname,"Button")) - { - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = swell_makeButton(m_make_owner,idx,&tr,cname,!(style&SWELL_NOT_WS_VISIBLE),(style&~SWELL_NOT_WS_VISIBLE)|WS_CHILD); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; - } - else if (!stricmp(classname,"REAPERhfader")||!stricmp(classname,"msctls_trackbar32")) - { - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,cname, !(style&SWELL_NOT_WS_VISIBLE)); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = !stricmp(classname,"REAPERhfader") ? "REAPERhfader" : "msctls_trackbar32"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - return hwnd; - } - return 0; -} - -HWND SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags) -{ - if (h>18)h=18; - RECT tr=MakeCoords(x,y,w,h,true); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(flags&SWELL_NOT_WS_VISIBLE),comboWindowProc); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "combobox"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - if (m_doautoright) UpdateAutoCoords(tr); - return hwnd; -} - -HWND SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style) -{ - RECT tr=MakeCoords(x,y,w,h,false); - HWND hwnd = new HWND__(m_make_owner,idx,&tr,name, !(style&SWELL_NOT_WS_VISIBLE),groupWindowProc); - hwnd->m_style |= WS_CHILD; - hwnd->m_classname = "groupbox"; - hwnd->m_wndproc(hwnd,WM_CREATE,0,0); - SetWindowPos(hwnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - return hwnd; -} - - -int TabCtrl_GetItemCount(HWND hwnd) -{ - if (!hwnd) return 0; - // todo - return 0; -} - -BOOL TabCtrl_AdjustRect(HWND hwnd, BOOL fLarger, RECT *r) -{ - if (!r || !hwnd) return FALSE; - - // todo - return FALSE; -} - - -BOOL TabCtrl_DeleteItem(HWND hwnd, int idx) -{ - if (!hwnd) return 0; - // todo - return 0; -} - -int TabCtrl_InsertItem(HWND hwnd, int idx, TCITEM *item) -{ - if (!item || !hwnd) return -1; - if (!(item->mask & TCIF_TEXT) || !item->pszText) return -1; - - return 0; // todo idx -} - -int TabCtrl_SetCurSel(HWND hwnd, int idx) -{ - if (!hwnd) return -1; - // todo - return 0; -} - -int TabCtrl_GetCurSel(HWND hwnd) -{ - if (!hwnd) return 0; - return 0; // todo -} - -void ListView_SetExtendedListViewStyleEx(HWND h, int flag, int mask) -{ -} - -void SWELL_SetListViewFastClickMask(HWND hList, int mask) -{ -} - -void ListView_SetImageList(HWND h, HIMAGELIST imagelist, int which) -{ - if (!h || !imagelist || which != LVSIL_STATE) return; - -} - -int ListView_GetColumnWidth(HWND h, int pos) -{ - if (!h) return 0; -// if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return 0; - -// return (int) floor(0.5+[col width]); - return 0; -} - -void ListView_InsertColumn(HWND h, int pos, const LVCOLUMN *lvc) -{ - if (!h || !lvc) return; -} -void ListView_SetColumn(HWND h, int pos, const LVCOLUMN *lvc) -{ -} - -void ListView_GetItemText(HWND hwnd, int item, int subitem, char *text, int textmax) -{ - LVITEM it={LVIF_TEXT,item,subitem,0,0,text,textmax,}; - ListView_GetItem(hwnd,&it); -} - -int ListView_InsertItem(HWND h, const LVITEM *item) -{ - if (!h || !item || item->iSubItem) return 0; - - return 0; -} - -void ListView_SetItemText(HWND h, int ipos, int cpos, const char *txt) -{ - if (!h || cpos < 0 || cpos >= 32) return; - -} - -int ListView_GetNextItem(HWND h, int istart, int flags) -{ - return -1; -} - -bool ListView_SetItem(HWND h, LVITEM *item) -{ - if (!item) return false; - if (!h) return false; - - return true; -} - -bool ListView_GetItem(HWND h, LVITEM *item) -{ - if (!item) return false; - if ((item->mask&LVIF_TEXT)&&item->pszText && item->cchTextMax > 0) item->pszText[0]=0; - item->state=0; - if (!h) return false; - - return true; -} -int ListView_GetItemState(HWND h, int ipos, int mask) -{ - if (!h) return 0; - int flag=0; - return flag; -} - -bool ListView_SetItemState(HWND h, int ipos, int state, int statemask) -{ - int doref=0; - if (!h) return false; - static int _is_doing_all; - - if (ipos == -1) - { - int x; - int n=ListView_GetItemCount(h); - _is_doing_all++; - for (x = 0; x < n; x ++) - ListView_SetItemState(h,x,state,statemask); - _is_doing_all--; - ListView_RedrawItems(h,0,n-1); - return true; - } - - if (!_is_doing_all) - { - if (0) // didsel) - { - static int __rent; - if (!__rent) - { - int tag=0; // todo - __rent=1; - NMLISTVIEW nm={{(HWND)h,tag,LVN_ITEMCHANGED},ipos,0,state,}; - SendMessage(GetParent(h),WM_NOTIFY,tag,(LPARAM)&nm); - __rent=0; - } - } - if (doref) - ListView_RedrawItems(h,ipos,ipos); - } - return true; -} -void ListView_RedrawItems(HWND h, int startitem, int enditem) -{ - if (!h) return; -} - -void ListView_DeleteItem(HWND h, int ipos) -{ - if (!h) return; - -} - -void ListView_DeleteAllItems(HWND h) -{ - if (!h) return; -} - -int ListView_GetSelectedCount(HWND h) -{ - if (!h) return 0; - return 0; -} - -int ListView_GetItemCount(HWND h) -{ - if (!h) return 0; - return 0; -} - -int ListView_GetSelectionMark(HWND h) -{ - if (!h) return 0; - return 0; -} -int SWELL_GetListViewHeaderHeight(HWND h) -{ - return 0; -} - -void ListView_SetColumnWidth(HWND h, int colpos, int wid) -{ -} - -int ListView_HitTest(HWND h, LVHITTESTINFO *pinf) -{ - if (!h) return -1; - return -1; -} -int ListView_SubItemHitTest(HWND h, LVHITTESTINFO *pinf) -{ - return -1; -} - -void ListView_SetItemCount(HWND h, int cnt) -{ - if (!h) return; -} - -void ListView_EnsureVisible(HWND h, int i, BOOL pok) -{ - if (!h) return; -} -bool ListView_GetSubItemRect(HWND h, int item, int subitem, int code, RECT *r) -{ - if (!h) return false; - return false; -} -bool ListView_GetItemRect(HWND h, int item, RECT *r, int code) -{ - return false; -} - -bool ListView_Scroll(HWND h, int xscroll, int yscroll) -{ - return false; -} -void ListView_SortItems(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm) -{ - if (!hwnd) return; -} -bool ListView_DeleteColumn(HWND h, int pos) -{ - return false; -} -int ListView_GetCountPerPage(HWND h) -{ - return 1; -} - -HWND ChildWindowFromPoint(HWND h, POINT p) -{ - if (!h) return 0; - - RECT r={0,}; - - for(;;) - { - HWND h2=h->m_children; - RECT sr; - - RECT tr=h->m_position; - if (h->m_wndproc) h->m_wndproc(h,WM_NCCALCSIZE,0,(LPARAM)&tr); - r.left += tr.left - h->m_position.left; - r.top += tr.top - h->m_position.top; - - while (h2) - { - sr = h2->m_position; - sr.left += r.left; - sr.right += r.left; - sr.top += r.top; - sr.bottom += r.top; - - if (h2->m_visible && PtInRect(&sr,p)) break; - - h2 = h2->m_next; - } - if (!h2) break; // h is the window we care about - - h=h2; // descend to h2 - r=sr; - } - - return h; -} - -HWND WindowFromPoint(POINT p) -{ - HWND h = SWELL_topwindows; - while (h) - { - RECT r; - GetWindowContentViewRect(h,&r); - if (PtInRect(&r,p)) - { - p.x -= r.left; - p.y -= r.top; - return ChildWindowFromPoint(h,p); - } - h = h->m_next; - } - return NULL; -} - -void UpdateWindow(HWND hwnd) -{ - if (hwnd) - { -#ifdef SWELL_TARGET_GDK - while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; - if (hwnd && hwnd->m_oswindow) gdk_window_process_updates(hwnd->m_oswindow,true); -#endif - } -} - -void InvalidateRect(HWND hwnd, RECT *r, int eraseBk) -{ - if (!hwnd) return; - HWND hwndCall=hwnd; -#ifdef SWELL_LICE_GDI - { - hwnd->m_invalidated=true; - HWND t=hwnd->m_parent; - while (t && !t->m_child_invalidated) - { - if (eraseBk) - { - t->m_invalidated=true; - eraseBk--; - } - t->m_child_invalidated=true; - t=t->m_parent; - } - } -#endif -#ifdef SWELL_TARGET_GDK - GdkRectangle rect; - if (r) { rect.x = r->left; rect.y = r->top; rect.width = r->right-r->left; rect.height = r->bottom - r->top; } - else - { - rect.x=rect.y=0; - rect.width = hwnd->m_position.right - hwnd->m_position.left; - rect.height = hwnd->m_position.bottom - hwnd->m_position.top; - } - while (hwnd && !hwnd->m_oswindow) - { - RECT tr=hwnd->m_position; - if (hwnd->m_wndproc) hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,0,(LPARAM)&tr); - rect.x += tr.left; - rect.y += tr.top; - hwnd=hwnd->m_parent; - } - if (hwnd && hwnd->m_oswindow) - { - RECT tr={0,0,hwnd->m_position.right-hwnd->m_position.left,hwnd->m_position.bottom-hwnd->m_position.top}; - if (hwnd->m_wndproc) hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,0,(LPARAM)&tr); - rect.x += tr.left; - rect.y += tr.top; - - gdk_window_invalidate_rect(hwnd->m_oswindow,hwnd!=hwndCall || r ? &rect : NULL,true); - } -#endif -} - - -HWND GetCapture() -{ - return s_captured_window; -} - -HWND SetCapture(HWND hwnd) -{ - HWND oc = s_captured_window; - if (oc != hwnd) - { - s_captured_window=hwnd; - if (oc) SendMessage(oc,WM_CAPTURECHANGED,0,(LPARAM)hwnd); -#ifdef SWELL_TARGET_GDK -// this doesnt seem to be necessary -// if (gdk_pointer_is_grabbed()) gdk_pointer_ungrab(GDK_CURRENT_TIME); -// while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; -// if (hwnd) gdk_pointer_grab(hwnd->m_oswindow,TRUE,GDK_ALL_EVENTS_MASK,hwnd->m_oswindow,NULL,GDK_CURRENT_TIME); -#endif - } - return oc; -} - -void ReleaseCapture() -{ - if (s_captured_window) - { - SendMessage(s_captured_window,WM_CAPTURECHANGED,0,0); - s_captured_window=0; -#ifdef SWELL_TARGET_GDK -// if (gdk_pointer_is_grabbed()) gdk_pointer_ungrab(GDK_CURRENT_TIME); -#endif - } -} - -LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - DLGPROC d=(DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); - if (d) - { - if (uMsg == WM_PAINT) - { - PAINTSTRUCT ps; - if (BeginPaint(hwnd,&ps)) - { - HBRUSH hbrush = (HBRUSH) d(hwnd,WM_CTLCOLORDLG,(WPARAM)ps.hdc,(LPARAM)hwnd); - if (hbrush && hbrush != (HBRUSH)1) - { - FillRect(ps.hdc,&ps.rcPaint,hbrush); - } - else if (1) - { - hbrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - FillRect(ps.hdc,&ps.rcPaint,hbrush); - DeleteObject(hbrush); - } - else if (0) // todo only on top level windows? - { - SWELL_FillDialogBackground(ps.hdc,&ps.rcPaint,3); - } - - EndPaint(hwnd,&ps); - } - } - - LRESULT r=(LRESULT) d(hwnd,uMsg,wParam,lParam); - - - if (r) return r; - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - -BOOL EndPaint(HWND hwnd, PAINTSTRUCT *ps) -{ - return TRUE; -} - -LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - const int menubar_size=12; // big for testing - const int menubar_xspacing=5; - switch (msg) - { - case WM_NCCALCSIZE: - if (!hwnd->m_parent && hwnd->m_menu) - { - RECT *r = (RECT*)lParam; - r->top += menubar_size; - } - break; - case WM_NCPAINT: - if (!hwnd->m_parent && hwnd->m_menu) - { - HDC dc = GetWindowDC(hwnd); - if (dc) - { - RECT r; - GetWindowContentViewRect(hwnd,&r); - r.right -= r.left; r.left=0; - r.bottom -= r.top; r.top=0; - if (r.bottom>menubar_size) r.bottom=menubar_size; - - HBRUSH br=CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - FillRect(dc,&r,br); - DeleteObject(br); - - SetBkMode(dc,TRANSPARENT); - int cols[2]={ GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_3DHILIGHT)}; - - int x,xpos=0; - HMENU__ *menu = (HMENU__*)hwnd->m_menu; - for(x=0;xitems.GetSize();x++) - { - MENUITEMINFO *inf = menu->items.Get(x); - if (inf->fType == MFT_STRING && inf->dwTypeData) - { - bool dis = !!(inf->fState & MF_GRAYED); - SetTextColor(dc,cols[dis]); - RECT cr=r; cr.left=cr.right=xpos; - DrawText(dc,inf->dwTypeData,-1,&cr,DT_CALCRECT); - DrawText(dc,inf->dwTypeData,-1,&cr,DT_VCENTER|DT_LEFT); - xpos=cr.right+menubar_xspacing; - } - } - - ReleaseDC(hwnd,dc); - } - } - break; - case WM_RBUTTONUP: - case WM_NCRBUTTONUP: - { - POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; - HWND hwndDest=hwnd; - if (msg==WM_RBUTTONUP) - { - ClientToScreen(hwnd,&p); - HWND h=WindowFromPoint(p); - if (h && IsChild(hwnd,h)) hwndDest=h; - } - SendMessage(hwnd,WM_CONTEXTMENU,(WPARAM)hwndDest,(p.x&0xffff)|(p.y<<16)); - } - return 1; -// case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONUP: - if (!hwnd->m_parent && hwnd->m_menu) - { - RECT r; - GetWindowContentViewRect(hwnd,&r); - if (GET_Y_LPARAM(lParam)>=r.top && GET_Y_LPARAM(lParam) < r.top+menubar_size) - { - HDC dc = GetWindowDC(hwnd); - - int x,xpos=r.left; - HMENU__ *menu = (HMENU__*)hwnd->m_menu; - for(x=0;xitems.GetSize();x++) - { - MENUITEMINFO *inf = menu->items.Get(x); - if (inf->fType == MFT_STRING && inf->dwTypeData) - { - bool dis = !!(inf->fState & MF_GRAYED); - RECT cr=r; cr.left=cr.right=xpos; - DrawText(dc,inf->dwTypeData,-1,&cr,DT_CALCRECT); - - if (GET_X_LPARAM(lParam) >=cr.left && GET_X_LPARAM(lParam)<=cr.right) - { - if (!dis) - { - if (inf->hSubMenu) TrackPopupMenu(inf->hSubMenu,0,xpos,r.top+menubar_size,0,hwnd,NULL); - else if (inf->wID) SendMessage(hwnd,WM_COMMAND,inf->wID,0); - } - break; - } - - xpos=cr.right+menubar_xspacing; - } - } - - if (dc) ReleaseDC(hwnd,dc); - } - } - break; - case WM_NCHITTEST: - if (!hwnd->m_parent && hwnd->m_menu) - { - RECT r; - GetWindowContentViewRect(hwnd,&r); - if (GET_Y_LPARAM(lParam)>=r.top && GET_Y_LPARAM(lParam) < r.top+menubar_size) return HTMENU; - } - return HTCLIENT; - case WM_KEYDOWN: - case WM_KEYUP: return 69; - case WM_CONTEXTMENU: - return hwnd->m_parent ? SendMessage(hwnd->m_parent,msg,wParam,lParam) : 0; - case WM_GETFONT: -#ifdef SWELL_FREETYPE - { - HFONT SWELL_GetDefaultFont(); - return (LRESULT)SWELL_GetDefaultFont(); - } -#endif - - return 0; - } - return 0; -} - - - - - - - - - - - - - - - - - - -///////////////// clipboard compatability (NOT THREAD SAFE CURRENTLY) - - -BOOL DragQueryPoint(HDROP hDrop,LPPOINT pt) -{ - if (!hDrop) return 0; - DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); - BOOL rv=!df->fNC; - *pt=df->pt; - GlobalUnlock(hDrop); - return rv; -} - -void DragFinish(HDROP hDrop) -{ -//do nothing for now (caller will free hdrops) -} - -UINT DragQueryFile(HDROP hDrop, UINT wf, char *buf, UINT bufsz) -{ - if (!hDrop) return 0; - DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); - - UINT rv=0; - char *p=(char*)df + df->pFiles; - if (wf == 0xFFFFFFFF) - { - while (*p) - { - rv++; - p+=strlen(p)+1; - } - } - else - { - while (*p) - { - if (!wf--) - { - if (buf) - { - lstrcpyn(buf,p,bufsz); - rv=strlen(buf); - } - else rv=strlen(p); - - break; - } - p+=strlen(p)+1; - } - } - GlobalUnlock(hDrop); - return rv; -} - - - -static WDL_PtrList m_clip_recs; -//static WDL_PtrList m_clip_fmts; -static WDL_PtrList m_clip_curfmts; -bool OpenClipboard(HWND hwndDlg) -{ - m_clip_curfmts.Empty(); - return true; -} - -void CloseClipboard() // frees any remaining items in clipboard -{ - m_clip_recs.Empty(true,GlobalFree); -} - -UINT EnumClipboardFormats(UINT lastfmt) -{ - return 0; -} - -HANDLE GetClipboardData(UINT type) -{ - return 0; -} - - -void EmptyClipboard() -{ -} - -void SetClipboardData(UINT type, HANDLE h) -{ -} - -UINT RegisterClipboardFormat(const char *desc) -{ - return 0; -} - - - -///////// PostMessage emulation - -BOOL PostMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - return SWELL_Internal_PostMessage(hwnd,message,wParam,lParam); -} - -void SWELL_MessageQueue_Clear(HWND h) -{ - SWELL_Internal_PMQ_ClearAllMessages(h); -} - - - -// implementation of postmessage stuff - - - - -typedef struct PMQ_rec -{ - HWND hwnd; - UINT msg; - WPARAM wParam; - LPARAM lParam; - - struct PMQ_rec *next; -} PMQ_rec; - -static WDL_Mutex *m_pmq_mutex; -static PMQ_rec *m_pmq, *m_pmq_empty, *m_pmq_tail; -static int m_pmq_size; - -#define MAX_POSTMESSAGE_SIZE 1024 - - -void SWELL_Internal_PostMessage_Init() -{ - if (m_pmq_mutex) return; - - m_pmq_mainthread=pthread_self(); - m_pmq_mutex = new WDL_Mutex; -} - -void SWELL_MessageQueue_Flush() -{ - if (!m_pmq_mutex) return; - - m_pmq_mutex->Enter(); - PMQ_rec *p=m_pmq, *startofchain=m_pmq; - m_pmq=m_pmq_tail=0; - m_pmq_mutex->Leave(); - - int cnt=0; - // process out queue - while (p) - { - // process this message - SendMessage(p->hwnd,p->msg,p->wParam,p->lParam); - - cnt ++; - if (!p->next) // add the chain back to empties - { - m_pmq_mutex->Enter(); - m_pmq_size-=cnt; - p->next=m_pmq_empty; - m_pmq_empty=startofchain; - m_pmq_mutex->Leave(); - break; - } - p=p->next; - } -} - -void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd) -{ - if (!m_pmq_mutex) return; - - m_pmq_mutex->Enter(); - PMQ_rec *p=m_pmq; - PMQ_rec *lastrec=NULL; - while (p) - { - if (hwnd && p->hwnd != hwnd) { lastrec=p; p=p->next; } - else - { - PMQ_rec *next=p->next; - - p->next=m_pmq_empty; // add p to empty list - m_pmq_empty=p; - m_pmq_size--; - - - if (p==m_pmq_tail) m_pmq_tail=lastrec; // update tail - - if (lastrec) p = lastrec->next = next; - else p = m_pmq = next; - } - } - m_pmq_mutex->Leave(); -} - -BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!hwnd||!m_pmq_mutex) return FALSE; - - BOOL ret=FALSE; - m_pmq_mutex->Enter(); - - if (m_pmq_empty||m_pmq_sizenext; - else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); - rec->next=0; - rec->hwnd=hwnd; - rec->msg=msg; - rec->wParam=wParam; - rec->lParam=lParam; - - if (m_pmq_tail) m_pmq_tail->next=rec; - else - { - PMQ_rec *p=m_pmq; - while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety - if (p) p->next=rec; - else m_pmq=rec; - } - m_pmq_tail=rec; - m_pmq_size++; - - ret=TRUE; - } - - m_pmq_mutex->Leave(); - - return ret; -} - - -int EnumPropsEx(HWND hwnd, PROPENUMPROCEX proc, LPARAM lParam) -{ - if (!hwnd) return -1; - int x; - for (x =0 ; x < hwnd->m_props.GetSize(); x ++) - { - const char *k=""; - void *p = hwnd->m_props.Enumerate(x,&k); - if (!proc(hwnd,k,p,lParam)) return 0; - } - return 1; -} - -HANDLE GetProp(HWND hwnd, const char *name) -{ - if (!hwnd) return NULL; - return hwnd->m_props.Get(name); -} - -BOOL SetProp(HWND hwnd, const char *name, HANDLE val) -{ - if (!hwnd) return false; - hwnd->m_props.Insert(name,(void *)val); - return TRUE; -} - -HANDLE RemoveProp(HWND hwnd, const char *name) -{ - HANDLE h =GetProp(hwnd,name); - hwnd->m_props.Delete(name); - return h; -} - - -int GetSystemMetrics(int p) -{ - switch (p) - { - case SM_CXSCREEN: - case SM_CYSCREEN: - { - RECT r; - SWELL_GetViewPort(&r, NULL, false); - return p==SM_CXSCREEN ? r.right-r.left : r.bottom-r.top; - } - case SM_CXHSCROLL: return 16; - case SM_CYHSCROLL: return 16; - case SM_CXVSCROLL: return 16; - case SM_CYVSCROLL: return 16; - } - return 0; -} - -BOOL ScrollWindow(HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect) -{ - if (!hwnd || (!xamt && !yamt)) return FALSE; - - // move child windows only - hwnd = hwnd->m_children; - while (hwnd) - { - hwnd->m_position.left += xamt; - hwnd->m_position.right += xamt; - hwnd->m_position.top += yamt; - hwnd->m_position.bottom += yamt; - - hwnd=hwnd->m_next; - } - return TRUE; -} - -HWND FindWindowEx(HWND par, HWND lastw, const char *classname, const char *title) -{ - if (!par&&!lastw) return NULL; // need to implement this modes - HWND h=lastw?GetWindow(lastw,GW_HWNDNEXT):GetWindow(par,GW_CHILD); - while (h) - { - bool isOk=true; - if (title) - { - char buf[512]; - buf[0]=0; - GetWindowText(h,buf,sizeof(buf)); - if (strcmp(title,buf)) isOk=false; - } - if (classname) - { - // todo: other classname translations - } - - if (isOk) return h; - h=GetWindow(h,GW_HWNDNEXT); - } - return h; -} - - -HTREEITEM TreeView_InsertItem(HWND hwnd, TV_INSERTSTRUCT *ins) -{ - if (!hwnd || !ins) return 0; - - return NULL; -} - -BOOL TreeView_Expand(HWND hwnd, HTREEITEM item, UINT flag) -{ - if (!hwnd || !item) return false; - - return TRUE; - -} - -HTREEITEM TreeView_GetSelection(HWND hwnd) -{ - if (!hwnd) return NULL; - - return NULL; - -} - -void TreeView_DeleteItem(HWND hwnd, HTREEITEM item) -{ - if (!hwnd) return; -} - -void TreeView_SelectItem(HWND hwnd, HTREEITEM item) -{ - if (!hwnd) return; - -} - -BOOL TreeView_GetItem(HWND hwnd, LPTVITEM pitem) -{ - if (!hwnd || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; - - return TRUE; -} - -BOOL TreeView_SetItem(HWND hwnd, LPTVITEM pitem) -{ - if (!hwnd || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; - - return TRUE; -} - -HTREEITEM TreeView_HitTest(HWND hwnd, TVHITTESTINFO *hti) -{ - if (!hwnd || !hti) return NULL; - - return NULL; // todo implement -} - -HTREEITEM TreeView_GetRoot(HWND hwnd) -{ - if (!hwnd) return NULL; - return NULL; -} - -HTREEITEM TreeView_GetChild(HWND hwnd, HTREEITEM item) -{ - if (!hwnd) return NULL; - return NULL; -} -HTREEITEM TreeView_GetNextSibling(HWND hwnd, HTREEITEM item) -{ - if (!hwnd) return NULL; - - return NULL; -} -BOOL TreeView_SetIndent(HWND hwnd, int indent) -{ - return FALSE; -} -void TreeView_SetBkColor(HWND hwnd, int color) -{ -} -void TreeView_SetTextColor(HWND hwnd, int color) -{ -} -void ListView_SetBkColor(HWND hwnd, int color) -{ -} -void ListView_SetTextBkColor(HWND hwnd, int color) -{ -} -void ListView_SetTextColor(HWND hwnd, int color) -{ -} -void ListView_SetGridColor(HWND hwnd, int color) -{ -} -void ListView_SetSelColors(HWND hwnd, int *colors, int ncolors) -{ -} -int ListView_GetTopIndex(HWND h) -{ -} -BOOL ListView_GetColumnOrderArray(HWND h, int cnt, int* arr) -{ -} -BOOL ListView_SetColumnOrderArray(HWND h, int cnt, int* arr) -{ - return FALSE; -} -HWND ListView_GetHeader(HWND h) -{ - return 0; -} - -int Header_GetItemCount(HWND h) -{ - return 0; -} - -BOOL Header_GetItem(HWND h, int col, HDITEM* hi) -{ - return FALSE; -} - -BOOL Header_SetItem(HWND h, int col, HDITEM* hi) -{ - return FALSE; -} - - -BOOL EnumChildWindows(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam) -{ - if (hwnd && hwnd->m_children) - { - HWND n=hwnd->m_children; - while (n) - { - if (!cwEnumFunc(n,lParam) || !EnumChildWindows(n,cwEnumFunc,lParam)) return FALSE; - n = n->m_next; - } - } - return TRUE; -} -void SWELL_GetDesiredControlSize(HWND hwnd, RECT *r) -{ -} - -BOOL SWELL_IsGroupBox(HWND hwnd) -{ - //todo - return FALSE; -} -BOOL SWELL_IsButton(HWND hwnd) -{ - //todo - return FALSE; -} -BOOL SWELL_IsStaticText(HWND hwnd) -{ - //todo - return FALSE; -} - - -BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah) -{ - return FALSE; -} - - - - -// r=NULL to "free" handle -// otherwise r is in hwndPar coordinates -void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) -{ - if (!handle) return; -} - -void SWELL_BroadcastMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - - HWND h = SWELL_topwindows; - while (h) - { - SendMessage(h,uMsg,wParam,lParam); - h = h->m_next; - } -} - -int SWELL_SetWindowLevel(HWND hwnd, int newlevel) -{ - return 0; -} -void SetOpaque(HWND h, bool opaque) -{ -} -int SWELL_GetDefaultButtonID(HWND hwndDlg, bool onlyIfEnabled) -{ - return 0; -} - -void GetCursorPos(POINT *pt) -{ - pt->x=0; - pt->y=0; -#ifdef SWELL_TARGET_GDK - if (SWELL_gdk_active>0) - gdk_display_get_pointer(gdk_display_get_default(),NULL,&pt->x,&pt->y,NULL); -#endif -} - -WORD GetAsyncKeyState(int key) -{ -#ifdef SWELL_TARGET_GDK - if (SWELL_gdk_active>0) - { - GdkModifierType mod=(GdkModifierType)0; - HWND h = GetFocus(); - while (h && !h->m_oswindow) h = h->m_parent; - gdk_window_get_pointer(h? h->m_oswindow : gdk_get_default_root_window(),NULL,NULL,&mod); - - if (key == VK_LBUTTON) return (mod&GDK_BUTTON1_MASK)?0x8000:0; - if (key == VK_MBUTTON) return (mod&GDK_BUTTON2_MASK)?0x8000:0; - if (key == VK_RBUTTON) return (mod&GDK_BUTTON3_MASK)?0x8000:0; - - if (key == VK_CONTROL) return (mod&GDK_CONTROL_MASK)?0x8000:0; - if (key == VK_MENU) return (mod&GDK_MOD1_MASK)?0x8000:0; - if (key == VK_SHIFT) return (mod&GDK_SHIFT_MASK)?0x8000:0; - } -#endif - return 0; -} - - -DWORD GetMessagePos() -{ - return s_lastMessagePos; -} - -void SWELL_HideApp() -{ -} - -BOOL SWELL_GetGestureInfo(LPARAM lParam, GESTUREINFO* gi) -{ - return FALSE; -} - -void SWELL_SetWindowWantRaiseAmt(HWND h, int amt) -{ -} -int SWELL_GetWindowWantRaiseAmt(HWND h) -{ - return 0; -} - -// copied from swell-wnd.mm, can maybe have a common impl instead -void SWELL_GenerateDialogFromList(const void *_list, int listsz) -{ -#define SIXFROMLIST list->p1,list->p2,list->p3, list->p4, list->p5, list->p6 - SWELL_DlgResourceEntry *list = (SWELL_DlgResourceEntry*)_list; - while (listsz>0) - { - if (!strcmp(list->str1,"__SWELL_BUTTON")) - { - SWELL_MakeButton(list->flag1,list->str2, SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_EDIT")) - { - SWELL_MakeEditField(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_COMBO")) - { - SWELL_MakeCombo(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_LISTBOX")) - { - SWELL_MakeListBox(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_GROUP")) - { - SWELL_MakeGroupBox(list->str2,SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_CHECKBOX")) - { - SWELL_MakeCheckBox(list->str2,SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_LABEL")) - { - SWELL_MakeLabel(list->flag1, list->str2, SIXFROMLIST); - } - else if (*list->str2) - { - SWELL_MakeControl(list->str1, list->flag1, list->str2, SIXFROMLIST); - } - listsz--; - list++; - } -} - -#endif diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm deleted file mode 100644 index 962d17cc..00000000 --- a/WDL/swell/swell-wnd.mm +++ /dev/null @@ -1,6128 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides basic windows APIs for handling windows, as well as the stubs to enable swell-dlggen to work. - - */ - - -#ifndef SWELL_PROVIDED_BY_APP - -#import -#import -#include "swell.h" -#include "../mutex.h" -#include "../ptrlist.h" -#include "../queue.h" - -#include "swell-dlggen.h" -#include "swell-internal.h" - - - -static LRESULT sendSwellMessage(id obj, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (obj && [obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - return [(SWELL_hwndChild *)obj onSwellMessage:uMsg p1:wParam p2:lParam]; - return 0; -} -static void InvalidateSuperViews(NSView *view); -#define STANDARD_CONTROL_NEEDSDISPLAY_IMPL \ - - (void)setNeedsDisplay:(BOOL)flag \ - { \ - [super setNeedsDisplay:flag]; \ - if (flag) InvalidateSuperViews(self); \ - } \ - - (void)setNeedsDisplayInRect:(NSRect)rect \ - { \ - [super setNeedsDisplayInRect:rect]; \ - InvalidateSuperViews(self); \ - } - - -char* lstrcpyn(char* dest, const char* src, int l); - -int g_swell_want_nice_style = 1; -static void *SWELL_CStringToCFString_FilterPrefix(const char *str) -{ - int c=0; - while (str[c] && str[c] != '&' && c++<1024); - if (!str[c] || c>=1024 || strlen(str)>=1024) return SWELL_CStringToCFString(str); - char buf[1500]; - const char *p=str; - char *op=buf; - while (*p) - { - if (*p == '&') p++; - if (!*p) break; - *op++=*p++; - } - *op=0; - return SWELL_CStringToCFString(buf); - -} - -static int _nsStringSearchProc(const void *_a, const void *_b) -{ - NSString *a=(NSString *)_a; - NSString *b = (NSString *)_b; - return [a compare:b]; -} -static int _nsMenuSearchProc(const void *_a, const void *_b) -{ - NSString *a=(NSString *)_a; - NSMenuItem *b = (NSMenuItem *)_b; - return [a compare:[b title]]; -} -static int _listviewrowSearchFunc(const void *_a, const void *_b, const void *ctx) -{ - const char *a = (const char *)_a; - SWELL_ListView_Row *row = (SWELL_ListView_Row *)_b; - const char *b=""; - if (!row || !(b=row->m_vals.Get(0))) b=""; - return strcmp(a,b); -} -static int _listviewrowSearchFunc2(const void *_a, const void *_b, const void *ctx) -{ - const char *a = (const char *)_a; - SWELL_ListView_Row *row = (SWELL_ListView_Row *)_b; - const char *b=""; - if (!row || !(b=row->m_vals.Get(0))) b=""; - return strcmp(b,a); -} - -// modified bsearch: returns place item SHOULD be in if it's not found -static int arr_bsearch_mod(void *key, NSArray *arr, int (*compar)(const void *, const void *)) -{ - size_t nmemb = [arr count]; - int base=0; - int lim, cmp; - int p; - - for (lim = nmemb; lim != 0; lim >>= 1) { - p = base + (lim >> 1); - cmp = compar(key, [arr objectAtIndex:p]); - if (cmp == 0) return (p); - if (cmp > 0) { /* key > p: move right */ - // check to see if key is less than p+1, if it is, we're done - base = p + 1; - if (base >= nmemb || compar(key,[arr objectAtIndex:base])<=0) return base; - lim--; - } /* else move left */ - } - return 0; -} - - -template static int ptrlist_bsearch_mod(void *key, WDL_PtrList *arr, int (*compar)(const void *, const void *, const void *ctx), void *ctx) -{ - size_t nmemb = arr->GetSize(); - int base=0; - int lim, cmp; - int p; - - for (lim = nmemb; lim != 0; lim >>= 1) { - p = base + (lim >> 1); - cmp = compar(key, arr->Get(p),ctx); - if (cmp == 0) return (p); - if (cmp > 0) { /* key > p: move right */ - // check to see if key is less than p+1, if it is, we're done - base = p + 1; - if (base >= nmemb || compar(key,arr->Get(base),ctx)<=0) return base; - lim--; - } /* else move left */ - } - return 0; -} - - -SWELL_ListView_Row::SWELL_ListView_Row() -{ - m_imageidx=0; - m_param=0; -} -SWELL_ListView_Row::~SWELL_ListView_Row() -{ - m_vals.Empty(true,free); -} - -HTREEITEM__::HTREEITEM__() -{ - m_param=0; - m_value=0; - m_haschildren=false; - m_dh = [[SWELL_DataHold alloc] initWithVal:this]; -} -HTREEITEM__::~HTREEITEM__() -{ - free(m_value); - m_children.Empty(true); - [m_dh release]; -} - - -bool HTREEITEM__::FindItem(HTREEITEM it, HTREEITEM__ **parOut, int *idxOut) -{ - int a=m_children.Find((HTREEITEM__*)it); - if (a>=0) - { - *parOut=this; - *idxOut=a; - return true; - } - int x; - for (x = 0; x < m_children.GetSize(); x ++) - { - if (m_children.Get(x)->FindItem(it,parOut,idxOut)) return true; - } - return false; -} - -@implementation SWELL_TabView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(void)setNotificationWindow:(id)dest -{ - m_dest=dest; -} --(id)getNotificationWindow -{ - return m_dest; -} --(NSInteger) tag -{ - return m_tag; -} --(void) setTag:(NSInteger)tag -{ - m_tag=tag; -} -- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem -{ - if (m_dest) - { - NMHDR nm={(HWND)self,[self tag],TCN_SELCHANGE}; - SendMessage((HWND)m_dest,WM_NOTIFY,[self tag],(LPARAM)&nm); - } -} -@end - - -@implementation SWELL_ProgressView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(NSInteger) tag -{ - return m_tag; -} --(void) setTag:(NSInteger)tag -{ - m_tag=tag; -} --(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam -{ - if (msg == PBM_SETRANGE) - { - [self setMinValue:LOWORD(lParam)]; - [self setMaxValue:HIWORD(lParam)]; - } - else if (msg==PBM_SETPOS) - { - [self setDoubleValue:(double)wParam]; - [self stopAnimation:self]; - } - else if (msg==PBM_DELTAPOS) - { - [self incrementBy:(double)wParam]; - } - return 0; -} - -@end - -@implementation SWELL_ListViewCell --(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView -{ - if ([controlView isKindOfClass:[SWELL_ListView class]] && ((SWELL_ListView *)controlView)->m_selColors) return nil; - if ([controlView isKindOfClass:[SWELL_TreeView class]] && ((SWELL_TreeView *)controlView)->m_selColors) return nil; - return [super highlightColorWithFrame:cellFrame inView:controlView]; -} -@end - -@implementation SWELL_StatusCell --(id)initNewCell -{ - if ((self=[super initTextCell:@""])) - { - status=0; - } - return self; -} --(void)setStatusImage:(NSImage *)img -{ - status=img; -} -- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView -{ - if (status) - { - [controlView lockFocus]; - [status drawInRect:NSMakeRect(cellFrame.origin.x,cellFrame.origin.y,cellFrame.size.height,cellFrame.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; - [controlView unlockFocus]; - } - cellFrame.origin.x += cellFrame.size.height + 2.0; - cellFrame.size.width -= cellFrame.size.height + 2.0; - [super drawWithFrame:cellFrame inView:controlView]; -} - --(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView -{ - if ([controlView isKindOfClass:[SWELL_ListView class]] && ((SWELL_ListView *)controlView)->m_selColors) return nil; - return [super highlightColorWithFrame:cellFrame inView:controlView]; -} - -@end - -@implementation SWELL_TreeView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(id) init -{ - if ((self = [super init])) - { - m_fakerightmouse=false; - m_items=new WDL_PtrList; - m_fgColor=0; - m_selColors=0; - } - return self; -} --(void) dealloc -{ - if (m_items) m_items->Empty(true); - delete m_items; - m_items=0; - [m_fgColor release]; - [m_selColors release]; - [super dealloc]; -} - --(bool) findItem:(HTREEITEM)item parOut:(HTREEITEM__ **)par idxOut:(int *)idx -{ - if (!m_items||!item) return false; - int x=m_items->Find((HTREEITEM__*)item); - if (x>=0) - { - *par=NULL; - *idx=x; - return true; - } - for (x = 0; x < m_items->GetSize(); x++) - { - if (m_items->Get(x)->FindItem(item,par,idx)) return true; - } - - return false; -} - --(NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item -{ - if (item == nil) return m_items ? m_items->GetSize() : 0; - return ((HTREEITEM__*)[item getValue])->m_children.GetSize(); -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item -{ - if (item==nil) return YES; - HTREEITEM__ *it=(HTREEITEM__ *)[item getValue]; - - return it && it->m_haschildren; -} - -- (id)outlineView:(NSOutlineView *)outlineView - child:(NSInteger)index - ofItem:(id)item -{ - HTREEITEM__ *row=item ? ((HTREEITEM__*)[item getValue])->m_children.Get(index) : m_items ? m_items->Get(index) : 0; - - return (id)row->m_dh; -} - -- (id)outlineView:(NSOutlineView *)outlineView - objectValueForTableColumn:(NSTableColumn *)tableColumn - byItem:(id)item -{ - if (!item) return @""; - HTREEITEM__ *it=(HTREEITEM__ *)[item getValue]; - - if (!it || !it->m_value) return @""; - - NSString *str=(NSString *)SWELL_CStringToCFString(it->m_value); - - return [str autorelease]; -} - - - --(void)mouseDown:(NSEvent *)theEvent -{ - if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) - { - m_fakerightmouse=1; - } - else - { - - NMCLICK nmlv={{(HWND)self,[self tag], NM_CLICK},}; - SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); - - m_fakerightmouse=0; - [super mouseDown:theEvent]; - } -} - --(void)mouseDragged:(NSEvent *)theEvent -{ -} - --(void)mouseUp:(NSEvent *)theEvent -{ - if (m_fakerightmouse||([theEvent modifierFlags] & NSControlKeyMask)) [self rightMouseUp:theEvent]; - else [super mouseUp:theEvent]; -} -- (void)rightMouseUp:(NSEvent *)theEvent -{ - bool wantContext=true; - - NMCLICK nmlv={{(HWND)self,[self tag], NM_RCLICK},}; - if (SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv)) wantContext=false; - - if (wantContext) - { - POINT p; - GetCursorPos(&p); - SendMessage((HWND)[self target],WM_CONTEXTMENU,(WPARAM)self,(p.x&0xffff)|(p.y<<16)); - } - - m_fakerightmouse=0; -} - -- (void)highlightSelectionInClipRect:(NSRect)theClipRect -{ - if (m_selColors) - { - int a = GetFocus() == (HWND)self ? 0 : 2; - if ([m_selColors count] >= a) - { - NSColor *c=[m_selColors objectAtIndex:a]; - if (c) - { - // calculate rect of selected items, combine with theClipRect, and fill these areas with our background (phew!) - - int x = [self selectedRow]; - if (x>=0) - { - NSRect r = [self rectOfRow:x]; - r = NSIntersectionRect(r,theClipRect); - if (r.size.height>0 && r.size.width>0) - { - [c setFill]; - NSRectFill(r); - } - } - return ; - } - } - } - return [super highlightSelectionInClipRect:theClipRect]; -} - - - - -@end - - - - - -@implementation SWELL_ListView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(LONG)getSwellStyle { return style; } - --(void)setSwellStyle:(LONG)st -{ - bool hdrchg= ((style&LVS_NOCOLUMNHEADER) != (st&LVS_NOCOLUMNHEADER)); - style=st; - if ((style&LVS_REPORT) && hdrchg) - { - // todo some crap with NSTableView::setHeaderView, but it's complicated - } -} - --(id) init -{ - if ((self = [super init])) - { - m_selColors=0; - m_fgColor = 0; - ownermode_cnt=0; - m_status_imagelist_type=-1; - m_status_imagelist=0; - m_leftmousemovecnt=0; - m_fakerightmouse=false; - m_lbMode=0; - m_fastClickMask=0; - m_start_item=-1; - m_start_subitem=-1; - m_start_item_clickmode=0; // 0=clicked item, 1=clicked image, &2=sent drag message, &4=quickclick mode - m_cols = new WDL_PtrList; - m_items=new WDL_PtrList; - } - return self; -} --(void) dealloc -{ - if (m_items) m_items->Empty(true); - delete m_items; - delete m_cols; - m_cols=0; - m_items=0; - [m_fgColor release]; - [m_selColors release]; - [super dealloc]; -} - --(int)getColumnPos:(int)idx // get current position of column that was originally at idx -{ - int pos=idx; - if (m_cols) - { - NSTableColumn* col=m_cols->Get(idx); - if (col) - { - NSArray* arr=[self tableColumns]; - if (arr) - { - pos=[arr indexOfObject:col]; - } - } - } - return pos; -} - -- (void)highlightSelectionInClipRect:(NSRect)theClipRect -{ - if (m_selColors) - { - int a = GetFocus() == (HWND)self ? 0 : 2; - if ([m_selColors count] >= a) - { - NSColor *c=[m_selColors objectAtIndex:a]; - if (c) - { - // calculate rect of selected items, combine with theClipRect, and fill these areas with our background (phew!) - bool needfillset=true; - int x = [self rowAtPoint:NSMakePoint(0,theClipRect.origin.y)]; - if (x<0)x=0; - int n = [self numberOfRows]; - for (;x = theClipRect.origin.y + theClipRect.size.height) break; - - if ([self isRowSelected:x]) - { - r = NSIntersectionRect(r,theClipRect); - if (r.size.height>0 && r.size.width>0) - { - if (needfillset) { needfillset=false; [c setFill]; } - NSRectFill(r); - } - } - } - return ; - } - } - } - return [super highlightSelectionInClipRect:theClipRect]; -} --(int)getColumnIdx:(int)pos // get original index of column that is currently at position -{ - int idx=pos; - NSArray* arr=[self tableColumns]; - if (arr && pos>=0 && pos < [arr count]) - { - NSTableColumn* col=[arr objectAtIndex:pos]; - if (col && m_cols) - { - idx=m_cols->Find(col); - } - } - return idx; -} - --(int)columnAtPoint:(NSPoint)pt -{ - int pos=[super columnAtPoint:pt]; - return [self getColumnIdx:pos]; -} - - -- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView -{ - return (!m_lbMode && (style & LVS_OWNERDATA)) ? ownermode_cnt : (m_items ? m_items->GetSize():0); -} - -- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex -{ - NSString *str=NULL; - int image_idx=0; - - if (!m_lbMode && (style & LVS_OWNERDATA)) - { - HWND tgt=(HWND)[self target]; - - char buf[1024]; - NMLVDISPINFO nm={{(HWND)self, [self tag], LVN_GETDISPINFO}}; - nm.item.mask=LVIF_TEXT; - if (m_status_imagelist_type==LVSIL_STATE) nm.item.mask |= LVIF_STATE; - else if (m_status_imagelist_type == LVSIL_SMALL) nm.item.mask |= LVIF_IMAGE; - nm.item.iImage = -1; - nm.item.iItem=rowIndex; - nm.item.iSubItem=m_cols->Find(aTableColumn); - nm.item.pszText=buf; - nm.item.cchTextMax=sizeof(buf)-1; - buf[0]=0; - SendMessage(tgt,WM_NOTIFY,[self tag],(LPARAM)&nm); - - if (m_status_imagelist_type == LVSIL_STATE) image_idx=(nm.item.state>>16)&0xff; - else if (m_status_imagelist_type == LVSIL_SMALL) image_idx = nm.item.iImage + 1; - str=(NSString *)SWELL_CStringToCFString(nm.item.pszText); - } - else - { - char *p=NULL; - SWELL_ListView_Row *r=0; - if (m_items && m_cols && (r=m_items->Get(rowIndex))) - { - p=r->m_vals.Get(m_cols->Find(aTableColumn)); - if (m_status_imagelist_type == LVSIL_STATE || m_status_imagelist_type == LVSIL_SMALL) - { - image_idx=r->m_imageidx; - } - } - - str=(NSString *)SWELL_CStringToCFString(p); - - if (style & LBS_OWNERDRAWFIXED) - { - SWELL_ODListViewCell *cell=[aTableColumn dataCell]; - if ([cell isKindOfClass:[SWELL_ODListViewCell class]]) [cell setItemIdx:rowIndex]; - } - } - - if (!m_lbMode && m_status_imagelist) - { - SWELL_StatusCell *cell=(SWELL_StatusCell*)[aTableColumn dataCell]; - if ([cell isKindOfClass:[SWELL_StatusCell class]]) - { - HICON icon=m_status_imagelist->Get(image_idx-1); - NSImage *img=NULL; - if (icon) img=(NSImage *)GetNSImageFromHICON(icon); - [cell setStatusImage:img]; - } - } - - return [str autorelease]; - -} - - --(void)mouseDown:(NSEvent *)theEvent -{ - if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) - { - m_fakerightmouse=1; - m_start_item=-1; - m_start_subitem=-1; - } - else - { - m_leftmousemovecnt=0; - m_fakerightmouse=0; - - NSPoint pt=[theEvent locationInWindow]; - pt=[self convertPoint:pt fromView:nil]; - m_start_item=[self rowAtPoint:pt]; - m_start_subitem=[self columnAtPoint:pt]; - - - - m_start_item_clickmode=0; - if (m_start_item >=0 && (m_fastClickMask&(1<Get(nmlv.iItem); - if (row) - nmlv.lParam = row->m_param; - SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); - m_start_item_clickmode=4; - } - else - { - if (m_start_item>=0 && m_status_imagelist && LVSIL_STATE == m_status_imagelist_type && pt.x <= [self rowHeight]) // in left area - { - m_start_item_clickmode=1; - } - } - } -} - --(void)mouseDragged:(NSEvent *)theEvent -{ - if (++m_leftmousemovecnt==4) - { - if (m_start_item>=0 && !(m_start_item_clickmode&3)) - { - if (!m_lbMode) - { - // if m_start_item isnt selected, change selection to it now - if (!(m_start_item_clickmode&4) && ![self isRowSelected:m_start_item]) - { - [self selectRowIndexes:[NSIndexSet indexSetWithIndex:m_start_item] byExtendingSelection:!!(GetAsyncKeyState(VK_CONTROL)&0x8000)]; - } - NMLISTVIEW hdr={{(HWND)self,[self tag],LVN_BEGINDRAG},m_start_item,m_start_subitem,0,}; - SendMessage((HWND)[self target],WM_NOTIFY,[self tag], (LPARAM) &hdr); - m_start_item_clickmode |= 2; - } - } - } - else if (m_leftmousemovecnt > 4 && !(m_start_item_clickmode&1)) - { - HWND tgt=(HWND)[self target]; - POINT p; - GetCursorPos(&p); - ScreenToClient(tgt,&p); - - SendMessage(tgt,WM_MOUSEMOVE,0,(p.x&0xffff) + (((int)p.y)<<16)); - } -} - --(void)mouseUp:(NSEvent *)theEvent -{ - if (m_fakerightmouse||([theEvent modifierFlags] & NSControlKeyMask)) - { - [self rightMouseUp:theEvent]; - } - else if (!(m_start_item_clickmode&1)) - { - if (m_leftmousemovecnt>=0 && m_leftmousemovecnt<4 && !(m_start_item_clickmode&4)) - { - if (m_lbMode && ![self allowsMultipleSelection]) // listboxes --- allow clicking to reset the selection - { - [self deselectAll:self]; - } - [super mouseDown:theEvent]; - [super mouseUp:theEvent]; - } - else if (m_leftmousemovecnt>=4) - { - HWND tgt=(HWND)[self target]; - POINT p; - GetCursorPos(&p); - ScreenToClient(tgt,&p); - SendMessage(tgt,WM_LBUTTONUP,0,(p.x&0xffff) + (((int)p.y)<<16)); - } - } - - if (!m_lbMode && !(m_start_item_clickmode&(2|4))) - { - NSPoint pt=[theEvent locationInWindow]; - pt=[self convertPoint:pt fromView:nil]; - int col = [self columnAtPoint:pt]; - NMLISTVIEW nmlv={{(HWND)self,[self tag], NM_CLICK}, [self rowAtPoint:pt], col, 0, 0, 0, {(int)floor(pt.x), (int)floor(pt.y)}, }; - SWELL_ListView_Row *row=m_items->Get(nmlv.iItem); - if (row) nmlv.lParam = row->m_param; - SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); - } -} - -- (void)rightMouseUp:(NSEvent *)theEvent -{ - bool wantContext=true; - - if (!m_lbMode) - { - NSPoint pt=[theEvent locationInWindow]; - pt=[self convertPoint:pt fromView:nil]; - - // note, windows selects on right mousedown - int row=[self rowAtPoint:pt]; - if (row >= 0 && ![self isRowSelected:row]) - { - NSIndexSet* rows=[NSIndexSet indexSetWithIndex:row]; - [self deselectAll:self]; - [self selectRowIndexes:rows byExtendingSelection:NO]; - } - - NMLISTVIEW nmlv={{(HWND)self,[self tag], NM_RCLICK}, [self rowAtPoint:pt], [self columnAtPoint:pt], 0, 0, 0, {(int)floor(pt.x), (int)floor(pt.y)}, }; - if (SendMessage((HWND)[self target],WM_NOTIFY,nmlv.hdr.idFrom,(LPARAM)&nmlv)) wantContext=false; - } - if (wantContext) - { - POINT p; - GetCursorPos(&p); - SendMessage((HWND)[self target],WM_CONTEXTMENU,(WPARAM)self,(p.x&0xffff)|(p.y<<16)); - } - m_fakerightmouse=0; -} - --(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam -{ - HWND hwnd=(HWND)self; - switch (msg) - { - case LB_RESETCONTENT: - ownermode_cnt=0; - if (m_items) - { - m_items->Empty(true); - [self reloadData]; - } - return 0; - case LB_ADDSTRING: - case LB_INSERTSTRING: - { - int cnt=ListView_GetItemCount(hwnd); - if (msg == LB_ADDSTRING && (style & LBS_SORT)) - { - SWELL_ListView *tv=(SWELL_ListView*)hwnd; - if (tv->m_lbMode && tv->m_items) - { - cnt=ptrlist_bsearch_mod((char *)lParam,tv->m_items,_listviewrowSearchFunc,NULL); - } - } - if (msg==LB_ADDSTRING) wParam=cnt; - else if (wParam > cnt) wParam=cnt; - LVITEM lvi={LVIF_TEXT,wParam,0,0,0,(char *)lParam}; - ListView_InsertItem(hwnd,&lvi); - } - return wParam; - case LB_GETCOUNT: return ListView_GetItemCount(hwnd); - case LB_SETSEL: - ListView_SetItemState(hwnd, lParam,wParam ? LVIS_SELECTED : 0,LVIS_SELECTED); - return 0; - case LB_GETTEXT: - if (lParam) - { - ListView_GetItemText(hwnd,wParam,0,(char *)lParam,4096); - } - return 0; - case LB_GETSEL: - return !!(ListView_GetItemState(hwnd,wParam,LVIS_SELECTED)&LVIS_SELECTED); - case LB_GETCURSEL: - return [self selectedRow]; - case LB_SETCURSEL: - { - if (wParamGet(wParam); - if (row) return row->m_param; - } - } - return 0; - case LB_SETITEMDATA: - { - if (m_items) - { - SWELL_ListView_Row *row=m_items->Get(wParam); - if (row) row->m_param=lParam; - } - } - return 0; - case LB_GETSELCOUNT: - return [[self selectedRowIndexes] count]; - case LB_DELETESTRING: - ListView_DeleteItem((HWND)self, wParam); - return 0; - } - return 0; -} - --(int)getSwellNotificationMode -{ - return m_lbMode; -} --(void)setSwellNotificationMode:(int)lbMode -{ - m_lbMode=lbMode; -} - --(void)onSwellCommand:(int)cmd -{ - // ignore commands -} - -@end - - -@implementation SWELL_ODButtonCell -- (BOOL)isTransparent -{ - return YES; -} -- (BOOL)isOpaque -{ - return NO; -} - -- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView -{ - NSView *ctl=[self controlView]; - if (!ctl) { [super drawWithFrame:cellFrame inView:controlView]; return; } - - HDC hdc=GetDC((HWND)controlView); - if (hdc) - { - HWND notWnd = GetParent((HWND)ctl); - RECT r={(int)(cellFrame.origin.x+0.5),(int)(cellFrame.origin.y+0.5)}; - r.right=r.left+(int)(cellFrame.size.width+0.5); - r.bottom=r.top+(int)(cellFrame.size.height+0.5); - DRAWITEMSTRUCT dis={ODT_BUTTON,[ctl tag],0,0,0,(HWND)ctl,hdc,{0,},0}; - dis.rcItem = r; - SendMessage(notWnd,WM_DRAWITEM,dis.CtlID,(LPARAM)&dis); - - ReleaseDC((HWND)controlView,hdc); - } - -} -@end - -@implementation SWELL_ODListViewCell --(void)setOwnerControl:(SWELL_ListView *)t { m_ownctl=t; m_lastidx=0; } --(void)setItemIdx:(int)idx -{ - m_lastidx=idx; -} -- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView -{ - if (!m_ownctl) { [super drawInteriorWithFrame:cellFrame inView:controlView]; return; } - - int itemidx=m_lastidx; - int itemData=0; // todo: get itemData - SWELL_ListView_Row *row=m_ownctl->m_items->Get(itemidx); - if (row) itemData=row->m_param; - - HDC hdc=GetDC((HWND)controlView); - if (hdc) - { - HWND notWnd = GetParent((HWND)m_ownctl); - RECT r={(int)(cellFrame.origin.x+0.5),(int)(cellFrame.origin.y+0.5)}; - r.right=r.left+(int)(cellFrame.size.width+0.5); - r.bottom=r.top+(int)(cellFrame.size.height+0.5); - DRAWITEMSTRUCT dis={ODT_LISTBOX,[m_ownctl tag],itemidx,0,0,(HWND)m_ownctl,hdc,{0,},itemData}; - dis.rcItem = r; - SendMessage(notWnd,WM_DRAWITEM,dis.CtlID,(LPARAM)&dis); - - ReleaseDC((HWND)controlView,hdc); - } -} - - -@end - - - - - -HWND GetDlgItem(HWND hwnd, int idx) -{ - if (!hwnd) return 0; - - NSView *v=0; - id pid=(id)hwnd; - if ([pid isKindOfClass:[NSWindow class]]) v=[((NSWindow *)pid) contentView]; - else if ([pid isKindOfClass:[NSView class]]) v=(NSView *)pid; - - if (!idx || !v) return (HWND)v; - - SWELL_BEGIN_TRY - - NSArray *ar = [v subviews]; - int n=[ar count]; - int x; - for (x=0;xhwnd && [rec->hwnd respondsToSelector:@selector(swellSetOwner:)]) - [(SWELL_ModelessWindow *)rec->hwnd swellSetOwner:(id)bla]; - rec=rec->_next; - } - } - } - } - // move all child and owned windows over to new window - NSArray *ar=[oldw childWindows]; - if (ar) - { - int x; - for (x = 0; x < [ar count]; x ++) - { - NSWindow *cw=[ar objectAtIndex:x]; - if (cw) - { - [cw retain]; - [oldw removeChildWindow:cw]; - [(NSWindow *)bla addChildWindow:cw ordered:NSWindowAbove]; - [cw release]; - - - } - } - } - - if (oldpar) [oldpar addChildWindow:(NSWindow *)bla ordered:NSWindowAbove]; - if (oldtitle[0]) SetWindowText(hwnd,oldtitle); - - [(NSWindow *)bla setFrame:fr display:dovis]; - [(NSWindow *)bla setLevel:oldlevel]; - if (dovis) ShowWindow(bla,SW_SHOW); - - DestroyWindow((HWND)oldw); - } - else - { - [oldw setContentView:tv]; - [tv release]; - } - - } - } - } - return 0; - } - - - if ([pid respondsToSelector:@selector(setSwellExtraData:value:)]) - { - LONG_PTR ov=0; - if ([pid respondsToSelector:@selector(getSwellExtraData:)]) ov=(LONG_PTR)[pid getSwellExtraData:idx]; - - [pid setSwellExtraData:idx value:val]; - - return ov; - } - - SWELL_END_TRY(;) - return 0; -} - -LONG_PTR GetWindowLong(HWND hwnd, int idx) -{ - if (!hwnd) return 0; - id pid=(id)hwnd; - - SWELL_BEGIN_TRY - - if (idx==GWL_EXSTYLE && [pid respondsToSelector:@selector(swellGetExtendedStyle)]) - { - return (LONG_PTR)[pid swellGetExtendedStyle]; - } - - if (idx==GWL_USERDATA && [pid respondsToSelector:@selector(getSwellUserData)]) - { - return (LONG_PTR)[pid getSwellUserData]; - } - if (idx==GWL_USERDATA && [pid isKindOfClass:[NSText class]]) - { - return 0xdeadf00b; - } - - if (idx==GWL_ID && [pid respondsToSelector:@selector(tag)]) - return [pid tag]; - - - if (idx==GWL_WNDPROC && [pid respondsToSelector:@selector(getSwellWindowProc)]) - { - return (LONG_PTR)[pid getSwellWindowProc]; - } - if (idx==DWL_DLGPROC && [pid respondsToSelector:@selector(getSwellDialogProc)]) - { - return (LONG_PTR)[pid getSwellDialogProc]; - } - if (idx==GWL_STYLE) - { - int ret=0; - if ([pid respondsToSelector:@selector(getSwellStyle)]) - { - return (LONG_PTR)[pid getSwellStyle]; - } - - if ([pid isKindOfClass:[NSButton class]]) - { - int tmp; - if ([pid allowsMixedState]) ret |= BS_AUTO3STATE; - else if ([pid isKindOfClass:[SWELL_Button class]] && (tmp = (int)[pid swellGetRadioFlags])) - { - ret |= BS_AUTORADIOBUTTON; - if (tmp&2) ret|=WS_GROUP; - } - else ret |= BS_AUTOCHECKBOX; - } - - if ([pid isKindOfClass:[NSView class]]) - { - if ([[pid window] contentView] != pid) ret |= WS_CHILDWINDOW; - else - { - unsigned int smask =[[pid window] styleMask]; - if (smask & NSTitledWindowMask) - { - ret|=WS_CAPTION; - if (smask & NSResizableWindowMask) ret|=WS_THICKFRAME; - } - } - } - - return ret; - } - if ([pid respondsToSelector:@selector(getSwellExtraData:)]) - { - return (LONG_PTR)[pid getSwellExtraData:idx]; - } - - SWELL_END_TRY(;) - return 0; -} - -static bool IsWindowImpl(NSView *ch, NSView *par) -{ - if (!par || ![par isKindOfClass:[NSView class]]) return false; - - NSArray *ar = [par subviews]; - if (!ar) return false; - [ar retain]; - int x,n=[ar count]; - for (x=0;xtype != TYPE_BITMAP) return 0; - return i->bitmapptr; -} - - -@implementation SWELL_Button : NSButton - -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(id) init { - self = [super init]; - if (self != nil) { - m_userdata=0; - m_swellGDIimage=0; - m_radioflags=0; - } - return self; -} --(int)swellGetRadioFlags { return m_radioflags; } --(void)swellSetRadioFlags:(int)f { m_radioflags=f; } --(LONG_PTR)getSwellUserData { return m_userdata; } --(void)setSwellUserData:(LONG_PTR)val { m_userdata=val; } - --(void)setSwellGDIImage:(void *)par -{ - m_swellGDIimage=par; -} --(void *)getSwellGDIImage -{ - return m_swellGDIimage; -} - -@end - -LRESULT SendMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!hwnd) return 0; - - SWELL_BEGIN_TRY - id obj=(id)hwnd; - if ([obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - { - return (LRESULT) [obj onSwellMessage:msg p1:wParam p2:lParam]; - } - else - { - if (msg == BM_GETCHECK && [obj isKindOfClass:[NSButton class]]) - { - int a=[(NSButton*)obj state]; - if (a==NSMixedState) return BST_INDETERMINATE; - return a!=NSOffState; - } - if (msg == BM_SETCHECK && [obj isKindOfClass:[NSButton class]]) - { - [(NSButton*)obj setState:(wParam&BST_INDETERMINATE)?NSMixedState:((wParam&BST_CHECKED)?NSOnState:NSOffState)]; - return 0; - } - if ((msg==BM_GETIMAGE || msg == BM_SETIMAGE) && [obj isKindOfClass:[SWELL_Button class]]) - { - if (wParam != IMAGE_BITMAP && wParam != IMAGE_ICON) return 0; // ignore unknown types - LONG_PTR ret=(LONG_PTR) (void *)[obj getSwellGDIImage]; - if (msg==BM_SETIMAGE) - { - NSImage *img=NULL; - if (lParam) img=(NSImage *)__GetNSImageFromHICON((HICON)lParam); - [obj setImage:img]; - [obj setSwellGDIImage:(void *)(img?lParam:0)]; - } - return ret; - } - else if (msg >= CB_ADDSTRING && msg <= CB_INITSTORAGE && ([obj isKindOfClass:[NSPopUpButton class]] || [obj isKindOfClass:[NSComboBox class]])) - { - switch (msg) - { - case CB_ADDSTRING: return SWELL_CB_AddString(hwnd,0,(char*)lParam); - case CB_DELETESTRING: SWELL_CB_DeleteString(hwnd,0,wParam); return 1; - case CB_GETCOUNT: return SWELL_CB_GetNumItems(hwnd,0); - case CB_GETCURSEL: return SWELL_CB_GetCurSel(hwnd,0); - case CB_GETLBTEXT: return SWELL_CB_GetItemText(hwnd,0,wParam,(char *)lParam, 1024); - case CB_INSERTSTRING: return SWELL_CB_InsertString(hwnd,0,wParam,(char *)lParam); - case CB_RESETCONTENT: SWELL_CB_Empty(hwnd,0); return 0; - case CB_SETCURSEL: SWELL_CB_SetCurSel(hwnd,0,wParam); return 0; - case CB_GETITEMDATA: return SWELL_CB_GetItemData(hwnd,0,wParam); - case CB_SETITEMDATA: SWELL_CB_SetItemData(hwnd,0,wParam,lParam); return 0; - case CB_FINDSTRING: - case CB_FINDSTRINGEXACT: - if (lParam) return SWELL_CB_FindString(hwnd,0,(int)wParam,(const char *)lParam,msg==CB_FINDSTRINGEXACT); - return CB_ERR; - case CB_INITSTORAGE: return 0; - } - return 0; - } - else if (msg >= TBM_GETPOS && msg <= TBM_SETRANGE && ([obj isKindOfClass:[NSSlider class]])) - { - switch (msg) - { - case TBM_GETPOS: return SWELL_TB_GetPos(hwnd,0); - case TBM_SETTIC: SWELL_TB_SetTic(hwnd,0,lParam); return 1; - case TBM_SETPOS: SWELL_TB_SetPos(hwnd,0,lParam); return 1; - case TBM_SETRANGE: SWELL_TB_SetRange(hwnd,0,LOWORD(lParam),HIWORD(lParam)); return 1; - } - return 0; - } - else if ((msg == EM_SETSEL || msg == EM_GETSEL || msg == EM_SETPASSWORDCHAR) && ([obj isKindOfClass:[NSTextField class]])) - { - if (msg == EM_GETSEL) - { - NSRange range={0,}; - if ([[obj window] firstResponder] == obj) - { - NSText* text=[[obj window] fieldEditor:YES forObject:(NSTextField*)obj]; - if (text) range=[text selectedRange]; - } - if (wParam) *(int*)wParam=range.location; - if (lParam) *(int*)lParam=range.location+range.length; - } - else if (msg == EM_SETSEL) - { - // [(NSTextField*)obj selectText:obj]; // Force the window's text field editor onto this control - // don't force it, just ignore EM_GETSEL/EM_SETSEL if not in focus - if ([[obj window] firstResponder] == obj) - { - NSText* text = [[obj window] fieldEditor:YES forObject:(NSTextField*)obj]; // then get it from the window - int sl = [[text string] length]; - if (wParam == -1) lParam = wParam = 0; - else if (lParam == -1) lParam = sl; - if (wParam>sl) wParam=sl; - if (lParam>sl) lParam=sl; - if (text) [text setSelectedRange:NSMakeRange(wParam, max(lParam-wParam,0))]; // and set the range - } - } - else if (msg == EM_SETPASSWORDCHAR) - { - // not implemented, because it requires replacing obj within its parent window - // instead caller explicitly destroy the edit control and create a new one with ES_PASSWORD - } - return 0; - } - else - { - NSWindow *w; - NSView *v; - // if content view gets unhandled message send to window - if ([obj isKindOfClass:[NSView class]] && (w=[obj window]) && [w contentView] == obj && [w respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - { - return (LRESULT) [(SWELL_hwndChild *)w onSwellMessage:msg p1:wParam p2:lParam]; - } - // if window gets unhandled message send to content view - else if ([obj isKindOfClass:[NSWindow class]] && (v=[obj contentView]) && [v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - { - return (LRESULT) [(SWELL_hwndChild *)v onSwellMessage:msg p1:wParam p2:lParam]; - } - } - } - SWELL_END_TRY(;) - return 0; -} - -void DestroyWindow(HWND hwnd) -{ - if (!hwnd) return; - SWELL_BEGIN_TRY - id pid=(id)hwnd; - if ([pid isKindOfClass:[NSView class]]) - { - KillTimer(hwnd,~(UINT_PTR)0); - sendSwellMessage((id)pid,WM_DESTROY,0,0); - - NSWindow *pw = [(NSView *)pid window]; - if (pw && [pw contentView] == pid) // destroying contentview should destroy top level window - { - DestroyWindow((HWND)pw); - } - else - { - if (pw && [NSApp keyWindow] == pw) - { - id foc=[pw firstResponder]; - if (foc && (foc == pid || IsChild((HWND)pid,(HWND)foc))) - { - HWND h=GetParent((HWND)pid); - if (h) SetFocus(h); - } - } - [(NSView *)pid removeFromSuperview]; - } - } - else if ([pid isKindOfClass:[NSWindow class]]) - { - KillTimer(hwnd,~(UINT_PTR)0); - sendSwellMessage([(id)pid contentView],WM_DESTROY,0,0); - sendSwellMessage((id)pid,WM_DESTROY,0,0); - - if ([(id)pid respondsToSelector:@selector(swellDoDestroyStuff)]) - [(id)pid swellDoDestroyStuff]; - - NSWindow *par=[(NSWindow*)pid parentWindow]; - if (par) - { - [par removeChildWindow:(NSWindow*)pid]; - } - [(NSWindow *)pid close]; // this is probably bad, but close takes too long to close! - } - SWELL_END_TRY(;) -} - -void EnableWindow(HWND hwnd, int enable) -{ - if (!hwnd) return; - SWELL_BEGIN_TRY - id bla=(id)hwnd; - if ([bla isKindOfClass:[NSWindow class]]) bla = [bla contentView]; - - if (bla && [bla respondsToSelector:@selector(setEnabled:)]) - { - [bla setEnabled:(enable?YES:NO)]; - if ([bla isKindOfClass:[SWELL_TextField class]]) - { - NSTextField* txt = (NSTextField*)bla; - if (![txt isEditable] && ![txt isBordered] && ![txt drawsBackground]) // looks like a static text control - { - NSColor* col = [txt textColor]; - float alpha = (enable ? 1.0f : 0.5f); - [txt setTextColor:[col colorWithAlphaComponent:alpha]]; - } - } - } - SWELL_END_TRY(;) -} - -void SetForegroundWindow(HWND hwnd) -{ - SetFocus(hwnd); -} - -void SetFocus(HWND hwnd) // these take NSWindow/NSView, and return NSView * -{ - id r=(id) hwnd; - if (!r) return; - - SWELL_BEGIN_TRY - if ([r isKindOfClass:[NSWindow class]]) - { - [(NSWindow *)r makeFirstResponder:[(NSWindow *)r contentView]]; - if ([(NSWindow *)r isVisible]) [(NSWindow *)r makeKeyAndOrderFront:nil]; - } - else if ([r isKindOfClass:[NSView class]]) - { - NSWindow *wnd=[(NSView *)r window]; - if (wnd) - { - [wnd makeFirstResponder:r]; - if ([wnd isVisible]) - { - [wnd makeKeyAndOrderFront:nil]; - } - } - } - SWELL_END_TRY(;) -} - -void SWELL_GetViewPort(RECT *r, RECT *sourcerect, bool wantWork) -{ - SWELL_BEGIN_TRY - - NSArray *ar=[NSScreen screens]; - - int cnt=[ar count]; - int x; - int cx=0; - int cy=0; - if (sourcerect) - { - cx=(sourcerect->left+sourcerect->right)/2; - cy=(sourcerect->top+sourcerect->bottom)/2; - } - for (x = 0; x < cnt; x ++) - { - NSScreen *sc=[ar objectAtIndex:x]; - if (sc) - { - NSRect tr=wantWork ? [sc visibleFrame] : [sc frame]; - if (!x || (cx >= tr.origin.x && cx < tr.origin.x+tr.size.width && - cy >= tr.origin.y && cy < tr.origin.y+tr.size.height)) - { - r->left=(int)tr.origin.x; - r->right=(int)(tr.origin.x+tr.size.width+0.5); - r->top=(int)tr.origin.y; - r->bottom=(int)(tr.origin.y+tr.size.height+0.5); - } - } - } - if (!cnt) - { - r->left=r->top=0; - r->right=1600; - r->bottom=1200; - } - SWELL_END_TRY(;) -} - -void ScreenToClient(HWND hwnd, POINT *p) -{ - if (!hwnd) return; - // no need to try/catch, this should never have an issue *wince* - - id ch=(id)hwnd; - if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; - if (!ch || ![ch isKindOfClass:[NSView class]]) return; - - NSWindow *window=[ch window]; - - NSPoint wndpt = [window convertScreenToBase:NSMakePoint(p->x,p->y)]; - - // todo : WM_NCCALCSIZE - NSPoint po = [ch convertPoint:wndpt fromView:nil]; - - p->x=(int)(po.x+0.5); - p->y=(int)(po.y+0.5); -} - -void ClientToScreen(HWND hwnd, POINT *p) -{ - if (!hwnd) return; - - id ch=(id)hwnd; - if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; - if (!ch || ![ch isKindOfClass:[NSView class]]) return; - - NSWindow *window=[ch window]; - - NSPoint wndpt = [ch convertPoint:NSMakePoint(p->x,p->y) toView:nil]; - - NSPoint po = [window convertBaseToScreen:wndpt]; - // todo : WM_NCCALCSIZE - - p->x=(int)(po.x+0.5); - p->y=(int)(po.y+0.5); -} - -static NSView *NavigateUpScrollClipViews(NSView *ch) -{ - NSView *par=[ch superview]; - if (par && [par isKindOfClass:[NSClipView class]]) - { - par=[par superview]; - if (par && [par isKindOfClass:[NSScrollView class]]) - { - ch=par; - } - } - return ch; -} - -HWND SWELL_NavigateUpScrollClipViews(HWND h) -{ - NSView *v = 0; - if (h && [(id)h isKindOfClass:[NSView class]]) v = (NSView *)h; - else if (h && [(id)h isKindOfClass:[NSWindow class]]) v = [(NSWindow *)h contentView]; - if (v) - return (HWND)NavigateUpScrollClipViews(v); - return 0; -} - -bool GetWindowRect(HWND hwnd, RECT *r) -{ - r->left=r->top=r->right=r->bottom=0; - if (!hwnd) return false; - - SWELL_BEGIN_TRY - - id ch=(id)hwnd; - NSWindow *nswnd; - if ([ch isKindOfClass:[NSView class]] && (nswnd=[(NSView *)ch window]) && [nswnd contentView]==ch) - ch=nswnd; - - if ([ch isKindOfClass:[NSWindow class]]) - { - NSRect b=[ch frame]; - r->left=(int)(b.origin.x); - r->top=(int)(b.origin.y); - r->right = (int)(b.origin.x+b.size.width+0.5); - r->bottom= (int)(b.origin.y+b.size.height+0.5); - return true; - } - if (![ch isKindOfClass:[NSView class]]) return false; - ch=NavigateUpScrollClipViews(ch); - NSRect b=[ch bounds]; - r->left=(int)(b.origin.x); - r->top=(int)(b.origin.y); - r->right = (int)(b.origin.x+b.size.width+0.5); - r->bottom= (int)(b.origin.y+b.size.height+0.5); - ClientToScreen((HWND)ch,(POINT *)r); - ClientToScreen((HWND)ch,((POINT *)r)+1); - SWELL_END_TRY(return false;) - - return true; -} - -void GetWindowContentViewRect(HWND hwnd, RECT *r) -{ - SWELL_BEGIN_TRY - NSWindow *nswnd; - if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)hwnd window]) && [nswnd contentView]==(id)hwnd) - hwnd=(HWND)nswnd; - - if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) - { - NSView *ch=[(id)hwnd contentView]; - NSRect b=[ch bounds]; - r->left=(int)(b.origin.x); - r->top=(int)(b.origin.y); - r->right = (int)(b.origin.x+b.size.width+0.5); - r->bottom= (int)(b.origin.y+b.size.height+0.5); - ClientToScreen(hwnd,(POINT *)r); - ClientToScreen(hwnd,((POINT *)r)+1); - } - else GetWindowRect(hwnd,r); - SWELL_END_TRY(;) -} - - -void GetClientRect(HWND hwnd, RECT *r) -{ - r->left=r->top=r->right=r->bottom=0; - if (!hwnd) return; - - SWELL_BEGIN_TRY - id ch=(id)hwnd; - if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; - if (!ch || ![ch isKindOfClass:[NSView class]]) return; - ch=NavigateUpScrollClipViews(ch); - - NSRect b=[ch bounds]; - r->left=(int)(b.origin.x); - r->top=(int)(b.origin.y); - r->right = (int)(b.origin.x+b.size.width+0.5); - r->bottom= (int)(b.origin.y+b.size.height+0.5); - - // todo this may need more attention - RECT tr=*r; - SendMessage(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&tr); - r->right = r->left + (tr.right-tr.left); - r->bottom = r->top + (tr.bottom-tr.top); - SWELL_END_TRY(;) -} - - - -void SetWindowPos(HWND hwnd, HWND hwndAfter, int x, int y, int cx, int cy, int flags) -{ - if (!hwnd) return; - - SWELL_BEGIN_TRY - NSWindow *nswnd; // content views = move window - if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)hwnd window]) && [nswnd contentView]==(id)hwnd) - hwnd=(HWND)nswnd; - - // todo: handle SWP_SHOWWINDOW - id ch=(id)hwnd; - bool isview=false; - if ([ch isKindOfClass:[NSWindow class]] || (isview=[ch isKindOfClass:[NSView class]])) - { - if (isview) - { - ch=NavigateUpScrollClipViews(ch); - if (isview && !(flags&SWP_NOZORDER)) - { - NSView *v = (NSView *)ch; - NSView *par = [v superview]; - NSArray *subs = [par subviews]; - int idx = [subs indexOfObjectIdenticalTo:v], cnt=[subs count]; - - NSView *viewafter = NULL; - NSWindowOrderingMode omode = NSWindowAbove; - - if (cnt>1 && hwndAfter != (HWND)ch) - { - if (hwndAfter==HWND_TOPMOST||hwndAfter==HWND_NOTOPMOST) - { - } - else if (hwndAfter == HWND_TOP) - { - if (idx0) viewafter = [subs objectAtIndex:0]; - omode = NSWindowBelow; - } - else - { - NSInteger a=[subs indexOfObjectIdenticalTo:(NSView *)hwndAfter]; - if (a != NSNotFound && a != (idx-1)) viewafter = (NSView *)hwndAfter; - } - } - - if (viewafter) - { - HWND h = GetCapture(); - if (!h || (h!=(HWND)v && !IsChild((HWND)v,h))) // if this window is captured don't reorder! - { - NSView *oldfoc = (NSView*)[[v window] firstResponder]; - if (!oldfoc || ![oldfoc isKindOfClass:[NSView class]] || - (oldfoc != v && ![oldfoc isDescendantOf:v])) oldfoc=NULL; - - // better way to do this? maybe :/ - [v retain]; - [v removeFromSuperviewWithoutNeedingDisplay]; - [par addSubview:v positioned:omode relativeTo:viewafter]; - [v release]; - - if (oldfoc) [[v window] makeFirstResponder:oldfoc]; - } - } - } - } - NSRect f=[ch frame]; - bool repos=false; - if (!(flags&SWP_NOMOVE)) - { - f.origin.x=(float)x; - f.origin.y=(float)y; - repos=true; - } - if (!(flags&SWP_NOSIZE)) - { - f.size.width=(float)cx; - f.size.height=(float)cy; - if (f.size.height<0)f.size.height=-f.size.height; - repos=true; - } - if (repos) - { - if (!isview) - { - NSSize mins=[ch minSize]; - NSSize maxs=[ch maxSize]; - if (f.size.width < mins.width) f.size.width=mins.width; - else if (f.size.width > maxs.width) f.size.width=maxs.width; - if (f.size.height < mins.height) f.size.height=mins.height; - else if (f.size.height> maxs.height) f.size.height=maxs.height; - [ch setFrame:f display:NO]; - [ch display]; - } - else - { - // this doesnt seem to actually be a good idea anymore - // if ([[ch window] contentView] != ch && ![[ch superview] isFlipped]) -// f.origin.y -= f.size.height; - [ch setFrame:f]; - if ([ch isKindOfClass:[NSScrollView class]]) - { - NSView *cv=[ch documentView]; - if (cv && [cv isKindOfClass:[NSTextView class]]) - { - NSRect fr=[cv frame]; - NSSize sz=[ch contentSize]; - int a=0; - if (![ch hasHorizontalScroller]) {a ++; fr.size.width=sz.width; } - if (![ch hasVerticalScroller]) { a++; fr.size.height=sz.height; } - if (a) [cv setFrame:fr]; - } - } - } - } - return; - } - SWELL_END_TRY(;) -} - - -HWND GetWindow(HWND hwnd, int what) -{ - if (!hwnd) return 0; - SWELL_BEGIN_TRY - - if ([(id)hwnd isKindOfClass:[NSWindow class]]) hwnd=(HWND)[(id)hwnd contentView]; - if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return 0; - - NSView *v=(NSView *)hwnd; - if (what == GW_CHILD) - { - NSArray *ar=[v subviews]; - if (ar && [ar count]>0) - { - return (HWND)[ar objectAtIndex:0]; - } - return 0; - } - if (what == GW_OWNER) - { - v=NavigateUpScrollClipViews(v); - if ([[v window] contentView] == v) - { - if ([[v window] respondsToSelector:@selector(swellGetOwner)]) - { - return (HWND)[(SWELL_ModelessWindow*)[v window] swellGetOwner]; - } - return 0; - } - return (HWND)[v superview]; - } - - if (what >= GW_HWNDFIRST && what <= GW_HWNDPREV) - { - v=NavigateUpScrollClipViews(v); - if ([[v window] contentView] == v) - { - if (what <= GW_HWNDLAST) return (HWND)hwnd; // content view is only window - - return 0; // we're the content view so cant do next/prev - } - NSView *par=[v superview]; - if (par) - { - NSArray *ar=[par subviews]; - int cnt; - if (ar && (cnt=[ar count]) > 0) - { - if (what == GW_HWNDFIRST) - return (HWND)[ar objectAtIndex:0]; - if (what == GW_HWNDLAST) - return (HWND)[ar objectAtIndex:(cnt-1)]; - - NSInteger idx=[ar indexOfObjectIdenticalTo:v]; - if (idx == NSNotFound) return 0; - - if (what==GW_HWNDNEXT) idx++; - else if (what==GW_HWNDPREV) idx--; - - if (idx<0 || idx>=cnt) return 0; - - return (HWND)[ar objectAtIndex:idx]; - } - } - return 0; - } - SWELL_END_TRY(;) - return 0; -} - - -HWND GetParent(HWND hwnd) -{ - SWELL_BEGIN_TRY - if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) - { - hwnd=(HWND)NavigateUpScrollClipViews((NSView *)hwnd); - - NSView *cv=[[(NSView *)hwnd window] contentView]; - if (cv == (NSView *)hwnd) hwnd=(HWND)[(NSView *)hwnd window]; // passthrough to get window parent - else - { - HWND h=(HWND)[(NSView *)hwnd superview]; - return h; - } - } - - if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) - { - HWND h= (HWND)[(NSWindow *)hwnd parentWindow]; - if (h) h=(HWND)[(NSWindow *)h contentView]; - if (h) return h; - } - - if (hwnd && [(id)hwnd respondsToSelector:@selector(swellGetOwner)]) - { - HWND h= (HWND)[(SWELL_ModelessWindow *)hwnd swellGetOwner]; - if (h && [(id)h isKindOfClass:[NSWindow class]]) h=(HWND)[(NSWindow *)h contentView]; - return h; - } - - SWELL_END_TRY(;) - return 0; -} - -HWND SetParent(HWND hwnd, HWND newPar) -{ - SWELL_BEGIN_TRY - NSView *v=(NSView *)hwnd; - if (!v || ![(id)v isKindOfClass:[NSView class]]) return 0; - v=NavigateUpScrollClipViews(v); - - if ([(id)hwnd isKindOfClass:[NSView class]]) - { - NSView *tv=(NSView *)hwnd; - if ([[tv window] contentView] == tv) // if we're reparenting a contentview (aka top level window) - { - if (!newPar) return NULL; - - NSView *npv = (NSView *)newPar; - if ([npv isKindOfClass:[NSWindow class]]) npv=[(NSWindow *)npv contentView]; - if (!npv || ![npv isKindOfClass:[NSView class]]) - return NULL; - - char oldtitle[2048]; - oldtitle[0]=0; - GetWindowText(hwnd,oldtitle,sizeof(oldtitle)); - - NSWindow *oldwnd = [tv window]; - id oldown = NULL; - if ([oldwnd respondsToSelector:@selector(swellGetOwner)]) oldown=[(SWELL_ModelessWindow*)oldwnd swellGetOwner]; - - if ([tv isKindOfClass:[SWELL_hwndChild class]]) ((SWELL_hwndChild*)tv)->m_lastTopLevelOwner = oldown; - - [tv retain]; - SWELL_hwndChild *tmpview = [[SWELL_hwndChild alloc] initChild:nil Parent:(NSView *)oldwnd dlgProc:nil Param:0]; - [tmpview release]; - - [npv addSubview:tv]; - [tv release]; - - DestroyWindow((HWND)oldwnd); // close old window since its no longer used - if (oldtitle[0]) SetWindowText(hwnd,oldtitle); - return (HWND)npv; - } - else if (!newPar) // not content view, not parent (so making it a top level modeless dialog) - { - char oldtitle[2048]; - oldtitle[0]=0; - GetWindowText(hwnd,oldtitle,sizeof(oldtitle)); - - [tv retain]; - [tv removeFromSuperview]; - - - unsigned int wf=(NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask); - if ([tv respondsToSelector:@selector(swellCreateWindowFlags)]) - wf=(unsigned int)[(SWELL_hwndChild *)tv swellCreateWindowFlags]; - - HWND newOwner=NULL; - if ([tv isKindOfClass:[SWELL_hwndChild class]]) - { - id oldown = ((SWELL_hwndChild*)tv)->m_lastTopLevelOwner; - if (oldown) - { - NSArray *ch=[NSApp windows]; - int x,n=[ch count]; - for(x=0;x=0 && wh<[p numberOfItems]) - { - [p removeItemAtIndex:wh]; - if (((SWELL_ComboBox*)p)->m_ids) ((SWELL_ComboBox*)p)->m_ids->Delete(wh); - } - } - else if ( [p isKindOfClass:[NSPopUpButton class]]) - { - NSMenu *menu = [p menu]; - if (menu) - { - if (wh >= 0 && wh < [menu numberOfItems]) - [menu removeItemAtIndex:wh]; - } - } -} - - -int SWELL_CB_FindString(HWND hwnd, int idx, int startAfter, const char *str, bool exact) -{ - NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); - if (!p) return 0; - - int pos = startAfter; - if (pos<0)pos=0; - else pos++; - - int l1len =strlen(str); - int ni=[p numberOfItems]; - - if ([p isKindOfClass:[NSComboBox class]]) - { - for(;pos= ni) return 0; - - if ([p isKindOfClass:[NSComboBox class]]) - { - NSString *s=[p itemObjectValueAtIndex:item]; - if (s) - { - SWELL_CFStringToCString(s,buf,bufsz); -// [s getCString:buf maxLength:bufsz]; - return 1; - } - } - else - { - NSMenuItem *i=[(NSPopUpButton *)p itemAtIndex:item]; - if (i) - { - NSString *s=[i title]; - if (s) - { - SWELL_CFStringToCString(s,buf,bufsz); -// [s getCString:buf maxLength:bufsz]; - return 1; - } - } - } - return 0; -} - - -int SWELL_CB_InsertString(HWND hwnd, int idx, int pos, const char *str) -{ - NSString *label=(NSString *)SWELL_CStringToCFString(str); - NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); - if (!p) return 0; - - bool isAppend=false; - int ni=[p numberOfItems]; - if (pos == -1000) - { - isAppend=true; - pos=ni; - } - else if (pos < 0) pos=0; - else if (pos > ni) pos=ni; - - - if ([p isKindOfClass:[SWELL_ComboBox class]]) - { - if (isAppend && (((int)[(SWELL_ComboBox*)p getSwellStyle]) & CBS_SORT)) - { - pos=arr_bsearch_mod(label,[p objectValues],_nsStringSearchProc); - } - - if (pos==ni) - [p addItemWithObjectValue:label]; - else - [p insertItemWithObjectValue:label atIndex:pos]; - - if (((SWELL_ComboBox*)p)->m_ids) ((SWELL_ComboBox*)p)->m_ids->Insert(pos,(char*)0); - [p setNumberOfVisibleItems:(ni+1)]; - } - else - { - NSMenu *menu = [(NSPopUpButton *)p menu]; - if (menu) - { - if (isAppend && [p respondsToSelector:@selector(getSwellStyle)] && (((int)[(SWELL_PopUpButton*)p getSwellStyle]) & CBS_SORT)) - { - pos=arr_bsearch_mod(label,[menu itemArray],_nsMenuSearchProc); - } - NSMenuItem *item=[menu insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; - [item setEnabled:YES]; - } - } - [label release]; - return pos; - -} - -int SWELL_CB_AddString(HWND hwnd, int idx, const char *str) -{ - return SWELL_CB_InsertString(hwnd,idx,-1000,str); -} - -int SWELL_CB_GetCurSel(HWND hwnd, int idx) -{ - NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); - if (!p) return -1; - return [p indexOfSelectedItem]; -} - -void SWELL_CB_SetCurSel(HWND hwnd, int idx, int item) -{ - if (item>=0 && item= [cb numberOfItems]) return; - NSMenuItem *it=[cb itemAtIndex:item]; - if (!it) return; - - SWELL_DataHold *p=[[SWELL_DataHold alloc] initWithVal:(void *)data]; - [it setRepresentedObject:p]; - [p release]; - } - else if ([cb isKindOfClass:[SWELL_ComboBox class]]) - { - if (item < 0 || item >= [cb numberOfItems]) return; - if (((SWELL_ComboBox*)cb)->m_ids) ((SWELL_ComboBox*)cb)->m_ids->Set(item,(char*)data); - } -} - -LONG_PTR SWELL_CB_GetItemData(HWND hwnd, int idx, int item) -{ - id cb=(id)GetDlgItem(hwnd,idx); - if (!cb) return 0; - if ([cb isKindOfClass:[NSPopUpButton class]]) - { - if (item < 0 || item >= [cb numberOfItems]) return 0; - NSMenuItem *it=[cb itemAtIndex:item]; - if (!it) return 0; - id p= [it representedObject]; - if (!p || ![p isKindOfClass:[SWELL_DataHold class]]) return 0; - return (LONG_PTR) (void *)[p getValue]; - } - else if ([cb isKindOfClass:[SWELL_ComboBox class]]) - { - if (item < 0 || item >= [cb numberOfItems]) return 0; - if (((SWELL_ComboBox*)cb)->m_ids) return (LONG_PTR) ((SWELL_ComboBox*)cb)->m_ids->Get(item); - } - return 0; -} - -void SWELL_CB_Empty(HWND hwnd, int idx) -{ - id cb=(id)GetDlgItem(hwnd,idx); - if (!cb) return; - if ([cb isKindOfClass:[NSPopUpButton class]] || - [cb isKindOfClass:[NSComboBox class]]) [cb removeAllItems]; - - if ([cb isKindOfClass:[SWELL_ComboBox class]]) - { - if (((SWELL_ComboBox*)cb)->m_ids) ((SWELL_ComboBox*)cb)->m_ids->Empty(); - } -} - - -BOOL SetDlgItemInt(HWND hwnd, int idx, int val, int issigned) -{ - char buf[128]; - sprintf(buf,issigned?"%d":"%u",val); - return SetDlgItemText(hwnd,idx,buf); -} - -int GetDlgItemInt(HWND hwnd, int idx, BOOL *translated, int issigned) -{ - char buf[128]; - if (!GetDlgItemText(hwnd,idx,buf,sizeof(buf))) - { - if (translated) *translated=0; - return 0; - } - char *p=buf; - while (*p == ' ' || *p == '\t') p++; - int a=atoi(p); - if ((a<0 && !issigned) || (!a && p[0] != '0')) { if (translated) *translated=0; return 0; } - if (translated) *translated=1; - return a; -} - -void SWELL_HideApp() -{ - [NSApp hide:NSApp]; -} - - -BOOL SWELL_GetGestureInfo(LPARAM lParam, GESTUREINFO* gi) -{ - if (!lParam || !gi) return FALSE; - memcpy(gi, (GESTUREINFO*)lParam, sizeof(GESTUREINFO)); - return TRUE; -} - - -void ShowWindow(HWND hwnd, int cmd) -{ - id pid=(id)hwnd; - - if (pid && [pid isKindOfClass:[NSWindow class]]) - { - if (cmd == SW_SHOWNA && [pid isKindOfClass:[SWELL_ModelessWindow class]]) - { - if (((SWELL_ModelessWindow *)pid)->m_wantInitialKeyWindowOnShow) - { - ((SWELL_ModelessWindow *)pid)->m_wantInitialKeyWindowOnShow=false; - cmd = SW_SHOW; - } - } - if (cmd==SW_SHOW) - { - [pid makeKeyAndOrderFront:pid]; - } - else if (cmd==SW_SHOWNA) - { - [pid orderFront:pid]; - } - else if (cmd==SW_HIDE) - { - [pid orderOut:pid]; - } - else if (cmd == SW_SHOWMINIMIZED) - { - // this ought to work - //if ([NSApp mainWindow] == pid) - //{ - // [NSApp hide:pid]; - //} - //else - //{ - [pid miniaturize:pid]; - //} - } - return; - } - if (!pid || ![pid isKindOfClass:[NSView class]]) return; - - pid=NavigateUpScrollClipViews(pid); - - switch (cmd) - { - case SW_SHOW: - case SW_SHOWNA: - [((NSView *)pid) setHidden:NO]; - break; - case SW_HIDE: - { - NSWindow *pw=[pid window]; - if (pw && [NSApp keyWindow] == pw) - { - id foc=[pw firstResponder]; - if (foc && (foc == pid || IsChild((HWND)pid,(HWND)foc))) - { - HWND h=GetParent((HWND)pid); - if (h) SetFocus(h); - } - } - if (![((NSView *)pid) isHidden]) - { - if ((NSView *)pid != [pw contentView]) - { - HWND par = (HWND) [(NSView *)pid superview]; - if (par) - { - RECT r; - GetWindowRect((HWND)pid,&r); - ScreenToClient(par,(LPPOINT)&r); - ScreenToClient(par,((LPPOINT)&r)+1); - InvalidateRect(par,&r,FALSE); - } - } - [((NSView *)pid) setHidden:YES]; - } - } - break; - } - - NSWindow *nswnd; - if ((nswnd=[(NSView *)pid window]) && [nswnd contentView]==(id)pid) - { - ShowWindow((HWND)nswnd,cmd); - } -} - -void *SWELL_ModalWindowStart(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) hwnd=(HWND)[(NSView *)hwnd window]; - if (!hwnd) return 0; - return (void *)[NSApp beginModalSessionForWindow:(NSWindow *)hwnd]; -} - -bool SWELL_ModalWindowRun(void *ctx, int *ret) // returns false and puts retval in *ret when done -{ - if (!ctx) return false; - int r=[NSApp runModalSession:(NSModalSession)ctx]; - if (r==NSRunContinuesResponse) return true; - if (ret) *ret=r; - return false; -} - -void SWELL_ModalWindowEnd(void *ctx) -{ - if (ctx) - { - if ([NSApp runModalSession:(NSModalSession)ctx] == NSRunContinuesResponse) - { - [NSApp stopModal]; - while ([NSApp runModalSession:(NSModalSession)ctx]==NSRunContinuesResponse) Sleep(10); - } - [NSApp endModalSession:(NSModalSession)ctx]; - } -} - -void SWELL_CloseWindow(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) - { - [((NSWindow*)hwnd) close]; - } - else if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) - { - [[(NSView*)hwnd window] close]; - } -} - - -#include "swell-dlggen.h" - -static id m_make_owner; -static NSRect m_transform; -static float m_parent_h; -static bool m_doautoright; -static NSRect m_lastdoauto; -static bool m_sizetofits; - -#define ACTIONTARGET (m_make_owner) - -void SWELL_MakeSetCurParms(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit) -{ - m_sizetofits=dosizetofit; - m_lastdoauto.origin.x = 0; - m_lastdoauto.origin.y = -100; - m_lastdoauto.size.width = 0; - m_doautoright=doauto; - m_transform.origin.x=xtrans; - m_transform.origin.y=ytrans; - m_transform.size.width=xscale; - m_transform.size.height=yscale; - m_make_owner=(id)parent; - if ([m_make_owner isKindOfClass:[NSWindow class]]) m_make_owner=[(NSWindow *)m_make_owner contentView]; - m_parent_h=100.0; - if ([(id)m_make_owner isKindOfClass:[NSView class]]) - { - m_parent_h=[(NSView *)m_make_owner bounds].size.height; - if (m_transform.size.height > 0 && [(id)parent isFlipped]) - m_transform.size.height*=-1; - } -} - -static void UpdateAutoCoords(NSRect r) -{ - m_lastdoauto.size.width=r.origin.x + r.size.width - m_lastdoauto.origin.x; -} - -static NSRect MakeCoords(int x, int y, int w, int h, bool wantauto, bool ignorevscaleheight=false) -{ - if (w<0&&h<0) - { - return NSMakeRect(-x,-y,-w,-h); - } - float ysc=m_transform.size.height; - float ysc2 = ignorevscaleheight ? 1.0 : ysc; - int newx=(int)((x+m_transform.origin.x)*m_transform.size.width + 0.5); - int newy=(int)((ysc >= 0.0 ? m_parent_h - ((y+m_transform.origin.y) )*ysc + h*ysc2 : - ((y+m_transform.origin.y) )*-ysc) + 0.5); - - NSRect ret= NSMakeRect(newx, - newy, - (int) (w*m_transform.size.width+0.5), - (int) (h*fabs(ysc2)+0.5)); - - NSRect oret=ret; - if (wantauto && m_doautoright) - { - float dx = ret.origin.x - m_lastdoauto.origin.x; - if (fabs(dx)<32 && m_lastdoauto.origin.y >= ret.origin.y && m_lastdoauto.origin.y < ret.origin.y + ret.size.height) - { - ret.origin.x += (int) m_lastdoauto.size.width; - } - - m_lastdoauto.origin.x = oret.origin.x + oret.size.width; - m_lastdoauto.origin.y = ret.origin.y + ret.size.height*0.5; - m_lastdoauto.size.width=0; - } - return ret; -} - -static const double minwidfontadjust=1.81; -#define TRANSFORMFONTSIZE (m_transform.size.width<1?8:m_transform.size.width<2?10:12) -/// these are for swell-dlggen.h -HWND SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags) -{ - UINT_PTR a=(UINT_PTR)label; - if (a < 65536) label = "ICONTEMP"; - SWELL_Button *button=[[SWELL_Button alloc] init]; - - if (m_transform.size.width < minwidfontadjust) - { - [button setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - } - - [button setTag:idx]; - if (g_swell_want_nice_style==1) - [button setBezelStyle:NSShadowlessSquareBezelStyle ]; - else - [button setBezelStyle:NSRoundedBezelStyle ]; - NSRect tr=MakeCoords(x,y,w,h,true); - - - if (g_swell_want_nice_style!=1 && tr.size.height >= 18 && tr.size.height<24) - { - tr.size.height=24; - } - - [button setFrame:tr]; - NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(label); - [button setTitle:labelstr]; - [button setTarget:ACTIONTARGET]; - [button setAction:@selector(onSwellCommand:)]; - if (flags&SWELL_NOT_WS_VISIBLE) [button setHidden:YES]; - [m_make_owner addSubview:button]; - if (m_doautoright) UpdateAutoCoords([button frame]); - if (def) [[m_make_owner window] setDefaultButtonCell:(NSButtonCell*)button]; - [labelstr release]; - [button release]; - return (HWND) button; -} - - -@implementation SWELL_TextView - -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(NSInteger) tag -{ - return m_tag; -} - --(void) setTag:(NSInteger)tag -{ - m_tag=tag; -} - --(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam -{ - switch (msg) - { - case EM_SCROLL: - if (wParam == SB_TOP) - { - [self scrollRangeToVisible:NSMakeRange(0, 0)]; - } - else if (wParam == SB_BOTTOM) - { - int len = [[self string] length]; - [self scrollRangeToVisible:NSMakeRange(len, 0)]; - } - return 0; - - case EM_SETSEL: - { - int sl = [[self string] length]; - if (wParam == -1) lParam = wParam = 0; - else if (lParam == -1) lParam = sl; - - if (wParam>sl)wParam=sl; - if (lParam>sl)lParam=sl; - [self setSelectedRange:NSMakeRange(wParam, max(lParam-wParam,0))]; - } - return 0; - - case EM_GETSEL: - { - NSRange r = [self selectedRange]; - if (wParam) *(int*)wParam = r.location; - if (lParam) *(int*)lParam = r.location+r.length; - } - return 0; - - case WM_SETFONT: - { - HGDIOBJ__* obj = (HGDIOBJ__*)wParam; - if (obj && obj->type == TYPE_FONT) - { - if (obj->ct_FontRef) - { - [self setFont:(NSFont *)obj->ct_FontRef]; - } -#ifdef SWELL_ATSUI_TEXT_SUPPORT - else if (obj->atsui_font_style) - { - ATSUFontID fontid = kATSUInvalidFontID; - Fixed fsize = 0; - Boolean isbold = NO; - Boolean isital = NO; - Boolean isunder = NO; - if (ATSUGetAttribute(obj->atsui_font_style, kATSUFontTag, sizeof(ATSUFontID), &fontid, 0) == noErr && - ATSUGetAttribute(obj->atsui_font_style, kATSUSizeTag, sizeof(Fixed), &fsize, 0) == noErr && fsize && - ATSUGetAttribute(obj->atsui_font_style, kATSUQDBoldfaceTag, sizeof(Boolean), &isbold, 0) == noErr && - ATSUGetAttribute(obj->atsui_font_style, kATSUQDItalicTag, sizeof(Boolean), &isital, 0) == noErr && - ATSUGetAttribute(obj->atsui_font_style, kATSUQDUnderlineTag, sizeof(Boolean), &isunder, 0) == noErr) - { - char name[255]; - name[0]=0; - ByteCount namelen=0; - if (ATSUFindFontName(fontid, kFontFullName, (FontPlatformCode)kFontNoPlatform, kFontNoScriptCode, kFontNoLanguageCode, sizeof(name), name, &namelen, 0) == noErr && name[0] && namelen) - { - namelen /= 2; - int i; - for (i = 0; i < namelen; ++i) name[i] = name[2*i]; - name[namelen]=0; - - // todo bold/ital/underline - NSString* str = (NSString*)SWELL_CStringToCFString(name); - CGFloat sz = Fix2Long(fsize); - NSFont* font = [NSFont fontWithName:str size:sz]; - [str release]; - if (font) - { - [self setFont:font]; - [font release]; - } - } - } - } -#endif - } - } - return 0; - } - return 0; -} - -@end - - -@implementation SWELL_TextField -STANDARD_CONTROL_NEEDSDISPLAY_IMPL -@end - - - -HWND SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags) -{ - if ((flags&WS_VSCROLL) || (flags&WS_HSCROLL)) // || (flags & ES_READONLY)) - { - SWELL_TextView *obj=[[SWELL_TextView alloc] init]; - [obj setEditable:(flags & ES_READONLY)?NO:YES]; - if (m_transform.size.width < minwidfontadjust) - [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - [obj setTag:idx]; - [obj setDelegate:ACTIONTARGET]; - - [obj setHorizontallyResizable:NO]; - - if (flags & WS_VSCROLL) - { - NSRect fr=MakeCoords(x,y,w,h,true); - - [obj setVerticallyResizable:YES]; - NSScrollView *obj2=[[NSScrollView alloc] init]; - [obj2 setFrame:fr]; - if (flags&WS_VSCROLL) [obj2 setHasVerticalScroller:YES]; - if (flags&WS_HSCROLL) [obj2 setHasHorizontalScroller:YES]; - [obj2 setAutohidesScrollers:YES]; - [obj2 setDrawsBackground:NO]; - [obj2 setDocumentView:obj]; - [m_make_owner addSubview:obj2]; - if (m_doautoright) UpdateAutoCoords([obj2 frame]); - if (flags&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; - [obj2 release]; - - NSRect tr={0,}; - tr.size = [obj2 contentSize]; - [obj setFrame:tr]; - [obj release]; - - return (HWND)obj2; - } - else - { - [obj setFrame:MakeCoords(x,y,w,h,true)]; - [obj setVerticallyResizable:NO]; - if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if (m_doautoright) UpdateAutoCoords([obj frame]); - [obj release]; - return (HWND)obj; - } - } - - NSTextField *obj; - - if (flags & ES_PASSWORD) obj=[[NSSecureTextField alloc] init]; - else obj=[[SWELL_TextField alloc] init]; - [obj setEditable:(flags & ES_READONLY)?NO:YES]; - if (flags & ES_READONLY) [obj setSelectable:YES]; - if (m_transform.size.width < minwidfontadjust) - [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - - NSCell* cell = [obj cell]; - if (flags&ES_CENTER) [cell setAlignment:NSCenterTextAlignment]; - else if (flags&ES_RIGHT) [cell setAlignment:NSRightTextAlignment]; - if (abs(h) < 20) - { - [cell setWraps:NO]; - [cell setScrollable:YES]; - } - [obj setTag:idx]; - [obj setTarget:ACTIONTARGET]; - [obj setAction:@selector(onSwellCommand:)]; - [obj setDelegate:ACTIONTARGET]; - - [obj setFrame:MakeCoords(x,y,w,h,true)]; - if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if (m_doautoright) UpdateAutoCoords([obj frame]); - [obj release]; - - return (HWND)obj; -} - -HWND SWELL_MakeLabel( int align, const char *label, int idx, int x, int y, int w, int h, int flags) -{ - NSTextField *obj=[[SWELL_TextField alloc] init]; - [obj setEditable:NO]; - [obj setSelectable:NO]; - [obj setBordered:NO]; - [obj setBezeled:NO]; - [obj setDrawsBackground:NO]; - if (m_transform.size.width < minwidfontadjust) - [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - - if (flags & SS_NOTIFY) - { - [obj setTarget:ACTIONTARGET]; - [obj setAction:@selector(onSwellCommand:)]; - } - - NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(label); - [obj setStringValue:labelstr]; - [obj setAlignment:(align<0?NSLeftTextAlignment:align>0?NSRightTextAlignment:NSCenterTextAlignment)]; - - [[obj cell] setWraps:(h>12 ? YES : NO)]; - - [obj setTag:idx]; - [obj setFrame:MakeCoords(x,y,w,h,true)]; - if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if (m_sizetofits && strlen(label)>1)[obj sizeToFit]; - if (m_doautoright) UpdateAutoCoords([obj frame]); - [obj release]; - [labelstr release]; - return (HWND)obj; -} - - -HWND SWELL_MakeCheckBox(const char *name, int idx, int x, int y, int w, int h, int flags=0) -{ - return SWELL_MakeControl(name,idx,"Button",BS_AUTOCHECKBOX|flags,x,y,w,h,0); -} - -HWND SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles) -{ - HWND hw=SWELL_MakeControl("",idx,"SysListView32_LB",styles,x,y,w,h,0); -/* if (hw) - { - LVCOLUMN lvc={0,}; - RECT r; - GetClientRect(hw,&r); - lvc.cx=300;//yer.right-r.left; - lvc.pszText=""; - ListView_InsertColumn(hw,0,&lvc); - } - */ - return hw; -} - - -typedef struct ccprocrec -{ - SWELL_ControlCreatorProc proc; - int cnt; - struct ccprocrec *next; -} ccprocrec; - -static ccprocrec *m_ccprocs; - -void SWELL_RegisterCustomControlCreator(SWELL_ControlCreatorProc proc) -{ - if (!proc) return; - - ccprocrec *p=m_ccprocs; - while (p && p->next) - { - if (p->proc == proc) - { - p->cnt++; - return; - } - p=p->next; - } - ccprocrec *ent = (ccprocrec*)malloc(sizeof(ccprocrec)); - ent->proc=proc; - ent->cnt=1; - ent->next=0; - - if (p) p->next=ent; - else m_ccprocs=ent; -} - -void SWELL_UnregisterCustomControlCreator(SWELL_ControlCreatorProc proc) -{ - if (!proc) return; - - ccprocrec *lp=NULL; - ccprocrec *p=m_ccprocs; - while (p) - { - if (p->proc == proc) - { - if (--p->cnt <= 0) - { - if (lp) lp->next=p->next; - else m_ccprocs=p->next; - free(p); - } - return; - } - lp=p; - p=p->next; - } -} - - -HWND SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle) -{ - if (m_ccprocs) - { - NSRect poo=MakeCoords(x,y,w,h,false); - ccprocrec *p=m_ccprocs; - while (p) - { - HWND h=p->proc((HWND)m_make_owner,cname,idx,classname,style,(int)(poo.origin.x+0.5),(int)(poo.origin.y+0.5),(int)(poo.size.width+0.5),(int)(poo.size.height+0.5)); - if (h) - { - if (exstyle) SetWindowLong(h,GWL_EXSTYLE,exstyle); - return h; - } - p=p->next; - } - } - if (!stricmp(classname,"SysTabControl32")) - { - SWELL_TabView *obj=[[SWELL_TabView alloc] init]; - if (1) // todo: only if on 10.4 maybe? - { - y-=1; - h+=6; - } - [obj setTag:idx]; - [obj setDelegate:(id)obj]; - [obj setAllowsTruncatedLabels:YES]; - [obj setNotificationWindow:ACTIONTARGET]; - [obj setHidden:NO]; - [obj setFrame:MakeCoords(x,y,w,h,false)]; - if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - [obj release]; - return (HWND)obj; - } - else if (!stricmp(classname, "SysListView32")||!stricmp(classname, "SysListView32_LB")) - { - SWELL_ListView *obj = [[SWELL_ListView alloc] init]; - [obj setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing]; - [obj setFocusRingType:NSFocusRingTypeNone]; - [obj setDataSource:(id)obj]; - obj->style=style; - - BOOL isLB=!stricmp(classname, "SysListView32_LB"); - [obj setSwellNotificationMode:isLB]; - - if (isLB) - { - [obj setHeaderView:nil]; - [obj setAllowsMultipleSelection:!!(style & LBS_EXTENDEDSEL)]; - } - else - { - if ((style & LVS_NOCOLUMNHEADER) || !(style & LVS_REPORT)) [obj setHeaderView:nil]; - [obj setAllowsMultipleSelection:!(style & LVS_SINGLESEL)]; - } - [obj setAllowsColumnReordering:NO]; - [obj setAllowsEmptySelection:YES]; - [obj setTag:idx]; - [obj setHidden:NO]; - id target=ACTIONTARGET; - [obj setDelegate:target]; - [obj setTarget:target]; - [obj setAction:@selector(onSwellCommand:)]; - if ([target respondsToSelector:@selector(swellOnControlDoubleClick:)]) - { - [obj setDoubleAction:@selector(swellOnControlDoubleClick:)]; - } - else - { - [obj setDoubleAction:@selector(onSwellCommand:)]; - } - NSScrollView *obj2=[[NSScrollView alloc] init]; - NSRect tr=MakeCoords(x,y,w,h,false); - [obj2 setFrame:tr]; - [obj2 setDocumentView:obj]; - [obj2 setHasVerticalScroller:YES]; - if (!isLB) [obj2 setHasHorizontalScroller:YES]; - [obj2 setAutohidesScrollers:YES]; - [obj2 setDrawsBackground:NO]; - [obj release]; - if (style&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; - [m_make_owner addSubview:obj2]; - [obj2 release]; - - if (isLB || !(style & LVS_REPORT)) - { - LVCOLUMN lvc={0,}; - lvc.cx=(int)ceil(max(tr.size.width,300.0)); - lvc.pszText=(char*)""; - ListView_InsertColumn((HWND)obj,0,&lvc); - if (isLB && (style & LBS_OWNERDRAWFIXED)) - { - NSArray *ar=[obj tableColumns]; - NSTableColumn *c; - if (ar && [ar count] && (c=[ar objectAtIndex:0])) - { - SWELL_ODListViewCell *t=[[SWELL_ODListViewCell alloc] init]; - [c setDataCell:t]; - [t setOwnerControl:obj]; - [t release]; - } - } - } - - return (HWND)obj; - } - else if (!stricmp(classname, "SysTreeView32")) - { - SWELL_TreeView *obj = [[SWELL_TreeView alloc] init]; - [obj setFocusRingType:NSFocusRingTypeNone]; - [obj setDataSource:(id)obj]; - obj->style=style; - id target=ACTIONTARGET; - [obj setHeaderView:nil]; - [obj setDelegate:target]; - [obj setAllowsColumnReordering:NO]; - [obj setAllowsMultipleSelection:NO]; - [obj setAllowsEmptySelection:YES]; - [obj setTag:idx]; - [obj setHidden:NO]; - [obj setTarget:target]; - [obj setAction:@selector(onSwellCommand:)]; - if ([target respondsToSelector:@selector(swellOnControlDoubleClick:)]) - [obj setDoubleAction:@selector(swellOnControlDoubleClick:)]; - else - [obj setDoubleAction:@selector(onSwellCommand:)]; - NSScrollView *obj2=[[NSScrollView alloc] init]; - NSRect tr=MakeCoords(x,y,w,h,false); - [obj2 setFrame:tr]; - [obj2 setDocumentView:obj]; - [obj2 setHasVerticalScroller:YES]; - [obj2 setAutohidesScrollers:YES]; - [obj2 setDrawsBackground:NO]; - [obj release]; - if (style&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; - [m_make_owner addSubview:obj2]; - [obj2 release]; - - { - NSTableColumn *col=[[NSTableColumn alloc] init]; - SWELL_ListViewCell *cell = [[SWELL_ListViewCell alloc] initTextCell:@""]; - [col setDataCell:cell]; - [cell release]; - - [col setWidth:(int)ceil(max(tr.size.width,300.0))]; - [col setEditable:NO]; - [[col dataCell] setWraps:NO]; - [obj addTableColumn:col]; - [obj setOutlineTableColumn:col]; - - [col release]; - } -/// [obj setIndentationPerLevel:10.0]; - - return (HWND)obj; - } - else if (!stricmp(classname, "msctls_progress32")) - { - SWELL_ProgressView *obj=[[SWELL_ProgressView alloc] init]; - [obj setStyle:NSProgressIndicatorBarStyle]; - [obj setIndeterminate:NO]; - [obj setTag:idx]; - [obj setFrame:MakeCoords(x,y,w,h,false)]; - if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - [obj release]; - return (HWND)obj; - } - else if (!stricmp(classname,"Edit")) - { - return SWELL_MakeEditField(idx,x,y,w,h,style); - } - else if (!stricmp(classname, "static")) - { - NSTextField *obj=[[SWELL_TextField alloc] init]; - [obj setEditable:NO]; - [obj setSelectable:NO]; - [obj setBordered:NO]; - [obj setBezeled:NO]; - [obj setDrawsBackground:NO]; - if (m_transform.size.width < minwidfontadjust) - [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - - if (cname && *cname) - { - NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(cname); - [obj setStringValue:labelstr]; - [labelstr release]; - } - - if ((style&SS_TYPEMASK) == SS_LEFTNOWORDWRAP) [[obj cell] setWraps:NO]; - if ((style&SS_TYPEMASK) == SS_CENTER) [[obj cell] setAlignment:NSCenterTextAlignment]; - [obj setTag:idx]; - [obj setFrame:MakeCoords(x,y,w,h,true)]; - if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if ((style & SS_TYPEMASK) == SS_BLACKRECT) - { - [obj setHidden:YES]; - } - [obj release]; - return (HWND)obj; - } - else if (!stricmp(classname,"Button")) - { - if (style & BS_GROUPBOX) - { - return SWELL_MakeGroupBox(cname, idx, x, y, w, h, style &~BS_GROUPBOX); - } - if (style & BS_DEFPUSHBUTTON) - { - return SWELL_MakeButton(1, cname, idx, x,y,w,h,style &~BS_DEFPUSHBUTTON); - } - if (style & BS_PUSHBUTTON) - { - return SWELL_MakeButton(0, cname, idx, x,y,w,h,style &~BS_PUSHBUTTON); - } - SWELL_Button *button=[[SWELL_Button alloc] init]; - [button setTag:idx]; - NSRect fr=MakeCoords(x,y,w,h,true); - if ((style & 0xf) == BS_AUTO3STATE) - { - [button setButtonType:NSSwitchButton]; - [button setAllowsMixedState:YES]; - } - else if ((style & 0xf) == BS_AUTOCHECKBOX) - { - [button setButtonType:NSSwitchButton]; - [button setAllowsMixedState:NO]; - } - else if ((style & 0xf) == BS_AUTORADIOBUTTON) - { - [button setButtonType:NSRadioButton]; - [button swellSetRadioFlags:(style & WS_GROUP)?3:1]; - } - else if ((style & 0xf) == BS_OWNERDRAW) - { - SWELL_ODButtonCell *cell = [[SWELL_ODButtonCell alloc] init]; - [button setCell:cell]; - [cell release]; - //NSButtonCell - } - else // normal button - { -// fr.size.width+=8; - } - - if (m_transform.size.width < minwidfontadjust) - [button setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; - [button setFrame:fr]; - NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(cname); - [button setTitle:labelstr]; - [button setTarget:ACTIONTARGET]; - [button setAction:@selector(onSwellCommand:)]; - if (style&BS_LEFTTEXT) [button setImagePosition:NSImageRight]; - if (style&SWELL_NOT_WS_VISIBLE) [button setHidden:YES]; - [m_make_owner addSubview:button]; - if (m_sizetofits && (style & 0xf) != BS_OWNERDRAW) [button sizeToFit]; - if (m_doautoright) UpdateAutoCoords([button frame]); - [labelstr release]; - [button release]; - return (HWND)button; - } - else if (!stricmp(classname,"REAPERhfader")||!stricmp(classname,"msctls_trackbar32")) - { - NSSlider *obj=[[NSSlider alloc] init]; - [obj setTag:idx]; - [obj setMinValue:0.0]; - [obj setMaxValue:1000.0]; - [obj setFrame:MakeCoords(x,y,w,h,false)]; - if (!stricmp(classname, "msctls_trackbar32")) - { - [[obj cell] setControlSize:NSMiniControlSize]; - } - [obj setTarget:ACTIONTARGET]; - [obj setAction:@selector(onSwellCommand:)]; - if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - [obj release]; - return (HWND)obj; - } - return 0; -} - -HWND SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags) -{ - if ((flags & 0x3) == CBS_DROPDOWNLIST) - { - SWELL_PopUpButton *obj=[[SWELL_PopUpButton alloc] init]; - [obj setTag:idx]; - [obj setFont:[NSFont systemFontOfSize:10.0f]]; - NSRect rc=MakeCoords(x,y,w,18,true,true); - - [obj setSwellStyle:flags]; - [obj setFrame:rc]; - [obj setAutoenablesItems:NO]; - [obj setTarget:ACTIONTARGET]; - [obj setAction:@selector(onSwellCommand:)]; - - if (g_swell_want_nice_style==1) - { - [obj setBezelStyle:NSShadowlessSquareBezelStyle ]; - [[obj cell] setArrowPosition:NSPopUpArrowAtBottom]; - } - if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if (m_doautoright) UpdateAutoCoords([obj frame]); - [obj release]; - return (HWND)obj; - } - else - { - SWELL_ComboBox *obj=[[SWELL_ComboBox alloc] init]; - [obj setFocusRingType:NSFocusRingTypeNone]; - [obj setFont:[NSFont systemFontOfSize:10.0f]]; - [obj setEditable:(flags & 0x3) == CBS_DROPDOWNLIST?NO:YES]; - [obj setSwellStyle:flags]; - [obj setTag:idx]; - [obj setFrame:MakeCoords(x,y-1,w,22,true,true)]; - [obj setTarget:ACTIONTARGET]; - [obj setAction:@selector(onSwellCommand:)]; - [obj setDelegate:ACTIONTARGET]; - if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; - [m_make_owner addSubview:obj]; - if (m_doautoright) UpdateAutoCoords([obj frame]); - [obj release]; - return (HWND)obj; - } -} - -@implementation SWELL_BoxView - -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(NSInteger) tag -{ - return m_tag; -} --(void) setTag:(NSInteger)tag -{ - m_tag=tag; -} -@end - -HWND SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style) -{ - SWELL_BoxView *obj=[[SWELL_BoxView alloc] init]; - - // this just doesn't work, you can't color the border unless it's NSBoxCustom, - // and I can't get it to show the title text if it's NSBoxCustom - //[obj setBoxType:(NSBoxType)4]; // NSBoxCustom, so we can color the border - //[obj setTitlePosition:(NSTitlePosition)2]; // NSAtTop, default but NSBoxCustom unsets it - -// [obj setTag:idx]; - if (1) // todo: only if on 10.4 maybe? - { - y-=1; - h+=3; - } - NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(name); - [obj setTitle:labelstr]; - [obj setTag:idx]; - [labelstr release]; - if (style & BS_CENTER) - { - [[obj titleCell] setAlignment:NSCenterTextAlignment]; - } - [obj setFrame:MakeCoords(x,y,w,h,false)]; - [m_make_owner addSubview:obj positioned:NSWindowBelow relativeTo:nil]; - [obj release]; - return (HWND)obj; -} - - -int TabCtrl_GetItemCount(HWND hwnd) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; - SWELL_TabView *tv=(SWELL_TabView*)hwnd; - return [tv numberOfTabViewItems]; -} - -BOOL TabCtrl_AdjustRect(HWND hwnd, BOOL fLarger, RECT *r) -{ - if (!r || !hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return FALSE; - - int sign=fLarger?-1:1; - r->left+=sign*7; // todo: correct this? - r->right-=sign*7; - r->top+=sign*26; - r->bottom-=sign*3; - return TRUE; -} - - -BOOL TabCtrl_DeleteItem(HWND hwnd, int idx) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; - SWELL_TabView *tv=(SWELL_TabView*)hwnd; - if (idx<0 || idx>= [tv numberOfTabViewItems]) return 0; - [tv removeTabViewItem:[tv tabViewItemAtIndex:idx]]; - return TRUE; -} - -int TabCtrl_InsertItem(HWND hwnd, int idx, TCITEM *item) -{ - if (!item || !hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return -1; - if (!(item->mask & TCIF_TEXT) || !item->pszText) return -1; - SWELL_TabView *tv=(SWELL_TabView*)hwnd; - if (idx<0) idx=0; - else if (idx>[tv numberOfTabViewItems]) idx=[tv numberOfTabViewItems]; - - NSTabViewItem *tabitem=[[NSTabViewItem alloc] init]; - NSString *str=(NSString *)SWELL_CStringToCFString(item->pszText); - [tabitem setLabel:str]; - [str release]; - id turd=[tv getNotificationWindow]; - [tv setNotificationWindow:nil]; - [tv insertTabViewItem:tabitem atIndex:idx]; - [tv setNotificationWindow:turd]; - [tabitem release]; - return idx; -} - -int TabCtrl_SetCurSel(HWND hwnd, int idx) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return -1; - SWELL_TabView *tv=(SWELL_TabView*)hwnd; - int ret=TabCtrl_GetCurSel(hwnd); - if (idx>=0 && idx < [tv numberOfTabViewItems]) - { - [tv selectTabViewItemAtIndex:idx]; - } - return ret; -} - -int TabCtrl_GetCurSel(HWND hwnd) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; - SWELL_TabView *tv=(SWELL_TabView*)hwnd; - NSTabViewItem *item=[tv selectedTabViewItem]; - if (!item) return 0; - return [tv indexOfTabViewItem:item]; -} - -void ListView_SetExtendedListViewStyleEx(HWND h, int mask, int style) -{ - if (!h) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *tv=(SWELL_ListView*)h; - - if (mask&LVS_EX_GRIDLINES) - { - int s=0; - if (style&LVS_EX_GRIDLINES) - { - s=NSTableViewSolidVerticalGridLineMask|NSTableViewSolidHorizontalGridLineMask; - } - [tv setGridStyleMask:s]; - } - - if (mask&LVS_EX_HEADERDRAGDROP) - { - [tv setAllowsColumnReordering:!!(style&LVS_EX_HEADERDRAGDROP)]; - } - - - // todo LVS_EX_FULLROWSELECT (enabled by default on OSX) -} - -void SWELL_SetListViewFastClickMask(HWND hList, int mask) -{ - if (!hList || ![(id)hList isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *lv = (SWELL_ListView *)hList; - lv->m_fastClickMask=mask; - -} - - -void ListView_SetImageList(HWND h, HIMAGELIST imagelist, int which) -{ - if (!h) return; - - SWELL_ListView *v=(SWELL_ListView *)h; - - v->m_status_imagelist_type=which; - v->m_status_imagelist=(WDL_PtrList *)imagelist; - if (v->m_cols && v->m_cols->GetSize()>0) - { - NSTableColumn *col=(NSTableColumn*)v->m_cols->Get(0); - if (![col isKindOfClass:[SWELL_StatusCell class]]) - { - SWELL_StatusCell *cell=[[SWELL_StatusCell alloc] initNewCell]; - [cell setWraps:NO]; - [col setDataCell:cell]; - [cell release]; - } - } -} - -int ListView_GetColumnWidth(HWND h, int pos) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - SWELL_ListView *v=(SWELL_ListView *)h; - if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return 0; - - NSTableColumn *col=v->m_cols->Get(pos); - if (!col) return 0; - - if ([col respondsToSelector:@selector(isHidden)] && [(SWELL_TableColumnExtensions*)col isHidden]) return 0; - return (int) floor(0.5+[col width]); -} - -void ListView_InsertColumn(HWND h, int pos, const LVCOLUMN *lvc) -{ - if (!h || !lvc) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_BEGIN_TRY - - SWELL_ListView *v=(SWELL_ListView *)h; - NSTableColumn *col=[[NSTableColumn alloc] init]; - // note, not looking at lvc->mask at all - - [col setEditable:NO]; - // [col setResizingMask:2]; // user resizable, this seems to be the default - - if (!lvc->cx && [col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; - else [col setWidth:lvc->cx]; - - if (lvc->fmt == LVCFMT_CENTER) [[col headerCell] setAlignment:NSCenterTextAlignment]; - else if (lvc->fmt == LVCFMT_RIGHT) [[col headerCell] setAlignment:NSRightTextAlignment]; - - if (!v->m_lbMode && !(v->style & LVS_NOCOLUMNHEADER)) - { - NSString *lbl=(NSString *)SWELL_CStringToCFString(lvc->pszText); - [[col headerCell] setStringValue:lbl]; - [lbl release]; - } - - if (!pos && v->m_status_imagelist) - { - SWELL_StatusCell *cell=[[SWELL_StatusCell alloc] initNewCell]; - [cell setWraps:NO]; - [col setDataCell:cell]; - [cell release]; - } - else - { - SWELL_ListViewCell *cell = [[SWELL_ListViewCell alloc] initTextCell:@""]; - [col setDataCell:cell]; - [cell setWraps:NO]; - - if (lvc->fmt == LVCFMT_CENTER) [cell setAlignment:NSCenterTextAlignment]; - else if (lvc->fmt == LVCFMT_RIGHT) [cell setAlignment:NSRightTextAlignment]; - [cell release]; - } - - [v addTableColumn:col]; - v->m_cols->Add(col); - [col release]; - SWELL_END_TRY(;) -} - -void ListView_SetColumn(HWND h, int pos, const LVCOLUMN *lvc) -{ - if (!h || !lvc || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *v=(SWELL_ListView *)h; - if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return; - - NSTableColumn *col=v->m_cols->Get(pos); - if (!col) return; - - if (lvc->mask&LVCF_FMT) - { - if (lvc->fmt == LVCFMT_LEFT) [[col headerCell] setAlignment:NSLeftTextAlignment]; - else if (lvc->fmt == LVCFMT_CENTER) [[col headerCell] setAlignment:NSCenterTextAlignment]; - else if (lvc->fmt == LVCFMT_RIGHT) [[col headerCell] setAlignment:NSRightTextAlignment]; - } - if (lvc->mask&LVCF_WIDTH) - { - if (!lvc->cx) - { - if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; - } - else - { - if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:NO]; - [col setWidth:lvc->cx]; - } - } - if (lvc->mask&LVCF_TEXT) - { - if (!v->m_lbMode && !(v->style&LVS_NOCOLUMNHEADER)) - { - NSString *lbl=(NSString *)SWELL_CStringToCFString(lvc->pszText); - [[col headerCell] setStringValue:lbl]; - [lbl release]; - } - } -} - -bool ListView_DeleteColumn(HWND h, int pos) -{ - if (!h) return false; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; - SWELL_ListView *v=(SWELL_ListView *)h; - if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return false; - [v removeTableColumn:v->m_cols->Get(pos)]; - v->m_cols->Delete(pos); - return true; -} - -void ListView_GetItemText(HWND hwnd, int item, int subitem, char *text, int textmax) -{ - LVITEM it={LVIF_TEXT,item,subitem,0,0,text,textmax,}; - ListView_GetItem(hwnd,&it); -} - -int ListView_InsertItem(HWND h, const LVITEM *item) -{ - if (!h || !item || item->iSubItem) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) return -1; - if (!tv->m_items) return -1; - - int a=item->iItem; - if (a<0)a=0; - else if (a > tv->m_items->GetSize()) a=tv->m_items->GetSize(); - - if (!tv->m_lbMode && (item->mask & LVIF_TEXT)) - { - if (tv->style & LVS_SORTASCENDING) - { - a=ptrlist_bsearch_mod((char *)item->pszText,tv->m_items,_listviewrowSearchFunc,NULL); - } - else if (tv->style & LVS_SORTDESCENDING) - { - a=ptrlist_bsearch_mod((char *)item->pszText,tv->m_items,_listviewrowSearchFunc2,NULL); - } - } - - SWELL_ListView_Row *nr=new SWELL_ListView_Row; - nr->m_vals.Add(strdup((item->mask & LVIF_TEXT) ? item->pszText : "")); - if (item->mask & LVIF_PARAM) nr->m_param = item->lParam; - tv->m_items->Insert(a,nr); - - - - if ((item->mask&LVIF_STATE) && (item->stateMask & (0xff<<16))) - { - nr->m_imageidx=(item->state>>16)&0xff; - } - - [tv reloadData]; - - if (a < tv->m_items->GetSize()-1) - { - NSIndexSet *sel=[tv selectedRowIndexes]; - if (sel && [sel count]) - { - NSMutableIndexSet *ms = [[NSMutableIndexSet alloc] initWithIndexSet:sel]; - [ms shiftIndexesStartingAtIndex:a by:1]; - [tv selectRowIndexes:ms byExtendingSelection:NO]; - [ms release]; - } - } - - if (item->mask & LVIF_STATE) - { - if (item->stateMask & LVIS_SELECTED) - { - if (item->state&LVIS_SELECTED) - { - bool isSingle = tv->m_lbMode ? !(tv->style & LBS_EXTENDEDSEL) : !!(tv->style&LVS_SINGLESEL); - [tv selectRowIndexes:[NSIndexSet indexSetWithIndex:a] byExtendingSelection:isSingle?NO:YES]; - } - } - } - - return a; -} - -void ListView_SetItemText(HWND h, int ipos, int cpos, const char *txt) -{ - if (!h || cpos < 0 || cpos >= 32) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) return; - if (!tv->m_items) return; - - SWELL_ListView_Row *p=tv->m_items->Get(ipos); - if (!p) return; - int x; - for (x = p->m_vals.GetSize(); x < cpos; x ++) - { - p->m_vals.Add(strdup("")); - } - if (cpos < p->m_vals.GetSize()) - { - free(p->m_vals.Get(cpos)); - p->m_vals.Set(cpos,strdup(txt)); - } - else p->m_vals.Add(strdup(txt)); - - [tv reloadData]; -} - -int ListView_GetNextItem(HWND h, int istart, int flags) -{ - if (flags==LVNI_FOCUSED||flags==LVNI_SELECTED) - { - if (!h) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView *tv=(SWELL_ListView*)h; - - if (flags==LVNI_SELECTED) - { - //int orig_start=istart; - if (istart++<0)istart=0; - int n = [tv numberOfRows]; - while (istart < n) - { - if ([tv isRowSelected:istart]) return istart; - istart++; - } - return -1; - } - - return [tv selectedRow]; - } - return -1; -} - -bool ListView_SetItem(HWND h, LVITEM *item) -{ - if (!item) return false; - if (!h) return false; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) - { - if (!tv->m_items) return false; - SWELL_ListView_Row *row=tv->m_items->Get(item->iItem); - if (!row) return false; - - if (item->mask & LVIF_PARAM) - { - row->m_param=item->lParam; - } - if ((item->mask & LVIF_TEXT) && item->pszText) - { - ListView_SetItemText(h,item->iItem,item->iSubItem,item->pszText); - } - if ((item->mask&LVIF_IMAGE) && item->iImage >= 0) - { - row->m_imageidx=item->iImage+1; - ListView_RedrawItems(h, item->iItem, item->iItem); - } - } - if ((item->mask & LVIF_STATE) && item->stateMask) - { - ListView_SetItemState(h,item->iItem,item->state,item->stateMask); - } - - return true; -} - -bool ListView_GetItem(HWND h, LVITEM *item) -{ - if (!item) return false; - if ((item->mask&LVIF_TEXT)&&item->pszText && item->cchTextMax > 0) item->pszText[0]=0; - item->state=0; - if (!h) return false; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; - - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) - { - if (!tv->m_items) return false; - - SWELL_ListView_Row *row=tv->m_items->Get(item->iItem); - if (!row) return false; - - if (item->mask & LVIF_PARAM) item->lParam=row->m_param; - if (item->mask & LVIF_TEXT) if (item->pszText && item->cchTextMax>0) - { - char *p=row->m_vals.Get(item->iSubItem); - lstrcpyn(item->pszText,p?p:"",item->cchTextMax); - } - if (item->mask & LVIF_STATE) - { - if (item->stateMask & (0xff<<16)) - { - item->state|=row->m_imageidx<<16; - } - } - } - else - { - if (item->iItem <0 || item->iItem >= tv->ownermode_cnt) return false; - } - if (item->mask & LVIF_STATE) - { - if ((item->stateMask&LVIS_SELECTED) && [tv isRowSelected:item->iItem]) item->state|=LVIS_SELECTED; - if ((item->stateMask&LVIS_FOCUSED) && [tv selectedRow] == item->iItem) item->state|=LVIS_FOCUSED; - } - - return true; -} -int ListView_GetItemState(HWND h, int ipos, int mask) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - SWELL_ListView *tv=(SWELL_ListView*)h; - int flag=0; - if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) - { - if (!tv->m_items) return 0; - SWELL_ListView_Row *row=tv->m_items->Get(ipos); - if (!row) return 0; - if (mask & (0xff<<16)) - { - flag|=row->m_imageidx<<16; - } - } - else - { - if (ipos<0 || ipos >= tv->ownermode_cnt) return 0; - } - - if ((mask&LVIS_SELECTED) && [tv isRowSelected:ipos]) flag|=LVIS_SELECTED; - if ((mask&LVIS_FOCUSED) && [tv selectedRow]==ipos) flag|=LVIS_FOCUSED; - return flag; -} - -bool ListView_SetItemState(HWND h, int ipos, int state, int statemask) -{ - int doref=0; - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return false; - SWELL_ListView *tv=(SWELL_ListView*)h; - static int _is_doing_all; - - if (ipos == -1) - { - int x; - int n=ListView_GetItemCount(h); - _is_doing_all++; - for (x = 0; x < n; x ++) - ListView_SetItemState(h,x,state,statemask); - _is_doing_all--; - ListView_RedrawItems(h,0,n-1); - return true; - } - - if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) - { - if (!tv->m_items) return false; - SWELL_ListView_Row *row=tv->m_items->Get(ipos); - if (!row) return false; - if (statemask & (0xff<<16)) - { - if (row->m_imageidx!=((state>>16)&0xff)) - { - row->m_imageidx=(state>>16)&0xff; - doref=1; - } - } - } - else - { - if (ipos<0 || ipos >= tv->ownermode_cnt) return 0; - } - bool didsel=false; - if (statemask & LVIS_SELECTED) - { - if (state & LVIS_SELECTED) - { - bool isSingle = tv->m_lbMode ? !(tv->style & LBS_EXTENDEDSEL) : !!(tv->style&LVS_SINGLESEL); - if (![tv isRowSelected:ipos]) { didsel=true; [tv selectRowIndexes:[NSIndexSet indexSetWithIndex:ipos] byExtendingSelection:isSingle?NO:YES]; } - } - else - { - if ([tv isRowSelected:ipos]) { didsel=true; [tv deselectRow:ipos]; } - } - } - if (statemask & LVIS_FOCUSED) - { - if (state&LVIS_FOCUSED) - { - } - else - { - - } - } - - if (!_is_doing_all) - { - if (didsel) - { - static int __rent; - if (!__rent) - { - __rent=1; - NMLISTVIEW nm={{(HWND)h,[tv tag],LVN_ITEMCHANGED},ipos,0,state,}; - SendMessage(GetParent(h),WM_NOTIFY,[tv tag],(LPARAM)&nm); - __rent=0; - } - } - if (doref) - ListView_RedrawItems(h,ipos,ipos); - } - return true; -} - -void ListView_RedrawItems(HWND h, int startitem, int enditem) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *tv=(SWELL_ListView*)h; - if (!tv->m_items) return; - [tv reloadData]; -} - -void ListView_DeleteItem(HWND h, int ipos) -{ - if (!h) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (!tv->m_items) return; - - if (ipos >=0 && ipos < tv->m_items->GetSize()) - { - if (ipos != tv->m_items->GetSize()-1) - { - NSIndexSet *sel=[tv selectedRowIndexes]; - if (sel && [sel count]) - { - NSMutableIndexSet *ms = [[NSMutableIndexSet alloc] initWithIndexSet:sel]; - [ms shiftIndexesStartingAtIndex:ipos+1 by:-1]; - [tv selectRowIndexes:ms byExtendingSelection:NO]; - [ms release]; - } - } - tv->m_items->Delete(ipos,true); - - [tv reloadData]; - - } -} - -void ListView_DeleteAllItems(HWND h) -{ - if (!h) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *tv=(SWELL_ListView*)h; - tv->ownermode_cnt=0; - if (tv->m_items) tv->m_items->Empty(true); - - [tv reloadData]; -} - -int ListView_GetSelectedCount(HWND h) -{ - if (!h) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView *tv=(SWELL_ListView*)h; - return [tv numberOfSelectedRows]; -} - -int ListView_GetItemCount(HWND h) -{ - if (!h) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) - { - if (!tv->m_items) return 0; - - return tv->m_items->GetSize(); - } - return tv->ownermode_cnt; -} - -int ListView_GetSelectionMark(HWND h) -{ - if (!h) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView *tv=(SWELL_ListView*)h; - return [tv selectedRow]; -} - -int SWELL_GetListViewHeaderHeight(HWND h) -{ - if (!h) return 0; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - - SWELL_ListView* tv=(SWELL_ListView*)h; - NSTableHeaderView* hv=[tv headerView]; - NSRect r=[hv bounds]; - return (int)(r.size.height+0.5); -} - -void ListView_SetColumnWidth(HWND h, int pos, int wid) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *v=(SWELL_ListView *)h; - if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return; - - NSTableColumn *col=v->m_cols->Get(pos); - if (!col) return; - - if (!wid) - { - if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; - } - else - { - if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:NO]; - [col setWidth:wid]; - } -} - -BOOL ListView_GetColumnOrderArray(HWND h, int cnt, int* arr) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return FALSE; - SWELL_ListView* lv=(SWELL_ListView*)h; - if (!lv->m_cols || lv->m_cols->GetSize() != cnt) return FALSE; - - int i; - for (i=0; i < cnt; ++i) - { - arr[i]=[lv getColumnPos:i]; - } - - return TRUE; -} - -BOOL ListView_SetColumnOrderArray(HWND h, int cnt, int* arr) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return FALSE; - SWELL_ListView* lv=(SWELL_ListView*)h; - if (!lv->m_cols || lv->m_cols->GetSize() != cnt) return FALSE; - - int i; - for (i=0; i < cnt; ++i) - { - int pos=[lv getColumnPos:i]; - int dest=arr[i]; - [lv moveColumn:pos toColumn:dest]; - } - - return TRUE; -} - -HWND ListView_GetHeader(HWND h) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - return h; -} - -int Header_GetItemCount(HWND h) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; - SWELL_ListView* lv=(SWELL_ListView*)h; - if (lv->m_cols) return lv->m_cols->GetSize(); - return 0; -} - -BOOL Header_GetItem(HWND h, int col, HDITEM* hi) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]] || !hi) return FALSE; - SWELL_ListView* lv=(SWELL_ListView*)h; - if (!lv->m_cols || col < 0 || col >= lv->m_cols->GetSize()) return FALSE; - NSTableColumn* hcol=lv->m_cols->Get(col); - if (!hcol) return FALSE; - - if (hi->mask&HDI_FORMAT) - { - hi->fmt=0; - NSImage* img=[lv indicatorImageInTableColumn:hcol]; - if (img) - { - NSString* imgname=[img name]; - if (imgname) - { - if ([imgname isEqualToString:@"NSAscendingSortIndicator"]) hi->fmt |= HDF_SORTUP; - else if ([imgname isEqualToString:@"NSDescendingSortIndicator"]) hi->fmt |= HDF_SORTDOWN; - } - } - } - // etc todo - - return TRUE; -} - -BOOL Header_SetItem(HWND h, int col, HDITEM* hi) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]] || !hi) return FALSE; - SWELL_ListView* lv=(SWELL_ListView*)h; - if (!lv->m_cols || col < 0 || col >= lv->m_cols->GetSize()) return FALSE; - NSTableColumn* hcol=lv->m_cols->Get(col); - if (!hcol) return FALSE; - - if (hi->mask&HDI_FORMAT) - { - NSImage* img=0; - if (hi->fmt&HDF_SORTUP) img=[NSImage imageNamed:@"NSAscendingSortIndicator"]; - else if (hi->fmt&HDF_SORTDOWN) img=[NSImage imageNamed:@"NSDescendingSortIndicator"]; - [lv setIndicatorImage:img inTableColumn:hcol]; - } - // etc todo - - return TRUE; -} - -int ListView_HitTest(HWND h, LVHITTESTINFO *pinf) -{ - if (!h || !pinf) return -1; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return -1; - - SWELL_ListView *tv=(SWELL_ListView*)h; - // return index - pinf->flags=0; - pinf->iItem=-1; - - // rowAtPoint will return a row even if it is scrolled out of the clip view - NSScrollView* sv=(NSScrollView *)NavigateUpScrollClipViews(tv); - if (![sv isKindOfClass:[NSScrollView class]] && ![sv isKindOfClass:[NSClipView class]]) sv=NULL; - - NSRect r=[sv documentVisibleRect]; - int x=pinf->pt.x-r.origin.x; - int y=pinf->pt.y-r.origin.y; - - if (x < 0) pinf->flags |= LVHT_TOLEFT; - if (x >= r.size.width) pinf->flags |= LVHT_TORIGHT; - if (y < 0) pinf->flags |= LVHT_ABOVE; - if (y >= r.size.height) pinf->flags |= LVHT_BELOW; - - if (!pinf->flags) - { - NSPoint pt = { pinf->pt.x, pinf->pt.y }; - pinf->iItem=[(NSTableView *)h rowAtPoint:pt]; - if (pinf->iItem >= 0) - { - if (tv->m_status_imagelist && pt.x <= [tv rowHeight]) - { - pinf->flags=LVHT_ONITEMSTATEICON; - } - else - { - pinf->flags=LVHT_ONITEMLABEL; - } - } - else - { - pinf->flags=LVHT_NOWHERE; - } - } - - return pinf->iItem; -} - -int ListView_SubItemHitTest(HWND h, LVHITTESTINFO *pinf) -{ - int row = ListView_HitTest(h, pinf); - - NSPoint pt={pinf->pt.x,pinf->pt.y}; - if (row < 0 && pt.y < 0) - { // Fake the point in the client area of the listview to get the column # (like win32) - pt.y = 0; - } - pinf->iSubItem=[(NSTableView *)h columnAtPoint:pt]; - return row; -} - -void ListView_SetItemCount(HWND h, int cnt) -{ - if (!h) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *tv=(SWELL_ListView*)h; - if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) - { - tv->ownermode_cnt=cnt; - } -} - -void ListView_EnsureVisible(HWND h, int i, BOOL pok) -{ - if (!h) return; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *tv=(SWELL_ListView*)h; - - if (i<0)i=0; - if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) - { - if (i >=tv->ownermode_cnt-1) i=tv->ownermode_cnt-1; - } - else - { - if (tv->m_items && i >= tv->m_items->GetSize()) i=tv->m_items->GetSize()-1; - } - if (i>=0) - { - [tv scrollRowToVisible:i]; - } -} - -static bool ListViewGetRectImpl(HWND h, int item, int subitem, RECT* r) // subitem<0 for full item rect -{ - if (!h) return false; - if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; - if (item < 0 || item > ListView_GetItemCount(h)) return false; - SWELL_ListView *tv=(SWELL_ListView*)h; - - if (subitem >= 0 && (!tv->m_cols || subitem >= tv->m_cols->GetSize())) return false; - subitem=[tv getColumnPos:subitem]; - - NSRect ar; - if (subitem < 0) ar = [tv rectOfRow:item]; - else ar=[tv frameOfCellAtColumn:subitem row:item]; - NSSize sp=[tv intercellSpacing]; - - r->left=(int)ar.origin.x; - r->top=(int)ar.origin.y; - r->right=(int)(ar.origin.x+ar.size.width+sp.width); - r->bottom=(int)(ar.origin.y+ar.size.height+sp.height); - - return true; -} - -bool ListView_GetSubItemRect(HWND h, int item, int subitem, int code, RECT *r) -{ - return ListViewGetRectImpl(h, item, subitem, r); -} - -bool ListView_GetItemRect(HWND h, int item, RECT *r, int code) -{ - return ListViewGetRectImpl(h, item, -1, r); -} - -int ListView_GetTopIndex(HWND h) -{ - NSTableView* tv = (NSTableView*)h; - if (!tv) return -1; - NSScrollView* sv = [tv enclosingScrollView]; - if (!sv) return -1; - - NSRect tvr = [sv documentVisibleRect]; - NSPoint pt = { 0, tvr.origin.y }; - return [tv rowAtPoint:pt]; -} - -int ListView_GetCountPerPage(HWND h) -{ - NSTableView* tv = (NSTableView*)h; - if (!tv) return 0; - NSScrollView* sv = [tv enclosingScrollView]; - if (!sv) return 0; - - NSRect tvr = [sv documentVisibleRect]; - int rowh = [tv rowHeight]; - return tvr.size.height/rowh; -} - -bool ListView_Scroll(HWND h, int xscroll, int yscroll) -{ - NSTableView* tv = (NSTableView*)h; - NSScrollView* sv = [tv enclosingScrollView]; - if (!sv) return false; - - NSRect tvr = [sv documentVisibleRect]; - NSPoint pt = { tvr.origin.x, tvr.origin.y }; - if (xscroll > 0) pt.x += tvr.size.width-1; - if (yscroll > 0) pt.y += tvr.size.height-1; - - int rowidx = [tv rowAtPoint:pt]; - if (rowidx < 0) rowidx=0; - else if (rowidx >= [tv numberOfRows]) rowidx=[tv numberOfRows]-1; - - int colidx = [tv columnAtPoint:pt]; - if (colidx < 0) colidx=0; - else if (colidx >= [tv numberOfColumns]) colidx = [tv numberOfColumns]-1; - - NSRect ir = [tv frameOfCellAtColumn:colidx row:rowidx]; - if (ir.size.width) xscroll /= ir.size.width; - else xscroll = 0; - if (ir.size.height) yscroll /= ir.size.height; - else yscroll = 0; - - rowidx += yscroll; - if (rowidx < 0) rowidx=0; - else if (rowidx >= [tv numberOfRows]) rowidx = [tv numberOfRows]-1; - - colidx += xscroll; - if (colidx < 0) colidx=0; - else if (colidx >= [tv numberOfColumns]) colidx = [tv numberOfColumns]-1; - - [tv scrollRowToVisible:rowidx]; - [tv scrollColumnToVisible:colidx]; - - return true; -} - -bool ListView_GetScroll(HWND h, POINT* p) -{ - NSTableView* tv = (NSTableView*)h; - NSScrollView* sv = [tv enclosingScrollView]; - if (sv) - { - NSRect cr = [sv documentVisibleRect]; - p->x = cr.origin.x; - p->y = cr.origin.y; - return true; - } - p->x=p->y=0; - return false; -} - -static int __listview_sortfunc(void *p1, void *p2, int (*compar)(LPARAM val1, LPARAM val2, LPARAM userval), LPARAM userval) -{ - SWELL_ListView_Row *a = *(SWELL_ListView_Row **)p1; - SWELL_ListView_Row *b = *(SWELL_ListView_Row **)p2; - return compar(a->m_param,b->m_param,userval); -} - -static void __listview_mergesort_internal(void *base, size_t nmemb, size_t size, - int (*compar)(LPARAM val1, LPARAM val2, LPARAM userval), - LPARAM parm, - char *tmpspace) -{ - char *b1,*b2; - size_t n1, n2; - - if (nmemb < 2) return; - - n1 = nmemb / 2; - b1 = (char *) base; - n2 = nmemb - n1; - b2 = b1 + (n1 * size); - - if (nmemb>2) - { - __listview_mergesort_internal(b1, n1, size, compar, parm, tmpspace); - __listview_mergesort_internal(b2, n2, size, compar, parm, tmpspace); - } - - char *p = tmpspace; - - do - { - if (__listview_sortfunc(b1, b2, compar,parm) > 0) - { - memcpy(p, b2, size); - b2 += size; - n2--; - } - else - { - memcpy(p, b1, size); - b1 += size; - n1--; - } - p += size; - } - while (n1 > 0 && n2 > 0); - - if (n1 > 0) memcpy(p, b1, n1 * size); - memcpy(base, tmpspace, (nmemb - n2) * size); -} - - -void ListView_SortItems(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm) -{ - if (!hwnd) return; - if (![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; - SWELL_ListView *tv=(SWELL_ListView*)hwnd; - if (tv->m_lbMode || (tv->style & LVS_OWNERDATA) || !tv->m_items) return; - - WDL_HeapBuf tmp; - tmp.Resize(tv->m_items->GetSize()*sizeof(void *)); - int x; - int sc=0; - for(x=0;xm_items->GetSize();x++) - { - SWELL_ListView_Row *r = tv->m_items->Get(x); - if (r) - { - r->m_tmp = !![tv isRowSelected:x]; - sc++; - } - } - __listview_mergesort_internal(tv->m_items->GetList(),tv->m_items->GetSize(),sizeof(void *),compf,parm,(char*)tmp.Get()); - if (sc) - { - NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init]; - - for(x=0;xm_items->GetSize();x++) - { - SWELL_ListView_Row *r = tv->m_items->Get(x); - if (r && (r->m_tmp&1)) [indexSet addIndex:x]; - } - [tv selectRowIndexes:indexSet byExtendingSelection:NO]; - [indexSet release]; - } - - [tv reloadData]; -} - - -HWND WindowFromPoint(POINT p) -{ - NSArray *windows=[NSApp orderedWindows]; - int x; - int cnt=windows ? [windows count] : 0; - - NSWindow *kw = [NSApp keyWindow]; - if (kw && windows && [windows containsObject:kw]) kw=NULL; - - NSWindow *bestwnd=0; - for (x = kw ? -1 : 0; x < cnt; x ++) - { - NSWindow *wnd = kw; - if (x>=0) wnd=[windows objectAtIndex:x]; - if (wnd && [wnd isVisible]) - { - NSRect fr=[wnd frame]; - if (p.x >= fr.origin.x && p.x < fr.origin.x + fr.size.width && - p.y >= fr.origin.y && p.y < fr.origin.y + fr.size.height) - { - bestwnd=wnd; - break; - } - } - } - - if (!bestwnd) return 0; - NSPoint pt={p.x,p.y}; - NSPoint lpt=[bestwnd convertScreenToBase:pt]; - NSView *v=[[bestwnd contentView] hitTest:lpt]; - if (v) return (HWND)v; - return (HWND)[bestwnd contentView]; -} - -void UpdateWindow(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && [(NSView *)hwnd needsDisplay]) - { - NSWindow *wnd = [(NSView *)hwnd window]; - [wnd displayIfNeeded]; - } -} - -void SWELL_FlushWindow(HWND h) -{ - if (h) - { - NSWindow *w=NULL; - if ([(id)h isKindOfClass:[NSView class]]) - { - if ([(NSView *)h needsDisplay]) return; - - w = [(NSView *)h window]; - } - else if ([(id)h isKindOfClass:[NSWindow class]]) w = (NSWindow *)h; - - if (w && ![w viewsNeedDisplay]) - { - [w flushWindow]; - } - } -} - -static void InvalidateSuperViews(NSView *view) -{ - if (!view) return; - view = [view superview]; - while (view) - { - if ([view isKindOfClass:[SWELL_hwndChild class]]) - { - if (((SWELL_hwndChild *)view)->m_isdirty&2) break; - ((SWELL_hwndChild *)view)->m_isdirty|=2; - } - view = [view superview]; - } -} - -void InvalidateRect(HWND hwnd, RECT *r, int eraseBk) -{ - if (!hwnd) return; - id view=(id)hwnd; - if ([view isKindOfClass:[NSWindow class]]) view=[view contentView]; - if ([view isKindOfClass:[NSView class]]) - { - - NSView *sv = view; - - bool skip_parent_invalidate=false; - if ([view isKindOfClass:[SWELL_hwndChild class]]) - { - if (!(((SWELL_hwndChild *)view)->m_isdirty&1)) - { - ((SWELL_hwndChild *)view)->m_isdirty|=1; - } - else skip_parent_invalidate=true; // if already dirty, then assume parents are already dirty too - } - if (!skip_parent_invalidate) - { - InvalidateSuperViews(view); - } - if (r) - { - RECT tr=*r; - if (tr.top>tr.bottom) - { - int a = tr.top; tr.top=tr.bottom; tr.bottom=a; - } - [sv setNeedsDisplayInRect:NSMakeRect(tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top)]; - } - else [sv setNeedsDisplay:YES]; - - } -} - -static HWND m_fakeCapture; -static BOOL m_capChangeNotify; -HWND GetCapture() -{ - - return m_fakeCapture; -} - -HWND SetCapture(HWND hwnd) -{ - HWND oc=m_fakeCapture; - int ocn=m_capChangeNotify; - m_fakeCapture=hwnd; - m_capChangeNotify = hwnd && [(id)hwnd respondsToSelector:@selector(swellCapChangeNotify)] && [(SWELL_hwndChild*)hwnd swellCapChangeNotify]; - - if (ocn && oc && oc != hwnd) SendMessage(oc,WM_CAPTURECHANGED,0,(LPARAM)hwnd); - return oc; -} - - -void ReleaseCapture() -{ - HWND h=m_fakeCapture; - m_fakeCapture=NULL; - if (m_capChangeNotify && h) - { - SendMessage(h,WM_CAPTURECHANGED,0,0); - } -} - - -HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) -{ - if (!ps) return 0; - memset(ps,0,sizeof(PAINTSTRUCT)); - if (!hwnd) return 0; - id turd = (id)hwnd; - if (![turd respondsToSelector:@selector(getSwellPaintInfo:)]) return 0; - - [(SWELL_hwndChild*)turd getSwellPaintInfo:(PAINTSTRUCT *)ps]; - return ps->hdc; -} - -BOOL EndPaint(HWND hwnd, PAINTSTRUCT *ps) -{ - return TRUE; -} - -LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg==WM_RBUTTONUP||msg==WM_NCRBUTTONUP) - { - POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; - HWND hwndDest=hwnd; - if (msg==WM_RBUTTONUP) - { - ClientToScreen(hwnd,&p); - HWND h=WindowFromPoint(p); - if (h && IsChild(hwnd,h)) hwndDest=h; - } - SendMessage(hwnd,WM_CONTEXTMENU,(WPARAM)hwndDest,(p.x&0xffff)|(p.y<<16)); - return 1; - } - else if (msg==WM_CONTEXTMENU || msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL || msg == WM_GESTURE) - { - if ([(id)hwnd isKindOfClass:[NSView class]]) - { - NSView *h=(NSView *)hwnd; - while (h && [[h window] contentView] != h) - { - h=[h superview]; - if (h && [h respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - { - return SendMessage((HWND)h,msg,wParam,lParam); - } - } - } - } - else if (msg==WM_NCHITTEST) - { - return HTCLIENT; - } - else if (msg==WM_KEYDOWN || msg==WM_KEYUP) return 69; - else if (msg == WM_DISPLAYCHANGE) - { - if ([(id)hwnd isKindOfClass:[NSView class]]) - { - NSArray *ch = [(NSView *)hwnd subviews]; - if (ch) - { - int x; - for(x=0;x<[ch count]; x ++) - { - NSView *v = [ch objectAtIndex:x]; - sendSwellMessage(v,WM_DISPLAYCHANGE,wParam,lParam); - } - if (x) - { - void SWELL_DoDialogColorUpdates(HWND hwnd, DLGPROC d, bool isUpdate); - DLGPROC d = (DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); - if (d) SWELL_DoDialogColorUpdates(hwnd,d,true); - } - } - } - } - return 0; -} - -void SWELL_BroadcastMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - int x; - NSArray *ch=[NSApp orderedWindows]; - for(x=0;x<[ch count]; x ++) - { - NSView *v = [[ch objectAtIndex:x] contentView]; - if (v && [v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) - { - [(SWELL_hwndChild *)v onSwellMessage:uMsg p1:wParam p2:lParam]; - - if (uMsg == WM_DISPLAYCHANGE) - InvalidateRect((HWND)v,NULL,FALSE); - } - } -} - - - - - - - - - - - - - - -///////////////// clipboard compatability (NOT THREAD SAFE CURRENTLY) - - -BOOL DragQueryPoint(HDROP hDrop,LPPOINT pt) -{ - if (!hDrop) return 0; - DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); - BOOL rv=!df->fNC; - *pt=df->pt; - GlobalUnlock(hDrop); - return rv; -} - -void DragFinish(HDROP hDrop) -{ -//do nothing for now (caller will free hdrops) -} - -UINT DragQueryFile(HDROP hDrop, UINT wf, char *buf, UINT bufsz) -{ - if (!hDrop) return 0; - DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); - - UINT rv=0; - char *p=(char*)df + df->pFiles; - if (wf == 0xFFFFFFFF) - { - while (*p) - { - rv++; - p+=strlen(p)+1; - } - } - else - { - while (*p) - { - if (!wf--) - { - if (buf) - { - lstrcpyn(buf,p,bufsz); - rv=strlen(buf); - } - else rv=strlen(p); - - break; - } - p+=strlen(p)+1; - } - } - GlobalUnlock(hDrop); - return rv; -} - - - - - - - - - - - -static WDL_PtrList m_clip_recs; -static WDL_PtrList m_clip_fmts; -static WDL_PtrList m_clip_curfmts; -struct swell_pendingClipboardStates -{ - UINT type; - HANDLE h; - swell_pendingClipboardStates(UINT _type, HANDLE _h) - { - type = _type; - h = _h; - } - ~swell_pendingClipboardStates() - { - GlobalFree(h); - } -}; - -static WDL_PtrList m_clipsPending; - -bool OpenClipboard(HWND hwndDlg) -{ - m_clipsPending.Empty(true); - - CF_TEXT; // ensure this type is registered - - NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:@"SWELL_APP"]; - m_clip_curfmts.Empty(); - NSArray *ar=[pasteboard types]; - - - if (ar && [ar count]) - { - int x; - - for (x = 0; x < [ar count]; x ++) - { - NSString *s=[ar objectAtIndex:x]; - if (!s) continue; - int y; - for (y = 0; y < m_clip_fmts.GetSize(); y ++) - { - if ([s compare:(NSString *)m_clip_fmts.Get(y)]==NSOrderedSame) - { - if (m_clip_curfmts.Find((char*)(y+1))<0) - m_clip_curfmts.Add((char*)(y+1)); - break; - } - } - - } - } - return true; -} - -void CloseClipboard() // frees any remaining items in clipboard -{ - m_clip_recs.Empty(GlobalFree); - - if (m_clipsPending.GetSize()) - { - int x; - for (x=0;xtype != CF_TEXT;x++); - NSPasteboard *pasteboard = xtype-1); - if (fmt) [ar addObject:fmt]; - } - if ([ar count]) - { - [pasteboard declareTypes:ar owner:nil]; - for (x=0;xtype-1); - if (!fmt) continue; - - void *buf=GlobalLock(cs->h); - if (buf) - { - int bufsz=GlobalSize(cs->h); - if (cs->type == CF_TEXT) - { - char *t = (char *)malloc(bufsz+1); - if (t) - { - memcpy(t,buf,bufsz); - t[bufsz]=0; - NSString *s = (NSString*)SWELL_CStringToCFString(t); - [pasteboard setString:s forType:fmt]; - [s release]; - free(t); - } - } - else - { - NSData *data=[NSData dataWithBytes:buf length:bufsz]; - [pasteboard setData:data forType:fmt]; - } - GlobalUnlock(cs->h); - } - } - } - [ar release]; - m_clipsPending.Empty(true); - } -} - -UINT EnumClipboardFormats(UINT lastfmt) // won't enumerate CF_TEXT (since thats a separate pasteboard) -{ - if (!m_clip_curfmts.GetSize()) return 0; - if (lastfmt == 0) return (UINT)(INT_PTR)m_clip_curfmts.Get(0); - int x; - for (x = m_clip_curfmts.GetSize()-2; x >= 0; x--) // scan backwards to avoid dupes causing infinite loops - { - if ((UINT)(INT_PTR)m_clip_curfmts.Get(x) == lastfmt) - return (UINT)(INT_PTR)m_clip_curfmts.Get(x+1); - } - return 0; -} - -HANDLE GetClipboardData(UINT type) -{ - NSString *fmt=m_clip_fmts.Get(type-1); - if (!fmt) return 0; - NSPasteboard *pasteboard = type == CF_TEXT ? [NSPasteboard generalPasteboard] : [NSPasteboard pasteboardWithName:@"SWELL_APP"]; - - HANDLE h=0; - if (type == CF_TEXT) - { - [pasteboard types]; - NSString *str = [pasteboard stringForType:fmt]; - if (str) - { - int l = [str length]*4 + 32; - char *buf = (char *)malloc(l); - if (!buf) return 0; - SWELL_CFStringToCString(str,buf,l); - buf[l-1]=0; - l = strlen(buf)+1; - h=GlobalAlloc(0,l); - memcpy(GlobalLock(h),buf,l); - GlobalUnlock(h); - free(buf); - } - } - else - { - - NSData *data=[pasteboard dataForType:fmt]; - if (!data) return 0; - int l=[data length]; - h=GlobalAlloc(0,l); - memcpy(GlobalLock(h),[data bytes],l); - GlobalUnlock(h); - } - - if (h) m_clip_recs.Add(h); - return h; -} - -void EmptyClipboard() -{ - m_clipsPending.Empty(true); -} - - -void SetClipboardData(UINT type, HANDLE h) -{ - m_clipsPending.Add(new swell_pendingClipboardStates(type,h)); -} - -UINT RegisterClipboardFormat(const char *desc) -{ - NSString *s=NULL; - if (!strcmp(desc,"SWELL__CF_TEXT")) - { - s=NSStringPboardType; - [s retain]; - } - if (!s) s=(NSString*)SWELL_CStringToCFString(desc); - int x; - for (x = 0; x < m_clip_fmts.GetSize(); x ++) - { - NSString *ts=m_clip_fmts.Get(x); - if ([ts compare:s]==NSOrderedSame) - { - [s release]; - return x+1; - } - } - m_clip_fmts.Add(s); - return m_clip_fmts.GetSize(); -} - -int EnumPropsEx(HWND hwnd, PROPENUMPROCEX proc, LPARAM lParam) -{ - if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellEnumProps:lp:)]) return -1; - return (int)[(SWELL_hwndChild *)hwnd swellEnumProps:proc lp:lParam]; -} - -HANDLE GetProp(HWND hwnd, const char *name) -{ - if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellGetProp:wantRemove:)]) return NULL; - return (HANDLE)[(SWELL_hwndChild *)hwnd swellGetProp:name wantRemove:NO]; -} - -BOOL SetProp(HWND hwnd, const char *name, HANDLE val) -{ - if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellSetProp:value:)]) return FALSE; - return (BOOL)!![(SWELL_hwndChild *)hwnd swellSetProp:name value:val]; -} - -HANDLE RemoveProp(HWND hwnd, const char *name) -{ - if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellGetProp:wantRemove:)]) return NULL; - return (HANDLE)[(SWELL_hwndChild *)hwnd swellGetProp:name wantRemove:YES]; -} - - -int GetSystemMetrics(int p) -{ -switch (p) -{ -case SM_CXSCREEN: -case SM_CYSCREEN: -{ - NSScreen *s=[NSScreen mainScreen]; - if (!s) return 1024; - return p==SM_CXSCREEN ? [s frame].size.width : [s frame].size.height; -} -case SM_CXHSCROLL: return 16; -case SM_CYHSCROLL: return 16; -case SM_CXVSCROLL: return 16; -case SM_CYVSCROLL: return 16; -} -return 0; -} - -BOOL ScrollWindow(HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect) -{ - if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) hwnd=(HWND)[(id)hwnd contentView]; - if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return FALSE; - - if (!xamt && !yamt) return FALSE; - - // move child windows only - if (1) - { - if (xamt || yamt) - { - NSArray *ar=[(NSView*)hwnd subviews]; - int i,c=[ar count]; - for(i=0;ihParent && ins->hParent != TVI_ROOT && ins->hParent != TVI_FIRST && ins->hParent != TVI_LAST && ins->hParent != TVI_SORT) - { - if ([tv findItem:ins->hParent parOut:&par idxOut:&inspos]) - { - par = (HTREEITEM__ *)ins->hParent; - } - else return 0; - } - - if (ins->hInsertAfter == TVI_FIRST) inspos=0; - else if (ins->hInsertAfter == TVI_LAST || ins->hInsertAfter == TVI_SORT || !ins->hInsertAfter) inspos=par ? par->m_children.GetSize() : tv->m_items ? tv->m_items->GetSize() : 0; - else inspos = par ? par->m_children.Find((HTREEITEM__*)ins->hInsertAfter)+1 : tv->m_items ? tv->m_items->Find((HTREEITEM__*)ins->hInsertAfter)+1 : 0; - - HTREEITEM__ *item=new HTREEITEM__; - if (ins->item.mask & TVIF_CHILDREN) - item->m_haschildren = !!ins->item.cChildren; - if (ins->item.mask & TVIF_PARAM) item->m_param = ins->item.lParam; - if (ins->item.mask & TVIF_TEXT) item->m_value = strdup(ins->item.pszText); - if (!par) - { - if (!tv->m_items) tv->m_items = new WDL_PtrList; - tv->m_items->Insert(inspos,item); - } - else par->m_children.Insert(inspos,item); - - [tv reloadData]; - return (HTREEITEM) item; -} - -BOOL TreeView_Expand(HWND hwnd, HTREEITEM item, UINT flag) -{ - if (!hwnd || !item) return false; - - if (![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return false; - - SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; - - id itemid=((HTREEITEM__*)item)->m_dh; - bool isExp=!![tv isItemExpanded:itemid]; - - if (flag == TVE_EXPAND && !isExp) [tv expandItem:itemid]; - else if (flag == TVE_COLLAPSE && isExp) [tv collapseItem:itemid]; - else if (flag==TVE_TOGGLE) - { - if (isExp) [tv collapseItem:itemid]; - else [tv expandItem:itemid]; - } - else return FALSE; - - return TRUE; - -} - -HTREEITEM TreeView_GetSelection(HWND hwnd) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; - - SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; - int idx=[tv selectedRow]; - if (idx<0) return NULL; - - SWELL_DataHold *t=[tv itemAtRow:idx]; - if (t) return (HTREEITEM)[t getValue]; - return NULL; - -} - -void TreeView_DeleteItem(HWND hwnd, HTREEITEM item) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; - SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; - - HTREEITEM__ *par=NULL; - int idx=0; - - if ([tv findItem:item parOut:&par idxOut:&idx]) - { - if (par) - { - par->m_children.Delete(idx,true); - } - else if (tv->m_items) - { - tv->m_items->Delete(idx,true); - } - [tv reloadData]; - } -} - -void TreeView_SelectItem(HWND hwnd, HTREEITEM item) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; - - int row=[(SWELL_TreeView*)hwnd rowForItem:((HTREEITEM__*)item)->m_dh]; - if (row>=0) - [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; - static int __rent; - if (!__rent) - { - __rent=1; - NMTREEVIEW nm={{(HWND)hwnd,[(SWELL_TreeView*)hwnd tag],TVN_SELCHANGED},}; - SendMessage(GetParent(hwnd),WM_NOTIFY,[(SWELL_TreeView*)hwnd tag],(LPARAM)&nm); - __rent=0; - } -} - -BOOL TreeView_GetItem(HWND hwnd, LPTVITEM pitem) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; - - HTREEITEM__ *ti = (HTREEITEM__*)pitem->hItem; - pitem->cChildren = ti->m_haschildren ? 1:0; - pitem->lParam = ti->m_param; - if ((pitem->mask&TVIF_TEXT)&&pitem->pszText&&pitem->cchTextMax>0) - { - lstrcpyn(pitem->pszText,ti->m_value?ti->m_value:"",pitem->cchTextMax); - } - pitem->state=0; - - - int itemRow = [(SWELL_TreeView*)hwnd rowForItem:ti->m_dh]; - if (itemRow >= 0 && [(SWELL_TreeView*)hwnd isRowSelected:itemRow]) - pitem->state |= TVIS_SELECTED; - if ([(SWELL_TreeView*)hwnd isItemExpanded:ti->m_dh]) - pitem->state |= TVIS_EXPANDED; - - return TRUE; -} - -BOOL TreeView_SetItem(HWND hwnd, LPTVITEM pitem) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; - - HTREEITEM__ *par=NULL; - int idx=0; - - if (![(SWELL_TreeView*)hwnd findItem:pitem->hItem parOut:&par idxOut:&idx]) return FALSE; - - HTREEITEM__ *ti = (HTREEITEM__*)pitem->hItem; - - if (pitem->mask & TVIF_CHILDREN) ti->m_haschildren = pitem->cChildren?1:0; - if (pitem->mask & TVIF_PARAM) ti->m_param = pitem->lParam; - - if ((pitem->mask&TVIF_TEXT)&&pitem->pszText) - { - free(ti->m_value); - ti->m_value=strdup(pitem->pszText); - InvalidateRect(hwnd, 0, FALSE); - } - - if (pitem->stateMask & TVIS_SELECTED) - { - int itemRow = [(SWELL_TreeView*)hwnd rowForItem:ti->m_dh]; - if (itemRow >= 0) - { - if (pitem->state&TVIS_SELECTED) - { - [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:NO]; - - static int __rent; - if (!__rent) - { - __rent=1; - NMTREEVIEW nm={{(HWND)hwnd,[(SWELL_TreeView*)hwnd tag],TVN_SELCHANGED},}; - SendMessage(GetParent(hwnd),WM_NOTIFY,[(SWELL_TreeView*)hwnd tag],(LPARAM)&nm); - __rent=0; - } - - } - else - { - // todo figure out unselect?! -// [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:NO]; - } - } - } - - if (pitem->stateMask & TVIS_EXPANDED) - TreeView_Expand(hwnd,pitem->hItem,(pitem->state&TVIS_EXPANDED)?TVE_EXPAND:TVE_COLLAPSE); - - - return TRUE; -} - -HTREEITEM TreeView_HitTest(HWND hwnd, TVHITTESTINFO *hti) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !hti) return NULL; - SWELL_TreeView* tv = (SWELL_TreeView*)hwnd; - int x = hti->pt.x; - int y = hti->pt.y; - - int i; - for (i = 0; i < [tv numberOfRows]; ++i) - { - NSRect r = [tv rectOfRow:i]; - if (x >= r.origin.x && x < r.origin.x+r.size.width && y >= r.origin.y && y < r.origin.y+r.size.height) - { - SWELL_DataHold* t = [tv itemAtRow:i]; - if (t) return (HTREEITEM)[t getValue]; - return 0; - } - } - - return NULL; // not hit -} - -HTREEITEM TreeView_GetRoot(HWND hwnd) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; - SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; - - if (!tv->m_items) return 0; - return (HTREEITEM) tv->m_items->Get(0); -} - -HTREEITEM TreeView_GetChild(HWND hwnd, HTREEITEM item) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; - - HTREEITEM__ *titem=(HTREEITEM__ *)item; - if (!titem) return TreeView_GetRoot(hwnd); - - return (HTREEITEM) titem->m_children.Get(0); -} -HTREEITEM TreeView_GetNextSibling(HWND hwnd, HTREEITEM item) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; - SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; - - if (!item) return TreeView_GetRoot(hwnd); - - HTREEITEM__ *par=NULL; - int idx=0; - if ([tv findItem:item parOut:&par idxOut:&idx]) - { - if (par) - { - return par->m_children.Get(idx+1); - } - } - return 0; -} - -void TreeView_SetBkColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; - [(NSOutlineView*)hwnd setBackgroundColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]]; -} -void TreeView_SetTextColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; - - SWELL_TreeView *f = (SWELL_TreeView *)hwnd; - [f->m_fgColor release]; - f->m_fgColor = [NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]; - [f->m_fgColor retain]; -} -void ListView_SetBkColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; - [(NSTableView*)hwnd setBackgroundColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]]; -} - -void ListView_SetSelColors(HWND hwnd, int *colors, int ncolors) // this works for SWELL_ListView as well as SWELL_TreeView -{ - if (!hwnd) return; - NSMutableArray *ar=[[NSMutableArray alloc] initWithCapacity:ncolors]; - if (ncolors>0 && colors) - { - ar = [[NSMutableArray alloc] initWithCapacity:ncolors]; - while (ncolors-->0) - { - int color = *colors++; - [ar addObject:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]]; - } - } - - if ([(id)hwnd isKindOfClass:[SWELL_ListView class]]) - { - SWELL_ListView *lv = (SWELL_ListView*)hwnd; - [lv->m_selColors release]; - lv->m_selColors=ar; - } - else if ([(id)hwnd isKindOfClass:[SWELL_TreeView class]]) - { - SWELL_TreeView *lv = (SWELL_TreeView*)hwnd; - [lv->m_selColors release]; - lv->m_selColors=ar; - } - else - { - [ar release]; - } -} -void ListView_SetGridColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; - [(NSTableView*)hwnd setGridColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]]; -} -void ListView_SetTextBkColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; - // not implemented atm -} -void ListView_SetTextColor(HWND hwnd, int color) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; - - SWELL_ListView *f = (SWELL_ListView *)hwnd; - [f->m_fgColor release]; - f->m_fgColor = [NSColor colorWithCalibratedRed:GetRValue(color)/255.0f - green:GetGValue(color)/255.0f - blue:GetBValue(color)/255.0f alpha:1.0f]; - [f->m_fgColor retain]; -} - - -BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah) -{ - if (content1 && !strnicmp(content1,"http://",7)) - { - NSWorkspace *wk = [NSWorkspace sharedWorkspace]; - if (!wk) return FALSE; - NSString *fnstr=(NSString *)SWELL_CStringToCFString(content1); - BOOL ret=[wk openURL:[NSURL URLWithString:fnstr]]; - [fnstr release]; - return ret; - } - - if (content1 && !stricmp(content1,"explorer.exe")) content1=""; - else if (content1 && (!stricmp(content1,"notepad.exe")||!stricmp(content1,"notepad"))) content1="TextEdit.app"; - - if (content2 && !stricmp(content2,"explorer.exe")) content2=""; - - if (content1 && content2 && *content1 && *content2) - { - NSWorkspace *wk = [NSWorkspace sharedWorkspace]; - if (!wk) return FALSE; - NSString *appstr=(NSString *)SWELL_CStringToCFString(content1); - NSString *fnstr=(NSString *)SWELL_CStringToCFString(content2); - BOOL ret=[wk openFile:fnstr withApplication:appstr andDeactivate:YES]; - [fnstr release]; - [appstr release]; - return ret; - } - else if ((content1&&*content1) || (content2&&*content2)) - { - const char *fn = (content1 && *content1) ? content1 : content2; - NSWorkspace *wk = [NSWorkspace sharedWorkspace]; - if (!wk) return FALSE; - NSString *fnstr=(NSString *)SWELL_CStringToCFString(fn); - BOOL ret; - - if (strlen(fn)>4 && !stricmp(fn+strlen(fn)-4,".app")) ret=[wk launchApplication:fnstr]; - else ret=[wk openFile:fnstr]; - - [fnstr release]; - return ret; - } - return FALSE; -} - - - - -@implementation SWELL_FocusRectWnd - --(BOOL)isOpaque { return YES; } --(void) drawRect:(NSRect)rect -{ - NSColor *col=[NSColor colorWithCalibratedRed:0.5 green:0.5 blue:0.5 alpha:1.0]; - [col set]; - - CGRect r = CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); - - CGContextRef ctx = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; - - CGContextFillRect(ctx,r); - -} -@end - -// r=NULL to "free" handle -// otherwise r is in hwndPar coordinates -void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) -{ - if (!handle) return; - NSWindow *wnd = (NSWindow *)*handle; - - if (!rct) - { - if (wnd) - { - NSWindow *ow=[wnd parentWindow]; - if (ow) [ow removeChildWindow:wnd]; -// [wnd setParentWindow:nil]; - [wnd close]; - *handle=0; - } - } - else - { - RECT r=*rct; - if (hwndPar) - { - ClientToScreen(hwndPar,((LPPOINT)&r)); - ClientToScreen(hwndPar,((LPPOINT)&r)+1); - } - else - { - // todo: flip? - } - if (r.top>r.bottom) { int a=r.top; r.top=r.bottom;r.bottom=a; } - NSRect rr=NSMakeRect(r.left,r.top,r.right-r.left,r.bottom-r.top); - - NSWindow *par=nil; - if (hwndPar) - { - if ([(id)hwndPar isKindOfClass:[NSWindow class]]) par=(NSWindow *)hwndPar; - else if ([(id)hwndPar isKindOfClass:[NSView class]]) par=[(NSView *)hwndPar window]; - else return; - } - - if (wnd && ([wnd parentWindow] != par)) - { - NSWindow *ow=[wnd parentWindow]; - if (ow) [ow removeChildWindow:wnd]; - // [wnd setParentWindow:nil]; - [wnd close]; - *handle=0; - wnd=0; - } - - if (!wnd) - { - *handle = wnd = [[NSWindow alloc] initWithContentRect:rr styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [wnd setOpaque:YES]; - [wnd setAlphaValue:0.5]; - [wnd setExcludedFromWindowsMenu:YES]; - [wnd setIgnoresMouseEvents:YES]; - [wnd setContentView:[[SWELL_FocusRectWnd alloc] init]]; - - if (par) [par addChildWindow:wnd ordered:NSWindowAbove]; - else - { - [wnd setLevel:NSPopUpMenuWindowLevel]; - [wnd orderFront:wnd]; - } - // [wnd setParentWindow:par]; -// [wnd orderWindow:NSWindowAbove relativeTo:[par windowNumber]]; - } - - [wnd setFrame:rr display:YES]; - } -} - - -@implementation SWELL_PopUpButton -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(void)setSwellStyle:(LONG)style { m_style=style; } --(LONG)getSwellStyle { return m_style; } -@end - -@implementation SWELL_ComboBox -STANDARD_CONTROL_NEEDSDISPLAY_IMPL - --(void)setSwellStyle:(LONG)style { m_style=style; } --(LONG)getSwellStyle { return m_style; } --(id)init { self = [super init]; if (self) { m_ids=new WDL_PtrList; } return self; } --(void)dealloc { delete m_ids; [super dealloc]; } -@end - - - - -bool SWELL_HandleMouseEvent(NSEvent *evt) -{ - int etype = [evt type]; - if (GetCapture()) return false; - if (etype >= NSLeftMouseDown && etype <= NSRightMouseDragged) - { - } - else return false; - - NSWindow *w = [evt window]; - if (w) - { - NSView *cview = [w contentView]; - NSView *besthit=NULL; - if (cview) - { - NSPoint lpt = [evt locationInWindow]; - NSView *hitv=[cview hitTest:lpt]; - lpt = [w convertBaseToScreen:lpt]; - - int xpos=(int)floor(lpt.x); - int ypos=(int)floor(lpt.y); - - while (hitv) - { - int ht=(int)sendSwellMessage(hitv,WM_NCHITTEST,0,MAKELPARAM(xpos,ypos)); - if (ht && ht != HTCLIENT) besthit=hitv; - - if (hitv==cview) break; - hitv = [hitv superview]; - } - } - if (besthit) - { - if (etype == NSLeftMouseDown) [besthit mouseDown:evt]; - else if (etype == NSLeftMouseUp) [besthit mouseUp:evt]; - else if (etype == NSLeftMouseDragged) [besthit mouseDragged:evt]; - else if (etype == NSRightMouseDown) [besthit rightMouseDown:evt]; - else if (etype == NSRightMouseUp) [besthit rightMouseUp:evt]; - else if (etype == NSRightMouseDragged) [besthit rightMouseDragged:evt]; - else if (etype == NSMouseMoved) [besthit mouseMoved:evt]; - else return false; - - return true; - } - } - return false; -} - -int SWELL_GetWindowWantRaiseAmt(HWND h) -{ - SWELL_ModelessWindow* mw=0; - if ([(id)h isKindOfClass:[SWELL_ModelessWindow class]]) - { - mw=(SWELL_ModelessWindow*)h; - } - else if ([(id)h isKindOfClass:[NSView class]]) - { - NSWindow* wnd=[(NSView*)h window]; - if (wnd && [wnd isKindOfClass:[SWELL_ModelessWindow class]]) - { - mw=(SWELL_ModelessWindow*)wnd; - } - } - if (mw) return mw->m_wantraiseamt; - return 0; -} - -void SWELL_SetWindowWantRaiseAmt(HWND h, int amt) -{ - SWELL_ModelessWindow *mw=NULL; - if ([(id)h isKindOfClass:[SWELL_ModelessWindow class]]) mw=(SWELL_ModelessWindow *)h; - else if ([(id)h isKindOfClass:[NSView class]]) - { - NSWindow *w = [(NSView *)h window]; - if (w && [w isKindOfClass:[SWELL_ModelessWindow class]]) mw = (SWELL_ModelessWindow*)w; - } - if (mw) - { - int diff = amt - mw->m_wantraiseamt; - mw->m_wantraiseamt = amt; - if (diff && [NSApp isActive]) [mw setLevel:[mw level]+diff]; - } -} - - -int SWELL_SetWindowLevel(HWND hwnd, int newlevel) -{ - NSWindow *w = (NSWindow *)hwnd; - if (w && [w isKindOfClass:[NSView class]]) w= [(NSView *)w window]; - - if (w && [w isKindOfClass:[NSWindow class]]) - { - int ol = [w level]; - [w setLevel:newlevel]; - return ol; - } - return 0; -} - -void SetOpaque(HWND h, bool opaque) -{ - if (!h || ![(id)h isKindOfClass:[SWELL_hwndChild class]]) return; - SWELL_hwndChild* v = (SWELL_hwndChild*)h; - [v setOpaque:opaque]; -} - -void SetTransparent(HWND h) -{ - if (!h) return; - NSWindow* wnd=0; - if ([(id)h isKindOfClass:[NSWindow class]]) wnd=(NSWindow*)h; - else if ([(id)h isKindOfClass:[NSView class]]) wnd=[(NSView*)h window]; - if (wnd) - { - [wnd setBackgroundColor:[NSColor clearColor]]; - [wnd setOpaque:NO]; - } -} - -int SWELL_GetDefaultButtonID(HWND hwndDlg, bool onlyIfEnabled) -{ - if (![(id)hwndDlg isKindOfClass:[NSView class]]) return 0; - NSWindow *wnd = [(NSView *)hwndDlg window]; - NSButtonCell * cell = wnd ? [wnd defaultButtonCell] : nil; - NSView *view; - if (!cell || !(view=[cell controlView])) return 0; - int cmdid = [view tag]; - if (cmdid && onlyIfEnabled) - { - if (![cell isEnabled]) return 0; - } - return cmdid; -} - - -void SWELL_SetWindowRepre(HWND hwnd, const char *fn, bool isDirty) -{ - if (!hwnd) return; - NSWindow *w = NULL; - if ([(id)hwnd isKindOfClass:[NSWindow class]]) w=(NSWindow *)hwnd; - if ([(id)hwnd isKindOfClass:[NSView class]]) w=[(NSView *)hwnd window]; - - if (w) - { - if (GetProp((HWND)[w contentView],"SWELL_DisableWindowRepre")) return; - - [w setDocumentEdited:isDirty]; - - if (!fn || !*fn) [w setRepresentedFilename:@""]; - else - { - NSString *str = (NSString *)SWELL_CStringToCFString(fn); - [w setRepresentedFilename:str]; - [str release]; - } - } -} - -int g_swell_terminating; -void SWELL_PostQuitMessage(void *sender) -{ - g_swell_terminating=true; - - [NSApp terminate:(id)sender]; -} - -void SWELL_SetWindowShadow(HWND hwnd, bool shadow) -{ - if (!hwnd) return; - NSWindow *w = (NSWindow *)hwnd; - if ([w isKindOfClass:[NSView class]]) w = [(NSView *)w window]; - if (w && [w isKindOfClass:[NSWindow class]]) [w setHasShadow:shadow]; -} - -#if 0 // not sure if this will interfere with coolSB -BOOL ShowScrollBar(HWND hwnd, int nBar, BOOL vis) -{ - int v=0; - if (nBar == SB_HORZ || nBar == SB_BOTH) v |= WS_HSCROLL; - if (nBar == SB_VERT || nBar == SB_BOTH) v |= WS_VSCROLL; - if (v) - { - int s=GetWindowLong(hwnd, GWL_STYLE); - if (vis) s |= v; - else s &= ~v; - SetWindowLong(hwnd, GWL_STYLE, s); - SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - return TRUE; - } - return FALSE; -} -#endif - - -void SWELL_GenerateDialogFromList(const void *_list, int listsz) -{ -#define SIXFROMLIST list->p1,list->p2,list->p3, list->p4, list->p5, list->p6 - SWELL_DlgResourceEntry *list = (SWELL_DlgResourceEntry*)_list; - while (listsz>0) - { - if (!strcmp(list->str1,"__SWELL_BUTTON")) - { - SWELL_MakeButton(list->flag1,list->str2, SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_EDIT")) - { - SWELL_MakeEditField(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_COMBO")) - { - SWELL_MakeCombo(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_LISTBOX")) - { - SWELL_MakeListBox(SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_GROUP")) - { - SWELL_MakeGroupBox(list->str2,SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_CHECKBOX")) - { - SWELL_MakeCheckBox(list->str2,SIXFROMLIST); - } - else if (!strcmp(list->str1,"__SWELL_LABEL")) - { - SWELL_MakeLabel(list->flag1, list->str2, SIXFROMLIST); - } - else if (*list->str2) - { - SWELL_MakeControl(list->str1, list->flag1, list->str2, SIXFROMLIST); - } - listsz--; - list++; - } -} - -BOOL EnumChildWindows(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam) -{ - if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return TRUE; - NSArray *ar = [(NSView *)hwnd subviews]; - if (ar) - { - [ar retain]; - int x,n=[ar count]; - for (x=0;xleft=r->top=0; - r->right = (int)frnew.size.width; - r->bottom = (int)frnew.size.height; - } -} - -BOOL SWELL_IsGroupBox(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[SWELL_BoxView class]]) return TRUE; - return FALSE; -} -BOOL SWELL_IsButton(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[SWELL_Button class]]) return TRUE; - return FALSE; -} -BOOL SWELL_IsStaticText(HWND hwnd) -{ - if (hwnd && [(id)hwnd isKindOfClass:[NSTextField class]]) return TRUE; - //todo - return FALSE; -} - - -bool SWELL_SetAppAutoHideMenuAndDock(int ah) -{ - static char _init; - static NSUInteger _defpres; - if (!_init) - { - _init=-1; - SInt32 v=0x1040; - Gestalt(gestaltSystemVersion,&v); - if (v>=0x1060) - { - _init=1; - _defpres = [(SWELL_AppExtensions*)[NSApplication sharedApplication] presentationOptions]; - } - } - if (_init > 0) - { - const int NSApplicationPresentationAutoHideDock = (1 << 0), - NSApplicationPresentationHideDock = (1<<1), - NSApplicationPresentationAutoHideMenuBar = (1 << 2); - - if (ah>0) [(SWELL_AppExtensions*)[NSApplication sharedApplication] setPresentationOptions:((ah>=2?NSApplicationPresentationHideDock:NSApplicationPresentationAutoHideDock)|NSApplicationPresentationAutoHideMenuBar)]; - else [(SWELL_AppExtensions*)[NSApplication sharedApplication] setPresentationOptions:_defpres]; - return true; - } - return false; -} - -#endif diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp deleted file mode 100644 index 818bb486..00000000 --- a/WDL/swell/swell.cpp +++ /dev/null @@ -1,909 +0,0 @@ - -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) - Copyright (C) 2006-2007, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file implements a few Windows calls using their posix equivilents - - */ - -#ifndef SWELL_PROVIDED_BY_APP - - -#include "swell.h" -#include -#include -#include -#include -#include - - -#include "swell-internal.h" - - -#ifdef __APPLE__ -#include -#include -#include -#endif - - -#include - - -#include "../mutex.h" -#include "../assocarray.h" - -void Sleep(int ms) -{ - usleep(ms?ms*1000:100); -} - -DWORD GetTickCount() -{ - struct timeval tm={0,}; - gettimeofday(&tm,NULL); - return tm.tv_sec*1000 + tm.tv_usec/1000; -} - - -static void intToFileTime(time_t t, FILETIME *out) -{ - unsigned long long a=(unsigned long long)t; // seconds since january 1st, 1970 - a+=(60*60*24*(365*4+1)/4)*(long long)(1970-1601); // this is approximate - a*=1000*10000; // seconds to 1/10th microseconds (100 nanoseconds) - out->dwLowDateTime=a & 0xffffffff; - out->dwHighDateTime=a>>32; -} - -BOOL GetFileTime(int filedes, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime) -{ - if (filedes<0) return 0; - struct stat st; - if (fstat(filedes,&st)) return 0; - - if (lpCreationTime) intToFileTime(st.st_ctime,lpCreationTime); - if (lpLastAccessTime) intToFileTime(st.st_atime,lpLastAccessTime); - if (lpLastWriteTime) intToFileTime(st.st_mtime,lpLastWriteTime); - - return 1; -} - -BOOL SWELL_PtInRect(RECT *r, POINT p) -{ - if (!r) return FALSE; - int tp=r->top; - int bt=r->bottom; - if (tp>bt) - { - bt=tp; - tp=r->bottom; - } - return p.x>=r->left && p.xright && p.y >= tp && p.y < bt; -} - - -int MulDiv(int a, int b, int c) -{ - if(c == 0) return 0; - return (int)((double)a*(double)b/c); -} - -unsigned int _controlfp(unsigned int flag, unsigned int mask) -{ -#if !defined(__ppc__) && !defined(__LP64__) - unsigned short ret; - mask &= _MCW_RC; // don't let the caller set anything other than round control for now - __asm__ __volatile__("fnstcw %0\n\t":"=m"(ret)); - ret=(ret&~(mask<<2))|(flag<<2); - - if (mask) __asm__ __volatile__( - "fldcw %0\n\t"::"m"(ret)); - return (unsigned int) (ret>>2); -#else - return 0; -#endif -} - - -BOOL CloseHandle(HANDLE hand) -{ - SWELL_InternalObjectHeader *hdr=(SWELL_InternalObjectHeader*)hand; - if (!hdr) return FALSE; - if (hdr->type <= INTERNAL_OBJECT_START || hdr->type >= INTERNAL_OBJECT_END) return FALSE; - -#ifdef SWELL_TARGET_OSX - if (!OSAtomicDecrement32(&hdr->count)) -#else - if (!--hdr->count) // todo: atomic decrement on posix/ glib? -#endif - { - switch (hdr->type) - { - case INTERNAL_OBJECT_FILE: - { - SWELL_InternalObjectHeader_File *file = (SWELL_InternalObjectHeader_File*)hdr; - if (file->fp) fclose(file->fp); - } - break; - case INTERNAL_OBJECT_EXTERNALSOCKET: return FALSE; // pure sockets are not to be closed this way; - case INTERNAL_OBJECT_SOCKETEVENT: - { - SWELL_InternalObjectHeader_SocketEvent *se= (SWELL_InternalObjectHeader_SocketEvent *)hdr; - if (se->socket[0]>=0) close(se->socket[0]); - if (se->socket[1]>=0) close(se->socket[1]); - } - break; - case INTERNAL_OBJECT_EVENT: - { - SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hdr; - pthread_cond_destroy(&evt->cond); - pthread_mutex_destroy(&evt->mutex); - } - break; - case INTERNAL_OBJECT_THREAD: - { - SWELL_InternalObjectHeader_Thread *thr = (SWELL_InternalObjectHeader_Thread*)hdr; - void *tmp; - pthread_join(thr->pt,&tmp); - pthread_detach(thr->pt); - } - break; -#ifdef __APPLE__ - case INTERNAL_OBJECT_NSTASK: - { - SWELL_InternalObjectHeader_NSTask *nst = (SWELL_InternalObjectHeader_NSTask*)hdr; - extern void SWELL_ReleaseNSTask(void *); - if (nst->task) SWELL_ReleaseNSTask(nst->task); - } - break; -#endif - } - free(hdr); - } - return TRUE; -} - -HANDLE CreateEventAsSocket(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored) -{ - SWELL_InternalObjectHeader_SocketEvent *buf = (SWELL_InternalObjectHeader_SocketEvent*)malloc(sizeof(SWELL_InternalObjectHeader_SocketEvent)); - buf->hdr.type=INTERNAL_OBJECT_SOCKETEVENT; - buf->hdr.count=1; - buf->autoReset = !manualReset; - buf->socket[0]=buf->socket[1]=-1; - if (socketpair(AF_UNIX,SOCK_STREAM,0,buf->socket)<0) - { - free(buf); - return 0; - } - fcntl(buf->socket[0], F_SETFL, fcntl(buf->socket[0],F_GETFL) | O_NONBLOCK); // nonblocking - - char c=0; - if (initialSig&&buf->socket[1]>=0) write(buf->socket[1],&c,1); - - return buf; -} - -DWORD WaitForAnySocketObject(int numObjs, HANDLE *objs, DWORD msTO) // only supports special (socket) handles at the moment -{ - int max_s=0; - fd_set s; - FD_ZERO(&s); - int x; - for (x = 0; x < numObjs; x ++) - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)objs[x]; - if ((se->hdr.type == INTERNAL_OBJECT_EXTERNALSOCKET || se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) && se->socket[0]>=0) - { - FD_SET(se->socket[0],&s); - if (se->socket[0] > max_s) max_s = se->socket[0]; - } - } - - if (max_s>0) - { -again: - struct timeval tv={msTO/1000,(msTO%1000)*1000}; - if (select(max_s+1,&s,NULL,NULL,msTO==INFINITE?NULL:&tv)>0) for (x = 0; x < numObjs; x ++) - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)objs[x]; - if ((se->hdr.type == INTERNAL_OBJECT_EXTERNALSOCKET || se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) && se->socket[0]>=0) - { - if (FD_ISSET(se->socket[0],&s)) - { - if (se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT && se->autoReset) - { - char buf[128]; - if (read(se->socket[0],buf,sizeof(buf))<1) goto again; - } - return WAIT_OBJECT_0 + x; - } - } - } - } - - return WAIT_TIMEOUT; -} - -DWORD WaitForSingleObject(HANDLE hand, DWORD msTO) -{ - SWELL_InternalObjectHeader *hdr=(SWELL_InternalObjectHeader*)hand; - if (!hdr) return WAIT_FAILED; - - switch (hdr->type) - { -#ifdef __APPLE__ - case INTERNAL_OBJECT_NSTASK: - { - SWELL_InternalObjectHeader_NSTask *nst = (SWELL_InternalObjectHeader_NSTask*)hdr; - extern DWORD SWELL_WaitForNSTask(void *,DWORD); - if (nst->task) return SWELL_WaitForNSTask(nst->task,msTO); - } - break; -#endif - case INTERNAL_OBJECT_THREAD: - { - SWELL_InternalObjectHeader_Thread *thr = (SWELL_InternalObjectHeader_Thread*)hdr; - void *tmp; - if (!thr->done) - { - if (!msTO) return WAIT_TIMEOUT; - if (msTO != INFINITE) - { - DWORD d=GetTickCount()+msTO; - while (GetTickCount()done) Sleep(1); - if (!thr->done) return WAIT_TIMEOUT; - } - } - - if (!pthread_join(thr->pt,&tmp)) return WAIT_OBJECT_0; - } - break; - case INTERNAL_OBJECT_EXTERNALSOCKET: - case INTERNAL_OBJECT_SOCKETEVENT: - { - SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)hdr; - if (se->socket[0]<0) Sleep(msTO!=INFINITE?msTO:1); - else - { - fd_set s; - FD_ZERO(&s); -again: - FD_SET(se->socket[0],&s); - struct timeval tv={msTO/1000,(msTO%1000)*1000}; - if (select(se->socket[0]+1,&s,NULL,NULL,msTO==INFINITE?NULL:&tv)>0 && FD_ISSET(se->socket[0],&s)) - { - if (se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT && se->autoReset) - { - char buf[128]; - if (read(se->socket[0],buf,sizeof(buf))<1) goto again; - } - return WAIT_OBJECT_0; - } - return WAIT_TIMEOUT; - } - } - break; - case INTERNAL_OBJECT_EVENT: - { - SWELL_InternalObjectHeader_Event *evt = (SWELL_InternalObjectHeader_Event*)hdr; - int rv=WAIT_OBJECT_0; - pthread_mutex_lock(&evt->mutex); - if (msTO == 0) - { - if (!evt->isSignal) rv=WAIT_TIMEOUT; - } - else if (msTO == INFINITE) - { - while (!evt->isSignal) pthread_cond_wait(&evt->cond,&evt->mutex); - } - else - { - // timed wait - struct timespec ts={msTO/1000, (msTO%1000)*1000000}; - while (!evt->isSignal) - { -#ifdef SWELL_TARGET_OSX - if (pthread_cond_timedwait_relative_np(&evt->cond,&evt->mutex,&ts)==ETIMEDOUT) - { - rv = WAIT_TIMEOUT; - break; - } -#else -#if 1 - struct timeval tm={0,}; - gettimeofday(&tm,NULL); - ts.tv_sec += tm.tv_sec; - ts.tv_nsec += tm.tv_usec * 1000; -#else - struct timespec ts2={0,0,}; - clock_gettime(CLOCK_REALTIME,&ts2); - ts.tv_sec += ts2.tv_sec; - ts.tv_nsec += ts2.tv_nsec; -#endif - if (ts.tv_nsec>=1000000000) - { - int n = ts.tv_nsec/1000000000; - ts.tv_sec+=n; - ts.tv_nsec -= ((long long)n * (long long)1000000000); - } - if (pthread_cond_timedwait(&evt->cond,&evt->mutex,&ts)) - { - rv = WAIT_TIMEOUT; - break; - } -#endif - // we should track/correct the timeout amount here since in theory we could end up waiting a bit longer! - } - } - if (!evt->isManualReset && rv==WAIT_OBJECT_0) evt->isSignal=false; - pthread_mutex_unlock(&evt->mutex); - - return rv; - } - break; - } - - return WAIT_FAILED; -} - -static void *__threadproc(void *parm) -{ -#ifdef SWELL_TARGET_OSX - void *arp=SWELL_InitAutoRelease(); -#endif - - SWELL_InternalObjectHeader_Thread *t=(SWELL_InternalObjectHeader_Thread*)parm; - t->retv=t->threadProc(t->threadParm); - t->done=1; - CloseHandle(parm); - -#ifdef SWELL_TARGET_OSX - SWELL_QuitAutoRelease(arp); -#endif - - pthread_exit(0); - return 0; -} - -DWORD GetCurrentThreadId() -{ - return (DWORD)(INT_PTR)pthread_self(); // this is incorrect on x64 -} - -HANDLE CreateEvent(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored) -{ - SWELL_InternalObjectHeader_Event *buf = (SWELL_InternalObjectHeader_Event*)malloc(sizeof(SWELL_InternalObjectHeader_Event)); - buf->hdr.type=INTERNAL_OBJECT_EVENT; - buf->hdr.count=1; - buf->isSignal = !!initialSig; - buf->isManualReset = !!manualReset; - - pthread_mutex_init(&buf->mutex,NULL); - pthread_cond_init(&buf->cond,NULL); - - return (HANDLE)buf; -} - -HANDLE CreateThread(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut) -{ -#ifdef SWELL_TARGET_OSX - SWELL_EnsureMultithreadedCocoa(); -#endif - SWELL_InternalObjectHeader_Thread *buf = (SWELL_InternalObjectHeader_Thread *)malloc(sizeof(SWELL_InternalObjectHeader_Thread)); - buf->hdr.type=INTERNAL_OBJECT_THREAD; - buf->hdr.count=2; - buf->threadProc=ThreadProc; - buf->threadParm = parm; - buf->retv=0; - buf->pt=0; - buf->done=0; - pthread_create(&buf->pt,NULL,__threadproc,buf); - - if (tidOut) *tidOut=(DWORD)(INT_PTR)buf->pt; // incorrect on x64 - - return (HANDLE)buf; -} - - -BOOL SetThreadPriority(HANDLE hand, int prio) -{ - SWELL_InternalObjectHeader_Thread *evt=(SWELL_InternalObjectHeader_Thread*)hand; - if (!evt || evt->hdr.type != INTERNAL_OBJECT_THREAD) return FALSE; - - if (evt->done) return FALSE; - - int pol; - struct sched_param param; - if (!pthread_getschedparam(evt->pt,&pol,¶m)) - { - -// printf("thread prio %d(%d,%d), %d(FIFO=%d, RR=%d)\n",param.sched_priority, sched_get_priority_min(pol),sched_get_priority_max(pol), pol,SCHED_FIFO,SCHED_RR); - param.sched_priority = 31 + prio; - int mt=sched_get_priority_min(pol); - if (param.sched_priority (mt=sched_get_priority_max(pol)))param.sched_priority=mt; - - if (!pthread_setschedparam(evt->pt,pol,¶m)) - { - return TRUE; - } - } - - - - return FALSE; -} - -BOOL SetEvent(HANDLE hand) -{ - SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hand; - if (!evt) return FALSE; - if (evt->hdr.type == INTERNAL_OBJECT_EVENT) - { - pthread_mutex_lock(&evt->mutex); - if (!evt->isSignal) - { - evt->isSignal = true; - if (evt->isManualReset) pthread_cond_broadcast(&evt->cond); - else pthread_cond_signal(&evt->cond); - } - pthread_mutex_unlock(&evt->mutex); - return TRUE; - } - if (evt->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) - { - SWELL_InternalObjectHeader_SocketEvent *se=(SWELL_InternalObjectHeader_SocketEvent*)hand; - if (se->socket[1]>=0) - { - if (se->socket[0]>=0) - { - fd_set s; - FD_ZERO(&s); - FD_SET(se->socket[0],&s); - struct timeval tv={0,}; - if (select(se->socket[0]+1,&s,NULL,NULL,&tv)>0 && FD_ISSET(se->socket[0],&s)) return TRUE; // already set - } - char c=0; - write(se->socket[1],&c,1); - } - return TRUE; - } - return FALSE; -} -BOOL ResetEvent(HANDLE hand) -{ - SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hand; - if (!evt) return FALSE; - if (evt->hdr.type == INTERNAL_OBJECT_EVENT) - { - evt->isSignal=false; - return TRUE; - } - if (evt->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) - { - SWELL_InternalObjectHeader_SocketEvent *se=(SWELL_InternalObjectHeader_SocketEvent*)hand; - if (se->socket[0]>=0) - { - char buf[128]; - read(se->socket[0],buf,sizeof(buf)); - } - return TRUE; - } - return FALSE; -} - -HANDLE CreateFile( const char * lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - void *lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile) -{ - return 0;// INVALID_HANDLE_VALUE; -} - -DWORD SetFilePointer(HANDLE hFile, DWORD low, DWORD *high) -{ - SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; - if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || (high && *high) || fseek(file->fp,low,SEEK_SET)==-1) { if (high) *high=0xffffffff; return 0xffffffff; } - return ftell(file->fp); -} - -DWORD GetFilePointer(HANDLE hFile, DWORD *high) -{ - int pos; - SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; - if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || (pos=ftell(file->fp))==-1) { if (high) *high=0xffffffff; return 0xffffffff; } - if (high) *high=0; - return (DWORD)pos; -} - -DWORD GetFileSize(HANDLE hFile, DWORD *high) -{ - SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; - if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp) { if (high) *high=0xffffffff; return 0xffffffff; } - - int a=ftell(file->fp); - fseek(file->fp,0,SEEK_END); - int ret=ftell(file->fp); - fseek(file->fp,a,SEEK_SET); - - if (high) *high=ret==-1 ? 0xffffffff: 0; - return (DWORD)ret; -} - - - -BOOL WriteFile(HANDLE hFile,void *buf, DWORD len, DWORD *lenOut, void *ovl) -{ - SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; - if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || !buf || !len) return FALSE; - int lo=fwrite(buf,1,len,file->fp); - if (lenOut) *lenOut = lo; - return !!lo; -} - -BOOL ReadFile(HANDLE hFile,void *buf, DWORD len, DWORD *lenOut, void *ovl) -{ - SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; - if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || !buf || !len) return FALSE; - int lo=fread(buf,1,len,file->fp); - if (lenOut) *lenOut = lo; - return !!lo; -} - -BOOL WinOffsetRect(LPRECT lprc, int dx, int dy) -{ - if(!lprc) return 0; - lprc->left+=dx; - lprc->top+=dy; - lprc->right+=dx; - lprc->bottom+=dy; - return TRUE; -} - -BOOL WinSetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom) -{ - if(!lprc) return 0; - lprc->left = xLeft; - lprc->top = yTop; - lprc->right = xRight; - lprc->bottom = yBottom; - return TRUE; -} - - -int WinIntersectRect(RECT *out, RECT *in1, RECT *in2) -{ - memset(out,0,sizeof(RECT)); - if (in1->right <= in1->left) return false; - if (in2->right <= in2->left) return false; - if (in1->bottom <= in1->top) return false; - if (in2->bottom <= in2->top) return false; - - // left is maximum of minimum of right edges and max of left edges - out->left = max(in1->left,in2->left); - out->right = min(in1->right,in2->right); - out->top=max(in1->top,in2->top); - out->bottom = min(in1->bottom,in2->bottom); - - return out->right>out->left && out->bottom>out->top; -} -void WinUnionRect(RECT *out, RECT *in1, RECT *in2) -{ - out->left = min(in1->left,in2->left); - out->top = min(in1->top,in2->top); - out->right=max(in1->right,in2->right); - out->bottom=max(in1->bottom,in2->bottom); -} - - -typedef struct -{ - int sz; - int refcnt; -} GLOBAL_REC; - - -void *GlobalLock(HANDLE h) -{ - if (!h) return 0; - GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; - rec->refcnt++; - return h; -} -int GlobalSize(HANDLE h) -{ - if (!h) return 0; - GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; - return rec->sz; -} - -void GlobalUnlock(HANDLE h) -{ - if (!h) return; - GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; - rec->refcnt--; -} -void GlobalFree(HANDLE h) -{ - if (!h) return; - GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; - if (rec->refcnt) - { - // note error freeing locked ram - } - free(rec); - -} -HANDLE GlobalAlloc(int flags, int sz) -{ - if (sz<0)sz=0; - GLOBAL_REC *rec=(GLOBAL_REC*)malloc(sizeof(GLOBAL_REC)+sz); - if (!rec) return 0; - rec->sz=sz; - rec->refcnt=0; - if (flags&GMEM_FIXED) memset(rec+1,0,sz); - return rec+1; -} - -char *lstrcpyn(char *dest, const char *src, int l) -{ - if (l<1) return dest; - - char *dsrc=dest; - while (--l > 0) - { - char p=*src++; - if (!p) break; - *dest++=p; - } - *dest++=0; - - return dsrc; -} - -static WDL_Mutex s_libraryMutex; -static int libkeycomp(void **p1, void **p2) -{ - INT_PTR a=(INT_PTR)(*p1) - (INT_PTR)(*p2); - if (a<0)return -1; - if (a>0) return 1; - return 0; -} -static WDL_AssocArray s_loadedLibs(libkeycomp); // index by OS-provided handle (rather than filename since filenames could be relative etc) - -HINSTANCE LoadLibrary(const char *fn) -{ - return LoadLibraryGlobals(fn,false); -} -HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) -{ - if (!fn || !*fn) return NULL; - - void *inst = NULL, *bundleinst=NULL; - -#ifdef __APPLE__ - struct stat ss; - if (stat(fn,&ss) || (ss.st_mode&S_IFDIR)) - { - CFStringRef str=(CFStringRef)SWELL_CStringToCFString(fn); - CFURLRef r=CFURLCreateWithFileSystemPath(NULL,str,kCFURLPOSIXPathStyle,true); - CFRelease(str); - - bundleinst=(void *)CFBundleCreate(NULL,r); - CFRelease(r); - - if (bundleinst) - { - CFURLRef executableURL = CFBundleCopyExecutableURL((CFBundleRef)bundleinst); - char path[PATH_MAX]; - path[0]=0; - if (executableURL) - { - if (!CFURLGetFileSystemRepresentation(executableURL, true, (UInt8*)path, sizeof(path))) path[0]=0; - CFRelease(executableURL); - } - - if (path[0]) - { - - inst=dlopen(path,RTLD_NOW|(symbolsAsGlobals?RTLD_GLOBAL:RTLD_LOCAL)); - if (!inst) - { - CFRelease(bundleinst); - return 0; - } - } - } - } -#endif - - if (!inst && !bundleinst) - { - inst=dlopen(fn,RTLD_NOW|(symbolsAsGlobals?RTLD_GLOBAL:RTLD_LOCAL)); - if (!inst) return 0; - } - - WDL_MutexLock lock(&s_libraryMutex); - - SWELL_HINSTANCE *rec = s_loadedLibs.Get(bundleinst ? bundleinst : inst); - if (!rec) - { - rec = (SWELL_HINSTANCE *)calloc(sizeof(SWELL_HINSTANCE),1); - rec->instptr = inst; - rec->bundleinstptr = bundleinst; - rec->refcnt = 1; - s_loadedLibs.Insert(bundleinst ? bundleinst : inst,rec); - - int (*SWELL_dllMain)(HINSTANCE, DWORD, LPVOID) = 0; - BOOL (*dllMain)(HINSTANCE, DWORD, LPVOID) = 0; - *(void **)&SWELL_dllMain = GetProcAddress(rec,"SWELL_dllMain"); - if (SWELL_dllMain) - { - void *SWELLAPI_GetFunc(const char *name); - - if (!SWELL_dllMain(rec,DLL_PROCESS_ATTACH,(void*)NULL)) // todo: eventually pass SWELLAPI_GetFunc, maybe? - { - FreeLibrary(rec); - return 0; - } - *(void **)&dllMain = GetProcAddress(rec,"DllMain"); - if (dllMain) - { - if (!dllMain(rec,DLL_PROCESS_ATTACH,NULL)) - { - SWELL_dllMain(rec,DLL_PROCESS_DETACH,(void*)NULL); - FreeLibrary(rec); - return 0; - } - } - } - rec->SWELL_dllMain = SWELL_dllMain; - rec->dllMain = dllMain; - } - else rec->refcnt++; - - return rec; -} - -void *GetProcAddress(HINSTANCE hInst, const char *procName) -{ - if (!hInst) return 0; - - SWELL_HINSTANCE *rec=(SWELL_HINSTANCE*)hInst; - - void *ret = NULL; -#ifdef __APPLE__ - if (rec->bundleinstptr) - { - CFStringRef str=(CFStringRef)SWELL_CStringToCFString(procName); - ret = (void *)CFBundleGetFunctionPointerForName((CFBundleRef)rec->bundleinstptr, str); - if (ret) rec->lastSymbolRequested=ret; - CFRelease(str); - return ret; - } -#endif - if (rec->instptr) ret=(void *)dlsym(rec->instptr, procName); - if (ret) rec->lastSymbolRequested=ret; - return ret; -} - -BOOL FreeLibrary(HINSTANCE hInst) -{ - if (!hInst) return FALSE; - - WDL_MutexLock lock(&s_libraryMutex); - - bool dofree=false; - SWELL_HINSTANCE *rec=(SWELL_HINSTANCE*)hInst; - if (--rec->refcnt<=0) - { - dofree=true; - s_loadedLibs.Delete(rec->bundleinstptr ? rec->bundleinstptr : rec->instptr); - - if (rec->SWELL_dllMain) - { - rec->SWELL_dllMain(rec,DLL_PROCESS_DETACH,NULL); - if (rec->dllMain) rec->dllMain(rec,DLL_PROCESS_DETACH,NULL); - } - - } - -#ifdef __APPLE__ - if (rec->bundleinstptr) CFRelease((CFBundleRef)rec->bundleinstptr); -#endif - if (rec->instptr) dlclose(rec->instptr); - - if (dofree) free(rec); - return TRUE; -} - -DWORD GetModuleFileName(HINSTANCE hInst, char *fn, DWORD nSize) -{ - *fn=0; - - void *instptr = NULL, *bundleinstptr=NULL, *lastSymbolRequested=NULL; - if (hInst) - { - SWELL_HINSTANCE *p = (SWELL_HINSTANCE*)hInst; - instptr = p->instptr; - bundleinstptr = p->bundleinstptr; - lastSymbolRequested=p->lastSymbolRequested; - } -#ifdef __APPLE__ - if (!instptr || bundleinstptr) - { - CFBundleRef bund=bundleinstptr ? (CFBundleRef)bundleinstptr : CFBundleGetMainBundle(); - if (bund) - { - CFURLRef url=CFBundleCopyBundleURL(bund); - if (url) - { - char buf[8192]; - if (CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf))) lstrcpyn(fn,buf,nSize); - CFRelease(url); - } - } - return strlen(fn); - } -#else - if (!instptr) // get exe file name - { - char tmp[64]; - sprintf(tmp,"/proc/%d/exe",getpid()); - int sz=readlink(tmp,fn,nSize); - if (sz<0)sz=0; - else if (sz>=nSize)sz=nSize-1; - fn[sz]=0; - return sz; - } -#endif - - if (instptr && lastSymbolRequested) - { - Dl_info inf={0,}; - dladdr(lastSymbolRequested,&inf); - if (inf.dli_fname) - { - lstrcpyn(fn,inf.dli_fname,nSize); - return strlen(fn); - } - } - return 0; -} - -#ifdef __APPLE__ - -void SWELL_GenerateGUID(void *g) -{ - CFUUIDRef r = CFUUIDCreate(NULL); - if (r) - { - CFUUIDBytes a = CFUUIDGetUUIDBytes(r); - if (g) memcpy(g,&a,16); - CFRelease(r); - } -} - -#endif - - -#endif diff --git a/WDL/swell/swell.h b/WDL/swell/swell.h deleted file mode 100644 index 08c7a47c..00000000 --- a/WDL/swell/swell.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) - Copyright (C) 2006-2010, Cockos, Inc. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. - - */ - - -#ifndef _WIN32 - - -#ifndef _WDL_SWELL_H_ // here purely for apps/other libraries (dirscan.h uses it), each section actually has its own define -#define _WDL_SWELL_H_ - - -#ifdef __APPLE__ -#define SWELL_TARGET_OSX -#define SWELL_TARGET_OSX_COCOA -#endif - -// for swell*generic -// #define SWELL_TARGET_GDK -// #define SWELL_LICE_GDI - -#endif - -#ifdef __APPLE__ -// go ahead and get this included before we define FSHIFT in swell-types.h -#include -#endif - -// IF YOU ADD TO SWELL: -// Adding types, defines, etc: add to swell-types.h -// Adding functions: put them in swell-functions.h - - -#include "swell-types.h" -#include "swell-functions.h" - - -#ifndef SWELL_PROVIDED_BY_APP -#ifndef _WDL_SWELL_H_UTIL_DEFINED_ -#define _WDL_SWELL_H_UTIL_DEFINED_ - -// these should never be called directly!!! put SWELL_POSTMESSAGE_DELEGATE_IMPL in your nsapp delegate, and call SWELL_POSTMESSAGE_INIT at some point from there too - -#define SWELL_POSTMESSAGE_INIT SWELL_Internal_PostMessage_Init(); -#define SWELL_POSTMESSAGE_DELEGATE_IMPL \ - -(bool)swellPostMessage:(HWND)dest msg:(int)message wp:(WPARAM)wParam lp:(LPARAM)lParam { \ - return SWELL_Internal_PostMessage(dest,message,wParam,lParam); \ - } \ - -(void)swellPostMessageClearQ:(HWND)dest { \ - SWELL_Internal_PMQ_ClearAllMessages(dest); \ - } \ - -(void)swellPostMessageTick:(id)sender { \ - SWELL_MessageQueue_Flush(); \ - } - -BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd); - - -// if you use this then include swell-appstub.mm in your project -#define SWELL_APPAPI_DELEGATE_IMPL \ - -(void *)swellGetAPPAPIFunc { \ - void *SWELLAPI_GetFunc(const char *name); \ - return (void*)SWELLAPI_GetFunc; \ - } - -#endif // _WDL_SWELL_H_UTIL_DEFINED_ -#endif // !SWELL_PROVIDED_BY_APP - -#endif // !_WIN32 - - -#ifndef SWELL_TARGET_OSX - -#ifndef SWELL_CB_InsertString - -#define SWELL_CB_InsertString(hwnd, idx, pos, str) SendDlgItemMessage(hwnd,idx,CB_INSERTSTRING,(pos),(LPARAM)(str)) -#define SWELL_CB_AddString(hwnd, idx, str) SendDlgItemMessage(hwnd,idx,CB_ADDSTRING,0,(LPARAM)(str)) -#define SWELL_CB_SetCurSel(hwnd,idx,val) SendDlgItemMessage(hwnd,idx,CB_SETCURSEL,(WPARAM)(val),0) -#define SWELL_CB_GetNumItems(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_GETCOUNT,0,0) -#define SWELL_CB_GetCurSel(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_GETCURSEL,0,0) -#define SWELL_CB_SetItemData(hwnd,idx,item,val) SendDlgItemMessage(hwnd,idx,CB_SETITEMDATA,(item),(val)) -#define SWELL_CB_GetItemData(hwnd,idx,item) SendDlgItemMessage(hwnd,idx,CB_GETITEMDATA,(item),0) -#define SWELL_CB_GetItemText(hwnd,idx,item,buf,bufsz) SendDlgItemMessage(hwnd,idx,CB_GETLBTEXT,(item),(LPARAM)(buf)) -#define SWELL_CB_Empty(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_RESETCONTENT,0,0) -#define SWELL_CB_DeleteString(hwnd,idx,str) SendDlgItemMessage(hwnd,idx,CB_DELETESTRING,str,0) - -#define SWELL_TB_SetPos(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx, TBM_SETPOS,TRUE,(pos)) -#define SWELL_TB_SetRange(hwnd, idx, low, hi) SendDlgItemMessage(hwnd,idx,TBM_SETRANGE,TRUE,(LPARAM)MAKELONG((low),(hi))) -#define SWELL_TB_GetPos(hwnd, idx) SendDlgItemMessage(hwnd,idx,TBM_GETPOS,0,0) -#define SWELL_TB_SetTic(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx,TBM_SETTIC,0,(pos)) - -#endif - -#endif// !SWELL_TARGET_OSX - - - - -#ifndef WDL_GDP_CTX // stupid GDP compatibility layer, deprecated - - -#define WDL_GDP_CTX HDC -#define WDL_GDP_PEN HPEN -#define WDL_GDP_BRUSH HBRUSH -#define WDL_GDP_CreatePen(col, wid) (WDL_GDP_PEN)CreatePen(PS_SOLID,(wid),(col)) -#define WDL_GDP_DeletePen(pen) DeleteObject((HGDIOBJ)(pen)) -#define WDL_GDP_SetPen(ctx, pen) ((WDL_GDP_PEN)SelectObject(ctx,(HGDIOBJ)(pen))) -#define WDL_GDP_SetBrush(ctx, brush) ((WDL_GDP_BRUSH)SelectObject(ctx,(HGDIOBJ)(brush))) -#define WDL_GDP_CreateBrush(col) (WDL_GDP_BRUSH)CreateSolidBrush(col) -#define WDL_GDP_DeleteBrush(brush) DeleteObject((HGDIOBJ)(brush)) -#define WDL_GDP_FillRectWithBrush(hdc,r,br) FillRect(hdc,r,(HBRUSH)(br)) -#define WDL_GDP_Rectangle(hdc,l,t,r,b) Rectangle(hdc,l,t,r,b) -#define WDL_GDP_Polygon(hdc,pts,n) Polygon(hdc,pts,n) -#define WDL_GDP_MoveToEx(hdc,x,y,op) MoveToEx(hdc,x,y,op) -#define WDL_GDP_LineTo(hdc,x,y) LineTo(hdc,x,y) -#define WDL_GDP_PutPixel(hdc,x,y,c) SetPixel(hdc,x,y,c) -#define WDL_GDP_PolyBezierTo(hdc,p,np) PolyBezierTo(hdc,p,np) - -#define SWELL_SyncCtxFrameBuffer(x) // no longer used - -#endif - -#if defined(_WIN32) && !defined(LoadLibraryGlobals) -#define LoadLibraryGlobals(a,b) LoadLibrary(a) -#endif - diff --git a/WDL/swell/swellappmain.h b/WDL/swell/swellappmain.h deleted file mode 100644 index 5069860f..00000000 --- a/WDL/swell/swellappmain.h +++ /dev/null @@ -1,14 +0,0 @@ -#import - - -@interface SWELLApplication : NSApplication { - -} -- (void)sendEvent:(NSEvent *)anEvent; - -@end - -@interface SWELLAppController : NSObject { -} --(IBAction)onSysMenuCommand:(id)sender; -@end \ No newline at end of file diff --git a/WDL/swell/swellappmain.mm b/WDL/swell/swellappmain.mm deleted file mode 100644 index 3c434aa9..00000000 --- a/WDL/swell/swellappmain.mm +++ /dev/null @@ -1,232 +0,0 @@ -#import "swellappmain.h" - -#include "swell.h" -#include "swell-internal.h" - - -HMENU SWELL_app_stocksysmenu; // exposed to app, simply the contents of the default system menu (as defined in the nib) -static bool IsMultiLineEditControl(NSView *cv, id fs) -{ - if (fs && [fs isKindOfClass:[NSTextView class]]) - { - NSTextView *v = (NSTextView *)fs; - if ([v isEditable]) - { - NSView *a=[v superview]; - while (a && a != cv) - { - if ([a isKindOfClass:[NSTextField class]]) return false; - a = [a superview]; - } - return true; - } - } - return false; -} - -@implementation SWELLApplication -- (void)sendEvent:(NSEvent *)anEvent -{ - int etype = [anEvent type]; - if (etype == NSKeyUp) - { - // toss keyup if next keydown is the same key - NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE]; - if (nextDown && [nextDown keyCode] == [anEvent keyCode]) return; - } - else if (etype == NSKeyDown) - { - NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE]; - if (nextDown && [nextDown keyCode] == [anEvent keyCode]) - { -#if 0 - // no need to check timestamps -- if a queued key is there, just ignore this one(prevent a backlog) - static double sc=0.0; - if (sc == 0.0) - { - struct mach_timebase_info inf={0,}; - mach_timebase_info(&inf); - if (inf.numer && inf.denom) sc = inf.numer / (inf.denom * 1000.0 * 1000.0 * 1000.0); - } - - if (sc != 0.0 && [anEvent timestamp] < (double) mach_absolute_time() * sc - 0.05) -#endif - return; - } - } - - - NSWindow *modalWindow = [NSApp modalWindow]; - - NSWindow *focwnd=[anEvent window]; - NSView *dest_view=NULL; // only valid when key message - - if (etype==NSKeyDown||etype==NSKeyUp) - { - int msgtype = etype==NSKeyDown ? WM_KEYDOWN : WM_KEYUP; - int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag); - - if (focwnd) - { - if (flag&(FCONTROL|FALT)) - { - NSWindow *f = focwnd; - // handle carbon windows, sending all cmd/alt modified keys to their parent NSView (to be handled later) - // perhaps it'd be good to have a flag on these to see if they want it .. i.e. SWELL_SetCarbonHostView_WantKeyFlgs().. - while (f) - { - if ((dest_view=[f delegate]) && [dest_view respondsToSelector:@selector(swellIsCarbonHostingView)] && [(SWELL_hwndCarbonHost*)dest_view swellIsCarbonHostingView]) - { - focwnd = [dest_view window]; - break; - } - dest_view=0; - f=[f parentWindow]; - } - } - if (!dest_view) // get default dest_view, and validate it as a NSView - { - if ((dest_view=(NSView *)[focwnd firstResponder]) && ![dest_view isKindOfClass:[NSView class]]) dest_view=NULL; - } - } - if (!modalWindow && (!focwnd || dest_view)) - { - MSG msg={(HWND)dest_view,msgtype,(WPARAM)code,(LPARAM)flag}; // LPARAM is treated differently (giving modifier flags/FVIRTKEY etc) in sWELL's WM_KEYDOWN than in windows, deal with it - - if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE,(INT_PTR)&msg,(INT_PTR)anEvent)>0) return; - } - } - // default window handling: - if (etype == NSKeyDown && focwnd && dest_view) - { - NSView *cv = [focwnd contentView]; - if (cv && [cv respondsToSelector:@selector(onSwellMessage:p1:p2:)]) //only work for swell windows - { - int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag); - int cmdid=0; - - // todo: other keys (such as shift+insert?) - if (((flag&~FVIRTKEY)==FCONTROL && (code=='V'||code=='C' ||code=='X')) && [dest_view isKindOfClass:[NSText class]]) - { - if (code=='V') [(NSText *)dest_view paste:(id)cv]; - else if (code=='C') [(NSText *)dest_view copy:(id)cv]; - else if (code=='X') [(NSText *)dest_view cut:(id)cv]; - return; - } - - if ((!(flag&~(FVIRTKEY|FSHIFT)) && code == VK_ESCAPE) || - ((flag&~FVIRTKEY)==FCONTROL && code=='W')) - { - if (code == 'W') cmdid= IDCANCEL; // cmd+w always idcancel's - else if (!dest_view || ![dest_view isKindOfClass:[NSTextView class]]) cmdid=IDCANCEL; // not text view, idcancel - else if (!(flag&FSHIFT) && !IsMultiLineEditControl(cv,dest_view)) cmdid=IDCANCEL; // if singleline edit and shift not set, idcancel - - if (!cmdid) - { - SetFocus((HWND)cv); - return; - } - } - else if (!(flag&~FVIRTKEY) && code == VK_RETURN) - { - // get default button command id, if any, if enabled - if (!IsMultiLineEditControl(cv,dest_view)) - { - cmdid = SWELL_GetDefaultButtonID((HWND)cv,true); - - if (!cmdid) // no action, set focus to parent - { - SetFocus((HWND)cv); - return; - } - } - } - - if (cmdid) - { - SendMessage((HWND)cv,WM_COMMAND,cmdid,0); - return; - } - } // is swell CV - } // key down - - [super sendEvent:anEvent]; -} -@end - - -@implementation SWELLAppController - -- (void)awakeFromNib -{ - SWELL_EnsureMultithreadedCocoa(); - [NSApp setDelegate:self]; - - SWELL_POSTMESSAGE_INIT - - HMENU stockMenu=(HMENU)[NSApp mainMenu]; - if (stockMenu) - { - HMENU nf = GetSubMenu(stockMenu,0); - if (nf) SWELL_app_stocksysmenu = SWELL_DuplicateMenu(nf); - } - - SWELLAppMain(SWELLAPP_ONLOAD,0,0); -} - --(IBAction)onSysMenuCommand:(id)sender -{ - int a = [sender tag]; - if (a) SWELLAppMain(SWELLAPP_ONCOMMAND,a,(INT_PTR)sender); -} - -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - char buf[4096]; - buf[0]=0; - SWELL_CFStringToCString(filename,buf,sizeof(buf)); - return buf[0] && SWELLAppMain(SWELLAPP_OPENFILE,(INT_PTR)buf,0)>0; -} -- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication -{ - return SWELLAppMain(SWELLAPP_NEWFILE,0,0)>0; -} - -- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender -{ - return SWELLAppMain(SWELLAPP_SHOULDOPENNEWFILE,0,0)>0; -} - --(void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - SWELLAppMain(SWELLAPP_LOADED,0,0); -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - return SWELLAppMain(SWELLAPP_SHOULDDESTROY,0,0) > 0 ? NSTerminateLater : NSTerminateNow; -} - -- (void)applicationWillTerminate:(NSNotification *)notification -{ - SWELLAppMain(SWELLAPP_DESTROY,0,0); -} - -- (void)applicationDidBecomeActive:(NSNotification *)aNotification -{ - if (!SWELLAppMain(SWELLAPP_ACTIVATE,TRUE,0)) - SWELL_BroadcastMessage(WM_ACTIVATEAPP,TRUE,0); -} - -- (void)applicationDidResignActive:(NSNotification *)aNotification -{ - if (!SWELLAppMain(SWELLAPP_ACTIVATE,FALSE,0)) - SWELL_BroadcastMessage(WM_ACTIVATEAPP,FALSE,0); -} - -SWELL_APPAPI_DELEGATE_IMPL - -SWELL_POSTMESSAGE_DELEGATE_IMPL - - -@end diff --git a/WDL/swell/test-gtk.cpp b/WDL/swell/test-gtk.cpp deleted file mode 100644 index 6f897d39..00000000 --- a/WDL/swell/test-gtk.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -int main( int argc, - char *argv[] ) -{ - GtkWidget *window; - - gtk_init (&argc, &argv); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_show (window); - - gtk_main (); - - return 0; -} diff --git a/WDL/swell/test.cpp b/WDL/swell/test.cpp deleted file mode 100644 index ece030fa..00000000 --- a/WDL/swell/test.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "swell.h" - -int main() -{ - MessageBox(NULL,"hello world","a",0); - return 0; -} diff --git a/WDL/swell/windows.h b/WDL/swell/windows.h deleted file mode 100644 index 2927ef7f..00000000 --- a/WDL/swell/windows.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef _SWELL_WINDOWS_H_ -#define _SWELL_WINDOWS_H_ - -#ifdef _WIN32 -#include -#else -#include "swell.h" - - -#define BIF_RETURNONLYFSDIRS 0x0001 -#define BIF_DONTGOBELOWDOMAIN 0x0002 -#define BIF_STATUSTEXT 0x0004 -#define BIF_RETURNFSANCESTORS 0x0008 -#define BIF_EDITBOX 0x0010 -#define BIF_VALIDATE 0x0020 - -#define BIF_BROWSEFORCOMPUTER 0x1000 -#define BIF_BROWSEFORPRINTER 0x2000 -#define BIF_BROWSEINCLUDEFILES 0x4000 - -#define BFFM_INITIALIZED 1 -#define BFFM_SELCHANGED 2 -typedef int (CALLBACK* BFFCALLBACK)(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData); - -typedef struct __ITEMIDLIST ITEMIDLIST; -typedef const ITEMIDLIST *LPCITEMIDLIST; - -typedef struct _browseinfoA { - HWND hwndOwner; - LPCITEMIDLIST pidlRoot; - LPSTR pszDisplayName; - LPCSTR lpszTitle; - UINT ulFlags; - BFFCALLBACK lpfn; - LPARAM lParam; - int iImage; -} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; - -#ifdef __cplusplus -class IMalloc -{ - public: - void Release() { delete this; } - void Free(void *p) { free(p); } -}; -#define SHGetMalloc(x) { *(x) = new IMalloc; } -#define SHGetPathFromIDList(src,dest) { if (src) {lstrcpyn(dest,(char *)src,MAX_PATH); } else *dest=0; } -#endif - -SWELL_API_DEFINE(ITEMIDLIST *, SHBrowseForFolder, (LPBROWSEINFO)) - -#define BFFM_SETSELECTION (WM_USER + 102) - -#define Shell_NotifyIcon(a,b) (0) -#define PostQuitMessage(x) { /* todo: mac quit message*/ } -#define SetClassLong(a,b,c) (0) -#define LoadIcon(a,b) ((HICON)0) -#define IsIconic(x) (0) -#define IsWindowEnabled(x) (1) -#define TrackPopupMenuEx(a,b,c,d,e,f) TrackPopupMenu(a,b,c,d,0,e,NULL) -#endif - -typedef UINT (CALLBACK *LPOFNHOOKPROC) (HWND, UINT, WPARAM, LPARAM); - -typedef struct tagOFNA { - DWORD lStructSize; - HWND hwndOwner; - HINSTANCE hInstance; - LPCSTR lpstrFilter; - LPSTR lpstrCustomFilter; - DWORD nMaxCustFilter; - DWORD nFilterIndex; - LPSTR lpstrFile; - DWORD nMaxFile; - LPSTR lpstrFileTitle; - DWORD nMaxFileTitle; - LPCSTR lpstrInitialDir; - LPCSTR lpstrTitle; - DWORD Flags; - WORD nFileOffset; - WORD nFileExtension; - LPCSTR lpstrDefExt; - LPARAM lCustData; - LPOFNHOOKPROC lpfnHook; - LPCSTR lpTemplateName; -} OPENFILENAME, *LPOPENFILENAME; - - -SWELL_API_DEFINE(BOOL,GetOpenFileName,(LPOPENFILENAME)); -SWELL_API_DEFINE(BOOL,GetSaveFileName,(LPOPENFILENAME)); - -#define OFN_READONLY 0x00000001 -#define OFN_OVERWRITEPROMPT 0x00000002 -#define OFN_HIDEREADONLY 0x00000004 -#define OFN_NOCHANGEDIR 0x00000008 -#define OFN_SHOWHELP 0x00000010 -#define OFN_ENABLEHOOK 0x00000020 -#define OFN_ENABLETEMPLATE 0x00000040 -#define OFN_ENABLETEMPLATEHANDLE 0x00000080 -#define OFN_NOVALIDATE 0x00000100 -#define OFN_ALLOWMULTISELECT 0x00000200 -#define OFN_EXTENSIONDIFFERENT 0x00000400 -#define OFN_PATHMUSTEXIST 0x00000800 -#define OFN_FILEMUSTEXIST 0x00001000 -#define OFN_CREATEPROMPT 0x00002000 -#define OFN_SHAREAWARE 0x00004000 -#define OFN_NOREADONLYRETURN 0x00008000 -#define OFN_NOTESTFILECREATE 0x00010000 -#define OFN_NONETWORKBUTTON 0x00020000 -#define OFN_NOLONGNAMES 0x00040000 -#define OFN_EXPLORER 0x00080000 -#define OFN_NODEREFERENCELINKS 0x00100000 -#define OFN_LONGNAMES 0x00200000 -#define OFN_ENABLEINCLUDENOTIFY 0x00400000 -#define OFN_ENABLESIZING 0x00800000 - - -#define MB_ICONHAND 0x00000010L -#define MB_ICONQUESTION 0x00000020L -#define MB_ICONEXCLAMATION 0x00000030L -#define MB_ICONASTERISK 0x00000040L - -typedef struct _SHELLEXECUTEINFOA -{ - DWORD cbSize; - ULONG fMask; - HWND hwnd; - LPCSTR lpVerb; - LPCSTR lpFile; - LPCSTR lpParameters; - LPCSTR lpDirectory; - int nShow; - HINSTANCE hInstApp; -} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO; - - -SWELL_API_DEFINE(BOOL, ShellExecuteEx,(LPSHELLEXECUTEINFO lpExecInfo)); -SWELL_API_DEFINE(BOOL,WriteFile,(HANDLE,void *, DWORD, DWORD *lenOut, void *ovl)) -SWELL_API_DEFINE(BOOL,ReadFile,(HANDLE,void *, DWORD, DWORD *lenOut, void *ovl)) -SWELL_API_DEFINE(HANDLE,CreateFile,( const char * lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,void *lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)) -SWELL_API_DEFINE(DWORD,SetFilePointer,(HANDLE, DWORD low, DWORD *high)) -SWELL_API_DEFINE(DWORD,GetFilePointer,(HANDLE, DWORD *high)) -SWELL_API_DEFINE(DWORD,GetFileSize,(HANDLE, DWORD *high)) - -#define InitCommonControls() { } -#define CoInitialize(x) { } - -/* -#define IsDialogMessage(wnd,a) (0) -#define TranslateMessage(a) { } -#define DispatchMessage(a) { } -*/ - -#define INVALID_HANDLE_VALUE ((HANDLE)((unsigned int)-1)) - -#define RemoveDirectory(x) (!rmdir(x)) - -#define CharNext(x) ((x)+1) -#define CharPrev(base,x) ( (x)>(base)?(x)-1:(base)) -#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n') - -#define lstrcpyA strcpy -#define lstrcpynA lstrcpyn - -#endif diff --git a/WDL/timing.c b/WDL/timing.c deleted file mode 100644 index 2871feb5..00000000 --- a/WDL/timing.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "timing.h" - -#ifdef TIMING - -#include -#ifdef _WIN32 -#include -#endif - -static struct { - __int64 st_time; - __int64 cycles,mint,maxt; - int foo; - int calls; -} timingInfo[64]; - - -static void rdtsc(__int64 *t) -{ -#ifdef _WIN64 - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - *t = now.QuadPart; -#else - __asm - { - mov esi, t - _emit 0xf - _emit 0x31 - mov [esi], eax - mov [esi+4], edx - } -#endif -} - -void _timingInit(void) -{ - memset(timingInfo,0,sizeof(timingInfo)); -} - -void _timingEnter(int which) -{ - rdtsc(&timingInfo[which].st_time); -} - -void _timingLeave(int which) -{ - __int64 t; - rdtsc(&t); - t -= timingInfo[which].st_time; - if (!timingInfo[which].mint || t < timingInfo[which].mint) timingInfo[which].mint=t?t:1; - if (t > timingInfo[which].maxt) timingInfo[which].maxt=t; - timingInfo[which].cycles += t; - timingInfo[which].calls += 1; -} - -void _timingPrint(void) -{ - int x,p=0; - for (x = 0; x < sizeof(timingInfo)/sizeof(timingInfo[0]); x ++) - { - char buf[512]; - if (timingInfo[x].calls) - { - p++; - sprintf(buf,"%d: %d calls, %.4f clocks/call (min=%.4f, max=%.4f). %.8f thingies of CPU time spent\n", - x,timingInfo[x].calls,(timingInfo[x].cycles/(double)timingInfo[x].calls), - (double)timingInfo[x].mint,(double)timingInfo[x].maxt, - (double)timingInfo[x].cycles -#ifdef _WIN64 - / 1000000.0 -#else - / (2.4*1000.0*1000.0*1000.0) -#endif - - ); - OutputDebugString(buf); - } - } - if (!p) OutputDebugString("no calls to timing lib\n"); - - timingInit(); -} - -#endif diff --git a/WDL/timing.h b/WDL/timing.h deleted file mode 100644 index 00781ee3..00000000 --- a/WDL/timing.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - WDL - timing.h - - this is based on some public domain Pentium RDTSC timing code from usenet in 1996. - - To enable this, your app must #define TIMING, include timing.h, call timingInit(), then timingEnter(x)/timingLeave(x) a bunch - of times (where x is 0-64), then timingPrint at the end. - - on timingPrint(), C:\\timings.txt will be overwritten. - -*/ - -#ifndef _TIMING_H_ -#define _TIMING_H_ - - -//#define TIMING - - - -#if defined(TIMING) && !defined(__alpha) -#ifdef __cplusplus -extern "C" { -#endif -void _timingInit(void); -void _timingPrint(void); -void _timingEnter(int); -void _timingLeave(int); -#ifdef __cplusplus -} -#endif -#define timingPrint() _timingPrint() -#define timingInit() _timingInit() -#define timingLeave(x) _timingLeave(x) -#define timingEnter(x) _timingEnter(x) -#else -#define timingPrint() -#define timingInit() -#define timingLeave(x) -#define timingEnter(x) -#endif - -#endif \ No newline at end of file diff --git a/WDL/tinyxml/libxml_tinyxml.cpp b/WDL/tinyxml/libxml_tinyxml.cpp deleted file mode 100644 index 595cdce7..00000000 --- a/WDL/tinyxml/libxml_tinyxml.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "libxml_tinyxml.h" -#include "tinyxml.h" - -xmlAttr* MakeAttrList(const TiXmlAttribute* attr) -{ - xmlAttr* xattr = 0; - if (attr) - { - xattr = new xmlAttr; - memset(xattr, 0, sizeof(xmlAttr)); - - xattr->name = attr->Name(); - xattr->content = attr->Value(); - - // svgtiny expect xattr->children to be a pointer back to the attribute, - // though in libxml it is supposed to always be NULL - xattr->children = xattr; - - xattr->next = MakeAttrList(attr->Next()); - } - return xattr; -} - -xmlNode* MakeNodeTree(TiXmlNode* node) -{ - xmlNode* xnode = 0; - if (node) - { - xnode = new xmlNode; - memset(xnode, 0, sizeof(xmlNode)); - - int type = node->Type(); - if (type == TiXmlNode::ELEMENT) - { - xnode->type = XML_ELEMENT_NODE; - xnode->name = node->Value(); - const TiXmlElement* elem = node->ToElement(); - if (elem) xnode->properties = MakeAttrList(elem->FirstAttribute()); - } - else if (type == TiXmlNode::TEXT) - { - xnode->type = XML_TEXT_NODE; - xnode->content = node->Value(); - } - else xnode->type = 0; - - xnode->children = MakeNodeTree(node->FirstChild()); - xnode->next = MakeNodeTree(node->NextSibling()); - } - return xnode; -} - - -xmlDoc* xmlReadMemory(const char* buffer, size_t size, const char* url, const char* encoding, int flags) -{ - if (buffer[size] != 0 || strlen(buffer) != size) return 0; - - if (!url) url = ""; - TiXmlDocument* doc = new TiXmlDocument(url); - doc->Parse(buffer); - if (doc->Error()) - { - delete(doc); - doc = 0; - } - - xmlDoc* xdoc = 0; - if (doc) - { - xdoc = new xmlDoc; - memset(xdoc, 0, sizeof(xmlDoc)); - xdoc->tinyxml_obj = doc; - xdoc->children = MakeNodeTree((TiXmlNode*) doc->RootElement()); - } - return xdoc; -} - -xmlNode* xmlDocGetRootElement(xmlDoc* xdoc) -{ - xmlNode* xnode = 0; - if (xdoc) xnode = xdoc->children; - return xnode; -} - -xmlAttr* xmlHasProp(xmlNode* xnode, const xmlChar* name) -{ - xmlAttr* xattr = 0; - if (xnode && name && name[0]) - { - xattr = xnode->properties; -#ifdef _WIN32 - while (xattr && (!xattr->name || stricmp(xattr->name, name))) xattr = xattr->next; -#else - while (xattr && (!xattr->name || strcasecmp(xattr->name, name))) xattr = xattr->next; -#endif - } - return xattr; -} - -xmlChar* xmlGetProp(xmlNode* xnode, const xmlChar* name) -{ - xmlChar* xcontent = 0; - xmlAttr* xattr = xmlHasProp(xnode, name); - if (xattr) xcontent = strdup(xattr->content); - return xcontent; -} - -void xmlFree(xmlChar* str) -{ - free(str); -} - -void xmlFreeDoc(xmlDoc* xdoc) -{ - if (xdoc) - { - delete((TiXmlDocument*)xdoc->tinyxml_obj); - xdoc->tinyxml_obj = 0; - // todo make sure tinyxmldoc owns all its nodes - xdoc->children = 0; - } -} - - -char* strndup(const char* s, size_t size) -{ - // no doubt the real strndup protects against s not being null-terminated - if (size < strlen(s)) size = strlen(s); - char* t = (char*) malloc(size+1); - strncpy(t, s, size); // strncpy should be ok since we checked size - return t; -} \ No newline at end of file diff --git a/WDL/tinyxml/libxml_tinyxml.h b/WDL/tinyxml/libxml_tinyxml.h deleted file mode 100644 index 9186c16e..00000000 --- a/WDL/tinyxml/libxml_tinyxml.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef LIBXML_TINYXML -#define LIBXML_TINYXML - -// libxml interface, tinyxml implementation - -#include - -enum { XML_PARSE_NONET=1, XML_PARSE_COMPACT=2 }; -enum { XML_ELEMENT_NODE=1, XML_TEXT_NODE=2 }; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _xmlNode -{ - void* tinyxml_obj; - unsigned short line; - int type; - const char* name; - const char* content; - struct _xmlNode* properties; - struct _xmlNode* children; - struct _xmlNode* next; -} xmlNode; - -typedef xmlNode xmlDoc; -typedef xmlNode xmlAttr; - -typedef char xmlChar; - - -xmlDoc* xmlReadMemory(const char* buffer, size_t size, const char* url, const char* encoding, int flags); - -xmlNode* xmlDocGetRootElement(xmlDoc* document); - -xmlAttr* xmlHasProp(xmlNode* node, const xmlChar* name); - -xmlChar* xmlGetProp(xmlNode* node, const xmlChar * name); // return is on the heap - -void xmlFree(xmlChar* str); - -void xmlFreeDoc(xmlDoc* document); - - -char* strndup(const char* s, size_t size); // argh - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/WDL/tinyxml/svgtiny_colors.c b/WDL/tinyxml/svgtiny_colors.c deleted file mode 100644 index dc2a460b..00000000 --- a/WDL/tinyxml/svgtiny_colors.c +++ /dev/null @@ -1,955 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.1 */ -/* Command-line: gperf colors.gperf */ -/* Computed positions: -k'1,3,6-8,12-13' */ - -#if 0 -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif -#endif - -//#line 15 "colors.gperf" - -#include -#include - -//#include "svgtiny.h" -//#include "svgtiny_internal.h" - -typedef int svgtiny_colour; // == LICE_pixel -#define svgtiny_RGB(r,g,b) (((b)&0xFF)|(((g)&0xFF)<<8)|(((r)&0xFF)<<16)|(0xFF<<24)) - -struct svgtiny_named_color -{ - const char *name; - svgtiny_colour color; -}; - -//#line 21 "colors.gperf" - -//struct svgtiny_named_color; - -#define TOTAL_KEYWORDS 147 -#define MIN_WORD_LENGTH 3 -#define MAX_WORD_LENGTH 20 -#define MIN_HASH_VALUE 4 -#define MAX_HASH_VALUE 565 -/* maximum key range = 562, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -svgtiny_color_hash (register const char *str, register unsigned int len) -{ - static const unsigned short asso_values[] = - { - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 5, 55, 0, - 35, 0, 75, 10, 5, 0, 566, 250, 10, 40, - 85, 60, 70, 144, 0, 20, 45, 10, 30, 185, - 95, 195, 566, 0, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566 - }; - register int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[12]]; - /*FALLTHROUGH*/ - case 12: - hval += asso_values[(unsigned char)str[11]]; - /*FALLTHROUGH*/ - case 11: - case 10: - case 9: - case 8: - hval += asso_values[(unsigned char)str[7]]; - /*FALLTHROUGH*/ - case 7: - hval += asso_values[(unsigned char)str[6]]; - /*FALLTHROUGH*/ - case 6: - hval += asso_values[(unsigned char)str[5]]; - /*FALLTHROUGH*/ - case 5: - case 4: - case 3: - hval += asso_values[(unsigned char)str[2]+2]; - /*FALLTHROUGH*/ - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval; -} - -#ifdef __GNUC__ -__inline -#endif -const struct svgtiny_named_color * -svgtiny_color_lookup (register const char *str, register unsigned int len) -{ - static const struct svgtiny_named_color wordlist[] = - { -//#line 43 "colors.gperf" - {"cyan", svgtiny_RGB( 0, 255, 255)}, -//#line 76 "colors.gperf" - {"gray", svgtiny_RGB(128, 128, 128)}, -//#line 37 "colors.gperf" - {"chartreuse", svgtiny_RGB(127, 255, 0)}, -//#line 77 "colors.gperf" - {"grey", svgtiny_RGB(128, 128, 128)}, -//#line 78 "colors.gperf" - {"green", svgtiny_RGB( 0, 128, 0)}, -//#line 96 "colors.gperf" - {"lightgrey", svgtiny_RGB(211, 211, 211)}, -//#line 95 "colors.gperf" - {"lightgreen", svgtiny_RGB(144, 238, 144)}, -//#line 94 "colors.gperf" - {"lightgray", svgtiny_RGB(211, 211, 211)}, -//#line 152 "colors.gperf" - {"skyblue", svgtiny_RGB(135, 206, 235)}, -//#line 155 "colors.gperf" - {"slategrey", svgtiny_RGB(112, 128, 144)}, -//#line 150 "colors.gperf" - {"sienna", svgtiny_RGB(160, 82, 45)}, -//#line 154 "colors.gperf" - {"slategray", svgtiny_RGB(112, 128, 144)}, -//#line 149 "colors.gperf" - {"seashell", svgtiny_RGB(255, 245, 238)}, -//#line 160 "colors.gperf" - {"teal", svgtiny_RGB( 0, 128, 128)}, -//#line 39 "colors.gperf" - {"coral", svgtiny_RGB(255, 127, 80)}, -//#line 98 "colors.gperf" - {"lightsalmon", svgtiny_RGB(255, 160, 122)}, -//#line 102 "colors.gperf" - {"lightslategrey", svgtiny_RGB(119, 136, 153)}, -//#line 30 "colors.gperf" - {"black", svgtiny_RGB( 0, 0, 0)}, -//#line 101 "colors.gperf" - {"lightslategray", svgtiny_RGB(119, 136, 153)}, -//#line 128 "colors.gperf" - {"orange", svgtiny_RGB(255, 165, 0)}, -//#line 129 "colors.gperf" - {"orangered", svgtiny_RGB(255, 69, 0)}, -//#line 29 "colors.gperf" - {"bisque", svgtiny_RGB(255, 228, 196)}, -//#line 105 "colors.gperf" - {"lime", svgtiny_RGB( 0, 255, 0)}, -//#line 142 "colors.gperf" - {"red", svgtiny_RGB(255, 0, 0)}, -//#line 106 "colors.gperf" - {"limegreen", svgtiny_RGB( 50, 205, 50)}, -//#line 91 "colors.gperf" - {"lightcoral", svgtiny_RGB(240, 128, 128)}, -//#line 144 "colors.gperf" - {"royalblue", svgtiny_RGB( 65, 105, 225)}, -//#line 107 "colors.gperf" - {"linen", svgtiny_RGB(250, 240, 230)}, -//#line 71 "colors.gperf" - {"fuchsia", svgtiny_RGB(255, 0, 255)}, -//#line 48 "colors.gperf" - {"darkgreen", svgtiny_RGB( 0, 100, 0)}, -//#line 90 "colors.gperf" - {"lightblue", svgtiny_RGB(173, 216, 230)}, -//#line 54 "colors.gperf" - {"darkorchid", svgtiny_RGB(153, 50, 204)}, -//#line 157 "colors.gperf" - {"springgreen", svgtiny_RGB( 0, 255, 127)}, -//#line 108 "colors.gperf" - {"magenta", svgtiny_RGB(255, 0, 255)}, -//#line 74 "colors.gperf" - {"gold", svgtiny_RGB(255, 215, 0)}, -//#line 130 "colors.gperf" - {"orchid", svgtiny_RGB(218, 112, 214)}, -//#line 153 "colors.gperf" - {"slateblue", svgtiny_RGB(106, 90, 205)}, -//#line 51 "colors.gperf" - {"darkmagenta", svgtiny_RGB(139, 0, 139)}, -//#line 44 "colors.gperf" - {"darkblue", svgtiny_RGB( 0, 0, 139)}, -//#line 103 "colors.gperf" - {"lightsteelblue", svgtiny_RGB(176, 196, 222)}, -//#line 151 "colors.gperf" - {"silver", svgtiny_RGB(192, 192, 192)}, -//#line 148 "colors.gperf" - {"seagreen", svgtiny_RGB( 46, 139, 87)}, -//#line 158 "colors.gperf" - {"steelblue", svgtiny_RGB( 70, 130, 180)}, -//#line 159 "colors.gperf" - {"tan", svgtiny_RGB(210, 180, 140)}, -//#line 137 "colors.gperf" - {"peru", svgtiny_RGB(205, 133, 63)}, -//#line 141 "colors.gperf" - {"purple", svgtiny_RGB(128, 0, 128)}, -//#line 55 "colors.gperf" - {"darkred", svgtiny_RGB(139, 0, 0)}, -//#line 120 "colors.gperf" - {"mintcream", svgtiny_RGB(245, 255, 250)}, -//#line 68 "colors.gperf" - {"firebrick", svgtiny_RGB(178, 34, 34)}, -//#line 99 "colors.gperf" - {"lightseagreen", svgtiny_RGB( 32, 178, 170)}, -//#line 52 "colors.gperf" - {"darkolivegreen", svgtiny_RGB( 85, 107, 47)}, -//#line 121 "colors.gperf" - {"mistyrose", svgtiny_RGB(255, 228, 225)}, -//#line 83 "colors.gperf" - {"indigo", svgtiny_RGB( 75, 0, 130)}, -//#line 125 "colors.gperf" - {"oldlace", svgtiny_RGB(253, 245, 230)}, -//#line 138 "colors.gperf" - {"pink", svgtiny_RGB(255, 192, 203)}, -//#line 56 "colors.gperf" - {"darksalmon", svgtiny_RGB(233, 150, 122)}, -//#line 86 "colors.gperf" - {"lavender", svgtiny_RGB(230, 230, 250)}, -//#line 84 "colors.gperf" - {"ivory", svgtiny_RGB(255, 255, 240)}, -//#line 122 "colors.gperf" - {"moccasin", svgtiny_RGB(255, 228, 181)}, -//#line 36 "colors.gperf" - {"cadetblue", svgtiny_RGB( 95, 158, 160)}, -//#line 62 "colors.gperf" - {"darkviolet", svgtiny_RGB(148, 0, 211)}, -//#line 145 "colors.gperf" - {"saddlebrown", svgtiny_RGB(139, 69, 19)}, -//#line 58 "colors.gperf" - {"darkslateblue", svgtiny_RGB( 72, 61, 139)}, -//#line 132 "colors.gperf" - {"palegreen", svgtiny_RGB(152, 251, 152)}, -//#line 156 "colors.gperf" - {"snow", svgtiny_RGB(255, 250, 250)}, -//#line 82 "colors.gperf" - {"indianred", svgtiny_RGB(205, 92, 92)}, -//#line 93 "colors.gperf" - {"lightgoldenrodyellow", svgtiny_RGB(250, 250, 210)}, -//#line 162 "colors.gperf" - {"tomato", svgtiny_RGB(255, 99, 71)}, -//#line 89 "colors.gperf" - {"lemonchiffon", svgtiny_RGB(255, 250, 205)}, -//#line 97 "colors.gperf" - {"lightpink", svgtiny_RGB(255, 182, 193)}, -//#line 109 "colors.gperf" - {"maroon", svgtiny_RGB(128, 0, 0)}, -//#line 87 "colors.gperf" - {"lavenderblush", svgtiny_RGB(255, 240, 245)}, -//#line 163 "colors.gperf" - {"turquoise", svgtiny_RGB( 64, 224, 208)}, -//#line 53 "colors.gperf" - {"darkorange", svgtiny_RGB(255, 140, 0)}, -//#line 124 "colors.gperf" - {"navy", svgtiny_RGB( 0, 0, 128)}, -//#line 67 "colors.gperf" - {"dodgerblue", svgtiny_RGB( 30, 144, 255)}, -//#line 70 "colors.gperf" - {"forestgreen", svgtiny_RGB( 34, 139, 34)}, -//#line 119 "colors.gperf" - {"midnightblue", svgtiny_RGB( 25, 25, 112)}, -//#line 114 "colors.gperf" - {"mediumseagreen", svgtiny_RGB( 60, 179, 113)}, -//#line 57 "colors.gperf" - {"darkseagreen", svgtiny_RGB(143, 188, 143)}, -//#line 25 "colors.gperf" - {"aqua", svgtiny_RGB( 0, 255, 255)}, -//#line 27 "colors.gperf" - {"azure", svgtiny_RGB(240, 255, 255)}, -//#line 146 "colors.gperf" - {"salmon", svgtiny_RGB(250, 128, 114)}, -//#line 165 "colors.gperf" - {"wheat", svgtiny_RGB(245, 222, 179)}, -//#line 34 "colors.gperf" - {"brown", svgtiny_RGB(165, 42, 42)}, -//#line 26 "colors.gperf" - {"aquamarine", svgtiny_RGB(127, 255, 212)}, -//#line 38 "colors.gperf" - {"chocolate", svgtiny_RGB(210, 105, 30)}, -//#line 88 "colors.gperf" - {"lawngreen", svgtiny_RGB(124, 252, 0)}, -//#line 147 "colors.gperf" - {"sandybrown", svgtiny_RGB(244, 164, 96)}, -//#line 92 "colors.gperf" - {"lightcyan", svgtiny_RGB(224, 255, 255)}, -//#line 164 "colors.gperf" - {"violet", svgtiny_RGB(238, 130, 238)}, -//#line 104 "colors.gperf" - {"lightyellow", svgtiny_RGB(255, 255, 224)}, -//#line 111 "colors.gperf" - {"mediumblue", svgtiny_RGB( 0, 0, 205)}, -//#line 136 "colors.gperf" - {"peachpuff", svgtiny_RGB(255, 218, 185)}, -//#line 79 "colors.gperf" - {"greenyellow", svgtiny_RGB(173, 255, 47)}, -//#line 24 "colors.gperf" - {"antiquewhite", svgtiny_RGB(250, 235, 215)}, -//#line 32 "colors.gperf" - {"blue", svgtiny_RGB( 0, 0, 255)}, -//#line 118 "colors.gperf" - {"mediumvioletred", svgtiny_RGB(199, 21, 133)}, -//#line 113 "colors.gperf" - {"mediumpurple", svgtiny_RGB(147, 112, 219)}, -//#line 75 "colors.gperf" - {"goldenrod", svgtiny_RGB(218, 165, 32)}, -//#line 31 "colors.gperf" - {"blanchedalmond", svgtiny_RGB(255, 235, 205)}, -//#line 85 "colors.gperf" - {"khaki", svgtiny_RGB(240, 230, 140)}, -//#line 139 "colors.gperf" - {"plum", svgtiny_RGB(221, 160, 221)}, -//#line 112 "colors.gperf" - {"mediumorchid", svgtiny_RGB(186, 85, 211)}, -//#line 143 "colors.gperf" - {"rosybrown", svgtiny_RGB(188, 143, 143)}, -//#line 115 "colors.gperf" - {"mediumslateblue", svgtiny_RGB(123, 104, 238)}, -//#line 61 "colors.gperf" - {"darkturquoise", svgtiny_RGB( 0, 206, 209)}, -//#line 134 "colors.gperf" - {"palevioletred", svgtiny_RGB(219, 112, 147)}, -//#line 135 "colors.gperf" - {"papayawhip", svgtiny_RGB(255, 239, 213)}, -//#line 116 "colors.gperf" - {"mediumspringgreen", svgtiny_RGB( 0, 250, 154)}, -//#line 49 "colors.gperf" - {"darkgrey", svgtiny_RGB(169, 169, 169)}, -//#line 117 "colors.gperf" - {"mediumturquoise", svgtiny_RGB( 72, 209, 204)}, -//#line 47 "colors.gperf" - {"darkgray", svgtiny_RGB(169, 169, 169)}, -//#line 46 "colors.gperf" - {"darkgoldenrod", svgtiny_RGB(184, 134, 11)}, -//#line 66 "colors.gperf" - {"dimgrey", svgtiny_RGB(105, 105, 105)}, -//#line 65 "colors.gperf" - {"dimgray", svgtiny_RGB(105, 105, 105)}, -//#line 80 "colors.gperf" - {"honeydew", svgtiny_RGB(240, 255, 240)}, -//#line 28 "colors.gperf" - {"beige", svgtiny_RGB(245, 245, 220)}, -//#line 161 "colors.gperf" - {"thistle", svgtiny_RGB(216, 191, 216)}, -//#line 41 "colors.gperf" - {"cornsilk", svgtiny_RGB(255, 248, 220)}, -//#line 126 "colors.gperf" - {"olive", svgtiny_RGB(128, 128, 0)}, -//#line 33 "colors.gperf" - {"blueviolet", svgtiny_RGB(138, 43, 226)}, -//#line 110 "colors.gperf" - {"mediumaquamarine", svgtiny_RGB(102, 205, 170)}, -//#line 40 "colors.gperf" - {"cornflowerblue", svgtiny_RGB(100, 149, 237)}, -//#line 23 "colors.gperf" - {"aliceblue", svgtiny_RGB(240, 248, 255)}, -//#line 140 "colors.gperf" - {"powderblue", svgtiny_RGB(176, 224, 230)}, -//#line 133 "colors.gperf" - {"paleturquoise", svgtiny_RGB(175, 238, 238)}, -//#line 60 "colors.gperf" - {"darkslategrey", svgtiny_RGB( 47, 79, 79)}, -//#line 50 "colors.gperf" - {"darkkhaki", svgtiny_RGB(189, 183, 107)}, -//#line 59 "colors.gperf" - {"darkslategray", svgtiny_RGB( 47, 79, 79)}, -//#line 73 "colors.gperf" - {"ghostwhite", svgtiny_RGB(248, 248, 255)}, -//#line 127 "colors.gperf" - {"olivedrab", svgtiny_RGB(107, 142, 35)}, -//#line 131 "colors.gperf" - {"palegoldenrod", svgtiny_RGB(238, 232, 170)}, -//#line 45 "colors.gperf" - {"darkcyan", svgtiny_RGB( 0, 139, 139)}, -//#line 81 "colors.gperf" - {"hotpink", svgtiny_RGB(255, 105, 180)}, -//#line 72 "colors.gperf" - {"gainsboro", svgtiny_RGB(220, 220, 220)}, -//#line 63 "colors.gperf" - {"deeppink", svgtiny_RGB(255, 20, 147)}, -//#line 42 "colors.gperf" - {"crimson", svgtiny_RGB(220, 20, 60)}, -//#line 35 "colors.gperf" - {"burlywood", svgtiny_RGB(222, 184, 135)}, -//#line 69 "colors.gperf" - {"floralwhite", svgtiny_RGB(255, 250, 240)}, -//#line 166 "colors.gperf" - {"white", svgtiny_RGB(255, 255, 255)}, -//#line 123 "colors.gperf" - {"navajowhite", svgtiny_RGB(255, 222, 173)}, -//#line 168 "colors.gperf" - {"yellow", svgtiny_RGB(255, 255, 0)}, -//#line 169 "colors.gperf" - {"yellowgreen", svgtiny_RGB(154, 205, 50)}, -//#line 100 "colors.gperf" - {"lightskyblue", svgtiny_RGB(135, 206, 250)}, -//#line 64 "colors.gperf" - {"deepskyblue", svgtiny_RGB( 0, 191, 255)}, -//#line 167 "colors.gperf" - {"whitesmoke", svgtiny_RGB(245, 245, 245)} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = svgtiny_color_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) - { - register const struct svgtiny_named_color *resword; - - switch (key - 4) - { - case 0: - resword = &wordlist[0]; - goto compare; - case 10: - resword = &wordlist[1]; - goto compare; - case 16: - resword = &wordlist[2]; - goto compare; - case 20: - resword = &wordlist[3]; - goto compare; - case 21: - resword = &wordlist[4]; - goto compare; - case 25: - resword = &wordlist[5]; - goto compare; - case 26: - resword = &wordlist[6]; - goto compare; - case 30: - resword = &wordlist[7]; - goto compare; - case 33: - resword = &wordlist[8]; - goto compare; - case 35: - resword = &wordlist[9]; - goto compare; - case 37: - resword = &wordlist[10]; - goto compare; - case 40: - resword = &wordlist[11]; - goto compare; - case 44: - resword = &wordlist[12]; - goto compare; - case 45: - resword = &wordlist[13]; - goto compare; - case 46: - resword = &wordlist[14]; - goto compare; - case 52: - resword = &wordlist[15]; - goto compare; - case 55: - resword = &wordlist[16]; - goto compare; - case 56: - resword = &wordlist[17]; - goto compare; - case 60: - resword = &wordlist[18]; - goto compare; - case 62: - resword = &wordlist[19]; - goto compare; - case 65: - resword = &wordlist[20]; - goto compare; - case 67: - resword = &wordlist[21]; - goto compare; - case 70: - resword = &wordlist[22]; - goto compare; - case 74: - resword = &wordlist[23]; - goto compare; - case 75: - resword = &wordlist[24]; - goto compare; - case 76: - resword = &wordlist[25]; - goto compare; - case 80: - resword = &wordlist[26]; - goto compare; - case 81: - resword = &wordlist[27]; - goto compare; - case 83: - resword = &wordlist[28]; - goto compare; - case 85: - resword = &wordlist[29]; - goto compare; - case 90: - resword = &wordlist[30]; - goto compare; - case 91: - resword = &wordlist[31]; - goto compare; - case 92: - resword = &wordlist[32]; - goto compare; - case 93: - resword = &wordlist[33]; - goto compare; - case 95: - resword = &wordlist[34]; - goto compare; - case 97: - resword = &wordlist[35]; - goto compare; - case 100: - resword = &wordlist[36]; - goto compare; - case 102: - resword = &wordlist[37]; - goto compare; - case 104: - resword = &wordlist[38]; - goto compare; - case 105: - resword = &wordlist[39]; - goto compare; - case 107: - resword = &wordlist[40]; - goto compare; - case 109: - resword = &wordlist[41]; - goto compare; - case 110: - resword = &wordlist[42]; - goto compare; - case 114: - resword = &wordlist[43]; - goto compare; - case 115: - resword = &wordlist[44]; - goto compare; - case 117: - resword = &wordlist[45]; - goto compare; - case 118: - resword = &wordlist[46]; - goto compare; - case 120: - resword = &wordlist[47]; - goto compare; - case 125: - resword = &wordlist[48]; - goto compare; - case 129: - resword = &wordlist[49]; - goto compare; - case 130: - resword = &wordlist[50]; - goto compare; - case 135: - resword = &wordlist[51]; - goto compare; - case 137: - resword = &wordlist[52]; - goto compare; - case 138: - resword = &wordlist[53]; - goto compare; - case 140: - resword = &wordlist[54]; - goto compare; - case 141: - resword = &wordlist[55]; - goto compare; - case 144: - resword = &wordlist[56]; - goto compare; - case 145: - resword = &wordlist[57]; - goto compare; - case 149: - resword = &wordlist[58]; - goto compare; - case 155: - resword = &wordlist[59]; - goto compare; - case 156: - resword = &wordlist[60]; - goto compare; - case 157: - resword = &wordlist[61]; - goto compare; - case 159: - resword = &wordlist[62]; - goto compare; - case 160: - resword = &wordlist[63]; - goto compare; - case 164: - resword = &wordlist[64]; - goto compare; - case 165: - resword = &wordlist[65]; - goto compare; - case 166: - resword = &wordlist[66]; - goto compare; - case 167: - resword = &wordlist[67]; - goto compare; - case 168: - resword = &wordlist[68]; - goto compare; - case 170: - resword = &wordlist[69]; - goto compare; - case 172: - resword = &wordlist[70]; - goto compare; - case 174: - resword = &wordlist[71]; - goto compare; - case 175: - resword = &wordlist[72]; - goto compare; - case 176: - resword = &wordlist[73]; - goto compare; - case 180: - resword = &wordlist[74]; - goto compare; - case 181: - resword = &wordlist[75]; - goto compare; - case 182: - resword = &wordlist[76]; - goto compare; - case 183: - resword = &wordlist[77]; - goto compare; - case 185: - resword = &wordlist[78]; - goto compare; - case 188: - resword = &wordlist[79]; - goto compare; - case 190: - resword = &wordlist[80]; - goto compare; - case 191: - resword = &wordlist[81]; - goto compare; - case 192: - resword = &wordlist[82]; - goto compare; - case 196: - resword = &wordlist[83]; - goto compare; - case 200: - resword = &wordlist[84]; - goto compare; - case 201: - resword = &wordlist[85]; - goto compare; - case 209: - resword = &wordlist[86]; - goto compare; - case 210: - resword = &wordlist[87]; - goto compare; - case 211: - resword = &wordlist[88]; - goto compare; - case 215: - resword = &wordlist[89]; - goto compare; - case 221: - resword = &wordlist[90]; - goto compare; - case 222: - resword = &wordlist[91]; - goto compare; - case 226: - resword = &wordlist[92]; - goto compare; - case 230: - resword = &wordlist[93]; - goto compare; - case 232: - resword = &wordlist[94]; - goto compare; - case 238: - resword = &wordlist[95]; - goto compare; - case 240: - resword = &wordlist[96]; - goto compare; - case 241: - resword = &wordlist[97]; - goto compare; - case 243: - resword = &wordlist[98]; - goto compare; - case 245: - resword = &wordlist[99]; - goto compare; - case 250: - resword = &wordlist[100]; - goto compare; - case 251: - resword = &wordlist[101]; - goto compare; - case 255: - resword = &wordlist[102]; - goto compare; - case 258: - resword = &wordlist[103]; - goto compare; - case 260: - resword = &wordlist[104]; - goto compare; - case 261: - resword = &wordlist[105]; - goto compare; - case 263: - resword = &wordlist[106]; - goto compare; - case 269: - resword = &wordlist[107]; - goto compare; - case 271: - resword = &wordlist[108]; - goto compare; - case 278: - resword = &wordlist[109]; - goto compare; - case 279: - resword = &wordlist[110]; - goto compare; - case 281: - resword = &wordlist[111]; - goto compare; - case 284: - resword = &wordlist[112]; - goto compare; - case 289: - resword = &wordlist[113]; - goto compare; - case 293: - resword = &wordlist[114]; - goto compare; - case 298: - resword = &wordlist[115]; - goto compare; - case 299: - resword = &wordlist[116]; - goto compare; - case 306: - resword = &wordlist[117]; - goto compare; - case 308: - resword = &wordlist[118]; - goto compare; - case 309: - resword = &wordlist[119]; - goto compare; - case 311: - resword = &wordlist[120]; - goto compare; - case 316: - resword = &wordlist[121]; - goto compare; - case 321: - resword = &wordlist[122]; - goto compare; - case 330: - resword = &wordlist[123]; - goto compare; - case 335: - resword = &wordlist[124]; - goto compare; - case 336: - resword = &wordlist[125]; - goto compare; - case 338: - resword = &wordlist[126]; - goto compare; - case 344: - resword = &wordlist[127]; - goto compare; - case 345: - resword = &wordlist[128]; - goto compare; - case 349: - resword = &wordlist[129]; - goto compare; - case 350: - resword = &wordlist[130]; - goto compare; - case 355: - resword = &wordlist[131]; - goto compare; - case 364: - resword = &wordlist[132]; - goto compare; - case 369: - resword = &wordlist[133]; - goto compare; - case 373: - resword = &wordlist[134]; - goto compare; - case 380: - resword = &wordlist[135]; - goto compare; - case 384: - resword = &wordlist[136]; - goto compare; - case 398: - resword = &wordlist[137]; - goto compare; - case 410: - resword = &wordlist[138]; - goto compare; - case 426: - resword = &wordlist[139]; - goto compare; - case 436: - resword = &wordlist[140]; - goto compare; - case 437: - resword = &wordlist[141]; - goto compare; - case 467: - resword = &wordlist[142]; - goto compare; - case 482: - resword = &wordlist[143]; - goto compare; - case 483: - resword = &wordlist[144]; - goto compare; - case 552: - resword = &wordlist[145]; - goto compare; - case 561: - resword = &wordlist[146]; - goto compare; - } - return 0; - compare: - { - register const char *s = resword->name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return resword; - } - } - } - return 0; -} - -int LICE_RGBA_from_SVG(const char* s,int len) // returns LICE_pixel -{ - int r = 0, g = 0, b = 0; - double rf = 0.0, gf = 0.0, bf = 0.0; - const struct svgtiny_named_color* c = 0; - -#ifdef _WIN32 - if (len == 4 && !strnicmp(s, "none", 4)) return 0; -#else - if (len == 4 && !strncasecmp(s, "none", 4)) return 0; -#endif - - if (len == 4 && s[0] == '#') - { - if (sscanf(s+1, "%1x%1x%1x", &r, &g, &b) == 3) - { - return svgtiny_RGB(r<<4,g<<4,b<<4); - } - } - else if (len == 7 && s[0] == '#') - { - if (sscanf(s+1, "%2x%2x%2x", &r, &g, &b) == 3) - { - return svgtiny_RGB(r, g, b); - } - } - else if (10 <= len && s[0] == 'r' && s[1] == 'g' && s[2] == 'b' && s[3] == '(' && s[len - 1] == ')') - { - if (sscanf(s+4, "%i,%i,%i", &r, &g, &b) == 3) - { - return svgtiny_RGB(r, g, b); - } - else - { - if (sscanf(s+4, "%f%%,%f%%,%f%%", &rf, &gf, &bf) == 3) - { - b = (int) (bf*2.55); - g = (int) (gf*2.55); - r = (int) (rf*2.55); - return svgtiny_RGB(r, g, b); - } - } - } - else - { - c = svgtiny_color_lookup(s, len); - if (c) return c->color; - } - - return 0; -} diff --git a/WDL/tinyxml/tinystr.cpp b/WDL/tinyxml/tinystr.cpp deleted file mode 100644 index 68125071..00000000 --- a/WDL/tinyxml/tinystr.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original file by Yves Berquin. - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -/* - * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. - */ - - -#ifndef TIXML_USE_STL - -#include "tinystr.h" - -// Error value for find primitive -const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); - - -// Null rep. -TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; - - -void TiXmlString::reserve (size_type cap) -{ - if (cap > capacity()) - { - TiXmlString tmp; - tmp.init(length(), cap); - memcpy(tmp.start(), data(), length()); - swap(tmp); - } -} - - -TiXmlString& TiXmlString::assign(const char* str, size_type len) -{ - size_type cap = capacity(); - if (len > cap || cap > 3*(len + 8)) - { - TiXmlString tmp; - tmp.init(len); - memcpy(tmp.start(), str, len); - swap(tmp); - } - else - { - memmove(start(), str, len); - set_size(len); - } - return *this; -} - - -TiXmlString& TiXmlString::append(const char* str, size_type len) -{ - size_type newsize = length() + len; - if (newsize > capacity()) - { - reserve (newsize + capacity()); - } - memmove(finish(), str, len); - set_size(newsize); - return *this; -} - - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) -{ - TiXmlString tmp; - tmp.reserve(a.length() + b.length()); - tmp += a; - tmp += b; - return tmp; -} - -TiXmlString operator + (const TiXmlString & a, const char* b) -{ - TiXmlString tmp; - TiXmlString::size_type b_len = static_cast( strlen(b) ); - tmp.reserve(a.length() + b_len); - tmp += a; - tmp.append(b, b_len); - return tmp; -} - -TiXmlString operator + (const char* a, const TiXmlString & b) -{ - TiXmlString tmp; - TiXmlString::size_type a_len = static_cast( strlen(a) ); - tmp.reserve(a_len + b.length()); - tmp.append(a, a_len); - tmp += b; - return tmp; -} - - -#endif // TIXML_USE_STL diff --git a/WDL/tinyxml/tinystr.h b/WDL/tinyxml/tinystr.h deleted file mode 100644 index 8e03028b..00000000 --- a/WDL/tinyxml/tinystr.h +++ /dev/null @@ -1,320 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original file by Yves Berquin. - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -/* - * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. - * - * - completely rewritten. compact, clean, and fast implementation. - * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) - * - fixed reserve() to work as per specification. - * - fixed buggy compares operator==(), operator<(), and operator>() - * - fixed operator+=() to take a const ref argument, following spec. - * - added "copy" constructor with length, and most compare operators. - * - added swap(), clear(), size(), capacity(), operator+(). - */ - -#ifndef TIXML_USE_STL - -#ifndef TIXML_STRING_INCLUDED -#define TIXML_STRING_INCLUDED - -#include -#include - -/* The support for explicit isn't that universal, and it isn't really - required - it is used to check that the TiXmlString class isn't incorrectly - used. Be nice to old compilers and macro it here: -*/ - -#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - #define TIXML_EXPLICIT explicit -#elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - #define TIXML_EXPLICIT explicit -#else - #define TIXML_EXPLICIT -#endif - -/* - TiXmlString is an emulation of a subset of the std::string template. - Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. - Only the member functions relevant to the TinyXML project have been implemented. - The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase - a string and there's no more room, we allocate a buffer twice as big as we need. -*/ - -class TiXmlString -{ - public : - // The size type used - typedef size_t size_type; - - // Error value for find primitive - static const size_type npos; // = -1; - - - // TiXmlString empty constructor - TiXmlString () : rep_(&nullrep_) - { - } - - // TiXmlString copy constructor - TiXmlString ( const TiXmlString & copy) : rep_(0) - { - init(copy.length()); - memcpy(start(), copy.data(), length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) - { - init( static_cast( strlen(copy) )); - memcpy(start(), copy, length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) - { - init(len); - memcpy(start(), str, len); - } - - // TiXmlString destructor - ~TiXmlString () - { - quit(); - } - - // = operator - TiXmlString& operator = (const char * copy) - { - return assign( copy, (size_type)strlen(copy)); - } - - // = operator - TiXmlString& operator = (const TiXmlString & copy) - { - return assign(copy.start(), copy.length()); - } - - - // += operator. Maps to append - TiXmlString& operator += (const char * suffix) - { - return append(suffix, static_cast( strlen(suffix) )); - } - - // += operator. Maps to append - TiXmlString& operator += (char single) - { - return append(&single, 1); - } - - // += operator. Maps to append - TiXmlString& operator += (const TiXmlString & suffix) - { - return append(suffix.data(), suffix.length()); - } - - - // Convert a TiXmlString into a null-terminated char * - const char * c_str () const { return rep_->str; } - - // Convert a TiXmlString into a char * (need not be null terminated). - const char * data () const { return rep_->str; } - - // Return the length of a TiXmlString - size_type length () const { return rep_->size; } - - // Alias for length() - size_type size () const { return rep_->size; } - - // Checks if a TiXmlString is empty - bool empty () const { return rep_->size == 0; } - - // Return capacity of string - size_type capacity () const { return rep_->capacity; } - - - // single char extraction - const char& at (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // [] operator - char& operator [] (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // find a char in a string. Return TiXmlString::npos if not found - size_type find (char lookup) const - { - return find(lookup, 0); - } - - // find a char in a string from an offset. Return TiXmlString::npos if not found - size_type find (char tofind, size_type offset) const - { - if (offset >= length()) return npos; - - for (const char* p = c_str() + offset; *p != '\0'; ++p) - { - if (*p == tofind) return static_cast< size_type >( p - c_str() ); - } - return npos; - } - - void clear () - { - //Lee: - //The original was just too strange, though correct: - // TiXmlString().swap(*this); - //Instead use the quit & re-init: - quit(); - init(0,0); - } - - /* Function to reserve a big amount of data when we know we'll need it. Be aware that this - function DOES NOT clear the content of the TiXmlString if any exists. - */ - void reserve (size_type cap); - - TiXmlString& assign (const char* str, size_type len); - - TiXmlString& append (const char* str, size_type len); - - void swap (TiXmlString& other) - { - Rep* r = rep_; - rep_ = other.rep_; - other.rep_ = r; - } - - private: - - void init(size_type sz) { init(sz, sz); } - void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } - char* start() const { return rep_->str; } - char* finish() const { return rep_->str + rep_->size; } - - struct Rep - { - size_type size, capacity; - char str[1]; - }; - - void init(size_type sz, size_type cap) - { - if (cap) - { - // Lee: the original form: - // rep_ = static_cast(operator new(sizeof(Rep) + cap)); - // doesn't work in some cases of new being overloaded. Switching - // to the normal allocation, although use an 'int' for systems - // that are overly picky about structure alignment. - const size_type bytesNeeded = sizeof(Rep) + cap; - const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); - rep_ = reinterpret_cast( new int[ intsNeeded ] ); - - rep_->str[ rep_->size = sz ] = '\0'; - rep_->capacity = cap; - } - else - { - rep_ = &nullrep_; - } - } - - void quit() - { - if (rep_ != &nullrep_) - { - // The rep_ is really an array of ints. (see the allocator, above). - // Cast it back before delete, so the compiler won't incorrectly call destructors. - delete [] ( reinterpret_cast( rep_ ) ); - } - } - - Rep * rep_; - static Rep nullrep_; - -} ; - - -inline bool operator == (const TiXmlString & a, const TiXmlString & b) -{ - return ( a.length() == b.length() ) // optimization on some platforms - && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare -} -inline bool operator < (const TiXmlString & a, const TiXmlString & b) -{ - return strcmp(a.c_str(), b.c_str()) < 0; -} - -inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } -inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } -inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } -inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } - -inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } -inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } -inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } -inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); -TiXmlString operator + (const TiXmlString & a, const char* b); -TiXmlString operator + (const char* a, const TiXmlString & b); - - -/* - TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. - Only the operators that we need for TinyXML have been developped. -*/ -class TiXmlOutStream : public TiXmlString -{ -public : - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const TiXmlString & in) - { - *this += in; - return *this; - } - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const char * in) - { - *this += in; - return *this; - } - -} ; - -#endif // TIXML_STRING_INCLUDED -#endif // TIXML_USE_STL diff --git a/WDL/tinyxml/tinyxml.cpp b/WDL/tinyxml/tinyxml.cpp deleted file mode 100644 index 5de21f6d..00000000 --- a/WDL/tinyxml/tinyxml.cpp +++ /dev/null @@ -1,1888 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include - -#ifdef TIXML_USE_STL -#include -#include -#endif - -#include "tinyxml.h" - - -bool TiXmlBase::condenseWhiteSpace = true; - -// Microsoft compiler security -FILE* TiXmlFOpen( const char* filename, const char* mode ) -{ - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filename, mode ); - if ( !err && fp ) - return fp; - return 0; - #else - return fopen( filename, mode ); - #endif -} - -void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) -{ - int i=0; - - while( i<(int)str.length() ) - { - unsigned char c = (unsigned char) str[i]; - - if ( c == '&' - && i < ( (int)str.length() - 2 ) - && str[i+1] == '#' - && str[i+2] == 'x' ) - { - // Hexadecimal character reference. - // Pass through unchanged. - // © -- copyright symbol, for example. - // - // The -1 is a bug fix from Rob Laveaux. It keeps - // an overflow from happening if there is no ';'. - // There are actually 2 ways to exit this loop - - // while fails (error case) and break (semicolon found). - // However, there is no mechanism (currently) for - // this function to return an error. - while ( i<(int)str.length()-1 ) - { - outString->append( str.c_str() + i, 1 ); - ++i; - if ( str[i] == ';' ) - break; - } - } - else if ( c == '&' ) - { - outString->append( entity[0].str, entity[0].strLength ); - ++i; - } - else if ( c == '<' ) - { - outString->append( entity[1].str, entity[1].strLength ); - ++i; - } - else if ( c == '>' ) - { - outString->append( entity[2].str, entity[2].strLength ); - ++i; - } - else if ( c == '\"' ) - { - outString->append( entity[3].str, entity[3].strLength ); - ++i; - } - else if ( c == '\'' ) - { - outString->append( entity[4].str, entity[4].strLength ); - ++i; - } - else if ( c < 32 ) - { - // Easy pass at non-alpha/numeric/symbol - // Below 32 is symbolic. - char buf[ 32 ]; - - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); - #else - sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); - #endif - - //*ME: warning C4267: convert 'size_t' to 'int' - //*ME: Int-Cast to make compiler happy ... - outString->append( buf, (int)strlen( buf ) ); - ++i; - } - else - { - //char realc = (char) c; - //outString->append( &realc, 1 ); - *outString += (char) c; // somewhat more efficient function call. - ++i; - } - } -} - - -TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -{ - parent = 0; - type = _type; - firstChild = 0; - lastChild = 0; - prev = 0; - next = 0; -} - - -TiXmlNode::~TiXmlNode() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } -} - - -void TiXmlNode::CopyTo( TiXmlNode* target ) const -{ - target->SetValue (value.c_str() ); - target->userData = userData; -} - - -void TiXmlNode::Clear() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } - - firstChild = 0; - lastChild = 0; -} - - -TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -{ - assert( node->parent == 0 || node->parent == this ); - assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); - - if ( node->Type() == TiXmlNode::DOCUMENT ) - { - delete node; - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - node->parent = this; - - node->prev = lastChild; - node->next = 0; - - if ( lastChild ) - lastChild->next = node; - else - firstChild = node; // it was an empty list. - - lastChild = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -{ - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - - return LinkEndChild( node ); -} - - -TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -{ - if ( !beforeThis || beforeThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->next = beforeThis; - node->prev = beforeThis->prev; - if ( beforeThis->prev ) - { - beforeThis->prev->next = node; - } - else - { - assert( firstChild == beforeThis ); - firstChild = node; - } - beforeThis->prev = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -{ - if ( !afterThis || afterThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->prev = afterThis; - node->next = afterThis->next; - if ( afterThis->next ) - { - afterThis->next->prev = node; - } - else - { - assert( lastChild == afterThis ); - lastChild = node; - } - afterThis->next = node; - return node; -} - - -TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -{ - if ( replaceThis->parent != this ) - return 0; - - TiXmlNode* node = withThis.Clone(); - if ( !node ) - return 0; - - node->next = replaceThis->next; - node->prev = replaceThis->prev; - - if ( replaceThis->next ) - replaceThis->next->prev = node; - else - lastChild = node; - - if ( replaceThis->prev ) - replaceThis->prev->next = node; - else - firstChild = node; - - delete replaceThis; - node->parent = this; - return node; -} - - -bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -{ - if ( removeThis->parent != this ) - { - assert( 0 ); - return false; - } - - if ( removeThis->next ) - removeThis->next->prev = removeThis->prev; - else - lastChild = removeThis->prev; - - if ( removeThis->prev ) - removeThis->prev->next = removeThis->next; - else - firstChild = removeThis->next; - - delete removeThis; - return true; -} - -const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = firstChild; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = lastChild; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild(); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling(); - } -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild( val ); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling( val ); - } -} - - -const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = next; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = prev; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -void TiXmlElement::RemoveAttribute( const char * name ) -{ - #ifdef TIXML_USE_STL - TIXML_STRING str( name ); - TiXmlAttribute* node = attributeSet.Find( str ); - #else - TiXmlAttribute* node = attributeSet.Find( name ); - #endif - if ( node ) - { - attributeSet.Remove( node ); - delete node; - } -} - -const TiXmlElement* TiXmlNode::FirstChildElement() const -{ - const TiXmlNode* node; - - for ( node = FirstChild(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = FirstChild( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement() const -{ - const TiXmlNode* node; - - for ( node = NextSibling(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = NextSibling( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlDocument* TiXmlNode::GetDocument() const -{ - const TiXmlNode* node; - - for( node = this; node; node = node->parent ) - { - if ( node->ToDocument() ) - return node->ToDocument(); - } - return 0; -} - - -TiXmlElement::TiXmlElement (const char * _value) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} - - -#ifdef TIXML_USE_STL -TiXmlElement::TiXmlElement( const std::string& _value ) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} -#endif - - -TiXmlElement::TiXmlElement( const TiXmlElement& copy) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - copy.CopyTo( this ); -} - - -void TiXmlElement::operator=( const TiXmlElement& base ) -{ - ClearThis(); - base.CopyTo( this ); -} - - -TiXmlElement::~TiXmlElement() -{ - ClearThis(); -} - - -void TiXmlElement::ClearThis() -{ - Clear(); - while( attributeSet.First() ) - { - TiXmlAttribute* node = attributeSet.First(); - attributeSet.Remove( node ); - delete node; - } -} - - -const char* TiXmlElement::Attribute( const char* name ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return node->Value(); - return 0; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return &node->ValueStr(); - return 0; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, int* i ) const -{ - const char* s = Attribute( name ); - if ( i ) - { - if ( s ) { - *i = atoi( s ); - } - else { - *i = 0; - } - } - return s; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const -{ - const std::string* s = Attribute( name ); - if ( i ) - { - if ( s ) { - *i = atoi( s->c_str() ); - } - else { - *i = 0; - } - } - return s; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, double* d ) const -{ - const char* s = Attribute( name ); - if ( d ) - { - if ( s ) { - *d = atof( s ); - } - else { - *d = 0; - } - } - return s; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const -{ - const std::string* s = Attribute( name ); - if ( d ) - { - if ( s ) { - *d = atof( s->c_str() ); - } - else { - *d = 0; - } - } - return s; -} -#endif - - -int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); -} -#endif - - -int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); -} -#endif - - -void TiXmlElement::SetAttribute( const char * name, int val ) -{ - char buf[64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); - #else - sprintf( buf, "%d", val ); - #endif - SetAttribute( name, buf ); -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& name, int val ) -{ - std::ostringstream oss; - oss << val; - SetAttribute( name, oss.str() ); -} -#endif - - -void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -{ - char buf[256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); - #else - sprintf( buf, "%f", val ); - #endif - SetAttribute( name, buf ); -} - - -void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) -{ - #ifdef TIXML_USE_STL - TIXML_STRING _name( cname ); - TIXML_STRING _value( cvalue ); - #else - const char* _name = cname; - const char* _value = cvalue; - #endif - - TiXmlAttribute* node = attributeSet.Find( _name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) -{ - TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } -} -#endif - - -void TiXmlElement::Print( FILE* cfile, int depth ) const -{ - int i; - assert( cfile ); - for ( i=0; iNext() ) - { - fprintf( cfile, " " ); - attrib->Print( cfile, depth ); - } - - // There are 3 different formatting approaches: - // 1) An element without children is printed as a node - // 2) An element with only a text child is printed as text - // 3) An element with children is printed on multiple lines. - TiXmlNode* node; - if ( !firstChild ) - { - fprintf( cfile, " />" ); - } - else if ( firstChild == lastChild && firstChild->ToText() ) - { - fprintf( cfile, ">" ); - firstChild->Print( cfile, depth + 1 ); - fprintf( cfile, "", value.c_str() ); - } - else - { - fprintf( cfile, ">" ); - - for ( node = firstChild; node; node=node->NextSibling() ) - { - if ( !node->ToText() ) - { - fprintf( cfile, "\n" ); - } - node->Print( cfile, depth+1 ); - } - fprintf( cfile, "\n" ); - for( i=0; i", value.c_str() ); - } -} - - -void TiXmlElement::CopyTo( TiXmlElement* target ) const -{ - // superclass: - TiXmlNode::CopyTo( target ); - - // Element class: - // Clone the attributes, then clone the children. - const TiXmlAttribute* attribute = 0; - for( attribute = attributeSet.First(); - attribute; - attribute = attribute->Next() ) - { - target->SetAttribute( attribute->Name(), attribute->Value() ); - } - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - -bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, attributeSet.First() ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -TiXmlNode* TiXmlElement::Clone() const -{ - TiXmlElement* clone = new TiXmlElement( Value() ); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -const char* TiXmlElement::GetText() const -{ - const TiXmlNode* child = this->FirstChild(); - if ( child ) { - const TiXmlText* childText = child->ToText(); - if ( childText ) { - return childText->Value(); - } - } - return 0; -} - - -TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - ClearError(); -} - -TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} - - -#ifdef TIXML_USE_STL -TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} -#endif - - -TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDocument::operator=( const TiXmlDocument& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -{ - // See STL_STRING_BUG below. - //StringToBuffer buf( value ); - - return LoadFile( Value(), encoding ); -} - - -bool TiXmlDocument::SaveFile() const -{ - // See STL_STRING_BUG below. -// StringToBuffer buf( value ); -// -// if ( buf.buffer && SaveFile( buf.buffer ) ) -// return true; -// -// return false; - return SaveFile( Value() ); -} - -bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) -{ - // There was a really terrifying little bug here. The code: - // value = filename - // in the STL case, cause the assignment method of the std::string to - // be called. What is strange, is that the std::string had the same - // address as it's c_str() method, and so bad things happen. Looks - // like a bug in the Microsoft STL implementation. - // Add an extra string to avoid the crash. - TIXML_STRING filename( _filename ); - value = filename; - - // reading in binary mode so that tinyxml can normalize the EOL - FILE* file = TiXmlFOpen( value.c_str (), "rb" ); - - if ( file ) - { - bool result = LoadFile( file, encoding ); - fclose( file ); - return result; - } - else - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } -} - -bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) -{ - if ( !file ) - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Delete the existing data: - Clear(); - location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = 0; - fseek( file, 0, SEEK_END ); - length = ftell( file ); - fseek( file, 0, SEEK_SET ); - - // Strange case, but good to handle up front. - if ( length <= 0 ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // If we have a file, assume it is all one big XML file, and read it in. - // The document parser may decide the document ends sooner than the entire file, however. - TIXML_STRING data; - data.reserve( length ); - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // - // - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[ length+1 ]; - buf[0] = 0; - - if ( fread( buf, length, 1, file ) != 1 ) { - delete [] buf; - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - const char* lastPos = buf; - const char* p = buf; - - buf[length] = 0; - while( *p ) { - assert( p < (buf+length) ); - if ( *p == 0xa ) { - // Newline character. No special rules for this. Append all the characters - // since the last string, and include the newline. - data.append( lastPos, (p-lastPos+1) ); // append, include the newline - ++p; // move past the newline - lastPos = p; // and point to the new buffer (may be 0) - assert( p <= (buf+length) ); - } - else if ( *p == 0xd ) { - // Carriage return. Append what we have so far, then - // handle moving forward in the buffer. - if ( (p-lastPos) > 0 ) { - data.append( lastPos, p-lastPos ); // do not add the CR - } - data += (char)0xa; // a proper newline - - if ( *(p+1) == 0xa ) { - // Carriage return - new line sequence - p += 2; - lastPos = p; - assert( p <= (buf+length) ); - } - else { - // it was followed by something else...that is presumably characters again. - ++p; - lastPos = p; - assert( p <= (buf+length) ); - } - } - else { - ++p; - } - } - // Handle any left over characters. - if ( p-lastPos ) { - data.append( lastPos, p-lastPos ); - } - delete [] buf; - buf = 0; - - Parse( data.c_str(), 0, encoding ); - - if ( Error() ) - return false; - else - return true; -} - - -bool TiXmlDocument::SaveFile( const char * filename ) const -{ - // The old c stuff lives on... - FILE* fp = TiXmlFOpen( filename, "w" ); - if ( fp ) - { - bool result = SaveFile( fp ); - fclose( fp ); - return result; - } - return false; -} - - -bool TiXmlDocument::SaveFile( FILE* fp ) const -{ - if ( useMicrosoftBOM ) - { - const unsigned char TIXML_UTF_LEAD_0 = 0xefU; - const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; - const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - fputc( TIXML_UTF_LEAD_0, fp ); - fputc( TIXML_UTF_LEAD_1, fp ); - fputc( TIXML_UTF_LEAD_2, fp ); - } - Print( fp, 0 ); - return (ferror(fp) == 0); -} - - -void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->error = error; - target->errorId = errorId; - target->errorDesc = errorDesc; - target->tabsize = tabsize; - target->errorLocation = errorLocation; - target->useMicrosoftBOM = useMicrosoftBOM; - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - - -TiXmlNode* TiXmlDocument::Clone() const -{ - TiXmlDocument* clone = new TiXmlDocument(); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlDocument::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - node->Print( cfile, depth ); - fprintf( cfile, "\n" ); - } -} - - -bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -const TiXmlAttribute* TiXmlAttribute::Next() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} - -/* -TiXmlAttribute* TiXmlAttribute::Next() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} -*/ - -const TiXmlAttribute* TiXmlAttribute::Previous() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} - -/* -TiXmlAttribute* TiXmlAttribute::Previous() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} -*/ - -void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - TIXML_STRING n, v; - - EncodeString( name, &n ); - EncodeString( value, &v ); - - if (value.find ('\"') == TIXML_STRING::npos) { - if ( cfile ) { - fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; - } - } - else { - if ( cfile ) { - fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; - } - } -} - - -int TiXmlAttribute::QueryIntValue( int* ival ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -int TiXmlAttribute::QueryDoubleValue( double* dval ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -void TiXmlAttribute::SetIntValue( int _value ) -{ - char buf [64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); - #else - sprintf (buf, "%d", _value); - #endif - SetValue (buf); -} - -void TiXmlAttribute::SetDoubleValue( double _value ) -{ - char buf [256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); - #else - sprintf (buf, "%lf", _value); - #endif - SetValue (buf); -} - -int TiXmlAttribute::IntValue() const -{ - return atoi (value.c_str ()); -} - -double TiXmlAttribute::DoubleValue() const -{ - return atof (value.c_str ()); -} - - -TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlComment::operator=( const TiXmlComment& base ) -{ - Clear(); - base.CopyTo( this ); -} - - -void TiXmlComment::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlComment::CopyTo( TiXmlComment* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlComment::Clone() const -{ - TiXmlComment* clone = new TiXmlComment(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlText::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - if ( cdata ) - { - int i; - fprintf( cfile, "\n" ); - for ( i=0; i\n", value.c_str() ); // unformatted output - } - else - { - TIXML_STRING buffer; - EncodeString( value, &buffer ); - fprintf( cfile, "%s", buffer.c_str() ); - } -} - - -void TiXmlText::CopyTo( TiXmlText* target ) const -{ - TiXmlNode::CopyTo( target ); - target->cdata = cdata; -} - - -bool TiXmlText::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlText::Clone() const -{ - TiXmlText* clone = 0; - clone = new TiXmlText( "" ); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlDeclaration::TiXmlDeclaration( const char * _version, - const char * _encoding, - const char * _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} - - -#ifdef TIXML_USE_STL -TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} -#endif - - -TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - if ( cfile ) fprintf( cfile, "" ); - if ( str ) (*str) += "?>"; -} - - -void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->version = version; - target->encoding = encoding; - target->standalone = standalone; -} - - -bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlDeclaration::Clone() const -{ - TiXmlDeclaration* clone = new TiXmlDeclaration(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlUnknown::Print( FILE* cfile, int depth ) const -{ - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlUnknown::Clone() const -{ - TiXmlUnknown* clone = new TiXmlUnknown(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlAttributeSet::TiXmlAttributeSet() -{ - sentinel.next = &sentinel; - sentinel.prev = &sentinel; -} - - -TiXmlAttributeSet::~TiXmlAttributeSet() -{ - assert( sentinel.next == &sentinel ); - assert( sentinel.prev == &sentinel ); -} - - -void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -{ - #ifdef TIXML_USE_STL - assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. - #else - assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. - #endif - - addMe->next = &sentinel; - addMe->prev = sentinel.prev; - - sentinel.prev->next = addMe; - sentinel.prev = addMe; -} - -void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -{ - TiXmlAttribute* node; - - for( node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node == removeMe ) - { - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; - return; - } - } - assert( 0 ); // we tried to remove a non-linked attribute. -} - - -#ifdef TIXML_USE_STL -const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const -{ - for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} - -/* -TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} -*/ -#endif - - -const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const -{ - for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} - -/* -TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} -*/ - -#ifdef TIXML_USE_STL -std::istream& operator>> (std::istream & in, TiXmlNode & base) -{ - TIXML_STRING tag; - tag.reserve( 8 * 1000 ); - base.StreamIn( &in, &tag ); - - base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); - return in; -} -#endif - - -#ifdef TIXML_USE_STL -std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out << printer.Str(); - - return out; -} - - -std::string& operator<< (std::string& out, const TiXmlNode& base ) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out.append( printer.Str() ); - - return out; -} -#endif - - -TiXmlHandle TiXmlHandle::FirstChild() const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement() const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild(); - for ( i=0; - child && iNextSibling(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild( value ); - for ( i=0; - child && iNextSibling( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement(); - for ( i=0; - child && iNextSiblingElement(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement( value ); - for ( i=0; - child && iNextSiblingElement( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) -{ - DoIndent(); - buffer += "<"; - buffer += element.Value(); - - for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) - { - buffer += " "; - attrib->Print( 0, 0, &buffer ); - } - - if ( !element.FirstChild() ) - { - buffer += " />"; - DoLineBreak(); - } - else - { - buffer += ">"; - if ( element.FirstChild()->ToText() - && element.LastChild() == element.FirstChild() - && element.FirstChild()->ToText()->CDATA() == false ) - { - simpleTextPrint = true; - // no DoLineBreak()! - } - else - { - DoLineBreak(); - } - } - ++depth; - return true; -} - - -bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) -{ - --depth; - if ( !element.FirstChild() ) - { - // nothing. - } - else - { - if ( simpleTextPrint ) - { - simpleTextPrint = false; - } - else - { - DoIndent(); - } - buffer += ""; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlText& text ) -{ - if ( text.CDATA() ) - { - DoIndent(); - buffer += ""; - DoLineBreak(); - } - else if ( simpleTextPrint ) - { - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - } - else - { - DoIndent(); - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) -{ - DoIndent(); - declaration.Print( 0, 0, &buffer ); - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlComment& comment ) -{ - DoIndent(); - buffer += ""; - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) -{ - DoIndent(); - buffer += "<"; - buffer += unknown.Value(); - buffer += ">"; - DoLineBreak(); - return true; -} - diff --git a/WDL/tinyxml/tinyxml.h b/WDL/tinyxml/tinyxml.h deleted file mode 100644 index e08f7cca..00000000 --- a/WDL/tinyxml/tinyxml.h +++ /dev/null @@ -1,1802 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - - -#ifndef TINYXML_INCLUDED -#define TINYXML_INCLUDED - -#ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4530 ) -#pragma warning( disable : 4786 ) -#endif - -#include -#include -#include -#include -#include - -// Help out windows: -#if defined( _DEBUG ) && !defined( DEBUG ) -#define DEBUG -#endif - -#ifdef TIXML_USE_STL - #include - #include - #include - #define TIXML_STRING std::string -#else - #include "tinystr.h" - #define TIXML_STRING TiXmlString -#endif - -// Deprecated library function hell. Compilers want to use the -// new safe versions. This probably doesn't fully address the problem, -// but it gets closer. There are too many compilers for me to fully -// test. If you get compilation troubles, undefine TIXML_SAFE -#define TIXML_SAFE - -#ifdef TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s - #define TIXML_SNSCANF _snscanf_s - #define TIXML_SSCANF sscanf_s - #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SNSCANF _snscanf - #define TIXML_SSCANF sscanf - #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_SNSCANF snscanf - #define TIXML_SSCANF sscanf - #else - #define TIXML_SSCANF sscanf - #endif -#endif - -class TiXmlDocument; -class TiXmlElement; -class TiXmlComment; -class TiXmlUnknown; -class TiXmlAttribute; -class TiXmlText; -class TiXmlDeclaration; -class TiXmlParsingData; - -const int TIXML_MAJOR_VERSION = 2; -const int TIXML_MINOR_VERSION = 5; -const int TIXML_PATCH_VERSION = 3; - -/* Internal structure for tracking location of items - in the XML file. -*/ -struct TiXmlCursor -{ - TiXmlCursor() { Clear(); } - void Clear() { row = col = -1; } - - int row; // 0 based. - int col; // 0 based. -}; - - -/** - If you call the Accept() method, it requires being passed a TiXmlVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves - are simple called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its sibilings will be Visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. - - You should never change the document from a callback. - - @sa TiXmlNode::Accept() -*/ -class TiXmlVisitor -{ -public: - virtual ~TiXmlVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } - /// Visit a document. - virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } - - /// Visit an element. - virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } - /// Visit an element. - virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } - - /// Visit a declaration - virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } - /// Visit a text node - virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } - /// Visit a comment node - virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } - /// Visit an unknow node - virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } -}; - -// Only used by Attribute::Query functions -enum -{ - TIXML_SUCCESS, - TIXML_NO_ATTRIBUTE, - TIXML_WRONG_TYPE -}; - - -// Used by the parsing routines. -enum TiXmlEncoding -{ - TIXML_ENCODING_UNKNOWN, - TIXML_ENCODING_UTF8, - TIXML_ENCODING_LEGACY -}; - -const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; - -/** TiXmlBase is a base class for every class in TinyXml. - It does little except to establish that TinyXml classes - can be printed and provide some utility functions. - - In XML, the document and elements can contain - other elements and other types of nodes. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - A Decleration contains: Attributes (not on tree) - @endverbatim -*/ -class TiXmlBase -{ - friend class TiXmlNode; - friend class TiXmlElement; - friend class TiXmlDocument; - -public: - TiXmlBase() : userData(0) {} - virtual ~TiXmlBase() {} - - /** All TinyXml classes can print themselves to a filestream - or the string class (TiXmlString in non-STL mode, std::string - in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert - tabs and newlines. - - (For an unformatted stream, use the << operator.) - */ - virtual void Print( FILE* cfile, int depth ) const = 0; - - /** The world does not agree on whether white space should be kept or - not. In order to make everyone happy, these global, static functions - are provided to set whether or not TinyXml will condense all white space - into a single space or not. The default is to condense. Note changing this - value is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } - - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } - - /** Return the position, in the original source file, of this node or attribute. - The row and column are 1-based. (That is the first row and first column is - 1,1). If the returns values are 0 or less, then the parser does not have - a row and column value. - - Generally, the row and column value will be set when the TiXmlDocument::Load(), - TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set - when the DOM was created from operator>>. - - The values reflect the initial load. Once the DOM is modified programmatically - (by adding or changing nodes and attributes) the new values will NOT update to - reflect changes in the document. - - There is a minor performance cost to computing the row and column. Computation - can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. - - @sa TiXmlDocument::SetTabSize() - */ - int Row() const { return location.row + 1; } - int Column() const { return location.col + 1; } ///< See Row() - - void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. - void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. - const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. - - // Table that returs, for a given lead byte, the total number of bytes - // in the UTF-8 sequence. - static const int utf8ByteTable[256]; - - virtual const char* Parse( const char* p, - TiXmlParsingData* data, - TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - - /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, - or they will be transformed into entities! - */ - static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); - - enum - { - TIXML_NO_ERROR = 0, - TIXML_ERROR, - TIXML_ERROR_OPENING_FILE, - TIXML_ERROR_OUT_OF_MEMORY, - TIXML_ERROR_PARSING_ELEMENT, - TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, - TIXML_ERROR_READING_ELEMENT_VALUE, - TIXML_ERROR_READING_ATTRIBUTES, - TIXML_ERROR_PARSING_EMPTY, - TIXML_ERROR_READING_END_TAG, - TIXML_ERROR_PARSING_UNKNOWN, - TIXML_ERROR_PARSING_COMMENT, - TIXML_ERROR_PARSING_DECLARATION, - TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, - TIXML_ERROR_PARSING_CDATA, - TIXML_ERROR_DOCUMENT_TOP_ONLY, - - TIXML_ERROR_STRING_COUNT - }; - -protected: - - static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); - } - inline static bool IsWhiteSpace( int c ) - { - if ( c < 256 ) - return IsWhiteSpace( (char) c ); - return false; // Again, only truly correct for English/Latin...but usually works. - } - - #ifdef TIXML_USE_STL - static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); - static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); - #endif - - /* Reads an XML name into the string provided. Returns - a pointer just past the last character of the name, - or 0 if the function has an error. - */ - static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); - - /* Reads text. Returns a pointer past the given end tag. - Wickedly complex options, but it keeps the (sensitive) code in one place. - */ - static const char* ReadText( const char* in, // where to start - TIXML_STRING* text, // the string read - bool ignoreWhiteSpace, // whether to keep the white space - const char* endTag, // what ends this text - bool ignoreCase, // whether to ignore case in the end tag - TiXmlEncoding encoding ); // the current encoding - - // If an entity has been found, transform it into a character. - static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); - - // Get a character, while interpreting entities. - // The length can be from 0 to 4 bytes. - inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) - { - assert( p ); - if ( encoding == TIXML_ENCODING_UTF8 ) - { - *length = utf8ByteTable[ *((const unsigned char*)p) ]; - assert( *length >= 0 && *length < 5 ); - } - else - { - *length = 1; - } - - if ( *length == 1 ) - { - if ( *p == '&' ) - return GetEntity( p, _value, length, encoding ); - *_value = *p; - return p+1; - } - else if ( *length ) - { - //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), - // and the null terminator isn't needed - for( int i=0; p[i] && i<*length; ++i ) { - _value[i] = p[i]; - } - return p + (*length); - } - else - { - // Not valid text. - return 0; - } - } - - // Return true if the next characters in the stream are any of the endTag sequences. - // Ignore case only works for english, and should only be relied on when comparing - // to English words: StringEqual( p, "version", true ) is fine. - static bool StringEqual( const char* p, - const char* endTag, - bool ignoreCase, - TiXmlEncoding encoding ); - - static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; - - TiXmlCursor location; - - /// Field containing a generic user pointer - void* userData; - - // None of these methods are reliable for any language except English. - // Good for approximation, not great for accuracy. - static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); - static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); - inline static int ToLower( int v, TiXmlEncoding encoding ) - { - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( v < 128 ) return tolower( v ); - return v; - } - else - { - return tolower( v ); - } - } - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - -private: - TiXmlBase( const TiXmlBase& ); // not implemented. - void operator=( const TiXmlBase& base ); // not allowed. - - struct Entity - { - const char* str; - unsigned int strLength; - char chr; - }; - enum - { - NUM_ENTITY = 5, - MAX_ENTITY_LENGTH = 6 - - }; - static Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; -}; - - -/** The parent class for everything in the Document Object Model. - (Except for attributes). - Nodes have siblings, a parent, and children. A node can be - in a document, or stand on its own. The type of a TiXmlNode - can be queried, and it can be cast to its more defined type. -*/ -class TiXmlNode : public TiXmlBase -{ - friend class TiXmlDocument; - friend class TiXmlElement; - -public: - #ifdef TIXML_USE_STL - - /** An input stream operator, for every class. Tolerant of newlines and - formatting, but doesn't expect them. - */ - friend std::istream& operator >> (std::istream& in, TiXmlNode& base); - - /** An output stream operator, for every class. Note that this outputs - without any newlines or formatting, as opposed to Print(), which - includes tabs and new lines. - - The operator<< and operator>> are not completely symmetric. Writing - a node to a stream is very well defined. You'll get a nice stream - of output, without any extra whitespace or newlines. - - But reading is not as well defined. (As it always is.) If you create - a TiXmlElement (for example) and read that from an input stream, - the text needs to define an element or junk will result. This is - true of all input streams, but it's worth keeping in mind. - - A TiXmlDocument will read nodes until it reads a root element, and - all the children of that root element. - */ - friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); - - /// Appends the XML node or attribute to a std::string. - friend std::string& operator<< (std::string& out, const TiXmlNode& base ); - - #endif - - /** The types of XML nodes supported by TinyXml. (All the - unsupported types are picked up by UNKNOWN.) - */ - enum NodeType - { - DOCUMENT, - ELEMENT, - COMMENT, - UNKNOWN, - TEXT, - DECLARATION, - TYPECOUNT - }; - - virtual ~TiXmlNode(); - - /** The meaning of 'value' changes for the specific type of - TiXmlNode. - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - - The subclasses will wrap this function. - */ - const char *Value() const { return value.c_str (); } - - #ifdef TIXML_USE_STL - /** Return Value() as a std::string. If you only use STL, - this is more efficient than calling Value(). - Only available in STL mode. - */ - const std::string& ValueStr() const { return value; } - #endif - - const TIXML_STRING& ValueTStr() const { return value; } - - /** Changes the value of the node. Defined as: - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - void SetValue(const char * _value) { value = _value;} - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Delete all the children of this node. Does not affect 'this'. - void Clear(); - - /// One step up the DOM. - TiXmlNode* Parent() { return parent; } - const TiXmlNode* Parent() const { return parent; } - - const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. - TiXmlNode* FirstChild() { return firstChild; } - const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. - /// The first child of this node with the matching 'value'. Will be null if none found. - TiXmlNode* FirstChild( const char * _value ) { - // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) - // call the method, cast the return back to non-const. - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); - } - const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. - TiXmlNode* LastChild() { return lastChild; } - - const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. - TiXmlNode* LastChild( const char * _value ) { - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. - #endif - - /** An alternate way to walk the children of a node. - One way to iterate over nodes is: - @verbatim - for( child = parent->FirstChild(); child; child = child->NextSibling() ) - @endverbatim - - IterateChildren does the same thing with the syntax: - @verbatim - child = 0; - while( child = parent->IterateChildren( child ) ) - @endverbatim - - IterateChildren takes the previous child as input and finds - the next one. If the previous child is null, it returns the - first. IterateChildren will return null when done. - */ - const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); - } - - /// This flavor of IterateChildren searches for children with a particular 'value' - const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - #endif - - /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); - - - /** Add a new node related to this. Adds a child past the LastChild. - - NOTE: the node to be added is passed by pointer, and will be - henceforth owned (and deleted) by tinyXml. This method is efficient - and avoids an extra copy, but should be used with care as it - uses a different memory model than the other insert functions. - - @sa InsertEndChild - */ - TiXmlNode* LinkEndChild( TiXmlNode* addThis ); - - /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); - - /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); - - /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); - - /// Delete a child of this node. - bool RemoveChild( TiXmlNode* removeThis ); - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling() const { return prev; } - TiXmlNode* PreviousSibling() { return prev; } - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling( const char * ) const; - TiXmlNode* PreviousSibling( const char *_prev ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Navigate to a sibling node. - const TiXmlNode* NextSibling() const { return next; } - TiXmlNode* NextSibling() { return next; } - - /// Navigate to a sibling node with the given 'value'. - const TiXmlNode* NextSibling( const char * ) const; - TiXmlNode* NextSibling( const char* _next ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement() const; - TiXmlElement* NextSiblingElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement( const char * ) const; - TiXmlElement* NextSiblingElement( const char *_next ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement() const; - TiXmlElement* FirstChildElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); - } - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement( const char * _value ) const; - TiXmlElement* FirstChildElement( const char * _value ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /** Query the type (as an enumerated value, above) of this node. - The possible types are: DOCUMENT, ELEMENT, COMMENT, - UNKNOWN, TEXT, and DECLARATION. - */ - int Type() const { return type; } - - /** Return a pointer to the Document this node lives in. - Returns null if not in a document. - */ - const TiXmlDocument* GetDocument() const; - TiXmlDocument* GetDocument() { - return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); - } - - /// Returns true if this node has no children. - bool NoChildren() const { return !firstChild; } - - virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. - */ - virtual TiXmlNode* Clone() const = 0; - - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( TiXmlVisitor* visitor ) const = 0; - -protected: - TiXmlNode( NodeType _type ); - - // Copy to the allocated object. Shared functionality between Clone, Copy constructor, - // and the assignment operator. - void CopyTo( TiXmlNode* target ) const; - - #ifdef TIXML_USE_STL - // The real work of the input operator. - virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; - #endif - - // Figure out what is at *p, and parse it. Returns null if it is not an xml node. - TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); - - TiXmlNode* parent; - NodeType type; - - TiXmlNode* firstChild; - TiXmlNode* lastChild; - - TIXML_STRING value; - - TiXmlNode* prev; - TiXmlNode* next; - -private: - TiXmlNode( const TiXmlNode& ); // not implemented. - void operator=( const TiXmlNode& base ); // not allowed. -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not TiXmlNodes, since they are not - part of the tinyXML document object model. There are other - suggested ways to look at this problem. -*/ -class TiXmlAttribute : public TiXmlBase -{ - friend class TiXmlAttributeSet; - -public: - /// Construct an empty attribute. - TiXmlAttribute() : TiXmlBase() - { - document = 0; - prev = next = 0; - } - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlAttribute( const std::string& _name, const std::string& _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - #endif - - /// Construct an attribute with a name and value. - TiXmlAttribute( const char * _name, const char * _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - - const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. - const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. - #ifdef TIXML_USE_STL - const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. - #endif - int IntValue() const; ///< Return the value of this attribute, converted to an integer. - double DoubleValue() const; ///< Return the value of this attribute, converted to a double. - - // Get the tinyxml string representation - const TIXML_STRING& NameTStr() const { return name; } - - /** QueryIntValue examines the value string. It is an alternative to the - IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. - - A specialized but useful call. Note that for success it returns 0, - which is the opposite of almost all other TinyXml calls. - */ - int QueryIntValue( int* _value ) const; - /// QueryDoubleValue examines the value string. See QueryIntValue(). - int QueryDoubleValue( double* _value ) const; - - void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. - void SetValue( const char* _value ) { value = _value; } ///< Set the value. - - void SetIntValue( int _value ); ///< Set the value from an integer. - void SetDoubleValue( double _value ); ///< Set the value from a double. - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetName( const std::string& _name ) { name = _name; } - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Get the next sibling attribute in the DOM. Returns null at end. - const TiXmlAttribute* Next() const; - TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); - } - - /// Get the previous sibling attribute in the DOM. Returns null at beginning. - const TiXmlAttribute* Previous() const; - TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); - } - - bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } - bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } - bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } - - /* Attribute parsing starts: first letter of the name - returns: the next char after the value end quote - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - - // [internal use] - // Set the document pointer so the attribute can report errors. - void SetDocument( TiXmlDocument* doc ) { document = doc; } - -private: - TiXmlAttribute( const TiXmlAttribute& ); // not implemented. - void operator=( const TiXmlAttribute& base ); // not allowed. - - TiXmlDocument* document; // A pointer back to a document, for error reporting. - TIXML_STRING name; - TIXML_STRING value; - TiXmlAttribute* prev; - TiXmlAttribute* next; -}; - - -/* A class used to manage a group of attributes. - It is only used internally, both by the ELEMENT and the DECLARATION. - - The set can be changed transparent to the Element and Declaration - classes that use it, but NOT transparent to the Attribute - which has to implement a next() and previous() method. Which makes - it a bit problematic and prevents the use of STL. - - This version is implemented with circular lists because: - - I like circular lists - - it demonstrates some independence from the (typical) doubly linked list. -*/ -class TiXmlAttributeSet -{ -public: - TiXmlAttributeSet(); - ~TiXmlAttributeSet(); - - void Add( TiXmlAttribute* attribute ); - void Remove( TiXmlAttribute* attribute ); - - const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - - const TiXmlAttribute* Find( const char* _name ) const; - TiXmlAttribute* Find( const char* _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } - #ifdef TIXML_USE_STL - const TiXmlAttribute* Find( const std::string& _name ) const; - TiXmlAttribute* Find( const std::string& _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } - - #endif - -private: - //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), - //*ME: this class must be also use a hidden/disabled copy-constructor !!! - TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed - void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) - - TiXmlAttribute sentinel; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TiXmlElement : public TiXmlNode -{ -public: - /// Construct an element. - TiXmlElement (const char * in_value); - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlElement( const std::string& _value ); - #endif - - TiXmlElement( const TiXmlElement& ); - - void operator=( const TiXmlElement& base ); - - virtual ~TiXmlElement(); - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - */ - const char* Attribute( const char* name ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an integer, - the integer value will be put in the return 'i', if 'i' - is non-null. - */ - const char* Attribute( const char* name, int* i ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an double, - the double value will be put in the return 'd', if 'd' - is non-null. - */ - const char* Attribute( const char* name, double* d ) const; - - /** QueryIntAttribute examines the attribute - it is an alternative to the - Attribute() method with richer error checking. - If the attribute is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. If the attribute - does not exist, then TIXML_NO_ATTRIBUTE is returned. - */ - int QueryIntAttribute( const char* name, int* _value ) const; - /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). - int QueryDoubleAttribute( const char* name, double* _value ) const; - /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). - int QueryFloatAttribute( const char* name, float* _value ) const { - double d; - int result = QueryDoubleAttribute( name, &d ); - if ( result == TIXML_SUCCESS ) { - *_value = (float)d; - } - return result; - } - - #ifdef TIXML_USE_STL - /** Template form of the attribute query which will try to read the - attribute into the specified type. Very easy, very powerful, but - be careful to make sure to call this with the correct type. - - NOTE: This method doesn't work correctly for 'string' types. - - @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE - */ - template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - - std::stringstream sstream( node->ValueStr() ); - sstream >> *outValue; - if ( !sstream.fail() ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; - } - /* - This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" - but template specialization is hard to get working cross-compiler. Leaving the bug for now. - - // The above will fail for std::string because the space character is used as a seperator. - // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string - template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - *outValue = node->ValueStr(); - return TIXML_SUCCESS; - } - */ - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char* name, const char * _value ); - - #ifdef TIXML_USE_STL - const std::string* Attribute( const std::string& name ) const; - const std::string* Attribute( const std::string& name, int* i ) const; - const std::string* Attribute( const std::string& name, double* d ) const; - int QueryIntAttribute( const std::string& name, int* _value ) const; - int QueryDoubleAttribute( const std::string& name, double* _value ) const; - - /// STL std::string form. - void SetAttribute( const std::string& name, const std::string& _value ); - ///< STL std::string form. - void SetAttribute( const std::string& name, int _value ); - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char * name, int value ); - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetDoubleAttribute( const char * name, double value ); - - /** Deletes an attribute with the given name. - */ - void RemoveAttribute( const char * name ); - #ifdef TIXML_USE_STL - void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. - #endif - - const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. - TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } - const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. - TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are - safe type casts on the referenced node. - */ - const char* GetText() const; - - /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; - // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: next char past '<' - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - - void CopyTo( TiXmlElement* target ) const; - void ClearThis(); // like clear, but initializes 'this' object as well - - // Used to be public [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - /* [internal use] - Reads the "value" of the element -- another element, or text. - This should terminate with the current end tag. - */ - const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - -private: - - TiXmlAttributeSet attributeSet; -}; - - -/** An XML comment. -*/ -class TiXmlComment : public TiXmlNode -{ -public: - /// Constructs an empty comment. - TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} - /// Construct a comment from text. - TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { - SetValue( _value ); - } - TiXmlComment( const TiXmlComment& ); - void operator=( const TiXmlComment& base ); - - virtual ~TiXmlComment() {} - - /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; - // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: at the ! of the !-- - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlComment* target ) const; - - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif -// virtual void StreamOut( TIXML_OSTREAM * out ) const; - -private: - -}; - - -/** XML text. A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). -*/ -class TiXmlText : public TiXmlNode -{ - friend class TiXmlElement; -public: - /** Constructor for text element. By default, it is treated as - normal, encoded text. If you want it be output as a CDATA text - element, set the parameter _cdata to 'true' - */ - TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - virtual ~TiXmlText() {} - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - #endif - - TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } - void operator=( const TiXmlText& base ) { base.CopyTo( this ); } - - // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /// Queries whether this represents text using a CDATA section. - bool CDATA() const { return cdata; } - /// Turns on or off a CDATA representation of text. - void SetCDATA( bool _cdata ) { cdata = _cdata; } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; - void CopyTo( TiXmlText* target ) const; - - bool Blank() const; // returns true if all white space and new lines - // [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - bool cdata; // true if this should be input and output as a CDATA style text element -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim - - TinyXml will happily read or write files without a declaration, - however. There are 3 possible attributes to the declaration: - version, encoding, and standalone. - - Note: In this version of the code, the attributes are - handled as special cases, not generic attributes, simply - because there can only be at most 3 and they are always the same. -*/ -class TiXmlDeclaration : public TiXmlNode -{ -public: - /// Construct an empty declaration. - TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} - -#ifdef TIXML_USE_STL - /// Constructor. - TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ); -#endif - - /// Construct. - TiXmlDeclaration( const char* _version, - const char* _encoding, - const char* _standalone ); - - TiXmlDeclaration( const TiXmlDeclaration& copy ); - void operator=( const TiXmlDeclaration& copy ); - - virtual ~TiXmlDeclaration() {} - - /// Version. Will return an empty string if none was found. - const char *Version() const { return version.c_str (); } - /// Encoding. Will return an empty string if none was found. - const char *Encoding() const { return encoding.c_str (); } - /// Is this a standalone document? - const char *Standalone() const { return standalone.c_str (); } - - /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; - // Print this declaration to a FILE stream. - virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlDeclaration* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - - TIXML_STRING version; - TIXML_STRING encoding; - TIXML_STRING standalone; -}; - - -/** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into TiXmlUnknowns. -*/ -class TiXmlUnknown : public TiXmlNode -{ -public: - TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} - virtual ~TiXmlUnknown() {} - - TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } - void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } - - /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; - // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected: - void CopyTo( TiXmlUnknown* target ) const; - - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - -}; - - -/** Always the top level node. A document binds together all the - XML pieces. It can be saved, loaded, and printed to the screen. - The 'value' of a document node is the xml file name. -*/ -class TiXmlDocument : public TiXmlNode -{ -public: - /// Create an empty document, that has no name. - TiXmlDocument(); - /// Create a document with a name. The name of the document is also the filename of the xml. - TiXmlDocument( const char * documentName ); - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDocument( const std::string& documentName ); - #endif - - TiXmlDocument( const TiXmlDocument& copy ); - void operator=( const TiXmlDocument& copy ); - - virtual ~TiXmlDocument() {} - - /** Load a file using the current document value. - Returns true if successful. Will delete any existing - document data before loading. - */ - bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the current document value. Returns true if successful. - bool SaveFile() const; - /// Load a file using the given filename. Returns true if successful. - bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given filename. Returns true if successful. - bool SaveFile( const char * filename ) const; - /** Load a file using the given FILE*. Returns true if successful. Note that this method - doesn't stream - the entire object pointed at by the FILE* - will be interpreted as an XML file. TinyXML doesn't stream in XML from the current - file location. Streaming may be added in the future. - */ - bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given FILE*. Returns true if successful. - bool SaveFile( FILE* ) const; - - #ifdef TIXML_USE_STL - bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && LoadFile( f.buffer, encoding )); - return LoadFile( filename.c_str(), encoding ); - } - bool SaveFile( const std::string& filename ) const ///< STL std::string version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && SaveFile( f.buffer )); - return SaveFile( filename.c_str() ); - } - #endif - - /** Parse the given null terminated block of xml data. Passing in an encoding to this - method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml - to use that encoding, regardless of what TinyXml might otherwise try to detect. - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - - /** Get the root element -- the only top level element -- of the document. - In well formed XML, there should only be one. TinyXml is tolerant of - multiple elements at the document level. - */ - const TiXmlElement* RootElement() const { return FirstChildElement(); } - TiXmlElement* RootElement() { return FirstChildElement(); } - - /** If an error occurs, Error will be set to true. Also, - - The ErrorId() will contain the integer identifier of the error (not generally useful) - - The ErrorDesc() method will return the name of the error. (very useful) - - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ - bool Error() const { return error; } - - /// Contains a textual (english) description of the error if one occurs. - const char * ErrorDesc() const { return errorDesc.c_str (); } - - /** Generally, you probably want the error string ( ErrorDesc() ). But if you - prefer the ErrorId, this function will fetch it. - */ - int ErrorId() const { return errorId; } - - /** Returns the location (if known) of the error. The first column is column 1, - and the first row is row 1. A value of 0 means the row and column wasn't applicable - (memory errors, for example, have no row/column) or the parser lost the error. (An - error in the error reporting, in that case.) - - @sa SetTabSize, Row, Column - */ - int ErrorRow() const { return errorLocation.row+1; } - int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() - - /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) - to report the correct values for row and column. It does not change the output - or input in any way. - - By calling this method, with a tab size - greater than 0, the row and column of each node and attribute is stored - when the file is loaded. Very useful for tracking the DOM back in to - the source file. - - The tab size is required for calculating the location of nodes. If not - set, the default of 4 is used. The tabsize is set per document. Setting - the tabsize to 0 disables row/column tracking. - - Note that row and column tracking is not supported when using operator>>. - - The tab size needs to be enabled before the parse or load. Correct usage: - @verbatim - TiXmlDocument doc; - doc.SetTabSize( 8 ); - doc.Load( "myfile.xml" ); - @endverbatim - - @sa Row, Column - */ - void SetTabSize( int _tabsize ) { tabsize = _tabsize; } - - int TabSize() const { return tabsize; } - - /** If you have handled the error, it can be reset with this call. The error - state is automatically cleared if you Parse a new XML block. - */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; - } - - /** Write the document to standard out using formatted printing ("pretty print"). */ - void Print() const { Print( stdout, 0 ); } - - /* Write the document to a string using formatted printing ("pretty print"). This - will allocate a character array (new char[]) and return it as a pointer. The - calling code pust call delete[] on the return char* to avoid a memory leak. - */ - //char* PrintToMemory() const; - - /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; - // [internal use] - void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - // [internal use] - virtual TiXmlNode* Clone() const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - void CopyTo( TiXmlDocument* target ) const; - - bool error; - int errorId; - TIXML_STRING errorDesc; - int tabsize; - TiXmlCursor errorLocation; - bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. -}; - - -/** - A TiXmlHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - TiXmlElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - TiXmlElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - TiXmlHandle handleCopy = handle; - @endverbatim - - What they should not be used for is iteration: - - @verbatim - int i=0; - while ( true ) - { - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); - if ( !child ) - break; - // do something - ++i; - } - @endverbatim - - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs - to. Instead, prefer: - - @verbatim - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); - - for( child; child; child=child->NextSiblingElement() ) - { - // do something - } - @endverbatim -*/ -class TiXmlHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } - /// Copy constructor - TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } - TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } - - /// Return a handle to the first child node. - TiXmlHandle FirstChild() const; - /// Return a handle to the first child node with the given name. - TiXmlHandle FirstChild( const char * value ) const; - /// Return a handle to the first child element. - TiXmlHandle FirstChildElement() const; - /// Return a handle to the first child element with the given name. - TiXmlHandle FirstChildElement( const char * value ) const; - - /** Return a handle to the "index" child with the given name. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( int index ) const; - - #ifdef TIXML_USE_STL - TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } - TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } - - TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } - TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } - #endif - - /** Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* ToNode() const { return node; } - /** Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } - /** Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } - /** Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - - /** @deprecated use ToNode. - Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. - Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* Element() const { return ToElement(); } - /** @deprecated use ToText() - Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* Text() const { return ToText(); } - /** @deprecated use ToUnknown() - Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* Unknown() const { return ToUnknown(); } - -private: - TiXmlNode* node; -}; - - -/** Print to memory functionality. The TiXmlPrinter is useful when you need to: - - -# Print to memory (especially in non-STL mode) - -# Control formatting (line endings, etc.) - - When constructed, the TiXmlPrinter is in its default "pretty printing" mode. - Before calling Accept() you can call methods to control the printing - of the XML document. After TiXmlNode::Accept() is called, the printed document can - be accessed via the CStr(), Str(), and Size() methods. - - TiXmlPrinter uses the Visitor API. - @verbatim - TiXmlPrinter printer; - printer.SetIndent( "\t" ); - - doc.Accept( &printer ); - fprintf( stdout, "%s", printer.CStr() ); - @endverbatim -*/ -class TiXmlPrinter : public TiXmlVisitor -{ -public: - TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), - buffer(), indent( " " ), lineBreak( "\n" ) {} - - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); - - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); - - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); - - /** Set the indent characters for printing. By default 4 spaces - but tab (\t) is also useful, or null/empty string for no indentation. - */ - void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } - /// Query the indention string. - const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). - Some operating systems prefer other characters, or can be - set to the null/empty string for no indenation. - */ - void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } - /// Query the current line breaking string. - const char* LineBreak() { return lineBreak.c_str(); } - - /** Switch over to "stream printing" which is the most dense formatting without - linebreaks. Common when the XML is needed for network transmission. - */ - void SetStreamPrinting() { indent = ""; - lineBreak = ""; - } - /// Return the result. - const char* CStr() { return buffer.c_str(); } - /// Return the length of the result string. - size_t Size() { return buffer.size(); } - - #ifdef TIXML_USE_STL - /// Return the result. - const std::string& Str() { return buffer; } - #endif - -private: - void DoIndent() { - for( int i=0; i -#include - -#include "tinyxml.h" - -//#define DEBUG_PARSER -#if defined( DEBUG_PARSER ) -# if defined( DEBUG ) && defined( _MSC_VER ) -# include -# define TIXML_LOG OutputDebugString -# else -# define TIXML_LOG printf -# endif -#endif - -// Note tha "PutString" hardcodes the same list. This -// is less flexible than it appears. Changing the entries -// or order will break putstring. -TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -{ - { "&", 5, '&' }, - { "<", 4, '<' }, - { ">", 4, '>' }, - { """, 6, '\"' }, - { "'", 6, '\'' } -}; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// Including the basic of this table, which determines the #bytes in the -// sequence from the lead byte. 1 placed for invalid sequences -- -// although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: -// ef bb bf (Microsoft "lead bytes") -// ef bf be -// ef bf bf - -const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -const int TiXmlBase::utf8ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; - - -void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) - *length = 1; - else if ( input < 0x800 ) - *length = 2; - else if ( input < 0x10000 ) - *length = 3; - else if ( input < 0x200000 ) - *length = 4; - else - { *length = 0; return; } // This code won't covert this correctly anyway. - - output += *length; - - // Scary scary fall throughs. - switch (*length) - { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - } -} - - -/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalpha( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalpha( anyByte ); -// } -} - - -/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalnum( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalnum( anyByte ); -// } -} - - -class TiXmlParsingData -{ - friend class TiXmlDocument; - public: - void Stamp( const char* now, TiXmlEncoding encoding ); - - const TiXmlCursor& Cursor() { return cursor; } - - private: - // Only used by the document! - TiXmlParsingData( const char* start, int _tabsize, int row, int col ) - { - assert( start ); - stamp = start; - tabsize = _tabsize; - cursor.row = row; - cursor.col = col; - } - - TiXmlCursor cursor; - const char* stamp; - int tabsize; -}; - - -void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -{ - assert( now ); - - // Do nothing if the tabsize is 0. - if ( tabsize < 1 ) - { - return; - } - - // Get the current row, column. - int row = cursor.row; - int col = cursor.col; - const char* p = stamp; - assert( p ); - - while ( p < now ) - { - // Treat p as unsigned, so we have a happy compiler. - const unsigned char* pU = (const unsigned char*)p; - - // Code contributed by Fletcher Dunn: (modified by lee) - switch (*pU) { - case 0: - // We *should* never get here, but in case we do, don't - // advance past the terminating null character, ever - return; - - case '\r': - // bump down to the next line - ++row; - col = 0; - // Eat the character - ++p; - - // Check for \r\n sequence, and treat this as a single character - if (*p == '\n') { - ++p; - } - break; - - case '\n': - // bump down to the next line - ++row; - col = 0; - - // Eat the character - ++p; - - // Check for \n\r sequence, and treat this as a single - // character. (Yes, this bizarre thing does occur still - // on some arcane platforms...) - if (*p == '\r') { - ++p; - } - break; - - case '\t': - // Eat the character - ++p; - - // Skip to next tab stop - col = (col / tabsize + 1) * tabsize; - break; - - case TIXML_UTF_LEAD_0: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( *(p+1) && *(p+2) ) - { - // In these cases, don't advance the column. These are - // 0-width spaces. - if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; - else - { p +=3; ++col; } // A normal character. - } - } - else - { - ++p; - ++col; - } - break; - - default: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // Eat the 1 to 4 byte utf8 character. - int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; - if ( step == 0 ) - step = 1; // Error case from bad encoding, but handle gracefully. - p += step; - - // Just advance one column, of course. - ++col; - } - else - { - ++p; - ++col; - } - break; - } - } - cursor.row = row; - cursor.col = col; - assert( cursor.row >= -1 ); - assert( cursor.col >= -1 ); - stamp = p; - assert( stamp ); -} - - -const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -{ - if ( !p || !*p ) - { - return 0; - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - while ( *p ) - { - const unsigned char* pU = (const unsigned char*)p; - - // Skip the stupid Microsoft UTF-8 Byte order marks - if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 - && *(pU+2)==TIXML_UTF_LEAD_2 ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbeU ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbfU ) - { - p += 3; - continue; - } - - if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. - ++p; - else - break; - } - } - else - { - while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) - ++p; - } - - return p; -} - -#ifdef TIXML_USE_STL -/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) -{ - for( ;; ) - { - if ( !in->good() ) return false; - - int c = in->peek(); - // At this scope, we can't get to a document. So fail silently. - if ( !IsWhiteSpace( c ) || c <= 0 ) - return true; - - *tag += (char) in->get(); - } -} - -/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) -{ - //assert( character > 0 && character < 128 ); // else it won't work in utf-8 - while ( in->good() ) - { - int c = in->peek(); - if ( c == character ) - return true; - if ( c <= 0 ) // Silent failure: can't get document at this scope - return false; - - in->get(); - *tag += (char) c; - } - return false; -} -#endif - -// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The -// "assign" optimization removes over 10% of the execution time. -// -const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -{ - // Oddly, not supported on some comilers, - //name->clear(); - // So use this: - *name = ""; - assert( p ); - - // Names start with letters or underscores. - // Of course, in unicode, tinyxml has no idea what a letter *is*. The - // algorithm is generous. - // - // After that, they can be letters, underscores, numbers, - // hyphens, or colons. (Colons are valid ony for namespaces, - // but tinyxml can't tell namespaces from names.) - if ( p && *p - && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) - { - const char* start = p; - while( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) - || *p == '_' - || *p == '-' - || *p == '.' - || *p == ':' ) ) - { - //(*name) += *p; // expensive - ++p; - } - if ( p-start > 0 ) { - name->assign( start, p-start ); - } - return p; - } - return 0; -} - -const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -{ - // Presume an entity, and pull it out. - TIXML_STRING ent; - int i; - *length = 0; - - if ( *(p+1) && *(p+1) == '#' && *(p+2) ) - { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) - { - // Hexadecimal. - if ( !*(p+3) ) return 0; - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != 'x' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else if ( *q >= 'a' && *q <= 'f' ) - ucs += mult * (*q - 'a' + 10); - else if ( *q >= 'A' && *q <= 'F' ) - ucs += mult * (*q - 'A' + 10 ); - else - return 0; - mult *= 16; - --q; - } - } - else - { - // Decimal. - if ( !*(p+2) ) return 0; - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != '#' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else - return 0; - mult *= 10; - --q; - } - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - } - else - { - *value = (char)ucs; - *length = 1; - } - return p + delta + 1; - } - - // Now try to match it. - for( i=0; iappend( cArr, len ); - } - } - else - { - bool whitespace = false; - - // Remove leading white space: - p = SkipWhiteSpace( p, encoding ); - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) ) - { - if ( *p == '\r' || *p == '\n' ) - { - whitespace = true; - ++p; - } - else if ( IsWhiteSpace( *p ) ) - { - whitespace = true; - ++p; - } - else - { - // If we've found whitespace, add it before the - // new character. Any whitespace just becomes a space. - if ( whitespace ) - { - (*text) += ' '; - whitespace = false; - } - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - if ( len == 1 ) - (*text) += cArr[0]; // more efficient - else - text->append( cArr, len ); - } - } - } - if ( p ) - p += strlen( endTag ); - return p; -} - -#ifdef TIXML_USE_STL - -void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - // The basic issue with a document is that we don't know what we're - // streaming. Read something presumed to be a tag (and hope), then - // identify it, and call the appropriate stream method on the tag. - // - // This "pre-streaming" will never read the closing ">" so the - // sub-tag can orient itself. - - if ( !StreamTo( in, '<', tag ) ) - { - SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - while ( in->good() ) - { - int tagIndex = (int) tag->length(); - while ( in->good() && in->peek() != '>' ) - { - int c = in->get(); - if ( c <= 0 ) - { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - break; - } - (*tag) += (char) c; - } - - if ( in->good() ) - { - // We now have something we presume to be a node of - // some sort. Identify it, and call the node to - // continue streaming. - TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); - - if ( node ) - { - node->StreamIn( in, tag ); - bool isElement = node->ToElement() != 0; - delete node; - node = 0; - - // If this is the root element, we're done. Parsing will be - // done by the >> operator. - if ( isElement ) - { - return; - } - } - else - { - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - } - } - // We should have returned sooner. - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -} - -#endif - -const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -{ - ClearError(); - - // Parse away, at the document level. Since a document - // contains nothing but other tags, most of what happens - // here is skipping white space. - if ( !p || !*p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - // Note that, for a document, this needs to come - // before the while space skip, so that parsing - // starts from the pointer we are given. - location.Clear(); - if ( prevData ) - { - location.row = prevData->cursor.row; - location.col = prevData->cursor.col; - } - else - { - location.row = 0; - location.col = 0; - } - TiXmlParsingData data( p, TabSize(), location.row, location.col ); - location = data.Cursor(); - - if ( encoding == TIXML_ENCODING_UNKNOWN ) - { - // Check for the Microsoft UTF-8 lead bytes. - const unsigned char* pU = (const unsigned char*)p; - if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 - && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 - && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) - { - encoding = TIXML_ENCODING_UTF8; - useMicrosoftBOM = true; - } - } - - p = SkipWhiteSpace( p, encoding ); - if ( !p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - while ( p && *p ) - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, &data, encoding ); - LinkEndChild( node ); - } - else - { - break; - } - - // Did we get encoding info? - if ( encoding == TIXML_ENCODING_UNKNOWN - && node->ToDeclaration() ) - { - TiXmlDeclaration* dec = node->ToDeclaration(); - const char* enc = dec->Encoding(); - assert( enc ); - - if ( *enc == 0 ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else - encoding = TIXML_ENCODING_LEGACY; - } - - p = SkipWhiteSpace( p, encoding ); - } - - // Was this empty? - if ( !firstChild ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); - return 0; - } - - // All is well. - return p; -} - -void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - // The first error in a chain is more accurate - don't set again! - if ( error ) - return; - - assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); - error = true; - errorId = err; - errorDesc = errorString[ errorId ]; - - errorLocation.Clear(); - if ( pError && data ) - { - data->Stamp( pError, encoding ); - errorLocation = data->Cursor(); - } -} - - -TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -{ - TiXmlNode* returnNode = 0; - - p = SkipWhiteSpace( p, encoding ); - if( !p || !*p || *p != '<' ) - { - return 0; - } - - TiXmlDocument* doc = GetDocument(); - p = SkipWhiteSpace( p, encoding ); - - if ( !p || !*p ) - { - return 0; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: "; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // [ 1475201 ] TinyXML parses entities in comments - // Oops - ReadText doesn't work, because we don't want to parse the entities. - // p = ReadText( p, &value, false, endTag, false, encoding ); - // - // from the XML spec: - /* - [Definition: Comments may appear anywhere in a document outside other markup; in addition, - they may appear within the document type declaration at places allowed by the grammar. - They are not part of the document's character data; an XML processor MAY, but need not, - make it possible for an application to retrieve the text of comments. For compatibility, - the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity - references MUST NOT be recognized within comments. - - An example of a comment: - - - */ - - value = ""; - // Keep all the white space. - while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) - { - value.append( p, 1 ); - ++p; - } - if ( p ) - p += strlen( endTag ); - - return p; -} - - -const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) return 0; - -// int tabsize = 4; -// if ( document ) -// tabsize = document->TabSize(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - // Read the name, the '=' and the value. - const char* pErr = p; - p = ReadName( p, &name, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '=' ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - ++p; // skip '=' - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - const char* end; - const char SINGLE_QUOTE = '\''; - const char DOUBLE_QUOTE = '\"'; - - if ( *p == SINGLE_QUOTE ) - { - ++p; - end = "\'"; // single quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else if ( *p == DOUBLE_QUOTE ) - { - ++p; - end = "\""; // double quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else - { - // All attribute values should be in single or double quotes. - // But this is such a common error that the parser will try - // its best, even without them. - value = ""; - while ( p && *p // existence - && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace - && *p != '/' && *p != '>' ) // tag end - { - if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { - // [ 1451649 ] Attribute values with trailing quotes not handled correctly - // We did not have an opening quote but seem to have a - // closing one. Give up and throw an error. - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - value += *p; - ++p; - } - } - return p; -} - -#ifdef TIXML_USE_STL -void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->peek(); - if ( !cdata && (c == '<' ) ) - { - return; - } - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - in->get(); // "commits" the peek made above - - if ( cdata && c == '>' && tag->size() >= 3 ) { - size_t len = tag->size(); - if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { - // terminator of cdata. - return; - } - } - } -} -#endif - -const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - value = ""; - TiXmlDocument* document = GetDocument(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - const char* const startTag = ""; - - if ( cdata || StringEqual( p, startTag, false, encoding ) ) - { - cdata = true; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // Keep all the white space, ignore the encoding, etc. - while ( p && *p - && !StringEqual( p, endTag, false, encoding ) - ) - { - value += *p; - ++p; - } - - TIXML_STRING dummy; - p = ReadText( p, &dummy, false, endTag, false, encoding ); - return p; - } - else - { - bool ignoreWhite = true; - - const char* end = "<"; - p = ReadText( p, &value, ignoreWhite, end, false, encoding ); - if ( p ) - return p-1; // don't truncate the '<' - return 0; - } -} - -#ifdef TIXML_USE_STL -void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } -} -#endif - -const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -{ - p = SkipWhiteSpace( p, _encoding ); - // Find the beginning, find the end, and look for - // the stuff in-between. - TiXmlDocument* document = GetDocument(); - if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); - return 0; - } - if ( data ) - { - data->Stamp( p, _encoding ); - location = data->Cursor(); - } - p += 5; - - version = ""; - encoding = ""; - standalone = ""; - - while ( p && *p ) - { - if ( *p == '>' ) - { - ++p; - return p; - } - - p = SkipWhiteSpace( p, _encoding ); - if ( StringEqual( p, "version", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - version = attrib.Value(); - } - else if ( StringEqual( p, "encoding", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - encoding = attrib.Value(); - } - else if ( StringEqual( p, "standalone", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - standalone = attrib.Value(); - } - else - { - // Read over whatever it is. - while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) - ++p; - } - } - return 0; -} - -bool TiXmlText::Blank() const -{ - for ( unsigned i=0; i=buffer.GetSize()) bufidx = 0; - - return output; - } - void Reset() { memset(buffer.Get(),0,buffer.GetSize()*sizeof(double)); } - void setfeedback(double val) { feedback=val; } - -private: - double feedback; - WDL_TypedBuf buffer; - int bufidx; - int __pad; - -} WDL_FIXALIGN; - - -class WDL_ReverbComb -{ -public: - WDL_ReverbComb() { feedback=0.5; damp=0.5; filterstore=0; setsize(1); } - ~WDL_ReverbComb() { } - - void setsize(int size) - { - if (size<1)size=1; - if (buffer.GetSize()!=size) - { - bufidx=0; - buffer.Resize(size); - Reset(); - } - } - - double process(double inp) - { - double *bptr=buffer.Get()+bufidx; - double output = *bptr; - filterstore = denormal_filter_double((output*(1-damp)) + (filterstore*damp)); - - *bptr = inp + (filterstore*feedback); - - if(++bufidx>=buffer.GetSize()) bufidx = 0; - - return output; - } - void Reset() { memset(buffer.Get(),0,buffer.GetSize()*sizeof(double)); } - void setdamp(double val) { damp=val; } - void setfeedback(double val) { feedback=val; } - -private: - - double feedback; - double filterstore; - double damp; - WDL_TypedBuf buffer; - int bufidx; - int __pad; -} WDL_FIXALIGN; - - // these represent lengths in samples at 44.1khz but are scaled accordingly -const int wdl_verb__stereospread=23; -const short wdl_verb__combtunings[]={1116,1188,1277,1356,1422,1491,1557,1617,1685,1748}; -const short wdl_verb__allpasstunings[]={556,441,341,225,180,153}; - - -class WDL_ReverbEngine -{ -public: - WDL_ReverbEngine() - { - m_srate=44100.0; - m_roomsize=0.5; - m_damp=0.5; - SetWidth(1.0); - Reset(false); - } - ~WDL_ReverbEngine() - { - } - void SetSampleRate(double srate) - { - if (m_srate!=srate) - { - m_srate=srate; - Reset(true); - } - } - - void ProcessSampleBlock(double *spl0, double *spl1, double *outp0, double *outp1, int ns) - { - int x; - memset(outp0,0,ns*sizeof(double)); - memset(outp1,0,ns*sizeof(double)); - - for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x += 2) - { - int i=ns; - double *p0=outp0,*p1=outp1,*i0=spl0,*i1=spl1; - while (i--) - { - double a=*i0++,b=*i1++; - *p0+=m_combs[x][0].process(a); - *p1+=m_combs[x][1].process(b); - *p0+++=m_combs[x+1][0].process(a); - *p1+++=m_combs[x+1][1].process(b); - } - } - for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0])-2; x += 2) - { - int i=ns; - double *p0=outp0,*p1=outp1; - while (i--) - { - double tmp=m_allpasses[x][0].process(*p0); - double tmp2=m_allpasses[x][1].process(*p1); - *p0++=m_allpasses[x+1][0].process(tmp); - *p1++=m_allpasses[x+1][1].process(tmp2); - } - } - int i=ns; - double *p0=outp0,*p1=outp1; - while (i--) - { - double a=m_allpasses[x+1][0].process(m_allpasses[x][0].process(*p0))*0.015; - double b=m_allpasses[x+1][1].process(m_allpasses[x][1].process(*p1))*0.015; - - if (m_wid<0) - { - double m=-m_wid; - *p0 = b*m + a*(1.0-m); - *p1 = a*m + b*(1.0-m); - } - else - { - double m=m_wid; - *p0 = a*m + b*(1.0-m); - *p1 = b*m + a*(1.0-m); - } - p0++; - p1++; - } - - } - - void ProcessSample(double *spl0, double *spl1) - { - int x; - double in0=*spl0 * 0.015; - double in1=*spl1 * 0.015; - - double out0=0.0; - double out1=0.0; - for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x ++) - { - out0+=m_combs[x][0].process(in0); - out1+=m_combs[x][1].process(in1); - } - for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0]); x ++) - { - out0=m_allpasses[x][0].process(out0); - out1=m_allpasses[x][1].process(out1); - } - - if (m_wid<0) - { - double m=-m_wid; - *spl0 = out1*m + out0*(1.0-m); - *spl1 = out0*m + out1*(1.0-m); - } - else - { - double m=m_wid; - *spl0 = out0*m + out1*(1.0-m); - *spl1 = out1*m + out0*(1.0-m); - } - } - - void Reset(bool doclear=false) // call this after changing roomsize or dampening - { - int x; - double sc=m_srate / 44100.0; - for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0]); x ++) - { - m_allpasses[x][0].setsize((int) (wdl_verb__allpasstunings[x] * sc)); - m_allpasses[x][1].setsize((int) ((wdl_verb__allpasstunings[x]+wdl_verb__stereospread) * sc)); - m_allpasses[x][0].setfeedback(0.5); - m_allpasses[x][1].setfeedback(0.5); - if (doclear) - { - m_allpasses[x][0].Reset(); - m_allpasses[x][1].Reset(); - } - } - for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x ++) - { - m_combs[x][0].setsize((int) (wdl_verb__combtunings[x] * sc)); - m_combs[x][1].setsize((int) ((wdl_verb__combtunings[x]+wdl_verb__stereospread) * sc)); - m_combs[x][0].setfeedback(m_roomsize); - m_combs[x][1].setfeedback(m_roomsize); - m_combs[x][0].setdamp(m_damp*0.4); - m_combs[x][1].setdamp(m_damp*0.4); - if (doclear) - { - m_combs[x][0].Reset(); - m_combs[x][1].Reset(); - } - } - - } - - void SetRoomSize(double sz) { m_roomsize=sz;; } // 0.3..0.99 or so - void SetDampening(double dmp) { m_damp=dmp; } // 0..1 - void SetWidth(double wid) - { - if (wid<-1) wid=-1; - else if (wid>1) wid=1; - wid*=0.5; - if (wid>=0.0) wid+=0.5; - else wid-=0.5; - m_wid=wid; - } // -1..1 - -private: - double m_wid; - double m_roomsize; - double m_damp; - double m_srate; - WDL_ReverbAllpass m_allpasses[sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0])][2]; - WDL_ReverbComb m_combs[sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0])][2]; - -}; - - -#endif \ No newline at end of file diff --git a/WDL/vorbisencdec.h b/WDL/vorbisencdec.h deleted file mode 100644 index 0835092d..00000000 --- a/WDL/vorbisencdec.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - WDL - vorbisencdec.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* - - This file provides simple interfaces for encoding and decoding of OGG Vorbis data. - It is a wrapper around what their SDKs expose, which is not too easy to use. - - This stuff is pretty limited and simple, but works, usually. - - For full control you probably want to #define VORBISENC_WANT_FULLCONFIG - but for compatibility with some older code, it's left disabled here. - -*/ - -#ifndef _VORBISENCDEC_H_ -#define _VORBISENCDEC_H_ - -#ifndef OV_EXCLUDE_STATIC_CALLBACKS -#define OV_EXCLUDE_STATIC_CALLBACKS -#endif -#include "vorbis/vorbisenc.h" -#include "vorbis/codec.h" - -class VorbisDecoderInterface -{ -public: - virtual ~VorbisDecoderInterface(){} - virtual int GetSampleRate()=0; - virtual int GetNumChannels()=0; - virtual void *DecodeGetSrcBuffer(int srclen)=0; - virtual void DecodeWrote(int srclen)=0; - virtual void Reset()=0; - virtual int Available()=0; - virtual float *Get()=0; - virtual void Skip(int amt)=0; -}; - -class VorbisEncoderInterface -{ -public: - virtual ~VorbisEncoderInterface(){} - virtual void Encode(float *in, int inlen, int advance=1, int spacing=1)=0; // length in sample (PAIRS) - virtual int isError()=0; - virtual int Available()=0; - virtual void *Get()=0; - virtual void Advance(int)=0; - virtual void Compact()=0; - virtual void reinit(int bla=0)=0; -}; - - -#ifndef WDL_VORBIS_INTERFACE_ONLY - -#include "../WDL/queue.h" - -class VorbisDecoder : public VorbisDecoderInterface -{ - public: - VorbisDecoder() - { - m_samples_used=0; - packets=0; - memset(&oy,0,sizeof(oy)); - memset(&os,0,sizeof(os)); - memset(&og,0,sizeof(og)); - memset(&op,0,sizeof(op)); - memset(&vi,0,sizeof(vi)); - memset(&vc,0,sizeof(vc)); - memset(&vd,0,sizeof(vd)); - memset(&vb,0,sizeof(vb)); - - - ogg_sync_init(&oy); /* Now we can read pages */ - m_err=0; - } - ~VorbisDecoder() - { - ogg_stream_clear(&os); - vorbis_block_clear(&vb); - vorbis_dsp_clear(&vd); - vorbis_comment_clear(&vc); - vorbis_info_clear(&vi); - - ogg_sync_clear(&oy); - } - - int GetSampleRate() { return vi.rate; } - int GetNumChannels() { return vi.channels?vi.channels:1; } - - void *DecodeGetSrcBuffer(int srclen) - { - return ogg_sync_buffer(&oy,srclen); - } - - void DecodeWrote(int srclen) - { - ogg_sync_wrote(&oy,srclen); - - while(ogg_sync_pageout(&oy,&og)>0) - { - int serial=ogg_page_serialno(&og); - if (!packets) ogg_stream_init(&os,serial); - else if (serial!=os.serialno) - { - vorbis_block_clear(&vb); - vorbis_dsp_clear(&vd); - vorbis_comment_clear(&vc); - vorbis_info_clear(&vi); - - ogg_stream_clear(&os); - ogg_stream_init(&os,serial); - packets=0; - } - if (!packets) - { - vorbis_info_init(&vi); - vorbis_comment_init(&vc); - } - ogg_stream_pagein(&os,&og); - while(ogg_stream_packetout(&os,&op)>0) - { - if (packets<3) - { - if(vorbis_synthesis_headerin(&vi,&vc,&op)<0) return; - } - else - { - float ** pcm; - int samples; - if(vorbis_synthesis(&vb,&op)==0) vorbis_synthesis_blockin(&vd,&vb); - while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0) - { - int n,c; - - int newsize=(m_samples_used+(samples+4096)*vi.channels)*sizeof(float); - - if (m_samples.GetSize() < newsize) m_samples.Resize(newsize+32768); - - float *bufmem = (float *)m_samples.Get(); - - for(n=0;n0) - memcpy(sptr,sptr+amt,m_samples_used*sizeof(float)); - else m_samples_used=0; - } - - void Reset() - { - m_samples_used=0; - - vorbis_block_clear(&vb); - vorbis_dsp_clear(&vd); - vorbis_comment_clear(&vc); - vorbis_info_clear(&vi); - - ogg_stream_clear(&os); - packets=0; - } - - private: - - WDL_HeapBuf m_samples; // we let the size get as big as it needs to, so we don't worry about tons of mallocs/etc - - int m_err; - int packets; - int m_samples_used; - - ogg_sync_state oy; /* sync and verify incoming physical bitstream */ - ogg_stream_state os; /* take physical pages, weld into a logical - stream of packets */ - ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ - ogg_packet op; /* one raw packet of data for decode */ - - vorbis_info vi; /* struct that stores all the static vorbis bitstream - settings */ - vorbis_comment vc; /* struct that stores all the bitstream user comments */ - vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ - vorbis_block vb; /* local working space for packet->PCM decode */ - - -} WDL_FIXALIGN; - - -class VorbisEncoder : public VorbisEncoderInterface -{ -public: -#ifdef VORBISENC_WANT_FULLCONFIG - VorbisEncoder(int srate, int nch, int serno, float qv, int cbr=-1, int minbr=-1, int maxbr=-1, const char *encname=NULL) -#elif defined(VORBISENC_WANT_QVAL) - VorbisEncoder(int srate, int nch, float qv, int serno, const char *encname=NULL) -#else - VorbisEncoder(int srate, int nch, int bitrate, int serno, const char *encname=NULL) -#endif - { - m_flushmode=false; - m_ds=0; - - memset(&vi,0,sizeof(vi)); - memset(&vc,0,sizeof(vc)); - memset(&vd,0,sizeof(vd)); - memset(&vb,0,sizeof(vb)); - - m_nch=nch; - vorbis_info_init(&vi); - -#ifdef VORBISENC_WANT_FULLCONFIG - - if (cbr > 0) - { - m_err=vorbis_encode_init(&vi,nch,srate,maxbr*1000,cbr*1000,minbr*1000); - } - else - m_err=vorbis_encode_init_vbr(&vi,nch,srate,qv); - -#else - - #ifndef VORBISENC_WANT_QVAL - float qv=0.0; - if (nch == 2) bitrate= (bitrate*5)/8; - // at least for mono 44khz - //-0.1 = ~40kbps - //0.0 == ~64kbps - //0.1 == 75 - //0.3 == 95 - //0.5 == 110 - //0.75== 140 - //1.0 == 240 - if (bitrate <= 32) - { - m_ds=1; - bitrate*=2; - } - - if (bitrate < 40) qv=-0.1f; - else if (bitrate < 64) qv=-0.10f + (bitrate-40)*(0.10f/24.0f); - else if (bitrate < 75) qv=(bitrate-64)*(0.1f/9.0f); - else if (bitrate < 95) qv=0.1f+(bitrate-75)*(0.2f/20.0f); - else if (bitrate < 110) qv=0.3f+(bitrate-95)*(0.2f/15.0f); - else if (bitrate < 140) qv=0.5f+(bitrate-110)*(0.25f/30.0f); - else qv=0.75f+(bitrate-140)*(0.25f/100.0f); - - if (qv<-0.10f)qv=-0.10f; - if (qv>1.0f)qv=1.0f; - #endif - - m_err=vorbis_encode_init_vbr(&vi,nch,srate>>m_ds,qv); -#endif - - vorbis_comment_init(&vc); - if (encname) vorbis_comment_add_tag(&vc,"ENCODER",(char *)encname); - vorbis_analysis_init(&vd,&vi); - vorbis_block_init(&vd,&vb); - ogg_stream_init(&os,m_ser=serno); - - if (m_err) return; - - - reinit(1); - } - - void reinit(int bla=0) - { - if (!bla) - { - ogg_stream_clear(&os); - vorbis_block_clear(&vb); - vorbis_dsp_clear(&vd); - - vorbis_analysis_init(&vd,&vi); - vorbis_block_init(&vd,&vb); - ogg_stream_init(&os,m_ser++); //++? - - outqueue.Advance(outqueue.Available()); - outqueue.Compact(); - } - - - ogg_packet header; - ogg_packet header_comm; - ogg_packet header_code; - vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); - ogg_stream_packetin(&os,&header); /* automatically placed in its own page */ - ogg_stream_packetin(&os,&header_comm); - ogg_stream_packetin(&os,&header_code); - - for (;;) - { - ogg_page og; - int result=ogg_stream_flush(&os,&og); - if(result==0)break; - outqueue.Add(og.header,og.header_len); - outqueue.Add(og.body,og.body_len); - } - } - - void Encode(float *in, int inlen, int advance=1, int spacing=1) // length in sample (PAIRS) - { - if (m_err) return; - - if (inlen == 0) - { - // disable this for now, it fucks us sometimes - // maybe we should throw some silence in instead? - vorbis_analysis_wrote(&vd,0); - } - else - { - inlen >>= m_ds; - float **buffer=vorbis_analysis_buffer(&vd,inlen); - int i,i2=0; - - if (m_nch==1) - { - for (i = 0; i < inlen; i ++) - { - buffer[0][i]=in[i2]; - i2+=advance<2) - { - int n=m_nch; - for (i = 0; i < inlen; i ++) - { - int a; - int i3=i2; - for(a=0;a -#include "pcmfmtcvt.h" -#include "wdlstring.h" - -class WaveWriter -{ - public: - // appending doesnt check sample types - WaveWriter() - { - m_fp=0; - m_bps=0; - m_srate=0; - m_nch=0; - } - - WaveWriter(const char *filename, int bps, int nch, int srate, int allow_append=1) - { - m_fp=0; - m_bps=0; - m_srate=0; - m_nch=0; - Open(filename,bps,nch,srate,allow_append); - - } - - int Open(const char *filename, int bps, int nch, int srate, int allow_append=1) - { - m_fn.Set(filename); - m_fp=0; - if (allow_append) - { - m_fp=fopen(filename,"r+b"); - if (m_fp) - { - fseek(m_fp,0,SEEK_END); - int pos=ftell(m_fp); - if (pos < 44) - { - char buf[44]={0,}; - fwrite(buf,1,44-pos,m_fp); - } - } - } - if (!m_fp) - { - m_fp=fopen(filename,"wb"); - if (!m_fp) return 0; - - char tbuf[44]; - fwrite(tbuf,1,44,m_fp); // room for header - } - m_bps=bps; - m_nch=nch>1?2:1; - m_srate=srate; - - return !!m_fp; - } - - ~WaveWriter() - { - if (m_fp) - { - int bytelen=ftell(m_fp)-44; - fseek(m_fp,0,SEEK_SET); - - // write header - fwrite("RIFF",1,4,m_fp); - int riff_size=bytelen+44-8; - int x; - for (x = 0; x < 32; x += 8) - { - unsigned char c=(riff_size>>x)&255; - fwrite(&c,1,1,m_fp); - } - fwrite("WAVEfmt \x10\0\0\0",1,12,m_fp); - fwrite("\1\0",1,2,m_fp); // PCM - - for (x = 0; x < 16; x += 8) // nch - { - char c=(m_nch>>x)&255; - fwrite(&c,1,1,m_fp); - } - for (x = 0; x < 32; x += 8) // srate - { - char c=(m_srate>>x)&255; - fwrite(&c,1,1,m_fp); - } - for (x = 0; x < 32; x += 8) // bytes_per_sec - { - char c=((m_nch * (m_bps/8) * m_srate)>>x)&255; - fwrite(&c,1,1,m_fp); - } - int blockalign=m_nch * (m_bps/8); - for (x = 0; x < 16; x += 8) // block alignment - { - char c=(blockalign>>x)&255; - fwrite(&c,1,1,m_fp); - } - for (x = 0; x < 16; x += 8) // bits/sample - { - char c=((m_bps&~7)>>x)&255; - fwrite(&c,1,1,m_fp); - } - fwrite("data",1,4,m_fp); - for (x = 0; x < 32; x += 8) // size - { - char c=((bytelen)>>x)&255; - fwrite(&c,1,1,m_fp); - } - - fclose(m_fp); - m_fp=0; - } - } - - const char *GetFileName() { return m_fn.Get(); } - - int Status() { return !!m_fp; } - - int BytesWritten() - { - if (m_fp) return ftell(m_fp)-44; - return 0; - } - - void WriteRaw(void *buf, int len) - { - if (m_fp) fwrite(buf,1,len,m_fp); - } - - void WriteFloats(float *samples, int nsamples) - { - if (!m_fp) return; - - if (m_bps == 16) - { - while (nsamples-->0) - { - short a; - float_TO_INT16(a,*samples); - unsigned char c=a&0xff; - fwrite(&c,1,1,m_fp); - c=a>>8; - fwrite(&c,1,1,m_fp); - samples++; - } - } - else if (m_bps == 24) - { - while (nsamples-->0) - { - unsigned char a[3]; - float_to_i24(samples,a); - fwrite(a,1,3,m_fp); - samples++; - } - } - } - - void WriteDoubles(double *samples, int nsamples) - { - if (!m_fp) return; - - if (m_bps == 16) - { - while (nsamples-->0) - { - short a; - double_TO_INT16(a,*samples); - unsigned char c=a&0xff; - fwrite(&c,1,1,m_fp); - c=a>>8; - fwrite(&c,1,1,m_fp); - samples++; - } - } - else if (m_bps == 24) - { - while (nsamples-->0) - { - unsigned char a[3]; - double_to_i24(samples,a); - fwrite(a,1,3,m_fp); - samples++; - } - } - } - - void WriteFloatsNI(float **samples, int offs, int nsamples, int nchsrc=0) - { - if (!m_fp) return; - - if (nchsrc < 1) nchsrc=m_nch; - - float *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL}; - - if (m_bps == 16) - { - while (nsamples-->0) - { - int ch; - for (ch = 0; ch < m_nch; ch ++) - { - short a; - float_TO_INT16(a,tmpptrs[ch][0]); - unsigned char c=a&0xff; - fwrite(&c,1,1,m_fp); - c=a>>8; - fwrite(&c,1,1,m_fp); - tmpptrs[ch]++; - } - } - } - else if (m_bps == 24) - { - while (nsamples-->0) - { - int ch; - for (ch = 0; ch < m_nch; ch ++) - { - unsigned char a[3]; - float_to_i24(tmpptrs[ch],a); - fwrite(a,1,3,m_fp); - tmpptrs[ch]++; - } - } - } - } - - void WriteDoublesNI(double **samples, int offs, int nsamples, int nchsrc=0) - { - if (!m_fp) return; - - if (nchsrc < 1) nchsrc=m_nch; - - double *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL}; - - if (m_bps == 16) - { - while (nsamples-->0) - { - int ch; - for (ch = 0; ch < m_nch; ch ++) - { - short a; - double_TO_INT16(a,tmpptrs[ch][0]); - unsigned char c=a&0xff; - fwrite(&c,1,1,m_fp); - c=a>>8; - fwrite(&c,1,1,m_fp); - tmpptrs[ch]++; - } - } - } - else if (m_bps == 24) - { - while (nsamples-->0) - { - int ch; - for (ch = 0; ch < m_nch; ch ++) - { - unsigned char a[3]; - double_to_i24(tmpptrs[ch],a); - fwrite(a,1,3,m_fp); - tmpptrs[ch]++; - } - } - } - } - - - int get_nch() { return m_nch; } - int get_srate() { return m_srate; } - int get_bps() { return m_bps; } - - private: - WDL_String m_fn; - FILE *m_fp; - int m_bps,m_nch,m_srate; -}; - - -#endif//_WAVWRITE_H_ \ No newline at end of file diff --git a/WDL/wdlcstring.h b/WDL/wdlcstring.h deleted file mode 100644 index a6f92f15..00000000 --- a/WDL/wdlcstring.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - WDL - wdlcstring.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* -C string manipulation utilities -- [v]snprintf for Win32, also snprintf_append, lstrcatn, etc - */ -#ifndef _WDL_CSTRING_H_ -#define _WDL_CSTRING_H_ - -#include -#include - -#include "wdltypes.h" - -#ifdef _WDL_CSTRING_IMPL_ONLY_ - #ifdef _WDL_CSTRING_IF_ONLY_ - #undef _WDL_CSTRING_IF_ONLY_ - #endif - #define _WDL_CSTRING_PREFIX -#else - #define _WDL_CSTRING_PREFIX static -#endif - - - -#if defined(_WIN32) && defined(_MSC_VER) - // provide snprintf()/vsnprintf() for win32 -- note that these have no way of knowing - // what the amount written was, code should(must) be written to not depend on this. - #ifdef snprintf - #undef snprintf - #endif - #define snprintf WDL_snprintf - - #ifdef vsnprintf - #undef vsnprintf - #endif - #define vsnprintf WDL_vsnprintf - -#endif // win32 snprintf/vsnprintf - -// use wdlcstring.h's lstrcpyn_safe rather than the real lstrcpyn. -#ifdef _WIN32 - #ifdef lstrcpyn - #undef lstrcpyn - #endif - #define lstrcpyn lstrcpyn_safe -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WDL_CSTRING_IF_ONLY_ - - void lstrcpyn_safe(char *o, const char *in, int count); - void lstrcatn(char *o, const char *in, int count); - void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...); - void vsnprintf_append(char *o, int count, const char *format, va_list va); - - #if defined(_WIN32) && defined(_MSC_VER) - void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args); - void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...); - #endif - -#else - - - #if defined(_WIN32) && defined(_MSC_VER) - - _WDL_CSTRING_PREFIX void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args) - { - if (count>0) - { - int rv; - o[0]=0; - rv=_vsnprintf(o,count,format,args); // returns -1 if over, and does not null terminate, ugh - if (rv < 0 || rv>=(int)count-1) o[count-1]=0; - } - } - _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...) - { - if (count>0) - { - int rv; - va_list va; - va_start(va,format); - o[0]=0; - rv=_vsnprintf(o,count,format,va); // returns -1 if over, and does not null terminate, ugh - va_end(va); - - if (rv < 0 || rv>=(int)count-1) o[count-1]=0; - } - } - #endif - - _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, int count) - { - if (count>0) - { - while (--count>0 && *in) *o++ = *in++; - *o=0; - } - } - - _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, int count) - { - if (count>0) - { - while (*o) { if (--count < 1) return; o++; } - while (--count>0 && *in) *o++ = *in++; - *o=0; - } - } - _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...) - { - if (count>0) - { - va_list va; - while (*o) { if (--count < 1) return; o++; } - va_start(va,format); - vsnprintf(o,count,format,va); - va_end(va); - } - } - - _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, int count, const char *format, va_list va) - { - if (count>0) - { - while (*o) { if (--count < 1) return; o++; } - vsnprintf(o,count,format,va); - } - } - -#endif - - -#ifdef __cplusplus -}; -#endif - -#undef _WDL_CSTRING_PREFIX - -#endif diff --git a/WDL/wdlstring.h b/WDL/wdlstring.h deleted file mode 100644 index 4030778c..00000000 --- a/WDL/wdlstring.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - WDL - wdlstring.h - Copyright (C) 2005 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides a simple class for variable-length string manipulation. - It provides only the simplest features, and does not do anything confusing like - operator overloading. It uses a WDL_HeapBuf for internal storage. - - Actually: there are WDL_String and WDL_FastString -- the latter's Get() returns const char, and tracks - the length of the string, which is often faster. Because of this, you are not permitted to directly modify - the buffer returned by Get(). - - -*/ - -#ifndef _WDL_STRING_H_ -#define _WDL_STRING_H_ - -#include "heapbuf.h" -#include -#include - -#ifndef WDL_STRING_IMPL_ONLY -class WDL_String -{ - public: - #ifdef WDL_STRING_INTF_ONLY - void Set(const char *str, int maxlen=0); - void Set(const WDL_String *str, int maxlen=0); - void Append(const char *str, int maxlen=0); - void Append(const WDL_String *str, int maxlen=0); - void DeleteSub(int position, int len); - void Insert(const char *str, int position, int maxlen=0); - void Insert(const WDL_String *str, int position, int maxlen=0); - void SetLen(int length, bool resizeDown=false); - void Ellipsize(int minlen, int maxlen); - - void SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist); - void WDL_VARARG_WARN(printf,3,4) SetFormatted(int maxlen, const char *fmt, ...); - void WDL_VARARG_WARN(printf,3,4) AppendFormatted(int maxlen, const char *fmt, ...); - #endif - - #ifdef WDL_STRING_FASTSUB_DEFINED - const char *Get() const { return m_hb.GetSize()?(char*)m_hb.Get():""; } - int GetLength() const { int a = m_hb.GetSize(); return a>0?a-1:0; } - #else - char *Get() const - { - if (m_hb.GetSize()) return (char *)m_hb.Get(); - static char c; c=0; return &c; // don't return "", in case it gets written to. - } - int GetLength() const { return m_hb.GetSize()?(int)strlen((const char*)m_hb.Get()):0; } - #endif - - explicit WDL_String(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_String(4)")) { } - explicit WDL_String(const char *initial=NULL, int initial_len=0) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String")) - { - if (initial) Set(initial,initial_len); - } - WDL_String(const WDL_String &s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(2)")) { Set(&s); } - WDL_String(const WDL_String *s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(3)")) { if (s && s != this) Set(s); } - ~WDL_String() { } -#endif // ! WDL_STRING_IMPL_ONLY - -#ifndef WDL_STRING_INTF_ONLY - #ifdef WDL_STRING_IMPL_ONLY - #define WDL_STRING_FUNCPREFIX WDL_String:: - #define WDL_STRING_DEFPARM(x) - #else - #define WDL_STRING_FUNCPREFIX - #define WDL_STRING_DEFPARM(x) =(x) - #endif - - void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0)) - { - int s=0; - if (maxlen>0) while (s < maxlen && str[s]) s++; - else s=(int)strlen(str); - __doSet(0,str,s,0); - } - - void WDL_STRING_FUNCPREFIX Set(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) - { - #ifdef WDL_STRING_FASTSUB_DEFINED - int s = str->GetLength(); - if (maxlen>0 && maxlenGet(),s,0); - #else - Set(str->Get(), maxlen); // might be faster: "partial" strlen - #endif - } - - void WDL_STRING_FUNCPREFIX Append(const char *str, int maxlen WDL_STRING_DEFPARM(0)) - { - int s=0; - if (maxlen>0) while (s < maxlen && str[s]) s++; - else s=(int)strlen(str); - - __doSet(GetLength(),str,s,0); - } - - void WDL_STRING_FUNCPREFIX Append(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) - { - #ifdef WDL_STRING_FASTSUB_DEFINED - int s = str->GetLength(); - if (maxlen>0 && maxlenGet(),s,0); - #else - Append(str->Get(), maxlen); // might be faster: "partial" strlen - #endif - } - - void WDL_STRING_FUNCPREFIX DeleteSub(int position, int len) - { - char *p=(char *)m_hb.Get(); - if (!m_hb.GetSize() || !*p) return; - int l=m_hb.GetSize()-1; - if (position < 0 || position >= l) return; - if (position+len > l) len=l-position; - if (len>0) - { - memmove(p+position,p+position+len,l-position-len+1); - m_hb.Resize(l+1-len,false); - } - } - - void WDL_STRING_FUNCPREFIX Insert(const char *str, int position, int maxlen WDL_STRING_DEFPARM(0)) - { - int ilen=0; - if (maxlen>0) while (ilen < maxlen && str[ilen]) ilen++; - else ilen=(int)strlen(str); - - int srclen = GetLength(); - if (position<0) position=0; - else if (position>srclen) position=srclen; - if (ilen>0) __doSet(position,str,ilen,srclen-position); - } - - void WDL_STRING_FUNCPREFIX Insert(const WDL_String *str, int position, int maxlen WDL_STRING_DEFPARM(0)) - { - #ifdef WDL_STRING_FASTSUB_DEFINED - int ilen = str->GetLength(); - if (maxlen>0 && maxlen0 ? m_hb.GetSize()-1 : 0; - if (position<0) position=0; - else if (position>srclen) position=srclen; - if (ilen>0) __doSet(position,str->Get(),ilen,srclen-position); - #else - Insert(str->Get(), position, maxlen); // might be faster: "partial" strlen - #endif - } - - void WDL_STRING_FUNCPREFIX SetLen(int length, bool resizeDown WDL_STRING_DEFPARM(false)) - { - #ifdef WDL_STRING_FASTSUB_DEFINED - int osz = m_hb.GetSize()?m_hb.GetSize()-1:0; - #endif - char *b=(char*)m_hb.Resize(length+1,resizeDown); - if (m_hb.GetSize()==length+1) - { - #ifdef WDL_STRING_FASTSUB_DEFINED - if (length > osz) memset(b+osz,' ',length-osz); - #endif - b[length]=0; - } - } - - void WDL_STRING_FUNCPREFIX SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist) - { - int offs = append ? GetLength() : 0; - char* b= (char*) m_hb.Resize(offs+maxlen+1,false)+offs; - if (m_hb.GetSize() != offs+maxlen+1) return; - - #ifdef _WIN32 - int written = _vsnprintf(b, maxlen+1, fmt, arglist); - if (written < 0 || written>=maxlen) b[written=b[0]?maxlen:0]=0; - #else - int written = vsnprintf(b, maxlen+1, fmt, arglist); - if (written > maxlen) written=maxlen; - #endif - - m_hb.Resize(offs + written + 1,false); - } - - void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX SetFormatted(int maxlen, const char *fmt, ...) - { - va_list arglist; - va_start(arglist, fmt); - SetAppendFormattedArgs(false,maxlen,fmt,arglist); - va_end(arglist); - } - - void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX AppendFormatted(int maxlen, const char *fmt, ...) - { - va_list arglist; - va_start(arglist, fmt); - SetAppendFormattedArgs(true,maxlen,fmt,arglist); - va_end(arglist); - } - - void WDL_STRING_FUNCPREFIX Ellipsize(int minlen, int maxlen) - { - if (maxlen >= 4 && m_hb.GetSize() && GetLength() > maxlen) - { - if (minlen<0) minlen=0; - char *b = (char *)m_hb.Get(); - int i; - for (i = maxlen-4; i >= minlen; --i) - { - if (b[i] == ' ') - { - memcpy(b+i, "...",4); - m_hb.Resize(i+4,false); - break; - } - } - if (i < minlen && maxlen >= 4) - { - memcpy(b+maxlen-4, "...",4); - m_hb.Resize(maxlen,false); - } - } - } - -#ifndef WDL_STRING_IMPL_ONLY - private: -#endif - void WDL_STRING_FUNCPREFIX __doSet(int offs, const char *str, int len, int trailkeep) - { - if (len>0 || (!trailkeep && !offs && m_hb.GetSize()>1)) // if non-empty, or (empty and allocated and Set() rather than append/insert), then allow update, otherwise do nothing - { - char *newbuf=(char*)m_hb.Resize(offs+len+trailkeep+1,false); - if (m_hb.GetSize()==offs+len+trailkeep+1) - { - if (trailkeep>0) memmove(newbuf+offs+len,newbuf+offs,trailkeep); - memcpy(newbuf+offs,str,len); - newbuf[offs+len+trailkeep]=0; - } - } - } - - #undef WDL_STRING_FUNCPREFIX - #undef WDL_STRING_DEFPARM -#endif // ! WDL_STRING_INTF_ONLY - -#ifndef WDL_STRING_IMPL_ONLY - - private: - #ifdef WDL_STRING_INTF_ONLY - void __doSet(int offs, const char *str, int len, int trailkeep); - #endif - - WDL_HeapBuf m_hb; -}; -#endif - -#ifndef WDL_STRING_FASTSUB_DEFINED -#undef _WDL_STRING_H_ -#define WDL_STRING_FASTSUB_DEFINED -#define WDL_String WDL_FastString -#include "wdlstring.h" -#undef WDL_STRING_FASTSUB_DEFINED -#undef WDL_String -#endif - -#endif - diff --git a/WDL/wdltypes.h b/WDL/wdltypes.h deleted file mode 100644 index 181b2121..00000000 --- a/WDL/wdltypes.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _WDLTYPES_ -#define _WDLTYPES_ - -#ifdef _MSC_VER - -typedef __int64 WDL_INT64; -typedef unsigned __int64 WDL_UINT64; - -#else - -typedef long long WDL_INT64; -typedef unsigned long long WDL_UINT64; - -#endif - -#define WDL_UINT64_CONST(x) ((WDL_UINT64)(x)) -#define WDL_INT64_CONST(x) ((WDL_INT64)(x)) - - -#if !defined(_MSC_VER) || _MSC_VER > 1200 -#define WDL_DLGRET INT_PTR CALLBACK -#else -#define WDL_DLGRET BOOL CALLBACK -#endif - - -#ifdef _WIN32 -#include -#else -#include -typedef intptr_t INT_PTR; -typedef uintptr_t UINT_PTR; -#endif - -#if defined(__ppc__) || !defined(__cplusplus) -typedef char WDL_bool; -#else -typedef bool WDL_bool; -#endif - -#ifndef GWLP_USERDATA -#define GWLP_USERDATA GWL_USERDATA -#define GWLP_WNDPROC GWL_WNDPROC -#define GWLP_HINSTANCE GWL_HINSTANCE -#define GWLP_HWNDPARENT GWL_HWNDPARENT -#define DWLP_USER DWL_USER -#define DWLP_DLGPROC DWL_DLGPROC -#define DWLP_MSGRESULT DWL_MSGRESULT -#define SetWindowLongPtr(a,b,c) SetWindowLong(a,b,c) -#define GetWindowLongPtr(a,b) GetWindowLong(a,b) -#define SetWindowLongPtrW(a,b,c) SetWindowLongW(a,b,c) -#define GetWindowLongPtrW(a,b) GetWindowLongW(a,b) -#define SetWindowLongPtrA(a,b,c) SetWindowLongA(a,b,c) -#define GetWindowLongPtrA(a,b) GetWindowLongA(a,b) - -#define GCLP_WNDPROC GCL_WNDPROC -#define GCLP_HICON GCL_HICON -#define GCLP_HICONSM GCL_HICONSM -#define SetClassLongPtr(a,b,c) SetClassLong(a,b,c) -#define GetClassLongPtr(a,b) GetClassLong(a,b) -#endif - - -#ifdef __GNUC__ -// for structures that contain doubles, or doubles in structures that are after stuff of questionable alignment (for OSX/linux) - #define WDL_FIXALIGN __attribute__ ((aligned (8))) -// usage: void func(int a, const char *fmt, ...) WDL_VARARG_WARN(printf,2,3); // note: if member function, this pointer is counted as well, so as member function that would be 3,4 - #define WDL_VARARG_WARN(x,n,s) __attribute__ ((format (x,n,s))) - -#else - #define WDL_FIXALIGN - #define WDL_VARARG_WARN(x,n,s) -#endif - - - -#endif diff --git a/WDL/win32_curses/curses.h b/WDL/win32_curses/curses.h deleted file mode 100644 index 398dbd8c..00000000 --- a/WDL/win32_curses/curses.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef _CURSES_WIN32SIM_H_ -#define _CURSES_WIN32SIM_H_ - -#if !defined(_WIN32) && !defined(MAC_NATIVE) && !defined(FORCE_WIN32_CURSES) - #ifdef MAC - #include - #else - #include - #endif -#else - - #ifdef _WIN32 - #include - #else - #include "../swell/swell.h" - #endif - #include "../queue.h" - -/* -** this implements a tiny subset of curses on win32. -** It creates a window (Resizeable by user), and gives you a callback to run -** your UI. -*/ - - -// if you need multiple contexts, define this in your sourcefiles BEFORE including curses.h -// if you don't need multiple contexts, declare win32CursesCtx g_curses_context; in one of your source files. -#ifndef CURSES_INSTANCE -#define CURSES_INSTANCE (&g_curses_context) -#endif - -#define LINES ((CURSES_INSTANCE)->lines) -#define COLS ((CURSES_INSTANCE)->cols) - -//ncurses WIN32 wrapper functions - - -#define addnstr(str,n) __addnstr(CURSES_INSTANCE,str,n) -#define addstr(str) __addnstr(CURSES_INSTANCE,str,-1) -#define addch(c) __addch(CURSES_INSTANCE,c) - -#define mvaddstr(x,y,str) __mvaddnstr(CURSES_INSTANCE,x,y,str,-1) -#define mvaddnstr(x,y,str,n) __mvaddnstr(CURSES_INSTANCE,x,y,str,n) -#define clrtoeol() __clrtoeol(CURSES_INSTANCE) -#define move(x,y) __move(CURSES_INSTANCE, x,y, 0) -#define attrset(a) (CURSES_INSTANCE)->m_cur_attr=(a) -#define bkgdset(a) (CURSES_INSTANCE)->m_cur_erase_attr=(a) -#define initscr() __initscr(CURSES_INSTANCE) -#define endwin() __endwin(CURSES_INSTANCE) -#define curses_erase(x) __curses_erase(x) -#define start_color() -#define init_pair(x,y,z) __init_pair((CURSES_INSTANCE),x,y,z) -#define has_colors() 1 - -#define A_NORMAL 0 -#define A_BOLD 1 -#define COLOR_PAIR(x) ((x)< -#include -#else -#include "../swell/swell.h" -#endif -#define CURSES_INSTANCE ___ERRROR_____ - -#include "curses.h" - -#include -#include - -#define CURSOR_BLINK_TIMER_MS 400 -#define CURSOR_BLINK_TIMER 2 -#define CURSOR_BLINK_TIMER_ZEROEVERY 3 - -#ifndef WIN32_CURSES_CURSORTYPE -#define WIN32_CURSES_CURSORTYPE 1 // 1 for vertical bar, 2 for horz bar, 0 for block -#endif -#define WIN32CURSES_CLASS_NAME "WDLCursesWindow" - -#define WIN32_CONSOLE_KBQUEUE - -static void doFontCalc(win32CursesCtx*, HDC); - -static void m_InvalidateArea(win32CursesCtx *ctx, int sx, int sy, int ex, int ey) -{ - doFontCalc(ctx,NULL); - - RECT r; - r.left=sx*ctx->m_font_w; - r.top=sy*ctx->m_font_h; - r.right=ex*ctx->m_font_w; - r.bottom=ey*ctx->m_font_h; - if (ctx->m_hwnd) InvalidateRect(ctx->m_hwnd,&r,FALSE); -} - -void __addnstr(win32CursesCtx *ctx, const char *str,int n) -{ - if (ctx->m_cursor_x<0) - { - int skip = -ctx->m_cursor_x; - ctx->m_cursor_x=0; - if (n>=0) - { - n -= skip; - if (n<0)n=0; - } - int slen = strlen(str); - str += min(slen,skip); - } - - int sx=ctx->m_cursor_x; - int sy=ctx->m_cursor_y; - if (n==0||!ctx->m_framebuffer || ctx->m_cursor_y < 0 || ctx->m_cursor_y >= ctx->lines) return; - char *p=(char *)ctx->m_framebuffer + 2*(ctx->m_cursor_x + ctx->m_cursor_y*ctx->cols); - while (n-- && *str) - { - p[0]=*str++; - p[1]=ctx->m_cur_attr; - p+=2; - if (++ctx->m_cursor_x >= ctx->cols) - { - ctx->m_cursor_y++; - ctx->m_cursor_x=0; - if (ctx->m_cursor_y >= ctx->lines) { ctx->m_cursor_y=ctx->lines-1; ctx->m_cursor_x=ctx->cols-1; break; } - } - } - m_InvalidateArea(ctx,sx,sy,sy < ctx->m_cursor_y ? ctx->cols : ctx->m_cursor_x+1,ctx->m_cursor_y+1); -} - -void __clrtoeol(win32CursesCtx *ctx) -{ - if (ctx->m_cursor_x<0)ctx->m_cursor_x=0; - int n = ctx->cols - ctx->m_cursor_x; - if (!ctx->m_framebuffer || ctx->m_cursor_y < 0 || ctx->m_cursor_y >= ctx->lines || n < 1) return; - char *p=(char *)ctx->m_framebuffer + 2*(ctx->m_cursor_x + ctx->m_cursor_y*ctx->cols); - int sx=ctx->m_cursor_x; - while (n--) - { - p[0]=0; - p[1]=ctx->m_cur_erase_attr; - p+=2; - } - m_InvalidateArea(ctx,sx,ctx->m_cursor_y,ctx->cols,ctx->m_cursor_y+1); -} - -void __curses_erase(win32CursesCtx *ctx) -{ - ctx->m_cur_attr=0; - ctx->m_cur_erase_attr=0; - if (ctx->m_framebuffer) memset(ctx->m_framebuffer,0,ctx->cols*ctx->lines*2); - ctx->m_cursor_x=0; - ctx->m_cursor_y=0; - m_InvalidateArea(ctx,0,0,ctx->cols,ctx->lines); -} - -void __move(win32CursesCtx *ctx, int x, int y, int noupdest) -{ - m_InvalidateArea(ctx,ctx->m_cursor_x,ctx->m_cursor_y,ctx->m_cursor_x+1,ctx->m_cursor_y+1); - ctx->m_cursor_x=y; - ctx->m_cursor_y=x; - if (!noupdest) m_InvalidateArea(ctx,ctx->m_cursor_x,ctx->m_cursor_y,ctx->m_cursor_x+1,ctx->m_cursor_y+1); -} - - -void __init_pair(win32CursesCtx *ctx, int pair, int fcolor, int bcolor) -{ - if (pair < 0 || pair >= COLOR_PAIRS) return; - - pair=COLOR_PAIR(pair); - - ctx->colortab[pair][0]=fcolor; - ctx->colortab[pair][1]=bcolor; - - if (fcolor & 0xff) fcolor|=0xff; - if (fcolor & 0xff00) fcolor|=0xff00; - if (fcolor & 0xff0000) fcolor|=0xff0000; - ctx->colortab[pair|A_BOLD][0]=fcolor; - ctx->colortab[pair|A_BOLD][1]=bcolor; - -} - -static int xlateKey(int msg, int wParam, int lParam) -{ - if (msg == WM_KEYDOWN) - { -#ifndef _WIN32 - if (lParam & FVIRTKEY) -#endif - switch (wParam) - { - case VK_HOME: return KEY_HOME; - case VK_UP: return KEY_UP; - case VK_PRIOR: return KEY_PPAGE; - case VK_LEFT: return KEY_LEFT; - case VK_RIGHT: return KEY_RIGHT; - case VK_END: return KEY_END; - case VK_DOWN: return KEY_DOWN; - case VK_NEXT: return KEY_NPAGE; - case VK_INSERT: return KEY_IC; - case VK_DELETE: return KEY_DC; - case VK_F1: return KEY_F1; - case VK_F2: return KEY_F2; - case VK_F3: return KEY_F3; - case VK_F4: return KEY_F4; - case VK_F5: return KEY_F5; - case VK_F6: return KEY_F6; - case VK_F7: return KEY_F7; - case VK_F8: return KEY_F8; - case VK_F9: return KEY_F9; - case VK_F10: return KEY_F10; - case VK_F11: return KEY_F11; - case VK_F12: return KEY_F12; -#ifndef _WIN32 - case VK_SUBTRACT: return (GetAsyncKeyState(VK_SHIFT)&0x8000)?'_':'-'; // numpad - -#endif - } - - switch (wParam) - { - case VK_RETURN: case VK_BACK: case VK_TAB: case VK_ESCAPE: return wParam; - case VK_CONTROL: break; - - default: - if(GetAsyncKeyState(VK_CONTROL)&0x8000) - { - if (wParam>='a' && wParam<='z') - { - wParam += 1-'a'; - return wParam; - } - if (wParam>='A' && wParam<='Z') - { - wParam += 1-'A'; - return wParam; - } - } - } - } - -#ifdef _WIN32 // todo : fix for nonwin32 - if (msg == WM_CHAR) - { - if(wParam>=32) return wParam; - } -#else - - //osx/linux - if (wParam >= 32) - { - if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) - { - if (wParam>='A' && wParam<='Z') - { - if ((GetAsyncKeyState(VK_MENU)&0x8000)) wParam -= 'A'-1; - else - wParam += 'a'-'A'; - } - } - else - { - if (wParam=='-') wParam='_'; - else if (wParam>='0' && wParam<='9') - { - if (wParam=='0') wParam = ')'; - else if (wParam=='1') wParam = '!'; - else if (wParam=='2') wParam = '@'; - else if (wParam=='3') wParam = '#'; - else if (wParam=='4') wParam = '$'; - else if (wParam=='5') wParam = '%'; - else if (wParam=='6') wParam = '^'; - else if (wParam=='7') wParam = '&'; - else if (wParam=='8') wParam = '*'; - else if (wParam=='9') wParam = '('; - } - } - return wParam; - } - -#endif - return ERR; -} - - -static void m_reinit_framebuffer(win32CursesCtx *ctx) -{ - doFontCalc(ctx,NULL); - RECT r; - - GetClientRect(ctx->m_hwnd,&r); - - ctx->lines=r.bottom / ctx->m_font_h; - ctx->cols=r.right / ctx->m_font_w; - if (ctx->lines<1) ctx->lines=1; - if (ctx->cols<1) ctx->cols=1; - ctx->m_cursor_x=0; - ctx->m_cursor_y=0; - ctx->m_framebuffer=(unsigned char *)realloc(ctx->m_framebuffer,2*ctx->lines*ctx->cols); - if (ctx->m_framebuffer) memset(ctx->m_framebuffer,0,2*ctx->lines*ctx->cols); -} -#ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 0x20A -#endif - -LRESULT CALLBACK cursesWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - win32CursesCtx *ctx = (win32CursesCtx*)GetWindowLongPtr(hwnd,GWLP_USERDATA); - -#ifdef _WIN32 - - static int Scroll_Message; - if (!Scroll_Message) - { - Scroll_Message = (int)RegisterWindowMessage("MSWHEEL_ROLLMSG"); - if (!Scroll_Message) Scroll_Message=-1; - } - if (Scroll_Message > 0 && uMsg == (UINT)Scroll_Message) - { - uMsg=WM_MOUSEWHEEL; - wParam<<=16; - } -#endif - - if (ctx)switch (uMsg) - { - case WM_DESTROY: - ctx->m_hwnd=0; - return 0; -#ifdef WIN32_CONSOLE_KBQUEUE - case WM_CHAR: case WM_KEYDOWN: - - { - int a=xlateKey(uMsg,wParam,lParam); - if (a != ERR && ctx->m_kbq) - { - ctx->m_kbq->Add(&a,sizeof(int)); - } - } - case WM_KEYUP: - return 0; -#endif - case WM_GETMINMAXINFO: - { - LPMINMAXINFO p=(LPMINMAXINFO)lParam; - p->ptMinTrackSize.x = 160; - p->ptMinTrackSize.y = 120; - } - return 0; - case WM_SIZE: - if (wParam != SIZE_MINIMIZED) - { - m_reinit_framebuffer(ctx); - ctx->m_need_redraw=1; - } - return 0; - case WM_RBUTTONDOWN: - case WM_LBUTTONDOWN: - SetFocus(hwnd); - case WM_LBUTTONUP: - case WM_RBUTTONUP: - case WM_CAPTURECHANGED: - case WM_MOUSEMOVE: - case WM_MOUSEWHEEL: - if (ctx && ctx->onMouseMessage) return ctx->onMouseMessage(ctx->user_data,hwnd,uMsg,wParam,lParam); - return 0; -#ifdef _WIN32 - case WM_GETDLGCODE: - if (GetParent(hwnd)) - { - return DLGC_WANTALLKEYS; - } - return 0; -#endif - case WM_TIMER: - if (wParam==CURSOR_BLINK_TIMER && ctx) - { - int la = ctx->m_cursor_state; - ctx->m_cursor_state= (ctx->m_cursor_state+1)%CURSOR_BLINK_TIMER_ZEROEVERY; - - if (!!ctx->m_cursor_state != !!la) - __move(ctx,ctx->m_cursor_y,ctx->m_cursor_x,1);// refresh cursor - } -#ifdef WIN32_CONSOLE_KBQUEUE - if (wParam == 1) - { - if (!ctx->m_intimer) - { - ctx->m_intimer=1; - if (ctx->ui_run) ctx->ui_run(ctx); - ctx->m_intimer=0; - } - } -#endif - return 0; - case WM_CREATE: - - // this only is called on osx or from standalone, it seems, since on win32 ctx isnt set up yet - ctx->m_hwnd=hwnd; - #ifdef WIN32_CONSOLE_KBQUEUE - SetTimer(hwnd,1,33,NULL); - #endif - #ifndef _WIN32 - m_reinit_framebuffer(ctx); - ctx->m_need_redraw=1; - #endif - SetTimer(hwnd,CURSOR_BLINK_TIMER,CURSOR_BLINK_TIMER_MS,NULL); - return 0; - case WM_ERASEBKGND: - return 0; - case WM_PAINT: - { - RECT r; -#ifdef _WIN32 - if (GetUpdateRect(hwnd,&r,FALSE)) -#else - GetClientRect(hwnd,&r); -#endif - { - PAINTSTRUCT ps; - HDC hdc=BeginPaint(hwnd,&ps); - if (hdc) - { - doFontCalc(ctx,ps.hdc); - - HGDIOBJ oldf=SelectObject(hdc,ctx->mOurFont); - int y,ypos; - int lattr=-1; -#ifdef _WIN32 - SetTextAlign(hdc,TA_TOP|TA_LEFT); -#endif - const char *ptr=(const char*)ctx->m_framebuffer; - RECT updr=r; - - r.left /= ctx->m_font_w; - r.top /= ctx->m_font_h; - r.bottom += ctx->m_font_h-1; - r.bottom /= ctx->m_font_h; - r.right += ctx->m_font_w-1; - r.right /= ctx->m_font_w; - - ypos = r.top * ctx->m_font_h; - ptr += 2*(r.top * ctx->cols); - - if (r.top < 0) r.top=0; - if (r.bottom > ctx->lines) r.bottom=ctx->lines; - if (r.left < 0) r.left=0; - if (r.right > ctx->cols) r.right=ctx->cols; - - HBRUSH bgbrushes[COLOR_PAIRS << NUM_ATTRBITS]; - for(y=0;ycolortab[y][1]); - - int cstate=ctx->m_cursor_state; - if (ctx->m_cursor_y != ctx->m_cursor_state_ly || - ctx->m_cursor_x != ctx->m_cursor_state_lx) - { - ctx->m_cursor_state_lx=ctx->m_cursor_x; - ctx->m_cursor_state_ly=ctx->m_cursor_y; - ctx->m_cursor_state=0; - cstate=1; - } - - if (ctx->m_framebuffer) for (y = r.top; y < r.bottom; y ++, ypos+=ctx->m_font_h, ptr += ctx->cols*2) - { - int x = r.left,xpos = r.left * ctx->m_font_w; - - const char *p = ptr + r.left*2; - - int defer_blanks=0; - - for (;; x ++, xpos+=ctx->m_font_w, p += 2) - { - char c=' ',attr=0; - - if (x < r.right) - { - c=p[0]; - attr=p[1]; - } - - bool isCursor = cstate && y == ctx->m_cursor_y && x == ctx->m_cursor_x; - bool isNotBlank = (isprint(c) && !isspace(c)); - - if (defer_blanks > 0 && (isNotBlank || isCursor || attr != lattr || x>=r.right)) - { - RECT tr={xpos - defer_blanks*ctx->m_font_w,ypos,xpos,ypos+ctx->m_font_h}; - FillRect(hdc,&tr,bgbrushes[lattr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]); - defer_blanks=0; - } - - if (x>=r.right) break; - -#if WIN32_CURSES_CURSORTYPE == 0 - if (isCursor) - { - SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); - SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); - lattr = -1; - } - else -#endif // WIN32_CURSES_CURSORTYPE == 0 - if (attr != lattr) - { - SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); - SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); - lattr=attr; - } - - if (isNotBlank||isCursor) - { - #ifdef _WIN32 - int txpos = xpos; - TextOut(hdc,txpos,ypos,isNotBlank ? p : " ",1); - #else - RECT tr={xpos,ypos,xpos+32,ypos+32}; - HBRUSH br=bgbrushes[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]; -#if WIN32_CURSES_CURSORTYPE == 0 - if (isCursor) - { - br = CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); - FillRect(hdc,&tr,br); - DeleteObject(br); - } - else -#endif - { - FillRect(hdc,&tr,br); - } - char tmp[2]={c,0}; - DrawText(hdc,isprint(c) && !isspace(c) ?tmp : " ",-1,&tr,DT_LEFT|DT_TOP|DT_NOPREFIX|DT_NOCLIP); - #endif -#if WIN32_CURSES_CURSORTYPE > 0 - if (isCursor) - { - #if WIN32_CURSES_CURSORTYPE == 1 - RECT r={xpos,ypos,xpos+2,ypos+ctx->m_font_h}; - #elif WIN32_CURSES_CURSORTYPE == 2 - RECT r={xpos,ypos+ctx->m_font_h-2,xpos+ctx->m_font_w,ypos+ctx->m_font_h}; - #endif - HBRUSH br=CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); - FillRect(hdc,&r,br); - DeleteObject(br); - } -#endif - } - else - { - defer_blanks++; - } - } - } - int rm=ctx->cols * ctx->m_font_w; - int bm=ctx->lines * ctx->m_font_h; - if (updr.right >= rm) - { - RECT tr={max(rm,updr.left),max(updr.top,0),updr.right,updr.bottom}; - FillRect(hdc,&tr,bgbrushes[0]); - } - if (updr.bottom >= bm) - { - RECT tr={max(0,updr.left),max(updr.top,bm),updr.right,updr.bottom}; - FillRect(hdc,&tr,bgbrushes[0]); - } - - for(y=0;ym_hwnd || !ctx->m_need_fontcalc) return; - - HDC hdc = hdcIn; - if (!hdc) hdc = GetDC(ctx->m_hwnd); - - if (!hdc) return; - - ctx->m_need_fontcalc=false; - HGDIOBJ oldf=SelectObject(hdc,ctx->mOurFont); - TEXTMETRIC tm; - GetTextMetrics(hdc,&tm); - ctx->m_font_h=tm.tmHeight; - ctx->m_font_w=tm.tmAveCharWidth; - SelectObject(hdc,oldf); - - if (hdc != hdcIn) ReleaseDC(ctx->m_hwnd,hdc); - -} - -static void reInitializeContext(win32CursesCtx *ctx) -{ - if (!ctx->mOurFont) ctx->mOurFont = CreateFont( -#ifdef _WIN32 - 16, -#else -#ifdef __LP64__ - 14, -#else - 13, -#endif -#endif - 0, // width - 0, // escapement - 0, // orientation -#ifdef _WIN32 - FW_NORMAL, // normal -#else - FW_BOLD, -#endif - FALSE, //italic - FALSE, //undelrine - FALSE, //strikeout - ANSI_CHARSET, - OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, - NONANTIALIASED_QUALITY,//DEFAULT_QUALITY, -#ifdef _WIN32 - FF_MODERN, -#else - 0, -#endif - "Courier New"); - - ctx->m_need_fontcalc=true; - ctx->m_font_w=8; - ctx->m_font_h=8; - doFontCalc(ctx,NULL); -} - - - - -void __initscr(win32CursesCtx *ctx) -{ - __init_pair(ctx,0,RGB(192,192,192),RGB(0,0,0)); -} - -void __endwin(win32CursesCtx *ctx) -{ - if (ctx->m_hwnd) - curses_setWindowContext(ctx->m_hwnd,0); - ctx->m_hwnd=0; - free(ctx->m_framebuffer); - ctx->m_framebuffer=0; - delete ctx->m_kbq; - ctx->m_kbq=0; - if (ctx->mOurFont) DeleteObject(ctx->mOurFont); - ctx->mOurFont=0; - -} - - -int curses_getch(win32CursesCtx *ctx) -{ - if (!ctx->m_hwnd) return ERR; - - -#ifndef WIN32_CONSOLE_KBQUEUE - // if we're suppose to run the message pump ourselves (optional!) - MSG msg; - while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) - { - TranslateMessage(&msg); - int a=xlateKey(msg.message,msg.wParam,msg.lParam); - if (a != ERR) return a; - - DispatchMessage(&msg); - - } -#else - -#ifdef _WIN32 - if (ctx->want_getch_runmsgpump>0) - { - MSG msg; - if (ctx->want_getch_runmsgpump>1) - { - while(!(ctx->m_kbq && ctx->m_kbq->Available()>=(int)sizeof(int)) && GetMessage(&msg,NULL,0,0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - else while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } -#endif - - if (ctx->m_kbq && ctx->m_kbq->Available()>=(int)sizeof(int)) - { - int a=*(int *) ctx->m_kbq->Get(); - ctx->m_kbq->Advance(sizeof(int)); - ctx->m_kbq->Compact(); - return a; - } -#endif - - if (ctx->m_need_redraw) - { - ctx->m_need_redraw=0; - InvalidateRect(ctx->m_hwnd,NULL,FALSE); - return 'L'-'A'+1; - } - - return ERR; -} - -void curses_setWindowContext(HWND hwnd, win32CursesCtx *ctx) -{ - SetWindowLongPtr(hwnd,GWLP_USERDATA,(INT_PTR)ctx); - if (ctx) - { - ctx->m_hwnd=hwnd; - delete ctx->m_kbq; - ctx->m_kbq=new WDL_Queue; - - free(ctx->m_framebuffer); - ctx->m_framebuffer=0; - - SetTimer(hwnd,CURSOR_BLINK_TIMER,CURSOR_BLINK_TIMER_MS,NULL); - reInitializeContext(ctx); - m_reinit_framebuffer(ctx); - InvalidateRect(hwnd,NULL,FALSE); - } -} - -static int m_regcnt; -void curses_unregisterChildClass(HINSTANCE hInstance) -{ -#ifdef _WIN32 - if (!--m_regcnt) - UnregisterClass(WIN32CURSES_CLASS_NAME,hInstance); -#endif -} - -void curses_registerChildClass(HINSTANCE hInstance) -{ -#ifdef _WIN32 - if (!m_regcnt++) - { - WNDCLASS wc={0,}; - wc.lpfnWndProc = cursesWindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.lpszClassName = WIN32CURSES_CLASS_NAME; - - RegisterClass(&wc); - } -#endif -} - -#ifndef _WIN32 -HWND curses_ControlCreator(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h) -{ - HWND hw=0; - if (!strcmp(classname,WIN32CURSES_CLASS_NAME)) - { - hw=CreateDialog(NULL,0,parent,(DLGPROC)cursesWindowProc); - } - - if (hw) - { - SetWindowLong(hw,GWL_ID,idx); - SetWindowPos(hw,HWND_TOP,x,y,w,h,SWP_NOZORDER|SWP_NOACTIVATE); - ShowWindow(hw,SW_SHOWNA); - return hw; - } - - return 0; -} - -#endif - -HWND curses_CreateWindow(HINSTANCE hInstance, win32CursesCtx *ctx, const char *title) -{ -#ifdef _WIN32 - ctx->m_hwnd = CreateWindowEx(0,WIN32CURSES_CLASS_NAME, title,WS_CAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX|WS_SYSMENU, - CW_USEDEFAULT,CW_USEDEFAULT,640,480, - NULL, NULL,hInstance,NULL); -#else - ctx->m_hwnd = CreateDialog(NULL,0,NULL,(DLGPROC)cursesWindowProc); - -#endif - if (ctx->m_hwnd) - { - curses_setWindowContext(ctx->m_hwnd,ctx); - ShowWindow(ctx->m_hwnd,SW_SHOW); - } - return ctx->m_hwnd; -} diff --git a/WDL/win32_curses/test.cpp b/WDL/win32_curses/test.cpp deleted file mode 100644 index 6be8ff80..00000000 --- a/WDL/win32_curses/test.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "curses.h" - -#ifdef _WIN32 -win32CursesCtx g_curses_context; // we only need the one instance -#endif - -#ifdef _WIN32 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - g_curses_context.want_getch_runmsgpump = 1; // non-block - - curses_registerChildClass(hInstance); - curses_CreateWindow(hInstance,&g_curses_context,"Sample Test App"); -#else -int main() { -#endif - - - initscr(); - cbreak(); - noecho(); - nonl(); - intrflush(stdscr,FALSE); - keypad(stdscr,TRUE); - nodelay(stdscr,TRUE); - raw(); -#if !defined(_WIN32) && !defined(MAC_NATIVE) - ESCDELAY=0; // dont wait--at least on the console this seems to work. -#endif - - if (has_colors()) // we don't use color yet, but we could - { - start_color(); - init_pair(1, COLOR_WHITE, COLOR_BLUE); // normal status lines - init_pair(2, COLOR_BLACK, COLOR_CYAN); // value - } - - erase(); - refresh(); - - float xpos=0,ypos=0, xdir=0.7, ydir=1.5; - for (;;) - { - int t=getch(); - if (t==27) break; - else if (t== KEY_LEFT) xdir *=0.9; - else if (t== KEY_RIGHT) xdir *=1.1; - else if (t== KEY_UP) ydir *=1.1; - else if (t== KEY_DOWN) ydir *=0.9; - - xpos+=xdir; ypos+=ydir; - if (xpos >= COLS-1||xpos<1) { if (xpos<1)xpos=1; else xpos=COLS-1; xdir=-xdir; } - if (ypos >= LINES-1||ypos<1) { if (ypos<1)ypos=1; else ypos=LINES-1; ydir=-ydir; } - - erase(); - mvaddstr(ypos,xpos,"X"); - - - Sleep(10); -#ifdef _WIN32 - if (!g_curses_context.m_hwnd) break; -#endif - } - - - erase(); - refresh(); - endwin(); - -#ifdef _WIN32 - if (g_curses_context.m_hwnd) DestroyWindow(g_curses_context.m_hwnd); - curses_unregisterChildClass(hInstance); -#endif - - return 0; - - -} - - - diff --git a/WDL/win32_utf8.c b/WDL/win32_utf8.c deleted file mode 100644 index 7bebea52..00000000 --- a/WDL/win32_utf8.c +++ /dev/null @@ -1,984 +0,0 @@ -#include "win32_utf8.h" -#include "wdltypes.h" - -#ifdef _WIN32 - -#if !defined(WDL_NO_SUPPORT_UTF8) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef WDL_UTF8_MAXFNLEN -#define WDL_UTF8_MAXFNLEN 2048 -#endif - -#define MBTOWIDE(symbase, src) \ - int symbase##_size; \ - WCHAR symbase##_buf[1024]; \ - WCHAR *symbase = (symbase##_size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,NULL,0)) >= 1000 ? (WCHAR *)malloc(symbase##_size * sizeof(WCHAR) + 10) : symbase##_buf; \ - int symbase##_ok = symbase ? (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,symbase,symbase##_size < 1 ? 1024 : symbase##_size)) : 0 - -#define MBTOWIDE_FREE(symbase) if (symbase != symbase##_buf) free(symbase) - - -#define WIDETOMB_ALLOC(symbase, length) \ - WCHAR symbase##_buf[1024]; \ - int symbase##_size = sizeof(symbase##_buf); \ - WCHAR *symbase = length > 1000 ? (WCHAR *)malloc(symbase##_size = (sizeof(WCHAR)*length + 10)) : symbase##_buf - -#define WIDETOMB_FREE(symbase) if (symbase != symbase##_buf) free(symbase) - -BOOL WDL_HasUTF8(const char *_str) -{ - const unsigned char *str = (const unsigned char *)_str; - BOOL hasUTF=FALSE; - - if (str) while (*str) - { - unsigned char c = *str++; - if (c<0x80) { } // allow 7 bit ascii straight through - else if (c < 0xC2 || c > 0xF7) return FALSE; // treat overlongs or other values in this range as indicators of non-utf8ness - else - { - hasUTF=TRUE; - if (str[0] < 0x80 || str[0] > 0xBF) return FALSE; - else if (c < 0xE0) str++; - else if (str[1] < 0x80 || str[1] > 0xBF) return FALSE; - else if (c < 0xF0) str+=2; - else if (str[2] < 0x80 || str[2] > 0xBF) return FALSE; - else str+=3; - } - } - return hasUTF; -} - -int GetWindowTextUTF8(HWND hWnd, LPTSTR lpString, int nMaxCount) -{ - if (lpString && nMaxCount>0 && GetVersion()< 0x80000000) - { - int alloc_size=nMaxCount; - - // prevent large values of nMaxCount from allocating memory unless the underlying text is big too - if (alloc_size > 512) - { - int l=GetWindowTextLengthW(hWnd); - if (l>=0 && l < 512) alloc_size=1000; - } - - { - WIDETOMB_ALLOC(wbuf, alloc_size); - if (wbuf) - { - GetWindowTextW(hWnd,wbuf,wbuf_size/sizeof(WCHAR)); - - if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpString,nMaxCount,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - lpString[nMaxCount-1]=0; - - WIDETOMB_FREE(wbuf); - - return strlen(lpString); - } - } - } - return GetWindowTextA(hWnd,lpString,nMaxCount); -} - -UINT GetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount) -{ - HWND h = GetDlgItem(hDlg,nIDDlgItem); - if (h) return GetWindowTextUTF8(h,lpString,nMaxCount); - return 0; -} - - -BOOL SetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPCTSTR lpString) -{ - HWND h = GetDlgItem(hDlg,nIDDlgItem); - if (h) return SetWindowTextUTF8(h,lpString); - return FALSE; -} - -BOOL SetWindowTextUTF8(HWND hwnd, LPCTSTR str) -{ - if (WDL_HasUTF8(str) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - BOOL rv=SetWindowTextW(hwnd,wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - - MBTOWIDE_FREE(wbuf); - } - - return SetWindowTextA(hwnd,str); -} - -int MessageBoxUTF8(HWND hwnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT fl) -{ - if ((WDL_HasUTF8(lpText)||WDL_HasUTF8(lpCaption)) && GetVersion()< 0x80000000) - { - int ret; - MBTOWIDE(wbuf,lpText); - if (wbuf_ok) - { - MBTOWIDE(wcap,lpCaption?lpCaption:""); - if (wcap_ok) - { - ret=MessageBoxW(hwnd,wbuf,lpCaption?wcap:NULL,fl); - MBTOWIDE_FREE(wcap); - MBTOWIDE_FREE(wbuf); - return ret; - } - MBTOWIDE_FREE(wbuf); - } - } - return MessageBoxA(hwnd,lpText,lpCaption,fl); -} - -int DragQueryFileUTF8(HDROP hDrop, int idx, char *buf, int bufsz) -{ - if (buf && bufsz && idx!=-1 && GetVersion()< 0x80000000) - { - int reqsz = DragQueryFileW(hDrop,idx,NULL,0)+32; - WIDETOMB_ALLOC(wbuf, reqsz); - if (wbuf) - { - int rv=DragQueryFileW(hDrop,idx,wbuf,wbuf_size/sizeof(WCHAR)); - if (rv) - { - if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,buf,bufsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - buf[bufsz-1]=0; - } - WIDETOMB_FREE(wbuf); - return rv; - } - } - return DragQueryFileA(hDrop,idx,buf,bufsz); -} - - -WCHAR *WDL_UTF8ToWC(const char *buf, BOOL doublenull, int minsize, DWORD *sizeout) -{ - if (doublenull) - { - int sz=1; - const char *p = (const char *)buf; - WCHAR *pout,*ret; - - while (*p) - { - int a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,p,-1,NULL,0); - int sp=strlen(p)+1; - if (a < sp)a=sp; // in case it needs to be ansi mapped - sz+=a; - p+=sp; - } - if (sz < minsize) sz=minsize; - - pout = (WCHAR *) malloc(sizeof(WCHAR)*(sz+4)); - ret=pout; - p = (const char *)buf; - while (*p) - { - int a; - *pout=0; - a = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,p,-1,pout,sz-(pout-ret)); - if (!a) - { - pout[0]=0; - a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,p,-1,pout,sz-(pout-ret)); - } - pout += a; - p+=strlen(p)+1; - } - *pout=0; - pout[1]=0; - if (sizeout) *sizeout=sz; - return ret; - } - else - { - int srclen = strlen(buf)+1; - int size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,buf,srclen,NULL,0); - if (size < srclen)size=srclen; // for ansi code page - if (size1) - { - a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,buf,srclen,outbuf, size); - if (!a) - { - outbuf[0]=0; - a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,buf,srclen,outbuf,size); - } - } - if (sizeout) *sizeout = size; - return outbuf; - } - } -} - -static BOOL GetOpenSaveFileNameUTF8(LPOPENFILENAME lpofn, BOOL save) -{ - - OPENFILENAMEW tmp={sizeof(tmp),lpofn->hwndOwner,lpofn->hInstance,}; - BOOL ret; - - // allocate, convert input - if (lpofn->lpstrFilter) tmp.lpstrFilter = WDL_UTF8ToWC(lpofn->lpstrFilter,TRUE,0,0); - tmp.nFilterIndex = lpofn->nFilterIndex ; - - if (lpofn->lpstrFile) tmp.lpstrFile = WDL_UTF8ToWC(lpofn->lpstrFile,FALSE,lpofn->nMaxFile,&tmp.nMaxFile); - if (lpofn->lpstrFileTitle) tmp.lpstrFileTitle = WDL_UTF8ToWC(lpofn->lpstrFileTitle,FALSE,lpofn->nMaxFileTitle,&tmp.nMaxFileTitle); - if (lpofn->lpstrInitialDir) tmp.lpstrInitialDir = WDL_UTF8ToWC(lpofn->lpstrInitialDir,0,0,0); - if (lpofn->lpstrTitle) tmp.lpstrTitle = WDL_UTF8ToWC(lpofn->lpstrTitle,0,0,0); - if (lpofn->lpstrDefExt) tmp.lpstrDefExt = WDL_UTF8ToWC(lpofn->lpstrDefExt,0,0,0); - tmp.Flags = lpofn->Flags; - tmp.lCustData = lpofn->lCustData; - tmp.lpfnHook = lpofn->lpfnHook; - tmp.lpTemplateName = (const WCHAR *)lpofn->lpTemplateName ; - - ret=save ? GetSaveFileNameW(&tmp) : GetOpenFileNameW(&tmp); - - // free, convert output - if (ret) - { - if ((tmp.Flags & OFN_ALLOWMULTISELECT) && tmp.lpstrFile[wcslen(tmp.lpstrFile)+1]) - { - char *op = lpofn->lpstrFile; - WCHAR *ip = tmp.lpstrFile; - while (*ip) - { - int bcount = WideCharToMultiByte(CP_UTF8,0,ip,-1,NULL,0,NULL,NULL); - - int maxout=lpofn->nMaxFile -2 - (op - lpofn->lpstrFile); - if (maxout < 2+bcount) break; - op += WideCharToMultiByte(CP_UTF8,0,ip,-1,op,maxout,NULL,NULL); - ip += wcslen(ip)+1; - } - *op=0; - } - else - { - int len = WideCharToMultiByte(CP_UTF8,0,tmp.lpstrFile,-1,lpofn->lpstrFile,lpofn->nMaxFile-1,NULL,NULL); - if (len == 0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER) len = lpofn->nMaxFile-2; - lpofn->lpstrFile[len]=0; - if (!len) - { - lpofn->lpstrFile[len+1]=0; - ret=0; - } - } - // convert - } - - lpofn->nFileOffset = tmp.nFileOffset ; - lpofn->nFileExtension = tmp.nFileExtension; - lpofn->lCustData = tmp.lCustData; - - free((WCHAR *)tmp.lpstrFilter); - free((WCHAR *)tmp.lpstrFile); - free((WCHAR *)tmp.lpstrFileTitle); - free((WCHAR *)tmp.lpstrInitialDir); - free((WCHAR *)tmp.lpstrTitle); - free((WCHAR *)tmp.lpstrDefExt ); - - lpofn->nFilterIndex = tmp.nFilterIndex ; - return ret; -} - -BOOL GetOpenFileNameUTF8(LPOPENFILENAME lpofn) -{ - if (GetVersion()< 0x80000000) return GetOpenSaveFileNameUTF8(lpofn,FALSE); - return GetOpenFileNameA(lpofn); -} - -BOOL GetSaveFileNameUTF8(LPOPENFILENAME lpofn) -{ - if (GetVersion()< 0x80000000)return GetOpenSaveFileNameUTF8(lpofn,TRUE); - return GetSaveFileNameA(lpofn); -} - - -BOOL SetCurrentDirectoryUTF8(LPCTSTR path) -{ - if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,path); - if (wbuf_ok) - { - BOOL rv=SetCurrentDirectoryW(wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return SetCurrentDirectoryA(path); -} - -BOOL RemoveDirectoryUTF8(LPCTSTR path) -{ - if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,path); - if (wbuf_ok) - { - BOOL rv=RemoveDirectoryW(wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return RemoveDirectoryA(path); -} - -HINSTANCE LoadLibraryUTF8(LPCTSTR path) -{ - if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,path); - if (wbuf_ok) - { - HINSTANCE rv=LoadLibraryW(wbuf); - if (rv) - { - MBTOWIDE_FREE(wbuf); - return rv; - } - } - MBTOWIDE_FREE(wbuf); - } - return LoadLibraryA(path); -} - -BOOL CreateDirectoryUTF8(LPCTSTR path, LPSECURITY_ATTRIBUTES attr) -{ - if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,path); - if (wbuf_ok) - { - BOOL rv=CreateDirectoryW(wbuf,attr); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return CreateDirectoryA(path,attr); -} - -BOOL DeleteFileUTF8(LPCTSTR path) -{ - if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,path); - if (wbuf_ok) - { - BOOL rv=DeleteFileW(wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return DeleteFileA(path); -} - -BOOL MoveFileUTF8(LPCTSTR existfn, LPCTSTR newfn) -{ - if ((WDL_HasUTF8(existfn)||WDL_HasUTF8(newfn)) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,existfn); - if (wbuf_ok) - { - MBTOWIDE(wbuf2,newfn); - if (wbuf2_ok) - { - int rv=MoveFileW(wbuf,wbuf2); - MBTOWIDE_FREE(wbuf2); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf2); - } - MBTOWIDE_FREE(wbuf); - } - return MoveFileA(existfn,newfn); -} - -BOOL CopyFileUTF8(LPCTSTR existfn, LPCTSTR newfn, BOOL fie) -{ - if ((WDL_HasUTF8(existfn)||WDL_HasUTF8(newfn)) && GetVersion()< 0x80000000) - { - MBTOWIDE(wbuf,existfn); - if (wbuf_ok) - { - MBTOWIDE(wbuf2,newfn); - if (wbuf2_ok) - { - int rv=CopyFileW(wbuf,wbuf2,fie); - MBTOWIDE_FREE(wbuf2); - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf2); - } - MBTOWIDE_FREE(wbuf); - } - return CopyFileA(existfn,newfn,fie); -} - -DWORD GetCurrentDirectoryUTF8(DWORD nBufferLength, LPTSTR lpBuffer) -{ - if (lpBuffer && nBufferLength > 1 && GetVersion()< 0x80000000) - { - - WCHAR wbuf[WDL_UTF8_MAXFNLEN]; - wbuf[0]=0; - GetCurrentDirectoryW(WDL_UTF8_MAXFNLEN,wbuf); - if (wbuf[0]) - { - int rv=WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpBuffer,nBufferLength,NULL,NULL); - if (rv) return rv; - } - } - return GetCurrentDirectoryA(nBufferLength,lpBuffer); -} - -HANDLE CreateFileUTF8(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) -{ - if (WDL_HasUTF8(lpFileName) && GetVersion()<0x80000000) - { - HANDLE h = INVALID_HANDLE_VALUE; - - MBTOWIDE(wstr, lpFileName); - if (wstr_ok) h = CreateFileW(wstr,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); - MBTOWIDE_FREE(wstr); - - if (h != INVALID_HANDLE_VALUE) return h; - } - return CreateFileA(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); -} - - -int DrawTextUTF8(HDC hdc, LPCTSTR str, int nc, LPRECT lpRect, UINT format) -{ - if (WDL_HasUTF8(str) && GetVersion()<0x80000000) - { - if (nc<0) nc=strlen(str); - - { - MBTOWIDE(wstr, str); - if (wstr_ok) - { - int rv=DrawTextW(hdc,wstr,-1,lpRect,format);; - MBTOWIDE_FREE(wstr); - return rv; - } - MBTOWIDE_FREE(wstr); - } - - } - return DrawTextA(hdc,str,nc,lpRect,format); -} - - -BOOL InsertMenuUTF8(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR str) -{ - if (!(uFlags&(MF_BITMAP|MF_SEPARATOR)) && str && WDL_HasUTF8(str) && GetVersion()<0x80000000) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - BOOL rv=InsertMenuW(hMenu,uPosition,uFlags,uIDNewItem,wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - } - return InsertMenuA(hMenu,uPosition,uFlags,uIDNewItem,str); -} - -BOOL InsertMenuItemUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) -{ - if (lpmii && (lpmii->fMask & MIIM_TYPE) && (lpmii->fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING && lpmii->dwTypeData && WDL_HasUTF8(lpmii->dwTypeData) && GetVersion()<0x80000000) - { - BOOL rv; - MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; - MBTOWIDE(wbuf,lpmii->dwTypeData); - if (wbuf_ok) - { - - tmp.cbSize=sizeof(tmp); - tmp.dwTypeData = wbuf; - rv=InsertMenuItemW(hMenu,uItem,fByPosition,&tmp); - - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return InsertMenuItemA(hMenu,uItem,fByPosition,lpmii); -} -BOOL SetMenuItemInfoUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) -{ - if (lpmii && (lpmii->fMask & MIIM_TYPE) && (lpmii->fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING && lpmii->dwTypeData && WDL_HasUTF8(lpmii->dwTypeData) && GetVersion()<0x80000000) - { - BOOL rv; - MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; - MBTOWIDE(wbuf,lpmii->dwTypeData); - if (wbuf_ok) - { - tmp.cbSize=sizeof(tmp); - tmp.dwTypeData = wbuf; - rv=SetMenuItemInfoW(hMenu,uItem,fByPosition,&tmp); - - MBTOWIDE_FREE(wbuf); - return rv; - } - MBTOWIDE_FREE(wbuf); - } - return SetMenuItemInfoA(hMenu,uItem,fByPosition,lpmii); -} - -BOOL GetMenuItemInfoUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) -{ - if (lpmii && (lpmii->fMask & MIIM_TYPE) && lpmii->dwTypeData && lpmii->cch && GetVersion()<0x80000000) - { - MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; - WIDETOMB_ALLOC(wbuf,lpmii->cch); - - if (wbuf) - { - BOOL rv; - char *otd=lpmii->dwTypeData; - int osz=lpmii->cbSize; - tmp.cbSize=sizeof(tmp); - tmp.dwTypeData = wbuf; - tmp.cch = wbuf_size/sizeof(WCHAR); - rv=GetMenuItemInfoW(hMenu,uItem,fByPosition,&tmp); - - if (rv && (tmp.fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING) - { - if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpmii->dwTypeData,lpmii->cch,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - { - lpmii->dwTypeData[lpmii->cch-1]=0; - } - - *lpmii = *(MENUITEMINFO*)&tmp; // copy results - lpmii->cbSize=osz; // restore old stuff - lpmii->dwTypeData = otd; - } - else rv=0; - - WIDETOMB_FREE(wbuf); - if (rv)return rv; - } - } - return GetMenuItemInfoA(hMenu,uItem,fByPosition,lpmii); -} - - -FILE *fopenUTF8(const char *filename, const char *mode) -{ - if (WDL_HasUTF8(filename) && GetVersion()<0x80000000) - { - MBTOWIDE(wbuf,filename); - if (wbuf_ok) - { - FILE *rv; - WCHAR tb[32]; - tb[0]=0; - MultiByteToWideChar(CP_UTF8,0,mode,-1,tb,32); - rv=tb[0] ? _wfopen(wbuf,tb) : NULL; - MBTOWIDE_FREE(wbuf); - if (rv) return rv; - } - } - return fopen(filename,mode); -} - -int statUTF8(const char *filename, struct stat *buffer) -{ - if (WDL_HasUTF8(filename) && GetVersion()<0x80000000) - { - MBTOWIDE(wbuf,filename); - if (wbuf_ok) - { - int rv=_wstat(wbuf,(struct _stat*)buffer); - MBTOWIDE_FREE(wbuf); - if (!rv) return rv; - } - else - { - MBTOWIDE_FREE(wbuf); - } - } - return stat(filename,buffer); -} - -LPSTR GetCommandParametersUTF8() -{ - char *buf; - int szneeded; - LPWSTR w=GetCommandLineW(); - if (!w) return NULL; - szneeded = WideCharToMultiByte(CP_UTF8,0,w,-1,NULL,0,NULL,NULL); - if (szneeded<1) return NULL; - buf = (char *)malloc(szneeded+10); - if (!buf) return NULL; - if (WideCharToMultiByte(CP_UTF8,0,w,-1,buf,szneeded+9,NULL,NULL)<1) return NULL; - while (*buf == ' ') buf++; - if (*buf == '\"') - { - buf++; - while (*buf && *buf != '\"') buf++; - } - else - { - while (*buf && *buf != ' ') buf++; - } - if (*buf) buf++; - while (*buf == ' ') buf++; - if (*buf) return buf; - - return NULL; -} - - -HINSTANCE ShellExecuteUTF8(HWND hwnd, LPCTSTR lpOp, LPCTSTR lpFile, LPCTSTR lpParm, LPCTSTR lpDir, INT nShowCmd) -{ - if (GetVersion()<0x80000000 && (WDL_HasUTF8(lpOp)||WDL_HasUTF8(lpFile)||WDL_HasUTF8(lpParm)||WDL_HasUTF8(lpDir))) - { - DWORD sz; - WCHAR *p1=lpOp ? WDL_UTF8ToWC(lpOp,0,0,&sz) : NULL; - WCHAR *p2=lpFile ? WDL_UTF8ToWC(lpFile,0,0,&sz) : NULL; - WCHAR *p3=lpParm ? WDL_UTF8ToWC(lpParm,0,0,&sz) : NULL; - WCHAR *p4=lpDir ? WDL_UTF8ToWC(lpDir,0,0,&sz) : NULL; - HINSTANCE rv= ShellExecuteW(hwnd,p1,p2,p3,p4,nShowCmd); - free(p1); - free(p2); - free(p3); - free(p4); - return rv; - } - return ShellExecuteA(hwnd,lpOp,lpFile,lpParm,lpDir,nShowCmd); -} - -#if defined(WDL_WIN32_UTF8_IMPL_NOTSTATIC) || defined(WDL_WIN32_UTF8_IMPL_STATICHOOKS) - - -#define WDL_UTF8_OLDPROCPROP "WDLUTF8OldProc" - -static LRESULT WINAPI cb_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); - if (!oldproc) return 0; - - if (msg==WM_NCDESTROY) - { - SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); - RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); - RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); - } - else if (msg == CB_ADDSTRING || msg == CB_INSERTSTRING || msg == LB_ADDSTRING || msg == LB_INSERTSTRING) - { - char *str=(char*)lParam; - if (lParam && WDL_HasUTF8(str)) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); - LRESULT rv=CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,(LPARAM)wbuf); - MBTOWIDE_FREE(wbuf); - return rv; - } - - MBTOWIDE_FREE(wbuf); - } - } - else if (msg == CB_GETLBTEXT && lParam) - { - WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); - int l = CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,CB_GETLBTEXTLEN,wParam,0)+1; - WIDETOMB_ALLOC(tmp,l); - if (tmp) - { - int rv=CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,(LPARAM)tmp)+1; - if (rv>=0) - { - *(char *)lParam=0; - rv=WideCharToMultiByte(CP_UTF8,0,tmp,-1,(char *)lParam,l*3 + 32,NULL,NULL); - if (rv>0) rv--; - } - WIDETOMB_FREE(tmp); - - return rv; - } - } - else if (msg == CB_GETLBTEXTLEN) - { - WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); - return CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,lParam) * 3 + 32; // make sure caller allocates a lot extra - } - - return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); -} - -void WDL_UTF8_HookComboBox(HWND h) -{ - if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; - SetProp(h,WDL_UTF8_OLDPROCPROP "W",(HANDLE)GetWindowLongPtrW(h,GWLP_WNDPROC)); - SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)cb_newProc)); -} - -void WDL_UTF8_HookListBox(HWND h) -{ - WDL_UTF8_HookComboBox(h); -} - -static LRESULT WINAPI tc_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); - if (!oldproc) return 0; - - if (msg==WM_NCDESTROY) - { - SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); - RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); - } - else if (msg == TCM_INSERTITEMA) - { - LPTCITEM pItem = (LPTCITEM) lParam; - char *str; - if (pItem && (str=pItem->pszText) && (pItem->mask&TCIF_TEXT) && WDL_HasUTF8(str)) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - LRESULT rv; - pItem->pszText=(char*)wbuf; // set new buffer - rv=CallWindowProc(oldproc,hwnd,TCM_INSERTITEMW,wParam,lParam); - pItem->pszText = str; // restore old pointer - MBTOWIDE_FREE(wbuf); - return rv; - } - - MBTOWIDE_FREE(wbuf); - } - } - - - return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); -} - - -static LRESULT WINAPI tv_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); - if (!oldproc) return 0; - - if (msg==WM_NCDESTROY) - { - SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); - RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); - } - else if (msg == TVM_INSERTITEMA || msg == TVM_SETITEMA) - { - LPTVITEM pItem = msg == TVM_INSERTITEMA ? &((LPTVINSERTSTRUCT)lParam)->item : (LPTVITEM) lParam; - char *str; - if (pItem && (str=pItem->pszText) && (pItem->mask&TVIF_TEXT) && WDL_HasUTF8(str)) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - LRESULT rv; - pItem->pszText=(char*)wbuf; // set new buffer - rv=CallWindowProc(oldproc,hwnd,msg == TVM_INSERTITEMA ? TVM_INSERTITEMW : TVM_SETITEMW,wParam,lParam); - pItem->pszText = str; // restore old pointer - MBTOWIDE_FREE(wbuf); - return rv; - } - - MBTOWIDE_FREE(wbuf); - } - } - else if (msg==TVM_GETITEMA) - { - LPTVITEM pItem = (LPTVITEM) lParam; - char *obuf; - if (pItem && (pItem->mask & TVIF_TEXT) && (obuf=pItem->pszText) && pItem->cchTextMax > 3) - { - WIDETOMB_ALLOC(wbuf,pItem->cchTextMax); - if (wbuf) - { - LRESULT rv; - int oldsz=pItem->cchTextMax; - *wbuf=0; - *obuf=0; - pItem->cchTextMax=wbuf_size/sizeof(WCHAR); - pItem->pszText = (char *)wbuf; - rv=CallWindowProc(oldproc,hwnd,TVM_GETITEMW,wParam,lParam); - - if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,obuf,oldsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - obuf[oldsz-1]=0; - - pItem->cchTextMax=oldsz; - pItem->pszText=obuf; - WIDETOMB_FREE(wbuf); - - if (obuf[0]) return rv; - } - } - } - - return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); -} - -static LRESULT WINAPI lv_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); - if (!oldproc) return 0; - - if (msg==WM_NCDESTROY) - { - SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); - RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); - } - else if (msg == LVM_INSERTCOLUMNA || msg==LVM_SETCOLUMNA) - { - LPLVCOLUMNA pCol = (LPLVCOLUMNA) lParam; - char *str; - if (pCol && (str=pCol->pszText) && (pCol->mask & LVCF_TEXT) && WDL_HasUTF8(str)) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - LRESULT rv; - pCol->pszText=(char*)wbuf; // set new buffer - rv=CallWindowProc(oldproc,hwnd,msg==LVM_INSERTCOLUMNA?LVM_INSERTCOLUMNW:LVM_SETCOLUMNW,wParam,lParam); - pCol->pszText = str; // restore old pointer - MBTOWIDE_FREE(wbuf); - return rv; - } - - } - } - else if (msg == LVM_INSERTITEMA || msg == LVM_SETITEMA || msg == LVM_SETITEMTEXTA) - { - LPLVITEMA pItem = (LPLVITEMA) lParam; - char *str; - if (pItem && (str=pItem->pszText) && (msg==LVM_SETITEMTEXTA || (pItem->mask&LVIF_TEXT)) && WDL_HasUTF8(str)) - { - MBTOWIDE(wbuf,str); - if (wbuf_ok) - { - LRESULT rv; - pItem->pszText=(char*)wbuf; // set new buffer - rv=CallWindowProc(oldproc,hwnd,msg == LVM_INSERTITEMA ? LVM_INSERTITEMW : msg == LVM_SETITEMA ? LVM_SETITEMW : LVM_SETITEMTEXTW,wParam,lParam); - pItem->pszText = str; // restore old pointer - MBTOWIDE_FREE(wbuf); - return rv; - } - - MBTOWIDE_FREE(wbuf); - } - } - else if (msg==LVM_GETITEMA||msg==LVM_GETITEMTEXTA) - { - LPLVITEMA pItem = (LPLVITEMA) lParam; - char *obuf; - if (pItem && (msg == LVM_GETITEMTEXTA || (pItem->mask & LVIF_TEXT)) && (obuf=pItem->pszText) && pItem->cchTextMax > 3) - { - WIDETOMB_ALLOC(wbuf,pItem->cchTextMax); - if (wbuf) - { - LRESULT rv; - int oldsz=pItem->cchTextMax; - *wbuf=0; - *obuf=0; - pItem->cchTextMax=wbuf_size/sizeof(WCHAR); - pItem->pszText = (char *)wbuf; - rv=CallWindowProc(oldproc,hwnd,msg==LVM_GETITEMTEXTA ? LVM_GETITEMTEXTW : LVM_GETITEMW,wParam,lParam); - - if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,obuf,oldsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - obuf[oldsz-1]=0; - - pItem->cchTextMax=oldsz; - pItem->pszText=obuf; - WIDETOMB_FREE(wbuf); - - if (obuf[0]) return rv; - } - } - } - - return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); -} - -void WDL_UTF8_HookListView(HWND h) -{ - if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; - SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)lv_newProc)); -} - -void WDL_UTF8_HookTreeView(HWND h) -{ - if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; - SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)tv_newProc)); -} - -void WDL_UTF8_HookTabCtrl(HWND h) -{ - if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; - SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)tc_newProc)); -} - -void WDL_UTF8_ListViewConvertDispInfoToW(void *_di) -{ - NMLVDISPINFO *di = (NMLVDISPINFO *)_di; - if (di && (di->item.mask & LVIF_TEXT) && di->item.pszText && di->item.cchTextMax>0) - { - char tmp_buf[1024], *tmp=tmp_buf; - char *src = di->item.pszText; - - if (strlen(src) < 1024) strcpy(tmp,src); - else tmp = strdup(src); - - if (!MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,tmp,-1,(LPWSTR)di->item.pszText,di->item.cchTextMax)) - { - if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) - { - ((WCHAR *)di->item.pszText)[di->item.cchTextMax-1] = 0; - } - else - { - if (!MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,tmp,-1,(LPWSTR)di->item.pszText,di->item.cchTextMax) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) - ((WCHAR *)di->item.pszText)[di->item.cchTextMax-1] = 0; - } - } - - if (tmp!=tmp_buf) free(tmp); - - } -} - -#endif - -#ifdef __cplusplus -}; -#endif - -#endif - -#endif //_WIN32 diff --git a/WDL/win32_utf8.h b/WDL/win32_utf8.h deleted file mode 100644 index 091c9bbd..00000000 --- a/WDL/win32_utf8.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef _WDL_WIN32_UTF8_H_ -#define _WDL_WIN32_UTF8_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) - -#ifndef WDL_WIN32_UTF8_IMPL -#define WDL_WIN32_UTF8_IMPL -#define WDL_WIN32_UTF8_IMPL_NOTSTATIC -#endif - -#include -#include -#include - -WDL_WIN32_UTF8_IMPL BOOL SetWindowTextUTF8(HWND hwnd, LPCTSTR str); -WDL_WIN32_UTF8_IMPL BOOL SetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPCTSTR lpString); -WDL_WIN32_UTF8_IMPL int GetWindowTextUTF8(HWND hWnd, LPTSTR lpString, int nMaxCount); -WDL_WIN32_UTF8_IMPL UINT GetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount); -WDL_WIN32_UTF8_IMPL int MessageBoxUTF8(HWND hwnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT fl); - -WDL_WIN32_UTF8_IMPL BOOL CreateDirectoryUTF8(LPCTSTR path, LPSECURITY_ATTRIBUTES attr); -WDL_WIN32_UTF8_IMPL BOOL DeleteFileUTF8(LPCTSTR path); -WDL_WIN32_UTF8_IMPL BOOL MoveFileUTF8(LPCTSTR existfn, LPCTSTR newfn); -WDL_WIN32_UTF8_IMPL BOOL CopyFileUTF8(LPCTSTR existfn, LPCTSTR newfn, BOOL fie); -WDL_WIN32_UTF8_IMPL DWORD GetCurrentDirectoryUTF8(DWORD nBufferLength, LPTSTR lpBuffer); -WDL_WIN32_UTF8_IMPL BOOL SetCurrentDirectoryUTF8(LPCTSTR path); -WDL_WIN32_UTF8_IMPL BOOL RemoveDirectoryUTF8(LPCTSTR path); -WDL_WIN32_UTF8_IMPL HINSTANCE LoadLibraryUTF8(LPCTSTR path); - -WDL_WIN32_UTF8_IMPL HANDLE CreateFileUTF8(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); - -WDL_WIN32_UTF8_IMPL int DragQueryFileUTF8(HDROP hDrop, int idx, char *buf, int bufsz); - -WDL_WIN32_UTF8_IMPL int DrawTextUTF8(HDC hdc, LPCTSTR str, int nc, LPRECT lpRect, UINT format); - -WDL_WIN32_UTF8_IMPL BOOL GetOpenFileNameUTF8(LPOPENFILENAME lpofn); -WDL_WIN32_UTF8_IMPL BOOL GetSaveFileNameUTF8(LPOPENFILENAME lpofn); - - -WDL_WIN32_UTF8_IMPL HINSTANCE ShellExecuteUTF8(HWND hwnd, LPCTSTR lpOp, LPCTSTR lpFile, LPCTSTR lpParm, LPCTSTR lpDir, INT nShowCmd); - -WDL_WIN32_UTF8_IMPL BOOL InsertMenuUTF8(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR str); -WDL_WIN32_UTF8_IMPL BOOL InsertMenuItemUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii); -WDL_WIN32_UTF8_IMPL BOOL SetMenuItemInfoUTF8(HMENU hMenu, UINT uItem, BOOL fByPosition,LPMENUITEMINFO lpmii); -WDL_WIN32_UTF8_IMPL BOOL GetMenuItemInfoUTF8(HMENU hMenu, UINT uItem,BOOL fByPosition,LPMENUITEMINFO lpmii); - -WDL_WIN32_UTF8_IMPL int statUTF8(const char *filename, struct stat *buffer); -WDL_WIN32_UTF8_IMPL FILE *fopenUTF8(const char *filename, const char *mode); - - -WDL_WIN32_UTF8_IMPL WCHAR *WDL_UTF8ToWC(const char *buf, BOOL doublenull, int minsize, DWORD *sizeout); - -WDL_WIN32_UTF8_IMPL BOOL WDL_HasUTF8(const char *_str); - -WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookComboBox(HWND h); -WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookListView(HWND h); -WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookListBox(HWND h); -WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookTreeView(HWND h); -WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookTabCtrl(HWND h); - -WDL_WIN32_UTF8_IMPL LPSTR GetCommandParametersUTF8(); -WDL_WIN32_UTF8_IMPL void WDL_UTF8_ListViewConvertDispInfoToW(void *di); //NMLVDISPINFO - -#ifdef SetWindowText -#undef SetWindowText -#endif -#define SetWindowText SetWindowTextUTF8 - -#ifdef SetDlgItemText -#undef SetDlgItemText -#endif -#define SetDlgItemText SetDlgItemTextUTF8 - - -#ifdef GetWindowText -#undef GetWindowText -#endif -#define GetWindowText GetWindowTextUTF8 - -#ifdef GetDlgItemText -#undef GetDlgItemText -#endif -#define GetDlgItemText GetDlgItemTextUTF8 - -#ifdef MessageBox -#undef MessageBox -#endif -#define MessageBox MessageBoxUTF8 - -#ifdef DragQueryFile -#undef DragQueryFile -#endif -#define DragQueryFile DragQueryFileUTF8 - -#ifdef GetOpenFileName -#undef GetOpenFileName -#endif -#define GetOpenFileName GetOpenFileNameUTF8 - -#ifdef GetSaveFileName -#undef GetSaveFileName -#endif -#define GetSaveFileName GetSaveFileNameUTF8 - -#ifdef ShellExecute -#undef ShellExecute -#endif -#define ShellExecute ShellExecuteUTF8 - - -#ifdef CreateDirectory -#undef CreateDirectory -#endif -#define CreateDirectory CreateDirectoryUTF8 - -#ifdef DeleteFile -#undef DeleteFile -#endif -#define DeleteFile DeleteFileUTF8 - -#ifdef MoveFile -#undef MoveFile -#endif -#define MoveFile MoveFileUTF8 - -#ifdef CopyFile -#undef CopyFile -#endif -#define CopyFile CopyFileUTF8 - -#ifdef GetCurrentDirectory -#undef GetCurrentDirectory -#endif -#define GetCurrentDirectory GetCurrentDirectoryUTF8 - -#ifdef SetCurrentDirectory -#undef SetCurrentDirectory -#endif -#define SetCurrentDirectory SetCurrentDirectoryUTF8 - - -#ifdef RemoveDirectory -#undef RemoveDirectory -#endif -#define RemoveDirectory RemoveDirectoryUTF8 - - -#ifdef CreateFile -#undef CreateFile -#endif -#define CreateFile CreateFileUTF8 - - -#ifdef InsertMenu -#undef InsertMenu -#endif -#define InsertMenu InsertMenuUTF8 - -#ifdef InsertMenuItem -#undef InsertMenuItem -#endif -#define InsertMenuItem InsertMenuItemUTF8 - -#ifdef SetMenuItemInfo -#undef SetMenuItemInfo -#endif -#define SetMenuItemInfo SetMenuItemInfoUTF8 - -#ifdef GetMenuItemInfo -#undef GetMenuItemInfo -#endif -#define GetMenuItemInfo GetMenuItemInfoUTF8 - -#ifdef LoadLibrary -#undef LoadLibrary -#endif -#define LoadLibrary LoadLibraryUTF8 - -#else - -// compat defines for when UTF disabled -#define DrawTextUTF8 DrawText -#define statUTF8 stat -#define fopenUTF8 fopen -#define WDL_UTF8_HookComboBox(x) -#define WDL_UTF8_HookListView(x) -#define WDL_UTF8_HookListBox(x) -#define WDL_UTF8_HookTreeView(x) -#define WDL_UTF8_HookTabCtrl(x) -#define WDL_UTF8_ListViewConvertDispInfoToW(x) - -#endif - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/WDL/win7filedialog.cpp b/WDL/win7filedialog.cpp deleted file mode 100644 index f212c990..00000000 --- a/WDL/win7filedialog.cpp +++ /dev/null @@ -1,507 +0,0 @@ -#include "win7filedialog.h" - -#include "ptrlist.h" -#include "win32_utf8.h" - - -Win7FileDialog::Win7FileDialog(const char *name, int issave) -{ - m_dlgid = 0; - m_inst = 0; - m_proc = NULL; - - if(!issave) - CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast(&m_fod)); - else - CoCreateInstance(__uuidof(FileSaveDialog), NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast(&m_fod)); - - if(m_fod != NULL) - { - m_fdc = m_fod; - -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[1024]; - mbstowcs(tmp, name, 1023); - tmp[1023]=0; - m_fod->SetTitle(tmp); -#else - WCHAR *tmp = WDL_UTF8ToWC(name, false, 0, NULL); - m_fod->SetTitle(tmp); - free(tmp); -#endif - } -} - -Win7FileDialog::~Win7FileDialog() -{ -} - -void Win7FileDialog::setFilterList(const char *list) -{ - //generate wchar filter list - WDL_PtrList wlist; - { - const char *p = list; - while(*p) - { -#if defined(WDL_NO_SUPPORT_UTF8) - int l = strlen(p); - WCHAR *n = (WCHAR*)malloc(sizeof(WCHAR)*(l+1)); - mbstowcs(n, p, l+1); - wlist.Add(n); -#else - wlist.Add(WDL_UTF8ToWC(p, false, 0, NULL)); -#endif - p+=strlen(p)+1; - } - } - m_fod->SetFileTypes(wlist.GetSize()/2, (_COMDLG_FILTERSPEC *)wlist.GetList()); - wlist.Empty(true,free); -} - -void Win7FileDialog::addOptions(DWORD o) -{ - DWORD fileOpenDialogOptions; - m_fod->GetOptions(&fileOpenDialogOptions); - fileOpenDialogOptions |= o; - m_fod->SetOptions(fileOpenDialogOptions); -} - -void Win7FileDialog::setDefaultExtension(const char *ext) -{ -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[1024]; - mbstowcs(tmp, ext, 1023); - tmp[1023]=0; - m_fod->SetDefaultExtension(tmp); -#else - WCHAR *tmp = WDL_UTF8ToWC(ext, false, 0, NULL); - m_fod->SetDefaultExtension(tmp); - free(tmp); -#endif -} - -void Win7FileDialog::setFileTypeIndex(int i) -{ - m_fod->SetFileTypeIndex(i); -} - -void Win7FileDialog::setFolder(const char *folder, int def) -{ - static HRESULT (WINAPI *my_SHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) = NULL; - if(!my_SHCreateItemFromParsingName) - { - HMODULE dll = LoadLibrary("shell32.dll"); - if(dll) - { - *((void **)(&my_SHCreateItemFromParsingName)) = (void *)GetProcAddress(dll, "SHCreateItemFromParsingName"); - } - } - if(!my_SHCreateItemFromParsingName) return; - -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[4096]; - mbstowcs(tmp, folder, 4095); - tmp[4095]=0; -#else - WCHAR *tmp = WDL_UTF8ToWC(folder, false, 0, NULL); -#endif - - IShellItemPtr si; - my_SHCreateItemFromParsingName(tmp, NULL, __uuidof(IShellItem), (void **)&si); - -#if !defined(WDL_NO_SUPPORT_UTF8) - free(tmp); -#endif - - if(si == NULL) return; - - if(def) - m_fod->SetDefaultFolder(si); - else - m_fod->SetFolder(si); -} - -void Win7FileDialog::addText(DWORD id, char *txt) -{ - if(m_fdc == NULL) return; -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[1024]; - mbstowcs(tmp, txt, 1023); - tmp[1023]=0; - m_fdc->AddText(id, tmp); -#else - WCHAR *tmp = WDL_UTF8ToWC(txt, false, 0, NULL); - m_fdc->AddText(id, tmp); - free(tmp); -#endif -} - -void Win7FileDialog::addCheckbox(char *name, DWORD id, int defval) -{ - if(m_fdc == NULL) return; - -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[1024]; - mbstowcs(tmp, name, 1023); - tmp[1023]=0; - m_fdc->AddCheckButton(id, tmp, defval); -#else - WCHAR *tmp = WDL_UTF8ToWC(name, false, 0, NULL); - m_fdc->AddCheckButton(id, tmp, defval); - free(tmp); -#endif -} - -void Win7FileDialog::startGroup(DWORD id, char *label) -{ - if(m_fdc == NULL) return; -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[1024]; - mbstowcs(tmp, label, 1023); - tmp[1023]=0; - m_fdc->StartVisualGroup(id, tmp); -#else - WCHAR *tmp = WDL_UTF8ToWC(label, false, 0, NULL); - m_fdc->StartVisualGroup(id, tmp); - free(tmp); -#endif -} - -void Win7FileDialog::endGroup() -{ - if(m_fdc == NULL) return; - m_fdc->EndVisualGroup(); -} - -void Win7FileDialog::getResult(char *fn, int maxlen) -{ - IShellItemPtr si; - m_fod->GetResult(&si); - if(si == NULL) - { - fn[0] = 0; - return; - } - WCHAR *res = NULL; - si->GetDisplayName(SIGDN_FILESYSPATH, &res); - if(!res) - { - fn[0] = 0; - return; - } - -#if defined(WDL_NO_SUPPORT_UTF8) - wcstombs(fn, res, maxlen); -#else - int len = WideCharToMultiByte(CP_UTF8,0,res,-1,fn,maxlen-1,NULL,NULL); - fn[len] = 0; -#endif - - CoTaskMemFree(res); -} - -int Win7FileDialog::getResult(int i, char *fn, int maxlen) -{ - //FIXME -#if 0 - IShellItemArrayPtr sia; - m_fod->GetResults(&sia); -#endif - return 0; -} - -int Win7FileDialog::getState(DWORD id) -{ - BOOL c = FALSE; - m_fdc->GetCheckButtonState(id, &c); - return c; -} - -static WNDPROC m_oldproc, m_oldproc2; -static LRESULT CALLBACK newWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - if(msg == WM_SIZE) - { - //disable the win7 dialog to resize our custom dialog - static int reent = 0; - if(!reent) - { - reent = 1; - RECT r2; - GetWindowRect(hwnd, &r2); - SetWindowPos(hwnd, NULL, r2.left, r2.top, 1000, r2.bottom-r2.top, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); - reent = 0; - } - return 0; - } - if(msg == WM_GETDLGCODE) - { - int a=1; - } - return CallWindowProc(m_oldproc, hwnd, msg, wparam, lparam); -} - -class myEvent : public IFileDialogEvents -{ -public: - myEvent(HINSTANCE inst, char *dlgid, LPOFNHOOKPROC proc, char *statictxt) - { - m_didhook = 0; - m_didhook2 = 0; - m_inst = inst; - m_dlgid = dlgid; - m_proc = proc; - m_crwnd = NULL; - m_statictxt.Set(statictxt); - } - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) - { - return E_NOINTERFACE; - } - STDMETHODIMP_(ULONG) AddRef() - { - return 1; - } - STDMETHODIMP_(ULONG) Release() - { - if(m_crwnd) DestroyWindow(m_crwnd); - return 0; - } - - virtual HRESULT STDMETHODCALLTYPE OnFileOk( - /* [in] */ __RPC__in_opt IFileDialog *pfd) - { - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnFolderChanging( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psiFolder) - { - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnFolderChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) - { - doHook2(pfd); //post a msg for the actual hook - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnSelectionChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) - { - doHook2(pfd); //post a msg for the actual hook - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnShareViolation( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse) - { - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnTypeChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) - { - return E_NOTIMPL; - } - - virtual HRESULT STDMETHODCALLTYPE OnOverwrite( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse) - { - return E_NOTIMPL; - } - - static BOOL CALLBACK enumProc(HWND hwnd, LPARAM lParam) - { - char tmp[1024]={0,}; - GetClassName(hwnd, tmp, 1023); - if(!stricmp(tmp,"FloatNotifySink")) - { - myEvent *me = (myEvent *)lParam; - if(!FindWindowEx(hwnd, NULL, NULL, me->m_statictxt.Get())) - return TRUE; - me->m_findwnd = hwnd; - return FALSE; - } - return TRUE; - } - - void doHook() - { - if(m_dlgid && !m_didhook) - { - IOleWindowPtr ow = m_lastpfd; - if(ow!=NULL) - { - HWND filehwnd = NULL; - ow->GetWindow(&filehwnd); - if(filehwnd) - { - m_findwnd = NULL; - EnumChildWindows(filehwnd, enumProc, (LPARAM)this); - if(m_findwnd) - { - //hide other button - HWND h3 = m_findwnd; - HWND h5 = FindWindowEx(h3, NULL, NULL, NULL); - ShowWindow(h5, SW_HIDE); - - //resize the sink - RECT r,r2; - GetWindowRect(h3, &r2); - SetWindowPos(h3, NULL, r2.left, r2.top, 1000, r2.bottom-r2.top, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); - - //put our own dialog instead - HWND h4 = CreateDialog(m_inst, m_dlgid, h3, (DLGPROC)m_proc); - - //SetWindowLong(h4, GWL_ID, 1001); - //SetWindowLong(h4, GWL_STYLE, GetWindowLong(h4, GWL_STYLE)&~(DS_CONTROL|DS_3DLOOK|DS_SETFONT)); - //SetWindowLong(h4, GWL_STYLE, GetWindowLong(h4, GWL_STYLE)|WS_GROUP); - SetWindowLong(h3, GWL_STYLE, GetWindowLong(h3, GWL_STYLE)|WS_TABSTOP); - - m_crwnd = h4; - ShowWindow(h4, SW_SHOW); - - GetClientRect(h3, &r); - SetWindowPos(h4, NULL, 0, 0, r.right, r.bottom, 0); - - //disable the win7 dialog to resize our custom dialog sink - m_oldproc = (WNDPROC)SetWindowLongPtr(h3, GWLP_WNDPROC, (LPARAM)&newWndProc); - m_didhook = 1; - } - } - } - } - } - - static LRESULT CALLBACK newWndProc2(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) - { - if(msg == WM_USER+666) - { - myEvent *me = (myEvent*)lparam; - me->doHook(); - } - return CallWindowProc(m_oldproc2, hwnd, msg, wparam, lparam); - } - - void doHook2(IFileDialog *pfd) - { - if(m_dlgid && !m_didhook2) - { - IOleWindowPtr ow = pfd; - HWND filehwnd = NULL; - ow->GetWindow(&filehwnd); - if(filehwnd) - { - m_lastpfd = pfd; - m_oldproc2 = (WNDPROC)SetWindowLongPtr(filehwnd, GWLP_WNDPROC, (LPARAM)&newWndProc2); - PostMessage(filehwnd, WM_USER+666,0,(LPARAM)this); - m_didhook2 = 1; - } - } - } - - int m_didhook, m_didhook2; - HINSTANCE m_inst; - char *m_dlgid; - LPOFNHOOKPROC m_proc; - HWND m_findwnd; - HWND m_crwnd; - WDL_String m_statictxt; - IFileDialog *m_lastpfd; -}; - -int Win7FileDialog::show(HWND parent) -{ - DWORD c; - myEvent *ev = new myEvent(m_inst, (char*)m_dlgid, m_proc, m_statictxt.Get()); - m_fod->Advise(ev, &c); - - int res = SUCCEEDED(m_fod->Show(parent)); - - m_fod->Unadvise(c); - delete ev; - return res; -} - -#ifndef DLGTEMPLATEEX -#pragma pack(push, 1) -typedef struct -{ - WORD dlgVer; - WORD signature; - DWORD helpID; - DWORD exStyle; - DWORD style; - WORD cDlgItems; - short x; - short y; - short cx; - short cy; -} DLGTEMPLATEEX; -#pragma pack(pop) -#endif - -void Win7FileDialog::setTemplate(HINSTANCE inst, const char *dlgid, LPOFNHOOKPROC proc) -{ - //get the dialog height size - HRSRC r = FindResource(inst, dlgid, RT_DIALOG); - if(!r) return; - HGLOBAL hTemplate = LoadResource(inst, r); - if(!hTemplate) return; - int ysizedlg = 0; - DLGTEMPLATEEX* pTemplate = (DLGTEMPLATEEX*)LockResource(hTemplate); - if(pTemplate->signature == 0xffff) - ysizedlg = pTemplate->cy; - else - { - DLGTEMPLATE *p2 = (DLGTEMPLATE*)pTemplate; - ysizedlg = p2->cy; - } - UnlockResource(hTemplate); - FreeResource(hTemplate); - - int ysize = ysizedlg/8; - - //make room for our custom template dialog - WDL_String txt("."); - if(ysize) - { - while(--ysize) - { - txt.Append("\n."); - } - } - addText(1, txt.Get()); - m_statictxt.Set(txt.Get()); - addText(2, ""); - - m_inst = inst; - m_dlgid = dlgid; - m_proc = proc; -} - -void Win7FileDialog::setFilename(const char *fn) -{ - if(m_fod == NULL) return; - -#if defined(WDL_NO_SUPPORT_UTF8) - WCHAR tmp[4096]; - mbstowcs(tmp, fn, 4095); - tmp[4095]=0; - m_fod->SetFileName(tmp); -#else - WCHAR *tmp = WDL_UTF8ToWC(fn, false, 0, NULL); - m_fod->SetFileName(tmp); - free(tmp); -#endif - -} diff --git a/WDL/win7filedialog.h b/WDL/win7filedialog.h deleted file mode 100644 index e547d351..00000000 --- a/WDL/win7filedialog.h +++ /dev/null @@ -1,2206 +0,0 @@ -#ifndef _WIN7FILEDIALOG_H -#define _WIN7FILEDIALOG_H - -#ifdef _WIN32 - -#include -#include "wdlstring.h" - -#ifndef __RPC__in_opt -//defines for msvc6 -#define __RPC__in_opt -#define __RPC__in -#define __RPC__out -#define __RPC__deref_out_opt -#define __RPC__deref_out_opt_string -#define __RPC__in_ecount_full(x) -#define __RPC__out_ecount_part(x,y) -#ifndef __in -#define __in -#endif - -typedef ULONG SFGAOF; - -typedef /* [v1_enum] */ -enum tagFDE_OVERWRITE_RESPONSE -{ FDEOR_DEFAULT = 0, -FDEOR_ACCEPT = 0x1, -FDEOR_REFUSE = 0x2 - } FDE_OVERWRITE_RESPONSE; - -typedef /* [v1_enum] */ -enum tagFDE_SHAREVIOLATION_RESPONSE -{ FDESVR_DEFAULT = 0, -FDESVR_ACCEPT = 0x1, -FDESVR_REFUSE = 0x2 -} FDE_SHAREVIOLATION_RESPONSE; - -typedef /* [v1_enum] */ -enum tagFDAP -{ FDAP_BOTTOM = 0, -FDAP_TOP = 0x1 -} FDAP; - -typedef struct _COMDLG_FILTERSPEC -{ - LPCWSTR pszName; - LPCWSTR pszSpec; -} COMDLG_FILTERSPEC; - -typedef -enum tagSHCONTF -{ SHCONTF_FOLDERS = 0x20, -SHCONTF_NONFOLDERS = 0x40, -SHCONTF_INCLUDEHIDDEN = 0x80, -SHCONTF_INIT_ON_FIRST_NEXT = 0x100, -SHCONTF_NETPRINTERSRCH = 0x200, -SHCONTF_SHAREABLE = 0x400, -SHCONTF_STORAGE = 0x800, -SHCONTF_FASTITEMS = 0x2000, -SHCONTF_FLATLIST = 0x4000, -SHCONTF_ENABLE_ASYNC = 0x8000 -} SHCONT; - -typedef DWORD SHCONTF; - -enum tagGETPROPERTYSTOREFLAGS -{ GPS_DEFAULT = 0, -GPS_HANDLERPROPERTIESONLY = 0x1, -GPS_READWRITE = 0x2, -GPS_TEMPORARY = 0x4, -GPS_FASTPROPERTIESONLY = 0x8, -GPS_OPENSLOWITEM = 0x10, -GPS_DELAYCREATION = 0x20, -GPS_BESTEFFORT = 0x40, -GPS_MASK_VALID = 0x7f -} ; -typedef int GETPROPERTYSTOREFLAGS; - -typedef /* [v1_enum] */ -enum tagCDCONTROLSTATE -{ CDCS_INACTIVE = 0, -CDCS_ENABLED = 0x1, -CDCS_VISIBLE = 0x2 -} CDCONTROLSTATE; - -typedef DWORD CDCONTROLSTATEF; - -typedef void *REFPROPERTYKEY; - -class IPropertyStore; -class IPropertyDescriptionList; -class IFileOperationProgressSink; -//msvc6 -#else -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#include -#endif -#endif - -#ifndef __IFileDialog_FWD_DEFINED__ -#define __IFileDialog_FWD_DEFINED__ -typedef interface IFileDialog IFileDialog; -#endif /* __IFileDialog_FWD_DEFINED__ */ - - - - -#ifndef __IShellItem_INTERFACE_DEFINED__ -#define __IShellItem_INTERFACE_DEFINED__ - -/* interface IShellItem */ -/* [unique][object][uuid][helpstring] */ - -typedef /* [v1_enum] */ -enum tagSIGDN - { SIGDN_NORMALDISPLAY = 0, - SIGDN_PARENTRELATIVEPARSING = ( int )0x80018001, - SIGDN_DESKTOPABSOLUTEPARSING = ( int )0x80028000, - SIGDN_PARENTRELATIVEEDITING = ( int )0x80031001, - SIGDN_DESKTOPABSOLUTEEDITING = ( int )0x8004c000, - SIGDN_FILESYSPATH = ( int )0x80058000, - SIGDN_URL = ( int )0x80068000, - SIGDN_PARENTRELATIVEFORADDRESSBAR = ( int )0x8007c001, - SIGDN_PARENTRELATIVE = ( int )0x80080001 - } SIGDN; - -/* [v1_enum] */ -enum tagSHELLITEMCOMPAREHINTF - { SICHINT_DISPLAY = 0, - SICHINT_ALLFIELDS = ( int )0x80000000, - SICHINT_CANONICAL = 0x10000000 - } ; -typedef DWORD SICHINTF; - - -EXTERN_C const IID IID_IShellItem; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("43826d1e-e718-42ee-bc55-a1e261c37bfe") - IShellItem : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE BindToHandler( - /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, - /* [in] */ __RPC__in REFGUID bhid, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetParent( - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDisplayName( - /* [in] */ SIGDN sigdnName, - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppszName) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAttributes( - /* [in] */ SFGAOF sfgaoMask, - /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0; - - virtual HRESULT STDMETHODCALLTYPE Compare( - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ SICHINTF hint, - /* [out] */ __RPC__out int *piOrder) = 0; - - }; - -#else /* C style interface */ - - typedef struct IShellItemVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IShellItem * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IShellItem * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IShellItem * This); - - HRESULT ( STDMETHODCALLTYPE *BindToHandler )( - IShellItem * This, - /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, - /* [in] */ __RPC__in REFGUID bhid, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); - - HRESULT ( STDMETHODCALLTYPE *GetParent )( - IShellItem * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( - IShellItem * This, - /* [in] */ SIGDN sigdnName, - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppszName); - - HRESULT ( STDMETHODCALLTYPE *GetAttributes )( - IShellItem * This, - /* [in] */ SFGAOF sfgaoMask, - /* [out] */ __RPC__out SFGAOF *psfgaoAttribs); - - HRESULT ( STDMETHODCALLTYPE *Compare )( - IShellItem * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ SICHINTF hint, - /* [out] */ __RPC__out int *piOrder); - - END_INTERFACE - } IShellItemVtbl; - - interface IShellItem - { - CONST_VTBL struct IShellItemVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IShellItem_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IShellItem_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IShellItem_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IShellItem_BindToHandler(This,pbc,bhid,riid,ppv) \ - ( (This)->lpVtbl -> BindToHandler(This,pbc,bhid,riid,ppv) ) - -#define IShellItem_GetParent(This,ppsi) \ - ( (This)->lpVtbl -> GetParent(This,ppsi) ) - -#define IShellItem_GetDisplayName(This,sigdnName,ppszName) \ - ( (This)->lpVtbl -> GetDisplayName(This,sigdnName,ppszName) ) - -#define IShellItem_GetAttributes(This,sfgaoMask,psfgaoAttribs) \ - ( (This)->lpVtbl -> GetAttributes(This,sfgaoMask,psfgaoAttribs) ) - -#define IShellItem_Compare(This,psi,hint,piOrder) \ - ( (This)->lpVtbl -> Compare(This,psi,hint,piOrder) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IShellItem_INTERFACE_DEFINED__ */ - -#ifndef __IFileDialogEvents_INTERFACE_DEFINED__ -#define __IFileDialogEvents_INTERFACE_DEFINED__ - -/* interface IFileDialogEvents */ -/* [unique][object][uuid] */ - -EXTERN_C const IID IID_IFileDialogEvents; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("973510db-7d7f-452b-8975-74a85828d354") - IFileDialogEvents : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE OnFileOk( - /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnFolderChanging( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psiFolder) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnFolderChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnSelectionChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnShareViolation( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnTypeChange( - /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; - - virtual HRESULT STDMETHODCALLTYPE OnOverwrite( - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse) = 0; - - }; - -#else /* C style interface */ - - typedef struct IFileDialogEventsVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IFileDialogEvents * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IFileDialogEvents * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IFileDialogEvents * This); - - HRESULT ( STDMETHODCALLTYPE *OnFileOk )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd); - - HRESULT ( STDMETHODCALLTYPE *OnFolderChanging )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psiFolder); - - HRESULT ( STDMETHODCALLTYPE *OnFolderChange )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd); - - HRESULT ( STDMETHODCALLTYPE *OnSelectionChange )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd); - - HRESULT ( STDMETHODCALLTYPE *OnShareViolation )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse); - - HRESULT ( STDMETHODCALLTYPE *OnTypeChange )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd); - - HRESULT ( STDMETHODCALLTYPE *OnOverwrite )( - IFileDialogEvents * This, - /* [in] */ __RPC__in_opt IFileDialog *pfd, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse); - - END_INTERFACE - } IFileDialogEventsVtbl; - - interface IFileDialogEvents - { - CONST_VTBL struct IFileDialogEventsVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IFileDialogEvents_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IFileDialogEvents_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IFileDialogEvents_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IFileDialogEvents_OnFileOk(This,pfd) \ - ( (This)->lpVtbl -> OnFileOk(This,pfd) ) - -#define IFileDialogEvents_OnFolderChanging(This,pfd,psiFolder) \ - ( (This)->lpVtbl -> OnFolderChanging(This,pfd,psiFolder) ) - -#define IFileDialogEvents_OnFolderChange(This,pfd) \ - ( (This)->lpVtbl -> OnFolderChange(This,pfd) ) - -#define IFileDialogEvents_OnSelectionChange(This,pfd) \ - ( (This)->lpVtbl -> OnSelectionChange(This,pfd) ) - -#define IFileDialogEvents_OnShareViolation(This,pfd,psi,pResponse) \ - ( (This)->lpVtbl -> OnShareViolation(This,pfd,psi,pResponse) ) - -#define IFileDialogEvents_OnTypeChange(This,pfd) \ - ( (This)->lpVtbl -> OnTypeChange(This,pfd) ) - -#define IFileDialogEvents_OnOverwrite(This,pfd,psi,pResponse) \ - ( (This)->lpVtbl -> OnOverwrite(This,pfd,psi,pResponse) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IFileDialogEvents_INTERFACE_DEFINED__ */ - - -#ifndef __IModalWindow_INTERFACE_DEFINED__ -#define __IModalWindow_INTERFACE_DEFINED__ - -/* interface IModalWindow */ -/* [unique][object][uuid][helpstring] */ - - -EXTERN_C const IID IID_IModalWindow; - -#if defined(__cplusplus) && !defined(CINTERFACE) - -MIDL_INTERFACE("b4db1657-70d7-485e-8e3e-6fcb5a5c1802") -IModalWindow : public IUnknown -{ - public: - virtual /* [local] */ HRESULT STDMETHODCALLTYPE Show( - /* [in] */ - __in HWND hwndParent) = 0; - - }; - -#else /* C style interface */ - - typedef struct IModalWindowVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IModalWindow * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IModalWindow * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IModalWindow * This); - - /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( - IModalWindow * This, - /* [in] */ - __in HWND hwndParent); - - END_INTERFACE - } IModalWindowVtbl; - - interface IModalWindow - { - CONST_VTBL struct IModalWindowVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IModalWindow_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IModalWindow_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IModalWindow_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IModalWindow_Show(This,hwndParent) \ - ( (This)->lpVtbl -> Show(This,hwndParent) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - /* [call_as] */ HRESULT STDMETHODCALLTYPE IModalWindow_RemoteShow_Proxy( - IModalWindow * This, - /* [in] */ __RPC__in HWND hwndParent); - - - void __RPC_STUB IModalWindow_RemoteShow_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IModalWindow_INTERFACE_DEFINED__ */ - -#ifndef __IShellItemFilter_INTERFACE_DEFINED__ -#define __IShellItemFilter_INTERFACE_DEFINED__ - - /* interface IShellItemFilter */ - /* [unique][uuid][object] */ - - - EXTERN_C const IID IID_IShellItemFilter; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("2659B475-EEB8-48b7-8F07-B378810F48CF") -IShellItemFilter : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE IncludeItem( - /* [in] */ __RPC__in_opt IShellItem *psi) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEnumFlagsForItem( - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out SHCONTF *pgrfFlags) = 0; - - }; - -#else /* C style interface */ - - typedef struct IShellItemFilterVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IShellItemFilter * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IShellItemFilter * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IShellItemFilter * This); - - HRESULT ( STDMETHODCALLTYPE *IncludeItem )( - IShellItemFilter * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *GetEnumFlagsForItem )( - IShellItemFilter * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [out] */ __RPC__out SHCONTF *pgrfFlags); - - END_INTERFACE - } IShellItemFilterVtbl; - - interface IShellItemFilter - { - CONST_VTBL struct IShellItemFilterVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IShellItemFilter_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IShellItemFilter_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IShellItemFilter_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IShellItemFilter_IncludeItem(This,psi) \ - ( (This)->lpVtbl -> IncludeItem(This,psi) ) - -#define IShellItemFilter_GetEnumFlagsForItem(This,psi,pgrfFlags) \ - ( (This)->lpVtbl -> GetEnumFlagsForItem(This,psi,pgrfFlags) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IShellItemFilter_INTERFACE_DEFINED__ */ - - - - -#ifndef __IFileDialog_INTERFACE_DEFINED__ -#define __IFileDialog_INTERFACE_DEFINED__ - -/* interface IFileDialog */ -/* [unique][object][uuid] */ - - -enum tagFILEOPENDIALOGOPTIONS - { FOS_OVERWRITEPROMPT = 0x2, - FOS_STRICTFILETYPES = 0x4, - FOS_NOCHANGEDIR = 0x8, - FOS_PICKFOLDERS = 0x20, - FOS_FORCEFILESYSTEM = 0x40, - FOS_ALLNONSTORAGEITEMS = 0x80, - FOS_NOVALIDATE = 0x100, - FOS_ALLOWMULTISELECT = 0x200, - FOS_PATHMUSTEXIST = 0x800, - FOS_FILEMUSTEXIST = 0x1000, - FOS_CREATEPROMPT = 0x2000, - FOS_SHAREAWARE = 0x4000, - FOS_NOREADONLYRETURN = 0x8000, - FOS_NOTESTFILECREATE = 0x10000, - FOS_HIDEMRUPLACES = 0x20000, - FOS_HIDEPINNEDPLACES = 0x40000, - FOS_NODEREFERENCELINKS = 0x100000, - FOS_DONTADDTORECENT = 0x2000000, - FOS_FORCESHOWHIDDEN = 0x10000000, - FOS_DEFAULTNOMINIMODE = 0x20000000, - FOS_FORCEPREVIEWPANEON = 0x40000000 - } ; - -EXTERN_C const IID IID_IFileDialog; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("42f85136-db7e-439c-85f1-e4075d135fc8") - IFileDialog : public IModalWindow - { - public: - virtual HRESULT STDMETHODCALLTYPE SetFileTypes( - /* [in] */ UINT cFileTypes, - /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex( - /* [in] */ UINT iFileType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex( - /* [out] */ __RPC__out UINT *piFileType) = 0; - - virtual HRESULT STDMETHODCALLTYPE Advise( - /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, - /* [out] */ __RPC__out DWORD *pdwCookie) = 0; - - virtual HRESULT STDMETHODCALLTYPE Unadvise( - /* [in] */ DWORD dwCookie) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetOptions( - /* [in] */ DWORD fos) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetOptions( - /* [out] */ __RPC__out DWORD *pfos) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder( - /* [in] */ __RPC__in_opt IShellItem *psi) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFolder( - /* [in] */ __RPC__in_opt IShellItem *psi) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFolder( - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection( - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFileName( - /* [string][in] */ __RPC__in LPCWSTR pszName) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFileName( - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetTitle( - /* [string][in] */ __RPC__in LPCWSTR pszTitle) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel( - /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel( - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetResult( - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddPlace( - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ FDAP fdap) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension( - /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension) = 0; - - virtual HRESULT STDMETHODCALLTYPE Close( - /* [in] */ HRESULT hr) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetClientGuid( - /* [in] */ __RPC__in REFGUID guid) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFilter( - /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0; - - }; - -#else /* C style interface */ - - typedef struct IFileDialogVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IFileDialog * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IFileDialog * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IFileDialog * This); - - /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( - IFileDialog * This, - /* [in] */ - __in HWND hwndParent); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( - IFileDialog * This, - /* [in] */ UINT cFileTypes, - /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( - IFileDialog * This, - /* [in] */ UINT iFileType); - - HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( - IFileDialog * This, - /* [out] */ __RPC__out UINT *piFileType); - - HRESULT ( STDMETHODCALLTYPE *Advise )( - IFileDialog * This, - /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, - /* [out] */ __RPC__out DWORD *pdwCookie); - - HRESULT ( STDMETHODCALLTYPE *Unadvise )( - IFileDialog * This, - /* [in] */ DWORD dwCookie); - - HRESULT ( STDMETHODCALLTYPE *SetOptions )( - IFileDialog * This, - /* [in] */ DWORD fos); - - HRESULT ( STDMETHODCALLTYPE *GetOptions )( - IFileDialog * This, - /* [out] */ __RPC__out DWORD *pfos); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( - IFileDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *SetFolder )( - IFileDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *GetFolder )( - IFileDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( - IFileDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *SetFileName )( - IFileDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszName); - - HRESULT ( STDMETHODCALLTYPE *GetFileName )( - IFileDialog * This, - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); - - HRESULT ( STDMETHODCALLTYPE *SetTitle )( - IFileDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszTitle); - - HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( - IFileDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( - IFileDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *GetResult )( - IFileDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *AddPlace )( - IFileDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ FDAP fdap); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( - IFileDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); - - HRESULT ( STDMETHODCALLTYPE *Close )( - IFileDialog * This, - /* [in] */ HRESULT hr); - - HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( - IFileDialog * This, - /* [in] */ __RPC__in REFGUID guid); - - HRESULT ( STDMETHODCALLTYPE *ClearClientData )( - IFileDialog * This); - - HRESULT ( STDMETHODCALLTYPE *SetFilter )( - IFileDialog * This, - /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); - - END_INTERFACE - } IFileDialogVtbl; - - interface IFileDialog - { - CONST_VTBL struct IFileDialogVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IFileDialog_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IFileDialog_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IFileDialog_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IFileDialog_Show(This,hwndParent) \ - ( (This)->lpVtbl -> Show(This,hwndParent) ) - - -#define IFileDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ - ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) - -#define IFileDialog_SetFileTypeIndex(This,iFileType) \ - ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) - -#define IFileDialog_GetFileTypeIndex(This,piFileType) \ - ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) - -#define IFileDialog_Advise(This,pfde,pdwCookie) \ - ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) - -#define IFileDialog_Unadvise(This,dwCookie) \ - ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) - -#define IFileDialog_SetOptions(This,fos) \ - ( (This)->lpVtbl -> SetOptions(This,fos) ) - -#define IFileDialog_GetOptions(This,pfos) \ - ( (This)->lpVtbl -> GetOptions(This,pfos) ) - -#define IFileDialog_SetDefaultFolder(This,psi) \ - ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) - -#define IFileDialog_SetFolder(This,psi) \ - ( (This)->lpVtbl -> SetFolder(This,psi) ) - -#define IFileDialog_GetFolder(This,ppsi) \ - ( (This)->lpVtbl -> GetFolder(This,ppsi) ) - -#define IFileDialog_GetCurrentSelection(This,ppsi) \ - ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) - -#define IFileDialog_SetFileName(This,pszName) \ - ( (This)->lpVtbl -> SetFileName(This,pszName) ) - -#define IFileDialog_GetFileName(This,pszName) \ - ( (This)->lpVtbl -> GetFileName(This,pszName) ) - -#define IFileDialog_SetTitle(This,pszTitle) \ - ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) - -#define IFileDialog_SetOkButtonLabel(This,pszText) \ - ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) - -#define IFileDialog_SetFileNameLabel(This,pszLabel) \ - ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) - -#define IFileDialog_GetResult(This,ppsi) \ - ( (This)->lpVtbl -> GetResult(This,ppsi) ) - -#define IFileDialog_AddPlace(This,psi,fdap) \ - ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) - -#define IFileDialog_SetDefaultExtension(This,pszDefaultExtension) \ - ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) - -#define IFileDialog_Close(This,hr) \ - ( (This)->lpVtbl -> Close(This,hr) ) - -#define IFileDialog_SetClientGuid(This,guid) \ - ( (This)->lpVtbl -> SetClientGuid(This,guid) ) - -#define IFileDialog_ClearClientData(This) \ - ( (This)->lpVtbl -> ClearClientData(This) ) - -#define IFileDialog_SetFilter(This,pFilter) \ - ( (This)->lpVtbl -> SetFilter(This,pFilter) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - -#ifndef __IEnumShellItems_INTERFACE_DEFINED__ -#define __IEnumShellItems_INTERFACE_DEFINED__ - -/* interface IEnumShellItems */ -/* [unique][object][uuid][helpstring] */ - - -EXTERN_C const IID IID_IEnumShellItems; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("70629033-e363-4a28-a567-0db78006e6d7") - IEnumShellItems : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ __RPC__out_ecount_part(celt, *pceltFetched) IShellItem **rgelt, - /* [out] */ __RPC__out ULONG *pceltFetched) = 0; - - virtual HRESULT STDMETHODCALLTYPE Skip( - /* [in] */ ULONG celt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( - /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenum) = 0; - - }; - -#else /* C style interface */ - - typedef struct IEnumShellItemsVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IEnumShellItems * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IEnumShellItems * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IEnumShellItems * This); - - HRESULT ( STDMETHODCALLTYPE *Next )( - IEnumShellItems * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ __RPC__out_ecount_part(celt, *pceltFetched) IShellItem **rgelt, - /* [out] */ __RPC__out ULONG *pceltFetched); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - IEnumShellItems * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - IEnumShellItems * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - IEnumShellItems * This, - /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenum); - - END_INTERFACE - } IEnumShellItemsVtbl; - - interface IEnumShellItems - { - CONST_VTBL struct IEnumShellItemsVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IEnumShellItems_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IEnumShellItems_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IEnumShellItems_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IEnumShellItems_Next(This,celt,rgelt,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) - -#define IEnumShellItems_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define IEnumShellItems_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define IEnumShellItems_Clone(This,ppenum) \ - ( (This)->lpVtbl -> Clone(This,ppenum) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IEnumShellItems_INTERFACE_DEFINED__ */ - - -#ifndef __IShellItemArray_INTERFACE_DEFINED__ -#define __IShellItemArray_INTERFACE_DEFINED__ - -/* interface IShellItemArray */ -/* [unique][object][uuid][helpstring] */ - -typedef /* [v1_enum] */ -enum tagSIATTRIBFLAGS - { SIATTRIBFLAGS_AND = 0x1, - SIATTRIBFLAGS_OR = 0x2, - SIATTRIBFLAGS_APPCOMPAT = 0x3, - SIATTRIBFLAGS_MASK = 0x3 - } SIATTRIBFLAGS; - - -EXTERN_C const IID IID_IShellItemArray; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("b63ea76d-1f85-456f-a19c-48159efa858b") - IShellItemArray : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE BindToHandler( - /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, - /* [in] */ __RPC__in REFGUID rbhid, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppvOut) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetPropertyStore( - /* [in] */ GETPROPERTYSTOREFLAGS flags, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetPropertyDescriptionList( - /* [in] */ __RPC__in REFPROPERTYKEY keyType, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAttributes( - /* [in] */ SIATTRIBFLAGS dwAttribFlags, - /* [in] */ SFGAOF sfgaoMask, - /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( - /* [out] */ __RPC__out DWORD *pdwNumItems) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetItemAt( - /* [in] */ DWORD dwIndex, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumItems( - /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenumShellItems) = 0; - - }; - -#else /* C style interface */ - - typedef struct IShellItemArrayVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IShellItemArray * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IShellItemArray * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IShellItemArray * This); - - HRESULT ( STDMETHODCALLTYPE *BindToHandler )( - IShellItemArray * This, - /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, - /* [in] */ __RPC__in REFGUID rbhid, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppvOut); - - HRESULT ( STDMETHODCALLTYPE *GetPropertyStore )( - IShellItemArray * This, - /* [in] */ GETPROPERTYSTOREFLAGS flags, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); - - HRESULT ( STDMETHODCALLTYPE *GetPropertyDescriptionList )( - IShellItemArray * This, - /* [in] */ __RPC__in REFPROPERTYKEY keyType, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); - - HRESULT ( STDMETHODCALLTYPE *GetAttributes )( - IShellItemArray * This, - /* [in] */ SIATTRIBFLAGS dwAttribFlags, - /* [in] */ SFGAOF sfgaoMask, - /* [out] */ __RPC__out SFGAOF *psfgaoAttribs); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - IShellItemArray * This, - /* [out] */ __RPC__out DWORD *pdwNumItems); - - HRESULT ( STDMETHODCALLTYPE *GetItemAt )( - IShellItemArray * This, - /* [in] */ DWORD dwIndex, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *EnumItems )( - IShellItemArray * This, - /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenumShellItems); - - END_INTERFACE - } IShellItemArrayVtbl; - - interface IShellItemArray - { - CONST_VTBL struct IShellItemArrayVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IShellItemArray_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IShellItemArray_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IShellItemArray_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IShellItemArray_BindToHandler(This,pbc,rbhid,riid,ppvOut) \ - ( (This)->lpVtbl -> BindToHandler(This,pbc,rbhid,riid,ppvOut) ) - -#define IShellItemArray_GetPropertyStore(This,flags,riid,ppv) \ - ( (This)->lpVtbl -> GetPropertyStore(This,flags,riid,ppv) ) - -#define IShellItemArray_GetPropertyDescriptionList(This,keyType,riid,ppv) \ - ( (This)->lpVtbl -> GetPropertyDescriptionList(This,keyType,riid,ppv) ) - -#define IShellItemArray_GetAttributes(This,dwAttribFlags,sfgaoMask,psfgaoAttribs) \ - ( (This)->lpVtbl -> GetAttributes(This,dwAttribFlags,sfgaoMask,psfgaoAttribs) ) - -#define IShellItemArray_GetCount(This,pdwNumItems) \ - ( (This)->lpVtbl -> GetCount(This,pdwNumItems) ) - -#define IShellItemArray_GetItemAt(This,dwIndex,ppsi) \ - ( (This)->lpVtbl -> GetItemAt(This,dwIndex,ppsi) ) - -#define IShellItemArray_EnumItems(This,ppenumShellItems) \ - ( (This)->lpVtbl -> EnumItems(This,ppenumShellItems) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IShellItemArray_INTERFACE_DEFINED__ */ - - - - - -#endif /* __IFileDialog_INTERFACE_DEFINED__ */ - -#ifndef __IFileOpenDialog_INTERFACE_DEFINED__ -#define __IFileOpenDialog_INTERFACE_DEFINED__ - -/* interface IFileOpenDialog */ -/* [unique][object][uuid] */ - - -EXTERN_C const IID IID_IFileOpenDialog; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("d57c7288-d4ad-4768-be02-9d969532d960") - IFileOpenDialog : public IFileDialog - { - public: - virtual HRESULT STDMETHODCALLTYPE GetResults( - /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSelectedItems( - /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai) = 0; - - }; - -#else /* C style interface */ - - typedef struct IFileOpenDialogVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IFileOpenDialog * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IFileOpenDialog * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IFileOpenDialog * This); - - /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( - IFileOpenDialog * This, - /* [in] */ - __in HWND hwndParent); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( - IFileOpenDialog * This, - /* [in] */ UINT cFileTypes, - /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( - IFileOpenDialog * This, - /* [in] */ UINT iFileType); - - HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( - IFileOpenDialog * This, - /* [out] */ __RPC__out UINT *piFileType); - - HRESULT ( STDMETHODCALLTYPE *Advise )( - IFileOpenDialog * This, - /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, - /* [out] */ __RPC__out DWORD *pdwCookie); - - HRESULT ( STDMETHODCALLTYPE *Unadvise )( - IFileOpenDialog * This, - /* [in] */ DWORD dwCookie); - - HRESULT ( STDMETHODCALLTYPE *SetOptions )( - IFileOpenDialog * This, - /* [in] */ DWORD fos); - - HRESULT ( STDMETHODCALLTYPE *GetOptions )( - IFileOpenDialog * This, - /* [out] */ __RPC__out DWORD *pfos); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( - IFileOpenDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *SetFolder )( - IFileOpenDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *GetFolder )( - IFileOpenDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( - IFileOpenDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *SetFileName )( - IFileOpenDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszName); - - HRESULT ( STDMETHODCALLTYPE *GetFileName )( - IFileOpenDialog * This, - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); - - HRESULT ( STDMETHODCALLTYPE *SetTitle )( - IFileOpenDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszTitle); - - HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( - IFileOpenDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( - IFileOpenDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *GetResult )( - IFileOpenDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *AddPlace )( - IFileOpenDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ FDAP fdap); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( - IFileOpenDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); - - HRESULT ( STDMETHODCALLTYPE *Close )( - IFileOpenDialog * This, - /* [in] */ HRESULT hr); - - HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( - IFileOpenDialog * This, - /* [in] */ __RPC__in REFGUID guid); - - HRESULT ( STDMETHODCALLTYPE *ClearClientData )( - IFileOpenDialog * This); - - HRESULT ( STDMETHODCALLTYPE *SetFilter )( - IFileOpenDialog * This, - /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); - - HRESULT ( STDMETHODCALLTYPE *GetResults )( - IFileOpenDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum); - - HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )( - IFileOpenDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai); - - END_INTERFACE - } IFileOpenDialogVtbl; - - interface IFileOpenDialog - { - CONST_VTBL struct IFileOpenDialogVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IFileOpenDialog_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IFileOpenDialog_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IFileOpenDialog_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IFileOpenDialog_Show(This,hwndParent) \ - ( (This)->lpVtbl -> Show(This,hwndParent) ) - - -#define IFileOpenDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ - ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) - -#define IFileOpenDialog_SetFileTypeIndex(This,iFileType) \ - ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) - -#define IFileOpenDialog_GetFileTypeIndex(This,piFileType) \ - ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) - -#define IFileOpenDialog_Advise(This,pfde,pdwCookie) \ - ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) - -#define IFileOpenDialog_Unadvise(This,dwCookie) \ - ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) - -#define IFileOpenDialog_SetOptions(This,fos) \ - ( (This)->lpVtbl -> SetOptions(This,fos) ) - -#define IFileOpenDialog_GetOptions(This,pfos) \ - ( (This)->lpVtbl -> GetOptions(This,pfos) ) - -#define IFileOpenDialog_SetDefaultFolder(This,psi) \ - ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) - -#define IFileOpenDialog_SetFolder(This,psi) \ - ( (This)->lpVtbl -> SetFolder(This,psi) ) - -#define IFileOpenDialog_GetFolder(This,ppsi) \ - ( (This)->lpVtbl -> GetFolder(This,ppsi) ) - -#define IFileOpenDialog_GetCurrentSelection(This,ppsi) \ - ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) - -#define IFileOpenDialog_SetFileName(This,pszName) \ - ( (This)->lpVtbl -> SetFileName(This,pszName) ) - -#define IFileOpenDialog_GetFileName(This,pszName) \ - ( (This)->lpVtbl -> GetFileName(This,pszName) ) - -#define IFileOpenDialog_SetTitle(This,pszTitle) \ - ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) - -#define IFileOpenDialog_SetOkButtonLabel(This,pszText) \ - ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) - -#define IFileOpenDialog_SetFileNameLabel(This,pszLabel) \ - ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) - -#define IFileOpenDialog_GetResult(This,ppsi) \ - ( (This)->lpVtbl -> GetResult(This,ppsi) ) - -#define IFileOpenDialog_AddPlace(This,psi,fdap) \ - ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) - -#define IFileOpenDialog_SetDefaultExtension(This,pszDefaultExtension) \ - ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) - -#define IFileOpenDialog_Close(This,hr) \ - ( (This)->lpVtbl -> Close(This,hr) ) - -#define IFileOpenDialog_SetClientGuid(This,guid) \ - ( (This)->lpVtbl -> SetClientGuid(This,guid) ) - -#define IFileOpenDialog_ClearClientData(This) \ - ( (This)->lpVtbl -> ClearClientData(This) ) - -#define IFileOpenDialog_SetFilter(This,pFilter) \ - ( (This)->lpVtbl -> SetFilter(This,pFilter) ) - - -#define IFileOpenDialog_GetResults(This,ppenum) \ - ( (This)->lpVtbl -> GetResults(This,ppenum) ) - -#define IFileOpenDialog_GetSelectedItems(This,ppsai) \ - ( (This)->lpVtbl -> GetSelectedItems(This,ppsai) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IFileOpenDialog_INTERFACE_DEFINED__ */ - - -#ifndef __IFileDialogCustomize_INTERFACE_DEFINED__ -#define __IFileDialogCustomize_INTERFACE_DEFINED__ - -/* interface IFileDialogCustomize */ -/* [unique][object][uuid] */ - - -EXTERN_C const IID IID_IFileDialogCustomize; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("e6fdd21a-163f-4975-9c8c-a69f1ba37034") - IFileDialogCustomize : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE EnableOpenDropDown( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddMenu( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddPushButton( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddComboBox( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddRadioButtonList( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddCheckButton( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel, - /* [in] */ BOOL bChecked) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddEditBox( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddSeparator( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddText( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetControlLabel( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetControlState( - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetControlState( - /* [in] */ DWORD dwIDCtl, - /* [in] */ CDCONTROLSTATEF dwState) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEditBoxText( - /* [in] */ DWORD dwIDCtl, - /* [string][out] */ __RPC__deref_out_opt_string WCHAR **ppszText) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetEditBoxText( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCheckButtonState( - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out BOOL *pbChecked) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetCheckButtonState( - /* [in] */ DWORD dwIDCtl, - /* [in] */ BOOL bChecked) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddControlItem( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemoveControlItem( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemoveAllControlItems( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetControlItemState( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetControlItemState( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [in] */ CDCONTROLSTATEF dwState) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSelectedControlItem( - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out DWORD *pdwIDItem) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetSelectedControlItem( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem) = 0; - - virtual HRESULT STDMETHODCALLTYPE StartVisualGroup( - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - virtual HRESULT STDMETHODCALLTYPE EndVisualGroup( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE MakeProminent( - /* [in] */ DWORD dwIDCtl) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetControlItemText( - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; - - }; - -#else /* C style interface */ - - typedef struct IFileDialogCustomizeVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IFileDialogCustomize * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IFileDialogCustomize * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IFileDialogCustomize * This); - - HRESULT ( STDMETHODCALLTYPE *EnableOpenDropDown )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *AddMenu )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *AddPushButton )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *AddComboBox )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *AddRadioButtonList )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *AddCheckButton )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel, - /* [in] */ BOOL bChecked); - - HRESULT ( STDMETHODCALLTYPE *AddEditBox )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *AddSeparator )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *AddText )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *SetControlLabel )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *GetControlState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState); - - HRESULT ( STDMETHODCALLTYPE *SetControlState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ CDCONTROLSTATEF dwState); - - HRESULT ( STDMETHODCALLTYPE *GetEditBoxText )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][out] */ __RPC__deref_out_opt_string WCHAR **ppszText); - - HRESULT ( STDMETHODCALLTYPE *SetEditBoxText )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *GetCheckButtonState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out BOOL *pbChecked); - - HRESULT ( STDMETHODCALLTYPE *SetCheckButtonState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ BOOL bChecked); - - HRESULT ( STDMETHODCALLTYPE *AddControlItem )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *RemoveControlItem )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem); - - HRESULT ( STDMETHODCALLTYPE *RemoveAllControlItems )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *GetControlItemState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState); - - HRESULT ( STDMETHODCALLTYPE *SetControlItemState )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [in] */ CDCONTROLSTATEF dwState); - - HRESULT ( STDMETHODCALLTYPE *GetSelectedControlItem )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [out] */ __RPC__out DWORD *pdwIDItem); - - HRESULT ( STDMETHODCALLTYPE *SetSelectedControlItem )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem); - - HRESULT ( STDMETHODCALLTYPE *StartVisualGroup )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *EndVisualGroup )( - IFileDialogCustomize * This); - - HRESULT ( STDMETHODCALLTYPE *MakeProminent )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl); - - HRESULT ( STDMETHODCALLTYPE *SetControlItemText )( - IFileDialogCustomize * This, - /* [in] */ DWORD dwIDCtl, - /* [in] */ DWORD dwIDItem, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - END_INTERFACE - } IFileDialogCustomizeVtbl; - - interface IFileDialogCustomize - { - CONST_VTBL struct IFileDialogCustomizeVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IFileDialogCustomize_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IFileDialogCustomize_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IFileDialogCustomize_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IFileDialogCustomize_EnableOpenDropDown(This,dwIDCtl) \ - ( (This)->lpVtbl -> EnableOpenDropDown(This,dwIDCtl) ) - -#define IFileDialogCustomize_AddMenu(This,dwIDCtl,pszLabel) \ - ( (This)->lpVtbl -> AddMenu(This,dwIDCtl,pszLabel) ) - -#define IFileDialogCustomize_AddPushButton(This,dwIDCtl,pszLabel) \ - ( (This)->lpVtbl -> AddPushButton(This,dwIDCtl,pszLabel) ) - -#define IFileDialogCustomize_AddComboBox(This,dwIDCtl) \ - ( (This)->lpVtbl -> AddComboBox(This,dwIDCtl) ) - -#define IFileDialogCustomize_AddRadioButtonList(This,dwIDCtl) \ - ( (This)->lpVtbl -> AddRadioButtonList(This,dwIDCtl) ) - -#define IFileDialogCustomize_AddCheckButton(This,dwIDCtl,pszLabel,bChecked) \ - ( (This)->lpVtbl -> AddCheckButton(This,dwIDCtl,pszLabel,bChecked) ) - -#define IFileDialogCustomize_AddEditBox(This,dwIDCtl,pszText) \ - ( (This)->lpVtbl -> AddEditBox(This,dwIDCtl,pszText) ) - -#define IFileDialogCustomize_AddSeparator(This,dwIDCtl) \ - ( (This)->lpVtbl -> AddSeparator(This,dwIDCtl) ) - -#define IFileDialogCustomize_AddText(This,dwIDCtl,pszText) \ - ( (This)->lpVtbl -> AddText(This,dwIDCtl,pszText) ) - -#define IFileDialogCustomize_SetControlLabel(This,dwIDCtl,pszLabel) \ - ( (This)->lpVtbl -> SetControlLabel(This,dwIDCtl,pszLabel) ) - -#define IFileDialogCustomize_GetControlState(This,dwIDCtl,pdwState) \ - ( (This)->lpVtbl -> GetControlState(This,dwIDCtl,pdwState) ) - -#define IFileDialogCustomize_SetControlState(This,dwIDCtl,dwState) \ - ( (This)->lpVtbl -> SetControlState(This,dwIDCtl,dwState) ) - -#define IFileDialogCustomize_GetEditBoxText(This,dwIDCtl,ppszText) \ - ( (This)->lpVtbl -> GetEditBoxText(This,dwIDCtl,ppszText) ) - -#define IFileDialogCustomize_SetEditBoxText(This,dwIDCtl,pszText) \ - ( (This)->lpVtbl -> SetEditBoxText(This,dwIDCtl,pszText) ) - -#define IFileDialogCustomize_GetCheckButtonState(This,dwIDCtl,pbChecked) \ - ( (This)->lpVtbl -> GetCheckButtonState(This,dwIDCtl,pbChecked) ) - -#define IFileDialogCustomize_SetCheckButtonState(This,dwIDCtl,bChecked) \ - ( (This)->lpVtbl -> SetCheckButtonState(This,dwIDCtl,bChecked) ) - -#define IFileDialogCustomize_AddControlItem(This,dwIDCtl,dwIDItem,pszLabel) \ - ( (This)->lpVtbl -> AddControlItem(This,dwIDCtl,dwIDItem,pszLabel) ) - -#define IFileDialogCustomize_RemoveControlItem(This,dwIDCtl,dwIDItem) \ - ( (This)->lpVtbl -> RemoveControlItem(This,dwIDCtl,dwIDItem) ) - -#define IFileDialogCustomize_RemoveAllControlItems(This,dwIDCtl) \ - ( (This)->lpVtbl -> RemoveAllControlItems(This,dwIDCtl) ) - -#define IFileDialogCustomize_GetControlItemState(This,dwIDCtl,dwIDItem,pdwState) \ - ( (This)->lpVtbl -> GetControlItemState(This,dwIDCtl,dwIDItem,pdwState) ) - -#define IFileDialogCustomize_SetControlItemState(This,dwIDCtl,dwIDItem,dwState) \ - ( (This)->lpVtbl -> SetControlItemState(This,dwIDCtl,dwIDItem,dwState) ) - -#define IFileDialogCustomize_GetSelectedControlItem(This,dwIDCtl,pdwIDItem) \ - ( (This)->lpVtbl -> GetSelectedControlItem(This,dwIDCtl,pdwIDItem) ) - -#define IFileDialogCustomize_SetSelectedControlItem(This,dwIDCtl,dwIDItem) \ - ( (This)->lpVtbl -> SetSelectedControlItem(This,dwIDCtl,dwIDItem) ) - -#define IFileDialogCustomize_StartVisualGroup(This,dwIDCtl,pszLabel) \ - ( (This)->lpVtbl -> StartVisualGroup(This,dwIDCtl,pszLabel) ) - -#define IFileDialogCustomize_EndVisualGroup(This) \ - ( (This)->lpVtbl -> EndVisualGroup(This) ) - -#define IFileDialogCustomize_MakeProminent(This,dwIDCtl) \ - ( (This)->lpVtbl -> MakeProminent(This,dwIDCtl) ) - -#define IFileDialogCustomize_SetControlItemText(This,dwIDCtl,dwIDItem,pszLabel) \ - ( (This)->lpVtbl -> SetControlItemText(This,dwIDCtl,dwIDItem,pszLabel) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IFileDialogCustomize_INTERFACE_DEFINED__ */ - - -#ifndef __IFileSaveDialog_INTERFACE_DEFINED__ -#define __IFileSaveDialog_INTERFACE_DEFINED__ - -/* interface IFileSaveDialog */ -/* [unique][object][uuid] */ - - -EXTERN_C const IID IID_IFileSaveDialog; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("84bccd23-5fde-4cdb-aea4-af64b83d78ab") - IFileSaveDialog : public IFileDialog - { - public: - virtual HRESULT STDMETHODCALLTYPE SetSaveAsItem( - /* [in] */ __RPC__in_opt IShellItem *psi) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetProperties( - /* [in] */ __RPC__in_opt IPropertyStore *pStore) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetCollectedProperties( - /* [in] */ __RPC__in_opt IPropertyDescriptionList *pList, - /* [in] */ BOOL fAppendDefault) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProperties( - /* [out] */ __RPC__deref_out_opt IPropertyStore **ppStore) = 0; - - virtual HRESULT STDMETHODCALLTYPE ApplyProperties( - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ __RPC__in_opt IPropertyStore *pStore, - /* [unique][in] */ __RPC__in_opt HWND hwnd, - /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pSink) = 0; - - }; - -#else /* C style interface */ - - typedef struct IFileSaveDialogVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - IFileSaveDialog * This, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - IFileSaveDialog * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - IFileSaveDialog * This); - - /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( - IFileSaveDialog * This, - /* [in] */ - __in HWND hwndParent); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( - IFileSaveDialog * This, - /* [in] */ UINT cFileTypes, - /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); - - HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( - IFileSaveDialog * This, - /* [in] */ UINT iFileType); - - HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( - IFileSaveDialog * This, - /* [out] */ __RPC__out UINT *piFileType); - - HRESULT ( STDMETHODCALLTYPE *Advise )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, - /* [out] */ __RPC__out DWORD *pdwCookie); - - HRESULT ( STDMETHODCALLTYPE *Unadvise )( - IFileSaveDialog * This, - /* [in] */ DWORD dwCookie); - - HRESULT ( STDMETHODCALLTYPE *SetOptions )( - IFileSaveDialog * This, - /* [in] */ DWORD fos); - - HRESULT ( STDMETHODCALLTYPE *GetOptions )( - IFileSaveDialog * This, - /* [out] */ __RPC__out DWORD *pfos); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *SetFolder )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *GetFolder )( - IFileSaveDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( - IFileSaveDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *SetFileName )( - IFileSaveDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszName); - - HRESULT ( STDMETHODCALLTYPE *GetFileName )( - IFileSaveDialog * This, - /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); - - HRESULT ( STDMETHODCALLTYPE *SetTitle )( - IFileSaveDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszTitle); - - HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( - IFileSaveDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszText); - - HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( - IFileSaveDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszLabel); - - HRESULT ( STDMETHODCALLTYPE *GetResult )( - IFileSaveDialog * This, - /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); - - HRESULT ( STDMETHODCALLTYPE *AddPlace )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ FDAP fdap); - - HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( - IFileSaveDialog * This, - /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); - - HRESULT ( STDMETHODCALLTYPE *Close )( - IFileSaveDialog * This, - /* [in] */ HRESULT hr); - - HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( - IFileSaveDialog * This, - /* [in] */ __RPC__in REFGUID guid); - - HRESULT ( STDMETHODCALLTYPE *ClearClientData )( - IFileSaveDialog * This); - - HRESULT ( STDMETHODCALLTYPE *SetFilter )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); - - HRESULT ( STDMETHODCALLTYPE *SetSaveAsItem )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi); - - HRESULT ( STDMETHODCALLTYPE *SetProperties )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IPropertyStore *pStore); - - HRESULT ( STDMETHODCALLTYPE *SetCollectedProperties )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IPropertyDescriptionList *pList, - /* [in] */ BOOL fAppendDefault); - - HRESULT ( STDMETHODCALLTYPE *GetProperties )( - IFileSaveDialog * This, - /* [out] */ __RPC__deref_out_opt IPropertyStore **ppStore); - - HRESULT ( STDMETHODCALLTYPE *ApplyProperties )( - IFileSaveDialog * This, - /* [in] */ __RPC__in_opt IShellItem *psi, - /* [in] */ __RPC__in_opt IPropertyStore *pStore, - /* [unique][in] */ __RPC__in_opt HWND hwnd, - /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pSink); - - END_INTERFACE - } IFileSaveDialogVtbl; - - interface IFileSaveDialog - { - CONST_VTBL struct IFileSaveDialogVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IFileSaveDialog_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define IFileSaveDialog_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define IFileSaveDialog_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define IFileSaveDialog_Show(This,hwndParent) \ - ( (This)->lpVtbl -> Show(This,hwndParent) ) - - -#define IFileSaveDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ - ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) - -#define IFileSaveDialog_SetFileTypeIndex(This,iFileType) \ - ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) - -#define IFileSaveDialog_GetFileTypeIndex(This,piFileType) \ - ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) - -#define IFileSaveDialog_Advise(This,pfde,pdwCookie) \ - ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) - -#define IFileSaveDialog_Unadvise(This,dwCookie) \ - ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) - -#define IFileSaveDialog_SetOptions(This,fos) \ - ( (This)->lpVtbl -> SetOptions(This,fos) ) - -#define IFileSaveDialog_GetOptions(This,pfos) \ - ( (This)->lpVtbl -> GetOptions(This,pfos) ) - -#define IFileSaveDialog_SetDefaultFolder(This,psi) \ - ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) - -#define IFileSaveDialog_SetFolder(This,psi) \ - ( (This)->lpVtbl -> SetFolder(This,psi) ) - -#define IFileSaveDialog_GetFolder(This,ppsi) \ - ( (This)->lpVtbl -> GetFolder(This,ppsi) ) - -#define IFileSaveDialog_GetCurrentSelection(This,ppsi) \ - ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) - -#define IFileSaveDialog_SetFileName(This,pszName) \ - ( (This)->lpVtbl -> SetFileName(This,pszName) ) - -#define IFileSaveDialog_GetFileName(This,pszName) \ - ( (This)->lpVtbl -> GetFileName(This,pszName) ) - -#define IFileSaveDialog_SetTitle(This,pszTitle) \ - ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) - -#define IFileSaveDialog_SetOkButtonLabel(This,pszText) \ - ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) - -#define IFileSaveDialog_SetFileNameLabel(This,pszLabel) \ - ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) - -#define IFileSaveDialog_GetResult(This,ppsi) \ - ( (This)->lpVtbl -> GetResult(This,ppsi) ) - -#define IFileSaveDialog_AddPlace(This,psi,fdap) \ - ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) - -#define IFileSaveDialog_SetDefaultExtension(This,pszDefaultExtension) \ - ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) - -#define IFileSaveDialog_Close(This,hr) \ - ( (This)->lpVtbl -> Close(This,hr) ) - -#define IFileSaveDialog_SetClientGuid(This,guid) \ - ( (This)->lpVtbl -> SetClientGuid(This,guid) ) - -#define IFileSaveDialog_ClearClientData(This) \ - ( (This)->lpVtbl -> ClearClientData(This) ) - -#define IFileSaveDialog_SetFilter(This,pFilter) \ - ( (This)->lpVtbl -> SetFilter(This,pFilter) ) - - -#define IFileSaveDialog_SetSaveAsItem(This,psi) \ - ( (This)->lpVtbl -> SetSaveAsItem(This,psi) ) - -#define IFileSaveDialog_SetProperties(This,pStore) \ - ( (This)->lpVtbl -> SetProperties(This,pStore) ) - -#define IFileSaveDialog_SetCollectedProperties(This,pList,fAppendDefault) \ - ( (This)->lpVtbl -> SetCollectedProperties(This,pList,fAppendDefault) ) - -#define IFileSaveDialog_GetProperties(This,ppStore) \ - ( (This)->lpVtbl -> GetProperties(This,ppStore) ) - -#define IFileSaveDialog_ApplyProperties(This,psi,pStore,hwnd,pSink) \ - ( (This)->lpVtbl -> ApplyProperties(This,psi,pStore,hwnd,pSink) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __IFileSaveDialog_INTERFACE_DEFINED__ */ - - -class DECLSPEC_UUID("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7") FileOpenDialog; -class DECLSPEC_UUID("C0B4E2F3-BA21-4773-8DBA-335EC946EB8B") FileSaveDialog; - -_COM_SMARTPTR_TYPEDEF(IFileDialog, __uuidof(IFileDialog)); -_COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog)); -_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); -_COM_SMARTPTR_TYPEDEF(IFileDialogCustomize, __uuidof(IFileDialogCustomize)); -_COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray)); - -//helper class -class Win7FileDialog -{ -public: - Win7FileDialog(const char *name, int issave=0); - ~Win7FileDialog(); - - int inited() { return m_fod != NULL; } - int show(HWND parent); - - void setFilterList(const char *list); - void setDefaultExtension(const char *ext); - void setFileTypeIndex(int i); //1-based - void setFolder(const char *folder, int def=1); //def is for default folder - void setFilename(const char *fn); - void setTemplate(HINSTANCE inst, const char *dlgid, LPOFNHOOKPROC proc); - - void addOptions(DWORD o); - - void startGroup(DWORD id, char *label); - void addText(DWORD id, char *txt); - void addCheckbox(char *name, DWORD id, int defval); - void endGroup(); - - int getState(DWORD id); - void getResult(char *fn, int maxlen); - int getResult(int i, char *fn, int maxlen); - -private: - IFileDialogPtr m_fod; - IFileDialogCustomizePtr m_fdc; - - HINSTANCE m_inst; - const char *m_dlgid; - LPOFNHOOKPROC m_proc; - - WDL_String m_statictxt; -}; -#endif - -#endif diff --git a/WDL/wingui/dlgitemborder.h b/WDL/wingui/dlgitemborder.h deleted file mode 100644 index ff7dd436..00000000 --- a/WDL/wingui/dlgitemborder.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - WDL - dlgitemborder.h - Copyright (C) 1998-2003, Nullsoft Inc. - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides code to aide in drawing additional borders in dialogs. - - */ - - -#ifndef _WDL_DLGITEMBORDER_H_ -#define _WDL_DLGITEMBORDER_H_ - -#define DCW_SUNKENBORDER 0x00010000 -#define DCW_SUNKENBORDER_NOTOP 0x00020000 -#define DCW_DIVIDER_VERT 0x00030000 -#define DCW_DIVIDER_HORZ 0x00040000 -#define DCW_HWND_FOLLOW 0x40000000 - -#ifndef WDL_DLGITEMBORDER_NOIMPL - -static int RectInRect(RECT *rect1, RECT *rect2) -{ - // this has a bias towards true - - // this could probably be optimized a lot - return ((rect1->top >= rect2->top && rect1->top <= rect2->bottom) || - (rect1->bottom >= rect2->top && rect1->bottom <= rect2->bottom) || - (rect2->top >= rect1->top && rect2->top <= rect1->bottom) || - (rect2->bottom >= rect1->top && rect2->bottom <= rect1->bottom)) // vertical intersect - && - ((rect1->left >= rect2->left && rect1->left <= rect2->right) || - (rect1->right >= rect2->left && rect1->right <= rect2->right) || - (rect2->left >= rect1->left && rect2->left <= rect1->right) || - (rect2->right >= rect1->left && rect2->right <= rect1->right)) // horiz intersect - ; -} - -#ifdef _WIN32 -static void Dlg_removeFromRgn(HRGN hrgn, int left, int top, int right, int bottom) -{ - HRGN rgn2=CreateRectRgn(left,top,right,bottom); - CombineRgn(hrgn,hrgn,rgn2,RGN_DIFF); - DeleteObject(rgn2); -} -#else -#define Dlg_removeFromRgn(a,b,c,d,e) -#endif - -static void Dlg_DrawChildWindowBorders(HWND hwndDlg, INT_PTR *tab, int tabsize, int (*GSC)(int)=0, PAINTSTRUCT *__use_ps=NULL -#ifdef WDL_DLGITEMBORDER_CUSTOMPARMS - , WDL_DLGITEMBORDER_CUSTOMPARMS -#endif - - ) -{ - PAINTSTRUCT ps; - if (!__use_ps) - { - BeginPaint(hwndDlg,&ps); - __use_ps=&ps; - } - -#ifdef _WIN32 - HRGN hrgn=NULL; - if(__use_ps->fErase) - { - RECT r=__use_ps->rcPaint; - hrgn=CreateRectRgn(r.left,r.top,r.right,r.bottom); - } -#else - int hrgn=0; -#endif - - HPEN pen=CreatePen(PS_SOLID,0,GSC?GSC(COLOR_3DHILIGHT):GetSysColor(COLOR_3DHILIGHT)); - HPEN pen2=CreatePen(PS_SOLID,0,GSC?GSC(COLOR_3DSHADOW):GetSysColor(COLOR_3DSHADOW)); - - while (tabsize--) - { - RECT r; - int a=*tab++; - if (a & DCW_HWND_FOLLOW) - { - a&=~DCW_HWND_FOLLOW; - if (!tabsize) break; - GetWindowRect((HWND)*tab++,&r); - tabsize--; - - ScreenToClient(hwndDlg,(LPPOINT)&r); - ScreenToClient(hwndDlg,((LPPOINT)&r)+1); - } - else - { - int sa=a&0xffff; - if (sa == 0) - { - GetClientRect(hwndDlg,&r); - } - else - { - GetWindowRect(GetDlgItem(hwndDlg,sa),&r); - - #ifdef CUSTOM_CHILDWNDBORDERCODE - CUSTOM_CHILDWNDBORDERCODE - #endif - ScreenToClient(hwndDlg,(LPPOINT)&r); - ScreenToClient(hwndDlg,((LPPOINT)&r)+1); - } - } - - if (RectInRect(&__use_ps->rcPaint,&r)) - { - if ((a & 0xffff0000) == DCW_SUNKENBORDER || (a&0xffff0000) == DCW_SUNKENBORDER_NOTOP) - { - MoveToEx(__use_ps->hdc,r.left-1,r.bottom,NULL); - HGDIOBJ o=SelectObject(__use_ps->hdc,pen); - LineTo(__use_ps->hdc,r.right,r.bottom); - LineTo(__use_ps->hdc,r.right,r.top-1); - SelectObject(__use_ps->hdc,pen2); - if ((a&0xffff0000) == DCW_SUNKENBORDER_NOTOP) - MoveToEx(__use_ps->hdc,r.left-1,r.top-1,NULL); - else - LineTo(__use_ps->hdc,r.left-1,r.top-1); - LineTo(__use_ps->hdc,r.left-1,r.bottom); - SelectObject(__use_ps->hdc,o); - if(hrgn) - { - Dlg_removeFromRgn(hrgn,r.left,r.bottom,r.right,r.bottom+1); - Dlg_removeFromRgn(hrgn,r.right,r.top,r.right+1,r.bottom); - if ((a&0xffff0000) != DCW_SUNKENBORDER_NOTOP) - Dlg_removeFromRgn(hrgn,r.left,r.top-1,r.right,r.top); - Dlg_removeFromRgn(hrgn,r.left-1,r.top,r.left,r.bottom); - } - } - else if ((a & 0xffff0000) == DCW_DIVIDER_VERT || (a & 0xffff0000) == DCW_DIVIDER_HORZ) - { - if ((a & 0xffff0000) == DCW_DIVIDER_VERT) // vertical - { - int left=r.left; - HGDIOBJ o=SelectObject(__use_ps->hdc,pen2); - MoveToEx(__use_ps->hdc,left,r.top,NULL); - LineTo(__use_ps->hdc,left,r.bottom+1); - SelectObject(__use_ps->hdc,pen); - MoveToEx(__use_ps->hdc,left+1,r.top,NULL); - LineTo(__use_ps->hdc,left+1,r.bottom+1); - SelectObject(__use_ps->hdc,o); - if(hrgn) Dlg_removeFromRgn(hrgn,left,r.top,left+2,r.bottom); - } - else // horiz - { - int top=r.top+1; - HGDIOBJ o=SelectObject(__use_ps->hdc,pen2); - MoveToEx(__use_ps->hdc,r.left,top,NULL); - LineTo(__use_ps->hdc,r.right+1,top); - SelectObject(__use_ps->hdc,pen); - MoveToEx(__use_ps->hdc,r.left,top+1,NULL); - LineTo(__use_ps->hdc,r.right+1,top+1); - SelectObject(__use_ps->hdc,o); - if(hrgn) Dlg_removeFromRgn(hrgn,r.left,top,r.right,top+2); - } - } - } - } - - DeleteObject(pen); - DeleteObject(pen2); - -#ifdef _WIN32 - if(hrgn) { - //erase bkgnd while clipping out our own drawn stuff (for flickerless display) -#ifdef WDL_DLGITEMBORDER_CUSTOMBGCODE - WDL_DLGITEMBORDER_CUSTOMBGCODE -#else - HBRUSH b=CreateSolidBrush(GSC?GSC(COLOR_3DFACE):GetSysColor(COLOR_3DFACE)); - FillRgn(__use_ps->hdc,hrgn,b); - DeleteObject(b); -#endif - - DeleteObject(hrgn); - } -#endif - if (__use_ps == &ps) EndPaint(hwndDlg,&ps); -} - -#endif - -#endif \ No newline at end of file diff --git a/WDL/wingui/membitmap.h b/WDL/wingui/membitmap.h deleted file mode 100644 index bed2700b..00000000 --- a/WDL/wingui/membitmap.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - WDL - membitmap.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides a wrapper around the win32 bitmaps, to allow the callee to easily - manage a framebuffer. It's mostly deprecated by LICE/, however. - - */ - - - -#ifndef _WDL_WINMEMBITMAP_H_ -#define _WDL_WINMEMBITMAP_H_ - -#ifndef _WIN32 -#include "../swell/swell.h" -#endif - -class WDL_WinMemBitmap -{ -public: - WDL_WinMemBitmap() - { - m_w=m_h=-100; - m_hdc=0; -#ifdef _WIN32 - m_bm=0; m_oldbm=0; -#endif - } - ~WDL_WinMemBitmap() - { -#ifdef _WIN32 - if (m_oldbm) SelectObject(m_hdc,m_oldbm); - if (m_bm) DeleteObject(m_bm); - - if (m_hdc) DeleteDC(m_hdc); -#else - if (m_hdc) SWELL_DeleteGfxContext(m_hdc); -#endif - } - - int DoSize(HDC compatDC, int w, int h) // returns 1 if it was resized - { - if (m_w == w && m_h == h && m_hdc -#ifdef _WIN32 - && m_bm -#endif - ) return 0; - -#ifdef _WIN32 - if (!m_hdc) m_hdc=CreateCompatibleDC(compatDC); - if (m_oldbm) SelectObject(m_hdc,m_oldbm); - if (m_bm) DeleteObject(m_bm); - m_bm=CreateCompatibleBitmap(compatDC,m_w=w,m_h=h); - m_oldbm=SelectObject(m_hdc,m_bm); -#else - if (m_hdc) SWELL_DeleteGfxContext(m_hdc); - m_hdc=SWELL_CreateMemContext(compatDC,m_w=w,m_h=h); -#endif - return 1; - } - int GetW() { return m_w; } - int GetH() { return m_h; } - HDC GetDC() { return m_hdc; } - -private: - - HDC m_hdc; -#ifdef _WIN32 - HBITMAP m_bm; - HGDIOBJ m_oldbm; -#endif - int m_w,m_h; -}; - - -#endif \ No newline at end of file diff --git a/WDL/wingui/richeditctrl.h b/WDL/wingui/richeditctrl.h deleted file mode 100644 index 5fca39ae..00000000 --- a/WDL/wingui/richeditctrl.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - WDL - richeditctrl.h - Copyright (C) 2005 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - */ - - -#ifndef _WDL_RICHEDITCTRL_H -#define _WDL_RICHEDITCTRL_H - -#include -#include - -class WDL_RichEditCtrl -{ - public: - WDL_RichEditCtrl() { setWnd(NULL); m_color=0; m_bold=0; } - WDL_RichEditCtrl(HWND hwnd) { setWnd(hwnd); m_color=0; m_bold=0; } - ~WDL_RichEditCtrl() { }; - - void setWnd(HWND hwnd) { - m_hwnd=hwnd; - if(hwnd) { - SendMessage(m_hwnd, EM_SETEVENTMASK, 0, ENM_LINK); - SendMessage(m_hwnd, EM_AUTOURLDETECT, 1, 0); - } - } - HWND getWnd() { return m_hwnd; } - - int getLength() { return GetWindowTextLength(m_hwnd); } - void getText(char *txt, int size) { GetWindowText(m_hwnd, txt, size); } - void setText(char *txt) { SetWindowText(m_hwnd, txt); } - void addText(char *txt) - { - setSel(getLength(), getLength()); - CHARFORMAT2 cf2; - cf2.cbSize=sizeof(cf2); - cf2.dwMask=CFM_COLOR|CFM_BOLD; - cf2.dwEffects=m_bold?CFE_BOLD:0; - cf2.crTextColor=m_color; - SendMessage(m_hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); - replaceSel(txt); - - int mi,ma; - GetScrollRange(m_hwnd,SB_VERT,&mi,&ma); - SendMessage(m_hwnd, WM_VSCROLL, (ma<<16)+SB_THUMBPOSITION,0); - //SetScrollPos(m_hwnd,SB_VERT,ma,TRUE); - - //SendMessage(m_hwnd, WM_VSCROLL, SB_BOTTOM,0); // buggy on windows ME - } - void setSel(int start, int end) { SendMessage(m_hwnd, EM_SETSEL, start, end); } - void replaceSel(char *txt) { SendMessage(m_hwnd, EM_REPLACESEL, 0L, (LPARAM)txt); } - - void clear() { setText(""); } - - void setTextColor(int color) { m_color=color; } - - void setBold(int b) { m_bold=b; } - - protected: - HWND m_hwnd; - COLORREF m_color; - int m_bold; -}; - -#endif//_WDL_RICHEDITCTRL_H \ No newline at end of file diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp deleted file mode 100644 index 830b3aee..00000000 --- a/WDL/wingui/scrollbar/coolscroll.cpp +++ /dev/null @@ -1,3741 +0,0 @@ -/* - WDL - Skinned/Resizing thumb scrollbar library - Based on the "Cool Scrollbar Library v1.2" by James Brown - http://www.catch22.net - - Original version Copyright(c) 2001 J Brown - Modifications copyright (C) 2006 and later Cockos Incorporated - - Note: for a more featureful and complete, less hacked up version, you may wish to - download the original from http://www.catch22.net. It has lots of added features, - whereas this version is very much tailored for Cockos' needs. - - License: - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Original readme from Cool Scrollbar Library Version 1.2 - - Copyright (c) J Brown 2001 - - This code is freeware, however, you may not publish - this code elsewhere or charge any money for it. This code - is supplied as-is. I make no guarantees about the suitability - of this code - use at your own risk. - - It would be nice if you credited me, in the event - that you use this code in a product. - - VERSION HISTORY: - - V1.2: TreeView problem fixed by Diego Tartara - Small problem in thumbsize calculation also fixed (thanks Diego!) - - V1.1: Added support for Right-left windows - Changed calling convention of APIs to WINAPI (__stdcall) - Completely standalone (no need for c-runtime) - Now supports ALL windows with appropriate USER32.DLL patching - (you provide!!) - - V1.0: Apr 2001: Initial Version - - IMPORTANT: - This whole library is based around code for a horizontal scrollbar. - All "vertical" scrollbar drawing / mouse interaction uses the - horizontal scrollbar functions, but uses a trick to convert the vertical - scrollbar coordinates into horizontal equivelants. When I started this project, - I quickly realised that the code for horz/vert bars was IDENTICAL, apart - from the fact that horizontal code uses left/right coords, and vertical code - uses top/bottom coords. On entry to a "vertical" drawing function, for example, - the coordinates are "rotated" before the horizontal function is called, and - then rotated back once the function has completed. When something needs to - be drawn, the coords are converted back again before drawing. - - This trick greatly reduces the amount of code required, and makes - maintanence much simpler. This way, only one function is needed to draw - a scrollbar, but this can be used for both horizontal and vertical bars - with careful thought. - - Notes on Cockos modifications: - - We tweaked this to support resizing thumbs, native zoom buttons, etc, and skinnability using LICE (if a skin image is supplied). - Additionally we modified it to support OS X using SWELL (since SWELL does not provide a scrollbar API, this can be used for that purpose). - We also shoved everything into one file, for various reasons. - -*/ - -#ifdef _WIN32 - #include - #include - #include - #include -#else - #include "../../swell/swell.h" - #define __stdcall - typedef char TCHAR; - #ifndef SWP_FRAMECHANGED - #define SWP_FRAMECHANGED 0 - #endif -#endif - -#include "../../lice/lice.h" -#include "../../ptrlist.h" - -#include "coolscroll.h" - -#define ZOOMBUTTON_RESIZER_SIZE(zbs) (max(((zbs)/4),2)) -#define MIN_SIZE_FOR_ZOOMBUTTONS(zbs) (6*(zbs)) - -// -// SCROLLBAR datatype. There are two of these structures per window -// -typedef struct -{ - UINT fScrollFlags; //flags - BOOL fScrollVisible; //if this scrollbar visible? - SCROLLINFO scrollInfo; //positional data (range, position, page size etc) - - int nBarType; //SB_HORZ / SB_VERT - - int nMinThumbSize; - - LICE_SysBitmap *liceBkgnd; - LICE_SysBitmap *liceThumb; - int liceBkgnd_ver; - int liceThumb_ver; - - int liceThumbState; - -} SCROLLBAR; - -// -// Container structure for a cool scrollbar window. -// -typedef struct -{ - UINT bars; //which of the scrollbars do we handle? SB_VERT / SB_HORZ / SB_BOTH - WNDPROC oldproc; //old window procedure to call for every message - - SCROLLBAR sbarHorz; //one scrollbar structure each for - SCROLLBAR sbarVert; //the horizontal and vertical scrollbars - - BOOL fThumbTracking; // are we currently thumb-tracking?? - BOOL fLeftScrollbar; // support the WS_EX_LEFTSCROLLBAR style - - //size of the window borders - int cxLeftEdge, cxRightEdge; - int cyTopEdge, cyBottomEdge; - - // To prevent calling original WindowProc in response - // to our own temporary style change (fixes TreeView problem) - BOOL bPreventStyleChange; - - BOOL resizingHthumb; - - - // internal state stuff - - UINT uScrollTimerMsg; - - UINT uMouseOverId; - UINT uScrollTimerId; - UINT uZoomTimerId, uZoomTimerMode; - - RECT MouseOverRect; - BOOL MouseOverRect_hasZoomButtons; - - UINT uCurrentScrollbar; - UINT uCurrentScrollPortion; - UINT uMouseOverScrollbar; - UINT uHitTestPortion; - UINT uLastHitTestPortion; - UINT uScrollTimerPortion; - - -} SCROLLWND; - - - -// -// Minimum size in pixels of a scrollbar thumb -// -#define MINTHUMBSIZE_NT4 8 -#define MINTHUMBSIZE_2000 6 -#define RESIZETHUMBSIZE 6 - - -// To complement the exisiting SB_HORZ, SB_VERT, SB_BOTH -// scrollbar identifiers -#define COOLSB_NONE (-1) - -// general scrollbar styles -// -// use the standard ESB_DISABLE_xxx flags to represent the -// enabled / disabled states. (defined in winuser.h) -// -#define CSBS_THUMBALWAYS 4 -#define CSBS_VISIBLE 8 - - -//define some more hittest values for our cool-scrollbar -#define HTSCROLL_LEFT (SB_LINELEFT) -#define HTSCROLL_RIGHT (SB_LINERIGHT) -#define HTSCROLL_UP (SB_LINEUP) -#define HTSCROLL_DOWN (SB_LINEDOWN) -#define HTSCROLL_THUMB (SB_THUMBTRACK) -#define HTSCROLL_PAGEGUP (SB_PAGEUP) -#define HTSCROLL_PAGEGDOWN (SB_PAGEDOWN) -#define HTSCROLL_PAGELEFT (SB_PAGELEFT) -#define HTSCROLL_PAGERIGHT (SB_PAGERIGHT) - -#define HTSCROLL_NONE (-1) -#define HTSCROLL_NORMAL (-1) - -#define HTSCROLL_INSERTED (128) -#define HTSCROLL_PRE (32 | HTSCROLL_INSERTED) -#define HTSCROLL_POST (64 | HTSCROLL_INSERTED) - -#define HTSCROLL_LRESIZER (256) -#define HTSCROLL_RRESIZER (256+1) - -#define HTSCROLL_RESIZER (256+2) - -#define HTSCROLL_ZOOMIN (256+3) -#define HTSCROLL_ZOOMOUT (256+4) - - -// -#define SM_CXVERTSB 1 -#define SM_CYVERTSB 0 -#define SM_CXHORZSB 0 -#define SM_CYHORZSB 1 -#define SM_SCROLL_WIDTH 1 -#define SM_SCROLL_LENGTH 0 - - - -#define InvertCOLORREF(col) ((col) ^ RGB(255,255,255)) - -#define COOLSB_TIMERID1 65533 //initial timer -#define COOLSB_TIMERID2 65534 //scroll message timer -#define COOLSB_TIMERID3 -14 //mouse hover timer -#define COOLSB_TIMERID4 0xfffef110 // used for when holding a zoom button -#define COOLSB_TIMERINTERVAL1 300 -#define COOLSB_TIMERINTERVAL2 55 -#define COOLSB_TIMERINTERVAL3 20 //mouse hover time -#define COOLSB_TIMERINTERVAL4 150 //holding the zoom buttons - - - - -static int g_coolsb_imageVersion; // liceBkgnd_ver, liceThumb_ver - -static LICE_IBitmap **m_scrollbar_bmp = NULL; -static int m_scrollbar_hasPink; -static int m_sb_thumbHV[5], m_sb_thumbVV[5]; // -static int m_sb_bkghl, m_sb_bkghr; -static int m_sb_bkgvt, m_sb_bkgvb; - - - - -// -// Special thumb-tracking variables -// -// - -static RECT rcThumbBounds; //area that the scroll thumb can travel in -static int nThumbSize; //(pixels) -static int nThumbPos; //(pixels) -static int nThumbMouseOffset; //(pixels) -static int nLastPos = -1; //(scrollbar units) -static int nThumbPos0; //(pixels) initial thumb position - -// -// Temporary state used to auto-generate timer messages -// - -static HWND hwndCurCoolSB = 0; -static float m_scale = 1.0; -static int m_thumbsize = 6; - -static LRESULT MouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam); - -static SCROLLWND *GetScrollWndFromHwnd(HWND hwnd); -// -// Provide this so there are NO dependencies on CRT -// - - -// -// swap the rectangle's x coords with its y coords -// -static void __stdcall RotateRect(RECT *rect) -{ - int temp; - temp = rect->left; - rect->left = rect->top; - rect->top = temp; - - temp = rect->right; - rect->right = rect->bottom; - rect->bottom = temp; -} - -// -// swap the coords if the scrollbar is a SB_VERT -// -static void __stdcall RotateRect0(SCROLLBAR *sb, RECT *rect) -{ - if(sb->nBarType == SB_VERT) - RotateRect(rect); -} - -// -// Calculate if the SCROLLINFO members produce -// an enabled or disabled scrollbar -// -static BOOL IsScrollInfoActive(SCROLLINFO *si) -{ - if((si->nPage > (UINT)si->nMax - || si->nMax <= si->nMin || si->nMax == 0)) - return FALSE; - else - return TRUE; -} - -// -// Return if the specified scrollbar is enabled or not -// -static BOOL IsScrollbarActive(SCROLLBAR *sb) -{ - SCROLLINFO *si = &sb->scrollInfo; - if(((sb->fScrollFlags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) || - !(sb->fScrollFlags & CSBS_THUMBALWAYS) && !IsScrollInfoActive(si)) - return FALSE; - else - return TRUE; -} - -#ifdef __APPLE__ -static void GET_WINDOW_RECT(HWND hwnd, RECT *r) -{ - GetWindowContentViewRect(hwnd,r); - if (r->top>r->bottom) - { - int tmp = r->top; - r->top = r->bottom; - r->bottom = tmp; - } - -} -#else -#define GET_WINDOW_RECT(hwnd, r) GetWindowRect(hwnd,r) -#endif - -#ifdef __APPLE__ -static void OSX_REMAP_SCREENY(HWND hwnd, LONG *y) -{ -// POINT p={0,0}; - //ClientToScreen(hwnd,&p); - POINT p={0,*y}; - RECT tr; - GetClientRect(hwnd,&tr); - ScreenToClient(hwnd,&p); - p.y-=tr.top; - RECT r; - GetWindowRect(hwnd,&r); - - *y=min(r.bottom,r.top)+p.y; -// map Y from "screen" coordinate -} - -#else - -#define OSX_REMAP_SCREENY(hwnd, y) -#endif - -static BOOL ownDrawEdge(HWND hwnd, HDC hdc, LPRECT qrc, UINT edge, UINT grfFlags) -{ - HPEN pen1 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT)); - HPEN pen2 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DSHADOW)); - HPEN pen3 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - HPEN pen4 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); - HPEN oldpen = (HPEN)SelectObject(hdc,pen3); - - if(edge == EDGE_RAISED) - { - MoveToEx(hdc, qrc->left, qrc->top, NULL); - LineTo(hdc, qrc->right, qrc->top); - MoveToEx(hdc, qrc->left, qrc->top, NULL); - LineTo(hdc, qrc->left, qrc->bottom); - SelectObject(hdc,pen1); - MoveToEx(hdc, qrc->left+1, qrc->top+1, NULL); - LineTo(hdc, qrc->right-1, qrc->top+1); - MoveToEx(hdc, qrc->left+1, qrc->top+1, NULL); - LineTo(hdc, qrc->left+1, qrc->bottom-2); - SelectObject(hdc,pen2); - MoveToEx(hdc, qrc->left+1, qrc->bottom-2, NULL); - LineTo(hdc, qrc->right-1, qrc->bottom-2); - MoveToEx(hdc, qrc->right-2, qrc->bottom-2, NULL); - LineTo(hdc, qrc->right-2, qrc->top+1); - SelectObject(hdc,pen4); - MoveToEx(hdc, qrc->left, qrc->bottom-1, NULL); - LineTo(hdc, qrc->right, qrc->bottom-1); - MoveToEx(hdc, qrc->right-1, qrc->bottom-1, NULL); - LineTo(hdc, qrc->right-1, qrc->top); - } - else - { - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - FillRect(hdc, qrc, br); - DeleteObject(br); - - SelectObject(hdc, pen2); - MoveToEx(hdc, qrc->left, qrc->top, NULL); - LineTo(hdc, qrc->right, qrc->top); - MoveToEx(hdc, qrc->right-1, qrc->top, NULL); - LineTo(hdc, qrc->right-1, qrc->bottom); - MoveToEx(hdc, qrc->right-1, qrc->bottom-1, NULL); - LineTo(hdc, qrc->left, qrc->bottom-1); - MoveToEx(hdc, qrc->left, qrc->bottom-1, NULL); - LineTo(hdc, qrc->left, qrc->top); - } - - SelectObject(hdc, oldpen); - - DeleteObject(pen1); - DeleteObject(pen2); - DeleteObject(pen3); - DeleteObject(pen4); - - if(grfFlags & BF_ADJUST) - { - qrc->left+=2; - qrc->top+=2; - qrc->bottom-=2; - qrc->right-=2; - } - return 1; -} - - -static LRESULT CallWindowProcStyleMod(SCROLLWND *sw, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ -#ifdef _WIN32 - bool restore=false; - DWORD dwStyle = GetWindowLong(hwnd,GWL_STYLE); - if (!sw->bPreventStyleChange && ( dwStyle & (WS_VSCROLL|WS_HSCROLL) )) - { - sw->bPreventStyleChange = TRUE; - SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~(WS_VSCROLL|WS_HSCROLL)); - restore = true; - } -#endif - - LRESULT ret = CallWindowProc(sw->oldproc,hwnd,msg,wParam,lParam); -#ifdef _WIN32 - if (restore) - { - SetWindowLong(hwnd, GWL_STYLE, dwStyle); - sw->bPreventStyleChange = FALSE; - } -#endif - return ret; -} - -static BOOL ownDrawFrameControl(HWND hwnd, HDC hdc, LPRECT lprc, UINT uType, UINT uState, int mouseOver) -{ - LICE_IBitmap *bmp; - if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) - { - static LICE_SysBitmap tmpbmp; - int w = lprc->right-lprc->left; - int h = lprc->bottom-lprc->top; - int startx = 116; - int starty = 121; - if((uState&0xf) == DFCS_SCROLLLEFT) starty += 20; - else if((uState&0xf) == DFCS_SCROLLRIGHT) starty += 40; - else if((uState&0xf) == DFCS_SCROLLDOWN) starty += 60; - if(uState & DFCS_PUSHED) startx += 34; - else if(mouseOver) startx += 17; - - if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) - tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); - - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - #ifndef _WIN32 - SWELL_SyncCtxFrameBuffer(tmpbmp.getDC()); - #endif - BitBlt(hdc, lprc->left, lprc->top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - return 1; - } - - RECT r = *lprc; - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - HBRUSH br2 = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNTEXT)); - HPEN pen = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_BTNTEXT)); - HPEN oldpen; - HBRUSH oldbrush; - - ownDrawEdge(hwnd,hdc, &r, uState&DFCS_PUSHED?EDGE_ETCHED:EDGE_RAISED, BF_ADJUST); - FillRect(hdc, &r, br); - - if(uState & DFCS_PUSHED) - { - r.left++; - r.top++; - r.bottom++; - r.right++; - } - if(!((r.bottom-r.top)&1)) - { - if((uState&0xf) == DFCS_SCROLLRIGHT || (uState&0xf) == DFCS_SCROLLLEFT) - { - /*if ((uState&0xf) == DFCS_SCROLLLEFT) r.right++; - else r.left--; - r.top--;*/ - r.bottom--; - if ((uState&0xf) == DFCS_SCROLLRIGHT) - { - r.left--; - r.right--; - } - } - else - { - /*if ((uState&0xf) != DFCS_SCROLLUP) r.top--; - else r.bottom++; - r.left--;*/ - r.right--; - if ((uState&0xf) != DFCS_SCROLLUP) - { - r.top--; - r.bottom--; - } - else - { - r.top++; - r.bottom++; - } - } - } - oldpen = (HPEN)SelectObject(hdc, pen); - oldbrush = (HBRUSH)SelectObject(hdc, br2); - if((uState&0xf) == DFCS_SCROLLRIGHT) - { - int h = r.bottom-r.top-6; - POINT p[3]={{r.right-4,r.top+3+(h/2)},{r.left+5,r.top+2},{r.left+5,r.bottom-3}}; - Polygon(hdc, p, 3); - } - else if((uState&0xf) == DFCS_SCROLLLEFT) - { - int h = r.bottom-r.top-6; - POINT p[3]={{r.left+3,r.top+3+(h/2)},{r.right-6,r.top+2},{r.right-6,r.bottom-3}}; - Polygon(hdc, p, 3); - } - else if((uState&0xf) == DFCS_SCROLLDOWN) - { - int w = r.right-r.left-6; - POINT p[3]={{r.left+3+(w/2),r.bottom-4},{r.left+2,r.top+5},{r.right-3,r.top+5}}; - Polygon(hdc, p, 3); - } - else if((uState&0xf) == DFCS_SCROLLUP) - { - int w = r.right-r.left-6; - POINT p[3]={{r.left+3+(w/2),r.top+3},{r.left+2,r.bottom-6},{r.right-3,r.bottom-6}}; - Polygon(hdc, p, 3); - } - - SelectObject(hdc, oldpen); - SelectObject(hdc, oldbrush); - - DeleteObject(br); - DeleteObject(br2); - DeleteObject(pen); - - return 1; -} - -// -// Draw a standard scrollbar arrow -// -static int DrawScrollArrow(HWND hwnd, SCROLLBAR *sbar, HDC hdc, RECT *rect, UINT arrow, BOOL fMouseDown, BOOL fMouseOver) -{ - UINT ret; - UINT flags = arrow; - - //HACKY bit so this routine can be called by vertical and horizontal code - if(sbar->nBarType == SB_VERT) - { - if(flags & DFCS_SCROLLLEFT) flags = (flags & ~DFCS_SCROLLLEFT) | DFCS_SCROLLUP; - if(flags & DFCS_SCROLLRIGHT) flags = (flags & ~DFCS_SCROLLRIGHT) | DFCS_SCROLLDOWN; - } - - if(fMouseDown) flags |= (DFCS_FLAT | DFCS_PUSHED); - - - ret = ownDrawFrameControl(hwnd,hdc, rect, DFC_SCROLL, flags, fMouseOver); - - return ret; -} - -void CoolSB_SetScale(float scale) -{ - m_scale = scale; - m_thumbsize = (int)(RESIZETHUMBSIZE * scale); - if (m_thumbsize<2)m_thumbsize=2; -} - -// -// Return the size in pixels for the specified scrollbar metric, -// for the specified scrollbar -// -static int GetScrollMetric(BOOL isVert, int metric) -{ - if(!isVert) - { - if(metric == SM_CXHORZSB) - { - return (int)(GetSystemMetrics(SM_CXHSCROLL) * m_scale); - } - else - { - return (int)(GetSystemMetrics(SM_CYHSCROLL) * m_scale); - } - } - else - { - if(metric == SM_CYVERTSB) - { - return (int)(GetSystemMetrics(SM_CYVSCROLL) * m_scale); - } - else - { - return (int)(GetSystemMetrics(SM_CXVSCROLL) * m_scale); - } - } - - return 0; -} -static int GetZoomButtonSize(BOOL isVert) -{ - return (int)(GetSystemMetrics(isVert ? SM_CYVSCROLL : SM_CXHSCROLL) * m_scale); -} - - -// -// -// -static COLORREF GetSBForeColor(HWND hwnd) -{ - COLORREF c1 = CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT); - COLORREF c2 = CoolSB_GetSysColor(hwnd,COLOR_WINDOW); - - if(c1 != 0xffffff && c1 == c2) - { - return CoolSB_GetSysColor(hwnd,COLOR_BTNFACE); - } - else - { - return CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT); - } -} - -static COLORREF GetSBBackColor(HWND hwnd) -{ - return CoolSB_GetSysColor(hwnd,COLOR_SCROLLBAR); -} - -// -// Paint a checkered rectangle, with each alternate -// pixel being assigned a different colour -// -static void DrawCheckedRect(LICE_IBitmap *bmOut, HDC hdc, RECT *rect, COLORREF fg, COLORREF bg, SCROLLBAR *sb, const RECT *wndrect, int on, int offsx=0, int offsy=0) -{ - int isvert = sb->nBarType==SB_VERT; - - LICE_IBitmap *bmp; - if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) - { - int w = rect->right-rect->left; - int h = rect->bottom-rect->top; - int ww = wndrect->right - wndrect->left; - int wh = wndrect->bottom - wndrect->top; - if(isvert) - { - ww = wndrect->bottom - wndrect->top; - wh = wndrect->right - wndrect->left; - } - int nw = ww; - int nh = wh; - if(!isvert) nh *= 2; - else nw *= 2; - - if(!sb->liceBkgnd || sb->liceBkgnd->getWidth()!=nw || sb->liceBkgnd->getHeight()!=nh || sb->liceBkgnd_ver!=g_coolsb_imageVersion) - { - sb->liceBkgnd_ver=g_coolsb_imageVersion; - if(!sb->liceBkgnd) sb->liceBkgnd = new LICE_SysBitmap; - sb->liceBkgnd->resize(nw, nh); - if(!isvert) - { - int desth = nh/2; - if(m_scrollbar_hasPink) - { - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, m_sb_bkghl, desth, - 0, 0, m_sb_bkghl, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, m_sb_bkghl, 0, ww-m_sb_bkghl-m_sb_bkghr, desth, - m_sb_bkghl, 0, 204-m_sb_bkghl-m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, ww-m_sb_bkghr, 0, m_sb_bkghr, desth, - 204-m_sb_bkghr, 0, m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, desth, m_sb_bkghl, desth, - 0, 17, m_sb_bkghl, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, m_sb_bkghl, desth, ww-m_sb_bkghl-m_sb_bkghr, desth, - m_sb_bkghl, 17, 204-m_sb_bkghl-m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, ww-m_sb_bkghr, desth, m_sb_bkghr, desth, 204-m_sb_bkghr, - 17, m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - } - else - { - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, ww, desth, 0, 0, 204, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, desth, ww, desth, 0, 17, 204, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - } - } - else - { - int destw = nw/2; - int starty = 34; - if(m_scrollbar_hasPink) - { - starty = 37; - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, destw, m_sb_bkgvt, - 170, starty, 17, m_sb_bkgvt, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, m_sb_bkgvt, destw, wh-m_sb_bkgvt-m_sb_bkgvb, - 170, starty+m_sb_bkgvt, 17, 238-starty-m_sb_bkgvt-m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, wh-m_sb_bkgvb, destw, m_sb_bkgvb, - 170, 238-m_sb_bkgvb, 17, m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, 0, destw, m_sb_bkgvt, - 187, starty, 17, m_sb_bkgvt, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, m_sb_bkgvt, destw, wh-m_sb_bkgvt-m_sb_bkgvb, - 187, starty+m_sb_bkgvt, 17, 238-starty-m_sb_bkgvt-m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, wh-m_sb_bkgvb, destw, m_sb_bkgvb, - 187, 238-m_sb_bkgvb, 17, m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); - } - else - { - LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, destw, wh, 170, starty, 17, 238-starty, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, 0, destw, wh, 187, starty, 17, 238-starty, 1.0f, LICE_BLIT_FILTER_BILINEAR); - } - } - } - if(!isvert) - { -// if (nh/2 != h) OutputDebugString("blah\n"); - if (bmOut) - LICE_ScaledBlit(bmOut, sb->liceBkgnd, rect->left,rect->top, w, h, - rect->left+offsx,on?nh/2:0, w, nh/2, 1.0f, LICE_BLIT_MODE_COPY); - else - { - BitBlt(hdc, rect->left, rect->top, w, h, sb->liceBkgnd->getDC(), rect->left+offsx, on?nh/2:0, SRCCOPY); - } - } - else - { -// if (nw/2 != w) OutputDebugString("blah2\n"); - if (bmOut) - LICE_ScaledBlit(bmOut, sb->liceBkgnd, rect->left,rect->top, w, h, on?nw/2:0, rect->top+offsy, nw/2, h, 1.0f, LICE_BLIT_MODE_COPY); - else - { - BitBlt(hdc, rect->left, rect->top, w, h, sb->liceBkgnd->getDC(), on?nw/2:0, rect->top+offsy, SRCCOPY); - } - } - return; - } - - static WORD wCheckPat[8] = - { - 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555 - }; - -#ifdef _WIN32 - HBITMAP hbmp; - HBRUSH hbr, hbrold; - COLORREF fgold, bgold; - - hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat); - hbr = CreatePatternBrush(hbmp); - - UnrealizeObject(hbr); - SetBrushOrgEx(hdc, rect->left, rect->top, 0); - - hbrold = (HBRUSH)SelectObject(hdc, hbr); - - fgold = SetTextColor(hdc, fg); - bgold = SetBkColor(hdc, bg); - - PatBlt(hdc, rect->left, rect->top, - rect->right - rect->left, - rect->bottom - rect->top, - PATCOPY); - - SetBkColor(hdc, bgold); - SetTextColor(hdc, fgold); - - SelectObject(hdc, hbrold); - DeleteObject(hbr); - DeleteObject(hbmp); -#else - HBRUSH br=CreateSolidBrush(RGB(100,100,100)); - FillRect(hdc,rect,br); - DeleteObject(br); - //FUCKO> osx version! -#endif - -} - -// -// Fill the specifed rectangle using a solid colour -// -static void PaintRect(HDC hdc, RECT *rect, COLORREF color) -{ -#ifdef _WIN32 - COLORREF oldcol = SetBkColor(hdc, color); - ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, _T(""), 0, 0); - SetBkColor(hdc, oldcol); -#else - HBRUSH br=CreateSolidBrush(color); - FillRect(hdc,rect,br); - DeleteObject(br); -#endif -} - -// -// Draw a simple blank scrollbar push-button. Can be used -// to draw a push button, or the scrollbar thumb -// drawflag - could set to BF_FLAT to make flat scrollbars -// -static void DrawBlankButton(HWND hwnd, HDC hdc, const RECT *rect) -{ - RECT rc = *rect; - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - - ownDrawEdge(hwnd,hdc, &rc, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &rc, br); - DeleteObject(br); -} - -// -// Send a WM_VSCROLL or WM_HSCROLL message -// -static void SendScrollMessage(HWND hwnd, UINT scrMsg, UINT scrId, UINT pos) -{ - SendMessage(hwnd, scrMsg, MAKEWPARAM(scrId, pos), 0); -} - -// -// Calculate the screen coordinates of the area taken by -// the horizontal scrollbar. Take into account the size -// of the window borders -// -static BOOL GetHScrollRect(SCROLLWND *sw, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) -{ - GET_WINDOW_RECT(hwnd, rect); - - if(sw->fLeftScrollbar) - { - rect->left += sw->cxLeftEdge + (sw->sbarVert.fScrollVisible ? - GetScrollMetric(TRUE, SM_CXVERTSB) : 0); - rect->right -= sw->cxRightEdge; - } - else - { - rect->left += sw->cxLeftEdge; //left window edge - - rect->right -= sw->cxRightEdge + //right window edge - (sw->sbarVert.fScrollVisible ? - GetScrollMetric(TRUE, SM_CXVERTSB) : 0); - } - - rect->bottom -= sw->cyBottomEdge; //bottom window edge - - rect->top = rect->bottom - - (sw->sbarHorz.fScrollVisible ? - GetScrollMetric(FALSE, SM_CYHORZSB) : 0); - - if (hasZoomButtons) *hasZoomButtons=0; - if(sw->resizingHthumb) - { - int zbs = GetZoomButtonSize(FALSE); - if (rect->right - rect->left >= MIN_SIZE_FOR_ZOOMBUTTONS(zbs)) - { - if (hasZoomButtons) *hasZoomButtons=1; - rect->right -= zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs); - } - } - //printf("ry=%d,%d\n",rect->top,rect->bottom); - - return TRUE; -} - -// -// Calculate the screen coordinates of the area taken by the -// vertical scrollbar -// -static BOOL GetVScrollRect(SCROLLWND *sw, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) -{ - GET_WINDOW_RECT(hwnd, rect); - rect->top += sw->cyTopEdge; //top window edge - - rect->bottom -= sw->cyBottomEdge + - (sw->sbarHorz.fScrollVisible ? //bottom window edge - GetScrollMetric(FALSE, SM_CYHORZSB) : 0); - - if(sw->fLeftScrollbar) - { - rect->left += sw->cxLeftEdge; - rect->right = rect->left + (sw->sbarVert.fScrollVisible ? - GetScrollMetric(TRUE, SM_CXVERTSB) : 0); - } - else - { - rect->right -= sw->cxRightEdge; - rect->left = rect->right - (sw->sbarVert.fScrollVisible ? - GetScrollMetric(TRUE, SM_CXVERTSB) : 0); - } - - if (hasZoomButtons) *hasZoomButtons=0; - if(sw->resizingHthumb) - { - int zbs = GetZoomButtonSize(TRUE); - if (rect->bottom - rect->top >= MIN_SIZE_FOR_ZOOMBUTTONS(zbs)) - { - if (hasZoomButtons) *hasZoomButtons=1; - rect->bottom -= zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs); - } - } - - return TRUE; -} - -// Depending on what type of scrollbar nBar refers to, call the -// appropriate Get?ScrollRect function -// -static BOOL GetScrollRect(SCROLLWND *sw, UINT nBar, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) -{ - if(nBar == SB_HORZ) - return GetHScrollRect(sw, hwnd, rect,hasZoomButtons); - else if(nBar == SB_VERT) - return GetVScrollRect(sw, hwnd, rect,hasZoomButtons); - else - { - if (hasZoomButtons) *hasZoomButtons=0; - return FALSE; - } -} - - - -// -// Work out the scrollbar width/height for either type of scrollbar (SB_HORZ/SB_VERT) -// rect - coords of the scrollbar. -// store results into *thumbsize and *thumbpos -// -static int CalcThumbSize(SCROLLBAR *sbar, const RECT *rect, int *pthumbsize, int *pthumbpos) -{ - SCROLLINFO *si; - int scrollsize; //total size of the scrollbar including arrow buttons - int workingsize; //working area (where the thumb can slide) - int siMaxMin; - int butsize; - int startcoord; - int thumbpos = 0, thumbsize = 0; - - int adjust=0; - static int count=0; - - //work out the width (for a horizontal) or the height (for a vertical) - //of a standard scrollbar button - butsize = GetScrollMetric(sbar->nBarType == SB_VERT, SM_SCROLL_LENGTH); - - if(1) //sbar->nBarType == SB_HORZ) - { - scrollsize = rect->right - rect->left; - startcoord = rect->left; - } - /*else if(sbar->nBarType == SB_VERT) - { - scrollsize = rect->bottom - rect->top; - startcoord = rect->top; - } - else - { - return 0; - }*/ - - si = &sbar->scrollInfo; - siMaxMin = si->nMax - si->nMin + 1; - workingsize = scrollsize - butsize * 2; - - // - // Work out the scrollbar thumb SIZE - // - if(si->nPage == 0) - { - thumbsize = butsize; - } - else if(siMaxMin > 0) - { - thumbsize = MulDiv(si->nPage, workingsize, siMaxMin); - - if(thumbsize < sbar->nMinThumbSize) - thumbsize = sbar->nMinThumbSize; - } - - // - // Work out the scrollbar thumb position - // - if(siMaxMin > 0) - { - int pagesize = max(1, si->nPage); - thumbpos = MulDiv(si->nPos - si->nMin, workingsize-thumbsize, siMaxMin - pagesize); - - if(thumbpos < 0) - thumbpos = 0; - - if(thumbpos >= workingsize-thumbsize) - thumbpos = workingsize-thumbsize; - } - - thumbpos += startcoord + butsize; - - *pthumbpos = thumbpos; - *pthumbsize = thumbsize; - - return 1; -} - -// -// return a hit-test value for whatever part of the scrollbar x,y is located in -// rect, x, y: SCREEN coordinates -// the rectangle must not include space for any inserted buttons -// (i.e, JUST the scrollbar area) -// -static UINT GetHorzScrollPortion(SCROLLBAR *sbar, HWND hwnd, const RECT *rect, int x, int y, BOOL hasZoomButtons) -{ - int thumbwidth, thumbpos; - int butwidth = GetScrollMetric(sbar->nBarType == SB_VERT, SM_SCROLL_LENGTH); - int scrollwidth = rect->right-rect->left; - int workingwidth = scrollwidth - butwidth*2; - SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); - - if(y < rect->top || y >= rect->bottom) - return HTSCROLL_NONE; - - CalcThumbSize(sbar, rect, &thumbwidth, &thumbpos); - - //if we have had to scale the buttons to fit in the rect, - //then adjust the button width accordingly - if(scrollwidth <= butwidth * 2) - { - butwidth = scrollwidth / 2; - } - - if(sw->resizingHthumb&&hasZoomButtons) - { - //check for resizer - if(x>=rect->right) - { - const int zbs = GetZoomButtonSize(sbar->nBarType==SB_VERT); - const int zrs = ZOOMBUTTON_RESIZER_SIZE(zbs); - if (x < rect->right+zbs) return HTSCROLL_ZOOMIN; - if (x < rect->right+zbs+zrs) return HTSCROLL_RESIZER; - if (x < rect->right+zbs*2+zrs) return HTSCROLL_ZOOMOUT; - } - } - - //check for left button click - if(x >= rect->left && x < rect->left + butwidth) - { - return HTSCROLL_LEFT; - } - //check for right button click - else if(x >= rect->right-butwidth && x < rect->right) - { - return HTSCROLL_RIGHT; - } - - //if the thumb is too big to fit (i.e. it isn't visible) - //then return a NULL scrollbar area - if(thumbwidth >= workingwidth) - return HTSCROLL_NONE; - - //check for point in the thumbbar - if(x >= thumbpos && x < thumbpos+thumbwidth) - { - if(sw->resizingHthumb) - { - if(sbar->nBarType == SB_HORZ) //only for horizontal - { - if(x<=thumbpos+m_thumbsize) - return HTSCROLL_LRESIZER; - if(x>=(thumbpos+thumbwidth-m_thumbsize)) - return HTSCROLL_RRESIZER; - } - } - return HTSCROLL_THUMB; - } - //check for left margin - else if(x >= rect->left+butwidth && x < thumbpos) - { - return HTSCROLL_PAGELEFT; - } - else if(x >= thumbpos+thumbwidth && x < rect->right-butwidth) - { - return HTSCROLL_PAGERIGHT; - } - - return HTSCROLL_NONE; -} - -// -// For vertical scrollbars, rotate all coordinates by -90 degrees -// so that we can use the horizontal version of this function -// -static UINT GetVertScrollPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) -{ - UINT r; - - RotateRect(rect); - r = GetHorzScrollPortion(sb, hwnd, rect, y, x,hasZoomButtons); - RotateRect(rect); - return r; -} - - - -static void drawSkinThumb(HDC hdc, RECT r, int fBarHot, int pressed, int vert, const RECT *wndrect, SCROLLBAR *sb) -{ - LICE_IBitmap *bmp; - if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) - { - int w = r.right-r.left; - int h = r.bottom-r.top; - int startx = 0; - int starty = 187; - if(m_scrollbar_hasPink) starty = 37; - if(!vert) - { - static LICE_SysBitmap tmpbmp; - if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) - tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); - - //draw background first so alpha channel thumbs work - { - RECT bgr = {0,0,w,h}; - DrawCheckedRect(&tmpbmp,tmpbmp.getDC(), &bgr, 0, 0, sb, wndrect, 0, r.left); - } - - int st = (fBarHot?1:0) + (pressed?2:0); - int neww = w; - int part1 = 16, part2 = 10, part3 = 14, part4 = 10, part5 = 16; - if(m_scrollbar_hasPink) - { - part1 = m_sb_thumbHV[0]; part2 = m_sb_thumbHV[1]; part3 = m_sb_thumbHV[2]; part4 = m_sb_thumbHV[3]; part5 = m_sb_thumbHV[4]; - } - - double sc = h==16||h==17 ? 1.0 : h / 17.0; - - int part1_s = (int)(part1*sc+0.5); - int part3_s = (int)(part3*sc+0.5); - int part5_s = (int)(part5*sc+0.5); - int tl = part1_s+part3_s+part5_s; - if(wliceThumb || sb->liceThumb->getWidth()!=w || sb->liceThumb->getHeight()!=h || sb->liceThumbState!=st || sb->liceThumb_ver!=g_coolsb_imageVersion) - { - sb->liceThumb_ver=g_coolsb_imageVersion; - if(!sb->liceThumb) sb->liceThumb = new LICE_SysBitmap; - sb->liceThumb->resize(w, h); - sb->liceThumbState = st; - - if(fBarHot) starty += 17; - else if(pressed) starty += 17*2; - - int mid = (w-part3_s)/2; - LICE_ScaledBlit(sb->liceThumb, bmp, 0, 0, part1_s, h, startx, starty, part1, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, part1_s, 0, mid-part1_s, h, startx+part1, starty, part2, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, mid, 0, part3_s, h, startx+part1+part2, starty, part3, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, mid+part3_s, 0, w-(mid+part3_s)-part5, h, startx+part1+part2+part3, starty, part4, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, w-part5_s, 0, part5_s, h, startx+part1+part2+part3+part4, starty, part5, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - - } - - LICE_ScaledBlit(&tmpbmp, sb->liceThumb, 0, 0, neww, h, 0, 0, w, h, 1.0f, LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - BitBlt(hdc, r.left, r.top, neww, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - } - else - { - static LICE_SysBitmap tmpbmp; - if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) - tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); - starty = 116; - if(m_scrollbar_hasPink) starty = 91; - - //draw background first so alpha channel thumbs work - { - RECT bgr = {0,0,w,h}; - DrawCheckedRect(&tmpbmp,tmpbmp.getDC(), &bgr, 0, 0, sb, wndrect, 0, 0, r.top); - } - - int st = (fBarHot?1:0) + (pressed?2:0); - - int newh = h; - int part1 = 8, part2 = 16, part3 = 18, part4 = 16, part5 = 8; - if(m_scrollbar_hasPink) - { - part1 = m_sb_thumbVV[0]; part2 = m_sb_thumbVV[1]; part3 = m_sb_thumbVV[2]; part4 = m_sb_thumbVV[3]; part5 = m_sb_thumbVV[4]; - } - - double sc = w==16||w==17 ? 1.0 : w / 17.0; - - int part1_s = (int)(part1*sc+0.5); - int part3_s = (int)(part3*sc+0.5); - int part5_s = (int)(part5*sc+0.5); - int tl = part1_s+part3_s+part5_s; - if(hliceThumb || sb->liceThumb->getWidth()!=w || sb->liceThumb->getHeight()!=h || sb->liceThumbState!=st || sb->liceThumb_ver!=g_coolsb_imageVersion) - { - sb->liceThumb_ver = g_coolsb_imageVersion; - if(!sb->liceThumb) sb->liceThumb = new LICE_SysBitmap; - sb->liceThumb->resize(w, h); - - sb->liceThumbState = st; - - if(fBarHot) startx += 17; - else if(pressed) startx += 17*2; - - int mid = (h-part3)/2; - LICE_ScaledBlit(sb->liceThumb, bmp, 0, 0, w, part1_s, startx, starty, 17, part1, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, 0, part1_s, w, mid-part1_s, startx, starty+part1, 17, part2, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, 0, mid, w, part3_s, startx, starty+part1+part2, 17, part3, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, 0, mid+part3_s, w, h-(mid+part3_s)-part5_s, startx, starty+part1+part2+part3, 17, part4, 1.0f, LICE_BLIT_FILTER_BILINEAR); - LICE_ScaledBlit(sb->liceThumb, bmp, 0, h-part5_s, w, part5_s, startx, starty+part1+part2+part3+part4, 17, part5, 1.0f, LICE_BLIT_FILTER_BILINEAR); - } - - LICE_ScaledBlit(&tmpbmp, sb->liceThumb, 0, 0, w, newh, 0, 0, w, h, 1.0f, LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - BitBlt(hdc, r.left, r.top, w, newh, tmpbmp.getDC(), 0, 0, SRCCOPY); - } - } -} - - -// -// Draw a complete HORIZONTAL scrollbar in the given rectangle -// Don't draw any inserted buttons in this procedure -// -// uDrawFlags - hittest code, to say if to draw the -// specified portion in an active state or not. -// -// -static LRESULT NCDrawHScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) -{ - SCROLLINFO *si; - RECT ctrl, thumb; - RECT sbm; - int butwidth = GetScrollMetric(sb->nBarType == SB_VERT, SM_SCROLL_LENGTH); - int scrollwidth = rect->right-rect->left; - int workingwidth = scrollwidth - butwidth*2; - int thumbwidth = 0, thumbpos = 0; - int siMaxMin; - - BOOL fMouseDownL = 0, fMouseOverL = 0, fBarHot = 0; - BOOL fMouseDownR = 0, fMouseOverR = 0; - - COLORREF crCheck1 = GetSBForeColor(hwnd); - COLORREF crCheck2 = GetSBBackColor(hwnd); - COLORREF crInverse1 = InvertCOLORREF(crCheck1); - COLORREF crInverse2 = InvertCOLORREF(crCheck2); - - //drawing flags to modify the appearance of the scrollbar buttons - UINT uLeftButFlags = DFCS_SCROLLLEFT; - UINT uRightButFlags = DFCS_SCROLLRIGHT; - - SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); - - if(scrollwidth <= 0) - return 0; - - si = &sb->scrollInfo; - siMaxMin = si->nMax - si->nMin; - - int sbYoffs=0,sbXoffs=0; -#ifdef _WIN32 - // this is a stupid fix for now . this needs a ton of overhauling - { - RECT r; - POINT p={0,0}; - ClientToScreen(hwnd,&p); - GetWindowRect(hwnd,&r); - - if (sb == &sw->sbarVert) sbYoffs = r.top - p.y; - if (sb == &sw->sbarHorz) sbXoffs = r.left - p.x; - } -#endif - - - if(hwnd != hwndCurCoolSB) - uDrawFlags = HTSCROLL_NONE; - // - // work out the thumb size and position - // - CalcThumbSize(sb, rect, &thumbwidth, &thumbpos); - - if(sb->fScrollFlags & ESB_DISABLE_LEFT) uLeftButFlags |= DFCS_INACTIVE; - if(sb->fScrollFlags & ESB_DISABLE_RIGHT) uRightButFlags |= DFCS_INACTIVE; - - //if we need to grey the arrows because there is no data to scroll - if(!IsScrollInfoActive(si) && !(sb->fScrollFlags & CSBS_THUMBALWAYS)) - { - uLeftButFlags |= DFCS_INACTIVE; - uRightButFlags |= DFCS_INACTIVE; - } - - if(hwnd == hwndCurCoolSB) - { - fMouseDownL = (uDrawFlags == HTSCROLL_LEFT); - fMouseDownR = (uDrawFlags == HTSCROLL_RIGHT); - } - - - int fMouseOverPlus, fMouseOverMinus; - { - BOOL ldis = !(uLeftButFlags & DFCS_INACTIVE); - BOOL rdis = !(uRightButFlags & DFCS_INACTIVE); - - fBarHot = sb->nBarType == (int)sw->uMouseOverScrollbar; - - fMouseOverL = sw->uHitTestPortion == HTSCROLL_LEFT && fBarHot && ldis; - fMouseOverR = sw->uHitTestPortion == HTSCROLL_RIGHT && fBarHot && rdis; - fMouseOverPlus = sw->uHitTestPortion == HTSCROLL_ZOOMIN && fBarHot && ldis; - fMouseOverMinus = sw->uHitTestPortion == HTSCROLL_ZOOMOUT && fBarHot && ldis; - } - - // - // Draw the scrollbar now - // - if(scrollwidth > butwidth*2) - { - //LEFT ARROW - SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom); - - RotateRect0(sb, &ctrl); - - DrawScrollArrow(hwnd,sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL); - - RotateRect0(sb, &ctrl); - - //MIDDLE PORTION - //if we can fit the thumbbar in, then draw it - if(thumbwidth > 0 && thumbwidth <= workingwidth - && IsScrollInfoActive(si) && ((sb->fScrollFlags & ESB_DISABLE_BOTH) != ESB_DISABLE_BOTH)) - { - //Draw the scrollbar margin above the thumb - SetRect(&sbm, rect->left + butwidth, rect->top, thumbpos, rect->bottom); - - RotateRect0(sb, &sbm); - - if(uDrawFlags == HTSCROLL_PAGELEFT) - DrawCheckedRect(NULL,hdc, &sbm, crInverse1, crInverse2, sb, rect, 1,sbXoffs,sbYoffs); - else - DrawCheckedRect(NULL,hdc, &sbm, crCheck1, crCheck2, sb, rect, 0,sbXoffs,sbYoffs); - - RotateRect0(sb, &sbm); - - //Draw the margin below the thumb - sbm.left = thumbpos+thumbwidth; - sbm.right = rect->right - butwidth; - - RotateRect0(sb, &sbm); - if(uDrawFlags == HTSCROLL_PAGERIGHT) - DrawCheckedRect(NULL,hdc, &sbm, crInverse1, crInverse2, sb, rect, 1,sbXoffs,sbYoffs); - else - DrawCheckedRect(NULL,hdc, &sbm, crCheck1, crCheck2, sb, rect, 0,sbXoffs,sbYoffs); - RotateRect0(sb, &sbm); - - //Draw the THUMB finally - SetRect(&thumb, thumbpos, rect->top, thumbpos+thumbwidth, rect->bottom); - - RotateRect0(sb, &thumb); - - if(m_scrollbar_bmp && *m_scrollbar_bmp) - { - drawSkinThumb(hdc, thumb, sw->uHitTestPortion == HTSCROLL_THUMB, 0, sb->nBarType == SB_VERT, rect, sb); - } - else - { - //no skinning - - { - RECT r = thumb; - if(sw->resizingHthumb) - { - if(sb->nBarType == SB_HORZ) - { - r.left += m_thumbsize; - r.right -= m_thumbsize; - } - else - { - //disabled for now - /*r.top += m_thumbsize; - r.bottom -= m_thumbsize;*/ - } - } - DrawBlankButton(hwnd,hdc, &r); - } - - if(sw->resizingHthumb) - { - //draw left and right resizers - if(sb->nBarType == SB_HORZ) - { - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - { - RECT r={thumb.left, thumb.top, thumb.left+m_thumbsize, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - { - RECT r={thumb.right-m_thumbsize, thumb.top, thumb.right, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - DeleteObject(br); - } - else - { - //disabled for now - /*HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - { - RECT r={thumb.left, thumb.top, thumb.right, thumb.top+m_thumbsize}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - { - RECT r={thumb.left, thumb.bottom - m_thumbsizeE, thumb.right, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - DeleteObject(br);*/ - } - } - } - RotateRect0(sb, &thumb); - - } - //otherwise, just leave that whole area blank - else - { - OffsetRect(&ctrl, butwidth, 0); - ctrl.right = rect->right - butwidth; - - //if we always show the thumb covering the whole scrollbar, - //then draw it that way - if(!IsScrollInfoActive(si) && (sb->fScrollFlags & CSBS_THUMBALWAYS) - && ctrl.right - ctrl.left > sb->nMinThumbSize) - { - //leave a 1-pixel gap between the thumb + right button - ctrl.right --; - RotateRect0(sb, &ctrl); - - DrawBlankButton(hwnd,hdc, &ctrl); - - RotateRect0(sb, &ctrl); - - //draw the single-line gap - ctrl.left = ctrl.right; - ctrl.right += 1; - - RECT r2 = ctrl; - r2.right -= 1; - RotateRect0(sb, &ctrl); - RotateRect0(sb, &r2); - - PaintRect(hdc, &r2, CoolSB_GetSysColor(hwnd,COLOR_SCROLLBAR)); - - RotateRect0(sb, &ctrl); - } - //otherwise, paint a blank if the thumb doesn't fit in - else - { - RotateRect0(sb, &ctrl); - - DrawCheckedRect(NULL,hdc, &ctrl, crCheck1, crCheck2, sb, rect, 0, sbXoffs,sbYoffs); - - RotateRect0(sb, &ctrl); - } - } - - //RIGHT ARROW - SetRect(&ctrl, rect->right - butwidth, rect->top, rect->right, rect->bottom); - - RECT r2 = ctrl; - // r2.right -= 1; - RotateRect0(sb, &ctrl); - RotateRect0(sb, &r2); - - DrawScrollArrow(hwnd,sb, hdc, &r2, uRightButFlags, fMouseDownR, fMouseOverR); - - if(sw->resizingHthumb && hasZoomButtons) - { - //zoom/resize buttons - { - SetBkMode(hdc, TRANSPARENT); - if(sb->nBarType == SB_HORZ) - { - int zbs = GetZoomButtonSize(FALSE); - if(m_scrollbar_bmp && *m_scrollbar_bmp) - { - LICE_IBitmap *bmp = *m_scrollbar_bmp; - static LICE_SysBitmap tmpbmp; - - int w = zbs; - int h = ctrl.bottom-ctrl.top; - int startx = 116; - int starty = 201; - if(fMouseOverPlus) startx += 17; - if(uDrawFlags == HTSCROLL_ZOOMIN) startx = 116+17+17; - if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) - tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - - BitBlt(hdc, ctrl.right, ctrl.top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, ZOOMBUTTON_RESIZER_SIZE(zbs), h, 163, 101, 4, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - BitBlt(hdc, ctrl.right+zbs, ctrl.top, ZOOMBUTTON_RESIZER_SIZE(zbs), h, tmpbmp.getDC(), 0, 0, SRCCOPY); - - startx = 116; - starty = 221; - if(fMouseOverMinus) startx += 17; - if(uDrawFlags == HTSCROLL_ZOOMOUT) startx = 116+17+17; - - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - BitBlt(hdc, ctrl.right+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - } - else - { - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - HPEN pen=CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); - HGDIOBJ oldPen=SelectObject(hdc,pen); - // + - { - int pressed = (uDrawFlags == HTSCROLL_ZOOMIN); - RECT r = {ctrl.right+pressed, ctrl.top+pressed, ctrl.right + zbs, ctrl.bottom}; - ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - - - int cy=(ctrl.top+ctrl.bottom)/2+pressed, - cx=ctrl.right+zbs/2+pressed; - int sz=min(14,ctrl.bottom-ctrl.top)/4; - - MoveToEx(hdc,cx-sz,cy,NULL); - LineTo(hdc,cx+sz+1,cy); - MoveToEx(hdc,cx,cy-sz,NULL); - LineTo(hdc,cx,cy+sz+1); - } - // resize thumb - { - RECT r = {ctrl.right + zbs, ctrl.top, ctrl.right + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - // - - { - int pressed = (uDrawFlags == HTSCROLL_ZOOMOUT); - RECT r = {ctrl.right + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs) +pressed, ctrl.top+pressed, - ctrl.right + zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.bottom}; - ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - int cy=(ctrl.top+ctrl.bottom)/2+pressed, - cx=ctrl.right+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs)+zbs/2+pressed; - int sz=min(14,ctrl.bottom-ctrl.top)/4; - - MoveToEx(hdc,cx-sz,cy,NULL); - LineTo(hdc,cx+sz+1,cy); - } - SelectObject(hdc,oldPen); - DeleteObject(pen); - DeleteObject(br); - } - } - else - { - int zbs = GetZoomButtonSize(TRUE); - if(m_scrollbar_bmp && *m_scrollbar_bmp) - { - LICE_IBitmap *bmp = *m_scrollbar_bmp; - static LICE_SysBitmap tmpbmp; - int w = ctrl.right - ctrl.left; - int h = zbs; - int startx = 116; - int starty = 201; - if(fMouseOverPlus) startx += 17; - if(uDrawFlags == HTSCROLL_ZOOMIN) startx = 116+17+17; - if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) - tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - BitBlt(hdc, ctrl.left, ctrl.bottom, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, ZOOMBUTTON_RESIZER_SIZE(zbs), 143, 114, 17, 4, 1.0f, LICE_BLIT_FILTER_BILINEAR); - BitBlt(hdc, ctrl.left, ctrl.bottom+zbs, w, ZOOMBUTTON_RESIZER_SIZE(zbs), tmpbmp.getDC(), 0, 0, SRCCOPY); - - startx = 116; - starty = 221; - if(fMouseOverMinus) startx += 17; - if(uDrawFlags == HTSCROLL_ZOOMOUT) startx = 116+17+17; - - LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); - BitBlt(hdc, ctrl.left, ctrl.bottom+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs), w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); - } - else - { - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - HPEN pen=CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); - HGDIOBJ oldPen=SelectObject(hdc,pen); - // + - { - int pressed = (uDrawFlags == HTSCROLL_ZOOMIN); - RECT r = {ctrl.left+pressed, ctrl.bottom+pressed, ctrl.right, ctrl.bottom + zbs}; - ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - - int cx=(ctrl.left+ctrl.right)/2+pressed,cy=ctrl.bottom+zbs/2+pressed; - int sz=min(14,ctrl.right-ctrl.left)/4; - - MoveToEx(hdc,cx-sz,cy,NULL); - LineTo(hdc,cx+sz+1,cy); - MoveToEx(hdc,cx,cy-sz,NULL); - LineTo(hdc,cx,cy+sz+1); - } - // resize thumb - { - RECT r = {ctrl.left, ctrl.bottom + zbs, ctrl.right, ctrl.bottom + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs)}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - // - - { - int pressed = (uDrawFlags == HTSCROLL_ZOOMOUT); - RECT r = {ctrl.left+pressed, ctrl.bottom + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs) + pressed, - ctrl.right, ctrl.bottom + ZOOMBUTTON_RESIZER_SIZE(zbs) + zbs*2}; - ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - - int cx=(ctrl.left+ctrl.right)/2+pressed,cy=ctrl.bottom+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs)+zbs/2+pressed; - int sz=min(14,ctrl.right-ctrl.left)/4; - - MoveToEx(hdc,cx-sz,cy,NULL); - LineTo(hdc,cx+sz+1,cy); - } - SelectObject(hdc,oldPen); - DeleteObject(pen); - DeleteObject(br); - } - } - } - } - RotateRect0(sb, &ctrl); - } - //not enough room for the scrollbar, so just draw the buttons (scaled in size to fit) - else - { - butwidth = scrollwidth / 2; - - //LEFT ARROW - SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom); - - RotateRect0(sb, &ctrl); - DrawScrollArrow(hwnd,sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL); - RotateRect0(sb, &ctrl); - - //RIGHT ARROW - OffsetRect(&ctrl, scrollwidth - butwidth, 0); - - RotateRect0(sb, &ctrl); - DrawScrollArrow(hwnd,sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR); - RotateRect0(sb, &ctrl); - - //if there is a gap between the buttons, fill it with a solid color - //if(butwidth & 0x0001) - if(ctrl.left != rect->left + butwidth) - { - ctrl.left --; - ctrl.right -= butwidth; - RotateRect0(sb, &ctrl); - - DrawCheckedRect(NULL,hdc, &ctrl, crCheck1, crCheck2, sb, rect, 0, sbXoffs, sbYoffs); - - RotateRect0(sb, &ctrl); - } - - } - - return FALSE; -} - -// -// Draw a vertical scrollbar using the horizontal draw routine, but -// with the coordinates adjusted accordingly -// -static LRESULT NCDrawVScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) -{ - LRESULT ret; - RECT rc; - - rc = *rect; - RotateRect(&rc); - ret = NCDrawHScrollbar(sb, hwnd, hdc, &rc, uDrawFlags,hasZoomButtons); - RotateRect(&rc); - - return ret; -} - -// -// Generic wrapper function for the scrollbar drawing -// -static LRESULT NCDrawScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) -{ - if(sb->nBarType == SB_HORZ) - return NCDrawHScrollbar(sb, hwnd, hdc, rect, uDrawFlags,hasZoomButtons); - else - return NCDrawVScrollbar(sb, hwnd, hdc, rect, uDrawFlags,hasZoomButtons); -} - - - -static int getPink(int x, int y, int vert, int np=0, int add=1) -{ - LICE_IBitmap *bmp; - if(!m_scrollbar_bmp || !(bmp = *m_scrollbar_bmp)) return 0; - - int w = bmp->getWidth(); - int h = bmp->getHeight(); - int rs=bmp->getRowSpan(); - LICE_pixel *p = bmp->getBits(); - if(x>=w || y>=h) return 0; - p += rs * y + x; - if(!vert) - { - int l; - for(l=0;;l++) - { - if(np && *p==LICE_RGBA(255,0,255,255)) break; - if(!np && *p!=LICE_RGBA(255,0,255,255)) break; - p += add; - x += add; - if(x>=w || x<0) break; - } - return l; - } - - int l; - for(l=0;;l++) - { - if(np && *p==LICE_RGBA(255,0,255,255)) break; - if(!np && *p!=LICE_RGBA(255,0,255,255)) break; - p += rs*add; - y += add; - if(y>=h || y<0) break; - } - return l; -} - -static void initLiceBmp() -{ - m_scrollbar_bmp = (LICE_IBitmap **)GetIconThemePointer("scrollbar"); - if(!m_scrollbar_bmp) return; - - m_scrollbar_hasPink = getPink(0,35,0)>0; - if(m_scrollbar_hasPink) - { - LICE_IBitmap *bmp = *m_scrollbar_bmp; - memset(&m_sb_thumbHV, 0, sizeof(m_sb_thumbHV)); - memset(&m_sb_thumbVV, 0, sizeof(m_sb_thumbVV)); - int w = bmp->getWidth(); - int h = bmp->getHeight(); - { - int l = getPink(0,89,0); - m_sb_thumbHV[0] = l; - int x = l; - l = getPink(x, 89, 0, 1); - m_sb_thumbHV[1] = l; - x += l; - l = getPink(x, 89, 0); - m_sb_thumbHV[2] = l; - x += l; - l = getPink(x, 89, 0, 1); - m_sb_thumbHV[3] = l; - x += l; - l = getPink(x, 89, 0); - m_sb_thumbHV[4] = l; - - int y = 91; - l = getPink(52, y, 1); - m_sb_thumbVV[0] = l; - y += l; - l = getPink(52, y, 1, 1); - m_sb_thumbVV[1] = l; - y += l; - l = getPink(52, y, 1); - m_sb_thumbVV[2] = l; - y += l; - l = getPink(52, y, 1, 1); - m_sb_thumbVV[3] = l; - y += l; - l = getPink(52, y, 1); - m_sb_thumbVV[4] = l; - - m_sb_bkghl = getPink(0, 35, 0); - m_sb_bkghr = getPink(203, 35, 0, 0, -1); - - m_sb_bkgvt = getPink(168, 37, 1); - m_sb_bkgvb = getPink(168, 237, 1, 0, -1); - } - } -} - -static LRESULT NCPaint(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam, HDC hdcParam=NULL) -{ - SCROLLBAR *sb; - HDC hdc; - HRGN hrgn; - RECT winrect, rect; - HRGN clip; - BOOL fUpdateAll = (wParam == 1); - UINT ret; - - if(!m_scrollbar_bmp) - { - initLiceBmp(); - } - - GET_WINDOW_RECT(hwnd, &winrect); - - //if entire region needs painting, then make a region to cover the entire window -/* if(fUpdateAll) - hrgn = (HRGN)wParam; - else - */ - hrgn = (HRGN)wParam; - - //hdc = GetWindowDC(hwnd); - if(hdcParam != NULL) - hdc = hdcParam; - else - hdc = GetWindowDC(hwnd); - -// printf("wndrect: %d,%d,%d,%d hdc=%d hv=%d\n",winrect.left,winrect.top,winrect.right,winrect.bottom,hdc,sw->sbarHorz.fScrollVisible); - - // - // Only draw the horizontal scrollbar if the window is tall enough - // - sb = &sw->sbarHorz; - if(sb->fScrollVisible) - { - int hbarwidth = 0, leftright = 0; - - //get the screen coordinates of the whole horizontal scrollbar area - BOOL hasZoomButtons; - GetHScrollRect(sw, hwnd, &rect, &hasZoomButtons); - - //make the coordinates relative to the window for drawing - OffsetRect(&rect, -winrect.left, -winrect.top); - - - if(sw->uCurrentScrollbar == SB_HORZ) - NCDrawHScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); - else - NCDrawHScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); - } - - // - // Only draw the vertical scrollbar if the window is wide enough to accomodate it - // - sb = &sw->sbarVert; - if(sb->fScrollVisible) - { - int vbarheight = 0, updown = 0; - - //get the screen cooridinates of the whole horizontal scrollbar area - BOOL hasZoomButtons; - GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); - - //make the coordinates relative to the window for drawing - OffsetRect(&rect, -winrect.left, -winrect.top); - - - if(sw->uCurrentScrollbar == SB_VERT) - { - NCDrawVScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); - } - else - NCDrawVScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); - } - - //Call the default window procedure for WM_NCPAINT, with the - //new window region. ** region must be in SCREEN coordinates ** - - // If the window has WS_(H-V)SCROLL bits set, we should reset them - // to avoid windows taking the scrollbars into account. - // We temporarily set a flag preventing the subsecuent - // WM_STYLECHANGING/WM_STYLECHANGED to be forwarded to - // the original window procedure - - ret = CallWindowProcStyleMod(sw, hwnd, WM_NCPAINT, (WPARAM)hrgn, lParam); - - - - - // DRAW THE DEAD AREA - // only do this if the horizontal and vertical bars are visible - if(sw->sbarHorz.fScrollVisible && sw->sbarVert.fScrollVisible) - { - GET_WINDOW_RECT(hwnd, &rect); - OffsetRect(&rect, -winrect.left, -winrect.top); - - rect.bottom -= sw->cyBottomEdge; - rect.top = rect.bottom - GetScrollMetric(FALSE, SM_CYHORZSB); - - if(sw->fLeftScrollbar) - { - rect.left += sw->cxLeftEdge; - rect.right = rect.left + GetScrollMetric(TRUE, SM_CXVERTSB); - } - else - { - rect.right -= sw->cxRightEdge; - rect.left = rect.right - GetScrollMetric(TRUE, SM_CXVERTSB); - } - - { - //calculate the position of THIS window's dead area - //with the position of the PARENT window's client rectangle. - //if THIS window has been positioned such that its bottom-right - //corner sits in the parent's bottom-right corner, then we should - //show the sizing-grip. - //Otherwise, assume this window is not in the right place, and - //just draw a blank rectangle - RECT parent; - RECT rect2; - HWND hwndParent = GetParent(hwnd); - - GetClientRect(hwndParent, &parent); - //MapWindowPoints(hwndParent, 0, (POINT *)&parent, 2); - ClientToScreen(hwndParent, (LPPOINT)&parent); - ClientToScreen(hwndParent, ((LPPOINT)&parent)+1); - if (parent.bottomfLeftScrollbar && parent.right == rect2.right+sw->cxRightEdge && parent.bottom == rect2.bottom+sw->cyBottomEdge - || sw->fLeftScrollbar && parent.left == rect2.left -sw->cxLeftEdge && parent.bottom == rect2.bottom+sw->cyBottomEdge) - ownDrawFrameControl(hwnd,hdc, &rect, DFC_SCROLL, sw->fLeftScrollbar ? DFCS_SCROLLSIZEGRIPRIGHT : DFCS_SCROLLSIZEGRIP, 0 ); - else -#endif - PaintRect(hdc, &rect, CoolSB_GetSysColor(hwnd,COLOR_3DFACE)); - } - } - - UNREFERENCED_PARAMETER(clip); - - if(!hdcParam) ReleaseDC(hwnd, hdc); - return ret; -} - -// -// Need to detect if we have clicked in the scrollbar region or not -// -static LRESULT NCHitTest(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - RECT hrect; - RECT vrect; - POINT pt; - - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - OSX_REMAP_SCREENY(hwnd,&pt.y); - - //work out exactly where the Horizontal and Vertical scrollbars are - BOOL hasZoomButtons; - GetHScrollRect(sw, hwnd, &hrect, &hasZoomButtons); - if (hasZoomButtons && sw->resizingHthumb) - { - int zbs = GetZoomButtonSize(FALSE); - hrect.right += zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); - } - GetVScrollRect(sw, hwnd, &vrect,&hasZoomButtons); - if (hasZoomButtons && sw->resizingHthumb) - { - int zbs = GetZoomButtonSize(TRUE); - vrect.bottom += zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); - } - -#ifndef _WIN32 - if (sw->sbarHorz.fScrollVisible || sw->sbarVert.fScrollVisible) - { - int sz=sw->sbarHorz.fScrollVisible ? hrect.bottom-hrect.top : vrect.right-vrect.left; - if (sz<0)sz=-sz; - RECT r; - GetWindowRect(hwnd,&r); - int bot = max(r.top,r.bottom); - int v= (bot-pt.y) + (r.right-pt.x); - if (v < sz*3/4) return HTNOWHERE; - } -#endif - - - //Clicked in the horizontal scrollbar area - if(sw->sbarHorz.fScrollVisible && PtInRect(&hrect, pt)) - { - return HTHSCROLL; - } - //Clicked in the vertical scrollbar area - else if(sw->sbarVert.fScrollVisible && PtInRect(&vrect, pt)) - { - - return HTVSCROLL; - } -#ifndef _WIN32 - else if (sw->sbarHorz.fScrollVisible && sw->sbarVert.fScrollVisible && pt.y >= hrect.top && pt.y <= hrect.bottom && pt.x >= vrect.left && pt.x <= vrect.right) - { - return HTNOWHERE; - } -#endif - //clicked somewhere else - else - { - return CallWindowProc(sw->oldproc, hwnd, WM_NCHITTEST, wParam, lParam); - } -} - -// -// Return a HT* value indicating what part of the scrollbar was clicked -// Rectangle is not adjusted -// -static UINT GetHorzPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) -{ - RECT rc = *rect; - - if(y < rc.top || y >= rc.bottom) return HTSCROLL_NONE; - - - //Now we have the rectangle for the scrollbar itself, so work out - //what part we clicked on. - return GetHorzScrollPortion(sb, hwnd, &rc, x, y,hasZoomButtons); -} - -// -// Just call the horizontal version, with adjusted coordinates -// -static UINT GetVertPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) -{ - UINT ret; - RotateRect(rect); - ret = GetHorzPortion(sb, hwnd, rect, y, x,hasZoomButtons); - RotateRect(rect); - return ret; -} - -// -// Wrapper function for GetHorzPortion and GetVertPortion -// -static UINT GetPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) -{ - if(sb->nBarType == SB_HORZ) - return GetHorzPortion(sb, hwnd, rect, x, y,hasZoomButtons); - else if(sb->nBarType == SB_VERT) - return GetVertPortion(sb, hwnd, rect, x, y,hasZoomButtons); - else - return HTSCROLL_NONE; -} - - -// -// Left button click in the non-client area -// -static LRESULT NCLButtonDown(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL isDouble) -{ - RECT rect, winrect; - HDC hdc; - SCROLLBAR *sb; - POINT pt; - - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - OSX_REMAP_SCREENY(hwnd,&pt.y); - - hwndCurCoolSB = hwnd; - - // - // HORIZONTAL SCROLLBAR PROCESSING - // - BOOL hasZoomButtons; - if(wParam == HTHSCROLL) - { - sw->uScrollTimerMsg = WM_HSCROLL; - sw->uCurrentScrollbar = SB_HORZ; - sb = &sw->sbarHorz; - - //get the total area of the normal Horz scrollbar area - GetHScrollRect(sw, hwnd, &rect,&hasZoomButtons); - sw->uCurrentScrollPortion = GetHorzPortion(sb, hwnd, &rect, pt.x,pt.y,hasZoomButtons); - } - // - // VERTICAL SCROLLBAR PROCESSING - // - else if(wParam == HTVSCROLL) - { - sw->uScrollTimerMsg = WM_VSCROLL; - sw->uCurrentScrollbar = SB_VERT; - sb = &sw->sbarVert; - - //get the total area of the normal Horz scrollbar area - GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); - sw->uCurrentScrollPortion = GetVertPortion(sb, hwnd, &rect, pt.x,pt.y,hasZoomButtons); - } - // - // NORMAL PROCESSING - // - else - { - sw->uCurrentScrollPortion = HTSCROLL_NONE; - return CallWindowProc(sw->oldproc, hwnd, WM_NCLBUTTONDOWN, wParam, lParam); - } - - // - // we can now share the same code for vertical - // and horizontal scrollbars - // - switch(sw->uCurrentScrollPortion) - { - //inserted buttons to the left/right - - case HTSCROLL_THUMB: - - //if the scrollbar is disabled, then do no further processing - if(!IsScrollbarActive(sb)) - return 0; - - if (isDouble) - { - SendMessage(hwnd,WM_SB_DBLCLK,wParam == HTVSCROLL ? SB_VERT : SB_HORZ,0); - } - else - { - - RotateRect0(sb, &rect); - CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); - RotateRect0(sb, &rect); - - //remember the bounding rectangle of the scrollbar work area - rcThumbBounds = rect; - - sw->fThumbTracking = TRUE; - sb->scrollInfo.nTrackPos = sb->scrollInfo.nPos; - - if(wParam == HTVSCROLL) - nThumbMouseOffset = pt.y - nThumbPos; - else - nThumbMouseOffset = pt.x - nThumbPos; - - nLastPos = sb->scrollInfo.nPos; - nThumbPos0 = nThumbPos; - -#if 0 - //if(sb->fFlatScrollbar) - //{ - GetWindowRect(hwnd, &winrect); - FIXWINDOWRECT(&winrect); - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_THUMB); - ReleaseDC(hwnd, hdc); - //} -#endif - - MouseMove(sw, hwnd, 0, 0); - } - - break; - - //Any part of the scrollbar - case HTSCROLL_LEFT: - if(sb->fScrollFlags & ESB_DISABLE_LEFT) return 0; - else goto target1; - - case HTSCROLL_RIGHT: - if(sb->fScrollFlags & ESB_DISABLE_RIGHT) return 0; - else goto target1; - - goto target1; - - case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: - - target1: - - //if the scrollbar is disabled, then do no further processing - if(!IsScrollbarActive(sb)) - break; - - //ajust the horizontal rectangle to NOT include - //any inserted buttons - - SendScrollMessage(hwnd, sw->uScrollTimerMsg, sw->uCurrentScrollPortion, 0); - - // Check what area the mouse is now over : - // If the scroll thumb has moved under the mouse in response to - // a call to SetScrollPos etc, then we don't hilight the scrollbar margin - if(sw->uCurrentScrollbar == SB_HORZ) - sw->uScrollTimerPortion = GetHorzScrollPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); - else - sw->uScrollTimerPortion = GetVertScrollPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); - - GET_WINDOW_RECT(hwnd, &winrect); - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - - NCDrawScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); - ReleaseDC(hwnd, hdc); - - //Post the scroll message!!!! - sw->uScrollTimerPortion = sw->uCurrentScrollPortion; - - //set a timer going on the first click. - //if this one expires, then we can start off a more regular timer - //to generate the auto-scroll behaviour - sw->uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID1, COOLSB_TIMERINTERVAL1, 0); - break; - case HTSCROLL_LRESIZER: - case HTSCROLL_RRESIZER: - if(wParam == HTVSCROLL) - nThumbMouseOffset = pt.y - nThumbPos; - else - nThumbMouseOffset = pt.x; - if(wParam == HTHSCROLL) - { - RECT rect; - int nThumbSize, nThumbPos; - GetHScrollRect(sw, hwnd, &rect,NULL); - CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); - SendMessage(hwnd, WM_SB_TRESIZE_START, nThumbSize, nThumbPos); - } - else - { - RECT rect; - int nThumbSize, nThumbPos; - GetVScrollRect(sw, hwnd, &rect,NULL); - RotateRect0(sb, &rect); - CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); - SendMessage(hwnd, WM_SB_TRESIZE_START, nThumbSize, nThumbPos); - } - break; - case HTSCROLL_RESIZER: - if(wParam == HTVSCROLL) - nThumbMouseOffset = pt.y; - else - nThumbMouseOffset = pt.x; - break; - case HTSCROLL_ZOOMIN: - SendMessage(hwnd, WM_SB_ZOOM, 0, (wParam == HTVSCROLL)); - if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); - sw->uZoomTimerId=SetTimer(hwnd,COOLSB_TIMERID4,COOLSB_TIMERINTERVAL4,NULL); - sw->uZoomTimerMode=wParam == HTVSCROLL; - sw->uScrollTimerPortion = HTSCROLL_ZOOMIN; - { - GET_WINDOW_RECT(hwnd, &winrect); - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_ZOOMIN,hasZoomButtons); - ReleaseDC(hwnd, hdc); - } - break; - case HTSCROLL_ZOOMOUT: - SendMessage(hwnd, WM_SB_ZOOM, 1, (wParam == HTVSCROLL)); - if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); - sw->uZoomTimerId=SetTimer(hwnd,COOLSB_TIMERID4,COOLSB_TIMERINTERVAL4,NULL); - sw->uZoomTimerMode=2 + (wParam == HTVSCROLL); - sw->uScrollTimerPortion = HTSCROLL_ZOOMOUT; - { - GET_WINDOW_RECT(hwnd, &winrect); - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_ZOOMOUT,hasZoomButtons); - ReleaseDC(hwnd, hdc); - } - break; - default: - return CallWindowProc(sw->oldproc, hwnd, WM_NCLBUTTONDOWN, wParam, lParam); - //return 0; - } - - SetCapture(hwnd); - return 0; -} - -// -// Left button released -// -static LRESULT LButtonUp(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - RECT rect; - //UINT thisportion; - HDC hdc; - POINT pt; - RECT winrect; - UINT buttonIdx = 0; - - if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); - sw->uZoomTimerId=0; - - //current scrollportion is the button that we clicked down on - if(sw->uCurrentScrollPortion != HTSCROLL_NONE) - { - SCROLLBAR *sb = &sw->sbarHorz; - lParam = GetMessagePos(); - ReleaseCapture(); -#ifndef _WIN32 - SetCursor(LoadCursor(NULL,IDC_ARROW)); // OS X seems to like this -#endif - GET_WINDOW_RECT(hwnd, &winrect); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - OSX_REMAP_SCREENY(hwnd,&pt.y); - BOOL hasZoomButtons=0; - - - //emulate the mouse input on a scrollbar here... - if(sw->uCurrentScrollbar == SB_HORZ) - { - //get the total area of the normal Horz scrollbar area - sb = &sw->sbarHorz; - GetHScrollRect(sw, hwnd, &rect,&hasZoomButtons); - } - else if(sw->uCurrentScrollbar == SB_VERT) - { - //get the total area of the normal Horz scrollbar area - sb = &sw->sbarVert; - GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); - } - - //we need to do different things depending on if the - //user is activating the scrollbar itself, or one of - //the inserted buttons - switch(sw->uCurrentScrollPortion) - { - - //The scrollbar is active - case HTSCROLL_LEFT: case HTSCROLL_RIGHT: - case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: - case HTSCROLL_NONE: - case HTSCROLL_ZOOMIN: - case HTSCROLL_ZOOMOUT: - - KillTimer(hwnd, sw->uScrollTimerId); - - case HTSCROLL_THUMB: - - //In case we were thumb tracking, make sure we stop NOW - if(sw->fThumbTracking == TRUE) - { - SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_THUMBPOSITION, nLastPos); - sw->fThumbTracking = FALSE; - } - - //send the SB_ENDSCROLL message now that scrolling has finished - SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_ENDSCROLL, 0); - - //adjust the total scroll area to become where the scrollbar - //really is (take into account the inserted buttons) - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - - //draw whichever scrollbar sb is - NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NORMAL,hasZoomButtons); - - ReleaseDC(hwnd, hdc); - break; - } - - //reset our state to default - sw->uCurrentScrollPortion = HTSCROLL_NONE; - sw->uScrollTimerPortion = HTSCROLL_NONE; - sw->uScrollTimerId = 0; - - sw->uScrollTimerMsg = 0; - sw->uCurrentScrollbar = COOLSB_NONE; - - return 0; - } - else - { - /* - // Can't remember why I did this! - if(GetCapture() == hwnd) - { - ReleaseCapture(); - }*/ - } - - return CallWindowProc(sw->oldproc, hwnd, WM_LBUTTONUP, wParam, lParam); -} - -// -// This function is called whenever the mouse is moved and -// we are dragging the scrollbar thumb about. -// -static LRESULT ThumbTrackHorz(SCROLLBAR *sbar, HWND hwnd, int x, int y) -{ - POINT pt; - RECT rc, winrect, rc2; - COLORREF crCheck1 = GetSBForeColor(hwnd); - COLORREF crCheck2 = GetSBBackColor(hwnd); - HDC hdc; - int thumbpos = nThumbPos; - int pos; - int siMaxMin = 0; - SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); - - SCROLLINFO *si; - si = &sbar->scrollInfo; - - pt.x = x; - pt.y = y; - - - int sbYoffs=0,sbXoffs=0; -#ifdef _WIN32 - // this is a stupid fix for now . this needs a ton of overhauling - { - RECT r; - POINT p={0,0}; - ClientToScreen(hwnd,&p); - GetWindowRect(hwnd,&r); - - if (sbar == &sw->sbarVert) sbYoffs = r.top - p.y; - if (sbar == &sw->sbarHorz) sbXoffs = r.left - p.x; - } -#endif - - //draw the thumb at whatever position - rc = rcThumbBounds; - -#define THUMBTRACK_SNAPDIST 24 - - SetRect(&rc2, rc.left - THUMBTRACK_SNAPDIST*2, rc.top - THUMBTRACK_SNAPDIST, - rc.right + THUMBTRACK_SNAPDIST*2, rc.bottom + THUMBTRACK_SNAPDIST); - - int adj = GetScrollMetric(sbar->nBarType == SB_VERT, SM_CXHORZSB); - rc.left += adj; - rc.right -= adj; - - //keep the thumb within the scrollbar limits - thumbpos = pt.x - nThumbMouseOffset; - if(thumbpos < rc.left) thumbpos = rc.left; - if(thumbpos > rc.right - nThumbSize) thumbpos = rc.right - nThumbSize; - - GET_WINDOW_RECT(hwnd, &winrect); - - if(sbar->nBarType == SB_VERT) - RotateRect(&winrect); - - hdc = GetWindowDC(hwnd); - - - OffsetRect(&rc, -winrect.left, -winrect.top); - thumbpos -= winrect.left; - - //draw the margin before the thumb - SetRect(&rc2, rc.left, rc.top, thumbpos, rc.bottom); - RotateRect0(sbar, &rc2); - - DrawCheckedRect(NULL,hdc, &rc2, crCheck1, crCheck2, sbar, &rcThumbBounds, 0,sbXoffs, sbYoffs ); - - RotateRect0(sbar, &rc2); - - //draw the margin after the thumb - SetRect(&rc2, thumbpos+nThumbSize, rc.top, rc.right, rc.bottom); - - RotateRect0(sbar, &rc2); - - DrawCheckedRect(NULL,hdc, &rc2, crCheck1, crCheck2, sbar, &rcThumbBounds, 0, sbXoffs, sbYoffs ); - - RotateRect0(sbar, &rc2); - - //finally draw the thumb itelf. This is how it looks on win2000, anyway - SetRect(&rc2, thumbpos, rc.top, thumbpos+nThumbSize, rc.bottom); - - RotateRect0(sbar, &rc2); - - if(m_scrollbar_bmp && *m_scrollbar_bmp) - { - drawSkinThumb(hdc, rc2, 0, 1, sbar->nBarType == SB_VERT, &rcThumbBounds, sbar); - } - else - { - // no skinning - { - RECT r = rc2; - if(sw->resizingHthumb) - { - if(sbar->nBarType == SB_HORZ) - { - r.left += m_thumbsize; - r.right -= m_thumbsize; - } - else - { - //disabled for now - /*r.top += m_thumbsize; - r.bottom -= m_thumbsize;*/ - } - } - DrawBlankButton(hwnd,hdc, &r); - } - - if(sw->resizingHthumb) - { - //draw left and right resizers - if(sbar->nBarType == SB_HORZ) - { - RECT thumb = rc2; - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - { - RECT r={thumb.left, thumb.top, thumb.left+m_thumbsize, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - { - RECT r={thumb.right-m_thumbsize, thumb.top, thumb.right, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - DeleteObject(br); - } - else - { - //disabled for now - /*RECT thumb = rc2; - HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); - { - RECT r={thumb.left, thumb.top, thumb.right, thumb.top+m_thumbsize}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - { - RECT r={thumb.left, thumb.bottom - m_thumbsize, thumb.right, thumb.bottom}; - ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); - FillRect(hdc, &r, br); - } - DeleteObject(br);*/ - } - } - } - - RotateRect0(sbar, &rc2); - ReleaseDC(hwnd, hdc); - - //post a SB_TRACKPOS message!!! - siMaxMin = si->nMax - si->nMin; - - if(siMaxMin > 0) - pos = MulDiv(thumbpos-rc.left, siMaxMin-si->nPage + 1, rc.right-rc.left-nThumbSize); - else - pos = thumbpos - rc.left; - - if(pos != nLastPos) - { - si->nTrackPos = pos; - SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_THUMBTRACK, pos); - } - - nLastPos = pos; - - - return 0; -} - -// -// remember to rotate the thumb bounds rectangle!! -// -static LRESULT ThumbTrackVert(SCROLLBAR *sb, HWND hwnd, int x, int y) -{ - //sw->swapcoords = TRUE; - RotateRect(&rcThumbBounds); - ThumbTrackHorz(sb, hwnd, y, x); - RotateRect(&rcThumbBounds); - //sw->swapcoords = FALSE; - - return 0; -} - -// -// Called when we have set the capture from the NCLButtonDown(...) -// -static LRESULT MouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - RECT rect; - UINT thisportion; - HDC hdc; - static UINT lastportion = 0; - static UINT lastbutton = 0; - POINT pt; - RECT winrect; - UINT buttonIdx = 0; - - if(sw->fThumbTracking == TRUE) - { - LONG x, y; - lParam = GetMessagePos(); - x = GET_X_LPARAM(lParam); - y = GET_Y_LPARAM(lParam); - OSX_REMAP_SCREENY(hwnd,&y); - - if(sw->uCurrentScrollbar == SB_HORZ) - return ThumbTrackHorz(&sw->sbarHorz, hwnd, x,y); - - - else if(sw->uCurrentScrollbar == SB_VERT) - return ThumbTrackVert(&sw->sbarVert, hwnd, x,y); - } - - if(sw->uCurrentScrollPortion == HTSCROLL_NONE) - { - return CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam); - } - else - { - LPARAM nlParam; - SCROLLBAR *sb = &sw->sbarHorz; - - nlParam = GetMessagePos(); - - GET_WINDOW_RECT(hwnd, &winrect); - - pt.x = GET_X_LPARAM(nlParam); - pt.y = GET_Y_LPARAM(nlParam); - OSX_REMAP_SCREENY(hwnd,&pt.y); - - //emulate the mouse input on a scrollbar here... - if(sw->uCurrentScrollbar == SB_HORZ) - { - sb = &sw->sbarHorz; - } - else if(sw->uCurrentScrollbar == SB_VERT) - { - sb = &sw->sbarVert; - } - - //get the total area of the normal scrollbar area - BOOL hasZoomButtons; - GetScrollRect(sw, sb->nBarType, hwnd, &rect,&hasZoomButtons); - - //see if we clicked in the inserted buttons / normal scrollbar - //thisportion = GetPortion(sb, hwnd, &rect, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - thisportion = GetPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); - - //we need to do different things depending on if the - //user is activating the scrollbar itself, or one of - //the inserted buttons - switch(sw->uCurrentScrollPortion) - { - - - //The scrollbar is active - case HTSCROLL_LEFT: case HTSCROLL_RIGHT:case HTSCROLL_THUMB: - case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: - case HTSCROLL_NONE: - - //adjust the total scroll area to become where the scrollbar - //really is (take into account the inserted buttons) - - OffsetRect(&rect, -winrect.left, -winrect.top); - hdc = GetWindowDC(hwnd); - - if(thisportion != sw->uCurrentScrollPortion) - { - sw->uScrollTimerPortion = HTSCROLL_NONE; - - if(lastportion != thisportion) - NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NORMAL,hasZoomButtons); - } - //otherwise, draw the button in its depressed / clicked state - else - { - sw->uScrollTimerPortion = sw->uCurrentScrollPortion; - - if(lastportion != thisportion) - NCDrawScrollbar(sb, hwnd, hdc, &rect, thisportion,hasZoomButtons); - } - - ReleaseDC(hwnd, hdc); - - break; - case HTSCROLL_LRESIZER: - case HTSCROLL_RRESIZER: - { - RECT rect; - int nThumbSize, nThumbPos; - int offs = pt.x - nThumbMouseOffset; - if(sw->uCurrentScrollbar == SB_VERT) offs = pt.y - nThumbMouseOffset; - if(sw->uCurrentScrollPortion == HTSCROLL_RRESIZER) offs = -offs; - - if((sw->uCurrentScrollbar == SB_VERT)) - { - GetVScrollRect(sw, hwnd, &rect,NULL); - RotateRect0(sb, &rect); - CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); - SendMessage(hwnd, (sw->uCurrentScrollPortion == HTSCROLL_RRESIZER?WM_SB_TRESIZE_VB:WM_SB_TRESIZE_VT), offs, ((nThumbSize&0xffff)<<16) + ((rect.right-rect.left)&0xffff)); - } - else - { - GetHScrollRect(sw, hwnd, &rect,NULL); - CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); - SendMessage(hwnd, (sw->uCurrentScrollPortion == HTSCROLL_RRESIZER?WM_SB_TRESIZE_HR:WM_SB_TRESIZE_HL), offs, ((nThumbSize&0xffff)<<16) + ((rect.right-rect.left)&0xffff)); - } - - if(sw->uCurrentScrollbar == SB_VERT) - { - //nThumbMouseOffset = pt.y; - SetCursor(LoadCursor(NULL,IDC_SIZENS)); - } - else - { - //nThumbMouseOffset = pt.x; - SetCursor(LoadCursor(NULL,IDC_SIZEWE)); - } - } - break; - case HTSCROLL_RESIZER: - { - int offs = pt.x - nThumbMouseOffset; - if(sw->uCurrentScrollbar == SB_VERT) offs = pt.y - nThumbMouseOffset; - SendMessage(hwnd, WM_SB_RESIZE, offs, sw->uCurrentScrollbar == SB_VERT); - if(sw->uCurrentScrollbar == SB_VERT) - { - nThumbMouseOffset = pt.y; - SetCursor(LoadCursor(NULL,IDC_SIZENS)); - } - else - { - nThumbMouseOffset = pt.x; - SetCursor(LoadCursor(NULL,IDC_SIZEWE)); - } - } - break; - } - - - lastportion = thisportion; - lastbutton = buttonIdx; - - //must return zero here, because we might get cursor anomilies - //CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam); - return 0; - - } -} - - -// -// We must allocate from in the non-client area for our scrollbars -// Call the default window procedure first, to get the borders (if any) -// allocated some space, then allocate the space for the scrollbars -// if they fit -// -static LRESULT NCCalcSize(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - NCCALCSIZE_PARAMS *nccsp; - RECT *rect; - RECT oldrect; - BOOL fCalcValidRects = (wParam == TRUE); - SCROLLBAR *sb; - UINT ret; - - //Regardless of the value of fCalcValidRects, the first rectangle - //in the array specified by the rgrc structure member of the - //NCCALCSIZE_PARAMS structure contains the coordinates of the window, - //so we can use the exact same code to modify this rectangle, when - //wParam is TRUE and when it is FALSE. - nccsp = (NCCALCSIZE_PARAMS *)lParam; - rect = &nccsp->rgrc[0]; - oldrect = *rect; - - - //call the default procedure to get the borders allocated - ret = CallWindowProcStyleMod(sw,hwnd, WM_NCCALCSIZE, wParam, lParam); - - // calculate what the size of each window border is, - sw->cxLeftEdge = rect->left - oldrect.left; - sw->cxRightEdge = oldrect.right - rect->right; - sw->cyTopEdge = rect->top - oldrect.top; - sw->cyBottomEdge = oldrect.bottom - rect->bottom; - - sb = &sw->sbarHorz; - - //if there is room, allocate some space for the horizontal scrollbar - //NOTE: Change the ">" to a ">=" to make the horz bar totally fill the - //window before disappearing - - if((sb->fScrollFlags & CSBS_VISIBLE) && - rect->bottom - rect->top > GetScrollMetric(FALSE, SM_CYHORZSB)) - { - rect->bottom -= GetScrollMetric(FALSE, SM_CYHORZSB); - sb->fScrollVisible = TRUE; - } - else - { - sb->fScrollVisible = FALSE; - } - - sb = &sw->sbarVert; - - //if there is room, allocate some space for the vertical scrollbar - if((sb->fScrollFlags & CSBS_VISIBLE) && - rect->right - rect->left >= GetScrollMetric(TRUE, SM_CXVERTSB)) - { - if(sw->fLeftScrollbar) - rect->left += GetScrollMetric(TRUE, SM_CXVERTSB); - else - rect->right -= GetScrollMetric(TRUE, SM_CXVERTSB); - - sb->fScrollVisible = TRUE; - } - else - sb->fScrollVisible = FALSE; - -//printf("nccalcsize, %d,%d,%d,%d -> %d,%d,%d,%d\n",oldrect.left,oldrect.top,oldrect.right,oldrect.bottom, -// rect->left,rect->top,rect->right,rect->bottom); - - //don't return a value unless we actually modify the other rectangles - //in the NCCALCSIZE_PARAMS structure. In this case, we return 0 - //no matter what the value of fCalcValidRects is - return ret;//FALSE; -} - -// -// used for hot-tracking over the scroll buttons -// -static LRESULT NCMouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wHitTest, LPARAM lParam) -{ - { - LONG x, y; - int p; - RECT hr, vr; - lParam = GetMessagePos(); - x = GET_X_LPARAM(lParam); - y = GET_Y_LPARAM(lParam); - OSX_REMAP_SCREENY(hwnd,&y); - BOOL hasZoomButtons; - GetHScrollRect(sw, hwnd, &hr,&hasZoomButtons); - p = GetHorzPortion(&sw->sbarHorz, hwnd, &hr, x, y,hasZoomButtons); - if(p == HTSCROLL_NONE) - { - GetVScrollRect(sw, hwnd, &vr,&hasZoomButtons); - p = GetVertPortion(&sw->sbarVert, hwnd, &vr, x, y,hasZoomButtons); - } - if(p == HTSCROLL_RESIZER || p == HTSCROLL_LRESIZER || p == HTSCROLL_RRESIZER) - { - if(wHitTest == HTHSCROLL) - SetCursor(LoadCursor(NULL,IDC_SIZEWE)); - else - SetCursor(LoadCursor(NULL,IDC_SIZENS)); - } -#ifndef _WIN32 - else SetCursor(LoadCursor(NULL,IDC_ARROW)); -#endif - } - - //install a timer for the mouse-over events, if the mouse moves - //over one of the scrollbars - hwndCurCoolSB = hwnd; - if(wHitTest == HTHSCROLL) - { - if(sw->uMouseOverScrollbar == SB_HORZ) - return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); - - sw->uLastHitTestPortion = HTSCROLL_NONE; - sw->uHitTestPortion = HTSCROLL_NONE; - GetScrollRect(sw, SB_HORZ, hwnd, &sw->MouseOverRect, &sw->MouseOverRect_hasZoomButtons); - sw->uMouseOverScrollbar = SB_HORZ; - sw->uMouseOverId = SetTimer(hwnd, COOLSB_TIMERID3, COOLSB_TIMERINTERVAL3, 0); - - NCPaint(sw, hwnd, 1, 0); - } - else if(wHitTest == HTVSCROLL) - { - if(sw->uMouseOverScrollbar == SB_VERT) - return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); - - sw->uLastHitTestPortion = HTSCROLL_NONE; - sw->uHitTestPortion = HTSCROLL_NONE; - GetScrollRect(sw, SB_VERT, hwnd, &sw->MouseOverRect, &sw->MouseOverRect_hasZoomButtons); - sw->uMouseOverScrollbar = SB_VERT; - sw->uMouseOverId = SetTimer(hwnd, COOLSB_TIMERID3, COOLSB_TIMERINTERVAL3, 0); - - NCPaint(sw, hwnd, 1, 0); - } - - - return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); -} - -// -// Timer routine to generate scrollbar messages -// -static LRESULT CoolSB_Timer(SCROLLWND *swnd, HWND hwnd, WPARAM wTimerId, LPARAM lParam) -{ - //let all timer messages go past if we don't have a timer installed ourselves - if(swnd->uScrollTimerId == 0 && swnd->uMouseOverId == 0 && swnd->uZoomTimerId == 0) - { - return CallWindowProc(swnd->oldproc, hwnd, WM_TIMER, wTimerId, lParam); - } - - if (wTimerId == COOLSB_TIMERID4) - { - SendMessage(hwnd, WM_SB_ZOOM, swnd->uZoomTimerMode/2, swnd->uZoomTimerMode&1); - return 0; - } - - //mouse-over timer - if(wTimerId == COOLSB_TIMERID3) - { - POINT pt; - RECT rect, winrect; - HDC hdc; - SCROLLBAR *sbar; - - if(swnd->fThumbTracking) - return 0; - - //if the mouse moves outside the current scrollbar, - //then kill the timer.. - GetCursorPos(&pt); - - RECT mor = swnd->MouseOverRect; - BOOL hasZoomButtons = swnd->MouseOverRect_hasZoomButtons; - - if (hasZoomButtons && swnd->resizingHthumb) - { - int zbs = GetZoomButtonSize(swnd->uMouseOverScrollbar==SB_VERT); - int extrasz=zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); - - if(swnd->uMouseOverScrollbar == SB_VERT) - mor.bottom += extrasz; - else - mor.right += extrasz; - } - - if(!PtInRect(&mor, pt)||WindowFromPoint(pt)!=hwnd) - { - KillTimer(hwnd, swnd->uMouseOverId); - swnd->uMouseOverId = 0; - swnd->uMouseOverScrollbar = COOLSB_NONE; - swnd->uLastHitTestPortion = HTSCROLL_NONE; - - swnd->uHitTestPortion = HTSCROLL_NONE; - NCPaint(swnd, hwnd, 1, 0); - } - else - { - if(swnd->uMouseOverScrollbar == SB_HORZ) - { - sbar = &swnd->sbarHorz; - swnd->uHitTestPortion = GetHorzPortion(sbar, hwnd, &swnd->MouseOverRect, pt.x, pt.y,hasZoomButtons); - } - else - { - sbar = &swnd->sbarVert; - swnd->uHitTestPortion = GetVertPortion(sbar, hwnd, &swnd->MouseOverRect, pt.x, pt.y,hasZoomButtons); - } - - if(swnd->uLastHitTestPortion != swnd->uHitTestPortion) - { - rect = swnd->MouseOverRect; - - GET_WINDOW_RECT(hwnd, &winrect); - OffsetRect(&rect, -winrect.left, -winrect.top); - - hdc = GetWindowDC(hwnd); - NCDrawScrollbar(sbar, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); - ReleaseDC(hwnd, hdc); - } - - swnd->uLastHitTestPortion = swnd->uHitTestPortion; - } - - return 0; - } - - //if the first timer goes off, then we can start a more - //regular timer interval to auto-generate scroll messages - //this gives a slight pause between first pressing the scroll arrow, and the - //actual scroll starting - if(wTimerId == COOLSB_TIMERID1) - { - KillTimer(hwnd, swnd->uScrollTimerId); - swnd->uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID2, COOLSB_TIMERINTERVAL2, 0); - return 0; - } - //send the scrollbar message repeatedly - else if(wTimerId == COOLSB_TIMERID2) - { - //need to process a spoof WM_MOUSEMOVE, so that - //we know where the mouse is each time the scroll timer goes off. - //This is so we can stop sending scroll messages if the thumb moves - //under the mouse. - POINT pt; - GetCursorPos(&pt); - ScreenToClient(hwnd, &pt); - - MouseMove(swnd, hwnd, MK_LBUTTON, MAKELPARAM(pt.x, pt.y)); - - if(swnd->uScrollTimerPortion != HTSCROLL_NONE) - SendScrollMessage(hwnd, swnd->uScrollTimerMsg, swnd->uScrollTimerPortion, 0); - - return 0; - } - else - { - return CallWindowProc(swnd->oldproc, hwnd, WM_TIMER, wTimerId, lParam); - } -} - -// -// We must intercept any calls to SetWindowLong, to check if -// left-scrollbars are taking effect or not -// -static LRESULT CoolSB_StyleChange(SCROLLWND *swnd, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - STYLESTRUCT *ss = (STYLESTRUCT *)lParam; - - if(wParam == GWL_EXSTYLE) - { - if(ss->styleNew & WS_EX_LEFTSCROLLBAR) - swnd->fLeftScrollbar = TRUE; - else - swnd->fLeftScrollbar = FALSE; - } - - return CallWindowProc(swnd->oldproc, hwnd, msg, wParam, lParam); -} - - - -// -// CoolScrollbar subclass procedure. -// Handle all messages needed to mimick normal windows scrollbars -// -static LRESULT CALLBACK CoolSBWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc; - SCROLLWND *swnd = GetScrollWndFromHwnd(hwnd); - static int count; - - switch(message) - { - case WM_NCDESTROY: - //this should NEVER be called, because the user - //should have called Uninitialize() themselves. - - //However, if the user tries to call Uninitialize().. - //after this window is destroyed, this window's entry in the lookup - //table will not be there, and the call will fail - oldproc = swnd->oldproc; - UninitializeCoolSB(hwnd); - - //we must call the original window procedure, otherwise it - //will never get the WM_NCDESTROY message, and it wouldn't - //be able to clean up etc. - return CallWindowProc(oldproc, hwnd, message, wParam, lParam); - - case WM_NCCALCSIZE: - return NCCalcSize(swnd, hwnd, wParam, lParam); - - case WM_NCPAINT: - return NCPaint(swnd, hwnd, wParam, lParam); - - case WM_NCHITTEST: - return NCHitTest(swnd, hwnd, wParam, lParam); - - #ifdef _WIN32 - case WM_NCRBUTTONDOWN: case WM_NCRBUTTONUP: - case WM_NCMBUTTONDOWN: case WM_NCMBUTTONUP: - if(wParam == HTHSCROLL || wParam == HTVSCROLL) - return 0; - break; - #endif - - case WM_NCLBUTTONDBLCLK: - if(wParam == HTHSCROLL || wParam == HTVSCROLL) - return NCLButtonDown(swnd, hwnd, wParam, lParam,TRUE); - else - break; - - case WM_NCLBUTTONDOWN: - return NCLButtonDown(swnd, hwnd, wParam, lParam,FALSE); - - - case WM_LBUTTONUP: - return LButtonUp(swnd, hwnd, wParam, lParam); - - case WM_MOUSEMOVE: - return MouseMove(swnd, hwnd, wParam, lParam); - - case WM_TIMER: - return CoolSB_Timer(swnd, hwnd, wParam, lParam); - - //case WM_STYLECHANGING: - // return CoolSB_StyleChange(swnd, hwnd, WM_STYLECHANGING, wParam, lParam); - case WM_STYLECHANGED: - - if(swnd->bPreventStyleChange) - { - // the NCPAINT handler has told us to eat this message! - return 0; - } - else - { - if (message == WM_STYLECHANGED) - return CoolSB_StyleChange(swnd, hwnd, WM_STYLECHANGED, wParam, lParam); - else - break; - } - - case WM_NCMOUSEMOVE: - return NCMouseMove(swnd, hwnd, wParam, lParam); - - - case WM_CAPTURECHANGED: - break; - -#ifdef _WIN32 - case WM_NCACTIVATE: // fix for floating windows etc on XPsp2 etc - case WM_SYSCOMMAND: // fix for MIDI editor when fully zoomed out on XPsp2 - - return CallWindowProcStyleMod(swnd,hwnd,message,wParam,lParam); -#endif - default: -#if 0 - if (message) - { - static int msgs[512]={0,}; - int x; - for(x=0;x<512&&msgs[x] && msgs[x]!=message;x++); - if (x<512 && !msgs[x]) - { - msgs[x]=message; - FILE *fp = fopen("C:/log.txt","a+"); - if (fp) { fprintf(fp,"%d\n",message); fclose(fp); } - - } - } -#endif - break; - } - - - return CallWindowProc(swnd->oldproc, hwnd, message, wParam, lParam); -} - -void CoolSB_OnColorThemeChange() -{ - m_scrollbar_bmp = NULL; - g_coolsb_imageVersion++; -} - - - - -#ifndef _WIN32 // SWELL does not yet emulate these, so we have some default behaviors here - -static BOOL GetScrollInfo(HWND hwnd, int sb, SCROLLINFO *si) -{ - si->nMin=0; si->nMax=1000; si->nPage=10; si->nPos=si->nTrackPos=0; - return FALSE; -} -static int GetScrollPos(HWND hwnd, int sb) -{ - return 0; -} - -static BOOL GetScrollRange(HWND hwnd, int sb, int *minpos, int *maxpos) -{ - if (minpos) *minpos=0; - if (maxpos) *maxpos=1000; - return 0; -} -static BOOL SetScrollInfo(HWND hwnd, int sb, SCROLLINFO *si, BOOL redraw) -{ - return 0; -} -static BOOL SetScrollRange(HWND hwnd, int nBar, int minv, int maxv, BOOL fRedraw) -{ -return 0; -} -static int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) -{ - return 0; -} -static BOOL ShowScrollBar(HWND hwnd, int nBar, BOOL vis) -{ - return 0; -} - - -#endif - -static TCHAR szPropStr[] = _T("CoolSBSubclassPtr"); - -SCROLLWND *GetScrollWndFromHwnd(HWND hwnd) -{ - return (SCROLLWND *)GetProp(hwnd, szPropStr); -} - -SCROLLBAR *GetScrollBarFromHwnd(HWND hwnd, UINT nBar) -{ - SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); - - if(!sw) return 0; - - if(nBar == SB_HORZ) - return &sw->sbarHorz; - else if(nBar == SB_VERT) - return &sw->sbarVert; - else - return 0; -} - -BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd) -{ - if(GetScrollWndFromHwnd(hwnd)) - return TRUE; - else - return FALSE; -} - -// -// Special support for USER32.DLL patching (using Detours library) -// The only place we call a real scrollbar API is in InitializeCoolSB, -// where we call EnableScrollbar. -// -// We HAVE to call the origial EnableScrollbar function, -// so we need to be able to set a pointer to this func when using -// using Detours (or any other LIB??) -// - - -static void RedrawNonClient(HWND hwnd, BOOL fFrameChanged) -{ - if(fFrameChanged == FALSE) - { - SendMessage(hwnd, WM_NCPAINT, (WPARAM)1, 0); - } - else - { -#ifdef _WIN32 - SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE - | SWP_FRAMECHANGED | SWP_DRAWFRAME); -#endif - } -} - -// -// return the default minimum size of a scrollbar thumb -// -int WINAPI CoolSB_GetDefaultMinThumbSize(void) -{ -#ifdef _WIN32 - DWORD dwVersion = GetVersion(); - - // set the minimum thumb size for a scrollbar. This - // differs between NT4 and 2000, so need to check to see - // which platform we are running under - if(dwVersion < 0x80000000) // Windows NT/2000 - { - if(LOBYTE(LOWORD(dwVersion)) >= 5) - return MINTHUMBSIZE_2000; - else - return MINTHUMBSIZE_NT4; - } - else - { - return MINTHUMBSIZE_NT4; - } - #else - return MINTHUMBSIZE_2000; - #endif -} - - -static SCROLLINFO *GetScrollInfoFromHwnd(HWND hwnd, int fnBar) -{ - SCROLLBAR *sb = GetScrollBarFromHwnd(hwnd, fnBar); - - if(sb == 0) - return FALSE; - - if(fnBar == SB_HORZ) - { - return &sb->scrollInfo; - } - else if(fnBar == SB_VERT) - { - return &sb->scrollInfo; - } - else - return NULL; -} -// -// Initialize the cool scrollbars for a window by subclassing it -// and using the coolsb window procedure instead -// -BOOL WINAPI InitializeCoolSB(HWND hwnd) -{ - SCROLLWND *sw; - SCROLLINFO *si; - RECT rect; - DWORD dwCurStyle; - //BOOL fDisabled; - - - GetClientRect(hwnd, &rect); - - //if we have already initialized Cool Scrollbars for this window, - //then stop the user from doing it again - if(GetScrollWndFromHwnd(hwnd) != 0) - { - return FALSE; - } - - //allocate a private scrollbar structure which we - //will use to keep track of the scrollbar data -#ifdef _WIN32 - sw = (SCROLLWND *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCROLLWND)); -#else - sw = (SCROLLWND *)calloc(1,sizeof(SCROLLWND)); -#endif - - sw->uCurrentScrollbar = COOLSB_NONE; //SB_HORZ / SB_VERT - sw->uCurrentScrollPortion = HTSCROLL_NONE; - sw->uMouseOverScrollbar = COOLSB_NONE; - sw->uHitTestPortion = HTSCROLL_NONE; - sw->uLastHitTestPortion = HTSCROLL_NONE; - sw->uScrollTimerPortion = HTSCROLL_NONE; - - si = &sw->sbarHorz.scrollInfo; - si->cbSize = sizeof(SCROLLINFO); - si->fMask = SIF_ALL; - GetScrollInfo(hwnd, SB_HORZ, si); - - si = &sw->sbarVert.scrollInfo; - si->cbSize = sizeof(SCROLLINFO); - si->fMask = SIF_ALL; - GetScrollInfo(hwnd, SB_VERT, si); - - //check to see if the window has left-aligned scrollbars - if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR) - sw->fLeftScrollbar = TRUE; - else - sw->fLeftScrollbar = FALSE; - - dwCurStyle = GetWindowLong(hwnd, GWL_STYLE); - - SetProp(hwnd, szPropStr, (HANDLE)sw); - - - //scrollbars will automatically get enabled, even if - //they aren't to start with....sorry, but there isn't an - //easy alternative. - if(dwCurStyle & WS_HSCROLL) - sw->sbarHorz.fScrollFlags = CSBS_VISIBLE; - - if(dwCurStyle & WS_VSCROLL) - sw->sbarVert.fScrollFlags = CSBS_VISIBLE; - - //need to be able to distinguish between horizontal and vertical - //scrollbars in some instances - sw->sbarHorz.nBarType = SB_HORZ; - sw->sbarVert.nBarType = SB_VERT; - - sw->bPreventStyleChange = FALSE; - - sw->resizingHthumb = FALSE; - - sw->oldproc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR)CoolSBWndProc); - - CoolSB_SetMinThumbSize(hwnd, SB_BOTH, CoolSB_GetDefaultMinThumbSize()); - - - //send the window a frame changed message to update the scrollbars - RedrawNonClient(hwnd, TRUE); - - return TRUE; -} - - -BOOL WINAPI CoolSB_IsThumbTracking(HWND hwnd) -{ - SCROLLWND *sw; - - if((sw = GetScrollWndFromHwnd(hwnd)) == NULL) - return FALSE; - else - return sw->fThumbTracking; -} - - -BOOL WINAPI CoolSB_GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi) -{ - SCROLLINFO *mysi; - BOOL copied = FALSE; - - if(!lpsi) - return FALSE; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) - { - return GetScrollInfo(hwnd, fnBar, lpsi); - } - - if(lpsi->fMask & SIF_PAGE) - { - lpsi->nPage = mysi->nPage; - copied = TRUE; - } - - if(lpsi->fMask & SIF_POS) - { - lpsi->nPos = mysi->nPos; - copied = TRUE; - } - - if(lpsi->fMask & SIF_TRACKPOS) - { - lpsi->nTrackPos = mysi->nTrackPos; - copied = TRUE; - } - - if(lpsi->fMask & SIF_RANGE) - { - lpsi->nMin = mysi->nMin; - lpsi->nMax = mysi->nMax; - copied = TRUE; - } - - return copied; -} - -int WINAPI CoolSB_GetScrollPos (HWND hwnd, int nBar) -{ - SCROLLINFO *mysi; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) - return GetScrollPos(hwnd, nBar); - - return mysi->nPos; -} - -BOOL WINAPI CoolSB_GetScrollRange (HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) -{ - SCROLLINFO *mysi; - - if(!lpMinPos || !lpMaxPos) - return FALSE; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) - return GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); - - *lpMinPos = mysi->nMin; - *lpMaxPos = mysi->nMax; - - return TRUE; -} - -int WINAPI CoolSB_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw) -{ - SCROLLINFO *mysi; - SCROLLBAR *sbar; - BOOL fRecalcFrame = FALSE; - - if(!lpsi) - return FALSE; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) - return SetScrollInfo(hwnd, fnBar, lpsi, fRedraw); - - //if(CoolSB_IsThumbTracking(hwnd)) - // return mysi->nPos; - - if(lpsi->fMask & SIF_RANGE) - { - mysi->nMin = lpsi->nMin; - mysi->nMax = lpsi->nMax; - } - - //The nPage member must specify a value from 0 to nMax - nMin +1. - if(lpsi->fMask & SIF_PAGE) - { - UINT t = (UINT)(mysi->nMax - mysi->nMin + 1); - mysi->nPage = min(max(0, lpsi->nPage), t); - } - - //The nPos member must specify a value between nMin and nMax - max(nPage - 1, 0). - if(lpsi->fMask & SIF_POS) - { - mysi->nPos = max(lpsi->nPos, mysi->nMin); - mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); - } - - sbar = GetScrollBarFromHwnd(hwnd, fnBar); - - if((lpsi->fMask & SIF_DISABLENOSCROLL) || (sbar->fScrollFlags & CSBS_THUMBALWAYS)) - { - if(!sbar->fScrollVisible) - { - CoolSB_ShowScrollBar(hwnd, fnBar, TRUE); - fRecalcFrame = TRUE; - } - } - else - { - if( mysi->nPage > (UINT)mysi->nMax - || mysi->nPage == (UINT)mysi->nMax && mysi->nMax == 0 - || mysi->nMax <= mysi->nMin) - { - if(sbar->fScrollVisible) - { - CoolSB_ShowScrollBar(hwnd, fnBar, FALSE); - fRecalcFrame = TRUE; - } - } - else - { - if(!sbar->fScrollVisible) - { - CoolSB_ShowScrollBar(hwnd, fnBar, TRUE); - fRecalcFrame = TRUE; - } - - } - - } - - if(fRedraw && !CoolSB_IsThumbTracking(hwnd)) - RedrawNonClient(hwnd, fRecalcFrame); - - return mysi->nPos; -} - - -int WINAPI CoolSB_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) -{ - SCROLLINFO *mysi; - int oldpos; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) - { - return SetScrollPos(hwnd, nBar, nPos, fRedraw); - } - - //this is what should happen, but real scrollbars don't work like this.. - //if(CoolSB_IsThumbTracking(hwnd)) - // return mysi->nPos; - - //validate and set the scollbar position - oldpos = mysi->nPos; - mysi->nPos = max(nPos, mysi->nMin); - mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); - - if(fRedraw && !CoolSB_IsThumbTracking(hwnd)) - RedrawNonClient(hwnd, FALSE); - - return oldpos; -} - -int WINAPI CoolSB_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) -{ - SCROLLINFO *mysi; - - if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) - return SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); - - if(CoolSB_IsThumbTracking(hwnd)) - return mysi->nPos; - - //hide the scrollbar if nMin == nMax - //nMax-nMin must not be greater than MAXLONG - mysi->nMin = nMinPos; - mysi->nMax = nMaxPos; - - if(fRedraw) - RedrawNonClient(hwnd, FALSE); - - return TRUE; -} - -// -// Show or hide the specified scrollbars -// -BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow) -{ - SCROLLBAR *sbar; - BOOL bFailed = FALSE; - DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE); - - if(!CoolSB_IsCoolScrollEnabled(hwnd)) - { - return ShowScrollBar(hwnd, wBar, fShow); - } - if((wBar == SB_HORZ || wBar == SB_BOTH) && - (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) - { - sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; - sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); - //bFailed = TRUE; - - if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL); - else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL); - } - - if((wBar == SB_VERT || wBar == SB_BOTH) && - (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) - { - sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; - sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); - //bFailed = TRUE; - - if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL); - else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL); - } - - if(bFailed) - { - return FALSE; - } - else - { - //DWORD style = GetWindowLong(hwnd, GWL_STYLE); - //style |= WS_VSCROLL; - - //if(s - //SetWindowLong(hwnd, GWL_STYLE, style); - - SetWindowPos(hwnd, 0, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | - SWP_NOACTIVATE | SWP_FRAMECHANGED); - - return TRUE; - } -} - -// -// Remove cool scrollbars from the specified window. -// -HRESULT WINAPI UninitializeCoolSB(HWND hwnd) -{ - int i = 0; - SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); - if(!sw) return E_FAIL; - - //restore the window procedure with the original one - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR)sw->oldproc); - - RemoveProp(hwnd, szPropStr); - //SetWindowLong(hwnd, GWL_USERDATA, 0); - - delete sw->sbarHorz.liceBkgnd; - delete sw->sbarHorz.liceThumb; - delete sw->sbarVert.liceBkgnd; - delete sw->sbarVert.liceThumb; - sw->sbarHorz.liceBkgnd = NULL; - sw->sbarHorz.liceThumb = NULL; - sw->sbarVert.liceBkgnd = NULL; - sw->sbarVert.liceThumb = NULL; - - //finally, release the memory needed for the cool scrollbars -#ifdef _WIN32 - HeapFree(GetProcessHeap(), 0, sw); -#else - free(sw); -#endif - - //Force WM_NCCALCSIZE and WM_NCPAINT so the original scrollbars can kick in - RedrawNonClient(hwnd, TRUE); - - return S_OK; -} - - -// -// Set the minimum size, in pixels, that the thumb box will shrink to. -// -BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size) -{ - SCROLLBAR *sbar; - - if(!GetScrollWndFromHwnd(hwnd)) - return FALSE; - - if(size == -1) - size = CoolSB_GetDefaultMinThumbSize(); - - if((wBar == SB_HORZ || wBar == SB_BOTH) && - (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) - { - sbar->nMinThumbSize = size; - } - - if((wBar == SB_VERT || wBar == SB_BOTH) && - (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) - { - sbar->nMinThumbSize = size; - } - - return TRUE; -} - -BOOL WINAPI CoolSB_SetResizingThumb(HWND hwnd, BOOL active) -{ - SCROLLWND *swnd; - - if(!(swnd = GetScrollWndFromHwnd(hwnd))) - return FALSE; - - swnd->resizingHthumb = active; - - return TRUE; -} diff --git a/WDL/wingui/scrollbar/coolscroll.h b/WDL/wingui/scrollbar/coolscroll.h deleted file mode 100644 index 22ced403..00000000 --- a/WDL/wingui/scrollbar/coolscroll.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef _COOLSBLIB_INCLUDED -#define _COOLSBLIB_INCLUDED - -/* - WDL - Skinned/Resizing thumb scrollbar library - Based on the "Cool Scrollbar Library v1.2" by James Brown - http://www.catch22.net - - Original version Copyright(c) 2001 J Brown - Modifications copyright (C) 2006 and later Cockos Incorporated - - Note: for a more featureful, less hacked up version, you may wish to download the - original from catch22.net. It has lots of added features, whereas this version is - very much tailored for Cockos' needs. - - License: - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -#ifdef __cplusplus -extern "C"{ -#endif - -/* - - Public interface to the Cool Scrollbar library - - -*/ - -// notifications sent on user actions -#define WM_SB_RESIZE (WM_USER+511) -#define WM_SB_ZOOM (WM_USER+512) -#define WM_SB_TRESIZE_HL (WM_USER+513) -#define WM_SB_TRESIZE_HR (WM_USER+514) -#define WM_SB_TRESIZE_VT (WM_USER+515) -#define WM_SB_TRESIZE_VB (WM_USER+516) -#define WM_SB_TRESIZE_START (WM_USER+517) -#define WM_SB_DBLCLK (WM_USER+518) // wParam has SB_HORZ or SB_VERT - - -#ifndef COOLSB_NO_FUNC_DEFS -BOOL WINAPI InitializeCoolSB(HWND hwnd); -HRESULT WINAPI UninitializeCoolSB(HWND hwnd); // call in WM_DESTROY -- not strictly required, but recommended - -BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size); -BOOL WINAPI CoolSB_IsThumbTracking(HWND hwnd); -BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd); - -// -BOOL WINAPI CoolSB_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi); -int WINAPI CoolSB_GetScrollPos(HWND hwnd, int nBar); -BOOL WINAPI CoolSB_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos); - -// -int WINAPI CoolSB_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw); -int WINAPI CoolSB_SetScrollPos (HWND hwnd, int nBar, int nPos, BOOL fRedraw); -int WINAPI CoolSB_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw); -BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow); - -BOOL WINAPI CoolSB_SetResizingThumb(HWND hwnd, BOOL active); -void CoolSB_SetScale(float scale); // sets scale to use for scrollbars (does not refresh, though -- set this at startup/etc) -void CoolSB_OnColorThemeChange(); // refreshes all - - - -// TO BE IMPLEMENTED BY APP: -void *GetIconThemePointer(const char *name); // implemented by calling app, can return a LICE_IBitmap **img for "scrollbar" -int CoolSB_GetSysColor(HWND hwnd, int val); // can be a passthrough to GetSysColor() - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/WDL/wingui/virtwnd-controls.h b/WDL/wingui/virtwnd-controls.h deleted file mode 100644 index cb93607d..00000000 --- a/WDL/wingui/virtwnd-controls.h +++ /dev/null @@ -1,370 +0,0 @@ -/* - WDL - virtwnd-controls.h - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - - - -#ifndef _WDL_VIRTWND_CONTROLS_H_ -#define _WDL_VIRTWND_CONTROLS_H_ - -#include "virtwnd.h" -#include "virtwnd-skin.h" - -#include "../lice/lice_text.h" - -// an app should implement these -extern int WDL_STYLE_WantGlobalButtonBorders(); -extern bool WDL_STYLE_WantGlobalButtonBackground(int *col); -extern int WDL_STYLE_GetSysColor(int); -extern void WDL_STYLE_ScaleImageCoords(int *x, int *y); -extern bool WDL_Style_WantTextShadows(int *col); - -// this is the default, you can override per painter if you want -extern bool WDL_STYLE_GetBackgroundGradient(double *gradstart, double *gradslope); // return values 0.0-1.0 for each, return false if no gradient desired - -// for slider -extern LICE_IBitmap *WDL_STYLE_GetSliderBitmap2(bool vert); -extern bool WDL_STYLE_AllowSliderMouseWheel(); -extern int WDL_STYLE_GetSliderDynamicCenterPos(); - - -// functions for handling knob drawing in non-vwnds -extern WDL_VirtualWnd_BGCfg *vwnd_slider_getknobimageforsize(WDL_VirtualWnd_BGCfg *knoblist, int nknoblist,int *vieww, int *viewh, int *ksw, int *ksh, int *ks_offs); -extern void vwnd_slider_drawknobstack(LICE_IBitmap *drawbm, double val, WDL_VirtualWnd_BGCfg *knobimage, int ksw, int ksh, int ks_offs, int dx, int dy, int dw, int dh, double alpha=1.0f); - - -/* recommended defaults for the above: - -int WDL_STYLE_WantGlobalButtonBorders() { return 0; } -bool WDL_STYLE_WantGlobalButtonBackground(int *col) { return false; } -int WDL_STYLE_GetSysColor(int p) { return GetSysColor(p); } -void WDL_STYLE_ScaleImageCoords(int *x, int *y) { } -bool WDL_Style_WantTextShadows(int *col) { return false; } -bool WDL_STYLE_GetBackgroundGradient(double *gradstart, double *gradslope) { return false; } -LICE_IBitmap *WDL_STYLE_GetSliderBitmap2(bool vert) { return NULL; } -bool WDL_STYLE_AllowSliderMouseWheel() { return true; } -int WDL_STYLE_GetSliderDynamicCenterPos() { return 500; } - -*/ - - - - -// virtwnd-iconbutton.cpp -class WDL_VirtualIconButton : public WDL_VWnd -{ - public: - WDL_VirtualIconButton(); - virtual ~WDL_VirtualIconButton(); - virtual const char *GetType() { return "vwnd_iconbutton"; } - - virtual int OnMouseDown(int xpos, int ypos); // return -1 to eat, >0 to capture - virtual void OnMouseMove(int xpos, int ypos); - virtual void OnMouseUp(int xpos, int ypos); - virtual bool OnMouseDblClick(int xpos, int ypos); - - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual void OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - - virtual bool WantsPaintOver(); - virtual void GetPositionPaintOverExtent(RECT *r); - - - void SetEnabled(bool en) {m_en=en; } - bool GetEnabled() { return m_en; } - - void SetGrayed(bool grayed) { m_grayed = grayed; SetEnabled(!grayed); } - - void SetIcon(WDL_VirtualIconButton_SkinConfig *cfg, float alpha=1.0f, bool buttonownsicon=false); - void SetIsButton(bool isbutton) { m_is_button=isbutton; } - bool GetIsButton() { return m_is_button; } - - void SetImmediate(bool immediate) { m_immediate=immediate; } // send message on mousedown, not mouseup - - void SetBGCol1Callback(int msg) { m_bgcol1_msg=msg; } - - void SetForceBorder(bool fb) { m_forceborder=fb; } - - // only used if no icon config set, or if force is set - void SetTextLabel(const char *text); // no change of alignment etc - void SetTextLabel(const char *text, int align, LICE_IFont *font=NULL); - const char* GetTextLabel() { return m_textlbl.Get(); } - void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } - void SetVMargins(int t, int b) { m_margin_t=t; m_margin_b=b; }; - - // if icon config is set, check state == 1 will swap the up and down image - void SetCheckState(char state); // -1 = no checkbox, 0=unchecked, 1=checked - char GetCheckState() { return m_checkstate; } - - WDL_VirtualIconButton_SkinConfig* GetIcon() { return m_iconCfg; } // note button does not own m_iconCfg - bool ButtonOwnsIcon() { return m_ownsicon; } - - void SetForceText(bool ft, int color=0) { m_forcetext=ft; m_forcetext_color=color; } - bool GetForceText() { return m_forcetext; } - void SetTextLabelAlign(char align) { m_textalign=align; } - - void SetFont(LICE_IFont *font, LICE_IFont *vfont=NULL) { m_textfont=font; m_textfontv=vfont; } - LICE_IFont *GetFont(bool vfont=false) { return vfont?m_textfontv:m_textfont; } - - protected: - - void DoSendCommand(int xpos, int ypos); - - WDL_VirtualIconButton_SkinConfig *m_iconCfg; - int m_bgcol1_msg; - int m_margin_r, m_margin_l; - int m_margin_t, m_margin_b; - float m_alpha; - bool m_is_button,m_forceborder; - char m_pressed; - bool m_en, m_grayed, m_ownsicon; - bool m_immediate; - char m_textalign; - char m_checkstate; - bool m_forcetext; - int m_forcetext_color; - - WDL_String m_textlbl; - LICE_IFont *m_textfont,*m_textfontv; -}; - - - -class WDL_VirtualStaticText : public WDL_VWnd -{ - public: - WDL_VirtualStaticText(); - virtual ~WDL_VirtualStaticText(); - - virtual const char *GetType() { return "vwnd_statictext"; } - - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual bool OnMouseDblClick(int xpos, int ypos); - virtual int OnMouseDown(int xpos, int ypos); - - virtual void GetPositionPaintExtent(RECT *r); // override in case m_bkbm has outer areas - - void SetWantSingleClick(bool ws) {m_wantsingle=ws; } - void SetFont(LICE_IFont *font, LICE_IFont *vfont=NULL) { m_font=font; m_vfont=vfont; } - LICE_IFont *GetFont(bool vfont=false) { return vfont?m_vfont:m_font; } - void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right - void SetText(const char *text); - void SetBorder(bool bor) { m_wantborder=bor; } - const char *GetText() { return m_text.Get(); } - void SetColors(int fg=0, int bg=0, bool tint=false) { m_fg=fg; m_bg=bg; m_dotint=tint; } - void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } - void SetVMargins(int t, int b) { m_margin_t=t; m_margin_b=b; }; - void SetBkImage(WDL_VirtualWnd_BGCfg *bm) { m_bkbm=bm; } - WDL_VirtualWnd_BGCfg* GetBkImage() { return m_bkbm; } - int GetCharFromCoord(int xpos, int ypos); // for "AB", -1=out of bounds left, 0="A", 1="B", 2=out of bounds right - void SetWantPreserveTrailingNumber(bool preserve); // if the text ends in a number, make sure the number is always displayed - - protected: - WDL_VirtualWnd_BGCfg *m_bkbm; - int m_align; - bool m_dotint; - int m_fg,m_bg; - int m_margin_r, m_margin_l; - int m_margin_t, m_margin_b; - bool m_wantborder; - bool m_wantsingle; - bool m_wantabbr; - LICE_IFont *m_font,*m_vfont; - WDL_String m_text; - bool m_didvert; // true if text was drawn vertically on the last paint - int m_didalign; // the actual alignment used on the last paint -}; - -class WDL_VirtualComboBox : public WDL_VWnd -{ - public: - WDL_VirtualComboBox(); - virtual ~WDL_VirtualComboBox(); - virtual const char *GetType() { return "vwnd_combobox"; } - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual int OnMouseDown(int xpos, int ypos); - - void SetFont(LICE_IFont *font) { m_font=font; } - LICE_IFont *GetFont() { return m_font; } - void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right - - int GetCurSel() { if (m_items.Get(m_curitem)) return m_curitem; return -1; } - void SetCurSel(int sel) { if (!m_items.Get(sel)) sel=-1; if (m_curitem != sel) { m_curitem=sel; RequestRedraw(NULL); } } - - int GetCount() { return m_items.GetSize(); } - void Empty() { m_items.Empty(true,free); m_itemdatas.Empty(); } - - int AddItem(const char *str, void *data=NULL) { m_items.Add(strdup(str)); m_itemdatas.Add(data); return m_items.GetSize()-1; } - const char *GetItem(int item) { return m_items.Get(item); } - void *GetItemData(int item) { return m_itemdatas.Get(item); } - - - protected: - int m_align; - int m_curitem; - LICE_IFont *m_font; - - WDL_PtrList m_items; - WDL_PtrList m_itemdatas; -}; - - - -class WDL_VirtualSlider : public WDL_VWnd -{ - public: - WDL_VirtualSlider(); - virtual ~WDL_VirtualSlider(); - virtual const char *GetType() { return "vwnd_slider"; } - - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual int OnMouseDown(int xpos, int ypos); - virtual void OnMouseMove(int xpos, int ypos); - virtual void OnMouseUp(int xpos, int ypos); - virtual bool OnMouseDblClick(int xpos, int ypos); - virtual bool OnMouseWheel(int xpos, int ypos, int amt); - virtual void GetPositionPaintExtent(RECT *r); - - virtual void OnCaptureLost(); - - void SetBGCol1Callback(int msg) { m_bgcol1_msg=msg; } - void SetScrollMessage(int msg) { m_scrollmsg=msg; } - void SetRange(int minr, int maxr, int center) { m_minr=minr; m_maxr=maxr; m_center=center; } - void GetRange(int *minr, int *maxr, int *center) { if (minr) *minr=m_minr; if (maxr) *maxr=m_maxr; if (center) *center=m_center; } - int GetSliderPosition(); - void SetSliderPosition(int pos); - bool GetIsVert(); - void SetNotifyOnClick(bool en) { m_sendmsgonclick=en; } // default false - - void SetDblClickCallback(int msg) { m_dblclickmsg=msg; } - int GetDblClickCallback() { return m_dblclickmsg; } - - void SetGrayed(bool grayed) { m_grayed = grayed; } - - void GetButtonSize(int *w, int *h); - - void SetSkinImageInfo(WDL_VirtualSlider_SkinConfig *cfg, WDL_VirtualWnd_BGCfg *knobbg=NULL, WDL_VirtualWnd_BGCfg *knobbgsm=NULL, WDL_VirtualWnd_BGCfg *knobstacks=NULL, int nknobstacks=0) - { - m_skininfo=cfg; - m_knobbg[0]=knobbgsm; - m_knobbg[1]=knobbg; - m_knobstacks=knobstacks; - m_nknobstacks=nknobstacks; - } - - void SetFGColors(int knobcol, int zlcol) { m_knob_color=knobcol; m_zl_color = zlcol; } - void SetKnobBias(int knobbias, int knobextrasize=0) { m_knobbias=knobbias; m_knob_lineextrasize=knobextrasize; } // 1=force knob, -1=prevent knob - - protected: - WDL_VirtualSlider_SkinConfig *m_skininfo; - WDL_VirtualWnd_BGCfg *m_knobbg[2]; - WDL_VirtualWnd_BGCfg *m_knobstacks; - int m_nknobstacks; - - int m_bgcol1_msg; - int m_scrollmsg; - int m_dblclickmsg; - - void OnMoveOrUp(int xpos, int ypos, int isup); - int m_minr, m_maxr, m_center, m_pos; - - int m_tl_extra, m_br_extra; - - int m_knob_color,m_zl_color; - - signed char m_knobbias; - signed char m_knob_lineextrasize; - bool m_captured; - bool m_needflush; - bool m_sendmsgonclick; - bool m_grayed; - bool m_is_knob; -}; - - -#define WDL_VWND_LISTBOX_ARROWINDEX 0x10000000 -#define WDL_VWND_LISTBOX_ARROWINDEX_LR 0x10000001 - -class WDL_VirtualListBox : public WDL_VWnd -{ - public: - WDL_VirtualListBox(); - virtual ~WDL_VirtualListBox(); - virtual const char *GetType() { return "vwnd_listbox"; } - - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual int OnMouseDown(int xpos, int ypos); - virtual bool OnMouseDblClick(int xpos, int ypos); - virtual bool OnMouseWheel(int xpos, int ypos, int amt); - virtual void OnMouseMove(int xpos, int ypos); - virtual void OnMouseUp(int xpos, int ypos); - - void SetFont(LICE_IFont *font) { m_font=font; } - LICE_IFont *GetFont() { return m_font; } - void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right - void SetRowHeight(int rh) { m_rh=rh; } - void SetMaxColWidth(int cw) { m_maxcolwidth=cw; } // 0 = default = allow any sized columns - void SetMinColWidth(int cw) { m_mincolwidth = cw; } // 0 = default = full width columns - void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } - void SetScrollButtonSize(int sz) { m_scrollbuttonsize=sz; } // def 14 - int GetRowHeight() { return m_rh; } - int GetMaxColWidth() { return m_maxcolwidth; } - int GetMinColWidth() { return m_mincolwidth; } - - void SetDroppedMessage(int msg) { m_dropmsg=msg; } - void SetClickedMessage(int msg) { m_clickmsg=msg; } - void SetDragBeginMessage(int msg) { m_dragbeginmsg=msg; } - int IndexFromPt(int x, int y); - bool GetItemRect(int item, RECT *r); // returns FALSE if not onscreen - - void SetGrayed(bool grayed) { m_grayed=grayed; } - - void SetViewOffset(int offs); - int GetViewOffset(); - - RECT *GetScrollButtonRect(bool isDown) { return m_lastscrollbuttons[isDown?1:0].left - -#include -#if !defined(_MSC_VER) || _MSC_VER < 1600 -#include -#else -#include -#endif - - -#include "virtwnd-controls.h" -#include "../wdltypes.h" -#include "../wdlcstring.h" - -static BSTR SysAllocStringUTF8(const char *str) -{ - WCHAR tmp[1024]; - int slen = strlen(str)+1; - WCHAR *wstr = slen < 1000 ? tmp : (WCHAR*)malloc(2*slen+32); - - wstr[0]=0; - int a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,slen,wstr, slen<1000?1024:slen+16); - if (!a) - { - wstr[0]=0; - a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,str,slen,wstr,slen<1000?1024:slen+16); - } - - BSTR ret = SysAllocString(wstr); - if (wstr != tmp) free(wstr); - return ret; -} - -class CVWndAccessible; -class VWndBridge : public WDL_VWnd_IAccessibleBridge -{ -public: - VWndBridge() { } - ~VWndBridge() { } - virtual void Release() { vwnd=0; } - - CVWndAccessible *par; - WDL_VWnd *vwnd; - -}; -static IAccessible *GetVWndIAccessible(WDL_VWnd *vwnd); - -static int g_freelist_acc_size; -static CVWndAccessible *g_freelist_acc; - -static HRESULT (WINAPI *__CreateStdAccessibleObject)( - HWND hwnd, - LONG idObject, - REFIID riidInterface, - void **ppvObject -); - - -static int allocated_cnt; -class CVWndAccessible : public IAccessible -{ -public: - CVWndAccessible(WDL_VWnd *vwnd) - { - m_br.vwnd=vwnd; - m_br.par = this; - m_refCnt = 1; - allocated_cnt++; - } - ~CVWndAccessible() - { - allocated_cnt--; - //char buf[512]; - //sprintf(buf,"allocated total = %d\n",allocated_cnt); - // OutputDebugString(buf); - } - - //IUnknown interface - STDMETHOD_(HRESULT, QueryInterface)(REFIID riid , void **ppObj) - { - if (IsEqualIID(riid, IID_IUnknown)) - { - *ppObj = this; - } - else if (IsEqualIID(riid, IID_IAccessible)) - { - *ppObj = this; - } - else if (IsEqualIID(riid, IID_IDispatch)) - { - *ppObj = this; - } - else - { - *ppObj = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; - } - STDMETHOD_(ULONG, AddRef)() - { - return InterlockedIncrement(&m_refCnt); - } - STDMETHOD_(ULONG, Release)() - { - LONG nRefCount=0; - nRefCount=InterlockedDecrement(&m_refCnt) ; - if (nRefCount == 0) - { - if (m_br.vwnd) - { - m_br.vwnd->SetAccessibilityBridge(NULL); - m_br.vwnd=0; - } - - if (g_freelist_acc_size<2048) - { - g_freelist_acc_size++; - _freelist_next = g_freelist_acc; - g_freelist_acc = this; - } - else - { - delete this; - } - } - return nRefCount; - } - - - //IDispatch - STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo ) - { - *pctinfo=0; - return NOERROR; - } - STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) - { - return S_OK; - } - STDMETHOD( GetIDsOfNames)( - REFIID riid, - OLECHAR FAR* FAR* rgszNames, - unsigned int cNames, - LCID lcid, - DISPID FAR* rgDispId - ) - { - *rgDispId=0; - return E_OUTOFMEMORY; - } - - STDMETHOD(Invoke)( - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS FAR* pDispParams, - VARIANT FAR* pVarResult, - EXCEPINFO FAR* pExcepInfo, - unsigned int FAR* puArgErr - ) - { - return DISP_E_BADPARAMCOUNT; - } - - // IAccessible - - - STDMETHOD(get_accParent)(THIS_ IDispatch * FAR* ppdispParent) - { - WDL_VWnd *par=m_br.vwnd ? m_br.vwnd->GetParent() : NULL; - if (par) - { - *ppdispParent = GetVWndIAccessible(par); - if (*ppdispParent) return S_OK; - } - - *ppdispParent = NULL; - return S_FALSE; - } -#define ISVWNDLIST(x) ((x)&&!strcmp((x)->GetType(),"vwnd_listbox")) - STDMETHOD(get_accChildCount)(THIS_ long FAR* pChildCount) - { - *pChildCount = m_br.vwnd ? m_br.vwnd->GetNumChildren() : 0; - HWND realparent; - if (__CreateStdAccessibleObject && m_br.vwnd && !m_br.vwnd->GetParent() && (realparent=m_br.vwnd->GetRealParent())) - { - HWND h=GetWindow(realparent,GW_CHILD); - while (h) - { - (*pChildCount) += 1; - h=GetWindow(h,GW_HWNDNEXT); - } - } - - if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - int c = 0; - if (list->m_GetItemInfo) c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if(c<0)c=0; - *pChildCount += c+2; - } - return S_OK; - } - STDMETHOD(get_accChild)(THIS_ VARIANT varChildIndex, IDispatch * FAR* ppdispChild) - { - *ppdispChild=0; - if (!m_br.vwnd || varChildIndex.vt != VT_I4) return E_INVALIDARG; - - WDL_VWnd *vw = m_br.vwnd->EnumChildren(varChildIndex.lVal-1); - if (vw) - { - *ppdispChild=GetVWndIAccessible(vw); - if (*ppdispChild) return S_OK; - } - - int index = varChildIndex.lVal-1 - m_br.vwnd->GetNumChildren(); - - if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - int c = 0; - if (list->m_GetItemInfo) c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if(c<0)c=0; - index -= c+2; - } - - - HWND realparent; - if (index >= 0 && __CreateStdAccessibleObject && m_br.vwnd && !m_br.vwnd->GetParent() && (realparent=m_br.vwnd->GetRealParent())) - { - HWND h=GetWindow(realparent,GW_CHILD); - while (h) - { - if (!index) break; - index--; - h=GetWindow(h,GW_HWNDNEXT); - } - - if (h) - { - *ppdispChild=0; - HRESULT res = __CreateStdAccessibleObject(h,OBJID_CLIENT,IID_IAccessible,(void**)ppdispChild); - if (SUCCEEDED(res)) - { - return S_OK; - } - - } - } - - - return S_FALSE; - } - - STDMETHOD(get_accName)(THIS_ VARIANT varChild, BSTR* pszOut) - { - *pszOut=NULL; - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (vw) - { - const char *txt=NULL; - const char *ctltype = vw->GetType(); - if (!strcmp(ctltype,"vwnd_iconbutton")) - txt = ((WDL_VirtualIconButton*)vw)->GetTextLabel(); - else if (!strcmp(ctltype,"vwnd_statictext")) - txt = ((WDL_VirtualStaticText*)vw)->GetText(); - else if (!strcmp(ctltype,"vwnd_combobox")) - txt = ((WDL_VirtualComboBox*)vw)->GetItem(((WDL_VirtualComboBox*)vw)->GetCurSel()); - - const char *p = vw->GetAccessDesc(); - if (p && *p && txt && *txt) - { - char buf[1024]; - sprintf(buf,"%.500s %.500s",p,txt); - *pszOut= SysAllocStringUTF8(buf); - } - else if (txt && *txt) - { - *pszOut= SysAllocStringUTF8(txt); - } - else if (p && *p) - { - *pszOut = SysAllocStringUTF8(p); - } - } - else if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); - int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - char buf[2048]; - buf[0]=0; - if (idx>=0&&idxm_GetItemInfo(list,idx,buf,512,NULL,NULL); - else if (idx==ni||idx==ni+1) - { - strcpy(buf,idx==ni?"Scroll previous" : "Scroll next"); - } - - // we put this in the desc field instead - /*const char *txt1 = list->GetAccessDesc(); - if (txt1) - { - if (buf[0]) strcat(buf," "); - lstrcpyn_safe(buf+strlen(buf),txt1,512); - }*/ - -// OutputDebugString(buf); - if (buf[0]) - *pszOut = SysAllocStringUTF8(buf); - } - } - return S_OK; - - } - STDMETHOD(get_accValue)(THIS_ VARIANT varChild, BSTR* pszValue) - { - *pszValue=NULL; - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - return DISP_E_MEMBERNOTFOUND; - } - STDMETHOD(get_accDescription)(THIS_ VARIANT varChild, BSTR FAR* pszOut) - { - *pszOut=NULL; - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - if (vw) - { - char buf[1024]; - buf[0]=0; - WDL_VWnd *p = vw->GetParent(); - if (0) // disabled for now - while (p && strlen(buf)<800) - { - const char *txt= p->GetAccessDesc(); - if (txt && *txt) - { - if (buf[0]) strcat(buf," "); - lstrcpyn_safe(buf+strlen(buf),txt,200); - } - p=p->GetParent(); - } - if (buf[0]) - { - *pszOut = SysAllocStringUTF8(buf); - return S_OK; - } - return S_FALSE; - } - else if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - const char *txt = list->GetAccessDesc(); - if (txt) - { - *pszOut = SysAllocStringUTF8(txt); - return S_OK; - } - } - } - return E_INVALIDARG; - } - - STDMETHOD(get_accRole)(THIS_ VARIANT varChild, VARIANT *pvarRole) - { - if (!m_br.vwnd || varChild.vt != VT_I4) - { - pvarRole->vt = VT_EMPTY; - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw && ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); - int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if (idx>=0&&idxvt = VT_I4; - pvarRole->lVal = ROLE_SYSTEM_LISTITEM; - return S_OK; - } - else if (idx==ni || idx==ni+1) - { - pvarRole->vt = VT_I4; - pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON; - return S_OK; - } - } - } - - if (!vw) - { - pvarRole->vt = VT_EMPTY; - return E_INVALIDARG; - } - - pvarRole->vt = VT_I4; - if (vw->GetNumChildren()) pvarRole->lVal = ROLE_SYSTEM_GROUPING; - else - { - - const char *type = vw->GetType(); - - if (!strcmp(type,"vwnd_iconbutton")) - { - WDL_VirtualIconButton *vb = (WDL_VirtualIconButton*)vw; - if (vb->GetIsButton()) - { - if (vb->GetCheckState()>=0) pvarRole->lVal = ROLE_SYSTEM_CHECKBUTTON; - else pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON; - } - else - pvarRole->lVal = ROLE_SYSTEM_STATICTEXT; - } - else if (!strcmp(type,"vwnd_statictext")) pvarRole->lVal = ROLE_SYSTEM_STATICTEXT; - else if (!strcmp(type,"vwnd_combobox")) pvarRole->lVal = ROLE_SYSTEM_COMBOBOX; - else if (!strcmp(type,"vwnd_slider")) pvarRole->lVal = ROLE_SYSTEM_SLIDER; - else if (!strcmp(type,"vwnd_listbox")) pvarRole->lVal = ROLE_SYSTEM_LIST; - else pvarRole->lVal=ROLE_SYSTEM_CLIENT; - } - - return S_OK; - } - - STDMETHOD(get_accState)(THIS_ VARIANT varChild, VARIANT *pvarState) - { - if (!m_br.vwnd || varChild.vt != VT_I4) - { - pvarState->vt = VT_EMPTY; - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw) - { - if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - int index = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); - int c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if (index>=0&&indexvt = VT_I4; - pvarState->lVal = 0; - RECT r; - if (list->GetItemRect(index,&r)) - { - } - else - pvarState->lVal|=STATE_SYSTEM_INVISIBLE; - - return S_OK; - } - else if (index==c||index==c+1) - { - pvarState->vt = VT_I4; - pvarState->lVal = 0; - if (!list->GetScrollButtonRect(index==c+1)) - pvarState->lVal |= STATE_SYSTEM_UNAVAILABLE; - return S_OK; - - } - } - } - - pvarState->vt = VT_EMPTY; - return E_INVALIDARG; - } - - const char *type = vw->GetType(); - pvarState->vt = VT_I4; - pvarState->lVal = 0; - if (!vw->IsVisible()) pvarState->lVal |= STATE_SYSTEM_INVISIBLE; - - if (!strcmp(type,"vwnd_iconbutton")) - { - WDL_VirtualIconButton *vb = (WDL_VirtualIconButton*)vw; - if (vb->GetIsButton()) - { - if (vb->GetCheckState()>0) pvarState->lVal |= STATE_SYSTEM_CHECKED; - } - } - - return S_OK; - } - STDMETHOD(get_accHelp)(THIS_ VARIANT varChild, BSTR* pszHelp) - { - *pszHelp=NULL; - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw) - { - return E_INVALIDARG; - } - return S_FALSE; - } - STDMETHOD(get_accHelpTopic)(THIS_ BSTR* pszHelpFile, VARIANT varChild, long* pidTopic) - { - return DISP_E_MEMBERNOTFOUND; - } - STDMETHOD(get_accKeyboardShortcut)(THIS_ VARIANT varChild, BSTR* pszKeyboardShortcut) - { - *pszKeyboardShortcut=NULL; - - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw) - { - return E_INVALIDARG; - } - return S_FALSE; - } - STDMETHOD(get_accFocus)(THIS_ VARIANT FAR * pvarFocusChild) - { - pvarFocusChild->vt= VT_EMPTY; - if (!m_br.vwnd) - { - return S_FALSE; - } - //return DISP_E_MEMBERNOTFOUND; - - if (!m_br.vwnd->GetParent() && - m_br.vwnd->GetRealParent() && - GetFocus()==m_br.vwnd->GetRealParent()) - { - pvarFocusChild->vt=VT_I4; - pvarFocusChild->lVal = CHILDID_SELF; - } - return S_OK; - } - STDMETHOD(get_accSelection)(THIS_ VARIANT FAR * pvarSelectedChildren) - { - pvarSelectedChildren->vt= VT_EMPTY; - if (!m_br.vwnd) - { - return S_FALSE; - } - return S_OK; - } - STDMETHOD(get_accDefaultAction)(THIS_ VARIANT varChild, BSTR* pszDefaultAction) - { - *pszDefaultAction=NULL; - - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw) - { - return E_INVALIDARG; - } - return S_FALSE; - } - - STDMETHOD(accSelect)(THIS_ long flagsSelect, VARIANT varChild) - { - return S_FALSE; - } - STDMETHOD(accLocation)(THIS_ long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild) - { - *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; - if (!m_br.vwnd || varChild.vt != VT_I4) - { - return E_INVALIDARG; - } - WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); - - if (!vw && ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); - int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if (idx>=0&&idxGetItemRect(idx,&r2)) - { - HWND h = list->GetRealParent(); - RECT r; - list->GetPositionInTopVWnd(&r); - ClientToScreen(h,(LPPOINT)&r); - ClientToScreen(h,((LPPOINT)&r)+1); - *pxLeft=r.left+r2.left; - *pyTop=r.top+r2.top; - *pcxWidth=r2.right-r2.left; - *pcyHeight=r2.bottom-r2.top; - } - else *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; - return S_OK; - } - else if (idx==ni||idx==ni+1) - { - RECT *rr = list->GetScrollButtonRect(idx==ni+1); - if (rr) - { - HWND h = list->GetRealParent(); - RECT r; - list->GetPositionInTopVWnd(&r); - ClientToScreen(h,(LPPOINT)&r); - ClientToScreen(h,((LPPOINT)&r)+1); - *pxLeft=r.left+rr->left; - *pyTop=r.top+rr->top; - *pcxWidth=rr->right-rr->left; - *pcyHeight=rr->bottom-rr->top; - } - else *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; - return S_OK; - - } - } - } - if (!vw) return E_INVALIDARG; - - HWND h = vw->GetRealParent(); - if (h) - { - RECT r; - vw->GetPositionInTopVWnd(&r); - ClientToScreen(h,(LPPOINT)&r); - ClientToScreen(h,((LPPOINT)&r)+1); - *pxLeft=r.left; - *pyTop=r.top; - *pcxWidth=r.right-r.left; - *pcyHeight=r.bottom-r.top; - } - return S_OK; - } - - STDMETHOD(accNavigate)(THIS_ long navDir, VARIANT varStart, VARIANT * pvarEndUpAt) - { - return DISP_E_MEMBERNOTFOUND; - } - STDMETHOD(accHitTest)(THIS_ long xLeft, long yTop, VARIANT * pvarChildAtPoint) - { - pvarChildAtPoint->vt = VT_EMPTY; - - if (!m_br.vwnd) - { - return E_INVALIDARG; - } - - HWND h = m_br.vwnd->GetRealParent(); - if (!h) return S_FALSE; - - POINT p={xLeft,yTop}; - ScreenToClient(h,&p); - if (!m_br.vwnd->GetParent() && __CreateStdAccessibleObject) - { - HWND hhit = ChildWindowFromPoint(h,p); - if (hhit && hhit != h) - { - pvarChildAtPoint->pdispVal=0; - HRESULT res = __CreateStdAccessibleObject(hhit,OBJID_CLIENT,IID_IAccessible,(void**)&pvarChildAtPoint->pdispVal); - if (SUCCEEDED(res)) - { - pvarChildAtPoint->vt = VT_DISPATCH; - return S_OK; - } - } - } - - RECT r; - m_br.vwnd->GetPositionInTopVWnd(&r); - if (!PtInRect(&r,p)) return S_FALSE; - - WDL_VWnd *vw = m_br.vwnd->VirtWndFromPoint(p.x-r.left,p.y-r.top,0); - if (vw&&vw != m_br.vwnd) - { - IAccessible *pac = GetVWndIAccessible(vw); - if (pac) - { - pvarChildAtPoint->vt = VT_DISPATCH; - pvarChildAtPoint->pdispVal = pac; - return S_OK; - } - } - else if (ISVWNDLIST(m_br.vwnd)) - { - WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; - if (list->m_GetItemInfo) - { - int c = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); - if (c<0)c=0; - int a= list->IndexFromPt(p.x-r.left,p.y-r.top); - if (a>=0 && avt = VT_I4; - pvarChildAtPoint->lVal = 1+list->GetNumChildren()+a;; - return S_OK; - } - else - { - POINT pp = { p.x-r.left, p.y-r.top}; - int x; - for(x=0;x<2;x++) - { - RECT *rr = list->GetScrollButtonRect(!!x); - if (rr && PtInRect(rr,pp)) - { - pvarChildAtPoint->vt = VT_I4; - pvarChildAtPoint->lVal = 1+list->GetNumChildren()+c+x;; - return S_OK; - } - } - } - } - } - - pvarChildAtPoint->vt = VT_I4; - pvarChildAtPoint->lVal = CHILDID_SELF; - return S_OK; - } - STDMETHOD(accDoDefaultAction)(THIS_ VARIANT varChild) - { - return DISP_E_MEMBERNOTFOUND; - } - - STDMETHOD(put_accName)(THIS_ VARIANT varChild, BSTR szName) - { - return E_NOTIMPL; - } - - STDMETHOD(put_accValue)(THIS_ VARIANT varChild, BSTR pszValue) - { - return E_NOTIMPL; - } - - VWndBridge m_br; - LONG m_refCnt; - - CVWndAccessible *_freelist_next; - -}; - - -static IAccessible *GetVWndIAccessible(WDL_VWnd *vwnd) -{ - if (!vwnd) return 0; - - WDL_VWnd_IAccessibleBridge *br = vwnd->GetAccessibilityBridge(); - if (!br) - { - CVWndAccessible *acc; - if (g_freelist_acc) - { - g_freelist_acc_size--; - acc=g_freelist_acc; - g_freelist_acc=acc->_freelist_next; - - acc->m_br.vwnd = vwnd; - acc->m_refCnt = 1; - } - else - acc = new CVWndAccessible(vwnd); - - br = &acc->m_br; - vwnd->SetAccessibilityBridge(br); - } - else ((VWndBridge*)br)->par->AddRef(); - - return ((VWndBridge*)br)->par; -} - - -LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) -{ - if (vw) - { - if ((DWORD)lParam != (DWORD)OBJID_CLIENT) return 0; - - static LRESULT (WINAPI *__LresultFromObject)(REFIID riid, WPARAM, LPUNKNOWN); - - static int init; - if (!init) - { - init=1; - HINSTANCE hInst = LoadLibrary("oleacc.dll"); - if (hInst) - { - *(FARPROC *)&__LresultFromObject = GetProcAddress(hInst,"LresultFromObject"); - *(FARPROC *)&__CreateStdAccessibleObject = GetProcAddress(hInst,"CreateStdAccessibleObject"); - } - } - if (!__LresultFromObject) return 0; - - IAccessible *ac = GetVWndIAccessible(vw); - if (!ac) return 0; - - - LRESULT res = __LresultFromObject(IID_IAccessible,wParam,ac); // lresultfromobject retains? - ac->Release(); - if (isDialog) - { - SetWindowLongPtr(hwnd,DWLP_MSGRESULT,res); - return 1; - } - return res; - } - return 0; -} - - -#else - -#ifdef _WIN32 -#include -#else -#include "../swell/swell.h" -#endif - - -#ifdef __APPLE__ - -// see virtwnd-nsaccessibility.mm - -#else - - -class WDL_VWnd; -LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) -{ - return 0; -} - -#endif - -#endif diff --git a/WDL/wingui/virtwnd-iconbutton.cpp b/WDL/wingui/virtwnd-iconbutton.cpp deleted file mode 100644 index 7ff8b636..00000000 --- a/WDL/wingui/virtwnd-iconbutton.cpp +++ /dev/null @@ -1,1118 +0,0 @@ -/* - WDL - virtwnd-iconbutton.cpp - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Implementation for virtual window icon buttons, icons, combo boxes, and static text controls. - -*/ - -#include -#include "virtwnd-controls.h" -#include "../lice/lice.h" - -#ifdef _WIN32 -#define WDL_WIN32_UTF8_IMPL static -#include "../win32_utf8.c" -#endif - -WDL_VirtualIconButton::WDL_VirtualIconButton() -{ - m_alpha=1.0; - m_checkstate=-1; - m_textfont=0; - m_textfontv=0; - m_textalign=0; - m_bgcol1_msg=0; - m_is_button=true; - m_pressed=0; - m_iconCfg=0; - m_en=true; - m_grayed = false; - m_forceborder=false; - m_forcetext=false; - m_forcetext_color=0; - m_ownsicon=false; - m_immediate=false; - m_margin_r = m_margin_l = 0; - m_margin_t = m_margin_b = 0; -} - -WDL_VirtualIconButton::~WDL_VirtualIconButton() -{ - if (m_ownsicon && m_iconCfg) - { - delete m_iconCfg->image; - delete m_iconCfg->olimage; - delete m_iconCfg; - } -} - -void WDL_VirtualIconButton::SetTextLabel(const char *text) -{ - m_textlbl.Set(text); - if (!m_iconCfg || m_forcetext) RequestRedraw(NULL); -} - -void WDL_VirtualIconButton::SetTextLabel(const char *text, int align, LICE_IFont *font) -{ - if (font) m_textfont=font; - m_textalign=align; - m_textlbl.Set(text); - if (!m_iconCfg || m_forcetext) RequestRedraw(NULL); -} - -void WDL_VirtualIconButton::SetCheckState(char state) -{ - if (state != m_checkstate) - { - m_checkstate=state; - RequestRedraw(NULL); - } -} - -void WDL_VirtualIconButton::SetIcon(WDL_VirtualIconButton_SkinConfig *cfg, float alpha, bool buttonownsicon) -{ - if (m_iconCfg != cfg || m_alpha != alpha) - { - bool combineRects=false; - RECT r; - if (m_iconCfg && m_iconCfg != cfg && m_iconCfg->olimage) - { - combineRects=true; - GetPositionPaintExtent(&r); - if (WantsPaintOver()) - { - RECT r3; - GetPositionPaintOverExtent(&r3); - if (r3.leftr.right) r.right=r3.right; - if (r3.bottom>r.bottom) r.bottom=r3.bottom; - } - } - if (m_ownsicon && m_iconCfg && m_iconCfg != cfg) - { - delete m_iconCfg->image; - delete m_iconCfg->olimage; - delete m_iconCfg; - } - m_alpha=alpha; - m_iconCfg=cfg; - - if (combineRects) - { - RECT r3; - GetPositionPaintExtent(&r3); - if (r3.leftr.right) r.right=r3.right; - if (r3.bottom>r.bottom) r.bottom=r3.bottom; - - if (WantsPaintOver()) - { - GetPositionPaintOverExtent(&r3); - if (r3.leftr.right) r.right=r3.right; - if (r3.bottom>r.bottom) r.bottom=r3.bottom; - } - - r.left -= m_position.left; - r.right -= m_position.left; - r.top -= m_position.top; - r.bottom -= m_position.top; - RequestRedraw(&r); - } - else - { - RequestRedraw(NULL); - } - } - m_ownsicon = buttonownsicon; - } - -void WDL_VirtualIconButton::OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - if (m_iconCfg && m_iconCfg->olimage) - { - int sx=0; - int sy=0; - int w=m_iconCfg->olimage->getWidth(); - int h=m_iconCfg->olimage->getHeight(); - if (m_iconCfg->image_ltrb_used.flags&1) { w-=2; h-= 2; sx++,sy++; } - - w/=3; - - if (w>0 && h>0) - { - if (m_is_button) - { - if ((m_pressed&2)) sx+=(m_pressed&1) ? w*2 : w; - } - - if (m_iconCfg->image_ltrb_used.flags&2) // use main image's stretch areas (outer areas become unstretched) - { - WDL_VirtualWnd_BGCfg cfg={0,}; - LICE_SubBitmap sb(m_iconCfg->olimage,sx,sy,w,h); - cfg.bgimage = &sb; - cfg.bgimage_lt[0] = m_iconCfg->image_ltrb_main[0]+1; // image_ltrb_main expects 1-based number - cfg.bgimage_lt[1] = m_iconCfg->image_ltrb_main[1]+1; - cfg.bgimage_rb[0] = m_iconCfg->image_ltrb_main[2]+1; - cfg.bgimage_rb[1] = m_iconCfg->image_ltrb_main[3]+1; - cfg.bgimage_lt_out[0] = m_iconCfg->image_ltrb_ol[0]+1; - cfg.bgimage_lt_out[1] = m_iconCfg->image_ltrb_ol[1]+1; - cfg.bgimage_rb_out[0] = m_iconCfg->image_ltrb_ol[2]+1; - cfg.bgimage_rb_out[1] = m_iconCfg->image_ltrb_ol[3]+1; - cfg.bgimage_noalphaflags=0; - - RECT r=m_position,r2; - GetPositionPaintOverExtent(&r2); - WDL_VirtualWnd_ScaledBlitBG(drawbm,&cfg, - r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, - r2.left+origin_x,r2.top+origin_y,r2.right-r2.left,r2.bottom-r2.top, - m_alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - } - else - { - RECT r; - GetPositionPaintOverExtent(&r); - LICE_ScaledBlit(drawbm,m_iconCfg->olimage,r.left+origin_x,r.top+origin_y, - r.right-r.left, - r.bottom-r.top, - (float)sx,(float)sy,(float)w,(float)h, m_alpha, // m_grayed? - LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - } - } - } -} - - -void WDL_VirtualIconButton::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - HDC hdc=drawbm->getDC(); - int col; - - float alpha = (m_grayed ? 0.25f : 1.0f) * m_alpha; - - bool isdown = !!(m_pressed&1); - bool ishover = !!(m_pressed&2); - - if (m_iconCfg && m_iconCfg->image && !m_iconCfg->image_issingle) - { - bool swapupdown = (m_checkstate > 0); - bool isdownimg = (swapupdown != isdown); - - RECT r=m_position; - - int sx=0; - int sy=0; - int w=m_iconCfg->image->getWidth(); - int h=m_iconCfg->image->getHeight(); - - if (w>0 && (m_iconCfg->image_ltrb_used.flags&2)) - w-=2; - - w/=3; - if (w>0 && h > 0) - { - if (m_is_button) - { - if (isdownimg) sx += w*2; - else if (ishover) sx += w; - } - - - if (m_iconCfg->image_ltrb_used.flags&2) - { - WDL_VirtualWnd_BGCfg cfg={0,}; - LICE_SubBitmap sb(m_iconCfg->image,sx+1,sy+1,w,h-2); - cfg.bgimage = &sb; - cfg.bgimage_lt[0] = m_iconCfg->image_ltrb_main[0]+1; // image_ltrb_main expects 1-based number - cfg.bgimage_lt[1] = m_iconCfg->image_ltrb_main[1]+1; - cfg.bgimage_rb[0] = m_iconCfg->image_ltrb_main[2]+1; - cfg.bgimage_rb[1] = m_iconCfg->image_ltrb_main[3]+1; - cfg.bgimage_noalphaflags=0; - - WDL_VirtualWnd_ScaledBlitBG(drawbm,&cfg, - r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, - r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, - alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - - } - else - LICE_ScaledBlit(drawbm,m_iconCfg->image,r.left+origin_x,r.top+origin_y, - r.right-r.left, - r.bottom-r.top, - (float)sx,(float)sy,(float)w,(float)h, alpha, - LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - } - } - else - { - RECT r=m_position; - r.left+=origin_x; - r.right+=origin_x; - r.top+=origin_y; - r.bottom+=origin_y; - if (m_is_button) - { - if (WDL_STYLE_WantGlobalButtonBackground(&col)) - { - LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,LICE_RGBA_FROMNATIVE(col,255),alpha,LICE_BLIT_MODE_COPY); - } - - if (ishover || m_forceborder || WDL_STYLE_WantGlobalButtonBorders()) - { - int cidx=isdown?COLOR_3DSHADOW:COLOR_3DHILIGHT; - - int pencol = GSC(cidx); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - - LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); - cidx = isdown?COLOR_3DHILIGHT:COLOR_3DSHADOW; - pencol = GSC(cidx); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); - } - } - if (m_iconCfg && m_iconCfg->image) - { - int sz=16,sz2=16; - WDL_STYLE_ScaleImageCoords(&sz,&sz2); - - //if (m_position.right-m_position.left > 24) sz=m_position.right-m_position.left-8; - - int x=r.left+((r.right-r.left)-sz)/2; - int y=r.top+((r.bottom-r.top)-sz2)/2; - if (m_is_button) - { - if (isdown && ishover) { x++; y++; } - } - - LICE_ScaledBlit(drawbm,m_iconCfg->image,x,y,sz,sz2,0.0f,0.0f, - (float)m_iconCfg->image->getWidth(), - (float)m_iconCfg->image->getHeight(),alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - - } - } - - if (!m_iconCfg || m_forcetext) - { - RECT r2=m_position; - r2.left+=origin_x; - r2.right+=origin_x; - r2.top+=origin_y; - r2.bottom+=origin_y; - - if (m_checkstate>=0 && !m_iconCfg) - { - RECT tr=r2; - int sz=tr.bottom-tr.top; - r2.left+=sz+2; - - tr.top+=2; - tr.bottom-=2; - sz-=4; - sz&=~1; - LICE_FillRect(drawbm ,tr.left,tr.top,sz,sz,LICE_RGBA(255,255,255,255),alpha,LICE_BLIT_MODE_COPY); - LICE_Line(drawbm,tr.left,tr.top,tr.left+sz,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,tr.left+sz,tr.top,tr.left+sz,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,tr.left+sz,tr.bottom,tr.left,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,tr.left,tr.bottom,tr.left,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); - int nl = (m_checkstate>0) ? 3:0; - if (isdown) nl ^= 2; - - if (nl&1) - LICE_Line(drawbm,tr.left+2,tr.bottom-2,tr.left+sz-2,tr.top+2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); - if (nl&2) - LICE_Line(drawbm,tr.left+2,tr.top+2,tr.left+sz-2,tr.bottom-2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); - - - } - - LICE_IFont *font = m_textfont; - bool isVert=false; - if (font && m_textfontv && m_position.right-m_position.left < m_position.bottom - m_position.top) - { - isVert=true; - font = m_textfontv; - } - // draw text - if (font&&m_textlbl.Get()[0]) - { - int fgc=m_forcetext_color ? m_forcetext_color : LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); - //font->SetCombineMode(LICE_BLIT_MODE_COPY, alpha); // this affects the glyphs that get cached - font->SetBkMode(TRANSPARENT); - font->SetTextColor(fgc); - - r2.left += m_margin_l; - r2.right -= m_margin_r; - r2.top += m_margin_t; - r2.bottom -= m_margin_b; - - if (isdown) - { - if (m_textalign<0) r2.left+=1; - else if (m_textalign>0) r2.right+=1; - else r2.left+=2; - r2.top+=2; - } - int f = DT_SINGLELINE|DT_NOPREFIX; - if (isVert) - { - f |= DT_CENTER | (m_textalign<0?DT_TOP:m_textalign>0?DT_BOTTOM:DT_VCENTER); - } - else - { - f |= DT_VCENTER|(m_textalign<0?DT_LEFT:m_textalign>0?DT_RIGHT:DT_CENTER); - } - font->DrawText(drawbm,m_textlbl.Get(),-1,&r2,f); - } - - } - - if (m_bgcol1_msg) - { - int brcol=-100; - SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); - if (brcol != -100) - { - RECT r=m_position; - - int bh=(r.bottom-r.top)/5; - if (bh<1) bh=1; - int bw=(r.right-r.left)/5; - if (bw<1) bw=1; - - LICE_FillRect(drawbm, - r.left+origin_x,r.top+origin_y, - r.right-r.left, - bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); - - LICE_FillRect(drawbm, - r.left+origin_x,r.top+origin_y+bh, - bw, - r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); - - LICE_FillRect(drawbm, - r.right+origin_x-bw,r.top+origin_y+bh, - bw, - r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); - - LICE_FillRect(drawbm, - r.left+origin_x,r.bottom+origin_y-bh, - r.right-r.left, - bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); - } - } - -} - - -void WDL_VirtualIconButton::OnMouseMove(int xpos, int ypos) -{ - if (m_en&&m_is_button) - { - int wp=m_pressed; - - WDL_VWnd *parhit = GetParent(); - if (parhit) - { - parhit = parhit->VirtWndFromPoint(m_position.left+xpos,m_position.top+ypos,0); - } - - if (parhit == this) - { - m_pressed|=2; - } - else - { - m_pressed&=~2; - } - - if ((m_pressed&3)!=(wp&3)) - { - RequestRedraw(NULL); - } - } -} - -int WDL_VirtualIconButton::OnMouseDown(int xpos, int ypos) -{ - if (m_en&&m_is_button) - { - m_pressed=3; - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnFocused(); - - if (m_immediate) - { - DoSendCommand(xpos, ypos); - } - - return 1; - } - return 0; -} - -bool WDL_VirtualIconButton::OnMouseDblClick(int xpos, int ypos) -{ - if (m_is_button) - { - DoSendCommand(xpos, ypos); - return true; - } - return false; -} - -void WDL_VirtualIconButton::OnMouseUp(int xpos, int ypos) -{ - if (!m_is_button) return; - - int waspress=!!m_pressed; - m_pressed&=~1; - RequestRedraw(NULL); - - if (waspress && !m_immediate) - { - DoSendCommand(xpos, ypos); - } -} - -void WDL_VirtualIconButton::DoSendCommand(int xpos, int ypos) -{ - if (m_en && - xpos >= 0 && - xpos < m_position.right-m_position.left && - ypos >= 0 && - ypos < m_position.bottom-m_position.top) - { - int code=GetID(); - if (!m_iconCfg && m_textlbl.Get()[0] && m_checkstate >= 0) - { - if (xpos < m_position.bottom-m_position.top) - { - code|=600<<16; - } - } - WDL_VWND_DCHK(a); - SendCommand(WM_COMMAND,code,0,this); - if (a.isOK() && m__iaccess && m_checkstate>=0) m__iaccess->OnStateChange(); - } -} - - -WDL_VirtualComboBox::WDL_VirtualComboBox() -{ - m_font=0; - m_align=-1; - m_curitem=-1; -} - -WDL_VirtualComboBox::~WDL_VirtualComboBox() -{ - m_items.Empty(true,free); -} - - -static void GenSubMenu(HMENU menu, int *x, WDL_PtrList *items, int curitem) -{ - int pos=0; - while (*x < items->GetSize()) - { - MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, 0,1000+*x,NULL,NULL,NULL,0}; - mi.dwTypeData = (char *)items->Get(*x); - mi.fState = curitem == *x ?MFS_CHECKED:0; - - (*x) ++; // advance to next item - - if (!strcmp(mi.dwTypeData,"")) mi.fType=MFT_SEPARATOR; - else if (!strcmp(mi.dwTypeData,"")) break; // done! - else if (!strncmp(mi.dwTypeData,"",5)) - { - mi.hSubMenu= CreatePopupMenu(); - GenSubMenu(mi.hSubMenu,x,items,curitem); - mi.fMask |= MIIM_SUBMENU; - mi.dwTypeData += 5; // skip - } - InsertMenuItem(menu,pos++,TRUE,&mi); - } -} - -int WDL_VirtualComboBox::OnMouseDown(int xpos, int ypos) -{ - if (m__iaccess) m__iaccess->OnFocused(); - if (m_items.GetSize()) - { - //SendCommand(WM_COMMAND, GetID()|(CBN_DROPDOWN<<16), 0, this); - - HMENU menu=CreatePopupMenu(); - int x=0; - GenSubMenu(menu,&x,&m_items,m_curitem); - - HWND h=GetRealParent(); - POINT p={0,}; - WDL_VirtualWnd *w=this; - while (w) - { - RECT r; - w->GetPosition(&r); - p.x+=r.left; - p.y+=w==this?r.bottom:r.top; - w=w->GetParent(); - } - if (h) - { - ClientToScreen(h,&p); - //SetFocus(h); - } - - int ret=TrackPopupMenu(menu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_NONOTIFY,p.x,p.y,0,h,NULL); - - if (ret>=1000) - { - m_curitem=ret-1000; - RequestRedraw(NULL); - // track menu - WDL_VWND_DCHK(a); - SendCommand(WM_COMMAND,GetID() | (CBN_SELCHANGE<<16),0,this); - if (a.isOK() && m__iaccess) m__iaccess->OnStateChange(); - } - } - return -1; -} - -void WDL_VirtualComboBox::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - { - if (m_font) m_font->SetBkMode(TRANSPARENT); - - RECT r=m_position; - r.left+=origin_x; - r.right+=origin_x; - r.top+=origin_y; - r.bottom+=origin_y; - - int col=GSC(COLOR_WINDOW); - col = LICE_RGBA_FROMNATIVE(col,255); - LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,col,1.0f,LICE_BLIT_MODE_COPY); - - { - RECT tr=r; - tr.left=tr.right-(tr.bottom-tr.top); - int col2=GSC(COLOR_BTNFACE); - col2 = LICE_RGBA_FROMNATIVE(col2,255); - - LICE_FillRect(drawbm,tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top,col,1.0f,LICE_BLIT_MODE_COPY); - } - - - int tcol=GSC(COLOR_BTNTEXT); - tcol=LICE_RGBA_FROMNATIVE(tcol,255); - if (m_font && m_items.Get(m_curitem)&&m_items.Get(m_curitem)[0]) - { - RECT tr=r; - tr.left+=2; - tr.right-=16; - m_font->SetTextColor(tcol); - m_font->DrawText(drawbm,m_items.Get(m_curitem),-1,&tr,DT_SINGLELINE|DT_VCENTER|(m_align<0?DT_LEFT:m_align>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); - } - - - // pen3=tcol - int pencol = GSC(COLOR_3DSHADOW); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - int pencol2 = GSC(COLOR_3DHILIGHT); - pencol2 = LICE_RGBA_FROMNATIVE(pencol2,255); - - // draw the down arrow button - { - int bs=(r.bottom-r.top); - int l=r.right-bs; - - int a=(bs/4)&~1; - - LICE_Line(drawbm,l,r.top,l,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,l-1,r.top,l-1,r.bottom-1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - - LICE_Line(drawbm,l+bs/2-a,r.top+bs/2-a/2, - l+bs/2,r.top+bs/2+a/2,tcol,1.0f,LICE_BLIT_MODE_COPY,true); - LICE_Line(drawbm,l+bs/2,r.top+bs/2+a/2, - l+bs/2+a,r.top+bs/2-a/2, tcol,1.0f,LICE_BLIT_MODE_COPY,true); - } - - - - // draw the border - LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,0,false); - LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,0,false); - LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol2,1.0f,0,false); - LICE_Line(drawbm,r.left,r.bottom-1,r.right-1,r.bottom-1,pencol2,1.0f,0,false); - - } -} - - - -WDL_VirtualStaticText::WDL_VirtualStaticText() -{ - m_dotint=false; - m_bkbm=0; - m_margin_r=m_margin_l=0; - m_margin_t=m_margin_b=0; - m_fg=m_bg=0; - m_wantborder=false; - m_vfont=m_font=0; - m_align=-1; - m_wantsingle=false; - m_didvert=0; - m_didalign=-1; - m_wantabbr=false; -} - -WDL_VirtualStaticText::~WDL_VirtualStaticText() -{ -} - -void WDL_VirtualStaticText::SetText(const char *text) -{ - if (strcmp(m_text.Get(),text)) - { - m_text.Set(text); - if (m_font) RequestRedraw(NULL); - } -} - -void WDL_VirtualStaticText::SetWantPreserveTrailingNumber(bool abbreviate) -{ - m_wantabbr=abbreviate; - if (m_font) RequestRedraw(NULL); -} - -void WDL_VirtualStaticText::GetPositionPaintExtent(RECT *r) -{ - // overridden in case m_bkbm has outer areas - *r = m_position; - if (m_bkbm && m_bkbm->bgimage) - { - if (m_bkbm->bgimage_lt[0]>0 && - m_bkbm->bgimage_lt[1]>0 && - m_bkbm->bgimage_rb[0]>0 && - m_bkbm->bgimage_rb[1]>0 && - m_bkbm->bgimage_lt_out[0]>0 && - m_bkbm->bgimage_lt_out[1]>0 && - m_bkbm->bgimage_rb_out[0]>0 && - m_bkbm->bgimage_rb_out[1]>0) - { - r->left -= m_bkbm->bgimage_lt_out[0]-1; - r->top -= m_bkbm->bgimage_lt_out[1]-1; - r->right += m_bkbm->bgimage_rb_out[0]-1; - r->bottom += m_bkbm->bgimage_rb_out[1]-1; - } - } -} - -int WDL_VirtualStaticText::OnMouseDown(int xpos, int ypos) -{ - int a = WDL_VWnd::OnMouseDown(xpos,ypos); - if (a) return a; - - if (m__iaccess) m__iaccess->OnFocused(); - - if (m_wantsingle) - { - SendCommand(WM_COMMAND,GetID() | (STN_CLICKED<<16),0,this); - return -1; - } - return 0; -} - -void WDL_VirtualStaticText::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - RECT r=m_position; - r.left+=origin_x; - r.right+=origin_x; - r.top += origin_y; - r.bottom += origin_y; - - if (m_bkbm && m_bkbm->bgimage) - { - WDL_VirtualWnd_ScaledBlitBG(drawbm,m_bkbm, - r.left,r.top,r.right-r.left,r.bottom-r.top, - r.left,r.top,r.right-r.left,r.bottom-r.top, - 1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - - if (m_dotint && LICE_GETA(m_bg)) - { - float amt = LICE_GETA(m_bg)/255.0f; - - // todo: apply amt - - float rv=LICE_GETR(m_bg)/255.0f; - float gv=LICE_GETG(m_bg)/255.0f; - float bv=LICE_GETB(m_bg)/255.0f; - - float avg=(rv+gv+bv)*0.33333f; - if (avg<0.05f)avg=0.05f; - - float sc=0.5f*amt; - float sc2 = (amt-sc)/avg; - - float sc3=32.0f * amt; - float sc4=64.0f*(avg-0.5f) * amt; - - // tint - LICE_MultiplyAddRect(drawbm, - r.left,r.top, - r.right-r.left, - r.bottom-r.top, - sc+rv*sc2 + (1.0-amt), - sc+gv*sc2 + (1.0-amt), - sc+bv*sc2 + (1.0-amt), - 1, - (rv-avg)*sc3+sc4, - (gv-avg)*sc3+sc4, - (bv-avg)*sc3+sc4, - 0); - } - } - else - { - if (LICE_GETA(m_bg)) - { - LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,m_bg,LICE_GETA(m_bg)/255.0f,LICE_BLIT_MODE_COPY); - } - - if (m_wantborder) - { - int cidx=COLOR_3DSHADOW; - - int pencol = GSC(cidx); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - - LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - cidx=COLOR_3DHILIGHT; - pencol = GSC(cidx); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - - r.left++; - r.bottom--; - r.top++; - r.right--; - - } - } - - if (m_text.Get()[0]) - { - r.left += m_margin_l; - r.right -= m_margin_r; - r.top += m_margin_t; - r.bottom -= m_margin_b; - - m_didvert=m_vfont && (r.right-r.left)<(r.bottom-r.top)/2; - LICE_IFont *font = m_didvert ? m_vfont : m_font; - - if (font) - { - font->SetBkMode(TRANSPARENT); - - m_didalign=m_align; - if (m_didalign==0) - { - RECT r2={0,0,0,0}; - font->DrawText(drawbm,m_text.Get(),-1,&r2,DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); - if (m_didvert) - { - if (r2.bottom > r.bottom-r.top) m_didalign=-1; - } - else - { - if (r2.right > r.right-r.left) m_didalign=-1; - } - } - - int dtflags=DT_SINGLELINE|DT_NOPREFIX; - - if (m_didvert) - { - dtflags |= DT_CENTER; - if (m_didalign < 0) dtflags |= DT_TOP; - else if (m_didalign > 0) dtflags |= DT_BOTTOM; - else dtflags |= DT_VCENTER; - } - else - { - dtflags|=DT_VCENTER; - - if (m_didalign < 0) dtflags |= DT_LEFT; - else if (m_didalign > 0) dtflags |= DT_RIGHT; - else dtflags |= DT_CENTER; - } - const char* txt=m_text.Get(); - - int abbrx=0; - char abbrbuf[64]; - abbrbuf[0]=0; - - if (m_wantabbr) - { - int len=strlen(txt); - if (len && isdigit(txt[len-1])) - { - RECT tr = { 0, 0, 0, 0 }; - font->DrawText(drawbm, txt, -1, &tr, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); - if (m_didvert ? (tr.bottom > r.bottom-r.top) : (tr.right > r.right-r.left)) - { - strcpy(abbrbuf, ".."); - int i; - for (i=len-1; i >= 0; --i) - { - if (!isdigit(txt[i]) || len-i > 4) break; - } - strcat(abbrbuf, txt+i+1); - - int f=dtflags&~(DT_TOP|DT_VCENTER|DT_BOTTOM|DT_LEFT|DT_CENTER|DT_RIGHT); - RECT tr2 = { 0, 0, 0, 0 }; - if (m_didvert) - { - font->DrawText(drawbm, abbrbuf, -1, &tr2, f|DT_CALCRECT); - abbrx=tr2.bottom; - } - else - { - font->DrawText(drawbm, abbrbuf, -1, &tr2, f|DT_CALCRECT); - abbrx=tr2.right; - } - } - } - } - - int tcol=m_fg ? m_fg : LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT)); - font->SetTextColor(tcol); - if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,LICE_GETA(m_fg)/255.0f); - - if (abbrx && abbrbuf[0]) - { - if (m_didvert) - { - int f=dtflags&~(DT_TOP|DT_VCENTER|DT_BOTTOM); - RECT r1 = { r.left, r.top, r.right, r.bottom-abbrx }; - font->DrawText(drawbm, txt, -1, &r1, f|DT_TOP); - RECT r2 = { r.left, r.bottom-abbrx, r.right, r.bottom }; - font->DrawText(drawbm, abbrbuf, -1, &r2, f|DT_BOTTOM); - } - else - { - int f=dtflags&~(DT_LEFT|DT_CENTER|DT_RIGHT); - RECT r1 = { r.left, r.top, r.right-abbrx, r.bottom }; - font->DrawText(drawbm, txt, -1, &r1, f|DT_LEFT); - RECT r2 = { r.right-abbrx, r.top, r.right, r.bottom }; - font->DrawText(drawbm, abbrbuf, -1, &r2, f|DT_RIGHT); - } - } - else - { - font->DrawText(drawbm,txt,-1,&r,dtflags); - } - - if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,1.0f); - } - - - } - WDL_VWnd::OnPaint(drawbm,origin_x,origin_y,cliprect); -} - - -int WDL_VirtualStaticText::GetCharFromCoord(int xpos, int ypos) -{ - LICE_IFont *font = (m_didvert ? m_vfont : m_font); - if (!font) return -1; - - const char* str = m_text.Get(); - int len = strlen(str); - if (!len) return -1; - - // for align left/right, we could DT_CALCRECT with 1 char, then 2, etc, but that won't work for align center - // so we'll just estimate - RECT tr = { 0, 0, m_position.right-m_position.left, m_position.bottom-m_position.top }; - font->DrawText(0, str, len, &tr, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); - int tw = tr.right; - int th = tr.bottom; - - RECT r = m_position; - if (m_wantborder) - { - r.left++; - r.top++; - r.right--; - r.bottom--; - } - r.left += m_margin_l; - r.top += m_margin_t; - r.right -= m_margin_r; - r.bottom -= m_margin_b; - int w = r.right-r.left; - int h = r.bottom-r.top; - - if (m_didvert) - { - r.left += (w-tw)/2; - r.right -= (w-tw)/2; - } - else - { - r.top += (h-th)/2; - r.bottom -= (h-th)/2; - } - - if (m_didalign < 0) - { - if (m_didvert) r.bottom = r.top+th; - else r.right = r.left+tw; - } - else if (m_didalign > 0) - { - if (m_didvert) r.top = r.bottom-th; - else r.left = r.right-tw; - } - else - { - if (m_didvert) - { - r.top += (h-th)/2; - r.bottom -= (h-th)/2; - } - else - { - r.left += (w-tw)/2; - r.right -= (w-tw)/2; - } - } - - int c=-1; - if (m_didvert) - { - if (ypos < r.top) c=-1; - else if (ypos > r.bottom) c=len; - else c = (int)((double)len*(double)(ypos-r.top)/(double)(r.bottom-r.top)); - } - else - { - if (xpos < r.left) c=-1; - else if (xpos > r.right) c=len; - else c = (int)((double)len*(double)(xpos-r.left)/(double)(r.right-r.left)); - } - - return c; -} - - -bool WDL_VirtualStaticText::OnMouseDblClick(int xpos, int ypos) -{ - if (!WDL_VWnd::OnMouseDblClick(xpos,ypos)) - { - SendCommand(WM_COMMAND,GetID() | (STN_DBLCLK<<16),0,this); - } - - return true; -} - - -bool WDL_VirtualIconButton::WantsPaintOver() -{ - return m_is_button && m_iconCfg && m_iconCfg->image && m_iconCfg->olimage; -} - -void WDL_VirtualIconButton::GetPositionPaintOverExtent(RECT *r) -{ - *r=m_position; - if (m_iconCfg && m_iconCfg->image && m_iconCfg->olimage && (m_iconCfg->image_ltrb_used.flags&1)) - { - if (m_iconCfg->image_ltrb_used.flags&2) // main image has pink lines, use 1:1 pixel for outer area size - { - r->left -= m_iconCfg->image_ltrb_ol[0]; - r->top -= m_iconCfg->image_ltrb_ol[1]; - r->right += m_iconCfg->image_ltrb_ol[2]; - r->bottom += m_iconCfg->image_ltrb_ol[3]; - } - else - { - int w=(m_iconCfg->olimage->getWidth()-2)/3-m_iconCfg->image_ltrb_ol[0]-m_iconCfg->image_ltrb_ol[2]; - if (w<1)w=1; - double wsc=(r->right-r->left)/(double)w; - - int h=m_iconCfg->olimage->getHeight()-2-m_iconCfg->image_ltrb_ol[1]-m_iconCfg->image_ltrb_ol[3]; - if (h<1)h=1; - double hsc=(r->bottom-r->top)/(double)h; - - r->left-=(int) (m_iconCfg->image_ltrb_ol[0]*wsc); - r->top-=(int) (m_iconCfg->image_ltrb_ol[1]*hsc); - r->right+=(int) (m_iconCfg->image_ltrb_ol[2]*wsc); - r->bottom+=(int) (m_iconCfg->image_ltrb_ol[3]*hsc); - } - } -} -void WDL_VirtualIconButton_PreprocessSkinConfig(WDL_VirtualIconButton_SkinConfig *a) -{ - if (a && a->image) - { - a->image_ltrb_used.flags=0; - int wi; - for(wi=0;wi<2;wi++) - { - LICE_IBitmap *srcimg = wi ? a->image : a->olimage; - if (!srcimg) continue; - int w=srcimg->getWidth(); - int h=srcimg->getHeight(); - - if (LICE_GetPixel(srcimg,0,0)==LICE_RGBA(255,0,255,255)&& - LICE_GetPixel(srcimg,w-1,h-1)==LICE_RGBA(255,0,255,255)) - { - int lext=0,rext=0,bext=0,text=0; - int x; - for (x = 1; x < w/3 && LICE_GetPixel(srcimg,x,0)==LICE_RGBA(255,0,255,255); x ++); - lext=x-1; - for (x = 1; x < h && LICE_GetPixel(srcimg,0,x)==LICE_RGBA(255,0,255,255); x ++); - text=x-1; - - for (x = w-2; x >= (w*2/3) && LICE_GetPixel(srcimg,x,h-1)==LICE_RGBA(255,0,255,255); x --); - rext=w-2-x; - for (x = h-2; x >= text && LICE_GetPixel(srcimg,w-1,x)==LICE_RGBA(255,0,255,255); x --); - bext=h-2-x; - if (lext||text||rext||bext) - { - a->image_ltrb_used.flags |= 1 << wi; - short *buf = wi ? a->image_ltrb_main : a->image_ltrb_ol; - buf[0]=lext; - buf[1]=text; - buf[2]=rext; - buf[3]=bext; - } - } - } - } -} diff --git a/WDL/wingui/virtwnd-listbox.cpp b/WDL/wingui/virtwnd-listbox.cpp deleted file mode 100644 index dab21b57..00000000 --- a/WDL/wingui/virtwnd-listbox.cpp +++ /dev/null @@ -1,728 +0,0 @@ -/* - WDL - virtwnd-listbox.cpp - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Implementation for virtual window listboxes. - -*/ - -#include "virtwnd-controls.h" -#include "../lice/lice.h" - -WDL_VirtualListBox::WDL_VirtualListBox() -{ - memset(m_lastscrollbuttons,0,sizeof(m_lastscrollbuttons)); - m_scrollbuttonsize=14; - m_cap_startitem=-1; - m_cap_state=0; - m_margin_l=m_margin_r=0; - m_GetItemInfo=0; - m_CustomDraw=0; - m_GetItemInfo_ctx=0; - m_viewoffs=0; - m_align=-1; - m_rh=14; - m_maxcolwidth=m_mincolwidth=0; - m_font=0; - m_clickmsg=0; - m_dropmsg=0; - m_dragbeginmsg=0; - m_grayed=false; -} - -WDL_VirtualListBox::~WDL_VirtualListBox() -{ -} - -void WDL_VirtualListBox::CalcLayout(int num_items, int *nrows, int *ncols, int *leftrightbuttonsize, int *updownbuttonsize, int *startpos, - int *usedw) -{ - *usedw = m_position.right - m_position.left; - *leftrightbuttonsize=*updownbuttonsize=0; - if (m_rh<7) m_rh=7; - - *ncols=1; - - *nrows= (m_position.bottom - m_position.top) / m_rh; - if (*nrows<1) *nrows=1; - - if (m_mincolwidth>0) - { - *ncols = (num_items+*nrows-1) / *nrows; // round up - if (*ncols<1) *ncols=1; - if ((m_position.right-m_position.left) < m_mincolwidth* *ncols) - *ncols = (m_position.right-m_position.left)/m_mincolwidth; - } - - if (m_maxcolwidth>0) - { - int oc = *ncols; - if (m_mincolwidth<=0 || (m_position.right-m_position.left) <= m_maxcolwidth * *ncols) - *ncols = (m_position.right-m_position.left) / m_maxcolwidth; // round down - } - - if (*ncols < 1) *ncols=1; - *startpos=0; - - if (num_items > *nrows * *ncols) - { - *startpos=m_viewoffs; - - if (*ncols > 1 && m_mincolwidth>0) // reduce columns to meet size requirements - { - if ((m_position.right-m_position.left - m_scrollbuttonsize*2) < m_mincolwidth* *ncols) - { - *ncols = (m_position.right-m_position.left - m_scrollbuttonsize*2)/m_mincolwidth; - if (*ncols < 1) *ncols=1; - } - } - - if (*ncols > 1) *leftrightbuttonsize = m_scrollbuttonsize; - else *updownbuttonsize = m_scrollbuttonsize; - - *nrows = (m_position.bottom - m_position.top - *updownbuttonsize) / m_rh; - if (*nrows<1) *nrows=1; - - if (m_maxcolwidth>0 && *ncols == 1 && *nrows ==1) - { - *leftrightbuttonsize = m_scrollbuttonsize; - *updownbuttonsize=0; - - *nrows = (m_position.bottom - m_position.top - *updownbuttonsize) / m_rh; - if (*nrows<1) *nrows=1; - } - - int tot=*nrows * *ncols - (*nrows-1); - if (*startpos > num_items-tot) *startpos=num_items-tot; - if (*startpos<0)*startpos=0; - - if (*ncols>1) - *startpos -= *startpos % *nrows; - } - - if (m_maxcolwidth > 0) - { - int maxw=*ncols*m_maxcolwidth + 2* *leftrightbuttonsize; - if (maxw < *usedw) *usedw=maxw; - } - -} - -static void maxSizePreservingAspect(int sw, int sh, int dw, int dh, int *outw, int *outh) -{ - *outw=dw; - *outh=dh; - if (sw < 1 || sh < 1) return; - int xwid = (sw * dh) / sh; // calculate width required if we make it dh pixels tall - if (xwid > dw) - { - // too wide, make maximum width and reduce height - *outh = (dw * sh) / sw; - } - else - { - // too narrow, use full height and reduce width - *outw = (dh * sw) / sh; - } -} - -static void DrawBkImage(LICE_IBitmap *drawbm, WDL_VirtualWnd_BGCfg *bkbm, int drawx, int drawy, int draww, int drawh, - RECT *cliprect, int drawsrcx, int drawsrcw, int bkbmstate, float alpha, int whichpass=0) -{ - bool haspink=bkbm->bgimage_lt[0]||bkbm->bgimage_lt[1]||bkbm->bgimage_rb[0] || bkbm->bgimage_rb[1]; - - if (whichpass==1) - { - int sw = (bkbm->bgimage->getWidth() - (haspink? 2 :0))/2; - int sh = (bkbm->bgimage->getHeight() - (haspink? 2 :0))/3; - - int usew,useh; - // scale drawing coords by image dimensions - maxSizePreservingAspect(sw,sh,draww,drawh,&usew,&useh); - - if (usew == sw-1 || usew == sw+1) usew=sw; - if (useh == sh-1 || useh == sh+1) useh=sh; - drawx += (draww-usew)/2; - drawy += (drawh-useh)/2; - draww = usew; - drawh = useh; - } - - int hh=bkbm->bgimage->getHeight()/3; - - if (haspink) - { - WDL_VirtualWnd_BGCfg tmp = *bkbm; - if ((tmp.bgimage_noalphaflags&0xffff)!=0xffff) tmp.bgimage_noalphaflags=0; // force alpha channel if any alpha - - if (drawsrcx>0) { drawsrcx--; drawsrcw++; } - LICE_SubBitmap bm(tmp.bgimage,drawsrcx,bkbmstate*hh,drawsrcw+1,hh+2); - tmp.bgimage = &bm; - - WDL_VirtualWnd_ScaledBlitBG(drawbm,&tmp, - drawx,drawy,draww,drawh, - cliprect->left,cliprect->top,cliprect->right-cliprect->left,cliprect->bottom-cliprect->top, - alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - else - { - LICE_ScaledBlit(drawbm,bkbm->bgimage, - drawx,drawy,draww,drawh, - drawsrcx,bkbmstate*hh, - drawsrcw,hh,alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } -} - - -void WDL_VirtualListBox::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - RECT r=m_position; - r.left+=origin_x; - r.right+=origin_x; - r.top+=origin_y; - r.bottom+=origin_y; - - WDL_VirtualWnd_BGCfg *mainbk=0; - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,&mainbk) : 0; - LICE_pixel bgc=GSC(COLOR_BTNFACE); - bgc=LICE_RGBA_FROMNATIVE(bgc,255); - - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - if (r.right > r.left + usedw) r.right=r.left+usedw; - - if (mainbk && mainbk->bgimage) - { - if (mainbk->bgimage->getWidth()>1 && mainbk->bgimage->getHeight()>1) - { - WDL_VirtualWnd_ScaledBlitBG(drawbm,mainbk, - r.left,r.top,r.right-r.left,r.bottom-r.top, - cliprect->left,cliprect->top,cliprect->right-cliprect->left,cliprect->bottom-cliprect->top, - 1.0,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - } - } - else - { - LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,bgc,1.0f,LICE_BLIT_MODE_COPY); - } - - LICE_pixel pencol = GSC(COLOR_3DSHADOW); - LICE_pixel pencol2 = GSC(COLOR_3DHILIGHT); - pencol=LICE_RGBA_FROMNATIVE(pencol,255); - pencol2=LICE_RGBA_FROMNATIVE(pencol2,255); - - LICE_pixel tcol=GSC(COLOR_BTNTEXT); - if (m_font) m_font->SetBkMode(TRANSPARENT); - - float alpha = (m_grayed ? 0.25f : 1.0f); - - int endpos=r.bottom - updownbuttonsize; - int itempos=startpos; - - int colpos; - int y=0; - for (colpos = 0; colpos < num_cols; colpos ++) - { - int col_x = r.left + leftrightbuttonsize + ((r.right-r.left-leftrightbuttonsize*2)*colpos) / num_cols; - int col_w = r.left + leftrightbuttonsize + ((r.right-r.left-leftrightbuttonsize*2)*(colpos+1)) / num_cols - col_x; - for (y = r.top + m_rh; y <= endpos; y += m_rh) - { - int ly=y-m_rh; - WDL_VirtualWnd_BGCfg *bkbm=0; - if (m_GetItemInfo && ly >= r.top) - { - char buf[64]; - buf[0]=0; - int color=tcol; - - if (m_GetItemInfo(this,itempos++,buf,sizeof(buf),&color,&bkbm)) - { - color=LICE_RGBA_FROMNATIVE(color,0); - RECT thisr; - thisr.left = col_x; - thisr.right = col_x + col_w; - thisr.top = ly+1; - thisr.bottom = y-1; - int rev=0; - int bkbmstate=0; - if (m_cap_state==1 && m_cap_startitem==itempos-1) - { - if (bkbm) bkbmstate=1; - else color = ((color>>1)&0x7f7f7f7f)+LICE_RGBA(0x7f,0x7f,0x7f,0); - } - if (m_cap_state>=0x1000 && m_cap_startitem==itempos-1) - { - if (bkbm) bkbmstate=2; - else - { - rev=1; - LICE_FillRect(drawbm,thisr.left,thisr.top,thisr.right-thisr.left,thisr.bottom-thisr.top, color,alpha,LICE_BLIT_MODE_COPY); - } - } - if (bkbm && bkbm->bgimage) //draw image! - { - DrawBkImage(drawbm,bkbm, - thisr.left,thisr.top-1,thisr.right-thisr.left,thisr.bottom-thisr.top+2, - cliprect, - 0,bkbm->bgimage->getWidth(),bkbmstate,alpha); - - } - if (m_CustomDraw) - { - m_CustomDraw(this,itempos-1,&thisr,drawbm); - } - - if (buf[0]) - { - thisr.left+=m_margin_l; - thisr.right-=m_margin_r; - if (m_font) - { - m_font->SetTextColor(rev?bgc:color); - m_font->SetCombineMode(LICE_BLIT_MODE_COPY, alpha); // maybe gray text only if !bkbm->bgimage - m_font->DrawText(drawbm,buf,-1,&thisr,DT_VCENTER|(m_align<0?DT_LEFT:m_align>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); - } - } - } - } - - if (!bkbm) - { - LICE_Line(drawbm,col_x,y,col_x+col_w,y,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - } - } - } - memset(&m_lastscrollbuttons,0,sizeof(m_lastscrollbuttons)); - if (updownbuttonsize||leftrightbuttonsize) - { - WDL_VirtualWnd_BGCfg *bkbm[2]={0,}; - int a=m_GetItemInfo ? m_GetItemInfo(this, - leftrightbuttonsize ? WDL_VWND_LISTBOX_ARROWINDEX_LR : WDL_VWND_LISTBOX_ARROWINDEX,NULL,0,NULL,bkbm) : 0; - - if (!a) bkbm[0]=0; - - if (leftrightbuttonsize) - { - RECT br={0,0,r.right-r.left,r.bottom-r.top}; - - if (startpos>0) - { - m_lastscrollbuttons[0]=br; - m_lastscrollbuttons[0].right = br.left + m_scrollbuttonsize; - } - if (itempos < num_items) - { - m_lastscrollbuttons[1]=br; - m_lastscrollbuttons[1].left=br.right - m_scrollbuttonsize; - } - } - else - { - RECT br={0,y-r.top - m_rh,r.right-r.left,y-r.top - m_rh + m_scrollbuttonsize}; - if (startpos>0) - { - m_lastscrollbuttons[0]=br; - m_lastscrollbuttons[0].right = (br.left+br.right)/2; - } - if (itempos < num_items) - { - m_lastscrollbuttons[1]=br; - m_lastscrollbuttons[1].left = (br.left+br.right)/2; - } - } - - - int wb; - for (wb=0;wb<2;wb++) - { - if (bkbm[wb] && bkbm[wb]->bgimage) - { - int tw = bkbm[wb]->bgimage->getWidth(); - int bkbmstate=startpos>0 ? 2 : 1; - if (leftrightbuttonsize) - { - DrawBkImage(drawbm,bkbm[wb], - r.left,r.top,m_scrollbuttonsize,(r.bottom-r.top), - cliprect, - 0,tw/2,bkbmstate,1.0, wb); - - - bkbmstate=itemposbgimage || - !bkbm[1] || !bkbm[1]->bgimage) - { - bool butaa = true; - if (updownbuttonsize) - { - int cx=(r.left+r.right)/2; - int bs=5; - int bsh=8; - y -= m_rh-m_scrollbuttonsize; - - if (!bkbm[0] || !bkbm[0]->bgimage) - { - LICE_Line(drawbm,cx,y-m_scrollbuttonsize+2,cx,y-1,pencol2,1.0f,0,false); - LICE_Line(drawbm,r.left,y,r.right,y,pencol2,1.0f,0,false); - } - - y-=m_scrollbuttonsize/2+bsh/2; - - if (!bkbm[1] || !bkbm[1]->bgimage) - { - if (itempos0) - { - y-=2; - cx=(r.left+r.right)/4; - LICE_Line(drawbm,cx-bs+1,y+bsh,cx,y+3+1,pencol2,1.0f,0,butaa); - LICE_Line(drawbm,cx,y+3+1,cx+bs-1,y+bsh,pencol2,1.0f,0,butaa); - LICE_Line(drawbm,cx+bs-1,y+bsh,cx-bs+1,y+bsh,pencol2,1.0f,0,butaa); - - LICE_Line(drawbm,cx-bs-1,y+bsh+1,cx,y+3,pencol,1.0f,0,butaa); - LICE_Line(drawbm,cx,y+3,cx+bs+1,y+bsh+1,pencol,1.0f,0,butaa); - LICE_Line(drawbm,cx+bs+1,y+bsh+1, cx-bs-1,y+bsh+1, pencol,1.0f,0,butaa); - } - } - } - else // sideways buttons - { - if (!bkbm[1] || !bkbm[1]->bgimage) - { - #define LICE_LINEROT(bm,x1,y1,x2,y2,pc,al,mode,aa) LICE_Line(bm,y1,x1,y2,x2,pc,al,mode,aa) - int bs=5; - int bsh=8; - int cx = (r.bottom + r.top)/2; - if (itempos < num_items) - { - int y = r.right - leftrightbuttonsize/2 - bsh/2; - LICE_LINEROT(drawbm,cx-bs+1,y+2,cx,y+bsh-2,pencol2,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx,y+bsh-2,cx+bs-1,y+2,pencol2,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx+bs-1,y+2,cx-bs+1,y+2,pencol2,1.0f,0,butaa); - - LICE_LINEROT(drawbm,cx-bs-1,y+1,cx,y+bsh-1,pencol,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx,y+bsh-1,cx+bs+1,y+1,pencol,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx+bs+1,y+1,cx-bs-1,y+1,pencol,1.0f,0,butaa); - } - if (startpos>0) - { - int y = r.left + leftrightbuttonsize/2-bsh/2 - 2; - LICE_LINEROT(drawbm,cx-bs+1,y+bsh,cx,y+3+1,pencol2,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx,y+3+1,cx+bs-1,y+bsh,pencol2,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx+bs-1,y+bsh,cx-bs+1,y+bsh,pencol2,1.0f,0,butaa); - - LICE_LINEROT(drawbm,cx-bs-1,y+bsh+1,cx,y+3,pencol,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx,y+3,cx+bs+1,y+bsh+1,pencol,1.0f,0,butaa); - LICE_LINEROT(drawbm,cx+bs+1,y+bsh+1, cx-bs-1,y+bsh+1, pencol,1.0f,0,butaa); - } - #undef LICE_LINEROT - } - } - } - } - - - - if (!mainbk) - { - LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,0,false); - LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,0,false); - LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol2,1.0f,0,false); - LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol2,1.0f,0,false); - } - - -} - -bool WDL_VirtualListBox::HandleScrollClicks(int xpos, int ypos, int leftrightbuttonsize, int updownbuttonsize, int nrows, int num_cols, int num_items, int usedw) -{ - if (leftrightbuttonsize && (xpos= usedw-m_scrollbuttonsize)) - { - if (xpos0) - { - m_viewoffs-=nrows; - if (m_viewoffs<0)m_viewoffs=0; - RequestRedraw(NULL); - } - } - else - { - if (m_viewoffs+nrows*num_cols < num_items) - { - m_viewoffs+=nrows; - RequestRedraw(NULL); - } - } - m_cap_state=0; - m_cap_startitem=-1; - return true; - } - if (updownbuttonsize && ypos >= nrows*m_rh) - { - if (ypos < (nrows)*m_rh + m_scrollbuttonsize) - { - if (xpos < usedw/2) - { - if (m_viewoffs>0) - { - m_viewoffs--; - RequestRedraw(NULL); - } - } - else - { - if (m_viewoffs+nrows*num_cols < num_items) - { - m_viewoffs++; - RequestRedraw(NULL); - } - } - } - m_cap_state=0; - m_cap_startitem=-1; - return true; - } - return false; -} - -int WDL_VirtualListBox::OnMouseDown(int xpos, int ypos) -{ - if (m_grayed) return 0; - - if (m__iaccess) m__iaccess->OnFocused(); - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - - if (xpos >= usedw) return 0; - - if (HandleScrollClicks(xpos,ypos,leftrightbuttonsize,updownbuttonsize,nrows,num_cols,num_items,usedw)) return 1; - - - - m_cap_state=0x1000; - int usewid=(usedw-leftrightbuttonsize*2); - int col = num_cols > 0 && usewid>0 ? ((xpos-leftrightbuttonsize)*num_cols)/usewid : 0; - m_cap_startitem=startpos + (ypos)/m_rh + col*nrows; - RequestRedraw(NULL); - - return 1; -} - - -bool WDL_VirtualListBox::OnMouseDblClick(int xpos, int ypos) -{ - if (m_grayed) return false; - - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - - if (xpos >= usedw) return false; - - if (HandleScrollClicks(xpos,ypos,leftrightbuttonsize,updownbuttonsize,nrows,num_cols,num_items,usedw)) return true; - - return false; -} - -bool WDL_VirtualListBox::OnMouseWheel(int xpos, int ypos, int amt) -{ - if (m_grayed) return false; - - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - - if (xpos >= usedw) return false; - - if (num_items > nrows*num_cols) - { - if (amt>0 && m_viewoffs>0) - { - m_viewoffs-=(num_cols>1?nrows:1); - if (m_viewoffs<0)m_viewoffs=0; - RequestRedraw(NULL); - } - else if (amt<0) - { - if (m_viewoffs+nrows*num_cols < num_items) - { - m_viewoffs+=(num_cols>1?nrows:1); - RequestRedraw(NULL); - } - } - } - return true; -} - -void WDL_VirtualListBox::OnMouseMove(int xpos, int ypos) -{ - if (m_grayed) return; - - if (m_cap_state>=0x1000) - { - m_cap_state++; - if (m_cap_state==0x1008) - { - if (m_dragbeginmsg) - { - SendCommand(m_dragbeginmsg,(INT_PTR)this,m_cap_startitem,this); - } - } - } - else if (m_cap_state==0) - { - int a=IndexFromPt(xpos,ypos); - if (a>=0) - { - m_cap_startitem=a; - m_cap_state=1; - RequestRedraw(NULL); - } - } - else if (m_cap_state==1) - { - int a=IndexFromPt(xpos,ypos); - if (a>=0 && a != m_cap_startitem) - { - m_cap_startitem=a; - m_cap_state=1; - RequestRedraw(NULL); - } - else if (a<0) - { - m_cap_state=0; - RequestRedraw(NULL); - } - } -} - -void WDL_VirtualListBox::OnMouseUp(int xpos, int ypos) -{ - if (m_grayed) return; - - int hit=IndexFromPt(xpos,ypos); - if (m_cap_state>=0x1000 && m_cap_state<0x1008 && hit==m_cap_startitem) - { - if (m_clickmsg) - { - SendCommand(m_clickmsg,(INT_PTR)this,hit,this); - } - } - else if (m_cap_state>=0x1008) - { - // send a message saying drag & drop occurred - if (m_dropmsg) - SendCommand(m_dropmsg,(INT_PTR)this,m_cap_startitem,this); - } - - m_cap_state=0; - RequestRedraw(NULL); -} - -bool WDL_VirtualListBox::GetItemRect(int item, RECT *r) -{ - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos, usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - item -= startpos; - - if (r) - { - int col = item / nrows; - int row = item % nrows; - r->top = row * m_rh; - r->bottom = (row+1)*m_rh; - r->left = leftrightbuttonsize + (col * (usedw - leftrightbuttonsize*2)) / num_cols; - r->right = leftrightbuttonsize + ((col+1) * (usedw - leftrightbuttonsize*2)) / num_cols; - } - return item >= startpos && item < startpos + nrows*num_cols;; -} - -int WDL_VirtualListBox::IndexFromPt(int x, int y) -{ - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; - CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); - - if (x>=usedw) return -2; - - if (y < 0 || y >= nrows*m_rh ||x= (usedw-leftrightbuttonsize)) return -1; - - int usewid=(usedw-leftrightbuttonsize*2); - int col = num_cols > 0 && usewid>0 ? ((x-leftrightbuttonsize)*num_cols)/usewid : 0; - - return startpos + (y)/m_rh + col * nrows; -} - -void WDL_VirtualListBox::SetViewOffset(int offs) -{ - int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; - if (num_items) - { - if (offs < 0) offs=0; - else if (offs >= num_items) offs = num_items-1; - if (offs != m_viewoffs) - { - m_viewoffs = offs; - RequestRedraw(0); - } - } -} - -int WDL_VirtualListBox::GetViewOffset() -{ - return m_viewoffs; -} diff --git a/WDL/wingui/virtwnd-nsaccessibility.mm b/WDL/wingui/virtwnd-nsaccessibility.mm deleted file mode 100644 index c290c936..00000000 --- a/WDL/wingui/virtwnd-nsaccessibility.mm +++ /dev/null @@ -1,644 +0,0 @@ -#include "../swell/swell.h" - -#include "virtwnd-controls.h" - - -@class VWndNSAccessibility; -static VWndNSAccessibility *GetVWndNSAccessible(WDL_VWnd *vwnd); -static WDL_VWnd *__focus; -class VWndBridgeNS; - - -@interface VWndNSAccessibility : NSObject -{ -@public - VWndBridgeNS *m_br; - NSArray *m_cached_children; - int m_cached_children_lastcnt; - NSArray *m_cached_attrnames; -} --(id) initWithVWnd:(WDL_VWnd *)vw; --(void)dealloc; --(void)clearCaches; - - -// attribute methods -- (NSArray *)accessibilityAttributeNames; -- (id)accessibilityAttributeValue:(NSString *)attribute; -- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; -- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; - -// parameterized attribute methods -- (NSArray *)accessibilityParameterizedAttributeNames; -- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter; - -// action methods -- (NSArray *)accessibilityActionNames; -- (NSString *)accessibilityActionDescription:(NSString *)action; -- (void)accessibilityPerformAction:(NSString *)action; - -// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. -- (BOOL)accessibilityIsIgnored; - -// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. -- (id)accessibilityHitTest:(NSPoint)point; - -// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. -- (id)accessibilityFocusedUIElement; - - -@end - - -class VWndBridgeNS : public WDL_VWnd_IAccessibleBridge -{ -public: - VWndBridgeNS(VWndNSAccessibility *p, WDL_VWnd *vw) - { - [(par=p) retain]; - (vwnd=vw)->SetAccessibilityBridge(this); - } - ~VWndBridgeNS() - { -// if (vwnd) printf("Destroying self before Released, wtf!\n"); - } - - virtual void Release() - { - if (__focus == vwnd) __focus=0; - - vwnd=0; - if (par) - { - NSAccessibilityPostNotification(par,NSAccessibilityUIElementDestroyedNotification); - [par release]; - // this is probably no longer valid! - } - } - virtual void ClearCaches() - { - if (par) [par clearCaches]; - } - virtual void OnFocused() - { - if (vwnd && __focus != vwnd && par) - { - __focus = vwnd; -// NSAccessibilityPostNotification(par,NSAccessibilityFocusedWindowChangedNotification); - NSAccessibilityPostNotification(par,NSAccessibilityFocusedUIElementChangedNotification); - } - } - virtual void OnStateChange() - { - if (par) NSAccessibilityPostNotification(par,NSAccessibilityValueChangedNotification); - } - - VWndNSAccessibility *par; - WDL_VWnd *vwnd; -}; - -@implementation VWndNSAccessibility --(id) initWithVWnd:(WDL_VWnd *)vw -{ - if ((self = [super init])) - { - m_br = new VWndBridgeNS(self,vw); - m_cached_children=0; - m_cached_attrnames = 0; - m_cached_children_lastcnt=0; - } - return self; -} --(void)clearCaches -{ - if (m_cached_children) - { - [m_cached_children release]; - m_cached_children=0; - m_cached_children_lastcnt=0; - } - if (m_cached_attrnames) - { - [m_cached_attrnames release]; - m_cached_attrnames = 0; - } -} --(void)dealloc -{ - [self clearCaches]; - delete m_br; - [super dealloc]; -} - -- (NSArray *)accessibilityAttributeNames -{ - if (m_cached_attrnames) return m_cached_attrnames; - NSString *s[32]; - int sidx=0; - const char *type = NULL; - if (m_br->vwnd) - { - type = m_br->vwnd->GetType(); - if (!type) type = ""; - } - if (type) - { -// if (m_br->vwnd->GetNumChildren()) - { - s[sidx++] = NSAccessibilityChildrenAttribute; - s[sidx++] = NSAccessibilityVisibleChildrenAttribute; - } - s[sidx++]=NSAccessibilityTitleAttribute; - - if (!strcmp(type,"vwnd_iconbutton")) s[sidx++] = NSAccessibilityEnabledAttribute; - - s[sidx++] = NSAccessibilityFocusedAttribute; - s[sidx++] = NSAccessibilityParentAttribute; - - RECT r; - m_br->vwnd->GetPosition(&r); - if (m_br->vwnd->IsVisible() && r.right>r.left && r.bottom>r.top) - { - s[sidx++] = NSAccessibilityPositionAttribute; - s[sidx++] = NSAccessibilitySizeAttribute; - } - - s[sidx++] = NSAccessibilityRoleAttribute; - s[sidx++] = NSAccessibilityRoleDescriptionAttribute; - - if (!strcmp(type,"vwnd_statictext")) - { - // s[sidx++]=NSAccessibilityDescriptionAttribute; -// s[sidx++]=NSAccessibilityValueDescriptionAttribute; - } - - s[sidx++] = NSAccessibilityWindowAttribute; - bool hasState = false; - if (!strcmp(type,"vwnd_iconbutton")) - { - hasState = ((WDL_VirtualIconButton*)m_br->vwnd)->GetCheckState()>=0; - } - else if (!strcmp(type,"vwnd_combobox")) hasState=true; - else if (!strcmp(type,"vwnd_slider")) hasState=true; - - if (hasState) - { - s[sidx++] = NSAccessibilityMaxValueAttribute; - s[sidx++] = NSAccessibilityMinValueAttribute; - s[sidx++] = NSAccessibilityValueAttribute; - } - } - - if (m_cached_attrnames) [m_cached_attrnames release]; - m_cached_attrnames = [NSArray arrayWithObjects:s count:sidx]; - [m_cached_attrnames retain]; - return m_cached_attrnames; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute -{ - if (!m_br->vwnd) return nil; - const char *type = m_br->vwnd->GetType(); - if (!type) type=""; - - //NSLog(@"Requesting attribute: %@ %s %p\n",attribute,type,m_br->vwnd); - - int a = [attribute isEqual:NSAccessibilityChildrenAttribute]?1:0; - if (!a) a= [attribute isEqual:NSAccessibilityVisibleChildrenAttribute]?2:0; - if (a) // if 2, only add visible items - { - int nc = m_br->vwnd->GetNumChildren(); -// if (!nc) { if (m_cached_children) { [m_cached_children release]; m_cached_children=0; } printf("ret nil\n"); return nil; } - - if (m_cached_children && nc == m_cached_children_lastcnt) return m_cached_children; - - NSMutableArray *ar = [NSMutableArray arrayWithCapacity:nc]; - int x; - for (x=0;xvwnd->EnumChildren(x); - if (!ch) continue; - RECT r; - ch->GetPosition(&r); - if (a==1 || (ch->IsVisible() && r.right>r.left && r.bottom>r.top)) - { - VWndNSAccessibility *cid = GetVWndNSAccessible(ch); - if (cid) - { - [ar addObject:cid]; - [cid release]; - } - } - } - [m_cached_children release]; - m_cached_children_lastcnt = nc; - m_cached_children = NSAccessibilityUnignoredChildren(ar); - [m_cached_children retain]; - return m_cached_children; - } - - if ([attribute isEqual:NSAccessibilityEnabledAttribute]) - { - if (!strcmp(type,"vwnd_iconbutton")) - { - return [NSNumber numberWithBool:!!((WDL_VirtualIconButton *)m_br->vwnd)->GetEnabled()]; - } - return nil; - } - if ([attribute isEqual:NSAccessibilityFocusedAttribute]) - { - return [NSNumber numberWithBool:(__focus == m_br->vwnd || (m_br->vwnd && m_br->vwnd->IsDescendent(__focus)))]; // todo focus bleh - } - if ([attribute isEqual:NSAccessibilityParentAttribute]) - { - WDL_VWnd *parw = m_br->vwnd->GetParent(); - if (parw) - { - VWndNSAccessibility *cid = GetVWndNSAccessible(parw); - if (cid) return NSAccessibilityUnignoredAncestor([cid autorelease]); - } - HWND h =m_br->vwnd->GetRealParent(); - if (h) return NSAccessibilityUnignoredAncestor((id)h); - return NULL; - } - if ([attribute isEqual:NSAccessibilityPositionAttribute]) - { - RECT r; - m_br->vwnd->GetPosition(&r); - r.top = r.bottom; // this wants the lower left corner - WDL_VWnd *p = m_br->vwnd->GetParent(); - while (p) - { - RECT tr; - p->GetPosition(&tr); - r.left += tr.left; - r.top += tr.top; - p = p->GetParent(); - } - HWND h = m_br->vwnd->GetRealParent(); - if (h) - { - ClientToScreen(h,(LPPOINT)&r); - } - //printf("position of (%s) %d,%d\n",m_br->vwnd->GetAccessDesc()?m_br->vwnd->GetAccessDesc():"nul",r.left,r.top); - return [NSValue valueWithPoint:NSMakePoint(r.left,r.top)]; - } - if ([attribute isEqual:NSAccessibilitySizeAttribute]) - { - RECT r; - m_br->vwnd->GetPosition(&r); -// printf("size of (%s) %d,%d\n",m_br->vwnd->GetAccessDesc()?m_br->vwnd->GetAccessDesc():"nul",r.right-r.left,r.bottom-r.top); - return [NSValue valueWithSize:NSMakeSize(r.right-r.left,r.bottom-r.top)]; - } - if ([attribute isEqual:NSAccessibilityRoleDescriptionAttribute]) - { - const char *str= NULL; - if (!str || !*str) - { - if (!strcmp(type,"vwnd_statictext")) str = "text"; - else if (!strcmp(type,"vwnd_slider")) str = "slider"; - else if (!strcmp(type,"vwnd_combobox")) str = "selection box"; - else if (!strcmp(type,"vwnd_iconbutton")) - { - WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; - if (b->GetCheckState()>=0) str = "check box"; - else str = "button"; - } - if (!str) str = m_br->vwnd->GetAccessDesc(); - } - if (str && *str) return [(id)SWELL_CStringToCFString(str) autorelease]; - - } - if ([attribute isEqual:NSAccessibilityRoleAttribute]) - { - if (!strcmp(type,"vwnd_statictext")) return NSAccessibilityButtonRole; // fail: seems to need 10.5+ to deliver text? NSAccessibilityStaticTextRole; - if (!strcmp(type,"vwnd_slider")) return NSAccessibilitySliderRole; - if (!strcmp(type,"vwnd_combobox")) return NSAccessibilityPopUpButtonRole; - if (!strcmp(type,"vwnd_iconbutton")) - { - WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; - if (b->GetCheckState()>=0) - return NSAccessibilityCheckBoxRole; - return NSAccessibilityButtonRole; - } - return NSAccessibilityUnknownRole; - } - if ([attribute isEqual:NSAccessibilityTitleAttribute] || [attribute isEqual:NSAccessibilityDescriptionAttribute])// || [attribute isEqual:NSAccessibilityValueDescriptionAttribute]) - { - const char *str=NULL; - int cs=-1; - if (!strcmp(type,"vwnd_statictext")) - { - WDL_VirtualStaticText *t = (WDL_VirtualStaticText *)m_br->vwnd; - str = t->GetText(); - } - if (!strcmp(type,"vwnd_combobox")) - { - WDL_VirtualComboBox *cb = (WDL_VirtualComboBox *)m_br->vwnd; - str = cb->GetItem(cb->GetCurSel()); - } - if (!strcmp(type,"vwnd_iconbutton")) - { - WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; - str = b->GetTextLabel(); - cs = b->GetCheckState(); - } - char buf[2048]; - if (!str || !*str) str= m_br->vwnd->GetAccessDesc(); - else - { - const char *p = m_br->vwnd->GetAccessDesc(); - if (p && *p) - { - char buf[1024]; - sprintf(buf,"%.512s: %.512s",p,str); - str=buf; - } - } - - -#if 0 - if (cs>=0) - { - if (str!=buf) - { - lstrcpyn(buf,str?str:"",sizeof(buf)-128); - str=buf; - } -// strcat(buf,cs>0 ? " checked" : " unchecked"); - - } -#endif - - if (str && *str) return [(id)SWELL_CStringToCFString(str) autorelease]; - } - if ([attribute isEqual:NSAccessibilityWindowAttribute]) - { - HWND h = m_br->vwnd->GetRealParent(); - if (h) - { - return [(NSView *)h window]; - } - } - int s; - if ((s=!![attribute isEqual:NSAccessibilityMaxValueAttribute]) || - (s=[attribute isEqual:NSAccessibilityValueAttribute]?2:0) || - [attribute isEqual:NSAccessibilityMinValueAttribute]) - { - if (!strcmp(type,"vwnd_slider")) - { - WDL_VirtualSlider *slid = (WDL_VirtualSlider *)m_br->vwnd; - int v=0; - if (s!=2) slid->GetRange(s ? NULL : &v, s ? &v :NULL,NULL); - else v= slid->GetSliderPosition(); - return [NSNumber numberWithInt:v]; - } - if (!strcmp(type,"vwnd_combobox")) - { - int v=0; - if (s==1) v=((WDL_VirtualComboBox*)m_br->vwnd)->GetCount(); - else if (s==2) v= !!((WDL_VirtualComboBox *)m_br->vwnd)->GetCurSel(); - if (v<0)v=0; - return [NSNumber numberWithInt:v]; - } - if (!strcmp(type,"vwnd_iconbutton")) - { - int v=0; - if (s==1) v=1; - else if (s==2) v= !!((WDL_VirtualIconButton *)m_br->vwnd)->GetCheckState()>0; - return [NSNumber numberWithInt:v]; - } - } - return nil; -} -- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - // NSLog(@"accessibilityIsAttributeSettable: %@ %s %p\n",attribute,type,m_br->vwnd); - } - - if ([attribute isEqual:NSAccessibilityFocusedAttribute]) return YES; - return false; -} -- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilitySetValue: %@ %s %p\n",attribute,type,m_br->vwnd); - } - - if ([attribute isEqual:NSAccessibilityFocusedAttribute]) - { - if ([value isKindOfClass:[NSNumber class]]) - { - NSNumber *p = (NSNumber *)value; - if ([p boolValue]) __focus = m_br->vwnd; - else if (__focus == m_br->vwnd) __focus=NULL; - } - } -} - -// parameterized attribute methods -- (NSArray *)accessibilityParameterizedAttributeNames -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityParameterizedAttributeNames: %@ %s %p\n",@"",type,m_br->vwnd); - } - return [NSArray arrayWithObjects:nil count:0]; - return nil; -} -- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityAttributeValue: %@ %s %p\n",attribute,type,m_br->vwnd); - } - return nil; -} - -// action methods -- (NSArray *)accessibilityActionNames -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityActionNames: %@ %s %p\n",@"",type,m_br->vwnd); - } - NSString *s[32]; - int sidx=0; - - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (type) - { - if (!strcmp(type,"vwnd_combobox") || - !strcmp(type,"vwnd_iconbutton") || - !strcmp(type,"vwnd_statictext") - ) s[sidx++] = NSAccessibilityPressAction; - - if (!strcmp(type,"vwnd_slider")) - { - s[sidx++] = NSAccessibilityDecrementAction; - s[sidx++] = NSAccessibilityIncrementAction; - } - } - - return [NSArray arrayWithObjects:s count:sidx]; -} -- (NSString *)accessibilityActionDescription:(NSString *)action -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityActionDescription: %@ %s %p\n",action,type,m_br->vwnd); - } - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (type) - { - if ([action isEqual:NSAccessibilityPressAction]) - { - if (!strcmp(type,"vwnd_combobox")) return @"Choose item"; - if (!strcmp(type,"vwnd_iconbutton")) return @"Press button"; - if (!strcmp(type,"vwnd_statictext")) return @"Doubleclick text"; - } - else if (!strcmp(type,"vwnd_slider")) - { - if ([action isEqual:NSAccessibilityDecrementAction]) return @"Decrease value of control"; - else if ([action isEqual:NSAccessibilityIncrementAction])return @"Increase value of control"; - } - } - return nil; -} - -- (void)accessibilityPerformAction:(NSString *)action -{ - if (m_br->vwnd) - { - const char *type = m_br->vwnd->GetType(); - if (!type) type=""; - - if ([action isEqual:NSAccessibilityPressAction]) - { - if (!strcmp(type,"vwnd_statictext")) m_br->vwnd->OnMouseDblClick(0,0); - else - { - m_br->vwnd->OnMouseDown(0,0); - m_br->vwnd->OnMouseUp(0,0); - } - } - else if ([action isEqual:NSAccessibilityDecrementAction]) - { - m_br->vwnd->OnMouseWheel(0,0,-1); - } - else if ([action isEqual:NSAccessibilityIncrementAction]) - { - m_br->vwnd->OnMouseWheel(0,0,1); - } - //NSLog(@"accessibilityPerformAction: %@ %s %p\n",action,type,m_br->vwnd); - } - // todo -} - -// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. -- (BOOL)accessibilityIsIgnored -{ - if (m_br->vwnd) - { - if (!m_br->vwnd->IsVisible()) return YES; - if (m_br->vwnd->GetNumChildren()) - { - const char *type = m_br->vwnd->GetType(); - if (type) if (!strcmp(type,"vwnd_unknown") || strstr(type,"container")) return YES; - } - else - { - RECT r; - m_br->vwnd->GetPosition(&r); - if (r.right <= r.left || r.bottom <= r.top) return YES; - } - } - return NO; -} - -// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. -- (id)accessibilityHitTest:(NSPoint)point -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; -// NSLog(@"accessibilityHitTest: %f,%f %s %p\n",point.x,point.y,type,m_br->vwnd); - } - - if (m_br->vwnd) - { - HWND h = m_br->vwnd->GetRealParent(); - if (h) - { - POINT pt = {(int)point.x,(int)point.y}; - ScreenToClient(h,&pt); - WDL_VWnd *par = m_br->vwnd; - while (par->GetParent()) par=par->GetParent(); - RECT r; - par->GetPosition(&r); - WDL_VWnd *hit = par->VirtWndFromPoint(pt.x-r.left,pt.y-r.top); - if (hit) - { - VWndNSAccessibility *a = GetVWndNSAccessible(hit); - if (a) - { - [a autorelease]; - return a; - } - } - } - } - return nil; -} -// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. -- (id)accessibilityFocusedUIElement -{ - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityFocusedUIElement: %s %p\n",type,m_br->vwnd); - } - if (__focus && m_br && m_br->vwnd && m_br->vwnd->IsDescendent(__focus)) - { - VWndBridgeNS *p = (VWndBridgeNS *)__focus->GetAccessibilityBridge(); - if (p) return p->par; - } - return self; -} - - -@end - - - -static VWndNSAccessibility *GetVWndNSAccessible(WDL_VWnd *vwnd) -{ - if (!vwnd) return NULL; - VWndBridgeNS *p = (VWndBridgeNS *)vwnd->GetAccessibilityBridge(); - if (p) - { - if (p->par) [p->par retain]; - return p->par; - } - - return [[VWndNSAccessibility alloc] initWithVWnd:vwnd]; -} - -LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) -{ - if (vw && lParam && wParam==0x1001) - { - VWndNSAccessibility *nsa = GetVWndNSAccessible(vw); - if (nsa) *(id *)lParam = nsa; - } - return 0; -} diff --git a/WDL/wingui/virtwnd-skin.h b/WDL/wingui/virtwnd-skin.h deleted file mode 100644 index d6e79291..00000000 --- a/WDL/wingui/virtwnd-skin.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _WDL_VIRTWND_SKIN_H_ -#define _WDL_VIRTWND_SKIN_H_ - -class LICE_IBitmap; - -#include "../ptrlist.h" - -typedef struct // if set these override the default virtualwnd styles for this object -{ - LICE_IBitmap *bgimage; - int bgimage_lt[2],bgimage_rb[2]; // size of - int bgimage_lt_out[2],bgimage_rb_out[2]; // size of outside area (like shadows) - int bgimage_noalphaflags; // 4x4 flags of "no alpha", so 65535 is image has no alpha whatsoever -} WDL_VirtualWnd_BGCfg; - - - -class WDL_VirtualWnd_BGCfgCache_ar; - -class WDL_VirtualWnd_BGCfgCache -{ -public: - WDL_VirtualWnd_BGCfgCache(int want_size=15, int max_size=30); - ~WDL_VirtualWnd_BGCfgCache(); - - void Invalidate(); - - LICE_IBitmap *GetCachedBG(int w, int h, void *owner_hint, const LICE_IBitmap *bgbmp); - void SetCachedBG(int w, int h, LICE_IBitmap *bm, void *owner_hint, const LICE_IBitmap *bgbmp); - -private: - WDL_VirtualWnd_BGCfgCache_ar *m_ar; - - - int m_want_size, m_max_size; -}; - -void WDL_VirtualWnd_PreprocessBGConfig(WDL_VirtualWnd_BGCfg *a); - -// used by elements to draw a WDL_VirtualWnd_BGCfg -#define WDL_VWND_SCALEDBLITBG_IGNORE_LR 0x40000000 -#define WDL_VWND_SCALEDBLITBG_IGNORE_INSIDE 0x20000000 -#define WDL_VWND_SCALEDBLITBG_IGNORE_OUTSIDE 0x10000000 -void WDL_VirtualWnd_ScaledBlitBG(LICE_IBitmap *dest, - WDL_VirtualWnd_BGCfg *src, - int destx, int desty, int destw, int desth, - int clipx, int clipy, int clipw, int cliph, - float alpha, int mode); -int WDL_VirtualWnd_ScaledBG_GetPix(WDL_VirtualWnd_BGCfg *src, - int ww, int wh, - int x, int y); - -void WDL_VirtualWnd_ScaledBlitSubBG(LICE_IBitmap *dest, - WDL_VirtualWnd_BGCfg *src, - int destx, int desty, int destw, int desth, - int clipx, int clipy, int clipw, int cliph, - int srcx, int srcy, int srcw, int srch, // these coordinates are not including pink lines (i.e. if pink lines are present, use src->bgimage->getWidth()-2, etc) - float alpha, int mode); - - -typedef struct // if set these override the default virtualwnd styles for this object -{ - WDL_VirtualWnd_BGCfg bgimagecfg[2]; - LICE_IBitmap *thumbimage[2]; // h,v - int thumbimage_lt[2],thumbimage_rb[2]; - unsigned int zeroline_color; // needs alpha channel set! -} WDL_VirtualSlider_SkinConfig; - -void WDL_VirtualSlider_PreprocessSkinConfig(WDL_VirtualSlider_SkinConfig *a); - -typedef struct -{ - LICE_IBitmap *image; // 3x width, second third is "mouseover" image. then mousedown, or straight image if image_issingle set - LICE_IBitmap *olimage; // drawn in second pass - - union - { - char flags; // &1 = overlay, &2=main - bool asBool; // on PPC this is 4 bytes, need to preserve it - } - image_ltrb_used; - bool image_issingle; - short image_ltrb_ol[4]; // extents outside the rect - short image_ltrb_main[4]; // unscaled areas of main image (not used if single) -} WDL_VirtualIconButton_SkinConfig; - -void WDL_VirtualIconButton_PreprocessSkinConfig(WDL_VirtualIconButton_SkinConfig *a); - - - -#endif \ No newline at end of file diff --git a/WDL/wingui/virtwnd-slider.cpp b/WDL/wingui/virtwnd-slider.cpp deleted file mode 100644 index 88f3e1bd..00000000 --- a/WDL/wingui/virtwnd-slider.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* - WDL - virtwnd-slider.cpp - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Implementation for virtual window sliders. - -*/ - -#include -#include "virtwnd-controls.h" -#include "../lice/lice.h" - -void vwnd_slider_drawknobstack(LICE_IBitmap *drawbm, double val, WDL_VirtualWnd_BGCfg *knobimage, int ksw, int ksh, int ks_offs, int dx, int dy, int dw, int dh, double alpha) -{ - const bool v = knobimage->bgimage->getWidth() < knobimage->bgimage->getHeight(); - - const int ni=((v ? knobimage->bgimage->getHeight() : knobimage->bgimage->getWidth())-ks_offs*2) / (v ? ksh : ksw); - - if (val<0.0)val=0.0; - else if (val>1.0)val=1.0; - int p=(int) (val * (ni-1)); - if (p<0) p=0; - else if (p> ni-1) p=ni-1; - - p *= (v ? ksh : ksw); - - if (ks_offs && - knobimage->bgimage_lt_out[0] > 0 && - knobimage->bgimage_lt_out[1] > 0 && - knobimage->bgimage_rb_out[0] > 0 && - knobimage->bgimage_rb_out[1] > 0) - { - int l = knobimage->bgimage_lt_out[0]-1; - int t = knobimage->bgimage_lt_out[1]-1; - int r = knobimage->bgimage_rb_out[0]-1; - int b = knobimage->bgimage_rb_out[1]-1; - - int ww = ksw - l - r; - if (ww > 0) - { - dx -= (dw * l) / ww; - dw = (dw * ksw) / ww; - } - int wh=ksh - t -b; - if (wh) - { - dy -= (dh * t) / wh; - dh = (dh * ksh) / wh; - } - } - - LICE_ScaledBlit(drawbm,knobimage->bgimage,dx,dy,dw,dh,ks_offs + (v?0:p),ks_offs + (v?p:0),ksw,ksh,alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR); -} - - -WDL_VirtualWnd_BGCfg *vwnd_slider_getknobimageforsize(WDL_VirtualWnd_BGCfg *knoblist, int nknoblist,int *vieww, int *viewh, int *ksw, int *ksh, int *ks_offs) -{ - if (!knoblist) return NULL; - WDL_VirtualWnd_BGCfg *knobimage=NULL; - int x; - int best_neww=*vieww, best_newh = *viewh; - - double bestdiff=0; - double target_area_inv=1.0 / ((double)*vieww * *viewh); - - double target_aspect_inv = *viewh / (double) *vieww; - - for(x=0;xgetWidth(), h=knoblist[x].bgimage->getHeight(); - const bool isVS = w < h; - - const int hasPink = knoblist[x].bgimage_lt[0] > 0 && - knoblist[x].bgimage_lt[1] > 0 && - knoblist[x].bgimage_rb[0] > 0 && - knoblist[x].bgimage_rb[1] > 0; - - const int slice_w = isVS ? (w - hasPink*2) : - hasPink && knoblist[x].bgimage_lt[0]>1 ? (knoblist[x].bgimage_lt[0]-1 + (knoblist[x].bgimage_lt_out[0]>1 ? knoblist[x].bgimage_lt_out[0]-1:0)) : - (h-hasPink*2); - const int slice_h = !isVS ? (h - hasPink*2) : - hasPink && knoblist[x].bgimage_lt[1]>1 ? (knoblist[x].bgimage_lt[1]-1 + (knoblist[x].bgimage_lt_out[1]>1 ? knoblist[x].bgimage_lt_out[1]-1:0)) : - (w-hasPink*2); - - - int fmtw = slice_w, fmth=slice_h; - if (hasPink && - knoblist[x].bgimage_lt_out[0] > 0 && - knoblist[x].bgimage_lt_out[1] > 0 && - knoblist[x].bgimage_rb_out[0] > 0 && - knoblist[x].bgimage_rb_out[1] > 0) - { - int l = knoblist[x].bgimage_lt_out[0]-1; - int t = knoblist[x].bgimage_lt_out[1]-1; - int r = knoblist[x].bgimage_rb_out[0]-1; - int b = knoblist[x].bgimage_rb_out[1]-1; - - if (fmtw > l+r) fmtw -= l+r; - if (fmth > b+t) fmth -= b+t; - } - - // prioritize getting the aspect ratio right, then add target area differences -- this needs testing! - double diff = ((double)fmtw / fmth) * target_aspect_inv; - if (diff < 1.0) diff=1.0/diff; - - double diff2 = ((fmtw * (double)fmth) * target_area_inv); - if (diff2 < 1.0) diff2=1.0/diff2; - - diff += diff2 * 0.01; - - if (slice_w > 0 && slice_h > 0 && (!knobimage || bestdiff > diff)) - { - knobimage=&knoblist[x]; - bestdiff=diff; - *ksw = slice_w; - *ksh = slice_h; - *ks_offs = hasPink; - - int tmp=(fmtw * *viewh) / fmth; - if (tmp <= *vieww) - { - best_neww = tmp; - best_newh = *viewh; - } - else - { - best_neww = *vieww; - best_newh = (fmth * *vieww) / fmtw; - } - } - } - } - if (knobimage) - { - *vieww=best_neww; - *viewh=best_newh; - } - return knobimage; -} - - -WDL_VirtualSlider::WDL_VirtualSlider() -{ - m_knob_lineextrasize=0; - m_knobbias=0; - m_zl_color = m_knob_color=0; - m_is_knob=false; - m_tl_extra=m_br_extra=0; - m_skininfo=0; - m_bgcol1_msg=0; - m_minr=0; - m_maxr=1000; - m_needflush=0; - m_pos=m_center=500; - m_captured=false; - m_grayed = false; - m_knobbg[0]=m_knobbg[1]=0; - m_knobstacks=0; - m_nknobstacks=0; - m_sendmsgonclick=false; - m_dblclickmsg=0; -} - -WDL_VirtualSlider::~WDL_VirtualSlider() -{ -} - -bool WDL_VirtualSlider::GetIsVert() -{ - return m_position.right-m_position.left < m_position.bottom-m_position.top; -} - -static void AdjustThumbImageSize(int wndw, int wndh, WDL_VirtualSlider_SkinConfig *a, bool vert, int *bmw, int *bmh, int *startoffs=NULL, bool *want_knob=NULL, int knob_bias=0) -{ - if (want_knob) *want_knob=knob_bias>0; - if (a) - { - int ret=a->thumbimage_rb[vert] - a->thumbimage_lt[vert]; - if (ret>0) - { - if (startoffs) *startoffs = a->thumbimage_lt[vert]; - if (vert) - { - if (*bmh > ret) (*bmw)--; - *bmh=ret; - } - else - { - if (*bmw > ret) (*bmh)--; - *bmw=ret; - } - } - } - if (vert) - { - if (want_knob && *bmh >= wndh*3/4 && !knob_bias) *want_knob=true; - if (*bmh > wndh/2) - { - if (startoffs) *startoffs += (*bmh - wndh/2)/2; - *bmh=wndh/2; - } - } - else - { - if (want_knob && *bmw >= wndw*3/4 && !knob_bias) *want_knob=true; - if (*bmw > wndw/2) - { - if (startoffs) *startoffs += (*bmw - wndw/2)/2; - *bmw=wndw/2; - } - } -} - -void WDL_VirtualSlider_PreprocessSkinConfig(WDL_VirtualSlider_SkinConfig *a) -{ - if (a&&a->thumbimage[0]) - { - int w=a->thumbimage[0]->getWidth(); - int h=a->thumbimage[0]->getHeight(); - int x; - for (x = 0; x < w && LICE_GetPixel(a->thumbimage[0],x,h-1)==LICE_RGBA(255,0,255,255); x ++); - a->thumbimage_lt[0] = x; - for (x = w-1; x > a->thumbimage_lt[0]+1 && LICE_GetPixel(a->thumbimage[0],x,h-1)==LICE_RGBA(255,0,255,255); x --); - a->thumbimage_rb[0] = x; - } - if (a&&a->thumbimage[1]) - { - int w=a->thumbimage[1]->getWidth(); - int h=a->thumbimage[1]->getHeight(); - int y; - for (y = 0; y < h-4 && LICE_GetPixel(a->thumbimage[1],w-1,y)==LICE_RGBA(255,0,255,255); y++); - a->thumbimage_lt[1] = y; - for (y = h-1; y > a->thumbimage_lt[1]+1 && LICE_GetPixel(a->thumbimage[1],w-1,y)==LICE_RGBA(255,0,255,255); y --); - a->thumbimage_rb[1] = y; - } - WDL_VirtualWnd_PreprocessBGConfig(&a->bgimagecfg[0]); - WDL_VirtualWnd_PreprocessBGConfig(&a->bgimagecfg[1]); -} - -void WDL_VirtualSlider::GetButtonSize(int *w, int *h) -{ - if (m_is_knob) - { - *w=*h=0; - return; - } - bool isVert = GetIsVert(); - LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; - if (bm_image) - { - *w = bm_image->getWidth(); - *h = bm_image->getHeight(); - AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,m_skininfo,isVert,w,h); - } - else - { - bm_image=WDL_STYLE_GetSliderBitmap2(isVert); - if (bm_image) - { - *w=bm_image->getWidth(); - *h=bm_image->getHeight(); - } - else *w=*h=16; - AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,NULL,isVert,w,h); - } -} - - -void WDL_VirtualSlider::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - origin_x += m_position.left; // convert drawing origin to local coords - origin_y += m_position.top; - - bool isVert = GetIsVert(); - - int rsize=m_maxr-m_minr; - if (rsize<1)rsize=1; - - int viewh=m_position.bottom-m_position.top; - int vieww=m_position.right-m_position.left; - - WDL_VirtualWnd_BGCfg *back_image=m_skininfo && m_skininfo->bgimagecfg[isVert].bgimage ? &m_skininfo->bgimagecfg[isVert] : 0; - LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; - int bm_w=16,bm_h=16,bm_w2=16,bm_h2=16; - int imgoffset=0; - HBITMAP bm=0; - bool wantKnob=false; - if (bm_image) - { - bm_w2=bm_w=bm_image->getWidth(); - bm_h2=bm_h=bm_image->getHeight(); - AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w2,&bm_h2,&imgoffset,&wantKnob,m_knobbias); - } - else - { - bm_image=WDL_STYLE_GetSliderBitmap2(isVert); - if (bm_image) - { - bm_w2=bm_w=bm_image->getWidth(); - bm_h2=bm_h=bm_image->getHeight(); - } - AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w2,&bm_h2,&imgoffset,&wantKnob,m_knobbias); - } - - float alpha = (m_grayed ? 0.25f : 1.0f); - - m_is_knob = wantKnob; - - if (isVert||wantKnob) - { - int pos = ((m_maxr-m_pos)*(viewh-bm_h2))/rsize; //viewh - bm_h2 - ((m_pos-m_minr) * (viewh - bm_h2))/rsize; - - const int old_vieww=vieww, old_viewh=viewh, old_origin_x=origin_x, old_origin_y=origin_y; - - if (wantKnob) - { - int sz= min(vieww,viewh); - origin_x += (vieww-sz)/2; - origin_y += (viewh-sz)/2; - vieww = viewh = sz; - back_image = m_knobbg[sz>28]; - - if (back_image && !back_image->bgimage) back_image=NULL; - } - - - if (back_image) - { - WDL_VirtualWnd_ScaledBlitBG(drawbm,back_image, - origin_x,origin_y,vieww,viewh, - origin_x,origin_y,vieww,viewh, - 1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - - if (m_bgcol1_msg) - { - int brcol=-100; - SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); - if (brcol != -100) - { - static LICE_MemBitmap tmpbm;//not threadsafe - tmpbm.resize(vieww,viewh); - WDL_VirtualWnd_ScaledBlitBG(&tmpbm,back_image,0,0,vieww,viewh, - 0,0,vieww,viewh,1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - - LICE_ClearRect(&tmpbm,0,0,vieww,viewh,LICE_RGBA(0,0,0,255),LICE_RGBA(GetRValue(brcol),GetGValue(brcol),GetBValue(brcol),0)); - - RECT r={0,0,vieww,viewh}; - LICE_Blit(drawbm,&tmpbm,origin_x,origin_y,&r,0.5,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - } - } - } - - if (!wantKnob) - { - int zlc = m_zl_color; - if (!zlc && m_skininfo) zlc = m_skininfo->zeroline_color; - if (!back_image || zlc) - { - int center=m_center; - if (center < 0) center=WDL_STYLE_GetSliderDynamicCenterPos(); - - int y=((m_maxr-center)*(viewh-bm_h2))/rsize + ((bm_h-1)/2-imgoffset); - - if (!zlc) zlc = LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); - LICE_Line(drawbm,origin_x+2,origin_y+y,origin_x+vieww-2,origin_y+y, zlc, LICE_GETA(zlc)/255.0, LICE_BLIT_MODE_COPY,false); - } - - - if (!back_image) - { - - LICE_pixel fgcol = GSC(COLOR_3DHILIGHT); - fgcol = LICE_RGBA_FROMNATIVE(fgcol,255); - LICE_pixel bgcol=GSC(COLOR_3DSHADOW); - if (m_bgcol1_msg) - SendCommand(m_bgcol1_msg,(INT_PTR)&bgcol,GetID(),this); - bgcol = LICE_RGBA_FROMNATIVE(bgcol,255); - - - int offs= (vieww - 4)/2; - // white with black border, mmm - - RECT r={origin_x + offs,origin_y + bm_h2/3, origin_x + offs + 5,origin_y + viewh - bm_h2/3}; - - LICE_FillRect(drawbm,r.left+1,r.top+1, - r.right-r.left-2,r.bottom-r.top-2,bgcol,1.0f,LICE_BLIT_MODE_COPY); - - LICE_Line(drawbm,r.left+1,r.top,r.right-2,r.top,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.left+1,r.bottom-1,r.right-2,r.bottom-1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - - LICE_Line(drawbm,r.left,r.top+1,r.left,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.right-1,r.top+1,r.right-1,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - - } - - if (bm_image) - { - int ypos=origin_y+pos-imgoffset; - int xpos=origin_x; - - RECT r={0,0,bm_w2,bm_h}; - /* if (vieww m_minr && (m_pos < center || center >= m_maxr)) val = (m_pos-center) / (double)(center-m_minr); - else val = (m_pos-center) / (double)(m_maxr-center); - - if (knobimage && ksw>0 && ksh>0) - { - vwnd_slider_drawknobstack(drawbm,(val+1.0)*0.5,knobimage,ksw,ksh,ks_offs, - old_origin_x + (old_vieww - vw)/2,old_origin_y+(old_viewh - vh)/2,vw,vh,alpha - ); - } - else - { - LICE_pixel col = m_knob_color ? m_knob_color : LICE_RGBA_FROMNATIVE(GSC(COLOR_3DHILIGHT),255); - - float alpha = LICE_GETA(col)/255.0f; - int cx=origin_x+vieww/2; - int cy=origin_y+viewh/2; - float rd = vieww/2-4 + m_knob_lineextrasize; - float r2=rd*0.125f; - if (!back_image) LICE_Circle(drawbm, cx, cy, rd, col, alpha, LICE_BLIT_MODE_COPY, true); - - #define KNOBANGLE_MAX (3.14159*7.0/8.0); - float a = val*KNOBANGLE_MAX; - float sina=sin(a); - float cosa=cos(a); - float x1=cx+r2*sina; - float y1=cy-r2*cosa; - float x2=cx+rd*sina; - float y2=cy-rd*cosa; - LICE_FLine(drawbm, x1, y1, x2, y2, col, alpha, LICE_BLIT_MODE_COPY, true); - } - } - } - else - { - int pos = ((m_pos-m_minr) * (vieww - bm_w2))/rsize; - - if (back_image) - { - WDL_VirtualWnd_ScaledBlitBG(drawbm,back_image, - origin_x,origin_y,vieww,viewh, - origin_x,origin_y,vieww,viewh, - 1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); - // blit, tint color too? - - if (m_bgcol1_msg) - { - int brcol=-100; - SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); - if (brcol != -100) - { - static LICE_MemBitmap tmpbm; //not threadsafe - tmpbm.resize(vieww,viewh); - - WDL_VirtualWnd_ScaledBlitBG(&tmpbm,back_image,0,0,vieww,viewh, - 0,0,vieww,viewh,1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); - - LICE_ClearRect(&tmpbm,0,0,vieww,viewh,LICE_RGBA(0,0,0,255),LICE_RGBA(GetRValue(brcol),GetGValue(brcol),GetBValue(brcol),0)); - - RECT r={0,0,vieww,viewh}; - LICE_Blit(drawbm,&tmpbm,origin_x,origin_y,&r,0.5,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - } - } - - } - - int zlc = m_zl_color; - if (!zlc && m_skininfo) zlc = m_skininfo->zeroline_color; - if (!back_image || zlc) - { - int center=m_center; - if (center < 0) center=WDL_STYLE_GetSliderDynamicCenterPos(); - - int x=((center-m_minr)*(vieww-bm_w2))/rsize + bm_w/2 - imgoffset; - - if (!zlc) zlc = LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); - - LICE_Line(drawbm,origin_x+x,origin_y+2,origin_x+x,origin_y+viewh-2, - zlc, LICE_GETA(zlc)/255.0, LICE_BLIT_MODE_COPY,false); - } - - if (!back_image) - { - LICE_pixel fgcol = GSC(COLOR_3DHILIGHT); - fgcol = LICE_RGBA_FROMNATIVE(fgcol,255); - LICE_pixel bgcol=GSC(COLOR_3DSHADOW); - if (m_bgcol1_msg) - SendCommand(m_bgcol1_msg,(INT_PTR)&bgcol,GetID(),this); - bgcol = LICE_RGBA_FROMNATIVE(bgcol,255); - - int offs= (viewh - 4)/2; - // white with black border, mmm - RECT r={origin_x + bm_w2/3,origin_y + offs, origin_x + vieww - bm_w2/3,origin_y + offs + 5}; - - LICE_FillRect(drawbm,r.left+1,r.top+1, - r.right-r.left-2,r.bottom-r.top-2,bgcol,1.0f,LICE_BLIT_MODE_COPY); - - LICE_Line(drawbm,r.left+1,r.top,r.right-2,r.top,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.left+1,r.bottom-1,r.right-2,r.bottom-1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - - LICE_Line(drawbm,r.left,r.top+1,r.left,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(drawbm,r.right-1,r.top+1,r.right-1,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); - - } - - if (bm_image) - { - int xpos=origin_x+pos-imgoffset; - int ypos=origin_y; - - RECT r={0,0,bm_w,bm_h2}; - /*if (viewh origin_x+m_position.right-m_position.left) - r.right = origin_x+m_position.right-m_position.left - (xpos-r.left); -*/ - - LICE_Blit(drawbm,bm_image,xpos,ypos,&r,alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); - } - } - -} - -static double m_move_offset; -static int m_click_pos,m_last_y,m_last_x, m_last_precmode; - - -int WDL_VirtualSlider::OnMouseDown(int xpos, int ypos) -{ - if (m_grayed) return 0; - m_needflush=0; - - if (m__iaccess) m__iaccess->OnFocused(); - - bool isVert = GetIsVert(); - int rsize=m_maxr-m_minr; - if (rsize<1)rsize=1; - - int viewh=m_position.bottom-m_position.top; - int vieww=m_position.right-m_position.left; - if (vieww<1) vieww=1; - if (viewh<1) viewh=1; - - LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; - int bm_w=16,bm_h=16; - bool wantKnob=false; - if (bm_image) - { - bm_w=bm_image->getWidth(); - bm_h=bm_image->getHeight(); - AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w,&bm_h,NULL,&wantKnob,m_knobbias); - } - else - { - bm_image=WDL_STYLE_GetSliderBitmap2(isVert); - if (bm_image) - { - bm_w=bm_image->getWidth(); - bm_h=bm_image->getHeight(); - } - AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w,&bm_h,NULL,&wantKnob,m_knobbias); - } - - m_is_knob = wantKnob; - - m_last_y=ypos; - m_last_x=xpos; - m_last_precmode=0; - - bool needsendcmd = m_sendmsgonclick; - if (m_is_knob) - { - m_move_offset=0; - m_click_pos=m_pos; - } - else if (isVert) - { - m_move_offset=ypos-( viewh - bm_h - ((double)((m_pos-m_minr) * (viewh-bm_h))/(double)rsize)); - m_click_pos=m_pos; - if (!m_is_knob && (m_move_offset < 0 || m_move_offset >= bm_h)) - { - int xcent=xpos - vieww/2; - bool hit; - - if (m_skininfo && m_skininfo->bgimagecfg[1].bgimage) - { - LICE_pixel pix=WDL_VirtualWnd_ScaledBG_GetPix(&m_skininfo->bgimagecfg[1], - vieww,viewh,xpos,ypos); - - hit = LICE_GETA(pix)>=64; - } - else hit= (xcent >= -2 && xcent < 3 && ypos >= bm_h/3 && ypos <= viewh-bm_h/3); - - if (hit) - { - m_move_offset=bm_h/2; - int pos=m_minr+((viewh-bm_h - (ypos-m_move_offset))*rsize)/(viewh-bm_h); - if (pos < m_minr)pos=m_minr; - else if (pos > m_maxr)pos=m_maxr; - m_pos=pos; - - needsendcmd=false; - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,SB_THUMBTRACK,GetID(),this); - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - } - else return 0; - } - } - else - { - m_move_offset=xpos-( ((double)((m_pos-m_minr) * (vieww-bm_w))/(double)rsize)); - m_click_pos=m_pos; - if (m_move_offset < 0 || m_move_offset >= bm_w) - { - int ycent=ypos - viewh/2; - - bool hit; - if (m_skininfo && m_skininfo->bgimagecfg[0].bgimage) - { - LICE_pixel pix=WDL_VirtualWnd_ScaledBG_GetPix(&m_skininfo->bgimagecfg[0], - vieww,viewh,xpos,ypos); - - hit = LICE_GETA(pix)>=64; - } - else hit = (ycent >= -2 && ycent < 3 && xpos >= bm_w/3 && xpos <= vieww-bm_w/3); - - if (hit) - { - m_move_offset=bm_w/2; - int pos=m_minr+((xpos-m_move_offset)*rsize)/(vieww-bm_w); - if (pos < m_minr)pos=m_minr; - else if (pos > m_maxr)pos=m_maxr; - m_pos=pos; - - needsendcmd=false; - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:WM_HSCROLL,SB_THUMBTRACK,GetID(),this); - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - } - else return 0; - } - } - - m_captured=true; - if (needsendcmd) - { - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,SB_THUMBTRACK,GetID(),this); - if (chk.isOK() && m__iaccess) m__iaccess->OnStateChange(); - } - return 1; -} - - -void WDL_VirtualSlider::OnMoveOrUp(int xpos, int ypos, int isup) -{ - int pos; - bool isVert = GetIsVert(); - int rsize=m_maxr-m_minr; - if (rsize<1)rsize=1; - - int viewh=m_position.bottom-m_position.top; - int vieww=m_position.right-m_position.left; - - LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; - int bm_w=16,bm_h=16; - if (bm_image) - { - bm_w=bm_image->getWidth(); - bm_h=bm_image->getHeight(); - AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w,&bm_h); - } - else - { - bm_image=WDL_STYLE_GetSliderBitmap2(isVert); - if (bm_image) - { - bm_w=bm_image->getWidth(); - bm_h=bm_image->getHeight(); - } - AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w,&bm_h); - } - - int precmode=0; - if (m_is_knob) isVert=true; - - if (isVert) - { -#ifndef _WIN32 - if (isup) pos=m_pos; - else -#endif - if (viewh <= bm_h || m_is_knob || (GetAsyncKeyState(VK_CONTROL)&0x8000)) - { - int sc=m_is_knob && !(GetAsyncKeyState(VK_CONTROL)&0x8000)?4:1; - pos = m_pos- ((ypos-m_last_y) - (m_is_knob ?xpos-m_last_x:0))*sc; - precmode=1; - } - else - { - pos=m_minr+ (((double)(viewh-bm_h - ypos + m_move_offset)*(double)rsize)/(double)(viewh-bm_h)); - } - if (pos < m_minr)pos=m_minr; - else if (pos > m_maxr)pos=m_maxr; - - - if (pos != m_pos || isup) - { - if (ypos == m_last_y&&(m_is_knob && xpos==m_last_x)) - pos=m_pos; - - if ((GetAsyncKeyState(VK_MENU)&0x8000) && isup) - pos=m_click_pos; - - m_pos=pos; - - if (isup || ypos != m_last_y||(m_is_knob&&xpos!=m_last_x)) - { - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,isup?SB_ENDSCROLL:SB_THUMBTRACK,GetID(),this); - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - } - } - } - else - { -#ifndef _WIN32 - if (isup) pos=m_pos; - else -#endif - if ((GetAsyncKeyState(VK_CONTROL)&0x8000) || vieww <= bm_w || m_is_knob) - { - pos = m_pos+ (xpos-m_last_x); - precmode=1; - } - else - { - pos=m_minr + (((double)(xpos - m_move_offset)*(double)rsize)/(double)(vieww-bm_w)); - } - if (pos < m_minr)pos=m_minr; - else if (pos > m_maxr)pos=m_maxr; - - if (pos != m_pos || isup) - { - if (xpos == m_last_x) - pos=m_pos; - - if ((GetAsyncKeyState(VK_MENU)&0x8000) && isup) - pos=m_click_pos; - - m_pos=pos; - - if (isup || xpos != m_last_x) - { - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:WM_HSCROLL,isup?SB_ENDSCROLL:SB_THUMBTRACK,GetID(),this); - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - } - } - } - if (precmode&&GetRealParent()) - { - if (xpos != m_last_x || ypos != m_last_y) - { - POINT p; - GetCursorPos(&p); - p.x-=(xpos-m_last_x); -#ifdef _WIN32 - p.y-=(ypos-m_last_y); -#else - p.y+=(ypos-m_last_y); -#endif - - - #ifdef _WIN32 - if (!m_is_knob) - { - POINT pt={0,0}; - ClientToScreen(GetRealParent(),&pt); - WDL_VWnd *wnd=this; - while (wnd) - { - RECT r; - wnd->GetPosition(&r); - pt.x+=r.left; - pt.y+=r.top; - wnd=wnd->GetParent(); - } - - if (isVert) - { - m_last_y=( viewh - bm_h - (((m_pos-m_minr) * (viewh-bm_h))/rsize))+m_move_offset; - p.y=m_last_y+pt.y; - } - else - { - m_last_x=( (((m_pos-m_minr) * (vieww-bm_w))/rsize))+m_move_offset; - p.x=m_last_x+pt.x; - } - } - #endif - - if (!SetCursorPos(p.x,p.y)) - { - m_last_y = ypos; - m_last_x = xpos; - } - } - do m_last_precmode++; while (ShowCursor(FALSE)>=0); - } - else - { - m_last_y=ypos; - m_last_x=xpos; - while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } - } - m_needflush=0; -} - -void WDL_VirtualSlider::OnMouseMove(int xpos, int ypos) -{ - if (m_grayed) return; - - if (m_captured) OnMoveOrUp(xpos,ypos,0); - else if (m_needflush && (xpos <0 || xpos > m_position.right- m_position.left || ypos < 0|| ypos > m_position.bottom-m_position.top )) - { - bool isVert = GetIsVert(); - m_needflush=0; - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_ENDSCROLL,GetID(),this); - if (chk.isOK() && m__iaccess) m__iaccess->OnStateChange(); - } -} - -void WDL_VirtualSlider::OnCaptureLost() -{ - m_captured=false; - while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } -} - -void WDL_VirtualSlider::OnMouseUp(int xpos, int ypos) -{ - if (m_grayed) return; - - if (m_captured) - { - OnMoveOrUp(xpos,ypos,1); - while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } - } - m_captured=false; -} - -bool WDL_VirtualSlider::OnMouseDblClick(int xpos, int ypos) -{ - if (m_grayed) return false; - - if (m_dblclickmsg) - { - SendCommand(m_dblclickmsg, 0, 0, this); - return true; - } - - bool isVert = GetIsVert(); - int pos=m_center; - if (pos < 0) pos=WDL_STYLE_GetSliderDynamicCenterPos(); - m_pos=pos; - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_ENDSCROLL,GetID(),this); - - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - - m_captured=false; - return true; -} - -bool WDL_VirtualSlider::OnMouseWheel(int xpos, int ypos, int amt) -{ - if (m_grayed) return false; - - if (!WDL_STYLE_AllowSliderMouseWheel()) return false; - - bool isVert = GetIsVert(); - int l=amt; - if (!(GetAsyncKeyState(VK_CONTROL)&0x8000)) l *= 16; - l *= (m_maxr-m_minr); - l/=120000; - if (!l) { if (amt<0)l=-1; else if (amt>0) l=1; } - - int pos=m_pos+l; - if (pos < m_minr)pos=m_minr; - else if (pos > m_maxr)pos=m_maxr; - - m_pos=pos; - - m_needflush=1; - WDL_VWND_DCHK(chk); - SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_THUMBTRACK,GetID(),this); - - if (chk.isOK()) - { - RequestRedraw(NULL); - if (m__iaccess) m__iaccess->OnStateChange(); - } - return true; -} - - - - -int WDL_VirtualSlider::GetSliderPosition() -{ - if (m_pos < m_minr) return m_minr; - if (m_pos > m_maxr) return m_maxr; - return m_pos; -} - -void WDL_VirtualSlider::SetSliderPosition(int pos) -{ - if (!m_captured) - { - if (pos < m_minr) pos=m_minr; - else if (pos>m_maxr) pos=m_maxr; - - if (pos != m_pos) - { - m_pos=pos; - RequestRedraw(NULL); - } - } -} - -void WDL_VirtualSlider::GetPositionPaintExtent(RECT *r) -{ - *r=m_position; - bool isVert=GetIsVert(); - bool wantKnob=m_knobbias > 0; - LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; - if (!bm_image && !wantKnob) - { - bm_image=WDL_STYLE_GetSliderBitmap2(isVert); - } - if (bm_image && !wantKnob) - { - int bm_w=bm_image->getWidth(); - int bm_h=bm_image->getHeight(); - int s=0; - int bm_w2=bm_w; - int bm_h2=bm_h; - AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,m_skininfo,isVert,&bm_w,&bm_h,&s,&wantKnob,m_knobbias); - - if (!wantKnob) - { - int rsize=m_maxr-m_minr; - int viewh=m_position.bottom-m_position.top; - int vieww=m_position.right-m_position.left; - - if (isVert) - { - if (bm_w > vieww) - { - r->left-=(bm_w-vieww)/2+1; - r->right+=(bm_w-vieww)/2+1; - } - - int tadj=m_tl_extra; - int badj=m_br_extra; - - int pos = viewh - bm_h - ((m_pos-m_minr) * (viewh - bm_h))/rsize-s; - - if (-pos > tadj) tadj=-pos; - if (pos+bm_h2 > viewh+badj) badj=pos+bm_h2-viewh; - - //m_tl_extra=m_br_extra= - r->top-=tadj; //s; - r->bottom += badj; //(bm_h2-bm_h)-s; - } - else - { - if (bm_h > viewh) - { - r->top-=(bm_h-viewh)/2+1; - r->bottom+=(bm_h-viewh)/2+1; - } - - int ladj=m_tl_extra; - int radj=m_br_extra; - - int pos = ((m_pos-m_minr) * (vieww - bm_w))/rsize - s; - - if (-pos > ladj) ladj=-pos; - if (pos+bm_w2 > vieww+radj) radj=pos+bm_w2-vieww; - - r->left-=ladj; //s; - r->right += radj; // (bm_w2-bm_w)-s; - } - } - } - - if (wantKnob) - { - const int viewh=m_position.bottom-m_position.top; - const int vieww=m_position.right-m_position.left; - { - int sz= min(vieww,viewh); - int ox = m_position.left + (vieww-sz)/2; - int oy = m_position.top + (viewh-sz)/2; - - WDL_VirtualWnd_BGCfg *back_image = m_knobbg[sz>28]; - if (back_image && back_image->bgimage && - back_image->bgimage_lt_out[0]>0 && - back_image->bgimage_lt_out[1]>0 && - back_image->bgimage_rb_out[0]>0 && - back_image->bgimage_rb_out[1]>0) - { - int tmp = ox - (back_image->bgimage_lt_out[0]-1); - if (tmp < r->left) r->left=tmp; - tmp = oy - (back_image->bgimage_lt_out[1]-1); - if (tmp < r->top) r->top=tmp; - tmp = ox+sz+(back_image->bgimage_rb_out[0]-1); - if (tmp > r->right) r->right = tmp; - tmp = oy+sz+(back_image->bgimage_rb_out[1]-1); - if (tmp > r->bottom) r->bottom = tmp; - } - } - - { - int kvw = vieww, kvh=viewh; - int ksw=0,ksh=0,kso=0; - WDL_VirtualWnd_BGCfg *knobimage=vwnd_slider_getknobimageforsize(m_knobstacks,m_nknobstacks,&kvw,&kvh,&ksw,&ksh,&kso); - - if (knobimage && kso && ksw>0 && ksh>0 && - knobimage->bgimage_lt_out[0] > 0 && - knobimage->bgimage_lt_out[1] > 0 && - knobimage->bgimage_rb_out[0] > 0 && - knobimage->bgimage_rb_out[1] > 0) - { - const int ox = m_position.left + (vieww - kvw)/2; - const int oy = m_position.top + (viewh - kvh)/2; - - int ww = ksw - (knobimage->bgimage_lt_out[0]-1) - (knobimage->bgimage_rb_out[0]-1); - int wh = ksh - (knobimage->bgimage_lt_out[1]-1) - (knobimage->bgimage_rb_out[1]-1); - - if (ww > 0) - { - int tmp = ox - (kvw * (knobimage->bgimage_lt_out[0]-1))/ww; - if (tmp < r->left) r->left=tmp; - tmp = ox + kvw + (kvw * (knobimage->bgimage_rb_out[0]-1))/ww; - if (tmp > r->right) r->right=tmp; - } - if (wh > 0) - { - int tmp = oy - (kvh * (knobimage->bgimage_lt_out[1]-1))/wh; - if (tmp < r->top) r->top=tmp; - tmp = oy + kvh + (kvh * (knobimage->bgimage_rb_out[1]-1))/wh; - if (tmp > r->bottom) r->bottom=tmp; - } - } - } - } - else if (m_skininfo && m_skininfo->bgimagecfg[isVert].bgimage) - { - // expand paintextent by background image outer extent if necessary - WDL_VirtualWnd_BGCfg *b = &m_skininfo->bgimagecfg[isVert]; - if (b->bgimage_lt[0]>0 && - b->bgimage_lt[1]>0 && - b->bgimage_rb[0]>0 && - b->bgimage_rb[1]>0 && - b->bgimage_lt_out[0]>0 && - b->bgimage_lt_out[1]>0 && - b->bgimage_rb_out[0]>0 && - b->bgimage_rb_out[1]>0) - { - int l = m_position.left - (b->bgimage_lt_out[0]-1); - int t = m_position.top - (b->bgimage_lt_out[1]-1); - int right = m_position.right + b->bgimage_rb_out[0]-1; - int bot = m_position.bottom + b->bgimage_rb_out[1]-1; - - if (l < r->left) r->left=l; - if (t < r->top) r->top=t; - if (right > r->right) r->right = right; - if (bot > r->bottom) r->bottom = bot; - } - } -} diff --git a/WDL/wingui/virtwnd.cpp b/WDL/wingui/virtwnd.cpp deleted file mode 100644 index 21d3850e..00000000 --- a/WDL/wingui/virtwnd.cpp +++ /dev/null @@ -1,1635 +0,0 @@ -/* - WDL - virtwnd.cpp - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - Implementation for basic virtual window types. - -*/ - -#include "virtwnd-controls.h" -#include "../lice/lice.h" -#include "../assocarray.h" - -WDL_VWnd_Painter::WDL_VWnd_Painter() -{ - m_GSC=0; - m_bm=0; - m_bgbm=0; - - m_paint_xorig=m_paint_yorig=0; - m_cur_hwnd=0; - m_wantg=-1; - m_gradstart=0.5; - m_gradslope=0.2; - m_bgcache=0; -} - -WDL_VWnd_Painter::~WDL_VWnd_Painter() -{ - delete m_bm; -} - -void WDL_VWnd_Painter::SetGSC(int (*GSC)(int)) -{ - m_GSC=GSC; -} -int WDL_VWnd_Painter::GSC(int a) -{ - if (m_GSC) return m_GSC(a); - return GetSysColor(a); -} - -void WDL_VWnd_Painter::SetBGGradient(int wantGradient, double start, double slope) -{ - m_wantg=wantGradient; - m_gradstart=start; - m_gradslope=slope; -} - -void WDL_VWnd_Painter::DoPaintBackground(LICE_IBitmap *bmOut, int bgcolor, const RECT *clipr, int wnd_w, int wnd_h, int xoffs, int yoffs) -{ - if (!bmOut) return; - - if (m_bgbm&&m_bgbm->bgimage) - { - int srcw=m_bgbm->bgimage->getWidth(); - int srch=m_bgbm->bgimage->getHeight(); - if (srcw && srch) - { - int fflags=0; - if (srcw < wnd_w/4 || srch < wnd_h/4) - fflags|=LICE_BLIT_FILTER_BILINEAR; - - - if (m_bgcache && !xoffs && !yoffs) - { - LICE_IBitmap *tmp = m_bgcache->GetCachedBG(wnd_w,wnd_h,this,m_bgbm->bgimage); - if (tmp) - { -// OutputDebugString("got cached render\n"); - LICE_Blit(bmOut,tmp,clipr->left,clipr->top,clipr->left,clipr->top,clipr->right-clipr->left,clipr->bottom-clipr->top,1.0f,LICE_BLIT_MODE_COPY); - } - else - { -// char bf[4096]; -// sprintf(bf,"fail %d,%d %08x\n",wnd_w,wnd_h,m_bgbm->bgimage); -// OutputDebugString(bf); - WDL_VirtualWnd_ScaledBlitBG(bmOut,m_bgbm,0,0,wnd_w,wnd_h, - 0,0, - wnd_w, - wnd_h, - 1.0,LICE_BLIT_MODE_COPY|fflags); - m_bgcache->SetCachedBG(wnd_w,wnd_h,bmOut,this,m_bgbm->bgimage); - } - } - else - { - WDL_VirtualWnd_ScaledBlitBG(bmOut,m_bgbm,xoffs,yoffs,wnd_w,wnd_h, - clipr->left+xoffs,clipr->top+yoffs, - clipr->right-clipr->left, - clipr->bottom-clipr->top, - 1.0,LICE_BLIT_MODE_COPY|fflags); - } - - tintRect(bmOut,clipr,xoffs,yoffs); - - m_bgbm=0; - return; - } - } - - if (bgcolor<0) bgcolor=m_GSC?m_GSC(COLOR_3DFACE):GetSysColor(COLOR_3DFACE); - - double gradslope=m_gradslope; - double gradstart=m_gradstart; - bool wantGrad=m_wantg>0; - if (m_wantg<0) wantGrad=WDL_STYLE_GetBackgroundGradient(&gradstart,&gradslope); - - int needfill=1; - - if (wantGrad && gradslope >= 0.01) - { - - { - needfill=0; - - int spos = (int) (gradstart * wnd_h); - if (spos > 0) - { - if (spos > wnd_h) spos=wnd_h; - if (clipr->top < spos) - { - LICE_FillRect(bmOut,clipr->left+xoffs,clipr->top+yoffs, - clipr->right-clipr->left,spos-clipr->top, - LICE_RGBA_FROMNATIVE(bgcolor,255),1.0f,LICE_BLIT_MODE_COPY); - } - } - else spos=0; - - if (spos < wnd_h) - { - struct - { - int x,y,Red,Green,Blue; - } - vert[2]={{0,},}; - - double sr=GetRValue(bgcolor); - double sg=GetGValue(bgcolor); - double sb=GetBValue(bgcolor); - - vert [0] .x = clipr->left; - vert [1] .x = clipr->right; - - - vert[0].y=clipr->top; - vert[1].y=clipr->bottom; - - if (vert[0].y < spos) vert[0].y=spos; - if (vert[1].y>wnd_h) vert[1].y=wnd_h; - - wnd_h-=spos; - - int x; - for (x =0 ; x < 2; x ++) - { - double sc1=(wnd_h-(vert[x].y-spos)*gradslope)/(double)wnd_h * 256.0; - - vert[x].Red = (int) (sr * sc1); - vert[x].Green = (int) (sg * sc1); - vert[x].Blue = (int) (sb * sc1); - } - - { - - int bmh=vert[1].y-vert[0].y; - float s=(float) (1.0/(65535.0*bmh)); - - LICE_GradRect(bmOut,vert[0].x+xoffs,vert[0].y+yoffs,clipr->right-clipr->left,bmh, - vert[0].Red/65535.0f,vert[0].Green/65535.0f,vert[0].Blue/65535.0f,1.0,0,0,0,0, - (vert[1].Red-vert[0].Red)*s, - (vert[1].Green-vert[0].Green)*s, - (vert[1].Blue-vert[0].Blue)*s, - 0.0,LICE_BLIT_MODE_COPY); - } - } - } - } - - - - if (needfill) - { - LICE_FillRect(bmOut,clipr->left+xoffs, - clipr->top+yoffs, - clipr->right-clipr->left, - clipr->bottom-clipr->top,LICE_RGBA_FROMNATIVE(bgcolor,255),1.0f,LICE_BLIT_MODE_COPY); - } - -} - -void WDL_VWnd_Painter::PaintBegin(HWND hwnd, int bgcolor, const RECT *limitBGrect, const RECT *windowRect) -{ - if (!hwnd) return; - if (!m_cur_hwnd) - { - if (BeginPaint(hwnd,&m_ps)) - { - m_cur_hwnd=hwnd; - } - if (m_cur_hwnd) - { - RECT r; - if (windowRect) r=*windowRect; - else GetClientRect(m_cur_hwnd,&r); - int fwnd_w=r.right-r.left,fwnd_h=r.bottom-r.top; - if (fwnd_h<0)fwnd_h=-fwnd_h; - - int wnd_w,wnd_h; - - if (fwnd_w < 2048 && fwnd_h < 2048) - { - m_paint_xorig=m_paint_yorig=0; - wnd_w=fwnd_w; - wnd_h=fwnd_h; - } - else // alternate large canvas mode - { - m_bgcache=0; // force no caching in large canvas mode - - // note: there can be some slight background artifacts in this mode that need to be resolved (REAPER TCP bg bottom line on partial redraw etc) - m_paint_xorig=m_ps.rcPaint.left; - m_paint_yorig=m_ps.rcPaint.top; - wnd_w = m_ps.rcPaint.right-m_ps.rcPaint.left; - wnd_h = m_ps.rcPaint.bottom - m_ps.rcPaint.top; - } - - if (wnd_h<0)wnd_h=-wnd_h; - - if (!m_bm) m_bm=new LICE_SysBitmap; - - if (m_bm->getWidth()getHeight() < wnd_h) - { - m_bm->resize(max(m_bm->getWidth(),wnd_w),max(m_bm->getHeight(),wnd_h)); - } - - if (!limitBGrect || (limitBGrect->left <1 && limitBGrect->top < 1 && limitBGrect->right >= fwnd_w && limitBGrect->bottom >= fwnd_h)) - { - DoPaintBackground(m_bm,bgcolor,&m_ps.rcPaint, fwnd_w, fwnd_h, -m_paint_xorig, -m_paint_yorig); - } - else - { - RECT tr = m_ps.rcPaint; - if (tr.left < limitBGrect->left) tr.left = limitBGrect->left; - if (tr.top < limitBGrect->top) tr.top = limitBGrect->top; - if (tr.right > limitBGrect->right) tr.right = limitBGrect->right; - if (tr.bottom > limitBGrect->bottom) tr.bottom = limitBGrect->bottom; - - if (tr.left < tr.right && tr.top < tr.bottom) - { - int w=limitBGrect->right-limitBGrect->left; - int h=limitBGrect->bottom-limitBGrect->top; - - int x=limitBGrect->left - m_paint_xorig; - int y=limitBGrect->top - m_paint_yorig; - LICE_SubBitmap bm(m_bm,x,y,w,h); - tr.left -= max(x,0); - tr.right -= max(x,0); - tr.bottom -= max(y,0); - tr.top -= max(y,0); - DoPaintBackground(&bm,bgcolor,&tr, w,h,-m_paint_xorig + min(x,0), -m_paint_yorig + min(y,0)); - } - } - } - } -} - - -#ifdef _WIN32 -typedef struct -{ - HRGN rgn; - HWND par; - RECT *sr; -} enumInfo; - -static BOOL CALLBACK enumProc(HWND hwnd,LPARAM lParam) -{ - enumInfo *p=(enumInfo*)lParam; - if (IsWindowVisible(hwnd)) - { - RECT r; - GetWindowRect(hwnd,&r); - ScreenToClient(p->par,(LPPOINT)&r); - ScreenToClient(p->par,((LPPOINT)&r)+1); - if (!p->rgn) p->rgn=CreateRectRgnIndirect(p->sr); - - HRGN rgn2=CreateRectRgnIndirect(&r); - CombineRgn(p->rgn,p->rgn,rgn2,RGN_DIFF); - DeleteObject(rgn2); - } - return TRUE; -} -#endif - -void WDL_VWnd_Painter::PaintEnd() -{ - if (!m_cur_hwnd) return; - if (m_bm) - { -#ifdef _WIN32 - HRGN rgnsave=0; - if (1) - { - enumInfo a={0,m_cur_hwnd,&m_ps.rcPaint}; - EnumChildWindows(m_cur_hwnd,enumProc,(LPARAM)&a); - if (a.rgn) - { - rgnsave=CreateRectRgn(0,0,0,0); - GetClipRgn(m_ps.hdc,rgnsave); - - ExtSelectClipRgn(m_ps.hdc,a.rgn,RGN_AND); - DeleteObject(a.rgn); - } - } - BitBlt(m_ps.hdc,m_ps.rcPaint.left,m_ps.rcPaint.top, - m_ps.rcPaint.right-m_ps.rcPaint.left, - m_ps.rcPaint.bottom-m_ps.rcPaint.top, - m_bm->getDC(),m_ps.rcPaint.left-m_paint_xorig,m_ps.rcPaint.top-m_paint_yorig,SRCCOPY); - - if (rgnsave) - { - SelectClipRgn(m_ps.hdc,rgnsave); - DeleteObject(rgnsave); - } -#else - SWELL_SyncCtxFrameBuffer(m_bm->getDC()); - BitBlt(m_ps.hdc,m_ps.rcPaint.left,m_ps.rcPaint.top, - m_ps.rcPaint.right-m_ps.rcPaint.left, - m_ps.rcPaint.bottom-m_ps.rcPaint.top, - m_bm->getDC(),m_ps.rcPaint.left-m_paint_xorig,m_ps.rcPaint.top-m_paint_yorig,SRCCOPY); -#endif - } - EndPaint(m_cur_hwnd,&m_ps); - m_cur_hwnd=0; -} - -void WDL_VWnd_Painter::GetPaintInfo(RECT *rclip, int *xoffsdraw, int *yoffsdraw) -{ - if (rclip) *rclip = m_ps.rcPaint; - if (xoffsdraw) *xoffsdraw = -m_paint_xorig; - if (yoffsdraw) *yoffsdraw = -m_paint_yorig; -} - -void WDL_VWnd_Painter::tintRect(LICE_IBitmap *bmOut, const RECT *clipr, int xoffs, int yoffs) -{ - if (m_bgbmtintcolor>=0) - { - float rv=GetRValue(m_bgbmtintcolor)/255.0f; - float gv=GetGValue(m_bgbmtintcolor)/255.0f; - float bv=GetBValue(m_bgbmtintcolor)/255.0f; - - float avg=(rv+gv+bv)*0.33333f; - if (avg<0.05f)avg=0.05f; - - float sc=0.5f; - float sc2 = (1.0f-sc)/avg; - - float sc3=32.0f; - float sc4=64.0f*(avg-0.5f); - // tint - LICE_MultiplyAddRect(bmOut,clipr->left+xoffs,clipr->top+yoffs,clipr->right-clipr->left,clipr->bottom-clipr->top, - sc+rv*sc2,sc+gv*sc2,sc+bv*sc2,1, - (rv-avg)*sc3+sc4, - (gv-avg)*sc3+sc4, - (bv-avg)*sc3+sc4, - 0); - } -} - - -void WDL_VWnd_Painter::PaintBGCfg(WDL_VirtualWnd_BGCfg *bitmap, const RECT *coords, bool allowTint, float alpha, int mode) -{ - if (!bitmap || !coords || !bitmap->bgimage || !m_bm) return; - - - WDL_VirtualWnd_ScaledBlitBG(m_bm,bitmap,coords->left - m_paint_xorig, - coords->top - m_paint_yorig, - coords->right-coords->left, - coords->bottom-coords->top, - m_ps.rcPaint.left - m_paint_xorig, - m_ps.rcPaint.top - m_paint_yorig, - m_ps.rcPaint.right - m_ps.rcPaint.left, - m_ps.rcPaint.bottom - m_ps.rcPaint.top,alpha,mode); - - if (allowTint) - { - RECT rr={ - max(coords->left,m_ps.rcPaint.left), - max(coords->top,m_ps.rcPaint.top), - min(coords->right,m_ps.rcPaint.right), - min(coords->bottom,m_ps.rcPaint.bottom) - }; - - if (rr.right>rr.left && rr.bottom>rr.top) - tintRect(m_bm,&rr,-m_paint_xorig,-m_paint_yorig); - } - -} - -void WDL_VWnd_Painter::PaintVirtWnd(WDL_VWnd *vwnd, int borderflags) -{ - RECT tr=m_ps.rcPaint; - if (!m_bm||!m_cur_hwnd|| !vwnd->IsVisible()) return; - - RECT r; - vwnd->GetPosition(&r); // maybe should use GetPositionPaintExtent or GetPositionPaintOverExtent ? - - if (tr.leftr.right) tr.right=r.right; - if (tr.topr.bottom)tr.bottom=r.bottom; - - if (tr.bottom > tr.top && tr.right > tr.left) - { - tr.left -= m_paint_xorig; - tr.right -= m_paint_xorig; - tr.top -= m_paint_yorig; - tr.bottom -= m_paint_yorig; - vwnd->SetCurPainter(this); - vwnd->OnPaint(m_bm,-m_paint_xorig,-m_paint_yorig,&tr); - if (borderflags) - { - PaintBorderForRect(&r,borderflags); - } - if (vwnd->WantsPaintOver()) vwnd->OnPaintOver(m_bm,-m_paint_xorig,-m_paint_yorig,&tr); - vwnd->SetCurPainter(NULL); - - } -} - -void WDL_VWnd_Painter::PaintBorderForHWND(HWND hwnd, int borderflags) -{ -#ifdef _WIN32 - if (m_cur_hwnd) - { - RECT r; - GetWindowRect(hwnd,&r); - ScreenToClient(m_cur_hwnd,(LPPOINT)&r); - ScreenToClient(m_cur_hwnd,((LPPOINT)&r)+1); - PaintBorderForRect(&r,borderflags); - } -#endif -} - -void WDL_VWnd_Painter::PaintBorderForRect(const RECT *r, int borderflags) -{ - if (!m_bm|| !m_cur_hwnd||!borderflags) return; - RECT rrr = *r; - rrr.left-=m_paint_xorig; - rrr.right-=m_paint_xorig; - rrr.top-=m_paint_yorig; - rrr.bottom-=m_paint_yorig; - - LICE_pixel pencol = m_GSC?m_GSC(COLOR_3DHILIGHT):GetSysColor(COLOR_3DHILIGHT); - LICE_pixel pencol2 = m_GSC?m_GSC(COLOR_3DSHADOW):GetSysColor(COLOR_3DSHADOW); - pencol = LICE_RGBA_FROMNATIVE(pencol,255); - pencol2 = LICE_RGBA_FROMNATIVE(pencol2,255); - - if (borderflags== WDL_VWP_SUNKENBORDER || borderflags == WDL_VWP_SUNKENBORDER_NOTOP) - { - LICE_Line(m_bm,rrr.left-1,rrr.bottom,rrr.right,rrr.bottom,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(m_bm,rrr.right,rrr.bottom,rrr.right,rrr.top-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - - if (borderflags != WDL_VWP_SUNKENBORDER_NOTOP) - LICE_Line(m_bm,rrr.right,rrr.top-1,rrr.left-1,rrr.top-1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - - LICE_Line(m_bm,rrr.left-1,rrr.top-1,rrr.left-1,rrr.bottom,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - } - else if (borderflags == WDL_VWP_DIVIDER_VERT) // vertical - { - int left=rrr.left; - - LICE_Line(m_bm,left,rrr.top,left,rrr.bottom+1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(m_bm,left+1,rrr.top,left+1,rrr.bottom+1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - } - else if (borderflags == WDL_VWP_DIVIDER_HORZ) - { - int top=rrr.top+1; - LICE_Line(m_bm,rrr.left,top,rrr.right+1,top,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); - LICE_Line(m_bm,rrr.left,top+1,rrr.right+1,top+1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); - } -} - -WDL_VWnd::WDL_VWnd() -{ - m__iaccess=0; - m__iaccess_desc=0; - m_visible=true; m_id=0; - m_position.left=0; m_position.top=0; m_position.right=0; m_position.bottom=0; - m_parent=0; - m_children=0; - m_realparent=0; - m_captureidx=-1; - m_lastmouseidx=-1; - m_userdata=0; - m_curPainter=0; -} - -WDL_VWnd::~WDL_VWnd() -{ - if (m_children) - { - m_children->Empty(true); - delete m_children; - } - if (m__iaccess) m__iaccess->Release(); -} - -int WDL_VWnd::GSC(int a) -{ - return m_curPainter ? m_curPainter->GSC(a) : GetSysColor(a); -} - -INT_PTR WDL_VWnd::SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src) -{ - if (m_realparent) - { - return SendMessage(m_realparent,command,parm1,parm2); - } - else if (m_parent) return m_parent->SendCommand(command,parm1,parm2,src); - return 0; -} - -void WDL_VWnd::RequestRedraw(RECT *r) -{ - if (!IsVisible() || - m_position.right <= m_position.left || - m_position.bottom <= m_position.top) return; - - RECT r2; - - if (r) - { - r2=*r; - r2.left+=m_position.left; r2.right += m_position.left; - r2.top += m_position.top; r2.bottom += m_position.top; - } - else - { - GetPositionPaintExtent(&r2); - RECT r3; - if (WantsPaintOver()) - { - GetPositionPaintOverExtent(&r3); - if (r3.leftr2.right)r2.right=r3.right; - if (r3.bottom>r2.bottom)r2.bottom=r3.bottom; - } - } - - if (m_realparent) - { -#ifdef _WIN32 - HWND hCh; - if ((hCh=GetWindow(m_realparent,GW_CHILD))) - { - HRGN rgn=CreateRectRgnIndirect(&r2); - int n=30; // limit to 30 children - while (n-- && hCh) - { - if (IsWindowVisible(hCh)) - { - RECT r; - GetWindowRect(hCh,&r); - ScreenToClient(m_realparent,(LPPOINT)&r); - ScreenToClient(m_realparent,((LPPOINT)&r)+1); - HRGN tmprgn=CreateRectRgn(r.left,r.top,r.right,r.bottom); - CombineRgn(rgn,rgn,tmprgn,RGN_DIFF); - DeleteObject(tmprgn); - } - hCh=GetWindow(hCh,GW_HWNDNEXT); - } - InvalidateRgn(m_realparent,rgn,FALSE); - DeleteObject(rgn); - - } - else -#else - // OS X, expand region up slightly - r2.top--; -#endif - InvalidateRect(m_realparent,&r2,FALSE); - } - else if (m_parent) m_parent->RequestRedraw(&r2); -} - -bool WDL_VWnd::IsDescendent(WDL_VWnd *w) -{ - if (!w || !m_children) return false; - int x,n=m_children->GetSize(); - for(x=0;xGet(x) == w) return true; - for(x=0;xGet(x); - if (tmp && tmp->IsDescendent(w)) return true; - } - return false; -} - -void WDL_VWnd::SetChildPosition(WDL_VWnd *ch, int pos) -{ - if (!ch || !m_children) return; - int x; - for(x=0;xGetSize();x++) - { - if (m_children->Get(x) == ch) - { - if (pos>x) pos--; - if (pos != x) - { - m_children->Delete(x); - m_children->Insert(pos,ch); - } - return; - } - } -} - - -void WDL_VWnd::AddChild(WDL_VWnd *wnd, int pos) -{ - if (!wnd) return; - - wnd->SetParent(this); - if (!m_children) m_children=new WDL_PtrList; - if (pos<0||pos>=m_children->GetSize()) m_children->Add(wnd); - else m_children->Insert(pos,wnd); - if (m__iaccess) m__iaccess->ClearCaches(); -} - -WDL_VWnd *WDL_VWnd::GetChildByID(int id) -{ - if (m_children) - { - int x; - for (x = 0; x < m_children->GetSize(); x ++) - if (m_children->Get(x)->GetID()==id) return m_children->Get(x); - WDL_VWnd *r; - for (x = 0; x < m_children->GetSize(); x ++) if ((r=m_children->Get(x)->GetChildByID(id))) return r; - } - - return 0; -} - -void WDL_VWnd::RemoveChild(WDL_VWnd *wnd, bool dodel) -{ - int idx=m_children ? m_children->Find(wnd) : -1; - if (idx>=0) - { - if (!dodel) - { - WDL_VWnd *ch = m_children->Get(idx); - if (ch) ch->SetParent(NULL); - } - m_children->Delete(idx,dodel); - } - if (m__iaccess) m__iaccess->ClearCaches(); -} - - -void WDL_VWnd::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - int x; - if (m_children) for (x = m_children->GetSize()-1; x >=0; x --) - { - WDL_VWnd *ch=m_children->Get(x); - if (ch->IsVisible()) - { - RECT re; - ch->GetPosition(&re); - if (re.right>re.left&&re.bottom>re.top) - { - ch->GetPositionPaintExtent(&re); - re.left += origin_x + m_position.left; - re.right += origin_x + m_position.left; - re.top += origin_y + m_position.top; - re.bottom += origin_y + m_position.top; - - RECT cr=*cliprect; - if (cr.left < re.left) cr.left=re.left; - if (cr.right > re.right) cr.right=re.right; - if (cr.top < re.top) cr.top=re.top; - if (cr.bottom > re.bottom) cr.bottom=re.bottom; - - if (cr.left < cr.right && cr.top < cr.bottom) - { - ch->SetCurPainter(m_curPainter); - ch->OnPaint(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr); - ch->SetCurPainter(NULL); - } - } - } - } -} - -void WDL_VWnd::OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) -{ - int x; - if (m_children) for (x = m_children->GetSize()-1; x >=0; x --) - { - WDL_VWnd *ch=m_children->Get(x); - if (ch->IsVisible() && ch->WantsPaintOver()) - { - RECT re; - ch->GetPosition(&re); - if (re.right>re.left && re.bottom > re.top) - { - ch->GetPositionPaintOverExtent(&re); - re.left += origin_x + m_position.left; - re.right += origin_x + m_position.left; - re.top += origin_y + m_position.top; - re.bottom += origin_y + m_position.top; - - RECT cr=*cliprect; - - if (cr.left < re.left) cr.left=re.left; - if (cr.right > re.right) cr.right=re.right; - if (cr.top < re.top) cr.top=re.top; - if (cr.bottom > re.bottom) cr.bottom=re.bottom; - - if (cr.left < cr.right && cr.top < cr.bottom) - { - ch->SetCurPainter(m_curPainter); - ch->OnPaintOver(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr); - ch->SetCurPainter(NULL); - } - } - } - } -} - -int WDL_VWnd::GetNumChildren() -{ - return m_children ? m_children->GetSize() : 0; -} -WDL_VWnd *WDL_VWnd::EnumChildren(int x) -{ - return m_children ? m_children->Get(x) : 0; -} - -void WDL_VWnd::RemoveAllChildren(bool dodel) -{ - if (m_children) - { - if (!dodel) // update parent pointers - { - int x; - for (x = 0; x < m_children->GetSize(); x++) - { - WDL_VWnd *ch = m_children->Get(x); - if (ch) ch->SetParent(NULL); - } - } - m_children->Empty(dodel); - } -} - -WDL_VWnd *WDL_VWnd::VirtWndFromPoint(int xpos, int ypos, int maxdepth) -{ - int x; - if (m_children) for (x = 0; x < m_children->GetSize(); x++) - { - WDL_VWnd *wnd=m_children->Get(x); - if (wnd->IsVisible()) - { - RECT r; - wnd->GetPosition(&r); - if (xpos >= r.left && xpos < r.right && ypos >= r.top && ypos < r.bottom) - { - if (maxdepth!=0) - { - WDL_VWnd *cwnd=wnd->VirtWndFromPoint(xpos-r.left,ypos-r.top,maxdepth > 0 ? (maxdepth-1) : -1); - if (cwnd) return cwnd; - } - return wnd; - } - } - } - return 0; - -} - - -int WDL_VWnd::OnMouseDown(int xpos, int ypos) // returns TRUE if handled -{ - if (!m_children) return 0; - - WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); - if (!wnd) - { - m_captureidx=-1; - return 0; - } - RECT r; - wnd->GetPosition(&r); - WDL_VWND_DCHK(chk); - int a; - if ((a=wnd->OnMouseDown(xpos-r.left,ypos-r.top))) - { - if (a<0) return -1; - if (chk.isOK()) m_captureidx=m_children->Find(wnd); - return 1; - } - return 0; -} - -bool WDL_VWnd::OnMouseDblClick(int xpos, int ypos) // returns TRUE if handled -{ - WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); - if (!wnd) return false; - RECT r; - wnd->GetPosition(&r); - return wnd->OnMouseDblClick(xpos-r.left,ypos-r.top); -} - - -bool WDL_VWnd::OnMouseWheel(int xpos, int ypos, int amt) -{ - WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); - if (!wnd) return false; - RECT r; - wnd->GetPosition(&r); - return wnd->OnMouseWheel(xpos-r.left,ypos-r.top,amt); -} - - -bool WDL_VWnd::GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz) -{ - WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); - if (!wnd) return false; - - RECT r; - wnd->GetPosition(&r); - return wnd->GetToolTipString(xpos-r.left,ypos-r.top,bufOut,bufOutSz); -} - -int WDL_VWnd::UpdateCursor(int xpos, int ypos) -{ - WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); - if (!wnd) return 0; - - RECT r; - wnd->GetPosition(&r); - return wnd->UpdateCursor(xpos-r.left,ypos-r.top); -} - -void WDL_VWnd::OnMouseMove(int xpos, int ypos) -{ - if (!m_children) return; - - WDL_VWnd *wnd=m_children->Get(m_captureidx); - - WDL_VWND_DCHK(chk); - if (!wnd) - { - wnd=VirtWndFromPoint(xpos,ypos,0); - if (wnd) // todo: stuff so if the mouse goes out of the window completely, the virtualwnd gets notified - { - int idx=m_children->Find(wnd); - if (idx != m_lastmouseidx) - { - WDL_VWnd *t=m_children->Get(m_lastmouseidx); - if (t) - { - RECT r; - t->GetPosition(&r); - t->OnMouseMove(xpos-r.left,ypos-r.top); - } - if (chk.isOK()) m_lastmouseidx=idx; - } - } - else - { - WDL_VWnd *t=m_children->Get(m_lastmouseidx); - if (t) - { - RECT r; - t->GetPosition(&r); - t->OnMouseMove(xpos-r.left,ypos-r.top); - } - if (chk.isOK()) m_lastmouseidx=-1; - } - } - - if (wnd && chk.isOK()) - { - RECT r; - wnd->GetPosition(&r); - wnd->OnMouseMove(xpos-r.left,ypos-r.top); - } -} - -void WDL_VWnd::OnCaptureLost() -{ - int oldcap=m_captureidx; - m_captureidx=-1; - if (m_children) - { - WDL_VWnd *wnd=m_children->Get(oldcap); - if (wnd) - { - wnd->OnCaptureLost(); - } - } -} - -void WDL_VWnd::OnMouseUp(int xpos, int ypos) -{ - int oldcap=m_captureidx; - m_captureidx=-1; // set this before passing to children, in case a child ends up destroying us - if (m_children) - { - WDL_VWnd *wnd=m_children->Get(oldcap); - - if (!wnd) - { - wnd=VirtWndFromPoint(xpos,ypos,0); - } - - if (wnd) - { - RECT r; - wnd->GetPosition(&r); - wnd->OnMouseUp(xpos-r.left,ypos-r.top); - } - } -} -void WDL_VWnd::GetPositionInTopVWnd(RECT *r) -{ - GetPosition(r); - WDL_VWnd *par=GetParent(); - while (par) - { - WDL_VWnd *tmp=par; - par=par->GetParent(); - if (par) - { - RECT t; - tmp->GetPosition(&t); - r->left+=t.left; - r->right+=t.left; - r->top+=t.top; - r->bottom+=t.top; - } - }; - -} - -class WDL_VirtualWnd_BGCfgCache_img -{ -public: - WDL_VirtualWnd_BGCfgCache_img(int szinfo, LICE_IBitmap *image, unsigned int now) - { - lastowner=0; - bgimage=image; - sizeinfo=szinfo; - lastused=now; - } - ~WDL_VirtualWnd_BGCfgCache_img() - { - delete bgimage; - } - - LICE_IBitmap *bgimage; - unsigned int sizeinfo; // (h<<16)+w - unsigned int lastused; // last used time - void *lastowner; - - static int compar(const WDL_VirtualWnd_BGCfgCache_img **a, const WDL_VirtualWnd_BGCfgCache_img ** b) - { - return (*a)->sizeinfo - (*b)->sizeinfo; - } -}; - - -class WDL_VirtualWnd_BGCfgCache_ar -{ -public: - WDL_VirtualWnd_BGCfgCache_ar() : m_cachelist(compar, NULL, NULL, destrval) { } - ~WDL_VirtualWnd_BGCfgCache_ar() { } - - WDL_AssocArray * > m_cachelist; - - static void destrval(WDL_PtrList *list) - { - if (list) list->Empty(true); - delete list; - } - static int compar(const LICE_IBitmap **a, const LICE_IBitmap ** b) - { - if ((*a) < (*b)) return -1; - if ((*a) > (*b)) return 1; - return 0; - } - -}; - - -WDL_VirtualWnd_BGCfgCache::WDL_VirtualWnd_BGCfgCache(int want_size, int max_size) -{ - m_ar = new WDL_VirtualWnd_BGCfgCache_ar; - m_want_size=want_size; - m_max_size = max_size; -} -WDL_VirtualWnd_BGCfgCache::~WDL_VirtualWnd_BGCfgCache() -{ - delete m_ar; -} - -void WDL_VirtualWnd_BGCfgCache::Invalidate() -{ - m_ar->m_cachelist.DeleteAll(); -} - -LICE_IBitmap *WDL_VirtualWnd_BGCfgCache::GetCachedBG(int w, int h, void *owner_hint, const LICE_IBitmap *bgbmp) -{ - if (w<1 || h<1 || w>65535 || h>65535) return NULL; - - WDL_PtrList *cache = m_ar->m_cachelist.Get(bgbmp); - if (!cache) return NULL; - - WDL_VirtualWnd_BGCfgCache_img tmp((h<<16)+w,NULL,0); - WDL_VirtualWnd_BGCfgCache_img *r = cache->Get(cache->FindSorted(&tmp,WDL_VirtualWnd_BGCfgCache_img::compar)); - if (r) - { - r->lastused = GetTickCount(); - if (owner_hint && r->lastowner != owner_hint) r->lastowner=0; - return r->bgimage; - } - return NULL; -} - -void WDL_VirtualWnd_BGCfgCache::SetCachedBG(int w, int h, LICE_IBitmap *bm, void *owner_hint, const LICE_IBitmap *bgbmp) -{ - if (!bm || w<1 || h<1 || w>65535 || h>65535) return; - - WDL_PtrList *cache = m_ar->m_cachelist.Get(bgbmp); - if (!cache) - { - cache = new WDL_PtrList; - m_ar->m_cachelist.Insert(bgbmp,cache); - } - - // caller should ALWAYS call GetCachedBG() and use that if present - - WDL_VirtualWnd_BGCfgCache_img *img = NULL; - unsigned int now = GetTickCount(); - bool cacheAtWantSize = cache->GetSize()>=m_want_size; - if (cacheAtWantSize || owner_hint) - { - int x; - int bestpos=-1; - unsigned int bestt=0xffffff00; - for(x=0;xGetSize();x++) - { - WDL_VirtualWnd_BGCfgCache_img *a = cache->Get(x); - if (owner_hint && a->lastowner == owner_hint) - { - cacheAtWantSize=true; - bestt = now-5000; - bestpos=x; - break; // FOUND exact match! - } - if (a->lastused < bestt) - { - bestt=a->lastused; - bestpos=x; - } - } - - if (cacheAtWantSize && (bestt < now-500 || cache->GetSize() >= m_max_size)) // use this slot if over 1000ms old, or if we're up against the max size - { - img = cache->Get(bestpos); - cache->Delete(bestpos,false); - if (img) - { - img->sizeinfo = (h<<16)+w; - img->lastused = now; - } - } - - } - - - if (!img) - { - LICE_IBitmap *bmcp = new LICE_MemBitmap(w,h); - if (bmcp->getWidth()==w && bmcp->getHeight()==h) img = new WDL_VirtualWnd_BGCfgCache_img((h<<16)+w,bmcp,now); - else delete bmcp; - } - - if (img) - { - img->lastowner = owner_hint; - LICE_Copy(img->bgimage,bm); - cache->InsertSorted(img,WDL_VirtualWnd_BGCfgCache_img::compar); - } - -} - -void WDL_VirtualWnd_PreprocessBGConfig(WDL_VirtualWnd_BGCfg *a) -{ - if (!a) return; - - if (!a->bgimage) return; - a->bgimage_lt[0]=a->bgimage_lt[1]=a->bgimage_rb[0]=a->bgimage_rb[1]=0; - a->bgimage_lt_out[0]=a->bgimage_lt_out[1]=a->bgimage_rb_out[0]=a->bgimage_rb_out[1]=1; - - int w=a->bgimage->getWidth(); - int h=a->bgimage->getHeight(); - if (w>1&&h>1 && LICE_GetPixel(a->bgimage,0,0)==LICE_RGBA(255,0,255,255) && - LICE_GetPixel(a->bgimage,w-1,h-1)==LICE_RGBA(255,0,255,255)) - { - int x; - for (x = 1; x < w && LICE_GetPixel(a->bgimage,x,0)==LICE_RGBA(255,0,255,255); x ++); - a->bgimage_lt[0] = x; - for (x = w-2; x >= a->bgimage_lt[0]+1 && LICE_GetPixel(a->bgimage,x,h-1)==LICE_RGBA(255,0,255,255); x --); - a->bgimage_rb[0] = w-1-x; - - for (x = 1; x < h && LICE_GetPixel(a->bgimage,0,x)==LICE_RGBA(255,0,255,255); x ++); - a->bgimage_lt[1] = x; - for (x = h-2; x >= a->bgimage_lt[1]+1 && LICE_GetPixel(a->bgimage,w-1,x)==LICE_RGBA(255,0,255,255); x --); - a->bgimage_rb[1] = h-1-x; - } - else if (w>1&&h>1 && LICE_GetPixel(a->bgimage,0,0)==LICE_RGBA(255,255,0,255) && - LICE_GetPixel(a->bgimage,w-1,h-1)==LICE_RGBA(255,255,0,255)) - { - - bool hadPink=false; - - //graphic image contains an outside area -- must contain at least one pink pixel in its definition or we assume it's just a yellow image... - int x, x2, x3; - for (x = 1, x2 = 0, x3 = 0; x < w; x++) - { - LICE_pixel p = LICE_GetPixel(a->bgimage,x,0); - if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } - else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } - else break; - } - a->bgimage_lt[0] = x2+1; - a->bgimage_lt_out[0] = x3+1; - for (x = w-2, x2 = 0, x3 = 0; x >= a->bgimage_lt[0]+1; x--) - { - LICE_pixel p = LICE_GetPixel(a->bgimage,x,h-1); - if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } - else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } - else break; - } - a->bgimage_rb[0] = x2+1; - a->bgimage_rb_out[0] = x3+1; - - for (x = 1, x2 = 0, x3 = 0; x < h;x++) - { - LICE_pixel p = LICE_GetPixel(a->bgimage,0,x); - if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } - else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } - else break; - } - a->bgimage_lt[1] = x2+1; - a->bgimage_lt_out[1] = x3+1; - for (x = h-2, x2 = 0, x3 = 0; x >= a->bgimage_lt[1]+1; x --) - { - LICE_pixel p = LICE_GetPixel(a->bgimage,w-1,x); - if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } - else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } - else break; - } - a->bgimage_rb[1] = x2+1; - a->bgimage_rb_out[1] = x3+1; - if (!hadPink) // yellow by itself isnt enough, need at least a bit of pink. - { - a->bgimage_lt[0]=a->bgimage_lt[1]=a->bgimage_rb[0]=a->bgimage_rb[1]=0; - a->bgimage_lt_out[0]=a->bgimage_lt_out[1]=a->bgimage_rb_out[0]=a->bgimage_rb_out[1]=1; - } - } - - - int flags=0xffff; - LICE_pixel_chan *ch = (LICE_pixel_chan *) a->bgimage->getBits(); - int span = a->bgimage->getRowSpan()*4; - if (a->bgimage->isFlipped()) - { - ch += span*(h-1); - span=-span; - } - - // not sure if this works yet -- it needs more testing for sure - bool isFull=true; - if (a->bgimage_lt[0] ||a->bgimage_lt[1] || a->bgimage_rb[0] || a->bgimage_rb[1]) - { - isFull=false; - ch += span; // skip a line - ch += 4; // skip a column - h-=2; - w-=2; - } - - // points at which we change to the next block - int xdivs[3] = { a->bgimage_lt[0]+a->bgimage_lt_out[0]-2, - w-a->bgimage_rb[0]-a->bgimage_rb_out[0]+2, - w-a->bgimage_rb_out[0]+1}; - int ydivs[3] = { a->bgimage_lt[1]+a->bgimage_lt_out[1]-2, - h-a->bgimage_rb[1]-a->bgimage_rb_out[1]+2, - h-a->bgimage_rb_out[1]+1}; - - int y,ystate=0; - for(y=0;y=ydivs[ystate]) ystate++; - int xstate=0; - - int x; - LICE_pixel_chan *chptr = ch + LICE_PIXEL_A; - for (x=0;x=xdivs[xstate]) xstate++; - - if (*chptr != 255) - { - if (isFull) - { - flags=0; - break; - } - else - { - flags &= ~(1<<(ystate*4 + xstate)); - if (!flags) break; - } - } - chptr+=4; - } - if (!flags) break; - - ch += span; - } - - a->bgimage_noalphaflags=flags; - -} - -static void __VirtClipBlit(int clipx, int clipy, int clipright, int clipbottom, - LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, - int _srcx, int _srcy, int _srcw, int _srch, float alpha, int mode) -{ - if (dstw<1||dsth<1 || dstx+dstw < clipx || dstx > clipright || - dsty+dsth < clipy || dsty > clipbottom) - { - return; // dont draw if fully outside - } - - double srcx = (double) _srcx; - double srcy = (double) _srcy; - double srcw = (double) _srcw; - double srch = (double) _srch; - - if (dstx < clipx || dsty < clipy || dstx+dstw > clipright || dsty+dsth > clipbottom) - { - double xsc=srcw/dstw; - double ysc=srch/dsth; - - if (dstx clipright) - { - int diff = dstx+dstw-clipright; //clipright-dstx-dstw; - dstw -= diff; - srcw -= diff*xsc; - } - if (dsty+dsth > clipbottom) - { - int diff = dsty+dsth-clipbottom; //clipbottom-dsty-dsth; - dsth -= diff; - srch -= diff*ysc; - } - - } - - if (dstw>0&&dsth>0) - { - const double eps=0.0005; - if (srcw > 0.0 && srcw < eps) srcw=eps; - if (srch > 0.0 && srch < eps) srch=eps; - LICE_ScaledBlit(dest,src,dstx,dsty,dstw,dsth,(float)srcx,(float)srcy,(float)srcw,(float)srch,alpha,mode); - } -} - -void WDL_VirtualWnd_ScaledBlitSubBG(LICE_IBitmap *dest, - WDL_VirtualWnd_BGCfg *src, - int destx, int desty, int destw, int desth, - int clipx, int clipy, int clipw, int cliph, - int srcx, int srcy, int srcw, int srch, // these coordinates are not including pink lines (i.e. if pink lines are present, use src->bgimage->getWidth()-2, etc) - float alpha, int mode) -{ - if (!src || !src->bgimage) return; - - int adj=2; - if (src->bgimage_lt[0] < 1 || src->bgimage_lt[1] < 1 || src->bgimage_rb[0] < 1 || src->bgimage_rb[1] < 1) - { - adj=0; - } - if (srcx == 0 && srcy == 0 && srcw+adj >= src->bgimage->getWidth() && srch+adj >= src->bgimage->getHeight()) - { - WDL_VirtualWnd_ScaledBlitBG(dest,src,destx,desty,destw,desth,clipx,clipy,clipw,cliph,alpha,mode); - return; - } - - LICE_SubBitmap bm(src->bgimage,srcx,srcy,srcw+adj,srch+adj); - WDL_VirtualWnd_BGCfg ts = *src; - ts.bgimage = &bm; - - if ((ts.bgimage_noalphaflags&0xffff)!=0xffff) ts.bgimage_noalphaflags=0; // force alpha channel if any alpha - - WDL_VirtualWnd_ScaledBlitBG(dest,&ts,destx,desty,destw,desth,clipx,clipy,clipw,cliph,alpha,mode); -} - -void WDL_VirtualWnd_ScaledBlitBG(LICE_IBitmap *dest, - WDL_VirtualWnd_BGCfg *src, - int destx, int desty, int destw, int desth, - int clipx, int clipy, int clipw, int cliph, - float alpha, int mode) -{ - // todo: blit clipping optimizations - if (!src || !src->bgimage) return; - - int left_margin=src->bgimage_lt[0]; - int top_margin=src->bgimage_lt[1]; - int right_margin=src->bgimage_rb[0]; - int bottom_margin=src->bgimage_rb[1]; - - int left_margin_out=src->bgimage_lt_out[0]; - int top_margin_out=src->bgimage_lt_out[1]; - int right_margin_out=src->bgimage_rb_out[0]; - int bottom_margin_out=src->bgimage_rb_out[1]; - - int sw=src->bgimage->getWidth(); - int sh=src->bgimage->getHeight(); - - int clipright=clipx+clipw; - int clipbottom=clipy+cliph; - - if (clipxdestx+destw) clipright=clipx+destw; - if (clipbottom>desty+desth) clipbottom=clipy+desth; - - if (left_margin<1||top_margin<1||right_margin<1||bottom_margin<1) - { - float xsc=(float)sw/destw; - float ysc=(float)sh/desth; - - if (mode&LICE_BLIT_USE_ALPHA) - { - if ((src->bgimage_noalphaflags & 0xffff)==0xffff) - { - mode &= ~LICE_BLIT_USE_ALPHA; - } - } - - - LICE_ScaledBlit(dest,src->bgimage, - clipx,clipy,clipright-clipx,clipbottom-clipy, - (clipx-destx)*xsc, - (clipy-desty)*ysc, - (clipright-clipx)*xsc, - (clipbottom-clipy)*ysc, - alpha,mode); - - return; - } - - // remove 1px additional margins from calculations - left_margin--; top_margin--; right_margin--; bottom_margin--; - left_margin_out--; top_margin_out--; right_margin_out--; bottom_margin_out--; - - if (left_margin+right_margin>destw) - { - int w=left_margin+right_margin; - left_margin = destw*left_margin/max(w,1); - right_margin=destw-left_margin; - } - if (top_margin+bottom_margin>desth) - { - int h=(top_margin+bottom_margin); - top_margin=desth*top_margin/max(h,1); - bottom_margin=desth-top_margin; - } - - int no_alpha_flags=src->bgimage_noalphaflags; - int pass; - int nbpass = 3; - if (bottom_margin_out>0) - nbpass = 4; - - bool no_inside = !!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_INSIDE); - bool no_outside = !!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_OUTSIDE); - - bool no_lr=!!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_LR); - - - for (pass=(top_margin_out> 0 ? -1 : 0); passbgimage_lt[1]-1; - break; - case 1: - outy=desty+top_margin; - outh=desth-top_margin-bottom_margin; - iny=src->bgimage_lt[1]+top_margin_out; - inh=sh-src->bgimage_rb[1]-bottom_margin_out - iny; - break; - case 2: - outy=desty+desth-bottom_margin; - outh=bottom_margin; - iny=sh - src->bgimage_rb[1] - bottom_margin_out; - inh=src->bgimage_rb[1]-1; - break; - case 3: - outy=desty+desth; - outh=bottom_margin_out; - iny=sh-1-bottom_margin_out; - inh=bottom_margin_out; - clipbottom += bottom_margin_out; - break; - } - bool is_outer = pass<0 || pass>=3; - - if (no_outside && is_outer) - { - } - else if (outh > 0 && inh > 0) - { - - if (no_lr) - { - __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx,outy, - destw,outh, - src->bgimage_lt[0]+left_margin_out,iny, - sw-src->bgimage_lt[0]-src->bgimage_rb[0]-left_margin_out - right_margin_out, - inh,alpha,(no_alpha_flags&2) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - } - else - { - // left - if (left_margin_out>0 && !no_outside) - { - __VirtClipBlit(clipx-left_margin_out,this_clipy,clipright,clipbottom,dest,src->bgimage,destx-left_margin_out,outy,left_margin_out,outh, - 1,iny,left_margin_out,inh,alpha, - (no_alpha_flags&1) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - } - - if (!no_inside||is_outer) - { - if (left_margin > 0) - __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx,outy,left_margin,outh, - 1+left_margin_out,iny,src->bgimage_lt[0]-1,inh,alpha, - (no_alpha_flags&1) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - - - // center - __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx+left_margin,outy, - destw-right_margin-left_margin,outh, - src->bgimage_lt[0]+left_margin_out,iny, - sw-src->bgimage_lt[0]-src->bgimage_rb[0]-right_margin_out-left_margin_out, - inh,alpha,(no_alpha_flags&2) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - // right - if (right_margin > 0) - __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx+destw-right_margin,outy, right_margin,outh, - sw-src->bgimage_rb[0]-right_margin_out,iny, - src->bgimage_rb[0]-1,inh,alpha,(no_alpha_flags&4) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - } - - // right outside area - if (right_margin_out>0 && !no_outside) - __VirtClipBlit(clipx,this_clipy,clipright+right_margin_out,clipbottom,dest,src->bgimage,destx+destw,outy,right_margin_out,outh, - sw-right_margin_out-1,iny, - right_margin_out,inh,alpha,(no_alpha_flags&8) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); - - } - } - if (pass>=0) - no_alpha_flags>>=4; - } -} - -int WDL_VirtualWnd_ScaledBG_GetPix(WDL_VirtualWnd_BGCfg *src, - int ww, int wh, - int x, int y) -{ - if (!src->bgimage) return 0; - int imgw=src->bgimage->getWidth(); - int imgh=src->bgimage->getHeight(); - - int left_margin=src->bgimage_lt[0]; - int top_margin=src->bgimage_lt[1]; - int right_margin=src->bgimage_rb[0]; - int bottom_margin=src->bgimage_rb[1]; - - if (left_margin<1||top_margin<1||right_margin<1||bottom_margin<1) - { - if (ww<1)ww=1; - x=(x * imgw)/ww; - if (wh<1)wh=1; - y=(y * imgh)/wh; - } - else - { - // remove 1px additional margins from calculations - left_margin--; top_margin--; right_margin--; bottom_margin--; - int destw=ww,desth=wh; - if (left_margin+right_margin>destw) - { - int w=left_margin+right_margin; - left_margin = destw*left_margin/max(w,1); - right_margin=destw-left_margin; - } - if (top_margin+bottom_margin>desth) - { - int h=(top_margin+bottom_margin); - top_margin=desth*top_margin/max(h,1); - bottom_margin=desth-top_margin; - } - - if (x >= ww-right_margin) x=imgw-1- (ww-x); - else if (x >= left_margin) - { - int xd=ww-left_margin-right_margin; - if (xd<1)xd=1; - x=src->bgimage_lt[0] + - (x-left_margin) * (imgw-src->bgimage_lt[0]-src->bgimage_rb[0])/xd; - } - else x++; - - if (y >= wh-bottom_margin) y=imgh -1- (wh-y); - else if (y >= top_margin) - { - int yd=wh-top_margin-bottom_margin; - if (yd<1)yd=1; - y=src->bgimage_lt[1] + - (y-top_margin) * (imgh-src->bgimage_lt[1]-src->bgimage_rb[1])/yd; - } - else y++; - } - - return LICE_GetPixel(src->bgimage,x,y); -} - - -#ifdef _WIN32 - -static WNDPROC vwndDlgHost_oldProc; -static LRESULT CALLBACK vwndDlgHost_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg==WM_ERASEBKGND) return 1; - if (msg==WM_PAINT) - { - WNDPROC pc=(WNDPROC)GetWindowLongPtr(hwnd,DWLP_DLGPROC); - if (pc) - { - CallWindowProc(pc,hwnd,msg,wParam,lParam); - return 0; - } - } - - return CallWindowProc(vwndDlgHost_oldProc,hwnd,msg,wParam,lParam); -} - -#endif - -void WDL_VWnd_regHelperClass(const char *classname, void *icon1, void *icon2) -{ -#ifdef _WIN32 - static bool reg; - if (reg) return; - - reg=true; - - WNDCLASSEX wc={sizeof(wc),}; - GetClassInfoEx(NULL,"#32770",&wc); - wc.lpszClassName = (char*)classname; - if (icon1) wc.hIcon = (HICON)icon1; - if (icon2) wc.hIconSm = (HICON)icon2; - vwndDlgHost_oldProc=wc.lpfnWndProc; - wc.lpfnWndProc=vwndDlgHost_newProc; - RegisterClassEx(&wc); -#endif -} - diff --git a/WDL/wingui/virtwnd.h b/WDL/wingui/virtwnd.h deleted file mode 100644 index 8fc92652..00000000 --- a/WDL/wingui/virtwnd.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - WDL - virtwnd.h - Copyright (C) 2006 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - - This file provides interfaces for the WDL Virtual Windows layer, a system that allows - creating many controls within one system device context. - - The base class is a WDL_VWnd. - - If you create a WDL_VWnd, you should send it (or its parent) mouse messages etc. - - To paint a WDL_VWnd, use a WDL_VWnd_Painter in WM_PAINT etc. - - - More documentation should follow... -*/ - - - -#ifndef _WDL_VIRTWND_H_ -#define _WDL_VIRTWND_H_ - -#ifdef _WIN32 -#include -#else -#include "../swell/swell.h" -#endif -#include "../ptrlist.h" -#include "../wdlstring.h" - - - -class WDL_VWnd_Painter; -class LICE_IBitmap; - -// deprecated -#define WDL_VirtualWnd_ChildList WDL_VWnd -#define WDL_VirtualWnd WDL_VWnd -#define WDL_VirtualWnd_Painter WDL_VWnd_Painter - -class WDL_VWnd; - -class WDL_VWnd_IAccessibleBridge -{ -public: - virtual void Release()=0; - virtual void ClearCaches(){} - virtual void OnFocused() {} - virtual void OnStateChange() {} -}; - - -#include "../destroycheck.h" -#define WDL_VWND_DCHK(n) WDL_DestroyCheck n(&m_destroystate) - -class WDL_VWnd -{ -public: - WDL_VWnd(); - virtual ~WDL_VWnd(); - virtual const char *GetType() { return "vwnd_unknown"; } - - virtual void SetID(int id) { m_id=id; } - virtual int GetID() { return m_id; } - virtual INT_PTR GetUserData() { return m_userdata; } - virtual INT_PTR SetUserData(INT_PTR ud) { INT_PTR od=m_userdata; m_userdata=ud; return od; } - virtual void SetPosition(const RECT *r) { m_position=*r; } - virtual void GetPosition(RECT *r) { *r=m_position; } - virtual void GetPositionPaintExtent(RECT *r) { *r=m_position; } - virtual void GetPositionPaintOverExtent(RECT *r) { *r=m_position; } - virtual void SetVisible(bool vis) { m_visible=vis; } - virtual bool IsVisible() { return m_visible; } - virtual bool WantsPaintOver() { return m_children && m_children->GetSize(); } - virtual WDL_VWnd *GetParent() { return m_parent; } - virtual void SetParent(WDL_VWnd *par) { m_parent=par; } - - virtual void RequestRedraw(RECT *r); - virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - virtual void OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); - - virtual int OnMouseDown(int xpos, int ypos); // return -1 to eat, >0 to capture - virtual bool OnMouseDblClick(int xpos, int ypos); - virtual bool OnMouseWheel(int xpos, int ypos, int amt); - - virtual void OnMouseMove(int xpos, int ypos); - virtual void OnMouseUp(int xpos, int ypos); - - // child windows - virtual WDL_VWnd *EnumChildren(int x); - virtual int GetNumChildren(); - virtual WDL_VWnd *GetChildByID(int id); - virtual void AddChild(WDL_VWnd *wnd, int pos=-1); - virtual void RemoveChild(WDL_VWnd *wnd, bool dodel=false); - virtual void RemoveAllChildren(bool dodel=true); - virtual WDL_VWnd *GetCaptureWnd() { return m_children ? m_children->Get(m_captureidx) : 0; } - virtual WDL_VWnd *VirtWndFromPoint(int xpos, int ypos, int maxdepth=-1); // maxdepth=0 only direct children, etc, -1 is unlimited - - // OS access - virtual HWND GetRealParent() { if (m_realparent) return m_realparent; if (GetParent()) return GetParent()->GetRealParent(); return 0; } - virtual void SetRealParent(HWND par) { m_realparent=par; } - - virtual INT_PTR SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src); - - // request if window has cursor - virtual int UpdateCursor(int xpos, int ypos); // >0 if set, 0 if cursor wasnt set , <0 if cursor should be default... - virtual bool GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz); // true if handled - - virtual void GetPositionInTopVWnd(RECT *r); - - // these do not store a copy, usually you set them to static strings etc, but a control can override, too... - virtual void SetAccessDesc(const char *desc) { m__iaccess_desc=desc; } - virtual const char *GetAccessDesc() { return m__iaccess_desc; } - - virtual WDL_VWnd_IAccessibleBridge *GetAccessibilityBridge() { return m__iaccess; } - virtual void SetAccessibilityBridge(WDL_VWnd_IAccessibleBridge *br) { m__iaccess=br; } - - virtual void SetChildPosition(WDL_VWnd *ch, int pos); - - virtual void SetCurPainter(WDL_VWnd_Painter *p) { m_curPainter=p; } - virtual bool IsDescendent(WDL_VWnd *w); - - virtual void OnCaptureLost(); -protected: - WDL_VWnd *m_parent; - WDL_VWnd_IAccessibleBridge *m__iaccess; - bool m_visible; - int m_id; - RECT m_position; - INT_PTR m_userdata; - - HWND m_realparent; - int m_captureidx; - int m_lastmouseidx; - WDL_PtrList *m_children; - - const char *m__iaccess_desc; - - WDL_VWnd_Painter *m_curPainter; - virtual int GSC(int a); - - WDL_DestroyState m_destroystate; -}; - - -// painting object (can be per window or per thread or however you like) -#define WDL_VWP_SUNKENBORDER 0x00010000 -#define WDL_VWP_SUNKENBORDER_NOTOP 0x00020000 -#define WDL_VWP_DIVIDER_VERT 0x00030000 -#define WDL_VWP_DIVIDER_HORZ 0x00040000 - - -#include "virtwnd-skin.h" - -class WDL_VWnd_Painter -{ -public: - WDL_VWnd_Painter(); - ~WDL_VWnd_Painter(); - - - void SetGSC(int (*GSC)(int)); - void PaintBegin(HWND hwnd, int bgcolor=-1, const RECT *limitBGrect=NULL, const RECT *windowRect=NULL); - void SetBGImage(WDL_VirtualWnd_BGCfg *bitmap, int tint=-1, WDL_VirtualWnd_BGCfgCache *cacheObj=NULL) { m_bgbm=bitmap; m_bgbmtintcolor=tint; m_bgcache=cacheObj; } // call before every paintbegin (resets if you dont) - void SetBGGradient(int wantGradient, double start, double slope); // wantg < 0 to use system defaults - - void PaintBGCfg(WDL_VirtualWnd_BGCfg *bitmap, const RECT *coords, bool allowTint=true, float alpha=1.0, int mode=0); - void PaintVirtWnd(WDL_VWnd *vwnd, int borderflags=0); - void PaintBorderForHWND(HWND hwnd, int borderflags); - void PaintBorderForRect(const RECT *r, int borderflags); - - void GetPaintInfo(RECT *rclip, int *xoffsdraw, int *yoffsdraw); - - LICE_IBitmap *GetBuffer(int *xo, int *yo) - { - *xo = -m_paint_xorig; - *yo = -m_paint_yorig; - return m_bm; - } - - void PaintEnd(); - - int GSC(int a); -private: - - double m_gradstart,m_gradslope; - - int m_wantg; - int (*m_GSC)(int); - void DoPaintBackground(LICE_IBitmap *bmOut, int bgcolor, const RECT *clipr, int wnd_w, int wnd_h, int xoffs, int yoffs); - void tintRect(LICE_IBitmap *bmOut, const RECT *clipr, int xoffs, int yoffs); - LICE_IBitmap *m_bm; - WDL_VirtualWnd_BGCfg *m_bgbm; - int m_bgbmtintcolor; - - WDL_VirtualWnd_BGCfgCache *m_bgcache; - HWND m_cur_hwnd; - PAINTSTRUCT m_ps; - int m_paint_xorig, m_paint_yorig; - -}; - -void WDL_VWnd_regHelperClass(const char *classname, void *icon=NULL, void *iconsm=NULL); // register this class if you wish to make your dialogs use it (better paint behavior) - -// in virtwnd-iaccessible.cpp -LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam); - -#endif diff --git a/WDL/wingui/wndsize.cpp b/WDL/wingui/wndsize.cpp deleted file mode 100644 index faeda6c5..00000000 --- a/WDL/wingui/wndsize.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - WDL - wndsize.cpp - Copyright (C) 2004 and later, Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* -For information on how to use this class, see wndsize.h :) -*/ - -#ifndef _WIN32 -#include "../swell/swell.h" -#else -#include -#endif - -#include "wndsize.h" -#include "virtwnd.h" - -void WDL_WndSizer::init(HWND hwndDlg, RECT *initr) -{ - m_hwnd=hwndDlg; - RECT r={0,}; - if (initr) - r=*initr; - else if (m_hwnd) - GetClientRect(m_hwnd,&r); - set_orig_rect(&r); - - m_list.Resize(0); - - memset(&m_margins,0,sizeof(m_margins)); -} - - -void WDL_WndSizer::init_item(int dlg_id, float *scales, RECT *initr) -{ - init_item(dlg_id,scales[0],scales[1],scales[2],scales[3],initr); -} -void WDL_WndSizer::init_itemvirt(WDL_VWnd *vwnd, float *scales) -{ - init_itemvirt(vwnd,scales[0],scales[1],scales[2],scales[3]); -} - -void WDL_WndSizer::init_itemvirt(WDL_VirtualWnd *vwnd, - float left_scale, float top_scale, float right_scale, float bottom_scale) -{ - RECT this_r={0,}; - if (vwnd) vwnd->GetPosition(&this_r); - int osize=m_list.GetSize(); - m_list.Resize(osize+sizeof(WDL_WndSizer__rec)); - - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()+osize); - - rec->hwnd=0; - rec->vwnd=vwnd; - rec->scales[0]=left_scale; - rec->scales[1]=top_scale; - rec->scales[2]=right_scale; - rec->scales[3]=bottom_scale; - rec->real_orig = rec->last = rec->orig = this_r; -} - -POINT WDL_WndSizer::get_min_size(bool applyMargins) -{ - POINT p = m_min_size; - if (applyMargins) - { - p.x += m_margins.left+m_margins.right; - p.y += m_margins.top+m_margins.bottom; - } - return p; -} - - -void WDL_WndSizer::init_itemhwnd(HWND h, float left_scale, float top_scale, float right_scale, float bottom_scale, RECT *srcr) -{ - RECT this_r={0,}; - if (srcr) this_r=*srcr; - else if (h) - { - GetWindowRect(h,&this_r); - if (m_hwnd) - { - ScreenToClient(m_hwnd,(LPPOINT) &this_r); - ScreenToClient(m_hwnd,((LPPOINT) &this_r)+1); - } - #ifndef _WIN32 - if (this_r.bottom < this_r.top) - { - int oh=this_r.top-this_r.bottom; - this_r.bottom=this_r.top; - this_r.top -= oh; - } - #endif - } - int osize=m_list.GetSize(); - m_list.Resize(osize+sizeof(WDL_WndSizer__rec)); - - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()+osize); - - rec->hwnd=h; - rec->vwnd=0; - rec->scales[0]=left_scale; - rec->scales[1]=top_scale; - rec->scales[2]=right_scale; - rec->scales[3]=bottom_scale; - - rec->real_orig = rec->last = rec->orig = this_r; -} - -void WDL_WndSizer::init_item(int dlg_id, float left_scale, float top_scale, float right_scale, float bottom_scale, RECT *initr) -{ - if (m_hwnd) - init_itemhwnd(GetDlgItem(m_hwnd,dlg_id),left_scale,top_scale,right_scale,bottom_scale,initr); -} - -#ifdef _WIN32 -BOOL CALLBACK WDL_WndSizer::enum_RegionRemove(HWND hwnd,LPARAM lParam) -{ - WDL_WndSizer *_this=(WDL_WndSizer *)lParam; -// if(GetParent(hwnd)!=_this->m_hwnd) return TRUE; - - if (IsWindowVisible(hwnd)) - { - RECT r; - GetWindowRect(hwnd,&r); - if (_this->m_hwnd) - { - ScreenToClient(_this->m_hwnd,(LPPOINT)&r); - ScreenToClient(_this->m_hwnd,((LPPOINT)&r)+1); - } - HRGN rgn2=CreateRectRgn(r.left,r.top,r.right,r.bottom); - CombineRgn(_this->m_enum_rgn,_this->m_enum_rgn,rgn2,RGN_DIFF); - DeleteObject(rgn2); - } - - return TRUE; -} -#endif - -void WDL_WndSizer::remove_item(int dlg_id) -{ - if (m_hwnd) remove_itemhwnd(GetDlgItem(m_hwnd,dlg_id)); -} - -void WDL_WndSizer::remove_itemhwnd(HWND h) -{ - WDL_WndSizer__rec *rec; - while ((rec=get_itembywnd(h))) - { - WDL_WndSizer__rec *list=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int list_size=m_list.GetSize()/sizeof(WDL_WndSizer__rec); - int idx=rec-list; - - if (idx >= 0 && idx < list_size-1) - memcpy(rec,rec+1,(list_size-(idx+1))*sizeof(WDL_WndSizer__rec)); - m_list.Resize((list_size-1)*sizeof(WDL_WndSizer__rec)); - } -} - -void WDL_WndSizer::remove_itemvirt(WDL_VirtualWnd *vwnd) -{ - WDL_WndSizer__rec *rec; - while ((rec=get_itembyvirt(vwnd))) - { - WDL_WndSizer__rec *list=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int list_size=m_list.GetSize()/sizeof(WDL_WndSizer__rec); - int idx=rec-list; - - if (idx >= 0 && idx < list_size-1) - memcpy(rec,rec+1,(list_size-(idx+1))*sizeof(WDL_WndSizer__rec)); - m_list.Resize((list_size-1)*sizeof(WDL_WndSizer__rec)); - } -} - -void WDL_WndSizer::transformRect(RECT *r, const float *scales, const RECT *wndSize) -{ - POINT sz = { wndSize->right, wndSize->bottom }; - - sz.x -= m_margins.left+m_margins.right; - sz.y -= m_margins.top+m_margins.bottom; - - if (sz.x < m_min_size.x) sz.x=m_min_size.x; - if (sz.y < m_min_size.y) sz.y=m_min_size.y; - - sz.x -= m_orig_size.x; - sz.y -= m_orig_size.y; - - if (scales[0] >= 1.0) r->left += sz.x; - else if (scales[0]>0.0) r->left += (int) (sz.x*scales[0]); - - if (scales[1] >= 1.0) r->top += sz.y; - else if (scales[1]>0.0) r->top += (int) (sz.y*scales[1]); - - if (scales[2] >= 1.0) r->right += sz.x; - else if (scales[2]>0.0) r->right += (int) (sz.x*scales[2]); - - if (scales[3] >= 1.0) r->bottom += sz.y; - else if (scales[3]>0.0) r->bottom += (int) (sz.y*scales[3]); - - r->left += m_margins.left; - r->right += m_margins.left; - r->top += m_margins.top; - r->bottom += m_margins.top; - - if (r->bottom < r->top) r->bottom=r->top; - if (r->right < r->left) r->right=r->left; -} - - -void WDL_WndSizer::onResize(HWND only, int notouch, int xtranslate, int ytranslate) -{ - if (!m_hwnd) return; - - RECT new_rect; - - GetClientRect(m_hwnd,&new_rect); -#ifdef _WIN32 - - m_enum_rgn=CreateRectRgn(new_rect.left,new_rect.top,new_rect.right,new_rect.bottom); - // EnumChildWindows(m_hwnd,enum_RegionRemove,(LPARAM)this); - - HDWP hdwndpos=NULL; - int has_dfwp=0; -#endif - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); - - int x; - for (x = 0; x < cnt; x ++) - { - - if ((rec->vwnd && !only) || (rec->hwnd && (!only || only == rec->hwnd))) - { - RECT r=rec->orig; - transformRect(&r,rec->scales,&new_rect); - - rec->last = r; - - if (!notouch) - { - if (rec->hwnd) - { -#ifdef _WIN32 - if (!has_dfwp) - { - has_dfwp=1; - if (!only && GetVersion() < 0x80000000) hdwndpos=BeginDeferWindowPos(cnt); - } - - - if (IsWindow(rec->hwnd)) - { - if (!hdwndpos) -#endif - SetWindowPos(rec->hwnd, NULL, r.left+xtranslate,r.top+ytranslate,r.right-r.left,r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE); - -#ifdef _WIN32 - else - { - hdwndpos=DeferWindowPos(hdwndpos, rec->hwnd, NULL, r.left+xtranslate,r.top+ytranslate,r.right-r.left,r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE); - } - } -#endif - } - if (rec->vwnd) - { - rec->vwnd->SetPosition(&r); - } - } - } - rec++; - } -#ifdef _WIN32 - if (hdwndpos) EndDeferWindowPos(hdwndpos); - - EnumChildWindows(m_hwnd,enum_RegionRemove,(LPARAM)this); - InvalidateRgn(m_hwnd,m_enum_rgn,FALSE); - DeleteObject(m_enum_rgn); -#endif -} - -WDL_WndSizer__rec *WDL_WndSizer::get_itembyindex(int id) -{ - if (id >= 0 && id < (m_list.GetSize() / (int)sizeof(WDL_WndSizer__rec))) - { - return ((WDL_WndSizer__rec *) m_list.Get())+id; - } - return NULL; -} - -WDL_WndSizer__rec *WDL_WndSizer::get_itembywnd(HWND h) -{ - if (h) - { - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); - while (cnt--) - { - if (rec->hwnd == h) return rec; - rec++; - } - } - return 0; -} - - -WDL_WndSizer__rec *WDL_WndSizer::get_itembyvirt(WDL_VirtualWnd *vwnd) -{ - if (!vwnd) return 0; - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); - while (cnt--) - { - if (rec->vwnd == vwnd) return rec; - rec++; - } - return 0; -} - -WDL_WndSizer__rec *WDL_WndSizer::get_item(int dlg_id) -{ - WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); - int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); - while (cnt--) - { - if (rec->vwnd && rec->vwnd->GetID() == dlg_id) return rec; - rec++; - } - - return m_hwnd ? get_itembywnd(GetDlgItem(m_hwnd,dlg_id)) : 0; -} diff --git a/WDL/wingui/wndsize.h b/WDL/wingui/wndsize.h deleted file mode 100644 index de90d5c1..00000000 --- a/WDL/wingui/wndsize.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - WDL - wndsize.h - Copyright (C) 2004 and later Cockos Incorporated - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -*/ - -/* - - This file provides the interface for a simple class that allows one to easily - make resizeable dialogs and have controls that move according to ratios of the - new size. - - Usually, one does a - - static WDL_WndSizer resize; - - in their DlgProc, and in WM_INITDIALOG: - - resize.init(hwndDlg); - - // add a list of items - resize.init_item(IDC_MASTERVOL, // dialog id - 0.0, // left position, 0=left anchor, 1=right anchor, etc - 0.0, // top position, 0=anchored to its initial top position, 1=anchored to distance from bottom, etc - 0.7f, // right position - 0.0); // bottom position - ... - - - then, in WM_SIZE, - if (wParam != SIZE_MINIMIZED) - { - resize.onResize(); // don't actually resize, just compute the rects - } - - - is about all that's needed. - - -*/ - -#ifndef _WNDSIZE_H_ -#define _WNDSIZE_H_ - - -#include "../heapbuf.h" - -class WDL_VWnd; - -struct WDL_WndSizer__rec -{ - HWND hwnd; - RECT orig; - RECT real_orig; - RECT last; - float scales[4]; - WDL_VWnd *vwnd; - -}; - -class WDL_WndSizer -{ -public: - WDL_WndSizer() - { - m_hwnd=NULL; - memset(&m_min_size,0,sizeof(m_min_size)); - memset(&m_orig_size,0,sizeof(m_orig_size)); - memset(&m_margins,0,sizeof(m_margins)); - } - ~WDL_WndSizer() { } - - void init(HWND hwndDlg, RECT *initr=NULL); - - // 1.0 means it moves completely with the point, 0.0 = not at all - void init_item(int dlg_id, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0, RECT *initr=NULL); - void init_itemvirt(WDL_VWnd *vwnd, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0); - void init_item(int dlg_id, float *scales, RECT *initr=NULL); - void init_itemvirt(WDL_VWnd *vwnd, float *scales); - void init_itemhwnd(HWND h, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0, RECT *srcr=NULL); - void remove_item(int dlg_id); - void remove_itemvirt(WDL_VWnd *vwnd); - void remove_itemhwnd(HWND h); - - WDL_WndSizer__rec *get_item(int dlg_id); - WDL_WndSizer__rec *get_itembyindex(int id); - WDL_WndSizer__rec *get_itembywnd(HWND h); - WDL_WndSizer__rec *get_itembyvirt(WDL_VWnd *vwnd); - - RECT get_orig_rect() { RECT r={0,0,m_orig_size.x,m_orig_size.y}; return r; } - void set_orig_rect(const RECT *r, const POINT *minSize=NULL) - { - if (r) { m_orig_size.x = r->right; m_orig_size.y = r->bottom; } - if (minSize) m_min_size = *minSize; - else m_min_size.x=m_min_size.y=0; - } - POINT get_min_size(bool applyMargins=false); - - void onResize(HWND only=0, int notouch=0, int xtranslate=0, int ytranslate=0); - - - void set_margins(int left, int top, int right, int bottom) { m_margins.left=left; m_margins.top=top; m_margins.right=right; m_margins.bottom=bottom; } - void get_margins(int *left, int *top, int *right, int *bottom) - { - if (left) *left=m_margins.left; - if (top) *top=m_margins.top; - if (right) *right=m_margins.right; - if (bottom) *bottom=m_margins.bottom; - } - - void transformRect(RECT *r, const float *scales, const RECT *wndSize); - -private: -#ifdef _WIN32 - static BOOL CALLBACK enum_RegionRemove(HWND hwnd,LPARAM lParam); - HRGN m_enum_rgn; -#endif - HWND m_hwnd; - POINT m_orig_size,m_min_size; - RECT m_margins; - - // treat as WDL_WndSizer__rec[] - WDL_HeapBuf m_list; - -}; - -#endif//_WNDSIZE_H_ \ No newline at end of file diff --git a/WDL/zlib/adler32.c b/WDL/zlib/adler32.c deleted file mode 100644 index a868f073..00000000 --- a/WDL/zlib/adler32.c +++ /dev/null @@ -1,179 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define local static - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521 /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/WDL/zlib/compress.c b/WDL/zlib/compress.c deleted file mode 100644 index ea4dfbe9..00000000 --- a/WDL/zlib/compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/WDL/zlib/crc32.c b/WDL/zlib/crc32.c deleted file mode 100644 index cc711899..00000000 --- a/WDL/zlib/crc32.c +++ /dev/null @@ -1,449 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# ifndef Z_SOLO -# include -# endif -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR - typedef u4 crc_table_t; -# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else - typedef unsigned long crc_table_t; -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local crc_table_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const crc_table_t FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - crc_table_t c; - int n, k; - crc_table_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (crc_table_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (crc_table_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const crc_table_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const crc_table_t FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/WDL/zlib/crc32.h b/WDL/zlib/crc32.h deleted file mode 100644 index c3e7171c..00000000 --- a/WDL/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const crc_table_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/WDL/zlib/deflate.c b/WDL/zlib/deflate.c deleted file mode 100644 index 8bd480eb..00000000 --- a/WDL/zlib/deflate.c +++ /dev/null @@ -1,1965 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.6 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - unsigned char *next; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - deflate_state *s; - int put; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - Bytef *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/WDL/zlib/deflate.h b/WDL/zlib/deflate.h deleted file mode 100644 index fbac44d9..00000000 --- a/WDL/zlib/deflate.h +++ /dev/null @@ -1,346 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2012 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/WDL/zlib/gzclose.c b/WDL/zlib/gzclose.c deleted file mode 100644 index caeb99a3..00000000 --- a/WDL/zlib/gzclose.c +++ /dev/null @@ -1,25 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/WDL/zlib/gzguts.h b/WDL/zlib/gzguts.h deleted file mode 100644 index 3107c363..00000000 --- a/WDL/zlib/gzguts.h +++ /dev/null @@ -1,190 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif -#include - -#ifdef __TURBOC__ -# include -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# include -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifdef STDC -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/WDL/zlib/gzlib.c b/WDL/zlib/gzlib.c deleted file mode 100644 index 7aedab8e..00000000 --- a/WDL/zlib/gzlib.c +++ /dev/null @@ -1,564 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const char *, int, const char *)); - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const char *path; - int fd; - const char *mode; -{ - gz_statep state; - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - case 'T': - state->direct = 1; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ - state->path = malloc(strlen(path) + 1); - if (state->path == NULL) { - free(state); - return NULL; - } - strcpy(state->path, path); - - /* open the file with the appropriate mode (or just use fd) */ - state->fd = fd != -1 ? fd : - open(path, -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | ( - state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))), - 0666); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; - sprintf(path, "", fd); /* for debugging */ - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->msg == NULL ? "" : state->msg; -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, save as static string */ - if (err == Z_MEM_ERROR) { - state->msg = (char *)msg; - return; - } - - /* construct error message with path */ - if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; - state->msg = (char *)"out of memory"; - return; - } - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); - return; -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/WDL/zlib/gzread.c b/WDL/zlib/gzread.c deleted file mode 100644 index 46d40e0b..00000000 --- a/WDL/zlib/gzread.c +++ /dev/null @@ -1,584 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ - int ret; - - *have = 0; - do { - ret = read(state->fd, buf + *have, len - *have); - if (ret <= 0) - break; - *have += ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) - memmove(state->in, strm->next_in, strm->avail_in); - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - unsigned got, n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return -1; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - continue; /* no progress yet -- go back to memcpy() above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) - return -1; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - strm->avail_out = len; - strm->next_out = buf; - if (gz_decomp(state) == -1) - return -1; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzgetc_(file) - gzFile file; -{ - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -#undef gzgetc -int ZEXPORT gzgetc(file) -gzFile file; -{ - return gzgetc_(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/WDL/zlib/gzwrite.c b/WDL/zlib/gzwrite.c deleted file mode 100644 index caa35b61..00000000 --- a/WDL/zlib/gzwrite.c +++ /dev/null @@ -1,593 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on failure or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer */ - state->in = malloc(state->want); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file, otherwise 0. - flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. If gz->direct - is true, then simply write to the output file without compressing, and - ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ - int ret, got; - unsigned have; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); - if (got < 0 || (unsigned)got != strm->avail_in) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in = 0; - return 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || - (unsigned)got != have)) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - state->x.next = strm->next_out; - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on error, 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - unsigned put = len; - unsigned n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - if (strm->avail_in == 0) - strm->next_in = state->in; - n = state->size - strm->avail_in; - if (n > len) - n = len; - memcpy(strm->next_in + strm->avail_in, buf, n); - strm->avail_in += n; - state->x.pos += n; - buf = (char *)buf + n; - len -= n; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (voidp)buf; - state->x.pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } - - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (strm->avail_in < state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - strm->next_in[strm->avail_in++] = c; - state->x.pos++; - return c & 0xff; - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ - int ret; - unsigned len; - - /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) -{ - int size, len; - gz_statep state; - z_streamp strm; - va_list va; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(state->in, format, va); - va_end(va); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = vsprintf(state->in, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(state->in, size, format, va); - va_end(va); - len = strlen(state->in); -# else - len = vsnprintf((char *)(state->in), size, format, va); - va_end(va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - int size, len; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return 0; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(state->in); -# else - len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* compress remaining data with requested flush */ - gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} - -/* used by zlibVersion() to get the vsnprintf story from the horse's mouth */ -unsigned long ZEXPORT gzflags() -{ - unsigned long flags = 0; -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} diff --git a/WDL/zlib/infback.c b/WDL/zlib/infback.c deleted file mode 100644 index 981aff17..00000000 --- a/WDL/zlib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/WDL/zlib/inffast.c b/WDL/zlib/inffast.c deleted file mode 100644 index 2f1d60b4..00000000 --- a/WDL/zlib/inffast.c +++ /dev/null @@ -1,340 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/WDL/zlib/inffast.h b/WDL/zlib/inffast.h deleted file mode 100644 index e5c1aa4c..00000000 --- a/WDL/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/WDL/zlib/inffixed.h b/WDL/zlib/inffixed.h deleted file mode 100644 index d6283277..00000000 --- a/WDL/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/WDL/zlib/inflate.c b/WDL/zlib/inflate.c deleted file mode 100644 index cc89517b..00000000 --- a/WDL/zlib/inflate.c +++ /dev/null @@ -1,1501 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - unsigned char *next; - unsigned avail; - int ret; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - next = strm->next_out; - avail = strm->avail_out; - strm->next_out = (Bytef *)dictionary + dictLength; - strm->avail_out = 0; - ret = updatewindow(strm, dictLength); - strm->avail_out = avail; - strm->next_out = next; - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/WDL/zlib/inflate.h b/WDL/zlib/inflate.h deleted file mode 100644 index 95f4986d..00000000 --- a/WDL/zlib/inflate.h +++ /dev/null @@ -1,122 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/WDL/zlib/inftrees.c b/WDL/zlib/inftrees.c deleted file mode 100644 index 60bbd58b..00000000 --- a/WDL/zlib/inftrees.c +++ /dev/null @@ -1,306 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.6 Copyright 1995-2012 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 69}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/WDL/zlib/inftrees.h b/WDL/zlib/inftrees.h deleted file mode 100644 index baa53a0b..00000000 --- a/WDL/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/WDL/zlib/ioapi.c b/WDL/zlib/ioapi.c deleted file mode 100644 index 7f5c191b..00000000 --- a/WDL/zlib/ioapi.c +++ /dev/null @@ -1,247 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - -*/ - -#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) - #define _CRT_SECURE_NO_WARNINGS -#endif - -#if defined(__APPLE__) || defined(IOAPI_NO_64) -// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions -#define FOPEN_FUNC(filename, mode) fopen(filename, mode) -#define FTELLO_FUNC(stream) ftello(stream) -#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) -#else -#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) -#define FTELLO_FUNC(stream) ftello64(stream) -#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) -#endif - - -#include "ioapi.h" - -voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) -{ - if (pfilefunc->zfile_func64.zopen64_file != NULL) - return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); - else - { - return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); - } -} - -long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) -{ - if (pfilefunc->zfile_func64.zseek64_file != NULL) - return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); - else - { - uLong offsetTruncated = (uLong)offset; - if (offsetTruncated != offset) - return -1; - else - return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); - } -} - -ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) -{ - if (pfilefunc->zfile_func64.zseek64_file != NULL) - return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); - else - { - uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); - if ((tell_uLong) == MAXU32) - return (ZPOS64_T)-1; - else - return tell_uLong; - } -} - -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) -{ - p_filefunc64_32->zfile_func64.zopen64_file = NULL; - p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; - p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; - p_filefunc64_32->zfile_func64.ztell64_file = NULL; - p_filefunc64_32->zfile_func64.zseek64_file = NULL; - p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; - p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; - p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; -} - - - -static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); -static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); -static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); -static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); -static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); - -static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) -{ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; -} - -static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) -{ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = FOPEN_FUNC((const char*)filename, mode_fopen); - return file; -} - - -static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) -{ - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) -{ - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) -{ - long ret; - ret = ftell((FILE *)stream); - return ret; -} - - -static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) -{ - ZPOS64_T ret; - ret = FTELLO_FUNC((FILE *)stream); - return ret; -} - -static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) -{ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - if (fseek((FILE *)stream, offset, fseek_origin) != 0) - ret = -1; - return ret; -} - -static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) -{ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - - if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) - ret = -1; - - return ret; -} - - -static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) -{ - int ret; - ret = fclose((FILE *)stream); - return ret; -} - -static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) -{ - int ret; - ret = ferror((FILE *)stream); - return ret; -} - -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; -{ - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} - -void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) -{ - pzlib_filefunc_def->zopen64_file = fopen64_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell64_file = ftell64_file_func; - pzlib_filefunc_def->zseek64_file = fseek64_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} diff --git a/WDL/zlib/ioapi.h b/WDL/zlib/ioapi.h deleted file mode 100644 index 8dcbdb06..00000000 --- a/WDL/zlib/ioapi.h +++ /dev/null @@ -1,208 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - - Changes - - Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) - Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. - More if/def section may be needed to support other platforms - Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. - (but you should use iowin32.c for windows instead) - -*/ - -#ifndef _ZLIBIOAPI64_H -#define _ZLIBIOAPI64_H - -#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) - - // Linux needs this to support file operation on files larger then 4+GB - // But might need better if/def to select just the platforms that needs them. - - #ifndef __USE_FILE_OFFSET64 - #define __USE_FILE_OFFSET64 - #endif - #ifndef __USE_LARGEFILE64 - #define __USE_LARGEFILE64 - #endif - #ifndef _LARGEFILE64_SOURCE - #define _LARGEFILE64_SOURCE - #endif - #ifndef _FILE_OFFSET_BIT - #define _FILE_OFFSET_BIT 64 - #endif - -#endif - -#include -#include -#include "zlib.h" - -#if defined(USE_FILE32API) -#define fopen64 fopen -#define ftello64 ftell -#define fseeko64 fseek -#else -#ifdef __FreeBSD__ -#define fopen64 fopen -#define ftello64 ftello -#define fseeko64 fseeko -#endif -#ifdef _MSC_VER - #define fopen64 fopen - #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) - #define ftello64 _ftelli64 - #define fseeko64 _fseeki64 - #else // old MSC - #define ftello64 ftell - #define fseeko64 fseek - #endif -#endif -#endif - -/* -#ifndef ZPOS64_T - #ifdef _WIN32 - #define ZPOS64_T fpos_t - #else - #include - #define ZPOS64_T uint64_t - #endif -#endif -*/ - -#ifdef HAVE_MINIZIP64_CONF_H -#include "mz64conf.h" -#endif - -/* a type choosen by DEFINE */ -#ifdef HAVE_64BIT_INT_CUSTOM -typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; -#else -#ifdef HAS_STDINT_H -#include "stdint.h" -typedef uint64_t ZPOS64_T; -#else - -/* Maximum unsigned 32-bit value used as placeholder for zip64 */ -#define MAXU32 0xffffffff - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef unsigned __int64 ZPOS64_T; -#else -typedef unsigned long long int ZPOS64_T; -#endif -#endif -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) - #define ZCALLBACK CALLBACK - #else - #define ZCALLBACK - #endif -#endif - - - - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); - - -/* here is the "old" 32 bits structure structure */ -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - -typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); - -typedef struct zlib_filefunc64_def_s -{ - open64_file_func zopen64_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell64_file_func ztell64_file; - seek64_file_func zseek64_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc64_def; - -void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -/* now internal definition, only for zip.c and unzip.h */ -typedef struct zlib_filefunc64_32_def_s -{ - zlib_filefunc64_def zfile_func64; - open_file_func zopen32_file; - tell_file_func ztell32_file; - seek_file_func zseek32_file; -} zlib_filefunc64_32_def; - - -#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) -//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) - -voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); -long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); -ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); - -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); - -#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) -#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) -#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/WDL/zlib/trees.c b/WDL/zlib/trees.c deleted file mode 100644 index 8c32b214..00000000 --- a/WDL/zlib/trees.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2012 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/WDL/zlib/trees.h b/WDL/zlib/trees.h deleted file mode 100644 index d35639d8..00000000 --- a/WDL/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/WDL/zlib/uncompr.c b/WDL/zlib/uncompr.c deleted file mode 100644 index ad98be3a..00000000 --- a/WDL/zlib/uncompr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/WDL/zlib/unzip.c b/WDL/zlib/unzip.c deleted file mode 100644 index affad4bf..00000000 --- a/WDL/zlib/unzip.c +++ /dev/null @@ -1,2125 +0,0 @@ -/* unzip.c -- IO for uncompress .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications of Unzip for Zip64 - Copyright (C) 2007-2008 Even Rouault - - Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - - - ------------------------------------------------------------------------------------ - Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of - compatibility with older software. The following is from the original crypt.c. - Code woven in by Terry Thorsen 1/2003. - - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html - - crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - ------------------------------------------------------------------------------------ - - Changes in unzip.c - - 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos - 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* - 2007-2008 - Even Rouault - Remove old C style function prototypes - 2007-2008 - Even Rouault - Add unzip support for ZIP64 - - Copyright (C) 2007-2008 Even Rouault - - - Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). - Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G - should only read the compressed/uncompressed size from the Zip64 format if - the size from normal header was 0xFFFFFFFF - Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant - Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) - Patch created by Daniel Borca - - Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer - - Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson - -*/ - - -#include -#include -#include - -#ifndef NOUNCRYPT - #define NOUNCRYPT -#endif - -#include "zlib.h" -#include "unzip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - - -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - -const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info64_internal_s -{ - ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ -} unz_file_info64_internal; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - -#ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ -#endif - - ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ - - ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ - ZPOS64_T total_out_64; - - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ - ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; -} file_in_zip64_read_info_s; - - -/* unz64_s contain internal information about the zipfile -*/ -typedef struct -{ - zlib_filefunc64_32_def z_filefunc; - int is64bitOpenFunction; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info64 gi; /* public global information */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - ZPOS64_T num_file; /* number of the current file in the zipfile*/ - ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ - ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ - ZPOS64_T central_pos; /* position of the beginning of the central dir*/ - - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info64 cur_file_info; /* public info about the current file in zip*/ - unz_file_info64_internal cur_file_info_internal; /* private info about it*/ - file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; - - int isZip64; - -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif -} unz64_s; - - -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unz64local_getByte OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) -{ - unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unz64local_getShort OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) -{ - uLong x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unz64local_getLong OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) -{ - uLong x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unz64local_getLong64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX)); - - -local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX) -{ - ZPOS64_T x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<24; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<32; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<40; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<48; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<56; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, - const char* fileName2, - int iCaseSensitivity) - -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); -local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - - -/* - Locate the Central directory 64 of a zipfile (at the end, just before - the global comment) -*/ -local ZPOS64_T unz64local_SearchCentralDir64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream)); - -local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream) -{ - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - uLong uL; - ZPOS64_T relativeOffset; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - if (uPosFound == 0) - return 0; - - /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature, already checked */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - - /* number of the disk with the start of the zip64 end of central directory */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - if (uL != 0) - return 0; - - /* relative offset of the zip64 end of central directory record */ - if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) - return 0; - - /* total number of disks */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - if (uL != 1) - return 0; - - /* Goto end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - - if (uL != 0x06064b50) - return 0; - - return relativeOffset; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -local unzFile unzOpenInternal (const void *path, - zlib_filefunc64_32_def* pzlib_filefunc64_32_def, - int is64bitOpenFunction) -{ - unz64_s us; - unz64_s *s; - ZPOS64_T central_pos; - uLong uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - if (unz_copyright[0]!=' ') - return NULL; - - us.z_filefunc.zseek32_file = NULL; - us.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) - fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); - else - us.z_filefunc = *pzlib_filefunc64_32_def; - us.is64bitOpenFunction = is64bitOpenFunction; - - - - us.filestream = ZOPEN64(us.z_filefunc, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; - - central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); - if (central_pos) - { - uLong uS; - ZPOS64_T uL64; - - us.isZip64 = 1; - - if (ZSEEK64(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* size of zip64 end of central directory record */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) - err=UNZ_ERRNO; - - /* version made by */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; - - /* version needed to extract */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central directory on this disk */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - us.gi.size_comment = 0; - } - else - { - central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; - - us.isZip64 = 0; - - if (ZSEEK64(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.gi.number_entry = uL; - - /* total number of entries in the central dir */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - number_entry_CD = uL; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.size_central_dir = uL; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.offset_central_dir = uL; - - /* zipfile comment length */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - } - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - ZCLOSE64(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) -{ - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - -extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) -{ - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - /* to do : check if number_entry is not truncated */ - pglobal_info32->number_entry = (uLong)s->gi.number_entry; - pglobal_info32->size_comment = s->gi.size_comment; - return UNZ_OK; -} -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) -{ - ZPOS64_T uDate; - uDate = (ZPOS64_T)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -local int unz64local_GetCurrentFileInfoInternal (unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize) -{ - unz64_s* s; - unz_file_info64 file_info; - unz_file_info64_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - uLong uL; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) - { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info.compressed_size = uL; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info.uncompressed_size = uL; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - // relative offset of local header - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info_internal.offset_curfile = uL; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - // Read extrafield - if ((err==UNZ_OK) && (extraField!=NULL)) - { - ZPOS64_T uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - - lSeek += file_info.size_file_extra - (uLong)uSizeRead; - } - else - lSeek += file_info.size_file_extra; - - - if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) - { - uLong acc = 0; - - // since lSeek now points to after the extra field we need to move back - lSeek -= file_info.size_file_extra; - - if (lSeek!=0) - { - if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - - while(acc < file_info.size_file_extra) - { - uLong headerId; - uLong dataSize; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) - err=UNZ_ERRNO; - - /* ZIP64 extra fields */ - if (headerId == 0x0001) - { - uLong uL; - - if(file_info.uncompressed_size == MAXU32) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.compressed_size == MAXU32) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info_internal.offset_curfile == MAXU32) - { - /* Relative Header offset */ - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.disk_num_start == MAXU32) - { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - } - - } - else - { - if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) - err=UNZ_ERRNO; - } - - acc += 2 + 2 + dataSize; - } - } - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, - unz_file_info64 * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) -{ - return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, - unz_file_info * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) -{ - int err; - unz_file_info64 file_info64; - err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); - if ((err==UNZ_OK) && (pfile_info != NULL)) - { - pfile_info->version = file_info64.version; - pfile_info->version_needed = file_info64.version_needed; - pfile_info->flag = file_info64.flag; - pfile_info->compression_method = file_info64.compression_method; - pfile_info->dosDate = file_info64.dosDate; - pfile_info->crc = file_info64.crc; - - pfile_info->size_filename = file_info64.size_filename; - pfile_info->size_file_extra = file_info64.size_file_extra; - pfile_info->size_file_comment = file_info64.size_file_comment; - - pfile_info->disk_num_start = file_info64.disk_num_start; - pfile_info->internal_fa = file_info64.internal_fa; - pfile_info->external_fa = file_info64.external_fa; - - pfile_info->tmu_date = file_info64.tmu_date, - - - pfile_info->compressed_size = (uLong)file_info64.compressed_size; - pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; - - } - return err; -} -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (unzFile file) -{ - int err=UNZ_OK; - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (unzFile file) -{ - unz64_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) -{ - unz64_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info64 cur_file_infoSaved; - unz_file_info64_internal cur_file_info_internalSaved; - ZPOS64_T num_fileSaved; - ZPOS64_T pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo64(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - ZPOS64_T pos_in_zip_directory; // offset in file - ZPOS64_T num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) -{ - unz64_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos) -{ - unz64_file_pos file_pos64; - int err = unzGetFilePos64(file,&file_pos64); - if (err==UNZ_OK) - { - file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; - file_pos->num_of_file = (uLong)file_pos64.num_of_file; - } - return err; -} - -extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) -{ - unz64_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos) -{ - unz64_file_pos file_pos64; - if (file_pos == NULL) - return UNZ_PARAMERROR; - - file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; - file_pos64.num_of_file = file_pos->num_of_file; - return unzGoToFilePos64(file,&file_pos64); -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, - ZPOS64_T * poffset_local_extrafield, - uInt * psize_local_extrafield) -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) - { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, - int* level, int raw, const char* password) -{ - int err=UNZ_OK; - uInt iSizeVar; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->total_out_64=0; - pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) - { -#ifdef HAVE_BZIP2 - pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; - pfile_in_zip_read_info->bstream.bzfree = (free_func)0; - pfile_in_zip_read_info->bstream.opaque = (voidpf)0; - pfile_in_zip_read_info->bstream.state = (voidpf)0; - - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } -#else - pfile_in_zip_read_info->raw=1; -#endif - } - else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = 0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - s->pfile_in_zip_read = pfile_in_zip_read_info; - s->encrypted = 0; - -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; -} - -extern int ZEXPORT unzOpenCurrentFile (unzFile file) -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -/** Addition for GDAL : START */ - -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) -{ - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - s=(unz64_s*)file; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - pfile_in_zip_read_info=s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return 0; //UNZ_PARAMERROR; - return pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile; -} - -/** Addition for GDAL : END */ - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) -{ - int err=UNZ_OK; - uInt iRead = 0; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if (pfile_in_zip_read_info->read_buffer == NULL) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) - { -#ifdef HAVE_BZIP2 - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - - pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; - pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; - pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; - pfile_in_zip_read_info->bstream.total_in_hi32 = 0; - pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; - pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; - pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; - pfile_in_zip_read_info->bstream.total_out_hi32 = 0; - - uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; - bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; - - err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); - - uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); - pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; - pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; - pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; - pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; - pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; - pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; - - if (err==BZ_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=BZ_OK) - break; -#endif - } // end Z_BZIP2ED - else - { - ZPOS64_T uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - ZPOS64_T uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; - - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (unzFile file) -{ - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; -} - -extern ZPOS64_T ZEXPORT unztell64 (unzFile file) -{ - - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return (ZPOS64_T)-1; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return (ZPOS64_T)-1; - - return pfile_in_zip_read_info->total_out_64; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (unzFile file) -{ - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* -Read extra field from the current file (opened by unzOpenCurrentFile) -This is the local-header version of the extra field (sometimes, there is -more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) -{ - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - uInt read_now; - ZPOS64_T size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (unzFile file) -{ - int err=UNZ_OK; - - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) - inflateEnd(&pfile_in_zip_read_info->stream); -#ifdef HAVE_BZIP2 - else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) - BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); -#endif - - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) -{ - unz64_s* s; - uLong uReadThis ; - if (file==NULL) - return (int)UNZ_PARAMERROR; - s=(unz64_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* Additions by RX '2004 */ -extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) -{ - unz64_s* s; - - if (file==NULL) - return 0; //UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; -} - -extern uLong ZEXPORT unzGetOffset (unzFile file) -{ - ZPOS64_T offset64; - - if (file==NULL) - return 0; //UNZ_PARAMERROR; - offset64 = unzGetOffset64(file); - return (uLong)offset64; -} - -extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) -{ - unz64_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) -{ - return unzSetOffset64(file,pos); -} diff --git a/WDL/zlib/unzip.h b/WDL/zlib/unzip.h deleted file mode 100644 index 3183968b..00000000 --- a/WDL/zlib/unzip.h +++ /dev/null @@ -1,437 +0,0 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications of Unzip for Zip64 - Copyright (C) 2007-2008 Even Rouault - - Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - - --------------------------------------------------------------------------------- - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - --------------------------------------------------------------------------------- - - Changes - - See header of unzip64.c - -*/ - -#ifndef _unz64_H -#define _unz64_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#ifdef HAVE_BZIP2 -#include "bzlib.h" -#endif - -#define Z_BZIP2ED 12 - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info64_s -{ - ZPOS64_T number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info64; - -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info64_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - ZPOS64_T compressed_size; /* compressed size 8 bytes */ - ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info64; - -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -extern unzFile ZEXPORT unzOpen64 OF((const void *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. - the "64" function take a const void* pointer, because the path is just the - value passed to the open64_file_func callback. - Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path - is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* - does not describe the reality -*/ - - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, - zlib_filefunc64_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unz64Open, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); - -extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, - unz_global_info64 *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -typedef struct unz64_file_pos_s -{ - ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ - ZPOS64_T num_of_file; /* # of file */ -} unz64_file_pos; - -extern int ZEXPORT unzGetFilePos64( - unzFile file, - unz64_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos64( - unzFile file, - const unz64_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, - unz_file_info64 *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - - -/** Addition for GDAL : START */ - -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); - -/** Addition for GDAL : END */ - - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); - -extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz64_H */ diff --git a/WDL/zlib/zconf.h b/WDL/zlib/zconf.h deleted file mode 100644 index 51c80ac1..00000000 --- a/WDL/zlib/zconf.h +++ /dev/null @@ -1,466 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2011 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflags z_gzflags -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# endif -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# ifndef Z_SOLO -# define gz_header_s z_gz_header_s -# endif -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define Z_LARGE -#endif - -#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO) -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0) -# define z_off64_t off64_t -#else -# if defined(_WIN32) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -#endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/WDL/zlib/zconf.in.h b/WDL/zlib/zconf.in.h deleted file mode 100644 index e3b0c962..00000000 --- a/WDL/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/WDL/zlib/zip.c b/WDL/zlib/zip.c deleted file mode 100644 index deb9b3a9..00000000 --- a/WDL/zlib/zip.c +++ /dev/null @@ -1,2012 +0,0 @@ -/* zip.c -- IO on .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - - Changes - Oct-2009 - Mathias Svensson - Remove old C style function prototypes - Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives - Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. - Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data - It is used when recreting zip archive with RAW when deleting items from a zip. - ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. - Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) - Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer - -*/ - - -#include -#include -#include -#include -#include "zlib.h" -#include "zip.h" - - -#ifndef NOCRYPT - #define NOCRYPT -#endif - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ -#endif - -#ifndef Z_BUFSIZE -#define Z_BUFSIZE (64*1024) //(16384) -#endif - -#ifndef Z_MAXFILENAMEINZIP -#define Z_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -/* -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) -*/ - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - - -// NOT sure that this work on ALL platform -#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#ifndef DEF_MEM_LEVEL -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -#endif -const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - - -#define SIZEDATA_INDATABLOCK (4096-(4*4)) - -#define LOCALHEADERMAGIC (0x04034b50) -#define CENTRALHEADERMAGIC (0x02014b50) -#define ENDHEADERMAGIC (0x06054b50) -#define ZIP64ENDHEADERMAGIC (0x6064b50) -#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) - -#define FLAG_LOCALHEADER_OFFSET (0x06) -#define CRC_LOCALHEADER_OFFSET (0x0e) - -#define SIZECENTRALHEADER (0x2e) /* 46 */ - -typedef struct linkedlist_datablock_internal_s -{ - struct linkedlist_datablock_internal_s* next_datablock; - uLong avail_in_this_block; - uLong filled_in_this_block; - uLong unused; /* for future use and alignement */ - unsigned char data[SIZEDATA_INDATABLOCK]; -} linkedlist_datablock_internal; - -typedef struct linkedlist_data_s -{ - linkedlist_datablock_internal* first_block; - linkedlist_datablock_internal* last_block; -} linkedlist_data; - - -typedef struct -{ - z_stream stream; /* zLib stream structure for inflate */ -#ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ -#endif - - int stream_initialised; /* 1 is stream is initialised */ - uInt pos_in_buffered_data; /* last written byte in buffered_data */ - - ZPOS64_T pos_local_header; /* offset of the local header of the file - currenty writing */ - char* central_header; /* central header data for the current file */ - uLong size_centralExtra; - uLong size_centralheader; /* size of the central header for cur file */ - uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ - uLong flag; /* flag of the file currently writing */ - - int method; /* compression method of file currenty wr.*/ - int raw; /* 1 for directly writing raw data */ - Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ - uLong dosDate; - uLong crc32; - int encrypt; - int zip64; /* Add ZIP64 extened information in the extra field */ - ZPOS64_T pos_zip64extrainfo; - ZPOS64_T totalCompressedData; - ZPOS64_T totalUncompressedData; -#ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; - int crypt_header_size; -#endif -} curfile64_info; - -typedef struct -{ - zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - linkedlist_data central_dir;/* datablock with central dir in construction*/ - int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile64_info ci; /* info on the file curretly writing */ - - ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ - ZPOS64_T add_position_when_writting_offset; - ZPOS64_T number_entry; - -#ifndef NO_ADDFILEINEXISTINGZIP - char *globalcomment; -#endif - -} zip64_internal; - - -#ifndef NOCRYPT -#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#include "crypt.h" -#endif - -local linkedlist_datablock_internal* allocate_new_datablock() -{ - linkedlist_datablock_internal* ldi; - ldi = (linkedlist_datablock_internal*) - ALLOC(sizeof(linkedlist_datablock_internal)); - if (ldi!=NULL) - { - ldi->next_datablock = NULL ; - ldi->filled_in_this_block = 0 ; - ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; - } - return ldi; -} - -local void free_datablock(linkedlist_datablock_internal* ldi) -{ - while (ldi!=NULL) - { - linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE(ldi); - ldi = ldinext; - } -} - -local void init_linkedlist(linkedlist_data* ll) -{ - ll->first_block = ll->last_block = NULL; -} - -local void free_linkedlist(linkedlist_data* ll) -{ - free_datablock(ll->first_block); - ll->first_block = ll->last_block = NULL; -} - - -local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) -{ - linkedlist_datablock_internal* ldi; - const unsigned char* from_copy; - - if (ll==NULL) - return ZIP_INTERNALERROR; - - if (ll->last_block == NULL) - { - ll->first_block = ll->last_block = allocate_new_datablock(); - if (ll->first_block == NULL) - return ZIP_INTERNALERROR; - } - - ldi = ll->last_block; - from_copy = (unsigned char*)buf; - - while (len>0) - { - uInt copy_this; - uInt i; - unsigned char* to_copy; - - if (ldi->avail_in_this_block==0) - { - ldi->next_datablock = allocate_new_datablock(); - if (ldi->next_datablock == NULL) - return ZIP_INTERNALERROR; - ldi = ldi->next_datablock ; - ll->last_block = ldi; - } - - if (ldi->avail_in_this_block < len) - copy_this = (uInt)ldi->avail_in_this_block; - else - copy_this = (uInt)len; - - to_copy = &(ldi->data[ldi->filled_in_this_block]); - - for (i=0;ifilled_in_this_block += copy_this; - ldi->avail_in_this_block -= copy_this; - from_copy += copy_this ; - len -= copy_this; - } - return ZIP_OK; -} - - - -/****************************************************************************/ - -#ifndef NO_ADDFILEINEXISTINGZIP -/* =========================================================================== - Inputs a long in LSB order to the given file - nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) -*/ - -local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); -local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) -{ - unsigned char buf[8]; - int n; - for (n = 0; n < nbByte; n++) - { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } - if (x != 0) - { /* data overflow - hack for ZIP64 (X Roche) */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } - - if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) - return ZIP_ERRNO; - else - return ZIP_OK; -} - -local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); -local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) -{ - unsigned char* buf=(unsigned char*)dest; - int n; - for (n = 0; n < nbByte; n++) { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } - - if (x != 0) - { /* data overflow - hack for ZIP64 */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } -} - -/****************************************************************************/ - - -local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) -{ - uLong year = (uLong)ptm->tm_year; - if (year>=1980) - year-=1980; - else if (year>=80) - year-=80; - return - (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | - ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); -} - - -/****************************************************************************/ - -local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); - -local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) -{ - unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return ZIP_OK; - } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return ZIP_ERRNO; - else - return ZIP_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ - uLong x ; - int i = 0; - int err; - - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ - uLong x ; - int i = 0; - int err; - - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); - - -local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) -{ - ZPOS64_T x; - int i = 0; - int err; - - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<8; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<16; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<24; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<32; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<40; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<48; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<56; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - - return err; -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -/* -Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before -the global comment) -*/ -local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - uLong uL; - ZPOS64_T relativeOffset; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - { - // Signature "0x07064b50" Zip64 end of central directory locater - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } - } - - if (uPosFound!=0) - break; - } - - TRYFREE(buf); - if (uPosFound == 0) - return 0; - - /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature, already checked */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - - /* number of the disk with the start of the zip64 end of central directory */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 0) - return 0; - - /* relative offset of the zip64 end of central directory record */ - if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) - return 0; - - /* total number of disks */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 1) - return 0; - - /* Goto Zip64 end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - - if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' - return 0; - - return relativeOffset; -} - -int LoadCentralDirectoryRecord(zip64_internal* pziinit) -{ - int err=ZIP_OK; - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory */ - ZPOS64_T central_pos; - uLong uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry; - ZPOS64_T number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - uLong VersionMadeBy; - uLong VersionNeeded; - uLong size_comment; - - int hasZIP64Record = 0; - - // check first if we find a ZIP64 record - central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); - if(central_pos > 0) - { - hasZIP64Record = 1; - } - else if(central_pos == 0) - { - central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); - } - -/* disable to allow appending to empty ZIP archive - if (central_pos==0) - err=ZIP_ERRNO; -*/ - - if(hasZIP64Record) - { - ZPOS64_T sizeEndOfCentralDirectory; - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; - - /* size of zip64 end of central directory record */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) - err=ZIP_ERRNO; - - /* version made by */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) - err=ZIP_ERRNO; - - /* version needed to extract */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of this disk */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of the disk with the start of the central directory */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central directory on this disk */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; - - /* size of the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - // TODO.. - // read the comment from the standard central header. - size_comment = 0; - } - else - { - // Read End of central Directory info - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=ZIP_ERRNO; - - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of this disk */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of the disk with the start of the central directory */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central dir on this disk */ - number_entry = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry = uL; - - /* total number of entries in the central dir */ - number_entry_CD = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry_CD = uL; - - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; - - /* size of the central directory */ - size_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - size_central_dir = uL; - - /* offset of start of central directory with respect to the starting disk number */ - offset_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - offset_central_dir = uL; - - - /* zipfile global comment length */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) - err=ZIP_ERRNO; - } - - if ((central_posz_filefunc, pziinit->filestream); - return ZIP_ERRNO; - } - - if (size_comment>0) - { - pziinit->globalcomment = (char*)ALLOC(size_comment+1); - if (pziinit->globalcomment) - { - size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); - pziinit->globalcomment[size_comment]=0; - } - } - - byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); - pziinit->add_position_when_writting_offset = byte_before_the_zipfile; - - { - ZPOS64_T size_central_dir_to_read = size_central_dir; - size_t buf_size = SIZEDATA_INDATABLOCK; - void* buf_read = (void*)ALLOC(buf_size); - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - while ((size_central_dir_to_read>0) && (err==ZIP_OK)) - { - ZPOS64_T read_this = SIZEDATA_INDATABLOCK; - if (read_this > size_central_dir_to_read) - read_this = size_central_dir_to_read; - - if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) - err=ZIP_ERRNO; - - if (err==ZIP_OK) - err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); - - size_central_dir_to_read-=read_this; - } - TRYFREE(buf_read); - } - pziinit->begin_pos = byte_before_the_zipfile; - pziinit->number_entry = number_entry_CD; - - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - return err; -} - - -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - - -/************************************************************/ -extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) -{ - zip64_internal ziinit; - zip64_internal* zi; - int err=ZIP_OK; - - ziinit.z_filefunc.zseek32_file = NULL; - ziinit.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) - fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); - else - ziinit.z_filefunc = *pzlib_filefunc64_32_def; - - ziinit.filestream = ZOPEN64(ziinit.z_filefunc, - pathname, - (append == APPEND_STATUS_CREATE) ? - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); - - if (ziinit.filestream == NULL) - return NULL; - - if (append == APPEND_STATUS_CREATEAFTER) - ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); - - ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); - ziinit.in_opened_file_inzip = 0; - ziinit.ci.stream_initialised = 0; - ziinit.number_entry = 0; - ziinit.add_position_when_writting_offset = 0; - init_linkedlist(&(ziinit.central_dir)); - - - - zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); - if (zi==NULL) - { - ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); - return NULL; - } - - /* now we add file in a zipfile */ -# ifndef NO_ADDFILEINEXISTINGZIP - ziinit.globalcomment = NULL; - if (append == APPEND_STATUS_ADDINZIP) - { - // Read and Cache Central Directory Records - err = LoadCentralDirectoryRecord(&ziinit); - } - - if (globalcomment) - { - *globalcomment = ziinit.globalcomment; - } -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - - if (err != ZIP_OK) - { -# ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(ziinit.globalcomment); -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE(zi); - return NULL; - } - else - { - *zi = ziinit; - return (zipFile)zi; - } -} - -extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) -{ - if (pzlib_filefunc32_def != NULL) - { - zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; - fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); - } - else - return zipOpen3(pathname, append, globalcomment, NULL); -} - -extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - { - zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; - zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; - zlib_filefunc64_32_def_fill.ztell32_file = NULL; - zlib_filefunc64_32_def_fill.zseek32_file = NULL; - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); - } - else - return zipOpen3(pathname, append, globalcomment, NULL); -} - - - -extern zipFile ZEXPORT zipOpen (const char* pathname, int append) -{ - return zipOpen3((const void*)pathname,append,NULL,NULL); -} - -extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) -{ - return zipOpen3(pathname,append,NULL,NULL); -} - -int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) -{ - /* write the local header */ - int err; - uInt size_filename = (uInt)strlen(filename); - uInt size_extrafield = size_extrafield_local; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); - - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); - - // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ - } - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); - - if(zi->ci.zip64) - { - size_extrafield += 20; - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); - - if ((err==ZIP_OK) && (size_filename > 0)) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) - err = ZIP_ERRNO; - } - - if ((err==ZIP_OK) && (size_extrafield_local > 0)) - { - if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) - err = ZIP_ERRNO; - } - - - if ((err==ZIP_OK) && (zi->ci.zip64)) - { - // write the Zip64 extended info - short HeaderID = 1; - short DataSize = 16; - ZPOS64_T CompressedSize = 0; - ZPOS64_T UncompressedSize = 0; - - // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) - zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); - - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); - - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); - } - - return err; -} - -/* - NOTE. - When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped - before calling this function it can be done with zipRemoveExtraInfoBlock - - It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize - unnecessary allocations. - */ -extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase, int zip64) -{ - zip64_internal* zi; - uInt size_filename; - uInt size_comment; - uInt i; - int err = ZIP_OK; - -# ifdef NOCRYPT - (crcForCrypting); - if (password != NULL) - return ZIP_PARAMERROR; -# endif - - if (file == NULL) - return ZIP_PARAMERROR; - -#ifdef HAVE_BZIP2 - if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) - return ZIP_PARAMERROR; -#else - if ((method!=0) && (method!=Z_DEFLATED)) - return ZIP_PARAMERROR; -#endif - - zi = (zip64_internal*)file; - - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - if (err != ZIP_OK) - return err; - } - - if (filename==NULL) - filename="-"; - - if (comment==NULL) - size_comment = 0; - else - size_comment = (uInt)strlen(comment); - - size_filename = (uInt)strlen(filename); - - if (zipfi == NULL) - zi->ci.dosDate = 0; - else - { - if (zipfi->dosDate != 0) - zi->ci.dosDate = zipfi->dosDate; - else - zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); - } - - zi->ci.flag = flagBase; - if ((level==8) || (level==9)) - zi->ci.flag |= 2; - if ((level==2)) - zi->ci.flag |= 4; - if ((level==1)) - zi->ci.flag |= 6; - if (password != NULL) - zi->ci.flag |= 1; - - zi->ci.crc32 = 0; - zi->ci.method = method; - zi->ci.encrypt = 0; - zi->ci.stream_initialised = 0; - zi->ci.pos_in_buffered_data = 0; - zi->ci.raw = raw; - zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); - - zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; - zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data - - zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); - - zi->ci.size_centralExtra = size_extrafield_global; - zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); - /* version info */ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); - zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); - zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); - zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); - zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ - zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); - zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); - zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ - - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); - else - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); - - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); - else - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); - - if(zi->ci.pos_local_header >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); - else - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); - - for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = - *(((const char*)extrafield_global)+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ - size_extrafield_global+i) = *(comment+i); - if (zi->ci.central_header == NULL) - return ZIP_INTERNALERROR; - - zi->ci.zip64 = zip64; - zi->ci.totalCompressedData = 0; - zi->ci.totalUncompressedData = 0; - zi->ci.pos_zip64extrainfo = 0; - - err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); - -#ifdef HAVE_BZIP2 - zi->ci.bstream.avail_in = (uInt)0; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - zi->ci.bstream.total_in_hi32 = 0; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_out_hi32 = 0; - zi->ci.bstream.total_out_lo32 = 0; -#endif - - zi->ci.stream.avail_in = (uInt)0; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - zi->ci.stream.total_in = 0; - zi->ci.stream.total_out = 0; - zi->ci.stream.data_type = Z_BINARY; - -#ifdef HAVE_BZIP2 - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) -#else - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) -#endif - { - if(zi->ci.method == Z_DEFLATED) - { - zi->ci.stream.zalloc = (alloc_func)0; - zi->ci.stream.zfree = (free_func)0; - zi->ci.stream.opaque = (voidpf)0; - - if (windowBits>0) - windowBits = -windowBits; - - err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); - - if (err==Z_OK) - zi->ci.stream_initialised = Z_DEFLATED; - } - else if(zi->ci.method == Z_BZIP2ED) - { -#ifdef HAVE_BZIP2 - // Init BZip stuff here - zi->ci.bstream.bzalloc = 0; - zi->ci.bstream.bzfree = 0; - zi->ci.bstream.opaque = (voidpf)0; - - err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); - if(err == BZ_OK) - zi->ci.stream_initialised = Z_BZIP2ED; -#endif - } - - } - -# ifndef NOCRYPT - zi->ci.crypt_header_size = 0; - if ((err==Z_OK) && (password != NULL)) - { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; - zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = get_crc_table(); - /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ - - sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); - zi->ci.crypt_header_size = sizeHead; - - if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) - err = ZIP_ERRNO; - } -# endif - - if (err==Z_OK) - zi->in_opened_file_inzip = 1; - return err; -} - -extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, versionMadeBy, flagBase, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, zip64); -} - -extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); -} - -extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); -} - -extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); -} - -local int zip64FlushWriteBuffer(zip64_internal* zi) -{ - int err=ZIP_OK; - - if (zi->ci.encrypt != 0) - { -#ifndef NOCRYPT - uInt i; - int t; - for (i=0;ici.pos_in_buffered_data;i++) - zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); -#endif - } - - if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) - err = ZIP_ERRNO; - - zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; - -#ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED) - { - zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_in_hi32 = 0; - } - else -#endif - { - zi->ci.totalUncompressedData += zi->ci.stream.total_in; - zi->ci.stream.total_in = 0; - } - - - zi->ci.pos_in_buffered_data = 0; - - return err; -} - -extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) -{ - zip64_internal* zi; - int err=ZIP_OK; - - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip64_internal*)file; - - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; - - zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); - -#ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) - { - zi->ci.bstream.next_in = (void*)buf; - zi->ci.bstream.avail_in = len; - err = BZ_RUN_OK; - - while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) - { - if (zi->ci.bstream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } - - - if(err != BZ_RUN_OK) - break; - - if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; -// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; - } - } - - if(err == BZ_RUN_OK) - err = ZIP_OK; - } - else -#endif - { - zi->ci.stream.next_in = (Bytef*)buf; - zi->ci.stream.avail_in = len; - - while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) - { - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - - - if(err != ZIP_OK) - break; - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_NO_FLUSH); - if(uTotalOutBefore > zi->ci.stream.total_out) - { - int bBreak = 0; - bBreak++; - } - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - else - { - uInt copy_this,i; - if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) - copy_this = zi->ci.stream.avail_in; - else - copy_this = zi->ci.stream.avail_out; - - for (i = 0; i < copy_this; i++) - *(((char*)zi->ci.stream.next_out)+i) = - *(((const char*)zi->ci.stream.next_in)+i); - { - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out-= copy_this; - zi->ci.stream.next_in+= copy_this; - zi->ci.stream.next_out+= copy_this; - zi->ci.stream.total_in+= copy_this; - zi->ci.stream.total_out+= copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - }// while(...) - } - - return err; -} - -extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) -{ - return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); -} - -extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) -{ - zip64_internal* zi; - ZPOS64_T compressed_size; - uLong invalidValue = 0xffffffff; - short datasize = 0; - int err=ZIP_OK; - - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip64_internal*)file; - - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; - zi->ci.stream.avail_in = 0; - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - while (err==ZIP_OK) - { - uLong uTotalOutBefore; - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_FINISH); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - } - else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { -#ifdef HAVE_BZIP2 - err = BZ_FINISH_OK; - while (err==BZ_FINISH_OK) - { - uLong uTotalOutBefore; - if (zi->ci.bstream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.bstream.total_out_lo32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); - if(err == BZ_STREAM_END) - err = Z_STREAM_END; - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); - } - - if(err == BZ_FINISH_OK) - err = ZIP_OK; -#endif - } - - if (err==Z_STREAM_END) - err=ZIP_OK; /* this is normal */ - - if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) - { - if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) - err = ZIP_ERRNO; - } - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - int tmp_err = deflateEnd(&zi->ci.stream); - if (err == ZIP_OK) - err = tmp_err; - zi->ci.stream_initialised = 0; - } -#ifdef HAVE_BZIP2 - else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); - if (err==ZIP_OK) - err = tmperr; - zi->ci.stream_initialised = 0; - } -#endif - - if (!zi->ci.raw) - { - crc32 = (uLong)zi->ci.crc32; - uncompressed_size = zi->ci.totalUncompressedData; - } - compressed_size = zi->ci.totalCompressedData; - -# ifndef NOCRYPT - compressed_size += zi->ci.crypt_header_size; -# endif - - // update Current Item crc and sizes, - if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) - { - /*version Made by*/ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); - /*version needed*/ - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); - - } - - zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ - - - if(compressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ - else - zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ - - /// set internal file attributes field - if (zi->ci.stream.data_type == Z_ASCII) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); - - if(uncompressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ - else - zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ - - // Add ZIP64 extra info field for uncompressed size - if(uncompressed_size >= 0xffffffff) - datasize += 8; - - // Add ZIP64 extra info field for compressed size - if(compressed_size >= 0xffffffff) - datasize += 8; - - // Add ZIP64 extra info field for relative offset to local file header of current file - if(zi->ci.pos_local_header >= 0xffffffff) - datasize += 8; - - if(datasize > 0) - { - char* p = NULL; - - if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) - { - // we can not write more data to the buffer that we have room for. - return ZIP_BADZIPFILE; - } - - p = zi->ci.central_header + zi->ci.size_centralheader; - - // Add Extra Information Header for 'ZIP64 information' - zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID - p += 2; - zip64local_putValue_inmemory(p, datasize, 2); // DataSize - p += 2; - - if(uncompressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, uncompressed_size, 8); - p += 8; - } - - if(compressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, compressed_size, 8); - p += 8; - } - - if(zi->ci.pos_local_header >= 0xffffffff) - { - zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); - p += 8; - } - - // Update how much extra free space we got in the memory buffer - // and increase the centralheader size so the new ZIP64 fields are included - // ( 4 below is the size of HeaderID and DataSize field ) - zi->ci.size_centralExtraFree -= datasize + 4; - zi->ci.size_centralheader += datasize + 4; - - // Update the extra info size field - zi->ci.size_centralExtra += datasize + 4; - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); - } - - if (err==ZIP_OK) - err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); - - free(zi->ci.central_header); - - if (err==ZIP_OK) - { - // Update the LocalFileHeader with the new values. - - ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); - - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ - - if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) - { - if(zi->ci.pos_zip64extrainfo > 0) - { - // Update the size in the ZIP64 extended field. - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); - - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); - } - else - err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal - } - else - { - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); - - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); - } - - if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - } - - zi->number_entry ++; - zi->in_opened_file_inzip = 0; - - return err; -} - -extern int ZEXPORT zipCloseFileInZip (zipFile file) -{ - return zipCloseFileInZipRaw (file,0,0); -} - -int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) -{ - int err = ZIP_OK; - ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); - - /*num disks*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - /*relative offset*/ - if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); - - /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); - - return err; -} - -int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ - int err = ZIP_OK; - - uLong Zip64DataSize = 44; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); - - if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? - - if (err==ZIP_OK) /* version made by */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); - - if (err==ZIP_OK) /* version needed */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); - - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - - if (err==ZIP_OK) /* total number of entries in the central dir */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); - - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); - } - return err; -} -int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ - int err = ZIP_OK; - - /*signature*/ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); - - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - { - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } - } - - if (err==ZIP_OK) /* total number of entries in the central dir */ - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } - - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); - - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff) - { - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); - } - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); - } - - return err; -} - -int Write_GlobalComment(zip64_internal* zi, const char* global_comment) -{ - int err = ZIP_OK; - uInt size_global_comment = 0; - - if(global_comment != NULL) - size_global_comment = (uInt)strlen(global_comment); - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); - - if (err == ZIP_OK && size_global_comment > 0) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) - err = ZIP_ERRNO; - } - return err; -} - -extern int ZEXPORT zipClose (zipFile file, const char* global_comment) -{ - zip64_internal* zi; - int err = 0; - uLong size_centraldir = 0; - ZPOS64_T centraldir_pos_inzip; - ZPOS64_T pos; - - if (file == NULL) - return ZIP_PARAMERROR; - - zi = (zip64_internal*)file; - - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - } - -#ifndef NO_ADDFILEINEXISTINGZIP - if (global_comment==NULL) - global_comment = zi->globalcomment; -#endif - - centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); - - if (err==ZIP_OK) - { - linkedlist_datablock_internal* ldi = zi->central_dir.first_block; - while (ldi!=NULL) - { - if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) - err = ZIP_ERRNO; - } - - size_centraldir += ldi->filled_in_this_block; - ldi = ldi->next_datablock; - } - } - free_linkedlist(&(zi->central_dir)); - - pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) - { - ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); - Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); - - Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); - } - - if (err==ZIP_OK) - err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); - - if(err == ZIP_OK) - err = Write_GlobalComment(zi, global_comment); - - if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) - if (err == ZIP_OK) - err = ZIP_ERRNO; - -#ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(zi->globalcomment); -#endif - TRYFREE(zi); - - return err; -} - -extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) -{ - char* p = pData; - int size = 0; - char* pNewHeader; - char* pTmp; - short header; - short dataSize; - - int retVal = ZIP_OK; - - if(pData == NULL || *dataLen < 4) - return ZIP_PARAMERROR; - - pNewHeader = (char*)ALLOC(*dataLen); - pTmp = pNewHeader; - - while(p < (pData + *dataLen)) - { - header = *(short*)p; - dataSize = *(((short*)p)+1); - - if( header == sHeader ) // Header found. - { - p += dataSize + 4; // skip it. do not copy to temp buffer - } - else - { - // Extra Info block should not be removed, So copy it to the temp buffer. - memcpy(pTmp, p, dataSize + 4); - p += dataSize + 4; - size += dataSize + 4; - } - - } - - if(size < *dataLen) - { - // clean old extra info block. - memset(pData,0, *dataLen); - - // copy the new extra info block over the old - if(size > 0) - memcpy(pData, pNewHeader, size); - - // set the new extra info size - *dataLen = size; - - retVal = ZIP_OK; - } - else - retVal = ZIP_ERRNO; - - TRYFREE(pNewHeader); - - return retVal; -} diff --git a/WDL/zlib/zip.h b/WDL/zlib/zip.h deleted file mode 100644 index 8aaebb62..00000000 --- a/WDL/zlib/zip.h +++ /dev/null @@ -1,362 +0,0 @@ -/* zip.h -- IO on .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt - - --------------------------------------------------------------------------- - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - --------------------------------------------------------------------------- - - Changes - - See header of zip.h - -*/ - -#ifndef _zip12_H -#define _zip12_H - -#ifdef __cplusplus -extern "C" { -#endif - -//#define HAVE_BZIP2 - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#ifdef HAVE_BZIP2 -#include "bzlib.h" -#endif - -#define Z_BZIP2ED 12 - -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zipFile__; -typedef zipFile__ *zipFile; -#else -typedef voidp zipFile; -#endif - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif -#endif -/* default memLevel */ - -/* tm_zip contain date/time info */ -typedef struct tm_zip_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_zip; - -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ - - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; - -typedef const char* zipcharpc; - - -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); -/* - Create a zipfile. - pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on - an Unix computer "zlib/zlib113.zip". - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ - -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ - -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); - -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_def)); - -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); - -extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int zip64)); - -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) - zip64 is set to 1 if a zip64 extended information block should be added to the local file header. - this MUST be '1' if the uncompressed size is >= 0xffffffff. - -*/ - - -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - - -extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int zip64)); -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file - */ - -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting)); - -extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - int zip64 - )); - -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 - password : crypting password (NULL for no crypting) - crcForCrypting : crc of file to compress (needed for crypting) - */ - -extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase - )); - - -extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase, - int zip64 - )); -/* - Same than zipOpenNewFileInZip4, except - versionMadeBy : value for Version made by field - flag : value for flag field (compression level info will be added) - */ - - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* - Write data in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* - Close the current file in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); - -extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, - ZPOS64_T uncompressed_size, - uLong crc32)); - -/* - Close the current file in the zipfile, for file opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ - -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* - Close the zipfile -*/ - - -extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); -/* - zipRemoveExtraInfoBlock - Added by Mathias Svensson - - Remove extra information block from a extra information data for the local file header or central directory header - - It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. - - 0x0001 is the signature header for the ZIP64 extra information blocks - - usage. - Remove ZIP64 Extra information from a central director extra field data - zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); - - Remove ZIP64 Extra information from a Local File Header extra field data - zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); -*/ - -#ifdef __cplusplus -} -#endif - -#endif /* _zip64_H */ diff --git a/WDL/zlib/zlib.h b/WDL/zlib/zlib.h deleted file mode 100644 index 4e1aea89..00000000 --- a/WDL/zlib/zlib.h +++ /dev/null @@ -1,1732 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.6, January 29th, 2012 - - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.6.f" -#define ZLIB_VERNUM 0x126f -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 6 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is not required to perform an - inflation in one step. However it may be used to inform inflate that a - faster approach can be used for the single inflate() call. Z_FINISH also - informs inflate to not maintain a sliding window if the stream completes, - which reduces inflate's memory footprint. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); -#define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc_(g)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef _LARGEFILE64_SOURCE - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#ifndef Z_SOLO - ZEXTERN unsigned long ZEXPORT gzflags OF((void)); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/WDL/zlib/zutil.c b/WDL/zlib/zutil.c deleted file mode 100644 index 835b4d46..00000000 --- a/WDL/zlib/zutil.c +++ /dev/null @@ -1,303 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - -#if 0 - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef Z_SOLO - return flags; -#else - return flags + gzflags(); -#endif -} -#endif - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/WDL/zlib/zutil.h b/WDL/zlib/zutil.h deleted file mode 100644 index dff1112f..00000000 --- a/WDL/zlib/zutil.h +++ /dev/null @@ -1,248 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2011 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/licecap/background.png b/background.png similarity index 100% rename from licecap/background.png rename to background.png diff --git a/licecap/capturewindow.mm b/capturewindow.mm similarity index 100% rename from licecap/capturewindow.mm rename to capturewindow.mm diff --git a/licecap/icon1.ico b/icon1.ico similarity index 100% rename from licecap/icon1.ico rename to icon1.ico diff --git a/licecap/installer.nsi b/installer.nsi similarity index 100% rename from licecap/installer.nsi rename to installer.nsi diff --git a/licecap/licecap-Info.plist b/licecap-Info.plist similarity index 100% rename from licecap/licecap-Info.plist rename to licecap-Info.plist diff --git a/licecap/licecap.dsw b/licecap.dsw similarity index 100% rename from licecap/licecap.dsw rename to licecap.dsw diff --git a/licecap/licecap.icns b/licecap.icns similarity index 100% rename from licecap/licecap.icns rename to licecap.icns diff --git a/licecap/licecap.rc b/licecap.rc similarity index 100% rename from licecap/licecap.rc rename to licecap.rc diff --git a/licecap/licecap.xcodeproj/project.pbxproj b/licecap.xcodeproj/project.pbxproj similarity index 100% rename from licecap/licecap.xcodeproj/project.pbxproj rename to licecap.xcodeproj/project.pbxproj diff --git a/licecap/licecap_Prefix.pch b/licecap_Prefix.pch similarity index 100% rename from licecap/licecap_Prefix.pch rename to licecap_Prefix.pch diff --git a/licecap/licecap_cli.cpp b/licecap_cli.cpp similarity index 100% rename from licecap/licecap_cli.cpp rename to licecap_cli.cpp diff --git a/licecap/licecap_cli.dsp b/licecap_cli.dsp similarity index 100% rename from licecap/licecap_cli.dsp rename to licecap_cli.dsp diff --git a/licecap/licecap_gui.dsp b/licecap_gui.dsp similarity index 100% rename from licecap/licecap_gui.dsp rename to licecap_gui.dsp diff --git a/licecap/licecap_ui.cpp b/licecap_ui.cpp similarity index 100% rename from licecap/licecap_ui.cpp rename to licecap_ui.cpp diff --git a/licecap/licecap_version.h b/licecap_version.h similarity index 100% rename from licecap/licecap_version.h rename to licecap_version.h diff --git a/licecap/license.txt b/license.txt similarity index 100% rename from licecap/license.txt rename to license.txt diff --git a/licecap/main.m b/main.m similarity index 100% rename from licecap/main.m rename to main.m diff --git a/licecap/makedmg.sh b/makedmg.sh similarity index 100% rename from licecap/makedmg.sh rename to makedmg.sh diff --git a/licecap/pkg-dmg b/pkg-dmg similarity index 100% rename from licecap/pkg-dmg rename to pkg-dmg diff --git a/licecap/requires_wdl.txt b/requires_wdl.txt similarity index 100% rename from licecap/requires_wdl.txt rename to requires_wdl.txt diff --git a/licecap/resource.h b/resource.h similarity index 100% rename from licecap/resource.h rename to resource.h diff --git a/licecap/stage_DS_Store b/stage_DS_Store similarity index 100% rename from licecap/stage_DS_Store rename to stage_DS_Store diff --git a/licecap/whatsnew.txt b/whatsnew.txt similarity index 100% rename from licecap/whatsnew.txt rename to whatsnew.txt From 71917ede534e3edd03c5968095dcd2424289b8a7 Mon Sep 17 00:00:00 2001 From: petec Date: Tue, 27 Aug 2013 00:08:58 -0400 Subject: [PATCH 2/6] Add WDL as submodule --- .gitmodules | 3 +++ WDL | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 WDL diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..045d21bc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "WDL"] + path = WDL + url = http://www-dev.cockos.com/wdl/WDL.git diff --git a/WDL b/WDL new file mode 160000 index 00000000..53ff5f1e --- /dev/null +++ b/WDL @@ -0,0 +1 @@ +Subproject commit 53ff5f1e4fefedc2bba9a3de1e1c4492c9b5a393 From 0340642df73d8ee5b751cfb9f38ec39304c8eda6 Mon Sep 17 00:00:00 2001 From: petec Date: Tue, 27 Aug 2013 01:53:47 -0400 Subject: [PATCH 3/6] Add README.md --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ docs/demo2.gif | Bin 0 -> 397813 bytes docs/how_to_licecap.gif | Bin 0 -> 1299531 bytes docs/licecap_rules.gif | Bin 0 -> 48010 bytes 4 files changed, 40 insertions(+) create mode 100644 README.md create mode 100644 docs/demo2.gif create mode 100644 docs/how_to_licecap.gif create mode 100644 docs/licecap_rules.gif diff --git a/README.md b/README.md new file mode 100644 index 00000000..96b897a2 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# LICEcap +_simple animated screen captures_ + +![licecap demo animation](/docs/licecap_rules.gif) + +LICEcap can capture an area of your desktop and save it directly to .GIF (for viewing in web browsers, etc) or .LCF (see below). + +LICEcap is an intuitive but flexible application (for Windows and now OSX), that is designed to be lightweight and function with high performance. + +LICEcap is easy to use: [view a demo](/docs/how_to_licecap.gif) (output is [here](/docs/demo2.gif)). + +In addition to .GIF, LICEcap supports its own native lossless .LCF file format, which allows for higher compression ratios than .GIF, higher quality (more than 256 colors per frame), and more accurate timestamping. If you record to .LCF, you can play back the .LCF files within [REAPER](http://www.reaper.fm) (and/or use it to convert to .gif or another video format). + +## License ## + +LICEcap is GPL free software, each download package includes the source. + +## Features and Options ## + + * Record directly to .GIF or .LCF. + * Move the screen capture frame while recording. + * Pause and restart recording, with optional inserted text messages. + * Global hotkey (shift+space) to toggle pausing while recording + * Adjustable maximum recording framerate, to allow throttling CPU usage. + * Basic title frame, with or without text. + * Record mouse button presses. + * Display elapsed time in the recording. + +## Requirements ## + +* For Windows: Windows XP/Vista/7 (might work with reduced functionality on other versions) +* For OSX: OS 10.4%2B (10.6%2B for full feature support), PPC or Intel (note: OS X support is still preliminary, some features are not supported) +* A reasonably fast CPU +* A healthy amount of RAM (1GB%2B, especially when encoding to LCF) + +## Author and Original Source +This project was created by [Cockos Interactive](http://www.cockos.com), and is available on the web at the [official homepage](http://www.cockos.com/licecap/). + +The original source code repository is available via git from the [cockos licecap git repository](http://www-dev.cockos.com/licecap/licecap.git) + \ No newline at end of file diff --git a/docs/demo2.gif b/docs/demo2.gif new file mode 100644 index 0000000000000000000000000000000000000000..a43565cb8350d75fd0197b0b50dcba14ce4f31ef GIT binary patch literal 397813 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

sX+#yv{L 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 UUFZQW&hBdf@?Z8qMTNq@0nDs*{r~^~ literal 0 HcmV?d00001 diff --git a/docs/how_to_licecap.gif b/docs/how_to_licecap.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad0bdac6f28ce8e8f9658bf379dc4e6c2f258014 GIT binary patch literal 1299531 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

B$OA(4`=E%2DCIgpKcVFrniMdK|MIn zlJGyy6h~_gR6c`5k2saA<-=J!aaAn{E8?M#_f_Y%xaw&Vj~&~8XUJ-DBt zw25Cp&Xh_bnNgofL@VBCK2^Qec};WvP~K1QnaEng$x6J^jIl`cY3^LRMJiuPReSM5 zH%vFy8;T~07UWEA2FY|-{ z(TeR-Rja!&myeA76GQ5X-sw{8h=Q^hd^t!XMa{QJ#p8>_Y|x75Ga+bT&e|x?YU;)o zOrx5)CR@H5)B>(U2JyvBzBm zmeJAzhK!^ipB^HC(}<*#9D5hDAL$=lZxq__0%$E^i6bg<1CiqX^x)VH7)L1LKh;Q5 zmp9x<(blWfg+Ry(({Y|yo-!5_Ak`t(k5|=8%ch5akC&j!?GTwH6}{>U;<%l2oFZ!_ zm6Z@U#YQV;3W5jq;L4-4>KWPQPkvPhexv?gvCOtl zJ6``uxA&9SF0K*x$BtElABH-BsUMv5^NlkyMnb>T^Mx8MRK|Q+)rghjWZ5uuRIr5P z*ZQvmM)g+1YlAILihZEd_!^MOp3kW#vf!3F-6Gjcd2>wIy3kEV*~87~|Zpp5N4Xt}-vV(u#*1sbBJ{!#22!KQjGsrrf_@ z9H)gpdwrh~md`WkKhMm_>r?(#{rzue%FM5OIEDwaOp|js)_%?E*j?%ja;EtAtLe_` zOY;<#UTzCgF@HJJH}|vpMQ@Lb_C;?vpP*_Qhm5q#QkN#ACePQ(4v;f_*iF`Vzak38 z*SIBde|sB0`2Fq!Xsh3ypFqx3QxZKxDPgZ{k5u(>R6Y(hslLB} z)}mDsdQU02&Ds~z^HJIWS~;bU)RZyOO~x4e7Mu`{*rEjpMbBUqdm&gL^y!^bwg4cI zzPfe*KqMT8X2^-Ohcx9FS{~C+i;vusDdt!Vn=~*K0Ec-Rpl{oPf;hS6b^d{bf7dkB z)_CcT3JSdWKcYg|Dd(=@l5%})n+{@|OGXZ&WGCaAf+lUqLo}ga5cF@;w*yNT^_=*K z#Hs}RB~VDCOC=bD)lYUMSj6nrhhq%i_3aI{hO>|!o$jd=RRajWW~1p`R=g87iXV?lh9sDpd~izC+802lqz1C#Y* zkAmWHWJdT}NBe5uG7xLr@Qo=vVhtQ4gcHK*gJXm?ijhIomVnhmtp$S4;q(U9RQCL} zx7*7mZ-m;E--p4R>+;TxNp#XTSGfGwuK@9Y{^2eamN*&8H&71@FCIKjjd^Hy{ z%9-neypO};J(EUG2OssmLjlx)Ti+6|(oC~8*LGUNX?Q?cB>^E^?Jr<>3?{HNz*+*Z ztV*X-7lSvLJFkD7KE0(b25mHVe#2?o&}s*JhjV2qfZ2);5Pl*99Qn~h@tvWeXDmVL zyY}@V`8wSiPGB#(LUVoaCE~!{-DhK`NA$h;UY)w#N89t`_v=mau69>ju-gQZXW_;d zFhHc7Lw|JVRg5$co|~X4KmXM_=Goy0i~sjvdeu!1Jud{AJp24&=J&5n87wy&jom(H zP6T5wO;1@a-QRxP8hq&d31{H3iUvS~2LR!vknjBrh{53dy)ICJ;Dd{=zoYcME|q?} z&d=gKAP#5le`$8x{Y~qgQ zjmp7$qFa5_iRLzGO3z(Qq_17)l6lYC^zO;f%rMpQ?C@(gsTjVl9OC>nI14WB;mPTCCSJlIZYeUP+b2G&HRP@>_Hr}iErQIkHY86v zJToI6vevjd9QnQuKnYTT4;B##2bqSvU%VRWxW5x-ht%&VhGK9ID zQn>{(ILhd1Bk}5A{WNm@G)oh;N6?20;<`x3F%V^@v1Jze8BH{kOx==r!jddB<18g7 zsAI=R&lumEzW0pvr;q=t-dyXg-<2)boLKtBxA;Q4WIc(kELXk_%1X#M^T?g!Omd^b zPpI@y^wXbIV4tpu9*=h&?$PJ-$ZO-s7gEU^&&f%yHUB!JZPAf_G^YD4lLow&zAuo! zIHS0Hk=I(CN{7Qe`!#&!*#SUG14DwgfRu;BV}NK(eIr#EDxWe4l|xLdhF8UcoRHUo zRB+OfheiJhh9EcdG@Z~o{h^W*X@B~2B^}0m3W})IB z9$pmRp-lSm3ZpM8lsGz-m_g3;4wq$KjB)-as^|>&_$QimkP$4)~%4$#yDw*>aU_`#wDuldqd3(y{ER*uDT*`&2U%hh4%&Wgd&T~clWDr$*#8xv) z%))=lHHDYb(Vf*&R?|b5)b~!8w$TVdhoKE6mDPlP z53kgS=+yWzp%J;R5upkd^{Nqrv>bk?5lg2TU#Wr4p&3h-9KH{c=%pD$rkRqd`6E#? zZGFjfSTl27^N%xq)yzTC%Ei;lyVEpdfYD-5PifICve7E`S}Bs%EGg7T%G4_F)T*Fc z)?L!7I@hXx)v7_#uEo=?qtmWOS~X#Sp}k73VAV{wS&jD6ZdunT&0Hzdg-*^~O_^Wq zoY1No2vS<|rvrlb4uJRY>hMuQ>2R!8LFw>u=nRYM4A`tGxvmWdt@Z1!btA2f4Xlm4 zu4M3{bm8gFOsup8t+dnW&g-s6u50ORK@f8FU@w7B@UAZE`eV1mp<;rsIO)DG&6k8T z`7Y0|Ek>??z}={p)owCbk22XfaMBCsT`vY*RSME;)m=aJTG1H}QZh&-vkL&d6!tAD za&uo)%Aj*u{X5;w^K}7Qln|#-{l`rGP(1Ko`x`OZ)J4Q)`COa#NSxHu;9&R$bS01w zMgCOn`geDvKZEpOytg6}^@?S6VXL+(27(q7ecLUGNd>?u4E@Oo*GL!ud&-WqVP{65S4T7DM({qeH9Cd0U+6)oz#wf(DAFZ=vZF0B${_6& z6EUiEEzEb=x?8lrQdcjVGpb@4-BA_4FMS3=eG#XPgdxI_;%L8o~sd zb~T!&WkRXe?4iPfnVlBKUz2s3$?1 z92tDFHCxSs>Za*fV{7i-wM7j6wuNsC%K&&awS4BY9gYec$G=LgJWKAh2A?|9Oo7sZ zW&2^s5+2`V0pXi^e?hk-jK_0x$)x|rY} zkk@Dyzz8+K@hDCBO2D*$21LKR%W1B4F@0en+o>z>RO>K4*KT>j$>03he8LA4ZY}Ks@$F+dNna)AxY}?!MmNG{xjk4=#J(G&G2e zJgZZ`b8r_v)gd z%7-phOu)$m&#>Y^_}lRhsQy%I{v@?Ou^>k|FMNHgE59DW?SYka_u3F#+nq zJ=e=W6<0eKAuq@4Kf_eHwPt&?ReQ8|dvr{BbZ$OFZ9e5Jx*ghh#JsxI5j-F73-`-= z4*coCc@Ft_4o7>AfNr={dyaK`j!$_`40#rZctl*_O(T2#B=DL6_2Bru=H$KR^}QCp zc`f>QEtz>ep*(xBdlpA}txb8ouY+XhrPt=W*A|S2@9&o>Wba*m?>%|%eSPoEY_ISM zx18qJA`|bEYVT7RFS;@B^G)xIzj|<&hX_{$J~x+d%@p1Toqv$&{%;r$SD%MypT}&U zr)r<)?)L}rP(M4LmrI{_7+4Q*sKL74OF|*>4rfP- zJA={06y*Qv!C4>Qkb#`3(NjJ9?ZLP|tkq6O=`3kqu$mYuo#ijkkmV;2CYzIARC6U1 zZc>p?@dWc_RMq5&D^o-wg@y#dxakcQ%Y|BhoGFIsLNg~4{tudD8lh@~*_-oI_R=+= zKa6-|#5)SWuwM}j*kRdXTrsS0jX%fDa;BeW&g`+amdtQ8ou|onF!aDMH~R%|buD~e zzapU4LrD$uJN@BW8)x*zx%PL9`66ZZqKHP;QH?j}8)dmw*TvQ3WYM+tpY?a)OS5km z7wa}xfn{g}YMwD2$FpHU^~RMmZbBmy`{GI6=uSc0Klxai&YWnZa#l;$Ghu&n)}g=UAK_b4!b&Nf;vLtEU3tkU_jNLgwx@keiPkDnpN|tQ>L5|XS!VyIbnCfcs`7W4 zltF~{@zqhru?p1@iq)4`bR*ThWC!sw&dRD%g%2d zxvQoo{213xdYhZ~hCx0be@)RNci!&v(}NT$&U=^WdLMtc?Fq%Z&)e|4p7O(hIXCiUZsQ%&^ZT&>%HV5I@t?ToQQ>qF&Zg0EDKtQ3o<@M zMZsZcQ(*O3 zCbhiUn886!^5Cy6dK|m4uDu(QiC@DEPW9tW6R1>qE#z$Vr4u#|_30Zgf1Ih@w4qjcX_%=cSTTE}KbA`i>#ZARvm> zs-SA|y(l^0k29UkylE)rd!`NHFBNhsQR}2u zt1p|++dv6nTi;Xn5t*-zLod_irO}!#dtYd*Ypk?YJ<#4ARZ|^qtTHbw*S*!^ML%k+ zUbwZ=zlPUnPim|&!lN}rD_`6kR3AiB82NFlBzGsi~=xPFpr&b={V&=?&m(y@;mMKkVEBMEdeA zepPcNDyd-tsnS-yeQlm^vA*|}&b~H%y&rM0Wmxu$Yafl?pqNX?!QH8opNCEvhD+z# zz=fLy_xhZgOa0xvwVN>a=Ilmu-SPT`N_)BP@4;puG~bop#|neyr-jZ-*=l>Z4ugq{ z#n#4idXwAJW%v+`zIYp(K)j4~FsJ}{m46C!e4003lyKsygf01UhU1{xY15*jLEI>vt$==dlZSXqf# zxVZoTDF8qf4NC+K%LG8F3ZQhsBQYTXsPX|+$?3#Nsa0vYh3Hrn`KVQyc!d}_lt`#t z>Da9Js9hMjY&Zn?0FtUS0%B}JA{>9|Aw~&%PE$|NWDW=r2?7|^sQ{9!tUdsMF(8y^gMxu%oq^irHUf zIx9B|OGgJ#oX*qJ{QF;VItuDLfMg1qU=W&7KC@cr7poK!vnEE_nT2k9#PMj(aBxbDBd;B9JR_Fw{4sONg~gN zafjAy3%gCh6L;M{8@OKH1 z^+?SO6v^;YNlN~no#R##AX6Hw3KB-u;nul1uJ1{JU)f|=`OLsz@!kx}#XOU(VvC^g z@W0b_;qmdH5~+V+DX3K!l2M=5nBZGj7@pJO+uRI_)`5z3>5Yx$A))z!RiH_>-2D8U zmeP{?`uc{3=#(Yj=JDX>x#Z^Y^ro4-j-}@I-uBL?grUqN&@|C#M(K2A*>t)HJ@{} zT>%^)pPKqPF+01`)3dbJ3u>SK+&BYK(!I6G_xHg)(Btga+4c4N`|kDiHAn{ihWjs= zR_Y%a#B8}XTuUO%fFKl(OXaZH{T~Ioe`HX7(Zt^}sJ?jWj|}n}K_nf?N08yu9&IR{ zEmp{v%9LvSj{;p|`C|1yGDx#jG!|dgy{U2)l%O2Vly0tCZwDPxcq15~0-Y}e0=`U( zoo1(p@IC8zOYQDZ42iUJILGzQ$e#k;ce66qRL&9^ zyR7)VSkheAL;l4pqOy|3i~_Ulk~&xtMu5ic6z@UkyK*GQ!P;#!D*z?FB;dzA_CY={ znEkk>zfQfhD0wj9xTscBt=QJ}CO59(JtHlh0Y$(8hlvw#<;OB-x4PHd%dxdb=uzeG z+teD?4o1GnRdex;zHW4icZ@EekMj|b14iEd<>(an3EJw)ZGfETtkyPfu0RSoyP+b( z(cN9UVK%J|r|C?okCC;4!S@TOh0sCKOmAF{LusMVchg7=EXQezeK;lt{AMctM*8~< z0ssUP76%Q2;p0~HN{EkM70PkpUh|{9FIt;VF+EO|Xjt*ok2c$npAWaBju$U&ANYQu zAsRljAIA|^aP&vYGeGL%+C`CMy(<70o)$uTKWBFqgGm3iWu>-KGwaG0sWe9>hi5RK z-DYgFq~no6w~}bRZoe#>$1M_1XLJe!0ci1CU2LutvfWRzqG@8Vjz9nq9)M5R(H1}e zC0L)L^tdiL9u-sT%7%R$ zpyI9Xdz6yfaN5VM&jW9{W@{BBTT27|d$?J5BQR9nAcOSrh#2Q=>yE4GF4}<=Ef~p} zA_7Ll5R2_W4T1nu&;k|={cuT>Rc{*__Ts}Q*p^kM1V2Pd5qbAH>D)Wq#7+#QQM(bQ z`B@BhQdvbAHjI4e1P=Rfd82MJE;SxI3 zg-ydCr4&ZL+B#4730?TISC3(wRH?R-_|roEngt`}YZ_kl?L|t~**u6L8WAtE@ofPE zHGyIW=)h%vj5~^b=o;qXVHCp9VUYtDAdFl8VX4old9r>6ceqW92TTEdWG zH&*mRl)-^qSKx75@y&AW?dOS(fA^yopBIiyFcs+4iqM@?iKw-aLur6Ja<*2 z{|8_96dw2c=zD*XiOnWy)TXg*+g4-SZfvu0!#1|9iOn{4W3zEG&-}3dYwc(4YoFwF z4su?_`Z0`#+NU`lVv2Ve<9iFja|R!8%NE;w^V@)vC0RYl#Kf?JHPFQ~880 z;RnUt4j6zQ>TM%L-KFouck)qPJ0`|tDg$6~&Z?b;${^+n-8HwgF9GHT%#^~NyNS(> z{#D^O`7J98?RQP@q8XS8hGLI(?%S8D983wd7FNHx*LR^Z1?!P>&5p5B_$mwtRAPqA z*Dthn2RpbG*$$fqZFfIR*7)D>X`Tx%bbOtx@`BI)fww);IZUCB){50XKfw+ZA0KN|h~u+_4lMuMY?W>Jct3wQ^hm zg!z@f8l@}&5v$wl{#^!9aAnt7#ZQ>!bAJTN9@k~veMJAj^*E+IRiEbUB1Yl$IBsNc zoi=pPC2&IfD@;eBI^{-`+6QxUfue>G8@Z%K!U7c_u$Wn0UaXJu%RQPpKcxEn!1YjdD;1Z z-ZmnIcI~{DKTiz?v*NE2@1%6_ZqQ_M$>1yAd|Q3l=V*zT@{GU9eSSH3Y#yHUtac5* z0MdkiXqyvrh%Msl+EEB-|Hb5RO`!dHtUdiSuT_17Z%ceqllCYbsCZYO^?GWh)Ujgg ze_J5`dgheSv9@XOr)G8iSWjyd^+GVDcG?=s7QJ&TWXkaew%=u>QfJqy;@86I^&^#l z&bd!aUy>GcE_9}S9y|R#d!}Ws^3l5vrI@^i5(=+NmAa18{l83@>fcZ=`y3d@W7Wlk z-nLG6okI@Sf5r@4Re-toLZ+{_v4wW3JOwsBpKromuHV$Nbl#RIy&hu=kW3#+FrA-- ze)0l8OF2P<@h4`G4f*?57yc>G-F1LpFB5uR+|QpAiNJ3UQhwK|=+DU`8|O3W_&4|d z7F#fiMsV$0$P-4+&mfcsBj<@N52T^#1N=v)Y zM1G-r2r$G8^brXaw}gA1LD%#O(?$Sjw}!nYhNyA}ELl1qXgMF;hgndEkm3hRdj&rZ zhu^n^`YwiM!v{8cVm0GoS(YL*2T?J7N49+MzcI4qqk>xGLJ#nY1X_j4v_{63Iy-^A zJYAN2r?n!$P7%mX;oY?n%-hJ3BmTHjZlSHNdD5YOW)R_O;l#C~ORUh#Bcu7?k&^SSfZHlT>~s($68}2mSU$KVrQ&iCldVu ziT)E9aZ9DK?ScLac<2_1aT8X7ip=4-R8V;LD8CWnS4QGaB9McP(DN`5`3@i*x|j?6 zgc_>^UMi$@jDS;S__k92=%q-Q(a7Eh_kM1bI^$S{UaYi3WDJ5NES@Bs&q?pB{gI&n z$X6(M%Sqic$cUx>Scgg2Wyq@t(TkQ}$q|!2j7FW|A-_r|@WLnGZN;-6#h-$mfN&VV zCoA-#OVl!}XyQv$9>{)!ItGq8rPe80;!6q(b4qwiOzcC=pGw*`4{x-_|-d9LzaAFHZ(>aZU8v{!i<1Rl9We@DzYWKbhsqU#Y(oLm zKYlY{fmDldEv^0KKSC)$CC!K7mX7*!wWZ%FXEkM}*HS0f8fC@NB=FuNHh4wf9%cY& zvKw0ASP4?4hhwJNA~PSob;=S44}(z=?OCkC+nK+qZ$}uF`kx}??tno_3ftf0js15p za@P<2ZzB_U7jvKR6M_g5IuWxk9^+3yaOFmMg9L~P1R3`{eyLwFVZ423+uVPSW-c71 zE`4SpF~+a}<*12-;r9AJTw**J*;TgT?6=``Z`tD=V_ayVOVmau$o!~?{86f%!q1b@ zWaZU23iVAn1@1%U1wssYI~==B0rX0?+GDniSN`~-``6a|+~xdP%W$Ja{Uum{ytls5 zOwScZ{S!-CL-9o*v%`pDLu!K+P~Wf z1+olEFGtR3FLQZc6fEoJVS^x~t>3j3qBB;MM_Xz{TU^QOX=YPA|5&<+7~<*@K6Pm( zl@D{z5roM76)Q6Ez6eGt5lS&XH^`=B!U(R9w{oKd#^S@bz;ET{vZXSSrDc{?srTh^ z?<mky9E0C4MgKrE+fEF-`nEffoezfoeKId#>YaM8|Z{h<#fsqeFnqROvV ziYivh0etQ&vW2?K!S!SLjo%6ltx7z;)LY1Zt_%jt*2vA4usx$ZBh|Y-)j$z8 z%38XxDmOy1aniPpwePWHd>WNY-{o+l6P!4!o;2`rH8IIGyc@33^obuIv<037{b~<4j>+_lX_2XDF&}Rs-)_kshy2QD z&p2tV)@@5B>`3xy%c^K=L~hGH@o-=5kmYVK^l2=XYcA!(D$nXjTx}m2Z>{a1=XFI_m1FOC)Zv9pcgDz-$)c^M^qdB4C0Oaso19Ee0^7vz?e8f$BTD z9-!~-a`=;PPp3~`sl2;2QKxNeqkSiUi3rH1Jm6f}%^?hD!aV3bF?>J=46lU=y+js1 z9XU7|W>H2M{eUtM+xdlmG>8yhb)q#!nO1*dwCw}JIR?re9E?;HF2Cp8Q2c!Kb8abV+=$P0f&62$JPdv@+Xc@Ce$iX4JKMM z6GwxLMpHWw!2t9)r%95|$<@=zVtK5x>{;COKAX-y0Dr{@H`Ou!`0;5cFF%ro(bqqE zKySP05nY6SlvaOv1OxEe^avl~)yxQcAgY`m!n=}@5#-VHt-&dI;9B5dbQYpsEQ)sL z%)(ml8qxea{gAv>(DqCCZfwiGU1JUXxD)-b+gkS(|Fnxdu#l)L>~z@LZ((X2Zl!i0 zNDc^%I;c7UcNX{y;xlGWwB_*68tcs#$w2)_Y`L@-yM$Z0 zZ~_ z?Kb|zZ2YO%xE$X|I@u`qn=M&fr$kxXVpyw=-Sm^&fScI7JlVWN-a4b(N|f6=L*D#E zw@D$l`DJ|TKyQ5ydHXpIgtO88uDTolt@V9%_gdW6qpeGZPjmG1m~+++?_1e}^1Q|A zwuujr=;mVreIYVaHu=C)IXm&UW|H$0kkxJ?-2*o$kH=xePKh*thWC zx0u>pM&8v#%@HNp6Bpbg7o@T>IPma4@X9^#?mqB!*t7B9QrzfJR%}ysXj5mz@&o4{ zMt2{^ZXCwE9rO&Z4a2WGaUCY<9)>-S#djZNZye=L9VI#h1Th{uDjqsJ9J(?R=5-%e zZX8#m?SDs`vU}UP5!juL!Yx;2e+sV6nS?dFldX^D^q~d=~BO#vY*y zfTFE@dgp)o&<#M_ydrTt5XCzMqt#NvL-xFWn#$0$J=gR-*Osf-3<;;CV4)j!@E-5M zP8I4!uP5*~7n~p|u%F;oG@x0O>6X>-Mmq0S!xoNA=(@@q_$(X*S4t6hOKz$ANAY@0 zvFA_B2;?&sz|C}JG#<&tj5cM2vXXvB+jU3l*K9X^$6dYaB6Lr97}v0Lt7n*R?s&H} zScdhbnfP%`Lg*pX@F6_lAu{hFy5}Kw^C2GmkVyI%SpzUm2uMNmOb2`T2%%+fKJq?4 zPB}H_*E9q(Jr)N%mF7K__dHcHJ*Fhwe+kIs%6GF|b*|~GZq0jc?|JUreD0op#>IH) z6M7jid>IOO8OeJY>v@^je3=5j%m}?4A>BzCqjbNaEMA;&Deqf?SNCdS|NL8^LzgxJ zKOg439rwIJmO+pLU6&G6uhJ_%@v{lEJP$0}-%b-H- z*?$XkR?b1tKuCcOrOYU3Ac0)tJ@e!JPv+;Q>_%7tB^B>5-XqgT&U{z4)=II)7YH$qwd1#=SJ)KYV*~!Q%pnv?^F?F z8MGeFf(qDLU1Tx@Qhhvr)m<_kkHV#m)Cc{#G95{xP|_UxRkm2AUS)DtmTIdtVMH+P zrn_=`^pj=xxB2=C$4P{l^kgwuKPxsg0@HMHU*XupA({Yxv5gO)!uYM4~3uJ!&S%W!Di8$ zUsNczEe|v@`z2^U(VMaSP`u#0;iUfOIl@27AhuslVrYDg7@$a!x}$f9lC9*##4Bpf zg996@CNW+HDbAA5tbx=(ycTT}DH6{VOaKzCi*YM3S+!dFd%XBu2~2_xMmZeM&L~?o z*)Io5^oCz9a*QG=fpO+;_{Nx@kf4fCwT9S(B{&!RS&+GRf?O4O(*Yn!M5kRA65^-R zWF?Y|N@}>FH1=C%u(-3$*HWsyXqWb>a^NH#qEyVbsyy4go0=lupIbF$wmbRqiXwqQ_H*t#;&K(4 zB3pV@1hEd)VyoX@DBw8zq9SsXMgJ<$@xXqCcKgXNfa|uX&;ldoChckPcY)6LX5Q1# z|Dei9i`Wj;%P80x)n(Ce-db4Gkm2y>mUk3t%;#vj@QKgg^ZndbXegSlS71e)ee!2KO`!n;$K*T^GJs=K9=ywxj}F-ed|!QR+k#Kskxl<-1>M z1jCiu}+B%w^D7lUB~@B)S8V(H!kfhLgj7r};R9>2$Xx zY8g#+Kx5-9*a?VSy{8NbtS>cPJ(m$ zJHOkp><$OhhO(yzou>38F+!5VG(V5!v*t|oK}slzI!*(YZE<1*Jb$m>u2TS%QS3a~ z$3ZT5F_vAwDt^}qLJy(?a(ur1o9Z4&h}E?J&f0F0sPN8CR>UCx4=Lkv4(d`&`sM*2 zDzsVz&d3D7pJd`R#{&ST9OyzQcKzO?73eU9LQon=fbtMKp-}Z@iZ2oi|7YykACVBk zzm`D)4`N&07Ai5iyC!&D4-)j((6OfErUVVt zl5CJ=(C5zH_gUM0meRkW3>#^i+h@E@TVrC9@YXSiSHk0wA0PVF1O5 zI*^P|5jpDpqES5ck?DRe~-2_vT<*x$WkXp>JyeX@B{e(@ClHc>LrO+!u z8Wcbnk?xa~2&(stBC!bGkddSq@sqOY;ctXYRcbL(@7YMj6gADmBK}2b`Gl{Sg&$!* z2~1i|XKZ2n<*RSX>OHAu45=5hqzYpV1S)6mtC#Ri9$|8iDSn01C>1j=AXI4wq)sX4 zExs31%Xv~SmDDI#E3(n3I#y>!Nh$ez8B`uhc#0LNQL8awMK^OXeE`!YNZS|jZmWCk9AU}IJQB~@>Jx#aYC!;EA2byWYcE$Y^ z4$g5tdb^ZbZR6$+t{Ns^P2$jeqrNfz@EXV7%vCDu?MicnEQ2n?wK{i*ncUzDb#FCK z+xbQvhObB0`Sw-1Z;BlK&U`l0*EH#eGNb}tAq6^kZ4i+1G9XXI=&xnao4{o-@rx07 z1JHNFZ4)H0Ix$NPp#b)sA_QKHF(R}FK0%g23ce;dCEA0;?@oFC|2 zdFwN$yXan{pT-_dKfr$;5u=2VTfS!GRNzde*+OYqljw}zz}-=Xv=O<+1%ab@hb~_0 z3q?jfZ8-+b3Dag_q!mWbOAzYxNhU3bc%6&-hUb8E3>0xGYms9YZuR?!HZUj>xzWzVrB z(VY>36_g=<*-C#hItlqPFcv`ybQYc+>#ye?T!aAE zuh==KllB59tefITEMiE8(Y9+j)P`?^~n7>-djHhCuAaImfPZ>iK ze{qwDxF-8f3^~tGjMv|=&d7U~Wz6?kKlAtOJkY=JIq=zhee(pt8(fA^@o&_;fd*I@ zud-aB#Zjc%%Jk5J)oxPf;LJ~oEOTiTEFY0KH%?l?I)3xyen$!cvH*#MFBLVuI}}D? zy9!Fd7>yg;G-P!$A%x@GoZ$7=b+j^KN3HV}9>1%&0N-|~(!h}H{2Ov%sChQVU=`CJ zXAxmvCM^S~v+w=JgD&=F*oe#?C;}cQr^NswDp8a0Aa0s`e_h(kYl}_4*OsBzW}iIM zt$>S5DOZ00iZIk}=B-@e!woJpGcb}FsL2b0QwFW}3!Y_xER6Z!9=l$B+TO4Q5|8lE zUxYDGL@R!<16FC^0 z0*_FXjJ_{!DJJkF%-MyFY6g~n6ri60ZBJX`;L`V)#ey`^mjmiS{?$YJLT||`%0kpn zwuWpR6-jj+7Sm1*Hq_1sumCyq#3F3^*(yc8R^T_WCGyi_FrJDq(Q|#+1=*^wiqeaV z@r#Sg57>_Z=$J)(f+F352K?%JFMf*3#YPCa;gG_JGZUfWzKAQMNT?7=sM1TQ@k^-7 zOK9jxXxd3=;Yd(LLP=#yAmxjHo9QLm6@WeJG@+L?<(D+emeB1K zw-^v7`86PfBIt@Nd4?}++bL<+DXBXk!apGK$9u@?N&*!|@~R`vj$g`6Ug~k|TcNEa z(!_w%3x61LPiYpSd#9A|#BiSRaP5|4^s*Q<)W}|-luPoEF#YhuoK%?Ji0|%jrjwK$ z`G^Ahh@u$^IJ{Fjc0w|uQ^fH_iUBwr{35YkFa-W71ve(0LIjGd6px$`jEa>^%9aeR z9I~AVl>3fB;RKztCX=fUjntNsEHCqYpdht#u;E0y7HTvqb~L0?DzkP7WkiOmHdv{$ zT&WQ{M?E;7NVb|N_Y^bcb4HksmCTus%(SV@%ql38UIr?AtfIVp_*ga%>W5b=Y&R51 z^~+eTbc9=eSlxuga|3?Esl*pwUT^h0s6xQ7Dub^w14ST9+po-L7AV#$(#?;_DZj=e zVk6u#VC#Q%_R z6Xb{G6SVL)5kxpD>scBrkIGRLQtiIq>}d{&V`<%Lj0<1nNO&SiLlNxqm`jREUdDk zGMjNJWq~QZYor>YCYwPtoTMi=v^0w`ubkL6OSh~%%L_E$u z2VNGLLou5Tc2#N2mbz0XH7xzRKsTu-u>O<(3|3zmq+AEDoCIK-2{YJI6IW1|&{yX( zhqGjcqe>)h?}YtGM#fP@$f+@RAtGxY^pjIT&c$vTmRoQzKM-nU&Xxc$(y0z9&`I@) za!Dvr3ydqJ{!}IwQ0352@50ik0%*O?8&0Y#3cRB#LQ#6{LqbK~Rf|>YdWW{BF$mDK z?o#KBo1frYn1x{*(q2Hq543nK$%rhr%F%R@5H$9i0lf@uj0@>VXxifh)_P`DvN!FZ5y{e(ay(`l;n_uRV9OxF)vf7@`c8Oj7;> zGf#s%@8uV@fUgztx}+AogbS;Ei=|y$DeV=fwRowKXum9kwMTf8WVh*zJ^Xew4pHIGN^u?<6XR9Sz>r}1l ztYGT=px`dhpVoy;ejv*riO7=F6}f_C{nPF&;-zfdn7*vlj+;;IUAmo< z7oGRWy0H>Ef3|h|1@s0KAO$+TzMEBlbzL!KPb$L(@ z+gR61T~}H;pZ+g}b*0C$;Z$wVTJN_%{Vf8^W;uxSUHWSR`U|k@GpKst@*L$A3hmWN z{of25gDd*+Zu;dTHYTg~{R~>a8JwRPWJ6c*-AeBjWtH@FEi_|s+hGMF;tO-~TBE=mH*~kx^++}Jj9aZ8QA9g8LVq*D@Ta-C-i&(PER5B+%3d$9 zA3H=b#`8DEk2n7P-gu+PXpY9Pl0#~7&6s3?U@dVgW2**{&;-VonN09EfX#&5;P;nA zW`qi6=${5>+AOryCUo5<^l!|xpZYC>n2d8c;xJj!_E5$Ldytsq$z;SelAvtFDn_Nnc&$<0*`Hg?^> zE@id>s|FXHhTg>85B+8tGiI_Izt3VD2tvZys7=|X@Y$Pnp3Kbz**LWP&9x1Xam*TF zYoWzj&Gi<50)gkD-F|b zCy8|XD9|*PS<@$$>SdthRpo}uV)S5^aG+BK**?cOu%^3qs zi}AsqK5q?&dN_(vXB*QE+!W|JEWLptcB7;P0qwL!p?45UA+IR*ZA~FCM0nC6a&Dg{no(`xBSY^k{ z1-qMfJo>#n!F8!QJ{fwCZTY77hINihxrm`t_5gGzsFuU^=EDt-!_BlPd4hBN#2~BE zb5Rg10W|@4B)p1tmOVl`g5jlkWbmFvi2Y?S`eyjnzJoIqMom`WA4R~m!_^hsh0RHO zTJPy)_0^x;KzvXB#|_@X(e@udol7#a$1*$1k9eYm+m}c#qlfG%9FHj%A^(p{$eCD1 zEgv%`bbE&jUaN~NAWT9S_H$r}){F}VS1{P2F3Qa)*zOA~o|BXPkskMbN55_$48G$v zNnilT^*SE0J~=QS@glMICO|rn_rR56=88f!d$56DD4l4efoS4;=OoW90_0=N-$j1< z7Q}cNo#ql=e62zp`HUH<(v!z24QC91Hs*#=rv76N2)1MXsWKfXqaCsI-Cb8`btMyF z3HhP~!42=gby1AO(9n@k%TY2xu-r&sCo_k#@D7(lUPHA|aCAd!`dHkSz*7-lXSqLVE z&Z49bFo{u!RzjBW09?;vL~gHD-EJ_oNe`ZH{!!M4(3;!YRyTV{fiB{@OmPqP!HQ!c zzDFgNjWmf(Dyd_Qc+D7SdHF7N(P8Qr)Y(+lw~Osw8KE#P4;7n-7|;B12e0p>PvJG3 zt06tWuMe>7`41glHcHp=n|Gz@Po?*FQE>MnaDRTck!BCqKi8Kib!-RrL?k~#np4(cyqlUb#0PfhGd1j|RJw554Jv^AX=W{Xxp`1i|NdfiK z1pQJk4m!OLw!L_vzPevu=&})QFT5NUZzreSIufip;oTWY{K&-n0NY^{ox7C2q7>vM z_N;;PJxL3eqI46<%UZ812|nP=8L##WKLxOFB-(2dDe4@PzZOgXR-hP9wiuVV7-S!0 zk>Af1+rO9Ye^BDj)94>N{8Dz|D}Vn+1^*WD&R>%xj!Q7$RwR$K|%U=88j68p37wy-xO*j z5&2k{&ibzc9j#V9e_P34%OHjBZ0noiQ9|zTL5~MF2R)XeVXQ#x`n~Rau{@|(YjyHp ziNqzURW^TU7bBFb+(QWx1Nhpy3jGK{WXHiQF^#stHI&y ziQ{z1H(?hy>#qV`E7$5N$}OA0th-#EWS21K_3l_Yo0cM9x!F1=i(GGmK`tSRnQ;N@YaaU4P)`5d+toN+S5>p%*0NZk3xr%^aLzO?%3 z9~4lk#SP`}&fr&|`=UJYzLa5dYr_$GKYX`^3*XHRq4*Yw9m*^dX&Cl|8etqhjF};V z!b0R6ilul6DbUHTX`4oTK;kJhBnuARibCcsB@dx#Zv3r^qr?5niv=x1BwkUQWd>j0 z8~nH@ta(@}o+$q9$QY|BrM{ci8J7wP~P^|6c_wkDljYG_N;sopN=bvXpNs@Q`}S$3re6=nM1H9d7teX?u7ZyP%4hcvBvA%q?CM&usLN=_WLDfAiW?CUAfcmrI^Y=37q8o^Bp=1oaGbun$2=V>RwH8<-hMV9Y%yx@CqX1V~& zMg|3B83cLOC^e7>H3eA)xxyjuoU%=AU-SRF4C2uuA}BoRK4ABFpEq#jN#Yt!|ApOF zpkd5&YKJvmH%7o?LI(UYw#;3UkAQB`@yfZz%fx^cg}+Li_lr^`$FS2Kde6|n3_15Y z&a*jtdpv|ru$j%lGKQ^1q~~|l4`*F}o@v(zH-{)?t%EkVFX@e*F@7O0_c<}i>+Z1; z$?2`fb$NDSOmSIf_CL(~ab17E5PwQ3G`7!X`mX|=-=D5S zlW-UgZ*bTBU7%1mjK$#`^4(EIkKpqh+fFQtVyA%BcRn?6b^qmKkN%6a!t-YFp_l6W zcN_^qr7=lwTg`Y#DEaOL?*p5#sCyA11v-nJ&8x2^y%R8rUxr)^Mn+6U3N-?Q(8$qY z=$QL(>ubX@c1RD>ZiP7AodQ*kwPgk2`hXTAVPdOtK(<>Bob$m5Nq#b{y24^q)+W)wEl{)8E(VMKp40W!#oSf z9Dly;5Mjd&30$){C~BKv1EbQ|-YDaI8@_dVQHwJ5sX!yw;sMAY1v*((Blna*lIPM< z1+24#1RFI1SM0HM`sr{N)laf++!A>JMp{QZa!Rl%&G_dztYrONaz>t`Q3J&Kbn}m9 zo+zJr#h>D$5qwPct&|EHss3ndVK9&DTUbd|15**8;cnIXyi?gXK7Fx z^Enj|CGX2-HNNdDvi`jc`t=>F3G$GXMnPz_SY;!;jELXrBR20u*t_IZL4m)QK~<0f z9jO8>lOydy@~(RMk}rwPP|3f`AU`_29oogVxu$B5E;@rv8(7!R>fwM;8|KL|rN(`V zns9-CmqB;6K21y7pZG{YI%>6iXO=pI70Z(@%?-Khr>2>jv$J!F^+)1+GU`#weg4f& z)qV_iLO!80a|-oI47SC}wpjC6oV0bXkg7M`S_>^yo%HoC#T)3lG}8Tfc?h)%w?bnaKt#lM*Wy2(7h1?X1`GRRH*jKbq6ZD;bo zsn~qIZs~b@WeNn+Z$V+Vf}SRYi3>zaVcA-H(fpZ1KhbX^st+sT@(n>54spZU zwK8+w+>JWvP7#@{>E)s8bBI}`N&OgibQBS#2M}s=UBM|>&V?t63-mDO7r_2 zcH4-gAnVs;-(9=|^I=7Q)|3MN9TL-rVGJ}EzZ=#B2G_Q6gE!WUe)@fua7F*e=lsqUYR*ws#-`T8+rnE@0u)`6cgzOSJMcnwhTTtyGBZevV)k#nIr>TsYl#p;%Dp_mB58_RzfOb^112a9f}zQtz6>>i|n zd-#js1+BjCWF8Vk^BsyYJ)Kz_flMvOkW*QicWqbOyf&ce$Rti&+d>ci_} zdb^6~L0s43-4heFoWTC}dgck{W@oaR+FZWb{V4EuQv)tKfd&)=Lj!n`0nmB40O3In zB7l4hG;I*n6bV3Bq~U`I$_o&S9T^ZW3w%$^rcK!Or|+34htUi$-mCOeKn#v3|04kO zu5#<0SrD=X6mq>0T(J@MFC%OOD6|zL)Nn&MO8uuGm>1aZ7|`owEa{$Mp#@=Jyg~@~ z%JCgL+yKmjjP(M17zu2c_y8CHAlZGy`ymWx_x+yz1Dp8A#Fu^pFC|z`IrNRywM>!p z45&4p5XJ$}vP=+xcJIY!5hBIB**}|DFWXp$fgg?mAD~U(?nu!n$@u6^$S6(F$@KYQ z2wxtv_f&pQj~eFB=H)EsIrD#~IyStfG5q;Q^qu##VZJc_u>q1M2<8EXvh4><#&?4E zAK384z}6q>-uj`*CkTpv%r5`NKkS<&5M^fETqX`;A>Y9t2qd}d!>1NuA}?Su3uM-W zjQf7@niasB?R-EY100gj{QdxE1Y(Q*#A71-$$w`~f~*wvJ6}C1CGoD=&v(lq84F&5`}YH z*O)4VW#fq2O)GVX(*jw5$A3$b&>dez(eJuulP(gQ+TwB??|F_cKrrw-8b_ zr>4wd0R&3h?Fngr6=nng-1NaLMxAP=-6@^(_y{k1P} z*{atBYP{y^k(9oa#MWt)b1XoBys-3)g?;b<4CG}E_Mo}Rbp_2Jf2E1c7*?qK;SK{` ziWn7z14K(Sz6D(wXNB?t+3+o|p$xBi)-J++>)YhJEtt6*P?;QGuN9QITlnG zlCn|q$-FSgdru2GP)6}kIHNc0{W_*oR#RB?JPj05s7M4!FZ>Es^!s8M@_n}aQrMBw zStwyINeeHVqgctor_2KtxR3G2nepEH4N;*9Po;^JHXJ1DY!5L>`>>(1X8Nku(lc10 zcL&!jVg>cTgGD6@WohRGLRcQ4pYZz;Sj({^kGcfL^FZG}mX^(OlxI&JS3-l}Ic>c5 zZDJS9&6^A2-pXrXZE{gLGS(f)<;p_8pLGzhG*jBc1GqjyLVBuEI6D2_luWto0Ur%N+i==O9 zo{OkJP^WP=7QP&d&~6rW?`)($(Dn1KbKgQP)Y%%zg8+fO-1zJLlBY(>m4hbq1G4l+ zPN##x8{EtxxY=~=)fKpheItT)Py-d&?}UeW`}>iEyH-vVB?AEy^k1H6Yu`?b5$SR< z>HHYB>p1D>(9990hyW={{KCKIrm}yE+QTuQ{fai=XYOZX%*P50V&XsRmSh;wubLeU zS+XEnMl-j5pxZ~R>}g}DM?A~HJd-4-5};(*IH%hvQPZv%OyXI%~&TEP7D_yQ_t>D?y4sX*G|zj?=2=7u6R(V42SD z-l?pw{s@&9i#}w1lX+kW8z5BUH#m4aY<%eepV{RUJDdrhLNg; zNdK@}wXlZFaF(@jj?D0$PCzQB3(nQ}G&sccTEskNq>@^s8fN5{TI3#Pl;K*GX=c>L zTGUNuv;!xk2I+_E6f`h127Da`ItwNqxDJz)1&iv+I;^%gt`cb4LboCtVtfK6s8p%S~Qb(9v8|qsp3>XyrRY$zZLUK?? za^XyZ2a7;j`3{c`Z@3Pr=8BM%l`O5}CWSN$g;7vd5YVyZe)yi-ips~H~13$daQ zx{w91QVU&?HPn%VL#gmssHAWo;Oei?>QVAssE6z6fmhUEAYh4=akHNBfR*W@p6Q;I z8GOx@UathY#wc+ys;WnDykY=KuvIWqEMJqqhLWc;Q)%5G5xT1JvoWfr2E5qijTacW{W zBUQNb$dDRPDX}vryMGpIlGSQd=VM3ezkxVeV*PG%=$u-gIPF@P zwQpQSrEUaE*v)#})WL2nQXW#^J4aIwzPvik8V~!;J9VFCiv~BBJZ2lVX8A04msJnf z;b!;#S`(!f>&08s3J)YXPNWtNC*5WzT{h>Rclw^5YCk!Bk~v)+TM)4ut))DTFB+Zu z@7)jXk*1qH_?o#ZJl%aby=*4>)bSp zFFINDw^F!L(#3#l=!R>3H@UxN)rlj!GIQ}H3$-PCHbi5)o8{f(g}8B2wWUQk$D`Lf z5`96Vd!UH96+m{uHElC=Z2P9>tmIagwaSzb!h;smmPpExl*dEPcKz+*ktewh4mg-~ zUz2*n^Bs@Z66GaY$LBfJYe zy$`JGOY?ZkZF$NTA)b2gm=!71*HY{@=a=5JnXuE09pBLu3U~A?tr+1y*#U{~NBLMo#-LuE5G` zk0%Z!Qic7X4f~I>K&s)-B`(D(w({%ovfru{FjU}3Ij z@2v0SZl$X77pP#R1_2e!ZGBAKEo}b_RB-(-Pyt3N8KNn0XhqW6WHFmZu-j#@IptE@ z)GKR5{^ck*X6e`!+4zOI`n3N?P;iWJ`$tgV2^oU$2?`O7-Vu=yKEW#KUp~R7tW4y; z_ymprlTWbw51-I9;nKd~+IaB4`GiPI<|Iq{uXdcNE&@S%qF)_lV?EuA{8b==LXcZb zcChL{c0zTSQhA(BVS(@ePfeKrVF6JSf@5PtzQsVItf?6p;h8nxno|G45`tP8h7}bhl{ZIz@5ua7RP;a9gy0_&f58dO{|zTJcl1Nxgyb;@oKW62 zlv_8}0D%+YMi>4=CKN9(L)3)MwYC4K2@P8Z{ePrsC+4hi`)BD|$~vDHg`zd<~Z1RRbFCBma*|I)v~_>I%~JQ(mDY9a#>dxMZy zJp!1F=7vH19)jmbV0`Rbm1?rl@KPbQVgK;mc%gEvJ9_`4*IiDbt#G3n}5$1DHIIJx3TRnrd1)4Dt5O14?$t3K<+<+f}z1s^L<7^ z4@6L466Al(0MGpoK|!gf`(Ht!rw0s%v{knPVcH|)JrBYx3?PDn*FrENc0d9`ev`~AheC4By08stDQLZp@(%V?z_l>7-2Y? z-9+(s*1Jj4lx5_R%*PLD$;zAv+h61~|7xpRlJ^W4#XL82t>QDKUS zS3XVXyYfXnS>^DfVz)1{%SM48o8On@3Z~JPkNAE&5-lhLuh_`fe}l%i$(<`735C5o zKB)o0(Vf-~yt6&6yU_63%CCus!!LGWd9H++<&>==n|p(1XjZWDsiIqV7`H2)^44XL z`kC8-VgCJg)Rz5ni05b^32x6-S6@Y7pPD z@@k04^VFI9cPRb!2zk2Q^*?P@`egp8apqzAn+f*CmxOxr%Vm10Hbo}{{UYPpo9RTE zM7rsQC%sq#8Sn&qu`HefQfp;X2p(m1(~*g7 z==4aVPf6Pv8G7|~r&2uQ%`|vQ<=3<;8WUj2vPR%8-}6GCrwG1s{2h_mbnm4+WPt13e6Az)axLUzy zLaB3dm=ajl%P&!6afaZ_!V+;<2IYWjwQRH|VKEw&$m%aYavxm8anvt^e{F@lYm$z; zHA@UJdNFwLh6=QP2_gA?7|!1Q5zYI>^gZBE0%>xnkGK9J%Hbj@gJv@tBMu*TI0xAc2IJVZ6O2WK@1=gI;`SfZ}DWl^K>#_Szt9Jyj%XF*Han8c#k zGLc(umkfKE51xbd>v7aB`Hse@x@1Attg-~GEWwmyple9xS`fv-A4D$kf}9j}5xN5n z8EH_38z6rV1;>bIW_c#gHlE;^LZPgi}Tpp)9LWXq3B|VkymGq!bXx2=}vePtf^jnj+Ek zy#Rh`FN*B1`;WI_$O`4JHl^~B2AAKDGfU5Dy`^m&aAdVm6+Ue@D0oFRW-%7Q2&hEM zC_v|@sDg6&=#CD-p*(!=>pcoqo(66Cj$bRYWg(=M4h*iFve@q)<%rE%Jvq{bqz4u%#0pZC%11`0-R3>;xsyM z4b`+^gpw-Fa%D}C5NF`A>JQ+wZkubbx+=NvdV`*k=zAX59baDLEK)N)1XktF&fFr| zm=Cuhf^mPH1e*MM-5oZBk4xhUsG8^Desf#@$^K>!RC7~A52EC z&%(*Oh?tpAv?i+P8fq0hESOla%cu3&KBE5$v*3GPo{9fkP+<1W#~3?=xD{R7_C6iN z>u=3r$iy{bpPq1{7Z_p+SWI2Y`?Af5t7DV?KdSD6FUqc6`0&8cHI$SzBHi5xg0ys} zbf-uOLw86@ch^vo(w!sSAl=ddHUHM;4pSP#~r%y zvX&D|iw?!NjvQ_a*D58=aIg@9Td5HV?f5&}(*cCqaP1H%OQGreX0iRN)cMF$Uq_2uHG&b((dFuzrN!Uv>n zu8*lAO`Oja+1wvcSSx`?sr3~n%ZKk%R`)6g>RLMOxA9*{Fo(W8B`bH5oBXM|LC2MZ zIK&|_!9zfZW|Si-&<1gVcIjBWH(M32Ib3<)58Q-?dBgpwql6Q8{oiu2o5hiWzL9S@ zskL9E#5zrUkFm-P#W7-hCNDL$mZyW+4#74$MSD3Qh+7kgVS{(ct)t&MU}R?(cx{kK z5sJi=-1EqR9v(2v1u);ellr;+;%oc;Vd>rFE!ywfkEkQw$MxBGe9r`lxl`cgmuoWs z0LHX$ySBL0p7RgFFf{6Yf0uQqhwb}RP33prlf4}bkz!4(dBS)dwIICl8>ORy0lw$Z zd`F^Zn(xFoEn7}EqM6A+aW z@Dv)77#3nXAM&$_trj5^Koh#p0fJLTai9O@@iWwGki%y_)UPSRf8OPDQ&^CUUzE1r z)o!pFN=PSPNPpT-R8-=Rbl1QS^|6imr0>j0fgS zQ`iE1q;5`ha2VznPS2G#v}GFjDnvl zX1xS42pl{=AHBR69X*J)G9SD3Gp@xWreiPwbKm~pXDqG`#j!FH4L0D&dpPY7Y?<9~qUV@0+8TC~FbleG_<(XC@ z!2F6AR4~K@gogx|`qZFWIh6+e^8By1YTH73`+a)b0^Bh>2py2o@0l_9I#Sh~F}jd3 zexCttPCuzht6WG+ZBCt+wF(^~HwS}O?=#nlvo>G?Sz9_;JDyp4saXfjS^MEBdJv2? zf#3@P(2-8|jc4|aZ1%N4_Ct8qqZ2`}_)qv2A9MCh{23rhS`J!E4#r{*)*bY}mwCPS2dN1QL;B-BQL8QBvep-qccJs~l~c<2OiY@(9MbqcnLP z1o{Oj*M%T8w^T&vqKrONKuO9<7~wpI<3iFrD@np?S}KED0(>G|*BJBd%gD{KD|blB ze#<5H{Y~oQ0PTBK6+U3TF+qQGj(O%)y(3sz-%^dATnTQe^cO6DO3VBeQH|7^ZwmoE zLm(JS5C9Z{y#zY(g5)rk;`W!O&6VP}*5nCR&Il&Wd3nA(lmWbpR&9jkJ#Ri>T~8?pO3d4TDfFf=!O3 zeEs`!zgCoVNA#%8G;(t&mhCGX@IQirchf&@)knlZXbAvXG6-o3u|+3oE%9Y)HZqPT zdTT<;ZZcvV9WURUEr%Y!4$1IjA2Enh}j)MU^!iOTkjk?lrG#Juav8SBfX z8ZB+=Tb2?UtSg$8+xorR2GiSyTiZsL+QuK-(j!O#VA2u5@8L-FhuxB1+u!|+Eqv*9 zzhF6j(8%AP4@))pL1jY0yYelEOelNU2uM&ML{}uX?lBwa*tY5kJ=up#UoOgcki$A0nDxecj0UY`2sY%JeQ?bHP~nY zPMgo0QG1)FMi{hF*}LjjXWv`ux&qy1mB-TKGt3!zDobIibTpH!;i2fVmMWp(GK|*Z z)}CVdfs*u=LT@amIJ7#9Uf+z~=8Sd};XF-@zHsKg$mKi@($Qr4q3sCJ(x1_Z8l;~U zRH#g3al@k{{-6S#eq7FB+<5dJ>#G#GT z{W9&3Q28|T(jVIBObL-`Y`IC(6+c<@*@7~R6YXeekBSYUx!*RWj?u$%Z>I*q6^>)& z26a<*iZ!D4P_eO2xr0uN-#Jp5KC!}9(FP{AWb?U6d{vm8~x`c!th;JZ*zvV#Kn5#58MtoNS&sj~OvrLpIbjL#}nam`5_j9<|sXiLRSd z+HXrlj4_WU@+Tgx2U!(oAbPp&dsQH2Epl{a4>PoWB`4Cp;FJB&X4qKfAH^~}%wfFl zqvvz%p8f^~nE^{vcR z+}TAKS>=?-&l#55IkL&S%6UY^m0*Kh+289VS>^D)CTQ({N9EQY4Z?3l{<7-+rO6t7 zR;)r^%E8T={}s0~7`JjPzVwJ)0ux`lSXlRXTu;>6z-wPgxt;fy-pWes~K(<*g zvRQAi8UB6KGHvsfezW|sQA_ssebyR%%=Y`=8$NH_U)!qfW$S0k6=q61KW_iZDJ>~v z%`0WiD?7}pIuxlp%xXFiP#mrkX8DN6tVxI#u2g0kiw@B^?S;Jx3JTHaMwpXU8eyWNG#wJfY3GUM64BT%)bIa~0YhV6o#Fi4O5uvYZ2 zeii7+S`aus|BQT4Pqrsyx#fp+WT(4loO4^h zCJcgw`?>xHB|7@>@wc?YW&3$E!N!`CL+^+SU(NJWSPYWx`YKJ_5l`$C4d9gL`{iX; zjwtx-!y52G)U_`P8SWH#`vQFXxzR-&O@tlg3m94X^R=1+it=Za3UE%6G8Wb6#-9+- zo6qMW>nL@dd9jddYqpXZR+Rl*&=>IW3*dTbd|ylSBoXDrg5|^mX4xP+!(EN25`Cn0 zhaT{GCJZ(m#FmX#hNx$Jio$rV__LS1C$cunVQBK@6P@)__fi#Yf@2Yd&cVK(3Zhm)I!5qENJGl^`JEFFD@^ieK zwYm#5Y9DmE`z!+ghwXU`c8Owh^)dE2E%xCV=6f%42K?o88hHe4gQAImuSL$T`i_7_ zpmROrhscTtg4k&02vj`^6wA|sv@_6ACrTX%yTR*YJP*Ve6eP04vP{?YR}%I3-Tx94 z=KpMdio+dwqS3in<4mOgkt91mxh?;b!@LE-m?@<;?q5M+%2Y0acI4@yFqmE?|D&t* zhhNyK$@-r@VP^_zFiZubd)qNcN=Fg|eenVxQ@QUfqXp*tqoOja z92}rdjvGUfQDxKeUw?IVS(s>ite}i22s+>Sy)=$b& z(2>}!RNYS}Gls`jp2DmvVnt&1+X|O!-vi~>7v`)RpTD<&Bg6L@wm-e^=FL|{M~A$? zG-S`?UO_eDL_&`BlPH2Lxzn1i^a8JfLR|h*z@$B2^2=j&Q9A2uTXi8By$nNNRiP%T zTD`y__fVgds*l)G{f|(k?m-??kUKN9CuQ;wj$h*m$eAm70na4+JI2kLJsf{)LWU0L zW0(D1TyiATo;QC|7KJ!oIbc?18AX7LO`@(FLvb;V?{zwzwU?Vkw{ATAq+;x2g0dS< z3R{kR4K_=%&fZ%X3!2KGeiDs$)6mn6*KuAsriQD@6zW9m&q_jl*p17o0eEVu;`rlg z>W5ouC1Pq%-G3wqZRq}J>V4-f_mr9Ws%7Zir#>|^tk6Iva?b4D#4GPrCuxM2b~&vS ztEi@%tw~!NB~d%$z9caVh0h9J*D=L(7&*St(@)p3d4{jwRn$tJ>lB}-hAr&&`?!L0y=I4$`Ky9K{nA{s{P|l~G zMDB2-6T6G)S?sIhbFy7MT*AualXy|%BV<+ z^xn|@(%$O;W}^b%fWcfhD|ndMc#~!uVsf#dn)CIIu2!BbPYYjxtVSA7(kA)2^@_9x zp}D$NyYgvhOO+!I}SD&Bv$ zRpt4f-KN#FzJHySAFv#axlCTNR?amfbo_i@rTi`K$>I6idf-2TLL{Hz+1%!e&wU&t z8}Zuu&lK|ft04tUXb?#(?Eu=FjkBQ&O6RV(WgjEclE8lKw4)9qV&*Qh>PF^ZjQql6nsCxfrh97|+ZH zn5}5LAVKy3{Rxh@}LqIqFzAB5+wM>OXcqTFjGRnP~PA_ zfPilut;J;reE4rcL4;K*_)&jPTB~KM(BUi3A>5#w8Oi~)x`S{;vXsu0M~|J5frd)VSpYw3zvk#$TjXniD9)O7ZS5b z9eOpLkwOTkFP{)RLcaQ_ijqoZcVAT^{Jz0K;{O~6d$&CbKOox4nXuzZ8ynuL#lhsUjDh&yY%qeflVikx# z(FNq~J>wK61x}P(@QhzY>3otgBOo>Qryc$fB)Z$ulBw?|MD%Pc8QWP)b61zg*S4qR zsEKT%=@gWpwyz{I|HC5b%<#F-1c2f_ZbTJi*mP{K`Zj-N)8e|E1s&NG+aEEa37$$E z2U)Y?5v`@D(J6ez)|gEfeSw^}qyZX3jUc=Z1NdQe@GJp)b<-v(m{YsoE^*rJiEqs3 zH1)#e1b(JLSTQ^Aqt~x>{-!d#Od8fxA+V03JpC~143PS5fVKFY=EKfT&i$w@tE-?M z?+#qC0E&;2t3OTGda6`YP(idJ_p7FsA?TG>`kT%+pIdBDQ2rMn6`!~v+UHZuE)?;vDa=+3s6T1TXu-Z62NWEq7Dk%8; z{dZ2;@cfnkXh(Fw$|8ijhzEJha$$hMu-9Mnz2*s~YQ%0r5f>~Ye%-f955>PQXmyRG zSNDY%s&0)>Yb~R=79~-1GenLp2Vnj5>(Iw&Ke8=%wl~(dSPPqyyjZzl`^!w&)AUI? z%9Ih(b-42LA)!A?wWBZ~Y~2-0o066Q0-pE)`OXrji9RZwUl(2HCd{*~vvV@9&Oa;oQ=L~=_l1S1hn-dI%PC!(8efX!W}0DUM^ zVmIKZ7t|RG3X;@%>bQ>Yem@!jJd%(=2^KI8W?z;vJnFla019%8nJ9etpdW~H2j)SM zepCP9f<~H@Iq+t&Yeoi1@(B2kpfD~X5Hu}`y>y3}T zS5n~_GH43YFcZ@L$c#@{wS$pIgTe&^*YVO}^N6+zND0ESi3+kw`m)J(vI%X7DN(Yi z8AAy{vT1EYNz>FB%d%-tz^o_P)Oy)h9U%!{F3)br

&K1g0&rr2j#DNm*}L$0(Q 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

n%f794Qqp!`D1Z)=YMIccR^`E8K@U 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

K(^)uozS<@1N5v;9cVza{H!LM10 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

0rHDZVetSZosq&dDv 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�?(XiE&3E24v!9uH*WS;} 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
a8#e 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
~N05rsVRQh%aXC^<)s# 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 z

SsKSEC0t#i>TA({|WdQ5rrog0SPC0QXXf7@N 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�|-;Q(XLZ0ncyxcDtY2R{xTBEQ0aUk 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%0D(Y)@o8TZ7;WeQ4Vv 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 z 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 JBLe|m{~wF+V($O| literal 0 HcmV?d00001 diff --git a/docs/licecap_rules.gif b/docs/licecap_rules.gif new file mode 100644 index 0000000000000000000000000000000000000000..60201be3af51a538e34afb04e47ca75011eb0c9c GIT binary patch literal 48010 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 Q1HrSM;N#%SLZe6i7p|M|NdN!< literal 0 HcmV?d00001 From 1051c6214ce9f3a81c9243072e38a20e24eb3134 Mon Sep 17 00:00:00 2001 From: Nelson Chen Date: Wed, 15 Jan 2014 16:54:33 -0800 Subject: [PATCH 4/6] Update README.md Fix some HTML escaped characters. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 96b897a2..55ca57a2 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,12 @@ LICEcap is GPL free software, each download package includes the source. ## Requirements ## * For Windows: Windows XP/Vista/7 (might work with reduced functionality on other versions) -* For OSX: OS 10.4%2B (10.6%2B for full feature support), PPC or Intel (note: OS X support is still preliminary, some features are not supported) +* For OSX: OS 10.4+ (10.6+ for full feature support), PPC or Intel (note: OS X support is still preliminary, some features are not supported) * A reasonably fast CPU -* A healthy amount of RAM (1GB%2B, especially when encoding to LCF) +* A healthy amount of RAM (1GB+, especially when encoding to LCF) ## Author and Original Source This project was created by [Cockos Interactive](http://www.cockos.com), and is available on the web at the [official homepage](http://www.cockos.com/licecap/). The original source code repository is available via git from the [cockos licecap git repository](http://www-dev.cockos.com/licecap/licecap.git) - \ No newline at end of file + From 448cc8143f8576f0456de4f1fa4670e755f5f3a7 Mon Sep 17 00:00:00 2001 From: lepht Date: Wed, 27 Aug 2014 16:25:25 -0400 Subject: [PATCH 5/6] Converting WDL back from submodule To avoid issues when updating from upstream This reverts commit 71917ede534e3edd03c5968095dcd2424289b8a7. --- .gitmodules | 3 --- WDL | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 WDL diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 045d21bc..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "WDL"] - path = WDL - url = http://www-dev.cockos.com/wdl/WDL.git diff --git a/WDL b/WDL deleted file mode 160000 index 53ff5f1e..00000000 --- a/WDL +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 53ff5f1e4fefedc2bba9a3de1e1c4492c9b5a393 From b226d2d2b9889f57aa7ee110e199b91d93b069e4 Mon Sep 17 00:00:00 2001 From: lepht Date: Wed, 27 Aug 2014 16:26:04 -0400 Subject: [PATCH 6/6] Revert "Remove WDL library repo from licecap repo" This reverts commit 7861a4e3d9376c72bc81d50a245e0a5e03c209e1. --- WDL/IPlug/Containers.h | 173 + WDL/IPlug/Example/IPlugExample.cpp | 185 + WDL/IPlug/Example/IPlugExample.exp | 2 + WDL/IPlug/Example/IPlugExample.h | 29 + WDL/IPlug/Example/IPlugExample.rc | 7 + WDL/IPlug/Example/IPlugExample.vcproj | 299 + .../IPlugExample.xcodeproj/project.pbxproj | 675 + WDL/IPlug/Example/IPlugExampleAU-Info.plist | 22 + WDL/IPlug/Example/IPlugExample_Prefix.pch | 7 + WDL/IPlug/Example/Info.plist | 26 + WDL/IPlug/Example/README.txt | 4 + WDL/IPlug/Example/img/BG_400x200.png | Bin 0 -> 1856 bytes WDL/IPlug/Example/img/VU-meter_sm.png | Bin 0 -> 743112 bytes WDL/IPlug/Example/img/fader-cap_sm.png | Bin 0 -> 3733 bytes WDL/IPlug/Example/img/knob_sm.png | Bin 0 -> 4198 bytes WDL/IPlug/Example/img/toggle-switch.png | Bin 0 -> 18625 bytes WDL/IPlug/Example/resource.h | 54 + WDL/IPlug/Hosts.cpp | 63 + WDL/IPlug/Hosts.h | 43 + WDL/IPlug/IControl.cpp | 449 + WDL/IPlug/IControl.h | 402 + WDL/IPlug/IGraphics.cpp | 446 + WDL/IPlug/IGraphics.h | 162 + WDL/IPlug/IGraphicsCarbon.cpp | 264 + WDL/IPlug/IGraphicsCarbon.h | 37 + WDL/IPlug/IGraphicsCocoa.h | 40 + WDL/IPlug/IGraphicsCocoa.mm | 156 + WDL/IPlug/IGraphicsLice.cpp | 295 + WDL/IPlug/IGraphicsLice.h | 68 + WDL/IPlug/IGraphicsMac.h | 96 + WDL/IPlug/IGraphicsMac.mm | 313 + WDL/IPlug/IGraphicsWin.cpp | 718 + WDL/IPlug/IGraphicsWin.h | 79 + WDL/IPlug/IParam.cpp | 185 + WDL/IPlug/IParam.h | 82 + WDL/IPlug/IPlug.sln | 39 + WDL/IPlug/IPlug.vcproj | 350 + WDL/IPlug/IPlug.vcxproj | 213 + WDL/IPlug/IPlug.xcodeproj/project.pbxproj | 1009 ++ WDL/IPlug/IPlugAU.cpp | 1558 ++ WDL/IPlug/IPlugAU.h | 147 + WDL/IPlug/IPlugAU.r | 140 + WDL/IPlug/IPlugAU_ViewFactory.mm | 50 + WDL/IPlug/IPlugBase.cpp | 692 + WDL/IPlug/IPlugBase.h | 247 + WDL/IPlug/IPlugStructs.cpp | 147 + WDL/IPlug/IPlugStructs.h | 300 + WDL/IPlug/IPlugVST.cpp | 685 + WDL/IPlug/IPlugVST.h | 84 + WDL/IPlug/IPlug_Prefix.pch | 7 + WDL/IPlug/IPlug_include_in_plug_hdr.h | 32 + WDL/IPlug/IPlug_include_in_plug_src.h | 94 + WDL/IPlug/Log.cpp | 405 + WDL/IPlug/Log.h | 56 + WDL/IPlug/README.txt | 4 + WDL/IPlug/VSTHosts.cpp | 55 + WDL/IPlug/VSTHosts.h | 32 + WDL/IPlug/lice.vcproj | 1165 ++ WDL/MersenneTwister.h | 411 + WDL/adpcm_decode.h | 317 + WDL/adpcm_encode.h | 137 + WDL/assocarray.h | 317 + WDL/audiobuffercontainer.cpp | 495 + WDL/audiobuffercontainer.h | 106 + WDL/blowfish.c | 399 + WDL/blowfish.h | 23 + WDL/chunkalloc.h | 93 + WDL/circbuf.h | 171 + WDL/cmath/bessel_polynomial.h | 75 + WDL/cmath/complex_number.h | 368 + WDL/cmath/custom_math.h | 209 + WDL/cmath/durand_kerner.h | 117 + WDL/cmath/factorial.h | 114 + WDL/cmath/horner.h | 71 + WDL/cmath/test_bessel.c | 119 + WDL/cmath/test_eval.c | 87 + WDL/convoengine.cpp | 1057 ++ WDL/convoengine.h | 161 + WDL/db2val.h | 22 + WDL/denormal.h | 166 + WDL/des.cpp | 325 + WDL/des.h | 34 + WDL/destroycheck.h | 65 + WDL/dirscan.h | 245 + WDL/eel2/.gitignore | 1 + WDL/eel2/Makefile | 22 + WDL/eel2/a2i.php | 243 + WDL/eel2/a2x64.php | 305 + WDL/eel2/asm-nseel-ppc-gcc.c | 1377 ++ WDL/eel2/asm-nseel-x64-macho.asm | 1881 +++ WDL/eel2/asm-nseel-x64-macho.o | Bin 0 -> 9979 bytes WDL/eel2/asm-nseel-x64.asm | 1880 +++ WDL/eel2/asm-nseel-x64.obj | Bin 0 -> 9975 bytes WDL/eel2/asm-nseel-x86-gcc.c | 2035 +++ WDL/eel2/asm-nseel-x86-msvc.c | 3931 +++++ WDL/eel2/eel2.l | 73 + WDL/eel2/eel2.y | 147 + WDL/eel2/gen-lex-yacc | 1 + WDL/eel2/glue_port.h | 995 ++ WDL/eel2/glue_ppc.h | 257 + WDL/eel2/glue_x86.h | 355 + WDL/eel2/glue_x86_64.h | 261 + WDL/eel2/ns-eel-addfuncs.h | 87 + WDL/eel2/ns-eel-int.h | 318 + WDL/eel2/ns-eel.h | 207 + WDL/eel2/nseel-caltab.c | 545 + WDL/eel2/nseel-cfunc.c | 133 + WDL/eel2/nseel-compiler.c | 4574 ++++++ WDL/eel2/nseel-eval.c | 151 + WDL/eel2/nseel-lextab.c | 290 + WDL/eel2/nseel-ram.c | 342 + WDL/eel2/nseel-yylex.c | 189 + WDL/eel2/preproc_test.cpp | 76 + WDL/eel2/test.cpp | 65 + WDL/eel2/test_vc6.dsp | 144 + WDL/eel2/test_vc6.dsw | 29 + WDL/eel2/y.tab.c | 1819 +++ WDL/eel2/y.tab.h | 84 + WDL/fastqueue.h | 187 + WDL/ffmpeg.h | 533 + WDL/fft.c | 1647 +++ WDL/fft.h | 73 + WDL/filebrowse.cpp | 380 + WDL/filebrowse.h | 52 + WDL/filename.h | 65 + WDL/fileread.h | 796 + WDL/filewrite.h | 642 + WDL/giflib/AUTHORS | 36 + WDL/giflib/COPYING | 19 + WDL/giflib/ChangeLog | 549 + WDL/giflib/DEVELOPERS | 29 + WDL/giflib/README | 69 + WDL/giflib/config.h | 11 + WDL/giflib/dgif_lib.c | 1088 ++ WDL/giflib/egif_lib.c | 1103 ++ WDL/giflib/gif_hash.c | 152 + WDL/giflib/gif_hash.h | 50 + WDL/giflib/gif_lib.h | 336 + WDL/giflib/gif_lib_private.h | 59 + WDL/giflib/gifalloc.c | 441 + WDL/gpu/gpu.cpp | 317 + WDL/gpu/gpu.h | 121 + WDL/gpu/wglext.h | 611 + WDL/heapbuf.h | 346 + WDL/history.txt | 470 + WDL/jnetlib/Makefile | 20 + WDL/jnetlib/asyncdns.cpp | 266 + WDL/jnetlib/asyncdns.h | 74 + WDL/jnetlib/connection.cpp | 479 + WDL/jnetlib/connection.h | 188 + WDL/jnetlib/httpget.cpp | 445 + WDL/jnetlib/httpget.h | 152 + WDL/jnetlib/httpserv.cpp | 254 + WDL/jnetlib/httpserv.h | 114 + WDL/jnetlib/irc_util.h | 59 + WDL/jnetlib/jnetlib.h | 47 + WDL/jnetlib/listen.cpp | 73 + WDL/jnetlib/listen.h | 62 + WDL/jnetlib/netinc.h | 75 + WDL/jnetlib/test.cpp | 555 + WDL/jnetlib/test.dsp | 166 + WDL/jnetlib/test.dsw | 29 + WDL/jnetlib/testbnc.cpp | 102 + WDL/jnetlib/util.cpp | 36 + WDL/jnetlib/util.h | 39 + WDL/jnetlib/webserver.cpp | 398 + WDL/jnetlib/webserver.h | 224 + WDL/jpeglib/README | 385 + WDL/jpeglib/example.c | 433 + WDL/jpeglib/jcapimin.c | 280 + WDL/jpeglib/jcapistd.c | 161 + WDL/jpeglib/jccoefct.c | 449 + WDL/jpeglib/jccolor.c | 459 + WDL/jpeglib/jcdctmgr.c | 387 + WDL/jpeglib/jchuff.c | 909 ++ WDL/jpeglib/jchuff.h | 47 + WDL/jpeglib/jcinit.c | 72 + WDL/jpeglib/jcmainct.c | 293 + WDL/jpeglib/jcmarker.c | 664 + WDL/jpeglib/jcmaster.c | 590 + WDL/jpeglib/jcomapi.c | 106 + WDL/jpeglib/jconfig.h | 15 + WDL/jpeglib/jcparam.c | 610 + WDL/jpeglib/jcphuff.c | 833 ++ WDL/jpeglib/jcprepct.c | 354 + WDL/jpeglib/jcsample.c | 519 + WDL/jpeglib/jctrans.c | 388 + WDL/jpeglib/jdapimin.c | 395 + WDL/jpeglib/jdapistd.c | 275 + WDL/jpeglib/jdatadst.c | 151 + WDL/jpeglib/jdatasrc.c | 212 + WDL/jpeglib/jdcoefct.c | 736 + WDL/jpeglib/jdcolor.c | 396 + WDL/jpeglib/jdct.h | 176 + WDL/jpeglib/jddctmgr.c | 269 + WDL/jpeglib/jdhuff.c | 651 + WDL/jpeglib/jdhuff.h | 201 + WDL/jpeglib/jdinput.c | 381 + WDL/jpeglib/jdmainct.c | 512 + WDL/jpeglib/jdmarker.c | 1360 ++ WDL/jpeglib/jdmaster.c | 557 + WDL/jpeglib/jdmerge.c | 400 + WDL/jpeglib/jdphuff.c | 668 + WDL/jpeglib/jdpostct.c | 290 + WDL/jpeglib/jdsample.c | 478 + WDL/jpeglib/jdtrans.c | 143 + WDL/jpeglib/jerror.c | 252 + WDL/jpeglib/jerror.h | 291 + WDL/jpeglib/jfdctflt.c | 168 + WDL/jpeglib/jfdctfst.c | 224 + WDL/jpeglib/jfdctint.c | 283 + WDL/jpeglib/jidctflt.c | 242 + WDL/jpeglib/jidctfst.c | 368 + WDL/jpeglib/jidctint.c | 389 + WDL/jpeglib/jidctred.c | 398 + WDL/jpeglib/jinclude.h | 91 + WDL/jpeglib/jmemmgr.c | 1118 ++ WDL/jpeglib/jmemnobs.c | 109 + WDL/jpeglib/jmemsys.h | 198 + WDL/jpeglib/jmorecfg.h | 363 + WDL/jpeglib/jpegint.h | 392 + WDL/jpeglib/jpeglib.h | 1096 ++ WDL/jpeglib/jquant1.c | 856 ++ WDL/jpeglib/jquant2.c | 1310 ++ WDL/jpeglib/jutils.c | 179 + WDL/jpeglib/jversion.h | 14 + WDL/lameencdec.cpp | 1004 ++ WDL/lameencdec.h | 136 + WDL/libpng/LICENSE | 111 + WDL/libpng/README | 202 + WDL/libpng/png.c | 2870 ++++ WDL/libpng/png.h | 2654 ++++ WDL/libpng/pngconf.h | 596 + WDL/libpng/pngdebug.h | 157 + WDL/libpng/pngerror.c | 685 + WDL/libpng/pngget.c | 1124 ++ WDL/libpng/pnginfo.h | 269 + WDL/libpng/pnglibconf.h | 189 + WDL/libpng/pngmem.c | 667 + WDL/libpng/pngpread.c | 1846 +++ WDL/libpng/pngpriv.h | 1629 ++ WDL/libpng/pngread.c | 1308 ++ WDL/libpng/pngrio.c | 176 + WDL/libpng/pngrtran.c | 5023 +++++++ WDL/libpng/pngrutil.c | 4160 ++++++ WDL/libpng/pngset.c | 1284 ++ WDL/libpng/pngstruct.h | 360 + WDL/libpng/pngtest.c | 1820 +++ WDL/libpng/pngtrans.c | 678 + WDL/libpng/pngwio.c | 254 + WDL/libpng/pngwrite.c | 1655 +++ WDL/libpng/pngwtran.c | 633 + WDL/libpng/pngwutil.c | 3180 ++++ WDL/lice/Makefile | 24 + WDL/lice/glew/include/GL/WGLEXT.H | 631 + WDL/lice/glew/include/GL/glew.h | 12262 ++++++++++++++++ WDL/lice/glew/include/GL/glxew.h | 1397 ++ WDL/lice/glew/include/GL/wglew.h | 1165 ++ WDL/lice/glew/src/glew.c | 12180 +++++++++++++++ WDL/lice/glew/src/glewinfo.c | 7180 +++++++++ WDL/lice/glew/src/visualinfo.c | 1173 ++ WDL/lice/lice.cpp | 2173 +++ WDL/lice/lice.dsp | 942 ++ WDL/lice/lice.dsw | 59 + WDL/lice/lice.h | 554 + WDL/lice/lice.vcxproj | 431 + WDL/lice/lice_arc.cpp | 496 + WDL/lice/lice_bezier.h | 295 + WDL/lice/lice_bmp.cpp | 114 + WDL/lice/lice_colorspace.cpp | 134 + WDL/lice/lice_combine.h | 831 ++ WDL/lice/lice_extended.h | 164 + WDL/lice/lice_gif.cpp | 159 + WDL/lice/lice_gif_write.cpp | 323 + WDL/lice/lice_gl_ctx.cpp | 264 + WDL/lice/lice_gl_ctx.h | 27 + WDL/lice/lice_glbitmap.cpp | 708 + WDL/lice/lice_glbitmap.h | 110 + WDL/lice/lice_ico.cpp | 186 + WDL/lice/lice_image.cpp | 148 + WDL/lice/lice_jpg.cpp | 310 + WDL/lice/lice_jpg_write.cpp | 117 + WDL/lice/lice_lcf.cpp | 663 + WDL/lice/lice_lcf.h | 110 + WDL/lice/lice_line.cpp | 1612 ++ WDL/lice/lice_lvg.cpp | 620 + WDL/lice/lice_palette.cpp | 327 + WDL/lice/lice_pcx.cpp | 108 + WDL/lice/lice_png.cpp | 364 + WDL/lice/lice_png_write.cpp | 131 + WDL/lice/lice_svg.cpp | 851 ++ WDL/lice/lice_texgen.cpp | 341 + WDL/lice/lice_text.cpp | 1390 ++ WDL/lice/lice_text.h | 110 + WDL/lice/lice_textnew.cpp | 1014 ++ WDL/lice/makedist.bat | 2 + WDL/lice/test/Controller.h | 9 + WDL/lice/test/Controller.mm | 40 + WDL/lice/test/English.lproj/InfoPlist.strings | Bin 0 -> 202 bytes .../English.lproj/MainMenu.nib/classes.nib | 7 + .../test/English.lproj/MainMenu.nib/info.nib | 21 + .../MainMenu.nib/keyedobjects.nib | Bin 0 -> 13648 bytes WDL/lice/test/Info.plist | 28 + WDL/lice/test/fly.cpp | 286 + WDL/lice/test/image.png | Bin 0 -> 4910 bytes WDL/lice/test/imgs2gif.cpp | 100 + WDL/lice/test/main.cpp | 1026 ++ WDL/lice/test/main.ico | Bin 0 -> 24942 bytes WDL/lice/test/main.m | 14 + WDL/lice/test/resource.h | 27 + WDL/lice/test/test.dsp | 120 + WDL/lice/test/test.rc | 107 + WDL/lice/test/test.xcodeproj/project.pbxproj | 918 ++ WDL/lineparse.h | 331 + WDL/makedist.bat | 13 + WDL/mergesort.h | 65 + WDL/mp3write.h | 138 + WDL/mutex.h | 238 + WDL/nsv/nsvbs.h | 272 + WDL/nsv/nsvlib.cpp | 738 + WDL/nsv/nsvlib.h | 390 + WDL/pcmfmtcvt.h | 528 + WDL/plush2/pl_cam.cpp | 748 + WDL/plush2/pl_make.cpp | 480 + WDL/plush2/pl_math.cpp | 67 + WDL/plush2/pl_obj.cpp | 128 + WDL/plush2/pl_pf_tex.h | 442 + WDL/plush2/pl_putface.cpp | 707 + WDL/plush2/pl_read_3ds.cpp | 347 + WDL/plush2/pl_read_cob.cpp | 181 + WDL/plush2/pl_read_jaw.cpp | 69 + WDL/plush2/pl_spline.cpp | 50 + WDL/plush2/plush.h | 598 + WDL/plush2/plush2.dsp | 217 + WDL/poollist.h | 155 + WDL/projectcontext.cpp | 678 + WDL/projectcontext.h | 50 + WDL/ptrlist.h | 223 + WDL/queue.h | 273 + WDL/reminder.h | 13 + WDL/resample.cpp | 597 + WDL/resample.h | 101 + WDL/rfb_client.cpp | 443 + WDL/rfb_client.h | 70 + WDL/rng.cpp | 95 + WDL/rng.h | 42 + WDL/rpool.h | 186 + WDL/sc_bounce/stream-config.php | 21 + WDL/sc_bounce/stream.php | 243 + WDL/scsrc.cpp | 700 + WDL/scsrc.h | 114 + WDL/sha.cpp | 133 + WDL/sha.h | 54 + WDL/sharedpool.h | 128 + WDL/shm_connection.cpp | 521 + WDL/shm_connection.h | 87 + WDL/shm_msgreply.cpp | 346 + WDL/shm_msgreply.h | 86 + WDL/simple_pitchshift.h | 311 + WDL/simple_pitchshift2.h | 315 + WDL/sinewavegen.h | 59 + WDL/stringpool.h | 92 + WDL/swell/Makefile.libSwell | 65 + WDL/swell/commctrl.h | 1 + WDL/swell/mac_resgen.php | 283 + WDL/swell/make-libSwells.sh | 10 + .../English.lproj/InfoPlist.strings | Bin 0 -> 92 bytes .../sample_project/English.lproj/MainMenu.xib | 520 + WDL/swell/sample_project/Info.plist | 28 + WDL/swell/sample_project/app_main.cpp | 198 + WDL/swell/sample_project/main.h | 23 + WDL/swell/sample_project/main.m | 14 + WDL/swell/sample_project/main_dialog.cpp | 55 + WDL/swell/sample_project/resource.h | 21 + WDL/swell/sample_project/sample_project.dsp | 119 + WDL/swell/sample_project/sample_project.dsw | 29 + WDL/swell/sample_project/sample_project.rc | 118 + .../TemplateIcon.icns | Bin 0 -> 52318 bytes .../sample_project.xcodeproj/project.pbxproj | 369 + .../sample_project/sample_project_Prefix.pch | 7 + WDL/swell/sample_project/version.plist | 16 + WDL/swell/shlobj.h | 1 + WDL/swell/swell-appstub-generic.cpp | 44 + WDL/swell/swell-appstub.mm | 42 + WDL/swell/swell-dlg-generic.cpp | 212 + WDL/swell/swell-dlg.mm | 3214 ++++ WDL/swell/swell-dlggen.h | 280 + WDL/swell/swell-functions.h | 1092 ++ WDL/swell/swell-gdi-generic.cpp | 676 + WDL/swell/swell-gdi-internalpool.h | 194 + WDL/swell/swell-gdi-lice.cpp | 1284 ++ WDL/swell/swell-gdi.mm | 1530 ++ WDL/swell/swell-ini.cpp | 551 + WDL/swell/swell-internal.h | 758 + WDL/swell/swell-kb-generic.cpp | 110 + WDL/swell/swell-kb.mm | 601 + WDL/swell/swell-menu-generic.cpp | 631 + WDL/swell/swell-menu.mm | 919 ++ WDL/swell/swell-menugen.h | 94 + WDL/swell/swell-misc-generic.cpp | 20 + WDL/swell/swell-misc.mm | 566 + WDL/swell/swell-miscdlg-generic.cpp | 184 + WDL/swell/swell-miscdlg-gtk.cpp | 141 + WDL/swell/swell-miscdlg.mm | 354 + WDL/swell/swell-modstub-generic.cpp | 111 + WDL/swell/swell-modstub.mm | 70 + WDL/swell/swell-types.h | 1337 ++ WDL/swell/swell-wnd-generic.cpp | 3562 +++++ WDL/swell/swell-wnd.mm | 6128 ++++++++ WDL/swell/swell.cpp | 909 ++ WDL/swell/swell.h | 147 + WDL/swell/swellappmain.h | 14 + WDL/swell/swellappmain.mm | 232 + WDL/swell/test-gtk.cpp | 16 + WDL/swell/test.cpp | 7 + WDL/swell/windows.h | 165 + WDL/timing.c | 85 + WDL/timing.h | 43 + WDL/tinyxml/libxml_tinyxml.cpp | 132 + WDL/tinyxml/libxml_tinyxml.h | 52 + WDL/tinyxml/svgtiny_colors.c | 955 ++ WDL/tinyxml/tinystr.cpp | 116 + WDL/tinyxml/tinystr.h | 320 + WDL/tinyxml/tinyxml.cpp | 1888 +++ WDL/tinyxml/tinyxml.h | 1802 +++ WDL/tinyxml/tinyxmlerror.cpp | 53 + WDL/tinyxml/tinyxmlparser.cpp | 1638 +++ WDL/verbengine.h | 298 + WDL/vorbisencdec.h | 468 + WDL/wavwrite.h | 318 + WDL/wdlcstring.h | 163 + WDL/wdlstring.h | 290 + WDL/wdltypes.h | 77 + WDL/win32_curses/curses.h | 180 + WDL/win32_curses/curses_win32.cpp | 742 + WDL/win32_curses/test.cpp | 80 + WDL/win32_utf8.c | 984 ++ WDL/win32_utf8.h | 202 + WDL/win7filedialog.cpp | 507 + WDL/win7filedialog.h | 2206 +++ WDL/wingui/dlgitemborder.h | 204 + WDL/wingui/membitmap.h | 94 + WDL/wingui/richeditctrl.h | 83 + WDL/wingui/scrollbar/coolscroll.cpp | 3741 +++++ WDL/wingui/scrollbar/coolscroll.h | 93 + WDL/wingui/virtwnd-controls.h | 370 + WDL/wingui/virtwnd-iaccessible.cpp | 866 ++ WDL/wingui/virtwnd-iconbutton.cpp | 1118 ++ WDL/wingui/virtwnd-listbox.cpp | 728 + WDL/wingui/virtwnd-nsaccessibility.mm | 644 + WDL/wingui/virtwnd-skin.h | 91 + WDL/wingui/virtwnd-slider.cpp | 1173 ++ WDL/wingui/virtwnd.cpp | 1635 +++ WDL/wingui/virtwnd.h | 224 + WDL/wingui/wndsize.cpp | 349 + WDL/wingui/wndsize.h | 143 + WDL/zlib/adler32.c | 179 + WDL/zlib/compress.c | 80 + WDL/zlib/crc32.c | 449 + WDL/zlib/crc32.h | 441 + WDL/zlib/deflate.c | 1965 +++ WDL/zlib/deflate.h | 346 + WDL/zlib/gzclose.c | 25 + WDL/zlib/gzguts.h | 190 + WDL/zlib/gzlib.c | 564 + WDL/zlib/gzread.c | 584 + WDL/zlib/gzwrite.c | 593 + WDL/zlib/infback.c | 640 + WDL/zlib/inffast.c | 340 + WDL/zlib/inffast.h | 11 + WDL/zlib/inffixed.h | 94 + WDL/zlib/inflate.c | 1501 ++ WDL/zlib/inflate.h | 122 + WDL/zlib/inftrees.c | 306 + WDL/zlib/inftrees.h | 62 + WDL/zlib/ioapi.c | 247 + WDL/zlib/ioapi.h | 208 + WDL/zlib/trees.c | 1224 ++ WDL/zlib/trees.h | 128 + WDL/zlib/uncompr.c | 59 + WDL/zlib/unzip.c | 2125 +++ WDL/zlib/unzip.h | 437 + WDL/zlib/zconf.h | 466 + WDL/zlib/zconf.in.h | 332 + WDL/zlib/zip.c | 2012 +++ WDL/zlib/zip.h | 362 + WDL/zlib/zlib.h | 1732 +++ WDL/zlib/zutil.c | 303 + WDL/zlib/zutil.h | 248 + .../English.lproj}/InfoPlist.strings | 0 .../English.lproj}/MainMenu.xib | 0 background.png => licecap/background.png | Bin capturewindow.mm => licecap/capturewindow.mm | 0 icon1.ico => licecap/icon1.ico | Bin installer.nsi => licecap/installer.nsi | 0 .../licecap-Info.plist | 0 licecap.dsw => licecap/licecap.dsw | 0 licecap.icns => licecap/licecap.icns | Bin licecap.rc => licecap/licecap.rc | 0 .../licecap.xcodeproj}/project.pbxproj | 0 .../licecap_Prefix.pch | 0 licecap_cli.cpp => licecap/licecap_cli.cpp | 0 licecap_cli.dsp => licecap/licecap_cli.dsp | 0 licecap_gui.dsp => licecap/licecap_gui.dsp | 0 licecap_ui.cpp => licecap/licecap_ui.cpp | 0 .../licecap_version.h | 0 license.txt => licecap/license.txt | 0 main.m => licecap/main.m | 0 makedmg.sh => licecap/makedmg.sh | 0 pkg-dmg => licecap/pkg-dmg | 0 requires_wdl.txt => licecap/requires_wdl.txt | 0 resource.h => licecap/resource.h | 0 stage_DS_Store => licecap/stage_DS_Store | Bin whatsnew.txt => licecap/whatsnew.txt | 0 514 files changed, 254056 insertions(+) create mode 100644 WDL/IPlug/Containers.h create mode 100644 WDL/IPlug/Example/IPlugExample.cpp create mode 100644 WDL/IPlug/Example/IPlugExample.exp create mode 100644 WDL/IPlug/Example/IPlugExample.h create mode 100644 WDL/IPlug/Example/IPlugExample.rc create mode 100644 WDL/IPlug/Example/IPlugExample.vcproj create mode 100644 WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj create mode 100644 WDL/IPlug/Example/IPlugExampleAU-Info.plist create mode 100644 WDL/IPlug/Example/IPlugExample_Prefix.pch create mode 100644 WDL/IPlug/Example/Info.plist create mode 100644 WDL/IPlug/Example/README.txt create mode 100644 WDL/IPlug/Example/img/BG_400x200.png create mode 100644 WDL/IPlug/Example/img/VU-meter_sm.png create mode 100644 WDL/IPlug/Example/img/fader-cap_sm.png create mode 100644 WDL/IPlug/Example/img/knob_sm.png create mode 100644 WDL/IPlug/Example/img/toggle-switch.png create mode 100644 WDL/IPlug/Example/resource.h create mode 100644 WDL/IPlug/Hosts.cpp create mode 100644 WDL/IPlug/Hosts.h create mode 100644 WDL/IPlug/IControl.cpp create mode 100644 WDL/IPlug/IControl.h create mode 100644 WDL/IPlug/IGraphics.cpp create mode 100644 WDL/IPlug/IGraphics.h create mode 100644 WDL/IPlug/IGraphicsCarbon.cpp create mode 100644 WDL/IPlug/IGraphicsCarbon.h create mode 100644 WDL/IPlug/IGraphicsCocoa.h create mode 100644 WDL/IPlug/IGraphicsCocoa.mm create mode 100644 WDL/IPlug/IGraphicsLice.cpp create mode 100644 WDL/IPlug/IGraphicsLice.h create mode 100644 WDL/IPlug/IGraphicsMac.h create mode 100644 WDL/IPlug/IGraphicsMac.mm create mode 100644 WDL/IPlug/IGraphicsWin.cpp create mode 100644 WDL/IPlug/IGraphicsWin.h create mode 100644 WDL/IPlug/IParam.cpp create mode 100644 WDL/IPlug/IParam.h create mode 100644 WDL/IPlug/IPlug.sln create mode 100644 WDL/IPlug/IPlug.vcproj create mode 100644 WDL/IPlug/IPlug.vcxproj create mode 100644 WDL/IPlug/IPlug.xcodeproj/project.pbxproj create mode 100644 WDL/IPlug/IPlugAU.cpp create mode 100644 WDL/IPlug/IPlugAU.h create mode 100644 WDL/IPlug/IPlugAU.r create mode 100644 WDL/IPlug/IPlugAU_ViewFactory.mm create mode 100644 WDL/IPlug/IPlugBase.cpp create mode 100644 WDL/IPlug/IPlugBase.h create mode 100644 WDL/IPlug/IPlugStructs.cpp create mode 100644 WDL/IPlug/IPlugStructs.h create mode 100644 WDL/IPlug/IPlugVST.cpp create mode 100644 WDL/IPlug/IPlugVST.h create mode 100644 WDL/IPlug/IPlug_Prefix.pch create mode 100644 WDL/IPlug/IPlug_include_in_plug_hdr.h create mode 100644 WDL/IPlug/IPlug_include_in_plug_src.h create mode 100644 WDL/IPlug/Log.cpp create mode 100644 WDL/IPlug/Log.h create mode 100644 WDL/IPlug/README.txt create mode 100644 WDL/IPlug/VSTHosts.cpp create mode 100644 WDL/IPlug/VSTHosts.h create mode 100644 WDL/IPlug/lice.vcproj create mode 100644 WDL/MersenneTwister.h create mode 100644 WDL/adpcm_decode.h create mode 100644 WDL/adpcm_encode.h create mode 100644 WDL/assocarray.h create mode 100644 WDL/audiobuffercontainer.cpp create mode 100644 WDL/audiobuffercontainer.h create mode 100644 WDL/blowfish.c create mode 100644 WDL/blowfish.h create mode 100644 WDL/chunkalloc.h create mode 100644 WDL/circbuf.h create mode 100644 WDL/cmath/bessel_polynomial.h create mode 100644 WDL/cmath/complex_number.h create mode 100644 WDL/cmath/custom_math.h create mode 100644 WDL/cmath/durand_kerner.h create mode 100644 WDL/cmath/factorial.h create mode 100644 WDL/cmath/horner.h create mode 100644 WDL/cmath/test_bessel.c create mode 100644 WDL/cmath/test_eval.c create mode 100644 WDL/convoengine.cpp create mode 100644 WDL/convoengine.h create mode 100644 WDL/db2val.h create mode 100644 WDL/denormal.h create mode 100644 WDL/des.cpp create mode 100644 WDL/des.h create mode 100644 WDL/destroycheck.h create mode 100644 WDL/dirscan.h create mode 100644 WDL/eel2/.gitignore create mode 100644 WDL/eel2/Makefile create mode 100644 WDL/eel2/a2i.php create mode 100644 WDL/eel2/a2x64.php create mode 100644 WDL/eel2/asm-nseel-ppc-gcc.c create mode 100644 WDL/eel2/asm-nseel-x64-macho.asm create mode 100644 WDL/eel2/asm-nseel-x64-macho.o create mode 100644 WDL/eel2/asm-nseel-x64.asm create mode 100644 WDL/eel2/asm-nseel-x64.obj create mode 100644 WDL/eel2/asm-nseel-x86-gcc.c create mode 100644 WDL/eel2/asm-nseel-x86-msvc.c create mode 100644 WDL/eel2/eel2.l create mode 100644 WDL/eel2/eel2.y create mode 100644 WDL/eel2/gen-lex-yacc create mode 100644 WDL/eel2/glue_port.h create mode 100644 WDL/eel2/glue_ppc.h create mode 100644 WDL/eel2/glue_x86.h create mode 100644 WDL/eel2/glue_x86_64.h create mode 100644 WDL/eel2/ns-eel-addfuncs.h create mode 100644 WDL/eel2/ns-eel-int.h create mode 100644 WDL/eel2/ns-eel.h create mode 100644 WDL/eel2/nseel-caltab.c create mode 100644 WDL/eel2/nseel-cfunc.c create mode 100644 WDL/eel2/nseel-compiler.c create mode 100644 WDL/eel2/nseel-eval.c create mode 100644 WDL/eel2/nseel-lextab.c create mode 100644 WDL/eel2/nseel-ram.c create mode 100644 WDL/eel2/nseel-yylex.c create mode 100644 WDL/eel2/preproc_test.cpp create mode 100644 WDL/eel2/test.cpp create mode 100644 WDL/eel2/test_vc6.dsp create mode 100644 WDL/eel2/test_vc6.dsw create mode 100644 WDL/eel2/y.tab.c create mode 100644 WDL/eel2/y.tab.h create mode 100644 WDL/fastqueue.h create mode 100644 WDL/ffmpeg.h create mode 100644 WDL/fft.c create mode 100644 WDL/fft.h create mode 100644 WDL/filebrowse.cpp create mode 100644 WDL/filebrowse.h create mode 100644 WDL/filename.h create mode 100644 WDL/fileread.h create mode 100644 WDL/filewrite.h create mode 100644 WDL/giflib/AUTHORS create mode 100644 WDL/giflib/COPYING create mode 100644 WDL/giflib/ChangeLog create mode 100644 WDL/giflib/DEVELOPERS create mode 100644 WDL/giflib/README create mode 100644 WDL/giflib/config.h create mode 100644 WDL/giflib/dgif_lib.c create mode 100644 WDL/giflib/egif_lib.c create mode 100644 WDL/giflib/gif_hash.c create mode 100644 WDL/giflib/gif_hash.h create mode 100644 WDL/giflib/gif_lib.h create mode 100644 WDL/giflib/gif_lib_private.h create mode 100644 WDL/giflib/gifalloc.c create mode 100644 WDL/gpu/gpu.cpp create mode 100644 WDL/gpu/gpu.h create mode 100644 WDL/gpu/wglext.h create mode 100644 WDL/heapbuf.h create mode 100644 WDL/history.txt create mode 100644 WDL/jnetlib/Makefile create mode 100644 WDL/jnetlib/asyncdns.cpp create mode 100644 WDL/jnetlib/asyncdns.h create mode 100644 WDL/jnetlib/connection.cpp create mode 100644 WDL/jnetlib/connection.h create mode 100644 WDL/jnetlib/httpget.cpp create mode 100644 WDL/jnetlib/httpget.h create mode 100644 WDL/jnetlib/httpserv.cpp create mode 100644 WDL/jnetlib/httpserv.h create mode 100644 WDL/jnetlib/irc_util.h create mode 100644 WDL/jnetlib/jnetlib.h create mode 100644 WDL/jnetlib/listen.cpp create mode 100644 WDL/jnetlib/listen.h create mode 100644 WDL/jnetlib/netinc.h create mode 100644 WDL/jnetlib/test.cpp create mode 100644 WDL/jnetlib/test.dsp create mode 100644 WDL/jnetlib/test.dsw create mode 100644 WDL/jnetlib/testbnc.cpp create mode 100644 WDL/jnetlib/util.cpp create mode 100644 WDL/jnetlib/util.h create mode 100644 WDL/jnetlib/webserver.cpp create mode 100644 WDL/jnetlib/webserver.h create mode 100644 WDL/jpeglib/README create mode 100644 WDL/jpeglib/example.c create mode 100644 WDL/jpeglib/jcapimin.c create mode 100644 WDL/jpeglib/jcapistd.c create mode 100644 WDL/jpeglib/jccoefct.c create mode 100644 WDL/jpeglib/jccolor.c create mode 100644 WDL/jpeglib/jcdctmgr.c create mode 100644 WDL/jpeglib/jchuff.c create mode 100644 WDL/jpeglib/jchuff.h create mode 100644 WDL/jpeglib/jcinit.c create mode 100644 WDL/jpeglib/jcmainct.c create mode 100644 WDL/jpeglib/jcmarker.c create mode 100644 WDL/jpeglib/jcmaster.c create mode 100644 WDL/jpeglib/jcomapi.c create mode 100644 WDL/jpeglib/jconfig.h create mode 100644 WDL/jpeglib/jcparam.c create mode 100644 WDL/jpeglib/jcphuff.c create mode 100644 WDL/jpeglib/jcprepct.c create mode 100644 WDL/jpeglib/jcsample.c create mode 100644 WDL/jpeglib/jctrans.c create mode 100644 WDL/jpeglib/jdapimin.c create mode 100644 WDL/jpeglib/jdapistd.c create mode 100644 WDL/jpeglib/jdatadst.c create mode 100644 WDL/jpeglib/jdatasrc.c create mode 100644 WDL/jpeglib/jdcoefct.c create mode 100644 WDL/jpeglib/jdcolor.c create mode 100644 WDL/jpeglib/jdct.h create mode 100644 WDL/jpeglib/jddctmgr.c create mode 100644 WDL/jpeglib/jdhuff.c create mode 100644 WDL/jpeglib/jdhuff.h create mode 100644 WDL/jpeglib/jdinput.c create mode 100644 WDL/jpeglib/jdmainct.c create mode 100644 WDL/jpeglib/jdmarker.c create mode 100644 WDL/jpeglib/jdmaster.c create mode 100644 WDL/jpeglib/jdmerge.c create mode 100644 WDL/jpeglib/jdphuff.c create mode 100644 WDL/jpeglib/jdpostct.c create mode 100644 WDL/jpeglib/jdsample.c create mode 100644 WDL/jpeglib/jdtrans.c create mode 100644 WDL/jpeglib/jerror.c create mode 100644 WDL/jpeglib/jerror.h create mode 100644 WDL/jpeglib/jfdctflt.c create mode 100644 WDL/jpeglib/jfdctfst.c create mode 100644 WDL/jpeglib/jfdctint.c create mode 100644 WDL/jpeglib/jidctflt.c create mode 100644 WDL/jpeglib/jidctfst.c create mode 100644 WDL/jpeglib/jidctint.c create mode 100644 WDL/jpeglib/jidctred.c create mode 100644 WDL/jpeglib/jinclude.h create mode 100644 WDL/jpeglib/jmemmgr.c create mode 100644 WDL/jpeglib/jmemnobs.c create mode 100644 WDL/jpeglib/jmemsys.h create mode 100644 WDL/jpeglib/jmorecfg.h create mode 100644 WDL/jpeglib/jpegint.h create mode 100644 WDL/jpeglib/jpeglib.h create mode 100644 WDL/jpeglib/jquant1.c create mode 100644 WDL/jpeglib/jquant2.c create mode 100644 WDL/jpeglib/jutils.c create mode 100644 WDL/jpeglib/jversion.h create mode 100644 WDL/lameencdec.cpp create mode 100644 WDL/lameencdec.h create mode 100644 WDL/libpng/LICENSE create mode 100644 WDL/libpng/README create mode 100644 WDL/libpng/png.c create mode 100644 WDL/libpng/png.h create mode 100644 WDL/libpng/pngconf.h create mode 100644 WDL/libpng/pngdebug.h create mode 100644 WDL/libpng/pngerror.c create mode 100644 WDL/libpng/pngget.c create mode 100644 WDL/libpng/pnginfo.h create mode 100644 WDL/libpng/pnglibconf.h create mode 100644 WDL/libpng/pngmem.c create mode 100644 WDL/libpng/pngpread.c create mode 100644 WDL/libpng/pngpriv.h create mode 100644 WDL/libpng/pngread.c create mode 100644 WDL/libpng/pngrio.c create mode 100644 WDL/libpng/pngrtran.c create mode 100644 WDL/libpng/pngrutil.c create mode 100644 WDL/libpng/pngset.c create mode 100644 WDL/libpng/pngstruct.h create mode 100644 WDL/libpng/pngtest.c create mode 100644 WDL/libpng/pngtrans.c create mode 100644 WDL/libpng/pngwio.c create mode 100644 WDL/libpng/pngwrite.c create mode 100644 WDL/libpng/pngwtran.c create mode 100644 WDL/libpng/pngwutil.c create mode 100644 WDL/lice/Makefile create mode 100644 WDL/lice/glew/include/GL/WGLEXT.H create mode 100644 WDL/lice/glew/include/GL/glew.h create mode 100644 WDL/lice/glew/include/GL/glxew.h create mode 100644 WDL/lice/glew/include/GL/wglew.h create mode 100644 WDL/lice/glew/src/glew.c create mode 100644 WDL/lice/glew/src/glewinfo.c create mode 100644 WDL/lice/glew/src/visualinfo.c create mode 100644 WDL/lice/lice.cpp create mode 100644 WDL/lice/lice.dsp create mode 100644 WDL/lice/lice.dsw create mode 100644 WDL/lice/lice.h create mode 100644 WDL/lice/lice.vcxproj create mode 100644 WDL/lice/lice_arc.cpp create mode 100644 WDL/lice/lice_bezier.h create mode 100644 WDL/lice/lice_bmp.cpp create mode 100644 WDL/lice/lice_colorspace.cpp create mode 100644 WDL/lice/lice_combine.h create mode 100644 WDL/lice/lice_extended.h create mode 100644 WDL/lice/lice_gif.cpp create mode 100644 WDL/lice/lice_gif_write.cpp create mode 100644 WDL/lice/lice_gl_ctx.cpp create mode 100644 WDL/lice/lice_gl_ctx.h create mode 100644 WDL/lice/lice_glbitmap.cpp create mode 100644 WDL/lice/lice_glbitmap.h create mode 100644 WDL/lice/lice_ico.cpp create mode 100644 WDL/lice/lice_image.cpp create mode 100644 WDL/lice/lice_jpg.cpp create mode 100644 WDL/lice/lice_jpg_write.cpp create mode 100644 WDL/lice/lice_lcf.cpp create mode 100644 WDL/lice/lice_lcf.h create mode 100644 WDL/lice/lice_line.cpp create mode 100644 WDL/lice/lice_lvg.cpp create mode 100644 WDL/lice/lice_palette.cpp create mode 100644 WDL/lice/lice_pcx.cpp create mode 100644 WDL/lice/lice_png.cpp create mode 100644 WDL/lice/lice_png_write.cpp create mode 100644 WDL/lice/lice_svg.cpp create mode 100644 WDL/lice/lice_texgen.cpp create mode 100644 WDL/lice/lice_text.cpp create mode 100644 WDL/lice/lice_text.h create mode 100644 WDL/lice/lice_textnew.cpp create mode 100644 WDL/lice/makedist.bat create mode 100644 WDL/lice/test/Controller.h create mode 100644 WDL/lice/test/Controller.mm create mode 100644 WDL/lice/test/English.lproj/InfoPlist.strings create mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/classes.nib create mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/info.nib create mode 100644 WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 WDL/lice/test/Info.plist create mode 100644 WDL/lice/test/fly.cpp create mode 100644 WDL/lice/test/image.png create mode 100644 WDL/lice/test/imgs2gif.cpp create mode 100644 WDL/lice/test/main.cpp create mode 100644 WDL/lice/test/main.ico create mode 100644 WDL/lice/test/main.m create mode 100644 WDL/lice/test/resource.h create mode 100644 WDL/lice/test/test.dsp create mode 100644 WDL/lice/test/test.rc create mode 100644 WDL/lice/test/test.xcodeproj/project.pbxproj create mode 100644 WDL/lineparse.h create mode 100644 WDL/makedist.bat create mode 100644 WDL/mergesort.h create mode 100644 WDL/mp3write.h create mode 100644 WDL/mutex.h create mode 100644 WDL/nsv/nsvbs.h create mode 100644 WDL/nsv/nsvlib.cpp create mode 100644 WDL/nsv/nsvlib.h create mode 100644 WDL/pcmfmtcvt.h create mode 100644 WDL/plush2/pl_cam.cpp create mode 100644 WDL/plush2/pl_make.cpp create mode 100644 WDL/plush2/pl_math.cpp create mode 100644 WDL/plush2/pl_obj.cpp create mode 100644 WDL/plush2/pl_pf_tex.h create mode 100644 WDL/plush2/pl_putface.cpp create mode 100644 WDL/plush2/pl_read_3ds.cpp create mode 100644 WDL/plush2/pl_read_cob.cpp create mode 100644 WDL/plush2/pl_read_jaw.cpp create mode 100644 WDL/plush2/pl_spline.cpp create mode 100644 WDL/plush2/plush.h create mode 100644 WDL/plush2/plush2.dsp create mode 100644 WDL/poollist.h create mode 100644 WDL/projectcontext.cpp create mode 100644 WDL/projectcontext.h create mode 100644 WDL/ptrlist.h create mode 100644 WDL/queue.h create mode 100644 WDL/reminder.h create mode 100644 WDL/resample.cpp create mode 100644 WDL/resample.h create mode 100644 WDL/rfb_client.cpp create mode 100644 WDL/rfb_client.h create mode 100644 WDL/rng.cpp create mode 100644 WDL/rng.h create mode 100644 WDL/rpool.h create mode 100644 WDL/sc_bounce/stream-config.php create mode 100644 WDL/sc_bounce/stream.php create mode 100644 WDL/scsrc.cpp create mode 100644 WDL/scsrc.h create mode 100644 WDL/sha.cpp create mode 100644 WDL/sha.h create mode 100644 WDL/sharedpool.h create mode 100644 WDL/shm_connection.cpp create mode 100644 WDL/shm_connection.h create mode 100644 WDL/shm_msgreply.cpp create mode 100644 WDL/shm_msgreply.h create mode 100644 WDL/simple_pitchshift.h create mode 100644 WDL/simple_pitchshift2.h create mode 100644 WDL/sinewavegen.h create mode 100644 WDL/stringpool.h create mode 100644 WDL/swell/Makefile.libSwell create mode 100644 WDL/swell/commctrl.h create mode 100755 WDL/swell/mac_resgen.php create mode 100644 WDL/swell/make-libSwells.sh create mode 100644 WDL/swell/sample_project/English.lproj/InfoPlist.strings create mode 100644 WDL/swell/sample_project/English.lproj/MainMenu.xib create mode 100644 WDL/swell/sample_project/Info.plist create mode 100644 WDL/swell/sample_project/app_main.cpp create mode 100644 WDL/swell/sample_project/main.h create mode 100644 WDL/swell/sample_project/main.m create mode 100644 WDL/swell/sample_project/main_dialog.cpp create mode 100644 WDL/swell/sample_project/resource.h create mode 100644 WDL/swell/sample_project/sample_project.dsp create mode 100644 WDL/swell/sample_project/sample_project.dsw create mode 100644 WDL/swell/sample_project/sample_project.rc create mode 100644 WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns create mode 100644 WDL/swell/sample_project/sample_project.xcodeproj/project.pbxproj create mode 100644 WDL/swell/sample_project/sample_project_Prefix.pch create mode 100644 WDL/swell/sample_project/version.plist create mode 100644 WDL/swell/shlobj.h create mode 100644 WDL/swell/swell-appstub-generic.cpp create mode 100644 WDL/swell/swell-appstub.mm create mode 100644 WDL/swell/swell-dlg-generic.cpp create mode 100644 WDL/swell/swell-dlg.mm create mode 100644 WDL/swell/swell-dlggen.h create mode 100644 WDL/swell/swell-functions.h create mode 100644 WDL/swell/swell-gdi-generic.cpp create mode 100644 WDL/swell/swell-gdi-internalpool.h create mode 100644 WDL/swell/swell-gdi-lice.cpp create mode 100644 WDL/swell/swell-gdi.mm create mode 100644 WDL/swell/swell-ini.cpp create mode 100644 WDL/swell/swell-internal.h create mode 100644 WDL/swell/swell-kb-generic.cpp create mode 100644 WDL/swell/swell-kb.mm create mode 100644 WDL/swell/swell-menu-generic.cpp create mode 100644 WDL/swell/swell-menu.mm create mode 100644 WDL/swell/swell-menugen.h create mode 100644 WDL/swell/swell-misc-generic.cpp create mode 100644 WDL/swell/swell-misc.mm create mode 100644 WDL/swell/swell-miscdlg-generic.cpp create mode 100644 WDL/swell/swell-miscdlg-gtk.cpp create mode 100644 WDL/swell/swell-miscdlg.mm create mode 100644 WDL/swell/swell-modstub-generic.cpp create mode 100644 WDL/swell/swell-modstub.mm create mode 100644 WDL/swell/swell-types.h create mode 100644 WDL/swell/swell-wnd-generic.cpp create mode 100644 WDL/swell/swell-wnd.mm create mode 100644 WDL/swell/swell.cpp create mode 100644 WDL/swell/swell.h create mode 100644 WDL/swell/swellappmain.h create mode 100644 WDL/swell/swellappmain.mm create mode 100644 WDL/swell/test-gtk.cpp create mode 100644 WDL/swell/test.cpp create mode 100644 WDL/swell/windows.h create mode 100644 WDL/timing.c create mode 100644 WDL/timing.h create mode 100644 WDL/tinyxml/libxml_tinyxml.cpp create mode 100644 WDL/tinyxml/libxml_tinyxml.h create mode 100644 WDL/tinyxml/svgtiny_colors.c create mode 100644 WDL/tinyxml/tinystr.cpp create mode 100644 WDL/tinyxml/tinystr.h create mode 100644 WDL/tinyxml/tinyxml.cpp create mode 100644 WDL/tinyxml/tinyxml.h create mode 100644 WDL/tinyxml/tinyxmlerror.cpp create mode 100644 WDL/tinyxml/tinyxmlparser.cpp create mode 100644 WDL/verbengine.h create mode 100644 WDL/vorbisencdec.h create mode 100644 WDL/wavwrite.h create mode 100644 WDL/wdlcstring.h create mode 100644 WDL/wdlstring.h create mode 100644 WDL/wdltypes.h create mode 100644 WDL/win32_curses/curses.h create mode 100644 WDL/win32_curses/curses_win32.cpp create mode 100644 WDL/win32_curses/test.cpp create mode 100644 WDL/win32_utf8.c create mode 100644 WDL/win32_utf8.h create mode 100644 WDL/win7filedialog.cpp create mode 100644 WDL/win7filedialog.h create mode 100644 WDL/wingui/dlgitemborder.h create mode 100644 WDL/wingui/membitmap.h create mode 100644 WDL/wingui/richeditctrl.h create mode 100644 WDL/wingui/scrollbar/coolscroll.cpp create mode 100644 WDL/wingui/scrollbar/coolscroll.h create mode 100644 WDL/wingui/virtwnd-controls.h create mode 100644 WDL/wingui/virtwnd-iaccessible.cpp create mode 100644 WDL/wingui/virtwnd-iconbutton.cpp create mode 100644 WDL/wingui/virtwnd-listbox.cpp create mode 100644 WDL/wingui/virtwnd-nsaccessibility.mm create mode 100644 WDL/wingui/virtwnd-skin.h create mode 100644 WDL/wingui/virtwnd-slider.cpp create mode 100644 WDL/wingui/virtwnd.cpp create mode 100644 WDL/wingui/virtwnd.h create mode 100644 WDL/wingui/wndsize.cpp create mode 100644 WDL/wingui/wndsize.h create mode 100644 WDL/zlib/adler32.c create mode 100644 WDL/zlib/compress.c create mode 100644 WDL/zlib/crc32.c create mode 100644 WDL/zlib/crc32.h create mode 100644 WDL/zlib/deflate.c create mode 100644 WDL/zlib/deflate.h create mode 100644 WDL/zlib/gzclose.c create mode 100644 WDL/zlib/gzguts.h create mode 100644 WDL/zlib/gzlib.c create mode 100644 WDL/zlib/gzread.c create mode 100644 WDL/zlib/gzwrite.c create mode 100644 WDL/zlib/infback.c create mode 100644 WDL/zlib/inffast.c create mode 100644 WDL/zlib/inffast.h create mode 100644 WDL/zlib/inffixed.h create mode 100644 WDL/zlib/inflate.c create mode 100644 WDL/zlib/inflate.h create mode 100644 WDL/zlib/inftrees.c create mode 100644 WDL/zlib/inftrees.h create mode 100644 WDL/zlib/ioapi.c create mode 100644 WDL/zlib/ioapi.h create mode 100644 WDL/zlib/trees.c create mode 100644 WDL/zlib/trees.h create mode 100644 WDL/zlib/uncompr.c create mode 100644 WDL/zlib/unzip.c create mode 100644 WDL/zlib/unzip.h create mode 100644 WDL/zlib/zconf.h create mode 100644 WDL/zlib/zconf.in.h create mode 100644 WDL/zlib/zip.c create mode 100644 WDL/zlib/zip.h create mode 100644 WDL/zlib/zlib.h create mode 100644 WDL/zlib/zutil.c create mode 100644 WDL/zlib/zutil.h rename {English.lproj => licecap/English.lproj}/InfoPlist.strings (100%) rename {English.lproj => licecap/English.lproj}/MainMenu.xib (100%) rename background.png => licecap/background.png (100%) rename capturewindow.mm => licecap/capturewindow.mm (100%) rename icon1.ico => licecap/icon1.ico (100%) rename installer.nsi => licecap/installer.nsi (100%) rename licecap-Info.plist => licecap/licecap-Info.plist (100%) rename licecap.dsw => licecap/licecap.dsw (100%) rename licecap.icns => licecap/licecap.icns (100%) rename licecap.rc => licecap/licecap.rc (100%) rename {licecap.xcodeproj => licecap/licecap.xcodeproj}/project.pbxproj (100%) rename licecap_Prefix.pch => licecap/licecap_Prefix.pch (100%) rename licecap_cli.cpp => licecap/licecap_cli.cpp (100%) rename licecap_cli.dsp => licecap/licecap_cli.dsp (100%) rename licecap_gui.dsp => licecap/licecap_gui.dsp (100%) rename licecap_ui.cpp => licecap/licecap_ui.cpp (100%) rename licecap_version.h => licecap/licecap_version.h (100%) rename license.txt => licecap/license.txt (100%) rename main.m => licecap/main.m (100%) rename makedmg.sh => licecap/makedmg.sh (100%) rename pkg-dmg => licecap/pkg-dmg (100%) rename requires_wdl.txt => licecap/requires_wdl.txt (100%) rename resource.h => licecap/resource.h (100%) rename stage_DS_Store => licecap/stage_DS_Store (100%) rename whatsnew.txt => licecap/whatsnew.txt (100%) diff --git a/WDL/IPlug/Containers.h b/WDL/IPlug/Containers.h new file mode 100644 index 00000000..f8da2cb6 --- /dev/null +++ b/WDL/IPlug/Containers.h @@ -0,0 +1,173 @@ +#ifndef _CONTAINERS_ +#define _CONTAINERS_ + +#ifdef WIN32 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#undef WINVER +#define WINVER 0x0501 +#pragma warning(disable:4018 4267) // size_t/signed/unsigned mismatch.. +#pragma warning(disable:4800) // if (pointer) ... +#pragma warning(disable:4805) // Compare bool and BOOL. +#endif + +#include +#include +#include +#include +#include "../mutex.h" +#include "../wdlstring.h" +#include "../ptrlist.h" + +#define FREE_NULL(p) {free(p);p=0;} +#define DELETE_NULL(p) {delete(p); p=0;} +#define MIN(x,y) ((x)<(y)?(x):(y)) +#define MAX(x,y) ((x)<(y)?(y):(x)) +#define BOUNDED(x,lo,hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) +#define CSTR_NOT_EMPTY(cStr) ((cStr) && (cStr)[0] != '\0') + +#define MAKE_QUOTE(str) #str +#define MAKE_STR(str) MAKE_QUOTE(str) + +#define PI 3.141592653589793238 +#define AMP_DB 8.685889638065036553 +#define IAMP_DB 0.11512925464970 + +inline double DBToAmp(double dB) +{ + return exp(IAMP_DB * dB); +} + +inline double AmpToDB(double amp) +{ + return AMP_DB * log(fabs(amp)); +} + +#ifndef REMINDER + #if defined WIN32 + // This enables: #pragma REMINDER("change this line!") with click-through from VC++. + #define REMINDER(msg) message(__FILE__ "(" MAKE_STR(__LINE__) "): " msg) + #else if defined __APPLE__ + #define REMINDER(msg) WARNING msg + #endif +#endif + +template inline void SWAP(T& a, T& b) +{ + T tmp = a; a = b; b = tmp; +} + +typedef unsigned char BYTE; +class ByteChunk +{ +public: + + ByteChunk() {} + ~ByteChunk() {} + + template inline int Put(const T* pVal) + { + int n = mBytes.GetSize(); + mBytes.Resize(n + sizeof(T)); + memcpy(mBytes.Get() + n, (BYTE*) pVal, sizeof(T)); + return mBytes.GetSize(); + } + + template inline int Get(T* pVal, int startPos) + { + int endPos = startPos + sizeof(T); + if (startPos >= 0 && endPos <= mBytes.GetSize()) { + memcpy((BYTE*) pVal, mBytes.Get() + startPos, sizeof(T)); + return endPos; + } + return -1; + } + + inline int PutStr(const char* str) + { + int slen = strlen(str); + Put(&slen); + int n = mBytes.GetSize(); + mBytes.Resize(n + slen); + memcpy(mBytes.Get() + n, (BYTE*) str, slen); + return mBytes.GetSize(); + } + + inline int GetStr(WDL_String* pStr, int startPos) + { + int len; + int strStartPos = Get(&len, startPos); + if (strStartPos >= 0) { + int strEndPos = strStartPos + len; + if (strEndPos <= mBytes.GetSize() && len > 0) { + pStr->Set((char*) (mBytes.Get() + strStartPos), len); + } + return strEndPos; + } + return -1; + } + + inline int PutBool(bool b) + { + int n = mBytes.GetSize(); + mBytes.Resize(n + 1); + *(mBytes.Get() + n) = (BYTE) (b ? 1 : 0); + return mBytes.GetSize(); + } + + inline int GetBool(bool* pB, int startPos) + { + int endPos = startPos + 1; + if (startPos >= 0 && endPos <= mBytes.GetSize()) { + BYTE byt = *(mBytes.Get() + startPos); + *pB = (byt); + return endPos; + } + return -1; + } + + inline int PutChunk(ByteChunk* pRHS) + { + int n = mBytes.GetSize(); + int nRHS = pRHS->Size(); + mBytes.Resize(n + nRHS); + memcpy(mBytes.Get() + n, pRHS->GetBytes(), nRHS); + return mBytes.GetSize(); + } + + inline void Clear() + { + mBytes.Resize(0); + } + + inline int Size() + { + return mBytes.GetSize(); + } + + inline int Resize(int newSize) + { + int n = mBytes.GetSize(); + mBytes.Resize(newSize); + if (newSize > n) { + memset(mBytes.Get() + n, 0, (newSize - n)); + } + return n; + } + + inline BYTE* GetBytes() + { + return mBytes.Get(); + } + + inline bool IsEqual(ByteChunk* pRHS) + { + return (pRHS && pRHS->Size() == Size() && !memcmp(pRHS->GetBytes(), GetBytes(), Size())); + } + +private: + + WDL_TypedBuf mBytes; +}; + +#endif diff --git a/WDL/IPlug/Example/IPlugExample.cpp b/WDL/IPlug/Example/IPlugExample.cpp new file mode 100644 index 00000000..6deda431 --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.cpp @@ -0,0 +1,185 @@ +#include "IPlugExample.h" +#include "../IPlug_include_in_plug_src.h" +#include "../IControl.h" +#include "resource.h" +#include + +const int kNumPrograms = 1; + +enum EParams { + kGainL = 0, + kGainR, + kPan, + kChannelSw, + kNumParams +}; + +enum EChannelSwitch { + kDefault = 0, + kReversed, + kAllLeft, + kAllRight, + kOff, + kNumChannelSwitchEnums +}; + +enum ELayout +{ + kW = 400, + kH = 200, + + kSwitch_N = 5, // # of sub-bitmaps. + kMeter_N = 51, // # of sub-bitmaps. + + kFader_Len = 150, + kGainL_X = 80, + kGainL_Y = 20, + kGainR_X = 350, + kGainR_Y = 20, + + kSwitch_X = 20, + kSwitch_Y = 40, + + kPan_X = 225, + kPan_Y = 145, + + kMeterL_X = 135, + kMeterL_Y = 20, + kMeterR_X = 250, + kMeterR_Y = 20 +}; + +PlugExample::PlugExample(IPlugInstanceInfo instanceInfo) +: IPLUG_CTOR(kNumParams, 6, instanceInfo), prevL(0.0), prevR(0.0) +{ + TRACE; + + // Define parameter ranges, display units, labels. + + GetParam(kGainL)->InitDouble("Gain L", 0.0, -44.0, 12.0, 0.1, "dB"); + GetParam(kGainL)->NegateDisplay(); + GetParam(kGainR)->InitDouble("Gain R", 0.0, -44.0, 12.0, 0.1, "dB"); + GetParam(kPan)->InitInt("Pan", 0, -100, 100, "%"); + + // Params can be enums. + + GetParam(kChannelSw)->InitEnum("Channel", kDefault, kNumChannelSwitchEnums); + GetParam(kChannelSw)->SetDisplayText(kDefault, "default"); + GetParam(kChannelSw)->SetDisplayText(kReversed, "reversed"); + GetParam(kChannelSw)->SetDisplayText(kAllLeft, "all L"); + GetParam(kChannelSw)->SetDisplayText(kAllRight, "all R"); + GetParam(kChannelSw)->SetDisplayText(kOff, "mute"); + + MakePreset("preset 1", -5.0, 5.0, 17, kReversed); + MakePreset("preset 2", -15.0, 25.0, 37, kAllRight); + MakeDefaultPreset("-", 4); + + // Instantiate a graphics engine. + + IGraphics* pGraphics = MakeGraphics(this, kW, kH); // MakeGraphics(this, kW, kH); + pGraphics->AttachBackground(BG_ID, BG_FN); + + // Attach controls to the graphics engine. Controls are automatically associated + // with a parameter if you construct the control with a parameter index. + + // Attach a couple of meters, not associated with any parameter, + // which we keep indexes for, so we can push updates from the plugin class. + + IBitmap bitmap = pGraphics->LoadIBitmap(METER_ID, METER_FN, kMeter_N); + mMeterIdx_L = pGraphics->AttachControl(new IBitmapControl(this, kMeterL_X, kMeterL_Y, &bitmap)); + mMeterIdx_R = pGraphics->AttachControl(new IBitmapControl(this, kMeterR_X, kMeterR_Y, &bitmap)); + + // Attach a couple of faders, associated with the parameters GainL and GainR. + + bitmap = pGraphics->LoadIBitmap(FADER_ID, FADER_FN); + pGraphics->AttachControl(new IFaderControl(this, kGainL_X, kGainL_Y, kFader_Len, kGainL, &bitmap, kVertical)); + pGraphics->AttachControl(new IFaderControl(this, kGainR_X, kGainR_Y, kFader_Len, kGainR, &bitmap, kVertical)); + + // Attach a 5-position switch associated with the ChannelSw parameter. + + bitmap = pGraphics->LoadIBitmap(TOGGLE_ID, TOGGLE_FN, kSwitch_N); + pGraphics->AttachControl(new ISwitchControl(this, kSwitch_X, kSwitch_Y, kChannelSw, &bitmap)); + + // Attach a rotating knob associated with the Pan parameter. + + bitmap = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN); + pGraphics->AttachControl(new IKnobRotaterControl(this, kPan_X, kPan_Y, kPan, &bitmap)); + + // See IControl.h for other control types, + // IKnobMultiControl, ITextControl, IBitmapOverlayControl, IFileSelectorControl, IGraphControl, etc. + + // Attach the graphics engine to the plugin. + + AttachGraphics(pGraphics); + + // No cleanup necessary, the graphics engine manages all of its resources and cleans up when closed. +} + +void PlugExample::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames) +{ + // Mutex is already locked for us. + + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + double gain1 = GetParam(kGainL)->DBToAmp(); + double gain2 = GetParam(kGainR)->DBToAmp(); + double pan = 0.01 * GetParam(kPan)->Value(); + EChannelSwitch chanSwitch = (EChannelSwitch) int(GetParam(kChannelSw)->Value()); + double peakL = 0.0, peakR = 0.0; + + for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2) { + + *out1 = *in1 * gain1 * (1.0 - pan); + *out2 = *in2 * gain2 * (1.0 + pan); + + // In an actual plugin you'd switch outside of the sample loop, + // it's very inefficient to switch on every sample like this. + + switch (chanSwitch) { + + case kReversed: + SWAP(*out1, *out2); + break; + + case kAllLeft: + *out1 += *out2; + *out2 = 0.0; + break; + + case kAllRight: + *out2 += *out1; + *out1 = 0.0; + break; + + case kOff: + *out1 = *out2 = 0.0; + break; + + default: + break; + } + + peakL = MAX(peakL, fabs(*out1)); + peakR = MAX(peakR, fabs(*out2)); + } + + const double METER_ATTACK = 0.6, METER_DECAY = 0.1; + double xL = (peakL < prevL ? METER_DECAY : METER_ATTACK); + double xR = (peakR < prevR ? METER_DECAY : METER_ATTACK); + + peakL = peakL * xL + prevL * (1.0 - xL); + peakR = peakR * xR + prevR * (1.0 - xR); + + prevL = peakL; + prevR = peakR; + + if (GetGUI()) { + GetGUI()->SetControlFromPlug(mMeterIdx_L, peakL); + GetGUI()->SetControlFromPlug(mMeterIdx_R, peakR); + } +} + + diff --git a/WDL/IPlug/Example/IPlugExample.exp b/WDL/IPlug/Example/IPlugExample.exp new file mode 100644 index 00000000..77215542 --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.exp @@ -0,0 +1,2 @@ +_PlugExample_Entry +_PlugExample_ViewEntry diff --git a/WDL/IPlug/Example/IPlugExample.h b/WDL/IPlug/Example/IPlugExample.h new file mode 100644 index 00000000..17595840 --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.h @@ -0,0 +1,29 @@ +#ifndef __PLUGEXAMPLE__ +#define __PLUGEXAMPLE__ + +// In the project settings, define either VST_API or AU_API. +#include "../IPlug_include_in_plug_hdr.h" + +class PlugExample : public IPlug +{ +public: + + PlugExample(IPlugInstanceInfo instanceInfo); + ~PlugExample() {} // Nothing to clean up. + + // Implement these if your audio or GUI logic requires doing something + // when params change or when audio processing stops/starts. + void Reset() {} + void OnParamChange(int paramIdx) {} + + void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames); + +private: + + int mMeterIdx_L, mMeterIdx_R; + double prevL, prevR; +}; + +//////////////////////////////////////// + +#endif diff --git a/WDL/IPlug/Example/IPlugExample.rc b/WDL/IPlug/Example/IPlugExample.rc new file mode 100644 index 00000000..472169ca --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.rc @@ -0,0 +1,7 @@ +#include "resource.h" + +TOGGLE_ID PNG TOGGLE_FN +KNOB_ID PNG KNOB_FN +FADER_ID PNG FADER_FN +BG_ID PNG BG_FN +METER_ID PNG METER_FN diff --git a/WDL/IPlug/Example/IPlugExample.vcproj b/WDL/IPlug/Example/IPlugExample.vcproj new file mode 100644 index 00000000..973e432e --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.vcproj @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj b/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..ec3ceb55 --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample.xcodeproj/project.pbxproj @@ -0,0 +1,675 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 44; + objects = { + +/* Begin PBXBuildFile section */ + 45BFA26B1060DF5E00307BE8 /* libIPlug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BFA2581060DDDB00307BE8 /* libIPlug.a */; }; + 45BFA2861060DFDB00307BE8 /* libIPlug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BFA2581060DDDB00307BE8 /* libIPlug.a */; }; + 522988B10D14D52B00B3A00C /* IPlugExample.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */; }; + 523F19130D19AD7600ACA98D /* BG_400x200.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440E0D0E55A200961B48 /* BG_400x200.png */; }; + 523F19140D19AD7A00ACA98D /* fader-cap_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */; }; + 523F19150D19AD7E00ACA98D /* knob_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844100D0E55A200961B48 /* knob_sm.png */; }; + 523F19160D19AD8100ACA98D /* toggle-switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844110D0E55A200961B48 /* toggle-switch.png */; }; + 523F19170D19AD8500ACA98D /* VU-meter_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844120D0E55A200961B48 /* VU-meter_sm.png */; }; + 525FE3870D15C0E900E4C9FB /* IPlugAU.r in Rez */ = {isa = PBXBuildFile; fileRef = 525FE3860D15C0E900E4C9FB /* IPlugAU.r */; }; + 526F9C020D7DC7D700562CF8 /* IPlugExample.exp in Sources */ = {isa = PBXBuildFile; fileRef = 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */; }; + 526F9C030D7DC7D700562CF8 /* IPlugExample.exp in Sources */ = {isa = PBXBuildFile; fileRef = 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */; }; + 52780D5E0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */; }; + 52C4DB190D0E51270007A920 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; }; + 52E41BB70D14C11C00A0943B /* IPlugExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */; }; + 52E41C7A0D14C12800A0943B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; }; + 52E41C7F0D14C12C00A0943B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 52E41DA70D14C2DC00A0943B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D920D14C2D600A0943B /* AudioToolbox.framework */; }; + 52E41DA80D14C2DF00A0943B /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */; }; + 52E41DA90D14C2E400A0943B /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CC40D14C2B000A0943B /* CoreServices.framework */; }; + 52E41DAA0D14C2E700A0943B /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CB90D14C2A900A0943B /* CoreAudio.framework */; }; + 52E844130D0E55A200961B48 /* BG_400x200.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440E0D0E55A200961B48 /* BG_400x200.png */; }; + 52E844140D0E55A200961B48 /* fader-cap_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */; }; + 52E844150D0E55A200961B48 /* knob_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844100D0E55A200961B48 /* knob_sm.png */; }; + 52E844160D0E55A200961B48 /* toggle-switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844110D0E55A200961B48 /* toggle-switch.png */; }; + 52E844170D0E55A200961B48 /* VU-meter_sm.png in Resources */ = {isa = PBXBuildFile; fileRef = 52E844120D0E55A200961B48 /* VU-meter_sm.png */; }; + 52FBBED10D0CF139001C8B8A /* IPlugExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */; }; + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 45BFA2571060DDDB00307BE8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = IPlug; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 522988A80D14D49B00B3A00C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 525C4CEC0D1CD7EE00AB2038 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 32DBCF630370AF2F00C91783 /* IPlugExample_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugExample_Prefix.pch; sourceTree = ""; }; + 525FE3860D15C0E900E4C9FB /* IPlugAU.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = IPlugAU.r; path = ../IPlugAU.r; sourceTree = SOURCE_ROOT; }; + 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = IPlugExample.exp; sourceTree = ""; }; + 5276FBE30D158937006A299A /* IPlug_include_in_plug_hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_hdr.h; path = ../IPlug_include_in_plug_hdr.h; sourceTree = SOURCE_ROOT; }; + 5276FBE40D15893B006A299A /* IPlug_include_in_plug_src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_src.h; path = ../IPlug_include_in_plug_src.h; sourceTree = SOURCE_ROOT; }; + 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IPlugAU_ViewFactory.mm; path = ../IPlugAU_ViewFactory.mm; sourceTree = SOURCE_ROOT; }; + 528A62261159258E00BD5F20 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; + 528A62281159258E00BD5F20 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; + 528A622A1159258E00BD5F20 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 528A622C1159258E00BD5F20 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 52C4DB180D0E51270007A920 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = IPlug.xcodeproj; path = ../IPlug.xcodeproj; sourceTree = SOURCE_ROOT; }; + 52E41BB20D14C0F500A0943B /* IPlugExample.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPlugExample.component; sourceTree = BUILT_PRODUCTS_DIR; }; + 52E41BB30D14C0F500A0943B /* IPlugExampleAU-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "IPlugExampleAU-Info.plist"; sourceTree = ""; }; + 52E41CB90D14C2A900A0943B /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 52E41CC40D14C2B000A0943B /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; + 52E41D920D14C2D600A0943B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; + 52E8440E0D0E55A200961B48 /* BG_400x200.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = BG_400x200.png; sourceTree = ""; }; + 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "fader-cap_sm.png"; sourceTree = ""; }; + 52E844100D0E55A200961B48 /* knob_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = knob_sm.png; sourceTree = ""; }; + 52E844110D0E55A200961B48 /* toggle-switch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "toggle-switch.png"; sourceTree = ""; }; + 52E844120D0E55A200961B48 /* VU-meter_sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "VU-meter_sm.png"; sourceTree = ""; }; + 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugExample.cpp; sourceTree = ""; }; + 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugExample.h; sourceTree = ""; }; + 52FBBED30D0CF143001C8B8A /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = ""; }; + 8D5B49B6048680CD000E48DA /* IPlugExample.vst */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IPlugExample.vst; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 52E41BB00D14C0F500A0943B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 52E41C7A0D14C12800A0943B /* Carbon.framework in Frameworks */, + 52E41C7F0D14C12C00A0943B /* Cocoa.framework in Frameworks */, + 52E41DA70D14C2DC00A0943B /* AudioToolbox.framework in Frameworks */, + 52E41DA80D14C2DF00A0943B /* AudioUnit.framework in Frameworks */, + 52E41DA90D14C2E400A0943B /* CoreServices.framework in Frameworks */, + 52E41DAA0D14C2E700A0943B /* CoreAudio.framework in Frameworks */, + 45BFA2861060DFDB00307BE8 /* libIPlug.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D5B49B3048680CD000E48DA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, + 52C4DB190D0E51270007A920 /* Carbon.framework in Frameworks */, + 45BFA26B1060DF5E00307BE8 /* libIPlug.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* IPlugExample */ = { + isa = PBXGroup; + children = ( + 526F9C010D7DC7D700562CF8 /* IPlugExample.exp */, + 52780D5D0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm */, + 525FE3860D15C0E900E4C9FB /* IPlugAU.r */, + 5276FBE40D15893B006A299A /* IPlug_include_in_plug_src.h */, + 5276FBE30D158937006A299A /* IPlug_include_in_plug_hdr.h */, + 52FBBED30D0CF143001C8B8A /* resource.h */, + 52FBBED20D0CF13D001C8B8A /* IPlugExample.h */, + 52FBBED00D0CF139001C8B8A /* IPlugExample.cpp */, + 08FB77AFFE84173DC02AAC07 /* Classes */, + 32C88E010371C26100C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + name = IPlugExample; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 52E8440D0D0E55A200961B48 /* img */, + 8D5B49B7048680CD000E48DA /* Info.plist */, + 52E41BB30D14C0F500A0943B /* IPlugExampleAU-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */, + 52E41D920D14C2D600A0943B /* AudioToolbox.framework */, + 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */, + 52E41CC40D14C2B000A0943B /* CoreServices.framework */, + 52E41CB90D14C2A900A0943B /* CoreAudio.framework */, + 52C4DB180D0E51270007A920 /* Carbon.framework */, + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + 528A62261159258E00BD5F20 /* AudioUnit.framework */, + 528A62281159258E00BD5F20 /* Carbon.framework */, + 528A622A1159258E00BD5F20 /* Cocoa.framework */, + 528A622C1159258E00BD5F20 /* CoreAudio.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 089C167FFE841241C02AAC07 /* AppKit.framework */, + D2F7E65807B2D6F200F64583 /* CoreData.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D5B49B6048680CD000E48DA /* IPlugExample.vst */, + 52E41BB20D14C0F500A0943B /* IPlugExample.component */, + ); + name = Products; + sourceTree = ""; + }; + 32C88E010371C26100C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF630370AF2F00C91783 /* IPlugExample_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 45BFA2541060DDDB00307BE8 /* Products */ = { + isa = PBXGroup; + children = ( + 45BFA2581060DDDB00307BE8 /* libIPlug.a */, + ); + name = Products; + sourceTree = ""; + }; + 52E8440D0D0E55A200961B48 /* img */ = { + isa = PBXGroup; + children = ( + 52E8440E0D0E55A200961B48 /* BG_400x200.png */, + 52E8440F0D0E55A200961B48 /* fader-cap_sm.png */, + 52E844100D0E55A200961B48 /* knob_sm.png */, + 52E844110D0E55A200961B48 /* toggle-switch.png */, + 52E844120D0E55A200961B48 /* VU-meter_sm.png */, + ); + path = img; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 522988B40D14D54000B3A00C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 522988B10D14D52B00B3A00C /* IPlugExample.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 52E41BB10D14C0F500A0943B /* IPlugExampleAU */ = { + isa = PBXNativeTarget; + buildConfigurationList = 52E41BB60D14C0F500A0943B /* Build configuration list for PBXNativeTarget "IPlugExampleAU" */; + buildPhases = ( + 522988B40D14D54000B3A00C /* Headers */, + 52E41BAE0D14C0F500A0943B /* Resources */, + 52E41BAF0D14C0F500A0943B /* Sources */, + 52E41BB00D14C0F500A0943B /* Frameworks */, + 5229883B0D14CE8600B3A00C /* Rez */, + 522988A80D14D49B00B3A00C /* CopyFiles */, + 525C4CEC0D1CD7EE00AB2038 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IPlugExampleAU; + productName = IPlugExampleAU; + productReference = 52E41BB20D14C0F500A0943B /* IPlugExample.component */; + productType = "com.apple.product-type.bundle"; + }; + 8D5B49AC048680CD000E48DA /* IPlugExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "IPlugExample" */; + buildPhases = ( + 8D5B49AF048680CD000E48DA /* Resources */, + 8D5B49B1048680CD000E48DA /* Sources */, + 8D5B49B3048680CD000E48DA /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IPlugExample; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = IPlugExample; + productReference = 8D5B49B6048680CD000E48DA /* IPlugExample.vst */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "IPlugExample" */; + compatibilityVersion = "Xcode 3.0"; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* IPlugExample */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 45BFA2541060DDDB00307BE8 /* Products */; + ProjectRef = 52DC4B560D29B54E00DD0B91 /* IPlug.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 8D5B49AC048680CD000E48DA /* IPlugExample */, + 52E41BB10D14C0F500A0943B /* IPlugExampleAU */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 45BFA2581060DDDB00307BE8 /* libIPlug.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libIPlug.a; + remoteRef = 45BFA2571060DDDB00307BE8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 52E41BAE0D14C0F500A0943B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 523F19130D19AD7600ACA98D /* BG_400x200.png in Resources */, + 523F19140D19AD7A00ACA98D /* fader-cap_sm.png in Resources */, + 523F19150D19AD7E00ACA98D /* knob_sm.png in Resources */, + 523F19160D19AD8100ACA98D /* toggle-switch.png in Resources */, + 523F19170D19AD8500ACA98D /* VU-meter_sm.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D5B49AF048680CD000E48DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52E844130D0E55A200961B48 /* BG_400x200.png in Resources */, + 52E844140D0E55A200961B48 /* fader-cap_sm.png in Resources */, + 52E844150D0E55A200961B48 /* knob_sm.png in Resources */, + 52E844160D0E55A200961B48 /* toggle-switch.png in Resources */, + 52E844170D0E55A200961B48 /* VU-meter_sm.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 5229883B0D14CE8600B3A00C /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + 525FE3870D15C0E900E4C9FB /* IPlugAU.r in Rez */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 52E41BAF0D14C0F500A0943B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52E41BB70D14C11C00A0943B /* IPlugExample.cpp in Sources */, + 52780D5E0D20A3FC00C2BCA7 /* IPlugAU_ViewFactory.mm in Sources */, + 526F9C020D7DC7D700562CF8 /* IPlugExample.exp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D5B49B1048680CD000E48DA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52FBBED10D0CF139001C8B8A /* IPlugExample.cpp in Sources */, + 526F9C030D7DC7D700562CF8 /* IPlugExample.exp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB913B08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = VST_API; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../IPlug/build/Debug\"", + ); + PRODUCT_NAME = IPlugExample; + WRAPPER_EXTENSION = vst; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DEB913C08733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = VST_API; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../IPlug/build/Debug\"", + ); + PRODUCT_NAME = IPlugExample; + WRAPPER_EXTENSION = vst; + }; + name = Release; + }; + 1DEB913F08733D840010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_EXTENSION = ""; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + HEADER_SEARCH_PATHS = ( + ., + ../IPlug, + ); + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_PREPROCESS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + WRAPPER_EXTENSION = ""; + }; + name = Debug; + }; + 1DEB914008733D840010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + EXECUTABLE_EXTENSION = ""; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + HEADER_SEARCH_PATHS = ( + ., + ../IPlug, + ); + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_PREPROCESS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + WRAPPER_EXTENSION = ""; + }; + name = Release; + }; + 528359A90D7F0C3A00577159 /* Tracer */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + EXECUTABLE_EXTENSION = ""; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + HEADER_SEARCH_PATHS = ( + ., + ../IPlug, + ); + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_PREPROCESS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + WRAPPER_EXTENSION = ""; + }; + name = Tracer; + }; + 528359AA0D7F0C3A00577159 /* Tracer */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlugExample_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = VST_API; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../IPlug/build/Debug\"", + ); + PRODUCT_NAME = IPlugExample; + WRAPPER_EXTENSION = vst; + }; + name = Tracer; + }; + 528359AB0D7F0C3A00577159 /* Tracer */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXPORTED_SYMBOLS_FILE = IPlugExample.exp; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G4; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + TRACER_BUILD, + AU_API, + ); + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; + INFOPLIST_PREPROCESS = YES; + INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; + LIBRARY_SEARCH_PATHS = ( + ../IPlug/Build/Tracer, + "\"$(SRCROOT)/../Crypto/build/Release\"", + ); + LIBRARY_STYLE = Bundle; + OTHER_LDFLAGS = "-bundle"; + OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; + PREBINDING = YES; + PRODUCT_NAME = IPlugExample; + REZ_SEARCH_PATHS = ( + /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, + /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, + ); + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; + WRAPPER_EXTENSION = component; + ZERO_LINK = NO; + }; + name = Tracer; + }; + 52E41BB40D14C0F500A0943B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + EXPORTED_SYMBOLS_FILE = IPlugExample.exp; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = AU_API; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; + INFOPLIST_PREPROCESS = YES; + INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; + LIBRARY_SEARCH_PATHS = ( + "\"$(SRCROOT)/../IPlug/build/Debug\"", + "\"$(SRCROOT)/../Crypto/build/Release\"", + ); + LIBRARY_STYLE = Bundle; + OTHER_LDFLAGS = "-bundle"; + OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; + PREBINDING = YES; + PRODUCT_NAME = IPlugExample; + REZ_SEARCH_PATHS = ( + /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, + /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, + ); + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; + WRAPPER_EXTENSION = component; + ZERO_LINK = NO; + }; + name = Debug; + }; + 52E41BB50D14C0F500A0943B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXPORTED_SYMBOLS_FILE = IPlugExample.exp; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G4; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_PREPROCESSOR_DEFINITIONS = AU_API; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + INFOPLIST_FILE = "IPlugExampleAU-Info.plist"; + INFOPLIST_PREPROCESS = YES; + INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; + LIBRARY_SEARCH_PATHS = ( + ../IPlug/Build/Release, + "\"$(SRCROOT)/../Crypto/build/Release\"", + ); + LIBRARY_STYLE = Bundle; + OTHER_LDFLAGS = "-bundle"; + OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase"; + PREBINDING = YES; + PRODUCT_NAME = IPlugExample; + REZ_SEARCH_PATHS = ( + /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers, + /Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase, + ); + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; + WRAPPER_EXTENSION = component; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "IPlugExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913B08733D840010E9CD /* Debug */, + 1DEB913C08733D840010E9CD /* Release */, + 528359AA0D7F0C3A00577159 /* Tracer */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "IPlugExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB913F08733D840010E9CD /* Debug */, + 1DEB914008733D840010E9CD /* Release */, + 528359A90D7F0C3A00577159 /* Tracer */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 52E41BB60D14C0F500A0943B /* Build configuration list for PBXNativeTarget "IPlugExampleAU" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 52E41BB40D14C0F500A0943B /* Debug */, + 52E41BB50D14C0F500A0943B /* Release */, + 528359AB0D7F0C3A00577159 /* Tracer */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/WDL/IPlug/Example/IPlugExampleAU-Info.plist b/WDL/IPlug/Example/IPlugExampleAU-Info.plist new file mode 100644 index 00000000..6f397ec4 --- /dev/null +++ b/WDL/IPlug/Example/IPlugExampleAU-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.Schwa.audiounit.IPlugExample + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + PlugExample_View + + diff --git a/WDL/IPlug/Example/IPlugExample_Prefix.pch b/WDL/IPlug/Example/IPlugExample_Prefix.pch new file mode 100644 index 00000000..4d9bfcab --- /dev/null +++ b/WDL/IPlug/Example/IPlugExample_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'IPlugExample' target in the 'IPlugExample' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/WDL/IPlug/Example/Info.plist b/WDL/IPlug/Example/Info.plist new file mode 100644 index 00000000..c9e1c5a2 --- /dev/null +++ b/WDL/IPlug/Example/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.Schwa.vst.IPlugExample + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + + + diff --git a/WDL/IPlug/Example/README.txt b/WDL/IPlug/Example/README.txt new file mode 100644 index 00000000..3a49dbaa --- /dev/null +++ b/WDL/IPlug/Example/README.txt @@ -0,0 +1,4 @@ +IPlug version 20070607 + +The image files in this package were created by White Tie. You may not use these images as part of any product that is offered for sale. + diff --git a/WDL/IPlug/Example/img/BG_400x200.png b/WDL/IPlug/Example/img/BG_400x200.png new file mode 100644 index 0000000000000000000000000000000000000000..43f57061bcedf7e9f9b51a8d32ee8a467bfa5076 GIT binary patch literal 1856 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpWt8ulAh%XTY(f~age(c!@6@aFM%AEbVpxD z28NCO+hglc$SgNJZS+>y5k(1_I0*H&wc`AG0_*SD`3Q(B}KS$AStD3W^_ir@1#U zG`1Y@Tp}`wfsyI|dj(b|7LE`Wp0K5wmYf0~TA#9U2)y9J69Y#H zP=2|#C+8V%i8Vik85|ZUCv32a_4G=JJCJa8J_7@jEMxQ4mtH|kpPAUQ|FJLtO^{gQ z7d}a7hPXk*XLW`K2loRBrMo6gIk2bU;4FJa1{NzOw$+!XE@64b%5&`xCxgNTL4%07 z>r_+?^b}xnU>V(ly7)=YKIbyV27#gKxT&Y6Kg$+w8R{^Un22WQ%mvv4F FO#oXOk*fdz literal 0 HcmV?d00001 diff --git a/WDL/IPlug/Example/img/VU-meter_sm.png b/WDL/IPlug/Example/img/VU-meter_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..1e81c73b7b10be853a5aa3fb415ef982e85ce666 GIT binary patch literal 743112 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 z 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
f41med&6h|{tpLY!n>_VGnX2Enk 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 z

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

h>eY)cF&iOX&L{&LDm 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

esb39kJk66?6D}Ef?EiB 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 literal 0 HcmV?d00001 diff --git a/WDL/IPlug/Example/img/toggle-switch.png b/WDL/IPlug/Example/img/toggle-switch.png new file mode 100644 index 0000000000000000000000000000000000000000..7a94d82f24686b28cd6355e64f913e31147ff486 GIT binary patch literal 18625 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 +#include "Log.h" + +EHost LookUpHost(const char* inHost) +{ + char host[256]; + ToLower(host, inHost); + + // C4 is version >= 8.2 + if (strstr(host, "cubase")) { + return kHostCubase; + } + if (strstr(host, "reaper")) { + return kHostReaper; + } + if (strstr(host, "nuendo")) { + return kHostNuendo; + } + if (strstr(host, "cakewalk")) { + return kHostSonar; + } + if (strstr(host, "samplitude")) { + return kHostSamplitude; + } + if (strstr(host, "fruity")) { + return kHostFL; + } + if (strstr(host, "live")) { + return kHostAbletonLive; + } + if (strstr(host, "melodyne")) { + return kHostMelodyneStudio; + } + if (strstr(host, "vstmanlib")) { + return kHostVSTScanner; + } + if (strstr(host, "aulab")) { + return kHostAULab; + } + if (strstr(host, "forte")) { + return kHostForte; + } + if (strstr(host, "chainer")) { + return kHostChainer; + } + if (strstr(host, "audition")) { + return kHostAudition; + } + if (strstr(host, "orion")) { + return kHostOrion; + } + if (strstr(host, "sawstudio")) { + return kHostSAWStudio; + } + if (strstr(host, "logic")) { + return kHostLogic; + } + if (strstr(host, "digital")) { + return kHostDigitalPerformer; + } + return kHostUnknown; +} \ No newline at end of file diff --git a/WDL/IPlug/Hosts.h b/WDL/IPlug/Hosts.h new file mode 100644 index 00000000..c9210f78 --- /dev/null +++ b/WDL/IPlug/Hosts.h @@ -0,0 +1,43 @@ +#ifndef _PLUGINHOSTS_ +#define _PLUGINHOSTS_ + +#include +#include + +enum EHost { + kHostUninit = -1, + kHostUnknown = 0, + kHostReaper, + kHostProTools, + kHostCubase, + kHostNuendo, + kHostSonar, + kHostVegas, + kHostFL, + kHostSamplitude, + kHostAbletonLive, + kHostTracktion, + kHostNTracks, + kHostMelodyneStudio, + kHostVSTScanner, + kHostAULab, + kHostForte, + kHostChainer, + kHostAudition, + kHostOrion, + kHostBias, + kHostSAWStudio, + kHostLogic, + kHostDigitalPerformer, + + // These hosts don't report the host name: + // EnergyXT2 + // MiniHost +}; + +EHost LookUpHost(const char* host); + +#endif + + + \ No newline at end of file diff --git a/WDL/IPlug/IControl.cpp b/WDL/IPlug/IControl.cpp new file mode 100644 index 00000000..35cdf4d7 --- /dev/null +++ b/WDL/IPlug/IControl.cpp @@ -0,0 +1,449 @@ +#include "IControl.h" +#include "math.h" +#include "Log.h" + +const float GRAYED_ALPHA = 0.25f; + +void IControl::SetValueFromPlug(double value) +{ + if (mDefaultValue < 0.0) { + mDefaultValue = mValue = value; + SetDirty(false); + Redraw(); + } + else + if (mValue != value) { + mValue = value; + SetDirty(false); + Redraw(); + } +} + +void IControl::SetValueFromUserInput(double value) +{ + if (mValue != value) { + mValue = value; + SetDirty(); + Redraw(); + } +} + +void IControl::SetDirty(bool pushParamToPlug) +{ + mValue = BOUNDED(mValue, mClampLo, mClampHi); + mDirty = true; + if (pushParamToPlug && mPlug && mParamIdx >= 0) { + mPlug->SetParameterFromGUI(mParamIdx, mValue); + } +} + +void IControl::SetClean() +{ + mDirty = mRedraw; + mRedraw = false; +} + +void IControl::Hide(bool hide) +{ + mHide = hide; + mRedraw = true; + SetDirty(false); +} + +void IControl::GrayOut(bool gray) +{ + mGrayed = gray; + mBlend.mWeight = (gray ? GRAYED_ALPHA : 1.0f); + SetDirty(false); +} + +void IControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (pMod->R) { + PromptUserInput(); + } +} + +void IControl::OnMouseDblClick(int x, int y, IMouseMod* pMod) +{ + if (mDefaultValue >= 0.0) { + mValue = mDefaultValue; + SetDirty(); + } +} + +void IControl::OnMouseWheel(int x, int y, IMouseMod* pMod, int d) +{ + if (pMod->C || pMod->S) { + mValue += 0.001 * d; + } + else { + mValue += 0.01 * d; + } + SetDirty(); +} + +void IControl::PromptUserInput() +{ + if (mParamIdx >= 0 && !mDisablePrompt) { + mPlug->GetGUI()->PromptUserInput(this, mPlug->GetParam(mParamIdx)); + Redraw(); + } +} + +bool IBitmapControl::Draw(IGraphics* pGraphics) +{ + int i = 1; + if (mBitmap.N > 1) { + i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1)); + i = BOUNDED(i, 1, mBitmap.N); + } + return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend); +} + +void ISwitchControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (pMod->R) { + PromptUserInput(); + } + else + if (mBitmap.N > 1) { + mValue += 1.0 / (double) (mBitmap.N - 1); + } + else { + mValue += 1.0; + } + if (mValue > 1.001) { + mValue = 0.0; + } + SetDirty(); +} + +IInvisibleSwitchControl::IInvisibleSwitchControl(IPlugBase* pPlug, IRECT* pR, int paramIdx) +: IControl(pPlug, pR, paramIdx, IChannelBlend::kBlendClobber) +{ + mDisablePrompt = true; +} + +void IInvisibleSwitchControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (mValue < 0.5) { + mValue = 1.0; + } + else { + mValue = 0.0; + } + SetDirty(); +} + +IRadioButtonsControl::IRadioButtonsControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, int nButtons, + IBitmap* pBitmap, EDirection direction) +: IControl(pPlug, pR, paramIdx), mBitmap(*pBitmap) +{ + mRECTs.Resize(nButtons); + int x = mRECT.L, y = mRECT.T, h = int((double) pBitmap->H / (double) pBitmap->N); + if (direction == kHorizontal) { + int dX = int((double) (pR->W() - nButtons * pBitmap->W) / (double) (nButtons - 1)); + for (int i = 0; i < nButtons; ++i) { + mRECTs.Get()[i] = IRECT(x, y, x + pBitmap->W, y + h); + x += pBitmap->W + dX; + } + } + else { + int dY = int((double) (pR->H() - nButtons * h) / (double) (nButtons - 1)); + for (int i = 0; i < nButtons; ++i) { + mRECTs.Get()[i] = IRECT(x, y, x + pBitmap->W, y + h); + y += h + dY; + } + } +} + +void IRadioButtonsControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (pMod->R) { + PromptUserInput(); + return; + } + int i, n = mRECTs.GetSize(); + for (i = 0; i < n; ++i) { + if (mRECTs.Get()[i].Contains(x, y)) { + mValue = (double) i / (double) (n - 1); + break; + } + } + SetDirty(); +} + +bool IRadioButtonsControl::Draw(IGraphics* pGraphics) +{ + int i, n = mRECTs.GetSize(); + int active = int(0.5 + mValue * (double) (n - 1)); + active = BOUNDED(active, 0, n - 1); + for (i = 0; i < n; ++i) { + if (i == active) { + pGraphics->DrawBitmap(&mBitmap, &mRECTs.Get()[i], 2, &mBlend); + } + else { + pGraphics->DrawBitmap(&mBitmap, &mRECTs.Get()[i], 1, &mBlend); + } + } + return true; +} + +void IContactControl::OnMouseUp(int x, int y, IMouseMod* pMod) +{ + mValue = 0.0; + SetDirty(); +} + +IFaderControl::IFaderControl(IPlugBase* pPlug, int x, int y, int len, int paramIdx, IBitmap* pBitmap, EDirection direction) +: IControl(pPlug, &IRECT(), paramIdx), mLen(len), mBitmap(*pBitmap), mDirection(direction) +{ + if (direction == kVertical) { + mHandleHeadroom = mBitmap.H; + mRECT = mTargetRECT = IRECT(x, y, x + mBitmap.W, y + len); + } + else { + mHandleHeadroom = mBitmap.W; + mRECT = mTargetRECT = IRECT(x, y, x + len, y + mBitmap.H); + } +} + +IRECT IFaderControl::GetHandleRECT(double value) const +{ + if (value < 0.0) { + value = mValue; + } + IRECT r(mRECT.L, mRECT.T, mRECT.L + mBitmap.W, mRECT.T + mBitmap.H); + if (mDirection == kVertical) { + int offs = int((1.0 - value) * (double) (mLen - mHandleHeadroom)); + r.T += offs; + r.B += offs; + } + else { + int offs = int(value * (double) (mLen - mHandleHeadroom)); + r.L += offs; + r.R += offs; + } + return r; +} + +void IFaderControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (pMod->R) { + PromptUserInput(); + return; + } + + return SnapToMouse(x, y); +} + +void IFaderControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) +{ + return SnapToMouse(x, y); +} + +void IFaderControl::SnapToMouse(int x, int y) +{ + if (mDirection == kVertical) { + mValue = 1.0 - (double) (y - mRECT.T - mHandleHeadroom / 2) / (double) (mLen - mHandleHeadroom); + } + else { + mValue = (double) (x - mRECT.L - mHandleHeadroom / 2) / (double) (mLen - mHandleHeadroom); + } + SetDirty(); +} + +bool IFaderControl::Draw(IGraphics* pGraphics) +{ + IRECT r = GetHandleRECT(); + return pGraphics->DrawBitmap(&mBitmap, &r, 1, &mBlend); +} + +void IKnobControl::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) +{ + double gearing = mGearing; + if (pMod->C || pMod->S) gearing *= 10.0; + + if (mDirection == kVertical) + { + mValue += (double) dY / (double) (mRECT.T - mRECT.B) / gearing; + } + else + { + mValue += (double) dX / (double) (mRECT.R - mRECT.L) / gearing; + } + + SetDirty(); +} + +IKnobLineControl::IKnobLineControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, + const IColor* pColor, double innerRadius, double outerRadius, + double minAngle, double maxAngle, EDirection direction, double gearing) +: IKnobControl(pPlug, pR, paramIdx, direction, gearing), + mColor(*pColor) +{ + mMinAngle = (float) minAngle; + mMaxAngle = (float) maxAngle; + mInnerRadius = (float) innerRadius; + mOuterRadius = (float) outerRadius; + if (mOuterRadius == 0.0f) { + mOuterRadius = 0.5f * (float) pR->W(); + } + mBlend = IChannelBlend(IChannelBlend::kBlendClobber); +} + +bool IKnobLineControl::Draw(IGraphics* pGraphics) +{ + double v = mMinAngle + mValue * (mMaxAngle - mMinAngle); + float sinV = (float) sin(v); + float cosV = (float) cos(v); + float cx = mRECT.MW(), cy = mRECT.MH(); + float x1 = cx + mInnerRadius * sinV, y1 = cy - mInnerRadius * cosV; + float x2 = cx + mOuterRadius * sinV, y2 = cy - mOuterRadius * cosV; + return pGraphics->DrawLine(&mColor, x1, y1, x2, y2, &mBlend, true); +} + +bool IKnobRotaterControl::Draw(IGraphics* pGraphics) +{ + int cX = (mRECT.L + mRECT.R) / 2; + int cY = (mRECT.T + mRECT.B) / 2; + double angle = mMinAngle + mValue * (mMaxAngle - mMinAngle); + return pGraphics->DrawRotatedBitmap(&mBitmap, cX, cY, angle, mYOffset, &mBlend); +} + +// Same as IBitmapControl::Draw. +bool IKnobMultiControl::Draw(IGraphics* pGraphics) +{ + int i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1)); + i = BOUNDED(i, 1, mBitmap.N); + return pGraphics->DrawBitmap(&mBitmap, &mRECT, i, &mBlend); +} + +bool IKnobRotatingMaskControl::Draw(IGraphics* pGraphics) +{ + double angle = mMinAngle + mValue * (mMaxAngle - mMinAngle); + return pGraphics->DrawRotatedMask(&mBase, &mMask, &mTop, mRECT.L, mRECT.T, angle, &mBlend); +} + +bool IBitmapOverlayControl::Draw(IGraphics* pGraphics) +{ + if (mValue < 0.5) { + mTargetRECT = mTargetArea; + return true; // Don't draw anything. + } + else { + mTargetRECT = mRECT; + return IBitmapControl::Draw(pGraphics); + } +} + +void ITextControl::SetTextFromPlug(char* str) +{ + if (strcmp(mStr.Get(), str)) { + SetDirty(false); + mStr.Set(str); + } +} + +bool ITextControl::Draw(IGraphics* pGraphics) +{ + char* cStr = mStr.Get(); + if (CSTR_NOT_EMPTY(cStr)) { + return pGraphics->DrawIText(&mText, cStr, &mRECT); + } + return true; +} + +ICaptionControl::ICaptionControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IText* pText, bool showParamLabel) +: ITextControl(pPlug, pR, pText), mShowParamLabel(showParamLabel) +{ + mParamIdx = paramIdx; +} + +bool ICaptionControl::Draw(IGraphics* pGraphics) +{ + IParam* pParam = mPlug->GetParam(mParamIdx); + char cStr[32]; + pParam->GetDisplayForHost(cStr); + mStr.Set(cStr); + if (mShowParamLabel) { + mStr.Append(" "); + mStr.Append(pParam->GetLabelForHost()); + } + return ITextControl::Draw(pGraphics); +} + +IURLControl::IURLControl(IPlugBase* pPlug, IRECT* pR, const char* url, const char* backupURL, const char* errMsgOnFailure) +: IControl(pPlug, pR) +{ + memset(mURL, 0, MAX_URL_LEN); + memset(mBackupURL, 0, MAX_URL_LEN); + memset(mErrMsg, 0, MAX_NET_ERR_MSG_LEN); + if (CSTR_NOT_EMPTY(url)) { + strcpy(mURL, url); + } + if (CSTR_NOT_EMPTY(backupURL)) { + strcpy(mBackupURL, backupURL); + } + if (CSTR_NOT_EMPTY(errMsgOnFailure)) { + strcpy(mErrMsg, errMsgOnFailure); + } +} + +void IURLControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + bool opened = false; + if (CSTR_NOT_EMPTY(mURL)) { + opened = mPlug->GetGUI()->OpenURL(mURL, mErrMsg); + } + if (!opened && CSTR_NOT_EMPTY(mBackupURL)) { + opened = mPlug->GetGUI()->OpenURL(mBackupURL, mErrMsg); + } +} + +void IFileSelectorControl::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + if (mPlug && mPlug->GetGUI()) { + mState = kFSSelecting; + SetDirty(false); + + mPlug->GetGUI()->PromptForFile(&mFile, mFileAction, mDir.Get(), mExtensions.Get()); + mValue += 1.0; + if (mValue > 1.0) { + mValue = 0.0; + } + mState = kFSDone; + SetDirty(); + } +} + +bool IFileSelectorControl::Draw(IGraphics* pGraphics) +{ + if (mState == kFSSelecting) { + pGraphics->DrawBitmap(&mBitmap, &mRECT, 0, 0); + } + return true; +} + +void IFileSelectorControl::GetLastSelectedFileForPlug(WDL_String* pStr) +{ + pStr->Set(mFile.Get()); +} + +void IFileSelectorControl::SetLastSelectedFileFromPlug(char* file) +{ + mFile.Set(file); +} + +bool IFileSelectorControl::IsDirty() +{ + if (mDirty) { + return true; + } + if (mState == kFSDone) { + mState = kFSNone; + return true; + } + return false; +} diff --git a/WDL/IPlug/IControl.h b/WDL/IPlug/IControl.h new file mode 100644 index 00000000..ef7350a0 --- /dev/null +++ b/WDL/IPlug/IControl.h @@ -0,0 +1,402 @@ +#ifndef _ICONTROL_ +#define _ICONTROL_ + +#include "IPlugBase.h" +#include "IGraphics.h" + +// A control is anything on the GUI, it could be a static bitmap, or +// something that moves or changes. The control could manipulate +// canned bitmaps or do run-time vector drawing, or whatever. +// +// Some controls respond to mouse actions, either by moving a bitmap, +// transforming a bitmap, or cycling through a set of bitmaps. +// Other controls are readouts only. + +class IControl +{ +public: + + // If paramIdx is > -1, this control will be associated with a plugin parameter. + IControl(IPlugBase* pPlug, IRECT* pR, int paramIdx = -1, IChannelBlend blendMethod = IChannelBlend::kBlendNone) + : mPlug(pPlug), mRECT(*pR), mTargetRECT(*pR), mParamIdx(paramIdx), mValue(0.0), mDefaultValue(-1.0), + mBlend(blendMethod), mDirty(true), mHide(false), mGrayed(false), mDisablePrompt(false), mDblAsSingleClick(false), + mClampLo(0.0), mClampHi(1.0) {} + + virtual ~IControl() {} + + virtual void OnMouseDown(int x, int y, IMouseMod* pMod); + virtual void OnMouseUp(int x, int y, IMouseMod* pMod) {} + virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) {} + virtual void OnMouseDblClick(int x, int y, IMouseMod* pMod); + virtual void OnMouseWheel(int x, int y, IMouseMod* pMod, int d); + virtual void OnKeyDown(int x, int y, int key) {} + + // For efficiency, mouseovers/mouseouts are ignored unless you call IGraphics::HandleMouseOver. + virtual void OnMouseOver(int x, int y, IMouseMod* pMod) {} + virtual void OnMouseOut() {} + + // By default, mouse double click has its own handler. A control can set mDblAsSingleClick to true to change, + // which maps double click to single click for this control (and also causes the mouse to be + // captured by the control on double click). + bool MouseDblAsSingleClick() { return mDblAsSingleClick; } + + virtual bool Draw(IGraphics* pGraphics) = 0; + + // Ask the IGraphics object to open an edit box so the user can enter a value for this control. + void PromptUserInput(); + + int ParamIdx() { return mParamIdx; } + virtual void SetValueFromPlug(double value); + void SetValueFromUserInput(double value); + double GetValue() { return mValue; } + + IRECT* GetRECT() { return &mRECT; } // The draw area for this control. + IRECT* GetTargetRECT() { return &mTargetRECT; } // The mouse target area (default = draw area). + void SetTargetArea(IRECT* pR) { mTargetRECT = *pR; } + + virtual void Hide(bool hide); + bool IsHidden() const { return mHide; } + + virtual void GrayOut(bool gray); + bool IsGrayed() { return mGrayed; } + + // Override if you want the control to be hit only if a visible part of it is hit, or whatever. + virtual bool IsHit(int x, int y) { return mTargetRECT.Contains(x, y); } + + void SetBlendMethod(IChannelBlend::EBlendMethod blendMethod) { mBlend = IChannelBlend(blendMethod); } + + virtual void SetDirty(bool pushParamToPlug = true); + virtual void SetClean(); + virtual bool IsDirty() { return mDirty; } + void Clamp(double lo, double hi) { mClampLo = lo; mClampHi = hi; } + void DisablePrompt(bool disable) { mDisablePrompt = disable; } // Disables the right-click manual value entry. + + // Sometimes a control changes its state as part of its Draw method. + // Redraw() prevents the control from being cleaned immediately after drawing. + void Redraw() { mRedraw = true; } + + // This is an idle call from the GUI thread, as opposed to + // IPlugBase::OnIdle which is called from the audio processing thread. + // Only active if USE_IDLE_CALLS is defined. + virtual void OnGUIIdle() {} + +protected: + + IPlugBase* mPlug; + IRECT mRECT, mTargetRECT; + int mParamIdx; + double mValue, mDefaultValue, mClampLo, mClampHi; + bool mDirty, mHide, mGrayed, mRedraw, mDisablePrompt, mClamped, mDblAsSingleClick; + IChannelBlend mBlend; +}; + +enum EDirection { kVertical, kHorizontal }; + +// Draws a bitmap, or one frame of a stacked bitmap depending on the current value. +class IBitmapControl : public IControl +{ +public: + + IBitmapControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, + IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) + : IControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, blendMethod), mBitmap(*pBitmap) {} + + IBitmapControl(IPlugBase* pPlug, int x, int y, IBitmap* pBitmap, + IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) + : IControl(pPlug, &IRECT(x, y, pBitmap), -1, blendMethod), mBitmap(*pBitmap) {} + + virtual ~IBitmapControl() {} + + virtual bool Draw(IGraphics* pGraphics); + +protected: + IBitmap mBitmap; +}; + +// A switch. Click to cycle through the bitmap states. +class ISwitchControl : public IBitmapControl +{ +public: + + ISwitchControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, + IChannelBlend::EBlendMethod blendMethod = IChannelBlend::kBlendNone) + : IBitmapControl(pPlug, x, y, paramIdx, pBitmap, blendMethod) {} + ~ISwitchControl() {} + + void OnMouseDown(int x, int y, IMouseMod* pMod); +}; + +// On/off switch that has a target area only. +class IInvisibleSwitchControl : public IControl +{ +public: + + IInvisibleSwitchControl(IPlugBase* pPlug, IRECT* pR, int paramIdx); + ~IInvisibleSwitchControl() {} + + void OnMouseDown(int x, int y, IMouseMod* pMod); + + virtual bool Draw(IGraphics* pGraphics) { return true; } +}; + +// A set of buttons that maps to a single selection. Bitmap has 2 states, off and on. +class IRadioButtonsControl : public IControl +{ +public: + + IRadioButtonsControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, int nButtons, IBitmap* pBitmap, + EDirection direction = kVertical); + ~IRadioButtonsControl() {} + + void OnMouseDown(int x, int y, IMouseMod* pMod); + bool Draw(IGraphics* pGraphics); + +protected: + WDL_TypedBuf mRECTs; + IBitmap mBitmap; +}; + +// A switch that reverts to 0.0 when released. +class IContactControl : public ISwitchControl +{ +public: + + IContactControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap) + : ISwitchControl(pPlug, x, y, paramIdx, pBitmap) {} + ~IContactControl() {} + + void OnMouseUp(int x, int y, IMouseMod* pMod); +}; + +// A fader. The bitmap snaps to a mouse click or drag. +class IFaderControl : public IControl +{ +public: + + IFaderControl(IPlugBase* pPlug, int x, int y, int len, int paramIdx, IBitmap* pBitmap, + EDirection direction = kVertical); + ~IFaderControl() {} + + int GetLength() const { return mLen; } + // Size of the handle in pixels. + int GetHandleHeadroom() const { return mHandleHeadroom; } + // Size of the handle in terms of the control value. + double GetHandleValueHeadroom() const { return (double) mHandleHeadroom / (double) mLen; } + // Where is the handle right now? + IRECT GetHandleRECT(double value = -1.0) const; + + virtual void OnMouseDown(int x, int y, IMouseMod* pMod); + virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod); + + virtual bool Draw(IGraphics* pGraphics); + +protected: + void SnapToMouse(int x, int y); + int mLen, mHandleHeadroom; + IBitmap mBitmap; + EDirection mDirection; +}; + +const double DEFAULT_GEARING = 4.0; + +// Parent for knobs, to handle mouse action and ballistics. +class IKnobControl : public IControl +{ +public: + + IKnobControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, EDirection direction = kVertical, + double gearing = DEFAULT_GEARING) + : IControl(pPlug, pR, paramIdx), mDirection(direction), mGearing(gearing) {} + virtual ~IKnobControl() {} + + void SetGearing(double gearing) { mGearing = gearing; } + virtual void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod); + +protected: + EDirection mDirection; + double mGearing; +}; + +// A knob that is just a line. +class IKnobLineControl : public IKnobControl +{ +public: + + IKnobLineControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, + const IColor* pColor, double innerRadius = 0.0, double outerRadius = 0.0, + double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, + EDirection direction = kVertical, double gearing = DEFAULT_GEARING); + ~IKnobLineControl() {} + + bool Draw(IGraphics* pGraphics); + +private: + IColor mColor; + float mMinAngle, mMaxAngle, mInnerRadius, mOuterRadius; +}; + +// A rotating knob. The bitmap rotates with any mouse drag. +class IKnobRotaterControl : public IKnobControl +{ +public: + + IKnobRotaterControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, + double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, int yOffsetZeroDeg = 0, + EDirection direction = kVertical, double gearing = DEFAULT_GEARING) + : IKnobControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, direction, gearing), + mBitmap(*pBitmap), mMinAngle(minAngle), mMaxAngle(maxAngle), mYOffset(yOffsetZeroDeg) {} + ~IKnobRotaterControl() {} + + bool Draw(IGraphics* pGraphics); + +private: + IBitmap mBitmap; + double mMinAngle, mMaxAngle; + int mYOffset; +}; + +// A multibitmap knob. The bitmap cycles through states as the mouse drags. +class IKnobMultiControl : public IKnobControl +{ +public: + + IKnobMultiControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, + EDirection direction = kVertical, double gearing = DEFAULT_GEARING) + : IKnobControl(pPlug, &IRECT(x, y, pBitmap), paramIdx, direction, gearing), mBitmap(*pBitmap) {} + ~IKnobMultiControl() {} + + bool Draw(IGraphics* pGraphics); + +private: + IBitmap mBitmap; +}; + +// A knob that consists of a static base, a rotating mask, and a rotating top. +// The bitmaps are assumed to be symmetrical and identical sizes. +class IKnobRotatingMaskControl : public IKnobControl +{ +public: + + IKnobRotatingMaskControl(IPlugBase* pPlug, int x, int y, int paramIdx, + IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, + double minAngle = -0.75 * PI, double maxAngle = 0.75 * PI, + EDirection direction = kVertical, double gearing = DEFAULT_GEARING) + : IKnobControl(pPlug, &IRECT(x, y, pBase), paramIdx, direction, gearing), + mBase(*pBase), mMask(*pMask), mTop(*pTop), mMinAngle(minAngle), mMaxAngle(maxAngle) {} + ~IKnobRotatingMaskControl() {} + + bool Draw(IGraphics* pGraphics); + +private: + IBitmap mBase, mMask, mTop; + double mMinAngle, mMaxAngle; +}; + +// Bitmap shows when value = 0, then toggles its target area to the whole bitmap +// and waits for another click to hide itself. +class IBitmapOverlayControl : public ISwitchControl +{ +public: + + IBitmapOverlayControl(IPlugBase* pPlug, int x, int y, int paramIdx, IBitmap* pBitmap, IRECT* pTargetArea) + : ISwitchControl(pPlug, x, y, paramIdx, pBitmap), mTargetArea(*pTargetArea) {} + + IBitmapOverlayControl(IPlugBase* pPlug, int x, int y, IBitmap* pBitmap, IRECT* pTargetArea) + : ISwitchControl(pPlug, x, y, -1, pBitmap), mTargetArea(*pTargetArea) {} + + ~IBitmapOverlayControl() {} + + bool Draw(IGraphics* pGraphics); + +private: + IRECT mTargetArea; // Keep this around to swap in & out. +}; + +// Output text to the screen. +class ITextControl : public IControl +{ +public: + + ITextControl(IPlugBase* pPlug, IRECT* pR, IText* pText, const char* str = "") + : IControl(pPlug, pR), mText(*pText) + { + mStr.Set(str); + } + ~ITextControl() {} + + void SetTextFromPlug(char* str); + void ClearTextFromPlug() { SetTextFromPlug(""); } + + bool Draw(IGraphics* pGraphics); + +protected: + IText mText; + WDL_String mStr; +}; + +// If paramIdx is specified, the text is automatically set to the output +// of Param::GetDisplayForHost(). If showParamLabel = true, Param::GetLabelForHost() is appended. +class ICaptionControl : public ITextControl +{ +public: + + ICaptionControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IText* pText, bool showParamLabel = true); + ~ICaptionControl() {} + + bool Draw(IGraphics* pGraphics); + +protected: + bool mShowParamLabel; +}; + +#define MAX_URL_LEN 256 +#define MAX_NET_ERR_MSG_LEN 1024 + +class IURLControl : public IControl +{ +public: + + IURLControl(IPlugBase* pPlug, IRECT* pR, const char* url, const char* backupURL = 0, const char* errMsgOnFailure = 0); + ~IURLControl() {} + + void OnMouseDown(int x, int y, IMouseMod* pMod); + bool Draw(IGraphics* pGraphics) { return true; } + +protected: + char mURL[MAX_URL_LEN], mBackupURL[MAX_URL_LEN], mErrMsg[MAX_NET_ERR_MSG_LEN]; +}; + +// This is a weird control for a few reasons. +// - Although its numeric mValue is not meaningful, it needs to be associated with a plugin parameter +// so it can inform the plug when the file selection has changed. If the associated plugin parameter is +// declared after kNumParams in the EParams enum, the parameter will be a dummy for this purpose only. +// - Because it puts up a modal window, it needs to redraw itself twice when it's dirty, +// because moving the modal window will clear the first dirty state. +class IFileSelectorControl : public IControl +{ +public: + + enum EFileSelectorState { kFSNone, kFSSelecting, kFSDone }; + + IFileSelectorControl(IPlugBase* pPlug, IRECT* pR, int paramIdx, IBitmap* pBitmap, + IGraphics::EFileAction action, char* dir = "", char* extensions = "") // extensions = "txt wav" for example. + : IControl(pPlug, pR, paramIdx), mBitmap(*pBitmap), + mFileAction(action), mDir(dir), mExtensions(extensions), mState(kFSNone) {} + ~IFileSelectorControl() {} + + void OnMouseDown(int x, int y, IMouseMod* pMod); + + void GetLastSelectedFileForPlug(WDL_String* pStr); + void SetLastSelectedFileFromPlug(char* file); + + bool Draw(IGraphics* pGraphics); + bool IsDirty(); + +private: + IBitmap mBitmap; + WDL_String mDir, mFile, mExtensions; + IGraphics::EFileAction mFileAction; + EFileSelectorState mState; +}; + +#endif diff --git a/WDL/IPlug/IGraphics.cpp b/WDL/IPlug/IGraphics.cpp new file mode 100644 index 00000000..d7398760 --- /dev/null +++ b/WDL/IPlug/IGraphics.cpp @@ -0,0 +1,446 @@ +#include "IGraphics.h" +#include "IControl.h" + +#define DEFAULT_FPS 24 + +// If not dirty for this many timer ticks, we call OnGUIIDle. +// Only looked at if USE_IDLE_CALLS is defined. +#define IDLE_TICKS 20 + +IGraphics::IGraphics(IPlugBase* pPlug, int w, int h, int refreshFPS) +: mPlug(pPlug), mWidth(w), mHeight(h), mIdleTicks(0), + mMouseCapture(-1), mMouseOver(-1), mMouseX(0), mMouseY(0), mHandleMouseOver(false), mStrict(true), mDisplayControlValue(false) +{ + mFPS = (refreshFPS > 0 ? refreshFPS : DEFAULT_FPS); +} + +IGraphics::~IGraphics() +{ + mControls.Empty(true); +} + +void IGraphics::Resize(int w, int h) +{ + // The OS implementation class has to do all the work, then call up to here. + mWidth = w; + mHeight = h; + ReleaseMouseCapture(); + mControls.Empty(true); + mPlug->ResizeGraphics(w, h); +} + +void IGraphics::AttachBackground(int ID, const char* name) +{ + IBitmap bg = LoadIBitmap(ID, name); + IControl* pBG = new IBitmapControl(mPlug, 0, 0, -1, &bg, IChannelBlend::kBlendClobber); + mControls.Insert(0, pBG); +} + +int IGraphics::AttachControl(IControl* pControl) +{ + mControls.Add(pControl); + return mControls.GetSize() - 1; +} + +void IGraphics::HideControl(int paramIdx, bool hide) +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->ParamIdx() == paramIdx) { + pControl->Hide(hide); + } + // Could be more than one, don't break until we check them all. + } +} + +void IGraphics::GrayOutControl(int paramIdx, bool gray) +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->ParamIdx() == paramIdx) { + pControl->GrayOut(gray); + } + // Could be more than one, don't break until we check them all. + } +} + +void IGraphics::ClampControl(int paramIdx, double lo, double hi, bool normalized) +{ + if (!normalized) { + IParam* pParam = mPlug->GetParam(paramIdx); + lo = pParam->GetNormalized(lo); + hi = pParam->GetNormalized(hi); + } + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->ParamIdx() == paramIdx) { + pControl->Clamp(lo, hi); + } + // Could be more than one, don't break until we check them all. + } +} + +void IGraphics::SetParameterFromPlug(int paramIdx, double value, bool normalized) +{ + if (!normalized) { + IParam* pParam = mPlug->GetParam(paramIdx); + value = pParam->GetNormalized(value); + } + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->ParamIdx() == paramIdx) { + //WDL_MutexLock lock(&mMutex); + pControl->SetValueFromPlug(value); + // Could be more than one, don't break until we check them all. + } + } +} + +void IGraphics::SetControlFromPlug(int controlIdx, double normalizedValue) +{ + if (controlIdx >= 0 && controlIdx < mControls.GetSize()) { + //WDL_MutexLock lock(&mMutex); + mControls.Get(controlIdx)->SetValueFromPlug(normalizedValue); + } +} + +void IGraphics::SetAllControlsDirty() +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + pControl->SetDirty(false); + } +} + +void IGraphics::SetParameterFromGUI(int paramIdx, double normalizedValue) +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->ParamIdx() == paramIdx) { + pControl->SetValueFromUserInput(normalizedValue); + // Could be more than one, don't break until we check them all. + } + } +} + +bool IGraphics::DrawBitmap(IBitmap* pBitmap, IRECT* pR, int bmpState, const IChannelBlend* pBlend) +{ + int srcY = 0; + if (pBitmap->N > 1 && bmpState > 1) { + srcY = int(0.5 + (double) pBitmap->H * (double) (bmpState - 1) / (double) pBitmap->N); + } + return DrawBitmap(pBitmap, pR, 0, srcY, pBlend); +} + +bool IGraphics::DrawRect(const IColor* pColor, IRECT* pR) +{ + bool rc = DrawHorizontalLine(pColor, pR->T, pR->L, pR->R); + rc &= DrawHorizontalLine(pColor, pR->B, pR->L, pR->R); + rc &= DrawVerticalLine(pColor, pR->L, pR->T, pR->B); + rc &= DrawVerticalLine(pColor, pR->R, pR->T, pR->B); + return rc; +} + +bool IGraphics::DrawVerticalLine(const IColor* pColor, IRECT* pR, float x) +{ + x = BOUNDED(x, 0.0f, 1.0f); + int xi = pR->L + int(x * (float) (pR->R - pR->L)); + return DrawVerticalLine(pColor, xi, pR->T, pR->B); +} + +bool IGraphics::DrawHorizontalLine(const IColor* pColor, IRECT* pR, float y) +{ + y = BOUNDED(y, 0.0f, 1.0f); + int yi = pR->B - int(y * (float) (pR->B - pR->T)); + return DrawHorizontalLine(pColor, yi, pR->L, pR->R); +} + +bool IGraphics::DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi) +{ + IChannelBlend clobber(IChannelBlend::kBlendClobber); + return DrawLine(pColor, (float) xi, (float) yLo, (float) xi, (float) yHi, &clobber); +} + +bool IGraphics::DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi) +{ + IChannelBlend clobber(IChannelBlend::kBlendClobber); + return DrawLine(pColor, (float) xLo, (float) yi, (float) xHi, (float) yi, &clobber); +} + +bool IGraphics::DrawRadialLine(const IColor* pColor, float cx, float cy, float angle, float rMin, float rMax, + const IChannelBlend* pBlend, bool antiAlias) +{ + float sinV = sin(angle); + float cosV = cos(angle); + float xLo = cx + rMin * sinV; + float xHi = cx + rMax * sinV; + float yLo = cy - rMin * cosV; + float yHi = cy - rMax * cosV; + return DrawLine(pColor, xLo, yLo, xHi, yHi, pBlend, antiAlias); +} + +bool IGraphics::IsDirty(IRECT* pR) +{ + bool dirty = false; + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (pControl->IsDirty()) { + *pR = pR->Union(pControl->GetRECT()); + dirty = true; + } + } + +#ifdef USE_IDLE_CALLS + if (dirty) { + mIdleTicks = 0; + } + else + if (++mIdleTicks > IDLE_TICKS) { + OnGUIIdle(); + mIdleTicks = 0; + } +#endif + + return dirty; +} + +void IGraphics::DisplayControlValue(IControl* pControl) +{ +// char str[32]; +// int paramIdx = pControl->ParamIdx(); +// if (paramIdx >= 0) { +// IParam* pParam = mPlug->GetParam(paramIdx); +// pParam->GetDisplayForHost(str); +// IRECT r = *(pControl->GetRECT()); +// r.L = r.MW() - 10; +// r.R = r.L + 20; +// r.T = r.MH() - 5; +// r.B = r.T + 10; +// DrawIText(&IText(), str, &r); +// } +} + +// The OS is announcing what needs to be redrawn, +// which may be a larger area than what is strictly dirty. +bool IGraphics::Draw(IRECT* pR) +{ +// #pragma REMINDER("Mutex set while drawing") +// WDL_MutexLock lock(&mMutex); + + int i, j, n = mControls.GetSize(); + if (!n) { + return true; + } + + if (mStrict) { + mDrawRECT = *pR; + int n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (int i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + if (!(pControl->IsHidden()) && pR->Intersects(pControl->GetRECT())) { + pControl->Draw(this); +// if (mDisplayControlValue && i == mMouseCapture) { +// DisplayControlValue(pControl); +// } + } + pControl->SetClean(); + } + } + else { + IControl* pBG = mControls.Get(0); + if (pBG->IsDirty()) { // Special case when everything needs to be drawn. + mDrawRECT = *(pBG->GetRECT()); + for (int j = 0; j < n; ++j) { + IControl* pControl2 = mControls.Get(j); + if (!j || !(pControl2->IsHidden())) { + pControl2->Draw(this); + pControl2->SetClean(); + } + } + } + else { + for (i = 1; i < n; ++i) { + IControl* pControl = mControls.Get(i); + if (pControl->IsDirty()) { + mDrawRECT = *(pControl->GetRECT()); + for (j = 0; j < n; ++j) { + IControl* pControl2 = mControls.Get(j); + if ((i == j) || (!(pControl2->IsHidden()) && pControl2->GetRECT()->Intersects(&mDrawRECT))) { + pControl2->Draw(this); + } + } + pControl->SetClean(); + } + } + } + } + + return DrawScreen(pR); + +} + +void IGraphics::SetStrictDrawing(bool strict) +{ + mStrict = strict; + SetAllControlsDirty(); +} + +void IGraphics::OnMouseDown(int x, int y, IMouseMod* pMod) +{ + ReleaseMouseCapture(); + int c = GetMouseControlIdx(x, y); + if (c >= 0) { + mMouseCapture = c; + mMouseX = x; + mMouseY = y; + mDisplayControlValue = (pMod->R); + IControl* pControl = mControls.Get(c); + pControl->OnMouseDown(x, y, pMod); + int paramIdx = pControl->ParamIdx(); + if (paramIdx >= 0) { + mPlug->BeginInformHostOfParamChange(paramIdx); + } + } +} + +void IGraphics::OnMouseUp(int x, int y, IMouseMod* pMod) +{ + int c = GetMouseControlIdx(x, y); + mMouseCapture = mMouseX = mMouseY = -1; + mDisplayControlValue = false; + if (c >= 0) { + IControl* pControl = mControls.Get(c); + pControl->OnMouseUp(x, y, pMod); + int paramIdx = pControl->ParamIdx(); + if (paramIdx >= 0) { + mPlug->EndInformHostOfParamChange(paramIdx); + } + } +} + +bool IGraphics::OnMouseOver(int x, int y, IMouseMod* pMod) +{ + if (mHandleMouseOver) { + int c = GetMouseControlIdx(x, y); + if (c >= 0) { + mMouseX = x; + mMouseY = y; + mControls.Get(c)->OnMouseOver(x, y, pMod); + if (mMouseOver >= 0 && mMouseOver != c) { + mControls.Get(mMouseOver)->OnMouseOut(); + } + mMouseOver = c; + } + } + return mHandleMouseOver; +} + +void IGraphics::OnMouseOut() +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + pControl->OnMouseOut(); + } + mMouseOver = -1; +} + +void IGraphics::OnMouseDrag(int x, int y, IMouseMod* pMod) +{ + int c = mMouseCapture; + if (c >= 0) { + int dX = x - mMouseX; + int dY = y - mMouseY; + if (dX != 0 || dY != 0) { + mMouseX = x; + mMouseY = y; + mControls.Get(c)->OnMouseDrag(x, y, dX, dY, pMod); + } + } +} + +bool IGraphics::OnMouseDblClick(int x, int y, IMouseMod* pMod) +{ + ReleaseMouseCapture(); + bool newCapture = false; + int c = GetMouseControlIdx(x, y); + if (c >= 0) { + IControl* pControl = mControls.Get(c); + if (pControl->MouseDblAsSingleClick()) { + mMouseCapture = c; + mMouseX = x; + mMouseY = y; + pControl->OnMouseDown(x, y, pMod); + newCapture = true; + } + else { + pControl->OnMouseDblClick(x, y, pMod); + } + } + return newCapture; +} + +void IGraphics::OnMouseWheel(int x, int y, IMouseMod* pMod, int d) +{ + int c = GetMouseControlIdx(x, y); + if (c >= 0) { + mControls.Get(c)->OnMouseWheel(x, y, pMod, d); + } +} + +void IGraphics::ReleaseMouseCapture() +{ + mMouseCapture = mMouseX = mMouseY = -1; +} + +void IGraphics::OnKeyDown(int x, int y, int key) +{ + int c = GetMouseControlIdx(x, y); + if (c >= 0) { + mControls.Get(c)->OnKeyDown(x, y, key); + } +} + +int IGraphics::GetMouseControlIdx(int x, int y) +{ + if (mMouseCapture >= 0) { + return mMouseCapture; + } + // The BG is a control and will catch everything, so assume the programmer + // attached the controls from back to front, and return the frontmost match. + int i = mControls.GetSize() - 1; + IControl** ppControl = mControls.GetList() + i; + for (/* */; i >= 0; --i, --ppControl) { + IControl* pControl = *ppControl; + if (!pControl->IsHidden() && !pControl->IsGrayed() && pControl->IsHit(x, y)) { + return i; + } + } + return -1; +} + +void IGraphics::OnGUIIdle() +{ + int i, n = mControls.GetSize(); + IControl** ppControl = mControls.GetList(); + for (i = 0; i < n; ++i, ++ppControl) { + IControl* pControl = *ppControl; + pControl->OnGUIIdle(); + } +} diff --git a/WDL/IPlug/IGraphics.h b/WDL/IPlug/IGraphics.h new file mode 100644 index 00000000..6b915620 --- /dev/null +++ b/WDL/IPlug/IGraphics.h @@ -0,0 +1,162 @@ +#ifndef _IGRAPHICS_ +#define _IGRAPHICS_ + +#include "IPlugStructs.h" + +class IPlugBase; +class IControl; +class IParam; + +class IGraphics +{ +public: + + virtual void PrepDraw() = 0; // Called once, when the IGraphics class is attached to the IPlug class. + bool IsDirty(IRECT* pR); // Ask the plugin what needs to be redrawn. + bool Draw(IRECT* pR); // The system announces what needs to be redrawn. Ordering and drawing logic. + virtual bool DrawScreen(IRECT* pR) = 0; // Tells the OS class to put the final bitmap on the screen. + + // Methods for the drawing implementation class. + virtual bool DrawBitmap(IBitmap* pBitmap, IRECT* pDest, int srcX, int srcY, + const IChannelBlend* pBlend = 0) = 0; + virtual bool DrawRotatedBitmap(IBitmap* pBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg = 0, + const IChannelBlend* pBlend = 0) = 0; + virtual bool DrawRotatedMask(IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, int x, int y, double angle, + const IChannelBlend* pBlend = 0) = 0; + virtual bool DrawPoint(const IColor* pColor, float x, float y, + const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; + // Live ammo! Will crash if out of bounds! etc. + virtual bool ForcePixel(const IColor* pColor, int x, int y) = 0; + virtual bool DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, + const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; + virtual bool DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, + const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; + virtual bool DrawCircle(const IColor* pColor, float cx, float cy, float r, + const IChannelBlend* pBlend = 0, bool antiAlias = false) = 0; + virtual bool FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend = 0) = 0; + virtual bool DrawIText(IText* pTxt, char* str, IRECT* pR) = 0; + virtual IColor GetPoint(int x, int y) = 0; + virtual void* GetData() = 0; + + // Methods for the OS implementation class. + virtual void Resize(int w, int h); + virtual bool WindowIsOpen() { return (GetWindow()); } + virtual void PromptUserInput(IControl* pControl, IParam* pParam) = 0; + virtual void HostPath(WDL_String* pPath) = 0; // Full path to host executable. + virtual void PluginPath(WDL_String* pPath) = 0; // Full path to plugin dll. + // Run the "open file" or "save file" dialog. Default to host executable path. + enum EFileAction { kFileOpen, kFileSave }; + virtual void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = 0, + char* extensions = 0) = 0; // extensions = "txt wav" for example. + virtual bool PromptForColor(IColor* pColor, char* prompt = 0) = 0; + + virtual bool OpenURL(const char* url, + const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0) = 0; + + // Strict (default): draw everything within the smallest rectangle that contains everything dirty. + // Every control is guaranteed to get no more than one Draw() call per cycle. + // Fast: draw only controls that intersect something dirty. + // If there are overlapping controls, fast drawing can generate multiple Draw() calls per cycle + // (a control may be asked to draw multiple parts of itself, if it intersects with something dirty.) + void SetStrictDrawing(bool strict); + + virtual void* OpenWindow(void* pParentWnd) = 0; + virtual void* OpenWindow(void* pParentWnd, void* pParentControl) { return 0; } // For OSX Carbon hosts ... ugh. + virtual void CloseWindow() = 0; + virtual void* GetWindow() = 0; + + //////////////////////////////////////// + + IGraphics(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); + virtual ~IGraphics(); + + int Width() { return mWidth; } + int Height() { return mHeight; } + int FPS() { return mFPS; } + + IPlugBase* GetPlug() { return mPlug; } + + virtual IBitmap LoadIBitmap(int ID, const char* name, int nStates = 1) = 0; + virtual IBitmap ScaleBitmap(IBitmap* pSrcBitmap, int destW, int destH) = 0; + virtual IBitmap CropBitmap(IBitmap* pSrcBitmap, IRECT* pR) = 0; + virtual void AttachBackground(int ID, const char* name); + // Returns the control index of this control (not the number of controls). + int AttachControl(IControl* pControl); + + IControl* GetControl(int idx) { return mControls.Get(idx); } + void HideControl(int paramIdx, bool hide); + void GrayOutControl(int paramIdx, bool gray); + + // Normalized means the value is in [0, 1]. + void ClampControl(int paramIdx, double lo, double hi, bool normalized); + void SetParameterFromPlug(int paramIdx, double value, bool normalized); + // For setting a control that does not have a parameter associated with it. + void SetControlFromPlug(int controlIdx, double normalizedValue); + + void SetAllControlsDirty(); + + // This is for when the gui needs to change a control value that it can't redraw + // for context reasons. If the gui has redrawn the control, use IPlug::SetParameterFromGUI. + void SetParameterFromGUI(int paramIdx, double normalizedValue); + + // Convenience wrappers. + bool DrawBitmap(IBitmap* pBitmap, IRECT* pR, int bmpState = 1, const IChannelBlend* pBlend = 0); + bool DrawRect(const IColor* pColor, IRECT* pR); + bool DrawVerticalLine(const IColor* pColor, IRECT* pR, float x); + bool DrawHorizontalLine(const IColor* pColor, IRECT* pR, float y); + virtual bool DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi); + virtual bool DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi); + bool DrawRadialLine(const IColor* pColor, float cx, float cy, float angle, float rMin, float rMax, + const IChannelBlend* pBlend = 0, bool antiAlias = false); + + void OnMouseDown(int x, int y, IMouseMod* pMod); + void OnMouseUp(int x, int y, IMouseMod* pMod); + void OnMouseDrag(int x, int y, IMouseMod* pMod); + // Returns true if the control receiving the double click will treat it as a single click + // (meaning the OS should capture the mouse). + bool OnMouseDblClick(int x, int y, IMouseMod* pMod); + void OnMouseWheel(int x, int y, IMouseMod* pMod, int d); + void OnKeyDown(int x, int y, int key); + + void DisplayControlValue(IControl* pControl); + + // For efficiency, mouseovers/mouseouts are ignored unless you explicity say you can handle them. + void HandleMouseOver(bool canHandle) { mHandleMouseOver = canHandle; } + bool OnMouseOver(int x, int y, IMouseMod* pMod); // Returns true if mouseovers are handled. + void OnMouseOut(); + // Some controls may not need to capture the mouse for dragging, they can call ReleaseCapture when the mouse leaves. + void ReleaseMouseCapture(); + + // This is an idle call from the GUI thread, as opposed to + // IPlug::OnIdle which is called from the audio processing thread. + void OnGUIIdle(); + + virtual void RetainBitmap(IBitmap* pBitmap) = 0; + virtual void ReleaseBitmap(IBitmap* pBitmap) = 0; + + WDL_Mutex mMutex; + + struct IMutexLock + { + WDL_Mutex* mpMutex; + IMutexLock(IGraphics* pGraphics) : mpMutex(&(pGraphics->mMutex)) { mpMutex->Enter(); } + ~IMutexLock() { mpMutex->Leave(); } + }; + +protected: + + WDL_PtrList mControls; + IPlugBase* mPlug; + IRECT mDrawRECT; + + bool CanHandleMouseOver() { return mHandleMouseOver; } + +private: + + int mWidth, mHeight, mFPS, mIdleTicks; + int GetMouseControlIdx(int x, int y); + int mMouseCapture, mMouseOver, mMouseX, mMouseY; + bool mHandleMouseOver, mStrict, mDisplayControlValue; +}; + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsCarbon.cpp b/WDL/IPlug/IGraphicsCarbon.cpp new file mode 100644 index 00000000..f9d64fd4 --- /dev/null +++ b/WDL/IPlug/IGraphicsCarbon.cpp @@ -0,0 +1,264 @@ +#include "IGraphicsCarbon.h" + +IRECT GetRegionRect(EventRef pEvent, int gfxW, int gfxH) +{ + RgnHandle pRgn = 0; + if (GetEventParameter(pEvent, kEventParamRgnHandle, typeQDRgnHandle, 0, sizeof(RgnHandle), 0, &pRgn) == noErr && pRgn) { + Rect rct; + GetRegionBounds(pRgn, &rct); + return IRECT(rct.left, rct.top, rct.right, rct.bottom); + } + return IRECT(0, 0, gfxW, gfxH); +} + +IRECT GetControlRect(EventRef pEvent, int gfxW, int gfxH) +{ + Rect rct; + if (GetEventParameter(pEvent, kEventParamCurrentBounds, typeQDRectangle, 0, sizeof(Rect), 0, &rct) == noErr) { + int w = rct.right - rct.left; + int h = rct.bottom - rct.top; + if (w > 0 && h > 0) { + return IRECT(0, 0, w, h); + } + } + return IRECT(0, 0, gfxW, gfxH); +} + +// static +pascal OSStatus IGraphicsCarbon::CarbonEventHandler(EventHandlerCallRef pHandlerCall, EventRef pEvent, void* pGraphicsCarbon) +{ + IGraphicsCarbon* _this = (IGraphicsCarbon*) pGraphicsCarbon; + IGraphicsMac* pGraphicsMac = _this->mGraphicsMac; + UInt32 eventClass = GetEventClass(pEvent); + UInt32 eventKind = GetEventKind(pEvent); + switch (eventClass) { + case kEventClassControl: { + switch (eventKind) { + case kEventControlDraw: { + + int gfxW = pGraphicsMac->Width(), gfxH = pGraphicsMac->Height(); + IRECT r = GetRegionRect(pEvent, gfxW, gfxH); + + CGrafPtr port = 0; + if (_this->mIsComposited) { + GetEventParameter(pEvent, kEventParamCGContextRef, typeCGContextRef, 0, sizeof(CGContextRef), 0, &(_this->mCGC)); + CGContextTranslateCTM(_this->mCGC, 0, gfxH); + CGContextScaleCTM(_this->mCGC, 1.0, -1.0); + pGraphicsMac->Draw(&r); + } + else { + #pragma REMINDER("not swapping gfx ports in non-composited mode") + + int ctlH = r.H(); + _this->mContentYOffset = ctlH - gfxH; + + //Rect rct; + //GetWindowBounds(_this->mWindow, kWindowContentRgn, &rct); + //int wndH = rct.bottom - rct.top; + //if (wndH > gfxH) { + // int yOffs = wndH - gfxH; + // _this->mContentYOffset = yOffs; + // } + + GetEventParameter(pEvent, kEventParamGrafPort, typeGrafPtr, 0, sizeof(CGrafPtr), 0, &port); + QDBeginCGContext(port, &(_this->mCGC)); + // Old-style controls drawing, ask the plugin what's dirty rather than relying on the OS. + r.R = r.T = r.R = r.B = 0; + _this->mGraphicsMac->IsDirty(&r); + } + + pGraphicsMac->Draw(&r); + + if (port) { + CGContextFlush(_this->mCGC); + QDEndCGContext(port, &(_this->mCGC)); + } + + return noErr; + } + case kEventControlBoundsChanged: { + int gfxW = pGraphicsMac->Width(), gfxH = pGraphicsMac->Height(); + IRECT r = GetControlRect(pEvent, gfxW, gfxH); + //pGraphicsMac->GetPlug()->UserResizedWindow(&r); + return noErr; + } + case kEventControlDispose: { + // kComponentCloseSelect call should already have done this for us (and deleted mGraphicsMac, for that matter). + // pGraphicsMac->CloseWindow(); + return noErr; + } + } + break; + } + case kEventClassMouse: { + HIPoint hp; + GetEventParameter(pEvent, kEventParamWindowMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hp); + HIPointConvert(&hp, kHICoordSpaceWindow, _this->mWindow, kHICoordSpaceView, _this->mView); + int x = (int) hp.x; + int y = (int) hp.y; + + UInt32 mods; + GetEventParameter(pEvent, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &mods); + IMouseMod mmod(true, (mods & cmdKey), (mods & shiftKey), (mods & controlKey), (mods & optionKey)); + + switch (eventKind) { + case kEventMouseDown: { + CallNextEventHandler(pHandlerCall, pEvent); // Activates the window, if inactive. + + UInt32 clickCount = 0; + GetEventParameter(pEvent, kEventParamClickCount, typeUInt32, 0, sizeof(UInt32), 0, &clickCount); + if (clickCount > 1) { + pGraphicsMac->OnMouseDblClick(x, y, &mmod); + } + else { + pGraphicsMac->OnMouseDown(x, y, &mmod); + } + return noErr; + } + case kEventMouseUp: { + pGraphicsMac->OnMouseUp(x, y, &mmod); + return noErr; + } + case kEventMouseMoved: { + pGraphicsMac->OnMouseOver(x, y, &mmod); + return noErr; + } + case kEventMouseDragged: { + pGraphicsMac->OnMouseDrag(x, y, &mmod); + return noErr; + } + case kEventMouseWheelMoved: { + EventMouseWheelAxis axis; + GetEventParameter(pEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0, sizeof(EventMouseWheelAxis), 0, &axis); + if (axis == kEventMouseWheelAxisY) { + int d; + GetEventParameter(pEvent, kEventParamMouseWheelDelta, typeSInt32, 0, sizeof(SInt32), 0, &d); + pGraphicsMac->OnMouseWheel(x, y, &mmod, d); + return noErr; + } + } + } + break; + } + } + return eventNotHandledErr; +} + +// static +pascal void IGraphicsCarbon::CarbonTimerHandler(EventLoopTimerRef pTimer, void* pGraphicsCarbon) +{ + IGraphicsCarbon* _this = (IGraphicsCarbon*) pGraphicsCarbon; + IRECT r; + if (_this->mGraphicsMac->IsDirty(&r)) { + if (_this->mIsComposited) { + HIViewSetNeedsDisplayInRect(_this->mView, &CGRectMake(r.L, r.T, r.W(), r.H()), true); + } + else { + int h = _this->mGraphicsMac->Height(); + SetRectRgn(_this->mRgn, r.L, h - r.B, r.R, h - r.T); + UpdateControls(_this->mWindow, 0);// _this->mRgn); + } + } +} + +void ResizeWindow(WindowRef pWindow, int w, int h) +{ + Rect gr; // Screen. + GetWindowBounds(pWindow, kWindowContentRgn, &gr); + gr.right = gr.left + w; + gr.bottom = gr.top + h; + SetWindowBounds(pWindow, kWindowContentRgn, &gr); +} + +IGraphicsCarbon::IGraphicsCarbon(IGraphicsMac* pGraphicsMac, WindowRef pWindow, ControlRef pParentControl) +: mGraphicsMac(pGraphicsMac), mWindow(pWindow), mView(0), mTimer(0), mControlHandler(0), mWindowHandler(0), mCGC(0), + mContentXOffset(0), mContentYOffset(0) +{ + TRACE; + + Rect r; // Client. + r.left = r.top = 0; + r.right = pGraphicsMac->Width(); + r.bottom = pGraphicsMac->Height(); + //ResizeWindow(pWindow, r.right, r.bottom); + + WindowAttributes winAttrs = 0; + GetWindowAttributes(pWindow, &winAttrs); + mIsComposited = (winAttrs & kWindowCompositingAttribute); + mRgn = NewRgn(); + + UInt32 features = kControlSupportsFocus | kControlHandlesTracking | kControlSupportsEmbedding; + if (mIsComposited) { + features |= kHIViewIsOpaque | kHIViewFeatureDoesNotUseSpecialParts; + } + CreateUserPaneControl(pWindow, &r, features, &mView); + + const EventTypeSpec controlEvents[] = { + //{ kEventClassControl, kEventControlInitialize }, + //{kEventClassControl, kEventControlGetOptimalBounds}, + //{ kEventClassControl, kEventControlHitTest }, + { kEventClassControl, kEventControlClick }, + //{ kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassControl, kEventControlDraw }, + { kEventClassControl, kEventControlDispose }, + { kEventClassControl, kEventControlBoundsChanged } + }; + InstallControlEventHandler(mView, CarbonEventHandler, GetEventTypeCount(controlEvents), controlEvents, this, &mControlHandler); + + const EventTypeSpec windowEvents[] = { + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassMouse, kEventMouseWheelMoved } + }; + InstallWindowEventHandler(mWindow, CarbonEventHandler, GetEventTypeCount(windowEvents), windowEvents, this, &mWindowHandler); + + double t = 2.0*kEventDurationSecond/(double)pGraphicsMac->FPS(); + OSStatus s = InstallEventLoopTimer(GetMainEventLoop(), 0.0, t, CarbonTimerHandler, this, &mTimer); + + if (mIsComposited) { + if (!pParentControl) { + HIViewRef hvRoot = HIViewGetRoot(pWindow); + s = HIViewFindByID(hvRoot, kHIViewWindowContentID, &pParentControl); + } + s = HIViewAddSubview(pParentControl, mView); + } + else { + if (!pParentControl) { + if (GetRootControl(pWindow, &pParentControl) != noErr) { + CreateRootControl(pWindow, &pParentControl); + } + } + s = EmbedControl(mView, pParentControl); + } + + if (s == noErr) { + SizeControl(mView, r.right, r.bottom); // offset? + } +} + +IGraphicsCarbon::~IGraphicsCarbon() +{ + // Called from IGraphicsMac::CloseWindow. + RemoveEventLoopTimer(mTimer); + RemoveEventHandler(mControlHandler); + RemoveEventHandler(mWindowHandler); + mTimer = 0; + mView = 0; + DisposeRgn(mRgn); +} + +void IGraphicsCarbon::OffsetContentRect(CGRect* pR) +{ + *pR = CGRectOffset(*pR, (float) mContentXOffset, (float) mContentYOffset); +} + +bool IGraphicsCarbon::Resize(int w, int h) +{ + if (mWindow && mView) { + ResizeWindow(mWindow, w, h); + return (HIViewSetFrame(mView, &CGRectMake(0, 0, w, h)) == noErr); + } + return false; +} diff --git a/WDL/IPlug/IGraphicsCarbon.h b/WDL/IPlug/IGraphicsCarbon.h new file mode 100644 index 00000000..25a4850d --- /dev/null +++ b/WDL/IPlug/IGraphicsCarbon.h @@ -0,0 +1,37 @@ +#ifndef _IGRAPHICSCARBON_ +#define _IGRAPHICSCARBON_ + +#include +#include "IGraphicsMac.h" + +class IGraphicsCarbon +{ +public: + + IGraphicsCarbon(IGraphicsMac* pGraphicsMac, WindowRef pWindow, ControlRef pParentControl); + ~IGraphicsCarbon(); + + ControlRef GetView() { return mView; } + CGContextRef GetCGContext() { return mCGC; } + void OffsetContentRect(CGRect* pR); + bool Resize(int w, int h); + +private: + + IGraphicsMac* mGraphicsMac; + bool mIsComposited; + int mContentXOffset, mContentYOffset; + RgnHandle mRgn; + WindowRef mWindow; + ControlRef mView; // was HIViewRef + EventLoopTimerRef mTimer; + EventHandlerRef mControlHandler, mWindowHandler; + CGContextRef mCGC; + +public: + + static pascal OSStatus CarbonEventHandler(EventHandlerCallRef pHandlerCall, EventRef pEvent, void* pGraphicsCarbon); + static pascal void CarbonTimerHandler(EventLoopTimerRef pTimer, void* pGraphicsCarbon); +}; + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsCocoa.h b/WDL/IPlug/IGraphicsCocoa.h new file mode 100644 index 00000000..06cda044 --- /dev/null +++ b/WDL/IPlug/IGraphicsCocoa.h @@ -0,0 +1,40 @@ +#import +#include +#include +#import +#include "IGraphicsMac.h" + +// Cocoa objects can be supplied by any existing component, +// so we need to make sure the C++ static lib code gets the +// IGraphicsCocoa that it expects. +#define IGRAPHICS_COCOA IGraphicsCocoa_v1002 + +NSString* ToNSString(const char* cStr); + +inline CGRect ToCGRect(int h, IRECT* pR) +{ + int B = h - pR->B; + return CGRectMake(pR->L, B, pR->W(), B + pR->H()); +} + +@interface IGRAPHICS_COCOA : NSView +{ + IGraphicsMac* mGraphics; + NSTimer* mTimer; +} +- (id) init; +- (id) initWithIGraphics: (IGraphicsMac*) pGraphics; +- (BOOL) isOpaque; +- (BOOL) acceptsFirstResponder; +- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent; +- (void) viewDidMoveToWindow; +- (void) drawRect: (NSRect) rect; +- (void) onTimer: (NSTimer*) pTimer; +- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY; +- (void) mouseDown: (NSEvent*) pEvent; +- (void) mouseUp: (NSEvent*) pEvent; +- (void) mouseDragged: (NSEvent*) pEvent; +- (void) mouseMoved: (NSEvent*) pEvent; +- (void) scrollWheel: (NSEvent*) pEvent; +- (void) killTimer; +@end diff --git a/WDL/IPlug/IGraphicsCocoa.mm b/WDL/IPlug/IGraphicsCocoa.mm new file mode 100644 index 00000000..2aa138d6 --- /dev/null +++ b/WDL/IPlug/IGraphicsCocoa.mm @@ -0,0 +1,156 @@ +#include "IGraphicsCocoa.h" + +inline NSRect ToNSRect(IGraphics* pGraphics, IRECT* pR) +{ + int B = pGraphics->Height() - pR->B; + return NSMakeRect(pR->L, B, pR->W(), pR->H()); +} + +inline IRECT ToIRECT(IGraphics* pGraphics, NSRect* pR) +{ + int x = pR->origin.x, y = pR->origin.y, w = pR->size.width, h = pR->size.height, gh = pGraphics->Height(); + return IRECT(x, gh - (y + h), x + w, gh - y); +} + +NSString* ToNSString(const char* cStr) +{ + return [NSString stringWithCString:cStr]; +} + +inline IMouseMod GetMouseMod(NSEvent* pEvent) +{ + int mods = [pEvent modifierFlags]; + return IMouseMod(true, (mods & NSRightMouseDownMask) || (mods & NSCommandKeyMask), (mods & NSShiftKeyMask), (mods & NSControlKeyMask), (mods & NSAlternateKeyMask)); +} + +@implementation IGRAPHICS_COCOA + +- (id) init +{ + TRACE; + + mGraphics = 0; + mTimer = 0; + return self; +} + +- (id) initWithIGraphics: (IGraphicsMac*) pGraphics +{ + TRACE; + + mGraphics = pGraphics; + NSRect r; + r.origin.x = r.origin.y = 0.0f; + r.size.width = (float) pGraphics->Width(); + r.size.height = (float) pGraphics->Height(); + self = [super initWithFrame:r]; + + double sec = 1.0 / (double) pGraphics->FPS(); + mTimer = [NSTimer timerWithTimeInterval:sec target:self selector:@selector(onTimer:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer: mTimer forMode: (NSString*) kCFRunLoopCommonModes]; + + return self; +} + +- (BOOL) isOpaque +{ + return YES; +} + +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent +{ + return YES; +} + +- (void) viewDidMoveToWindow +{ + NSWindow* pWindow = [self window]; + if (pWindow) { + [pWindow makeFirstResponder: self]; + [pWindow setAcceptsMouseMovedEvents: YES]; + } +} + +- (void) drawRect: (NSRect) rect +{ + mGraphics->Draw(&ToIRECT(mGraphics, &rect)); +} + +- (void) onTimer: (NSTimer*) pTimer +{ + IRECT r; + if (pTimer == mTimer && mGraphics && mGraphics->IsDirty(&r)) { + [self setNeedsDisplayInRect:ToNSRect(mGraphics, &r)]; + } +} + +- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY +{ + NSPoint pt = [self convertPoint:[pEvent locationInWindow] fromView:nil]; + *pX = (int) pt.x; + *pY = mGraphics->Height() - (int) pt.y; +} + +- (void) mouseDown: (NSEvent*) pEvent +{ + int x, y; + [self getMouseXY:pEvent x:&x y:&y]; + if ([pEvent clickCount] > 1) { + mGraphics->OnMouseDblClick(x, y, &GetMouseMod(pEvent)); + } + else { + mGraphics->OnMouseDown(x, y, &GetMouseMod(pEvent)); + } +} + +- (void) mouseUp: (NSEvent*) pEvent +{ + int x, y; + [self getMouseXY:pEvent x:&x y:&y]; + mGraphics->OnMouseUp(x, y, &GetMouseMod(pEvent)); +} + +- (void) mouseDragged: (NSEvent*) pEvent +{ + int x, y; + [self getMouseXY:pEvent x:&x y:&y]; + mGraphics->OnMouseDrag(x, y, &GetMouseMod(pEvent)); +} + +- (void) mouseMoved: (NSEvent*) pEvent +{ + int x, y; + [self getMouseXY:pEvent x:&x y:&y]; + mGraphics->OnMouseOver(x, y, &GetMouseMod(pEvent)); +} + +- (void) scrollWheel: (NSEvent*) pEvent +{ + int x, y; + [self getMouseXY:pEvent x:&x y:&y]; + int d = [pEvent deltaY]; + mGraphics->OnMouseWheel(x, y, &GetMouseMod(pEvent), d); +} + +- (void) killTimer +{ + [mTimer invalidate]; + mTimer = 0; +} + +- (void) removeFromSuperview +{ + if (mGraphics) + { + IGraphics* graphics = mGraphics; + mGraphics = 0; + graphics->CloseWindow(); + } +} + +@end diff --git a/WDL/IPlug/IGraphicsLice.cpp b/WDL/IPlug/IGraphicsLice.cpp new file mode 100644 index 00000000..ead35474 --- /dev/null +++ b/WDL/IPlug/IGraphicsLice.cpp @@ -0,0 +1,295 @@ +#include "IGraphicsLice.h" +#include "IControl.h" +#include "math.h" +#include "Log.h" + +extern HINSTANCE gHInstance; + +class BitmapStorage +{ +public: + + struct BitmapKey + { + int id; + LICE_IBitmap* bitmap; + }; + + WDL_PtrList m_bitmaps; + WDL_Mutex m_mutex; + + LICE_IBitmap* Find(int id) + { + WDL_MutexLock lock(&m_mutex); + int i, n = m_bitmaps.GetSize(); + for (i = 0; i < n; ++i) + { + BitmapKey* key = m_bitmaps.Get(i); + if (key->id == id) return key->bitmap; + } + return 0; + } + + void Add(LICE_IBitmap* bitmap, int id = -1) + { + WDL_MutexLock lock(&m_mutex); + BitmapKey* key = m_bitmaps.Add(new BitmapKey); + key->id = id; + key->bitmap = bitmap; + } + + void Remove(LICE_IBitmap* bitmap) + { + WDL_MutexLock lock(&m_mutex); + int i, n = m_bitmaps.GetSize(); + for (i = 0; i < n; ++i) + { + if (m_bitmaps.Get(i)->bitmap == bitmap) + { + m_bitmaps.Delete(i, true); + delete(bitmap); + break; + } + } + } + + ~BitmapStorage() + { + int i, n = m_bitmaps.GetSize(); + for (i = 0; i < n; ++i) + { + delete(m_bitmaps.Get(i)->bitmap); + } + m_bitmaps.Empty(true); + } +}; + +static BitmapStorage s_bitmapCache; + +inline LICE_pixel LiceColor(const IColor* pColor) +{ + return LICE_RGBA(pColor->R, pColor->G, pColor->B, pColor->A); +} + +inline float LiceWeight(const IChannelBlend* pBlend) +{ + return (pBlend ? pBlend->mWeight : 1.0f); +} + +inline int LiceBlendMode(const IChannelBlend* pBlend) +{ + if (!pBlend) { + return LICE_BLIT_MODE_COPY | LICE_BLIT_USE_ALPHA; + } + switch (pBlend->mMethod) { + case IChannelBlend::kBlendClobber: { + return LICE_BLIT_MODE_COPY; + } + case IChannelBlend::kBlendAdd: { + return LICE_BLIT_MODE_ADD | LICE_BLIT_USE_ALPHA; + } + case IChannelBlend::kBlendColorDodge: { + return LICE_BLIT_MODE_DODGE | LICE_BLIT_USE_ALPHA; + } + case IChannelBlend::kBlendNone: + default: { + return LICE_BLIT_MODE_COPY | LICE_BLIT_USE_ALPHA; + } + } +} + +IGraphicsLice::IGraphicsLice(IPlugBase* pPlug, int w, int h, int refreshFPS) +: IGraphics(pPlug, w, h, refreshFPS), mDrawBitmap(0), mTmpBitmap(0) +{} + +IGraphicsLice::~IGraphicsLice() +{ + DELETE_NULL(mDrawBitmap); + DELETE_NULL(mTmpBitmap); +} + +IBitmap IGraphicsLice::LoadIBitmap(int ID, const char* name, int nStates) +{ + LICE_IBitmap* lb = s_bitmapCache.Find(ID); + if (!lb) + { + lb = OSLoadBitmap(ID, name); + bool imgResourceFound = (lb); + assert(imgResourceFound); // Protect against typos in resource.h and .rc files. + s_bitmapCache.Add(lb, ID); + } + return IBitmap(lb, lb->getWidth(), lb->getHeight(), nStates); +} + +void IGraphicsLice::RetainBitmap(IBitmap* pBitmap) +{ + s_bitmapCache.Add((LICE_IBitmap*)pBitmap->mData); +} + +void IGraphicsLice::ReleaseBitmap(IBitmap* pBitmap) +{ + s_bitmapCache.Remove((LICE_IBitmap*)pBitmap->mData); +} + +void IGraphicsLice::PrepDraw() +{ + mDrawBitmap = new LICE_SysBitmap(Width(), Height()); + mTmpBitmap = new LICE_MemBitmap(); +} + +bool IGraphicsLice::DrawBitmap(IBitmap* pIBitmap, IRECT* pDest, int srcX, int srcY, const IChannelBlend* pBlend) +{ + LICE_IBitmap* pLB = (LICE_IBitmap*) pIBitmap->mData; + IRECT r = pDest->Intersect(&mDrawRECT); + srcX += r.L - pDest->L; + srcY += r.T - pDest->T; + _LICE::LICE_Blit(mDrawBitmap, pLB, r.L, r.T, srcX, srcY, r.W(), r.H(), LiceWeight(pBlend), LiceBlendMode(pBlend)); + return true; +} + +bool IGraphicsLice::DrawRotatedBitmap(IBitmap* pIBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg, + const IChannelBlend* pBlend) +{ + LICE_IBitmap* pLB = (LICE_IBitmap*) pIBitmap->mData; + + //double dA = angle * PI / 180.0; + // Can't figure out what LICE_RotatedBlit is doing for irregular bitmaps exactly. + //double w = (double) bitmap.W; + //double h = (double) bitmap.H; + //double sinA = fabs(sin(dA)); + //double cosA = fabs(cos(dA)); + //int W = int(h * sinA + w * cosA); + //int H = int(h * cosA + w * sinA); + + int W = pIBitmap->W; + int H = pIBitmap->H; + int destX = destCtrX - W / 2; + int destY = destCtrY - H / 2; + + _LICE::LICE_RotatedBlit(mDrawBitmap, pLB, destX, destY, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) angle, + false, LiceWeight(pBlend), LiceBlendMode(pBlend) | LICE_BLIT_FILTER_BILINEAR, 0.0f, (float) yOffsetZeroDeg); + + return true; +} + +bool IGraphicsLice::DrawRotatedMask(IBitmap* pIBase, IBitmap* pIMask, IBitmap* pITop, int x, int y, double angle, + const IChannelBlend* pBlend) +{ + LICE_IBitmap* pBase = (LICE_IBitmap*) pIBase->mData; + LICE_IBitmap* pMask = (LICE_IBitmap*) pIMask->mData; + LICE_IBitmap* pTop = (LICE_IBitmap*) pITop->mData; + + double dA = angle * PI / 180.0; + int W = pIBase->W; + int H = pIBase->H; +// RECT srcR = { 0, 0, W, H }; + float xOffs = (W % 2 ? -0.5f : 0.0f); + + if (!mTmpBitmap) { + mTmpBitmap = new LICE_MemBitmap(); + } + _LICE::LICE_Copy(mTmpBitmap, pBase); + _LICE::LICE_ClearRect(mTmpBitmap, 0, 0, W, H, LICE_RGBA(255, 255, 255, 0)); + + _LICE::LICE_RotatedBlit(mTmpBitmap, pMask, 0, 0, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) dA, + true, 1.0f, LICE_BLIT_MODE_ADD | LICE_BLIT_FILTER_BILINEAR | LICE_BLIT_USE_ALPHA, xOffs, 0.0f); + _LICE::LICE_RotatedBlit(mTmpBitmap, pTop, 0, 0, W, H, 0.0f, 0.0f, (float) W, (float) H, (float) dA, + true, 1.0f, LICE_BLIT_MODE_COPY | LICE_BLIT_FILTER_BILINEAR | LICE_BLIT_USE_ALPHA, xOffs, 0.0f); + + IRECT r = IRECT(x, y, x + W, y + H).Intersect(&mDrawRECT); + _LICE::LICE_Blit(mDrawBitmap, mTmpBitmap, r.L, r.T, r.L - x, r.T - y, r.R - r.L, r.B - r.T, + LiceWeight(pBlend), LiceBlendMode(pBlend)); +// ReaperExt::LICE_Blit(mDrawBitmap, mTmpBitmap, x, y, &srcR, LiceWeight(pBlend), LiceBlendMode(pBlend)); + return true; +} + +bool IGraphicsLice::DrawPoint(const IColor* pColor, float x, float y, + const IChannelBlend* pBlend, bool antiAlias) +{ + float weight = (pBlend ? pBlend->mWeight : 1.0f); + _LICE::LICE_PutPixel(mDrawBitmap, int(x + 0.5f), int(y + 0.5f), LiceColor(pColor), weight, LiceBlendMode(pBlend)); + return true; +} + +bool IGraphicsLice::ForcePixel(const IColor* pColor, int x, int y) +{ + LICE_pixel* px = mDrawBitmap->getBits(); + px += x + y * mDrawBitmap->getRowSpan(); + *px = LiceColor(pColor); + return true; +} + +bool IGraphicsLice::DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, + const IChannelBlend* pBlend, bool antiAlias) +{ + _LICE::LICE_Line(mDrawBitmap, x1, y1, x2, y2, LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); + return true; +} + +bool IGraphicsLice::DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, + const IChannelBlend* pBlend, bool antiAlias) +{ + _LICE::LICE_Arc(mDrawBitmap, cx, cy, r, minAngle, maxAngle, LiceColor(pColor), + LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); + return true; +} + +bool IGraphicsLice::DrawCircle(const IColor* pColor, float cx, float cy, float r, + const IChannelBlend* pBlend, bool antiAlias) +{ + _LICE::LICE_Circle(mDrawBitmap, cx, cy, r, LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend), antiAlias); + return true; +} + +bool IGraphicsLice::FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend) +{ + _LICE::LICE_FillRect(mDrawBitmap, pR->L, pR->T, pR->W(), pR->H(), LiceColor(pColor), LiceWeight(pBlend), LiceBlendMode(pBlend)); + return true; +} + +IColor IGraphicsLice::GetPoint(int x, int y) +{ + LICE_pixel pix = _LICE::LICE_GetPixel(mDrawBitmap, x, y); + return IColor(LICE_GETA(pix), LICE_GETR(pix), LICE_GETG(pix), LICE_GETB(pix)); +} + +bool IGraphicsLice::DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi) +{ + _LICE::LICE_Line(mDrawBitmap, (float)xi, (float)yLo, (float)xi, (float)yHi, LiceColor(pColor), 1.0f, LICE_BLIT_MODE_COPY, false); + return true; +} + +bool IGraphicsLice::DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi) +{ + _LICE::LICE_Line(mDrawBitmap, (float)xLo, (float)yi, (float)xHi, (float)yi, LiceColor(pColor), 1.0f, LICE_BLIT_MODE_COPY, false); + return true; +} + +IBitmap IGraphicsLice::ScaleBitmap(IBitmap* pIBitmap, int destW, int destH) +{ + LICE_IBitmap* pSrc = (LICE_IBitmap*) pIBitmap->mData; + LICE_MemBitmap* pDest = new LICE_MemBitmap(destW, destH); + _LICE::LICE_ScaledBlit(pDest, pSrc, 0, 0, destW, destH, 0.0f, 0.0f, (float) pIBitmap->W, (float) pIBitmap->H, 1.0f, + LICE_BLIT_MODE_COPY | LICE_BLIT_FILTER_BILINEAR); + + IBitmap bmp(pDest, destW, destH, pIBitmap->N); + RetainBitmap(&bmp); + return bmp; +} + +IBitmap IGraphicsLice::CropBitmap(IBitmap* pIBitmap, IRECT* pR) +{ + int destW = pR->W(), destH = pR->H(); + LICE_IBitmap* pSrc = (LICE_IBitmap*) pIBitmap->mData; + LICE_MemBitmap* pDest = new LICE_MemBitmap(destW, destH); + _LICE::LICE_Blit(pDest, pSrc, 0, 0, pR->L, pR->T, destW, destH, 1.0f, LICE_BLIT_MODE_COPY); + + IBitmap bmp(pDest, destW, destH, pIBitmap->N); + RetainBitmap(&bmp); + return bmp; +} + +LICE_pixel* IGraphicsLice::GetBits() +{ + return mDrawBitmap->getBits(); +} \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsLice.h b/WDL/IPlug/IGraphicsLice.h new file mode 100644 index 00000000..44c00256 --- /dev/null +++ b/WDL/IPlug/IGraphicsLice.h @@ -0,0 +1,68 @@ +#ifndef _IGRAPHICSLICE_ +#define _IGRAPHICSLICE_ + +#include "IControl.h" +#include "../lice/lice.h" + +// Specialty stuff for calling in to Reaper for Lice functionality. +#ifdef REAPER_SPECIAL + #include "../IPlugExt/ReaperExt.h" + #define _LICE ReaperExt +#else + #define _LICE +#endif + +class IGraphicsLice : public IGraphics +{ +public: + + IGraphicsLice(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); + ~IGraphicsLice(); + + void PrepDraw(); + + bool DrawBitmap(IBitmap* pBitmap, IRECT* pDest, int srcX, int srcY, + const IChannelBlend* pBlend = 0); + virtual bool DrawRotatedBitmap(IBitmap* pBitmap, int destCtrX, int destCtrY, double angle, int yOffsetZeroDeg = 0, + const IChannelBlend* pBlend = 0); + virtual bool DrawRotatedMask(IBitmap* pBase, IBitmap* pMask, IBitmap* pTop, int x, int y, double angle, + const IChannelBlend* pBlend = 0); + bool DrawPoint(const IColor* pColor, float x, float y, + const IChannelBlend* pBlend = 0, bool antiAlias = false); + bool ForcePixel(const IColor* pColor, int x, int y); + bool DrawLine(const IColor* pColor, float x1, float y1, float x2, float y2, + const IChannelBlend* pBlend = 0, bool antiAlias = false); + bool DrawArc(const IColor* pColor, float cx, float cy, float r, float minAngle, float maxAngle, + const IChannelBlend* pBlend = 0, bool antiAlias = false); + bool DrawCircle(const IColor* pColor, float cx, float cy, float r, + const IChannelBlend* pBlend = 0, bool antiAlias = false); + bool FillIRect(const IColor* pColor, IRECT* pR, const IChannelBlend* pBlend = 0); + IColor GetPoint(int x, int y); + void* GetData() { return GetBits(); } + bool DrawVerticalLine(const IColor* pColor, int xi, int yLo, int yHi); + bool DrawHorizontalLine(const IColor* pColor, int yi, int xLo, int xHi); + + // The backing store for any bitmaps created by LoadIBitmap, ScaleBitmap, or CropBitmap, + // or any bitmaps passed to RetainBitmap, will be retained across all plugin instances + // until explicitly released, or until the dll completely unloads. + + IBitmap LoadIBitmap(int ID, const char* name, int nStates = 1); + + // Specialty use... + IBitmap ScaleBitmap(IBitmap* pBitmap, int destW, int destH); + IBitmap CropBitmap(IBitmap* pBitmap, IRECT* pR); + void RetainBitmap(IBitmap* pBitmap); + void ReleaseBitmap(IBitmap* pBitmap); + LICE_pixel* GetBits(); + +protected: + virtual LICE_IBitmap* OSLoadBitmap(int ID, const char* name) = 0; + LICE_SysBitmap* mDrawBitmap; + +private: + LICE_MemBitmap* mTmpBitmap; +}; + +//////////////////////////////////////// + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsMac.h b/WDL/IPlug/IGraphicsMac.h new file mode 100644 index 00000000..ddb82df0 --- /dev/null +++ b/WDL/IPlug/IGraphicsMac.h @@ -0,0 +1,96 @@ +#ifndef _IGRAPHICSMAC_ +#define _IGRAPHICSMAC_ + +#include "IGraphicsLice.h" +#include "../swell/swell.h" +#include + +class IGraphicsCarbon; +class NSMutableDictionary; + +class IGraphicsMac : public IGraphicsLice +{ +public: + + IGraphicsMac(IPlugBase* pPlug, int w, int h, int refreshFPS = FPS); + virtual ~IGraphicsMac(); + + void SetBundleID(const char* bundleID) { mBundleID.Set(bundleID); } + + bool DrawScreen(IRECT* pR); + + void* OpenWindow(void* pWindow); + void* OpenWindow(void* pWindow, void* pControl); + + void* OpenCocoaWindow(void* pParentView); + void* OpenCarbonWindow(void* pParentWnd, void* pParentControl); + + void CloseWindow(); + bool WindowIsOpen(); + void Resize(int w, int h); + + void HostPath(WDL_String* pPath); + void PluginPath(WDL_String* pPath); + + void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = "", + char* extensions = ""); // extensions = "txt wav" for example. + bool PromptForColor(IColor* pColor, char* prompt = ""); + void PromptUserInput(IControl* pControl, IParam* pParam); + bool OpenURL(const char* url, const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0); + + void* GetWindow(); + + int mIdleTicks; + + const char* GetBundleID() { return mBundleID.Get(); } + static int GetUserOSVersion(); // Returns a number like 0x1050 (10.5). + bool DrawIText(IText* pTxt, char* str, IRECT* pR); + +protected: + + virtual LICE_IBitmap* OSLoadBitmap(int ID, const char* name); + +private: + + IGraphicsCarbon* mGraphicsCarbon; + void* mGraphicsCocoa; // Can't forward-declare IGraphicsCocoa because it's an obj-C object. + + WDL_String mBundleID; + NSMutableDictionary* mTxtAttrs; + IText mTxt; +}; + +inline CFStringRef MakeCFString(const char* cStr) +{ + return CFStringCreateWithCString(0, cStr, kCFStringEncodingUTF8); +} + +struct CFStrLocal +{ + CFStringRef mCFStr; + CFStrLocal(const char* cStr) + { + mCFStr = MakeCFString(cStr); + } + ~CFStrLocal() + { + CFRelease(mCFStr); + } +}; + +struct CStrLocal +{ + char* mCStr; + CStrLocal(CFStringRef cfStr) + { + int n = CFStringGetLength(cfStr) + 1; + mCStr = (char*) malloc(n); + CFStringGetCString(cfStr, mCStr, n, kCFStringEncodingUTF8); + } + ~CStrLocal() + { + FREE_NULL(mCStr); + } +}; + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsMac.mm b/WDL/IPlug/IGraphicsMac.mm new file mode 100644 index 00000000..3bdf62c2 --- /dev/null +++ b/WDL/IPlug/IGraphicsMac.mm @@ -0,0 +1,313 @@ +#include +#include "IGraphicsMac.h" +#include "IControl.h" +#include "Log.h" +#import "IGraphicsCocoa.h" +#include "IGraphicsCarbon.h" +#include "../swell/swell-internal.h" + +struct CocoaAutoReleasePool +{ + NSAutoreleasePool* mPool; + + CocoaAutoReleasePool() + { + mPool = [[NSAutoreleasePool alloc] init]; + } + + ~CocoaAutoReleasePool() + { + [mPool release]; + } +}; + +inline NSColor* ToNSColor(IColor* pColor) +{ + double r = (double) pColor->R / 255.0; + double g = (double) pColor->G / 255.0; + double b = (double) pColor->B / 255.0; + double a = (double) pColor->A / 255.0; + return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a]; +} + +IGraphicsMac::IGraphicsMac(IPlugBase* pPlug, int w, int h, int refreshFPS) +: IGraphicsLice(pPlug, w, h, refreshFPS), mGraphicsCarbon(0), mGraphicsCocoa(0), mTxtAttrs(0) +{ + NSApplicationLoad(); + +} + +IGraphicsMac::~IGraphicsMac() +{ + CloseWindow(); + if (mTxtAttrs) { + [mTxtAttrs release]; + mTxtAttrs = 0; + } +} + +LICE_IBitmap* LoadImgFromResourceOSX(const char* bundleID, const char* filename) +{ + if (!filename) return 0; + CocoaAutoReleasePool pool; + + const char* ext = filename+strlen(filename)-1; + while (ext >= filename && *ext != '.') --ext; + ++ext; + + bool ispng = !stricmp(ext, "png"); + bool isjpg = !stricmp(ext, "jpg"); + if (!ispng && !isjpg) return 0; + + NSBundle* pBundle = [NSBundle bundleWithIdentifier:ToNSString(bundleID)]; + NSString* pFile = [[[NSString stringWithCString:filename] lastPathComponent] stringByDeletingPathExtension]; + if (pBundle && pFile) + { + NSString* pPath = 0; + if (ispng) pPath = [pBundle pathForResource:pFile ofType:@"png"]; + if (isjpg) pPath = [pBundle pathForResource:pFile ofType:@"jpg"]; + + if (pPath) + { + const char* resourceFileName = [pPath cString]; + if (CSTR_NOT_EMPTY(resourceFileName)) + { + if (ispng) return LICE_LoadPNG(resourceFileName); + if (isjpg) return LICE_LoadJPG(resourceFileName); + } + } + } + return 0; +} + +LICE_IBitmap* IGraphicsMac::OSLoadBitmap(int ID, const char* name) +{ + return LoadImgFromResourceOSX(GetBundleID(), name); +} + +bool IGraphicsMac::DrawScreen(IRECT* pR) +{ + CGContextRef pCGC = 0; + CGRect r = CGRectMake(0, 0, Width(), Height()); + if (mGraphicsCocoa) { + pCGC = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; // Leak? + NSGraphicsContext* gc = [NSGraphicsContext graphicsContextWithGraphicsPort: pCGC flipped: YES]; + pCGC = (CGContextRef) [gc graphicsPort]; + } + else + if (mGraphicsCarbon) { + pCGC = mGraphicsCarbon->GetCGContext(); + mGraphicsCarbon->OffsetContentRect(&r); + // Flipping is handled in IGraphicsCarbon. + } + if (!pCGC) { + return false; + } + + HDC__ * srcCtx = (HDC__*) mDrawBitmap->getDC(); + CGImageRef img = CGBitmapContextCreateImage(srcCtx->ctx); + CGContextDrawImage(pCGC, r, img); + CGImageRelease(img); + return true; +} + +void* IGraphicsMac::OpenWindow(void* pParent) +{ + return OpenCocoaWindow(pParent); +} + +void* IGraphicsMac::OpenWindow(void* pWindow, void* pControl) +{ + return OpenCarbonWindow(pWindow, pControl); +} + +void* IGraphicsMac::OpenCocoaWindow(void* pParentView) +{ + TRACE; + CloseWindow(); + mGraphicsCocoa = (IGRAPHICS_COCOA*) [[IGRAPHICS_COCOA alloc] initWithIGraphics: this]; + if (pParentView) { // Cocoa VST host. + [(NSView*) pParentView addSubview: (IGRAPHICS_COCOA*) mGraphicsCocoa]; + } + // Else we are being called by IGraphicsCocoaFactory, which is being called by a Cocoa AU host, + // and the host will take care of attaching the view to the window. + return mGraphicsCocoa; +} + +void* IGraphicsMac::OpenCarbonWindow(void* pParentWnd, void* pParentControl) +{ + TRACE; + CloseWindow(); + WindowRef pWnd = (WindowRef) pParentWnd; + ControlRef pControl = (ControlRef) pParentControl; + // On 10.5 or later we could have used HICocoaViewCreate, but for 10.4 we have to support Carbon explicitly. + mGraphicsCarbon = new IGraphicsCarbon(this, pWnd, pControl); + return mGraphicsCarbon->GetView(); +} + +void IGraphicsMac::CloseWindow() +{ + if (mGraphicsCarbon) + { + DELETE_NULL(mGraphicsCarbon); + } + else + if (mGraphicsCocoa) + { + IGRAPHICS_COCOA* graphicscocoa = (IGRAPHICS_COCOA*)mGraphicsCocoa; + [graphicscocoa killTimer]; + mGraphicsCocoa = 0; + if (graphicscocoa->mGraphics) + { + graphicscocoa->mGraphics = 0; + [graphicscocoa removeFromSuperview]; // Releases. + } + + } +} + +bool IGraphicsMac::WindowIsOpen() +{ + return (mGraphicsCarbon || mGraphicsCocoa); +} + +void IGraphicsMac::Resize(int w, int h) +{ + IGraphics::Resize(w, h); + if (mDrawBitmap) { + mDrawBitmap->resize(w, h); + } + + if (mGraphicsCarbon) { + mGraphicsCarbon->Resize(w, h); + } + else + if (mGraphicsCocoa) { + NSSize size = { w, h }; + [(IGRAPHICS_COCOA*) mGraphicsCocoa setFrameSize: size ]; + } +} + +void IGraphicsMac::HostPath(WDL_String* pPath) +{ + CocoaAutoReleasePool pool; + NSBundle* pBundle = [NSBundle bundleWithIdentifier: ToNSString(GetBundleID())]; + if (pBundle) { + NSString* path = [pBundle executablePath]; + if (path) { + pPath->Set([path cString]); + } + } +} + +void IGraphicsMac::PluginPath(WDL_String* pPath) +{ + CocoaAutoReleasePool pool; + NSBundle* pBundle = [NSBundle bundleWithIdentifier: ToNSString(GetBundleID())]; + if (pBundle) { + NSString* path = [[pBundle bundlePath] stringByDeletingLastPathComponent]; + if (path) { + pPath->Set([path cString]); + pPath->Append("/"); + } + } +} + +// extensions = "txt wav" for example +void IGraphicsMac::PromptForFile(WDL_String* pFilename, EFileAction action, char* dir, char* extensions) +{ +} + +bool IGraphicsMac::PromptForColor(IColor* pColor, char* prompt) +{ + return false; +} + +void IGraphicsMac::PromptUserInput(IControl* pControl, IParam* pParam) +{ +} + +bool IGraphicsMac::OpenURL(const char* url, + const char* msgWindowTitle, const char* confirmMsg, const char* errMsgOnFailure) +{ +#pragma REMINDER("Warning and error messages for OpenURL not implemented") + NSURL* pURL = 0; + if (strstr(url, "http")) { + pURL = [NSURL URLWithString:ToNSString(url)]; + } + else { + pURL = [NSURL fileURLWithPath:ToNSString(url)]; + } + if (pURL) { + bool ok = ([[NSWorkspace sharedWorkspace] openURL:pURL]); + // [pURL release]; + return ok; + } + return true; +} + +void* IGraphicsMac::GetWindow() +{ + return mGraphicsCocoa; +} + +// static +int IGraphicsMac::GetUserOSVersion() // Returns a number like 0x1050 (10.5). +{ + SInt32 ver = 0; + Gestalt(gestaltSystemVersion, &ver); + Trace(TRACELOC, "%x", ver); + return ver; +} + +bool IGraphicsMac::DrawIText(IText* pTxt, char* cStr, IRECT* pR) +{ + bool init = (mTxtAttrs); + if (!init) { + mTxtAttrs = [[NSMutableDictionary alloc] init]; + } + + int fontSize = int(0.75 * (double) pTxt->mSize); + int yAdj = fontSize / 4; + bool antialias = (fontSize >= 12); + + if (!init) { // || strcmp(pTxt->mFont, mTxt.mFont)) { + NSFont* font = [NSFont fontWithName: ToNSString(pTxt->mFont) size: fontSize]; + [mTxtAttrs setValue: font forKey: NSFontAttributeName]; + strcpy(mTxt.mFont, pTxt->mFont); + } + + if (!init || pTxt->mColor != mTxt.mColor) { + [mTxtAttrs setValue: ToNSColor(&(pTxt->mColor)) forKey: NSForegroundColorAttributeName]; + mTxt.mColor = pTxt->mColor; + } + + if (!init || pTxt->mAlign != mTxt.mAlign) { + NSTextAlignment align; + switch (pTxt->mAlign) { + case IText::kAlignNear: align = NSLeftTextAlignment; break; + case IText::kAlignFar: align = NSRightTextAlignment; break; + case IText::kAlignCenter: + default: align = NSCenterTextAlignment; break; + } + NSMutableParagraphStyle* paraStyle = [[NSMutableParagraphStyle alloc] init]; + [paraStyle setAlignment: align]; + [mTxtAttrs setValue: paraStyle forKey: NSParagraphStyleAttributeName]; + [paraStyle release]; + mTxt.mAlign = pTxt->mAlign; + } + + [NSGraphicsContext saveGraphicsState]; + HDC__* destCtx = (HDC__*) mDrawBitmap->getDC(); + NSGraphicsContext* destGC = [NSGraphicsContext graphicsContextWithGraphicsPort:destCtx->ctx flipped:YES]; + [destGC setShouldAntialias: antialias]; + [NSGraphicsContext setCurrentContext:destGC]; + NSRect r = { pR->L, pR->T+yAdj+6, pR->W(), pR->H() }; + NSString* str = ToNSString(cStr); + [str drawWithRect:r options: NSStringDrawingUsesDeviceMetrics attributes: mTxtAttrs]; + [NSGraphicsContext restoreGraphicsState]; + + return true; +} + + \ No newline at end of file diff --git a/WDL/IPlug/IGraphicsWin.cpp b/WDL/IPlug/IGraphicsWin.cpp new file mode 100644 index 00000000..9c2a5c16 --- /dev/null +++ b/WDL/IPlug/IGraphicsWin.cpp @@ -0,0 +1,718 @@ +#include "IGraphicsWin.h" +#include "IControl.h" +#include "Log.h" +#include + +#pragma warning(disable:4244) // Pointer size cast mismatch. +#pragma warning(disable:4312) // Pointer size cast mismatch. +#pragma warning(disable:4311) // Pointer size cast mismatch. + +static int nWndClassReg = 0; +static const char* wndClassName = "IPlugWndClass"; +static double sFPS = 0.0; + +#define MAX_PARAM_LEN 32 +#define PARAM_EDIT_ID 99 + +enum EParamEditMsg { + kNone, + kEditing, + kUpdate, + kCancel, + kCommit +}; + +#define IPLUG_TIMER_ID 2 + +inline IMouseMod GetMouseMod(WPARAM wParam) +{ + return IMouseMod((wParam & MK_LBUTTON), (wParam & MK_RBUTTON), + (wParam & MK_SHIFT), (wParam & MK_CONTROL), GetKeyState(VK_MENU) < 0); +} + +// static +LRESULT CALLBACK IGraphicsWin::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_CREATE) { + LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM) (lpcs->lpCreateParams)); + int mSec = int(1000.0 / sFPS); + SetTimer(hWnd, IPLUG_TIMER_ID, mSec, NULL); + return 0; + } + + IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); + char txt[MAX_PARAM_LEN]; + double v; + + if (!pGraphics || hWnd != pGraphics->mPlugWnd) { + return DefWindowProc(hWnd, msg, wParam, lParam); + } + if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg == kEditing) { + if (msg == WM_RBUTTONDOWN) { + pGraphics->mParamEditMsg = kCancel; + return 0; + } + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + switch (msg) { + + case WM_TIMER: { + if (wParam == IPLUG_TIMER_ID) { + + if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg != kNone) { + switch (pGraphics->mParamEditMsg) { + case kUpdate: { + pGraphics->mEdParam->GetDisplayForHost(txt); + SendMessage(pGraphics->mParamEditWnd, WM_SETTEXT, 0, (LPARAM) txt); + break; + } + case kCommit: { + SendMessage(pGraphics->mParamEditWnd, WM_GETTEXT, MAX_PARAM_LEN, (LPARAM) txt); + if (pGraphics->mEdParam->GetNDisplayTexts()) { + int vi = 0; + pGraphics->mEdParam->MapDisplayText(txt, &vi); + v = (double) vi; + } + else { + v = atof(txt); + if (pGraphics->mEdParam->DisplayIsNegated()) { + v = -v; + } + } + pGraphics->mEdControl->SetValueFromUserInput(pGraphics->mEdParam->GetNormalized(v)); + // Fall through. + } + case kCancel: + { + SetWindowLongPtr(pGraphics->mParamEditWnd, GWLP_WNDPROC, (LPARAM) pGraphics->mDefEditProc); + DestroyWindow(pGraphics->mParamEditWnd); + pGraphics->mParamEditWnd = 0; + pGraphics->mEdParam = 0; + pGraphics->mEdControl = 0; + pGraphics->mDefEditProc = 0; + } + break; + } + pGraphics->mParamEditMsg = kNone; + return 0; + } + + IRECT dirtyR; + if (pGraphics->IsDirty(&dirtyR)) { + RECT r = { dirtyR.L, dirtyR.T, dirtyR.R, dirtyR.B }; + InvalidateRect(hWnd, &r, FALSE); + UpdateWindow(hWnd); + if (pGraphics->mParamEditWnd) { + pGraphics->mParamEditMsg = kUpdate; + } + } + } + return 0; + } + case WM_RBUTTONDOWN: { + if (pGraphics->mParamEditWnd) { + pGraphics->mParamEditMsg = kCancel; + return 0; + } + // Else fall through. + } + case WM_LBUTTONDOWN: { + SetCapture(hWnd); + pGraphics->OnMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); + return 0; + } + case WM_MOUSEMOVE: { + if (!(wParam & (MK_LBUTTON | MK_RBUTTON))) { + if (pGraphics->OnMouseOver(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { + TRACKMOUSEEVENT eventTrack = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hWnd, HOVER_DEFAULT }; + TrackMouseEvent(&eventTrack); + } + } + else + if (GetCapture() == hWnd) { + pGraphics->OnMouseDrag(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); + } + return 0; + } + case WM_MOUSELEAVE: { + pGraphics->OnMouseOut(); + return 0; + } + case WM_LBUTTONUP: + case WM_RBUTTONUP: { + ReleaseCapture(); + pGraphics->OnMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); + return 0; + } + case WM_LBUTTONDBLCLK: { + if (pGraphics->OnMouseDblClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { + SetCapture(hWnd); + } + return 0; + } + case WM_MOUSEWHEEL: { + int d = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; + int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); + RECT r; + GetWindowRect(hWnd, &r); + pGraphics->OnMouseWheel(x - r.left, y - r.top, &GetMouseMod(wParam), d); + return 0; + } + + case WM_KEYDOWN: + { + bool ok = true; + int key; + + if (wParam == VK_SPACE) key = KEY_SPACE; + else if (wParam == VK_UP) key = KEY_UPARROW; + else if (wParam == VK_DOWN) key = KEY_DOWNARROW; + else if (wParam == VK_LEFT) key = KEY_LEFTARROW; + else if (wParam == VK_RIGHT) key = KEY_RIGHTARROW; + else if (wParam >= '0' && wParam <= '9') key = KEY_DIGIT_0+wParam-'0'; + else if (wParam >= 'A' && wParam <= 'Z') key = KEY_ALPHA_A+wParam-'A'; + else if (wParam >= 'a' && wParam <= 'z') key = KEY_ALPHA_A+wParam-'a'; + else ok = false; + + if (ok) + { + POINT p; + GetCursorPos(&p); + ScreenToClient(hWnd, &p); + pGraphics->OnKeyDown(p.x, p.y, key); + } + } + return 0; + + case WM_PAINT: { + RECT r; + if (GetUpdateRect(hWnd, &r, FALSE)) { + IRECT ir(r.left, r.top, r.right, r.bottom); + pGraphics->Draw(&ir); + } + return 0; + } + + //case WM_CTLCOLOREDIT: { + // // An edit control just opened. + // HDC dc = (HDC) wParam; + // SetTextColor(dc, ///); + // return 0; + //} + + case WM_CLOSE: { + pGraphics->CloseWindow(); + return 0; + } + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +// static +LRESULT CALLBACK IGraphicsWin::ParamEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); + + if (pGraphics && pGraphics->mParamEditWnd && pGraphics->mParamEditWnd == hWnd) + { + switch (msg) { + case WM_KEYDOWN: { + if (wParam == VK_RETURN) { + pGraphics->mParamEditMsg = kCommit; + return 0; + } + break; + } + case WM_SETFOCUS: { + pGraphics->mParamEditMsg = kEditing; + break; + } + case WM_KILLFOCUS: { + pGraphics->mParamEditMsg = kNone; + break; + } + case WM_COMMAND: { + switch HIWORD(wParam) { + case CBN_SELCHANGE: { + if (pGraphics->mParamEditWnd) { + pGraphics->mParamEditMsg = kCommit; + return 0; + } + } + + } + break; // Else let the default proc handle it. + } + } + return CallWindowProc(pGraphics->mDefEditProc, hWnd, msg, wParam, lParam); + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +IGraphicsWin::IGraphicsWin(IPlugBase* pPlug, int w, int h, int refreshFPS) +: IGraphicsLice(pPlug, w, h, refreshFPS), mPlugWnd(0), mParamEditWnd(0), + mPID(0), mParentWnd(0), mMainWnd(0), mCustomColorStorage(0), + mEdControl(0), mEdParam(0), mDefEditProc(0), mParamEditMsg(kNone), mIdleTicks(0), + mFontActive(false), mHInstance(0) +{ +} + +IGraphicsWin::~IGraphicsWin() +{ + CloseWindow(); + FREE_NULL(mCustomColorStorage); +} + +LICE_IBitmap* IGraphicsWin::OSLoadBitmap(int ID, const char* name) +{ + const char* ext = name+strlen(name)-1; + while (ext > name && *ext != '.') --ext; + ++ext; + + if (!stricmp(ext, "png")) return _LICE::LICE_LoadPNGFromResource(mHInstance, ID, 0); + if (!stricmp(ext, "jpg") || !stricmp(ext, "jpeg")) return _LICE::LICE_LoadJPGFromResource(mHInstance, ID, 0); + return 0; +} + +void GetWindowSize(HWND pWnd, int* pW, int* pH) +{ + if (pWnd) { + RECT r; + GetWindowRect(pWnd, &r); + *pW = r.right - r.left; + *pH = r.bottom - r.top; + } + else { + *pW = *pH = 0; + } +} + +bool IsChildWindow(HWND pWnd) +{ + if (pWnd) { + int style = GetWindowLong(pWnd, GWL_STYLE); + int exStyle = GetWindowLong(pWnd, GWL_EXSTYLE); + return ((style & WS_CHILD) && !(exStyle & WS_EX_MDICHILD)); + } + return false; +} + +#define SETPOS_FLAGS SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE + +void IGraphicsWin::Resize(int w, int h) +{ + int dw = w - Width(), dh = h - Height(); + IGraphics::Resize(w, h); + if (mDrawBitmap) { + mDrawBitmap->resize(w, h); + } + if (WindowIsOpen()) { + HWND pParent = 0, pGrandparent = 0; + int w = 0, h = 0, parentW = 0, parentH = 0, grandparentW = 0, grandparentH = 0; + GetWindowSize(mPlugWnd, &w, &h); + if (IsChildWindow(mPlugWnd)) { + pParent = GetParent(mPlugWnd); + GetWindowSize(pParent, &parentW, &parentH); + if (IsChildWindow(pParent)) { + pGrandparent = GetParent(pParent); + GetWindowSize(pGrandparent, &grandparentW, &grandparentH); + } + } + SetWindowPos(mPlugWnd, 0, 0, 0, w + dw, h + dh, SETPOS_FLAGS); + if (pParent) { + SetWindowPos(pParent, 0, 0, 0, parentW + dw, parentH + dh, SETPOS_FLAGS); + } + if (pGrandparent) { + SetWindowPos(pGrandparent, 0, 0, 0, grandparentW + dw, grandparentH + dh, SETPOS_FLAGS); + } + + RECT r = { 0, 0, w, h }; + InvalidateRect(mPlugWnd, &r, FALSE); + } +} + +bool IGraphicsWin::DrawScreen(IRECT* pR) +{ + PAINTSTRUCT ps; + HWND hWnd = (HWND) GetWindow(); + HDC dc = BeginPaint(hWnd, &ps); + BitBlt(dc, pR->L, pR->T, pR->W(), pR->H(), mDrawBitmap->getDC(), pR->L, pR->T, SRCCOPY); + EndPaint(hWnd, &ps); + return true; +} + +void* IGraphicsWin::OpenWindow(void* pParentWnd) +{ + int x = 0, y = 0, w = Width(), h = Height(); + mParentWnd = (HWND) pParentWnd; + + if (mPlugWnd) { + RECT pR, cR; + GetWindowRect((HWND) pParentWnd, &pR); + GetWindowRect(mPlugWnd, &cR); + CloseWindow(); + x = cR.left - pR.left; + y = cR.top - pR.top; + w = cR.right - cR.left; + h = cR.bottom - cR.top; + } + + if (nWndClassReg++ == 0) { + WNDCLASS wndClass = { CS_DBLCLKS, WndProc, 0, 0, mHInstance, 0, LoadCursor(NULL, IDC_ARROW), 0, 0, wndClassName }; + RegisterClass(&wndClass); + } + + sFPS = FPS(); + mPlugWnd = CreateWindow(wndClassName, "IPlug", WS_CHILD | WS_VISIBLE, // | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + x, y, w, h, (HWND) pParentWnd, 0, mHInstance, this); + //SetWindowLong(mPlugWnd, GWL_USERDATA, (LPARAM) this); + + if (!mPlugWnd && --nWndClassReg == 0) { + UnregisterClass(wndClassName, mHInstance); + } + else { + SetAllControlsDirty(); + } + + return mPlugWnd; +} + +#define MAX_CLASSNAME_LEN 128 +void GetWndClassName(HWND hWnd, WDL_String* pStr) +{ + char cStr[MAX_CLASSNAME_LEN]; + cStr[0] = '\0'; + GetClassName(hWnd, cStr, MAX_CLASSNAME_LEN); + pStr->Set(cStr); +} + +BOOL CALLBACK IGraphicsWin::FindMainWindow(HWND hWnd, LPARAM lParam) +{ + IGraphicsWin* pGraphics = (IGraphicsWin*) lParam; + if (pGraphics) { + DWORD wPID; + GetWindowThreadProcessId(hWnd, &wPID); + WDL_String str; + GetWndClassName(hWnd, &str); + if (wPID == pGraphics->mPID && !strcmp(str.Get(), pGraphics->mMainWndClassName.Get())) { + pGraphics->mMainWnd = hWnd; + return FALSE; // Stop enumerating. + } + } + return TRUE; +} + +HWND IGraphicsWin::GetMainWnd() +{ + if (!mMainWnd) { + if (mParentWnd) { + HWND parentWnd = mParentWnd; + while (parentWnd) { + mMainWnd = parentWnd; + parentWnd = GetParent(mMainWnd); + } + GetWndClassName(mMainWnd, &mMainWndClassName); + } + else + if (CSTR_NOT_EMPTY(mMainWndClassName.Get())) { + mPID = GetCurrentProcessId(); + EnumWindows(FindMainWindow, (LPARAM) this); + } + } + return mMainWnd; +} + +#define TOOLWIN_BORDER_W 6 +#define TOOLWIN_BORDER_H 23 + +IRECT IGraphicsWin::GetWindowRECT() +{ + if (mPlugWnd) { + RECT r; + GetWindowRect(mPlugWnd, &r); + r.right -= TOOLWIN_BORDER_W; + r.bottom -= TOOLWIN_BORDER_H; + return IRECT(r.left, r.top, r.right, r.bottom); + } + return IRECT(); +} + +void IGraphicsWin::SetWindowTitle(char* str) +{ + SetWindowText(mPlugWnd, str); +} + +void IGraphicsWin::CloseWindow() +{ + if (mPlugWnd) { + DestroyWindow(mPlugWnd); + mPlugWnd = 0; + + if (--nWndClassReg == 0) { + UnregisterClass(wndClassName, mHInstance); + } + } +} + +#define PARAM_EDIT_W 36 +#define PARAM_EDIT_H 16 +#define PARAM_EDIT_H_PER_ENUM 36 +#define PARAM_LIST_MIN_W 24 +#define PARAM_LIST_W_PER_CHAR 8 + +void IGraphicsWin::PromptUserInput(IControl* pControl, IParam* pParam) +{ + if (!pControl || !pParam || mParamEditWnd) { + return; + } + + IRECT* pR = pControl->GetRECT(); + int cX = int(pR->MW()), cY = int(pR->MH()); + char currentText[MAX_PARAM_NAME_LEN]; + pParam->GetDisplayForHost(currentText); + + int n = pParam->GetNDisplayTexts(); + if (n) { + int i, currentIdx = -1; + int w = PARAM_LIST_MIN_W, h = PARAM_EDIT_H_PER_ENUM * (n + 1); + for (i = 0; i < n; ++i) { + const char* str = pParam->GetDisplayText(i); + w = MAX(w, PARAM_LIST_MIN_W + strlen(str) * PARAM_LIST_W_PER_CHAR); + if (!strcmp(str, currentText)) { + currentIdx = i; + } + } + + mParamEditWnd = CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, + cX - w/2, cY, w, h, mPlugWnd, (HMENU) PARAM_EDIT_ID, mHInstance, 0); + + for (i = 0; i < n; ++i) { + const char* str = pParam->GetDisplayText(i); + SendMessage(mParamEditWnd, CB_ADDSTRING, 0, (LPARAM) str); + } + SendMessage(mParamEditWnd, CB_SETCURSEL, (WPARAM) currentIdx, 0); + } + else { + int w = PARAM_EDIT_W, h = PARAM_EDIT_H; + mParamEditWnd = CreateWindow("EDIT", currentText, WS_CHILD | WS_VISIBLE | ES_CENTER | ES_MULTILINE, + cX - w/2, cY - h/2, w, h, mPlugWnd, (HMENU) PARAM_EDIT_ID, mHInstance, 0); + } + + mDefEditProc = (WNDPROC) SetWindowLongPtr(mParamEditWnd, GWLP_WNDPROC, (LONG_PTR) ParamEditProc); + SetWindowLong(mParamEditWnd, GWLP_USERDATA, (LPARAM) this); + + IText txt; + HFONT font = CreateFont(txt.mSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, txt.mFont); + SendMessage(mParamEditWnd, WM_SETFONT, (WPARAM) font, 0); + //DeleteObject(font); + + mEdControl = pControl; + mEdParam = pParam; +} + +#define MAX_PATH_LEN 256 + +void GetModulePath(HMODULE hModule, WDL_String* pPath) +{ + pPath->Set(""); + char pathCStr[MAX_PATH_LEN]; + pathCStr[0] = '\0'; + if (GetModuleFileName(hModule, pathCStr, MAX_PATH_LEN)) { + int s = -1; + for (int i = 0; i < strlen(pathCStr); ++i) { + if (pathCStr[i] == '\\') { + s = i; + } + } + if (s >= 0 && s + 1 < strlen(pathCStr)) { + pPath->Set(pathCStr, s + 1); + } + } +} + +void IGraphicsWin::HostPath(WDL_String* pPath) +{ + GetModulePath(0, pPath); +} + +void IGraphicsWin::PluginPath(WDL_String* pPath) +{ + GetModulePath(mHInstance, pPath); +} + +void IGraphicsWin::PromptForFile(WDL_String* pFilename, EFileAction action, char* dir, char* extensions) +{ + pFilename->Set(""); + if (!WindowIsOpen()) { + return; + } + + WDL_String pathStr; + char fnCStr[MAX_PATH_LEN], dirCStr[MAX_PATH_LEN]; + fnCStr[0] = '\0'; + dirCStr[0] = '\0'; + if (CSTR_NOT_EMPTY(dir)) { + pathStr.Set(dir); + strcpy(dirCStr, dir); + } + else { + HostPath(&pathStr); + } + + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mPlugWnd; + ofn.lpstrFile = fnCStr; + ofn.nMaxFile = MAX_PATH_LEN - 1; + ofn.lpstrInitialDir = dirCStr; + ofn.Flags = OFN_PATHMUSTEXIST; + + //if (!extensions.empty()) { + //static char extStr[256]; + //static char defExtStr[16]; + //int i, j, p; + + //for (j = 0, p = 0; j < extensions.size(); ++j) { + // extStr[p++] = extensions[j++]; + //} + //extStr[p++] = '\0'; + + //StrVector exts = SplitStr(extensions); + //for (i = 0, p = 0; i < exts.size(); ++i) { + // const std::string& ext = exts[i]; + // if (i) { + // extStr[p++] = ';'; + // } + // extStr[p++] = '*'; + // extStr[p++] = '.'; + // for (j = 0; j < ext.size(); ++j) { + // extStr[p++] = ext[j]; + // } + //} + //extStr[p++] = '\0'; + //extStr[p++] = '\0'; + //ofn.lpstrFilter = extStr; + // + //strcpy(defExtStr, exts.front().c_str()); + //ofn.lpstrDefExt = defExtStr; + //} + + bool rc = false; + switch (action) { + case kFileSave: + ofn.Flags |= OFN_OVERWRITEPROMPT; + rc = GetSaveFileName(&ofn); + break; + + case kFileOpen: + default: + ofn.Flags |= OFN_FILEMUSTEXIST; + rc = GetOpenFileName(&ofn); + break; + } + + if (rc) { + pFilename->Set(ofn.lpstrFile); + } +} + +UINT_PTR CALLBACK CCHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + if (uiMsg == WM_INITDIALOG && lParam) { + CHOOSECOLOR* cc = (CHOOSECOLOR*) lParam; + if (cc && cc->lCustData) { + char* str = (char*) cc->lCustData; + SetWindowText(hdlg, str); + } + } + return 0; +} + +bool IGraphicsWin::PromptForColor(IColor* pColor, char* prompt) +{ + if (!mPlugWnd) { + return false; + } + if (!mCustomColorStorage) { + mCustomColorStorage = (COLORREF*) calloc(16, sizeof(COLORREF)); + } + CHOOSECOLOR cc; + memset(&cc, 0, sizeof(CHOOSECOLOR)); + cc.lStructSize = sizeof(CHOOSECOLOR); + cc.hwndOwner = mPlugWnd; + cc.rgbResult = RGB(pColor->R, pColor->G, pColor->B); + cc.lpCustColors = mCustomColorStorage; + cc.lCustData = (LPARAM) prompt; + cc.lpfnHook = CCHookProc; + cc.Flags = CC_RGBINIT | CC_ANYCOLOR | CC_FULLOPEN | CC_SOLIDCOLOR | CC_ENABLEHOOK; + + if (ChooseColor(&cc)) { + pColor->R = GetRValue(cc.rgbResult); + pColor->G = GetGValue(cc.rgbResult); + pColor->B = GetBValue(cc.rgbResult); + return true; + } + return false; +} + +#define MAX_INET_ERR_CODE 32 +bool IGraphicsWin::OpenURL(const char* url, + const char* msgWindowTitle, const char* confirmMsg, const char* errMsgOnFailure) +{ + if (confirmMsg && MessageBox(mPlugWnd, confirmMsg, msgWindowTitle, MB_YESNO) != IDYES) { + return false; + } + DWORD inetStatus = 0; + if (InternetGetConnectedState(&inetStatus, 0)) { + if ((int) ShellExecute(mPlugWnd, "open", url, 0, 0, SW_SHOWNORMAL) > MAX_INET_ERR_CODE) { + return true; + } + } + if (errMsgOnFailure) { + MessageBox(mPlugWnd, errMsgOnFailure, msgWindowTitle, MB_OK); + } + return false; +} + +bool IGraphicsWin::DrawIText(IText* pText, char* str, IRECT* pR) +{ + if (!str || str == '\0') { + return true; + } + + HDC pDC = mDrawBitmap->getDC(); + + bool setColor = (pText->mColor != mActiveFontColor); + if (!mFontActive) { + int h = pText->mSize; + int esc = 10 * pText->mOrientation; + int wt = (pText->mStyle == IText::kStyleBold ? FW_BOLD : 0); + int it = (pText->mStyle == IText::kStyleItalic ? 1 : 0); + HFONT font = CreateFont(h, 0, esc, esc, wt, it, 0, 0, 0, 0, 0, 0, 0, pText->mFont); + SelectObject(pDC, font); // leak? + SetBkMode(pDC, TRANSPARENT); + mFontActive = true; + setColor = true; + } + + if (setColor) { + SetTextColor(pDC, RGB(pText->mColor.R, pText->mColor.G, pText->mColor.B)); + mActiveFontColor = pText->mColor; + } + + UINT fmt = DT_NOCLIP; + switch(pText->mAlign) { + case IText::kAlignCenter: fmt |= DT_CENTER; break; + case IText::kAlignFar: fmt |= DT_RIGHT; break; + case IText::kAlignNear: + default: fmt |= DT_LEFT; break; + } + + RECT R = { pR->L, pR->T, pR->R, pR->B }; + return !!DrawText(pDC, str, strlen(str), &R, fmt); +} + diff --git a/WDL/IPlug/IGraphicsWin.h b/WDL/IPlug/IGraphicsWin.h new file mode 100644 index 00000000..b62db7ca --- /dev/null +++ b/WDL/IPlug/IGraphicsWin.h @@ -0,0 +1,79 @@ +#ifndef _IGRAPHICSWIN_ +#define _IGRAPHICSWIN_ + +#include "IGraphicsLice.h" + +#include +#include +#include + +class IGraphicsWin : public IGraphicsLice +{ +public: + + IGraphicsWin(IPlugBase* pPlug, int w, int h, int refreshFPS = 0); + virtual ~IGraphicsWin(); + + void SetHInstance(HINSTANCE hInstance) { mHInstance = hInstance; } + + void Resize(int w, int h); + bool DrawScreen(IRECT* pR); + + void* OpenWindow(void* pParentWnd); + void CloseWindow(); + bool WindowIsOpen() { return (mPlugWnd); } + + void HostPath(WDL_String* pPath); + void PluginPath(WDL_String* pPath); + + void PromptForFile(WDL_String* pFilename, EFileAction action = kFileOpen, char* dir = "", + char* extensions = ""); // extensions = "txt wav" for example. + + bool PromptForColor(IColor* pColor, char* prompt = ""); + void PromptUserInput(IControl* pControl, IParam* pParam); + + bool OpenURL(const char* url, + const char* msgWindowTitle = 0, const char* confirmMsg = 0, const char* errMsgOnFailure = 0); + + // Specialty use! + void* GetWindow() { return mPlugWnd; } + HWND GetParentWindow() { return mParentWnd; } + HWND GetMainWnd(); + void SetMainWndClassName(char* name) { mMainWndClassName.Set(name); } + void GetMainWndClassName(char* name) { strcpy(name, mMainWndClassName.Get()); } + IRECT GetWindowRECT(); + void SetWindowTitle(char* str); + + bool DrawIText(IText* pText, char* str, IRECT* pR); + +protected: + LICE_IBitmap* OSLoadBitmap(int ID, const char* name); + +private: + bool mFontActive; + IColor mActiveFontColor; + + HINSTANCE mHInstance; + HWND mPlugWnd, mParamEditWnd; + // Ed = being edited manually. + IControl* mEdControl; + IParam* mEdParam; + WNDPROC mDefEditProc; + int mParamEditMsg; + int mIdleTicks; + COLORREF* mCustomColorStorage; + + DWORD mPID; + HWND mParentWnd, mMainWnd; + WDL_String mMainWndClassName; + +public: + + static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ParamEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + static BOOL CALLBACK FindMainWindow(HWND hWnd, LPARAM lParam); +}; + +//////////////////////////////////////// + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IParam.cpp b/WDL/IPlug/IParam.cpp new file mode 100644 index 00000000..8885e0fc --- /dev/null +++ b/WDL/IPlug/IParam.cpp @@ -0,0 +1,185 @@ +#include "IParam.h" +#include + +#define MAX_PARAM_DISPLAY_PRECISION 6 +#define MAX_PARAM_DISPLAY_LEN 8 + +IParam::IParam() +: mType(kTypeNone), mValue(0.0), mMin(0.0), mMax(1.0), mStep(1.0), + mDisplayPrecision(0), mNegateDisplay(false), mShape(1.0) +{ + memset(mName, 0, MAX_PARAM_NAME_LEN * sizeof(char)); + memset(mLabel, 0, MAX_PARAM_NAME_LEN * sizeof(char)); +} + +IParam::~IParam() +{ +} + +void IParam::InitBool(const char* name, bool defaultVal, const char* label) +{ + if (mType == kTypeNone) { + mType = kTypeBool; + } + InitEnum(name, (defaultVal ? 1 : 0), 2); + + SetDisplayText(0, "off"); + SetDisplayText(1, "on"); +} + +void IParam::InitEnum(const char* name, int defaultVal, int nEnums) +{ + if (mType == kTypeNone) { + mType = kTypeEnum; + } + InitInt(name, defaultVal, 0, nEnums - 1); +} + +void IParam::InitInt(const char* name, int defaultVal, int minVal, int maxVal, const char* label) +{ + if (mType == kTypeNone) { + mType = kTypeInt; + } + InitDouble(name, (double) defaultVal, (double) minVal, (double) maxVal, 1.0, label); +} + +void IParam::InitDouble(const char* name, double defaultVal, double minVal, double maxVal, double step, const char* label) +{ + if (mType == kTypeNone) { + mType = kTypeDouble; + } + strcpy(mName, name); + strcpy(mLabel, label); + mValue = defaultVal; + mMin = minVal; + mMax = MAX(maxVal, minVal + step); + mStep = step; + + for (mDisplayPrecision = 0; + mDisplayPrecision < MAX_PARAM_DISPLAY_PRECISION && step != floor(step); + ++mDisplayPrecision, step *= 10.0) { + ; + } +} + +void IParam::SetShape(double shape) +{ + if (shape != 0.0) { + mShape = shape; + } +} + +void IParam::SetDisplayText(int value, const char* text) +{ + int n = mDisplayTexts.GetSize(); + mDisplayTexts.Resize(n + 1); + DisplayText* pDT = mDisplayTexts.Get() + n; + pDT->mValue = value; + strcpy(pDT->mText, text); +} + +double IParam::DBToAmp() +{ + return ::DBToAmp(mValue); +} + +void IParam::SetNormalized(double normalizedValue) +{ + mValue = FromNormalizedParam(normalizedValue, mMin, mMax, mShape); + if (mType != kTypeDouble) { + mValue = floor(0.5 + mValue / mStep) * mStep; + } + mValue = MIN(mValue, mMax); +} + +double IParam::GetNormalized() +{ + return GetNormalized(mValue); +} + +double IParam::GetNormalized(double nonNormalizedValue) +{ + nonNormalizedValue = BOUNDED(nonNormalizedValue, mMin, mMax); + return ToNormalizedParam(nonNormalizedValue, mMin, mMax, mShape); +} + +void IParam::GetDisplayForHost(double value, bool normalized, char* rDisplay) +{ + if (normalized) { + value = FromNormalizedParam(value, mMin, mMax, mShape); + } + + const char* displayText = GetDisplayText((int) value); + if (CSTR_NOT_EMPTY(displayText)) { + strcpy(rDisplay, displayText); + return; + } + + double displayValue = value; + if (mNegateDisplay) { + displayValue = -displayValue; + } + + if (displayValue == 0.0) { + strcpy(rDisplay, "0"); + } + else + if (mDisplayPrecision == 0) { + sprintf(rDisplay, "%d", int(displayValue)); + } + else { + char fmt[16]; + sprintf(fmt, "%%.%df", mDisplayPrecision); + sprintf(rDisplay, fmt, displayValue); + } +} + +const char* IParam::GetNameForHost() +{ + return mName; +} + +const char* IParam::GetLabelForHost() +{ + return mLabel; +} + +int IParam::GetNDisplayTexts() +{ + return mDisplayTexts.GetSize(); +} + +const char* IParam::GetDisplayText(int value) +{ + int n = mDisplayTexts.GetSize(); + if (n) { + DisplayText* pDT = mDisplayTexts.Get(); + for (int i = 0; i < n; ++i, ++pDT) { + if (value == pDT->mValue) { + return pDT->mText; + } + } + } + return ""; +} + +bool IParam::MapDisplayText(char* str, int* pValue) +{ + int n = mDisplayTexts.GetSize(); + if (n) { + DisplayText* pDT = mDisplayTexts.Get(); + for (int i = 0; i < n; ++i, ++pDT) { + if (!strcmp(str, pDT->mText)) { + *pValue = pDT->mValue; + return true; + } + } + } + return false; +} + +void IParam::GetBounds(double* pMin, double* pMax) +{ + *pMin = mMin; + *pMax = mMax; +} \ No newline at end of file diff --git a/WDL/IPlug/IParam.h b/WDL/IPlug/IParam.h new file mode 100644 index 00000000..5450f89f --- /dev/null +++ b/WDL/IPlug/IParam.h @@ -0,0 +1,82 @@ +#ifndef _IPARAM_ +#define _IPARAM_ + +#include "Containers.h" +#include + +const int MAX_PARAM_NAME_LEN = 32; + +inline double ToNormalizedParam(double nonNormalizedValue, double min, double max, double shape) +{ + return pow((nonNormalizedValue - min) / (max - min), 1.0 / shape); +} + +inline double FromNormalizedParam(double normalizedValue, double min, double max, double shape) +{ + return min + pow((double) normalizedValue, shape) * (max - min); +} + +class IParam +{ +public: + + enum EParamType { kTypeNone, kTypeBool, kTypeInt, kTypeEnum, kTypeDouble }; + + IParam(); + ~IParam(); + + EParamType Type() { return mType; } + + void InitBool(const char* name, bool defaultVal, const char* label = ""); + void InitEnum(const char* name, int defaultVal, int nEnums); + void InitInt(const char* name, int defaultVal, int minVal, int maxVal, const char* label = ""); + void InitDouble(const char* name, double defaultVal, double minVal, double maxVal, double step, const char* label = ""); + + void Set(double value) { mValue = BOUNDED(value, mMin, mMax); } + void SetDisplayText(int value, const char* text); + + // The higher the shape, the more resolution around host value zero. + void SetShape(double shape); + + // Call this if your param is (x, y) but you want to always display (-x, -y). + void NegateDisplay() { mNegateDisplay = true; } + bool DisplayIsNegated() const { return mNegateDisplay; } + + // Accessors / converters. + // These all return the readable value, not the VST (0,1). + double Value() const { return mValue; } + bool Bool() const { return (mValue >= 0.5); } + int Int() const { return int(mValue); } + double DBToAmp(); + + void SetNormalized(double normalizedValue); + double GetNormalized(); + double GetNormalized(double nonNormalizedValue); + void GetDisplayForHost(char* rDisplay) { GetDisplayForHost(mValue, false, rDisplay); } + void GetDisplayForHost(double value, bool normalized, char* rDisplay); + const char* GetNameForHost(); + const char* GetLabelForHost(); + + int GetNDisplayTexts(); + const char* GetDisplayText(int value); + bool MapDisplayText(char* str, int* pValue); // Reverse map back to value. + void GetBounds(double* pMin, double* pMax); + +private: + + // All we store is the readable values. + // SetFromHost() and GetForHost() handle conversion from/to (0,1). + EParamType mType; + double mValue, mMin, mMax, mStep, mShape; + int mDisplayPrecision; + char mName[MAX_PARAM_NAME_LEN], mLabel[MAX_PARAM_NAME_LEN]; + bool mNegateDisplay; + + struct DisplayText { + int mValue; + char mText[MAX_PARAM_NAME_LEN]; + }; + WDL_TypedBuf mDisplayTexts; +}; + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug.sln b/WDL/IPlug/IPlug.sln new file mode 100644 index 00000000..be221b88 --- /dev/null +++ b/WDL/IPlug/IPlug.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IPlugExample", "Example\IPlugExample.vcproj", "{D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IPlug", "IPlug.vcproj", "{D744660A-89B6-4EA7-A085-BF92ABE4540F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lice", "lice.vcproj", "{141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Tracer|Win32 = Tracer|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Debug|Win32.Build.0 = Debug|Win32 + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Release|Win32.ActiveCfg = Release|Win32 + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Release|Win32.Build.0 = Release|Win32 + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Tracer|Win32.ActiveCfg = Tracer|Win32 + {D25032DF-715D-4AA1-A62C-31BC6CE4A4D6}.Tracer|Win32.Build.0 = Tracer|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Debug|Win32.ActiveCfg = Debug|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Debug|Win32.Build.0 = Debug|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Release|Win32.ActiveCfg = Release|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Release|Win32.Build.0 = Release|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Tracer|Win32.ActiveCfg = Tracer|Win32 + {D744660A-89B6-4EA7-A085-BF92ABE4540F}.Tracer|Win32.Build.0 = Tracer|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Debug|Win32.Build.0 = Debug|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Release|Win32.ActiveCfg = Release|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Release|Win32.Build.0 = Release|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Tracer|Win32.ActiveCfg = Release|Win32 + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC}.Tracer|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/WDL/IPlug/IPlug.vcproj b/WDL/IPlug/IPlug.vcproj new file mode 100644 index 00000000..16e966b0 --- /dev/null +++ b/WDL/IPlug/IPlug.vcproj @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WDL/IPlug/IPlug.vcxproj b/WDL/IPlug/IPlug.vcxproj new file mode 100644 index 00000000..7c4564b8 --- /dev/null +++ b/WDL/IPlug/IPlug.vcxproj @@ -0,0 +1,213 @@ + + + + Debug + Win32 + + + Debug + X64 + + + Release + Win32 + + + Release + X64 + + + Tracer + Win32 + + + Tracer + X64 + + + + {D744660A-89B6-4EA7-A085-BF92ABE4540F} + Win32Proj + + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + false + + + StaticLibrary + MultiByte + + + StaticLibrary + + + StaticLibrary + + + StaticLibrary + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.20506.1 + $(Platform)/$(Configuration)/ + $(Platform)/$(Configuration)/ + IPlug + .lib + $(Platform)/$(Configuration)/ + $(Platform)/$(Configuration)/ + IPlug + .lib + $(Platform)/$(Configuration)/ + $(Platform)/$(Configuration)/ + IPlug + .lib + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + false + + + Level3 + EditAndContinue + + + lice.lib;wininet.lib;%(AdditionalDependencies) + %(IgnoreSpecificDefaultLibraries) + ../lice/$(Platform)/$(Configuration) + + + + + MaxSpeed + AnySuitable + true + Speed + false + %(AdditionalIncludeDirectories) + WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreaded + false + StreamingSIMDExtensions2 + Fast + false + + + Level3 + ProgramDatabase + true + + + lice.lib;wininet.lib;%(AdditionalDependencies) + ../lice/$(Platform)/$(Configuration) + + + + + MaxSpeed + %(AdditionalIncludeDirectories) + TRACER_BUILD;WIN32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + lice.lib;wininet.lib;%(AdditionalDependencies) + ../lice/$(Platform)/$(Configuration) + + + + + StreamingSIMDExtensions2 + Fast + true + Speed + true + + + wininet.lib;lice.lib + ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + + + + + ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + wininet.lib;lice.lib + + + true + + + + + ../lice/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + wininet.lib;lice.lib + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WDL/IPlug/IPlug.xcodeproj/project.pbxproj b/WDL/IPlug/IPlug.xcodeproj/project.pbxproj new file mode 100644 index 00000000..441fd7c5 --- /dev/null +++ b/WDL/IPlug/IPlug.xcodeproj/project.pbxproj @@ -0,0 +1,1009 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 44; + objects = { + +/* Begin PBXBuildFile section */ + 452A87500FCBFE1900360071 /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A874E0FCBFE1900360071 /* aeffect.h */; }; + 452A87510FCBFE1900360071 /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A874F0FCBFE1900360071 /* aeffectx.h */; }; + 452A87830FCBFFDD00360071 /* lice_arc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87670FCBFFDD00360071 /* lice_arc.cpp */; }; + 452A87840FCBFFDD00360071 /* lice_bezier.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87680FCBFFDD00360071 /* lice_bezier.h */; }; + 452A87850FCBFFDD00360071 /* lice_bmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87690FCBFFDD00360071 /* lice_bmp.cpp */; }; + 452A87860FCBFFDD00360071 /* lice_colorspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */; }; + 452A87870FCBFFDD00360071 /* lice_combine.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A876B0FCBFFDD00360071 /* lice_combine.h */; }; + 452A87880FCBFFDD00360071 /* lice_extended.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A876C0FCBFFDD00360071 /* lice_extended.h */; }; + 452A878F0FCBFFDD00360071 /* lice_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87730FCBFFDD00360071 /* lice_image.cpp */; }; + 452A87900FCBFFDD00360071 /* lice_jpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87740FCBFFDD00360071 /* lice_jpg.cpp */; }; + 452A87910FCBFFDD00360071 /* lice_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87750FCBFFDD00360071 /* lice_line.cpp */; }; + 452A87940FCBFFDD00360071 /* lice_png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A87780FCBFFDD00360071 /* lice_png.cpp */; }; + 452A87970FCBFFDD00360071 /* lice_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877B0FCBFFDD00360071 /* lice_text.cpp */; }; + 452A87980FCBFFDD00360071 /* lice_text.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A877C0FCBFFDD00360071 /* lice_text.h */; }; + 452A87990FCBFFDD00360071 /* lice_textnew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */; }; + 452A879A0FCBFFDD00360071 /* lice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 452A877E0FCBFFDD00360071 /* lice.cpp */; }; + 452A879B0FCBFFDD00360071 /* lice.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87810FCBFFDD00360071 /* lice.h */; }; + 452A87A50FCC004600360071 /* swell.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A87A40FCC004600360071 /* swell.h */; }; + 452A89060FCC0A2D00360071 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88ED0FCC0A2D00360071 /* adler32.c */; }; + 452A89070FCC0A2D00360071 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88EE0FCC0A2D00360071 /* compress.c */; }; + 452A89080FCC0A2D00360071 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88EF0FCC0A2D00360071 /* crc32.c */; }; + 452A89090FCC0A2D00360071 /* crc32.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F00FCC0A2D00360071 /* crc32.h */; }; + 452A890A0FCC0A2D00360071 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F10FCC0A2D00360071 /* deflate.c */; }; + 452A890B0FCC0A2D00360071 /* deflate.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F20FCC0A2D00360071 /* deflate.h */; }; + 452A890D0FCC0A2D00360071 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F40FCC0A2D00360071 /* infback.c */; }; + 452A890E0FCC0A2D00360071 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F50FCC0A2D00360071 /* inffast.c */; }; + 452A890F0FCC0A2D00360071 /* inffast.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F60FCC0A2D00360071 /* inffast.h */; }; + 452A89100FCC0A2D00360071 /* inffixed.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F70FCC0A2D00360071 /* inffixed.h */; }; + 452A89110FCC0A2D00360071 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88F80FCC0A2D00360071 /* inflate.c */; }; + 452A89120FCC0A2D00360071 /* inflate.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88F90FCC0A2D00360071 /* inflate.h */; }; + 452A89130FCC0A2D00360071 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FA0FCC0A2D00360071 /* inftrees.c */; }; + 452A89140FCC0A2D00360071 /* inftrees.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88FB0FCC0A2D00360071 /* inftrees.h */; }; + 452A89150FCC0A2D00360071 /* minigzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FC0FCC0A2D00360071 /* minigzip.c */; }; + 452A89160FCC0A2D00360071 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FD0FCC0A2D00360071 /* trees.c */; }; + 452A89170FCC0A2D00360071 /* trees.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A88FE0FCC0A2D00360071 /* trees.h */; }; + 452A89180FCC0A2D00360071 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A88FF0FCC0A2D00360071 /* uncompr.c */; }; + 452A89190FCC0A2D00360071 /* zconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89000FCC0A2D00360071 /* zconf.h */; }; + 452A891A0FCC0A2D00360071 /* zconf.in.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89010FCC0A2D00360071 /* zconf.in.h */; }; + 452A891B0FCC0A2D00360071 /* zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89020FCC0A2D00360071 /* zlib.h */; }; + 452A891C0FCC0A2D00360071 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89030FCC0A2D00360071 /* zutil.c */; }; + 452A891D0FCC0A2D00360071 /* zutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89040FCC0A2D00360071 /* zutil.h */; }; + 452A891E0FCC0A2D00360071 /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89050FCC0A2D00360071 /* gzio.c */; }; + 452A895D0FCC0A4C00360071 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89220FCC0A4C00360071 /* jcapimin.c */; }; + 452A895E0FCC0A4C00360071 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89230FCC0A4C00360071 /* jcapistd.c */; }; + 452A895F0FCC0A4C00360071 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89240FCC0A4C00360071 /* jccoefct.c */; }; + 452A89600FCC0A4C00360071 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89250FCC0A4C00360071 /* jccolor.c */; }; + 452A89610FCC0A4C00360071 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89260FCC0A4C00360071 /* jcdctmgr.c */; }; + 452A89620FCC0A4C00360071 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89270FCC0A4C00360071 /* jchuff.c */; }; + 452A89630FCC0A4C00360071 /* jchuff.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89280FCC0A4C00360071 /* jchuff.h */; }; + 452A89640FCC0A4C00360071 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89290FCC0A4C00360071 /* jcinit.c */; }; + 452A89650FCC0A4C00360071 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892A0FCC0A4C00360071 /* jcmainct.c */; }; + 452A89660FCC0A4C00360071 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892B0FCC0A4C00360071 /* jcmarker.c */; }; + 452A89670FCC0A4C00360071 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892C0FCC0A4C00360071 /* jcmaster.c */; }; + 452A89680FCC0A4C00360071 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892D0FCC0A4C00360071 /* jcomapi.c */; }; + 452A89690FCC0A4C00360071 /* jconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A892E0FCC0A4C00360071 /* jconfig.h */; }; + 452A896A0FCC0A4C00360071 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A892F0FCC0A4C00360071 /* jcparam.c */; }; + 452A896B0FCC0A4C00360071 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89300FCC0A4C00360071 /* jcphuff.c */; }; + 452A896C0FCC0A4C00360071 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89310FCC0A4C00360071 /* jcprepct.c */; }; + 452A896D0FCC0A4C00360071 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89320FCC0A4C00360071 /* jcsample.c */; }; + 452A896E0FCC0A4C00360071 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89330FCC0A4C00360071 /* jctrans.c */; }; + 452A896F0FCC0A4C00360071 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89340FCC0A4C00360071 /* jdapimin.c */; }; + 452A89700FCC0A4C00360071 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89350FCC0A4C00360071 /* jdapistd.c */; }; + 452A89710FCC0A4C00360071 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89360FCC0A4C00360071 /* jdatadst.c */; }; + 452A89720FCC0A4C00360071 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89370FCC0A4C00360071 /* jdatasrc.c */; }; + 452A89730FCC0A4C00360071 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89380FCC0A4C00360071 /* jdcoefct.c */; }; + 452A89740FCC0A4C00360071 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89390FCC0A4C00360071 /* jdcolor.c */; }; + 452A89750FCC0A4C00360071 /* jdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A893A0FCC0A4C00360071 /* jdct.h */; }; + 452A89760FCC0A4C00360071 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893B0FCC0A4C00360071 /* jddctmgr.c */; }; + 452A89770FCC0A4C00360071 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893C0FCC0A4C00360071 /* jdhuff.c */; }; + 452A89780FCC0A4C00360071 /* jdhuff.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A893D0FCC0A4C00360071 /* jdhuff.h */; }; + 452A89790FCC0A4C00360071 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893E0FCC0A4C00360071 /* jdinput.c */; }; + 452A897A0FCC0A4C00360071 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A893F0FCC0A4C00360071 /* jdmainct.c */; }; + 452A897B0FCC0A4C00360071 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89400FCC0A4C00360071 /* jdmarker.c */; }; + 452A897C0FCC0A4C00360071 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89410FCC0A4C00360071 /* jdmaster.c */; }; + 452A897D0FCC0A4C00360071 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89420FCC0A4C00360071 /* jdmerge.c */; }; + 452A897E0FCC0A4C00360071 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89430FCC0A4C00360071 /* jdphuff.c */; }; + 452A897F0FCC0A4C00360071 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89440FCC0A4C00360071 /* jdpostct.c */; }; + 452A89800FCC0A4C00360071 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89450FCC0A4C00360071 /* jdsample.c */; }; + 452A89810FCC0A4C00360071 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89460FCC0A4C00360071 /* jdtrans.c */; }; + 452A89820FCC0A4C00360071 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89470FCC0A4C00360071 /* jerror.c */; }; + 452A89830FCC0A4C00360071 /* jerror.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89480FCC0A4C00360071 /* jerror.h */; }; + 452A89840FCC0A4C00360071 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89490FCC0A4C00360071 /* jfdctflt.c */; }; + 452A89850FCC0A4C00360071 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894A0FCC0A4C00360071 /* jfdctfst.c */; }; + 452A89860FCC0A4C00360071 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894B0FCC0A4C00360071 /* jfdctint.c */; }; + 452A89870FCC0A4C00360071 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894C0FCC0A4C00360071 /* jidctflt.c */; }; + 452A89880FCC0A4C00360071 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894D0FCC0A4C00360071 /* jidctfst.c */; }; + 452A89890FCC0A4C00360071 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894E0FCC0A4C00360071 /* jidctint.c */; }; + 452A898A0FCC0A4C00360071 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A894F0FCC0A4C00360071 /* jidctred.c */; }; + 452A898B0FCC0A4C00360071 /* jinclude.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89500FCC0A4C00360071 /* jinclude.h */; }; + 452A898C0FCC0A4C00360071 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89510FCC0A4C00360071 /* jmemmgr.c */; }; + 452A898D0FCC0A4C00360071 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89520FCC0A4C00360071 /* jmemnobs.c */; }; + 452A898E0FCC0A4C00360071 /* jmemsys.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89530FCC0A4C00360071 /* jmemsys.h */; }; + 452A898F0FCC0A4C00360071 /* jmorecfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89540FCC0A4C00360071 /* jmorecfg.h */; }; + 452A89900FCC0A4C00360071 /* jpegint.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89550FCC0A4C00360071 /* jpegint.h */; }; + 452A89910FCC0A4C00360071 /* jpeglib.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89560FCC0A4C00360071 /* jpeglib.h */; }; + 452A89920FCC0A4C00360071 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89570FCC0A4C00360071 /* jquant1.c */; }; + 452A89930FCC0A4C00360071 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89580FCC0A4C00360071 /* jquant2.c */; }; + 452A89940FCC0A4C00360071 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89590FCC0A4C00360071 /* jutils.c */; }; + 452A89950FCC0A4C00360071 /* jversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A895A0FCC0A4C00360071 /* jversion.h */; }; + 452A89AA0FCC0A6500360071 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89960FCC0A6500360071 /* png.c */; }; + 452A89AB0FCC0A6500360071 /* png.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89970FCC0A6500360071 /* png.h */; }; + 452A89AC0FCC0A6500360071 /* pngconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A89980FCC0A6500360071 /* pngconf.h */; }; + 452A89AD0FCC0A6500360071 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89990FCC0A6500360071 /* pngerror.c */; }; + 452A89AE0FCC0A6500360071 /* pnggccrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899A0FCC0A6500360071 /* pnggccrd.c */; }; + 452A89AF0FCC0A6500360071 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899B0FCC0A6500360071 /* pngget.c */; }; + 452A89B00FCC0A6500360071 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899C0FCC0A6500360071 /* pngmem.c */; }; + 452A89B10FCC0A6500360071 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899D0FCC0A6500360071 /* pngpread.c */; }; + 452A89B20FCC0A6500360071 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899E0FCC0A6500360071 /* pngread.c */; }; + 452A89B30FCC0A6500360071 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A899F0FCC0A6500360071 /* pngrtran.c */; }; + 452A89B40FCC0A6500360071 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A00FCC0A6500360071 /* pngrutil.c */; }; + 452A89B50FCC0A6500360071 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A10FCC0A6500360071 /* pngset.c */; }; + 452A89B70FCC0A6500360071 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A30FCC0A6500360071 /* pngtrans.c */; }; + 452A89B80FCC0A6500360071 /* pngvcrd.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A40FCC0A6500360071 /* pngvcrd.c */; }; + 452A89B90FCC0A6500360071 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A50FCC0A6500360071 /* pngwio.c */; }; + 452A89BB0FCC0A6500360071 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A70FCC0A6500360071 /* pngwtran.c */; }; + 452A89BC0FCC0A6500360071 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A80FCC0A6500360071 /* pngwutil.c */; }; + 452A89BD0FCC0A6500360071 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 452A89A90FCC0A6500360071 /* pngrio.c */; }; + 452A8A030FCC0F4E00360071 /* swell-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 452A8A020FCC0F4E00360071 /* swell-internal.h */; }; + 45B61BC610B15E25009E1E8C /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45B61BC510B15E25009E1E8C /* swell-gdi.mm */; }; + 521F387F0D1704080060FE32 /* IPlug_include_in_plug_src.h in Headers */ = {isa = PBXBuildFile; fileRef = 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */; }; + 521F38800D1704080060FE32 /* IPlug_include_in_plug_hdr.h in Headers */ = {isa = PBXBuildFile; fileRef = 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */; }; + 52780D4C0D20A1A000C2BCA7 /* IGraphicsCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */; }; + 52A2156B0D11C1E4006341F0 /* Hosts.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A2156A0D11C1E4006341F0 /* Hosts.h */; }; + 52A2156D0D11C1EC006341F0 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A2156C0D11C1EC006341F0 /* Hosts.cpp */; }; + 52A215720D11C200006341F0 /* IPlugBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A2156E0D11C200006341F0 /* IPlugBase.h */; }; + 52A215730D11C200006341F0 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A2156F0D11C200006341F0 /* IPlugBase.cpp */; }; + 52A215780D11C20C006341F0 /* IPlugVST.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A215760D11C20C006341F0 /* IPlugVST.h */; }; + 52A215790D11C20C006341F0 /* IPlugVST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A215770D11C20C006341F0 /* IPlugVST.cpp */; }; + 52A4AB440D2BFA510042A248 /* IGraphicsCarbon.h in Headers */ = {isa = PBXBuildFile; fileRef = 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */; }; + 52A4AB450D2BFA510042A248 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */; }; + 52C4DA4F0D0E50F90007A920 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DA4E0D0E50F90007A920 /* Carbon.framework */; }; + 52E41BA90D14C09E00A0943B /* IPlugAU.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E41BA70D14C09E00A0943B /* IPlugAU.h */; }; + 52E41BAA0D14C09E00A0943B /* IPlugAU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */; }; + 52FBBEA60D0CF0D3001C8B8A /* Containers.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE870D0CF0D3001C8B8A /* Containers.h */; }; + 52FBBEA70D0CF0D3001C8B8A /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */; }; + 52FBBEA80D0CF0D3001C8B8A /* IControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE890D0CF0D3001C8B8A /* IControl.h */; }; + 52FBBEA90D0CF0D3001C8B8A /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */; }; + 52FBBEAA0D0CF0D3001C8B8A /* IGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */; }; + 52FBBEAC0D0CF0D3001C8B8A /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */; }; + 52FBBEAD0D0CF0D3001C8B8A /* IGraphicsLice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */; }; + 52FBBEAE0D0CF0D3001C8B8A /* IGraphicsLice.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */; }; + 52FBBEB00D0CF0D3001C8B8A /* IGraphicsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */; }; + 52FBBEB10D0CF0D3001C8B8A /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */; }; + 52FBBEB50D0CF0D3001C8B8A /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */; }; + 52FBBEB60D0CF0D3001C8B8A /* IParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBE970D0CF0D3001C8B8A /* IParam.h */; }; + 52FBBEBB0D0CF0D3001C8B8A /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */; }; + 52FBBEBC0D0CF0D3001C8B8A /* IPlugStructs.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */; }; + 52FBBEBD0D0CF0D3001C8B8A /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */; }; + 52FBBEBE0D0CF0D3001C8B8A /* Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBEA20D0CF0D3001C8B8A /* Log.h */; }; + D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 32DBCF5E0370ADEE00C91783 /* IPlug_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_Prefix.pch; sourceTree = ""; }; + 452A874E0FCBFE1900360071 /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffect.h; sourceTree = ""; }; + 452A874F0FCBFE1900360071 /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffectx.h; sourceTree = ""; }; + 452A87670FCBFFDD00360071 /* lice_arc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_arc.cpp; path = ../lice/lice_arc.cpp; sourceTree = SOURCE_ROOT; }; + 452A87680FCBFFDD00360071 /* lice_bezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_bezier.h; path = ../lice/lice_bezier.h; sourceTree = SOURCE_ROOT; }; + 452A87690FCBFFDD00360071 /* lice_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_bmp.cpp; path = ../lice/lice_bmp.cpp; sourceTree = SOURCE_ROOT; }; + 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_colorspace.cpp; path = ../lice/lice_colorspace.cpp; sourceTree = SOURCE_ROOT; }; + 452A876B0FCBFFDD00360071 /* lice_combine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_combine.h; path = ../lice/lice_combine.h; sourceTree = SOURCE_ROOT; }; + 452A876C0FCBFFDD00360071 /* lice_extended.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_extended.h; path = ../lice/lice_extended.h; sourceTree = SOURCE_ROOT; }; + 452A87730FCBFFDD00360071 /* lice_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_image.cpp; path = ../lice/lice_image.cpp; sourceTree = SOURCE_ROOT; }; + 452A87740FCBFFDD00360071 /* lice_jpg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg.cpp; path = ../lice/lice_jpg.cpp; sourceTree = SOURCE_ROOT; }; + 452A87750FCBFFDD00360071 /* lice_line.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_line.cpp; path = ../lice/lice_line.cpp; sourceTree = SOURCE_ROOT; }; + 452A87780FCBFFDD00360071 /* lice_png.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png.cpp; path = ../lice/lice_png.cpp; sourceTree = SOURCE_ROOT; }; + 452A877B0FCBFFDD00360071 /* lice_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_text.cpp; path = ../lice/lice_text.cpp; sourceTree = SOURCE_ROOT; }; + 452A877C0FCBFFDD00360071 /* lice_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_text.h; path = ../lice/lice_text.h; sourceTree = SOURCE_ROOT; }; + 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_textnew.cpp; path = ../lice/lice_textnew.cpp; sourceTree = SOURCE_ROOT; }; + 452A877E0FCBFFDD00360071 /* lice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice.cpp; path = ../lice/lice.cpp; sourceTree = SOURCE_ROOT; }; + 452A87810FCBFFDD00360071 /* lice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice.h; path = ../lice/lice.h; sourceTree = SOURCE_ROOT; }; + 452A87A40FCC004600360071 /* swell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swell.h; path = ../swell/swell.h; sourceTree = SOURCE_ROOT; }; + 452A88ED0FCC0A2D00360071 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ../zlib/adler32.c; sourceTree = SOURCE_ROOT; }; + 452A88EE0FCC0A2D00360071 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ../zlib/compress.c; sourceTree = SOURCE_ROOT; }; + 452A88EF0FCC0A2D00360071 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ../zlib/crc32.c; sourceTree = SOURCE_ROOT; }; + 452A88F00FCC0A2D00360071 /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = ../zlib/crc32.h; sourceTree = SOURCE_ROOT; }; + 452A88F10FCC0A2D00360071 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ../zlib/deflate.c; sourceTree = SOURCE_ROOT; }; + 452A88F20FCC0A2D00360071 /* deflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = deflate.h; path = ../zlib/deflate.h; sourceTree = SOURCE_ROOT; }; + 452A88F40FCC0A2D00360071 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ../zlib/infback.c; sourceTree = SOURCE_ROOT; }; + 452A88F50FCC0A2D00360071 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../zlib/inffast.c; sourceTree = SOURCE_ROOT; }; + 452A88F60FCC0A2D00360071 /* inffast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffast.h; path = ../zlib/inffast.h; sourceTree = SOURCE_ROOT; }; + 452A88F70FCC0A2D00360071 /* inffixed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffixed.h; path = ../zlib/inffixed.h; sourceTree = SOURCE_ROOT; }; + 452A88F80FCC0A2D00360071 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ../zlib/inflate.c; sourceTree = SOURCE_ROOT; }; + 452A88F90FCC0A2D00360071 /* inflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inflate.h; path = ../zlib/inflate.h; sourceTree = SOURCE_ROOT; }; + 452A88FA0FCC0A2D00360071 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ../zlib/inftrees.c; sourceTree = SOURCE_ROOT; }; + 452A88FB0FCC0A2D00360071 /* inftrees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inftrees.h; path = ../zlib/inftrees.h; sourceTree = SOURCE_ROOT; }; + 452A88FC0FCC0A2D00360071 /* minigzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minigzip.c; path = ../zlib/minigzip.c; sourceTree = SOURCE_ROOT; }; + 452A88FD0FCC0A2D00360071 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ../zlib/trees.c; sourceTree = SOURCE_ROOT; }; + 452A88FE0FCC0A2D00360071 /* trees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = trees.h; path = ../zlib/trees.h; sourceTree = SOURCE_ROOT; }; + 452A88FF0FCC0A2D00360071 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ../zlib/uncompr.c; sourceTree = SOURCE_ROOT; }; + 452A89000FCC0A2D00360071 /* zconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zconf.h; path = ../zlib/zconf.h; sourceTree = SOURCE_ROOT; }; + 452A89010FCC0A2D00360071 /* zconf.in.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zconf.in.h; path = ../zlib/zconf.in.h; sourceTree = SOURCE_ROOT; }; + 452A89020FCC0A2D00360071 /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = ../zlib/zlib.h; sourceTree = SOURCE_ROOT; }; + 452A89030FCC0A2D00360071 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ../zlib/zutil.c; sourceTree = SOURCE_ROOT; }; + 452A89040FCC0A2D00360071 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = ../zlib/zutil.h; sourceTree = SOURCE_ROOT; }; + 452A89050FCC0A2D00360071 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzio.c; path = ../zlib/gzio.c; sourceTree = SOURCE_ROOT; }; + 452A89220FCC0A4C00360071 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../jpeglib/jcapimin.c; sourceTree = SOURCE_ROOT; }; + 452A89230FCC0A4C00360071 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../jpeglib/jcapistd.c; sourceTree = SOURCE_ROOT; }; + 452A89240FCC0A4C00360071 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../jpeglib/jccoefct.c; sourceTree = SOURCE_ROOT; }; + 452A89250FCC0A4C00360071 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../jpeglib/jccolor.c; sourceTree = SOURCE_ROOT; }; + 452A89260FCC0A4C00360071 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../jpeglib/jcdctmgr.c; sourceTree = SOURCE_ROOT; }; + 452A89270FCC0A4C00360071 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../jpeglib/jchuff.c; sourceTree = SOURCE_ROOT; }; + 452A89280FCC0A4C00360071 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../jpeglib/jchuff.h; sourceTree = SOURCE_ROOT; }; + 452A89290FCC0A4C00360071 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../jpeglib/jcinit.c; sourceTree = SOURCE_ROOT; }; + 452A892A0FCC0A4C00360071 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../jpeglib/jcmainct.c; sourceTree = SOURCE_ROOT; }; + 452A892B0FCC0A4C00360071 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../jpeglib/jcmarker.c; sourceTree = SOURCE_ROOT; }; + 452A892C0FCC0A4C00360071 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../jpeglib/jcmaster.c; sourceTree = SOURCE_ROOT; }; + 452A892D0FCC0A4C00360071 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../jpeglib/jcomapi.c; sourceTree = SOURCE_ROOT; }; + 452A892E0FCC0A4C00360071 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../jpeglib/jconfig.h; sourceTree = SOURCE_ROOT; }; + 452A892F0FCC0A4C00360071 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../jpeglib/jcparam.c; sourceTree = SOURCE_ROOT; }; + 452A89300FCC0A4C00360071 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../jpeglib/jcphuff.c; sourceTree = SOURCE_ROOT; }; + 452A89310FCC0A4C00360071 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../jpeglib/jcprepct.c; sourceTree = SOURCE_ROOT; }; + 452A89320FCC0A4C00360071 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../jpeglib/jcsample.c; sourceTree = SOURCE_ROOT; }; + 452A89330FCC0A4C00360071 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../jpeglib/jctrans.c; sourceTree = SOURCE_ROOT; }; + 452A89340FCC0A4C00360071 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../jpeglib/jdapimin.c; sourceTree = SOURCE_ROOT; }; + 452A89350FCC0A4C00360071 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../jpeglib/jdapistd.c; sourceTree = SOURCE_ROOT; }; + 452A89360FCC0A4C00360071 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../jpeglib/jdatadst.c; sourceTree = SOURCE_ROOT; }; + 452A89370FCC0A4C00360071 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../jpeglib/jdatasrc.c; sourceTree = SOURCE_ROOT; }; + 452A89380FCC0A4C00360071 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../jpeglib/jdcoefct.c; sourceTree = SOURCE_ROOT; }; + 452A89390FCC0A4C00360071 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../jpeglib/jdcolor.c; sourceTree = SOURCE_ROOT; }; + 452A893A0FCC0A4C00360071 /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jdct.h; path = ../jpeglib/jdct.h; sourceTree = SOURCE_ROOT; }; + 452A893B0FCC0A4C00360071 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../jpeglib/jddctmgr.c; sourceTree = SOURCE_ROOT; }; + 452A893C0FCC0A4C00360071 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../jpeglib/jdhuff.c; sourceTree = SOURCE_ROOT; }; + 452A893D0FCC0A4C00360071 /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jdhuff.h; path = ../jpeglib/jdhuff.h; sourceTree = SOURCE_ROOT; }; + 452A893E0FCC0A4C00360071 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../jpeglib/jdinput.c; sourceTree = SOURCE_ROOT; }; + 452A893F0FCC0A4C00360071 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../jpeglib/jdmainct.c; sourceTree = SOURCE_ROOT; }; + 452A89400FCC0A4C00360071 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../jpeglib/jdmarker.c; sourceTree = SOURCE_ROOT; }; + 452A89410FCC0A4C00360071 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../jpeglib/jdmaster.c; sourceTree = SOURCE_ROOT; }; + 452A89420FCC0A4C00360071 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../jpeglib/jdmerge.c; sourceTree = SOURCE_ROOT; }; + 452A89430FCC0A4C00360071 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../jpeglib/jdphuff.c; sourceTree = SOURCE_ROOT; }; + 452A89440FCC0A4C00360071 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../jpeglib/jdpostct.c; sourceTree = SOURCE_ROOT; }; + 452A89450FCC0A4C00360071 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../jpeglib/jdsample.c; sourceTree = SOURCE_ROOT; }; + 452A89460FCC0A4C00360071 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../jpeglib/jdtrans.c; sourceTree = SOURCE_ROOT; }; + 452A89470FCC0A4C00360071 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../jpeglib/jerror.c; sourceTree = SOURCE_ROOT; }; + 452A89480FCC0A4C00360071 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../jpeglib/jerror.h; sourceTree = SOURCE_ROOT; }; + 452A89490FCC0A4C00360071 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../jpeglib/jfdctflt.c; sourceTree = SOURCE_ROOT; }; + 452A894A0FCC0A4C00360071 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../jpeglib/jfdctfst.c; sourceTree = SOURCE_ROOT; }; + 452A894B0FCC0A4C00360071 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../jpeglib/jfdctint.c; sourceTree = SOURCE_ROOT; }; + 452A894C0FCC0A4C00360071 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../jpeglib/jidctflt.c; sourceTree = SOURCE_ROOT; }; + 452A894D0FCC0A4C00360071 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../jpeglib/jidctfst.c; sourceTree = SOURCE_ROOT; }; + 452A894E0FCC0A4C00360071 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../jpeglib/jidctint.c; sourceTree = SOURCE_ROOT; }; + 452A894F0FCC0A4C00360071 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../jpeglib/jidctred.c; sourceTree = SOURCE_ROOT; }; + 452A89500FCC0A4C00360071 /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jinclude.h; path = ../jpeglib/jinclude.h; sourceTree = SOURCE_ROOT; }; + 452A89510FCC0A4C00360071 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../jpeglib/jmemmgr.c; sourceTree = SOURCE_ROOT; }; + 452A89520FCC0A4C00360071 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../jpeglib/jmemnobs.c; sourceTree = SOURCE_ROOT; }; + 452A89530FCC0A4C00360071 /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jmemsys.h; path = ../jpeglib/jmemsys.h; sourceTree = SOURCE_ROOT; }; + 452A89540FCC0A4C00360071 /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jmorecfg.h; path = ../jpeglib/jmorecfg.h; sourceTree = SOURCE_ROOT; }; + 452A89550FCC0A4C00360071 /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jpegint.h; path = ../jpeglib/jpegint.h; sourceTree = SOURCE_ROOT; }; + 452A89560FCC0A4C00360071 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../jpeglib/jpeglib.h; sourceTree = SOURCE_ROOT; }; + 452A89570FCC0A4C00360071 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../jpeglib/jquant1.c; sourceTree = SOURCE_ROOT; }; + 452A89580FCC0A4C00360071 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../jpeglib/jquant2.c; sourceTree = SOURCE_ROOT; }; + 452A89590FCC0A4C00360071 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../jpeglib/jutils.c; sourceTree = SOURCE_ROOT; }; + 452A895A0FCC0A4C00360071 /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jversion.h; path = ../jpeglib/jversion.h; sourceTree = SOURCE_ROOT; }; + 452A89960FCC0A6500360071 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../libpng/png.c; sourceTree = SOURCE_ROOT; }; + 452A89970FCC0A6500360071 /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = png.h; path = ../libpng/png.h; sourceTree = SOURCE_ROOT; }; + 452A89980FCC0A6500360071 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = ../libpng/pngconf.h; sourceTree = SOURCE_ROOT; }; + 452A89990FCC0A6500360071 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../libpng/pngerror.c; sourceTree = SOURCE_ROOT; }; + 452A899A0FCC0A6500360071 /* pnggccrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pnggccrd.c; path = ../libpng/pnggccrd.c; sourceTree = SOURCE_ROOT; }; + 452A899B0FCC0A6500360071 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../libpng/pngget.c; sourceTree = SOURCE_ROOT; }; + 452A899C0FCC0A6500360071 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../libpng/pngmem.c; sourceTree = SOURCE_ROOT; }; + 452A899D0FCC0A6500360071 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../libpng/pngpread.c; sourceTree = SOURCE_ROOT; }; + 452A899E0FCC0A6500360071 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../libpng/pngread.c; sourceTree = SOURCE_ROOT; }; + 452A899F0FCC0A6500360071 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; }; + 452A89A00FCC0A6500360071 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; }; + 452A89A10FCC0A6500360071 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../libpng/pngset.c; sourceTree = SOURCE_ROOT; }; + 452A89A30FCC0A6500360071 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; }; + 452A89A40FCC0A6500360071 /* pngvcrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngvcrd.c; path = ../libpng/pngvcrd.c; sourceTree = SOURCE_ROOT; }; + 452A89A50FCC0A6500360071 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../libpng/pngwio.c; sourceTree = SOURCE_ROOT; }; + 452A89A70FCC0A6500360071 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; }; + 452A89A80FCC0A6500360071 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; }; + 452A89A90FCC0A6500360071 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../libpng/pngrio.c; sourceTree = SOURCE_ROOT; }; + 452A8A020FCC0F4E00360071 /* swell-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-internal.h"; path = "../swell/swell-internal.h"; sourceTree = SOURCE_ROOT; }; + 45B61BC510B15E25009E1E8C /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../swell/swell-gdi.mm"; sourceTree = SOURCE_ROOT; }; + 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_include_in_plug_src.h; sourceTree = ""; }; + 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlug_include_in_plug_hdr.h; sourceTree = ""; }; + 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsCocoa.h; sourceTree = ""; }; + 52A2156A0D11C1E4006341F0 /* Hosts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hosts.h; sourceTree = ""; }; + 52A2156C0D11C1EC006341F0 /* Hosts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hosts.cpp; sourceTree = ""; }; + 52A2156E0D11C200006341F0 /* IPlugBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugBase.h; sourceTree = ""; }; + 52A2156F0D11C200006341F0 /* IPlugBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugBase.cpp; sourceTree = ""; }; + 52A215760D11C20C006341F0 /* IPlugVST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugVST.h; sourceTree = ""; }; + 52A215770D11C20C006341F0 /* IPlugVST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugVST.cpp; sourceTree = ""; }; + 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsCarbon.h; sourceTree = ""; }; + 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphicsCarbon.cpp; sourceTree = ""; }; + 52C4DA4E0D0E50F90007A920 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 52E41BA70D14C09E00A0943B /* IPlugAU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugAU.h; sourceTree = ""; }; + 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugAU.cpp; sourceTree = ""; }; + 52FBBE870D0CF0D3001C8B8A /* Containers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Containers.h; sourceTree = ""; }; + 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IControl.cpp; sourceTree = ""; }; + 52FBBE890D0CF0D3001C8B8A /* IControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IControl.h; sourceTree = ""; }; + 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphics.cpp; sourceTree = ""; }; + 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphics.h; sourceTree = ""; }; + 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IGraphicsCocoa.mm; sourceTree = ""; }; + 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IGraphicsLice.cpp; sourceTree = ""; }; + 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsLice.h; sourceTree = ""; }; + 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGraphicsMac.h; sourceTree = ""; }; + 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IGraphicsMac.mm; sourceTree = ""; }; + 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IParam.cpp; sourceTree = ""; }; + 52FBBE970D0CF0D3001C8B8A /* IParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IParam.h; sourceTree = ""; }; + 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPlugStructs.cpp; sourceTree = ""; }; + 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPlugStructs.h; sourceTree = ""; }; + 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Log.cpp; sourceTree = ""; }; + 52FBBEA20D0CF0D3001C8B8A /* Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = ""; }; + D2AAC07E0554694100DB518D /* libIPlug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIPlug.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D2F7E8BE07B2D77200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D2AAC07C0554694100DB518D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D2AAC088055469A000DB518D /* Cocoa.framework in Frameworks */, + 52C4DA4F0D0E50F90007A920 /* Carbon.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DFFF38A50411DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC07E0554694100DB518D /* libIPlug.a */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* IPlug */ = { + isa = PBXGroup; + children = ( + 452A875D0FCBFF5B00360071 /* LICE */, + 452A874D0FCBFE1900360071 /* VST_SDK */, + 52FBBE770D0CF0D3001C8B8A /* IPlug */, + 08FB77AEFE84172EC02AAC07 /* Classes */, + 32C88DFF0371C24200C91783 /* Other Sources */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DFFF38A50411DB9C8B /* Products */, + ); + name = IPlug; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, + 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 08FB77AEFE84172EC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + ); + name = Classes; + sourceTree = ""; + }; + 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 52C4DA4E0D0E50F90007A920 /* Carbon.framework */, + 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 0867D6A5FE840307C02AAC07 /* AppKit.framework */, + D2F7E8BE07B2D77200F64583 /* CoreData.framework */, + 0867D69BFE84028FC02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 32C88DFF0371C24200C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF5E0370ADEE00C91783 /* IPlug_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 452A874D0FCBFE1900360071 /* VST_SDK */ = { + isa = PBXGroup; + children = ( + 452A874E0FCBFE1900360071 /* aeffect.h */, + 452A874F0FCBFE1900360071 /* aeffectx.h */, + ); + name = VST_SDK; + path = ../../VST_SDK; + sourceTree = SOURCE_ROOT; + }; + 452A875D0FCBFF5B00360071 /* LICE */ = { + isa = PBXGroup; + children = ( + 452A88EB0FCC0A1E00360071 /* zlib */, + 452A88E80FCC09FD00360071 /* jpeglib */, + 452A88E70FCC09EF00360071 /* libpng */, + 452A87670FCBFFDD00360071 /* lice_arc.cpp */, + 452A87680FCBFFDD00360071 /* lice_bezier.h */, + 452A87690FCBFFDD00360071 /* lice_bmp.cpp */, + 452A876A0FCBFFDD00360071 /* lice_colorspace.cpp */, + 452A876B0FCBFFDD00360071 /* lice_combine.h */, + 452A876C0FCBFFDD00360071 /* lice_extended.h */, + 452A87730FCBFFDD00360071 /* lice_image.cpp */, + 452A87740FCBFFDD00360071 /* lice_jpg.cpp */, + 452A87750FCBFFDD00360071 /* lice_line.cpp */, + 452A87780FCBFFDD00360071 /* lice_png.cpp */, + 452A877B0FCBFFDD00360071 /* lice_text.cpp */, + 452A877C0FCBFFDD00360071 /* lice_text.h */, + 452A877D0FCBFFDD00360071 /* lice_textnew.cpp */, + 452A877E0FCBFFDD00360071 /* lice.cpp */, + 452A87810FCBFFDD00360071 /* lice.h */, + 452A87600FCBFFA500360071 /* SWELL */, + ); + name = LICE; + sourceTree = ""; + }; + 452A87600FCBFFA500360071 /* SWELL */ = { + isa = PBXGroup; + children = ( + 45B61BC510B15E25009E1E8C /* swell-gdi.mm */, + 452A8A020FCC0F4E00360071 /* swell-internal.h */, + 452A87A40FCC004600360071 /* swell.h */, + ); + name = SWELL; + sourceTree = ""; + }; + 452A88E70FCC09EF00360071 /* libpng */ = { + isa = PBXGroup; + children = ( + 452A89960FCC0A6500360071 /* png.c */, + 452A89970FCC0A6500360071 /* png.h */, + 452A89980FCC0A6500360071 /* pngconf.h */, + 452A89990FCC0A6500360071 /* pngerror.c */, + 452A899A0FCC0A6500360071 /* pnggccrd.c */, + 452A899B0FCC0A6500360071 /* pngget.c */, + 452A899C0FCC0A6500360071 /* pngmem.c */, + 452A899D0FCC0A6500360071 /* pngpread.c */, + 452A899E0FCC0A6500360071 /* pngread.c */, + 452A899F0FCC0A6500360071 /* pngrtran.c */, + 452A89A00FCC0A6500360071 /* pngrutil.c */, + 452A89A10FCC0A6500360071 /* pngset.c */, + 452A89A30FCC0A6500360071 /* pngtrans.c */, + 452A89A40FCC0A6500360071 /* pngvcrd.c */, + 452A89A50FCC0A6500360071 /* pngwio.c */, + 452A89A70FCC0A6500360071 /* pngwtran.c */, + 452A89A80FCC0A6500360071 /* pngwutil.c */, + 452A89A90FCC0A6500360071 /* pngrio.c */, + ); + name = libpng; + sourceTree = ""; + }; + 452A88E80FCC09FD00360071 /* jpeglib */ = { + isa = PBXGroup; + children = ( + 452A89220FCC0A4C00360071 /* jcapimin.c */, + 452A89230FCC0A4C00360071 /* jcapistd.c */, + 452A89240FCC0A4C00360071 /* jccoefct.c */, + 452A89250FCC0A4C00360071 /* jccolor.c */, + 452A89260FCC0A4C00360071 /* jcdctmgr.c */, + 452A89270FCC0A4C00360071 /* jchuff.c */, + 452A89280FCC0A4C00360071 /* jchuff.h */, + 452A89290FCC0A4C00360071 /* jcinit.c */, + 452A892A0FCC0A4C00360071 /* jcmainct.c */, + 452A892B0FCC0A4C00360071 /* jcmarker.c */, + 452A892C0FCC0A4C00360071 /* jcmaster.c */, + 452A892D0FCC0A4C00360071 /* jcomapi.c */, + 452A892E0FCC0A4C00360071 /* jconfig.h */, + 452A892F0FCC0A4C00360071 /* jcparam.c */, + 452A89300FCC0A4C00360071 /* jcphuff.c */, + 452A89310FCC0A4C00360071 /* jcprepct.c */, + 452A89320FCC0A4C00360071 /* jcsample.c */, + 452A89330FCC0A4C00360071 /* jctrans.c */, + 452A89340FCC0A4C00360071 /* jdapimin.c */, + 452A89350FCC0A4C00360071 /* jdapistd.c */, + 452A89360FCC0A4C00360071 /* jdatadst.c */, + 452A89370FCC0A4C00360071 /* jdatasrc.c */, + 452A89380FCC0A4C00360071 /* jdcoefct.c */, + 452A89390FCC0A4C00360071 /* jdcolor.c */, + 452A893A0FCC0A4C00360071 /* jdct.h */, + 452A893B0FCC0A4C00360071 /* jddctmgr.c */, + 452A893C0FCC0A4C00360071 /* jdhuff.c */, + 452A893D0FCC0A4C00360071 /* jdhuff.h */, + 452A893E0FCC0A4C00360071 /* jdinput.c */, + 452A893F0FCC0A4C00360071 /* jdmainct.c */, + 452A89400FCC0A4C00360071 /* jdmarker.c */, + 452A89410FCC0A4C00360071 /* jdmaster.c */, + 452A89420FCC0A4C00360071 /* jdmerge.c */, + 452A89430FCC0A4C00360071 /* jdphuff.c */, + 452A89440FCC0A4C00360071 /* jdpostct.c */, + 452A89450FCC0A4C00360071 /* jdsample.c */, + 452A89460FCC0A4C00360071 /* jdtrans.c */, + 452A89470FCC0A4C00360071 /* jerror.c */, + 452A89480FCC0A4C00360071 /* jerror.h */, + 452A89490FCC0A4C00360071 /* jfdctflt.c */, + 452A894A0FCC0A4C00360071 /* jfdctfst.c */, + 452A894B0FCC0A4C00360071 /* jfdctint.c */, + 452A894C0FCC0A4C00360071 /* jidctflt.c */, + 452A894D0FCC0A4C00360071 /* jidctfst.c */, + 452A894E0FCC0A4C00360071 /* jidctint.c */, + 452A894F0FCC0A4C00360071 /* jidctred.c */, + 452A89500FCC0A4C00360071 /* jinclude.h */, + 452A89510FCC0A4C00360071 /* jmemmgr.c */, + 452A89520FCC0A4C00360071 /* jmemnobs.c */, + 452A89530FCC0A4C00360071 /* jmemsys.h */, + 452A89540FCC0A4C00360071 /* jmorecfg.h */, + 452A89550FCC0A4C00360071 /* jpegint.h */, + 452A89560FCC0A4C00360071 /* jpeglib.h */, + 452A89570FCC0A4C00360071 /* jquant1.c */, + 452A89580FCC0A4C00360071 /* jquant2.c */, + 452A89590FCC0A4C00360071 /* jutils.c */, + 452A895A0FCC0A4C00360071 /* jversion.h */, + ); + name = jpeglib; + sourceTree = ""; + }; + 452A88EB0FCC0A1E00360071 /* zlib */ = { + isa = PBXGroup; + children = ( + 452A88ED0FCC0A2D00360071 /* adler32.c */, + 452A88EE0FCC0A2D00360071 /* compress.c */, + 452A88EF0FCC0A2D00360071 /* crc32.c */, + 452A88F00FCC0A2D00360071 /* crc32.h */, + 452A88F10FCC0A2D00360071 /* deflate.c */, + 452A88F20FCC0A2D00360071 /* deflate.h */, + 452A88F40FCC0A2D00360071 /* infback.c */, + 452A88F50FCC0A2D00360071 /* inffast.c */, + 452A88F60FCC0A2D00360071 /* inffast.h */, + 452A88F70FCC0A2D00360071 /* inffixed.h */, + 452A88F80FCC0A2D00360071 /* inflate.c */, + 452A88F90FCC0A2D00360071 /* inflate.h */, + 452A88FA0FCC0A2D00360071 /* inftrees.c */, + 452A88FB0FCC0A2D00360071 /* inftrees.h */, + 452A88FC0FCC0A2D00360071 /* minigzip.c */, + 452A88FD0FCC0A2D00360071 /* trees.c */, + 452A88FE0FCC0A2D00360071 /* trees.h */, + 452A88FF0FCC0A2D00360071 /* uncompr.c */, + 452A89000FCC0A2D00360071 /* zconf.h */, + 452A89010FCC0A2D00360071 /* zconf.in.h */, + 452A89020FCC0A2D00360071 /* zlib.h */, + 452A89030FCC0A2D00360071 /* zutil.c */, + 452A89040FCC0A2D00360071 /* zutil.h */, + 452A89050FCC0A2D00360071 /* gzio.c */, + ); + name = zlib; + sourceTree = ""; + }; + 52FBBE770D0CF0D3001C8B8A /* IPlug */ = { + isa = PBXGroup; + children = ( + 521F387D0D1704080060FE32 /* IPlug_include_in_plug_src.h */, + 521F387E0D1704080060FE32 /* IPlug_include_in_plug_hdr.h */, + 52E41BA70D14C09E00A0943B /* IPlugAU.h */, + 52E41BA80D14C09E00A0943B /* IPlugAU.cpp */, + 52A215760D11C20C006341F0 /* IPlugVST.h */, + 52A215770D11C20C006341F0 /* IPlugVST.cpp */, + 52A2156E0D11C200006341F0 /* IPlugBase.h */, + 52A2156F0D11C200006341F0 /* IPlugBase.cpp */, + 52A2156C0D11C1EC006341F0 /* Hosts.cpp */, + 52A2156A0D11C1E4006341F0 /* Hosts.h */, + 52FBBE870D0CF0D3001C8B8A /* Containers.h */, + 52FBBE880D0CF0D3001C8B8A /* IControl.cpp */, + 52FBBE890D0CF0D3001C8B8A /* IControl.h */, + 52FBBE8A0D0CF0D3001C8B8A /* IGraphics.cpp */, + 52FBBE8B0D0CF0D3001C8B8A /* IGraphics.h */, + 52A4AB420D2BFA510042A248 /* IGraphicsCarbon.h */, + 52A4AB430D2BFA510042A248 /* IGraphicsCarbon.cpp */, + 52780D4B0D20A1A000C2BCA7 /* IGraphicsCocoa.h */, + 52FBBE8D0D0CF0D3001C8B8A /* IGraphicsCocoa.mm */, + 52FBBE8E0D0CF0D3001C8B8A /* IGraphicsLice.cpp */, + 52FBBE8F0D0CF0D3001C8B8A /* IGraphicsLice.h */, + 52FBBE910D0CF0D3001C8B8A /* IGraphicsMac.h */, + 52FBBE920D0CF0D3001C8B8A /* IGraphicsMac.mm */, + 52FBBE960D0CF0D3001C8B8A /* IParam.cpp */, + 52FBBE970D0CF0D3001C8B8A /* IParam.h */, + 52FBBE9F0D0CF0D3001C8B8A /* IPlugStructs.cpp */, + 52FBBEA00D0CF0D3001C8B8A /* IPlugStructs.h */, + 52FBBEA10D0CF0D3001C8B8A /* Log.cpp */, + 52FBBEA20D0CF0D3001C8B8A /* Log.h */, + ); + name = IPlug; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC07A0554694100DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 52FBBEA60D0CF0D3001C8B8A /* Containers.h in Headers */, + 52FBBEA80D0CF0D3001C8B8A /* IControl.h in Headers */, + 52FBBEAA0D0CF0D3001C8B8A /* IGraphics.h in Headers */, + 52FBBEAE0D0CF0D3001C8B8A /* IGraphicsLice.h in Headers */, + 52FBBEB00D0CF0D3001C8B8A /* IGraphicsMac.h in Headers */, + 52FBBEB60D0CF0D3001C8B8A /* IParam.h in Headers */, + 52FBBEBC0D0CF0D3001C8B8A /* IPlugStructs.h in Headers */, + 52FBBEBE0D0CF0D3001C8B8A /* Log.h in Headers */, + 52A2156B0D11C1E4006341F0 /* Hosts.h in Headers */, + 52A215720D11C200006341F0 /* IPlugBase.h in Headers */, + 52A215780D11C20C006341F0 /* IPlugVST.h in Headers */, + 52E41BA90D14C09E00A0943B /* IPlugAU.h in Headers */, + 521F387F0D1704080060FE32 /* IPlug_include_in_plug_src.h in Headers */, + 521F38800D1704080060FE32 /* IPlug_include_in_plug_hdr.h in Headers */, + 52780D4C0D20A1A000C2BCA7 /* IGraphicsCocoa.h in Headers */, + 52A4AB440D2BFA510042A248 /* IGraphicsCarbon.h in Headers */, + 452A87500FCBFE1900360071 /* aeffect.h in Headers */, + 452A87510FCBFE1900360071 /* aeffectx.h in Headers */, + 452A87840FCBFFDD00360071 /* lice_bezier.h in Headers */, + 452A87870FCBFFDD00360071 /* lice_combine.h in Headers */, + 452A87880FCBFFDD00360071 /* lice_extended.h in Headers */, + 452A87980FCBFFDD00360071 /* lice_text.h in Headers */, + 452A879B0FCBFFDD00360071 /* lice.h in Headers */, + 452A87A50FCC004600360071 /* swell.h in Headers */, + 452A89090FCC0A2D00360071 /* crc32.h in Headers */, + 452A890B0FCC0A2D00360071 /* deflate.h in Headers */, + 452A890F0FCC0A2D00360071 /* inffast.h in Headers */, + 452A89100FCC0A2D00360071 /* inffixed.h in Headers */, + 452A89120FCC0A2D00360071 /* inflate.h in Headers */, + 452A89140FCC0A2D00360071 /* inftrees.h in Headers */, + 452A89170FCC0A2D00360071 /* trees.h in Headers */, + 452A89190FCC0A2D00360071 /* zconf.h in Headers */, + 452A891A0FCC0A2D00360071 /* zconf.in.h in Headers */, + 452A891B0FCC0A2D00360071 /* zlib.h in Headers */, + 452A891D0FCC0A2D00360071 /* zutil.h in Headers */, + 452A89630FCC0A4C00360071 /* jchuff.h in Headers */, + 452A89690FCC0A4C00360071 /* jconfig.h in Headers */, + 452A89750FCC0A4C00360071 /* jdct.h in Headers */, + 452A89780FCC0A4C00360071 /* jdhuff.h in Headers */, + 452A89830FCC0A4C00360071 /* jerror.h in Headers */, + 452A898B0FCC0A4C00360071 /* jinclude.h in Headers */, + 452A898E0FCC0A4C00360071 /* jmemsys.h in Headers */, + 452A898F0FCC0A4C00360071 /* jmorecfg.h in Headers */, + 452A89900FCC0A4C00360071 /* jpegint.h in Headers */, + 452A89910FCC0A4C00360071 /* jpeglib.h in Headers */, + 452A89950FCC0A4C00360071 /* jversion.h in Headers */, + 452A89AB0FCC0A6500360071 /* png.h in Headers */, + 452A89AC0FCC0A6500360071 /* pngconf.h in Headers */, + 452A8A030FCC0F4E00360071 /* swell-internal.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D2AAC07D0554694100DB518D /* IPlug */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "IPlug" */; + buildPhases = ( + D2AAC07A0554694100DB518D /* Headers */, + D2AAC07B0554694100DB518D /* Sources */, + D2AAC07C0554694100DB518D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IPlug; + productName = IPlug; + productReference = D2AAC07E0554694100DB518D /* libIPlug.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "IPlug" */; + compatibilityVersion = "Xcode 3.0"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* IPlug */; + productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC07D0554694100DB518D /* IPlug */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + D2AAC07B0554694100DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52FBBEA70D0CF0D3001C8B8A /* IControl.cpp in Sources */, + 52FBBEA90D0CF0D3001C8B8A /* IGraphics.cpp in Sources */, + 52FBBEAC0D0CF0D3001C8B8A /* IGraphicsCocoa.mm in Sources */, + 52FBBEAD0D0CF0D3001C8B8A /* IGraphicsLice.cpp in Sources */, + 52FBBEB10D0CF0D3001C8B8A /* IGraphicsMac.mm in Sources */, + 52FBBEB50D0CF0D3001C8B8A /* IParam.cpp in Sources */, + 52FBBEBB0D0CF0D3001C8B8A /* IPlugStructs.cpp in Sources */, + 52FBBEBD0D0CF0D3001C8B8A /* Log.cpp in Sources */, + 52A2156D0D11C1EC006341F0 /* Hosts.cpp in Sources */, + 52A215730D11C200006341F0 /* IPlugBase.cpp in Sources */, + 52A215790D11C20C006341F0 /* IPlugVST.cpp in Sources */, + 52E41BAA0D14C09E00A0943B /* IPlugAU.cpp in Sources */, + 52A4AB450D2BFA510042A248 /* IGraphicsCarbon.cpp in Sources */, + 452A87830FCBFFDD00360071 /* lice_arc.cpp in Sources */, + 452A87850FCBFFDD00360071 /* lice_bmp.cpp in Sources */, + 452A87860FCBFFDD00360071 /* lice_colorspace.cpp in Sources */, + 452A878F0FCBFFDD00360071 /* lice_image.cpp in Sources */, + 452A87900FCBFFDD00360071 /* lice_jpg.cpp in Sources */, + 452A87910FCBFFDD00360071 /* lice_line.cpp in Sources */, + 452A87940FCBFFDD00360071 /* lice_png.cpp in Sources */, + 452A87970FCBFFDD00360071 /* lice_text.cpp in Sources */, + 452A87990FCBFFDD00360071 /* lice_textnew.cpp in Sources */, + 452A879A0FCBFFDD00360071 /* lice.cpp in Sources */, + 452A89060FCC0A2D00360071 /* adler32.c in Sources */, + 452A89070FCC0A2D00360071 /* compress.c in Sources */, + 452A89080FCC0A2D00360071 /* crc32.c in Sources */, + 452A890A0FCC0A2D00360071 /* deflate.c in Sources */, + 452A890D0FCC0A2D00360071 /* infback.c in Sources */, + 452A890E0FCC0A2D00360071 /* inffast.c in Sources */, + 452A89110FCC0A2D00360071 /* inflate.c in Sources */, + 452A89130FCC0A2D00360071 /* inftrees.c in Sources */, + 452A89150FCC0A2D00360071 /* minigzip.c in Sources */, + 452A89160FCC0A2D00360071 /* trees.c in Sources */, + 452A89180FCC0A2D00360071 /* uncompr.c in Sources */, + 452A891C0FCC0A2D00360071 /* zutil.c in Sources */, + 452A891E0FCC0A2D00360071 /* gzio.c in Sources */, + 452A895D0FCC0A4C00360071 /* jcapimin.c in Sources */, + 452A895E0FCC0A4C00360071 /* jcapistd.c in Sources */, + 452A895F0FCC0A4C00360071 /* jccoefct.c in Sources */, + 452A89600FCC0A4C00360071 /* jccolor.c in Sources */, + 452A89610FCC0A4C00360071 /* jcdctmgr.c in Sources */, + 452A89620FCC0A4C00360071 /* jchuff.c in Sources */, + 452A89640FCC0A4C00360071 /* jcinit.c in Sources */, + 452A89650FCC0A4C00360071 /* jcmainct.c in Sources */, + 452A89660FCC0A4C00360071 /* jcmarker.c in Sources */, + 452A89670FCC0A4C00360071 /* jcmaster.c in Sources */, + 452A89680FCC0A4C00360071 /* jcomapi.c in Sources */, + 452A896A0FCC0A4C00360071 /* jcparam.c in Sources */, + 452A896B0FCC0A4C00360071 /* jcphuff.c in Sources */, + 452A896C0FCC0A4C00360071 /* jcprepct.c in Sources */, + 452A896D0FCC0A4C00360071 /* jcsample.c in Sources */, + 452A896E0FCC0A4C00360071 /* jctrans.c in Sources */, + 452A896F0FCC0A4C00360071 /* jdapimin.c in Sources */, + 452A89700FCC0A4C00360071 /* jdapistd.c in Sources */, + 452A89710FCC0A4C00360071 /* jdatadst.c in Sources */, + 452A89720FCC0A4C00360071 /* jdatasrc.c in Sources */, + 452A89730FCC0A4C00360071 /* jdcoefct.c in Sources */, + 452A89740FCC0A4C00360071 /* jdcolor.c in Sources */, + 452A89760FCC0A4C00360071 /* jddctmgr.c in Sources */, + 452A89770FCC0A4C00360071 /* jdhuff.c in Sources */, + 452A89790FCC0A4C00360071 /* jdinput.c in Sources */, + 452A897A0FCC0A4C00360071 /* jdmainct.c in Sources */, + 452A897B0FCC0A4C00360071 /* jdmarker.c in Sources */, + 452A897C0FCC0A4C00360071 /* jdmaster.c in Sources */, + 452A897D0FCC0A4C00360071 /* jdmerge.c in Sources */, + 452A897E0FCC0A4C00360071 /* jdphuff.c in Sources */, + 452A897F0FCC0A4C00360071 /* jdpostct.c in Sources */, + 452A89800FCC0A4C00360071 /* jdsample.c in Sources */, + 452A89810FCC0A4C00360071 /* jdtrans.c in Sources */, + 452A89820FCC0A4C00360071 /* jerror.c in Sources */, + 452A89840FCC0A4C00360071 /* jfdctflt.c in Sources */, + 452A89850FCC0A4C00360071 /* jfdctfst.c in Sources */, + 452A89860FCC0A4C00360071 /* jfdctint.c in Sources */, + 452A89870FCC0A4C00360071 /* jidctflt.c in Sources */, + 452A89880FCC0A4C00360071 /* jidctfst.c in Sources */, + 452A89890FCC0A4C00360071 /* jidctint.c in Sources */, + 452A898A0FCC0A4C00360071 /* jidctred.c in Sources */, + 452A898C0FCC0A4C00360071 /* jmemmgr.c in Sources */, + 452A898D0FCC0A4C00360071 /* jmemnobs.c in Sources */, + 452A89920FCC0A4C00360071 /* jquant1.c in Sources */, + 452A89930FCC0A4C00360071 /* jquant2.c in Sources */, + 452A89940FCC0A4C00360071 /* jutils.c in Sources */, + 452A89AA0FCC0A6500360071 /* png.c in Sources */, + 452A89AD0FCC0A6500360071 /* pngerror.c in Sources */, + 452A89AE0FCC0A6500360071 /* pnggccrd.c in Sources */, + 452A89AF0FCC0A6500360071 /* pngget.c in Sources */, + 452A89B00FCC0A6500360071 /* pngmem.c in Sources */, + 452A89B10FCC0A6500360071 /* pngpread.c in Sources */, + 452A89B20FCC0A6500360071 /* pngread.c in Sources */, + 452A89B30FCC0A6500360071 /* pngrtran.c in Sources */, + 452A89B40FCC0A6500360071 /* pngrutil.c in Sources */, + 452A89B50FCC0A6500360071 /* pngset.c in Sources */, + 452A89B70FCC0A6500360071 /* pngtrans.c in Sources */, + 452A89B80FCC0A6500360071 /* pngvcrd.c in Sources */, + 452A89B90FCC0A6500360071 /* pngwio.c in Sources */, + 452A89BB0FCC0A6500360071 /* pngwtran.c in Sources */, + 452A89BC0FCC0A6500360071 /* pngwutil.c in Sources */, + 452A89BD0FCC0A6500360071 /* pngrio.c in Sources */, + 45B61BC610B15E25009E1E8C /* swell-gdi.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB921F08733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlug_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = _DEBUG; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../wdl/lice/build/Debug\"", + ); + PRODUCT_NAME = IPlug; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DEB922008733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlug_Prefix.pch; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../wdl/lice/build/Release\"", + ); + PRODUCT_NAME = IPlug; + }; + name = Release; + }; + 1DEB922308733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_PREPROCESSOR_DEFINITIONS = _DEBUG; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + }; + name = Debug; + }; + 1DEB922408733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + }; + name = Release; + }; + 528359A40D7F0BF500577159 /* Tracer */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + }; + name = Tracer; + }; + 528359A50D7F0BF500577159 /* Tracer */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlug_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = TRACER_BUILD; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../wdl/lice/build/Release\"", + ); + PRODUCT_NAME = IPlug; + }; + name = Tracer; + }; + 52CC00400D2DFBE900EE9465 /* Reaper Special x86 */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + }; + name = "Reaper Special x86"; + }; + 52CC00410D2DFBE900EE9465 /* Reaper Special x86 */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlug_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = REAPER_SPECIAL; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../wdl/lice/build/Release\"", + ); + PRODUCT_NAME = IPlug; + }; + name = "Reaper Special x86"; + }; + 52CC00440D2DFC3900EE9465 /* Reaper Special ppc */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_EXPAND_BUILD_SETTINGS = YES; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + }; + name = "Reaper Special ppc"; + }; + 52CC00450D2DFC3900EE9465 /* Reaper Special ppc */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = IPlug_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = REAPER_SPECIAL; + INSTALL_PATH = /usr/local/lib; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../wdl/lice/build/Release\"", + ); + PRODUCT_NAME = IPlug; + }; + name = "Reaper Special ppc"; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "IPlug" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB921F08733DC00010E9CD /* Debug */, + 1DEB922008733DC00010E9CD /* Release */, + 528359A50D7F0BF500577159 /* Tracer */, + 52CC00410D2DFBE900EE9465 /* Reaper Special x86 */, + 52CC00450D2DFC3900EE9465 /* Reaper Special ppc */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "IPlug" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB922308733DC00010E9CD /* Debug */, + 1DEB922408733DC00010E9CD /* Release */, + 528359A40D7F0BF500577159 /* Tracer */, + 52CC00400D2DFBE900EE9465 /* Reaper Special x86 */, + 52CC00440D2DFC3900EE9465 /* Reaper Special ppc */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/WDL/IPlug/IPlugAU.cpp b/WDL/IPlug/IPlugAU.cpp new file mode 100644 index 00000000..f883dd42 --- /dev/null +++ b/WDL/IPlug/IPlugAU.cpp @@ -0,0 +1,1558 @@ +#include "IPlugAU.h" +#include "IGraphicsMac.h" +#include "Log.h" +#include "Hosts.h" + +//#include "/Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h" + +#define kAudioUnitRemovePropertyListenerWithUserDataSelect 0x0012 + +typedef AudioStreamBasicDescription STREAM_DESC; + +/* inline */ void MakeDefaultASBD(STREAM_DESC* pASBD, double sampleRate, int nChannels, bool interleaved) +{ + memset(pASBD, 0, sizeof(STREAM_DESC)); + pASBD->mSampleRate = sampleRate; + pASBD->mFormatID = kAudioFormatLinearPCM; + pASBD->mFormatFlags = kAudioFormatFlagsCanonical; + pASBD->mBitsPerChannel = 8 * sizeof(AudioSampleType); + pASBD->mChannelsPerFrame = nChannels; + pASBD->mFramesPerPacket = 1; + int nBytes = sizeof(AudioSampleType); + if (interleaved) { + nBytes *= nChannels; + } + else { + pASBD->mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + } + pASBD->mBytesPerPacket = pASBD->mBytesPerFrame = nBytes; +} + +template +int PtrListAddFromStack(WDL_PtrList* pList, C* pStackInstance) +{ + C* pNew = new C; + memcpy(pNew, pStackInstance, sizeof(C)); + pList->Add(pNew); + return pList->GetSize() - 1; +} + +template +int PtrListInitialize(WDL_PtrList* pList, int size) +{ + for (int i = 0; i < size; ++i) { + C* pNew = new C; + memset(pNew, 0, sizeof(C)); + pList->Add(pNew); + } + return size; +} + +#define GET_COMP_PARAM(TYPE, IDX) *((TYPE*)&(params->params[IDX])) +#define NO_OP(select) case select: return badComponentSelector; + +// static +ComponentResult IPlugAU::IPlugAUEntry(ComponentParameters *params, void* pPlug) +{ + int select = params->what; + + Trace(TRACELOC, "(%d:%s)", select, AUSelectStr(select)); + + if (select == kComponentOpenSelect) { + IPlugAU* _this = MakePlug(); + _this->HostSpecificInit(); + _this->PruneUninitializedPresets(); + _this->mCI = GET_COMP_PARAM(ComponentInstance, 0); + SetComponentInstanceStorage(_this->mCI, (Handle) _this); + return noErr; + } + + IPlugAU* _this = (IPlugAU*) pPlug; + + if (select == kComponentCloseSelect) { + DELETE_NULL(_this); + return noErr; + } + + IPlugBase::IMutexLock lock(_this); + + switch (select) { + case kComponentVersionSelect: { + return _this->GetEffectVersion(false); + } + case kAudioUnitInitializeSelect: { + if (!(_this->CheckLegalIO())) { + return badComponentSelector; + } + _this->mActive = true; + _this->OnParamReset(); + _this->OnActivate(true); + return noErr; + } + case kAudioUnitUninitializeSelect: { + _this->mActive = false; + _this->ClearConnections(); + _this->OnActivate(false); + return noErr; + } + case kAudioUnitGetPropertyInfoSelect: { + AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); + AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); + AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); + UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 1); + Boolean* pWriteable = GET_COMP_PARAM(Boolean*, 0); + + UInt32 dataSize = 0; + if (!pDataSize) { + pDataSize = &dataSize; + } + Boolean writeable; + if (!pWriteable) { + pWriteable = &writeable; + } + *pWriteable = false; + return _this->GetProperty(propID, scope, element, pDataSize, pWriteable, 0); + } + case kAudioUnitGetPropertySelect: { + AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); + AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); + AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); + void* pData = GET_COMP_PARAM(void*, 1); + UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 0); + + UInt32 dataSize = 0; + if (!pDataSize) { + pDataSize = &dataSize; + } + Boolean writeable = false; + return _this->GetProperty(propID, scope, element, pDataSize, &writeable, pData); + } + case kAudioUnitSetPropertySelect: { + AudioUnitPropertyID propID = GET_COMP_PARAM(AudioUnitPropertyID, 4); + AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); + AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); + const void* pData = GET_COMP_PARAM(const void*, 1); + UInt32* pDataSize = GET_COMP_PARAM(UInt32*, 0); + return _this->SetProperty(propID, scope, element, pDataSize, pData); + } + case kAudioUnitAddPropertyListenerSelect: { + PropertyListener listener; + listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 2); + listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 1); + listener.mProcArgs = GET_COMP_PARAM(void*, 0); + int i, n = _this->mPropertyListeners.GetSize(); + for (i = 0; i < n; ++i) { + PropertyListener* pListener = _this->mPropertyListeners.Get(i); + if (listener.mPropID == pListener->mPropID && listener.mListenerProc == pListener->mListenerProc) { + return noErr; + } + } + PtrListAddFromStack(&(_this->mPropertyListeners), &listener); + return noErr; + } + case kAudioUnitRemovePropertyListenerSelect: { + PropertyListener listener; + listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 1); + listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 0); + int i, n = _this->mPropertyListeners.GetSize(); + for (i = 0; i < n; ++i) { + PropertyListener* pListener = _this->mPropertyListeners.Get(i); + if (listener.mPropID == pListener->mPropID && listener.mListenerProc == pListener->mListenerProc) { + _this->mPropertyListeners.Delete(i); + break; + } + } + return noErr; + } + case kAudioUnitRemovePropertyListenerWithUserDataSelect: { + PropertyListener listener; + listener.mPropID = GET_COMP_PARAM(AudioUnitPropertyID, 2); + listener.mListenerProc = GET_COMP_PARAM(AudioUnitPropertyListenerProc, 1); + listener.mProcArgs = GET_COMP_PARAM(void*, 0); + int i, n = _this->mPropertyListeners.GetSize(); + for (i = 0; i < n; ++i) { + PropertyListener* pListener = _this->mPropertyListeners.Get(i); + if (listener.mPropID == pListener->mPropID && + listener.mListenerProc == pListener->mListenerProc && listener.mProcArgs == pListener->mProcArgs) { + _this->mPropertyListeners.Delete(i); + break; + } + } + return noErr; + } + case kAudioUnitAddRenderNotifySelect: { + AURenderCallbackStruct acs; + acs.inputProc = GET_COMP_PARAM(AURenderCallback, 1); + acs.inputProcRefCon = GET_COMP_PARAM(void*, 0); + PtrListAddFromStack(&(_this->mRenderNotify), &acs); + return noErr; + } + case kAudioUnitRemoveRenderNotifySelect: { + AURenderCallbackStruct acs; + acs.inputProc = GET_COMP_PARAM(AURenderCallback, 1); + acs.inputProcRefCon = GET_COMP_PARAM(void*, 0); + int i, n = _this->mRenderNotify.GetSize(); + for (i = 0; i < n; ++i) { + AURenderCallbackStruct* pACS = _this->mRenderNotify.Get(i); + if (acs.inputProc == pACS->inputProc) { + _this->mRenderNotify.Delete(i); + break; + } + } + return noErr; + } + case kAudioUnitGetParameterSelect: { + AudioUnitParameterID paramID = GET_COMP_PARAM(AudioUnitParameterID, 3); + AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 2); + AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 1); + AudioUnitParameterValue* pValue = GET_COMP_PARAM(AudioUnitParameterValue*, 0); + return GetParamProc(pPlug, paramID, scope, element, pValue); + } + case kAudioUnitSetParameterSelect: { + AudioUnitParameterID paramID = GET_COMP_PARAM(AudioUnitParameterID, 4); + AudioUnitScope scope = GET_COMP_PARAM(AudioUnitScope, 3); + AudioUnitElement element = GET_COMP_PARAM(AudioUnitElement, 2); + AudioUnitParameterValue value = GET_COMP_PARAM(AudioUnitParameterValue, 1); + UInt32 offset = GET_COMP_PARAM(UInt32, 0); + return SetParamProc(pPlug, paramID, scope, element, value, offset); + } + case kAudioUnitScheduleParametersSelect: { + AudioUnitParameterEvent* pEvent = GET_COMP_PARAM(AudioUnitParameterEvent*, 1); + UInt32 nEvents = GET_COMP_PARAM(UInt32, 0); + for (int i = 0; i < nEvents; ++i, ++pEvent) { + if (pEvent->eventType == kParameterEvent_Immediate) { + ComponentResult r = SetParamProc(pPlug, pEvent->parameter, pEvent->scope, pEvent->element, + pEvent->eventValues.immediate.value, pEvent->eventValues.immediate.bufferOffset); + if (r != noErr) { + return r; + } + } + } + return noErr; + } + case kAudioUnitRenderSelect: { + AudioUnitRenderActionFlags* pFlags = GET_COMP_PARAM(AudioUnitRenderActionFlags*, 4); + const AudioTimeStamp* pTimestamp = GET_COMP_PARAM(AudioTimeStamp*, 3); + UInt32 outputBusIdx = GET_COMP_PARAM(UInt32, 2); + UInt32 nFrames = GET_COMP_PARAM(UInt32, 1); + AudioBufferList* pBufferList = GET_COMP_PARAM(AudioBufferList*, 0); + return RenderProc(_this, pFlags, pTimestamp, outputBusIdx, nFrames, pBufferList); + } + case kAudioUnitResetSelect: { + _this->Reset(); + return noErr; + } + case kMusicDeviceMIDIEventSelect: { // Ignore kMusicDeviceSysExSelect for now. + IMidiMsg msg; + msg.mStatus = GET_COMP_PARAM(UInt32, 3); + msg.mData1 = GET_COMP_PARAM(UInt32, 2); + msg.mData2 = GET_COMP_PARAM(UInt32, 1); + msg.mOffset = GET_COMP_PARAM(UInt32, 0); + _this->ProcessMidiMsg(&msg); + return noErr; + } + NO_OP(kMusicDeviceSysExSelect); + case kMusicDevicePrepareInstrumentSelect: { + return noErr; + } + case kMusicDeviceReleaseInstrumentSelect: { + return noErr; + } + case kMusicDeviceStartNoteSelect: { + MusicDeviceInstrumentID deviceID = GET_COMP_PARAM(MusicDeviceInstrumentID, 4); + MusicDeviceGroupID groupID = GET_COMP_PARAM(MusicDeviceGroupID, 3); + NoteInstanceID* pNoteID = GET_COMP_PARAM(NoteInstanceID*, 2); + UInt32 offset = GET_COMP_PARAM(UInt32, 1); + MusicDeviceNoteParams* pNoteParams = GET_COMP_PARAM(MusicDeviceNoteParams*, 0); + int note = (int) pNoteParams->mPitch; + *pNoteID = note; + IMidiMsg msg; + msg.MakeNoteOnMsg(note, (int) pNoteParams->mVelocity, offset); + return noErr; + } + case kMusicDeviceStopNoteSelect: { + MusicDeviceGroupID groupID = GET_COMP_PARAM(MusicDeviceGroupID, 2); + NoteInstanceID noteID = GET_COMP_PARAM(NoteInstanceID, 1); + UInt32 offset = GET_COMP_PARAM(UInt32, 0); + // noteID is supposed to be some incremented unique ID, but we're just storing note number in it. + IMidiMsg msg; + msg.MakeNoteOffMsg(noteID, offset); + return noErr; + } + case kComponentCanDoSelect: { + switch (params->params[0]) { + case kAudioUnitInitializeSelect: + case kAudioUnitUninitializeSelect: + case kAudioUnitGetPropertyInfoSelect: + case kAudioUnitGetPropertySelect: + case kAudioUnitSetPropertySelect: + case kAudioUnitAddPropertyListenerSelect: + case kAudioUnitRemovePropertyListenerSelect: + case kAudioUnitGetParameterSelect: + case kAudioUnitSetParameterSelect: + case kAudioUnitResetSelect: + case kAudioUnitRenderSelect: + case kAudioUnitAddRenderNotifySelect: + case kAudioUnitRemoveRenderNotifySelect: + case kAudioUnitScheduleParametersSelect: + return 1; + default: + return 0; + } + } + default: return badComponentSelector; + } +} + +struct AudioUnitCarbonViewCreateGluePB { + unsigned char componentFlags; + unsigned char componentParamSize; + short componentWhat; + ControlRef* outControl; + const Float32Point* inSize; + const Float32Point* inLocation; + ControlRef inParentControl; + WindowRef inWindow; + AudioUnit inAudioUnit; + AudioUnitCarbonView inView; +}; + +struct CarbonViewInstance { + ComponentInstance mCI; + IPlugAU* mPlug; +}; + +// static +ComponentResult IPlugAU::IPlugAUCarbonViewEntry(ComponentParameters *params, void* pView) +{ + int select = params->what; + + Trace(TRACELOC, "%d:%s", select, AUSelectStr(select)); + + if (select == kComponentOpenSelect) { + CarbonViewInstance* pCVI = new CarbonViewInstance; + pCVI->mCI = GET_COMP_PARAM(ComponentInstance, 0); + pCVI->mPlug = 0; + SetComponentInstanceStorage(pCVI->mCI, (Handle) pCVI); + return noErr; + } + + CarbonViewInstance* pCVI = (CarbonViewInstance*) pView; + + switch (select) { + case kComponentCloseSelect: { + IPlugAU* _this = pCVI->mPlug; + if (_this && _this->GetGUI()) { + _this->GetGUI()->CloseWindow(); + } + DELETE_NULL(pCVI); + return noErr; + } + case kAudioUnitCarbonViewCreateSelect: { + AudioUnitCarbonViewCreateGluePB* pb = (AudioUnitCarbonViewCreateGluePB*) params; + IPlugAU* _this = (IPlugAU*) GetComponentInstanceStorage(pb->inAudioUnit); + pCVI->mPlug = _this; + if (_this && _this->GetGUI()) { + *(pb->outControl) = (ControlRef) (_this->GetGUI()->OpenWindow(pb->inWindow, pb->inParentControl)); + return noErr; + } + return badComponentSelector; + } + default: return badComponentSelector; + } +} + +#define ASSERT_SCOPE(reqScope) if (scope != reqScope) { return kAudioUnitErr_InvalidProperty; } +#define ASSERT_INPUT_OR_GLOBAL_SCOPE \ + if (scope != kAudioUnitScope_Input && scope != kAudioUnitScope_Global) { \ + return kAudioUnitErr_InvalidProperty; \ + } +#undef NO_OP +#define NO_OP(propID) case propID: return kAudioUnitErr_InvalidProperty; + +// pData == 0 means return property info only. +ComponentResult IPlugAU::GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, + UInt32* pDataSize, Boolean* pWriteable, void* pData) +{ + Trace(TRACELOC, "%s(%d:%s):(%d:%s):%d", (pData ? "" : "info:"), propID, AUPropertyStr(propID), scope, AUScopeStr(scope), element); + + // Writeable defaults to false, we only need to set it if true. + + switch (propID) { + case kAudioUnitProperty_ClassInfo: { // 0, + *pDataSize = sizeof(CFPropertyListRef); + *pWriteable = true; + if (pData) { + CFPropertyListRef* pList = (CFPropertyListRef*) pData; + return GetState(pList); + } + return noErr; + } + case kAudioUnitProperty_MakeConnection: { // 1, + ASSERT_INPUT_OR_GLOBAL_SCOPE; + *pDataSize = sizeof(AudioUnitConnection); + *pWriteable = true; + return noErr; + } + case kAudioUnitProperty_SampleRate: { // 2, + *pDataSize = sizeof(Float64); + *pWriteable = true; + if (pData) { + *((Float64*) pData) = GetSampleRate(); + } + return noErr; + } + case kAudioUnitProperty_ParameterList: { // 3, listenable + int n = (scope == kAudioUnitScope_Global ? NParams() : 0); + *pDataSize = n * sizeof(AudioUnitParameterID); + if (pData && n) { + AudioUnitParameterID* pParamID = (AudioUnitParameterID*) pData; + for (int i = 0; i < n; ++i, ++pParamID) { + *pParamID = (AudioUnitParameterID) i; + } + } + return noErr; + } + case kAudioUnitProperty_ParameterInfo: { // 4, listenable + ASSERT_SCOPE(kAudioUnitScope_Global); + *pDataSize = sizeof(AudioUnitParameterInfo); + if (pData) { + AudioUnitParameterInfo* pInfo = (AudioUnitParameterInfo*) pData; + memset(pInfo, 0, sizeof(AudioUnitParameterInfo)); + pInfo->flags = kAudioUnitParameterFlag_CFNameRelease | + kAudioUnitParameterFlag_HasCFNameString | + kAudioUnitParameterFlag_IsReadable | + kAudioUnitParameterFlag_IsWritable; + IParam* pParam = GetParam(element); + const char* paramName = pParam->GetNameForHost(); + pInfo->cfNameString = MakeCFString(pParam->GetNameForHost()); + strcpy(pInfo->name, paramName); // Max 52. + switch (pParam->Type()) { + case IParam::kTypeBool: + pInfo->unit = kAudioUnitParameterUnit_Boolean; + break; + case IParam::kTypeEnum: + pInfo->unit = kAudioUnitParameterUnit_Indexed; + break; + default: { + const char* label = pParam->GetLabelForHost(); + if (CSTR_NOT_EMPTY(label)) { + pInfo->unit = kAudioUnitParameterUnit_CustomUnit; + pInfo->unitName = MakeCFString(label); + } + else { + pInfo->unit = kAudioUnitParameterUnit_Generic; + } + } + } + double vMin, vMax; + pParam->GetBounds(&vMin, &vMax); + pInfo->minValue = vMin; + pInfo->maxValue = vMax; + pInfo->defaultValue = pParam->Value(); + } + return noErr; + } + case kAudioUnitProperty_FastDispatch: { // 5, + return GetProc(element, pDataSize, pData); + } + NO_OP(kAudioUnitProperty_CPULoad); // 6, + case kAudioUnitProperty_StreamFormat: { // 8, + BusChannels* pBus = GetBus(scope, element); + if (!pBus) { + return kAudioUnitErr_InvalidProperty; + } + *pDataSize = sizeof(STREAM_DESC); + *pWriteable = true; + if (pData) { + int nChannels = pBus->mNHostChannels; // Report how many channels the host has connected. + if (nChannels < 0) { // Unless the host hasn't connected any yet, in which case report the default. + nChannels = pBus->mNPlugChannels; + } + STREAM_DESC* pASBD = (STREAM_DESC*) pData; + MakeDefaultASBD(pASBD, GetSampleRate(), nChannels, false); + } + return noErr; + } + case kAudioUnitProperty_ElementCount: { // 11, + *pDataSize = sizeof(UInt32); + if (pData) { + int n = 0; + if (scope == kAudioUnitScope_Input) { + n = mInBuses.GetSize(); + } + else + if (scope == kAudioUnitScope_Output) { + n = mOutBuses.GetSize(); + } + else + if (scope == kAudioUnitScope_Global) { + n = 1; + } + *((UInt32*) pData) = n; + } + return noErr; + } + case kAudioUnitProperty_Latency: { // 12, // listenable + ASSERT_SCOPE(kAudioUnitScope_Global); + *pDataSize = sizeof(Float64); + if (pData) { + *((Float64*) pData) = (double) GetLatency() / GetSampleRate(); + } + return noErr; + } + case kAudioUnitProperty_SupportedNumChannels: { // 13, + ASSERT_SCOPE(kAudioUnitScope_Global); + int n = mChannelIO.GetSize(); + *pDataSize = n * sizeof(AUChannelInfo); + if (pData) { + AUChannelInfo* pChInfo = (AUChannelInfo*) pData; + for (int i = 0; i < n; ++i, ++pChInfo) { + ChannelIO* pIO = mChannelIO.Get(i); + pChInfo->inChannels = pIO->mIn; + pChInfo->outChannels = pIO->mOut; + Trace(TRACELOC, "IO:%d:%d", pIO->mIn, pIO->mOut); + } + } + return noErr; + } + case kAudioUnitProperty_MaximumFramesPerSlice: { // 14, + ASSERT_SCOPE(kAudioUnitScope_Global); + *pDataSize = sizeof(UInt32); + *pWriteable = true; + if (pData) { + *((UInt32*) pData) = GetBlockSize(); + } + return noErr; + } + NO_OP(kAudioUnitProperty_SetExternalBuffer); // 15, + case kAudioUnitProperty_ParameterValueStrings: { // 16, + ASSERT_SCOPE(kAudioUnitScope_Global); + IParam* pParam = GetParam(element); + int n = pParam->GetNDisplayTexts(); + if (!n) { + *pDataSize = 0; + return kAudioUnitErr_InvalidProperty; + } + *pDataSize = sizeof(CFArrayRef); + if (pData) { + CFMutableArrayRef nameArray = CFArrayCreateMutable(0, n, 0); + for (int i = 0; i < n; ++i) { + const char* str = pParam->GetDisplayText(i); + CFArrayAppendValue(nameArray, MakeCFString(str)); // Release here? + } + *((CFArrayRef*) pData) = nameArray; + } + return noErr; + } + case kAudioUnitProperty_GetUIComponentList: { // 18, + if (GetGUI()) { + *pDataSize = sizeof(ComponentDescription); + if (pData) { + ComponentDescription* pDesc = (ComponentDescription*) pData; + pDesc->componentType = kAudioUnitCarbonViewComponentType; + pDesc->componentSubType = GetUniqueID(); + pDesc->componentManufacturer = GetMfrID(); + pDesc->componentFlags = 0; + pDesc->componentFlagsMask = 0; + } + return noErr; + } + return kAudioUnitErr_InvalidProperty; + } + NO_OP(kAudioUnitProperty_AudioChannelLayout); // 19, + case kAudioUnitProperty_TailTime: { // 20, // listenable + return GetProperty(kAudioUnitProperty_Latency, scope, element, pDataSize, pWriteable, pData); + } + case kAudioUnitProperty_BypassEffect: { // 21, + ASSERT_SCOPE(kAudioUnitScope_Global); + *pWriteable = true; + *pDataSize = sizeof(UInt32); + if (pData) { + *((UInt32*) pData) = (mBypassed ? 1 : 0); + } + return noErr; + } + case kAudioUnitProperty_LastRenderError: { // 22, + ASSERT_SCOPE(kAudioUnitScope_Global); + *pDataSize = sizeof(OSStatus); + if (pData) { + *((OSStatus*) pData) = noErr; + } + return noErr; + } + case kAudioUnitProperty_SetRenderCallback: { // 23, + ASSERT_INPUT_OR_GLOBAL_SCOPE; + if (element >= mInBuses.GetSize()) { + return kAudioUnitErr_InvalidProperty; + } + *pDataSize = sizeof(AURenderCallbackStruct); + *pWriteable = true; + return noErr; + } + case kAudioUnitProperty_FactoryPresets: { // 24, // listenable + *pDataSize = sizeof(CFArrayRef); + if (pData) { + int i, n = NPresets(); + CFMutableArrayRef presetArray = CFArrayCreateMutable(0, n, 0); + for (i = 0; i < n; ++i) { + AUPreset* pAUPreset = new AUPreset; + pAUPreset->presetNumber = i; + pAUPreset->presetName = MakeCFString(GetPresetName(i)); + CFArrayAppendValue(presetArray, pAUPreset); + } + *((CFMutableArrayRef*) pData) = presetArray; + } + return noErr; + } + NO_OP(kAudioUnitProperty_ContextName); // 25, + NO_OP(kAudioUnitProperty_RenderQuality); // 26, + case kAudioUnitProperty_HostCallbacks: { // 27, + ASSERT_SCOPE(kAudioUnitScope_Global); + *pDataSize = sizeof(HostCallbackInfo); + *pWriteable = true; + return noErr; + } + NO_OP(kAudioUnitProperty_InPlaceProcessing); // 29, + NO_OP(kAudioUnitProperty_ElementName); // 30, + case kAudioUnitProperty_CocoaUI: { // 31, + if (GetGUI() && IGraphicsMac::GetUserOSVersion() >= 0x1050) { + *pDataSize = sizeof(AudioUnitCocoaViewInfo); // Just one view. + if (pData) { + AudioUnitCocoaViewInfo* pViewInfo = (AudioUnitCocoaViewInfo*) pData; + CFStrLocal bundleID(mOSXBundleID.Get()); + CFBundleRef pBundle = CFBundleGetBundleWithIdentifier(bundleID.mCFStr); + CFURLRef url = CFBundleCopyBundleURL(pBundle); + pViewInfo->mCocoaAUViewBundleLocation = url; + pViewInfo->mCocoaAUViewClass[0] = MakeCFString(mCocoaViewFactoryClassName.Get()); + } + return noErr; + } + return kAudioUnitErr_InvalidProperty; + } + NO_OP(kAudioUnitProperty_SupportedChannelLayoutTags);// 32, + case kAudioUnitProperty_ParameterIDName: { // 34, + *pDataSize = sizeof(AudioUnitParameterIDName); + if (pData && scope == kAudioUnitScope_Global) { + AudioUnitParameterIDName* pIDName = (AudioUnitParameterIDName*) pData; + IParam* pParam = GetParam(pIDName->inID); + char cStr[MAX_PARAM_NAME_LEN]; + strcpy(cStr, pParam->GetNameForHost()); + if (pIDName->inDesiredLength != kAudioUnitParameterName_Full) { + int n = MIN(MAX_PARAM_NAME_LEN - 1, pIDName->inDesiredLength); + cStr[n] = '\0'; + } + pIDName->outName = MakeCFString(cStr); + } + return noErr; + } + NO_OP(kAudioUnitProperty_ParameterClumpName); // 35, + case kAudioUnitProperty_CurrentPreset: // 28, + case kAudioUnitProperty_PresentPreset: { // 36, // listenable + *pDataSize = sizeof(AUPreset); + *pWriteable = true; + if (pData) { + AUPreset* pAUPreset = (AUPreset*) pData; + pAUPreset->presetNumber = GetCurrentPresetIdx(); + const char* name = GetPresetName(pAUPreset->presetNumber); + pAUPreset->presetName = MakeCFString(name); + } + return noErr; + } + NO_OP(kAudioUnitProperty_OfflineRender); // 37, + case kAudioUnitProperty_ParameterStringFromValue: { // 33, + *pDataSize = sizeof(AudioUnitParameterStringFromValue); + if (pData && scope == kAudioUnitScope_Global) { + AudioUnitParameterStringFromValue* pSFV = (AudioUnitParameterStringFromValue*) pData; + IParam* pParam = GetParam(pSFV->inParamID); + int v = (pSFV->inValue ? *(pSFV->inValue) : pParam->Int()); + const char* str = pParam->GetDisplayText(v); + pSFV->outString = MakeCFString(str); + } + return noErr; + } + case kAudioUnitProperty_ParameterValueFromString: { // 38, + *pDataSize = sizeof(AudioUnitParameterValueFromString); + if (pData) { + AudioUnitParameterValueFromString* pVFS = (AudioUnitParameterValueFromString*) pData; + if (scope == kAudioUnitScope_Global) { + CStrLocal cStr(pVFS->inString); + IParam* pParam = GetParam(pVFS->inParamID); + int v; + if (pParam->MapDisplayText(cStr.mCStr, &v)) { + pVFS->outValue = (AudioUnitParameterValue) v; + } + } + } + return noErr; + } + NO_OP(kAudioUnitProperty_IconLocation); // 39, + NO_OP(kAudioUnitProperty_PresentationLatency); // 40, + NO_OP(kAudioUnitProperty_DependentParameters); // 45, + case kMusicDeviceProperty_InstrumentCount: { + ASSERT_SCOPE(kAudioUnitScope_Global); + if (IsInst()) { + *pDataSize = sizeof(UInt32); + if (pData) { + *((UInt32*) pData) = 1; //(mBypassed ? 1 : 0); + } + return noErr; + } + else { + return kAudioUnitErr_InvalidProperty; + } + } + + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 + NO_OP(kAudioUnitProperty_AUHostIdentifier); // 46, + NO_OP(kAudioUnitProperty_MIDIOutputCallbackInfo); // 47, + NO_OP(kAudioUnitProperty_MIDIOutputCallback); // 48, + NO_OP(kAudioUnitProperty_InputSamplesInOutput); // 49, + NO_OP(kAudioUnitProperty_ClassInfoFromDocument); // 50 + #endif + + default: { + return kAudioUnitErr_InvalidProperty; + } + } +} + +ComponentResult IPlugAU::SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, + UInt32* pDataSize, const void* pData) +{ + Trace(TRACELOC, "(%d:%s):(%d:%s):%d", propID, AUPropertyStr(propID), scope, AUScopeStr(scope), element); + + InformListeners(propID, scope); + + switch (propID) { + + case kAudioUnitProperty_ClassInfo: { // 0, + return SetState(*((CFPropertyListRef*) pData)); + } + case kAudioUnitProperty_MakeConnection: { // 1, + ASSERT_INPUT_OR_GLOBAL_SCOPE; + AudioUnitConnection* pAUC = (AudioUnitConnection*) pData; + if (pAUC->destInputNumber >= mInBusConnections.GetSize()) { + return kAudioUnitErr_InvalidProperty; + } + InputBusConnection* pInBusConn = mInBusConnections.Get(pAUC->destInputNumber); + memset(pInBusConn, 0, sizeof(InputBusConnection)); + bool negotiatedOK = true; + if (pAUC->sourceAudioUnit) { // Opening connection. + AudioStreamBasicDescription srcASBD; + UInt32 size = sizeof(AudioStreamBasicDescription); + negotiatedOK = // Ask whoever is sending us audio what the format is. + (AudioUnitGetProperty(pAUC->sourceAudioUnit, kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, pAUC->sourceOutputNumber, &srcASBD, &size) == noErr); + negotiatedOK &= // Try to set our own format to match. + (SetProperty(kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, + pAUC->destInputNumber, &size, &srcASBD) == noErr); + if (negotiatedOK) { // Connection terms successfully negotiated. + pInBusConn->mUpstreamUnit = pAUC->sourceAudioUnit; + pInBusConn->mUpstreamBusIdx = pAUC->sourceOutputNumber; + // Will the upstream unit give us a fast render proc for input? + AudioUnitRenderProc srcRenderProc; + size = sizeof(AudioUnitRenderProc); + if (AudioUnitGetProperty(pAUC->sourceAudioUnit, kAudioUnitProperty_FastDispatch, kAudioUnitScope_Global, kAudioUnitRenderSelect, + &srcRenderProc, &size) == noErr) { + // Yes, we got a fast render proc, and we also need to store the pointer to the upstream audio unit object. + pInBusConn->mUpstreamRenderProc = srcRenderProc; + pInBusConn->mUpstreamObj = GetComponentInstanceStorage(pAUC->sourceAudioUnit); + } + // Else no fast render proc, so leave the input bus connection struct's upstream render proc and upstream object empty, + // and we will need to make a component call through the component manager to get input data. + } + // Else this is a call to close the connection, which we effectively did by clearing the InputBusConnection struct, + // which counts as a successful negotiation. + } + AssessInputConnections(); + return (negotiatedOK ? noErr : kAudioUnitErr_InvalidProperty); + } + case kAudioUnitProperty_SampleRate: { // 2, + SetSampleRate(*((Float64*) pData)); + Reset(); + return noErr; + } + NO_OP(kAudioUnitProperty_ParameterList); // 3, + NO_OP(kAudioUnitProperty_ParameterInfo); // 4, + NO_OP(kAudioUnitProperty_FastDispatch); // 5, + NO_OP(kAudioUnitProperty_CPULoad); // 6, + case kAudioUnitProperty_StreamFormat: { // 8, + AudioStreamBasicDescription* pASBD = (AudioStreamBasicDescription*) pData; + int nHostChannels = pASBD->mChannelsPerFrame; + BusChannels* pBus = GetBus(scope, element); + if (!pBus) { + return kAudioUnitErr_InvalidProperty; + } + pBus->mNHostChannels = 0; + // The connection is OK if the plugin expects the same number of channels as the host is attempting to connect, + // or if the plugin supports mono channels (meaning it's flexible about how many inputs to expect) + // and the plugin supports at least as many channels as the host is attempting to connect. + bool connectionOK = (nHostChannels > 0); + connectionOK &= CheckLegalIO(scope, element, nHostChannels); + connectionOK &= (pASBD->mFormatID == kAudioFormatLinearPCM && pASBD->mFormatFlags & kAudioFormatFlagsCanonical); + + Trace(TRACELOC, "%d:%d:%s:%s:%s", + nHostChannels, pBus->mNPlugChannels, + (pASBD->mFormatID == kAudioFormatLinearPCM ? "linearPCM" : "notLinearPCM"), + (pASBD->mFormatFlags & kAudioFormatFlagsCanonical ? "canonicalFormat" : "notCanonicalFormat"), + (connectionOK ? "connectionOK" : "connectionNotOK")); + + // bool interleaved = !(pASBD->mFormatFlags & kAudioFormatFlagIsNonInterleaved); + if (connectionOK) { + pBus->mNHostChannels = nHostChannels; + if (pASBD->mSampleRate > 0.0) { + SetSampleRate(pASBD->mSampleRate); + } + } + AssessInputConnections(); + return (connectionOK ? noErr : kAudioUnitErr_InvalidProperty); + } + NO_OP(kAudioUnitProperty_ElementCount); // 11, + NO_OP(kAudioUnitProperty_Latency); // 12, + NO_OP(kAudioUnitProperty_SupportedNumChannels); // 13, + case kAudioUnitProperty_MaximumFramesPerSlice: { // 14, + SetBlockSize(*((UInt32*) pData)); + Reset(); + return noErr; + } + NO_OP(kAudioUnitProperty_SetExternalBuffer); // 15, + NO_OP(kAudioUnitProperty_ParameterValueStrings); // 16, + NO_OP(kAudioUnitProperty_GetUIComponentList); // 18, + NO_OP(kAudioUnitProperty_AudioChannelLayout); // 19, + NO_OP(kAudioUnitProperty_TailTime); // 20, + case kAudioUnitProperty_BypassEffect: { // 21, + mBypassed = (*((UInt32*) pData) != 0); + Reset(); + return noErr; + } + NO_OP(kAudioUnitProperty_LastRenderError); // 22, + case kAudioUnitProperty_SetRenderCallback: { // 23, + ASSERT_SCOPE(kAudioUnitScope_Input); // if global scope, set all + if (element >= mInBusConnections.GetSize()) { + return kAudioUnitErr_InvalidProperty; + } + InputBusConnection* pInBusConn = mInBusConnections.Get(element); + memset(pInBusConn, 0, sizeof(InputBusConnection)); + AURenderCallbackStruct* pCS = (AURenderCallbackStruct*) pData; + if (pCS->inputProc != 0) { + pInBusConn->mUpstreamRenderCallback = *pCS; + } + AssessInputConnections(); + return noErr; + } + NO_OP(kAudioUnitProperty_FactoryPresets); // 24, + NO_OP(kAudioUnitProperty_ContextName); // 25, + NO_OP(kAudioUnitProperty_RenderQuality); // 26, + case kAudioUnitProperty_HostCallbacks: { // 27, + ASSERT_SCOPE(kAudioUnitScope_Global); + memcpy(&mHostCallbacks, pData, sizeof(HostCallbackInfo)); + return noErr; + } + NO_OP(kAudioUnitProperty_InPlaceProcessing); // 29, + NO_OP(kAudioUnitProperty_ElementName); // 30, + NO_OP(kAudioUnitProperty_CocoaUI); // 31, + NO_OP(kAudioUnitProperty_SupportedChannelLayoutTags); // 32, + NO_OP(kAudioUnitProperty_ParameterIDName); // 34, + NO_OP(kAudioUnitProperty_ParameterClumpName); // 35, + case kAudioUnitProperty_CurrentPreset: // 28, + case kAudioUnitProperty_PresentPreset: { // 36, + int presetIdx = ((AUPreset*) pData)->presetNumber; + RestorePreset(presetIdx); + return noErr; + } + NO_OP(kAudioUnitProperty_OfflineRender); // 37, + NO_OP(kAudioUnitProperty_ParameterStringFromValue); // 33, + NO_OP(kAudioUnitProperty_ParameterValueFromString); // 38, + NO_OP(kAudioUnitProperty_IconLocation); // 39, + NO_OP(kAudioUnitProperty_PresentationLatency); // 40, + NO_OP(kAudioUnitProperty_DependentParameters); // 45, + + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 + case kAudioUnitProperty_AUHostIdentifier: { // 46, + AUHostIdentifier* pHostID = (AUHostIdentifier*) pData; + CStrLocal hostStr(pHostID->hostName); + int hostVer = (pHostID->hostVersion.majorRev << 16) + (pHostID->hostVersion.minorAndBugRev << 8); + SetHost("", hostStr.mCStr, hostVer); + return noErr; + } + NO_OP(kAudioUnitProperty_MIDIOutputCallbackInfo); // 47, + NO_OP(kAudioUnitProperty_MIDIOutputCallback); // 48, + NO_OP(kAudioUnitProperty_InputSamplesInOutput); // 49, + NO_OP(kAudioUnitProperty_ClassInfoFromDocument) // 50 + #endif + + default: { + return kAudioUnitErr_InvalidProperty; + } + } +} + +const char* AUInputTypeStr(IPlugAU::EAUInputType type) +{ + switch (type) { + case IPlugAU::eDirectFastProc: return "DirectFastProc"; + case IPlugAU::eDirectNoFastProc: return "DirectNoFastProc"; + case IPlugAU::eRenderCallback: return "RenderCallback"; + case IPlugAU::eNotConnected: + default: return "NotConnected"; + } +} + +int IPlugAU::NHostChannelsConnected(WDL_PtrList* pBuses, int excludeIdx) +{ + bool init = false; + int nCh = 0, n = pBuses->GetSize(); + for (int i = 0; i < n; ++i) { + if (i != excludeIdx) { + int nHostChannels = pBuses->Get(i)->mNHostChannels; + if (nHostChannels >= 0) { + nCh += nHostChannels; + init = true; + } + } + } + if (init) { + return nCh; + } + return -1; +} + +bool IPlugAU::CheckLegalIO(AudioUnitScope scope, int busIdx, int nChannels) +{ + if (scope == kAudioUnitScope_Input) { + int nIn = MAX(NHostChannelsConnected(&mInBuses, busIdx), 0); + int nOut = (mActive ? NHostChannelsConnected(&mOutBuses) : -1); + return LegalIO(nIn + nChannels, nOut); + } + else { + int nIn = (mActive ? NHostChannelsConnected(&mInBuses) : -1); + int nOut = MAX(NHostChannelsConnected(&mOutBuses, busIdx), 0); + return LegalIO(nIn, nOut + nChannels); + } +} + +bool IPlugAU::CheckLegalIO() +{ + int nIn = NHostChannelsConnected(&mInBuses); + int nOut = NHostChannelsConnected(&mOutBuses); + return ((!nIn && !nOut) || LegalIO(nIn, nOut)); +} + +void IPlugAU::AssessInputConnections() +{ + TRACE; + IMutexLock lock(this); + + SetInputChannelConnections(0, NInChannels(), false); + + int nIn = mInBuses.GetSize(); + for (int i = 0; i < nIn; ++i) { + BusChannels* pInBus = mInBuses.Get(i); + InputBusConnection* pInBusConn = mInBusConnections.Get(i); + + // AU supports 3 ways to get input from the host (or whoever is upstream). + if (pInBusConn->mUpstreamRenderProc && pInBusConn->mUpstreamObj) { + // 1: direct input connection with fast render proc (and buffers) supplied by the upstream unit. + pInBusConn->mInputType = eDirectFastProc; + } + else + if (pInBusConn->mUpstreamUnit) { + // 2: direct input connection with no render proc, buffers supplied by the upstream unit. + pInBusConn->mInputType = eDirectNoFastProc; + } + else + if (pInBusConn->mUpstreamRenderCallback.inputProc) { + // 3: no direct connection, render callback, buffers supplied by us. + pInBusConn->mInputType = eRenderCallback; + } + else { + pInBusConn->mInputType = eNotConnected; + } + pInBus->mConnected = (pInBusConn->mInputType != eNotConnected); + + int startChannelIdx = pInBus->mPlugChannelStartIdx; + if (pInBus->mConnected) { + // There's an input connection, so we need to tell the plug to expect however many channels + // are in the negotiated host stream format. + if (pInBus->mNHostChannels < 0) { + // The host set up a connection without specifying how many channels in the stream. + // Assume the host will send all the channels the plugin asks for, and hope for the best. + Trace(TRACELOC, "AssumeChannels:%d", pInBus->mNPlugChannels); + pInBus->mNHostChannels = pInBus->mNPlugChannels; + } + int nConnected = pInBus->mNHostChannels; + int nUnconnected = MAX(pInBus->mNPlugChannels - nConnected, 0); + SetInputChannelConnections(startChannelIdx, nConnected, true); + SetInputChannelConnections(startChannelIdx + nConnected, nUnconnected, false); + } + + Trace(TRACELOC, "%d:%s:%d:%d:%d", i, AUInputTypeStr(pInBusConn->mInputType), startChannelIdx, pInBus->mNPlugChannels, pInBus->mNHostChannels); + } +} + +inline void PutNumberInDict(CFMutableDictionaryRef pDict, const char* key, void* pNumber, CFNumberType type) +{ + CFStrLocal cfKey(key); + CFNumberRef pValue = CFNumberCreate(0, type, pNumber); + CFDictionarySetValue(pDict, cfKey.mCFStr, pValue); + CFRelease(pValue); +} + +inline void PutStrInDict(CFMutableDictionaryRef pDict, const char* key, const char* value) +{ + CFStrLocal cfKey(key); + CFStrLocal cfValue(value); + CFDictionarySetValue(pDict, cfKey.mCFStr, cfValue.mCFStr); +} + +inline void PutDataInDict(CFMutableDictionaryRef pDict, const char* key, ByteChunk* pChunk) +{ + CFStrLocal cfKey(key); + CFDataRef pData = CFDataCreate(0, pChunk->GetBytes(), pChunk->Size()); + CFDictionarySetValue(pDict, cfKey.mCFStr, pData); + CFRelease(pData); +} + +inline bool GetNumberFromDict(CFDictionaryRef pDict, const char* key, void* pNumber, CFNumberType type) +{ + CFStrLocal cfKey(key); + CFNumberRef pValue = (CFNumberRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); + if (pValue) { + CFNumberGetValue(pValue, type, pNumber); + return true; + } + return false; +} + +inline bool GetStrFromDict(CFDictionaryRef pDict, const char* key, char* value) +{ + CFStrLocal cfKey(key); + CFStringRef pValue = (CFStringRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); + if (pValue) { + CStrLocal cStr(pValue); + strcpy(value, cStr.mCStr); + return true; + } + value[0] = '\0'; + return false; +} + +inline bool GetDataFromDict(CFDictionaryRef pDict, const char* key, ByteChunk* pChunk) +{ + CFStrLocal cfKey(key); + CFDataRef pData = (CFDataRef) CFDictionaryGetValue(pDict, cfKey.mCFStr); + if (pData) { + int n = CFDataGetLength(pData); + pChunk->Resize(n); + memcpy(pChunk->GetBytes(), CFDataGetBytePtr(pData), n); + return true; + } + return false; +} + +ComponentResult IPlugAU::GetState(CFPropertyListRef* ppPropList) +{ + ComponentDescription cd; + ComponentResult r = GetComponentInfo((Component) mCI, &cd, 0, 0, 0); + if (r != noErr) { + return r; + } + + CFMutableDictionaryRef pDict = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + int version = GetEffectVersion(false); + PutNumberInDict(pDict, kAUPresetVersionKey, &version, kCFNumberSInt32Type); + PutNumberInDict(pDict, kAUPresetTypeKey, &(cd.componentType), kCFNumberSInt32Type); + PutNumberInDict(pDict, kAUPresetSubtypeKey, &(cd.componentSubType), kCFNumberSInt32Type); + PutNumberInDict(pDict, kAUPresetManufacturerKey, &(cd.componentManufacturer), kCFNumberSInt32Type); + PutStrInDict(pDict, kAUPresetNameKey, GetPresetName(GetCurrentPresetIdx())); + + ByteChunk chunk; + if (DoesStateChunks()) { + if (SerializeState(&chunk)) { + PutDataInDict(pDict, kAUPresetDataKey, &chunk); + } + } + else { + SerializeParams(&chunk); + PutDataInDict(pDict, kAUPresetDataKey, &chunk); + } + + *ppPropList = pDict; +TRACE; + return noErr; +} + +ComponentResult IPlugAU::SetState(CFPropertyListRef pPropList) +{ + ComponentDescription cd; + ComponentResult r = GetComponentInfo((Component) mCI, &cd, 0, 0, 0); + if (r != noErr) { + return r; + } + + CFDictionaryRef pDict = (CFDictionaryRef) pPropList; + int version, type, subtype, mfr; + char presetName[64]; + if (!GetNumberFromDict(pDict, kAUPresetVersionKey, &version, kCFNumberSInt32Type) || + !GetNumberFromDict(pDict, kAUPresetTypeKey, &type, kCFNumberSInt32Type) || + !GetNumberFromDict(pDict, kAUPresetSubtypeKey, &subtype, kCFNumberSInt32Type) || + !GetNumberFromDict(pDict, kAUPresetManufacturerKey, &mfr, kCFNumberSInt32Type) || + !GetStrFromDict(pDict, kAUPresetNameKey, presetName) || + //version != GetEffectVersion(false) || + type != cd.componentType || + subtype != cd.componentSubType || + mfr != cd.componentManufacturer) { + return kAudioUnitErr_InvalidPropertyValue; + } + RestorePreset(presetName); + + ByteChunk chunk; + if (!GetDataFromDict(pDict, kAUPresetDataKey, &chunk)) { + return kAudioUnitErr_InvalidPropertyValue; + } + + if (DoesStateChunks()) { + if (!UnserializeState(&chunk, 0)) { + return kAudioUnitErr_InvalidPropertyValue; + } + } + else { + if (!UnserializeParams(&chunk, 0)) { + return kAudioUnitErr_InvalidPropertyValue; + } + } + + RedrawParamControls(); + return noErr; +} + +// pData == 0 means return property info only. +ComponentResult IPlugAU::GetProc(AudioUnitElement element, UInt32* pDataSize, void* pData) +{ + Trace(TRACELOC, "%s:(%d:%s)", (pData ? "" : "Info"), element, AUSelectStr(element)); + + switch (element) { + case kAudioUnitGetParameterSelect: { + *pDataSize = sizeof(AudioUnitGetParameterProc); + if (pData) { + *((AudioUnitGetParameterProc*) pData) = (AudioUnitGetParameterProc) IPlugAU::GetParamProc; + } + return noErr; + } + case kAudioUnitSetParameterSelect: { + *pDataSize = sizeof(AudioUnitSetParameterProc); + if (pData) { + *((AudioUnitSetParameterProc*) pData) = (AudioUnitSetParameterProc) IPlugAU::SetParamProc; + } + return noErr; + } + case kAudioUnitRenderSelect: { + *pDataSize = sizeof(AudioUnitRenderProc); + if (pData) { + *((AudioUnitRenderProc*) pData) = (AudioUnitRenderProc) IPlugAU::RenderProc; + } + return noErr; + } + default: + return kAudioUnitErr_InvalidElement; + } +} + +// static +ComponentResult IPlugAU::GetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, + AudioUnitParameterValue* pValue) +{ + Trace(TRACELOC, "%d:(%d:%s):%d", paramID, scope, AUScopeStr(scope), element); + + ASSERT_SCOPE(kAudioUnitScope_Global); + IPlugAU* _this = (IPlugAU*) pPlug; + IMutexLock lock(_this); + *pValue = _this->GetParam(paramID)->Value(); + return noErr; +} + +// static +ComponentResult IPlugAU::SetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, + AudioUnitParameterValue value, UInt32 offsetFrames) +{ + Trace(TRACELOC, "%d:(%d:%s):%d", paramID, scope, AUScopeStr(scope), element); + + // In the SDK, offset frames is only looked at in group scope. + ASSERT_SCOPE(kAudioUnitScope_Global); + IPlugAU* _this = (IPlugAU*) pPlug; + IMutexLock lock(_this); + IParam* pParam = _this->GetParam(paramID); + pParam->Set(value); + if (_this->GetGUI()) { + _this->GetGUI()->SetParameterFromPlug(paramID, value, false); + } + _this->OnParamChange(paramID); + return noErr; +} + +struct BufferList { + int mNumberBuffers; + AudioBuffer mBuffers[MAX_IO_CHANNELS]; +}; + +inline ComponentResult RenderCallback(AURenderCallbackStruct* pCB, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, + UInt32 inputBusIdx, UInt32 nFrames, AudioBufferList* pOutBufList) +{ + TRACE; + return pCB->inputProc(pCB->inputProcRefCon, pFlags, pTimestamp, inputBusIdx, nFrames, pOutBufList); +} + +// static +ComponentResult IPlugAU::RenderProc(void* pPlug, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, + UInt32 outputBusIdx, UInt32 nFrames, AudioBufferList* pOutBufList) +{ + Trace(TRACELOC, "%d:%d:%d", outputBusIdx, pOutBufList->mNumberBuffers, nFrames); + + IPlugAU* _this = (IPlugAU*) pPlug; + if (_this->mBypassed) { + return noErr; + } + + if (!(pTimestamp->mFlags & kAudioTimeStampSampleTimeValid) || + outputBusIdx >= _this->mOutBuses.GetSize() || + nFrames > _this->GetBlockSize()) { + return kAudioUnitErr_InvalidPropertyValue; + } + + int nRenderNotify = _this->mRenderNotify.GetSize(); + if (nRenderNotify) { + for (int i = 0; i < nRenderNotify; ++i) { + AURenderCallbackStruct* pRN = _this->mRenderNotify.Get(i); + AudioUnitRenderActionFlags flags = kAudioUnitRenderAction_PreRender; + RenderCallback(pRN, &flags, pTimestamp, outputBusIdx, nFrames, pOutBufList); + } + } + + double renderTimestamp = pTimestamp->mSampleTime; + if (renderTimestamp != _this->mRenderTimestamp) { // Pull input buffers. + + BufferList bufList; + AudioBufferList* pInBufList = (AudioBufferList*) &bufList; + + int nIn = _this->mInBuses.GetSize(); + for (int i = 0; i < nIn; ++i) { + BusChannels* pInBus = _this->mInBuses.Get(i); + InputBusConnection* pInBusConn = _this->mInBusConnections.Get(i); + + if (pInBus->mConnected) { + pInBufList->mNumberBuffers = pInBus->mNHostChannels; + for (int b = 0; b < pInBufList->mNumberBuffers; ++b) { + AudioBuffer* pBuffer = &(pInBufList->mBuffers[b]); + pBuffer->mNumberChannels = 1; + pBuffer->mDataByteSize = nFrames * sizeof(AudioSampleType); + pBuffer->mData = 0; + } + + AudioUnitRenderActionFlags flags = 0; + ComponentResult r = noErr; + switch (pInBusConn->mInputType) { + case eDirectFastProc: { + r = pInBusConn->mUpstreamRenderProc(pInBusConn->mUpstreamObj, &flags, pTimestamp, pInBusConn->mUpstreamBusIdx, nFrames, pInBufList); + break; + } + case eDirectNoFastProc: { + r = AudioUnitRender(pInBusConn->mUpstreamUnit, &flags, pTimestamp, pInBusConn->mUpstreamBusIdx, nFrames, pInBufList); + break; + } + case eRenderCallback: { + AudioSampleType* pScratchInput = _this->mInScratchBuf.Get() + pInBus->mPlugChannelStartIdx * nFrames; + for (int b = 0; b < pInBufList->mNumberBuffers; ++b, pScratchInput += nFrames) { + pInBufList->mBuffers[b].mData = pScratchInput; + } + r = RenderCallback(&(pInBusConn->mUpstreamRenderCallback), &flags, pTimestamp, i /* 0 */, nFrames, pInBufList); + break; + } + default: { + bool inputBusAssessed = false; + assert(inputBusAssessed); // InputBus.mConnected should be false, we didn't correctly assess the input connections. + } + } + if (r != noErr) { + return r; // Something went wrong upstream. + } + + for (int i = 0, chIdx = pInBus->mPlugChannelStartIdx; i < pInBus->mNHostChannels; ++i, ++chIdx) { + _this->AttachInputBuffers(chIdx, 1, (AudioSampleType**) &(pInBufList->mBuffers[i].mData), nFrames); + } + } + } + _this->mRenderTimestamp = renderTimestamp; + } + + BusChannels* pOutBus = _this->mOutBuses.Get(outputBusIdx); + if (!(pOutBus->mConnected) || pOutBus->mNHostChannels != pOutBufList->mNumberBuffers) { + int startChannelIdx = pOutBus->mPlugChannelStartIdx; + int nConnected = MIN(pOutBus->mNHostChannels, pOutBufList->mNumberBuffers); + int nUnconnected = MAX(pOutBus->mNPlugChannels - nConnected, 0); + _this->SetOutputChannelConnections(startChannelIdx, nConnected, true); + _this->SetOutputChannelConnections(startChannelIdx + nConnected, nUnconnected, false); + pOutBus->mConnected = true; + } + + for (int i = 0, chIdx = pOutBus->mPlugChannelStartIdx; i < pOutBufList->mNumberBuffers; ++i, ++chIdx) { + if (!(pOutBufList->mBuffers[i].mData)) { // Grr. Downstream unit didn't give us buffers. + pOutBufList->mBuffers[i].mData = _this->mOutScratchBuf.Get() + chIdx * nFrames; + } + _this->AttachOutputBuffers(chIdx, 1, (AudioSampleType**) &(pOutBufList->mBuffers[i].mData)); + } + + _this->ProcessBuffers((AudioSampleType) 0, nFrames); + + if (nRenderNotify) { + for (int i = 0; i < nRenderNotify; ++i) { + AURenderCallbackStruct* pRN = _this->mRenderNotify.Get(i); + AudioUnitRenderActionFlags flags = kAudioUnitRenderAction_PostRender; + RenderCallback(pRN, &flags, pTimestamp, outputBusIdx, nFrames, pOutBufList); + } + } + + return noErr; +} + +IPlugAU::BusChannels* IPlugAU::GetBus(AudioUnitScope scope, AudioUnitElement busIdx) +{ + if (scope == kAudioUnitScope_Input && busIdx >= 0 && busIdx < mInBuses.GetSize()) { + return mInBuses.Get(busIdx); + } + if (scope == kAudioUnitScope_Output && busIdx >= 0 && busIdx < mOutBuses.GetSize()) { + return mOutBuses.Get(busIdx); + } + // Global bus is an alias for output bus zero. + if (scope == kAudioUnitScope_Global && mOutBuses.GetSize()) { + return mOutBuses.Get(busIdx); + } + return 0; +} + +// Garageband doesn't always report tempo when the transport is stopped, so we need it to persist in the class. +#define DEFAULT_TEMPO 120.0 + +void IPlugAU::ClearConnections() +{ + int nInBuses = mInBuses.GetSize(); + for (int i = 0,; i < nInBuses; ++i) { + BusChannels* pInBus = mInBuses.Get(i); + pInBus->mConnected = false; + pInBus->mNHostChannels = -1; + InputBusConnection* pInBusConn = mInBusConnections.Get(i); + memset(pInBusConn, 0, sizeof(InputBusConnection)); + } + int nOutBuses = mOutBuses.GetSize(); + for (int i = 0,; i < nOutBuses; ++i) { + BusChannels* pOutBus = mOutBuses.Get(i); + pOutBus->mConnected = false; + pOutBus->mNHostChannels = -1; + } +} + +IPlugAU::IPlugAU(IPlugInstanceInfo instanceInfo, + int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency, + bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) +: IPlugBase(nParams, channelIOStr, nPresets, + effectName, productName, mfrName, vendorVersion, uniqueID, mfrID, latency, + plugDoesMidi, plugDoesChunks, plugIsInst), + mCI(0), mBypassed(false), mRenderTimestamp(-1.0), mTempo(DEFAULT_TEMPO), mActive(false) +{ + Trace(TRACELOC, "%s", effectName); + + memset(&mHostCallbacks, 0, sizeof(HostCallbackInfo)); + memset(&mMidiCallback, 0, sizeof(AUMIDIOutputCallbackStruct)); + + mOSXBundleID.Set(instanceInfo.mOSXBundleID.Get()); + mCocoaViewFactoryClassName.Set(instanceInfo.mCocoaViewFactoryClassName.Get()); + + // Every channel pair requested on input or output is a separate bus. + int nInputs = NInChannels(), nOutputs = NOutChannels(); + int nInBuses = (int) ceil(nInputs / 2); + int nOutBuses = (int) ceil(nOutputs / 2); + + PtrListInitialize(&mInBusConnections, nInBuses); + PtrListInitialize(&mInBuses, nInBuses); + PtrListInitialize(&mOutBuses, nOutBuses); + + for (int i = 0, startCh = 0; i < nInBuses; ++i, startCh += 2) { + BusChannels* pInBus = mInBuses.Get(i); + pInBus->mNHostChannels = -1; + pInBus->mPlugChannelStartIdx = startCh; + pInBus->mNPlugChannels = MIN(nInputs - startCh, 2); + } + for (int i = 0, startCh = 0; i < nOutBuses; ++i, startCh += 2) { + BusChannels* pOutBus = mOutBuses.Get(i); + pOutBus->mNHostChannels = -1; + pOutBus->mPlugChannelStartIdx = startCh; + pOutBus->mNPlugChannels = MIN(nOutputs - startCh, 2); + } + + AssessInputConnections(); + + SetBlockSize(DEFAULT_BLOCK_SIZE); +} + +IPlugAU::~IPlugAU() +{ + mRenderNotify.Empty(true); + mInBuses.Empty(true); + mOutBuses.Empty(true); + mInBusConnections.Empty(true); + mPropertyListeners.Empty(true); +} + +void SendAUEvent(AudioUnitEventType type, ComponentInstance ci, int idx) +{ + AudioUnitEvent auEvent; + memset(&auEvent, 0, sizeof(AudioUnitEvent)); + auEvent.mEventType = type; + auEvent.mArgument.mParameter.mAudioUnit = ci; + auEvent.mArgument.mParameter.mParameterID = idx; + auEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global; + auEvent.mArgument.mParameter.mElement = 0; + AUEventListenerNotify(0, 0, &auEvent); +} + +void IPlugAU::BeginInformHostOfParamChange(int idx) +{ + Trace(TRACELOC, "%d", idx); + SendAUEvent(kAudioUnitEvent_BeginParameterChangeGesture, mCI, idx); +} + +void IPlugAU::InformHostOfParamChange(int idx, double normalizedValue) +{ + Trace(TRACELOC, "%d:%f", idx, normalizedValue); + SendAUEvent(kAudioUnitEvent_ParameterValueChange, mCI, idx); +} + +void IPlugAU::EndInformHostOfParamChange(int idx) +{ + Trace(TRACELOC, "%d", idx); + SendAUEvent(kAudioUnitEvent_EndParameterChangeGesture, mCI, idx); +} + +// Samples since start of project. +int IPlugAU::GetSamplePos() +{ + if (mHostCallbacks.transportStateProc) { + double samplePos = 0.0, loopStartBeat, loopEndBeat; + Boolean playing, changed, looping; + mHostCallbacks.transportStateProc(mHostCallbacks.hostUserData, &playing, &changed, &samplePos, + &looping, &loopStartBeat, &loopEndBeat); + return (int) samplePos; + } + return 0; +} + +double IPlugAU::GetTempo() +{ + if (mHostCallbacks.beatAndTempoProc) { + double currentBeat = 0.0, tempo = 0.0; + mHostCallbacks.beatAndTempoProc(mHostCallbacks.hostUserData, ¤tBeat, &tempo); + if (tempo > 0.0) { + mTempo = tempo; + } + } + return mTempo; +} + +void IPlugAU::GetTimeSig(int* pNum, int* pDenom) +{ + UInt32 sampleOffsetToNextBeat = 0, tsDenom = 0; + float tsNum = 0.0f; + double currentMeasureDownBeat = 0.0; + if (mHostCallbacks.musicalTimeLocationProc) { + mHostCallbacks.musicalTimeLocationProc(mHostCallbacks.hostUserData, &sampleOffsetToNextBeat, + &tsNum, &tsDenom, ¤tMeasureDownBeat); + *pNum = (int) tsNum; + *pDenom = (int) tsDenom; + } +} + +EHost IPlugAU::GetHost() +{ + EHost host = IPlugBase::GetHost(); + if (host == kHostUninit) { + CFBundleRef mainBundle = CFBundleGetMainBundle(); + if (mainBundle) { + CFStringRef id = CFBundleGetIdentifier(mainBundle); + if (id) { + CStrLocal str(id); + SetHost(str.mCStr, 0); + host = IPlugBase::GetHost(); + } + } + if (host == kHostUninit) { + SetHost("", 0); + host = IPlugBase::GetHost(); + } + } + return host; +} + +void IPlugAU::HostSpecificInit() +{ + EHost host = GetHost(); +} + +void IPlugAU::SetBlockSize(int blockSize) +{ + TRACE; + int nIn = NInChannels() * blockSize; + int nOut = NOutChannels() * blockSize; + mInScratchBuf.Resize(nIn); + mOutScratchBuf.Resize(nOut); + memset(mInScratchBuf.Get(), 0, nIn * sizeof(AudioSampleType)); + memset(mOutScratchBuf.Get(), 0, nOut * sizeof(AudioSampleType)); + IPlugBase::SetBlockSize(blockSize); +} + +void IPlugAU::InformListeners(AudioUnitPropertyID propID, AudioUnitScope scope) +{ + TRACE; + int i, n = mPropertyListeners.GetSize(); + for (i = 0; i < n; ++i) { + PropertyListener* pListener = mPropertyListeners.Get(i); + if (pListener->mPropID == propID) { + pListener->mListenerProc(pListener->mProcArgs, mCI, propID, scope, 0); + } + } +} + +void IPlugAU::SetLatency(int samples) +{ + TRACE; + int i, n = mPropertyListeners.GetSize(); + for (i = 0; i < n; ++i) { + PropertyListener* pListener = mPropertyListeners.Get(i); + if (pListener->mPropID == kAudioUnitProperty_Latency) { + pListener->mListenerProc(pListener->mProcArgs, mCI, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0); + } + } + IPlugBase::SetLatency(samples); +} + +bool IPlugAU::SendMidiMsg(IMidiMsg* pMsg) +{ + // I believe AU passes midi messages through automatically. + // For the case where we're generating midi messages, we'll use AUMIDIOutputCallback. + // See AudioUnitProperties.h. + if (mMidiCallback.midiOutputCallback) { + // Todo. + } + return false; +} + +bool IPlugAU::SendMidiMsgs(WDL_TypedBuf* pMsgs) +{ + int i, n = pMsgs->GetSize(); + IMidiMsg* pMsg = pMsgs->Get(); + for (i = 0; i < n; ++i, ++pMsg) { + SendMidiMsg(pMsg); + } + return true; +} diff --git a/WDL/IPlug/IPlugAU.h b/WDL/IPlug/IPlugAU.h new file mode 100644 index 00000000..ddea6040 --- /dev/null +++ b/WDL/IPlug/IPlugAU.h @@ -0,0 +1,147 @@ +#ifndef _IPLUGAPI_ +#define _IPLUGAPI_ +// Only load one API class! + +#include "IPlugBase.h" +#include +#include +#include +#include +#include + +// Argh! +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 + typedef Float32 AudioSampleType; + typedef Float32 AudioUnitParameterValue; + typedef OSStatus (*AUMIDIOutputCallback)(void*, const AudioTimeStamp*, UInt32, const struct MIDIPacketList*); + struct AUMIDIOutputCallbackStruct { AUMIDIOutputCallback midiOutputCallback; void* userData; }; + #define kAudioFormatFlagsCanonical (kAudioFormatFlagIsFloat|kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsPacked) +#endif + +#define MAX_IO_CHANNELS 128 + +struct IPlugInstanceInfo +{ + WDL_String mOSXBundleID, mCocoaViewFactoryClassName; +}; + +class IPlugAU : public IPlugBase +{ +public: + + // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). + IPlugAU(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency, + bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst); + + virtual ~IPlugAU(); + + // ---------------------------------------- + // See IPlugBase for the full list of methods that your plugin class can implement. + + void BeginInformHostOfParamChange(int idx); + void InformHostOfParamChange(int idx, double normalizedValue); + void EndInformHostOfParamChange(int idx); + + int GetSamplePos(); // Samples since start of project. + double GetTempo(); + void GetTimeSig(int* pNum, int* pDenom); + EHost GetHost(); // GetHostVersion() is inherited. + + // Tell the host that the graphics resized. + // Should be called only by the graphics object when it resizes itself. + void ResizeGraphics(int w, int h) {} + + enum EAUInputType { + eNotConnected = 0, + eDirectFastProc, + eDirectNoFastProc, + eRenderCallback + }; + +protected: + + void HostSpecificInit(); + void SetBlockSize(int blockSize); + void SetLatency(int samples); + bool SendMidiMsg(IMidiMsg* pMsg); + bool SendMidiMsgs(WDL_TypedBuf* pMsgs); + +private: + + WDL_String mOSXBundleID, mCocoaViewFactoryClassName; + ComponentInstance mCI; + bool mActive, mBypassed; + double mRenderTimestamp, mTempo; + HostCallbackInfo mHostCallbacks; + + // InScratchBuf is only needed if the upstream connection is a callback. + // OutScratchBuf is only needed if the downstream connection fails to give us a buffer. + WDL_TypedBuf mInScratchBuf, mOutScratchBuf; + WDL_PtrList mRenderNotify; + AUMIDIOutputCallbackStruct mMidiCallback; + + // Every stereo pair of plugin input or output is a bus. + // Buses can have zero host channels if the host hasn't connected the bus at all, + // one host channel if the plugin supports mono and the host has supplied a mono stream, + // or two host channels if the host has supplied a stereo stream. + struct BusChannels { + bool mConnected; + int mNHostChannels, mNPlugChannels, mPlugChannelStartIdx; + }; + WDL_PtrList mInBuses, mOutBuses; + BusChannels* GetBus(AudioUnitScope scope, AudioUnitElement busIdx); + int NHostChannelsConnected(WDL_PtrList* pBuses, int excludeIdx = -1); + void ClearConnections(); + + struct InputBusConnection { + void* mUpstreamObj; + AudioUnit mUpstreamUnit; + int mUpstreamBusIdx; + AudioUnitRenderProc mUpstreamRenderProc; + AURenderCallbackStruct mUpstreamRenderCallback; + EAUInputType mInputType; + }; + WDL_PtrList mInBusConnections; + + bool CheckLegalIO(AudioUnitScope scope, int busIdx, int nChannels); + bool CheckLegalIO(); + void AssessInputConnections(); + + struct PropertyListener { + AudioUnitPropertyID mPropID; + AudioUnitPropertyListenerProc mListenerProc; + void* mProcArgs; + }; + WDL_PtrList mPropertyListeners; + + ComponentResult GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, + UInt32* pDataSize, Boolean* pWriteable); + ComponentResult GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, + UInt32* pDataSize, Boolean* pWriteable, void* pData); + ComponentResult SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element, + UInt32* pDataSize, const void* pData); + ComponentResult GetProc(AudioUnitElement element, UInt32* pDataSize, void* pData); + ComponentResult GetState(CFPropertyListRef* ppPropList); + ComponentResult SetState(CFPropertyListRef pPropList); + void InformListeners(AudioUnitPropertyID propID, AudioUnitScope scope); + + +public: + + static ComponentResult IPlugAUEntry(ComponentParameters *params, void* pVPlug); + static ComponentResult IPlugAUCarbonViewEntry(ComponentParameters *params, void* pView); + static ComponentResult GetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, + AudioUnitParameterValue* pValue); + static ComponentResult SetParamProc(void* pPlug, AudioUnitParameterID paramID, AudioUnitScope scope, AudioUnitElement element, + AudioUnitParameterValue value, UInt32 offsetFrames); + static ComponentResult RenderProc(void* pPlug, AudioUnitRenderActionFlags* pFlags, const AudioTimeStamp* pTimestamp, + UInt32 outputBusIdx, UInt32 nFrames, AudioBufferList* pBufferList); +}; + +IPlugAU* MakePlug(); + +#endif + + diff --git a/WDL/IPlug/IPlugAU.r b/WDL/IPlug/IPlugAU.r new file mode 100644 index 00000000..b6d13b11 --- /dev/null +++ b/WDL/IPlug/IPlugAU.r @@ -0,0 +1,140 @@ +#include "resource.h" // This is your plugin's resource.h. +#include + +#define UseExtendedThingResource 1 + +#include + +// this is a define used to indicate that a component has no static data that would mean +// that no more than one instance could be open at a time - never been true for AUs +#ifndef cmpThreadSafeOnMac +#define cmpThreadSafeOnMac 0x10000000 +#endif + +#undef TARGET_REZ_MAC_PPC +#ifdef ppc_YES + #define TARGET_REZ_MAC_PPC 1 +#else + #define TARGET_REZ_MAC_PPC 0 +#endif + +#undef TARGET_REZ_MAC_X86 +#ifdef i386_YES + #define TARGET_REZ_MAC_X86 1 +#else + #define TARGET_REZ_MAC_X86 0 +#endif + +#if TARGET_OS_MAC + #if TARGET_REZ_MAC_PPC && TARGET_REZ_MAC_X86 + #define TARGET_REZ_FAT_COMPONENTS 1 + #define Target_PlatformType platformPowerPCNativeEntryPoint + #define Target_SecondPlatformType platformIA32NativeEntryPoint + #elif TARGET_REZ_MAC_X86 + #define Target_PlatformType platformIA32NativeEntryPoint + #else + #define Target_PlatformType platformPowerPCNativeEntryPoint + #endif + #define Target_CodeResType 'dlle' + #define TARGET_REZ_USE_DLLE 1 +#else + #error get a real platform type +#endif // not TARGET_OS_MAC + +#ifndef TARGET_REZ_FAT_COMPONENTS + #define TARGET_REZ_FAT_COMPONENTS 0 +#endif + +// ---------------- + +//#ifdef _DEBUG +// #define PLUG_PUBLIC_NAME PLUG_NAME "_DEBUG" +//#else +#define PLUG_PUBLIC_NAME PLUG_NAME +//#endif + +#define RES_ID 1000 +#define RES_NAME PLUG_MFR ": " PLUG_PUBLIC_NAME + +resource 'STR ' (RES_ID, purgeable) { + RES_NAME +}; + +resource 'STR ' (RES_ID + 1, purgeable) { + PLUG_PUBLIC_NAME " AU" +}; + +resource 'dlle' (RES_ID) { + PLUG_ENTRY_STR +}; + +resource 'thng' (RES_ID, RES_NAME) { +#if PLUG_IS_INST + kAudioUnitType_MusicDevice, +#else + kAudioUnitType_Effect, +#endif + PLUG_UNIQUE_ID, + PLUG_MFR_ID, + 0, 0, 0, 0, // no 68K + 'STR ', RES_ID, + 'STR ', RES_ID + 1, + 0, 0, // icon + PLUG_VER, + componentHasMultiplePlatforms | componentDoAutoVersion, + 0, + { + cmpThreadSafeOnMac, + Target_CodeResType, RES_ID, + Target_PlatformType, +#if TARGET_REZ_FAT_COMPONENTS + cmpThreadSafeOnMac, + Target_CodeResType, RES_ID, + Target_SecondPlatformType, +#endif + } +}; + +#undef RES_ID +#define RES_ID 2000 +#undef RES_NAME +#define RES_NAME PLUG_MFR ": " PLUG_PUBLIC_NAME " Carbon View" + +resource 'STR ' (RES_ID, purgeable) { + RES_NAME +}; + +resource 'STR ' (RES_ID + 1, purgeable) { + PLUG_PUBLIC_NAME " AU Carbon View" +}; + +resource 'dlle' (RES_ID) { + PLUG_VIEW_ENTRY_STR +}; + +resource 'thng' (RES_ID, RES_NAME) { + kAudioUnitCarbonViewComponentType, + PLUG_UNIQUE_ID, + PLUG_MFR_ID, + 0, 0, 0, 0, // no 68K + 'STR ', RES_ID, + 'STR ', RES_ID + 1, + 0, 0, // icon + PLUG_VER, + componentHasMultiplePlatforms | componentDoAutoVersion, + 0, + { + cmpThreadSafeOnMac, + Target_CodeResType, RES_ID, + Target_PlatformType, +#if TARGET_REZ_FAT_COMPONENTS + cmpThreadSafeOnMac, + Target_CodeResType, RES_ID, + Target_SecondPlatformType, +#endif + } +}; + +#undef RES_ID + + diff --git a/WDL/IPlug/IPlugAU_ViewFactory.mm b/WDL/IPlug/IPlugAU_ViewFactory.mm new file mode 100644 index 00000000..da6ce9af --- /dev/null +++ b/WDL/IPlug/IPlugAU_ViewFactory.mm @@ -0,0 +1,50 @@ +#import +#include "../IPlug/IGraphicsCocoa.h" +#include "resource.h" // This is your plugin's resource.h. + +@interface VIEW_CLASS : NSObject +{ + IPlugBase* mPlug; +} +- (id) init; +- (NSView*) uiViewForAudioUnit: (AudioUnit) audioUnit withSize: (NSSize) preferredSize; +- (unsigned) interfaceVersion; +- (NSString*) description; +@end + +@implementation VIEW_CLASS + +- (id) init +{ + TRACE; + mPlug = 0; + return [super init]; +} + +- (NSView*) uiViewForAudioUnit: (AudioUnit) audioUnit withSize: (NSSize) preferredSize +{ + TRACE; + mPlug = (IPlugBase*) GetComponentInstanceStorage(audioUnit); + if (mPlug) { + IGraphics* pGraphics = mPlug->GetGUI(); + if (pGraphics) { + IGRAPHICS_COCOA* pView = (IGRAPHICS_COCOA*) pGraphics->OpenWindow(0); + return pView; + } + } + return 0; +} + +- (unsigned) interfaceVersion +{ + return 0; +} + +- (NSString *) description +{ + return ToNSString(PLUG_NAME " View"); +} + +@end + + diff --git a/WDL/IPlug/IPlugBase.cpp b/WDL/IPlug/IPlugBase.cpp new file mode 100644 index 00000000..8882ef03 --- /dev/null +++ b/WDL/IPlug/IPlugBase.cpp @@ -0,0 +1,692 @@ +#include "IPlugBase.h" +#include "IGraphics.h" +#include "IControl.h" +#include +#include +#include + +const double DEFAULT_SAMPLE_RATE = 44100.0; + +template +void CastCopy(DEST* pDest, SRC* pSrc, int n) +{ + for (int i = 0; i < n; ++i, ++pDest, ++pSrc) { + *pDest = (DEST) *pSrc; + } +} + +void GetVersionParts(int version, int* pVer, int* pMaj, int* pMin) +{ + *pVer = (version & 0xFFFF0000) >> 16; + *pMaj = (version & 0x0000FF00) >> 8; + *pMin = version & 0x000000FF; +} + +int GetDecimalVersion(int version) +{ + int ver, rmaj, rmin; + GetVersionParts(version, &ver, &rmaj, &rmin); + return 10000 * ver + 100 * rmaj + rmin; +} + +void GetVersionStr(int version, char* str) +{ + int ver, rmaj, rmin; + GetVersionParts(version, &ver, &rmaj, &rmin); + //if (rmin) { + // sprintf(str, "v%d.%d.%d", ver, rmaj, rmin); + //} + //else + //if (rmaj) { + sprintf(str, "v%d.%02d", ver, rmaj); + //} + //else { + // sprintf(str, "v%d", ver); + //} +} + +IPlugBase::IPlugBase(int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency, + bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) +: mUniqueID(uniqueID), mMfrID(mfrID), mVersion(vendorVersion), + mSampleRate(DEFAULT_SAMPLE_RATE), mBlockSize(0), mLatency(latency), mHost(kHostUninit), mHostVersion(0), + mStateChunks(plugDoesChunks), mGraphics(0), mCurrentPresetIdx(0), mIsInst(plugIsInst) +{ + Trace(TRACELOC, "%s:%s", effectName, CurrentTime()); + + for (int i = 0; i < nParams; ++i) { + mParams.Add(new IParam); + } + + for (int i = 0; i < nPresets; ++i) { + mPresets.Add(new IPreset(i)); + } + + strcpy(mEffectName, effectName); + strcpy(mProductName, productName); + strcpy(mMfrName, mfrName); + + int nInputs = 0, nOutputs = 0; + while (channelIOStr) { + int nIn = 0, nOut = 0; + assert(sscanf(channelIOStr, "%d-%d", &nIn, &nOut) == 2); + nInputs = MAX(nInputs, nIn); + nOutputs = MAX(nOutputs, nOut); + mChannelIO.Add(new ChannelIO(nIn, nOut)); + channelIOStr = strstr(channelIOStr, " "); + if (channelIOStr) { + ++channelIOStr; + } + } + + mInData.Resize(nInputs); + mOutData.Resize(nOutputs); + + double** ppInData = mInData.Get(); + for (int i = 0; i < nInputs; ++i, ++ppInData) { + InChannel* pInChannel = new InChannel; + pInChannel->mConnected = false; + pInChannel->mSrc = ppInData; + mInChannels.Add(pInChannel); + } + double** ppOutData = mOutData.Get(); + for (int i = 0; i < nOutputs; ++i, ++ppOutData) { + OutChannel* pOutChannel = new OutChannel; + pOutChannel->mConnected = false; + pOutChannel->mDest = ppOutData; + pOutChannel->mFDest = 0; + mOutChannels.Add(pOutChannel); + } +} + +IPlugBase::~IPlugBase() +{ + TRACE; + DELETE_NULL(mGraphics); + mParams.Empty(true); + mPresets.Empty(true); + mInChannels.Empty(true); + mOutChannels.Empty(true); + mChannelIO.Empty(true); +} + +int IPlugBase::GetHostVersion(bool decimal) +{ + GetHost(); + if (decimal) { + return GetDecimalVersion(mHostVersion); + } + return mHostVersion; +} + +void IPlugBase::GetHostVersionStr(char* str) +{ + GetVersionStr(mHostVersion, str); +} + +bool IPlugBase::LegalIO(int nIn, int nOut) +{ + bool legal = false; + int i, n = mChannelIO.GetSize(); + for (i = 0; i < n && !legal; ++i) { + ChannelIO* pIO = mChannelIO.Get(i); + legal = ((nIn < 0 || nIn == pIO->mIn) && (nOut < 0 || nOut == pIO->mOut)); + } + Trace(TRACELOC, "%d:%d:%s", nIn, nOut, (legal ? "legal" : "illegal")); + return legal; +} + +void IPlugBase::LimitToStereoIO() +{ + int nIn = NInChannels(), nOut = NOutChannels(); + if (nIn > 2) { + SetInputChannelConnections(2, nIn - 2, false); + } + if (nOut > 2) { + SetOutputChannelConnections(2, nOut - 2, true); + } +} + +void IPlugBase::SetHost(const char* host, int version) +{ + mHost = LookUpHost(host); + mHostVersion = version; + + char vStr[32]; + GetVersionStr(version, vStr); + Trace(TRACELOC, "host_%sknown:%s:%s", (mHost == kHostUnknown ? "un" : ""), host, vStr); +} + +void IPlugBase::AttachGraphics(IGraphics* pGraphics) +{ + if (pGraphics) { + WDL_MutexLock lock(&mMutex); + int i, n = mParams.GetSize(); + for (i = 0; i < n; ++i) { + pGraphics->SetParameterFromPlug(i, GetParam(i)->GetNormalized(), true); + } + pGraphics->PrepDraw(); + mGraphics = pGraphics; + } +} + +// Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. +int IPlugBase::GetEffectVersion(bool decimal) +{ + if (decimal) { + return GetDecimalVersion(mVersion); + } + return mVersion; +} + +void IPlugBase::GetEffectVersionStr(char* str) +{ + GetVersionStr(mVersion, str); + #if defined _DEBUG + strcat(str, "D"); + #elif defined TRACER_BUILD + strcat(str, "T"); + #endif +} + +double IPlugBase::GetSamplesPerBeat() +{ + double tempo = GetTempo(); + if (tempo > 0.0) { + return GetSampleRate() * 60.0 / tempo; + } + return 0.0; +} + +void IPlugBase::SetSampleRate(double sampleRate) +{ + mSampleRate = sampleRate; +} + +void IPlugBase::SetBlockSize(int blockSize) +{ + if (blockSize != mBlockSize) { + int i, nIn = NInChannels(), nOut = NOutChannels(); + for (i = 0; i < nIn; ++i) { + InChannel* pInChannel = mInChannels.Get(i); + pInChannel->mScratchBuf.Resize(blockSize); + memset(pInChannel->mScratchBuf.Get(), 0, blockSize * sizeof(double)); + } + for (i = 0; i < nOut; ++i) { + OutChannel* pOutChannel = mOutChannels.Get(i); + pOutChannel->mScratchBuf.Resize(blockSize); + memset(pOutChannel->mScratchBuf.Get(), 0, blockSize * sizeof(double)); + } + mBlockSize = blockSize; + } +} + +void IPlugBase::SetInputChannelConnections(int idx, int n, bool connected) +{ + int iEnd = MIN(idx + n, mInChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + InChannel* pInChannel = mInChannels.Get(i); + pInChannel->mConnected = connected; + if (!connected) { + *(pInChannel->mSrc) = pInChannel->mScratchBuf.Get(); + } + } +} + +void IPlugBase::SetOutputChannelConnections(int idx, int n, bool connected) +{ + int iEnd = MIN(idx + n, mOutChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + OutChannel* pOutChannel = mOutChannels.Get(i); + pOutChannel->mConnected = connected; + if (!connected) { + *(pOutChannel->mDest) = pOutChannel->mScratchBuf.Get(); + } + } +} + +bool IPlugBase::IsInChannelConnected(int chIdx) +{ + return (chIdx < mInChannels.GetSize() && mInChannels.Get(chIdx)->mConnected); +} + +bool IPlugBase:: IsOutChannelConnected(int chIdx) +{ + return (chIdx < mOutChannels.GetSize() && mOutChannels.Get(chIdx)->mConnected); +} + +void IPlugBase::AttachInputBuffers(int idx, int n, double** ppData, int nFrames) +{ + int iEnd = MIN(idx + n, mInChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + InChannel* pInChannel = mInChannels.Get(i); + if (pInChannel->mConnected) { + *(pInChannel->mSrc) = *(ppData++); + } + } +} + +void IPlugBase::AttachInputBuffers(int idx, int n, float** ppData, int nFrames) +{ + int iEnd = MIN(idx + n, mInChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + InChannel* pInChannel = mInChannels.Get(i); + if (pInChannel->mConnected) { + double* pScratch = pInChannel->mScratchBuf.Get(); + CastCopy(pScratch, *(ppData++), nFrames); + *(pInChannel->mSrc) = pScratch; + } + } +} + +void IPlugBase::AttachOutputBuffers(int idx, int n, double** ppData) +{ + int iEnd = MIN(idx + n, mOutChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + OutChannel* pOutChannel = mOutChannels.Get(i); + if (pOutChannel->mConnected) { + *(pOutChannel->mDest) = *(ppData++); + } + } +} + +void IPlugBase::AttachOutputBuffers(int idx, int n, float** ppData) +{ + int iEnd = MIN(idx + n, mOutChannels.GetSize()); + for (int i = idx; i < iEnd; ++i) { + OutChannel* pOutChannel = mOutChannels.Get(i); + if (pOutChannel->mConnected) { + *(pOutChannel->mDest) = pOutChannel->mScratchBuf.Get(); + pOutChannel->mFDest = *(ppData++); + } + } +} + +#pragma REMINDER("lock mutex before calling into any IPlugBase processing functions") + +void IPlugBase::ProcessBuffers(double sampleType, int nFrames) +{ + ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); +} + +void IPlugBase::ProcessBuffers(float sampleType, int nFrames) +{ + ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); + int i, n = NOutChannels(); + OutChannel** ppOutChannel = mOutChannels.GetList(); + for (i = 0; i < n; ++i, ++ppOutChannel) { + OutChannel* pOutChannel = *ppOutChannel; + if (pOutChannel->mConnected) { + CastCopy(pOutChannel->mFDest, *(pOutChannel->mDest), nFrames); + } + } +} + +void IPlugBase::ProcessBuffersAccumulating(float sampleType, int nFrames) +{ + ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames); + int i, n = NOutChannels(); + OutChannel** ppOutChannel = mOutChannels.GetList(); + for (i = 0; i < n; ++i, ++ppOutChannel) { + OutChannel* pOutChannel = *ppOutChannel; + if (pOutChannel->mConnected) { + float* pDest = pOutChannel->mFDest; + double* pSrc = *(pOutChannel->mDest); + for (int j = 0; j < nFrames; ++j, ++pDest, ++pSrc) { + *pDest += (float) *pSrc; + } + } + } +} + +// If latency changes after initialization (often not supported by the host). +void IPlugBase::SetLatency(int samples) +{ + mLatency = samples; +} + +void IPlugBase::SetParameterFromGUI(int idx, double normalizedValue) +{ + Trace(TRACELOC, "%d:%f", idx, normalizedValue); + WDL_MutexLock lock(&mMutex); + GetParam(idx)->SetNormalized(normalizedValue); + InformHostOfParamChange(idx, normalizedValue); + OnParamChange(idx); +} + +void IPlugBase::OnParamReset() +{ + for (int i = 0; i < mParams.GetSize(); ++i) { + OnParamChange(i); + } + //Reset(); +} + +// Default passthrough. +void IPlugBase::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames) +{ + // Mutex is already locked. + int i, nIn = mInChannels.GetSize(), nOut = mOutChannels.GetSize(); + for (i = 0; i < nIn; ++i) { + memcpy(outputs[i], inputs[i], nFrames * sizeof(double)); + } + for (/* same i */; i < nOut; ++i) { + memset(outputs[i], 0, nFrames * sizeof(double)); + } +} + +// Default passthrough. +void IPlugBase::ProcessMidiMsg(IMidiMsg* pMsg) +{ + SendMidiMsg(pMsg); +} + +IPreset* GetNextUninitializedPreset(WDL_PtrList* pPresets) +{ + int n = pPresets->GetSize(); + for (int i = 0; i < n; ++i) { + IPreset* pPreset = pPresets->Get(i); + if (!(pPreset->mInitialized)) { + return pPreset; + } + } + return 0; +} + +void IPlugBase::MakeDefaultPreset(char* name, int nPresets) +{ + for (int i = 0; i < nPresets; ++i) { + IPreset* pPreset = GetNextUninitializedPreset(&mPresets); + if (pPreset) { + pPreset->mInitialized = true; + strcpy(pPreset->mName, (name ? name : "Default")); + SerializeParams(&(pPreset->mChunk)); + } + } +} + +#define GET_PARAM_FROM_VARARG(paramType, vp, v) \ +{ \ + v = 0.0; \ + switch (paramType) { \ + case IParam::kTypeBool: \ + case IParam::kTypeInt: \ + case IParam::kTypeEnum: { \ + v = (double) va_arg(vp, int); \ + break; \ + } \ + case IParam::kTypeDouble: \ + default: { \ + v = (double) va_arg(vp, double); \ + break; \ + } \ + } \ +} + +void IPlugBase::MakePreset(char* name, ...) +{ + IPreset* pPreset = GetNextUninitializedPreset(&mPresets); + if (pPreset) { + pPreset->mInitialized = true; + strcpy(pPreset->mName, name); + int i, n = mParams.GetSize(); + + double v = 0.0; + va_list vp; + va_start(vp, name); + for (i = 0; i < n; ++i) { + GET_PARAM_FROM_VARARG(GetParam(i)->Type(), vp, v); + pPreset->mChunk.Put(&v); + } + } +} + +#define PARAM_UNINIT 99.99e-9 + +void IPlugBase::MakePresetFromNamedParams(char* name, int nParamsNamed, ...) +{ + IPreset* pPreset = GetNextUninitializedPreset(&mPresets); + if (pPreset) { + pPreset->mInitialized = true; + strcpy(pPreset->mName, name); + + int i = 0, n = mParams.GetSize(); + + WDL_TypedBuf vals; + vals.Resize(n); + double* pV = vals.Get(); + for (i = 0; i < n; ++i, ++pV) { + *pV = PARAM_UNINIT; + } + + va_list vp; + va_start(vp, nParamsNamed); + for (int i = 0; i < nParamsNamed; ++i) { + int paramIdx = (int) va_arg(vp, int); + // This assert will fire if any of the passed-in param values do not match + // the type that the param was initialized with (int for bool, int, enum; double for double). + assert(paramIdx >= 0 && paramIdx < n); + GET_PARAM_FROM_VARARG(GetParam(paramIdx)->Type(), vp, *(vals.Get() + paramIdx)); + } + va_end(vp); + + pV = vals.Get(); + for (int i = 0; i < n; ++i, ++pV) { + if (*pV == PARAM_UNINIT) { // Any that weren't explicitly set, use the defaults. + *pV = GetParam(i)->Value(); + } + pPreset->mChunk.Put(pV); + } + } +} + +#define DEFAULT_USER_PRESET_NAME "user preset" + +void MakeDefaultUserPresetName(WDL_PtrList* pPresets, char* str) +{ + int nDefaultNames = 0; + int n = pPresets->GetSize(); + for (int i = 0; i < n; ++i) { + IPreset* pPreset = pPresets->Get(i); + if (strstr(pPreset->mName, DEFAULT_USER_PRESET_NAME)) { + ++nDefaultNames; + } + } + sprintf(str, "%s %d", DEFAULT_USER_PRESET_NAME, nDefaultNames + 1); +} + +void IPlugBase::EnsureDefaultPreset() +{ + if (!(mPresets.GetSize())) { + mPresets.Add(new IPreset(0)); + MakeDefaultPreset(); + } +} + +void IPlugBase::PruneUninitializedPresets() +{ + int i = 0; + while (i < mPresets.GetSize()) { + IPreset* pPreset = mPresets.Get(i); + if (pPreset->mInitialized) { + ++i; + } + else { + mPresets.Delete(i, true); + } + } +} + +bool IPlugBase::RestorePreset(int idx) +{ + bool restoredOK = false; + if (idx >= 0 && idx < mPresets.GetSize()) { + IPreset* pPreset = mPresets.Get(idx); + + if (!(pPreset->mInitialized)) { + pPreset->mInitialized = true; + MakeDefaultUserPresetName(&mPresets, pPreset->mName); + restoredOK = SerializeParams(&(pPreset->mChunk)); + } + else { + restoredOK = (UnserializeParams(&(pPreset->mChunk), 0) > 0); + } + + if (restoredOK) { + mCurrentPresetIdx = idx; + RedrawParamControls(); + } + } + return restoredOK; +} + +bool IPlugBase::RestorePreset(const char* name) +{ + if (CSTR_NOT_EMPTY(name)) { + int n = mPresets.GetSize(); + for (int i = 0; i < n; ++i) { + IPreset* pPreset = mPresets.Get(i); + if (!strcmp(pPreset->mName, name)) { + return RestorePreset(i); + } + } + } + return false; +} + +const char* IPlugBase::GetPresetName(int idx) +{ + if (idx >= 0 && idx < mPresets.GetSize()) { + return mPresets.Get(idx)->mName; + } + return ""; +} + +void IPlugBase::ModifyCurrentPreset(const char* name) +{ + if (mCurrentPresetIdx >= 0 && mCurrentPresetIdx < mPresets.GetSize()) { + IPreset* pPreset = mPresets.Get(mCurrentPresetIdx); + pPreset->mChunk.Clear(); + + + SerializeParams(&(pPreset->mChunk)); + + if (CSTR_NOT_EMPTY(name)) + { + strcpy(pPreset->mName, name); + } + } +} + +bool IPlugBase::SerializePresets(ByteChunk* pChunk) +{ + bool savedOK = true; + int n = mPresets.GetSize(); + for (int i = 0; i < n && savedOK; ++i) { + IPreset* pPreset = mPresets.Get(i); + pChunk->PutStr(pPreset->mName); + pChunk->PutBool(pPreset->mInitialized); + if (pPreset->mInitialized) { + savedOK &= (pChunk->PutChunk(&(pPreset->mChunk)) > 0); + } + } + return savedOK; +} + +int IPlugBase::UnserializePresets(ByteChunk* pChunk, int startPos) +{ + WDL_String name; + int n = mPresets.GetSize(), pos = startPos; + for (int i = 0; i < n && pos >= 0; ++i) { + IPreset* pPreset = mPresets.Get(i); + pos = pChunk->GetStr(&name, pos); + strcpy(pPreset->mName, name.Get()); + pos = pChunk->GetBool(&(pPreset->mInitialized), pos); + if (pPreset->mInitialized) { + pos = UnserializeParams(pChunk, pos); + if (pos > 0) { + pPreset->mChunk.Clear(); + SerializeParams(&(pPreset->mChunk)); + } + } + } + RestorePreset(mCurrentPresetIdx); + return pos; +} + +bool IPlugBase::SerializeParams(ByteChunk* pChunk) +{ + TRACE; + + WDL_MutexLock lock(&mMutex); + bool savedOK = true; + int i, n = mParams.GetSize(); + for (i = 0; i < n && savedOK; ++i) { + IParam* pParam = mParams.Get(i); + double v = pParam->Value(); + savedOK &= (pChunk->Put(&v) > 0); + } + return savedOK; +} + +int IPlugBase::UnserializeParams(ByteChunk* pChunk, int startPos) +{ + TRACE; + + WDL_MutexLock lock(&mMutex); + int i, n = mParams.GetSize(), pos = startPos; + for (i = 0; i < n && pos >= 0; ++i) { + IParam* pParam = mParams.Get(i); + double v = 0.0; + Trace(TRACELOC, "%d %s", i, pParam->GetNameForHost()); + pos = pChunk->Get(&v, pos); + pParam->Set(v); + } + OnParamReset(); + return pos; +} + +void IPlugBase::RedrawParamControls() +{ + if (mGraphics) { + int i, n = mParams.GetSize(); + for (i = 0; i < n; ++i) { + double v = mParams.Get(i)->Value(); + mGraphics->SetParameterFromPlug(i, v, false); + } + } +} + +void IPlugBase::DumpPresetSrcCode(const char* filename, const char* paramEnumNames[]) +{ + static bool sDumped = false; + if (!sDumped) { + sDumped = true; + int i, n = NParams(); + FILE* fp = fopen(filename, "w"); + fprintf(fp, " MakePresetFromNamedParams(\"name\", %d", n - 1); + for (i = 0; i < n - 1; ++i) { + IParam* pParam = GetParam(i); + char paramVal[32]; + switch (pParam->Type()) { + case IParam::kTypeBool: + sprintf(paramVal, "%s", (pParam->Bool() ? "true" : "false")); + break; + case IParam::kTypeInt: + sprintf(paramVal, "%d", pParam->Int()); + break; + case IParam::kTypeEnum: + sprintf(paramVal, "%d", pParam->Int()); + break; + case IParam::kTypeDouble: + default: + sprintf(paramVal, "%.2f", pParam->Value()); + break; + } + fprintf(fp, ",\n %s, %s", paramEnumNames[i], paramVal); + } + fprintf(fp, ");\n"); + fclose(fp); + } +} \ No newline at end of file diff --git a/WDL/IPlug/IPlugBase.h b/WDL/IPlug/IPlugBase.h new file mode 100644 index 00000000..b8c3e506 --- /dev/null +++ b/WDL/IPlug/IPlugBase.h @@ -0,0 +1,247 @@ +#ifndef _IPLUGBASE_ +#define _IPLUGBASE_ + +#define IPLUG_VERSION 0x010000 + +#include "Containers.h" +#include "IPlugStructs.h" +#include "IParam.h" +#include "Hosts.h" +#include "Log.h" + +// Uncomment to enable IPlug::OnIdle() and IGraphics::OnGUIIdle(). +// #define USE_IDLE_CALLS + +#define MAX_EFFECT_NAME_LEN 128 +#define DEFAULT_BLOCK_SIZE 1024 + +// All version ints are stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. + +class IGraphics; + +class IPlugBase +{ +public: + + // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). + IPlugBase(int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency, + bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst); + + // ---------------------------------------- + // Your plugin class implements these. + // There are default impls, mostly just for reference. + + virtual ~IPlugBase(); + + // Implementations should set a mutex lock like in the no-op! + virtual void Reset() { TRACE; IMutexLock lock(this); } + virtual void OnParamChange(int paramIdx) { IMutexLock lock(this); } + + // Default passthrough. Inputs and outputs are [nChannel][nSample]. + // Mutex is already locked. + virtual void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames); + + // In case the audio processing thread needs to do anything when the GUI opens + // (like for example, set some state dependent initial values for controls). + virtual void OnGUIOpen() { TRACE; } + virtual void OnGUIClose() { TRACE; } + + // This is an idle call from the audio processing thread, as opposed to + // IGraphics::OnGUIIdle which is called from the GUI thread. + // Only active if USE_IDLE_CALLS is defined. + virtual void OnIdle() {} + + // Not usually needed ... Reset is called on activate regardless of whether this is implemented. + // Also different hosts have different interpretations of "activate". + // Implementations should set a mutex lock like in the no-op! + virtual void OnActivate(bool active) { TRACE; IMutexLock lock(this); } + + virtual void ProcessMidiMsg(IMidiMsg* pMsg); + virtual bool MidiNoteName(int noteNumber, char* rName) { *rName = '\0'; return false; } + + // Implementations should set a mutex lock. + virtual bool SerializeState(ByteChunk* pChunk) { return SerializeParams(pChunk); } + // Return the new chunk position (endPos). + virtual int UnserializeState(ByteChunk* pChunk, int startPos) { return UnserializeParams(pChunk, startPos); } + + // ---------------------------------------- + // Your plugin class, or a control class, can call these functions. + + int NParams() { return mParams.GetSize(); } + IParam* GetParam(int idx) { return mParams.Get(idx); } + IGraphics* GetGUI() { return mGraphics; } + + const char* GetEffectName() { return mEffectName; } + int GetEffectVersion(bool decimal); // Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. + void GetEffectVersionStr(char* str); + const char* GetMfrName() { return mMfrName; } + const char* GetProductName() { return mProductName; } + + int GetUniqueID() { return mUniqueID; } + int GetMfrID() { return mMfrID; } + + void SetParameterFromGUI(int idx, double normalizedValue); + // If a parameter change comes from the GUI, midi, or external input, + // the host needs to be informed in case the changes are being automated. + virtual void BeginInformHostOfParamChange(int idx) = 0; + virtual void InformHostOfParamChange(int idx, double normalizedValue) = 0; + virtual void EndInformHostOfParamChange(int idx) = 0; + + // ---------------------------------------- + // Useful stuff for your plugin class or an outsider to call, + // most of which is implemented by the API class. + + double GetSampleRate() { return mSampleRate; } + int GetBlockSize() { return mBlockSize; } + int GetLatency() { return mLatency; } + + // In ProcessDoubleReplacing you are always guaranteed to get valid pointers + // to all the channels the plugin requested. If the host hasn't connected all the pins, + // the unconnected channels will be full of zeros. + int NInChannels() { return mInChannels.GetSize(); } + int NOutChannels() { return mOutChannels.GetSize(); } + bool IsInChannelConnected(int chIdx); + bool IsOutChannelConnected(int chIdx); + + virtual int GetSamplePos() = 0; // Samples since start of project. + virtual double GetTempo() = 0; + double GetSamplesPerBeat(); + virtual void GetTimeSig(int* pNum, int* pDenom) = 0; + + virtual EHost GetHost() { return mHost; } + int GetHostVersion(bool decimal); // Decimal = VVVVRRMM, otherwise 0xVVVVRRMM. + void GetHostVersionStr(char* str); + + // Tell the host that the graphics resized. + // Should be called only by the graphics object when it resizes itself. + virtual void ResizeGraphics(int w, int h) = 0; + + // Not fully supported. A call back from the host saying the user has resized the window. + // If the plugin supports different sizes, it may wish to resize. + virtual void UserResizedWindow(IRECT* pR) {} + + void EnsureDefaultPreset(); + +protected: + + // ---------------------------------------- + // Useful stuff for your plugin class to call, implemented here or in the API class, or partly in both. + + struct ChannelIO + { + int mIn, mOut; + ChannelIO(int nIn, int nOut) : mIn(nIn), mOut(nOut) {} + }; + WDL_PtrList mChannelIO; + bool LegalIO(int nIn, int nOut); // -1 for either means check the other value only. + void LimitToStereoIO(); + + void SetHost(const char* host, int version); // Version = 0xVVVVRRMM. + virtual void HostSpecificInit() = 0; + + virtual void AttachGraphics(IGraphics* pGraphics); + + void SetSampleRate(double sampleRate); + virtual void SetBlockSize(int blockSize); + // If latency changes after initialization (often not supported by the host). + virtual void SetLatency(int samples); + virtual bool SendMidiMsg(IMidiMsg* pMsg) = 0; + virtual bool SendMidiMsgs(WDL_TypedBuf* pMsgs) = 0; + bool IsInst() { return mIsInst; } + + void MakeDefaultPreset(char* name = 0, int nPresets = 1); + // MakePreset(name, param1, param2, ..., paramN) + void MakePreset(char* name, ...); + // MakePresetFromNamedParams(name, nParamsNamed, paramEnum1, paramVal1, paramEnum2, paramVal2, ..., paramEnumN, paramVal2) + // nParamsNamed may be less than the total number of params. + void MakePresetFromNamedParams(char* name, int nParamsNamed, ...); + + bool DoesStateChunks() { return mStateChunks; } + // Will append if the chunk is already started. + bool SerializeParams(ByteChunk* pChunk); + // Returns the new chunk position (endPos). + int UnserializeParams(ByteChunk* pChunk, int startPos); + void RedrawParamControls(); // Called after restoring state. + + // ---------------------------------------- + // Internal IPlug stuff (but API classes need to get at it). + + void OnParamReset(); // Calls OnParamChange(each param) + Reset(). + + int NPresets() { return mPresets.GetSize(); } + int GetCurrentPresetIdx() { return mCurrentPresetIdx; } + void PruneUninitializedPresets(); + bool RestorePreset(int idx); + bool RestorePreset(const char* name); + const char* GetPresetName(int idx); + void ModifyCurrentPreset(const char* name = 0); // Sets the currently active preset to whatever current params are. + bool SerializePresets(ByteChunk* pChunk); + // Returns the new chunk position (endPos). + int UnserializePresets(ByteChunk* pChunk, int startPos); + + // Dump the current state as source code for a call to MakePresetFromNamedParams. + void DumpPresetSrcCode(const char* filename, const char* paramEnumNames[]); + + // Set connection state for n channels. + // If a channel is connected, we expect a call to attach the buffers before each process call. + // If a channel is not connected, we attach scratch buffers now and don't need to do anything else. + void SetInputChannelConnections(int idx, int n, bool connected); + void SetOutputChannelConnections(int idx, int n, bool connected); + + void AttachInputBuffers(int idx, int n, double** ppData, int nFrames); + void AttachInputBuffers(int idx, int n, float** ppData, int nFrames); + void AttachOutputBuffers(int idx, int n, double** ppData); + void AttachOutputBuffers(int idx, int n, float** ppData); + void ProcessBuffers(float sampleType, int nFrames); + void ProcessBuffers(double sampleType, int nFrames); + void ProcessBuffersAccumulating(float sampleType, int nFrames); + +public: + + WDL_Mutex mMutex; + + struct IMutexLock + { + WDL_Mutex* mpMutex; + IMutexLock(IPlugBase* pPlug) : mpMutex(&(pPlug->mMutex)) { mpMutex->Enter(); } + ~IMutexLock() { if (mpMutex) { mpMutex->Leave(); } } + void Destroy() { mpMutex->Leave(); mpMutex = 0; } + }; + +private: + + char mEffectName[MAX_EFFECT_NAME_LEN], mProductName[MAX_EFFECT_NAME_LEN], mMfrName[MAX_EFFECT_NAME_LEN]; + int mUniqueID, mMfrID, mVersion; // Version stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. + + EHost mHost; + int mHostVersion; // Version stored as 0xVVVVRRMM: V = version, R = revision, M = minor revision. + + bool mStateChunks, mIsInst; + double mSampleRate; + int mBlockSize, mLatency; + + WDL_PtrList mParams; + IGraphics* mGraphics; + + WDL_PtrList mPresets; + int mCurrentPresetIdx; + + WDL_TypedBuf mInData, mOutData; + struct InChannel { + bool mConnected; + double** mSrc; // Points into mInData. + WDL_TypedBuf mScratchBuf; + }; + struct OutChannel { + bool mConnected; + double** mDest; // Points into mOutData. + float* mFDest; + WDL_TypedBuf mScratchBuf; + }; + WDL_PtrList mInChannels; + WDL_PtrList mOutChannels; +}; + +#endif diff --git a/WDL/IPlug/IPlugStructs.cpp b/WDL/IPlug/IPlugStructs.cpp new file mode 100644 index 00000000..3791b7d1 --- /dev/null +++ b/WDL/IPlug/IPlugStructs.cpp @@ -0,0 +1,147 @@ +#include "IPlugStructs.h" +#include "Log.h" + +//bool IText::operator==(const IText& rhs) const +//{ +// int s = sizeof(*this); +// int r = sizeof(rhs); +// return (s == r && !strcmp(mFont.Get(), rhs.mFont.Get()) && memcmp(this, &rhs, s) == 0); +//} +// +//bool IText::operator<(const IText& rhs) const +//{ +// if (mFont != rhs.mFont) { +// return (mFont < rhs.mFont); +// } +// int s = sizeof(*this); +// int r = sizeof(rhs); +// if (s != r) { +// return (s < r); +// } +// return memcmp(this, &rhs, MIN(s, r)); +//} + +void IMidiMsg::MakeNoteOnMsg(int noteNumber, int velocity, int offset) +{ + Clear(); + mStatus = kNoteOn << 4; + mData1 = noteNumber; + mData2 = velocity; + mOffset = offset; +} + +void IMidiMsg::MakeNoteOffMsg(int noteNumber, int offset) +{ + Clear(); + mStatus = kNoteOff << 4; + mData1 = noteNumber; + mOffset = offset; +} + +void IMidiMsg::MakePitchWheelMsg(double value) +{ + Clear(); + mStatus = kPitchWheel << 4; + int i = 8192 + (int) (value * 8192.0); + i = BOUNDED(i, 0, 16383); + mData2 = i>>7; + mData1 = i&0x7F; +} + +void IMidiMsg::MakeControlChangeMsg(EControlChangeMsg idx, double value) +{ + Clear(); + mStatus = kControlChange << 4; + mData1 = idx; + mData2 = (int) (value * 127.0); +} + +IMidiMsg::EStatusMsg IMidiMsg::StatusMsg() const +{ + unsigned int e = mStatus >> 4; + if (e < kNoteOff || e > kPitchWheel) { + return kNone; + } + return (EStatusMsg) e; +} + +int IMidiMsg::NoteNumber() const +{ + switch (StatusMsg()) { + case kNoteOn: + case kNoteOff: + case kPolyAftertouch: + return mData1; + default: + return -1; + } +} + +int IMidiMsg::Velocity() const +{ + switch (StatusMsg()) { + case kNoteOn: + case kNoteOff: + return mData2; + default: + return -1; + } +} + +int IMidiMsg::Program() const +{ + if (StatusMsg() == kProgramChange) { + return mData1; + } + return -1; +} + +double IMidiMsg::PitchWheel() const +{ + if (StatusMsg() == kPitchWheel) { + int iVal = (mData2 << 7) + mData1; + return (double) (iVal - 8192) / 8192.0; + } + return 0.0; +} + +IMidiMsg::EControlChangeMsg IMidiMsg::ControlChangeIdx() const +{ + return (EControlChangeMsg) mData1; +} + +double IMidiMsg::ControlChange(EControlChangeMsg idx) const +{ + if (StatusMsg() == kControlChange && ControlChangeIdx() == idx) { + return (double) mData2 / 127.0; + } + return -1.0; +} + +void IMidiMsg::Clear() +{ + mOffset = 0; + mStatus = mData1 = mData2 = 0; +} + +const char* StatusMsgStr(IMidiMsg::EStatusMsg msg) +{ + switch (msg) { + case IMidiMsg::kNone: return "none"; + case IMidiMsg::kNoteOff: return "noteoff"; + case IMidiMsg::kNoteOn: return "noteon"; + case IMidiMsg::kPolyAftertouch: return "aftertouch"; + case IMidiMsg::kControlChange: return "controlchange"; + case IMidiMsg::kProgramChange: return "programchange"; + case IMidiMsg::kChannelAftertouch: return "channelaftertouch"; + case IMidiMsg::kPitchWheel: return "pitchwheel"; + default: return "unknown"; + }; +} + +void IMidiMsg::LogMsg() +{ +#ifdef TRACER_BUILD + Trace(TRACELOC, "midi:(%s:%d:%d)", StatusMsgStr(StatusMsg()), NoteNumber(), Velocity()); +#endif +} \ No newline at end of file diff --git a/WDL/IPlug/IPlugStructs.h b/WDL/IPlug/IPlugStructs.h new file mode 100644 index 00000000..b972c31c --- /dev/null +++ b/WDL/IPlug/IPlugStructs.h @@ -0,0 +1,300 @@ +#ifndef _IPLUGSTRUCTS_ +#define _IPLUGSTRUCTS_ + +#include "Containers.h" + +// Abstracting the graphics made it easy to go ahead and abstract the OS ... +// the cost is this crap redefining some basic stuff. + +struct IBitmap +{ + void* mData; + int W, H, N; // N = number of states (for multibitmaps). + IBitmap(void* pData = 0, int w = 0, int h = 0, int n = 1) : mData(pData), W(w), H(h), N(n) {} +}; + +struct IColor +{ + int A, R, G, B; + IColor(int a = 255, int r = 0, int g = 0, int b = 0) : A(a), R(r), G(g), B(b) {} + bool operator==(const IColor& rhs) { return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); } + bool operator!=(const IColor& rhs) { return !operator==(rhs); } + bool Empty() const { return A == 0 && R == 0 && G == 0 && B == 0; } + void Clamp() { A = MIN(A, 255); R = MIN(R, 255); G = MIN(G, 255); B = MIN(B, 255); } +}; + +const IColor COLOR_TRANSPARENT(0, 0, 0, 0); +const IColor COLOR_BLACK(255, 0, 0, 0); +const IColor COLOR_GRAY(255, 127, 127, 127); +const IColor COLOR_WHITE(255, 255, 255, 255); +const IColor COLOR_RED(255, 255, 0, 0); +const IColor COLOR_GREEN(255, 0, 255, 0); +const IColor COLOR_BLUE(255, 0, 0, 255); +const IColor COLOR_YELLOW(255, 255, 255, 0); +const IColor COLOR_ORANGE(255, 255, 127, 0); + +struct IChannelBlend +{ + enum EBlendMethod { + kBlendNone, // Copy over whatever is already there, but look at src alpha. + kBlendClobber, // Copy completely over whatever is already there. + kBlendAdd, + kBlendColorDodge, + // etc + }; + EBlendMethod mMethod; + float mWeight; + + IChannelBlend(EBlendMethod method = kBlendNone, float weight = 1.0f) : mMethod(method), mWeight(weight) {} +}; + +const int DEFAULT_TEXT_SIZE = 14; +const IColor DEFAULT_TEXT_COLOR = COLOR_BLACK; +const char* const DEFAULT_FONT = "Arial"; +const int FONT_LEN = 32; + +struct IText +{ + char mFont[FONT_LEN]; + int mSize; + IColor mColor; + enum EStyle { kStyleNormal, kStyleBold, kStyleItalic } mStyle; + enum EAlign { kAlignNear, kAlignCenter, kAlignFar } mAlign; + int mOrientation; // Degrees ccwise from normal. + + IText(int size = DEFAULT_TEXT_SIZE, const IColor* pColor = 0, char* font = 0, + EStyle style = kStyleNormal, EAlign align = kAlignCenter, int orientation = 0) + : mSize(size), mColor(pColor ? *pColor : DEFAULT_TEXT_COLOR), //mFont(font ? font : DEFAULT_FONT), + mStyle(style), mAlign(align), mOrientation(orientation) + { + strcpy(mFont, (font ? font : DEFAULT_FONT)); + } + + IText(const IColor* pColor) + : mSize(DEFAULT_TEXT_SIZE), mColor(*pColor), //mFont(DEFAULT_FONT), + mStyle(kStyleNormal), mAlign(kAlignCenter), mOrientation(0) + { + strcpy(mFont, DEFAULT_FONT); + } + + // bool operator==(const IText& rhs) const; + // bool operator!=(const IText& rhs) const { return !operator==(rhs); } + // bool operator<(const IText& rhs) const; // For sorting. +}; + +struct IRECT +{ + int L, T, R, B; + + IRECT() { L = T = R = B = 0; } + IRECT(int l, int t, int r, int b) : L(l), R(r), T(t), B(b) {} + IRECT(int x, int y, IBitmap* pBitmap) : L(x), T(y), R(x + pBitmap->W), B(y + pBitmap->H / pBitmap->N) {} + + bool Empty() const { + return (L == 0 && T == 0 && R == 0 && B == 0); + } + void Clear() { + L = T = R = B = 0; + } + bool operator==(const IRECT& rhs) const { + return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B); + } + bool operator!=(const IRECT& rhs) const { + return !(*this == rhs); + } + + inline int W() const { return R - L; } + inline int H() const { return B - T; } + inline float MW() const { return 0.5f * (float) (L + R); } + inline float MH() const { return 0.5f * (float) (T + B); } + + inline IRECT Union(IRECT* pRHS) { + if (Empty()) { return *pRHS; } + if (pRHS->Empty()) { return *this; } + return IRECT(MIN(L, pRHS->L), MIN(T, pRHS->T), MAX(R, pRHS->R), MAX(B, pRHS->B)); + } + inline IRECT Intersect(IRECT* pRHS) { + if (Intersects(pRHS)) { + return IRECT(MAX(L, pRHS->L), MAX(T, pRHS->T), MIN(R, pRHS->R), MIN(B, pRHS->B)); + } + return IRECT(); + } + inline bool Intersects(IRECT* pRHS) { + return (!Empty() && !pRHS->Empty() && R >= pRHS->L && L < pRHS->R && B >= pRHS->T && T < pRHS->B); + } + inline bool Contains(IRECT* pRHS) { + return (!Empty() && !pRHS->Empty() && pRHS->L >= L && pRHS->R <= R && pRHS->T >= T && pRHS->B <= B); + } + inline bool Contains(int x, int y) { + return (!Empty() && x >= L && x < R && y >= T && y < B); + } + + void Clank(IRECT* pRHS) { + if (L < pRHS->L) { + R = MIN(pRHS->R - 1, R + pRHS->L - L); + L = pRHS->L; + } + if (T < pRHS->T) { + B = MIN(pRHS->B - 1, B + pRHS->T - T); + T = pRHS->T; + } + if (R >= pRHS->R) { + L = MAX(pRHS->L, L - (R - pRHS->R + 1)); + R = pRHS->R - 1; + } + if (B >= pRHS->B) { + T = MAX(pRHS->T, T - (B - pRHS->B + 1)); + B = pRHS->B - 1; + } + } +}; + +struct IMouseMod +{ + bool L, R, S, C, A; + IMouseMod(bool l = false, bool r = false, bool s = false, bool c = false, bool a = false) + : L(l), R(r), S(s), C(c), A(a) {} +}; + +struct IMidiMsg +{ + int mOffset; + BYTE mStatus, mData1, mData2; + + enum EStatusMsg { + kNone = 0, + kNoteOff = 8, + kNoteOn = 9, + kPolyAftertouch = 10, + kControlChange = 11, + kProgramChange = 12, + kChannelAftertouch = 13, + kPitchWheel = 14 + }; + + enum EControlChangeMsg { + kModWheel = 1, + kBreathController = 2, + kUndefined003 = 3, + kFootController = 4, + kPortamentoTime = 5, + kChannelVolume = 7, + kBalance = 8, + kUndefined009 = 9, + kPan = 10, + kExpressionController = 11, + kEffectControl1 = 12, + kEffectControl2 = 13, + kUndefined014 = 14, + kUndefined015 = 15, + kGeneralPurposeController1 = 16, + kGeneralPurposeController2 = 17, + kGeneralPurposeController3 = 18, + kGeneralPurposeController4 = 19, + kUndefined020 = 20, + kUndefined021 = 21, + kUndefined022 = 22, + kUndefined023 = 23, + kUndefined024 = 24, + kUndefined025 = 25, + kUndefined026 = 26, + kUndefined027 = 27, + kUndefined028 = 28, + kUndefined029 = 29, + kUndefined030 = 30, + kUndefined031 = 31, + kSustainOnOff = 64, + kPortamentoOnOff = 65, + kSustenutoOnOff = 66, + kSoftPedalOnOff = 67, + kLegatoOnOff = 68, + kHold2OnOff = 69, + kSoundVariation = 70, + kResonance = 71, + kReleaseTime = 72, + kAttackTime = 73, + kCutoffFrequency = 74, + kDecayTime = 75, + kVibratoRate = 76, + kVibratoDepth = 77, + kVibratoDelay = 78, + kSoundControllerUndefined = 79, + kUndefined085 = 85, + kUndefined086 = 86, + kUndefined087 = 87, + kUndefined088 = 88, + kUndefined089 = 89, + kUndefined090 = 90, + kTremoloDepth = 92, + kChorusDepth = 93, + kPhaserDepth = 95, + kUndefined102 = 102, + kUndefined103 = 103, + kUndefined104 = 104, + kUndefined105 = 105, + kUndefined106 = 106, + kUndefined107 = 107, + kUndefined108 = 108, + kUndefined109 = 109, + kUndefined110 = 110, + kUndefined111 = 111, + kUndefined112 = 112, + kUndefined113 = 113, + kUndefined114 = 114, + kUndefined115 = 115, + kUndefined116 = 116, + kUndefined117 = 117, + kUndefined118 = 118, + kUndefined119 = 119, + kAllNotesOff = 123 + }; + + IMidiMsg(int offs = 0, BYTE s = 0, BYTE d1 = 0, BYTE d2 = 0) : mOffset(offs), mStatus(s), mData1(d1), mData2(d2) {} + + void MakeNoteOnMsg(int noteNumber, int velocity, int offset); + void MakeNoteOffMsg(int noteNumber, int offset); + void MakePitchWheelMsg(double value); // Value in [-1, 1], converts to [0, 16384) where 8192 = no pitch change. + void MakeControlChangeMsg(EControlChangeMsg idx, double value); // Value in [0, 1]. + + EStatusMsg StatusMsg() const; + int NoteNumber() const; // Returns [0, 128), -1 if NA. + int Velocity() const; // Returns [0, 128), -1 if NA. + int Program() const; // Returns [0, 128), -1 if NA. + double PitchWheel() const; // Returns [-1.0, 1.0], zero if NA. + EControlChangeMsg ControlChangeIdx() const; + double ControlChange(EControlChangeMsg idx) const; // return [0, 1], -1 if NA. + static bool ControlChangeOnOff(double msgValue) { return (msgValue >= 0.5); } // true = on. + void Clear(); + void LogMsg(); +}; + +const int MAX_PRESET_NAME_LEN = 256; +#define UNUSED_PRESET_NAME "empty" + +struct IPreset +{ + bool mInitialized; + char mName[MAX_PRESET_NAME_LEN]; + ByteChunk mChunk; + + IPreset(int idx) + : mInitialized(false) + { + sprintf(mName, "- %d -", idx+1); + } +}; + +enum +{ + KEY_SPACE, + KEY_UPARROW, + KEY_DOWNARROW, + KEY_LEFTARROW, + KEY_RIGHTARROW, + KEY_DIGIT_0, + KEY_DIGIT_9=KEY_DIGIT_0+9, + KEY_ALPHA_A, + KEY_ALPHA_Z=KEY_ALPHA_A+25 +}; + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlugVST.cpp b/WDL/IPlug/IPlugVST.cpp new file mode 100644 index 00000000..327dd88b --- /dev/null +++ b/WDL/IPlug/IPlugVST.cpp @@ -0,0 +1,685 @@ +#include "IPlugVST.h" +#include "IGraphics.h" +#include + +const int VST_VERSION = 2400; + + +int VSTSpkrArrType(int nchan) +{ + if (!nchan) return kSpeakerArrEmpty; + if (nchan == 1) return kSpeakerArrMono; + if (nchan == 2) return kSpeakerArrStereo; + return kSpeakerArrUserDefined; +} + + +IPlugVST::IPlugVST(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency, + bool plugDoesMidi, bool plugDoesChunks, bool plugIsInst) +: IPlugBase(nParams, channelIOStr, nPresets, effectName, productName, mfrName, + vendorVersion, uniqueID, mfrID, latency, + plugDoesMidi, plugDoesChunks, plugIsInst), + mDoesMidi(plugDoesMidi), mHostCallback(instanceInfo.mVSTHostCallback), mHostSpecificInitDone(false) +{ + Trace(TRACELOC, "%s", effectName); + + mHasVSTExtensions = VSTEXT_NONE; + + int nInputs = NInChannels(), nOutputs = NOutChannels(); + + memset(&mAEffect, 0, sizeof(AEffect)); + mAEffect.object = this; + mAEffect.magic = kEffectMagic; + mAEffect.dispatcher = VSTDispatcher; + mAEffect.getParameter = VSTGetParameter; + mAEffect.setParameter = VSTSetParameter; + mAEffect.numPrograms = nPresets; + mAEffect.numParams = nParams; + mAEffect.numInputs = nInputs; + mAEffect.numOutputs = nOutputs; + mAEffect.uniqueID = uniqueID; + mAEffect.version = GetEffectVersion(true); + mAEffect.__ioRatioDeprecated = 1.0f; + mAEffect.__processDeprecated = VSTProcess; + mAEffect.processReplacing = VSTProcessReplacing; + mAEffect.processDoubleReplacing = VSTProcessDoubleReplacing; + mAEffect.initialDelay = latency; + mAEffect.flags = effFlagsCanReplacing | effFlagsCanDoubleReplacing; + if (plugDoesChunks) { + mAEffect.flags |= effFlagsProgramChunks; + } + if (LegalIO(1, -1)) { + mAEffect.flags |= __effFlagsCanMonoDeprecated; + } + if (plugIsInst) { + mAEffect.flags |= effFlagsIsSynth; + } + + memset(&mEditRect, 0, sizeof(ERect)); + + memset(&mInputSpkrArr, 0, sizeof(VstSpeakerArrangement)); + memset(&mOutputSpkrArr, 0, sizeof(VstSpeakerArrangement)); + mInputSpkrArr.numChannels = nInputs; + mOutputSpkrArr.numChannels = nOutputs; + mInputSpkrArr.type = VSTSpkrArrType(nInputs); + mOutputSpkrArr.type = VSTSpkrArrType(nOutputs); + + // Default everything to connected, then disconnect pins if the host says to. + SetInputChannelConnections(0, nInputs, true); + SetOutputChannelConnections(0, nOutputs, true); + + SetBlockSize(DEFAULT_BLOCK_SIZE); +} + +void IPlugVST::BeginInformHostOfParamChange(int idx) +{ + mHostCallback(&mAEffect, audioMasterBeginEdit, idx, 0, 0, 0.0f); +} + +void IPlugVST::InformHostOfParamChange(int idx, double normalizedValue) +{ + mHostCallback(&mAEffect, audioMasterAutomate, idx, 0, 0, (float) normalizedValue); +} + +void IPlugVST::EndInformHostOfParamChange(int idx) +{ + mHostCallback(&mAEffect, audioMasterEndEdit, idx, 0, 0, 0.0f); +} + +inline VstTimeInfo* GetTimeInfo(audioMasterCallback hostCallback, AEffect* pAEffect, int filter = 0) +{ +#pragma warning(disable:4312) // Pointer size cast mismatch. + VstTimeInfo* pTI = (VstTimeInfo*) hostCallback(pAEffect, audioMasterGetTime, 0, filter, 0, 0); +#pragma warning(default:4312) + if (pTI && (!filter || (pTI->flags & filter))) { + return pTI; + } + return 0; +} + +int IPlugVST::GetSamplePos() +{ + VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect); + if (pTI && pTI->samplePos >= 0.0) { + return int(pTI->samplePos); + } + return 0; +} + +double IPlugVST::GetTempo() +{ + if (mHostCallback) { + VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect, kVstTempoValid); + if (pTI && pTI->tempo >= 0.0) { + return pTI->tempo; + } + } + return 0.0; +} + +void IPlugVST::GetTimeSig(int* pNum, int* pDenom) +{ + *pNum = *pDenom = 0; + VstTimeInfo* pTI = GetTimeInfo(mHostCallback, &mAEffect, kVstTimeSigValid); + if (pTI && pTI->timeSigNumerator >= 0.0 && pTI->timeSigDenominator >= 0.0) { + *pNum = pTI->timeSigNumerator; + *pDenom = pTI->timeSigDenominator; + } +} + +EHost IPlugVST::GetHost() +{ + EHost host = IPlugBase::GetHost(); + if (host == kHostUninit) { + char vendorStr[256], productStr[256]; + productStr[0] = '\0'; + int version = 0; + mHostCallback(&mAEffect, audioMasterGetProductString, 0, 0, productStr, 0.0f); + if (CSTR_NOT_EMPTY(vendorStr) || CSTR_NOT_EMPTY(productStr)) { + int decVer = mHostCallback(&mAEffect, audioMasterGetVendorVersion, 0, 0, 0, 0.0f); + int ver = decVer / 10000; + int rmaj = (decVer - 10000 * ver) / 100; + int rmin = (decVer - 10000 * ver - 100 * rmaj); + version = (ver << 16) + (rmaj << 8) + rmin; + } + SetHost(productStr, version); + host = IPlugBase::GetHost(); + } + return host; +} + +void IPlugVST::AttachGraphics(IGraphics* pGraphics) +{ + if (pGraphics) { + IPlugBase::AttachGraphics(pGraphics); + mAEffect.flags |= effFlagsHasEditor; + mEditRect.left = mEditRect.top = 0; + mEditRect.right = pGraphics->Width(); + mEditRect.bottom = pGraphics->Height(); + } +} + +void IPlugVST::ResizeGraphics(int w, int h) +{ + IGraphics* pGraphics = GetGUI(); + if (pGraphics) { + mEditRect.left = mEditRect.top = 0; + mEditRect.right = pGraphics->Width(); + mEditRect.bottom = pGraphics->Height(); + } +} + +void IPlugVST::SetLatency(int samples) +{ + mAEffect.initialDelay = samples; + IPlugBase::SetLatency(samples); +} + +bool IPlugVST::SendVSTEvent(VstEvent* pEvent) +{ + // It would be more efficient to bundle these and send at the end of a processed block, + // but that would require writing OnBlockEnd and making sure it always gets called, + // and who cares anyway, midi events aren't that dense. + VstEvents events; + memset(&events, 0, sizeof(VstEvents)); + events.numEvents = 1; + events.events[0] = pEvent; + return (mHostCallback(&mAEffect, audioMasterProcessEvents, 0, 0, &events, 0.0f) == 1); +} + +bool IPlugVST::SendMidiMsg(IMidiMsg* pMsg) +{ + VstMidiEvent midiEvent; + memset(&midiEvent, 0, sizeof(VstMidiEvent)); + + midiEvent.type = kVstMidiType; + midiEvent.byteSize = sizeof(VstMidiEvent); // Should this be smaller? + midiEvent.deltaFrames = pMsg->mOffset; + midiEvent.midiData[0] = pMsg->mStatus; + midiEvent.midiData[1] = pMsg->mData1; + midiEvent.midiData[2] = pMsg->mData2; + + return SendVSTEvent((VstEvent*) &midiEvent); +} + +bool IPlugVST::SendMidiMsgs(WDL_TypedBuf* pMsgs) +{ + // Todo: bundle and SendVSTEvents. + bool rc = true; + int n = pMsgs->GetSize(); + IMidiMsg* pMsg = pMsgs->Get(); + for (int i = 0; i < n; ++i, ++pMsg) { + rc &= SendMidiMsg(pMsg); + } + return rc; +} + +audioMasterCallback IPlugVST::GetHostCallback() +{ + return mHostCallback; +} + +void IPlugVST::HostSpecificInit() +{ + if (!mHostSpecificInitDone) { + mHostSpecificInitDone = true; + EHost host = GetHost(); + switch (host) { + case kHostAudition: + case kHostOrion: + case kHostForte: + case kHostSAWStudio: + LimitToStereoIO(); + break; + } + + // This won't always solve a picky host problem -- for example Forte + // looks at mAEffect IO count before identifying itself. + mAEffect.numInputs = mInputSpkrArr.numChannels = NInChannels(); + mAEffect.numOutputs = mOutputSpkrArr.numChannels = NOutChannels(); + } +} + +#define IPLUG_VERSION_MAGIC 'pfft' + +void InitializeVSTChunk(ByteChunk* pChunk) +{ + pChunk->Clear(); + int magic = IPLUG_VERSION_MAGIC; + pChunk->Put(&magic); + int ver = IPLUG_VERSION; + pChunk->Put(&ver); +} + +int GetIPlugVerFromChunk(ByteChunk* pChunk, int* pPos) +{ + int magic = 0, ver = 0; + int pos = pChunk->Get(&magic, *pPos); + if (pos > *pPos && magic == IPLUG_VERSION_MAGIC) { + *pPos = pChunk->Get(&ver, pos); + } + return ver; +} + +VstIntPtr VSTCALLBACK IPlugVST::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt) +{ + // VSTDispatcher is an IPlugVST class member, we can access anything in IPlugVST from here. + IPlugVST* _this = (IPlugVST*) pEffect->object; + if (!_this) { + return 0; + } + IPlugBase::IMutexLock lock(_this); + + // Handle a couple of opcodes here to make debugging easier. + switch (opCode) { + case effEditIdle: + case __effIdleDeprecated: + #ifdef USE_IDLE_CALLS + _this->OnIdle(); + #endif + return 0; + } + + Trace(TRACELOC, "%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (int) value); + + switch (opCode) { + + case effOpen: { + _this->HostSpecificInit(); + _this->OnParamReset(); + return 0; + } + case effClose: { + lock.Destroy(); + DELETE_NULL(_this); + return 0; + } + case effGetParamLabel: { + if (idx >= 0 && idx < _this->NParams()) + { + strcpy((char*) ptr, _this->GetParam(idx)->GetLabelForHost()); + } + return 0; + } + case effGetParamDisplay: { + if (idx >= 0 && idx < _this->NParams()) + { + _this->GetParam(idx)->GetDisplayForHost((char*) ptr); + } + return 0; + } + case effGetParamName: { + if (idx >= 0 && idx < _this->NParams()) + { + strcpy((char*) ptr, _this->GetParam(idx)->GetNameForHost()); + } + return 0; + } + case effSetSampleRate: { + _this->SetSampleRate(opt); + _this->Reset(); + return 0; + } + case effSetBlockSize: { + _this->SetBlockSize(value); + _this->Reset(); + return 0; + } + case effMainsChanged: { + if (!value) { + _this->OnActivate(false); + _this->Reset(); + } + else { + _this->OnActivate(true); + } + return 0; + } + case effEditGetRect: { + if (ptr && _this->GetGUI()) { + *(ERect**) ptr = &(_this->mEditRect); + return 1; + } + ptr = 0; + return 0; + } + case effEditOpen: + { + IGraphics* pGraphics = _this->GetGUI(); + if (pGraphics) + { +#ifdef _WIN32 + if (!pGraphics->OpenWindow(ptr)) pGraphics=0; +#else // OSX, check if we are in a Cocoa VST host + bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA); + if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0; + if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0; +#endif + if (pGraphics) + { + _this->OnGUIOpen(); + return 1; + } + } + return 0; + } + case effEditClose: { + if (_this->GetGUI()) { + _this->OnGUIClose(); + _this->GetGUI()->CloseWindow(); + return 1; + } + return 0; + } + case __effIdentifyDeprecated: { + return 'NvEf'; // Random deprecated magic. + } + case effGetChunk: { + BYTE** ppData = (BYTE**) ptr; + if (ppData) { + bool isBank = (!idx); + ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); + InitializeVSTChunk(pChunk); + bool savedOK = true; + if (isBank) { + _this->ModifyCurrentPreset(); + //savedOK = _this->SerializePresets(pChunk); + savedOK = _this->SerializeState(pChunk); + } + else { + savedOK = _this->SerializeState(pChunk); + } + if (savedOK && pChunk->Size()) { + *ppData = pChunk->GetBytes(); + return pChunk->Size(); + } + } + return 0; + } + case effSetChunk: { + if (ptr) { + bool isBank = (!idx); + ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState)); + pChunk->Resize(value); + memcpy(pChunk->GetBytes(), ptr, value); + int pos = 0; + int iplugVer = GetIPlugVerFromChunk(pChunk, &pos); + isBank &= (iplugVer >= 0x010000); + if (isBank) { + //pos = _this->UnserializePresets(pChunk, pos); + pos = _this->UnserializeState(pChunk, pos); + } + else { + pos = _this->UnserializeState(pChunk, pos); + _this->ModifyCurrentPreset(); + } + if (pos >= 0) { + _this->RedrawParamControls(); + return 1; + } + } + return 0; + } + case effProcessEvents: { + VstEvents* pEvents = (VstEvents*) ptr; + if (pEvents && pEvents->events) { + for (int i = 0; i < pEvents->numEvents; ++i) { + VstEvent* pEvent = pEvents->events[i]; + if (pEvent) { + if (pEvent->type == kVstMidiType) { + VstMidiEvent* pME = (VstMidiEvent*) pEvent; + IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]); + _this->ProcessMidiMsg(&msg); + //#ifdef TRACER_BUILD + // msg.LogMsg(); + //#endif + } + else { + _this->SendVSTEvent(pEvent); // Pass sysex messages through. + } + } + } + return 1; + } + return 0; + } + case effCanBeAutomated: { + return 1; + } + case effGetInputProperties: { + if (ptr && idx >= 0 && idx < _this->NInChannels()) { + VstPinProperties* pp = (VstPinProperties*) ptr; + pp->flags = kVstPinIsActive; + if (!(idx%2) && idx < _this->NInChannels()-1) + { + pp->flags |= kVstPinIsStereo; + } + sprintf(pp->label, "Input %d", idx + 1); + return 1; + } + return 0; + } + case effGetOutputProperties: { + if (ptr && idx >= 0 && idx < _this->NOutChannels()) { + VstPinProperties* pp = (VstPinProperties*) ptr; + pp->flags = kVstPinIsActive; + if (!(idx%2) && idx < _this->NOutChannels()-1) + { + pp->flags |= kVstPinIsStereo; + } + sprintf(pp->label, "Output %d", idx + 1); + return 1; + } + return 0; + } + case effGetPlugCategory: { + if (_this->IsInst()) return kPlugCategSynth; + return kPlugCategEffect; + } + case effProcessVarIo: { + // VstVariableIo* pIO = (VstVariableIo*) ptr; // For offline processing (of audio files?) + return 0; + } + case effSetSpeakerArrangement: { + VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value; + VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr; + if (pInputArr) { + int n = pInputArr->numChannels; + _this->SetInputChannelConnections(0, n, true); + _this->SetInputChannelConnections(n, _this->NInChannels() - n, false); + } + if (pOutputArr) { + int n = pOutputArr->numChannels; + _this->SetOutputChannelConnections(0, n, true); + _this->SetOutputChannelConnections(n, _this->NOutChannels() - n, false); + } + return 1; + } + case effGetSpeakerArrangement: { + VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value; + VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr; + if (ppInputArr) { + *ppInputArr = &(_this->mInputSpkrArr); + } + if (ppOutputArr) { + *ppOutputArr = &(_this->mOutputSpkrArr); + } + return 1; + } + case effGetEffectName: { + if (ptr) { + strcpy((char*) ptr, _this->GetEffectName()); + return 1; + } + return 0; + } + case effGetProductString: { + if (ptr) { + strcpy((char*) ptr, _this->GetProductName()); + return 1; + } + return 0; + } + case effGetVendorString: { + if (ptr) { + strcpy((char*) ptr, _this->GetMfrName()); + return 1; + } + return 0; + } + case effCanDo: { + if (ptr) { + Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr); + if (!strcmp((char*) ptr, "receiveVstTimeInfo")) { + return 1; + } + if (_this->mDoesMidi) { + if (!strcmp((char*) ptr, "sendVstEvents") || + !strcmp((char*) ptr, "sendVstMidiEvent") || + !strcmp((char*) ptr, "receiveVstEvents") || + !strcmp((char*) ptr, "receiveVstMidiEvent")) { // || + //!strcmp((char*) ptr, "midiProgramNames")) { + return 1; + } + } + // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ + if (!strcmp((char*) ptr, "hasCockosExtensions")) + { + _this->mHasVSTExtensions |= VSTEXT_COCKOS; + return 0xbeef0000; + } + else if (!strcmp((char*) ptr, "hasCockosViewAsConfig")) + { + _this->mHasVSTExtensions |= VSTEXT_COCOA; + return 0xbeef0000; + } + } + return 0; + } + case effVendorSpecific: { + // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/ + if (idx == effGetParamDisplay && ptr) { + if (value >= 0 && value < _this->NParams()) { + _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr); + } + return 0xbeef; + } + return 0; + } + case effGetProgram: { + return _this->GetCurrentPresetIdx(); + } + case effSetProgram: { + if (!(_this->DoesStateChunks())) { + _this->ModifyCurrentPreset(); + } + _this->RestorePreset((int) value); + return 0; + } + case effGetProgramNameIndexed: { + strcpy((char*) ptr, _this->GetPresetName(idx)); + return (CSTR_NOT_EMPTY((char*) ptr) ? 1 : 0); + } + case effSetProgramName: { + if (ptr) { + _this->ModifyCurrentPreset((char*) ptr); + } + return 0; + } + case effGetProgramName: { + if (ptr) { + int idx = _this->GetCurrentPresetIdx(); + strcpy((char*) ptr, _this->GetPresetName(idx)); + } + return 0; + } + case effGetMidiKeyName: { + if (ptr) { + MidiKeyName* pMKN = (MidiKeyName*) ptr; + pMKN->keyName[0] = '\0'; + if (_this->MidiNoteName(pMKN->thisKeyNumber, pMKN->keyName)) { + return 1; + } + } + return 0; + } + case effGetVstVersion: { + return VST_VERSION; + } + case effBeginSetProgram: + case effEndSetProgram: + case effGetMidiProgramName: + case effHasMidiProgramsChanged: + case effGetMidiProgramCategory: + case effGetCurrentMidiProgram: + case effSetBypass: + default: { + return 0; + } + } +} + +template +void IPlugVST::VSTPrepProcess(SAMPLETYPE** inputs, SAMPLETYPE** outputs, VstInt32 nFrames) +{ + if (mDoesMidi) { + mHostCallback(&mAEffect, __audioMasterWantMidiDeprecated, 0, 0, 0, 0.0f); + } + AttachInputBuffers(0, NInChannels(), inputs, nFrames); + AttachOutputBuffers(0, NOutChannels(), outputs); +} + +// Deprecated. +void VSTCALLBACK IPlugVST::VSTProcess(AEffect* pEffect, float** inputs, float** outputs, VstInt32 nFrames) +{ + TRACE; + IPlugVST* _this = (IPlugVST*) pEffect->object; + IMutexLock lock(_this); + _this->VSTPrepProcess(inputs, outputs, nFrames); + _this->ProcessBuffersAccumulating((float) 0.0f, nFrames); +} + +void VSTCALLBACK IPlugVST::VSTProcessReplacing(AEffect* pEffect, float** inputs, float** outputs, VstInt32 nFrames) +{ + TRACE; + IPlugVST* _this = (IPlugVST*) pEffect->object; + IMutexLock lock(_this); + _this->VSTPrepProcess(inputs, outputs, nFrames); + _this->ProcessBuffers((float) 0.0f, nFrames); +} + +void VSTCALLBACK IPlugVST::VSTProcessDoubleReplacing(AEffect* pEffect, double** inputs, double** outputs, VstInt32 nFrames) +{ + TRACE; + IPlugVST* _this = (IPlugVST*) pEffect->object; + IMutexLock lock(_this); + _this->VSTPrepProcess(inputs, outputs, nFrames); + _this->ProcessBuffers((double) 0.0, nFrames); +} + +float VSTCALLBACK IPlugVST::VSTGetParameter(AEffect *pEffect, VstInt32 idx) +{ + Trace(TRACELOC, "%d", idx); + IPlugVST* _this = (IPlugVST*) pEffect->object; + IMutexLock lock(_this); + if (idx >= 0 && idx < _this->NParams()) { + return (float) _this->GetParam(idx)->GetNormalized(); + } + return 0.0f; +} + +void VSTCALLBACK IPlugVST::VSTSetParameter(AEffect *pEffect, VstInt32 idx, float value) +{ + Trace(TRACELOC, "%d:%f", idx, value); + IPlugVST* _this = (IPlugVST*) pEffect->object; + IMutexLock lock(_this); + if (idx >= 0 && idx < _this->NParams()) { + if (_this->GetGUI()) { + _this->GetGUI()->SetParameterFromPlug(idx, value, true); + } + _this->GetParam(idx)->SetNormalized(value); + _this->OnParamChange(idx); + } +} diff --git a/WDL/IPlug/IPlugVST.h b/WDL/IPlug/IPlugVST.h new file mode 100644 index 00000000..ee69abda --- /dev/null +++ b/WDL/IPlug/IPlugVST.h @@ -0,0 +1,84 @@ +#ifndef _IPLUGAPI_ +#define _IPLUGAPI_ +// Only load one API class! + +#include "IPlugBase.h" +#include "../../VST_SDK/aeffectx.h" + +struct IPlugInstanceInfo +{ + audioMasterCallback mVSTHostCallback; +}; + +class IPlugVST : public IPlugBase +{ +public: + + // Use IPLUG_CTOR instead of calling directly (defined in IPlug_include_in_plug_src.h). + IPlugVST(IPlugInstanceInfo instanceInfo, int nParams, const char* channelIOStr, int nPresets, + const char* effectName, const char* productName, const char* mfrName, + int vendorVersion, int uniqueID, int mfrID, int latency = 0, + bool plugDoesMidi = false, bool plugDoesChunks = false, + bool plugIsInst = false); + + // ---------------------------------------- + // See IPlugBase for the full list of methods that your plugin class can implement. + + void BeginInformHostOfParamChange(int idx); + void InformHostOfParamChange(int idx, double normalizedValue); + void EndInformHostOfParamChange(int idx); + + int GetSamplePos(); // Samples since start of project. + double GetTempo(); + void GetTimeSig(int* pNum, int* pDenom); + EHost GetHost(); // GetHostVersion() is inherited. + + // Tell the host that the graphics resized. + // Should be called only by the graphics object when it resizes itself. + void ResizeGraphics(int w, int h); + +protected: + + void HostSpecificInit(); + void AttachGraphics(IGraphics* pGraphics); + void SetLatency(int samples); + bool SendMidiMsg(IMidiMsg* pMsg); + bool SendMidiMsgs(WDL_TypedBuf* pMsgs); + audioMasterCallback GetHostCallback(); + +private: + + template + void VSTPrepProcess(SAMPLETYPE** inputs, SAMPLETYPE** outputs, VstInt32 nFrames); + + ERect mEditRect; + audioMasterCallback mHostCallback; + + bool SendVSTEvent(VstEvent* pEvent); + bool SendVSTEvents(WDL_TypedBuf* pEvents); + + VstSpeakerArrangement mInputSpkrArr, mOutputSpkrArr; + + bool mHostSpecificInitDone; + bool mDoesMidi; + + enum { VSTEXT_NONE=0, VSTEXT_COCKOS, VSTEXT_COCOA }; // list of VST extensions supported by host + int mHasVSTExtensions; + + ByteChunk mState; // Persistent storage if the host asks for plugin state. + ByteChunk mBankState; // Persistent storage if the host asks for bank state. + +public: + + static VstIntPtr VSTCALLBACK VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt); + static void VSTCALLBACK VSTProcess(AEffect *pEffect, float **inputs, float **outputs, VstInt32 nFrames); // Deprecated. + static void VSTCALLBACK VSTProcessReplacing(AEffect *pEffect, float **inputs, float **outputs, VstInt32 nFrames); + static void VSTCALLBACK VSTProcessDoubleReplacing(AEffect *pEffect, double **inputs, double **outputs, VstInt32 nFrames); + static float VSTCALLBACK VSTGetParameter(AEffect *pEffect, VstInt32 idx); + static void VSTCALLBACK VSTSetParameter(AEffect *pEffect, VstInt32 idx, float value); + AEffect mAEffect; +}; + +IPlugVST* MakePlug(); + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug_Prefix.pch b/WDL/IPlug/IPlug_Prefix.pch new file mode 100644 index 00000000..f0850233 --- /dev/null +++ b/WDL/IPlug/IPlug_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'IPlug' target in the 'IPlug' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/WDL/IPlug/IPlug_include_in_plug_hdr.h b/WDL/IPlug/IPlug_include_in_plug_hdr.h new file mode 100644 index 00000000..7540fa38 --- /dev/null +++ b/WDL/IPlug/IPlug_include_in_plug_hdr.h @@ -0,0 +1,32 @@ +#ifndef _IPLUG_INCLUDE_HDR_ +#define _IPLUG_INCLUDE_HDR_ + +// Include this file in the main header for your plugin, +// after #defining either VST_API or AU_API. + +#include "resource.h" // This is your plugin's resource.h. + +#if defined VST_API + #include "IPlugVST.h" + typedef IPlugVST IPlug; + #define API_EXT "vst" +#elif defined AU_API + #include "IPlugAU.h" + typedef IPlugAU IPlug; + #define API_EXT "audiounit" +#else + #error "No API defined!" +#endif + +#if defined _WIN32 + #include "IGraphicsWin.h" + #define EXPORT __declspec(dllexport) +#elif defined __APPLE__ + #include "IGraphicsMac.h" + #define EXPORT + #define BUNDLE_ID "com." BUNDLE_MFR "." API_EXT "." BUNDLE_NAME +#else + #error "No OS defined!" +#endif + +#endif \ No newline at end of file diff --git a/WDL/IPlug/IPlug_include_in_plug_src.h b/WDL/IPlug/IPlug_include_in_plug_src.h new file mode 100644 index 00000000..f53d9dac --- /dev/null +++ b/WDL/IPlug/IPlug_include_in_plug_src.h @@ -0,0 +1,94 @@ +#ifndef _IPLUG_INCLUDE_SRC_ +#define _IPLUG_INCLUDE_SRC_ + +// Include this file in the main source for your plugin, +// after #including the main header for your plugin. + +#if defined _WIN32 + HINSTANCE gHInstance = 0; + BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD fdwReason, LPVOID res) + { + gHInstance = hDllInst; + return TRUE; + } + IGraphics* MakeGraphics(IPlug* pPlug, int w, int h, int FPS = 0) + { + IGraphicsWin* pGraphics = new IGraphicsWin(pPlug, w, h, FPS); + pGraphics->SetHInstance(gHInstance); + return pGraphics; + } +#elif defined __APPLE__ + IGraphics* MakeGraphics(IPlug* pPlug, int w, int h, int FPS = 0) + { + IGraphicsMac* pGraphics = new IGraphicsMac(pPlug, w, h, FPS); + pGraphics->SetBundleID(BUNDLE_ID); + return pGraphics; + } +#else + #error "No OS defined!" +#endif + +#if defined VST_API + extern "C" + { + EXPORT void* VSTPluginMain(audioMasterCallback hostCallback) + { + static WDL_Mutex sMutex; + WDL_MutexLock lock(&sMutex); + IPlugInstanceInfo instanceInfo; + instanceInfo.mVSTHostCallback = hostCallback; + IPlugVST* pPlug = new PLUG_CLASS_NAME(instanceInfo); + if (pPlug) { + pPlug->EnsureDefaultPreset(); + pPlug->mAEffect.numPrograms = MAX(pPlug->mAEffect.numPrograms, 1); + return &(pPlug->mAEffect); + } + return 0; + } + EXPORT int main(audioMasterCallback hostCallback) + { + return (int) VSTPluginMain(hostCallback); + } + }; +#elif defined AU_API + IPlug* MakePlug() + { + static WDL_Mutex sMutex; + WDL_MutexLock lock(&sMutex); + IPlugInstanceInfo instanceInfo; + instanceInfo.mOSXBundleID.Set(BUNDLE_ID); + instanceInfo.mCocoaViewFactoryClassName.Set(VIEW_CLASS_STR); + return new PLUG_CLASS_NAME(instanceInfo); + } + extern "C" + { + ComponentResult PLUG_ENTRY(ComponentParameters* params, void* pPlug) + { + return IPlugAU::IPlugAUEntry(params, pPlug); + } + ComponentResult PLUG_VIEW_ENTRY(ComponentParameters* params, void* pView) + { + return IPlugAU::IPlugAUCarbonViewEntry(params, pView); + } + }; +#else + #error "No API defined!" +#endif + +#if defined _DEBUG + #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME " DEBUG") +#elif defined TRACER_BUILD + #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME " TRACER") +#elif defined TIMESTAMP_PLUG_NAME + #pragma REMINDER("plug name is timestamped") + #define PUBLIC_NAME APPEND_TIMESTAMP(PLUG_NAME) +#else + #define PUBLIC_NAME PLUG_NAME +#endif + +#define IPLUG_CTOR(nParams, nPresets, instanceInfo) \ + IPlug(instanceInfo, nParams, PLUG_CHANNEL_IO, nPresets, \ + PUBLIC_NAME, "", PLUG_MFR, PLUG_VER, PLUG_UNIQUE_ID, PLUG_MFR_ID, \ + PLUG_LATENCY, PLUG_DOES_MIDI, PLUG_DOES_STATE_CHUNKS, PLUG_IS_INST) + +#endif \ No newline at end of file diff --git a/WDL/IPlug/Log.cpp b/WDL/IPlug/Log.cpp new file mode 100644 index 00000000..1509d09c --- /dev/null +++ b/WDL/IPlug/Log.cpp @@ -0,0 +1,405 @@ +#include "Log.h" +#include "stdio.h" +#include "string.h" +#include "time.h" +#include + +#ifdef _WIN32 + #define LOGFILE "C:\\IPlugLog.txt" +#else + #define LOGFILE "/IPlugLog.txt" +#endif + +const int TXTLEN = 1024; + +// _vsnsprintf + +#define VARARGS_TO_STR(str) { \ + try { \ + va_list argList; \ + va_start(argList, format); \ + int i = vsnprintf(str, TXTLEN-2, format, argList); \ + if (i < 0 || i > TXTLEN-2) { \ + str[TXTLEN-1] = '\0'; \ + } \ + va_end(argList); \ + } \ + catch(...) { \ + strcpy(str, "parse error"); \ + } \ + strcat(str, "\r\n"); \ +} + +struct LogFile +{ + FILE* mFP; + + LogFile() + { + mFP = fopen(LOGFILE, "w"); + assert(mFP); + } + + ~LogFile() + { + fclose(mFP); + mFP = 0; + } +}; + +Timer::Timer() +{ + mT = clock(); +} + +bool Timer::Every(double sec) +{ + if (clock() - mT > sec * CLOCKS_PER_SEC) { + mT = clock(); + return true; + } + return false; +}; + +// Needs rewriting for WDL. +//StrVector ReadFileIntoStr(WDL_String* pFileName) +//{ +// WDL_PtrList lines; +// if (!strlen(pFileName->Get())) { +// WDL_String line; +// std::ifstream ifs(pFileName->Get()); +// if (ifs) { +// while (std::getline(ifs, line, '\n')) { +// if (!line.empty()) { +// lines.push_back(line); +// } +// } +// ifs.close(); +// } +// } +// return lines; +//} + +// Needs rewriting for WDL. +//int WriteBufferToFile(const DBuffer& buf, const std::string& fileName) +//{ +// std::ofstream ofs(fileName.c_str()); +// if (ofs) { +// for (int i = 0, p = buf.Pos(); i < buf.Size(); ++i, ++p) { +// ofs << buf[p] << ' '; +// } +// ofs << '\n'; +// ofs.close(); +// return buf.Size(); +// } +// return 0; +//} + +bool IsWhitespace(char c) +{ + return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); +} + +// Needs rewriting for WDL. +//StrVector SplitStr(const std::string& line, char separator) +//{ +// std::string field; +// StrVector fields; +// for (int i = 0; i < line.size(); ++i) { +// bool sep = (line[i] == separator); +// sep |= (IsWhitespace(separator) && IsWhitespace(line[i])); +// +// if (!sep) { +// field.push_back(line[i]); +// } +// else +// if (!field.empty()) { +// fields.push_back(field); +// field.clear(); +// } +// } +// if (!field.empty()) { +// fields.push_back(field); +// } +// return fields; +//} + +void ToLower(char* cDest, const char* cSrc) +{ + int i, n = (int) strlen(cSrc); + for (i = 0; i < n; ++i) { + cDest[i] = tolower(cSrc[i]); + } + cDest[i] = '\0'; +} + +const char* CurrentTime() +{ + time_t t = time(0); + tm* pT = localtime(&t); + + char cStr[64]; + strftime(cStr, 64, "%Y%m%d %H:%M ", pT); + + char cTZ[64], tz[64]; + strftime(cTZ, 64, "%Z", pT); + int i, j, nZ = strlen(cTZ); + for (i = 0, j = 0; i < nZ; ++i) { + if (isupper(cTZ[i])) { + tz[j++] = cTZ[i]; + } + } + tz[j] = '\0'; + + static char sTimeStr[256]; + strcpy(sTimeStr, cStr); + strcat(sTimeStr, tz); + return sTimeStr; +} + +void CompileTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, WDL_String* pStr) +{ + pStr->Set("["); + pStr->Append(Mmm_dd_yyyy); + pStr->SetLen(7); + pStr->DeleteSub(4, 1); + pStr->Append(" "); + pStr->Append(hh_mm_ss); + pStr->SetLen(12); + pStr->Append("]"); +} + +const char* AppendTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, const char* cStr) +{ + static WDL_String str(cStr); + WDL_String tStr; + CompileTimestamp(Mmm_dd_yyyy, hh_mm_ss, &tStr); + str.Append(" "); + str.Append(tStr.Get()); + return str.Get(); +} + +#if defined TRACER_BUILD + + int GetOrdinalThreadID(int sysThreadID) + { + static WDL_TypedBuf sThreadIDs; + int i, n = sThreadIDs.GetSize(); + int* pThreadID = sThreadIDs.Get(); + for (i = 0; i < n; ++i, ++pThreadID) { + if (sysThreadID == *pThreadID) { + return i; + } + } + sThreadIDs.Resize(n + 1); + *(sThreadIDs.Get() + n) = sysThreadID; + return n; + } + + #define MAX_LOG_LINES 16384 + void Trace(const char* funcName, int line, const char* format, ...) + { + static int sTrace = 0; + if (sTrace++ < MAX_LOG_LINES) { + static LogFile sLogFile; + static WDL_Mutex sLogMutex; + char str[TXTLEN]; + VARARGS_TO_STR(str); + printf("[%d:%s:%d]%s", GetOrdinalThreadID(SYS_THREAD_ID), funcName, line, str); + + //WDL_MutexLock lock(&sLogMutex); + //fprintf(sLogFile.mFP, "[%d:%s:%d]%s", GetOrdinalThreadID(SYS_THREAD_ID), funcName, line, str); + //fflush(sLogFile.mFP); + } + } + + #include "../../VST_SDK/aeffectx.h" + const char* VSTOpcodeStr(int opCode) + { + switch (opCode) { + case effOpen: return "effOpen"; + case effClose: return "effClose"; + case effSetProgram: return "effSetProgram"; + case effGetProgram: return "effGetProgram"; + case effSetProgramName: return "effSetProgramName"; + case effGetProgramName: return "effGetProgramName"; + case effGetParamLabel: return "effGetParamLabel"; + case effGetParamDisplay: return "effGetParamDisplay"; + case effGetParamName: return "effGetParamName"; + case __effGetVuDeprecated: return "__effGetVuDeprecated"; + case effSetSampleRate: return "effSetSampleRate"; + case effSetBlockSize: return "effSetBlockSize"; + case effMainsChanged: return "effMainsChanged"; + case effEditGetRect: return "effEditGetRect"; + case effEditOpen: return "effEditOpen"; + case effEditClose: return "effEditClose"; + case __effEditDrawDeprecated: return "__effEditDrawDeprecated"; + case __effEditMouseDeprecated: return "__effEditMouseDeprecated"; + case __effEditKeyDeprecated: return "__effEditKeyDeprecated"; + case effEditIdle: return "effEditIdle"; + case __effEditTopDeprecated: return "__effEditTopDeprecated"; + case __effEditSleepDeprecated: return "__effEditSleepDeprecated"; + case __effIdentifyDeprecated: return "__effIdentifyDeprecated"; + case effGetChunk: return "effGetChunk"; + case effSetChunk: return "effSetChunk"; + case effProcessEvents: return "effProcessEvents"; + case effCanBeAutomated: return "effCanBeAutomated"; + case effString2Parameter: return "effString2Parameter"; + case __effGetNumProgramCategoriesDeprecated: return "__effGetNumProgramCategoriesDeprecated"; + case effGetProgramNameIndexed: return "effGetProgramNameIndexed"; + case __effCopyProgramDeprecated: return "__effCopyProgramDeprecated"; + case __effConnectInputDeprecated: return "__effConnectInputDeprecated"; + case __effConnectOutputDeprecated: return "__effConnectOutputDeprecated"; + case effGetInputProperties: return "effGetInputProperties"; + case effGetOutputProperties: return "effGetOutputProperties"; + case effGetPlugCategory: return "effGetPlugCategory"; + case __effGetCurrentPositionDeprecated: return "__effGetCurrentPositionDeprecated"; + case __effGetDestinationBufferDeprecated: return "__effGetDestinationBufferDeprecated"; + case effOfflineNotify: return "effOfflineNotify"; + case effOfflinePrepare: return "effOfflinePrepare"; + case effOfflineRun: return "effOfflineRun"; + case effProcessVarIo: return "effProcessVarIo"; + case effSetSpeakerArrangement: return "effSetSpeakerArrangement"; + case __effSetBlockSizeAndSampleRateDeprecated: return "__effSetBlockSizeAndSampleRateDeprecated"; + case effSetBypass: return "effSetBypass"; + case effGetEffectName: return "effGetEffectName"; + case __effGetErrorTextDeprecated: return "__effGetErrorTextDeprecated"; + case effGetVendorString: return "effGetVendorString"; + case effGetProductString: return "effGetProductString"; + case effGetVendorVersion: return "effGetVendorVersion"; + case effVendorSpecific: return "effVendorSpecific"; + case effCanDo: return "effCanDo"; + case effGetTailSize: return "effGetTailSize"; + case __effIdleDeprecated: return "__effIdleDeprecated"; + case __effGetIconDeprecated: return "__effGetIconDeprecated"; + case __effSetViewPositionDeprecated: return "__effSetViewPositionDeprecated"; + case effGetParameterProperties: return "effGetParameterProperties"; + case __effKeysRequiredDeprecated: return "__effKeysRequiredDeprecated"; + case effGetVstVersion: return "effGetVstVersion"; + case effEditKeyDown: return "effEditKeyDown"; + case effEditKeyUp: return "effEditKeyUp"; + case effSetEditKnobMode: return "effSetEditKnobMode"; + case effGetMidiProgramName: return "effGetMidiProgramName"; + case effGetCurrentMidiProgram: return "effGetCurrentMidiProgram"; + case effGetMidiProgramCategory: return "effGetMidiProgramCategory"; + case effHasMidiProgramsChanged: return "effHasMidiProgramsChanged"; + case effGetMidiKeyName: return "effGetMidiKeyName"; + case effBeginSetProgram: return "effBeginSetProgram"; + case effEndSetProgram: return "effEndSetProgram"; + case effGetSpeakerArrangement: return "effGetSpeakerArrangement"; + case effShellGetNextPlugin: return "effShellGetNextPlugin"; + case effStartProcess: return "effStartProcess"; + case effStopProcess: return "effStopProcess"; + case effSetTotalSampleToProcess: return "effSetTotalSampleToProcess"; + case effSetPanLaw: return "effSetPanLaw"; + case effBeginLoadBank: return "effBeginLoadBank"; + case effBeginLoadProgram: return "effBeginLoadProgram"; + case effSetProcessPrecision: return "effSetProcessPrecision"; + case effGetNumMidiInputChannels: return "effGetNumMidiInputChannels"; + case effGetNumMidiOutputChannels: return "effGetNumMidiOutputChannels"; + default: return "unknown"; + } + } + #if defined __APPLE__ + #include + #include + const char* AUSelectStr(int select) + { + switch (select) { + case kComponentOpenSelect: return "kComponentOpenSelect"; + case kComponentCloseSelect: return "kComponentCloseSelect"; + case kComponentVersionSelect: return "kComponentVersionSelect"; + case kAudioUnitInitializeSelect: return "kAudioUnitInitializeSelect"; + case kAudioUnitUninitializeSelect: return "kAudioUnitUninitializeSelect"; + case kAudioUnitGetPropertyInfoSelect: return "kAudioUnitGetPropertyInfoSelect"; + case kAudioUnitGetPropertySelect: return "kAudioUnitGetPropertySelect"; + case kAudioUnitSetPropertySelect: return "kAudioUnitSetPropertySelect"; + case kAudioUnitAddPropertyListenerSelect: return "kAudioUnitAddPropertyListenerSelect"; + case kAudioUnitRemovePropertyListenerSelect: return "kAudioUnitRemovePropertyListenerSelect"; + case kAudioUnitAddRenderNotifySelect: return "kAudioUnitAddRenderNotifySelect"; + case kAudioUnitRemoveRenderNotifySelect: return "kAudioUnitRemoveRenderNotifySelect"; + case kAudioUnitGetParameterSelect: return "kAudioUnitGetParameterSelect"; + case kAudioUnitSetParameterSelect: return "kAudioUnitSetParameterSelect"; + case kAudioUnitScheduleParametersSelect: return "kAudioUnitScheduleParametersSelect"; + case kAudioUnitRenderSelect: return "kAudioUnitRenderSelect"; + case kAudioUnitResetSelect: return "kAudioUnitResetSelect"; + case kComponentCanDoSelect: return "kComponentCanDoSelect"; + case kAudioUnitCarbonViewRange: return "kAudioUnitCarbonViewRange"; + case kAudioUnitCarbonViewCreateSelect: return "kAudioUnitCarbonViewCreateSelect"; + case kAudioUnitCarbonViewSetEventListenerSelect: return "kAudioUnitCarbonViewSetEventListenerSelect"; + default: return "unknown"; + } + } + const char* AUPropertyStr(int propID) + { + switch (propID) { + case kAudioUnitProperty_ClassInfo: return "kAudioUnitProperty_ClassInfo"; + case kAudioUnitProperty_MakeConnection: return "kAudioUnitProperty_MakeConnection"; + case kAudioUnitProperty_SampleRate: return "kAudioUnitProperty_SampleRate"; + case kAudioUnitProperty_ParameterList: return "kAudioUnitProperty_ParameterList"; + case kAudioUnitProperty_ParameterInfo: return "kAudioUnitProperty_ParameterInfo"; + case kAudioUnitProperty_FastDispatch: return "kAudioUnitProperty_FastDispatch"; + case kAudioUnitProperty_CPULoad: return "kAudioUnitProperty_CPULoad"; + case kAudioUnitProperty_StreamFormat: return "kAudioUnitProperty_StreamFormat"; + case kAudioUnitProperty_ElementCount: return "kAudioUnitProperty_ElementCount"; + case kAudioUnitProperty_Latency: return "kAudioUnitProperty_Latency"; + case kAudioUnitProperty_SupportedNumChannels: return "kAudioUnitProperty_SupportedNumChannels"; + case kAudioUnitProperty_MaximumFramesPerSlice: return "kAudioUnitProperty_MaximumFramesPerSlice"; + case kAudioUnitProperty_SetExternalBuffer: return "kAudioUnitProperty_SetExternalBuffer"; + case kAudioUnitProperty_ParameterValueStrings: return "kAudioUnitProperty_ParameterValueStrings"; + case kAudioUnitProperty_GetUIComponentList: return "kAudioUnitProperty_GetUIComponentList"; + case kAudioUnitProperty_AudioChannelLayout: return "kAudioUnitProperty_AudioChannelLayout"; + case kAudioUnitProperty_TailTime: return "kAudioUnitProperty_TailTime"; + case kAudioUnitProperty_BypassEffect: return "kAudioUnitProperty_BypassEffect"; + case kAudioUnitProperty_LastRenderError: return "kAudioUnitProperty_LastRenderError"; + case kAudioUnitProperty_SetRenderCallback: return "kAudioUnitProperty_SetRenderCallback"; + case kAudioUnitProperty_FactoryPresets: return "kAudioUnitProperty_FactoryPresets"; + case kAudioUnitProperty_ContextName: return "kAudioUnitProperty_ContextName"; + case kAudioUnitProperty_RenderQuality: return "kAudioUnitProperty_RenderQuality"; + case kAudioUnitProperty_HostCallbacks: return "kAudioUnitProperty_HostCallbacks"; + case kAudioUnitProperty_CurrentPreset: return "kAudioUnitProperty_CurrentPreset"; + case kAudioUnitProperty_InPlaceProcessing: return "kAudioUnitProperty_InPlaceProcessing"; + case kAudioUnitProperty_ElementName: return "kAudioUnitProperty_ElementName"; + case kAudioUnitProperty_CocoaUI: return "kAudioUnitProperty_CocoaUI"; + case kAudioUnitProperty_SupportedChannelLayoutTags: return "kAudioUnitProperty_SupportedChannelLayoutTags"; + case kAudioUnitProperty_ParameterIDName: return "kAudioUnitProperty_ParameterIDName"; + case kAudioUnitProperty_ParameterClumpName: return "kAudioUnitProperty_ParameterClumpName"; + case kAudioUnitProperty_PresentPreset: return "kAudioUnitProperty_PresentPreset"; + case kAudioUnitProperty_OfflineRender: return "kAudioUnitProperty_OfflineRender"; + case kAudioUnitProperty_ParameterStringFromValue: return "kAudioUnitProperty_ParameterStringFromValue"; + case kAudioUnitProperty_ParameterValueFromString: return "kAudioUnitProperty_ParameterValueFromString"; + case kAudioUnitProperty_IconLocation: return "kAudioUnitProperty_IconLocation"; + case kAudioUnitProperty_PresentationLatency: return "kAudioUnitProperty_PresentationLatency"; + case kAudioUnitProperty_DependentParameters: return "kAudioUnitProperty_DependentParameters"; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + case kAudioUnitProperty_AUHostIdentifier: return "kAudioUnitProperty_AUHostIdentifier"; + case kAudioUnitProperty_MIDIOutputCallbackInfo: return "kAudioUnitProperty_MIDIOutputCallbackInfo"; + case kAudioUnitProperty_MIDIOutputCallback: return "kAudioUnitProperty_MIDIOutputCallback"; + case kAudioUnitProperty_InputSamplesInOutput: return "kAudioUnitProperty_InputSamplesInOutput"; + case kAudioUnitProperty_ClassInfoFromDocument: return "kAudioUnitProperty_ClassInfoFromDocument"; + #endif + default: return "unknown"; + } + } + const char* AUScopeStr(int scope) + { + switch (scope) { + case kAudioUnitScope_Global: return "kAudioUnitScope_Global"; + case kAudioUnitScope_Input: return "kAudioUnitScope_Input"; + case kAudioUnitScope_Output: return "kAudioUnitScope_Output"; + case kAudioUnitScope_Group: return "kAudioUnitScope_Group"; + case kAudioUnitScope_Part: return "kAudioUnitScope_Part"; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + case kAudioUnitScope_Note: return "kAudioUnitScope_Note"; + #endif + default: return "unknown"; + } + } + #endif // __APPLE__ +#else + void Trace(const char* funcName, int line, const char* format, ...) {} + const char* VSTOpcodeStr(int opCode) { return ""; } + const char* AUSelectStr(int select) { return ""; } + const char* AUPropertyStr(int propID) { return ""; } + const char* AUScopeStr(int scope) { return ""; } +#endif // TRACER_BUILD \ No newline at end of file diff --git a/WDL/IPlug/Log.h b/WDL/IPlug/Log.h new file mode 100644 index 00000000..b1a34513 --- /dev/null +++ b/WDL/IPlug/Log.h @@ -0,0 +1,56 @@ +#ifndef _LOG_ +#define _LOG_ + +#include "stdarg.h" +#include "Containers.h" + +#if defined _WIN32 + #define SYS_THREAD_ID (int) GetCurrentThreadId() +#elif defined __APPLE__ + #define SYS_THREAD_ID (int) pthread_self() +#else + #error "No OS defined!" +#endif + +#if defined TRACER_BUILD + #define TRACE Trace(TRACELOC, ""); +#else + #define TRACE +#endif + +#define TRACELOC __FUNCTION__,__LINE__ +void Trace(const char* funcName, int line, const char* fmtStr, ...); + +// To trace some arbitrary data: Trace(TRACELOC, "%s:%d", myStr, myInt); +// To simply create a trace entry in the log: TRACE; +// No need to wrap tracer calls in #ifdef TRACER_BUILD because Trace is a no-op unless TRACER_BUILD is defined. + +const char* VSTOpcodeStr(int opCode); +const char* AUSelectStr(int select); +const char* AUPropertyStr(int propID); +const char* AUScopeStr(int scope); + +struct Timer +{ + int mT; + Timer(); + + // Returns true every sec seconds. + bool Every(double sec); +}; + +// Not yet ported to WDL. +// Snarf the whole file into a StrVector. +//StrVector ReadFileIntoStr(WDL_String* pFileName); +//int WriteBufferToFile(const DBuffer& buf, WDL_String* pFileName); +// Split line into fields. Whitespace is treated as contiguous. +//StrVector SplitStr(WDL_String* pFileName, char separator = ' '); +void ToLower(char* cDest, const char* cSrc); + +const char* CurrentTime(); +void CompileTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, WDL_String* pStr); +const char* AppendTimestamp(const char* Mmm_dd_yyyy, const char* hh_mm_ss, const char* cStr); +#define APPEND_TIMESTAMP(str) AppendTimestamp(__DATE__, __TIME__, str) + +#endif + diff --git a/WDL/IPlug/README.txt b/WDL/IPlug/README.txt new file mode 100644 index 00000000..3a49dbaa --- /dev/null +++ b/WDL/IPlug/README.txt @@ -0,0 +1,4 @@ +IPlug version 20070607 + +The image files in this package were created by White Tie. You may not use these images as part of any product that is offered for sale. + diff --git a/WDL/IPlug/VSTHosts.cpp b/WDL/IPlug/VSTHosts.cpp new file mode 100644 index 00000000..33e2dbca --- /dev/null +++ b/WDL/IPlug/VSTHosts.cpp @@ -0,0 +1,55 @@ +#include "VSTHosts.h" +#include + +void ToLower(char* cStr) +{ + int i, n = (int) strlen(cStr); + for (i = 0; i < n; ++i) { + cStr[i] = tolower(cStr[i]); + } +} + +EVSTHost LookUpHost(char* vendorStr, char* productStr, int version) +{ + ToLower(vendorStr); + ToLower(productStr); + + // Cockos:REAPER:1990 + if (strstr(productStr, "reaper")) { + return kHostReaper; + } + // Steinberg:Cubase VST:8200 ... C4 = (version >= 8200) + if (strstr(productStr, "cubase")) { + return kHostCubase; + } + // Steinberg:Nuendo:2200 + if (strstr(productStr, "nuendo")) { + return kHostNuendo; + } + // Twelve Tone Systems:Cakewalk VST Wizard 4.5:4 + if (strstr(productStr, "cakewalk")) { + return kHostSonar; + } + // MAGIX:Samplitude:9001 + if (strstr(productStr, "samplitude")) { + return kHostSamplitude; + } + // Image-Line:Fruity Wrapper:6400 + if (strstr(productStr, "fruity")) { + return kHostFL; + } + // Ableton:Live:5020 + if (strstr(vendorStr, "ableton") && strstr(productStr, "live")) { + return kHostAbletonLive; + } + // Celemony Software GmbH:Melodyne:0 + if (strstr(productStr, "melodyne")) { + return kHostMelodyneStudio; + } + // Vincent Burel Inc:VSTMANLIB:1031 + if (strstr(productStr, "vstmanlib")) { + return kHostVSTScanner; + } + + return kHostUnknown; +} \ No newline at end of file diff --git a/WDL/IPlug/VSTHosts.h b/WDL/IPlug/VSTHosts.h new file mode 100644 index 00000000..ff777596 --- /dev/null +++ b/WDL/IPlug/VSTHosts.h @@ -0,0 +1,32 @@ +#ifndef _VSTHOSTS_ +#define _VSTHOSTS_ + +#include +#include + +enum EVSTHost { + kHostUnknown = 0, + kHostReaper, + kHostProTools, + kHostCubase, + kHostNuendo, + kHostSonar, + kHostVegas, + kHostFL, + kHostSamplitude, + kHostAbletonLive, + kHostTracktion, + kHostNTracks, + kHostMelodyneStudio, + kHostVSTScanner, + + // These hosts don't report the host name: + // MiniHost +}; + +EVSTHost LookUpHost(char* vendorStr, char* productStr, int version); + +#endif + + + \ No newline at end of file diff --git a/WDL/IPlug/lice.vcproj b/WDL/IPlug/lice.vcproj new file mode 100644 index 00000000..fa51cbe8 --- /dev/null +++ b/WDL/IPlug/lice.vcproj @@ -0,0 +1,1165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WDL/MersenneTwister.h b/WDL/MersenneTwister.h new file mode 100644 index 00000000..279cfab3 --- /dev/null +++ b/WDL/MersenneTwister.h @@ -0,0 +1,411 @@ +// Taken from http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html + + +// MersenneTwister.h +// Mersenne Twister random number generator -- a C++ class MTRand +// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com + +// The Mersenne Twister is an algorithm for generating random numbers. It +// was designed with consideration of the flaws in various other generators. +// The period, 2^19937-1, and the order of equidistribution, 623 dimensions, +// are far greater. The generator is also fast; it avoids multiplication and +// division, and it benefits from caches and pipelines. For more information +// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html + +// Reference +// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally +// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on +// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. + +// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, +// Copyright (C) 2000 - 2003, Richard J. Wagner +// 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. The names of its contributors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The original code included the following notice: +// +// When you use this, send an email to: matumoto@math.keio.ac.jp +// with an appropriate reference to your work. +// +// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu +// when you write. + +#ifndef _MERSENNETWISTER_H_ +#define _MERSENNETWISTER_H_ + +// Not thread safe (unless auto-initialization is avoided and each thread has +// its own MTRand object) + +#include +#include +#include +#include + +class MTRand { +// Data +public: + typedef unsigned int uint32; // unsigned integer type, at least 32 bits + + enum { N = 624 }; // length of state vector + enum { SAVE = N + 1 }; // length of array for save() + +protected: + enum { M = 397 }; // period parameter + + uint32 state[N]; // internal state + uint32 *pNext; // next value to get from state + int left; // number of values left before reload needed + + +//Methods +public: + MTRand( const uint32& oneSeed ); // initialize with a simple uint32 + MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array + MTRand(); // auto-initialize with /dev/urandom or time() and clock() + + // Do NOT use for CRYPTOGRAPHY without securely hashing several returned + // values together, otherwise the generator state can be learned after + // reading 624 consecutive values. + + // Access to 32-bit random numbers + double rand(); // real number in [0,1] + double rand( const double& n ); // real number in [0,n] + double randExc(); // real number in [0,1) + double randExc( const double& n ); // real number in [0,n) + double randDblExc(); // real number in (0,1) + double randDblExc( const double& n ); // real number in (0,n) + uint32 randInt(); // integer in [0,2^32-1] + uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32 + double operator()() { return rand(); } // same as rand() + + // Access to 53-bit random numbers (capacity of IEEE double precision) + double rand53(); // real number in [0,1) + + // Access to nonuniform random number distributions + double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); + + // Re-seeding functions with same behavior as initializers + void seed( const uint32 oneSeed ); + void seed( uint32 *const bigSeed, const uint32 seedLength = N ); + void seed(); + + // Saving and loading generator state + void save( uint32* saveArray ) const; // to array of size SAVE + void load( uint32 *const loadArray ); // from such array + +protected: + void initialize( const uint32 oneSeed ); + void reload(); + uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } + uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } + uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } + uint32 mixBits( const uint32& u, const uint32& v ) const + { return hiBit(u) | loBits(v); } + uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const + { return m ^ (mixBits(s0,s1)>>1) ^ (-((int)loBit(s1)) & 0x9908b0dfUL); } + +public: + // This was protected, but we need it exposed so FIRan1.h can use it for seeding + static uint32 hash( time_t t, clock_t c ); +}; + + +inline MTRand::MTRand( const uint32& oneSeed ) + { seed(oneSeed); } + +inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) + { seed(bigSeed,seedLength); } + +inline MTRand::MTRand() + { seed(); } + +inline double MTRand::rand() + { return double(randInt()) * (1.0/4294967295.0); } + +inline double MTRand::rand( const double& n ) + { return rand() * n; } + +inline double MTRand::randExc() + { return double(randInt()) * (1.0/4294967296.0); } + +inline double MTRand::randExc( const double& n ) + { return randExc() * n; } + +inline double MTRand::randDblExc() + { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } + +inline double MTRand::randDblExc( const double& n ) + { return randDblExc() * n; } + +inline double MTRand::rand53() +{ + uint32 a = randInt() >> 5, b = randInt() >> 6; + return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada +} + +inline double MTRand::randNorm( const double& mean, const double& variance ) +{ + // Return a real number from a normal (Gaussian) distribution with given + // mean and variance by Box-Muller method + double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; + double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); + return mean + r * cos(phi); +} + +inline MTRand::uint32 MTRand::randInt() +{ + // Pull a 32-bit integer from the generator state + // Every other access function simply transforms the numbers extracted here + + if( left == 0 ) reload(); + --left; + + register uint32 s1; + s1 = *pNext++; + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9d2c5680UL; + s1 ^= (s1 << 15) & 0xefc60000UL; + return ( s1 ^ (s1 >> 18) ); +} + +inline MTRand::uint32 MTRand::randInt( const uint32& n ) +{ + // Find which bits are used in n + // Optimized by Magnus Jonsson (magnus@smartelectronix.com) + uint32 used = n; + used |= used >> 1; + used |= used >> 2; + used |= used >> 4; + used |= used >> 8; + used |= used >> 16; + + // Draw numbers until one is found in [0,n] + uint32 i; + do + i = randInt() & used; // toss unused bits to shorten search + while( i > n ); + return i; +} + + +inline void MTRand::seed( const uint32 oneSeed ) +{ + // Seed the generator with a simple uint32 + initialize(oneSeed); + reload(); +} + + +inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) +{ + // Seed the generator with an array of uint32's + // There are 2^19937-1 possible initial states. This function allows + // all of those to be accessed by providing at least 19937 bits (with a + // default seed length of N = 624 uint32's). Any bits above the lower 32 + // in each element are discarded. + // Just call seed() if you want to get array from /dev/urandom + initialize(19650218UL); + register int i = 1; + register uint32 j = 0; + register int k = ( N > seedLength ? N : seedLength ); + for( ; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); + state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; + state[i] &= 0xffffffffUL; + ++i; ++j; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + if( j >= seedLength ) j = 0; + } + for( k = N - 1; k; --k ) + { + state[i] = + state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); + state[i] -= i; + state[i] &= 0xffffffffUL; + ++i; + if( i >= N ) { state[0] = state[N-1]; i = 1; } + } + state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array + reload(); +} + + +inline void MTRand::seed() +{ + // Seed the generator with an array from /dev/urandom if available + // Otherwise use a hash of time() and clock() values + + // No point in trying this on Windows machines - won't work, so it just slows things down +#ifndef WIN32 + // First try getting an array from /dev/urandom + FILE* urandom = fopen( "/dev/urandom", "rb" ); + if( urandom ) + { + uint32 bigSeed[N]; + register uint32 *s = bigSeed; + register int i = N; + register bool success = true; + while( success && i-- ) + success = fread( s++, sizeof(uint32), 1, urandom ); + fclose(urandom); + if( success ) { seed( bigSeed, N ); return; } + } +#endif + + // Was not successful, so use time() and clock() instead + seed( hash( time(NULL), clock() ) ); +} + + +inline void MTRand::initialize( const uint32 seed ) +{ + // Initialize generator state with seed + // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. + // In previous versions, most significant bits (MSBs) of the seed affect + // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. + register uint32 *s = state; + register uint32 *r = state; + register int i = 1; + *s++ = seed & 0xffffffffUL; + for( ; i < N; ++i ) + { + *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; + r++; + } +} + + +inline void MTRand::reload() +{ + // Generate N new values in state + // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) + register uint32 *p = state; + register int i; + for( i = int(N) - int(M); i--; ++p ) + *p = twist( p[M], p[0], p[1] ); + for( i = M; --i; ++p ) + *p = twist( p[int(M)-int(N)], p[0], p[1] ); + *p = twist( p[int(M)-int(N)], p[0], state[0] ); + + left = N, pNext = state; +} + + +inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) +{ + // Get a uint32 from t and c + // Better than uint32(x) in case x is floating point in [0,1] + // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) + + static uint32 differ = 0; // guarantee time-based seeds will change + + uint32 h1 = 0; + unsigned char *p = (unsigned char *) &t; + for( size_t i = 0; i < sizeof(t); ++i ) + { + h1 *= UCHAR_MAX + 2U; + h1 += p[i]; + } + uint32 h2 = 0; + p = (unsigned char *) &c; + for( size_t j = 0; j < sizeof(c); ++j ) + { + h2 *= UCHAR_MAX + 2U; + h2 += p[j]; + } + return ( h1 + differ++ ) ^ h2; +} + + +inline void MTRand::save( uint32* saveArray ) const +{ + register uint32 *sa = saveArray; + register const uint32 *s = state; + register int i = N; + for( ; i--; *sa++ = *s++ ) {} + *sa = left; +} + + +inline void MTRand::load( uint32 *const loadArray ) +{ + register uint32 *s = state; + register uint32 *la = loadArray; + register int i = N; + for( ; i--; *s++ = *la++ ) {} + left = *la; + pNext = &state[N-left]; +} + + + +#endif // MERSENNETWISTER_H + +// Change log: +// +// v0.1 - First release on 15 May 2000 +// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus +// - Translated from C to C++ +// - Made completely ANSI compliant +// - Designed convenient interface for initialization, seeding, and +// obtaining numbers in default or user-defined ranges +// - Added automatic seeding from /dev/urandom or time() and clock() +// - Provided functions for saving and loading generator state +// +// v0.2 - Fixed bug which reloaded generator one step too late +// +// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew +// +// v0.4 - Removed trailing newline in saved generator format to be consistent +// with output format of built-in types +// +// v0.5 - Improved portability by replacing static const int's with enum's and +// clarifying return values in seed(); suggested by Eric Heimburg +// - Removed MAXINT constant; use 0xffffffffUL instead +// +// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits +// - Changed integer [0,n] generator to give better uniformity +// +// v0.7 - Fixed operator precedence ambiguity in reload() +// - Added access for real numbers in (0,1) and (0,n) +// +// v0.8 - Included time.h header to properly support time_t and clock_t +// +// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto +// - Allowed for seeding with arrays of any length +// - Added access for real numbers in [0,1) with 53-bit resolution +// - Added access for real numbers from normal (Gaussian) distributions +// - Increased overall speed by optimizing twist() +// - Doubled speed of integer [0,n] generation +// - Fixed out-of-range number generation on 64-bit machines +// - Improved portability by substituting literal constants for long enum's +// - Changed license from GNU LGPL to BSD diff --git a/WDL/adpcm_decode.h b/WDL/adpcm_decode.h new file mode 100644 index 00000000..efcaf332 --- /dev/null +++ b/WDL/adpcm_decode.h @@ -0,0 +1,317 @@ +#ifndef _WDL_ADPCM_DECODE_H_ +#define _WDL_ADPCM_DECODE_H_ + +#include "queue.h" + +#define MSADPCM_TYPE 2 +#define IMAADPCM_TYPE 0x11 +#define CADPCM2_TYPE 0xac0c + +class WDL_adpcm_decoder +{ + typedef struct + { + int cf1,cf2,deltas,spl1,spl2; + } WDL_adpcm_decode_chanctx; + +public: + enum { MSADPCM_PREAMBLELEN=7, IMA_PREAMBLELEN=4 }; + static INT64 sampleLengthFromBytes(INT64 nbytes, int blockalign, int nch, int type, int bps) + { + if (!bps||type!=CADPCM2_TYPE) bps=4; + // remove overhead of headers + INT64 nblocks=((nbytes+blockalign-1)/blockalign); + + // remove preambles + if (type==IMAADPCM_TYPE||type==CADPCM2_TYPE) nbytes -= nblocks*IMA_PREAMBLELEN*nch; + else nbytes -= nblocks*MSADPCM_PREAMBLELEN*nch; + + // scale from bytes to samples + nbytes = (nbytes*8)/(nch*bps); + + if (type==IMAADPCM_TYPE||type==CADPCM2_TYPE) nbytes++; // IMA has just one initial sample + else nbytes+=2; // msadpcm has 2 initial sample values + + return nbytes; + } + + WDL_adpcm_decoder(int blockalign,int nch, int type, int bps) + { + m_bps=0; + m_type=0; + m_nch=0; + m_blockalign=0; + m_srcbuf=0; + m_chans=0; + setParameters(blockalign,nch,type,bps); + } + ~WDL_adpcm_decoder() + { + free(m_srcbuf); + free(m_chans); + } + + + void resetState() + { + if (m_chans) memset(m_chans,0,m_nch*sizeof(WDL_adpcm_decode_chanctx)); + m_srcbuf_valid=0; + samplesOut.Clear(); + samplesOut.Compact(); + } + + void setParameters(int ba, int nch, int type, int bps) + { + if (m_blockalign != ba||nch != m_nch||type!=m_type||bps != m_bps) + { + free(m_srcbuf); + free(m_chans); + m_bps=bps; + m_blockalign=ba; + m_nch=nch; + m_srcbuf_valid=0; + m_srcbuf=(unsigned char*)malloc(ba); + m_chans=(WDL_adpcm_decode_chanctx*)malloc(sizeof(WDL_adpcm_decode_chanctx)*nch); + m_type=type; + resetState(); + } + } + + int blockAlign() { return m_blockalign; } + + int samplesPerBlock() + { + if (m_type==IMAADPCM_TYPE||m_type==CADPCM2_TYPE) + { + if (m_bps == 2) return (m_blockalign/m_nch - IMA_PREAMBLELEN)*4 + 1; + return (m_blockalign/m_nch - IMA_PREAMBLELEN)*2 + 1; //4 bit + } + return (m_blockalign/m_nch - MSADPCM_PREAMBLELEN)*2 + 2; // 4 bit + } + + INT64 samplesToSourceBytes(INT64 outlen_samples) // length in samplepairs + { + outlen_samples -= samplesOut.Available()/m_nch; + if (outlen_samples<1) return 0; // no data required + + int spls_block = samplesPerBlock(); + if (spls_block<1) return 0; + INT64 nblocks = (outlen_samples+spls_block-1)/spls_block; + INT64 v=nblocks * m_blockalign; + + v -= m_srcbuf_valid; + + return max(v,0); + } + + void AddInput(void *buf, int len, short *parm_cotab=NULL) + { + unsigned char *rdbuf = (unsigned char *)buf; + if (m_srcbuf_valid) + { + int v=min(len,m_blockalign-m_srcbuf_valid); + memcpy(m_srcbuf+m_srcbuf_valid,rdbuf,v); + len-=v; + rdbuf+=v; + if ((m_srcbuf_valid+=v)>=m_blockalign) + { + DecodeBlock(m_srcbuf,parm_cotab); + m_srcbuf_valid=0; + } + } + + while (len >= m_blockalign) + { + DecodeBlock(rdbuf,parm_cotab); + rdbuf+=m_blockalign; + len-=m_blockalign; + } + if (len>0) memcpy(m_srcbuf,rdbuf,m_srcbuf_valid=len); + } + + + int sourceBytesQueued() { return m_srcbuf_valid; } + WDL_TypedQueue samplesOut; + +private: + static int getwordsigned(unsigned char **rdptr) + { + int s = (*rdptr)[0] + ((*rdptr)[1]<<8); + (*rdptr)+=2; + if (s & 0x8000) s -= 0x10000; + return s; + } + + bool DecodeBlockIMA(unsigned char *buf) + { + int samples_block = samplesPerBlock(); + + int nch=m_nch; + int ch; + short *outptr = samplesOut.Add(NULL,samples_block * nch); + + for (ch=0;ch>2; break; + default: nib=lastbyte>>4; bstate=0; break; + } + nib &= 8|4; + } + else + { + if ((bstate^=1)) nib=(lastbyte=*buf++)&0xf; + else nib=lastbyte>>4; + } + + int step_index=m_chans[ch].cf1; + if (step_index<0)step_index=0; + else if (step_index>88)step_index=88; + + int step=step_table[step_index]; + + int diff = ((nib&7)*step)/4 + step/8; + + int v=m_chans[ch].spl1 + ((nib&8) ? -diff : diff); + + if (v<-32768)v=-32768; + else if (v>32767)v=32767; + + outptr[wrpos]=(short)v; + wrpos+=nch; + + m_chans[ch].spl1=v; + + m_chans[ch].cf1=step_index + index_table[nib&7]; + + + // advance channelcounts + if (++cnt==chunksize) + { + if (++ch>=nch) + { + ch=0; + outptr += chunksize*nch; + } + wrpos = ch; + cnt=0; + } + } + + return true; + } + + bool DecodeBlock(unsigned char *buf, short *parm_cotab=NULL) + { + if (m_type==IMAADPCM_TYPE||m_type==CADPCM2_TYPE) return DecodeBlockIMA(buf); + static short cotab[14] = { 256,0, 512,-256, 0,0, 192,64, 240, 0,460, -208, 392, -232 }; + static short adtab[16] = { 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 }; + + short *use_cotab = parm_cotab ? parm_cotab : cotab; + int nch = m_nch; + int ch; + for(ch=0;ch 6) return false; + c*=2; + m_chans[ch].cf1 = use_cotab[c]; + m_chans[ch].cf2 = use_cotab[c+1]; + } + for(ch=0;ch>4; + else nib=lastbyte&0xf; + + int sn=nib; + if (sn & 8) sn -= 16; + + int pred = ( ((m_chans[ch].spl1 * m_chans[ch].cf1) + + (m_chans[ch].spl2 * m_chans[ch].cf2)) / 256) + + (sn * m_chans[ch].deltas); + + m_chans[ch].spl2 = m_chans[ch].spl1; + + if (pred < -32768) pred=-32768; + else if (pred > 32767) pred=32767; + + *outptr++ = m_chans[ch].spl1 = pred; + + int i= (adtab[nib] * m_chans[ch].deltas) / 256; + if (i <= 16) m_chans[ch].deltas=16; + else m_chans[ch].deltas = i; + } + } + return true; + } + + WDL_adpcm_decode_chanctx *m_chans; + unsigned char *m_srcbuf; + int m_srcbuf_valid; + + int m_blockalign,m_nch,m_type,m_bps; + + +}; + + +#endif \ No newline at end of file diff --git a/WDL/adpcm_encode.h b/WDL/adpcm_encode.h new file mode 100644 index 00000000..558dc192 --- /dev/null +++ b/WDL/adpcm_encode.h @@ -0,0 +1,137 @@ +#ifndef _WDL_ADPCM_ENCODE_H_ +#define _WDL_ADPCM_ENCODE_H_ + + +#include "pcmfmtcvt.h" + +void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps, + unsigned char *bufout, int *bufout_used, short **predState); + +#define WDL_adpcm_encode_IMA_samplesneededbytes(bytes,bps) ((((bytes)-4)*8)/(bps)+1) + + +// untested. also probably slow. +#ifdef WDL_ADPCM_ENCODE_IMPL + + +static signed char ima_adpcm_index_table[8] = { -1, -1, -1, -1, 2, 4, 6, 8, }; +static short ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +static char calcBestNibble(int *initial_step_index, int lastSpl, int thisSpl, short *lastsplout, int bps) +{ + + int step=ima_adpcm_step_table[*initial_step_index]; + + char sign=0; + int adiff = thisSpl - lastSpl; + if (adiff<0) { adiff=-adiff; sign=8; } + + // adiff == (nib*step)/4 + step/8 + // adiff - step/8 = nib*step/4 + // nib = 4*(adiff-step/8)/step = 4*adiff/step - 0.5 + int nib = step ? ((4 * adiff - step/2) / step) : 0; + if (nib<0) nib=0; + else if(nib>7) nib=7; + + if (bps==2) nib&=4; + + int diff = (nib*step)/4 + step/8; + *lastsplout = lastSpl + (sign?-diff:diff); + + + *initial_step_index += ima_adpcm_index_table[nib]; + + if (*initial_step_index<0)*initial_step_index=0; + else if (*initial_step_index>88)*initial_step_index=88; + + return (char)nib|sign; +} + + + +void WDL_adpcm_encode_IMA(PCMFMTCVT_DBL_TYPE *samples, int numsamples, int nch, int bps, + unsigned char *bufout, int *bufout_used, short **predState) +{ + int x; + if (!*predState) *predState=(short *)calloc(nch,sizeof(short)); + + short *pstate = *predState; + for(x=0;x>8; + spl+=nch; + + *wrptr++ = step_index&0xff; *wrptr++ = step_index>>8; + + wrptr += (nch-1)*4; + + + int outpos=0; + const int outblocklen = bps == 2 ? 16 : 8; + unsigned char buildchar=0; + + while (left-->0) + { + short this_spl; + double_TO_INT16(this_spl,*spl); + char nib = calcBestNibble(&step_index,last_out,this_spl,&last_out,bps); + + spl+=nch; + + // update output + if (bps == 2) + { + nib>>=2; + switch (outpos&3) + { + case 0: buildchar = nib; break; + case 1: buildchar |= nib<<2; break; + case 2: buildchar |= nib<<4; break; + case 3: *wrptr++ = buildchar | (nib<<6); break; + } + } + else + { + if (!(outpos&1)) buildchar = nib; + else *wrptr++ = buildchar | (nib<<4); + } + + // skip other channels + if (++outpos == outblocklen) + { + wrptr += ((nch-1)*outblocklen*bps)/8; + outpos=0; + } + } + pstate[x] = step_index; + + } + *bufout_used = (((numsamples-1)*bps)/8 + 4)*nch; + + +} + +#endif + + +#endif//_WDL_ADPCM_ENCODE_H_ \ No newline at end of file diff --git a/WDL/assocarray.h b/WDL/assocarray.h new file mode 100644 index 00000000..4406e732 --- /dev/null +++ b/WDL/assocarray.h @@ -0,0 +1,317 @@ +#ifndef _WDL_ASSOCARRAY_H_ +#define _WDL_ASSOCARRAY_H_ + +#include "heapbuf.h" + + +// on all of these, if valdispose is set, the array will dispose of values as needed. +// if keydup/keydispose are set, copies of (any) key data will be made/destroyed as necessary + + +// WDL_AssocArrayImpl can be used on its own, and can contain structs for keys or values +template class WDL_AssocArrayImpl +{ +public: + + explicit WDL_AssocArrayImpl(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) + { + m_keycmp = keycmp; + m_keydup = keydup; + m_keydispose = keydispose; + m_valdispose = valdispose; + } + + ~WDL_AssocArrayImpl() + { + DeleteAll(); + } + + VAL* GetPtr(KEY key, KEY *keyPtrOut=NULL) const + { + bool ismatch = false; + int i = LowerBound(key, &ismatch); + if (ismatch) + { + KeyVal* kv = m_data.Get()+i; + if (keyPtrOut) *keyPtrOut = kv->key; + return &(kv->val); + } + return 0; + } + + bool Exists(KEY key) const + { + bool ismatch = false; + LowerBound(key, &ismatch); + return ismatch; + } + + void Insert(KEY key, VAL val, KEY *keyPtrOut=NULL) + { + bool ismatch = false; + int i = LowerBound(key, &ismatch); + if (ismatch) + { + KeyVal* kv = m_data.Get()+i; + if (m_valdispose) m_valdispose(kv->val); + kv->val = val; + if (keyPtrOut) *keyPtrOut = kv->key; + } + else + { + KeyVal* kv = m_data.Resize(m_data.GetSize()+1)+i; + memmove(kv+1, kv, (m_data.GetSize()-i-1)*sizeof(KeyVal)); + if (m_keydup) key = m_keydup(key); + kv->key = key; + kv->val = val; + if (keyPtrOut) *keyPtrOut = key; + } + } + + void Delete(KEY key) + { + bool ismatch = false; + int i = LowerBound(key, &ismatch); + if (ismatch) + { + KeyVal* kv = m_data.Get()+i; + if (m_keydispose) m_keydispose(kv->key); + if (m_valdispose) m_valdispose(kv->val); + memmove(kv, kv+1, (m_data.GetSize()-i-1)*sizeof(KeyVal)); + m_data.Resize(m_data.GetSize()-1); + } + } + + void DeleteByIndex(int idx) + { + if (idx>=0&&idxkey); + if (m_valdispose) m_valdispose(kv->val); + memmove(kv, kv+1, (m_data.GetSize()-idx-1)*sizeof(KeyVal)); + m_data.Resize(m_data.GetSize()-1); + } + } + + void DeleteAll(bool resizedown=false) + { + if (m_keydispose || m_valdispose) + { + int i; + for (i = 0; i < m_data.GetSize(); ++i) + { + KeyVal* kv = m_data.Get()+i; + if (m_keydispose) m_keydispose(kv->key); + if (m_valdispose) m_valdispose(kv->val); + } + } + m_data.Resize(0, resizedown); + } + + int GetSize() const + { + return m_data.GetSize(); + } + + VAL* EnumeratePtr(int i, KEY* key=0) const + { + if (i >= 0 && i < m_data.GetSize()) + { + KeyVal* kv = m_data.Get()+i; + if (key) *key = kv->key; + return &(kv->val); + } + return 0; + } + + KEY* ReverseLookupPtr(VAL val) const + { + int i; + for (i = 0; i < m_data.GetSize(); ++i) + { + KeyVal* kv = m_data.Get()+i; + if (kv->val == val) return &kv->key; + } + return 0; + } + + void ChangeKey(KEY oldkey, KEY newkey) + { + bool ismatch=false; + int i = LowerBound(oldkey, &ismatch); + if (ismatch) + { + KeyVal* kv = m_data.Get()+i; + if (m_keydispose) m_keydispose(kv->key); + if (m_keydup) newkey = m_keydup(newkey); + kv->key = newkey; + Resort(); + } + } + + // fast add-block mode + void AddUnsorted(KEY key, VAL val) + { + int i=m_data.GetSize(); + KeyVal* kv = m_data.Resize(i+1)+i; + if (m_keydup) key = m_keydup(key); + kv->key = key; + kv->val = val; + } + + void Resort() + { + if (m_data.GetSize() > 1 && m_keycmp) + { + qsort(m_data.Get(),m_data.GetSize(),sizeof(KeyVal),(int(*)(const void *,const void *))m_keycmp); + + // AddUnsorted can add duplicate keys + // unfortunately qsort is not guaranteed to preserve order, + // ideally this filter would always preserve the last-added key + int i; + for (i=0; i < m_data.GetSize()-1; ++i) + { + KeyVal* kv=m_data.Get()+i; + KeyVal* nv=kv+1; + if (!m_keycmp(&kv->key, &nv->key)) + { + DeleteByIndex(i--); + } + } + } + } + + int LowerBound(KEY key, bool* ismatch) const + { + int a = 0; + int c = m_data.GetSize(); + while (a != c) + { + int b = (a+c)/2; + KeyVal* kv=m_data.Get()+b; + int cmp = m_keycmp(&key, &kv->key); + if (cmp > 0) a = b+1; + else if (cmp < 0) c = b; + else + { + *ismatch = true; + return b; + } + } + *ismatch = false; + return a; + } + + int GetIdx(KEY key) const + { + bool ismatch=false; + int i = LowerBound(key, &ismatch); + if (ismatch) return i; + return -1; + } + + void SetGranul(int gran) + { + m_data.SetGranul(gran); + } + +private: + + struct KeyVal + { + KEY key; + VAL val; + }; + WDL_TypedBuf m_data; + + int (*m_keycmp)(KEY *k1, KEY *k2); + KEY (*m_keydup)(KEY); + void (*m_keydispose)(KEY); + void (*m_valdispose)(VAL); + +}; + + +// WDL_AssocArray adds useful functions but cannot contain structs for keys or values +template class WDL_AssocArray : public WDL_AssocArrayImpl +{ +public: + + explicit WDL_AssocArray(int (*keycmp)(KEY *k1, KEY *k2), KEY (*keydup)(KEY)=0, void (*keydispose)(KEY)=0, void (*valdispose)(VAL)=0) + : WDL_AssocArrayImpl(keycmp, keydup, keydispose, valdispose) + { + } + + VAL Get(KEY key, VAL notfound=0) const + { + VAL* p = this->GetPtr(key); + if (p) return *p; + return notfound; + } + + VAL Enumerate(int i, KEY* key=0, VAL notfound=0) const + { + VAL* p = this->EnumeratePtr(i, key); + if (p) return *p; + return notfound; + } + + KEY ReverseLookup(VAL val, KEY notfound=0) const + { + KEY* p=this->ReverseLookupPtr(val); + if (p) return *p; + return notfound; + } +}; + + +template class WDL_IntKeyedArray : public WDL_AssocArray +{ +public: + + explicit WDL_IntKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpint, NULL, NULL, valdispose) {} + ~WDL_IntKeyedArray() {} + +private: + + static int cmpint(int *i1, int *i2) { return *i1-*i2; } +}; + + +template class WDL_StringKeyedArray : public WDL_AssocArray +{ +public: + + explicit WDL_StringKeyedArray(bool caseSensitive=true, void (*valdispose)(VAL)=0) : WDL_AssocArray(caseSensitive?cmpstr:cmpistr, dupstr, freestr, valdispose) {} + + ~WDL_StringKeyedArray() { } + +private: + + static const char *dupstr(const char *s) { return strdup(s); } // these might not be necessary but depending on the libc maybe... + static int cmpstr(const char **s1, const char **s2) { return strcmp(*s1, *s2); } + static int cmpistr(const char **a, const char **b) { return stricmp(*a,*b); } + static void freestr(const char* s) { free((void*)s); } + +public: + static void freecharptr(char *p) { free(p); } +}; + + +template class WDL_PtrKeyedArray : public WDL_AssocArray +{ +public: + + explicit WDL_PtrKeyedArray(void (*valdispose)(VAL)=0) : WDL_AssocArray(cmpptr, 0, 0, valdispose) {} + + ~WDL_PtrKeyedArray() {} + +private: + + static int cmpptr(INT_PTR* a, INT_PTR* b) { return *a-*b; } +}; + + +#endif + diff --git a/WDL/audiobuffercontainer.cpp b/WDL/audiobuffercontainer.cpp new file mode 100644 index 00000000..c7406dde --- /dev/null +++ b/WDL/audiobuffercontainer.cpp @@ -0,0 +1,495 @@ +#include "audiobuffercontainer.h" +#include "queue.h" +#include + +void ChannelPinMapper::SetNPins(int nPins) +{ + if (nPins<0) nPins=0; + else if (nPins>CHANNELPINMAPPER_MAXPINS) nPins=CHANNELPINMAPPER_MAXPINS; + int i; + for (i = m_nPins; i < nPins; ++i) { + ClearPin(i); + if (i < m_nCh) { + SetPin(i, i, true); + } + } + m_nPins = nPins; +} + +void ChannelPinMapper::SetNChannels(int nCh) +{ + int i; + for (i = m_nCh; i < nCh && i < m_nPins; ++i) { + SetPin(i, i, true); + } + m_nCh = nCh; +} + +void ChannelPinMapper::Init(WDL_UINT64* pMapping, int nPins) +{ + if (nPins<0) nPins=0; + else if (nPins>CHANNELPINMAPPER_MAXPINS) nPins=CHANNELPINMAPPER_MAXPINS; + memcpy(m_mapping, pMapping, nPins*sizeof(WDL_UINT64)); + m_nPins = m_nCh = nPins; +} + +#define BITMASK64(bitIdx) (((WDL_UINT64)1)<<(bitIdx)) + +void ChannelPinMapper::ClearPin(int pinIdx) +{ + if (pinIdx >=0 && pinIdx < CHANNELPINMAPPER_MAXPINS) m_mapping[pinIdx] = 0; +} + +void ChannelPinMapper::SetPin(int pinIdx, int chIdx, bool on) +{ + if (pinIdx >=0 && pinIdx < CHANNELPINMAPPER_MAXPINS) + { + if (on) + { + m_mapping[pinIdx] |= BITMASK64(chIdx); + } + else + { + m_mapping[pinIdx] &= ~BITMASK64(chIdx); + } + } +} + +bool ChannelPinMapper::TogglePin(int pinIdx, int chIdx) +{ + bool on = GetPin(pinIdx, chIdx); + on = !on; + SetPin(pinIdx, chIdx, on); + return on; +} + +bool ChannelPinMapper::GetPin(int pinIdx, int chIdx) +{ + if (pinIdx >= 0 && pinIdx < CHANNELPINMAPPER_MAXPINS) + { + WDL_UINT64 map = m_mapping[pinIdx]; + return !!(map & BITMASK64(chIdx)); + } + return false; +} + +bool ChannelPinMapper::PinHasMoreMappings(int pinIdx, int chIdx) +{ + if (pinIdx >= 0 && pinIdx < CHANNELPINMAPPER_MAXPINS) + { + WDL_UINT64 map = m_mapping[pinIdx]; + return (chIdx < 63 && map >= BITMASK64(chIdx+1)); + } + return false; +} + +bool ChannelPinMapper::IsStraightPassthrough() +{ + if (m_nCh != m_nPins) return false; + WDL_UINT64* pMap = m_mapping; + int i; + for (i = 0; i < m_nPins; ++i, ++pMap) { + if (*pMap != BITMASK64(i)) return false; + } + return true; +} + +#define PINMAPPER_MAGIC 1000 + +// return is on the heap +char* ChannelPinMapper::SaveStateNew(int* pLen) +{ + m_cfgret.Clear(); + int magic = PINMAPPER_MAGIC; + WDL_Queue__AddToLE(&m_cfgret, &magic); + WDL_Queue__AddToLE(&m_cfgret, &m_nCh); + WDL_Queue__AddToLE(&m_cfgret, &m_nPins); + WDL_Queue__AddDataToLE(&m_cfgret, m_mapping, m_nPins*sizeof(WDL_UINT64), sizeof(WDL_UINT64)); + *pLen = m_cfgret.GetSize(); + return (char*)m_cfgret.Get(); +} + +bool ChannelPinMapper::LoadState(char* buf, int len) +{ + WDL_Queue chunk; + chunk.Add(buf, len); + int* pMagic = WDL_Queue__GetTFromLE(&chunk, (int*)0); + if (!pMagic || *pMagic != PINMAPPER_MAGIC) return false; + int* pNCh = WDL_Queue__GetTFromLE(&chunk, (int*) 0); + int* pNPins = WDL_Queue__GetTFromLE(&chunk, (int*) 0); + if (!pNCh || !pNPins || !(*pNCh) || !(*pNPins)) return false; + SetNPins(*pNCh); + SetNChannels(*pNCh); + int maplen = *pNPins*sizeof(WDL_UINT64); + if (chunk.Available() < maplen) return false; + void* pMap = WDL_Queue__GetDataFromLE(&chunk, maplen, sizeof(WDL_UINT64)); + + int sz= m_nPins*sizeof(WDL_UINT64); + if (sz>maplen) sz=maplen; + memcpy(m_mapping, pMap, sz); + return true; +} + +template void BufConvertT(TDEST* dest, TSRC* src, int nFrames, int destStride, int srcStride) +{ + int i; + for (i = 0; i < nFrames; ++i) + { + dest[i*destStride] = (TDEST)src[i*srcStride]; + } +} + +template void BufMixT(T* dest, T* src, int nFrames, bool addToDest, double wt_start, double wt_end) +{ + int i; + + if (wt_start == 1.0 && wt_end == 1.0) + { + if (addToDest) + { + for (i = 0; i < nFrames; ++i) + { + dest[i] += src[i]; + } + } + else + { + memcpy(dest, src, nFrames*sizeof(T)); + } + } + else + { + double dw = (wt_end-wt_start)/(double)nFrames; + double cw = wt_start; + + if (addToDest) + { + for (i = 0; i < nFrames; ++i) + { + dest[i] += (T)(1.0-cw)*dest[i]+(T)cw*src[i]; + cw += dw; + } + } + else + { + for (i = 0; i < nFrames; ++i) + { + dest[i] = (T)(1.0-cw)*dest[i]+(T)cw*src[i]; + cw += dw; + } + } + } +} + +// static +bool AudioBufferContainer::BufConvert(void* dest, void* src, int destFmt, int srcFmt, int nFrames, int destStride, int srcStride) +{ + if (destFmt == FMT_32FP) + { + if (srcFmt == FMT_32FP) + { + BufConvertT((float*)dest, (float*)src, nFrames, destStride, srcStride); + return true; + } + else if (srcFmt == FMT_64FP) + { + BufConvertT((float*)dest, (double*)src, nFrames, destStride, srcStride); + return true; + } + } + else if (destFmt == FMT_64FP) + { + if (srcFmt == FMT_32FP) + { + BufConvertT((double*)dest, (float*)src, nFrames, destStride, srcStride); + return true; + } + else if (srcFmt == FMT_64FP) + { + BufConvertT((double*)dest, (double*)src, nFrames, destStride, srcStride); + return true; + } + } + return false; +} + +AudioBufferContainer::AudioBufferContainer() +{ + m_nCh = 0; + m_nFrames = 0; + m_fmt = FMT_32FP; + m_interleaved = true; + m_hasData = false; +} + +void AudioBufferContainer::Resize(int nCh, int nFrames, bool preserveData) +{ + if (!m_hasData) + { + preserveData = false; + } + + int newsz = nCh*nFrames*(int)m_fmt; + + if (preserveData && (nCh != m_nCh || nFrames != m_nFrames)) + { + GetAllChannels(m_fmt, true); // causes m_data to be interleaved + } + + m_data.Resize(newsz); + m_hasData = preserveData; + m_nCh = nCh; + m_nFrames = nFrames; +} + +void AudioBufferContainer::Reformat(int fmt, bool preserveData) +{ + if (!m_hasData) + { + preserveData = false; + } + + int newsz = m_nCh*m_nFrames*(int)fmt; + + if (preserveData && fmt != m_fmt) + { + int oldsz = m_data.GetSize(); + void* src = m_data.Resize(oldsz+newsz); + void* dest = (unsigned char*)src+oldsz; + BufConvert(dest, src, fmt, m_fmt, m_nCh*m_nFrames, 1, 1); + memmove(src, dest, newsz); + } + + m_data.Resize(newsz); + m_hasData = preserveData; + m_fmt = fmt; +} + +// src=NULL to memset(0) +void* AudioBufferContainer::SetAllChannels(int fmt, void* src, int nCh, int nFrames) +{ + Reformat(fmt, false); + Resize(nCh, nFrames, false); + + int sz = nCh*nFrames*(int)fmt; + void* dest = GetAllChannels(fmt, false); + if (src) + { + memcpy(dest, src, sz); + } + else + { + memset(dest, 0, sz); + } + + m_interleaved = true; + m_hasData = true; + return dest; +} + +// src=NULL to memset(0) +void* AudioBufferContainer::SetChannel(int fmt, void* src, int chIdx, int nFrames) +{ + Reformat(fmt, true); + if (nFrames > m_nFrames || chIdx >= m_nCh) + { + int maxframes = (nFrames > m_nFrames ? nFrames : m_nFrames); + Resize(chIdx+1, maxframes, true); + } + + int sz = nFrames*(int)fmt; + void* dest = GetChannel(fmt, chIdx, true); + if (src) + { + memcpy(dest, src, sz); + } + else + { + memset(dest, 0, sz); + } + + m_interleaved = false; + m_hasData = true; + return dest; +} + +void* AudioBufferContainer::MixChannel(int fmt, void* src, int chIdx, int nFrames, bool addToDest, double wt_start, double wt_end) +{ + Reformat(fmt, true); + if (nFrames > m_nFrames || chIdx >= m_nCh) + { + int maxframes = (nFrames > m_nFrames ? nFrames : m_nFrames); + Resize(chIdx+1, maxframes, true); + } + + void* dest = GetChannel(fmt, chIdx, true); + + if (fmt == FMT_32FP) + { + BufMixT((float*)dest, (float*)src, nFrames, addToDest, wt_start, wt_end); + } + else if (fmt == FMT_64FP) + { + BufMixT((double*)dest, (double*)src, nFrames, addToDest, wt_start, wt_end); + } + + m_interleaved = false; + m_hasData = true; + return dest; +} + + +void* AudioBufferContainer::GetAllChannels(int fmt, bool preserveData) +{ + Reformat(fmt, preserveData); + ReLeave(true, preserveData); + + m_hasData = true; // because caller may use the returned pointer to populate the container + + return m_data.Get(); +} + +void* AudioBufferContainer::GetChannel(int fmt, int chIdx, bool preserveData) +{ + Reformat(fmt, preserveData); + if (chIdx >= m_nCh) + { + Resize(chIdx+1, m_nFrames, true); + } + ReLeave(false, preserveData); + + m_hasData = true; // because caller may use the returned pointer to populate the container + + int offsz = chIdx*m_nFrames*(int)fmt; + return (unsigned char*)m_data.Get()+offsz; +} + +void AudioBufferContainer::ReLeave(bool interleave, bool preserveData) +{ + if (interleave != m_interleaved && preserveData && m_hasData) + { + int elemsz = (int)m_fmt; + int chansz = m_nFrames*elemsz; + int bufsz = m_nCh*chansz; + int i; + + unsigned char* src = (unsigned char*)m_data.Resize(bufsz*2); + unsigned char* dest = src+bufsz; + + if (interleave) + { + for (i = 0; i < m_nCh; ++i) + { + BufConvert((void*)(dest+i*elemsz), (void*)(src+i*chansz), m_fmt, m_fmt, m_nFrames, m_nCh, 1); + } + } + else + { + for (i = 0; i < m_nCh; ++i) + { + BufConvert((void*)(dest+i*chansz), (void*)(src+i*elemsz), m_fmt, m_fmt, m_nFrames, 1, m_nCh); + } + } + + memcpy(src, dest, bufsz); // no overlap + m_data.Resize(bufsz); + } + + m_hasData = preserveData; + m_interleaved = interleave; +} + +void AudioBufferContainer::CopyFrom(AudioBufferContainer* rhs) +{ + int sz = rhs->m_data.GetSize(); + void* dest = m_data.Resize(sz); + + if (rhs->m_hasData) + { + void* src = rhs->m_data.Get(); + memcpy(dest, src, sz); + } + + m_nCh = rhs->m_nCh; + m_nFrames = rhs->m_nFrames; + m_fmt = rhs->m_fmt; + m_interleaved = rhs->m_interleaved; + m_hasData = rhs->m_hasData; +} + + +void SetPinsFromChannels(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper) +{ + if (mapper->IsStraightPassthrough()) + { + dest->CopyFrom(src); + return; + } + + int nch = mapper->GetNChannels(); + int npins = mapper->GetNPins(); + int nframes = src->GetNFrames(); + int fmt = src->GetFormat(); + + dest->Resize(npins, nframes, false); + + int c, p; + for (p = 0; p < npins; ++p) + { + bool pinused = false; + for (c = 0; c < nch; ++c) + { + if (mapper->GetPin(p, c)) + { + void* srcbuf = src->GetChannel(fmt, c, true); + dest->MixChannel(fmt, srcbuf, p, nframes, pinused, 1.0, 1.0); + pinused = true; + + if (!mapper->PinHasMoreMappings(p, c)) + { + break; + } + } + } + + if (!pinused) + { + dest->SetChannel(fmt, 0, p, nframes); // clear unused pins + } + } +} + +void SetChannelsFromPins(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper, double wt_start, double wt_end) +{ + if (wt_start == 1.0 && wt_end == 1.0 && mapper->IsStraightPassthrough()) + { + dest->CopyFrom(src); + return; + } + + int nch = mapper->GetNChannels(); + int npins = mapper->GetNPins(); + int nframes = src->GetNFrames(); + int fmt = src->GetFormat(); + + dest->Resize(nch, nframes, true); + + int c, p; + for (c = 0; c < nch; ++c) + { + bool chanused = false; + for (p = 0; p < npins; ++p) + { + if (mapper->GetPin(p, c)) + { + void* srcbuf = src->GetChannel(fmt, p, true); + dest->MixChannel(fmt, srcbuf, c, nframes, chanused, wt_start, wt_end); + chanused = true; + } + } + // don't clear unused channels + } +} + + + diff --git a/WDL/audiobuffercontainer.h b/WDL/audiobuffercontainer.h new file mode 100644 index 00000000..ab8c3d30 --- /dev/null +++ b/WDL/audiobuffercontainer.h @@ -0,0 +1,106 @@ +#ifndef _AUDIOBUFFERCONTAINER_ +#define _AUDIOBUFFERCONTAINER_ + +#include "wdltypes.h" +#include +#include +#include "ptrlist.h" +#include "queue.h" + + +#define CHANNELPINMAPPER_MAXPINS 64 + +class ChannelPinMapper +{ +public: + + ChannelPinMapper() : m_nCh(0), m_nPins(0) {} + ~ChannelPinMapper() {} + + void SetNPins(int nPins); + void SetNChannels(int nCh); + // or ... + void Init(WDL_UINT64* pMapping, int nPins); + + int GetNPins() { return m_nPins; } + int GetNChannels() { return m_nCh; } + + void ClearPin(int pinIdx); + void SetPin(int pinIdx, int chIdx, bool on); + bool TogglePin(int pinIdx, int chIdx); + + // true if this pin is mapped to this channel + bool GetPin(int pinIdx, int chIdx); + // true if this pin is to any higher channel + bool PinHasMoreMappings(int pinIdx, int chIdx); + // true if this mapper is a straight 1:1 passthrough + bool IsStraightPassthrough(); + + char* SaveStateNew(int* pLen); // owned + bool LoadState(char* buf, int len); + + WDL_UINT64 m_mapping[CHANNELPINMAPPER_MAXPINS]; + +private: + + WDL_Queue m_cfgret; + int m_nCh, m_nPins; +}; + + +// use for float and double only ... ints will break it +class AudioBufferContainer +{ +public: + + AudioBufferContainer(); + ~AudioBufferContainer() {} + + enum + { + FMT_32FP=4, + FMT_64FP=8 + }; + + static bool BufConvert(void* dest, void* src, int destFmt, int srcFmt, int nFrames, int destStride, int srcStride); + + int GetNChannels() { return m_nCh; } + int GetNFrames() { return m_nFrames; } + int GetFormat() { return m_fmt; } + + void Resize(int nCh, int nFrames, bool preserveData); + // call Reformat(GetFormat(), false) to discard current data (for efficient repopulating) + void Reformat(int fmt, bool preserveData); + + // src=NULL to memset(0) + void* SetAllChannels(int fmt, void* src, int nCh, int nFrames); + + // src=NULL to memset(0) + void* SetChannel(int fmt, void* src, int chIdx, int nFrames); + + void* MixChannel(int fmt, void* src, int chIdx, int nFrames, bool addToDest, double wt_start, double wt_end); + + void* GetAllChannels(int fmt, bool preserveData); + void* GetChannel(int fmt, int chIdx, bool preserveData); + + void CopyFrom(AudioBufferContainer* rhs); + +private: + + void ReLeave(bool interleave, bool preserveData); + + WDL_HeapBuf m_data; + int m_nCh; + int m_nFrames; + + int m_fmt; + bool m_interleaved; + bool m_hasData; +} WDL_FIXALIGN; + + +void SetPinsFromChannels(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper); +void SetChannelsFromPins(AudioBufferContainer* dest, AudioBufferContainer* src, ChannelPinMapper* mapper, double wt_start=1.0, double wt_end=1.0); + + +#endif diff --git a/WDL/blowfish.c b/WDL/blowfish.c new file mode 100644 index 00000000..f9151ab3 --- /dev/null +++ b/WDL/blowfish.c @@ -0,0 +1,399 @@ +/* + * Author : Paul Kocher + * E-mail : pck@netcom.com + * Date : 1997 + * Description: C implementation of the Blowfish algorithm. + +*/ + +#include "blowfish.h" + +#define N 16 + +static const unsigned int ORIG_P[16 + 2] = { + 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, + 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, + 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, + 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, + 0x9216D5D9L, 0x8979FB1BL + +}; + +static const unsigned int ORIG_S[4*256] = { + 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, + 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, + 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, + 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, + 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, + 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, + 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, + 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, + 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, + 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, + 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, + 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, + 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, + 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, + 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, + 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, + 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, + 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, + 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, + 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, + 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, + 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, + 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, + 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, + 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, + 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, + 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, + 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, + 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, + 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, + 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, + 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, + 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, + 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, + 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, + 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, + 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, + 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, + 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, + 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, + 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, + 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, + 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, + 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, + 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, + 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, + 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, + 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, + 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, + 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, + 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, + 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, + 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, + 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, + 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, + 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, + 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, + 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, + 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, + 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, + 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, + 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, + 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, + 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL, + 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, + 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, + 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, + 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, + 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, + 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, + 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, + 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, + 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, + 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, + 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, + 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, + 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, + 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, + 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, + 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, + 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, + 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, + 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, + 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, + 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, + 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, + 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, + 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, + 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, + 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, + 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, + 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, + 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, + 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, + 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, + 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, + 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, + 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, + 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, + 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, + 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, + 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, + 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, + 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, + 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, + 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, + 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, + 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, + 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, + 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, + 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, + 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, + 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, + 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, + 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, + 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, + 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, + 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, + 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, + 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, + 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, + 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, + 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, + 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, + 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, + 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, + 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, + 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L, + 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, + 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, + 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, + 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, + 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, + 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, + 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, + 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, + 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, + 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, + 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, + 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, + 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, + 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, + 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, + 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, + 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, + 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, + 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, + 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, + 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, + 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, + 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, + 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, + 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, + 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, + 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, + 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, + 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, + 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, + 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, + 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, + 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, + 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, + 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, + 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, + 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, + 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, + 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, + 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, + 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, + 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, + 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, + 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, + 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, + 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, + 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, + 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, + 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, + 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, + 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, + 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, + 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, + 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, + 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, + 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, + 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, + 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, + 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, + 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, + 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, + 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, + 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, + 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L, + 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, + 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, + 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, + 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, + 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, + 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, + 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, + 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, + 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, + 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, + 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, + 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, + 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, + 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, + 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, + 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, + 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, + 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, + 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, + 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, + 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, + 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, + 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, + 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, + 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, + 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, + 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, + 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, + 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, + 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, + 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, + 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, + 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, + 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, + 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, + 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, + 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, + 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, + 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, + 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, + 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, + 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, + 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, + 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, + 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, + 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, + 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, + 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, + 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, + 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, + 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, + 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, + 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, + 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, + 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, + 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, + 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, + 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, + 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, + 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, + 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, + 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, + 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, + 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L + +}; + +#define F(x) (((s[(x>>24)&0xff] + s[256+((x>>16)&0xff)]) ^ s[512+((x>>8)&0xff)]) + s[768+(x&0xff)]) + +static char __bigE; + +static void BSWAPONBIGE(unsigned int *a,unsigned int *a2) +{ + if (__bigE>0) + { + unsigned char *b=(unsigned char *)a; + unsigned char c=b[0]; + b[0]=b[3]; + b[3]=c; + c=b[1]; + b[1]=b[2]; + b[2]=c; + + b=(unsigned char *)a2; + c=b[0]; + b[0]=b[3]; + b[3]=c; + c=b[1]; + b[1]=b[2]; + b[2]=c; + + } +} + +void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr) +{ + BSWAPONBIGE(xl,xr); + { + unsigned int Xl=*xl; + unsigned int Xr=*xr; + int i=N/2; + unsigned int *p=ctx->P; + unsigned int *s=(unsigned int *)ctx->S; + while (i--) + { + Xl ^= *p++; + Xr ^= F(Xl) ^ *p++; + Xl ^= F(Xr); + } + *xr = Xl ^ *p++; + *xl = Xr ^ *p; + } + BSWAPONBIGE(xl,xr); +} + +void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr) +{ + BSWAPONBIGE(xl,xr); + { + unsigned int Xl=*xl; + unsigned int Xr=*xr; + unsigned int *p=ctx->P + N + 1; + unsigned int *s=(unsigned int *)ctx->S; + int i=N/2; + while (i--) + { + Xl ^= *p--; + Xr ^= F(Xl) ^ *p--; + Xl ^= F(Xr); + } + *xr = Xl ^ *p--; + *xl = Xr ^ *p; + } + BSWAPONBIGE(xl,xr); +} + +void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen) { + int i, j=0; + unsigned int *s=(unsigned int *)ORIG_P; + unsigned int *p=ctx->P; + + unsigned int datal=0, datar=0; + + if (!__bigE) + { + int a=1; + __bigE = (*(char *)&a) ? -1 : 1; + } + + i=N+2; + while (i--) + { + int k=4; + unsigned int data = 0; + while (k--) + { + data = (data << 8) | key[j]; + if (++j >= keyLen) j = 0; + } + *p++=*s++ ^ data; + } + for(i=0;i<256*4; i++) ctx->S[i]=ORIG_S[i]; + + p=ctx->P; + i=(N+2)/2; + while (i--) + { + BSWAPONBIGE(&datal,&datar); + Blowfish_Encrypt(ctx, &datal, &datar); + BSWAPONBIGE(&datal,&datar); + *p++=datal; + *p++=datar; + } + + s=ctx->S; + i=256/2*4; + while (i--) + { + BSWAPONBIGE(&datal,&datar); + Blowfish_Encrypt(ctx, &datal, &datar); + BSWAPONBIGE(&datal,&datar); + *s++ = datal; + *s++ = datar; + } +} diff --git a/WDL/blowfish.h b/WDL/blowfish.h new file mode 100644 index 00000000..7bd4c4f8 --- /dev/null +++ b/WDL/blowfish.h @@ -0,0 +1,23 @@ +/* + * Author : Paul Kocher + * E-mail : pck@netcom.com + * Date : 1997 + * Description: C implementation of the Blowfish algorithm. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + unsigned int P[16 + 2]; + unsigned int S[4*256]; +} BLOWFISH_CTX; + +void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen); +void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr); +void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned int *xl, unsigned int *xr); + +#ifdef __cplusplus +}; +#endif \ No newline at end of file diff --git a/WDL/chunkalloc.h b/WDL/chunkalloc.h new file mode 100644 index 00000000..14fc35b1 --- /dev/null +++ b/WDL/chunkalloc.h @@ -0,0 +1,93 @@ +#ifndef _WDL_CHUNKALLOC_H_ +#define _WDL_CHUNKALLOC_H_ + +#include "wdltypes.h" + +class WDL_ChunkAlloc +{ + struct _hdr + { + struct _hdr *_next; + char data[16]; + }; + + _hdr *m_chunks; + int m_chunksize, m_chunkused; + + public: + + WDL_ChunkAlloc(int chunksize=65500) { m_chunks=NULL; m_chunkused=0; m_chunksize=chunksize>16?16:chunksize; } + ~WDL_ChunkAlloc() { Free(); } + + void Free() + { + _hdr *a = m_chunks; + m_chunks=0; + m_chunkused=0; + while (a) { _hdr *f=a; a=a->_next; free(f); } + } + + void *Alloc(int sz, int align=0) + { + if (sz<1) return NULL; + + if (align < 1 || (align & (align-1))) align=1; + + if (m_chunks) + { + int use_sz=sz; + char *p = m_chunks->data + m_chunkused; + int a = ((int) (INT_PTR)p) & (align-1); + if (a) + { + use_sz += align-a; + p += align-a; + } + if (use_sz <= m_chunksize - m_chunkused) + { + m_chunkused += use_sz; + return p; + } + } + + // we assume that malloc always gives at least 8 byte alignment, and our _next ptr may offset that by 4, + // so no need to allocate extra if less than 4 bytes of alignment requested + int use_align = (align>=4 ? align : 0); + int alloc_sz=sz+use_align; + if (alloc_sz < m_chunksize) + { + // if existing chunk has less free space in it than we would at chunksize, allocate chunksize + if (!m_chunks || m_chunkused > alloc_sz) alloc_sz=m_chunksize; + } + _hdr *nc = (_hdr *)malloc(sizeof(_hdr) + alloc_sz - 16); + if (!nc) return NULL; + + int use_sz=sz; + char *ret = nc->data; + int a = ((int) (INT_PTR)ret) & (align-1); + if (a) + { + use_sz += align-a; + ret += align-a; + } + + if (m_chunks && (m_chunksize-m_chunkused) >= (alloc_sz - use_sz)) + { + // current chunk has as much or more free space than our chunk, put our chunk on the list second + nc->_next = m_chunks->_next; + m_chunks->_next=nc; + } + else + { + // push our chunk to the top of the list + nc->_next = m_chunks; + m_chunks=nc; + m_chunkused = alloc_sz >= m_chunksize ? use_sz : m_chunksize; + } + + return ret; + } + +}; + +#endif diff --git a/WDL/circbuf.h b/WDL/circbuf.h new file mode 100644 index 00000000..96d7bc32 --- /dev/null +++ b/WDL/circbuf.h @@ -0,0 +1,171 @@ +/* + WDL - circbuf.h + Copyright (C) 2005 Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple class for a circular FIFO queue of bytes. It + has a strong advantage over WDL_Queue with large buffers, as it does far + fewer memcpy()'s. + +*/ + +#ifndef _WDL_CIRCBUF_H_ +#define _WDL_CIRCBUF_H_ + +#include "heapbuf.h" + +class WDL_CircBuf +{ +public: + WDL_CircBuf() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_CircBuf")) + { + m_size = 0; + m_inbuf = 0; + m_head = m_tail = 0; + } + ~WDL_CircBuf() + { + } + void SetSize(int size, bool keepcontents=false) + { + WDL_HeapBuf tmp(4096 WDL_HEAPBUF_TRACEPARM("WDL_CircBuf/TEMP")); + if (keepcontents) + { + int ms=NbInBuf(); + if (ms>size) ms=size; + if (ms>0) Get(tmp.Resize(ms),ms); + } + m_size = size; + m_hb.Resize(size); + Reset(); + if (tmp.GetSize()) Add(tmp.Get(),tmp.GetSize()); // add old data back in + } + void Reset() + { + m_head = (char *)m_hb.Get(); + m_tail = (char *)m_hb.Get(); + m_endbuf = (char *)m_hb.Get() + m_size; + m_inbuf = 0; + } + int Add(const void *buf, int l) + { + char *p = (char *)buf; + if (l > m_size) l = m_size; + int put = l; + int l2; + if (!m_size) return 0; + l2 = m_endbuf - m_head; + if (l2 <= l) + { + memcpy(m_head, p, l2); + m_head = (char *)m_hb.Get(); + p += l2; + l -= l2; + } + if (l) + { + memcpy(m_head, p, l); + m_head += l; + p += l; + } + m_inbuf += put; + if (m_inbuf > m_size) m_inbuf = m_size; + return put; + } + int Get(void *buf, int l) + { + char *p = (char *)buf; + int got = 0; + if (!m_size) return 0; + if (m_inbuf <= 0) return 0; + if (l > m_inbuf) l = m_inbuf; + m_inbuf -= l; + got = l; + if (m_tail+l >= m_endbuf) + { + int l1 = m_endbuf - m_tail; + l -= l1; + memcpy(p, m_tail, l1); + m_tail = (char *)m_hb.Get(); + p += l1; + memcpy(p, m_tail, l); + m_tail += l; + } + else + { + memcpy(p, m_tail, l); + m_tail += l; + } + return got; + } + int Available() { return m_size - m_inbuf; } + int NbInBuf() { return m_inbuf; } + +private: + WDL_HeapBuf m_hb; + char *m_head, *m_tail, *m_endbuf; + int m_size, m_inbuf; +} WDL_FIXALIGN; + + +template +class WDL_TypedCircBuf +{ +public: + + WDL_TypedCircBuf() {} + ~WDL_TypedCircBuf() {} + + void SetSize(int size, bool keepcontents = false) + { + mBuf.SetSize(size * sizeof(T), keepcontents); + } + + void Reset() + { + mBuf.Reset(); + } + + int Add(const T* buf, int l) + { + return mBuf.Add(buf, l * sizeof(T)) / sizeof(T); + } + + int Get(T* buf, int l) + { + return mBuf.Get(buf, l * sizeof(T)) / sizeof(T); + } + + int Available() + { + return mBuf.Available() / sizeof(T); + } + int NbInBuf() + { + return mBuf.NbInBuf() / sizeof(T); + } + +private: + WDL_CircBuf mBuf; +} WDL_FIXALIGN; + +#endif diff --git a/WDL/cmath/bessel_polynomial.h b/WDL/cmath/bessel_polynomial.h new file mode 100644 index 00000000..030d32b0 --- /dev/null +++ b/WDL/cmath/bessel_polynomial.h @@ -0,0 +1,75 @@ +/* + bessel_polynomial.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + algorithm to calculate coefficients for a bessel polynomial from krall & fink + series. +*/ + +#ifndef _BESSEL_POLYNOMIAL_H_ +#define _BESSEL_POLYNOMIAL_H_ + +#include "custom_math.h" +#include "factorial.h" + +#ifdef _BESSEL_USE_INLINE_ + #define _BESSEL_INLINE _CMATH_INLINE +#else + #define _BESSEL_INLINE +#endif + +#ifndef _CMATH_ANSI + #define _BESSEL_MAX_ORDER 10 +#else + #define _BESSEL_MAX_ORDER 3 +#endif + +/* return a coefficient */ +_BESSEL_INLINE cmath_std_int_t +bessel_coefficient(const cmath_uint16_t k, const cmath_uint16_t n) +{ + register cmath_std_int_t c; + const cmath_uint16_t nmk = (cmath_uint16_t)(n - k); + c = factorial(2*n - k); + c /= (factorial(nmk)*factorial(k)) * (1 << nmk); + return c; +} + +/* calculate all coefficients for n-th order polynomial */ +_BESSEL_INLINE +void bessel_polynomial( cmath_std_int_t *coeff, + const cmath_uint16_t order, + const cmath_uint16_t reverse ) +{ + register cmath_uint16_t i = (cmath_uint16_t)(order + 1); + if (reverse) + { + while (i--) + coeff[order-i] = bessel_coefficient(i, order); + } + else + { + while (i--) + coeff[i] = bessel_coefficient(i, order); + } +} + +#endif /* _BESSEL_POLYNOMIAL_H */ diff --git a/WDL/cmath/complex_number.h b/WDL/cmath/complex_number.h new file mode 100644 index 00000000..c5be1931 --- /dev/null +++ b/WDL/cmath/complex_number.h @@ -0,0 +1,368 @@ +/* + complex_number.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + portable complex number operations +*/ + +#ifndef _COMPLEX_NUMBER_H_ +#define _COMPLEX_NUMBER_H_ + +#include "custom_math.h" + +/* settings */ +#ifndef _CNUM_NO_INLINE + #define _CNUM_INLINE _CMATH_INLINE +#else + #define _CNUM_INLINE +#endif + +#ifndef _CNUM_NO_ALIAS + #define _CNUM_ALIAS _CMATH_MAY_ALIAS +#else + #define _CNUM_ALIAS +#endif + +/* types & constants */ +#ifndef cnum_t + #define cnum_t cmath_t +#endif + +typedef struct +{ + cnum_t r _CMATH_ALIGN(8); + cnum_t i _CMATH_ALIGN(8); +} _CNUM_ALIAS cnum_s; + +const cnum_s cnum_zero = {0, 0}; +const cnum_s cnum_i1 = {0, 1}; +const cnum_s cnum_r1 = {1, 0}; +const cnum_s cnum_r2 = {2, 0}; + +/* methods */ +#define _CNUM(r, i) cnum_new(r, i) +#define _CNUMD(x, r, i) cnum_s x = {r, i} + +_CNUM_INLINE +cnum_s cnum_set(cnum_s *x, const cnum_t r, const cnum_t i) +{ + x->r = r; + x->i = i; + return *x; +} + +_CNUM_INLINE +cnum_s cnum_from(cnum_s *x, const cnum_s y) +{ + x->r = y.r; + x->i = y.i; + return *x; +} + +_CNUM_INLINE +cnum_s cnum_new(const cnum_t r, const cnum_t i) +{ + cnum_s x; + x.r = r; + x.i = i; + return x; +} + +_CNUM_INLINE +cnum_s cnum_cartesian(const cnum_s x) +{ + return cnum_new(x.r * cmath_cos(x.i), x.r * cmath_sin(x.i)); +} + +_CNUM_INLINE +cnum_s cnum_polar(const cnum_s x) +{ + return cnum_new(cmath_cabs(x.r, x.i), cmath_carg(x.r, x.i)); +} + +_CNUM_INLINE +cnum_s cnum_conjugate(const cnum_s x) +{ + return cnum_new(x.r, -x.i); +} + +_CNUM_INLINE +cnum_s cnum_negative(const cnum_s x) +{ + return cnum_new(-x.r, -x.i); +} + +_CNUM_INLINE +cnum_s cnum_swap(const cnum_s x) +{ + return cnum_new(x.i, x.r); +} + +_CNUM_INLINE +cnum_s cnum_add(const cnum_s x, const cnum_s y) +{ + return cnum_new(x.r + y.r, x.i + y.i); +} + +_CNUM_INLINE +cnum_s cnum_add_r(const cnum_s x, const cnum_t y) +{ + return cnum_new(x.r + y, x.i + y); +} + +_CNUM_INLINE +cnum_s cnum_sub(const cnum_s x, const cnum_s y) +{ + return cnum_new(x.r - y.r, x.i - y.i); +} + +_CNUM_INLINE +cnum_s cnum_sub_r(register cnum_s x, const cnum_t y) +{ + return cnum_new(x.r - y, x.i - y); +} + +_CNUM_INLINE +cnum_s cnum_r_sub(const cnum_t x, register cnum_s y) +{ + return cnum_new(x - y.r, x - y.i); +} + +_CNUM_INLINE +cnum_s cnum_mul(const cnum_s x, const cnum_s y) +{ + return cnum_new(x.r*y.r - x.i*y.i, x.r*y.i + x.i*y.r); +} + +_CNUM_INLINE +cnum_s cnum_mul_r(const cnum_s x, const cnum_t y) +{ + return cnum_new(x.r*y, x.i*y); +} + +#define cnum_sqr(x) \ + cnum_mul(x, x) + +_CNUM_INLINE +cnum_s cnum_div_r(const cnum_s x, const cnum_t y) +{ + return cnum_new(x.r/y, x.i/y); +} + +_CNUM_INLINE +cnum_s cnum_r_div(const cnum_t x, const cnum_s y) +{ + return cnum_new(x/y.r, x/y.i); +} + +_CNUM_INLINE +cnum_s cnum_div(const cnum_s x, const cnum_s y) +{ + return cnum_div_r(cnum_mul(x, cnum_conjugate(y)), + (y.r*y.r + cmath_abs(y.i*y.i))); +} + +#define cnum_inv(x) \ + cnum_div(cnum_r1, x) + +#define _CNUM_CHECK_EXP_D_ \ + cmath_abs(deg - cmath_round(deg)) == 0 + +_CNUM_INLINE +cnum_s cnum_exp(const cnum_s x) +{ + cnum_t sin_i = cmath_sin(x.i); + cnum_t cos_i = cmath_cos(x.i); + const cnum_t exp_r = cmath_exp(x.r); + + #ifndef _CNUM_NO_CHECK_EXP_ + register cnum_t deg; + + if (x.r == 0) + return cnum_zero; + deg = x.i / cmath_pi; + if (_CNUM_CHECK_EXP_D_) + sin_i = 0; + deg += 0.5; + if (_CNUM_CHECK_EXP_D_) + cos_i = 0; + deg = x.i / cmath_pi2; + if (_CNUM_CHECK_EXP_D_) + cos_i = 1; + #endif + + return cnum_new(exp_r*cos_i, exp_r*sin_i); +} + +_CNUM_INLINE +cnum_s cnum_log_k(const cnum_s x, const cmath_int32_t k) +{ + return cnum_new(cmath_log(cmath_cabs(x.r, x.i)), + (cmath_carg(x.r, x.i) + (cmath_pi2*k))); +} + +#define cnum_log(x) \ + cnum_log_k(x, 0) + +#define cnum_log_b_k(x, b, k) \ + cnum_div(cnum_log_k(x, k), cnum_log_k(b, k)) + +#define cnum_log_b(b, x) \ + cnum_div(cnum_log(x), cnum_log(b)) + +#define cnum_log2(x) \ + cnum_log_b(x, 2) + +#define cnum_log2_k(x, k) \ + cnum_log_b_k(x, 2, k) + +#define cnum_log10(x) \ + cnum_log_b(x, 2) + +#define cnum_log10_k(x, k) \ + cnum_log_b_k(x, 10, k) + +#define _CNUM_CHECK_POW_C_ \ + if (x.r == 0 && x.i == 0) \ + return cnum_zero; \ + if (y.r == 0 && y.i == 0) \ + return cnum_r1 \ + +_CNUM_INLINE +cnum_s cnum_pow_c_k(const cnum_s x, const cnum_s y, const cmath_int32_t k) +{ + _CNUM_CHECK_POW_C_; + return cnum_exp(cnum_mul(cnum_log_k(x, k), y)); +} + +_CNUM_INLINE +cnum_s cnum_pow_c(const cnum_s x, const cnum_s y) +{ + _CNUM_CHECK_POW_C_; + return cnum_exp(cnum_mul(cnum_log(x), y)); +} + +_CNUM_INLINE +cnum_s cnum_pow(const cnum_s x, const cnum_t n) +{ + const cnum_t r_pow_n = cmath_pow(cmath_cabs(x.r, x.i), n); + const cnum_t theta_n = cmath_carg(x.r, x.i) * n; + if (n == 0) + return cnum_new(1, 0); + if (n == 1) + return x; + return cnum_new(r_pow_n * cmath_cos(theta_n), r_pow_n * cmath_sin(theta_n)); +} + +#define cnum_root_c_k(x, y, k) \ + cnum_exp(cnum_div(cnum_log_k(x, k), y)) + +#define cnum_root_c(x, y) \ + cnum_exp(cnum_div(cnum_log(x), y)) + +#define cnum_root(x, n) \ + cnum_pow(x, 1/n) + +#define cnum_sqrt(x) \ + cnum_pow(x, 0.5) + +#define cnum_sin(x) \ + cnum_new(cmath_sin((x).r)*cmath_cosh((x).i), \ + cmath_cos((x).r)*cmath_sinh((x).i)) + +#define cnum_sinh(x) \ + cnum_new(cmath_sinh(x.r)*cmath_cos(x.i), cmath_cosh(x.r)*sin(x.i)) + +#define cnum_cos(x) \ + cnum_new(cmath_cos(x.r)*cmath_cosh(x.i), -cmath_sin(x.r)*cmath_sinh(x.i)) + +#define cnum_cosh(x) \ + cnum_new(cmath_cosh(x.r)*cmath_cos(x.i), cmath_sinh(x.r)*cmath_sin(x.i)) + +#define cnum_tan(x) \ + cnum_div(cnum_sin(x), cnum_cos(x)) + +#define cnum_tanh(x) \ + cnum_div(cnum_sinh(x), cnum_cosh(x)) + +#define cnum_csc(x) \ + cnum_inv(cnum_sin(x)) + +#define cnum_sec(x) \ + cnum_inv(cnum_cos(x)) + +#define cnum_cotan(x) \ + cnum_inv(cnum_tan(x)) + +#define cnum_asin(x) \ + cnum_negative(cnum_mul(cnum_i1, cnum_log(cnum_add(cnum_mul(cnum_i1, x), \ + cnum_sqrt(cnum_sub(cnum_r1, cnum_sqr(x))))))) + +#define cnum_acos(x) \ + cnum_negative(cnum_mul(cnum_i1, cnum_log(cnum_add(x, cnum_mul(cnum_i1, \ + cnum_sqrt(cnum_sub(cnum_r1, cnum_sqr(x)))))))) + +#define cnum_atan(x) \ + cnum_div(cnum_mul(cnum_i1, cnum_log(cnum_div(cnum_sub(cnum_r1, \ + cnum_mul(cnum_i1, x)), cnum_add(cnum_r1, cnum_mul(cnum_i1, x))))), cnum_r2) + +#define cnum_acsc(x) \ + cnum_asin(cnum_inv(x)) + +#define cnum_asec(x) \ + cnum_acos(cnum_inv(x)) + +#define cnum_acot(x) \ + cnum_atan(cnum_inv(x)) + +#define cnum_csch(x) \ + cnum_inv(cnum_sinh(x)) + +#define cnum_sech(x) \ + cnum_inv(cnum_cosh(x)) + +#define cnum_coth(x) \ + cnum_inv(cnum_tanh(x)) + +#define cnum_asinh(x) \ + cnum_log(cnum_add(x, cnum_sqrt(cnum_add(cnum_r1, cnum_sqr(x))))) + +#define cnum_acosh(x) \ + cnum_log(cnum_add(x, cnum_mul(cnum_sqrt(cnum_add(x, cnum_r1)), \ + cnum_sqrt(cnum_sub(x, cnum_r1))))) + +#define cnum_atanh(x) \ + cnum_div(cnum_sub(cnum_log(cnum_add(cnum_r1, x)), \ + cnum_log(cnum_sub(cnum_r1, x))), cnum_r2) + +#define cnum_acsch(x) \ + cnum_asinh(cnum_inv(x)) + +#define cnum_asech(x) \ + cnum_acosh(cnum_inv(x)) + +#define cnum_asech(x) \ + cnum_acosh(cnum_inv(x)) + +#define cnum_acoth(x) \ + cnum_atanh(cnum_inv(x)) + +#endif /* _COMPLEX_NUMBER_H_ */ diff --git a/WDL/cmath/custom_math.h b/WDL/cmath/custom_math.h new file mode 100644 index 00000000..a624b3a2 --- /dev/null +++ b/WDL/cmath/custom_math.h @@ -0,0 +1,209 @@ +/* + custom_math.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + portable definitions for ansi c and cross compiler compatibility. + contains: numeric constants, custom math functions, macros & other. +*/ + +#ifndef _CUSTOM_MATH_H_ +#define _CUSTOM_MATH_H_ + +#include "math.h" + +/* check for "c89" mode */ +#if (defined _MSC_VER && defined __STDC__) || \ + (defined __GNUC__ && defined __STRICT_ANSI__) + #define _CMATH_ANSI +#endif + +/* enable inline */ +#if defined __cplusplus || (!defined _CMATH_ANSI && defined _CMATH_USE_INLINE) + #ifdef _MSC_VER + #define _CMATH_INLINE __inline + #else + #define _CMATH_INLINE inline + #endif +#else + #define _CMATH_INLINE +#endif + +/* align type to size of type */ +#if defined __GNUC__ || defined __TINYC__ + #define _CMATH_ALIGN(x) __attribute__ ((aligned(x))) + #define _CMATH_ALIGN_T(x) __attribute__ ((aligned(sizeof(x)))) +#else + #define _CMATH_ALIGN(x) + #define _CMATH_ALIGN_T(x) +#endif + +/* printf max integer */ +#ifndef _CMATH_ANSI + #ifdef _WIN32 + #define _CMATH_PR_STD_UINT "I64u" + #define _CMATH_PR_STD_INT "I64i" + #define _CMATH_PR_STD_HEX "I64x" + #else + #define _CMATH_PR_STD_UINT "llu" + #define _CMATH_PR_STD_INT "lli" + #define _CMATH_PR_STD_HEX "llx" + #endif +#else + #define _CMATH_PR_STD_UINT "u" + #define _CMATH_PR_STD_INT "d" + #define _CMATH_PR_STD_HEX "x" +#endif + +/* msvc specifics */ +#ifdef _MSC_VER + #pragma warning(disable : 4514) + + #define MK_L(x) (x) + #define MK_UL(x) (x) + #define MK_LL(x) (x) + #define MK_ULL(x) (x) +#else + #define MK_L(x) (x##L) + #define MK_UL(x) (x##UL) + #ifdef _CMATH_ANSI + #define MK_LL(x) (x##L) + #define MK_ULL(x) (x##UL) + #else + #define MK_LL(x) (x##LL) + #define MK_ULL(x) (x##ULL) + #endif +#endif + +/* definitions depending on c standard */ +#ifdef _CMATH_ANSI + #define cmath_std_signbit MK_UL(0x7fffffff) + #define cmath_std_float_t float + #define cmath_std_int_t int +#else + #define cmath_std_signbit MK_ULL(0x7fffffffffffffff) + #define cmath_std_float_t double + #ifdef _MSC_VER + #define cmath_std_int_t __int64 + #else + #define cmath_std_int_t long long + #endif +#endif + +/* types and constants */ +#ifndef cmath_t + #define cmath_t double +#endif + +#define cmath_std_uint_t unsigned cmath_std_int_t + +#define cmath_pi 3.1415926535897932384626433832795 +#define cmath_pi2 6.2831853071795864769252867665590 +#define cmath_pi_2 1.5707963267948966192313216916398 +#define cmath_e 2.7182818284590452353602874713526 +#define cmath_sqrt2 1.4142135623730950488016887242097 +#define cmath_pi_180 0.0174532925199432957692369076848 +#define cmath_180_pi 57.295779513082320876798154814105 + +#define cmath_int8_t char +#define cmath_uint8_t unsigned char +#define cmath_int16_t short +#define cmath_uint16_t unsigned short +#define cmath_int32_t int +#define cmath_uint32_t unsigned int + +/* aliased types */ +#ifdef __GNUC__ + #define _CMATH_MAY_ALIAS __attribute__((__may_alias__)) +#else + #define _CMATH_MAY_ALIAS +#endif + +typedef cmath_t _CMATH_MAY_ALIAS cmath_t_a; + +/* possible approximations */ +#define cmath_sin sin +#define cmath_cos cos +#define cmath_tan tan +#define cmath_asin asin +#define cmath_acos acos +#define cmath_atan atan +#define cmath_atan2 atan2 +#define cmath_sinh sinh +#define cmath_cosh cosh +#define cmath_tanh tanh +#define cmath_exp exp +#define cmath_pow pow +#define cmath_sqrt sqrt +#define cmath_log log +#define cmath_log2 log2 +#define cmath_log10 log10 + +/* methods */ +#define cmath_array_size(x) \ + (sizeof(x) / sizeof(*(x))) + +#define poly_order(x) \ + (sizeof(x) / sizeof(*(x)) - 1) + +#define cmath_cabs(a, b) \ + cmath_sqrt((a)*(a) + (b)*(b)) + +#define cmath_carg(a, b) \ + cmath_atan2((b), (a)) + +#define cmath_radians(x) \ + ((x)*cmath_pi_180) + +#define cmath_degrees(x) \ + ((x)*cmath_180_pi) + +_CMATH_INLINE +cmath_t cmath_powi(const cmath_t x, register cmath_uint16_t n) +{ + register cmath_t result = 1; + while (n--) + result *= x; + return result; +} + +_CMATH_INLINE +cmath_t cmath_abs(const cmath_t x) +{ + register union + { + cmath_std_int_t i; + cmath_std_float_t j; + } u; + u.j = (cmath_std_float_t)x; + u.i &= cmath_std_signbit; + return u.j; +} + +_CMATH_INLINE +cmath_t cmath_round(const cmath_t x) +{ + if (x < 0.0) + return (cmath_t)(cmath_std_int_t)(x - 0.5); + else + return (cmath_t)(cmath_std_int_t)(x + 0.5); +} + +#endif /* _CUSTOM_MATH_H_ */ diff --git a/WDL/cmath/durand_kerner.h b/WDL/cmath/durand_kerner.h new file mode 100644 index 00000000..36572fce --- /dev/null +++ b/WDL/cmath/durand_kerner.h @@ -0,0 +1,117 @@ +/* + durand_kerner.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + durand-kerner (weierstrass) algorithm for finding complex roots + of polynomials. + accuracy depends a lot on data type precision. +*/ + +#ifndef _DURAND_KERNER_H_ +#define _DURAND_KERNER_H_ + +#include "horner.h" +#include "custom_math.h" +#include "complex_number.h" + +/* settings */ +#ifdef _DURAND_KERNER_USE_INLINE_ + #define _DURAND_KERNER_INLINE _CMATH_INLINE +#else + #define _DURAND_KERNER_INLINE +#endif + +#define DK_EPSILON 1E-16 +#define DK_MAX_ITR 1E+3 +#define DK_MAX_N 256 + +const cnum_s dk_demoivre_c = {0.4, 0.9}; + +/* accepts an array of complex numbers */ +_DURAND_KERNER_INLINE +void durand_kerner_c +(const cnum_s *coeff, cnum_s *roots, const cmath_uint16_t order) +{ + register cmath_uint16_t i, j; + register cmath_uint32_t itr; + cnum_s coeff_sc[DK_MAX_N]; + cnum_s x; + cnum_s hor; /* needs an address or breaks g++ 4.x */ + + i = 0; + while(i < order) + { + cnum_from(&roots[i], cnum_pow(dk_demoivre_c, i)); + i++; + } + + cnum_from(&coeff_sc[0], cnum_r1); + i = 1; + while(i < order+1) + { + cnum_from(&coeff_sc[i], cnum_div(coeff[i], coeff[0])); + i++; + } + + itr = 0; + while(itr < DK_MAX_ITR) + { + i = 0; + while(i < order) + { + j = 0; + x = cnum_r1; + while (j < order) + { + if (i != j) + x = cnum_mul(cnum_sub(roots[i], roots[j]), x); + j++; + } + hor = horner_eval_c(coeff_sc, roots[i], order); + x = cnum_div(hor, x); + x = cnum_sub(roots[i], x); + if (cmath_abs(cmath_abs(x.r) - cmath_abs(roots[i].r)) < DK_EPSILON && + cmath_abs(cmath_abs(x.i) - cmath_abs(roots[i].i)) < DK_EPSILON) + return; + cnum_from(&roots[i], x); + i++; + } + itr++; + } +} + +/* accepts an array of real numbers */ +_DURAND_KERNER_INLINE +void durand_kerner +(const cmath_t *coeff, cnum_s *roots, const cmath_uint16_t order) +{ + register cmath_uint16_t i; + cnum_s coeff_c[DK_MAX_N]; + i = 0; + while(i < (order+1)) + { + cnum_set(&coeff_c[i], coeff[i], 0); + i++; + } + durand_kerner_c(coeff_c, roots, order); +} + +#endif /* _DURAND_KERNER_H_ */ diff --git a/WDL/cmath/factorial.h b/WDL/cmath/factorial.h new file mode 100644 index 00000000..f19803da --- /dev/null +++ b/WDL/cmath/factorial.h @@ -0,0 +1,114 @@ +/* + factorial.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + methods to return low-order factorials depending on allowed data types. + + 20! = 2432902008176640000 is the maximum factorial to be held + in a unsigned 64bit integer. + 13! = 479001600 is the maximum factorial to be held in a unsigned + 32bit integer. +*/ + +#ifndef _FACTORIAL_H_ +#define _FACTORIAL_H_ + +#include "custom_math.h" + +#define FACTORIAL_LOWER \ + MK_ULL(1), \ + MK_ULL(1), \ + MK_ULL(2), \ + MK_ULL(6), \ + MK_ULL(24), \ + MK_ULL(120), \ + MK_ULL(720), \ + MK_ULL(5040), \ + MK_ULL(40320), \ + MK_ULL(362880), \ + MK_ULL(3628800), \ + MK_ULL(39916800), \ + MK_ULL(479001600) + +#define FACTORIAL_HIGHER \ + MK_ULL(6227020800), \ + MK_ULL(87178291200), \ + MK_ULL(1307674368000), \ + MK_ULL(20922789888000), \ + MK_ULL(355687428096000), \ + MK_ULL(6402373705728000), \ + MK_ULL(121645100408832000), \ + MK_ULL(2432902008176640000) + +static const cmath_std_uint_t _factorials[] = +{ + #ifdef _CMATH_ANSI + FACTORIAL_LOWER + #else + FACTORIAL_LOWER, + FACTORIAL_HIGHER + #endif +}; + +static const cmath_t _inv_factorials[] = +{ + 1.00000000000000000000000000000000, + 1.00000000000000000000000000000000, + 0.50000000000000000000000000000000, + 0.16666666666666666666666666666667, + 0.04166666666666666666666666666666, + 0.00833333333333333333333333333333, + 0.00138888888888888888888888888888, + 0.00019841269841269841269841269841, + 0.00002480158730158730158730158730, + 0.00000275573192239858906525573192, + 0.00000027557319223985890652557319, + 0.00000002505210838544171877505210, + 0.00000000208767569878680989792100, + 0.00000000016059043836821614599390, + 0.00000000001147074559772972471385, + 0.00000000000076471637318198164750, + 0.00000000000004779477332387385297, + 0.00000000000000281145725434552076, + 0.00000000000000015619206968586225, + 0.00000000000000000822063524662433, + 0.00000000000000000041103176233122 +}; + +_CMATH_INLINE +cmath_std_uint_t factorial(const cmath_uint32_t x) +{ + if(x >= cmath_array_size(_factorials)) + return 0; + else + return _factorials[x]; +} + +_CMATH_INLINE +cmath_t inv_factorial(const cmath_uint32_t x) +{ + if(x >= cmath_array_size(_inv_factorials)) + return 0; + else + return _inv_factorials[x]; +} + +#endif /* _FACTORIAL_H_ */ diff --git a/WDL/cmath/horner.h b/WDL/cmath/horner.h new file mode 100644 index 00000000..d943457f --- /dev/null +++ b/WDL/cmath/horner.h @@ -0,0 +1,71 @@ +/* + horner.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + algorithm to evaluate integer order polynomials using horner's scheme. +*/ + +#ifndef _HORNER_H_ +#define _HORNER_H_ + +#include "custom_math.h" +#include "complex_number.h" + +/* settings */ +#ifndef _HORNER_INLINE + #define _HORNER_INLINE _CMATH_INLINE +#else + #define _HORNER_INLINE +#endif + +/* real */ +_HORNER_INLINE +cmath_t horner_eval +(const cmath_t *coeff, const cmath_t x, cmath_uint16_t order) +{ + register cmath_t y = coeff[0]; + register cmath_uint16_t n = 1; + order += 1; + while(n < order) + { + y = y*x + coeff[n]; + n++; + } + return y; +} + +/* complex */ +_HORNER_INLINE +cnum_s horner_eval_c +(const cnum_s *coeff, const cnum_s x, cmath_uint16_t order) +{ + register cmath_uint16_t n = 1; + cnum_s y = coeff[0]; + order += 1; + while(n < order) + { + y = cnum_add(cnum_mul(y, x), coeff[n]); + n++; + } + return y; +} + +#endif /* _HORNER_H_ */ diff --git a/WDL/cmath/test_bessel.c b/WDL/cmath/test_bessel.c new file mode 100644 index 00000000..83915a6c --- /dev/null +++ b/WDL/cmath/test_bessel.c @@ -0,0 +1,119 @@ +/* + test_bessel.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + test bessel_polynomial.h and other related headers + + gcc -W -Wall -Wextra -ansi pedantic + cl /W4 /Za + + reduced precisions for ansi c +*/ + +#include "stdio.h" +#include "custom_math.h" +#include "bessel_polynomial.h" +#include "durand_kerner.h" + +int main(void) +{ + register cmath_uint16_t i = 0; + register cmath_int16_t diff = 0; + + cmath_uint32_t in_order = _BESSEL_MAX_ORDER + 1; + cmath_uint16_t order; + const cmath_uint16_t reverse = 1; + + cmath_std_int_t coeff[_BESSEL_MAX_ORDER + 1]; + + cnum_t dk_coeff[_BESSEL_MAX_ORDER + 1]; + cnum_s dk_roots[_BESSEL_MAX_ORDER]; + + /* */ + #ifdef _CMATH_ANSI + puts("\n\nansi c is: on"); + #else + puts("\n\nansi c is: off"); + #endif + + /* */ + while (in_order > _BESSEL_MAX_ORDER) + { + printf("\nenter order of bessel polynomial (0 - %d): ", _BESSEL_MAX_ORDER); + scanf("%u", &in_order); + } + + order = (cmath_uint16_t)in_order; + bessel_polynomial(coeff, order, reverse); + + printf("\norder [N]: %d", order); + printf("\nreversed bessel: %d\n\n", reverse); + printf("list of coefficients:\n"); + while (i <= order) + { + printf("order[%2d]: ", (order - i)); + printf("%"_CMATH_PR_STD_INT"\n", coeff[i]); + i++; + } + puts("\npolynomial:"); + printf("y(x) = "); + + i = 0; + while (i <= order) + { + diff = (cmath_int16_t)(order - i); + if (diff > 0) + if (coeff[i] > 1) + { + printf("%"_CMATH_PR_STD_INT, coeff[i]); + if (diff > 1) + printf("*x^%d + ", diff); + else + printf("*x + "); + } + else + printf("x^%d + ", diff); + else + printf("%"_CMATH_PR_STD_INT"", coeff[i]); + i++; + } + + /* */ + puts("\n\nlist roots:"); + i = 0; + while (i < order+1) + { + dk_coeff[i] = (cnum_t)coeff[i]; + i++; + } + + durand_kerner(dk_coeff, dk_roots, order); + + i = 0; + while (i < order) + { + printf("root[%2d]: %.15f \t % .15f*i\n", + i+1, (double)dk_roots[i].r, (double)dk_roots[i].i); + i++; + } + + return 0; +} diff --git a/WDL/cmath/test_eval.c b/WDL/cmath/test_eval.c new file mode 100644 index 00000000..fabf9ff1 --- /dev/null +++ b/WDL/cmath/test_eval.c @@ -0,0 +1,87 @@ +/* + test_eval.h + Copyright (C) 2011 and later Lubomir I. Ivanov (neolit123 [at] gmail) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + test horner.h for complex numbers and other related headers + + gcc -W -Wall -Wextra -ansi pedantic + cl /W4 /Za + + reduced precisions for ansi c +*/ + +#include "stdio.h" +#include "complex_number.h" +#include "horner.h" +#include "durand_kerner.h" + +int main(void) +{ + cmath_uint16_t i = 0; + + cnum_t y[] = {2, -6, 2, -1}; + cnum_s cy[] = {{2, 0}, {-6, 0}, {2, 0}, {-1, 0}}; + + cnum_t fx = horner_eval(y, 5, poly_order(y)); + cnum_s fcx = horner_eval_c(cy, _CNUM(5, 0), poly_order(y)); + + cnum_t dk_coeff[] = {12, -7, 0.001, 0, 3, -5}; + cnum_s dk_roots[5]; + + cnum_s dk_coeff_c[] = {{12, 0}, {-7, 0}, {0.001, 0}, {0, 0}, {3, 0}, {-5, 0}}; + cnum_s dk_roots_c[5]; + + durand_kerner(dk_coeff, dk_roots, poly_order(dk_coeff)); + durand_kerner_c(dk_coeff_c, dk_roots_c, poly_order(dk_coeff_c)); + + /* */ + #ifdef _CMATH_ANSI + puts("\n\nansi c is: on"); + #else + puts("\n\nansi c is: off"); + #endif + + /* */ + puts("\n\nevaluate polynomials:\n"); + printf("* y[]: %.15f\n", (double)fx); + printf("* cy[]: %.15f \t %.15f*i\n", (double)fcx.r, (double)fcx.i); + + /* */ + puts("\nfind roots:"); + puts("\n* dk_coeff[]:"); + i = 0; + while (i < poly_order(dk_coeff)) + { + printf("root[%2d]: %.15f \t % .15f*i\n", + i+1, (double)dk_roots[i].r, (double)dk_roots[i].i); + i++; + } + i = 0; + puts("\n* dk_coeff_c[]:"); + while (i < poly_order(dk_coeff_c)) + { + printf("root[%2d]: %.15f \t % .15f*i\n", + i+1, (double)dk_roots_c[i].r, (double)dk_roots_c[i].i); + i++; + } + + return 0; +} diff --git a/WDL/convoengine.cpp b/WDL/convoengine.cpp new file mode 100644 index 00000000..204ed35e --- /dev/null +++ b/WDL/convoengine.cpp @@ -0,0 +1,1057 @@ +/* + WDL - convoengine.cpp + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include +#include "convoengine.h" + +#include "denormal.h" + +//#define TIMING +#include "timing.c" + +static void WDL_CONVO_CplxMul2(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_CONVO_IMPULSEBUFCPLXf *b, int n) +{ + WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + if (n<2 || (n&1)) return; + + do { + t1 = a[0].re * b[0].re; + t2 = a[0].im * b[0].im; + t3 = a[0].im * b[0].re; + t4 = a[0].re * b[0].im; + t5 = a[1].re * b[1].re; + t6 = a[1].im * b[1].im; + t7 = a[1].im * b[1].re; + t8 = a[1].re * b[1].im; + t1 -= t2; + t3 += t4; + t5 -= t6; + t7 += t8; + c[0].re = t1; + c[1].re = t5; + c[0].im = t3; + c[1].im = t7; + a += 2; + b += 2; + c += 2; + } while (n -= 2); +} +static void WDL_CONVO_CplxMul3(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_CONVO_IMPULSEBUFCPLXf *b, int n) +{ + WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + if (n<2 || (n&1)) return; + + do { + t1 = a[0].re * b[0].re; + t2 = a[0].im * b[0].im; + t3 = a[0].im * b[0].re; + t4 = a[0].re * b[0].im; + t5 = a[1].re * b[1].re; + t6 = a[1].im * b[1].im; + t7 = a[1].im * b[1].re; + t8 = a[1].re * b[1].im; + t1 -= t2; + t3 += t4; + t5 -= t6; + t7 += t8; + c[0].re += t1; + c[1].re += t5; + c[0].im += t3; + c[1].im += t7; + a += 2; + b += 2; + c += 2; + } while (n -= 2); +} + +static bool CompareQueueToBuf(WDL_FastQueue *q, const void *data, int len) +{ + int offs=0; + while (len>0) + { + void *td=NULL; + int sz=q->GetPtr(offs,&td); + if (sz<1) return true; // not enough data = not equal! + if (sz>len) sz=len; + + int i=sz/sizeof(WDL_FFT_REAL); + WDL_FFT_REAL *a1=(WDL_FFT_REAL*)td; + WDL_FFT_REAL *b1=(WDL_FFT_REAL*)data; + while (i--) + { + if (fabs(*a1-*b1)>1.0e-7) return true; + a1++; + b1++; + } + + data = ((char *)data)+sz; + offs+=sz; + len-=sz; + } + return false; +} + + +WDL_ConvolutionEngine::WDL_ConvolutionEngine() +{ + WDL_fft_init(); + m_impulse_nch=1; + m_fft_size=0; + m_impulse_len=0; + m_proc_nch=0; +} + +WDL_ConvolutionEngine::~WDL_ConvolutionEngine() +{ +} + +int WDL_ConvolutionEngine::SetImpulse(WDL_ImpulseBuffer *impulse, int fft_size, int impulse_sample_offset, int max_imp_size, bool forceBrute) +{ + int impulse_len=0; + int x; + int nch=impulse->GetNumChannels(); + for (x = 0; x < nch; x ++) + { + int l=impulse->impulses[x].GetSize()-impulse_sample_offset; + if (max_imp_size && l>max_imp_size) l=max_imp_size; + if (impulse_len < l) impulse_len=l; + } + m_impulse_nch=nch; + + if (m_impulse_nch>1) // detect mono signals pretending to be multichannel + { + for (x = 1; x < m_impulse_nch; x ++) + { + if (impulse->impulses[x].GetSize()!=impulse->impulses[0].GetSize()|| + memcmp(impulse->impulses[x].Get(),impulse->impulses[0].Get(), + impulse->impulses[0].GetSize()*sizeof(WDL_FFT_REAL))) + break; + } + if (x >= m_impulse_nch) m_impulse_nch=1; + } + + m_impulse_len=impulse_len; + m_proc_nch=-1; + + + if (forceBrute) + { + m_fft_size=0; + + // save impulse + for (x = 0; x < m_impulse_nch; x ++) + { + WDL_FFT_REAL *imp=impulse->impulses[x].Get()+impulse_sample_offset; + int lenout=impulse->impulses[x].GetSize()-impulse_sample_offset; + if (max_imp_size && lenout>max_imp_size) lenout=max_imp_size; + + WDL_CONVO_IMPULSEBUFf *impout=m_impulse[x].Resize(lenout)+lenout; + while (lenout-->0) *--impout = (WDL_CONVO_IMPULSEBUFf) *imp++; + } + + for (x = 0; x < WDL_CONVO_MAX_PROC_NCH; x ++) + { + m_samplesin[x].Clear(); + m_samplesin2[x].Clear(); + m_samplesout[x].Clear(); + } + + return 0; + } + + + if (fft_size<=0) + { + int msz=fft_size<=-16? -fft_size*2 : 32768; + + fft_size=32; + while (fft_size < impulse_len*2 && fft_size < msz) fft_size*=2; + } + + m_fft_size=fft_size; + + int impchunksize=fft_size/2; + int nblocks=(impulse_len+impchunksize-1)/impchunksize; + //char buf[512]; + //sprintf(buf,"il=%d, ffts=%d, cs=%d, nb=%d\n",impulse_len,fft_size,impchunksize,nblocks); + //OutputDebugString(buf); + + const bool smallerSizeMode=sizeof(WDL_CONVO_IMPULSEBUFf)!=sizeof(WDL_FFT_REAL); + + WDL_FFT_REAL scale=(WDL_FFT_REAL) (1.0/fft_size); + for (x = 0; x < m_impulse_nch; x ++) + { + WDL_FFT_REAL *imp=impulse->impulses[x].Get()+impulse_sample_offset; + + WDL_FFT_REAL *imp2=x < m_impulse_nch-1 ? impulse->impulses[x+1].Get()+impulse_sample_offset : NULL; + + WDL_CONVO_IMPULSEBUFf *impout=m_impulse[x].Resize((nblocks+!!smallerSizeMode)*fft_size*2); + char *zbuf=m_impulse_zflag[x].Resize(nblocks); + int lenout=impulse->impulses[x].GetSize()-impulse_sample_offset; + if (max_imp_size && lenout>max_imp_size) lenout=max_imp_size; + + int bl; + for (bl = 0; bl < nblocks; bl ++) + { + + int thissz=lenout; + if (thissz > impchunksize) thissz=impchunksize; + + lenout -= thissz; + int i=0; + WDL_FFT_REAL mv=0.0; + WDL_FFT_REAL mv2=0.0; + WDL_FFT_REAL *imptmp = (WDL_FFT_REAL *)impout; //-V615 + + for (; i < thissz; i ++) + { + WDL_FFT_REAL v=*imp++; + WDL_FFT_REAL v2=(WDL_FFT_REAL)fabs(v); + if (v2 > mv) mv=v2; + + imptmp[i*2]=denormal_filter_aggressive(v * scale); + + if (imp2) + { + v=*imp2++; + v2=(WDL_FFT_REAL)fabs(v); + if (v2>mv2) mv2=v2; + imptmp[i*2+1]=denormal_filter_aggressive(v*scale); + } + else imptmp[i*2+1]=0.0; + } + for (; i < fft_size; i ++) + { + imptmp[i*2]=0.0; + imptmp[i*2+1]=0.0; + } + if (mv>1.0e-14||mv2>1.0e-14) + { + *zbuf++=mv>1.0e-14 ? 2 : 1; // 1 means only second channel has content + WDL_fft((WDL_FFT_COMPLEX*)impout,fft_size,0); + + if (smallerSizeMode) + { + int x,n=fft_size*2; + for(x=0;x=m_impulse_nch) wch-=m_impulse_nch; + WDL_CONVO_IMPULSEBUFf *imp=m_impulse[wch].Get(); + int imp_len = m_impulse[wch].GetSize(); + + + if (imp_len>0) + { + if (m_samplesin2[ch].Available()mso) mso=so; + + if (x>=nch) + { + m_samplesin[x].Clear(); + m_samplesout[x].Clear(); + } + else + { + if (m_impulse_len<1||!nblocks) + { + if (m_samplesin[x].Available()) + { + int s=m_samplesin[x].Available(); + void *buf=m_samplesout[x].Add(NULL,s); + m_samplesin[x].GetToBuf(0,buf,s); + m_samplesin[x].Clear(); + } + } + + if (so < mso) + { + memset(m_samplesout[x].Add(NULL,mso-so),0,mso-so); + } + } + + int sz=0; + if (x=m_impulse_nch) srcc=m_impulse_nch-1; + + bool allow_mono_input_mode=true; + bool mono_impulse_mode=false; + + if (m_impulse_nch==1 && ch= sz && + m_samplesout[ch].Available() < want*(int)sizeof(WDL_FFT_REAL)) + { + int histpos; + if ((histpos=++m_hist_pos[ch]) >= nblocks) histpos=m_hist_pos[ch]=0; + + // get samples from input, to history + WDL_FFT_REAL *optr = m_samplehist[ch].Get()+histpos*m_fft_size*2; + + m_samplesin[ch].GetToBuf(0,optr+sz,in_needed*sizeof(WDL_FFT_REAL)); + m_samplesin[ch].Advance(in_needed*sizeof(WDL_FFT_REAL)); + + + bool mono_input_mode=false; + + bool nonzflag=false; + if (mono_impulse_mode) + { + if (++m_hist_pos[ch+1] >= nblocks) m_hist_pos[ch+1]=0; + m_samplesin[ch+1].GetToBuf(0,workbuf2,sz*sizeof(WDL_FFT_REAL)); + m_samplesin[ch+1].Advance(sz*sizeof(WDL_FFT_REAL)); + int i; + for (i = 0; i < sz; i ++) // unpack samples + { + WDL_FFT_REAL f = optr[i*2]=denormal_filter_aggressive(optr[sz+i]); + if (!nonzflag && (f<-1.0e-6 || f>1.0e-6)) nonzflag=true; + f=optr[i*2+1]=denormal_filter_aggressive(workbuf2[i]); + if (!nonzflag && (f<-1.0e-6 || f>1.0e-6)) nonzflag=true; + } + } + else + { + if (allow_mono_input_mode && + ch < m_proc_nch-1 && + srcc1.0e-6)) nonzflag=true; + } + } + + int i; + for (i = 1; mono_input_mode && i < nblocks; i ++) // start @ 1, since hist[histpos] is no longer used for here + { + int srchistpos = histpos-i; + if (srchistpos < 0) srchistpos += nblocks; + if (useSilentList[srchistpos]==2) mono_input_mode=false; + } + + if (nonzflag||!useSilentList) memset(optr+sz*2,0,sz*2*sizeof(WDL_FFT_REAL)); + + +#ifdef WDLCONVO_ZL_ACCOUNTING + m_zl_fftcnt++; +#endif + + if (nonzflag) WDL_fft((WDL_FFT_COMPLEX*)optr,m_fft_size,0); + + if (useSilentList) useSilentList[histpos]=nonzflag ? (mono_input_mode ? 1 : 2) : 0; + + int mzfl=2; + if (mono_input_mode) + { + mzfl=1; + + m_samplesin[ch+1].Advance(sz*sizeof(WDL_FFT_REAL)); + + // save a valid copy in sample hist incase we switch from mono to stereo + if (++m_hist_pos[ch+1] >= nblocks) m_hist_pos[ch+1]=0; + WDL_FFT_REAL *optr2 = m_samplehist[ch+1].Get()+m_hist_pos[ch+1]*m_fft_size*2; + memcpy(optr2,optr,m_fft_size*2*sizeof(WDL_FFT_REAL)); + } + + int applycnt=0; + char *useImpSilentList=m_impulse_zflag[srcc].GetSize() == nblocks ? m_impulse_zflag[srcc].Get() : NULL; + + WDL_CONVO_IMPULSEBUFf *impulseptr=m_impulse[srcc].Get(); + for (i = 0; i < nblocks; i ++, impulseptr+=m_fft_size*2) + { + int srchistpos = histpos-i; + if (srchistpos < 0) srchistpos += nblocks; + + if (useImpSilentList && useImpSilentList[i]32768) maxfft_size=32768; + + + const int MAX_SIZE_FOR_BRUTE=64; + + int fftsize = MAX_SIZE_FOR_BRUTE; + int impulsechunksize = MAX_SIZE_FOR_BRUTE; + + if (known_blocksize && !(known_blocksize&(known_blocksize-1)) && known_blocksize>MAX_SIZE_FOR_BRUTE*2) + { + fftsize=known_blocksize/2; + impulsechunksize=known_blocksize/2; + } + if (latency_allowed*2 > fftsize) + { + int x = 16; + while (x <= latency_allowed) x*=2; + if (x>32768) x=32768; + fftsize=impulsechunksize=x; + } + + int offs=0; + int samplesleft=impulse->impulses[0].GetSize()-impulse_offset; + if (max_imp_size>0 && samplesleft>max_imp_size) samplesleft=max_imp_size; + + do + { + WDL_ConvolutionEngine *eng=new WDL_ConvolutionEngine; + + bool wantBrute = !latency_allowed && !offs; + if (impulsechunksize*(wantBrute ? 2 : 3) >= samplesleft) impulsechunksize=samplesleft; // early-out, no point going to a larger FFT (since if we did this, we wouldnt have enough samples for a complete next pass) + if (fftsize>=maxfft_size) { impulsechunksize=samplesleft; fftsize=maxfft_size; } // if FFTs are as large as possible, finish up + + eng->SetImpulse(impulse,fftsize,offs+impulse_offset,impulsechunksize, wantBrute); + eng->m_zl_delaypos = offs; + eng->m_zl_dumpage=0; + m_engines.Add(eng); + +#ifdef WDLCONVO_ZL_ACCOUNTING + char buf[512]; + wsprintf(buf,"ce%d: offs=%d, len=%d, fftsize=%d\n",m_engines.GetSize(),offs,impulsechunksize,fftsize); + OutputDebugString(buf); +#endif + + samplesleft -= impulsechunksize; + offs+=impulsechunksize; + +#if 1 // this seems about 10% faster (maybe due to better cache use from less sized ffts used?) + impulsechunksize=offs*3; + fftsize=offs*2; +#else + impulsechunksize=fftsize; + + fftsize*=2; +#endif + } + while (samplesleft > 0); + + return GetLatency(); +} + +int WDL_ConvolutionEngine_Div::GetLatency() +{ + return m_engines.GetSize() ? m_engines.Get(0)->GetLatency() : 0; +} + + +void WDL_ConvolutionEngine_Div::Reset() +{ + int x; + for (x = 0; x < m_engines.GetSize(); x ++) + { + WDL_ConvolutionEngine *eng=m_engines.Get(x); + eng->Reset(); + } + for (x = 0; x < WDL_CONVO_MAX_PROC_NCH; x ++) + { + m_samplesout[x].Clear(); + } + + m_need_feedsilence=true; +} + +WDL_ConvolutionEngine_Div::~WDL_ConvolutionEngine_Div() +{ + timingPrint(); + m_engines.Empty(true); +} + +void WDL_ConvolutionEngine_Div::Add(WDL_FFT_REAL **bufs, int len, int nch) +{ + m_proc_nch=nch; + + bool ns=m_need_feedsilence; + m_need_feedsilence=false; + + int x; + for (x = 0; x < m_engines.GetSize(); x ++) + { + WDL_ConvolutionEngine *eng=m_engines.Get(x); + if (ns) + { + eng->m_zl_dumpage = (x>0 && x < m_engines.GetSize()-1) ? (eng->GetLatency()/4) : 0; // reduce max number of ffts per block by staggering them + + if (eng->m_zl_dumpage>0) + eng->Add(NULL,eng->m_zl_dumpage,nch); // added silence to input (to control when fft happens) + } + + eng->Add(bufs,len,nch); + + if (ns) eng->AddSilenceToOutput(eng->m_zl_delaypos,nch); // add silence to output (to delay output to its correct time) + + } +} +WDL_FFT_REAL **WDL_ConvolutionEngine_Div::Get() +{ + int x; + for (x = 0; x < m_proc_nch; x ++) + { + m_get_tmpptrs[x]=(WDL_FFT_REAL *)m_samplesout[x].Get(); + } + return m_get_tmpptrs; +} + +void WDL_ConvolutionEngine_Div::Advance(int len) +{ + int x; + for (x = 0; x < m_proc_nch; x ++) + { + m_samplesout[x].Advance(len*sizeof(WDL_FFT_REAL)); + m_samplesout[x].Compact(); + } +} + +int WDL_ConvolutionEngine_Div::Avail(int wantSamples) +{ + timingEnter(1); + int wso=wantSamples; + int x; +#ifdef WDLCONVO_ZL_ACCOUNTING + int cnt=0; + static int maxcnt=-1; + int h=0; +#endif + for (x = 0; x < m_engines.GetSize(); x ++) + { + WDL_ConvolutionEngine *eng=m_engines.Get(x); +#ifdef WDLCONVO_ZL_ACCOUNTING + eng->m_zl_fftcnt=0; +#endif + int a=eng->Avail(wso+eng->m_zl_dumpage) - eng->m_zl_dumpage; +#ifdef WDLCONVO_ZL_ACCOUNTING + cnt += !!eng->m_zl_fftcnt; + +#if 0 + if (eng->m_zl_fftcnt) + h|=1<m_zl_fftcnt && x==m_engines.GetSize()-1 && cnt>1) + { + char buf[512]; + wsprintf(buf,"fft flags=%08x (%08x=max)\n",h,1<maxcnt)maxcnt=cnt; + if (GetTickCount()>lastt+1000) + { + lastt=GetTickCount(); + char buf[512]; + wsprintf(buf,"maxcnt=%d\n",maxcnt); + OutputDebugString(buf); + maxcnt=-1; + } +#endif + if (wantSamples>0) + { + WDL_FFT_REAL *tp[WDL_CONVO_MAX_PROC_NCH]; + for (x =0; x < m_proc_nch; x ++) + { + memset(tp[x]=(WDL_FFT_REAL*)m_samplesout[x].Add(NULL,wantSamples*sizeof(WDL_FFT_REAL)),0,wantSamples*sizeof(WDL_FFT_REAL)); + } + + for (x = 0; x < m_engines.GetSize(); x ++) + { + WDL_ConvolutionEngine *eng=m_engines.Get(x); + if (eng->m_zl_dumpage>0) { eng->Advance(eng->m_zl_dumpage); eng->m_zl_dumpage=0; } + + WDL_FFT_REAL **p=eng->Get(); + if (p) + { + int i; + for (i =0; i < m_proc_nch; i ++) + { + WDL_FFT_REAL *o=tp[i]; + WDL_FFT_REAL *in=p[i]; + int j=wantSamples; + while (j-->0) *o++ += *in++; + } + } + eng->Advance(wantSamples); + } + } + timingLeave(1); + + int av=m_samplesout[0].Available()/sizeof(WDL_FFT_REAL); + return av>wso ? wso : av; +} + + +#ifdef WDL_TEST_CONVO + +#include + +int main(int argc, char **argv) +{ + if (argc!=5) + { + printf("usage: convoengine fftsize implen oneoffs pingoffs\n"); + return -1; + } + + int fftsize=atoi(argv[1]); + int implen = atoi(argv[2]); + int oneoffs = atoi(argv[3]); + int pingoffs=atoi(argv[4]); + + if (implen < 1 || oneoffs < 0 || oneoffs >= implen || pingoffs < 0) + { + printf("invalid parameters\n"); + return -1; + } + + WDL_ImpulseBuffer imp; + imp.nch=1; + memset(imp.impulses[0].Resize(implen),0,implen*sizeof(WDL_FFT_REAL)); + imp.impulses[0].Get()[oneoffs]=1.0; + + +#if WDL_TEST_CONVO==2 + WDL_ConvolutionEngine_Div engine; +#else + WDL_ConvolutionEngine engine; +#endif + engine.SetImpulse(&imp,fftsize); + WDL_TypedBuf m_tmpbuf; + memset(m_tmpbuf.Resize(pingoffs+1),0,pingoffs*sizeof(WDL_FFT_REAL)); + m_tmpbuf.Get()[pingoffs]=1.0; + WDL_FFT_REAL *p=m_tmpbuf.Get(); + engine.Add(&p,pingoffs+1,1); + + p=m_tmpbuf.Resize(4096); + memset(p,0,m_tmpbuf.GetSize()*sizeof(WDL_FFT_REAL)); + + int avail; + while ((avail=engine.Avail(pingoffs+oneoffs + 8192)) < pingoffs+oneoffs + 8192) + { + engine.Add(&p,4096,1); + } + WDL_FFT_REAL **output = engine.Get(); + if (!output || !*output) + { + printf("cant get output\n"); + return -1; + } + int x; + for (x = 0; x < avail; x ++) + { + WDL_FFT_REAL val=output[0][x]; + WDL_FFT_REAL expval = (x==pingoffs+oneoffs) ? 1.0:0.0; + if (fabs(val-expval)>0.000000001) + { + printf("%d: %.4fdB - %f %f\n",x,log10(max(val,0.000000000001))*20.0 - log10(max(expval,0.000000000001))*20.0,val,expval); + } + } + + return 0; +} + +#endif + + +int WDL_ImpulseBuffer::SetLength(int samples) +{ + int x; + for(x=0;xWDL_CONVO_MAX_IMPULSE_NCH) usench=WDL_CONVO_MAX_IMPULSE_NCH; + + if (usench > m_nch) + { + int len = GetLength(); + int x,ax=0; + for(x=m_nch;x impulses[WDL_CONVO_MAX_IMPULSE_NCH]; + +private: + int m_nch; + +}; + +class WDL_ConvolutionEngine +{ +public: + WDL_ConvolutionEngine(); + ~WDL_ConvolutionEngine(); + + int SetImpulse(WDL_ImpulseBuffer *impulse, int fft_size=-1, int impulse_sample_offset=0, int max_imp_size=0, bool forceBrute=false); + + int GetFFTSize() { return m_fft_size; } + int GetLatency() { return m_fft_size/2; } + + void Reset(); // clears out any latent samples + + void Add(WDL_FFT_REAL **bufs, int len, int nch); + + int Avail(int wantSamples); + WDL_FFT_REAL **Get(); // returns length valid + void Advance(int len); + +private: + WDL_TypedBuf m_impulse[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel + WDL_TypedBuf m_impulse_zflag[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel + + int m_impulse_nch; + int m_fft_size; + int m_impulse_len; + int m_proc_nch; + + WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH]; + WDL_Queue m_samplesin2[WDL_CONVO_MAX_PROC_NCH]; + WDL_FastQueue m_samplesin[WDL_CONVO_MAX_PROC_NCH]; + + int m_hist_pos[WDL_CONVO_MAX_PROC_NCH]; + + WDL_TypedBuf m_samplehist[WDL_CONVO_MAX_PROC_NCH]; // FFT'd sample blocks per channel + WDL_TypedBuf m_samplehist_zflag[WDL_CONVO_MAX_IMPULSE_NCH]; + WDL_TypedBuf m_overlaphist[WDL_CONVO_MAX_PROC_NCH]; + WDL_TypedBuf m_combinebuf; + + WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH]; + +public: + + // _div stuff + int m_zl_delaypos; + int m_zl_dumpage; + +//#define WDLCONVO_ZL_ACCOUNTING +#ifdef WDLCONVO_ZL_ACCOUNTING + int m_zl_fftcnt;//removeme (testing of benchmarks) +#endif + void AddSilenceToOutput(int len, int nch); + +} WDL_FIXALIGN; + +// low latency version +class WDL_ConvolutionEngine_Div +{ +public: + WDL_ConvolutionEngine_Div(); + ~WDL_ConvolutionEngine_Div(); + + int SetImpulse(WDL_ImpulseBuffer *impulse, int maxfft_size=0, int known_blocksize=0, int max_imp_size=0, int impulse_offset=0, int latency_allowed=0); + + int GetLatency(); + void Reset(); + + void Add(WDL_FFT_REAL **bufs, int len, int nch); + + int Avail(int wantSamples); + WDL_FFT_REAL **Get(); // returns length valid + void Advance(int len); + +private: + WDL_PtrList m_engines; + + WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH]; + WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH]; + + int m_proc_nch; + bool m_need_feedsilence; + +} WDL_FIXALIGN; + + +#endif \ No newline at end of file diff --git a/WDL/db2val.h b/WDL/db2val.h new file mode 100644 index 00000000..46abd76c --- /dev/null +++ b/WDL/db2val.h @@ -0,0 +1,22 @@ +#ifndef _WDL_DB2VAL_H_ +#define _WDL_DB2VAL_H_ + +#include + +#define TWENTY_OVER_LN10 8.6858896380650365530225783783321 +#define LN10_OVER_TWENTY 0.11512925464970228420089957273422 +#define DB2VAL(x) exp((x)*LN10_OVER_TWENTY) + +static inline double VAL2DB(double x) +{ + if (x < 0.0000000298023223876953125) return -150.0; + double v=log(x)*TWENTY_OVER_LN10; + return v<-150.0?-150.0:v; +} + +static inline double VAL2DB_EX(double x, double mindb) +{ + return x <= DB2VAL(mindb) ? mindb : (log(x)*TWENTY_OVER_LN10); +} + +#endif \ No newline at end of file diff --git a/WDL/denormal.h b/WDL/denormal.h new file mode 100644 index 00000000..d7dc4197 --- /dev/null +++ b/WDL/denormal.h @@ -0,0 +1,166 @@ +#ifndef _WDL_DENORMAL_H_ +#define _WDL_DENORMAL_H_ + +typedef struct +{ + #ifdef __ppc__ // todo: other big endian platforms... + unsigned int hw; + unsigned int lw; + #else + unsigned int lw; + unsigned int hw; + #endif +} WDL_DenormalTwoInts; + +typedef union { double fl; WDL_DenormalTwoInts w; } WDL_DenormalDoubleAccess; +typedef union { float fl; unsigned int w; } WDL_DenormalFloatAccess; + + +// note: the _aggressive versions filter out anything less than around 1.0e-16 or so (approximately) to 0.0, including -0.0 (becomes 0.0) +// note: new! the _aggressive versions also filter inf and NaN to 0.0 + +#ifdef __cplusplus +#define WDL_DENORMAL_INLINE inline +#elif defined(_MSC_VER) +#define WDL_DENORMAL_INLINE __inline +#else +#define WDL_DENORMAL_INLINE +#endif + +#define WDL_DENORMAL_DOUBLE_HW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.hw) +#define WDL_DENORMAL_DOUBLE_LW(a) (((const WDL_DenormalDoubleAccess*)(a))->w.lw) +#define WDL_DENORMAL_FLOAT_W(a) (((const WDL_DenormalFloatAccess*)(a))->w) + +#define WDL_DENORMAL_DOUBLE_HW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.hw) +#define WDL_DENORMAL_DOUBLE_LW_NC(a) (((WDL_DenormalDoubleAccess*)(a))->w.lw) +#define WDL_DENORMAL_FLOAT_W_NC(a) (((WDL_DenormalFloatAccess*)(a))->w) + +#define WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF 0x3cA00000 // 0x3B8000000 maybe instead? that's 10^-5 smaller or so +#define WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF 0x25000000 + + +static double WDL_DENORMAL_INLINE denormal_filter_double(double a) +{ + return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; +} + +static double WDL_DENORMAL_INLINE denormal_filter_double2(double a) +{ + return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) > 0x100000 ? a : 0.0; +} + +static double WDL_DENORMAL_INLINE denormal_filter_double_aggressive(double a) +{ + return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; +} + +static float WDL_DENORMAL_INLINE denormal_filter_float(float a) +{ + return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; +} + +static float WDL_DENORMAL_INLINE denormal_filter_float2(float a) +{ + return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) > 0x800000 ? a : 0.0f; +} + + +static float WDL_DENORMAL_INLINE denormal_filter_float_aggressive(float a) +{ + return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; +} +static void WDL_DENORMAL_INLINE denormal_fix_double(double *a) +{ + if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; +} + +static void WDL_DENORMAL_INLINE denormal_fix_double_aggressive(double *a) +{ + if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; +} + +static void WDL_DENORMAL_INLINE denormal_fix_float(float *a) +{ + if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; +} +static void WDL_DENORMAL_INLINE denormal_fix_float_aggressive(float *a) +{ + if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; +} + + + +#ifdef __cplusplus // automatic typed versions (though one should probably use the explicit versions... + + +static double WDL_DENORMAL_INLINE denormal_filter(double a) +{ + return (WDL_DENORMAL_DOUBLE_HW(&a)&0x7ff00000) ? a : 0.0; +} +static double WDL_DENORMAL_INLINE denormal_filter_aggressive(double a) +{ + return ((WDL_DENORMAL_DOUBLE_HW(&a)+0x100000)&0x7ff00000) >= WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF ? a : 0.0; +} + +static float WDL_DENORMAL_INLINE denormal_filter(float a) +{ + return (WDL_DENORMAL_FLOAT_W(&a)&0x7f800000) ? a : 0.0f; +} + +static float WDL_DENORMAL_INLINE denormal_filter_aggressive(float a) +{ + return ((WDL_DENORMAL_FLOAT_W(&a)+0x800000)&0x7f800000) >= WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF ? a : 0.0f; +} + +static void WDL_DENORMAL_INLINE denormal_fix(double *a) +{ + if (!(WDL_DENORMAL_DOUBLE_HW(a)&0x7ff00000)) *a=0.0; +} +static void WDL_DENORMAL_INLINE denormal_fix_aggressive(double *a) +{ + if (((WDL_DENORMAL_DOUBLE_HW(a)+0x100000)&0x7ff00000) < WDL_DENORMAL_DOUBLE_AGGRESSIVE_CUTOFF) *a=0.0; +} +static void WDL_DENORMAL_INLINE denormal_fix(float *a) +{ + if (!(WDL_DENORMAL_FLOAT_W(a)&0x7f800000)) *a=0.0f; +} +static void WDL_DENORMAL_INLINE denormal_fix_aggressive(float *a) +{ + if (((WDL_DENORMAL_FLOAT_W(a)+0x800000)&0x7f800000) < WDL_DENORMAL_FLOAT_AGGRESSIVE_CUTOFF) *a=0.0f; +} + + + +#endif // cplusplus versions + + + + +//////////////////// +// this isnt a denormal function but it is similar, so we'll put it here as a bonus + +static void WDL_DENORMAL_INLINE GetDoubleMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 +{ + unsigned int hw = WDL_DENORMAL_DOUBLE_HW(in)&0x7fffffff; + if (hw >= WDL_DENORMAL_DOUBLE_HW(out) && (hw>WDL_DENORMAL_DOUBLE_HW(out) || WDL_DENORMAL_DOUBLE_LW(in) > WDL_DENORMAL_DOUBLE_LW(out))) + { + WDL_DENORMAL_DOUBLE_LW_NC(out) = WDL_DENORMAL_DOUBLE_LW(in); + WDL_DENORMAL_DOUBLE_HW_NC(out) = hw; + } +} + +static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(float *out, const float *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 +{ + unsigned int hw = WDL_DENORMAL_FLOAT_W(in)&0x7fffffff; + if (hw > WDL_DENORMAL_FLOAT_W(out)) WDL_DENORMAL_FLOAT_W_NC(out)=hw; +} + + +#ifdef __cplusplus +static void WDL_DENORMAL_INLINE GetFloatMaxAbsValue(double *out, const double *in) // note: the value pointed to by "out" must be >=0.0, __NOT__ <= -0.0 +{ + GetDoubleMaxAbsValue(out,in); +} +#endif + +#endif diff --git a/WDL/des.cpp b/WDL/des.cpp new file mode 100644 index 00000000..cab4dd4e --- /dev/null +++ b/WDL/des.cpp @@ -0,0 +1,325 @@ +/* Loosely based on: + * + * D3DES (V5.09) - + * + * A portable, public domain, version of the Data Encryption Standard. + * + * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + */ + + +#include "des.h" + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; +static const unsigned char totrot[16] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +static unsigned int SP1[64] = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static unsigned int SP2[64] = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static unsigned int SP3[64] = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static unsigned int SP4[64] = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static unsigned int SP5[64] = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static unsigned int SP6[64] = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static unsigned int SP7[64] = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static unsigned int SP8[64] = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +WDL_DES::WDL_DES() +{ +} +WDL_DES::~WDL_DES() +{ +} + +void WDL_DES::SetKey(const unsigned char *key8, bool isEncrypt) +{ + int i; + unsigned char pc1m[56], pcr[56]; + for ( i = 0; i < 56; i++ ) + { + int l = pc1[i]; + int m = l & 07; + pc1m[i] = (key8[l >> 3] & (1<> 10) | + ((m_keydata[i+1] & 0x00000fc0) >> 6); + + unsigned int b= ((m_keydata[i] & 0x0003f000) << 12) | + ((m_keydata[i] & 0x0000003f) << 16) | + ((m_keydata[i+1] & 0x0003f000) >> 4) | + (m_keydata[i+1] & 0x0000003f); + m_keydata[i]=a; + m_keydata[i+1]=b; + } + + +} + +void WDL_DES::Process8(unsigned char *buf8) +{ + unsigned int leftt=(buf8[0]<<24)|(buf8[1]<<16)|(buf8[2]<<8)|(buf8[3]); + unsigned int right=(buf8[4]<<24)|(buf8[5]<<16)|(buf8[6]<<8)|(buf8[7]); + + unsigned int *keys = m_keydata; + unsigned int fval, work; + int round; + + work = ((leftt >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffff; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ff; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffff; + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffff; + + for (round = 0; round < 8; round++) + { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaa; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ff; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffff; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0f; + leftt ^= work; + right ^= (work << 4); + + buf8[0] = (right>>24)&0xff; + buf8[1] = (right>>16)&0xff; + buf8[2] = (right>>8)&0xff; + buf8[3] = (right)&0xff; + buf8[4] = (leftt>>24)&0xff; + buf8[5] = (leftt>>16)&0xff; + buf8[6] = (leftt>>8)&0xff; + buf8[7] = (leftt)&0xff; +} diff --git a/WDL/des.h b/WDL/des.h new file mode 100644 index 00000000..861bd015 --- /dev/null +++ b/WDL/des.h @@ -0,0 +1,34 @@ +/* Loosely based on: + * + * D3DES (V5.09) - + * + * A portable, public domain, version of the Data Encryption Standard. + * + * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + */ + + +#ifndef _WDL_DES_H_ +#define _WDL_DES_H_ + + +class WDL_DES +{ +public: + WDL_DES(); + ~WDL_DES(); + + void SetKey(const unsigned char *key8, bool isEncrypt); + + void Process8(unsigned char *buf8); + +private: + + unsigned int m_keydata[32]; + +}; + +#endif \ No newline at end of file diff --git a/WDL/destroycheck.h b/WDL/destroycheck.h new file mode 100644 index 00000000..d8deee3a --- /dev/null +++ b/WDL/destroycheck.h @@ -0,0 +1,65 @@ +#ifndef _WDL_DESTROYCHECK_H_ +#define _WDL_DESTROYCHECK_H_ + +// this is a useful class for verifying that an object (usually "this") hasn't been destroyed: +// to use it you add a WDL_DestroyState as a member of your class, then use the WDL_DestroyCheck +// helper class (creating it when the pointer is known valid, and checking it later to see if it +// is still valid). +// +// example: +// class myClass { +// WDL_DestroyState dest; +// ... +// }; +// +// calling code (on myClass *classInstnace): +// WDL_DestroyCheck chk(&classInstance->dest); +// somefunction(); +// if (!chk.isOK()) printf("classInstance got deleted!\n"); +// +// NOTE: only use this when these objects will be accessed from the same thread -- it will fail miserably +// in a multithreaded environment + + + + +class WDL_DestroyCheck +{ + public: + class WDL_DestroyStateNextRec { public: WDL_DestroyCheck *next; }; + + WDL_DestroyStateNextRec n, *prev; + WDL_DestroyCheck(WDL_DestroyStateNextRec *state) + { + n.next=NULL; + if ((prev=state)) + { + if ((n.next=prev->next)) n.next->prev = &n; + prev->next=this; + } + } + ~WDL_DestroyCheck() + { + if (prev) + { + prev->next = n.next; + if (n.next) n.next->prev = prev; + } + } + + bool isOK() { return !!prev; } +}; + +class WDL_DestroyState : public WDL_DestroyCheck::WDL_DestroyStateNextRec +{ + public: + WDL_DestroyState() { next=NULL; } + + ~WDL_DestroyState() + { + WDL_DestroyCheck *p = next; + while (p) { WDL_DestroyCheck *np = p->n.next; p->prev=NULL; p->n.next=NULL; p=np; } + } +}; + +#endif diff --git a/WDL/dirscan.h b/WDL/dirscan.h new file mode 100644 index 00000000..a03a62bf --- /dev/null +++ b/WDL/dirscan.h @@ -0,0 +1,245 @@ +/* + WDL - dirscan.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides the interface and implementation for WDL_DirScan, a simple + (and somewhat portable) directory reading class. On non-Win32 systems it wraps + opendir()/readdir()/etc. On Win32, it uses FindFirst*, and supports wildcards as + well. + + +*/ + + +#ifndef _WDL_DIRSCAN_H_ +#define _WDL_DIRSCAN_H_ + +#include "wdlstring.h" + +#ifndef _WIN32 +#include +#include +#include +#endif + +class WDL_DirScan +{ + public: + WDL_DirScan() : +#ifdef _WIN32 + m_h(INVALID_HANDLE_VALUE) + #ifndef WDL_NO_SUPPORT_UTF8 + , m_wcmode(false) + #endif +#else + m_h(NULL), m_ent(NULL) +#endif + { + } + + ~WDL_DirScan() + { + Close(); + } + + int First(const char *dirname +#ifdef _WIN32 + , int isExactSpec=0 +#endif + ) // returns 0 if success + { + int l=strlen(dirname); + if (l < 1) return -1; + + WDL_String scanstr(dirname); +#ifdef _WIN32 + if (!isExactSpec) +#endif + if (dirname[l-1] == '\\' || dirname[l-1] == '/') scanstr.SetLen(l-1); + + m_leading_path.Set(scanstr.Get()); + +#ifdef _WIN32 + if (!isExactSpec) scanstr.Append("\\*"); + else + { + // remove trailing stuff from m_leading_path + char *p=m_leading_path.Get(); + while (*p) p++; + while (p > m_leading_path.Get() && *p != '/' && *p != '\\') p--; + if (p > m_leading_path.Get()) *p=0; + } +#else + if (l && !scanstr.Get()[0]) + scanstr.Set("/"); // fix for scanning / +#endif + + Close(); +#ifdef _WIN32 + #ifndef WDL_NO_SUPPORT_UTF8 + m_h=INVALID_HANDLE_VALUE; + m_wcmode = GetVersion()< 0x80000000; + + if (m_wcmode) + { + int reqbuf = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,NULL,0); + if (reqbuf > 1000) + { + WDL_TypedBuf tmp; + tmp.Resize(reqbuf+10); + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,tmp.Get(),tmp.GetSize())) + m_h=FindFirstFileW(tmp.Get(),&m_fd); + } + else + { + WCHAR wfilename[1024]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,scanstr.Get(),-1,wfilename,1024)) + m_h=FindFirstFileW(wfilename,&m_fd); + } + } + + if (m_h==INVALID_HANDLE_VALUE) m_wcmode=false; + + if (m_h==INVALID_HANDLE_VALUE) + #endif + m_h=FindFirstFile(scanstr.Get(),(WIN32_FIND_DATA*)&m_fd); + return (m_h == INVALID_HANDLE_VALUE); +#else + m_ent=0; + m_h=opendir(scanstr.Get()); + return !m_h || Next(); +#endif + } + int Next() // returns 0 on success + { +#ifdef _WIN32 + if (m_h == INVALID_HANDLE_VALUE) return -1; + #ifndef WDL_NO_SUPPORT_UTF8 + if (m_wcmode) return !FindNextFileW(m_h,&m_fd); + #endif + return !FindNextFile(m_h,(WIN32_FIND_DATA*)&m_fd); +#else + if (!m_h) return -1; + return !(m_ent=readdir(m_h)); +#endif + } + void Close() + { +#ifdef _WIN32 + if (m_h != INVALID_HANDLE_VALUE) FindClose(m_h); + m_h=INVALID_HANDLE_VALUE; +#else + if (m_h) closedir(m_h); + m_h=0; m_ent=0; +#endif + } + +#ifdef _WIN32 + char *GetCurrentFN() + { +#ifndef WDL_NO_SUPPORT_UTF8 + if (m_wcmode) + { + if (!WideCharToMultiByte(CP_UTF8,0,m_fd.cFileName,-1,m_tmpbuf,sizeof(m_tmpbuf),NULL,NULL)) + m_tmpbuf[0]=0; + return m_tmpbuf; + } +#endif + return ((WIN32_FIND_DATA *)&m_fd)->cFileName; + } +#else + char *GetCurrentFN() const { return m_ent?m_ent->d_name : (char *)""; } +#endif + void GetCurrentFullFN(WDL_String *str) + { + str->Set(m_leading_path.Get()); +#ifdef _WIN32 + str->Append("\\"); +#else + str->Append("/"); +#endif + str->Append(GetCurrentFN()); + } + int GetCurrentIsDirectory() const + { +#ifdef _WIN32 + return !!(m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); +#else + return m_ent && (m_ent->d_type & DT_DIR); +#endif + } + + // these are somewhat windows specific calls, eh +#ifdef _WIN32 + DWORD GetCurrentFileSize(DWORD *HighWord=NULL) const { if (HighWord) *HighWord = m_fd.nFileSizeHigh; return m_fd.nFileSizeLow; } + void GetCurrentLastWriteTime(FILETIME *ft) const { *ft = m_fd.ftLastWriteTime; } + void GetCurrentLastAccessTime(FILETIME *ft) const { *ft = m_fd.ftLastAccessTime; } + void GetCurrentCreationTime(FILETIME *ft) const { *ft = m_fd.ftCreationTime; } +#elif defined(_WDL_SWELL_H_) + + // todo: compat for more of these functions + + void GetCurrentLastWriteTime(FILETIME *ft) + { + WDL_String tmp; + GetCurrentFullFN(&tmp); + struct stat st={0,}; + stat(tmp.Get(),&st); + unsigned long long a=(unsigned long long)st.st_mtime; // seconds since january 1st, 1970 + a+=((unsigned long long)(60*60*24*(365*4+1)/4))*(unsigned long long)(1970-1601); // this is approximate + a*=1000*10000; // seconds to 1/10th microseconds (100 nanoseconds) + ft->dwLowDateTime=a & 0xffffffff; + ft->dwHighDateTime=a>>32; + } + DWORD GetCurrentFileSize(DWORD *HighWord=NULL) + { + WDL_String tmp; + GetCurrentFullFN(&tmp); + struct stat st={0,}; + stat(tmp.Get(),&st); + + if (HighWord) *HighWord = (DWORD)(st.st_size>>32); + return (DWORD)(st.st_size&0xffffffff); + } + +#endif + + private: +#ifdef _WIN32 + +#ifndef WDL_NO_SUPPORT_UTF8 + bool m_wcmode; + WIN32_FIND_DATAW m_fd; + char m_tmpbuf[MAX_PATH*5]; // even if each byte gets encoded as 4 utf-8 bytes this should be plenty ;) +#else + WIN32_FIND_DATA m_fd; +#endif + HANDLE m_h; +#else + DIR *m_h; + struct dirent *m_ent; +#endif + WDL_String m_leading_path; +} WDL_FIXALIGN; + +#endif diff --git a/WDL/eel2/.gitignore b/WDL/eel2/.gitignore new file mode 100644 index 00000000..6e582baf --- /dev/null +++ b/WDL/eel2/.gitignore @@ -0,0 +1 @@ +!asm-nseel-x64-macho.o diff --git a/WDL/eel2/Makefile b/WDL/eel2/Makefile new file mode 100644 index 00000000..952b939b --- /dev/null +++ b/WDL/eel2/Makefile @@ -0,0 +1,22 @@ +CC=gcc +CFLAGS=-O -g +CXX=g++ + +OBJS=nseel-caltab.o nseel-compiler.o nseel-eval.o nseel-lextab.o nseel-ram.o nseel-yylex.o + +default: test + +nseel-compiler.o: glue*.h +nseel-cfunc.o: asm*.c + +ifdef PORTABLE + CFLAGS += -DEEL_TARGET_PORTABLE + OBJS += nseel-cfunc.o +endif +CXXFLAGS=$(CFLAGS) + +test: test.o $(OBJS) + g++ -o $@ $^ $(CXXFLAGS) + +clean: + -rm test.o $(OBJS) diff --git a/WDL/eel2/a2i.php b/WDL/eel2/a2i.php new file mode 100644 index 00000000..cf0e620a --- /dev/null +++ b/WDL/eel2/a2i.php @@ -0,0 +1,243 @@ +1) + $end_restore = substr($line,1-strlen($lastchunk)); + else $end_restore=""; + + $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); + + // get rid of chars we can ignore + $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); + + $sline=str_replace("\\n","", $sline); + $sline=str_replace("\"","", $sline); + $sline=str_replace("$","", $sline); + $sline=str_replace("%","", $sline); + + + // get rid of excess whitespace, especially around commas + $sline=str_replace(" "," ", $sline); + $sline=str_replace(" "," ", $sline); + $sline=str_replace(" "," ", $sline); + $sline=str_replace(", ",",", $sline); + $sline=str_replace(" ,",",", $sline); + + $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); + + + if (preg_match("/^([0-9]+):/",trim($sline))) + { + $d = (int) $sline; + $a = strstr($sline,":"); + if ($a) $sline = substr($a,1); + + if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; + else $thislbl = "label_" . $labelcnt++; + + $btfut[$d]=""; + $bthist[$d] = $thislbl; + + fputs($out,$thislbl . ":\n"); + } + + $sploded = explode(" ",trim($sline)); + if ($sline != "" && count($sploded)>0) + { + $inst = trim($sploded[0]); + $suffix = ""; + + $instline = strstr($sline,$inst); + $beg_restore .= substr($sline,0,-strlen($instline)); + + $parms = trim(substr($instline,strlen($inst))); + + if ($inst=="j") $inst="jmp"; + + //if ($inst == "fdiv" && $parms == "") $inst="fdivr"; + + if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; + else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; + else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fabs" && $inst != "fchs" && substr($inst,-1) == "s") $suffix = "s"; + + + if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); + + $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); + + $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","EEL_ASM_TYPE [$2+$1]",$parms); + $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","EEL_ASM_TYPE [$1]",$parms); + + if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } + + if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword ptr "; + else if ($suffix == "l") $suffixstr = "dword ptr "; + else if ($suffix == "s") $suffixstr = "dword ptr "; + else $suffixstr = ""; + $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); + $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); + + + $parms=str_replace("NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR","NSEEL_LOOPFUNC_SUPPORT_MAXLEN", $parms); + $parms=str_replace("EEL_F_SUFFIX","EEL_ASM_TYPE", $parms); + $parms=str_replace("EEL_F_SSTR","EEL_F_SIZE", $parms); + + $plist = explode(",",$parms); + if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; + else if (count($plist)==2) + { + $parms = trim($plist[1]) . ", " . trim($plist[0]); + } + else + { + } + + if ($inst=="fsts") $inst="fstsw"; + if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); + if (substr($inst,0,1) == "j") + { + if (substr($parms,-1) == "f") + { + $d = (int) substr($parms,0,-1); + if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; + else $btfut[$d] = $thislbl = "label_" . $labelcnt++; + $parms = $thislbl; + } + else if (substr($parms,-1) == "b") + { + $d = (int) substr($parms,0,-1); + if ($bthist[$d]=="") echo "Error resolving label $parms\n"; + $parms = $bthist[$d]; + } + } + if (stristr($parms,"[0xfefefefe]")) + { + if ($inst == "fmul" || $inst=="fadd" || $inst == "fcomp") + { + if ($inst=="fmul") $hdr="0x0D"; + if ($inst=="fadd") $hdr="0x05"; + if ($inst=="fcomp") $hdr="0x1D"; + + fputs($out,"#if EEL_F_SIZE == 8\n"); + fputs($out,"_emit 0xDC; // $inst qword ptr [0xfefefefe]\n"); + fputs($out,"_emit $hdr;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"#else\n"); + fputs($out,"_emit 0xD8; // $inst dword ptr [0xfefefefe]\n"); + fputs($out,"_emit $hdr;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"_emit 0xFE;\n"); + fputs($out,"#endif\n"); + $nowrite=1; + } + } + + + $sline = $inst; + if ($parms !="") $sline .= " " . $parms; + $sline .= ";"; + + } + + $sline=preg_replace("/FPREG_([0-9]+)/","st($1)",$sline); + $line = $beg_restore . $sline . $end_restore; + + } + + + } + } + + if (!$nowrite) + { + if (strstr($line,"__TEMP_REPLACE__")) + { + $a = strstr($line,"//REPLACE="); + if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); + $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); + } + fputs($out,$line . "\n"); + } +} + +if ($inblock) echo "Error (ended in __asm__ block???)\n"; + + +fclose($in); +fclose($out); + +}; + +process_file("asm-nseel-x86-gcc.c" , "asm-nseel-x86-msvc.c"); +// process_file("asm-miscfunc-x86-gcc.c" , "asm-miscfunc-x86-msvc.c"); +//process_file("asm-megabuf-x86-gcc.c" , "asm-megabuf-x86-msvc.c"); + +?> diff --git a/WDL/eel2/a2x64.php b/WDL/eel2/a2x64.php new file mode 100644 index 00000000..c3142b8c --- /dev/null +++ b/WDL/eel2/a2x64.php @@ -0,0 +1,305 @@ +1) + $end_restore = substr($line,1-strlen($lastchunk)); + else $end_restore=""; + + $sline = substr($sline,1,strlen($sline)-1-strlen($lastchunk)); + + $sline=preg_replace("/%\d+/","__TEMP_REPLACE__", $sline); + + // get rid of chars we can ignore + $sline=str_replace("\\n","", $sline); + $sline=str_replace("\"","", $sline); + $sline=str_replace("$","", $sline); + $sline=str_replace("%","", $sline); + + + // get rid of excess whitespace, especially around commas + $sline=str_replace(" "," ", $sline); + $sline=str_replace(" "," ", $sline); + $sline=str_replace(" "," ", $sline); + $sline=str_replace(", ",",", $sline); + $sline=str_replace(" ,",",", $sline); + + $sline=preg_replace("/st\\(([0-9]+)\\)/","FPREG_$1",$sline); + + + if (preg_match("/^([0-9]+):/",trim($sline))) + { + $d = (int) $sline; + $a = strstr($sline,":"); + if ($a) $sline = substr($a,1); + + if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; + else $thislbl = "label_" . $labelcnt++; + + $btfut[$d]=""; + $bthist[$d] = $thislbl; + + fputs($out,$thislbl . ":\n"); + } + + $sploded = explode(" ",trim($sline)); + if ($sline != "" && count($sploded)>0) + { + $inst = trim($sploded[0]); + $suffix = ""; + + $instline = strstr($sline,$inst); + $beg_restore .= substr($sline,0,-strlen($instline)); + + $parms = trim(substr($instline,strlen($inst))); + + if ($inst=="j") $inst="jmp"; + +// if ($inst == "fdiv" && $parms == "") $inst="fdivr"; + + if ($inst != "call" && substr($inst,-2) == "ll") $suffix = "ll"; + else if ($inst != "call" && $inst != "fmul" && substr($inst,-1) == "l") $suffix = "l"; + else if (substr($inst,0,1)=="f" && $inst != "fcos" && $inst != "fsincos" && $inst != "fchs" && $inst != "fabs" && substr($inst,-1) == "s") $suffix = "s"; + + + if ($suffix != "" && $inst != "jl") $inst = substr($inst,0,-strlen($suffix)); + + $parms = preg_replace("/\\((.{2,3}),(.{2,3})\\)/","($1+$2)",$parms); + + $parms=preg_replace("/EEL_F_SUFFIX (-?[0-9]+)\\((.*)\\)/","qword [$2+$1]",$parms); + $parms=preg_replace("/EEL_F_SUFFIX \\((.*)\\)/","qword [$1]",$parms); + + if ($inst == "sh" && $suffix == "ll") { $suffix="l"; $inst="shl"; } + + if ($suffix == "ll" || ($suffix == "l" && substr($inst,0,1) == "f" && substr($inst,0,2) != "fi")) $suffixstr = "qword "; + else if ($suffix == "l") $suffixstr = "dword "; + else if ($suffix == "s") $suffixstr = "dword "; + else $suffixstr = ""; + $parms=preg_replace("/(-?[0-9]+)\\((.*)\\)/",$suffixstr . "[$2+$1]",$parms); + $parms=preg_replace("/\\((.*)\\)/",$suffixstr . "[$1]",$parms); + + + $parms=str_replace("NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR","10000000", $parms); + $parms=str_replace("EEL_F_SUFFIX","qword", $parms); + $parms=str_replace("EEL_F_SSTR","8", $parms); + + $plist = explode(",",$parms); + if (count($plist) > 2) echo "Warning: too many parameters $parms!\n"; + else if (count($plist)==2) + { + if ($suffixstr != "dword " || strstr($plist[0],"[")) + makeregs64($plist[0]); + if ($suffixstr != "dword " || stristr($plist[0],"ffffffff") || strstr($plist[1],"[")) makeregs64($plist[1]); + + if (!stristr($plist[0],"[") && + !stristr($plist[1],"[")) { makeregs64($plist[1]); makeregs64($plist[0]); } + + $parms = trim($plist[1]) . ", " . trim($plist[0]); + } + else + { + // if ($suffixstr != "dword ") + makeregs64($parms); + } + + if ($inst=="fsts") $inst="fstsw"; + if ($inst=="fistp") $inst="fisttp"; + if ($inst=="call" && substr($parms,0,1) == "*") $parms=substr($parms,1); + if (substr($inst,0,1) == "j") + { + if (substr($parms,-1) == "f") + { + $d = (int) substr($parms,0,-1); + if (isset($btfut[$d]) && $btfut[$d] != "") $thislbl = $btfut[$d]; + else $btfut[$d] = $thislbl = "label_" . $labelcnt++; + $parms = $thislbl; + } + else if (substr($parms,-1) == "b") + { + $d = (int) substr($parms,0,-1); + if ($bthist[$d]=="") echo "Error resolving label $parms\n"; + $parms = $bthist[$d]; + } + } + $parms = preg_replace("/0x[fe,FE]{8}/","qword 0xFEFEFEFEFEFEFEFE",$parms); + + + + $sline = $inst; + if ($parms !="") $sline .= " " . $parms; + + } + + $sline=preg_replace("/FPREG_([0-9]+)/","st$1",$sline); + $line = $beg_restore . $sline . $end_restore; + + } + + + } + } + + if ($inblock) + { + if (strstr($line,"__TEMP_REPLACE__")) + { + $a = strstr($line,"; REPLACE="); + if ($a === false) die ("__TEMP_REPLACE__ found, no REPLACE=\n"); + $line=str_replace("__TEMP_REPLACE__",substr($a,10),$line); + } + fputs($out,$line . "\n"); + } +} + +if ($inblock) echo "Error (ended in __asm__ block???)\n"; + + +fclose($in); +fclose($out); + +}; + +$nasm="nasm"; +$want_funclead=""; + +$fmt = "win64"; +if (isset($argv[1]) && $argv[1] != "") $fmt = $argv[1]; + +$fnout = "asm-nseel-x64.asm"; + +if ($fmt == "macho64") { $fnout="asm-nseel-x64-macho.asm"; $nasm = "nasm64"; $want_funclead = "_"; } +if ($fmt == "macho64x") { $fnout="asm-nseel-x64-macho.asm"; $nasm = "nasm"; $want_funclead = "_"; $fmt="macho64"; } +if ($fmt == "win64x") { $nasm="nasm64"; $fmt = "win64"; } + +process_file("asm-nseel-x86-gcc.c" , $fnout, $fmt != "win64" ? "%define AMD64ABI\n" : ""); + + +system("$nasm -f $fmt $fnout"); + +?> diff --git a/WDL/eel2/asm-nseel-ppc-gcc.c b/WDL/eel2/asm-nseel-ppc-gcc.c new file mode 100644 index 00000000..3ce27e36 --- /dev/null +++ b/WDL/eel2/asm-nseel-ppc-gcc.c @@ -0,0 +1,1377 @@ +#define FUNCTION_MARKER "mr r0, r0\n" \ + "mr r1, r1\n" \ + "mr r2, r2\n" + +#if EEL_F_SIZE == 8 + +void nseel_asm_1pdd(void) +{ + + __asm__( + FUNCTION_MARKER + "addis r5, 0, 0xdead\n" + "ori r5, r5, 0xbeef\n" + "mtctr r5\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: ); +} +void nseel_asm_1pdd_end(void){} + +void nseel_asm_2pdd(void) +{ + + __asm__( + FUNCTION_MARKER + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "fmr f2, f1\n" + "lfd f1, 0(r14)\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: ); +}; +void nseel_asm_2pdd_end(void){} + +void nseel_asm_2pdds(void) +{ + __asm__( + FUNCTION_MARKER + "addis r5, 0, 0xdead\n" + "ori r5, r5, 0xbeef\n" + "fmr f2, f1\n" + "lfd f1, 0(r14)\n" + "mtctr r5\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + "stfd f1, 0(r14)\n" + "mr r3, r14\n" + FUNCTION_MARKER + :: ); +} +void nseel_asm_2pdds_end(void){} + +#else // 32 bit floating point calls + +#error no 32 bit float support + +#endif + +//--------------------------------------------------------------------------------------------------------------- + + + +// do nothing, eh +void nseel_asm_exec2(void) +{ + __asm__( + FUNCTION_MARKER + FUNCTION_MARKER + ); +} +void nseel_asm_exec2_end(void) { } + + + +void nseel_asm_invsqrt(void) +{ + __asm__( + FUNCTION_MARKER + "frsqrte f1, f1\n" // less accurate than our x86 equivilent, but invsqrt() is inherently inaccurate anyway + FUNCTION_MARKER + ); +} +void nseel_asm_invsqrt_end(void) {} + +void nseel_asm_dbg_getstackptr(void) +{ + __asm__( + FUNCTION_MARKER + "addis r11, 0, 0x4330\n" + "xoris r10, r1, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_dbg_getstackptr_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_sqr(void) +{ + __asm__( + FUNCTION_MARKER + "fmul f1, f1, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_sqr_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_abs(void) +{ + __asm__( + FUNCTION_MARKER + "fabs f1, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_abs_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_assign(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f1, 0(r3)\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_assign_end(void) {} +// +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_assign_fromfp(void) +{ + __asm__( + FUNCTION_MARKER + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_assign_fromfp_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_assign_fast(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f1, 0(r3)\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_assign_fast_end(void) {} +// +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_assign_fast_fromfp(void) +{ + __asm__( + FUNCTION_MARKER + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_assign_fast_fromfp_end(void) {} + + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_add(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fadd f1, f1, f2\n" + FUNCTION_MARKER + ); +} +void nseel_asm_add_end(void) {} + +void nseel_asm_add_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fadd f1, f1, f2\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_add_op_end(void) {} + +void nseel_asm_add_op_fast(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fadd f1, f1, f2\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_add_op_fast_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_sub(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fsub f1, f2, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_sub_end(void) {} + +void nseel_asm_sub_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fsub f1, f2, f1\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_sub_op_end(void) {} + +void nseel_asm_sub_op_fast(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fsub f1, f2, f1\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_sub_op_fast_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_mul(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fmul f1, f2, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_mul_end(void) {} + +void nseel_asm_mul_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fmul f1, f2, f1\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_mul_op_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_div(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fdiv f1, f2, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_div_end(void) {} + +void nseel_asm_div_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fdiv f1, f2, f1\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_div_op_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_mod(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fabs f1, f1\n" + "fabs f2, f2\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + + "divw r12, r11, r10\n" + "mullw r12, r12, r10\n" + "subf r10, r12, r11\n" + + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_mod_end(void) {} + +void nseel_asm_shl(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "slw r10, r11, r10\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_shl_end(void) {} + +void nseel_asm_shr(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "sraw r10, r11, r10\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_shr_end(void) {} + +void nseel_asm_mod_op(void) +{ + + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fabs f1, f1\n" + "fabs f2, f2\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + + "divw r12, r11, r10\n" + "mullw r12, r12, r10\n" + "subf r10, r12, r11\n" + + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); + +} +void nseel_asm_mod_op_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_or(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "or r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_or_end(void) {} + +void nseel_asm_or0(void) +{ + __asm__( + FUNCTION_MARKER + "fctiwz f1, f1\n" + "addis r11, 0, 0x4330\n" + "stfd f1, -8(r1)\n" + "lwz r10, -4(r1)\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_or0_end(void) {} + +void nseel_asm_or_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "or r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_or_op_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_xor(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "xor r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + ); +} +void nseel_asm_xor_end(void) {} + +void nseel_asm_xor_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "xor r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_xor_op_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_and(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "and r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + FUNCTION_MARKER + );} +void nseel_asm_and_end(void) {} + +void nseel_asm_and_op(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fctiwz f1, f1\n" + "fctiwz f2, f2\n" + "stfd f1, -8(r1)\n" + "stfd f2, -16(r1)\n" + "lwz r10, -4(r1)\n" + "lwz r11, -12(r1)\n" //r11 and r12 have the integers + "and r10, r10, r11\n" // r10 has the result + "addis r11, 0, 0x4330\n" + "xoris r10, r10, 0x8000\n" + "stw r11, -8(r1)\n" // 0x43300000 + "stw r10, -4(r1)\n" // our integer sign flipped + "lfd f1, -8(r1)\n" + "fsub f1, f1, f30\n" + "mr r3, r14\n" + "stfd f1, 0(r14)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_and_op_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_uplus(void) // this is the same as doing nothing, it seems +{ + __asm__( + FUNCTION_MARKER + FUNCTION_MARKER + ); +} +void nseel_asm_uplus_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_uminus(void) +{ + __asm__( + FUNCTION_MARKER + "fneg f1, f1\n" + FUNCTION_MARKER + ); +} +void nseel_asm_uminus_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_sign(void) +{ + __asm__( + FUNCTION_MARKER + "li r9, 0\n" + "stw r9, -4(r1)\n" + "lis r9, 0xbf80\n" // -1 in float + "lfs f2, -4(r1)\n" + + "fcmpu cr7, f1, f2\n" + "blt- cr7, 0f\n" + "ble- cr7, 1f\n" + " lis r9, 0x3f80\n" // 1 in float + "0:\n" + " stw r9, -4(r1)\n" + " lfs f1, -4(r1)\n" + "1:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_sign_end(void) {} + + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_bnot(void) +{ + __asm__( + FUNCTION_MARKER + "cmpwi cr0, r3, 0\n" + "addis r3, 0, 0\n" + "bne cr0, 0f\n" + "addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + ); +} +void nseel_asm_bnot_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_if(void) +{ + __asm__( + FUNCTION_MARKER + "cmpwi cr0, r3, 0\n" + "beq cr0, 0f\n" + " addis r6, 0, 0xdead\n" + " ori r6, r6, 0xbeef\n" + " mtctr r6\n" + " bctrl\n" + "b 1f\n" + "0:\n" + " addis r6, 0, 0xdead\n" + " ori r6, r6, 0xbeef\n" + " mtctr r6\n" + " bctrl\n" + "1:\n" + FUNCTION_MARKER + :: ); +} +void nseel_asm_if_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_repeat(void) +{ + __asm__( + FUNCTION_MARKER + "fctiwz f1, f1\n" + "stfd f1, -8(r1)\n" + "lwz r5, -4(r1)\n" // r5 has count now + "cmpwi cr0, r5, 0\n" + "ble cr0, 1f\n" // skip the loop + + "addis r7, 0, ha16(%0)\n" + "addi r7, r7, lo16(%0)\n" + + "stwu r16, -16(r1)\n" // set up the stack for the loop, save r16 + + "cmpw cr0, r7, r5\n" + "bge cr0, 0f\n" + "mr r5, r7\n" // set r5 to max if we have to +"0:\n" + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" + + "addi r5, r5, -1\n" + "stw r5, 4(r1)\n" + + "mtctr r6\n" + "bctrl\n" + + "lwz r16, 0(r1)\n" + "lwz r5, 4(r1)\n" + + "cmpwi cr0, r5, 0\n" + "bgt cr0, 0b\n" + + "addi r1, r1, 16\n" // restore old stack + + "1:\n" + FUNCTION_MARKER + ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) + ); +} +void nseel_asm_repeat_end(void) {} + +void nseel_asm_repeatwhile(void) +{ + __asm__( + FUNCTION_MARKER + "stwu r16, -16(r1)\n" // save r16 to stack, update stack + "addis r5, 0, ha16(%0)\n" + "addi r5, r5, lo16(%0)\n" +"0:\n" + + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" + "stw r5, 4(r1)\n" // save maxcnt + + "mtctr r6\n" + "bctrl\n" + + "lwz r16, 0(r1)\n" // restore r16 + "lwz r5, 4(r1)\n" // restore, check maxcnt + + "cmpwi cr7, r3, 0\n" // check return value + "addi r5, r5, -1\n" + + "beq cr7, 1f\n" + + "cmpwi cr0, r5, 0\n" + "bgt cr0, 0b\n" + "1:\n" + "addi r1, r1, 16\n" // restore stack + FUNCTION_MARKER + ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN) + ); +} +void nseel_asm_repeatwhile_end(void) {} + + +void nseel_asm_band(void) +{ + __asm__( + FUNCTION_MARKER + "cmpwi cr7, r3, 0\n" + "beq cr7, 0f\n" + " addis r6, 0, 0xdead\n" + " ori r6, r6, 0xbeef\n" + " mtctr r6\n" + " bctrl\n" + "0:\n" + FUNCTION_MARKER + :: ); +} +void nseel_asm_band_end(void) {} + +void nseel_asm_bor(void) +{ + __asm__( + FUNCTION_MARKER + "cmpwi cr7, r3, 0\n" + "bne cr7, 0f\n" + " addis r6, 0, 0xdead\n" + " ori r6, r6, 0xbeef\n" + " mtctr r6\n" + " bctrl\n" + "0:\n" + FUNCTION_MARKER + :: ); +} +void nseel_asm_bor_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_equal(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fsub f1, f1, f2\n" + "fabs f1, f1\n" + "fcmpu cr7, f1, f31\n" + "addis r3, 0, 0\n" + "bge cr7, 0f\n" + "addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_equal_end(void) {} +// +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_notequal(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fsub f1, f1, f2\n" + "fabs f1, f1\n" + "fcmpu cr7, f1, f31\n" + "addis r3, 0, 0\n" + "blt cr7, 0f\n" + " addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_notequal_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_below(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f1, f2\n" + "addis r3, 0, 0\n" + "ble cr7, 0f\n" + "addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_below_end(void) {} + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_beloweq(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f1, f2\n" + "addis r3, 0, 0\n" + "blt cr7, 0f\n" + " addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_beloweq_end(void) {} + + +//--------------------------------------------------------------------------------------------------------------- +void nseel_asm_above(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f1, f2\n" + "addis r3, 0, 0\n" + "bge cr7, 0f\n" + "addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_above_end(void) {} + +void nseel_asm_aboveeq(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f1, f2\n" + "addis r3, 0, 0\n" + "bgt cr7, 0f\n" + "addis r3, 0, 1\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_aboveeq_end(void) {} + + + +void nseel_asm_min(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f1, 0(r3)\n" + "lfd f2, 0(r14)\n" + "fcmpu cr7, f2, f1\n" + "bgt cr7, 0f\n" + "mr r3, r14\n" + "0:\n" + FUNCTION_MARKER + ); +} +void nseel_asm_min_end(void) {} + +void nseel_asm_max(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f1, 0(r3)\n" + "lfd f2, 0(r14)\n" + "fcmpu cr7, f2, f1\n" + "blt cr7, 0f\n" + "mr r3, r14\n" + "0:\n" + FUNCTION_MARKER + ); +} + +void nseel_asm_max_end(void) {} + + +void nseel_asm_min_fp(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f2, f1\n" + "bgt cr7, 0f\n" + "fmr f1, f2\n" + "0:\n" + FUNCTION_MARKER + ); +} +void nseel_asm_min_fp_end(void) {} + +void nseel_asm_max_fp(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, 0(r14)\n" + "fcmpu cr7, f2, f1\n" + "blt cr7, 0f\n" + "fmr f1, f2\n" + "0:\n" + FUNCTION_MARKER + ); +} + +void nseel_asm_max_fp_end(void) {} + + + + + + +void _asm_generic3parm(void) +{ + __asm__( + FUNCTION_MARKER + "mr r6, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mr r4, r15\n" + "mr r5, r14\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic3parm_end(void) {} + +void _asm_generic3parm_retd(void) +{ + __asm__( + FUNCTION_MARKER + "mr r6, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mr r4, r15\n" + "mr r5, r14\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic3parm_retd_end(void) {} + + +void _asm_generic2parm(void) // this prob neds to be fixed for ppc +{ + __asm__( + FUNCTION_MARKER + "mr r5, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mr r4, r14\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic2parm_end(void) {} + + +void _asm_generic2parm_retd(void) +{ + __asm__( + FUNCTION_MARKER + "mr r5, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mr r4, r14\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic2parm_retd_end(void) {} + +void _asm_generic1parm(void) // this prob neds to be fixed for ppc +{ + __asm__( + FUNCTION_MARKER + "mr r4, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic1parm_end(void) {} + + + +void _asm_generic1parm_retd(void) +{ + __asm__( + FUNCTION_MARKER + "mr r4, r3\n" + "addis r3, 0, 0xdead\n" + "ori r3, r3, 0xbeef\n" + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} +void _asm_generic1parm_retd_end(void) {} + + + + +void _asm_megabuf(void) +{ + __asm__( + FUNCTION_MARKER + "lfd f2, -8(r13)\n" + "mr r3, r13\n" + + "fadd f1, f2, f1\n" + + // f1 has (float) index of array, r3 has EEL_F ** + "fctiwz f1, f1\n" + "stfd f1, -8(r1)\n" + "lwz r4, -4(r1)\n" // r4 is index of array + + "andis. r15, r4, %0\n" // check to see if it has any bits in 0xFF800000, which is 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + "bne cr0, 0f\n" // out of range, jump to error + + // shr 14 (16 for NSEEL_RAM_ITEMSPERBLOCK, minus two for pointer size), which is rotate 18 + // mask 7 bits (NSEEL_RAM_BLOCKS), but leave two empty bits (pointer size) + "rlwinm r15, r4, %1, %2, 29\n" + "lwzx r15, r3, r15\n" // r15 = (r3+r15) + "cmpi cr0, r15, 0\n" + "bne cr0, 1f\n" // if nonzero, jump to final calculation + + "0:\n" + // set up function call + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + "mtctr r7\n" + "subi r1, r1, 64\n" + "bctrl\n" + "addi r1, r1, 64\n" + "b 2f\n" + "1:\n" + // good news: we can do a direct addr return + // bad news: more rlwinm ugliness! + // shift left by 3 (sizeof(EEL_F)), mask off lower 3 bits, only allow 16 bits (NSEEL_RAM_ITEMSPERBLOCK) through + "rlwinm r3, r4, 3, %3, 28\n" + + // add offset of loaded block + "add r3, r3, r15\n" + + "2:\n" + FUNCTION_MARKER + :: + "i" ((0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1))>>16), + "i" (32 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 2), + "i" (30 - NSEEL_RAM_BLOCKS_LOG2), + "i" (28 - NSEEL_RAM_ITEMSPERBLOCK_LOG2 + 1) + ); +} + +void _asm_megabuf_end(void) {} + +void _asm_gmegabuf(void) +{ + __asm__( + FUNCTION_MARKER + "fadd f1, f31, f1\n" + "addis r3, 0, 0xdead\n" // set up context pointer + "ori r3, r3, 0xbeef\n" + + "fctiwz f1, f1\n" + "subi r1, r1, 64\n" + + "addis r7, 0, 0xdead\n" + "ori r7, r7, 0xbeef\n" + + "stfd f1, 8(r1)\n" + "mtctr r7\n" + + "lwz r4, 12(r1)\n" + + "bctrl\n" + "addi r1, r1, 64\n" + FUNCTION_MARKER + :: + ); +} + +void _asm_gmegabuf_end(void) {} + +void nseel_asm_fcall(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" + "mtctr r6\n" + "bctrl\n" + FUNCTION_MARKER + ); +} +void nseel_asm_fcall_end(void) {} + + + +void nseel_asm_stack_push(void) +{ + __asm__( + FUNCTION_MARKER + + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + + "lfd f1, 0(r3)\n" // f1 is value to copy to stack + "lwz r3, 0(r6)\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "addi r3, r3, 0x8\n" + + "and r3, r3, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "or r3, r3, r14\n" + + "stfd f1, 0(r3)\n" // copy parameter to stack + + "stw r3, 0(r6)\n" // update stack state + FUNCTION_MARKER + ); +} +void nseel_asm_stack_push_end(void) {} + +void nseel_asm_stack_pop(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + "lwz r15, 0(r6)\n" // return the old stack pointer + + "lfd f1, 0(r15)\n" + "subi r15, r15, 0x8\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "and r15, r15, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "or r15, r15, r14\n" + "stw r15, 0(r6)\n" + + "stfd f1, 0(r3)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_stack_pop_end(void) {} + + + +void nseel_asm_stack_pop_fast(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + "lwz r3, 0(r6)\n" // return the old stack pointer + + "mr r15, r3\n" // update stack pointer + "subi r15, r15, 0x8\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "and r15, r15, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "or r15, r15, r14\n" + "stw r15, 0(r6)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_stack_pop_fast_end(void) {} + +void nseel_asm_stack_peek(void) +{ + __asm__( + FUNCTION_MARKER + "fctiwz f1, f1\n" + "stfd f1, -8(r1)\n" + + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + + "lwz r14, -4(r1)\n" + "rlwinm r14, r14, 3, 0, 28\n" // slwi r14, r14, 3 -- 3 is log2(sizeof(EEL_F)) -- 28 represents 31-3 + "lwz r3, 0(r6)\n" // return the old stack pointer + + "sub r3, r3, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "and r3, r3, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "or r3, r3, r14\n" + FUNCTION_MARKER + ); +} +void nseel_asm_stack_peek_end(void) {} + + +void nseel_asm_stack_peek_top(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + "lwz r3, 0(r6)\n" // return the old stack pointer + FUNCTION_MARKER + ); +} +void nseel_asm_stack_peek_top_end(void) {} + + +void nseel_asm_stack_peek_int(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + "lwz r3, 0(r6)\n" // return the old stack pointer + + "addis r14, 0, 0xdead\n" // add manual offset + "ori r14, r14, 0xbeef\n" + "sub r3, r3, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "and r3, r3, r14\n" + + "addis r14, 0, 0xdead\n" + "ori r14, r14, 0xbeef\n" + "or r3, r3, r14\n" + FUNCTION_MARKER + ); +} +void nseel_asm_stack_peek_int_end(void) {} + +void nseel_asm_stack_exch(void) +{ + __asm__( + FUNCTION_MARKER + "addis r6, 0, 0xdead\n" + "ori r6, r6, 0xbeef\n" // r6 is stack + "lfd f1, 0(r3)\n" + "lwz r14, 0(r6)\n" + "lfd f2, 0(r14)\n" + + "stfd f1, 0(r14)\n" + "stfd f2, 0(r3)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_stack_exch_end(void) {} + + +void nseel_asm_booltofp(void) +{ + __asm__( + FUNCTION_MARKER + "cmpwi cr7, r3, 0\n" + "li r14, 0\n" + "beq cr7, 0f\n" + "addis r14, 0, 0x3f80\n" + "0:\n" + "stw r14, -8(r1)\n" + "lfs f1, -8(r1)\n" + FUNCTION_MARKER + ); +} +void nseel_asm_booltofp_end(void){ } + +void nseel_asm_fptobool(void) +{ + __asm__( + FUNCTION_MARKER + "fabs f1, f1\n" + "fcmpu cr7, f1, f31\n" + "addis r3, 0, 1\n" + "bge cr7, 0f\n" + " addis r3, 0, 0\n" + "0:\n" + FUNCTION_MARKER + :: + ); +} +void nseel_asm_fptobool_end(void){ } + diff --git a/WDL/eel2/asm-nseel-x64-macho.asm b/WDL/eel2/asm-nseel-x64-macho.asm new file mode 100644 index 00000000..3f10c37d --- /dev/null +++ b/WDL/eel2/asm-nseel-x64-macho.asm @@ -0,0 +1,1881 @@ +; THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2x64.php + +%define AMD64ABI +%define EEL_F_SIZE 8 +%define TARGET_X64 +SECTION .text + + +global _nseel_asm_1pdd +_nseel_asm_1pdd: + + + mov rdi, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp] + movq xmm0, [rsp] +%ifdef AMD64ABI + mov r15, rsi + call rdi + mov rsi, r15 +%else + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + sub rsp, 16 + fstp qword [rsp] + call rdi + add rsp, 16 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_1pdd_end +_nseel_asm_1pdd_end: + + +global _nseel_asm_2pdd +_nseel_asm_2pdd: + + + mov rdi, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp+8] + fstp qword [rsp] + movq xmm1, [rsp+8] + movq xmm0, [rsp] +%ifdef AMD64ABI + mov r15, rsi + call rdi + mov rsi, r15 +%else + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + sub rsp, 16 + fstp qword [rsp+8] + fstp qword [rsp] + call rdi + add rsp, 16 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_2pdd_end +_nseel_asm_2pdd_end: + + +global _nseel_asm_2pdds +_nseel_asm_2pdds: + + + mov rax, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp] + movq xmm0, [rdi] + movq xmm1, [rsp] +%ifdef AMD64ABI + mov r15, rsi + mov r14, rdi + call rax + mov rsi, r15 + movq [r14], xmm0 + mov rax, r14 ; set return value +%else + call rax + movq [rdi], xmm0 + mov rax, rdi ; set return value +%endif + add rsp, 128 +%else + sub rsp, 8 + fstp qword [rsp] + push dword [rdi+4] ; push parameter + push dword [rdi] ; push the rest of the parameter + call rax + add rsp, 16 + fstp qword [rdi] ; store result + mov rax, rdi ; set return value +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_2pdds_end +_nseel_asm_2pdds_end: + + +global _nseel_asm_exec2 +_nseel_asm_exec2: + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_exec2_end +_nseel_asm_exec2_end: + + +global _nseel_asm_invsqrt +_nseel_asm_invsqrt: + + mov rdx, 0x5f3759df + fst dword [rsi] +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + sub rcx, rcx + fmul qword [rax] +%else + fmul qword [qword 0xFEFEFEFEFEFEFEFE] +%endif + mov ecx, dword [rsi] + sar rcx, 1 + sub rdx, rcx + mov dword [rsi], edx + fmul dword [rsi] + fmul dword [rsi] +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rax] +%else + fadd qword [qword 0xFEFEFEFEFEFEFEFE] +%endif + fmul dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_invsqrt_end +_nseel_asm_invsqrt_end: + + +global _nseel_asm_sin +_nseel_asm_sin: + + fsin +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sin_end +_nseel_asm_sin_end: + + +global _nseel_asm_cos +_nseel_asm_cos: + + fcos +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_cos_end +_nseel_asm_cos_end: + + +global _nseel_asm_tan +_nseel_asm_tan: + + fptan + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_tan_end +_nseel_asm_tan_end: + + +global _nseel_asm_sqr +_nseel_asm_sqr: + + fmul st0, st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sqr_end +_nseel_asm_sqr_end: + + +global _nseel_asm_sqrt +_nseel_asm_sqrt: + + fabs + fsqrt +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sqrt_end +_nseel_asm_sqrt_end: + + +global _nseel_asm_log +_nseel_asm_log: + + fldln2 + fxch + fyl2x +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_log_end +_nseel_asm_log_end: + + +global _nseel_asm_log10 +_nseel_asm_log10: + + fldlg2 + fxch + fyl2x + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_log10_end +_nseel_asm_log10_end: + + +global _nseel_asm_abs +_nseel_asm_abs: + + fabs +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_abs_end +_nseel_asm_abs_end: + + +global _nseel_asm_assign +_nseel_asm_assign: +%ifdef TARGET_X64 + + mov rdx, qword [rax] + mov rcx, rdx + shr rdx, 32 + and rdx, 0x7FF00000 + jz label_0 + cmp rdx, 0x7FF00000 + je label_0 + jmp label_1 +label_0: + + sub rcx, rcx +label_1: + + mov qword [rdi], rcx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov edx, dword [rax+4] + mov ecx, dword [rax] + and rdx, 0x7ff00000 + jz label_2 ; if exponent=zero, zero + cmp rdx, 0x7ff00000 + je label_2 ; if exponent=all 1s, zero + mov edx, dword [rax+4] ; reread + jmp label_3 +label_2: + + sub rcx, rcx + sub rdx, rdx +label_3: + + mov dword [rdi], ecx + mov dword [rdi+4], edx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_assign_end +_nseel_asm_assign_end: + + +global _nseel_asm_assign_fromfp +_nseel_asm_assign_fromfp: +%ifdef TARGET_X64 + + fstp qword [rdi] + mov rdx, qword [rdi] + mov r15, 0x7FF0000000000000 + and rdx, r15 + jz label_4 + cmp rdx, r15 + jne label_5 +label_4: + + sub rcx, rcx + mov qword [rdi], rcx +label_5: + + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + fstp qword [rdi] + mov edx, dword [rdi+4] + and rdx, 0x7ff00000 + jz label_6 + cmp rdx, 0x7ff00000 + jne label_7 +label_6: + + fldz + fstp qword [rdi] +label_7: + + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_assign_fromfp_end +_nseel_asm_assign_fromfp_end: + + +global _nseel_asm_assign_fast +_nseel_asm_assign_fast: +%ifdef TARGET_X64 + + mov rdx, qword [rax] + mov qword [rdi], rdx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov edx, dword [rax+4] + mov ecx, dword [rax] + mov dword [rdi], ecx + mov dword [rdi+4], edx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_assign_fast_end +_nseel_asm_assign_fast_end: + + +global _nseel_asm_add +_nseel_asm_add: + + fadd +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_add_end +_nseel_asm_add_end: + + +global _nseel_asm_add_op +_nseel_asm_add_op: + + fadd qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_add_op_end +_nseel_asm_add_op_end: + + +global _nseel_asm_sub +_nseel_asm_sub: + +%ifdef __GNUC__ + fsubr ; gnuc has fsub/fsubr backwards, ack +%else + fsub +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sub_end +_nseel_asm_sub_end: + + +global _nseel_asm_sub_op +_nseel_asm_sub_op: + + fsubr qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sub_op_end +_nseel_asm_sub_op_end: + + +global _nseel_asm_mul +_nseel_asm_mul: + + fmul +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_mul_end +_nseel_asm_mul_end: + + +global _nseel_asm_mul_op +_nseel_asm_mul_op: + + fmul qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_mul_op_end +_nseel_asm_mul_op_end: + + +global _nseel_asm_div +_nseel_asm_div: + +%ifdef __GNUC__ + fdivr ; gcc inline asm seems to have fdiv/fdivr backwards +%else + fdiv +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_div_end +_nseel_asm_div_end: + + +global _nseel_asm_div_op +_nseel_asm_div_op: + + fld qword [rdi] +%ifndef __GNUC__ + fxch ; gcc inline asm seems to have fdiv/fdivr backwards +%endif + fdiv + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_div_op_end +_nseel_asm_div_op_end: + + +global _nseel_asm_mod +_nseel_asm_mod: + + fabs + fisttp dword [rsi] + fabs + fisttp dword [rsi+4] + xor rdx, rdx +%ifdef TARGET_X64 + sub rax, rax +%endif + cmp dword [rsi], 0 + je label_8 ; skip devide, set return to 0 + mov eax, dword [rsi+4] + div dword [rsi] +label_8: + + mov dword [rsi], edx + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_mod_end +_nseel_asm_mod_end: + + +global _nseel_asm_shl +_nseel_asm_shl: + + fisttp dword [rsi] + fisttp dword [rsi+4] + mov ecx, dword [rsi] + mov eax, dword [rsi+4] + shl rax, cl + mov dword [rsi], eax + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_shl_end +_nseel_asm_shl_end: + + +global _nseel_asm_shr +_nseel_asm_shr: + + fisttp dword [rsi] + fisttp dword [rsi+4] + mov ecx, dword [rsi] + mov eax, dword [rsi+4] + sar rax, cl + mov dword [rsi], eax + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_shr_end +_nseel_asm_shr_end: + + +global _nseel_asm_mod_op +_nseel_asm_mod_op: + + fld qword [rdi] + fxch + fabs + fisttp dword [rdi] + fabs + fisttp dword [rsi] +%ifdef TARGET_X64 + sub rax, rax +%endif + xor rdx, rdx + cmp dword [rdi], 0 + je label_9 ; skip devide, set return to 0 + mov eax, dword [rsi] + div dword [rdi] +label_9: + + mov dword [rdi], edx + fild dword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_mod_op_end +_nseel_asm_mod_op_end: + + +global _nseel_asm_or +_nseel_asm_or: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + or qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + or dword [rsi], edi + or dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_or_end +_nseel_asm_or_end: + + +global _nseel_asm_or0 +_nseel_asm_or0: + + frndint +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_or0_end +_nseel_asm_or0_end: + + +global _nseel_asm_or_op +_nseel_asm_or_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + or qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + or dword [rdi], eax + or dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_or_op_end +_nseel_asm_or_op_end: + + +global _nseel_asm_xor +_nseel_asm_xor: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + xor qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + xor dword [rsi], edi + xor dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_xor_end +_nseel_asm_xor_end: + + +global _nseel_asm_xor_op +_nseel_asm_xor_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + xor qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + xor dword [rdi], eax + xor dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_xor_op_end +_nseel_asm_xor_op_end: + + +global _nseel_asm_and +_nseel_asm_and: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + and qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + and dword [rsi], edi + and dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_and_end +_nseel_asm_and_end: + + +global _nseel_asm_and_op +_nseel_asm_and_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + and qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + and dword [rdi], eax + and dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_and_op_end +_nseel_asm_and_op_end: + + +global _nseel_asm_uplus +_nseel_asm_uplus: + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_uplus_end +_nseel_asm_uplus_end: + + +global _nseel_asm_uminus +_nseel_asm_uminus: + + fchs +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_uminus_end +_nseel_asm_uminus_end: + + +global _nseel_asm_sign +_nseel_asm_sign: + + +%ifdef TARGET_X64 + + + fst qword [rsp+-8] + mov rdx, qword [rsp+-8] + mov rcx, 0x7FFFFFFFFFFFFFFF + test rdx, rcx + jz label_10 ; zero zero, return the value passed directly + ; calculate sign + inc rcx ; rcx becomes 0x80000... + fstp st0 + fld1 + test rdx, rcx + jz label_10 + fchs +label_10: + + +%else + + fst -dword [rsp+4] + mov ecx, -dword [rsp+4] + mov rdx, 0x7FFFFFFF + test rcx, rdx + jz label_11 ; zero zero, return the value passed directly + ; calculate sign + inc rdx ; edx becomes 0x8000... + fstp st0 + fld1 + test rcx, rdx + jz label_11 + fchs +label_11: + + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_sign_end +_nseel_asm_sign_end: + + +global _nseel_asm_bnot +_nseel_asm_bnot: + + test rax, rax + setz al + and rax, 0xff +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_bnot_end +_nseel_asm_bnot_end: + + +global _nseel_asm_if +_nseel_asm_if: + +%ifdef TARGET_X64 + sub rsp, 8 + test rax, rax + jz label_12 + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax + jmp label_13 +label_12: + + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax +label_13: + + add rsp, 8 +%else + sub rsp, 12 + test rax, rax + jz label_14 + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax + jmp label_15 +label_14: + + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax +label_15: + + add rsp, 12 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_if_end +_nseel_asm_if_end: + + +global _nseel_asm_repeat +_nseel_asm_repeat: + +%ifdef TARGET_X64 + fisttp qword [rsi] + mov rcx, qword [rsi] +%else + fisttp dword [rsi] + mov ecx, dword [rsi] +%endif + cmp rcx, 1 + jl label_16 + cmp rcx, 10000000 + jl label_17 + mov rcx, 10000000 +label_17: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 ; keep stack aligned to 16 byte +%else + sub rsp, 4 ; keep stack aligned to 16 byte +%endif + push rsi ; revert back to last temp workspace + push rcx + + call rdx + + pop rcx + pop rsi +%ifdef TARGET_X64 + add rsp, 8 ; keep stack aligned to 16 byte +%else + add rsp, 4 ; keep stack aligned to 16 byte +%endif + dec rcx + jnz label_17 +label_16: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_repeat_end +_nseel_asm_repeat_end: + + +global _nseel_asm_fcall +_nseel_asm_fcall: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 + call rdx + add rsp, 8 +%else + sub rsp, 12 ; keep stack 16 byte aligned, 4 bytes for return address + call rdx + add rsp, 12 +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_fcall_end +_nseel_asm_fcall_end: + + +global _nseel_asm_repeatwhile +_nseel_asm_repeatwhile: + + mov rcx, 10000000 +label_18: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + +%ifdef TARGET_X64 + sub rsp, 8 ; keep stack aligned -- required on x86 and x64 +%else + sub rsp, 4 ; keep stack aligned -- required on x86 and x64 +%endif + push rsi ; revert back to last temp workspace + push rcx + call rdx + pop rcx + pop rsi +%ifdef TARGET_X64 + add rsp, 8 ; keep stack aligned -- required on x86 and x64 +%else + add rsp, 4 ; keep stack aligned -- required on x86 and x64 +%endif + test rax, rax + jz label_19 + dec rcx + jnz label_18 +label_19: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_repeatwhile_end +_nseel_asm_repeatwhile_end: + + +global _nseel_asm_band +_nseel_asm_band: + + test rax, rax + jz label_20 + + mov rcx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 +%else + sub rsp, 12 +%endif + call rcx +%ifdef TARGET_X64 + add rsp, 8 +%else + add rsp, 12 +%endif +label_20: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_band_end +_nseel_asm_band_end: + + +global _nseel_asm_bor +_nseel_asm_bor: + + test rax, rax + jnz label_21 + + mov rcx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 +%else + sub rsp, 12 +%endif + call rcx +%ifdef TARGET_X64 + add rsp, 8 +%else + add rsp, 12 +%endif +label_21: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_bor_end +_nseel_asm_bor_end: + + +global _nseel_asm_equal +_nseel_asm_equal: + + fsub + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 ; old behavior: if 256 set, true (NaN means true) +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_equal_end +_nseel_asm_equal_end: + + +global _nseel_asm_notequal +_nseel_asm_notequal: + + fsub + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 + xor rax, 256 ; old behavior: if 256 set, FALSE (NaN makes for false) +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_notequal_end +_nseel_asm_notequal_end: + + +global _nseel_asm_above +_nseel_asm_above: + + fcompp + fstsw ax + and rax, 1280 ; (1024+256) old behavior: NaN would mean 1, preserve that +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_above_end +_nseel_asm_above_end: + + +global _nseel_asm_beloweq +_nseel_asm_beloweq: + + fcompp + fstsw ax + and rax, 256 ; old behavior: NaN would be 0 (ugh) + xor rax, 256 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_beloweq_end +_nseel_asm_beloweq_end: + + +global _nseel_asm_booltofp +_nseel_asm_booltofp: + + test rax, rax + jz label_22 + fld1 + jmp label_23 +label_22: + + fldz +label_23: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_booltofp_end +_nseel_asm_booltofp_end: + + +global _nseel_asm_fptobool +_nseel_asm_fptobool: + + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 + xor rax, 256 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_fptobool_end +_nseel_asm_fptobool_end: + + +global _nseel_asm_min +_nseel_asm_min: + + fld qword [rdi] + fcomp qword [rax] + push rax + fstsw ax + test rax, 256 + pop rax + jz label_24 + mov rax, rdi +label_24: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_min_end +_nseel_asm_min_end: + + +global _nseel_asm_max +_nseel_asm_max: + + fld qword [rdi] + fcomp qword [rax] + push rax + fstsw ax + test rax, 256 + pop rax + jnz label_25 + mov rax, rdi +label_25: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_max_end +_nseel_asm_max_end: + + +global _nseel_asm_min_fp +_nseel_asm_min_fp: + + fcom + fstsw ax + test rax, 256 + jz label_26 + fxch +label_26: + + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_min_fp_end +_nseel_asm_min_fp_end: + + +global _nseel_asm_max_fp +_nseel_asm_max_fp: + + fcom + fstsw ax + test rax, 256 + jnz label_27 + fxch +label_27: + + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _nseel_asm_max_fp_end +_nseel_asm_max_fp_end: + + +global __asm_generic3parm +__asm_generic3parm: + +%ifdef TARGET_X64 + +%ifdef AMD64ABI + + mov r15, rsi + mov rdx, rdi ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + + mov rsi, rcx ; second parameter = parm + mov rcx, rax ; fourth parameter = parm + mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rax + + mov rsi, r15 + add rsp, 128 + +%else + mov rdx, rcx ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r8, rdi ; third parameter = parm + mov r9, rax ; fourth parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif + +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + push rax ; push parameter + push rdi ; push parameter + push rcx ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic3parm_end +__asm_generic3parm_end: + + +global __asm_generic3parm_retd +__asm_generic3parm_retd: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov r15, rsi + mov rdx, rdi ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rsi, rcx ; second parameter = parm + mov rcx, rax ; fourth parameter = parm + mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rax + mov rsi, r15 +%else + mov rdx, rcx ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r8, rdi ; third parameter = parm + mov r9, rax ; fourth parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + sub rsp, 16 + mov dword [rsp+8], edi + mov rdx, qword 0xFEFEFEFEFEFEFEFE + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov dword [rsp+12], eax + mov dword [rsp+4], ecx + mov dword [rsp], edx + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic3parm_retd_end +__asm_generic3parm_retd_end: + + +global __asm_generic2parm +__asm_generic2parm: + +%ifdef TARGET_X64 + +%ifdef AMD64ABI + mov r15, rsi + mov rsi, rdi ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rax ; third parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rcx + mov rsi, r15 + add rsp, 128 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rdi ; second parameter = parm + mov r8, rax ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 4 ; keep stack aligned + push rax ; push parameter + push rdi ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic2parm_end +__asm_generic2parm_end: + + +global __asm_generic2parm_retd +__asm_generic2parm_retd: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov r15, rsi + mov rsi, rdi ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + mov rdx, rax ; third parameter = parm + sub rsp, 128 + call rcx + mov rsi, r15 +%else + mov rdx, rdi ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + mov r8, rax ; third parameter = parm + sub rsp, 128 + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + sub rsp, 16 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rsp], edx + mov dword [rsp+4], edi + mov dword [rsp+8], eax + call rcx + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic2parm_retd_end +__asm_generic2parm_retd_end: + + +global __asm_generic1parm +__asm_generic1parm: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r15, rsi + mov rsi, rax ; second parameter = parm + sub rsp, 128 + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + call rcx + mov rsi, r15 + add rsp, 128 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rax ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 8 ; keep stack aligned + push rax ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic1parm_end +__asm_generic1parm_end: + + +global __asm_generic1parm_retd +__asm_generic1parm_retd: + +%ifdef TARGET_X64 + sub rsp, 128 +%ifdef AMD64ABI + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; function address + mov r15, rsi ; save rsi + mov rsi, rax ; second parameter = parameter + + call rcx + + mov rsi, r15 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + + mov rdx, rax ; second parameter = parm + + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE ; context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; func-addr + sub rsp, 16 + mov dword [rsp+4], eax ; push parameter + mov dword [rsp], edx ; push context pointer + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_generic1parm_retd_end +__asm_generic1parm_retd_end: + + +global __asm_megabuf +__asm_megabuf: + + + +%ifdef TARGET_X64 + + +%ifdef AMD64ABI + + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + + fadd qword [rdx] + fisttp dword [rsi] + sub rdx, rdx + + ; check if (%rsi) is in range, and buffer available, otherwise call function + mov edx, dword [rsi] + test rdx, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_28 + mov rax, rdx + shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) + and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov rax, qword [rdi+rax] + test rax, rax + jz label_28 + and rdx, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdx, 3 ; log2(sizeof(EEL_F)) + add rax, rdx + jmp label_29 + + +label_28: + + mov r15, rsi ; save rsi + mov rsi, rdx ; esi becomes second parameter (edi is first, context pointer) + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdx + mov rsi, r15 ; restore rsi + add rsp, 128 +label_29: + + +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rdi, rdi + + fadd qword [rdx] + + fisttp dword [rsi] + + ; check if (%esi) is in range... + mov edi, dword [rsi] + test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_30 + mov rax, rdi + shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) + and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov rax, qword [rcx+rax] + test rax, rax + jz label_30 + and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdi, 3 ; log2(sizeof(EEL_F)) + add rax, rdi + jmp label_31 + +label_30: + + mov rdx, rdi ; rdx is second parameter (rcx is first) + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; function ptr + sub rsp, 128 + call rdi + add rsp, 128 +label_31: + +%endif + + +%else + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [qword 0xFEFEFEFEFEFEFEFE] + fisttp dword [rsi] + + ; check if (%esi) is in range, and buffer available, otherwise call function + mov edi, dword [rsi] + test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_32 + + mov rax, rdi + shr rax, 14 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void *)) + and rax, 0x1FC ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov eax, dword [rdx+rax] + test rax, rax + jz label_32 + and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdi, 3 ; log2(sizeof(EEL_F)) + add rax, rdi + jmp label_33 + + +label_32: + + sub rsp, 8 ; keep stack aligned + push rdi ; parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +label_33: + + + +%endif + + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_megabuf_end +__asm_megabuf_end: + + +global __asm_gmegabuf +__asm_gmegabuf: + + + +%ifdef TARGET_X64 + + +%ifdef AMD64ABI + + mov r15, rsi + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rdx] + fisttp dword [r15] + xor rsi, rsi + mov esi, dword [r15] ; r15 = esi (from above) + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdx + mov rsi, r15 + add rsp, 128 + +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rdx] + fisttp dword [rsi] + xor rdx, rdx + mov edx, dword [rsi] + mov rdi, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdi + add rsp, 128 +%endif + + +%else + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [qword 0xFEFEFEFEFEFEFEFE] + fisttp dword [rsi] + sub rsp, 8 ; keep stack aligned + push dword [rsi] ; parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif + + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global __asm_gmegabuf_end +__asm_gmegabuf_end: + + +global _nseel_asm_stack_push +_nseel_asm_stack_push: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rax] + mov rax, qword [rdi] + add rax, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx + mov qword [rax], rcx + mov qword [rdi], rax +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + + mov ecx, dword [rax] + mov edx, dword [rax+4] + + mov eax, dword [rdi] + + add rax, 8 + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE + + mov dword [rax], ecx + mov dword [rax+4], edx + + mov dword [rdi], eax +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_push_end +_nseel_asm_stack_push_end: + + +global _nseel_asm_stack_pop +_nseel_asm_stack_pop: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + movq xmm0, [rcx] + sub rcx, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rcx, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rcx, rdx + mov qword [rdi], rcx + movq [rax], xmm0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + fld qword [rcx] + sub rcx, 8 + and rcx, qword 0xFEFEFEFEFEFEFEFE + or rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rdi], ecx + fstp qword [rax] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_pop_end +_nseel_asm_stack_pop_end: + + +global _nseel_asm_stack_pop_fast +_nseel_asm_stack_pop_fast: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + mov rax, rcx + sub rcx, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rcx, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rcx, rdx + mov qword [rdi], rcx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + mov rax, rcx + sub rcx, 8 + and rcx, qword 0xFEFEFEFEFEFEFEFE + or rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rdi], ecx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_pop_fast_end +_nseel_asm_stack_pop_fast_end: + + +global _nseel_asm_stack_peek_int +_nseel_asm_stack_peek_int: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rax, qword [rdi] + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov eax, dword [rdi] + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rax, rdx + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_peek_int_end +_nseel_asm_stack_peek_int_end: + + +global _nseel_asm_stack_peek +_nseel_asm_stack_peek: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + fisttp dword [rsi] + mov rax, qword [rdi] + mov rdx, qword [rsi] + shl rdx, 3 ; log2(sizeof(EEL_F)) + sub rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + fisttp dword [rsi] + mov eax, dword [rdi] + mov edx, dword [rsi] + shl rdx, 3 ; log2(sizeof(EEL_F)) + sub rax, rdx + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_peek_end +_nseel_asm_stack_peek_end: + + +global _nseel_asm_stack_peek_top +_nseel_asm_stack_peek_top: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rax, qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov eax, dword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_peek_top_end +_nseel_asm_stack_peek_top_end: + + +global _nseel_asm_stack_exch +_nseel_asm_stack_exch: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + movq xmm0, [rcx] + movq xmm1, [rax] + movq [rax], xmm0 + movq [rcx], xmm1 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + fld qword [rcx] + fld qword [rax] + fstp qword [rcx] + fstp qword [rax] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global _nseel_asm_stack_exch_end +_nseel_asm_stack_exch_end: +%ifdef TARGET_X64 + + +global _win64_callcode +_win64_callcode: + +%ifdef AMD64ABI + mov rax, rdi +%else + mov rax, rcx +%endif + + push rbx + push rbp +%ifndef AMD64ABI + push rdi + push rsi + push r12 + push r13 +%endif + push r14 ; on AMD64ABI, we'll use r14/r15 to save edi/esi + push r15 + call rax + pop r15 + pop r14 +%ifndef AMD64ABI + pop r13 + pop r12 + pop rsi + pop rdi + fclex +%endif + pop rbp + pop rbx + ret +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif diff --git a/WDL/eel2/asm-nseel-x64-macho.o b/WDL/eel2/asm-nseel-x64-macho.o new file mode 100644 index 0000000000000000000000000000000000000000..f40f6e0b5f0d509511ab44416b5d7e5b19ed8fe8 GIT binary patch literal 9979 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 literal 0 HcmV?d00001 diff --git a/WDL/eel2/asm-nseel-x64.asm b/WDL/eel2/asm-nseel-x64.asm new file mode 100644 index 00000000..429352f8 --- /dev/null +++ b/WDL/eel2/asm-nseel-x64.asm @@ -0,0 +1,1880 @@ +; THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2x64.php + +%define EEL_F_SIZE 8 +%define TARGET_X64 +SECTION .text + + +global nseel_asm_1pdd +nseel_asm_1pdd: + + + mov rdi, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp] + movq xmm0, [rsp] +%ifdef AMD64ABI + mov r15, rsi + call rdi + mov rsi, r15 +%else + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + sub rsp, 16 + fstp qword [rsp] + call rdi + add rsp, 16 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_1pdd_end +nseel_asm_1pdd_end: + + +global nseel_asm_2pdd +nseel_asm_2pdd: + + + mov rdi, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp+8] + fstp qword [rsp] + movq xmm1, [rsp+8] + movq xmm0, [rsp] +%ifdef AMD64ABI + mov r15, rsi + call rdi + mov rsi, r15 +%else + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + sub rsp, 16 + fstp qword [rsp+8] + fstp qword [rsp] + call rdi + add rsp, 16 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_2pdd_end +nseel_asm_2pdd_end: + + +global nseel_asm_2pdds +nseel_asm_2pdds: + + + mov rax, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 128 + fstp qword [rsp] + movq xmm0, [rdi] + movq xmm1, [rsp] +%ifdef AMD64ABI + mov r15, rsi + mov r14, rdi + call rax + mov rsi, r15 + movq [r14], xmm0 + mov rax, r14 ; set return value +%else + call rax + movq [rdi], xmm0 + mov rax, rdi ; set return value +%endif + add rsp, 128 +%else + sub rsp, 8 + fstp qword [rsp] + push dword [rdi+4] ; push parameter + push dword [rdi] ; push the rest of the parameter + call rax + add rsp, 16 + fstp qword [rdi] ; store result + mov rax, rdi ; set return value +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_2pdds_end +nseel_asm_2pdds_end: + + +global nseel_asm_exec2 +nseel_asm_exec2: + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_exec2_end +nseel_asm_exec2_end: + + +global nseel_asm_invsqrt +nseel_asm_invsqrt: + + mov rdx, 0x5f3759df + fst dword [rsi] +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + sub rcx, rcx + fmul qword [rax] +%else + fmul qword [qword 0xFEFEFEFEFEFEFEFE] +%endif + mov ecx, dword [rsi] + sar rcx, 1 + sub rdx, rcx + mov dword [rsi], edx + fmul dword [rsi] + fmul dword [rsi] +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rax] +%else + fadd qword [qword 0xFEFEFEFEFEFEFEFE] +%endif + fmul dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_invsqrt_end +nseel_asm_invsqrt_end: + + +global nseel_asm_sin +nseel_asm_sin: + + fsin +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sin_end +nseel_asm_sin_end: + + +global nseel_asm_cos +nseel_asm_cos: + + fcos +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_cos_end +nseel_asm_cos_end: + + +global nseel_asm_tan +nseel_asm_tan: + + fptan + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_tan_end +nseel_asm_tan_end: + + +global nseel_asm_sqr +nseel_asm_sqr: + + fmul st0, st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sqr_end +nseel_asm_sqr_end: + + +global nseel_asm_sqrt +nseel_asm_sqrt: + + fabs + fsqrt +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sqrt_end +nseel_asm_sqrt_end: + + +global nseel_asm_log +nseel_asm_log: + + fldln2 + fxch + fyl2x +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_log_end +nseel_asm_log_end: + + +global nseel_asm_log10 +nseel_asm_log10: + + fldlg2 + fxch + fyl2x + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_log10_end +nseel_asm_log10_end: + + +global nseel_asm_abs +nseel_asm_abs: + + fabs +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_abs_end +nseel_asm_abs_end: + + +global nseel_asm_assign +nseel_asm_assign: +%ifdef TARGET_X64 + + mov rdx, qword [rax] + mov rcx, rdx + shr rdx, 32 + and rdx, 0x7FF00000 + jz label_0 + cmp rdx, 0x7FF00000 + je label_0 + jmp label_1 +label_0: + + sub rcx, rcx +label_1: + + mov qword [rdi], rcx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov edx, dword [rax+4] + mov ecx, dword [rax] + and rdx, 0x7ff00000 + jz label_2 ; if exponent=zero, zero + cmp rdx, 0x7ff00000 + je label_2 ; if exponent=all 1s, zero + mov edx, dword [rax+4] ; reread + jmp label_3 +label_2: + + sub rcx, rcx + sub rdx, rdx +label_3: + + mov dword [rdi], ecx + mov dword [rdi+4], edx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_assign_end +nseel_asm_assign_end: + + +global nseel_asm_assign_fromfp +nseel_asm_assign_fromfp: +%ifdef TARGET_X64 + + fstp qword [rdi] + mov rdx, qword [rdi] + mov r15, 0x7FF0000000000000 + and rdx, r15 + jz label_4 + cmp rdx, r15 + jne label_5 +label_4: + + sub rcx, rcx + mov qword [rdi], rcx +label_5: + + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + fstp qword [rdi] + mov edx, dword [rdi+4] + and rdx, 0x7ff00000 + jz label_6 + cmp rdx, 0x7ff00000 + jne label_7 +label_6: + + fldz + fstp qword [rdi] +label_7: + + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_assign_fromfp_end +nseel_asm_assign_fromfp_end: + + +global nseel_asm_assign_fast +nseel_asm_assign_fast: +%ifdef TARGET_X64 + + mov rdx, qword [rax] + mov qword [rdi], rdx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov edx, dword [rax+4] + mov ecx, dword [rax] + mov dword [rdi], ecx + mov dword [rdi+4], edx + mov rax, rdi +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_assign_fast_end +nseel_asm_assign_fast_end: + + +global nseel_asm_add +nseel_asm_add: + + fadd +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_add_end +nseel_asm_add_end: + + +global nseel_asm_add_op +nseel_asm_add_op: + + fadd qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_add_op_end +nseel_asm_add_op_end: + + +global nseel_asm_sub +nseel_asm_sub: + +%ifdef __GNUC__ + fsubr ; gnuc has fsub/fsubr backwards, ack +%else + fsub +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sub_end +nseel_asm_sub_end: + + +global nseel_asm_sub_op +nseel_asm_sub_op: + + fsubr qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sub_op_end +nseel_asm_sub_op_end: + + +global nseel_asm_mul +nseel_asm_mul: + + fmul +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_mul_end +nseel_asm_mul_end: + + +global nseel_asm_mul_op +nseel_asm_mul_op: + + fmul qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_mul_op_end +nseel_asm_mul_op_end: + + +global nseel_asm_div +nseel_asm_div: + +%ifdef __GNUC__ + fdivr ; gcc inline asm seems to have fdiv/fdivr backwards +%else + fdiv +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_div_end +nseel_asm_div_end: + + +global nseel_asm_div_op +nseel_asm_div_op: + + fld qword [rdi] +%ifndef __GNUC__ + fxch ; gcc inline asm seems to have fdiv/fdivr backwards +%endif + fdiv + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_div_op_end +nseel_asm_div_op_end: + + +global nseel_asm_mod +nseel_asm_mod: + + fabs + fisttp dword [rsi] + fabs + fisttp dword [rsi+4] + xor rdx, rdx +%ifdef TARGET_X64 + sub rax, rax +%endif + cmp dword [rsi], 0 + je label_8 ; skip devide, set return to 0 + mov eax, dword [rsi+4] + div dword [rsi] +label_8: + + mov dword [rsi], edx + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_mod_end +nseel_asm_mod_end: + + +global nseel_asm_shl +nseel_asm_shl: + + fisttp dword [rsi] + fisttp dword [rsi+4] + mov ecx, dword [rsi] + mov eax, dword [rsi+4] + shl rax, cl + mov dword [rsi], eax + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_shl_end +nseel_asm_shl_end: + + +global nseel_asm_shr +nseel_asm_shr: + + fisttp dword [rsi] + fisttp dword [rsi+4] + mov ecx, dword [rsi] + mov eax, dword [rsi+4] + sar rax, cl + mov dword [rsi], eax + fild dword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_shr_end +nseel_asm_shr_end: + + +global nseel_asm_mod_op +nseel_asm_mod_op: + + fld qword [rdi] + fxch + fabs + fisttp dword [rdi] + fabs + fisttp dword [rsi] +%ifdef TARGET_X64 + sub rax, rax +%endif + xor rdx, rdx + cmp dword [rdi], 0 + je label_9 ; skip devide, set return to 0 + mov eax, dword [rsi] + div dword [rdi] +label_9: + + mov dword [rdi], edx + fild dword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_mod_op_end +nseel_asm_mod_op_end: + + +global nseel_asm_or +nseel_asm_or: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + or qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + or dword [rsi], edi + or dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_or_end +nseel_asm_or_end: + + +global nseel_asm_or0 +nseel_asm_or0: + + frndint +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_or0_end +nseel_asm_or0_end: + + +global nseel_asm_or_op +nseel_asm_or_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + or qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + or dword [rdi], eax + or dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_or_op_end +nseel_asm_or_op_end: + + +global nseel_asm_xor +nseel_asm_xor: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + xor qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + xor dword [rsi], edi + xor dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_xor_end +nseel_asm_xor_end: + + +global nseel_asm_xor_op +nseel_asm_xor_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + xor qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + xor dword [rdi], eax + xor dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_xor_op_end +nseel_asm_xor_op_end: + + +global nseel_asm_and +nseel_asm_and: + + fisttp qword [rsi] + fisttp qword [rsi+8] +%ifdef TARGET_X64 + mov rdi, qword [rsi+8] + and qword [rsi], rdi +%else + mov edi, dword [rsi+8] + mov ecx, dword [rsi+12] + and dword [rsi], edi + and dword [rsi+4], ecx +%endif + fild qword [rsi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_and_end +nseel_asm_and_end: + + +global nseel_asm_and_op +nseel_asm_and_op: + + fld qword [rdi] + fxch + fisttp qword [rdi] + fisttp qword [rsi] +%ifdef TARGET_X64 + mov rax, qword [rsi] + and qword [rdi], rax +%else + mov eax, dword [rsi] + mov ecx, dword [rsi+4] + and dword [rdi], eax + and dword [rdi+4], ecx +%endif + fild qword [rdi] + mov rax, rdi + fstp qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_and_op_end +nseel_asm_and_op_end: + + +global nseel_asm_uplus +nseel_asm_uplus: + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_uplus_end +nseel_asm_uplus_end: + + +global nseel_asm_uminus +nseel_asm_uminus: + + fchs +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_uminus_end +nseel_asm_uminus_end: + + +global nseel_asm_sign +nseel_asm_sign: + + +%ifdef TARGET_X64 + + + fst qword [rsp+-8] + mov rdx, qword [rsp+-8] + mov rcx, 0x7FFFFFFFFFFFFFFF + test rdx, rcx + jz label_10 ; zero zero, return the value passed directly + ; calculate sign + inc rcx ; rcx becomes 0x80000... + fstp st0 + fld1 + test rdx, rcx + jz label_10 + fchs +label_10: + + +%else + + fst -dword [rsp+4] + mov ecx, -dword [rsp+4] + mov rdx, 0x7FFFFFFF + test rcx, rdx + jz label_11 ; zero zero, return the value passed directly + ; calculate sign + inc rdx ; edx becomes 0x8000... + fstp st0 + fld1 + test rcx, rdx + jz label_11 + fchs +label_11: + + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_sign_end +nseel_asm_sign_end: + + +global nseel_asm_bnot +nseel_asm_bnot: + + test rax, rax + setz al + and rax, 0xff +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_bnot_end +nseel_asm_bnot_end: + + +global nseel_asm_if +nseel_asm_if: + +%ifdef TARGET_X64 + sub rsp, 8 + test rax, rax + jz label_12 + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax + jmp label_13 +label_12: + + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax +label_13: + + add rsp, 8 +%else + sub rsp, 12 + test rax, rax + jz label_14 + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax + jmp label_15 +label_14: + + mov rax, qword 0xFEFEFEFEFEFEFEFE + call rax +label_15: + + add rsp, 12 +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_if_end +nseel_asm_if_end: + + +global nseel_asm_repeat +nseel_asm_repeat: + +%ifdef TARGET_X64 + fisttp qword [rsi] + mov rcx, qword [rsi] +%else + fisttp dword [rsi] + mov ecx, dword [rsi] +%endif + cmp rcx, 1 + jl label_16 + cmp rcx, 10000000 + jl label_17 + mov rcx, 10000000 +label_17: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 ; keep stack aligned to 16 byte +%else + sub rsp, 4 ; keep stack aligned to 16 byte +%endif + push rsi ; revert back to last temp workspace + push rcx + + call rdx + + pop rcx + pop rsi +%ifdef TARGET_X64 + add rsp, 8 ; keep stack aligned to 16 byte +%else + add rsp, 4 ; keep stack aligned to 16 byte +%endif + dec rcx + jnz label_17 +label_16: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_repeat_end +nseel_asm_repeat_end: + + +global nseel_asm_fcall +nseel_asm_fcall: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 + call rdx + add rsp, 8 +%else + sub rsp, 12 ; keep stack 16 byte aligned, 4 bytes for return address + call rdx + add rsp, 12 +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_fcall_end +nseel_asm_fcall_end: + + +global nseel_asm_repeatwhile +nseel_asm_repeatwhile: + + mov rcx, 10000000 +label_18: + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + +%ifdef TARGET_X64 + sub rsp, 8 ; keep stack aligned -- required on x86 and x64 +%else + sub rsp, 4 ; keep stack aligned -- required on x86 and x64 +%endif + push rsi ; revert back to last temp workspace + push rcx + call rdx + pop rcx + pop rsi +%ifdef TARGET_X64 + add rsp, 8 ; keep stack aligned -- required on x86 and x64 +%else + add rsp, 4 ; keep stack aligned -- required on x86 and x64 +%endif + test rax, rax + jz label_19 + dec rcx + jnz label_18 +label_19: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_repeatwhile_end +nseel_asm_repeatwhile_end: + + +global nseel_asm_band +nseel_asm_band: + + test rax, rax + jz label_20 + + mov rcx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 +%else + sub rsp, 12 +%endif + call rcx +%ifdef TARGET_X64 + add rsp, 8 +%else + add rsp, 12 +%endif +label_20: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_band_end +nseel_asm_band_end: + + +global nseel_asm_bor +nseel_asm_bor: + + test rax, rax + jnz label_21 + + mov rcx, qword 0xFEFEFEFEFEFEFEFE +%ifdef TARGET_X64 + sub rsp, 8 +%else + sub rsp, 12 +%endif + call rcx +%ifdef TARGET_X64 + add rsp, 8 +%else + add rsp, 12 +%endif +label_21: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_bor_end +nseel_asm_bor_end: + + +global nseel_asm_equal +nseel_asm_equal: + + fsub + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 ; old behavior: if 256 set, true (NaN means true) +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_equal_end +nseel_asm_equal_end: + + +global nseel_asm_notequal +nseel_asm_notequal: + + fsub + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 + xor rax, 256 ; old behavior: if 256 set, FALSE (NaN makes for false) +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_notequal_end +nseel_asm_notequal_end: + + +global nseel_asm_above +nseel_asm_above: + + fcompp + fstsw ax + and rax, 1280 ; (1024+256) old behavior: NaN would mean 1, preserve that +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_above_end +nseel_asm_above_end: + + +global nseel_asm_beloweq +nseel_asm_beloweq: + + fcompp + fstsw ax + and rax, 256 ; old behavior: NaN would be 0 (ugh) + xor rax, 256 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_beloweq_end +nseel_asm_beloweq_end: + + +global nseel_asm_booltofp +nseel_asm_booltofp: + + test rax, rax + jz label_22 + fld1 + jmp label_23 +label_22: + + fldz +label_23: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_booltofp_end +nseel_asm_booltofp_end: + + +global nseel_asm_fptobool +nseel_asm_fptobool: + + fabs +%ifdef TARGET_X64 + mov rax, qword 0xFEFEFEFEFEFEFEFE + fcomp qword [rax] ; [g_closefact] +%else + fcomp qword [qword 0xFEFEFEFEFEFEFEFE] ; [g_closefact] +%endif + fstsw ax + and rax, 256 + xor rax, 256 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_fptobool_end +nseel_asm_fptobool_end: + + +global nseel_asm_min +nseel_asm_min: + + fld qword [rdi] + fcomp qword [rax] + push rax + fstsw ax + test rax, 256 + pop rax + jz label_24 + mov rax, rdi +label_24: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_min_end +nseel_asm_min_end: + + +global nseel_asm_max +nseel_asm_max: + + fld qword [rdi] + fcomp qword [rax] + push rax + fstsw ax + test rax, 256 + pop rax + jnz label_25 + mov rax, rdi +label_25: + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_max_end +nseel_asm_max_end: + + +global nseel_asm_min_fp +nseel_asm_min_fp: + + fcom + fstsw ax + test rax, 256 + jz label_26 + fxch +label_26: + + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_min_fp_end +nseel_asm_min_fp_end: + + +global nseel_asm_max_fp +nseel_asm_max_fp: + + fcom + fstsw ax + test rax, 256 + jnz label_27 + fxch +label_27: + + fstp st0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global nseel_asm_max_fp_end +nseel_asm_max_fp_end: + + +global _asm_generic3parm +_asm_generic3parm: + +%ifdef TARGET_X64 + +%ifdef AMD64ABI + + mov r15, rsi + mov rdx, rdi ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + + mov rsi, rcx ; second parameter = parm + mov rcx, rax ; fourth parameter = parm + mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rax + + mov rsi, r15 + add rsp, 128 + +%else + mov rdx, rcx ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r8, rdi ; third parameter = parm + mov r9, rax ; fourth parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif + +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + push rax ; push parameter + push rdi ; push parameter + push rcx ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic3parm_end +_asm_generic3parm_end: + + +global _asm_generic3parm_retd +_asm_generic3parm_retd: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov r15, rsi + mov rdx, rdi ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rsi, rcx ; second parameter = parm + mov rcx, rax ; fourth parameter = parm + mov rax, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rax + mov rsi, r15 +%else + mov rdx, rcx ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r8, rdi ; third parameter = parm + mov r9, rax ; fourth parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + sub rsp, 16 + mov dword [rsp+8], edi + mov rdx, qword 0xFEFEFEFEFEFEFEFE + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov dword [rsp+12], eax + mov dword [rsp+4], ecx + mov dword [rsp], edx + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic3parm_retd_end +_asm_generic3parm_retd_end: + + +global _asm_generic2parm +_asm_generic2parm: + +%ifdef TARGET_X64 + +%ifdef AMD64ABI + mov r15, rsi + mov rsi, rdi ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rax ; third parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rcx + mov rsi, r15 + add rsp, 128 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rdi ; second parameter = parm + mov r8, rax ; third parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 4 ; keep stack aligned + push rax ; push parameter + push rdi ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic2parm_end +_asm_generic2parm_end: + + +global _asm_generic2parm_retd +_asm_generic2parm_retd: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov r15, rsi + mov rsi, rdi ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + mov rdx, rax ; third parameter = parm + sub rsp, 128 + call rcx + mov rsi, r15 +%else + mov rdx, rdi ; second parameter = parm + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + mov r8, rax ; third parameter = parm + sub rsp, 128 + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + sub rsp, 16 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rsp], edx + mov dword [rsp+4], edi + mov dword [rsp+8], eax + call rcx + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic2parm_retd_end +_asm_generic2parm_retd_end: + + +global _asm_generic1parm +_asm_generic1parm: + +%ifdef TARGET_X64 +%ifdef AMD64ABI + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov r15, rsi + mov rsi, rax ; second parameter = parm + sub rsp, 128 + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; call function + call rcx + mov rsi, r15 + add rsp, 128 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdx, rax ; second parameter = parm + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + sub rsp, 128 + call rdi + add rsp, 128 +%endif +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 8 ; keep stack aligned + push rax ; push parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic1parm_end +_asm_generic1parm_end: + + +global _asm_generic1parm_retd +_asm_generic1parm_retd: + +%ifdef TARGET_X64 + sub rsp, 128 +%ifdef AMD64ABI + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; function address + mov r15, rsi ; save rsi + mov rsi, rax ; second parameter = parameter + + call rcx + + mov rsi, r15 +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter= context + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; call function + + mov rdx, rax ; second parameter = parm + + call rdi +%endif + movq [rsp], xmm0 + fld qword [rsp] + add rsp, 128 +%else + + mov rdx, qword 0xFEFEFEFEFEFEFEFE ; context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; func-addr + sub rsp, 16 + mov dword [rsp+4], eax ; push parameter + mov dword [rsp], edx ; push context pointer + call rdi + add rsp, 16 + +%endif +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_generic1parm_retd_end +_asm_generic1parm_retd_end: + + +global _asm_megabuf +_asm_megabuf: + + + +%ifdef TARGET_X64 + + +%ifdef AMD64ABI + + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + + mov rdx, qword 0xFEFEFEFEFEFEFEFE + + fadd qword [rdx] + fisttp dword [rsi] + sub rdx, rdx + + ; check if (%rsi) is in range, and buffer available, otherwise call function + mov edx, dword [rsi] + test rdx, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_28 + mov rax, rdx + shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) + and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov rax, qword [rdi+rax] + test rax, rax + jz label_28 + and rdx, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdx, 3 ; log2(sizeof(EEL_F)) + add rax, rdx + jmp label_29 + + +label_28: + + mov r15, rsi ; save rsi + mov rsi, rdx ; esi becomes second parameter (edi is first, context pointer) + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdx + mov rsi, r15 ; restore rsi + add rsp, 128 +label_29: + + +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rdi, rdi + + fadd qword [rdx] + + fisttp dword [rsi] + + ; check if (%esi) is in range... + mov edi, dword [rsi] + test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_30 + mov rax, rdi + shr rax, 13 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void*)) + and rax, 0x3F8 ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov rax, qword [rcx+rax] + test rax, rax + jz label_30 + and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdi, 3 ; log2(sizeof(EEL_F)) + add rax, rdi + jmp label_31 + +label_30: + + mov rdx, rdi ; rdx is second parameter (rcx is first) + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; function ptr + sub rsp, 128 + call rdi + add rsp, 128 +label_31: + +%endif + + +%else + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [qword 0xFEFEFEFEFEFEFEFE] + fisttp dword [rsi] + + ; check if (%esi) is in range, and buffer available, otherwise call function + mov edi, dword [rsi] + test rdi, 0xff800000 ; 0xFFFFFFFF - (NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - 1) + jnz label_32 + + mov rax, rdi + shr rax, 14 ; log2(NSEEL_RAM_ITEMSPERBLOCK) - log2(sizeof(void *)) + and rax, 0x1FC ; (NSEEL_RAM_BLOCKS-1)*sizeof(void*) + mov eax, dword [rdx+rax] + test rax, rax + jz label_32 + and rdi, 0xFFFF ; (NSEEL_RAM_ITEMSPERBLOCK-1) + shl rdi, 3 ; log2(sizeof(EEL_F)) + add rax, rdi + jmp label_33 + + +label_32: + + sub rsp, 8 ; keep stack aligned + push rdi ; parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +label_33: + + + +%endif + + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_megabuf_end +_asm_megabuf_end: + + +global _asm_gmegabuf +_asm_gmegabuf: + + + +%ifdef TARGET_X64 + + +%ifdef AMD64ABI + + mov r15, rsi + mov rdi, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rdx] + fisttp dword [r15] + xor rsi, rsi + mov esi, dword [r15] ; r15 = esi (from above) + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdx + mov rsi, r15 + add rsp, 128 + +%else + mov rcx, qword 0xFEFEFEFEFEFEFEFE ; first parameter = context pointer + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [rdx] + fisttp dword [rsi] + xor rdx, rdx + mov edx, dword [rsi] + mov rdi, qword 0xFEFEFEFEFEFEFEFE + sub rsp, 128 + call rdi + add rsp, 128 +%endif + + +%else + mov rdx, qword 0xFEFEFEFEFEFEFEFE + fadd qword [qword 0xFEFEFEFEFEFEFEFE] + fisttp dword [rsi] + sub rsp, 8 ; keep stack aligned + push dword [rsi] ; parameter + push rdx ; push context pointer + mov rdi, qword 0xFEFEFEFEFEFEFEFE + call rdi + add rsp, 16 + +%endif + + + +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + +global _asm_gmegabuf_end +_asm_gmegabuf_end: + + +global nseel_asm_stack_push +nseel_asm_stack_push: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rax] + mov rax, qword [rdi] + add rax, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx + mov qword [rax], rcx + mov qword [rdi], rax +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + + mov ecx, dword [rax] + mov edx, dword [rax+4] + + mov eax, dword [rdi] + + add rax, 8 + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE + + mov dword [rax], ecx + mov dword [rax+4], edx + + mov dword [rdi], eax +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_push_end +nseel_asm_stack_push_end: + + +global nseel_asm_stack_pop +nseel_asm_stack_pop: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + movq xmm0, [rcx] + sub rcx, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rcx, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rcx, rdx + mov qword [rdi], rcx + movq [rax], xmm0 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + fld qword [rcx] + sub rcx, 8 + and rcx, qword 0xFEFEFEFEFEFEFEFE + or rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rdi], ecx + fstp qword [rax] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_pop_end +nseel_asm_stack_pop_end: + + +global nseel_asm_stack_pop_fast +nseel_asm_stack_pop_fast: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + mov rax, rcx + sub rcx, 8 + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rcx, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rcx, rdx + mov qword [rdi], rcx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + mov rax, rcx + sub rcx, 8 + and rcx, qword 0xFEFEFEFEFEFEFEFE + or rcx, qword 0xFEFEFEFEFEFEFEFE + mov dword [rdi], ecx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_pop_fast_end +nseel_asm_stack_pop_fast_end: + + +global nseel_asm_stack_peek_int +nseel_asm_stack_peek_int: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rax, qword [rdi] + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov eax, dword [rdi] + mov rdx, qword 0xFEFEFEFEFEFEFEFE + sub rax, rdx + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_peek_int_end +nseel_asm_stack_peek_int_end: + + +global nseel_asm_stack_peek +nseel_asm_stack_peek: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + fisttp dword [rsi] + mov rax, qword [rdi] + mov rdx, qword [rsi] + shl rdx, 3 ; log2(sizeof(EEL_F)) + sub rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + and rax, rdx + mov rdx, qword 0xFEFEFEFEFEFEFEFE + or rax, rdx +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + fisttp dword [rsi] + mov eax, dword [rdi] + mov edx, dword [rsi] + shl rdx, 3 ; log2(sizeof(EEL_F)) + sub rax, rdx + and rax, qword 0xFEFEFEFEFEFEFEFE + or rax, qword 0xFEFEFEFEFEFEFEFE +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_peek_end +nseel_asm_stack_peek_end: + + +global nseel_asm_stack_peek_top +nseel_asm_stack_peek_top: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rax, qword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov eax, dword [rdi] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_peek_top_end +nseel_asm_stack_peek_top_end: + + +global nseel_asm_stack_exch +nseel_asm_stack_exch: +%ifdef TARGET_X64 + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov rcx, qword [rdi] + movq xmm0, [rcx] + movq xmm1, [rax] + movq [rax], xmm0 + movq [rcx], xmm1 +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%else + + mov rdi, qword 0xFEFEFEFEFEFEFEFE + mov ecx, dword [rdi] + fld qword [rcx] + fld qword [rax] + fstp qword [rcx] + fstp qword [rax] +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif + + +global nseel_asm_stack_exch_end +nseel_asm_stack_exch_end: +%ifdef TARGET_X64 + + +global win64_callcode +win64_callcode: + +%ifdef AMD64ABI + mov rax, rdi +%else + mov rax, rcx +%endif + + push rbx + push rbp +%ifndef AMD64ABI + push rdi + push rsi + push r12 + push r13 +%endif + push r14 ; on AMD64ABI, we'll use r14/r15 to save edi/esi + push r15 + call rax + pop r15 + pop r14 +%ifndef AMD64ABI + pop r13 + pop r12 + pop rsi + pop rdi + fclex +%endif + pop rbp + pop rbx + ret +db 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 +%endif diff --git a/WDL/eel2/asm-nseel-x64.obj b/WDL/eel2/asm-nseel-x64.obj new file mode 100644 index 0000000000000000000000000000000000000000..a9c13738826fc63684235bf48f2c5e19b54b1beb GIT binary patch literal 9975 zcmbuDe{56N6~|vlNCE>VTct2DM4?J5p_Meh2p}P7CfF`x;>T!1D`;FNu@es`Hn9!S zgc_p3rYBb$t2%_%twP(RcGdPz*G+(`m9T0fteX;;XiVaSpskRJwv0_{h^Bbo``%05 zIrrL53QvlB&gXv5x##|P_q~_a@8%h!yZ7#y_87)*4g0E$`MYC|Eq^YeZ4-W_X69OD z?0&&K>0aX9Y3E9<{CCNVg`)S)DrnOmh~D?45h%GEUTdi z89Xy}44{A_VNN>bB=!}E-iwA&YKY#OhHp0a?TO>+_IVk%6xhmu0VEKCT#hQL$me43_ryk9= zvNCv%#f2pGD9uJ~tF~p3P)P03KI&0>L~gw7mCaR_6HYTydvt<&)E;^A;rg}1X+~;~ z_EV4ABP9>j@92G+jM}N9WdG>>hf1CtANJsHXMw1`(z{vSu(5@SuNHh-Z3lLS1yQ(G!~6!q&A*A#b|~!_IdZ%PY+Bik#zP6 zksiPUNeXE!wdEq=A$C6xnxpkFj-5Jf99=BV$zOSi^D_@Ur_07Y=_}7QIcY_@Kc1rb zsI7&jugp=+yt~D)7s|e~K6d29EEngL+S7w`6>#E0`~kv7Cz9h0BL~VSUmd$4Dhx~} zod;^`O0h1dK53_1m?NblL9e-U$vG)X-kw;1WleretD?3#lH55{MI&DnW}htbmvS7! zycEmF2}(0kJA*!+OFuL?n;N%FfA;qbB8=x03iGnNFSeVL+s!`r^>F5OZsxU;mQL-@ zlw^)~Q+Jb^Q`^l84^qsOJ0dq+=K5@J$)u8tZXPuWod;@XszI0+)$rW2(J->Ld~(>6 z*erT+{2eo*W!Oxj@AgtrF_~`|+YfL_v9Asj(zrZY?iJhRO@} zKGX1Y!!r$y4g2;rZa4py9&GZyI()Oi+tAeTe8Yj~_a~ny$0n4~f2a%uLw*?Yn#N9S z%kxD$)^*h-8#J(+%Sh z{K=P2mprbKbs)!?MlcfcHTy%}Dr4Bu*nK?R!sBEm$WNK3N+X*=&N0nyjWmH=WtxaadO$v5nwK?l24pD~3O~+z zy`_x^BF#va!v(ClYX1@Jgo4)SfLsnf_;Kwe>* zrx~$(UuXQu(clM{A3s+efPF=F?=(P(ru_H4Wk%|RCRjz;=He#kV}HF6u|*Gw~|k;Q1g&NM4E@&t%cNJqL^ zBfCJ>GEJ*Sx;kys44%Ag7t;uNoNxd5dZO!-zfe)m1kfjXm@E@b0jv zGL2M#lorw1*uaRBxn`rI$u}HQyKR=pJ--c6&$2v?j5ty2Ps~O+r2dUrBJ;E%>TQnLp!qtBdPyU4&40i&Z)@bwAlI4ZLygEaU-3D*rXGxv zlM0Ylrg=&u-vs$N)3j@(2jn)>{Fo7YHfpO^;J;e--QpR7ZZxnBJq_tIXz5Y&$YPdqW85B{HL`tHH#^3F4 zsUaH6S2V%S!_h-sF`{yaqHAq#^S1e8(U`C0U?kQ>^h%2o7Y%k2Ej*>YB}_*FPic?& zXgoZn9mUi9hr0B3IygC2MG*?Okqq$k_UbCGsIF2p_@E>Tcxrnz8f>Ej@mV0F${Xkk zcLX9dpDng|mKa|&mOapI%pRSgKN-gNrH^e~czU}x%u0tO9LcEi29TfjYD*v{_qI|Dm{#R%Q804$Oxtn?Z`w z*Bm}fE4O?_ga62dkN6Lf@i|1*g~Op(m>tE<4pNkXNGvRyNXi+cD6v0?2%g&R>!$6# zZnYf|tRk5rpq{WDh~p{?Sh=iMkT!p(zbn{M8}W5@7#hi}^LF`Ttr^4;YY{bCW{YIj z>6vYD#>~}PW{YTGCecxM!)}{H`qx}1}B}Z6bm{B3}wie(y#j6g%i aD1Ud0K2s7}>LbC<`Z}*Xu3Eyae&hd+%t +#include + +#define YY_USER_ACTION yylloc->first_line = yylineno; + +#define YY_FATAL_ERROR(msg) { ((struct yyguts_t*)yyscanner)->yyextra_r->errVar=1; } +#define YY_INPUT(buf,result,max_size) { (result) = nseel_gets(yyextra,(buf),max_size); } + +#define YY_EXTRA_TYPE compileContext * + +#undef YY_BUF_SIZE +#define YY_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN*2) + +#undef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE (NSEEL_MAX_VARIABLE_NAMELEN) + +#include "y.tab.h" + +#ifdef _WIN32 +#define YY_NO_UNISTD_H +#endif + +#include "ns-eel-int.h" + +int nseel_gets(compileContext *ctx, char *buf, size_t sz); + +#define PARSENUM *yylval = nseel_translate(yyextra,yytext); return VALUE; +#define EEL_ACTION(x) return x; + +#ifdef stdin +#undef stdin +#endif +#define stdin (0) + +#ifdef stdout +#undef stdout +#endif +#define stdout (0) + +static int g_fake_errno; +#ifdef errno +#undef errno +#endif + +#define errno g_fake_errno + +%} + +%% + +[0-9]+\.?[0-9]* PARSENUM; +\.[0-9]+ PARSENUM; +0[xX][0-9a-fA-F]+ PARSENUM; + +[a-zA-Z_][a-zA-Z0-9\._]* do { int toktype=IDENTIFIER; *yylval = nseel_lookup(yyextra,&toktype, yytext); return toktype; } while (0); + +[ \t\r\n]+ /* whitespace */ + +. return (int)yytext[0]; + +%% diff --git a/WDL/eel2/eel2.y b/WDL/eel2/eel2.y new file mode 100644 index 00000000..b5317cc2 --- /dev/null +++ b/WDL/eel2/eel2.y @@ -0,0 +1,147 @@ +%pure-parser +%name-prefix="nseel" +%parse-param { compileContext* context } +%lex-param { void* scanner } + + +/* this will prevent y.tab.c from ever calling yydestruct(), since we do not use it and it is a waste */ +%destructor { + #define yydestruct(a,b,c,d,e) 0 +} VALUE + + +%{ +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include + +#include "y.tab.h" +#include "ns-eel-int.h" + +#define scanner context->scanner +#define YY_(x) ("") + +%} + +%token VALUE IDENTIFIER FUNCTION1 FUNCTION2 FUNCTION3 FUNCTIONX + + +%start program + +%% + +more_params: + expression + | expression ',' more_params + { + $$ = nseel_createMoreParametersOpcode(context,$1,$3); + } + ; + +value_thing: + VALUE + | IDENTIFIER + | '(' expression ')' + { + $$ = $2; + } + | FUNCTION1 '(' expression ')' + { + $$ = nseel_setCompiledFunctionCallParameters($1, $3, 0, 0); + } + | FUNCTION2 '(' expression ',' expression ')' + { + $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, 0); + } + | FUNCTION3 '(' expression ',' expression ',' expression ')' + { + $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, $7); + } + | FUNCTIONX '(' expression ',' expression ',' more_params ')' + { + $$ = nseel_setCompiledFunctionCallParameters($1, $3, $5, $7); + } + ; + +unary_expr: + value_thing + | '+' unary_expr + { + $$ = $2; + } + | '-' unary_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,$2,0); + } + ; + + +div_expr: + unary_expr + | div_expr '/' unary_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,$1,$3); + } + ; + + +mul_expr: + div_expr + | mul_expr '*' div_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,$1,$3); + } + ; + + +sub_expr: + mul_expr + | sub_expr '-' mul_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_SUB,2,$1,$3); + } + ; + +add_expr: + sub_expr + | add_expr '+' sub_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_ADD,2,$1,$3); + } + ; + +andor_expr: + add_expr + | andor_expr '&' add_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_AND,2,$1,$3); + } + | andor_expr '|' add_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_OR,2,$1,$3); + } + ; + +expression: + andor_expr + | expression '%' andor_expr + { + $$ = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,$1,$3); + } + ; + + +program: + expression + { + int a = @1.first_line; + context->result = $1; + } + ; + + +%% diff --git a/WDL/eel2/gen-lex-yacc b/WDL/eel2/gen-lex-yacc new file mode 100644 index 00000000..6fd3b4cf --- /dev/null +++ b/WDL/eel2/gen-lex-yacc @@ -0,0 +1 @@ +yacc -v -d eel2.y && flex eel2.l diff --git a/WDL/eel2/glue_port.h b/WDL/eel2/glue_port.h new file mode 100644 index 00000000..eb8fb2c9 --- /dev/null +++ b/WDL/eel2/glue_port.h @@ -0,0 +1,995 @@ +#ifndef _EEL_GLUE_PORTABLE_H_ +#define _EEL_GLUE_PORTABLE_H_ + + +#define DECL_ASMFUNC(x) +#define GLUE_JMP_TYPE int +#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((GLUE_JMP_TYPE *)(endOfInstruction))[-1] = (offset)) + +#define GLUE_HAS_FXCH +#define GLUE_MAX_FPSTACK_SIZE 64 +#define BIF_FPSTACKUSE(x) (0) // fp stack is not used within functions +#define BIF_GETFPSTACKUSE(x) (1) + +enum { + EEL_BC_NOP=1, + EEL_BC_RET, + EEL_BC_JMP_NC, // followed by GLUE_JMP_TYPE + EEL_BC_JMP_IF_P1_Z, + EEL_BC_JMP_IF_P1_NZ, + + EEL_BC_MOV_FPTOP_DV, + EEL_BC_MOV_P1_DV, // followed by INT_PTR ptr + EEL_BC_MOV_P2_DV, + EEL_BC_MOV_P3_DV, + EEL_BC__RESET_WTP, + + EEL_BC_PUSH_P1, + EEL_BC_PUSH_P1PTR_AS_VALUE, + EEL_BC_POP_P1, + EEL_BC_POP_P2, + EEL_BC_POP_P3, + EEL_BC_POP_VALUE_TO_ADDR, + + EEL_BC_SET_P2_FROM_P1, + EEL_BC_SET_P3_FROM_P1, + EEL_BC_COPY_VALUE_AT_P1_TO_ADDR, + EEL_BC_SET_P1_FROM_WTP, + EEL_BC_SET_P2_FROM_WTP, + EEL_BC_SET_P3_FROM_WTP, + + EEL_BC_POP_FPSTACK_TO_PTR, + EEL_BC_POP_FPSTACK_TOSTACK, + + EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, + EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, + EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, + EEL_BC_POP_FPSTACK_TO_WTP, + EEL_BC_SET_P1_Z, + EEL_BC_SET_P1_NZ, + + EEL_BC_LOOP_LOADCNT, + EEL_BC_LOOP_END, + + EEL_BC_WHILE_SETUP, + EEL_BC_WHILE_END, + EEL_BC_WHILE_CHECK_RV, + + + + EEL_BC_BNOT, + EEL_BC_EQUAL, + EEL_BC_NOTEQUAL, + EEL_BC_ABOVE, + EEL_BC_BELOWEQ, + + + EEL_BC_ADD, + EEL_BC_SUB, + EEL_BC_MUL, + EEL_BC_DIV, + EEL_BC_AND, + EEL_BC_OR, + EEL_BC_OR0, + EEL_BC_XOR, + + EEL_BC_ADD_OP, + EEL_BC_SUB_OP, + EEL_BC_ADD_OP_FAST, + EEL_BC_SUB_OP_FAST, + EEL_BC_MUL_OP, + EEL_BC_DIV_OP, + EEL_BC_AND_OP, + EEL_BC_OR_OP, + EEL_BC_XOR_OP, + + EEL_BC_UMINUS, + + EEL_BC_ASSIGN, + EEL_BC_ASSIGN_FAST, + EEL_BC_ASSIGN_FAST_FROMFP, + EEL_BC_ASSIGN_FROMFP, + EEL_BC_MOD, + EEL_BC_MOD_OP, + EEL_BC_SHR, + EEL_BC_SHL, + + EEL_BC_SQR, + EEL_BC_MIN, + EEL_BC_MAX, + EEL_BC_MIN_FP, + EEL_BC_MAX_FP, + EEL_BC_ABS, + EEL_BC_SIGN, + EEL_BC_INVSQRT, + + EEL_BC_FXCH, + EEL_BC_POP_FPSTACK, + + EEL_BC_FCALL, + EEL_BC_BOOLTOFP, + EEL_BC_FPTOBOOL, + + EEL_BC_CFUNC_1PDD, + EEL_BC_CFUNC_2PDD, + EEL_BC_CFUNC_2PDDS, + + EEL_BC_MEGABUF, + EEL_BC_GMEGABUF, + + EEL_BC_GENERIC1PARM, + EEL_BC_GENERIC2PARM, + EEL_BC_GENERIC3PARM, + EEL_BC_GENERIC1PARM_RETD, + EEL_BC_GENERIC2PARM_RETD, + EEL_BC_GENERIC3PARM_RETD, + + EEL_BC_USERSTACK_PUSH, + EEL_BC_USERSTACK_POP, + EEL_BC_USERSTACK_POPFAST, + EEL_BC_USERSTACK_PEEK, + EEL_BC_USERSTACK_PEEK_INT, + EEL_BC_USERSTACK_PEEK_TOP, + EEL_BC_USERSTACK_EXCH, + + EEL_BC_DBG_GETSTACKPTR, + +}; + +#define BC_DECL(x) static const EEL_BC_TYPE GLUE_##x[] = { EEL_BC_##x }; +#define BC_DECL_JMP(x) static const EEL_BC_TYPE GLUE_##x[1 + sizeof(GLUE_JMP_TYPE) / sizeof(EEL_BC_TYPE)] = { EEL_BC_##x }; +BC_DECL_JMP(JMP_NC) +BC_DECL_JMP(JMP_IF_P1_Z) +BC_DECL_JMP(JMP_IF_P1_NZ) +BC_DECL(RET) +BC_DECL(FXCH) +BC_DECL(POP_FPSTACK) +#define GLUE_POP_FPSTACK_SIZE sizeof(EEL_BC_TYPE) +BC_DECL(PUSH_P1) +BC_DECL(PUSH_P1PTR_AS_VALUE) +BC_DECL(POP_FPSTACK_TOSTACK) +BC_DECL(POP_FPSTACK_TO_WTP) +BC_DECL(SET_P1_Z) +BC_DECL(SET_P1_NZ) +BC_DECL_JMP(LOOP_LOADCNT) +BC_DECL_JMP(LOOP_END) +static const EEL_BC_TYPE GLUE_LOOP_CLAMPCNT[1]={EEL_BC_NOP}; +static const EEL_BC_TYPE GLUE_LOOP_BEGIN[1]={EEL_BC_NOP}; +static const EEL_BC_TYPE GLUE_WHILE_BEGIN[1]={EEL_BC_NOP}; + +BC_DECL(WHILE_SETUP) +BC_DECL_JMP(WHILE_END) +BC_DECL_JMP(WHILE_CHECK_RV) + +#define GLUE_MOV_PX_DIRECTVALUE_SIZE (sizeof(EEL_BC_TYPE) + sizeof(INT_PTR)) +#define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE GLUE_MOV_PX_DIRECTVALUE_SIZE +static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) +{ + static const EEL_BC_TYPE tab[] = { + EEL_BC_MOV_FPTOP_DV, + EEL_BC_MOV_P1_DV, + EEL_BC_MOV_P2_DV, + EEL_BC_MOV_P3_DV, + }; + *(EEL_BC_TYPE *)b = tab[wv+1]; + *(INT_PTR *) ((char *)b + sizeof(EEL_BC_TYPE)) = v; +} + +#define GLUE_FUNC_ENTER_SIZE 0 +#define GLUE_FUNC_LEAVE_SIZE 0 +static const EEL_BC_TYPE GLUE_FUNC_ENTER[1]={-1}; +static const EEL_BC_TYPE GLUE_FUNC_LEAVE[1]={-1}; + +static int GLUE_RESET_WTP(unsigned char *out, void *ptr) +{ + BC_DECL(_RESET_WTP) + if (out) memcpy(out,&GLUE__RESET_WTP,sizeof(GLUE__RESET_WTP)); + if (out) *(void **) (out+sizeof(GLUE__RESET_WTP)) = ptr; + return sizeof(GLUE__RESET_WTP) + sizeof(void *); +} + +#define GLUE_POP_PX_SIZE sizeof(EEL_BC_TYPE) +static void GLUE_POP_PX(void *b, int wv) +{ + static const EEL_BC_TYPE tab[3] ={ + EEL_BC_POP_P1, + EEL_BC_POP_P2, + EEL_BC_POP_P3, + }; + *(EEL_BC_TYPE *)b = tab[wv]; +} + +#define GLUE_SET_PX_FROM_P1_SIZE sizeof(EEL_BC_TYPE) +static void GLUE_SET_PX_FROM_P1(void *b, int wv) +{ + static const unsigned int tab[3]={ + EEL_BC_NOP, + EEL_BC_SET_P2_FROM_P1, + EEL_BC_SET_P3_FROM_P1, + }; + *(EEL_BC_TYPE *)b = tab[wv]; +} + +static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) +{ + if (buf) + { + *(EEL_BC_TYPE *)buf = EEL_BC_POP_VALUE_TO_ADDR; + *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; + } + return sizeof(EEL_BC_TYPE) + sizeof(void *); +} + +static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) +{ + if (buf) + { + *(EEL_BC_TYPE *)buf = EEL_BC_COPY_VALUE_AT_P1_TO_ADDR; + *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; + } + return sizeof(EEL_BC_TYPE) + sizeof(void *); +} + + + + +static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) +{ + int mv=5; + char *p=(char*)_p; + p+=sizeof(EEL_BC_TYPE); + while (*(INT_PTR*)p && mv-- > 0) p++; + if (!mv) return p; + + *(INT_PTR *)p = newv; + return (unsigned char *) p + sizeof(INT_PTR) - sizeof(EEL_BC_TYPE); +} + +#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(EEL_BC_TYPE) +static void GLUE_SET_PX_FROM_WTP(void *b, int wv) +{ + static const EEL_BC_TYPE tab[3]={ + EEL_BC_SET_P1_FROM_WTP, + EEL_BC_SET_P2_FROM_WTP, + EEL_BC_SET_P3_FROM_WTP, + }; + *(EEL_BC_TYPE *)b = tab[wv]; +} + +static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) +{ + if (buf) + { + *(EEL_BC_TYPE *)buf = EEL_BC_POP_FPSTACK_TO_PTR; + *(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr; + } + return sizeof(EEL_BC_TYPE) + sizeof(void *); +} + + #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE sizeof(EEL_BC_TYPE) + static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) + { + static const EEL_BC_TYPE tab[3] = { + EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK, + EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK, + EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK, + }; + *(EEL_BC_TYPE *)b = tab[wv]; + } + +#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) +static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) +{ + GLUE_SET_PX_FROM_WTP(buf,wv); + memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); +}; + +static unsigned char GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo + +#define GLUE_INLINE_LOOPS + +// end of bytecode glue, now for stubbage + +#define EEL_BC_ENDOF(x) (((char*)(x))+sizeof(x)) +#define BC_DECLASM(x,y) static EEL_BC_TYPE nseel_asm_##x[1]={EEL_BC_##y}; + +BC_DECLASM(if,NOP) +BC_DECLASM(band,NOP) +BC_DECLASM(bor,NOP) +BC_DECLASM(repeat,NOP) +BC_DECLASM(repeatwhile,NOP) + +BC_DECLASM(bnot,BNOT) +BC_DECLASM(equal,EQUAL) +BC_DECLASM(notequal,NOTEQUAL) +BC_DECLASM(above,ABOVE) +BC_DECLASM(beloweq,BELOWEQ) + +BC_DECLASM(add,ADD) +BC_DECLASM(sub,SUB) +BC_DECLASM(mul,MUL) +BC_DECLASM(div,DIV) +BC_DECLASM(and,AND) +BC_DECLASM(or,OR) +BC_DECLASM(or0,OR0) +BC_DECLASM(xor,XOR) + +BC_DECLASM(add_op,ADD_OP) +BC_DECLASM(sub_op,SUB_OP) +BC_DECLASM(add_op_fast,ADD_OP_FAST) +BC_DECLASM(sub_op_fast,SUB_OP_FAST) +BC_DECLASM(mul_op,MUL_OP) +BC_DECLASM(div_op,DIV_OP) +BC_DECLASM(and_op,AND_OP) +BC_DECLASM(or_op,OR_OP) +BC_DECLASM(xor_op,XOR_OP) + +BC_DECLASM(uminus,UMINUS) + +BC_DECLASM(assign,ASSIGN) +BC_DECLASM(assign_fast,ASSIGN_FAST) +BC_DECLASM(assign_fast_fromfp,ASSIGN_FAST_FROMFP) +BC_DECLASM(assign_fromfp,ASSIGN_FROMFP) +BC_DECLASM(mod,MOD) +BC_DECLASM(mod_op,MOD_OP) +BC_DECLASM(shr,SHR) +BC_DECLASM(shl,SHL) +BC_DECLASM(sqr,SQR) + +BC_DECLASM(min,MIN) +BC_DECLASM(max,MAX) +BC_DECLASM(min_fp,MIN_FP) +BC_DECLASM(max_fp,MAX_FP) +BC_DECLASM(abs,ABS) +BC_DECLASM(sign,SIGN) +BC_DECLASM(invsqrt,INVSQRT) +BC_DECLASM(dbg_getstackptr,DBG_GETSTACKPTR) + +BC_DECLASM(booltofp,BOOLTOFP) +BC_DECLASM(fptobool,FPTOBOOL) + +#define BC_DECLASM_N(x,y,n) static EEL_BC_TYPE nseel_asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; + +#define BC_DECLASM_N_EXPORT(x,y,n) EEL_BC_TYPE _asm_##x[1 + (n*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE)]={EEL_BC_##y, }; EEL_BC_TYPE _asm_##x##_end[1]={1,}; + +BC_DECLASM_N(stack_push,USERSTACK_PUSH,3) +BC_DECLASM_N(stack_pop,USERSTACK_POP,3) +BC_DECLASM_N(stack_pop_fast,USERSTACK_POPFAST,3) +BC_DECLASM_N(stack_peek,USERSTACK_PEEK,3) + +BC_DECLASM_N(stack_peek_int,USERSTACK_PEEK_INT,4) + +BC_DECLASM_N(stack_peek_top,USERSTACK_PEEK_TOP,1) +BC_DECLASM_N(stack_exch,USERSTACK_EXCH,1) + +BC_DECLASM_N(fcall,FCALL,1) + +BC_DECLASM_N(1pdd,CFUNC_1PDD,1) +BC_DECLASM_N(2pdd,CFUNC_2PDD,1) +BC_DECLASM_N(2pdds,CFUNC_2PDDS,1) + +BC_DECLASM_N_EXPORT(megabuf,MEGABUF,0) +BC_DECLASM_N_EXPORT(gmegabuf,GMEGABUF,2) +BC_DECLASM_N_EXPORT(generic1parm,GENERIC1PARM,2) +BC_DECLASM_N_EXPORT(generic2parm,GENERIC2PARM,2) +BC_DECLASM_N_EXPORT(generic3parm,GENERIC3PARM,2) +BC_DECLASM_N_EXPORT(generic1parm_retd,GENERIC1PARM_RETD,2) +BC_DECLASM_N_EXPORT(generic2parm_retd,GENERIC2PARM_RETD,2) +BC_DECLASM_N_EXPORT(generic3parm_retd,GENERIC3PARM_RETD,2) + + +#define nseel_asm_1pdd_end EEL_BC_ENDOF(nseel_asm_1pdd) +#define nseel_asm_2pdd_end EEL_BC_ENDOF(nseel_asm_2pdd) +#define nseel_asm_2pdds_end EEL_BC_ENDOF(nseel_asm_2pdds) + +#define nseel_asm_fcall_end EEL_BC_ENDOF(nseel_asm_fcall) + +#define nseel_asm_if_end EEL_BC_ENDOF(nseel_asm_if) +#define nseel_asm_band_end EEL_BC_ENDOF(nseel_asm_band) +#define nseel_asm_bor_end EEL_BC_ENDOF(nseel_asm_bor) +#define nseel_asm_repeat_end EEL_BC_ENDOF(nseel_asm_repeat) +#define nseel_asm_repeatwhile_end EEL_BC_ENDOF(nseel_asm_repeatwhile) +#define nseel_asm_bnot_end EEL_BC_ENDOF(nseel_asm_bnot) +#define nseel_asm_equal_end EEL_BC_ENDOF(nseel_asm_equal) +#define nseel_asm_notequal_end EEL_BC_ENDOF(nseel_asm_notequal) +#define nseel_asm_above_end EEL_BC_ENDOF(nseel_asm_above) +#define nseel_asm_beloweq_end EEL_BC_ENDOF(nseel_asm_beloweq) + +#define nseel_asm_min_end EEL_BC_ENDOF(nseel_asm_min) +#define nseel_asm_max_end EEL_BC_ENDOF(nseel_asm_max) +#define nseel_asm_abs_end EEL_BC_ENDOF(nseel_asm_abs) +#define nseel_asm_min_fp_end EEL_BC_ENDOF(nseel_asm_min_fp) +#define nseel_asm_max_fp_end EEL_BC_ENDOF(nseel_asm_max_fp) +#define nseel_asm_sign_end EEL_BC_ENDOF(nseel_asm_sign) +#define nseel_asm_invsqrt_end EEL_BC_ENDOF(nseel_asm_invsqrt) +#define nseel_asm_dbg_getstackptr_end EEL_BC_ENDOF(nseel_asm_dbg_getstackptr) + + +#define nseel_asm_add_end EEL_BC_ENDOF(nseel_asm_add) +#define nseel_asm_sub_end EEL_BC_ENDOF(nseel_asm_sub) +#define nseel_asm_mul_end EEL_BC_ENDOF(nseel_asm_mul) +#define nseel_asm_div_end EEL_BC_ENDOF(nseel_asm_div) +#define nseel_asm_and_end EEL_BC_ENDOF(nseel_asm_and) +#define nseel_asm_or_end EEL_BC_ENDOF(nseel_asm_or) +#define nseel_asm_or0_end EEL_BC_ENDOF(nseel_asm_or0) +#define nseel_asm_xor_end EEL_BC_ENDOF(nseel_asm_xor) + +#define nseel_asm_add_op_end EEL_BC_ENDOF(nseel_asm_add_op) +#define nseel_asm_sub_op_end EEL_BC_ENDOF(nseel_asm_sub_op) +#define nseel_asm_add_op_fast_end EEL_BC_ENDOF(nseel_asm_add_op_fast) +#define nseel_asm_sub_op_fast_end EEL_BC_ENDOF(nseel_asm_sub_op_fast) +#define nseel_asm_mul_op_end EEL_BC_ENDOF(nseel_asm_mul_op) +#define nseel_asm_div_op_end EEL_BC_ENDOF(nseel_asm_div_op) +#define nseel_asm_and_op_end EEL_BC_ENDOF(nseel_asm_and_op) +#define nseel_asm_or_op_end EEL_BC_ENDOF(nseel_asm_or_op) +#define nseel_asm_xor_op_end EEL_BC_ENDOF(nseel_asm_xor_op) + +#define nseel_asm_uminus_end EEL_BC_ENDOF(nseel_asm_uminus) +#define nseel_asm_assign_end EEL_BC_ENDOF(nseel_asm_assign) +#define nseel_asm_assign_fast_end EEL_BC_ENDOF(nseel_asm_assign_fast) +#define nseel_asm_assign_fast_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fast_fromfp) +#define nseel_asm_assign_fromfp_end EEL_BC_ENDOF(nseel_asm_assign_fromfp) +#define nseel_asm_mod_end EEL_BC_ENDOF(nseel_asm_mod) +#define nseel_asm_mod_op_end EEL_BC_ENDOF(nseel_asm_mod_op) +#define nseel_asm_shr_end EEL_BC_ENDOF(nseel_asm_shr) +#define nseel_asm_shl_end EEL_BC_ENDOF(nseel_asm_shl) + +#define nseel_asm_sqr_end EEL_BC_ENDOF(nseel_asm_sqr) + + +#define nseel_asm_booltofp_end EEL_BC_ENDOF(nseel_asm_booltofp) +#define nseel_asm_fptobool_end EEL_BC_ENDOF(nseel_asm_fptobool) + +#define nseel_asm_stack_push_end EEL_BC_ENDOF(nseel_asm_stack_push) +#define nseel_asm_stack_pop_end EEL_BC_ENDOF(nseel_asm_stack_pop) +#define nseel_asm_stack_pop_fast_end EEL_BC_ENDOF(nseel_asm_stack_pop_fast) +#define nseel_asm_stack_peek_end EEL_BC_ENDOF(nseel_asm_stack_peek) +#define nseel_asm_stack_peek_int_end EEL_BC_ENDOF(nseel_asm_stack_peek_int) +#define nseel_asm_stack_peek_top_end EEL_BC_ENDOF(nseel_asm_stack_peek_top) +#define nseel_asm_stack_exch_end EEL_BC_ENDOF(nseel_asm_stack_exch) + + +static void *GLUE_realAddress(void *fn, void *fn_e, int *size) +{ + *size = (char *)fn_e - (char *)fn; + return fn; +} + +#define EEL_BC_STACKSIZE (65536) + +// todo: check for stack overflows! we could determine if this is possible at compile time. +#define EEL_BC_STACK_ADV_SIZE 8 +#define EEL_BC_STACK_FWD() (stackptr += EEL_BC_STACK_ADV_SIZE) +#define EEL_BC_STACK_REW() (stackptr -= EEL_BC_STACK_ADV_SIZE) + +#define EEL_BC_TRUE ((EEL_F*)(INT_PTR)1) + + + + +static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) +{ + char __stack[EEL_BC_STACKSIZE]; + char *iptr = (char*)cp; + char *stackptr=__stack; + EEL_F *p1, *p2, *p3, *wtp = (EEL_F*)bp; +#define fp_top (_fpstacktop[0]) +#define fp_top2 (_fpstacktop[-1]) +#define fp_push(x) *++_fpstacktop=(x) +#define fp_pop() (*_fpstacktop--) +#define fp_rewind(x) { _fpstacktop -= (x); } + + EEL_F fpstack[GLUE_MAX_FPSTACK_SIZE]; + EEL_F *_fpstacktop=fpstack-1; + for (;;) + { + EEL_BC_TYPE inst = *(EEL_BC_TYPE *)iptr; + iptr += sizeof(EEL_BC_TYPE); + switch (inst) + { + case EEL_BC_FXCH: + { + EEL_F a = fp_top; + fp_top=fp_top2; + fp_top2=a; + } + break; + case EEL_BC_POP_FPSTACK: fp_rewind(1); break; + case EEL_BC_NOP: break; + case EEL_BC_RET: + EEL_BC_STACK_REW(); + if (stackptr < __stack) + { + return; + } + memcpy(&iptr, stackptr, sizeof(void *)); + break; + case EEL_BC_JMP_NC: + iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; + break; + case EEL_BC_JMP_IF_P1_Z: + iptr += p1 ? sizeof(GLUE_JMP_TYPE) : sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; + break; + case EEL_BC_JMP_IF_P1_NZ: + iptr += p1 ? sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr : sizeof(GLUE_JMP_TYPE); + break; + case EEL_BC_MOV_FPTOP_DV: + fp_push(**(EEL_F **)iptr); + iptr += sizeof(void*); + break; + case EEL_BC_MOV_P1_DV: + p1 = *(void **)iptr; + iptr += sizeof(void*); + break; + case EEL_BC_MOV_P2_DV: + p2 = *(void **)iptr; + iptr += sizeof(void*); + break; + case EEL_BC_MOV_P3_DV: + p3 = *(void **)iptr; + iptr += sizeof(void*); + break; + case EEL_BC__RESET_WTP: + wtp = *(void **)iptr; + iptr += sizeof(void*); + break; + case EEL_BC_PUSH_P1: + memcpy(stackptr,&p1,sizeof(void *)); + EEL_BC_STACK_FWD(); + break; + case EEL_BC_PUSH_P1PTR_AS_VALUE: + memcpy(stackptr,p1,sizeof(EEL_F)); + EEL_BC_STACK_FWD(); + break; + case EEL_BC_POP_P1: + EEL_BC_STACK_REW(); + memcpy(&p1,stackptr,sizeof(void *)); + break; + case EEL_BC_POP_P2: + EEL_BC_STACK_REW(); + memcpy(&p2,stackptr,sizeof(void *)); + break; + case EEL_BC_POP_P3: + EEL_BC_STACK_REW(); + memcpy(&p3,stackptr,sizeof(void *)); + break; + case EEL_BC_POP_VALUE_TO_ADDR: + EEL_BC_STACK_REW(); + memcpy(*(void **)iptr,stackptr,sizeof(EEL_F)); + iptr += sizeof(void*); + break; + case EEL_BC_SET_P2_FROM_P1: + p2=p1; + break; + case EEL_BC_SET_P3_FROM_P1: + p3=p1; + break; + case EEL_BC_COPY_VALUE_AT_P1_TO_ADDR: + memcpy(*(void **)iptr,p1,sizeof(EEL_F)); + iptr += sizeof(void*); + break; + case EEL_BC_SET_P1_FROM_WTP: + p1 = wtp; + break; + case EEL_BC_SET_P2_FROM_WTP: + p2 = wtp; + break; + case EEL_BC_SET_P3_FROM_WTP: + p3 = wtp; + break; + case EEL_BC_POP_FPSTACK_TO_PTR: + *((EEL_F *)iptr) = fp_pop(); + iptr += sizeof(void *); + break; + case EEL_BC_POP_FPSTACK_TOSTACK: + *(EEL_F*)stackptr = fp_pop(); + EEL_BC_STACK_FWD(); + break; + case EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK: + fp_push(*p1); + break; + case EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK: + fp_push(*p2); + break; + case EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK: + fp_push(*p3); + break; + case EEL_BC_POP_FPSTACK_TO_WTP: + *wtp++ = fp_pop(); + break; + case EEL_BC_SET_P1_Z: + p1=NULL; + break; + case EEL_BC_SET_P1_NZ: + p1 = EEL_BC_TRUE; + break; + + case EEL_BC_LOOP_LOADCNT: + if ((*(int *)stackptr = (int) fp_pop()) < 1) + { + iptr+= sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; + } + else + { + iptr += sizeof(GLUE_JMP_TYPE); + if (*(int *)stackptr > NSEEL_LOOPFUNC_SUPPORT_MAXLEN) *(int *)stackptr=NSEEL_LOOPFUNC_SUPPORT_MAXLEN; + stackptr += EEL_BC_STACK_ADV_SIZE; + *(void **)stackptr = wtp; + stackptr += EEL_BC_STACK_ADV_SIZE; + } + break; + case EEL_BC_LOOP_END: + if (--*(int *)(stackptr-2*EEL_BC_STACK_ADV_SIZE) <= 0) + { + stackptr -= 2*EEL_BC_STACK_ADV_SIZE; + iptr += sizeof(GLUE_JMP_TYPE); + } + else + { + wtp = *(void **) (stackptr - EEL_BC_STACK_ADV_SIZE); + iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // back to the start! + } + break; + + case EEL_BC_WHILE_SETUP: + *(int *)stackptr = NSEEL_LOOPFUNC_SUPPORT_MAXLEN; + stackptr += EEL_BC_STACK_ADV_SIZE; + *(void **)stackptr = wtp; + stackptr += EEL_BC_STACK_ADV_SIZE; + break; + case EEL_BC_WHILE_END: + if (--*(int *)(stackptr-2*EEL_BC_STACK_ADV_SIZE) <= 0) + { + stackptr -= EEL_BC_STACK_ADV_SIZE*2; + iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // endpt + } + else + { + iptr += sizeof(GLUE_JMP_TYPE); + } + break; + case EEL_BC_WHILE_CHECK_RV: + if (p1) + { + iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // loop + wtp = *(void **) (stackptr - EEL_BC_STACK_ADV_SIZE); + } + else + { + // done + stackptr -= EEL_BC_STACK_ADV_SIZE*2; + iptr += sizeof(GLUE_JMP_TYPE); + } + break; + case EEL_BC_BNOT: + p1 = p1 ? NULL : EEL_BC_TRUE; + break; + case EEL_BC_EQUAL: + p1 = fabs(fp_top - fp_top2) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; + fp_rewind(2); + break; + case EEL_BC_NOTEQUAL: + p1 = fabs(fp_top - fp_top2) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; + fp_rewind(2); + break; + case EEL_BC_ABOVE: + p1 = fp_top < fp_top2 ? EEL_BC_TRUE : NULL; + fp_rewind(2); + break; + case EEL_BC_BELOWEQ: + p1 = fp_top >= fp_top2 ? EEL_BC_TRUE : NULL; + fp_rewind(2); + break; + + case EEL_BC_ADD: + fp_top2 += fp_top; + fp_rewind(1); + break; + case EEL_BC_SUB: + fp_top2 -= fp_top; + fp_rewind(1); + break; + case EEL_BC_MUL: + fp_top2 *= fp_top; + fp_rewind(1); + break; + case EEL_BC_DIV: + fp_top2 /= fp_top; + fp_rewind(1); + break; + case EEL_BC_AND: + fp_top2 = (EEL_F) (((int)fp_top) & (int)(fp_top2)); + fp_rewind(1); + break; + case EEL_BC_OR: + fp_top2 = (EEL_F) (((int)fp_top) | (int)(fp_top2)); + fp_rewind(1); + break; + case EEL_BC_OR0: + fp_top = (EEL_F) ((int)(fp_top)); + break; + case EEL_BC_XOR: + fp_top2 = (EEL_F) (((int)fp_top) ^ (int)(fp_top2)); + fp_rewind(1); + break; + + case EEL_BC_ADD_OP: + *(p1 = p2) = denormal_filter_double2(*p2 + fp_pop()); + break; + case EEL_BC_SUB_OP: + *(p1 = p2) = denormal_filter_double2(*p2 - fp_pop()); + break; + case EEL_BC_ADD_OP_FAST: + *(p1 = p2) += fp_pop(); + break; + case EEL_BC_SUB_OP_FAST: + *(p1 = p2) -= fp_pop(); + break; + case EEL_BC_MUL_OP: + *(p1 = p2) = denormal_filter_double2(*p2 * fp_pop()); + break; + case EEL_BC_DIV_OP: + *(p1 = p2) = denormal_filter_double2(*p2 * fp_pop()); + break; + case EEL_BC_AND_OP: + p1 = p2; + *p2 = (EEL_F) (((int)*p2) & (int)fp_pop()); + break; + case EEL_BC_OR_OP: + p1 = p2; + *p2 = (EEL_F) (((int)*p2) | (int)fp_pop()); + break; + case EEL_BC_XOR_OP: + p1 = p2; + *p2 = (EEL_F) (((int)*p2) ^ (int)fp_pop()); + break; + case EEL_BC_UMINUS: + fp_top = -fp_top; + break; + case EEL_BC_ASSIGN: + *p2 = denormal_filter_double2(*p1); + p1 = p2; + break; + + case EEL_BC_ASSIGN_FAST: + *p2 = *p1; + break; + case EEL_BC_ASSIGN_FAST_FROMFP: + *p2 = fp_pop(); + p1 = p2; + break; + case EEL_BC_ASSIGN_FROMFP: + *p2 = denormal_filter_double2(fp_pop()); + p1 = p2; + break; + case EEL_BC_MOD: + { + int a = (int) (fp_pop()); + fp_top = a ? (EEL_F) ((int)fp_top % a) : 0.0; + } + break; + case EEL_BC_MOD_OP: + { + int a = (int) (fp_pop()); + *p2 = a ? (EEL_F) ((int)*p2 % a) : 0.0; + p1=p2; + + } + break; + case EEL_BC_SHR: + fp_top2 = (EEL_F) (((int)fp_top2) >> (int)fp_top); + fp_rewind(1); + break; + case EEL_BC_SHL: + fp_top2 = (EEL_F) (((int)fp_top2) << (int)fp_top); + fp_rewind(1); + break; + case EEL_BC_SQR: + fp_top *= fp_top; + break; + case EEL_BC_MIN: + if (*p1 > *p2) p1 = p2; + break; + case EEL_BC_MAX: + if (*p1 < *p2) p1 = p2; + break; + case EEL_BC_MIN_FP: + { + EEL_F a=fp_pop(); + if (afp_top) fp_top=a; + } + break; + case EEL_BC_ABS: + fp_top = fabs(fp_top); + break; + case EEL_BC_SIGN: + if (fp_top<0.0) fp_top=-1.0; + else if (fp_top>0.0) fp_top=1.0; + break; + case EEL_BC_DBG_GETSTACKPTR: + fp_top = (int)(INT_PTR)stackptr; + break; + case EEL_BC_INVSQRT: + { + float y = (float)fp_top; + int i = 0x5f3759df - ( (* (int *) &y) >> 1 ); + y = *(float *) &i; + fp_top = y * ( 1.5F - ( (fp_top * 0.5) * y * y ) ); + } + break; + case EEL_BC_FCALL: + { + char *newiptr = *(char **)iptr; + iptr += sizeof(void *); + memcpy(stackptr, &iptr, sizeof(void *)); + EEL_BC_STACK_FWD(); + iptr = newiptr; + } + break; + case EEL_BC_BOOLTOFP: + fp_push(p1 ? 1.0 : 0.0); + break; + case EEL_BC_FPTOBOOL: + p1 = fabs(fp_pop()) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL; + break; + + case EEL_BC_CFUNC_1PDD: + { + double (*f)(double) = (double (*)(double)) *(void **)iptr; + fp_top = f(fp_top); + iptr += sizeof(void *); + } + break; + case EEL_BC_CFUNC_2PDD: + { + double (*f)(double,double) = (double (*)(double,double)) *(void **)iptr; + fp_top2 = f(fp_top2,fp_top); + fp_rewind(1); + iptr += sizeof(void *); + } + break; + case EEL_BC_CFUNC_2PDDS: + { + double (*f)(double,double) = (double (*)(double,double)) *(void **)iptr; + *p2 = f(*p2,fp_pop()); + p1 = p2; + iptr += sizeof(void *); + } + break; + + case EEL_BC_MEGABUF: + { + unsigned int idx=(unsigned int) (fp_pop() + NSEEL_CLOSEFACTOR); + EEL_F **f = (EEL_F **)rt,*f2; + p1 = (idx < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK && (f2=f[idx/NSEEL_RAM_ITEMSPERBLOCK])) ? + (f2 + (idx&(NSEEL_RAM_ITEMSPERBLOCK-1))) : + __NSEEL_RAMAlloc((void*)rt,idx); + } + break; + case EEL_BC_GMEGABUF: + { + p1 = __NSEEL_RAMAllocGMEM(*(EEL_F ****)iptr,(int) (fp_pop() + NSEEL_CLOSEFACTOR)); + iptr += sizeof(void *)*2; // also includes ptr to __NSEEL_RAMAllocGMEM, which we ignore + } + break; + case EEL_BC_GENERIC1PARM: + { + EEL_F *(*f)(void *,EEL_F*) = (EEL_F *(*)(void *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + p1 = f(*(void **)iptr,p1); + iptr += sizeof(void *)*2; + } + break; + case EEL_BC_GENERIC2PARM: + { + EEL_F *(*f)(void *,EEL_F*,EEL_F*) = (EEL_F *(*)(void *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + p1 = f(*(void **)iptr,p2, p1); + iptr += sizeof(void *)*2; + } + break; + case EEL_BC_GENERIC3PARM: + { + EEL_F *(*f)(void *,EEL_F*,EEL_F*,EEL_F*) = (EEL_F *(*)(void *, EEL_F *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + p1 = f(*(void **)iptr,p3, p2, p1); + iptr += sizeof(void *)*2; + } + break; + case EEL_BC_GENERIC1PARM_RETD: + { + EEL_F (*f)(void *,EEL_F*) = (EEL_F (*)(void *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + fp_push(f(*(void **)iptr,p1)); + iptr += sizeof(void *)*2; + } + break; + case EEL_BC_GENERIC2PARM_RETD: + { + EEL_F (*f)(void *,EEL_F*,EEL_F*) = (EEL_F (*)(void *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + fp_push(f(*(void **)iptr,p2, p1)); + iptr += sizeof(void *)*2; + } + break; + case EEL_BC_GENERIC3PARM_RETD: + { + EEL_F (*f)(void *,EEL_F*,EEL_F*,EEL_F*) = (EEL_F (*)(void *, EEL_F *, EEL_F *, EEL_F *)) *(void **)(iptr+sizeof(void *)); + fp_push(f(*(void **)iptr,p3, p2, p1)); + iptr += sizeof(void *)*2; + } + break; + + case EEL_BC_USERSTACK_PUSH: + { + UINT_PTR *sptr = *(UINT_PTR **)iptr; + (*sptr) += 8; + (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); + (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); + *(EEL_F *)*sptr = *p1; + } + iptr += sizeof(void*)*3; + break; + case EEL_BC_USERSTACK_POP: + { + UINT_PTR *sptr = *(UINT_PTR **)iptr; + *p1 = *(EEL_F *)*sptr; + (*sptr) -= 8; + (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); + (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); + } + iptr += sizeof(void*)*3; + break; + case EEL_BC_USERSTACK_POPFAST: + { + UINT_PTR *sptr = *(UINT_PTR **)iptr; + p1 = (EEL_F *)*sptr; + (*sptr) -= 8; + (*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *)); + (*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *)); + } + iptr += sizeof(void*)*3; + break; + case EEL_BC_USERSTACK_PEEK: + { + UINT_PTR sptr = **(UINT_PTR **)iptr; + sptr -= sizeof(EEL_F) * (int)(fp_pop()); + sptr &= *(UINT_PTR*)(iptr+sizeof(void *)); + sptr |= *(UINT_PTR*)(iptr+2*sizeof(void *)); + p1 = (EEL_F *)sptr; + } + iptr += sizeof(void*)*3; + break; + case EEL_BC_USERSTACK_PEEK_INT: + { + UINT_PTR sptr = **(UINT_PTR **)iptr; + sptr -= *(UINT_PTR*)(iptr+sizeof(void*)); + sptr &= *(UINT_PTR*)(iptr+2*sizeof(void *)); + sptr |= *(UINT_PTR*)(iptr+3*sizeof(void *)); + p1 = (EEL_F *)sptr; + } + iptr += sizeof(void*)*4; + break; + case EEL_BC_USERSTACK_PEEK_TOP: + p1 = (EEL_F *)**(UINT_PTR **)iptr; + iptr += sizeof(void*); + break; + case EEL_BC_USERSTACK_EXCH: + { + EEL_F *p=(EEL_F *)**(UINT_PTR **)iptr; + EEL_F a=*p; + *p=*p1; + *p1=a; + } + iptr += sizeof(void*); + break; + } + } +#undef fp_top +#undef fp_top2 +#undef fp_pop +#undef fp_push +}; + +#endif diff --git a/WDL/eel2/glue_ppc.h b/WDL/eel2/glue_ppc.h new file mode 100644 index 00000000..22607259 --- /dev/null +++ b/WDL/eel2/glue_ppc.h @@ -0,0 +1,257 @@ +#ifndef _NSEEL_GLUE_PPC_H_ +#define _NSEEL_GLUE_PPC_H_ + +#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support +#define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible) + + +// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction. +// on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so +// we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions) +#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC) + +static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b + +static const unsigned int GLUE_JMP_IF_P1_Z[]= +{ + 0x2f830000, //cmpwi cr7, r3, 0 + 0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction +}; +static const unsigned int GLUE_JMP_IF_P1_NZ[]= +{ + 0x2f830000, //cmpwi cr7, r3, 0 + 0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction +}; + + +#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8 +static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) +{ + static const unsigned short tab[3][2] = { + {0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw + {0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw + {0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw + }; + unsigned int uv=(unsigned int)v; + unsigned short *p=(unsigned short *)b; + + *p++ = tab[wv][0]; // addis rX, r0, hw + *p++ = (uv>>16)&0xffff; + *p++ = tab[wv][1]; // ori rX, rX, lw + *p++ = uv&0xffff; +} + + +// mflr r5 +// stwu r5, -16(r1) +const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 }; +#define GLUE_FUNC_ENTER_SIZE 8 + +// lwz r5, 0(r1) +// addi r1, r1, 16 +// mtlr r5 +const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 }; +#define GLUE_FUNC_LEAVE_SIZE 12 + +const static unsigned int GLUE_RET[]={0x4E800020}; // blr + +static int GLUE_RESET_WTP(unsigned char *out, void *ptr) +{ + const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src) + if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17)); + return sizeof(GLUE_SET_WTP_FROM_R17); + +} + + + +// stwu r3, -16(r1) +const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0}; + + +#define GLUE_POP_PX_SIZE 8 +static void GLUE_POP_PX(void *b, int wv) +{ + static const unsigned int tab[3] ={ + 0x80610000, // lwz r3, 0(r1) + 0x81c10000, // lwz r14, 0(r1) + 0x81e10000, // lwz r15, 0(r1) + }; + ((unsigned int *)b)[0] = tab[wv]; + ((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16 +} + +#define GLUE_SET_PX_FROM_P1_SIZE 4 +static void GLUE_SET_PX_FROM_P1(void *b, int wv) +{ + static const unsigned int tab[3]={ + 0x7c631b78, // never used: mr r3, r3 + 0x7c6e1b78, // mr r14, r3 + 0x7c6f1b78, // mr r15, r3 + }; + *(unsigned int *)b = tab[wv]; +} + + + +// lfd f2, 0(r3) +// stfdu f2, -16(r1) +static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 }; + +static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) +{ + // lfd f2, 0(r1) + // addi r1,r1,16 + // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) + // stfd f2, 0(r3) + if (buf) + { + unsigned int *bufptr = (unsigned int *)buf; + *bufptr++ = 0xC8410000; + *bufptr++ = 0x38210010; + GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); + bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; + *bufptr++ = 0xd8430000; + } + return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; +} + +static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) +{ + // lfd f2, 0(r3) + // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3) + // stfd f2, 0(r3) + + if (buf) + { + unsigned int *bufptr = (unsigned int *)buf; + *bufptr++ = 0xc8430000; + GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); + bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; + *bufptr++ = 0xd8430000; + } + + return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4; +} + + +static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt) +{ + static const double consttab[] = { + NSEEL_CLOSEFACTOR, + 4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/, + }; + // we could have r18 refer to the current user-stack pointer, someday, perhaps + __asm__( + "subi r1, r1, 128\n" + "stfd f31, 8(r1)\n" + "stfd f30, 16(r1)\n" + "stmw r13, 32(r1)\n" + "mtctr %0\n" + "mr r17, %1\n" + "mr r13, %2\n" + "lfd f31, 0(%3)\n" + "lfd f30, 8(%3)\n" + "subi r17, r17, 8\n" + "mflr r0\n" + "stw r0, 24(r1)\n" + "bctrl\n" + "lwz r0, 24(r1)\n" + "mtlr r0\n" + "lmw r13, 32(r1)\n" + "lfd f31, 8(r1)\n" + "lfd f30, 16(r1)\n" + "addi r1, r1, 128\n" + ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab)); +}; + +static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) +{ + // 64 bit ppc would take some work + unsigned int *p=(unsigned int *)_p; + while ((p[0]&0x0000FFFF) != 0x0000dead && + (p[1]&0x0000FFFF) != 0x0000beef) p++; + p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF); + p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF); + + return (unsigned char *)(p+1); +} + + #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int) + static void GLUE_SET_PX_FROM_WTP(void *b, int wv) + { + static const unsigned int tab[3]={ + 0x7e038378, // mr r3, r16 + 0x7e0e8378, // mr r14, r16 + 0x7e0f8378, // mr r15, r16 + }; + *(unsigned int *)b = tab[wv]; + } + static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) + { + // set r3 to destptr + // stfd f1, 0(r3) + if (buf) + { + unsigned int *bufptr = (unsigned int *)buf; + GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0); + bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4; + + *bufptr++ = 0xD8230000; // stfd f1, 0(r3) + } + return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int); + } + #define GLUE_POP_FPSTACK_SIZE 0 + static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack + + static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = { + 0xdc21fff0, // stfdu f1, -16(r1) + }; + + static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = { + 0xdc300008, // stfdu f1, 8(r16) + }; + + #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4 + static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) + { + static const unsigned int tab[3] = { + 0xC8230000, // lfd f1, 0(r3) + 0xC82E0000, // lfd f1, 0(r14) + 0xC82F0000, // lfd f1, 0(r15) + }; + *(unsigned int *)b = tab[wv]; + } + +#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE) +static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) +{ + memcpy(buf,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); + GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after +}; + +static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo + + +static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0 +static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1 + + +static void *GLUE_realAddress(void *fn, void *fn_e, int *size) +{ + // magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2 + static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 }; + unsigned char *p = (unsigned char *)fn; + + while (memcmp(p,sig,sizeof(sig))) p+=4; + p+=sizeof(sig); + fn = p; + + while (memcmp(p,sig,sizeof(sig))) p+=4; + *size = p - (unsigned char *)fn; + return fn; +} + +// end of ppc + +#endif diff --git a/WDL/eel2/glue_x86.h b/WDL/eel2/glue_x86.h new file mode 100644 index 00000000..c7c62a38 --- /dev/null +++ b/WDL/eel2/glue_x86.h @@ -0,0 +1,355 @@ +#ifndef _NSEEL_GLUE_X86_H_ +#define _NSEEL_GLUE_X86_H_ + +#define GLUE_MAX_FPSTACK_SIZE 8 + +// endOfInstruction is end of jump with relative offset, offset is offset from end of instruction to jump to +#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset)) + +static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp +static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz +static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz + +#define GLUE_FUNC_ENTER_SIZE 0 +#define GLUE_FUNC_LEAVE_SIZE 0 +const static unsigned int GLUE_FUNC_ENTER[1]; +const static unsigned int GLUE_FUNC_LEAVE[1]; + + // x86 + // stack is 16 byte aligned + // when pushing values to stack, alignment pushed first, then value (value is at the lower address) + // when pushing pointers to stack, alignment pushed first, then pointer (pointer is at the lower address) + + static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = + { + 0x83, 0xEC, 8, /* sub esp, 8 */ + 0xff, 0x70, 0x4, /* push dword [eax+4] */ + 0xff, 0x30, /* push dword [eax] */ + }; + + static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) + { + if (buf) + { + *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue + + *buf++ = 0x8f; *buf++ = 0x00; // pop dword [eax] + *buf++ = 0x8f; *buf++ = 0x40; *buf++ = 4; // pop dword [eax+4] + + *buf++ = 0x59; // pop ecx (alignment) + *buf++ = 0x59; // pop ecx (alignment) + } + + return 12; + } + + static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) + { + if (buf) + { + *buf++ = 0x8B; *buf++ = 0x38; // mov edi, [eax] + *buf++ = 0x8B; *buf++ = 0x48; *buf++ = 0x04; // mov ecx, [eax+4] + + + *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue + *buf++ = 0x89; *buf++ = 0x38; // mov [eax], edi + *buf++ = 0x89; *buf++ = 0x48; *buf++ = 0x04; // mov [eax+4], ecx + } + + return 2 + 3 + 5 + 2 + 3; + } + + static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) + { + if (buf) + { + *buf++ = 0xB8; *(void **) buf = destptr; buf+=4; // mov eax, directvalue + *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [eax] + } + return 1+4+2; + } + + + #define GLUE_MOV_PX_DIRECTVALUE_SIZE 5 + #define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE 6 // length when wv == -1 + + static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv) + { + if (wv==-1) + { + const static unsigned char t[2] = {0xDD, 0x05}; + memcpy(b,t,2); + b= ((unsigned char *)b)+2; + } + else + { + const static unsigned char tab[3] = { + 0xB8 /* mov eax, dv*/, + 0xBF /* mov edi, dv */ , + 0xB9 /* mov ecx, dv */ + }; + *((unsigned char *)b) = tab[wv]; // mov eax, dv + b= ((unsigned char *)b)+1; + } + *(INT_PTR *)b = v; + } + const static unsigned char GLUE_PUSH_P1[4]={0x83, 0xEC, 12, 0x50}; // sub esp, 12, push eax + + #define GLUE_POP_PX_SIZE 4 + static void GLUE_POP_PX(void *b, int wv) + { + static const unsigned char tab[3][GLUE_POP_PX_SIZE]= + { + {0x58,/*pop eax*/ 0x83, 0xC4, 12 /* add esp, 12*/}, + {0x5F,/*pop edi*/ 0x83, 0xC4, 12}, + {0x59,/*pop ecx*/ 0x83, 0xC4, 12}, + }; + memcpy(b,tab[wv],GLUE_POP_PX_SIZE); + } + + #define GLUE_SET_PX_FROM_P1_SIZE 2 + static void GLUE_SET_PX_FROM_P1(void *b, int wv) + { + static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ + {0x90,0x90}, // should never be used! (nopnop) + {0x89,0xC7}, // mov edi, eax + {0x89,0xC1}, // mov ecx, eax + }; + memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); + } + + #define GLUE_POP_FPSTACK_SIZE 2 + static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 + + static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { + 0x83, 0xEC, 16, // sub esp, 16 + 0xDD, 0x1C, 0x24 // fstp qword (%esp) + }; + + static const unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { + 0xDD, 0x04, 0x24, // fld qword (%esp) + 0x83, 0xC4, 16 // add esp, 16 + }; + + static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { + 0xDD, 0x1E, /* fstp qword [esi] */ + 0x83, 0xC6, 8, /* add esi, 8 */ + }; + + #define GLUE_SET_PX_FROM_WTP_SIZE 2 + static void GLUE_SET_PX_FROM_WTP(void *b, int wv) + { + static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ + {0x89,0xF0}, // mov eax, esi + {0x89,0xF7}, // mov edi, esi + {0x89,0xF1}, // mov ecx, esi + }; + memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); + } + + #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 + static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) + { + static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ + {0xDD,0x00}, // fld qword [eax] + {0xDD,0x07}, // fld qword [edi] + {0xDD,0x01}, // fld qword [ecx] + }; + memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); + } + +#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) +static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) +{ + GLUE_SET_PX_FROM_WTP(buf,wv); + memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); +}; + + +const static unsigned char GLUE_RET=0xC3; + +static int GLUE_RESET_WTP(unsigned char *out, void *ptr) +{ + if (out) + { + *out++ = 0xBE; // mov esi, constant + memcpy(out,&ptr,sizeof(void *)); + out+=sizeof(void *); + } + return 1+sizeof(void *); +} + + +static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR ramptr) +{ + #ifndef NSEEL_EEL1_COMPAT_MODE + short oldsw, newsw; + #endif + #ifdef _MSC_VER + + __asm + { +#ifndef NSEEL_EEL1_COMPAT_MODE + fnstcw [oldsw] + mov ax, [oldsw] + or ax, 0xC00 + mov [newsw], ax + fldcw [newsw] +#endif + + mov eax, cp + mov ebx, ramptr + + pushad + mov ebp, esp + and esp, -16 + + // on win32, which _MSC_VER implies, we keep things aligned to 16 bytes, and if we call a win32 function, + // the stack is 16 byte aligned before the call, meaning that if calling a function with no frame pointer, + // the stack would be aligned to a 16 byte boundary +4, which isn't good for performance. Having said that, + // normally we compile with frame pointers (which brings that to 16 byte + 8, which is fine), or ICC, which + // for nontrivial functions will align the stack itself (for very short functions, it appears to weigh the + // cost of aligning the stack vs that of the slower misaligned double accesses). + + // it may be worthwhile (at some point) to put some logic in the code that calls out to functions + // (generic1parm etc) to detect which alignment would be most optimal. + sub esp, 12 + call eax + mov esp, ebp + popad +#ifndef NSEEL_EEL1_COMPAT_MODE + fldcw [oldsw] +#endif + }; + + #else // gcc x86 + __asm__( +#ifndef NSEEL_EEL1_COMPAT_MODE + "fnstcw %2\n" + "movw %2, %%ax\n" + "orw $0xC00, %%ax\n" + "movw %%ax, %3\n" + "fldcw %3\n" +#endif + "pushl %%ebx\n" + "movl %%ecx, %%ebx\n" + "pushl %%ebp\n" + "movl %%esp, %%ebp\n" + "andl $-16, %%esp\n" // align stack to 16 bytes + "subl $12, %%esp\n" // call will push 4 bytes on stack, align for that + "call *%%edx\n" + "leave\n" + "popl %%ebx\n" +#ifndef NSEEL_EEL1_COMPAT_MODE + "fldcw %2\n" +#endif + :: + "d" (cp), "c" (ramptr) +#ifndef NSEEL_EEL1_COMPAT_MODE + , "g" (&oldsw), "g" (&newsw) +#endif + : "%eax","%esi","%edi"); + #endif //gcc x86 +} + +static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) +{ + char *p=(char*)_p; + INT_PTR scan = 0xFEFEFEFE; + while (*(INT_PTR *)p != scan) p++; + *(INT_PTR *)p = newv; + return (unsigned char *) (((INT_PTR*)p)+1); +} + +#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) + + +#define GLUE_INLINE_LOOPS + +static const unsigned char GLUE_LOOP_LOADCNT[]={ + 0xDB, 0x1E, //fistp dword [esi] + 0x8B, 0x0E, // mov ecx, [esi] + 0x81, 0xf9, 1,0,0,0, // cmp ecx, 1 + 0x0F, 0x8C, 0,0,0,0, // JL +}; +static const unsigned char GLUE_LOOP_CLAMPCNT[]={ + 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN + 0x0F, 0x8C, 5,0,0,0, // JL over-the-mov + 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN +}; +static const unsigned char GLUE_LOOP_BEGIN[]={ + 0x56, //push esi + 0x51, // push ecx + 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 +}; +static const unsigned char GLUE_LOOP_END[]={ + 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 + 0x59, //pop ecx + 0x5E, // pop esi + 0x49, // dec ecx + 0x0f, 0x85, 0,0,0,0, // jnz ... +}; + + +static const unsigned char GLUE_WHILE_SETUP[]={ + 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN +}; +static const unsigned char GLUE_WHILE_BEGIN[]={ + 0x56, //push esi + 0x51, // push ecx + 0x81, 0xEC, 0x08, 0,0,0, // sub esp, 8 +}; +static const unsigned char GLUE_WHILE_END[]={ + 0x81, 0xC4, 0x08, 0,0,0, // add esp, 8 + 0x59, //pop ecx + 0x5E, // pop esi + + + 0x49, // dec ecx + 0x0f, 0x84, 0,0,0,0, // jz endpt +}; +static const unsigned char GLUE_WHILE_CHECK_RV[] = { + 0x85, 0xC0, // test eax, eax + 0x0F, 0x85, 0,0,0,0 // jnz looppt +}; + +static const unsigned char GLUE_SET_P1_Z[] = { 0x29, 0xC0 }; // sub eax, eax +static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 + +#define GLUE_HAS_FXCH +static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; + +#define GLUE_HAS_FLDZ +static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; +#define GLUE_HAS_FLD1 +static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; + +static EEL_F negativezeropointfive=-0.5f; +static EEL_F onepointfive=1.5f; +#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, + + +#define GLUE_HAS_NATIVE_TRIGSQRTLOG + +static void *GLUE_realAddress(void *fn, void *fn_e, int *size) +{ + static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; + unsigned char *p = (unsigned char *)fn; + + #if defined(_DEBUG) && defined(_MSC_VER) + if (*p == 0xE9) // this means jump to the following address (debug stub) + { + p += 5 + *(int *)(p+1); + } + #endif + + while (memcmp(p,sig,sizeof(sig))) p++; + p+=sizeof(sig); + fn = p; + + while (memcmp(p,sig,sizeof(sig))) p++; + *size = p - (unsigned char *)fn; + return fn; +} + +#endif diff --git a/WDL/eel2/glue_x86_64.h b/WDL/eel2/glue_x86_64.h new file mode 100644 index 00000000..95598c62 --- /dev/null +++ b/WDL/eel2/glue_x86_64.h @@ -0,0 +1,261 @@ +#ifndef _NSEEL_GLUE_X86_64_H_ +#define _NSEEL_GLUE_X86_64_H_ + +#define GLUE_MAX_FPSTACK_SIZE 8 +#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (offset)) + +#define GLUE_PREFER_NONFP_DV_ASSIGNS + +static const unsigned char GLUE_JMP_NC[] = { 0xE9, 0,0,0,0, }; // jmp +static const unsigned char GLUE_JMP_IF_P1_Z[] = {0x85, 0xC0, 0x0F, 0x84, 0,0,0,0 }; // test eax, eax, jz +static const unsigned char GLUE_JMP_IF_P1_NZ[] = {0x85, 0xC0, 0x0F, 0x85, 0,0,0,0 }; // test eax, eax, jnz + + +#define GLUE_FUNC_ENTER_SIZE 0 +#define GLUE_FUNC_LEAVE_SIZE 0 +const static unsigned int GLUE_FUNC_ENTER[1]; +const static unsigned int GLUE_FUNC_LEAVE[1]; + + // on x86-64: + // stack is always 16 byte aligned + // pushing values to the stack (for eel functions) has alignment pushed first, then value (value is at the lower address) + // pushing pointers to the stack has the pointer pushed first, then the alignment (pointer is at the higher address) + #define GLUE_MOV_PX_DIRECTVALUE_SIZE 10 + static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wr) { + const static unsigned short tab[3] = + { + 0xB848 /* mov rax, dv*/, + 0xBF48 /* mov rdi, dv */ , + 0xB948 /* mov rcx, dv */ + }; + unsigned short *bb = (unsigned short *)b; + *bb++ = tab[wr]; // mov rax, directvalue + *(INT_PTR *)bb = v; + } + + const static unsigned char GLUE_PUSH_P1[2]={ 0x50,0x50}; // push rax (pointer); push rax (alignment) + + #define GLUE_POP_PX_SIZE 2 + static void GLUE_POP_PX(void *b, int wv) + { + static const unsigned char tab[3][GLUE_POP_PX_SIZE]= + { + {0x58,/*pop eax*/ 0x58}, // pop alignment, then pop pointer + {0x5F,/*pop edi*/ 0x5F}, + {0x59,/*pop ecx*/ 0x59}, + }; + memcpy(b,tab[wv],GLUE_POP_PX_SIZE); + } + + static const unsigned char GLUE_PUSH_P1PTR_AS_VALUE[] = + { + 0x50, /*push rax - for alignment */ + 0xff, 0x30, /* push qword [rax] */ + }; + + static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr) // trashes P2 (rdi) and P3 (rcx) + { + if (buf) + { + *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue + *buf++ = 0x8f; *buf++ = 0x01; // pop qword [rcx] + *buf++ = 0x5F ; // pop rdi (alignment, safe to trash rdi though) + } + return 1+10+2; + } + + static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr) // trashes P2/P3 + { + if (buf) + { + *buf++ = 0x48; *buf++ = 0xB9; *(void **) buf = destptr; buf+=8; // mov rcx, directvalue + *buf++ = 0x48; *buf++ = 0x8B; *buf++ = 0x38; // mov rdi, [rax] + *buf++ = 0x48; *buf++ = 0x89; *buf++ = 0x39; // mov [rcx], rdi + } + + return 3 + 10 + 3; + } + + static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr) + { + if (buf) + { + *buf++ = 0x48; + *buf++ = 0xB8; + *(void **) buf = destptr; buf+=8; // mov rax, directvalue + *buf++ = 0xDD; *buf++ = 0x18; // fstp qword [rax] + } + return 2+8+2; + } + + + #define GLUE_SET_PX_FROM_P1_SIZE 3 + static void GLUE_SET_PX_FROM_P1(void *b, int wv) + { + static const unsigned char tab[3][GLUE_SET_PX_FROM_P1_SIZE]={ + {0x90,0x90,0x90}, // should never be used! (nopnop) + {0x48,0x89,0xC7}, // mov rdi, rax + {0x48,0x89,0xC1}, // mov rcx, rax + }; + memcpy(b,tab[wv],GLUE_SET_PX_FROM_P1_SIZE); + } + + + #define GLUE_POP_FPSTACK_SIZE 2 + static const unsigned char GLUE_POP_FPSTACK[2] = { 0xDD, 0xD8 }; // fstp st0 + + static const unsigned char GLUE_POP_FPSTACK_TOSTACK[] = { + 0x48, 0x81, 0xEC, 16, 0,0,0, // sub rsp, 16 + 0xDD, 0x1C, 0x24 // fstp qword (%rsp) + }; + + static const unsigned char GLUE_POP_FPSTACK_TO_WTP[] = { + 0xDD, 0x1E, /* fstp qword [rsi] */ + 0x48, 0x81, 0xC6, 8, 0,0,0,/* add rsi, 8 */ + }; + + #define GLUE_SET_PX_FROM_WTP_SIZE 3 + static void GLUE_SET_PX_FROM_WTP(void *b, int wv) + { + static const unsigned char tab[3][GLUE_SET_PX_FROM_WTP_SIZE]={ + {0x48, 0x89,0xF0}, // mov rax, rsi + {0x48, 0x89,0xF7}, // mov rdi, rsi + {0x48, 0x89,0xF1}, // mov rcx, rsi + }; + memcpy(b,tab[wv],GLUE_SET_PX_FROM_WTP_SIZE); + } + + #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 2 + static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv) + { + static const unsigned char tab[3][GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE]={ + {0xDD,0x00}, // fld qword [rax] + {0xDD,0x07}, // fld qword [rdi] + {0xDD,0x01}, // fld qword [rcx] + }; + memcpy(b,tab[wv],GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE); + } + static unsigned char GLUE_POP_STACK_TO_FPSTACK[] = { + 0xDD, 0x04, 0x24, // fld qword (%rsp) + 0x48, 0x81, 0xC4, 16, 0,0,0, // add rsp, 16 + }; + + +#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (GLUE_SET_PX_FROM_WTP_SIZE + sizeof(GLUE_POP_FPSTACK_TO_WTP)) +static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv) +{ + GLUE_SET_PX_FROM_WTP(buf,wv); + memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP)); +}; + + +const static unsigned char GLUE_RET=0xC3; + +static int GLUE_RESET_WTP(unsigned char *out, void *ptr) +{ + if (out) + { + *out++ = 0x48; + *out++ = 0xBE; // mov rsi, constant64 + *(void **)out = ptr; + out+=sizeof(void *); + } + return 2+sizeof(void *); +} + +extern void win64_callcode(INT_PTR code, INT_PTR ram_tab); +#define GLUE_CALL_CODE(bp, cp, rt) win64_callcode(cp, rt) + +static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv) +{ + char *p=(char*)_p; + INT_PTR scan = 0xFEFEFEFEFEFEFEFE; + while (*(INT_PTR *)p != scan) p++; + *(INT_PTR *)p = newv; + return (unsigned char *) (((INT_PTR*)p)+1); +} + +#define INT_TO_LECHARS(x) ((x)&0xff),(((x)>>8)&0xff), (((x)>>16)&0xff), (((x)>>24)&0xff) + +#define GLUE_INLINE_LOOPS + +static const unsigned char GLUE_LOOP_LOADCNT[]={ + 0xDD, 0x0E, //fistTp qword [rsi] + 0x48, 0x8B, 0x0E, // mov rcx, [rsi] + 0x48, 0x81, 0xf9, 1,0,0,0, // cmp rcx, 1 + 0x0F, 0x8C, 0,0,0,0, // JL +}; +static const unsigned char GLUE_LOOP_CLAMPCNT[]={ + 0x48, 0x81, 0xf9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), // cmp rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN + 0x0F, 0x8C, 10,0,0,0, // JL over-the-mov + 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN +}; +static const unsigned char GLUE_LOOP_BEGIN[]={ + 0x56, //push rsi + 0x51, // push rcx +}; +static const unsigned char GLUE_LOOP_END[]={ + 0x59, //pop rcx + 0x5E, // pop rsi + 0xff, 0xc9, // dec rcx + 0x0f, 0x85, 0,0,0,0, // jnz ... +}; + + + +static const unsigned char GLUE_WHILE_SETUP[]={ + 0x48, 0xB9, INT_TO_LECHARS(NSEEL_LOOPFUNC_SUPPORT_MAXLEN), 0,0,0,0, // mov rcx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN +}; +static const unsigned char GLUE_WHILE_BEGIN[]={ + 0x56, //push rsi + 0x51, // push rcx +}; +static const unsigned char GLUE_WHILE_END[]={ + 0x59, //pop rcx + 0x5E, // pop rsi + + 0xff, 0xc9, // dec rcx + 0x0f, 0x84, 0,0,0,0, // jz endpt +}; +static const unsigned char GLUE_WHILE_CHECK_RV[] = { + 0x85, 0xC0, // test eax, eax + 0x0F, 0x85, 0,0,0,0 // jnz looppt +}; + +static const unsigned char GLUE_SET_P1_Z[] = { 0x48, 0x29, 0xC0 }; // sub rax, rax +static const unsigned char GLUE_SET_P1_NZ[] = { 0xb0, 0x01 }; // mov al, 1 + + +#define GLUE_HAS_FXCH +static const unsigned char GLUE_FXCH[] = {0xd9, 0xc9}; + +#define GLUE_HAS_FLDZ +static const unsigned char GLUE_FLDZ[] = {0xd9, 0xee}; +#define GLUE_HAS_FLD1 +static const unsigned char GLUE_FLD1[] = {0xd9, 0xe8}; + + +static EEL_F negativezeropointfive=-0.5f; +static EEL_F onepointfive=1.5f; +#define GLUE_INVSQRT_NEEDREPL &negativezeropointfive, &onepointfive, + +#define GLUE_HAS_NATIVE_TRIGSQRTLOG + + +static void *GLUE_realAddress(void *fn, void *fn_e, int *size) +{ + static const unsigned char sig[12] = { 0x89, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; + unsigned char *p = (unsigned char *)fn; + + while (memcmp(p,sig,sizeof(sig))) p++; + p+=sizeof(sig); + fn = p; + + while (memcmp(p,sig,sizeof(sig))) p++; + *size = p - (unsigned char *)fn; + return fn; +} + +// end of x86-64 + +#endif diff --git a/WDL/eel2/ns-eel-addfuncs.h b/WDL/eel2/ns-eel-addfuncs.h new file mode 100644 index 00000000..e1e0d6f7 --- /dev/null +++ b/WDL/eel2/ns-eel-addfuncs.h @@ -0,0 +1,87 @@ +/* + Nullsoft Expression Evaluator Library (NS-EEL) + Copyright (C) 1999-2003 Nullsoft, Inc. + + ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __NS_EEL_ADDFUNCS_H__ +#define __NS_EEL_ADDFUNCS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct _compileContext; + +void *NSEEL_PProc_RAM(void *data, int data_size, struct _compileContext *ctx); +void *NSEEL_PProc_THIS(void *data, int data_size, struct _compileContext *ctx); + + +#ifdef EEL_TARGET_PORTABLE + +extern EEL_BC_TYPE _asm_generic3parm[]; // 3 double * parms, returning double * +extern EEL_BC_TYPE _asm_generic3parm_end[]; +extern EEL_BC_TYPE _asm_generic3parm_retd[]; // 3 double * parms, returning double +extern EEL_BC_TYPE _asm_generic3parm_retd_end[]; +extern EEL_BC_TYPE _asm_generic2parm[]; // 2 double * parms, returning double * +extern EEL_BC_TYPE _asm_generic2parm_end[]; +extern EEL_BC_TYPE _asm_generic2parm_retd[]; // 2 double * parms, returning double +extern EEL_BC_TYPE _asm_generic2parm_retd_end[]; +extern EEL_BC_TYPE _asm_generic1parm[]; // 1 double * parms, returning double * +extern EEL_BC_TYPE _asm_generic1parm_end[]; +extern EEL_BC_TYPE _asm_generic1parm_retd[]; // 1 double * parms, returning double +extern EEL_BC_TYPE _asm_generic1parm_retd_end[]; + +#else + +void _asm_generic3parm(void); // 3 double * parms, returning double * +void _asm_generic3parm_end(void); +void _asm_generic3parm_retd(void); // 3 double * parms, returning double +void _asm_generic3parm_retd_end(void); +void _asm_generic2parm(void); // 2 double * parms, returning double * +void _asm_generic2parm_end(void); +void _asm_generic2parm_retd(void); // 2 double * parms, returning double +void _asm_generic2parm_retd_end(void); +void _asm_generic1parm(void); // 1 double * parms, returning double * +void _asm_generic1parm_end(void); +void _asm_generic1parm_retd(void); // 1 double * parms, returning double +void _asm_generic1parm_retd_end(void); + +#endif + +#if EEL_F_SIZE == 4 +#define EEL_F_SSTR "4" +#define EEL_F_SUFFIX "s" +#else +#define EEL_F_SSTR "8" +#define EEL_F_SUFFIX "l" +#endif + +#ifdef _MSC_VER +#define NSEEL_CGEN_CALL __cdecl +#else +#define NSEEL_CGEN_CALL +#endif + +#ifdef __cplusplus +}; + +#endif +#endif//__NS_EEL_ADDFUNCS_H__ diff --git a/WDL/eel2/ns-eel-int.h b/WDL/eel2/ns-eel-int.h new file mode 100644 index 00000000..e9e04702 --- /dev/null +++ b/WDL/eel2/ns-eel-int.h @@ -0,0 +1,318 @@ +/* + Nullsoft Expression Evaluator Library (NS-EEL) + Copyright (C) 1999-2003 Nullsoft, Inc. + + ns-eel-int.h: internal code definition header. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __NS_EELINT_H__ +#define __NS_EELINT_H__ + +#ifdef _WIN32 +#include +#else +#include "../wdltypes.h" +#endif + +#include "ns-eel.h" +#include "ns-eel-addfuncs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +enum { + + // these ignore fn in opcodes, just use fntype to determine function + FN_MULTIPLY=0, + FN_DIVIDE, + FN_JOIN_STATEMENTS, + FN_ADD, + FN_SUB, + FN_AND, + FN_OR, + FN_UMINUS, + FN_UPLUS, + FUNCTYPE_SIMPLEMAX, + + + FUNCTYPE_FUNCTIONTYPEREC, // fn is a functionType * + FUNCTYPE_EELFUNC, // fn is a _codeHandleFunctionRec * + + + // _codeHandleFunctionRec*, relname in opcode field is the namespace specifier + // (i.e. if called via this.something.function(), "something".) + // note that calls to function() or some.function() are both normal FUNCTYPE_EELFUNC calls, as they can be resolved + // earlier in the process + FUNCTYPE_EELFUNC_THIS, // fn is a _codeHandleFunctionRec * to base function, relname set +}; + + + +#define YYSTYPE opcodeRec * + +#define NSEEL_CLOSEFACTOR 0.00001 + +typedef struct +{ + int srcByteCount; + int destByteCount; +} lineRecItem; + + +typedef struct opcodeRec opcodeRec; + +typedef struct _codeHandleFunctionRec +{ + struct _codeHandleFunctionRec *next; // main linked list (only used for high level functions) + struct _codeHandleFunctionRec *derivedCopies; // separate linked list, head being the main function, other copies being derived versions + + void *startptr; // compiled code (may be cleared + recompiled when shraed) + opcodeRec *opcodes; + + int startptr_size; + int tmpspace_req; + + int num_params; + + int rvMode; // RETURNVALUE_* + int fpStackUsage; // 0-8, usually + int canHaveDenormalOutput; + + // local storage's first items are the parameters, then locals. Note that the opcodes will reference localstorage[] via VARPTRPTR, but + // the values localstorage[x] points are reallocated from context-to-context, if it is a common function. + + // separately allocated list of pointers, the contents of the list should be zeroed on context changes if a common function + // note that when making variations on a function (context), it is shared, but since it is zeroed on context changes, it is context-local + int localstorage_size; + EEL_F **localstorage; + + int isCommonFunction; + int usesThisPointer; + + char fname[NSEEL_MAX_VARIABLE_NAMELEN+1]; +} _codeHandleFunctionRec; + +#define LLB_DSIZE (65536-64) +typedef struct _llBlock { + struct _llBlock *next; + int sizeused; + char block[LLB_DSIZE]; +} llBlock; + +typedef struct { + llBlock *blocks, + *blocks_data; + void *workTable; // references a chunk in blocks_data + + void *code; + int code_size; // in case the caller wants to write it out + int code_stats[4]; + + int want_stack; + void *stack; // references a chunk in blocks_data, somewhere within the complete NSEEL_STACK_SIZE aligned at NSEEL_STACK_SIZE + + void *ramPtr; + + int workTable_size; // size (minus padding/extra space) of workTable -- only used if EEL_VALIDATE_WORKTABLE_USE set, but might be handy to have around too +} codeHandleType; + + + +typedef struct _compileContext +{ + EEL_F **varTable_Values; + char ***varTable_Names; + int varTable_numBlocks; + + int errVar; + opcodeRec *result; + char last_error_string[256]; + +#ifdef NSEEL_USE_OLD_PARSER + int colCount; + YYSTYPE yylval; + int yychar; /* the lookahead symbol */ + int yynerrs; /* number of parse errors so far */ + + char *llsave[16]; /* Look ahead buffer */ + char llbuf[NSEEL_MAX_VARIABLE_NAMELEN*2+128]; /* work buffer */ + char *llp1;// = &llbuf[0]; /* pointer to next avail. in token */ + char *llp2;// = &llbuf[0]; /* pointer to end of lookahead */ + char *llend;// = &llbuf[0]; /* pointer to end of token */ + char *llebuf;// = &llbuf[sizeof llbuf]; + int lleof; +#else + void *scanner; + #ifdef NSEEL_SUPER_MINIMAL_LEXER + char *rdbuf, *rdbuf_start; + #else + const char *inputbufferptr; + int errVar_l; + #endif +#endif + + llBlock *tmpblocks_head, // used while compiling, and freed after compiling + + *blocks_head, // used while compiling, transferred to code context (these are pages marked as executable) + *blocks_head_data, // used while compiling, transferred to code context + + *pblocks; // persistent blocks, stores data used by varTable_Names, varTable_Values, etc. + + int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes + + lineRecItem *compileLineRecs; + int compileLineRecs_size; + int compileLineRecs_alloc; + + _codeHandleFunctionRec *functions_local, *functions_common; + + // state used while generating functions + int optimizeDisableFlags; + struct opcodeRec *directValueCache; // linked list using fn as next + + int isSharedFunctions; + int function_usesThisPointer; + // [0] is parameter+local symbols (combined space) + // [1] is symbols which get implied "this." if used + int function_localTable_Size[2]; // for parameters only + char **function_localTable_Names[2]; // lists of pointers + EEL_F **function_localTable_ValuePtrs; + const char *function_curName; // name of current function + + codeHandleType *tmpCodeHandle; + + struct + { + int needfree; + int __pad; + double closefact; + EEL_F *blocks[NSEEL_RAM_BLOCKS]; + } ram_state +#ifdef __GNUC__ + __attribute__ ((aligned (8))) +#endif + ; + + void *gram_blocks; + + void *caller_this; +} +compileContext; + +#define NSEEL_VARS_PER_BLOCK 64 + +#define NSEEL_NPARAMS_FLAG_CONST 0x80000 +typedef struct { + const char *name; + void *afunc; + void *func_e; + int nParams; + void *replptrs[4]; + NSEEL_PPPROC pProc; +} functionType; + + +typedef struct +{ + int refcnt; + char isreg; +} varNameHdr; + +extern functionType *nseel_getFunctionFromTable(int idx); + +opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value); +opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue); +opcodeRec *nseel_createCompiledValuePtrPtr(compileContext *ctx, EEL_F **addrValue); + +opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2); +opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2); +opcodeRec *nseel_createCompiledFunctionCall(compileContext *ctx, int np, int ftype, void *fn); +opcodeRec *nseel_createCompiledFunctionCallEELThis(compileContext *ctx, _codeHandleFunctionRec *fn, const char *thistext); +opcodeRec *nseel_setCompiledFunctionCallParameters(opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3); + +opcodeRec *nseel_createCompiledValueFromNamespaceName(compileContext *ctx, const char *relName); +EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg); +_codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr); + +extern EEL_F nseel_globalregs[100]; + +#ifdef NSEEL_USE_OLD_PARSER + #define VALUE 258 + #define IDENTIFIER 259 + #define FUNCTION1 260 + #define FUNCTION2 261 + #define FUNCTION3 262 + #define UMINUS 263 + #define UPLUS 264 + + #define INTCONST 1 + #define DBLCONST 2 + #define HEXCONST 3 + #define VARIABLE 4 + #define OTHER 5 +#else + #include "y.tab.h" +#endif + +opcodeRec *nseel_translate(compileContext *ctx, const char *tmp); +int nseel_gettokenlen(compileContext *ctx, int maxlen); +opcodeRec *nseel_lookup(compileContext *ctx, int *typeOfObject, const char *sname); +int nseel_yyerror(compileContext *ctx); +int nseel_yylex(compileContext *ctx, char **exp); +int nseel_yyparse(compileContext *ctx, char *exp); +void nseel_llinit(compileContext *ctx); +int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz); + +struct lextab { + int llendst; /* Last state number */ + char *lldefault; /* Default state table */ + char *llnext; /* Next state table */ + char *llcheck; /* Check table */ + int *llbase; /* Base table */ + int llnxtmax; /* Last in next table */ + int (*llmove)(); /* Move between states */ + char *llfinal; /* Final state descriptions */ + int (*llactr)(); /* Action routine */ + int *lllook; /* Look ahead vector if != NULL */ + char *llign; /* Ignore char vec if != NULL */ + char *llbrk; /* Break char vec if != NULL */ + char *llill; /* Illegal char vec if != NULL */ +}; +extern struct lextab nseel_lextab; + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **blocks, unsigned int w); +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w); +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr); +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which); +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr); + + + +#ifndef max +#define max(x,y) ((x)<(y)?(y):(x)) +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif//__NS_EELINT_H__ diff --git a/WDL/eel2/ns-eel.h b/WDL/eel2/ns-eel.h new file mode 100644 index 00000000..27fde9a4 --- /dev/null +++ b/WDL/eel2/ns-eel.h @@ -0,0 +1,207 @@ +/* + Nullsoft Expression Evaluator Library (NS-EEL) + Copyright (C) 1999-2003 Nullsoft, Inc. + + ns-eel.h: main application interface header + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef __NS_EEL_H__ +#define __NS_EEL_H__ + +// put standard includes here +#include +#include + +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +#ifndef EEL_F_SIZE +#define EEL_F_SIZE 8 +#endif + +#include "../wdltypes.h" + +#if EEL_F_SIZE == 4 +typedef float EEL_F; +#else +typedef double EEL_F WDL_FIXALIGN; +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +// host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once) + + // implement if you will be running the code in same VM from multiple threads, + // or VMs that have the same GRAM pointer from different threads, or multiple + // VMs that have a NULL GRAM pointer from multiple threads. + // if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank. + + // or if you're daring.... + +void NSEEL_HOSTSTUB_EnterMutex(); +void NSEEL_HOSTSTUB_LeaveMutex(); + + +int NSEEL_init(); // returns 0 on success. clears any added functions as well + + + +// adds a function that returns a value (EEL_F) +#define NSEEL_addfunc_retval(name,np,pproc,fptr) \ + NSEEL_addfunctionex(name,np,(char *)_asm_generic##np##parm_retd,(char *)_asm_generic##np##parm_retd##_end-(char *)_asm_generic##np##parm_retd,(void*)(pproc),(void*)(fptr)) + +// adds a function that returns a pointer (EEL_F*) +#define NSEEL_addfunc_retptr(name,np,pproc,fptr) \ + NSEEL_addfunctionex(name,np,(char *)_asm_generic##np##parm,(char *)_asm_generic##np##parm##_end-(char *)_asm_generic##np##parm,(void*)(pproc),(void*)(fptr)) + +// adds a void or bool function +#define NSEEL_addfunc_retbool(name,np,pproc,fptr) \ + NSEEL_addfunctionex(name,(np)|(/*BIF_RETURNSBOOL*/0x00400),(char *)_asm_generic##np##parm_retd,(char *)_asm_generic##np##parm_retd##_end-(char *)_asm_generic##np##parm_retd,(void*)(pproc),(void*)(fptr)) + + +#define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0) +#define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0) + +typedef void *(*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data); + +void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2); + +void NSEEL_quit(); + +int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles +EEL_F *NSEEL_getglobalregs(); + +typedef void *NSEEL_VMCTX; +typedef void *NSEEL_CODEHANDLE; + +NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle +void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well + +void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx); +void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx); +void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx); +void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop + +EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation) +int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0 + +void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used +void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory +int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested? + +// if you set this, it uses a local GMEM context. +// Must be set before compilation. +// void *p=NULL; +// NSEEL_VM_SetGRAM(ctx,&p); +// .. do stuff +// NSEEL_VM_FreeGRAM(&p); +void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram); +void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context. +void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr); + + +NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, const char *code, int lineoffs); +#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS 1 // allows that code's functions to be used in other code (note you shouldn't destroy that codehandle without destroying others first if used) +#define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET 2 // resets common code functions + +NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags); + +char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx); +void NSEEL_code_execute(NSEEL_CODEHANDLE code); +void NSEEL_code_free(NSEEL_CODEHANDLE code); +int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes + + +// global memory control/view +extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes +extern unsigned int NSEEL_RAM_memused; +extern int NSEEL_RAM_memused_errors; + + + +// configuration: + + // the old parser may have more quirks. + // Changes in the new parser: + // 1) expressions such as a = (1+5;3); now work as expected (a is set to 3, rather than 4). + // 2) 0xHEXNUMBER is now allowed (old parser required $xHEXNUMBER + // 3) error notices (unsure which is more accurate) + // 4) new parser allows more than 3 parameter eel-functions (up to NSEEL_MAX_EELFUNC_PARAMETERS) + + //#define NSEEL_USE_OLD_PARSER +#define NSEEL_SUPER_MINIMAL_LEXER // smaller code that uses far less ram, but the flex version we'll keep around too in case we want to do fancier things someday + + // #define NSEEL_EEL1_COMPAT_MODE // supports old behaviors (continue after failed compile), old functions _bnot etc. + +#define NSEEL_MAX_VARIABLE_NAMELEN 128 // define this to override the max variable length +#define NSEEL_MAX_EELFUNC_PARAMETERS 40 + +// maximum loop length +#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576 // scary, we can do a million entries. probably will never want to, though. +#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR "1048576" + + +#define NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE 2048 + +// when a VM ctx doesn't have a GRAM context set, make the global one this big +#define NSEEL_SHARED_GRAM_SIZE (1<<20) + + + + +// note: if you wish to change NSEEL_RAM_*, and your target is x86-64, you will need to regenerate things. + +// on osx: +// php a2x64.php win64x +// php a2x64.php macho64 + +// or on win32: +// php a2x64.php +// php a2x64.php macho64x +// this will regenerate the .asm files and object files + +// 128*65536 = ~8million entries. (64MB RAM used) + + +#define NSEEL_RAM_BLOCKS_LOG2 7 +#define NSEEL_RAM_ITEMSPERBLOCK_LOG2 16 + +#define NSEEL_RAM_BLOCKS (1 << NSEEL_RAM_BLOCKS_LOG2) +#define NSEEL_RAM_ITEMSPERBLOCK (1<yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#define YYLEX nseel_yylex(ctx,&exp) + +/* If nonreentrant, generate the variables here */ + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#define YYINITDEPTH 5000 +#define YYMAXDEPTH 5000 + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0) + +//#ln 131 "bison.simple" +int nseel_yyparse(compileContext *ctx, char *exp) +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + + int yystacksize = YYINITDEPTH; + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + + ctx->yylval = 0; + yystate = 0; + yyerrstatus = 0; + ctx->yynerrs = 0; + ctx->yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. */ + + yyssp = yyss - 1; + yyvsp = yyvs; + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ +// YYSTYPE *yyvs1 = yyvs; + // short *yyss1 = yyss; + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + + if (yystacksize >= YYMAXDEPTH) + { + YYERROR("internal error: parser stack overflow"); + return 2; + } + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; + + + if (yyssp >= yyss + yystacksize - 1) YYABORT; + } + + +// yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (ctx->yychar == YYEMPTY) + { +// yyStackSize = yyssp - (yyss - 1); + ctx->yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (ctx->yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + ctx->yychar = YYEOF; /* Don't call YYLEX any more */ + + } + else + { + yychar1 = YYTRANSLATE(ctx->yychar); + + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + + + /* Discard the token being shifted unless it is eof. */ + if (ctx->yychar != YYEOF) + ctx->yychar = YYEMPTY; + + *++yyvsp = ctx->yylval; + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + + + switch (yyn) { + +case 1: +//#ln 32 "cal.y" +{ yyval = yyvsp[0]; ctx->result = yyvsp[0]; ; + break;} +case 2: +//#ln 34 "cal.y" +{ { + ctx->result = yyval = yyvsp[0]; // unused! + } + ; + break;} +case 3: +//#ln 50 "cal.y" +{ yyval = yyvsp[0] ; + break;} +case 4: +//#ln 55 "cal.y" +{ yyval = yyvsp[0];; + break;} +case 5: +//#ln 57 "cal.y" +{ yyval = yyvsp[0];; + break;} +case 6: +//#ln 59 "cal.y" +{ yyval = yyvsp[-1];; + break;} +case 7: +//#ln 64 "cal.y" +{ yyval = yyvsp[0]; ; + break;} +case 8: +//#ln 66 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_MULTIPLY, 2, yyvsp[-2], yyvsp[0]); + break;} +case 9: +//#ln 72 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_DIVIDE, 2, yyvsp[-2], yyvsp[0]); + break;} +case 10: +//#ln 78 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_JOIN_STATEMENTS, 2, yyvsp[-2], yyvsp[0]); + break;} +case 11: +//#ln 84 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_ADD, 2, yyvsp[-2], yyvsp[0]); + break;} +case 12: +//#ln 90 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_SUB, 2, yyvsp[-2], yyvsp[0]); + break;} +case 13: +//#ln 96 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_AND, 2, yyvsp[-2], yyvsp[0]); + break;} +case 14: +//#ln 102 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_OR, 2, yyvsp[-2], yyvsp[0]); + break;} +case 15: +//#ln 108 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_UMINUS, 1, yyvsp[0], 0); + break;} +case 16: +//#ln 114 "cal.y" +{ yyval = nseel_createSimpleCompiledFunction(ctx,FN_UPLUS, 1, yyvsp[0], 0); + break;} +case 17: +//#ln 120 "cal.y" +{ yyval = yyvsp[0]; + break;} +case 18: +//#ln 125 "cal.y" +{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-3], yyvsp[-1], 0, 0); + break;} +case 19: +//#ln 131 "cal.y" +{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-5], yyvsp[-3], yyvsp[-1], 0); + break;} +case 20: +//#ln 137 "cal.y" +{ yyval = nseel_setCompiledFunctionCallParameters(yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]); + break;} +} + /* the action file gets copied in in place of this dollarsign */ +//#ln 362 "bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; + + *++yyvsp = yyval; + + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++ctx->yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; +#error this should not compile + msg = (char *) xmalloc(size + 15); + strcpy(msg, "syntax error"); + + if (count < 5) + { + count = 0; + for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + YYERROR(msg); + free(msg); + } + else +#endif /* YYERROR_VERBOSE */ + YYERROR("syntax error"); + } + +//yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (ctx->yychar == YYEOF) YYABORT; + + ctx->yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; + + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = ctx->yylval; + + yystate = yyn; + goto yynewstate; +} + +#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-cfunc.c b/WDL/eel2/nseel-cfunc.c new file mode 100644 index 00000000..fff36061 --- /dev/null +++ b/WDL/eel2/nseel-cfunc.c @@ -0,0 +1,133 @@ +/* + Expression Evaluator Library (NS-EEL) v2 + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + nseel-cfunc.c: assembly/C implementation of operator/function templates + This file should be ideally compiled with optimizations towards "minimize size" + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "ns-eel-int.h" +#include +#include + + + +// these are used by our assembly code + + +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned int genrand_int32(void) +{ + + unsigned int y; + static unsigned int mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + static unsigned int mt[N]; /* the array for the state vector */ + static int mti; /* mti==N+1 means mt[N] is not initialized */ + + + if (!mti) + { + unsigned int s=0x4141f00d; + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } + } + + if (mti >= N) { /* generate N words at one time */ + int kk; + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + + + +//--------------------------------------------------------------------------------------------------------------- +EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f) +{ + EEL_F x=floor(f); + if (x < 1.0) x=1.0; + +#ifdef NSEEL_EEL1_COMPAT_MODE + return (EEL_F)(genrand_int32()%(int)x); +#else + return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x); +#endif +} + +//--------------------------------------------------------------------------------------------------------------- + + +#ifndef EEL_TARGET_PORTABLE + +#ifdef __ppc__ +#include "asm-nseel-ppc-gcc.c" +#else + #ifdef _MSC_VER + #ifdef _WIN64 + //nasm + #else + #include "asm-nseel-x86-msvc.c" + #endif + #elif !defined(__LP64__) + #define FUNCTION_MARKER "\n.byte 0x89,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90\n" + #include "asm-nseel-x86-gcc.c" + #endif +#endif + +#endif diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c new file mode 100644 index 00000000..95eceb91 --- /dev/null +++ b/WDL/eel2/nseel-compiler.c @@ -0,0 +1,4574 @@ +/* + Expression Evaluator Library (NS-EEL) v2 + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + nseel-compiler.c + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +// for VirtualProtect + +#include "ns-eel-int.h" + +#include "../denormal.h" +#include "../wdlcstring.h" + +#include +#include +#include +#include + +#ifdef __APPLE__ + #ifdef __LP64__ + #define EEL_USE_MPROTECT + #endif +#endif + +#ifdef EEL_USE_MPROTECT +#include +#include +#include +#endif + +#define NSEEL_VARS_MALLOC_CHUNKSIZE 8 + +//#define LOG_OPT +//#define EEL_PPC_NOFREECODE +//#define EEL_PRINT_FAILS +//#define EEL_VALIDATE_WORKTABLE_USE +//#define EEL_VALIDATE_FSTUBS + + +#ifdef EEL_PRINT_FAILS + #ifdef _WIN32 + #define RET_MINUS1_FAIL(x) { OutputDebugString(x); return -1; } + #else + #define RET_MINUS1_FAIL(x) { printf("%s\n",x); return -1; } + #endif +#else +#define RET_MINUS1_FAIL(x) return -1; +#endif + + + +#ifdef EEL_VALIDATE_WORKTABLE_USE + #define MIN_COMPUTABLE_SIZE 0 + #define COMPUTABLE_EXTRA_SPACE 64 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking +#else + #define MIN_COMPUTABLE_SIZE 32 // always use at least this big of a temp storage table (and reset the temp ptr when it goes past this boundary) + #define COMPUTABLE_EXTRA_SPACE 16 // safety buffer, if EEL_VALIDATE_WORKTABLE_USE set, used for magic-value-checking +#endif + + +/* + P1 is rightmost parameter + P2 is second rightmost, if any + P3 is third rightmost, if any + registers on x86 are (RAX etc on x86-64) + P1(ret) EAX + P2 EDI + P3 ECX + WTP RSI + x86_64: r12 is a pointer to ram_state.blocks + x86_64: r13 is a pointer to closenessfactor + + registers on PPC are: + P1(ret) r3 + P2 r14 + P3 r15 + WTP r16 (r17 has the original value) + r13 is a pointer to ram_state.blocks + + ppc uses f31 and f30 and others for certain constants + + */ + +#ifdef EEL_TARGET_PORTABLE + +#define EEL_DOESNT_NEED_EXEC_PERMS +#include "glue_port.h" + +#elif defined(__ppc__) + +#include "glue_ppc.h" + +#elif defined(_WIN64) || defined(__LP64__) + +#include "glue_x86_64.h" + +#else + +#include "glue_x86.h" + +#endif + +#ifndef GLUE_INVSQRT_NEEDREPL +#define GLUE_INVSQRT_NEEDREPL 0 +#endif + + +// used by //#eel-no-optimize:xxx, in ctx->optimizeDisableFlags +#define OPTFLAG_NO_OPTIMIZE 1 +#define OPTFLAG_NO_FPSTACK 2 +#define OPTFLAG_NO_INLINEFUNC 4 +#define OPTFLAG_FULL_DENORMAL_CHECKS 8 // if set, denormals/NaN are always filtered on assign +#define OPTFLAG_NO_DENORMAL_CHECKS 16 // if set and FULL not set, denormals/NaN are never filtered on assign + + + + +static int nseel_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments +int *NSEEL_getstats() +{ + return nseel_evallib_stats; +} +EEL_F *NSEEL_getglobalregs() +{ + return nseel_globalregs; +} + +// this stuff almost works +static int findByteOffsetInSource(compileContext *ctx, int byteoffs,int *destoffs) +{ + int x; + if (!ctx->compileLineRecs || !ctx->compileLineRecs_size) return *destoffs=0; + if (byteoffs < ctx->compileLineRecs[0].destByteCount) + { + *destoffs=0; + return 1; + } + for (x = 0; x < ctx->compileLineRecs_size-1; x ++) + { + if (byteoffs >= ctx->compileLineRecs[x].destByteCount && + byteoffs < ctx->compileLineRecs[x+1].destByteCount) break; + } + *destoffs=ctx->compileLineRecs[(x&&x==ctx->compileLineRecs_size-1)?x-1:x].srcByteCount; + + return x+2; +} + + +static void onCompileNewLine(compileContext *ctx, int srcBytes, int destBytes) +{ + if (!ctx->compileLineRecs || ctx->compileLineRecs_size >= ctx->compileLineRecs_alloc) + { + ctx->compileLineRecs_alloc = ctx->compileLineRecs_size+1024; + ctx->compileLineRecs = (lineRecItem *)realloc(ctx->compileLineRecs,sizeof(lineRecItem)*ctx->compileLineRecs_alloc); + } + if (ctx->compileLineRecs) + { + ctx->compileLineRecs[ctx->compileLineRecs_size].srcByteCount=srcBytes; + ctx->compileLineRecs[ctx->compileLineRecs_size++].destByteCount=destBytes; + } +} + +static void *__newBlock(llBlock **start,int size, int wantMprotect); + +#define OPCODE_IS_TRIVIAL(x) ((x)->opcodeType <= OPCODETYPE_VARPTRPTR) +enum { + OPCODETYPE_DIRECTVALUE=0, + OPCODETYPE_VALUE_FROM_NAMESPACENAME, // this.* are encoded this way + OPCODETYPE_VARPTR, + OPCODETYPE_VARPTRPTR, + OPCODETYPE_FUNC1, + OPCODETYPE_FUNC2, + OPCODETYPE_FUNC3, + OPCODETYPE_FUNCX, + + OPCODETYPE_MOREPARAMS, + + OPCODETYPE_INVALID, +}; + +struct opcodeRec +{ + int opcodeType; + int fntype; + void *fn; + + union { + struct opcodeRec *parms[3]; + struct { + double directValue; + EEL_F *valuePtr; // if direct value, valuePtr can be cached + } dv; + } parms; + + // allocate extra if using this field. used with: + // OPCODETYPE_VALUE_FROM_NAMESPACENAME + /// or + // OPCODETYPE_FUNC* with fntype=FUNCTYPE_EELFUNC_THIS + char relname[1]; +}; + + + + +static void *newTmpBlock(compileContext *ctx, int size) +{ + const int align = 8; + const int a1=align-1; + char *p=(char*)__newBlock(&ctx->tmpblocks_head,size+a1, 0); + return p+((align-(((INT_PTR)p)&a1))&a1); +} + +static void *__newBlock_align(compileContext *ctx, int size, int align, int isForCode) +{ + const int a1=align-1; + char *p=(char*)__newBlock( + ( + isForCode < 0 ? (isForCode == -2 ? &ctx->pblocks : &ctx->tmpblocks_head) : + isForCode > 0 ? &ctx->blocks_head : + &ctx->blocks_head_data) ,size+a1, isForCode>0); + return p+((align-(((INT_PTR)p)&a1))&a1); +} + +static opcodeRec *newOpCode(compileContext *ctx) +{ + return (opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec),8, ctx->isSharedFunctions ? 0 : -1); +} + +#define newCodeBlock(x,a) __newBlock_align(ctx,x,a,1) +#define newDataBlock(x,a) __newBlock_align(ctx,x,a,0) +#define newCtxDataBlock(x,a) __newBlock_align(ctx,x,a,-2) + +static void freeBlocks(llBlock **start); + +#ifndef DECL_ASMFUNC +#define DECL_ASMFUNC(x) \ + void nseel_asm_##x(void); \ + void nseel_asm_##x##_end(void); + + +void _asm_megabuf(void); +void _asm_megabuf_end(void); +void _asm_gmegabuf(void); +void _asm_gmegabuf_end(void); + +#endif + + + DECL_ASMFUNC(booltofp) + DECL_ASMFUNC(fptobool) + DECL_ASMFUNC(sin) + DECL_ASMFUNC(cos) + DECL_ASMFUNC(tan) + DECL_ASMFUNC(1pdd) + DECL_ASMFUNC(2pdd) + DECL_ASMFUNC(2pdds) + DECL_ASMFUNC(1pp) + DECL_ASMFUNC(2pp) + DECL_ASMFUNC(sqr) + DECL_ASMFUNC(sqrt) + DECL_ASMFUNC(log) + DECL_ASMFUNC(log10) + DECL_ASMFUNC(abs) + DECL_ASMFUNC(min) + DECL_ASMFUNC(max) + DECL_ASMFUNC(min_fp) + DECL_ASMFUNC(max_fp) + DECL_ASMFUNC(sig) + DECL_ASMFUNC(sign) + DECL_ASMFUNC(band) + DECL_ASMFUNC(bor) + DECL_ASMFUNC(bnot) + DECL_ASMFUNC(if) + DECL_ASMFUNC(fcall) + DECL_ASMFUNC(repeat) + DECL_ASMFUNC(repeatwhile) + DECL_ASMFUNC(equal) + DECL_ASMFUNC(notequal) + DECL_ASMFUNC(below) + DECL_ASMFUNC(above) + DECL_ASMFUNC(beloweq) + DECL_ASMFUNC(aboveeq) + DECL_ASMFUNC(assign) + DECL_ASMFUNC(assign_fromfp) + DECL_ASMFUNC(assign_fast) + DECL_ASMFUNC(assign_fast_fromfp) + DECL_ASMFUNC(add) + DECL_ASMFUNC(sub) + DECL_ASMFUNC(add_op) + DECL_ASMFUNC(sub_op) + DECL_ASMFUNC(add_op_fast) + DECL_ASMFUNC(sub_op_fast) + DECL_ASMFUNC(mul) + DECL_ASMFUNC(div) + DECL_ASMFUNC(mul_op) + DECL_ASMFUNC(div_op) + DECL_ASMFUNC(mod) + DECL_ASMFUNC(shl) + DECL_ASMFUNC(shr) + DECL_ASMFUNC(mod_op) + DECL_ASMFUNC(or) + DECL_ASMFUNC(or0) + DECL_ASMFUNC(xor) + DECL_ASMFUNC(xor_op) + DECL_ASMFUNC(and) + DECL_ASMFUNC(or_op) + DECL_ASMFUNC(and_op) + DECL_ASMFUNC(uplus) + DECL_ASMFUNC(uminus) + DECL_ASMFUNC(invsqrt) + DECL_ASMFUNC(dbg_getstackptr) + DECL_ASMFUNC(exec2) + + DECL_ASMFUNC(stack_push) + DECL_ASMFUNC(stack_pop) + DECL_ASMFUNC(stack_pop_fast) // just returns value, doesn't mod param + DECL_ASMFUNC(stack_peek) + DECL_ASMFUNC(stack_peek_int) + DECL_ASMFUNC(stack_peek_top) + DECL_ASMFUNC(stack_exch) + +static void *NSEEL_PProc_GRAM(void *data, int data_size, compileContext *ctx) +{ + if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->gram_blocks); + return data; +} + +static void *NSEEL_PProc_Stack(void *data, int data_size, compileContext *ctx) +{ + codeHandleType *ch=ctx->tmpCodeHandle; + + if (data_size>0) + { + UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); + UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); + + ch->want_stack=1; + if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); + + data=EEL_GLUE_set_immediate(data, stackptr); + data=EEL_GLUE_set_immediate(data, m1); // and + data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or + } + return data; +} + +static void *NSEEL_PProc_Stack_PeekInt(void *data, int data_size, compileContext *ctx, INT_PTR offs) +{ + codeHandleType *ch=ctx->tmpCodeHandle; + + if (data_size>0) + { + UINT_PTR m1=(UINT_PTR)(NSEEL_STACK_SIZE * sizeof(EEL_F) - 1); + UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); + + ch->want_stack=1; + if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); + + data=EEL_GLUE_set_immediate(data, stackptr); + data=EEL_GLUE_set_immediate(data, offs); + data=EEL_GLUE_set_immediate(data, m1); // and + data=EEL_GLUE_set_immediate(data, ((UINT_PTR)ch->stack&~m1)); //or + } + return data; +} +static void *NSEEL_PProc_Stack_PeekTop(void *data, int data_size, compileContext *ctx) +{ + codeHandleType *ch=ctx->tmpCodeHandle; + + if (data_size>0) + { + UINT_PTR stackptr = ((UINT_PTR) (&ch->stack)); + + ch->want_stack=1; + if (!ch->stack) ch->stack = newDataBlock(NSEEL_STACK_SIZE*sizeof(EEL_F),NSEEL_STACK_SIZE*sizeof(EEL_F)); + + data=EEL_GLUE_set_immediate(data, stackptr); + } + return data; +} + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +static double __floor(double a) { return floor(a); } +static double __ceil(double a) { return ceil(a); } +#define floor __floor +#define ceil __ceil +#endif + + +#ifdef NSEEL_EEL1_COMPAT_MODE +static double eel1band(double a, double b) +{ + return (fabs(a)>NSEEL_CLOSEFACTOR && fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; +} +static double eel1bor(double a, double b) +{ + return (fabs(a)>NSEEL_CLOSEFACTOR || fabs(b) > NSEEL_CLOSEFACTOR) ? 1.0 : 0.0; +} + +static double eel1sigmoid(double x, double constraint) +{ + double t = (1+exp(-x * (constraint))); + return fabs(t)>NSEEL_CLOSEFACTOR ? 1.0/t : 0; +} + +#endif + + + +#define FUNCTIONTYPE_PARAMETERCOUNTMASK 0xff + +#define BIF_NPARAMS_MASK 0x7fff00 +#define BIF_RETURNSONSTACK 0x000100 +#define BIF_LASTPARMONSTACK 0x000200 +#define BIF_RETURNSBOOL 0x000400 // this value is used in ns-eel.h in some macros, be sure to update it there if you change it here +#define BIF_LASTPARM_ASBOOL 0x000800 +#define BIF_WONTMAKEDENORMAL 0x100000 +#define BIF_CLEARDENORMAL 0x200000 + +#if defined(GLUE_HAS_FXCH) && GLUE_MAX_FPSTACK_SIZE > 0 + #define BIF_SECONDLASTPARMST 0x001000 // use with BIF_LASTPARMONSTACK only (last two parameters get passed on fp stack) + #define BIF_LAZYPARMORDERING 0x002000 // allow optimizer to avoid fxch when using BIF_TWOPARMSONFPSTACK_LAZY etc + #define BIF_REVERSEFPORDER 0x004000 // force a fxch (reverse order of last two parameters on fp stack, used by comparison functions) + + #ifndef BIF_FPSTACKUSE + #define BIF_FPSTACKUSE(x) (((x)>=0&&(x)<8) ? ((7-(x))<<16):0) + #endif + #ifndef BIF_GETFPSTACKUSE + #define BIF_GETFPSTACKUSE(x) (7 - (((x)>>16)&7)) + #endif +#else + // do not support fp stack use unless GLUE_HAS_FXCH and GLUE_MAX_FPSTACK_SIZE>0 + #define BIF_SECONDLASTPARMST 0 + #define BIF_LAZYPARMORDERING 0 + #define BIF_REVERSEFPORDER 0 + #define BIF_FPSTACKUSE(x) 0 + #define BIF_GETFPSTACKUSE(x) 0 +#endif + +#define BIF_TWOPARMSONFPSTACK (BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) +#define BIF_TWOPARMSONFPSTACK_LAZY (BIF_LAZYPARMORDERING|BIF_SECONDLASTPARMST|BIF_LASTPARMONSTACK) + + + + +EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F f); + +#define FNPTR_HAS_CONDITIONAL_EXEC(op) (op->fntype == FUNCTYPE_FUNCTIONTYPEREC && (functionType*)op->fn >= fnTable1 && (functionType*)op->fn < fnTable1+5) + +static functionType fnTable1[] = { + { "_if", nseel_asm_if,nseel_asm_if_end, 3|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL, }, + { "_and", nseel_asm_band,nseel_asm_band_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSBOOL } , + { "_or", nseel_asm_bor,nseel_asm_bor_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSBOOL } , + { "loop", nseel_asm_repeat,nseel_asm_repeat_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL }, + { "while", nseel_asm_repeatwhile,nseel_asm_repeatwhile_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL }, + + { "_not", nseel_asm_bnot,nseel_asm_bnot_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARM_ASBOOL|BIF_RETURNSBOOL|BIF_FPSTACKUSE(1), } , + + { "_equal", nseel_asm_equal,nseel_asm_equal_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2), {0} }, + { "_noteq", nseel_asm_notequal,nseel_asm_notequal_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK_LAZY|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2), {0} }, + +#ifdef GLUE_HAS_FXCH + { "_above", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2) }, + { "_aboeq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2) }, + { "_below", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_REVERSEFPORDER|BIF_FPSTACKUSE(2)}, + { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL|BIF_FPSTACKUSE(2) }, +#else + { "_above", nseel_asm_above,nseel_asm_above_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSBOOL }, + { "_aboeq", nseel_asm_aboveeq,nseel_asm_aboveeq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSBOOL }, + { "_below", nseel_asm_below,nseel_asm_below_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL }, + { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_TWOPARMSONFPSTACK|BIF_RETURNSBOOL }, +#endif + + +#ifndef GLUE_HAS_NATIVE_TRIGSQRTLOG + { "sin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&sin} }, + { "cos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&cos} }, + { "tan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&tan} }, + { "sqrt", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&sqrt}, }, + { "log", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log} }, + { "log10", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&log10} }, +#else + { "sin", nseel_asm_sin,nseel_asm_sin_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, + { "cos", nseel_asm_cos,nseel_asm_cos_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, + { "tan", nseel_asm_tan,nseel_asm_tan_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, + { "sqrt", nseel_asm_sqrt,nseel_asm_sqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, + { "log", nseel_asm_log,nseel_asm_log_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, + { "log10", nseel_asm_log10,nseel_asm_log10_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), }, +#endif + + { "_set",nseel_asm_assign,nseel_asm_assign_end,2|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL, }, // if denormal flag set, we'll use assign which will take care of the denormal + { "_mod",nseel_asm_mod,nseel_asm_mod_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL }, + { "_shr",nseel_asm_shr,nseel_asm_shr_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL }, + { "_shl",nseel_asm_shl,nseel_asm_shl_end,2 | NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL }, + + { "_mulop",nseel_asm_mul_op,nseel_asm_mul_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // mulop/divop clear denormals manually + { "_divop",nseel_asm_div_op,nseel_asm_div_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, + + { "_orop",nseel_asm_or_op,nseel_asm_or_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // these go to int so they clear denormals too + { "_andop",nseel_asm_and_op,nseel_asm_and_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, + { "_xorop",nseel_asm_xor_op,nseel_asm_xor_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, + { "_modop",nseel_asm_mod_op,nseel_asm_mod_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, + + { "_addop",nseel_asm_add_op,nseel_asm_add_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, // default versions of these clear denormals, but we can shortcut to non-denorm check versions if input is known non-denormal + { "_subop",nseel_asm_sub_op,nseel_asm_sub_op_end,2|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL}, + + + { "asin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&asin}, }, + { "acos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&acos}, }, + { "atan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&atan}, }, + { "atan2", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&atan2}, }, + { "pow", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&pow}, }, + { "_powop", nseel_asm_2pdds,nseel_asm_2pdds_end, 2|BIF_LASTPARMONSTACK|BIF_CLEARDENORMAL, {&pow}, }, + { "exp", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK, {&exp}, }, + { "abs", nseel_asm_abs,nseel_asm_abs_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0)|BIF_WONTMAKEDENORMAL }, + { "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1) }, + { "min", nseel_asm_min,nseel_asm_min_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, + { "max", nseel_asm_max,nseel_asm_max_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_FPSTACKUSE(3)|BIF_WONTMAKEDENORMAL }, + { "sign", nseel_asm_sign,nseel_asm_sign_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL, }, + { "rand", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&nseel_int_rand}, }, + + { "floor", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&floor} }, + { "ceil", nseel_asm_1pdd,nseel_asm_1pdd_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL, {&ceil} }, + + { "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(3), {GLUE_INVSQRT_NEEDREPL} }, + + { "__dbg_getstackptr", nseel_asm_dbg_getstackptr,nseel_asm_dbg_getstackptr_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1), }, + + { "_xor", nseel_asm_xor,nseel_asm_xor_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL } , + +#ifdef NSEEL_EEL1_COMPAT_MODE + { "sigmoid", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK, {&eel1sigmoid}, }, + + // these differ from _and/_or, they always evaluate both... + { "band", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1band}, }, + { "bor", nseel_asm_2pdd,nseel_asm_2pdd_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_CLEARDENORMAL , {&eel1bor}, }, + + {"exec2",nseel_asm_exec2,nseel_asm_exec2_end,2|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, + {"exec3",nseel_asm_exec2,nseel_asm_exec2_end,3|NSEEL_NPARAMS_FLAG_CONST|BIF_WONTMAKEDENORMAL}, +#endif // end EEL1 compat + + + {"_mem",_asm_megabuf,_asm_megabuf_end,1|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL,{&__NSEEL_RAMAlloc}, + #ifdef GLUE_MEM_NEEDS_PPROC + NSEEL_PProc_RAM, + #else + NULL + #endif + }, + + {"_gmem",_asm_gmegabuf,_asm_gmegabuf_end,1|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(1)|BIF_CLEARDENORMAL,{&__NSEEL_RAMAllocGMEM},NSEEL_PProc_GRAM}, + {"freembuf",_asm_generic1parm,_asm_generic1parm_end,1,{&__NSEEL_RAM_MemFree},NSEEL_PProc_RAM}, + {"memcpy",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemCpy},NSEEL_PProc_RAM}, + {"memset",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemSet},NSEEL_PProc_RAM}, + + {"stack_push",nseel_asm_stack_push,nseel_asm_stack_push_end,1|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, + {"stack_pop",nseel_asm_stack_pop,nseel_asm_stack_pop_end,1|BIF_FPSTACKUSE(1),{0,},NSEEL_PProc_Stack}, + {"stack_peek",nseel_asm_stack_peek,nseel_asm_stack_peek_end,1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_FPSTACKUSE(0),{0,},NSEEL_PProc_Stack}, + {"stack_exch",nseel_asm_stack_exch,nseel_asm_stack_exch_end,1|BIF_FPSTACKUSE(1), {0,},NSEEL_PProc_Stack_PeekTop}, +}; + +static functionType *fnTableUser; +static int fnTableUser_size; + +functionType *nseel_getFunctionFromTable(int idx) +{ + if (idx<0) return 0; + if (idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) + { + idx -= sizeof(fnTable1)/sizeof(fnTable1[0]); + if (!fnTableUser || idx >= fnTableUser_size) return 0; + return fnTableUser+idx; + } + return fnTable1+idx; +} + +int NSEEL_init() // returns 0 on success +{ + +#ifdef EEL_VALIDATE_FSTUBS + int a; + for (a=0;a < sizeof(fnTable1)/sizeof(fnTable1[0]);a++) + { + char *code_startaddr = (char*)fnTable1[a].afunc; + char *endp = (char *)fnTable1[a].func_e; + // validate + int sz=0; + char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); + + if (f+sz > endp) + { +#ifdef _WIN32 + OutputDebugString("bad eel function stub\n"); +#else + printf("bad eel function stub\n"); +#endif + *(char *)NULL = 0; + } + } +#ifdef _WIN32 + OutputDebugString("eel function stub (builtin) validation complete\n"); +#else + printf("eel function stub (builtin) validation complete\n"); +#endif +#endif + + NSEEL_quit(); + return 0; +} + +void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2) +{ + if (!fnTableUser || !(fnTableUser_size&7)) + { + fnTableUser=(functionType *)realloc(fnTableUser,(fnTableUser_size+8)*sizeof(functionType)); + } + if (fnTableUser) + { + +#ifdef EEL_VALIDATE_FSTUBS + { + char *endp = code_startaddr+code_len; + // validate + int sz=0; + char *f=(char *)GLUE_realAddress(code_startaddr,endp,&sz); + + if (f+sz > endp) + { +#ifdef _WIN32 + OutputDebugString("bad eel function stub\n"); +#else + printf("bad eel function stub\n"); +#endif + *(char *)NULL = 0; + } +#ifdef _WIN32 + OutputDebugString(name); + OutputDebugString(" - validated eel function stub\n"); +#else + printf("eel function stub validation complete for %s\n",name); +#endif + } +#endif + + memset(&fnTableUser[fnTableUser_size],0,sizeof(functionType)); + + if (!(nparms & BIF_RETURNSBOOL)) + { + if (code_startaddr == (void *)&_asm_generic1parm_retd || + code_startaddr == (void *)&_asm_generic2parm_retd || + code_startaddr == (void *)&_asm_generic3parm_retd) + { + nparms |= BIF_RETURNSONSTACK; + } + } + fnTableUser[fnTableUser_size].nParams = nparms; + fnTableUser[fnTableUser_size].name = name; + fnTableUser[fnTableUser_size].afunc = code_startaddr; + fnTableUser[fnTableUser_size].func_e = code_startaddr + code_len; + fnTableUser[fnTableUser_size].pProc = pproc; + fnTableUser[fnTableUser_size].replptrs[0]=fptr; + fnTableUser[fnTableUser_size].replptrs[1]=fptr2; + fnTableUser_size++; + } +} + +void NSEEL_quit() +{ + free(fnTableUser); + fnTableUser_size=0; + fnTableUser=0; +} + +//--------------------------------------------------------------------------------------------------------------- +static void freeBlocks(llBlock **start) +{ + llBlock *s=*start; + *start=0; + while (s) + { + llBlock *llB = s->next; + free(s); + s=llB; + } +} + +//--------------------------------------------------------------------------------------------------------------- +static void *__newBlock(llBlock **start, int size, int wantMprotect) +{ +#if !defined(EEL_DOESNT_NEED_EXEC_PERMS) && defined(_WIN32) + DWORD ov; + UINT_PTR offs,eoffs; +#endif + llBlock *llb; + int alloc_size; + if (*start && (LLB_DSIZE - (*start)->sizeused) >= size) + { + void *t=(*start)->block+(*start)->sizeused; + (*start)->sizeused+=(size+7)&~7; + return t; + } + + alloc_size=sizeof(llBlock); + if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE; + llb = (llBlock *)malloc(alloc_size); // grab bigger block if absolutely necessary (heh) + if (!llb) return NULL; + +#ifndef EEL_DOESNT_NEED_EXEC_PERMS + if (wantMprotect) + { + #ifdef _WIN32 + offs=((UINT_PTR)llb)&~4095; + eoffs=((UINT_PTR)llb + alloc_size + 4095)&~4095; + VirtualProtect((LPVOID)offs,eoffs-offs,PAGE_EXECUTE_READWRITE,&ov); + // MessageBox(NULL,"vprotecting, yay\n","a",0); + #elif defined(EEL_USE_MPROTECT) + { + static int pagesize = 0; + if (!pagesize) + { + pagesize=sysconf(_SC_PAGESIZE); + if (!pagesize) pagesize=4096; + } + uintptr_t offs,eoffs; + offs=((uintptr_t)llb)&~(pagesize-1); + eoffs=((uintptr_t)llb + alloc_size + pagesize-1)&~(pagesize-1); + mprotect((void*)offs,eoffs-offs,PROT_WRITE|PROT_READ|PROT_EXEC); + } + #endif + } +#endif + llb->sizeused=(size+7)&~7; + llb->next = *start; + *start = llb; + return llb->block; +} + + +//--------------------------------------------------------------------------------------------------------------- +opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value) +{ + opcodeRec *r=newOpCode(ctx); + if (r) + { + r->opcodeType = OPCODETYPE_DIRECTVALUE; + r->parms.dv.directValue = value; + r->parms.dv.valuePtr = NULL; + } + return r; +} + +opcodeRec *nseel_createCompiledValueFromNamespaceName(compileContext *ctx, const char *relName) +{ + int n=strlen(relName); + opcodeRec *r=(opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec)+NSEEL_MAX_VARIABLE_NAMELEN,8, ctx->isSharedFunctions ? 0 : -1); + if (!r) return 0; + r->opcodeType=OPCODETYPE_VALUE_FROM_NAMESPACENAME; + if (n > NSEEL_MAX_VARIABLE_NAMELEN) n=NSEEL_MAX_VARIABLE_NAMELEN; + memcpy(r->relname,relName,n); + r->relname[n]=0; + return r; +} + +opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue) +{ + opcodeRec *r=newOpCode(ctx); + if (r) + { + r->opcodeType = OPCODETYPE_VARPTR; + r->parms.dv.valuePtr=addrValue; + r->parms.dv.directValue=0.0; + } + return r; +} + +opcodeRec *nseel_createCompiledValuePtrPtr(compileContext *ctx, EEL_F **addrValue) +{ + opcodeRec *r=newOpCode(ctx); + if (r) + { + r->opcodeType = OPCODETYPE_VARPTRPTR; + r->parms.dv.valuePtr=(EEL_F *)addrValue; + r->parms.dv.directValue=0.0; + } + return r; +} + +opcodeRec *nseel_createCompiledFunctionCallEELThis(compileContext *ctx, _codeHandleFunctionRec *fnp, const char *relName) +{ + int n=strlen(relName); + opcodeRec *r=(opcodeRec*)__newBlock_align(ctx,sizeof(opcodeRec)+NSEEL_MAX_VARIABLE_NAMELEN,8, ctx->isSharedFunctions ? 0 : -1); + if (!r) return 0; + r->fntype=FUNCTYPE_EELFUNC_THIS; + r->fn = fnp; + if (fnp->num_params > 3) r->opcodeType = OPCODETYPE_FUNCX; + else if (fnp->num_params == 3) r->opcodeType = OPCODETYPE_FUNC3; + else if (fnp->num_params==2) r->opcodeType = OPCODETYPE_FUNC2; + else r->opcodeType = OPCODETYPE_FUNC1; + if (n > NSEEL_MAX_VARIABLE_NAMELEN) n=NSEEL_MAX_VARIABLE_NAMELEN; + memcpy(r->relname,relName,n); + r->relname[n]=0; + + return r; +} + +opcodeRec *nseel_createCompiledFunctionCall(compileContext *ctx, int np, int fntype, void *fn) +{ + opcodeRec *r=newOpCode(ctx); + if (!r) return 0; + r->fntype=fntype; + r->fn = fn; + + if (np > 3) r->opcodeType = OPCODETYPE_FUNCX; + else if (np == 3) r->opcodeType = OPCODETYPE_FUNC3; + else if (np==2) r->opcodeType = OPCODETYPE_FUNC2; + else r->opcodeType = OPCODETYPE_FUNC1; + + return r; +} + +opcodeRec *nseel_setCompiledFunctionCallParameters(opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3) +{ + if (fn) + { + opcodeRec *r = fn; + r->parms.parms[0] = code1; + r->parms.parms[1] = code2; + r->parms.parms[2] = code3; + } + return fn; +} + + +opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2) +{ + opcodeRec *r=code1 && code2 ? newOpCode(ctx) : NULL; + if (r) + { + r->opcodeType = OPCODETYPE_MOREPARAMS; + r->parms.parms[0] = code1; + r->parms.parms[1] = code2; + r->parms.parms[2] = 0; + } + return r; +} + +opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2) +{ + opcodeRec *r=code1 && (np<2 || code2) ? newOpCode(ctx) : NULL; + if (r) + { + r->opcodeType = np>=2 ? OPCODETYPE_FUNC2:OPCODETYPE_FUNC1; + r->fntype = fn; + r->fn = fn == FN_JOIN_STATEMENTS ? r : NULL; // for joins, fn is temporarily used for tail pointers + if (code1 && fn == FN_JOIN_STATEMENTS && code1->opcodeType == OPCODETYPE_FUNC2 && code1->fntype == fn) + { + opcodeRec *t = (opcodeRec *)code1->fn; + // keep joins in the form of dosomething->morestuff. + // in this instance, code1 is previous stuff to do, code2 is new stuff to do + r->parms.parms[0] = t->parms.parms[1]; + r->parms.parms[1] = code2; + + code1->fn = (t->parms.parms[1] = r); + return code1; + } + r->parms.parms[0] = code1; + r->parms.parms[1] = code2; + } + return r; +} + + +// these are bitmasks; on request you can tell what is supported, and compileOpcodes will return one of them +#define RETURNVALUE_IGNORE 0 // ignore return value +#define RETURNVALUE_NORMAL 1 // pointer +#define RETURNVALUE_FPSTACK 2 +#define RETURNVALUE_BOOL 4 // P1 is nonzero if true + + + + +static int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTable, const char *namespacePathToThis, + int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput); + + +static unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const char *namespacePathToThis, + int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput); + +_codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr) +{ + int n; + _codeHandleFunctionRec *subfr = fr->isCommonFunction ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); + if (!subfr) return 0; + // fr points to functionname()'s rec, nameptr to blah.functionname() + + *subfr = *fr; + n = strlen(nameptr); + if (n > sizeof(subfr->fname)-1) n=sizeof(subfr->fname)-1; + memcpy(subfr->fname,nameptr,n); + subfr->fname[n]=0; + + subfr->next = NULL; + subfr->startptr=0; // make sure this code gets recompiled (with correct member ptrs) for this instance! + + // subfr->derivedCopies already points to the right place + fr->derivedCopies = subfr; + + return subfr; + +} +static void combineNamespaceFields(char *nm, const char *prefix, const char *relname) // nm must be NSEEL_MAX_VARIABLE_NAMELEN+1 bytes +{ + int lfp = prefix ? strlen(prefix) : 0, lrn=strlen(relname); + + while (*relname == '.') // if relname begins with ., then remove a chunk of context from prefix + { + relname++; + while (lfp>0 && prefix[lfp-1] != '.') lfp--; + if (lfp>0) lfp--; + } + + if (lfp > NSEEL_MAX_VARIABLE_NAMELEN-3) lfp=NSEEL_MAX_VARIABLE_NAMELEN-3; + if (lfp>0) memcpy(nm,prefix,lfp); + + if (lrn > NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0)) lrn=NSEEL_MAX_VARIABLE_NAMELEN - lfp - (lfp>0); + if (lrn > 0) + { + if (lfp>0) nm[lfp++] = '.'; + memcpy(nm+lfp,relname,lrn); + lfp+=lrn; + } + nm[lfp++]=0; +} + + +//--------------------------------------------------------------------------------------------------------------- +static void *nseel_getBuiltinFunctionAddress(compileContext *ctx, + int fntype, void *fn, + NSEEL_PPPROC *pProc, void ***replList, + void **endP, int *abiInfo, int preferredReturnValues) +{ + switch (fntype) + { +#define RF(x) *endP = nseel_asm_##x##_end; return (void*)nseel_asm_##x + case FN_ADD: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; RF(add); + case FN_SUB: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL; RF(sub); + case FN_MULTIPLY: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2); RF(mul); + case FN_DIVIDE: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK|BIF_FPSTACKUSE(2); RF(div); +#ifndef EEL_TARGET_PORTABLE + case FN_JOIN_STATEMENTS: *abiInfo = BIF_WONTMAKEDENORMAL; RF(exec2); // shouldn't ever be used anyway, but scared to remove +#endif + case FN_AND: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(and); + case FN_OR: *abiInfo = BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_CLEARDENORMAL; RF(or); +#ifndef EEL_TARGET_PORTABLE + case FN_UPLUS: *abiInfo = BIF_WONTMAKEDENORMAL; RF(uplus); // shouldn't ever be used anyway, but scared to remove +#endif + case FN_UMINUS: *abiInfo = BIF_RETURNSONSTACK|BIF_LASTPARMONSTACK|BIF_WONTMAKEDENORMAL; RF(uminus); +#undef RF + + case FUNCTYPE_FUNCTIONTYPEREC: + if (fn) + { + functionType *p=(functionType *)fn; + + // if prefers fpstack or bool, or ignoring value, then use fp-stack versions + if ((preferredReturnValues&(RETURNVALUE_BOOL|RETURNVALUE_FPSTACK)) || !preferredReturnValues) + { + static functionType min2={ "min", nseel_asm_min_fp,nseel_asm_min_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; + static functionType max2={ "max", nseel_asm_max_fp,nseel_asm_max_fp_end, 2|NSEEL_NPARAMS_FLAG_CONST|BIF_RETURNSONSTACK|BIF_TWOPARMSONFPSTACK_LAZY|BIF_FPSTACKUSE(2)|BIF_WONTMAKEDENORMAL }; + + if (p->afunc == (void*)nseel_asm_min) p = &min2; + else if (p->afunc == (void*)nseel_asm_max) p = &max2; + } + + *replList=p->replptrs; + *pProc=p->pProc; + *endP = p->func_e; + *abiInfo = p->nParams & BIF_NPARAMS_MASK; + return p->afunc; + } + break; + } + + return 0; +} + + + +static void *nseel_getEELFunctionAddress(compileContext *ctx, + opcodeRec *op, + int *customFuncParmSize, int *customFuncLocalStorageSize, + EEL_F ***customFuncLocalStorage, int *computTableTop, + void **endP, int *isRaw, int wantCodeGenerated, + const char *namespacePathToThis, int *rvMode, int *fpStackUse, int *canHaveDenormalOutput) // if wantCodeGenerated is false, can return bogus pointers in raw mode +{ + _codeHandleFunctionRec *fn = (_codeHandleFunctionRec*)op->fn; + switch (op->fntype) + { + case FUNCTYPE_EELFUNC_THIS: + if (fn) + { + _codeHandleFunctionRec *fr_base = fn; + char nm[NSEEL_MAX_VARIABLE_NAMELEN+1]; + combineNamespaceFields(nm,namespacePathToThis,op->relname); + + fn = 0; // if this gets re-set, it will be the new function + + // find resolved function + if (!fn) + { + _codeHandleFunctionRec *fr = fr_base; + // scan for function + while (fr && !fn) + { + if (!strcasecmp(fr->fname,nm)) fn = fr; + fr=fr->derivedCopies; + } + } + + if (!fn) // generate copy of function + { + fn = eel_createFunctionNamespacedInstance(ctx,fr_base,nm); + } + } + + // fall through! + case FUNCTYPE_EELFUNC: + if (fn) + { + const char *fPrefix=NULL; + char prefix_buf[NSEEL_MAX_VARIABLE_NAMELEN+1]; + + _codeHandleFunctionRec *fr = (_codeHandleFunctionRec *) fn; + + if (fr->usesThisPointer) + { + char *p=fr->fname; + while (*p) p++; + while (p >= fr->fname && *p != '.') p--; + if (p >= fr->fname) + { + int l = p-fr->fname; + memcpy(prefix_buf,fr->fname,l); + prefix_buf[l]=0; + fPrefix = prefix_buf; + } + else + { + fPrefix = fr->fname; // default prefix is function name if no other context + } + } + + + if (!fr->startptr && fr->opcodes && fr->startptr_size > 0) + { + int sz; + fr->tmpspace_req=0; + fr->rvMode = RETURNVALUE_IGNORE; + fr->canHaveDenormalOutput=0; + + sz=compileOpcodes(ctx,fr->opcodes,NULL,128*1024*1024,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); + + if (!wantCodeGenerated) + { + // don't compile anything for now, just give stats + if (computTableTop) *computTableTop += fr->tmpspace_req; + *customFuncParmSize = fr->num_params; + *customFuncLocalStorage = fr->localstorage; + *customFuncLocalStorageSize = fr->localstorage_size; + *rvMode = fr->rvMode; + *fpStackUse = fr->fpStackUsage; + if (canHaveDenormalOutput) *canHaveDenormalOutput=fr->canHaveDenormalOutput; + + if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) + { + *isRaw = 1; + *endP = ((char *)1) + sz; + return (char *)1; + } + *endP = (void*)nseel_asm_fcall_end; + return (void*)nseel_asm_fcall; + } + + if (sz <= NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE && !(ctx->optimizeDisableFlags&OPTFLAG_NO_INLINEFUNC)) + { + void *p=newTmpBlock(ctx,sz); + fr->tmpspace_req=0; + if (p) + { + fr->canHaveDenormalOutput=0; + sz=compileOpcodes(ctx,fr->opcodes,(unsigned char*)p,sz,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); + // recompile function with native context pointers + if (sz>0) + { + fr->startptr_size=sz; + fr->startptr=p; + } + } + } + else + { + unsigned char *codeCall; + fr->tmpspace_req=0; + fr->fpStackUsage=0; + fr->canHaveDenormalOutput=0; + codeCall=compileCodeBlockWithRet(ctx,fr->opcodes,&fr->tmpspace_req,fPrefix,RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK,&fr->rvMode,&fr->fpStackUsage,&fr->canHaveDenormalOutput); + if (codeCall) + { + void *f=GLUE_realAddress(nseel_asm_fcall,nseel_asm_fcall_end,&sz); + fr->startptr = newTmpBlock(ctx,sz); + if (fr->startptr) + { + memcpy(fr->startptr,f,sz); + EEL_GLUE_set_immediate(fr->startptr,(INT_PTR)codeCall); + fr->startptr_size = sz; + } + } + } + } + if (fr->startptr) + { + if (computTableTop) *computTableTop += fr->tmpspace_req; + *customFuncParmSize = fr->num_params; + *customFuncLocalStorage = fr->localstorage; + *customFuncLocalStorageSize = fr->localstorage_size; + *rvMode = fr->rvMode; + *fpStackUse = fr->fpStackUsage; + if (canHaveDenormalOutput) *canHaveDenormalOutput= fr->canHaveDenormalOutput; + *endP = (char*)fr->startptr + fr->startptr_size; + *isRaw=1; + return fr->startptr; + } + } + break; + } + + return 0; +} + + + +// returns true if does something (other than calculating and throwing away a value) +static char optimizeOpcodes(compileContext *ctx, opcodeRec *op, int needsResult) +{ + opcodeRec *lastJoinOp=NULL; + char retv, retv_parm[3], joined_retv=0; + while (op && op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) + { + if (!optimizeOpcodes(ctx,op->parms.parms[0], 0) || OPCODE_IS_TRIVIAL(op->parms.parms[0])) + { + // direct value, can skip ourselves + memcpy(op,op->parms.parms[1],sizeof(*op)); + } + else + { + joined_retv |= 1; + lastJoinOp = op; + op = op->parms.parms[1]; + } + } + +start_over: // when an opcode changed substantially in optimization, goto here to reprocess it + + retv = retv_parm[0]=retv_parm[1]=retv_parm[2]=0; + + if (!op || // should never really happen + OPCODE_IS_TRIVIAL(op) || // should happen often (vars) + op->opcodeType < 0 || op->opcodeType >= OPCODETYPE_INVALID // should never happen (assert would be appropriate heh) + ) return joined_retv; + + if (!needsResult) + { + if (op->fntype == FUNCTYPE_EELFUNC || op->fntype == FUNCTYPE_EELFUNC_THIS) + { + needsResult=1; // assume eel functions are non-const for now + } + else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) + { + functionType *pfn = (functionType *)op->fn; + if (!pfn || !(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) needsResult=1; + } + } + + if (op->opcodeType>=OPCODETYPE_FUNC2) retv_parm[1] = optimizeOpcodes(ctx,op->parms.parms[1], needsResult); + if (op->opcodeType>=OPCODETYPE_FUNC3) retv_parm[2] = optimizeOpcodes(ctx,op->parms.parms[2], needsResult); + + retv_parm[0] = optimizeOpcodes(ctx,op->parms.parms[0], needsResult || + (FNPTR_HAS_CONDITIONAL_EXEC(op) && (retv_parm[1] || retv_parm[2] || op->opcodeType <= OPCODETYPE_FUNC1)) ); + + if (op->opcodeType != OPCODETYPE_MOREPARAMS) + { + if (op->fntype >= 0 && op->fntype < FUNCTYPE_SIMPLEMAX) + { + if (op->opcodeType == OPCODETYPE_FUNC1) // within FUNCTYPE_SIMPLE + { + if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) + { + switch (op->fntype) + { + case FN_UMINUS: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = - op->parms.parms[0]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_UPLUS: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + } + } + } + else if (op->opcodeType == OPCODETYPE_FUNC2) // within FUNCTYPE_SIMPLE + { + int dv0 = op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE; + int dv1 = op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE; + if (dv0 && dv1) + { + switch (op->fntype) + { + case FN_DIVIDE: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue / op->parms.parms[1]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_MULTIPLY: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue * op->parms.parms[1]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_ADD: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue + op->parms.parms[1]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_SUB: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = op->parms.parms[0]->parms.dv.directValue - op->parms.parms[1]->parms.dv.directValue; + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_AND: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = (double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) & ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue)); + op->parms.dv.valuePtr=NULL; + goto start_over; + case FN_OR: + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = (double) (((WDL_INT64)op->parms.parms[0]->parms.dv.directValue) | ((WDL_INT64)op->parms.parms[1]->parms.dv.directValue)); + op->parms.dv.valuePtr=NULL; + goto start_over; + } + } + else if (dv0 || dv1) + { + double dvalue = op->parms.parms[!dv0]->parms.dv.directValue; + switch (op->fntype) + { + case FN_OR: + if (!(WDL_INT64)dvalue) + { + // replace with or0 + static functionType fr={"or0",nseel_asm_or0, nseel_asm_or0_end, 1|NSEEL_NPARAMS_FLAG_CONST|BIF_LASTPARMONSTACK|BIF_RETURNSONSTACK|BIF_CLEARDENORMAL, {0}, NULL}; + + op->opcodeType = OPCODETYPE_FUNC1; + op->fntype = FUNCTYPE_FUNCTIONTYPEREC; + op->fn = &fr; + if (dv0) op->parms.parms[0] = op->parms.parms[1]; + goto start_over; + } + break; + case FN_SUB: + if (dv0) + { + if (dvalue == 0.0) + { + op->opcodeType = OPCODETYPE_FUNC1; + op->fntype = FN_UMINUS; + op->parms.parms[0] = op->parms.parms[1]; + goto start_over; + } + break; + } + // fall through, if dv1 we can remove +0.0 + + case FN_ADD: + if (dvalue == 0.0) + { + memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); + goto start_over; + } + break; + case FN_AND: + if ((WDL_INT64)dvalue) break; + dvalue = 0.0; // treat x&0 as x*0, which optimizes to 0 + + // fall through + case FN_MULTIPLY: + if (dvalue == 0.0) // remove multiply by 0.0 (using 0.0 direct value as replacement), unless the nonzero side did something + { + if (!retv_parm[!!dv0]) + { + memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything + goto start_over; + } + else + { + // this is 0.0 * oldexpressionthatmustbeprocessed or oldexpressionthatmustbeprocessed*0.0 + op->fntype = FN_JOIN_STATEMENTS; + + if (dv0) // 0.0*oldexpression, reverse the order so that 0 is returned + { + // set to (oldexpression;0) + opcodeRec *tmp = op->parms.parms[1]; + op->parms.parms[1] = op->parms.parms[0]; + op->parms.parms[0] = tmp; + } + goto start_over; + } + } + else if (dvalue == 1.0) // remove multiply by 1.0 (using non-1.0 value as replacement) + { + memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); + goto start_over; + } + break; + case FN_DIVIDE: + if (dv1) + { + if (dvalue == 1.0) // remove divide by 1.0 (using non-1.0 value as replacement) + { + memcpy(op,op->parms.parms[!!dv0],sizeof(*op)); + goto start_over; + } + else + { + // change to a multiply + if (op->parms.parms[1]->parms.dv.directValue == 0.0) + { + op->fntype = FN_MULTIPLY; + goto start_over; + } + else + { + double d = 1.0/op->parms.parms[1]->parms.dv.directValue; + + WDL_DenormalDoubleAccess *p = (WDL_DenormalDoubleAccess*)&d; + // allow conversion to multiply if reciprocal is exact + // we could also just look to see if the last few digits of the mantissa were 0, which would probably be good + // enough, but if the user really wants it they should do * (1/x) instead to force precalculation of reciprocal. + if (!p->w.lw && !(p->w.hw & 0xfffff)) + { + op->fntype = FN_MULTIPLY; + op->parms.parms[1]->parms.dv.directValue = d; + op->parms.parms[1]->parms.dv.valuePtr=NULL; + goto start_over; + } + } + } + } + else if (dvalue == 0.0) + { + if (!retv_parm[!!dv0]) + { + // if 0/x set to always 0. + // this is 0.0 / (oldexpression that can be eliminated) + memcpy(op,op->parms.parms[!dv0],sizeof(*op)); // set to 0 if other action wouldn't do anything + } + else + { + opcodeRec *tmp; + // this is 0.0 / oldexpressionthatmustbeprocessed + op->fntype = FN_JOIN_STATEMENTS; + tmp = op->parms.parms[1]; + op->parms.parms[1] = op->parms.parms[0]; + op->parms.parms[0] = tmp; + // set to (oldexpression;0) + } + goto start_over; + } + break; + } + } + } + // FUNCTYPE_SIMPLE + } + else if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC && op->fn) + { + + /* + probably worth doing reduction on: + _divop (constant change to multiply) + _and + _or + _not + _mod + _shr + _shl + _xor + abs + + maybe: + min + max + _equal + _noteq + _below + _above + _beleq + _aboeq + + + also, optimize should (recursively or maybe iteratively?) search transitive functions (mul/div) for more constant reduction possibilities + + + */ + + + functionType *pfn = (functionType *)op->fn; + + if (!(pfn->nParams&NSEEL_NPARAMS_FLAG_CONST)) retv|=1; + + if (op->opcodeType==OPCODETYPE_FUNC1) // within FUNCTYPE_FUNCTIONTYPEREC + { + if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) + { + int suc=1; + EEL_F v = op->parms.parms[0]->parms.dv.directValue; + #define DOF(x) if (!strcmp(pfn->name,#x)) v = x(v); else + DOF(sin) + DOF(cos) + DOF(tan) + DOF(asin) + DOF(acos) + DOF(atan) + DOF(sqrt) + DOF(exp) + DOF(log) + DOF(log10) + /*else*/ suc=0; + #undef DOF + if (suc) + { + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = v; + op->parms.dv.valuePtr=NULL; + goto start_over; + } + + + } + } + else if (op->opcodeType==OPCODETYPE_FUNC2) // within FUNCTYPE_FUNCTIONTYPEREC + { + if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE && + op->parms.parms[1]->opcodeType == OPCODETYPE_DIRECTVALUE) + { + if (pfn->replptrs[0] == &pow || + pfn->replptrs[0] == &atan2) + { + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.directValue = pfn->replptrs[0]==pow ? + pow(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue) : + atan2(op->parms.parms[0]->parms.dv.directValue, op->parms.parms[1]->parms.dv.directValue); + op->parms.dv.valuePtr=NULL; + goto start_over; + } + } + else if (pfn->replptrs[0] == &pow) + { + opcodeRec *first_parm = op->parms.parms[0]; + if (first_parm->opcodeType == op->opcodeType && first_parm->fn == op->fn && first_parm->fntype == op->fntype) + { + // since first_parm is a pow too, we can multiply the exponents. + + // set our base to be the base of the inner pow + op->parms.parms[0] = first_parm->parms.parms[0]; + + // make the old extra pow be a multiply of the exponents + first_parm->fntype = FN_MULTIPLY; + first_parm->parms.parms[0] = op->parms.parms[1]; + + // put that as the exponent + op->parms.parms[1] = first_parm; + + goto start_over; + } + } + } + else if (op->opcodeType==OPCODETYPE_FUNC3) // within FUNCTYPE_FUNCTIONTYPEREC + { + if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) + { + if (!strcmp(pfn->name,"_if")) + { + int s = fabs(op->parms.parms[0]->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; + memcpy(op,op->parms.parms[s ? 1 : 2],sizeof(opcodeRec)); + goto start_over; + } + } + } + // FUNCTYPE_FUNCTIONTYPEREC + } + else + { + // unknown or eel func, assume non-const + retv |= 1; + } + } + + // if we need results, or our function has effects itself, then finish + if (retv || needsResult) + { + return retv || joined_retv || retv_parm[0] || retv_parm[1] || retv_parm[2]; + } + + // we don't need results here, and our function is const, which means we can remove it + { + int cnt=0, idx1=0, idx2=0, x; + for (x=0;x<3;x++) if (retv_parm[x]) { if (!cnt++) idx1=x; else idx2=x; } + + if (!cnt) // none of the parameters do anything, remove this opcode + { + if (lastJoinOp) + { + // replace previous join with its first linked opcode, removing this opcode completely + memcpy(lastJoinOp,lastJoinOp->parms.parms[0],sizeof(*lastJoinOp)); + } + else if (op->opcodeType != OPCODETYPE_DIRECTVALUE) + { + // allow caller to easily detect this as trivial and remove it + op->opcodeType = OPCODETYPE_DIRECTVALUE; + op->parms.dv.valuePtr=NULL; + op->parms.dv.directValue=0.0; + } + // return joined_retv below + } + else + { + // if parameters are non-const, and we're a conditional, preserve our function + if (FNPTR_HAS_CONDITIONAL_EXEC(op)) return 1; + + // otherwise, condense into either the non-const statement, or a join + if (cnt==1) + { + memcpy(op,op->parms.parms[idx1],sizeof(*op)); + } + else if (cnt == 2) + { + op->opcodeType = OPCODETYPE_FUNC2; + op->fntype = FN_JOIN_STATEMENTS; + op->fn = op; + op->parms.parms[0] = op->parms.parms[idx1]; + op->parms.parms[1] = op->parms.parms[idx2]; + op->parms.parms[2] = NULL; + } + else + { + // todo need to create a new opcodeRec here, for now just leave as is + // (non-conditional const 3 parameter functions are rare anyway) + } + return 1; + } + } + return joined_retv; +} + + +static int generateValueToReg(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int whichReg, const char *functionPrefix, int allowCache) +{ + EEL_F *b=NULL; + if (op->opcodeType==OPCODETYPE_VALUE_FROM_NAMESPACENAME) + { + char nm[NSEEL_MAX_VARIABLE_NAMELEN+1]; + + combineNamespaceFields(nm,functionPrefix,op->relname); + + b = nseel_int_register_var(ctx,nm,0); + if (!b) RET_MINUS1_FAIL("error registering var") + } + else + { + if (op->opcodeType != OPCODETYPE_DIRECTVALUE) allowCache=0; + + b=op->parms.dv.valuePtr; + if (b && op->opcodeType == OPCODETYPE_VARPTRPTR) b = *(EEL_F **)b; + if (!b && allowCache) + { + int n=50; // only scan last X items + opcodeRec *r = ctx->directValueCache; + while (r && n--) + { + if (r->parms.dv.directValue == op->parms.dv.directValue && (b=r->parms.dv.valuePtr)) break; + r=(opcodeRec*)r->fn; + } + } + if (!b) + { + ctx->l_stats[3]++; + b = newDataBlock(sizeof(EEL_F),sizeof(EEL_F)); + if (!b) RET_MINUS1_FAIL("error allocating data block") + + if (op->opcodeType != OPCODETYPE_VARPTRPTR) op->parms.dv.valuePtr = b; + #if EEL_F_SIZE == 8 + *b = denormal_filter_double2(op->parms.dv.directValue); + #else + *b = denormal_filter_float2(op->parms.dv.directValue); + #endif + + if (allowCache) + { + op->fn = ctx->directValueCache; + ctx->directValueCache = op; + } + } + } + + GLUE_MOV_PX_DIRECTVALUE_GEN(bufOut,(INT_PTR)b,whichReg); + return GLUE_MOV_PX_DIRECTVALUE_SIZE; +} + + +unsigned char *compileCodeBlockWithRet(compileContext *ctx, opcodeRec *rec, int *computTableSize, const char *namespacePathToThis, + int supportedReturnValues, int *rvType, int *fpStackUsage, int *canHaveDenormalOutput) +{ + unsigned char *p, *newblock2; + // generate code call + int funcsz=compileOpcodes(ctx,rec,NULL,1024*1024*128,NULL,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, NULL); + if (funcsz<0) return NULL; + + p = newblock2 = newCodeBlock(funcsz+ sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32); + if (!newblock2) return NULL; + #if GLUE_FUNC_ENTER_SIZE > 0 + memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); + p += GLUE_FUNC_ENTER_SIZE; + #endif + *fpStackUsage=0; + funcsz=compileOpcodes(ctx,rec,p, funcsz, computTableSize,namespacePathToThis,supportedReturnValues, rvType,fpStackUsage, canHaveDenormalOutput); + if (funcsz<0) return NULL; + p+=funcsz; + + #if GLUE_FUNC_LEAVE_SIZE > 0 + memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); + p+=GLUE_FUNC_LEAVE_SIZE; + #endif + memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET); + + ctx->l_stats[2]+=funcsz+2; + return newblock2; +} + + +static int compileNativeFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, + int *rvMode, int *fpStackUsage, int preferredReturnValues, int *canHaveDenormalOutput) +{ + // builtin function generation + int cfunc_abiinfo=0; + int local_fpstack_use=0; // how many items we have pushed onto the fp stack + int parm_size=0; + int need_fxch=0; + int pn; + int last_nt_parm=-1, last_nt_parm_type; + void *func_e=NULL; + int n_params= 1 + op->opcodeType - OPCODETYPE_FUNC1; + NSEEL_PPPROC preProc=0; + void **repl=NULL; + void *func = nseel_getBuiltinFunctionAddress(ctx, op->fntype, op->fn, &preProc,&repl,&func_e,&cfunc_abiinfo,preferredReturnValues); + + if (!func) RET_MINUS1_FAIL("error getting funcaddr") + + if (op->opcodeType == OPCODETYPE_FUNCX) + { + // this is not yet supported (calling conventions will need to be sorted, among other things) + RET_MINUS1_FAIL("funcx not supported for native functions") + } + *fpStackUsage=BIF_GETFPSTACKUSE(cfunc_abiinfo); + + *rvMode = RETURNVALUE_NORMAL; + + if (op->parms.parms[0]->opcodeType == OPCODETYPE_DIRECTVALUE) + { + if (func == nseel_asm_stack_pop) + { + int func_size=0; + func = GLUE_realAddress(nseel_asm_stack_pop_fast,nseel_asm_stack_pop_fast_end,&func_size); + if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on popfast size":"failed on popfast addr") + + if (bufOut) + { + memcpy(bufOut,func,func_size); + NSEEL_PProc_Stack(bufOut,func_size,ctx); + } + return func_size; + } + else if (func == nseel_asm_stack_peek) + { + int f = (int) op->parms.parms[0]->parms.dv.directValue; + if (!f) + { + int func_size=0; + func = GLUE_realAddress(nseel_asm_stack_peek_top,nseel_asm_stack_peek_top_end,&func_size); + if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peek size":"failed on peek addr") + + if (bufOut) + { + memcpy(bufOut,func,func_size); + NSEEL_PProc_Stack_PeekTop(bufOut,func_size,ctx); + } + return func_size; + } + else + { + int func_size=0; + func = GLUE_realAddress(nseel_asm_stack_peek_int,nseel_asm_stack_peek_int_end,&func_size); + if (!func || bufOut_len < func_size) RET_MINUS1_FAIL(func?"failed on peekint size":"failed on peekint addr") + + if (bufOut) + { + memcpy(bufOut,func,func_size); + NSEEL_PProc_Stack_PeekInt(bufOut,func_size,ctx,f*sizeof(EEL_F)); + } + return func_size; + } + } + } + // end of built-in function specific special casing + + + // first pass, calculate any non-trivial parameters + for (pn=0; pn < n_params; pn++) + { + if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) + { + int canHaveDenorm=0; + int subfpstackuse=0; + int lsz=0; + int rvt=RETURNVALUE_NORMAL; + int may_need_fppush=-1; + if (last_nt_parm>=0) + { + if (last_nt_parm_type==RETURNVALUE_FPSTACK) + { + may_need_fppush= parm_size; + } + else + { + // push last result + if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1)) RET_MINUS1_FAIL("failed on size, pushp1") + if (bufOut) memcpy(bufOut + parm_size, &GLUE_PUSH_P1, sizeof(GLUE_PUSH_P1)); + parm_size += sizeof(GLUE_PUSH_P1); + } + } + + if (pn == n_params - 1) + { + if (cfunc_abiinfo&BIF_LASTPARMONSTACK) rvt=RETURNVALUE_FPSTACK; + else if (cfunc_abiinfo&BIF_LASTPARM_ASBOOL) rvt=RETURNVALUE_BOOL; + else if (func == nseel_asm_assign) rvt=RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL; + } + else if (pn == n_params -2 && (cfunc_abiinfo&BIF_SECONDLASTPARMST)) + { + rvt=RETURNVALUE_FPSTACK; + } + + lsz = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, rvt,&rvt, &subfpstackuse, &canHaveDenorm); + + if (canHaveDenorm && canHaveDenormalOutput) *canHaveDenormalOutput = 1; + + if (lsz<0) RET_MINUS1_FAIL("call coc failed") + + parm_size += lsz; + + if (may_need_fppush>=0) + { + if (local_fpstack_use+subfpstackuse >= (GLUE_MAX_FPSTACK_SIZE-1) || (ctx->optimizeDisableFlags&OPTFLAG_NO_FPSTACK)) + { + if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) + RET_MINUS1_FAIL("failed on size, popfpstacktostack") + + if (bufOut) + { + memmove(bufOut + may_need_fppush + sizeof(GLUE_POP_FPSTACK_TOSTACK), bufOut + may_need_fppush, parm_size - may_need_fppush); + memcpy(bufOut + may_need_fppush, &GLUE_POP_FPSTACK_TOSTACK, sizeof(GLUE_POP_FPSTACK_TOSTACK)); + + } + parm_size += sizeof(GLUE_POP_FPSTACK_TOSTACK); + } + else + { + local_fpstack_use++; + } + } + + if (subfpstackuse+local_fpstack_use > *fpStackUsage) *fpStackUsage = subfpstackuse+local_fpstack_use; + + last_nt_parm = pn; + last_nt_parm_type = rvt; + + if (pn == n_params - 1 && func == nseel_asm_assign) + { + if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS) && + (!canHaveDenorm || (ctx->optimizeDisableFlags & OPTFLAG_NO_DENORMAL_CHECKS))) + { + if (rvt == RETURNVALUE_FPSTACK) + { + cfunc_abiinfo |= BIF_LASTPARMONSTACK; + func = nseel_asm_assign_fast_fromfp; + func_e = nseel_asm_assign_fast_fromfp_end; + } + else + { + func = nseel_asm_assign_fast; + func_e = nseel_asm_assign_fast_end; + } + } + else + { + if (rvt == RETURNVALUE_FPSTACK) + { + cfunc_abiinfo |= BIF_LASTPARMONSTACK; + func = nseel_asm_assign_fromfp; + func_e = nseel_asm_assign_fromfp_end; + } + } + + } + } + } + + pn = last_nt_parm; + + if (pn >= 0) // if the last thing executed doesn't go to the last parameter, move it there + { + if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) + { + // do nothing, things are in the right place + } + else if (pn != n_params-1) + { + // generate mov p1->pX + if (bufOut_len < parm_size + GLUE_SET_PX_FROM_P1_SIZE) RET_MINUS1_FAIL("size, pxfromp1") + if (bufOut) GLUE_SET_PX_FROM_P1(bufOut + parm_size,n_params - 1 - pn); + parm_size += GLUE_SET_PX_FROM_P1_SIZE; + } + } + + // pop any pushed parameters + while (--pn >= 0) + { + if (!OPCODE_IS_TRIVIAL(op->parms.parms[pn])) + { + if ((cfunc_abiinfo&BIF_SECONDLASTPARMST) && pn == n_params-2) + { + if (!local_fpstack_use) + { + if (bufOut_len < parm_size + sizeof(GLUE_POP_STACK_TO_FPSTACK)) RET_MINUS1_FAIL("size, popstacktofpstack 2") + if (bufOut) memcpy(bufOut+parm_size,GLUE_POP_STACK_TO_FPSTACK,sizeof(GLUE_POP_STACK_TO_FPSTACK)); + parm_size += sizeof(GLUE_POP_STACK_TO_FPSTACK); + need_fxch = 1; + } + else + { + local_fpstack_use--; + } + } + else + { + if (bufOut_len < parm_size + GLUE_POP_PX_SIZE) RET_MINUS1_FAIL("size, poppx") + if (bufOut) GLUE_POP_PX(bufOut + parm_size,n_params - 1 - pn); + parm_size += GLUE_POP_PX_SIZE; + } + } + } + + // finally, set trivial pointers + for (pn=0; pn < n_params; pn++) + { + if (OPCODE_IS_TRIVIAL(op->parms.parms[pn])) + { + if (pn == n_params-2 && (cfunc_abiinfo&(BIF_SECONDLASTPARMST))) // second to last parameter + { + int a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, + RETURNVALUE_FPSTACK,NULL,NULL,canHaveDenormalOutput); + if (a<0) RET_MINUS1_FAIL("coc call here 2") + parm_size+=a; + need_fxch = 1; + } + else if (pn == n_params-1) // last parameter, but we should call compileOpcodes to get it in the right format (compileOpcodes can optimize that process if it needs to) + { + int rvt=0, a; + int wantFpStack = func == nseel_asm_assign; +#ifdef GLUE_PREFER_NONFP_DV_ASSIGNS // x86-64, and maybe others, prefer to avoid the fp stack for a simple copy + if (wantFpStack && + (op->parms.parms[pn]->opcodeType != OPCODETYPE_DIRECTVALUE || + (op->parms.parms[pn]->parms.dv.directValue != 1.0 && op->parms.parms[pn]->parms.dv.directValue != 0.0))) + { + wantFpStack=0; + } +#endif + + a = compileOpcodes(ctx,op->parms.parms[pn],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size,computTableSize,namespacePathToThis, + (cfunc_abiinfo & BIF_LASTPARMONSTACK) ? RETURNVALUE_FPSTACK : + (cfunc_abiinfo & BIF_LASTPARM_ASBOOL) ? RETURNVALUE_BOOL : + wantFpStack ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : + RETURNVALUE_NORMAL,&rvt, NULL,canHaveDenormalOutput); + + if (a<0) RET_MINUS1_FAIL("coc call here 3") + parm_size+=a; + need_fxch = 0; + + if (func == nseel_asm_assign) + { + if (rvt == RETURNVALUE_FPSTACK) + { + if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) + { + func = nseel_asm_assign_fast_fromfp; + func_e = nseel_asm_assign_fast_fromfp_end; + } + else + { + func = nseel_asm_assign_fromfp; + func_e = nseel_asm_assign_fromfp_end; + } + } + else if (!(ctx->optimizeDisableFlags & OPTFLAG_FULL_DENORMAL_CHECKS)) + { + // assigning a value (from a variable or other non-computer), can use a fast assign (no denormal/result checking) + func = nseel_asm_assign_fast; + func_e = nseel_asm_assign_fast_end; + } + } + } + else + { + if (bufOut_len < parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE) RET_MINUS1_FAIL("size, pxdvsz") + if (bufOut) + { + if (generateValueToReg(ctx,op->parms.parms[pn],bufOut + parm_size,n_params - 1 - pn,namespacePathToThis, 0/*nocaching, function gets pointer*/)<0) RET_MINUS1_FAIL("gvtr") + } + parm_size += GLUE_MOV_PX_DIRECTVALUE_SIZE; + } + } + } + +#ifdef GLUE_HAS_FXCH + if ((cfunc_abiinfo&(BIF_SECONDLASTPARMST)) && !(cfunc_abiinfo&(BIF_LAZYPARMORDERING))&& + ((!!need_fxch)^!!(cfunc_abiinfo&BIF_REVERSEFPORDER)) + ) + { + // emit fxch + if (bufOut_len < sizeof(GLUE_FXCH)) RET_MINUS1_FAIL("len,fxch") + if (bufOut) + { + memcpy(bufOut+parm_size,GLUE_FXCH,sizeof(GLUE_FXCH)); + } + parm_size+=sizeof(GLUE_FXCH); + } +#endif + + if (!*canHaveDenormalOutput) + { + // if add_op or sub_op, and non-denormal input, safe to omit denormal checks + if (func == (void*)nseel_asm_add_op) + { + func = nseel_asm_add_op_fast; + func_e = nseel_asm_add_op_fast_end; + } + else if (func == (void*)nseel_asm_sub_op) + { + func = nseel_asm_sub_op_fast; + func_e = nseel_asm_sub_op_fast_end; + } + } + + + if (cfunc_abiinfo & (BIF_CLEARDENORMAL | BIF_RETURNSBOOL) ) *canHaveDenormalOutput=0; + else if (!(cfunc_abiinfo & BIF_WONTMAKEDENORMAL)) *canHaveDenormalOutput=1; + + { + int func_size=0; + func = GLUE_realAddress(func,func_e,&func_size); + if (!func) RET_MINUS1_FAIL("failrealladdrfunc") + + if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("funcsz") + + if (bufOut) + { + unsigned char *p=bufOut + parm_size; + memcpy(p, func, func_size); + if (preProc) p=preProc(p,func_size,ctx); + if (repl) + { + if (repl[0]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[0]); + if (repl[1]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[1]); + if (repl[2]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[2]); + if (repl[3]) p=EEL_GLUE_set_immediate(p,(INT_PTR)repl[3]); + } + } + + if (cfunc_abiinfo&BIF_RETURNSONSTACK) *rvMode = RETURNVALUE_FPSTACK; + else if (cfunc_abiinfo&BIF_RETURNSBOOL) *rvMode=RETURNVALUE_BOOL; + + return parm_size + func_size; + } + // end of builtin function generation +} + +static int compileEelFunctionCall(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, + int *rvMode, int *fpStackUse, int *canHaveDenormalOutput) +{ + int func_size=0, parm_size=0; + int pn; + int last_nt_parm=-1,last_nt_parm_mode=0; + void *func_e=NULL; + int n_params; + opcodeRec *parmptrs[NSEEL_MAX_EELFUNC_PARAMETERS]; + int cfp_numparams=-1; + int cfp_statesize=0; + EEL_F **cfp_ptrs=NULL; + int func_raw=0; + int do_parms; + int x; + + void *func; + + for (x=0; x < 3; x ++) parmptrs[x] = op->parms.parms[x]; + + if (op->opcodeType == OPCODETYPE_FUNCX) + { + n_params=0; + for (x=0;x<3;x++) + { + opcodeRec *prni=op->parms.parms[x]; + while (prni && n_params < NSEEL_MAX_EELFUNC_PARAMETERS) + { + const int isMP = prni->opcodeType == OPCODETYPE_MOREPARAMS; + parmptrs[n_params++] = isMP ? prni->parms.parms[0] : prni; + if (!isMP) break; + prni = prni->parms.parms[1]; + } + } + } + else + { + n_params = 1 + op->opcodeType - OPCODETYPE_FUNC1; + } + + *fpStackUse = 0; + func = nseel_getEELFunctionAddress(ctx, op, + &cfp_numparams,&cfp_statesize,&cfp_ptrs, + computTableSize, + &func_e, &func_raw, + !!bufOut,namespacePathToThis,rvMode,fpStackUse,canHaveDenormalOutput); + + if (func_raw) func_size = (char*)func_e - (char*)func; + else if (func) func = GLUE_realAddress(func,func_e,&func_size); + + if (!func) RET_MINUS1_FAIL("eelfuncaddr") + + *fpStackUse += 1; + + if (cfp_numparams>0 && n_params != cfp_numparams) + { + _codeHandleFunctionRec *fn = (_codeHandleFunctionRec*)op->fn; + snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"Function '%s' takes %d parameters, passed %d\n",fn->fname,cfp_numparams,n_params); + RET_MINUS1_FAIL("eelfuncnp") + } + + // user defined function + do_parms = cfp_numparams>0 && cfp_ptrs && cfp_statesize>0; + + // if function local/parameter state is zero, we need to allocate storage for it + if (cfp_statesize>0 && cfp_ptrs && !cfp_ptrs[0]) + { + EEL_F *pstate = newDataBlock(sizeof(EEL_F)*cfp_statesize,8); + if (!pstate) RET_MINUS1_FAIL("eelfuncdb") + + for (pn=0;pn= 0 && do_parms) + { + if (last_nt_parm_mode == RETURNVALUE_FPSTACK) + { + if (bufOut_len < parm_size + (int)sizeof(GLUE_POP_FPSTACK_TOSTACK)) RET_MINUS1_FAIL("eelfunc_size popfpstacktostack") + if (bufOut) memcpy(bufOut + parm_size,GLUE_POP_FPSTACK_TOSTACK,sizeof(GLUE_POP_FPSTACK_TOSTACK)); + parm_size+=sizeof(GLUE_POP_FPSTACK_TOSTACK); + } + else + { + if (bufOut_len < parm_size + (int)sizeof(GLUE_PUSH_P1PTR_AS_VALUE)) RET_MINUS1_FAIL("eelfunc_size pushp1ptrasval") + + // push + if (bufOut) memcpy(bufOut + parm_size,&GLUE_PUSH_P1PTR_AS_VALUE,sizeof(GLUE_PUSH_P1PTR_AS_VALUE)); + parm_size+=sizeof(GLUE_PUSH_P1PTR_AS_VALUE); + } + } + + last_nt_parm_mode=0; + lsz = compileOpcodes(ctx,parmptrs[pn],bufOut ? bufOut + parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, + do_parms ? (RETURNVALUE_FPSTACK|RETURNVALUE_NORMAL) : RETURNVALUE_IGNORE,&last_nt_parm_mode,&sUse, &needDenorm); + + // todo: if needDenorm, denorm convert when copying parameter + + if (lsz<0) RET_MINUS1_FAIL("eelfunc, coc fail") + + if (last_nt_parm_mode == RETURNVALUE_FPSTACK) sUse++; + if (sUse > *fpStackUse) *fpStackUse=sUse; + parm_size += lsz; + + last_nt_parm = pn; + } + // pop non-trivial results into place + if (last_nt_parm >=0 && do_parms) + { + while (--pn >= 0) + { + if (OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // skip and process after + if (pn == last_nt_parm) + { + if (last_nt_parm_mode == RETURNVALUE_FPSTACK) + { + // pop to memory directly + const int cpsize = GLUE_POP_FPSTACK_TO_PTR(NULL,NULL); + if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size popfpstacktoptr") + + if (bufOut) GLUE_POP_FPSTACK_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); + parm_size += cpsize; + } + else + { + // copy direct p1ptr to mem + const int cpsize = GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); + if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size copyvalueatp1toptr") + + if (bufOut) GLUE_COPY_VALUE_AT_P1_TO_PTR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); + parm_size += cpsize; + } + } + else + { + const int popsize = GLUE_POP_VALUE_TO_ADDR(NULL,NULL); + if (bufOut_len < parm_size + popsize) RET_MINUS1_FAIL("eelfunc size pop value to addr") + + if (bufOut) GLUE_POP_VALUE_TO_ADDR((unsigned char *)bufOut + parm_size,cfp_ptrs[pn]); + parm_size+=popsize; + + } + } + } + + // finally, set any trivial parameters + if (do_parms) + { + const int cpsize = GLUE_MOV_PX_DIRECTVALUE_SIZE + GLUE_COPY_VALUE_AT_P1_TO_PTR(NULL,NULL); + for (pn=0; pn < n_params; pn++) + { + if (!OPCODE_IS_TRIVIAL(parmptrs[pn])) continue; // set trivial values, we already set nontrivials + + if (bufOut_len < parm_size + cpsize) RET_MINUS1_FAIL("eelfunc size trivial set") + + if (bufOut) + { + if (generateValueToReg(ctx,parmptrs[pn],bufOut + parm_size,0,namespacePathToThis, 1)<0) RET_MINUS1_FAIL("eelfunc gvr fail") + GLUE_COPY_VALUE_AT_P1_TO_PTR(bufOut + parm_size + GLUE_MOV_PX_DIRECTVALUE_SIZE,cfp_ptrs[pn]); + } + parm_size += cpsize; + + } + } + + if (bufOut_len < parm_size + func_size) RET_MINUS1_FAIL("eelfunc size combined") + + if (bufOut) memcpy(bufOut + parm_size, func, func_size); + + return parm_size + func_size; + // end of EEL function generation +} + +#ifdef DUMP_OPS_DURING_COMPILE +void dumpOp(compileContext *ctx, opcodeRec *op, int start); +#endif + +#ifdef GLUE_MAX_JMPSIZE +#define CHECK_SIZE_FORJMP(x,y) if ((x)<0 || (x)>=GLUE_MAX_JMPSIZE) goto y; +#define RET_MINUS1_FAIL_FALLBACK(err,j) goto j; +#else +#define CHECK_SIZE_FORJMP(x,y) +#define RET_MINUS1_FAIL_FALLBACK(err,j) RET_MINUS1_FAIL(err) +#endif +static int compileOpcodesInternal(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, int *calledRvType, int preferredReturnValues, int *fpStackUse, int *canHaveDenormalOutput) +{ + int rv_offset=0; + if (!op) RET_MINUS1_FAIL("coi !op") + + *fpStackUse=0; + // special case: statement delimiting means we can process the left side into place, and iteratively do the second parameter without recursing + // also we don't need to save/restore anything to the stack (which the normal 2 parameter function processing does) + while (op->opcodeType == OPCODETYPE_FUNC2 && op->fntype == FN_JOIN_STATEMENTS) + { + int fUse; + int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL,&fUse,NULL); + if (parm_size < 0) RET_MINUS1_FAIL("coc join fail") + op = op->parms.parms[1]; + if (!op) RET_MINUS1_FAIL("join got to null") + + if (fUse>*fpStackUse) *fpStackUse=fUse; + if (bufOut) bufOut += parm_size; + bufOut_len -= parm_size; + rv_offset += parm_size; +#ifdef DUMP_OPS_DURING_COMPILE + if (op->opcodeType != OPCODETYPE_FUNC2 || op->fntype != FN_JOIN_STATEMENTS) dumpOp(ctx,op,0); +#endif + } + + if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) + { + // special case: while + functionType *fn_ptr = (functionType *)op->fn; + if (op->opcodeType == OPCODETYPE_FUNC1 && fn_ptr == fnTable1 + 4) + { + *calledRvType = RETURNVALUE_BOOL; + +#ifndef GLUE_INLINE_LOOPS + // todo: PPC looping support when loop length is small enough + { + unsigned char *pwr=bufOut; + unsigned char *newblock2; + int stubsz; + void *stubfunc = GLUE_realAddress(nseel_asm_repeatwhile,nseel_asm_repeatwhile_end,&stubsz); + if (!stubfunc || bufOut_len < stubsz) RET_MINUS1_FAIL(stubfunc ? "repeatwhile size fail" :"repeatwhile addr fail") + + if (bufOut) + { + newblock2=compileCodeBlockWithRet(ctx,op->parms.parms[0],computTableSize,namespacePathToThis, RETURNVALUE_BOOL, NULL, fpStackUse, NULL); + if (!newblock2) RET_MINUS1_FAIL("repeatwhile ccbwr fail") + + memcpy(pwr,stubfunc,stubsz); + pwr=EEL_GLUE_set_immediate(pwr,(INT_PTR)newblock2); + } + + return rv_offset+stubsz; + } +#else + { + unsigned char *looppt, *jzoutpt; + int parm_size=0,subsz; + if (bufOut_len < parm_size + sizeof(GLUE_WHILE_SETUP) + sizeof(GLUE_WHILE_BEGIN)) RET_MINUS1_FAIL("while size fail 1") + if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_SETUP,sizeof(GLUE_WHILE_SETUP)); + parm_size+=sizeof(GLUE_WHILE_SETUP); + looppt = bufOut + parm_size; + if (bufOut) memcpy(bufOut + parm_size,GLUE_WHILE_BEGIN,sizeof(GLUE_WHILE_BEGIN)); + parm_size+=sizeof(GLUE_WHILE_BEGIN); + + subsz = compileOpcodes(ctx,op->parms.parms[0],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL,fpStackUse, NULL); + if (subsz<0) RET_MINUS1_FAIL("while coc fail") + + if (bufOut_len < parm_size + sizeof(GLUE_WHILE_END) + sizeof(GLUE_WHILE_CHECK_RV)) RET_MINUS1_FAIL("which size fial 2") + + parm_size+=subsz; + if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_END, sizeof(GLUE_WHILE_END)); + parm_size+=sizeof(GLUE_WHILE_END); + jzoutpt = bufOut + parm_size; + + if (bufOut) memcpy(bufOut + parm_size, GLUE_WHILE_CHECK_RV, sizeof(GLUE_WHILE_CHECK_RV)); + parm_size+=sizeof(GLUE_WHILE_CHECK_RV); + if (bufOut) + { + GLUE_JMP_SET_OFFSET(bufOut + parm_size,(looppt - (bufOut+parm_size)) ); + GLUE_JMP_SET_OFFSET(jzoutpt, (bufOut + parm_size) - jzoutpt); + } + return rv_offset+parm_size; + } + +#endif + } + + // special case: loop + if (op->opcodeType == OPCODETYPE_FUNC2 && fn_ptr == fnTable1+3) + { + int fUse; + int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_FPSTACK, NULL,&fUse, NULL); + if (parm_size < 0) RET_MINUS1_FAIL("loop coc fail") + + *calledRvType = RETURNVALUE_BOOL; + if (fUse > *fpStackUse) *fpStackUse=fUse; + +#ifndef GLUE_INLINE_LOOPS + // todo: PPC looping support when loop length is small enough + { + void *stub; + int stubsize; + unsigned char *newblock2, *p; + stub = GLUE_realAddress(nseel_asm_repeat,nseel_asm_repeat_end,&stubsize); + if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("loop size fail") + if (bufOut) + { + newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, RETURNVALUE_IGNORE, NULL,fpStackUse, NULL); + + p = bufOut + parm_size; + memcpy(p, stub, stubsize); + + p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); + } + return rv_offset + parm_size + stubsize; + } +#else + { + int subsz; + int fUse=0; + unsigned char *skipptr1,*loopdest; + if (bufOut_len < parm_size + sizeof(GLUE_LOOP_LOADCNT) + sizeof(GLUE_LOOP_CLAMPCNT) + sizeof(GLUE_LOOP_BEGIN)) RET_MINUS1_FAIL("loop size fail") + + // store, convert to int, compare against 1, if less than, skip to end + if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_LOADCNT,sizeof(GLUE_LOOP_LOADCNT)); + parm_size += sizeof(GLUE_LOOP_LOADCNT); + skipptr1 = bufOut+parm_size; + + // compare aginst max loop length, jump to loop start if not above it + if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_CLAMPCNT,sizeof(GLUE_LOOP_CLAMPCNT)); + parm_size += sizeof(GLUE_LOOP_CLAMPCNT); + + // loop code: + loopdest = bufOut + parm_size; + if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_BEGIN,sizeof(GLUE_LOOP_BEGIN)); + parm_size += sizeof(GLUE_LOOP_BEGIN); + + subsz = compileOpcodes(ctx,op->parms.parms[1],bufOut ? (bufOut + parm_size) : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, RETURNVALUE_IGNORE, NULL, &fUse, NULL); + if (subsz<0) RET_MINUS1_FAIL("loop coc fail") + if (fUse > *fpStackUse) *fpStackUse=fUse; + + parm_size += subsz; + + if (bufOut_len < parm_size + sizeof(GLUE_LOOP_END)) RET_MINUS1_FAIL("loop size fail 2") + + if (bufOut) memcpy(bufOut+parm_size,GLUE_LOOP_END,sizeof(GLUE_LOOP_END)); + parm_size += sizeof(GLUE_LOOP_END); + + if (bufOut) + { + GLUE_JMP_SET_OFFSET(bufOut + parm_size,loopdest - (bufOut+parm_size)); + GLUE_JMP_SET_OFFSET(skipptr1, (bufOut+parm_size) - skipptr1); + } + + return rv_offset + parm_size; + + } +#endif + } + + // special case: BAND/BOR + if (op->opcodeType == OPCODETYPE_FUNC2 && (fn_ptr == fnTable1+1 || fn_ptr == fnTable1+2)) + { + int fUse=0; + int parm_size,parm_size_pre; + int retType=RETURNVALUE_IGNORE; + if (preferredReturnValues != RETURNVALUE_IGNORE) retType = RETURNVALUE_BOOL; + + *calledRvType = retType; + + parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL, &fUse, NULL); + if (parm_size < 0) RET_MINUS1_FAIL("loop band/bor coc fail") + + if (fUse > *fpStackUse) *fpStackUse=fUse; + + + parm_size_pre=parm_size; + + { + int sz2, fUse=0; + unsigned char *destbuf; + const int testsz=(fn_ptr == fnTable1+2) ? sizeof(GLUE_JMP_IF_P1_NZ) : sizeof(GLUE_JMP_IF_P1_Z); + if (bufOut_len < parm_size+testsz) RET_MINUS1_FAIL_FALLBACK("band/bor size fail",doNonInlinedAndOr_) + + if (bufOut) memcpy(bufOut+parm_size,(fn_ptr == fnTable1+2) ? GLUE_JMP_IF_P1_NZ : GLUE_JMP_IF_P1_Z,testsz); + parm_size += testsz; + destbuf = bufOut + parm_size; + + sz2= compileOpcodes(ctx,op->parms.parms[1],bufOut?bufOut+parm_size:NULL,bufOut_len-parm_size, computTableSize, namespacePathToThis, retType, NULL,&fUse, NULL); + + CHECK_SIZE_FORJMP(sz2,doNonInlinedAndOr_) + if (sz2<0) RET_MINUS1_FAIL("band/bor coc fail") + + parm_size+=sz2; + if (bufOut) GLUE_JMP_SET_OFFSET(destbuf, (bufOut + parm_size) - destbuf); + + if (fUse > *fpStackUse) *fpStackUse=fUse; + return rv_offset + parm_size; + } +#ifdef GLUE_MAX_JMPSIZE + if (0) + { + void *stub; + int stubsize; + unsigned char *newblock2, *p; + + // encode as function call +doNonInlinedAndOr_: + parm_size = parm_size_pre; + + if (fn_ptr == fnTable1+1) + { + stub = GLUE_realAddress(nseel_asm_band,nseel_asm_band_end,&stubsize); + } + else + { + stub = GLUE_realAddress(nseel_asm_bor,nseel_asm_bor_end,&stubsize); + } + + if (bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL("band/bor len fail") + + if (bufOut) + { + fUse=0; + newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, retType, NULL, &fUse, NULL); + if (!newblock2) RET_MINUS1_FAIL("band/bor ccbwr fail") + + if (fUse > *fpStackUse) *fpStackUse=fUse; + + p = bufOut + parm_size; + memcpy(p, stub, stubsize); + + p=EEL_GLUE_set_immediate(p,(INT_PTR)newblock2); + } + return rv_offset + parm_size + stubsize; + } +#endif + } + + if (op->opcodeType == OPCODETYPE_FUNC3 && fn_ptr == fnTable1 + 0) // special case: IF + { + int fUse=0; + int parm_size_pre; + int use_rv = RETURNVALUE_IGNORE; + int parm_size = compileOpcodes(ctx,op->parms.parms[0],bufOut,bufOut_len, computTableSize, namespacePathToThis, RETURNVALUE_BOOL, NULL,&fUse, NULL); + if (parm_size < 0) RET_MINUS1_FAIL("if coc fail") + if (fUse > *fpStackUse) *fpStackUse=fUse; + + if (preferredReturnValues & RETURNVALUE_NORMAL) use_rv=RETURNVALUE_NORMAL; + else if (preferredReturnValues & RETURNVALUE_FPSTACK) use_rv=RETURNVALUE_FPSTACK; + else if (preferredReturnValues & RETURNVALUE_BOOL) use_rv=RETURNVALUE_BOOL; + + *calledRvType = use_rv; + parm_size_pre = parm_size; + + { + int csz,hasSecondHalf; + if (bufOut_len < parm_size + sizeof(GLUE_JMP_IF_P1_Z)) RET_MINUS1_FAIL_FALLBACK("if size fail",doNonInlineIf_) + if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_IF_P1_Z,sizeof(GLUE_JMP_IF_P1_Z)); + parm_size += sizeof(GLUE_JMP_IF_P1_Z); + csz=compileOpcodes(ctx,op->parms.parms[1],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); + if (fUse > *fpStackUse) *fpStackUse=fUse; + hasSecondHalf = preferredReturnValues || !OPCODE_IS_TRIVIAL(op->parms.parms[2]); + + CHECK_SIZE_FORJMP(csz,doNonInlineIf_) + if (csz<0) RET_MINUS1_FAIL("if coc fial") + + if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size, csz + (hasSecondHalf?sizeof(GLUE_JMP_NC):0)); + parm_size+=csz; + + if (hasSecondHalf) + { + if (bufOut_len < parm_size + sizeof(GLUE_JMP_NC)) RET_MINUS1_FAIL_FALLBACK("if len fail",doNonInlineIf_) + if (bufOut) memcpy(bufOut+parm_size,GLUE_JMP_NC,sizeof(GLUE_JMP_NC)); + parm_size+=sizeof(GLUE_JMP_NC); + + csz=compileOpcodes(ctx,op->parms.parms[2],bufOut ? bufOut+parm_size : NULL,bufOut_len - parm_size, computTableSize, namespacePathToThis, use_rv, NULL, &fUse, canHaveDenormalOutput); + + CHECK_SIZE_FORJMP(csz,doNonInlineIf_) + if (csz<0) RET_MINUS1_FAIL("if coc 2 fail") + + // update jump address + if (bufOut) GLUE_JMP_SET_OFFSET(bufOut + parm_size,csz); + parm_size+=csz; + if (fUse > *fpStackUse) *fpStackUse=fUse; + } + return rv_offset + parm_size; + } +#ifdef GLUE_MAX_JMPSIZE + if (0) + { + unsigned char *newblock2,*newblock3,*ptr; + void *stub; + int stubsize; +doNonInlineIf_: + parm_size = parm_size_pre; + stub = GLUE_realAddress(nseel_asm_if,nseel_asm_if_end,&stubsize); + + if (!stub || bufOut_len < parm_size + stubsize) RET_MINUS1_FAIL(stub ? "if sz fail" : "if addr fail") + + if (bufOut) + { + fUse=0; + newblock2 = compileCodeBlockWithRet(ctx,op->parms.parms[1],computTableSize,namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); + if (fUse > *fpStackUse) *fpStackUse=fUse; + newblock3 = compileCodeBlockWithRet(ctx,op->parms.parms[2],computTableSize,namespacePathToThis, use_rv, NULL,&fUse, canHaveDenormalOutput); + if (fUse > *fpStackUse) *fpStackUse=fUse; + if (!newblock2 || !newblock3) RET_MINUS1_FAIL("if subblock gen fail") + + ptr = bufOut + parm_size; + memcpy(ptr, stub, stubsize); + + ptr=EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock2); + EEL_GLUE_set_immediate(ptr,(INT_PTR)newblock3); + } + return rv_offset + parm_size + stubsize; + } +#endif + } + } + + switch (op->opcodeType) + { + case OPCODETYPE_DIRECTVALUE: + if (preferredReturnValues == RETURNVALUE_BOOL) + { + int w = fabs(op->parms.dv.directValue) >= NSEEL_CLOSEFACTOR; + int wsz=(w?sizeof(GLUE_SET_P1_NZ):sizeof(GLUE_SET_P1_Z)); + + *calledRvType = RETURNVALUE_BOOL; + if (bufOut_len < wsz) RET_MINUS1_FAIL("direct bool size fail3") + if (bufOut) memcpy(bufOut,w?GLUE_SET_P1_NZ:GLUE_SET_P1_Z,wsz); + return rv_offset+wsz; + } + else if (preferredReturnValues & RETURNVALUE_FPSTACK) + { +#ifdef GLUE_HAS_FLDZ + if (op->parms.dv.directValue == 0.0) + { + *fpStackUse = 1; + *calledRvType = RETURNVALUE_FPSTACK; + if (bufOut_len < sizeof(GLUE_FLDZ)) RET_MINUS1_FAIL("direct fp fail 1") + if (bufOut) memcpy(bufOut,GLUE_FLDZ,sizeof(GLUE_FLDZ)); + return rv_offset+sizeof(GLUE_FLDZ); + } +#endif +#ifdef GLUE_HAS_FLD1 + if (op->parms.dv.directValue == 1.0) + { + *fpStackUse = 1; + *calledRvType = RETURNVALUE_FPSTACK; + if (bufOut_len < sizeof(GLUE_FLD1)) RET_MINUS1_FAIL("direct fp fail 1") + if (bufOut) memcpy(bufOut,GLUE_FLD1,sizeof(GLUE_FLD1)); + return rv_offset+sizeof(GLUE_FLD1); + } +#endif + } + // fall through + + case OPCODETYPE_VALUE_FROM_NAMESPACENAME: + case OPCODETYPE_VARPTR: + case OPCODETYPE_VARPTRPTR: + + + #ifdef GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE + if (OPCODE_IS_TRIVIAL(op)) + { + if (preferredReturnValues & RETURNVALUE_FPSTACK) + { + *fpStackUse = 1; + if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE) RET_MINUS1_FAIL("direct fp fail 2") + if (bufOut) + { + if (generateValueToReg(ctx,op,bufOut,-1,namespacePathToThis, 1 /*allow caching*/)<0) RET_MINUS1_FAIL("direct fp fail gvr") + } + *calledRvType = RETURNVALUE_FPSTACK; + return rv_offset+GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE; + } + } + #endif + + if (bufOut_len < GLUE_MOV_PX_DIRECTVALUE_SIZE) + { + RET_MINUS1_FAIL("direct value fail 1") + } + if (bufOut) + { + if (generateValueToReg(ctx,op,bufOut,0,namespacePathToThis, !!(preferredReturnValues&RETURNVALUE_FPSTACK)/*cache if going to the fp stack*/)<0) RET_MINUS1_FAIL("direct value gvr fail3") + } + return rv_offset + GLUE_MOV_PX_DIRECTVALUE_SIZE; + + case OPCODETYPE_FUNCX: + case OPCODETYPE_FUNC1: + case OPCODETYPE_FUNC2: + case OPCODETYPE_FUNC3: + + if (op->fntype == FUNCTYPE_EELFUNC_THIS || op->fntype == FUNCTYPE_EELFUNC) + { + int a; + + a = compileEelFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,canHaveDenormalOutput); + if (a<0) return a; + rv_offset += a; + } + else + { + int a; + a = compileNativeFunctionCall(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis, calledRvType,fpStackUse,preferredReturnValues,canHaveDenormalOutput); + if (a<0)return a; + rv_offset += a; + } + return rv_offset; + } + + RET_MINUS1_FAIL("default opcode fail") +} + +#ifdef DUMP_OPS_DURING_COMPILE +FILE *g_debugfp; +int g_debugfp_indent; +int g_debugfp_histsz=0; + +void dumpOp(compileContext *ctx, opcodeRec *op, int start) +{ + if (start>=0) + { + if (g_debugfp) + { + static opcodeRec **hist; + + int x; + int hit=0; + if (!hist) hist = (opcodeRec**) calloc(1024,1024*sizeof(opcodeRec*)); + for(x=0;x=100) *(char *)1=0; + fprintf(g_debugfp,"%*s{ %p : %d%s: ",g_debugfp_indent," ",op,op->opcodeType, hit ? " -- DUPLICATE" : ""); + switch (op->opcodeType) + { + case OPCODETYPE_DIRECTVALUE: + fprintf(g_debugfp,"dv %f",op->parms.dv.directValue); + break; + case OPCODETYPE_VARPTR: + { + int wb; + for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + char **plist=ctx->varTable_Names[wb]; + if (!plist) break; + + if (op->parms.dv.valuePtr >= ctx->varTable_Values[wb] && op->parms.dv.valuePtr < ctx->varTable_Values[wb] + NSEEL_VARS_PER_BLOCK) + { + fprintf(g_debugfp,"var %s",plist[op->parms.dv.valuePtr - ctx->varTable_Values[wb]]); + break; + } + } + } + break; + case OPCODETYPE_FUNC1: + case OPCODETYPE_FUNC2: + case OPCODETYPE_FUNC3: + case OPCODETYPE_FUNCX: + if (op->fntype == FUNCTYPE_FUNCTIONTYPEREC) + { + functionType *p=(functionType*)op->fn; + fprintf(g_debugfp,"func %d: %s",p->nParams&0xff,p->name); + } + else + fprintf(g_debugfp,"sf %d",op->fntype); + break; + + } + fprintf(g_debugfp,"\n"); + g_debugfp_indent+=2; + } + } + else + { + if (g_debugfp) + { + g_debugfp_indent-=2; + fprintf(g_debugfp,"%*s}%p\n",g_debugfp_indent," ",op); + } + } +} +#endif + +int compileOpcodes(compileContext *ctx, opcodeRec *op, unsigned char *bufOut, int bufOut_len, int *computTableSize, const char *namespacePathToThis, + int supportedReturnValues, int *rvType, int *fpStackUse, int *canHaveDenormalOutput) +{ + int code_returns=RETURNVALUE_NORMAL; + int fpsu=0; + int codesz; + int denorm=0; + +#ifdef DUMP_OPS_DURING_COMPILE + dumpOp(ctx,op,1); +#endif + + codesz = compileOpcodesInternal(ctx,op,bufOut,bufOut_len,computTableSize,namespacePathToThis,&code_returns, supportedReturnValues,&fpsu,&denorm); + if (denorm && canHaveDenormalOutput) *canHaveDenormalOutput=1; + +#ifdef DUMP_OPS_DURING_COMPILE + dumpOp(ctx,op,-1); +#endif + + if (codesz < 0) return codesz; + + + /* + { + char buf[512]; + sprintf(buf,"opcode %d %d (%s): fpu use: %d\n",op->opcodeType,op->fntype, + op->opcodeType >= OPCODETYPE_FUNC1 && op->fntype == FUNCTYPE_FUNCTIONTYPEREC ? ( + ((functionType *)op->fn)->name + ) : "", + fpsu); + OutputDebugString(buf); + } + */ + + if (fpStackUse) *fpStackUse=fpsu; + + if (bufOut) bufOut += codesz; + bufOut_len -= codesz; + + + if (code_returns == RETURNVALUE_BOOL && !(supportedReturnValues & RETURNVALUE_BOOL) && supportedReturnValues) + { + int stubsize; + void *stub = GLUE_realAddress(nseel_asm_booltofp,nseel_asm_booltofp_end,&stubsize); + if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"booltofp size":"booltfp addr") + if (bufOut) + { + unsigned char *p=bufOut; + memcpy(bufOut,stub,stubsize); + bufOut += stubsize; + } + codesz+=stubsize; + bufOut_len -= stubsize; + + code_returns = RETURNVALUE_FPSTACK; + } + + + // default processing of code_returns to meet return value requirements + if (supportedReturnValues & code_returns) + { + if (rvType) *rvType = code_returns; + return codesz; + } + + + if (rvType) *rvType = RETURNVALUE_IGNORE; + + + if (code_returns == RETURNVALUE_NORMAL) + { + if (supportedReturnValues & (RETURNVALUE_FPSTACK|RETURNVALUE_BOOL)) + { + if (bufOut_len < GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE) RET_MINUS1_FAIL("pushvalatpxtofpstack,size") + if (bufOut) + { + GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(bufOut,0); // always fld qword [eax] but we might change that later + bufOut += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; + } + codesz += GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; + bufOut_len -= GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE; + + if (supportedReturnValues & RETURNVALUE_BOOL) + { + code_returns = RETURNVALUE_FPSTACK; + } + else + { + if (rvType) *rvType = RETURNVALUE_FPSTACK; + } + } + } + + if (code_returns == RETURNVALUE_FPSTACK) + { + if (supportedReturnValues & RETURNVALUE_BOOL) + { + int stubsize; + void *stub = GLUE_realAddress(nseel_asm_fptobool,nseel_asm_fptobool_end,&stubsize); + if (!stub || bufOut_len < stubsize) RET_MINUS1_FAIL(stub?"fptobool size":"fptobool addr") + if (bufOut) + { + memcpy(bufOut,stub,stubsize); + bufOut += stubsize; + } + codesz+=stubsize; + bufOut_len -= stubsize; + + if (rvType) *rvType = RETURNVALUE_BOOL; + } + else if (supportedReturnValues & RETURNVALUE_NORMAL) + { + if (computTableSize) (*computTableSize) ++; + + if (bufOut_len < GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE) RET_MINUS1_FAIL("popfpstacktowtptopxsize") + + // generate fp-pop to temp space + if (bufOut) GLUE_POP_FPSTACK_TO_WTP_TO_PX(bufOut,0); + codesz+=GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE; + if (rvType) *rvType = RETURNVALUE_NORMAL; + } + else + { + // toss return value that will be ignored + if (bufOut_len < GLUE_POP_FPSTACK_SIZE) RET_MINUS1_FAIL("popfpstack size") + if (bufOut) memcpy(bufOut,GLUE_POP_FPSTACK,GLUE_POP_FPSTACK_SIZE); + codesz+=GLUE_POP_FPSTACK_SIZE; + } + } + + return codesz; +} + + + + +static char *preprocessCode(compileContext *ctx, char *expression, int src_offset_bytes, int dest_offset_bytes) +{ + char *expression_start=expression; + int len=0; + int alloc_len=strlen(expression)+1+64; + char *buf=(char *)malloc(alloc_len); + int semicnt=0; + // we need to call onCompileNewLine for each new line we get + + //onCompileNewLine(ctx, + + while (*expression) + { + if (len > alloc_len-64) + { + alloc_len = len+128; + buf=(char*)realloc(buf,alloc_len); + } + + if (expression[0] == '/') + { + if (expression[1] == '/') + { + expression+=2; + if (!strncasecmp(expression,"#eel-no-optimize:",17)) + { + ctx->optimizeDisableFlags = atoi(expression+17); + } + + while (expression[0] && expression[0] != '\n') expression++; + continue; + } + else if (expression[1] == '*') + { + expression+=2; + while (expression[0] && (expression[0] != '*' || expression[1] != '/')) + { + if (expression[0] == '\n') onCompileNewLine(ctx,expression+1-expression_start + src_offset_bytes,dest_offset_bytes+len); + expression++; + } + if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/ + continue; + } + } + + if (expression[0] == '(' && expression[1]==')') + { + expression+=2; + memcpy(buf+len,"(0)",3); + len+=3; + ctx->l_stats[0]+=3; + continue; + } + if (expression[0] == '$') + { + if (toupper(expression[1]) == 'X'||expression[1] == '~') + { + char isBits = expression[1] == '~'; + char *p=expression+2; + unsigned int v=strtoul(expression+2,&p,isBits ? 10 : 16); + char tmp[256]; + expression=p; + + if (isBits) + { + if (v>53) v=53; + sprintf(tmp,"%.1f",(double) ((((WDL_INT64)1) << v) - 1)); + } + else + { + sprintf(tmp,"%u",v); + } + memcpy(buf+len,tmp,strlen(tmp)); + len+=strlen(tmp); + ctx->l_stats[0]+=strlen(tmp); + continue; + + } + if (expression[1]=='\'' && expression[2] && expression[3]=='\'') + { + char tmp[64]; + sprintf(tmp,"%u",((unsigned char *)expression)[2]); + expression+=4; + + memcpy(buf+len,tmp,strlen(tmp)); + len+=strlen(tmp); + ctx->l_stats[0]+=strlen(tmp); + continue; + } + if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I') + { + static char *str="3.141592653589793"; + expression+=3; + memcpy(buf+len,str,17); + len+=17; //strlen(str); + ctx->l_stats[0]+=17; + continue; + } + if (toupper(expression[1]) == 'E') + { + static char *str="2.71828183"; + expression+=2; + memcpy(buf+len,str,10); + len+=10; //strlen(str); + ctx->l_stats[0]+=10; + continue; + } + if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I') + { + static char *str="1.61803399"; + expression+=4; + memcpy(buf+len,str,10); + len+=10; //strlen(str); + ctx->l_stats[0]+=10; + continue; + } + + } + + { + char c=*expression++; + + if (c == '\n') onCompileNewLine(ctx,expression-expression_start + src_offset_bytes,len + dest_offset_bytes); + if (isspace(c)) c=' '; + + if (c == '(') semicnt++; + else if (c == ')') { semicnt--; if (semicnt < 0) semicnt=0; } + else if (c == ';' && semicnt > 0) + { + // convert ; to % if next nonwhitespace char is alnum, otherwise convert to space + int p=0; + int nc; + int commentstate=0; + while ((nc=expression[p])) + { + if (!commentstate && nc == '/') + { + if (expression[p+1] == '/') commentstate=1; + else if (expression[p+1] == '*') commentstate=2; + } + + if (commentstate == 1 && nc == '\n') commentstate=0; + else if (commentstate == 2 && nc == '*' && expression[p+1]=='/') + { + p++; // skip * + commentstate=0; + } + else if (!commentstate && !isspace(nc)) break; + + p++; + } + // fucko, we should look for even more chars, me thinks + if (nc && (isalnum(nc) +#if 1 + || nc == '(' || nc == '_' || nc == '!' || nc == '$' || nc == '-' || nc == '+' /* unary +, -, !, symbols, etc, mean new statement */ +#endif + )) c='%'; + else c = ' '; // stray ; + } +#if 0 + else if (semicnt > 0 && c == ',') + { + int p=0; + int nc; + while ((nc=expression[p]) && isspace(nc)) p++; + if (nc == ',' || nc == ')') + { + expression += p+1; + buf[len++]=','; + buf[len++]='0'; + c=nc; // append this char + } + } +#endif + // list of operators + + else if (!isspace(c) && !isalnum(c)) // check to see if this operator is ours + { + + static char *symbollists[]= + { + "", // stop at any control char that is not parenthed + ":(,;?%", + ",):?;", // or || or && + ",);", // jf> removed :? from this, for = + ",);", + "", // rscan=5, only scans for a negative ] level + "", // rscan=6, like rscan==0 but lower precedence -- stop at any non-^ control char that is not parenthed + }; + + + static const struct + { + char op[2]; + char lscan,rscan; + char *func; + } preprocSymbols[] = + { + {{'+','='}, 0, 3, "_addop" }, + {{'-','='}, 0, 3, "_subop" }, + {{'%','='}, 0, 3, "_modop" }, + {{'|','='}, 0, 3, "_orop" }, + {{'&','='}, 0, 3, "_andop"}, + {{'~','='}, 0, 3, "_xorop" }, + + {{'/','='}, 0, 3, "_divop"}, + {{'*','='}, 0, 3, "_mulop"}, + {{'^','='}, 0, 3, "_powop"}, + + {{'=','='}, 1, 2, "_equal" }, + {{'<','='}, 1, 2, "_beleq" }, + {{'>','='}, 1, 2, "_aboeq" }, + {{'<','<'}, 0, 6, "_shl" }, + {{'>','>'}, 0, 6, "_shr" }, + {{'<',0 }, 1, 2, "_below" }, + {{'>',0 }, 1, 2, "_above" }, + {{'!','='}, 1, 2, "_noteq" }, + {{'|','|'}, 1, 2, "_or" }, + {{'&','&'}, 1, 2, "_and" }, + {{'=',0 }, 0, 3, "_set" }, + {{'~',0}, 0, 6, "_xor" }, + {{'%',0}, 0, 6, "_mod" }, + {{'^',0}, 0, 0, "pow" }, + + + {{'[',0 }, 0, 5, }, + {{'!',0 },-1, 0, }, // this should also ignore any leading +- + {{'?',0 }, 1, 4, }, + + }; + + + int n; + int ns=sizeof(preprocSymbols)/sizeof(preprocSymbols[0]); + for (n = 0; n < ns; n++) + { + if (c == preprocSymbols[n].op[0] && (!preprocSymbols[n].op[1] || expression[0] == preprocSymbols[n].op[1])) + { + break; + } + } + if (n < ns) + { + + int lscan=preprocSymbols[n].lscan; + int rscan=preprocSymbols[n].rscan; + + // parse left side of =, scanning back for an unparenthed nonwhitespace nonalphanumeric nonparenth? + // so megabuf(x+y)= would be fine, x=, but +x= would do +set(x,) + char *l_ptr=0; + char *r_ptr=0; + if (lscan >= 0) + { + char *scan=symbollists[lscan]; + int l_semicnt=0; + l_ptr=buf + len - 1; + while (l_ptr >= buf) + { + if (*l_ptr == ')') l_semicnt++; + else if (*l_ptr == '(') + { + l_semicnt--; + if (l_semicnt < 0) break; + } + else if (!l_semicnt) + { + if (!*scan) + { + if (!isspace(*l_ptr) && !isalnum(*l_ptr) && *l_ptr != '_' && *l_ptr != '.') break; + } + else + { + char *sc=scan; + if (lscan == 2 && ( // not currently used, even + (l_ptr[0]=='|' && l_ptr[1] == '|')|| + (l_ptr[0]=='&' && l_ptr[1] == '&') + ) + ) break; + while (*sc && *l_ptr != *sc) sc++; + if (*sc) break; + } + } + l_ptr--; + } + buf[len]=0; + + l_ptr++; + + len = l_ptr - buf; + + l_ptr = strdup(l_ptr); // doesn't need to be preprocessed since it just was + } + if (preprocSymbols[n].op[1]) expression++; + + r_ptr=expression; + { + // scan forward to an uncommented, unparenthed semicolon, comma, or ), or ] + int r_semicnt=0,r_semicnt2=0; + int r_qcnt=0; + char *scan=symbollists[rscan]; + int commentstate=0; + int hashadch=0; + while (*r_ptr) + { + if (!commentstate && *r_ptr == '/') + { + if (r_ptr[1] == '/') commentstate=1; + else if (r_ptr[1] == '*') commentstate=2; + } + if (commentstate == 1 && *r_ptr == '\n') commentstate=0; + else if (commentstate == 2 && *r_ptr == '*' && r_ptr[1]=='/') + { + r_ptr++; // skip * + commentstate=0; + } + else if (!commentstate) + { + if (*r_ptr == '(') { hashadch=1; r_semicnt++; } + else if (*r_ptr == '[') { hashadch=1; r_semicnt2++; } + else if (*r_ptr == ')') + { + r_semicnt--; + if (r_semicnt < 0 && r_semicnt2<=0) break; + } + else if (*r_ptr == ']') + { + r_semicnt2--; + if (r_semicnt2 < 0 && r_semicnt<=0) break; + } + else if (!r_semicnt && !r_semicnt2) + { + char *sc=scan; + if (*r_ptr == ';' || *r_ptr == ',') break; + + if (!rscan || rscan == 6) + { + if (*r_ptr == ':') break; + if (!isspace(*r_ptr) && !isalnum(*r_ptr) && *r_ptr != '_' && *r_ptr != '.' && + (rscan != 6 || *r_ptr != '^' || r_ptr[1] == '=') && hashadch) break; + if (isalnum(*r_ptr) || *r_ptr == '_')hashadch=1; + } + else if (rscan == 2 && + ((r_ptr[0]=='|' && r_ptr[1] == '|')|| + (r_ptr[0]=='&' && r_ptr[1] == '&') + ) + ) break; + + else if (rscan == 3 || rscan == 4) + { + if (*r_ptr == ':') r_qcnt--; + else if (*r_ptr == '?') r_qcnt++; + + if (r_qcnt < 3-rscan) break; + } + + while (*sc && *r_ptr != *sc) sc++; + if (*sc) break; + } + } + r_ptr++; + } + // expression -> r_ptr is our string (not including r_ptr) + + { + char *orp=r_ptr; + + char rps=*orp; + *orp=0; // temporarily terminate + + r_ptr=preprocessCode(ctx,expression,src_offset_bytes + (expression-expression_start),dest_offset_bytes + len); + expression=orp; + + *orp = rps; // fix termination(restore string) + } + + } + + if (r_ptr) + { + int thisl = strlen(l_ptr?l_ptr:"") + strlen(r_ptr) + 32; + + if (len+thisl > alloc_len-64) + { + alloc_len = len+thisl+128; + buf=(char*)realloc(buf,alloc_len); + } + + + if (n == ns-3) + { + char *lp = l_ptr; + char *rp = r_ptr; + while (lp && *lp && isspace(*lp)) lp++; + while (rp && *rp && isspace(*rp)) rp++; + if (lp && !strncasecmp(lp,"gmem",4) && (!lp[4] || isspace(lp[4]))) + { + len+=sprintf(buf+len,"_gmem(%s",r_ptr && *r_ptr ? r_ptr : "0"); + ctx->l_stats[0]+=strlen(l_ptr)+4; + } + else if (rp && *rp && strcmp(rp,"0")) + { + len+=sprintf(buf+len,"_mem((%s)+(%s)",lp,rp); + ctx->l_stats[0]+=strlen(lp)+strlen(rp)+8; + } + else + { + len+=sprintf(buf+len,"_mem(%s",lp); + ctx->l_stats[0]+=strlen(lp)+4; + } + + // skip the ] + if (*expression == ']') expression++; + + } + else if (n == ns-2) + { + len+=sprintf(buf+len,"_not(%s",r_ptr); + + ctx->l_stats[0]+=4; + } + else if (n == ns-1)// if (l_ptr,r_ptr1,r_ptr2) + { + char *rptr2=r_ptr; + char *tmp=r_ptr; + int parcnt=0; + int qcnt=1; + while (*rptr2) + { + if (*rptr2 == '?') qcnt++; + else if (*rptr2 == ':') qcnt--; + else if (*rptr2 == '(') parcnt++; + else if (*rptr2 == ')') parcnt--; + if (parcnt < 0) break; + if (!parcnt && !qcnt && *rptr2 == ':') break; + rptr2++; + } + if (*rptr2) *rptr2++=0; + while (isspace(*rptr2)) rptr2++; + + while (isspace(*tmp)) tmp++; + + len+=sprintf(buf+len,"_if(%s,%s,%s",l_ptr,*tmp?tmp:"0",*rptr2?rptr2:"0"); + ctx->l_stats[0]+=6; + } + else + { + len+=sprintf(buf+len,"%s(%s,%s",preprocSymbols[n].func,l_ptr?l_ptr:"",r_ptr); + ctx->l_stats[0]+=strlen(preprocSymbols[n].func)+2; + } + + } + + free(r_ptr); + free(l_ptr); + + + c = ')'; // close parenth below + } + } + +// if (c != ' ' || (len && buf[len-1] != ' ')) // don't bother adding multiple spaces + { + buf[len++]=c; + if (c != ' ') ctx->l_stats[0]++; + } + } + } + buf[len]=0; + + return buf; +} + +#ifdef PPROC_TEST + +int main(int argc, char* argv[]) +{ + compileContext ctx={0}; + char *p=preprocessCode(&ctx,argv[1]); + if (p)printf("%s\n",p); + free(p); + return 0; +} + +#endif + +#if 0 +static void movestringover(char *str, int amount) +{ + char tmp[1024+8]; + + int l=(int)strlen(str); + l=min(1024-amount-1,l); + + memcpy(tmp,str,l+1); + + while (l >= 0 && tmp[l]!='\n') l--; + l++; + + tmp[l]=0;//ensure we null terminate + + memcpy(str+amount,tmp,l+1); +} +#endif + +//------------------------------------------------------------------------------ +NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX _ctx, const char *__expression, int lineoffs) +{ + return NSEEL_code_compile_ex(_ctx,__expression,lineoffs,0); +} + +typedef struct topLevelCodeSegmentRec { + struct topLevelCodeSegmentRec *_next; + void *code; + int codesz; + int tmptable_use; +} topLevelCodeSegmentRec; + +NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX _ctx, const char *__expression, int lineoffs, int compile_flags) +{ + char *_expression; + compileContext *ctx = (compileContext *)_ctx; + char *expression,*expression_start; + codeHandleType *handle; + topLevelCodeSegmentRec *startpts_tail=NULL; + topLevelCodeSegmentRec *startpts=NULL; + _codeHandleFunctionRec *oldCommonFunctionList; + int curtabptr_sz=0; + void *curtabptr=NULL; + int had_err=0; + + if (!ctx) return 0; + + ctx->directValueCache=0; + ctx->optimizeDisableFlags=0; + + if (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET) + { + ctx->functions_common=NULL; // reset common function list + } + else + { + // reset common compiled function code, forcing a recompile if shared + _codeHandleFunctionRec *a = ctx->functions_common; + while (a) + { + _codeHandleFunctionRec *b = a->derivedCopies; + + if (a->localstorage) + { + // force local storage actual values to be reallocated if used again + memset(a->localstorage,0,sizeof(EEL_F *) * a->localstorage_size); + } + + a->startptr = NULL; // force this copy to be recompiled + + while (b) + { + b->startptr = NULL; // force derived copies to get recompiled + // no need to reset b->localstorage, since it points to a->localstorage + b=b->derivedCopies; + } + + a=a->next; + } + } + + ctx->last_error_string[0]=0; + + if (!__expression || !*__expression) return 0; + + + _expression = strdup(__expression); + if (!_expression) return 0; + + oldCommonFunctionList = ctx->functions_common; + { + // do in place replace of "$'x'" to "56 " or whatnot + // we avoid changing the length of the string here, due to wanting to know where errors occur + char *p=_expression; + while (*p) + { + if (p[0] == '$' && p[1]=='\'' && p[2] && p[3]=='\'') + { + char tmp[64]; + int a,tl; + sprintf(tmp,"%d",(int)((unsigned char *)p)[2]); + tl=strlen(tmp); + if (tl>3) tl=3; + for (a=0;aisSharedFunctions = !!(compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS); + ctx->functions_local = NULL; + + freeBlocks(&ctx->tmpblocks_head); // free blocks + freeBlocks(&ctx->blocks_head); // free blocks + freeBlocks(&ctx->blocks_head_data); // free blocks + memset(ctx->l_stats,0,sizeof(ctx->l_stats)); + free(ctx->compileLineRecs); + ctx->compileLineRecs=0; + ctx->compileLineRecs_size=0; + ctx->compileLineRecs_alloc=0; + + handle = (codeHandleType*)newDataBlock(sizeof(codeHandleType),8); + + if (!handle) + { + free(_expression); + return 0; + } + + + memset(handle,0,sizeof(codeHandleType)); + + ctx->tmpCodeHandle = handle; + expression_start=expression=preprocessCode(ctx,_expression,0,0); + + while (*expression) + { + int computTableTop = 0; + int startptr_size=0; + void *startptr=NULL; + opcodeRec *start_opcode=NULL; + char *expr; + int function_numparms=0; + char is_fname[NSEEL_MAX_VARIABLE_NAMELEN+1]; + is_fname[0]=0; + + memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); + memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); + ctx->function_localTable_ValuePtrs=0; + ctx->function_usesThisPointer=0; + ctx->function_curName=NULL; + +#ifdef NSEEL_USE_OLD_PARSER + ctx->colCount=0; +#endif + + // single out segment + while (*expression == ';' || isspace(*expression)) expression++; + if (!*expression) break; + expr=expression; + + while (*expression && *expression != ';') expression++; + if (*expression) *expression++ = 0; + + // parse + + if (!strncasecmp(expr,"function",8) && isspace(expr[8])) + { + char *p = expr+8; + while (isspace(p[0])) p++; + if (isalpha(p[0]) || p[0] == '_') + { + int had_parms_locals=0; + char *sp=p; + int l; + while (isalnum(p[0]) || p[0] == '_') p++; + l=min(p-sp, sizeof(is_fname)-1); + memcpy(is_fname, sp, l); + is_fname[l]=0; + ctx->function_curName = is_fname; // only assigned for the duration of the loop, cleared later //-V507 + + expr = p; + + while (*expr) + { + const char *tn; + int tn_len; + p=expr; + while (isspace(*p)) p++; + + tn = p; + while (*p && !isspace(*p) && *p != '(') p++; + tn_len = p - tn; + + while (isspace(*p)) p++; + + if (*p == '(' && + ( + !tn_len || + (tn_len == 5 && !strncasecmp(tn,"local",tn_len)) || + (tn_len == 6 && !strncasecmp(tn,"static",tn_len)) || + (tn_len == 8 && !strncasecmp(tn,"instance",tn_len)) + ) + ) + { + int maxcnt=0,state=0; + int is_parms = 0; + int localTableContext = 0; + + if (tn_len == 0) + { + if (had_parms_locals) break; // formal parameters must be before instance() static() or local(), otherwise it is assumed to be the body of the function + is_parms = 1; + } + else + { + localTableContext = (tn_len == 8 && !strncasecmp(tn,"instance",tn_len)); //adding to "implied this" table + } + had_parms_locals=1; + + // skip past opening paren + p++; + + sp=p; + while (*p && *p != ')') + { + if (isspace(*p) || *p == ',') + { + if (state) maxcnt++; + state=0; + } + else state=1; + p++; + } + if (state) maxcnt++; + if (*p) + { + expr=p+1; + + if (maxcnt > 0) + { + char **ot = ctx->function_localTable_Names[localTableContext]; + int osz = ctx->function_localTable_Size[localTableContext]; + + maxcnt += osz; + + ctx->function_localTable_Names[localTableContext] = (char **)newTmpBlock(ctx,sizeof(char *) * maxcnt); + + if (ctx->function_localTable_Names[localTableContext]) + { + int i=osz; + if (osz && ot) memcpy(ctx->function_localTable_Names[localTableContext],ot,sizeof(char *) * osz); + p=sp; + while (p < expr-1 && i < maxcnt) + { + while (p < expr && (isspace(*p) || *p == ',')) p++; + sp=p; + while (p < expr-1 && (!isspace(*p) && *p != ',')) p++; + + if (isalpha(*sp) || *sp == '_') + { + char *newstr; + int l = (p-sp); + if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; + newstr = newTmpBlock(ctx,l+1); + if (newstr) + { + memcpy(newstr,sp,l); + newstr[l]=0; + ctx->function_localTable_Names[localTableContext][i++] = newstr; + } + } + } + + ctx->function_localTable_Size[localTableContext]=i; + + if (is_parms) function_numparms = i; + } + } + } + } + else break; + } + } + } + if (ctx->function_localTable_Size>0) + { + ctx->function_localTable_ValuePtrs = + ctx->isSharedFunctions ? newDataBlock(ctx->function_localTable_Size[0] * sizeof(EEL_F *),8) : + newTmpBlock(ctx,ctx->function_localTable_Size[0] * sizeof(EEL_F *)); + if (!ctx->function_localTable_ValuePtrs) + { + ctx->function_localTable_Size[0]=0; + function_numparms=0; + } + else + { + memset(ctx->function_localTable_ValuePtrs,0,sizeof(EEL_F *) * ctx->function_localTable_Size[0]); // force values to be allocated + } + } + + ctx->errVar=0; + +#ifdef NSEEL_USE_OLD_PARSER + nseel_llinit(ctx); + if (!nseel_yyparse(ctx,expr) && !ctx->errVar) + { + start_opcode = ctx->result; + } +#else + { + int nseelparse(compileContext* context); + +#ifdef NSEEL_SUPER_MINIMAL_LEXER + ctx->rdbuf_start = ctx->rdbuf = expr; + if (!nseelparse(ctx) && !ctx->errVar) + { + start_opcode = ctx->result; + } + ctx->rdbuf = NULL; +#else + + void nseelrestart (void *input_file ,void *yyscanner ); + + nseelrestart(NULL,ctx->scanner); + ctx->inputbufferptr = expr; + + if (!nseelparse(ctx) && !ctx->errVar) + { + start_opcode = ctx->result; + } + if (ctx->errVar && ctx->errVar_l>0) + { + const char *p=expr; + while (*p && ctx->errVar_l-->0) + { + while (*p && *p != '\n') { p++; ctx->errVar++; } + if (*p) { ctx->errVar++; p++; } + } + } + ctx->inputbufferptr=NULL; +#endif + + } +#endif + + if (start_opcode) + { + int rvMode=0, fUse=0; + +#ifdef LOG_OPT + char buf[512]; + int sd=0; + sprintf(buf,"pre opt sz=%d (tsackDepth=%d)\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL,RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); +#ifdef _WIN32 + OutputDebugString(buf); +#else + printf("%s\n",buf); +#endif +#endif + if (!(ctx->optimizeDisableFlags&OPTFLAG_NO_OPTIMIZE)) optimizeOpcodes(ctx,start_opcode,is_fname[0] ? 1 : 0); +#ifdef LOG_OPT + sprintf(buf,"post opt sz=%d, stack depth=%d\n",compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL,NULL, RETURNVALUE_IGNORE,NULL,&sd,NULL),sd); +#ifdef _WIN32 + OutputDebugString(buf); +#else + printf("%s\n",buf); +#endif +#endif + +#ifdef DUMP_OPS_DURING_COMPILE + g_debugfp_indent=0; + g_debugfp_histsz=0; + g_debugfp = fopen("C:/temp/foo.txt","w"); +#endif + startptr_size = compileOpcodes(ctx,start_opcode,NULL,1024*1024*256,NULL, NULL, + is_fname[0] ? (RETURNVALUE_NORMAL|RETURNVALUE_FPSTACK) : RETURNVALUE_IGNORE, &rvMode, &fUse, NULL); // if not a function, force return value as address (avoid having to pop it ourselves + // if a function, allow the code to decide how return values are generated + +#ifdef DUMP_OPS_DURING_COMPILE + if (g_debugfp) fclose(g_debugfp); + g_debugfp=0; +#endif + + if (is_fname[0]) + { + _codeHandleFunctionRec *fr = ctx->isSharedFunctions ? newDataBlock(sizeof(_codeHandleFunctionRec),8) : + newTmpBlock(ctx,sizeof(_codeHandleFunctionRec)); + if (fr) + { + memset(fr,0,sizeof(_codeHandleFunctionRec)); + fr->startptr_size = startptr_size; + fr->opcodes = start_opcode; + fr->rvMode = rvMode; + + fr->fpStackUsage=fUse; + fr->tmpspace_req = computTableTop; + + if (ctx->function_localTable_Size[0] > 0 && ctx->function_localTable_ValuePtrs) + { + fr->num_params=function_numparms; + fr->localstorage = ctx->function_localTable_ValuePtrs; + fr->localstorage_size = ctx->function_localTable_Size[0]; + } + + fr->usesThisPointer = ctx->function_usesThisPointer; + fr->isCommonFunction = ctx->isSharedFunctions; + + strcpy(fr->fname,is_fname); + + if (ctx->isSharedFunctions) + { + fr->next = ctx->functions_common; + ctx->functions_common = fr; + } + else + { + fr->next = ctx->functions_local; + ctx->functions_local = fr; + } + } + continue; + } + + if (!startptr_size) continue; // optimized away + if (startptr_size>0) + { + startptr = newTmpBlock(ctx,startptr_size); + if (startptr) + { + startptr_size=compileOpcodes(ctx,start_opcode,(unsigned char*)startptr,startptr_size,&computTableTop, NULL, RETURNVALUE_IGNORE, NULL,NULL, NULL); + if (startptr_size<=0) startptr = NULL; + + } + } + } + + if (!startptr) + { + int byteoffs = expr - expression_start; + int destoffs,linenumber; + char buf[50], *p; + int x,le; + +#ifdef NSEEL_EEL1_COMPAT_MODE + if (!startptr) continue; +#endif + + if (ctx->errVar > 0) byteoffs += ctx->errVar; + linenumber=findByteOffsetInSource(ctx,byteoffs,&destoffs); + if (destoffs < 0) destoffs=0; + + le=strlen(_expression); + if (destoffs >= le) destoffs=le; + p= _expression + destoffs; + x=0; + while (x < sizeof(buf)-1) + { + if (!*p) break; + if (x && (*p == '\r' || *p == '\n')) break; + + if (!isspace(*p) || (x && !isspace(p[-1]))) buf[x++]=*p; + + p++; + } + buf[x]=0; + + if (!ctx->last_error_string[0]) + snprintf(ctx->last_error_string,sizeof(ctx->last_error_string),"Around line %d '%s'",linenumber+lineoffs,buf); + + startpts=NULL; + startpts_tail=NULL; + had_err=1; + break; + } + + if (!is_fname[0]) // redundant check (if is_fname[0] is set and we succeeded, it should continue) + // but we'll be on the safe side + { + topLevelCodeSegmentRec *p = newTmpBlock(ctx,sizeof(topLevelCodeSegmentRec)); + p->_next=0; + p->code = startptr; + p->codesz = startptr_size; + p->tmptable_use = computTableTop; + + if (!startpts_tail) startpts_tail=startpts=p; + else + { + startpts_tail->_next=p; + startpts_tail=p; + } + + if (curtabptr_sz < computTableTop) + { + curtabptr_sz=computTableTop; + } + } + } + free(ctx->compileLineRecs); + ctx->compileLineRecs=0; + ctx->compileLineRecs_size=0; + ctx->compileLineRecs_alloc=0; + + memset(ctx->function_localTable_Size,0,sizeof(ctx->function_localTable_Size)); + memset(ctx->function_localTable_Names,0,sizeof(ctx->function_localTable_Names)); + ctx->function_localTable_ValuePtrs=0; + ctx->function_usesThisPointer=0; + ctx->function_curName=NULL; + + ctx->tmpCodeHandle = NULL; + + if (handle->want_stack) + { + if (!handle->stack) startpts=NULL; + } + + if (startpts) + { + curtabptr_sz += 2; // many functions use the worktable for temporary storage of up to 2 EEL_F's + + handle->workTable_size = curtabptr_sz; + handle->workTable = curtabptr = newDataBlock((curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F),32); + +#ifdef EEL_VALIDATE_WORKTABLE_USE + if (curtabptr) memset(curtabptr,0x3a,(curtabptr_sz+MIN_COMPUTABLE_SIZE + COMPUTABLE_EXTRA_SPACE) * sizeof(EEL_F)); +#endif + if (!curtabptr) startpts=NULL; + } + + + if (startpts || (!had_err && (compile_flags & NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS))) + { + unsigned char *writeptr; + topLevelCodeSegmentRec *p=startpts; + int size=sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE; // for ret at end :) + int wtpos=0; + + // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item as necessary + while (p) + { + if (wtpos <= 0) + { + wtpos=MIN_COMPUTABLE_SIZE; + size += GLUE_RESET_WTP(NULL,0); + } + size+=p->codesz; + wtpos -= p->tmptable_use; + p=p->_next; + } + handle->code = newCodeBlock(size,32); + if (handle->code) + { + writeptr=(unsigned char *)handle->code; + #if GLUE_FUNC_ENTER_SIZE > 0 + memcpy(writeptr,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); + writeptr += GLUE_FUNC_ENTER_SIZE; + #endif + p=startpts; + wtpos=0; + while (p) + { + if (wtpos <= 0) + { + wtpos=MIN_COMPUTABLE_SIZE; + writeptr+=GLUE_RESET_WTP(writeptr,curtabptr); + } + memcpy(writeptr,(char*)p->code,p->codesz); + writeptr += p->codesz; + wtpos -= p->tmptable_use; + + p=p->_next; + } + #if GLUE_FUNC_LEAVE_SIZE > 0 + memcpy(writeptr,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); + writeptr += GLUE_FUNC_LEAVE_SIZE; + #endif + memcpy(writeptr,&GLUE_RET,sizeof(GLUE_RET)); writeptr += sizeof(GLUE_RET); + ctx->l_stats[1]=size; + handle->code_size = writeptr - (unsigned char *)handle->code; + } + + handle->blocks = ctx->blocks_head; + handle->blocks_data = ctx->blocks_head_data; + ctx->blocks_head=0; + ctx->blocks_head_data=0; + } + else + { + // failed compiling, or failed calloc() + handle=NULL; // return NULL (after resetting blocks_head) + } + + + ctx->directValueCache=0; + ctx->functions_local = NULL; + + ctx->isSharedFunctions=0; + + freeBlocks(&ctx->tmpblocks_head); // free blocks + freeBlocks(&ctx->blocks_head); // free blocks of code (will be nonzero only on error) + freeBlocks(&ctx->blocks_head_data); // free blocks of data (will be nonzero only on error) + + if (handle) + { + handle->ramPtr = ctx->ram_state.blocks; + memcpy(handle->code_stats,ctx->l_stats,sizeof(ctx->l_stats)); + nseel_evallib_stats[0]+=ctx->l_stats[0]; + nseel_evallib_stats[1]+=ctx->l_stats[1]; + nseel_evallib_stats[2]+=ctx->l_stats[2]; + nseel_evallib_stats[3]+=ctx->l_stats[3]; + nseel_evallib_stats[4]++; + } + else + { + ctx->functions_common = oldCommonFunctionList; // failed compiling, remove any added common functions from the list + + // remove any derived copies of functions due to error, since we may have added some that have been freed + while (oldCommonFunctionList) + { + oldCommonFunctionList->derivedCopies=NULL; + oldCommonFunctionList=oldCommonFunctionList->next; + } + } + memset(ctx->l_stats,0,sizeof(ctx->l_stats)); + + free(expression_start); + free(_expression); + + return (NSEEL_CODEHANDLE)handle; +} + +//------------------------------------------------------------------------------ +void NSEEL_code_execute(NSEEL_CODEHANDLE code) +{ + INT_PTR tabptr; + INT_PTR codeptr; + codeHandleType *h = (codeHandleType *)code; + if (!h || !h->code) return; + + codeptr = (INT_PTR) h->code; +#if 0 + { + unsigned int *p=(unsigned int *)codeptr; + while (*p != GLUE_RET[0]) + { + printf("instr:%04X:%04X\n",*p>>16,*p&0xffff); + p++; + } + } +#endif + + tabptr=(INT_PTR)h->workTable; + //printf("calling code!\n"); + GLUE_CALL_CODE(tabptr,codeptr,(INT_PTR)h->ramPtr); + +} + + +char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx) +{ + compileContext *c=(compileContext *)ctx; + if (ctx && c->last_error_string[0]) return c->last_error_string; + return 0; +} + +//------------------------------------------------------------------------------ +void NSEEL_code_free(NSEEL_CODEHANDLE code) +{ + codeHandleType *h = (codeHandleType *)code; + if (h != NULL) + { +#ifdef EEL_VALIDATE_WORKTABLE_USE + if (h->workTable) + { + char *p = ((char*)h->workTable) + h->workTable_size*sizeof(EEL_F); + int x; + for(x=COMPUTABLE_EXTRA_SPACE*sizeof(EEL_F) - 1;x >= 0; x --) + if (p[x] != 0x3a) + { + char buf[512]; + sprintf(buf,"worktable overrun at byte %d (wts=%d), value = %f\n",x,h->workTable_size, *(EEL_F*)(p+(x&~(sizeof(EEL_F)-1)))); + OutputDebugString(buf); + break; + } + } +#endif + + nseel_evallib_stats[0]-=h->code_stats[0]; + nseel_evallib_stats[1]-=h->code_stats[1]; + nseel_evallib_stats[2]-=h->code_stats[2]; + nseel_evallib_stats[3]-=h->code_stats[3]; + nseel_evallib_stats[4]--; + +#ifdef EEL_PPC_NOFREECODE + #pragma warn leaky-code mode, not freeing code, will leak, fixme!!! +#else + freeBlocks(&h->blocks); +#endif + + freeBlocks(&h->blocks_data); + + + } + +} + + +//------------------------------------------------------------------------------ +static void NSEEL_VM_freevars(NSEEL_VMCTX _ctx) +{ + if (_ctx) + { + compileContext *ctx=(compileContext *)_ctx; + + free(ctx->varTable_Values); + free(ctx->varTable_Names); + ctx->varTable_Values=0; + ctx->varTable_Names=0; + + ctx->varTable_numBlocks=0; + } +} + + +NSEEL_VMCTX NSEEL_VM_alloc() // return a handle +{ + compileContext *ctx=calloc(1,sizeof(compileContext)); +#ifndef NSEEL_USE_OLD_PARSER + + #ifdef NSEEL_SUPER_MINIMAL_LEXER + ctx->scanner = ctx; + #else + if (ctx) + { + int nseellex_init(void ** ptr_yy_globals); + void nseelset_extra(void *user_defined , void *yyscanner); + if (nseellex_init(&ctx->scanner)) + { + free(ctx); + return NULL; + } + nseelset_extra(ctx,ctx->scanner); + } + #endif + +#endif + + if (ctx) ctx->ram_state.closefact = NSEEL_CLOSEFACTOR; + return ctx; +} + +void NSEEL_VM_free(NSEEL_VMCTX _ctx) // free when done with a VM and ALL of its code have been freed, as well +{ + + if (_ctx) + { + compileContext *ctx=(compileContext *)_ctx; + NSEEL_VM_freevars(_ctx); + NSEEL_VM_freeRAM(_ctx); + + freeBlocks(&ctx->pblocks); + + // these should be 0 normally but just in case + freeBlocks(&ctx->tmpblocks_head); // free blocks + freeBlocks(&ctx->blocks_head); // free blocks + freeBlocks(&ctx->blocks_head_data); // free blocks + + + free(ctx->compileLineRecs); + +#ifndef NSEEL_USE_OLD_PARSER + #ifndef NSEEL_SUPER_MINIMAL_LEXER + if (ctx->scanner) + { + int nseellex_destroy(void *yyscanner); + nseellex_destroy(ctx->scanner); + } + #endif + ctx->scanner=0; +#endif + free(ctx); + } + +} + +int *NSEEL_code_getstats(NSEEL_CODEHANDLE code) +{ + codeHandleType *h = (codeHandleType *)code; + if (h) + { + return h->code_stats; + } + return 0; +} + +void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr) +{ + if (ctx) + { + compileContext *c=(compileContext*)ctx; + c->caller_this=thisptr; + } +} + + + + + +void *NSEEL_PProc_RAM(void *data, int data_size, compileContext *ctx) +{ + if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->ram_state.blocks); + return data; +} + +void *NSEEL_PProc_THIS(void *data, int data_size, compileContext *ctx) +{ + if (data_size>0) data=EEL_GLUE_set_immediate(data, (INT_PTR)ctx->caller_this); + return data; +} + +void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx) +{ + compileContext *ctx = (compileContext *)_ctx; + int wb; + if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + int ti; + char **plist=ctx->varTable_Names[wb]; + if (!plist) break; + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (plist[ti]) + { + varNameHdr *v = ((varNameHdr*)plist[ti])-1; + if (!v->refcnt && !v->isreg) + { + plist[ti]=NULL; + } + } + } + } +} + +void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx) +{ + compileContext *ctx = (compileContext *)_ctx; + int wb; + if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + int ti; + char **plist=ctx->varTable_Names[wb]; + if (!plist) break; + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (plist[ti]) + { + varNameHdr *v = ((varNameHdr*)plist[ti])-1; + if (!v->isreg) + { + plist[ti]=NULL; + } + } + } + } +} + +void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx) +{ + compileContext *ctx = (compileContext *)_ctx; + int wb; + if (ctx) for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + int ti; + char **plist=ctx->varTable_Names[wb]; + if (!plist) break; + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (plist[ti]) + { + varNameHdr *v = ((varNameHdr*)plist[ti])-1; + v->refcnt=0; + } + } + } +} + +EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg) +{ + int match_wb = -1, match_ti=-1; + int wb; + int ti=0; + for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + char **plist=ctx->varTable_Names[wb]; + if (!plist) return NULL; // error! + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (!plist[ti]) + { + if (match_wb < 0) + { + match_wb=wb; + match_ti=ti; + } + } + else if (!strncasecmp(plist[ti],name,NSEEL_MAX_VARIABLE_NAMELEN)) + { + varNameHdr *v = ((varNameHdr*)plist[ti])-1; + v->refcnt++; + if (isReg) v->isreg=isReg; + break; + } + } + if (ti < NSEEL_VARS_PER_BLOCK) break; + } + + if (wb == ctx->varTable_numBlocks && match_wb >=0 && match_ti >= 0) + { + wb = match_wb; + ti = match_ti; + } + + if (wb == ctx->varTable_numBlocks) + { + ti=0; + // add new block + if (!(ctx->varTable_numBlocks&(NSEEL_VARS_MALLOC_CHUNKSIZE-1)) || !ctx->varTable_Values || !ctx->varTable_Names ) + { + ctx->varTable_Values = (EEL_F **)realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(EEL_F *)); + ctx->varTable_Names = (char ***)realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char **)); + + if (!ctx->varTable_Names || !ctx->varTable_Values) return NULL; + } + ctx->varTable_numBlocks++; + + ctx->varTable_Values[wb] = (EEL_F *)newCtxDataBlock(sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK,8); + ctx->varTable_Names[wb] = (char **)newCtxDataBlock(sizeof(char *)*NSEEL_VARS_PER_BLOCK,1); + if (ctx->varTable_Values[wb]) + { + memset(ctx->varTable_Values[wb],0,sizeof(EEL_F)*NSEEL_VARS_PER_BLOCK); + } + if (ctx->varTable_Names[wb]) + { + memset(ctx->varTable_Names[wb],0,sizeof(char *)*NSEEL_VARS_PER_BLOCK); + } + } + + if (!ctx->varTable_Names[wb] || !ctx->varTable_Values[wb]) return NULL; + + if (!ctx->varTable_Names[wb][ti]) + { + int l = strlen(name); + char *b; + varNameHdr *vh; + if (l > NSEEL_MAX_VARIABLE_NAMELEN) l = NSEEL_MAX_VARIABLE_NAMELEN; + b=newCtxDataBlock( sizeof(varNameHdr) + l+1,1); + if (!b) return NULL; // malloc fail + vh=(varNameHdr *)b; + vh->refcnt=1; + vh->isreg=isReg; + + b+=sizeof(varNameHdr); + + memcpy(b,name,l); + b[l] = 0; + + ctx->varTable_Names[wb][ti] = b; + ctx->varTable_Values[wb][ti]=0.0; + } + return ctx->varTable_Values[wb] + ti; +} + + + +EEL_F nseel_globalregs[100]; + + +//------------------------------------------------------------------------------ + +void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx) +{ + compileContext *tctx = (compileContext *) ctx; + int wb; + if (!tctx) return; + + for (wb = 0; wb < tctx->varTable_numBlocks; wb ++) + { + int ti; + char **plist=tctx->varTable_Names[wb]; + if (!plist) break; + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (plist[ti] && !func(plist[ti],tctx->varTable_Values[wb] + ti,userctx)) break; + } + if (ti < NSEEL_VARS_PER_BLOCK) + break; + } +} + + +//------------------------------------------------------------------------------ +EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, const char *var) +{ + compileContext *ctx = (compileContext *)_ctx; + if (!ctx) return 0; + + if (!strncasecmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4])) + { + int x=atoi(var+3); + if (x < 0 || x > 99) x=0; + return nseel_globalregs + x; + } + + return nseel_int_register_var(ctx,var,1); +} + +int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name) +{ + compileContext *ctx = (compileContext *)_ctx; + int wb; + if (!ctx) return -1; + + for (wb = 0; wb < ctx->varTable_numBlocks; wb ++) + { + int ti; + if (!ctx->varTable_Values[wb] || !ctx->varTable_Names[wb]) break; + + for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++) + { + if (ctx->varTable_Names[wb][ti] && !strcasecmp(ctx->varTable_Names[wb][ti],name)) + { + varNameHdr *h = ((varNameHdr *)ctx->varTable_Names[wb][ti])-1; + return h->refcnt; + } + } + } + + return -1; +} + + + +//------------------------------------------------------------------------------ +opcodeRec *nseel_lookup(compileContext *ctx, int *typeOfObject, const char *sname) +{ + char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; + int i; + *typeOfObject = IDENTIFIER; + + lstrcpyn_safe(tmp,sname,sizeof(tmp)); + + if (!strncasecmp(tmp,"reg",3) && strlen(tmp) == 5 && isdigit(tmp[3]) && isdigit(tmp[4]) && (i=atoi(tmp+3))>=0 && i<100) + { + return nseel_createCompiledValuePtr(ctx,nseel_globalregs+i); + } + + // scan for parameters/local variables before user functions + if (strncasecmp(tmp,"this.",5) && + ctx->function_localTable_Size[0] > 0 && + ctx->function_localTable_Names[0] && + ctx->function_localTable_ValuePtrs) + { + char **namelist = ctx->function_localTable_Names[0]; + for (i=0; i < ctx->function_localTable_Size[0]; i++) + { + if (namelist[i] && !strncasecmp(namelist[i],tmp,NSEEL_MAX_VARIABLE_NAMELEN)) + { + return nseel_createCompiledValuePtrPtr(ctx, ctx->function_localTable_ValuePtrs+i); + } + } + } + + // if instance name set, translate tmp or tmp.* into "this.tmp.*" + if (strncasecmp(tmp,"this.",5) && + ctx->function_localTable_Size[1] > 0 && + ctx->function_localTable_Names[1]) + { + char **namelist = ctx->function_localTable_Names[1]; + for (i=0; i < ctx->function_localTable_Size[1]; i++) + { + int tl = namelist[i] ? strlen(namelist[i]) : 0; + + if (tl && !strncasecmp(namelist[i],tmp,tl) && (tmp[tl] == 0 || tmp[tl] == '.')) + { + strcpy(tmp,"this."); + lstrcpyn_safe(tmp + 5, sname, sizeof(tmp) - 5); // update tmp with "this.tokenname" + break; + } + } + } + + + if (strncasecmp(tmp,"this.",5)) + { + const char *nptr = tmp; + +#ifdef NSEEL_EEL1_COMPAT_MODE + if (!strcasecmp(nptr,"if")) nptr="_if"; + else if (!strcasecmp(nptr,"bnot")) nptr="_not"; + else if (!strcasecmp(nptr,"assign")) nptr="_set"; + else if (!strcasecmp(nptr,"equal")) nptr="_equal"; + else if (!strcasecmp(nptr,"below")) nptr="_below"; + else if (!strcasecmp(nptr,"above")) nptr="_above"; + else if (!strcasecmp(nptr,"megabuf")) nptr="_mem"; + else if (!strcasecmp(nptr,"gmegabuf")) nptr="_gmem"; +#endif + + for (i=0;nseel_getFunctionFromTable(i);i++) + { + functionType *f=nseel_getFunctionFromTable(i); + if (!strcasecmp(f->name, nptr)) + { + int np=f->nParams&FUNCTIONTYPE_PARAMETERCOUNTMASK; + switch (np) + { + case 0: + case 1: *typeOfObject = FUNCTION1; break; + case 2: *typeOfObject = FUNCTION2; break; + case 3: *typeOfObject = FUNCTION3; break; + default: +#ifndef NSEEL_USE_OLD_PARSER + *typeOfObject = FUNCTIONX; // newly supported X-parameter functions +#else + *typeOfObject = FUNCTION1; // should never happen, unless the caller was silly +#endif + break; + } + return nseel_createCompiledFunctionCall(ctx,np,FUNCTYPE_FUNCTIONTYPEREC,(void *) f); + } + } + } + + { + _codeHandleFunctionRec *fr = NULL; + + char *postName = tmp; + while (*postName) postName++; + while (postName >= tmp && *postName != '.') postName--; + if (++postName <= tmp) postName=0; + + if (!fr) + { + fr = ctx->functions_local; + while (fr) + { + if (!strcasecmp(fr->fname,postName?postName:tmp)) break; + fr=fr->next; + } + } + if (!fr) + { + fr = ctx->functions_common; + while (fr) + { + if (!strcasecmp(fr->fname,postName?postName:tmp)) break; + fr=fr->next; + } + } + + if (fr) + { + *typeOfObject= +#ifndef NSEEL_USE_OLD_PARSER + fr->num_params>3?FUNCTIONX : +#endif + fr->num_params>=3?FUNCTION3 : fr->num_params==2?FUNCTION2 : FUNCTION1; + + if (!strncasecmp(tmp,"this.",5) && tmp[5]) // relative scoped call + { + // we're calling this. something, defer lookup of derived version to code generation + ctx->function_usesThisPointer = 1; + return nseel_createCompiledFunctionCallEELThis(ctx,fr,tmp+5); + } + + if (postName && fr->usesThisPointer) // if has context and calling an eel function that needs context + { + _codeHandleFunctionRec *scan=fr; + while (scan) + { + if (!strcasecmp(scan->fname,tmp)) break; + scan=scan->derivedCopies; + } + + // if didn't find a cached instance, create our fully qualified function instance + if (!scan) scan = eel_createFunctionNamespacedInstance(ctx,fr,tmp); + + + // use our derived/cached version if we didn't fail + if (scan) fr=scan; + } + + return nseel_createCompiledFunctionCall(ctx,fr->num_params,FUNCTYPE_EELFUNC,(void *)fr); + } + + } + + // instance variables + if (!strncasecmp(tmp,"this.",5) && tmp[5]) + { + ctx->function_usesThisPointer=1; + return nseel_createCompiledValueFromNamespaceName(ctx,tmp+5); + } + + { + EEL_F *p=nseel_int_register_var(ctx,tmp,0); + if (p) return nseel_createCompiledValuePtr(ctx,p); + } + return nseel_createCompiledValue(ctx,0.0); +} + + + + +//------------------------------------------------------------------------------ +opcodeRec *nseel_translate(compileContext *ctx, const char *tmp) +{ + if (tmp[0] == '0' && toupper(tmp[1])=='X') + { + char *p; + return nseel_createCompiledValue(ctx,(EEL_F)strtoul(tmp+2,&p,16)); + } + if (strstr(tmp,".")) return nseel_createCompiledValue(ctx,(EEL_F)atof(tmp)); + return nseel_createCompiledValue(ctx,(EEL_F)atoi(tmp)); // todo: this could be atof() too, eventually, but that might break things +} + diff --git a/WDL/eel2/nseel-eval.c b/WDL/eel2/nseel-eval.c new file mode 100644 index 00000000..d1850e4d --- /dev/null +++ b/WDL/eel2/nseel-eval.c @@ -0,0 +1,151 @@ +/* + Expression Evaluator Library (NS-EEL) v2 + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + nseel-eval.c + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include "ns-eel-int.h" +#include "../wdlcstring.h" + +#ifndef NSEEL_USE_OLD_PARSER + + #ifdef NSEEL_SUPER_MINIMAL_LEXER + + int nseellex(opcodeRec **output, YYLTYPE * yylloc_param, compileContext *scctx) + { + int rv,toklen=0; + *output = 0; + while ((rv=scctx->rdbuf[0]) && (rv== ' ' || rv=='\t' || rv == '\r' || rv == '\n')) scctx->rdbuf++; + + if (rv) + { + char buf[NSEEL_MAX_VARIABLE_NAMELEN*2]; + int l; + char *ss = scctx->rdbuf++; + if (isalpha(rv) || rv == '_') + { + while ((rv=scctx->rdbuf[0]) && (isalnum(rv) || rv == '_' || rv == '.')) scctx->rdbuf++; + l = scctx->rdbuf - ss + 1; + if (l > sizeof(buf)) l=sizeof(buf); + lstrcpyn_safe(buf,ss,l); + + rv=0; + *output = nseel_lookup(scctx,&rv,buf); + } + else if ((rv >= '0' && rv <= '9') || (rv == '.' && (scctx->rdbuf[0] >= '0' && scctx->rdbuf[0] <= '9'))) + { + if (rv == '0' && (scctx->rdbuf[0] == 'x' || scctx->rdbuf[0] == 'X')) + { + scctx->rdbuf++; + while ((rv=scctx->rdbuf[0]) && ((rv>='0' && rv<='9') || (rv>='a' && rv<='f') || (rv>='A' && rv<='F'))) scctx->rdbuf++; + // this allows 0x, whereas the lex version will not parse that as a token + } + else + { + int pcnt=rv == '.'; + while ((rv=scctx->rdbuf[0]) && ((rv>='0' && rv<='9') || (rv == '.' && !pcnt++))) scctx->rdbuf++; + } + l = scctx->rdbuf - ss + 1; + if (l > sizeof(buf)) l=sizeof(buf); + lstrcpyn_safe(buf,ss,l); + *output = nseel_translate(scctx,buf); + rv=VALUE; + } + toklen = scctx->rdbuf - ss; + } + + yylloc_param->first_column = scctx->rdbuf - scctx->rdbuf_start - toklen; + return rv; + } + void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) + { + ctx->errVar=pos->first_column>0?pos->first_column:1; + } +#else + + int nseel_gets(compileContext *ctx, char *buf, size_t sz) + { + int n=0; + if (ctx->inputbufferptr) while (n < sz) + { + char c=ctx->inputbufferptr[0]; + if (!c) break; + if (c == '/' && ctx->inputbufferptr[1] == '*') + { + ctx->inputbufferptr+=2; // skip /* + + while (ctx->inputbufferptr[0] && (ctx->inputbufferptr[0] != '*' || ctx->inputbufferptr[1] != '/')) ctx->inputbufferptr++; + if (ctx->inputbufferptr[0]) ctx->inputbufferptr+=2; // skip */ + continue; + } + + ctx->inputbufferptr++; + buf[n++] = c; + } + return n; + + } + + + //#define EEL_TRACE_LEX + + #ifdef EEL_TRACE_LEX + #define nseellex nseellex2 + + #endif + #include "lex.nseel.c" + + #ifdef EEL_TRACE_LEX + + #undef nseellex + + int nseellex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) + { + int a=nseellex2(yylval_param,yylloc_param,yyscanner); + + char buf[512]; + sprintf(buf,"tok: %c (%d)\n",a,a); + OutputDebugString(buf); + return a; + } + #endif//EEL_TRACE_LEX + + + void nseelerror(YYLTYPE *pos,compileContext *ctx, const char *str) + { + ctx->errVar=pos->first_column>0?pos->first_column:1; + ctx->errVar_l = pos->first_line; + } +#endif // !NSEEL_SUPER_MINIMAL_LEXER + +#else + +//--------------------------------------------------------------------------- +int nseel_yyerror(compileContext *ctx) +{ + ctx->errVar = ctx->colCount; + return 0; +} + + +#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-lextab.c b/WDL/eel2/nseel-lextab.c new file mode 100644 index 00000000..76dacedf --- /dev/null +++ b/WDL/eel2/nseel-lextab.c @@ -0,0 +1,290 @@ +/* + Expression Evaluator Library (NS-EEL) v2 + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + nseel-lextab.c + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "ns-eel-int.h" + +#ifdef NSEEL_USE_OLD_PARSER + +#define LEXSKIP (-1) + +static int _lmovb(struct lextab *lp, int c, int st) +{ + int base; + if (c == '.' && st >= 15 && st < 30) c='_'; // if in a token, treat . as _ (should probably modify llnext instead) + + while ((base = lp->llbase[st]+c) > lp->llnxtmax || + (lp->llcheck[base] & 0377) != st) { + + if (st != lp->llendst) { + base = lp->lldefault[st] & 0377; + st = base; + } + else + return(-1); + } + return(lp->llnext[base]&0377); +} + +static int _Alextab(compileContext *ctx, int __na__) +{ + // fucko: JF> 17 -> 19? + + if (__na__ >= 0 && __na__ <= 17) + { + ctx->colCount+=nseel_gettokenlen(ctx,256); + } + switch (__na__) + { + case 0: + { + char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; + nseel_gettoken(ctx,tmp, sizeof(tmp)); + if (tmp[0] < '0' || tmp[0] > '9') // not sure where this logic came from + { + ctx->yylval = nseel_lookup(ctx,&__na__,tmp); + return __na__; + } + } + case 1: + case 2: + case 3: + { + char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; + nseel_gettoken(ctx,tmp, sizeof(tmp)); + ctx->yylval = nseel_translate(ctx,tmp); + return VALUE; + } + case 4: + case 5: + { + char tmp[NSEEL_MAX_VARIABLE_NAMELEN*2]; + nseel_gettoken(ctx,tmp, sizeof(tmp)); + ctx->yylval = nseel_lookup(ctx,&__na__,tmp); + return __na__; + } + case 6: return '+'; + case 7: return '-'; + case 8: return '*'; + case 9: return '/'; + case 10: return '%'; + case 11: return '&'; + case 12: return '|'; + case 13: return '('; + case 14: return ')'; + case 15: return '='; + case 16: return ','; + case 17: return ';'; + } + return (LEXSKIP); +} + + +static char _Flextab[] = + { + 1, 18, 17, 16, 15, 14, 13, 12, + 11, 10, 9, 8, 7, 6, 4, 5, + 5, 4, 4, 3, 3, 3, 3, 4, + 0, 4, 5, 0, 5, 4, 1, 3, + 0, 2, -1, 1, -1, + }; + + +static char _Nlextab[] = + { + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 1, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 1, 36, 36, 36, 36, 9, 8, 36, + 6, 5, 11, 13, 3, 12, 19, 10, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 36, 2, 36, 4, 36, 36, + 36, 29, 29, 29, 29, 29, 29, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 36, 36, 36, 36, 18, + 36, 29, 29, 29, 29, 29, 23, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 14, 18, + 18, 18, 18, 36, 7, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 36, + 36, 36, 36, 36, 36, 36, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 36, 36, 36, 36, 17, 36, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 36, 36, 36, 36, 36, 36, + 36, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 36, 36, 36, 36, 16, + 36, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 36, + 20, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 36, 36, 36, 36, 36, + 36, 36, 25, 25, 25, 25, 25, 25, + 36, 24, 36, 36, 36, 36, 36, 36, + 20, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 25, 25, 25, 25, 25, 25, + 36, 24, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 36, 36, 36, 36, + 36, 36, 36, 28, 28, 28, 28, 28, + 28, 36, 27, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 28, 28, 28, 28, 28, + 28, 31, 27, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 36, 36, 36, + 36, 36, 36, 36, 34, 34, 34, 33, + 34, 34, 36, 32, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 34, 34, 34, 33, + 34, 34, 36, 32, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 36, 36, + 36, 36, 36, 36, 36, 34, 34, 34, + 34, 34, 34, 36, 32, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 34, 34, 34, + 34, 34, 34, 36, 32, + }; + +static char _Clextab[] = + { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, -1, 0, 0, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, 0, -1, 0, -1, -1, + -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, -1, -1, -1, -1, 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, -1, 0, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, -1, + -1, -1, -1, -1, -1, -1, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + -1, -1, -1, -1, 14, -1, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, -1, -1, -1, -1, -1, -1, + -1, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, -1, -1, -1, -1, 15, + -1, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, -1, + 19, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, -1, -1, -1, -1, -1, + -1, -1, 23, 23, 23, 23, 23, 23, + -1, 23, -1, -1, -1, -1, -1, -1, + 19, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 23, 23, 23, 23, 23, 23, + -1, 23, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, -1, -1, -1, -1, + -1, -1, -1, 26, 26, 26, 26, 26, + 26, -1, 26, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 26, 26, 26, 26, 26, + 26, 30, 26, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, -1, -1, -1, + -1, -1, -1, -1, 30, 30, 30, 30, + 30, 30, -1, 30, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 30, 30, 30, 30, + 30, 30, -1, 30, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, -1, -1, + -1, -1, -1, -1, -1, 33, 33, 33, + 33, 33, 33, -1, 33, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 33, 33, 33, + 33, 33, 33, -1, 33, + }; + +static char _Dlextab[] = + { + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 15, 14, 14, 36, 36, 20, 19, 14, + 14, 23, 15, 15, 26, 23, 36, 19, + 36, 36, 33, 30, + }; + +static int _Blextab[] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 77, 152, + 0, 0, 0, 227, 237, 0, 0, 249, + 0, 0, 306, 0, 0, 0, 363, 0, + 0, 420, 0, 0, 0, + }; + +struct lextab nseel_lextab = { + 36, + _Dlextab, + _Nlextab, + _Clextab, + _Blextab, + 524, + _lmovb, + _Flextab, + _Alextab, + + 0, + 0, + 0, + 0, + }; + + + +#endif \ No newline at end of file diff --git a/WDL/eel2/nseel-ram.c b/WDL/eel2/nseel-ram.c new file mode 100644 index 00000000..ff539b70 --- /dev/null +++ b/WDL/eel2/nseel-ram.c @@ -0,0 +1,342 @@ +/* + Expression Evaluator Library (NS-EEL) v2 + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "ns-eel.h" +#include "ns-eel-int.h" +#include +#include +#include +#include + + +#ifdef _WIN32 +#include +#endif + +unsigned int NSEEL_RAM_limitmem=0; +unsigned int NSEEL_RAM_memused=0; +int NSEEL_RAM_memused_errors=0; + + + +int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx) +{ + if (ctx) + { + compileContext *c=(compileContext*)ctx; + if (c->ram_state.needfree) + return 1; + } + return 0; +} + +void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX ctx) // check to see if our free flag was set +{ + if (ctx) + { + compileContext *c=(compileContext*)ctx; + if (c->ram_state.needfree) + { + NSEEL_HOSTSTUB_EnterMutex(); + { + INT_PTR startpos=((INT_PTR)c->ram_state.needfree)-1; + EEL_F **blocks = c->ram_state.blocks; + INT_PTR pos=0; + int x; + for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) + { + if (pos >= startpos) + { + if (blocks[x]) + { + if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) + NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; + else NSEEL_RAM_memused_errors++; + free(blocks[x]); + blocks[x]=0; + } + } + pos+=NSEEL_RAM_ITEMSPERBLOCK; + } + c->ram_state.needfree=0; + } + NSEEL_HOSTSTUB_LeaveMutex(); + } + + } +} + + + + + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w) +{ + static EEL_F * volatile gmembuf; + static EEL_F fail; + if (blocks) + { + EEL_F **pblocks=*blocks; + + int is_locked=0; + + if (!pblocks) + { + if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); } + + if (!(pblocks=*blocks)) + { + pblocks = *blocks = (EEL_F **)calloc(sizeof(EEL_F *),NSEEL_RAM_BLOCKS); + if (!pblocks) { + if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); + return &fail; + } + } + } + + if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) + { + unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; + EEL_F *p=pblocks[whichblock]; + if (!p) + { + if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); } + + if (!(p=pblocks[whichblock])) + { + const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; + if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) + { + p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); + if (p) NSEEL_RAM_memused+=msize; + } + } + } + if (p) + { + if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); + return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); + } + } + if (is_locked) NSEEL_HOSTSTUB_LeaveMutex(); + return &fail; + } + + if (!gmembuf) + { + NSEEL_HOSTSTUB_EnterMutex(); + if (!gmembuf) gmembuf=(EEL_F*)calloc(sizeof(EEL_F),NSEEL_SHARED_GRAM_SIZE); + NSEEL_HOSTSTUB_LeaveMutex(); + if (!gmembuf) return &fail; + } + + return gmembuf+(((unsigned int)w)&((NSEEL_SHARED_GRAM_SIZE)-1)); +} + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **pblocks, unsigned int w) +{ + static EEL_F fail; + +// fprintf(stderr,"got request at %d, %d\n",w/NSEEL_RAM_ITEMSPERBLOCK, w&(NSEEL_RAM_ITEMSPERBLOCK-1)); + if (w < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) + { + unsigned int whichblock = w/NSEEL_RAM_ITEMSPERBLOCK; + EEL_F *p=pblocks[whichblock]; + if (!p) + { + NSEEL_HOSTSTUB_EnterMutex(); + + if (!(p=pblocks[whichblock])) + { + + const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; + if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem) + { + p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK); + if (p) NSEEL_RAM_memused+=msize; + } + } + NSEEL_HOSTSTUB_LeaveMutex(); + } + if (p) return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1)); + } +// fprintf(stderr,"ret 0\n"); + return &fail; +} + + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which) +{ + // blocks points to ram_state.blocks, so back it up past closefact and pad to needfree + int *flag = (int *)((char *)blocks - sizeof(double) - 2*sizeof(int)); + int d=(int)(*which); + if (d < 0) d=0; + if (d < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) flag[0]=1+d; + return which; +} + + + + + + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr) +{ + int dest_offs = (int)(*dest + 0.0001); + int src_offs = (int)(*src + 0.0001); + int len = (int)(*lenptr + 0.0001); + + // trim to front + if (src_offs<0) + { + len += src_offs; + dest_offs -= src_offs; + src_offs=0; + } + if (dest_offs<0) + { + len += dest_offs; + src_offs -= dest_offs; + dest_offs=0; + } + + while (len > 0) + { + EEL_F *srcptr,*destptr; + int copy_len = len; + int maxdlen=NSEEL_RAM_ITEMSPERBLOCK - (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); + int maxslen=NSEEL_RAM_ITEMSPERBLOCK - (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); + + if (dest_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK || + src_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) break; + + if (copy_len > maxdlen) copy_len=maxdlen; + if (copy_len > maxslen) copy_len=maxslen; + + if (copy_len<1) break; + + srcptr = __NSEEL_RAMAlloc(blocks,src_offs); + destptr = __NSEEL_RAMAlloc(blocks,dest_offs); + if (!srcptr || !destptr) break; + + memmove(destptr,srcptr,sizeof(EEL_F)*copy_len); + src_offs+=copy_len; + dest_offs+=copy_len; + len-=copy_len; + } + return dest; +} + +EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr) +{ + int offs = (int)(*dest + 0.0001); + int len = (int)(*lenptr + 0.0001); + EEL_F t; + if (offs<0) + { + len += offs; + offs=0; + } + if (offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest; + + if (offs+len > NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) len = NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - offs; + + if (len < 1) return dest; + + + t=*v; // set value + +// int lastBlock=-1; + while (len > 0) + { + int lcnt; + EEL_F *ptr=__NSEEL_RAMAlloc(blocks,offs); + if (!ptr) break; + + lcnt=NSEEL_RAM_ITEMSPERBLOCK-(offs&(NSEEL_RAM_ITEMSPERBLOCK-1)); + if (lcnt > len) lcnt=len; + + len -= lcnt; + offs += lcnt; + + while (lcnt--) + { + *ptr++=t; + } + } + return dest; +} + + +void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram) +{ + if (ctx) + { + compileContext *c=(compileContext*)ctx; + c->gram_blocks = gram; + } +} + + +void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx) +{ + if (ctx) + { + int x; + compileContext *c=(compileContext*)ctx; + EEL_F **blocks = c->ram_state.blocks; + for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) + { + if (blocks[x]) + { + if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) + NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; + else NSEEL_RAM_memused_errors++; + free(blocks[x]); + blocks[x]=0; + } + } + c->ram_state.needfree=0; // no need to free anymore + } +} + +void NSEEL_VM_FreeGRAM(void **ufd) +{ + if (ufd[0]) + { + EEL_F **blocks = (EEL_F **)ufd[0]; + int x; + for (x = 0; x < NSEEL_RAM_BLOCKS; x ++) + { + if (blocks[x]) + { + if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK) + NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK; + else NSEEL_RAM_memused_errors++; + } + free(blocks[x]); + blocks[x]=0; + } + free(blocks); + ufd[0]=0; + } +} diff --git a/WDL/eel2/nseel-yylex.c b/WDL/eel2/nseel-yylex.c new file mode 100644 index 00000000..e48b833d --- /dev/null +++ b/WDL/eel2/nseel-yylex.c @@ -0,0 +1,189 @@ +/* + Expression Evaluator Library (NS-EEL) + Copyright (C) 2004-2013 Cockos Incorporated + Copyright (C) 1999-2003 Nullsoft, Inc. + + nseel-yylex.c + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include "ns-eel-int.h" + + +#ifndef NSEEL_USE_OLD_PARSER + +# define YYMALLOC malloc +# define YYFREE free + +int nseellex(void * yylval_param,void * yylloc_param ,void *yyscanner); +void nseelerror(void *pos,compileContext *ctx, const char *str); + +#include +#include + +#include "y.tab.c" + +#else + +#define NBPW 16 +#define EOF (-1) + + +#define YYERRORVAL 256 /* yacc's value */ + +static int llset(compileContext *ctx); +static int llinp(compileContext *ctx, char **exp); +static int lexgetc(char **exp) +{ + char c= **exp; + if (c) (*exp)++; + return( c != 0 ? c : -1); +} +static int tst__b(register int c, char tab[]) +{ + return (tab[(c >> 3) & 037] & (1 << (c & 07)) ); +} + + +int nseel_gettokenlen(compileContext *ctx, int lltbsiz) +{ + char *lp; + int tp=0; + for (lp = ctx->llbuf; lp < ctx->llend && tp < lltbsiz; tp++, lp++); + return tp; + +} + +int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz) +{ + char *lp, *tp, *ep; + + tp = lltb; + ep = tp+lltbsiz-1; + for (lp = ctx->llbuf; lp < ctx->llend && tp < ep;) *tp++ = *lp++; + *tp = 0; + return(tp-lltb); +} + + +int nseel_yylex(compileContext *ctx, char **exp) +{ + register int c, st; + int final, l, llk, i; + register struct lextab *lp; + char *cp; + + while (1) + { + llk = 0; + if (llset(ctx)) return(0); + st = 0; + final = -1; + lp = &nseel_lextab; + + do { + if (lp->lllook && (l = lp->lllook[st])) { + for (c=0; cllsave[c] = ctx->llp1; + llk++; + } + if ((i = lp->llfinal[st]) != -1) { + final = i; + ctx->llend = ctx->llp1; + } + if ((c = llinp(ctx,exp)) < 0) + break; + if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) { + ctx->llp1--; + break; + } + } while ((st = (*lp->llmove)(lp, c, st)) != -1); + + + if (ctx->llp2 < ctx->llp1) + ctx->llp2 = ctx->llp1; + if (final == -1) { + ctx->llend = ctx->llp1; + if (st == 0 && c < 0) + return(0); + if ((cp = lp->llill) && tst__b(c, cp)) { + continue; + } + return(YYERRORVAL); + } + if ((c = (final >> 11) & 037)) + ctx->llend = ctx->llsave[c-1]; + if ((c = (*lp->llactr)(ctx,final&03777)) >= 0) + return(c); + } +} + +void nseel_llinit(compileContext *ctx) +{ + ctx->llp1 = ctx->llp2 = ctx->llend = ctx->llbuf; + ctx->llebuf = ctx->llbuf + sizeof(ctx->llbuf); + ctx->lleof = 0; +} + + +static int llinp(compileContext *ctx, char **exp) +{ + register int c; + register struct lextab *lp; + register char *cp; + + lp = &nseel_lextab; + cp = lp->llign; /* Ignore class */ + for (;;) { + /* + * Get the next character from the save buffer (if possible) + * If the save buffer's empty, then return EOF or the next + * input character. Ignore the character if it's in the + * ignore class. + */ + c = (ctx->llp1 < ctx->llp2) ? *ctx->llp1 & 0377 : (ctx->lleof) ? EOF : lexgetc(exp); + if (c >= 0) { /* Got a character? */ + if (cp && tst__b(c, cp)) + continue; /* Ignore it */ + if (ctx->llp1 >= ctx->llebuf) { /* No, is there room? */ + return -1; + } + *ctx->llp1++ = c; /* Store in token buff */ + } else + ctx->lleof = 1; /* Set EOF signal */ + return(c); + } +} + +static int llset(compileContext *ctx) +/* + * Return TRUE if EOF and nothing was moved in the look-ahead buffer + */ +{ + register char *lp1, *lp2; + + for (lp1 = ctx->llbuf, lp2 = ctx->llend; lp2 < ctx->llp2;) + *lp1++ = *lp2++; + ctx->llend = ctx->llp1 = ctx->llbuf; + ctx->llp2 = lp1; + return(ctx->lleof && lp1 == ctx->llbuf); +} + +#endif \ No newline at end of file diff --git a/WDL/eel2/preproc_test.cpp b/WDL/eel2/preproc_test.cpp new file mode 100644 index 00000000..65680b9f --- /dev/null +++ b/WDL/eel2/preproc_test.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include "../wdltypes.h" +#include "../wdlstring.h" + +#ifdef _WIN32 +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +typedef struct compileContext { + int l_stats[4]; +} compileContext; +#define onCompileNewLine(a,b,c) {} +#include "tmp.c" + +int ppOut(char *input) +{ + if (input[0]) + { + compileContext ctx = { 0,}; + char *exp=preprocessCode(&ctx,input); + if (!exp) + { + return -1; + } + int cc=0; + while (*exp) + { + if (*exp != ' ' && *exp != '\t' && *exp != '\r' && *exp != '\n') { + + printf("%c",*exp); + if (cc++ >= 60) { cc=0; printf("\n"); } + } + exp++; + } + printf("\n"); + } + return 0; +} +int main(int argc, char **argv) +{ + if (argc != 2) { fprintf(stderr,"usage: preproc_test filename\n"); return 0; } + FILE *fp =fopen(argv[1],"rb"); + if (!fp) { fprintf(stderr,"error opening '%s'\n",argv[1]); return 1; } + + int insec=0; + WDL_FastString cursec; + for (;;) + { + char buf[4096]; + buf[0]=0; + fgets(buf,sizeof(buf),fp); + if (!buf[0]) break; + char *p=buf; + while (*p == ' ' || *p == '\t') p++; + if (p[0] == '@') + { + insec=1; + if (ppOut((char*)cursec.Get())) { fprintf(stderr,"Error preprocessing %s!\n",argv[1]); return -1; } + cursec.Set(""); + } + else if (insec) + { + cursec.Append(buf); + continue; + } + printf("%s",buf); + } + if (ppOut((char*)cursec.Get())) { fprintf(stderr,"Error preprocessing %s!\n",argv[1]); return -1; } + + fclose(fp); + return 0; +} diff --git a/WDL/eel2/test.cpp b/WDL/eel2/test.cpp new file mode 100644 index 00000000..3c345aef --- /dev/null +++ b/WDL/eel2/test.cpp @@ -0,0 +1,65 @@ +#include "ns-eel.h" +#include + +void NSEEL_HOSTSTUB_EnterMutex() +{ +} +void NSEEL_HOSTSTUB_LeaveMutex() +{ +} + +int main() +{ + printf("init\n"); + if (NSEEL_init()) + { + printf("Error initializing EEL\n"); + return -1; + } + + printf("alloc\n"); + NSEEL_VMCTX vm = NSEEL_VM_alloc(); + if (!vm) + { + printf("Error creating VM\n"); + return -1; + } + + printf("reg\n"); + double *var_ret = NSEEL_VM_regvar(vm,"ret"); + + if (var_ret) *var_ret=1.0; + + printf("compile\n"); + char buf[1024]; + gets(buf); + + + // note that you shouldnt pass a readonly string directly, since it may need to + // fudge with the string during the compilation (it will always restore it to the + // original value though). + NSEEL_CODEHANDLE ch = NSEEL_code_compile(vm,buf,0); + + if (ch) + { + int n; + for (n = 0; n < 10; n ++) + { + NSEEL_code_execute(ch); + printf("pass(%d), ret=%f\n",n+1,var_ret ? *var_ret : 0.0); + } + + NSEEL_code_free(ch); + } + else + { + char *err = NSEEL_code_getcodeerror(vm); + + printf("Error compiling code at '%s'\n",err?err:"????"); + } + + NSEEL_VM_free(vm); + + + return 0; +} \ No newline at end of file diff --git a/WDL/eel2/test_vc6.dsp b/WDL/eel2/test_vc6.dsp new file mode 100644 index 00000000..476cd67b --- /dev/null +++ b/WDL/eel2/test_vc6.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="test_vc6" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=test_vc6 - 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 "test_vc6.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 "test_vc6.mak" CFG="test_vc6 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "test_vc6 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "test_vc6 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +RSC=rc.exe + +!IF "$(CFG)" == "test_vc6 - 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 "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "test_vc6 - 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 "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "test_vc6 - Win32 Release" +# Name "test_vc6 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "eel2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\ns-eel-addfuncs.h" +# End Source File +# Begin Source File + +SOURCE=".\ns-eel-int.h" +# End Source File +# Begin Source File + +SOURCE=".\ns-eel.h" +# End Source File +# Begin Source File + +SOURCE=".\nseel-caltab.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-cfunc.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-compiler.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-eval.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-lextab.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-ram.c" +# End Source File +# Begin Source File + +SOURCE=".\nseel-yylex.c" +# End Source File +# End Group +# Begin Source File + +SOURCE=.\test.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/WDL/eel2/test_vc6.dsw b/WDL/eel2/test_vc6.dsw new file mode 100644 index 00000000..d96be066 --- /dev/null +++ b/WDL/eel2/test_vc6.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "test_vc6"=.\test_vc6.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/WDL/eel2/y.tab.c b/WDL/eel2/y.tab.c new file mode 100644 index 00000000..61943771 --- /dev/null +++ b/WDL/eel2/y.tab.c @@ -0,0 +1,1819 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 1 + +/* Substitute the variable and function names. */ +#define yyparse nseelparse +#define yylex nseellex +#define yyerror nseelerror +#define yylval nseellval +#define yychar nseelchar +#define yydebug nseeldebug +#define yynerrs nseelnerrs +#define yylloc nseellloc + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 13 "eel2.y" + +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include + +#include "y.tab.h" +#include "ns-eel-int.h" + +#define scanner context->scanner +#define YY_(x) ("") + + + +/* Line 189 of yacc.c */ +#line 99 "y.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + VALUE = 258, + IDENTIFIER = 259, + FUNCTION1 = 260, + FUNCTION2 = 261, + FUNCTION3 = 262, + FUNCTIONX = 263 + }; +#endif +/* Tokens. */ +#define VALUE 258 +#define IDENTIFIER 259 +#define FUNCTION1 260 +#define FUNCTION2 261 +#define FUNCTION3 262 +#define FUNCTIONX 263 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 170 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 33 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 66 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 19 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 11 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 27 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 63 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 263 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 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, 18, 16, 2, + 10, 11, 15, 12, 9, 13, 2, 14, 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, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 17, 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, 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, 1, 2, 3, 4, + 5, 6, 7, 8 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 9, 11, 13, 17, 22, 29, + 38, 47, 49, 52, 55, 57, 61, 63, 67, 69, + 73, 75, 79, 81, 85, 89, 91, 95 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 29, 0, -1, 28, -1, 28, 9, 20, -1, 3, + -1, 4, -1, 10, 28, 11, -1, 5, 10, 28, + 11, -1, 6, 10, 28, 9, 28, 11, -1, 7, + 10, 28, 9, 28, 9, 28, 11, -1, 8, 10, + 28, 9, 28, 9, 20, 11, -1, 21, -1, 12, + 22, -1, 13, 22, -1, 22, -1, 23, 14, 22, + -1, 23, -1, 24, 15, 23, -1, 24, -1, 25, + 13, 24, -1, 25, -1, 26, 12, 25, -1, 26, + -1, 27, 16, 26, -1, 27, 17, 26, -1, 27, + -1, 28, 18, 27, -1, 28, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 38, 38, 39, 46, 47, 48, 52, 56, 60, + 64, 71, 72, 76, 84, 85, 93, 94, 102, 103, + 110, 111, 118, 119, 123, 130, 131, 139 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "VALUE", "IDENTIFIER", "FUNCTION1", + "FUNCTION2", "FUNCTION3", "FUNCTIONX", "','", "'('", "')'", "'+'", "'-'", + "'/'", "'*'", "'&'", "'|'", "'%'", "$accept", "more_params", + "value_thing", "unary_expr", "div_expr", "mul_expr", "sub_expr", + "add_expr", "andor_expr", "expression", "program", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 44, + 40, 41, 43, 45, 47, 42, 38, 124, 37 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 19, 20, 20, 21, 21, 21, 21, 21, 21, + 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, + 26, 26, 27, 27, 27, 28, 28, 29 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 3, 1, 1, 3, 4, 6, 8, + 8, 1, 2, 2, 1, 3, 1, 3, 1, 3, + 1, 3, 1, 3, 3, 1, 3, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, + 11, 14, 16, 18, 20, 22, 25, 27, 0, 0, + 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 6, 15, + 17, 19, 21, 23, 24, 26, 7, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 0, 2, 9, + 10, 0, 3 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 57, 10, 11, 12, 13, 14, 15, 16, 58, + 18 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -28 +static const yytype_int8 yypact[] = +{ + 5, -28, -28, 4, 30, 35, 36, 5, 5, 5, + -28, -28, 16, 27, 39, 41, -15, 13, 55, 5, + 5, 5, 5, 21, -28, -28, 5, 5, 5, 5, + 5, 5, 5, -28, 23, 7, 15, 17, -28, -28, + 16, 27, 39, 41, 41, -15, -28, 5, 5, 5, + 32, 18, 19, -28, 5, 5, 33, 45, 20, -28, + -28, 5, -28 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -28, -4, -28, -3, 31, 34, 37, -27, 28, 0, + -28 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 17, 30, 31, 43, 44, 24, 25, 23, 1, 2, + 3, 4, 5, 6, 19, 7, 47, 8, 9, 34, + 35, 36, 37, 39, 48, 32, 49, 54, 55, 61, + 26, 32, 38, 32, 46, 32, 32, 32, 32, 32, + 20, 32, 27, 53, 59, 21, 22, 50, 51, 52, + 32, 32, 28, 29, 56, 33, 60, 62, 40, 0, + 45, 0, 41, 0, 0, 0, 42 +}; + +static const yytype_int8 yycheck[] = +{ + 0, 16, 17, 30, 31, 8, 9, 7, 3, 4, + 5, 6, 7, 8, 10, 10, 9, 12, 13, 19, + 20, 21, 22, 26, 9, 18, 9, 9, 9, 9, + 14, 18, 11, 18, 11, 18, 18, 18, 18, 18, + 10, 18, 15, 11, 11, 10, 10, 47, 48, 49, + 18, 18, 13, 12, 54, 0, 11, 61, 27, -1, + 32, -1, 28, -1, -1, -1, 29 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 10, 12, 13, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, + 10, 10, 10, 28, 22, 22, 14, 15, 13, 12, + 16, 17, 18, 0, 28, 28, 28, 28, 11, 22, + 23, 24, 25, 26, 26, 27, 11, 9, 9, 9, + 28, 28, 28, 11, 9, 9, 28, 20, 28, 11, + 11, 9, 20 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, context); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + compileContext* context; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (context); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, compileContext* context) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + compileContext* context; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, compileContext* context) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, context) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + compileContext* context; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , context); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, context); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, compileContext* context) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + compileContext* context; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (context); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + case 3: /* "VALUE" */ + +/* Line 1000 of yacc.c */ +#line 8 "eel2.y" + { + #define yydestruct(a,b,c,d,e) 0 +}; + +/* Line 1000 of yacc.c */ +#line 1123 "y.tab.c" + break; + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (compileContext* context); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (compileContext* context) +#else +int +yyparse (context) + compileContext* context; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + yylsp = yyls; + +#if YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 1; +#endif + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + *++yylsp = yylloc; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: + +/* Line 1455 of yacc.c */ +#line 40 "eel2.y" + { + (yyval) = nseel_createMoreParametersOpcode(context,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 6: + +/* Line 1455 of yacc.c */ +#line 49 "eel2.y" + { + (yyval) = (yyvsp[(2) - (3)]); + } + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 53 "eel2.y" + { + (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (4)]), (yyvsp[(3) - (4)]), 0, 0); + } + break; + + case 8: + +/* Line 1455 of yacc.c */ +#line 57 "eel2.y" + { + (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(5) - (6)]), 0); + } + break; + + case 9: + +/* Line 1455 of yacc.c */ +#line 61 "eel2.y" + { + (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (8)]), (yyvsp[(3) - (8)]), (yyvsp[(5) - (8)]), (yyvsp[(7) - (8)])); + } + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 65 "eel2.y" + { + (yyval) = nseel_setCompiledFunctionCallParameters((yyvsp[(1) - (8)]), (yyvsp[(3) - (8)]), (yyvsp[(5) - (8)]), (yyvsp[(7) - (8)])); + } + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 73 "eel2.y" + { + (yyval) = (yyvsp[(2) - (2)]); + } + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 77 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_UMINUS,1,(yyvsp[(2) - (2)]),0); + } + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 86 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_DIVIDE,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 95 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_MULTIPLY,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 19: + +/* Line 1455 of yacc.c */ +#line 104 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_SUB,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 21: + +/* Line 1455 of yacc.c */ +#line 112 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_ADD,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 23: + +/* Line 1455 of yacc.c */ +#line 120 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_AND,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 24: + +/* Line 1455 of yacc.c */ +#line 124 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_OR,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 26: + +/* Line 1455 of yacc.c */ +#line 132 "eel2.y" + { + (yyval) = nseel_createSimpleCompiledFunction(context,FN_JOIN_STATEMENTS,2,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)])); + } + break; + + case 27: + +/* Line 1455 of yacc.c */ +#line 140 "eel2.y" + { + int a = (yylsp[(1) - (1)]).first_line; + context->result = (yyvsp[(1) - (1)]); + } + break; + + + +/* Line 1455 of yacc.c */ +#line 1599 "y.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, context, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (&yylloc, context, yymsg); + } + else + { + yyerror (&yylloc, context, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[0] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, context); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[0] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[0] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, context); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, context, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, context); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, context); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 147 "eel2.y" + + diff --git a/WDL/eel2/y.tab.h b/WDL/eel2/y.tab.h new file mode 100644 index 00000000..2c4942bb --- /dev/null +++ b/WDL/eel2/y.tab.h @@ -0,0 +1,84 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + VALUE = 258, + IDENTIFIER = 259, + FUNCTION1 = 260, + FUNCTION2 = 261, + FUNCTION3 = 262, + FUNCTIONX = 263 + }; +#endif +/* Tokens. */ +#define VALUE 258 +#define IDENTIFIER 259 +#define FUNCTION1 260 +#define FUNCTION2 261 +#define FUNCTION3 262 +#define FUNCTIONX 263 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/WDL/fastqueue.h b/WDL/fastqueue.h new file mode 100644 index 00000000..7663322d --- /dev/null +++ b/WDL/fastqueue.h @@ -0,0 +1,187 @@ +/* + WDL - fastqueue.h + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file defines and implements a class which can queue arbitrary amounts of data. + It is optimized for lots of reads and writes with a significant queue (i.e. it doesnt + have to shuffle much memory around). + + The downside is that you can't just ask for a pointer to specific bytes, it may have to peice + it together into a buffer of your choosing (or you can step through the buffers using GetPtr()). + + +*/ + +#ifndef _WDL_FASTQUEUE_H_ +#define _WDL_FASTQUEUE_H_ + + +#include "ptrlist.h" + +class WDL_FastQueue +{ +public: + WDL_FastQueue() + { + m_avail=0; + m_bsize=65536-64; + m_offs=0; + } + ~WDL_FastQueue() + { + m_queue.Empty(true); + m_empties.Empty(true); + } + + void Add(const void *buf, int len) // buf can be NULL to add zeroes + { + char *inptr=(char *)buf; + while (len>0) + { + WDL_HeapBuf *qb=m_queue.Get(m_queue.GetSize()-1); + int os; + if (!qb || (os=qb->GetSize()) >= m_bsize) + { + int esz=m_empties.GetSize()-1; + + qb=m_empties.Get(esz); + if (qb) m_empties.Delete(esz); + else qb=new WDL_HeapBuf(4096 WDL_HEAPBUF_TRACEPARM("WDL_FastQueue")); + + if (qb) m_queue.Add(qb); + os=0; + } + + if (!qb) break; + + int addl=m_bsize-os; + if (addl>len) addl=len; + char *b=(char *)qb->Resize(os+addl,false)+os; + if (inptr) + { + memcpy(b,inptr,addl); + inptr+=addl; + } + else memset(b,0,addl); + len -= addl; + m_avail+=addl; + } + } + + void Clear() + { + int x=m_queue.GetSize(); + while (x > 0) + { + m_empties.Add(m_queue.Get(--x)); + m_queue.Delete(x); + } + m_offs=0; + m_avail=0; + } + + void Advance(int cnt) + { + m_offs += cnt; + m_avail -= cnt; + if (m_avail<0)m_avail=0; + + WDL_HeapBuf *mq; + while ((mq=m_queue.Get(0))) + { + int sz=mq->GetSize(); + if (m_offs < sz) break; + m_offs -= sz; + m_empties.Add(mq); + m_queue.Delete(0); + } + if (!mq||m_offs<0) m_offs=0; + } + + int Available() // bytes available + { + return m_avail; + } + + + int GetPtr(int offset, void **buf) // returns bytes available in this block + { + offset += m_offs; + + int x=0; + WDL_HeapBuf *mq; + while ((mq=m_queue.Get(x))) + { + int sz=mq->GetSize(); + if (offset < sz) + { + *buf = (char *)mq->Get() + offset; + return sz-offset; + } + x++; + offset -= sz; + } + *buf=NULL; + return 0; + } + + int SetFromBuf(int offs, void *buf, int len) // returns length set + { + int pos=0; + while (len > 0) + { + void *p=NULL; + int l=GetPtr(offs+pos,&p); + if (!l || !p) break; + if (l > len) l=len; + memcpy(p,(char *)buf + pos,l); + pos += l; + len -= l; + } + return pos; + } + + int GetToBuf(int offs, void *buf, int len) + { + int pos=0; + while (len > 0) + { + void *p=NULL; + int l=GetPtr(offs+pos,&p); + if (!l || !p) break; + if (l > len) l=len; + memcpy((char *)buf + pos,p,l); + pos += l; + len -= l; + } + return pos; + } + +private: + + WDL_PtrList m_queue, m_empties; + int m_offs; + int m_avail; + int m_bsize; + int __pad; +} WDL_FIXALIGN; + + +#endif //_WDL_FASTQUEUE_H_ \ No newline at end of file diff --git a/WDL/ffmpeg.h b/WDL/ffmpeg.h new file mode 100644 index 00000000..e712fff2 --- /dev/null +++ b/WDL/ffmpeg.h @@ -0,0 +1,533 @@ +/* + WDL - ffmpeg.h + Copyright (C) 2005 Cockos Incorporated + Copyright (C) 1999-2004 Nullsoft, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _WDL_FFMPEG_H +#define _WDL_FFMPEG_H + +#ifdef _MSC_VER +#include "../sdks/ffmpeg/include/stdint.h" +#include "../sdks/ffmpeg/include/inttypes.h" +#endif + +extern "C" +{ +#include "../sdks/ffmpeg/include/libavformat/avformat.h" +#include "../sdks/ffmpeg/include/libswscale/swscale.h" +}; + +#include "queue.h" + +#ifndef INT64_C +#define INT64_C(val) val##i64 +#endif + +#ifndef INT64_MIN +#ifdef _MSC_VER +#define INT64_MIN (-0x7fffffffffffffff##i64 - 1) +#else +#define INT64_MIN (-0x7fffffffffffffffLL - 1) +#endif +#endif + +#ifndef INT64_MAX +#define INT64_MAX INT64_C(9223372036854775807) +#endif + +class WDL_VideoEncode +{ +public: + //bitrates are in kbps + WDL_VideoEncode(const char *format, int width, int height, double fps, int bitrate, const char *audioformat=NULL, int asr=44100, int ach=2, int abitrate=0) + { + m_init = 0; + m_img_resample_ctx = NULL; + m_stream = NULL; + m_astream = NULL; + m_video_enc = NULL; + m_audio_enc = NULL; + m_bit_buffer = NULL; + avcodec_get_frame_defaults(&m_cvtpic); + + //initialize FFMpeg + { + static int init = 0; + if(!init) av_register_all(); + init = 1; + } + + m_ctx = av_alloc_format_context(); + AVOutputFormat *fmt = guess_format(format, NULL, NULL); + if(!m_ctx || !fmt) return; + + m_ctx->oformat = fmt; + + m_stream = av_new_stream(m_ctx, m_ctx->nb_streams); + if(!m_stream) return; + + //init video + avcodec_get_context_defaults2(m_stream->codec, CODEC_TYPE_VIDEO); + m_video_enc = m_stream->codec; + + CodecID codec_id = av_guess_codec(m_ctx->oformat, NULL, NULL, NULL, CODEC_TYPE_VIDEO); + m_video_enc->codec_id = codec_id; + + AVCodec *codec; + codec = avcodec_find_encoder(codec_id); + if (!codec) return; + + m_video_enc->width = width; + m_video_enc->height = height; + m_video_enc->time_base.den = fps * 10000; + m_video_enc->time_base.num = 10000; + + m_video_enc->pix_fmt = PIX_FMT_BGRA; + if (codec && codec->pix_fmts) + { + const enum PixelFormat *p= codec->pix_fmts; + for (; *p!=-1; p++) { + if (*p == m_video_enc->pix_fmt) + break; + } + if (*p == -1) + m_video_enc->pix_fmt = codec->pix_fmts[0]; + } + + if(m_video_enc->pix_fmt != PIX_FMT_BGRA) + { + //this codec needs colorplane conversion + int sws_flags = SWS_BICUBIC; + m_img_resample_ctx = sws_getContext( + width, + height, + PIX_FMT_BGRA, + width, + height, + m_video_enc->pix_fmt, + sws_flags, NULL, NULL, NULL); + + if ( avpicture_alloc( (AVPicture*)&m_cvtpic, m_video_enc->pix_fmt, + m_video_enc->width, m_video_enc->height) ) + return; + } + + m_video_enc->bit_rate = bitrate*1024; + m_video_enc->gop_size = 12; /* emit one intra frame every twelve frames at most */ + + // some formats want stream headers to be separate + if(m_ctx->oformat->flags & AVFMT_GLOBALHEADER) + m_video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; + + m_video_enc->max_qdiff = 3; // set the default maximum quantizer difference between frames + m_video_enc->thread_count = 1; // set how many thread need be used in encoding + m_video_enc->rc_override_count = 0; // set ratecontrol override to 0 + if (!m_video_enc->rc_initial_buffer_occupancy) + { + m_video_enc->rc_initial_buffer_occupancy = m_video_enc->rc_buffer_size*3/4; // set decoder buffer size + } + m_video_enc->me_threshold = 0; // set motion estimation threshold value to 0 + m_video_enc->intra_dc_precision = 0; + m_video_enc->strict_std_compliance = 0; + m_ctx->preload = (int)(0.5 * AV_TIME_BASE); + m_ctx->max_delay = (int)(0.7 * AV_TIME_BASE); + m_ctx->loop_output = -1; + + m_ctx->timestamp = 0; + + av_log_set_callback(ffmpeg_avcodec_log); + av_log_set_level(AV_LOG_ERROR); + + if (avcodec_open(m_video_enc, codec) < 0) + { + return; + } + + //init audio + if(abitrate) + { + m_astream = av_new_stream(m_ctx, m_ctx->nb_streams); + if(!m_astream) return; + + avcodec_get_context_defaults2(m_astream->codec, CODEC_TYPE_AUDIO); + m_audio_enc = m_astream->codec; + + //use the format's default audio codec + CodecID codeca_id = av_guess_codec(m_ctx->oformat, audioformat, NULL, NULL, CODEC_TYPE_AUDIO); + m_audio_enc->codec_id = codeca_id; + + AVCodec *acodec; + acodec = avcodec_find_encoder(codeca_id); + if (!acodec) return; + + m_audio_enc->bit_rate = abitrate*1024; + m_audio_enc->sample_rate = asr; + m_audio_enc->channels = ach; + + if (avcodec_open(m_audio_enc, acodec) < 0) return; + } + + AVFormatParameters params, *ap = ¶ms; + memset(ap, 0, sizeof(*ap)); + if (av_set_parameters(m_ctx, ap) < 0) return; + + url_open_dyn_buf(&m_ctx->pb); + av_write_header(m_ctx); + + int size = width * height; + m_bit_buffer_size = 1024 * 256; + m_bit_buffer_size= FFMAX(m_bit_buffer_size, 4*size); + + m_bit_buffer = (uint8_t*)av_malloc(m_bit_buffer_size); + + m_init = 1; + } + ~WDL_VideoEncode() + { + if(m_stream && m_stream->codec) avcodec_close(m_stream->codec); + if(m_astream && m_astream->codec) avcodec_close(m_astream->codec); + av_free(m_bit_buffer); + av_free(m_cvtpic.data[0]); + av_free(m_ctx); + } + + int isInited() { return m_init; } + + void encodeVideo(const LICE_pixel *buf) + { + if(m_img_resample_ctx) + { + //convert to output format + uint8_t *p[1]={(uint8_t*)buf}; + int w[1]={m_video_enc->width*4}; + sws_scale(m_img_resample_ctx, p, w, + 0, m_video_enc->height, m_cvtpic.data, m_cvtpic.linesize); + } + int ret = avcodec_encode_video(m_video_enc, m_bit_buffer, m_bit_buffer_size, &m_cvtpic); + if(ret>0) + { + AVPacket pkt; + av_init_packet(&pkt); + pkt.stream_index = 0; + pkt.data = m_bit_buffer; + pkt.size = ret; + if (m_video_enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(m_video_enc->coded_frame->pts, m_video_enc->time_base, m_stream->time_base); + if(m_video_enc->coded_frame->key_frame) + pkt.flags |= PKT_FLAG_KEY; + av_interleaved_write_frame(m_ctx, &pkt); + } + } + + void encodeAudio(short *data, int nbsamples) + { + AVPacket pkt; + int l = nbsamples; + int fs = m_audio_enc->frame_size*m_audio_enc->channels; + while(l>=fs) + { + av_init_packet(&pkt); + pkt.size= avcodec_encode_audio(m_audio_enc, m_bit_buffer, m_bit_buffer_size, data); + if (m_audio_enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(m_audio_enc->coded_frame->pts, m_audio_enc->time_base, m_astream->time_base); + pkt.flags |= PKT_FLAG_KEY; + pkt.stream_index = 1; + pkt.data = m_bit_buffer; + av_interleaved_write_frame(m_ctx, &pkt); + + data += fs; + l -= fs; + } + } + + int getBytes(unsigned char *p, int size) + { + //looks like there's no other way to get data from ffmpeg's dynamic buffers apart from closing them + if (m_queue.GetSize() < size && m_init) + { + uint8_t *pb_buffer; + int l = url_close_dyn_buf(m_ctx-> pb, &pb_buffer); + if(l > 0) + { + m_queue.Add(pb_buffer, l); + av_free(pb_buffer); + } + url_open_dyn_buf(&m_ctx->pb); //sets up next dynamic buffer for ffmpeg + } + + int s = min(size, m_queue.GetSize()); + if(s) + { + memcpy(p, m_queue.Get(), s); + m_queue.Advance(s); + m_queue.Compact(); + } + return s; + } + + void close() + { + av_write_trailer(m_ctx); + uint8_t *pb_buffer; + int l = url_close_dyn_buf(m_ctx-> pb, &pb_buffer); + if(l) + { + m_queue.Add(pb_buffer, l); + av_free(pb_buffer); + } + m_init=0; + } + + //useful to get debugging information from ffmpeg + static void ffmpeg_avcodec_log(void *ptr, int val, const char * msg, va_list ap) + { + AVClass* avc= ptr ? *(AVClass**)ptr : NULL; + vprintf(msg, ap); + } + +protected: + int m_init; + + AVFormatContext *m_ctx; + AVStream *m_stream, *m_astream; + AVCodecContext *m_video_enc, *m_audio_enc; + struct SwsContext *m_img_resample_ctx; + AVFrame m_cvtpic; + uint8_t *m_bit_buffer; + int m_bit_buffer_size; + + WDL_Queue m_queue; +}; + +class WDL_VideoDecode +{ +public: + WDL_VideoDecode(const char *fn) + { + m_inited = 0; + m_ctx = NULL; + m_frame = NULL; + m_ic = NULL; + m_sws = NULL; + m_sws_destw=0; + m_sws_desth=0; + m_curtime=-1.0; + + //initialize FFMpeg + { + static int init = 0; + if(!init) av_register_all(); + init = 1; + } + + int ret = av_open_input_file(&m_ic, fn, NULL, 0, NULL); + if (ret < 0) return; + + ret = av_find_stream_info(m_ic); + if (ret < 0) return; + + // find the stream that corresponds to the stream type + int i, stream = -1; + for(i=0; i < (int)m_ic->nb_streams; i++) + { + int st = m_ic->streams[i]->codec->codec_type; + if(st==CODEC_TYPE_VIDEO) + { + stream = i; + break; + } + } + if(stream==-1) return; //no stream found + + m_ctx = m_ic->streams[stream]->codec; + + AVCodec *pCodec = avcodec_find_decoder(m_ctx->codec_id); + if(pCodec == NULL) return; // codec not found + + if(avcodec_open(m_ctx, pCodec)<0) return; // Could not open codec + + AVStream *st = m_ic->streams[stream]; + if(st->r_frame_rate.den && st->r_frame_rate.num) + m_fps = av_q2d(st->r_frame_rate); + else + m_fps = 1/av_q2d(st->codec->time_base); + + m_frame = avcodec_alloc_frame(); + + m_w = m_ctx->width; + m_h = m_ctx->height; + + m_pixfmt=st->codec->pix_fmt; + + if(m_ic->duration == AV_NOPTS_VALUE) + { + //FFmpeg can't get the duration + //approximate the duration of the file with the first packets bitrates + AVStream *st = m_ic->streams[stream]; + int bitrate = 0; + for(i=0; i < (int)m_ic->nb_streams; i++) + { + bitrate += m_ic->streams[i]->codec->bit_rate; + } + bitrate /= 8; + if(bitrate) + m_len = (double)m_ic->file_size/bitrate; + else + m_len = 30; //last resort + } + else + m_len = (double)m_ic->duration/AV_TIME_BASE; + m_stream = stream; + + m_inited = 1; + } + ~WDL_VideoDecode() + { + if(m_frame) av_free(m_frame); + if(m_ic) av_close_input_file(m_ic); + if(m_sws) sws_freeContext(m_sws); + } + int isInited() { return m_inited; } + int GetVideoFrameAtTime(LICE_IBitmap *dst, double atTime, double *startTime, double *endTime, bool resizeToBuf) + { + if(!m_inited) return 0; + if(m_curtime == -1.0 || atTime(1.0/m_fps)) + { + if(avformat_seek_file(m_ic, -1, INT64_MIN, atTime*AV_TIME_BASE, INT64_MAX, AVSEEK_FLAG_BACKWARD) < 0) + { + //fallback to old seeking API + av_seek_frame(m_ic, -1, atTime*AV_TIME_BASE, AVSEEK_FLAG_BACKWARD); + } + avcodec_flush_buffers(m_ctx); + } + + double startpts = -1; + while(1) + { + AVPacket packet; + if(av_read_frame(m_ic, &packet)<0) return 0; //end of file + if(packet.stream_index==m_stream) + { + double packetpts = getPresentationTime(&packet); + if(startpts == -1) startpts = packetpts; + + int frameFinished = 0; + int l = avcodec_decode_video(m_ctx, m_frame, &frameFinished, packet.data, packet.size); + if(l>=0) + { + // Did we get a video frame? + if(frameFinished) + { + double pts = startpts; + double epts = packetpts+(1.0/m_fps); + + if(eptsgetWidth(); + h = dst->getHeight(); + } + else + { + dst->resize(w, h); + } + unsigned int *bits = dst->getBits(); +/*#ifdef _WIN32 + uint8_t *dstd[4]= {(uint8_t *)bits+(dst->getRowSpan()*4*(h-1)),}; + int dst_stride[4]={-dst->getRowSpan()*4,}; +#else*/ + uint8_t *dstd[4]= {(uint8_t *)bits,}; + int dst_stride[4]={dst->getRowSpan()*4,}; +//#endif + + if (!m_sws || m_sws_desth != h || m_sws_destw != w) + { + int sws_flags = SWS_BICUBIC; + PixelFormat pfout = + #ifdef _WIN32 + PIX_FMT_RGB32; + #else + PIX_FMT_BGR32_1; + #endif + if(m_sws) sws_freeContext(m_sws); + m_sws = sws_getContext(m_w, m_h, m_pixfmt, w, h, pfout, sws_flags, NULL, NULL, NULL); + m_sws_desth = h; + m_sws_destw = w; + } + + if (m_sws) + sws_scale(m_sws, m_frame->data, m_frame->linesize, 0, m_h, dstd, dst_stride); + + av_free_packet(&packet); + return 1; + } + } + + av_free_packet(&packet); + } + } + + return 0; + } + +protected: + + double getPresentationTime(AVPacket *packet) + { + double mpts = 0; + if(packet->dts != AV_NOPTS_VALUE) mpts = (double)packet->dts; + mpts *= av_q2d(m_ic->streams[packet->stream_index]->time_base); + mpts -= (double)m_ic->start_time/AV_TIME_BASE; + return mpts; + } + + int m_inited; + + AVFormatContext *m_ic; + AVCodecContext *m_ctx; + + AVFrame *m_frame; + + int m_stream; + + int m_w, m_h, m_format; + double m_fps, m_len; + struct SwsContext *m_sws; + int m_sws_desth, m_sws_destw; + PixelFormat m_pixfmt; + + double m_curtime; +}; + +#endif diff --git a/WDL/fft.c b/WDL/fft.c new file mode 100644 index 00000000..f58ab5df --- /dev/null +++ b/WDL/fft.c @@ -0,0 +1,1647 @@ +/* + WDL - fft.cpp + Copyright (C) 2006 and later Cockos Incorporated + Copyright 1999 D. J. Bernstein + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + + This file implements the WDL FFT library. These routines are based on the + DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com + + The DJB FFT web page is: http://cr.yp.to/djbfft.html + +*/ + + +// this is based on djbfft + +#include +#include "fft.h" + + +#define FFT_MAXBITLEN 15 + +#ifdef _MSC_VER +#define inline __inline +#endif + +#define PI 3.1415926535897932384626433832795 + +static WDL_FFT_COMPLEX d16[3]; +static WDL_FFT_COMPLEX d32[7]; +static WDL_FFT_COMPLEX d64[15]; +static WDL_FFT_COMPLEX d128[31]; +static WDL_FFT_COMPLEX d256[63]; +static WDL_FFT_COMPLEX d512[127]; +static WDL_FFT_COMPLEX d1024[127]; +static WDL_FFT_COMPLEX d2048[255]; +static WDL_FFT_COMPLEX d4096[511]; +static WDL_FFT_COMPLEX d8192[1023]; +static WDL_FFT_COMPLEX d16384[2047]; +static WDL_FFT_COMPLEX d32768[4095]; + + +#define sqrthalf (d16[1].re) + +#define VOL *(volatile WDL_FFT_REAL *)& + +#define TRANSFORM(a0,a1,a2,a3,wre,wim) { \ + t6 = a2.re; \ + t1 = a0.re - t6; \ + t6 += a0.re; \ + a0.re = t6; \ + t3 = a3.im; \ + t4 = a1.im - t3; \ + t8 = t1 - t4; \ + t1 += t4; \ + t3 += a1.im; \ + a1.im = t3; \ + t5 = wre; \ + t7 = t8 * t5; \ + t4 = t1 * t5; \ + t8 *= wim; \ + t2 = a3.re; \ + t3 = a1.re - t2; \ + t2 += a1.re; \ + a1.re = t2; \ + t1 *= wim; \ + t6 = a2.im; \ + t2 = a0.im - t6; \ + t6 += a0.im; \ + a0.im = t6; \ + t6 = t2 + t3; \ + t2 -= t3; \ + t3 = t6 * wim; \ + t7 -= t3; \ + a2.re = t7; \ + t6 *= t5; \ + t6 += t8; \ + a2.im = t6; \ + t5 *= t2; \ + t5 -= t1; \ + a3.im = t5; \ + t2 *= wim; \ + t4 += t2; \ + a3.re = t4; \ + } + +#define TRANSFORMHALF(a0,a1,a2,a3) { \ + t1 = a2.re; \ + t5 = a0.re - t1; \ + t1 += a0.re; \ + a0.re = t1; \ + t4 = a3.im; \ + t8 = a1.im - t4; \ + t1 = t5 - t8; \ + t5 += t8; \ + t4 += a1.im; \ + a1.im = t4; \ + t3 = a3.re; \ + t7 = a1.re - t3; \ + t3 += a1.re; \ + a1.re = t3; \ + t8 = a2.im; \ + t6 = a0.im - t8; \ + t2 = t6 + t7; \ + t6 -= t7; \ + t8 += a0.im; \ + a0.im = t8; \ + t4 = t6 + t5; \ + t3 = sqrthalf; \ + t4 *= t3; \ + a3.re = t4; \ + t6 -= t5; \ + t6 *= t3; \ + a3.im = t6; \ + t7 = t1 - t2; \ + t7 *= t3; \ + a2.re = t7; \ + t2 += t1; \ + t2 *= t3; \ + a2.im = t2; \ + } + +#define TRANSFORMZERO(a0,a1,a2,a3) { \ + t5 = a2.re; \ + t1 = a0.re - t5; \ + t5 += a0.re; \ + a0.re = t5; \ + t8 = a3.im; \ + t4 = a1.im - t8; \ + t7 = a3.re; \ + t6 = t1 - t4; \ + a2.re = t6; \ + t1 += t4; \ + a3.re = t1; \ + t8 += a1.im; \ + a1.im = t8; \ + t3 = a1.re - t7; \ + t7 += a1.re; \ + a1.re = t7; \ + t6 = a2.im; \ + t2 = a0.im - t6; \ + t7 = t2 + t3; \ + a2.im = t7; \ + t2 -= t3; \ + a3.im = t2; \ + t6 += a0.im; \ + a0.im = t6; \ + } + +#define UNTRANSFORM(a0,a1,a2,a3,wre,wim) { \ + t6 = VOL wre; \ + t1 = VOL a2.re; \ + t1 *= t6; \ + t8 = VOL wim; \ + t3 = VOL a2.im; \ + t3 *= t8; \ + t2 = VOL a2.im; \ + t4 = VOL a2.re; \ + t5 = VOL a3.re; \ + t5 *= t6; \ + t7 = VOL a3.im; \ + t1 += t3; \ + t7 *= t8; \ + t5 -= t7; \ + t3 = t5 + t1; \ + t5 -= t1; \ + t2 *= t6; \ + t6 *= a3.im; \ + t4 *= t8; \ + t2 -= t4; \ + t8 *= a3.re; \ + t6 += t8; \ + t1 = a0.re - t3; \ + t3 += a0.re; \ + a0.re = t3; \ + t7 = a1.im - t5; \ + t5 += a1.im; \ + a1.im = t5; \ + t4 = t2 - t6; \ + t6 += t2; \ + t8 = a1.re - t4; \ + t4 += a1.re; \ + a1.re = t4; \ + t2 = a0.im - t6; \ + t6 += a0.im; \ + a0.im = t6; \ + a2.re = t1; \ + a3.im = t7; \ + a3.re = t8; \ + a2.im = t2; \ + } + + +#define UNTRANSFORMHALF(a0,a1,a2,a3) { \ + t6 = sqrthalf; \ + t1 = a2.re; \ + t2 = a2.im - t1; \ + t2 *= t6; \ + t1 += a2.im; \ + t1 *= t6; \ + t4 = a3.im; \ + t3 = a3.re - t4; \ + t3 *= t6; \ + t4 += a3.re; \ + t4 *= t6; \ + t8 = t3 - t1; \ + t7 = t2 - t4; \ + t1 += t3; \ + t2 += t4; \ + t4 = a1.im - t8; \ + a3.im = t4; \ + t8 += a1.im; \ + a1.im = t8; \ + t3 = a1.re - t7; \ + a3.re = t3; \ + t7 += a1.re; \ + a1.re = t7; \ + t5 = a0.re - t1; \ + a2.re = t5; \ + t1 += a0.re; \ + a0.re = t1; \ + t6 = a0.im - t2; \ + a2.im = t6; \ + t2 += a0.im; \ + a0.im = t2; \ + } + +#define UNTRANSFORMZERO(a0,a1,a2,a3) { \ + t2 = a3.im; \ + t3 = a2.im - t2; \ + t2 += a2.im; \ + t1 = a2.re; \ + t4 = a3.re - t1; \ + t1 += a3.re; \ + t5 = a0.re - t1; \ + a2.re = t5; \ + t6 = a0.im - t2; \ + a2.im = t6; \ + t7 = a1.re - t3; \ + a3.re = t7; \ + t8 = a1.im - t4; \ + a3.im = t8; \ + t1 += a0.re; \ + a0.re = t1; \ + t2 += a0.im; \ + a0.im = t2; \ + t3 += a1.re; \ + a1.re = t3; \ + t4 += a1.im; \ + a1.im = t4; \ + } + +#define R(a0,a1,b0,b1,wre,wim) { \ + t1 = a0 - a1; \ + t2 = b0 - b1; \ + t5 = t1 * wim; \ + t6 = t2 * wim; \ + t3 = VOL a0; \ + t1 *= wre; \ + t3 += a1; \ + t2 *= wre; \ + t1 -= t6; \ + t4 = VOL b0; \ + t2 += t5; \ + t4 += b1; \ + a0 = t3; \ + b1 = t2; \ + a1 = t4; \ + b0 = t1; \ + } + +#define RHALF(a0,a1,b0,b1) { \ + t1 = a0 - a1; \ + t2 = b0 - b1; \ + t3 = a0 + a1; \ + t5 = t1 - t2; \ + t1 += t2; \ + t4 = VOL b0; \ + t5 *= sqrthalf; \ + t4 += b1; \ + t1 *= sqrthalf; \ + a0 = t3; \ + b1 = t1; \ + a1 = t4; \ + b0 = t5; \ + } + +#define RZERO(a0,a1,b0,b1) { \ + t1 = a0 - a1; \ + t2 = b0 - b1; \ + t3 = a0 + a1; \ + t4 = b0 + b1; \ + b0 = t1; \ + a0 = t3; \ + b1 = t2; \ + a1 = t4; \ + } + +#define V(a0,a1,b0,b1,wre,wim) { \ + t5 = b0 * wre; \ + t1 = b1 * wim; \ + t6 = b1 * wre; \ + t5 += t1; \ + t3 = b0 * wim; \ + t2 = a0 - t5; \ + t6 -= t3; \ + t5 += a0; \ + t4 = a1 - t6; \ + t6 += a1; \ + a1 = t2; \ + a0 = t5; \ + b1 = t4; \ + b0 = t6; \ + } + +#define VHALF(a0,a1,b0,b1) { \ + t5 = b0 + b1; \ + t6 = b1 - b0; \ + t5 *= sqrthalf; \ + t2 = VOL a0; \ + t6 *= sqrthalf; \ + t2 -= t5; \ + t5 += a0; \ + t4 = a1 - t6; \ + t6 += a1; \ + a1 = t2; \ + a0 = t5; \ + b0 = t6; \ + b1 = t4; \ + } + +#define VZERO(a0,a1,b0,b1) { \ + t1 = a0 + b0; \ + t2 = a0 - b0; \ + t3 = a1 + b1; \ + t4 = a1 - b1; \ + a0 = t1; \ + b0 = t3; \ + a1 = t2; \ + b1 = t4; \ + } + +static void c2(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1; + + t1 = a[1].re; + a[1].re = a[0].re - t1; + a[0].re += t1; + + t1 = a[1].im; + a[1].im = a[0].im - t1; + a[0].im += t1; +} + +static inline void c4(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + t5 = a[2].re; + t1 = a[0].re - t5; + t7 = a[3].re; + t5 += a[0].re; + t3 = a[1].re - t7; + t7 += a[1].re; + t8 = t5 + t7; + a[0].re = t8; + t5 -= t7; + a[1].re = t5; + t6 = a[2].im; + t2 = a[0].im - t6; + t6 += a[0].im; + t5 = a[3].im; + a[2].im = t2 + t3; + t2 -= t3; + a[3].im = t2; + t4 = a[1].im - t5; + a[3].re = t1 + t4; + t1 -= t4; + a[2].re = t1; + t5 += a[1].im; + a[0].im = t6 + t5; + t6 -= t5; + a[1].im = t6; +} + +static void c8(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + t7 = a[4].im; + t4 = a[0].im - t7; + t7 += a[0].im; + a[0].im = t7; + + t8 = a[6].re; + t5 = a[2].re - t8; + t8 += a[2].re; + a[2].re = t8; + + t7 = a[6].im; + a[6].im = t4 - t5; + t4 += t5; + a[4].im = t4; + + t6 = a[2].im - t7; + t7 += a[2].im; + a[2].im = t7; + + t8 = a[4].re; + t3 = a[0].re - t8; + t8 += a[0].re; + a[0].re = t8; + + a[4].re = t3 - t6; + t3 += t6; + a[6].re = t3; + + t7 = a[5].re; + t3 = a[1].re - t7; + t7 += a[1].re; + a[1].re = t7; + + t8 = a[7].im; + t6 = a[3].im - t8; + t8 += a[3].im; + a[3].im = t8; + t1 = t3 - t6; + t3 += t6; + + t7 = a[5].im; + t4 = a[1].im - t7; + t7 += a[1].im; + a[1].im = t7; + + t8 = a[7].re; + t5 = a[3].re - t8; + t8 += a[3].re; + a[3].re = t8; + + t2 = t4 - t5; + t4 += t5; + + t6 = t1 - t4; + t8 = sqrthalf; + t6 *= t8; + a[5].re = a[4].re - t6; + t1 += t4; + t1 *= t8; + a[5].im = a[4].im - t1; + t6 += a[4].re; + a[4].re = t6; + t1 += a[4].im; + a[4].im = t1; + + t5 = t2 - t3; + t5 *= t8; + a[7].im = a[6].im - t5; + t2 += t3; + t2 *= t8; + a[7].re = a[6].re - t2; + t2 += a[6].re; + a[6].re = t2; + t5 += a[6].im; + a[6].im = t5; + + c4(a); +} + +static void c16(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + TRANSFORMZERO(a[0],a[4],a[8],a[12]); + TRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); + TRANSFORMHALF(a[2],a[6],a[10],a[14]); + TRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); + c4(a + 8); + c4(a + 12); + + c8(a); +} + +/* a[0...8n-1], w[0...2n-2]; n >= 2 */ +static void cpass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + register WDL_FFT_COMPLEX *a1; + register WDL_FFT_COMPLEX *a2; + register WDL_FFT_COMPLEX *a3; + + a2 = a + 4 * n; + a1 = a + 2 * n; + a3 = a2 + 2 * n; + --n; + + TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); + TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); + + for (;;) { + TRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); + TRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); + if (!--n) break; + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w += 2; + } +} + +static void c32(register WDL_FFT_COMPLEX *a) +{ + cpass(a,d32,4); + c8(a + 16); + c8(a + 24); + c16(a); +} + +static void c64(register WDL_FFT_COMPLEX *a) +{ + cpass(a,d64,8); + c16(a + 32); + c16(a + 48); + c32(a); +} + +static void c128(register WDL_FFT_COMPLEX *a) +{ + cpass(a,d128,16); + c32(a + 64); + c32(a + 96); + c64(a); +} + +static void c256(register WDL_FFT_COMPLEX *a) +{ + cpass(a,d256,32); + c64(a + 128); + c64(a + 192); + c128(a); +} + +static void c512(register WDL_FFT_COMPLEX *a) +{ + cpass(a,d512,64); + c128(a + 384); + c128(a + 256); + c256(a); +} + +/* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ +static void cpassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + register WDL_FFT_COMPLEX *a1; + register WDL_FFT_COMPLEX *a2; + register WDL_FFT_COMPLEX *a3; + register unsigned int k; + + a2 = a + 4 * n; + a1 = a + 2 * n; + a3 = a2 + 2 * n; + k = n - 2; + + TRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); + TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + + do { + TRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); + TRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w += 2; + } while (k -= 2); + + TRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); + TRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + + k = n - 2; + do { + TRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); + TRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w -= 2; + } while (k -= 2); +} + + +static void c1024(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d1024,128); + c256(a + 768); + c256(a + 512); + c512(a); +} + +static void c2048(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d2048,256); + c512(a + 1536); + c512(a + 1024); + c1024(a); +} + +static void c4096(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d4096,512); + c1024(a + 3072); + c1024(a + 2048); + c2048(a); +} + +static void c8192(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d8192,1024); + c2048(a + 6144); + c2048(a + 4096); + c4096(a); +} + +static void c16384(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d16384,2048); + c4096(a + 8192 + 4096); + c4096(a + 8192); + c8192(a); +} + +static void c32768(register WDL_FFT_COMPLEX *a) +{ + cpassbig(a,d32768,4096); + c8192(a + 16384 + 8192); + c8192(a + 16384); + c16384(a); +} + +#if 0 +static void mulr4(WDL_FFT_REAL *a,WDL_FFT_REAL *b) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + + t1 = a[2] * b[2]; + t2 = a[3] * b[3]; + t3 = a[3] * b[2]; + t4 = a[2] * b[3]; + t5 = a[0] * b[0]; + t6 = a[1] * b[1]; + t1 -= t2; + t3 += t4; + a[0] = t5; + a[1] = t6; + a[2] = t1; + a[3] = t3; +} + +#endif +/* n even, n > 0 */ +void WDL_fft_complexmul(WDL_FFT_COMPLEX *a,WDL_FFT_COMPLEX *b,int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + if (n<2 || (n&1)) return; + + do { + t1 = a[0].re * b[0].re; + t2 = a[0].im * b[0].im; + t3 = a[0].im * b[0].re; + t4 = a[0].re * b[0].im; + t5 = a[1].re * b[1].re; + t6 = a[1].im * b[1].im; + t7 = a[1].im * b[1].re; + t8 = a[1].re * b[1].im; + t1 -= t2; + t3 += t4; + t5 -= t6; + t7 += t8; + a[0].re = t1; + a[1].re = t5; + a[0].im = t3; + a[1].im = t7; + a += 2; + b += 2; + } while (n -= 2); +} + +void WDL_fft_complexmul2(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + if (n<2 || (n&1)) return; + + do { + t1 = a[0].re * b[0].re; + t2 = a[0].im * b[0].im; + t3 = a[0].im * b[0].re; + t4 = a[0].re * b[0].im; + t5 = a[1].re * b[1].re; + t6 = a[1].im * b[1].im; + t7 = a[1].im * b[1].re; + t8 = a[1].re * b[1].im; + t1 -= t2; + t3 += t4; + t5 -= t6; + t7 += t8; + c[0].re = t1; + c[1].re = t5; + c[0].im = t3; + c[1].im = t7; + a += 2; + b += 2; + c += 2; + } while (n -= 2); +} +void WDL_fft_complexmul3(WDL_FFT_COMPLEX *c, WDL_FFT_COMPLEX *a, WDL_FFT_COMPLEX *b, int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + if (n<2 || (n&1)) return; + + do { + t1 = a[0].re * b[0].re; + t2 = a[0].im * b[0].im; + t3 = a[0].im * b[0].re; + t4 = a[0].re * b[0].im; + t5 = a[1].re * b[1].re; + t6 = a[1].im * b[1].im; + t7 = a[1].im * b[1].re; + t8 = a[1].re * b[1].im; + t1 -= t2; + t3 += t4; + t5 -= t6; + t7 += t8; + c[0].re += t1; + c[1].re += t5; + c[0].im += t3; + c[1].im += t7; + a += 2; + b += 2; + c += 2; + } while (n -= 2); +} + + +static inline void u4(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + t1 = VOL a[1].re; + t3 = a[0].re - t1; + t6 = VOL a[2].re; + t1 += a[0].re; + t8 = a[3].re - t6; + t6 += a[3].re; + a[0].re = t1 + t6; + t1 -= t6; + a[2].re = t1; + + t2 = VOL a[1].im; + t4 = a[0].im - t2; + t2 += a[0].im; + t5 = VOL a[3].im; + a[1].im = t4 + t8; + t4 -= t8; + a[3].im = t4; + + t7 = a[2].im - t5; + t5 += a[2].im; + a[1].re = t3 + t7; + t3 -= t7; + a[3].re = t3; + a[0].im = t2 + t5; + t2 -= t5; + a[2].im = t2; +} + +static void u8(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + u4(a); + + t1 = a[5].re; + a[5].re = a[4].re - t1; + t1 += a[4].re; + + t3 = a[7].re; + a[7].re = a[6].re - t3; + t3 += a[6].re; + + t8 = t3 - t1; + t1 += t3; + + t6 = a[2].im - t8; + t8 += a[2].im; + a[2].im = t8; + + t5 = a[0].re - t1; + a[4].re = t5; + t1 += a[0].re; + a[0].re = t1; + + t2 = a[5].im; + a[5].im = a[4].im - t2; + t2 += a[4].im; + + t4 = a[7].im; + a[7].im = a[6].im - t4; + t4 += a[6].im; + + a[6].im = t6; + + t7 = t2 - t4; + t2 += t4; + + t3 = a[2].re - t7; + a[6].re = t3; + t7 += a[2].re; + a[2].re = t7; + + t6 = a[0].im - t2; + a[4].im = t6; + t2 += a[0].im; + a[0].im = t2; + + t6 = sqrthalf; + + t1 = a[5].re; + t2 = a[5].im - t1; + t2 *= t6; + t1 += a[5].im; + t1 *= t6; + t4 = a[7].im; + t3 = a[7].re - t4; + t3 *= t6; + t4 += a[7].re; + t4 *= t6; + + t8 = t3 - t1; + t1 += t3; + t7 = t2 - t4; + t2 += t4; + + t4 = a[3].im - t8; + a[7].im = t4; + t5 = a[1].re - t1; + a[5].re = t5; + t3 = a[3].re - t7; + a[7].re = t3; + t6 = a[1].im - t2; + a[5].im = t6; + + t8 += a[3].im; + a[3].im = t8; + t1 += a[1].re; + a[1].re = t1; + t7 += a[3].re; + a[3].re = t7; + t2 += a[1].im; + a[1].im = t2; +} + +static void u16(register WDL_FFT_COMPLEX *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + u8(a); + u4(a + 8); + u4(a + 12); + + UNTRANSFORMZERO(a[0],a[4],a[8],a[12]); + UNTRANSFORMHALF(a[2],a[6],a[10],a[14]); + UNTRANSFORM(a[1],a[5],a[9],a[13],d16[0].re,d16[0].im); + UNTRANSFORM(a[3],a[7],a[11],a[15],d16[0].im,d16[0].re); +} + +/* a[0...8n-1], w[0...2n-2] */ +static void upass(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + register WDL_FFT_COMPLEX *a1; + register WDL_FFT_COMPLEX *a2; + register WDL_FFT_COMPLEX *a3; + + a2 = a + 4 * n; + a1 = a + 2 * n; + a3 = a2 + 2 * n; + n -= 1; + + UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); + UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); + + for (;;) { + UNTRANSFORM(a[2],a1[2],a2[2],a3[2],w[1].re,w[1].im); + UNTRANSFORM(a[3],a1[3],a2[3],a3[3],w[2].re,w[2].im); + if (!--n) break; + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w += 2; + } +} + +static void u32(register WDL_FFT_COMPLEX *a) +{ + u16(a); + u8(a + 16); + u8(a + 24); + upass(a,d32,4); +} + +static void u64(register WDL_FFT_COMPLEX *a) +{ + u32(a); + u16(a + 32); + u16(a + 48); + upass(a,d64,8); +} + +static void u128(register WDL_FFT_COMPLEX *a) +{ + u64(a); + u32(a + 64); + u32(a + 96); + upass(a,d128,16); +} + +static void u256(register WDL_FFT_COMPLEX *a) +{ + u128(a); + u64(a + 128); + u64(a + 192); + upass(a,d256,32); +} + +static void u512(register WDL_FFT_COMPLEX *a) +{ + u256(a); + u128(a + 256); + u128(a + 384); + upass(a,d512,64); +} + + +/* a[0...8n-1], w[0...n-2]; n even, n >= 4 */ +static void upassbig(register WDL_FFT_COMPLEX *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + register WDL_FFT_COMPLEX *a1; + register WDL_FFT_COMPLEX *a2; + register WDL_FFT_COMPLEX *a3; + register unsigned int k; + + a2 = a + 4 * n; + a1 = a + 2 * n; + a3 = a2 + 2 * n; + k = n - 2; + + UNTRANSFORMZERO(a[0],a1[0],a2[0],a3[0]); + UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].re,w[0].im); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + + do { + UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[1].re,w[1].im); + UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[2].re,w[2].im); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w += 2; + } while (k -= 2); + + UNTRANSFORMHALF(a[0],a1[0],a2[0],a3[0]); + UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[0].im,w[0].re); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + + k = n - 2; + do { + UNTRANSFORM(a[0],a1[0],a2[0],a3[0],w[-1].im,w[-1].re); + UNTRANSFORM(a[1],a1[1],a2[1],a3[1],w[-2].im,w[-2].re); + a += 2; + a1 += 2; + a2 += 2; + a3 += 2; + w -= 2; + } while (k -= 2); +} + + + +static void u1024(register WDL_FFT_COMPLEX *a) +{ + u512(a); + u256(a + 512); + u256(a + 768); + upassbig(a,d1024,128); +} + +static void u2048(register WDL_FFT_COMPLEX *a) +{ + u1024(a); + u512(a + 1024); + u512(a + 1536); + upassbig(a,d2048,256); +} + + +static void u4096(register WDL_FFT_COMPLEX *a) +{ + u2048(a); + u1024(a + 2048); + u1024(a + 3072); + upassbig(a,d4096,512); +} + +static void u8192(register WDL_FFT_COMPLEX *a) +{ + u4096(a); + u2048(a + 4096); + u2048(a + 6144); + upassbig(a,d8192,1024); +} + +static void u16384(register WDL_FFT_COMPLEX *a) +{ + u8192(a); + u4096(a + 8192); + u4096(a + 8192 + 4096); + upassbig(a,d16384,2048); +} + +static void u32768(register WDL_FFT_COMPLEX *a) +{ + u16384(a); + u8192(a + 16384); + u8192(a + 16384 + 8192 ); + upassbig(a,d32768,4096); +} + + +static void __fft_gen(WDL_FFT_COMPLEX *buf, int sz, int isfull) +{ + int x; + double div=PI*0.25/(sz+1.0); + + if (isfull) div*=2.0; + + for (x = 0; x < sz; x ++) + { + buf[x].re = (WDL_FFT_REAL) cos((x+1)*div); + buf[x].im = (WDL_FFT_REAL) sin((x+1)*div); + } +} + +#ifndef WDL_FFT_NO_PERMUTE + +static unsigned int fftfreq_c(unsigned int i,unsigned int n) +{ + unsigned int m; + + if (n <= 2) return i; + + m = n >> 1; + if (i < m) return fftfreq_c(i,m) << 1; + + i -= m; + m >>= 1; + if (i < m) return (fftfreq_c(i,m) << 2) + 1; + i -= m; + return ((fftfreq_c(i,m) << 2) - 1) & (n - 1); +} + +static int _idxperm[2<= 8 */ +void WDL_fft_realmul(WDL_FFT_REAL *a,WDL_FFT_REAL *b,int n) +{ + if (n<8 || (n&3)) return; + mulr4(a,b); + WDL_fft_complexmul((WDL_FFT_COMPLEX *)(a + 4),(WDL_FFT_COMPLEX *)(b + 4),(n - 4) / 2); +} + + + + +//////////// begin WDL_FFT_REAL modes +static void r2(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2; + + t1 = a[0] + a[1]; + t2 = a[0] - a[1]; + a[0] = t1; + a[1] = t2; +} + +static void r4(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t6; + + t3 = a[0] + a[1]; + t4 = a[2] + a[3]; + t1 = a[0] - a[1]; + t2 = a[2] - a[3]; + t6 = t3 - t4; + t3 += t4; + a[2] = t1; + a[3] = t2; + a[0] = t3; + a[1] = t6; +} + +static void r8(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + t2 = a[0] + a[1]; + t8 = a[4] + a[5]; + t3 = a[2] - a[3]; + t6 = t2 - t8; + t2 += t8; + t1 = a[2] + a[3]; + t7 = a[6] + a[7]; + a[2] = t6; + t5 = t1 - t7; + t1 += t7; + t4 = a[0] - a[1]; + a[3] = t5; + t8 = t2 - t1; + t2 += t1; + t7 = a[6] - a[7]; + a[1] = t8; + t6 = t3 - t7; + t3 += t7; + a[0] = t2; + t6 *= sqrthalf; + t8 = a[4] - a[5]; + t3 *= sqrthalf; + t1 = t4 - t6; + t4 += t6; + t2 = t8 - t3; + t8 += t3; + a[6] = t1; + a[4] = t4; + a[7] = t2; + a[5] = t8; +} + +/* a[0...8n-1], w[0...2n-1]; n even, n >= 4 */ +static void rpass(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + register WDL_FFT_REAL *b; + register unsigned int k; + + b = a + 4 * n; + k = n - 2; + + RZERO(a[0],a[1],b[0],b[1]); + R(a[2],a[3],b[2],b[3],w[0].re,w[0].im); + R(a[4],a[5],b[4],b[5],w[1].re,w[1].im); + R(a[6],a[7],b[6],b[7],w[2].re,w[2].im); + + for (;;) { + R(a[8],a[9],b[8],b[9],w[3].re,w[3].im); + R(a[10],a[11],b[10],b[11],w[4].re,w[4].im); + R(a[12],a[13],b[12],b[13],w[5].re,w[5].im); + R(a[14],a[15],b[14],b[15],w[6].re,w[6].im); + if (!(k -= 2)) break; + a += 8; + b += 8; + w += 4; + } +} + +static void r16(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + + RZERO(a[0],a[1],a[8],a[9]); + R(a[2],a[3],a[10],a[11],d16[0].re,d16[0].im); + R(a[4],a[5],a[12],a[13],d16[1].re,d16[1].im); + R(a[6],a[7],a[14],a[15],d16[2].re,d16[2].im); + r8(a); + c4((WDL_FFT_COMPLEX *)(a + 8)); +} + +static void r32(register WDL_FFT_REAL *a) +{ + rpass(a,d32,4); + r16(a); + c8((WDL_FFT_COMPLEX *)(a + 16)); +} + +static void r64(register WDL_FFT_REAL *a) +{ + rpass(a,d64,8); + r32(a); + c16((WDL_FFT_COMPLEX *)(a + 32)); +} + +static void r128(register WDL_FFT_REAL *a) +{ + rpass(a,d128,16); + r64(a); + c32((WDL_FFT_COMPLEX *)(a + 64)); +} + +static void r256(register WDL_FFT_REAL *a) +{ + rpass(a,d256,32); + r128(a); + c64((WDL_FFT_COMPLEX *)(a + 128)); +} + +static void r512(register WDL_FFT_REAL *a) +{ + rpass(a,d512,64); + r256(a); + c128((WDL_FFT_COMPLEX *)(a + 256)); +} + + +/* a[0...8n-1], w[0...n-1]; n even, n >= 8 */ +static void rpassbig(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + register WDL_FFT_REAL *b; + register unsigned int k; + + b = a + 4 * n; + + RZERO(a[0],a[1],b[0],b[1]); + R(a[2],a[3],b[2],b[3],w[0].re,w[0].im); + + k = n - 2; + do { + R(a[4],a[5],b[4],b[5],w[1].re,w[1].im); + R(a[6],a[7],b[6],b[7],w[2].re,w[2].im); + a += 4; + b += 4; + w += 2; + } while (k -= 2); + + RHALF(a[4],a[5],b[4],b[5]); + R(a[6],a[7],b[6],b[7],w[0].im,w[0].re); + + k = n - 2; + do { + R(a[8],a[9],b[8],b[9],w[-1].im,w[-1].re); + R(a[10],a[11],b[10],b[11],w[-2].im,w[-2].re); + a += 4; + b += 4; + w -= 2; + } while (k -= 2); +} + + +static void r1024(register WDL_FFT_REAL *a) +{ + rpassbig(a,d1024,128); + r512(a); + c256((WDL_FFT_COMPLEX *)(a + 512)); +} + +static void r2048(register WDL_FFT_REAL *a) +{ + rpassbig(a,d2048,256); + r1024(a); + c512((WDL_FFT_COMPLEX *)(a + 1024)); +} + + +static void r4096(register WDL_FFT_REAL *a) +{ + rpassbig(a,d4096,512); + r2048(a); + c1024((WDL_FFT_COMPLEX *)(a + 2048)); +} + +static void r8192(register WDL_FFT_REAL *a) +{ + rpassbig(a,d8192,1024); + r4096(a); + c2048((WDL_FFT_COMPLEX *)(a + 4096)); +} + +static void r16384(register WDL_FFT_REAL *a) +{ + rpassbig(a,d16384,2048); + r8192(a); + c4096((WDL_FFT_COMPLEX *)(a + 8192)); +} + +static void r32768(register WDL_FFT_REAL *a) +{ + rpassbig(a,d32768,4096); + r16384(a); + c8192((WDL_FFT_COMPLEX *)(a + 16384)); +} + + + +static void v4(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t3, t5, t6; + + t5 = a[0] + a[1]; + t6 = a[0] - a[1]; + t1 = t5 + a[2]; + t5 -= a[2]; + t3 = t6 + a[3]; + t6 -= a[3]; + a[0] = t1; + a[1] = t5; + a[2] = t3; + a[3] = t6; +} + +static void v8(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6, t7, t8; + + t5 = a[0] + a[1]; + t2 = a[4] + a[6]; + t8 = t5 + a[2]; + t5 -= a[2]; + t1 = a[0] - a[1]; + t7 = t8 + t2; + t8 -= t2; + t3 = a[4] - a[6]; + a[0] = t7; + t6 = a[5] + a[7]; + a[1] = t8; + t7 = t5 + t6; + t5 -= t6; + t4 = a[5] - a[7]; + a[4] = t7; + t6 = t4 - t3; + t3 += t4; + a[5] = t5; + t3 *= sqrthalf; + t2 = t1 + a[3]; + t1 -= a[3]; + t6 *= sqrthalf; + t7 = t2 - t3; + t3 += t2; + t8 = t1 - t6; + t6 += t1; + a[3] = t7; + a[7] = t8; + a[2] = t3; + a[6] = t6; +} + +/* a[0...8n-1], w[0...2n-1]; n even, n >= 4 */ +static void vpass(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + register WDL_FFT_REAL *b; + register unsigned int k; + + b = a + 4 * n; + k = n - 2; + + VZERO(a[0],a[1],b[0],b[1]); + V(a[2],a[3],b[2],b[3],w[0].re,w[0].im); + V(a[4],a[5],b[4],b[5],w[1].re,w[1].im); + V(a[6],a[7],b[6],b[7],w[2].re,w[2].im); + + for (;;) { + V(a[8],a[9],b[8],b[9],w[3].re,w[3].im); + V(a[10],a[11],b[10],b[11],w[4].re,w[4].im); + V(a[12],a[13],b[12],b[13],w[5].re,w[5].im); + V(a[14],a[15],b[14],b[15],w[6].re,w[6].im); + if (!(k -= 2)) break; + a += 8; + b += 8; + w += 4; + } +} + +static void v16(register WDL_FFT_REAL *a) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + + u4((WDL_FFT_COMPLEX *)(a + 8)); + v8(a); + VZERO(a[0],a[1],a[8],a[9]); + V(a[2],a[3],a[10],a[11],d16[0].re,d16[0].im); + V(a[4],a[5],a[12],a[13],d16[1].re,d16[1].im); + V(a[6],a[7],a[14],a[15],d16[2].re,d16[2].im); +} + +static void v32(register WDL_FFT_REAL *a) +{ + u8((WDL_FFT_COMPLEX *)(a + 16)); + v16(a); + vpass(a,d32,4); +} + +static void v64(register WDL_FFT_REAL *a) +{ + u16((WDL_FFT_COMPLEX *)(a + 32)); + v32(a); + vpass(a,d64,8); +} + +static void v128(register WDL_FFT_REAL *a) +{ + u32((WDL_FFT_COMPLEX *)(a + 64)); + v64(a); + vpass(a,d128,16); +} + +static void v256(register WDL_FFT_REAL *a) +{ + u64((WDL_FFT_COMPLEX *)(a + 128)); + v128(a); + vpass(a,d256,32); +} + +static void v512(register WDL_FFT_REAL *a) +{ + u128((WDL_FFT_COMPLEX *)(a + 256)); + v256(a); + vpass(a,d512,64); +} + + + +/* a[0...8n-1], w[0...n-1]; n even, n >= 8 */ +static void vpassbig(register WDL_FFT_REAL *a,register const WDL_FFT_COMPLEX *w,register unsigned int n) +{ + register WDL_FFT_REAL t1, t2, t3, t4, t5, t6; + register WDL_FFT_REAL *b; + register unsigned int k; + + b = a + 4 * n; + + VZERO(a[0],a[1],b[0],b[1]); + V(a[2],a[3],b[2],b[3],w[0].re,w[0].im); + + k = n - 2; + do { + V(a[4],a[5],b[4],b[5],w[1].re,w[1].im); + V(a[6],a[7],b[6],b[7],w[2].re,w[2].im); + a += 4; + b += 4; + w += 2; + } while (k -= 2); + + VHALF(a[4],a[5],b[4],b[5]); + V(a[6],a[7],b[6],b[7],w[0].im,w[0].re); + + k = n - 2; + do { + V(a[8],a[9],b[8],b[9],w[-1].im,w[-1].re); + V(a[10],a[11],b[10],b[11],w[-2].im,w[-2].re); + a += 4; + b += 4; + w -= 2; + } while (k -= 2); +} + + +static void v1024(register WDL_FFT_REAL *a) +{ + u256((WDL_FFT_COMPLEX *)(a + 512)); + v512(a); + vpassbig(a,d1024,128); +} + +static void v2048(register WDL_FFT_REAL *a) +{ + u512((WDL_FFT_COMPLEX *)(a + 1024)); + v1024(a); + vpassbig(a,d2048,256); +} + + +static void v4096(register WDL_FFT_REAL *a) +{ + u1024((WDL_FFT_COMPLEX *)(a + 2048)); + v2048(a); + vpassbig(a,d4096,512); +} + +static void v8192(register WDL_FFT_REAL *a) +{ + u2048((WDL_FFT_COMPLEX *)(a + 4096)); + v4096(a); + vpassbig(a,d8192,1024); +} + +static void v16384(register WDL_FFT_REAL *a) +{ + u4096((WDL_FFT_COMPLEX *)(a + 8192)); + v8192(a); + vpassbig(a,d16384,2048); +} + +static void v32768(register WDL_FFT_REAL *a) +{ + u8192((WDL_FFT_COMPLEX *)(a + 16384)); + v16384(a); + vpassbig(a,d32768,4096); +} + + +void WDL_real_fft(WDL_FFT_REAL *buf, int len, int isInverse) +{ + switch (len) + { + case 2: r2(buf); break; +#define TMP(x) case x: if (!isInverse) r##x(buf); else v##x(buf); break; + TMP(4) + TMP(8) + TMP(16) + TMP(32) + TMP(64) + TMP(128) + TMP(256) + TMP(512) + TMP(1024) + TMP(2048) + TMP(4096) + TMP(8192) + TMP(16384) + TMP(32768) +#undef TMP + } +} + +#endif diff --git a/WDL/fft.h b/WDL/fft.h new file mode 100644 index 00000000..0d2dc9b2 --- /dev/null +++ b/WDL/fft.h @@ -0,0 +1,73 @@ +/* + WDL - fft.h + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + + This file defines the interface to the WDL FFT library. These routines are based on the + DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com + + The DJB FFT web page is: http://cr.yp.to/djbfft.html + +*/ + +#ifndef _WDL_FFT_H_ +#define _WDL_FFT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WDL_FFT_REALSIZE +#define WDL_FFT_REALSIZE 4 +#endif + +#if WDL_FFT_REALSIZE == 4 +typedef float WDL_FFT_REAL; +#elif WDL_FFT_REALSIZE == 8 +typedef double WDL_FFT_REAL; +#else +#error invalid FFT item size +#endif + +typedef struct { + WDL_FFT_REAL re; + WDL_FFT_REAL im; +} WDL_FFT_COMPLEX; + +extern void WDL_fft_init(); + +extern void WDL_fft_complexmul(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, int len); +extern void WDL_fft_complexmul2(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); +extern void WDL_fft_complexmul3(WDL_FFT_COMPLEX *destAdd, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len); + +extern void WDL_fft(WDL_FFT_COMPLEX *, int len, int isInverse); + +#if 0 // these dont work right! +extern void WDL_fft_realmul(WDL_FFT_REAL *dest, WDL_FFT_REAL *src, int len); +extern void WDL_real_fft(WDL_FFT_REAL *, int len, int isInverse); +#endif + +int WDL_fft_permute(int fftsize, int idx); + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/WDL/filebrowse.cpp b/WDL/filebrowse.cpp new file mode 100644 index 00000000..57bd7134 --- /dev/null +++ b/WDL/filebrowse.cpp @@ -0,0 +1,380 @@ +// todo: support win7/vista extensions rather than GetOpenFileName? -- merge win7filedialog into here. + + +#include "filebrowse.h" + +#include "win32_utf8.h" +#include "wdlcstring.h" + + +#ifdef _WIN32 + #define PREF_DIRCH '\\' + #ifdef _MSC_VER // todo: win7filedialog.cpp support for mingw32 + #define WDL_FILEBROWSE_WIN7VISTAMODE + #endif +#else + #define PREF_DIRCH '/' +#endif + + + + +#ifdef WDL_FILEBROWSE_WIN7VISTAMODE // win7/vista file dialog support + #include "win7filedialog.cpp" + + // stuff since win7filedialog.h collides with shlobj.h below + #define tagSHCONTF tagSHCONTF___ + #define SHCONTF SHCONTF___ + #define SHCONTF_FOLDERS SHCONTF_FOLDERS___ + #define SHCONTF_NONFOLDERS SHCONTF_NONFOLDERS___ + #define SHCONTF_INCLUDEHIDDEN SHCONTF_INCLUDEHIDDEN___ + #define SHCONTF_SHAREABLE SHCONTF_SHAREABLE__ + #define SHCONTF_INIT_ON_FIRST_NEXT SHCONTF_INIT_ON_FIRST_NEXT__ + #define SHCONTF_NETPRINTERSRCH SHCONTF_NETPRINTERSRCH__ + #define SHCONTF_STORAGE SHCONTF_STORAGE__ +#endif + + +#ifdef _WIN32 +// include after win7filedialog.* + + #include + #include +#endif + +#ifndef BIF_NEWDIALOGSTYLE + #define BIF_NEWDIALOGSTYLE 0x40 +#endif + + +static void WDL_fixfnforopenfn(char *buf) +{ + char *p=buf; + while (*p) + { + if (*p == '/' || *p == '\\') *p=PREF_DIRCH; + p++; + } +#ifdef _WIN32 + if (buf[0] && buf[1] == ':') + { + p=buf+2; + char *op=p; + while (*p) + { + while (p[0]=='\\' && p[1] == '\\') p++; + *op++ = *p++; + } + *op=0; + } +#endif +} + + +#ifdef _WIN32 +static int CALLBACK WINAPI WDL_BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + switch (uMsg) + { + case BFFM_INITIALIZED: + if (lpData && ((char *)lpData)[0]) SendMessage(hwnd,BFFM_SETSELECTION,1,(LPARAM)lpData); + break; + } + return 0; +} +#endif + + +bool WDL_ChooseDirectory(HWND parent, const char *text, const char *initialdir, char *fn, int fnsize, bool preservecwd) +{ + char olddir[2048]; + GetCurrentDirectory(sizeof(olddir),olddir); +#ifdef _WIN32 + char name[4096]; + lstrcpyn_safe(name,initialdir?initialdir:"",sizeof(name)); + BROWSEINFO bi={parent,NULL, name, text, BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE, WDL_BrowseCallbackProc, (LPARAM)name,}; + LPITEMIDLIST idlist = SHBrowseForFolder( &bi ); + if (idlist) + { + SHGetPathFromIDList( idlist, name ); + IMalloc *m; + SHGetMalloc(&m); + m->Free(idlist); + lstrcpyn_safe(fn,name,fnsize); + return true; + } + return false; + +#else + bool r = BrowseForDirectory(text,initialdir,fn,fnsize); + if (preservecwd) SetCurrentDirectory(olddir); + return r; +#endif +} + +static const char *stristr(const char* a, const char* b) +{ + int i; + int len = strlen(b); + int n = strlen(a)-len; + for (i = 0; i <= n; ++i) + if (!strnicmp(a+i, b, len)) + return a+i; + return NULL; +} + +bool WDL_ChooseFileForSave(HWND parent, + const char *text, + const char *initialdir, + const char *initialfile, + const char *extlist, + const char *defext, + bool preservecwd, + char *fn, + int fnsize, + const char *dlgid, + void *dlgProc, +#ifdef _WIN32 + HINSTANCE hInstance +#else + struct SWELL_DialogResourceIndex *reshead +#endif + ) +{ + char cwd[2048]; + GetCurrentDirectory(sizeof(cwd),cwd); + +#ifdef _WIN32 + char temp[4096]; + memset(temp,0,sizeof(temp)); + if (initialfile) lstrcpyn_safe(temp,initialfile,sizeof(temp)); + WDL_fixfnforopenfn(temp); + +#ifdef WDL_FILEBROWSE_WIN7VISTAMODE + { + Win7FileDialog fd(text, 1); + if(fd.inited()) + { + fd.addOptions(FOS_DONTADDTORECENT); + //vista+ file open dialog + char olddir[2048]; + GetCurrentDirectory(sizeof(olddir),olddir); + + fd.setFilterList(extlist); + if (defext) + { + fd.setDefaultExtension(defext); + + int i = 0; + const char *p = extlist; + while(*p) + { + if(*p) p+=strlen(p)+1; + if(!*p) break; + if(stristr(p, defext)) + { + fd.setFileTypeIndex(i+1); + break; + } + i++; + p+=strlen(p)+1; + } + } + fd.setFolder(initialdir?initialdir:olddir, 0); + if(initialfile) + { + //check for folder name + char *p = temp+strlen(temp); + while(p>temp && *p!='/' && *p!='\\') p--; + if(*p=='/'||*p=='\\') + { + //folder found + *p=0; + fd.setFolder(temp, 0); + fd.setFilename(p+1); + } + else + fd.setFilename(temp); + } + fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); + + if(fd.show(parent)) + { + //ifilesavedialog saves the last folder automatically + fd.getResult(fn, fnsize); + + if (preservecwd) SetCurrentDirectory(olddir); + return true; + } + + if (preservecwd) SetCurrentDirectory(olddir); + return NULL; + } + } +#endif + + + OPENFILENAME l={sizeof(l),parent, hInstance, extlist, NULL,0, 0, temp, sizeof(temp)-1, NULL, 0, initialdir&&initialdir[0] ? initialdir : cwd, text, + OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT,0,0,defext, 0, (LPOFNHOOKPROC)dlgProc, dlgid}; + + if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; + if (preservecwd) l.Flags |= OFN_NOCHANGEDIR; + + if (!GetSaveFileName(&l)||!temp[0]) + { + if (preservecwd) SetCurrentDirectory(cwd); + return false; + } + if (preservecwd) SetCurrentDirectory(cwd); + lstrcpyn_safe(fn,temp,fnsize); + return true; + +#else + BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); + char if_temp[4096]; + if (initialfile) + { + lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); + WDL_fixfnforopenfn(if_temp); + initialfile = if_temp; + } + + bool r = BrowseForSaveFile(text,initialdir,initialfile,extlist,fn,fnsize); + + if (preservecwd) SetCurrentDirectory(cwd); + + return r; +#endif +} + + +char *WDL_ChooseFileForOpen(HWND parent, + const char *text, + const char *initialdir, + const char *initialfile, + const char *extlist, + const char *defext, + + bool preservecwd, + bool allowmul, + + const char *dlgid, + void *dlgProc, +#ifdef _WIN32 + HINSTANCE hInstance +#else + struct SWELL_DialogResourceIndex *reshead +#endif + ) +{ + char olddir[2048]; + GetCurrentDirectory(sizeof(olddir),olddir); + +#ifdef _WIN32 + +#ifdef WDL_FILEBROWSE_WIN7VISTAMODE + if (!allowmul) // todo : check impl of multiple select, too? + { + Win7FileDialog fd(text); + if(fd.inited()) + { + //vista+ file open dialog + fd.addOptions(FOS_FILEMUSTEXIST); + fd.setFilterList(extlist); + if (defext) + { + fd.setDefaultExtension(defext); + + int i = 0; + const char *p = extlist; + while(*p) + { + if(*p) p+=strlen(p)+1; + if(!*p) break; + if(stristr(p, defext)) + { + fd.setFileTypeIndex(i+1); + break; + } + i++; + p+=strlen(p)+1; + } + } + fd.setFolder(initialdir?initialdir:olddir, 0); + fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); + if(initialfile) + { + char temp[4096]; + lstrcpyn_safe(temp,initialfile,sizeof(temp)); + //check for folder name + char *p = temp+strlen(temp); + while(p>temp && *p!='/' && *p!='\\') p--; + if(*p=='/'||*p=='\\') + { + //folder found + *p=0; + fd.setFolder(temp, 0); + fd.setFilename(p+1); + } + else + fd.setFilename(temp); + } + + if(fd.show(parent)) + { + char temp[4096]; + temp[0]=0; + //ifileopendialog saves the last folder automatically + fd.getResult(temp, sizeof(temp)-1); + + + + if (preservecwd) SetCurrentDirectory(olddir); + return temp[0] ? strdup(temp) : NULL; + } + + if (preservecwd) SetCurrentDirectory(olddir); + return NULL; + } + } +#endif + + int temp_size = allowmul ? 256*1024-1 : 4096-1; + char *temp = (char *)calloc(temp_size+1,1); + + OPENFILENAME l={sizeof(l), parent, hInstance, extlist, NULL, 0, 0, temp, temp_size, NULL, 0, initialdir, text, + OFN_HIDEREADONLY|OFN_EXPLORER|OFN_FILEMUSTEXIST,0,0, (char *)(defext ? defext : ""), 0, (LPOFNHOOKPROC)dlgProc, dlgid}; + + if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; + if (allowmul) l.Flags|=OFN_ALLOWMULTISELECT; + if (preservecwd) l.Flags|=OFN_NOCHANGEDIR; + + if (initialfile) lstrcpyn_safe(temp,initialfile,temp_size); + + WDL_fixfnforopenfn(temp); + + if (!l.lpstrInitialDir||!l.lpstrInitialDir[0]) l.lpstrInitialDir=olddir; + + int r = GetOpenFileName(&l); + if (preservecwd) SetCurrentDirectory(olddir); + + if (!r) free(temp); + return r?temp:NULL; + +#else + char if_temp[4096]; + if (initialfile) + { + lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); + WDL_fixfnforopenfn(if_temp); + initialfile = if_temp; + } + + // defext support? + BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); + char *ret = BrowseForFiles(text,initialdir,initialfile,allowmul,extlist); + if (preservecwd) SetCurrentDirectory(olddir); + + return ret; +#endif +} diff --git a/WDL/filebrowse.h b/WDL/filebrowse.h new file mode 100644 index 00000000..642c254f --- /dev/null +++ b/WDL/filebrowse.h @@ -0,0 +1,52 @@ +#ifndef _WDL_FILEBROWSE_H_ +#define _WDL_FILEBROWSE_H_ + +#ifdef _WIN32 +#include +#else +#include "swell/swell.h" +#endif + + +bool WDL_ChooseDirectory(HWND parent, const char *text, const char *initialdir, char *fn, int fnsize, bool preservecwd); +bool WDL_ChooseFileForSave(HWND parent, + const char *text, + const char *initialdir, + const char *initialfile, + const char *extlist, + const char *defext, + bool preservecwd, + char *fn, + int fnsize, + const char *dlgid=NULL, + void *dlgProc=NULL, +#ifdef _WIN32 + HINSTANCE hInstance=NULL +#else + struct SWELL_DialogResourceIndex *reshead=NULL +#endif + ); + + +char *WDL_ChooseFileForOpen(HWND parent, + const char *text, + const char *initialdir, + const char *initialfile, + const char *extlist, + const char *defext, + + bool preservecwd, + bool allowmul, + + const char *dlgid=NULL, + void *dlgProc=NULL, +#ifdef _WIN32 + HINSTANCE hInstance=NULL +#else + struct SWELL_DialogResourceIndex *reshead=NULL +#endif + ); + + + +#endif \ No newline at end of file diff --git a/WDL/filename.h b/WDL/filename.h new file mode 100644 index 00000000..763de3d1 --- /dev/null +++ b/WDL/filename.h @@ -0,0 +1,65 @@ +/* + WDL - filename.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _WDL_FILENAME_H_ +#define _WDL_FILENAME_H_ + +#include +#include + + +char WDL_filename_filterchar(char p, char repl='_', bool filterSlashes=true) +{ + if (p == '?' || + p == '*' || + p == ':' || + p == '\"' || + p == '|' || + p == '<' || + p == '>') + { + return repl; + } + + if (filterSlashes && (p == '/' || p == '\\' )) + { + return repl; + } + + return p; +} + + +void WDL_filename_filterstr(char *buf, char repl='_', bool filterSlashes=true) +{ + char *rd = buf; + while (*rd) + { + char r=WDL_filename_filterchar(*rd++,repl,filterSlashes); + if (r) *buf++ = r; + } + *buf=0; +} + + + +#endif // _WDL_FILENAME_H_ \ No newline at end of file diff --git a/WDL/fileread.h b/WDL/fileread.h new file mode 100644 index 00000000..77960515 --- /dev/null +++ b/WDL/fileread.h @@ -0,0 +1,796 @@ +/* + WDL - fileread.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides the WDL_FileRead object, which can be used to read files. + On windows systems it supports reading synchronous, asynchronous, memory mapped, and asynchronous unbuffered. + On non-windows systems it acts as a wrapper for fopen()/etc. + + +*/ + + +#ifndef _WDL_FILEREAD_H_ +#define _WDL_FILEREAD_H_ + + + + +#include "ptrlist.h" + + + +#if defined(_WIN32) && !defined(WDL_NO_WIN32_FILEREAD) + #ifndef WDL_WIN32_NATIVE_READ + #define WDL_WIN32_NATIVE_READ + #endif +#else + #ifdef WDL_WIN32_NATIVE_READ + #undef WDL_WIN32_NATIVE_READ + #endif + + #if !defined(WDL_NO_POSIX_FILEREAD) + #define WDL_POSIX_NATIVE_READ + #include + #include + #include + #include + #ifdef __APPLE__ + #include + #include + #endif + #endif + +#endif + + + +#ifdef _MSC_VER +#define WDL_FILEREAD_POSTYPE __int64 +#else +#define WDL_FILEREAD_POSTYPE long long +#endif +class WDL_FileRead +{ + +#ifdef WDL_WIN32_NATIVE_READ + + +class WDL_FileRead__ReadEnt +{ +public: + WDL_FileRead__ReadEnt(int sz, char *buf) + { + m_size=0; + memset(&m_ol,0,sizeof(m_ol)); + m_ol.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL); + m_buf=buf; + } + ~WDL_FileRead__ReadEnt() + { + CloseHandle(m_ol.hEvent); + } + + OVERLAPPED m_ol; + DWORD m_size; + LPVOID m_buf; +}; + +#endif + +#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) + BOOL HasUTF8(const char *_str) + { + const unsigned char *str = (const unsigned char *)_str; + if (!str) return FALSE; + while (*str) + { + unsigned char c = *str; + if (c >= 0xC2) + { + if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; + else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + } + str++; + } + return FALSE; + } +#endif + +public: + // allow_async=1 for unbuffered async, 2 for buffered async, =-1 for unbuffered sync + // async aspect is unused on OS X, but the buffered mode affects F_NOCACHE + WDL_FileRead(const char *filename, int allow_async=1, int bufsize=8192, int nbufs=4, unsigned int mmap_minsize=0, unsigned int mmap_maxsize=0) : m_bufspace(4096 WDL_HEAPBUF_TRACEPARM("WDL_FileRead")) + { + m_async_hashaderr=false; + m_sync_bufmode_used=m_sync_bufmode_pos=0; + m_async_readpos=m_file_position=0; + m_fsize=0; + m_fsize_maychange=false; + m_syncrd_firstbuf=true; + m_mmap_view=0; + m_mmap_totalbufmode=0; + +#define WDL_UNBUF_ALIGN 8192 + if (bufsize&(WDL_UNBUF_ALIGN-1)) bufsize=(bufsize&~(WDL_UNBUF_ALIGN-1))+WDL_UNBUF_ALIGN; // ensure bufsize is multiple of 4kb + +#ifdef WDL_WIN32_NATIVE_READ + + m_mmap_fmap=0; + bool isNT = GetVersion()<0x80000000; + m_async = isNT ? allow_async : 0; + + int flags=FILE_ATTRIBUTE_NORMAL; + if (m_async>0) + { + flags|=FILE_FLAG_OVERLAPPED; + if (m_async==1) flags|=FILE_FLAG_NO_BUFFERING; + } + else if (nbufs*bufsize>=WDL_UNBUF_ALIGN && !mmap_maxsize && m_async==-1) + flags|=FILE_FLAG_NO_BUFFERING; // non-async mode unbuffered if we do our own buffering + +#ifndef WDL_NO_SUPPORT_UTF8 + m_fh = INVALID_HANDLE_VALUE; + if (isNT && HasUTF8(filename)) // only convert to wide if there are UTF-8 chars + { + int szreq=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,NULL,0); + if (szreq > 1000) + { + WDL_TypedBuf wfilename; + wfilename.Resize(szreq+10); + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename.Get(),wfilename.GetSize())) + { + m_fh = CreateFileW(wfilename.Get(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); + if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) + { + m_fh = CreateFileW(wfilename.Get(),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); + m_fsize_maychange=true; + } + } + } + else + { + WCHAR wfilename[1024]; + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename,1024)) + { + m_fh = CreateFileW(wfilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); + if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) + { + m_fh = CreateFileW(wfilename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); + m_fsize_maychange=true; + } + } + } + } + if (m_fh == INVALID_HANDLE_VALUE) +#endif + { + m_fh = CreateFileA(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL); + if (m_fh == INVALID_HANDLE_VALUE && GetLastError()==ERROR_SHARING_VIOLATION) + { + m_fh = CreateFileA(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,flags,NULL); + m_fsize_maychange=true; + } + } + + if (m_fh != INVALID_HANDLE_VALUE) + { + DWORD h=0; + DWORD l=GetFileSize(m_fh,&h); + m_fsize=(((WDL_FILEREAD_POSTYPE)h)<<32)|l; + + if (!h && l < mmap_maxsize && m_async<=0) + { + if (l >= mmap_minsize) + { + m_mmap_fmap=CreateFileMapping(m_fh,NULL,PAGE_READONLY,NULL,0,NULL); + if (m_mmap_fmap) + { + m_mmap_view=MapViewOfFile(m_mmap_fmap,FILE_MAP_READ,0,0,(int)m_fsize); + if (!m_mmap_view) + { + CloseHandle(m_mmap_fmap); + m_mmap_fmap=0; + } + else m_fsize_maychange=false; + } + } + else if (l>0) + { + m_mmap_totalbufmode = malloc(l); + DWORD sz; + ReadFile(m_fh,m_mmap_totalbufmode,l,&sz,NULL); + m_fsize_maychange=false; + } + } + + if (m_async>0) + { + m_async_bufsize=bufsize; + int x; + char *bptr=(char *)m_bufspace.Resize(nbufs*bufsize + (WDL_UNBUF_ALIGN-1)); + int a=((int)(INT_PTR)bptr)&(WDL_UNBUF_ALIGN-1); + if (a) bptr += WDL_UNBUF_ALIGN-a; + for (x = 0; x < nbufs; x ++) + { + WDL_FileRead__ReadEnt *t=new WDL_FileRead__ReadEnt(m_async_bufsize,bptr); + m_empties.Add(t); + bptr+=m_async_bufsize; + } + } + else if (!m_mmap_view && !m_mmap_totalbufmode && nbufs*bufsize>=WDL_UNBUF_ALIGN) + { + m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); + } + } + +#elif defined(WDL_POSIX_NATIVE_READ) + m_filedes_locked=false; + m_filedes_rdpos=0; + m_filedes=open(filename,O_RDONLY); + if (m_filedes>=0) + { + if (flock(m_filedes,LOCK_SH|LOCK_NB)>=0) // get shared lock + m_filedes_locked=true; + else + m_fsize_maychange=true; // if couldnt get shared lock, then it may change + +#ifdef __APPLE__ + if (allow_async==1 || allow_async==-1) + { + struct statfs sfs; + if (fstatfs(m_filedes,&sfs)||(sfs.f_flags&MNT_LOCAL)) // don't use F_NOCACHE on nfs/smb/afp mounts, we need caching there! + fcntl(m_filedes,F_NOCACHE,1); + } +#endif + m_fsize=lseek(m_filedes,0,SEEK_END); + lseek(m_filedes,0,SEEK_SET); + + if (m_fsize < mmap_maxsize) + { + if (m_fsize >= mmap_minsize) + { + m_mmap_view = mmap(NULL,m_fsize,PROT_READ,MAP_SHARED,m_filedes,0); + if (m_mmap_view == MAP_FAILED) m_mmap_view = 0; + else m_fsize_maychange=false; + } + else + { + m_mmap_totalbufmode = malloc(m_fsize); + m_fsize = pread(m_filedes,m_mmap_totalbufmode,m_fsize,0); + m_fsize_maychange=false; + } + } + + } + if (!m_mmap_view && !m_mmap_totalbufmode && m_filedes>=0 && nbufs*bufsize>=WDL_UNBUF_ALIGN) + m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); + +#else + m_fp=fopen(filename,"rb"); + if(m_fp) + { + fseek(m_fp,0,SEEK_END); + m_fsize=ftell(m_fp); + fseek(m_fp,0,SEEK_SET); + } + if (m_fp && nbufs*bufsize>=WDL_UNBUF_ALIGN) + m_bufspace.Resize(nbufs*bufsize+(WDL_UNBUF_ALIGN-1)); +#endif + } + + ~WDL_FileRead() + { + free(m_mmap_totalbufmode); + m_mmap_totalbufmode=0; + +#ifdef WDL_WIN32_NATIVE_READ + int x; + for (x = 0; x < m_empties.GetSize();x ++) delete m_empties.Get(x); + m_empties.Empty(); + for (x = 0; x < m_full.GetSize();x ++) delete m_full.Get(x); + m_full.Empty(); + for (x = 0; x < m_pending.GetSize();x ++) + { + WaitForSingleObject(m_pending.Get(x)->m_ol.hEvent,INFINITE); + delete m_pending.Get(x); + } + m_pending.Empty(); + + if (m_mmap_view) UnmapViewOfFile(m_mmap_view); + m_mmap_view=0; + + if (m_mmap_fmap) CloseHandle(m_mmap_fmap); + m_mmap_fmap=0; + + if (m_fh != INVALID_HANDLE_VALUE) CloseHandle(m_fh); + m_fh=INVALID_HANDLE_VALUE; +#elif defined(WDL_POSIX_NATIVE_READ) + if (m_mmap_view) munmap(m_mmap_view,m_fsize); + m_mmap_view=0; + if (m_filedes>=0) + { + if (m_filedes_locked) flock(m_filedes,LOCK_UN); // release shared lock + close(m_filedes); + } + m_filedes=-1; +#else + if (m_fp) fclose(m_fp); + m_fp=0; +#endif + + } + + bool IsOpen() + { +#ifdef WDL_WIN32_NATIVE_READ + return (m_fh != INVALID_HANDLE_VALUE); +#elif defined(WDL_POSIX_NATIVE_READ) + return m_filedes >= 0; +#else + return m_fp != NULL; +#endif + } + +#ifdef WDL_WIN32_NATIVE_READ + + int RunReads() + { + int retval=0; + + while (m_pending.GetSize()) + { + WDL_FileRead__ReadEnt *ent=m_pending.Get(0); + DWORD s=0; + + if (!ent->m_size && !GetOverlappedResult(m_fh,&ent->m_ol,&s,FALSE)) break; + m_pending.Delete(0); + if (!ent->m_size) ent->m_size=s; + m_full.Add(ent); + } + + + int x=m_empties.GetSize(); + + if (x>0) + { + int cnt=0; + if (m_async_readpos < m_file_position) m_async_readpos = m_file_position; + + if (m_async==1) m_async_readpos &= ~((WDL_FILEREAD_POSTYPE) WDL_UNBUF_ALIGN-1); + + while (x>0) + { + + if (m_async_readpos >= m_fsize) break; + + WDL_FileRead__ReadEnt *t=m_empties.Get(--x); + + ResetEvent(t->m_ol.hEvent); + + *(WDL_FILEREAD_POSTYPE *)&t->m_ol.Offset = m_async_readpos; + + m_async_readpos += m_async_bufsize; + DWORD dw; + if (ReadFile(m_fh,t->m_buf,m_async_bufsize,&dw,&t->m_ol)) + { + if (!dw) + { + retval++; + break; + } + + m_empties.Delete(x); + t->m_size=dw; + m_pending.Add(t); + } + else + { + if (GetLastError() != ERROR_IO_PENDING) + { + retval++; + break; + } + t->m_size=0; + m_empties.Delete(x); + m_pending.Add(t); + } + //if (cnt++>1) + break; + } + } + return retval; + } + + int AsyncRead(char *buf, int maxlen) + { + char *obuf=buf; + int lenout=0; + if (m_file_position+maxlen > m_fsize) + { + maxlen=(int) (m_fsize-m_file_position); + } + if (maxlen<1) return 0; + + int errcnt=!!m_async_hashaderr; + do + { + while (m_full.GetSize() > 0) + { + WDL_FileRead__ReadEnt *ti=m_full.Get(0); + WDL_FILEREAD_POSTYPE tiofs=*(WDL_FILEREAD_POSTYPE *)&ti->m_ol.Offset; + if (m_file_position >= tiofs && m_file_position < tiofs + ti->m_size) + { + if (maxlen < 1) break; + + int l=ti->m_size-(int) (m_file_position-tiofs); + if (l > maxlen) l=maxlen; + + memcpy(buf,(char *)ti->m_buf+m_file_position - tiofs,l); + buf += l; + m_file_position += l; + maxlen -= l; + lenout += l; + } + else + { + m_empties.Add(ti); + m_full.Delete(0); + } + } + + if (maxlen > 0 && m_async_readpos != m_file_position) + { + int x; + for (x = 0; x < m_pending.GetSize(); x ++) + { + WDL_FileRead__ReadEnt *ent=m_pending.Get(x); + WDL_FILEREAD_POSTYPE tiofs=*(WDL_FILEREAD_POSTYPE *)&ent->m_ol.Offset; + if (m_file_position >= tiofs && m_file_position < tiofs + m_async_bufsize) break; + } + if (x == m_pending.GetSize()) + { + m_async_readpos=m_file_position; + } + } + + errcnt+=RunReads(); + + if (maxlen > 0 && m_pending.GetSize() && !m_full.GetSize()) + { + WDL_FileRead__ReadEnt *ent=m_pending.Get(0); + m_pending.Delete(0); + + if (ent->m_size) m_full.Add(ent); + else + { +// WaitForSingleObject(ent->m_ol.hEvent,INFINITE); + + DWORD s=0; + if (GetOverlappedResult(m_fh,&ent->m_ol,&s,TRUE) && s) + { + ent->m_size=s; + m_full.Add(ent); + } + else // failed read, set the error flag + { + errcnt++; + ent->m_size=0; + m_empties.Add(ent); + } + } + } + } + while (maxlen > 0 && (m_pending.GetSize()||m_full.GetSize()) && !errcnt); + if (!errcnt) RunReads(); + else m_async_hashaderr=true; + + return lenout; + } + +#endif + + void *GetMappedView(int offs, int *len) + { + if (!m_mmap_view && !m_mmap_totalbufmode) return 0; + + int maxl=(int) (m_fsize-(WDL_FILEREAD_POSTYPE)offs); + if (*len > maxl) *len=maxl; + if (m_mmap_view) + return (char *)m_mmap_view + offs; + else + return (char *)m_mmap_totalbufmode + offs; + } + + int Read(void *buf, int len) + { + if (m_mmap_view||m_mmap_totalbufmode) + { + int maxl=(int) (m_fsize-m_file_position); + if (maxl > len) maxl=len; + if (maxl < 0) maxl=0; + if (maxl>0) + { + if (m_mmap_view) + memcpy(buf,(char *)m_mmap_view + (int)m_file_position,maxl); + else + memcpy(buf,(char *)m_mmap_totalbufmode + (int)m_file_position,maxl); + + } + m_file_position+=maxl; + return maxl; + } + + if (m_fsize_maychange) GetSize(); // update m_fsize + +#ifdef WDL_WIN32_NATIVE_READ + if (m_fh == INVALID_HANDLE_VALUE||len<1) return 0; + + if (m_async>0) + { + return AsyncRead((char *)buf,len); + } +#elif defined(WDL_POSIX_NATIVE_READ) + if (m_filedes<0 || len<1) return 0; + +#else + if (!m_fp || len<1) return 0; + +#endif + + if (m_bufspace.GetSize()>=WDL_UNBUF_ALIGN*2-1) + { + int rdout=0; + int sz=m_bufspace.GetSize()-(WDL_UNBUF_ALIGN-1); + char *srcbuf=(char *)m_bufspace.Get(); // read size + if (((int)(INT_PTR)srcbuf)&(WDL_UNBUF_ALIGN-1)) srcbuf += WDL_UNBUF_ALIGN-(((int)(INT_PTR)srcbuf)&(WDL_UNBUF_ALIGN-1)); + while (len > rdout) + { + int a=m_sync_bufmode_used-m_sync_bufmode_pos; + if (a>(len-rdout)) a=(len-rdout); + if (a>0) + { + memcpy((char*)buf+rdout,srcbuf+m_sync_bufmode_pos,a); + rdout+=a; + m_sync_bufmode_pos+=a; + m_file_position+=a; + } + + if (len > rdout) + { + m_sync_bufmode_used=0; + m_sync_bufmode_pos=0; + + int thissz=sz; + if (m_syncrd_firstbuf) // this is a scheduling mechanism to avoid having reads on various files always happening at the same time -- not needed in async modes, only in sync with large buffers + { + m_syncrd_firstbuf=false; + int a= thissz/WDL_UNBUF_ALIGN; + if (a > 1) + { + static int rrs; // may not be ideal on multithread, but having it incorrect isnt a big deal. + if (a>7) thissz >>= (rrs++)&3; + else thissz>>= (rrs++)&1; + } + } + + #ifdef WDL_WIN32_NATIVE_READ + DWORD o; + if (m_async==-1) + { + if (m_file_position&(WDL_UNBUF_ALIGN-1)) + { + int offs = (int)(m_file_position&(WDL_UNBUF_ALIGN-1)); + LONG high=(LONG) ((m_file_position-offs)>>32); + SetFilePointer(m_fh,(LONG)((m_file_position-offs)&((WDL_FILEREAD_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN); + m_sync_bufmode_pos=offs; + } + } + if (!ReadFile(m_fh,srcbuf,thissz,&o,NULL) || o<1 || m_sync_bufmode_pos>=(int)o) + { + break; + } + #elif defined(WDL_POSIX_NATIVE_READ) + int o; + o=pread(m_filedes,srcbuf,thissz,m_filedes_rdpos); + if (o>0) m_filedes_rdpos+=o; + if (o<1 || m_sync_bufmode_pos>=o) break; + + #else + int o; + o=fread(srcbuf,1,thissz,m_fp); + if (o<1 || m_sync_bufmode_pos>=o) break; + #endif + m_sync_bufmode_used=o; + } + + } + return rdout; + } + else + { + #ifdef WDL_WIN32_NATIVE_READ + DWORD dw=0; + ReadFile(m_fh,buf,len,&dw,NULL); + m_file_position+=dw; + return dw; + #elif defined(WDL_POSIX_NATIVE_READ) + + int ret=pread(m_filedes,buf,len,m_filedes_rdpos); + if (ret>0) m_filedes_rdpos+=ret; + m_file_position+=ret; + return ret; + #else + int ret=fread(buf,1,len,m_fp); + m_file_position+=ret; + return ret; + #endif + } + + } + + WDL_FILEREAD_POSTYPE GetSize() + { +#ifdef WDL_WIN32_NATIVE_READ + if (m_fh == INVALID_HANDLE_VALUE) return 0; +#elif defined(WDL_POSIX_NATIVE_READ) + if (m_filedes<0) return -1; + +#else + if (!m_fp) return -1; +#endif + + if (m_fsize_maychange) + { +#ifdef WDL_WIN32_NATIVE_READ + DWORD h=0; + DWORD l=GetFileSize(m_fh,&h); + m_fsize=(((WDL_FILEREAD_POSTYPE)h)<<32)|l; +#elif defined(WDL_POSIX_NATIVE_READ) + struct stat st; + if (!fstat(m_filedes,&st)) m_fsize = st.st_size; + +#endif + } + + return m_fsize; + } + + WDL_FILEREAD_POSTYPE GetPosition() + { +#ifdef WDL_WIN32_NATIVE_READ + if (m_fh == INVALID_HANDLE_VALUE) return -1; +#elif defined(WDL_POSIX_NATIVE_READ) + if (m_filedes<0) return -1; +#else + if (!m_fp) return -1; +#endif + return m_file_position; + } + + bool SetPosition(WDL_FILEREAD_POSTYPE pos) // returns 0 on success + { + m_async_hashaderr=false; + +#ifdef WDL_WIN32_NATIVE_READ + if (m_fh == INVALID_HANDLE_VALUE) return true; +#elif defined(WDL_POSIX_NATIVE_READ) + if (m_filedes<0) return true; +#else + if (!m_fp) return true; +#endif + + if (m_fsize_maychange) GetSize(); + + if (pos < 0) pos=0; + if (pos > m_fsize) pos=m_fsize; + WDL_FILEREAD_POSTYPE oldpos=m_file_position; + if (m_file_position!=pos) m_file_position=pos; + else return false; + + if (m_mmap_view||m_mmap_totalbufmode) return false; + +#ifdef WDL_WIN32_NATIVE_READ + if (m_async>0) + { + WDL_FileRead__ReadEnt *ent; + + if (pos > m_async_readpos || !(ent=m_full.Get(0)) || pos < *(WDL_FILEREAD_POSTYPE *)&ent->m_ol.Offset) + { + m_async_readpos=pos; + } + + return FALSE; + } +#endif + + + if (m_bufspace.GetSize()>=WDL_UNBUF_ALIGN*2-1) + { + if (pos >= oldpos-m_sync_bufmode_pos && pos < oldpos-m_sync_bufmode_pos + m_sync_bufmode_used) + { + int diff=(int) (pos-oldpos); + m_sync_bufmode_pos+=diff; + + return 0; + } + m_sync_bufmode_pos=m_sync_bufmode_used=0; + } + + m_syncrd_firstbuf=true; +#ifdef WDL_WIN32_NATIVE_READ + LONG high=(LONG) (m_file_position>>32); + return SetFilePointer(m_fh,(LONG)(m_file_position&((WDL_FILEREAD_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN)==0xFFFFFFFF && GetLastError() != NO_ERROR; +#elif defined(WDL_POSIX_NATIVE_READ) + m_filedes_rdpos = m_file_position; + return false; +#else + return !!fseek(m_fp,m_file_position,SEEK_SET); +#endif + } + + WDL_HeapBuf m_bufspace; + int m_sync_bufmode_used, m_sync_bufmode_pos; + + WDL_FILEREAD_POSTYPE m_file_position,m_async_readpos; + WDL_FILEREAD_POSTYPE m_fsize; + + void *m_mmap_view; + void *m_mmap_totalbufmode; + +#ifdef WDL_WIN32_NATIVE_READ + HANDLE GetHandle() { return m_fh; } + HANDLE m_fh; + HANDLE m_mmap_fmap; + int m_mmap_size; + int m_async; // 1=nobuf, 2=buffered async, -1=unbuffered sync + + int m_async_bufsize; + WDL_PtrList m_empties; + WDL_PtrList m_pending; + WDL_PtrList m_full; + +#elif defined(WDL_POSIX_NATIVE_READ) + WDL_FILEREAD_POSTYPE m_filedes_rdpos; + int m_filedes; + bool m_filedes_locked; + + int GetHandle() { return m_filedes; } +#else + FILE *m_fp; + + int GetHandle() { return fileno(m_fp); } +#endif + + bool m_fsize_maychange; + bool m_syncrd_firstbuf; + bool m_async_hashaderr; + +} WDL_FIXALIGN; + + + + + + +#endif diff --git a/WDL/filewrite.h b/WDL/filewrite.h new file mode 100644 index 00000000..10233f18 --- /dev/null +++ b/WDL/filewrite.h @@ -0,0 +1,642 @@ +/* + WDL - filewrite.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides the WDL_FileWrite object, which can be used to create/write files. + On windows systems it supports writing synchronously, asynchronously, and asynchronously without buffering. + On windows systems it supports files larger than 4gb. + On non-windows systems it acts as a wrapper for fopen()/etc. + + +*/ + + +#ifndef _WDL_FILEWRITE_H_ +#define _WDL_FILEWRITE_H_ + + + + +#include "ptrlist.h" + + + +#if defined(_WIN32) && !defined(WDL_NO_WIN32_FILEWRITE) + #ifndef WDL_WIN32_NATIVE_WRITE + #define WDL_WIN32_NATIVE_WRITE + #endif +#else + #ifdef WDL_WIN32_NATIVE_WRITE + #undef WDL_WIN32_NATIVE_WRITE + #endif + #if !defined(WDL_NO_POSIX_FILEWRITE) + #include + #include + #include + #define WDL_POSIX_NATIVE_WRITE + #endif +#endif + + + +#ifdef _MSC_VER +#define WDL_FILEWRITE_POSTYPE __int64 +#else +#define WDL_FILEWRITE_POSTYPE long long +#endif + +//#define WIN32_ASYNC_NOBUF_WRITE // this doesnt seem to give much perf increase (writethrough with buffering is fine, since ultimately writes get deferred anyway) + +class WDL_FileWrite +{ +#ifdef WDL_WIN32_NATIVE_WRITE + +class WDL_FileWrite__WriteEnt +{ +public: + WDL_FileWrite__WriteEnt(int sz) + { + m_last_writepos=0; + m_bufused=0; + m_bufsz=sz; + m_bufptr = (char *)__buf.Resize(sz+4095); + int a=((int)(INT_PTR)m_bufptr)&4095; + if (a) m_bufptr += 4096-a; + + memset(&m_ol,0,sizeof(m_ol)); + m_ol.hEvent=CreateEvent(NULL,TRUE,TRUE,NULL); + } + ~WDL_FileWrite__WriteEnt() + { + CloseHandle(m_ol.hEvent); + } + + WDL_FILEWRITE_POSTYPE m_last_writepos; + + int m_bufused,m_bufsz; + OVERLAPPED m_ol; + char *m_bufptr; + WDL_TypedBuf __buf; +}; + +#endif + +#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) + BOOL HasUTF8(const char *_str) + { + const unsigned char *str = (const unsigned char *)_str; + if (!str) return FALSE; + while (*str) + { + unsigned char c = *str; + if (c >= 0xC2) + { + if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; + else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + } + str++; + } + return FALSE; + } +#endif + + +public: + WDL_FileWrite(const char *filename, int allow_async=1, int bufsize=8192, int minbufs=16, int maxbufs=16, bool wantAppendTo=false, bool noFileLocking=false) // async==2 is unbuffered + { + m_file_position=0; + m_file_max_position=0; + if(!filename) + { +#ifdef WDL_WIN32_NATIVE_WRITE + m_fh = INVALID_HANDLE_VALUE; + m_async = 0; +#elif defined(WDL_POSIX_NATIVE_WRITE) + m_filedes_locked=false; + m_filedes=-1; + m_bufspace_used=0; +#else + m_fp = NULL; +#endif + return; + } + +#ifdef WDL_WIN32_NATIVE_WRITE + bool isNT = (GetVersion()<0x80000000); + m_async = allow_async && isNT; +#ifdef WIN32_ASYNC_NOBUF_WRITE + bufsize = (bufsize+4095)&~4095; + if (bufsize<4096) bufsize=4096; +#endif + + int rwflag = GENERIC_WRITE; + int createFlag= wantAppendTo?OPEN_ALWAYS:CREATE_ALWAYS; + int shareFlag = noFileLocking ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : FILE_SHARE_READ; + int flag = FILE_ATTRIBUTE_NORMAL; + + if (m_async) + { + rwflag |= GENERIC_READ; +#ifdef WIN32_ASYNC_NOBUF_WRITE + flag |= FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH; +#else + flag |= FILE_FLAG_OVERLAPPED|(allow_async>1 ? FILE_FLAG_WRITE_THROUGH: 0); +#endif + } + + { +#ifndef WDL_NO_SUPPORT_UTF8 + m_fh=INVALID_HANDLE_VALUE; + if (isNT && HasUTF8(filename)) + { + int szreq=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,NULL,0); + if (szreq > 1000) + { + WDL_TypedBuf wfilename; + wfilename.Resize(szreq+10); + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename.Get(),wfilename.GetSize())) + m_fh = CreateFileW(wfilename.Get(),rwflag,shareFlag,NULL,createFlag,flag,NULL); + } + else + { + WCHAR wfilename[1024]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wfilename,1024)) + m_fh = CreateFileW(wfilename,rwflag,shareFlag,NULL,createFlag,flag,NULL); + } + } + + if (m_fh == INVALID_HANDLE_VALUE) +#endif + m_fh = CreateFileA(filename,rwflag,shareFlag,NULL,createFlag,flag,NULL); + } + + if (m_async && m_fh != INVALID_HANDLE_VALUE) + { + m_async_bufsize=bufsize; + m_async_maxbufs=maxbufs; + m_async_minbufs=minbufs; + int x; + for (x = 0; x < m_async_minbufs; x ++) + { + WDL_FileWrite__WriteEnt *t=new WDL_FileWrite__WriteEnt(m_async_bufsize); + m_empties.Add(t); + } + } + + if (m_fh != INVALID_HANDLE_VALUE && wantAppendTo) + SetPosition(GetSize()); + +#elif defined(WDL_POSIX_NATIVE_WRITE) + m_bufspace_used=0; + m_filedes_locked=false; + m_filedes=open(filename,O_WRONLY|O_CREAT,0644); + if (m_filedes>=0) + { + + if (!noFileLocking) + { + m_filedes_locked = !flock(m_filedes,LOCK_EX|LOCK_NB); + if (!m_filedes_locked) + { + // this check might not be necessary, it might be sufficient to just fail and close if no exclusive lock possible + if (errno == EWOULDBLOCK) + { + // FAILED exclusive locking because someone else has a lock + close(m_filedes); + m_filedes=-1; + } + else // failed for some other reason, try to keep a shared lock at least + { + m_filedes_locked = !flock(m_filedes,LOCK_SH|LOCK_NB); + } + } + } + + if (m_filedes>=0) + { + if (!wantAppendTo) ftruncate(m_filedes,0); + else + { + struct stat st; + if (!fstat(m_filedes,&st)) SetPosition(st.st_size); + } + } + + +#ifdef __APPLE__ + if (m_filedes >= 0 && allow_async>1) fcntl(m_filedes,F_NOCACHE,1); +#endif + } + if (minbufs * bufsize >= 16384) m_bufspace.Resize((minbufs*bufsize+4095)&~4095); +#else + m_fp=fopen(filename,wantAppendTo ? "a+b" : "wb"); + if (wantAppendTo && m_fp) + fseek(m_fp,0,SEEK_END); +#endif + } + + ~WDL_FileWrite() + { +#ifdef WDL_WIN32_NATIVE_WRITE + // todo, async close stuff? + if (m_fh != INVALID_HANDLE_VALUE && m_async) + { + SyncOutput(true); + } + + m_empties.Empty(true); + m_pending.Empty(true); + + if (m_fh != INVALID_HANDLE_VALUE) CloseHandle(m_fh); + m_fh=INVALID_HANDLE_VALUE; +#elif defined(WDL_POSIX_NATIVE_WRITE) + if (m_filedes >= 0) + { + if (m_bufspace.GetSize() > 0 && m_bufspace_used>0) + { + int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); + if (v>0) m_file_position+=v; + if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; + m_bufspace_used=0; + } + if (m_filedes_locked) flock(m_filedes,LOCK_UN); + close(m_filedes); + } + m_filedes=-1; + +#else + if (m_fp) fclose(m_fp); + m_fp=0; +#endif + + } + + bool IsOpen() + { +#ifdef WDL_WIN32_NATIVE_WRITE + return (m_fh != INVALID_HANDLE_VALUE); +#elif defined(WDL_POSIX_NATIVE_WRITE) + return m_filedes >= 0; +#else + return m_fp != NULL; +#endif + } + + + int Write(const void *buf, int len) + { +#ifdef WDL_WIN32_NATIVE_WRITE + if (m_fh == INVALID_HANDLE_VALUE) return 0; + + if (m_async) + { + char *pbuf=(char *)buf; + + while (len > 0) + { + if (!m_empties.GetSize()) + { + WDL_FileWrite__WriteEnt *ent=m_pending.Get(0); + DWORD s=0; + if (ent) + { + bool wasabort=false; + if (GetOverlappedResult(m_fh,&ent->m_ol,&s,FALSE)|| + (wasabort=(GetLastError()==ERROR_OPERATION_ABORTED))) + { + m_pending.Delete(0); + + if (wasabort) + { + if (!RunAsyncWrite(ent,false)) m_empties.Add(ent); + } + else + { + m_empties.Add(ent); + ent->m_bufused=0; + } + } + } + } + + + WDL_FileWrite__WriteEnt *ent=m_empties.Get(0); + if (!ent) + { + if (m_pending.GetSize()>=m_async_maxbufs) + { + SyncOutput(false); + } + + if (!(ent=m_empties.Get(0))) + m_empties.Add(ent = new WDL_FileWrite__WriteEnt(m_async_bufsize)); // new buffer + + + } + + int ml=ent->m_bufsz-ent->m_bufused; + if (ml>len) ml=len; + memcpy(ent->m_bufptr+ent->m_bufused,pbuf,ml); + + ent->m_bufused+=ml; + len-=ml; + pbuf+=ml; + + if (ent->m_bufused >= ent->m_bufsz) + { + if (RunAsyncWrite(ent,true)) m_empties.Delete(0); // if queued remove from list + } + } + return pbuf - (char *)buf; + } + else + { + DWORD dw=0; + WriteFile(m_fh,buf,len,&dw,NULL); + m_file_position+=dw; + if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; + return dw; + } +#elif defined(WDL_POSIX_NATIVE_WRITE) + if (m_bufspace.GetSize()>0) + { + char *rdptr = (char *)buf; + int rdlen = len; + while (rdlen>0) + { + int amt = m_bufspace.GetSize() - m_bufspace_used; + if (amt>0) + { + if (amt>rdlen) amt=rdlen; + memcpy((char *)m_bufspace.Get()+m_bufspace_used,rdptr,amt); + m_bufspace_used += amt; + rdptr+=amt; + rdlen -= amt; + + if (m_file_position+m_bufspace_used > m_file_max_position) m_file_max_position=m_file_position + m_bufspace_used; + } + if (m_bufspace_used >= m_bufspace.GetSize()) + { + int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); + if (v>0) m_file_position+=v; + m_bufspace_used=0; + } + } + return len; + } + else + { + int v=pwrite(m_filedes,buf,len,m_file_position); + if (v>0) m_file_position+=v; + if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; + return v; + } +#else + return fwrite(buf,1,len,m_fp); +#endif + + + } + + WDL_FILEWRITE_POSTYPE GetSize() + { +#ifdef WDL_WIN32_NATIVE_WRITE + if (m_fh == INVALID_HANDLE_VALUE) return 0; + DWORD h=0; + DWORD l=GetFileSize(m_fh,&h); + WDL_FILEWRITE_POSTYPE tmp=(((WDL_FILEWRITE_POSTYPE)h)<<32)|l; + WDL_FILEWRITE_POSTYPE tmp2=GetPosition(); + if (tmpm_bufused; + } + return pos; +#elif defined(WDL_POSIX_NATIVE_WRITE) + if (m_filedes < 0) return -1; + return m_file_position + m_bufspace_used; +#else + if (!m_fp) return -1; + return ftell(m_fp); + +#endif + } + +#ifdef WDL_WIN32_NATIVE_WRITE + + bool RunAsyncWrite(WDL_FileWrite__WriteEnt *ent, bool updatePosition) // returns true if ent is added to pending + { + if (ent && ent->m_bufused>0) + { + if (updatePosition) + { + ent->m_last_writepos = m_file_position; + m_file_position += ent->m_bufused; + if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; + } + +#ifdef WIN32_ASYNC_NOBUF_WRITE + if (ent->m_bufused&4095) + { + int offs=(ent->m_bufused&4095); + char tmp[4096]; + memset(tmp,0,4096); + + *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = ent->m_last_writepos + ent->m_bufused - offs; + ResetEvent(ent->m_ol.hEvent); + + DWORD dw=0; + if (!ReadFile(m_fh,tmp,4096,&dw,&ent->m_ol)) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(ent->m_ol.hEvent,INFINITE); + } + memcpy(ent->m_bufptr+ent->m_bufused,tmp+offs,4096-offs); + + ent->m_bufused += 4096-offs; + } +#endif + DWORD d=0; + + *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = ent->m_last_writepos; + + ResetEvent(ent->m_ol.hEvent); + + if (!WriteFile(m_fh,ent->m_bufptr,ent->m_bufused,&d,&ent->m_ol)) + { + if (GetLastError()==ERROR_IO_PENDING) + { + m_pending.Add(ent); + return true; + } + } + ent->m_bufused=0; + } + return false; + } + + void SyncOutput(bool syncall) + { + if (syncall) + { + if (RunAsyncWrite(m_empties.Get(0),true)) m_empties.Delete(0); + } + for (;;) + { + WDL_FileWrite__WriteEnt *ent=m_pending.Get(0); + if (!ent) break; + DWORD s=0; + m_pending.Delete(0); + if (!GetOverlappedResult(m_fh,&ent->m_ol,&s,TRUE) && GetLastError()==ERROR_OPERATION_ABORTED) + { + // rewrite this one + if (!RunAsyncWrite(ent,false)) m_empties.Add(ent); + } + else + { + m_empties.Add(ent); + ent->m_bufused=0; + if (!syncall) break; + } + } + } + +#endif + + + bool SetPosition(WDL_FILEWRITE_POSTYPE pos) // returns 0 on success + { +#ifdef WDL_WIN32_NATIVE_WRITE + if (m_fh == INVALID_HANDLE_VALUE) return true; + if (m_async) + { + SyncOutput(true); + m_file_position=pos; + if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; + +#ifdef WIN32_ASYNC_NOBUF_WRITE + if (m_file_position&4095) + { + WDL_FileWrite__WriteEnt *ent=m_empties.Get(0); + if (ent) + { + int psz=(int) (m_file_position&4095); + + m_file_position -= psz; + *(WDL_FILEWRITE_POSTYPE *)&ent->m_ol.Offset = m_file_position; + ResetEvent(ent->m_ol.hEvent); + + DWORD dwo=0; + if (!ReadFile(m_fh,ent->m_bufptr,4096,&dwo,&ent->m_ol)) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(ent->m_ol.hEvent,INFINITE); + } + ent->m_bufused=(int)psz; + } + } +#endif + return false; + } + + m_file_position=pos; + if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; + + LONG high=(LONG) (m_file_position>>32); + return SetFilePointer(m_fh,(LONG)(m_file_position&((WDL_FILEWRITE_POSTYPE)0xFFFFFFFF)),&high,FILE_BEGIN)==0xFFFFFFFF && GetLastError() != NO_ERROR; +#elif defined(WDL_POSIX_NATIVE_WRITE) + + if (m_filedes < 0) return true; + if (m_bufspace.GetSize() > 0 && m_bufspace_used>0) + { + int v=pwrite(m_filedes,m_bufspace.Get(),m_bufspace_used,m_file_position); + if (v>0) m_file_position+=v; + if (m_file_position > m_file_max_position) m_file_max_position=m_file_position; + m_bufspace_used=0; + } + + m_file_position = pos; // seek! + if (m_file_position>m_file_max_position) m_file_max_position=m_file_position; + return false; +#else + if (!m_fp) return true; + return !!fseek(m_fp,pos,SEEK_SET); +#endif + } + + WDL_FILEWRITE_POSTYPE m_file_position, m_file_max_position; + +#ifdef WDL_WIN32_NATIVE_WRITE + HANDLE GetHandle() { return m_fh; } + HANDLE m_fh; + bool m_async; + + int m_async_bufsize, m_async_minbufs, m_async_maxbufs; + + WDL_PtrList m_empties; + WDL_PtrList m_pending; + +#elif defined(WDL_POSIX_NATIVE_WRITE) + int GetHandle() { return m_filedes; } + + WDL_HeapBuf m_bufspace; + int m_bufspace_used; + int m_filedes; + + bool m_filedes_locked; + +#else + int GetHandle() { return fileno(m_fp); } + + FILE *m_fp; +#endif +} WDL_FIXALIGN; + + + + + + +#endif diff --git a/WDL/giflib/AUTHORS b/WDL/giflib/AUTHORS new file mode 100644 index 00000000..43dee904 --- /dev/null +++ b/WDL/giflib/AUTHORS @@ -0,0 +1,36 @@ +Lennie Araki + Windows code providing a nicer interface and example program + +Michael Brown + callbacks to write data via user defined function + +Daniel Eisenbud + Fixes for crashes with invalid gif files and double freeing of + colormaps + +Gershon Elber + original giflib code + +Marc Ewing + spec file (for rpms) updates + +Toshio Kuratomi + uncompressed gif writing code + autoconf/automake process + current maintainer + +marek + Gif initialization fix + windows build code + +Peter Mehlitz + callbacks to read data from arbitrary sources (like libjpeg/libpng) + +Dick Porter + int/pointer fixes for Alpha + +Eric Raymond + long time maintainer of giflib code + +Georg Schwarz + IRIX fixes diff --git a/WDL/giflib/COPYING b/WDL/giflib/COPYING new file mode 100644 index 00000000..da543574 --- /dev/null +++ b/WDL/giflib/COPYING @@ -0,0 +1,19 @@ +The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/WDL/giflib/ChangeLog b/WDL/giflib/ChangeLog new file mode 100644 index 00000000..4186f255 --- /dev/null +++ b/WDL/giflib/ChangeLog @@ -0,0 +1,549 @@ +2005-10-09 Toshio Kuratomi - r94 + * Sync with libungif r93. + * ChangeLog: Update to r92. + * NEWS: Update with combined libungif/giflib changes. + +2005-10-09 Toshio Kuratomi - r92 + * lib/gif_lib.h: Change GifPrefixType to unsigned. + +2005-10-09 Toshio Kuratomi - r91 + * ChangeLog: Update to r90. + * NEWS: Update on GBA and Windows fixes. + +2005-10-06 Toshio Kuratomi - r90 + Changes from Lennie Araki: + * gba/giftest.mak: Prefix the names of defines for the GBA build with _GBA. + * lib/dgif_lib.c, lib/gif_lib_private.h, lib/gif_err.c: + - When Compiling for Game Boy Advance, file functions are not needed so + exclude DGifOpenFileName(), DGifOpenFileHandle(), DGifSlurp(), and + PrintGifError(). + - On Game Boy Advance we need to reduce memory usage. Change values to + short int where appropriate. + * lib/gif_lib.h: + - Handle te GBA changes by defining GifPrefixType and GifWord to int + unless compiling on GBA. Then use unsigned short and short + respectively. + - Fix a problem with the API on _WIN32. DrawText conflicts with the + Windows API. Call it DrawGifText instead. + +2005-09-27 Toshio Kuratomi - r86 + * Sync with libungif r85. + +2005-09-27 Toshio Kuratomi - r82 + * AUTHORS: Add Daniel Eisenbud. Obscure email addresses. + * libungif.spec: Bump to version 4.1.4. + * configure.ac: Bump to 4.1.4. No longer check for ranlib. + * doc/lzgif.txt: Change dos line encoding to UNIX. + * lib/dgif_lib.c: (eisenbud) + - Set GifFile's ColorMaps to NULL when we free a colormap object. + - Detect some cases of corrupted GIFs which were crashing the library. + * lib/egif_lib.c: Set ColorMaps to NULL when we free a colormap object. + * lib/gifalloc.c: Set ColorMaps to NULL when we free a colormap object. + * lib/dev2gif.c: Fix redefinition problem on IRIX. + * NEWS: Update to 4.1.4 + * util/gifcomb.c: Set a olorMap to NULL. + +2004-07-11 Toshio Kuratomi - r79 + * gif2iris.c: Fixes from Georg Schwarz . + - stdlib.h is available and needs to be included on IRIX. + - ColorMapSize was being set from non-existent variables. + +2004-05-29 Toshio Kuratomi - r76 + * Sync with libungif-4.1.3. + +2004-05-29 Toshio Kuratomi - r74 + * ChangeLog, prop=lastlog: Sync with the subversion logs. + +2004-05-29 Toshio Kuratomi - r73 + * test-unx: Add a test of extension code. + * lib/egif_lib.c: Remove a debugging statement + +2004-05-29 Toshio Kuratomi - r72 + * Makefile.am, doc/Makefile.am, pic/Makefile.am: Change wildcarded entries + into explicit filenames so make distcheck will succeed. + +2004-05-29 Toshio Kuratomi - r71 + * ChangeLog, prop=lastlog: Sync the ChangeLog for the release. + +2004-05-29 Toshio Kuratomi - r70 + * AUTHORS: Add Lennie Araki to the list of contributers. + * windows: The windows subdirectory and all files under it are contributions + from Lennie Araki to provide a nice interface on MS Windows. + * README: Redundancy fix. + * doc/gif_lib.html: Add EGifPutExtension{First,Next,Last} to the documentation + so people know they should use it instead of EGifPutExtension. + * Makefile.am: Mark the windows files to be distributed. + * NEWS: Complete the NEWS item for 4.1.3. + +2004-05-29 Toshio Kuratomi - r69 + * libungif.spec: Some updates from the latest RedHat spec. + * configure.ac: Bump version to 4.1.3. + * lib/gifalloc.c: Add to my comments on ESR's note about Extension blocks. + * lib/egif_lib.c: + - EGifPutComment(): reimplemented using EGifPutExtensionFirst, Next, and + Last so that it won't break on unusually long comments. + - EGifPutExtension{First,Next,Last}: Changed fwrites to WRITE so any + user defined write function will get called properly. + - EGifPutExtensionLast: if the Extension block is empty (Zero length) + then don't attempt to output a last extension block, just output the + block terminator. + - EGifPutExtension: Comment that this function does not work when there + are multiple subblocks in an Extension block. Use the functions + EGifPutExtension{First,Next,Last} instead. + - EGifSpew: Reimplement to use EGifPutExtension{First,Next,Last} so we + don't output broken GIFs when there are multiple sub-blocks on an + extension. + * lib/Makefile.am: Bump version to 4.1.3. + * NEWS: Begin writing an entry for 4.1.3. + * util/icon2gif.c: Few casting fixes to make gcc -Wall happy. + * util/gif2ps.c: printf format string corrections. + +2004-05-26 Toshio Kuratomi - r67 + * Clean up some typos. + +2004-05-25 Toshio Kuratomi - r66 + * Sync with libungif-4.1.2. + +2004-03-03 Toshio Kuratomi - r64 + Last minute updates to the release notes in various files. + +2004-03-03 Toshio Kuratomi - r63 + * Set property lastlog to remind me when I last synced the ChangeLog + +2004-03-03 Toshio Kuratomi - r62 + * ChangeLog: Update + +2004-03-03 Toshio Kuratomi - r61 + * configure.ac: Bump version to 4.1.2 + +2004-02-22 Toshio Kuratomi - r59 + * configure.ac, lib/Makefile.am: Bump version. Forgot to do this for 4.1.1... + +2004-02-22 Toshio Kuratomi - r58 + * TODO: Take out -Wall as that's all ready now. + +2004-02-22 Toshio Kuratomi - r57 + Merge changes to the code from branch indent-audit r55 + * README: MakeExtension deprecation note. + * TODO: Bunch of things I need to fix or check that I saw while doing the + indentation of the code. + * lib/getarg.h: indent changes + * lib/dgif_lib.c: indent changes + - Move stdlib.h out of #ifdef's as it's included on all platforms. + - Add checks to be sure malloc and MakeMapObject succeed. + * lib/quantize.c: indent changes + - Move stdlib.h out of #ifdef's as it's included on all platforms. + - _GifError already pulled in through gif_lib_private.h. Remove decl. + - Make Count in NewColorMapType be unsigned. + - Separated mallocs from conditionals in a few places. Easier reading. + * lib/gifalloc.c: indent changes + - Added four FIXME's where I think the code might not be doing what we + want. Need to do more research to figure out. + - Add note to MakeExtension that I think it needs to be deprecated. + - Separated mallocs from conditionals in a few places. Easier reading. + - FreeLastSavedImage: New private function to free the last image in a + GifFile structure. Used to back out when unable to completely + allocate a new SavedImage structure. + - check for NULL values before deallocating in Free* functions and make + sure all Free* functions set the pointer to NULL after they deallocate + the memory. + * lib/egif_lib.c: indent changes + - EGifPutScreenDesc: If we have no colormap, output a default value for + its size instead of trying to reference its unallocated BitsPerPixel + field. (Fixes bug noted in r46) + * lib/gif_lib.h: indent changes + - Condense the #else #if VARARGS to #elif VARARGS check. + * lib/qprintf.c: indent changes + - Condense the #else #if VARARGS to #elif VARARGS check. + * lib/dev2gif.c: indent changes + * lib/getarg.c: indent changes + * lib/gif_lib_private.h: indent changes + * lib/gif_font.c: indent changes + * lib/gif_err.c: indent changes + +2004-02-22 Toshio Kuratomi - r56 + * lib/Makefile.am, util/Makefile.am: Add -Wall to the compilation flags so + we can keep the code from acquiring too much bad style. + +2004-02-20 Toshio Kuratomi - r46 + * egif_lib.c: Note for a bug fix (Can wait until after indent because + there's no patch.) + * gif_lib.h, dev2gif.c: Change int type to explicit long type in + DumpScreen2Gif. + * util/gifinto.c: Give the fprintf back its %d format. + GifFile->ImageCount is used as the Image number. + +2004-02-20 Toshio Kuratomi - r45 + * README: add varargs to the deprecation list + +2004-02-20 Toshio Kuratomi - r44 + * test-unx: Quote the program names. + * lib/dgif_lib.c: + - Make sure memory was allocated for the colormap + - Some reformatting of code but no syntactic changes. + * lib/gif_lib.h: + - C++ extern "C" fix + - Fix typo with EGifOpen + * lib/qprintf.c, lib/getarg.c: Update the varargs code. Some users reported + that not all systems can handle the hybridized varargs parameter lists + we had. Need to use old-style declarations instead. + +2004-02-20 Toshio Kuratomi - r43 + * NEWS: Note bugfixes and deprecations + * README: Deprecation list is now being compiled in this file. + * TODO: Notes about interlace bug, -Wall status, merging of old bug status + +2004-02-19 Toshio Kuratomi - r42 + * Makefile.am: Disable testing for now because gif2x11 is broken so none + of the tests _appear_ to complete successfully. + +2004-02-19 Toshio Kuratomi - r38 + Merge -Wall fixes from branches/Wall-audit r29 + * configure.ac: + - Make the stdarg vs varargs check simpler by relying on + AC_CHECK_HEADERS() magic. + - Check for unistd.h + * dgif_lib.c, gif_lib.h, egif_lib.c, gifalloc.c, quantize.c, dev2gif.c, + getarg.c, gif_lib_private.h, gif_font.c gif_err.c, gifinto.c, icon2gif.c, + raw2gif.c, gifcolor.c, gifasm.c, gif2epsn.c, gif2iris.c, gifrotat.c, + gifovly.c, gif2x11.c, rle2gif.c, gif2rle.c, text2gif.c, gifspnge.c, + gifclrmp.c, giffiltr.c, giftext.c, gifinfo.c, rgb2gif.c, gif2rgb.c, gif2ps.c + - Changes to get rid of -Wall compile warnings. + + Casting of types + + New header includes for unistd.h and fcntl.h + + Explicit declaration of many types to unsigned + + Removed unused variables and functions + + Removed VersionStr from every library file. Instead include it via + gif_lib_private.h + * gif_lib.h, gif_lib_private.h: Moved the VersionStr into gif_lib_private.h + and made it a #define instead of a static char *. + +2004-02-19 Toshio Kuratomi - r37 + Deprecation notes + +2004-02-19 Toshio Kuratomi - r36 + Add notes about security things to do and giflib syncing + +2004-02-18 Toshio Kuratomi - r32 + * TODO: Add notes about how to go about syncing Wall-audit and indent changes + into giflib. It won't be pretty. + * svn:ignore: Change the tarball names from libungif to giflib + +2004-02-18 Toshio Kuratomi - r31 + Add config.h include to gif_hash.c + +2004-02-17 Toshio Kuratomi - r30 + Sync up with libungif 4.1.1 + +2004-02-17 Toshio Kuratomi - r26 + Updated ChangeLog + +2004-02-17 Toshio Kuratomi + * Updated libungif.spec to look more like fedora core spec + * Updated version numbers in all files + +2004-02-17 Toshio Kuratomi + * Add the libungif*.tar.bz2 distribution tarball to the ignored files + * configure.ac, lib/getarg.c, lib/getarg.h, lib/gif_lib.h, lib/qprintf.c: + Prefer stdarg.h over vararg.h + * TODO: Add information about functions that will go away in 5.0 + (In reality, I don't think new software uses libungif, so there may never + be a 5.0 release.) + * lib/gif_lib.h: Change version from 4.0 to 4.1 + * NEWS: add deprecation warning for the qprintf stuff: GifQuietPrint var and + GifQprintf function. + +2004-02-16 Toshio Kuratomi + * util/gif2iris.c, util/gif2rle.c, util/gifinfo.c: Fix problems with fprintf error statements in the utils + +2004-02-16 Toshio Kuratomi + Add DEVELOPERS file to the distribution. + +2004-02-16 Toshio Kuratomi + * AUTHORS, libungif.spec, libungif.lsm, README, BUGS, NEWS: + Lots of changes to my email address and the website/download. (libungif is + moving to sourceforge.) + * TODO: Few notes on cleanups that need to happen. State what needs to be done + for 4.1.1 to be released. + +2004-02-15 Toshio Kuratomi + Changes imported from last cvs checkout + * TODO: note to check return of malloc everywhere + * lib/dgif_lib.c, lib/egif_lib.c: Fix some deallocation bugs + * lib/gifalloc.c: Fix a colormap allocation problem + * lib/gif_font.c: Fix to drawing text + +2004-02-15 Toshio Kuratomi + Added libgetarg.a to the ignore list. + +2004-02-15 Toshio Kuratomi + Changes to the build infrastructure to build under current libtool, automake, + and libtool. + * configure.in: renamed to configure.ac + * acconfig.h: deleted. Functionality moved into the configure.ac + * autogen.sh: now runs libtoolize --automake + * lib/Makefile.am, util/Makefile.am: CFLAGS=>AM_CFLAGS; INCLUDES=>AM_CPPFLAGS + * configure.ac: + - initialization macros for automake and autoconf have changed + - removed checks for C++ compiler and Awk + - acconfig.h functionality moved here. + - add other X11 libraries to the X11_LIB define + +2004-02-15 Toshio Kuratomi + * Remove INSTALL file as it's autogenerated.\n* Add stamp-h1 to ignored files + +2004-02-15 Toshio Kuratomi + Additional adds and deletes to make version 4.1.0b1 + +2004-02-15 Toshio Kuratomi + Import of version 4.1.0b1 + +2004-02-15 Toshio Kuratomi - r10 + Import giflib 4.1.0 + +2004-02-15 Toshio Kuratomi - r9 + Copy the 4.1.0 libungif release to be the base of the 4.1.0 giflib release. + +2004-02-15 Toshio Kuratomi - r7 + Release 4.1.0 + +2004-02-15 Toshio Kuratomi - r6 + Import of version 4.1.0 + +2004-02-15 Toshio Kuratomi - r5 + Set ignore patterns on the project directories. + +2004-02-15 Toshio Kuratomi - r3 + Remove a Makefile.in that was left in in the first commit. + +2004-02-14 Toshio Kuratomi - r2 + Commit revision 3.1.0 to subversion + +2004-02-14 Toshio Kuratomi - r1 + Initial SVN Repository Layout + +2000 6 Feb Toshio Kuratomi + * configure.in: Change to using config.h + - Every .c file: Change to using config.h. + * configure.in: added check for varargs header. + * lib/getarg.c: Changed the ifdef USE_VARARGS to ifdef HAVE_VARARGS_H. + - lib/getarg.h: Ditto. + - lib/gif_lib.h: Ditto. + - lib/qprintf.h: Ditto. + +2000 6 Feb Toshio Kuratomi + * lib/getarg.h: Prepend an underscore to the header file define. + * lib/gif_lib.h: Ditto + * lib/gif_lib_private.h: Ditto + * lib/getarg.c: ifdef'd MyMalloc so it actually won't define if it already + is. + +2000 3 Feb Toshio Kuratomi + * A new cvs repository based my private tree from home. It now goes back + to giflib-3.0. + * Updated the cvs repository to make multiple developers possible. + * Merge all of Michael's patches into the distribution. + * DEVELOPER: Updated to reflect the new versions of + autoconf/automake/libtool we're using. + * libungif.spec: Updated a few things from the latest redhat spec file. + +1999 5 Dec Toshio Kuratomi + * Update links to the web pages as I have reorganized them somewhat. + * Add the welcome2.gif to the pic directory and a test that utilizes + it to test-unx. + +1999 17 Nov Toshio Kuratomi + * New cvs Repository. Hopefully I've got everything that was in the + old one. This one is available on anonymous cvs. + * Update to libtool 1.3.3, automake 1.4, and autoconf 2.13 + +1999 23 May Michael R Brown + * Lots of 'const' qualifiers added, thanks Alexis + Wilke for finding these. + +1999 22 Mar Michael R Brown + * util/gif2x11.c: Patch by (who?) to fix lots of memory leeks. + * util/*.c: + lib/dgif_lib.c: + Makefile.in: + Patch by David Kaelbling to compile on IRIX 6.x. Basically fixing + lots of bad/missing parameter passing to printf, scanf and similar. + * Added pics/welcome2.gif, from Peter Merz which provokes a bug prior + to patch 19990224 to do with colour map management. There is still + a problem with util/gifspnge processing this image, so it will not + be added to test-unx yet. + +1999 05 Mar Michael R Brown + * lib/getarg.c: Lines 107 and 189 + Added ifdef's to use stdarg when available. On dec-alpha the + default code was causing programs to crash, probably because + it assumes a stack that grows-up. + +1999 24 Feb Michael R Brown + * lib/dgif_lib.c: Lines 363 and 367 + Bug reported by Steve Sanders, where &'s where causing the + memcpy to overwrite the pointers. Fixed by removing the &'s + so that memcpy overwrote the memory pointed to. + +1999 09 Feb Toshio Kuratomi + * Release 4.1.0 + +1999 09 Feb Toshio Kuratomi + * Merge libungif changes into the giflib tree: + - upgrade to libtool 1.2b + - util/Makefile.am: Minor change to allow compilation outside the + source_dir. + - lib/egif_lib.c: FILE_STATE_WRITE, FILE_STATE_SCREEN, + FILE_STATE_IMAGE, IS_WRITEABLE are now in gif_lib_private.h + - lib/dgif_lib.c: FILE_STATE_READ and IS_READABLE are now in + gif_lib_private.h + - lib/gif_lib_private.h: Above mentioned constants and macros are now + here. FILE_STATE_READ is now 0x08 instead of 0x00. + - configure.in: Update version to 4.1.0 + - lib/Makefile.am: Update libtool version to 5:0:1 (libtool) + - giflib.spec: Update for version 4.1.0 (Add libungif-4.1 + compatibility stuff and change version.) + - giflib.lsm: Update for version 4.1.0 + - lib/egif_lib.c: (WRITE) change from a function to a macro. + - lib/dgif_lib.c: (DGifOpenFileName) close FileHandle on error. + - lib/dgif_lib.c: (DGifOpenFileHandle) make sure the FILE stream is + closed if we hit an error. + - lib/dev2gif.c, lib/quantize.c, lib/gif_err.c, lib/gif_lib_private.h: + Reflect Eric's copyright notice rather than Gershon's + +1999 14 Jan Michael R Brown + * lib/gif_lib.h: Add OutputFunc type + * lib/gif_lib.h: Add EGifOpen for user supplied output function + * lib/egif_lib.c: (EGifOpenFileName) Fixed wasted memory when an + error occurs in EGifOpenFileHandle + * lib/egif_lib.c: Add EGifOpen, WRITE, and lots of changes to + support user supplied output function. Basically changing + all fwrite's to WRITE, and then all of the knock on effects. + +1998 17 Dec Toshio Kuratomi + * configure.in: Change references to libungif to giflib. + * libungif.lsm: Rename to giflib.lsm and change to reflect giflib + rather than libungif. + * libungif.spec: Rename to giflib.spec and change to reflect giflib + rather than libungif. + * UNCOMPRESSED_GIF: Removed from this branch. + * PATENT_PROBLEMS: Add file explaining Unisys's patent claims. + * Makefile.am: Replace libungif with giflib. + * README: Adapted language to giflib. + * lib/Makefile.am: Changed references to libungif to libgif. + * util/Makefile.am: Changed references to libungif to libgif. + +1998 17 Dec Toshio Kuratomi + * lib/egif_lib.c: Merge LZW stuff into this branch of the library. + This includes numerous changes to initialize the hash table as well + as the code forthe encoder. + * lib/gif_hash.c: Functions needed for the LZW encoder. + * lib/gif_hash.h: Functions needed for the LZW encoder. + * lib/Makefile.am: Add gif_hash.c gif_hash.h to the list of sources. + +1998 15 Dec Toshio Kuratomi + * lib/dgif_lib.c: (DGifSlurp) Fix a Seg Fault when an image contains + no extension blocks. + +1998 14 Dec Toshio Kuratomi + * configure.in: Update version to 4.0 + * lib/Makefile.am: Update libtool version to 4:0:0 (libtool) + * libungif.spec: Update for version 4.0 (not binary compatible with + giflib, change version.) + * lib/gif_lib_private.h: (PrivateType) New header for common stuff + private to the library. Currently, this is only the Private struct. + * lib/dgif_lib.c: (PrivateType) Extract the Private struct to + gif_lib_private.h + * lib/egif_lib.c: (PrivateType) Extract the Private struct to + gif_lib_private.h + * lib/Makefile.am: Add gif_lib_private.h to the list of source files. + * lib/gif_lib.h: (ExtensionBlock) Add a Function entry to the + ExtensionBlock record. Note that this is not entirely correct: + the GifLib ExtensionBlock structure is actually a data sub-block + record. By adding the function entry here, we are pushing the + ExtensionBlockType in with the DataSubBlock. + Sometime in the future, we need to change the API to have true + ExtensionBlocks which have DataSubBlocks belonging to them. + * lib/gif_lib.h: (ExtensionBlock) Deprecate the use of Function in + the SavedImage struct. Use ExtensionBlock's Function instead. + * lib/egif_lib.c: (EGifSpew) Changes to use the new Function variable. + * lib/dgif_lib.c: (DGifSlurp) Changes to put data into the new + Function variable. + +1998 3 Dec Toshio Kuratomi + * lib/dgif_lib.c: (DGifSlurp) Three changes: + - No longer allocate SaveImage in this function. All allocations + of SaveImage take place in DGifGetImageDesc. + - Extension blocks are now associated with the Image Block that is + read in subsequent to them, not before. This should now be + conformant to the gif89a specification. + - Fix an off-by-one error when copying extension data from structure + to structure. + * lib/dgif_lib.c: (DGifGetImageDesc) Change the function to do its own + allocation of space for the SavedImage structure no matter what. + * lib/egif_lib.c: (EGifSpew) The function now spits out + ExtensionBlocks before the associated Image Block to conform with + the gif89a specification. + * lib/egif_lib.c: (EGifOpenFileHandle) Move the write of the + GifVersion (gif87a or gif89a) from this function into + EGifPutScreenDesc so that it can be controlled by EGifSpew. Note + that this is still a hack as the GifVersion write doesn't really + belong in either of these functions. + * lib/egif_lib.c: (EGifPutScreenDesc) Moved writing the version + (gif87a or gif89a) into the file into this function from + EGifOpenFileHandle. + * test-unx: Now test the extension code. + * pic/x-trans.gif: New image with Comments and transparency to test + the extension code with. + +1998 29 Nov Toshio Kuratomi + * lib/dgif_lib.c: (DGifSlurp) Fix a few of the minor bugs plaguing + this function. At this point, the function should no longer cause + a Seg Fault. It is now losing all extension data however. I know + how to hack a fix in, but I need to commit these changes first. + * lib/dgif_lib.c: (DGifGetImageDesc) Fix my bug fix: the colormap is + now only copied if it exists :-). + +1998 10 Nov Toshio Kuratomi + * test-unx: Add a test for DGifSlurp and EGifSpew + +1998 14 Oct Toshio Kuratomi + * lib/dgif_lib.c: (DGifGetImageDesc) Fix a bug where the Colormap for + the image description and the SaveImage were pointers to the same + structure, causing a SegV when DGifClosing the file. + +1998 9 Oct Toshio Kuratomi + * lib/dgif_lib.c: (DGifSlurp) memory for the extensions was not being + allocated. Now I call AddExtensionBlock when I add an extension to + the structure. Additionally, fix a memory leak here. + * configure.in, NEWS, lib/Makefile.am: Update to version 3.1.1 + * ltmain.sh, ltconfig: removed from the cvs repository + * BUGS: add the BUGS file to list unresolved BUGS. + +1998 9 Sep Toshio Kuratomi + * libungif.spec: Fix wrong version in %files and %install section. + +1998 8 Sep Toshio Kuratomi + * lib/gif_hash.c, lib/gif_hash.h: Removed these because a hash table + is not needed to create uncompressed gifs. + * lib/egif_lib.c: Remove all references to the hash functions. + * lib/Makefile.am: Remove gif_hash.c gif_hash.h from the source files. + * libungif.lsm: added this file + +1998 7 Sep Toshio Kuratomi + * lib/dgif_lib.c, lib/gif_lib.h: (DGifOpen) Add callback to read gif + image through user supplied function (Peter Mehlitz). + +1998 6 Sep Toshio Kuratomi + * util/*.{gif.rle}: removed files that were left by my testing + process and shouldn't have been in the distribution. + * UNCOMPRESSED_GIF: add section on why software that can decode + LZW compressed gifs (but not write them) is legal. + * .cvsignore: added .cvsignore files to ignore Makefiles and other + generated files in my cvs repository. + * Makefile.am's: Fixes to allow the dist* family of targets to work + correctly. Preliminary support for make check as well. + * configure.in: Update version to 3.1.0 + * lib/Makefile.am: Update libtool version to 4:0:1 libtool) + * libungif-3.0.spec: Update from Marc Ewing. + * Add int/pointer Alpha fixes from Dick Porter to many source files. diff --git a/WDL/giflib/DEVELOPERS b/WDL/giflib/DEVELOPERS new file mode 100644 index 00000000..2d3f6deb --- /dev/null +++ b/WDL/giflib/DEVELOPERS @@ -0,0 +1,29 @@ +Things to tell developers of libungif.... + +======= +Build Tools: +libungif presently uses autoconf, automake, and libtool in order to build +shared libraries for a wide variety of platforms. The distributed tarball has +files prebuilt from these tools. The cvs repository does not. If you want to +build libungif you will need to have these tools available. I currently run +with the following versions: +autoconf 2.57 +automake 1.7.8 +libtool 1.5 + +(P.S. I use the autogen.sh script in the top level directory to generate +configure, Makefile.in, etc using these tools.) + +======= +cvs: +I currently do my work in a subversion repository. Since sourceforge is still +using cvs and not subversion, there's nothing in the sourceforge tree. + +If someone else wants to do development we can definitely talk about the best +way to share version control access. + +======= +I create the distribution tar ball by using the `make dist` command.... After +hacking all I want, I check my sources into cvs, checkout a clean tree, run +./autogen.sh; make dist and then attempt to compile from the libungif-*.tar.gz +file that is generated. diff --git a/WDL/giflib/README b/WDL/giflib/README new file mode 100644 index 00000000..90e8dbf6 --- /dev/null +++ b/WDL/giflib/README @@ -0,0 +1,69 @@ +This is giflib version 4.1.2, a library for manipulating gif files. It is based +on Eric S. Raymond's giflib-3.0 with bugfixes and changes generated for the +libungif library. + +PLEASE BE AWARE OF POSSIBLE LEGAL PROBLEMS WITH USING THIS LIBRARY: READ +THE PATENT_PROBLEMS FILE NOW! + +======= +Latest versions of giflib, as well as a library which does not have the +mentioned patent problems (libungif), are available from: + http://sourceforge.net/projects/libungif + +==== +Building this package should be as simple as: + + ./configure + gmake + gmake install + +==== +Deprecation list. Will be removed in giflib 5.0: +* GIF_ERROR and GIF_MESSAGE are on the deprecation list as they are also + utility helper functions rather than essential to the functioning of the + library. +* The qprintf methods of the library are now deprecated. Do not use + GifQuietPrint or GifQprintf. These should have been pushed out into the + utility helper library instead of sitting around in the library proper at + the same time as the getarg functions were moved out. Getting rid of these + will let us get rid of our dependence on stdarg.h/varargs.h (Which a Gif + reading library has no business requiring.) +* In the SavedImage struct: int Function will be removed. Use + SavedImage.ExtensionBlocks[x].Function instead. +* In gifalloc.c: MakeExtension is deprecated as well. Use AddExtensionBlock + instead. (This and the previous int Function were deprecated because they + only handle one Extension per image. The new code handles multiple + extensions.) +* varargs style interface in qprintf and getarg: It's a mistake to have two + different interfaces that depend on compile time choices between varargs + and stdargs. The future is to get rid of varargs style altogether. + (Also: these are probably going strictly into the utility functions so + the library won't have to worry about them at all.) +==== + +I have found that automake currently generates Makefile's containing some +GNUmake specific syntax. If you're having troubles building with your +system provided make, please install GNU make and try rebuilding. + +==== +This package uses autoconf, automake, and libtool to create the configure +script, so if you need to edit the configure.ac or change a makefile target +you should read the DEVELOPER file for hints on recreating the distribution +using these tools. + +Good luck! +-Toshio Kuratomi + +==== READ.ME file for giflib version 3.0: + + READ ME for GIFLIB + +For complete documentation on the package, point a web browser at +doc/index.html. See the file INSTALL for instructions on how to +install and test the package. + +GIFLIB has a home page at http://www.ccil.org/~esr/giflib. + + Eric S. Raymond + esr@snark.thyrsus.com. + (http://www.ccil.org/~esr) diff --git a/WDL/giflib/config.h b/WDL/giflib/config.h new file mode 100644 index 00000000..4eadf6c0 --- /dev/null +++ b/WDL/giflib/config.h @@ -0,0 +1,11 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ +#ifdef _WIN32 +#include +#include +#define _OPEN_BINARY +#else +typedef unsigned int UINT32; +#endif +#include +#endif \ No newline at end of file diff --git a/WDL/giflib/dgif_lib.c b/WDL/giflib/dgif_lib.c new file mode 100644 index 00000000..e8580bcd --- /dev/null +++ b/WDL/giflib/dgif_lib.c @@ -0,0 +1,1088 @@ +/****************************************************************************** + * "Gif-Lib" - Yet another gif library. + * + * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 + ****************************************************************************** + * The kernel of the GIF Decoding process can be found here. + ****************************************************************************** + * History: + * 16 Jun 89 - Version 1.0 by Gershon Elber. + * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). + *****************************************************************************/ + +#include "config.h" + +#include +#if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__) +#include +#include +#include +#else +#include +#include +#endif /* __MSDOS__ */ + +#ifdef HAVE_IO_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include "gif_lib.h" +#include "gif_lib_private.h" + +#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for + comment. */ + +/* avoid extra function call in case we use fread (TVT) */ +#define READ(_gif,_buf,_len) \ + (((GifFilePrivateType*)_gif->Private)->Read ? \ + ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ + fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File)) + +static int DGifGetWord(GifFileType *GifFile, GifWord *Word); +static int DGifSetupDecompress(GifFileType *GifFile); +static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, + int LineLen); +static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode); +static int DGifDecompressInput(GifFileType *GifFile, int *Code); +static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, + GifByteType *NextByte); +#ifndef _GBA_NO_FILEIO + +/****************************************************************************** + * Open a new gif file for read, given by its name. + * Returns GifFileType pointer dynamically allocated which serves as the gif + * info record. _GifError is cleared if succesfull. + *****************************************************************************/ +GifFileType * +DGifOpenFileName(const char *FileName) { + int FileHandle; + GifFileType *GifFile; + + if ((FileHandle = open(FileName, O_RDONLY +#if defined(__MSDOS__) || defined(_OPEN_BINARY) + | O_BINARY +#endif /* __MSDOS__ || _OPEN_BINARY */ + )) == -1) { + _GifError = D_GIF_ERR_OPEN_FAILED; + return NULL; + } + + GifFile = DGifOpenFileHandle(FileHandle); + if (GifFile == (GifFileType *)NULL) + close(FileHandle); + return GifFile; +} + +/****************************************************************************** + * Update a new gif file, given its file handle. + * Returns GifFileType pointer dynamically allocated which serves as the gif + * info record. _GifError is cleared if succesfull. + *****************************************************************************/ +GifFileType * +DGifOpenFileHandle(int FileHandle) { + + unsigned char Buf[GIF_STAMP_LEN + 1]; + GifFileType *GifFile; + GifFilePrivateType *Private; + FILE *f; + + GifFile = (GifFileType *)malloc(sizeof(GifFileType)); + if (GifFile == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + memset(GifFile, '\0', sizeof(GifFileType)); + + Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); + if (Private == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + free((char *)GifFile); + return NULL; + } +#ifdef __MSDOS__ + setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* __MSDOS__ */ + + f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ + +#ifdef __MSDOS__ + setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream + buffer. */ +#endif /* __MSDOS__ */ + + GifFile->Private = (VoidPtr)Private; + Private->FileHandle = FileHandle; + Private->File = f; + Private->FileState = FILE_STATE_READ; + Private->Read = 0; /* don't use alternate input method (TVT) */ + GifFile->UserData = 0; /* TVT */ + + /* Lets see if this is a GIF file: */ + if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { + _GifError = D_GIF_ERR_READ_FAILED; + fclose(f); + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + /* The GIF Version number is ignored at this time. Maybe we should do + * something more useful with it. */ + Buf[GIF_STAMP_LEN] = 0; + if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { + _GifError = D_GIF_ERR_NOT_GIF_FILE; + fclose(f); + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { + fclose(f); + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + _GifError = 0; + + return GifFile; +} + +#endif /* _GBA_NO_FILEIO */ + +/****************************************************************************** + * GifFileType constructor with user supplied input function (TVT) + *****************************************************************************/ +GifFileType * +DGifOpen(void *userData, + InputFunc readFunc) { + + unsigned char Buf[GIF_STAMP_LEN + 1]; + GifFileType *GifFile; + GifFilePrivateType *Private; + + GifFile = (GifFileType *)malloc(sizeof(GifFileType)); + if (GifFile == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + memset(GifFile, '\0', sizeof(GifFileType)); + + Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); + if (!Private) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + free((char *)GifFile); + return NULL; + } + + GifFile->Private = (VoidPtr)Private; + Private->FileHandle = 0; + Private->File = 0; + Private->FileState = FILE_STATE_READ; + + Private->Read = readFunc; /* TVT */ + GifFile->UserData = userData; /* TVT */ + + /* Lets see if this is a GIF file: */ + if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { + _GifError = D_GIF_ERR_READ_FAILED; + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + /* The GIF Version number is ignored at this time. Maybe we should do + * something more useful with it. */ + Buf[GIF_STAMP_LEN] = 0; + if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { + _GifError = D_GIF_ERR_NOT_GIF_FILE; + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { + free((char *)Private); + free((char *)GifFile); + return NULL; + } + + _GifError = 0; + + return GifFile; +} + +/****************************************************************************** + * This routine should be called before any other DGif calls. Note that + * this routine is called automatically from DGif file open routines. + *****************************************************************************/ +int +DGifGetScreenDesc(GifFileType * GifFile) { + + int i, BitsPerPixel; + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + /* Put the screen descriptor into the file: */ + if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || + DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) + return GIF_ERROR; + + if (READ(GifFile, Buf, 3) != 3) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; + BitsPerPixel = (Buf[0] & 0x07) + 1; + GifFile->SBackGroundColor = Buf[1]; + if (Buf[0] & 0x80) { /* Do we have global color map? */ + + GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); + if (GifFile->SColorMap == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + + /* Get the global color map: */ + for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { + if (READ(GifFile, Buf, 3) != 3) { + FreeMapObject(GifFile->SColorMap); + GifFile->SColorMap = NULL; + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + GifFile->SColorMap->Colors[i].Red = Buf[0]; + GifFile->SColorMap->Colors[i].Green = Buf[1]; + GifFile->SColorMap->Colors[i].Blue = Buf[2]; + } + } else { + GifFile->SColorMap = NULL; + } + + return GIF_OK; +} + +/****************************************************************************** + * This routine should be called before any attempt to read an image. + *****************************************************************************/ +int +DGifGetRecordType(GifFileType * GifFile, + GifRecordType * Type) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + if (READ(GifFile, &Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + + switch (Buf) { + case ',': + *Type = IMAGE_DESC_RECORD_TYPE; + break; + case '!': + *Type = EXTENSION_RECORD_TYPE; + break; + case ';': + *Type = TERMINATE_RECORD_TYPE; + break; + default: + *Type = UNDEFINED_RECORD_TYPE; + _GifError = D_GIF_ERR_WRONG_RECORD; + return GIF_ERROR; + } + + return GIF_OK; +} + +/****************************************************************************** + * This routine should be called before any attempt to read an image. + * Note it is assumed the Image desc. header (',') has been read. + *****************************************************************************/ +int +DGifGetImageDesc(GifFileType * GifFile) { + + int i, BitsPerPixel; + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + SavedImage *sp; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || + DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || + DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR || + DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) + return GIF_ERROR; + if (READ(GifFile, Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + BitsPerPixel = (Buf[0] & 0x07) + 1; + GifFile->Image.Interlace = (Buf[0] & 0x40); + if (Buf[0] & 0x80) { /* Does this image have local color map? */ + + /*** FIXME: Why do we check both of these in order to do this? + * Why do we have both Image and SavedImages? */ + if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL) + FreeMapObject(GifFile->Image.ColorMap); + + GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); + if (GifFile->Image.ColorMap == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + + /* Get the image local color map: */ + for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { + if (READ(GifFile, Buf, 3) != 3) { + FreeMapObject(GifFile->Image.ColorMap); + _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Image.ColorMap = NULL; + return GIF_ERROR; + } + GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; + GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; + GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; + } + } else if (GifFile->Image.ColorMap) { + FreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + + if (GifFile->SavedImages) { + if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, + sizeof(SavedImage) * + (GifFile->ImageCount + 1))) == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } else { + if ((GifFile->SavedImages = + (SavedImage *) malloc(sizeof(SavedImage))) == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } + + sp = &GifFile->SavedImages[GifFile->ImageCount]; + memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); + if (GifFile->Image.ColorMap != NULL) { + sp->ImageDesc.ColorMap = MakeMapObject( + GifFile->Image.ColorMap->ColorCount, + GifFile->Image.ColorMap->Colors); + if (sp->ImageDesc.ColorMap == NULL) { + _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } + sp->RasterBits = (unsigned char *)NULL; + sp->ExtensionBlockCount = 0; + sp->ExtensionBlocks = (ExtensionBlock *) NULL; + + GifFile->ImageCount++; + + Private->PixelCount = (long)GifFile->Image.Width * + (long)GifFile->Image.Height; + + DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ + + return GIF_OK; +} + +/****************************************************************************** + * Get one full scanned line (Line) of length LineLen from GIF file. + *****************************************************************************/ +int +DGifGetLine(GifFileType * GifFile, + GifPixelType * Line, + int LineLen) { + + GifByteType *Dummy; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + if (!LineLen) + LineLen = GifFile->Image.Width; + +#if defined(__MSDOS__) || defined(__GNUC__) + if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { +#else + if ((Private->PixelCount -= LineLen) > 0xffff0000) { +#endif /* __MSDOS__ */ + _GifError = D_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + + if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { + if (Private->PixelCount == 0) { + /* We probably would not be called any more, so lets clean + * everything before we return: need to flush out all rest of + * image until empty block (size 0) detected. We use GetCodeNext. */ + do + if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) + return GIF_ERROR; + while (Dummy != NULL) ; + } + return GIF_OK; + } else + return GIF_ERROR; +} + +/****************************************************************************** + * Put one pixel (Pixel) into GIF file. + *****************************************************************************/ +int +DGifGetPixel(GifFileType * GifFile, + GifPixelType Pixel) { + + GifByteType *Dummy; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } +#if defined(__MSDOS__) || defined(__GNUC__) + if (--Private->PixelCount > 0xffff0000UL) +#else + if (--Private->PixelCount > 0xffff0000) +#endif /* __MSDOS__ */ + { + _GifError = D_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + + if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { + if (Private->PixelCount == 0) { + /* We probably would not be called any more, so lets clean + * everything before we return: need to flush out all rest of + * image until empty block (size 0) detected. We use GetCodeNext. */ + do + if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) + return GIF_ERROR; + while (Dummy != NULL) ; + } + return GIF_OK; + } else + return GIF_ERROR; +} + +/****************************************************************************** + * Get an extension block (see GIF manual) from gif file. This routine only + * returns the first data block, and DGifGetExtensionNext should be called + * after this one until NULL extension is returned. + * The Extension should NOT be freed by the user (not dynamically allocated). + * Note it is assumed the Extension desc. header ('!') has been read. + *****************************************************************************/ +int +DGifGetExtension(GifFileType * GifFile, + int *ExtCode, + GifByteType ** Extension) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + if (READ(GifFile, &Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + *ExtCode = Buf; + + return DGifGetExtensionNext(GifFile, Extension); +} + +/****************************************************************************** + * Get a following extension block (see GIF manual) from gif file. This + * routine should be called until NULL Extension is returned. + * The Extension should NOT be freed by the user (not dynamically allocated). + *****************************************************************************/ +int +DGifGetExtensionNext(GifFileType * GifFile, + GifByteType ** Extension) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (READ(GifFile, &Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + if (Buf > 0) { + *Extension = Private->Buf; /* Use private unused buffer. */ + (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ + if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + } else + *Extension = NULL; + + return GIF_OK; +} + +/****************************************************************************** + * This routine should be called last, to close the GIF file. + *****************************************************************************/ +int +DGifCloseFile(GifFileType * GifFile) { + + GifFilePrivateType *Private; + FILE *File; + + if (GifFile == NULL) + return GIF_ERROR; + + Private = (GifFilePrivateType *) GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + File = Private->File; + + if (GifFile->Image.ColorMap) { + FreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + + if (GifFile->SColorMap) { + FreeMapObject(GifFile->SColorMap); + GifFile->SColorMap = NULL; + } + + if (Private) { + free((char *)Private); + Private = NULL; + } + + if (GifFile->SavedImages) { + FreeSavedImages(GifFile); + GifFile->SavedImages = NULL; + } + + free(GifFile); + + if (File && (fclose(File) != 0)) { + _GifError = D_GIF_ERR_CLOSE_FAILED; + return GIF_ERROR; + } + return GIF_OK; +} + +/****************************************************************************** + * Get 2 bytes (word) from the given file: + *****************************************************************************/ +static int +DGifGetWord(GifFileType * GifFile, + GifWord *Word) { + + unsigned char c[2]; + + if (READ(GifFile, c, 2) != 2) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + + *Word = (((unsigned int)c[1]) << 8) + c[0]; + return GIF_OK; +} + +/****************************************************************************** + * Get the image code in compressed form. This routine can be called if the + * information needed to be piped out as is. Obviously this is much faster + * than decoding and encoding again. This routine should be followed by calls + * to DGifGetCodeNext, until NULL block is returned. + * The block should NOT be freed by the user (not dynamically allocated). + *****************************************************************************/ +int +DGifGetCode(GifFileType * GifFile, + int *CodeSize, + GifByteType ** CodeBlock) { + + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + *CodeSize = Private->BitsPerPixel; + + return DGifGetCodeNext(GifFile, CodeBlock); +} + +/****************************************************************************** + * Continue to get the image code in compressed form. This routine should be + * called until NULL block is returned. + * The block should NOT be freed by the user (not dynamically allocated). + *****************************************************************************/ +int +DGifGetCodeNext(GifFileType * GifFile, + GifByteType ** CodeBlock) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (READ(GifFile, &Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + + if (Buf > 0) { + *CodeBlock = Private->Buf; /* Use private unused buffer. */ + (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ + if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + } else { + *CodeBlock = NULL; + Private->Buf[0] = 0; /* Make sure the buffer is empty! */ + Private->PixelCount = 0; /* And local info. indicate image read. */ + } + + return GIF_OK; +} + +/****************************************************************************** + * Setup the LZ decompression for this image: + *****************************************************************************/ +static int +DGifSetupDecompress(GifFileType * GifFile) { + + int i, BitsPerPixel; + GifByteType CodeSize; + GifPrefixType *Prefix; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + READ(GifFile, &CodeSize, 1); /* Read Code size from file. */ + BitsPerPixel = CodeSize; + + Private->Buf[0] = 0; /* Input Buffer empty. */ + Private->BitsPerPixel = BitsPerPixel; + Private->ClearCode = (1 << BitsPerPixel); + Private->EOFCode = Private->ClearCode + 1; + Private->RunningCode = Private->EOFCode + 1; + Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ + Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ + Private->StackPtr = 0; /* No pixels on the pixel stack. */ + Private->LastCode = NO_SUCH_CODE; + Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ + Private->CrntShiftDWord = 0; + + Prefix = Private->Prefix; + for (i = 0; i <= LZ_MAX_CODE; i++) + Prefix[i] = NO_SUCH_CODE; + + return GIF_OK; +} + +/****************************************************************************** + * The LZ decompression routine: + * This version decompress the given gif file into Line of length LineLen. + * This routine can be called few times (one per scan line, for example), in + * order the complete the whole image. + *****************************************************************************/ +static int +DGifDecompressLine(GifFileType * GifFile, + GifPixelType * Line, + int LineLen) { + + int i = 0; + int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; + GifByteType *Stack, *Suffix; + GifPrefixType *Prefix; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + StackPtr = Private->StackPtr; + Prefix = Private->Prefix; + Suffix = Private->Suffix; + Stack = Private->Stack; + EOFCode = Private->EOFCode; + ClearCode = Private->ClearCode; + LastCode = Private->LastCode; + + if (StackPtr != 0) { + /* Let pop the stack off before continueing to read the gif file: */ + while (StackPtr != 0 && i < LineLen) + Line[i++] = Stack[--StackPtr]; + } + + while (i < LineLen) { /* Decode LineLen items. */ + if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) + return GIF_ERROR; + + if (CrntCode == EOFCode) { + /* Note however that usually we will not be here as we will stop + * decoding as soon as we got all the pixel, or EOF code will + * not be read at all, and DGifGetLine/Pixel clean everything. */ + if (i != LineLen - 1 || Private->PixelCount != 0) { + _GifError = D_GIF_ERR_EOF_TOO_SOON; + return GIF_ERROR; + } + i++; + } else if (CrntCode == ClearCode) { + /* We need to start over again: */ + for (j = 0; j <= LZ_MAX_CODE; j++) + Prefix[j] = NO_SUCH_CODE; + Private->RunningCode = Private->EOFCode + 1; + Private->RunningBits = Private->BitsPerPixel + 1; + Private->MaxCode1 = 1 << Private->RunningBits; + LastCode = Private->LastCode = NO_SUCH_CODE; + } else { + /* Its regular code - if in pixel range simply add it to output + * stream, otherwise trace to codes linked list until the prefix + * is in pixel range: */ + if (CrntCode < ClearCode) { + /* This is simple - its pixel scalar, so add it to output: */ + Line[i++] = CrntCode; + } else { + /* Its a code to needed to be traced: trace the linked list + * until the prefix is a pixel, while pushing the suffix + * pixels on our stack. If we done, pop the stack in reverse + * (thats what stack is good for!) order to output. */ + if (Prefix[CrntCode] == NO_SUCH_CODE) { + /* Only allowed if CrntCode is exactly the running code: + * In that case CrntCode = XXXCode, CrntCode or the + * prefix code is last code and the suffix char is + * exactly the prefix of last code! */ + if (CrntCode == Private->RunningCode - 2) { + CrntPrefix = LastCode; + Suffix[Private->RunningCode - 2] = + Stack[StackPtr++] = DGifGetPrefixChar(Prefix, + LastCode, + ClearCode); + } else { + _GifError = D_GIF_ERR_IMAGE_DEFECT; + return GIF_ERROR; + } + } else + CrntPrefix = CrntCode; + + /* Now (if image is O.K.) we should not get an NO_SUCH_CODE + * During the trace. As we might loop forever, in case of + * defective image, we count the number of loops we trace + * and stop if we got LZ_MAX_CODE. obviously we can not + * loop more than that. */ + j = 0; + while (j++ <= LZ_MAX_CODE && + CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { + Stack[StackPtr++] = Suffix[CrntPrefix]; + CrntPrefix = Prefix[CrntPrefix]; + } + if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { + _GifError = D_GIF_ERR_IMAGE_DEFECT; + return GIF_ERROR; + } + /* Push the last character on stack: */ + Stack[StackPtr++] = CrntPrefix; + + /* Now lets pop all the stack into output: */ + while (StackPtr != 0 && i < LineLen) + Line[i++] = Stack[--StackPtr]; + } + if (LastCode != NO_SUCH_CODE) { + Prefix[Private->RunningCode - 2] = LastCode; + + if (CrntCode == Private->RunningCode - 2) { + /* Only allowed if CrntCode is exactly the running code: + * In that case CrntCode = XXXCode, CrntCode or the + * prefix code is last code and the suffix char is + * exactly the prefix of last code! */ + Suffix[Private->RunningCode - 2] = + DGifGetPrefixChar(Prefix, LastCode, ClearCode); + } else { + Suffix[Private->RunningCode - 2] = + DGifGetPrefixChar(Prefix, CrntCode, ClearCode); + } + } + LastCode = CrntCode; + } + } + + Private->LastCode = LastCode; + Private->StackPtr = StackPtr; + + return GIF_OK; +} + +/****************************************************************************** + * Routine to trace the Prefixes linked list until we get a prefix which is + * not code, but a pixel value (less than ClearCode). Returns that pixel value. + * If image is defective, we might loop here forever, so we limit the loops to + * the maximum possible if image O.k. - LZ_MAX_CODE times. + *****************************************************************************/ +static int +DGifGetPrefixChar(GifPrefixType *Prefix, + int Code, + int ClearCode) { + + int i = 0; + + while (Code > ClearCode && i++ <= LZ_MAX_CODE) + Code = Prefix[Code]; + return Code; +} + +/****************************************************************************** + * Interface for accessing the LZ codes directly. Set Code to the real code + * (12bits), or to -1 if EOF code is returned. + *****************************************************************************/ +int +DGifGetLZCodes(GifFileType * GifFile, + int *Code) { + + GifByteType *CodeBlock; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_READABLE(Private)) { + /* This file was NOT open for reading: */ + _GifError = D_GIF_ERR_NOT_READABLE; + return GIF_ERROR; + } + + if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) + return GIF_ERROR; + + if (*Code == Private->EOFCode) { + /* Skip rest of codes (hopefully only NULL terminating block): */ + do { + if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) + return GIF_ERROR; + } while (CodeBlock != NULL) ; + + *Code = -1; + } else if (*Code == Private->ClearCode) { + /* We need to start over again: */ + Private->RunningCode = Private->EOFCode + 1; + Private->RunningBits = Private->BitsPerPixel + 1; + Private->MaxCode1 = 1 << Private->RunningBits; + } + + return GIF_OK; +} + +/****************************************************************************** + * The LZ decompression input routine: + * This routine is responsable for the decompression of the bit stream from + * 8 bits (bytes) packets, into the real codes. + * Returns GIF_OK if read succesfully. + *****************************************************************************/ +static int +DGifDecompressInput(GifFileType * GifFile, + int *Code) { + + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + GifByteType NextByte; + static unsigned short CodeMasks[] = { + 0x0000, 0x0001, 0x0003, 0x0007, + 0x000f, 0x001f, 0x003f, 0x007f, + 0x00ff, 0x01ff, 0x03ff, 0x07ff, + 0x0fff + }; + /* The image can't contain more than LZ_BITS per code. */ + if (Private->RunningBits > LZ_BITS) { + _GifError = D_GIF_ERR_IMAGE_DEFECT; + return GIF_ERROR; + } + + while (Private->CrntShiftState < Private->RunningBits) { + /* Needs to get more bytes from input stream for next code: */ + if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { + return GIF_ERROR; + } + Private->CrntShiftDWord |= + ((unsigned long)NextByte) << Private->CrntShiftState; + Private->CrntShiftState += 8; + } + *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; + + Private->CrntShiftDWord >>= Private->RunningBits; + Private->CrntShiftState -= Private->RunningBits; + + /* If code cannot fit into RunningBits bits, must raise its size. Note + * however that codes above 4095 are used for special signaling. + * If we're using LZ_BITS bits already and we're at the max code, just + * keep using the table as it is, don't increment Private->RunningCode. + */ + if (Private->RunningCode < LZ_MAX_CODE + 2 && + ++Private->RunningCode > Private->MaxCode1 && + Private->RunningBits < LZ_BITS) { + Private->MaxCode1 <<= 1; + Private->RunningBits++; + } + return GIF_OK; +} + +/****************************************************************************** + * This routines read one gif data block at a time and buffers it internally + * so that the decompression routine could access it. + * The routine returns the next byte from its internal buffer (or read next + * block in if buffer empty) and returns GIF_OK if succesful. + *****************************************************************************/ +static int +DGifBufferedInput(GifFileType * GifFile, + GifByteType * Buf, + GifByteType * NextByte) { + + if (Buf[0] == 0) { + /* Needs to read the next buffer - this one is empty: */ + if (READ(GifFile, Buf, 1) != 1) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + /* There shouldn't be any empty data blocks here as the LZW spec + * says the LZW termination code should come first. Therefore we + * shouldn't be inside this routine at that point. + */ + if (Buf[0] == 0) { + _GifError = D_GIF_ERR_IMAGE_DEFECT; + return GIF_ERROR; + } + if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) { + _GifError = D_GIF_ERR_READ_FAILED; + return GIF_ERROR; + } + *NextByte = Buf[1]; + Buf[1] = 2; /* We use now the second place as last char read! */ + Buf[0]--; + } else { + *NextByte = Buf[Buf[1]++]; + Buf[0]--; + } + + return GIF_OK; +} +#ifndef _GBA_NO_FILEIO + +/****************************************************************************** + * This routine reads an entire GIF into core, hanging all its state info off + * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() + * first to initialize I/O. Its inverse is EGifSpew(). + ******************************************************************************/ +int +DGifSlurp(GifFileType * GifFile) { + + int ImageSize; + GifRecordType RecordType; + SavedImage *sp; + GifByteType *ExtData; + SavedImage temp_save; + + temp_save.ExtensionBlocks = NULL; + temp_save.ExtensionBlockCount = 0; + + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) + return (GIF_ERROR); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) + return (GIF_ERROR); + + sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; + ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; + + sp->RasterBits = (unsigned char *)malloc(ImageSize * + sizeof(GifPixelType)); + if (sp->RasterBits == NULL) { + return GIF_ERROR; + } + if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == + GIF_ERROR) + return (GIF_ERROR); + if (temp_save.ExtensionBlocks) { + sp->ExtensionBlocks = temp_save.ExtensionBlocks; + sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; + + temp_save.ExtensionBlocks = NULL; + temp_save.ExtensionBlockCount = 0; + + /* FIXME: The following is wrong. It is left in only for + * backwards compatibility. Someday it should go away. Use + * the sp->ExtensionBlocks->Function variable instead. */ + sp->Function = sp->ExtensionBlocks[0].Function; + } + break; + + case EXTENSION_RECORD_TYPE: + if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) == + GIF_ERROR) + return (GIF_ERROR); + while (ExtData != NULL) { + + /* Create an extension block with our data */ + if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) + == GIF_ERROR) + return (GIF_ERROR); + + if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) + return (GIF_ERROR); + temp_save.Function = 0; + } + break; + + case TERMINATE_RECORD_TYPE: + break; + + default: /* Should be trapped by DGifGetRecordType */ + break; + } + } while (RecordType != TERMINATE_RECORD_TYPE); + + /* Just in case the Gif has an extension block without an associated + * image... (Should we save this into a savefile structure with no image + * instead? Have to check if the present writing code can handle that as + * well.... */ + if (temp_save.ExtensionBlocks) + FreeExtension(&temp_save); + + return (GIF_OK); +} +#endif /* _GBA_NO_FILEIO */ diff --git a/WDL/giflib/egif_lib.c b/WDL/giflib/egif_lib.c new file mode 100644 index 00000000..91eae003 --- /dev/null +++ b/WDL/giflib/egif_lib.c @@ -0,0 +1,1103 @@ +/****************************************************************************** + * "Gif-Lib" - Yet another gif library. + * + * Written by: Gershon Elber Ver 1.1, Aug. 1990 + ****************************************************************************** + * The kernel of the GIF Encoding process can be found here. + ****************************************************************************** + * History: + * 14 Jun 89 - Version 1.0 by Gershon Elber. + * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). + * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) + *****************************************************************************/ + +#include "config.h" + +/* Find a thirty-two bit int type */ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif + +#ifdef __MSDOS__ +#include +#include +#include +#else +#include +#include +#ifdef R6000 + +/* FIXME: What is sys/mode.h? Can we substitute a check for this file rather + * than a check based on machine type? + */ +#include +#endif +#endif /* __MSDOS__ */ + +#ifdef HAVE_IO_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include +#include +#include +#include "gif_lib.h" +#include "gif_lib_private.h" + +/* #define DEBUG_NO_PREFIX Dump only compressed data. */ + +/* Masks given codes to BitsPerPixel, to make sure all codes are in range: */ +static GifPixelType CodeMask[] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff +}; + +static char GifVersionPrefix[GIF_STAMP_LEN + 1] = GIF87_STAMP; + +#define WRITE(_gif,_buf,_len) \ + (((GifFilePrivateType*)_gif->Private)->Write ? \ + ((GifFilePrivateType*)_gif->Private)->Write(_gif,_buf,_len) : \ + fwrite(_buf, 1, _len, ((GifFilePrivateType*)_gif->Private)->File)) + +static int EGifPutWord(int Word, GifFileType * GifFile); +static int EGifSetupCompress(GifFileType * GifFile); +static int EGifCompressLine(GifFileType * GifFile, GifPixelType * Line, + int LineLen); +static int EGifCompressOutput(GifFileType * GifFile, int Code); +static int EGifBufferedOutput(GifFileType * GifFile, GifByteType * Buf, + int c); + +/****************************************************************************** + * Open a new gif file for write, given by its name. If TestExistance then + * if the file exists this routines fails (returns NULL). + * Returns GifFileType pointer dynamically allocated which serves as the gif + * info record. _GifError is cleared if succesfull. + *****************************************************************************/ +GifFileType * +EGifOpenFileName(const char *FileName, + int TestExistance) { + + int FileHandle; + GifFileType *GifFile; + + if (TestExistance) + FileHandle = open(FileName, O_WRONLY | O_CREAT | O_EXCL +#if defined(__MSDOS__) || defined(_WIN32) + | O_BINARY +#endif /* __MSDOS__ */ + , 0644 ); + else + FileHandle = open(FileName, O_WRONLY | O_CREAT | O_TRUNC +#if defined(__MSDOS__) || defined(_WIN32) + | O_BINARY +#endif /* __MSDOS__ */ + , 0644 ); + + if (FileHandle == -1) { + _GifError = E_GIF_ERR_OPEN_FAILED; + return NULL; + } + GifFile = EGifOpenFileHandle(FileHandle); + if (GifFile == (GifFileType *) NULL) + close(FileHandle); + return GifFile; +} + +/****************************************************************************** + * Update a new gif file, given its file handle, which must be opened for + * write in binary mode. + * Returns GifFileType pointer dynamically allocated which serves as the gif + * info record. _GifError is cleared if succesfull. + *****************************************************************************/ +GifFileType * +EGifOpenFileHandle(int FileHandle) { + + GifFileType *GifFile; + GifFilePrivateType *Private; + FILE *f; + + GifFile = (GifFileType *) malloc(sizeof(GifFileType)); + if (GifFile == NULL) { + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + memset(GifFile, '\0', sizeof(GifFileType)); + + Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); + if (Private == NULL) { + free(GifFile); + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + if ((Private->HashTable = _InitHashTable()) == NULL) { + free(GifFile); + free(Private); + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + +#ifdef __MSDOS__ + setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* __MSDOS__ */ + + f = fdopen(FileHandle, "wb"); /* Make it into a stream: */ + +#ifdef __MSDOS__ + setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream + * buffer. */ +#endif /* __MSDOS__ */ + + GifFile->Private = (VoidPtr)Private; + Private->FileHandle = FileHandle; + Private->File = f; + Private->FileState = FILE_STATE_WRITE; + + Private->Write = (OutputFunc) 0; /* No user write routine (MRB) */ + GifFile->UserData = (VoidPtr) 0; /* No user write handle (MRB) */ + + _GifError = 0; + + return GifFile; +} + +/****************************************************************************** + * Output constructor that takes user supplied output function. + * Basically just a copy of EGifOpenFileHandle. (MRB) + *****************************************************************************/ +GifFileType * +EGifOpen(void *userData, + OutputFunc writeFunc) { + + GifFileType *GifFile; + GifFilePrivateType *Private; + + GifFile = (GifFileType *)malloc(sizeof(GifFileType)); + if (GifFile == NULL) { + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + memset(GifFile, '\0', sizeof(GifFileType)); + + Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); + if (Private == NULL) { + free(GifFile); + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + Private->HashTable = _InitHashTable(); + if (Private->HashTable == NULL) { + free (GifFile); + free (Private); + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return NULL; + } + + GifFile->Private = (VoidPtr) Private; + Private->FileHandle = 0; + Private->File = (FILE *) 0; + Private->FileState = FILE_STATE_WRITE; + + Private->Write = writeFunc; /* User write routine (MRB) */ + GifFile->UserData = userData; /* User write handle (MRB) */ + + _GifError = 0; + + return GifFile; +} + +/****************************************************************************** + * Routine to set current GIF version. All files open for write will be + * using this version until next call to this routine. Version consists of + * 3 characters as "87a" or "89a". No test is made to validate the version. + *****************************************************************************/ +void +EGifSetGifVersion(const char *Version) { + strncpy(GifVersionPrefix + GIF_VERSION_POS, Version, 3); +} + +/****************************************************************************** + * This routine should be called before any other EGif calls, immediately + * follows the GIF file openning. + *****************************************************************************/ +int +EGifPutScreenDesc(GifFileType * GifFile, + int Width, + int Height, + int ColorRes, + int BackGround, + const ColorMapObject * ColorMap) { + + int i; + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + if (Private->FileState & FILE_STATE_SCREEN) { + /* If already has screen descriptor - something is wrong! */ + _GifError = E_GIF_ERR_HAS_SCRN_DSCR; + return GIF_ERROR; + } + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + +/* First write the version prefix into the file. */ +#ifndef DEBUG_NO_PREFIX + if (WRITE(GifFile, (unsigned char *)GifVersionPrefix, + strlen(GifVersionPrefix)) != strlen(GifVersionPrefix)) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } +#endif /* DEBUG_NO_PREFIX */ + + GifFile->SWidth = Width; + GifFile->SHeight = Height; + GifFile->SColorResolution = ColorRes; + GifFile->SBackGroundColor = BackGround; + if (ColorMap) { + GifFile->SColorMap = MakeMapObject(ColorMap->ColorCount, + ColorMap->Colors); + if (GifFile->SColorMap == NULL) { + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } else + GifFile->SColorMap = NULL; + + /* + * Put the logical screen descriptor into the file: + */ + /* Logical Screen Descriptor: Dimensions */ + EGifPutWord(Width, GifFile); + EGifPutWord(Height, GifFile); + + /* Logical Screen Descriptor: Packed Fields */ + /* Note: We have actual size of the color table default to the largest + * possible size (7+1 == 8 bits) because the decoder can use it to decide + * how to display the files. + */ + Buf[0] = (ColorMap ? 0x80 : 0x00) | /* Yes/no global colormap */ + ((ColorRes - 1) << 4) | /* Bits allocated to each primary color */ + (ColorMap ? ColorMap->BitsPerPixel - 1 : 0x07 ); /* Actual size of the + color table. */ + Buf[1] = BackGround; /* Index into the ColorTable for background color */ + Buf[2] = 0; /* Pixel Aspect Ratio */ +#ifndef DEBUG_NO_PREFIX + WRITE(GifFile, Buf, 3); +#endif /* DEBUG_NO_PREFIX */ + + /* If we have Global color map - dump it also: */ +#ifndef DEBUG_NO_PREFIX + if (ColorMap != NULL) + for (i = 0; i < ColorMap->ColorCount; i++) { + /* Put the ColorMap out also: */ + Buf[0] = ColorMap->Colors[i].Red; + Buf[1] = ColorMap->Colors[i].Green; + Buf[2] = ColorMap->Colors[i].Blue; + if (WRITE(GifFile, Buf, 3) != 3) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + } +#endif /* DEBUG_NO_PREFIX */ + + /* Mark this file as has screen descriptor, and no pixel written yet: */ + Private->FileState |= FILE_STATE_SCREEN; + + return GIF_OK; +} + +/****************************************************************************** + * This routine should be called before any attempt to dump an image - any + * call to any of the pixel dump routines. + *****************************************************************************/ +int +EGifPutImageDesc(GifFileType * GifFile, + int Left, + int Top, + int Width, + int Height, + int Interlace, + const ColorMapObject * ColorMap) { + + int i; + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (Private->FileState & FILE_STATE_IMAGE && +#if defined(__MSDOS__) || defined(__GNUC__) + Private->PixelCount > 0xffff0000UL) { +#else + Private->PixelCount > 0xffff0000) { +#endif /* __MSDOS__ */ + /* If already has active image descriptor - something is wrong! */ + _GifError = E_GIF_ERR_HAS_IMAG_DSCR; + return GIF_ERROR; + } + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + GifFile->Image.Left = Left; + GifFile->Image.Top = Top; + GifFile->Image.Width = Width; + GifFile->Image.Height = Height; + GifFile->Image.Interlace = Interlace; + if (ColorMap) { + GifFile->Image.ColorMap = MakeMapObject(ColorMap->ColorCount, + ColorMap->Colors); + if (GifFile->Image.ColorMap == NULL) { + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } else { + GifFile->Image.ColorMap = NULL; + } + + /* Put the image descriptor into the file: */ + Buf[0] = ','; /* Image seperator character. */ +#ifndef DEBUG_NO_PREFIX + WRITE(GifFile, Buf, 1); +#endif /* DEBUG_NO_PREFIX */ + EGifPutWord(Left, GifFile); + EGifPutWord(Top, GifFile); + EGifPutWord(Width, GifFile); + EGifPutWord(Height, GifFile); + Buf[0] = (ColorMap ? 0x80 : 0x00) | + (Interlace ? 0x40 : 0x00) | + (ColorMap ? ColorMap->BitsPerPixel - 1 : 0); +#ifndef DEBUG_NO_PREFIX + WRITE(GifFile, Buf, 1); +#endif /* DEBUG_NO_PREFIX */ + + /* If we have Global color map - dump it also: */ +#ifndef DEBUG_NO_PREFIX + if (ColorMap != NULL) + for (i = 0; i < ColorMap->ColorCount; i++) { + /* Put the ColorMap out also: */ + Buf[0] = ColorMap->Colors[i].Red; + Buf[1] = ColorMap->Colors[i].Green; + Buf[2] = ColorMap->Colors[i].Blue; + if (WRITE(GifFile, Buf, 3) != 3) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + } +#endif /* DEBUG_NO_PREFIX */ + if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) { + _GifError = E_GIF_ERR_NO_COLOR_MAP; + return GIF_ERROR; + } + + /* Mark this file as has screen descriptor: */ + Private->FileState |= FILE_STATE_IMAGE; + Private->PixelCount = (long)Width *(long)Height; + + EGifSetupCompress(GifFile); /* Reset compress algorithm parameters. */ + + return GIF_OK; +} + +/****************************************************************************** + * Put one full scanned line (Line) of length LineLen into GIF file. + *****************************************************************************/ +int +EGifPutLine(GifFileType * GifFile, + GifPixelType * Line, + int LineLen) { + + int i; + GifPixelType Mask; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + if (!LineLen) + LineLen = GifFile->Image.Width; + if (Private->PixelCount < (unsigned)LineLen) { + _GifError = E_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + Private->PixelCount -= LineLen; + + /* Make sure the codes are not out of bit range, as we might generate + * wrong code (because of overflow when we combine them) in this case: */ + Mask = CodeMask[Private->BitsPerPixel]; + for (i = 0; i < LineLen; i++) + Line[i] &= Mask; + + return EGifCompressLine(GifFile, Line, LineLen); +} + +/****************************************************************************** + * Put one pixel (Pixel) into GIF file. + *****************************************************************************/ +int +EGifPutPixel(GifFileType * GifFile, + GifPixelType Pixel) { + + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + if (Private->PixelCount == 0) { + _GifError = E_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + --Private->PixelCount; + + /* Make sure the code is not out of bit range, as we might generate + * wrong code (because of overflow when we combine them) in this case: */ + Pixel &= CodeMask[Private->BitsPerPixel]; + + return EGifCompressLine(GifFile, &Pixel, 1); +} + +/****************************************************************************** + * Put a comment into GIF file using the GIF89 comment extension block. + *****************************************************************************/ +int +EGifPutComment(GifFileType * GifFile, + const char *Comment) { + + unsigned int length = strlen(Comment); + char *buf; + + length = strlen(Comment); + if (length <= 255) { + return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE, + length, Comment); + } else { + buf = (char *)Comment; + if (EGifPutExtensionFirst(GifFile, COMMENT_EXT_FUNC_CODE, 255, buf) + == GIF_ERROR) { + return GIF_ERROR; + } + length -= 255; + buf = buf + 255; + + /* Break the comment into 255 byte sub blocks */ + while (length > 255) { + if (EGifPutExtensionNext(GifFile, 0, 255, buf) == GIF_ERROR) { + return GIF_ERROR; + } + buf = buf + 255; + length -= 255; + } + /* Output any partial block and the clear code. */ + if (length > 0) { + if (EGifPutExtensionLast(GifFile, 0, length, buf) == GIF_ERROR) { + return GIF_ERROR; + } + } else { + if (EGifPutExtensionLast(GifFile, 0, 0, NULL) == GIF_ERROR) { + return GIF_ERROR; + } + } + } + return GIF_OK; +} + +/****************************************************************************** + * Put a first extension block (see GIF manual) into gif file. Here more + * extensions can be dumped using EGifPutExtensionNext until + * EGifPutExtensionLast is invoked. + *****************************************************************************/ +int +EGifPutExtensionFirst(GifFileType * GifFile, + int ExtCode, + int ExtLen, + const VoidPtr Extension) { + + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + if (ExtCode == 0) { + WRITE(GifFile, (GifByteType *)&ExtLen, 1); + } else { + Buf[0] = '!'; + Buf[1] = ExtCode; + Buf[2] = ExtLen; + WRITE(GifFile, Buf, 3); + } + + WRITE(GifFile, Extension, ExtLen); + + return GIF_OK; +} + +/****************************************************************************** + * Put a middle extension block (see GIF manual) into gif file. + *****************************************************************************/ +int +EGifPutExtensionNext(GifFileType * GifFile, + int ExtCode, + int ExtLen, + const VoidPtr Extension) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + Buf = ExtLen; + WRITE(GifFile, &Buf, 1); + WRITE(GifFile, Extension, ExtLen); + + return GIF_OK; +} + +/****************************************************************************** + * Put a last extension block (see GIF manual) into gif file. + *****************************************************************************/ +int +EGifPutExtensionLast(GifFileType * GifFile, + int ExtCode, + int ExtLen, + const VoidPtr Extension) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + /* If we are given an extension sub-block output it now. */ + if (ExtLen > 0) { + Buf = ExtLen; + WRITE(GifFile, &Buf, 1); + WRITE(GifFile, Extension, ExtLen); + } + + /* Write the block terminator */ + Buf = 0; + WRITE(GifFile, &Buf, 1); + + return GIF_OK; +} + +/****************************************************************************** + * Put an extension block (see GIF manual) into gif file. + * Warning: This function is only useful for Extension blocks that have at + * most one subblock. Extensions with more than one subblock need to use the + * EGifPutExtension{First,Next,Last} functions instead. + *****************************************************************************/ +int +EGifPutExtension(GifFileType * GifFile, + int ExtCode, + int ExtLen, + const VoidPtr Extension) { + + GifByteType Buf[3]; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + if (ExtCode == 0) + WRITE(GifFile, (GifByteType *)&ExtLen, 1); + else { + Buf[0] = '!'; /* Extension Introducer 0x21 */ + Buf[1] = ExtCode; /* Extension Label */ + Buf[2] = ExtLen; /* Extension length */ + WRITE(GifFile, Buf, ExtCode==0xff ? 2 : 3); + } + WRITE(GifFile, Extension, ExtLen); + Buf[0] = 0; + WRITE(GifFile, Buf, 1); + + return GIF_OK; +} + +/****************************************************************************** + * Put the image code in compressed form. This routine can be called if the + * information needed to be piped out as is. Obviously this is much faster + * than decoding and encoding again. This routine should be followed by calls + * to EGifPutCodeNext, until NULL block is given. + * The block should NOT be freed by the user (not dynamically allocated). + *****************************************************************************/ +int +EGifPutCode(GifFileType * GifFile, + int CodeSize, + const GifByteType * CodeBlock) { + + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + /* No need to dump code size as Compression set up does any for us: */ + /* + * Buf = CodeSize; + * if (WRITE(GifFile, &Buf, 1) != 1) { + * _GifError = E_GIF_ERR_WRITE_FAILED; + * return GIF_ERROR; + * } + */ + + return EGifPutCodeNext(GifFile, CodeBlock); +} + +/****************************************************************************** + * Continue to put the image code in compressed form. This routine should be + * called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If + * given buffer pointer is NULL, empty block is written to mark end of code. + *****************************************************************************/ +int +EGifPutCodeNext(GifFileType * GifFile, + const GifByteType * CodeBlock) { + + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + + if (CodeBlock != NULL) { + if (WRITE(GifFile, CodeBlock, CodeBlock[0] + 1) + != (unsigned)(CodeBlock[0] + 1)) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + } else { + Buf = 0; + if (WRITE(GifFile, &Buf, 1) != 1) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + Private->PixelCount = 0; /* And local info. indicate image read. */ + } + + return GIF_OK; +} + +/****************************************************************************** + * This routine should be called last, to close GIF file. + *****************************************************************************/ +int +EGifCloseFile(GifFileType * GifFile) { + + GifByteType Buf; + GifFilePrivateType *Private; + FILE *File; + + if (GifFile == NULL) + return GIF_ERROR; + + Private = (GifFilePrivateType *) GifFile->Private; + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + _GifError = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } + + File = Private->File; + + Buf = ';'; + WRITE(GifFile, &Buf, 1); + + if (GifFile->Image.ColorMap) { + FreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + if (GifFile->SColorMap) { + FreeMapObject(GifFile->SColorMap); + GifFile->SColorMap = NULL; + } + if (Private) { + if (Private->HashTable) { + free((char *) Private->HashTable); + } + free((char *) Private); + } + free(GifFile); + + if (File && fclose(File) != 0) { + _GifError = E_GIF_ERR_CLOSE_FAILED; + return GIF_ERROR; + } + return GIF_OK; +} + +/****************************************************************************** + * Put 2 bytes (word) into the given file: + *****************************************************************************/ +static int +EGifPutWord(int Word, + GifFileType * GifFile) { + + unsigned char c[2]; + + c[0] = Word & 0xff; + c[1] = (Word >> 8) & 0xff; +#ifndef DEBUG_NO_PREFIX + if (WRITE(GifFile, c, 2) == 2) + return GIF_OK; + else + return GIF_ERROR; +#else + return GIF_OK; +#endif /* DEBUG_NO_PREFIX */ +} + +/****************************************************************************** + * Setup the LZ compression for this image: + *****************************************************************************/ +static int +EGifSetupCompress(GifFileType * GifFile) { + + int BitsPerPixel; + GifByteType Buf; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + /* Test and see what color map to use, and from it # bits per pixel: */ + if (GifFile->Image.ColorMap) + BitsPerPixel = GifFile->Image.ColorMap->BitsPerPixel; + else if (GifFile->SColorMap) + BitsPerPixel = GifFile->SColorMap->BitsPerPixel; + else { + _GifError = E_GIF_ERR_NO_COLOR_MAP; + return GIF_ERROR; + } + + Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel); + WRITE(GifFile, &Buf, 1); /* Write the Code size to file. */ + + Private->Buf[0] = 0; /* Nothing was output yet. */ + Private->BitsPerPixel = BitsPerPixel; + Private->ClearCode = (1 << BitsPerPixel); + Private->EOFCode = Private->ClearCode + 1; + Private->RunningCode = Private->EOFCode + 1; + Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ + Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ + Private->CrntCode = FIRST_CODE; /* Signal that this is first one! */ + Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ + Private->CrntShiftDWord = 0; + + /* Clear hash table and send Clear to make sure the decoder do the same. */ + _ClearHashTable(Private->HashTable); + + if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + return GIF_OK; +} + +/****************************************************************************** + * The LZ compression routine: + * This version compresses the given buffer Line of length LineLen. + * This routine can be called a few times (one per scan line, for example), in + * order to complete the whole image. +******************************************************************************/ +static int +EGifCompressLine(GifFileType * GifFile, + GifPixelType * Line, + int LineLen) { + + int i = 0, CrntCode, NewCode; + unsigned long NewKey; + GifPixelType Pixel; + GifHashTableType *HashTable; + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + + HashTable = Private->HashTable; + + if (Private->CrntCode == FIRST_CODE) /* Its first time! */ + CrntCode = Line[i++]; + else + CrntCode = Private->CrntCode; /* Get last code in compression. */ + + while (i < LineLen) { /* Decode LineLen items. */ + Pixel = Line[i++]; /* Get next pixel from stream. */ + /* Form a new unique key to search hash table for the code combines + * CrntCode as Prefix string with Pixel as postfix char. + */ + NewKey = (((UINT32) CrntCode) << 8) + Pixel; + if ((NewCode = _ExistsHashTable(HashTable, NewKey)) >= 0) { + /* This Key is already there, or the string is old one, so + * simple take new code as our CrntCode: + */ + CrntCode = NewCode; + } else { + /* Put it in hash table, output the prefix code, and make our + * CrntCode equal to Pixel. + */ + if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + CrntCode = Pixel; + + /* If however the HashTable if full, we send a clear first and + * Clear the hash table. + */ + if (Private->RunningCode >= LZ_MAX_CODE) { + /* Time to do some clearance: */ + if (EGifCompressOutput(GifFile, Private->ClearCode) + == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + Private->RunningCode = Private->EOFCode + 1; + Private->RunningBits = Private->BitsPerPixel + 1; + Private->MaxCode1 = 1 << Private->RunningBits; + _ClearHashTable(HashTable); + } else { + /* Put this unique key with its relative Code in hash table: */ + _InsertHashTable(HashTable, NewKey, Private->RunningCode++); + } + } + + } + + /* Preserve the current state of the compression algorithm: */ + Private->CrntCode = CrntCode; + + if (Private->PixelCount == 0) { + /* We are done - output last Code and flush output buffers: */ + if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) { + _GifError = E_GIF_ERR_DISK_IS_FULL; + return GIF_ERROR; + } + } + + return GIF_OK; +} + +/****************************************************************************** + * The LZ compression output routine: + * This routine is responsible for the compression of the bit stream into + * 8 bits (bytes) packets. + * Returns GIF_OK if written succesfully. + *****************************************************************************/ +static int +EGifCompressOutput(GifFileType * GifFile, + int Code) { + + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + int retval = GIF_OK; + + if (Code == FLUSH_OUTPUT) { + while (Private->CrntShiftState > 0) { + /* Get Rid of what is left in DWord, and flush it. */ + if (EGifBufferedOutput(GifFile, Private->Buf, + Private->CrntShiftDWord & 0xff) == GIF_ERROR) + retval = GIF_ERROR; + Private->CrntShiftDWord >>= 8; + Private->CrntShiftState -= 8; + } + Private->CrntShiftState = 0; /* For next time. */ + if (EGifBufferedOutput(GifFile, Private->Buf, + FLUSH_OUTPUT) == GIF_ERROR) + retval = GIF_ERROR; + } else { + Private->CrntShiftDWord |= ((long)Code) << Private->CrntShiftState; + Private->CrntShiftState += Private->RunningBits; + while (Private->CrntShiftState >= 8) { + /* Dump out full bytes: */ + if (EGifBufferedOutput(GifFile, Private->Buf, + Private->CrntShiftDWord & 0xff) == GIF_ERROR) + retval = GIF_ERROR; + Private->CrntShiftDWord >>= 8; + Private->CrntShiftState -= 8; + } + } + + /* If code cannt fit into RunningBits bits, must raise its size. Note */ + /* however that codes above 4095 are used for special signaling. */ + if (Private->RunningCode >= Private->MaxCode1 && Code <= 4095) { + Private->MaxCode1 = 1 << ++Private->RunningBits; + } + + return retval; +} + +/****************************************************************************** + * This routines buffers the given characters until 255 characters are ready + * to be output. If Code is equal to -1 the buffer is flushed (EOF). + * The buffer is Dumped with first byte as its size, as GIF format requires. + * Returns GIF_OK if written succesfully. + *****************************************************************************/ +static int +EGifBufferedOutput(GifFileType * GifFile, + GifByteType * Buf, + int c) { + + if (c == FLUSH_OUTPUT) { + /* Flush everything out. */ + if (Buf[0] != 0 + && WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + /* Mark end of compressed data, by an empty block (see GIF doc): */ + Buf[0] = 0; + if (WRITE(GifFile, Buf, 1) != 1) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + } else { + if (Buf[0] == 255) { + /* Dump out this buffer - it is full: */ + if (WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { + _GifError = E_GIF_ERR_WRITE_FAILED; + return GIF_ERROR; + } + Buf[0] = 0; + } + Buf[++Buf[0]] = c; + } + + return GIF_OK; +} + +/****************************************************************************** + * This routine writes to disk an in-core representation of a GIF previously + * created by DGifSlurp(). + *****************************************************************************/ +int +EGifSpew(GifFileType * GifFileOut) { + + int i, j, gif89 = FALSE; + int bOff; /* Block Offset for adding sub blocks in Extensions */ + char SavedStamp[GIF_STAMP_LEN + 1]; + + for (i = 0; i < GifFileOut->ImageCount; i++) { + for (j = 0; j < GifFileOut->SavedImages[i].ExtensionBlockCount; j++) { + int function = + GifFileOut->SavedImages[i].ExtensionBlocks[j].Function; + + if (function == COMMENT_EXT_FUNC_CODE + || function == GRAPHICS_EXT_FUNC_CODE + || function == PLAINTEXT_EXT_FUNC_CODE + || function == APPLICATION_EXT_FUNC_CODE) + gif89 = TRUE; + } + } + + strncpy(SavedStamp, GifVersionPrefix, GIF_STAMP_LEN); + if (gif89) { + strncpy(GifVersionPrefix, GIF89_STAMP, GIF_STAMP_LEN); + } else { + strncpy(GifVersionPrefix, GIF87_STAMP, GIF_STAMP_LEN); + } + if (EGifPutScreenDesc(GifFileOut, + GifFileOut->SWidth, + GifFileOut->SHeight, + GifFileOut->SColorResolution, + GifFileOut->SBackGroundColor, + GifFileOut->SColorMap) == GIF_ERROR) { + strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); + return (GIF_ERROR); + } + strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); + + for (i = 0; i < GifFileOut->ImageCount; i++) { + SavedImage *sp = &GifFileOut->SavedImages[i]; + int SavedHeight = sp->ImageDesc.Height; + int SavedWidth = sp->ImageDesc.Width; + ExtensionBlock *ep; + + /* this allows us to delete images by nuking their rasters */ + if (sp->RasterBits == NULL) + continue; + + if (sp->ExtensionBlocks) { + for (j = 0; j < sp->ExtensionBlockCount; j++) { + ep = &sp->ExtensionBlocks[j]; + if (j == sp->ExtensionBlockCount - 1 || (ep+1)->Function != 0) { + /*** FIXME: Must check whether outputting + * is ever valid or if we should just + * drop anything with a 0 for the Function. (And whether + * we should drop here or in EGifPutExtension) + */ + if (EGifPutExtension(GifFileOut, + (ep->Function != 0) ? ep->Function : '\0', + ep->ByteCount, + ep->Bytes) == GIF_ERROR) { + return (GIF_ERROR); + } + } else { + EGifPutExtensionFirst(GifFileOut, ep->Function, ep->ByteCount, ep->Bytes); + for (bOff = j+1; bOff < sp->ExtensionBlockCount; bOff++) { + ep = &sp->ExtensionBlocks[bOff]; + if (ep->Function != 0) { + break; + } + EGifPutExtensionNext(GifFileOut, 0, + ep->ByteCount, ep->Bytes); + } + EGifPutExtensionLast(GifFileOut, 0, 0, NULL); + j = bOff-1; + } + } + } + + if (EGifPutImageDesc(GifFileOut, + sp->ImageDesc.Left, + sp->ImageDesc.Top, + SavedWidth, + SavedHeight, + sp->ImageDesc.Interlace, + sp->ImageDesc.ColorMap) == GIF_ERROR) + return (GIF_ERROR); + + for (j = 0; j < SavedHeight; j++) { + if (EGifPutLine(GifFileOut, + sp->RasterBits + j * SavedWidth, + SavedWidth) == GIF_ERROR) + return (GIF_ERROR); + } + } + + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + return (GIF_ERROR); + + return (GIF_OK); +} diff --git a/WDL/giflib/gif_hash.c b/WDL/giflib/gif_hash.c new file mode 100644 index 00000000..82073723 --- /dev/null +++ b/WDL/giflib/gif_hash.c @@ -0,0 +1,152 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * +****************************************************************************** +* Module to support the following operations: * +* * +* 1. InitHashTable - initialize hash table. * +* 2. ClearHashTable - clear the hash table to an empty state. * +* 2. InsertHashTable - insert one item into data structure. * +* 3. ExistsHashTable - test if item exists in data structure. * +* * +* This module is used to hash the GIF codes during encoding. * +****************************************************************************** +* History: * +* 14 Jun 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#include "config.h" + +/* Find a thirty-two bit int type */ +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef __MSDOS__ +#include +#include +#include +#else +#include +#include +#endif /* __MSDOS__ */ + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ +#include +#include +#include "gif_lib.h" +#include "gif_hash.h" +#include "gif_lib_private.h" + +/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */ + +#ifdef DEBUG_HIT_RATE +static long NumberOfTests = 0, + NumberOfMisses = 0; +#endif /* DEBUG_HIT_RATE */ + +static int KeyItem(UINT32 Item); + +/****************************************************************************** +* Initialize HashTable - allocate the memory needed and clear it. * +******************************************************************************/ +GifHashTableType *_InitHashTable(void) +{ + GifHashTableType *HashTable; + + if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType))) + == NULL) + return NULL; + + _ClearHashTable(HashTable); + + return HashTable; +} + +/****************************************************************************** +* Routine to clear the HashTable to an empty state. * +* This part is a little machine depended. Use the commented part otherwise. * +******************************************************************************/ +void _ClearHashTable(GifHashTableType *HashTable) +{ + memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(UINT32)); +} + +/****************************************************************************** +* Routine to insert a new Item into the HashTable. The data is assumed to be * +* new one. * +******************************************************************************/ +void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code) +{ + int HKey = KeyItem(Key); + UINT32 *HTable = HashTable -> HTable; + +#ifdef DEBUG_HIT_RATE + NumberOfTests++; + NumberOfMisses++; +#endif /* DEBUG_HIT_RATE */ + + while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { +#ifdef DEBUG_HIT_RATE + NumberOfMisses++; +#endif /* DEBUG_HIT_RATE */ + HKey = (HKey + 1) & HT_KEY_MASK; + } + HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code); +} + +/****************************************************************************** +* Routine to test if given Key exists in HashTable and if so returns its code * +* Returns the Code if key was found, -1 if not. * +******************************************************************************/ +int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key) +{ + int HKey = KeyItem(Key); + UINT32 *HTable = HashTable -> HTable, HTKey; + +#ifdef DEBUG_HIT_RATE + NumberOfTests++; + NumberOfMisses++; +#endif /* DEBUG_HIT_RATE */ + + while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { +#ifdef DEBUG_HIT_RATE + NumberOfMisses++; +#endif /* DEBUG_HIT_RATE */ + if (Key == HTKey) return HT_GET_CODE(HTable[HKey]); + HKey = (HKey + 1) & HT_KEY_MASK; + } + + return -1; +} + +/****************************************************************************** +* Routine to generate an HKey for the hashtable out of the given unique key. * +* The given Key is assumed to be 20 bits as follows: lower 8 bits are the * +* new postfix character, while the upper 12 bits are the prefix code. * +* Because the average hit ratio is only 2 (2 hash references per entry), * +* evaluating more complex keys (such as twin prime keys) does not worth it! * +******************************************************************************/ +static int KeyItem(UINT32 Item) +{ + return ((Item >> 12) ^ Item) & HT_KEY_MASK; +} + +#ifdef DEBUG_HIT_RATE +/****************************************************************************** +* Debugging routine to print the hit ratio - number of times the hash table * +* was tested per operation. This routine was used to test the KeyItem routine * +******************************************************************************/ +void HashTablePrintHitRatio(void) +{ + printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", + NumberOfMisses, NumberOfTests, + NumberOfMisses * 100 / NumberOfTests); +} +#endif /* DEBUG_HIT_RATE */ diff --git a/WDL/giflib/gif_hash.h b/WDL/giflib/gif_hash.h new file mode 100644 index 00000000..f45e34d8 --- /dev/null +++ b/WDL/giflib/gif_hash.h @@ -0,0 +1,50 @@ +/****************************************************************************** +* Declarations, global to other of the GIF-HASH.C module. * +* * +* Written by Gershon Elber, Jun 1989 * +******************************************************************************* +* History: * +* 14 Jun 89 - Version 1.0 by Gershon Elber. * +******************************************************************************/ + +#ifndef _GIF_HASH_H_ +#define _GIF_HASH_H_ + +#include "config.h" + +/* Find a thirty-two bit int type */ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_BASETSD_H +#include +#endif + +#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ +#define HT_KEY_MASK 0x1FFF /* 13bits keys */ +#define HT_KEY_NUM_BITS 13 /* 13bits keys */ +#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ +#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ + +/* The 32 bits of the long are divided into two parts for the key & code: */ +/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ +/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ +/* The key is the upper 20 bits. The code is the lower 12. */ +#define HT_GET_KEY(l) (l >> 12) +#define HT_GET_CODE(l) (l & 0x0FFF) +#define HT_PUT_KEY(l) (l << 12) +#define HT_PUT_CODE(l) (l & 0x0FFF) + +typedef struct GifHashTableType { + UINT32 HTable[HT_SIZE]; +} GifHashTableType; + +GifHashTableType *_InitHashTable(void); +void _ClearHashTable(GifHashTableType *HashTable); +void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code); +int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key); + +#endif /* _GIF_HASH_H_ */ diff --git a/WDL/giflib/gif_lib.h b/WDL/giflib/gif_lib.h new file mode 100644 index 00000000..be644ae0 --- /dev/null +++ b/WDL/giflib/gif_lib.h @@ -0,0 +1,336 @@ +/****************************************************************************** + * In order to make life a little bit easier when using the GIF file format, + * this library was written, and which does all the dirty work... + * + * Written by Gershon Elber, Jun. 1989 + * Hacks by Eric S. Raymond, Sep. 1992 + ****************************************************************************** + * History: + * 14 Jun 89 - Version 1.0 by Gershon Elber. + * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names) + * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp) + * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) + * 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code) + *****************************************************************************/ + +#ifndef _GIF_LIB_H_ +#define _GIF_LIB_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GIF_LIB_VERSION " Version 4.1, " + +#define GIF_ERROR 0 +#define GIF_OK 1 + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ +#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 +#define GIF_VERSION_POS 3 /* Version first character in stamp. */ +#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */ +#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */ + +#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */ + +typedef int GifBooleanType; +typedef unsigned char GifPixelType; +typedef unsigned char *GifRowType; +typedef unsigned char GifByteType; +#ifdef _GBA_OPTMEM + typedef unsigned short GifPrefixType; + typedef short GifWord; +#else + typedef unsigned int GifPrefixType; + typedef int GifWord; +#endif + +#define GIF_MESSAGE(Msg) +#define GIF_EXIT(Msg) + +#ifdef SYSV +#define VoidPtr char * +#else +#define VoidPtr void * +#endif /* SYSV */ + +typedef struct GifColorType { + GifByteType Red, Green, Blue; +} GifColorType; + +typedef struct ColorMapObject { + int ColorCount; + int BitsPerPixel; + GifColorType *Colors; /* on malloc(3) heap */ +} ColorMapObject; + +typedef struct GifImageDesc { + GifWord Left, Top, Width, Height, /* Current image dimensions. */ + Interlace; /* Sequential/Interlaced lines. */ + ColorMapObject *ColorMap; /* The local color map */ +} GifImageDesc; + +typedef struct GifFileType { + GifWord SWidth, SHeight, /* Screen dimensions. */ + SColorResolution, /* How many colors can we generate? */ + SBackGroundColor; /* I hope you understand this one... */ + ColorMapObject *SColorMap; /* NULL if not exists. */ + int ImageCount; /* Number of current image */ + GifImageDesc Image; /* Block describing current image */ + struct SavedImage *SavedImages; /* Use this to accumulate file state */ + VoidPtr UserData; /* hook to attach user data (TVT) */ + VoidPtr Private; /* Don't mess with this! */ +} GifFileType; + +typedef enum { + UNDEFINED_RECORD_TYPE, + SCREEN_DESC_RECORD_TYPE, + IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */ + EXTENSION_RECORD_TYPE, /* Begin with '!' */ + TERMINATE_RECORD_TYPE /* Begin with ';' */ +} GifRecordType; + +/* DumpScreen2Gif routine constants identify type of window/screen to dump. + * Note all values below 1000 are reserved for the IBMPC different display + * devices (it has many!) and are compatible with the numbering TC2.0 + * (Turbo C 2.0 compiler for IBM PC) gives to these devices. + */ +typedef enum { + GIF_DUMP_SGI_WINDOW = 1000, + GIF_DUMP_X_WINDOW = 1001 +} GifScreenDumpType; + +/* func type to read gif data from arbitrary sources (TVT) */ +typedef int (*InputFunc) (GifFileType *, GifByteType *, int); + +/* func type to write gif data ro arbitrary targets. + * Returns count of bytes written. (MRB) + */ +typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int); + +/****************************************************************************** + * GIF89 extension function codes +******************************************************************************/ + +#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ +#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */ +#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ +#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ + +/****************************************************************************** + * O.K., here are the routines one can access in order to encode GIF file: + * (GIF_LIB file EGIF_LIB.C). +******************************************************************************/ + +GifFileType *EGifOpenFileName(const char *GifFileName, + int GifTestExistance); +GifFileType *EGifOpenFileHandle(int GifFileHandle); +GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc); + +int EGifSpew(GifFileType * GifFile); +void EGifSetGifVersion(const char *Version); +int EGifPutScreenDesc(GifFileType * GifFile, + int GifWidth, int GifHeight, int GifColorRes, + int GifBackGround, + const ColorMapObject * GifColorMap); +int EGifPutImageDesc(GifFileType * GifFile, int GifLeft, int GifTop, + int Width, int GifHeight, int GifInterlace, + const ColorMapObject * GifColorMap); +int EGifPutLine(GifFileType * GifFile, GifPixelType * GifLine, + int GifLineLen); +int EGifPutPixel(GifFileType * GifFile, GifPixelType GifPixel); +int EGifPutComment(GifFileType * GifFile, const char *GifComment); +int EGifPutExtensionFirst(GifFileType * GifFile, int GifExtCode, + int GifExtLen, const VoidPtr GifExtension); +int EGifPutExtensionNext(GifFileType * GifFile, int GifExtCode, + int GifExtLen, const VoidPtr GifExtension); +int EGifPutExtensionLast(GifFileType * GifFile, int GifExtCode, + int GifExtLen, const VoidPtr GifExtension); +int EGifPutExtension(GifFileType * GifFile, int GifExtCode, int GifExtLen, + const VoidPtr GifExtension); +int EGifPutCode(GifFileType * GifFile, int GifCodeSize, + const GifByteType * GifCodeBlock); +int EGifPutCodeNext(GifFileType * GifFile, + const GifByteType * GifCodeBlock); +int EGifCloseFile(GifFileType * GifFile); + +#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */ +#define E_GIF_ERR_WRITE_FAILED 2 +#define E_GIF_ERR_HAS_SCRN_DSCR 3 +#define E_GIF_ERR_HAS_IMAG_DSCR 4 +#define E_GIF_ERR_NO_COLOR_MAP 5 +#define E_GIF_ERR_DATA_TOO_BIG 6 +#define E_GIF_ERR_NOT_ENOUGH_MEM 7 +#define E_GIF_ERR_DISK_IS_FULL 8 +#define E_GIF_ERR_CLOSE_FAILED 9 +#define E_GIF_ERR_NOT_WRITEABLE 10 + +/****************************************************************************** + * O.K., here are the routines one can access in order to decode GIF file: + * (GIF_LIB file DGIF_LIB.C). + *****************************************************************************/ +#ifndef _GBA_NO_FILEIO +GifFileType *DGifOpenFileName(const char *GifFileName); +GifFileType *DGifOpenFileHandle(int GifFileHandle); +int DGifSlurp(GifFileType * GifFile); +#endif /* _GBA_NO_FILEIO */ +GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); /* new one + * (TVT) */ +int DGifGetScreenDesc(GifFileType * GifFile); +int DGifGetRecordType(GifFileType * GifFile, GifRecordType * GifType); +int DGifGetImageDesc(GifFileType * GifFile); +int DGifGetLine(GifFileType * GifFile, GifPixelType * GifLine, int GifLineLen); +int DGifGetPixel(GifFileType * GifFile, GifPixelType GifPixel); +int DGifGetComment(GifFileType * GifFile, char *GifComment); +int DGifGetExtension(GifFileType * GifFile, int *GifExtCode, + GifByteType ** GifExtension); +int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension); +int DGifGetCode(GifFileType * GifFile, int *GifCodeSize, + GifByteType ** GifCodeBlock); +int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock); +int DGifGetLZCodes(GifFileType * GifFile, int *GifCode); +int DGifCloseFile(GifFileType * GifFile); + +#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ +#define D_GIF_ERR_READ_FAILED 102 +#define D_GIF_ERR_NOT_GIF_FILE 103 +#define D_GIF_ERR_NO_SCRN_DSCR 104 +#define D_GIF_ERR_NO_IMAG_DSCR 105 +#define D_GIF_ERR_NO_COLOR_MAP 106 +#define D_GIF_ERR_WRONG_RECORD 107 +#define D_GIF_ERR_DATA_TOO_BIG 108 +#define D_GIF_ERR_NOT_ENOUGH_MEM 109 +#define D_GIF_ERR_CLOSE_FAILED 110 +#define D_GIF_ERR_NOT_READABLE 111 +#define D_GIF_ERR_IMAGE_DEFECT 112 +#define D_GIF_ERR_EOF_TOO_SOON 113 + +/****************************************************************************** + * O.K., here are the routines from GIF_LIB file QUANTIZE.C. +******************************************************************************/ +int QuantizeBuffer(unsigned int Width, unsigned int Height, + int *ColorMapSize, GifByteType * RedInput, + GifByteType * GreenInput, GifByteType * BlueInput, + GifByteType * OutputBuffer, + GifColorType * OutputColorMap); + +/****************************************************************************** + * O.K., here are the routines from GIF_LIB file QPRINTF.C. +******************************************************************************/ +extern int GifQuietPrint; + +#ifdef HAVE_STDARG_H + extern void GifQprintf(char *Format, ...); +#elif defined (HAVE_VARARGS_H) + extern void GifQprintf(); +#endif /* HAVE_STDARG_H */ + +/****************************************************************************** + * O.K., here are the routines from GIF_LIB file GIF_ERR.C. +******************************************************************************/ +#ifndef _GBA_NO_FILEIO +extern void PrintGifError(void); +#endif /* _GBA_NO_FILEIO */ +extern int GifLastError(void); + +/****************************************************************************** + * O.K., here are the routines from GIF_LIB file DEV2GIF.C. +******************************************************************************/ +extern int DumpScreen2Gif(const char *FileName, + int ReqGraphDriver, + long ReqGraphMode1, + long ReqGraphMode2, + long ReqGraphMode3); + +/***************************************************************************** + * + * Everything below this point is new after version 1.2, supporting `slurp + * mode' for doing I/O in two big belts with all the image-bashing in core. + * + *****************************************************************************/ + +/****************************************************************************** + * Color Map handling from ALLOCGIF.C + *****************************************************************************/ + +extern ColorMapObject *MakeMapObject(int ColorCount, + const GifColorType * ColorMap); +extern void FreeMapObject(ColorMapObject * Object); +extern ColorMapObject *UnionColorMap(const ColorMapObject * ColorIn1, + const ColorMapObject * ColorIn2, + GifPixelType ColorTransIn2[]); +extern int BitSize(int n); + +/****************************************************************************** + * Support for the in-core structures allocation (slurp mode). + *****************************************************************************/ + +/* This is the in-core version of an extension record */ +typedef struct { + int ByteCount; + char *Bytes; /* on malloc(3) heap */ + int Function; /* Holds the type of the Extension block. */ +} ExtensionBlock; + +/* This holds an image header, its unpacked raster bits, and extensions */ +typedef struct SavedImage { + GifImageDesc ImageDesc; + unsigned char *RasterBits; /* on malloc(3) heap */ + int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */ + int ExtensionBlockCount; + ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */ +} SavedImage; + +extern void ApplyTranslation(SavedImage * Image, GifPixelType Translation[]); +extern void MakeExtension(SavedImage * New, int Function); +extern int AddExtensionBlock(SavedImage * New, int Len, + unsigned char ExtData[]); +extern void FreeExtension(SavedImage * Image); +extern SavedImage *MakeSavedImage(GifFileType * GifFile, + const SavedImage * CopyFrom); +extern void FreeSavedImages(GifFileType * GifFile); + +/****************************************************************************** + * The library's internal utility font + *****************************************************************************/ + +#define GIF_FONT_WIDTH 8 +#define GIF_FONT_HEIGHT 8 +extern unsigned char AsciiTable[][GIF_FONT_WIDTH]; + +#ifdef _WIN32 + extern void DrawGifText(SavedImage * Image, +#else + extern void DrawText(SavedImage * Image, +#endif + const int x, const int y, + const char *legend, const int color); + +extern void DrawBox(SavedImage * Image, + const int x, const int y, + const int w, const int d, const int color); + +void DrawRectangle(SavedImage * Image, + const int x, const int y, + const int w, const int d, const int color); + +extern void DrawBoxedText(SavedImage * Image, + const int x, const int y, + const char *legend, + const int border, const int bg, const int fg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GIF_LIB_H */ diff --git a/WDL/giflib/gif_lib_private.h b/WDL/giflib/gif_lib_private.h new file mode 100644 index 00000000..9261e3bb --- /dev/null +++ b/WDL/giflib/gif_lib_private.h @@ -0,0 +1,59 @@ +#ifndef _GIF_LIB_PRIVATE_H +#define _GIF_LIB_PRIVATE_H + +#include "gif_lib.h" +#include "gif_hash.h" + +#define PROGRAM_NAME "GIFLIB" + +#ifdef SYSV +#define VersionStr "Gif library module,\t\tEric S. Raymond\n\ + (C) Copyright 1997 Eric S. Raymond\n" +#else +#define VersionStr PROGRAM_NAME " IBMPC " GIF_LIB_VERSION \ + " Eric S. Raymond, " __DATE__ ", " \ + __TIME__ "\n" "(C) Copyright 1997 Eric S. Raymond\n" +#endif /* SYSV */ + +#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ +#define LZ_BITS 12 + +#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */ +#define FIRST_CODE 4097 /* Impossible code, to signal first. */ +#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */ + +#define FILE_STATE_WRITE 0x01 +#define FILE_STATE_SCREEN 0x02 +#define FILE_STATE_IMAGE 0x04 +#define FILE_STATE_READ 0x08 + +#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ) +#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE) + +typedef struct GifFilePrivateType { + GifWord FileState, FileHandle, /* Where all this data goes to! */ + BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */ + ClearCode, /* The CLEAR LZ code. */ + EOFCode, /* The EOF LZ code. */ + RunningCode, /* The next code algorithm can generate. */ + RunningBits, /* The number of bits required to represent RunningCode. */ + MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */ + LastCode, /* The code before the current code. */ + CrntCode, /* Current algorithm code. */ + StackPtr, /* For character stack (see below). */ + CrntShiftState; /* Number of bits in CrntShiftDWord. */ + unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */ + unsigned long PixelCount; /* Number of pixels in image. */ + FILE *File; /* File as stream. */ + InputFunc Read; /* function to read gif input (TVT) */ + OutputFunc Write; /* function to write gif output (MRB) */ + GifByteType Buf[256]; /* Compressed input is buffered here. */ + GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */ + GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */ + GifPrefixType Prefix[LZ_MAX_CODE + 1]; + GifHashTableType *HashTable; +} GifFilePrivateType; + +extern int _GifError; + +#endif /* _GIF_LIB_PRIVATE_H */ diff --git a/WDL/giflib/gifalloc.c b/WDL/giflib/gifalloc.c new file mode 100644 index 00000000..f48bbfb4 --- /dev/null +++ b/WDL/giflib/gifalloc.c @@ -0,0 +1,441 @@ +/***************************************************************************** + * "Gif-Lib" - Yet another gif library. + * + * Written by: Gershon Elber Ver 0.1, Jun. 1989 + * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 + ***************************************************************************** + * GIF construction tools + ***************************************************************************** + * History: + * 15 Sep 92 - Version 1.0 by Eric Raymond. + ****************************************************************************/ + +#include "config.h" + +#include +#include +#include +#include "gif_lib.h" + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +/****************************************************************************** + * Miscellaneous utility functions + *****************************************************************************/ + +/* return smallest bitfield size n will fit in */ +int +BitSize(int n) { + + register int i; + + for (i = 1; i <= 8; i++) + if ((1 << i) >= n) + break; + return (i); +} + +/****************************************************************************** + * Color map object functions + *****************************************************************************/ + +/* + * Allocate a color map of given size; initialize with contents of + * ColorMap if that pointer is non-NULL. + */ +ColorMapObject * +MakeMapObject(int ColorCount, + const GifColorType * ColorMap) { + + ColorMapObject *Object; + + /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to + * make the user know that or should we automatically round up instead? */ + if (ColorCount != (1 << BitSize(ColorCount))) { + return ((ColorMapObject *) NULL); + } + + Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); + if (Object == (ColorMapObject *) NULL) { + return ((ColorMapObject *) NULL); + } + + Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType)); + if (Object->Colors == (GifColorType *) NULL) { + return ((ColorMapObject *) NULL); + } + + Object->ColorCount = ColorCount; + Object->BitsPerPixel = BitSize(ColorCount); + + if (ColorMap) { + memcpy((char *)Object->Colors, + (char *)ColorMap, ColorCount * sizeof(GifColorType)); + } + + return (Object); +} + +/* + * Free a color map object + */ +void +FreeMapObject(ColorMapObject * Object) { + + if (Object != NULL) { + free(Object->Colors); + free(Object); + /*** FIXME: + * When we are willing to break API we need to make this function + * FreeMapObject(ColorMapObject **Object) + * and do this assignment to NULL here: + * *Object = NULL; + */ + } +} + +#ifdef DEBUG +void +DumpColorMap(ColorMapObject * Object, + FILE * fp) { + + if (Object) { + int i, j, Len = Object->ColorCount; + + for (i = 0; i < Len; i += 4) { + for (j = 0; j < 4 && j < Len; j++) { + fprintf(fp, "%3d: %02x %02x %02x ", i + j, + Object->Colors[i + j].Red, + Object->Colors[i + j].Green, + Object->Colors[i + j].Blue); + } + fprintf(fp, "\n"); + } + } +} +#endif /* DEBUG */ + +/* + * Compute the union of two given color maps and return it. If result can't + * fit into 256 colors, NULL is returned, the allocated union otherwise. + * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are + * copied iff they didn't exist before. ColorTransIn2 maps the old + * ColorIn2 into ColorUnion color map table. + */ +ColorMapObject * +UnionColorMap(const ColorMapObject * ColorIn1, + const ColorMapObject * ColorIn2, + GifPixelType ColorTransIn2[]) { + + int i, j, CrntSlot, RoundUpTo, NewBitSize; + ColorMapObject *ColorUnion; + + /* + * Allocate table which will hold the result for sure. + */ + ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount, + ColorIn2->ColorCount) * 2, NULL); + + if (ColorUnion == NULL) + return (NULL); + + /* Copy ColorIn1 to ColorUnionSize; */ + /*** FIXME: What if there are duplicate entries into the colormap to begin + * with? */ + for (i = 0; i < ColorIn1->ColorCount; i++) + ColorUnion->Colors[i] = ColorIn1->Colors[i]; + CrntSlot = ColorIn1->ColorCount; + + /* + * Potentially obnoxious hack: + * + * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end + * of table 1. This is very useful if your display is limited to + * 16 colors. + */ + while (ColorIn1->Colors[CrntSlot - 1].Red == 0 + && ColorIn1->Colors[CrntSlot - 1].Green == 0 + && ColorIn1->Colors[CrntSlot - 1].Blue == 0) + CrntSlot--; + + /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */ + for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) { + /* Let's see if this color already exists: */ + /*** FIXME: Will it ever occur that ColorIn2 will contain duplicate + * entries? So we should search from 0 to CrntSlot rather than + * ColorIn1->ColorCount? + */ + for (j = 0; j < ColorIn1->ColorCount; j++) + if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], + sizeof(GifColorType)) == 0) + break; + + if (j < ColorIn1->ColorCount) + ColorTransIn2[i] = j; /* color exists in Color1 */ + else { + /* Color is new - copy it to a new slot: */ + ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i]; + ColorTransIn2[i] = CrntSlot++; + } + } + + if (CrntSlot > 256) { + FreeMapObject(ColorUnion); + return ((ColorMapObject *) NULL); + } + + NewBitSize = BitSize(CrntSlot); + RoundUpTo = (1 << NewBitSize); + + if (RoundUpTo != ColorUnion->ColorCount) { + register GifColorType *Map = ColorUnion->Colors; + + /* + * Zero out slots up to next power of 2. + * We know these slots exist because of the way ColorUnion's + * start dimension was computed. + */ + for (j = CrntSlot; j < RoundUpTo; j++) + Map[j].Red = Map[j].Green = Map[j].Blue = 0; + + /* perhaps we can shrink the map? */ + if (RoundUpTo < ColorUnion->ColorCount) + ColorUnion->Colors = (GifColorType *)realloc(Map, + sizeof(GifColorType) * RoundUpTo); + } + + ColorUnion->ColorCount = RoundUpTo; + ColorUnion->BitsPerPixel = NewBitSize; + + return (ColorUnion); +} + +/* + * Apply a given color translation to the raster bits of an image + */ +void +ApplyTranslation(SavedImage * Image, + GifPixelType Translation[]) { + + register int i; + register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; + + for (i = 0; i < RasterSize; i++) + Image->RasterBits[i] = Translation[Image->RasterBits[i]]; +} + +/****************************************************************************** + * Extension record functions + *****************************************************************************/ + +void +MakeExtension(SavedImage * New, + int Function) { + + New->Function = Function; + /*** FIXME: + * Someday we might have to deal with multiple extensions. + * ??? Was this a note from Gershon or from me? Does the multiple + * extension blocks solve this or do we need multiple Functions? Or is + * this an obsolete function? (People should use AddExtensionBlock + * instead?) + * Looks like AddExtensionBlock needs to take the int Function argument + * then it can take the place of this function. Right now people have to + * use both. Fix AddExtensionBlock and add this to the deprecation list. + */ +} + +int +AddExtensionBlock(SavedImage * New, + int Len, + unsigned char ExtData[]) { + + ExtensionBlock *ep; + + if (New->ExtensionBlocks == NULL) + New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); + else + New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks, + sizeof(ExtensionBlock) * + (New->ExtensionBlockCount + 1)); + + if (New->ExtensionBlocks == NULL) + return (GIF_ERROR); + + ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; + + ep->ByteCount=Len; + ep->Bytes = (char *)malloc(ep->ByteCount); + if (ep->Bytes == NULL) + return (GIF_ERROR); + + if (ExtData) { + memcpy(ep->Bytes, ExtData, Len); + ep->Function = New->Function; + } + + return (GIF_OK); +} + +void +FreeExtension(SavedImage * Image) +{ + ExtensionBlock *ep; + + if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) { + return; + } + for (ep = Image->ExtensionBlocks; + ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++) + (void)free((char *)ep->Bytes); + free((char *)Image->ExtensionBlocks); + Image->ExtensionBlocks = NULL; +} + +/****************************************************************************** + * Image block allocation functions +******************************************************************************/ + +/* Private Function: + * Frees the last image in the GifFile->SavedImages array + */ +void +FreeLastSavedImage(GifFileType *GifFile) { + + SavedImage *sp; + + if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) + return; + + /* Remove one SavedImage from the GifFile */ + GifFile->ImageCount--; + sp = &GifFile->SavedImages[GifFile->ImageCount]; + + /* Deallocate its Colormap */ + if (sp->ImageDesc.ColorMap) { + FreeMapObject(sp->ImageDesc.ColorMap); + sp->ImageDesc.ColorMap = NULL; + } + + /* Deallocate the image data */ + if (sp->RasterBits) + free((char *)sp->RasterBits); + + /* Deallocate any extensions */ + if (sp->ExtensionBlocks) + FreeExtension(sp); + + /*** FIXME: We could realloc the GifFile->SavedImages structure but is + * there a point to it? Saves some memory but we'd have to do it every + * time. If this is used in FreeSavedImages then it would be inefficient + * (The whole array is going to be deallocated.) If we just use it when + * we want to free the last Image it's convenient to do it here. + */ +} + +/* + * Append an image block to the SavedImages array + */ +SavedImage * +MakeSavedImage(GifFileType * GifFile, + const SavedImage * CopyFrom) { + + SavedImage *sp; + + if (GifFile->SavedImages == NULL) + GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); + else + GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, + sizeof(SavedImage) * (GifFile->ImageCount + 1)); + + if (GifFile->SavedImages == NULL) + return ((SavedImage *)NULL); + else { + sp = &GifFile->SavedImages[GifFile->ImageCount++]; + memset((char *)sp, '\0', sizeof(SavedImage)); + + if (CopyFrom) { + memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); + + /* + * Make our own allocated copies of the heap fields in the + * copied record. This guards against potential aliasing + * problems. + */ + + /* first, the local color map */ + if (sp->ImageDesc.ColorMap) { + sp->ImageDesc.ColorMap = MakeMapObject( + CopyFrom->ImageDesc.ColorMap->ColorCount, + CopyFrom->ImageDesc.ColorMap->Colors); + if (sp->ImageDesc.ColorMap == NULL) { + FreeLastSavedImage(GifFile); + return (SavedImage *)(NULL); + } + } + + /* next, the raster */ + sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) * + CopyFrom->ImageDesc.Height * + CopyFrom->ImageDesc.Width); + if (sp->RasterBits == NULL) { + FreeLastSavedImage(GifFile); + return (SavedImage *)(NULL); + } + memcpy(sp->RasterBits, CopyFrom->RasterBits, + sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * + CopyFrom->ImageDesc.Width); + + /* finally, the extension blocks */ + if (sp->ExtensionBlocks) { + sp->ExtensionBlocks = (ExtensionBlock *)malloc( + sizeof(ExtensionBlock) * + CopyFrom->ExtensionBlockCount); + if (sp->ExtensionBlocks == NULL) { + FreeLastSavedImage(GifFile); + return (SavedImage *)(NULL); + } + memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, + sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); + + /* + * For the moment, the actual blocks can take their + * chances with free(). We'll fix this later. + *** FIXME: [Better check this out... Toshio] + * 2004 May 27: Looks like this was an ESR note. + * It means the blocks are shallow copied from InFile to + * OutFile. However, I don't see that in this code.... + * Did ESR fix it but never remove this note (And other notes + * in gifspnge?) + */ + } + } + + return (sp); + } +} + +void +FreeSavedImages(GifFileType * GifFile) { + + SavedImage *sp; + + if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { + return; + } + for (sp = GifFile->SavedImages; + sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { + if (sp->ImageDesc.ColorMap) { + FreeMapObject(sp->ImageDesc.ColorMap); + sp->ImageDesc.ColorMap = NULL; + } + + if (sp->RasterBits) + free((char *)sp->RasterBits); + + if (sp->ExtensionBlocks) + FreeExtension(sp); + } + free((char *)GifFile->SavedImages); + GifFile->SavedImages=NULL; +} diff --git a/WDL/gpu/gpu.cpp b/WDL/gpu/gpu.cpp new file mode 100644 index 00000000..290e1e8d --- /dev/null +++ b/WDL/gpu/gpu.cpp @@ -0,0 +1,317 @@ +/* + WDL - gpu.cpp + Copyright (C) 2007 Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +#include "gpu.h" + +static int static_disableOpenGl = 0; + +WDL_GPU::WDL_GPU() +{ + m_glDll = NULL; + m_rc = NULL; +} + +WDL_GPU::~WDL_GPU() +{ + release(); +} + +void WDL_GPU::release() +{ + if(m_glDll) + { + if(m_rc) + { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(m_rc); + } + FreeLibrary(m_glDll); + m_glDll = NULL; + } +} + +int WDL_GPU::init(HWND hwnd) +{ + m_hwnd = hwnd; + + if(static_disableOpenGl) return 0; + + m_glDll = LoadLibrary("opengl32.dll"); + if(!m_glDll) return 0; + + *((int *)&wglCreateContext) = (int)GetProcAddress(m_glDll, "wglCreateContext"); + *((int *)&wglDeleteContext) = (int)GetProcAddress(m_glDll, "wglDeleteContext"); + *((int *)&wglMakeCurrent) = (int)GetProcAddress(m_glDll, "wglMakeCurrent"); + *((int *)&wglGetProcAddress) = (int)GetProcAddress(m_glDll, "wglGetProcAddress"); + *((int *)&glClearColor) = (int)GetProcAddress(m_glDll, "glClearColor"); + *((int *)&glClear) = (int)GetProcAddress(m_glDll, "glClear"); + *((int *)&glEnable) = (int)GetProcAddress(m_glDll, "glEnable"); + *((int *)&glDisable) = (int)GetProcAddress(m_glDll, "glDisable"); + *((int *)&glBlendFunc) = (int)GetProcAddress(m_glDll, "glBlendFunc"); + *((int *)&glLineWidth) = (int)GetProcAddress(m_glDll, "glLineWidth"); + *((int *)&glColor3f) = (int)GetProcAddress(m_glDll, "glColor3f"); + *((int *)&glBegin) = (int)GetProcAddress(m_glDll, "glBegin"); + *((int *)&glEnd) = (int)GetProcAddress(m_glDll, "glEnd"); + *((int *)&glFlush) = (int)GetProcAddress(m_glDll, "glFlush"); + *((int *)&glVertex2f) = (int)GetProcAddress(m_glDll, "glVertex2f"); + *((int *)&glFinish) = (int)GetProcAddress(m_glDll, "glFinish"); + *((int *)&glGetString) = (int)GetProcAddress(m_glDll, "glGetString"); + *((int *)&glReadPixels) = (int)GetProcAddress(m_glDll, "glReadPixels"); + + if(!wglGetProcAddress) + { + FreeLibrary(m_glDll); + m_glDll = NULL; + return 0; + } + + HDC pdc = GetDC(m_hwnd); + + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory( &pfd, sizeof( pfd ) ); + pfd.nSize = sizeof( pfd ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 16; + pfd.iLayerType = PFD_MAIN_PLANE; + int format = ChoosePixelFormat( pdc, &pfd ); + SetPixelFormat( pdc, format, &pfd ); + + m_rc = wglCreateContext(pdc); + + if(!m_rc) + { + ReleaseDC(m_hwnd, pdc); + FreeLibrary(m_glDll); + m_glDll = NULL; + return 0; + } + wglMakeCurrent(pdc, m_rc); + + char *rend = (char *)glGetString(GL_RENDERER); + if(!rend || (rend && strstr(rend, "GDI"))) goto ret; //opengl software rendering is slooooow + + wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + + if(!wglGetExtensionsStringARB) + { +ret: + ReleaseDC(m_hwnd, pdc); + wglMakeCurrent(NULL, NULL); + wglDeleteContext(m_rc); + FreeLibrary(m_glDll); + m_glDll = NULL; + return 0; + } + + char *ext = NULL; + ext = (char*)wglGetExtensionsStringARB( pdc ); + if(!strstr( ext, "WGL_ARB_pbuffer" )) goto ret; + + wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB"); + wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB"); + wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB"); + wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB"); + wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB"); + if( !wglCreatePbufferARB || !wglGetPbufferDCARB || !wglReleasePbufferDCARB || !wglDestroyPbufferARB || !wglQueryPbufferARB ) goto ret; + + wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); + wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB"); + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + + if( !wglGetExtensionsStringARB || !wglCreatePbufferARB || !wglGetPbufferDCARB ) goto ret; + + ReleaseDC(m_hwnd, pdc); + + return 1; +} + +WDL_GPU_Surface *WDL_GPU::createSurface(WDL_WinMemBitmap *bm, int w, int h) +{ + if(!isInited()) return 0; + return new WDL_GPU_Surface(this, bm, w, h); +} + +static LRESULT CALLBACK staticWndProc( + HWND hwnd, // handle to window + UINT uMsg, // message identifier + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter +) +{ + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +WDL_GPU_Surface::WDL_GPU_Surface(WDL_GPU *parent, WDL_WinMemBitmap *bm, int w, int h) +{ + m_parent = parent; + m_bm = bm; + m_hPBuffer = NULL; + m_hDC = NULL; + m_hRC = NULL; + + //m_w = ((w+15)/16)*16; m_h = ((h+15)/16)*16; + m_w = w; m_h = h; + + BITMAPINFO m_bmi; + memset(&m_bmi, 0, sizeof(BITMAPINFO)); + m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + m_bmi.bmiHeader.biWidth = m_w; + m_bmi.bmiHeader.biHeight = m_h; + m_bmi.bmiHeader.biPlanes = 1; + m_bmi.bmiHeader.biBitCount = 32; + m_bmi.bmiHeader.biCompression = BI_RGB; + m_bmi.bmiHeader.biSizeImage = m_w * m_h * 4; + m_bmp = CreateDIBSection(m_bm->GetDC(), &m_bmi, DIB_RGB_COLORS, &m_bits, NULL, 0); + m_oldbm = (HBITMAP)SelectObject(m_bm->GetDC(), m_bmp); + + //create pbuffer for offscreen rendering + int pf_attr[] = + { + WGL_SUPPORT_OPENGL_ARB, TRUE, // P-buffer will be used with OpenGL + WGL_DRAW_TO_PBUFFER_ARB, TRUE, // Enable render to p-buffer + WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // some cards need that in order not to crash in wglCreatePbufferARB + WGL_RED_BITS_ARB, 8, // At least 8 bits for RED channel + WGL_GREEN_BITS_ARB, 8, // At least 8 bits for GREEN channel + WGL_BLUE_BITS_ARB, 8, // At least 8 bits for BLUE channel + WGL_ALPHA_BITS_ARB, 8, // At least 8 bits for ALPHA channel + WGL_DEPTH_BITS_ARB, 16, // At least 16 bits for depth buffer + WGL_DOUBLE_BUFFER_ARB, FALSE, // We don't require double buffering + 0 // Zero terminates the list + }; + + HDC pdc = GetDC(m_parent->m_hwnd); + + try + { + unsigned int count = 0; + int pixelFormat; + m_parent->wglChoosePixelFormatARB( pdc,(const int*)pf_attr, NULL, 1, &pixelFormat, &count); + if(!count) + { + ReleaseDC(m_parent->m_hwnd, pdc); + m_parent->release(); + return; + } + + m_hPBuffer = m_parent->wglCreatePbufferARB( pdc, pixelFormat, m_w, m_h, NULL ); + if(!m_hPBuffer) + { + ReleaseDC(m_parent->m_hwnd, pdc); + m_parent->release(); + return; + } + } + catch(...) + { + //stupid opengl driver crashing, lets make sure we don't retry to reinitialize the whole thing + static_disableOpenGl = 1; + ReleaseDC(m_parent->m_hwnd, pdc); + m_parent->release(); + return; + } + + m_hDC = m_parent->wglGetPbufferDCARB( m_hPBuffer ); + m_hRC = m_parent->wglCreateContext( m_hDC ); + + ReleaseDC(m_parent->m_hwnd, pdc); +} + +WDL_GPU_Surface::~WDL_GPU_Surface() +{ + if(m_hRC) + { + m_parent->wglMakeCurrent(m_hDC, m_hRC); + m_parent->wglDeleteContext(m_hRC); + m_parent->wglReleasePbufferDCARB( m_hPBuffer, m_hDC ); + m_parent->wglDestroyPbufferARB( m_hPBuffer ); + ReleaseDC( m_parent->m_hwnd, m_hDC ); + } + if(m_parent->isInited()) m_parent->wglMakeCurrent(NULL, NULL); + SelectObject(m_bm->GetDC(), m_oldbm); + DeleteObject(m_bmp); +} + +void WDL_GPU_Surface::clear(float cr, float cg, float cb) +{ + m_parent->glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + m_parent->glClear( GL_COLOR_BUFFER_BIT ); +} + +void WDL_GPU_Surface::beginScene() +{ + if(!m_hRC) return; + m_parent->wglMakeCurrent(m_hDC, m_hRC); +} + +void WDL_GPU_Surface::setLineAA(int on) +{ + if(on) + { + m_parent->glEnable(GL_LINE_SMOOTH); + m_parent->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + m_parent->glEnable(GL_BLEND); + } + else + { + m_parent->glDisable(GL_LINE_SMOOTH); + } +} + +void WDL_GPU_Surface::beginLine(float cr, float cg, float cb) +{ + m_parent->glLineWidth (1); + m_parent->glBegin (GL_LINES); + m_parent->glColor3f (cb, cg, cr); +} + +void WDL_GPU_Surface::end() +{ + m_parent->glEnd (); + m_parent->glFinish(); +} + +void WDL_GPU_Surface::drawLine(int x1, int y1, int x2, int y2) +{ + float w = (float)m_w; + float h = (float)m_h; + float fx1 = ((float)x1/(w/2))-1; + float fy1 = -((float)y1/(h/2))+1; + float fx2 = ((float)x2/(w/2))-1; + float fy2 = -((float)y2/(h/2))+1; + m_parent->glVertex2f(fx1,fy1); + m_parent->glVertex2f(fx2,fy2); +} + +void WDL_GPU_Surface::flush() +{ + m_parent->glFlush(); +} + +void WDL_GPU_Surface::blit() +{ + if(!m_hRC) return; + m_parent->glReadPixels( 0, 0, m_w, m_h, GL_RGBA, GL_UNSIGNED_BYTE, m_bits); +} diff --git a/WDL/gpu/gpu.h b/WDL/gpu/gpu.h new file mode 100644 index 00000000..50bce940 --- /dev/null +++ b/WDL/gpu/gpu.h @@ -0,0 +1,121 @@ +/* + WDL - gpu.h + Copyright (C) 2007 Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifndef _WDL_GPU_H +#define _WDL_GPU_H + +#ifdef _WIN32 + +#include +#include +#include "wglext.h" + +#include "../wingui/membitmap.h" + +class WDL_GPU_Surface; + +class WDL_GPU +{ +public: + WDL_GPU(); + ~WDL_GPU(); + + int init(HWND hwnd); + void release(); + int isInited() { return m_glDll != NULL; } + + WDL_GPU_Surface *createSurface(WDL_WinMemBitmap *bm, int w, int h); + + HGLRC (WINAPI *wglCreateContext)(HDC dc); + BOOL (WINAPI *wglMakeCurrent)(HDC dc, HGLRC rc); + BOOL (WINAPI *wglDeleteContext)(HGLRC rc); + PROC (WINAPI *wglGetProcAddress)(LPCSTR name); + + void (WINAPI *glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void (WINAPI *glClear)(GLbitfield mask); + void (WINAPI *glEnable)(GLenum cap); + void (WINAPI *glDisable)(GLenum cap); + void (WINAPI *glBlendFunc)(GLenum sfactor, GLenum dfactor); + void (WINAPI *glLineWidth)(GLfloat width); + void (WINAPI *glColor3f)(GLfloat red, GLfloat green, GLfloat blue); + void (WINAPI *glBegin)(GLenum mode); + void (WINAPI *glEnd)(); + void (WINAPI *glVertex2f)(GLfloat x, GLfloat y); + void (WINAPI *glFlush)(); + void (WINAPI *glFinish)(); + const GLubyte *(WINAPI *glGetString)(GLenum name); + void (WINAPI *glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); + + // WGL_ARB_extensions_string + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; + + // WGL_ARB_pbuffer + PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB; + PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB; + PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB; + PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB; + PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB; + + // WGL_ARB_pixel_format + PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB; + PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB; + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; + + HINSTANCE m_glDll; + HWND m_hwnd; + HGLRC m_rc; +}; + +class WDL_GPU_Surface +{ +public: + WDL_GPU_Surface(WDL_GPU *parent, WDL_WinMemBitmap *bm, int w, int h); + ~WDL_GPU_Surface(); + + void clear(float cr, float cg, float cb); + void beginScene(); + void setLineAA(int on); + void beginLine(float cr, float cg, float cb); + void end(); + void drawLine(int x1, int y1, int x2, int y2); + void flush(); + void blit(); + +private: + WDL_GPU *m_parent; + WDL_WinMemBitmap *m_bm; + HBITMAP m_oldbm, m_bmp; + int m_w, m_h; + + HPBUFFERARB m_hPBuffer; + HDC m_hDC; + HGLRC m_hRC; + void *m_bits; +}; + +#else + +//todo + +#endif + +#endif \ No newline at end of file diff --git a/WDL/gpu/wglext.h b/WDL/gpu/wglext.h new file mode 100644 index 00000000..f424adcf --- /dev/null +++ b/WDL/gpu/wglext.h @@ -0,0 +1,611 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number */ +/* wglext.h last updated 2002/03/22 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define WGL_WGLEXT_VERSION 4 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_I3D_swap_frame_lock +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +extern void WINAPI wglFreeMemoryNV (void *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); +extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); +extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); +extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); +extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); +extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableGenlockI3D (HDC); +extern BOOL WINAPI wglDisableGenlockI3D (HDC); +extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); +extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); +extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); +extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); +extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); +extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#endif + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableFrameLockI3D (void); +extern BOOL WINAPI wglDisableFrameLockI3D (void); +extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); +extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#endif + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetFrameUsageI3D (float *); +extern BOOL WINAPI wglBeginFrameTrackingI3D (void); +extern BOOL WINAPI wglEndFrameTrackingI3D (void); +extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/WDL/heapbuf.h b/WDL/heapbuf.h new file mode 100644 index 00000000..c5e6b499 --- /dev/null +++ b/WDL/heapbuf.h @@ -0,0 +1,346 @@ +/* + WDL - heapbuf.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides the interface and implementation for WDL_HeapBuf, a simple + malloc() wrapper for resizeable blocks. + + Also in this file is WDL_TypedBuf which is a templated version WDL_HeapBuf + that manages type and type-size. + +*/ + +#ifndef _WDL_HEAPBUF_H_ +#define _WDL_HEAPBUF_H_ + +#ifndef WDL_HEAPBUF_IMPL_ONLY + +#ifdef WDL_HEAPBUF_TRACE +#include +#define WDL_HEAPBUF_TRACEPARM(x) ,(x) +#else +#define WDL_HEAPBUF_TRACEPARM(x) +#endif + +#include "wdltypes.h" + +class WDL_HeapBuf +{ + public: + // interface +#ifdef WDL_HEAPBUF_INTF_ONLY + void *Resize(int newsize, bool resizedown=true); + void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false); +#endif + void *Get() const { return m_size?m_buf:NULL; } + int GetSize() const { return m_size; } + void *GetAligned(int align) const { return (void *)(((UINT_PTR)Get() + (align-1)) & ~(UINT_PTR)(align-1)); } + + void SetGranul(int granul) { m_granul = granul; } + + void SetMinAllocSize(int mas) { m_mas=mas; } + + + WDL_HeapBuf(const WDL_HeapBuf &cp) + { + m_buf=0; + CopyFrom(&cp,true); + } + WDL_HeapBuf &operator=(const WDL_HeapBuf &cp) + { + CopyFrom(&cp,true); + return *this; + } + + + + #ifndef WDL_HEAPBUF_TRACE + explicit WDL_HeapBuf(int granul=4096) : m_alloc(0), m_size(0), m_mas(0) + { + SetGranul(granul); + m_buf=0; + } + ~WDL_HeapBuf() + { + free(m_buf); + } + #else + explicit WDL_HeapBuf(int granul=4096, const char *tracetype="WDL_HeapBuf" + ) : m_alloc(0), m_size(0), m_mas(0) + { + SetGranul(granul); + m_buf=0; + + m_tracetype = tracetype; + char tmp[512]; + wsprintf(tmp,"WDL_HeapBuf: created type: %s granul=%d\n",tracetype,granul); + OutputDebugString(tmp); + } + ~WDL_HeapBuf() + { + char tmp[512]; + wsprintf(tmp,"WDL_HeapBuf: destroying type: %s (alloc=%d, size=%d)\n",m_tracetype,m_alloc,m_size); + OutputDebugString(tmp); + free(m_buf); + } + #endif + +#endif // !WDL_HEAPBUF_IMPL_ONLY + + // implementation bits +#ifndef WDL_HEAPBUF_INTF_ONLY + #ifdef WDL_HEAPBUF_IMPL_ONLY + void *WDL_HeapBuf::Resize(int newsize, bool resizedown) + #else + void *Resize(int newsize, bool resizedown=true) + #endif + { + #ifdef DEBUG_TIGHT_ALLOC // horribly slow, do not use for release builds + if (newsize == m_size) return m_buf; + + int a = newsize; + if (a > m_size) a=m_size; + void *newbuf = newsize ? malloc(newsize) : 0; + if (!newbuf && newsize) + { + #ifdef WDL_HEAPBUF_ONMALLOCFAIL + WDL_HEAPBUF_ONMALLOCFAIL(newsize) + #endif + return m_buf; + } + if (newbuf&&m_buf) memcpy(newbuf,m_buf,a); + m_size=m_alloc=newsize; + free(m_buf); + return m_buf=newbuf; + #endif + + //#define WDL_HEAPBUF_DYNAMIC + #ifdef WDL_HEAPBUF_DYNAMIC + // ignoring m_granul and m_mas + + if (newsize!=m_size) + { + if ((newsize > m_size && newsize <= m_alloc) || (newsize < m_size && !resizedown)) + { + m_size = newsize; + return m_buf; + } + + // next highest power of 2 + int n = newsize; + if (n) + { + if (n < 64) + { + n = 64; + } + else + { + --n; + n = (n>>1)|n; + n = (n>>2)|n; + n = (n>>4)|n; + n = (n>>8)|n; + n = (n>>16)|n; + ++n; + } + } + + if (n == m_alloc) + { + m_size = newsize; + return m_buf; + } + + void* newbuf = realloc(m_buf, n); // realloc==free when size==0 + #ifdef WDL_HEAPBUF_ONMALLOCFAIL + if (!newbuf && n) { WDL_HEAPBUF_ONMALLOCFAIL(n) } ; + #endif + if (newbuf || !newsize) + { + m_alloc = n; + m_buf = newbuf; + m_size = newsize; + } + } + + return (m_size ? m_buf : 0); + #else // WDL_HEAPBUF_DYNAMIC + if (newsize!=m_size) + { + // if we are not using m_smallbuf or we need to not use it + // and if if growing or resizing down + if ( + (newsize > m_alloc || + (resizedown && newsize < m_size && + newsize < m_alloc/2 && + newsize < m_alloc - (m_granul<<2)))) + { + int granul=newsize/2; + int newalloc; + if (granul < m_granul) granul=m_granul; + + if (m_granul<4096) newalloc=newsize+granul; + else + { + granul &= ~4095; + if (granul< 4096) granul=4096; + else if (granul>4*1024*1024) granul=4*1024*1024; + newalloc = ((newsize + granul + 96)&~4095)-96; + } + + if (newalloc < m_mas) newalloc=m_mas; + + if (newalloc != m_alloc) + { + #ifdef WDL_HEAPBUF_TRACE + char tmp[512]; + wsprintf(tmp,"WDL_HeapBuf: type %s realloc(%d) from %d\n",m_tracetype,newalloc,m_alloc); + OutputDebugString(tmp); + #endif + void *nbuf= realloc(m_buf,newalloc); + if (!nbuf && newalloc) + { + if (!(nbuf=malloc(newalloc))) + { + #ifdef WDL_HEAPBUF_ONMALLOCFAIL + WDL_HEAPBUF_ONMALLOCFAIL(newalloc); + #endif + return m_size?m_buf:0; // failed, do not resize + } + + if (m_buf) + { + int sz=newsize0) memcpy(nbuf,m_buf,sz); + free(m_buf); + } + } + + m_buf=nbuf; + m_alloc=newalloc; + } // alloc size change + } // need size up or down + m_size=newsize; + } // size change + return m_size?m_buf:0; + #endif // WDL_HEAPBUF_DYNAMIC + } + + #ifdef WDL_HEAPBUF_IMPL_ONLY + void WDL_HeapBuf::CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig) + #else + void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false) + #endif + { + if (exactCopyOfConfig) // copy all settings + { + free(m_buf); + + #ifdef WDL_HEAPBUF_TRACE + m_tracetype = hb->m_tracetype; + #endif + m_granul = hb->m_granul; + m_mas = hb->m_mas; + + m_size=m_alloc=0; + m_buf=hb->m_buf && hb->m_alloc>0 ? malloc(m_alloc = hb->m_alloc) : NULL; + #ifdef WDL_HEAPBUF_ONMALLOCFAIL + if (!m_buf && m_alloc) { WDL_HEAPBUF_ONMALLOCFAIL(m_alloc) } ; + #endif + if (m_buf) memcpy(m_buf,hb->m_buf,m_size = hb->m_size); + else m_alloc=0; + } + else // copy just the data + size + { + int newsz=hb->GetSize(); + Resize(newsz); + if (GetSize()!=newsz) Resize(0); + else memcpy(Get(),hb->Get(),newsz); + } + } + +#endif // ! WDL_HEAPBUF_INTF_ONLY + +#ifndef WDL_HEAPBUF_IMPL_ONLY + + private: + void *m_buf; + #if !defined(_WIN64) && !defined(__LP64__) + int ___pad; // keep this 8 byte aligned on osx32 + #endif + int m_granul; + int m_alloc; + int m_size; + int m_mas; + + #ifdef WDL_HEAPBUF_TRACE + const char *m_tracetype; + #endif + +}; + +template class WDL_TypedBuf +{ + public: + PTRTYPE *Get() const { return (PTRTYPE *) m_hb.Get(); } + int GetSize() const { return m_hb.GetSize()/sizeof(PTRTYPE); } + + PTRTYPE *Resize(int newsize, bool resizedown=true) { return (PTRTYPE *)m_hb.Resize(newsize*sizeof(PTRTYPE),resizedown); } + + PTRTYPE *GetAligned(int align) const { return (PTRTYPE *) m_hb.GetAligned(align); } + + PTRTYPE *Add(PTRTYPE val) + { + int sz=GetSize(); + PTRTYPE *p=Resize(sz+1); + if (p && GetSize() == sz+1) { p[sz]=val; return p+sz; } + return 0; + } + + void SetGranul(int gran) { m_hb.SetGranul(gran); } + + int Find(PTRTYPE val) const + { + PTRTYPE* p=Get(); + int i; + for (i=0; i < GetSize(); ++i) if (p[i] == val) return i; + return -1; + } + +#ifndef WDL_HEAPBUF_TRACE + explicit WDL_TypedBuf(int granul=4096) : m_hb(granul) { } +#else + explicit WDL_TypedBuf(int granul=4096, const char *tracetype="WDL_TypedBuf") : m_hb(granul WDL_HEAPBUF_TRACEPARM(tracetype)) { } +#endif + ~WDL_TypedBuf() + { + } + + private: + WDL_HeapBuf m_hb; +}; + +#endif // ! WDL_HEAPBUF_IMPL_ONLY + +#endif // _WDL_HEAPBUF_H_ diff --git a/WDL/history.txt b/WDL/history.txt new file mode 100644 index 00000000..f17b4aa5 --- /dev/null +++ b/WDL/history.txt @@ -0,0 +1,470 @@ +FFMPEG: added WDL_VideoDecode class to grab video frames + +2010-08-16: +Now available via Git! The zipped distributions may go away someday? +EEL2: optional eel1 compat (allows you to build AVS using EEL2 and support old presets) +LICE: FillTriangle/Polygon/Bezier coordinates are now cleanly inclusive +LineParse: when parsing small lines, no heap use (requires an extra 2k of stack space per parser) +PtrList: do not pass NULLs to deletion functions +Scrollbar: improved zoom button sizing +sc_bounce: fixed a session ID handling bug +SWELL: no WM_CTLCOLOR* on text fields +SWELL: rendering glitch fix when destroying small subviews +SWELL: font and combo box sizes are more consistent +SWELL: emulate WM_NC/HTCAPTION on OSX for double-click in titlebar +SWELL: API for setting relative raise amounts for owned windows +Virtwnd: VirtualStaticText: added GetCharFromCoord() +Virtwnd: fixed scaled blit clipping on right/bottom, various other clip problems +Virtwnd: bgcache handles differing images automatically + + +2010-07-14: +SWELL: better TrackPopupMenu() behavior when using TPM_RETURNCMD +SWELL: resource script generation improved, faster, simpler use: mac_resgen.php file.rc [file2.rc ...] +SWELL: more accurate MoveToEx()/LineTo() +SWELL: fixes to no-maninmiddle-cocoa mode +SWELL: WM_ERASEBKGND fixes +SWELL: added GetPrivateProfileSection()/WritePrivateProfileSection() (untested) +EEL: tan() optimized and fixed on osx/i386 +EEL: fix for broken fmod() on VC2005/2008 x64 +Pitch shifter: bugfixes, latency compensation +LCF: fixed broken encoding on widths non multiples of 4 +LICE: better drawing of non-UTF8 8-bit text +LineParser: gettoken_str() now returns const char ptr +FileWrite: append support, option for no exclusive locking +Scrollbar: fixes for scaling, nonstandard scrollbar sizes, better image caching +String: allow SetLen() to shrink buffers +WIN32-UTF8: ShellExecute() UTF8 support +WndSizer: added set_orig_rect() +Virtwnd: more controls support disabling state +Virtwnd: static text controls support drawing text vertically + +2010-06-07: +File Browsing: fixed single file select on multifile open on Win2k/98 (windows bug) +File Browsing: UTF8 fixes +LICE: bitmaps are now forced to 64 byte alignment, backing stores are (by default) row aligned +IPlug: fixed OSX compiling (SWELL changes had made it not compile) +IPlug: VST_SDK path is now normalized, put VST_SDK/ at the same level as WDL/ +IPlug: image files for sample are now in the correct place (and not zipped) +Mutex: WDL_SharedMutex (for shared/exclusive locks) +Scrollbar: obey LICE rowspan on image loading +SWELL: CreateBitmap() optimizations +SWELL: Much faster INI file read/write +SWELL: Experimental mode to bypass OS X's default compositing code for SWELL views. This can be disabled by defining SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN to 0. +SWELL: hugely optimized BitBlt() (no longer floods kernel messages) +SWELL: removed BitBltAlpha*(), added flag for BitBlt(), SRCCOPY_USEALPHA +SWELL: added SWELL_FlushWindow(), ReleaseDC() no longer implies window flush +SWELL: dialog background drawing improvements/optimizations + +2010-06-01: +DirScan: GetCurrentFileSize() support for OSx/Linux +FileRead: detect when no shared lock acquired, update file size on demand since it can change +IPlug: tweaks from Tale +LCF: added LCF read/write (Lice Capture Format, a good high quality lossless screencapture codec) +LICE: moved warning pragma into lice_combine.h from lice.h, to prevent app warnings from being supressed +LICE: less dependent on SWELL +LICE: added octree palette generation/mapping +LICE: better .gif support, animated .gif writing +LICE: LICE_bitmapcmp() improvements (can give bounding rect of difference) +LICE: lice_arc simplification +Resampler: fixed crash on mode switches +SHM_msgreply: fixed issue with colliding named pipe names on OSX/Linux +SWELL: menu shortcuts fixed support for various keys, control modifier +SWELL: fixed GetDC()/ReleaseDC() updating window +SWELL: organized swell.h into swell-types.h, swell-functions.h +SWELL: stronger typing for various handles +SWELL: listview scrolling fixes +SWELL: fixed swell prefix support (for app-specific objC class name prefixes) +SWELL: ES_CENTER, ES_RIGHT support +SWELL: avoiding excessive WM_SIZE coming from top level window updates (destroying, focus change, etc) +SWELL: greatly optimized .ini file access functions (use assocarray, for bsearching of contents) +Virtwnd: rendered bg image cache support +Virtwnd: better support for 0px wide/tall windows (not drawing) +Virtwnd: better margin support in static text, button controls +Virtwnd: static text controls now can have children, autodisable border if background image set +Virtwnd: added GetPositionInTopVWnd() +Virtwnd: buttons can now force text along with their images, can ignore double click +Virtwnd: IAccessible wrapper layer, support for setting per-virtwnd description strings + + +2010-04-19: +SWELL: support for control key (as FLWIN, windows key) +iPlug: less dependent on SWELL for OSX (just swell-gdi) +iPlug: fixed projects to compile + +2010-04-15: +Added: Denormal.h denormal fixing functions and other FP utilities +Added: pooled string class +Added: basic unzip functions to zlib +Added: filebrowse.h for file browsing abstraction +Added: resample.h, low-decent-high quality samplerate conversion +assocarray: fixed leak on Clear(), added reverse lookup, changekey, deletebyindex +ConvoEngine: fixed quality when switching between silent/mono/stereo +convoEngine: optimizations +dirscan: better UTF8 fixes +EEL2: support for OS X x86_64, linux x86_64, fixes for Windows x64 +FileRead: open for read even when files are also opened for writes +HeapBuf: fixed leak on operator=() +iPlug: better cocoa view detection +iPlug: control+drag for slow control +LAME support: force newer APIs for x64, dynamic loading on linux, other fixes +Linux: better support for linux and linux/64 throughout much of WDL +LICE: arc drawing clipping fix +LICE: trapezoid drawing clipping fix (used by polygon drawing) +LICE: bezier clipping fix +LICE: added LICE_LoadPNGFromMemory() +Projectcontext: zlib mem support (ifdef'd out) +PtrList: WDL_PtrList_DeleteOnDestroy class for autodeletion of items +Scrollbar: prevent invalid draws with overlapping windows +SHM_msgreply/connection: support for OSX/linux +SWELL: generic target, with optional GDK support (in progress) +SWELL: clipboard improvements (CF_TEXT support, etc) +SWELL: more cursor images +SWELL: assorted OSX fixes/improvements/corrections +SWELL: text alignment support for listview columns/headers +SWELL: internal organization improvements +SWELL: stronger typing for HMENU +SWELL: GDI pooling optimizations, fixes for shutdown cleanup with pooled objects +SWELL: x86_64 support +SWELL: multitouch, hoirz mousewheel support +SWELL: OSX text drawing improvements +SWELL: LoadLibrary()/GetProcAddress() improvements, support for bundle loading, DllMain() +SWELL: CreateSocketEvent(), WaitForMultipleSocketObjects (or something) +SWELL: SWELL_CreateProcess() +SWELL: WM_SETFONT support for text boxes +SWELL: SetTimer() with callback support +SWELL: Carbon text field processing improvements +SWELL: better .cur loading (10.4 compat), hotspot detection +SWELL: AU Cocoa UI code fixed for certain bundle filanames +Timing: improvements +VerbEngine: fixed PPC denorm support +WDLTypes: WDL_FIXALIGN for forcing 8 byte alignment on struct members +WDLTypes: added WDL_bool (for 1 byte bools) +win32_utf8: fixes, added fopenUTF8() +wndsize: safer NULL pointer checking + +2009-11-30: +DirScan: handle scanning / on posix correctly +EEL: fixed x64 bugs on certain functions +FileRead: no longer use F_NOCACHE on OSX on remote filesystems +IPlug: OSX updates, project updates +JNetLib: added outgoing interface option for connections +LAME: fixed calling of LAME on win32 (correct tag writing, etc) +LAME: fixed VBR modes on linux/OSX, correct end of encode flushing +LICE: DrawText supports LICE_DT_NEEDALPHA for forcing setting of alphachannel +LICE: LICE_ProcessRect() for per pixel transformations +LICE: HSV adjust blend mode now has S and V adjusting full range rather than 0.5. +LICE: ++ Existing code using LICE_BLIT_MODE_HSVADJ may need to be adjusted. +SWELL: Sample SWELL application +SWELL: Main application framework (with instructions on creating new applications) +SWELL: Submenu fixes +SWELL: listview imagelist separate small/state support +SWELL: Added API to initiate a drag and drop operation +SWELL: Greatly improved keyboard handling for dialogs +SWELL: Tweaks to positioning of group and tab controls +SWELL: More listview/listbox APIs implemented (thanks sws), WM_CONTEXTMENU fixes +SWELL: SetWindowPos Z ordering enabled +SWELL: Added SetCurrentDirectory() +SWELL: Fixes for browseforfile etc +SWELL: GL support for swell HWNDs +SWELL: Fixed WritePrivateProfileString section deletion +SWELL: Fixed errors when GWL_STYLE changed in WM_CREATE/WM_INITDIALOG +SWELL: TrackPopupMenu() fixed when initiated from non-mouse-event +SWELL: preliminary support for targetting 64-bit on 10.6+ +virtwnd: buttons can own their image resources +virtwnd: handy utility dialog-derived class for win32 (handles paint correctly) +virtwnd: nested children fixes, vwnds automatically reset parent pointers of children on removal +virtwnd: cursor, tooltip processing infrastructure +virtwnd: fixed WDL_VirtualWnd_PreprocessBGConfig() on certain images +wdltypes: defined GCLP_HICONSM on VC6 +Added scrollbar emulation for SWELL, skinned scrollbar support for win32 (thanks to J Brown / Cool Scrollbar Library) +Added ProjectContext utility functions + +2009-10-10: +HeapBuf: optional WDL_HEAPBUF_DYNAMIC setting, for simpler and less configurable allocation management +HeapBuf/etc now handle failures better, added CopyFrom() +IPlug: OS X updates +LICE: line drawing optimizations, AA gamma correction +LICE: bezier-fill improvements +LICE: size optimizations, options to favor size over speed throughout LICE +LICE: scaledblit() no longer processes source-clipped pixels +LICE: scaledblit() now properly supports negative width source/dest rects (flips) +LICE: blit() fix for negative coordinates +LICE: Optimized copy/multiply blend modes to not require clamping (big gains in alpha-blended and filtered blits) +LICE: Optimized alpha blending (half the multiplies) +Virtwnd: buttons now have constant icon alpha parameter +Virtwnd: sliders no longer send excess scroll messages +Virtwnd: theme background drawing has flag to not draw left/right sides +SHM: fixed/optimized datapipe class, added low-latency threadsafe SHM message/reply class +SWELL: fixes to GetPrivateProfileString() with NULL second parameter +SWELL: added SWELL_GetAudioUnitCocoaView +SWELL: support for EndDialog() in modal WM_INITDIALOG +SWELL: SetMenuItemModifier() cleanups +SWELL: File browse dialogs now set default menu +SWELL: ScrollWindow() now properly invalidates the window +SWELL: EM_SCROLL, EM_SETSEL, EM_GETSEL support for edit fields +SWELL: OPAQUE text bk mode suport +SWELL: drag/drop source handling +SWELL: GetMenuItemInfo() MIIM_ID support +SWELL: Added SWELL_GetDefaultButtonID(), SWELL_KeyToASCII +scsrc: support for HTTP POST-ing chunks of encoded data to URL +scsrc: simplified data reprocessor api +scsrc: added sc_bounce/*.php (PHP data streaming server for scsrc) +WDL_PtrList::FindSorted() fixed +AssocArray fixes +win32_utf8 fixes +FileRead/FileWrite: better async file reading error handling, Win32 and OS X locking improvements +Added FFMPEG wrapper for encoding video files (with optional audio) +RFB client support (LICE--jnetlib) + +2009-07-04: + +WDL_SharedPool optimizations +SWELL: Fixes to carbon window hosting +SWELL: drop list tweaks +WDL_PtrList: fixed FindSorted() compilation on VC2008 +Added VC2010 projects for LICE etc + +2009-07-02: + +SWELL: mouse positioning updates (with synergy2 detection) +SWELL: WM_CTLCOLOR*, WM_DISPLAYCHANGE support +SWELL: BS_LEFTTEXT support for checkboxes +SWELL: Fixed menu item updating for top level submenus +SWELL: Implemented TreeView_HitTest +SWELL: Exposed API for SetOpaque +SWELL: nifty child window debug/diagnostic mode +SWELL: (default) options to use non-round buttons etc +SWELL: Fixed BitBltAlpha() for LICE sysbitmaps +SWELL: Carbon hosted window updates (no menu, activation fixes for BFD2, etc) +LICE: 8-bit PNG loading, JPG load from resource support +LICE: optimized source alpha w/ constalpha=1.0, other cases +virtwnd: listbox text drawing updates +LICE: LICE_CachedFont fixes when using both cached fonts and OS rendering +WDL_FileRead: support for synchronous unbuffered reads +WDL_FileRead/Write: OS X native open()/pread/mmap support (large files and unbuffered reads etc) +WDL_String: safer Get() for empty strings (returns read-write pointer) +WDL_PtrList: FindSorted / InsertSorted, EmptySafe() +WDL_Queue: optimized Compact() to autodetect pointless compacts +WDL_MergeSort: optimized for in-order data (stays in place) +EEL: safer locking of RAM +IPlug: better bitmap caching, jpg loading, x64 support, OS X udpates +AudioBufferContainer: supports wet/dry +UTF8 support fixes +Added WDL_AssocArray + + + +2009-04-08: + +UTF-8 support, win32_utf8.cpp for Win32 support (SWELL gets it automatically) +LICE: line and circle updates for fractional coordinates +LICE: preliminary SVG stuff +LICE: CachedFont updates (can render natively if possible and desired, better owned font support) +LICE: scaled blitting downsizing uses special filtering +LICE: disabled experimental GL extensions by default +LICE: better bezier stuff +IPlug: OSX URL update, VST parameter index validation, other updates +virtwnd: listbox improvements (horizontal mode etc) +SWELL: preliminary WM_CTLCOLORDLG support, dialog background updates +SWELL: better default button sizing +PtrList: InsertSorted() and FindSorted() methods +wndsize: margin querying api +LAME support handles mono signals better, better search paths +added basic blowfish implementation +added basic IRC line parsing/formatting functions +added incomplete non-working SHM datapipe class +convolution engine updates + + +2009-01-16: restored LICE bitmap ABI for compatability with older WDL versions +2009-01-15: Convolution engine optimizations and bugfixes, slightly updated impulse API +2009-01-13: simple reusable pitch shifter/time stretcher added +2009-01-11: WDL_Queue autocompact optimizations +2009-01-10: ADPCM decoder (IMA + MSADPCM + cADPCM), IMA/cADPCM encoder +2009-01-08: virtwnd comboboxes support SUB tags +2009-01-07: Vorbis encoder supports multichannel encoding +2009-01-01: Added LICE_DashedLine +2009-01-01: LICE_LoadPNGFromNamedResource() for OSX +2008-12-29: iPlug: added images for example +2008-12-27: LICE: Preliminary work for allowing LICE operations to be GL accelerated +2008-12-20: LICE: added effect names to test application +2008-12-20: LICE: added preliminary SVG support +2008-12-13: SWELL: Imagelists no longer free their bitmaps (to match win) +2008-12-13: WDL_WndSizer: reduced chance of HDWP leaks when invalid windows are stored +2008-12-09: Virtwnd: grayed state for buttons +2008-12-07: SWELL fixes for BitBlt/StretchBlt() with certain coordinates +2008-12-06: LICE HSV combining blend modes +2008-12-05: Plush2 multitexture fixes, fixed source-alpha modes +2008-12-04: Virtwnd: improved ordering of notification calls to allow deleting a vwnd from a command message +2008-11-24: WDL_String optimizations for empty strings +2008-11-22: LICE: line drawing improvements (changed signature of LICE_Line to use integers) +2008-11-20: SWELL: start on GTK implementations, far away from useful though +2008-11-19: EEL2 fixes for recent GCC versions on Linux, constness +2008-11-18: Added WDL_HeapBuf copy constructors +2008-11-18: LICE: RGB/HSV colorspace conversions +2008-11-17: LICE: overlay blend modes +2008-11-16: LICE: Better bezier drawing +2008-11-16: LICE: improved circle/arc drawing routes +2008-11-15: LICE JPEG loading fixes, JPEG writing, PNG writing byteorder fixes +2008-11-14: LICE_FillCircle() (needs optimizing) +2008-11-11: LICE_LoadImage, LICE_GetImageExtensoinList(),and LICE_CmpBitmap() +2008-11-08: LICE test app has new "fly" demo +2008-11-06: LICE: fixed bug in LICE_SubBitmap +2008-11-06: JNetLib: optional interface modes so you can easily reuse jnetlib across modules +2008-11-06: LICE: bitmaps no longer flipped on OS X, made isFlipped() non-virtual to enable better compile-time optimization +2008-11-05: LICE: reduced image resize heap thrashing +2008-11-05: virtwnd detects at load whether backgrounds have alphachannel info in each section +2008-11-04: virtwnd backgrounds disable filtering when not stretching +2008-11-03: LICE: optimizations for 50/50 fills, fast unfiltered stretchblt, etc +2008-11-03: virtwnd overhauls (removing HICON use) +2008-11-03: LICE: .ico loading overhaul, support for OS X +2008-11-01: SWELL: faster BitBlt() support +2008-11-01: LICE_CachedText OS X fixes +2008-10-31: LICE: LICE_LoadBMP() OS X support +2008-10-31: SWELL: GetObject() API subset +2008-10-31: LICE_MultiplyAddRect updated documentation and internals +2008-10-31: LICE_IFonts can own/destroy HFONTs +2008-10-30: LICE: Fixed a lot of small accuracy bugs +2008-10-30: LICE: PCX reading support +2008-10-30: Plush2: fixed singletexture mode when only multitexture compiled in +2008-10-30: Plush2: fixed repeating textures in bilinear mode +2008-10-30: Wndsizer: margin support +2008-10-30: Virtwnd: now uses LICE almost exclusively to draw controls +2008-10-30: Added Plush2: a port of the old 8bpp 3D rendering engine to a C++, 24 bit, LICE-combining multitexture capable colored lighting rendering engine +2008-10-27: Added LICE_FillTriangle(), LICE_HalveBlitAA(), fixed bug in LICE_StretchedBlit() +2008-10-26: Added iplug, a VST/AU plug-in framework +2008-10-26: LICE: LICE_SubBitmap for easy clipped rendering +2008-10-21: LICE: Added LICE_DrawRect(), LICE_DrawGlyph(), fast tiny circle drawing (glyph based), optimizations to internals +2008-10-20: LICE: Added LICE_IFont and LICE_CachedFont() for quick drawing and drawing to non-sysbitmaps. Also has certain useful other effects. +2008-10-20: LICE: Added LICE_DrawBezier +2008-10-20: Virtwnd: item backgrounds can now specify (with 255,255,0,255) outside-areas for some controls +2008-10-13: Added mergesort.h +2008-10-10: Added fast sinewave genereator (sinewavegen.h) +2008-10-10: SWELL: Keyboard fixes +2008-10-09: SWELL: Changed the way ScrollWindow() is implemented (scrolls children) +2008-10-09: Virtwnd: fixes for large canvas drawing +2008-10-05: Tweaks all around to reduce memory use (WDL_String gets WDL_HeapBuf granularity options etc in constructor) +2008-09-29: SWELL: Fixed MK_* VK_* bugs +2008-09-22: Win32_Curses updates, better OS X compatability, block cursor +2008-09-20: SWELL: ShowWindow(SW_HIDE) DestroyWindow() deal with focus better now +2008-09-17: Virtwnd: support for querying painter info, etc +2008-09-08: audiobuffercontainer fixes, optimizations +2008-09-06: Virtwnd sliders can optionally always send notifications on first click +2008-08-31: Overhauled pooling classes to be more general and reusable +2008-08-30: SWELL: Improved EndDialog() processing +2008-08-29: SWELL: Default menu for windows, modal windows +2008-08-28: SWELL: made GDI pooling threadsafe (Rosetta on 10.5 requires it) +2008-08-28: SWELL: fixed shift+mousewheel being sent correctly +2008-08-15: Fixed issues with Vorbis encoding-EOF-ness for NINJAM, added Vorbis comment support +2008-07-30: Cleaned up WDL_Queue's endian-converting functions +2008-07-28: Fixed WDL_String::Ellipsize() +2008-07-28: Added EEL2, a fast expression evaluator/code compiler that supports x86, x64 and PPC, MSVC and GCC. +2008-07-27: SWELL: fixed an issue with OS X hanging on fractional window positions +2008-07-22: Added WDL_String::Ellipsize() +2008-07-20: Win64 compatability, wdl_types.h has GetClassLongPtr() etc defines for MSVC6/OSX +2008-07-19: SWELL: GDI object pooling to reduce heap thrashing +2008-07-19: wndsize: fixed window positioning bug when used in SWELL. +2008-07-19: SWELL: LVNI_SELECTED support +2008-07-19: SWELL: better support for 64 bit OS X 10.5. +2008-07-17: VirtWnd slider mousewheel fixes +2008-07-15: SWELL: Treeview API improvements +2008-07-14: Added WDL_DLGRET for DLGPROC return type to ease compiler differences (use instead of BOOL CALLBACK or UINT_PTR CALLBACK) +2008-07-11: added win32_curses super-basic curses emulation for windows GUI +2008-07-10: LICE bitmap allocation changes (safer failures) +2008-07-10: SWELL: fixed GetCursorPos()/SetCursorPos() relationships +2008-07-10: SWELL: WM_MBUTTON* support +2008-07-08: Heapbuf can have optional small pre-allocations, heapbuf trace mode (to monitor heap use) +2008-06-30: LICE: Better bezierness +2008-06-30: SWELL: BitBltAlpha() and BitBltAlphaFromMem() +2008-06-24: WDL_FileWrite: fixed GetSize() at eof before flushing +2008-06-02: SWELL: many more bugfixes, initial work on 64 bit support, more +2008-05-21: Virtwnd: userdata for all virtwnd support +2008-05-05: SWELL: huge updates (too much to list) +2008-04-28: LICE: schwa's updated lice_bezier with support for quadratic nurbs +2008-04-27: SWELL: updates to EndDialog, added rc2cpp_dlg.php +2008-04-0x: fileread improvements for errors in async mode +2008-03-01: SWELL: ImageList_Destroy support +2008-02-09: lineparser improvements +2008-02-09: slightly faster drawtext, text cleanups +2008-02-09: virtwnd buttons only refresh on changes of button images +2008-02-09: virtwnd buttons support overlay outlines +2008-02-09: SWELL: php converter for menus: .rc to cpp +2008-02-09: SWELL: cursor hiding support +2008-02-09: wndsize: fix for when no window set +2008-02-09: lice: png write support (thanks cryptomail) +2008-02-09: shoutcast source: better encoder reinitialization, IRC channel support +2008-02-09: FFT: more define options +2008-02-09: convolution engine: fixed some bugs, added test app, _Div mode which allows high-cpu ZL operation +2008-01-25: LICE: flipped surface support for arcs +2007-12-17: SWELL: BM_SETCHECK support for buttons, basic FindWindowEx() emulation, better control font size selection +2007-12-13: SWELL: Basic ScrollWindow() emulation +2007-12-13: LICE: Updated LICE_IBitmap to include getDC() +2007-12-12: SWELL: GetDC(), GetWindowDC() improvements, GetSystemMetrics() +2007-12-12: SWELL: better WM_MOUSEWHEEL, WM_CONTEXTMENU message propagation +2007-12-11: SWELL: WM_NCCALCSIZE, WM_NCHITTEST etc support +2007-12-10: SWELL: basic _controlfp() support for rounding control (on x86) +2007-12-06: LICE: better bitmapped font +2007-12-05: LICE: schwa's faster/smaller lice_line +2007-12-04: SWELL: updated documentation in swell.h, GlobalAlloc supports GMEM_FIXED +2007-12-03: SWELL: added time.h inclusion for 10.5, fixed DrawText() when no font selected +2007-12-02: SWELL: GetProp API support, GetDC/GetWindowDC now usable during WM_PAINT/NCPAINT (they get the same HDC as BeginPaint) +2007-12-02: SWELL: dialogs can now have their window procedures subclassed, WM_NCPAINT support +2007-11-29: SWELL: fixed EnumClipboardFormats sometimes getting in an infinite loop +2007-11-29: SWELL: big DrawText overhaul (now uses NSAttributedString to draw) +2007-11-29: SWELL: added a bunch more compatibility defines to swell.h +2007-11-24: SWELL: support for having the application automatically provide the SWELL API to children +2007-11-24: SWELL: fixed some issues with name collisions to old deprecated Mac APIs +2007-11-24: SWELL: added opaque flag for dialogs (implicit on resourceless child windows) +2007-11-24: SWELL: basic GetDC()/ReleaseDC() support +2007-11-24: LICE: made OS X test app use opaque view (huge speedup) +2007-11-24: LICE: test app shows framerate +2007-11-23: SWELL: tons of menu fixes, dialog fixes, API extensions, more. too much to list. +2007-11-23: LICE: LICE_line supports flipped surfaces +2007-11-13: SWELL: Owned window support, tons of updates +2007-11-13: Virtwnd: support for controls eating mousedowns without capturing +2007-11-09: Fixed distribution making to include more docs/etc +2007-11-09: LICE: Test app now uses SWELL to run on OS X, included OS X example test project +2007-11-09: SWELL: Extensive updates for child dialogs, modal/modeless dialogs (mouse messages, painting, etc etc) +2007-11-09: SWELL: Modal/Modeless windows now support having their own menus (via GetMenu/SetMenu) +2007-11-09: SWELL: Added user-defined control classes for dialog template loading +2007-11-09: Updated GIFlib config.h for OS X support +2007-10-30: LICE: GIF, JPEG loading (included JPEG library and GifLib) +2007-10-30: LICE: Added bezier functions (Schwa) +2000-10-28: FileRead: better use of asynchronous buffer space, application level buffered synchronous reading support +2007-10-26: SWELL: WM_PAINT/BeginPaint/EndPaint emulation for child dialogs +2007-10-26: SWELL: SendMessage for windows that support it, made virtwnd use sendmessage +2007-10-26: SWELL: 3-state checkboxes, SetWindowLong improvements, fake *Capture, more +2007-10-24: SWELL: DialogBox/CreateDialog emulation, timer fixes, tons more +2007-10-23: LICE: scwha added LICE_ClipLine() +2007-10-19: LAMEEnc preliminary linux/OSX support (needs a lot of work though) +2007-09-17: virtual window system cleanups, sliders have mouse-hiding ctrl+ modifier mode +2007-09-17: virtual window system listbox custom drawing +2007-09-17: virtual window system, other improvements +2007-09-17: filewrite recovers from asynchronous failures from threads quitting +2007-09-12: pcmfmtcvt: corrected non-standard pcm format conversion +2007-09-14: LICE: fixed circle drawing with vc6 (template bug) +2007-09-01: LICE: faster rotating blit (fixed point) +2007-08-31: virtwnd: sliders can have centerline color defined in their skininfo +2007-08-27: LICE: faster more-fixed-point mode for LICE_ScaledBlit +2007-08-26: LICE: LICE_ScaledBlit properly obeys using a subimage source (and wont filter from outside) +2007-08-26: added db2val.h for easy dB<-->linear scale conversion +2007-08-25: virtwnd: stuff to let control bgs and window bg images have pink lines to define unstretched edges +2007-08-23: virtwnd: added listbox control +2007-08-22: LICE: defines for disabling Dodge, Add blend modes +2007-08-22: LICE: updated deltablit, added transformblit +2007-08-22: LICE: made LICE_FillRect support LICE_MODE_USE_ALPHA +2007-08-21: LICE: added LICE_BLIT_MODE_DODGE (thx schwa) +2007-08-21: LICE: added LICE_Blur, overloaded LICE_Blit() with better parameters +2007-08-16: LICE: added LICE_FillRect() +2007-08-15: filewrite: fixed GetSize() after flushed and unflushed writes in async mode +2007-08-04: virtwnd: made static text labels not refresh if text did not change +2007-08-04: started more detailed changelog +2007-07-23: added basic freeverb based reverb engine (verbengine.h) +2007-07-09: schwa fixes the FFT library's reordering API +2007-07-07: virtwnd fully uses LICE, support for advanced UI features +2007-07-01: lineparse.h now supports reading floats that use a , instead of . +2007-06-20: fileread.h has been asynchronous reading behavior +2007-06-20: virtwnd uses LICE for rendering gradients and general composition +2007-06-17: renamed string.h to wdlstring.h for if WDL is added to include paths +2007-05-09: first WDL release diff --git a/WDL/jnetlib/Makefile b/WDL/jnetlib/Makefile new file mode 100644 index 00000000..58cab477 --- /dev/null +++ b/WDL/jnetlib/Makefile @@ -0,0 +1,20 @@ +# freebsd3 makefile +default: jnl.a + +LDFLAGS = -pthread +CFLAGS = -s -O2 -Wall -DTHREAD_SAFE -D_THREAD_SAFE -D_REENTRANT +CC = gcc +CPP = g++ +CXX = g++ + +OBJS = asyncdns.o connection.o httpget.o httpserv.o listen.o util.o sercon.o + +jnl.a: ${OBJS} + -rm -f jnl.a + ar rcs jnl.a ${OBJS} + +test: ${OBJS} test.o + $(CC) ${CFLAGS} -o test test.o ${OBJS} ${LDFLAGS} + +clean: + -rm -f ${OBJS} test jnl.a test.o diff --git a/WDL/jnetlib/asyncdns.cpp b/WDL/jnetlib/asyncdns.cpp new file mode 100644 index 00000000..1b50139b --- /dev/null +++ b/WDL/jnetlib/asyncdns.cpp @@ -0,0 +1,266 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: asyncdns.cpp - JNL portable asynchronous DNS implementation +** License: see jnetlib.h +*/ + +#include "netinc.h" +#include "util.h" +#include "asyncdns.h" +#ifdef _WIN32 +#include +#endif + +JNL_AsyncDNS::JNL_AsyncDNS(int max_cache_entries) +{ + m_thread_kill=1; + m_thread=0; + m_cache_size=max_cache_entries; + m_cache=(cache_entry *)::malloc(sizeof(cache_entry)*m_cache_size); + memset(m_cache,0,sizeof(cache_entry)*m_cache_size); +} + +JNL_AsyncDNS::~JNL_AsyncDNS() +{ +#ifndef NO_DNS_SUPPORT + m_thread_kill=1; + +#ifdef _WIN32 + if (m_thread) + { + WaitForSingleObject(m_thread,INFINITE); + CloseHandle(m_thread); + } +#else + if (m_thread) + { + void *p; + pthread_join(m_thread,&p); + } +#endif//!_WIN32 +#endif//NO_DNS_SUPPORT + free(m_cache); +} + +#ifdef _WIN32 +unsigned WINAPI JNL_AsyncDNS::_threadfunc(void *_d) +#else +unsigned int JNL_AsyncDNS::_threadfunc(void *_d) +#endif +{ +#ifndef NO_DNS_SUPPORT + int nowinsock=JNL::open_socketlib(); + JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d; + int x; + for (x = 0; x < _this->m_cache_size && !_this->m_thread_kill; x ++) + { + if (_this->m_cache[x].last_used && !_this->m_cache[x].resolved) + { + if (!nowinsock) + { + if (_this->m_cache[x].mode==0) + { + struct hostent *hostentry; + hostentry=::gethostbyname(_this->m_cache[x].hostname); + if (hostentry) + { + _this->m_cache[x].addr=*((int*)hostentry->h_addr); + } + else + _this->m_cache[x].addr=INADDR_NONE; + } + else if (_this->m_cache[x].mode==1) + { + struct hostent *ent; + ent=::gethostbyaddr((const char *)&_this->m_cache[x].addr,4,AF_INET); + if (ent) + { + strncpy(_this->m_cache[x].hostname,ent->h_name,255); + _this->m_cache[x].hostname[255]=0; + } + else + { + _this->m_cache[x].hostname[0]=0; + } + } + _this->m_cache[x].resolved=1; + } + else + { + if (_this->m_cache[x].mode==0) + { + _this->m_cache[x].addr=INADDR_NONE; + _this->m_cache[x].resolved=1; + } + else if (_this->m_cache[x].mode==1) + { + _this->m_cache[x].hostname[0]=0; + _this->m_cache[x].resolved=1; + } + } + } + } + if (!nowinsock) JNL::close_socketlib(); + _this->m_thread_kill=1; +#endif // NO_DNS_SUPPORT + + return 0; +} + +int JNL_AsyncDNS::resolve(const char *hostname, unsigned int *addr) +{ + // return 0 on success, 1 on wait, -1 on unresolvable + int x; + unsigned int ip=inet_addr(hostname); + if (ip != INADDR_NONE) + { + *addr=ip; + return 0; + } +#ifndef NO_DNS_SUPPORT + + for (x = 0; x < m_cache_size; x ++) + { + if (!strcasecmp(m_cache[x].hostname,hostname) && m_cache[x].mode==0) + { + m_cache[x].last_used=time(NULL); + if (m_cache[x].resolved) + { + if (m_cache[x].addr == INADDR_NONE) + { + return -1; + } + struct in_addr in; + in.s_addr=m_cache[x].addr; + *addr=m_cache[x].addr; + return 0; + } + makesurethreadisrunning(); + return 1; + } + } + // add to resolve list + int oi=-1; + for (x = 0; x < m_cache_size; x ++) + { + if (!m_cache[x].last_used) + { + oi=x; + break; + } + if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved) + { + oi=x; + } + } + if (oi == -1) + { + return -1; + } + strcpy(m_cache[oi].hostname,hostname); + m_cache[oi].mode=0; + m_cache[oi].addr=INADDR_NONE; + m_cache[oi].resolved=0; + m_cache[oi].last_used=time(NULL); + + makesurethreadisrunning(); + return 1; +#else + return -1; +#endif +} + +int JNL_AsyncDNS::reverse(unsigned int addr, char *hostname) +{ + // return 0 on success, 1 on wait, -1 on unresolvable + int x; + if (addr == INADDR_NONE) + { + return -1; + } +#ifndef NO_DNS_SUPPORT + for (x = 0; x < m_cache_size; x ++) + { + if (m_cache[x].addr==addr && m_cache[x].mode==1) + { + m_cache[x].last_used=time(NULL); + if (m_cache[x].resolved) + { + if (!m_cache[x].hostname[0]) + { + return -1; + } + strncpy(hostname,m_cache[x].hostname,255); + hostname[255]=0; + return 0; + } + makesurethreadisrunning(); + return 1; + } + } + // add to resolve list + int oi=-1; + for (x = 0; x < m_cache_size; x ++) + { + if (!m_cache[x].last_used) + { + oi=x; + break; + } + if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved) + { + oi=x; + } + } + if (oi == -1) + { + return -1; + } + m_cache[oi].addr=addr; + m_cache[oi].hostname[0]=0; + m_cache[oi].resolved=0; + m_cache[oi].mode=1; + m_cache[oi].last_used=time(NULL); + + makesurethreadisrunning(); + return 1; +#else + return -1; +#endif +} + + +void JNL_AsyncDNS::makesurethreadisrunning(void) +{ +#ifndef NO_DNS_SUPPORT + if (m_thread_kill) + { + #ifdef _WIN32 + if (m_thread) + { + WaitForSingleObject(m_thread,INFINITE); + CloseHandle(m_thread); + } + unsigned id; + m_thread_kill=0; + m_thread=(HANDLE)_beginthreadex(NULL,0,_threadfunc,(void *)this,0,&id); + if (!m_thread) + { + #else + if (m_thread) + { + void *p; + pthread_join(m_thread,&p); + } + m_thread_kill=0; + if (pthread_create(&m_thread,NULL,(void *(*) (void *))_threadfunc,(void*)this) != 0) + { + #endif + m_thread_kill=1; + } + } +#endif//NO_DNS_SUPPORT +} diff --git a/WDL/jnetlib/asyncdns.h b/WDL/jnetlib/asyncdns.h new file mode 100644 index 00000000..172c2a94 --- /dev/null +++ b/WDL/jnetlib/asyncdns.h @@ -0,0 +1,74 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: asyncdns.h - JNL portable asynchronous DNS interface +** License: see jnetlib.h +** +** Usage: +** 1. Create JNL_AsyncDNS object, optionally with the number of cache entries. +** 2. call resolve() to resolve a hostname into an address. The return value of +** resolve is 0 on success (host successfully resolved), 1 on wait (meaning +** try calling resolve() with the same hostname in a few hundred milliseconds +** or so), or -1 on error (i.e. the host can't resolve). +** 3. call reverse() to do reverse dns (ala resolve()). +** 4. enjoy. +*/ + +#ifndef _ASYNCDNS_H_ +#define _ASYNCDNS_H_ + +#ifndef JNL_NO_DEFINE_INTERFACES +class JNL_IAsyncDNS +{ +public: + virtual ~JNL_IAsyncDNS() { } + virtual int resolve(const char *hostname, unsigned int *addr)=0; // return 0 on success, 1 on wait, -1 on unresolvable + virtual int reverse(unsigned int addr, char *hostname)=0; // return 0 on success, 1 on wait, -1 on unresolvable. hostname must be at least 256 bytes. +}; +#define JNL_AsyncDNS_PARENTDEF : public JNL_IAsyncDNS +#else +#define JNL_IAsyncDNS JNL_AsyncDNS +#define JNL_AsyncDNS_PARENTDEF +#endif + + +#ifndef JNL_NO_IMPLEMENTATION + +class JNL_AsyncDNS JNL_AsyncDNS_PARENTDEF +{ +public: + JNL_AsyncDNS(int max_cache_entries=64); + ~JNL_AsyncDNS(); + + int resolve(const char *hostname, unsigned int *addr); // return 0 on success, 1 on wait, -1 on unresolvable + int reverse(unsigned int addr, char *hostname); // return 0 on success, 1 on wait, -1 on unresolvable. hostname must be at least 256 bytes. + +private: + typedef struct + { + int last_used; // timestamp. + char resolved; + char mode; // 1=reverse + char hostname[256]; + unsigned int addr; + } + cache_entry; + + cache_entry *m_cache; + int m_cache_size; + volatile int m_thread_kill; +#ifdef _WIN32 + HANDLE m_thread; + static unsigned WINAPI _threadfunc(void *_d); +#else + pthread_t m_thread; + static unsigned int _threadfunc(void *_d); +#endif + void makesurethreadisrunning(void); + +}; +#endif // !JNL_NO_IMPLEMENTATION + +#endif //_ASYNCDNS_H_ diff --git a/WDL/jnetlib/connection.cpp b/WDL/jnetlib/connection.cpp new file mode 100644 index 00000000..43c2e1c8 --- /dev/null +++ b/WDL/jnetlib/connection.cpp @@ -0,0 +1,479 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: connection.cpp - JNL TCP connection implementation +** License: see jnetlib.h +*/ + +#include "netinc.h" +#include "util.h" +#include "connection.h" + + +JNL_Connection::JNL_Connection(JNL_IAsyncDNS *dns, int sendbufsize, int recvbufsize) +{ + m_errorstr=""; + if (dns == JNL_CONNECTION_AUTODNS) + { + m_dns=new JNL_AsyncDNS(); + m_dns_owned=1; + } + else + { + m_dns=dns; + m_dns_owned=0; + } + m_recv_buffer_len=recvbufsize; + m_send_buffer_len=sendbufsize; + m_recv_buffer=(char*)malloc(m_recv_buffer_len); + m_send_buffer=(char*)malloc(m_send_buffer_len); + m_socket=-1; + memset(m_recv_buffer,0,recvbufsize); + memset(m_send_buffer,0,sendbufsize); + m_remote_port=0; + m_state=STATE_NOCONNECTION; + m_localinterfacereq=INADDR_ANY; + m_recv_len=m_recv_pos=0; + m_send_len=m_send_pos=0; + m_host[0]=0; + m_saddr = new struct sockaddr_in; + memset(m_saddr,0,sizeof(struct sockaddr_in)); +} + +void JNL_Connection::connect(int s, struct sockaddr_in *loc) +{ + close(1); + m_socket=s; + m_remote_port=0; + m_dns=NULL; + if (loc) *m_saddr=*loc; + else memset(m_saddr,0,sizeof(struct sockaddr_in)); + if (m_socket != -1) + { + SET_SOCK_BLOCK(m_socket,0); + m_state=STATE_CONNECTED; + } + else + { + m_errorstr="invalid socket passed to connect"; + m_state=STATE_ERROR; + } +} + +void JNL_Connection::connect(char *hostname, int port) +{ + close(1); + m_remote_port=(short)port; + m_socket=::socket(AF_INET,SOCK_STREAM,0); + if (m_socket==-1) + { + m_errorstr="creating socket"; + m_state=STATE_ERROR; + } + else + { + if (m_localinterfacereq != INADDR_ANY) + { + sockaddr_in sa={0,}; + sa.sin_family=AF_INET; + sa.sin_addr.s_addr=m_localinterfacereq; + bind(m_socket,(struct sockaddr *)&sa,16); + } + SET_SOCK_BLOCK(m_socket,0); + strncpy(m_host,hostname,sizeof(m_host)-1); + m_host[sizeof(m_host)-1]=0; + memset(m_saddr,0,sizeof(struct sockaddr_in)); + if (!m_host[0]) + { + m_errorstr="empty hostname"; + m_state=STATE_ERROR; + } + else + { + m_state=STATE_RESOLVING; + m_saddr->sin_family=AF_INET; + m_saddr->sin_port=htons((unsigned short)port); + m_saddr->sin_addr.s_addr=inet_addr(hostname); + } + } +} + +JNL_Connection::~JNL_Connection() +{ + if (m_socket >= 0) + { + ::shutdown(m_socket, SHUT_RDWR); + ::closesocket(m_socket); + m_socket=-1; + } + free(m_recv_buffer); + free(m_send_buffer); + if (m_dns_owned) + { + delete m_dns; + } + delete m_saddr; +} + +void JNL_Connection::run(int max_send_bytes, int max_recv_bytes, int *bytes_sent, int *bytes_rcvd) +{ + int bytes_allowed_to_send=(max_send_bytes<0)?m_send_buffer_len:max_send_bytes; + int bytes_allowed_to_recv=(max_recv_bytes<0)?m_recv_buffer_len:max_recv_bytes; + + if (bytes_sent) *bytes_sent=0; + if (bytes_rcvd) *bytes_rcvd=0; + + switch (m_state) + { + case STATE_RESOLVING: + if (m_saddr->sin_addr.s_addr == INADDR_NONE) + { + int a=m_dns?m_dns->resolve(m_host,(unsigned int *)&m_saddr->sin_addr.s_addr):-1; + if (!a) { m_state=STATE_CONNECTING; } + else if (a == 1) + { + m_state=STATE_RESOLVING; + break; + } + else + { + m_errorstr="resolving hostname"; + m_state=STATE_ERROR; + return; + } + } + if (!::connect(m_socket,(struct sockaddr *)m_saddr,16)) + { + m_state=STATE_CONNECTED; + } + else if (ERRNO!=EINPROGRESS) + { + m_errorstr="connecting to host"; + m_state=STATE_ERROR; + } + else { m_state=STATE_CONNECTING; } + break; + case STATE_CONNECTING: + { + fd_set f[3]; + FD_ZERO(&f[0]); + FD_ZERO(&f[1]); + FD_ZERO(&f[2]); + FD_SET(m_socket,&f[0]); + FD_SET(m_socket,&f[1]); + FD_SET(m_socket,&f[2]); + struct timeval tv; + memset(&tv,0,sizeof(tv)); + if (select(m_socket+1,&f[0],&f[1],&f[2],&tv)==-1) + { + m_errorstr="connecting to host (calling select())"; + m_state=STATE_ERROR; + } + else if (FD_ISSET(m_socket,&f[1])) + { + m_state=STATE_CONNECTED; + } + else if (FD_ISSET(m_socket,&f[2])) + { + m_errorstr="connecting to host"; + m_state=STATE_ERROR; + } + } + break; + case STATE_CONNECTED: + case STATE_CLOSING: + if (m_send_len>0 && bytes_allowed_to_send>0) + { + int len=m_send_buffer_len-m_send_pos; + if (len > m_send_len) len=m_send_len; + if (len > bytes_allowed_to_send) len=bytes_allowed_to_send; + if (len > 0) + { + int res=::send(m_socket,m_send_buffer+m_send_pos,len,0); + if (res==-1 && ERRNO != EWOULDBLOCK) + { +// m_state=STATE_CLOSED; +// return; + } + if (res>0) + { + bytes_allowed_to_send-=res; + if (bytes_sent) *bytes_sent+=res; + m_send_pos+=res; + m_send_len-=res; + } + } + if (m_send_pos>=m_send_buffer_len) + { + m_send_pos=0; + if (m_send_len>0) + { + len=m_send_buffer_len-m_send_pos; + if (len > m_send_len) len=m_send_len; + if (len > bytes_allowed_to_send) len=bytes_allowed_to_send; + int res=::send(m_socket,m_send_buffer+m_send_pos,len,0); + if (res==-1 && ERRNO != EWOULDBLOCK) + { +// m_state=STATE_CLOSED; + } + if (res>0) + { + bytes_allowed_to_send-=res; + if (bytes_sent) *bytes_sent+=res; + m_send_pos+=res; + m_send_len-=res; + } + } + } + } + if (m_recv_len m_recv_buffer_len-m_recv_len) len=m_recv_buffer_len-m_recv_len; + if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv; + if (len>0) + { + int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0); + if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK)) + { + m_state=STATE_CLOSED; + break; + } + if (res > 0) + { + bytes_allowed_to_recv-=res; + if (bytes_rcvd) *bytes_rcvd+=res; + m_recv_pos+=res; + m_recv_len+=res; + } + } + if (m_recv_pos >= m_recv_buffer_len) + { + m_recv_pos=0; + if (m_recv_len < m_recv_buffer_len) + { + len=m_recv_buffer_len-m_recv_len; + if (len > bytes_allowed_to_recv) len=bytes_allowed_to_recv; + if (len > 0) + { + int res=::recv(m_socket,m_recv_buffer+m_recv_pos,len,0); + if (res == 0 || (res < 0 && ERRNO != EWOULDBLOCK)) + { + m_state=STATE_CLOSED; + break; + } + if (res > 0) + { + bytes_allowed_to_recv-=res; + if (bytes_rcvd) *bytes_rcvd+=res; + m_recv_pos+=res; + m_recv_len+=res; + } + } + } + } + } + if (m_state == STATE_CLOSING) + { + if (m_send_len < 1) m_state = STATE_CLOSED; + } + break; + default: break; + } +} + +void JNL_Connection::close(int quick) +{ + if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING) + { + m_state=STATE_CLOSED; + if (m_socket >= 0) + { + ::shutdown(m_socket, SHUT_RDWR); + ::closesocket(m_socket); + } + m_socket=-1; + memset(m_recv_buffer,0,m_recv_buffer_len); + memset(m_send_buffer,0,m_send_buffer_len); + m_remote_port=0; + m_recv_len=m_recv_pos=0; + m_send_len=m_send_pos=0; + m_host[0]=0; + memset(m_saddr,0,sizeof(struct sockaddr_in)); + } + else + { + if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING; + } +} + +int JNL_Connection::send_bytes_in_queue(void) +{ + return m_send_len; +} + +int JNL_Connection::send_bytes_available(void) +{ + return m_send_buffer_len-m_send_len; +} + +int JNL_Connection::send(const void *_data, int length) +{ + const char *data = static_cast(_data); + if (length > send_bytes_available()) + { + return -1; + } + + int write_pos=m_send_pos+m_send_len; + if (write_pos >= m_send_buffer_len) + { + write_pos-=m_send_buffer_len; + } + + int len=m_send_buffer_len-write_pos; + if (len > length) + { + len=length; + } + + memcpy(m_send_buffer+write_pos,data,len); + if (length > len) + { + memcpy(m_send_buffer,data+len,length-len); + } + m_send_len+=length; + return 0; +} + +int JNL_Connection::send_string(const char *line) +{ + return send(line,strlen(line)); +} + +int JNL_Connection::recv_bytes_available(void) +{ + return m_recv_len; +} + +int JNL_Connection::peek_bytes(void *_data, int maxlength) +{ + char *data = static_cast(_data); + if (maxlength > m_recv_len) + { + maxlength=m_recv_len; + } + int read_pos=m_recv_pos-m_recv_len; + if (read_pos < 0) + { + read_pos += m_recv_buffer_len; + } + int len=m_recv_buffer_len-read_pos; + if (len > maxlength) + { + len=maxlength; + } + if (data != NULL) { + memcpy(data,m_recv_buffer+read_pos,len); + if (len < maxlength) + { + memcpy(data+len,m_recv_buffer,maxlength-len); + } + } + + return maxlength; +} + +int JNL_Connection::recv_bytes(void *_data, int maxlength) +{ + char *data = static_cast(_data); + + int ml=peek_bytes(data,maxlength); + m_recv_len-=ml; + return ml; +} + +int JNL_Connection::getbfromrecv(int pos, int remove) +{ + int read_pos=m_recv_pos-m_recv_len + pos; + if (pos < 0 || pos > m_recv_len) return -1; + if (read_pos < 0) + { + read_pos += m_recv_buffer_len; + } + if (read_pos >= m_recv_buffer_len) + { + read_pos-=m_recv_buffer_len; + } + if (remove) m_recv_len--; + return m_recv_buffer[read_pos]; +} + +int JNL_Connection::recv_lines_available(void) +{ + int l=recv_bytes_available(); + int lcount=0; + int lastch=0; + int pos; + for (pos=0; pos < l; pos ++) + { + int t=getbfromrecv(pos,0); + if (t == -1) return lcount; + if ((t=='\r' || t=='\n') &&( + (lastch != '\r' && lastch != '\n') || lastch==t + )) lcount++; + lastch=t; + } + return lcount; +} + +int JNL_Connection::recv_line(char *line, int maxlength) +{ + if (maxlength > m_recv_len) maxlength=m_recv_len; + while (maxlength--) + { + int t=getbfromrecv(0,1); + if (t == -1) + { + *line=0; + return 0; + } + if (t == '\r' || t == '\n') + { + int r=getbfromrecv(0,0); + if ((r == '\r' || r == '\n') && r != t) getbfromrecv(0,1); + *line=0; + return 0; + } + *line++=(char)t; + } + return 1; +} + +void JNL_Connection::set_interface(int useInterface) // call before connect if needed +{ + m_localinterfacereq = useInterface; +} + + +unsigned int JNL_Connection::get_interface(void) +{ + if (m_socket==-1) return 0; + struct sockaddr_in sin; + memset(&sin,0,sizeof(sin)); + socklen_t len=16; + if (::getsockname(m_socket,(struct sockaddr *)&sin,&len)) return 0; + return (unsigned int) sin.sin_addr.s_addr; +} + +unsigned int JNL_Connection::get_remote() +{ + return m_saddr->sin_addr.s_addr; +} + +short JNL_Connection::get_remote_port() +{ + return m_remote_port; +} diff --git a/WDL/jnetlib/connection.h b/WDL/jnetlib/connection.h new file mode 100644 index 00000000..1ae140ac --- /dev/null +++ b/WDL/jnetlib/connection.h @@ -0,0 +1,188 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: connection.h - JNL TCP connection interface +** License: see jnetlib.h +** +** Usage: +** 1. Create a JNL_Connection object, optionally specifying a JNL_IAsyncDNS +** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto), +** and the send and receive buffer sizes. +** 2. Call connect() to have it connect to a host/port (the hostname will be +** resolved if possible). +** 3. call run() with the maximum send/recv amounts, and optionally parameters +** so you can tell how much has been send/received. You want to do this a lot, while: +** 4. check get_state() to check the state of the connection. The states are: +** JNL_Connection::STATE_ERROR +** - an error has occured on the connection. the connection has closed, +** and you can no longer write to the socket (there still might be +** data in the receive buffer - use recv_bytes_available()). +** JNL_Connection::STATE_NOCONNECTION +** - no connection has been made yet. call connect() already! :) +** JNL_Connection::STATE_RESOLVING +** - the connection is still waiting for a JNL_AsycnDNS to resolve the +** host. +** JNL_Connection::STATE_CONNECTING +** - the asynchronous call to connect() is still running. +** JNL_Connection::STATE_CONNECTED +** - the connection has connected, all is well. +** JNL_Connection::STATE_CLOSING +** - the connection is closing. This happens after a call to close, +** without the quick parameter set. This means that the connection +** will close once the data in the send buffer is sent (data could +** still be being received when it would be closed). After it is +** closed, the state will transition to: +** JNL_Connection::STATE_CLOSED +** - the connection has closed, generally without error. There still +** might be data in the receieve buffer, use recv_bytes_available(). +** 5. Use send() and send_string() to send data. You can use +** send_bytes_in_queue() to see how much has yet to go out, or +** send_bytes_available() to see how much you can write. If you use send() +** or send_string() and not enough room is available, both functions will +** return error ( < 0) +** 6. Use recv() and recv_line() to get data. If you want to see how much data +** there is, use recv_bytes_available() and recv_lines_available(). If you +** call recv() and not enough data is available, recv() will return how much +** data was actually read. See comments at the function defs. +** +** 7. To close, call close(1) for a quick close, or close() for a close that will +** make the socket close after sending all the data sent. +** +** 8. delete ye' ol' object. +*/ + +#ifndef _CONNECTION_H_ +#define _CONNECTION_H_ + +#include "asyncdns.h" + +#define JNL_CONNECTION_AUTODNS ((JNL_IAsyncDNS*)-1) + +struct sockaddr_in; + +#ifndef JNL_NO_DEFINE_INTERFACES +class JNL_IConnection +{ + public: + virtual ~JNL_IConnection() { } + virtual void connect(char *hostname, int port)=0; + virtual void connect(int sock, struct sockaddr_in *loc=NULL)=0; // used by the listen object, usually not needed by users. + + virtual void run(int max_send_bytes=-1, int max_recv_bytes=-1, int *bytes_sent=NULL, int *bytes_rcvd=NULL)=0; + virtual int get_state()=0; + virtual const char *get_errstr()=0; + + virtual void close(int quick=0)=0; + virtual void flush_send(void)=0; + + virtual int send_bytes_in_queue(void)=0; + virtual int send_bytes_available(void)=0; + virtual int send(const void *data, int length)=0; // returns -1 if not enough room + virtual int send_bytes(const void *data, int length)=0; + virtual int send_string(const char *line)=0; // returns -1 if not enough room + + virtual int recv_bytes_available(void)=0; + virtual int recv_bytes(void *data, int maxlength)=0; // returns actual bytes read + virtual int recv_lines_available(void)=0; + virtual int recv_line(char *line, int maxlength)=0; // returns 0 if the line was terminated with a \r or \n, 1 if not. + // (i.e. if you specify maxlength=10, and the line is 12 bytes long + // it will return 1. or if there is no \r or \n and that's all the data + // the connection has.) + virtual int peek_bytes(void *data, int maxlength)=0; // returns bytes peeked + + virtual unsigned int get_interface(void)=0; // this returns the interface the connection is on + virtual unsigned int get_remote(void)=0; // remote host ip. + virtual short get_remote_port(void)=0; // this returns the remote port of connection + + virtual void set_interface(int useInterface)=0; // call before connect if needed + }; + + #define JNL_Connection_PARENTDEF : public JNL_IConnection +#else + #define JNL_IConnection JNL_Connection + #define JNL_Connection_PARENTDEF +#endif + +#ifndef JNL_NO_IMPLEMENTATION + +class JNL_Connection JNL_Connection_PARENTDEF +{ + public: + typedef enum + { + STATE_ERROR, + STATE_NOCONNECTION, + STATE_RESOLVING, + STATE_CONNECTING, + STATE_CONNECTED, + STATE_CLOSING, + STATE_CLOSED + } state; + + JNL_Connection(JNL_IAsyncDNS *dns=JNL_CONNECTION_AUTODNS, int sendbufsize=8192, int recvbufsize=8192); + ~JNL_Connection(); + + void connect(char *hostname, int port); + void connect(int sock, struct sockaddr_in *loc=NULL); // used by the listen object, usually not needed by users. + + void run(int max_send_bytes=-1, int max_recv_bytes=-1, int *bytes_sent=NULL, int *bytes_rcvd=NULL); + int get_state() { return m_state; } + const char *get_errstr() { return m_errorstr; } + + void close(int quick=0); + void flush_send(void) { m_send_len=m_send_pos=0; } + + int send_bytes_in_queue(void); + int send_bytes_available(void); + int send(const void *data, int length); // returns -1 if not enough room + inline int send_bytes(const void *data, int length) { return send(data, length); } + int send_string(const char *line); // returns -1 if not enough room + + + int recv_bytes_available(void); + int recv_bytes(void *data, int maxlength); // returns actual bytes read + int recv_lines_available(void); + int recv_line(char *line, int maxlength); // returns 0 if the line was terminated with a \r or \n, 1 if not. + // (i.e. if you specify maxlength=10, and the line is 12 bytes long + // it will return 1. or if there is no \r or \n and that's all the data + // the connection has.) + int peek_bytes(void *data, int maxlength); // returns bytes peeked + + unsigned int get_interface(void); // this returns the interface the connection is on + unsigned int get_remote(void); // remote host ip. + short get_remote_port(void); // this returns the remote port of connection + + void set_interface(int useInterface); // call before connect if needed + + protected: + int m_socket; + short m_remote_port; + char *m_recv_buffer; + char *m_send_buffer; + int m_recv_buffer_len; + int m_send_buffer_len; + + int m_recv_pos; + int m_recv_len; + int m_send_pos; + int m_send_len; + + int m_localinterfacereq; + struct sockaddr_in *m_saddr; + char m_host[256]; + + JNL_IAsyncDNS *m_dns; + int m_dns_owned; + + state m_state; + const char *m_errorstr; + + int getbfromrecv(int pos, int remove); // used by recv_line* + +}; + +#endif + +#endif // _Connection_H_ diff --git a/WDL/jnetlib/httpget.cpp b/WDL/jnetlib/httpget.cpp new file mode 100644 index 00000000..ba0cbaca --- /dev/null +++ b/WDL/jnetlib/httpget.cpp @@ -0,0 +1,445 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: httpget.cpp - JNL HTTP GET implementation +** License: see jnetlib.h +*/ + +#include "netinc.h" +#include "util.h" +#include "httpget.h" + + +JNL_HTTPGet::JNL_HTTPGet(JNL_IAsyncDNS *dns, int recvbufsize, char *proxy) +{ + m_recvbufsize=recvbufsize; + m_dns=dns; + m_con=NULL; + m_http_proxylpinfo=0; + m_http_proxyhost=0; + m_http_proxyport=0; + if (proxy && *proxy) + { + char *p=(char*)malloc(strlen(proxy)+1); + if (p) + { + char *r=NULL; + strcpy(p,proxy); + do_parse_url(p,&m_http_proxyhost,&m_http_proxyport,&r,&m_http_proxylpinfo); + free(r); + free(p); + } + } + m_sendheaders=NULL; + reinit(); +} + +void JNL_HTTPGet::reinit() +{ + m_errstr=0; + m_recvheaders=NULL; + m_recvheaders_size=0; + m_http_state=0; + m_http_port=0; + m_http_url=0; + m_reply=0; + m_http_host=m_http_lpinfo=m_http_request=NULL; +} + +void JNL_HTTPGet::deinit() +{ + delete m_con; m_con = NULL; + free(m_recvheaders); + + free(m_http_url); + free(m_http_host); + free(m_http_lpinfo); + free(m_http_request); + free(m_errstr); + free(m_reply); + reinit(); +} + +JNL_HTTPGet::~JNL_HTTPGet() +{ + deinit(); + free(m_sendheaders); + free(m_http_proxylpinfo); + free(m_http_proxyhost); + +} + + +void JNL_HTTPGet::addheader(const char *header) +{ + if (strstr(header,"\r") || strstr(header,"\n")) return; + if (!m_sendheaders) + { + m_sendheaders=(char*)malloc(strlen(header)+3); + if (m_sendheaders) + { + strcpy(m_sendheaders,header); + strcat(m_sendheaders,"\r\n"); + } + } + else + { + char *t=(char*)malloc(strlen(header)+strlen(m_sendheaders)+1+2); + if (t) + { + strcpy(t,m_sendheaders); + strcat(t,header); + strcat(t,"\r\n"); + free(m_sendheaders); + m_sendheaders=t; + } + } +} + +void JNL_HTTPGet::do_encode_mimestr(char *in, char *out) +{ + char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int shift = 0; + int accum = 0; + + while (*in) + { + if (*in) + { + accum <<= 8; + shift += 8; + accum |= *in++; + } + while ( shift >= 6 ) + { + shift -= 6; + *out++ = alphabet[(accum >> shift) & 0x3F]; + } + } + if (shift == 4) + { + *out++ = alphabet[(accum & 0xF)<<2]; + *out++='='; + } + else if (shift == 2) + { + *out++ = alphabet[(accum & 0x3)<<4]; + *out++='='; + *out++='='; + } + + *out++=0; +} + + +void JNL_HTTPGet::connect(const char *url, int ver, const char *requestmethod) +{ + deinit(); + m_http_url=(char*)malloc(strlen(url)+1); + strcpy(m_http_url,url); + do_parse_url(m_http_url,&m_http_host,&m_http_port,&m_http_request, &m_http_lpinfo); + strcpy(m_http_url,url); + if (!m_http_host || !m_http_host[0] || !m_http_port) + { + m_http_state=-1; + seterrstr("invalid URL"); + return; + } + + int sendbufferlen=0; + + if (!m_http_proxyhost || !m_http_proxyhost[0]) + { + sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_request) + 9 /* HTTP/1.0 */ + 2; + } + else + { + sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_url) + 9 /* HTTP/1.0 */ + 2; + if (m_http_proxylpinfo&&m_http_proxylpinfo[0]) + { + sendbufferlen+=58+strlen(m_http_proxylpinfo)*2; // being safe here + } + } + sendbufferlen += 5 /* Host: */ + strlen(m_http_host) + 2; + + if (m_http_lpinfo&&m_http_lpinfo[0]) + { + sendbufferlen+=46+strlen(m_http_lpinfo)*2; // being safe here + } + + if (m_sendheaders) sendbufferlen+=strlen(m_sendheaders); + + char *str=(char*)malloc(sendbufferlen+1024); + if (!str) + { + seterrstr("error allocating memory"); + m_http_state=-1; + } + + if (!m_http_proxyhost || !m_http_proxyhost[0]) + { + wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod,m_http_request,ver%10); + } + else + { + wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod, m_http_url,ver%10); + } + + wsprintf(str+strlen(str),"Host:%s\r\n",m_http_host); + + if (m_http_lpinfo&&m_http_lpinfo[0]) + { + strcat(str,"Authorization: Basic "); + do_encode_mimestr(m_http_lpinfo,str+strlen(str)); + strcat(str,"\r\n"); + } + if (m_http_proxylpinfo&&m_http_proxylpinfo[0]) + { + strcat(str,"Proxy-Authorization: Basic "); + do_encode_mimestr(m_http_proxylpinfo,str+strlen(str)); + strcat(str,"\r\n"); + } + + if (m_sendheaders) strcat(str,m_sendheaders); + strcat(str,"\r\n"); + + int a=m_recvbufsize; + if (a < 4096) a=4096; + m_con=new JNL_Connection(m_dns,strlen(str)+4,a); + if (m_con) + { + if (!m_http_proxyhost || !m_http_proxyhost[0]) + { + m_con->connect(m_http_host,m_http_port); + } + else + { + m_con->connect(m_http_proxyhost,m_http_proxyport); + } + m_con->send_string(str); + } + else + { + m_http_state=-1; + seterrstr("could not create connection object"); + } + free(str); + +} + +void JNL_HTTPGet::do_parse_url(char *url, char **host, int *port, char **req, char **lp) +{ + char *p,*np; + free(*host); *host=0; + free(*req); *req=0; + free(*lp); *lp=0; + + if (strstr(url,"://")) np=p=strstr(url,"://")+3; + else np=p=url; + while (*np != '/' && *np) np++; + if (*np) + { + *req=(char*)malloc(strlen(np)+1); + if (*req) strcpy(*req,np); + *np++=0; + } + else + { + *req=(char*)malloc(2); + if (*req) strcpy(*req,"/"); + } + + np=p; + while (*np != '@' && *np) np++; + if (*np) + { + *np++=0; + *lp=(char*)malloc(strlen(p)+1); + if (*lp) strcpy(*lp,p); + p=np; + } + else + { + *lp=(char*)malloc(1); + if (*lp) strcpy(*lp,""); + } + np=p; + while (*np != ':' && *np) np++; + if (*np) + { + *np++=0; + *port=atoi(np); + } else *port=80; + *host=(char*)malloc(strlen(p)+1); + if (*host) strcpy(*host,p); +} + + +const char *JNL_HTTPGet::getallheaders() +{ // double null terminated, null delimited list + if (m_recvheaders) return m_recvheaders; + else return "\0\0"; +} + +const char *JNL_HTTPGet::getheader(const char *headername) +{ + char *ret=NULL; + if (strlen(headername)<1||!m_recvheaders) return NULL; + char *buf=(char*)malloc(strlen(headername)+2); + strcpy(buf,headername); + if (buf[strlen(buf)-1]!=':') strcat(buf,":"); + char *p=m_recvheaders; + while (*p) + { + if (!strnicmp(buf,p,strlen(buf))) + { + ret=p+strlen(buf); + while (*ret == ' ') ret++; + break; + } + p+=strlen(p)+1; + } + free(buf); + return ret; +} + +int JNL_HTTPGet::run() +{ + int cnt=0; + if (m_http_state==-1||!m_con) return -1; // error + + +run_again: + m_con->run(); + + if (m_con->get_state()==JNL_Connection::STATE_ERROR) + { + seterrstr(m_con->get_errstr()); + return -1; + } + if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1; + + if (m_http_state==0) // connected, waiting for reply + { + if (m_con->recv_lines_available()>0) + { + char buf[4096]; + m_con->recv_line(buf,4095); + buf[4095]=0; + m_reply=(char*)malloc(strlen(buf)+1); + strcpy(m_reply,buf); + + int code=getreplycode(); + if (code == 200 || code==206) m_http_state=2; // proceed to read headers normally + else if (code == 301 || code==302) + { + m_http_state=1; // redirect city + } + else + { + seterrstr(buf); + m_http_state=-1; + return -1; + } + cnt=0; + } + else if (!cnt++) goto run_again; + } + if (m_http_state == 1) // redirect + { + while (m_con->recv_lines_available() > 0) + { + char buf[4096]; + m_con->recv_line(buf,4096); + if (!buf[0]) + { + m_http_state=-1; + return -1; + } + if (!strnicmp(buf,"Location:",9)) + { + const char *p=buf+9; while (*p== ' ') p++; + if (*p) + { + connect(p); + return 0; + } + } + } + } + if (m_http_state==2) + { + if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again; + while (m_con->recv_lines_available() > 0) + { + char buf[4096]; + m_con->recv_line(buf,4096); + if (!buf[0]) { m_http_state=3; break; } + if (!m_recvheaders) + { + m_recvheaders_size=strlen(buf)+1; + m_recvheaders=(char*)malloc(m_recvheaders_size+1); + if (m_recvheaders) + { + strcpy(m_recvheaders,buf); + m_recvheaders[m_recvheaders_size]=0; + } + } + else + { + int oldsize=m_recvheaders_size; + m_recvheaders_size+=strlen(buf)+1; + char *n=(char*)malloc(m_recvheaders_size+1); + if (n) + { + memcpy(n,m_recvheaders,oldsize); + strcpy(n+oldsize,buf); + n[m_recvheaders_size]=0; + free(m_recvheaders); + m_recvheaders=n; + } + } + } + } + if (m_http_state==3) + { + } + return 0; +} + +int JNL_HTTPGet::get_status() // returns 0 if connecting, 1 if reading headers, + // 2 if reading content, -1 if error. +{ + if (m_http_state < 0) return -1; + if (m_http_state < 2) return 0; + if (m_http_state == 2) return 1; + if (m_http_state == 3) return 2; + return -1; +} + +int JNL_HTTPGet::getreplycode()// returns 0 if none yet, otherwise returns http reply code. +{ + if (!m_reply) return 0; + char *p=m_reply; + while (*p && *p != ' ') p++; // skip over HTTP/x.x + if (!*p) return 0; + return atoi(++p); +} + +int JNL_HTTPGet::bytes_available() +{ + if (m_con && m_http_state==3) return m_con->recv_bytes_available(); + return 0; +} +int JNL_HTTPGet::get_bytes(char *buf, int len) +{ + if (m_con && m_http_state==3) return m_con->recv_bytes(buf,len); + return 0; +} +int JNL_HTTPGet::peek_bytes(char *buf, int len) +{ + if (m_con && m_http_state==3) return m_con->peek_bytes(buf,len); + return 0; +} diff --git a/WDL/jnetlib/httpget.h b/WDL/jnetlib/httpget.h new file mode 100644 index 00000000..aebed13c --- /dev/null +++ b/WDL/jnetlib/httpget.h @@ -0,0 +1,152 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: httpget.h - JNL interface for doing HTTP GETs. +** License: see jnetlib.h +** +** Usage: +** 1. Create a JNL_HTTPGet object, optionally specifying a JNL_AsyncDNS +** object to use (or NULL for none, or JNL_CONNECTION_AUTODNS for auto), +** and the receive buffer size, and a string specifying proxy (or NULL +** for none). See note on proxy string below. +** 2. call addheader() to add whatever headers you want. It is recommended to +** add at least the following two: +** addheader("User-Agent:MyApp (Mozilla)"); +*/// addheader("Accept:*/*"); +/* ( the comment weirdness is there so I Can do the star-slash :) +** 3. Call connect() with the URL you wish to GET (see URL string note below) +** 4. Call run() once in a while, checking to see if it returns -1 +** (if it does return -1, call geterrorstr() to see what the error is). +** (if it returns 1, no big deal, the connection has closed). +** 5. While you're at it, you can call bytes_available() to see if any data +** from the http stream is available, or getheader() to see if any headers +** are available, or getreply() to see the HTTP reply, or getallheaders() +** to get a double null terminated, null delimited list of headers returned. +** 6. If you want to read from the stream, call get_bytes (which returns how much +** was actually read). +** 7. content_length() is a helper function that uses getheader() to check the +** content-length header. +** 8. Delete ye' ol' object when done. +** +** Proxy String: +** should be in the format of host:port, or user@host:port, or +** user:password@host:port. if port is not specified, 80 is assumed. +** URL String: +** should be in the format of http://user:pass@host:port/requestwhatever +** note that user, pass, port, and /requestwhatever are all optional :) +** note that also, http:// is really not important. if you do poo:// +** or even leave out the http:// altogether, it will still work. +*/ + +#ifndef _HTTPGET_H_ +#define _HTTPGET_H_ + +#include "connection.h" + +#ifndef JNL_NO_DEFINE_INTERFACES + class JNL_IHTTPGet + { + public: + + virtual ~JNL_IHTTPGet() { } + + virtual void addheader(const char *header)=0; + + virtual void connect(const char *url, int ver=0, const char *requestmethod="GET")=0; + + virtual int run()=0; // returns: 0 if all is OK. -1 if error (call geterrorstr()). 1 if connection closed. + + virtual int get_status()=0; // returns 0 if connecting, 1 if reading headers, + // 2 if reading content, -1 if error. + + virtual const char *getallheaders()=0; // double null terminated, null delimited list + virtual const char *getheader(const char *headername)=0; + virtual const char *getreply()=0; + virtual int getreplycode()=0; // returns 0 if none yet, otherwise returns http reply code. + + virtual const char *geterrorstr()=0; + + virtual int bytes_available()=0; + virtual int get_bytes(char *buf, int len)=0; + virtual int peek_bytes(char *buf, int len)=0; + + virtual int content_length()=0; + + virtual JNL_IConnection *get_con()=0; + }; + #define JNL_HTTPGet_PARENTDEF : public JNL_IHTTPGet +#else + #define JNL_IHTTPGet JNL_HTTPGet + #define JNL_HTTPGet_PARENTDEF +#endif + +#ifndef JNL_NO_IMPLEMENTATION + +class JNL_HTTPGet JNL_HTTPGet_PARENTDEF +{ + public: + JNL_HTTPGet(JNL_IAsyncDNS *dns=JNL_CONNECTION_AUTODNS, int recvbufsize=16384, char *proxy=NULL); + ~JNL_HTTPGet(); + + void addheader(const char *header); + + void connect(const char *url, int ver=0, const char *requestmethod="GET"); + + int run(); // returns: 0 if all is OK. -1 if error (call geterrorstr()). 1 if connection closed. + + int get_status(); // returns 0 if connecting, 1 if reading headers, + // 2 if reading content, -1 if error. + + const char *getallheaders(); // double null terminated, null delimited list + const char *getheader(const char *headername); + const char *getreply() { return m_reply; } + int getreplycode(); // returns 0 if none yet, otherwise returns http reply code. + + const char *geterrorstr() { return m_errstr;} + + int bytes_available(); + int get_bytes(char *buf, int len); + int peek_bytes(char *buf, int len); + + int content_length() { const char *p=getheader("content-length"); if (p) return atoi(p); return 0; } + + JNL_IConnection *get_con() { return m_con; } + + + + static void do_parse_url(char *url, char **host, int *port, char **req, char **lp); // url gets thrashed, and host/req/lp are freed/allocated + static void do_encode_mimestr(char *in, char *out); + + protected: + void reinit(); + void deinit(); + void seterrstr(const char *str) { if (m_errstr) free(m_errstr); m_errstr=(char*)malloc(strlen(str)+1); strcpy(m_errstr,str); } + + JNL_IAsyncDNS *m_dns; + JNL_IConnection *m_con; + int m_recvbufsize; + + int m_http_state; + + int m_http_port; + char *m_http_url; + char *m_http_host; + char *m_http_lpinfo; + char *m_http_request; + + char *m_http_proxylpinfo; + char *m_http_proxyhost; + int m_http_proxyport; + + char *m_sendheaders; + char *m_recvheaders; + int m_recvheaders_size; + char *m_reply; + + char *m_errstr; +}; +#endif + +#endif // _HTTPGET_H_ diff --git a/WDL/jnetlib/httpserv.cpp b/WDL/jnetlib/httpserv.cpp new file mode 100644 index 00000000..721bee63 --- /dev/null +++ b/WDL/jnetlib/httpserv.cpp @@ -0,0 +1,254 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: httpserv.cpp - JNL HTTP GET/POST serving implementation +** License: see jnetlib.h +** +** This class just manages the http reply/sending, not where the data +** comes from, etc. +*/ + +#include "netinc.h" +#include "util.h" + +#include "httpserv.h" + +/* + States for m_state: + -1 error (connection closed, etc) + 0 not read request yet. + 1 reading headers + 2 headers read, have not sent reply + 3 sent reply + 4 closed +*/ + +JNL_HTTPServ::JNL_HTTPServ(JNL_IConnection *con) +{ + m_keepalive=true; + m_con=con; + m_state=0; + m_reply_headers=0; + m_reply_string=0; + m_recvheaders=0; + m_recv_request=0; + m_recvheaders_size=0; + m_errstr=0; + m_reply_ready=0; +} + +JNL_HTTPServ::~JNL_HTTPServ() +{ + free(m_recv_request); + free(m_recvheaders); + free(m_reply_string); + free(m_reply_headers); + free(m_errstr); + delete m_con; +} + +int JNL_HTTPServ::run() +{ // returns: < 0 on error, 0 on connection close, 1 if reading request, 2 if reply not sent, 3 if reply sent, sending data. + int cnt=0; +run_again: + m_con->run(); + if (m_con->get_state()==JNL_Connection::STATE_ERROR) + { + seterrstr(m_con->get_errstr()); + return -1; + } + if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 4; + + if (m_state == 0) + { + if (m_con->recv_lines_available()>0) + { + char *buf=(char*)malloc(m_con->recv_bytes_available()-1); + m_con->recv_line(buf,m_con->recv_bytes_available()-1); + free(m_recv_request); + m_recv_request=(char*)malloc(strlen(buf)+2); + strcpy(m_recv_request,buf); + m_recv_request[strlen(m_recv_request)+1]=0; + free(buf); + buf=m_recv_request; + while (*buf) buf++; + while (buf >= m_recv_request && *buf != ' ') buf--; + if (strncmp(buf+1,"HTTP",4) || strncmp(m_recv_request,"GET ",3)) + { + seterrstr("malformed HTTP request"); + m_state=-1; + } + else + { + if (buf[strlen(buf)-1]=='0') m_keepalive=false; // old http 1.0 + m_state=1; + cnt=0; + if (buf >= m_recv_request) buf[0]=buf[1]=0; + + buf=strstr(m_recv_request,"?"); + if (buf) + { + *buf++=0; // change &'s into 0s now. + char *t=buf; + int stat=1; + while (*t) + { + if (*t == '&' && !stat) { stat=1; *t=0; } + else stat=0; + t++; + } + } + } + } + else if (!cnt++) goto run_again; + } + if (m_state == 1) + { + if (!cnt++ && m_con->recv_lines_available()<1) goto run_again; + while (m_con->recv_lines_available()>0) + { + char buf[4096]; + buf[0]=0; + m_con->recv_line(buf,4096); + if (!buf[0]) { m_state=2; break; } + + if (!strnicmp(buf,"Connection:",11)) + { + const char *p=buf+11; + while (*p && strnicmp(p,"close",5)) p++; + if (*p) m_keepalive=false; + } + + if (!m_recvheaders) + { + m_recvheaders_size=strlen(buf)+1; + m_recvheaders=(char*)malloc(m_recvheaders_size+1); + if (m_recvheaders) + { + strcpy(m_recvheaders,buf); + m_recvheaders[m_recvheaders_size]=0; + } + } + else + { + int oldsize=m_recvheaders_size; + m_recvheaders_size+=strlen(buf)+1; + char *n=(char*)malloc(m_recvheaders_size+1); + if (n) + { + memcpy(n,m_recvheaders,oldsize); + strcpy(n+oldsize,buf); + n[m_recvheaders_size]=0; + free(m_recvheaders); + m_recvheaders=n; + } + } + } + } + if (m_state == 2) + { + if (m_reply_ready) + { + // send reply + m_con->send_string((char*)(m_reply_string?m_reply_string:"HTTP/1.1 200 OK")); + m_con->send_string("\r\n"); + if (m_reply_headers) m_con->send_string(m_reply_headers); + m_con->send_string("\r\n"); + m_state=3; + } + } + if (m_state == 3) + { + // nothing. + } + + return m_state; +} + +const char *JNL_HTTPServ::get_request_file() +{ + // file portion of http request + if (!m_recv_request) return NULL; + char *t=m_recv_request; + while (*t != ' ' && *t) t++; + if (!*t) return NULL; + while (*t == ' ') t++; + return t; +} + +const char *JNL_HTTPServ::get_request_parm(const char *parmname) // parameter portion (after ?) +{ + const char *t=m_recv_request; + while (*t) t++; + t++; + while (*t) + { + while (*t == '&') t++; + if (!strnicmp(t,parmname,strlen(parmname)) && t[strlen(parmname)] == '=') + { + return t+strlen(parmname)+1; + } + t+=strlen(t)+1; + } + return NULL; +} + +const char *JNL_HTTPServ::getheader(const char *headername) +{ + const char *ret=NULL; + if (strlen(headername)<1||!m_recvheaders) return NULL; + char *buf=(char*)malloc(strlen(headername)+2); + strcpy(buf,headername); + if (buf[strlen(buf)-1]!=':') strcat(buf,":"); + const char *p=m_recvheaders; + while (*p) + { + if (!strnicmp(buf,p,strlen(buf))) + { + ret=p+strlen(buf); + while (*ret == ' ') ret++; + break; + } + p+=strlen(p)+1; + } + free(buf); + return ret; +} + +void JNL_HTTPServ::set_reply_string(const char *reply_string) // should be HTTP/1.1 OK or the like +{ + free(m_reply_string); + m_reply_string=(char*)malloc(strlen(reply_string)+1); + strcpy(m_reply_string,reply_string); +} + +void JNL_HTTPServ::set_reply_size(int sz) // if set, size will also add keep-alive etc +{ + if (sz>=0) + { + char buf[512]; + sprintf(buf,"Content-length: %d",sz); + set_reply_header(buf); + if (m_keepalive) set_reply_header("Connection: keep-alive"); + } +} +void JNL_HTTPServ::set_reply_header(const char *header) // "Connection: close" for example +{ + if (m_reply_headers) + { + char *tmp=(char*)malloc(strlen(m_reply_headers)+strlen(header)+3); + strcpy(tmp,m_reply_headers); + strcat(tmp,header); + strcat(tmp,"\r\n"); + free(m_reply_headers); + m_reply_headers=tmp; + } + else + { + m_reply_headers=(char*)malloc(strlen(header)+3); + strcpy(m_reply_headers,header); + strcat(m_reply_headers,"\r\n"); + } +} diff --git a/WDL/jnetlib/httpserv.h b/WDL/jnetlib/httpserv.h new file mode 100644 index 00000000..bd433696 --- /dev/null +++ b/WDL/jnetlib/httpserv.h @@ -0,0 +1,114 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: httpserv.h - JNL interface for doing HTTP GET/POST serving. +** License: see jnetlib.h +** This class just manages the http reply/sending, not where the data +** comes from, etc. +** for a mini-web server see webserver.h +*/ + +#ifndef _HTTPSERV_H_ +#define _HTTPSERV_H_ + +#include "connection.h" + +#ifndef JNL_NO_DEFINE_INTERFACES +class JNL_IHTTPServ +{ + public: + + virtual ~JNL_IHTTPServ() { } + + virtual int run()=0; // returns: < 0 on error, 0 on request not read yet, 1 if reading headers, 2 if reply not sent, 3 if reply sent, sending data. 4 on connection closed. + + virtual const char *geterrorstr()=0; + + // use these when state returned by run() is 2 + virtual const char *get_request_file()=0; // file portion of http request + virtual const char *get_request_parm(const char *parmname)=0; // parameter portion (after ?) + virtual const char *getallheaders()=0; + virtual const char *getheader(const char *headername)=0; + + virtual void set_reply_string(const char *reply_string)=0; // should be HTTP/1.1 OK or the like + virtual void set_reply_header(const char *header)=0; // i.e. "content-size: 12345" + virtual void set_reply_size(int sz)=0; // if set, size will also add keep-alive etc + + virtual void send_reply()=0; + + ////////// sending data /////////////// + virtual int bytes_inqueue()=0; + virtual int bytes_cansend()=0; + virtual void write_bytes(char *bytes, int length)=0; + + virtual void close(int quick)=0; + + virtual JNL_IConnection *get_con()=0; + virtual JNL_IConnection *steal_con()=0; + + virtual bool canKeepAlive()=0; +}; + #define JNL_HTTPServ_PARENTDEF : public JNL_IHTTPServ +#else + #define JNL_IHTTPServ JNL_HTTPServ + #define JNL_HTTPServ_PARENTDEF +#endif + + +#ifndef JNL_NO_IMPLEMENTATION + +class JNL_HTTPServ JNL_HTTPServ_PARENTDEF +{ + public: + JNL_HTTPServ(JNL_IConnection *con); + ~JNL_HTTPServ(); + + int run(); // returns: < 0 on error, 0 on request not read yet, 1 if reading headers, 2 if reply not sent, 3 if reply sent, sending data. 4 on connection closed. + + const char *geterrorstr() { return m_errstr;} + + // use these when state returned by run() is 2 + const char *get_request_file(); // file portion of http request + const char *get_request_parm(const char *parmname); // parameter portion (after ?) + const char *getallheaders() { return m_recvheaders; } // double null terminated, null delimited list + const char *getheader(const char *headername); + + void set_reply_string(const char *reply_string); // should be HTTP/1.1 OK or the like + void set_reply_header(const char *header); // i.e. "content-size: 12345" + void set_reply_size(int sz); // if set, size will also add keep-alive etc + + void send_reply() { m_reply_ready=1; } // send reply, state will advance to 3. + + ////////// sending data /////////////// + int bytes_inqueue() { if (m_state == 3 || m_state == -1 || m_state ==4) return m_con->send_bytes_in_queue(); else return 0; } + int bytes_cansend() { if (m_state == 3) return m_con->send_bytes_available(); else return 0; } + void write_bytes(char *bytes, int length) { m_con->send(bytes,length); } + + void close(int quick) { m_con->close(quick); m_state=4; } + + JNL_IConnection *get_con() { return m_con; } + JNL_IConnection *steal_con() { JNL_IConnection *ret= m_con; m_con=0; return ret; } + + bool canKeepAlive() { return m_keepalive; } + + protected: + void seterrstr(const char *str) { if (m_errstr) free(m_errstr); m_errstr=(char*)malloc(strlen(str)+1); strcpy(m_errstr,str); } + + int m_reply_ready; + int m_state; + bool m_keepalive; + + char *m_errstr; + char *m_reply_headers; + char *m_reply_string; + char *m_recvheaders; + int m_recvheaders_size; + char *m_recv_request; // either double-null terminated, or may contain parameters after first null. + JNL_IConnection *m_con; +}; + +#endif + +#endif // _HTTPSERV_H_ diff --git a/WDL/jnetlib/irc_util.h b/WDL/jnetlib/irc_util.h new file mode 100644 index 00000000..4b85fc94 --- /dev/null +++ b/WDL/jnetlib/irc_util.h @@ -0,0 +1,59 @@ +#ifndef _WDL_JNL_IRC_UTIL_H_ +#define _WDL_JNL_IRC_UTIL_H_ + +#include "netinc.h" + +static void FormatIRCMessage(char *bufout, const char *fmt, ...) // bufout should be 1024 bytes to be safe +{ + va_list arglist; + va_start(arglist, fmt); + #ifdef _WIN32 + int written = _vsnprintf(bufout, 1024-16, fmt, arglist); + #else + int written = vsnprintf(bufout, 1024-16, fmt, arglist); + #endif + if (written < 0) written = 0; + else if (written > 510) written=510; + bufout[written]=0; + va_end(arglist); + + strcat(bufout,"\r\n"); +} + + +static void ParseIRCMessage(char *buf, char **prefix, char *tokens[16], int *tokensvalid, bool *lastHadColon) // destroys buf +{ + if (lastHadColon) *lastHadColon=false; + *tokensvalid=0; + if (prefix) *prefix=NULL; + if (*buf==':') + { + if (prefix) *prefix=buf; + while (*buf && *buf != ' ') buf++; + if (*buf==' ') + { + *buf++=0; + while (*buf== ' ') buf++; + } + } + + while (*buf && *tokensvalid < 16) + { + tokens[(*tokensvalid)++] = buf[0] == ':' ? buf+1 : buf; + if (buf[0] == ':' || *tokensvalid == 16) + { + if (buf[0] == ':' && lastHadColon) *lastHadColon=true; + break; + } + + // skip over parameter + while (*buf && *buf != ' ') buf++; + if (*buf == ' ') + { + *buf++=0; + while (*buf== ' ') buf++; + } + + } +} +#endif \ No newline at end of file diff --git a/WDL/jnetlib/jnetlib.h b/WDL/jnetlib/jnetlib.h new file mode 100644 index 00000000..e4c73a08 --- /dev/null +++ b/WDL/jnetlib/jnetlib.h @@ -0,0 +1,47 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2003 Nullsoft, Inc. +** Author: Justin Frankel +** File: jnetlib.h - JNL main include file (not really necessary). +** +** For documentation, look at the following files: +** Generic network initialization: netinc.h +** DNS: asyncdns.h +** TCP connections: connection.h +** HTTP GET connections: httpget.h +** TCP listen: listen.h +** +** license: +** +** This software is provided 'as-is', without any express or implied +** warranty. In no event will the authors be held liable for any damages +** arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, +** including commercial applications, and to alter it and redistribute it +** freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not +** claim that you wrote the original software. If you use this software +** in a product, an acknowledgment in the product documentation would be +** appreciated but is not required. +** 2. Altered source versions must be plainly marked as such, and must not be +** misrepresented as being the original software. +** 3. This notice may not be removed or altered from any source distribution. +** +*/ + +#ifndef _JNETLIB_H_ +#define _JNETLIB_H_ + +#include "netinc.h" +#include "util.h" + +#include "asyncdns.h" +#include "connection.h" +#include "httpget.h" +#include "httpserv.h" +#include "listen.h" + +#endif//_JNETLIB_H_ diff --git a/WDL/jnetlib/listen.cpp b/WDL/jnetlib/listen.cpp new file mode 100644 index 00000000..e7578e19 --- /dev/null +++ b/WDL/jnetlib/listen.cpp @@ -0,0 +1,73 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: listen.cpp - JNL TCP listen implementation +** License: see jnetlib.h +*/ + +#include "netinc.h" +#include "util.h" +#include "listen.h" + +JNL_Listen::JNL_Listen(short port, unsigned int which_interface) +{ + m_port=port; + m_socket = ::socket(AF_INET,SOCK_STREAM,0); + if (m_socket < 0) + { + } + else + { + struct sockaddr_in sin; + SET_SOCK_BLOCK(m_socket,0); +#ifndef _WIN32 + int bflag = 1; + setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag)); +#endif + memset((char *) &sin, 0,sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons( (short) port ); + sin.sin_addr.s_addr = which_interface?which_interface:INADDR_ANY; + if (::bind(m_socket,(struct sockaddr *)&sin,sizeof(sin))) + { + closesocket(m_socket); + m_socket=-1; + } + else + { + if (::listen(m_socket,8)==-1) + { + closesocket(m_socket); + m_socket=-1; + } + } + } +} + +JNL_Listen::~JNL_Listen() +{ + if (m_socket>=0) + { + closesocket(m_socket); + } +} + +JNL_IConnection *JNL_Listen::get_connect(int sendbufsize, int recvbufsize) +{ + if (m_socket < 0) + { + return NULL; + } + struct sockaddr_in saddr; + socklen_t length = sizeof(struct sockaddr_in); + int s = accept(m_socket, (struct sockaddr *) &saddr, &length); + if (s != -1) + { + JNL_IConnection *c=new JNL_Connection(NULL,sendbufsize, recvbufsize); + c->connect(s,&saddr); + return c; + } + return NULL; +} diff --git a/WDL/jnetlib/listen.h b/WDL/jnetlib/listen.h new file mode 100644 index 00000000..d51edc66 --- /dev/null +++ b/WDL/jnetlib/listen.h @@ -0,0 +1,62 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: listen.h - JNL interface for opening a TCP listen +** License: see jnetlib.h +** +** Usage: +** 1. create a JNL_Listen object with the port and (optionally) the interface +** to listen on. +** 2. call get_connect() to get any new connections (optionally specifying what +** buffer sizes the connection should be created with) +** 3. check is_error() to see if an error has occured +** 4. call port() if you forget what port the listener is on. +** +*/ + +#ifndef _LISTEN_H_ +#define _LISTEN_H_ +#include "connection.h" + +#ifndef JNL_NO_DEFINE_INTERFACES + + class JNL_IListen + { + public: + + virtual ~JNL_IListen() { } + + virtual JNL_IConnection *get_connect(int sendbufsize=8192, int recvbufsize=8192)=0; + virtual short port(void)=0; + virtual int is_error(void)=0; + }; + + #define JNL_Listen_PARENTDEF : public JNL_IListen +#else + #define JNL_IListen JNL_Listen + #define JNL_Listen_PARENTDEF +#endif + +#ifndef JNL_NO_IMPLEMENTATION + + +class JNL_Listen JNL_Listen_PARENTDEF +{ + public: + JNL_Listen(short port, unsigned int which_interface=0); + ~JNL_Listen(); + + JNL_IConnection *get_connect(int sendbufsize=8192, int recvbufsize=8192); + short port(void) { return m_port; } + int is_error(void) { return (m_socket<0); } + + protected: + int m_socket; + short m_port; +}; + +#endif + +#endif //_LISTEN_H_ diff --git a/WDL/jnetlib/netinc.h b/WDL/jnetlib/netinc.h new file mode 100644 index 00000000..6bb94986 --- /dev/null +++ b/WDL/jnetlib/netinc.h @@ -0,0 +1,75 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: netinc.h - network includes and portability defines (used internally) +** License: see jnetlib.h +*/ + +#ifndef _NETINC_H_ +#define _NETINC_H_ + +#ifdef _WIN32 + +#include +#include +#include +#define strcasecmp(x,y) stricmp(x,y) +#define ERRNO (WSAGetLastError()) +#define SET_SOCK_BLOCK(s,block) { unsigned long __i=block?0:1; ioctlsocket(s,FIONBIO,&__i); } +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEWOULDBLOCK +typedef int socklen_t; + +#else + +#ifndef THREAD_SAFE +#define THREAD_SAFE +#endif +#ifndef _REENTRANT +#define _REENTRANT +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ERRNO errno +#define closesocket(s) close(s) +#define SET_SOCK_BLOCK(s,block) { int __flags; if ((__flags = fcntl(s, F_GETFL, 0)) != -1) { if (!block) __flags |= O_NONBLOCK; else __flags &= ~O_NONBLOCK; fcntl(s, F_SETFL, __flags); } } + +#define stricmp(x,y) strcasecmp(x,y) +#define strnicmp(x,y,z) strncasecmp(x,y,z) +#define wsprintf sprintf + +#ifdef MACOSX +typedef int socklen_t; +#endif + +#endif // !_WIN32 + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +#ifndef INADDR_ANY +#define INADDR_ANY 0 +#endif + +#ifndef SHUT_RDWR +#define SHUT_RDWR 2 +#endif + +#endif //_NETINC_H_ diff --git a/WDL/jnetlib/test.cpp b/WDL/jnetlib/test.cpp new file mode 100644 index 00000000..0d24f78b --- /dev/null +++ b/WDL/jnetlib/test.cpp @@ -0,0 +1,555 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: test.cpp - JNL test code +** License: see jnetlib.h +*/ + +#ifdef _WIN32 +#include +#else +#define Sleep(x) usleep((x)*1000) +#endif +#include +#include "jnetlib.h" + + +#define TEST_ASYNCDNS 0 +#define TEST_CONNECTION 0 +#define TEST_LISTEN 0 +#define TEST_TELNET_GATEWAY 0 +#define TEST_HTTPGET 0 +#define TEST_WEBSERVER 1 + +#define TEST_UDP 0 //udp is not done yet tho :) + + + +#if (TEST_WEBSERVER) +#include "webserver.h" + + +class MemPageGenerator : public IPageGenerator +{ + public: + virtual ~MemPageGenerator() { free(m_buf); } + MemPageGenerator(char *buf, int buf_len=-1) { m_buf=buf; if (buf_len >= 0) m_buf_size=buf_len; else m_buf_size=strlen(buf); m_buf_pos=0; } + virtual int GetData(char *buf, int size) // return 0 when done + { + int a=m_buf_size-m_buf_pos; + if (a < size) size=a; + memcpy(buf,m_buf+m_buf_pos,size); + m_buf_pos+=size; + return size; + } + + private: + char *m_buf; + int m_buf_size; + int m_buf_pos; +}; + +class wwwServer : public WebServerBaseClass +{ +public: + wwwServer() { } + virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port) + { + serv->set_reply_header("Server:jnetlib_test/0.0"); + if (!strcmp(serv->get_request_file(),"/")) + { + serv->set_reply_string("HTTP/1.1 200 OK"); + serv->set_reply_header("Content-Type:text/html"); + serv->send_reply(); + + return new MemPageGenerator(strdup("Test Web Server v0.0")); + } + else + { + serv->set_reply_string("HTTP/1.1 404 NOT FOUND"); + serv->send_reply(); + return 0; // no data + } + } +}; + + +int main(int argc, char **argv) +{ + JNL::open_socketlib(); + { + wwwServer foo; + foo.addListenPort(8080); + while (1) + { + foo.run(); + Sleep(10); + } + } + JNL::close_socketlib(); + return 0; +} + +#endif + + +#if (TEST_HTTPGET) +int main(int argc, char **argv) +{ + + if (argc != 3) + { + printf("usage: httpget \n"); + exit(0); + } + + JNL_HTTPGet get; + JNL::open_socketlib(); + + get.addheader("User-Agent:PooHead (Mozilla)"); + get.addheader("Accept:*/*"); + get.connect(argv[1]); + + FILE *fp=fopen(argv[2],"wb"); + int headerstate=0; + int has_printed_headers=0; + int has_printed_reply=0; + while (1) + { + int st=get.run(); + if (st<0) + { + printf("HTTPGet error: %s\n",get.geterrorstr()); + break; + } + if (get.get_status()>0) + { + if (!has_printed_reply) + { + has_printed_reply=1; + printf("reply: %s (code:%d)\n",get.getreply(),get.getreplycode()); + } + if (get.get_status()==2) + { + int len; + if (!has_printed_headers) + { + has_printed_headers=1; + printf("headers:\n"); + char *p=get.getallheaders(); + while (p&&*p) + { + printf("%s\n",p); + p+=strlen(p)+1; + } + } + while ((len=get.bytes_available()) > 0) + { + char buf[4096]; + if (len > 4096) len=4096; + len=get.get_bytes(buf,len); + if (len>0)fwrite(buf,len,1,fp); + } + } + } + if (st==1) // 1 means connection closed + { + printf("HTTPGet done!\n"); + break; + } + } + if (fp) fclose(fp); + JNL::close_socketlib(); + return 0; +} + +#endif + + +#if (TEST_TELNET_GATEWAY) + +int main() +{ + JNL_Connection *cons[32]={0,}; + JNL_Connection *outcons[32]={0,}; + char textpos[32][256]; + int n_cons=0; + int states[32]={0,}; + + JNL::open_socketlib(); + JNL_AsyncDNS dns; + JNL_Listen l(23); + while (!l.is_error()) + { + Sleep(30); + if (n_cons<32) + { + JNL_Connection *con=l.get_connect(); + if (con) + { + int x; + for (x = 0; x < 32; x ++) + { + if (!cons[x]) + { + cons[x]=con; + outcons[x]=0; + states[x]=0; + n_cons++; + break; + } + } + } + } + int x; + for (x = 0; x < 32; x ++) + { + if (cons[x]) + { + cons[x]->run(); + if (outcons[x]) outcons[x]->run(); + + if (cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED || + (outcons[x] && (cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED))) + { + delete cons[x]; + if (outcons[x]) delete outcons[x]; + outcons[x]=0; + cons[x]=0; + states[x]=0; + n_cons--; + } + else + { + if (states[x]==0) + { + cons[x]->send_string("\r\nwelcome "); + states[x]++; + } + if (states[x]==1) + { + char hoststr[256]; + int ret=dns.reverse(cons[x]->get_remote(),hoststr); + if (ret==0) + { + cons[x]->send_string(hoststr); + cons[x]->send_string(". host: "); + states[x]++; + textpos[x][0]=0; + } + if (ret==-1) + { + JNL::addr_to_ipstr(cons[x]->get_remote(),hoststr,256); + cons[x]->send_string(hoststr); + cons[x]->send_string(". host: "); + states[x]++; + textpos[x][0]=0; + } + } + if (states[x]==2) + { + char b; + while (cons[x]->recv_bytes(&b,1) && states[x]==2) + { + if (b == '\r' || b == '\n') + { + if (strlen(textpos[x])) + { + char *p=strstr(textpos[x],":"); + int port=23; + if (p) + { + *p++=0; + if (atoi(p)) port=atoi(p); + } + outcons[x]=new JNL_Connection(&dns); + outcons[x]->connect(textpos[x],port); + + char str[512]; + sprintf(str,"\r\nconnecting to port %d of %s\r\n",port,textpos[x]); + cons[x]->send_string(str); + states[x]++; + } + else states[x]=0; + } + else if (b == '\b') + { + if (textpos[x][0]) + { + textpos[x][strlen(textpos[x])-1]=0; + cons[x]->send_string("\b \b"); + } + } + else + { + textpos[x][strlen(textpos[x])+1]=0; + textpos[x][strlen(textpos[x])]=b; + cons[x]->send(&b,1); + } + } + } + if (states[x]==3) + { + char buf[1024]; + outcons[x]->run(); + int l=cons[x]->recv_bytes(buf,1024); + if (l) outcons[x]->send(buf,l); + l=outcons[x]->recv_bytes(buf,1024); + if (l) cons[x]->send(buf,l); + } + } + } + } + } + JNL::close_socketlib(); + return 0; +} + + +#endif + +#if (TEST_LISTEN) + +int main() +{ + JNL_HTTPServ *cons[32]={0,}; + char *contents[32]={0,}; + int n_cons=0; + + JNL::open_socketlib(); + JNL_AsyncDNS dns; + JNL_Listen l(8000); + while (!l.is_error()) + { + Sleep(100); + if (n_cons<32) + { + JNL_Connection *con=l.get_connect(); + if (con) + { + int x; + for (x = 0; x < 32; x ++) + { + if (!cons[x]) + { + cons[x]=new JNL_HTTPServ(con); + n_cons++; + break; + } + } + } + } + int x; + for (x = 0; x < 32; x ++) + { + if (cons[x]) + { + int r=cons[x]->run(); + if (r == -1 || r == 4) + { + if (r == -1) printf("error:%s\n",cons[x]->geterrorstr()); + delete cons[x]; + cons[x]=0; + free(contents[x]); + contents[x]=0; + n_cons--; + } + if (r == 2) + { + cons[x]->set_reply_string("HTTP/1.1 200 OK"); + cons[x]->set_reply_header("Content-type:text/plain"); + cons[x]->set_reply_header("Server:JNLTest"); + contents[x]=(char*)malloc(32768); + char *poop=cons[x]->get_request_parm("poop"); + sprintf(contents[x],"test, sucka\r\n%s\r\n\r\n",poop?poop:"no poop"); + cons[x]->send_reply(); + } + if (r == 3) + { + if (contents[x] && cons[x]->bytes_cansend()>strlen(contents[x])) + { + cons[x]->write_bytes(contents[x],strlen(contents[x])); + cons[x]->close(0); + free(contents[x]); + contents[x]=0; + } + } + } + } + } + JNL::close_socketlib(); + return 0; +} + +#endif + +#if (TEST_CONNECTION) +int main() +{ + JNL::open_socketlib(); + { + JNL_AsyncDNS dns; + JNL_Connection con(&dns); + con.connect("localhost",80); + FILE *fp=fopen("c:\\hi.raw","wb"); + while (1) + { + con.run(); + if (con.get_state()==JNL_Connection::STATE_ERROR) + { + printf("error %s\n",con.get_errstr()); + } + if (con.get_state()==JNL_Connection::STATE_CLOSED) + { + } + while (con.recv_bytes_available()>0) + { + char buf[1024]; + int a=con.recv_bytes_available(); + if (a > 1024) a=1024; + con.recv_bytes(buf,a); + fwrite(buf,a,1,fp); + } + } + if (fp) fclose(fp); + } + JNL::close_socketlib(); + return 0; +} +#endif + +#if (TEST_ASYNCDNS) +int main() +{ + JNL_AsyncDNS dns; + char *hosts[]= + { + "www.firehose.net", + "gnutella.com", + "207.48.52.200", + "www.slashdot.org", + "www.google.com", + "www.winamp.com", + "www.genekan.com", + }; + char *reverses[]= + { + "64.0.160.98", + "205.188.245.120", + "207.48.52.222", + "207.48.52.200", + }; + int n=0; + int pass=0; + while (n\n"); + printf("mode: 0 for client, 1 for server\n"); + exit(0); + } + int mode=atoi(argv[1]); + + JNL::open_socketlib(); + + switch(mode) + { + case 0: // client mode + { + JNL_AsyncDNS dns; + JNL_UDPConnection con(0,&dns); // 0 chooses a random port + con.setpeer("localhost",80); + printf("Sending message...\n"); + con.send("blah",5); + while (1) + { + con.run(); + if (con.get_state()==JNL_UDPConnection::STATE_ERROR) + { + printf("error %s\n",con.get_errstr()); + } + while (con.recv_bytes_available()>0) + { + char buf[1024]; + int s=min(con.recv_bytes_available(), sizeof(buf)); + con.recv_bytes(buf,s); + printf("received message: %s\n", buf); + } + } + } + break; + case 1: // server (listening) mode + { + JNL_UDPConnection con(80); + printf("Waiting for messages...\n"); + while(1) + { + con.run(); + if (con.get_state()==JNL_UDPConnection::STATE_ERROR) + { + printf("error %s\n",con.get_errstr()); + } + while (con.recv_bytes_available()>0) + { + char buf[1024]; + int s=min(con.recv_bytes_available(), sizeof(buf)); + con.recv_bytes(buf,s); + printf("message received: %s. Replying...\n", buf); + // reply on the addr:port from sender + struct sockaddr from; + con.get_last_recv_msg_addr(&from); + con.setpeer(&from); + con.send("blorp",6); + } + } + } + break; + } + + JNL::close_socketlib(); + return 0; +} +#endif diff --git a/WDL/jnetlib/test.dsp b/WDL/jnetlib/test.dsp new file mode 100644 index 00000000..36f90a7c --- /dev/null +++ b/WDL/jnetlib/test.dsp @@ -0,0 +1,166 @@ +# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=test - 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 "test.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 "test.mak" CFG="test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName ""$/jnetlib", NTGAAAAA" +# PROP Scc_LocalPath "." +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "test - Win32 Release" +# Name "test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\asyncdns.cpp +# End Source File +# Begin Source File + +SOURCE=.\connection.cpp +# End Source File +# Begin Source File + +SOURCE=.\httpget.cpp +# End Source File +# Begin Source File + +SOURCE=.\httpserv.cpp +# End Source File +# Begin Source File + +SOURCE=.\listen.cpp +# End Source File +# Begin Source File + +SOURCE=.\test.cpp +# End Source File +# Begin Source File + +SOURCE=.\util.cpp +# End Source File +# Begin Source File + +SOURCE=.\webserver.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\asyncdns.h +# End Source File +# Begin Source File + +SOURCE=.\connection.h +# End Source File +# Begin Source File + +SOURCE=.\httpget.h +# End Source File +# Begin Source File + +SOURCE=.\httpserv.h +# End Source File +# Begin Source File + +SOURCE=.\jnetlib.h +# End Source File +# Begin Source File + +SOURCE=.\listen.h +# End Source File +# Begin Source File + +SOURCE=.\netinc.h +# End Source File +# Begin Source File + +SOURCE=.\util.h +# End Source File +# Begin Source File + +SOURCE=.\webserver.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/WDL/jnetlib/test.dsw b/WDL/jnetlib/test.dsw new file mode 100644 index 00000000..e25096d1 --- /dev/null +++ b/WDL/jnetlib/test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "test"=.\test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/WDL/jnetlib/testbnc.cpp b/WDL/jnetlib/testbnc.cpp new file mode 100644 index 00000000..5c3bca20 --- /dev/null +++ b/WDL/jnetlib/testbnc.cpp @@ -0,0 +1,102 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: testbnc.cpp - JNL network bounce test code +** License: see jnetlib.h +*/ + +#ifdef _WIN32 +#include +#else +#define Sleep(x) usleep((x)*1000) +#endif +#include +#include "jnetlib.h" + + +int main(int argc, char *argv[]) +{ + JNL_Connection *cons[32]={0,}; + JNL_Connection *outcons[32]={0,}; + int n_cons=0; + + if (argc != 4 || !atoi(argv[1]) || !atoi(argv[3]) || !argv[2][0]) + { + printf("usage: redir localport host remoteport\n"); + exit(1); + } + + JNL::open_socketlib(); + JNL_AsyncDNS dns; + JNL_Listen l((short)atoi(argv[1])); + printf("running...\n"); + while (!l.is_error()) + { + Sleep(10); + if (n_cons<32) + { + JNL_Connection *con=l.get_connect(); + if (con) + { + int x; + for (x = 0; x < 32; x ++) + { + if (!cons[x]) + { + outcons[x]=new JNL_Connection(); + outcons[x]->connect(argv[2],atoi(argv[3])); + cons[x]=con; + char host[256]; + JNL::addr_to_ipstr(cons[x]->get_remote(),host,sizeof(host)); + n_cons++; + printf("Connection %d (%s) opened (%d).\n",x,host,n_cons); + break; + } + } + } + } + int x; + for (x = 0; x < 32; x ++) + { + if (cons[x]) + { + cons[x]->run(); + outcons[x]->run(); + + int cerr=(cons[x]->get_state() == JNL_Connection::STATE_ERROR || cons[x]->get_state()==JNL_Connection::STATE_CLOSED); + int oerr=(outcons[x]->get_state() == JNL_Connection::STATE_ERROR || outcons[x]->get_state()==JNL_Connection::STATE_CLOSED); + + if ((!outcons[x]->send_bytes_in_queue() && !cons[x]->recv_bytes_available() && cerr) || + (!cons[x]->send_bytes_in_queue() && !outcons[x]->recv_bytes_available() && oerr) || + (cerr && oerr)) + { + char host[256]; + JNL::addr_to_ipstr(cons[x]->get_remote(),host,sizeof(host)); + delete cons[x]; + delete outcons[x]; + outcons[x]=0; + cons[x]=0; + n_cons--; + printf("Connection %d (%s) closed (%d)\n",x,host,n_cons); + } + else + { + char buf[4096]; + int l; + l=outcons[x]->send_bytes_available(); + if (l > 4096) l=4096; + if (l) l=cons[x]->recv_bytes(buf,l); + if (l) outcons[x]->send(buf,l); + + l=cons[x]->send_bytes_available(); + if (l > 4096) l=4096; + if (l) l=outcons[x]->recv_bytes(buf,l); + if (l) cons[x]->send(buf,l); + } + } + } + } + JNL::close_socketlib(); + return 0; +} diff --git a/WDL/jnetlib/util.cpp b/WDL/jnetlib/util.cpp new file mode 100644 index 00000000..c97a2869 --- /dev/null +++ b/WDL/jnetlib/util.cpp @@ -0,0 +1,36 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: util.cpp - JNL implementation of basic network utilities +** License: see jnetlib.h +*/ + +#include "netinc.h" + +#include "util.h" + +int JNL::open_socketlib() +{ +#ifdef _WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return 1; +#endif + return 0; +} +void JNL::close_socketlib() +{ +#ifdef _WIN32 + WSACleanup(); +#endif +} +unsigned int JNL::ipstr_to_addr(const char *cp) +{ + return ::inet_addr(cp); +} + +void JNL::addr_to_ipstr(unsigned int addr, char *host, int maxhostlen) +{ + struct in_addr a; a.s_addr=addr; + char *p=::inet_ntoa(a); strncpy(host,p?p:"",maxhostlen); +} diff --git a/WDL/jnetlib/util.h b/WDL/jnetlib/util.h new file mode 100644 index 00000000..7179ddc9 --- /dev/null +++ b/WDL/jnetlib/util.h @@ -0,0 +1,39 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: util.h - JNL interface for basic network utilities +** License: see jnetlib.h +** +** routines you may be interested in: +** JNL::open_socketlib(); +** opens the socket library. Call this once before using any network +** code. If you create a new thread, call this again. Only really an +** issue for Win32 support, but use it anyway for portability/ +** +** JNL::close_Socketlib(); +** closes the socketlib. Call this when you're done with the network, +** after all your JNetLib objects have been destroyed. +** +** unsigned int JNL::ipstr_to_addr(const char *cp); +** gives you the integer representation of a ip address in dotted +** decimal form. +** +** JNL::addr_to_ipstr(unsigned int addr, char *host, int maxhostlen); +** gives you the dotted decimal notation of an integer ip address. +** +*/ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +class JNL +{ + public: + static int open_socketlib(); + static void close_socketlib(); + static unsigned int ipstr_to_addr(const char *cp); + static void addr_to_ipstr(unsigned int addr, char *host, int maxhostlen); +}; + +#endif //_UTIL_H_ diff --git a/WDL/jnetlib/webserver.cpp b/WDL/jnetlib/webserver.cpp new file mode 100644 index 00000000..6037db31 --- /dev/null +++ b/WDL/jnetlib/webserver.cpp @@ -0,0 +1,398 @@ +/* +** JNetLib +** Copyright (C) 2000-2003 Nullsoft, Inc. +** Author: Justin Frankel +** File: webserver.cpp - Generic simple webserver baseclass +** License: see jnetlib.h +** see test.cpp for an example of how to use this class +*/ + +#ifdef _WIN32 +#include +#endif +#include "jnetlib.h" +#include "webserver.h" + +class WS_ItemList +{ + public: + WS_ItemList() { m_size=0; m_list=0; } + ~WS_ItemList() { ::free(m_list); } + + void *Add(void *i); + void *Get(int w); + void Del(int idx); + int GetSize(void) { return m_size; } + protected: + void **m_list; + int m_size; +}; + +class WS_conInst +{ +public: + WS_conInst(JNL_IConnection *c, int which_port); + ~WS_conInst(); + + // these will be used by WebServerBaseClass::onConnection yay + JNL_HTTPServ m_serv; + IPageGenerator *m_pagegen; + + + int m_port; // port this came in on + time_t m_connect_time; +}; + + + +void *WS_ItemList::Add(void *i) +{ + if (!m_list || !(m_size&31)) + { + m_list=(void**)::realloc(m_list,sizeof(void*)*(m_size+32)); + } + m_list[m_size++]=i; + return i; +} +void *WS_ItemList::Get(int w) { if (w >= 0 && w < m_size) return m_list[w]; return NULL; } + +void WS_ItemList::Del(int idx) +{ + if (m_list && idx >= 0 && idx < m_size) + { + m_size--; + if (idx != m_size) ::memcpy(m_list+idx,m_list+idx+1,sizeof(void *)*(m_size-idx)); + if (!(m_size&31)&&m_size) // resize down + { + m_list=(void**)::realloc(m_list,sizeof(void*)*m_size); + } + } +} + + +WS_conInst::WS_conInst(JNL_IConnection *c, int which_port) : m_serv(c), m_port(which_port) +{ + m_pagegen=0; + time(&m_connect_time); +} + +WS_conInst::~WS_conInst() +{ + delete m_pagegen; +} + +WebServerBaseClass::~WebServerBaseClass() +{ + int x; + for (x = 0; x < m_connections->GetSize(); x ++) + { + delete (WS_conInst *)m_connections->Get(x); + } + delete m_connections; + for (x = 0; x < m_listeners->GetSize(); x ++) + { + delete (JNL_Listen *)m_listeners->Get(x); + } + delete m_listeners; +} + +WebServerBaseClass::WebServerBaseClass() +{ + m_connections=new WS_ItemList; + m_listeners=new WS_ItemList; + m_listener_rot=0; + m_timeout_s=30; + m_max_con=100; +} + + +void WebServerBaseClass::setMaxConnections(int max_con) +{ + m_max_con=max_con; +} + +void WebServerBaseClass::setRequestTimeout(int timeout_s) +{ + m_timeout_s=timeout_s; +} + +int WebServerBaseClass::addListenPort(int port, unsigned int which_interface) +{ + removeListenPort(port); + + JNL_Listen *p=new JNL_Listen(port,which_interface); + m_listeners->Add((void *)p); + if (p->is_error()) return -1; + return 0; +} + +void WebServerBaseClass::removeListenPort(int port) +{ + int x; + for (x = 0; x < m_listeners->GetSize(); x ++) + { + JNL_Listen *p=(JNL_Listen *)m_listeners->Get(x); + if (p->port()==port) + { + delete p; + m_listeners->Del(x); + break; + } + } +} + +void WebServerBaseClass::removeListenIdx(int idx) +{ + if (idx >= 0 && idx < m_listeners->GetSize()) + { + JNL_Listen *p=(JNL_Listen *)m_listeners->Get(idx); + delete p; + m_listeners->Del(idx); + } +} + +int WebServerBaseClass::getListenPort(int idx, int *err) +{ + JNL_Listen *p=(JNL_Listen *)m_listeners->Get(idx); + if (p) + { + if (err) *err=p->is_error(); + return p->port(); + } + return 0; +} + +void WebServerBaseClass::attachConnection(JNL_IConnection *con, int port) +{ + m_connections->Add((void*)new WS_conInst(con,port)); +} + +void WebServerBaseClass::run(void) +{ + int nl; + if (m_connections->GetSize() < m_max_con && (nl=m_listeners->GetSize())) + { + JNL_Listen *l=(JNL_Listen *)m_listeners->Get(m_listener_rot++ % nl); + JNL_IConnection *c=l->get_connect(); + if (c) + { +// char buf[512]; +// sprintf(buf,"got new connection at %.3f",GetTickCount()/1000.0); +// OutputDebugString(buf); + attachConnection(c,l->port()); + } + } + int x; + for (x = 0; x < m_connections->GetSize(); x ++) + { + WS_conInst *ci = (WS_conInst *)m_connections->Get(x); + int rv = run_connection(ci); + + if (rv<0) + { + JNL_IConnection *c=ci->m_serv.steal_con(); + if (c) + { + if (c->get_state() == JNL_Connection::STATE_CONNECTED) + attachConnection(c,ci->m_port); + else delete c; + } + } + + if (rv) + { + delete ci; + m_connections->Del(x--); + } + } +} + +int WebServerBaseClass::run_connection(WS_conInst *con) +{ + int s=con->m_serv.run(); + if (s < 0) + { + // m_serv.geterrorstr() + return 1; + } + if (s < 2) + { + // return 1 if we timed out + return time(NULL)-con->m_connect_time > m_timeout_s; + } + if (s < 3) + { + con->m_pagegen=onConnection(&con->m_serv,con->m_port); + return 0; + } + if (s < 4) + { + if (!con->m_pagegen) + { + if (con->m_serv.canKeepAlive()) return -1; + + return !con->m_serv.bytes_inqueue(); + } + char buf[16384]; + int l=con->m_serv.bytes_cansend(); + if (l > 0) + { + if (l > sizeof(buf))l=sizeof(buf); + l=con->m_pagegen->GetData(buf,l); + if (l < (con->m_pagegen->IsNonBlocking() ? 0 : 1)) // if nonblocking, this is l < 0, otherwise it's l<1 + { + if (con->m_serv.canKeepAlive()) return -1; + return !con->m_serv.bytes_inqueue(); + } + if (l>0) + con->m_serv.write_bytes(buf,l); + } + return 0; + } + if (con->m_serv.canKeepAlive()) return -1; + return 1; // we're done by this point +} + + + +void WebServerBaseClass::url_encode(const char *in, char *out, int max_out) +{ + while (*in && max_out > 4) + { + if ((*in >= 'A' && *in <= 'Z')|| + (*in >= 'a' && *in <= 'z')|| + (*in >= '0' && *in <= '9')|| *in == '.' || *in == '_' || *in == '-') + { + *out++=*in++; + max_out--; + } + else + { + int i=*in++; + *out++ = '%'; + int b=(i>>4)&15; + if (b < 10) *out++='0'+b; + else *out++='A'+b-10; + b=i&15; + if (b < 10) *out++='0'+b; + else *out++='A'+b-10; + max_out-=3; + } + } + *out=0; +} + + +void WebServerBaseClass::url_decode(const char *in, char *out, int maxlen) +{ + while (*in && maxlen>1) + { + if (*in == '+') + { + in++; + *out++=' '; + } + else if (*in == '%' && in[1] != '%' && in[1]) + { + int a=0; + int b=0; + for ( b = 0; b < 2; b ++) + { + int r=in[1+b]; + if (r>='0'&&r<='9') r-='0'; + else if (r>='a'&&r<='z') r-='a'-10; + else if (r>='A'&&r<='Z') r-='A'-10; + else break; + a*=16; + a+=r; + } + if (b < 2) *out++=*in++; + else { *out++=a; in += 3;} + } + else *out++=*in++; + maxlen--; + } + *out=0; +} + + + + + +void WebServerBaseClass::base64decode(const char *src, char *dest, int destsize) +{ + int accum=0; + int nbits=0; + while (*src) + { + int x=0; + char c=*src++; + if (c >= 'A' && c <= 'Z') x=c-'A'; + else if (c >= 'a' && c <= 'z') x=c-'a' + 26; + else if (c >= '0' && c <= '9') x=c-'0' + 52; + else if (c == '+') x=62; + else if (c == '/') x=63; + else break; + + accum <<= 6; + accum |= x; + nbits += 6; + + while (nbits >= 8) + { + if (--destsize<=0) break; + nbits-=8; + *dest++ = (char)((accum>>nbits)&0xff); + } + + } + *dest=0; +} + +void WebServerBaseClass::base64encode(const char *in, char *out) +{ + char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int shift = 0; + int accum = 0; + + while (*in) + { + if (*in) + { + accum <<= 8; + shift += 8; + accum |= *in++; + } + while ( shift >= 6 ) + { + shift -= 6; + *out++ = alphabet[(accum >> shift) & 0x3F]; + } + } + if (shift == 4) + { + *out++ = alphabet[(accum & 0xF)<<2]; + *out++='='; + } + else if (shift == 2) + { + *out++ = alphabet[(accum & 0x3)<<4]; + *out++='='; + *out++='='; + } + + *out++=0; +} + +int WebServerBaseClass::parseAuth(const char *auth_header, char *out, int out_len)//returns 0 on unknown auth, 1 on basic +{ + const char *authstr=auth_header; + *out=0; + if (!auth_header || !*auth_header) return 0; + while (*authstr == ' ') authstr++; + if (strnicmp(authstr,"basic ",6)) return 0; + authstr+=6; + while (*authstr == ' ') authstr++; + base64decode(authstr,out,out_len); + return 1; +} diff --git a/WDL/jnetlib/webserver.h b/WDL/jnetlib/webserver.h new file mode 100644 index 00000000..0701d375 --- /dev/null +++ b/WDL/jnetlib/webserver.h @@ -0,0 +1,224 @@ +/* +** JNetLib +** Copyright (C) 2008 Cockos Inc +** Copyright (C) 2003 Nullsoft, Inc. +** Author: Justin Frankel +** File: webserver.h - Generic simple webserver baseclass +** License: see jnetlib.h +** +** You can derive your object from WebServerBaseClass to do simple web serving. Example: + + class wwwServer : public WebServerBaseClass + { + public: + wwwServer() { } + virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port) + { + serv->set_reply_header("Server:jnetlib_test/0.0"); + if (!strcmp(serv->get_request_file(),"/")) + { + serv->set_reply_string("HTTP/1.1 200 OK"); + serv->set_reply_header("Content-Type:text/html"); + serv->send_reply(); + + return new MemPageGenerator(strdup("Test Web Server v0.0")); + } + else + { + serv->set_reply_string("HTTP/1.1 404 NOT FOUND"); + serv->send_reply(); + return 0; // no data + } + } + }; + + + wwwServer foo; + foo.addListenPort(8080); + while (1) + { + foo.run(); + Sleep(10); + } + + You will also need to derive from the IPageGenerator interface to provide a data stream, here is an + example of MemPageGenerator: + + class MemPageGenerator : public IPageGenerator + { + public: + virtual ~MemPageGenerator() { free(m_buf); } + MemPageGenerator(char *buf, int buf_len=-1) { m_buf=buf; if (buf_len >= 0) m_buf_size=buf_len; else m_buf_size=strlen(buf); m_buf_pos=0; } + virtual int GetData(char *buf, int size) // return 0 when done + { + int a=m_buf_size-m_buf_pos; + if (a < size) size=a; + memcpy(buf,m_buf+m_buf_pos,size); + m_buf_pos+=size; + return size; + } + + private: + char *m_buf; + int m_buf_size; + int m_buf_pos; + }; + + +** +*/ + + +#ifndef _JNL_WEBSERVER_H_ +#define _JNL_WEBSERVER_H_ + +#include "httpserv.h" +#include "../wdlcstring.h" + +class IPageGenerator +{ +public: + virtual ~IPageGenerator() { }; + virtual int IsNonBlocking() { return 0; } // override this and return 1 if GetData should be allowed to return 0 + virtual int GetData(char *buf, int size)=0; // return < 0 when done (or 0 if IsNonBlocking() is 1) +}; + + + +class WS_ItemList; +class WS_conInst; + +class WebServerBaseClass +{ +protected: // never create one of these directly, always derive + WebServerBaseClass(); + +public: + virtual ~WebServerBaseClass(); + + // stuff for setting limits/timeouts + void setMaxConnections(int max_con); + void setRequestTimeout(int timeout_s); + + // stuff for setting listener port + int addListenPort(int port, unsigned int which_interface=0); + int getListenPort(int idx, int *err=0); + void removeListenPort(int port); + void removeListenIdx(int idx); + + // call this a lot :) + void run(void); + + // if you want to manually attach a connection, use this: + // you need to specify the port it came in on so the web server can build + // links + void attachConnection(JNL_IConnection *con, int port); + + // derived classes need to override this one =) + virtual IPageGenerator *onConnection(JNL_HTTPServ *serv, int port)=0; + + // stats getting functions + + // these can be used externally, as well as are used by the web server + static void url_encode(const char *in, char *out, int max_out); + static void url_decode(const char *in, char *out, int maxlen); + static void base64decode(const char *src, char *dest, int destsize); + static void base64encode(const char *in, char *out); + + static int parseAuth(const char *auth_header, char *out, int out_len);//returns 0 on unknown auth, 1 on basic + + +private: + int run_connection(WS_conInst *con); + + int m_timeout_s; + int m_max_con; + + JNL_AsyncDNS m_dns; + + WS_ItemList *m_listeners; + int m_listener_rot; + WS_ItemList *m_connections; +}; + + + +#ifdef JNETLIB_WEBSERVER_WANT_UTILS + +#include "../fileread.h" +#include "../wdlstring.h" + +class JNL_FilePageGenerator : public IPageGenerator +{ + public: + JNL_FilePageGenerator(WDL_FileRead *fr) { m_file = fr; } + virtual ~JNL_FilePageGenerator() { delete m_file; } + virtual int GetData(char *buf, int size) { return m_file ? m_file->Read(buf,size) : -1; } + + private: + + WDL_FileRead *m_file; +}; +class JNL_StringPageGenerator : public IPageGenerator +{ + public: + JNL_StringPageGenerator() { m_pos=0; m_len=-1; } + virtual ~JNL_StringPageGenerator() { } + virtual int GetData(char *buf, int size) + { + if (m_len<0) m_len=strlen(str.Get()); + if (size > m_len - m_pos) size=m_len-m_pos; + if (size>0) + { + memcpy(buf,str.Get()+m_pos,size); + m_pos+=size; + } + return size; + } + + WDL_String str; // set this before sending it off + + private: + int m_len; + int m_pos; +}; + +static void JNL_get_mime_type_for_file(const char *fn, char *strout, int stroutsz) +{ + const char *ext = fn; + while (*ext) ext++; + while (ext > fn && *ext != '.' && *ext != '/' && *ext != '\\') ext--; + + const char *type = "application/octet-stream"; + + if (!stricmp(ext,".jpg")) type = "image/jpeg"; + else if (!stricmp(ext,".png")) type = "image/png"; + else if (!stricmp(ext,".gif")) type = "image/gif"; + else if (!stricmp(ext,".html")) type = "text/html"; + else if (!stricmp(ext,".txt")) type = "text/plain"; + else if (!stricmp(ext,".js")) type = "application/x-javascript"; + + lstrcpyn_safe(strout,type,stroutsz); +} + +static void JNL_Format_RFC1123(time_t t, char *buf) +{ + + buf[0]=0; + static const char days[] = { "SunMonTueWedThuFriSat" }; + static const char mons[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" }; + + struct tm *tm = gmtime(&t); + if (!tm) return; + memcpy(buf, days + (tm->tm_wday%7)*3, 3); + strcpy(buf+3,", "); + char *p=buf+5; + strftime(p, 64, "%d xxx %Y %H:%M:%S GMT", tm); + while (*p && *p != 'x') p++; + if (*p) memcpy(p, mons + (tm->tm_mon%12)*3, 3); +} + +#endif //JNETLIB_WEBSERVER_WANT_UTILS + + +#endif//_JNL_WEBSERVER_H_ diff --git a/WDL/jpeglib/README b/WDL/jpeglib/README new file mode 100644 index 00000000..911d0e84 --- /dev/null +++ b/WDL/jpeglib/README @@ -0,0 +1,385 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6b of 27-Mar-1998 +==================================== + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, +Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, +Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG +Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1998, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The Unix configuration script "configure" was produced with GNU Autoconf. +It is copyright by the Free Software Foundation but is freely distributable. +The same holds for its supporting scripts (config.guess, config.sub, +ltconfig, ltmain.sh). Another support script, install-sh, is copyright +by M.I.T. but is also freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +The IJG distribution formerly included code to read and write GIF files. +To avoid entanglement with the Unisys LZW patent, GIF reading support has +been removed altogether, and the GIF writer has been simplified to produce +"uncompressed GIFs". This technique does not use the LZW algorithm; the +resulting GIF files are larger than usual, but are readable by all standard +GIF decoders. + +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." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article is +available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and IEEE, +and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides +good explanations and example C code for a multitude of compression methods +including JPEG. It is an excellent source if you are comfortable reading C +code but don't know much about data compression in general. The book's JPEG +sample code is far from industrial-strength, but when you are ready to look +at a full implementation, you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Some extensions to the original JPEG standard are defined in JPEG Part 3, +a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG +currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available by FTP at +ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text +version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing +the figures. + +The TIFF 6.0 file format specification can be obtained by FTP from +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or +from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision +of the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from ftp://ftp.sgi.com/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have +direct Internet access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or +on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 +"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net +release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ +and other news.answers archive sites, including the official news.answers +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS software, which provides many useful operations on PPM-format image +files. In particular, it can convert PPM images to and from a wide range of +other formats, thus making cjpeg/djpeg considerably more useful. The latest +version is distributed by the NetPBM group, and is available from numerous +sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; +you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from ftp://havefun.stanford.edu/pub/jpeg/. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. (On the other hand, it doesn't do progressive JPEG.) + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +The major thrust for v7 will probably be improvement of visual quality. +The current method for scaling the quantization tables is known not to be +very good at low Q values. We also intend to investigate block boundary +smoothing, "poor man's variable quantization", and other means of improving +quality-vs-file-size performance without sacrificing compatibility. + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +As always, speeding things up is of great interest. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/WDL/jpeglib/example.c b/WDL/jpeglib/example.c new file mode 100644 index 00000000..9dcbd7d9 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcapimin.c b/WDL/jpeglib/jcapimin.c new file mode 100644 index 00000000..493af5c3 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcapistd.c b/WDL/jpeglib/jcapistd.c new file mode 100644 index 00000000..fed66caf --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jccoefct.c b/WDL/jpeglib/jccoefct.c new file mode 100644 index 00000000..c713b858 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jccolor.c b/WDL/jpeglib/jccolor.c new file mode 100644 index 00000000..26637245 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcdctmgr.c b/WDL/jpeglib/jcdctmgr.c new file mode 100644 index 00000000..e3f90dc3 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jchuff.c b/WDL/jpeglib/jchuff.c new file mode 100644 index 00000000..16d9366a --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jchuff.h b/WDL/jpeglib/jchuff.h new file mode 100644 index 00000000..8c02c09a --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcinit.c b/WDL/jpeglib/jcinit.c new file mode 100644 index 00000000..19de8d0e --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcmainct.c b/WDL/jpeglib/jcmainct.c new file mode 100644 index 00000000..14aa4c75 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcmarker.c b/WDL/jpeglib/jcmarker.c new file mode 100644 index 00000000..0d3ca5e5 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcmaster.c b/WDL/jpeglib/jcmaster.c new file mode 100644 index 00000000..e61138b1 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcomapi.c b/WDL/jpeglib/jcomapi.c new file mode 100644 index 00000000..1b1a340c --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jconfig.h b/WDL/jpeglib/jconfig.h new file mode 100644 index 00000000..4d40a57d --- /dev/null +++ b/WDL/jpeglib/jconfig.h @@ -0,0 +1,15 @@ +#define HAVE_PROTOTYPES +#define HAVE_STDLIB_H +#define HAVE_UNSIGNED_SHORT +#define HAVE_UNSIGNED_CHAR +#ifndef _WIN32 +#define NEED_SYS_TYPES_H +#define HAVE_STDDEF_H +#else +#include +#define XMD_H +#undef FAR +#define HAVE_BOOLEAN +typedef short INT16; +#endif + diff --git a/WDL/jpeglib/jcparam.c b/WDL/jpeglib/jcparam.c new file mode 100644 index 00000000..bbd175c8 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcphuff.c b/WDL/jpeglib/jcphuff.c new file mode 100644 index 00000000..a4ee850e --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcprepct.c b/WDL/jpeglib/jcprepct.c new file mode 100644 index 00000000..fdc4bc2d --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jcsample.c b/WDL/jpeglib/jcsample.c new file mode 100644 index 00000000..fe29fcab --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jctrans.c b/WDL/jpeglib/jctrans.c new file mode 100644 index 00000000..8b36e363 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdapimin.c b/WDL/jpeglib/jdapimin.c new file mode 100644 index 00000000..bd1df927 --- /dev/null +++ b/WDL/jpeglib/jdapimin.c @@ -0,0 +1,395 @@ +/* + * 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" + + +/* + * 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; + + /* 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; +} diff --git a/WDL/jpeglib/jdapistd.c b/WDL/jpeglib/jdapistd.c new file mode 100644 index 00000000..f6c7fffe --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdatadst.c b/WDL/jpeglib/jdatadst.c new file mode 100644 index 00000000..2ece4e95 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdatasrc.c b/WDL/jpeglib/jdatasrc.c new file mode 100644 index 00000000..29b69832 --- /dev/null +++ b/WDL/jpeglib/jdatasrc.c @@ -0,0 +1,212 @@ +/* + * 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/WDL/jpeglib/jdcoefct.c b/WDL/jpeglib/jdcoefct.c new file mode 100644 index 00000000..992bd105 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdcolor.c b/WDL/jpeglib/jdcolor.c new file mode 100644 index 00000000..fd7b1388 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdct.h b/WDL/jpeglib/jdct.h new file mode 100644 index 00000000..b664cab0 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jddctmgr.c b/WDL/jpeglib/jddctmgr.c new file mode 100644 index 00000000..0e44eb14 --- /dev/null +++ b/WDL/jpeglib/jddctmgr.c @@ -0,0 +1,269 @@ +/* + * 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 */ + + +/* + * 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 + + +/* + * 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: + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + 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/WDL/jpeglib/jdhuff.c b/WDL/jpeglib/jdhuff.c new file mode 100644 index 00000000..b2ad66d4 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdhuff.h b/WDL/jpeglib/jdhuff.h new file mode 100644 index 00000000..12c07477 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdinput.c b/WDL/jpeglib/jdinput.c new file mode 100644 index 00000000..2d5c7470 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdmainct.c b/WDL/jpeglib/jdmainct.c new file mode 100644 index 00000000..6b0f06f5 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdmarker.c b/WDL/jpeglib/jdmarker.c new file mode 100644 index 00000000..9811761d --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdmaster.c b/WDL/jpeglib/jdmaster.c new file mode 100644 index 00000000..eda4b3fa --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdmerge.c b/WDL/jpeglib/jdmerge.c new file mode 100644 index 00000000..9e3a595d --- /dev/null +++ b/WDL/jpeglib/jdmerge.c @@ -0,0 +1,400 @@ +/* + * 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 + + +/* 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. + */ + +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]; + } +} + + +/* + * 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/WDL/jpeglib/jdphuff.c b/WDL/jpeglib/jdphuff.c new file mode 100644 index 00000000..24047432 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdpostct.c b/WDL/jpeglib/jdpostct.c new file mode 100644 index 00000000..7ba9eed5 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdsample.c b/WDL/jpeglib/jdsample.c new file mode 100644 index 00000000..e0d9040a --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jdtrans.c b/WDL/jpeglib/jdtrans.c new file mode 100644 index 00000000..12c193c8 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jerror.c b/WDL/jpeglib/jerror.c new file mode 100644 index 00000000..c98aed76 --- /dev/null +++ b/WDL/jpeglib/jerror.c @@ -0,0 +1,252 @@ +/* + * 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" + +#ifdef USE_WINDOWS_MESSAGEBOX +#include +#endif + +#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/WDL/jpeglib/jerror.h b/WDL/jpeglib/jerror.h new file mode 100644 index 00000000..79084f2e --- /dev/null +++ b/WDL/jpeglib/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/WDL/jpeglib/jfdctflt.c b/WDL/jpeglib/jfdctflt.c new file mode 100644 index 00000000..7ccfb380 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jfdctfst.c b/WDL/jpeglib/jfdctfst.c new file mode 100644 index 00000000..005a74fe --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jfdctint.c b/WDL/jpeglib/jfdctint.c new file mode 100644 index 00000000..d6269274 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jidctflt.c b/WDL/jpeglib/jidctflt.c new file mode 100644 index 00000000..5fea54c2 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jidctfst.c b/WDL/jpeglib/jidctfst.c new file mode 100644 index 00000000..078b8c44 --- /dev/null +++ b/WDL/jpeglib/jidctfst.c @@ -0,0 +1,368 @@ +/* + * 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 + + +/* + * 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 /* DCT_IFAST_SUPPORTED */ diff --git a/WDL/jpeglib/jidctint.c b/WDL/jpeglib/jidctint.c new file mode 100644 index 00000000..4f47fe83 --- /dev/null +++ b/WDL/jpeglib/jidctint.c @@ -0,0 +1,389 @@ +/* + * 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 */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/WDL/jpeglib/jidctred.c b/WDL/jpeglib/jidctred.c new file mode 100644 index 00000000..911899b8 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jinclude.h b/WDL/jpeglib/jinclude.h new file mode 100644 index 00000000..5ff60fed --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jmemmgr.c b/WDL/jpeglib/jmemmgr.c new file mode 100644 index 00000000..b636f1be --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jmemnobs.c b/WDL/jpeglib/jmemnobs.c new file mode 100644 index 00000000..6aa1e929 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jmemsys.h b/WDL/jpeglib/jmemsys.h new file mode 100644 index 00000000..2a879611 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jmorecfg.h b/WDL/jpeglib/jmorecfg.h new file mode 100644 index 00000000..c856e226 --- /dev/null +++ b/WDL/jpeglib/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/WDL/jpeglib/jpegint.h b/WDL/jpeglib/jpegint.h new file mode 100644 index 00000000..685a3610 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jpeglib.h b/WDL/jpeglib/jpeglib.h new file mode 100644 index 00000000..b9356f39 --- /dev/null +++ b/WDL/jpeglib/jpeglib.h @@ -0,0 +1,1096 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/WDL/jpeglib/jquant1.c b/WDL/jpeglib/jquant1.c new file mode 100644 index 00000000..aaa34a18 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jquant2.c b/WDL/jpeglib/jquant2.c new file mode 100644 index 00000000..87a3920b --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jutils.c b/WDL/jpeglib/jutils.c new file mode 100644 index 00000000..286cda20 --- /dev/null +++ b/WDL/jpeglib/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/WDL/jpeglib/jversion.h b/WDL/jpeglib/jversion.h new file mode 100644 index 00000000..dadd453a --- /dev/null +++ b/WDL/jpeglib/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/WDL/lameencdec.cpp b/WDL/lameencdec.cpp new file mode 100644 index 00000000..702b4799 --- /dev/null +++ b/WDL/lameencdec.cpp @@ -0,0 +1,1004 @@ +/* + WDL - lameencdec.cpp + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + +*/ + + + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include +#include + +#include "wdlcstring.h" +#include "lameencdec.h" + + +#ifdef USE_LAME_BLADE_API + +#pragma pack(push) +#pragma pack(1) + +#ifdef __cplusplus +extern "C" { +#endif + +/* encoding formats */ + +#define BE_CONFIG_MP3 0 +#define BE_CONFIG_LAME 256 + +/* type definitions */ + +typedef UINT_PTR HBE_STREAM; +typedef HBE_STREAM *PHBE_STREAM; +typedef unsigned long BE_ERR; + +/* error codes */ + +#define BE_ERR_SUCCESSFUL 0x00000000 +#define BE_ERR_INVALID_FORMAT 0x00000001 +#define BE_ERR_INVALID_FORMAT_PARAMETERS 0x00000002 +#define BE_ERR_NO_MORE_HANDLES 0x00000003 +#define BE_ERR_INVALID_HANDLE 0x00000004 +#define BE_ERR_BUFFER_TOO_SMALL 0x00000005 + +/* other constants */ + +#define BE_MAX_HOMEPAGE 128 + +/* format specific variables */ + +#define BE_MP3_MODE_STEREO 0 +#define BE_MP3_MODE_JSTEREO 1 +#define BE_MP3_MODE_DUALCHANNEL 2 +#define BE_MP3_MODE_MONO 3 + + + +#define MPEG1 1 +#define MPEG2 0 + +#ifdef _BLADEDLL +#undef FLOAT + #include +#endif + +#define CURRENT_STRUCT_VERSION 1 +#define CURRENT_STRUCT_SIZE sizeof(BE_CONFIG) // is currently 331 bytes + +/* OBSOLETE, VALUES STILL WORK +typedef enum +{ + NORMAL_QUALITY=0, + LOW_QUALITY, + HIGH_QUALITY, + VOICE_QUALITY +} LAME_QUALTIY_PRESET; + +*/ + + +typedef enum +{ + VBR_METHOD_NONE = -1, + VBR_METHOD_DEFAULT = 0, + VBR_METHOD_OLD = 1, + VBR_METHOD_NEW = 2, + VBR_METHOD_MTRH = 3, + VBR_METHOD_ABR = 4 +} VBRMETHOD; + +typedef enum +{ + LQP_NOPRESET=-1, + + // QUALITY PRESETS + LQP_NORMAL_QUALITY=0, + LQP_LOW_QUALITY, + LQP_HIGH_QUALITY, + LQP_VOICE_QUALITY, + LQP_R3MIX_QUALITY, + LQP_VERYHIGH_QUALITY, + + // NEW PRESET VALUES + LQP_PHONE =1000, + LQP_SW =2000, + LQP_AM =3000, + LQP_FM =4000, + LQP_VOICE =5000, + LQP_RADIO =6000, + LQP_TAPE =7000, + LQP_HIFI =8000, + LQP_CD =9000, + LQP_STUDIO =10000 + +} LAME_QUALTIY_PRESET; + + + +typedef struct { + DWORD dwConfig; // BE_CONFIG_XXXXX + // Currently only BE_CONFIG_MP3 is supported + union { + + struct { + + DWORD dwSampleRate; // 48000, 44100 and 32000 allowed. RG note: also seems to support 16000, 22050, 24000. + BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO + WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed. RG note: also seems to support 8,16,24. + BOOL bPrivate; + BOOL bCRC; + BOOL bCopyright; + BOOL bOriginal; + + } mp3; // BE_CONFIG_MP3 + + struct + { + // STRUCTURE INFORMATION + DWORD dwStructVersion; + DWORD dwStructSize; + + // BASIC ENCODER SETTINGS + DWORD dwSampleRate; // SAMPLERATE OF INPUT FILE + DWORD dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES + LONG nMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO + DWORD dwBitrate; // CBR bitrate, VBR min bitrate + DWORD dwMaxBitrate; // CBR ignored, VBR Max bitrate + LONG nPreset; // Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum + DWORD dwMpegVersion; // FUTURE USE, MPEG-1 OR MPEG-2 + DWORD dwPsyModel; // FUTURE USE, SET TO 0 + DWORD dwEmphasis; // FUTURE USE, SET TO 0 + + // BIT STREAM SETTINGS + BOOL bPrivate; // Set Private Bit (TRUE/FALSE) + BOOL bCRC; // Insert CRC (TRUE/FALSE) + BOOL bCopyright; // Set Copyright Bit (TRUE/FALSE) + BOOL bOriginal; // Set Original Bit (TRUE/FALSE) + + // VBR STUFF + BOOL bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE) + BOOL bEnableVBR; // USE VBR ENCODING (TRUE/FALSE) + INT nVBRQuality; // VBR QUALITY 0..9 + DWORD dwVbrAbr_bps; // Use ABR in stead of nVBRQuality + VBRMETHOD nVbrMethod; + BOOL bNoRes; // Disable Bit resorvoir + + BYTE btReserved[255-3*sizeof(DWORD)]; // FUTURE USE, SET TO 0 + + } LHV1; // LAME header version 1 + + struct { + + DWORD dwSampleRate; + BYTE byMode; + WORD wBitrate; + BYTE byEncodingMethod; + + } aac; + + } format; + +} BE_CONFIG, *PBE_CONFIG; + + +typedef struct { + + // BladeEnc DLL Version number + + BYTE byDLLMajorVersion; + BYTE byDLLMinorVersion; + + // BladeEnc Engine Version Number + + BYTE byMajorVersion; + BYTE byMinorVersion; + + // DLL Release date + + BYTE byDay; + BYTE byMonth; + WORD wYear; + + // BladeEnc Homepage URL + + CHAR zHomepage[BE_MAX_HOMEPAGE + 1]; + + BYTE byAlphaLevel; + BYTE byBetaLevel; + BYTE byMMXEnabled; + + BYTE btReserved[125]; + + +} BE_VERSION, *PBE_VERSION; + +typedef BE_ERR (*BEINITSTREAM) (PBE_CONFIG, PDWORD, PDWORD, PHBE_STREAM); +typedef BE_ERR (*BEENCODECHUNK) (HBE_STREAM, DWORD, PSHORT, PBYTE, PDWORD); +// added for floating point audio -- DSPguru, jd +typedef BE_ERR (*BEENCODECHUNKFLOATS16NI) (HBE_STREAM, DWORD, PFLOAT, PFLOAT, PBYTE, PDWORD); +typedef BE_ERR (*BEDEINITSTREAM) (HBE_STREAM, PBYTE, PDWORD); +typedef BE_ERR (*BECLOSESTREAM) (HBE_STREAM); +typedef VOID (*BEVERSION) (PBE_VERSION); + + + +#define MP3_ERR -1 +#define MP3_OK 0 +#define MP3_NEED_MORE 1 + +// void *InitMP3_Create(); +// void ExitMP3_Delete(void *); + +// int decodeMP3_unclipped(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); +// always uses all of inmemory, returns MP3_NEED_MORE if it needs more, and done is the output size. +// it appears outmemory is interleaved. outmemory is doubles, too. ick. +// is 'done' bytes or samples? inmemsize should be 1152*2*sizeof(double) + +// void get_decode_info(void *,int *nch, int *srate);//JF> added for querying the decode stats +// void remove_buf(void *); + + + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +static HINSTANCE hlamedll; +static BEINITSTREAM beInitStream; +static BECLOSESTREAM beCloseStream; +static BEENCODECHUNKFLOATS16NI beEncodeChunkFloatS16NI; +static BEDEINITSTREAM beDeinitStream; +static BE_ERR (*beWriteInfoTag)(HBE_STREAM, const char *); +static BEVERSION beVersion; +static void *(*InitMP3_Create)(); +static void (*ExitMP3_Delete)(void *); +static int (*decodeMP3_unclipped)(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); +static void (*get_decode_info)(void *,int *nch, int *srate);//JF> added for querying the decode stats +static void (*remove_buf)(void *); + + + +#endif // USE_LAME_BLADE_API + + +#ifdef DYNAMIC_LAME + #ifdef __APPLE__ + #include + #endif + #ifndef _WIN32 + #include + #endif + + +typedef enum MPEG_mode_e { + STEREO = 0, + JOINT_STEREO, + DUAL_CHANNEL, /* LAME doesn't supports this! */ + MONO, + NOT_SET, + MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ +} MPEG_mode; + + +static int (*lame_close)(lame_t); +static lame_t (*lame_init)(); +static int (*lame_set_in_samplerate)(lame_t, int); +static int (*lame_set_num_channels)(lame_t,int); +static int (*lame_set_out_samplerate)(lame_t,int); +static int (*lame_set_quality)(lame_t,int); +static int (*lame_set_mode)(lame_t,MPEG_mode); +static int (*lame_set_brate)(lame_t, int); +static int (*lame_init_params)(lame_t); +static int (*lame_get_framesize)(lame_t); +static int (*lame_set_VBR)(lame_t, int); +static int (*lame_set_VBR_q)(lame_t, int); +static int (*lame_set_VBR_mean_bitrate_kbps)(lame_t, int); +static int (*lame_set_VBR_min_bitrate_kbps)(lame_t, int); +static int (*lame_set_VBR_max_bitrate_kbps)(lame_t, int); + +static size_t (*lame_get_lametag_frame)(lame_t, unsigned char *, size_t); +static int (*lame_encode_buffer_float)(lame_t, + const float buffer_l [], /* PCM data for left channel */ + const float buffer_r [], /* PCM data for right channel */ + const int nsamples, /* number of samples per channel */ + unsigned char* mp3buf, /* pointer to encoded MP3 stream */ + const int mp3buf_size ); +static int (*lame_encode_flush)(lame_t,unsigned char* mp3buf, int size); + +#endif + + +void LameEncoder::InitDLL(const char *extrapath) +{ +#ifdef USE_LAME_BLADE_API + if (!hlamedll) + { +#ifdef _WIN64 + const char *dllName = "lame_enc64.dll"; +#else + const char *dllName = "lame_enc.dll"; +#endif + char me[1024]; + GetModuleFileName(NULL,me,sizeof(me)-64); + + char *p=me; + while (*p) p++; + while(p>=me && *p!='\\') p--; + + strcpy(++p,dllName); + + hlamedll=LoadLibrary(me); + if (extrapath && !hlamedll) + { + lstrcpyn_safe(me,extrapath,sizeof(me)-64); + lstrcatn(me,"\\",sizeof(me)); + lstrcatn(me,dllName,sizeof(me)); + hlamedll=LoadLibrary(me); + } + + if (!hlamedll) hlamedll=LoadLibrary(dllName); + + if (hlamedll) + { + *((void**)&beInitStream) = (void *) GetProcAddress(hlamedll, "beInitStream"); + *((void**)&beCloseStream) = (void *) GetProcAddress(hlamedll, "beCloseStream"); + *((void**)&beEncodeChunkFloatS16NI) = (void *) GetProcAddress(hlamedll, "beEncodeChunkFloatS16NI"); + *((void**)&beDeinitStream) = (void *) GetProcAddress(hlamedll, "beDeinitStream"); + *((void**)&beVersion) = (void *) GetProcAddress(hlamedll, "beVersion"); + *((void**)&beWriteInfoTag) = (void*) GetProcAddress(hlamedll, "beWriteInfoTag"); + *((void**)&InitMP3_Create) = (void *) GetProcAddress(hlamedll,"InitMP3_Create"); + *((void**)&ExitMP3_Delete) = (void *) GetProcAddress(hlamedll,"ExitMP3_Delete"); + *((void**)&decodeMP3_unclipped) = (void *) GetProcAddress(hlamedll,"decodeMP3_unclipped"); + *((void**)&get_decode_info) = (void *) GetProcAddress(hlamedll,"get_decode_info"); + *((void**)&remove_buf) = (void *) GetProcAddress(hlamedll,"remove_buf"); + } + + } +#elif defined(DYNAMIC_LAME) + static int a; + static void *dll; + if (!dll&& (a<100 || extrapath)) // try a bunch of times before giving up + { + a++; +#ifdef _WIN32 + const char *dllname = "libmp3lame.dll"; + #ifdef _WIN64 + const char *dllName2 = "lame_enc64.dll"; + #else + const char *dllName2 = "lame_enc.dll"; + #endif + char me[1024]; + + if (extrapath) + { + lstrcpyn_safe(me,extrapath,sizeof(me)-64); + lstrcatn(me,"\\",sizeof(me)); + lstrcatn(me,dllname,sizeof(me)); + dll=LoadLibrary(me); + if (!dll) + { + lstrcpyn_safe(me,extrapath,sizeof(me)-64); + lstrcatn(me,"\\",sizeof(me)); + lstrcatn(me,dllName2,sizeof(me)); + dll=LoadLibrary(me); + } + } + + if (!dll) + { + GetModuleFileName(NULL,me,sizeof(me)-64); + + char *p=me; + while (*p) p++; + while(p>=me && *p!='\\') p--; + + strcpy(++p,dllname); + + dll=(void*)LoadLibrary(me); + if (!dll) + { + strcpy(p,dllName2); + dll=(void*)LoadLibrary(me); + } + } + if (!dll) dll=LoadLibrary(dllname); + if (!dll) dll=LoadLibrary(dllName2); + +#elif defined(__APPLE__) + if (!dll && extrapath) + { + char me[1024]; + lstrcpyn_safe(me,extrapath,sizeof(me)-64); + lstrcatn(me,"/libmp3lame.dylib",sizeof(me)); + dll = dlopen(me, RTLD_NOW|RTLD_LOCAL); + } + if (!dll) dll = dlopen("/Library/Application Support/libmp3lame.dylib", RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("/usr/lib/libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); + + if (!dll) dll=dlopen("libmp3lame.dylib",RTLD_NOW|RTLD_LOCAL); + + if (!dll) + { + CFBundleRef bund=CFBundleGetMainBundle(); + if (bund) + { + CFURLRef url=CFBundleCopyBundleURL(bund); + if (url) + { + char buf[8192]; + if (CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf)-128)) + { + char *p=buf; + while (*p) p++; + while (p>=buf && *p != '/') p--; + if (p>=buf) + { + strcat(buf,"/Contents/Plugins/libmp3lame.dylib"); + if (!dll) dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); + + if (!dll) + { + strcpy(p,"/libmp3lame.dylib"); + dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); + } + if (!dll) + { + strcpy(p,"/Plugins/libmp3lame.dylib"); + if (!dll) dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); + } + } + } + CFRelease(url); + } + } + } +#else // linux default to .so + if (!dll && extrapath) + { + char me[1024]; + lstrcpyn_safe(me,extrapath,sizeof(me)-64); + lstrcatn(me,"/libmp3lame.so",sizeof(me)); + dll = dlopen(me, RTLD_NOW|RTLD_LOCAL); + } + if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.so",RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("/usr/lib/libmp3lame.so",RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("libmp3lame.so",RTLD_NOW|RTLD_LOCAL); + + if (!dll) dll=dlopen("/usr/local/lib/libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("/usr/lib/libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); + if (!dll) dll=dlopen("libmp3lame.so.0",RTLD_NOW|RTLD_LOCAL); + if (!dll) + { + char tmp[64]; + sprintf(tmp,"/proc/%d/exe",getpid()); + char buf[1024]; + buf[0]=0; + if (readlink(tmp,buf,sizeof(buf)-128)>0 && buf[0]) + { + char *p = buf; + while (*p) p++; + while (p>buf && *p != '/') p--; + if (p>buf) + { + strcpy(p,"/Plugins/libmp3lame.so"); + dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); + if (!dll) + { + strcpy(p,"/libmp3lame.so"); + dll=dlopen(buf,RTLD_NOW|RTLD_LOCAL); + } + } + } + } +#endif + + if (dll) + { + #ifdef _WIN32 + #define TURD(x) *(void **)&x = GetProcAddress((HINSTANCE)dll,#x); + #else + #define TURD(x) *(void **)&x = dlsym(dll,#x); + #endif + TURD(lame_get_lametag_frame) + TURD(lame_close) + TURD(lame_init) + TURD(lame_set_in_samplerate) + TURD(lame_set_num_channels) + TURD(lame_set_out_samplerate) + TURD(lame_set_quality) + TURD(lame_set_mode) + TURD(lame_set_brate) + TURD(lame_init_params) + TURD(lame_get_framesize) + TURD(lame_encode_buffer_float) + TURD(lame_encode_flush) + TURD(lame_set_VBR) + TURD(lame_set_VBR_q) + TURD(lame_set_VBR_mean_bitrate_kbps) + TURD(lame_set_VBR_min_bitrate_kbps) + TURD(lame_set_VBR_max_bitrate_kbps) + #undef TURD + } + } +#endif +} + +bool LameEncoder::CheckDLL() // returns true if dll is present +{ + InitDLL(); +#ifdef USE_LAME_BLADE_API + if (!beInitStream||!beCloseStream||!beEncodeChunkFloatS16NI||!beDeinitStream||!beVersion) return false; +#elif defined(DYNAMIC_LAME) + if (!lame_close||!lame_init||!lame_set_in_samplerate||!lame_set_num_channels||!lame_set_out_samplerate||!lame_set_quality||!lame_set_mode + ||!lame_set_brate||!lame_init_params||!lame_get_framesize||!lame_encode_buffer_float||!lame_encode_flush) return false; +#endif + return true; +} + +LameEncoder::LameEncoder(int srate, int nch, int bitrate, int stereomode, int quality, int vbrmethod, int vbrquality, int vbrmax, int abr) +{ + errorstat=0; + InitDLL(); +#ifdef USE_LAME_BLADE_API + hbeStream=0; + if (!CheckDLL()) + { + errorstat=1; + return; + } +#else + m_lamestate=0; + if (!CheckDLL()) + { + errorstat=1; + return; + } + m_lamestate=lame_init(); + if (!m_lamestate) + { + errorstat=1; + return; + } +#endif + m_nch=nch; + + +#ifdef USE_LAME_BLADE_API + + m_encoder_nch = stereomode == BE_MP3_MODE_MONO ? 1 : nch; + + BE_CONFIG beConfig; + memset(&beConfig,0,sizeof(beConfig)); + beConfig.dwConfig = BE_CONFIG_LAME; + + beConfig.format.LHV1.dwStructVersion = 1; + beConfig.format.LHV1.dwStructSize = sizeof(beConfig); + beConfig.format.LHV1.dwSampleRate = srate; + if (m_encoder_nch == 1) beConfig.format.LHV1.nMode = BE_MP3_MODE_MONO; + else beConfig.format.LHV1.nMode = stereomode; //bitrate >= 192 ? BE_MP3_MODE_STEREO : BE_MP3_MODE_JSTEREO; + + beConfig.format.LHV1.dwBitrate=bitrate; + beConfig.format.LHV1.dwMaxBitrate=(vbrmethod!=-1?vbrmax:bitrate); + beConfig.format.LHV1.dwReSampleRate = srate; + + // if mpeg 1, and bitrate is less than 32kbps per channel, switch to mpeg 2 + if (beConfig.format.LHV1.dwReSampleRate >= 32000 && beConfig.format.LHV1.dwMaxBitrate/m_encoder_nch <= 32) + { + beConfig.format.LHV1.dwReSampleRate/=2; + } + beConfig.format.LHV1.dwMpegVersion = (beConfig.format.LHV1.dwReSampleRate < 32000 ? MPEG2 : MPEG1); + + beConfig.format.LHV1.nPreset=quality; + + beConfig.format.LHV1.bNoRes = 0;//1; + + beConfig.format.LHV1.bWriteVBRHeader= 1; + beConfig.format.LHV1.bEnableVBR= vbrmethod!=-1; + beConfig.format.LHV1.nVBRQuality= vbrquality; + beConfig.format.LHV1.dwVbrAbr_bps = (vbrmethod!=-1?1000*abr:0); + beConfig.format.LHV1.nVbrMethod=(VBRMETHOD)vbrmethod; + + +/* LAME sets unwise bit if: + if (gfp->short_blocks == short_block_forced || gfp->short_blocks == short_block_dispensed || ((gfp->lowpassfreq == -1) && (gfp->highpassfreq == -1)) || // "-k" + (gfp->scale_left < gfp->scale_right) || + (gfp->scale_left > gfp->scale_right) || + (gfp->disable_reservoir && gfp->brate < 320) || + gfp->noATH || gfp->ATHonly || (nAthType == 0) || gfp->in_samplerate <= 32000) +*/ + + int out_size_bytes=0; + hbeStream=0; + + if (beInitStream(&beConfig, (DWORD*)&in_size_samples, (DWORD*)&out_size_bytes, (PHBE_STREAM) &hbeStream) != BE_ERR_SUCCESSFUL) + { + errorstat=2; + return; + } + in_size_samples/=m_encoder_nch; +#else + m_encoder_nch = stereomode == 3 ? 1 : m_nch; + + lame_set_in_samplerate(m_lamestate, srate); + lame_set_num_channels(m_lamestate,m_encoder_nch); + int outrate=srate; + + int maxbr = (vbrmethod != -1 ? vbrmax : bitrate); + if (outrate>=32000 && maxbr <= 32*m_encoder_nch) outrate/=2; + + lame_set_out_samplerate(m_lamestate,outrate); + lame_set_quality(m_lamestate,(quality>9 ||quality<0) ? 0 : quality); + lame_set_mode(m_lamestate,(MPEG_mode) (m_encoder_nch==1?3 :stereomode )); + lame_set_brate(m_lamestate,bitrate); + + //int vbrmethod (-1 no vbr), int vbrquality (nVBRQuality), int vbrmax, int abr + if (vbrmethod != -1 && lame_set_VBR) + { + int vm=4; // mtrh + if (vbrmethod == 4) vm = 3; //ABR + lame_set_VBR(m_lamestate,vm); + + if (lame_set_VBR_q) lame_set_VBR_q(m_lamestate,vbrquality); + + if (vbrmethod == 4&&lame_set_VBR_mean_bitrate_kbps) + { + lame_set_VBR_mean_bitrate_kbps(m_lamestate,abr); + } + if (lame_set_VBR_max_bitrate_kbps) + { + lame_set_VBR_max_bitrate_kbps(m_lamestate,vbrmax); + } + if (lame_set_VBR_min_bitrate_kbps) + { + lame_set_VBR_min_bitrate_kbps(m_lamestate,bitrate); + } + } + lame_init_params(m_lamestate); + in_size_samples=lame_get_framesize(m_lamestate); + int out_size_bytes=65536; +#endif + + outtmp.Resize(out_size_bytes); + +} + +void LameEncoder::Encode(float *in, int in_spls, int spacing) +{ + + if (errorstat) return; + + if (in_spls > 0) + { + if (m_nch > 1 && m_encoder_nch==1) + { + // downmix + int x; + int pos=0; + int adv=2*spacing; + for (x = 0; x < in_spls; x ++) + { + float f=in[pos]+in[pos+1]; + f*=16383.5f; + spltmp[0].Add(&f,sizeof(float)); + pos+=adv; + } + } + else if (m_encoder_nch > 1) // deinterleave + { + int x; + int pos=0; + int adv=2*spacing; + for (x = 0; x < in_spls; x ++) + { + float f=in[pos]; + f*=32767.0f; + spltmp[0].Add(&f,sizeof(float)); + + f=in[pos+1]; + f*=32767.0f; + spltmp[1].Add(&f,sizeof(float)); + + pos+=adv; + } + } + else + { + int x; + int pos=0; + for (x = 0; x < in_spls; x ++) + { + float f=in[pos]; + f*=32767.0f; + spltmp[0].Add(&f,sizeof(float)); + + pos+=spacing; + } + } + } + for (;;) + { + int a = spltmp[0].Available()/sizeof(float); + if (a >= in_size_samples) a = in_size_samples; + else if (a<1 || in_spls>0) break; // not enough samples available, and not flushing + +#ifdef USE_LAME_BLADE_API + DWORD dwo=0; + if (beEncodeChunkFloatS16NI(hbeStream, a, (float*)spltmp[0].Get(), (float*)spltmp[m_encoder_nch > 1].Get(), + (unsigned char*)outtmp.Get(), &dwo) != BE_ERR_SUCCESSFUL) + { + errorstat=3; + return; + } +// printf("encoded to %d bytes (%d) %d\n",dwo, outtmp.GetSize(),in_size_samples); +#else + int dwo=lame_encode_buffer_float(m_lamestate,(float *)spltmp[0].Get(),(float*)spltmp[m_encoder_nch>1].Get(), + a,(unsigned char *)outtmp.Get(),outtmp.GetSize()); + //printf("encoded %d to %d\n",in_size_samples,dwo); +#endif + outqueue.Add(outtmp.Get(),dwo); + spltmp[0].Advance(a*sizeof(float)); + if (m_encoder_nch > 1) spltmp[1].Advance(a*sizeof(float)); + } + + if (in_spls<1) + { +#ifdef USE_LAME_BLADE_API + DWORD dwo=0; + if (beDeinitStream(hbeStream, (unsigned char *)outtmp.Get(), &dwo) == BE_ERR_SUCCESSFUL && dwo>0) + outqueue.Add(outtmp.Get(),dwo); + +#else + int a=lame_encode_flush(m_lamestate,(unsigned char *)outtmp.Get(),outtmp.GetSize()); + if (a>0) outqueue.Add(outtmp.Get(),a); +#endif + } + + + + spltmp[0].Compact(); + spltmp[1].Compact(); + +} + +#ifdef _WIN32 + +static BOOL HasUTF8(const char *_str) +{ + const unsigned char *str = (const unsigned char *)_str; + if (!str) return FALSE; + while (*str) + { + unsigned char c = *str; + if (c >= 0xC2) // discard overlongs + { + if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; + else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + } + str++; + } + return FALSE; +} +#endif + +LameEncoder::~LameEncoder() +{ +#ifdef USE_LAME_BLADE_API + if (hbeStream) + { + if (m_vbrfile.Get()[0] && beWriteInfoTag) + { + // support UTF-8 filenames + if (HasUTF8(m_vbrfile.Get()) && GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,m_vbrfile.Get(),-1,wf,2048)) + { + FILE *fp = _wfopen(wf,L"r+b"); + if (fp) + { + char tmpspace[1024],tmpfn[2048]; + GetTempPath(sizeof(tmpspace),tmpspace); + GetTempFileName(tmpspace,"lameenc",0,tmpfn); + FILE *tmpfp = fopen(tmpfn,"wb"); + if (tmpfp) + { + fseek(fp,0,SEEK_SET); + int x=32; // 32kb + while(x--) + { + int a =fread(tmpspace,1,sizeof(tmpspace),fp); + if (a<1) break; + fwrite(tmpspace,1,a,tmpfp); + } + + fclose(tmpfp); + + beWriteInfoTag(hbeStream,tmpfn); + hbeStream=0; + + tmpfp = fopen(tmpfn,"r+b"); + if (tmpfp) + { + fseek(tmpfp,0,SEEK_SET); + fseek(fp,0,SEEK_SET); + + x=32; // 32kb + while(x--) + { + int a = fread(tmpspace,1,sizeof(tmpspace),tmpfp); + if (a<1) break; + fwrite(tmpspace,1,a,fp); + } + + fclose(tmpfp); + } + + DeleteFile(tmpfn); + } + fclose(fp); + + } + } + } + + + if (hbeStream) beWriteInfoTag(hbeStream,m_vbrfile.Get()); + } + else beCloseStream(hbeStream); + hbeStream=0; + } +#else + if (m_lamestate) + { + if (m_vbrfile.Get()[0] && lame_get_lametag_frame) + { + unsigned char buf[16384]; + int a=lame_get_lametag_frame(m_lamestate,buf,sizeof(buf)); + if (a>0 && a<=sizeof(buf)) + { + FILE *fp=NULL; +#ifdef _WIN32 + if (HasUTF8(m_vbrfile.Get()) && GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,m_vbrfile.Get(),-1,wf,2048)) + { + fp = _wfopen(wf,L"r+b"); + } + } +#endif + if (!fp) fp = fopen(m_vbrfile.Get(),"r+b"); + if (fp) + { + fseek(fp,0,SEEK_SET); + fwrite(buf,1,a,fp); + fclose(fp); + } + } + } + lame_close(m_lamestate); + m_lamestate=0; + } +#endif +} + +#ifdef USE_LAME_BLADE_API // todo: lame decoding on nonwin32 + +LameDecoder::LameDecoder() +{ + m_samples_remove=1152*2; + m_samplesdec=0; + decinst=0; + errorstat=0; + m_samples_used=0; + m_srate=m_nch=0; + LameEncoder::InitDLL(); + if (!InitMP3_Create||!ExitMP3_Delete||!decodeMP3_unclipped||!get_decode_info||!remove_buf) + { + errorstat=1; + return; + } + + decinst=InitMP3_Create(); + +} + +void LameDecoder::DecodeWrote(int srclen) +{ + if (errorstat||!decinst) return; + + for (;;) + { + double buf[1152*2]; + int bout; + //decodeMP3_unclipped(void *,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done); + int ret=decodeMP3_unclipped(decinst,(unsigned char *)srctmp.Get(),srclen,(char *)buf,sizeof(buf),&bout); + if (ret == MP3_ERR) { errorstat=1; break; } + if (ret == MP3_NEED_MORE) { break; } + + if (ret == MP3_OK) + { + if (!m_srate || !m_nch) get_decode_info(decinst,&m_nch,&m_srate); + bout /= sizeof(double); + + int bout_pairs=bout/m_nch; + double *bufptr=buf; + + + if (bout > 0) + { + int x; + int newsize=(m_samples_used+bout+4096)*sizeof(float); + if (m_samples.GetSize() < newsize) m_samples.Resize(newsize); + + float *fbuf=(float *)m_samples.Get(); + fbuf += m_samples_used; + + m_samplesdec += bout_pairs; + m_samples_used+=bout; + + for (x = 0; x < bout; x ++) + { + fbuf[x]=(float)(bufptr[x] * (1.0/32767.0)); + } + } + } + + srclen=0; + } +} + +void LameDecoder::Reset() +{ + m_samples_remove=1152*2; + m_samples_used=0; + m_samplesdec=0; + + //if (decinst) remove_buf(decinst); +/* + if (decinst) + { + ExitMP3_Delete(decinst); + } + decinst=InitMP3_Create(); + */ +} + +LameDecoder::~LameDecoder() +{ + if (decinst) + { + ExitMP3_Delete(decinst); + } +} +#endif diff --git a/WDL/lameencdec.h b/WDL/lameencdec.h new file mode 100644 index 00000000..f7778f36 --- /dev/null +++ b/WDL/lameencdec.h @@ -0,0 +1,136 @@ +/* + WDL - lameencdec.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides a simple interface for using lame_enc.dll on Windows for MP3 encoding and decoding. + +*/ + + +#ifndef _LAMEENCDEC_H_ +#define _LAMEENCDEC_H_ + +#include "queue.h" +#include "wdlstring.h" + +#ifdef _WIN32 + #ifndef _WIN64 + #define USE_LAME_BLADE_API + #endif +#endif + +#ifndef USE_LAME_BLADE_API + #define DYNAMIC_LAME + + #ifdef DYNAMIC_LAME + typedef void *lame_t; + #else + #include + #endif +#endif + + + +class LameEncoder +{ + public: + + LameEncoder(int srate, int nch, int bitrate, int stereomode = 1, int quality = 0, int vbrmethod = -1, int vbrquality = 2, int vbrmax = 320, int abr = 128); + ~LameEncoder(); + + int Status() { return errorstat; } // 1=no dll, 2=error + + void Encode(float *in, int in_spls, int spacing=1); + + WDL_Queue outqueue; + + void reinit() + { + spltmp[0].Advance(spltmp[0].Available()); + spltmp[0].Compact(); + spltmp[1].Advance(spltmp[1].Available()); + spltmp[1].Compact(); + } + + static bool CheckDLL(); // returns true if dll is present + static void InitDLL(const char *extrapath=NULL); // call with extrapath != NULL if you want to try loading from another path + + void SetVBRFilename(const char *fn) + { + m_vbrfile.Set(fn); + } + + int GetNumChannels() { return m_encoder_nch; } + + private: + int m_nch,m_encoder_nch; + WDL_Queue spltmp[2]; + WDL_HeapBuf outtmp; + WDL_String m_vbrfile; + int errorstat; + int in_size_samples; +#ifdef USE_LAME_BLADE_API + UINT_PTR hbeStream; +#else + lame_t m_lamestate; +#endif +}; + +class LameDecoder +{ + public: + LameDecoder(); + ~LameDecoder(); + + int GetSampleRate() { return m_srate?m_srate:48000; } + int GetNumChannels() { return m_nch?m_nch:1; } + + WDL_HeapBuf m_samples; // we let the size get as big as it needs to, so we don't worry about tons of mallocs/etc + int m_samples_used; + + void *DecodeGetSrcBuffer(int srclen) + { + if (srctmp.GetSize() < srclen) srctmp.Resize(srclen); + return srctmp.Get(); + } + void DecodeWrote(int srclen); + + int GetError() { return errorstat; } + + void Reset(); + + int m_samplesdec; + + private: + WDL_HeapBuf srctmp; + int errorstat; + int m_srate,m_nch; + int m_samples_remove; + +#ifdef USE_LAME_BLADE_API + void *decinst; +#else + lame_t *decinst; +#endif +}; + + + +#endif diff --git a/WDL/libpng/LICENSE b/WDL/libpng/LICENSE new file mode 100644 index 00000000..00787509 --- /dev/null +++ b/WDL/libpng/LICENSE @@ -0,0 +1,111 @@ + +This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +If you modify libpng you may insert additional notices immediately following +this sentence. + +This code is released under the libpng license. + +libpng versions 1.2.6, August 15, 2004, through 1.5.8, February 1, 2012, are +Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.2.5 +with the following individual added to the list of Contributing Authors + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +February 1, 2012 diff --git a/WDL/libpng/README b/WDL/libpng/README new file mode 100644 index 00000000..c9dc29ef --- /dev/null +++ b/WDL/libpng/README @@ -0,0 +1,202 @@ +README for libpng version 1.5.8 - February 1, 2012 (shared library 15.0) +See the note about version numbers near the top of png.h + +See INSTALL for instructions on how to install libpng. + +Libpng comes in several distribution formats. Get libpng-*.tar.gz, +libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings +in the text files, or lpng*.zip if you want DOS-style line endings. + +Version 0.89 was the first official release of libpng. Don't let the +fact that it's the first release fool you. The libpng library has been in +extensive use and testing since mid-1995. By late 1997 it had +finally gotten to the stage where there hadn't been significant +changes to the API in some time, and people have a bad feeling about +libraries with versions < 1.0. Version 1.0.0 was released in +March 1998. + +**** +Note that some of the changes to the png_info structure render this +version of the library binary incompatible with libpng-0.89 or +earlier versions if you are using a shared library. The type of the +"filler" parameter for png_set_filler() has changed from png_byte to +png_uint_32, which will affect shared-library applications that use +this function. + +To avoid problems with changes to the internals of png_info_struct, +new APIs have been made available in 0.95 to avoid direct application +access to info_ptr. These functions are the png_set_ and +png_get_ functions. These functions should be used when +accessing/storing the info_struct data, rather than manipulating it +directly, to avoid such problems in the future. + +It is important to note that the APIs do not make current programs +that access the info struct directly incompatible with the new +library. However, it is strongly suggested that new programs use +the new APIs (as shown in example.c and pngtest.c), and older programs +be converted to the new format, to facilitate upgrades in the future. +**** + +Additions since 0.90 include the ability to compile libpng as a +Windows DLL, and new APIs for accessing data in the info struct. +Experimental functions include the ability to set weighting and cost +factors for row filter selection, direct reads of integers from buffers +on big-endian processors that support misaligned data access, faster +methods of doing alpha composition, and more accurate 16->8 bit color +conversion. + +The additions since 0.89 include the ability to read from a PNG stream +which has had some (or all) of the signature bytes read by the calling +application. This also allows the reading of embedded PNG streams that +do not have the PNG file signature. As well, it is now possible to set +the library action on the detection of chunk CRC errors. It is possible +to set different actions based on whether the CRC error occurred in a +critical or an ancillary chunk. + +The changes made to the library, and bugs fixed are based on discussions +on the PNG-implement mailing list and not on material submitted +privately to Guy, Andreas, or Glenn. They will forward any good +suggestions to the list. + +For a detailed description on using libpng, read libpng-manual.txt. For +examples of libpng in a program, see example.c and pngtest.c. For usage +information and restrictions (what little they are) on libpng, see +png.h. For a description on using zlib (the compression library used by +libpng) and zlib's restrictions, see zlib.h + +I have included a general makefile, as well as several machine and +compiler specific ones, but you may have to modify one for your own needs. + +You should use zlib 1.0.4 or later to run this, but it MAY work with +versions as old as zlib 0.95. Even so, there are bugs in older zlib +versions which can cause the output of invalid compression streams for +some images. You will definitely need zlib 1.0.4 or later if you are +taking advantage of the MS-DOS "far" structure allocation for the small +and medium memory models. You should also note that zlib is a +compression library that is useful for more things than just PNG files. +You can use zlib as a drop-in replacement for fread() and fwrite() if +you are so inclined. + +zlib should be available at the same place that libpng is, or at. +ftp://ftp.info-zip.org/pub/infozip/zlib + +You may also want a copy of the PNG specification. It is available +as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find +these at http://www.libpng.org/pub/png/documents/ + +This code is currently being archived at libpng.sf.net in the +[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) +at GO GRAPHSUP. If you can't find it in any of those places, +e-mail me, and I'll help you find it. + +If you have any code changes, requests, problems, etc., please e-mail +them to me. Also, I'd appreciate any make files or project files, +and any modifications you needed to make to get libpng to compile, +along with a #define variable to tell what compiler/system you are on. +If you needed to add transformations to libpng, or wish libpng would +provide the image in a different way, drop me a note (and code, if +possible), so I can consider supporting the transformation. +Finally, if you get any warning messages when compiling libpng +(note: not zlib), and they are easy to fix, I'd appreciate the +fix. Please mention "libpng" somewhere in the subject line. Thanks. + +This release was created and will be supported by myself (of course +based in a large way on Guy's and Andreas' earlier work), and the PNG +development group. + +Send comments/corrections/commendations to png-mng-implement at +lists.sourceforge.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +You can't reach Guy, the original libpng author, at the addresses +given in previous versions of this document. He and Andreas will +read mail addressed to the png-implement list, however. + +Please do not send general questions about PNG. Send them to +png-mng-misc at lists.sf.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-misc to +subscribe). If you have a question about something +in the PNG specification that is related to using libpng, send it +to me. Send me any questions that start with "I was using libpng, +and ...". If in doubt, send questions to me. I'll bounce them +to others, if necessary. + +Please do not send suggestions on how to change PNG. We have +been discussing PNG for sixteen years now, and it is official and +finished. If you have suggestions for libpng, however, I'll +gladly listen. Even if your suggestion is not used immediately, +it may be used later. + +Files in this distribution: + + ANNOUNCE => Announcement of this version, with recent changes + CHANGES => Description of changes between libpng versions + KNOWNBUG => List of known bugs and deficiencies + LICENSE => License to use and redistribute libpng + README => This file + TODO => Things not implemented in the current library + Y2KINFO => Statement of Y2K compliance + example.c => Example code for using libpng functions + libpng.3 => manual page for libpng (includes libpng-manual.txt) + libpng-manual.txt => Description of libpng and its functions + libpngpf.3 => manual page for libpng's private functions + png.5 => manual page for the PNG format + png.c => Basic interface functions common to library + png.h => Library function and interface declarations (public) + pngpriv.h => Library function and interface declarations (private) + pngconf.h => System specific library configuration (public) + pngstruct.h => png_struct declaration (private) + pnginfo.h => png_info struct declaration (private) + pngdebug.h => debugging macros (private) + pngerror.c => Error/warning message I/O functions + pngget.c => Functions for retrieving info from struct + pngmem.c => Memory handling functions + pngbar.png => PNG logo, 88x31 + pngnow.png => PNG logo, 98x31 + pngpread.c => Progressive reading functions + pngread.c => Read data/helper high-level functions + pngrio.c => Lowest-level data read I/O functions + pngrtran.c => Read data transformation functions + pngrutil.c => Read data utility functions + pngset.c => Functions for storing data into the info_struct + pngtest.c => Library test program + pngtest.png => Library test sample image + pngtrans.c => Common data transformation functions + pngwio.c => Lowest-level write I/O functions + pngwrite.c => High-level write functions + pngwtran.c => Write data transformations + pngwutil.c => Write utility functions + contrib => Contributions + gregbook => source code for PNG reading and writing, from + Greg Roelofs' "PNG: The Definitive Guide", + O'Reilly, 1999 + msvctest => Builds and runs pngtest using a MSVC workspace + pngminus => Simple pnm2png and png2pnm programs + pngsuite => Test images + visupng => Contains a MSVC workspace for VisualPng + projects => Contains project files and workspaces for + building a DLL + cbuilder5 => Contains a Borland workspace for building + libpng and zlib + visualc6 => Contains a Microsoft Visual C++ (MSVC) + workspace for building libpng and zlib + visualc71 => Contains a Microsoft Visual C++ (MSVC) + workspace for building libpng and zlib + xcode => Contains an Apple xcode + workspace for building libpng and zlib + scripts => Directory containing scripts for building libpng: + (see scripts/README.txt for the list of scripts) + +Good luck, and happy coding. + +-Glenn Randers-Pehrson (current maintainer, since 1998) + Internet: glennrp at users.sourceforge.net + +-Andreas Eric Dilger (former maintainer, 1996-1997) + Internet: adilger at enel.ucalgary.ca + Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ + +-Guy Eric Schalnat (original author and former maintainer, 1995-1996) + (formerly of Group 42, Inc) + Internet: gschal at infinet.com diff --git a/WDL/libpng/png.c b/WDL/libpng/png.c new file mode 100644 index 00000000..80e90a8b --- /dev/null +++ b/WDL/libpng/png.c @@ -0,0 +1,2870 @@ + +/* png.c - location for general purpose libpng functions + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef png_libpng_version_1_5_8 Your_png_h_is_not_version_1_5_8; + +/* Tells libpng that we have already handled the first "num_bytes" bytes + * of the PNG file signature. If the PNG data is embedded into another + * stream we can set num_bytes = 8 so that libpng will not attempt to read + * or write any of the magic bytes before it starts on the IHDR. + */ + +#ifdef PNG_READ_SUPPORTED +void PNGAPI +png_set_sig_bytes(png_structp png_ptr, int num_bytes) +{ + png_debug(1, "in png_set_sig_bytes"); + + if (png_ptr == NULL) + return; + + if (num_bytes > 8) + png_error(png_ptr, "Too many bytes for PNG signature"); + + png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); +} + +/* Checks whether the supplied bytes match the PNG signature. We allow + * checking less than the full 8-byte signature so that those apps that + * already read the first few bytes of a file to determine the file type + * can simply check the remaining bytes for extra assurance. Returns + * an integer less than, equal to, or greater than zero if sig is found, + * respectively, to be less than, to match, or be greater than the correct + * PNG signature (this is the same behavior as strcmp, memcmp, etc). + */ +int PNGAPI +png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + + if (num_to_check > 8) + num_to_check = 8; + + else if (num_to_check < 1) + return (-1); + + if (start > 7) + return (-1); + + if (start + num_to_check > 8) + num_to_check = 8 - start; + + return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); +} + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Function to allocate memory for zlib */ +PNG_FUNCTION(voidpf /* PRIVATE */, +png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) +{ + png_voidp ptr; + png_structp p=(png_structp)png_ptr; + png_uint_32 save_flags=p->flags; + png_alloc_size_t num_bytes; + + if (png_ptr == NULL) + return (NULL); + + if (items > PNG_UINT_32_MAX/size) + { + png_warning (p, "Potential overflow in png_zalloc()"); + return (NULL); + } + num_bytes = (png_alloc_size_t)items * size; + + p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); + p->flags=save_flags; + + return ((voidpf)ptr); +} + +/* Function to free memory for zlib */ +void /* PRIVATE */ +png_zfree(voidpf png_ptr, voidpf ptr) +{ + png_free((png_structp)png_ptr, (png_voidp)ptr); +} + +/* Reset the CRC variable to 32 bits of 1's. Care must be taken + * in case CRC is > 32 bits to leave the top bits 0. + */ +void /* PRIVATE */ +png_reset_crc(png_structp png_ptr) +{ + /* The cast is safe because the crc is a 32 bit value. */ + png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); +} + +/* Calculate the CRC over a section of data. We can only pass as + * much data to this routine as the largest single buffer size. We + * also check that this data will actually be used before going to the + * trouble of calculating it. + */ +void /* PRIVATE */ +png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) +{ + int need_crc = 1; + + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + + /* 'uLong' is defined as unsigned long, this means that on some systems it is + * a 64 bit value. crc32, however, returns 32 bits so the following cast is + * safe. 'uInt' may be no more than 16 bits, so it is necessary to perform a + * loop here. + */ + if (need_crc && length > 0) + { + uLong crc = png_ptr->crc; /* Should never issue a warning */ + + do + { + uInt safeLength = (uInt)length; + if (safeLength == 0) + safeLength = (uInt)-1; /* evil, but safe */ + + crc = crc32(crc, ptr, safeLength); + + /* The following should never issue compiler warnings, if they do the + * target system has characteristics that will probably violate other + * assumptions within the libpng code. + */ + ptr += safeLength; + length -= safeLength; + } + while (length > 0); + + /* And the following is always safe because the crc is only 32 bits. */ + png_ptr->crc = (png_uint_32)crc; + } +} + +/* Check a user supplied version number, called from both read and write + * functions that create a png_struct + */ +int +png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver) +{ + if (user_png_ver) + { + int i = 0; + + do + { + if (user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + } + + else + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || + (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) + { +#ifdef PNG_WARNINGS_SUPPORTED + size_t pos = 0; + char m[128]; + + pos = png_safecat(m, sizeof m, pos, "Application built with libpng-"); + pos = png_safecat(m, sizeof m, pos, user_png_ver); + pos = png_safecat(m, sizeof m, pos, " but running with "); + pos = png_safecat(m, sizeof m, pos, png_libpng_ver); + + png_warning(png_ptr, m); +#endif + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags = 0; +#endif + + return 0; + } + } + + /* Success return. */ + return 1; +} + +/* Allocate the memory for an info_struct for the application. We don't + * really need the png_ptr, but it could potentially be useful in the + * future. This should be used in favour of malloc(png_sizeof(png_info)) + * and png_info_init() so that applications that want to use a shared + * libpng don't have to be recompiled if png_info changes size. + */ +PNG_FUNCTION(png_infop,PNGAPI +png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) +{ + png_infop info_ptr; + + png_debug(1, "in png_create_info_struct"); + + if (png_ptr == NULL) + return (NULL); + +#ifdef PNG_USER_MEM_SUPPORTED + info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, + png_ptr->malloc_fn, png_ptr->mem_ptr); +#else + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); +#endif + if (info_ptr != NULL) + png_info_init_3(&info_ptr, png_sizeof(png_info)); + + return (info_ptr); +} + +/* This function frees the memory associated with a single info struct. + * Normally, one would use either png_destroy_read_struct() or + * png_destroy_write_struct() to free an info struct, but this may be + * useful for some applications. + */ +void PNGAPI +png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) +{ + png_infop info_ptr = NULL; + + png_debug(1, "in png_destroy_info_struct"); + + if (png_ptr == NULL) + return; + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + png_info_destroy(png_ptr, info_ptr); + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, + png_ptr->mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } +} + +/* Initialize the info structure. This is now an internal function (0.89) + * and applications using it are urged to use png_create_info_struct() + * instead. + */ + +void PNGAPI +png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) +{ + png_infop info_ptr = *ptr_ptr; + + png_debug(1, "in png_info_init_3"); + + if (info_ptr == NULL) + return; + + if (png_sizeof(png_info) > png_info_struct_size) + { + png_destroy_struct(info_ptr); + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); + *ptr_ptr = info_ptr; + } + + /* Set everything to 0 */ + png_memset(info_ptr, 0, png_sizeof(png_info)); +} + +void PNGAPI +png_data_freer(png_structp png_ptr, png_infop info_ptr, + int freer, png_uint_32 mask) +{ + png_debug(1, "in png_data_freer"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (freer == PNG_DESTROY_WILL_FREE_DATA) + info_ptr->free_me |= mask; + + else if (freer == PNG_USER_WILL_FREE_DATA) + info_ptr->free_me &= ~mask; + + else + png_warning(png_ptr, + "Unknown freer parameter in png_data_freer"); +} + +void PNGAPI +png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, + int num) +{ + png_debug(1, "in png_free_data"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +#ifdef PNG_TEXT_SUPPORTED + /* Free text item num or (if num == -1) all text items */ + if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) + { + if (num != -1) + { + if (info_ptr->text && info_ptr->text[num].key) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + } + + else + { + int i; + for (i = 0; i < info_ptr->num_text; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + info_ptr->num_text=0; + } + } +#endif + +#ifdef PNG_tRNS_SUPPORTED + /* Free any tRNS entry */ + if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->trans_alpha); + info_ptr->trans_alpha = NULL; + info_ptr->valid &= ~PNG_INFO_tRNS; + } +#endif + +#ifdef PNG_sCAL_SUPPORTED + /* Free any sCAL entry */ + if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_height); + info_ptr->scal_s_width = NULL; + info_ptr->scal_s_height = NULL; + info_ptr->valid &= ~PNG_INFO_sCAL; + } +#endif + +#ifdef PNG_pCAL_SUPPORTED + /* Free any pCAL entry */ + if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + info_ptr->pcal_purpose = NULL; + info_ptr->pcal_units = NULL; + if (info_ptr->pcal_params != NULL) + { + int i; + for (i = 0; i < (int)info_ptr->pcal_nparams; i++) + { + png_free(png_ptr, info_ptr->pcal_params[i]); + info_ptr->pcal_params[i] = NULL; + } + png_free(png_ptr, info_ptr->pcal_params); + info_ptr->pcal_params = NULL; + } + info_ptr->valid &= ~PNG_INFO_pCAL; + } +#endif + +#ifdef PNG_iCCP_SUPPORTED + /* Free any iCCP entry */ + if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->iccp_name = NULL; + info_ptr->iccp_profile = NULL; + info_ptr->valid &= ~PNG_INFO_iCCP; + } +#endif + +#ifdef PNG_sPLT_SUPPORTED + /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ + if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) + { + if (num != -1) + { + if (info_ptr->splt_palettes) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + info_ptr->splt_palettes[num].name = NULL; + info_ptr->splt_palettes[num].entries = NULL; + } + } + + else + { + if (info_ptr->splt_palettes_num) + { + int i; + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = NULL; + info_ptr->splt_palettes_num = 0; + } + info_ptr->valid &= ~PNG_INFO_sPLT; + } + } +#endif + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + if (png_ptr->unknown_chunk.data) + { + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + + if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) + { + if (num != -1) + { + if (info_ptr->unknown_chunks) + { + png_free(png_ptr, info_ptr->unknown_chunks[num].data); + info_ptr->unknown_chunks[num].data = NULL; + } + } + + else + { + int i; + + if (info_ptr->unknown_chunks_num) + { + for (i = 0; i < info_ptr->unknown_chunks_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks_num = 0; + } + } + } +#endif + +#ifdef PNG_hIST_SUPPORTED + /* Free any hIST entry */ + if ((mask & PNG_FREE_HIST) & info_ptr->free_me) + { + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; + } +#endif + + /* Free any PLTE entry that was internally allocated */ + if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) + { + png_zfree(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; + info_ptr->num_palette = 0; + } + +#ifdef PNG_INFO_IMAGE_SUPPORTED + /* Free any image bits attached to the info structure */ + if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) + { + if (info_ptr->row_pointers) + { + int row; + for (row = 0; row < (int)info_ptr->height; row++) + { + png_free(png_ptr, info_ptr->row_pointers[row]); + info_ptr->row_pointers[row] = NULL; + } + png_free(png_ptr, info_ptr->row_pointers); + info_ptr->row_pointers = NULL; + } + info_ptr->valid &= ~PNG_INFO_IDAT; + } +#endif + + if (num != -1) + mask &= ~PNG_FREE_MUL; + + info_ptr->free_me &= ~mask; +} + +/* This is an internal routine to free any memory that the info struct is + * pointing to before re-using it or freeing the struct itself. Recall + * that png_free() checks for NULL pointers for us. + */ +void /* PRIVATE */ +png_info_destroy(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_info_destroy"); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list = NULL; + png_ptr->num_chunk_list = 0; + } +#endif + + png_info_init_3(&info_ptr, png_sizeof(png_info)); +} +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +/* This function returns a pointer to the io_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy() or png_read_destroy() are called. + */ +png_voidp PNGAPI +png_get_io_ptr(png_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return (png_ptr->io_ptr); +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +# ifdef PNG_STDIO_SUPPORTED +/* Initialize the default input/output functions for the PNG file. If you + * use your own read or write routines, you can call either png_set_read_fn() + * or png_set_write_fn() instead of png_init_io(). If you have defined + * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a + * function of your own because "FILE *" isn't necessarily available. + */ +void PNGAPI +png_init_io(png_structp png_ptr, png_FILE_p fp) +{ + png_debug(1, "in png_init_io"); + + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = (png_voidp)fp; +} +# endif + +# ifdef PNG_TIME_RFC1123_SUPPORTED +/* Convert the supplied time into an RFC 1123 string suitable for use in + * a "Creation Time" or other text-based time string. + */ +png_const_charp PNGAPI +png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) +{ + static PNG_CONST char short_months[12][4] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + if (png_ptr == NULL) + return (NULL); + + if (ptime->year > 9999 /* RFC1123 limitation */ || + ptime->month == 0 || ptime->month > 12 || + ptime->day == 0 || ptime->day > 31 || + ptime->hour > 23 || ptime->minute > 59 || + ptime->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + return (NULL); + } + + { + size_t pos = 0; + char number_buf[5]; /* enough for a four-digit year */ + +# define APPEND_STRING(string)\ + pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\ + pos, (string)) +# define APPEND_NUMBER(format, value)\ + APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) +# define APPEND(ch)\ + if (pos < (sizeof png_ptr->time_buffer)-1)\ + png_ptr->time_buffer[pos++] = (ch) + + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); + APPEND(' '); + APPEND_STRING(short_months[(ptime->month - 1)]); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); + APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ + +# undef APPEND +# undef APPEND_NUMBER +# undef APPEND_STRING + } + + return png_ptr->time_buffer; +} +# endif /* PNG_TIME_RFC1123_SUPPORTED */ + +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +png_const_charp PNGAPI +png_get_copyright(png_const_structp png_ptr) +{ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef PNG_STRING_COPYRIGHT + return PNG_STRING_COPYRIGHT +#else +# ifdef __STDC__ + return PNG_STRING_NEWLINE \ + "libpng version 1.5.8 - February 1, 2012" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ + "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ + "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ + PNG_STRING_NEWLINE; +# else + return "libpng version 1.5.8 - February 1, 2012\ + Copyright (c) 1998-2011 Glenn Randers-Pehrson\ + Copyright (c) 1996-1997 Andreas Dilger\ + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; +# endif +#endif +} + +/* The following return the library version as a short string in the + * format 1.0.0 through 99.99.99zz. To get the version of *.h files + * used with your application, print out PNG_LIBPNG_VER_STRING, which + * is defined in png.h. + * Note: now there is no difference between png_get_libpng_ver() and + * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, + * it is guaranteed that png.c uses the correct version of png.h. + */ +png_const_charp PNGAPI +png_get_libpng_ver(png_const_structp png_ptr) +{ + /* Version of *.c files used when building libpng */ + return png_get_header_ver(png_ptr); +} + +png_const_charp PNGAPI +png_get_header_ver(png_const_structp png_ptr) +{ + /* Version of *.h files used when building libpng */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ + return PNG_LIBPNG_VER_STRING; +} + +png_const_charp PNGAPI +png_get_header_version(png_const_structp png_ptr) +{ + /* Returns longer string containing both version and date */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef __STDC__ + return PNG_HEADER_VERSION_STRING +# ifndef PNG_READ_SUPPORTED + " (NO READ SUPPORT)" +# endif + PNG_STRING_NEWLINE; +#else + return PNG_HEADER_VERSION_STRING; +#endif +} + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) +{ + /* Check chunk_name and return "keep" value if it's on the list, else 0 */ + png_const_bytep p, p_end; + + if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0) + return PNG_HANDLE_CHUNK_AS_DEFAULT; + + p_end = png_ptr->chunk_list; + p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ + + /* The code is the fifth byte after each four byte string. Historically this + * code was always searched from the end of the list, so it should continue + * to do so in case there are duplicated entries. + */ + do /* num_chunk_list > 0, so at least one */ + { + p -= 5; + if (!png_memcmp(chunk_name, p, 4)) + return p[4]; + } + while (p > p_end); + + return PNG_HANDLE_CHUNK_AS_DEFAULT; +} + +int /* PRIVATE */ +png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name) +{ + png_byte chunk_string[5]; + + PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); + return png_handle_as_unknown(png_ptr, chunk_string); +} +#endif + +#ifdef PNG_READ_SUPPORTED +/* This function, added to libpng-1.0.6g, is untested. */ +int PNGAPI +png_reset_zstream(png_structp png_ptr) +{ + if (png_ptr == NULL) + return Z_STREAM_ERROR; + + return (inflateReset(&png_ptr->zstream)); +} +#endif /* PNG_READ_SUPPORTED */ + +/* This function was added to libpng-1.0.7 */ +png_uint_32 PNGAPI +png_access_version_number(void) +{ + /* Version of *.c files used when building libpng */ + return((png_uint_32)PNG_LIBPNG_VER); +} + + + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* png_convert_size: a PNGAPI but no longer in png.h, so deleted + * at libpng 1.5.5! + */ + +/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ +# ifdef PNG_CHECK_cHRM_SUPPORTED + +int /* PRIVATE */ +png_check_cHRM_fixed(png_structp png_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) +{ + int ret = 1; + unsigned long xy_hi,xy_lo,yx_hi,yx_lo; + + png_debug(1, "in function png_check_cHRM_fixed"); + + if (png_ptr == NULL) + return 0; + + /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white + * y must also be greater than 0. To test for the upper limit calculate + * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression + * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is + * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it + * pointless (and it produces compiler warnings!) + */ + if (white_x < 0 || white_y <= 0 || + red_x < 0 || red_y < 0 || + green_x < 0 || green_y < 0 || + blue_x < 0 || blue_y < 0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + ret = 0; + } + /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ + if (white_x > PNG_FP_1 - white_y) + { + png_warning(png_ptr, "Invalid cHRM white point"); + ret = 0; + } + + if (red_x > PNG_FP_1 - red_y) + { + png_warning(png_ptr, "Invalid cHRM red point"); + ret = 0; + } + + if (green_x > PNG_FP_1 - green_y) + { + png_warning(png_ptr, "Invalid cHRM green point"); + ret = 0; + } + + if (blue_x > PNG_FP_1 - blue_y) + { + png_warning(png_ptr, "Invalid cHRM blue point"); + ret = 0; + } + + png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); + png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); + + if (xy_hi == yx_hi && xy_lo == yx_lo) + { + png_warning(png_ptr, + "Ignoring attempt to set cHRM RGB triangle with zero area"); + ret = 0; + } + + return ret; +} +# endif /* PNG_CHECK_cHRM_SUPPORTED */ + +#ifdef PNG_cHRM_SUPPORTED +/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for + * cHRM, as opposed to using chromaticities. These internal APIs return + * non-zero on a parameter error. The X, Y and Z values are required to be + * positive and less than 1.0. + */ +int png_xy_from_XYZ(png_xy *xy, png_XYZ XYZ) +{ + png_int_32 d, dwhite, whiteX, whiteY; + + d = XYZ.redX + XYZ.redY + XYZ.redZ; + if (!png_muldiv(&xy->redx, XYZ.redX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->redy, XYZ.redY, PNG_FP_1, d)) return 1; + dwhite = d; + whiteX = XYZ.redX; + whiteY = XYZ.redY; + + d = XYZ.greenX + XYZ.greenY + XYZ.greenZ; + if (!png_muldiv(&xy->greenx, XYZ.greenX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->greeny, XYZ.greenY, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ.greenX; + whiteY += XYZ.greenY; + + d = XYZ.blueX + XYZ.blueY + XYZ.blueZ; + if (!png_muldiv(&xy->bluex, XYZ.blueX, PNG_FP_1, d)) return 1; + if (!png_muldiv(&xy->bluey, XYZ.blueY, PNG_FP_1, d)) return 1; + dwhite += d; + whiteX += XYZ.blueX; + whiteY += XYZ.blueY; + + /* The reference white is simply the same of the end-point (X,Y,Z) vectors, + * thus: + */ + if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1; + if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1; + + return 0; +} + +int png_XYZ_from_xy(png_XYZ *XYZ, png_xy xy) +{ + png_fixed_point red_inverse, green_inverse, blue_scale; + png_fixed_point left, right, denominator; + + /* Check xy and, implicitly, z. Note that wide gamut color spaces typically + * have end points with 0 tristimulus values (these are impossible end + * points, but they are used to cover the possible colors.) + */ + if (xy.redx < 0 || xy.redx > PNG_FP_1) return 1; + if (xy.redy < 0 || xy.redy > PNG_FP_1-xy.redx) return 1; + if (xy.greenx < 0 || xy.greenx > PNG_FP_1) return 1; + if (xy.greeny < 0 || xy.greeny > PNG_FP_1-xy.greenx) return 1; + if (xy.bluex < 0 || xy.bluex > PNG_FP_1) return 1; + if (xy.bluey < 0 || xy.bluey > PNG_FP_1-xy.bluex) return 1; + if (xy.whitex < 0 || xy.whitex > PNG_FP_1) return 1; + if (xy.whitey < 0 || xy.whitey > PNG_FP_1-xy.whitex) return 1; + + /* The reverse calculation is more difficult because the original tristimulus + * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 + * derived values were recorded in the cHRM chunk; + * (red,green,blue,white)x(x,y). This loses one degree of freedom and + * therefore an arbitrary ninth value has to be introduced to undo the + * original transformations. + * + * Think of the original end-points as points in (X,Y,Z) space. The + * chromaticity values (c) have the property: + * + * C + * c = --------- + * X + Y + Z + * + * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the + * three chromaticity values (x,y,z) for each end-point obey the + * relationship: + * + * x + y + z = 1 + * + * This describes the plane in (X,Y,Z) space that intersects each axis at the + * value 1.0; call this the chromaticity plane. Thus the chromaticity + * calculation has scaled each end-point so that it is on the x+y+z=1 plane + * and chromaticity is the intersection of the vector from the origin to the + * (X,Y,Z) value with the chromaticity plane. + * + * To fully invert the chromaticity calculation we would need the three + * end-point scale factors, (red-scale, green-scale, blue-scale), but these + * were not recorded. Instead we calculated the reference white (X,Y,Z) and + * recorded the chromaticity of this. The reference white (X,Y,Z) would have + * given all three of the scale factors since: + * + * color-C = color-c * color-scale + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * But cHRM records only white-x and white-y, so we have lost the white scale + * factor: + * + * white-C = white-c*white-scale + * + * To handle this the inverse transformation makes an arbitrary assumption + * about white-scale: + * + * Assume: white-Y = 1.0 + * Hence: white-scale = 1/white-y + * Or: red-Y + green-Y + blue-Y = 1.0 + * + * Notice the last statement of the assumption gives an equation in three of + * the nine values we want to calculate. 8 more equations come from the + * above routine as summarised at the top above (the chromaticity + * calculation): + * + * Given: color-x = color-X / (color-X + color-Y + color-Z) + * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 + * + * This is 9 simultaneous equations in the 9 variables "color-C" and can be + * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix + * determinants, however this is not as bad as it seems because only 28 of + * the total of 90 terms in the various matrices are non-zero. Nevertheless + * Cramer's rule is notoriously numerically unstable because the determinant + * calculation involves the difference of large, but similar, numbers. It is + * difficult to be sure that the calculation is stable for real world values + * and it is certain that it becomes unstable where the end points are close + * together. + * + * So this code uses the perhaps slighly less optimal but more understandable + * and totally obvious approach of calculating color-scale. + * + * This algorithm depends on the precision in white-scale and that is + * (1/white-y), so we can immediately see that as white-y approaches 0 the + * accuracy inherent in the cHRM chunk drops off substantially. + * + * libpng arithmetic: a simple invertion of the above equations + * ------------------------------------------------------------ + * + * white_scale = 1/white-y + * white-X = white-x * white-scale + * white-Y = 1.0 + * white-Z = (1 - white-x - white-y) * white_scale + * + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * This gives us three equations in (red-scale,green-scale,blue-scale) where + * all the coefficients are now known: + * + * red-x*red-scale + green-x*green-scale + blue-x*blue-scale + * = white-x/white-y + * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 + * red-z*red-scale + green-z*green-scale + blue-z*blue-scale + * = (1 - white-x - white-y)/white-y + * + * In the last equation color-z is (1 - color-x - color-y) so we can add all + * three equations together to get an alternative third: + * + * red-scale + green-scale + blue-scale = 1/white-y = white-scale + * + * So now we have a Cramer's rule solution where the determinants are just + * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve + * multiplication of three coefficients so we can't guarantee to avoid + * overflow in the libpng fixed point representation. Using Cramer's rule in + * floating point is probably a good choice here, but it's not an option for + * fixed point. Instead proceed to simplify the first two equations by + * eliminating what is likely to be the largest value, blue-scale: + * + * blue-scale = white-scale - red-scale - green-scale + * + * Hence: + * + * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = + * (white-x - blue-x)*white-scale + * + * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = + * 1 - blue-y*white-scale + * + * And now we can trivially solve for (red-scale,green-scale): + * + * green-scale = + * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale + * ----------------------------------------------------------- + * green-x - blue-x + * + * red-scale = + * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale + * --------------------------------------------------------- + * red-y - blue-y + * + * Hence: + * + * red-scale = + * ( (green-x - blue-x) * (white-y - blue-y) - + * (green-y - blue-y) * (white-x - blue-x) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * green-scale = + * ( (red-y - blue-y) * (white-x - blue-x) - + * (red-x - blue-x) * (white-y - blue-y) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * Accuracy: + * The input values have 5 decimal digits of accuracy. The values are all in + * the range 0 < value < 1, so simple products are in the same range but may + * need up to 10 decimal digits to preserve the original precision and avoid + * underflow. Because we are using a 32-bit signed representation we cannot + * match this; the best is a little over 9 decimal digits, less than 10. + * + * The approach used here is to preserve the maximum precision within the + * signed representation. Because the red-scale calculation above uses the + * difference between two products of values that must be in the range -1..+1 + * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The + * factor is irrelevant in the calculation because it is applied to both + * numerator and denominator. + * + * Note that the values of the differences of the products of the + * chromaticities in the above equations tend to be small, for example for + * the sRGB chromaticities they are: + * + * red numerator: -0.04751 + * green numerator: -0.08788 + * denominator: -0.2241 (without white-y multiplication) + * + * The resultant Y coefficients from the chromaticities of some widely used + * color space definitions are (to 15 decimal places): + * + * sRGB + * 0.212639005871510 0.715168678767756 0.072192315360734 + * Kodak ProPhoto + * 0.288071128229293 0.711843217810102 0.000085653960605 + * Adobe RGB + * 0.297344975250536 0.627363566255466 0.075291458493998 + * Adobe Wide Gamut RGB + * 0.258728243040113 0.724682314948566 0.016589442011321 + */ + /* By the argument, above overflow should be impossible here. The return + * value of 2 indicates an internal error to the caller. + */ + if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.redy - xy.bluey, 7)) return 2; + if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.redx - xy.bluex, 7)) return 2; + denominator = left - right; + + /* Now find the red numerator. */ + if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; + if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; + + /* Overflow is possible here and it indicates an extreme set of PNG cHRM + * chunk values. This calculation actually returns the reciprocal of the + * scale value because this allows us to delay the multiplication of white-y + * into the denominator, which tends to produce a small number. + */ + if (!png_muldiv(&red_inverse, xy.whitey, denominator, left-right) || + red_inverse <= xy.whitey /* r+g+b scales = white scale */) + return 1; + + /* Similarly for green_inverse: */ + if (!png_muldiv(&left, xy.redy-xy.bluey, xy.whitex-xy.bluex, 7)) return 2; + if (!png_muldiv(&right, xy.redx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2; + if (!png_muldiv(&green_inverse, xy.whitey, denominator, left-right) || + green_inverse <= xy.whitey) + return 1; + + /* And the blue scale, the checks above guarantee this can't overflow but it + * can still produce 0 for extreme cHRM values. + */ + blue_scale = png_reciprocal(xy.whitey) - png_reciprocal(red_inverse) - + png_reciprocal(green_inverse); + if (blue_scale <= 0) return 1; + + + /* And fill in the png_XYZ: */ + if (!png_muldiv(&XYZ->redX, xy.redx, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->redY, xy.redy, PNG_FP_1, red_inverse)) return 1; + if (!png_muldiv(&XYZ->redZ, PNG_FP_1 - xy.redx - xy.redy, PNG_FP_1, + red_inverse)) + return 1; + + if (!png_muldiv(&XYZ->greenX, xy.greenx, PNG_FP_1, green_inverse)) return 1; + if (!png_muldiv(&XYZ->greenY, xy.greeny, PNG_FP_1, green_inverse)) return 1; + if (!png_muldiv(&XYZ->greenZ, PNG_FP_1 - xy.greenx - xy.greeny, PNG_FP_1, + green_inverse)) + return 1; + + if (!png_muldiv(&XYZ->blueX, xy.bluex, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blueY, xy.bluey, blue_scale, PNG_FP_1)) return 1; + if (!png_muldiv(&XYZ->blueZ, PNG_FP_1 - xy.bluex - xy.bluey, blue_scale, + PNG_FP_1)) + return 1; + + return 0; /*success*/ +} + +int png_XYZ_from_xy_checked(png_structp png_ptr, png_XYZ *XYZ, png_xy xy) +{ + switch (png_XYZ_from_xy(XYZ, xy)) + { + case 0: /* success */ + return 1; + + case 1: + /* The chunk may be technically valid, but we got png_fixed_point + * overflow while trying to get XYZ values out of it. This is + * entirely benign - the cHRM chunk is pretty extreme. + */ + png_warning(png_ptr, + "extreme cHRM chunk cannot be converted to tristimulus values"); + break; + + default: + /* libpng is broken; this should be a warning but if it happens we + * want error reports so for the moment it is an error. + */ + png_error(png_ptr, "internal error in png_XYZ_from_xy"); + break; + } + + /* ERROR RETURN */ + return 0; +} +#endif + +void /* PRIVATE */ +png_check_IHDR(png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + int error = 0; + + /* Check for width and height valid values */ + if (width == 0) + { + png_warning(png_ptr, "Image width is zero in IHDR"); + error = 1; + } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max) + +# else + if (width > PNG_USER_WIDTH_MAX) +# endif + { + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); + error = 1; + } + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (height > png_ptr->user_height_max) +# else + if (height > PNG_USER_HEIGHT_MAX) +# endif + { + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); + error = 1; + } + + if (width > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + + if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + + if (width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 48 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + png_warning(png_ptr, "Width is too large for libpng to process pixels"); + + /* Check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && + bit_depth != 8 && bit_depth != 16) + { + png_warning(png_ptr, "Invalid bit depth in IHDR"); + error = 1; + } + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + { + png_warning(png_ptr, "Invalid color type in IHDR"); + error = 1; + } + + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || + ((color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) + { + png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); + error = 1; + } + + if (interlace_type >= PNG_INTERLACE_LAST) + { + png_warning(png_ptr, "Unknown interlace method in IHDR"); + error = 1; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Unknown compression method in IHDR"); + error = 1; + } + +# ifdef PNG_MNG_FEATURES_SUPPORTED + /* Accept filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not read a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && + png_ptr->mng_features_permitted) + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + + if (filter_type != PNG_FILTER_TYPE_BASE) + { + if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } + + if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) + { + png_warning(png_ptr, "Invalid filter method in IHDR"); + error = 1; + } + } + +# else + if (filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } +# endif + + if (error == 1) + png_error(png_ptr, "Invalid IHDR data"); +} + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* ASCII to fp functions */ +/* Check an ASCII formated floating point value, see the more detailed + * comments in pngpriv.h + */ +/* The following is used internally to preserve the sticky flags */ +#define png_fp_add(state, flags) ((state) |= (flags)) +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) + +int /* PRIVATE */ +png_check_fp_number(png_const_charp string, png_size_t size, int *statep, + png_size_tp whereami) +{ + int state = *statep; + png_size_t i = *whereami; + + while (i < size) + { + int type; + /* First find the type of the next character */ + switch (string[i]) + { + case 43: type = PNG_FP_SAW_SIGN; break; + case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; + case 46: type = PNG_FP_SAW_DOT; break; + case 48: type = PNG_FP_SAW_DIGIT; break; + case 49: case 50: case 51: case 52: + case 53: case 54: case 55: case 56: + case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; + case 69: + case 101: type = PNG_FP_SAW_E; break; + default: goto PNG_FP_End; + } + + /* Now deal with this type according to the current + * state, the type is arranged to not overlap the + * bits of the PNG_FP_STATE. + */ + switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) + { + case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, type); + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DOT: + /* Ok as trailer, ok as lead of fraction. */ + if (state & PNG_FP_SAW_DOT) /* two dots */ + goto PNG_FP_End; + + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ + png_fp_add(state, type); + + else + png_fp_set(state, PNG_FP_FRACTION | type); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + png_fp_add(state, type | PNG_FP_WAS_VALID); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_E: + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: + goto PNG_FP_End; ** no sign in fraction */ + + /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: + goto PNG_FP_End; ** Because SAW_DOT is always set */ + + case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: + png_fp_add(state, type | PNG_FP_WAS_VALID); + break; + + case PNG_FP_FRACTION + PNG_FP_SAW_E: + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); + + break; + + /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: + goto PNG_FP_End; */ + + case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); + + break; + + /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: + goto PNG_FP_End; */ + + default: goto PNG_FP_End; /* I.e. break 2 */ + } + + /* The character seems ok, continue. */ + ++i; + } + +PNG_FP_End: + /* Here at the end, update the state and return the correct + * return code. + */ + *statep = state; + *whereami = i; + + return (state & PNG_FP_SAW_DIGIT) != 0; +} + + +/* The same but for a complete string. */ +int +png_check_fp_string(png_const_charp string, png_size_t size) +{ + int state=0; + png_size_t char_index=0; + + if (png_check_fp_number(string, size, &state, &char_index) && + (char_index == size || string[char_index] == 0)) + return state /* must be non-zero - see above */; + + return 0; /* i.e. fail */ +} +#endif /* pCAL or sCAL */ + +#ifdef PNG_READ_sCAL_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +/* Utility used below - a simple accurate power of ten from an integral + * exponent. + */ +static double +png_pow10(int power) +{ + int recip = 0; + double d = 1; + + /* Handle negative exponent with a reciprocal at the end because + * 10 is exact whereas .1 is inexact in base 2 + */ + if (power < 0) + { + if (power < DBL_MIN_10_EXP) return 0; + recip = 1, power = -power; + } + + if (power > 0) + { + /* Decompose power bitwise. */ + double mult = 10; + do + { + if (power & 1) d *= mult; + mult *= mult; + power >>= 1; + } + while (power > 0); + + if (recip) d = 1/d; + } + /* else power is 0 and d is 1 */ + + return d; +} + +/* Function to format a floating point value in ASCII with a given + * precision. + */ +void /* PRIVATE */ +png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, + double fp, unsigned int precision) +{ + /* We use standard functions from math.h, but not printf because + * that would require stdio. The caller must supply a buffer of + * sufficient size or we will png_error. The tests on size and + * the space in ascii[] consumed are indicated below. + */ + if (precision < 1) + precision = DBL_DIG; + + /* Enforce the limit of the implementation precision too. */ + if (precision > DBL_DIG+1) + precision = DBL_DIG+1; + + /* Basic sanity checks */ + if (size >= precision+5) /* See the requirements below. */ + { + if (fp < 0) + { + fp = -fp; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ + --size; + } + + if (fp >= DBL_MIN && fp <= DBL_MAX) + { + int exp_b10; /* A base 10 exponent */ + double base; /* 10^exp_b10 */ + + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp_b10); /* exponent to base 2 */ + + exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ + + /* Avoid underflow here. */ + base = png_pow10(exp_b10); /* May underflow */ + + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp_b10+1); + + if (test <= DBL_MAX) + ++exp_b10, base = test; + + else + break; + } + + /* Normalize fp and correct exp_b10, after this fp is in the + * range [.1,1) and exp_b10 is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp_b10 is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) fp /= 10, ++exp_b10; + + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ + + { + int czero, clead, cdigits; + char exponent[10]; + + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ + { + czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ + exp_b10 = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ + + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + + do + { + double d; + + fp *= 10; + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero-clead+1 < (int)precision) + fp = modf(fp, &d); + + else + { + d = floor(fp + .5); + + if (d > 9) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero, d = 1; + if (cdigits == 0) --clead; + } + else + { + while (cdigits > 0 && d > 9) + { + int ch = *--ascii; + + if (exp_b10 != (-1)) + ++exp_b10; + + else if (ch == 46) + { + ch = *--ascii, ++size; + /* Advance exp_b10 to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp_b10 = 1; + } + + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } + + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9) /* cdigits == 0 */ + { + if (exp_b10 == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + + if (ch == 46) + ++size, exp_b10 = 1; + + /* Else lost a leading zero, so 'exp_b10' is + * still ok at (-1) + */ + } + else + ++exp_b10; + + /* In all cases we output a '1' */ + d = 1; + } + } + } + fp = 0; /* Guarantees termination below. */ + } + + if (d == 0) + { + ++czero; + if (cdigits == 0) ++clead; + } + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; + + while (czero > 0) + { + /* exp_b10 == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp_b10' any + * more! + */ + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) *ascii++ = 46, --size; + /* PLUS 1: TOTAL 4 */ + --exp_b10; + } + *ascii++ = 48, --czero; + } + + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) *ascii++ = 46, --size; /* counted + above */ + --exp_b10; + } + *ascii++ = (char)(48 + (int)d), ++cdigits; + } + } + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + + /* The total output count (max) is now 4+precision */ + + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At + * this point exp_b10==(-1) is effectively if flag - it got + * to '-1' because of the decrement after outputing + * the decimal point above (the exponent required is + * *not* -1!) + */ + if (exp_b10 >= (-1) && exp_b10 <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doest add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (--exp_b10 >= 0) *ascii++ = 48; + + *ascii = 0; + + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } + + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; + + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ + + /* The following use of an unsigned temporary avoids ambiguities in + * the signed arithmetic on exp_b10 and permits GCC at least to do + * better optimization. + */ + { + unsigned int uexp_b10; + + if (exp_b10 < 0) + { + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ + uexp_b10 = -exp_b10; + } + + else + uexp_b10 = exp_b10; + + cdigits = 0; + + while (uexp_b10 > 0) + { + exponent[cdigits++] = (char)(48 + uexp_b10 % 10); + uexp_b10 /= 10; + } + } + + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if ((int)size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + + *ascii = 0; + + return; + } + } + } + else if (!(fp >= DBL_MIN)) + { + *ascii++ = 48; /* '0' */ + *ascii = 0; + return; + } + else + { + *ascii++ = 105; /* 'i' */ + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} + +# endif /* FLOATING_POINT */ + +# ifdef PNG_FIXED_POINT_SUPPORTED +/* Function to format a fixed point value in ASCII. + */ +void /* PRIVATE */ +png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, + png_fixed_point fp) +{ + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: + */ + if (size > 12) + { + png_uint_32 num; + + /* Avoid overflow here on the minimum integer. */ + if (fp < 0) + *ascii++ = 45, --size, num = -fp; + else + num = fp; + + if (num <= 0x80000000) /* else overflowed */ + { + unsigned int ndigits = 0, first = 16 /* flag value */; + char digits[10]; + + while (num) + { + /* Split the low digit off num: */ + unsigned int tmp = num/10; + num -= tmp*10; + digits[ndigits++] = (char)(48 + num); + /* Record the first non-zero digit, note that this is a number + * starting at 1, it's not actually the array index. + */ + if (first == 16 && num > 0) + first = ndigits; + num = tmp; + } + + if (ndigits > 0) + { + while (ndigits > 5) *ascii++ = digits[--ndigits]; + /* The remaining digits are fractional digits, ndigits is '5' or + * smaller at this point. It is certainly not zero. Check for a + * non-zero fractional digit: + */ + if (first <= 5) + { + unsigned int i; + *ascii++ = 46; /* decimal point */ + /* ndigits may be <5 for small numbers, output leading zeros + * then ndigits digits to first: + */ + i = 5; + while (ndigits < i) *ascii++ = 48, --i; + while (ndigits >= first) *ascii++ = digits[--ndigits]; + /* Don't output the trailing zeros! */ + } + } + else + *ascii++ = 48; + + /* And null terminate the string: */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FIXED_POINT */ +#endif /* READ_SCAL */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) +png_fixed_point +png_fixed(png_structp png_ptr, double fp, png_const_charp text) +{ + double r = floor(100000 * fp + .5); + + if (r > 2147483647. || r < -2147483648.) + png_fixed_error(png_ptr, text); + + return (png_fixed_point)r; +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || \ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) +/* muldiv functions */ +/* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to + * the nearest .00001). Overflow and divide by zero are signalled in + * the result, a boolean - true on success, false on overflow. + */ +int +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, + png_int_32 divisor) +{ + /* Return a * times / divisor, rounded. */ + if (divisor != 0) + { + if (a == 0 || times == 0) + { + *res = 0; + return 1; + } + else + { +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a; + r *= times; + r /= divisor; + r = floor(r+.5); + + /* A png_fixed_point is a 32-bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } +#else + int negative = 0; + png_uint_32 A, T, D; + png_uint_32 s16, s32, s00; + + if (a < 0) + negative = 1, A = -a; + else + A = a; + + if (times < 0) + negative = !negative, T = -times; + else + T = times; + + if (divisor < 0) + negative = !negative, D = -divisor; + else + D = divisor; + + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + s00 = (A & 0xffff) * (T & 0xffff); + + s16 = (s16 & 0xffff) << 16; + s00 += s16; + + if (s00 < s16) + ++s32; /* carry */ + + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64-bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ + + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + + else + d32 = 0, d00 = D; + + if (s32 > d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) + ++result; + + if (negative) + result = -result; + + /* Check for overflow. */ + if ((negative && result <= 0) || (!negative && result >= 0)) + { + *res = result; + return 1; + } + } +#endif + } + } + + return 0; +} +#endif /* READ_GAMMA || INCH_CONVERSIONS */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* The following is for when the caller doesn't much care about the + * result. + */ +png_fixed_point +png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, + png_int_32 divisor) +{ + png_fixed_point result; + + if (png_muldiv(&result, a, times, divisor)) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; +} +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ +png_fixed_point +png_reciprocal(png_fixed_point a) +{ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(1E10/a+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, 100000, 100000, a)) + return res; +#endif + + return 0; /* error/overflow */ +} + +/* A local convenience routine. */ +static png_fixed_point +png_product2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, a, b, 100000)) + return res; +#endif + + return 0; /* overflow */ +} + +/* The inverse of the above. */ +png_fixed_point +png_reciprocal2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = 1E15/a; + r /= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + /* This may overflow because the range of png_fixed_point isn't symmetric, + * but this API is only used for the product of file and screen gamma so it + * doesn't matter that the smallest number it can produce is 1/21474, not + * 1/100000 + */ + png_fixed_point res = png_product2(a, b); + + if (res != 0) + return png_reciprocal(res); +#endif + + return 0; /* overflow */ +} +#endif /* READ_GAMMA */ + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, + * 2010: moved from pngset.c) */ +/* + * Multiply two 32-bit numbers, V1 and V2, using 32-bit + * arithmetic, to produce a 64-bit result in the HI/LO words. + * + * A B + * x C D + * ------ + * AD || BD + * AC || CB || 0 + * + * where A and B are the high and low 16-bit words of V1, + * C and D are the 16-bit words of V2, AD is the product of + * A and D, and X || Y is (X << 16) + Y. +*/ + +void /* PRIVATE */ +png_64bit_product (long v1, long v2, unsigned long *hi_product, + unsigned long *lo_product) +{ + int a, b, c, d; + long lo, hi, x, y; + + a = (v1 >> 16) & 0xffff; + b = v1 & 0xffff; + c = (v2 >> 16) & 0xffff; + d = v2 & 0xffff; + + lo = b * d; /* BD */ + x = a * d + c * b; /* AD + CB */ + y = ((lo >> 16) & 0xffff) + x; + + lo = (lo & 0xffff) | ((y & 0xffff) << 16); + hi = (y >> 16) & 0xffff; + + hi += a * c; /* AC */ + + *hi_product = (unsigned long)hi; + *lo_product = (unsigned long)lo; +} +#endif /* CHECK_cHRM */ + +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8-bit + * or 16-bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double + * precision floating point arithmetic would work fine. The programs are given + * at the head of each table. + * + * 8-bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8-bit floating point + * mantissa. The numbers are 32-bit fractions. + */ +static png_uint_32 +png_8bit_l2[128] = +{ +# ifdef PNG_DO_BC + for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } +# else + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U +# endif + +#if 0 + /* The following are the values for 16-bit tables - these work fine for the + * 8-bit conversions but produce very slightly larger errors in the 16-bit + * log (about 1.2 as opposed to 0.7 absolute error in the final value). To + * use these all the shifts below must be adjusted appropriately. + */ + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, + 1119, 744, 372 +#endif +}; + +PNG_STATIC png_int_32 +png_log8bit(unsigned int x) +{ + unsigned int lg2 = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 + * input), return 7.99998 for the overflow (log 0) case - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) + return 0xffffffff; + + if ((x & 0xf0) == 0) + lg2 = 4, x <<= 4; + + if ((x & 0xc0) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x80) == 0) + lg2 += 1, x <<= 1; + + /* result is at most 19 bits, so this cast is safe: */ + return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); +} + +/* The above gives exact (to 16 binary places) log2 values for 8-bit images, + * for 16-bit images we use the most significant 8 bits of the 16-bit value to + * get an approximation then multiply the approximation by a correction factor + * determined by the remaining up to 8 bits. This requires an additional step + * in the 16-bit case. + * + * We want log2(value/65535), we have log2(v'/255), where: + * + * value = v' * 256 + v'' + * = v' * f + * + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less + * than 258. The final factor also needs to correct for the fact that our 8-bit + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. + * + * This gives a final formula using a calculated value 'x' which is value/v' and + * scaling by 65536 to match the above table: + * + * log2(x/257) * 65536 + * + * Since these numbers are so close to '1' we can use simple linear + * interpolation between the two end values 256/257 (result -368.61) and 258/257 + * (result 367.179). The values used below are scaled by a further 64 to give + * 16-bit precision in the interpolation: + * + * Start (256): -23591 + * Zero (257): 0 + * End (258): 23499 + */ +PNG_STATIC png_int_32 +png_log16bit(png_uint_32 x) +{ + unsigned int lg2 = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) + return 0xffffffff; + + if ((x & 0xff00) == 0) + lg2 = 8, x <<= 8; + + if ((x & 0xf000) == 0) + lg2 += 4, x <<= 4; + + if ((x & 0xc000) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x8000) == 0) + lg2 += 1, x <<= 1; + + /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional + * value. + */ + lg2 <<= 28; + lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; + + /* Now we need to interpolate the factor, this requires a division by the top + * 8 bits. Do this with maximum precision. + */ + x = ((x << 16) + (x >> 9)) / (x >> 8); + + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly + * 16 bits to interpolate to get the low bits of the result. Round the + * answer. Note that the end point values are scaled by 64 to retain overall + * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust + * the overall scaling by 6-12. Round at every step. + */ + x -= 1U << 24; + + if (x <= 65536U) /* <= '257' */ + lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); + + else + lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); + + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((lg2 + 2048) >> 12); +} + +/* The 'exp()' case must invert the above, taking a 20-bit fixed point + * logarithmic value and returning a 16 or 8-bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * + * The worst case is the 16-bit distinction between 65535 and 65534, this + * requires perhaps spurious accuracy in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * + * To deal with this the following exp() function works out the exponent of the + * frational part of the logarithm by using an accurate 32-bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +static png_uint_32 +png_32bit_exp[16] = +{ +# ifdef PNG_DO_BC + for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } +# else + /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, + 2553802834U, 2445529972U, 2341847524U, 2242560872U +# endif +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#ifdef PNG_DO_BC +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 + 9 45303.31936980687359311872 + 8 45364.65110595323018870784 + 7 45395.35850361789624614912 + 6 45410.72259715102037508096 + 5 45418.40724413220722311168 + 4 45422.25021786898173001728 + 3 45424.17186732298419044352 + 2 45425.13273269940811464704 + 1 45425.61317555035558641664 + 0 45425.85339951654943850496 +#endif + +PNG_STATIC png_uint_32 +png_exp(png_fixed_point x) +{ + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ + { + /* Obtain a 4-bit approximation */ + png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; + + /* Incorporate the low 12 bits - these decrease the returned value by + * multiplying by a number less than 1 if the bit is set. The multiplier + * is determined by the above table and the shift. Notice that the values + * converge on 45426 and this is used to allow linear interpolation of the + * low bits. + */ + if (x & 0x800) + e -= (((e >> 16) * 44938U) + 16U) >> 5; + + if (x & 0x400) + e -= (((e >> 16) * 45181U) + 32U) >> 6; + + if (x & 0x200) + e -= (((e >> 16) * 45303U) + 64U) >> 7; + + if (x & 0x100) + e -= (((e >> 16) * 45365U) + 128U) >> 8; + + if (x & 0x080) + e -= (((e >> 16) * 45395U) + 256U) >> 9; + + if (x & 0x040) + e -= (((e >> 16) * 45410U) + 512U) >> 10; + + /* And handle the low 6 bits in a single block. */ + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; + + /* Handle the upper bits of x. */ + e >>= x >> 16; + return e; + } + + /* Check for overflow */ + if (x <= 0) + return png_32bit_exp[0]; + + /* Else underflow */ + return 0; +} + +PNG_STATIC png_byte +png_exp8bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ + x -= x >> 8; + return (png_byte)((x + 0x7fffffU) >> 24); +} + +PNG_STATIC png_uint_16 +png_exp16bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ + x -= x >> 16; + return (png_uint_16)((x + 32767U) >> 16); +} +#endif /* FLOATING_ARITHMETIC */ + +png_byte +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 255) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); + return (png_byte)r; +# else + png_int_32 lg2 = png_log8bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) + return png_exp8bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_byte)value; +} + +png_uint_16 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 65535) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); + return (png_uint_16)r; +# else + png_int_32 lg2 = png_log16bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) + return png_exp16bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_uint_16)value; +} + +/* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8-bit or 16-bit. While the result + * is nominally a 16-bit value if bit depth is 8 then the result is + * 8-bit (as are the arguments.) + */ +png_uint_16 /* PRIVATE */ +png_gamma_correct(png_structp png_ptr, unsigned int value, + png_fixed_point gamma_val) +{ + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma_val); + + else + return png_gamma_16bit_correct(value, gamma_val); +} + +/* This is the shared test on whether a gamma value is 'significant' - whether + * it is worth doing gamma correction. + */ +int /* PRIVATE */ +png_gamma_significant(png_fixed_point gamma_val) +{ + return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || + gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; +} + +/* Internal function to build a single 16-bit table - the table consists of + * 'num' 256-entry subtables, where 'num' is determined by 'shift' - the amount + * to shift the input values right (or 16-number_of_signifiant_bits). + * + * The caller is responsible for ensuring that the table gets cleaned up on + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument + * should be somewhere that will be cleaned. + */ +static void +png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) +{ + /* Various values derived from 'shift': */ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int i; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = + (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); + + /* The 'threshold' test is repeated here because it can arise for one of + * the 16-bit tables even if the others don't hit it. + */ + if (png_gamma_significant(gamma_val)) + { + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an + * arithmetic error. This code follows the spec exactly; ig is + * the recovered input sample, it always has 8-16 bits. + * + * We want input * 65535/max, rounded, the arithmetic fits in 32 + * bits (unsigned) so long as max <= 32767. + */ + unsigned int j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ + double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); + sub_table[j] = (png_uint_16)d; +# else + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); +# endif + } + } + else + { + /* We must still build a table, but do it the fast way. */ + unsigned int j; + + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = (png_uint_16)ig; + } + } + } +} + +/* NOTE: this function expects the *inverse* of the overall gamma transformation + * required. + */ +static void +png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) +{ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + unsigned int i; + png_uint_32 last; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + /* 'num' is the number of tables and also the number of low bits of the + * input 16-bit value used to select a table. Each table is itself indexed + * by the high 8 bits of the value. + */ + for (i = 0; i < num; i++) + table[i] = (png_uint_16p)png_malloc(png_ptr, + 256 * png_sizeof(png_uint_16)); + + /* 'gamma_val' is set to the reciprocal of the value calculated above, so + * pow(out,g) is an *input* value. 'last' is the last input value set. + * + * In the loop 'i' is used to find output values. Since the output is + * 8-bit there are only 256 possible values. The tables are set up to + * select the closest possible output value for each input by finding + * the input value at the boundary between each pair of output values + * and filling the table up to that boundary with the lower output + * value. + * + * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit + * values the code below uses a 16-bit value in i; the values start at + * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last + * entries are filled with 255). Start i at 128 and fill all 'last' + * table entries <= 'max' + */ + last = 0; + for (i = 0; i < 255; ++i) /* 8-bit output value */ + { + /* Find the corresponding maximum input value */ + png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ + + /* Find the boundary value in 16 bits: */ + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); + + /* Adjust (round) to (16-shift) bits: */ + bound = (bound * max + 32768U)/65535U + 1U; + + while (last < bound) + { + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; + } + } + + /* And fill in the final entries. */ + while (last < (num << 8)) + { + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; + last++; + } +} + +/* Build a single 8-bit table: same as the 16-bit case but much simpler (and + * typically much faster). Note that libpng currently does no sBIT processing + * (apparently contrary to the spec) so a 256-entry table is always generated. + */ +static void +png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, + PNG_CONST png_fixed_point gamma_val) +{ + unsigned int i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + + if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) + table[i] = png_gamma_8bit_correct(i, gamma_val); + + else for (i=0; i<256; ++i) + table[i] = (png_byte)i; +} + +/* Used from png_read_destroy and below to release the memory used by the gamma + * tables. + */ +void /* PRIVATE */ +png_destroy_gamma_table(png_structp png_ptr) +{ + png_free(png_ptr, png_ptr->gamma_table); + png_ptr->gamma_table = NULL; + + if (png_ptr->gamma_16_table != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_table[i]); + } + png_free(png_ptr, png_ptr->gamma_16_table); + png_ptr->gamma_16_table = NULL; + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_from_1); + png_ptr->gamma_from_1 = NULL; + png_free(png_ptr, png_ptr->gamma_to_1); + png_ptr->gamma_to_1 = NULL; + + if (png_ptr->gamma_16_from_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_from_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_from_1); + png_ptr->gamma_16_from_1 = NULL; + } + if (png_ptr->gamma_16_to_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_to_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_to_1); + png_ptr->gamma_16_to_1 = NULL; + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +} + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * the future. Note also how the gamma_16 tables are segmented so that + * we don't need to allocate > 64K chunks for a full 16-bit table. + */ +void /* PRIVATE */ +png_build_gamma_table(png_structp png_ptr, int bit_depth) +{ + png_debug(1, "in png_build_gamma_table"); + + /* Remove any existing table; this copes with multiple calls to + * png_read_update_info. The warning is because building the gamma tables + * multiple times is a performance hit - it's harmless but the ability to call + * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible + * to warn if the app introduces such a hit. + */ + if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) + { + png_warning(png_ptr, "gamma table being rebuilt"); + png_destroy_gamma_table(png_ptr); + } + + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, + png_reciprocal(png_ptr->gamma)); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } + else + { + png_byte shift, sig_bit; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = png_ptr->sig_bit.red; + + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + sig_bit = png_ptr->sig_bit.gray; + + /* 16-bit gamma code uses this equation: + * + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] + * + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * + * Thus the gamma table consists of up to 256 256-entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits of + * the color value then indexed by the upper 8 bits: + * + * table[low bits][high 8 bits] + * + * So the table 'n' corresponds to all those 'iv' of: + * + * ..<(n+1 << gamma_shift)-1> + * + */ + if (sig_bit > 0 && sig_bit < 16U) + shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ + + else + shift = 0; /* keep all 16 bits */ + + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } + + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ + + png_ptr->gamma_shift = shift; + +#ifdef PNG_16BIT_SUPPORTED + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now + * PNG_COMPOSE). This effectively smashed the background calculation for + * 16-bit output because the 8-bit table assumes the result will be reduced + * to 8 bits. + */ + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) +#endif + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#ifdef PNG_16BIT_SUPPORTED + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->gamma)); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. + * TODO: fix this. + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } +} +#endif /* READ_GAMMA */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/WDL/libpng/png.h b/WDL/libpng/png.h new file mode 100644 index 00000000..98bb8a9d --- /dev/null +++ b/WDL/libpng/png.h @@ -0,0 +1,2654 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.5.8 - February 1, 2012 + * Copyright (c) 1998-2012 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license (See LICENSE, below) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.5.8 - February 1, 2012: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 12.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 12.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-7 13 10210 12.so.0.10[.0] + * 1.2.10rc1-2 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.4.0beta1-5 14 10400 14.so.0.0[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.4.0beta7-8 14 10400 14.so.0.0[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.4.0beta9-14 14 10400 14.so.0.0[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.4.0beta15-36 14 10400 14.so.0.0[.0] + * 1.4.0beta37-87 14 10400 14.so.14.0[.0] + * 1.4.0rc01 14 10400 14.so.14.0[.0] + * 1.4.0beta88-109 14 10400 14.so.14.0[.0] + * 1.4.0rc02-08 14 10400 14.so.14.0[.0] + * 1.4.0 14 10400 14.so.14.0[.0] + * 1.4.1beta01-03 14 10401 14.so.14.1[.0] + * 1.4.1rc01 14 10401 14.so.14.1[.0] + * 1.4.1beta04-12 14 10401 14.so.14.1[.0] + * 1.4.1 14 10401 14.so.14.1[.0] + * 1.4.2 14 10402 14.so.14.2[.0] + * 1.4.3 14 10403 14.so.14.3[.0] + * 1.4.4 14 10404 14.so.14.4[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] + * 1.5.1beta01-11 15 10501 15.so.15.1[.0] + * 1.5.1rc01-02 15 10501 15.so.15.1[.0] + * 1.5.1 15 10501 15.so.15.1[.0] + * 1.5.2beta01-03 15 10502 15.so.15.2[.0] + * 1.5.2rc01-03 15 10502 15.so.15.2[.0] + * 1.5.2 15 10502 15.so.15.2[.0] + * 1.5.3beta01-10 15 10503 15.so.15.3[.0] + * 1.5.3rc01-02 15 10503 15.so.15.3[.0] + * 1.5.3beta11 15 10503 15.so.15.3[.0] + * 1.5.3 [omitted] + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] + * 1.5.5beta01-08 15 10505 15.so.15.5[.0] + * 1.5.5rc01 15 10505 15.so.15.5[.0] + * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-07 15 10506 15.so.15.6[.0] + * 1.5.6rc01-03 15 10506 15.so.15.6[.0] + * 1.5.6 15 10506 15.so.15.6[.0] + * 1.5.7beta01-05 15 10507 15.so.15.7[.0] + * 1.5.7rc01-03 15 10507 15.so.15.7[.0] + * 1.5.7 15 10507 15.so.15.7[.0] + * 1.5.8beta01 15 10508 15.so.15.8[.0] + * 1.5.8rc01 15 10508 15.so.15.8[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng-manual.txt or libpng.3 for more information. The PNG + * specification is available as a W3C Recommendation and as an ISO + * Specification, +# endif + + /* Need the time information for converting tIME chunks, it + * defines struct tm: + */ +# ifdef PNG_CONVERT_tIME_SUPPORTED + /* "time.h" functions are not supported on all operating systems */ +# include +# endif +# endif + +/* Machine specific configuration. */ +# include "pngconf.h" +#endif + +/* + * Added at libpng-1.2.8 + * + * Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# ifdef PNG_LIBPNG_SPECIALBUILD +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#define png_libpng_ver png_get_header_ver(NULL) + +/* This file is arranged in several sections: + * + * 1. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ +/* Section 1: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 2: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char* png_libpng_version_1_5_8; + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color FAR * png_colorp; +typedef PNG_CONST png_color FAR * png_const_colorp; +typedef png_color FAR * FAR * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 FAR * png_color_16p; +typedef PNG_CONST png_color_16 FAR * png_const_color_16p; +typedef png_color_16 FAR * FAR * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 FAR * png_color_8p; +typedef PNG_CONST png_color_8 FAR * png_const_color_8p; +typedef png_color_8 FAR * FAR * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry FAR * png_sPLT_entryp; +typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp; +typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t FAR * png_sPLT_tp; +typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp; +typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text" fields can be a + * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain + * the "text" field as a regular zero-terminated C string (possibly + * empty), never a NULL pointer, so it can be safely used in printf() and + * other string-handling functions. Note that the "itxt_length", "lang", and + * "lang_key" members of the structure only exist when the library is built + * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by + * default without iTXt support. Also note that when iTXt *is* supported, + * the "lang" and "lang_key" fields contain NULL pointers when the + * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or + * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the + * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" + * which is always 0 or 1, or its "compression method" which is always 0. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +} png_text; +typedef png_text FAR * png_textp; +typedef PNG_CONST png_text FAR * png_const_textp; +typedef png_text FAR * FAR * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time FAR * png_timep; +typedef PNG_CONST png_time FAR * png_const_timep; +typedef png_time FAR * FAR * png_timepp; + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; + png_byte *data; + png_size_t size; + + /* libpng-using applications should NOT directly modify this byte. */ + png_byte location; /* mode of operation at read time */ +} + + +png_unknown_chunk; +typedef png_unknown_chunk FAR * png_unknown_chunkp; +typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; +#endif + +/* Values for the unknown chunk location byte */ + +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* The complete definition of png_info has, as of libpng-1.5.0, + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_info_def png_info; +typedef png_info FAR * png_infop; +typedef PNG_CONST png_info FAR * png_const_infop; +typedef png_info FAR * FAR * png_infopp; + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) + +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 +#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) +#define PNG_FP_MIN (-PNG_FP_MAX) + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_ defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* The complete definition of png_struct has, as of libpng-1.5.0, + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_struct_def png_struct; +typedef PNG_CONST png_struct FAR * png_const_structp; +typedef png_struct FAR * png_structp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, + png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in , and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +typedef png_struct FAR * FAR * png_structpp; + +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_const_structp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, + png_size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), + PNG_ALLOCATED); + +PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structp png_ptr, png_infop info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structp png_ptr, png_infop info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED +PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, + (png_structp png_ptr, + png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + PNG_CONST struct tm FAR * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, + (png_timep ptime, time_t ttime)); +#endif /* PNG_CONVERT_tIME_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, + int error_action, double red, double green)); +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)); + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp + png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels of + * a PNG file are returned when an alpha channel, or tRNS chunk in a palette + * file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel. The gamma encoded color channels must be + * scaled according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. The + * advantage is that the color channels can be resampled (the image can be + * scaled) in this form. The disadvantage is that normal practice is to store + * linear, not (gamma) encoded, values and this requires 16-bit channels for + * still images rather than the 8-bit channels that are just about sufficient if + * gamma encoding is used. In addition all non-transparent pixel values, + * including completely opaque ones, must be gamma encoded to produce the final + * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the + * latter being the two common names for associated alpha color channels.) + * + * Since it is not necessary to perform arithmetic on opaque color values so + * long as they are not to be resampled and are in the final color space it is + * possible to optimize the handling of alpha by storing the opaque pixels in + * the PNG format (adjusted for the output color space) while storing partially + * opaque pixels in the standard, linear, format. The accuracy required for + * standard alpha composition is relatively low, because the pixels are + * isolated, therefore typically the accuracy loss in storing 8-bit linear + * values is acceptable. (This is not true if the alpha channel is used to + * simulate transparency over large areas - use 16 bits or the PNG mode in + * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is + * treated as opaque only if the alpha value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode, + double output_gamma)); +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr, + int mode, png_fixed_point output_gamma)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. The values used + * correspond to the normal numbers used to describe the overall gamma of a + * computer display system; for example 2.2 for an sRGB conformant system. The + * values are scaled by 100000 in the _fixed version of the API (so 220000 for + * sRGB.) + * + * The inverse of the value is always used to provide a default for the PNG file + * encoding if it has no gAMA chunk and if png_set_gamma() has not been called + * to override the PNG gamma information. + * + * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode + * opaque pixels however pixels with lower alpha values are not encoded, + * regardless of the output gamma setting. + * + * When the standard Porter Duff handling is requested with mode 1 the output + * encoding is set to be linear and the output_gamma value is only relevant + * as a default for input data that has no gamma information. The linear output + * encoding will be overridden if png_set_gamma() is called - the results may be + * highly unexpected! + * + * The following numbers are derived from the sRGB standard and the research + * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of + * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing + * correction required to take account of any differences in the color + * environment of the original scene and the intended display environment; the + * value expresses how to *decode* the image for display, not how the original + * data was *encoded*. + * + * sRGB provides a peg for the PNG standard by defining a viewing environment. + * sRGB itself, and earlier TV standards, actually use a more complex transform + * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is + * limited to simple power laws.) By saying that an image for direct display on + * an sRGB conformant system should be stored with a gAMA chunk value of 45455 + * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification + * makes it possible to derive values for other display systems and + * environments. + * + * The Mac value is deduced from the sRGB based on an assumption that the actual + * extra viewing correction used in early Mac display systems was implemented as + * a power 1.45 lookup table. + * + * Any system where a programmable lookup table is used or where the behavior of + * the final display device characteristics can be changed requires system + * specific code to obtain the current characteristic. However this can be + * difficult and most PNG gamma correction only requires an approximate value. + * + * By default, if png_set_alpha_mode() is not called, libpng assumes that all + * values are unencoded, linear, values and that the output device also has a + * linear characteristic. This is only very rarely correct - it is invariably + * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the + * default if you don't know what the right answer is! + * + * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS + * 10.6) which used a correction table to implement a somewhat lower gamma on an + * otherwise sRGB system. + * + * Both these values are reserved (not simple gamma values) in order to allow + * more precise correction internally in the future. + * + * NOTE: the following values can be passed to either the fixed or floating + * point APIs, but the floating point API will also accept floating point + * values. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceeded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(39, void, png_set_filler, (png_structp png_ptr, png_uint_32 filler, + int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(40, void, png_set_add_alpha, + (png_structp png_ptr, png_uint_32 filler, + int flags)); +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p + true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)); +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, + (png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, + (png_structp png_ptr, double screen_gamma, + double override_file_gamma)); +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)); +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, + png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, + (png_structp png_ptr, png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, + (png_structp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, + (png_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, + (png_structp png_ptr, int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +PNG_EXPORT(67, void, png_set_filter, + (png_structp png_ptr, int method, int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)); +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_fixed_point_p + filter_weights, png_const_fixed_point_p filter_costs)); +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +#ifdef PNG_WRITE_SUPPORTED +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +PNG_EXPORT(69, void, png_set_compression_level, + (png_structp png_ptr, int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, + int method)); +#endif + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, + (png_structp png_ptr, int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp + png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr, + int method)); +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +PNG_EXPORT(75, void, png_set_error_fn, + (png_structp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +PNG_EXPORT(82, void, png_set_mem_fn, (png_structp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, + (png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PNG_READ_INTERLACING_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +PNG_EXPORTA(94, png_voidp, png_malloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, + (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +PNG_EXPORT(99, void, png_data_freer, + (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); + +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, + (png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, + png_const_charp warning_message)); +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +# undef png_benign_error +PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); + +/* Same, chunk name is prepended to message. */ +# undef png_chunk_benign_error +PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, + (png_const_structp png_ptr, png_const_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr, + png_const_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structp png_ptr, png_const_infop info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, + (png_const_structp png_ptr, png_infop info_ptr)); + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, + (png_const_structp png_ptr, png_infop info_ptr, + png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr, + png_const_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_structp png_ptr, + png_const_infop info_ptr, double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, double *blue_X, + double *blue_Y, double *blue_Z)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structp png_ptr, + png_const_infop info_ptr, png_fixed_point *int_white_x, + png_fixed_point *int_white_y, png_fixed_point *int_red_x, + png_fixed_point *int_red_y, png_fixed_point *int_green_x, + png_fixed_point *int_green_y, png_fixed_point *int_blue_x, + png_fixed_point *int_blue_y)); +#endif +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, png_set_cHRM, + (png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y)); +PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_structp png_ptr, + png_infop info_ptr, double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, double blue_X, + double blue_Y, double blue_Z)); +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, + (png_const_structp png_ptr, png_const_infop info_ptr, + double *file_gamma)); +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_file_gamma)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, + png_infop info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, + int *interlace_method, int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, png_set_IHDR, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, + int interlace_method, int compression_method, int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, + (png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, + int *nparams, + png_charp *units, png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, + png_infop info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, + (png_structp png_ptr, png_infop info_ptr, + png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, + (png_const_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, + (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr, + png_const_infop info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, + (png_structp png_ptr, png_infop info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, + png_infop info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_charpp name, int *compression_type, png_bytepp profile, + png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, + (png_structp png_ptr, png_infop info_ptr, + png_const_charp name, int compression_type, png_const_bytep profile, + png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, png_uint_32, png_get_sPLT, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, + (png_structp png_ptr, png_infop info_ptr, + png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, png_uint_32, png_get_text, + (png_const_structp png_ptr, png_const_infop info_ptr, + png_textp *text_ptr, int *num_text)); +#endif + +/* Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, + (png_structp png_ptr, png_infop info_ptr, + png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, + (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, + (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, + (png_const_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, + (png_structp png_ptr, png_infop info_ptr, + png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, + (png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, double *width, double *height)); +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_structp png_ptr, png_const_infop info_ptr, int *unit, + png_fixed_point *width, + png_fixed_point *height)); +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, + (png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height)); +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, + png_infop info_ptr, int unit, png_fixed_point width, + png_fixed_point height)); +PNG_EXPORT(171, void, png_set_sCAL_s, + (png_structp png_ptr, png_infop info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight)); +#endif /* PNG_sCAL_SUPPORTED */ + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +/* Provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. Because this turns off the default handling for chunks + that would otherwise be recognized the behavior of libpng transformations may + well become incorrect! + keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior + = 1: PNG_HANDLE_CHUNK_NEVER: do not keep + = 2: PNG_HANDLE_CHUNK_IF_SAFE: keep only if safe-to-copy + = 3: PNG_HANDLE_CHUNK_ALWAYS: keep even if unsafe-to-copy +*/ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, + (png_structp png_ptr, int keep, + png_const_bytep chunk_list, int num_chunks)); + +/* The handling code is returned; the result is therefore true (non-zero) if + * special handling is required, false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, + png_const_bytep chunk_name)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, + png_infop info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr, + png_const_infop info_ptr, png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +PNG_EXPORT(177, void, png_set_invalid, + (png_structp png_ptr, png_infop info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); +PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr, + png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +PNG_EXPORT(185, void, png_set_strip_error_numbers, + (png_structp png_ptr, + png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structp png_ptr, png_const_infop info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structp png_ptr, png_const_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_structp png_ptr, png_const_infop info_ptr)); +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr, + png_const_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_structp png_ptr, png_const_infop info_ptr)); +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr, + png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); + +PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name, + (png_structp png_ptr), PNG_DEPRECATED); +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ + (((yIn)<>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535) +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, + png_const_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define png_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define png_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define png_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) +#endif + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) Maintainer, remember to add an entry to + * scripts/symbols.def as well. + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(233); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/WDL/libpng/pngconf.h b/WDL/libpng/pngconf.h new file mode 100644 index 00000000..f68c8d7c --- /dev/null +++ b/WDL/libpng/pngconf.h @@ -0,0 +1,596 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.5.8 - February 1, 2012 + * + * Copyright (c) 1998-2012 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C + * definition file for machine specific limits, this may impact the + * correctness of the definitons below (see uses of INT_MAX). + */ +# ifndef PNG_NO_LIMITS_H +# include +# endif + +/* For the memory copy APIs (i.e. the standard definitions of these), + * because this file defines png_memcpy and so on the base APIs must + * be defined here. + */ +# ifdef BSD +# include +# else +# include +# endif + +/* For png_FILE_p - this provides the standard definition of a + * FILE + */ +# ifdef PNG_STDIO_SUPPORTED +# include +# endif +#endif + +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used to the function is called. + * The library builder sets the default, if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +# ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +# else + +# ifdef _NO_PROTO +# define PNGARG(arglist) () +# else +# define PNGARG(arglist) arglist +# endif /* _NO_PROTO */ + +# endif /* OF */ + +#endif /* PNGARG */ + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows/x86 systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ + ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ + defined(_M_X64) || defined(_M_IA64) ) + /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes + * builds under Cygwin or MinGW. Also includes Watcom builds but these need + * special treatment because they are not compatible with GCC or Visual C + * because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) + ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows/x86 */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA + +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ + extern attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. + */ +# if defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# endif /* __GNUC__ */ + +# if defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# endif /* _MSC_VER */ +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + * + * This should not change how the APIs are called, so it can be done + * on a per-file basis in the application. + */ +#ifndef PNG_CONST +# ifndef PNG_NO_CONST +# define PNG_CONST const +# else +# define PNG_CONST +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. + */ + +#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL) +typedef unsigned int png_uint_32; +typedef int png_int_32; +#else +typedef unsigned long png_uint_32; +typedef long png_int_32; +#endif +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +#ifdef PNG_NO_SIZE_T +typedef unsigned int png_size_t; +#else +typedef size_t png_size_t; +#endif +#define png_sizeof(x) (sizeof (x)) + +/* The following is needed for medium model support. It cannot be in the + * pngpriv.h header. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + * defines FAR. (SJT) + */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K /* only used in build */ +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#ifdef FAR +# ifdef M_I86MM +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + * to fixed-point with a multiple of 100,000, e.g., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef PNG_CONST void FAR * png_const_voidp; +typedef png_byte FAR * png_bytep; +typedef PNG_CONST png_byte FAR * png_const_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef PNG_CONST png_int_32 FAR * png_const_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST png_int_16 FAR * png_const_int_16p; +typedef char FAR * png_charp; +typedef PNG_CONST char FAR * png_const_charp; +typedef png_fixed_point FAR * png_fixed_point_p; +typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; +typedef png_size_t FAR * png_size_tp; +typedef PNG_CONST png_size_t FAR * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +typedef PNG_CONST double FAR * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, + * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 + * to png_alloc_size_t are not necessary; in fact, it is recommended + * not to use them at all so that the compiler can complain when something + * turns out to be problematic. + * Casts in the other direction (from png_alloc_size_t to png_size_t or + * png_uint_32) should be explicitly applied; however, we do not expect + * to encounter practical situations that require such conversions. + */ +#if defined(__TURBOC__) && !defined(__FLAT__) + typedef unsigned long png_alloc_size_t; +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + typedef unsigned long png_alloc_size_t; +# else + /* This is an attempt to detect an old Windows system where (int) is + * actually 16 bits, in that case png_malloc must have an argument with a + * bigger size to accomodate the requirements of the library. + */ +# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \ + (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL) + typedef DWORD png_alloc_size_t; +# else + typedef png_size_t png_alloc_size_t; +# endif +# endif +#endif + +#endif /* PNGCONF_H */ diff --git a/WDL/libpng/pngdebug.h b/WDL/libpng/pngdebug.h new file mode 100644 index 00000000..96c1ea42 --- /dev/null +++ b/WDL/libpng/pngdebug.h @@ -0,0 +1,157 @@ + +/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c + * + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + * + * png_debug[1-2]?(level, message ,arg{0-2}) + * Expands to a statement (either a simple expression or a compound + * do..while(0) statement) that outputs a message with parameter + * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG + * is undefined, 0 or 1 every png_debug expands to a simple expression + * (actually ((void)0)). + * + * level: level of detail of message, starting at 0. A level 'n' + * message is preceded by 'n' tab characters (not implemented + * on Microsoft compilers unless PNG_DEBUG_FILE is also + * defined, to allow debug DLL compilation with no standard IO). + * message: a printf(3) style text string. A trailing '\n' is added + * to the message. + * arg: 0 to 2 arguments for printf(3) style substitution in message. + */ +#ifndef PNGDEBUG_H +#define PNGDEBUG_H +/* These settings control the formatting of messages in png.c and pngerror.c */ +/* Moved to pngdebug.h at 1.5.0 */ +# ifndef PNG_LITERAL_SHARP +# define PNG_LITERAL_SHARP 0x23 +# endif +# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET +# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b +# endif +# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET +# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d +# endif +# ifndef PNG_STRING_NEWLINE +# define PNG_STRING_NEWLINE "\n" +# endif + +#ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +# include +# if (PNG_DEBUG > 1) +# ifndef _DEBUG +# define _DEBUG +# endif +# ifndef png_debug +# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) +# endif +# endif +# else /* PNG_DEBUG_FILE || !_MSC_VER */ +# ifndef PNG_STDIO_SUPPORTED +# include /* not included yet */ +# endif +# ifndef PNG_DEBUG_FILE +# define PNG_DEBUG_FILE stderr +# endif /* PNG_DEBUG_FILE */ + +# if (PNG_DEBUG > 1) +/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on + * non-ISO compilers + */ +# ifdef __STDC__ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ + } while (0) +# endif +# else /* __STDC __ */ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1,p2); \ + } while (0) +# endif +# endif /* __STDC __ */ +# endif /* (PNG_DEBUG > 1) */ + +# endif /* _MSC_VER */ +# endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +# define png_debug(l, m) ((void)0) +#endif +#ifndef png_debug1 +# define png_debug1(l, m, p1) ((void)0) +#endif +#ifndef png_debug2 +# define png_debug2(l, m, p1, p2) ((void)0) +#endif +#endif /* PNGDEBUG_H */ diff --git a/WDL/libpng/pngerror.c b/WDL/libpng/pngerror.c new file mode 100644 index 00000000..f3154071 --- /dev/null +++ b/WDL/libpng/pngerror.c @@ -0,0 +1,685 @@ + +/* pngerror.c - stub functions for i/o and memory allocation + * + * Last changed in libpng 1.5.7 [February 1, 2012] + * Copyright (c) 1998-2012 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all error handling. Users who + * need special error handling are expected to write replacement functions + * and use png_set_error_fn() to use those functions. See the instructions + * at each function. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, + png_const_charp error_message)),PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +static void /* PRIVATE */ +png_default_warning PNGARG((png_structp png_ptr, + png_const_charp warning_message)); +#endif /* PNG_WARNINGS_SUPPORTED */ + +/* This function is called whenever there is a fatal error. This function + * should not be changed. If there is a need to handle errors differently, + * you should supply a replacement error function and use png_set_error_fn() + * to replace the error function at run-time. + */ +#ifdef PNG_ERROR_TEXT_SUPPORTED +PNG_FUNCTION(void,PNGAPI +png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) +{ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + char msg[16]; + if (png_ptr != NULL) + { + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) + { + if (*error_message == PNG_LITERAL_SHARP) + { + /* Strip "#nnnn " from beginning of error message. */ + int offset; + for (offset = 1; offset<15; offset++) + if (error_message[offset] == ' ') + break; + + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + int i; + for (i = 0; i < offset - 1; i++) + msg[i] = error_message[i + 1]; + msg[i - 1] = '\0'; + error_message = msg; + } + + else + error_message += offset; + } + + else + { + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + msg[0] = '0'; + msg[1] = '\0'; + error_message = msg; + } + } + } + } +#endif + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_ptr, error_message); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, error_message); +} +#else +PNG_FUNCTION(void,PNGAPI +png_err,(png_structp png_ptr),PNG_NORETURN) +{ + /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed + * erroneously as '\0', instead of the empty string "". This was + * apparently an error, introduced in libpng-1.2.20, and png_default_error + * will crash in this case. + */ + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_ptr, ""); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, ""); +} +#endif /* PNG_ERROR_TEXT_SUPPORTED */ + +/* Utility to safely appends strings to a buffer. This never errors out so + * error checking is not required in the caller. + */ +size_t +png_safecat(png_charp buffer, size_t bufsize, size_t pos, + png_const_charp string) +{ + if (buffer != NULL && pos < bufsize) + { + if (string != NULL) + while (*string != '\0' && pos < bufsize-1) + buffer[pos++] = *string++; + + buffer[pos] = '\0'; + } + + return pos; +} + +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. + */ +png_charp +png_format_number(png_const_charp start, png_charp end, int format, + png_alloc_size_t number) +{ + int count = 0; /* number of digits output */ + int mincount = 1; /* minimum number required */ + int output = 0; /* digit output (for the fixed point format) */ + + *--end = '\0'; + + /* This is written so that the loop always runs at least once, even with + * number zero. + */ + while (end > start && (number != 0 || count < mincount)) + { + + static const char digits[] = "0123456789ABCDEF"; + + switch (format) + { + case PNG_NUMBER_FORMAT_fixed: + /* Needs five digits (the fraction) */ + mincount = 5; + if (output || number % 10 != 0) + { + *--end = digits[number % 10]; + output = 1; + } + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02u: + /* Expects at least 2 digits. */ + mincount = 2; + /* fall through */ + + case PNG_NUMBER_FORMAT_u: + *--end = digits[number % 10]; + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02x: + /* This format expects at least two digits */ + mincount = 2; + /* fall through */ + + case PNG_NUMBER_FORMAT_x: + *--end = digits[number & 0xf]; + number >>= 4; + break; + + default: /* an error */ + number = 0; + break; + } + + /* Keep track of the number of digits added */ + ++count; + + /* Float a fixed number here: */ + if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start) + { + /* End of the fraction, but maybe nothing was output? In that case + * drop the decimal point. If the number is a true zero handle that + * here. + */ + if (output) + *--end = '.'; + else if (number == 0) /* and !output */ + *--end = '0'; + } + } + + return end; +} +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* This function is called whenever there is a non-fatal error. This function + * should not be changed. If there is a need to handle warnings differently, + * you should supply a replacement warning function and use + * png_set_error_fn() to replace the warning function at run-time. + */ +void PNGAPI +png_warning(png_structp png_ptr, png_const_charp warning_message) +{ + int offset = 0; + if (png_ptr != NULL) + { +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) +#endif + { + if (*warning_message == PNG_LITERAL_SHARP) + { + for (offset = 1; offset < 15; offset++) + if (warning_message[offset] == ' ') + break; + } + } + } + if (png_ptr != NULL && png_ptr->warning_fn != NULL) + (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); + else + png_default_warning(png_ptr, warning_message + offset); +} + +/* These functions support 'formatted' warning messages with up to + * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter + * is introduced by @, where 'number' starts at 1. This follows the + * standard established by X/Open for internationalizable error messages. + */ +void +png_warning_parameter(png_warning_parameters p, int number, + png_const_charp string) +{ + if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) + (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); +} + +void +png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, + png_alloc_size_t value) +{ + char buffer[PNG_NUMBER_BUFFER_SIZE]; + png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); +} + +void +png_warning_parameter_signed(png_warning_parameters p, int number, int format, + png_int_32 value) +{ + png_alloc_size_t u; + png_charp str; + char buffer[PNG_NUMBER_BUFFER_SIZE]; + + /* Avoid overflow by doing the negate in a png_alloc_size_t: */ + u = (png_alloc_size_t)value; + if (value < 0) + u = ~u + 1; + + str = PNG_FORMAT_NUMBER(buffer, format, u); + + if (value < 0 && str > buffer) + *--str = '-'; + + png_warning_parameter(p, number, str); +} + +void +png_formatted_warning(png_structp png_ptr, png_warning_parameters p, + png_const_charp message) +{ + /* The internal buffer is just 192 bytes - enough for all our messages, + * overflow doesn't happen because this code checks! If someone figures + * out how to send us a message longer than 192 bytes, all that will + * happen is that the message will be truncated appropriately. + */ + size_t i = 0; /* Index in the msg[] buffer: */ + char msg[192]; + + /* Each iteration through the following loop writes at most one character + * to msg[i++] then returns here to validate that there is still space for + * the trailing '\0'. It may (in the case of a parameter) read more than + * one character from message[]; it must check for '\0' and continue to the + * test if it finds the end of string. + */ + while (i<(sizeof msg)-1 && *message != '\0') + { + /* '@' at end of string is now just printed (previously it was skipped); + * it is an error in the calling code to terminate the string with @. + */ + if (p != NULL && *message == '@' && message[1] != '\0') + { + int parameter_char = *++message; /* Consume the '@' */ + static const char valid_parameters[] = "123456789"; + int parameter = 0; + + /* Search for the parameter digit, the index in the string is the + * parameter to use. + */ + while (valid_parameters[parameter] != parameter_char && + valid_parameters[parameter] != '\0') + ++parameter; + + /* If the parameter digit is out of range it will just get printed. */ + if (parameter < PNG_WARNING_PARAMETER_COUNT) + { + /* Append this parameter */ + png_const_charp parm = p[parameter]; + png_const_charp pend = p[parameter] + (sizeof p[parameter]); + + /* No need to copy the trailing '\0' here, but there is no guarantee + * that parm[] has been initialized, so there is no guarantee of a + * trailing '\0': + */ + while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) + msg[i++] = *parm++; + + /* Consume the parameter digit too: */ + ++message; + continue; + } + + /* else not a parameter and there is a character after the @ sign; just + * copy that. This is known not to be '\0' because of the test above. + */ + } + + /* At this point *message can't be '\0', even in the bad parameter case + * above where there is a lone '@' at the end of the message string. + */ + msg[i++] = *message++; + } + + /* i is always less than (sizeof msg), so: */ + msg[i] = '\0'; + + /* And this is the formatted message, it may be larger than + * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are + * not (currently) formatted. + */ + png_warning(png_ptr, msg); +} +#endif /* PNG_WARNINGS_SUPPORTED */ + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_benign_error(png_structp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); +} +#endif + +/* These utilities are used internally to build an error message that relates + * to the current chunk. The chunk name comes from png_ptr->chunk_name, + * this is used to prefix the message. The message is limited in length + * to 63 bytes, the name characters are output as hex digits wrapped in [] + * if the character is invalid. + */ +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) +static PNG_CONST char png_digit[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' +}; + +#define PNG_MAX_ERROR_TEXT 64 +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) +static void /* PRIVATE */ +png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp + error_message) +{ + png_uint_32 chunk_name = png_ptr->chunk_name; + int iout = 0, ishift = 24; + + while (ishift >= 0) + { + int c = (int)(chunk_name >> ishift) & 0xff; + + ishift -= 8; + if (isnonalpha(c)) + { + buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; + buffer[iout++] = png_digit[(c & 0xf0) >> 4]; + buffer[iout++] = png_digit[c & 0x0f]; + buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; + } + + else + { + buffer[iout++] = (char)c; + } + } + + if (error_message == NULL) + buffer[iout] = '\0'; + + else + { + int iin = 0; + + buffer[iout++] = ':'; + buffer[iout++] = ' '; + + while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') + buffer[iout++] = error_message[iin++]; + + /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ + buffer[iout] = '\0'; + } +} +#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_FUNCTION(void,PNGAPI +png_chunk_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_error(png_ptr, error_message); + + else + { + png_format_buffer(png_ptr, msg, error_message); + png_error(png_ptr, msg); + } +} +#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ + +#ifdef PNG_WARNINGS_SUPPORTED +void PNGAPI +png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_warning(png_ptr, warning_message); + + else + { + png_format_buffer(png_ptr, msg, warning_message); + png_warning(png_ptr, msg); + } +} +#endif /* PNG_WARNINGS_SUPPORTED */ + +#ifdef PNG_READ_SUPPORTED +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) +{ + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + png_chunk_warning(png_ptr, error_message); + + else + png_chunk_error(png_ptr, error_message); +} +#endif +#endif /* PNG_READ_SUPPORTED */ + +#ifdef PNG_ERROR_TEXT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_FUNCTION(void, +png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) +{ +# define fixed_message "fixed point overflow in " +# define fixed_message_ln ((sizeof fixed_message)-1) + int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; + png_memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; + if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) + { + msg[fixed_message_ln + iin] = name[iin]; + ++iin; + } + msg[fixed_message_ln + iin] = 0; + png_error(png_ptr, msg); +} +#endif +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This API only exists if ANSI-C style error handling is used, + * otherwise it is necessary for png_default_error to be overridden. + */ +jmp_buf* PNGAPI +png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, + size_t jmp_buf_size) +{ + if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf)) + return NULL; + + png_ptr->longjmp_fn = longjmp_fn; + return &png_ptr->longjmp_buffer; +} +#endif + +/* This is the default error handling function. Note that replacements for + * this function MUST NOT RETURN, or the program will likely crash. This + * function is used by default, or if the program supplies NULL for the + * error function pointer in png_set_error_fn(). + */ +static PNG_FUNCTION(void /* PRIVATE */, +png_default_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + /* Check on NULL only added in 1.5.4 */ + if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) + { + /* Strip "#nnnn " from beginning of error message. */ + int offset; + char error_number[16]; + for (offset = 0; offset<15; offset++) + { + error_number[offset] = error_message[offset + 1]; + if (error_message[offset] == ' ') + break; + } + + if ((offset > 1) && (offset < 15)) + { + error_number[offset - 1] = '\0'; + fprintf(stderr, "libpng error no. %s: %s", + error_number, error_message + offset + 1); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng error: %s, offset=%d", + error_message, offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } + } + else +#endif + { + fprintf(stderr, "libpng error: %s", error_message ? error_message : + "undefined"); + fprintf(stderr, PNG_STRING_NEWLINE); + } +#else + PNG_UNUSED(error_message) /* Make compiler happy */ +#endif + png_longjmp(png_ptr, 1); +} + +PNG_FUNCTION(void,PNGAPI +png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) +{ +#ifdef PNG_SETJMP_SUPPORTED + if (png_ptr && png_ptr->longjmp_fn) + { +# ifdef USE_FAR_KEYWORD + { + jmp_buf tmp_jmpbuf; + png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); + png_ptr->longjmp_fn(tmp_jmpbuf, val); + } + +# else + png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val); +# endif + } +#endif + /* Here if not setjmp support or if png_ptr is null. */ + PNG_ABORT(); +} + +#ifdef PNG_WARNINGS_SUPPORTED +/* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want them to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void /* PRIVATE */ +png_default_warning(png_structp png_ptr, png_const_charp warning_message) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED +# ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (*warning_message == PNG_LITERAL_SHARP) + { + int offset; + char warning_number[16]; + for (offset = 0; offset < 15; offset++) + { + warning_number[offset] = warning_message[offset + 1]; + if (warning_message[offset] == ' ') + break; + } + + if ((offset > 1) && (offset < 15)) + { + warning_number[offset + 1] = '\0'; + fprintf(stderr, "libpng warning no. %s: %s", + warning_number, warning_message + offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng warning: %s", + warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } + } + else +# endif + + { + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } +#else + PNG_UNUSED(warning_message) /* Make compiler happy */ +#endif + PNG_UNUSED(png_ptr) /* Make compiler happy */ +} +#endif /* PNG_WARNINGS_SUPPORTED */ + +/* This function is called when the application wants to use another method + * of handling errors and warnings. Note that the error function MUST NOT + * return to the calling routine or serious problems will occur. The return + * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1) + */ +void PNGAPI +png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->error_ptr = error_ptr; + png_ptr->error_fn = error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#else + PNG_UNUSED(warning_fn) +#endif +} + + +/* This function returns a pointer to the error_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_error_ptr(png_const_structp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return ((png_voidp)png_ptr->error_ptr); +} + + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +void PNGAPI +png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) +{ + if (png_ptr != NULL) + { + png_ptr->flags &= + ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | + PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); + } +} +#endif +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngget.c b/WDL/libpng/pngget.c new file mode 100644 index 00000000..1889e990 --- /dev/null +++ b/WDL/libpng/pngget.c @@ -0,0 +1,1124 @@ + +/* pngget.c - retrieval of values from info struct + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +png_uint_32 PNGAPI +png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 flag) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->valid & flag); + + return(0); +} + +png_size_t PNGAPI +png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->rowbytes); + + return(0); +} + +#ifdef PNG_INFO_IMAGE_SUPPORTED +png_bytepp PNGAPI +png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->row_pointers); + + return(0); +} +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Easy access to info, added in libpng-0.99 */ +png_uint_32 PNGAPI +png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->width; + + return (0); +} + +png_uint_32 PNGAPI +png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->height; + + return (0); +} + +png_byte PNGAPI +png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->bit_depth; + + return (0); +} + +png_byte PNGAPI +png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->color_type; + + return (0); +} + +png_byte PNGAPI +png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->filter_type; + + return (0); +} + +png_byte PNGAPI +png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->interlace_type; + + return (0); +} + +png_byte PNGAPI +png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->compression_type; + + return (0); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", + "png_get_x_pixels_per_meter"); + + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->x_pixels_per_unit); + } +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", + "png_get_y_pixels_per_meter"); + + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->y_pixels_per_unit); + } +#endif + + return (0); +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); + + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && + info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) + return (info_ptr->x_pixels_per_unit); + } +#endif + + return (0); +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); + + if (info_ptr->x_pixels_per_unit != 0) + return ((float)((float)info_ptr->y_pixels_per_unit + /(float)info_ptr->x_pixels_per_unit)); + } +#endif + + return ((float)0.0); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr, + png_const_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) + && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 + && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX + && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) + { + png_fixed_point res; + + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); + + /* The following casts work because a PNG 4 byte integer only has a valid + * range of 0..2^31-1; otherwise the cast might overflow. + */ + if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, + (png_int_32)info_ptr->x_pixels_per_unit)) + return res; + } +#endif + + return 0; +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->x_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->y_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->x_offset); + } +#endif + + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->y_offset); + } +#endif + + return (0); +} + +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED +static png_uint_32 +ppi_from_ppm(png_uint_32 ppm) +{ +#if 0 + /* The conversion is *(2.54/100), in binary (32 digits): + * .00000110100000001001110101001001 + */ + png_uint_32 t1001, t1101; + ppm >>= 1; /* .1 */ + t1001 = ppm + (ppm >> 3); /* .1001 */ + t1101 = t1001 + (ppm >> 1); /* .1101 */ + ppm >>= 20; /* .000000000000000000001 */ + t1101 += t1101 >> 15; /* .1101000000000001101 */ + t1001 >>= 11; /* .000000000001001 */ + t1001 += t1001 >> 12; /* .000000000001001000000001001 */ + ppm += t1001; /* .000000000001001000001001001 */ + ppm += t1101; /* .110100000001001110101001001 */ + return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ +#else + /* The argument is a PNG unsigned integer, so it is not permitted + * to be bigger than 2^31. + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, + 5000)) + return result; + + /* Overflow. */ + return 0; +#endif +} + +png_uint_32 PNGAPI +png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) +{ + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); +} + +#ifdef PNG_FIXED_POINT_SUPPORTED +static png_fixed_point +png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) +{ + /* Convert from metres * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. + * Notice that this can overflow - a warning is output and 0 is + * returned. + */ + return png_muldiv_warn(png_ptr, microns, 500, 127); +} + +png_fixed_point PNGAPI +png_get_x_offset_inches_fixed(png_structp png_ptr, + png_const_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_y_offset_inches_fixed(png_structp png_ptr, + png_const_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + + if (*unit_type == 1) + { + if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); + if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); + } + } + } + + return (retval); +} +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ + +/* png_get_channels really belongs in here, too, but it's been around longer */ + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +png_byte PNGAPI +png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); + + return (0); +} + +png_const_bytep PNGAPI +png_get_signature(png_const_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + + return (NULL); +} + +#ifdef PNG_bKGD_SUPPORTED +png_uint_32 PNGAPI +png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr, + png_color_16p *background) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) + && background != NULL) + { + png_debug1(1, "in %s retrieval function", "bKGD"); + + *background = &(info_ptr->background); + return (PNG_INFO_bKGD); + } + + return (0); +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the + * same time to correct the rgb grayscale coefficient defaults obtained from the + * cHRM chunk in 1.5.4 + */ +png_uint_32 PNGFAPI +png_get_cHRM_XYZ_fixed(png_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_xy xy; + png_XYZ XYZ; + + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + + xy.whitex = info_ptr->x_white; + xy.whitey = info_ptr->y_white; + xy.redx = info_ptr->x_red; + xy.redy = info_ptr->y_red; + xy.greenx = info_ptr->x_green; + xy.greeny = info_ptr->y_green; + xy.bluex = info_ptr->x_blue; + xy.bluey = info_ptr->y_blue; + + /* The *_checked function handles error reporting, so just return 0 if + * there is a failure here. + */ + if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) + { + if (int_red_X != NULL) + *int_red_X = XYZ.redX; + if (int_red_Y != NULL) + *int_red_Y = XYZ.redY; + if (int_red_Z != NULL) + *int_red_Z = XYZ.redZ; + if (int_green_X != NULL) + *int_green_X = XYZ.greenX; + if (int_green_Y != NULL) + *int_green_Y = XYZ.greenY; + if (int_green_Z != NULL) + *int_green_Z = XYZ.greenZ; + if (int_blue_X != NULL) + *int_blue_X = XYZ.blueX; + if (int_blue_Y != NULL) + *int_blue_Y = XYZ.blueY; + if (int_blue_Z != NULL) + *int_blue_Z = XYZ.blueZ; + + return (PNG_INFO_cHRM); + } + } + + return (0); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr, + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_debug1(1, "in %s retrieval function", "cHRM"); + + if (white_x != NULL) + *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); + if (white_y != NULL) + *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); + if (red_x != NULL) + *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); + if (red_y != NULL) + *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); + if (green_x != NULL) + *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); + if (green_y != NULL) + *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); + if (blue_x != NULL) + *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); + if (blue_y != NULL) + *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); + return (PNG_INFO_cHRM); + } + + return (0); +} + +png_uint_32 PNGAPI +png_get_cHRM_XYZ(png_structp png_ptr, png_const_infop info_ptr, + double *red_X, double *red_Y, double *red_Z, double *green_X, + double *green_Y, double *green_Z, double *blue_X, double *blue_Y, + double *blue_Z) +{ + png_XYZ XYZ; + + if (png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, + &XYZ.redX, &XYZ.redY, &XYZ.redZ, &XYZ.greenX, &XYZ.greenY, &XYZ.greenZ, + &XYZ.blueX, &XYZ.blueY, &XYZ.blueZ) & PNG_INFO_cHRM) + { + if (red_X != NULL) + *red_X = png_float(png_ptr, XYZ.redX, "cHRM red X"); + if (red_Y != NULL) + *red_Y = png_float(png_ptr, XYZ.redY, "cHRM red Y"); + if (red_Z != NULL) + *red_Z = png_float(png_ptr, XYZ.redZ, "cHRM red Z"); + if (green_X != NULL) + *green_X = png_float(png_ptr, XYZ.greenX, "cHRM green X"); + if (green_Y != NULL) + *green_Y = png_float(png_ptr, XYZ.greenY, "cHRM green Y"); + if (green_Z != NULL) + *green_Z = png_float(png_ptr, XYZ.greenZ, "cHRM green Z"); + if (blue_X != NULL) + *blue_X = png_float(png_ptr, XYZ.blueX, "cHRM blue X"); + if (blue_Y != NULL) + *blue_Y = png_float(png_ptr, XYZ.blueY, "cHRM blue Y"); + if (blue_Z != NULL) + *blue_Z = png_float(png_ptr, XYZ.blueZ, "cHRM blue Z"); + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_const_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, + png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y) +{ + png_debug1(1, "in %s retrieval function", "cHRM"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + if (white_x != NULL) + *white_x = info_ptr->x_white; + if (white_y != NULL) + *white_y = info_ptr->y_white; + if (red_x != NULL) + *red_x = info_ptr->x_red; + if (red_y != NULL) + *red_y = info_ptr->y_red; + if (green_x != NULL) + *green_x = info_ptr->x_green; + if (green_y != NULL) + *green_y = info_ptr->y_green; + if (blue_x != NULL) + *blue_x = info_ptr->x_blue; + if (blue_y != NULL) + *blue_y = info_ptr->y_blue; + return (PNG_INFO_cHRM); + } + + return (0); +} +# endif +#endif + +#ifdef PNG_gAMA_SUPPORTED +png_uint_32 PNGFAPI +png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr, + png_fixed_point *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && file_gamma != NULL) + { + *file_gamma = info_ptr->gamma; + return (PNG_INFO_gAMA); + } + + return (0); +} +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, + double *file_gamma) +{ + png_fixed_point igamma; + png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); + + if (ok) + *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); + + return ok; +} + +# endif +#endif + +#ifdef PNG_sRGB_SUPPORTED +png_uint_32 PNGAPI +png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, + int *file_srgb_intent) +{ + png_debug1(1, "in %s retrieval function", "sRGB"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) + && file_srgb_intent != NULL) + { + *file_srgb_intent = (int)info_ptr->srgb_intent; + return (PNG_INFO_sRGB); + } + + return (0); +} +#endif + +#ifdef PNG_iCCP_SUPPORTED +png_uint_32 PNGAPI +png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr, + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen) +{ + png_debug1(1, "in %s retrieval function", "iCCP"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) + && name != NULL && compression_type != NULL && profile != NULL && + proflen != NULL) + { + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; + /* Compression_type is a dummy so the API won't have to change + * if we introduce multiple compression types later. + */ + *proflen = info_ptr->iccp_proflen; + *compression_type = info_ptr->iccp_compression; + return (PNG_INFO_iCCP); + } + + return (0); +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +png_uint_32 PNGAPI +png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr, + png_sPLT_tpp spalettes) +{ + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + { + *spalettes = info_ptr->splt_palettes; + return ((png_uint_32)info_ptr->splt_palettes_num); + } + + return (0); +} +#endif + +#ifdef PNG_hIST_SUPPORTED +png_uint_32 PNGAPI +png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_16p *hist) +{ + png_debug1(1, "in %s retrieval function", "hIST"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) + && hist != NULL) + { + *hist = info_ptr->hist; + return (PNG_INFO_hIST); + } + + return (0); +} +#endif + +png_uint_32 PNGAPI +png_get_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) + +{ + png_debug1(1, "in %s retrieval function", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL || width == NULL || + height == NULL || bit_depth == NULL || color_type == NULL) + return (0); + + *width = info_ptr->width; + *height = info_ptr->height; + *bit_depth = info_ptr->bit_depth; + *color_type = info_ptr->color_type; + + if (compression_type != NULL) + *compression_type = info_ptr->compression_type; + + if (filter_type != NULL) + *filter_type = info_ptr->filter_type; + + if (interlace_type != NULL) + *interlace_type = info_ptr->interlace_type; + + /* This is redundant if we can be sure that the info_ptr values were all + * assigned in png_set_IHDR(). We do the check anyhow in case an + * application has ignored our advice not to mess with the members + * of info_ptr directly. + */ + png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + + return (1); +} + +#ifdef PNG_oFFs_SUPPORTED +png_uint_32 PNGAPI +png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) +{ + png_debug1(1, "in %s retrieval function", "oFFs"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) + && offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + *offset_x = info_ptr->x_offset; + *offset_y = info_ptr->y_offset; + *unit_type = (int)info_ptr->offset_unit_type; + return (PNG_INFO_oFFs); + } + + return (0); +} +#endif + +#ifdef PNG_pCAL_SUPPORTED +png_uint_32 PNGAPI +png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) +{ + png_debug1(1, "in %s retrieval function", "pCAL"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) + && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) + { + *purpose = info_ptr->pcal_purpose; + *X0 = info_ptr->pcal_X0; + *X1 = info_ptr->pcal_X1; + *type = (int)info_ptr->pcal_type; + *nparams = (int)info_ptr->pcal_nparams; + *units = info_ptr->pcal_units; + *params = info_ptr->pcal_params; + return (PNG_INFO_pCAL); + } + + return (0); +} +#endif + +#ifdef PNG_sCAL_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + /*TODO: make this work without FP support */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); + return (PNG_INFO_sCAL); + } + + return(0); +} +# endif /* FLOATING_ARITHMETIC */ +# endif /* FIXED_POINT */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, double *width, double *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = atof(info_ptr->scal_s_width); + *height = atof(info_ptr->scal_s_height); + return (PNG_INFO_sCAL); + } + + return(0); +} +# endif /* FLOATING POINT */ +png_uint_32 PNGAPI +png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr, + int *unit, png_charpp width, png_charpp height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; + *height = info_ptr->scal_s_height; + return (PNG_INFO_sCAL); + } + + return(0); +} +#endif /* sCAL */ + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs)) + { + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + } + } + + return (retval); +} +#endif /* pHYs */ + +png_uint_32 PNGAPI +png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, + png_colorp *palette, int *num_palette) +{ + png_debug1(1, "in %s retrieval function", "PLTE"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) + && palette != NULL) + { + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; + png_debug1(3, "num_palette = %d", *num_palette); + return (PNG_INFO_PLTE); + } + + return (0); +} + +#ifdef PNG_sBIT_SUPPORTED +png_uint_32 PNGAPI +png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit) +{ + png_debug1(1, "in %s retrieval function", "sBIT"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) + && sig_bit != NULL) + { + *sig_bit = &(info_ptr->sig_bit); + return (PNG_INFO_sBIT); + } + + return (0); +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +png_uint_32 PNGAPI +png_get_text(png_const_structp png_ptr, png_const_infop info_ptr, + png_textp *text_ptr, int *num_text) +{ + if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) + { + png_debug1(1, "in 0x%lx retrieval function", + (unsigned long)png_ptr->chunk_name); + + if (text_ptr != NULL) + *text_ptr = info_ptr->text; + + if (num_text != NULL) + *num_text = info_ptr->num_text; + + return ((png_uint_32)info_ptr->num_text); + } + + if (num_text != NULL) + *num_text = 0; + + return(0); +} +#endif + +#ifdef PNG_tIME_SUPPORTED +png_uint_32 PNGAPI +png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time) +{ + png_debug1(1, "in %s retrieval function", "tIME"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) + && mod_time != NULL) + { + *mod_time = &(info_ptr->mod_time); + return (PNG_INFO_tIME); + } + + return (0); +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +png_uint_32 PNGAPI +png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) +{ + png_uint_32 retval = 0; + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_debug1(1, "in %s retrieval function", "tRNS"); + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (trans_alpha != NULL) + { + *trans_alpha = info_ptr->trans_alpha; + retval |= PNG_INFO_tRNS; + } + + if (trans_color != NULL) + *trans_color = &(info_ptr->trans_color); + } + + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ + { + if (trans_color != NULL) + { + *trans_color = &(info_ptr->trans_color); + retval |= PNG_INFO_tRNS; + } + + if (trans_alpha != NULL) + *trans_alpha = NULL; + } + + if (num_trans != NULL) + { + *num_trans = info_ptr->num_trans; + retval |= PNG_INFO_tRNS; + } + } + + return (retval); +} +#endif + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr, + png_unknown_chunkpp unknowns) +{ + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) + { + *unknowns = info_ptr->unknown_chunks; + return info_ptr->unknown_chunks_num; + } + + return (0); +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +png_byte PNGAPI +png_get_rgb_to_gray_status (png_const_structp png_ptr) +{ + return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); +} +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +png_voidp PNGAPI +png_get_user_chunk_ptr(png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); +} +#endif + +png_size_t PNGAPI +png_get_compression_buffer_size(png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->zbuf_size : 0); +} + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* These functions were added to libpng 1.2.6 and were enabled + * by default in libpng-1.4.0 */ +png_uint_32 PNGAPI +png_get_user_width_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_width_max : 0); +} + +png_uint_32 PNGAPI +png_get_user_height_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_height_max : 0); +} + +/* This function was added to libpng 1.4.0 */ +png_uint_32 PNGAPI +png_get_chunk_cache_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_cache_max : 0); +} + +/* This function was added to libpng 1.4.1 */ +png_alloc_size_t PNGAPI +png_get_chunk_malloc_max (png_const_structp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +/* These functions were added to libpng 1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +png_uint_32 PNGAPI +png_get_io_state (png_structp png_ptr) +{ + return png_ptr->io_state; +} + +png_uint_32 PNGAPI +png_get_io_chunk_type (png_const_structp png_ptr) +{ + return png_ptr->chunk_name; +} + +png_const_bytep PNGAPI +png_get_io_chunk_name (png_structp png_ptr) +{ + PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name); + return png_ptr->io_chunk_string; +} +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pnginfo.h b/WDL/libpng/pnginfo.h new file mode 100644 index 00000000..bbfb105a --- /dev/null +++ b/WDL/libpng/pnginfo.h @@ -0,0 +1,269 @@ + +/* pnginfo.h - header file for PNG reference library + * + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + + /* png_info is a structure that holds the information in a PNG file so + * that the application can find out the characteristics of the image. + * If you are reading the file, this structure will tell you what is + * in the PNG file. If you are writing the file, fill in the information + * you want to put into the PNG file, using png_set_*() functions, then + * call png_write_info(). + * + * The names chosen should be very close to the PNG specification, so + * consult that document for information about the meaning of each field. + * + * With libpng < 0.95, it was only possible to directly set and read the + * the values in the png_info_struct, which meant that the contents and + * order of the values had to remain fixed. With libpng 0.95 and later, + * however, there are now functions that abstract the contents of + * png_info_struct from the application, so this makes it easier to use + * libpng with dynamic libraries, and even makes it possible to use + * libraries that don't have all of the libpng ancillary chunk-handing + * functionality. In libpng-1.5.0 this was moved into a separate private + * file that is not visible to applications. + * + * The following members may have allocated storage attached that should be + * cleaned up before the structure is discarded: palette, trans, text, + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, + * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these + * are automatically freed when the info structure is deallocated, if they were + * allocated internally by libpng. This behavior can be changed by means + * of the png_data_freer() function. + * + * More allocation details: all the chunk-reading functions that + * change these members go through the corresponding png_set_* + * functions. A function to clear these members is available: see + * png_free_data(). The png_set_* functions do not depend on being + * able to point info structure members to any of the storage they are + * passed (they make their own copies), EXCEPT that the png_set_text + * functions use the same storage passed to them in the text_ptr or + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns + * functions do not make their own copies. + */ +#ifndef PNGINFO_H +#define PNGINFO_H + +struct png_info_def +{ + /* the following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + png_size_t rowbytes; /* bytes needed to hold an untransformed row */ + png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ + png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ + png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ + png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ + png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ + /* The following three should have been named *_method not *_type */ + png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + + /* The following is informational only on read, and not used on writes. */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you + * are writing, set the valid field to those chunks you want written, + * and initialize the appropriate fields below. + */ + +#if defined(PNG_gAMA_SUPPORTED) + /* The gAMA chunk describes the gamma characteristics of the system + * on which the image was created, normally in the range [1.0, 2.5]. + * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. + */ + png_fixed_point gamma; +#endif + +#ifdef PNG_sRGB_SUPPORTED + /* GR-P, 0.96a */ + /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ + png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ +#endif + +#ifdef PNG_TEXT_SUPPORTED + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. + */ + int num_text; /* number of comments read or comments to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read or comments to write */ +#endif /* PNG_TEXT_SUPPORTED */ + +#ifdef PNG_tIME_SUPPORTED + /* The tIME chunk holds the last time the displayed image data was + * modified. See the png_time struct for the contents of this struct. + */ + png_time mod_time; +#endif + +#ifdef PNG_sBIT_SUPPORTED + /* The sBIT chunk specifies the number of significant high-order bits + * in the pixel data. Values are in the range [1, bit_depth], and are + * only specified for the channels in the pixel data. The contents of + * the low-order bits is not specified. Data is valid if + * (valid & PNG_INFO_sBIT) is non-zero. + */ + png_color_8 sig_bit; /* significant bits in color channels */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The tRNS chunk supplies transparency data for paletted images and + * other image types that don't need a full alpha channel. There are + * "num_trans" transparency values for a paletted image, stored in the + * same order as the palette colors, starting from index 0. Values + * for the data are in the range [0, 255], ranging from fully transparent + * to fully opaque, respectively. For non-paletted images, there is a + * single color specified that should be treated as fully transparent. + * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. + */ + png_bytep trans_alpha; /* alpha values for paletted image */ + png_color_16 trans_color; /* transparent color for non-palette image */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The bKGD chunk gives the suggested image background color if the + * display program does not have its own background color and the image + * is needs to composited onto a background before display. The colors + * in "background" are normally in the same color space/depth as the + * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. + */ + png_color_16 background; +#endif + +#ifdef PNG_oFFs_SUPPORTED + /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards + * and downwards from the top-left corner of the display, page, or other + * application-specific co-ordinate space. See the PNG_OFFSET_ defines + * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. + */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ + png_byte offset_unit_type; /* offset units type */ +#endif + +#ifdef PNG_pHYs_SUPPORTED + /* The pHYs chunk gives the physical pixel density of the image for + * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ + * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. + */ + png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ + png_uint_32 y_pixels_per_unit; /* vertical pixel density */ + png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ +#endif + +#ifdef PNG_hIST_SUPPORTED + /* The hIST chunk contains the relative frequency or importance of the + * various palette entries, so that a viewer can intelligently select a + * reduced-color palette, if required. Data is an array of "num_palette" + * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) + * is non-zero. + */ + png_uint_16p hist; +#endif + +#ifdef PNG_cHRM_SUPPORTED + /* The cHRM chunk describes the CIE color characteristics of the monitor + * on which the PNG was created. This data allows the viewer to do gamut + * mapping of the input image to ensure that the viewer sees the same + * colors in the image as the creator. Values are in the range + * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. + */ + png_fixed_point x_white; + png_fixed_point y_white; + png_fixed_point x_red; + png_fixed_point y_red; + png_fixed_point x_green; + png_fixed_point y_green; + png_fixed_point x_blue; + png_fixed_point y_blue; +#endif + +#ifdef PNG_pCAL_SUPPORTED + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. + * The integer range [0, 2^bit_depth - 1] maps to the floating-point + * range given by [pcal_X0, pcal_X1], and are further transformed by a + * (possibly non-linear) transformation function given by "pcal_type" + * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ + * defines below, and the PNG-Group's PNG extensions document for a + * complete description of the transformations and how they should be + * implemented, and for a description of the ASCII parameter strings. + * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. + */ + png_charp pcal_purpose; /* pCAL chunk description string */ + png_int_32 pcal_X0; /* minimum value */ + png_int_32 pcal_X1; /* maximum value */ + png_charp pcal_units; /* Latin-1 string giving physical units */ + png_charpp pcal_params; /* ASCII strings containing parameter values */ + png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ + png_byte pcal_nparams; /* number of parameters given in pcal_params */ +#endif + +/* New members added in libpng-1.0.6 */ + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + /* Storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + int unknown_chunks_num; +#endif + +#ifdef PNG_iCCP_SUPPORTED + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_bytep iccp_profile; /* International Color Consortium profile data */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#ifdef PNG_sPLT_SUPPORTED + /* Data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + png_uint_32 splt_palettes_num; +#endif + +#ifdef PNG_sCAL_SUPPORTED + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * a byte value, and two ASCII strings representing floating-point + * values. The values are width and height corresponsing to one pixel + * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is + * non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif + +#ifdef PNG_INFO_IMAGE_SUPPORTED + /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) + non-zero */ + /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ + png_bytepp row_pointers; /* the image bits */ +#endif + +}; +#endif /* PNGINFO_H */ diff --git a/WDL/libpng/pnglibconf.h b/WDL/libpng/pnglibconf.h new file mode 100644 index 00000000..06d6cdeb --- /dev/null +++ b/WDL/libpng/pnglibconf.h @@ -0,0 +1,189 @@ + +/* libpng STANDARD API DEFINITION */ + +/* pnglibconf.h - library build configuration */ + +/* Libpng 1.5.8 - February 1, 2012 */ + +/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */ + +/* This code is released under the libpng license. */ +/* For conditions of distribution and use, see the disclaimer */ +/* and license in png.h */ + +/* pnglibconf.h */ +/* Derived from: scripts/pnglibconf.dfa */ +/* If you edit this file by hand you must obey the rules expressed in */ +/* pnglibconf.dfa with respect to the dependencies between the following */ +/* symbols. It is much better to generate a new file using */ +/* scripts/libpngconf.mak */ + +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* settings */ +#define PNG_API_RULE 0 +#define PNG_CALLOC_SUPPORTED +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_sCAL_PRECISION 5 +#define PNG_USER_CHUNK_CACHE_MAX 0 +#define PNG_USER_CHUNK_MALLOC_MAX 0 +#define PNG_USER_HEIGHT_MAX 1000000 +#define PNG_USER_WIDTH_MAX 1000000 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +/* end of settings */ +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGN_MEMORY_SUPPORTED +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_cHRM_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONVERT_tIME_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ +#define PNG_ERROR_TEXT_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_FORMAT_AFIRST_SUPPORTED +#define PNG_FORMAT_BGR_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_MNG_FEATURES_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_MEM_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +#endif /* PNGLCONF_H */ diff --git a/WDL/libpng/pngmem.c b/WDL/libpng/pngmem.c new file mode 100644 index 00000000..25b5c735 --- /dev/null +++ b/WDL/libpng/pngmem.c @@ -0,0 +1,667 @@ + +/* pngmem.c - stub functions for memory allocation + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all memory allocation. Users who + * need special memory handling are expected to supply replacement + * functions for png_malloc() and png_free(), and to use + * png_create_read_struct_2() and png_create_write_struct_2() to + * identify the replacement functions. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +/* Borland DOS special memory handler */ +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* If you change this, be sure to change the one in png.h also */ + +/* Allocate memory for a png_struct. The malloc and memset can be replaced + by a single call to calloc() if this is thought to improve performance. */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) +{ +# ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, NULL, NULL)); +} + +/* Alternate version of png_create_struct, for use with user-defined malloc. */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) +{ +# endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + + else + return (png_get_copyright(NULL)); + +# ifdef PNG_USER_MEM_SUPPORTED + if (malloc_fn != NULL) + { + png_struct dummy_struct; + memset(&dummy_struct, 0, sizeof dummy_struct); + dummy_struct.mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(&dummy_struct, (png_alloc_size_t)size); + } + + else +# endif /* PNG_USER_MEM_SUPPORTED */ + struct_ptr = (png_voidp)farmalloc(size); + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + + return (struct_ptr); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +# ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, NULL, NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +# endif + if (struct_ptr != NULL) + { +# ifdef PNG_USER_MEM_SUPPORTED + if (free_fn != NULL) + { + png_struct dummy_struct; + memset(&dummy_struct, 0, sizeof dummy_struct); + dummy_struct.mem_ptr=mem_ptr; + (*(free_fn))(&dummy_struct, struct_ptr); + return; + } + +# endif /* PNG_USER_MEM_SUPPORTED */ + farfree (struct_ptr); + } +} + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + * + * Borland seems to have a problem in DOS mode for exactly 64K. + * It gives you a segment with an offset of 8 (perhaps to store its + * memory stuff). zlib doesn't like this at all, so we have to + * detect and deal with it. This code should not be needed in + * Windows or OS/2 modes, and only in 16 bit mode. This code has + * been updated by Alexander Lehmann for version 0.89 to waste less + * memory. + * + * Note that we can't use png_size_t for the "size" declaration, + * since on some systems a png_size_t is a 16-bit quantity, and as a + * result, we would be truncating potentially larger memory requests + * (which should cause a fatal error) and introducing major problems. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + ret = (png_malloc(png_ptr, size)); + + if (ret != NULL) + png_memset(ret,0,(png_size_t)size); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + if (png_ptr == NULL || size == 0) + return (NULL); + +# ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size)); + + else + ret = (png_malloc_default(png_ptr, size)); + + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory"); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; +# endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || size == 0) + return (NULL); + +# ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { + png_warning(png_ptr, "Cannot Allocate > 64K"); + ret = NULL; + } + + else +# endif + + if (size != (size_t)size) + ret = NULL; + + else if (size == (png_uint_32)65536L) + { + if (png_ptr->offset_table == NULL) + { + /* Try to see if we need to do any of this fancy stuff */ + ret = farmalloc(size); + if (ret == NULL || ((png_size_t)ret & 0xffff)) + { + int num_blocks; + png_uint_32 total_size; + png_bytep table; + int i, mem_level, window_bits; + png_byte huge * hptr; + int window_bits + + if (ret != NULL) + { + farfree(ret); + ret = NULL; + } + + window_bits = + png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ? + png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits; + + if (window_bits > 14) + num_blocks = (int)(1 << (window_bits - 14)); + + else + num_blocks = 1; + + mem_level = + png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ? + png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level; + + if (mem_level >= 7) + num_blocks += (int)(1 << (mem_level - 7)); + + else + num_blocks++; + + total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; + + table = farmalloc(total_size); + + if (table == NULL) + { +# ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ + + else + png_warning(png_ptr, "Out Of Memory"); +# endif + return (NULL); + } + + if ((png_size_t)table & 0xfff0) + { +# ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, + "Farmalloc didn't return normalized pointer"); + + else + png_warning(png_ptr, + "Farmalloc didn't return normalized pointer"); +# endif + return (NULL); + } + + png_ptr->offset_table = table; + png_ptr->offset_table_ptr = farmalloc(num_blocks * + png_sizeof(png_bytep)); + + if (png_ptr->offset_table_ptr == NULL) + { +# ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ + + else + png_warning(png_ptr, "Out Of memory"); +# endif + return (NULL); + } + + hptr = (png_byte huge *)table; + if ((png_size_t)hptr & 0xf) + { + hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); + hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ + } + + for (i = 0; i < num_blocks; i++) + { + png_ptr->offset_table_ptr[i] = (png_bytep)hptr; + hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ + } + + png_ptr->offset_table_number = num_blocks; + png_ptr->offset_table_count = 0; + png_ptr->offset_table_count_free = 0; + } + } + + if (png_ptr->offset_table_count >= png_ptr->offset_table_number) + { +# ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */ + + else + png_warning(png_ptr, "Out of Memory"); +# endif + return (NULL); + } + + ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; + } + + else + ret = farmalloc(size); + +# ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL) + { + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ + + else + png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ + } +# endif + + return (ret); +} + +/* Free a pointer allocated by png_malloc(). In the default + * configuration, png_ptr is not used, but is passed in case it + * is needed. If ptr is NULL, return without taking any action. + */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +# ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + + else + png_free_default(png_ptr, ptr); +} + +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ +# endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || ptr == NULL) + return; + + if (png_ptr->offset_table != NULL) + { + int i; + + for (i = 0; i < png_ptr->offset_table_count; i++) + { + if (ptr == png_ptr->offset_table_ptr[i]) + { + ptr = NULL; + png_ptr->offset_table_count_free++; + break; + } + } + if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) + { + farfree(png_ptr->offset_table); + farfree(png_ptr->offset_table_ptr); + png_ptr->offset_table = NULL; + png_ptr->offset_table_ptr = NULL; + } + } + + if (ptr != NULL) + farfree(ptr); +} + +#else /* Not the Borland DOS special memory handler */ + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) +{ +# ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, NULL, NULL)); +} + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) +{ +# endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + + else + return (NULL); + +# ifdef PNG_USER_MEM_SUPPORTED + if (malloc_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(png_ptr, size); + + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + + return (struct_ptr); + } +# endif /* PNG_USER_MEM_SUPPORTED */ + +# if defined(__TURBOC__) && !defined(__FLAT__) + struct_ptr = (png_voidp)farmalloc(size); +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + struct_ptr = (png_voidp)halloc(size, 1); +# else + struct_ptr = (png_voidp)malloc(size); +# endif +# endif + + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + + return (struct_ptr); +} + + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +# ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, NULL, NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +# endif /* PNG_USER_MEM_SUPPORTED */ + if (struct_ptr != NULL) + { +# ifdef PNG_USER_MEM_SUPPORTED + if (free_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + (*(free_fn))(png_ptr, struct_ptr); + return; + } +# endif /* PNG_USER_MEM_SUPPORTED */ +# if defined(__TURBOC__) && !defined(__FLAT__) + farfree(struct_ptr); + +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(struct_ptr); + +# else + free(struct_ptr); + +# endif +# endif + } +} + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + */ + +PNG_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + + ret = (png_malloc(png_ptr, size)); + + if (ret != NULL) + png_memset(ret,0,(png_size_t)size); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; + +# ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr == NULL || size == 0) + return (NULL); + + if (png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + + else + ret = (png_malloc_default(png_ptr, size)); + + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory"); + + return (ret); +} + +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ret; +# endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || size == 0) + return (NULL); + +# ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { +# ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Cannot Allocate > 64K"); + + else +# endif + return NULL; + } +# endif + + /* Check for overflow */ +# if defined(__TURBOC__) && !defined(__FLAT__) + + if (size != (unsigned long)size) + ret = NULL; + + else + ret = farmalloc(size); + +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + if (size != (unsigned long)size) + ret = NULL; + + else + ret = halloc(size, 1); + +# else + if (size != (size_t)size) + ret = NULL; + + else + ret = malloc((size_t)size); +# endif +# endif + +# ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory"); +# endif + + return (ret); +} + +/* Free a pointer allocated by png_malloc(). If ptr is NULL, return + * without taking any action. + */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +# ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + + else + png_free_default(png_ptr, ptr); +} + +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +# endif /* PNG_USER_MEM_SUPPORTED */ + +# if defined(__TURBOC__) && !defined(__FLAT__) + farfree(ptr); + +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(ptr); + +# else + free(ptr); + +# endif +# endif +} +#endif /* Not Borland DOS special memory handler */ + +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will set up png_malloc() to issue a png_warning and return NULL + * instead of issuing a png_error, if it fails to allocate the requested + * memory. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +{ + png_voidp ptr; + png_uint_32 save_flags; + if (png_ptr == NULL) + return (NULL); + + save_flags = png_ptr->flags; + png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); + png_ptr->flags=save_flags; + return(ptr); +} + + +#ifdef PNG_USER_MEM_SUPPORTED +/* This function is called when the application wants to use another method + * of allocating and freeing memory. + */ +void PNGAPI +png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr + malloc_fn, png_free_ptr free_fn) +{ + if (png_ptr != NULL) + { + png_ptr->mem_ptr = mem_ptr; + png_ptr->malloc_fn = malloc_fn; + png_ptr->free_fn = free_fn; + } +} + +/* This function returns a pointer to the mem_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_mem_ptr(png_const_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return ((png_voidp)png_ptr->mem_ptr); +} +#endif /* PNG_USER_MEM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngpread.c b/WDL/libpng/pngpread.c new file mode 100644 index 00000000..ca7607a6 --- /dev/null +++ b/WDL/libpng/pngpread.c @@ -0,0 +1,1846 @@ + +/* pngpread.c - read a png file in push mode + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + +/* Push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_SKIP_MODE 3 +#define PNG_READ_tEXt_MODE 4 +#define PNG_READ_zTXt_MODE 5 +#define PNG_READ_DONE_MODE 6 +#define PNG_READ_iTXt_MODE 7 +#define PNG_ERROR_MODE 8 + +void PNGAPI +png_process_data(png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_push_restore_buffer(png_ptr, buffer, buffer_size); + + while (png_ptr->buffer_size) + { + png_process_some_data(png_ptr, info_ptr); + } +} + +png_size_t PNGAPI +png_process_data_pause(png_structp png_ptr, int save) +{ + if (png_ptr != NULL) + { + /* It's easiest for the caller if we do the save, then the caller doesn't + * have to supply the same data again: + */ + if (save) + png_push_save_buffer(png_ptr); + else + { + /* This includes any pending saved bytes: */ + png_size_t remaining = png_ptr->buffer_size; + png_ptr->buffer_size = 0; + + /* So subtract the saved buffer size, unless all the data + * is actually 'saved', in which case we just return 0 + */ + if (png_ptr->save_buffer_size < remaining) + return remaining - png_ptr->save_buffer_size; + } + } + + return 0; +} + +png_uint_32 PNGAPI +png_process_data_skip(png_structp png_ptr) +{ + png_uint_32 remaining = 0; + + if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && + png_ptr->skip_length > 0) + { + /* At the end of png_process_data the buffer size must be 0 (see the loop + * above) so we can detect a broken call here: + */ + if (png_ptr->buffer_size != 0) + png_error(png_ptr, + "png_process_data_skip called inside png_process_data"); + + /* If is impossible for there to be a saved buffer at this point - + * otherwise we could not be in SKIP mode. This will also happen if + * png_process_skip is called inside png_process_data (but only very + * rarely.) + */ + if (png_ptr->save_buffer_size != 0) + png_error(png_ptr, "png_process_data_skip called with saved data"); + + remaining = png_ptr->skip_length; + png_ptr->skip_length = 0; + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + + return remaining; +} + +/* What we do with the incoming data depends on what we were previously + * doing before we ran out of data... + */ +void /* PRIVATE */ +png_process_some_data(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr == NULL) + return; + + switch (png_ptr->process_mode) + { + case PNG_READ_SIG_MODE: + { + png_push_read_sig(png_ptr, info_ptr); + break; + } + + case PNG_READ_CHUNK_MODE: + { + png_push_read_chunk(png_ptr, info_ptr); + break; + } + + case PNG_READ_IDAT_MODE: + { + png_push_read_IDAT(png_ptr); + break; + } + +#ifdef PNG_READ_tEXt_SUPPORTED + case PNG_READ_tEXt_MODE: + { + png_push_read_tEXt(png_ptr, info_ptr); + break; + } + +#endif +#ifdef PNG_READ_zTXt_SUPPORTED + case PNG_READ_zTXt_MODE: + { + png_push_read_zTXt(png_ptr, info_ptr); + break; + } + +#endif +#ifdef PNG_READ_iTXt_SUPPORTED + case PNG_READ_iTXt_MODE: + { + png_push_read_iTXt(png_ptr, info_ptr); + break; + } + +#endif + case PNG_SKIP_MODE: + { + png_push_crc_finish(png_ptr); + break; + } + + default: + { + png_ptr->buffer_size = 0; + break; + } + } +} + +/* Read any remaining signature bytes from the stream and compare them with + * the correct PNG signature. It is possible that this routine is called + * with bytes already read from the signature, either because they have been + * checked by the calling application, or because of multiple calls to this + * routine. + */ +void /* PRIVATE */ +png_push_read_sig(png_structp png_ptr, png_infop info_ptr) +{ + png_size_t num_checked = png_ptr->sig_bytes, + num_to_check = 8 - num_checked; + + if (png_ptr->buffer_size < num_to_check) + { + num_to_check = png_ptr->buffer_size; + } + + png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), + num_to_check); + png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + else + { + if (png_ptr->sig_bytes >= 8) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + } +} + +void /* PRIVATE */ +png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) +{ + png_uint_32 chunk_name; + + /* First we make sure we have enough data for the 4 byte chunk name + * and the 4 byte chunk length before proceeding with decoding the + * chunk data. To fully decode each of these chunks, we also make + * sure we have enough data in the buffer for the 4 byte CRC at the + * end of every chunk (except IDAT, which is handled separately). + */ + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + png_byte chunk_tag[4]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + + chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IDAT) + { + /* This is here above the if/else case statement below because if the + * unknown handling marks 'IDAT' as unknown then the IDAT handling case is + * completely skipped. + * + * TODO: there must be a better way of doing this. + */ + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + } + + if (chunk_name == png_IHDR) + { + if (png_ptr->push_length != 13) + png_error(png_ptr, "Invalid IHDR length"); + + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); + } + + else if (chunk_name == png_IEND) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + + png_ptr->process_mode = PNG_READ_DONE_MODE; + png_push_have_end(png_ptr, info_ptr); + } + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_chunk_unknown_handling(png_ptr, chunk_name)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (chunk_name == png_IDAT) + png_ptr->mode |= PNG_HAVE_IDAT; + + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + } + } + +#endif + else if (chunk_name == png_PLTE) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); + } + + else if (chunk_name == png_IDAT) + { + /* If we reach an IDAT chunk, this means we have read all of the + * header chunks, and we can start reading the image (or if this + * is called after the image has been read - we have an error). + */ + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + if (png_ptr->push_length == 0) + return; + + if (png_ptr->mode & PNG_AFTER_IDAT) + png_benign_error(png_ptr, "Too many IDATs found"); + } + + png_ptr->idat_size = png_ptr->push_length; + png_ptr->mode |= PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info_ptr); + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + png_ptr->zstream.next_out = png_ptr->row_buf; + return; + } + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (png_ptr->chunk_name == png_gAMA) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_sBIT_SUPPORTED + else if (png_ptr->chunk_name == png_sBIT) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_cHRM_SUPPORTED + else if (png_ptr->chunk_name == png_cHRM) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_iCCP_SUPPORTED + else if (png_ptr->chunk_name == png_iCCP) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); + } +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); + } + +#endif + else + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; +} + +void /* PRIVATE */ +png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) +{ + png_ptr->process_mode = PNG_SKIP_MODE; + png_ptr->skip_length = skip; +} + +void /* PRIVATE */ +png_push_crc_finish(png_structp png_ptr) +{ + if (png_ptr->skip_length && png_ptr->save_buffer_size) + { + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'save_buffer_size', but + * they are of different types and we don't know which variable has the + * fewest bits. Carefully select the smaller and cast it to the type of + * the larger - this cannot overflow. Do not cast in the following test + * - it will break on either 16 or 64 bit platforms. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; + + else + skip_length = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->skip_length -= skip_length; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->skip_length && png_ptr->current_buffer_size) + { + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'current_buffer_size', here, + * the same problem exists as above and the same solution. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; + + else + skip_length = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->skip_length -= skip_length; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->skip_length) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +} + +void PNGCBAPI +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) +{ + png_bytep ptr; + + if (png_ptr == NULL) + return; + + ptr = buffer; + if (png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->save_buffer_size) + save_size = length; + + else + save_size = png_ptr->save_buffer_size; + + png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (length && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->current_buffer_size) + save_size = length; + + else + save_size = png_ptr->current_buffer_size; + + png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +} + +void /* PRIVATE */ +png_push_save_buffer(png_structp png_ptr) +{ + if (png_ptr->save_buffer_size) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { + png_size_t i, istop; + png_bytep sp; + png_bytep dp; + + istop = png_ptr->save_buffer_size; + for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; + i < istop; i++, sp++, dp++) + { + *dp = *sp; + } + } + } + if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > + png_ptr->save_buffer_max) + { + png_size_t new_max; + png_bytep old_buffer; + + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + (png_ptr->current_buffer_size + 256)) + { + png_error(png_ptr, "Potential overflow of save_buffer"); + } + + new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; + old_buffer = png_ptr->save_buffer; + png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, + (png_size_t)new_max); + + if (png_ptr->save_buffer == NULL) + { + png_free(png_ptr, old_buffer); + png_error(png_ptr, "Insufficient memory for save_buffer"); + } + + png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + png_free(png_ptr, old_buffer); + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { + png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; + } + png_ptr->save_buffer_ptr = png_ptr->save_buffer; + png_ptr->buffer_size = 0; +} + +void /* PRIVATE */ +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + png_ptr->current_buffer = buffer; + png_ptr->current_buffer_size = buffer_length; + png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; + png_ptr->current_buffer_ptr = png_ptr->current_buffer; +} + +void /* PRIVATE */ +png_push_read_IDAT(png_structp png_ptr) +{ + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + png_byte chunk_tag[4]; + + /* TODO: this code can be commoned up with the same code in push_read */ + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + + if (png_ptr->chunk_name != png_IDAT) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_error(png_ptr, "Not enough compressed data"); + + return; + } + + png_ptr->idat_size = png_ptr->push_length; + } + + if (png_ptr->idat_size && png_ptr->save_buffer_size) + { + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. Do not cast in the following test - it + * will break on either 16 or 64 bit platforms. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + + if (png_ptr->idat_size && png_ptr->current_buffer_size) + { + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->idat_size) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_AFTER_IDAT; + } +} + +void /* PRIVATE */ +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + /* The caller checks for a non-zero buffer length. */ + if (!(buffer_length > 0) || buffer == NULL) + png_error(png_ptr, "No IDAT data (internal error)"); + + /* This routine must process all the data it has been given + * before returning, calling the row callback as required to + * handle the uncompressed results. + */ + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = (uInt)buffer_length; + + /* Keep going until the decompressed data is all processed + * or the stream marked as finished. + */ + while (png_ptr->zstream.avail_in > 0 && + !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { + int ret; + + /* We have data for zlib, but we must check that zlib + * has someplace to put the results. It doesn't matter + * if we don't expect any results -- it may be the input + * data is just the LZ end code. + */ + if (!(png_ptr->zstream.avail_out > 0)) + { + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + png_ptr->zstream.next_out = png_ptr->row_buf; + } + + /* Using Z_SYNC_FLUSH here means that an unterminated + * LZ stream (a stream with a missing end code) can still + * be handled, otherwise (Z_NO_FLUSH) a future zlib + * implementation might defer output and therefore + * change the current behavior (see comments in inflate.c + * for why this doesn't happen at present with zlib 1.2.5). + */ + ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); + + /* Check for any failure before proceeding. */ + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* Terminate the decompression. */ + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* This may be a truncated stream (missing or + * damaged end code). Treat that as a warning. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + png_warning(png_ptr, "Truncated compressed data in IDAT"); + + else + png_error(png_ptr, "Decompression error in IDAT"); + + /* Skip the check on unprocessed input */ + return; + } + + /* Did inflate output any data? */ + if (png_ptr->zstream.next_out != png_ptr->row_buf) + { + /* Is this unexpected data after the last row? + * If it is, artificially terminate the LZ output + * here. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + { + /* Extra data. */ + png_warning(png_ptr, "Extra compressed data in IDAT"); + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* Do no more processing; skip the unprocessed + * input check below. + */ + return; + } + + /* Do we have a complete row? */ + if (png_ptr->zstream.avail_out == 0) + png_push_process_row(png_ptr); + } + + /* And check for the end of the stream. */ + if (ret == Z_STREAM_END) + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + } + + /* All the data should have been processed, if anything + * is left at this point we have bytes of IDAT data + * after the zlib end code. + */ + if (png_ptr->zstream.avail_in > 0) + png_warning(png_ptr, "Extra compression data in IDAT"); +} + +void /* PRIVATE */ +png_push_process_row(png_structp png_ptr) +{ + /* 1.5.6: row_info moved out of png_struct to a local here. */ + png_row_info row_info; + + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced row count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "progressive row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal progressive row size calculation error"); + + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Blow up interlaced rows to full size */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + switch (png_ptr->pass) + { + case 0: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 0; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ + } + + if (png_ptr->pass == 2) /* Pass 1 might be empty */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + if (png_ptr->pass == 4 && png_ptr->height <= 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + if (png_ptr->pass == 6 && png_ptr->height <= 4) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + case 1: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 1; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 2) /* Skip top 4 generated rows */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 2: + { + int i; + + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 4) /* Pass 3 might be empty */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 3: + { + int i; + + for (i = 0; i < 4 && png_ptr->pass == 3; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 4) /* Skip top two generated rows */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 4: + { + int i; + + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 6) /* Pass 5 might be empty */ + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + case 5: + { + int i; + + for (i = 0; i < 2 && png_ptr->pass == 5; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 6) /* Skip top generated row */ + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + default: + case 6: + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + + if (png_ptr->pass != 6) + break; + + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + } + else +#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } +} + +void /* PRIVATE */ +png_read_push_finish_row(png_structp png_ptr) +{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + + /* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ + + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { + png_ptr->pass++; + if ((png_ptr->pass == 1 && png_ptr->width < 5) || + (png_ptr->pass == 3 && png_ptr->width < 3) || + (png_ptr->pass == 5 && png_ptr->width < 2)) + png_ptr->pass++; + + if (png_ptr->pass > 7) + png_ptr->pass--; + + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + if (png_ptr->transformations & PNG_INTERLACE) + break; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); + } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ +} + +#ifdef PNG_READ_tEXt_SUPPORTED +void /* PRIVATE */ +png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place tEXt"); + /* NOT REACHED */ + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_size_t)(length + 1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_tEXt_MODE; +} + +void /* PRIVATE */ +png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + + else + text_size = png_ptr->current_text_left; + + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#ifdef PNG_MAX_MALLOC_64K + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* Empty loop */ ; + + if (text < key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; + text_ptr->itxt_length = 0; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + png_ptr->current_text = NULL; + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk"); + } +} +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +void /* PRIVATE */ +png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place zTXt"); + /* NOT REACHED */ + } + +#ifdef PNG_MAX_MALLOC_64K + /* We can't handle zTXt chunks > 64K, since we don't have enough space + * to be able to store the uncompressed data. Actually, the threshold + * is probably around 32K, but it isn't as definite as 64K is. + */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_push_crc_skip(png_ptr, length); + return; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_size_t)(length + 1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_zTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + + else + text_size = png_ptr->current_text_left; + + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + png_size_t text_size, key_size; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* Empty loop */ ; + + /* zTXt can't have zero text */ + if (text >= key + png_ptr->current_text_size) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + png_ptr->zstream.next_in = (png_bytep)text; + png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - + (text - key)); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + key_size = text - key; + text_size = 0; + text = NULL; + ret = Z_STREAM_END; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + + if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) + { + if (text == NULL) + { + text = (png_charp)png_malloc(png_ptr, + (png_ptr->zbuf_size + - png_ptr->zstream.avail_out + key_size + 1)); + + png_memcpy(text + key_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + + png_memcpy(text, key, key_size); + + text_size = key_size + png_ptr->zbuf_size - + png_ptr->zstream.avail_out; + + *(text + text_size) = '\0'; + } + + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc(png_ptr, text_size + + (png_ptr->zbuf_size + - png_ptr->zstream.avail_out + 1)); + + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + + png_memcpy(text + text_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; + } + + if (ret != Z_STREAM_END) + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + else + { + break; + } + + if (ret == Z_STREAM_END) + break; + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (ret != Z_STREAM_END) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + + png_ptr->current_text = NULL; + png_free(png_ptr, key); + key = text; + text += key_size; + + text_ptr = (png_textp)png_malloc(png_ptr, + png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr->key = key; + text_ptr->itxt_length = 0; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk"); + } +} +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED +void /* PRIVATE */ +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place iTXt"); + /* NOT REACHED */ + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_size_t)(length + 1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_iTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) +{ + + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + + else + text_size = png_ptr->current_text_left; + + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp key; + int comp_flag; + png_charp lang; + png_charp lang_key; + png_charp text; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#ifdef PNG_MAX_MALLOC_64K + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (lang = key; *lang; lang++) + /* Empty loop */ ; + + if (lang < key + png_ptr->current_text_size - 3) + lang++; + + comp_flag = *lang++; + lang++; /* Skip comp_type, always zero */ + + for (lang_key = lang; *lang_key; lang_key++) + /* Empty loop */ ; + + lang_key++; /* Skip NUL separator */ + + text=lang_key; + + if (lang_key < key + png_ptr->current_text_size - 1) + { + for (; *text; text++) + /* Empty loop */ ; + } + + if (text < key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, + png_sizeof(png_text)); + + text_ptr->compression = comp_flag + 2; + text_ptr->key = key; + text_ptr->lang = lang; + text_ptr->lang_key = lang_key; + text_ptr->text = text; + text_ptr->text_length = 0; + text_ptr->itxt_length = png_strlen(text); + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_ptr->current_text = NULL; + + png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to store iTXt chunk"); + } +} +#endif + +/* This function is called when we haven't found a handler for this + * chunk. If there isn't a problem with the chunk itself (ie a bad chunk + * name or a critical chunk), the chunk is (currently) silently ignored. + */ +void /* PRIVATE */ +png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + png_uint_32 skip = 0; + png_uint_32 chunk_name = png_ptr->chunk_name; + + if (PNG_CHUNK_CRITICAL(chunk_name)) + { +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + } + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* TODO: the code below is apparently just using the + * png_struct::unknown_chunk member as a temporarily variable, it should be + * possible to eliminate both it and the temporary buffer. + */ + if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) + { +#ifdef PNG_MAX_MALLOC_64K + if (length > 65535) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - 65535; + length = 65535; + } +#endif + /* This is just a record for the user; libpng doesn't use the character + * form of the name. + */ + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + + /* The following cast should be safe because of the check above. */ + png_ptr->unknown_chunk.size = (png_size_t)length; + + if (length == 0) + png_ptr->unknown_chunk.data = NULL; + + else + { + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, + png_ptr->unknown_chunk.size); + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, + png_ptr->unknown_chunk.size); + } + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + if (png_ptr->read_user_chunk_fn != NULL) + { + /* Callback to user unknown chunk handler */ + int ret; + ret = (*(png_ptr->read_user_chunk_fn)) + (png_ptr, &png_ptr->unknown_chunk); + + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + if (ret == 0) + { + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) + png_chunk_error(png_ptr, "unknown critical chunk"); + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } + + else +#endif + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + + else +#endif + skip=length; + png_push_crc_skip(png_ptr, skip); +} + +void /* PRIVATE */ +png_push_have_info(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_end(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr->row_fn != NULL) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, + (int)png_ptr->pass); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void PNGAPI +png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, + png_const_bytep new_row) +{ + if (png_ptr == NULL) + return; + + /* new_row is a flag here - if it is NULL then the app callback was called + * from an empty row (see the calls to png_struct::row_fn below), otherwise + * it must be png_ptr->row_buf+1 + */ + if (new_row != NULL) + png_combine_row(png_ptr, old_row, 1/*display*/); +} +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +void PNGAPI +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->info_fn = info_fn; + png_ptr->row_fn = row_fn; + png_ptr->end_fn = end_fn; + + png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); +} + +png_voidp PNGAPI +png_get_progressive_ptr(png_const_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return png_ptr->io_ptr; +} +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/WDL/libpng/pngpriv.h b/WDL/libpng/pngpriv.h new file mode 100644 index 00000000..5f751de2 --- /dev/null +++ b/WDL/libpng/pngpriv.h @@ -0,0 +1,1629 @@ + +/* pngpriv.h - private declarations for use inside libpng + * + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* The symbols declared in this file (including the functions declared + * as PNG_EXTERN) are PRIVATE. They are not part of the libpng public + * interface, and are not recommended for use by regular applications. + * Some of them may become public in the future; others may stay private, + * change in an incompatible way, or even disappear. + * Although the libpng users are not forbidden to include this header, + * they should be well aware of the issues that may arise from doing so. + */ + +#ifndef PNGPRIV_H +#define PNGPRIV_H + +/* Feature Test Macros. The following are defined here to ensure that correctly + * implemented libraries reveal the APIs libpng needs to build and hide those + * that are not needed and potentially damaging to the compilation. + * + * Feature Test Macros must be defined before any system header is included (see + * POSIX 1003.1 2.8.2 "POSIX Symbols." + * + * These macros only have an effect if the operating system supports either + * POSIX 1003.1 or C99, or both. On other operating systems (particularly + * Windows/Visual Studio) there is no effect; the OS specific tests below are + * still required (as of 2011-05-02.) + */ +#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ + +/* This is required for the definition of abort(), used as a last ditch + * error handler when all else fails. + */ +#include + +/* This is used to find 'offsetof', used below for alignment tests. */ +#include + +#define PNGLIB_BUILD /*libpng is being built, not used*/ + +#ifdef PNG_USER_CONFIG +# include "pngusr.h" + /* These should have been defined in pngusr.h */ +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD "Custom libpng build" +# endif +# ifndef PNG_USER_DLLFNAME_POSTFIX +# define PNG_USER_DLLFNAME_POSTFIX "Cb" +# endif +#endif + +/* Is this a build of a DLL where compilation of the object modules requires + * different preprocessor settings to those required for a simple library? If + * so PNG_BUILD_DLL must be set. + * + * If libpng is used inside a DLL but that DLL does not export the libpng APIs + * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a + * static library of libpng then link the DLL against that. + */ +#ifndef PNG_BUILD_DLL +# ifdef DLL_EXPORT + /* This is set by libtool when files are compiled for a DLL; libtool + * always compiles twice, even on systems where it isn't necessary. Set + * PNG_BUILD_DLL in case it is necessary: + */ +# define PNG_BUILD_DLL +# else +# ifdef _WINDLL + /* This is set by the Microsoft Visual Studio IDE in projects that + * build a DLL. It can't easily be removed from those projects (it + * isn't visible in the Visual Studio UI) so it is a fairly reliable + * indication that PNG_IMPEXP needs to be set to the DLL export + * attributes. + */ +# define PNG_BUILD_DLL +# else +# ifdef __DLL__ + /* This is set by the Borland C system when compiling for a DLL + * (as above.) + */ +# define PNG_BUILD_DLL +# else + /* Add additional compiler cases here. */ +# endif +# endif +# endif +#endif /* Setting PNG_BUILD_DLL if required */ + +/* See pngconf.h for more details: the builder of the library may set this on + * the command line to the right thing for the specific compilation system or it + * may be automagically set above (at present we know of no system where it does + * need to be set on the command line.) + * + * PNG_IMPEXP must be set here when building the library to prevent pngconf.h + * setting it to the "import" setting for a DLL build. + */ +#ifndef PNG_IMPEXP +# ifdef PNG_BUILD_DLL +# define PNG_IMPEXP PNG_DLL_EXPORT +# else + /* Not building a DLL, or the DLL doesn't require specific export + * definitions. + */ +# define PNG_IMPEXP +# endif +#endif + +/* No warnings for private or deprecated functions in the build: */ +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE +#endif + +#include "png.h" +#include "pnginfo.h" +#include "pngstruct.h" + +/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ +#ifndef PNG_DLL_EXPORT +# define PNG_DLL_EXPORT +#endif + +/* This is used for 16 bit gamma tables - only the top level pointers are const, + * this could be changed: + */ +typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; + +/* Added at libpng-1.2.9 */ +/* Moved to pngpriv.h at libpng-1.5.0 */ + +/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" + * script. We may need it here to get the correct configuration on things + * like limits. + */ +#ifdef PNG_CONFIGURE_LIBPNG +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +#endif + +/* Moved to pngpriv.h at libpng-1.5.0 */ +/* NOTE: some of these may have been used in external applications as + * these definitions were exposed in pngconf.h prior to 1.5. + */ + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. + * + * zlib provides 'MAXSEG_64K' which, if defined, indicates the + * same limit and pngconf.h (already included) sets the limit + * if certain operating systems are detected. + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +#ifndef PNG_UNUSED +/* Unused formal parameter warnings are silenced using the following macro + * which is expected to have no bad effects on performance (optimizing + * compilers will probably remove it entirely). Note that if you replace + * it with something other than whitespace, you must include the terminating + * semicolon. + */ +# define PNG_UNUSED(param) (void)param; +#endif + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* PNG_STATIC is used to mark internal file scope functions if they need to be + * accessed for implementation tests (see the code in tests/?*). + */ +#ifndef PNG_STATIC +# define PNG_STATIC static +#endif + +/* C99 restrict is used where possible, to do this 'restrict' is defined as + * empty if we can't be sure it is supported. configure builds have already + * done this work. + */ +#ifdef PNG_CONFIGURE_LIBPNG +# define PNG_RESTRICT restrict +#else + /* Modern compilers support restrict, but assume not for anything not + * recognized here: + */ +# if defined __GNUC__ || defined _MSC_VER || defined __WATCOMC__ +# define PNG_RESTRICT restrict +# else +# define PNG_RESTRICT +# endif +#endif + +/* If warnings or errors are turned off the code is disabled or redirected here. + * From 1.5.4 functions have been added to allow very limited formatting of + * error and warning messages - this code will also be disabled here. + */ +#ifdef PNG_WARNINGS_SUPPORTED +# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +# define png_warning_parameter(p,number,string) ((void)0) +# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) +# define png_warning_parameter_signed(p,number,format,value) ((void)0) +# define png_formatted_warning(pp,p,message) ((void)(pp)) +# define PNG_WARNING_PARAMETERS(p) +#endif +#ifndef PNG_ERROR_TEXT_SUPPORTED +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +# define png_fixed_error(s1,s2) png_err(s1) +#endif + +/* C allows up-casts from (void*) to any pointer and (const void*) to any + * pointer to a const object. C++ regards this as a type error and requires an + * explicit, static, cast and provides the static_cast<> rune to ensure that + * const is not cast away. + */ +#ifdef __cplusplus +# define png_voidcast(type, value) static_cast(value) +#else +# define png_voidcast(type, value) (value) +#endif /* __cplusplus */ + +#ifndef PNG_EXTERN +/* The functions exported by PNG_EXTERN are internal functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it + * is possible to have run-time registry of chunk-handling functions, + * some of these might be made available again. + * + * 1.5.7: turned the use of 'extern' back on, since it is localized to pngpriv.h + * it should be safe now (it is unclear why it was turned off.) + */ +# define PNG_EXTERN extern +#endif + +/* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic + * deals with this: + */ +#ifdef PNG_FIXED_POINT_SUPPORTED +# define PNGFAPI PNGAPI +#else +# define PNGFAPI /* PRIVATE */ +#endif + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + /* png.c requires the following ANSI-C constants if the conversion of + * floating point to ASCII is implemented therein: + * + * DBL_DIG Maximum number of decimal digits (can be set to any constant) + * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) + * DBL_MAX Maximum floating point number (can be set to an arbitrary value) + */ +# include + +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ + defined(_WIN32) || defined(__WIN32__) +# include /* defines _WINDOWS_ macro */ +#endif + +/* Moved here around 1.5.0beta36 from pngconf.h */ +/* Users may want to use these so they are not private. Any library + * functions that are passed far data must be model-independent. + */ + +/* Memory model/platform independent fns */ +#ifndef PNG_ABORT +# ifdef _WINDOWS_ +# define PNG_ABORT() ExitProcess(0) +# else +# define PNG_ABORT() abort() +# endif +#endif + +#ifdef USE_FAR_KEYWORD +/* Use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else +# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strlen lstrlenA +# define png_memcmp memcmp +# define png_memcpy CopyMemory +# define png_memset memset +# else +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +# endif +#endif + +/* These macros may need to be architecture dependent. */ +#define PNG_ALIGN_NONE 0 /* do not use data alignment */ +#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ +#ifdef offsetof +# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ +#else +# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ +#endif +#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ + +#ifndef PNG_ALIGN_TYPE + /* Default to using aligned access optimizations and requiring alignment to a + * multiple of the data type size. Override in a compiler specific fashion + * if necessary by inserting tests here: + */ +# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE +#endif + +#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE + /* This is used because in some compiler implementations non-aligned + * structure members are supported, so the offsetof approach below fails. + * Set PNG_ALIGN_TO_SIZE=0 for compiler combinations where unaligned access + * is good for performance. Do not do this unless you have tested the result + * and understand it. + */ +# define png_alignof(type) (sizeof (type)) +#else +# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET +# define png_alignof(type) offsetof(struct{char c; type t;}, t) +# else +# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS +# define png_alignof(type) (1) +# endif + /* Else leave png_alignof undefined to prevent use thereof */ +# endif +#endif + +/* This implicitly assumes alignment is always to a power of 2. */ +#ifdef png_alignof +# define png_isaligned(ptr, type)\ + ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) +#else +# define png_isaligned(ptr, type) 0 +#endif + +/* End of memory model/platform independent support */ +/* End of 1.5.0beta36 move from pngconf.h */ + +/* CONSTANTS and UTILITY MACROS + * These are used internally by libpng and not exposed in the API + */ + +/* Various modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. Three of these + * are defined in png.h because they need to be visible to applications + * that call png_set_unknown_chunk(). + */ +/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */ +/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */ +#define PNG_HAVE_IDAT 0x04 +/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ +#define PNG_HAVE_IEND 0x10 +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* Flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_QUANTIZE 0x0040 +#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ +#define PNG_BACKGROUND_EXPAND 0x0100 +#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ +#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000 +#define PNG_PACKSWAP 0x10000 +#define PNG_SWAP_ALPHA 0x20000 +#define PNG_STRIP_ALPHA 0x40000 +#define PNG_INVERT_ALPHA 0x80000 +#define PNG_USER_TRANSFORM 0x100000 +#define PNG_RGB_TO_GRAY_ERR 0x200000 +#define PNG_RGB_TO_GRAY_WARN 0x400000 +#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ +#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ +#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ +#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ + /* 0x8000000 unused */ + /* 0x10000000 unused */ + /* 0x20000000 unused */ + /* 0x40000000 unused */ +/* Flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* Flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000 + /* 0x200000 unused */ + /* 0x400000 unused */ +#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000 /* Added to libpng-1.4.0 */ +#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000 /* 5 lines added */ +#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000 /* to libpng-1.5.4 */ +#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000 +#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000 +#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000 + /* 0x20000000 unused */ + /* 0x40000000 unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib + * can handle at once. This type need be no larger than 16 bits (so maximum of + * 65535), this define allows us to discover how big it is, but limited by the + * maximuum for png_size_t. The value can be overriden in a library build + * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably + * lower value (e.g. 255 works). A lower value may help memory usage (slightly) + * and may even improve performance on some systems (and degrade it on others.) + */ +#ifndef ZLIB_IO_MAX +# define ZLIB_IO_MAX ((uInt)-1) +#endif + +/* Save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ + (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + * ideal-delta..ideal+delta. Each argument is evaluated twice. + * "ideal" and "delta" should be constants, normally simple + * integers, "value" a variable. Added to libpng-1.2.6 JB + */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* Conversions between fixed and floating point, only defined if + * required (to make sure the code doesn't accidentally use float + * when it is supposedly disabled.) + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* The floating point conversion can't overflow, though it can and + * does lose accuracy relative to the original fixed point value. + * In practice this doesn't matter because png_fixed_point only + * stores numbers with very low precision. The png_ptr and s + * arguments are unused by default but are there in case error + * checking becomes a requirement. + */ +#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) + +/* The fixed point conversion performs range checking and evaluates + * its argument multiple times, so must be used with care. The + * range checking uses the PNG specification values for a signed + * 32 bit fixed point value except that the values are deliberately + * rounded-to-zero to an integral value - 21474 (21474.83 is roughly + * (2^31-1) * 100000). 's' is a string that describes the value being + * converted. + * + * NOTE: this macro will raise a png_error if the range check fails, + * therefore it is normally only appropriate to use this on values + * that come from API calls or other sources where an out of range + * error indicates a programming error, not a data error! + * + * NOTE: by default this is off - the macro is not used - because the + * function call saves a lot of code. + */ +#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED +#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +#else +PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, + png_const_charp text)); +#endif +#endif + +/* Constants for known chunk types. If you need to add a chunk, define the name + * here. For historical reasons these constants have the form png_; i.e. + * the prefix is lower case. Please use decimal values as the parameters to + * match the ISO PNG specification and to avoid relying on the C locale + * interpretation of character values. + * + * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values + * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string + * to be generated if required. + * + * PNG_32b correctly produces a value shifted by up to 24 bits, even on + * architectures where (int) is only 16 bits. + */ +#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) +#define PNG_CHUNK(b1,b2,b3,b4) \ + (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) + +#define png_IHDR PNG_CHUNK( 73, 72, 68, 82) +#define png_IDAT PNG_CHUNK( 73, 68, 65, 84) +#define png_IEND PNG_CHUNK( 73, 69, 78, 68) +#define png_PLTE PNG_CHUNK( 80, 76, 84, 69) +#define png_bKGD PNG_CHUNK( 98, 75, 71, 68) +#define png_cHRM PNG_CHUNK( 99, 72, 82, 77) +#define png_gAMA PNG_CHUNK(103, 65, 77, 65) +#define png_hIST PNG_CHUNK(104, 73, 83, 84) +#define png_iCCP PNG_CHUNK(105, 67, 67, 80) +#define png_iTXt PNG_CHUNK(105, 84, 88, 116) +#define png_oFFs PNG_CHUNK(111, 70, 70, 115) +#define png_pCAL PNG_CHUNK(112, 67, 65, 76) +#define png_sCAL PNG_CHUNK(115, 67, 65, 76) +#define png_pHYs PNG_CHUNK(112, 72, 89, 115) +#define png_sBIT PNG_CHUNK(115, 66, 73, 84) +#define png_sPLT PNG_CHUNK(115, 80, 76, 84) +#define png_sRGB PNG_CHUNK(115, 82, 71, 66) +#define png_sTER PNG_CHUNK(115, 84, 69, 82) +#define png_tEXt PNG_CHUNK(116, 69, 88, 116) +#define png_tIME PNG_CHUNK(116, 73, 77, 69) +#define png_tRNS PNG_CHUNK(116, 82, 78, 83) +#define png_zTXt PNG_CHUNK(122, 84, 88, 116) + +/* The following will work on (signed char*) strings, whereas the get_uint_32 + * macro will fail on top-bit-set values because of the sign extension. + */ +#define PNG_CHUNK_FROM_STRING(s)\ + PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) + +/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is + * signed and the argument is a (char[]) This macro will fail miserably on + * systems where (char) is more than 8 bits. + */ +#define PNG_STRING_FROM_CHUNK(s,c)\ + (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ + ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) + +/* Do the same but terminate with a null character. */ +#define PNG_CSTRING_FROM_CHUNK(s,c)\ + (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) + +/* Test on flag values as defined in the spec (section 5.4): */ +#define PNG_CHUNK_ANCILLIARY(c) (1 & ((c) >> 29)) +#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLIARY(c)) +#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) +#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) +#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) + +/* Gamma values (new at libpng-1.5.4): */ +#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ +#define PNG_GAMMA_MAC_INVERSE 65909 +#define PNG_GAMMA_sRGB_INVERSE 45455 + + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* These functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + +/* Check the user version string for compatibility, returns false if the version + * numbers aren't compatible. + */ +PNG_EXTERN int png_user_version_check(png_structp png_ptr, + png_const_charp user_png_ver); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), + PNG_ALLOCATED); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, + PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), + PNG_ALLOCATED); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* Function to allocate memory for zlib. PNGAPI is disallowed. */ +PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, + uInt size)),PNG_ALLOCATED); + +/* Function to free memory for zlib. PNGAPI is disallowed. */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +/* Next four functions are used internally as callbacks. PNGCBAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 + */ + +PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED +PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); +# endif +#endif + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Read and check the PNG file signature */ +PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); + +/* Read the chunk header (length + type name) */ +PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_READ_COMPRESSED_TEXT_SUPPORTED) +PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_size_t chunklength, png_size_t prefix_length, + png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, + png_const_bytep ptr, png_size_t length)); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* Write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, + png_const_colorp palette, png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#ifdef PNG_WRITE_gAMA_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +# endif +# ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, + png_fixed_point file_gamma)); +# endif +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, + png_const_color_8p sbit, int color_type)); +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +# endif +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_const_charp name, int compression_type, + png_const_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_const_sPLT_tp palette)); +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, + int color_type)); +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_const_color_16p values, int color_type)); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, + png_const_uint_16p hist, int num_hist)); +#endif + +/* Chunks that have keywords */ +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_const_charp key, png_charpp new_key)); +#endif + +#ifdef PNG_WRITE_tEXt_SUPPORTED +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len)); +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len, int compression)); +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_const_charp key, png_const_charp lang, + png_const_charp lang_key, png_const_charp text)); +#endif + +#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_const_timep mod_time)); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_const_charp width, png_const_charp height)); +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an + * array of png_ptr->width pixels. If the image is not interlaced or this + * is the final pass this just does a png_memcpy, otherwise the "display" flag + * is used to determine whether to copy pixels that are not in the current pass. + * + * Because 'png_do_read_interlace' (below) replicates pixels this allows this + * function to achieve the documented 'blocky' appearance during interlaced read + * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' + * are not changed if they are not in the current pass, when display is 0. + * + * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. + * + * The API always reads from the png_struct row buffer and always assumes that + * it is full width (png_do_read_interlace has already been called.) + * + * This function is only ever used to write to row buffers provided by the + * caller of the relevant libpng API and the row must have already been + * transformed by the read transformations. + * + * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed + * bitmasks for use within the code, otherwise runtime generated masks are used. + * The default is compile time masks. + */ +#ifndef PNG_USE_COMPILE_TIME_MASKS +# define PNG_USE_COMPILE_TIME_MASKS 1 +#endif +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int display)); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Expand an interlaced row: the 'row_info' describes the pass data that has + * been read in and must correspond to the pixels in 'row', the pixels are + * expanded (moved apart) in 'row' to match the final layout, when doing this + * the pixels are *replicated* to the intervening space. This is essential for + * the correct operation of png_combine_row, above. + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* Unfilter a row: check the filter value before calling this, there is no point + * calling it for PNG_FILTER_VALUE_NONE. + */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp pp, png_row_infop row_info, + png_bytep row, png_const_bytep prev_row, int filter)); + +PNG_EXTERN void png_read_filter_row_up_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_sub3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_sub4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_avg3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_avg4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_paeth3_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); +PNG_EXTERN void png_read_filter_row_paeth4_neon PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* Initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* These are the functions that do the transformations */ +#ifdef PNG_READ_FILLER_SUPPORTED +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info, + png_bytep row, int at_start)); +#endif + +#ifdef PNG_16BIT_SUPPORTED +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, + png_bytep row)); +#endif +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep palette_lookup, + png_const_bytep quantize_lookup)); + +# ifdef PNG_CORRECT_PALETTE_SUPPORTED +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) +PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info, + png_bytep row, png_structp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_const_colorp palette, png_const_bytep trans, + int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_16p trans_color)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* Decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#ifdef PNG_READ_bKGD_SUPPORTED +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED +PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_iTXt_SUPPORTED +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED +PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_sRGB_SUPPORTED +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +#endif + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_uint_32 chunk_name)); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk + * name, not a string. + */ +PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr, + png_uint_32 chunk_name)); +#endif + +/* Handle the transformations for reading and writing */ +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); +#endif +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +# ifdef PNG_READ_tEXt_SUPPORTED +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +# endif +# ifdef PNG_READ_zTXt_SUPPORTED +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +# endif +# ifdef PNG_READ_iTXt_SUPPORTED +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +# endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +/* Added at libpng version 1.4.0 */ +#ifdef PNG_CHECK_cHRM_SUPPORTED +PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 and 1.4.0 */ +/* Currently only used by png_check_cHRM_fixed */ +PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, + unsigned long *hi_product, unsigned long *lo_product)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +/* Added at libpng version 1.5.5 */ +typedef struct png_xy +{ + png_fixed_point redx, redy; + png_fixed_point greenx, greeny; + png_fixed_point bluex, bluey; + png_fixed_point whitex, whitey; +} png_xy; + +typedef struct png_XYZ +{ + png_fixed_point redX, redY, redZ; + png_fixed_point greenX, greenY, greenZ; + png_fixed_point blueX, blueY, blueZ; +} png_XYZ; + +/* The conversion APIs return 0 on success, non-zero on a parameter error. They + * allow conversion between the above representations of a color encoding. When + * converting from XYZ end points to chromaticities the absolute magnitude of + * the end points is lost, when converting back the sum of the Y values of the + * three end points will be 1.0 + */ +PNG_EXTERN int png_xy_from_XYZ PNGARG((png_xy *xy, png_XYZ XYZ)); +PNG_EXTERN int png_XYZ_from_xy PNGARG((png_XYZ *XYZ, png_xy xy)); +PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr, + png_XYZ *XYZ, png_xy xy)); +#endif + +/* Added at libpng version 1.4.0 */ +PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type)); + +/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ +PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr, png_infop end_info_ptr)); + +/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); + +#ifdef USE_FAR_KEYWORD /* memory model conversion function */ +PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, + png_const_charp name),PNG_NORETURN); +#endif + +/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite + * the end. Always leaves the buffer nul terminated. Never errors out (and + * there is no error code.) + */ +PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, + png_const_charp string); + +/* Various internal functions to handle formatted warning messages, currently + * only implemented for warnings. + */ +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. This utility only + * does unsigned values. + */ +PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end, + int format, png_alloc_size_t number); + +/* Convenience macro that takes an array: */ +#define PNG_FORMAT_NUMBER(buffer,format,number) \ + png_format_number(buffer, buffer + (sizeof buffer), format, number) + +/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ +#define PNG_NUMBER_BUFFER_SIZE 24 + +/* These are the integer formats currently supported, the name is formed from + * the standard printf(3) format string. + */ +#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ +#define PNG_NUMBER_FORMAT_02u 2 +#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ +#define PNG_NUMBER_FORMAT_02d 2 +#define PNG_NUMBER_FORMAT_x 3 +#define PNG_NUMBER_FORMAT_02x 4 +#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* New defines and members adding in libpng-1.5.4 */ +# define PNG_WARNING_PARAMETER_SIZE 32 +# define PNG_WARNING_PARAMETER_COUNT 8 + +/* An l-value of this type has to be passed to the APIs below to cache the + * values of the parameters to a formatted warning message. + */ +typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ + PNG_WARNING_PARAMETER_SIZE]; + +PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number, + png_const_charp string); + /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, + * including the trailing '\0'. + */ +PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p, + int number, int format, png_alloc_size_t value); + /* Use png_alloc_size_t because it is an unsigned type as big as any we + * need to output. Use the following for a signed value. + */ +PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p, + int number, int format, png_int_32 value); + +PNG_EXTERN void png_formatted_warning(png_structp png_ptr, + png_warning_parameters p, png_const_charp message); + /* 'message' follows the X/Open approach of using @1, @2 to insert + * parameters previously supplied using the above functions. Errors in + * specifying the paramters will simple result in garbage substitutions. + */ +#endif + +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +#if defined(PNG_READ_sCAL_SUPPORTED) +/* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant + * digits - a build time settable option) and assumpitions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) + +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, + png_size_t size, double fp, unsigned int precision)); +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, + png_charp ascii, png_size_t size, png_fixed_point fp)); +#endif /* FIXED_POINT */ +#endif /* READ_sCAL */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* An internal API to validate the format of a floating point number. + * The result is the index of the next character. If the number is + * not valid it will be the index of a character in the supposed number. + * + * The format of a number is defined in the PNG extensions specification + * and this API is strictly conformant to that spec, not anyone elses! + * + * The format as a regular expression is: + * + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? + * + * or: + * + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? + * + * The complexity is that either integer or fraction must be present and the + * fraction is permitted to have no digits only if the integer is present. + * + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * + * PNG floating point numb1.ers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this + * doesn't matter for PNG sCAL chunk values, but it requires more care + * if the value were ever to be embedded in something more complex. Use + * ANSI-C strtod if you need the lookahead. + */ +/* State table for the parser. */ +#define PNG_FP_INTEGER 0 /* before or in integer */ +#define PNG_FP_FRACTION 1 /* before or in fraction */ +#define PNG_FP_EXPONENT 2 /* before or in exponent */ +#define PNG_FP_STATE 3 /* mask for the above */ +#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ +#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ +#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ +#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ +#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ + +/* These three values don't affect the parser. They are set but not used. + */ +#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ +#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ +#define PNG_FP_NONZERO 256 /* A non-zero value */ +#define PNG_FP_STICKY 448 /* The above three flags */ + +/* This is available for the caller to store in 'state' if required. Do not + * call the parser after setting it (the parser sometimes clears it.) + */ +#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ + +/* Result codes for the parser (boolean - true meants ok, false means + * not ok yet.) + */ +#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ +#define PNG_FP_OK 1 /* The number is valid */ + +/* Tests on the sticky non-zero and negative flags. To pass these checks + * the state must also indicate that the whole number is valid - this is + * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this + * is equivalent to PNG_FP_OK above.) + */ +#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) + /* NZ_MASK: the string is valid and a non-zero negative value */ +#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) + /* Z MASK: the string is valid and a non-zero value. */ + /* PNG_FP_SAW_DIGIT: the string is valid. */ +#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) +#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) +#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) + +/* The actual parser. This can be called repeatedly, it updates + * the index into the string and the state variable (which must + * be initialzed to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * + * Note that the pointer will consume an E or even an E+ then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling + * the parser again (from the start, with state 0) but with a string + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, + png_size_t size, int *statep, png_size_tp whereami)); + +/* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. As of 1.5.4 this + * function also returns the state at the end of parsing the number if + * it was valid (otherwise it returns 0.) This can be used for testing + * for negative or zero values using the sticky flag. + */ +PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, + png_size_t size)); +#endif /* pCAL || sCAL */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) +/* Added at libpng version 1.5.0 */ +/* This is a utility to provide a*times/div (rounded) and indicate + * if there is an overflow. The result is a boolean - false (0) + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, + png_int_32 multiplied_by, png_int_32 divided_by)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Same deal, but issue a warning on overflow and return 0. */ +PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, + png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Calculate a reciprocal - used for gamma values. This returns + * 0 if the argument is 0 in order to maintain an undefined value, + * there are no warnings. + */ +PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); + +/* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is + * not exact - use png_muldiv for that. + */ +PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, + png_fixed_point b)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Internal fixed point gamma correction. These APIs are called as + * required to convert single values - they don't need to be fast, + * they are not used when processing image pixel values. + * + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, + unsigned int value, png_fixed_point gamma_value)); +PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value)); +PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, + png_fixed_point gamma_value)); +PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, + png_fixed_point gamma_value)); +PNG_EXTERN void png_destroy_gamma_table(png_structp png_ptr); +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, + int bit_depth)); +#endif + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#include "pngdebug.h" + +#ifdef __cplusplus +} +#endif + +#endif /* PNGPRIV_H */ diff --git a/WDL/libpng/pngread.c b/WDL/libpng/pngread.c new file mode 100644 index 00000000..e2641d54 --- /dev/null +++ b/WDL/libpng/pngread.c @@ -0,0 +1,1308 @@ + +/* pngread.c - read a PNG file + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that an application calls directly to + * read a PNG file or stream. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* Create a PNG structure for reading, and allocate any memory needed. */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) +{ + +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL)); +} + +/* Alternate create PNG structure for reading, and allocate any memory + * needed. + */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif + png_structp png_ptr; + volatile int png_cleanup_needed = 0; + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf tmp_jmpbuf; +#endif +#endif + + png_debug(1, "in png_create_read_struct"); + +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + malloc_fn, mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif + if (png_ptr == NULL) + return (NULL); + + /* Added at libpng-1.2.6 */ +#ifdef PNG_USER_LIMITS_SUPPORTED + png_ptr->user_width_max = PNG_USER_WIDTH_MAX; + png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; + +# ifdef PNG_USER_CHUNK_CACHE_MAX + /* Added at libpng-1.2.43 and 1.4.0 */ + png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; +# endif + +# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX + /* Added at libpng-1.2.43 and 1.4.1 */ + png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; +# endif +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then + * encounter a png_error() will longjmp here. Since the jmpbuf is + * then meaningless we abort instead of returning. + */ +#ifdef USE_FAR_KEYWORD + if (setjmp(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ +#endif + PNG_ABORT(); +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif + + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + /* Call the general version checker (shared with read and write code): */ + if (!png_user_version_check(png_ptr, user_png_ver)) + png_cleanup_needed = 1; + + if (!png_cleanup_needed) + { + /* Initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); + + if (png_ptr->zbuf == NULL) + png_cleanup_needed = 1; + } + + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + if (!png_cleanup_needed) + { + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: + break; /* Do nothing */ + + case Z_MEM_ERROR: + png_warning(png_ptr, "zlib memory error"); + png_cleanup_needed = 1; + break; + + case Z_STREAM_ERROR: + png_warning(png_ptr, "zlib stream error"); + png_cleanup_needed = 1; + break; + + case Z_VERSION_ERROR: + png_warning(png_ptr, "zlib version error"); + png_cleanup_needed = 1; + break; + + default: png_warning(png_ptr, "Unknown zlib error"); + png_cleanup_needed = 1; + } + } + + if (png_cleanup_needed) + { + /* Clean up PNG structure and deallocate any memory. */ + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, + (png_free_ptr)free_fn, (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + return (NULL); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, NULL, NULL); + + + return (png_ptr); +} + + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. This has been + * changed in v0.90 to allow reading a file that already has the magic + * bytes read from the stream. You can tell libpng how many bytes have + * been read from the beginning of the stream (up to the maximum of 8) + * via png_set_sig_bytes(), and we will only check the remaining bytes + * here. The application can then have access to the signature bytes we + * read if it is determined that this isn't a valid PNG file. + */ +void PNGAPI +png_read_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Read and check the PNG file signature. */ + png_read_sig(png_ptr, info_ptr); + + for (;;) + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ + if (chunk_name == png_IDAT) + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + + else if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) + { + if (chunk_name == png_IDAT) + png_ptr->mode |= PNG_HAVE_IDAT; + + png_handle_unknown(png_ptr, info_ptr, length); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + break; + } + } +#endif + else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + + else if (chunk_name == png_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + png_ptr->idat_size = length; + png_ptr->mode |= PNG_HAVE_IDAT; + break; + } + +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED + else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED + else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED + else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + + else + png_handle_unknown(png_ptr, info_ptr, length); + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +/* Optional call to update the users info_ptr structure */ +void PNGAPI +png_read_update_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_update_info"); + + if (png_ptr == NULL) + return; + + png_read_start_row(png_ptr); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_read_transform_info(png_ptr, info_ptr); +#else + PNG_UNUSED(info_ptr) +#endif +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Initialize palette, background, etc, after transformations + * are set, but before any reading takes place. This allows + * the user to obtain a gamma-corrected palette, for example. + * If the user doesn't call this, we will do it ourselves. + */ +void PNGAPI +png_start_read_image(png_structp png_ptr) +{ + png_debug(1, "in png_start_read_image"); + + if (png_ptr != NULL) + png_read_start_row(png_ptr); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void PNGAPI +png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) +{ + int ret; + + png_row_info row_info; + + if (png_ptr == NULL) + return; + + png_debug2(1, "in png_read_row (row %lu, pass %d)", + (unsigned long)png_ptr->row_number, png_ptr->pass); + + /* png_read_start_row sets the information (in particular iwidth) for this + * interlace pass. + */ + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + + /* 1.5.6: row_info moved out of png_struct to a local here. */ + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Check for transforms that have been set but were defined out */ +#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + !defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); +#endif + } + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* If interlaced and we do not need a new row, combine row and return. + * Notice that the pixels we have from previous rows have been transformed + * already; we can only combine like with like (transformed or + * untransformed) and, because of the libpng API for interlaced images, this + * means we must transform before de-interlacing. + */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + png_read_finish_row(png_ptr); + return; + } + break; + + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + if (dsp_row != NULL && (png_ptr->row_number & 4)) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 3: + if ((png_ptr->row_number & 3) || png_ptr->width < 3) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 4: + if ((png_ptr->row_number & 3) != 2) + { + if (dsp_row != NULL && (png_ptr->row_number & 2)) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + case 5: + if ((png_ptr->row_number & 1) || png_ptr->width < 2) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + default: + case 6: + if (!(png_ptr->row_number & 1)) + { + png_read_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "Invalid attempt to read row data"); + + png_ptr->zstream.next_out = png_ptr->row_buf; + png_ptr->zstream.avail_out = + (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1); + + do + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_crc_finish(png_ptr, 0); + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, + (png_size_t)png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_benign_error(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression error"); + + } while (png_ptr->zstream.avail_out); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); + } +#endif + + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "sequential row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal sequential row size calculation error"); + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Blow up interlaced rows to full size */ + if (png_ptr->interlaced && + (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + if (row != NULL) + png_combine_row(png_ptr, row, 0/*row*/); + } + + else +#endif + { + if (row != NULL) + png_combine_row(png_ptr, row, -1/*ignored*/); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, -1/*ignored*/); + } + png_read_finish_row(png_ptr); + + if (png_ptr->read_row_fn != NULL) + (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. If the image is interlaced, + * and png_set_interlace_handling() has been called, the rows need to + * contain the contents of the rows from the previous pass. If the + * image has alpha or transparency, and png_handle_alpha()[*] has been + * called, the rows contents must be initialized to the contents of the + * screen. + * + * "row" holds the actual image, and pixels are placed in it + * as they arrive. If the image is displayed after each pass, it will + * appear to "sparkle" in. "display_row" can be used to display a + * "chunky" progressive image, with finer detail added as it becomes + * available. If you do not want this "chunky" display, you may pass + * NULL for display_row. If you do not want the sparkle display, and + * you have not called png_handle_alpha(), you may pass NULL for rows. + * If you have called png_handle_alpha(), and the image has either an + * alpha channel or a transparency chunk, you must provide a buffer for + * rows. In this case, you do not have to provide a display_row buffer + * also, but you may. If the image is not interlaced, or if you have + * not called png_set_interlace_handling(), the display_row buffer will + * be ignored, so pass NULL to it. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ + +void PNGAPI +png_read_rows(png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) +{ + png_uint_32 i; + png_bytepp rp; + png_bytepp dp; + + png_debug(1, "in png_read_rows"); + + if (png_ptr == NULL) + return; + + rp = row; + dp = display_row; + if (rp != NULL && dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp++; + png_bytep dptr = *dp++; + + png_read_row(png_ptr, rptr, dptr); + } + + else if (rp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp; + png_read_row(png_ptr, rptr, NULL); + rp++; + } + + else if (dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep dptr = *dp; + png_read_row(png_ptr, NULL, dptr); + dp++; + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the entire image. If the image has an alpha channel or a tRNS + * chunk, and you have called png_handle_alpha()[*], you will need to + * initialize the image to the current image that PNG will be overlaying. + * We set the num_rows again here, in case it was incorrectly set in + * png_read_start_row() by a call to png_read_update_info() or + * png_start_read_image() if png_set_interlace_handling() wasn't called + * prior to either of these functions like it should have been. You can + * only call this function once. If you desire to have an image for + * each pass of a interlaced image, use png_read_rows() instead. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ +void PNGAPI +png_read_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i, image_height; + int pass, j; + png_bytepp rp; + + png_debug(1, "in png_read_image"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ + png_start_read_image(png_ptr); + } + else + { + if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; + } + + /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in + * the above error case. + */ + pass = png_set_interlace_handling(png_ptr); + } +#else + if (png_ptr->interlaced) + png_error(png_ptr, + "Cannot read interlaced image -- interlace handler disabled"); + + pass = 1; +#endif + + image_height=png_ptr->height; + + for (j = 0; j < pass; j++) + { + rp = image; + for (i = 0; i < image_height; i++) + { + png_read_row(png_ptr, *rp, NULL); + rp++; + } + } +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. Will not read past the end of the + * file, will verify the end is accurate, and will read any comments + * or time information at the end of the file, if info is not NULL. + */ +void PNGAPI +png_read_end(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_end"); + + if (png_ptr == NULL) + return; + + png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ + + do + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + + else if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) + { + if (chunk_name == png_IDAT) + { + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_benign_error(png_ptr, "Too many IDATs found"); + } + png_handle_unknown(png_ptr, info_ptr, length); + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + + else if (chunk_name == png_IDAT) + { + /* Zero length IDATs are legal after the last IDAT has been + * read, but not after other chunks have been read. + */ + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_benign_error(png_ptr, "Too many IDATs found"); + + png_crc_finish(png_ptr, length); + } + else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + +#ifdef PNG_READ_bKGD_SUPPORTED + else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED + else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_gAMA_SUPPORTED + else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED + else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED + else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED + else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED + else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED + else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iCCP_SUPPORTED + else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_sPLT_SUPPORTED + else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED + else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tIME_SUPPORTED + else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_tRNS_SUPPORTED + else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED + else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED + else if (chunk_name == png_iTXt) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + + else + png_handle_unknown(png_ptr, info_ptr, length); + } while (!(png_ptr->mode & PNG_HAVE_IEND)); +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +/* Free all memory used by the read */ +void PNGAPI +png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, + png_infopp end_info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL, end_info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn = NULL; + png_voidp mem_ptr = NULL; +#endif + + png_debug(1, "in png_destroy_read_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + if (png_ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (end_info_ptr_ptr != NULL) + end_info_ptr = *end_info_ptr_ptr; + + png_read_destroy(png_ptr, info_ptr, end_info_ptr); + + if (info_ptr != NULL) + { +#ifdef PNG_TEXT_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (end_info_ptr != NULL) + { +#ifdef PNG_READ_TEXT_SUPPORTED + png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); +#endif +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)end_info_ptr); +#endif + *end_info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + +/* Free all memory used by the read (old method) */ +void /* PRIVATE */ +png_read_destroy(png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; +#endif + png_error_ptr error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; +#endif + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_read_destroy"); + + if (info_ptr != NULL) + png_info_destroy(png_ptr, info_ptr); + + if (end_info_ptr != NULL) + png_info_destroy(png_ptr, end_info_ptr); + +#ifdef PNG_READ_GAMMA_SUPPORTED + png_destroy_gamma_table(png_ptr); +#endif + + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + png_free(png_ptr, png_ptr->chunkdata); + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_free(png_ptr, png_ptr->palette_lookup); + png_free(png_ptr, png_ptr->quantize_index); +#endif + + if (png_ptr->free_me & PNG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->free_me &= ~PNG_FREE_PLTE; + +#if defined(PNG_tRNS_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->free_me & PNG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->free_me &= ~PNG_FREE_TRNS; +#endif + +#ifdef PNG_READ_hIST_SUPPORTED + if (png_ptr->free_me & PNG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->free_me &= ~PNG_FREE_HIST; +#endif + + inflateEnd(&png_ptr->zstream); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +#ifdef PNG_TEXT_SUPPORTED + png_free(png_ptr, png_ptr->current_text); +#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + + /* Save the important info out of the png_struct, in case it is + * being used again. + */ +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + warning_fn = png_ptr->warning_fn; +#endif + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof(png_struct)); + + png_ptr->error_fn = error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#endif + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); +#endif + +} + +void PNGAPI +png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->read_row_fn = read_row_fn; +} + + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_read_png(png_structp png_ptr, png_infop info_ptr, + int transforms, + voidp params) +{ + int row; + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); + if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) + png_error(png_ptr, "Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + /* Tell libpng to strip 16-bit/color files down to 8 bits per color. + */ + if (transforms & PNG_TRANSFORM_SCALE_16) + { + /* Added at libpng-1.5.4. "strip_16" produces the same result that it + * did in earlier versions, while "scale_16" is now more accurate. + */ + png_set_scale_16(png_ptr); + } +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* If both SCALE and STRIP are required pngrtran will effectively cancel the + * latter by doing SCALE first. This is ok and allows apps not to check for + * which is supported to get the right answer. + */ + if (transforms & PNG_TRANSFORM_STRIP_16) + png_set_strip_16(png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ + if (transforms & PNG_TRANSFORM_STRIP_ALPHA) + png_set_strip_alpha(png_ptr); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) + /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED + /* Expand paletted colors into true RGB triplets + * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel + * Expand paletted or RGB images with transparency to full alpha + * channels so the data will be available as RGBA quartets. + */ + if (transforms & PNG_TRANSFORM_EXPAND) + if ((png_ptr->bit_depth < 8) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) + png_set_expand(png_ptr); +#endif + + /* We don't handle background color or gamma transformation or quantizing. + */ + +#ifdef PNG_READ_INVERT_SUPPORTED + /* Invert monochrome files to have 0 as white and 1 as black + */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) + { + png_color_8p sig_bit; + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, sig_bit); + } +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#ifdef PNG_READ_SWAP_SUPPORTED + /* Swap bytes of 16-bit files to least significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + +/* Added at libpng-1.2.41 */ +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + /* Invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + +/* Added at libpng-1.2.41 */ +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* Expand grayscale image to RGB */ + if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) + png_set_gray_to_rgb(png_ptr); +#endif + +/* Added at libpng-1.5.4 */ +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (transforms & PNG_TRANSFORM_EXPAND_16) + png_set_expand_16(png_ptr); +#endif + + /* We don't handle adding filler bytes */ + + /* We use png_read_image and rely on that for interlace handling, but we also + * call png_read_update_info therefore must turn on interlace handling now: + */ + (void)png_set_interlace_handling(png_ptr); + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (i.e., you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* -------------- image transformations end here ------------------- */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + if (info_ptr->row_pointers == NULL) + { + png_uint_32 iptr; + + info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, + info_ptr->height * png_sizeof(png_bytep)); + for (iptr=0; iptrheight; iptr++) + info_ptr->row_pointers[iptr] = NULL; + + info_ptr->free_me |= PNG_FREE_ROWS; + + for (row = 0; row < (int)info_ptr->height; row++) + info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr)); + } + + png_read_image(png_ptr, info_ptr->row_pointers); + info_ptr->valid |= PNG_INFO_IDAT; + + /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) + +} +#endif /* PNG_INFO_IMAGE_SUPPORTED */ +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrio.c b/WDL/libpng/pngrio.c new file mode 100644 index 00000000..d0d9d8a7 --- /dev/null +++ b/WDL/libpng/pngrio.c @@ -0,0 +1,176 @@ + +/* pngrio.c - functions for data input + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all input. Users who need + * special handling are expected to write a function that has the same + * arguments as this and performs a similar function, but that possibly + * has a different input method. Note that you shouldn't change this + * function, but rather write a replacement function and then make + * libpng use it at run time with png_set_read_fn(...). + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* Read the data from whatever input you are using. The default routine + * reads from a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered reads. This should never be asked + * to read more then 64K on a 16 bit machine. + */ +void /* PRIVATE */ +png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_debug1(4, "reading %d bytes", (int)length); + + if (png_ptr->read_data_fn != NULL) + (*(png_ptr->read_data_fn))(png_ptr, data, length); + + else + png_error(png_ptr, "Call to NULL read function"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* This is the function that does the actual reading of data. If you are + * not reading from a standard C stream, you should create a replacement + * read_data function and use it at run time with png_set_read_fn(), rather + * than changing the library. + */ +# ifndef USE_FAR_KEYWORD +void PNGCBAPI +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + if (png_ptr == NULL) + return; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr); + + if (check != length) + png_error(png_ptr, "Read Error"); +} +# else +/* This is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void PNGCBAPI +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + png_byte *n_data; + png_FILE_p io_ptr; + + if (png_ptr == NULL) + return; + + /* Check if data really is near. If so, use usual code. */ + n_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + + if ((png_bytep)n_data == data) + { + check = fread(n_data, 1, length, io_ptr); + } + + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + + do + { + read = MIN(NEAR_BUF_SIZE, remaining); + err = fread(buf, 1, read, io_ptr); + png_memcpy(data, buf, read); /* copy far buffer to near buffer */ + + if (err != read) + break; + + else + check += err; + + data += read; + remaining -= read; + } + while (remaining != 0); + } + + if ((png_uint_32)check != (png_uint_32)length) + png_error(png_ptr, "read Error"); +} +# endif +#endif + +/* This function allows the application to supply a new input function + * for libpng if standard C streams aren't being used. + * + * This function takes as its arguments: + * + * png_ptr - pointer to a png input data structure + * + * io_ptr - pointer to user supplied structure containing info about + * the input functions. May be NULL. + * + * read_data_fn - pointer to a new input function that takes as its + * arguments a pointer to a png_struct, a pointer to + * a location where input data can be stored, and a 32-bit + * unsigned int that is the number of bytes to be read. + * To exit and output any fatal error messages the new write + * function should call png_error(png_ptr, "Error msg"). + * May be NULL, in which case libpng's default function will + * be used. + */ +void PNGAPI +png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + +#ifdef PNG_STDIO_SUPPORTED + if (read_data_fn != NULL) + png_ptr->read_data_fn = read_data_fn; + + else + png_ptr->read_data_fn = png_default_read_data; +#else + png_ptr->read_data_fn = read_data_fn; +#endif + + /* It is an error to write to a read device */ + if (png_ptr->write_data_fn != NULL) + { + png_ptr->write_data_fn = NULL; + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; +#endif +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrtran.c b/WDL/libpng/pngrtran.c new file mode 100644 index 00000000..26083a0d --- /dev/null +++ b/WDL/libpng/pngrtran.c @@ -0,0 +1,5023 @@ + +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains functions optionally called by an application + * in order to tell libpng how to handle data when reading a PNG. + * Transformations that are used in both reading and writing are + * in pngtrans.c. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* Set the action on getting a CRC error for an ancillary or critical chunk. */ +void PNGAPI +png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) +{ + png_debug(1, "in png_set_crc_action"); + + if (png_ptr == NULL) + return; + + /* Tell libpng how we react to CRC errors in critical chunks */ + switch (crit_action) + { + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ + break; + + case PNG_CRC_WARN_USE: /* Warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; + break; + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | + PNG_FLAG_CRC_CRITICAL_IGNORE; + break; + + case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ + png_warning(png_ptr, + "Can't discard critical data on CRC error"); + case PNG_CRC_ERROR_QUIT: /* Error/quit */ + + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + break; + } + + /* Tell libpng how we react to CRC errors in ancillary chunks */ + switch (ancil_action) + { + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ + break; + + case PNG_CRC_WARN_USE: /* Warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; + break; + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | + PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + + case PNG_CRC_ERROR_QUIT: /* Error/quit */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + + case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ + + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + break; + } +} + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS via a background color */ +void PNGFAPI +png_set_background_fixed(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma) +{ + png_debug(1, "in png_set_background_fixed"); + + if (png_ptr == NULL) + return; + + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + { + png_warning(png_ptr, "Application must supply a known background gamma"); + return; + } + + png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + png_memcpy(&(png_ptr->background), background_color, + png_sizeof(png_color_16)); + png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + if (need_expand) + png_ptr->transformations |= PNG_BACKGROUND_EXPAND; + else + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_set_background_fixed(png_ptr, background_color, background_gamma_code, + need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); +} +# endif /* FLOATING_POINT */ +#endif /* READ_BACKGROUND */ + +/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the + * one that pngrtran does first (scale) happens. This is necessary to allow the + * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +void PNGAPI +png_set_scale_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_scale_16"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_SCALE_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +/* Chop 16-bit depth files to 8-bit depth */ +void PNGAPI +png_set_strip_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_16"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +void PNGAPI +png_set_strip_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_STRIP_ALPHA; +} +#endif + +#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) +static png_fixed_point +translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, + int is_screen) +{ + /* Check for flag values. The main reason for having the old Mac value as a + * flag is that it is pretty near impossible to work out what the correct + * value is from Apple documentation - a working Mac system is needed to + * discover the value! + */ + if (output_gamma == PNG_DEFAULT_sRGB || + output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) + { + /* If there is no sRGB support this just sets the gamma to the standard + * sRGB value. (This is a side effect of using this function!) + */ +# ifdef PNG_READ_sRGB_SUPPORTED + png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; +# endif + if (is_screen) + output_gamma = PNG_GAMMA_sRGB; + else + output_gamma = PNG_GAMMA_sRGB_INVERSE; + } + + else if (output_gamma == PNG_GAMMA_MAC_18 || + output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) + { + if (is_screen) + output_gamma = PNG_GAMMA_MAC_OLD; + else + output_gamma = PNG_GAMMA_MAC_INVERSE; + } + + return output_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +static png_fixed_point +convert_gamma_value(png_structp png_ptr, double output_gamma) +{ + /* The following silently ignores cases where fixed point (times 100,000) + * gamma values are passed to the floating point API. This is safe and it + * means the fixed point constants work just fine with the floating point + * API. The alternative would just lead to undetected errors and spurious + * bug reports. Negative values fail inside the _fixed API unless they + * correspond to the flag values. + */ + if (output_gamma > 0 && output_gamma < 128) + output_gamma *= PNG_FP_1; + + /* This preserves -1 and -2 exactly: */ + output_gamma = floor(output_gamma + .5); + + if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) + png_fixed_error(png_ptr, "gamma value"); + + return (png_fixed_point)output_gamma; +} +# endif +#endif /* READ_ALPHA_MODE || READ_GAMMA */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +void PNGFAPI +png_set_alpha_mode_fixed(png_structp png_ptr, int mode, + png_fixed_point output_gamma) +{ + int compose = 0; + png_fixed_point file_gamma; + + png_debug(1, "in png_set_alpha_mode"); + + if (png_ptr == NULL) + return; + + output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); + + /* Validate the value to ensure it is in a reasonable range. The value + * is expected to be 1 or greater, but this range test allows for some + * viewing correction values. The intent is to weed out users of this API + * who use the inverse of the gamma value accidentally! Since some of these + * values are reasonable this may have to be changed. + */ + if (output_gamma < 70000 || output_gamma > 300000) + png_error(png_ptr, "output gamma out of expected range"); + + /* The default file gamma is the inverse of the output gamma; the output + * gamma may be changed below so get the file value first: + */ + file_gamma = png_reciprocal(output_gamma); + + /* There are really 8 possibilities here, composed of any combination + * of: + * + * premultiply the color channels + * do not encode non-opaque pixels + * encode the alpha as well as the color channels + * + * The differences disappear if the input/output ('screen') gamma is 1.0, + * because then the encoding is a no-op and there is only the choice of + * premultiplying the color channels or not. + * + * png_set_alpha_mode and png_set_background interact because both use + * png_compose to do the work. Calling both is only useful when + * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along + * with a default gamma value. Otherwise PNG_COMPOSE must not be set. + */ + switch (mode) + { + case PNG_ALPHA_PNG: /* default: png standard */ + /* No compose, but it may be set by png_set_background! */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + /* The output is linear: */ + output_gamma = PNG_FP_1; + break; + + case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; + /* output_gamma records the encoding of opaque pixels! */ + break; + + case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ + compose = 1; + png_ptr->transformations |= PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + default: + png_error(png_ptr, "invalid alpha mode"); + } + + /* Only set the default gamma if the file gamma has not been set (this has + * the side effect that the gamma in a second call to png_set_alpha_mode will + * be ignored.) + */ + if (png_ptr->gamma == 0) + png_ptr->gamma = file_gamma; + + /* But always set the output gamma: */ + png_ptr->screen_gamma = output_gamma; + + /* Finally, if pre-multiplying, set the background fields to achieve the + * desired result. + */ + if (compose) + { + /* And obtain alpha pre-multiplication by composing on black: */ + png_memset(&png_ptr->background, 0, sizeof png_ptr->background); + png_ptr->background_gamma = png_ptr->gamma; /* just in case */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + + if (png_ptr->transformations & PNG_COMPOSE) + png_error(png_ptr, + "conflicting calls to set alpha mode and background"); + + png_ptr->transformations |= PNG_COMPOSE; + } + + /* New API, make sure apps call the correct initializers: */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) +{ + png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, + output_gamma)); +} +# endif +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Dither file to 8-bit. Supply a palette, the current number + * of elements in the palette, the maximum number of elements + * allowed, and a histogram if possible. If the current number + * of colors is greater then the maximum number, the palette will be + * modified to fit in the maximum number. "full_quantize" indicates + * whether we need a quantizing cube set up for RGB images, or if we + * simply are reducing the number of colors in a paletted image. + */ + +typedef struct png_dsort_struct +{ + struct png_dsort_struct FAR * next; + png_byte left; + png_byte right; +} png_dsort; +typedef png_dsort FAR * png_dsortp; +typedef png_dsort FAR * FAR * png_dsortpp; + +void PNGAPI +png_set_quantize(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize) +{ + png_debug(1, "in png_set_quantize"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_QUANTIZE; + + if (!full_quantize) + { + int i; + + png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof(png_byte))); + for (i = 0; i < num_palette; i++) + png_ptr->quantize_index[i] = (png_byte)i; + } + + if (num_palette > maximum_colors) + { + if (histogram != NULL) + { + /* This is easy enough, just throw out the least used colors. + * Perhaps not the best solution, but good enough. + */ + + int i; + + /* Initialize an array to sort colors */ + png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof(png_byte))); + + /* Initialize the quantize_sort array */ + for (i = 0; i < num_palette; i++) + png_ptr->quantize_sort[i] = (png_byte)i; + + /* Find the least used palette entries by starting a + * bubble sort, and running it until we have sorted + * out enough colors. Note that we don't care about + * sorting all the colors, just finding which are + * least used. + */ + + for (i = num_palette - 1; i >= maximum_colors; i--) + { + int done; /* To stop early if the list is pre-sorted */ + int j; + + done = 1; + for (j = 0; j < i; j++) + { + if (histogram[png_ptr->quantize_sort[j]] + < histogram[png_ptr->quantize_sort[j + 1]]) + { + png_byte t; + + t = png_ptr->quantize_sort[j]; + png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; + png_ptr->quantize_sort[j + 1] = t; + done = 0; + } + } + + if (done) + break; + } + + /* Swap the palette around, and set up a table, if necessary */ + if (full_quantize) + { + int j = num_palette; + + /* Put all the useful colors within the max, but don't + * move the others. + */ + for (i = 0; i < maximum_colors; i++) + { + if ((int)png_ptr->quantize_sort[i] >= maximum_colors) + { + do + j--; + while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + + palette[i] = palette[j]; + } + } + } + else + { + int j = num_palette; + + /* Move all the used colors inside the max limit, and + * develop a translation table. + */ + for (i = 0; i < maximum_colors; i++) + { + /* Only move the colors we need to */ + if ((int)png_ptr->quantize_sort[i] >= maximum_colors) + { + png_color tmp_color; + + do + j--; + while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + + tmp_color = palette[j]; + palette[j] = palette[i]; + palette[i] = tmp_color; + /* Indicate where the color went */ + png_ptr->quantize_index[j] = (png_byte)i; + png_ptr->quantize_index[i] = (png_byte)j; + } + } + + /* Find closest color for those colors we are not using */ + for (i = 0; i < num_palette; i++) + { + if ((int)png_ptr->quantize_index[i] >= maximum_colors) + { + int min_d, k, min_k, d_index; + + /* Find the closest color to one we threw out */ + d_index = png_ptr->quantize_index[i]; + min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); + for (k = 1, min_k = 0; k < maximum_colors; k++) + { + int d; + + d = PNG_COLOR_DIST(palette[d_index], palette[k]); + + if (d < min_d) + { + min_d = d; + min_k = k; + } + } + /* Point to closest color */ + png_ptr->quantize_index[i] = (png_byte)min_k; + } + } + } + png_free(png_ptr, png_ptr->quantize_sort); + png_ptr->quantize_sort = NULL; + } + else + { + /* This is much harder to do simply (and quickly). Perhaps + * we need to go through a median cut routine, but those + * don't always behave themselves with only a few colors + * as input. So we will just find the closest two colors, + * and throw out one of them (chosen somewhat randomly). + * [We don't understand this at all, so if someone wants to + * work on improving it, be our guest - AED, GRP] + */ + int i; + int max_d; + int num_new_palette; + png_dsortp t; + png_dsortpp hash; + + t = NULL; + + /* Initialize palette index arrays */ + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof(png_byte))); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof(png_byte))); + + /* Initialize the sort array */ + for (i = 0; i < num_palette; i++) + { + png_ptr->index_to_palette[i] = (png_byte)i; + png_ptr->palette_to_index[i] = (png_byte)i; + } + + hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * + png_sizeof(png_dsortp))); + + num_new_palette = num_palette; + + /* Initial wild guess at how far apart the farthest pixel + * pair we will be eliminating will be. Larger + * numbers mean more areas will be allocated, Smaller + * numbers run the risk of not saving enough data, and + * having to do this all over again. + * + * I have not done extensive checking on this number. + */ + max_d = 96; + + while (num_new_palette > maximum_colors) + { + for (i = 0; i < num_new_palette - 1; i++) + { + int j; + + for (j = i + 1; j < num_new_palette; j++) + { + int d; + + d = PNG_COLOR_DIST(palette[i], palette[j]); + + if (d <= max_d) + { + + t = (png_dsortp)png_malloc_warn(png_ptr, + (png_uint_32)(png_sizeof(png_dsort))); + + if (t == NULL) + break; + + t->next = hash[d]; + t->left = (png_byte)i; + t->right = (png_byte)j; + hash[d] = t; + } + } + if (t == NULL) + break; + } + + if (t != NULL) + for (i = 0; i <= max_d; i++) + { + if (hash[i] != NULL) + { + png_dsortp p; + + for (p = hash[i]; p; p = p->next) + { + if ((int)png_ptr->index_to_palette[p->left] + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) + { + int j, next_j; + + if (num_new_palette & 0x01) + { + j = p->left; + next_j = p->right; + } + else + { + j = p->right; + next_j = p->left; + } + + num_new_palette--; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; + if (!full_quantize) + { + int k; + + for (k = 0; k < num_palette; k++) + { + if (png_ptr->quantize_index[k] == + png_ptr->index_to_palette[j]) + png_ptr->quantize_index[k] = + png_ptr->index_to_palette[next_j]; + + if ((int)png_ptr->quantize_index[k] == + num_new_palette) + png_ptr->quantize_index[k] = + png_ptr->index_to_palette[j]; + } + } + + png_ptr->index_to_palette[png_ptr->palette_to_index + [num_new_palette]] = png_ptr->index_to_palette[j]; + + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] + = png_ptr->palette_to_index[num_new_palette]; + + png_ptr->index_to_palette[j] = + (png_byte)num_new_palette; + + png_ptr->palette_to_index[num_new_palette] = + (png_byte)j; + } + if (num_new_palette <= maximum_colors) + break; + } + if (num_new_palette <= maximum_colors) + break; + } + } + + for (i = 0; i < 769; i++) + { + if (hash[i] != NULL) + { + png_dsortp p = hash[i]; + while (p) + { + t = p->next; + png_free(png_ptr, p); + p = t; + } + } + hash[i] = 0; + } + max_d += 96; + } + png_free(png_ptr, hash); + png_free(png_ptr, png_ptr->palette_to_index); + png_free(png_ptr, png_ptr->index_to_palette); + png_ptr->palette_to_index = NULL; + png_ptr->index_to_palette = NULL; + } + num_palette = maximum_colors; + } + if (png_ptr->palette == NULL) + { + png_ptr->palette = palette; + } + png_ptr->num_palette = (png_uint_16)num_palette; + + if (full_quantize) + { + int i; + png_bytep distance; + int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + + PNG_QUANTIZE_BLUE_BITS; + int num_red = (1 << PNG_QUANTIZE_RED_BITS); + int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); + int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); + png_size_t num_entries = ((png_size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, + (png_uint_32)(num_entries * png_sizeof(png_byte))); + + distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + png_sizeof(png_byte))); + + png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); + + for (i = 0; i < num_palette; i++) + { + int ir, ig, ib; + int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); + int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); + int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); + + for (ir = 0; ir < num_red; ir++) + { + /* int dr = abs(ir - r); */ + int dr = ((ir > r) ? ir - r : r - ir); + int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + + PNG_QUANTIZE_GREEN_BITS)); + + for (ig = 0; ig < num_green; ig++) + { + /* int dg = abs(ig - g); */ + int dg = ((ig > g) ? ig - g : g - ig); + int dt = dr + dg; + int dm = ((dr > dg) ? dr : dg); + int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); + + for (ib = 0; ib < num_blue; ib++) + { + int d_index = index_g | ib; + /* int db = abs(ib - b); */ + int db = ((ib > b) ? ib - b : b - ib); + int dmax = ((dm > db) ? dm : db); + int d = dmax + dt + db; + + if (d < (int)distance[d_index]) + { + distance[d_index] = (png_byte)d; + png_ptr->palette_lookup[d_index] = (png_byte)i; + } + } + } + } + } + + png_free(png_ptr, distance); + } +} +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +void PNGFAPI +png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); + + if (png_ptr == NULL) + return; + + /* New in libpng-1.5.4 - reserve particular negative values as flags. */ + scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); + file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); + +#if PNG_LIBPNG_VER >= 10600 + /* Checking the gamma values for being >0 was added in 1.5.4 along with the + * premultiplied alpha support; this actually hides an undocumented feature + * of the previous implementation which allowed gamma processing to be + * disabled in background handling. There is no evidence (so far) that this + * was being used; however, png_set_background itself accepted and must still + * accept '0' for the gamma value it takes, because it isn't always used. + * + * Since this is an API change (albeit a very minor one that removes an + * undocumented API feature) it will not be made until libpng-1.6.0. + */ + if (file_gamma <= 0) + png_error(png_ptr, "invalid file gamma in png_set_gamma"); + + if (scrn_gamma <= 0) + png_error(png_ptr, "invalid screen gamma in png_set_gamma"); +#endif + + /* Set the gamma values unconditionally - this overrides the value in the PNG + * file if a gAMA chunk was present. png_set_alpha_mode provides a + * different, easier, way to default the file gamma. + */ + png_ptr->gamma = file_gamma; + png_ptr->screen_gamma = scrn_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), + convert_gamma_value(png_ptr, file_gamma)); +} +# endif /* FLOATING_POINT_SUPPORTED */ +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand paletted images to RGB, expand grayscale images of + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks + * to alpha channels. + */ +void PNGAPI +png_set_expand(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + +/* GRR 19990627: the following three functions currently are identical + * to png_set_expand(). However, it is entirely reasonable that someone + * might wish to expand an indexed image to RGB but *not* expand a single, + * fully transparent palette entry to a full alpha channel--perhaps instead + * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace + * the transparent color with a particular RGB value, or drop tRNS entirely. + * IOW, a future version of the library may make the transformations flag + * a bit more fine-grained, with separate bits for each of these three + * functions. + * + * More to the point, these functions make it obvious what libpng will be + * doing, whereas "expand" can (and does) mean any number of things. + * + * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha + * and its name was changed to png_set_expand_gray_1_2_4_to_8(). + */ + +/* Expand paletted images to RGB. */ +void PNGAPI +png_set_palette_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_palette_to_rgb"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_EXPAND; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} + + + +/* Expand tRNS chunks to alpha channels. */ +void PNGAPI +png_set_tRNS_to_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_tRNS_to_alpha"); + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} +#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise + * it may not work correctly.) + */ +void PNGAPI +png_set_expand_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_16"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + + /* New API, make sure apps call the correct initializers: */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; +} +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +void PNGAPI +png_set_gray_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_gray_to_rgb"); + + if (png_ptr != NULL) + { + /* Because rgb must be 8 bits or more: */ + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_ptr->transformations |= PNG_GRAY_TO_RGB; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +void PNGFAPI +png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) +{ + png_debug(1, "in png_set_rgb_to_gray"); + + if (png_ptr == NULL) + return; + + switch(error_action) + { + case PNG_ERROR_ACTION_NONE: + png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + + case PNG_ERROR_ACTION_WARN: + png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + + case PNG_ERROR_ACTION_ERROR: + png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + break; + + default: + png_error(png_ptr, "invalid error action to rgb_to_gray"); + break; + } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#ifdef PNG_READ_EXPAND_SUPPORTED + png_ptr->transformations |= PNG_EXPAND; +#else + { + png_warning(png_ptr, + "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); + + png_ptr->transformations &= ~PNG_RGB_TO_GRAY; + } +#endif + { + if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) + { + png_uint_16 red_int, green_int; + + /* NOTE: this calculation does not round, but this behavior is retained + * for consistency, the inaccuracy is very small. The code here always + * overwrites the coefficients, regardless of whether they have been + * defaulted or set already. + */ + red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); + green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); + + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; + png_ptr->rgb_to_gray_coefficients_set = 1; + } + + else + { + if (red >= 0 && green >= 0) + png_warning(png_ptr, + "ignoring out of range rgb_to_gray coefficients"); + + /* Use the defaults, from the cHRM chunk if set, else the historical + * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See + * png_do_rgb_to_gray for more discussion of the values. In this case + * the coefficients are not marked as 'set' and are not overwritten if + * something has already provided a default. + */ + if (png_ptr->rgb_to_gray_red_coeff == 0 && + png_ptr->rgb_to_gray_green_coeff == 0) + { + png_ptr->rgb_to_gray_red_coeff = 6968; + png_ptr->rgb_to_gray_green_coeff = 23434; + /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ + } + } + } +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* Convert a RGB image to a grayscale of the same width. This allows us, + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. + */ + +void PNGAPI +png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, + double green) +{ + if (png_ptr == NULL) + return; + + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); +} +#endif /* FLOATING POINT */ + +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +void PNGAPI +png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + read_user_transform_fn) +{ + png_debug(1, "in png_set_read_user_transform_fn"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +#endif +} +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +#ifdef PNG_READ_GAMMA_SUPPORTED +/* In the case of gamma transformations only do transformations on images where + * the [file] gamma and screen_gamma are not close reciprocals, otherwise it + * slows things down slightly, and also needlessly introduces small errors. + */ +static int /* PRIVATE */ +png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) +{ + /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma + * correction as a difference of the overall transform from 1.0 + * + * We want to compare the threshold with s*f - 1, if we get + * overflow here it is because of wacky gamma values so we + * turn on processing anyway. + */ + png_fixed_point gtest; + return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || + png_gamma_significant(gtest); +} +#endif + +/* Initialize everything needed for the read. This includes modifying + * the palette. + */ + +/*For the moment 'png_init_palette_transformations' and + * 'png_init_rgb_transformations' only do some flag canceling optimizations. + * The intent is that these two routines should have palette or rgb operations + * extracted from 'png_init_read_transformations'. + */ +static void /* PRIVATE */ +png_init_palette_transformations(png_structp png_ptr) +{ + /* Called to handle the (input) palette case. In png_do_read_transformations + * the first step is to expand the palette if requested, so this code must + * take care to only make changes that are invariant with respect to the + * palette expansion, or only do them if there is no expansion. + * + * STRIP_ALPHA has already been handled in the caller (by setting num_trans + * to 0.) + */ + int input_has_alpha = 0; + int input_has_transparency = 0; + + if (png_ptr->num_trans > 0) + { + int i; + + /* Ignore if all the entries are opaque (unlikely!) */ + for (i=0; inum_trans; ++i) + if (png_ptr->trans_alpha[i] == 255) + continue; + else if (png_ptr->trans_alpha[i] == 0) + input_has_transparency = 1; + else + input_has_alpha = 1; + } + + /* If no alpha we can optimize. */ + if (!input_has_alpha) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + if (!input_has_transparency) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND)) + { + { + png_ptr->background.red = + png_ptr->palette[png_ptr->background.index].red; + png_ptr->background.green = + png_ptr->palette[png_ptr->background.index].green; + png_ptr->background.blue = + png_ptr->palette[png_ptr->background.index].blue; + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + { + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later + */ + int i, istop = png_ptr->num_trans; + + for (i=0; itrans_alpha[i] = (png_byte)(255 - + png_ptr->trans_alpha[i]); + } + } +#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ + } + } /* background expand and (therefore) no alpha association. */ +#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +} + +static void /* PRIVATE */ +png_init_rgb_transformations(png_structp png_ptr) +{ + /* Added to libpng-1.5.4: check the color type to determine whether there + * is any alpha or transparency in the image and simply cancel the + * background and alpha mode stuff if there isn't. + */ + int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; + int input_has_transparency = png_ptr->num_trans > 0; + + /* If no alpha we can optimize. */ + if (!input_has_alpha) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ +# ifdef PNG_READ_ALPHA_MODE_SUPPORTED + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; +# endif + + if (!input_has_transparency) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND) && + !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + /* i.e., GRAY or GRAY_ALPHA */ + { + { + /* Expand background and tRNS chunks */ + int gray = png_ptr->background.gray; + int trans_gray = png_ptr->trans_color.gray; + + switch (png_ptr->bit_depth) + { + case 1: + gray *= 0xff; + trans_gray *= 0xff; + break; + + case 2: + gray *= 0x55; + trans_gray *= 0x55; + break; + + case 4: + gray *= 0x11; + trans_gray *= 0x11; + break; + + default: + + case 8: + /* Already 8 bits, fall through */ + + case 16: + /* Already a full 16 bits */ + break; + } + + png_ptr->background.red = png_ptr->background.green = + png_ptr->background.blue = (png_uint_16)gray; + + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_color.red = png_ptr->trans_color.green = + png_ptr->trans_color.blue = (png_uint_16)trans_gray; + } + } + } /* background expand and (therefore) no alpha association. */ +#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +} + +void /* PRIVATE */ +png_init_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_init_read_transformations"); + + /* This internal function is called from png_read_start_row in pngrutil.c + * and it is called before the 'rowbytes' calculation is done, so the code + * in here can change or update the transformations flags. + * + * First do updates that do not depend on the details of the PNG image data + * being processed. + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds + * png_set_alpha_mode and this is another source for a default file gamma so + * the test needs to be performed later - here. In addition prior to 1.5.4 + * the tests were repeated for the PALETTE color type here - this is no + * longer necessary (and doesn't seem to have been necessary before.) + */ + { + /* The following temporary indicates if overall gamma correction is + * required. + */ + int gamma_correction = 0; + + if (png_ptr->gamma != 0) /* has been set */ + { + if (png_ptr->screen_gamma != 0) /* screen set too */ + gamma_correction = png_gamma_threshold(png_ptr->gamma, + png_ptr->screen_gamma); + + else + /* Assume the output matches the input; a long time default behavior + * of libpng, although the standard has nothing to say about this. + */ + png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); + } + + else if (png_ptr->screen_gamma != 0) + /* The converse - assume the file matches the screen, note that this + * perhaps undesireable default can (from 1.5.4) be changed by calling + * png_set_alpha_mode (even if the alpha handling mode isn't required + * or isn't changed from the default.) + */ + png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); + + else /* neither are set */ + /* Just in case the following prevents any processing - file and screen + * are both assumed to be linear and there is no way to introduce a + * third gamma value other than png_set_background with 'UNIQUE', and, + * prior to 1.5.4 + */ + png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; + + /* Now turn the gamma transformation on or off as appropriate. Notice + * that PNG_GAMMA just refers to the file->screen correction. Alpha + * composition may independently cause gamma correction because it needs + * linear data (e.g. if the file has a gAMA chunk but the screen gamma + * hasn't been specified.) In any case this flag may get turned off in + * the code immediately below if the transform can be handled outside the + * row loop. + */ + if (gamma_correction) + png_ptr->transformations |= PNG_GAMMA; + + else + png_ptr->transformations &= ~PNG_GAMMA; + } +#endif + + /* Certain transformations have the effect of preventing other + * transformations that happen afterward in png_do_read_transformations, + * resolve the interdependencies here. From the code of + * png_do_read_transformations the order is: + * + * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) + * 2) PNG_STRIP_ALPHA (if no compose) + * 3) PNG_RGB_TO_GRAY + * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY + * 5) PNG_COMPOSE + * 6) PNG_GAMMA + * 7) PNG_STRIP_ALPHA (if compose) + * 8) PNG_ENCODE_ALPHA + * 9) PNG_SCALE_16_TO_8 + * 10) PNG_16_TO_8 + * 11) PNG_QUANTIZE (converts to palette) + * 12) PNG_EXPAND_16 + * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY + * 14) PNG_INVERT_MONO + * 15) PNG_SHIFT + * 16) PNG_PACK + * 17) PNG_BGR + * 18) PNG_PACKSWAP + * 19) PNG_FILLER (includes PNG_ADD_ALPHA) + * 20) PNG_INVERT_ALPHA + * 21) PNG_SWAP_ALPHA + * 22) PNG_SWAP_BYTES + * 23) PNG_USER_TRANSFORM [must be last] + */ +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + !(png_ptr->transformations & PNG_COMPOSE)) + { + /* Stripping the alpha channel happens immediately after the 'expand' + * transformations, before all other transformation, so it cancels out + * the alpha handling. It has the side effect negating the effect of + * PNG_EXPAND_tRNS too: + */ + png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | + PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen + * so transparency information would remain just so long as it wasn't + * expanded. This produces unexpected API changes if the set of things + * that do PNG_EXPAND_tRNS changes (perfectly possible given the + * documentation - which says ask for what you want, accept what you + * get.) This makes the behavior consistent from 1.5.4: + */ + png_ptr->num_trans = 0; + } +#endif /* STRIP_ALPHA supported, no COMPOSE */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA + * settings will have no effect. + */ + if (!png_gamma_significant(png_ptr->screen_gamma)) + { + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + } +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* Detect gray background and attempt to enable optimization for + * gray --> RGB case. + * + * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or + * RGB_ALPHA (in which case need_expand is superfluous anyway), the + * background color might actually be gray yet not be flagged as such. + * This is not a problem for the current code, which uses + * PNG_BACKGROUND_IS_GRAY only to decide when to do the + * png_do_gray_to_rgb() transformation. + * + * TODO: this code needs to be revised to avoid the complexity and + * interdependencies. The color type of the background should be recorded in + * png_set_background, along with the bit depth, then the code has a record + * of exactly what color space the background is currently in. + */ + if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) + { + /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if + * the file was grayscale the background value is gray. + */ + if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } + + else if (png_ptr->transformations & PNG_COMPOSE) + { + /* PNG_COMPOSE: png_set_background was called with need_expand false, + * so the color is in the color space of the output or png_set_alpha_mode + * was called and the color is black. Ignore RGB_TO_GRAY because that + * happens before GRAY_TO_RGB. + */ + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if (png_ptr->background.red == png_ptr->background.green && + png_ptr->background.red == png_ptr->background.blue) + { + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; + } + } + } +#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ + + /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations + * can be performed directly on the palette, and some (such as rgb to gray) + * can be optimized inside the palette. This is particularly true of the + * composite (background and alpha) stuff, which can be pretty much all done + * in the palette even if the result is expanded to RGB or gray afterward. + * + * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and + * earlier and the palette stuff is actually handled on the first row. This + * leads to the reported bug that the palette returned by png_get_PLTE is not + * updated. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_init_palette_transformations(png_ptr); + + else + png_init_rgb_transformations(png_ptr); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_EXPAND_16_SUPPORTED) + if ((png_ptr->transformations & PNG_EXPAND_16) && + (png_ptr->transformations & PNG_COMPOSE) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + png_ptr->bit_depth != 16) + { + /* TODO: fix this. Because the expand_16 operation is after the compose + * handling the background color must be 8, not 16, bits deep, but the + * application will supply a 16-bit value so reduce it here. + * + * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at + * present, so that case is ok (until do_expand_16 is moved.) + * + * NOTE: this discards the low 16 bits of the user supplied background + * color, but until expand_16 works properly there is no choice! + */ +# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) + CHOP(png_ptr->background.red); + CHOP(png_ptr->background.green); + CHOP(png_ptr->background.blue); + CHOP(png_ptr->background.gray); +# undef CHOP + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ + defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) + if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && + (png_ptr->transformations & PNG_COMPOSE) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + png_ptr->bit_depth == 16) + { + /* On the other hand, if a 16-bit file is to be reduced to 8-bits per + * component this will also happen after PNG_COMPOSE and so the background + * color must be pre-expanded here. + * + * TODO: fix this too. + */ + png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); + png_ptr->background.green = + (png_uint_16)(png_ptr->background.green * 257); + png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); + png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); + } +#endif + + /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the + * background support (see the comments in scripts/pnglibconf.dfa), this + * allows pre-multiplication of the alpha channel to be implemented as + * compositing on black. This is probably sub-optimal and has been done in + * 1.5.4 betas simply to enable external critique and testing (i.e. to + * implement the new API quickly, without lots of internal changes.) + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +# ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Includes ALPHA_MODE */ + png_ptr->background_1 = png_ptr->background; +# endif + + /* This needs to change - in the palette image case a whole set of tables are + * built when it would be quicker to just calculate the correct value for + * each palette entry directly. Also, the test is too tricky - why check + * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that + * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the + * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction + * the gamma tables will not be built even if composition is required on a + * gamma encoded value. + * + * In 1.5.4 this is addressed below by an additional check on the individual + * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the + * tables. + */ + if ((png_ptr->transformations & PNG_GAMMA) + || ((png_ptr->transformations & PNG_RGB_TO_GRAY) + && (png_gamma_significant(png_ptr->gamma) || + png_gamma_significant(png_ptr->screen_gamma))) + || ((png_ptr->transformations & PNG_COMPOSE) + && (png_gamma_significant(png_ptr->gamma) + || png_gamma_significant(png_ptr->screen_gamma) +# ifdef PNG_READ_BACKGROUND_SUPPORTED + || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE + && png_gamma_significant(png_ptr->background_gamma)) +# endif + )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) + && png_gamma_significant(png_ptr->screen_gamma)) + ) + { + png_build_gamma_table(png_ptr, png_ptr->bit_depth); + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + if (png_ptr->transformations & PNG_COMPOSE) + { + /* Issue a warning about this combination: because RGB_TO_GRAY is + * optimized to do the gamma transform if present yet do_background has + * to do the same thing if both options are set a + * double-gamma-correction happens. This is true in all versions of + * libpng to date. + */ + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + png_warning(png_ptr, + "libpng does not support gamma+background+rgb_to_gray"); + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + /* We don't get to here unless there is a tRNS chunk with non-opaque + * entries - see the checking code at the start of this function. + */ + png_color back, back_1; + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + png_fixed_point g, gs; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = PNG_FP_1; + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + default: + g = PNG_FP_1; /* back_1 */ + gs = PNG_FP_1; /* back */ + break; + } + + if (png_gamma_significant(gs)) + { + back.red = png_gamma_8bit_correct(png_ptr->background.red, + gs); + back.green = png_gamma_8bit_correct(png_ptr->background.green, + gs); + back.blue = png_gamma_8bit_correct(png_ptr->background.blue, + gs); + } + + else + { + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + } + + if (png_gamma_significant(g)) + { + back_1.red = png_gamma_8bit_correct(png_ptr->background.red, + g); + back_1.green = png_gamma_8bit_correct( + png_ptr->background.green, g); + back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, + g); + } + + else + { + back_1.red = (png_byte)png_ptr->background.red; + back_1.green = (png_byte)png_ptr->background.green; + back_1.blue = (png_byte)png_ptr->background.blue; + } + } + + for (i = 0; i < num_palette; i++) + { + if (i < (int)png_ptr->num_trans && + png_ptr->trans_alpha[i] != 0xff) + { + if (png_ptr->trans_alpha[i] == 0) + { + palette[i] = back; + } + else /* if (png_ptr->trans_alpha[i] != 0xff) */ + { + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + + /* Prevent the transformations being done again. + * + * NOTE: this is highly dubious; it removes the transformations in + * place. This seems inconsistent with the general treatment of the + * transformations elsewhere. + */ + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); + } /* color_type == PNG_COLOR_TYPE_PALETTE */ + + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else /* color_type != PNG_COLOR_TYPE_PALETTE */ + { + int gs_sig, g_sig; + png_fixed_point g = PNG_FP_1; /* Correction to linear */ + png_fixed_point gs = PNG_FP_1; /* Correction to screen */ + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = png_ptr->screen_gamma; + /* gs = PNG_FP_1; */ + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + + default: + png_error(png_ptr, "invalid background gamma type"); + } + + g_sig = png_gamma_significant(g); + gs_sig = png_gamma_significant(gs); + + if (g_sig) + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); + + if (gs_sig) + png_ptr->background.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, gs); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) + { + /* RGB or RGBA with color background */ + if (g_sig) + { + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); + + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); + + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); + } + + if (gs_sig) + { + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); + + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); + + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); + } + } + + else + { + /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ + png_ptr->background_1.red = png_ptr->background_1.green + = png_ptr->background_1.blue = png_ptr->background_1.gray; + + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + } + + /* The background is now in screen gamma: */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; + } /* color_type != PNG_COLOR_TYPE_PALETTE */ + }/* png_ptr->transformations & PNG_BACKGROUND */ + + else + /* Transformation does not include PNG_BACKGROUND */ +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ + && ((png_ptr->transformations & PNG_EXPAND) == 0 || + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) +#endif + ) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + + /*NOTE: there are other transformations that should probably be in here + * too. + */ + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + + /* Done the gamma correction. */ + png_ptr->transformations &= ~PNG_GAMMA; + } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ + } +#ifdef PNG_READ_BACKGROUND_SUPPORTED + else +#endif +#endif /* PNG_READ_GAMMA_SUPPORTED */ + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + /* No GAMMA transformation (see the hanging else 4 lines above) */ + if ((png_ptr->transformations & PNG_COMPOSE) && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = (int)png_ptr->num_trans; + png_color back; + png_colorp palette = png_ptr->palette; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < istop; i++) + { + if (png_ptr->trans_alpha[i] == 0) + { + palette[i] = back; + } + + else if (png_ptr->trans_alpha[i] != 0xff) + { + /* The png_composite() macro is defined in png.h */ + png_composite(palette[i].red, palette[i].red, + png_ptr->trans_alpha[i], back.red); + + png_composite(palette[i].green, palette[i].green, + png_ptr->trans_alpha[i], back.green); + + png_composite(palette[i].blue, palette[i].blue, + png_ptr->trans_alpha[i], back.blue); + } + } + + png_ptr->transformations &= ~PNG_COMPOSE; + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; + + /* significant bits can be in the range 1 to 7 for a meaninful result, if + * the number of significant bits is 0 then no shift is done (this is an + * error condition which is silently ignored.) + */ + if (shift > 0 && shift < 8) for (i=0; ipalette[i].red; + + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.green; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].green; + + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.blue; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue; + + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; + } + } +#endif /* PNG_READ_SHIFT_SUPPORTED */ +} + +/* Modify the info structure to reflect the transformations. The + * info should be updated so a PNG file could be written with it, + * assuming the transformations result in valid PNG data. + */ +void /* PRIVATE */ +png_read_transform_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_transform_info"); + +#ifdef PNG_READ_EXPAND_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + /* This check must match what actually happens in + * png_do_expand_palette; if it ever checks the tRNS chunk to see if + * it is all opaque we must do the same (at present it does not.) + */ + if (png_ptr->num_trans > 0) + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + + else + info_ptr->color_type = PNG_COLOR_TYPE_RGB; + + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + else + { + if (png_ptr->num_trans) + { + if (png_ptr->transformations & PNG_EXPAND_tRNS) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + + info_ptr->num_trans = 0; + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* The following is almost certainly wrong unless the background value is in + * the screen space! + */ + if (png_ptr->transformations & PNG_COMPOSE) + info_ptr->background = png_ptr->background; +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), + * however it seems that the code in png_init_read_transformations, which has + * been called before this from png_read_update_info->png_read_start_row + * sometimes does the gamma transform and cancels the flag. + */ + info_ptr->gamma = png_ptr->gamma; +#endif + + if (info_ptr->bit_depth == 16) + { +# ifdef PNG_READ_16BIT_SUPPORTED +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_SCALE_16_TO_8) + info_ptr->bit_depth = 8; +# endif + +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_16_TO_8) + info_ptr->bit_depth = 8; +# endif + +# else + /* No 16 bit support: force chopping 16-bit input down to 8, in this case + * the app program can chose if both APIs are available by setting the + * correct scaling to use. + */ +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* For compatibility with previous versions use the strip method by + * default. This code works because if PNG_SCALE_16_TO_8 is already + * set the code below will do that in preference to the chop. + */ + png_ptr->transformations |= PNG_16_TO_8; + info_ptr->bit_depth = 8; +# else + +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_ptr->transformations |= PNG_SCALE_16_TO_8; + info_ptr->bit_depth = 8; +# else + + CONFIGURATION ERROR: you must enable at least one 16 to 8 method +# endif +# endif +#endif /* !READ_16BIT_SUPPORTED */ + } + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + info_ptr->color_type = (png_byte)(info_ptr->color_type | + PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if (png_ptr->transformations & PNG_QUANTIZE) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } + } +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && + info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + info_ptr->bit_depth = 16; + } +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) + info_ptr->bit_depth = 8; +#endif + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_STRIP_ALPHA) + { + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); + info_ptr->num_trans = 0; + } +#endif + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + +#ifdef PNG_READ_FILLER_SUPPORTED + /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ + if ((png_ptr->transformations & PNG_FILLER) && + ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) + { + info_ptr->channels++; + /* If adding a true alpha channel not just filler */ + if (png_ptr->transformations & PNG_ADD_ALPHA) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } +#endif + +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ +defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + { + if (info_ptr->bit_depth < png_ptr->user_transform_depth) + info_ptr->bit_depth = png_ptr->user_transform_depth; + + if (info_ptr->channels < png_ptr->user_transform_channels) + info_ptr->channels = png_ptr->user_transform_channels; + } +#endif + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * + info_ptr->bit_depth); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); + + /* Adding in 1.5.4: cache the above value in png_struct so that we can later + * check in png_rowbytes that the user buffer won't get overwritten. Note + * that the field is not always set - if png_read_update_info isn't called + * the application has to either not do any transforms or get the calculation + * right itself. + */ + png_ptr->info_rowbytes = info_ptr->rowbytes; + +#ifndef PNG_READ_EXPAND_SUPPORTED + if (png_ptr) + return; +#endif +} + +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ +void /* PRIVATE */ +png_do_read_transformations(png_structp png_ptr, png_row_infop row_info) +{ + png_debug(1, "in png_do_read_transformations"); + + if (png_ptr->row_buf == NULL) + { + /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this + * error is incredibly rare and incredibly easy to debug without this + * information. + */ + png_error(png_ptr, "NULL row buffer"); + } + + /* The following is debugging; prior to 1.5.4 the code was never compiled in; + * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro + * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for + * selected new APIs to ensure that there is no API change. + */ + if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && + !(png_ptr->flags & PNG_FLAG_ROW_INIT)) + { + /* Application has failed to call either png_read_start_image() or + * png_read_update_info() after setting transforms that expand pixels. + * This check added to libpng-1.2.19 (but not enabled until 1.5.4). + */ + png_error(png_ptr, "Uninitialized row"); + } + +#ifdef PNG_READ_EXPAND_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND) + { + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_do_expand_palette(row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + } + + else + { + if (png_ptr->num_trans && + (png_ptr->transformations & PNG_EXPAND_tRNS)) + png_do_expand(row_info, png_ptr->row_buf + 1, + &(png_ptr->trans_color)); + + else + png_do_expand(row_info, png_ptr->row_buf + 1, + NULL); + } + } +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + !(png_ptr->transformations & PNG_COMPOSE) && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, row_info, + png_ptr->row_buf + 1); + + if (rgb_error) + { + png_ptr->rgb_to_gray_status=1; + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + } + } +#endif + +/* From Andreas Dilger e-mail to png-implement, 26 March 1998: + * + * In most cases, the "simple transparency" should be done prior to doing + * gray-to-RGB, or you will have to test 3x as many bytes to check if a + * pixel is transparent. You would also need to make sure that the + * transparency information is upgraded to RGB. + * + * To summarize, the current flow is: + * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + * with background "in place" if transparent, + * convert to RGB if necessary + * - Gray + alpha -> composite with gray background and remove alpha bytes, + * convert to RGB if necessary + * + * To support RGB backgrounds for gray images we need: + * - Gray + simple transparency -> convert to RGB + simple transparency, + * compare 3 or 6 bytes and composite with + * background "in place" if transparent + * (3x compare/pixel compared to doing + * composite with gray bkgrnd) + * - Gray + alpha -> convert to RGB + alpha, composite with background and + * remove alpha bytes (3x float + * operations/pixel compared with composite + * on gray background) + * + * Greg's change will do this. The reason it wasn't done before is for + * performance, as this increases the per-pixel operations. If we would check + * in advance if the background was gray or RGB, and position the gray-to-RGB + * transform appropriately, then it would save a lot of work/time. + */ + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* If gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons + */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_SUPPORTED) + if (png_ptr->transformations & PNG_COMPOSE) + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + if ((png_ptr->transformations & PNG_GAMMA) && +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Because RGB_TO_GRAY does the gamma transform. */ + !(png_ptr->transformations & PNG_RGB_TO_GRAY) && +#endif +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_SUPPORTED) + /* Because PNG_COMPOSE does the gamma transform if there is something to + * do (if there is an alpha channel or transparency.) + */ + !((png_ptr->transformations & PNG_COMPOSE) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && +#endif + /* Because png_init_read_transformations transforms the palette, unless + * RGB_TO_GRAY will do the transform. + */ + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) && + (png_ptr->transformations & PNG_COMPOSE) && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && + (row_info->color_type & PNG_COLOR_MASK_ALPHA)) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if (png_ptr->transformations & PNG_SCALE_16_TO_8) + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* There is no harm in doing both of these because only one has any effect, + * by putting the 'scale' option first if the app asks for scale (either by + * calling the API or in a TRANSFORM flag) this is what happens. + */ + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if (png_ptr->transformations & PNG_QUANTIZE) + { + png_do_quantize(row_info, png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); + + if (row_info->rowbytes == 0) + png_error(png_ptr, "png_do_quantize returned rowbytes=0"); + } +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Do the expansion now, after all the arithmetic has been done. Notice + * that previous transformations can handle the PNG_EXPAND_16 flag if this + * is efficient (particularly true in the case of gamma correction, where + * better accuracy results faster!) + */ + if (png_ptr->transformations & PNG_EXPAND_16) + png_do_expand_16(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /*NOTE: moved here in 1.5.4 (from much later in this list.) */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + if (png_ptr->transformations & PNG_SHIFT) + png_do_unshift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if (png_ptr->transformations & PNG_PACK) + png_do_unpack(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if (png_ptr->transformations & PNG_FILLER) + png_do_read_filler(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_16BIT_SUPPORTED +#ifdef PNG_READ_SWAP_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if (png_ptr->transformations & PNG_USER_TRANSFORM) + { + if (png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* User read transform function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + if (png_ptr->user_transform_depth) + row_info->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels) + row_info->channels = png_ptr->user_transform_channels; +#endif + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); + } +#endif +} + +#ifdef PNG_READ_PACK_SUPPORTED +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with + * a bit depth of 1, you would end up with bytes that only contained + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. + */ +void /* PRIVATE */ +png_do_unpack(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_unpack"); + + if (row_info->bit_depth < 8) + { + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + switch (row_info->bit_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x01); + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + + png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x03); + + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x0f); + + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED +/* Reverse the effects of png_do_shift. This routine merely shifts the + * pixels back to their significant bits values. Thus, if you have + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +void /* PRIVATE */ +png_do_unshift(png_row_infop row_info, png_bytep row, + png_const_color_8p sig_bits) +{ + int color_type; + + png_debug(1, "in png_do_unshift"); + + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; + int bit_depth = row_info->bit_depth; + + if (color_type & PNG_COLOR_MASK_COLOR) + { + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; + } + + else + { + shift[channels++] = bit_depth - sig_bits->gray; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + { + shift[channels++] = bit_depth - sig_bits->alpha; + } + + { + int c, have_shift; + + for (c = have_shift = 0; c < channels; ++c) + { + /* A shift of more than the bit depth is an error condition but it + * gets ignored here. + */ + if (shift[c] <= 0 || shift[c] >= bit_depth) + shift[c] = 0; + + else + have_shift = 1; + } + + if (!have_shift) + return; + } + + switch (bit_depth) + { + default: + /* Must be 1bpp gray: should not be here! */ + /* NOTREACHED */ + break; + + case 2: + /* Must be 2bpp gray */ + /* assert(channels == 1 && shift[0] == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + + while (bp < bp_end) + { + int b = (*bp >> 1) & 0x55; + *bp++ = (png_byte)b; + } + break; + } + + case 4: + /* Must be 4bpp gray */ + /* assert(channels == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int gray_shift = shift[0]; + int mask = 0xf >> gray_shift; + + mask |= mask << 4; + + while (bp < bp_end) + { + int b = (*bp >> gray_shift) & mask; + *bp++ = (png_byte)b; + } + break; + } + + case 8: + /* Single byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int b = *bp >> shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)b; + } + break; + } + +#ifdef PNG_READ_16BIT_SUPPORTED + case 16: + /* Double byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int value = (bp[0] << 8) + bp[1]; + + value >>= shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + break; + } +#endif + } + } +} +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale rows of bit depth 16 down to 8 accurately */ +void /* PRIVATE */ +png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_scale_16_to_8"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + /* The input is an array of 16 bit components, these must be scaled to + * 8 bits each. For a 16 bit value V the required value (from the PNG + * specification) is: + * + * (V * 255) / 65535 + * + * This reduces to round(V / 257), or floor((V + 128.5)/257) + * + * Represent V as the two byte value vhi.vlo. Make a guess that the + * result is the top byte of V, vhi, then the correction to this value + * is: + * + * error = floor(((V-vhi.vhi) + 128.5) / 257) + * = floor(((vlo-vhi) + 128.5) / 257) + * + * This can be approximated using integer arithmetic (and a signed + * shift): + * + * error = (vlo-vhi+128) >> 8; + * + * The approximate differs from the exact answer only when (vlo-vhi) is + * 128; it then gives a correction of +1 when the exact correction is + * 0. This gives 128 errors. The exact answer (correct for all 16 bit + * input values) is: + * + * error = (vlo-vhi+128)*65535 >> 24; + * + * An alternative arithmetic calculation which also gives no errors is: + * + * (V * 255 + 32895) >> 16 + */ + + png_int_32 tmp = *sp++; /* must be signed! */ + tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; + *dp++ = (png_byte)tmp; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_info->width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +void /* PRIVATE */ +/* Simply discard the low byte. This was the default behavior prior + * to libpng-1.5.4. + */ +png_do_chop(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_chop"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + *dp++ = *sp; + sp += 2; /* skip low byte */ + } + + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_info->width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_swap_alpha"); + + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from RGBA to ARGB */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This converts from RRGGBBAA to AARRGGBB */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } +#endif + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from GA to AG */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This converts from GGAA to AAGG */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } +#endif + } + } +} +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_uint_32 row_width; + png_debug(1, "in png_do_read_invert_alpha"); + + row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=3; + dp=sp; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=6; + dp=sp; + } + } +#endif + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = *(--sp); + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); +/* + *(--dp) = *(--sp); + *(--dp) = *(--sp); +*/ + sp-=2; + dp=sp; + } + } +#endif + } +} +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED +/* Add filler channel if we have RGB color */ +void /* PRIVATE */ +png_do_read_filler(png_row_infop row_info, png_bytep row, + png_uint_32 filler, png_uint_32 flags) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + +#ifdef PNG_READ_16BIT_SUPPORTED + png_byte hi_filler = (png_byte)((filler>>8) & 0xff); +#endif + png_byte lo_filler = (png_byte)(filler & 0xff); + + png_debug(1, "in png_do_read_filler"); + + if ( + row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from G to GX */ + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + + else + { + /* This changes the data from G to XG */ + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from GG to GGXX */ + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + + else + { + /* This changes the data from GG to XXGG */ + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } +#endif + } /* COLOR_TYPE == GRAY */ + else if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if (row_info->bit_depth == 8) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from RGB to RGBX */ + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + + else + { + /* This changes the data from RGB to XRGB */ + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + + else + { + /* This changes the data from RRGGBB to XXRRGGBB */ + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + } +#endif + } /* COLOR_TYPE == RGB */ +} +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand grayscale files to RGB, with or without alpha */ +void /* PRIVATE */ +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_gray_to_rgb"); + + if (row_info->bit_depth >= 8 && + !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + /* This changes G to RGB */ + png_bytep sp = row + (png_size_t)row_width - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + + else + { + /* This changes GG to RRGGBB */ + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This changes GA to RGBA */ + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + + else + { + /* This changes GGAA to RRGGBBAA */ + png_bytep sp = row + (png_size_t)row_width * 4 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + row_info->channels = (png_byte)(row_info->channels + 2); + row_info->color_type |= PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB files to grayscale, with or without alpha + * using the equation given in Poynton's ColorFAQ of 1998-01-04 at + * (THIS LINK IS DEAD June 2008 but + * versions dated 1998 through November 2002 have been archived at + * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ + * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) + * Charles Poynton poynton at poynton.com + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * + * Poynton's current link (as of January 2003 through July 2011): + * + * has changed the numbers slightly: + * + * Y = 0.2126*R + 0.7152*G + 0.0722*B + * + * which can be expressed with integers as + * + * Y = (6966 * R + 23436 * G + 2366 * B)/32768 + * + * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 + * end point chromaticities and the D65 white point. Depending on the + * precision used for the D65 white point this produces a variety of different + * numbers, however if the four decimal place value used in ITU-R Rec 709 is + * used (0.3127,0.3290) the Y calculation would be: + * + * Y = (6968 * R + 23435 * G + 2366 * B)/32768 + * + * While this is correct the rounding results in an overflow for white, because + * the sum of the rounded coefficients is 32769, not 32768. Consequently + * libpng uses, instead, the closest non-overflowing approximation: + * + * Y = (6968 * R + 23434 * G + 2366 * B)/32768 + * + * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk + * (including an sRGB chunk) then the chromaticities are used to calculate the + * coefficients. See the chunk handling in pngrutil.c for more information. + * + * In all cases the calculation is to be done in a linear colorspace. If no + * gamma information is available to correct the encoding of the original RGB + * values this results in an implicit assumption that the original PNG RGB + * values were linear. + * + * Other integer coefficents can be used via png_set_rgb_to_gray(). Because + * the API takes just red and green coefficients the blue coefficient is + * calculated to make the sum 32768. This will result in different rounding + * to that used above. + */ +int /* PRIVATE */ +png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) + +{ + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray"); + + if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + PNG_CONST png_uint_32 bc = 32768 - rc - gc; + PNG_CONST png_uint_32 row_width = row_info->width; + PNG_CONST int have_alpha = + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; + + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* Notice that gamma to/from 1 are not necessarily inverses (if + * there is an overall gamma correction). Prior to 1.5.5 this code + * checked the linearized values for equality; this doesn't match + * the documentation, the original values must be checked. + */ + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) + { + red = png_ptr->gamma_to_1[red]; + green = png_ptr->gamma_to_1[green]; + blue = png_ptr->gamma_to_1[blue]; + + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red + gc*green + bc*blue + 16384)>>15]; + } + + else + { + /* If there is no overall correction the table will not be + * set. + */ + if (png_ptr->gamma_table != NULL) + red = png_ptr->gamma_table[red]; + + *(dp++) = red; + } + + if (have_alpha) + *(dp++) = *(sp++); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) + { + rgb_error |= 1; + /*NOTE: this is the historical approach which simply + * truncates the results. + */ + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + } + + else + *(dp++) = red; + + if (have_alpha) + *(dp++) = *(sp++); + } + } + } + + else /* RGB bit_depth == 16 */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + + if (red == green && red == blue) + { + if (png_ptr->gamma_16_table != NULL) + w = png_ptr->gamma_16_table[(red&0xff) + >> png_ptr->gamma_shift][red>>8]; + + else + w = red; + } + + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) + >> png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = + png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) + >> png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + + bc*blue_1 + 16384)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + + if (have_alpha) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + + red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + + if (red != green || red != blue) + rgb_error |= 1; + + /* From 1.5.5 in the 16 bit case do the accurate conversion even + * in the 'fast' case - this is because this is where the code + * ends up when handling linear 16 bit data. + */ + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> + 15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + + if (have_alpha) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + } + + row_info->channels = (png_byte)(row_info->channels - 2); + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_COLOR); + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + return rgb_error; +} +#endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth + * large of png_color. This lets grayscale images be treated as + * paletted. Most useful for gamma correction and simplification + * of code. This API is not used internally. + */ +void PNGAPI +png_build_grayscale_palette(int bit_depth, png_colorp palette) +{ + int num_palette; + int color_inc; + int i; + int v; + + png_debug(1, "in png_do_build_grayscale_palette"); + + if (palette == NULL) + return; + + switch (bit_depth) + { + case 1: + num_palette = 2; + color_inc = 0xff; + break; + + case 2: + num_palette = 4; + color_inc = 0x55; + break; + + case 4: + num_palette = 16; + color_inc = 0x11; + break; + + case 8: + num_palette = 256; + color_inc = 1; + break; + + default: + num_palette = 0; + color_inc = 0; + break; + } + + for (i = 0, v = 0; i < num_palette; i++, v += color_inc) + { + palette[i].red = (png_byte)v; + palette[i].green = (png_byte)v; + palette[i].blue = (png_byte)v; + } +} +#endif + + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ + (defined PNG_READ_ALPHA_MODE_SUPPORTED) +/* Replace any alpha or transparency with the supplied background color. + * "background" is already in the screen gamma, while "background_1" is + * at a gamma of 1.0. Paletted files have already been taken care of. + */ +void /* PRIVATE */ +png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) +{ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; + png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; + png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; + png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; + int gamma_shift = png_ptr->gamma_shift; +#endif + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + int shift; + + png_debug(1, "in png_do_compose"); + + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_GRAY: + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row; + shift = 7; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x01) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 7; + sp++; + } + + else + shift--; + } + break; + } + + case 2: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x03); + png_byte g = (png_byte)((gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03); + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + + if (!shift) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + + else +#endif + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + break; + } + + case 4: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x0f); + png_byte g = (png_byte)((gamma_table[p | + (p << 4)] >> 4) & 0x0f); + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + + if (!shift) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + + else +#endif + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(png_ptr->background.gray << shift); + } + + if (!shift) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + break; + } + + case 8: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + + else + *sp = gamma_table[*sp]; + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + } + } + break; + } + + case 16: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + if (v == png_ptr->trans_color.gray) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else + { + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + if (v == png_ptr->trans_color.gray) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + } + } + break; + } + + default: + break; + } + break; + } + + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + *sp = gamma_table[*sp]; + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.gray; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.gray); + if (!optimize) + w = gamma_from_1[w]; + *sp = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_byte a = *(sp + 1); + + if (a == 0) + *sp = (png_byte)png_ptr->background.gray; + + else if (a < 0xff) + png_composite(*sp, *sp, a, png_ptr->background_1.gray); + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, png_ptr->background_1.gray); + if (optimize) + w = v; + else + w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, png_ptr->background_1.gray); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.red); + if (!optimize) w = gamma_from_1[w]; + *sp = w; + + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, png_ptr->background_1.green); + if (!optimize) w = gamma_from_1[w]; + *(sp + 1) = w; + + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, png_ptr->background_1.blue); + if (!optimize) w = gamma_from_1[w]; + *(sp + 2) = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else if (a < 0xff) + { + png_composite(*sp, *sp, a, png_ptr->background.red); + + png_composite(*(sp + 1), *(sp + 1), a, + png_ptr->background.green); + + png_composite(*(sp + 2), *(sp + 2), a, + png_ptr->background.blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v, w; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, png_ptr->background_1.red); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, png_ptr->background_1.green); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, png_ptr->background_1.blue); + if (!optimize) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 v; + + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + png_composite_16(v, r, a, png_ptr->background.red); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + png_composite_16(v, g, a, png_ptr->background.green); + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + png_composite_16(v, b, a, png_ptr->background.blue); + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + default: + break; + } + } +} +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Gamma correct the image, avoiding the alpha channel. Make sure + * you do this after you deal with the transparency issue on grayscale + * or RGB images. If your bit depth is 8, use gamma_table, if it + * is 16, use gamma_16_table and gamma_shift. Build these with + * build_gamma_table(). + */ +void /* PRIVATE */ +png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) +{ + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; + int gamma_shift = png_ptr->gamma_shift; + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma"); + + if (((row_info->bit_depth <= 8 && gamma_table != NULL) || + (row_info->bit_depth == 16 && gamma_16_table != NULL))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + + *sp = gamma_table[*sp]; + sp++; + + *sp = gamma_table[*sp]; + sp++; + + sp++; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp += 2; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY: + { + if (row_info->bit_depth == 2) + { + sp = row; + for (i = 0; i < row_width; i += 4) + { + int a = *sp & 0xc0; + int b = *sp & 0x30; + int c = *sp & 0x0c; + int d = *sp & 0x03; + + *sp = (png_byte)( + ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| + ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| + ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| + ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); + sp++; + } + } + + if (row_info->bit_depth == 4) + { + sp = row; + for (i = 0; i < row_width; i += 2) + { + int msb = *sp & 0xf0; + int lsb = *sp & 0x0f; + + *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) + | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); + sp++; + } + } + + else if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + } + } + + else if (row_info->bit_depth == 16) + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + + default: + break; + } + } +} +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* Encode the alpha channel to the output gamma (the input channel is always + * linear.) Called only with color types that have an alpha channel. Needs the + * from_1 tables. + */ +void /* PRIVATE */ +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) +{ + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_encode_alpha"); + + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + if (row_info->bit_depth == 8) + { + PNG_CONST png_bytep table = png_ptr->gamma_from_1; + + if (table != NULL) + { + PNG_CONST int step = + (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; + + /* The alpha channel is the last component: */ + row += step - 1; + + for (; row_width > 0; --row_width, row += step) + *row = table[*row]; + + return; + } + } + + else if (row_info->bit_depth == 16) + { + PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; + PNG_CONST int gamma_shift = png_ptr->gamma_shift; + + if (table != NULL) + { + PNG_CONST int step = + (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; + + /* The alpha channel is the last component: */ + row += step - 2; + + for (; row_width > 0; --row_width, row += step) + { + png_uint_16 v; + + v = table[*(row + 1) >> gamma_shift][*row]; + *row = (png_byte)((v >> 8) & 0xff); + *(row + 1) = (png_byte)(v & 0xff); + } + + return; + } + } + } + + /* Only get to here if called with a weird row_info; no harm has been done, + * so just issue a warning. + */ + png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); +} +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expands a palette row to an RGB or RGBA row depending + * upon whether you supply trans and num_trans. + */ +void /* PRIVATE */ +png_do_expand_palette(png_row_infop row_info, png_bytep row, + png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand_palette"); + + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 1; + + else + *dp = 0; + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)value; + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((row_width & 0x01) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)value; + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift += 4; + + dp--; + } + break; + } + + default: + break; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (row_info->bit_depth == 8) + { + { + if (num_trans > 0) + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + + for (i = 0; i < row_width; i++) + { + if ((int)(*sp) >= num_trans) + *dp-- = 0xff; + + else + *dp-- = trans_alpha[*sp]; + + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + row_info->color_type = 6; + row_info->channels = 4; + } + + else + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width * 3) - 1; + + for (i = 0; i < row_width; i++) + { + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = 24; + row_info->rowbytes = row_width * 3; + row_info->color_type = 2; + row_info->channels = 3; + } + } + } + } +} + +/* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. + */ +void /* PRIVATE */ +png_do_expand(png_row_infop row_info, png_bytep row, + png_const_color_16p trans_color) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); + + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + gray = (png_uint_16)((gray & 0x01) * 0xff); + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 0xff; + + else + *dp = 0; + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + gray = (png_uint_16)((gray & 0x03) * 0x55); + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + gray = (png_uint_16)((gray & 0x0f) * 0x11); + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (trans_color != NULL) + { + if (row_info->bit_depth == 8) + { + gray = gray & 0xff; + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 1) - 1; + + for (i = 0; i < row_width; i++) + { + if (*sp == gray) + *dp-- = 0; + + else + *dp-- = 0xff; + + *dp-- = *sp--; + } + } + + else if (row_info->bit_depth == 16) + { + png_byte gray_high = (png_byte)((gray >> 8) & 0xff); + png_byte gray_low = (png_byte)(gray & 0xff); + sp = row + row_info->rowbytes - 1; + dp = row + (row_info->rowbytes << 1) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 1) == gray_high && *(sp) == gray_low) + { + *dp-- = 0; + *dp-- = 0; + } + + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + + *dp-- = *sp--; + *dp-- = *sp--; + } + } + + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_width); + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) + { + if (row_info->bit_depth == 8) + { + png_byte red = (png_byte)(trans_color->red & 0xff); + png_byte green = (png_byte)(trans_color->green & 0xff); + png_byte blue = (png_byte)(trans_color->blue & 0xff); + sp = row + (png_size_t)row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) + *dp-- = 0; + + else + *dp-- = 0xff; + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_color->red & 0xff); + png_byte green_low = (png_byte)(trans_color->green & 0xff); + png_byte blue_low = (png_byte)(trans_color->blue & 0xff); + sp = row + row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 3) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 5) == red_high && + *(sp - 4) == red_low && + *(sp - 3) == green_high && + *(sp - 2) == green_low && + *(sp - 1) == blue_high && + *(sp ) == blue_low) + { + *dp-- = 0; + *dp-- = 0; + } + + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + row_info->channels = 4; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + } +} +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* If the bit depth is 8 and the color type is not a palette type expand the + * whole row to 16 bits. Has no effect otherwise. + */ +void /* PRIVATE */ +png_do_expand_16(png_row_infop row_info, png_bytep row) +{ + if (row_info->bit_depth == 8 && + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + /* The row have a sequence of bytes containing [0..255] and we need + * to turn it into another row containing [0..65535], to do this we + * calculate: + * + * (input / 255) * 65535 + * + * Which happens to be exactly input * 257 and this can be achieved + * simply by byte replication in place (copying backwards). + */ + png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ + png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ + while (dp > sp) + dp[-2] = dp[-1] = *--sp, dp -= 2; + + row_info->rowbytes *= 2; + row_info->bit_depth = 16; + row_info->pixel_depth = (png_byte)(row_info->channels * 16); + } +} +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +void /* PRIVATE */ +png_do_quantize(png_row_infop row_info, png_bytep row, + png_const_bytep palette_lookup, png_const_bytep quantize_lookup) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_quantize"); + + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + + /* This looks real messy, but the compiler will reduce + * it down to a reasonable formula. For example, with + * 5 bits per color, we get: + * p = (((r >> 3) & 0x1f) << 10) | + * (((g >> 3) & 0x1f) << 5) | + * ((b >> 3) & 0x1f); + */ + p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + palette_lookup != NULL) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + sp++; + + p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + + else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + quantize_lookup) + { + sp = row; + + for (i = 0; i < row_width; i++, sp++) + { + *sp = quantize_lookup[*sp]; + } + } + } +} +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_intrapixel"); + + if ( + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); + *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 red = (s0 + s1 + 65536) & 0xffff; + png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngrutil.c b/WDL/libpng/pngrutil.c new file mode 100644 index 00000000..62e96322 --- /dev/null +++ b/WDL/libpng/pngrutil.c @@ -0,0 +1,4160 @@ + +/* pngrutil.c - utilities to read a PNG file + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that are only called from within + * libpng itself during the course of reading an image. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#define png_strtod(p,a,b) strtod(a,b) + +png_uint_32 PNGAPI +png_get_uint_31(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range"); + + return (uval); +} + +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) +/* The following is a variation on the above for use with the fixed + * point values used for gAMA and cHRM. Instead of png_error it + * issues a warning and returns (-1) - an invalid value because both + * gAMA and cHRM use *unsigned* integers for fixed point values. + */ +#define PNG_FIXED_ERROR (-1) + +static png_fixed_point /* PRIVATE */ +png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval <= PNG_UINT_31_MAX) + return (png_fixed_point)uval; /* known to be in range */ + + /* The caller can turn off the warning by passing NULL. */ + if (png_ptr != NULL) + png_warning(png_ptr, "PNG fixed point integer out of range"); + + return PNG_FIXED_ERROR; +} +#endif + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +/* NOTE: the read macros will obscure these definitions, so that if + * PNG_USE_READ_MACROS is set the library will not use them internally, + * but the APIs will still be available externally. + * + * The parentheses around "PNGAPI function_name" in the following three + * functions are necessary because they allow the macros to co-exist with + * these (unused but exported) functions. + */ + +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ +png_uint_32 (PNGAPI +png_get_uint_32)(png_const_bytep buf) +{ + png_uint_32 uval = + ((png_uint_32)(*(buf )) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + ((png_uint_32)(*(buf + 3)) ) ; + + return uval; +} + +/* Grab a signed 32-bit integer from a buffer in big-endian format. The + * data is stored in the PNG file in two's complement format and there + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore + * the following code does a two's complement to native conversion. + */ +png_int_32 (PNGAPI +png_get_int_32)(png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + if ((uval & 0x80000000) == 0) /* non-negative */ + return uval; + + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + return -(png_int_32)uval; +} + +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ +png_uint_16 (PNGAPI +png_get_uint_16)(png_const_bytep buf) +{ + /* ANSI-C requires an int value to accomodate at least 16 bits so this + * works and allows the compiler not to worry about possible narrowing + * on 32 bit systems. (Pre-ANSI systems did not make integers smaller + * than 16 bits either.) + */ + unsigned int val = + ((unsigned int)(*buf) << 8) + + ((unsigned int)(*(buf + 1))); + + return (png_uint_16)val; +} + +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ + +/* Read and check the PNG file signature */ +void /* PRIVATE */ +png_read_sig(png_structp png_ptr, png_infop info_ptr) +{ + png_size_t num_checked, num_to_check; + + /* Exit if the user application does not expect a signature. */ + if (png_ptr->sig_bytes >= 8) + return; + + num_checked = png_ptr->sig_bytes; + num_to_check = 8 - num_checked; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; +#endif + + /* The signature must be serialized in a single I/O call. */ + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); + png_ptr->sig_bytes = 8; + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + if (num_checked < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +/* Read the chunk header (length + type name). + * Put the type name into png_ptr->chunk_name, and return the length. + */ +png_uint_32 /* PRIVATE */ +png_read_chunk_header(png_structp png_ptr) +{ + png_byte buf[8]; + png_uint_32 length; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; +#endif + + /* Read the length and the chunk name. + * This must be performed in a single I/O call. + */ + png_read_data(png_ptr, buf, 8); + length = png_get_uint_31(png_ptr, buf); + + /* Put the chunk name into png_ptr->chunk_name. */ + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); + + png_debug2(0, "Reading %lx chunk, length = %lu", + (unsigned long)png_ptr->chunk_name, (unsigned long)length); + + /* Reset the crc and run it over the chunk name. */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, buf + 4, 4); + + /* Check to see if chunk name is valid. */ + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; +#endif + + return length; +} + +/* Read data, and (optionally) run it through the CRC. */ +void /* PRIVATE */ +png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) +{ + if (png_ptr == NULL) + return; + + png_read_data(png_ptr, buf, length); + png_calculate_crc(png_ptr, buf, length); +} + +/* Optionally skip data and then check the CRC. Depending on whether we + * are reading a ancillary or critical chunk, and how the program has set + * things up, we may calculate the CRC on the data and print a message. + * Returns '1' if there was a CRC error, '0' otherwise. + */ +int /* PRIVATE */ +png_crc_finish(png_structp png_ptr, png_uint_32 skip) +{ + png_size_t i; + png_size_t istop = png_ptr->zbuf_size; + + for (i = (png_size_t)skip; i > istop; i -= istop) + { + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + } + + if (i) + { + png_crc_read(png_ptr, png_ptr->zbuf, i); + } + + if (png_crc_error(png_ptr)) + { + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ? + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) + { + png_chunk_warning(png_ptr, "CRC error"); + } + + else + { + png_chunk_benign_error(png_ptr, "CRC error"); + return (0); + } + + return (1); + } + + return (0); +} + +/* Compare the CRC stored in the PNG file with that calculated by libpng from + * the data it has read thus far. + */ +int /* PRIVATE */ +png_crc_error(png_structp png_ptr) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; +#endif + + /* The chunk CRC must be serialized in a single I/O call. */ + png_read_data(png_ptr, crc_bytes, 4); + + if (need_crc) + { + crc = png_get_uint_32(crc_bytes); + return ((int)(crc != png_ptr->crc)); + } + + else + return (0); +} + +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +static png_size_t +png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, + png_bytep output, png_size_t output_size) +{ + png_size_t count = 0; + + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't + * even necessarily handle 65536 bytes) because the type uInt is "16 bits or + * more". Consequently it is necessary to chunk the input to zlib. This + * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value + * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a + * lower value in pngpriv.h and this may sometimes have a performance + * advantage, because it forces access of the input data to be separated from + * at least some of the use by some period of time. + */ + png_ptr->zstream.next_in = data; + /* avail_in is set below from 'size' */ + png_ptr->zstream.avail_in = 0; + + while (1) + { + int ret, avail; + + /* The setting of 'avail_in' used to be outside the loop; by setting it + * inside it is possible to chunk the input to zlib and simply rely on + * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o + * data to be passed through zlib at the unavoidable cost of requiring a + * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX + * input bytes. + */ + if (png_ptr->zstream.avail_in == 0 && size > 0) + { + if (size <= ZLIB_IO_MAX) + { + /* The value is less than ZLIB_IO_MAX so the cast is safe: */ + png_ptr->zstream.avail_in = (uInt)size; + size = 0; + } + + else + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + size -= ZLIB_IO_MAX; + } + } + + /* Reset the output buffer each time round - we empty it + * after every inflate call. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = png_ptr->zbuf_size; + + ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; + + /* First copy/count any new output - but only if we didn't + * get an error code. + */ + if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) + { + png_size_t space = avail; /* > 0, see above */ + + if (output != 0 && output_size > count) + { + png_size_t copy = output_size - count; + + if (space < copy) + copy = space; + + png_memcpy(output + count, png_ptr->zbuf, copy); + } + count += space; + } + + if (ret == Z_OK) + continue; + + /* Termination conditions - always reset the zstream, it + * must be left in inflateInit state. + */ + png_ptr->zstream.avail_in = 0; + inflateReset(&png_ptr->zstream); + + if (ret == Z_STREAM_END) + return count; /* NOTE: may be zero. */ + + /* Now handle the error codes - the API always returns 0 + * and the error message is dumped into the uncompressed + * buffer if available. + */ +# ifdef PNG_WARNINGS_SUPPORTED + { + png_const_charp msg; + + if (png_ptr->zstream.msg != 0) + msg = png_ptr->zstream.msg; + + else switch (ret) + { + case Z_BUF_ERROR: + msg = "Buffer error in compressed datastream"; + break; + + case Z_DATA_ERROR: + msg = "Data error in compressed datastream"; + break; + + default: + msg = "Incomplete compressed datastream"; + break; + } + + png_chunk_warning(png_ptr, msg); + } +# endif + + /* 0 means an error - notice that this code simply ignores + * zero length compressed chunks as a result. + */ + return 0; + } +} + +/* + * Decompress trailing data in a chunk. The assumption is that chunkdata + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ +void /* PRIVATE */ +png_decompress_chunk(png_structp png_ptr, int comp_type, + png_size_t chunklength, + png_size_t prefix_size, png_size_t *newlength) +{ + /* The caller should guarantee this */ + if (prefix_size > chunklength) + { + /* The recovery is to delete the chunk. */ + png_warning(png_ptr, "invalid chunklength"); + prefix_size = 0; /* To delete everything */ + } + + else if (comp_type == PNG_COMPRESSION_TYPE_BASE) + { + png_size_t expanded_size = png_inflate(png_ptr, + (png_bytep)(png_ptr->chunkdata + prefix_size), + chunklength - prefix_size, + 0, /* output */ + 0); /* output size */ + + /* Now check the limits on this chunk - if the limit fails the + * compressed data will be removed, the prefix will remain. + */ +#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED + if (png_ptr->user_chunk_malloc_max && + (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) +#else +# ifdef PNG_USER_CHUNK_MALLOC_MAX + if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && + prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) +# endif +#endif + png_warning(png_ptr, "Exceeded size limit while expanding chunk"); + + /* If the size is zero either there was an error and a message + * has already been output (warning) or the size really is zero + * and we have nothing to do - the code will exit through the + * error case below. + */ +#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ + defined(PNG_USER_CHUNK_MALLOC_MAX) + else if (expanded_size > 0) +#else + if (expanded_size > 0) +#endif + { + /* Success (maybe) - really uncompress the chunk. */ + png_size_t new_size = 0; + png_charp text = (png_charp)png_malloc_warn(png_ptr, + prefix_size + expanded_size + 1); + + if (text != NULL) + { + png_memcpy(text, png_ptr->chunkdata, prefix_size); + new_size = png_inflate(png_ptr, + (png_bytep)(png_ptr->chunkdata + prefix_size), + chunklength - prefix_size, + (png_bytep)(text + prefix_size), expanded_size); + text[prefix_size + expanded_size] = 0; /* just in case */ + + if (new_size == expanded_size) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = text; + *newlength = prefix_size + expanded_size; + return; /* The success return! */ + } + + png_warning(png_ptr, "png_inflate logic error"); + png_free(png_ptr, text); + } + + else + png_warning(png_ptr, "Not enough memory to decompress chunk"); + } + } + + else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ + { + PNG_WARNING_PARAMETERS(p) + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); + png_formatted_warning(png_ptr, p, "Unknown compression type @1"); + + /* The recovery is to simply drop the data. */ + } + + /* Generic error return - leave the prefix, delete the compressed + * data, reallocate the chunkdata to remove the potentially large + * amount of compressed data. + */ + { + png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1); + + if (text != NULL) + { + if (prefix_size > 0) + png_memcpy(text, png_ptr->chunkdata, prefix_size); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = text; + + /* This is an extra zero in the 'uncompressed' part. */ + *(png_ptr->chunkdata + prefix_size) = 0x00; + } + /* Ignore a malloc error here - it is safe. */ + } + + *newlength = prefix_size; +} +#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ + +/* Read and check the IDHR chunk */ +void /* PRIVATE */ +png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[13]; + png_uint_32 width, height; + int bit_depth, color_type, compression_type, filter_type; + int interlace_type; + + png_debug(1, "in png_handle_IHDR"); + + if (png_ptr->mode & PNG_HAVE_IHDR) + png_error(png_ptr, "Out of place IHDR"); + + /* Check the length */ + if (length != 13) + png_error(png_ptr, "Invalid IHDR chunk"); + + png_ptr->mode |= PNG_HAVE_IHDR; + + png_crc_read(png_ptr, buf, 13); + png_crc_finish(png_ptr, 0); + + width = png_get_uint_31(png_ptr, buf); + height = png_get_uint_31(png_ptr, buf + 4); + bit_depth = buf[8]; + color_type = buf[9]; + compression_type = buf[10]; + filter_type = buf[11]; + interlace_type = buf[12]; + + /* Set internal variables */ + png_ptr->width = width; + png_ptr->height = height; + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->interlaced = (png_byte)interlace_type; + png_ptr->color_type = (png_byte)color_type; +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + + /* Find number of channels */ + switch (png_ptr->color_type) + { + default: /* invalid, png_set_IHDR calls png_error */ + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_PALETTE: + png_ptr->channels = 1; + break; + + case PNG_COLOR_TYPE_RGB: + png_ptr->channels = 3; + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_ptr->channels = 2; + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + png_ptr->channels = 4; + break; + } + + /* Set up other useful info */ + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * + png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); + png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); + png_debug1(3, "channels = %d", png_ptr->channels); + png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + color_type, interlace_type, compression_type, filter_type); +} + +/* Read and check the palette */ +void /* PRIVATE */ +png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_color palette[PNG_MAX_PALETTE_LENGTH]; + int num, i; +#ifdef PNG_POINTER_INDEXING_SUPPORTED + png_colorp pal_ptr; +#endif + + png_debug(1, "in png_handle_PLTE"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before PLTE"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid PLTE after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + png_error(png_ptr, "Duplicate PLTE chunk"); + + png_ptr->mode |= PNG_HAVE_PLTE; + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring PLTE chunk in grayscale PNG"); + png_crc_finish(png_ptr, length); + return; + } + +#ifndef PNG_READ_OPT_PLTE_SUPPORTED + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_crc_finish(png_ptr, length); + return; + } +#endif + + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) + { + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_warning(png_ptr, "Invalid palette chunk"); + png_crc_finish(png_ptr, length); + return; + } + + else + { + png_error(png_ptr, "Invalid palette chunk"); + } + } + + num = (int)length / 3; + +#ifdef PNG_POINTER_INDEXING_SUPPORTED + for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + pal_ptr->red = buf[0]; + pal_ptr->green = buf[1]; + pal_ptr->blue = buf[2]; + } +#else + for (i = 0; i < num; i++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + /* Don't depend upon png_color being any order */ + palette[i].red = buf[0]; + palette[i].green = buf[1]; + palette[i].blue = buf[2]; + } +#endif + + /* If we actually need the PLTE chunk (ie for a paletted image), we do + * whatever the normal CRC configuration tells us. However, if we + * have an RGB image, the PLTE can be considered ancillary, so + * we will act as though it is. + */ +#ifndef PNG_READ_OPT_PLTE_SUPPORTED + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#endif + { + png_crc_finish(png_ptr, 0); + } + +#ifndef PNG_READ_OPT_PLTE_SUPPORTED + else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ + { + /* If we don't want to use the data from an ancillary chunk, + * we have two options: an error abort, or a warning and we + * ignore the data in this chunk (which should be OK, since + * it's considered ancillary for a RGB or RGBA image). + */ + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) + { + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) + { + png_chunk_benign_error(png_ptr, "CRC error"); + } + + else + { + png_chunk_warning(png_ptr, "CRC error"); + return; + } + } + + /* Otherwise, we (optionally) emit a warning and use the chunk. */ + else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) + { + png_chunk_warning(png_ptr, "CRC error"); + } + } +#endif + + png_set_PLTE(png_ptr, info_ptr, palette, num); + +#ifdef PNG_READ_tRNS_SUPPORTED + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + if (png_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); + png_ptr->num_trans = (png_uint_16)num; + } + + if (info_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); + info_ptr->num_trans = (png_uint_16)num; + } + } + } +#endif + +} + +void /* PRIVATE */ +png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_debug(1, "in png_handle_IEND"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) + { + png_error(png_ptr, "No image in file"); + } + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + + if (length != 0) + { + png_warning(png_ptr, "Incorrect IEND chunk length"); + } + + png_crc_finish(png_ptr, length); + + PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ +} + +#ifdef PNG_READ_gAMA_SUPPORTED +void /* PRIVATE */ +png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_fixed_point igamma; + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before gAMA"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid gAMA after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place gAMA chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) +#ifdef PNG_READ_sRGB_SUPPORTED + && !(info_ptr->valid & PNG_INFO_sRGB) +#endif + ) + { + png_warning(png_ptr, "Duplicate gAMA chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 4) + { + png_warning(png_ptr, "Incorrect gAMA chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 4); + + if (png_crc_finish(png_ptr, 0)) + return; + + igamma = png_get_fixed_point(NULL, buf); + + /* Check for zero gamma or an error. */ + if (igamma <= 0) + { + png_warning(png_ptr, + "Ignoring gAMA chunk with out of range gamma"); + + return; + } + +# ifdef PNG_READ_sRGB_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(igamma, 45500, 500)) + { + PNG_WARNING_PARAMETERS(p) + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); + png_formatted_warning(png_ptr, p, + "Ignoring incorrect gAMA value @1 when sRGB is also present"); + return; + } + } +# endif /* PNG_READ_sRGB_SUPPORTED */ + +# ifdef PNG_READ_GAMMA_SUPPORTED + /* Gamma correction on read is supported. */ + png_ptr->gamma = igamma; +# endif + /* And set the 'info' structure members. */ + png_set_gAMA_fixed(png_ptr, info_ptr, igamma); +} +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +void /* PRIVATE */ +png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[4]; + + png_debug(1, "in png_handle_sBIT"); + + buf[0] = buf[1] = buf[2] = buf[3] = 0; + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sBIT"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sBIT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + { + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sBIT chunk"); + } + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) + { + png_warning(png_ptr, "Duplicate sBIT chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 3; + + else + truelen = (png_size_t)png_ptr->channels; + + if (length != truelen || length > 4) + { + png_warning(png_ptr, "Incorrect sBIT chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + + if (png_crc_finish(png_ptr, 0)) + return; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; + png_ptr->sig_bit.blue = buf[2]; + png_ptr->sig_bit.alpha = buf[3]; + } + + else + { + png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[0]; + png_ptr->sig_bit.blue = buf[0]; + png_ptr->sig_bit.alpha = buf[1]; + } + + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); +} +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +void /* PRIVATE */ +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[32]; + png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, + y_blue; + + png_debug(1, "in png_handle_cHRM"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before cHRM"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid cHRM after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place cHRM chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) +# ifdef PNG_READ_sRGB_SUPPORTED + && !(info_ptr->valid & PNG_INFO_sRGB) +# endif + ) + { + png_warning(png_ptr, "Duplicate cHRM chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 32) + { + png_warning(png_ptr, "Incorrect cHRM chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 32); + + if (png_crc_finish(png_ptr, 0)) + return; + + x_white = png_get_fixed_point(NULL, buf); + y_white = png_get_fixed_point(NULL, buf + 4); + x_red = png_get_fixed_point(NULL, buf + 8); + y_red = png_get_fixed_point(NULL, buf + 12); + x_green = png_get_fixed_point(NULL, buf + 16); + y_green = png_get_fixed_point(NULL, buf + 20); + x_blue = png_get_fixed_point(NULL, buf + 24); + y_blue = png_get_fixed_point(NULL, buf + 28); + + if (x_white == PNG_FIXED_ERROR || + y_white == PNG_FIXED_ERROR || + x_red == PNG_FIXED_ERROR || + y_red == PNG_FIXED_ERROR || + x_green == PNG_FIXED_ERROR || + y_green == PNG_FIXED_ERROR || + x_blue == PNG_FIXED_ERROR || + y_blue == PNG_FIXED_ERROR) + { + png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); + return; + } + +#ifdef PNG_READ_sRGB_SUPPORTED + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(x_red, 64000, 1000) || + PNG_OUT_OF_RANGE(y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(y_green, 60000, 1000) || + PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); + png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); + png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); + png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); + png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); + png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); + png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); + + png_formatted_warning(png_ptr, p, + "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " + "when sRGB is also present"); + } + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Store the _white values as default coefficients for the rgb to gray + * operation if it is supported. Check if the transform is already set to + * avoid destroying the transform values. + */ + if (!png_ptr->rgb_to_gray_coefficients_set) + { + /* png_set_background has not been called and we haven't seen an sRGB + * chunk yet. Find the XYZ of the three end points. + */ + png_XYZ XYZ; + png_xy xy; + + xy.redx = x_red; + xy.redy = y_red; + xy.greenx = x_green; + xy.greeny = y_green; + xy.bluex = x_blue; + xy.bluey = y_blue; + xy.whitex = x_white; + xy.whitey = y_white; + + if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) + { + /* The success case, because XYZ_from_xy normalises to a reference + * white Y of 1.0 we just need to scale the numbers. This should + * always work just fine. It is an internal error if this overflows. + */ + { + png_fixed_point r, g, b; + if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) && + r >= 0 && r <= 32768 && + png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) && + g >= 0 && g <= 32768 && + png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) && + b >= 0 && b <= 32768 && + r+g+b <= 32769) + { + /* We allow 0 coefficients here. r+g+b may be 32769 if two or + * all of the coefficients were rounded up. Handle this by + * reducing the *largest* coefficient by 1; this matches the + * approach used for the default coefficients in pngrtran.c + */ + int add = 0; + + if (r+g+b > 32768) + add = -1; + else if (r+g+b < 32768) + add = 1; + + if (add != 0) + { + if (g >= r && g >= b) + g += add; + else if (r >= g && r >= b) + r += add; + else + b += add; + } + + /* Check for an internal error. */ + if (r+g+b != 32768) + png_error(png_ptr, + "internal error handling cHRM coefficients"); + + png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; + png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; + } + + /* This is a png_error at present even though it could be ignored - + * it should never happen, but it is important that if it does, the + * bug is fixed. + */ + else + png_error(png_ptr, "internal error handling cHRM->XYZ"); + } + } + } +#endif + + png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, + x_green, y_green, x_blue, y_blue); +} +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED +void /* PRIVATE */ +png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + int intent; + png_byte buf[1]; + + png_debug(1, "in png_handle_sRGB"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sRGB"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sRGB after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sRGB chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { + png_warning(png_ptr, "Duplicate sRGB chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 1) + { + png_warning(png_ptr, "Incorrect sRGB chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 1); + + if (png_crc_finish(png_ptr, 0)) + return; + + intent = buf[0]; + + /* Check for bad intent */ + if (intent >= PNG_sRGB_INTENT_LAST) + { + png_warning(png_ptr, "Unknown sRGB intent"); + return; + } + +#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) + { + if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, + info_ptr->gamma); + + png_formatted_warning(png_ptr, p, + "Ignoring incorrect gAMA value @1 when sRGB is also present"); + } + } +#endif /* PNG_READ_gAMA_SUPPORTED */ + +#ifdef PNG_READ_cHRM_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + } +#endif /* PNG_READ_cHRM_SUPPORTED */ + + /* This is recorded for use when handling the cHRM chunk above. An sRGB + * chunk unconditionally overwrites the coefficients for grayscale conversion + * too. + */ + png_ptr->is_sRGB = 1; + +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Don't overwrite user supplied values: */ + if (!png_ptr->rgb_to_gray_coefficients_set) + { + /* These numbers come from the sRGB specification (or, since one has to + * pay much money to get a copy, the wikipedia sRGB page) the + * chromaticity values quoted have been inverted to get the reverse + * transformation from RGB to XYZ and the 'Y' coefficients scaled by + * 32768 (then rounded). + * + * sRGB and ITU Rec-709 both truncate the values for the D65 white + * point to four digits and, even though it actually stores five + * digits, the PNG spec gives the truncated value. + * + * This means that when the chromaticities are converted back to XYZ + * end points we end up with (6968,23435,2366), which, as described in + * pngrtran.c, would overflow. If the five digit precision and up is + * used we get, instead: + * + * 6968*R + 23435*G + 2365*B + * + * (Notice that this rounds the blue coefficient down, rather than the + * choice used in pngrtran.c which is to round the green one down.) + */ + png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */ + png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */ + /* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */ + + /* The following keeps the cHRM chunk from destroying the + * coefficients again in the event that it follows the sRGB chunk. + */ + png_ptr->rgb_to_gray_coefficients_set = 1; + } +# endif + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_READ_iCCP_SUPPORTED +void /* PRIVATE */ +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_byte compression_type; + png_bytep pC; + png_charp profile; + png_uint_32 skip = 0; + png_uint_32 profile_size; + png_alloc_size_t profile_length; + png_size_t slength, prefix_length, data_length; + + png_debug(1, "in png_handle_iCCP"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iCCP"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid iCCP after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place iCCP chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) + { + png_warning(png_ptr, "Duplicate iCCP chunk"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "iCCP chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (profile = png_ptr->chunkdata; *profile; profile++) + /* Empty loop to find end of name */ ; + + ++profile; + + /* There should be at least one zero (the compression type byte) + * following the separator, and we should be on it + */ + if (profile >= png_ptr->chunkdata + slength - 1) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "Malformed iCCP chunk"); + return; + } + + /* Compression_type should always be zero */ + compression_type = *profile++; + + if (compression_type) + { + png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); + compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 + wrote nonzero) */ + } + + prefix_length = profile - png_ptr->chunkdata; + png_decompress_chunk(png_ptr, compression_type, + slength, prefix_length, &data_length); + + profile_length = data_length - prefix_length; + + if (prefix_length > data_length || profile_length < 4) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "Profile size field missing from iCCP chunk"); + return; + } + + /* Check the profile_size recorded in the first 32 bits of the ICC profile */ + pC = (png_bytep)(png_ptr->chunkdata + prefix_length); + profile_size = ((*(pC )) << 24) | + ((*(pC + 1)) << 16) | + ((*(pC + 2)) << 8) | + ((*(pC + 3)) ); + + /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, + * because profile_size is a 32 bit value. + */ + if (profile_size < profile_length) + profile_length = profile_size; + + /* And the following guarantees that profile_size == profile_length. */ + if (profile_size > profile_length) + { + PNG_WARNING_PARAMETERS(p) + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); + png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); + png_formatted_warning(png_ptr, p, + "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); + return; + } + + png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, + compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, + profile_size); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#ifdef PNG_READ_sPLT_SUPPORTED +void /* PRIVATE */ +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep entry_start; + png_sPLT_t new_palette; + png_sPLT_entryp pp; + png_uint_32 data_length; + int entry_size, i; + png_uint_32 skip = 0; + png_size_t slength; + png_uint_32 dl; + png_size_t max_dl; + + png_debug(1, "in png_handle_sPLT"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for sPLT"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sPLT"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sPLT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "sPLT chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + + /* WARNING: this may break if size_t is less than 32 bits; it is assumed + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a + * potential breakage point if the types in pngconf.h aren't exactly right. + */ + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; + entry_start++) + /* Empty loop to find end of name */ ; + + ++entry_start; + + /* A sample depth should follow the separator, and we should be on it */ + if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "malformed sPLT chunk"); + return; + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + /* This must fit in a png_uint_32 because it is derived from the original + * chunk data length (and use 'length', not 'slength' here for clarity - + * they are guaranteed to be the same, see the tests above.) + */ + data_length = length - (png_uint_32)(entry_start - + (png_bytep)png_ptr->chunkdata); + + /* Integrity-check the data length */ + if (data_length % entry_size) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + dl = (png_int_32)(data_length / entry_size); + max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); + + if (dl > max_dl) + { + png_warning(png_ptr, "sPLT chunk too long"); + return; + } + + new_palette.nentries = (png_int_32)(data_length / entry_size); + + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( + png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); + + if (new_palette.entries == NULL) + { + png_warning(png_ptr, "sPLT chunk requires too much memory"); + return; + } + +#ifdef PNG_POINTER_INDEXING_SUPPORTED + for (i = 0; i < new_palette.nentries; i++) + { + pp = new_palette.entries + i; + + if (new_palette.depth == 8) + { + pp->red = *entry_start++; + pp->green = *entry_start++; + pp->blue = *entry_start++; + pp->alpha = *entry_start++; + } + + else + { + pp->red = png_get_uint_16(entry_start); entry_start += 2; + pp->green = png_get_uint_16(entry_start); entry_start += 2; + pp->blue = png_get_uint_16(entry_start); entry_start += 2; + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; + } + + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#else + pp = new_palette.entries; + + for (i = 0; i < new_palette.nentries; i++) + { + + if (new_palette.depth == 8) + { + pp[i].red = *entry_start++; + pp[i].green = *entry_start++; + pp[i].blue = *entry_start++; + pp[i].alpha = *entry_start++; + } + + else + { + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; + } + + pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#endif + + /* Discard all chunk data except the name and stash that */ + new_palette.name = png_ptr->chunkdata; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#ifdef PNG_READ_tRNS_SUPPORTED +void /* PRIVATE */ +png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_tRNS"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tRNS"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid tRNS after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_warning(png_ptr, "Duplicate tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + png_byte buf[2]; + + if (length != 2) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 2); + png_ptr->num_trans = 1; + png_ptr->trans_color.gray = png_get_uint_16(buf); + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_byte buf[6]; + + if (length != 6) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, (png_size_t)length); + png_ptr->num_trans = 1; + png_ptr->trans_color.red = png_get_uint_16(buf); + png_ptr->trans_color.green = png_get_uint_16(buf + 2); + png_ptr->trans_color.blue = png_get_uint_16(buf + 4); + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + /* Should be an error, but we can cope with it. */ + png_warning(png_ptr, "Missing PLTE before tRNS"); + } + + if (length > (png_uint_32)png_ptr->num_palette || + length > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + if (length == 0) + { + png_warning(png_ptr, "Zero length tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, readbuf, (png_size_t)length); + png_ptr->num_trans = (png_uint_16)length; + } + + else + { + png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_crc_finish(png_ptr, 0)) + { + png_ptr->num_trans = 0; + return; + } + + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_color)); +} +#endif + +#ifdef PNG_READ_bKGD_SUPPORTED +void /* PRIVATE */ +png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[6]; + png_color_16 background; + + png_debug(1, "in png_handle_bKGD"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before bKGD"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid bKGD after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before bKGD"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) + { + png_warning(png_ptr, "Duplicate bKGD chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 1; + + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + truelen = 6; + + else + truelen = 2; + + if (length != truelen) + { + png_warning(png_ptr, "Incorrect bKGD chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + + if (png_crc_finish(png_ptr, 0)) + return; + + /* We convert the index value into RGB components so that we can allow + * arbitrary RGB values for background when we have transparency, and + * so it is easy to determine the RGB values of the background color + * from the info_ptr struct. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + background.index = buf[0]; + + if (info_ptr && info_ptr->num_palette) + { + if (buf[0] >= info_ptr->num_palette) + { + png_warning(png_ptr, "Incorrect bKGD chunk index value"); + return; + } + + background.red = (png_uint_16)png_ptr->palette[buf[0]].red; + background.green = (png_uint_16)png_ptr->palette[buf[0]].green; + background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; + } + + else + background.red = background.green = background.blue = 0; + + background.gray = 0; + } + + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ + { + background.index = 0; + background.red = + background.green = + background.blue = + background.gray = png_get_uint_16(buf); + } + + else + { + background.index = 0; + background.red = png_get_uint_16(buf); + background.green = png_get_uint_16(buf + 2); + background.blue = png_get_uint_16(buf + 4); + background.gray = 0; + } + + png_set_bKGD(png_ptr, info_ptr, &background); +} +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +void /* PRIVATE */ +png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + unsigned int num, i; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_hIST"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before hIST"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid hIST after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before hIST"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) + { + png_warning(png_ptr, "Duplicate hIST chunk"); + png_crc_finish(png_ptr, length); + return; + } + + num = length / 2 ; + + if (num != (unsigned int)png_ptr->num_palette || num > + (unsigned int)PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect hIST chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + for (i = 0; i < num; i++) + { + png_byte buf[2]; + + png_crc_read(png_ptr, buf, 2); + readbuf[i] = png_get_uint_16(buf); + } + + if (png_crc_finish(png_ptr, 0)) + return; + + png_set_hIST(png_ptr, info_ptr, readbuf); +} +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +void /* PRIVATE */ +png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_uint_32 res_x, res_y; + int unit_type; + + png_debug(1, "in png_handle_pHYs"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pHYs"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pHYs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_warning(png_ptr, "Duplicate pHYs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect pHYs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + + if (png_crc_finish(png_ptr, 0)) + return; + + res_x = png_get_uint_32(buf); + res_y = png_get_uint_32(buf + 4); + unit_type = buf[8]; + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); +} +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +void /* PRIVATE */ +png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_int_32 offset_x, offset_y; + int unit_type; + + png_debug(1, "in png_handle_oFFs"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before oFFs"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid oFFs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_warning(png_ptr, "Duplicate oFFs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect oFFs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + + if (png_crc_finish(png_ptr, 0)) + return; + + offset_x = png_get_int_32(buf); + offset_y = png_get_int_32(buf + 4); + unit_type = buf[8]; + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); +} +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +/* Read the pCAL chunk (described in the PNG Extensions document) */ +void /* PRIVATE */ +png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_int_32 X0, X1; + png_byte type, nparams; + png_charp buf, units, endptr; + png_charpp params; + png_size_t slength; + int i; + + png_debug(1, "in png_handle_pCAL"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pCAL"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) + { + png_warning(png_ptr, "Duplicate pCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", + length + 1); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory for pCAL purpose"); + return; + } + + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string"); + for (buf = png_ptr->chunkdata; *buf; buf++) + /* Empty loop */ ; + + endptr = png_ptr->chunkdata + slength; + + /* We need to have at least 12 bytes after the purpose string + * in order to get the parameter information. + */ + if (endptr <= buf + 12) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); + X0 = png_get_int_32((png_bytep)buf+1); + X1 = png_get_int_32((png_bytep)buf+5); + type = buf[9]; + nparams = buf[10]; + units = buf + 11; + + png_debug(3, "Checking pCAL equation type and number of parameters"); + /* Check that we have the right number of parameters for known + * equation types. + */ + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || + (type == PNG_EQUATION_BASE_E && nparams != 3) || + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) + { + png_warning(png_ptr, "Invalid pCAL parameters for equation type"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + else if (type >= PNG_EQUATION_LAST) + { + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + } + + for (buf = units; *buf; buf++) + /* Empty loop to move past the units string. */ ; + + png_debug(3, "Allocating pCAL parameters array"); + + params = (png_charpp)png_malloc_warn(png_ptr, + (png_size_t)(nparams * png_sizeof(png_charp))); + + if (params == NULL) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "No memory for pCAL params"); + return; + } + + /* Get pointers to the start of each parameter string. */ + for (i = 0; i < (int)nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d", i); + + for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, params); + return; + } + } + + png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, + units, params); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, params); +} +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +/* Read the sCAL chunk */ +void /* PRIVATE */ +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t slength, i; + int state; + + png_debug(1, "in png_handle_sCAL"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sCAL"); + + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) + { + png_warning(png_ptr, "Duplicate sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + /* Need unit type, width, \0, height: minimum 4 bytes */ + else if (length < 4) + { + png_warning(png_ptr, "sCAL chunk too short"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", + length + 1); + + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + /* Validate the unit. */ + if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) + { + png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + /* Validate the ASCII numbers, need two ASCII numbers separated by + * a '\0' and they need to fit exactly in the chunk data. + */ + i = 1; + state = 0; + + if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || + i >= slength || png_ptr->chunkdata[i++] != 0) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); + + else + { + png_size_t heighti = i; + + state = 0; + if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || + i != slength) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + + else if (!PNG_FP_IS_POSITIVE(state)) + png_warning(png_ptr, + "Invalid sCAL chunk ignored: non-positive height"); + + else + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], + png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); + } + + /* Clean up - just free the temporarily allocated buffer. */ + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; +} +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +void /* PRIVATE */ +png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[7]; + png_time mod_time; + + png_debug(1, "in png_handle_tIME"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Out of place tIME chunk"); + + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) + { + png_warning(png_ptr, "Duplicate tIME chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + if (length != 7) + { + png_warning(png_ptr, "Incorrect tIME chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 7); + + if (png_crc_finish(png_ptr, 0)) + return; + + mod_time.second = buf[6]; + mod_time.minute = buf[5]; + mod_time.hour = buf[4]; + mod_time.day = buf[3]; + mod_time.month = buf[2]; + mod_time.year = png_get_uint_16(buf); + + png_set_tIME(png_ptr, info_ptr, &mod_time); +} +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +/* Note: this does not properly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp key; + png_charp text; + png_uint_32 skip = 0; + png_size_t slength; + int ret; + + png_debug(1, "in png_handle_tEXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for tEXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tEXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_free(png_ptr, png_ptr->chunkdata); + + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process text chunk"); + return; + } + + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + key = png_ptr->chunkdata; + + key[slength] = 0x00; + + for (text = key; *text; text++) + /* Empty loop to find end of key */ ; + + if (text != key + slength) + text++; + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + png_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process text chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; + text_ptr->text = text; + text_ptr->text_length = png_strlen(text); + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to process text chunk"); +} +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +/* Note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp text; + int comp_type; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_zTXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for zTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before zTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + * there is no hard and fast rule to tell us where to stop. + */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "Out of memory processing zTXt chunk"); + return; + } + + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (text = png_ptr->chunkdata; *text; text++) + /* Empty loop */ ; + + /* zTXt must have some text after the chunkdataword */ + if (text >= png_ptr->chunkdata + slength - 2) + { + png_warning(png_ptr, "Truncated zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + else + { + comp_type = *(++text); + + if (comp_type != PNG_TEXT_COMPRESSION_zTXt) + { + png_warning(png_ptr, "Unknown compression type in zTXt chunk"); + comp_type = PNG_TEXT_COMPRESSION_zTXt; + } + + text++; /* Skip the compression_method byte */ + } + + prefix_len = text - png_ptr->chunkdata; + + png_decompress_chunk(png_ptr, comp_type, + (png_size_t)length, prefix_len, &data_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + png_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = comp_type; + text_ptr->key = png_ptr->chunkdata; + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; + text_ptr->text = png_ptr->chunkdata + prefix_len; + text_ptr->text_length = data_len; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + if (ret) + png_error(png_ptr, "Insufficient memory to store zTXt chunk"); +} +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED +/* Note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp key, lang, text, lang_key; + int comp_flag; + int comp_type = 0; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_iTXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for iTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + * there is no hard and fast rule to tell us where to stop. + */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + + if (png_ptr->chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process iTXt chunk"); + return; + } + + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + png_ptr->chunkdata[slength] = 0x00; + + for (lang = png_ptr->chunkdata; *lang; lang++) + /* Empty loop */ ; + + lang++; /* Skip NUL separator */ + + /* iTXt must have a language tag (possibly empty), two compression bytes, + * translated keyword (possibly empty), and possibly some text after the + * keyword + */ + + if (lang >= png_ptr->chunkdata + slength - 3) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + else + { + comp_flag = *lang++; + comp_type = *lang++; + } + + if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt)) + { + png_warning(png_ptr, "Unknown iTXt compression type or method"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + for (lang_key = lang; *lang_key; lang_key++) + /* Empty loop */ ; + + lang_key++; /* Skip NUL separator */ + + if (lang_key >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + for (text = lang_key; *text; text++) + /* Empty loop */ ; + + text++; /* Skip NUL separator */ + + if (text >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Malformed iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + prefix_len = text - png_ptr->chunkdata; + + key=png_ptr->chunkdata; + + if (comp_flag) + png_decompress_chunk(png_ptr, comp_type, + (size_t)length, prefix_len, &data_len); + + else + data_len = png_strlen(png_ptr->chunkdata + prefix_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + png_sizeof(png_text)); + + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + + text_ptr->compression = (int)comp_flag + 1; + text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); + text_ptr->lang = png_ptr->chunkdata + (lang - key); + text_ptr->itxt_length = data_len; + text_ptr->text_length = 0; + text_ptr->key = png_ptr->chunkdata; + text_ptr->text = png_ptr->chunkdata + prefix_len; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + + if (ret) + png_error(png_ptr, "Insufficient memory to store iTXt chunk"); +} +#endif + +/* This function is called when we haven't found a handler for a + * chunk. If there isn't a problem with the chunk itself (ie bad + * chunk name, CRC, or a critical chunk), the chunk is silently ignored + * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which + * case it will be saved away to be written out later. + */ +void /* PRIVATE */ +png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_uint_32 skip = 0; + + png_debug(1, "in png_handle_unknown"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for unknown chunk"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif + + if (png_ptr->mode & PNG_HAVE_IDAT) + { + if (png_ptr->chunk_name != png_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + } + + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + { +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + || (png_ptr->read_user_chunk_fn != NULL) +#endif + ) + { +#ifdef PNG_MAX_MALLOC_64K + if (length > 65535) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - 65535; + length = 65535; + } +#endif + + /* TODO: this code is very close to the unknown handling in pngpread.c, + * maybe it can be put into a common utility routine? + * png_struct::unknown_chunk is just used as a temporary variable, along + * with the data into which the chunk is read. These can be eliminated. + */ + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + png_ptr->unknown_chunk.size = (png_size_t)length; + + if (length == 0) + png_ptr->unknown_chunk.data = NULL; + + else + { + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); + } + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + if (png_ptr->read_user_chunk_fn != NULL) + { + /* Callback to user unknown chunk handler */ + int ret; + + ret = (*(png_ptr->read_user_chunk_fn)) + (png_ptr, &png_ptr->unknown_chunk); + + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + if (ret == 0) + { + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + { +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } + + else +#endif + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + + else +#endif + skip = length; + + png_crc_finish(png_ptr, skip); + +#ifndef PNG_READ_USER_CHUNKS_SUPPORTED + PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ +#endif +} + +/* This function is called to verify that a chunk name is valid. + * This function can't have the "critical chunk check" incorporated + * into it, since in the future we will need to be able to call user + * functions to handle unknown critical chunks after we check that + * the chunk name itself is valid. + */ + +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: + * + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + */ + +void /* PRIVATE */ +png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) +{ + int i; + + png_debug(1, "in png_check_chunk_name"); + + for (i=1; i<=4; ++i) + { + int c = chunk_name & 0xff; + + if (c < 65 || c > 122 || (c > 90 && c < 97)) + png_chunk_error(png_ptr, "invalid chunk type"); + + chunk_name >>= 8; + } +} + +/* Combines the row recently read in with the existing pixels in the row. This + * routine takes care of alpha and transparency if requested. This routine also + * handles the two methods of progressive display of interlaced images, + * depending on the 'display' value; if 'display' is true then the whole row + * (dp) is filled from the start by replicating the available pixels. If + * 'display' is false only those pixels present in the pass are filled in. + */ +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep dp, int display) +{ + unsigned int pixel_depth = png_ptr->transformed_pixel_depth; + png_const_bytep sp = png_ptr->row_buf + 1; + png_uint_32 row_width = png_ptr->width; + unsigned int pass = png_ptr->pass; + png_bytep end_ptr = 0; + png_byte end_byte = 0; + unsigned int end_mask; + + png_debug(1, "in png_combine_row"); + + /* Added in 1.5.6: it should not be possible to enter this routine until at + * least one row has been read from the PNG data and transformed. + */ + if (pixel_depth == 0) + png_error(png_ptr, "internal row logic error"); + + /* Added in 1.5.4: the pixel depth should match the information returned by + * any call to png_read_update_info at this point. Do not continue if we got + * this wrong. + */ + if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != + PNG_ROWBYTES(pixel_depth, row_width)) + png_error(png_ptr, "internal row size calculation error"); + + /* Don't expect this to ever happen: */ + if (row_width == 0) + png_error(png_ptr, "internal row width error"); + + /* Preserve the last byte in cases where only part of it will be overwritten, + * the multiply below may overflow, we don't care because ANSI-C guarantees + * we get the low bits. + */ + end_mask = (pixel_depth * row_width) & 7; + if (end_mask != 0) + { + /* end_ptr == NULL is a flag to say do nothing */ + end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; + end_byte = *end_ptr; +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */ + end_mask = 0xff << end_mask; + + else /* big-endian byte */ +# endif + end_mask = 0xff >> end_mask; + /* end_mask is now the bits to *keep* from the destination row */ + } + + /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy() + * will also happen if interlacing isn't supported or if the application + * does not call png_set_interlace_handling(). In the latter cases the + * caller just gets a sequence of the unexpanded rows from each interlace + * pass. + */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) && + pass < 6 && (display == 0 || + /* The following copies everything for 'display' on passes 0, 2 and 4. */ + (display == 1 && (pass & 1) != 0))) + { + /* Narrow images may have no bits in a pass; the caller should handle + * this, but this test is cheap: + */ + if (row_width <= PNG_PASS_START_COL(pass)) + return; + + if (pixel_depth < 8) + { + /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit + * into 32 bits, then a single loop over the bytes using the four byte + * values in the 32-bit mask can be used. For the 'display' option the + * expanded mask may also not require any masking within a byte. To + * make this work the PACKSWAP option must be taken into account - it + * simply requires the pixels to be reversed in each byte. + * + * The 'regular' case requires a mask for each of the first 6 passes, + * the 'display' case does a copy for the even passes in the range + * 0..6. This has already been handled in the test above. + * + * The masks are arranged as four bytes with the first byte to use in + * the lowest bits (little-endian) regardless of the order (PACKSWAP or + * not) of the pixels in each byte. + * + * NOTE: the whole of this logic depends on the caller of this function + * only calling it on rows appropriate to the pass. This function only + * understands the 'x' logic; the 'y' logic is handled by the caller. + * + * The following defines allow generation of compile time constant bit + * masks for each pixel depth and each possibility of swapped or not + * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, + * is in the range 0..7; and the result is 1 if the pixel is to be + * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' + * for the block method. + * + * With some compilers a compile time expression of the general form: + * + * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) + * + * Produces warnings with values of 'shift' in the range 33 to 63 + * because the right hand side of the ?: expression is evaluated by + * the compiler even though it isn't used. Microsoft Visual C (various + * versions) and the Intel C compiler are known to do this. To avoid + * this the following macros are used in 1.5.6. This is a temporary + * solution to avoid destabilizing the code during the release process. + */ +# if PNG_USE_COMPILE_TIME_MASKS +# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) +# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) +# else +# define PNG_LSR(x,s) ((x)>>(s)) +# define PNG_LSL(x,s) ((x)<<(s)) +# endif +# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) +# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) + + /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is + * little endian - the first pixel is at bit 0 - however the extra + * parameter 's' can be set to cause the mask position to be swapped + * within each byte, to match the PNG format. This is done by XOR of + * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. + */ +# define PIXEL_MASK(p,x,d,s) \ + (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) + + /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. + */ +# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) +# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) + + /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp + * cases the result needs replicating, for the 4-bpp case the above + * generates a full 32 bits. + */ +# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) + +# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ + S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ + S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) + +# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ + B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ + B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) + +#if PNG_USE_COMPILE_TIME_MASKS + /* Utility macros to construct all the masks for a depth/swap + * combination. The 's' parameter says whether the format is PNG + * (big endian bytes) or not. Only the three odd-numbered passes are + * required for the display/block algorithm. + */ +# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ + S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } + +# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) } + +# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) + + /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and + * then pass: + */ + static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + { + /* Little-endian byte masks for PACKSWAP */ + { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } + }; + + /* display_mask has only three entries for the odd passes, so index by + * pass>>1. + */ + static PNG_CONST png_uint_32 display_mask[2][3][3] = + { + /* Little-endian byte masks for PACKSWAP */ + { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } + }; + +# define MASK(pass,depth,display,png)\ + ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ + row_mask[png][DEPTH_INDEX(depth)][pass]) + +#else /* !PNG_USE_COMPILE_TIME_MASKS */ + /* This is the runtime alternative: it seems unlikely that this will + * ever be either smaller or faster than the compile time approach. + */ +# define MASK(pass,depth,display,png)\ + ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) +#endif /* !PNG_USE_COMPILE_TIME_MASKS */ + + /* Use the appropriate mask to copy the required bits. In some cases + * the byte mask will be 0 or 0xff, optimize these cases. row_width is + * the number of pixels, but the code copies bytes, so it is necessary + * to special case the end. + */ + png_uint_32 pixels_per_byte = 8 / pixel_depth; + png_uint_32 mask; + +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + mask = MASK(pass, pixel_depth, display, 0); + + else +# endif + mask = MASK(pass, pixel_depth, display, 1); + + for (;;) + { + png_uint_32 m; + + /* It doesn't matter in the following if png_uint_32 has more than + * 32 bits because the high bits always match those in m<<24; it is, + * however, essential to use OR here, not +, because of this. + */ + m = mask; + mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ + m &= 0xff; + + if (m != 0) /* something to copy */ + { + if (m != 0xff) + *dp = (png_byte)((*dp & ~m) | (*sp & m)); + else + *dp = *sp; + } + + /* NOTE: this may overwrite the last byte with garbage if the image + * is not an exact number of bytes wide; libpng has always done + * this. + */ + if (row_width <= pixels_per_byte) + break; /* May need to restore part of the last byte */ + + row_width -= pixels_per_byte; + ++dp; + ++sp; + } + } + + else /* pixel_depth >= 8 */ + { + unsigned int bytes_to_copy, bytes_to_jump; + + /* Validate the depth - it must be a multiple of 8 */ + if (pixel_depth & 7) + png_error(png_ptr, "invalid user transform pixel depth"); + + pixel_depth >>= 3; /* now in bytes */ + row_width *= pixel_depth; + + /* Regardless of pass number the Adam 7 interlace always results in a + * fixed number of pixels to copy then to skip. There may be a + * different number of pixels to skip at the start though. + */ + { + unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; + + row_width -= offset; + dp += offset; + sp += offset; + } + + /* Work out the bytes to copy. */ + if (display) + { + /* When doing the 'block' algorithm the pixel in the pass gets + * replicated to adjacent pixels. This is why the even (0,2,4,6) + * passes are skipped above - the entire expanded row is copied. + */ + bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; + + /* But don't allow this number to exceed the actual row width. */ + if (bytes_to_copy > row_width) + bytes_to_copy = row_width; + } + + else /* normal row; Adam7 only ever gives us one pixel to copy. */ + bytes_to_copy = pixel_depth; + + /* In Adam7 there is a constant offset between where the pixels go. */ + bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; + + /* And simply copy these bytes. Some optimization is possible here, + * depending on the value of 'bytes_to_copy'. Special case the low + * byte counts, which we know to be frequent. + * + * Notice that these cases all 'return' rather than 'break' - this + * avoids an unnecessary test on whether to restore the last byte + * below. + */ + switch (bytes_to_copy) + { + case 1: + for (;;) + { + *dp = *sp; + + if (row_width <= bytes_to_jump) + return; + + dp += bytes_to_jump; + sp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + case 2: + /* There is a possibility of a partial copy at the end here; this + * slows the code down somewhat. + */ + do + { + dp[0] = sp[0], dp[1] = sp[1]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + while (row_width > 1); + + /* And there can only be one byte left at this point: */ + *dp = *sp; + return; + + case 3: + /* This can only be the RGB case, so each copy is exactly one + * pixel and it is not necessary to check for a partial copy. + */ + for(;;) + { + dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + default: +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE + /* Check for double byte alignment and, if possible, use a + * 16-bit copy. Don't attempt this for narrow images - ones that + * are less than an interlace panel wide. Don't attempt it for + * wide bytes_to_copy either - use the png_memcpy there. + */ + if (bytes_to_copy < 16 /*else use png_memcpy*/ && + png_isaligned(dp, png_uint_16) && + png_isaligned(sp, png_uint_16) && + bytes_to_copy % sizeof (png_uint_16) == 0 && + bytes_to_jump % sizeof (png_uint_16) == 0) + { + /* Everything is aligned for png_uint_16 copies, but try for + * png_uint_32 first. + */ + if (png_isaligned(dp, png_uint_32) && + png_isaligned(sp, png_uint_32) && + bytes_to_copy % sizeof (png_uint_32) == 0 && + bytes_to_jump % sizeof (png_uint_32) == 0) + { + png_uint_32p dp32 = (png_uint_32p)dp; + png_const_uint_32p sp32 = (png_const_uint_32p)sp; + unsigned int skip = (bytes_to_jump-bytes_to_copy) / + sizeof (png_uint_32); + + do + { + size_t c = bytes_to_copy; + do + { + *dp32++ = *sp32++; + c -= sizeof (png_uint_32); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp32 += skip; + sp32 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* Get to here when the row_width truncates the final copy. + * There will be 1-3 bytes left to copy, so don't try the + * 16-bit loop below. + */ + dp = (png_bytep)dp32; + sp = (png_const_bytep)sp32; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + + /* Else do it in 16-bit quantities, but only if the size is + * not too large. + */ + else + { + png_uint_16p dp16 = (png_uint_16p)dp; + png_const_uint_16p sp16 = (png_const_uint_16p)sp; + unsigned int skip = (bytes_to_jump-bytes_to_copy) / + sizeof (png_uint_16); + + do + { + size_t c = bytes_to_copy; + do + { + *dp16++ = *sp16++; + c -= sizeof (png_uint_16); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp16 += skip; + sp16 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* End of row - 1 byte left, bytes_to_copy > row_width: */ + dp = (png_bytep)dp16; + sp = (png_const_bytep)sp16; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + } +#endif /* PNG_ALIGN_ code */ + + /* The true default - use a png_memcpy: */ + for (;;) + { + png_memcpy(dp, sp, bytes_to_copy); + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + if (bytes_to_copy > row_width) + bytes_to_copy = row_width; + } + } + + /* NOT REACHED*/ + } /* pixel_depth >= 8 */ + + /* Here if pixel_depth < 8 to check 'end_ptr' below. */ + } + else +#endif + + /* If here then the switch above wasn't used so just png_memcpy the whole row + * from the temporary row buffer (notice that this overwrites the end of the + * destination row if it is a partial byte.) + */ + png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); + + /* Restore the overwritten bits from the last byte if necessary. */ + if (end_ptr != NULL) + *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void /* PRIVATE */ +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations /* Because these may affect the byte layout */) +{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Offset to next interlace block */ + static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_read_interlace"); + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_byte v; + png_uint_32 i; + int j; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 0x07); + dshift = (int)((final_width + 7) & 0x07); + s_start = 7; + s_end = 0; + s_inc = -1; + } + + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 0x07); + dshift = 7 - (int)((final_width + 7) & 0x07); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = 0; i < row_info->width; i++) + { + v = (png_byte)((*sp >> sshift) & 0x01); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift += s_inc; + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift += s_inc; + } + break; + } + + case 2: + { + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_uint_32 i; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 3) & 0x03) << 1); + dshift = (int)(((final_width + 3) & 0x03) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + + else +#endif + { + sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); + dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x03); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift += s_inc; + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift += s_inc; + } + break; + } + + case 4: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + int jstop = png_pass_inc[pass]; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 1) & 0x01) << 2); + dshift = (int)(((final_width + 1) & 0x01) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + + else +#endif + { + sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); + dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v = (png_byte)((*sp >> sshift) & 0x0f); + int j; + + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift += s_inc; + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift += s_inc; + } + break; + } + + default: + { + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); + + png_bytep sp = row + (png_size_t)(row_info->width - 1) + * pixel_bytes; + + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; + + int jstop = png_pass_inc[pass]; + png_uint_32 i; + + for (i = 0; i < row_info->width; i++) + { + png_byte v[8]; + int j; + + png_memcpy(v, sp, pixel_bytes); + + for (j = 0; j < jstop; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + + sp -= pixel_bytes; + } + break; + } + } + + row_info->width = final_width; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); + } +#ifndef PNG_READ_PACKSWAP_SUPPORTED + PNG_UNUSED(transformations) /* Silence compiler warning */ +#endif +} +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +static void +png_read_filter_row_sub(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + + PNG_UNUSED(prev_row) + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_up(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + png_bytep rp = row; + png_const_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_avg(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_bytep rp = row; + png_const_bytep pp = prev_row; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +static void +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp_end = row + row_info->rowbytes; + int a, c; + + /* First pixel/byte */ + c = *prev_row++; + a = *row + c; + *row++ = (png_byte)a; + + /* Remainder */ + while (row < rp_end) + { + int b, pa, pb, pc, p; + + a &= 0xff; /* From previous iteration or start */ + b = *prev_row++; + + p = b - c; + pc = a - c; + +# ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +# else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +# endif + + /* Find the best predictor, the least of pa, pb, pc favoring the earlier + * ones in the case of a tie. + */ + if (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + /* Calculate the current pixel in a, and move the previous row pixel to c + * for the next time round the loop + */ + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp_end = row + bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + while (row < rp_end) + { + int a = *row + *prev_row++; + *row++ = (png_byte)a; + } + + /* Remainder */ + rp_end += row_info->rowbytes - bpp; + + while (row < rp_end) + { + int a, b, c, pa, pb, pc, p; + + c = *(prev_row - bpp); + a = *(row - bpp); + b = *prev_row++; + + p = b - c; + pc = a - c; + +# ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +# else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +# endif + + if (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +#ifdef PNG_ARM_NEON + +#ifdef __linux__ +#include +#include +#include + +static int png_have_hwcap(unsigned cap) +{ + FILE *f = fopen("/proc/self/auxv", "r"); + Elf32_auxv_t aux; + int have_cap = 0; + + if (!f) + return 0; + + while (fread(&aux, sizeof(aux), 1, f) > 0) + { + if (aux.a_type == AT_HWCAP && + aux.a_un.a_val & cap) + { + have_cap = 1; + break; + } + } + + fclose(f); + + return have_cap; +} +#endif /* __linux__ */ + +static void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ +#ifdef __linux__ + if (!png_have_hwcap(HWCAP_NEON)) + return; +#endif + + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_neon; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; + } +} +#endif /* PNG_ARM_NEON */ + +static void +png_init_filter_functions(png_structp pp) +{ + unsigned int bpp = (pp->pixel_depth + 7) >> 3; + + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; + if (bpp == 1) + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_1byte_pixel; + else + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_multibyte_pixel; + +#ifdef PNG_ARM_NEON + png_init_filter_functions_neon(pp, bpp); +#endif +} + +void /* PRIVATE */ +png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) +{ + if (pp->read_filter[0] == NULL) + png_init_filter_functions(pp); + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) + pp->read_filter[filter-1](row_info, row, prev_row); +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void /* PRIVATE */ +png_read_finish_row(png_structp png_ptr) +{ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + png_debug(1, "in png_read_finish_row"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + + /* TO DO: don't do this if prev_row isn't needed (requires + * read-ahead of the next row's filter byte. + */ + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { + png_ptr->pass++; + + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + } + + else /* if (png_ptr->transformations & PNG_INTERLACE) */ + break; /* libpng deinterlacing sees every row */ + + } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); + + if (png_ptr->pass < 7) + return; + } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { + char extra; + int ret; + + png_ptr->zstream.next_out = (Byte *)&extra; + png_ptr->zstream.avail_out = (uInt)1; + + for (;;) + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_crc_finish(png_ptr, 0); + png_ptr->idat_size = png_read_chunk_header(png_ptr); + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } + + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + + if (ret == Z_STREAM_END) + { + if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_warning(png_ptr, "Extra compressed data"); + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression Error"); + + if (!(png_ptr->zstream.avail_out)) + { + png_warning(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + + } + png_ptr->zstream.avail_out = 0; + } + + if (png_ptr->idat_size || png_ptr->zstream.avail_in) + png_warning(png_ptr, "Extra compression data"); + + inflateReset(&png_ptr->zstream); + + png_ptr->mode |= PNG_AFTER_IDAT; +} +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ + +void /* PRIVATE */ +png_read_start_row(png_structp png_ptr) +{ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int max_pixel_depth; + png_size_t row_bytes; + + png_debug(1, "in png_read_start_row"); + png_ptr->zstream.avail_in = 0; +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_init_read_transformations(png_ptr); +#endif +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + + else + png_ptr->num_rows = png_ptr->height; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + } + + else +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; + } + + max_pixel_depth = png_ptr->pixel_depth; + + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of + * calculations to calculate the final pixel depth, then + * png_do_read_transforms actually does the transforms. This means that the + * code which effectively calculates this value is actually repeated in three + * separate places. They must all match. Innocent changes to the order of + * transformations can and will break libpng in a way that causes memory + * overwrites. + * + * TODO: fix this. + */ +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) + max_pixel_depth = 8; +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans) + max_pixel_depth = 32; + + else + max_pixel_depth = 24; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth < 8) + max_pixel_depth = 8; + + if (png_ptr->num_trans) + max_pixel_depth *= 2; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (png_ptr->num_trans) + { + max_pixel_depth *= 4; + max_pixel_depth /= 3; + } + } + } +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if (png_ptr->transformations & PNG_EXPAND_16) + { +# ifdef PNG_READ_EXPAND_SUPPORTED + /* In fact it is an error if it isn't supported, but checking is + * the safe way. + */ + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->bit_depth < 16) + max_pixel_depth *= 2; + } + else +# endif + png_ptr->transformations &= ~PNG_EXPAND_16; + } +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if (png_ptr->transformations & (PNG_FILLER)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth <= 8) + max_pixel_depth = 16; + + else + max_pixel_depth = 32; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; + + else + max_pixel_depth = 64; + } + } +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if ( +#ifdef PNG_READ_EXPAND_SUPPORTED + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || +#endif +#ifdef PNG_READ_FILLER_SUPPORTED + (png_ptr->transformations & (PNG_FILLER)) || +#endif + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (max_pixel_depth <= 16) + max_pixel_depth = 32; + + else + max_pixel_depth = 64; + } + + else + { + if (max_pixel_depth <= 8) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 32; + + else + max_pixel_depth = 24; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 64; + + else + max_pixel_depth = 48; + } + } +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + { + int user_pixel_depth = png_ptr->user_transform_depth * + png_ptr->user_transform_channels; + + if (user_pixel_depth > max_pixel_depth) + max_pixel_depth = user_pixel_depth; + } +#endif + + /* This value is stored in png_struct and double checked in the row read + * code. + */ + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ + + /* Align the width on the next larger 8 pixels. Mainly used + * for interlacing + */ + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); + /* Calculate the maximum bytes needed, adding a byte and a pixel + * for safety's sake + */ + row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + + 1 + ((max_pixel_depth + 7) >> 3); + +#ifdef PNG_MAX_MALLOC_64K + if (row_bytes > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) + { + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + + if (png_ptr->interlaced) + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); + + else + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED + /* Use 16-byte aligned memory for row_buf with at least 16 bytes + * of padding before and after row_buf; treat prev_row similarly. + * NOTE: the alignment is to the start of the pixels, one beyond the start + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this + * was incorrect; the filter byte was aligned, which had the exact + * opposite effect of that intended. + */ + { + png_bytep temp = png_ptr->big_row_buf + 32; + int extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->row_buf = temp - extra - 1/*filter byte*/; + + temp = png_ptr->big_prev_row + 32; + extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->prev_row = temp - extra - 1/*filter byte*/; + } + +#else + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ + png_ptr->row_buf = png_ptr->big_row_buf + 31; + png_ptr->prev_row = png_ptr->big_prev_row + 31; +#endif + png_ptr->old_big_row_buf_size = row_bytes + 48; + } + +#ifdef PNG_MAX_MALLOC_64K + if (png_ptr->rowbytes > 65535) + png_error(png_ptr, "This image requires a row greater than 64KB"); + +#endif + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory"); + + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %u,", png_ptr->width); + png_debug1(3, "height = %u,", png_ptr->height); + png_debug1(3, "iwidth = %u,", png_ptr->iwidth); + png_debug1(3, "num_rows = %u,", png_ptr->num_rows); + png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); + png_debug1(3, "irowbytes = %lu", + (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/WDL/libpng/pngset.c b/WDL/libpng/pngset.c new file mode 100644 index 00000000..e753ca88 --- /dev/null +++ b/WDL/libpng/pngset.c @@ -0,0 +1,1284 @@ + +/* pngset.c - storage of image information into info struct + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * The functions here are used during reads to store data from the file + * into the info struct, and during writes to store application data + * into the info struct for writing into the file. This abstracts the + * info struct and allows us to change the structure in the future. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#ifdef PNG_bKGD_SUPPORTED +void PNGAPI +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background) +{ + png_debug1(1, "in %s storage function", "bKGD"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); + info_ptr->valid |= PNG_INFO_bKGD; +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +void PNGFAPI +png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) +{ + png_debug1(1, "in %s storage function", "cHRM fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +# ifdef PNG_CHECK_cHRM_SUPPORTED + if (png_check_cHRM_fixed(png_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) +# endif + { + info_ptr->x_white = white_x; + info_ptr->y_white = white_y; + info_ptr->x_red = red_x; + info_ptr->y_red = red_y; + info_ptr->x_green = green_x; + info_ptr->y_green = green_y; + info_ptr->x_blue = blue_x; + info_ptr->y_blue = blue_y; + info_ptr->valid |= PNG_INFO_cHRM; + } +} + +void PNGFAPI +png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z) +{ + png_XYZ XYZ; + png_xy xy; + + png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + XYZ.redX = int_red_X; + XYZ.redY = int_red_Y; + XYZ.redZ = int_red_Z; + XYZ.greenX = int_green_X; + XYZ.greenY = int_green_Y; + XYZ.greenZ = int_green_Z; + XYZ.blueX = int_blue_X; + XYZ.blueY = int_blue_Y; + XYZ.blueZ = int_blue_Z; + + if (png_xy_from_XYZ(&xy, XYZ)) + png_error(png_ptr, "XYZ values out of representable range"); + + png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy, + xy.greenx, xy.greeny, xy.bluex, xy.bluey); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) +{ + png_set_cHRM_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); +} + +void PNGAPI +png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X, + double red_Y, double red_Z, double green_X, double green_Y, double green_Z, + double blue_X, double blue_Y, double blue_Z) +{ + png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Red X"), + png_fixed(png_ptr, green_Y, "cHRM Red Y"), + png_fixed(png_ptr, green_Z, "cHRM Red Z"), + png_fixed(png_ptr, blue_X, "cHRM Red X"), + png_fixed(png_ptr, blue_Y, "cHRM Red Y"), + png_fixed(png_ptr, blue_Z, "cHRM Red Z")); +} +# endif /* PNG_FLOATING_POINT_SUPPORTED */ + +#endif /* PNG_cHRM_SUPPORTED */ + +#ifdef PNG_gAMA_SUPPORTED +void PNGFAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + file_gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't + * occur. Since the fixed point representation is assymetrical it is + * possible for 1/gamma to overflow the limit of 21474 and this means the + * gamma value must be at least 5/100000 and hence at most 20000.0. For + * safety the limits here are a little narrower. The values are 0.00016 to + * 6250.0, which are truly ridiculous gammma values (and will produce + * displays that are all black or all white.) + */ + if (file_gamma < 16 || file_gamma > 625000000) + png_warning(png_ptr, "Out of range gamma value ignored"); + + else + { + info_ptr->gamma = file_gamma; + info_ptr->valid |= PNG_INFO_gAMA; + } +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) +{ + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); +} +# endif +#endif + +#ifdef PNG_hIST_SUPPORTED +void PNGAPI +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) +{ + int i; + + png_debug1(1, "in %s storage function", "hIST"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (info_ptr->num_palette == 0 || info_ptr->num_palette + > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, + "Invalid palette size, hIST allocation skipped"); + + return; + } + + png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); + + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in + * version 1.2.1 + */ + png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); + + if (png_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data"); + return; + } + + for (i = 0; i < info_ptr->num_palette; i++) + png_ptr->hist[i] = hist[i]; + + info_ptr->hist = png_ptr->hist; + info_ptr->valid |= PNG_INFO_hIST; + info_ptr->free_me |= PNG_FREE_HIST; +} +#endif + +void PNGAPI +png_set_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + png_debug1(1, "in %s storage function", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->width = width; + info_ptr->height = height; + info_ptr->bit_depth = (png_byte)bit_depth; + info_ptr->color_type = (png_byte)color_type; + info_ptr->compression_type = (png_byte)compression_type; + info_ptr->filter_type = (png_byte)filter_type; + info_ptr->interlace_type = (png_byte)interlace_type; + + png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); + + /* Check for potential overflow */ + if (width > + (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ + - 48 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + info_ptr->rowbytes = 0; + else + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); +} + +#ifdef PNG_oFFs_SUPPORTED +void PNGAPI +png_set_oFFs(png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type) +{ + png_debug1(1, "in %s storage function", "oFFs"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_offset = offset_x; + info_ptr->y_offset = offset_y; + info_ptr->offset_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_oFFs; +} +#endif + +#ifdef PNG_pCAL_SUPPORTED +void PNGAPI +png_set_pCAL(png_structp png_ptr, png_infop info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params) +{ + png_size_t length; + int i; + + png_debug1(1, "in %s storage function", "pCAL"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + length = png_strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)", + (unsigned long)length); + + /* TODO: validate format of calibration name and unit name */ + + /* Check that the type matches the specification. */ + if (type < 0 || type > 3) + png_error(png_ptr, "Invalid pCAL equation type"); + + /* Validate params[nparams] */ + for (i=0; ipcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + + if (info_ptr->pcal_purpose == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose"); + return; + } + + png_memcpy(info_ptr->pcal_purpose, purpose, length); + + png_debug(3, "storing X0, X1, type, and nparams in info"); + info_ptr->pcal_X0 = X0; + info_ptr->pcal_X1 = X1; + info_ptr->pcal_type = (png_byte)type; + info_ptr->pcal_nparams = (png_byte)nparams; + + length = png_strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)", + (unsigned long)length); + + info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units"); + return; + } + + png_memcpy(info_ptr->pcal_units, units, length); + + info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, + (png_size_t)((nparams + 1) * png_sizeof(png_charp))); + + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params"); + return; + } + + png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); + + for (i = 0; i < nparams; i++) + { + length = png_strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, + (unsigned long)length); + + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + + if (info_ptr->pcal_params[i] == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL parameter"); + return; + } + + png_memcpy(info_ptr->pcal_params[i], params[i], length); + } + + info_ptr->valid |= PNG_INFO_pCAL; + info_ptr->free_me |= PNG_FREE_PCAL; +} +#endif + +#ifdef PNG_sCAL_SUPPORTED +void PNGAPI +png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight) +{ + png_size_t lengthw = 0, lengthh = 0; + + png_debug1(1, "in %s storage function", "sCAL"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Double check the unit (should never get here with an invalid + * unit unless this is an API call.) + */ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + + if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || + swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || + sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + + info_ptr->scal_unit = (png_byte)unit; + + ++lengthw; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); + + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); + + if (info_ptr->scal_s_width == NULL) + { + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + return; + } + + png_memcpy(info_ptr->scal_s_width, swidth, lengthw); + + ++lengthh; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); + + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); + + if (info_ptr->scal_s_height == NULL) + { + png_free (png_ptr, info_ptr->scal_s_width); + info_ptr->scal_s_width = NULL; + + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + return; + } + + png_memcpy(info_ptr->scal_s_height, sheight, lengthh); + + info_ptr->valid |= PNG_INFO_sCAL; + info_ptr->free_me |= PNG_FREE_SCAL; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, + double height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, + PNG_sCAL_PRECISION); + png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, + png_fixed_point width, png_fixed_point height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); + png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif +#endif + +#ifdef PNG_pHYs_SUPPORTED +void PNGAPI +png_set_pHYs(png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type) +{ + png_debug1(1, "in %s storage function", "pHYs"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_pixels_per_unit = res_x; + info_ptr->y_pixels_per_unit = res_y; + info_ptr->phys_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_pHYs; +} +#endif + +void PNGAPI +png_set_PLTE(png_structp png_ptr, png_infop info_ptr, + png_const_colorp palette, int num_palette) +{ + + png_debug1(1, "in %s storage function", "PLTE"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Invalid palette length"); + + else + { + png_warning(png_ptr, "Invalid palette length"); + return; + } + } + + /* It may not actually be necessary to set png_ptr->palette here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); + + /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead + * of num_palette entries, in case of an invalid PNG file that has + * too-large sample values. + */ + png_ptr->palette = (png_colorp)png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + + png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); + info_ptr->palette = png_ptr->palette; + info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; + + info_ptr->free_me |= PNG_FREE_PLTE; + + info_ptr->valid |= PNG_INFO_PLTE; +} + +#ifdef PNG_sBIT_SUPPORTED +void PNGAPI +png_set_sBIT(png_structp png_ptr, png_infop info_ptr, + png_const_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function", "sBIT"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); + info_ptr->valid |= PNG_INFO_sBIT; +} +#endif + +#ifdef PNG_sRGB_SUPPORTED +void PNGAPI +png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->srgb_intent = (png_byte)srgb_intent; + info_ptr->valid |= PNG_INFO_sRGB; +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, + int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + +# ifdef PNG_gAMA_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); +# endif + +# ifdef PNG_cHRM_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); +# endif /* cHRM */ +} +#endif /* sRGB */ + + +#ifdef PNG_iCCP_SUPPORTED +void PNGAPI +png_set_iCCP(png_structp png_ptr, png_infop info_ptr, + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen) +{ + png_charp new_iccp_name; + png_bytep new_iccp_profile; + png_size_t length; + + png_debug1(1, "in %s storage function", "iCCP"); + + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + length = png_strlen(name)+1; + new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); + + if (new_iccp_name == NULL) + { + png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); + return; + } + + png_memcpy(new_iccp_name, name, length); + new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); + + if (new_iccp_profile == NULL) + { + png_free (png_ptr, new_iccp_name); + png_warning(png_ptr, + "Insufficient memory to process iCCP profile"); + return; + } + + png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); + + info_ptr->iccp_proflen = proflen; + info_ptr->iccp_name = new_iccp_name; + info_ptr->iccp_profile = new_iccp_profile; + /* Compression is always zero but is here so the API and info structure + * does not have to change if we introduce multiple compression types + */ + info_ptr->iccp_compression = (png_byte)compression_type; + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +void PNGAPI +png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, + int num_text) +{ + int ret; + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + + if (ret) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_structp png_ptr, png_infop info_ptr, + png_const_textp text_ptr, int num_text) +{ + int i; + + png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : + (unsigned long)png_ptr->chunk_name); + + if (png_ptr == NULL || info_ptr == NULL || num_text == 0) + return(0); + + /* Make sure we have enough space in the "text" array in info_struct + * to hold all of the incoming text_ptr objects. + */ + if (info_ptr->num_text + num_text > info_ptr->max_text) + { + if (info_ptr->text != NULL) + { + png_textp old_text; + int old_max; + + old_max = info_ptr->max_text; + info_ptr->max_text = info_ptr->num_text + num_text + 8; + old_text = info_ptr->text; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); + + if (info_ptr->text == NULL) + { + png_free(png_ptr, old_text); + return(1); + } + + png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * + png_sizeof(png_text))); + png_free(png_ptr, old_text); + } + + else + { + info_ptr->max_text = num_text + 8; + info_ptr->num_text = 0; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); + if (info_ptr->text == NULL) + return(1); + info_ptr->free_me |= PNG_FREE_TEXT; + } + + png_debug1(3, "allocated %d entries for info_ptr->text", + info_ptr->max_text); + } + for (i = 0; i < num_text; i++) + { + png_size_t text_length, key_len; + png_size_t lang_len, lang_key_len; + png_textp textp = &(info_ptr->text[info_ptr->num_text]); + + if (text_ptr[i].key == NULL) + continue; + + if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || + text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) + { + png_warning(png_ptr, "text compression mode is out of range"); + continue; + } + + key_len = png_strlen(text_ptr[i].key); + + if (text_ptr[i].compression <= 0) + { + lang_len = 0; + lang_key_len = 0; + } + + else +# ifdef PNG_iTXt_SUPPORTED + { + /* Set iTXt data */ + + if (text_ptr[i].lang != NULL) + lang_len = png_strlen(text_ptr[i].lang); + + else + lang_len = 0; + + if (text_ptr[i].lang_key != NULL) + lang_key_len = png_strlen(text_ptr[i].lang_key); + + else + lang_key_len = 0; + } +# else /* PNG_iTXt_SUPPORTED */ + { + png_warning(png_ptr, "iTXt chunk not supported"); + continue; + } +# endif + + if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') + { + text_length = 0; +# ifdef PNG_iTXt_SUPPORTED + if (text_ptr[i].compression > 0) + textp->compression = PNG_ITXT_COMPRESSION_NONE; + + else +# endif + textp->compression = PNG_TEXT_COMPRESSION_NONE; + } + + else + { + text_length = png_strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + + textp->key = (png_charp)png_malloc_warn(png_ptr, + (png_size_t) + (key_len + text_length + lang_len + lang_key_len + 4)); + + if (textp->key == NULL) + return(1); + + png_debug2(2, "Allocated %lu bytes at %p in png_set_text", + (unsigned long)(png_uint_32) + (key_len + lang_len + lang_key_len + text_length + 4), + textp->key); + + png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); + *(textp->key + key_len) = '\0'; + + if (text_ptr[i].compression > 0) + { + textp->lang = textp->key + key_len + 1; + png_memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang + lang_len) = '\0'; + textp->lang_key = textp->lang + lang_len + 1; + png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + *(textp->lang_key + lang_key_len) = '\0'; + textp->text = textp->lang_key + lang_key_len + 1; + } + + else + { + textp->lang=NULL; + textp->lang_key=NULL; + textp->text = textp->key + key_len + 1; + } + + if (text_length) + png_memcpy(textp->text, text_ptr[i].text, + (png_size_t)(text_length)); + + *(textp->text + text_length) = '\0'; + +# ifdef PNG_iTXt_SUPPORTED + if (textp->compression > 0) + { + textp->text_length = 0; + textp->itxt_length = text_length; + } + + else +# endif + { + textp->text_length = text_length; + textp->itxt_length = 0; + } + + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d", info_ptr->num_text); + } + return(0); +} +#endif + +#ifdef PNG_tIME_SUPPORTED +void PNGAPI +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) +{ + png_debug1(1, "in %s storage function", "tIME"); + + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_tIME)) + return; + + if (mod_time->month == 0 || mod_time->month > 12 || + mod_time->day == 0 || mod_time->day > 31 || + mod_time->hour > 23 || mod_time->minute > 59 || + mod_time->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + return; + } + + png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +void PNGAPI +png_set_tRNS(png_structp png_ptr, png_infop info_ptr, + png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) +{ + png_debug1(1, "in %s storage function", "tRNS"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (trans_alpha != NULL) + { + /* It may not actually be necessary to set png_ptr->trans_alpha here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); + + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + png_ptr->trans_alpha = info_ptr->trans_alpha = + (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); + + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + } + + if (trans_color != NULL) + { + int sample_max = (1 << info_ptr->bit_depth); + + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + (int)trans_color->gray > sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + ((int)trans_color->red > sample_max || + (int)trans_color->green > sample_max || + (int)trans_color->blue > sample_max))) + png_warning(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth"); + + png_memcpy(&(info_ptr->trans_color), trans_color, + png_sizeof(png_color_16)); + + if (num_trans == 0) + num_trans = 1; + } + + info_ptr->num_trans = (png_uint_16)num_trans; + + if (num_trans != 0) + { + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->free_me |= PNG_FREE_TRNS; + } +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +void PNGAPI +png_set_sPLT(png_structp png_ptr, + png_infop info_ptr, png_const_sPLT_tp entries, int nentries) +/* + * entries - array of png_sPLT_t structures + * to be added to the list of palettes + * in the info structure. + * + * nentries - number of palette structures to be + * added. + */ +{ + png_sPLT_tp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL) + return; + + np = (png_sPLT_tp)png_malloc_warn(png_ptr, + (info_ptr->splt_palettes_num + nentries) * + (png_size_t)png_sizeof(png_sPLT_t)); + + if (np == NULL) + { + png_warning(png_ptr, "No memory for sPLT palettes"); + return; + } + + png_memcpy(np, info_ptr->splt_palettes, + info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes=NULL; + + for (i = 0; i < nentries; i++) + { + png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; + png_const_sPLT_tp from = entries + i; + png_size_t length; + + length = png_strlen(from->name) + 1; + to->name = (png_charp)png_malloc_warn(png_ptr, length); + + if (to->name == NULL) + { + png_warning(png_ptr, + "Out of memory while processing sPLT chunk"); + continue; + } + + png_memcpy(to->name, from->name, length); + to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, + from->nentries * png_sizeof(png_sPLT_entry)); + + if (to->entries == NULL) + { + png_warning(png_ptr, + "Out of memory while processing sPLT chunk"); + png_free(png_ptr, to->name); + to->name = NULL; + continue; + } + + png_memcpy(to->entries, from->entries, + from->nentries * png_sizeof(png_sPLT_entry)); + + to->nentries = from->nentries; + to->depth = from->depth; + } + + info_ptr->splt_palettes = np; + info_ptr->splt_palettes_num += nentries; + info_ptr->valid |= PNG_INFO_sPLT; + info_ptr->free_me |= PNG_FREE_SPLT; +} +#endif /* PNG_sPLT_SUPPORTED */ + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +void PNGAPI +png_set_unknown_chunks(png_structp png_ptr, + png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) +{ + png_unknown_chunkp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) + return; + + np = (png_unknown_chunkp)png_malloc_warn(png_ptr, + (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk)); + + if (np == NULL) + { + png_warning(png_ptr, + "Out of memory while processing unknown chunk"); + return; + } + + png_memcpy(np, info_ptr->unknown_chunks, + (png_size_t)info_ptr->unknown_chunks_num * + png_sizeof(png_unknown_chunk)); + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + + for (i = 0; i < num_unknowns; i++) + { + png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; + png_const_unknown_chunkp from = unknowns + i; + + png_memcpy(to->name, from->name, png_sizeof(from->name)); + to->name[png_sizeof(to->name)-1] = '\0'; + to->size = from->size; + + /* Note our location in the read or write sequence */ + to->location = (png_byte)(png_ptr->mode & 0xff); + + if (from->size == 0) + to->data=NULL; + + else + { + to->data = (png_bytep)png_malloc_warn(png_ptr, + (png_size_t)from->size); + + if (to->data == NULL) + { + png_warning(png_ptr, + "Out of memory while processing unknown chunk"); + to->size = 0; + } + + else + png_memcpy(to->data, from->data, from->size); + } + } + + info_ptr->unknown_chunks = np; + info_ptr->unknown_chunks_num += num_unknowns; + info_ptr->free_me |= PNG_FREE_UNKN; +} + +void PNGAPI +png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, + int chunk, int location) +{ + if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < + info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks[chunk].location = (png_byte)location; +} +#endif + + +#ifdef PNG_MNG_FEATURES_SUPPORTED +png_uint_32 PNGAPI +png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) +{ + png_debug(1, "in png_permit_mng_features"); + + if (png_ptr == NULL) + return (png_uint_32)0; + + png_ptr->mng_features_permitted = + (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + + return (png_uint_32)png_ptr->mng_features_permitted; +} +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +void PNGAPI +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep + chunk_list, int num_chunks) +{ + png_bytep new_list, p; + int i, old_num_chunks; + if (png_ptr == NULL) + return; + + if (num_chunks == 0) + { + if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) + png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + + if (keep == PNG_HANDLE_CHUNK_ALWAYS) + png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; + + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; + + return; + } + + if (chunk_list == NULL) + return; + + old_num_chunks = png_ptr->num_chunk_list; + new_list=(png_bytep)png_malloc(png_ptr, + (png_size_t)(5*(num_chunks + old_num_chunks))); + + if (png_ptr->chunk_list != NULL) + { + png_memcpy(new_list, png_ptr->chunk_list, + (png_size_t)(5*old_num_chunks)); + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + } + + png_memcpy(new_list + 5*old_num_chunks, chunk_list, + (png_size_t)(5*num_chunks)); + + for (p = new_list + 5*old_num_chunks + 4, i = 0; inum_chunk_list = old_num_chunks + num_chunks; + png_ptr->chunk_list = new_list; + png_ptr->free_me |= PNG_FREE_LIST; +} +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +void PNGAPI +png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, + png_user_chunk_ptr read_user_chunk_fn) +{ + png_debug(1, "in png_set_read_user_chunk_fn"); + + if (png_ptr == NULL) + return; + + png_ptr->read_user_chunk_fn = read_user_chunk_fn; + png_ptr->user_chunk_ptr = user_chunk_ptr; +} +#endif + +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) +{ + png_debug1(1, "in %s storage function", "rows"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + + info_ptr->row_pointers = row_pointers; + + if (row_pointers) + info_ptr->valid |= PNG_INFO_IDAT; +} +#endif + +void PNGAPI +png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) +{ + if (png_ptr == NULL) + return; + + png_free(png_ptr, png_ptr->zbuf); + + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); + png_ptr->zbuf_size = ZLIB_IO_MAX; + size = ZLIB_IO_MAX; /* must fit */ + } + + else + png_ptr->zbuf_size = (uInt)size; + + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + + /* The following ensures a relatively safe failure if this gets called while + * the buffer is actually in use. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.avail_in = 0; +} + +void PNGAPI +png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) +{ + if (png_ptr && info_ptr) + info_ptr->valid &= ~mask; +} + + + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* This function was added to libpng 1.2.6 */ +void PNGAPI +png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, + png_uint_32 user_height_max) +{ + /* Images with dimensions larger than these limits will be + * rejected by png_set_IHDR(). To accept any PNG datastream + * regardless of dimensions, set both limits to 0x7ffffffL. + */ + if (png_ptr == NULL) + return; + + png_ptr->user_width_max = user_width_max; + png_ptr->user_height_max = user_height_max; +} + +/* This function was added to libpng 1.4.0 */ +void PNGAPI +png_set_chunk_cache_max (png_structp png_ptr, + png_uint_32 user_chunk_cache_max) +{ + if (png_ptr) + png_ptr->user_chunk_cache_max = user_chunk_cache_max; +} + +/* This function was added to libpng 1.4.1 */ +void PNGAPI +png_set_chunk_malloc_max (png_structp png_ptr, + png_alloc_size_t user_chunk_malloc_max) +{ + if (png_ptr) + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_set_benign_errors(png_structp png_ptr, int allowed) +{ + png_debug(1, "in png_set_benign_errors"); + + if (allowed) + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + + else + png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; +} +#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngstruct.h b/WDL/libpng/pngstruct.h new file mode 100644 index 00000000..bea7afe4 --- /dev/null +++ b/WDL/libpng/pngstruct.h @@ -0,0 +1,360 @@ + +/* pngstruct.h - header file for PNG reference library + * + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Last changed in libpng 1.5.5 [September 22, 2011] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application. + */ + +#ifndef PNGSTRUCT_H +#define PNGSTRUCT_H +/* zlib.h defines the structure z_stream, an instance of which is included + * in this structure and is required for decompressing the LZ compressed + * data in PNG files. + */ +#include "../zlib/zlib.h" + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf longjmp_buffer; /* used in png_error */ + png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; /* function for printing warnings */ +#endif + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + uInt zbuf_size; /* size of zbuf (typically 65536) */ +#ifdef PNG_WRITE_SUPPORTED + +/* Added in 1.5.4: state to keep track of whether the zstream has been + * initialized and if so whether it is for IDAT or some other chunk. + */ +#define PNG_ZLIB_UNINITIALIZED 0 +#define PNG_ZLIB_FOR_IDAT 1 +#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ +#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ +#define PNG_ZLIB_IN_USE 4 /* a flag value */ + + png_uint_32 zlib_state; /* State of zlib initialization */ +/* End of material added at libpng 1.5.4 */ + + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ +#endif +/* Added at libpng 1.5.4 */ +#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ + defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) + int zlib_text_level; /* holds zlib compression level */ + int zlib_text_method; /* holds zlib compression method */ + int zlib_text_window_bits; /* holds zlib compression window bits */ + int zlib_text_mem_level; /* holds zlib compression memory level */ + int zlib_text_strategy; /* holds zlib compression strategy */ +#endif +/* End of material added at libpng 1.5.4 */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_size_t rowbytes; /* size of row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row. + * This is a pointer into big_prev_row + */ + png_bytep row_buf; /* buffer to save current (unfiltered) row. + * This is a pointer into big_row_buf + */ + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ + png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row: write only */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write: write only */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + png_byte maximum_pixel_depth; + /* pixel depth used for the row buffers */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ + png_byte io_chunk_string[5]; + /* string name of chunk */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_byte background_gamma_type; + png_fixed_point background_gamma; + png_color_16 background; /* background color in screen gamma space */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_flush_ptr output_flush_fn; /* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ + png_fixed_point gamma; /* file gamma value */ + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans_alpha; /* alpha values for paletted files */ + png_color_16 trans_color; /* transparent color for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# ifdef PNG_TEXT_SUPPORTED + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* For the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_bytep palette_lookup; /* lookup table for quantizing */ + png_bytep quantize_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + char time_buffer[29]; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int num_chunk_list; + png_bytep chunk_list; +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED + /* Added in 1.5.5 to record an sRGB chunk in the png. */ + png_byte is_sRGB; +#endif + +/* New members added in libpng-1.0.3 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; + /* Added in libpng 1.5.5 to record setting of coefficients: */ + png_byte rgb_to_gray_coefficients_set; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Changed from png_byte to png_uint_32 at version 1.2.0 */ + png_uint_32 mng_features_permitted; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_byte filter_type; +#endif + +/* New members added in libpng-1.2.0 */ + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep quantize_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is + in the palette */ + png_bytep palette_to_index; /* which original index points to this + palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; + + /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown + * chunks that can be stored (0 means unlimited). + */ + png_uint_32 user_chunk_cache_max; + + /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk + * can occupy when decompressed. 0 means unlimited. + */ + png_alloc_size_t user_chunk_malloc_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif + +/* New member added in libpng-1.2.26 */ + png_size_t old_big_row_buf_size; + +/* New member added in libpng-1.2.30 */ + png_charp chunkdata; /* buffer for reading chunk data */ + +#ifdef PNG_IO_STATE_SUPPORTED +/* New member added in libpng-1.4.0 */ + png_uint_32 io_state; +#endif + +/* New member added in libpng-1.5.6 */ + png_bytep big_prev_row; + + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); +}; +#endif /* PNGSTRUCT_H */ diff --git a/WDL/libpng/pngtest.c b/WDL/libpng/pngtest.c new file mode 100644 index 00000000..0b29c60f --- /dev/null +++ b/WDL/libpng/pngtest.c @@ -0,0 +1,1820 @@ + +/* pngtest.c - a simple test program to test libpng + * + * Last changed in libpng 1.5.6 [November 3, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This program reads in a PNG image, writes it out again, and then + * compares the two files. If the files are identical, this shows that + * the basic chunk handling, filtering, and (de)compression code is working + * properly. It does not currently test all of the transforms, although + * it probably should. + * + * The program will report "FAIL" in certain legitimate cases: + * 1) when the compression level or filter selection method is changed. + * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. + * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks + * exist in the input file. + * 4) others not listed here... + * In these cases, it is best to check with another tool such as "pngcheck" + * to see what the differences between the two files are. + * + * If a filename is given on the command-line, then this file is used + * for the input, rather than the default "pngtest.png". This allows + * testing a wide variety of files easily. You can also test a number + * of files at once by typing "pngtest -m file1.png file2.png ..." + */ + +#define _POSIX_SOURCE 1 + +#include "zlib.h" +#include "png.h" +/* Copied from pngpriv.h but only used in error messages below. */ +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif +# include +# include +# include +# define FCLOSE(file) fclose(file) + +#ifndef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +/* Makes pngtest verbose so we can find problems. */ +#ifndef PNG_DEBUG +# define PNG_DEBUG 0 +#endif + +#if PNG_DEBUG > 1 +# define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) +# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1)) +# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2)) +#else +# define pngtest_debug(m) ((void)0) +# define pngtest_debug1(m,p1) ((void)0) +# define pngtest_debug2(m,p1,p2) ((void)0) +#endif + +#if !PNG_DEBUG +# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ +#endif + +/* The code uses memcmp and memcpy on large objects (typically row pointers) so + * it is necessary to do soemthing special on certain architectures, note that + * the actual support for this was effectively removed in 1.4, so only the + * memory remains in this program: + */ +#define CVT_PTR(ptr) (ptr) +#define CVT_PTR_NOCHECK(ptr) (ptr) +#define png_memcmp memcmp +#define png_memcpy memcpy +#define png_memset memset + +/* Turn on CPU timing +#define PNGTEST_TIMING +*/ + +#ifndef PNG_FLOATING_POINT_SUPPORTED +#undef PNGTEST_TIMING +#endif + +#ifdef PNGTEST_TIMING +static float t_start, t_stop, t_decode, t_encode, t_misc; +#include +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED +#define PNG_tIME_STRING_LENGTH 29 +static int tIME_chunk_present = 0; +static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; +#endif + +static int verbose = 0; +static int strict = 0; + +int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); + +#ifdef __TURBOC__ +#include +#endif + +/* Defined so I can write to a file on gui/windowing platforms */ +/* #define STDERR stderr */ +#define STDERR stdout /* For DOS */ + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) png_ptr->jmpbuf +#endif + +/* Example of using row callbacks to make a simple progress meter */ +static int status_pass = 1; +static int status_dots_requested = 0; +static int status_dots = 1; + +void PNGCBAPI +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void PNGCBAPI +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) + return; + + if (status_pass != pass) + { + fprintf(stdout, "\n Pass %d: ", pass); + status_pass = pass; + status_dots = 31; + } + + status_dots--; + + if (status_dots == 0) + { + fprintf(stdout, "\n "); + status_dots=30; + } + + fprintf(stdout, "r"); +} + +void PNGCBAPI +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void PNGCBAPI +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) + return; + + fprintf(stdout, "w"); +} + + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +/* Example of using user transform callback (we don't transform anything, + * but merely examine the row filters. We set this to 256 rather than + * 5 in case illegal filter values are present.) + */ +static png_uint_32 filters_used[256]; +void PNGCBAPI +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void PNGCBAPI +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + if (png_ptr != NULL && row_info != NULL) + ++filters_used[*(data - 1)]; +} +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +/* Example of using user transform callback (we don't transform anything, + * but merely count the zero samples) + */ + +static png_uint_32 zero_samples; + +void PNGCBAPI +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void PNGCBAPI +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + png_bytep dp = data; + if (png_ptr == NULL) + return; + + /* Contents of row_info: + * png_uint_32 width width of row + * png_uint_32 rowbytes number of bytes in row + * png_byte color_type color type of pixels + * png_byte bit_depth bit depth of samples + * png_byte channels number of channels (1-4) + * png_byte pixel_depth bits per pixel (depth*channels) + */ + + /* Counts the number of zero samples (or zero pixels if color_type is 3 */ + + if (row_info->color_type == 0 || row_info->color_type == 3) + { + int pos = 0; + png_uint_32 n, nstop; + + for (n = 0, nstop=row_info->width; nbit_depth == 1) + { + if (((*dp << pos++ ) & 0x80) == 0) + zero_samples++; + + if (pos == 8) + { + pos = 0; + dp++; + } + } + + if (row_info->bit_depth == 2) + { + if (((*dp << (pos+=2)) & 0xc0) == 0) + zero_samples++; + + if (pos == 8) + { + pos = 0; + dp++; + } + } + + if (row_info->bit_depth == 4) + { + if (((*dp << (pos+=4)) & 0xf0) == 0) + zero_samples++; + + if (pos == 8) + { + pos = 0; + dp++; + } + } + + if (row_info->bit_depth == 8) + if (*dp++ == 0) + zero_samples++; + + if (row_info->bit_depth == 16) + { + if ((*dp | *(dp+1)) == 0) + zero_samples++; + dp+=2; + } + } + } + else /* Other color types */ + { + png_uint_32 n, nstop; + int channel; + int color_channels = row_info->channels; + if (row_info->color_type > 3)color_channels--; + + for (n = 0, nstop=row_info->width; nbit_depth == 8) + if (*dp++ == 0) + zero_samples++; + + if (row_info->bit_depth == 16) + { + if ((*dp | *(dp+1)) == 0) + zero_samples++; + + dp+=2; + } + } + if (row_info->color_type > 3) + { + dp++; + if (row_info->bit_depth == 16) + dp++; + } + } + } +} +#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ + +static int wrote_question = 0; + +#ifndef PNG_STDIO_SUPPORTED +/* START of code to validate stdio-free compilation */ +/* These copies of the default read/write functions come from pngrio.c and + * pngwio.c. They allow "don't include stdio" testing of the library. + * This is the function that does the actual reading of data. If you are + * not reading from a standard C stream, you should create a replacement + * read_data function and use it at run time with png_set_read_fn(), rather + * than changing the library. + */ + +#ifdef PNG_IO_STATE_SUPPORTED +void +pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, + png_uint_32 io_op); +void +pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, + png_uint_32 io_op) +{ + png_uint_32 io_state = png_get_io_state(png_ptr); + int err = 0; + + /* Check if the current operation (reading / writing) is as expected. */ + if ((io_state & PNG_IO_MASK_OP) != io_op) + png_error(png_ptr, "Incorrect operation in I/O state"); + + /* Check if the buffer size specific to the current location + * (file signature / header / data / crc) is as expected. + */ + switch (io_state & PNG_IO_MASK_LOC) + { + case PNG_IO_SIGNATURE: + if (data_length > 8) + err = 1; + break; + case PNG_IO_CHUNK_HDR: + if (data_length != 8) + err = 1; + break; + case PNG_IO_CHUNK_DATA: + break; /* no restrictions here */ + case PNG_IO_CHUNK_CRC: + if (data_length != 4) + err = 1; + break; + default: + err = 1; /* uninitialized */ + } + if (err) + png_error(png_ptr, "Bad I/O state or buffer size"); +} +#endif + +#ifndef USE_FAR_KEYWORD +static void PNGCBAPI +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check = 0; + png_voidp io_ptr; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + io_ptr = png_get_io_ptr(png_ptr); + if (io_ptr != NULL) + { + check = fread(data, 1, length, (png_FILE_p)io_ptr); + } + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } + +#ifdef PNG_IO_STATE_SUPPORTED + pngtest_check_io_state(png_ptr, length, PNG_IO_READING); +#endif +} +#else +/* This is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void PNGCBAPI +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + png_byte *n_data; + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + n_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); + if ((png_bytep)n_data == data) + { + check = fread(n_data, 1, length, io_ptr); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + + do + { + read = MIN(NEAR_BUF_SIZE, remaining); + err = fread(buf, 1, 1, io_ptr); + png_memcpy(data, buf, read); /* Copy far buffer to near buffer */ + if (err != read) + break; + else + check += err; + data += read; + remaining -= read; + } + while (remaining != 0); + } + + if (check != length) + png_error(png_ptr, "Read Error"); + +#ifdef PNG_IO_STATE_SUPPORTED + pngtest_check_io_state(png_ptr, length, PNG_IO_READING); +#endif +} +#endif /* USE_FAR_KEYWORD */ + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +static void PNGCBAPI +pngtest_flush(png_structp png_ptr) +{ + /* Do nothing; fflush() is said to be just a waste of energy. */ + PNG_UNUSED(png_ptr) /* Stifle compiler warning */ +} +#endif + +/* This is the function that does the actual writing of data. If you are + * not writing to a standard C stream, you should create a replacement + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ +#ifndef USE_FAR_KEYWORD +static void PNGCBAPI +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); + + if (check != length) + { + png_error(png_ptr, "Write Error"); + } + +#ifdef PNG_IO_STATE_SUPPORTED + pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); +#endif +} +#else +/* This is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void PNGCBAPI +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); + + if ((png_bytep)near_data == data) + { + check = fwrite(near_data, 1, length, io_ptr); + } + + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ + err = fwrite(buf, 1, written, io_ptr); + if (err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + while (remaining != 0); + } + + if (check != length) + { + png_error(png_ptr, "Write Error"); + } + +#ifdef PNG_IO_STATE_SUPPORTED + pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); +#endif +} +#endif /* USE_FAR_KEYWORD */ + +/* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void PNGCBAPI +pngtest_warning(png_structp png_ptr, png_const_charp message) +{ + PNG_CONST char *name = "UNKNOWN (ERROR!)"; + char *test; + test = png_get_error_ptr(png_ptr); + + if (test == NULL) + fprintf(STDERR, "%s: libpng warning: %s\n", name, message); + + else + fprintf(STDERR, "%s: libpng warning: %s\n", test, message); +} + +/* This is the default error handling function. Note that replacements for + * this function MUST NOT RETURN, or the program will likely crash. This + * function is used by default, or if the program supplies NULL for the + * error function pointer in png_set_error_fn(). + */ +static void PNGCBAPI +pngtest_error(png_structp png_ptr, png_const_charp message) +{ + pngtest_warning(png_ptr, message); + /* We can return because png_error calls the default handler, which is + * actually OK in this case. + */ +} +#endif /* !PNG_STDIO_SUPPORTED */ +/* END of code to validate stdio-free compilation */ + +/* START of code to validate memory allocation and deallocation */ +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + * + * This piece of code can be compiled to validate max 64K allocations + * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. + */ +typedef struct memory_information +{ + png_alloc_size_t size; + png_voidp pointer; + struct memory_information FAR *next; +} memory_information; +typedef memory_information FAR *memory_infop; + +static memory_infop pinformation = NULL; +static int current_allocation = 0; +static int maximum_allocation = 0; +static int total_allocation = 0; +static int num_allocations = 0; + +png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr, + png_alloc_size_t size)); +void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); + +png_voidp +PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) +{ + + /* png_malloc has already tested for NULL; png_create_struct calls + * png_debug_malloc directly, with png_ptr == NULL which is OK + */ + + if (size == 0) + return (NULL); + + /* This calls the library allocator twice, once to get the requested + buffer and once to get a new free list entry. */ + { + /* Disable malloc_fn and free_fn */ + memory_infop pinfo; + png_set_mem_fn(png_ptr, NULL, NULL, NULL); + pinfo = (memory_infop)png_malloc(png_ptr, + png_sizeof(*pinfo)); + pinfo->size = size; + current_allocation += size; + total_allocation += size; + num_allocations ++; + + if (current_allocation > maximum_allocation) + maximum_allocation = current_allocation; + + pinfo->pointer = png_malloc(png_ptr, size); + /* Restore malloc_fn and free_fn */ + + png_set_mem_fn(png_ptr, + NULL, png_debug_malloc, png_debug_free); + + if (size != 0 && pinfo->pointer == NULL) + { + current_allocation -= size; + total_allocation -= size; + png_error(png_ptr, + "out of memory in pngtest->png_debug_malloc"); + } + + pinfo->next = pinformation; + pinformation = pinfo; + /* Make sure the caller isn't assuming zeroed memory. */ + png_memset(pinfo->pointer, 0xdd, pinfo->size); + + if (verbose) + printf("png_malloc %lu bytes at %p\n", (unsigned long)size, + pinfo->pointer); + + return (png_voidp)(pinfo->pointer); + } +} + +/* Free a pointer. It is removed from the list at the same time. */ +void PNGCBAPI +png_debug_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL) + fprintf(STDERR, "NULL pointer to png_debug_free.\n"); + + if (ptr == 0) + { +#if 0 /* This happens all the time. */ + fprintf(STDERR, "WARNING: freeing NULL pointer\n"); +#endif + return; + } + + /* Unlink the element from the list. */ + { + memory_infop FAR *ppinfo = &pinformation; + + for (;;) + { + memory_infop pinfo = *ppinfo; + + if (pinfo->pointer == ptr) + { + *ppinfo = pinfo->next; + current_allocation -= pinfo->size; + if (current_allocation < 0) + fprintf(STDERR, "Duplicate free of memory\n"); + /* We must free the list element too, but first kill + the memory that is to be freed. */ + png_memset(ptr, 0x55, pinfo->size); + png_free_default(png_ptr, pinfo); + pinfo = NULL; + break; + } + + if (pinfo->next == NULL) + { + fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); + break; + } + + ppinfo = &pinfo->next; + } + } + + /* Finally free the data. */ + if (verbose) + printf("Freeing %p\n", ptr); + + png_free_default(png_ptr, ptr); + ptr = NULL; +} +#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +/* END of code to test memory allocation/deallocation */ + + +/* Demonstration of user chunk support of the sTER and vpAg chunks */ +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + +/* (sTER is a public chunk not yet known by libpng. vpAg is a private +chunk used in ImageMagick to store "virtual page" size). */ + +static png_uint_32 user_chunk_data[4]; + + /* 0: sTER mode + 1 + * 1: vpAg width + * 2: vpAg height + * 3: vpAg units + */ + +static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, + png_unknown_chunkp chunk) +{ + png_uint_32 + *my_user_chunk_data; + + /* Return one of the following: + * return (-n); chunk had an error + * return (0); did not recognize + * return (n); success + * + * The unknown chunk structure contains the chunk data: + * png_byte name[5]; + * png_byte *data; + * png_size_t size; + * + * Note that libpng has already taken care of the CRC handling. + */ + + if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ + chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ + { + /* Found sTER chunk */ + if (chunk->size != 1) + return (-1); /* Error return */ + + if (chunk->data[0] != 0 && chunk->data[0] != 1) + return (-1); /* Invalid mode */ + + my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); + my_user_chunk_data[0]=chunk->data[0]+1; + return (1); + } + + if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ + chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ + return (0); /* Did not recognize */ + + /* Found ImageMagick vpAg chunk */ + + if (chunk->size != 9) + return (-1); /* Error return */ + + my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); + + my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); + my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); + my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; + + return (1); + +} +#endif +/* END of code to demonstrate user chunk support */ + +/* Test one file */ +int +test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) +{ + static png_FILE_p fpin; + static png_FILE_p fpout; /* "static" prevents setjmp corruption */ + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; +#ifdef PNG_WRITE_SUPPORTED + png_structp write_ptr; + png_infop write_info_ptr; + png_infop write_end_info_ptr; +#else + png_structp write_ptr = NULL; + png_infop write_info_ptr = NULL; + png_infop write_end_info_ptr = NULL; +#endif + png_bytep row_buf; + png_uint_32 y; + png_uint_32 width, height; + int num_pass, pass; + int bit_depth, color_type; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf tmp_jmpbuf; +#endif +#endif + + char inbuf[256], outbuf[256]; + + row_buf = NULL; + + if ((fpin = fopen(inname, "rb")) == NULL) + { + fprintf(STDERR, "Could not find input file %s\n", inname); + return (1); + } + + if ((fpout = fopen(outname, "wb")) == NULL) + { + fprintf(STDERR, "Could not open output file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + pngtest_debug("Allocating read and write structures"); +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + read_ptr = + png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL, NULL, png_debug_malloc, png_debug_free); +#else + read_ptr = + png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +#endif +#ifndef PNG_STDIO_SUPPORTED + png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + user_chunk_data[0] = 0; + user_chunk_data[1] = 0; + user_chunk_data[2] = 0; + user_chunk_data[3] = 0; + png_set_read_user_chunk_fn(read_ptr, user_chunk_data, + read_user_chunk_callback); + +#endif +#ifdef PNG_WRITE_SUPPORTED +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + write_ptr = + png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL, NULL, png_debug_malloc, png_debug_free); +#else + write_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +#endif +#ifndef PNG_STDIO_SUPPORTED + png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif +#endif + pngtest_debug("Allocating read_info, write_info and end_info structures"); + read_info_ptr = png_create_info_struct(read_ptr); + end_info_ptr = png_create_info_struct(read_ptr); +#ifdef PNG_WRITE_SUPPORTED + write_info_ptr = png_create_info_struct(write_ptr); + write_end_info_ptr = png_create_info_struct(write_ptr); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + pngtest_debug("Setting jmpbuf for read struct"); +#ifdef USE_FAR_KEYWORD + if (setjmp(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(read_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); + png_free(read_ptr, row_buf); + row_buf = NULL; + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif + +#ifdef PNG_WRITE_SUPPORTED + pngtest_debug("Setting jmpbuf for write struct"); +#ifdef USE_FAR_KEYWORD + + if (setjmp(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(write_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } + +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif +#endif +#endif + + pngtest_debug("Initializing input and output streams"); +#ifdef PNG_STDIO_SUPPORTED + png_init_io(read_ptr, fpin); +# ifdef PNG_WRITE_SUPPORTED + png_init_io(write_ptr, fpout); +# endif +#else + png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); +# ifdef PNG_WRITE_SUPPORTED + png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, +# ifdef PNG_WRITE_FLUSH_SUPPORTED + pngtest_flush); +# else + NULL); +# endif +# endif +#endif + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + /* Normally one would use Z_DEFAULT_STRATEGY for text compression. + * This is here just to make pngtest replicate the results from libpng + * versions prior to 1.5.4, and to test this new API. + */ + png_set_text_compression_strategy(write_ptr, Z_FILTERED); +#endif + + if (status_dots_requested == 1) + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, write_row_callback); +#endif + png_set_read_status_fn(read_ptr, read_row_callback); + } + + else + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, NULL); +#endif + png_set_read_status_fn(read_ptr, NULL); + } + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + { + int i; + + for (i = 0; i<256; i++) + filters_used[i] = 0; + + png_set_read_user_transform_fn(read_ptr, count_filters); + } +#endif +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + zero_samples = 0; + png_set_write_user_transform_fn(write_ptr, count_zero_samples); +#endif + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_HANDLE_CHUNK_ALWAYS +# define PNG_HANDLE_CHUNK_ALWAYS 3 +# endif + png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, + NULL, 0); +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_HANDLE_CHUNK_IF_SAFE +# define PNG_HANDLE_CHUNK_IF_SAFE 2 +# endif + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, + NULL, 0); +#endif + + pngtest_debug("Reading info struct"); + png_read_info(read_ptr, read_info_ptr); + + pngtest_debug("Transferring info struct"); + { + int interlace_type, compression_type, filter_type; + + if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, &compression_type, &filter_type)) + { + png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + color_type, interlace_type, compression_type, filter_type); +#else + color_type, PNG_INTERLACE_NONE, compression_type, filter_type); +#endif + } + } +#ifdef PNG_FIXED_POINT_SUPPORTED +#ifdef PNG_cHRM_SUPPORTED + { + png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + + if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, + &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#ifdef PNG_gAMA_SUPPORTED + { + png_fixed_point gamma; + + if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) + png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); + } +#endif +#else /* Use floating point versions */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +#ifdef PNG_cHRM_SUPPORTED + { + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + + if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, + &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#ifdef PNG_gAMA_SUPPORTED + { + double gamma; + + if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) + png_set_gAMA(write_ptr, write_info_ptr, gamma); + } +#endif +#endif /* Floating point */ +#endif /* Fixed point */ +#ifdef PNG_iCCP_SUPPORTED + { + png_charp name; + png_bytep profile; + png_uint_32 proflen; + int compression_type; + + if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, + &profile, &proflen)) + { + png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, + profile, proflen); + } + } +#endif +#ifdef PNG_sRGB_SUPPORTED + { + int intent; + + if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) + png_set_sRGB(write_ptr, write_info_ptr, intent); + } +#endif + { + png_colorp palette; + int num_palette; + + if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) + png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); + } +#ifdef PNG_bKGD_SUPPORTED + { + png_color_16p background; + + if (png_get_bKGD(read_ptr, read_info_ptr, &background)) + { + png_set_bKGD(write_ptr, write_info_ptr, background); + } + } +#endif +#ifdef PNG_hIST_SUPPORTED + { + png_uint_16p hist; + + if (png_get_hIST(read_ptr, read_info_ptr, &hist)) + png_set_hIST(write_ptr, write_info_ptr, hist); + } +#endif +#ifdef PNG_oFFs_SUPPORTED + { + png_int_32 offset_x, offset_y; + int unit_type; + + if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, + &unit_type)) + { + png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); + } + } +#endif +#ifdef PNG_pCAL_SUPPORTED + { + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + + if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, + &nparams, &units, ¶ms)) + { + png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, + nparams, units, params); + } + } +#endif +#ifdef PNG_pHYs_SUPPORTED + { + png_uint_32 res_x, res_y; + int unit_type; + + if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) + png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); + } +#endif +#ifdef PNG_sBIT_SUPPORTED + { + png_color_8p sig_bit; + + if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) + png_set_sBIT(write_ptr, write_info_ptr, sig_bit); + } +#endif +#ifdef PNG_sCAL_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED + { + int unit; + double scal_width, scal_height; + + if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + { + int unit; + png_charp scal_width, scal_height; + + if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, + scal_height); + } + } +#endif +#endif +#endif +#ifdef PNG_TEXT_SUPPORTED + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) + { + pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); + + if (verbose) + printf("\nText compression=%d\n", text_ptr->compression); + + png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); + } + } +#endif +#ifdef PNG_tIME_SUPPORTED + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_info_ptr, mod_time); +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* We have to use png_memcpy instead of "=" because the string + * pointed to by png_convert_to_rfc1123() gets free'ed before + * we use it. + */ + png_memcpy(tIME_string, + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); + + tIME_string[png_sizeof(tIME_string) - 1] = '\0'; + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#ifdef PNG_tRNS_SUPPORTED + { + png_bytep trans_alpha; + int num_trans; + png_color_16p trans_color; + + if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, + &trans_color)) + { + int sample_max = (1 << bit_depth); + /* libpng doesn't reject a tRNS chunk with out-of-range samples */ + if (!((color_type == PNG_COLOR_TYPE_GRAY && + (int)trans_color->gray > sample_max) || + (color_type == PNG_COLOR_TYPE_RGB && + ((int)trans_color->red > sample_max || + (int)trans_color->green > sample_max || + (int)trans_color->blue > sample_max)))) + png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, + trans_color); + } + } +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + { + png_unknown_chunkp unknowns; + int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, + &unknowns); + + if (num_unknowns) + { + int i; + png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, + num_unknowns); + /* Copy the locations from the read_info_ptr. The automatically + * generated locations in write_info_ptr are wrong because we + * haven't written anything yet. + */ + for (i = 0; i < num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, + unknowns[i].location); + } + } +#endif + +#ifdef PNG_WRITE_SUPPORTED + pngtest_debug("Writing info struct"); + +/* If we wanted, we could write info in two steps: + * png_write_info_before_PLTE(write_ptr, write_info_ptr); + */ + png_write_info(write_ptr, write_info_ptr); + +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + if (user_chunk_data[0] != 0) + { + png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}; + + unsigned char + ster_chunk_data[1]; + + if (verbose) + fprintf(STDERR, "\n stereo mode = %lu\n", + (unsigned long)(user_chunk_data[0] - 1)); + + ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1); + png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1); + } + + if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0) + { + png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'}; + + unsigned char + vpag_chunk_data[9]; + + if (verbose) + fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n", + (unsigned long)user_chunk_data[1], + (unsigned long)user_chunk_data[2], + (unsigned long)user_chunk_data[3]); + + png_save_uint_32(vpag_chunk_data, user_chunk_data[1]); + png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]); + vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff); + png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9); + } + +#endif +#endif + +#ifdef SINGLE_ROWBUF_ALLOC + pngtest_debug("Allocating row buffer..."); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + + pngtest_debug1("\t0x%08lx", (unsigned long)row_buf); +#endif /* SINGLE_ROWBUF_ALLOC */ + pngtest_debug("Writing row data"); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) + num_pass = png_set_interlace_handling(read_ptr); +# ifdef PNG_WRITE_SUPPORTED + png_set_interlace_handling(write_ptr); +# endif +#else + num_pass = 1; +#endif + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; +#endif + for (pass = 0; pass < num_pass; pass++) + { + pngtest_debug1("Writing row data for pass %d", pass); + for (y = 0; y < height; y++) + { +#ifndef SINGLE_ROWBUF_ALLOC + pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + + pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf, + png_get_rowbytes(read_ptr, read_info_ptr)); + +#endif /* !SINGLE_ROWBUF_ALLOC */ + png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_decode += (t_stop - t_start); + t_start = t_stop; +#endif + png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_encode += (t_stop - t_start); + t_start = t_stop; +#endif +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef SINGLE_ROWBUF_ALLOC + pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); + png_free(read_ptr, row_buf); + row_buf = NULL; +#endif /* !SINGLE_ROWBUF_ALLOC */ + } + } + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); +#endif + + pngtest_debug("Reading and writing end_info data"); + + png_read_end(read_ptr, end_info_ptr); +#ifdef PNG_TEXT_SUPPORTED + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) + { + pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); + png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); + } + } +#endif +#ifdef PNG_tIME_SUPPORTED + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_end_info_ptr, mod_time); +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* We have to use png_memcpy instead of "=" because the string + pointed to by png_convert_to_rfc1123() gets free'ed before + we use it */ + png_memcpy(tIME_string, + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); + + tIME_string[png_sizeof(tIME_string) - 1] = '\0'; + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + { + png_unknown_chunkp unknowns; + int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, + &unknowns); + + if (num_unknowns) + { + int i; + png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, + num_unknowns); + /* Copy the locations from the read_info_ptr. The automatically + * generated locations in write_end_info_ptr are wrong because we + * haven't written the end_info yet. + */ + for (i = 0; i < num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, + unknowns[i].location); + } + } +#endif +#ifdef PNG_WRITE_SUPPORTED + png_write_end(write_ptr, write_end_info_ptr); +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED + if (verbose) + { + png_uint_32 iwidth, iheight; + iwidth = png_get_image_width(write_ptr, write_info_ptr); + iheight = png_get_image_height(write_ptr, write_info_ptr); + fprintf(STDERR, "\n Image width = %lu, height = %lu\n", + (unsigned long)iwidth, (unsigned long)iheight); + } +#endif + + pngtest_debug("Destroying data structs"); +#ifdef SINGLE_ROWBUF_ALLOC + pngtest_debug("destroying row_buf for read_ptr"); + png_free(read_ptr, row_buf); + row_buf = NULL; +#endif /* SINGLE_ROWBUF_ALLOC */ + pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr"); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + pngtest_debug("destroying write_end_info_ptr"); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + pngtest_debug("destroying write_ptr, write_info_ptr"); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + pngtest_debug("Destruction complete."); + + FCLOSE(fpin); + FCLOSE(fpout); + + pngtest_debug("Opening files for comparison"); + if ((fpin = fopen(inname, "rb")) == NULL) + { + fprintf(STDERR, "Could not find file %s\n", inname); + return (1); + } + + if ((fpout = fopen(outname, "rb")) == NULL) + { + fprintf(STDERR, "Could not find file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + for (;;) + { + png_size_t num_in, num_out; + + num_in = fread(inbuf, 1, 1, fpin); + num_out = fread(outbuf, 1, 1, fpout); + + if (num_in != num_out) + { + fprintf(STDERR, "\nFiles %s and %s are of a different size\n", + inname, outname); + + if (wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname, PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question = 1; + } + + FCLOSE(fpin); + FCLOSE(fpout); + + if (strict != 0) + return (1); + + else + return (0); + } + + if (!num_in) + break; + + if (png_memcmp(inbuf, outbuf, num_in)) + { + fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); + + if (wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname, PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question = 1; + } + + FCLOSE(fpin); + FCLOSE(fpout); + + if (strict != 0) + return (1); + + else + return (0); + } + } + + FCLOSE(fpin); + FCLOSE(fpout); + + return (0); +} + +/* Input and output filenames */ +#ifdef RISCOS +static PNG_CONST char *inname = "pngtest/png"; +static PNG_CONST char *outname = "pngout/png"; +#else +static PNG_CONST char *inname = "pngtest.png"; +static PNG_CONST char *outname = "pngout.png"; +#endif + +int +main(int argc, char *argv[]) +{ + int multiple = 0; + int ierror = 0; + + fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); + fprintf(STDERR, "%s", png_get_copyright(NULL)); + /* Show the version of libpng used in building the library */ + fprintf(STDERR, " library (%lu):%s", + (unsigned long)png_access_version_number(), + png_get_header_version(NULL)); + + /* Show the version of libpng used in building the application */ + fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, + PNG_HEADER_VERSION_STRING); + + /* Do some consistency checking on the memory allocation settings, I'm + * not sure this matters, but it is nice to know, the first of these + * tests should be impossible because of the way the macros are set + * in pngconf.h + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); +#endif + /* I think the following can happen. */ +#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); +#endif + + if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) + { + fprintf(STDERR, + "Warning: versions are different between png.h and png.c\n"); + fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); + ++ierror; + } + + if (argc > 1) + { + if (strcmp(argv[1], "-m") == 0) + { + multiple = 1; + status_dots_requested = 0; + } + + else if (strcmp(argv[1], "-mv") == 0 || + strcmp(argv[1], "-vm") == 0 ) + { + multiple = 1; + verbose = 1; + status_dots_requested = 1; + } + + else if (strcmp(argv[1], "-v") == 0) + { + verbose = 1; + status_dots_requested = 1; + inname = argv[2]; + } + + else if (strcmp(argv[1], "--strict") == 0) + { + status_dots_requested = 0; + verbose = 1; + inname = argv[2]; + strict++; + } + + else + { + inname = argv[1]; + status_dots_requested = 0; + } + } + + if (!multiple && argc == 3 + verbose) + outname = argv[2 + verbose]; + + if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) + { + fprintf(STDERR, + "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", + argv[0], argv[0]); + fprintf(STDERR, + " reads/writes one PNG file (without -m) or multiple files (-m)\n"); + fprintf(STDERR, + " with -m %s is used as a temporary file\n", outname); + exit(1); + } + + if (multiple) + { + int i; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + for (i=2; isize, + (unsigned int)pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + + else + { + int i; + for (i = 0; i<3; ++i) + { + int kerror; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + if (i == 1) + status_dots_requested = 1; + + else if (verbose == 0) + status_dots_requested = 0; + + if (i == 0 || verbose == 1 || ierror != 0) + fprintf(STDERR, "\n Testing %s:", inname); + + kerror = test_one_file(inname, outname); + + if (kerror == 0) + { + if (verbose == 1 || i == 2) + { +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + int k; +#endif +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + fprintf(STDERR, "\n PASS (%lu zero samples)\n", + (unsigned long)zero_samples); +#else + fprintf(STDERR, " PASS\n"); +#endif +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + for (k = 0; k<256; k++) + if (filters_used[k]) + fprintf(STDERR, " Filter %d was used %lu times\n", + k, (unsigned long)filters_used[k]); +#endif +#ifdef PNG_TIME_RFC1123_SUPPORTED + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } + + else + { + if (verbose == 0 && i != 2) + fprintf(STDERR, "\n Testing %s:", inname); + + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + if (allocation_now != current_allocation) + fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", + current_allocation - allocation_now); + + if (current_allocation != 0) + { + memory_infop pinfo = pinformation; + + fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", + current_allocation); + + while (pinfo != NULL) + { + fprintf(STDERR, " %lu bytes at %x\n", + (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; + fprintf(STDERR, " CPU time used = %.3f seconds", + (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); + fprintf(STDERR, " (decoding %.3f,\n", + t_decode/(float)CLOCKS_PER_SEC); + fprintf(STDERR, " encoding %.3f ,", + t_encode/(float)CLOCKS_PER_SEC); + fprintf(STDERR, " other %.3f seconds)\n\n", + t_misc/(float)CLOCKS_PER_SEC); +#endif + + if (ierror == 0) + fprintf(STDERR, " libpng passes test\n"); + + else + fprintf(STDERR, " libpng FAILS test\n"); + + return (int)(ierror != 0); +} + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef png_libpng_version_1_5_8 Your_png_h_is_not_version_1_5_8; diff --git a/WDL/libpng/pngtrans.c b/WDL/libpng/pngtrans.c new file mode 100644 index 00000000..53d9a25b --- /dev/null +++ b/WDL/libpng/pngtrans.c @@ -0,0 +1,678 @@ + +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * Last changed in libpng 1.5.4 [July 7, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Turn on BGR-to-RGB mapping */ +void PNGAPI +png_set_bgr(png_structp png_ptr) +{ + png_debug(1, "in png_set_bgr"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_BGR; +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Turn on 16 bit byte swapping */ +void PNGAPI +png_set_swap(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth == 16) + png_ptr->transformations |= PNG_SWAP_BYTES; +} +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Turn on pixel packing */ +void PNGAPI +png_set_packing(png_structp png_ptr) +{ + png_debug(1, "in png_set_packing"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth < 8) + { + png_ptr->transformations |= PNG_PACK; + png_ptr->usr_bit_depth = 8; + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Turn on packed pixel swapping */ +void PNGAPI +png_set_packswap(png_structp png_ptr) +{ + png_debug(1, "in png_set_packswap"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth < 8) + png_ptr->transformations |= PNG_PACKSWAP; +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +void PNGAPI +png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) +{ + png_debug(1, "in png_set_shift"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_SHIFT; + png_ptr->shift = *true_bits; +} +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +int PNGAPI +png_set_interlace_handling(png_structp png_ptr) +{ + png_debug(1, "in png_set_interlace handling"); + + if (png_ptr && png_ptr->interlaced) + { + png_ptr->transformations |= PNG_INTERLACE; + return (7); + } + + return (1); +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte on read, or remove a filler or alpha byte on write. + * The filler type has changed in v0.95 to allow future 2-byte fillers + * for 48-bit input data, as well as to avoid problems with some compilers + * that don't like bytes as parameters. + */ +void PNGAPI +png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_filler"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_FILLER; + png_ptr->filler = (png_uint_16)filler; + + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; + + /* This should probably go in the "do_read_filler" routine. + * I attempted to do that in libpng-1.0.1a but that caused problems + * so I restored it in libpng-1.0.2a + */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_ptr->usr_channels = 4; + } + + /* Also I added this in libpng-1.0.2a (what happens when we expand + * a less-than-8-bit grayscale to GA?) */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + } +} + +/* Added to libpng-1.2.7 */ +void PNGAPI +png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_add_alpha"); + + if (png_ptr == NULL) + return; + + png_set_filler(png_ptr, filler, filler_loc); + png_ptr->transformations |= PNG_ADD_ALPHA; +} + +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void PNGAPI +png_set_swap_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_SWAP_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void PNGAPI +png_set_invert_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_INVERT_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +void PNGAPI +png_set_invert_mono(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_mono"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_INVERT_MONO; +} + +/* Invert monochrome grayscale data */ +void /* PRIVATE */ +png_do_invert(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_invert"); + + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_bytep rp = row; + png_size_t i; + png_size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(~(*rp)); + rp++; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 8) + { + png_bytep rp = row; + png_size_t i; + png_size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 2) + { + *rp = (png_byte)(~(*rp)); + rp += 2; + } + } + +#ifdef PNG_16BIT_SUPPORTED + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_size_t i; + png_size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 4) + { + *rp = (png_byte)(~(*rp)); + *(rp + 1) = (png_byte)(~(*(rp + 1))); + rp += 4; + } + } +#endif +} +#endif + +#ifdef PNG_16BIT_SUPPORTED +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swaps byte order on 16 bit depth images */ +void /* PRIVATE */ +png_do_swap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_swap"); + + if (row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop= row_info->width * row_info->channels; + + for (i = 0; i < istop; i++, rp += 2) + { + png_byte t = *rp; + *rp = *(rp + 1); + *(rp + 1) = t; + } + } +} +#endif +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +static PNG_CONST png_byte onebppswaptable[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 PNG_CONST png_byte twobppswaptable[256] = { + 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, + 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, + 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, + 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, + 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, + 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, + 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, + 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, + 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, + 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, + 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, + 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, + 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, + 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, + 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, + 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, + 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, + 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, + 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, + 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, + 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, + 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, + 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, + 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, + 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, + 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, + 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, + 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, + 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, + 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, + 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, + 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF +}; + +static PNG_CONST png_byte fourbppswaptable[256] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, + 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, + 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, + 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, + 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, + 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, + 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, + 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, + 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, + 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, + 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, + 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, + 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, + 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, + 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, + 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, + 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF +}; + +/* Swaps pixel packing order within bytes */ +void /* PRIVATE */ +png_do_packswap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_packswap"); + + if (row_info->bit_depth < 8) + { + png_bytep rp; + png_const_bytep end, table; + + end = row + row_info->rowbytes; + + if (row_info->bit_depth == 1) + table = onebppswaptable; + + else if (row_info->bit_depth == 2) + table = twobppswaptable; + + else if (row_info->bit_depth == 4) + table = fourbppswaptable; + + else + return; + + for (rp = row; rp < end; rp++) + *rp = table[*rp]; + } +} +#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +/* Remove a channel - this used to be 'png_do_strip_filler' but it used a + * somewhat weird combination of flags to determine what to do. All the calls + * to png_do_strip_filler are changed in 1.5.2 to call this instead with the + * correct arguments. + * + * The routine isn't general - the channel must be the channel at the start or + * end (not in the middle) of each pixel. + */ +void /* PRIVATE */ +png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) +{ + png_bytep sp = row; /* source pointer */ + png_bytep dp = row; /* destination pointer */ + png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + + /* At the start sp will point to the first byte to copy and dp to where + * it is copied to. ep always points just beyond the end of the row, so + * the loop simply copies (channels-1) channels until sp reaches ep. + * + * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. + * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. + */ + + /* GA, GX, XG cases */ + if (row_info->channels == 2) + { + if (row_info->bit_depth == 8) + { + if (at_start) /* Skip initial filler */ + ++sp; + else /* Skip initial channel and, for sp, the filler */ + sp += 2, ++dp; + + /* For a 1 pixel wide image there is nothing to do */ + while (sp < ep) + *dp++ = *sp, sp += 2; + + row_info->pixel_depth = 8; + } + + else if (row_info->bit_depth == 16) + { + if (at_start) /* Skip initial filler */ + sp += 2; + else /* Skip initial channel and, for sp, the filler */ + sp += 4, dp += 2; + + while (sp < ep) + *dp++ = *sp++, *dp++ = *sp, sp += 3; + + row_info->pixel_depth = 16; + } + + else + return; /* bad bit depth */ + + row_info->channels = 1; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_GRAY; + } + + /* RGBA, RGBX, XRGB cases */ + else if (row_info->channels == 4) + { + if (row_info->bit_depth == 8) + { + if (at_start) /* Skip initial filler */ + ++sp; + else /* Skip initial channels and, for sp, the filler */ + sp += 4, dp += 3; + + /* Note that the loop adds 3 to dp and 4 to sp each time. */ + while (sp < ep) + *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; + + row_info->pixel_depth = 24; + } + + else if (row_info->bit_depth == 16) + { + if (at_start) /* Skip initial filler */ + sp += 2; + else /* Skip initial channels and, for sp, the filler */ + sp += 8, dp += 6; + + while (sp < ep) + { + /* Copy 6 bytes, skip 2 */ + *dp++ = *sp++, *dp++ = *sp++; + *dp++ = *sp++, *dp++ = *sp++; + *dp++ = *sp++, *dp++ = *sp, sp += 3; + } + + row_info->pixel_depth = 48; + } + + else + return; /* bad bit depth */ + + row_info->channels = 3; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_RGB; + } + + else + return; /* The filler channel has gone already */ + + /* Fix the rowbytes value. */ + row_info->rowbytes = dp-row; +} +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Swaps red and blue bytes within a pixel */ +void /* PRIVATE */ +png_do_bgr(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_bgr"); + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 3) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 4) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + } + +#ifdef PNG_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 6) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 8) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + } +#endif + } +} +#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +void PNGAPI +png_set_user_transform_info(png_structp png_ptr, png_voidp + user_transform_ptr, int user_transform_depth, int user_transform_channels) +{ + png_debug(1, "in png_set_user_transform_info"); + + if (png_ptr == NULL) + return; + png_ptr->user_transform_ptr = user_transform_ptr; + png_ptr->user_transform_depth = (png_byte)user_transform_depth; + png_ptr->user_transform_channels = (png_byte)user_transform_channels; +} +#endif + +/* This function returns a pointer to the user_transform_ptr associated with + * the user transform functions. The application should free any memory + * associated with this pointer before png_write_destroy and png_read_destroy + * are called. + */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +png_voidp PNGAPI +png_get_user_transform_ptr(png_const_structp png_ptr) +{ + if (png_ptr == NULL) + return (NULL); + + return ((png_voidp)png_ptr->user_transform_ptr); +} +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +png_uint_32 PNGAPI +png_get_current_row_number(png_const_structp png_ptr) +{ + /* See the comments in png.h - this is the sub-image row when reading and + * interlaced image. + */ + if (png_ptr != NULL) + return png_ptr->row_number; + + return PNG_UINT_32_MAX; /* help the app not to fail silently */ +} + +png_byte PNGAPI +png_get_current_pass_number(png_const_structp png_ptr) +{ + if (png_ptr != NULL) + return png_ptr->pass; + return 8; /* invalid */ +} +#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ +#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || + PNG_WRITE_USER_TRANSFORM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwio.c b/WDL/libpng/pngwio.c new file mode 100644 index 00000000..8eacf9f6 --- /dev/null +++ b/WDL/libpng/pngwio.c @@ -0,0 +1,254 @@ + +/* pngwio.c - functions for data output + * + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all output. Users who need + * special handling are expected to write functions that have the same + * arguments as these and perform similar functions, but that possibly + * use different output methods. Note that you shouldn't change these + * functions, but rather write replacement functions and then change + * them at run time with png_set_write_fn(...). + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +/* Write the data to whatever output you are using. The default routine + * writes to a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered writes. This should never be asked + * to write more than 64K on a 16 bit machine. + */ + +void /* PRIVATE */ +png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) +{ + /* NOTE: write_data_fn must not change the buffer! */ + if (png_ptr->write_data_fn != NULL ) + (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); + + else + png_error(png_ptr, "Call to NULL write function"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* This is the function that does the actual writing of data. If you are + * not writing to a standard C stream, you should create a replacement + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ +#ifndef USE_FAR_KEYWORD +void PNGCBAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + if (png_ptr == NULL) + return; + + check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); + + if (check != length) + png_error(png_ptr, "Write Error"); +} +#else +/* This is the model-independent version. Since the standard I/O library + * can't handle far buffers in the medium and small models, we have to copy + * the data. + */ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +void PNGCBAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + if (png_ptr == NULL) + return; + + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + + if ((png_bytep)near_data == data) + { + check = fwrite(near_data, 1, length, io_ptr); + } + + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ + err = fwrite(buf, 1, written, io_ptr); + + if (err != written) + break; + + else + check += err; + + data += written; + remaining -= written; + } + while (remaining != 0); + } + + if (check != length) + png_error(png_ptr, "Write Error"); +} + +#endif +#endif + +/* This function is called to output any data pending writing (normally + * to disk). After png_flush is called, there should be no data pending + * writing in any buffers. + */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED +void /* PRIVATE */ +png_flush(png_structp png_ptr) +{ + if (png_ptr->output_flush_fn != NULL) + (*(png_ptr->output_flush_fn))(png_ptr); +} + +# ifdef PNG_STDIO_SUPPORTED +void PNGCBAPI +png_default_flush(png_structp png_ptr) +{ + png_FILE_p io_ptr; + + if (png_ptr == NULL) + return; + + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + fflush(io_ptr); +} +# endif +#endif + +/* This function allows the application to supply new output functions for + * libpng if standard C streams aren't being used. + * + * This function takes as its arguments: + * png_ptr - pointer to a png output data structure + * io_ptr - pointer to user supplied structure containing info about + * the output functions. May be NULL. + * write_data_fn - pointer to a new output function that takes as its + * arguments a pointer to a png_struct, a pointer to + * data to be written, and a 32-bit unsigned int that is + * the number of bytes to be written. The new write + * function should call png_error(png_ptr, "Error msg") + * to exit and output any fatal error messages. May be + * NULL, in which case libpng's default function will + * be used. + * flush_data_fn - pointer to a new flush function that takes as its + * arguments a pointer to a png_struct. After a call to + * the flush function, there should be no data in any buffers + * or pending transmission. If the output method doesn't do + * any buffering of output, a function prototype must still be + * supplied although it doesn't have to do anything. If + * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile + * time, output_flush_fn will be ignored, although it must be + * supplied for compatibility. May be NULL, in which case + * libpng's default function will be used, if + * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not + * a good idea if io_ptr does not point to a standard + * *FILE structure. + */ +void PNGAPI +png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + +#ifdef PNG_STDIO_SUPPORTED + if (write_data_fn != NULL) + png_ptr->write_data_fn = write_data_fn; + + else + png_ptr->write_data_fn = png_default_write_data; +#else + png_ptr->write_data_fn = write_data_fn; +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED + + if (output_flush_fn != NULL) + png_ptr->output_flush_fn = output_flush_fn; + + else + png_ptr->output_flush_fn = png_default_flush; + +# else + png_ptr->output_flush_fn = output_flush_fn; +# endif +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { + png_ptr->read_data_fn = NULL; + + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +} + +#ifdef USE_FAR_KEYWORD +# ifdef _MSC_VER +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + FP_OFF(near_ptr) = FP_OFF(ptr); + far_ptr = (void FAR *)near_ptr; + + if (check != 0) + if (FP_SEG(ptr) != FP_SEG(far_ptr)) + png_error(png_ptr, "segment lost in conversion"); + + return(near_ptr); +} +# else +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + near_ptr = (void FAR *)ptr; + far_ptr = (void FAR *)near_ptr; + + if (check != 0) + if (far_ptr != ptr) + png_error(png_ptr, "segment lost in conversion"); + + return(near_ptr); +} +# endif +#endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwrite.c b/WDL/libpng/pngwrite.c new file mode 100644 index 00000000..dc12a204 --- /dev/null +++ b/WDL/libpng/pngwrite.c @@ -0,0 +1,1655 @@ + +/* pngwrite.c - general routines to write a PNG file + * + * Last changed in libpng 1.5.7 [December 15, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +/* Writes all the PNG information. This is the suggested way to use the + * library. If you have a new chunk to add, make a function to write it, + * and put it in the correct location here. If you want the chunk written + * after the image data, put it in png_write_end(). I strongly encourage + * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing + * the chunk, as that will keep the code from breaking if you want to just + * write a plain PNG file. If you have long comments, I suggest writing + * them in png_write_end(), and compressing them. + */ +void PNGAPI +png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_info_before_PLTE"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + { + /* Write PNG signature */ + png_write_sig(png_ptr); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ + (png_ptr->mng_features_permitted)) + { + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted = 0; + } +#endif + + /* Write IHDR information. */ + png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + info_ptr->interlace_type); +#else + 0); +#endif + /* The rest of these check to see if the valid field has the appropriate + * flag set, and if it does, writes the chunk. + */ +#ifdef PNG_WRITE_gAMA_SUPPORTED + if (info_ptr->valid & PNG_INFO_gAMA) + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); +#endif +#ifdef PNG_WRITE_sRGB_SUPPORTED + if (info_ptr->valid & PNG_INFO_sRGB) + png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED + if (info_ptr->valid & PNG_INFO_iCCP) + png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, + (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +#endif +#ifdef PNG_WRITE_sBIT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sBIT) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); +#endif +#ifdef PNG_WRITE_cHRM_SUPPORTED + if (info_ptr->valid & PNG_INFO_cHRM) + png_write_cHRM_fixed(png_ptr, + info_ptr->x_white, info_ptr->y_white, + info_ptr->x_red, info_ptr->y_red, + info_ptr->x_green, info_ptr->y_green, + info_ptr->x_blue, info_ptr->y_blue); +#endif + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep = png_handle_as_unknown(png_ptr, up->name); + + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && + !(up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + !(up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + if (up->size == 0) + png_warning(png_ptr, "Writing zero-length unknown chunk"); + + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void PNGAPI +png_write_info(png_structp png_ptr, png_infop info_ptr) +{ +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) + int i; +#endif + + png_debug(1, "in png_write_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_write_info_before_PLTE(png_ptr, info_ptr); + + if (info_ptr->valid & PNG_INFO_PLTE) + png_write_PLTE(png_ptr, info_ptr->palette, + (png_uint_32)info_ptr->num_palette); + + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Valid palette required for paletted images"); + +#ifdef PNG_WRITE_tRNS_SUPPORTED + if (info_ptr->valid & PNG_INFO_tRNS) + { +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + /* Invert the alpha channel (in tRNS) */ + if ((png_ptr->transformations & PNG_INVERT_ALPHA) && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j; + for (j = 0; j<(int)info_ptr->num_trans; j++) + info_ptr->trans_alpha[j] = + (png_byte)(255 - info_ptr->trans_alpha[j]); + } +#endif + png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), + info_ptr->num_trans, info_ptr->color_type); + } +#endif +#ifdef PNG_WRITE_bKGD_SUPPORTED + if (info_ptr->valid & PNG_INFO_bKGD) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED + if (info_ptr->valid & PNG_INFO_hIST) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED + if (info_ptr->valid & PNG_INFO_oFFs) + png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, + info_ptr->offset_unit_type); +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED + if (info_ptr->valid & PNG_INFO_pCAL) + png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED + if (info_ptr->valid & PNG_INFO_sCAL) + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); +#endif /* sCAL */ + +#ifdef PNG_WRITE_pHYs_SUPPORTED + if (info_ptr->valid & PNG_INFO_pHYs) + png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); +#endif /* pHYs */ + +#ifdef PNG_WRITE_tIME_SUPPORTED + if (info_ptr->valid & PNG_INFO_tIME) + { + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + png_ptr->mode |= PNG_WROTE_tIME; + } +#endif /* tIME */ + +#ifdef PNG_WRITE_sPLT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sPLT) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); +#endif /* sPLT */ + +#ifdef PNG_WRITE_TEXT_SUPPORTED + /* Check to see if we need to write text chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing header text chunk %d, type %d", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef PNG_WRITE_iTXt_SUPPORTED + /* Write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + + /* If we want a compressed text chunk */ + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) + { +#ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, + 0); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; +#else + /* Can't get here */ + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + } + } +#endif /* tEXt */ + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep = png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && + (up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + !(up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif +} + +/* Writes the end of the PNG file. If you don't want to write comments or + * time information, you can pass NULL for info. If you already wrote these + * in png_write_info(), do not write them again here. If you have long + * comments, I suggest writing them here, and compressing them. + */ +void PNGAPI +png_write_end(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_end"); + + if (png_ptr == NULL) + return; + + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "No IDATs written into file"); + + /* See if user wants us to write information chunks */ + if (info_ptr != NULL) + { +#ifdef PNG_WRITE_TEXT_SUPPORTED + int i; /* local index variable */ +#endif +#ifdef PNG_WRITE_tIME_SUPPORTED + /* Check to see if user has supplied a time chunk */ + if ((info_ptr->valid & PNG_INFO_tIME) && + !(png_ptr->mode & PNG_WROTE_tIME)) + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + +#endif +#ifdef PNG_WRITE_TEXT_SUPPORTED + /* Loop through comment chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing trailer text chunk %d, type %d", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef PNG_WRITE_iTXt_SUPPORTED + /* Write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) + { +#ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0); +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } +#endif +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep = png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && + (up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + } + + png_ptr->mode |= PNG_AFTER_IDAT; + + /* Write end of PNG file */ + png_write_IEND(png_ptr); + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, + * and restored again in libpng-1.2.30, may cause some applications that + * do not set png_ptr->output_flush_fn to crash. If your application + * experiences a problem, please try building libpng with + * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to + * png-mng-implement at lists.sf.net . + */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED + png_flush(png_ptr); +# endif +#endif +} + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* "tm" structure is not supported on WindowsCE */ +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) +{ + png_debug(1, "in png_convert_from_struct_tm"); + + ptime->year = (png_uint_16)(1900 + ttime->tm_year); + ptime->month = (png_byte)(ttime->tm_mon + 1); + ptime->day = (png_byte)ttime->tm_mday; + ptime->hour = (png_byte)ttime->tm_hour; + ptime->minute = (png_byte)ttime->tm_min; + ptime->second = (png_byte)ttime->tm_sec; +} + +void PNGAPI +png_convert_from_time_t(png_timep ptime, time_t ttime) +{ + struct tm *tbuf; + + png_debug(1, "in png_convert_from_time_t"); + + tbuf = gmtime(&ttime); + png_convert_from_struct_tm(ptime, tbuf); +} +#endif + +/* Initialize png_ptr structure, and allocate any memory needed */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL)); +} + +/* Alternate initialize png_ptr structure, and allocate any memory needed */ +static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ + +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + volatile int png_cleanup_needed = 0; +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif + png_structp png_ptr; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf tmp_jmpbuf; +#endif +#endif + + png_debug(1, "in png_create_write_struct"); + +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL) + return (NULL); + + /* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max = PNG_USER_WIDTH_MAX; + png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then + * encounter a png_error() will longjmp here. Since the jmpbuf is + * then meaningless we abort instead of returning. + */ +#ifdef USE_FAR_KEYWORD + if (setjmp(tmp_jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ +#endif +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +#endif + PNG_ABORT(); +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif /* PNG_USER_MEM_SUPPORTED */ + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + if (!png_user_version_check(png_ptr, user_png_ver)) + png_cleanup_needed = 1; + + /* Initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + + if (!png_cleanup_needed) + { + png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, + png_ptr->zbuf_size); + if (png_ptr->zbuf == NULL) + png_cleanup_needed = 1; + } + + if (png_cleanup_needed) + { + /* Clean up PNG structure and deallocate any memory. */ + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, + (png_free_ptr)free_fn, (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + return (NULL); + } + + png_set_write_fn(png_ptr, NULL, NULL, NULL); + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + png_reset_filter_heuristics(png_ptr); +#endif + + return (png_ptr); +} + + +/* Write a few rows of image data. If the image is interlaced, + * either you will have to write the 7 sub images, or, if you + * have called png_set_interlace_handling(), you will have to + * "write" the image seven times. + */ +void PNGAPI +png_write_rows(png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows) +{ + png_uint_32 i; /* row counter */ + png_bytepp rp; /* row pointer */ + + png_debug(1, "in png_write_rows"); + + if (png_ptr == NULL) + return; + + /* Loop through the rows */ + for (i = 0, rp = row; i < num_rows; i++, rp++) + { + png_write_row(png_ptr, *rp); + } +} + +/* Write the image. You only need to call this function once, even + * if you are writing an interlaced image. + */ +void PNGAPI +png_write_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i; /* row index */ + int pass, num_pass; /* pass variables */ + png_bytepp rp; /* points to current row */ + + if (png_ptr == NULL) + return; + + png_debug(1, "in png_write_image"); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Initialize interlace handling. If image is not interlaced, + * this will set pass to 1 + */ + num_pass = png_set_interlace_handling(png_ptr); +#else + num_pass = 1; +#endif + /* Loop through passes */ + for (pass = 0; pass < num_pass; pass++) + { + /* Loop through image */ + for (i = 0, rp = image; i < png_ptr->height; i++, rp++) + { + png_write_row(png_ptr, *rp); + } + } +} + +/* Called by user to write a row of image data */ +void PNGAPI +png_write_row(png_structp png_ptr, png_const_bytep row) +{ + /* 1.5.6: moved from png_struct to be a local structure: */ + png_row_info row_info; + + if (png_ptr == NULL) + return; + + png_debug2(1, "in png_write_row (row %u, pass %d)", + png_ptr->row_number, png_ptr->pass); + + /* Initialize transformations and other stuff if first time */ + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Make sure we wrote the header info */ + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + png_error(png_ptr, + "png_write_info was never called before png_write_row"); + + /* Check for transforms that have been set but were defined out */ +#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); +#endif +#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, + "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); +#endif + + png_write_start_row(png_ptr); + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced and not interested in row, return */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 3: + if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 4: + if ((png_ptr->row_number & 0x03) != 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 5: + if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 6: + if (!(png_ptr->row_number & 0x01)) + { + png_write_finish_row(png_ptr); + return; + } + break; + + default: /* error: ignore it */ + break; + } + } +#endif + + /* Set up row info for transformations */ + row_info.color_type = png_ptr->color_type; + row_info.width = png_ptr->usr_width; + row_info.channels = png_ptr->usr_channels; + row_info.bit_depth = png_ptr->usr_bit_depth; + row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + png_debug1(3, "row_info->color_type = %d", row_info.color_type); + png_debug1(3, "row_info->width = %u", row_info.width); + png_debug1(3, "row_info->channels = %d", row_info.channels); + png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ + png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && + (png_ptr->transformations & PNG_INTERLACE)) + { + png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); + /* This should always get caught above, but still ... */ + if (!(row_info.width)) + { + png_write_finish_row(png_ptr); + return; + } + } +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED + /* Handle other transformations */ + if (png_ptr->transformations) + png_do_write_transformations(png_ptr, &row_info); +#endif + + /* At this point the row_info pixel depth must match the 'transformed' depth, + * which is also the output depth. + */ + if (row_info.pixel_depth != png_ptr->pixel_depth || + row_info.pixel_depth != png_ptr->transformed_pixel_depth) + png_error(png_ptr, "internal write transform logic error"); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); + } +#endif + + /* Find a filter if necessary, filter the row and write it out. */ + png_write_find_filter(png_ptr, &row_info); + + if (png_ptr->write_row_fn != NULL) + (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set the automatic flush interval or 0 to turn flushing off */ +void PNGAPI +png_set_flush(png_structp png_ptr, int nrows) +{ + png_debug(1, "in png_set_flush"); + + if (png_ptr == NULL) + return; + + png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); +} + +/* Flush the current output buffers now */ +void PNGAPI +png_write_flush(png_structp png_ptr) +{ + int wrote_IDAT; + + png_debug(1, "in png_write_flush"); + + if (png_ptr == NULL) + return; + + /* We have already written out all of the data */ + if (png_ptr->row_number >= png_ptr->num_rows) + return; + + do + { + int ret; + + /* Compress the data */ + ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); + wrote_IDAT = 0; + + /* Check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + + else + png_error(png_ptr, "zlib error"); + } + + if (!(png_ptr->zstream.avail_out)) + { + /* Write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + wrote_IDAT = 1; + } + } while (wrote_IDAT == 1); + + /* If there is any data left to be output, write it into a new IDAT */ + if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) + { + /* Write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + } + png_ptr->flush_rows = 0; + png_flush(png_ptr); +} +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + +/* Free all memory used by the write */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn = NULL; + png_voidp mem_ptr = NULL; +#endif + + png_debug(1, "in png_destroy_write_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr != NULL) + { + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; + } +#endif + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + if (png_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->num_chunk_list = 0; + } +#endif + } + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { + png_write_destroy(png_ptr); +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + + +/* Free any memory used in png_ptr struct (old method) */ +void /* PRIVATE */ +png_write_destroy(png_structp png_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* Save jump buffer */ +#endif + png_error_ptr error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; +#endif + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_write_destroy"); + + /* Free any memory zlib uses */ + if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) + deflateEnd(&png_ptr->zstream); + + /* Free our memory. png_free checks NULL for us. */ + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->row_buf); +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->sub_row); + png_free(png_ptr, png_ptr->up_row); + png_free(png_ptr, png_ptr->avg_row); + png_free(png_ptr, png_ptr->paeth_row); +#endif + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + /* Use this to save a little code space, it doesn't free the filter_costs */ + png_reset_filter_heuristics(png_ptr); + png_free(png_ptr, png_ptr->filter_costs); + png_free(png_ptr, png_ptr->inv_filter_costs); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Reset structure */ + png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + warning_fn = png_ptr->warning_fn; +#endif + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof(png_struct)); + + png_ptr->error_fn = error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#endif + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); +#endif +} + +/* Allow the application to select one or more row filters to use. */ +void PNGAPI +png_set_filter(png_structp png_ptr, int method, int filters) +{ + png_debug(1, "in png_set_filter"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; + +#endif + if (method == PNG_FILTER_TYPE_BASE) + { + switch (filters & (PNG_ALL_FILTERS | 0x07)) + { +#ifdef PNG_WRITE_FILTER_SUPPORTED + case 5: + case 6: + case 7: png_warning(png_ptr, "Unknown row filter for method 0"); +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + case PNG_FILTER_VALUE_NONE: + png_ptr->do_filter = PNG_FILTER_NONE; break; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + case PNG_FILTER_VALUE_SUB: + png_ptr->do_filter = PNG_FILTER_SUB; break; + + case PNG_FILTER_VALUE_UP: + png_ptr->do_filter = PNG_FILTER_UP; break; + + case PNG_FILTER_VALUE_AVG: + png_ptr->do_filter = PNG_FILTER_AVG; break; + + case PNG_FILTER_VALUE_PAETH: + png_ptr->do_filter = PNG_FILTER_PAETH; break; + + default: + png_ptr->do_filter = (png_byte)filters; break; +#else + default: + png_warning(png_ptr, "Unknown row filter for method 0"); +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + } + + /* If we have allocated the row_buf, this means we have already started + * with the image and we should have allocated all of the filter buffers + * that have been selected. If prev_row isn't already allocated, then + * it is too late to start using the filters that need it, since we + * will be missing the data in the previous row. If an application + * wants to start and stop using particular filters during compression, + * it should start out with all of the filters, and then add and + * remove them after the start of compression. + */ + if (png_ptr->row_buf != NULL) + { +#ifdef PNG_WRITE_FILTER_SUPPORTED + if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Up filter after starting"); + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_UP); + } + + else + { + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Average filter after starting"); + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_AVG); + } + + else + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_PAETH) && + png_ptr->paeth_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Paeth filter after starting"); + png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); + } + + else + { + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } + + if (png_ptr->do_filter == PNG_NO_FILTERS) +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + png_ptr->do_filter = PNG_FILTER_NONE; + } + } + else + png_error(png_ptr, "Unknown custom filter method"); +} + +/* This allows us to influence the way in which libpng chooses the "best" + * filter for the current scanline. While the "minimum-sum-of-absolute- + * differences metric is relatively fast and effective, there is some + * question as to whether it can be improved upon by trying to keep the + * filtered data going to zlib more consistent, hopefully resulting in + * better compression. + */ +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ +/* Convenience reset API. */ +static void +png_reset_filter_heuristics(png_structp png_ptr) +{ + /* Clear out any old values in the 'weights' - this must be done because if + * the app calls set_filter_heuristics multiple times with different + * 'num_weights' values we would otherwise potentially have wrong sized + * arrays. + */ + png_ptr->num_prev_filters = 0; + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + if (png_ptr->prev_filters != NULL) + { + png_bytep old = png_ptr->prev_filters; + png_ptr->prev_filters = NULL; + png_free(png_ptr, old); + } + if (png_ptr->filter_weights != NULL) + { + png_uint_16p old = png_ptr->filter_weights; + png_ptr->filter_weights = NULL; + png_free(png_ptr, old); + } + + if (png_ptr->inv_filter_weights != NULL) + { + png_uint_16p old = png_ptr->inv_filter_weights; + png_ptr->inv_filter_weights = NULL; + png_free(png_ptr, old); + } + + /* Leave the filter_costs - this array is fixed size. */ +} + +static int +png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights) +{ + if (png_ptr == NULL) + return 0; + + /* Clear out the arrays */ + png_reset_filter_heuristics(png_ptr); + + /* Check arguments; the 'reset' function makes the correct settings for the + * unweighted case, but we must handle the weight case by initializing the + * arrays for the caller. + */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + + if (num_weights > 0) + { + png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_byte) * num_weights)); + + /* To make sure that the weighting starts out fairly */ + for (i = 0; i < num_weights; i++) + { + png_ptr->prev_filters[i] = 255; + } + + png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + for (i = 0; i < num_weights; i++) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + /* Safe to set this now */ + png_ptr->num_prev_filters = (png_byte)num_weights; + } + + /* If, in the future, there are other filter methods, this would + * need to be based on png_ptr->filter. + */ + if (png_ptr->filter_costs == NULL) + { + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + } + + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + { + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; + } + + /* All the arrays are inited, safe to set this: */ + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; + + /* Return the 'ok' code. */ + return 1; + } + else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) + { + return 1; + } + else + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return 0; + } +} + +/* Provide floating and fixed point APIs */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] <= 0.0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); + + png_ptr->filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) + { + png_ptr->inv_filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); + + png_ptr->filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); + } + } +} +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics_fixed"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] <= 0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = (png_uint_16) + ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); + + png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* + PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + if (filter_costs[i] >= PNG_FP_1) + { + png_uint_32 tmp; + + /* Use a 32 bit unsigned temporary here because otherwise the + * intermediate value will be a 32 bit *signed* integer (ANSI rules) + * and this will get the wrong answer on division. + */ + tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); + tmp /= filter_costs[i]; + + png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; + + tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; + tmp /= PNG_FP_1; + + png_ptr->filter_costs[i] = (png_uint_16)tmp; + } + } +} +#endif /* FIXED_POINT */ +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +void PNGAPI +png_set_compression_level(png_structp png_ptr, int level) +{ + png_debug(1, "in png_set_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; + png_ptr->zlib_level = level; +} + +void PNGAPI +png_set_compression_mem_level(png_structp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; + png_ptr->zlib_mem_level = mem_level; +} + +void PNGAPI +png_set_compression_strategy(png_structp png_ptr, int strategy) +{ + png_debug(1, "in png_set_compression_strategy"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +void PNGAPI +png_set_compression_window_bits(png_structp png_ptr, int window_bits) +{ + if (png_ptr == NULL) + return; + + if (window_bits > 15) + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + + else if (window_bits < 8) + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + +#ifndef WBITS_8_OK + /* Avoid libpng bug with 256-byte windows */ + if (window_bits == 8) + { + png_warning(png_ptr, "Compression window is being reset to 512"); + window_bits = 9; + } + +#endif + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; + png_ptr->zlib_window_bits = window_bits; +} + +void PNGAPI +png_set_compression_method(png_structp png_ptr, int method) +{ + png_debug(1, "in png_set_compression_method"); + + if (png_ptr == NULL) + return; + + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; + png_ptr->zlib_method = method; +} + +/* The following were added to libpng-1.5.4 */ +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +void PNGAPI +png_set_text_compression_level(png_structp png_ptr, int level) +{ + png_debug(1, "in png_set_text_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; + png_ptr->zlib_text_level = level; +} + +void PNGAPI +png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_text_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; + png_ptr->zlib_text_mem_level = mem_level; +} + +void PNGAPI +png_set_text_compression_strategy(png_structp png_ptr, int strategy) +{ + png_debug(1, "in png_set_text_compression_strategy"); + + if (png_ptr == NULL) + return; + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; + png_ptr->zlib_text_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +void PNGAPI +png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) +{ + if (png_ptr == NULL) + return; + + if (window_bits > 15) + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + + else if (window_bits < 8) + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + +#ifndef WBITS_8_OK + /* Avoid libpng bug with 256-byte windows */ + if (window_bits == 8) + { + png_warning(png_ptr, "Text compression window is being reset to 512"); + window_bits = 9; + } + +#endif + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; + png_ptr->zlib_text_window_bits = window_bits; +} + +void PNGAPI +png_set_text_compression_method(png_structp png_ptr, int method) +{ + png_debug(1, "in png_set_text_compression_method"); + + if (png_ptr == NULL) + return; + + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + + png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; + png_ptr->zlib_text_method = method; +} +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +/* end of API added to libpng-1.5.4 */ + +void PNGAPI +png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->write_row_fn = write_row_fn; +} + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +void PNGAPI +png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + write_user_transform_fn) +{ + png_debug(1, "in png_set_write_user_transform_fn"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->write_user_transform_fn = write_user_transform_fn; +} +#endif + + +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_write_png(png_structp png_ptr, png_infop info_ptr, + int transforms, voidp params) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + +#ifdef PNG_WRITE_INVERT_SUPPORTED + /* Invert monochrome pixels */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && (info_ptr->valid & PNG_INFO_sBIT)) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED + /* Pack pixels into bytes */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + /* Swap location of alpha bytes from ARGB to RGBA */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#ifdef PNG_WRITE_FILLER_SUPPORTED + /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ + if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + + else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#endif + +#ifdef PNG_WRITE_BGR_SUPPORTED + /* Flip BGR pixels to RGB */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#ifdef PNG_WRITE_SWAP_SUPPORTED + /* Swap bytes of 16-bit files to most significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + /* Swap bits of 1, 2, 4 bit packed pixel formats */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + /* Invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + + /* ----------------------- end of transformations ------------------- */ + + /* Write the bits */ + if (info_ptr->valid & PNG_INFO_IDAT) + png_write_image(png_ptr, info_ptr->row_pointers); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) +} +#endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwtran.c b/WDL/libpng/pngwtran.c new file mode 100644 index 00000000..b598149a --- /dev/null +++ b/WDL/libpng/pngwtran.c @@ -0,0 +1,633 @@ + +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Last changed in libpng 1.5.6 [November 3, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ +void /* PRIVATE */ +png_do_write_transformations(png_structp png_ptr, png_row_infop row_info) +{ + png_debug(1, "in png_do_write_transformations"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + if (png_ptr->transformations & PNG_USER_TRANSFORM) + if (png_ptr->write_user_transform_fn != NULL) + (*(png_ptr->write_user_transform_fn)) /* User write transform + function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#endif + +#ifdef PNG_WRITE_FILLER_SUPPORTED + if (png_ptr->transformations & PNG_FILLER) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); +#endif + +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED + if (png_ptr->transformations & PNG_PACK) + png_do_pack(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif + +#ifdef PNG_WRITE_SWAP_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if (png_ptr->transformations & PNG_SHIFT) + png_do_shift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_BGR_SUPPORTED + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_SUPPORTED + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif +} + +#ifdef PNG_WRITE_PACK_SUPPORTED +/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The + * row_info bit depth should be 8 (one pixel per byte). The channels + * should be 1 (this only happens on grayscale and paletted images). + */ +void /* PRIVATE */ +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) +{ + png_debug(1, "in png_do_pack"); + + if (row_info->bit_depth == 8 && + row_info->channels == 1) + { + switch ((int)bit_depth) + { + case 1: + { + png_bytep sp, dp; + int mask, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + mask = 0x80; + v = 0; + + for (i = 0; i < row_width; i++) + { + if (*sp != 0) + v |= mask; + + sp++; + + if (mask > 1) + mask >>= 1; + + else + { + mask = 0x80; + *dp = (png_byte)v; + dp++; + v = 0; + } + } + + if (mask != 0x80) + *dp = (png_byte)v; + + break; + } + + case 2: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 6; + v = 0; + + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x03); + v |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp = (png_byte)v; + dp++; + v = 0; + } + + else + shift -= 2; + + sp++; + } + + if (shift != 6) + *dp = (png_byte)v; + + break; + } + + case 4: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 4; + v = 0; + + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x0f); + v |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp = (png_byte)v; + dp++; + v = 0; + } + + else + shift -= 4; + + sp++; + } + + if (shift != 4) + *dp = (png_byte)v; + + break; + } + + default: + break; + } + + row_info->bit_depth = (png_byte)bit_depth; + row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED +/* Shift pixel values to take advantage of whole range. Pass the + * true number of bits in bit_depth. The row should be packed + * according to row_info->bit_depth. Thus, if you had a row of + * bit depth 4, but the pixels only had values from 0 to 7, you + * would pass 3 as bit_depth, and this routine would translate the + * data to 0 to 15. + */ +void /* PRIVATE */ +png_do_shift(png_row_infop row_info, png_bytep row, + png_const_color_8p bit_depth) +{ + png_debug(1, "in png_do_shift"); + + if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift_start[4], shift_dec[4]; + int channels = 0; + + if (row_info->color_type & PNG_COLOR_MASK_COLOR) + { + shift_start[channels] = row_info->bit_depth - bit_depth->red; + shift_dec[channels] = bit_depth->red; + channels++; + + shift_start[channels] = row_info->bit_depth - bit_depth->green; + shift_dec[channels] = bit_depth->green; + channels++; + + shift_start[channels] = row_info->bit_depth - bit_depth->blue; + shift_dec[channels] = bit_depth->blue; + channels++; + } + + else + { + shift_start[channels] = row_info->bit_depth - bit_depth->gray; + shift_dec[channels] = bit_depth->gray; + channels++; + } + + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; + shift_dec[channels] = bit_depth->alpha; + channels++; + } + + /* With low row depths, could only be grayscale, so one channel */ + if (row_info->bit_depth < 8) + { + png_bytep bp = row; + png_size_t i; + png_byte mask; + png_size_t row_bytes = row_info->rowbytes; + + if (bit_depth->gray == 1 && row_info->bit_depth == 2) + mask = 0x55; + + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) + mask = 0x11; + + else + mask = 0xff; + + for (i = 0; i < row_bytes; i++, bp++) + { + png_uint_16 v; + int j; + + v = *bp; + *bp = 0; + + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + + else + *bp |= (png_byte)((v >> (-j)) & mask); + } + } + } + + else if (row_info->bit_depth == 8) + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (i = 0; i < istop; i++, bp++) + { + + png_uint_16 v; + int j; + int c = (int)(i%channels); + + v = *bp; + *bp = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + + else + *bp |= (png_byte)((v >> (-j)) & 0xff); + } + } + } + + else + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (bp = row, i = 0; i < istop; i++) + { + int c = (int)(i%channels); + png_uint_16 value, v; + int j; + + v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); + value = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); + + else + value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); + } + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + } + } +} +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_swap_alpha"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from ARGB to RGBA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AARRGGBB to RRGGBBAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from AG to GA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AAGG to GGAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + } +} +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_invert_alpha"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=3; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in RRGGBBAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=6; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + *(dp++) = *(sp++); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=2; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } + } +} +#endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_intrapixel"); + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); + *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); + } + } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/libpng/pngwutil.c b/WDL/libpng/pngwutil.c new file mode 100644 index 00000000..64888f7c --- /dev/null +++ b/WDL/libpng/pngwutil.c @@ -0,0 +1,3180 @@ + +/* pngwutil.c - utilities to write a PNG file + * + * Last changed in libpng 1.5.6 [November 3, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +/* Place a 32-bit number into a buffer in PNG byte order. We work + * with unsigned numbers for convenience, although one supported + * ancillary chunk uses signed (two's complement) numbers. + */ +void PNGAPI +png_save_uint_32(png_bytep buf, png_uint_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} + +#ifdef PNG_SAVE_INT_32_SUPPORTED +/* The png_save_int_32 function assumes integers are stored in two's + * complement format. If this isn't the case, then this routine needs to + * be modified to write data in two's complement format. Note that, + * the following works correctly even if png_int_32 has more than 32 bits + * (compare the more complex code required on read for sign extention.) + */ +void PNGAPI +png_save_int_32(png_bytep buf, png_int_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +void PNGAPI +png_save_uint_16(png_bytep buf, unsigned int i) +{ + buf[0] = (png_byte)((i >> 8) & 0xff); + buf[1] = (png_byte)(i & 0xff); +} +#endif + +/* Simple function to write the signature. If we have already written + * the magic bytes of the signature, or more likely, the PNG stream is + * being embedded into another stream and doesn't need its own signature, + * we should call png_set_sig_bytes() to tell libpng how many of the + * bytes have already been written. + */ +void PNGAPI +png_write_sig(png_structp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the signature is being written */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; +#endif + + /* Write the rest of the 8 byte signature */ + png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], + (png_size_t)(8 - png_ptr->sig_bytes)); + + if (png_ptr->sig_bytes < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +/* Write the start of a PNG chunk. The type is the chunk type. + * The total_length is the sum of the lengths of all the data you will be + * passing in png_write_chunk_data(). + */ +static void +png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, + png_uint_32 length) +{ + png_byte buf[8]; + +#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) + PNG_CSTRING_FROM_CHUNK(buf, chunk_name); + png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); +#endif + + if (png_ptr == NULL) + return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk header is being written. + * PNG_IO_CHUNK_HDR requires a single I/O call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; +#endif + + /* Write the length and the chunk name */ + png_save_uint_32(buf, length); + png_save_uint_32(buf + 4, chunk_name); + png_write_data(png_ptr, buf, 8); + + /* Put the chunk name into png_ptr->chunk_name */ + png_ptr->chunk_name = chunk_name; + + /* Reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + + png_calculate_crc(png_ptr, buf + 4, 4); + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that chunk data will (possibly) be written. + * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; +#endif +} + +void PNGAPI +png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, + png_uint_32 length) +{ + png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); +} + +/* Write the data of a PNG chunk started with png_write_chunk_header(). + * Note that multiple calls to this function are allowed, and that the + * sum of the lengths from these calls *must* add up to the total_length + * given to png_write_chunk_header(). + */ +void PNGAPI +png_write_chunk_data(png_structp png_ptr, png_const_bytep data, + png_size_t length) +{ + /* Write the data, and run the CRC over it */ + if (png_ptr == NULL) + return; + + if (data != NULL && length > 0) + { + png_write_data(png_ptr, data, length); + + /* Update the CRC after writing the data, + * in case that the user I/O routine alters it. + */ + png_calculate_crc(png_ptr, data, length); + } +} + +/* Finish a chunk started with png_write_chunk_header(). */ +void PNGAPI +png_write_chunk_end(png_structp png_ptr) +{ + png_byte buf[4]; + + if (png_ptr == NULL) return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk CRC is being written. + * PNG_IO_CHUNK_CRC requires a single I/O function call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; +#endif + + /* Write the crc in a single operation */ + png_save_uint_32(buf, png_ptr->crc); + + png_write_data(png_ptr, buf, (png_size_t)4); +} + +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +static void +png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, png_size_t length) +{ + if (png_ptr == NULL) + return; + + /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ + if (length > PNG_UINT_32_MAX) + png_error(png_ptr, "length exceeds PNG maxima"); + + png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* This is the API that calls the internal function above. */ +void PNGAPI +png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, + png_const_bytep data, png_size_t length) +{ + png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, + length); +} + +/* Initialize the compressor for the appropriate type of compression. */ +static void +png_zlib_claim(png_structp png_ptr, png_uint_32 state) +{ + if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) + { + /* If already initialized for 'state' do not re-init. */ + if (png_ptr->zlib_state != state) + { + int ret = Z_OK; + png_const_charp who = "-"; + + /* If actually initialized for another state do a deflateEnd. */ + if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) + { + ret = deflateEnd(&png_ptr->zstream); + who = "end"; + png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; + } + + /* zlib itself detects an incomplete state on deflateEnd */ + if (ret == Z_OK) switch (state) + { +# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + case PNG_ZLIB_FOR_TEXT: + ret = deflateInit2(&png_ptr->zstream, + png_ptr->zlib_text_level, png_ptr->zlib_text_method, + png_ptr->zlib_text_window_bits, + png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); + who = "text"; + break; +# endif + + case PNG_ZLIB_FOR_IDAT: + ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, + png_ptr->zlib_method, png_ptr->zlib_window_bits, + png_ptr->zlib_mem_level, png_ptr->zlib_strategy); + who = "IDAT"; + break; + + default: + png_error(png_ptr, "invalid zlib state"); + } + + if (ret == Z_OK) + png_ptr->zlib_state = state; + + else /* an error in deflateEnd or deflateInit2 */ + { + size_t pos = 0; + char msg[64]; + + pos = png_safecat(msg, sizeof msg, pos, + "zlib failed to initialize compressor ("); + pos = png_safecat(msg, sizeof msg, pos, who); + + switch (ret) + { + case Z_VERSION_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") version error"); + break; + + case Z_STREAM_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") stream error"); + break; + + case Z_MEM_ERROR: + pos = png_safecat(msg, sizeof msg, pos, ") memory error"); + break; + + default: + pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); + break; + } + + png_error(png_ptr, msg); + } + } + + /* Here on success, claim the zstream: */ + png_ptr->zlib_state |= PNG_ZLIB_IN_USE; + } + + else + png_error(png_ptr, "zstream already in use (internal error)"); +} + +/* The opposite: release the stream. It is also reset, this API will warn on + * error but will not fail. + */ +static void +png_zlib_release(png_structp png_ptr) +{ + if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) + { + int ret = deflateReset(&png_ptr->zstream); + + png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; + + if (ret != Z_OK) + { + png_const_charp err; + PNG_WARNING_PARAMETERS(p) + + switch (ret) + { + case Z_VERSION_ERROR: + err = "version"; + break; + + case Z_STREAM_ERROR: + err = "stream"; + break; + + case Z_MEM_ERROR: + err = "memory"; + break; + + default: + err = "unknown"; + break; + } + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); + png_warning_parameter(p, 2, err); + + if (png_ptr->zstream.msg) + err = png_ptr->zstream.msg; + else + err = "[no zlib message]"; + + png_warning_parameter(p, 3, err); + + png_formatted_warning(png_ptr, p, + "zlib failed to reset compressor: @1(@2): @3"); + } + } + + else + png_warning(png_ptr, "zstream not in use (internal error)"); +} + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +/* This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions + * set up by the caller in order to make the whole mess thread-safe. + */ + +typedef struct +{ + png_const_bytep input; /* The uncompressed input data */ + png_size_t input_len; /* Its length */ + int num_output_ptr; /* Number of output pointers used */ + int max_output_ptr; /* Size of output_ptr */ + png_bytep *output_ptr; /* Array of pointers to output */ +} compression_state; + +/* Compress given text into storage in the png_ptr structure */ +static int /* PRIVATE */ +png_text_compress(png_structp png_ptr, + png_const_charp text, png_size_t text_len, int compression, + compression_state *comp) +{ + int ret; + + comp->num_output_ptr = 0; + comp->max_output_ptr = 0; + comp->output_ptr = NULL; + comp->input = NULL; + comp->input_len = text_len; + + /* We may just want to pass the text right through */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + comp->input = (png_const_bytep)text; + return((int)text_len); + } + + if (compression >= PNG_TEXT_COMPRESSION_LAST) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, + compression); + png_formatted_warning(png_ptr, p, "Unknown compression type @1"); + } + + /* We can't write the chunk until we find out how much data we have, + * which means we need to run the compressor first and save the + * output. This shouldn't be a problem, as the vast majority of + * comments should be reasonable, but we will set up an array of + * malloc'd pointers to be sure. + * + * If we knew the application was well behaved, we could simplify this + * greatly by assuming we can always malloc an output buffer large + * enough to hold the compressed text ((1001 * text_len / 1000) + 12) + * and malloc this directly. The only time this would be a bad idea is + * if we can't malloc more than 64K and we have 64K of random input + * data, or if the input string is incredibly large (although this + * wouldn't cause a failure, just a slowdown due to swapping). + */ + png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); + + /* Set up the compression buffers */ + /* TODO: the following cast hides a potential overflow problem. */ + png_ptr->zstream.avail_in = (uInt)text_len; + + /* NOTE: assume zlib doesn't overwrite the input */ + png_ptr->zstream.next_in = (Bytef *)text; + png_ptr->zstream.avail_out = png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + + /* This is the same compression loop as in png_write_row() */ + do + { + /* Compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + + if (ret != Z_OK) + { + /* Error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + + else + png_error(png_ptr, "zlib error"); + } + + /* Check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* Make sure the output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_bytepp old_ptr; + + old_ptr = comp->output_ptr; + + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (comp->max_output_ptr * png_sizeof(png_charpp))); + + png_memcpy(comp->output_ptr, old_ptr, old_max + * png_sizeof(png_charp)); + + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (comp->max_output_ptr * png_sizeof(png_charp))); + } + + /* Save the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)png_ptr->zbuf_size); + + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + + comp->num_output_ptr++; + + /* and reset the buffer */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + /* Continue until we don't have any more to compress */ + } while (png_ptr->zstream.avail_in); + + /* Finish the compression */ + do + { + /* Tell zlib we are finished */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + + if (ret == Z_OK) + { + /* Check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* Check to make sure our output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_bytepp old_ptr; + + old_ptr = comp->output_ptr; + + /* This could be optimized to realloc() */ + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); + + png_memcpy(comp->output_ptr, old_ptr, + old_max * png_sizeof(png_charp)); + + png_free(png_ptr, old_ptr); + } + + else + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); + } + + /* Save the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)png_ptr->zbuf_size); + + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + + comp->num_output_ptr++; + + /* and reset the buffer pointers */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + } + else if (ret != Z_STREAM_END) + { + /* We got an error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* Text length is number of buffers plus last buffer */ + text_len = png_ptr->zbuf_size * comp->num_output_ptr; + + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + + return((int)text_len); +} + +/* Ship the compressed text out via chunk writes */ +static void /* PRIVATE */ +png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +{ + int i; + + /* Handle the no-compression case */ + if (comp->input) + { + png_write_chunk_data(png_ptr, comp->input, comp->input_len); + + return; + } + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* The zbuf_size test is because the code below doesn't work if zbuf_size is + * '1'; simply skip it to avoid memory overwrite. + */ + if (comp->input_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1) + { + unsigned int z_cmf; /* zlib compression method and flags */ + + /* Optimize the CMF field in the zlib stream. This hack of the zlib + * stream is compliant to the stream specification. + */ + + if (comp->num_output_ptr) + z_cmf = comp->output_ptr[0][0]; + else + z_cmf = png_ptr->zbuf[0]; + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + unsigned int z_cinfo; + unsigned int half_z_window_size; + png_size_t uncompressed_text_size = comp->input_len; + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1 << (z_cinfo + 7); + + while (uncompressed_text_size <= half_z_window_size && + half_z_window_size >= 256) + { + z_cinfo--; + half_z_window_size >>= 1; + } + + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + + if (comp->num_output_ptr) + { + + if (comp->output_ptr[0][0] != z_cmf) + { + int tmp; + + comp->output_ptr[0][0] = (png_byte)z_cmf; + tmp = comp->output_ptr[0][1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + comp->output_ptr[0][1] = (png_byte)tmp; + } + } + else + { + int tmp; + + png_ptr->zbuf[0] = (png_byte)z_cmf; + tmp = png_ptr->zbuf[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + png_ptr->zbuf[1] = (png_byte)tmp; + } + } + + else + png_error(png_ptr, + "Invalid zlib compression method or flags in non-IDAT chunk"); + } +#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ + + /* Write saved output buffers, if any */ + for (i = 0; i < comp->num_output_ptr; i++) + { + png_write_chunk_data(png_ptr, comp->output_ptr[i], + (png_size_t)png_ptr->zbuf_size); + + png_free(png_ptr, comp->output_ptr[i]); + } + + if (comp->max_output_ptr != 0) + png_free(png_ptr, comp->output_ptr); + + /* Write anything left in zbuf */ + if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) + png_write_chunk_data(png_ptr, png_ptr->zbuf, + (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + + /* Reset zlib for another zTXt/iTXt or image data */ + png_zlib_release(png_ptr); +} +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. Note that the rest of this code depends upon this + * information being correct. + */ +void /* PRIVATE */ +png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) +{ + png_byte buf[13]; /* Buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR"); + + /* Check that we have valid input data from the application info */ + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: +#ifdef PNG_WRITE_16BIT_SUPPORTED + case 16: +#endif + png_ptr->channels = 1; break; + + default: + png_error(png_ptr, + "Invalid bit depth for grayscale image"); + } + break; + + case PNG_COLOR_TYPE_RGB: +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif + png_error(png_ptr, "Invalid bit depth for RGB image"); + + png_ptr->channels = 3; + break; + + case PNG_COLOR_TYPE_PALETTE: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: + png_ptr->channels = 1; + break; + + default: + png_error(png_ptr, "Invalid bit depth for paletted image"); + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); + + png_ptr->channels = 2; + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif + png_error(png_ptr, "Invalid bit depth for RGBA image"); + + png_ptr->channels = 4; + break; + + default: + png_error(png_ptr, "Invalid image color type specified"); + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Invalid compression type specified"); + compression_type = PNG_COMPRESSION_TYPE_BASE; + } + + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ( +#ifdef PNG_MNG_FEATURES_SUPPORTED + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && +#endif + filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Invalid filter type specified"); + filter_type = PNG_FILTER_TYPE_BASE; + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + if (interlace_type != PNG_INTERLACE_NONE && + interlace_type != PNG_INTERLACE_ADAM7) + { + png_warning(png_ptr, "Invalid interlace type specified"); + interlace_type = PNG_INTERLACE_ADAM7; + } +#else + interlace_type=PNG_INTERLACE_NONE; +#endif + + /* Save the relevent information */ + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->color_type = (png_byte)color_type; + png_ptr->interlaced = (png_byte)interlace_type; +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + png_ptr->width = width; + png_ptr->height = height; + + png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); + /* Set the usr info, so any transformations can modify it */ + png_ptr->usr_width = png_ptr->width; + png_ptr->usr_bit_depth = png_ptr->bit_depth; + png_ptr->usr_channels = png_ptr->channels; + + /* Pack the header information into the buffer */ + png_save_uint_32(buf, width); + png_save_uint_32(buf + 4, height); + buf[8] = (png_byte)bit_depth; + buf[9] = (png_byte)color_type; + buf[10] = (png_byte)compression_type; + buf[11] = (png_byte)filter_type; + buf[12] = (png_byte)interlace_type; + + /* Write the chunk */ + png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); + + /* Initialize zlib with PNG info */ + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + if (!(png_ptr->do_filter)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + png_ptr->bit_depth < 8) + png_ptr->do_filter = PNG_FILTER_NONE; + + else + png_ptr->do_filter = PNG_ALL_FILTERS; + } + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) + { + if (png_ptr->do_filter != PNG_FILTER_NONE) + png_ptr->zlib_strategy = Z_FILTERED; + + else + png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; + } + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) + png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) + png_ptr->zlib_mem_level = 8; + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) + png_ptr->zlib_window_bits = 15; + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) + png_ptr->zlib_method = 8; + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) + png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) + png_ptr->zlib_text_level = png_ptr->zlib_level; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) + png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) + png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; + + if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) + png_ptr->zlib_text_method = png_ptr->zlib_method; +#else + png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = png_ptr->zlib_level; + png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; + png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; + png_ptr->zlib_text_method = png_ptr->zlib_method; +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + + /* Record that the compressor has not yet been initialized. */ + png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; + + png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ +} + +/* Write the palette. We are careful not to trust png_color to be in the + * correct order for PNG, so people can redefine it to any convenient + * structure. + */ +void /* PRIVATE */ +png_write_PLTE(png_structp png_ptr, png_const_colorp palette, + png_uint_32 num_pal) +{ + png_uint_32 i; + png_const_colorp pal_ptr; + png_byte buf[3]; + + png_debug(1, "in png_write_PLTE"); + + if (( +#ifdef PNG_MNG_FEATURES_SUPPORTED + !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && +#endif + num_pal == 0) || num_pal > 256) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_error(png_ptr, "Invalid number of colors in palette"); + } + + else + { + png_warning(png_ptr, "Invalid number of colors in palette"); + return; + } + } + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring request to write a PLTE chunk in grayscale PNG"); + + return; + } + + png_ptr->num_palette = (png_uint_16)num_pal; + png_debug1(3, "num_palette = %d", png_ptr->num_palette); + + png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); +#ifdef PNG_POINTER_INDEXING_SUPPORTED + + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) + { + buf[0] = pal_ptr->red; + buf[1] = pal_ptr->green; + buf[2] = pal_ptr->blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } + +#else + /* This is a little slower but some buggy compilers need to do this + * instead + */ + pal_ptr=palette; + + for (i = 0; i < num_pal; i++) + { + buf[0] = pal_ptr[i].red; + buf[1] = pal_ptr[i].green; + buf[2] = pal_ptr[i].blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } + +#endif + png_write_chunk_end(png_ptr); + png_ptr->mode |= PNG_HAVE_PLTE; +} + +/* Write an IDAT chunk */ +void /* PRIVATE */ +png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_debug(1, "in png_write_IDAT"); + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + { + /* Optimize the CMF field in the zlib stream. This hack of the zlib + * stream is compliant to the stream specification. + */ + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + /* Avoid memory underflows and multiplication overflows. + * + * The conditions below are practically always satisfied; + * however, they still must be checked. + */ + if (length >= 2 && + png_ptr->height < 16384 && png_ptr->width < 16384) + { + /* Compute the maximum possible length of the datastream */ + + /* Number of pixels, plus for each row a filter byte + * and possibly a padding byte, so increase the maximum + * size to account for these. + */ + unsigned int z_cinfo; + unsigned int half_z_window_size; + png_uint_32 uncompressed_idat_size = png_ptr->height * + ((png_ptr->width * + png_ptr->channels * png_ptr->bit_depth + 15) >> 3); + + /* If it's interlaced, each block of 8 rows is sent as up to + * 14 rows, i.e., 6 additional rows, each with a filter byte + * and possibly a padding byte + */ + if (png_ptr->interlaced) + uncompressed_idat_size += ((png_ptr->height + 7)/8) * + (png_ptr->bit_depth < 8 ? 12 : 6); + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1 << (z_cinfo + 7); + + while (uncompressed_idat_size <= half_z_window_size && + half_z_window_size >= 256) + { + z_cinfo--; + half_z_window_size >>= 1; + } + + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + + if (data[0] != z_cmf) + { + int tmp; + data[0] = (png_byte)z_cmf; + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; + } + } + } + + else + png_error(png_ptr, + "Invalid zlib compression method or flags in IDAT"); + } +#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ + + png_write_complete_chunk(png_ptr, png_IDAT, data, length); + png_ptr->mode |= PNG_HAVE_IDAT; + + /* Prior to 1.5.4 this code was replicated in every caller (except at the + * end, where it isn't technically necessary). Since this function has + * flushed the data we can safely reset the zlib output buffer here. + */ + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +} + +/* Write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structp png_ptr) +{ + png_debug(1, "in png_write_IEND"); + + png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_ptr->mode |= PNG_HAVE_IEND; +} + +#ifdef PNG_WRITE_gAMA_SUPPORTED +/* Write a gAMA chunk */ +void /* PRIVATE */ +png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) +{ + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA"); + + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); + png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); +} +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +/* Write a sRGB chunk */ +void /* PRIVATE */ +png_write_sRGB(png_structp png_ptr, int srgb_intent) +{ + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB"); + + if (srgb_intent >= PNG_sRGB_INTENT_LAST) + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + + buf[0]=(png_byte)srgb_intent; + png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); +} +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +/* Write an iCCP chunk */ +void /* PRIVATE */ +png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, + png_const_charp profile, int profile_len) +{ + png_size_t name_len; + png_charp new_name; + compression_state comp; + int embedded_profile_len = 0; + + png_debug(1, "in png_write_iCCP"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) + return; + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_warning(png_ptr, "Unknown compression type in iCCP chunk"); + + if (profile == NULL) + profile_len = 0; + + if (profile_len > 3) + embedded_profile_len = + ((*( (png_const_bytep)profile ))<<24) | + ((*( (png_const_bytep)profile + 1))<<16) | + ((*( (png_const_bytep)profile + 2))<< 8) | + ((*( (png_const_bytep)profile + 3)) ); + + if (embedded_profile_len < 0) + { + png_warning(png_ptr, + "Embedded profile length in iCCP chunk is negative"); + + png_free(png_ptr, new_name); + return; + } + + if (profile_len < embedded_profile_len) + { + png_warning(png_ptr, + "Embedded profile length too large in iCCP chunk"); + + png_free(png_ptr, new_name); + return; + } + + if (profile_len > embedded_profile_len) + { + png_warning(png_ptr, + "Truncating profile to actual length in iCCP chunk"); + + profile_len = embedded_profile_len; + } + + if (profile_len) + profile_len = png_text_compress(png_ptr, profile, + (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); + + /* Make sure we include the NULL after the name and the compression type */ + png_write_chunk_header(png_ptr, png_iCCP, + (png_uint_32)(name_len + profile_len + 2)); + + new_name[name_len + 1] = 0x00; + + png_write_chunk_data(png_ptr, (png_bytep)new_name, + (png_size_t)(name_len + 2)); + + if (profile_len) + { + comp.input_len = profile_len; + png_write_compressed_data_out(png_ptr, &comp); + } + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +/* Write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) +{ + png_size_t name_len; + png_charp new_name; + png_byte entrybuf[10]; + png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); + png_size_t palette_size = entry_size * spalette->nentries; + png_sPLT_entryp ep; +#ifndef PNG_POINTER_INDEXING_SUPPORTED + int i; +#endif + + png_debug(1, "in png_write_sPLT"); + + if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) + return; + + /* Make sure we include the NULL after the name */ + png_write_chunk_header(png_ptr, png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + + png_write_chunk_data(png_ptr, (png_bytep)new_name, + (png_size_t)(name_len + 1)); + + png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); + + /* Loop through each palette entry, writing appropriately */ +#ifdef PNG_POINTER_INDEXING_SUPPORTED + for (ep = spalette->entries; epentries + spalette->nentries; ep++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + } +#else + ep=spalette->entries; + for (i = 0; i>spalette->nentries; i++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep[i].red; + entrybuf[1] = (png_byte)ep[i].green; + entrybuf[2] = (png_byte)ep[i].blue; + entrybuf[3] = (png_byte)ep[i].alpha; + png_save_uint_16(entrybuf + 4, ep[i].frequency); + } + + else + { + png_save_uint_16(entrybuf + 0, ep[i].red); + png_save_uint_16(entrybuf + 2, ep[i].green); + png_save_uint_16(entrybuf + 4, ep[i].blue); + png_save_uint_16(entrybuf + 6, ep[i].alpha); + png_save_uint_16(entrybuf + 8, ep[i].frequency); + } + + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + } +#endif + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +/* Write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) +{ + png_byte buf[4]; + png_size_t size; + + png_debug(1, "in png_write_sBIT"); + + /* Make sure we don't depend upon the order of PNG_COLOR_8 */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + png_byte maxbits; + + maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : + png_ptr->usr_bit_depth); + + if (sbit->red == 0 || sbit->red > maxbits || + sbit->green == 0 || sbit->green > maxbits || + sbit->blue == 0 || sbit->blue > maxbits) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[0] = sbit->red; + buf[1] = sbit->green; + buf[2] = sbit->blue; + size = 3; + } + + else + { + if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[0] = sbit->gray; + size = 1; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + { + if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[size++] = sbit->alpha; + } + + png_write_complete_chunk(png_ptr, png_sBIT, buf, size); +} +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +/* Write the cHRM chunk */ +void /* PRIVATE */ +png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, + png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, + png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, + png_fixed_point blue_y) +{ + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM"); + + /* Each value is saved in 1/100,000ths */ +#ifdef PNG_CHECK_cHRM_SUPPORTED + if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, + green_x, green_y, blue_x, blue_y)) +#endif + { + png_save_uint_32(buf, (png_uint_32)white_x); + png_save_uint_32(buf + 4, (png_uint_32)white_y); + + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_y); + + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_y); + + png_save_uint_32(buf + 24, (png_uint_32)blue_x); + png_save_uint_32(buf + 28, (png_uint_32)blue_y); + + png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); + } +} +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +/* Write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, + png_const_color_16p tran, int num_trans, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS"); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + { + png_warning(png_ptr, "Invalid number of transparent colors specified"); + return; + } + + /* Write the chunk out as it is */ + png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); + } + + else if (color_type == PNG_COLOR_TYPE_GRAY) + { + /* One 16 bit value */ + if (tran->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + + return; + } + + png_save_uint_16(buf, tran->gray); + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + } + + else if (color_type == PNG_COLOR_TYPE_RGB) + { + /* Three 16 bit values */ + png_save_uint_16(buf, tran->red); + png_save_uint_16(buf + 2, tran->green); + png_save_uint_16(buf + 4, tran->blue); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + } + + else + { + png_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } +} +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +/* Write the background chunk */ +void /* PRIVATE */ +png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD"); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if ( +#ifdef PNG_MNG_FEATURES_SUPPORTED + (png_ptr->num_palette || + (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && +#endif + back->index >= png_ptr->num_palette) + { + png_warning(png_ptr, "Invalid background palette index"); + return; + } + + buf[0] = back->index; + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + } + + else if (color_type & PNG_COLOR_MASK_COLOR) + { + png_save_uint_16(buf, back->red); + png_save_uint_16(buf + 2, back->green); + png_save_uint_16(buf + 4, back->blue); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + + return; + } + + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + } + + else + { + if (back->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + + return; + } + + png_save_uint_16(buf, back->gray); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + } +} +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +/* Write the histogram */ +void /* PRIVATE */ +png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) +{ + int i; + png_byte buf[3]; + + png_debug(1, "in png_write_hIST"); + + if (num_hist > (int)png_ptr->num_palette) + { + png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, + png_ptr->num_palette); + + png_warning(png_ptr, "Invalid number of histogram entries specified"); + return; + } + + png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + + for (i = 0; i < num_hist; i++) + { + png_save_uint_16(buf, hist[i]); + png_write_chunk_data(png_ptr, buf, (png_size_t)2); + } + + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The new_key is allocated to hold the corrected keyword and must be freed + * by the calling routine. This avoids problems with trying to write to + * static keywords without having to have duplicate copies of the strings. + */ +png_size_t /* PRIVATE */ +png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) +{ + png_size_t key_len; + png_const_charp ikp; + png_charp kp, dp; + int kflag; + int kwarn=0; + + png_debug(1, "in png_check_keyword"); + + *new_key = NULL; + + if (key == NULL || (key_len = png_strlen(key)) == 0) + { + png_warning(png_ptr, "zero length keyword"); + return ((png_size_t)0); + } + + png_debug1(2, "Keyword to be checked is '%s'", key); + + *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); + + if (*new_key == NULL) + { + png_warning(png_ptr, "Out of memory while procesing keyword"); + return ((png_size_t)0); + } + + /* Replace non-printing characters with a blank and print a warning */ + for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) + { + if ((png_byte)*ikp < 0x20 || + ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, + (png_byte)*ikp); + png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); + *dp = ' '; + } + + else + { + *dp = *ikp; + } + } + *dp = '\0'; + + /* Remove any trailing white space. */ + kp = *new_key + key_len - 1; + if (*kp == ' ') + { + png_warning(png_ptr, "trailing spaces removed from keyword"); + + while (*kp == ' ') + { + *(kp--) = '\0'; + key_len--; + } + } + + /* Remove any leading white space. */ + kp = *new_key; + if (*kp == ' ') + { + png_warning(png_ptr, "leading spaces removed from keyword"); + + while (*kp == ' ') + { + kp++; + key_len--; + } + } + + png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); + + /* Remove multiple internal spaces. */ + for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) + { + if (*kp == ' ' && kflag == 0) + { + *(dp++) = *kp; + kflag = 1; + } + + else if (*kp == ' ') + { + key_len--; + kwarn = 1; + } + + else + { + *(dp++) = *kp; + kflag = 0; + } + } + *dp = '\0'; + if (kwarn) + png_warning(png_ptr, "extra interior spaces removed from keyword"); + + if (key_len == 0) + { + png_free(png_ptr, *new_key); + png_warning(png_ptr, "Zero length keyword"); + } + + if (key_len > 79) + { + png_warning(png_ptr, "keyword length must be 1 - 79 characters"); + (*new_key)[79] = '\0'; + key_len = 79; + } + + return (key_len); +} +#endif + +#ifdef PNG_WRITE_tEXt_SUPPORTED +/* Write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len) +{ + png_size_t key_len; + png_charp new_key; + + png_debug(1, "in png_write_tEXt"); + + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) + return; + + if (text == NULL || *text == '\0') + text_len = 0; + + else + text_len = png_strlen(text); + + /* Make sure we include the 0 after the key */ + png_write_chunk_header(png_ptr, png_tEXt, + (png_uint_32)(key_len + text_len + 1)); + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); + + if (text_len) + png_write_chunk_data(png_ptr, (png_const_bytep)text, + (png_size_t)text_len); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); +} +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +/* Write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len, int compression) +{ + png_size_t key_len; + png_byte buf; + png_charp new_key; + compression_state comp; + + png_debug(1, "in png_write_zTXt"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) + { + png_free(png_ptr, new_key); + return; + } + + if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) + { + png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); + png_free(png_ptr, new_key); + return; + } + + text_len = png_strlen(text); + + /* Compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression, + &comp); + + /* Write start of chunk */ + png_write_chunk_header(png_ptr, png_zTXt, + (png_uint_32)(key_len+text_len + 2)); + + /* Write key */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); + + png_free(png_ptr, new_key); + + buf = (png_byte)compression; + + /* Write compression */ + png_write_chunk_data(png_ptr, &buf, (png_size_t)1); + + /* Write the compressed data */ + comp.input_len = text_len; + png_write_compressed_data_out(png_ptr, &comp); + + /* Close the chunk */ + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +/* Write an iTXt chunk */ +void /* PRIVATE */ +png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) +{ + png_size_t lang_len, key_len, lang_key_len, text_len; + png_charp new_lang; + png_charp new_key = NULL; + png_byte cbuf[2]; + compression_state comp; + + png_debug(1, "in png_write_iTXt"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) + return; + + if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) + { + png_warning(png_ptr, "Empty language field in iTXt chunk"); + new_lang = NULL; + lang_len = 0; + } + + if (lang_key == NULL) + lang_key_len = 0; + + else + lang_key_len = png_strlen(lang_key); + + if (text == NULL) + text_len = 0; + + else + text_len = png_strlen(text); + + /* Compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression - 2, + &comp); + + + /* Make sure we include the compression flag, the compression byte, + * and the NULs after the key, lang, and lang_key parts + */ + + png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)( + 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + + key_len + + lang_len + + lang_key_len + + text_len)); + + /* We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); + + /* Set the compression flag */ + if (compression == PNG_ITXT_COMPRESSION_NONE || + compression == PNG_TEXT_COMPRESSION_NONE) + cbuf[0] = 0; + + else /* compression == PNG_ITXT_COMPRESSION_zTXt */ + cbuf[0] = 1; + + /* Set the compression method */ + cbuf[1] = 0; + + png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); + + cbuf[0] = 0; + png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), + (png_size_t)(lang_len + 1)); + + png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), + (png_size_t)(lang_key_len + 1)); + + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + + png_free(png_ptr, new_key); + png_free(png_ptr, new_lang); +} +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +/* Write the oFFs chunk */ +void /* PRIVATE */ +png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, + int unit_type) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs"); + + if (unit_type >= PNG_OFFSET_LAST) + png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); + + png_save_int_32(buf, x_offset); + png_save_int_32(buf + 4, y_offset); + buf[8] = (png_byte)unit_type; + + png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); +} +#endif +#ifdef PNG_WRITE_pCAL_SUPPORTED +/* Write the pCAL chunk (described in the PNG extensions document) */ +void /* PRIVATE */ +png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, + png_int_32 X1, int type, int nparams, png_const_charp units, + png_charpp params) +{ + png_size_t purpose_len, units_len, total_len; + png_size_tp params_len; + png_byte buf[10]; + png_charp new_purpose; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); + + if (type >= PNG_EQUATION_LAST) + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; + png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); + units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d", (int)units_len); + total_len = purpose_len + units_len + 10; + + params_len = (png_size_tp)png_malloc(png_ptr, + (png_alloc_size_t)(nparams * png_sizeof(png_size_t))); + + /* Find the length of each parameter, making sure we don't count the + * null terminator for the last parameter. + */ + for (i = 0; i < nparams; i++) + { + params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + png_debug2(3, "pCAL parameter %d length = %lu", i, + (unsigned long)params_len[i]); + total_len += params_len[i]; + } + + png_debug1(3, "pCAL total length = %d", (int)total_len); + png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); + png_save_int_32(buf, X0); + png_save_int_32(buf + 4, X1); + buf[8] = (png_byte)type; + buf[9] = (png_byte)nparams; + png_write_chunk_data(png_ptr, buf, (png_size_t)10); + png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); + + png_free(png_ptr, new_purpose); + + for (i = 0; i < nparams; i++) + { + png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); + } + + png_free(png_ptr, params_len); + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +/* Write the sCAL chunk */ +void /* PRIVATE */ +png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, + png_const_charp height) +{ + png_byte buf[64]; + png_size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s"); + + wlen = png_strlen(width); + hlen = png_strlen(height); + total_len = wlen + hlen + 2; + + if (total_len > 64) + { + png_warning(png_ptr, "Can't write sCAL (buffer too small)"); + return; + } + + buf[0] = (png_byte)unit; + png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ + png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ + + png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); + png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); +} +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +/* Write the pHYs chunk */ +void /* PRIVATE */ +png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs"); + + if (unit_type >= PNG_RESOLUTION_LAST) + png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); + + png_save_uint_32(buf, x_pixels_per_unit); + png_save_uint_32(buf + 4, y_pixels_per_unit); + buf[8] = (png_byte)unit_type; + + png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); +} +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +/* Write the tIME chunk. Use either png_convert_from_struct_tm() + * or png_convert_from_time_t(), or fill in the structure yourself. + */ +void /* PRIVATE */ +png_write_tIME(png_structp png_ptr, png_const_timep mod_time) +{ + png_byte buf[7]; + + png_debug(1, "in png_write_tIME"); + + if (mod_time->month > 12 || mod_time->month < 1 || + mod_time->day > 31 || mod_time->day < 1 || + mod_time->hour > 23 || mod_time->second > 60) + { + png_warning(png_ptr, "Invalid time specified for tIME chunk"); + return; + } + + png_save_uint_16(buf, mod_time->year); + buf[2] = mod_time->month; + buf[3] = mod_time->day; + buf[4] = mod_time->hour; + buf[5] = mod_time->minute; + buf[6] = mod_time->second; + + png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); +} +#endif + +/* Initializes the row writing capability of libpng */ +void /* PRIVATE */ +png_write_start_row(png_structp png_ptr) +{ +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_alloc_size_t buf_size; + int usr_pixel_depth; + + png_debug(1, "in png_write_start_row"); + + usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; + buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; + + /* 1.5.6: added to allow checking in the row write code. */ + png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; + png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; + + /* Set up row buffer */ + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); + + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + /* Set up filtering buffer, if using this filter */ + if (png_ptr->do_filter & PNG_FILTER_SUB) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); + + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + /* We only need to keep the previous row if we are using one of these. */ + if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + { + /* Set up previous row buffer */ + png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); + + if (png_ptr->do_filter & PNG_FILTER_UP) + { + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); + + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + + if (png_ptr->do_filter & PNG_FILTER_AVG) + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); + + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + + if (png_ptr->do_filter & PNG_FILTER_PAETH) + { + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); + + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, we need to set up width and height of pass */ + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + + png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - + png_pass_start[0]) / png_pass_inc[0]; + } + + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + } + + else +#endif + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + + png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; +} + +/* Internal use only. Called when finished processing a row of data. */ +void /* PRIVATE */ +png_write_finish_row(png_structp png_ptr) +{ +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int ret; + + png_debug(1, "in png_write_finish_row"); + + /* Next row */ + png_ptr->row_number++; + + /* See if we are done */ + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, go to next pass */ + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + if (png_ptr->transformations & PNG_INTERLACE) + { + png_ptr->pass++; + } + + else + { + /* Loop until we find a non-zero width or height pass */ + do + { + png_ptr->pass++; + + if (png_ptr->pass >= 7) + break; + + png_ptr->usr_width = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + if (png_ptr->transformations & PNG_INTERLACE) + break; + + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); + + } + + /* Reset the row above the image for the next pass */ + if (png_ptr->pass < 7) + { + if (png_ptr->prev_row != NULL) + png_memset(png_ptr->prev_row, 0, + (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* + png_ptr->usr_bit_depth, png_ptr->width)) + 1); + + return; + } + } +#endif + + /* If we get here, we've just written the last row, so we need + to flush the compressor */ + do + { + /* Tell the compressor we are done */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + + /* Check for an error */ + if (ret == Z_OK) + { + /* Check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + + else if (ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* Write any extra space */ + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - + png_ptr->zstream.avail_out); + } + + png_zlib_release(png_ptr); + png_ptr->zstream.data_type = Z_BINARY; +} + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Pick out the correct pixels for the interlace pass. + * The basic idea here is to go through the row with a source + * pointer and a destination pointer (sp and dp), and copy the + * correct pixels for the pass. As the row gets compacted, + * sp will always be >= dp, so we should never overwrite anything. + * See the default: case for the easiest code to understand. + */ +void /* PRIVATE */ +png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) +{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_write_interlace"); + + /* We don't have to do anything on the last pass (6) */ + if (pass < 6) + { + /* Each pixel depth is handled separately */ + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + d = 0; + shift = 7; + + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 3); + value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; + d |= (value << shift); + + if (shift == 0) + { + shift = 7; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift--; + + } + if (shift != 7) + *dp = (png_byte)d; + + break; + } + + case 2: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 6; + d = 0; + + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 2); + value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; + d |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift -= 2; + } + if (shift != 6) + *dp = (png_byte)d; + + break; + } + + case 4: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 4; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 1); + value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; + d |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift -= 4; + } + if (shift != 4) + *dp = (png_byte)d; + + break; + } + + default: + { + png_bytep sp; + png_bytep dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + png_size_t pixel_bytes; + + /* Start at the beginning */ + dp = row; + + /* Find out how many bytes each pixel takes up */ + pixel_bytes = (row_info->pixel_depth >> 3); + + /* Loop through the row, only looking at the pixels that matter */ + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + /* Find out where the original pixel is */ + sp = row + (png_size_t)i * pixel_bytes; + + /* Move the pixel */ + if (dp != sp) + png_memcpy(dp, sp, pixel_bytes); + + /* Next pixel */ + dp += pixel_bytes; + } + break; + } + } + /* Set new row width */ + row_info->width = (row_info->width + + png_pass_inc[pass] - 1 - + png_pass_start[pass]) / + png_pass_inc[pass]; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +/* This filters the row, chooses which filter to use, if it has not already + * been specified by the application, and then writes the row out with the + * chosen filter. + */ +static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t row_bytes); + +#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) +#define PNG_HISHIFT 10 +#define PNG_LOMASK ((png_uint_32)0xffffL) +#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) +void /* PRIVATE */ +png_write_find_filter(png_structp png_ptr, png_row_infop row_info) +{ + png_bytep best_row; +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_bytep prev_row, row_buf; + png_uint_32 mins, bpp; + png_byte filter_to_do = png_ptr->do_filter; + png_size_t row_bytes = row_info->rowbytes; +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + int num_p_filters = png_ptr->num_prev_filters; +#endif + + png_debug(1, "in png_write_find_filter"); + +#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) + { + /* These will never be selected so we need not test them. */ + filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); + } +#endif + + /* Find out how many bytes offset each pixel is */ + bpp = (row_info->pixel_depth + 7) >> 3; + + prev_row = png_ptr->prev_row; +#endif + best_row = png_ptr->row_buf; +#ifdef PNG_WRITE_FILTER_SUPPORTED + row_buf = best_row; + mins = PNG_MAXSUM; + + /* The prediction method we use is to find which method provides the + * smallest value when summing the absolute values of the distances + * from zero, using anything >= 128 as negative numbers. This is known + * as the "minimum sum of absolute differences" heuristic. Other + * heuristics are the "weighted minimum sum of absolute differences" + * (experimental and can in theory improve compression), and the "zlib + * predictive" method (not implemented yet), which does test compressions + * of lines using different filter methods, and then chooses the + * (series of) filter(s) that give minimum compressed data size (VERY + * computationally expensive). + * + * GRR 980525: consider also + * + * (1) minimum sum of absolute differences from running average (i.e., + * keep running sum of non-absolute differences & count of bytes) + * [track dispersion, too? restart average if dispersion too large?] + * + * (1b) minimum sum of absolute differences from sliding average, probably + * with window size <= deflate window (usually 32K) + * + * (2) minimum sum of squared differences from zero or running average + * (i.e., ~ root-mean-square approach) + */ + + + /* We don't need to test the 'no filter' case if this is the only filter + * that has been chosen, as it doesn't actually do anything to the data. + */ + if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) + { + png_bytep rp; + png_uint_32 sum = 0; + png_size_t i; + int v; + + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) + { + v = *rp; + sum += (v < 128) ? v : 256 - v; + } + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + png_uint_32 sumhi, sumlo; + int j; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ + + /* Reduce the sum if we match any of the previous rows */ + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + /* Factor in the cost of this filter (this is here for completeness, + * but it makes no sense to have a "cost" for the NONE filter, as + * it has the minimum possible computational cost - none). + */ + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + mins = sum; + } + + /* Sub filter */ + if (filter_to_do == PNG_FILTER_SUB) + /* It's the only filter so no testing is needed */ + { + png_bytep rp, lp, dp; + png_size_t i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + *dp = *rp; + } + + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + } + + best_row = png_ptr->sub_row; + } + + else if (filter_to_do & PNG_FILTER_SUB) + { + png_bytep rp, dp, lp; + png_uint_32 sum = 0, lmins = mins; + png_size_t i; + int v; + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + /* We temporarily increase the "minimum sum" by the factor we + * would reduce the sum of this filter, so that we can do the + * early exit comparison without scaling the sum each time. + */ + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + v = *dp = *rp; + + sum += (v < 128) ? v : 256 - v; + } + + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->sub_row; + } + } + + /* Up filter */ + if (filter_to_do == PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_size_t i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); + } + + best_row = png_ptr->up_row; + } + + else if (filter_to_do & PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_uint_32 sum = 0, lmins = mins; + png_size_t i; + int v; + + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->up_row; + } + } + + /* Avg filter */ + if (filter_to_do == PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + } + + for (lp = row_buf + 1; i < row_bytes; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + } + best_row = png_ptr->avg_row; + } + + else if (filter_to_do & PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 sum = 0, lmins = mins; + png_size_t i; + int v; + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + + for (lp = row_buf + 1; i < row_bytes; i++) + { + v = *dp++ = + (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->avg_row; + } + } + + /* Paeth filter */ + if (filter_to_do == PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_size_t i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + } + best_row = png_ptr->paeth_row; + } + + else if (filter_to_do & PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 sum = 0, lmins = mins; + png_size_t i; + int v; + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + +#ifndef PNG_SLOW_PAETH + p = b - c; + pc = a - c; +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; +#else /* PNG_SLOW_PAETH */ + p = a + b - c; + pa = abs(p - a); + pb = abs(p - b); + pc = abs(p - c); + + if (pa <= pb && pa <= pc) + p = a; + + else if (pb <= pc) + p = b; + + else + p = c; +#endif /* PNG_SLOW_PAETH */ + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + best_row = png_ptr->paeth_row; + } + } +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + + /* Do the actual writing of the filtered row data from the chosen filter. */ + png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); + +#ifdef PNG_WRITE_FILTER_SUPPORTED +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + /* Save the type of filter we picked this time for future calculations */ + if (png_ptr->num_prev_filters > 0) + { + int j; + + for (j = 1; j < num_p_filters; j++) + { + png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; + } + + png_ptr->prev_filters[j] = best_row[0]; + } +#endif +#endif /* PNG_WRITE_FILTER_SUPPORTED */ +} + + +/* Do the actual writing of a previously filtered row. */ +static void +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t avail/*includes filter byte*/) +{ + png_debug(1, "in png_write_filtered_row"); + + png_debug1(2, "filter = %d", filtered_row[0]); + /* Set up the zlib input buffer */ + + png_ptr->zstream.next_in = filtered_row; + png_ptr->zstream.avail_in = 0; + /* Repeat until we have compressed all the data */ + do + { + int ret; /* Return of zlib */ + + /* Record the number of bytes available - zlib supports at least 65535 + * bytes at one step, depending on the size of the zlib type 'uInt', the + * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). + * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. + * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a + * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called + * with smaller chunks of data. + */ + if (png_ptr->zstream.avail_in == 0) + { + if (avail > ZLIB_IO_MAX) + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + avail -= ZLIB_IO_MAX; + } + + else + { + /* So this will fit in the available uInt space: */ + png_ptr->zstream.avail_in = (uInt)avail; + avail = 0; + } + } + + /* Compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + + /* Check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + + else + png_error(png_ptr, "zlib error"); + } + + /* See if it is time to write another IDAT */ + if (!(png_ptr->zstream.avail_out)) + { + /* Write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + } + /* Repeat until all data has been compressed */ + } while (avail > 0 || png_ptr->zstream.avail_in > 0); + + /* Swap the current and previous rows */ + if (png_ptr->prev_row != NULL) + { + png_bytep tptr; + + tptr = png_ptr->prev_row; + png_ptr->prev_row = png_ptr->row_buf; + png_ptr->row_buf = tptr; + } + + /* Finish row - updates counters and flushes zlib if last row */ + png_write_finish_row(png_ptr); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->flush_rows++; + + if (png_ptr->flush_dist > 0 && + png_ptr->flush_rows >= png_ptr->flush_dist) + { + png_write_flush(png_ptr); + } +#endif +} +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/WDL/lice/Makefile b/WDL/lice/Makefile new file mode 100644 index 00000000..19c3ff10 --- /dev/null +++ b/WDL/lice/Makefile @@ -0,0 +1,24 @@ +CFLAGS=-O2 -s -D_LICE_NO_SYSBITMAPS_ +CC=gcc +CXX=g++ +WDL_PATH=.. + +CXXFLAGS=$(CFLAGS) + +vpath %.c $(WDL_PATH)/zlib $(WDL_PATH)/libpng $(WDL_PATH)/jpeglib $(WDL_PATH)/giflib +vpath %.cpp test/ + +ZLIB_OBJS = compress.o adler32.o crc32.o deflate.o gzio.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o unzip.o ioapi.o zip.o unzip.o + +PNGLIB_OBJS = png.o pngerror.o pngget.o pngmem.o pngpread.o pngread.o pngrio.o pngrtran.o pngrutil.o pngset.o pngtrans.o + +JPEGLIB_OBJS = jcomapi.o jdapimin.o jdapistd.o jdatadst.o jdatasrc.o jdcoefct.o jdcolor.o jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o \ + jdmaster.o jdmerge.o jdphuff.o jdpostct.o jdsample.o jerror.o jfdctflt.o jfdctfst.o jfdctint.o jidctflt.o jidctfst.o jidctint.o \ + jidctred.o jmemmgr.o jmemnobs.o jquant1.o jquant2.o jutils.o + +GIFLIB_OBJS = dgif_lib.o egif_lib.o gifalloc.o gif_hash.o + +LICEOBJS = lice.o lice_gif.o lice_gif_write.o lice_image.o lice_jpg.o lice_png.o lice_palette.o + +imgs2gif: $(LICEOBJS) $(JPEGLIB_OBJS) $(PNGLIB_OBJS) $(ZLIB_OBJS) $(GIFLIB_OBJS) imgs2gif.o + $(CXX) $(CFLAGS) -o $@ $^ diff --git a/WDL/lice/glew/include/GL/WGLEXT.H b/WDL/lice/glew/include/GL/WGLEXT.H new file mode 100644 index 00000000..989d86a2 --- /dev/null +++ b/WDL/lice/glew/include/GL/WGLEXT.H @@ -0,0 +1,631 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number */ +/* wglext.h last updated 2005/01/07 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define WGL_WGLEXT_VERSION 6 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_I3D_swap_frame_lock +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +extern void WINAPI wglFreeMemoryNV (void *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); +extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); +extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); +extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); +extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); +extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableGenlockI3D (HDC); +extern BOOL WINAPI wglDisableGenlockI3D (HDC); +extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); +extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); +extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); +extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); +extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); +extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#endif + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableFrameLockI3D (void); +extern BOOL WINAPI wglDisableFrameLockI3D (void); +extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); +extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#endif + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetFrameUsageI3D (float *); +extern BOOL WINAPI wglBeginFrameTrackingI3D (void); +extern BOOL WINAPI wglEndFrameTrackingI3D (void); +extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/WDL/lice/glew/include/GL/glew.h b/WDL/lice/glew/include/GL/glew.h new file mode 100644 index 00000000..0de2efc3 --- /dev/null +++ b/WDL/lice/glew/include/GL/glew.h @@ -0,0 +1,12262 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) +#error gl.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) + +/* + * GLEW does not include to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* */ +#ifndef APIENTRY +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) +# define APIENTRY __stdcall +# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* and */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__MINGW32__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include +#include + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY +#define GLEWAPI extern + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#endif /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +#if defined(_MSC_VER) +# if _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +# else +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +# endif +#else +# if defined(__MINGW32__) +#include +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_TRUE 1 +#define GL_FALSE 0 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_LOGIC_OP GL_INDEX_LOGIC_OP +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +/* this is where we can safely include GLU */ +#if defined(__APPLE__) && defined(__MACH__) +#include +#else +#include +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) +#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +typedef char GLchar; + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + +#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) + +#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) + +#endif /* GL_VERSION_2_1 */ + +/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum, GLuint, GLint*); +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLint*); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLint*, GLenum); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) +#define glClampColor GLEW_GET_FUN(__glewClampColor) +#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) +#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) +#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) +#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) +#define glColorMaski GLEW_GET_FUN(__glewColorMaski) +#define glDisablei GLEW_GET_FUN(__glewDisablei) +#define glEnablei GLEW_GET_FUN(__glewEnablei) +#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) +#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) +#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) +#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetStringi GLEW_GET_FUN(__glewGetStringi) +#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) +#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) +#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) +#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) +#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) +#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) +#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) +#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) +#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) +#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) +#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) +#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) +#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) +#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) +#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) +#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) +#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) +#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) +#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) +#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) +#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) +#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) +#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) +#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) +#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) +#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) +#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) +#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) +#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) +#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) +#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) +#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) +#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) +#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) +#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) +#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) +#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) + +#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) + +#endif /* GL_VERSION_3_0 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 + +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 + +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 + +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + +typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) + +#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) + +#endif /* GL_APPLE_flush_buffer_range */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 + +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D + +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) + +#endif /* GL_ARB_depth_buffer_float */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 + +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURLAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) +#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) +#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) +#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) +#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) +#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) +#define glFramebufferTexturLayer GLEW_GET_FUN(__glewFramebufferTexturLayer) +#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) +#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) +#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) +#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) +#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) +#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) + +#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) + +#endif /* GL_ARB_framebuffer_object */ + +/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) + +#endif /* GL_ARB_framebuffer_sRGB */ + +/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_ARB 0xA +#define GL_LINE_STRIP_ADJACENCY_ARB 0xB +#define GL_TRIANGLES_ADJACENCY_ARB 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) +#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) +#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) +#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) + +#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) + +#endif /* GL_ARB_geometry_shader4 */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 + +#define GL_HALF_FLOAT 0x140B + +#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) + +#endif /* GL_ARB_half_float_vertex */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) + +#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) + +#endif /* GL_ARB_instanced_arrays */ + +/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) +#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) + +#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) + +#endif /* GL_ARB_map_buffer_range */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 + +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 + +typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 + +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 + +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 + +typedef char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 + +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) + +#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) + +#endif /* GL_ARB_texture_buffer_object */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE + +#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) + +#endif /* GL_ARB_texture_compression_rgtc */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A + +#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 + +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 + +#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* --------------------------- GL_ARB_texture_rg --------------------------- */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 + +#define GL_RED 0x1903 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C + +#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) + +#endif /* GL_ARB_texture_rg */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + +#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) +#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) +#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) +#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) + +#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) + +#endif /* GL_ARB_vertex_array_object */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F + +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA + +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 + +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 + +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A + +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 +#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 +#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 +#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 +#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 +#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 + +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 + +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C + +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_RED_BIT_ATI 0x00000001 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 + +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 + +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glPNTrianglewesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glPNTrianglewesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 + +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 + +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ + +#ifndef GL_ATI_shader_texture_lod +#define GL_ATI_shader_texture_lod 1 + +#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) + +#endif /* GL_ATI_shader_texture_lod */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 + +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 + +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 + +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 + +typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 + +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 + +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF + +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + +#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) +#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) +#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) + +#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) + +#endif /* GL_EXT_bindable_uniform */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 + +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 + +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 + +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 + +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 + +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 + +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 + +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 + +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 + +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 + +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 + +typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 + +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 + +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_direct_state_access ---------------------- */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 + +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F + +typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void* data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); + +#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) +#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) +#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) +#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) +#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) +#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) +#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) +#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) +#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) +#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) +#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) +#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) +#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) +#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) +#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) +#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) +#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) +#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) +#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) +#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) +#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) +#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) +#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) +#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) +#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) +#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) +#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) +#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) +#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) +#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) +#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) +#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) +#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) +#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) +#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) +#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) +#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) +#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) +#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) +#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) +#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) +#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) +#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) +#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) +#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) +#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) +#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) +#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) +#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) +#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) +#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) +#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) +#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) +#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) +#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) +#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) +#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) +#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) +#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) +#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) +#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) +#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) +#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) +#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) +#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) +#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) +#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) +#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) +#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) +#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) +#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) +#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) +#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) +#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) +#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) +#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) +#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) +#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) +#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) +#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) +#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) +#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) +#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) +#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) +#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) +#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) +#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) +#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) +#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) +#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) +#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) +#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) +#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) +#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) +#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) +#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) +#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) +#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) +#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) +#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) + +#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) + +#endif /* GL_EXT_direct_state_access */ + +/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) +#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) + +#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) + +#endif /* GL_EXT_draw_buffers2 */ + +/* ------------------------- GL_EXT_draw_instanced ------------------------- */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); + +#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) +#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) + +#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) + +#endif /* GL_EXT_draw_instanced */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 + +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA + +#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) + +#endif /* GL_EXT_framebuffer_sRGB */ + +/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) +#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) + +#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) + +#endif /* GL_EXT_geometry_shader4 */ + +/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); + +#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) +#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) + +#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) + +#endif /* GL_EXT_gpu_program_parameters */ + +/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) +#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) +#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) +#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) +#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) +#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) +#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) +#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) +#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) +#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) +#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) +#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) +#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) +#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) +#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) +#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) +#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) +#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) +#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) +#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) +#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) +#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) +#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) +#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) +#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) +#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) +#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) +#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) +#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) +#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) +#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) +#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) +#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) +#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) + +#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) + +#endif /* GL_EXT_gpu_shader4 */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 + +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* -------------------------- GL_EXT_light_texture ------------------------- */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 + +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 + +typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint* first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_float -------------------------- */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 + +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C + +#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) + +#endif /* GL_EXT_packed_float */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 + +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 + +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 + +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GL_RESCALE_NORMAL_EXT 0x803A + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 + +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 + +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 + +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 + +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 + +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 + +#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 + +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------------- GL_EXT_texture_array ------------------------- */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 + +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D + +#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) + +#endif /* GL_EXT_texture_array */ + +/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) + +#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) + +#endif /* GL_EXT_texture_buffer_object */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_latc -------------------- */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 + +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 + +#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) + +#endif /* GL_EXT_texture_compression_latc */ + +/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE + +#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) + +#endif /* GL_EXT_texture_compression_rgtc */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 + +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_MODULATE_EXT 0 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 + +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ------------------------- GL_EXT_texture_integer ------------------------ */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 + +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E + +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); + +#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) +#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) +#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) +#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) +#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) +#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) + +#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) + +#endif /* GL_EXT_texture_integer */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 + +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 + +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 + +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A + +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 + +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF + +typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 + +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F + +#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) + +#endif /* GL_EXT_texture_shared_exponent */ + +/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 + +#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) + +#endif /* GL_EXT_texture_swizzle */ + +/* --------------------------- GL_EXT_timer_query -------------------------- */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 + +#define GL_TIME_ELAPSED_EXT 0x88BF + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); + +#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) +#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) + +#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) + +#endif /* GL_EXT_timer_query */ + +/* ----------------------- GL_EXT_transform_feedback ----------------------- */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 + +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F + +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, char *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); + +#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) +#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) +#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) +#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) +#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) +#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) +#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) + +#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) + +#endif /* GL_EXT_transform_feedback */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 + +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glGetPointervEXT GLEW_GET_FUN(__glewGetPointervEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) + +#endif /* GL_EXT_vertex_array_bgra */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 + +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED + +typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 + +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 + +typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); + +#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) + +#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) + +#endif /* GL_GREMEDY_frame_terminator */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 + +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 + +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 + +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 + +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) +#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) +#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) +#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) +#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 + +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 + +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ------------------------ GL_NV_conditional_render ----------------------- */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 + +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); + +#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) +#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) + +#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) + +#endif /* GL_NV_conditional_render */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 + +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + +#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) +#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) +#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) + +#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) + +#endif /* GL_NV_depth_buffer_float */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ + +#ifndef GL_NV_depth_range_unclamped +#define GL_NV_depth_range_unclamped 1 + +#define GL_SAMPLE_COUNT_BITS_NV 0x8864 +#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 +#define GL_QUERY_RESULT_NV 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 +#define GL_SAMPLE_COUNT_NV 0x8914 + +#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) + +#endif /* GL_NV_depth_range_unclamped */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 + +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* ----------------------- GL_NV_explicit_multisample ---------------------- */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 + +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + +#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) +#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) +#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) + +#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) + +#endif /* GL_NV_explicit_multisample */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 + +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 + +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 + +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 + +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* ------------------------ GL_NV_fragment_program4 ------------------------ */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 + +#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) + +#endif /* GL_NV_fragment_program4 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 + +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) + +#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +/* ------------------------ GL_NV_geometry_program4 ------------------------ */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 + +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 + +typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); + +#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) + +#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) + +#endif /* GL_NV_geometry_program4 */ + +/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 + +#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) + +#endif /* GL_NV_geometry_shader4 */ + +/* --------------------------- GL_NV_gpu_program4 -------------------------- */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 + +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); + +#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) +#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) +#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) +#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) + +#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) + +#endif /* GL_NV_gpu_program4 */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 + +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 + +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* --------------------- GL_NV_parameter_buffer_object --------------------- */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 + +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 + +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); + +#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) +#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) + +#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) + +#endif /* GL_NV_parameter_buffer_object */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 + +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D + +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 + +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* -------------------------- GL_NV_present_video -------------------------- */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 + +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B + +typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (GLAPIENTRY * PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint* params); + +#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) +#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) +#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) +#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) +#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) +#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) +#define glVideoParameterivNV GLEW_GET_FUN(__glewVideoParameterivNV) + +#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) + +#endif /* GL_NV_present_video */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 + +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 + +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 + +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 + +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 + +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 + +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D + +#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 + +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_transform_feedback ----------------------- */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 + +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F + +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); + +#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) +#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) +#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) +#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) +#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) +#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) +#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) +#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) +#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) +#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) +#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) + +#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) + +#endif /* GL_NV_transform_feedback */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 + +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ------------------------- GL_NV_vertex_program4 ------------------------- */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#define GL_BYTE 0x1400 + +#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) + +#endif /* GL_OES_byte_coordinates */ + +/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 + +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) + +#endif /* GL_OES_compressed_paletted_texture */ + +/* --------------------------- GL_OES_read_format -------------------------- */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 + +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B + +#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) + +#endif /* GL_OES_read_format */ + +/* ------------------------ GL_OES_single_precision ------------------------ */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + +#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) +#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) +#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) +#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) +#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) +#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) + +#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) + +#endif /* GL_OES_single_precision */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 + +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 + +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 + +#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 + +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 + +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 + +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 + +#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) + +#endif /* GL_SGIS_point_line_texgen */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 + +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 + +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 + +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 + +#define GL_CONVOLUTION_HINT_SGIX 0x8316 + +#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) + +#endif /* GL_SGIX_convolution_accuracy */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +#define GL_TEXTURE_FOG_SGIX 0 +#define GL_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 + +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 + +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 + +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 + +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 + +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------- GL_SGI_texture_color_table ---------------------- */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 + +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 + +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 + +typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 + +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA + +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB + +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +#if defined(GLEW_MX) && defined(_WIN32) +#define GLEW_FUN_EXPORT +#else +#define GLEW_FUN_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) +#define GLEW_VAR_EXPORT +#else +#define GLEW_VAR_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) && defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; +GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; +GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; +GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; +GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; +GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; +GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; +GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; +GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; + +GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; + +GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; +GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; + +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; +GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; +GLEW_FUN_EXPORT PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; +GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; +GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; +GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; +GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; + +#if defined(GLEW_MX) && !defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; + +#ifdef GLEW_MX +}; /* GLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* GL 1.1 and up are not supported */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* GLX 1.2 and up are not supported */ + +/* string codes */ +#define GLEW_VERSION 1 +#define GLEW_VERSION_MAJOR 2 +#define GLEW_VERSION_MINOR 3 +#define GLEW_VERSION_MICRO 4 + +/* API */ +#ifdef GLEW_MX + +typedef struct GLEWContextStruct GLEWContext; +GLEWAPI GLenum glewContextInit (GLEWContext* ctx); +GLEWAPI GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name); + +#define glewInit() glewContextInit(glewGetContext()) +#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x)) +#ifdef _WIN32 +# define GLEW_GET_FUN(x) glewGetContext()->x +#else +# define GLEW_GET_FUN(x) x +#endif + +#else /* GLEW_MX */ + +GLEWAPI GLenum glewInit (); +GLEWAPI GLboolean glewIsSupported (const char* name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLEW_GET_FUN(x) x + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean glewGetExtension (const char* name); +GLEWAPI const GLubyte* glewGetErrorString (GLenum error); +GLEWAPI const GLubyte* glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#undef GLAPIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/WDL/lice/glew/include/GL/glxew.h b/WDL/lice/glew/include/GL/glxew.h new file mode 100644 index 00000000..eeb4b280 --- /dev/null +++ b/WDL/lice/glew/include/GL/glxew.h @@ -0,0 +1,1397 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif +#ifdef GLX_H +#error glx.h included before glxew.h +#endif + +#define __glxext_h_ +#define __GLX_glx_h__ +#define GLX_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +#ifdef __sun +typedef struct __glXContextRec *GLXContext; +#else +typedef struct __GLXcontextRec *GLXContext; +#endif + +typedef unsigned int GLXVideoDeviceNV; + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_RGBA_BIT 0x00000001 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef struct __GLXFBConfigRec *GLXFBConfig; + +typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; +} GLXPbufferClobberEvent; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; +} GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------- GLX_ARB_create_context ------------------------ */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 + +typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + +#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) + +#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) + +#endif /* GLX_ARB_create_context */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#define GLX_RGBA_FLOAT_TYPE 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_ARB_framebuffer_sRGB +#define GLX_ARB_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 + +#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) + +#endif /* GLX_ARB_framebuffer_sRGB */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 + +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 + +#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) + +#endif /* GLX_EXT_fbconfig_packed_float */ + +/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 + +#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) + +#endif /* GLX_EXT_framebuffer_sRGB */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 + +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C + +typedef XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 + +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB + +typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer); + +#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) +#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) + +#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) + +#endif /* GLX_EXT_texture_from_pixmap */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 + +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 + +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 + +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 + +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 + +typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* -------------------------- GLX_NV_present_video ------------------------- */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 + +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 + +typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); + +#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) +#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) + +#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) + +#endif /* GLX_NV_present_video */ + +/* --------------------------- GLX_NV_swap_group --------------------------- */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 + +typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); +typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); +typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count); +typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); + +#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) +#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) +#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) +#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) +#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) +#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) + +#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) + +#endif /* GLX_NV_swap_group */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_NV_video_output -------------------------- */ + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output 1 + +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC + +typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); +typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); +typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); + +#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) +#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) +#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) +#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) +#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) +#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) + +#define GLXEW_NV_video_output GLXEW_GET_VAR(__GLXEW_NV_video_output) + +#endif /* GLX_NV_video_output */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 + +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#if !defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLX_MIN_RED_SGIS 0 +#define GLX_MAX_GREEN_SGIS 0 +#define GLX_MIN_BLUE_SGIS 0 +#define GLX_MAX_ALPHA_SGIS 0 +#define GLX_MIN_GREEN_SGIS 0 +#define GLX_MIN_ALPHA_SGIS 0 +#define GLX_MAX_RED_SGIS 0 +#define GLX_EXTENDED_RANGE_SGIS 0 +#define GLX_MAX_BLUE_SGIS 0 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 + +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 + +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); + +#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) +#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) +#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) +#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) +#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) +#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) +#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) +#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) + +#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) + +#endif /* GLX_SGIX_hyperpipe */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 + +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 + +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 + +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 + +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (uint* count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define GLXEW_EXPORT +#else +#define GLXEW_EXPORT extern +#endif /* GLEW_MX */ + +extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +extern PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; + +extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +extern PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; +extern PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; + +extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +extern PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; +extern PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; + +extern PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; +extern PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; +extern PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; +extern PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; +extern PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; +extern PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; + +extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +extern PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; +extern PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; +extern PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; +extern PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; +extern PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; +extern PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; + +#ifdef GLX_OML_sync_control +extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; +#endif + +extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +extern PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; +extern PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; +extern PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; +extern PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; +extern PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; +extern PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; + +extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context; +GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_EXPORT GLboolean __GLXEW_NV_present_video; +GLXEW_EXPORT GLboolean __GLXEW_NV_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_EXPORT GLboolean __GLXEW_NV_video_output; +GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +extern GLenum glxewContextInit (GLXEWContext* ctx); +extern GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name); + +#define glxewInit() glxewContextInit(glxewGetContext()) +#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x)) +#define GLXEW_GET_FUN(x) x + +#else /* GLEW_MX */ + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLXEW_GET_FUN(x) x + +extern GLboolean glxewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +extern GLboolean glxewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/WDL/lice/glew/include/GL/wglew.h b/WDL/lice/glew/include/GL/wglew.h new file mode 100644 index 00000000..d9dd3f25 --- /dev/null +++ b/WDL/lice/glew/include/GL/wglew.h @@ -0,0 +1,1165 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(APIENTRY) && !defined(__CYGWIN__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 + +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 + +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* ------------------------- WGL_ARB_create_context ------------------------ */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 + +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); + +#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) + +#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) + +#endif /* WGL_ARB_create_context */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + +#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) + +#endif /* WGL_ARB_framebuffer_sRGB */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 + +#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) + +#endif /* WGL_EXT_framebuffer_sRGB */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 + +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 + +#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) + +#endif /* WGL_EXT_pixel_format_packed_float */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 + +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 + +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 + +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F + +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 + +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C + +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 + +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 + +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 + +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 + +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 + +DECLARE_HANDLE(HGPUNV); +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; + +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); + +#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) +#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) +#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) +#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) +#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) + +#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) + +#endif /* WGL_NV_gpu_affinity */ + +/* -------------------------- WGL_NV_present_video ------------------------- */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 + +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 + +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); + +#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) +#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) +#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) + +#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) + +#endif /* WGL_NV_present_video */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* --------------------------- WGL_NV_swap_group --------------------------- */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 + +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + +#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) +#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) +#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) +#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) +#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) +#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) + +#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) + +#endif /* WGL_NV_swap_group */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_NV_video_output -------------------------- */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 + +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC + +DECLARE_HANDLE(HPVIDEODEV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); + +#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) +#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) +#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) +#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) +#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) +#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) + +#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) + +#endif /* WGL_NV_video_output */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define WGLEW_EXPORT +#else +#define WGLEW_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; +WGLEW_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; +WGLEW_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; +WGLEW_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; +WGLEW_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; + +WGLEW_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; +WGLEW_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; +WGLEW_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; + +WGLEW_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; +WGLEW_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; +WGLEW_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; +WGLEW_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; +WGLEW_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; +WGLEW_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; + +WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; +WGLEW_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; +WGLEW_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; +WGLEW_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; + +WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context; +WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_EXPORT GLboolean __WGLEW_NV_gpu_affinity; +WGLEW_EXPORT GLboolean __WGLEW_NV_present_video; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_NV_swap_group; +WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_EXPORT GLboolean __WGLEW_NV_video_output; +WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); +GLEWAPI GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name); + +#define wglewInit() wglewContextInit(wglewGetContext()) +#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x)) +#define WGLEW_GET_FUN(x) wglewGetContext()->x + +#else /* GLEW_MX */ + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define WGLEW_GET_FUN(x) x + +GLEWAPI GLboolean wglewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean wglewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/WDL/lice/glew/src/glew.c b/WDL/lice/glew/src/glew.c new file mode 100644 index 00000000..8767b580 --- /dev/null +++ b/WDL/lice/glew/src/glew.c @@ -0,0 +1,12180 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "../include/GL/glew.h" +#if defined(_WIN32) +# include "../include/GL/wglew.h" +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +# include "../include/GL/glxew.h" +#endif + +/* + * Define glewGetContext and related helper macros. + */ +#ifdef GLEW_MX +# define glewGetContext() ctx +# ifdef _WIN32 +# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx +# define GLEW_CONTEXT_ARG_VAR_INIT ctx +# define wglewGetContext() ctx +# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx +# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx +# else /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define glxewGetContext() ctx +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx +# endif /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx +#else /* GLEW_MX */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define GLEW_CONTEXT_ARG_DEF_LIST void +# define WGLEW_CONTEXT_ARG_DEF_INIT void +# define WGLEW_CONTEXT_ARG_DEF_LIST void +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST void +#endif /* GLEW_MX */ + +#if defined(__APPLE__) +#include +#include +#include + +void* NSGLGetProcAddress (const GLubyte *name) +{ + static const struct mach_header* image = NULL; + NSSymbol symbol; + char* symbolName; + if (NULL == image) + { + image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + /* prepend a '_' for the Unix C symbol mangling convention */ + symbolName = malloc(strlen((const char*)name) + 2); + strcpy(symbolName+1, (const char*)name); + symbolName[0] = '_'; + symbol = NULL; + /* if (NSIsSymbolNameDefined(symbolName)) + symbol = NSLookupAndBindSymbol(symbolName); */ + symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; + free(symbolName); + return symbol ? NSAddressOfSymbol(symbol) : NULL; +} +#endif /* __APPLE__ */ + +#if defined(__sgi) || defined (__sun) +#include +#include +#include + +void* dlGetProcAddress (const GLubyte* name) +{ + static void* h = NULL; + static void* gpa; + + if (h == NULL) + { + if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL; + gpa = dlsym(h, "glXGetProcAddress"); + } + + if (gpa != NULL) + return ((void*(*)(const GLubyte*))gpa)(name); + else + return dlsym(h, (const char*)name); +} +#endif /* __sgi || __sun */ + +/* + * Define glewGetProcAddress. + */ +#if defined(_WIN32) +# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) +#else +# if defined(__APPLE__) +# define glewGetProcAddress(name) NSGLGetProcAddress(name) +# else +# if defined(__sgi) || defined(__sun) +# define glewGetProcAddress(name) dlGetProcAddress(name) +# else /* __linux */ +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) +# endif +# endif +#endif + +/* + * Define GLboolean const cast. + */ +#define CONST_CAST(x) (*(GLboolean*)&x) + +/* + * GLEW, just like OpenGL or GLU, does not rely on the standard C library. + * These functions implement the functionality required in this file. + */ +static GLuint _glewStrLen (const GLubyte* s) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen (const GLubyte* s, GLubyte c) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) +{ + GLuint i=0; + if(a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewStrSame1 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t')) + { + (*a)++; + (*na)--; + } + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame2 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame3 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t')) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +#if !defined(_WIN32) || !defined(GLEW_MX) + +PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL; +PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL; +PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL; +PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL; + +PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL; +PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL; +PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL; +PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL; + +PFNGLBLENDCOLORPROC __glewBlendColor = NULL; +PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL; +PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL; +PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC __glewFogCoordd = NULL; +PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL; +PFNGLFOGCOORDFPROC __glewFogCoordf = NULL; +PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL; +PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL; +PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL; +PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL; +PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL; + +PFNGLBEGINQUERYPROC __glewBeginQuery = NULL; +PFNGLBINDBUFFERPROC __glewBindBuffer = NULL; +PFNGLBUFFERDATAPROC __glewBufferData = NULL; +PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL; +PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL; +PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL; +PFNGLENDQUERYPROC __glewEndQuery = NULL; +PFNGLGENBUFFERSPROC __glewGenBuffers = NULL; +PFNGLGENQUERIESPROC __glewGenQueries = NULL; +PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL; +PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL; +PFNGLISBUFFERPROC __glewIsBuffer = NULL; +PFNGLISQUERYPROC __glewIsQuery = NULL; +PFNGLMAPBUFFERPROC __glewMapBuffer = NULL; +PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL; + +PFNGLATTACHSHADERPROC __glewAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL; +PFNGLCOMPILESHADERPROC __glewCompileShader = NULL; +PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL; +PFNGLCREATESHADERPROC __glewCreateShader = NULL; +PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL; +PFNGLDELETESHADERPROC __glewDeleteShader = NULL; +PFNGLDETACHSHADERPROC __glewDetachShader = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL; +PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL; +PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL; +PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL; +PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL; +PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL; +PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL; +PFNGLISPROGRAMPROC __glewIsProgram = NULL; +PFNGLISSHADERPROC __glewIsShader = NULL; +PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL; +PFNGLSHADERSOURCEPROC __glewShaderSource = NULL; +PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL; +PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL; +PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL; +PFNGLUNIFORM1FPROC __glewUniform1f = NULL; +PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL; +PFNGLUNIFORM1IPROC __glewUniform1i = NULL; +PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL; +PFNGLUNIFORM2FPROC __glewUniform2f = NULL; +PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL; +PFNGLUNIFORM2IPROC __glewUniform2i = NULL; +PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL; +PFNGLUNIFORM3FPROC __glewUniform3f = NULL; +PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL; +PFNGLUNIFORM3IPROC __glewUniform3i = NULL; +PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL; +PFNGLUNIFORM4FPROC __glewUniform4f = NULL; +PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL; +PFNGLUNIFORM4IPROC __glewUniform4i = NULL; +PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL; +PFNGLUSEPROGRAMPROC __glewUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL; +PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL; + +PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL; + +PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL; +PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL; +PFNGLCLAMPCOLORPROC __glewClampColor = NULL; +PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL; +PFNGLCOLORMASKIPROC __glewColorMaski = NULL; +PFNGLDISABLEIPROC __glewDisablei = NULL; +PFNGLENABLEIPROC __glewEnablei = NULL; +PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL; +PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL; +PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL; +PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL; +PFNGLGETSTRINGIPROC __glewGetStringi = NULL; +PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL; +PFNGLISENABLEDIPROC __glewIsEnabledi = NULL; +PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL; +PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL; +PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL; +PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL; +PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL; + +PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; + +PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL; +PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL; + +PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL; +PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL; +PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL; +PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL; +PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL; +PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL; +PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL; +PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL; + +PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL; + +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL; +PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL; + +PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL; +PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL; + +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL; + +PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; + +PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; + +PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL; + +PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL; +PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; +PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; +PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; +PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL; +PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL; +PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL; +PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL; +PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL; +PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL; + +PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL; +PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL; + +PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL; +PFNGLCOLORTABLEPROC __glewColorTable = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL; +PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL; +PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL; +PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL; +PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL; +PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL; +PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL; +PFNGLGETMINMAXPROC __glewGetMinmax = NULL; +PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL; +PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL; +PFNGLHISTOGRAMPROC __glewHistogram = NULL; +PFNGLMINMAXPROC __glewMinmax = NULL; +PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL; +PFNGLRESETMINMAXPROC __glewResetMinmax = NULL; +PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL; + +PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL; + +PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL; +PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL; + +PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; + +PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL; + +PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL; +PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL; + +PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL; +PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL; +PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL; +PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL; +PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL; +PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL; +PFNGLISQUERYARBPROC __glewIsQueryARB = NULL; + +PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL; + +PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL; +PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL; +PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL; +PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL; +PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL; +PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL; +PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL; +PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL; +PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL; +PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL; +PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL; +PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL; +PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL; +PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL; +PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL; +PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL; +PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL; +PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL; +PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL; +PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL; +PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL; +PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL; +PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL; +PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL; +PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL; +PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL; +PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL; +PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL; +PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL; +PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL; + +PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL; + +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; + +PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; + +PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL; +PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL; +PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL; +PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL; + +PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL; +PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL; +PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL; +PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL; +PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL; +PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL; +PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL; +PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL; +PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL; +PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL; + +PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL; +PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL; +PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL; +PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL; +PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL; +PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL; +PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL; +PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL; + +PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL; +PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL; +PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL; +PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL; +PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL; +PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL; +PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL; + +PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL; +PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL; +PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL; + +PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL; +PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL; + +PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL; + +PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL; +PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL; + +PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL; + +PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL; +PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL; +PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL; +PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL; + +PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL; + +PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI = NULL; + +PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL; +PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL; + +PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL; +PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL; +PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL; +PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL; +PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL; + +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL; + +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL; +PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL; +PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL; +PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL; + +PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL; +PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL; +PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL; + +PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL; + +PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL; + +PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL; + +PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL; + +PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL; + +PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL; +PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL; + +PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL; + +PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL; + +PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL; + +PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL; + +PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL; + +PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL; +PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL; +PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL; +PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL; +PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL; +PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL; +PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL; +PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL; +PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL; +PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL; +PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL; +PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL; +PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL; +PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL; +PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL; +PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL; +PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL; +PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL; +PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL; +PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL; +PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL; +PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL; +PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL; +PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL; +PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL; +PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL; +PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL; +PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL; +PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL; +PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL; +PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL; +PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL; +PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL; +PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL; +PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL; +PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL; +PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL; +PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL; +PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL; +PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL; +PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL; +PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL; +PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL; +PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL; +PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL; +PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL; +PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL; +PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL; +PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL; +PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL; +PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL; +PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL; +PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL; +PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL; +PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL; +PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL; +PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL; +PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL; +PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL; +PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL; +PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL; +PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL; +PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL; +PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL; +PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL; +PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL; +PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL; +PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL; +PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL; +PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL; +PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL; +PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL; +PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL; +PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL; +PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL; +PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL; +PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL; +PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL; +PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL; +PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL; +PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL; +PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL; +PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL; +PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL; +PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL; +PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL; +PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL; +PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL; +PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL; +PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL; +PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL; +PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL; +PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL; +PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL; +PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL; +PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL; +PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL; +PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL; +PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL; +PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL; +PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL; +PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL; +PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL; + +PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL; +PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL; +PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL; +PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL; +PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL; +PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL; + +PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL; + +PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL; + +PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL; +PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL; +PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL; +PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL; +PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL; + +PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL; +PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL; +PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL; +PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL; +PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL; +PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL; +PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL; +PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL; +PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL; +PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL; +PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL; +PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL; +PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL; +PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL; + +PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL; + +PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL; +PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL; +PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL; +PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL; + +PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL; +PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL; + +PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL; +PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL; + +PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL; +PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL; +PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL; +PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL; +PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL; +PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL; +PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL; +PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL; +PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL; +PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL; +PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL; +PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL; +PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL; +PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL; +PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL; +PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL; +PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL; +PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL; +PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL; +PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL; +PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL; +PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL; +PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL; +PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL; +PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL; +PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL; +PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL; +PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL; +PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL; +PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL; +PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL; +PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL; +PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL; +PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL; + +PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL; +PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL; +PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL; +PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL; +PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL; +PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL; + +PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL; + +PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL; + +PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL; +PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL; + +PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL; + +PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL; +PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL; + +PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL; +PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL; + +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL; + +PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL; + +PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL; + +PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL; +PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL; + +PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL; + +PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; + +PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; + +PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; + +PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL; + +PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL; +PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL; +PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL; +PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL; +PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL; +PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL; + +PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL; +PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL; +PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL; +PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL; +PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL; + +PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL; + +PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL; +PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL; + +PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL; +PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL; +PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL; +PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL; +PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL; + +PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL; +PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL; +PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL; +PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT = NULL; +PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; + +PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL; +PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL; +PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL; +PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL; +PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL; +PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL; +PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL; +PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL; +PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL; +PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL; +PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL; +PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL; +PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL; +PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL; +PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL; +PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL; +PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL; +PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL; +PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL; +PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL; +PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL; + +PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL; + +PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL; + +PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL; + +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL; + +PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL; + +PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL; +PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL; +PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL; + +PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; + +PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; +PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; + +PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT = NULL; +PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT = NULL; +PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT = NULL; +PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT = NULL; +PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT = NULL; + +PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL; + +PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL; + +PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL; + +PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL; +PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL; +PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL; + +PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL; +PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL; +PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL; +PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL; + +PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL; +PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL; +PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL; + +PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL; +PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL; +PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL; +PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL; +PFNGLISFENCENVPROC __glewIsFenceNV = NULL; +PFNGLSETFENCENVPROC __glewSetFenceNV = NULL; +PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL; + +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL; + +PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL; + +PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL; +PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL; + +PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL; +PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL; +PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL; +PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL; +PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL; +PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL; +PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL; +PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL; +PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL; +PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL; +PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL; +PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL; +PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL; +PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL; + +PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL; +PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL; + +PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL; + +PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL; +PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL; + +PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL; + +PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL; +PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL; +PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL; +PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL; +PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL; +PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL; +PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV = NULL; + +PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL; + +PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL; +PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL; + +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL; + +PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL; +PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL; +PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL; +PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL; +PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL; +PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL; +PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL; +PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL; +PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL; + +PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; + +PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL; +PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL; +PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL; +PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL; +PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL; +PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL; +PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL; +PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL; +PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL; +PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL; +PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL; + +PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL; +PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL; +PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL; +PFNGLFRUSTUMFOESPROC __glewFrustumfOES = NULL; +PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES = NULL; +PFNGLORTHOFOESPROC __glewOrthofOES = NULL; + +PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL; + +PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL; +PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL; + +PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL; +PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL; + +PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL; +PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL; + +PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL; + +PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL; +PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL; + +PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL; +PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL; +PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL; +PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL; +PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL; + +PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL; + +PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL; + +PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL; + +PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL; + +PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL; + +PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL; + +PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL; + +PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL; + +PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL; +PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL; +PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL; +PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL; + +PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL; + +PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL; + +PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL; + +PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL; + +PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL; + +PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL; + +#endif /* !WIN32 || !GLEW_MX */ + +#if !defined(GLEW_MX) + +GLboolean __GLEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLEW_VERSION_1_5 = GL_FALSE; +GLboolean __GLEW_VERSION_2_0 = GL_FALSE; +GLboolean __GLEW_VERSION_2_1 = GL_FALSE; +GLboolean __GLEW_VERSION_3_0 = GL_FALSE; +GLboolean __GLEW_3DFX_multisample = GL_FALSE; +GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; +GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean __GLEW_APPLE_client_storage = GL_FALSE; +GLboolean __GLEW_APPLE_element_array = GL_FALSE; +GLboolean __GLEW_APPLE_fence = GL_FALSE; +GLboolean __GLEW_APPLE_float_pixels = GL_FALSE; +GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE; +GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; +GLboolean __GLEW_APPLE_specular_vector = GL_FALSE; +GLboolean __GLEW_APPLE_texture_range = GL_FALSE; +GLboolean __GLEW_APPLE_transform_hint = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE; +GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; +GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_texture = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; +GLboolean __GLEW_ARB_draw_instanced = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE; +GLboolean __GLEW_ARB_fragment_shader = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE; +GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE; +GLboolean __GLEW_ARB_imaging = GL_FALSE; +GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; +GLboolean __GLEW_ARB_multisample = GL_FALSE; +GLboolean __GLEW_ARB_multitexture = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; +GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_point_parameters = GL_FALSE; +GLboolean __GLEW_ARB_point_sprite = GL_FALSE; +GLboolean __GLEW_ARB_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; +GLboolean __GLEW_ARB_shadow = GL_FALSE; +GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; +GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_add = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_ARB_texture_float = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; +GLboolean __GLEW_ARB_texture_rg = GL_FALSE; +GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_blend = GL_FALSE; +GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_program = GL_FALSE; +GLboolean __GLEW_ARB_vertex_shader = GL_FALSE; +GLboolean __GLEW_ARB_window_pos = GL_FALSE; +GLboolean __GLEW_ATIX_point_sprites = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE; +GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE; +GLboolean __GLEW_ATI_draw_buffers = GL_FALSE; +GLboolean __GLEW_ATI_element_array = GL_FALSE; +GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE; +GLboolean __GLEW_ATI_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE; +GLboolean __GLEW_ATI_pn_triangles = GL_FALSE; +GLboolean __GLEW_ATI_separate_stencil = GL_FALSE; +GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE; +GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATI_texture_float = GL_FALSE; +GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE; +GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_streams = GL_FALSE; +GLboolean __GLEW_EXT_422_pixels = GL_FALSE; +GLboolean __GLEW_EXT_Cg_shader = GL_FALSE; +GLboolean __GLEW_EXT_abgr = GL_FALSE; +GLboolean __GLEW_EXT_bgra = GL_FALSE; +GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE; +GLboolean __GLEW_EXT_blend_color = GL_FALSE; +GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE; +GLboolean __GLEW_EXT_blend_minmax = GL_FALSE; +GLboolean __GLEW_EXT_blend_subtract = GL_FALSE; +GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE; +GLboolean __GLEW_EXT_cmyka = GL_FALSE; +GLboolean __GLEW_EXT_color_subtable = GL_FALSE; +GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_convolution = GL_FALSE; +GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE; +GLboolean __GLEW_EXT_copy_texture = GL_FALSE; +GLboolean __GLEW_EXT_cull_vertex = GL_FALSE; +GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE; +GLboolean __GLEW_EXT_direct_state_access = GL_FALSE; +GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE; +GLboolean __GLEW_EXT_draw_instanced = GL_FALSE; +GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE; +GLboolean __GLEW_EXT_fog_coord = GL_FALSE; +GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE; +GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_histogram = GL_FALSE; +GLboolean __GLEW_EXT_index_array_formats = GL_FALSE; +GLboolean __GLEW_EXT_index_func = GL_FALSE; +GLboolean __GLEW_EXT_index_material = GL_FALSE; +GLboolean __GLEW_EXT_index_texture = GL_FALSE; +GLboolean __GLEW_EXT_light_texture = GL_FALSE; +GLboolean __GLEW_EXT_misc_attribute = GL_FALSE; +GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE; +GLboolean __GLEW_EXT_multisample = GL_FALSE; +GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_EXT_packed_float = GL_FALSE; +GLboolean __GLEW_EXT_packed_pixels = GL_FALSE; +GLboolean __GLEW_EXT_paletted_texture = GL_FALSE; +GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE; +GLboolean __GLEW_EXT_point_parameters = GL_FALSE; +GLboolean __GLEW_EXT_polygon_offset = GL_FALSE; +GLboolean __GLEW_EXT_rescale_normal = GL_FALSE; +GLboolean __GLEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLEW_EXT_secondary_color = GL_FALSE; +GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; +GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE; +GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE; +GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE; +GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE; +GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE; +GLboolean __GLEW_EXT_subtexture = GL_FALSE; +GLboolean __GLEW_EXT_texture = GL_FALSE; +GLboolean __GLEW_EXT_texture3D = GL_FALSE; +GLboolean __GLEW_EXT_texture_array = GL_FALSE; +GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE; +GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE; +GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_env = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_add = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE; +GLboolean __GLEW_EXT_texture_integer = GL_FALSE; +GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE; +GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE; +GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE; +GLboolean __GLEW_EXT_timer_query = GL_FALSE; +GLboolean __GLEW_EXT_transform_feedback = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE; +GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; +GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; +GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE; +GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE; +GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_HP_image_transform = GL_FALSE; +GLboolean __GLEW_HP_occlusion_test = GL_FALSE; +GLboolean __GLEW_HP_texture_lighting = GL_FALSE; +GLboolean __GLEW_IBM_cull_vertex = GL_FALSE; +GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE; +GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE; +GLboolean __GLEW_IBM_static_data = GL_FALSE; +GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE; +GLboolean __GLEW_INGR_color_clamp = GL_FALSE; +GLboolean __GLEW_INGR_interlace_read = GL_FALSE; +GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; +GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; +GLboolean __GLEW_KTX_buffer_region = GL_FALSE; +GLboolean __GLEW_MESAX_texture_stack = GL_FALSE; +GLboolean __GLEW_MESA_pack_invert = GL_FALSE; +GLboolean __GLEW_MESA_resize_buffers = GL_FALSE; +GLboolean __GLEW_MESA_window_pos = GL_FALSE; +GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE; +GLboolean __GLEW_NV_blend_square = GL_FALSE; +GLboolean __GLEW_NV_conditional_render = GL_FALSE; +GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; +GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_NV_depth_clamp = GL_FALSE; +GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE; +GLboolean __GLEW_NV_evaluators = GL_FALSE; +GLboolean __GLEW_NV_explicit_multisample = GL_FALSE; +GLboolean __GLEW_NV_fence = GL_FALSE; +GLboolean __GLEW_NV_float_buffer = GL_FALSE; +GLboolean __GLEW_NV_fog_distance = GL_FALSE; +GLboolean __GLEW_NV_fragment_program = GL_FALSE; +GLboolean __GLEW_NV_fragment_program2 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program4 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program_option = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE; +GLboolean __GLEW_NV_geometry_program4 = GL_FALSE; +GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_NV_gpu_program4 = GL_FALSE; +GLboolean __GLEW_NV_half_float = GL_FALSE; +GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; +GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE; +GLboolean __GLEW_NV_occlusion_query = GL_FALSE; +GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_pixel_data_range = GL_FALSE; +GLboolean __GLEW_NV_point_sprite = GL_FALSE; +GLboolean __GLEW_NV_present_video = GL_FALSE; +GLboolean __GLEW_NV_primitive_restart = GL_FALSE; +GLboolean __GLEW_NV_register_combiners = GL_FALSE; +GLboolean __GLEW_NV_register_combiners2 = GL_FALSE; +GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; +GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE; +GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE; +GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE; +GLboolean __GLEW_NV_texture_rectangle = GL_FALSE; +GLboolean __GLEW_NV_texture_shader = GL_FALSE; +GLboolean __GLEW_NV_texture_shader2 = GL_FALSE; +GLboolean __GLEW_NV_texture_shader3 = GL_FALSE; +GLboolean __GLEW_NV_transform_feedback = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program = GL_FALSE; +GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE; +GLboolean __GLEW_NV_vertex_program3 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program4 = GL_FALSE; +GLboolean __GLEW_OES_byte_coordinates = GL_FALSE; +GLboolean __GLEW_OES_compressed_paletted_texture = GL_FALSE; +GLboolean __GLEW_OES_read_format = GL_FALSE; +GLboolean __GLEW_OES_single_precision = GL_FALSE; +GLboolean __GLEW_OML_interlace = GL_FALSE; +GLboolean __GLEW_OML_resample = GL_FALSE; +GLboolean __GLEW_OML_subsample = GL_FALSE; +GLboolean __GLEW_PGI_misc_hints = GL_FALSE; +GLboolean __GLEW_PGI_vertex_hints = GL_FALSE; +GLboolean __GLEW_REND_screen_coordinates = GL_FALSE; +GLboolean __GLEW_S3_s3tc = GL_FALSE; +GLboolean __GLEW_SGIS_color_range = GL_FALSE; +GLboolean __GLEW_SGIS_detail_texture = GL_FALSE; +GLboolean __GLEW_SGIS_fog_function = GL_FALSE; +GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE; +GLboolean __GLEW_SGIS_multisample = GL_FALSE; +GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE; +GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE; +GLboolean __GLEW_SGIS_texture4D = GL_FALSE; +GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE; +GLboolean __GLEW_SGIS_texture_lod = GL_FALSE; +GLboolean __GLEW_SGIS_texture_select = GL_FALSE; +GLboolean __GLEW_SGIX_async = GL_FALSE; +GLboolean __GLEW_SGIX_async_histogram = GL_FALSE; +GLboolean __GLEW_SGIX_async_pixel = GL_FALSE; +GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE; +GLboolean __GLEW_SGIX_clipmap = GL_FALSE; +GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE; +GLboolean __GLEW_SGIX_depth_texture = GL_FALSE; +GLboolean __GLEW_SGIX_flush_raster = GL_FALSE; +GLboolean __GLEW_SGIX_fog_offset = GL_FALSE; +GLboolean __GLEW_SGIX_fog_texture = GL_FALSE; +GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE; +GLboolean __GLEW_SGIX_framezoom = GL_FALSE; +GLboolean __GLEW_SGIX_interlace = GL_FALSE; +GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE; +GLboolean __GLEW_SGIX_list_priority = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE; +GLboolean __GLEW_SGIX_reference_plane = GL_FALSE; +GLboolean __GLEW_SGIX_resample = GL_FALSE; +GLboolean __GLEW_SGIX_shadow = GL_FALSE; +GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE; +GLboolean __GLEW_SGIX_sprite = GL_FALSE; +GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE; +GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE; +GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_range = GL_FALSE; +GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcb = GL_FALSE; +GLboolean __GLEW_SGI_color_matrix = GL_FALSE; +GLboolean __GLEW_SGI_color_table = GL_FALSE; +GLboolean __GLEW_SGI_texture_color_table = GL_FALSE; +GLboolean __GLEW_SUNX_constant_data = GL_FALSE; +GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_SUN_global_alpha = GL_FALSE; +GLboolean __GLEW_SUN_mesh_array = GL_FALSE; +GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE; +GLboolean __GLEW_SUN_slice_accum = GL_FALSE; +GLboolean __GLEW_SUN_triangle_list = GL_FALSE; +GLboolean __GLEW_SUN_vertex = GL_FALSE; +GLboolean __GLEW_WIN_phong_shading = GL_FALSE; +GLboolean __GLEW_WIN_specular_fog = GL_FALSE; +GLboolean __GLEW_WIN_swap_hint = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GL_VERSION_1_2 + +static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r; + r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r; + r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r; + r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_2 */ + +#ifdef GL_VERSION_1_3 + +static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r; + r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r; + r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r; + r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r; + r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r; + r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r; + r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r; + r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r; + r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r; + r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r; + r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r; + r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r; + r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r; + r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r; + r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r; + r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r; + r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r; + r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r; + r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r; + r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r; + r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r; + r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r; + r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r; + r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r; + r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r; + r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r; + r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r; + r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r; + r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r; + r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r; + r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r; + r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r; + r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r; + r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r; + r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r; + r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r; + r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r; + r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r; + r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r; + r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r; + r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r; + r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r; + r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r; + r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r; + r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r; + r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_3 */ + +#ifdef GL_VERSION_1_4 + +static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r; + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r; + r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r; + r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r; + r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r; + r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r; + r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r; + r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r; + r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r; + r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r; + r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r; + r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r; + r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r; + r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r; + r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r; + r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r; + r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r; + r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r; + r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r; + r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r; + r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r; + r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r; + r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r; + r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r; + r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r; + r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r; + r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r; + r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r; + r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r; + r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r; + r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r; + r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r; + r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r; + r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r; + r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r; + r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r; + r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r; + r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r; + r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r; + r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r; + r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r; + r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r; + r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r; + r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r; + r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r; + r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_4 */ + +#ifdef GL_VERSION_1_5 + +static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r; + r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r; + r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r; + r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r; + r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r; + r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r; + r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r; + r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r; + r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r; + r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r; + r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r; + r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r; + r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r; + r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r; + r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r; + r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r; + r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r; + r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r; + r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_5 */ + +#ifdef GL_VERSION_2_0 + +static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r; + r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r; + r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r; + r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r; + r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r; + r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r; + r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r; + r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r; + r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r; + r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r; + r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r; + r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r; + r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r; + r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r; + r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r; + r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r; + r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r; + r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r; + r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r; + r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r; + r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r; + r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r; + r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r; + r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r; + r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r; + r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r; + r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r; + r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r; + r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r; + r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r; + r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r; + r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r; + r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r; + r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r; + r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r; + r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r; + r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r; + r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r; + r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r; + r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r; + r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r; + r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r; + r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r; + r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r; + r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r; + r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r; + r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r; + r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r; + r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r; + r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r; + r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r; + r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r; + r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r; + r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r; + r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r; + r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r; + r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r; + r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r; + r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r; + r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r; + r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r; + r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r; + r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r; + r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r; + r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r; + r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r; + r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r; + r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r; + r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r; + r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r; + r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r; + r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r; + r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r; + r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r; + r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r; + r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r; + r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r; + r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r; + r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r; + r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r; + r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r; + r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r; + r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r; + r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r; + r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r; + r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r; + r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r; + r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r; + r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r; + r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r; + r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r; + r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r; + r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_0 */ + +#ifdef GL_VERSION_2_1 + +static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r; + r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r; + r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r; + r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r; + r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r; + r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_1 */ + +#ifdef GL_VERSION_3_0 + +static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r; + r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r; + r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r; + r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r; + r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r; + r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r; + r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r; + r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r; + r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r; + r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r; + r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r; + r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r; + r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r; + r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r; + r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r; + r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r; + r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r; + r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r; + r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r; + r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r; + r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r; + r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r; + r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r; + r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r; + r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r; + r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r; + r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r; + r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r; + r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r; + r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r; + r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r; + r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r; + r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r; + r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r; + r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r; + r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r; + r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r; + r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r; + r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r; + r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r; + r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r; + r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r; + r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r; + r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r; + r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r; + r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r; + r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r; + r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r; + r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r; + r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r; + r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r; + r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r; + r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r; + r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r; + r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r; + r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r; + r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r; + r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_0 */ + +#ifdef GL_3DFX_multisample + +#endif /* GL_3DFX_multisample */ + +#ifdef GL_3DFX_tbuffer + +static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r; + + return r; +} + +#endif /* GL_3DFX_tbuffer */ + +#ifdef GL_3DFX_texture_compression_FXT1 + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifdef GL_APPLE_client_storage + +#endif /* GL_APPLE_client_storage */ + +#ifdef GL_APPLE_element_array + +static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r; + r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r; + r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r; + r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r; + r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_element_array */ + +#ifdef GL_APPLE_fence + +static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r; + r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r; + r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r; + r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r; + r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r; + r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r; + r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r; + r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_fence */ + +#ifdef GL_APPLE_float_pixels + +#endif /* GL_APPLE_float_pixels */ + +#ifdef GL_APPLE_flush_buffer_range + +static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r; + r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_flush_buffer_range */ + +#ifdef GL_APPLE_pixel_buffer + +#endif /* GL_APPLE_pixel_buffer */ + +#ifdef GL_APPLE_specular_vector + +#endif /* GL_APPLE_specular_vector */ + +#ifdef GL_APPLE_texture_range + +static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r; + r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_texture_range */ + +#ifdef GL_APPLE_transform_hint + +#endif /* GL_APPLE_transform_hint */ + +#ifdef GL_APPLE_vertex_array_object + +static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r; + r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r; + r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r; + r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_object */ + +#ifdef GL_APPLE_vertex_array_range + +static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r; + r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r; + r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_range */ + +#ifdef GL_APPLE_ycbcr_422 + +#endif /* GL_APPLE_ycbcr_422 */ + +#ifdef GL_ARB_color_buffer_float + +static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_color_buffer_float */ + +#ifdef GL_ARB_depth_buffer_float + +#endif /* GL_ARB_depth_buffer_float */ + +#ifdef GL_ARB_depth_texture + +#endif /* GL_ARB_depth_texture */ + +#ifdef GL_ARB_draw_buffers + +static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers */ + +#ifdef GL_ARB_draw_instanced + +static GLboolean _glewInit_GL_ARB_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r; + r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_instanced */ + +#ifdef GL_ARB_fragment_program + +#endif /* GL_ARB_fragment_program */ + +#ifdef GL_ARB_fragment_program_shadow + +#endif /* GL_ARB_fragment_program_shadow */ + +#ifdef GL_ARB_fragment_shader + +#endif /* GL_ARB_fragment_shader */ + +#ifdef GL_ARB_framebuffer_object + +static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r; + r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r; + r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r; + r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r; + r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r; + r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r; + r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r; + r = ((glFramebufferTexturLayer = (PFNGLFRAMEBUFFERTEXTURLAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexturLayer")) == NULL) || r; + r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r; + r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r; + r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r; + r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r; + r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r; + r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r; + r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r; + r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r; + r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r; + r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r; + r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_framebuffer_object */ + +#ifdef GL_ARB_framebuffer_sRGB + +#endif /* GL_ARB_framebuffer_sRGB */ + +#ifdef GL_ARB_geometry_shader4 + +static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r; + r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r; + r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r; + r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_geometry_shader4 */ + +#ifdef GL_ARB_half_float_pixel + +#endif /* GL_ARB_half_float_pixel */ + +#ifdef GL_ARB_half_float_vertex + +#endif /* GL_ARB_half_float_vertex */ + +#ifdef GL_ARB_imaging + +static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r; + r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r; + r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r; + r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r; + r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r; + r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r; + r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r; + r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r; + r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r; + r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r; + r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r; + r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r; + r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r; + r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r; + r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r; + r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r; + r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r; + r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r; + r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r; + r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r; + r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r; + r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r; + r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r; + r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r; + r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r; + r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r; + r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r; + r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r; + r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r; + r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r; + r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r; + r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_imaging */ + +#ifdef GL_ARB_instanced_arrays + +static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_instanced_arrays */ + +#ifdef GL_ARB_map_buffer_range + +static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r; + r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_map_buffer_range */ + +#ifdef GL_ARB_matrix_palette + +static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r; + r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r; + r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r; + r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r; + r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_matrix_palette */ + +#ifdef GL_ARB_multisample + +static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multisample */ + +#ifdef GL_ARB_multitexture + +static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r; + r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r; + r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r; + r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r; + r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r; + r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r; + r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r; + r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r; + r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r; + r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r; + r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r; + r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r; + r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r; + r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r; + r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r; + r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r; + r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r; + r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r; + r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r; + r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r; + r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r; + r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r; + r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r; + r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r; + r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r; + r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r; + r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r; + r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r; + r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r; + r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r; + r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r; + r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r; + r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r; + r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multitexture */ + +#ifdef GL_ARB_occlusion_query + +static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r; + r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r; + r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r; + r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r; + r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r; + r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r; + r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r; + r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_occlusion_query */ + +#ifdef GL_ARB_pixel_buffer_object + +#endif /* GL_ARB_pixel_buffer_object */ + +#ifdef GL_ARB_point_parameters + +static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r; + r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_point_parameters */ + +#ifdef GL_ARB_point_sprite + +#endif /* GL_ARB_point_sprite */ + +#ifdef GL_ARB_shader_objects + +static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r; + r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r; + r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r; + r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r; + r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r; + r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r; + r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r; + r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r; + r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r; + r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r; + r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r; + r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r; + r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r; + r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r; + r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r; + r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r; + r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r; + r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r; + r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r; + r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r; + r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r; + r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r; + r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r; + r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r; + r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r; + r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r; + r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r; + r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r; + r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r; + r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r; + r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r; + r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r; + r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r; + r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r; + r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r; + r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r; + r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r; + r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r; + r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_objects */ + +#ifdef GL_ARB_shading_language_100 + +#endif /* GL_ARB_shading_language_100 */ + +#ifdef GL_ARB_shadow + +#endif /* GL_ARB_shadow */ + +#ifdef GL_ARB_shadow_ambient + +#endif /* GL_ARB_shadow_ambient */ + +#ifdef GL_ARB_texture_border_clamp + +#endif /* GL_ARB_texture_border_clamp */ + +#ifdef GL_ARB_texture_buffer_object + +static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_buffer_object */ + +#ifdef GL_ARB_texture_compression + +static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r; + r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r; + r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r; + r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r; + r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r; + r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r; + r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_compression */ + +#ifdef GL_ARB_texture_compression_rgtc + +#endif /* GL_ARB_texture_compression_rgtc */ + +#ifdef GL_ARB_texture_cube_map + +#endif /* GL_ARB_texture_cube_map */ + +#ifdef GL_ARB_texture_env_add + +#endif /* GL_ARB_texture_env_add */ + +#ifdef GL_ARB_texture_env_combine + +#endif /* GL_ARB_texture_env_combine */ + +#ifdef GL_ARB_texture_env_crossbar + +#endif /* GL_ARB_texture_env_crossbar */ + +#ifdef GL_ARB_texture_env_dot3 + +#endif /* GL_ARB_texture_env_dot3 */ + +#ifdef GL_ARB_texture_float + +#endif /* GL_ARB_texture_float */ + +#ifdef GL_ARB_texture_mirrored_repeat + +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifdef GL_ARB_texture_non_power_of_two + +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifdef GL_ARB_texture_rectangle + +#endif /* GL_ARB_texture_rectangle */ + +#ifdef GL_ARB_texture_rg + +#endif /* GL_ARB_texture_rg */ + +#ifdef GL_ARB_transpose_matrix + +static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r; + r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r; + r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r; + r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transpose_matrix */ + +#ifdef GL_ARB_vertex_array_object + +static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r; + r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r; + r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r; + r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_array_object */ + +#ifdef GL_ARB_vertex_blend + +static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r; + r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r; + r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r; + r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r; + r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r; + r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r; + r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r; + r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r; + r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r; + r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_blend */ + +#ifdef GL_ARB_vertex_buffer_object + +static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r; + r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r; + r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r; + r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r; + r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r; + r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r; + r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r; + r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r; + r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r; + r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r; + r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_buffer_object */ + +#ifdef GL_ARB_vertex_program + +static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r; + r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r; + r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r; + r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r; + r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r; + r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r; + r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r; + r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r; + r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r; + r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r; + r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r; + r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r; + r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r; + r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r; + r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r; + r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r; + r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r; + r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r; + r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r; + r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r; + r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r; + r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r; + r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r; + r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r; + r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r; + r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r; + r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r; + r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r; + r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r; + r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r; + r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r; + r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r; + r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r; + r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r; + r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r; + r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r; + r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r; + r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r; + r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r; + r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r; + r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r; + r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r; + r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r; + r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r; + r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r; + r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r; + r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r; + r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r; + r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r; + r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r; + r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r; + r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r; + r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r; + r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r; + r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r; + r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r; + r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r; + r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r; + r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r; + r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_program */ + +#ifdef GL_ARB_vertex_shader + +static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r; + r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r; + r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_shader */ + +#ifdef GL_ARB_window_pos + +static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r; + r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r; + r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r; + r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r; + r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r; + r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r; + r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r; + r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r; + r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r; + r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r; + r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r; + r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r; + r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r; + r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r; + r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r; + r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_window_pos */ + +#ifdef GL_ATIX_point_sprites + +#endif /* GL_ATIX_point_sprites */ + +#ifdef GL_ATIX_texture_env_combine3 + +#endif /* GL_ATIX_texture_env_combine3 */ + +#ifdef GL_ATIX_texture_env_route + +#endif /* GL_ATIX_texture_env_route */ + +#ifdef GL_ATIX_vertex_shader_output_point_size + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +#ifdef GL_ATI_draw_buffers + +static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_draw_buffers */ + +#ifdef GL_ATI_element_array + +static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r; + r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r; + r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_element_array */ + +#ifdef GL_ATI_envmap_bumpmap + +static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r; + r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r; + r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r; + r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_envmap_bumpmap */ + +#ifdef GL_ATI_fragment_shader + +static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r; + r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r; + r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r; + r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r; + r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r; + r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r; + r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r; + r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r; + r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r; + r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r; + r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r; + r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r; + r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r; + r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_fragment_shader */ + +#ifdef GL_ATI_map_object_buffer + +static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r; + r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_map_object_buffer */ + +#ifdef GL_ATI_pn_triangles + +static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r; + r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_pn_triangles */ + +#ifdef GL_ATI_separate_stencil + +static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r; + r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_separate_stencil */ + +#ifdef GL_ATI_shader_texture_lod + +#endif /* GL_ATI_shader_texture_lod */ + +#ifdef GL_ATI_text_fragment_shader + +#endif /* GL_ATI_text_fragment_shader */ + +#ifdef GL_ATI_texture_compression_3dc + +#endif /* GL_ATI_texture_compression_3dc */ + +#ifdef GL_ATI_texture_env_combine3 + +#endif /* GL_ATI_texture_env_combine3 */ + +#ifdef GL_ATI_texture_float + +#endif /* GL_ATI_texture_float */ + +#ifdef GL_ATI_texture_mirror_once + +#endif /* GL_ATI_texture_mirror_once */ + +#ifdef GL_ATI_vertex_array_object + +static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r; + r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r; + r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r; + r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r; + r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r; + r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r; + r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r; + r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r; + r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r; + r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r; + r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r; + r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_array_object */ + +#ifdef GL_ATI_vertex_attrib_array_object + +static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r; + r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r; + r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifdef GL_ATI_vertex_streams + +static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r; + r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r; + r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r; + r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r; + r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r; + r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r; + r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r; + r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r; + r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r; + r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r; + r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r; + r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r; + r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r; + r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r; + r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r; + r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r; + r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r; + r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r; + r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r; + r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r; + r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r; + r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r; + r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r; + r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r; + r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r; + r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r; + r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r; + r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r; + r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r; + r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r; + r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r; + r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r; + r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r; + r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r; + r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r; + r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r; + r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_streams */ + +#ifdef GL_EXT_422_pixels + +#endif /* GL_EXT_422_pixels */ + +#ifdef GL_EXT_Cg_shader + +#endif /* GL_EXT_Cg_shader */ + +#ifdef GL_EXT_abgr + +#endif /* GL_EXT_abgr */ + +#ifdef GL_EXT_bgra + +#endif /* GL_EXT_bgra */ + +#ifdef GL_EXT_bindable_uniform + +static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r; + r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r; + r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_bindable_uniform */ + +#ifdef GL_EXT_blend_color + +static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_color */ + +#ifdef GL_EXT_blend_equation_separate + +static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_equation_separate */ + +#ifdef GL_EXT_blend_func_separate + +static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_func_separate */ + +#ifdef GL_EXT_blend_logic_op + +#endif /* GL_EXT_blend_logic_op */ + +#ifdef GL_EXT_blend_minmax + +static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_minmax */ + +#ifdef GL_EXT_blend_subtract + +#endif /* GL_EXT_blend_subtract */ + +#ifdef GL_EXT_clip_volume_hint + +#endif /* GL_EXT_clip_volume_hint */ + +#ifdef GL_EXT_cmyka + +#endif /* GL_EXT_cmyka */ + +#ifdef GL_EXT_color_subtable + +static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r; + r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_color_subtable */ + +#ifdef GL_EXT_compiled_vertex_array + +static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r; + r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_compiled_vertex_array */ + +#ifdef GL_EXT_convolution + +static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r; + r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r; + r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r; + r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r; + r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r; + r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r; + r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r; + r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r; + r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r; + r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r; + r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_convolution */ + +#ifdef GL_EXT_coordinate_frame + +static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r; + r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_coordinate_frame */ + +#ifdef GL_EXT_copy_texture + +static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r; + r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_copy_texture */ + +#ifdef GL_EXT_cull_vertex + +static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r; + r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_cull_vertex */ + +#ifdef GL_EXT_depth_bounds_test + +static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_depth_bounds_test */ + +#ifdef GL_EXT_direct_state_access + +static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r; + r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r; + r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r; + r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r; + r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r; + r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r; + r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r; + r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r; + r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r; + r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r; + r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r; + r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r; + r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r; + r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r; + r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r; + r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r; + r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r; + r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r; + r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r; + r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r; + r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r; + r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r; + r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r; + r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r; + r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r; + r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r; + r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r; + r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r; + r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r; + r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r; + r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r; + r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r; + r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r; + r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r; + r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r; + r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r; + r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r; + r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r; + r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r; + r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r; + r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r; + r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r; + r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r; + r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r; + r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r; + r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r; + r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r; + r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r; + r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r; + r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r; + r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r; + r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r; + r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r; + r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r; + r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r; + r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r; + r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r; + r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r; + r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r; + r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r; + r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r; + r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r; + r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r; + r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r; + r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r; + r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r; + r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r; + r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r; + r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r; + r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r; + r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r; + r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r; + r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r; + r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r; + r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r; + r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r; + r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r; + r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r; + r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r; + r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r; + r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r; + r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r; + r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r; + r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r; + r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r; + r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r; + r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r; + r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r; + r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r; + r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r; + r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r; + r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r; + r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r; + r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r; + r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r; + r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r; + r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r; + r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r; + r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r; + r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r; + r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r; + r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r; + r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r; + r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r; + r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r; + r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r; + r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r; + r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r; + r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r; + r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r; + r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r; + r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r; + r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r; + r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r; + r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r; + r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r; + r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_direct_state_access */ + +#ifdef GL_EXT_draw_buffers2 + +static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r; + r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r; + r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r; + r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r; + r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r; + r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_buffers2 */ + +#ifdef GL_EXT_draw_instanced + +static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r; + r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_instanced */ + +#ifdef GL_EXT_draw_range_elements + +static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_range_elements */ + +#ifdef GL_EXT_fog_coord + +static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r; + r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r; + r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r; + r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r; + r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fog_coord */ + +#ifdef GL_EXT_fragment_lighting + +static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r; + r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r; + r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r; + r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r; + r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r; + r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r; + r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r; + r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r; + r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r; + r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r; + r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r; + r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r; + r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r; + r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r; + r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r; + r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r; + r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r; + r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fragment_lighting */ + +#ifdef GL_EXT_framebuffer_blit + +static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_blit */ + +#ifdef GL_EXT_framebuffer_multisample + +static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_multisample */ + +#ifdef GL_EXT_framebuffer_object + +static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r; + r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r; + r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r; + r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r; + r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r; + r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r; + r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r; + r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r; + r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r; + r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r; + r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r; + r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r; + r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r; + r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_object */ + +#ifdef GL_EXT_framebuffer_sRGB + +#endif /* GL_EXT_framebuffer_sRGB */ + +#ifdef GL_EXT_geometry_shader4 + +static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r; + r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r; + r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_geometry_shader4 */ + +#ifdef GL_EXT_gpu_program_parameters + +static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r; + r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_program_parameters */ + +#ifdef GL_EXT_gpu_shader4 + +static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r; + r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r; + r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r; + r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r; + r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r; + r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r; + r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r; + r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r; + r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r; + r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r; + r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r; + r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r; + r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r; + r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r; + r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r; + r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r; + r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r; + r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r; + r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r; + r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r; + r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r; + r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r; + r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r; + r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r; + r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r; + r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r; + r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r; + r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r; + r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r; + r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r; + r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r; + r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r; + r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r; + r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_shader4 */ + +#ifdef GL_EXT_histogram + +static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r; + r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r; + r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r; + r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r; + r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r; + r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r; + r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r; + r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r; + r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r; + r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_histogram */ + +#ifdef GL_EXT_index_array_formats + +#endif /* GL_EXT_index_array_formats */ + +#ifdef GL_EXT_index_func + +static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_func */ + +#ifdef GL_EXT_index_material + +static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_material */ + +#ifdef GL_EXT_index_texture + +#endif /* GL_EXT_index_texture */ + +#ifdef GL_EXT_light_texture + +static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r; + r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r; + r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_light_texture */ + +#ifdef GL_EXT_misc_attribute + +#endif /* GL_EXT_misc_attribute */ + +#ifdef GL_EXT_multi_draw_arrays + +static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r; + r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multi_draw_arrays */ + +#ifdef GL_EXT_multisample + +static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r; + r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multisample */ + +#ifdef GL_EXT_packed_depth_stencil + +#endif /* GL_EXT_packed_depth_stencil */ + +#ifdef GL_EXT_packed_float + +#endif /* GL_EXT_packed_float */ + +#ifdef GL_EXT_packed_pixels + +#endif /* GL_EXT_packed_pixels */ + +#ifdef GL_EXT_paletted_texture + +static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r; + r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r; + r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r; + r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_paletted_texture */ + +#ifdef GL_EXT_pixel_buffer_object + +#endif /* GL_EXT_pixel_buffer_object */ + +#ifdef GL_EXT_pixel_transform + +static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r; + r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r; + r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r; + r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_pixel_transform */ + +#ifdef GL_EXT_pixel_transform_color_table + +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifdef GL_EXT_point_parameters + +static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r; + r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_point_parameters */ + +#ifdef GL_EXT_polygon_offset + +static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_polygon_offset */ + +#ifdef GL_EXT_rescale_normal + +#endif /* GL_EXT_rescale_normal */ + +#ifdef GL_EXT_scene_marker + +static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r; + r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_scene_marker */ + +#ifdef GL_EXT_secondary_color + +static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r; + r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r; + r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r; + r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r; + r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r; + r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r; + r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r; + r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r; + r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r; + r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r; + r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r; + r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r; + r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r; + r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r; + r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r; + r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r; + r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_secondary_color */ + +#ifdef GL_EXT_separate_specular_color + +#endif /* GL_EXT_separate_specular_color */ + +#ifdef GL_EXT_shadow_funcs + +#endif /* GL_EXT_shadow_funcs */ + +#ifdef GL_EXT_shared_texture_palette + +#endif /* GL_EXT_shared_texture_palette */ + +#ifdef GL_EXT_stencil_clear_tag + +#endif /* GL_EXT_stencil_clear_tag */ + +#ifdef GL_EXT_stencil_two_side + +static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_stencil_two_side */ + +#ifdef GL_EXT_stencil_wrap + +#endif /* GL_EXT_stencil_wrap */ + +#ifdef GL_EXT_subtexture + +static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r; + r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r; + r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_subtexture */ + +#ifdef GL_EXT_texture + +#endif /* GL_EXT_texture */ + +#ifdef GL_EXT_texture3D + +static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture3D */ + +#ifdef GL_EXT_texture_array + +#endif /* GL_EXT_texture_array */ + +#ifdef GL_EXT_texture_buffer_object + +static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_buffer_object */ + +#ifdef GL_EXT_texture_compression_dxt1 + +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifdef GL_EXT_texture_compression_latc + +#endif /* GL_EXT_texture_compression_latc */ + +#ifdef GL_EXT_texture_compression_rgtc + +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifdef GL_EXT_texture_compression_s3tc + +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifdef GL_EXT_texture_cube_map + +#endif /* GL_EXT_texture_cube_map */ + +#ifdef GL_EXT_texture_edge_clamp + +#endif /* GL_EXT_texture_edge_clamp */ + +#ifdef GL_EXT_texture_env + +#endif /* GL_EXT_texture_env */ + +#ifdef GL_EXT_texture_env_add + +#endif /* GL_EXT_texture_env_add */ + +#ifdef GL_EXT_texture_env_combine + +#endif /* GL_EXT_texture_env_combine */ + +#ifdef GL_EXT_texture_env_dot3 + +#endif /* GL_EXT_texture_env_dot3 */ + +#ifdef GL_EXT_texture_filter_anisotropic + +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifdef GL_EXT_texture_integer + +static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r; + r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r; + r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r; + r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r; + r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r; + r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_integer */ + +#ifdef GL_EXT_texture_lod_bias + +#endif /* GL_EXT_texture_lod_bias */ + +#ifdef GL_EXT_texture_mirror_clamp + +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifdef GL_EXT_texture_object + +static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r; + r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r; + r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r; + r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r; + r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r; + r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_object */ + +#ifdef GL_EXT_texture_perturb_normal + +static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_perturb_normal */ + +#ifdef GL_EXT_texture_rectangle + +#endif /* GL_EXT_texture_rectangle */ + +#ifdef GL_EXT_texture_sRGB + +#endif /* GL_EXT_texture_sRGB */ + +#ifdef GL_EXT_texture_shared_exponent + +#endif /* GL_EXT_texture_shared_exponent */ + +#ifdef GL_EXT_texture_swizzle + +#endif /* GL_EXT_texture_swizzle */ + +#ifdef GL_EXT_timer_query + +static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r; + r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_timer_query */ + +#ifdef GL_EXT_transform_feedback + +static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r; + r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r; + r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r; + r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r; + r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r; + r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_transform_feedback */ + +#ifdef GL_EXT_vertex_array + +static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r; + r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r; + r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r; + r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r; + r = ((glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointervEXT")) == NULL) || r; + r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r; + r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r; + r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r; + r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_array */ + +#ifdef GL_EXT_vertex_array_bgra + +#endif /* GL_EXT_vertex_array_bgra */ + +#ifdef GL_EXT_vertex_shader + +static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r; + r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r; + r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r; + r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r; + r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r; + r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r; + r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r; + r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r; + r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r; + r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r; + r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r; + r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r; + r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r; + r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r; + r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r; + r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r; + r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r; + r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r; + r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r; + r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r; + r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r; + r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r; + r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r; + r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r; + r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r; + r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r; + r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r; + r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r; + r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r; + r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r; + r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r; + r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r; + r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r; + r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r; + r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r; + r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r; + r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r; + r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r; + r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r; + r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r; + r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r; + r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_shader */ + +#ifdef GL_EXT_vertex_weighting + +static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r; + r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r; + r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_weighting */ + +#ifdef GL_GREMEDY_frame_terminator + +static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_frame_terminator */ + +#ifdef GL_GREMEDY_string_marker + +static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_string_marker */ + +#ifdef GL_HP_convolution_border_modes + +#endif /* GL_HP_convolution_border_modes */ + +#ifdef GL_HP_image_transform + +static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r; + r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r; + r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r; + r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r; + r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r; + r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r; + + return r; +} + +#endif /* GL_HP_image_transform */ + +#ifdef GL_HP_occlusion_test + +#endif /* GL_HP_occlusion_test */ + +#ifdef GL_HP_texture_lighting + +#endif /* GL_HP_texture_lighting */ + +#ifdef GL_IBM_cull_vertex + +#endif /* GL_IBM_cull_vertex */ + +#ifdef GL_IBM_multimode_draw_arrays + +static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r; + r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifdef GL_IBM_rasterpos_clip + +#endif /* GL_IBM_rasterpos_clip */ + +#ifdef GL_IBM_static_data + +#endif /* GL_IBM_static_data */ + +#ifdef GL_IBM_texture_mirrored_repeat + +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifdef GL_IBM_vertex_array_lists + +static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r; + r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r; + r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r; + r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r; + r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r; + r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r; + r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r; + r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_vertex_array_lists */ + +#ifdef GL_INGR_color_clamp + +#endif /* GL_INGR_color_clamp */ + +#ifdef GL_INGR_interlace_read + +#endif /* GL_INGR_interlace_read */ + +#ifdef GL_INTEL_parallel_arrays + +static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r; + r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r; + r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r; + r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_parallel_arrays */ + +#ifdef GL_INTEL_texture_scissor + +static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r; + r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_texture_scissor */ + +#ifdef GL_KTX_buffer_region + +static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferRegionEnabledEXT = (PFNGLBUFFERREGIONENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabledEXT")) == NULL) || r; + r = ((glDeleteBufferRegionEXT = (PFNGLDELETEBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegionEXT")) == NULL) || r; + r = ((glDrawBufferRegionEXT = (PFNGLDRAWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegionEXT")) == NULL) || r; + r = ((glNewBufferRegionEXT = (PFNGLNEWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegionEXT")) == NULL) || r; + r = ((glReadBufferRegionEXT = (PFNGLREADBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegionEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_KTX_buffer_region */ + +#ifdef GL_MESAX_texture_stack + +#endif /* GL_MESAX_texture_stack */ + +#ifdef GL_MESA_pack_invert + +#endif /* GL_MESA_pack_invert */ + +#ifdef GL_MESA_resize_buffers + +static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_resize_buffers */ + +#ifdef GL_MESA_window_pos + +static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r; + r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r; + r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r; + r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r; + r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r; + r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r; + r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r; + r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r; + r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r; + r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r; + r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r; + r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r; + r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r; + r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r; + r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r; + r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r; + r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r; + r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r; + r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r; + r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r; + r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r; + r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r; + r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r; + r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_window_pos */ + +#ifdef GL_MESA_ycbcr_texture + +#endif /* GL_MESA_ycbcr_texture */ + +#ifdef GL_NV_blend_square + +#endif /* GL_NV_blend_square */ + +#ifdef GL_NV_conditional_render + +static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r; + r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conditional_render */ + +#ifdef GL_NV_copy_depth_to_color + +#endif /* GL_NV_copy_depth_to_color */ + +#ifdef GL_NV_depth_buffer_float + +static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r; + r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r; + r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_depth_buffer_float */ + +#ifdef GL_NV_depth_clamp + +#endif /* GL_NV_depth_clamp */ + +#ifdef GL_NV_depth_range_unclamped + +#endif /* GL_NV_depth_range_unclamped */ + +#ifdef GL_NV_evaluators + +static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r; + r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r; + r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r; + r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r; + r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r; + r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r; + r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r; + r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r; + r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_evaluators */ + +#ifdef GL_NV_explicit_multisample + +static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r; + r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r; + r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_explicit_multisample */ + +#ifdef GL_NV_fence + +static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r; + r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r; + r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r; + r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r; + r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r; + r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r; + r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fence */ + +#ifdef GL_NV_float_buffer + +#endif /* GL_NV_float_buffer */ + +#ifdef GL_NV_fog_distance + +#endif /* GL_NV_fog_distance */ + +#ifdef GL_NV_fragment_program + +static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r; + r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r; + r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r; + r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r; + r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r; + r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fragment_program */ + +#ifdef GL_NV_fragment_program2 + +#endif /* GL_NV_fragment_program2 */ + +#ifdef GL_NV_fragment_program4 + +#endif /* GL_NV_fragment_program4 */ + +#ifdef GL_NV_fragment_program_option + +#endif /* GL_NV_fragment_program_option */ + +#ifdef GL_NV_framebuffer_multisample_coverage + +static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifdef GL_NV_geometry_program4 + +static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_geometry_program4 */ + +#ifdef GL_NV_geometry_shader4 + +#endif /* GL_NV_geometry_shader4 */ + +#ifdef GL_NV_gpu_program4 + +static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r; + r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r; + r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_program4 */ + +#ifdef GL_NV_half_float + +static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r; + r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r; + r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r; + r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r; + r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r; + r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r; + r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r; + r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r; + r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r; + r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r; + r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r; + r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r; + r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r; + r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r; + r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r; + r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r; + r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r; + r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r; + r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r; + r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r; + r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r; + r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r; + r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r; + r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r; + r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r; + r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r; + r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r; + r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r; + r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r; + r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r; + r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r; + r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r; + r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r; + r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r; + r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r; + r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r; + r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r; + r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r; + r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r; + r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r; + r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r; + r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r; + r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r; + r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r; + r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r; + r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_half_float */ + +#ifdef GL_NV_light_max_exponent + +#endif /* GL_NV_light_max_exponent */ + +#ifdef GL_NV_multisample_filter_hint + +#endif /* GL_NV_multisample_filter_hint */ + +#ifdef GL_NV_occlusion_query + +static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r; + r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r; + r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r; + r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r; + r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r; + r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r; + r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_occlusion_query */ + +#ifdef GL_NV_packed_depth_stencil + +#endif /* GL_NV_packed_depth_stencil */ + +#ifdef GL_NV_parameter_buffer_object + +static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r; + r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r; + r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_parameter_buffer_object */ + +#ifdef GL_NV_pixel_data_range + +static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r; + r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_pixel_data_range */ + +#ifdef GL_NV_point_sprite + +static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r; + r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_point_sprite */ + +#ifdef GL_NV_present_video + +static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r; + r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r; + r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r; + r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r; + r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r; + r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r; + r = ((glVideoParameterivNV = (PFNGLVIDEOPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_present_video */ + +#ifdef GL_NV_primitive_restart + +static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r; + r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_primitive_restart */ + +#ifdef GL_NV_register_combiners + +static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r; + r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r; + r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r; + r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r; + r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r; + r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r; + r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r; + r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners */ + +#ifdef GL_NV_register_combiners2 + +static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r; + r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners2 */ + +#ifdef GL_NV_texgen_emboss + +#endif /* GL_NV_texgen_emboss */ + +#ifdef GL_NV_texgen_reflection + +#endif /* GL_NV_texgen_reflection */ + +#ifdef GL_NV_texture_compression_vtc + +#endif /* GL_NV_texture_compression_vtc */ + +#ifdef GL_NV_texture_env_combine4 + +#endif /* GL_NV_texture_env_combine4 */ + +#ifdef GL_NV_texture_expand_normal + +#endif /* GL_NV_texture_expand_normal */ + +#ifdef GL_NV_texture_rectangle + +#endif /* GL_NV_texture_rectangle */ + +#ifdef GL_NV_texture_shader + +#endif /* GL_NV_texture_shader */ + +#ifdef GL_NV_texture_shader2 + +#endif /* GL_NV_texture_shader2 */ + +#ifdef GL_NV_texture_shader3 + +#endif /* GL_NV_texture_shader3 */ + +#ifdef GL_NV_transform_feedback + +static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r; + r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r; + r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r; + r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r; + r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r; + r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r; + r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r; + r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r; + r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r; + r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_transform_feedback */ + +#ifdef GL_NV_vertex_array_range + +static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r; + r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_array_range */ + +#ifdef GL_NV_vertex_array_range2 + +#endif /* GL_NV_vertex_array_range2 */ + +#ifdef GL_NV_vertex_program + +static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r; + r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r; + r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r; + r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r; + r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r; + r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r; + r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r; + r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r; + r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r; + r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r; + r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r; + r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r; + r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r; + r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r; + r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r; + r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r; + r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r; + r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r; + r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r; + r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r; + r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r; + r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r; + r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r; + r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r; + r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r; + r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r; + r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r; + r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r; + r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r; + r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r; + r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r; + r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r; + r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r; + r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r; + r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r; + r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r; + r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r; + r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r; + r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r; + r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r; + r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r; + r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r; + r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r; + r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r; + r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r; + r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r; + r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r; + r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r; + r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r; + r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r; + r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r; + r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r; + r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r; + r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r; + r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r; + r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r; + r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r; + r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r; + r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r; + r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r; + r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r; + r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r; + r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r; + r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_program */ + +#ifdef GL_NV_vertex_program1_1 + +#endif /* GL_NV_vertex_program1_1 */ + +#ifdef GL_NV_vertex_program2 + +#endif /* GL_NV_vertex_program2 */ + +#ifdef GL_NV_vertex_program2_option + +#endif /* GL_NV_vertex_program2_option */ + +#ifdef GL_NV_vertex_program3 + +#endif /* GL_NV_vertex_program3 */ + +#ifdef GL_NV_vertex_program4 + +#endif /* GL_NV_vertex_program4 */ + +#ifdef GL_OES_byte_coordinates + +#endif /* GL_OES_byte_coordinates */ + +#ifdef GL_OES_compressed_paletted_texture + +#endif /* GL_OES_compressed_paletted_texture */ + +#ifdef GL_OES_read_format + +#endif /* GL_OES_read_format */ + +#ifdef GL_OES_single_precision + +static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC)glewGetProcAddress((const GLubyte*)"glClearDepthfOES")) == NULL) || r; + r = ((glClipPlanefOES = (PFNGLCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glClipPlanefOES")) == NULL) || r; + r = ((glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC)glewGetProcAddress((const GLubyte*)"glDepthRangefOES")) == NULL) || r; + r = ((glFrustumfOES = (PFNGLFRUSTUMFOESPROC)glewGetProcAddress((const GLubyte*)"glFrustumfOES")) == NULL) || r; + r = ((glGetClipPlanefOES = (PFNGLGETCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanefOES")) == NULL) || r; + r = ((glOrthofOES = (PFNGLORTHOFOESPROC)glewGetProcAddress((const GLubyte*)"glOrthofOES")) == NULL) || r; + + return r; +} + +#endif /* GL_OES_single_precision */ + +#ifdef GL_OML_interlace + +#endif /* GL_OML_interlace */ + +#ifdef GL_OML_resample + +#endif /* GL_OML_resample */ + +#ifdef GL_OML_subsample + +#endif /* GL_OML_subsample */ + +#ifdef GL_PGI_misc_hints + +#endif /* GL_PGI_misc_hints */ + +#ifdef GL_PGI_vertex_hints + +#endif /* GL_PGI_vertex_hints */ + +#ifdef GL_REND_screen_coordinates + +#endif /* GL_REND_screen_coordinates */ + +#ifdef GL_S3_s3tc + +#endif /* GL_S3_s3tc */ + +#ifdef GL_SGIS_color_range + +#endif /* GL_SGIS_color_range */ + +#ifdef GL_SGIS_detail_texture + +static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r; + r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_detail_texture */ + +#ifdef GL_SGIS_fog_function + +static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r; + r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_fog_function */ + +#ifdef GL_SGIS_generate_mipmap + +#endif /* GL_SGIS_generate_mipmap */ + +#ifdef GL_SGIS_multisample + +static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r; + r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_multisample */ + +#ifdef GL_SGIS_pixel_texture + +#endif /* GL_SGIS_pixel_texture */ + +#ifdef GL_SGIS_point_line_texgen + +#endif /* GL_SGIS_point_line_texgen */ + +#ifdef GL_SGIS_sharpen_texture + +static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r; + r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_sharpen_texture */ + +#ifdef GL_SGIS_texture4D + +static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r; + r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture4D */ + +#ifdef GL_SGIS_texture_border_clamp + +#endif /* GL_SGIS_texture_border_clamp */ + +#ifdef GL_SGIS_texture_edge_clamp + +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifdef GL_SGIS_texture_filter4 + +static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r; + r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture_filter4 */ + +#ifdef GL_SGIS_texture_lod + +#endif /* GL_SGIS_texture_lod */ + +#ifdef GL_SGIS_texture_select + +#endif /* GL_SGIS_texture_select */ + +#ifdef GL_SGIX_async + +static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r; + r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r; + r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r; + r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r; + r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r; + r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_async */ + +#ifdef GL_SGIX_async_histogram + +#endif /* GL_SGIX_async_histogram */ + +#ifdef GL_SGIX_async_pixel + +#endif /* GL_SGIX_async_pixel */ + +#ifdef GL_SGIX_blend_alpha_minmax + +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifdef GL_SGIX_clipmap + +#endif /* GL_SGIX_clipmap */ + +#ifdef GL_SGIX_convolution_accuracy + +#endif /* GL_SGIX_convolution_accuracy */ + +#ifdef GL_SGIX_depth_texture + +#endif /* GL_SGIX_depth_texture */ + +#ifdef GL_SGIX_flush_raster + +static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_flush_raster */ + +#ifdef GL_SGIX_fog_offset + +#endif /* GL_SGIX_fog_offset */ + +#ifdef GL_SGIX_fog_texture + +static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fog_texture */ + +#ifdef GL_SGIX_fragment_specular_lighting + +static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r; + r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r; + r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r; + r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r; + r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r; + r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r; + r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r; + r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r; + r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r; + r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r; + r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r; + r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r; + r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r; + r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fragment_specular_lighting */ + +#ifdef GL_SGIX_framezoom + +static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_framezoom */ + +#ifdef GL_SGIX_interlace + +#endif /* GL_SGIX_interlace */ + +#ifdef GL_SGIX_ir_instrument1 + +#endif /* GL_SGIX_ir_instrument1 */ + +#ifdef GL_SGIX_list_priority + +#endif /* GL_SGIX_list_priority */ + +#ifdef GL_SGIX_pixel_texture + +static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_pixel_texture */ + +#ifdef GL_SGIX_pixel_texture_bits + +#endif /* GL_SGIX_pixel_texture_bits */ + +#ifdef GL_SGIX_reference_plane + +static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_reference_plane */ + +#ifdef GL_SGIX_resample + +#endif /* GL_SGIX_resample */ + +#ifdef GL_SGIX_shadow + +#endif /* GL_SGIX_shadow */ + +#ifdef GL_SGIX_shadow_ambient + +#endif /* GL_SGIX_shadow_ambient */ + +#ifdef GL_SGIX_sprite + +static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r; + r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r; + r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r; + r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_sprite */ + +#ifdef GL_SGIX_tag_sample_buffer + +static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifdef GL_SGIX_texture_add_env + +#endif /* GL_SGIX_texture_add_env */ + +#ifdef GL_SGIX_texture_coordinate_clamp + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifdef GL_SGIX_texture_lod_bias + +#endif /* GL_SGIX_texture_lod_bias */ + +#ifdef GL_SGIX_texture_multi_buffer + +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifdef GL_SGIX_texture_range + +#endif /* GL_SGIX_texture_range */ + +#ifdef GL_SGIX_texture_scale_bias + +#endif /* GL_SGIX_texture_scale_bias */ + +#ifdef GL_SGIX_vertex_preclip + +#endif /* GL_SGIX_vertex_preclip */ + +#ifdef GL_SGIX_vertex_preclip_hint + +#endif /* GL_SGIX_vertex_preclip_hint */ + +#ifdef GL_SGIX_ycrcb + +#endif /* GL_SGIX_ycrcb */ + +#ifdef GL_SGI_color_matrix + +#endif /* GL_SGI_color_matrix */ + +#ifdef GL_SGI_color_table + +static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r; + r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r; + r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r; + r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r; + r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r; + r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r; + r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r; + + return r; +} + +#endif /* GL_SGI_color_table */ + +#ifdef GL_SGI_texture_color_table + +#endif /* GL_SGI_texture_color_table */ + +#ifdef GL_SUNX_constant_data + +static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r; + + return r; +} + +#endif /* GL_SUNX_constant_data */ + +#ifdef GL_SUN_convolution_border_modes + +#endif /* GL_SUN_convolution_border_modes */ + +#ifdef GL_SUN_global_alpha + +static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r; + r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_global_alpha */ + +#ifdef GL_SUN_mesh_array + +#endif /* GL_SUN_mesh_array */ + +#ifdef GL_SUN_read_video_pixels + +static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_read_video_pixels */ + +#ifdef GL_SUN_slice_accum + +#endif /* GL_SUN_slice_accum */ + +#ifdef GL_SUN_triangle_list + +static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r; + r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r; + r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r; + r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r; + r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r; + r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r; + r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_triangle_list */ + +#ifdef GL_SUN_vertex + +static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r; + r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r; + r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r; + r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r; + r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r; + r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_vertex */ + +#ifdef GL_WIN_phong_shading + +#endif /* GL_WIN_phong_shading */ + +#ifdef GL_WIN_specular_fog + +#endif /* GL_WIN_specular_fog */ + +#ifdef GL_WIN_swap_hint + +static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r; + + return r; +} + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +/* + * Search for name in the extensions string. Use of strstr() + * is not sufficient because extension names can be prefixes of + * other extension names. Could use strtok() but the constant + * string returned by glGetString might be in read-only memory. + */ +GLboolean glewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + p = (GLubyte*)glGetString(GL_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +/* ------------------------------------------------------------------------- */ + +#ifndef GLEW_MX +static +#endif +GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) +{ + const GLubyte* s; + GLuint dot, major, minor; + /* query opengl version */ + s = glGetString(GL_VERSION); + dot = _glewStrCLen(s, '.'); + major = dot-1; + minor = dot+1; + if (dot == 0 || s[minor] == '\0') + return GLEW_ERROR_NO_GL_VERSION; + if (s[major] == '1' && s[minor] == '0') + { + return GLEW_ERROR_GL_VERSION_10_ONLY; + } + else + { + CONST_CAST(GLEW_VERSION_1_1) = GL_TRUE; + if (s[major] >= '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; + CONST_CAST(GLEW_VERSION_2_0) = GL_TRUE; + if (s[minor] >= '1') + { + CONST_CAST(GLEW_VERSION_2_1) = GL_TRUE; + } + } + else + { + if (s[minor] >= '5') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '4') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '3') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] < '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + } + } + /* initialize extensions */ +#ifdef GL_VERSION_1_2 + if (glewExperimental || GLEW_VERSION_1_2) CONST_CAST(GLEW_VERSION_1_2) = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_3 + if (glewExperimental || GLEW_VERSION_1_3) CONST_CAST(GLEW_VERSION_1_3) = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_3 */ +#ifdef GL_VERSION_1_4 + if (glewExperimental || GLEW_VERSION_1_4) CONST_CAST(GLEW_VERSION_1_4) = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_4 */ +#ifdef GL_VERSION_1_5 + if (glewExperimental || GLEW_VERSION_1_5) CONST_CAST(GLEW_VERSION_1_5) = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_5 */ +#ifdef GL_VERSION_2_0 + if (glewExperimental || GLEW_VERSION_2_0) CONST_CAST(GLEW_VERSION_2_0) = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_2_0 */ +#ifdef GL_VERSION_2_1 + if (glewExperimental || GLEW_VERSION_2_1) CONST_CAST(GLEW_VERSION_2_1) = !_glewInit_GL_VERSION_2_1(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_2_1 */ +#ifdef GL_VERSION_3_0 + if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_0 */ +#ifdef GL_3DFX_multisample + CONST_CAST(GLEW_3DFX_multisample) = glewGetExtension("GL_3DFX_multisample"); +#endif /* GL_3DFX_multisample */ +#ifdef GL_3DFX_tbuffer + CONST_CAST(GLEW_3DFX_tbuffer) = glewGetExtension("GL_3DFX_tbuffer"); + if (glewExperimental || GLEW_3DFX_tbuffer) CONST_CAST(GLEW_3DFX_tbuffer) = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_3DFX_texture_compression_FXT1 + CONST_CAST(GLEW_3DFX_texture_compression_FXT1) = glewGetExtension("GL_3DFX_texture_compression_FXT1"); +#endif /* GL_3DFX_texture_compression_FXT1 */ +#ifdef GL_APPLE_client_storage + CONST_CAST(GLEW_APPLE_client_storage) = glewGetExtension("GL_APPLE_client_storage"); +#endif /* GL_APPLE_client_storage */ +#ifdef GL_APPLE_element_array + CONST_CAST(GLEW_APPLE_element_array) = glewGetExtension("GL_APPLE_element_array"); + if (glewExperimental || GLEW_APPLE_element_array) CONST_CAST(GLEW_APPLE_element_array) = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + CONST_CAST(GLEW_APPLE_fence) = glewGetExtension("GL_APPLE_fence"); + if (glewExperimental || GLEW_APPLE_fence) CONST_CAST(GLEW_APPLE_fence) = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_float_pixels + CONST_CAST(GLEW_APPLE_float_pixels) = glewGetExtension("GL_APPLE_float_pixels"); +#endif /* GL_APPLE_float_pixels */ +#ifdef GL_APPLE_flush_buffer_range + CONST_CAST(GLEW_APPLE_flush_buffer_range) = glewGetExtension("GL_APPLE_flush_buffer_range"); + if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_flush_buffer_range */ +#ifdef GL_APPLE_pixel_buffer + CONST_CAST(GLEW_APPLE_pixel_buffer) = glewGetExtension("GL_APPLE_pixel_buffer"); +#endif /* GL_APPLE_pixel_buffer */ +#ifdef GL_APPLE_specular_vector + CONST_CAST(GLEW_APPLE_specular_vector) = glewGetExtension("GL_APPLE_specular_vector"); +#endif /* GL_APPLE_specular_vector */ +#ifdef GL_APPLE_texture_range + CONST_CAST(GLEW_APPLE_texture_range) = glewGetExtension("GL_APPLE_texture_range"); + if (glewExperimental || GLEW_APPLE_texture_range) CONST_CAST(GLEW_APPLE_texture_range) = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_transform_hint + CONST_CAST(GLEW_APPLE_transform_hint) = glewGetExtension("GL_APPLE_transform_hint"); +#endif /* GL_APPLE_transform_hint */ +#ifdef GL_APPLE_vertex_array_object + CONST_CAST(GLEW_APPLE_vertex_array_object) = glewGetExtension("GL_APPLE_vertex_array_object"); + if (glewExperimental || GLEW_APPLE_vertex_array_object) CONST_CAST(GLEW_APPLE_vertex_array_object) = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_object */ +#ifdef GL_APPLE_vertex_array_range + CONST_CAST(GLEW_APPLE_vertex_array_range) = glewGetExtension("GL_APPLE_vertex_array_range"); + if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_range */ +#ifdef GL_APPLE_ycbcr_422 + CONST_CAST(GLEW_APPLE_ycbcr_422) = glewGetExtension("GL_APPLE_ycbcr_422"); +#endif /* GL_APPLE_ycbcr_422 */ +#ifdef GL_ARB_color_buffer_float + CONST_CAST(GLEW_ARB_color_buffer_float) = glewGetExtension("GL_ARB_color_buffer_float"); + if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_color_buffer_float */ +#ifdef GL_ARB_depth_buffer_float + CONST_CAST(GLEW_ARB_depth_buffer_float) = glewGetExtension("GL_ARB_depth_buffer_float"); +#endif /* GL_ARB_depth_buffer_float */ +#ifdef GL_ARB_depth_texture + CONST_CAST(GLEW_ARB_depth_texture) = glewGetExtension("GL_ARB_depth_texture"); +#endif /* GL_ARB_depth_texture */ +#ifdef GL_ARB_draw_buffers + CONST_CAST(GLEW_ARB_draw_buffers) = glewGetExtension("GL_ARB_draw_buffers"); + if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_draw_instanced + CONST_CAST(GLEW_ARB_draw_instanced) = glewGetExtension("GL_ARB_draw_instanced"); + if (glewExperimental || GLEW_ARB_draw_instanced) CONST_CAST(GLEW_ARB_draw_instanced) = !_glewInit_GL_ARB_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_instanced */ +#ifdef GL_ARB_fragment_program + CONST_CAST(GLEW_ARB_fragment_program) = glewGetExtension("GL_ARB_fragment_program"); +#endif /* GL_ARB_fragment_program */ +#ifdef GL_ARB_fragment_program_shadow + CONST_CAST(GLEW_ARB_fragment_program_shadow) = glewGetExtension("GL_ARB_fragment_program_shadow"); +#endif /* GL_ARB_fragment_program_shadow */ +#ifdef GL_ARB_fragment_shader + CONST_CAST(GLEW_ARB_fragment_shader) = glewGetExtension("GL_ARB_fragment_shader"); +#endif /* GL_ARB_fragment_shader */ +#ifdef GL_ARB_framebuffer_object + CONST_CAST(GLEW_ARB_framebuffer_object) = glewGetExtension("GL_ARB_framebuffer_object"); + if (glewExperimental || GLEW_ARB_framebuffer_object) CONST_CAST(GLEW_ARB_framebuffer_object) = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_framebuffer_object */ +#ifdef GL_ARB_framebuffer_sRGB + CONST_CAST(GLEW_ARB_framebuffer_sRGB) = glewGetExtension("GL_ARB_framebuffer_sRGB"); +#endif /* GL_ARB_framebuffer_sRGB */ +#ifdef GL_ARB_geometry_shader4 + CONST_CAST(GLEW_ARB_geometry_shader4) = glewGetExtension("GL_ARB_geometry_shader4"); + if (glewExperimental || GLEW_ARB_geometry_shader4) CONST_CAST(GLEW_ARB_geometry_shader4) = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_geometry_shader4 */ +#ifdef GL_ARB_half_float_pixel + CONST_CAST(GLEW_ARB_half_float_pixel) = glewGetExtension("GL_ARB_half_float_pixel"); +#endif /* GL_ARB_half_float_pixel */ +#ifdef GL_ARB_half_float_vertex + CONST_CAST(GLEW_ARB_half_float_vertex) = glewGetExtension("GL_ARB_half_float_vertex"); +#endif /* GL_ARB_half_float_vertex */ +#ifdef GL_ARB_imaging + CONST_CAST(GLEW_ARB_imaging) = glewGetExtension("GL_ARB_imaging"); + if (glewExperimental || GLEW_ARB_imaging) CONST_CAST(GLEW_ARB_imaging) = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_instanced_arrays + CONST_CAST(GLEW_ARB_instanced_arrays) = glewGetExtension("GL_ARB_instanced_arrays"); + if (glewExperimental || GLEW_ARB_instanced_arrays) CONST_CAST(GLEW_ARB_instanced_arrays) = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_instanced_arrays */ +#ifdef GL_ARB_map_buffer_range + CONST_CAST(GLEW_ARB_map_buffer_range) = glewGetExtension("GL_ARB_map_buffer_range"); + if (glewExperimental || GLEW_ARB_map_buffer_range) CONST_CAST(GLEW_ARB_map_buffer_range) = !_glewInit_GL_ARB_map_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_map_buffer_range */ +#ifdef GL_ARB_matrix_palette + CONST_CAST(GLEW_ARB_matrix_palette) = glewGetExtension("GL_ARB_matrix_palette"); + if (glewExperimental || GLEW_ARB_matrix_palette) CONST_CAST(GLEW_ARB_matrix_palette) = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multisample + CONST_CAST(GLEW_ARB_multisample) = glewGetExtension("GL_ARB_multisample"); + if (glewExperimental || GLEW_ARB_multisample) CONST_CAST(GLEW_ARB_multisample) = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + CONST_CAST(GLEW_ARB_multitexture) = glewGetExtension("GL_ARB_multitexture"); + if (glewExperimental || GLEW_ARB_multitexture) CONST_CAST(GLEW_ARB_multitexture) = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + CONST_CAST(GLEW_ARB_occlusion_query) = glewGetExtension("GL_ARB_occlusion_query"); + if (glewExperimental || GLEW_ARB_occlusion_query) CONST_CAST(GLEW_ARB_occlusion_query) = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_pixel_buffer_object + CONST_CAST(GLEW_ARB_pixel_buffer_object) = glewGetExtension("GL_ARB_pixel_buffer_object"); +#endif /* GL_ARB_pixel_buffer_object */ +#ifdef GL_ARB_point_parameters + CONST_CAST(GLEW_ARB_point_parameters) = glewGetExtension("GL_ARB_point_parameters"); + if (glewExperimental || GLEW_ARB_point_parameters) CONST_CAST(GLEW_ARB_point_parameters) = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_point_sprite + CONST_CAST(GLEW_ARB_point_sprite) = glewGetExtension("GL_ARB_point_sprite"); +#endif /* GL_ARB_point_sprite */ +#ifdef GL_ARB_shader_objects + CONST_CAST(GLEW_ARB_shader_objects) = glewGetExtension("GL_ARB_shader_objects"); + if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shading_language_100 + CONST_CAST(GLEW_ARB_shading_language_100) = glewGetExtension("GL_ARB_shading_language_100"); +#endif /* GL_ARB_shading_language_100 */ +#ifdef GL_ARB_shadow + CONST_CAST(GLEW_ARB_shadow) = glewGetExtension("GL_ARB_shadow"); +#endif /* GL_ARB_shadow */ +#ifdef GL_ARB_shadow_ambient + CONST_CAST(GLEW_ARB_shadow_ambient) = glewGetExtension("GL_ARB_shadow_ambient"); +#endif /* GL_ARB_shadow_ambient */ +#ifdef GL_ARB_texture_border_clamp + CONST_CAST(GLEW_ARB_texture_border_clamp) = glewGetExtension("GL_ARB_texture_border_clamp"); +#endif /* GL_ARB_texture_border_clamp */ +#ifdef GL_ARB_texture_buffer_object + CONST_CAST(GLEW_ARB_texture_buffer_object) = glewGetExtension("GL_ARB_texture_buffer_object"); + if (glewExperimental || GLEW_ARB_texture_buffer_object) CONST_CAST(GLEW_ARB_texture_buffer_object) = !_glewInit_GL_ARB_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_buffer_object */ +#ifdef GL_ARB_texture_compression + CONST_CAST(GLEW_ARB_texture_compression) = glewGetExtension("GL_ARB_texture_compression"); + if (glewExperimental || GLEW_ARB_texture_compression) CONST_CAST(GLEW_ARB_texture_compression) = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_compression_rgtc + CONST_CAST(GLEW_ARB_texture_compression_rgtc) = glewGetExtension("GL_ARB_texture_compression_rgtc"); +#endif /* GL_ARB_texture_compression_rgtc */ +#ifdef GL_ARB_texture_cube_map + CONST_CAST(GLEW_ARB_texture_cube_map) = glewGetExtension("GL_ARB_texture_cube_map"); +#endif /* GL_ARB_texture_cube_map */ +#ifdef GL_ARB_texture_env_add + CONST_CAST(GLEW_ARB_texture_env_add) = glewGetExtension("GL_ARB_texture_env_add"); +#endif /* GL_ARB_texture_env_add */ +#ifdef GL_ARB_texture_env_combine + CONST_CAST(GLEW_ARB_texture_env_combine) = glewGetExtension("GL_ARB_texture_env_combine"); +#endif /* GL_ARB_texture_env_combine */ +#ifdef GL_ARB_texture_env_crossbar + CONST_CAST(GLEW_ARB_texture_env_crossbar) = glewGetExtension("GL_ARB_texture_env_crossbar"); +#endif /* GL_ARB_texture_env_crossbar */ +#ifdef GL_ARB_texture_env_dot3 + CONST_CAST(GLEW_ARB_texture_env_dot3) = glewGetExtension("GL_ARB_texture_env_dot3"); +#endif /* GL_ARB_texture_env_dot3 */ +#ifdef GL_ARB_texture_float + CONST_CAST(GLEW_ARB_texture_float) = glewGetExtension("GL_ARB_texture_float"); +#endif /* GL_ARB_texture_float */ +#ifdef GL_ARB_texture_mirrored_repeat + CONST_CAST(GLEW_ARB_texture_mirrored_repeat) = glewGetExtension("GL_ARB_texture_mirrored_repeat"); +#endif /* GL_ARB_texture_mirrored_repeat */ +#ifdef GL_ARB_texture_non_power_of_two + CONST_CAST(GLEW_ARB_texture_non_power_of_two) = glewGetExtension("GL_ARB_texture_non_power_of_two"); +#endif /* GL_ARB_texture_non_power_of_two */ +#ifdef GL_ARB_texture_rectangle + CONST_CAST(GLEW_ARB_texture_rectangle) = glewGetExtension("GL_ARB_texture_rectangle"); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_ARB_texture_rg + CONST_CAST(GLEW_ARB_texture_rg) = glewGetExtension("GL_ARB_texture_rg"); +#endif /* GL_ARB_texture_rg */ +#ifdef GL_ARB_transpose_matrix + CONST_CAST(GLEW_ARB_transpose_matrix) = glewGetExtension("GL_ARB_transpose_matrix"); + if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_vertex_array_object + CONST_CAST(GLEW_ARB_vertex_array_object) = glewGetExtension("GL_ARB_vertex_array_object"); + if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_array_object */ +#ifdef GL_ARB_vertex_blend + CONST_CAST(GLEW_ARB_vertex_blend) = glewGetExtension("GL_ARB_vertex_blend"); + if (glewExperimental || GLEW_ARB_vertex_blend) CONST_CAST(GLEW_ARB_vertex_blend) = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_blend */ +#ifdef GL_ARB_vertex_buffer_object + CONST_CAST(GLEW_ARB_vertex_buffer_object) = glewGetExtension("GL_ARB_vertex_buffer_object"); + if (glewExperimental || GLEW_ARB_vertex_buffer_object) CONST_CAST(GLEW_ARB_vertex_buffer_object) = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_buffer_object */ +#ifdef GL_ARB_vertex_program + CONST_CAST(GLEW_ARB_vertex_program) = glewGetExtension("GL_ARB_vertex_program"); + if (glewExperimental || GLEW_ARB_vertex_program) CONST_CAST(GLEW_ARB_vertex_program) = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + CONST_CAST(GLEW_ARB_vertex_shader) = glewGetExtension("GL_ARB_vertex_shader"); + if (glewExperimental || GLEW_ARB_vertex_shader) CONST_CAST(GLEW_ARB_vertex_shader) = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_window_pos + CONST_CAST(GLEW_ARB_window_pos) = glewGetExtension("GL_ARB_window_pos"); + if (glewExperimental || GLEW_ARB_window_pos) CONST_CAST(GLEW_ARB_window_pos) = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATIX_point_sprites + CONST_CAST(GLEW_ATIX_point_sprites) = glewGetExtension("GL_ATIX_point_sprites"); +#endif /* GL_ATIX_point_sprites */ +#ifdef GL_ATIX_texture_env_combine3 + CONST_CAST(GLEW_ATIX_texture_env_combine3) = glewGetExtension("GL_ATIX_texture_env_combine3"); +#endif /* GL_ATIX_texture_env_combine3 */ +#ifdef GL_ATIX_texture_env_route + CONST_CAST(GLEW_ATIX_texture_env_route) = glewGetExtension("GL_ATIX_texture_env_route"); +#endif /* GL_ATIX_texture_env_route */ +#ifdef GL_ATIX_vertex_shader_output_point_size + CONST_CAST(GLEW_ATIX_vertex_shader_output_point_size) = glewGetExtension("GL_ATIX_vertex_shader_output_point_size"); +#endif /* GL_ATIX_vertex_shader_output_point_size */ +#ifdef GL_ATI_draw_buffers + CONST_CAST(GLEW_ATI_draw_buffers) = glewGetExtension("GL_ATI_draw_buffers"); + if (glewExperimental || GLEW_ATI_draw_buffers) CONST_CAST(GLEW_ATI_draw_buffers) = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + CONST_CAST(GLEW_ATI_element_array) = glewGetExtension("GL_ATI_element_array"); + if (glewExperimental || GLEW_ATI_element_array) CONST_CAST(GLEW_ATI_element_array) = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + CONST_CAST(GLEW_ATI_envmap_bumpmap) = glewGetExtension("GL_ATI_envmap_bumpmap"); + if (glewExperimental || GLEW_ATI_envmap_bumpmap) CONST_CAST(GLEW_ATI_envmap_bumpmap) = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + CONST_CAST(GLEW_ATI_fragment_shader) = glewGetExtension("GL_ATI_fragment_shader"); + if (glewExperimental || GLEW_ATI_fragment_shader) CONST_CAST(GLEW_ATI_fragment_shader) = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_fragment_shader */ +#ifdef GL_ATI_map_object_buffer + CONST_CAST(GLEW_ATI_map_object_buffer) = glewGetExtension("GL_ATI_map_object_buffer"); + if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_map_object_buffer */ +#ifdef GL_ATI_pn_triangles + CONST_CAST(GLEW_ATI_pn_triangles) = glewGetExtension("GL_ATI_pn_triangles"); + if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + CONST_CAST(GLEW_ATI_separate_stencil) = glewGetExtension("GL_ATI_separate_stencil"); + if (glewExperimental || GLEW_ATI_separate_stencil) CONST_CAST(GLEW_ATI_separate_stencil) = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_separate_stencil */ +#ifdef GL_ATI_shader_texture_lod + CONST_CAST(GLEW_ATI_shader_texture_lod) = glewGetExtension("GL_ATI_shader_texture_lod"); +#endif /* GL_ATI_shader_texture_lod */ +#ifdef GL_ATI_text_fragment_shader + CONST_CAST(GLEW_ATI_text_fragment_shader) = glewGetExtension("GL_ATI_text_fragment_shader"); +#endif /* GL_ATI_text_fragment_shader */ +#ifdef GL_ATI_texture_compression_3dc + CONST_CAST(GLEW_ATI_texture_compression_3dc) = glewGetExtension("GL_ATI_texture_compression_3dc"); +#endif /* GL_ATI_texture_compression_3dc */ +#ifdef GL_ATI_texture_env_combine3 + CONST_CAST(GLEW_ATI_texture_env_combine3) = glewGetExtension("GL_ATI_texture_env_combine3"); +#endif /* GL_ATI_texture_env_combine3 */ +#ifdef GL_ATI_texture_float + CONST_CAST(GLEW_ATI_texture_float) = glewGetExtension("GL_ATI_texture_float"); +#endif /* GL_ATI_texture_float */ +#ifdef GL_ATI_texture_mirror_once + CONST_CAST(GLEW_ATI_texture_mirror_once) = glewGetExtension("GL_ATI_texture_mirror_once"); +#endif /* GL_ATI_texture_mirror_once */ +#ifdef GL_ATI_vertex_array_object + CONST_CAST(GLEW_ATI_vertex_array_object) = glewGetExtension("GL_ATI_vertex_array_object"); + if (glewExperimental || GLEW_ATI_vertex_array_object) CONST_CAST(GLEW_ATI_vertex_array_object) = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_array_object */ +#ifdef GL_ATI_vertex_attrib_array_object + CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = glewGetExtension("GL_ATI_vertex_attrib_array_object"); + if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_attrib_array_object */ +#ifdef GL_ATI_vertex_streams + CONST_CAST(GLEW_ATI_vertex_streams) = glewGetExtension("GL_ATI_vertex_streams"); + if (glewExperimental || GLEW_ATI_vertex_streams) CONST_CAST(GLEW_ATI_vertex_streams) = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_422_pixels + CONST_CAST(GLEW_EXT_422_pixels) = glewGetExtension("GL_EXT_422_pixels"); +#endif /* GL_EXT_422_pixels */ +#ifdef GL_EXT_Cg_shader + CONST_CAST(GLEW_EXT_Cg_shader) = glewGetExtension("GL_EXT_Cg_shader"); +#endif /* GL_EXT_Cg_shader */ +#ifdef GL_EXT_abgr + CONST_CAST(GLEW_EXT_abgr) = glewGetExtension("GL_EXT_abgr"); +#endif /* GL_EXT_abgr */ +#ifdef GL_EXT_bgra + CONST_CAST(GLEW_EXT_bgra) = glewGetExtension("GL_EXT_bgra"); +#endif /* GL_EXT_bgra */ +#ifdef GL_EXT_bindable_uniform + CONST_CAST(GLEW_EXT_bindable_uniform) = glewGetExtension("GL_EXT_bindable_uniform"); + if (glewExperimental || GLEW_EXT_bindable_uniform) CONST_CAST(GLEW_EXT_bindable_uniform) = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_bindable_uniform */ +#ifdef GL_EXT_blend_color + CONST_CAST(GLEW_EXT_blend_color) = glewGetExtension("GL_EXT_blend_color"); + if (glewExperimental || GLEW_EXT_blend_color) CONST_CAST(GLEW_EXT_blend_color) = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_color */ +#ifdef GL_EXT_blend_equation_separate + CONST_CAST(GLEW_EXT_blend_equation_separate) = glewGetExtension("GL_EXT_blend_equation_separate"); + if (glewExperimental || GLEW_EXT_blend_equation_separate) CONST_CAST(GLEW_EXT_blend_equation_separate) = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_equation_separate */ +#ifdef GL_EXT_blend_func_separate + CONST_CAST(GLEW_EXT_blend_func_separate) = glewGetExtension("GL_EXT_blend_func_separate"); + if (glewExperimental || GLEW_EXT_blend_func_separate) CONST_CAST(GLEW_EXT_blend_func_separate) = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_func_separate */ +#ifdef GL_EXT_blend_logic_op + CONST_CAST(GLEW_EXT_blend_logic_op) = glewGetExtension("GL_EXT_blend_logic_op"); +#endif /* GL_EXT_blend_logic_op */ +#ifdef GL_EXT_blend_minmax + CONST_CAST(GLEW_EXT_blend_minmax) = glewGetExtension("GL_EXT_blend_minmax"); + if (glewExperimental || GLEW_EXT_blend_minmax) CONST_CAST(GLEW_EXT_blend_minmax) = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_subtract + CONST_CAST(GLEW_EXT_blend_subtract) = glewGetExtension("GL_EXT_blend_subtract"); +#endif /* GL_EXT_blend_subtract */ +#ifdef GL_EXT_clip_volume_hint + CONST_CAST(GLEW_EXT_clip_volume_hint) = glewGetExtension("GL_EXT_clip_volume_hint"); +#endif /* GL_EXT_clip_volume_hint */ +#ifdef GL_EXT_cmyka + CONST_CAST(GLEW_EXT_cmyka) = glewGetExtension("GL_EXT_cmyka"); +#endif /* GL_EXT_cmyka */ +#ifdef GL_EXT_color_subtable + CONST_CAST(GLEW_EXT_color_subtable) = glewGetExtension("GL_EXT_color_subtable"); + if (glewExperimental || GLEW_EXT_color_subtable) CONST_CAST(GLEW_EXT_color_subtable) = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_color_subtable */ +#ifdef GL_EXT_compiled_vertex_array + CONST_CAST(GLEW_EXT_compiled_vertex_array) = glewGetExtension("GL_EXT_compiled_vertex_array"); + if (glewExperimental || GLEW_EXT_compiled_vertex_array) CONST_CAST(GLEW_EXT_compiled_vertex_array) = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_convolution + CONST_CAST(GLEW_EXT_convolution) = glewGetExtension("GL_EXT_convolution"); + if (glewExperimental || GLEW_EXT_convolution) CONST_CAST(GLEW_EXT_convolution) = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + CONST_CAST(GLEW_EXT_coordinate_frame) = glewGetExtension("GL_EXT_coordinate_frame"); + if (glewExperimental || GLEW_EXT_coordinate_frame) CONST_CAST(GLEW_EXT_coordinate_frame) = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_texture + CONST_CAST(GLEW_EXT_copy_texture) = glewGetExtension("GL_EXT_copy_texture"); + if (glewExperimental || GLEW_EXT_copy_texture) CONST_CAST(GLEW_EXT_copy_texture) = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + CONST_CAST(GLEW_EXT_cull_vertex) = glewGetExtension("GL_EXT_cull_vertex"); + if (glewExperimental || GLEW_EXT_cull_vertex) CONST_CAST(GLEW_EXT_cull_vertex) = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_depth_bounds_test + CONST_CAST(GLEW_EXT_depth_bounds_test) = glewGetExtension("GL_EXT_depth_bounds_test"); + if (glewExperimental || GLEW_EXT_depth_bounds_test) CONST_CAST(GLEW_EXT_depth_bounds_test) = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_depth_bounds_test */ +#ifdef GL_EXT_direct_state_access + CONST_CAST(GLEW_EXT_direct_state_access) = glewGetExtension("GL_EXT_direct_state_access"); + if (glewExperimental || GLEW_EXT_direct_state_access) CONST_CAST(GLEW_EXT_direct_state_access) = !_glewInit_GL_EXT_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_direct_state_access */ +#ifdef GL_EXT_draw_buffers2 + CONST_CAST(GLEW_EXT_draw_buffers2) = glewGetExtension("GL_EXT_draw_buffers2"); + if (glewExperimental || GLEW_EXT_draw_buffers2) CONST_CAST(GLEW_EXT_draw_buffers2) = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_buffers2 */ +#ifdef GL_EXT_draw_instanced + CONST_CAST(GLEW_EXT_draw_instanced) = glewGetExtension("GL_EXT_draw_instanced"); + if (glewExperimental || GLEW_EXT_draw_instanced) CONST_CAST(GLEW_EXT_draw_instanced) = !_glewInit_GL_EXT_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_instanced */ +#ifdef GL_EXT_draw_range_elements + CONST_CAST(GLEW_EXT_draw_range_elements) = glewGetExtension("GL_EXT_draw_range_elements"); + if (glewExperimental || GLEW_EXT_draw_range_elements) CONST_CAST(GLEW_EXT_draw_range_elements) = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_range_elements */ +#ifdef GL_EXT_fog_coord + CONST_CAST(GLEW_EXT_fog_coord) = glewGetExtension("GL_EXT_fog_coord"); + if (glewExperimental || GLEW_EXT_fog_coord) CONST_CAST(GLEW_EXT_fog_coord) = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + CONST_CAST(GLEW_EXT_fragment_lighting) = glewGetExtension("GL_EXT_fragment_lighting"); + if (glewExperimental || GLEW_EXT_fragment_lighting) CONST_CAST(GLEW_EXT_fragment_lighting) = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + CONST_CAST(GLEW_EXT_framebuffer_blit) = glewGetExtension("GL_EXT_framebuffer_blit"); + if (glewExperimental || GLEW_EXT_framebuffer_blit) CONST_CAST(GLEW_EXT_framebuffer_blit) = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + CONST_CAST(GLEW_EXT_framebuffer_multisample) = glewGetExtension("GL_EXT_framebuffer_multisample"); + if (glewExperimental || GLEW_EXT_framebuffer_multisample) CONST_CAST(GLEW_EXT_framebuffer_multisample) = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_object + CONST_CAST(GLEW_EXT_framebuffer_object) = glewGetExtension("GL_EXT_framebuffer_object"); + if (glewExperimental || GLEW_EXT_framebuffer_object) CONST_CAST(GLEW_EXT_framebuffer_object) = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_framebuffer_sRGB + CONST_CAST(GLEW_EXT_framebuffer_sRGB) = glewGetExtension("GL_EXT_framebuffer_sRGB"); +#endif /* GL_EXT_framebuffer_sRGB */ +#ifdef GL_EXT_geometry_shader4 + CONST_CAST(GLEW_EXT_geometry_shader4) = glewGetExtension("GL_EXT_geometry_shader4"); + if (glewExperimental || GLEW_EXT_geometry_shader4) CONST_CAST(GLEW_EXT_geometry_shader4) = !_glewInit_GL_EXT_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_geometry_shader4 */ +#ifdef GL_EXT_gpu_program_parameters + CONST_CAST(GLEW_EXT_gpu_program_parameters) = glewGetExtension("GL_EXT_gpu_program_parameters"); + if (glewExperimental || GLEW_EXT_gpu_program_parameters) CONST_CAST(GLEW_EXT_gpu_program_parameters) = !_glewInit_GL_EXT_gpu_program_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_gpu_program_parameters */ +#ifdef GL_EXT_gpu_shader4 + CONST_CAST(GLEW_EXT_gpu_shader4) = glewGetExtension("GL_EXT_gpu_shader4"); + if (glewExperimental || GLEW_EXT_gpu_shader4) CONST_CAST(GLEW_EXT_gpu_shader4) = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_gpu_shader4 */ +#ifdef GL_EXT_histogram + CONST_CAST(GLEW_EXT_histogram) = glewGetExtension("GL_EXT_histogram"); + if (glewExperimental || GLEW_EXT_histogram) CONST_CAST(GLEW_EXT_histogram) = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_array_formats + CONST_CAST(GLEW_EXT_index_array_formats) = glewGetExtension("GL_EXT_index_array_formats"); +#endif /* GL_EXT_index_array_formats */ +#ifdef GL_EXT_index_func + CONST_CAST(GLEW_EXT_index_func) = glewGetExtension("GL_EXT_index_func"); + if (glewExperimental || GLEW_EXT_index_func) CONST_CAST(GLEW_EXT_index_func) = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + CONST_CAST(GLEW_EXT_index_material) = glewGetExtension("GL_EXT_index_material"); + if (glewExperimental || GLEW_EXT_index_material) CONST_CAST(GLEW_EXT_index_material) = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_index_texture + CONST_CAST(GLEW_EXT_index_texture) = glewGetExtension("GL_EXT_index_texture"); +#endif /* GL_EXT_index_texture */ +#ifdef GL_EXT_light_texture + CONST_CAST(GLEW_EXT_light_texture) = glewGetExtension("GL_EXT_light_texture"); + if (glewExperimental || GLEW_EXT_light_texture) CONST_CAST(GLEW_EXT_light_texture) = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_misc_attribute + CONST_CAST(GLEW_EXT_misc_attribute) = glewGetExtension("GL_EXT_misc_attribute"); +#endif /* GL_EXT_misc_attribute */ +#ifdef GL_EXT_multi_draw_arrays + CONST_CAST(GLEW_EXT_multi_draw_arrays) = glewGetExtension("GL_EXT_multi_draw_arrays"); + if (glewExperimental || GLEW_EXT_multi_draw_arrays) CONST_CAST(GLEW_EXT_multi_draw_arrays) = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multi_draw_arrays */ +#ifdef GL_EXT_multisample + CONST_CAST(GLEW_EXT_multisample) = glewGetExtension("GL_EXT_multisample"); + if (glewExperimental || GLEW_EXT_multisample) CONST_CAST(GLEW_EXT_multisample) = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_packed_depth_stencil + CONST_CAST(GLEW_EXT_packed_depth_stencil) = glewGetExtension("GL_EXT_packed_depth_stencil"); +#endif /* GL_EXT_packed_depth_stencil */ +#ifdef GL_EXT_packed_float + CONST_CAST(GLEW_EXT_packed_float) = glewGetExtension("GL_EXT_packed_float"); +#endif /* GL_EXT_packed_float */ +#ifdef GL_EXT_packed_pixels + CONST_CAST(GLEW_EXT_packed_pixels) = glewGetExtension("GL_EXT_packed_pixels"); +#endif /* GL_EXT_packed_pixels */ +#ifdef GL_EXT_paletted_texture + CONST_CAST(GLEW_EXT_paletted_texture) = glewGetExtension("GL_EXT_paletted_texture"); + if (glewExperimental || GLEW_EXT_paletted_texture) CONST_CAST(GLEW_EXT_paletted_texture) = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_paletted_texture */ +#ifdef GL_EXT_pixel_buffer_object + CONST_CAST(GLEW_EXT_pixel_buffer_object) = glewGetExtension("GL_EXT_pixel_buffer_object"); +#endif /* GL_EXT_pixel_buffer_object */ +#ifdef GL_EXT_pixel_transform + CONST_CAST(GLEW_EXT_pixel_transform) = glewGetExtension("GL_EXT_pixel_transform"); + if (glewExperimental || GLEW_EXT_pixel_transform) CONST_CAST(GLEW_EXT_pixel_transform) = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_pixel_transform */ +#ifdef GL_EXT_pixel_transform_color_table + CONST_CAST(GLEW_EXT_pixel_transform_color_table) = glewGetExtension("GL_EXT_pixel_transform_color_table"); +#endif /* GL_EXT_pixel_transform_color_table */ +#ifdef GL_EXT_point_parameters + CONST_CAST(GLEW_EXT_point_parameters) = glewGetExtension("GL_EXT_point_parameters"); + if (glewExperimental || GLEW_EXT_point_parameters) CONST_CAST(GLEW_EXT_point_parameters) = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + CONST_CAST(GLEW_EXT_polygon_offset) = glewGetExtension("GL_EXT_polygon_offset"); + if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_rescale_normal + CONST_CAST(GLEW_EXT_rescale_normal) = glewGetExtension("GL_EXT_rescale_normal"); +#endif /* GL_EXT_rescale_normal */ +#ifdef GL_EXT_scene_marker + CONST_CAST(GLEW_EXT_scene_marker) = glewGetExtension("GL_EXT_scene_marker"); + if (glewExperimental || GLEW_EXT_scene_marker) CONST_CAST(GLEW_EXT_scene_marker) = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + CONST_CAST(GLEW_EXT_secondary_color) = glewGetExtension("GL_EXT_secondary_color"); + if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_separate_specular_color + CONST_CAST(GLEW_EXT_separate_specular_color) = glewGetExtension("GL_EXT_separate_specular_color"); +#endif /* GL_EXT_separate_specular_color */ +#ifdef GL_EXT_shadow_funcs + CONST_CAST(GLEW_EXT_shadow_funcs) = glewGetExtension("GL_EXT_shadow_funcs"); +#endif /* GL_EXT_shadow_funcs */ +#ifdef GL_EXT_shared_texture_palette + CONST_CAST(GLEW_EXT_shared_texture_palette) = glewGetExtension("GL_EXT_shared_texture_palette"); +#endif /* GL_EXT_shared_texture_palette */ +#ifdef GL_EXT_stencil_clear_tag + CONST_CAST(GLEW_EXT_stencil_clear_tag) = glewGetExtension("GL_EXT_stencil_clear_tag"); +#endif /* GL_EXT_stencil_clear_tag */ +#ifdef GL_EXT_stencil_two_side + CONST_CAST(GLEW_EXT_stencil_two_side) = glewGetExtension("GL_EXT_stencil_two_side"); + if (glewExperimental || GLEW_EXT_stencil_two_side) CONST_CAST(GLEW_EXT_stencil_two_side) = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_stencil_two_side */ +#ifdef GL_EXT_stencil_wrap + CONST_CAST(GLEW_EXT_stencil_wrap) = glewGetExtension("GL_EXT_stencil_wrap"); +#endif /* GL_EXT_stencil_wrap */ +#ifdef GL_EXT_subtexture + CONST_CAST(GLEW_EXT_subtexture) = glewGetExtension("GL_EXT_subtexture"); + if (glewExperimental || GLEW_EXT_subtexture) CONST_CAST(GLEW_EXT_subtexture) = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture + CONST_CAST(GLEW_EXT_texture) = glewGetExtension("GL_EXT_texture"); +#endif /* GL_EXT_texture */ +#ifdef GL_EXT_texture3D + CONST_CAST(GLEW_EXT_texture3D) = glewGetExtension("GL_EXT_texture3D"); + if (glewExperimental || GLEW_EXT_texture3D) CONST_CAST(GLEW_EXT_texture3D) = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_array + CONST_CAST(GLEW_EXT_texture_array) = glewGetExtension("GL_EXT_texture_array"); +#endif /* GL_EXT_texture_array */ +#ifdef GL_EXT_texture_buffer_object + CONST_CAST(GLEW_EXT_texture_buffer_object) = glewGetExtension("GL_EXT_texture_buffer_object"); + if (glewExperimental || GLEW_EXT_texture_buffer_object) CONST_CAST(GLEW_EXT_texture_buffer_object) = !_glewInit_GL_EXT_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_buffer_object */ +#ifdef GL_EXT_texture_compression_dxt1 + CONST_CAST(GLEW_EXT_texture_compression_dxt1) = glewGetExtension("GL_EXT_texture_compression_dxt1"); +#endif /* GL_EXT_texture_compression_dxt1 */ +#ifdef GL_EXT_texture_compression_latc + CONST_CAST(GLEW_EXT_texture_compression_latc) = glewGetExtension("GL_EXT_texture_compression_latc"); +#endif /* GL_EXT_texture_compression_latc */ +#ifdef GL_EXT_texture_compression_rgtc + CONST_CAST(GLEW_EXT_texture_compression_rgtc) = glewGetExtension("GL_EXT_texture_compression_rgtc"); +#endif /* GL_EXT_texture_compression_rgtc */ +#ifdef GL_EXT_texture_compression_s3tc + CONST_CAST(GLEW_EXT_texture_compression_s3tc) = glewGetExtension("GL_EXT_texture_compression_s3tc"); +#endif /* GL_EXT_texture_compression_s3tc */ +#ifdef GL_EXT_texture_cube_map + CONST_CAST(GLEW_EXT_texture_cube_map) = glewGetExtension("GL_EXT_texture_cube_map"); +#endif /* GL_EXT_texture_cube_map */ +#ifdef GL_EXT_texture_edge_clamp + CONST_CAST(GLEW_EXT_texture_edge_clamp) = glewGetExtension("GL_EXT_texture_edge_clamp"); +#endif /* GL_EXT_texture_edge_clamp */ +#ifdef GL_EXT_texture_env + CONST_CAST(GLEW_EXT_texture_env) = glewGetExtension("GL_EXT_texture_env"); +#endif /* GL_EXT_texture_env */ +#ifdef GL_EXT_texture_env_add + CONST_CAST(GLEW_EXT_texture_env_add) = glewGetExtension("GL_EXT_texture_env_add"); +#endif /* GL_EXT_texture_env_add */ +#ifdef GL_EXT_texture_env_combine + CONST_CAST(GLEW_EXT_texture_env_combine) = glewGetExtension("GL_EXT_texture_env_combine"); +#endif /* GL_EXT_texture_env_combine */ +#ifdef GL_EXT_texture_env_dot3 + CONST_CAST(GLEW_EXT_texture_env_dot3) = glewGetExtension("GL_EXT_texture_env_dot3"); +#endif /* GL_EXT_texture_env_dot3 */ +#ifdef GL_EXT_texture_filter_anisotropic + CONST_CAST(GLEW_EXT_texture_filter_anisotropic) = glewGetExtension("GL_EXT_texture_filter_anisotropic"); +#endif /* GL_EXT_texture_filter_anisotropic */ +#ifdef GL_EXT_texture_integer + CONST_CAST(GLEW_EXT_texture_integer) = glewGetExtension("GL_EXT_texture_integer"); + if (glewExperimental || GLEW_EXT_texture_integer) CONST_CAST(GLEW_EXT_texture_integer) = !_glewInit_GL_EXT_texture_integer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_integer */ +#ifdef GL_EXT_texture_lod_bias + CONST_CAST(GLEW_EXT_texture_lod_bias) = glewGetExtension("GL_EXT_texture_lod_bias"); +#endif /* GL_EXT_texture_lod_bias */ +#ifdef GL_EXT_texture_mirror_clamp + CONST_CAST(GLEW_EXT_texture_mirror_clamp) = glewGetExtension("GL_EXT_texture_mirror_clamp"); +#endif /* GL_EXT_texture_mirror_clamp */ +#ifdef GL_EXT_texture_object + CONST_CAST(GLEW_EXT_texture_object) = glewGetExtension("GL_EXT_texture_object"); + if (glewExperimental || GLEW_EXT_texture_object) CONST_CAST(GLEW_EXT_texture_object) = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_object */ +#ifdef GL_EXT_texture_perturb_normal + CONST_CAST(GLEW_EXT_texture_perturb_normal) = glewGetExtension("GL_EXT_texture_perturb_normal"); + if (glewExperimental || GLEW_EXT_texture_perturb_normal) CONST_CAST(GLEW_EXT_texture_perturb_normal) = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_perturb_normal */ +#ifdef GL_EXT_texture_rectangle + CONST_CAST(GLEW_EXT_texture_rectangle) = glewGetExtension("GL_EXT_texture_rectangle"); +#endif /* GL_EXT_texture_rectangle */ +#ifdef GL_EXT_texture_sRGB + CONST_CAST(GLEW_EXT_texture_sRGB) = glewGetExtension("GL_EXT_texture_sRGB"); +#endif /* GL_EXT_texture_sRGB */ +#ifdef GL_EXT_texture_shared_exponent + CONST_CAST(GLEW_EXT_texture_shared_exponent) = glewGetExtension("GL_EXT_texture_shared_exponent"); +#endif /* GL_EXT_texture_shared_exponent */ +#ifdef GL_EXT_texture_swizzle + CONST_CAST(GLEW_EXT_texture_swizzle) = glewGetExtension("GL_EXT_texture_swizzle"); +#endif /* GL_EXT_texture_swizzle */ +#ifdef GL_EXT_timer_query + CONST_CAST(GLEW_EXT_timer_query) = glewGetExtension("GL_EXT_timer_query"); + if (glewExperimental || GLEW_EXT_timer_query) CONST_CAST(GLEW_EXT_timer_query) = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_timer_query */ +#ifdef GL_EXT_transform_feedback + CONST_CAST(GLEW_EXT_transform_feedback) = glewGetExtension("GL_EXT_transform_feedback"); + if (glewExperimental || GLEW_EXT_transform_feedback) CONST_CAST(GLEW_EXT_transform_feedback) = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_transform_feedback */ +#ifdef GL_EXT_vertex_array + CONST_CAST(GLEW_EXT_vertex_array) = glewGetExtension("GL_EXT_vertex_array"); + if (glewExperimental || GLEW_EXT_vertex_array) CONST_CAST(GLEW_EXT_vertex_array) = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_array_bgra + CONST_CAST(GLEW_EXT_vertex_array_bgra) = glewGetExtension("GL_EXT_vertex_array_bgra"); +#endif /* GL_EXT_vertex_array_bgra */ +#ifdef GL_EXT_vertex_shader + CONST_CAST(GLEW_EXT_vertex_shader) = glewGetExtension("GL_EXT_vertex_shader"); + if (glewExperimental || GLEW_EXT_vertex_shader) CONST_CAST(GLEW_EXT_vertex_shader) = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + CONST_CAST(GLEW_EXT_vertex_weighting) = glewGetExtension("GL_EXT_vertex_weighting"); + if (glewExperimental || GLEW_EXT_vertex_weighting) CONST_CAST(GLEW_EXT_vertex_weighting) = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_GREMEDY_frame_terminator + CONST_CAST(GLEW_GREMEDY_frame_terminator) = glewGetExtension("GL_GREMEDY_frame_terminator"); + if (glewExperimental || GLEW_GREMEDY_frame_terminator) CONST_CAST(GLEW_GREMEDY_frame_terminator) = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_frame_terminator */ +#ifdef GL_GREMEDY_string_marker + CONST_CAST(GLEW_GREMEDY_string_marker) = glewGetExtension("GL_GREMEDY_string_marker"); + if (glewExperimental || GLEW_GREMEDY_string_marker) CONST_CAST(GLEW_GREMEDY_string_marker) = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_string_marker */ +#ifdef GL_HP_convolution_border_modes + CONST_CAST(GLEW_HP_convolution_border_modes) = glewGetExtension("GL_HP_convolution_border_modes"); +#endif /* GL_HP_convolution_border_modes */ +#ifdef GL_HP_image_transform + CONST_CAST(GLEW_HP_image_transform) = glewGetExtension("GL_HP_image_transform"); + if (glewExperimental || GLEW_HP_image_transform) CONST_CAST(GLEW_HP_image_transform) = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_HP_image_transform */ +#ifdef GL_HP_occlusion_test + CONST_CAST(GLEW_HP_occlusion_test) = glewGetExtension("GL_HP_occlusion_test"); +#endif /* GL_HP_occlusion_test */ +#ifdef GL_HP_texture_lighting + CONST_CAST(GLEW_HP_texture_lighting) = glewGetExtension("GL_HP_texture_lighting"); +#endif /* GL_HP_texture_lighting */ +#ifdef GL_IBM_cull_vertex + CONST_CAST(GLEW_IBM_cull_vertex) = glewGetExtension("GL_IBM_cull_vertex"); +#endif /* GL_IBM_cull_vertex */ +#ifdef GL_IBM_multimode_draw_arrays + CONST_CAST(GLEW_IBM_multimode_draw_arrays) = glewGetExtension("GL_IBM_multimode_draw_arrays"); + if (glewExperimental || GLEW_IBM_multimode_draw_arrays) CONST_CAST(GLEW_IBM_multimode_draw_arrays) = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_multimode_draw_arrays */ +#ifdef GL_IBM_rasterpos_clip + CONST_CAST(GLEW_IBM_rasterpos_clip) = glewGetExtension("GL_IBM_rasterpos_clip"); +#endif /* GL_IBM_rasterpos_clip */ +#ifdef GL_IBM_static_data + CONST_CAST(GLEW_IBM_static_data) = glewGetExtension("GL_IBM_static_data"); +#endif /* GL_IBM_static_data */ +#ifdef GL_IBM_texture_mirrored_repeat + CONST_CAST(GLEW_IBM_texture_mirrored_repeat) = glewGetExtension("GL_IBM_texture_mirrored_repeat"); +#endif /* GL_IBM_texture_mirrored_repeat */ +#ifdef GL_IBM_vertex_array_lists + CONST_CAST(GLEW_IBM_vertex_array_lists) = glewGetExtension("GL_IBM_vertex_array_lists"); + if (glewExperimental || GLEW_IBM_vertex_array_lists) CONST_CAST(GLEW_IBM_vertex_array_lists) = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_vertex_array_lists */ +#ifdef GL_INGR_color_clamp + CONST_CAST(GLEW_INGR_color_clamp) = glewGetExtension("GL_INGR_color_clamp"); +#endif /* GL_INGR_color_clamp */ +#ifdef GL_INGR_interlace_read + CONST_CAST(GLEW_INGR_interlace_read) = glewGetExtension("GL_INGR_interlace_read"); +#endif /* GL_INGR_interlace_read */ +#ifdef GL_INTEL_parallel_arrays + CONST_CAST(GLEW_INTEL_parallel_arrays) = glewGetExtension("GL_INTEL_parallel_arrays"); + if (glewExperimental || GLEW_INTEL_parallel_arrays) CONST_CAST(GLEW_INTEL_parallel_arrays) = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_texture_scissor + CONST_CAST(GLEW_INTEL_texture_scissor) = glewGetExtension("GL_INTEL_texture_scissor"); + if (glewExperimental || GLEW_INTEL_texture_scissor) CONST_CAST(GLEW_INTEL_texture_scissor) = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KTX_buffer_region + CONST_CAST(GLEW_KTX_buffer_region) = glewGetExtension("GL_KTX_buffer_region"); + if (glewExperimental || GLEW_KTX_buffer_region) CONST_CAST(GLEW_KTX_buffer_region) = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESAX_texture_stack + CONST_CAST(GLEW_MESAX_texture_stack) = glewGetExtension("GL_MESAX_texture_stack"); +#endif /* GL_MESAX_texture_stack */ +#ifdef GL_MESA_pack_invert + CONST_CAST(GLEW_MESA_pack_invert) = glewGetExtension("GL_MESA_pack_invert"); +#endif /* GL_MESA_pack_invert */ +#ifdef GL_MESA_resize_buffers + CONST_CAST(GLEW_MESA_resize_buffers) = glewGetExtension("GL_MESA_resize_buffers"); + if (glewExperimental || GLEW_MESA_resize_buffers) CONST_CAST(GLEW_MESA_resize_buffers) = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + CONST_CAST(GLEW_MESA_window_pos) = glewGetExtension("GL_MESA_window_pos"); + if (glewExperimental || GLEW_MESA_window_pos) CONST_CAST(GLEW_MESA_window_pos) = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_window_pos */ +#ifdef GL_MESA_ycbcr_texture + CONST_CAST(GLEW_MESA_ycbcr_texture) = glewGetExtension("GL_MESA_ycbcr_texture"); +#endif /* GL_MESA_ycbcr_texture */ +#ifdef GL_NV_blend_square + CONST_CAST(GLEW_NV_blend_square) = glewGetExtension("GL_NV_blend_square"); +#endif /* GL_NV_blend_square */ +#ifdef GL_NV_conditional_render + CONST_CAST(GLEW_NV_conditional_render) = glewGetExtension("GL_NV_conditional_render"); + if (glewExperimental || GLEW_NV_conditional_render) CONST_CAST(GLEW_NV_conditional_render) = !_glewInit_GL_NV_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_conditional_render */ +#ifdef GL_NV_copy_depth_to_color + CONST_CAST(GLEW_NV_copy_depth_to_color) = glewGetExtension("GL_NV_copy_depth_to_color"); +#endif /* GL_NV_copy_depth_to_color */ +#ifdef GL_NV_depth_buffer_float + CONST_CAST(GLEW_NV_depth_buffer_float) = glewGetExtension("GL_NV_depth_buffer_float"); + if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_depth_buffer_float */ +#ifdef GL_NV_depth_clamp + CONST_CAST(GLEW_NV_depth_clamp) = glewGetExtension("GL_NV_depth_clamp"); +#endif /* GL_NV_depth_clamp */ +#ifdef GL_NV_depth_range_unclamped + CONST_CAST(GLEW_NV_depth_range_unclamped) = glewGetExtension("GL_NV_depth_range_unclamped"); +#endif /* GL_NV_depth_range_unclamped */ +#ifdef GL_NV_evaluators + CONST_CAST(GLEW_NV_evaluators) = glewGetExtension("GL_NV_evaluators"); + if (glewExperimental || GLEW_NV_evaluators) CONST_CAST(GLEW_NV_evaluators) = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_explicit_multisample + CONST_CAST(GLEW_NV_explicit_multisample) = glewGetExtension("GL_NV_explicit_multisample"); + if (glewExperimental || GLEW_NV_explicit_multisample) CONST_CAST(GLEW_NV_explicit_multisample) = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_explicit_multisample */ +#ifdef GL_NV_fence + CONST_CAST(GLEW_NV_fence) = glewGetExtension("GL_NV_fence"); + if (glewExperimental || GLEW_NV_fence) CONST_CAST(GLEW_NV_fence) = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fence */ +#ifdef GL_NV_float_buffer + CONST_CAST(GLEW_NV_float_buffer) = glewGetExtension("GL_NV_float_buffer"); +#endif /* GL_NV_float_buffer */ +#ifdef GL_NV_fog_distance + CONST_CAST(GLEW_NV_fog_distance) = glewGetExtension("GL_NV_fog_distance"); +#endif /* GL_NV_fog_distance */ +#ifdef GL_NV_fragment_program + CONST_CAST(GLEW_NV_fragment_program) = glewGetExtension("GL_NV_fragment_program"); + if (glewExperimental || GLEW_NV_fragment_program) CONST_CAST(GLEW_NV_fragment_program) = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_fragment_program2 + CONST_CAST(GLEW_NV_fragment_program2) = glewGetExtension("GL_NV_fragment_program2"); +#endif /* GL_NV_fragment_program2 */ +#ifdef GL_NV_fragment_program4 + CONST_CAST(GLEW_NV_fragment_program4) = glewGetExtension("GL_NV_fragment_program4"); +#endif /* GL_NV_fragment_program4 */ +#ifdef GL_NV_fragment_program_option + CONST_CAST(GLEW_NV_fragment_program_option) = glewGetExtension("GL_NV_fragment_program_option"); +#endif /* GL_NV_fragment_program_option */ +#ifdef GL_NV_framebuffer_multisample_coverage + CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = glewGetExtension("GL_NV_framebuffer_multisample_coverage"); + if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = !_glewInit_GL_NV_framebuffer_multisample_coverage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_framebuffer_multisample_coverage */ +#ifdef GL_NV_geometry_program4 + CONST_CAST(GLEW_NV_geometry_program4) = glewGetExtension("GL_NV_geometry_program4"); + if (glewExperimental || GLEW_NV_geometry_program4) CONST_CAST(GLEW_NV_geometry_program4) = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_geometry_shader4 + CONST_CAST(GLEW_NV_geometry_shader4) = glewGetExtension("GL_NV_geometry_shader4"); +#endif /* GL_NV_geometry_shader4 */ +#ifdef GL_NV_gpu_program4 + CONST_CAST(GLEW_NV_gpu_program4) = glewGetExtension("GL_NV_gpu_program4"); + if (glewExperimental || GLEW_NV_gpu_program4) CONST_CAST(GLEW_NV_gpu_program4) = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_gpu_program4 */ +#ifdef GL_NV_half_float + CONST_CAST(GLEW_NV_half_float) = glewGetExtension("GL_NV_half_float"); + if (glewExperimental || GLEW_NV_half_float) CONST_CAST(GLEW_NV_half_float) = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_half_float */ +#ifdef GL_NV_light_max_exponent + CONST_CAST(GLEW_NV_light_max_exponent) = glewGetExtension("GL_NV_light_max_exponent"); +#endif /* GL_NV_light_max_exponent */ +#ifdef GL_NV_multisample_filter_hint + CONST_CAST(GLEW_NV_multisample_filter_hint) = glewGetExtension("GL_NV_multisample_filter_hint"); +#endif /* GL_NV_multisample_filter_hint */ +#ifdef GL_NV_occlusion_query + CONST_CAST(GLEW_NV_occlusion_query) = glewGetExtension("GL_NV_occlusion_query"); + if (glewExperimental || GLEW_NV_occlusion_query) CONST_CAST(GLEW_NV_occlusion_query) = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_occlusion_query */ +#ifdef GL_NV_packed_depth_stencil + CONST_CAST(GLEW_NV_packed_depth_stencil) = glewGetExtension("GL_NV_packed_depth_stencil"); +#endif /* GL_NV_packed_depth_stencil */ +#ifdef GL_NV_parameter_buffer_object + CONST_CAST(GLEW_NV_parameter_buffer_object) = glewGetExtension("GL_NV_parameter_buffer_object"); + if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_parameter_buffer_object */ +#ifdef GL_NV_pixel_data_range + CONST_CAST(GLEW_NV_pixel_data_range) = glewGetExtension("GL_NV_pixel_data_range"); + if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_pixel_data_range */ +#ifdef GL_NV_point_sprite + CONST_CAST(GLEW_NV_point_sprite) = glewGetExtension("GL_NV_point_sprite"); + if (glewExperimental || GLEW_NV_point_sprite) CONST_CAST(GLEW_NV_point_sprite) = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_present_video + CONST_CAST(GLEW_NV_present_video) = glewGetExtension("GL_NV_present_video"); + if (glewExperimental || GLEW_NV_present_video) CONST_CAST(GLEW_NV_present_video) = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_present_video */ +#ifdef GL_NV_primitive_restart + CONST_CAST(GLEW_NV_primitive_restart) = glewGetExtension("GL_NV_primitive_restart"); + if (glewExperimental || GLEW_NV_primitive_restart) CONST_CAST(GLEW_NV_primitive_restart) = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + CONST_CAST(GLEW_NV_register_combiners) = glewGetExtension("GL_NV_register_combiners"); + if (glewExperimental || GLEW_NV_register_combiners) CONST_CAST(GLEW_NV_register_combiners) = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + CONST_CAST(GLEW_NV_register_combiners2) = glewGetExtension("GL_NV_register_combiners2"); + if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_texgen_emboss + CONST_CAST(GLEW_NV_texgen_emboss) = glewGetExtension("GL_NV_texgen_emboss"); +#endif /* GL_NV_texgen_emboss */ +#ifdef GL_NV_texgen_reflection + CONST_CAST(GLEW_NV_texgen_reflection) = glewGetExtension("GL_NV_texgen_reflection"); +#endif /* GL_NV_texgen_reflection */ +#ifdef GL_NV_texture_compression_vtc + CONST_CAST(GLEW_NV_texture_compression_vtc) = glewGetExtension("GL_NV_texture_compression_vtc"); +#endif /* GL_NV_texture_compression_vtc */ +#ifdef GL_NV_texture_env_combine4 + CONST_CAST(GLEW_NV_texture_env_combine4) = glewGetExtension("GL_NV_texture_env_combine4"); +#endif /* GL_NV_texture_env_combine4 */ +#ifdef GL_NV_texture_expand_normal + CONST_CAST(GLEW_NV_texture_expand_normal) = glewGetExtension("GL_NV_texture_expand_normal"); +#endif /* GL_NV_texture_expand_normal */ +#ifdef GL_NV_texture_rectangle + CONST_CAST(GLEW_NV_texture_rectangle) = glewGetExtension("GL_NV_texture_rectangle"); +#endif /* GL_NV_texture_rectangle */ +#ifdef GL_NV_texture_shader + CONST_CAST(GLEW_NV_texture_shader) = glewGetExtension("GL_NV_texture_shader"); +#endif /* GL_NV_texture_shader */ +#ifdef GL_NV_texture_shader2 + CONST_CAST(GLEW_NV_texture_shader2) = glewGetExtension("GL_NV_texture_shader2"); +#endif /* GL_NV_texture_shader2 */ +#ifdef GL_NV_texture_shader3 + CONST_CAST(GLEW_NV_texture_shader3) = glewGetExtension("GL_NV_texture_shader3"); +#endif /* GL_NV_texture_shader3 */ +#ifdef GL_NV_transform_feedback + CONST_CAST(GLEW_NV_transform_feedback) = glewGetExtension("GL_NV_transform_feedback"); + if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_transform_feedback */ +#ifdef GL_NV_vertex_array_range + CONST_CAST(GLEW_NV_vertex_array_range) = glewGetExtension("GL_NV_vertex_array_range"); + if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_array_range2 + CONST_CAST(GLEW_NV_vertex_array_range2) = glewGetExtension("GL_NV_vertex_array_range2"); +#endif /* GL_NV_vertex_array_range2 */ +#ifdef GL_NV_vertex_program + CONST_CAST(GLEW_NV_vertex_program) = glewGetExtension("GL_NV_vertex_program"); + if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_program */ +#ifdef GL_NV_vertex_program1_1 + CONST_CAST(GLEW_NV_vertex_program1_1) = glewGetExtension("GL_NV_vertex_program1_1"); +#endif /* GL_NV_vertex_program1_1 */ +#ifdef GL_NV_vertex_program2 + CONST_CAST(GLEW_NV_vertex_program2) = glewGetExtension("GL_NV_vertex_program2"); +#endif /* GL_NV_vertex_program2 */ +#ifdef GL_NV_vertex_program2_option + CONST_CAST(GLEW_NV_vertex_program2_option) = glewGetExtension("GL_NV_vertex_program2_option"); +#endif /* GL_NV_vertex_program2_option */ +#ifdef GL_NV_vertex_program3 + CONST_CAST(GLEW_NV_vertex_program3) = glewGetExtension("GL_NV_vertex_program3"); +#endif /* GL_NV_vertex_program3 */ +#ifdef GL_NV_vertex_program4 + CONST_CAST(GLEW_NV_vertex_program4) = glewGetExtension("GL_NV_vertex_program4"); +#endif /* GL_NV_vertex_program4 */ +#ifdef GL_OES_byte_coordinates + CONST_CAST(GLEW_OES_byte_coordinates) = glewGetExtension("GL_OES_byte_coordinates"); +#endif /* GL_OES_byte_coordinates */ +#ifdef GL_OES_compressed_paletted_texture + CONST_CAST(GLEW_OES_compressed_paletted_texture) = glewGetExtension("GL_OES_compressed_paletted_texture"); +#endif /* GL_OES_compressed_paletted_texture */ +#ifdef GL_OES_read_format + CONST_CAST(GLEW_OES_read_format) = glewGetExtension("GL_OES_read_format"); +#endif /* GL_OES_read_format */ +#ifdef GL_OES_single_precision + CONST_CAST(GLEW_OES_single_precision) = glewGetExtension("GL_OES_single_precision"); + if (glewExperimental || GLEW_OES_single_precision) CONST_CAST(GLEW_OES_single_precision) = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_OES_single_precision */ +#ifdef GL_OML_interlace + CONST_CAST(GLEW_OML_interlace) = glewGetExtension("GL_OML_interlace"); +#endif /* GL_OML_interlace */ +#ifdef GL_OML_resample + CONST_CAST(GLEW_OML_resample) = glewGetExtension("GL_OML_resample"); +#endif /* GL_OML_resample */ +#ifdef GL_OML_subsample + CONST_CAST(GLEW_OML_subsample) = glewGetExtension("GL_OML_subsample"); +#endif /* GL_OML_subsample */ +#ifdef GL_PGI_misc_hints + CONST_CAST(GLEW_PGI_misc_hints) = glewGetExtension("GL_PGI_misc_hints"); +#endif /* GL_PGI_misc_hints */ +#ifdef GL_PGI_vertex_hints + CONST_CAST(GLEW_PGI_vertex_hints) = glewGetExtension("GL_PGI_vertex_hints"); +#endif /* GL_PGI_vertex_hints */ +#ifdef GL_REND_screen_coordinates + CONST_CAST(GLEW_REND_screen_coordinates) = glewGetExtension("GL_REND_screen_coordinates"); +#endif /* GL_REND_screen_coordinates */ +#ifdef GL_S3_s3tc + CONST_CAST(GLEW_S3_s3tc) = glewGetExtension("GL_S3_s3tc"); +#endif /* GL_S3_s3tc */ +#ifdef GL_SGIS_color_range + CONST_CAST(GLEW_SGIS_color_range) = glewGetExtension("GL_SGIS_color_range"); +#endif /* GL_SGIS_color_range */ +#ifdef GL_SGIS_detail_texture + CONST_CAST(GLEW_SGIS_detail_texture) = glewGetExtension("GL_SGIS_detail_texture"); + if (glewExperimental || GLEW_SGIS_detail_texture) CONST_CAST(GLEW_SGIS_detail_texture) = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + CONST_CAST(GLEW_SGIS_fog_function) = glewGetExtension("GL_SGIS_fog_function"); + if (glewExperimental || GLEW_SGIS_fog_function) CONST_CAST(GLEW_SGIS_fog_function) = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_generate_mipmap + CONST_CAST(GLEW_SGIS_generate_mipmap) = glewGetExtension("GL_SGIS_generate_mipmap"); +#endif /* GL_SGIS_generate_mipmap */ +#ifdef GL_SGIS_multisample + CONST_CAST(GLEW_SGIS_multisample) = glewGetExtension("GL_SGIS_multisample"); + if (glewExperimental || GLEW_SGIS_multisample) CONST_CAST(GLEW_SGIS_multisample) = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_pixel_texture + CONST_CAST(GLEW_SGIS_pixel_texture) = glewGetExtension("GL_SGIS_pixel_texture"); +#endif /* GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_point_line_texgen + CONST_CAST(GLEW_SGIS_point_line_texgen) = glewGetExtension("GL_SGIS_point_line_texgen"); +#endif /* GL_SGIS_point_line_texgen */ +#ifdef GL_SGIS_sharpen_texture + CONST_CAST(GLEW_SGIS_sharpen_texture) = glewGetExtension("GL_SGIS_sharpen_texture"); + if (glewExperimental || GLEW_SGIS_sharpen_texture) CONST_CAST(GLEW_SGIS_sharpen_texture) = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + CONST_CAST(GLEW_SGIS_texture4D) = glewGetExtension("GL_SGIS_texture4D"); + if (glewExperimental || GLEW_SGIS_texture4D) CONST_CAST(GLEW_SGIS_texture4D) = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_border_clamp + CONST_CAST(GLEW_SGIS_texture_border_clamp) = glewGetExtension("GL_SGIS_texture_border_clamp"); +#endif /* GL_SGIS_texture_border_clamp */ +#ifdef GL_SGIS_texture_edge_clamp + CONST_CAST(GLEW_SGIS_texture_edge_clamp) = glewGetExtension("GL_SGIS_texture_edge_clamp"); +#endif /* GL_SGIS_texture_edge_clamp */ +#ifdef GL_SGIS_texture_filter4 + CONST_CAST(GLEW_SGIS_texture_filter4) = glewGetExtension("GL_SGIS_texture_filter4"); + if (glewExperimental || GLEW_SGIS_texture_filter4) CONST_CAST(GLEW_SGIS_texture_filter4) = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIS_texture_lod + CONST_CAST(GLEW_SGIS_texture_lod) = glewGetExtension("GL_SGIS_texture_lod"); +#endif /* GL_SGIS_texture_lod */ +#ifdef GL_SGIS_texture_select + CONST_CAST(GLEW_SGIS_texture_select) = glewGetExtension("GL_SGIS_texture_select"); +#endif /* GL_SGIS_texture_select */ +#ifdef GL_SGIX_async + CONST_CAST(GLEW_SGIX_async) = glewGetExtension("GL_SGIX_async"); + if (glewExperimental || GLEW_SGIX_async) CONST_CAST(GLEW_SGIX_async) = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_async_histogram + CONST_CAST(GLEW_SGIX_async_histogram) = glewGetExtension("GL_SGIX_async_histogram"); +#endif /* GL_SGIX_async_histogram */ +#ifdef GL_SGIX_async_pixel + CONST_CAST(GLEW_SGIX_async_pixel) = glewGetExtension("GL_SGIX_async_pixel"); +#endif /* GL_SGIX_async_pixel */ +#ifdef GL_SGIX_blend_alpha_minmax + CONST_CAST(GLEW_SGIX_blend_alpha_minmax) = glewGetExtension("GL_SGIX_blend_alpha_minmax"); +#endif /* GL_SGIX_blend_alpha_minmax */ +#ifdef GL_SGIX_clipmap + CONST_CAST(GLEW_SGIX_clipmap) = glewGetExtension("GL_SGIX_clipmap"); +#endif /* GL_SGIX_clipmap */ +#ifdef GL_SGIX_convolution_accuracy + CONST_CAST(GLEW_SGIX_convolution_accuracy) = glewGetExtension("GL_SGIX_convolution_accuracy"); +#endif /* GL_SGIX_convolution_accuracy */ +#ifdef GL_SGIX_depth_texture + CONST_CAST(GLEW_SGIX_depth_texture) = glewGetExtension("GL_SGIX_depth_texture"); +#endif /* GL_SGIX_depth_texture */ +#ifdef GL_SGIX_flush_raster + CONST_CAST(GLEW_SGIX_flush_raster) = glewGetExtension("GL_SGIX_flush_raster"); + if (glewExperimental || GLEW_SGIX_flush_raster) CONST_CAST(GLEW_SGIX_flush_raster) = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_offset + CONST_CAST(GLEW_SGIX_fog_offset) = glewGetExtension("GL_SGIX_fog_offset"); +#endif /* GL_SGIX_fog_offset */ +#ifdef GL_SGIX_fog_texture + CONST_CAST(GLEW_SGIX_fog_texture) = glewGetExtension("GL_SGIX_fog_texture"); + if (glewExperimental || GLEW_SGIX_fog_texture) CONST_CAST(GLEW_SGIX_fog_texture) = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fog_texture */ +#ifdef GL_SGIX_fragment_specular_lighting + CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = glewGetExtension("GL_SGIX_fragment_specular_lighting"); + if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fragment_specular_lighting */ +#ifdef GL_SGIX_framezoom + CONST_CAST(GLEW_SGIX_framezoom) = glewGetExtension("GL_SGIX_framezoom"); + if (glewExperimental || GLEW_SGIX_framezoom) CONST_CAST(GLEW_SGIX_framezoom) = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_interlace + CONST_CAST(GLEW_SGIX_interlace) = glewGetExtension("GL_SGIX_interlace"); +#endif /* GL_SGIX_interlace */ +#ifdef GL_SGIX_ir_instrument1 + CONST_CAST(GLEW_SGIX_ir_instrument1) = glewGetExtension("GL_SGIX_ir_instrument1"); +#endif /* GL_SGIX_ir_instrument1 */ +#ifdef GL_SGIX_list_priority + CONST_CAST(GLEW_SGIX_list_priority) = glewGetExtension("GL_SGIX_list_priority"); +#endif /* GL_SGIX_list_priority */ +#ifdef GL_SGIX_pixel_texture + CONST_CAST(GLEW_SGIX_pixel_texture) = glewGetExtension("GL_SGIX_pixel_texture"); + if (glewExperimental || GLEW_SGIX_pixel_texture) CONST_CAST(GLEW_SGIX_pixel_texture) = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_pixel_texture */ +#ifdef GL_SGIX_pixel_texture_bits + CONST_CAST(GLEW_SGIX_pixel_texture_bits) = glewGetExtension("GL_SGIX_pixel_texture_bits"); +#endif /* GL_SGIX_pixel_texture_bits */ +#ifdef GL_SGIX_reference_plane + CONST_CAST(GLEW_SGIX_reference_plane) = glewGetExtension("GL_SGIX_reference_plane"); + if (glewExperimental || GLEW_SGIX_reference_plane) CONST_CAST(GLEW_SGIX_reference_plane) = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_resample + CONST_CAST(GLEW_SGIX_resample) = glewGetExtension("GL_SGIX_resample"); +#endif /* GL_SGIX_resample */ +#ifdef GL_SGIX_shadow + CONST_CAST(GLEW_SGIX_shadow) = glewGetExtension("GL_SGIX_shadow"); +#endif /* GL_SGIX_shadow */ +#ifdef GL_SGIX_shadow_ambient + CONST_CAST(GLEW_SGIX_shadow_ambient) = glewGetExtension("GL_SGIX_shadow_ambient"); +#endif /* GL_SGIX_shadow_ambient */ +#ifdef GL_SGIX_sprite + CONST_CAST(GLEW_SGIX_sprite) = glewGetExtension("GL_SGIX_sprite"); + if (glewExperimental || GLEW_SGIX_sprite) CONST_CAST(GLEW_SGIX_sprite) = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + CONST_CAST(GLEW_SGIX_tag_sample_buffer) = glewGetExtension("GL_SGIX_tag_sample_buffer"); + if (glewExperimental || GLEW_SGIX_tag_sample_buffer) CONST_CAST(GLEW_SGIX_tag_sample_buffer) = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_texture_add_env + CONST_CAST(GLEW_SGIX_texture_add_env) = glewGetExtension("GL_SGIX_texture_add_env"); +#endif /* GL_SGIX_texture_add_env */ +#ifdef GL_SGIX_texture_coordinate_clamp + CONST_CAST(GLEW_SGIX_texture_coordinate_clamp) = glewGetExtension("GL_SGIX_texture_coordinate_clamp"); +#endif /* GL_SGIX_texture_coordinate_clamp */ +#ifdef GL_SGIX_texture_lod_bias + CONST_CAST(GLEW_SGIX_texture_lod_bias) = glewGetExtension("GL_SGIX_texture_lod_bias"); +#endif /* GL_SGIX_texture_lod_bias */ +#ifdef GL_SGIX_texture_multi_buffer + CONST_CAST(GLEW_SGIX_texture_multi_buffer) = glewGetExtension("GL_SGIX_texture_multi_buffer"); +#endif /* GL_SGIX_texture_multi_buffer */ +#ifdef GL_SGIX_texture_range + CONST_CAST(GLEW_SGIX_texture_range) = glewGetExtension("GL_SGIX_texture_range"); +#endif /* GL_SGIX_texture_range */ +#ifdef GL_SGIX_texture_scale_bias + CONST_CAST(GLEW_SGIX_texture_scale_bias) = glewGetExtension("GL_SGIX_texture_scale_bias"); +#endif /* GL_SGIX_texture_scale_bias */ +#ifdef GL_SGIX_vertex_preclip + CONST_CAST(GLEW_SGIX_vertex_preclip) = glewGetExtension("GL_SGIX_vertex_preclip"); +#endif /* GL_SGIX_vertex_preclip */ +#ifdef GL_SGIX_vertex_preclip_hint + CONST_CAST(GLEW_SGIX_vertex_preclip_hint) = glewGetExtension("GL_SGIX_vertex_preclip_hint"); +#endif /* GL_SGIX_vertex_preclip_hint */ +#ifdef GL_SGIX_ycrcb + CONST_CAST(GLEW_SGIX_ycrcb) = glewGetExtension("GL_SGIX_ycrcb"); +#endif /* GL_SGIX_ycrcb */ +#ifdef GL_SGI_color_matrix + CONST_CAST(GLEW_SGI_color_matrix) = glewGetExtension("GL_SGI_color_matrix"); +#endif /* GL_SGI_color_matrix */ +#ifdef GL_SGI_color_table + CONST_CAST(GLEW_SGI_color_table) = glewGetExtension("GL_SGI_color_table"); + if (glewExperimental || GLEW_SGI_color_table) CONST_CAST(GLEW_SGI_color_table) = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGI_color_table */ +#ifdef GL_SGI_texture_color_table + CONST_CAST(GLEW_SGI_texture_color_table) = glewGetExtension("GL_SGI_texture_color_table"); +#endif /* GL_SGI_texture_color_table */ +#ifdef GL_SUNX_constant_data + CONST_CAST(GLEW_SUNX_constant_data) = glewGetExtension("GL_SUNX_constant_data"); + if (glewExperimental || GLEW_SUNX_constant_data) CONST_CAST(GLEW_SUNX_constant_data) = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUNX_constant_data */ +#ifdef GL_SUN_convolution_border_modes + CONST_CAST(GLEW_SUN_convolution_border_modes) = glewGetExtension("GL_SUN_convolution_border_modes"); +#endif /* GL_SUN_convolution_border_modes */ +#ifdef GL_SUN_global_alpha + CONST_CAST(GLEW_SUN_global_alpha) = glewGetExtension("GL_SUN_global_alpha"); + if (glewExperimental || GLEW_SUN_global_alpha) CONST_CAST(GLEW_SUN_global_alpha) = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_mesh_array + CONST_CAST(GLEW_SUN_mesh_array) = glewGetExtension("GL_SUN_mesh_array"); +#endif /* GL_SUN_mesh_array */ +#ifdef GL_SUN_read_video_pixels + CONST_CAST(GLEW_SUN_read_video_pixels) = glewGetExtension("GL_SUN_read_video_pixels"); + if (glewExperimental || GLEW_SUN_read_video_pixels) CONST_CAST(GLEW_SUN_read_video_pixels) = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_read_video_pixels */ +#ifdef GL_SUN_slice_accum + CONST_CAST(GLEW_SUN_slice_accum) = glewGetExtension("GL_SUN_slice_accum"); +#endif /* GL_SUN_slice_accum */ +#ifdef GL_SUN_triangle_list + CONST_CAST(GLEW_SUN_triangle_list) = glewGetExtension("GL_SUN_triangle_list"); + if (glewExperimental || GLEW_SUN_triangle_list) CONST_CAST(GLEW_SUN_triangle_list) = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + CONST_CAST(GLEW_SUN_vertex) = glewGetExtension("GL_SUN_vertex"); + if (glewExperimental || GLEW_SUN_vertex) CONST_CAST(GLEW_SUN_vertex) = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_phong_shading + CONST_CAST(GLEW_WIN_phong_shading) = glewGetExtension("GL_WIN_phong_shading"); +#endif /* GL_WIN_phong_shading */ +#ifdef GL_WIN_specular_fog + CONST_CAST(GLEW_WIN_specular_fog) = glewGetExtension("GL_WIN_specular_fog"); +#endif /* GL_WIN_specular_fog */ +#ifdef GL_WIN_swap_hint + CONST_CAST(GLEW_WIN_swap_hint) = glewGetExtension("GL_WIN_swap_hint"); + if (glewExperimental || GLEW_WIN_swap_hint) CONST_CAST(GLEW_WIN_swap_hint) = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_WIN_swap_hint */ + + return GLEW_OK; +} + + +#if defined(_WIN32) + +#if !defined(GLEW_MX) + +PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL; + +PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL; +PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL; +PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL; +PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL; + +PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB = NULL; + +PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL; + +PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL; +PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL; + +PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL; +PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL; +PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL; +PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL; +PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL; + +PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL; +PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL; +PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL; + +PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL; +PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL; +PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL; + +PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL; +PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL; +PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL; +PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL; + +PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL; + +PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL; +PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL; + +PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL; +PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL; +PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL; +PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL; +PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL; + +PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL; + +PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL; +PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL; + +PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL; +PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL; + +PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL; +PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL; +PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL; +PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL; + +PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL; +PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL; +PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL; +PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL; +PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL; +PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL; +PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL; +PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL; +PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL; +PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL; +PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL; +PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL; + +PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL; +PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL; +PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL; +PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL; + +PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL; +PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL; +PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL; +PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL; + +PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL; +PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL; +PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL; +PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL; + +PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL; +PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL; +PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL; +PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV = NULL; +PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV = NULL; + +PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV = NULL; +PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV = NULL; +PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV = NULL; + +PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV = NULL; +PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV = NULL; +PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV = NULL; +PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV = NULL; +PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV = NULL; +PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV = NULL; + +PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL; +PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL; + +PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV = NULL; +PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV = NULL; +PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV = NULL; +PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV = NULL; +PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV = NULL; +PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV = NULL; + +PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL; +PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL; +PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL; +PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL; +PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL; +PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL; +GLboolean __WGLEW_3DFX_multisample = GL_FALSE; +GLboolean __WGLEW_3DL_stereo_control = GL_FALSE; +GLboolean __WGLEW_ARB_buffer_region = GL_FALSE; +GLboolean __WGLEW_ARB_create_context = GL_FALSE; +GLboolean __WGLEW_ARB_extensions_string = GL_FALSE; +GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __WGLEW_ARB_make_current_read = GL_FALSE; +GLboolean __WGLEW_ARB_multisample = GL_FALSE; +GLboolean __WGLEW_ARB_pbuffer = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ARB_render_texture = GL_FALSE; +GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_EXT_depth_float = GL_FALSE; +GLboolean __WGLEW_EXT_display_color_table = GL_FALSE; +GLboolean __WGLEW_EXT_extensions_string = GL_FALSE; +GLboolean __WGLEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __WGLEW_EXT_make_current_read = GL_FALSE; +GLboolean __WGLEW_EXT_multisample = GL_FALSE; +GLboolean __WGLEW_EXT_pbuffer = GL_FALSE; +GLboolean __WGLEW_EXT_pixel_format = GL_FALSE; +GLboolean __WGLEW_EXT_pixel_format_packed_float = GL_FALSE; +GLboolean __WGLEW_EXT_swap_control = GL_FALSE; +GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE; +GLboolean __WGLEW_I3D_gamma = GL_FALSE; +GLboolean __WGLEW_I3D_genlock = GL_FALSE; +GLboolean __WGLEW_I3D_image_buffer = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE; +GLboolean __WGLEW_NV_float_buffer = GL_FALSE; +GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE; +GLboolean __WGLEW_NV_present_video = GL_FALSE; +GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE; +GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_NV_swap_group = GL_FALSE; +GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __WGLEW_NV_video_output = GL_FALSE; +GLboolean __WGLEW_OML_sync_control = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef WGL_3DFX_multisample + +#endif /* WGL_3DFX_multisample */ + +#ifdef WGL_3DL_stereo_control + +static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r; + + return r; +} + +#endif /* WGL_3DL_stereo_control */ + +#ifdef WGL_ARB_buffer_region + +static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r; + r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r; + r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r; + r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_buffer_region */ + +#ifdef WGL_ARB_create_context + +static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateContextAttribsARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_create_context */ + +#ifdef WGL_ARB_extensions_string + +static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_extensions_string */ + +#ifdef WGL_ARB_framebuffer_sRGB + +#endif /* WGL_ARB_framebuffer_sRGB */ + +#ifdef WGL_ARB_make_current_read + +static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r; + r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_make_current_read */ + +#ifdef WGL_ARB_multisample + +#endif /* WGL_ARB_multisample */ + +#ifdef WGL_ARB_pbuffer + +static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r; + r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r; + r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r; + r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r; + r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pbuffer */ + +#ifdef WGL_ARB_pixel_format + +static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pixel_format */ + +#ifdef WGL_ARB_pixel_format_float + +#endif /* WGL_ARB_pixel_format_float */ + +#ifdef WGL_ARB_render_texture + +static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r; + r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r; + r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_render_texture */ + +#ifdef WGL_ATI_pixel_format_float + +#endif /* WGL_ATI_pixel_format_float */ + +#ifdef WGL_ATI_render_texture_rectangle + +#endif /* WGL_ATI_render_texture_rectangle */ + +#ifdef WGL_EXT_depth_float + +#endif /* WGL_EXT_depth_float */ + +#ifdef WGL_EXT_display_color_table + +static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r; + r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r; + r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r; + r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_display_color_table */ + +#ifdef WGL_EXT_extensions_string + +static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_extensions_string */ + +#ifdef WGL_EXT_framebuffer_sRGB + +#endif /* WGL_EXT_framebuffer_sRGB */ + +#ifdef WGL_EXT_make_current_read + +static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r; + r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_make_current_read */ + +#ifdef WGL_EXT_multisample + +#endif /* WGL_EXT_multisample */ + +#ifdef WGL_EXT_pbuffer + +static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r; + r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r; + r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r; + r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r; + r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pbuffer */ + +#ifdef WGL_EXT_pixel_format + +static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pixel_format */ + +#ifdef WGL_EXT_pixel_format_packed_float + +#endif /* WGL_EXT_pixel_format_packed_float */ + +#ifdef WGL_EXT_swap_control + +static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r; + r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_swap_control */ + +#ifdef WGL_I3D_digital_video_control + +static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r; + r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_digital_video_control */ + +#ifdef WGL_I3D_gamma + +static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r; + r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r; + r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r; + r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_gamma */ + +#ifdef WGL_I3D_genlock + +static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r; + r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r; + r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r; + r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r; + r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r; + r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_genlock */ + +#ifdef WGL_I3D_image_buffer + +static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r; + r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r; + r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r; + r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_image_buffer */ + +#ifdef WGL_I3D_swap_frame_lock + +static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r; + r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r; + r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r; + r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_lock */ + +#ifdef WGL_I3D_swap_frame_usage + +static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r; + r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r; + r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r; + r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_usage */ + +#ifdef WGL_NV_float_buffer + +#endif /* WGL_NV_float_buffer */ + +#ifdef WGL_NV_gpu_affinity + +static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglCreateAffinityDCNV")) == NULL) || r; + r = ((wglDeleteDCNV = (PFNWGLDELETEDCNVPROC)glewGetProcAddress((const GLubyte*)"wglDeleteDCNV")) == NULL) || r; + r = ((wglEnumGpuDevicesNV = (PFNWGLENUMGPUDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpuDevicesNV")) == NULL) || r; + r = ((wglEnumGpusFromAffinityDCNV = (PFNWGLENUMGPUSFROMAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusFromAffinityDCNV")) == NULL) || r; + r = ((wglEnumGpusNV = (PFNWGLENUMGPUSNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_gpu_affinity */ + +#ifdef WGL_NV_present_video + +static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindVideoDeviceNV = (PFNWGLBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoDeviceNV")) == NULL) || r; + r = ((wglEnumerateVideoDevicesNV = (PFNWGLENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoDevicesNV")) == NULL) || r; + r = ((wglQueryCurrentContextNV = (PFNWGLQUERYCURRENTCONTEXTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryCurrentContextNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_present_video */ + +#ifdef WGL_NV_render_depth_texture + +#endif /* WGL_NV_render_depth_texture */ + +#ifdef WGL_NV_render_texture_rectangle + +#endif /* WGL_NV_render_texture_rectangle */ + +#ifdef WGL_NV_swap_group + +static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"wglBindSwapBarrierNV")) == NULL) || r; + r = ((wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglJoinSwapGroupNV")) == NULL) || r; + r = ((wglQueryFrameCountNV = (PFNWGLQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameCountNV")) == NULL) || r; + r = ((wglQueryMaxSwapGroupsNV = (PFNWGLQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryMaxSwapGroupsNV")) == NULL) || r; + r = ((wglQuerySwapGroupNV = (PFNWGLQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglQuerySwapGroupNV")) == NULL) || r; + r = ((wglResetFrameCountNV = (PFNWGLRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglResetFrameCountNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_swap_group */ + +#ifdef WGL_NV_vertex_array_range + +static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r; + r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_vertex_array_range */ + +#ifdef WGL_NV_video_output + +static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindVideoImageNV = (PFNWGLBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoImageNV")) == NULL) || r; + r = ((wglGetVideoDeviceNV = (PFNWGLGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoDeviceNV")) == NULL) || r; + r = ((wglGetVideoInfoNV = (PFNWGLGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoInfoNV")) == NULL) || r; + r = ((wglReleaseVideoDeviceNV = (PFNWGLRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoDeviceNV")) == NULL) || r; + r = ((wglReleaseVideoImageNV = (PFNWGLRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoImageNV")) == NULL) || r; + r = ((wglSendPbufferToVideoNV = (PFNWGLSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"wglSendPbufferToVideoNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_video_output */ + +#ifdef WGL_OML_sync_control + +static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r; + r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r; + r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r; + r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r; + r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r; + r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL; +static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL; + +GLboolean wglewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + if (_wglewGetExtensionsStringARB == NULL) + if (_wglewGetExtensionsStringEXT == NULL) + return GL_FALSE; + else + p = (GLubyte*)_wglewGetExtensionsStringEXT(); + else + p = (GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) +{ + GLboolean crippled; + /* find wgl extension string query functions */ + _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); + _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); + /* initialize extensions */ + crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; +#ifdef WGL_3DFX_multisample + CONST_CAST(WGLEW_3DFX_multisample) = wglewGetExtension("WGL_3DFX_multisample"); +#endif /* WGL_3DFX_multisample */ +#ifdef WGL_3DL_stereo_control + CONST_CAST(WGLEW_3DL_stereo_control) = wglewGetExtension("WGL_3DL_stereo_control"); + if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) CONST_CAST(WGLEW_3DL_stereo_control)= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_3DL_stereo_control */ +#ifdef WGL_ARB_buffer_region + CONST_CAST(WGLEW_ARB_buffer_region) = wglewGetExtension("WGL_ARB_buffer_region"); + if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) CONST_CAST(WGLEW_ARB_buffer_region)= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_buffer_region */ +#ifdef WGL_ARB_create_context + CONST_CAST(WGLEW_ARB_create_context) = wglewGetExtension("WGL_ARB_create_context"); + if (glewExperimental || WGLEW_ARB_create_context|| crippled) CONST_CAST(WGLEW_ARB_create_context)= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_create_context */ +#ifdef WGL_ARB_extensions_string + CONST_CAST(WGLEW_ARB_extensions_string) = wglewGetExtension("WGL_ARB_extensions_string"); + if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) CONST_CAST(WGLEW_ARB_extensions_string)= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_extensions_string */ +#ifdef WGL_ARB_framebuffer_sRGB + CONST_CAST(WGLEW_ARB_framebuffer_sRGB) = wglewGetExtension("WGL_ARB_framebuffer_sRGB"); +#endif /* WGL_ARB_framebuffer_sRGB */ +#ifdef WGL_ARB_make_current_read + CONST_CAST(WGLEW_ARB_make_current_read) = wglewGetExtension("WGL_ARB_make_current_read"); + if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) CONST_CAST(WGLEW_ARB_make_current_read)= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_make_current_read */ +#ifdef WGL_ARB_multisample + CONST_CAST(WGLEW_ARB_multisample) = wglewGetExtension("WGL_ARB_multisample"); +#endif /* WGL_ARB_multisample */ +#ifdef WGL_ARB_pbuffer + CONST_CAST(WGLEW_ARB_pbuffer) = wglewGetExtension("WGL_ARB_pbuffer"); + if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) CONST_CAST(WGLEW_ARB_pbuffer)= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pbuffer */ +#ifdef WGL_ARB_pixel_format + CONST_CAST(WGLEW_ARB_pixel_format) = wglewGetExtension("WGL_ARB_pixel_format"); + if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) CONST_CAST(WGLEW_ARB_pixel_format)= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pixel_format */ +#ifdef WGL_ARB_pixel_format_float + CONST_CAST(WGLEW_ARB_pixel_format_float) = wglewGetExtension("WGL_ARB_pixel_format_float"); +#endif /* WGL_ARB_pixel_format_float */ +#ifdef WGL_ARB_render_texture + CONST_CAST(WGLEW_ARB_render_texture) = wglewGetExtension("WGL_ARB_render_texture"); + if (glewExperimental || WGLEW_ARB_render_texture|| crippled) CONST_CAST(WGLEW_ARB_render_texture)= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_render_texture */ +#ifdef WGL_ATI_pixel_format_float + CONST_CAST(WGLEW_ATI_pixel_format_float) = wglewGetExtension("WGL_ATI_pixel_format_float"); +#endif /* WGL_ATI_pixel_format_float */ +#ifdef WGL_ATI_render_texture_rectangle + CONST_CAST(WGLEW_ATI_render_texture_rectangle) = wglewGetExtension("WGL_ATI_render_texture_rectangle"); +#endif /* WGL_ATI_render_texture_rectangle */ +#ifdef WGL_EXT_depth_float + CONST_CAST(WGLEW_EXT_depth_float) = wglewGetExtension("WGL_EXT_depth_float"); +#endif /* WGL_EXT_depth_float */ +#ifdef WGL_EXT_display_color_table + CONST_CAST(WGLEW_EXT_display_color_table) = wglewGetExtension("WGL_EXT_display_color_table"); + if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) CONST_CAST(WGLEW_EXT_display_color_table)= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_display_color_table */ +#ifdef WGL_EXT_extensions_string + CONST_CAST(WGLEW_EXT_extensions_string) = wglewGetExtension("WGL_EXT_extensions_string"); + if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) CONST_CAST(WGLEW_EXT_extensions_string)= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_extensions_string */ +#ifdef WGL_EXT_framebuffer_sRGB + CONST_CAST(WGLEW_EXT_framebuffer_sRGB) = wglewGetExtension("WGL_EXT_framebuffer_sRGB"); +#endif /* WGL_EXT_framebuffer_sRGB */ +#ifdef WGL_EXT_make_current_read + CONST_CAST(WGLEW_EXT_make_current_read) = wglewGetExtension("WGL_EXT_make_current_read"); + if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) CONST_CAST(WGLEW_EXT_make_current_read)= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_make_current_read */ +#ifdef WGL_EXT_multisample + CONST_CAST(WGLEW_EXT_multisample) = wglewGetExtension("WGL_EXT_multisample"); +#endif /* WGL_EXT_multisample */ +#ifdef WGL_EXT_pbuffer + CONST_CAST(WGLEW_EXT_pbuffer) = wglewGetExtension("WGL_EXT_pbuffer"); + if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) CONST_CAST(WGLEW_EXT_pbuffer)= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pbuffer */ +#ifdef WGL_EXT_pixel_format + CONST_CAST(WGLEW_EXT_pixel_format) = wglewGetExtension("WGL_EXT_pixel_format"); + if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) CONST_CAST(WGLEW_EXT_pixel_format)= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pixel_format */ +#ifdef WGL_EXT_pixel_format_packed_float + CONST_CAST(WGLEW_EXT_pixel_format_packed_float) = wglewGetExtension("WGL_EXT_pixel_format_packed_float"); +#endif /* WGL_EXT_pixel_format_packed_float */ +#ifdef WGL_EXT_swap_control + CONST_CAST(WGLEW_EXT_swap_control) = wglewGetExtension("WGL_EXT_swap_control"); + if (glewExperimental || WGLEW_EXT_swap_control|| crippled) CONST_CAST(WGLEW_EXT_swap_control)= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_swap_control */ +#ifdef WGL_I3D_digital_video_control + CONST_CAST(WGLEW_I3D_digital_video_control) = wglewGetExtension("WGL_I3D_digital_video_control"); + if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) CONST_CAST(WGLEW_I3D_digital_video_control)= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_digital_video_control */ +#ifdef WGL_I3D_gamma + CONST_CAST(WGLEW_I3D_gamma) = wglewGetExtension("WGL_I3D_gamma"); + if (glewExperimental || WGLEW_I3D_gamma|| crippled) CONST_CAST(WGLEW_I3D_gamma)= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_gamma */ +#ifdef WGL_I3D_genlock + CONST_CAST(WGLEW_I3D_genlock) = wglewGetExtension("WGL_I3D_genlock"); + if (glewExperimental || WGLEW_I3D_genlock|| crippled) CONST_CAST(WGLEW_I3D_genlock)= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_genlock */ +#ifdef WGL_I3D_image_buffer + CONST_CAST(WGLEW_I3D_image_buffer) = wglewGetExtension("WGL_I3D_image_buffer"); + if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) CONST_CAST(WGLEW_I3D_image_buffer)= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_image_buffer */ +#ifdef WGL_I3D_swap_frame_lock + CONST_CAST(WGLEW_I3D_swap_frame_lock) = wglewGetExtension("WGL_I3D_swap_frame_lock"); + if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_lock)= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_lock */ +#ifdef WGL_I3D_swap_frame_usage + CONST_CAST(WGLEW_I3D_swap_frame_usage) = wglewGetExtension("WGL_I3D_swap_frame_usage"); + if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_usage)= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_usage */ +#ifdef WGL_NV_float_buffer + CONST_CAST(WGLEW_NV_float_buffer) = wglewGetExtension("WGL_NV_float_buffer"); +#endif /* WGL_NV_float_buffer */ +#ifdef WGL_NV_gpu_affinity + CONST_CAST(WGLEW_NV_gpu_affinity) = wglewGetExtension("WGL_NV_gpu_affinity"); + if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) CONST_CAST(WGLEW_NV_gpu_affinity)= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_gpu_affinity */ +#ifdef WGL_NV_present_video + CONST_CAST(WGLEW_NV_present_video) = wglewGetExtension("WGL_NV_present_video"); + if (glewExperimental || WGLEW_NV_present_video|| crippled) CONST_CAST(WGLEW_NV_present_video)= !_glewInit_WGL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_present_video */ +#ifdef WGL_NV_render_depth_texture + CONST_CAST(WGLEW_NV_render_depth_texture) = wglewGetExtension("WGL_NV_render_depth_texture"); +#endif /* WGL_NV_render_depth_texture */ +#ifdef WGL_NV_render_texture_rectangle + CONST_CAST(WGLEW_NV_render_texture_rectangle) = wglewGetExtension("WGL_NV_render_texture_rectangle"); +#endif /* WGL_NV_render_texture_rectangle */ +#ifdef WGL_NV_swap_group + CONST_CAST(WGLEW_NV_swap_group) = wglewGetExtension("WGL_NV_swap_group"); + if (glewExperimental || WGLEW_NV_swap_group|| crippled) CONST_CAST(WGLEW_NV_swap_group)= !_glewInit_WGL_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_swap_group */ +#ifdef WGL_NV_vertex_array_range + CONST_CAST(WGLEW_NV_vertex_array_range) = wglewGetExtension("WGL_NV_vertex_array_range"); + if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) CONST_CAST(WGLEW_NV_vertex_array_range)= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_vertex_array_range */ +#ifdef WGL_NV_video_output + CONST_CAST(WGLEW_NV_video_output) = wglewGetExtension("WGL_NV_video_output"); + if (glewExperimental || WGLEW_NV_video_output|| crippled) CONST_CAST(WGLEW_NV_video_output)= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_video_output */ +#ifdef WGL_OML_sync_control + CONST_CAST(WGLEW_OML_sync_control) = wglewGetExtension("WGL_OML_sync_control"); + if (glewExperimental || WGLEW_OML_sync_control|| crippled) CONST_CAST(WGLEW_OML_sync_control)= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_OML_sync_control */ + + return GLEW_OK; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL; + +PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL; +PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL; +PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL; +PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL; +PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL; +PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL; +PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL; +PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL; +PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL; +PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL; +PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL; +PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL; +PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL; +PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL; +PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL; +PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL; +PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL; + +PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB = NULL; + +PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL; +PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL; +PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL; + +PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL; +PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL; +PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL; +PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL; + +PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL; +PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL; + +PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL; + +PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL; + +PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL; + +PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL; + +PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL; + +PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL; +PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL; + +PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV = NULL; +PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV = NULL; +PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV = NULL; +PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV = NULL; +PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV = NULL; +PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV = NULL; + +PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL; +PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL; + +PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL; +PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL; +PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL; +PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL; +PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL; +PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL; + +#ifdef GLX_OML_sync_control +PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL; +PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL; +PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL; +PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL; +PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL; +#endif + +PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL; +PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL; +PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL; +PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL; +PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL; +PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL; + +PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX = NULL; +PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX = NULL; +PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX = NULL; +PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX = NULL; +PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX = NULL; +PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX = NULL; +PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX = NULL; +PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX = NULL; + +PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL; +PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL; +PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL; +PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL; +PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL; + +PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL; +PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL; + +PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL; + +PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL; +PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL; +PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL; +PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL; +PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL; + +PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL; + +PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL; +PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL; + +PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL; + +PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL; +PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL; + +PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL; + +PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL; +PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL; + +#if !defined(GLEW_MX) + +GLboolean __GLXEW_VERSION_1_0 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLXEW_3DFX_multisample = GL_FALSE; +GLboolean __GLXEW_ARB_create_context = GL_FALSE; +GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE; +GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE; +GLboolean __GLXEW_ARB_multisample = GL_FALSE; +GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __GLXEW_ATI_render_texture = GL_FALSE; +GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE; +GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __GLXEW_EXT_import_context = GL_FALSE; +GLboolean __GLXEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE; +GLboolean __GLXEW_EXT_visual_info = GL_FALSE; +GLboolean __GLXEW_EXT_visual_rating = GL_FALSE; +GLboolean __GLXEW_MESA_agp_offset = GL_FALSE; +GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE; +GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE; +GLboolean __GLXEW_MESA_release_buffers = GL_FALSE; +GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE; +GLboolean __GLXEW_NV_float_buffer = GL_FALSE; +GLboolean __GLXEW_NV_present_video = GL_FALSE; +GLboolean __GLXEW_NV_swap_group = GL_FALSE; +GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLXEW_NV_video_output = GL_FALSE; +GLboolean __GLXEW_OML_swap_method = GL_FALSE; +#ifdef GLX_OML_sync_control +GLboolean __GLXEW_OML_sync_control = GL_FALSE; +#endif +GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE; +GLboolean __GLXEW_SGIS_color_range = GL_FALSE; +GLboolean __GLXEW_SGIS_multisample = GL_FALSE; +GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE; +GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE; +GLboolean __GLXEW_SGIX_hyperpipe = GL_FALSE; +GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_group = GL_FALSE; +GLboolean __GLXEW_SGIX_video_resize = GL_FALSE; +GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE; +GLboolean __GLXEW_SGI_cushion = GL_FALSE; +GLboolean __GLXEW_SGI_make_current_read = GL_FALSE; +GLboolean __GLXEW_SGI_swap_control = GL_FALSE; +GLboolean __GLXEW_SGI_video_sync = GL_FALSE; +GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE; +GLboolean __GLXEW_SUN_video_resize = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GLX_VERSION_1_2 + +static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_2 */ + +#ifdef GLX_VERSION_1_3 + +static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r; + r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r; + r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r; + r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r; + r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r; + r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r; + r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r; + r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r; + r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r; + r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r; + r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r; + r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r; + r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r; + r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r; + r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r; + r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r; + r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_3 */ + +#ifdef GLX_VERSION_1_4 + +#endif /* GLX_VERSION_1_4 */ + +#ifdef GLX_3DFX_multisample + +#endif /* GLX_3DFX_multisample */ + +#ifdef GLX_ARB_create_context + +static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB")) == NULL) || r; + + return r; +} + +#endif /* GLX_ARB_create_context */ + +#ifdef GLX_ARB_fbconfig_float + +#endif /* GLX_ARB_fbconfig_float */ + +#ifdef GLX_ARB_framebuffer_sRGB + +#endif /* GLX_ARB_framebuffer_sRGB */ + +#ifdef GLX_ARB_get_proc_address + +#endif /* GLX_ARB_get_proc_address */ + +#ifdef GLX_ARB_multisample + +#endif /* GLX_ARB_multisample */ + +#ifdef GLX_ATI_pixel_format_float + +#endif /* GLX_ATI_pixel_format_float */ + +#ifdef GLX_ATI_render_texture + +static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r; + r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r; + r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r; + + return r; +} + +#endif /* GLX_ATI_render_texture */ + +#ifdef GLX_EXT_fbconfig_packed_float + +#endif /* GLX_EXT_fbconfig_packed_float */ + +#ifdef GLX_EXT_framebuffer_sRGB + +#endif /* GLX_EXT_framebuffer_sRGB */ + +#ifdef GLX_EXT_import_context + +static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r; + r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r; + r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r; + r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_import_context */ + +#ifdef GLX_EXT_scene_marker + +#endif /* GLX_EXT_scene_marker */ + +#ifdef GLX_EXT_texture_from_pixmap + +static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageEXT")) == NULL) || r; + r = ((glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_texture_from_pixmap */ + +#ifdef GLX_EXT_visual_info + +#endif /* GLX_EXT_visual_info */ + +#ifdef GLX_EXT_visual_rating + +#endif /* GLX_EXT_visual_rating */ + +#ifdef GLX_MESA_agp_offset + +static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_agp_offset */ + +#ifdef GLX_MESA_copy_sub_buffer + +static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_copy_sub_buffer */ + +#ifdef GLX_MESA_pixmap_colormap + +static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_pixmap_colormap */ + +#ifdef GLX_MESA_release_buffers + +static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_release_buffers */ + +#ifdef GLX_MESA_set_3dfx_mode + +static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_set_3dfx_mode */ + +#ifdef GLX_NV_float_buffer + +#endif /* GLX_NV_float_buffer */ + +#ifdef GLX_NV_present_video + +static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoDeviceNV")) == NULL) || r; + r = ((glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoDevicesNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_present_video */ + +#ifdef GLX_NV_swap_group + +static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierNV")) == NULL) || r; + r = ((glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupNV")) == NULL) || r; + r = ((glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryFrameCountNV")) == NULL) || r; + r = ((glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapGroupsNV")) == NULL) || r; + r = ((glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXQuerySwapGroupNV")) == NULL) || r; + r = ((glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXResetFrameCountNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_swap_group */ + +#ifdef GLX_NV_vertex_array_range + +static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r; + r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_vertex_array_range */ + +#ifdef GLX_NV_video_output + +static GLboolean _glewInit_GLX_NV_video_output (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoImageNV")) == NULL) || r; + r = ((glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoDeviceNV")) == NULL) || r; + r = ((glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoInfoNV")) == NULL) || r; + r = ((glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoDeviceNV")) == NULL) || r; + r = ((glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoImageNV")) == NULL) || r; + r = ((glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"glXSendPbufferToVideoNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_video_output */ + +#ifdef GLX_OML_swap_method + +#endif /* GLX_OML_swap_method */ + +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + +static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r; + r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r; + r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r; + r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r; + r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* GLX_OML_sync_control */ + +#ifdef GLX_SGIS_blended_overlay + +#endif /* GLX_SGIS_blended_overlay */ + +#ifdef GLX_SGIS_color_range + +#endif /* GLX_SGIS_color_range */ + +#ifdef GLX_SGIS_multisample + +#endif /* GLX_SGIS_multisample */ + +#ifdef GLX_SGIS_shared_multisample + +#endif /* GLX_SGIS_shared_multisample */ + +#ifdef GLX_SGIX_fbconfig + +static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r; + r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r; + r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r; + r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r; + r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r; + r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_fbconfig */ + +#ifdef GLX_SGIX_hyperpipe + +static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindHyperpipeSGIX")) == NULL) || r; + r = ((glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeAttribSGIX")) == NULL) || r; + r = ((glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeAttribSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeBestAttribSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeNetworkSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_hyperpipe */ + +#ifdef GLX_SGIX_pbuffer + +static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r; + r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r; + r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r; + r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r; + r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_pbuffer */ + +#ifdef GLX_SGIX_swap_barrier + +static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r; + r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_barrier */ + +#ifdef GLX_SGIX_swap_group + +static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_group */ + +#ifdef GLX_SGIX_video_resize + +static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r; + r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r; + r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r; + r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r; + r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_video_resize */ + +#ifdef GLX_SGIX_visual_select_group + +#endif /* GLX_SGIX_visual_select_group */ + +#ifdef GLX_SGI_cushion + +static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_cushion */ + +#ifdef GLX_SGI_make_current_read + +static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r; + r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_make_current_read */ + +#ifdef GLX_SGI_swap_control + +static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_swap_control */ + +#ifdef GLX_SGI_video_sync + +static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r; + r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_video_sync */ + +#ifdef GLX_SUN_get_transparent_index + +static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_get_transparent_index */ + +#ifdef GLX_SUN_video_resize + +static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r; + r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------ */ + +GLboolean glxewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); +/* if (glXQueryExtensionsString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; */ +/* p = (GLubyte*)glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay())); */ + if (glXGetClientString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; + p = (GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) +{ + int major, minor; + /* initialize core GLX 1.2 */ + if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY; + /* initialize flags */ + CONST_CAST(GLXEW_VERSION_1_0) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_1) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_4) = GL_TRUE; + /* query GLX version */ + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if (major == 1 && minor <= 3) + { + switch (minor) + { + case 3: + CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; + break; + case 2: + CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLXEW_VERSION_1_3) = GL_FALSE; + break; + default: + return GLEW_ERROR_GLX_VERSION_11_ONLY; + break; + } + } + /* initialize extensions */ +#ifdef GLX_VERSION_1_3 + if (glewExperimental || GLXEW_VERSION_1_3) CONST_CAST(GLXEW_VERSION_1_3) = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_VERSION_1_3 */ +#ifdef GLX_3DFX_multisample + CONST_CAST(GLXEW_3DFX_multisample) = glxewGetExtension("GLX_3DFX_multisample"); +#endif /* GLX_3DFX_multisample */ +#ifdef GLX_ARB_create_context + CONST_CAST(GLXEW_ARB_create_context) = glxewGetExtension("GLX_ARB_create_context"); + if (glewExperimental || GLXEW_ARB_create_context) CONST_CAST(GLXEW_ARB_create_context) = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ARB_create_context */ +#ifdef GLX_ARB_fbconfig_float + CONST_CAST(GLXEW_ARB_fbconfig_float) = glxewGetExtension("GLX_ARB_fbconfig_float"); +#endif /* GLX_ARB_fbconfig_float */ +#ifdef GLX_ARB_framebuffer_sRGB + CONST_CAST(GLXEW_ARB_framebuffer_sRGB) = glxewGetExtension("GLX_ARB_framebuffer_sRGB"); +#endif /* GLX_ARB_framebuffer_sRGB */ +#ifdef GLX_ARB_get_proc_address + CONST_CAST(GLXEW_ARB_get_proc_address) = glxewGetExtension("GLX_ARB_get_proc_address"); +#endif /* GLX_ARB_get_proc_address */ +#ifdef GLX_ARB_multisample + CONST_CAST(GLXEW_ARB_multisample) = glxewGetExtension("GLX_ARB_multisample"); +#endif /* GLX_ARB_multisample */ +#ifdef GLX_ATI_pixel_format_float + CONST_CAST(GLXEW_ATI_pixel_format_float) = glxewGetExtension("GLX_ATI_pixel_format_float"); +#endif /* GLX_ATI_pixel_format_float */ +#ifdef GLX_ATI_render_texture + CONST_CAST(GLXEW_ATI_render_texture) = glxewGetExtension("GLX_ATI_render_texture"); + if (glewExperimental || GLXEW_ATI_render_texture) CONST_CAST(GLXEW_ATI_render_texture) = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ATI_render_texture */ +#ifdef GLX_EXT_fbconfig_packed_float + CONST_CAST(GLXEW_EXT_fbconfig_packed_float) = glxewGetExtension("GLX_EXT_fbconfig_packed_float"); +#endif /* GLX_EXT_fbconfig_packed_float */ +#ifdef GLX_EXT_framebuffer_sRGB + CONST_CAST(GLXEW_EXT_framebuffer_sRGB) = glxewGetExtension("GLX_EXT_framebuffer_sRGB"); +#endif /* GLX_EXT_framebuffer_sRGB */ +#ifdef GLX_EXT_import_context + CONST_CAST(GLXEW_EXT_import_context) = glxewGetExtension("GLX_EXT_import_context"); + if (glewExperimental || GLXEW_EXT_import_context) CONST_CAST(GLXEW_EXT_import_context) = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_import_context */ +#ifdef GLX_EXT_scene_marker + CONST_CAST(GLXEW_EXT_scene_marker) = glxewGetExtension("GLX_EXT_scene_marker"); +#endif /* GLX_EXT_scene_marker */ +#ifdef GLX_EXT_texture_from_pixmap + CONST_CAST(GLXEW_EXT_texture_from_pixmap) = glxewGetExtension("GLX_EXT_texture_from_pixmap"); + if (glewExperimental || GLXEW_EXT_texture_from_pixmap) CONST_CAST(GLXEW_EXT_texture_from_pixmap) = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_texture_from_pixmap */ +#ifdef GLX_EXT_visual_info + CONST_CAST(GLXEW_EXT_visual_info) = glxewGetExtension("GLX_EXT_visual_info"); +#endif /* GLX_EXT_visual_info */ +#ifdef GLX_EXT_visual_rating + CONST_CAST(GLXEW_EXT_visual_rating) = glxewGetExtension("GLX_EXT_visual_rating"); +#endif /* GLX_EXT_visual_rating */ +#ifdef GLX_MESA_agp_offset + CONST_CAST(GLXEW_MESA_agp_offset) = glxewGetExtension("GLX_MESA_agp_offset"); + if (glewExperimental || GLXEW_MESA_agp_offset) CONST_CAST(GLXEW_MESA_agp_offset) = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_agp_offset */ +#ifdef GLX_MESA_copy_sub_buffer + CONST_CAST(GLXEW_MESA_copy_sub_buffer) = glxewGetExtension("GLX_MESA_copy_sub_buffer"); + if (glewExperimental || GLXEW_MESA_copy_sub_buffer) CONST_CAST(GLXEW_MESA_copy_sub_buffer) = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_copy_sub_buffer */ +#ifdef GLX_MESA_pixmap_colormap + CONST_CAST(GLXEW_MESA_pixmap_colormap) = glxewGetExtension("GLX_MESA_pixmap_colormap"); + if (glewExperimental || GLXEW_MESA_pixmap_colormap) CONST_CAST(GLXEW_MESA_pixmap_colormap) = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_pixmap_colormap */ +#ifdef GLX_MESA_release_buffers + CONST_CAST(GLXEW_MESA_release_buffers) = glxewGetExtension("GLX_MESA_release_buffers"); + if (glewExperimental || GLXEW_MESA_release_buffers) CONST_CAST(GLXEW_MESA_release_buffers) = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_release_buffers */ +#ifdef GLX_MESA_set_3dfx_mode + CONST_CAST(GLXEW_MESA_set_3dfx_mode) = glxewGetExtension("GLX_MESA_set_3dfx_mode"); + if (glewExperimental || GLXEW_MESA_set_3dfx_mode) CONST_CAST(GLXEW_MESA_set_3dfx_mode) = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_set_3dfx_mode */ +#ifdef GLX_NV_float_buffer + CONST_CAST(GLXEW_NV_float_buffer) = glxewGetExtension("GLX_NV_float_buffer"); +#endif /* GLX_NV_float_buffer */ +#ifdef GLX_NV_present_video + CONST_CAST(GLXEW_NV_present_video) = glxewGetExtension("GLX_NV_present_video"); + if (glewExperimental || GLXEW_NV_present_video) CONST_CAST(GLXEW_NV_present_video) = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_present_video */ +#ifdef GLX_NV_swap_group + CONST_CAST(GLXEW_NV_swap_group) = glxewGetExtension("GLX_NV_swap_group"); + if (glewExperimental || GLXEW_NV_swap_group) CONST_CAST(GLXEW_NV_swap_group) = !_glewInit_GLX_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_swap_group */ +#ifdef GLX_NV_vertex_array_range + CONST_CAST(GLXEW_NV_vertex_array_range) = glxewGetExtension("GLX_NV_vertex_array_range"); + if (glewExperimental || GLXEW_NV_vertex_array_range) CONST_CAST(GLXEW_NV_vertex_array_range) = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_vertex_array_range */ +#ifdef GLX_NV_video_output + CONST_CAST(GLXEW_NV_video_output) = glxewGetExtension("GLX_NV_video_output"); + if (glewExperimental || GLXEW_NV_video_output) CONST_CAST(GLXEW_NV_video_output) = !_glewInit_GLX_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_video_output */ +#ifdef GLX_OML_swap_method + CONST_CAST(GLXEW_OML_swap_method) = glxewGetExtension("GLX_OML_swap_method"); +#endif /* GLX_OML_swap_method */ +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + CONST_CAST(GLXEW_OML_sync_control) = glxewGetExtension("GLX_OML_sync_control"); + if (glewExperimental || GLXEW_OML_sync_control) CONST_CAST(GLXEW_OML_sync_control) = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_OML_sync_control */ +#ifdef GLX_SGIS_blended_overlay + CONST_CAST(GLXEW_SGIS_blended_overlay) = glxewGetExtension("GLX_SGIS_blended_overlay"); +#endif /* GLX_SGIS_blended_overlay */ +#ifdef GLX_SGIS_color_range + CONST_CAST(GLXEW_SGIS_color_range) = glxewGetExtension("GLX_SGIS_color_range"); +#endif /* GLX_SGIS_color_range */ +#ifdef GLX_SGIS_multisample + CONST_CAST(GLXEW_SGIS_multisample) = glxewGetExtension("GLX_SGIS_multisample"); +#endif /* GLX_SGIS_multisample */ +#ifdef GLX_SGIS_shared_multisample + CONST_CAST(GLXEW_SGIS_shared_multisample) = glxewGetExtension("GLX_SGIS_shared_multisample"); +#endif /* GLX_SGIS_shared_multisample */ +#ifdef GLX_SGIX_fbconfig + CONST_CAST(GLXEW_SGIX_fbconfig) = glxewGetExtension("GLX_SGIX_fbconfig"); + if (glewExperimental || GLXEW_SGIX_fbconfig) CONST_CAST(GLXEW_SGIX_fbconfig) = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_fbconfig */ +#ifdef GLX_SGIX_hyperpipe + CONST_CAST(GLXEW_SGIX_hyperpipe) = glxewGetExtension("GLX_SGIX_hyperpipe"); + if (glewExperimental || GLXEW_SGIX_hyperpipe) CONST_CAST(GLXEW_SGIX_hyperpipe) = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_hyperpipe */ +#ifdef GLX_SGIX_pbuffer + CONST_CAST(GLXEW_SGIX_pbuffer) = glxewGetExtension("GLX_SGIX_pbuffer"); + if (glewExperimental || GLXEW_SGIX_pbuffer) CONST_CAST(GLXEW_SGIX_pbuffer) = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_pbuffer */ +#ifdef GLX_SGIX_swap_barrier + CONST_CAST(GLXEW_SGIX_swap_barrier) = glxewGetExtension("GLX_SGIX_swap_barrier"); + if (glewExperimental || GLXEW_SGIX_swap_barrier) CONST_CAST(GLXEW_SGIX_swap_barrier) = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_barrier */ +#ifdef GLX_SGIX_swap_group + CONST_CAST(GLXEW_SGIX_swap_group) = glxewGetExtension("GLX_SGIX_swap_group"); + if (glewExperimental || GLXEW_SGIX_swap_group) CONST_CAST(GLXEW_SGIX_swap_group) = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_group */ +#ifdef GLX_SGIX_video_resize + CONST_CAST(GLXEW_SGIX_video_resize) = glxewGetExtension("GLX_SGIX_video_resize"); + if (glewExperimental || GLXEW_SGIX_video_resize) CONST_CAST(GLXEW_SGIX_video_resize) = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_video_resize */ +#ifdef GLX_SGIX_visual_select_group + CONST_CAST(GLXEW_SGIX_visual_select_group) = glxewGetExtension("GLX_SGIX_visual_select_group"); +#endif /* GLX_SGIX_visual_select_group */ +#ifdef GLX_SGI_cushion + CONST_CAST(GLXEW_SGI_cushion) = glxewGetExtension("GLX_SGI_cushion"); + if (glewExperimental || GLXEW_SGI_cushion) CONST_CAST(GLXEW_SGI_cushion) = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_cushion */ +#ifdef GLX_SGI_make_current_read + CONST_CAST(GLXEW_SGI_make_current_read) = glxewGetExtension("GLX_SGI_make_current_read"); + if (glewExperimental || GLXEW_SGI_make_current_read) CONST_CAST(GLXEW_SGI_make_current_read) = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_make_current_read */ +#ifdef GLX_SGI_swap_control + CONST_CAST(GLXEW_SGI_swap_control) = glxewGetExtension("GLX_SGI_swap_control"); + if (glewExperimental || GLXEW_SGI_swap_control) CONST_CAST(GLXEW_SGI_swap_control) = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_swap_control */ +#ifdef GLX_SGI_video_sync + CONST_CAST(GLXEW_SGI_video_sync) = glxewGetExtension("GLX_SGI_video_sync"); + if (glewExperimental || GLXEW_SGI_video_sync) CONST_CAST(GLXEW_SGI_video_sync) = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_video_sync */ +#ifdef GLX_SUN_get_transparent_index + CONST_CAST(GLXEW_SUN_get_transparent_index) = glxewGetExtension("GLX_SUN_get_transparent_index"); + if (glewExperimental || GLXEW_SUN_get_transparent_index) CONST_CAST(GLXEW_SUN_get_transparent_index) = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_get_transparent_index */ +#ifdef GLX_SUN_video_resize + CONST_CAST(GLXEW_SUN_video_resize) = glxewGetExtension("GLX_SUN_video_resize"); + if (glewExperimental || GLXEW_SUN_video_resize) CONST_CAST(GLXEW_SUN_video_resize) = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_video_resize */ + + return GLEW_OK; +} + +#endif /* !__APPLE__ || GLEW_APPLE_GLX */ + +/* ------------------------------------------------------------------------ */ + +const GLubyte* glewGetErrorString (GLenum error) +{ + static const GLubyte* _glewErrorString[] = + { + (const GLubyte*)"No error", + (const GLubyte*)"Missing GL version", + (const GLubyte*)"GL 1.1 and up are not supported", + (const GLubyte*)"GLX 1.2 and up are not supported", + (const GLubyte*)"Unknown error" + }; + const int max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; + return _glewErrorString[(int)error > max_error ? max_error : (int)error]; +} + +const GLubyte* glewGetString (GLenum name) +{ + static const GLubyte* _glewString[] = + { + (const GLubyte*)NULL, + (const GLubyte*)"1.5.1", + (const GLubyte*)"1", + (const GLubyte*)"5", + (const GLubyte*)"1" + }; + const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; + return _glewString[(int)name > max_string ? 0 : (int)name]; +} + +/* ------------------------------------------------------------------------ */ + +GLboolean glewExperimental = GL_FALSE; + +#if !defined(GLEW_MX) + +#if defined(_WIN32) +extern GLenum wglewContextInit (void); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ +extern GLenum glxewContextInit (void); +#endif /* _WIN32 */ + +GLenum glewInit () +{ + GLenum r; + if ( (r = glewContextInit()) ) return r; +#if defined(_WIN32) + return wglewContextInit(); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ + return glxewContextInit(); +#else + return r; +#endif /* _WIN32 */ +} + +#endif /* !GLEW_MX */ +#ifdef GLEW_MX +GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name) +#else +GLboolean glewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GL_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLEW_VERSION_1_2; + continue; + } +#endif +#ifdef GL_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLEW_VERSION_1_3; + continue; + } +#endif +#ifdef GL_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLEW_VERSION_1_4; + continue; + } +#endif +#ifdef GL_VERSION_1_5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3)) + { + ret = GLEW_VERSION_1_5; + continue; + } +#endif +#ifdef GL_VERSION_2_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3)) + { + ret = GLEW_VERSION_2_0; + continue; + } +#endif +#ifdef GL_VERSION_2_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3)) + { + ret = GLEW_VERSION_2_1; + continue; + } +#endif +#ifdef GL_VERSION_3_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3)) + { + ret = GLEW_VERSION_3_0; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_3DFX_multisample; + continue; + } +#endif +#ifdef GL_3DFX_tbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7)) + { + ret = GLEW_3DFX_tbuffer; + continue; + } +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24)) + { + ret = GLEW_3DFX_texture_compression_FXT1; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) + { +#ifdef GL_APPLE_client_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14)) + { + ret = GLEW_APPLE_client_storage; + continue; + } +#endif +#ifdef GL_APPLE_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_APPLE_element_array; + continue; + } +#endif +#ifdef GL_APPLE_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_APPLE_fence; + continue; + } +#endif +#ifdef GL_APPLE_float_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12)) + { + ret = GLEW_APPLE_float_pixels; + continue; + } +#endif +#ifdef GL_APPLE_flush_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18)) + { + ret = GLEW_APPLE_flush_buffer_range; + continue; + } +#endif +#ifdef GL_APPLE_pixel_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12)) + { + ret = GLEW_APPLE_pixel_buffer; + continue; + } +#endif +#ifdef GL_APPLE_specular_vector + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15)) + { + ret = GLEW_APPLE_specular_vector; + continue; + } +#endif +#ifdef GL_APPLE_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_APPLE_texture_range; + continue; + } +#endif +#ifdef GL_APPLE_transform_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14)) + { + ret = GLEW_APPLE_transform_hint; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_APPLE_vertex_array_object; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_APPLE_vertex_array_range; + continue; + } +#endif +#ifdef GL_APPLE_ycbcr_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9)) + { + ret = GLEW_APPLE_ycbcr_422; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GL_ARB_color_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) + { + ret = GLEW_ARB_color_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_ARB_depth_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ARB_depth_texture; + continue; + } +#endif +#ifdef GL_ARB_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ARB_draw_buffers; + continue; + } +#endif +#ifdef GL_ARB_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_ARB_draw_instanced; + continue; + } +#endif +#ifdef GL_ARB_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_ARB_fragment_program; + continue; + } +#endif +#ifdef GL_ARB_fragment_program_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23)) + { + ret = GLEW_ARB_fragment_program_shadow; + continue; + } +#endif +#ifdef GL_ARB_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ARB_fragment_shader; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_ARB_framebuffer_object; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_ARB_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_ARB_geometry_shader4; + continue; + } +#endif +#ifdef GL_ARB_half_float_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16)) + { + ret = GLEW_ARB_half_float_pixel; + continue; + } +#endif +#ifdef GL_ARB_half_float_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17)) + { + ret = GLEW_ARB_half_float_vertex; + continue; + } +#endif +#ifdef GL_ARB_imaging + if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7)) + { + ret = GLEW_ARB_imaging; + continue; + } +#endif +#ifdef GL_ARB_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_ARB_instanced_arrays; + continue; + } +#endif +#ifdef GL_ARB_map_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16)) + { + ret = GLEW_ARB_map_buffer_range; + continue; + } +#endif +#ifdef GL_ARB_matrix_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14)) + { + ret = GLEW_ARB_matrix_palette; + continue; + } +#endif +#ifdef GL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_ARB_multisample; + continue; + } +#endif +#ifdef GL_ARB_multitexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) + { + ret = GLEW_ARB_multitexture; + continue; + } +#endif +#ifdef GL_ARB_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_ARB_occlusion_query; + continue; + } +#endif +#ifdef GL_ARB_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_ARB_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_ARB_point_parameters; + continue; + } +#endif +#ifdef GL_ARB_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_ARB_point_sprite; + continue; + } +#endif +#ifdef GL_ARB_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14)) + { + ret = GLEW_ARB_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shading_language_100 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20)) + { + ret = GLEW_ARB_shading_language_100; + continue; + } +#endif +#ifdef GL_ARB_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_ARB_shadow; + continue; + } +#endif +#ifdef GL_ARB_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_ARB_shadow_ambient; + continue; + } +#endif +#ifdef GL_ARB_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_ARB_texture_border_clamp; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_ARB_texture_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_texture_compression + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19)) + { + ret = GLEW_ARB_texture_compression; + continue; + } +#endif +#ifdef GL_ARB_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_ARB_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_ARB_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_ARB_texture_cube_map; + continue; + } +#endif +#ifdef GL_ARB_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_ARB_texture_env_add; + continue; + } +#endif +#ifdef GL_ARB_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_ARB_texture_env_combine; + continue; + } +#endif +#ifdef GL_ARB_texture_env_crossbar + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20)) + { + ret = GLEW_ARB_texture_env_crossbar; + continue; + } +#endif +#ifdef GL_ARB_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_ARB_texture_env_dot3; + continue; + } +#endif +#ifdef GL_ARB_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ARB_texture_float; + continue; + } +#endif +#ifdef GL_ARB_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_ARB_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_ARB_texture_non_power_of_two + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24)) + { + ret = GLEW_ARB_texture_non_power_of_two; + continue; + } +#endif +#ifdef GL_ARB_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_ARB_texture_rectangle; + continue; + } +#endif +#ifdef GL_ARB_texture_rg + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10)) + { + ret = GLEW_ARB_texture_rg; + continue; + } +#endif +#ifdef GL_ARB_transpose_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16)) + { + ret = GLEW_ARB_transpose_matrix; + continue; + } +#endif +#ifdef GL_ARB_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ARB_vertex_array_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12)) + { + ret = GLEW_ARB_vertex_blend; + continue; + } +#endif +#ifdef GL_ARB_vertex_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) + { + ret = GLEW_ARB_vertex_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_ARB_vertex_program; + continue; + } +#endif +#ifdef GL_ARB_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_ARB_vertex_shader; + continue; + } +#endif +#ifdef GL_ARB_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_ARB_window_pos; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5)) + { +#ifdef GL_ATIX_point_sprites + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13)) + { + ret = GLEW_ATIX_point_sprites; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATIX_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_route + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17)) + { + ret = GLEW_ATIX_texture_env_route; + continue; + } +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31)) + { + ret = GLEW_ATIX_vertex_shader_output_point_size; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GL_ATI_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ATI_draw_buffers; + continue; + } +#endif +#ifdef GL_ATI_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_ATI_element_array; + continue; + } +#endif +#ifdef GL_ATI_envmap_bumpmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14)) + { + ret = GLEW_ATI_envmap_bumpmap; + continue; + } +#endif +#ifdef GL_ATI_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ATI_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_map_object_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17)) + { + ret = GLEW_ATI_map_object_buffer; + continue; + } +#endif +#ifdef GL_ATI_pn_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12)) + { + ret = GLEW_ATI_pn_triangles; + continue; + } +#endif +#ifdef GL_ATI_separate_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16)) + { + ret = GLEW_ATI_separate_stencil; + continue; + } +#endif +#ifdef GL_ATI_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_ATI_shader_texture_lod; + continue; + } +#endif +#ifdef GL_ATI_text_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20)) + { + ret = GLEW_ATI_text_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_texture_compression_3dc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23)) + { + ret = GLEW_ATI_texture_compression_3dc; + continue; + } +#endif +#ifdef GL_ATI_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATI_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATI_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ATI_texture_float; + continue; + } +#endif +#ifdef GL_ATI_texture_mirror_once + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19)) + { + ret = GLEW_ATI_texture_mirror_once; + continue; + } +#endif +#ifdef GL_ATI_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ATI_vertex_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_attrib_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26)) + { + ret = GLEW_ATI_vertex_attrib_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_streams + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14)) + { + ret = GLEW_ATI_vertex_streams; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GL_EXT_422_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10)) + { + ret = GLEW_EXT_422_pixels; + continue; + } +#endif +#ifdef GL_EXT_Cg_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9)) + { + ret = GLEW_EXT_Cg_shader; + continue; + } +#endif +#ifdef GL_EXT_abgr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4)) + { + ret = GLEW_EXT_abgr; + continue; + } +#endif +#ifdef GL_EXT_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4)) + { + ret = GLEW_EXT_bgra; + continue; + } +#endif +#ifdef GL_EXT_bindable_uniform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16)) + { + ret = GLEW_EXT_bindable_uniform; + continue; + } +#endif +#ifdef GL_EXT_blend_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11)) + { + ret = GLEW_EXT_blend_color; + continue; + } +#endif +#ifdef GL_EXT_blend_equation_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23)) + { + ret = GLEW_EXT_blend_equation_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_func_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19)) + { + ret = GLEW_EXT_blend_func_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_logic_op + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14)) + { + ret = GLEW_EXT_blend_logic_op; + continue; + } +#endif +#ifdef GL_EXT_blend_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12)) + { + ret = GLEW_EXT_blend_minmax; + continue; + } +#endif +#ifdef GL_EXT_blend_subtract + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14)) + { + ret = GLEW_EXT_blend_subtract; + continue; + } +#endif +#ifdef GL_EXT_clip_volume_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16)) + { + ret = GLEW_EXT_clip_volume_hint; + continue; + } +#endif +#ifdef GL_EXT_cmyka + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5)) + { + ret = GLEW_EXT_cmyka; + continue; + } +#endif +#ifdef GL_EXT_color_subtable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14)) + { + ret = GLEW_EXT_color_subtable; + continue; + } +#endif +#ifdef GL_EXT_compiled_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21)) + { + ret = GLEW_EXT_compiled_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_convolution + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11)) + { + ret = GLEW_EXT_convolution; + continue; + } +#endif +#ifdef GL_EXT_coordinate_frame + if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16)) + { + ret = GLEW_EXT_coordinate_frame; + continue; + } +#endif +#ifdef GL_EXT_copy_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12)) + { + ret = GLEW_EXT_copy_texture; + continue; + } +#endif +#ifdef GL_EXT_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_EXT_cull_vertex; + continue; + } +#endif +#ifdef GL_EXT_depth_bounds_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17)) + { + ret = GLEW_EXT_depth_bounds_test; + continue; + } +#endif +#ifdef GL_EXT_direct_state_access + if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19)) + { + ret = GLEW_EXT_direct_state_access; + continue; + } +#endif +#ifdef GL_EXT_draw_buffers2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13)) + { + ret = GLEW_EXT_draw_buffers2; + continue; + } +#endif +#ifdef GL_EXT_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_EXT_draw_instanced; + continue; + } +#endif +#ifdef GL_EXT_draw_range_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19)) + { + ret = GLEW_EXT_draw_range_elements; + continue; + } +#endif +#ifdef GL_EXT_fog_coord + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9)) + { + ret = GLEW_EXT_fog_coord; + continue; + } +#endif +#ifdef GL_EXT_fragment_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17)) + { + ret = GLEW_EXT_fragment_lighting; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_EXT_framebuffer_blit; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_EXT_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_EXT_framebuffer_object; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_EXT_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_EXT_geometry_shader4; + continue; + } +#endif +#ifdef GL_EXT_gpu_program_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22)) + { + ret = GLEW_EXT_gpu_program_parameters; + continue; + } +#endif +#ifdef GL_EXT_gpu_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11)) + { + ret = GLEW_EXT_gpu_shader4; + continue; + } +#endif +#ifdef GL_EXT_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9)) + { + ret = GLEW_EXT_histogram; + continue; + } +#endif +#ifdef GL_EXT_index_array_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19)) + { + ret = GLEW_EXT_index_array_formats; + continue; + } +#endif +#ifdef GL_EXT_index_func + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10)) + { + ret = GLEW_EXT_index_func; + continue; + } +#endif +#ifdef GL_EXT_index_material + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14)) + { + ret = GLEW_EXT_index_material; + continue; + } +#endif +#ifdef GL_EXT_index_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13)) + { + ret = GLEW_EXT_index_texture; + continue; + } +#endif +#ifdef GL_EXT_light_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13)) + { + ret = GLEW_EXT_light_texture; + continue; + } +#endif +#ifdef GL_EXT_misc_attribute + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14)) + { + ret = GLEW_EXT_misc_attribute; + continue; + } +#endif +#ifdef GL_EXT_multi_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17)) + { + ret = GLEW_EXT_multi_draw_arrays; + continue; + } +#endif +#ifdef GL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_EXT_multisample; + continue; + } +#endif +#ifdef GL_EXT_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_EXT_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_EXT_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12)) + { + ret = GLEW_EXT_packed_float; + continue; + } +#endif +#ifdef GL_EXT_packed_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13)) + { + ret = GLEW_EXT_packed_pixels; + continue; + } +#endif +#ifdef GL_EXT_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16)) + { + ret = GLEW_EXT_paletted_texture; + continue; + } +#endif +#ifdef GL_EXT_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_EXT_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15)) + { + ret = GLEW_EXT_pixel_transform; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27)) + { + ret = GLEW_EXT_pixel_transform_color_table; + continue; + } +#endif +#ifdef GL_EXT_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_EXT_point_parameters; + continue; + } +#endif +#ifdef GL_EXT_polygon_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14)) + { + ret = GLEW_EXT_polygon_offset; + continue; + } +#endif +#ifdef GL_EXT_rescale_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14)) + { + ret = GLEW_EXT_rescale_normal; + continue; + } +#endif +#ifdef GL_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GL_EXT_secondary_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15)) + { + ret = GLEW_EXT_secondary_color; + continue; + } +#endif +#ifdef GL_EXT_separate_specular_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23)) + { + ret = GLEW_EXT_separate_specular_color; + continue; + } +#endif +#ifdef GL_EXT_shadow_funcs + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12)) + { + ret = GLEW_EXT_shadow_funcs; + continue; + } +#endif +#ifdef GL_EXT_shared_texture_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22)) + { + ret = GLEW_EXT_shared_texture_palette; + continue; + } +#endif +#ifdef GL_EXT_stencil_clear_tag + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17)) + { + ret = GLEW_EXT_stencil_clear_tag; + continue; + } +#endif +#ifdef GL_EXT_stencil_two_side + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16)) + { + ret = GLEW_EXT_stencil_two_side; + continue; + } +#endif +#ifdef GL_EXT_stencil_wrap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12)) + { + ret = GLEW_EXT_stencil_wrap; + continue; + } +#endif +#ifdef GL_EXT_subtexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10)) + { + ret = GLEW_EXT_subtexture; + continue; + } +#endif +#ifdef GL_EXT_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7)) + { + ret = GLEW_EXT_texture; + continue; + } +#endif +#ifdef GL_EXT_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9)) + { + ret = GLEW_EXT_texture3D; + continue; + } +#endif +#ifdef GL_EXT_texture_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13)) + { + ret = GLEW_EXT_texture_array; + continue; + } +#endif +#ifdef GL_EXT_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_EXT_texture_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_EXT_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_latc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24)) + { + ret = GLEW_EXT_texture_compression_latc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_EXT_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) + { + ret = GLEW_EXT_texture_compression_s3tc; + continue; + } +#endif +#ifdef GL_EXT_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_EXT_texture_cube_map; + continue; + } +#endif +#ifdef GL_EXT_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_EXT_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11)) + { + ret = GLEW_EXT_texture_env; + continue; + } +#endif +#ifdef GL_EXT_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_EXT_texture_env_add; + continue; + } +#endif +#ifdef GL_EXT_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_EXT_texture_env_combine; + continue; + } +#endif +#ifdef GL_EXT_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_EXT_texture_env_dot3; + continue; + } +#endif +#ifdef GL_EXT_texture_filter_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) + { + ret = GLEW_EXT_texture_filter_anisotropic; + continue; + } +#endif +#ifdef GL_EXT_texture_integer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15)) + { + ret = GLEW_EXT_texture_integer; + continue; + } +#endif +#ifdef GL_EXT_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_EXT_texture_lod_bias; + continue; + } +#endif +#ifdef GL_EXT_texture_mirror_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20)) + { + ret = GLEW_EXT_texture_mirror_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14)) + { + ret = GLEW_EXT_texture_object; + continue; + } +#endif +#ifdef GL_EXT_texture_perturb_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22)) + { + ret = GLEW_EXT_texture_perturb_normal; + continue; + } +#endif +#ifdef GL_EXT_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_EXT_texture_rectangle; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12)) + { + ret = GLEW_EXT_texture_sRGB; + continue; + } +#endif +#ifdef GL_EXT_texture_shared_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23)) + { + ret = GLEW_EXT_texture_shared_exponent; + continue; + } +#endif +#ifdef GL_EXT_texture_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) + { + ret = GLEW_EXT_texture_swizzle; + continue; + } +#endif +#ifdef GL_EXT_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_EXT_timer_query; + continue; + } +#endif +#ifdef GL_EXT_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_EXT_transform_feedback; + continue; + } +#endif +#ifdef GL_EXT_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12)) + { + ret = GLEW_EXT_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_vertex_array_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) + { + ret = GLEW_EXT_vertex_array_bgra; + continue; + } +#endif +#ifdef GL_EXT_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_EXT_vertex_shader; + continue; + } +#endif +#ifdef GL_EXT_vertex_weighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16)) + { + ret = GLEW_EXT_vertex_weighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8)) + { +#ifdef GL_GREMEDY_frame_terminator + if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16)) + { + ret = GLEW_GREMEDY_frame_terminator; + continue; + } +#endif +#ifdef GL_GREMEDY_string_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13)) + { + ret = GLEW_GREMEDY_string_marker; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3)) + { +#ifdef GL_HP_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_HP_convolution_border_modes; + continue; + } +#endif +#ifdef GL_HP_image_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15)) + { + ret = GLEW_HP_image_transform; + continue; + } +#endif +#ifdef GL_HP_occlusion_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14)) + { + ret = GLEW_HP_occlusion_test; + continue; + } +#endif +#ifdef GL_HP_texture_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16)) + { + ret = GLEW_HP_texture_lighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4)) + { +#ifdef GL_IBM_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_IBM_cull_vertex; + continue; + } +#endif +#ifdef GL_IBM_multimode_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21)) + { + ret = GLEW_IBM_multimode_draw_arrays; + continue; + } +#endif +#ifdef GL_IBM_rasterpos_clip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14)) + { + ret = GLEW_IBM_rasterpos_clip; + continue; + } +#endif +#ifdef GL_IBM_static_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11)) + { + ret = GLEW_IBM_static_data; + continue; + } +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_IBM_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_IBM_vertex_array_lists + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18)) + { + ret = GLEW_IBM_vertex_array_lists; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5)) + { +#ifdef GL_INGR_color_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11)) + { + ret = GLEW_INGR_color_clamp; + continue; + } +#endif +#ifdef GL_INGR_interlace_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14)) + { + ret = GLEW_INGR_interlace_read; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6)) + { +#ifdef GL_INTEL_parallel_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) + { + ret = GLEW_INTEL_parallel_arrays; + continue; + } +#endif +#ifdef GL_INTEL_texture_scissor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15)) + { + ret = GLEW_INTEL_texture_scissor; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4)) + { +#ifdef GL_KTX_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = GLEW_KTX_buffer_region; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6)) + { +#ifdef GL_MESAX_texture_stack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13)) + { + ret = GLEW_MESAX_texture_stack; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GL_MESA_pack_invert + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11)) + { + ret = GLEW_MESA_pack_invert; + continue; + } +#endif +#ifdef GL_MESA_resize_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14)) + { + ret = GLEW_MESA_resize_buffers; + continue; + } +#endif +#ifdef GL_MESA_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_MESA_window_pos; + continue; + } +#endif +#ifdef GL_MESA_ycbcr_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13)) + { + ret = GLEW_MESA_ycbcr_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GL_NV_blend_square + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) + { + ret = GLEW_NV_blend_square; + continue; + } +#endif +#ifdef GL_NV_conditional_render + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) + { + ret = GLEW_NV_conditional_render; + continue; + } +#endif +#ifdef GL_NV_copy_depth_to_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19)) + { + ret = GLEW_NV_copy_depth_to_color; + continue; + } +#endif +#ifdef GL_NV_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_NV_depth_buffer_float; + continue; + } +#endif +#ifdef GL_NV_depth_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_NV_depth_clamp; + continue; + } +#endif +#ifdef GL_NV_depth_range_unclamped + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21)) + { + ret = GLEW_NV_depth_range_unclamped; + continue; + } +#endif +#ifdef GL_NV_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10)) + { + ret = GLEW_NV_evaluators; + continue; + } +#endif +#ifdef GL_NV_explicit_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20)) + { + ret = GLEW_NV_explicit_multisample; + continue; + } +#endif +#ifdef GL_NV_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_NV_fence; + continue; + } +#endif +#ifdef GL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLEW_NV_float_buffer; + continue; + } +#endif +#ifdef GL_NV_fog_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12)) + { + ret = GLEW_NV_fog_distance; + continue; + } +#endif +#ifdef GL_NV_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_NV_fragment_program; + continue; + } +#endif +#ifdef GL_NV_fragment_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17)) + { + ret = GLEW_NV_fragment_program2; + continue; + } +#endif +#ifdef GL_NV_fragment_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17)) + { + ret = GLEW_NV_fragment_program4; + continue; + } +#endif +#ifdef GL_NV_fragment_program_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23)) + { + ret = GLEW_NV_fragment_program_option; + continue; + } +#endif +#ifdef GL_NV_framebuffer_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32)) + { + ret = GLEW_NV_framebuffer_multisample_coverage; + continue; + } +#endif +#ifdef GL_NV_geometry_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17)) + { + ret = GLEW_NV_geometry_program4; + continue; + } +#endif +#ifdef GL_NV_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_NV_geometry_shader4; + continue; + } +#endif +#ifdef GL_NV_gpu_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12)) + { + ret = GLEW_NV_gpu_program4; + continue; + } +#endif +#ifdef GL_NV_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10)) + { + ret = GLEW_NV_half_float; + continue; + } +#endif +#ifdef GL_NV_light_max_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18)) + { + ret = GLEW_NV_light_max_exponent; + continue; + } +#endif +#ifdef GL_NV_multisample_filter_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23)) + { + ret = GLEW_NV_multisample_filter_hint; + continue; + } +#endif +#ifdef GL_NV_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_NV_occlusion_query; + continue; + } +#endif +#ifdef GL_NV_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_NV_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_NV_parameter_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23)) + { + ret = GLEW_NV_parameter_buffer_object; + continue; + } +#endif +#ifdef GL_NV_pixel_data_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16)) + { + ret = GLEW_NV_pixel_data_range; + continue; + } +#endif +#ifdef GL_NV_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_NV_point_sprite; + continue; + } +#endif +#ifdef GL_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = GLEW_NV_present_video; + continue; + } +#endif +#ifdef GL_NV_primitive_restart + if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17)) + { + ret = GLEW_NV_primitive_restart; + continue; + } +#endif +#ifdef GL_NV_register_combiners + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18)) + { + ret = GLEW_NV_register_combiners; + continue; + } +#endif +#ifdef GL_NV_register_combiners2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19)) + { + ret = GLEW_NV_register_combiners2; + continue; + } +#endif +#ifdef GL_NV_texgen_emboss + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13)) + { + ret = GLEW_NV_texgen_emboss; + continue; + } +#endif +#ifdef GL_NV_texgen_reflection + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17)) + { + ret = GLEW_NV_texgen_reflection; + continue; + } +#endif +#ifdef GL_NV_texture_compression_vtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23)) + { + ret = GLEW_NV_texture_compression_vtc; + continue; + } +#endif +#ifdef GL_NV_texture_env_combine4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20)) + { + ret = GLEW_NV_texture_env_combine4; + continue; + } +#endif +#ifdef GL_NV_texture_expand_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21)) + { + ret = GLEW_NV_texture_expand_normal; + continue; + } +#endif +#ifdef GL_NV_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_NV_texture_rectangle; + continue; + } +#endif +#ifdef GL_NV_texture_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14)) + { + ret = GLEW_NV_texture_shader; + continue; + } +#endif +#ifdef GL_NV_texture_shader2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15)) + { + ret = GLEW_NV_texture_shader2; + continue; + } +#endif +#ifdef GL_NV_texture_shader3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15)) + { + ret = GLEW_NV_texture_shader3; + continue; + } +#endif +#ifdef GL_NV_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_NV_transform_feedback; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19)) + { + ret = GLEW_NV_vertex_array_range2; + continue; + } +#endif +#ifdef GL_NV_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_NV_vertex_program; + continue; + } +#endif +#ifdef GL_NV_vertex_program1_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17)) + { + ret = GLEW_NV_vertex_program1_1; + continue; + } +#endif +#ifdef GL_NV_vertex_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15)) + { + ret = GLEW_NV_vertex_program2; + continue; + } +#endif +#ifdef GL_NV_vertex_program2_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22)) + { + ret = GLEW_NV_vertex_program2_option; + continue; + } +#endif +#ifdef GL_NV_vertex_program3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15)) + { + ret = GLEW_NV_vertex_program3; + continue; + } +#endif +#ifdef GL_NV_vertex_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15)) + { + ret = GLEW_NV_vertex_program4; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4)) + { +#ifdef GL_OES_byte_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16)) + { + ret = GLEW_OES_byte_coordinates; + continue; + } +#endif +#ifdef GL_OES_compressed_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_paletted_texture", 27)) + { + ret = GLEW_OES_compressed_paletted_texture; + continue; + } +#endif +#ifdef GL_OES_read_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format", 11)) + { + ret = GLEW_OES_read_format; + continue; + } +#endif +#ifdef GL_OES_single_precision + if (_glewStrSame3(&pos, &len, (const GLubyte*)"single_precision", 16)) + { + ret = GLEW_OES_single_precision; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GL_OML_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_OML_interlace; + continue; + } +#endif +#ifdef GL_OML_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_OML_resample; + continue; + } +#endif +#ifdef GL_OML_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) + { + ret = GLEW_OML_subsample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4)) + { +#ifdef GL_PGI_misc_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10)) + { + ret = GLEW_PGI_misc_hints; + continue; + } +#endif +#ifdef GL_PGI_vertex_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12)) + { + ret = GLEW_PGI_vertex_hints; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5)) + { +#ifdef GL_REND_screen_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18)) + { + ret = GLEW_REND_screen_coordinates; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3)) + { +#ifdef GL_S3_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4)) + { + ret = GLEW_S3_s3tc; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GL_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLEW_SGIS_color_range; + continue; + } +#endif +#ifdef GL_SGIS_detail_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14)) + { + ret = GLEW_SGIS_detail_texture; + continue; + } +#endif +#ifdef GL_SGIS_fog_function + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12)) + { + ret = GLEW_SGIS_fog_function; + continue; + } +#endif +#ifdef GL_SGIS_generate_mipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15)) + { + ret = GLEW_SGIS_generate_mipmap; + continue; + } +#endif +#ifdef GL_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_SGIS_multisample; + continue; + } +#endif +#ifdef GL_SGIS_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIS_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIS_point_line_texgen + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17)) + { + ret = GLEW_SGIS_point_line_texgen; + continue; + } +#endif +#ifdef GL_SGIS_sharpen_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15)) + { + ret = GLEW_SGIS_sharpen_texture; + continue; + } +#endif +#ifdef GL_SGIS_texture4D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9)) + { + ret = GLEW_SGIS_texture4D; + continue; + } +#endif +#ifdef GL_SGIS_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_SGIS_texture_border_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_SGIS_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_filter4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15)) + { + ret = GLEW_SGIS_texture_filter4; + continue; + } +#endif +#ifdef GL_SGIS_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11)) + { + ret = GLEW_SGIS_texture_lod; + continue; + } +#endif +#ifdef GL_SGIS_texture_select + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14)) + { + ret = GLEW_SGIS_texture_select; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GL_SGIX_async + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5)) + { + ret = GLEW_SGIX_async; + continue; + } +#endif +#ifdef GL_SGIX_async_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15)) + { + ret = GLEW_SGIX_async_histogram; + continue; + } +#endif +#ifdef GL_SGIX_async_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11)) + { + ret = GLEW_SGIX_async_pixel; + continue; + } +#endif +#ifdef GL_SGIX_blend_alpha_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18)) + { + ret = GLEW_SGIX_blend_alpha_minmax; + continue; + } +#endif +#ifdef GL_SGIX_clipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7)) + { + ret = GLEW_SGIX_clipmap; + continue; + } +#endif +#ifdef GL_SGIX_convolution_accuracy + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20)) + { + ret = GLEW_SGIX_convolution_accuracy; + continue; + } +#endif +#ifdef GL_SGIX_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_SGIX_depth_texture; + continue; + } +#endif +#ifdef GL_SGIX_flush_raster + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12)) + { + ret = GLEW_SGIX_flush_raster; + continue; + } +#endif +#ifdef GL_SGIX_fog_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10)) + { + ret = GLEW_SGIX_fog_offset; + continue; + } +#endif +#ifdef GL_SGIX_fog_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11)) + { + ret = GLEW_SGIX_fog_texture; + continue; + } +#endif +#ifdef GL_SGIX_fragment_specular_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26)) + { + ret = GLEW_SGIX_fragment_specular_lighting; + continue; + } +#endif +#ifdef GL_SGIX_framezoom + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9)) + { + ret = GLEW_SGIX_framezoom; + continue; + } +#endif +#ifdef GL_SGIX_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_SGIX_interlace; + continue; + } +#endif +#ifdef GL_SGIX_ir_instrument1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14)) + { + ret = GLEW_SGIX_ir_instrument1; + continue; + } +#endif +#ifdef GL_SGIX_list_priority + if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13)) + { + ret = GLEW_SGIX_list_priority; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIX_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture_bits + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18)) + { + ret = GLEW_SGIX_pixel_texture_bits; + continue; + } +#endif +#ifdef GL_SGIX_reference_plane + if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15)) + { + ret = GLEW_SGIX_reference_plane; + continue; + } +#endif +#ifdef GL_SGIX_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_SGIX_resample; + continue; + } +#endif +#ifdef GL_SGIX_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_SGIX_shadow; + continue; + } +#endif +#ifdef GL_SGIX_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_SGIX_shadow_ambient; + continue; + } +#endif +#ifdef GL_SGIX_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6)) + { + ret = GLEW_SGIX_sprite; + continue; + } +#endif +#ifdef GL_SGIX_tag_sample_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17)) + { + ret = GLEW_SGIX_tag_sample_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_add_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15)) + { + ret = GLEW_SGIX_texture_add_env; + continue; + } +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24)) + { + ret = GLEW_SGIX_texture_coordinate_clamp; + continue; + } +#endif +#ifdef GL_SGIX_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_SGIX_texture_lod_bias; + continue; + } +#endif +#ifdef GL_SGIX_texture_multi_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20)) + { + ret = GLEW_SGIX_texture_multi_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_SGIX_texture_range; + continue; + } +#endif +#ifdef GL_SGIX_texture_scale_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18)) + { + ret = GLEW_SGIX_texture_scale_bias; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14)) + { + ret = GLEW_SGIX_vertex_preclip; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19)) + { + ret = GLEW_SGIX_vertex_preclip_hint; + continue; + } +#endif +#ifdef GL_SGIX_ycrcb + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5)) + { + ret = GLEW_SGIX_ycrcb; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GL_SGI_color_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12)) + { + ret = GLEW_SGI_color_matrix; + continue; + } +#endif +#ifdef GL_SGI_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11)) + { + ret = GLEW_SGI_color_table; + continue; + } +#endif +#ifdef GL_SGI_texture_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19)) + { + ret = GLEW_SGI_texture_color_table; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5)) + { +#ifdef GL_SUNX_constant_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13)) + { + ret = GLEW_SUNX_constant_data; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GL_SUN_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_SUN_convolution_border_modes; + continue; + } +#endif +#ifdef GL_SUN_global_alpha + if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12)) + { + ret = GLEW_SUN_global_alpha; + continue; + } +#endif +#ifdef GL_SUN_mesh_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10)) + { + ret = GLEW_SUN_mesh_array; + continue; + } +#endif +#ifdef GL_SUN_read_video_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17)) + { + ret = GLEW_SUN_read_video_pixels; + continue; + } +#endif +#ifdef GL_SUN_slice_accum + if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11)) + { + ret = GLEW_SUN_slice_accum; + continue; + } +#endif +#ifdef GL_SUN_triangle_list + if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13)) + { + ret = GLEW_SUN_triangle_list; + continue; + } +#endif +#ifdef GL_SUN_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6)) + { + ret = GLEW_SUN_vertex; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4)) + { +#ifdef GL_WIN_phong_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13)) + { + ret = GLEW_WIN_phong_shading; + continue; + } +#endif +#ifdef GL_WIN_specular_fog + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12)) + { + ret = GLEW_WIN_specular_fog; + continue; + } +#endif +#ifdef GL_WIN_swap_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9)) + { + ret = GLEW_WIN_swap_hint; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#if defined(_WIN32) + +#if defined(GLEW_MX) +GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name) +#else +GLboolean wglewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef WGL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4)) + { +#ifdef WGL_3DL_stereo_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14)) + { + ret = WGLEW_3DL_stereo_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef WGL_ARB_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = WGLEW_ARB_buffer_region; + continue; + } +#endif +#ifdef WGL_ARB_create_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) + { + ret = WGLEW_ARB_create_context; + continue; + } +#endif +#ifdef WGL_ARB_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_ARB_extensions_string; + continue; + } +#endif +#ifdef WGL_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = WGLEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef WGL_ARB_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_ARB_make_current_read; + continue; + } +#endif +#ifdef WGL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_ARB_multisample; + continue; + } +#endif +#ifdef WGL_ARB_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_ARB_pbuffer; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_ARB_pixel_format; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ARB_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ARB_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = WGLEW_ARB_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef WGL_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ATI_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_ATI_render_texture_rectangle; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef WGL_EXT_depth_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11)) + { + ret = WGLEW_EXT_depth_float; + continue; + } +#endif +#ifdef WGL_EXT_display_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19)) + { + ret = WGLEW_EXT_display_color_table; + continue; + } +#endif +#ifdef WGL_EXT_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_EXT_extensions_string; + continue; + } +#endif +#ifdef WGL_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = WGLEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef WGL_EXT_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_EXT_make_current_read; + continue; + } +#endif +#ifdef WGL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_EXT_multisample; + continue; + } +#endif +#ifdef WGL_EXT_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_EXT_pbuffer; + continue; + } +#endif +#ifdef WGL_EXT_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_EXT_pixel_format; + continue; + } +#endif +#ifdef WGL_EXT_pixel_format_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_packed_float", 25)) + { + ret = WGLEW_EXT_pixel_format_packed_float; + continue; + } +#endif +#ifdef WGL_EXT_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = WGLEW_EXT_swap_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4)) + { +#ifdef WGL_I3D_digital_video_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21)) + { + ret = WGLEW_I3D_digital_video_control; + continue; + } +#endif +#ifdef WGL_I3D_gamma + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5)) + { + ret = WGLEW_I3D_gamma; + continue; + } +#endif +#ifdef WGL_I3D_genlock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7)) + { + ret = WGLEW_I3D_genlock; + continue; + } +#endif +#ifdef WGL_I3D_image_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12)) + { + ret = WGLEW_I3D_image_buffer; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_lock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15)) + { + ret = WGLEW_I3D_swap_frame_lock; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_usage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16)) + { + ret = WGLEW_I3D_swap_frame_usage; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef WGL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = WGLEW_NV_float_buffer; + continue; + } +#endif +#ifdef WGL_NV_gpu_affinity + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_affinity", 12)) + { + ret = WGLEW_NV_gpu_affinity; + continue; + } +#endif +#ifdef WGL_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = WGLEW_NV_present_video; + continue; + } +#endif +#ifdef WGL_NV_render_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20)) + { + ret = WGLEW_NV_render_depth_texture; + continue; + } +#endif +#ifdef WGL_NV_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_NV_render_texture_rectangle; + continue; + } +#endif +#ifdef WGL_NV_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = WGLEW_NV_swap_group; + continue; + } +#endif +#ifdef WGL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = WGLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef WGL_NV_video_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) + { + ret = WGLEW_NV_video_output; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef WGL_OML_sync_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = WGLEW_OML_sync_control; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +#if defined(GLEW_MX) +GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name) +#else +GLboolean glxewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GLX_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLXEW_VERSION_1_2; + continue; + } +#endif +#ifdef GLX_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLXEW_VERSION_1_3; + continue; + } +#endif +#ifdef GLX_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLXEW_VERSION_1_4; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GLX_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GLX_ARB_create_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) + { + ret = GLXEW_ARB_create_context; + continue; + } +#endif +#ifdef GLX_ARB_fbconfig_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14)) + { + ret = GLXEW_ARB_fbconfig_float; + continue; + } +#endif +#ifdef GLX_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLXEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef GLX_ARB_get_proc_address + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16)) + { + ret = GLXEW_ARB_get_proc_address; + continue; + } +#endif +#ifdef GLX_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_ARB_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GLX_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = GLXEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef GLX_ATI_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = GLXEW_ATI_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GLX_EXT_fbconfig_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_packed_float", 21)) + { + ret = GLXEW_EXT_fbconfig_packed_float; + continue; + } +#endif +#ifdef GLX_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLXEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef GLX_EXT_import_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14)) + { + ret = GLXEW_EXT_import_context; + continue; + } +#endif +#ifdef GLX_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLXEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GLX_EXT_texture_from_pixmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19)) + { + ret = GLXEW_EXT_texture_from_pixmap; + continue; + } +#endif +#ifdef GLX_EXT_visual_info + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11)) + { + ret = GLXEW_EXT_visual_info; + continue; + } +#endif +#ifdef GLX_EXT_visual_rating + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13)) + { + ret = GLXEW_EXT_visual_rating; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GLX_MESA_agp_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10)) + { + ret = GLXEW_MESA_agp_offset; + continue; + } +#endif +#ifdef GLX_MESA_copy_sub_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15)) + { + ret = GLXEW_MESA_copy_sub_buffer; + continue; + } +#endif +#ifdef GLX_MESA_pixmap_colormap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15)) + { + ret = GLXEW_MESA_pixmap_colormap; + continue; + } +#endif +#ifdef GLX_MESA_release_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15)) + { + ret = GLXEW_MESA_release_buffers; + continue; + } +#endif +#ifdef GLX_MESA_set_3dfx_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13)) + { + ret = GLXEW_MESA_set_3dfx_mode; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GLX_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLXEW_NV_float_buffer; + continue; + } +#endif +#ifdef GLX_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = GLXEW_NV_present_video; + continue; + } +#endif +#ifdef GLX_NV_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = GLXEW_NV_swap_group; + continue; + } +#endif +#ifdef GLX_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLXEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GLX_NV_video_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) + { + ret = GLXEW_NV_video_output; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GLX_OML_swap_method + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11)) + { + ret = GLXEW_OML_swap_method; + continue; + } +#endif +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = GLXEW_OML_sync_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GLX_SGIS_blended_overlay + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15)) + { + ret = GLXEW_SGIS_blended_overlay; + continue; + } +#endif +#ifdef GLX_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLXEW_SGIS_color_range; + continue; + } +#endif +#ifdef GLX_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_SGIS_multisample; + continue; + } +#endif +#ifdef GLX_SGIS_shared_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18)) + { + ret = GLXEW_SGIS_shared_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GLX_SGIX_fbconfig + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8)) + { + ret = GLXEW_SGIX_fbconfig; + continue; + } +#endif +#ifdef GLX_SGIX_hyperpipe + if (_glewStrSame3(&pos, &len, (const GLubyte*)"hyperpipe", 9)) + { + ret = GLXEW_SGIX_hyperpipe; + continue; + } +#endif +#ifdef GLX_SGIX_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = GLXEW_SGIX_pbuffer; + continue; + } +#endif +#ifdef GLX_SGIX_swap_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12)) + { + ret = GLXEW_SGIX_swap_barrier; + continue; + } +#endif +#ifdef GLX_SGIX_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = GLXEW_SGIX_swap_group; + continue; + } +#endif +#ifdef GLX_SGIX_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SGIX_video_resize; + continue; + } +#endif +#ifdef GLX_SGIX_visual_select_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19)) + { + ret = GLXEW_SGIX_visual_select_group; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GLX_SGI_cushion + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7)) + { + ret = GLXEW_SGI_cushion; + continue; + } +#endif +#ifdef GLX_SGI_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = GLXEW_SGI_make_current_read; + continue; + } +#endif +#ifdef GLX_SGI_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = GLXEW_SGI_swap_control; + continue; + } +#endif +#ifdef GLX_SGI_video_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10)) + { + ret = GLXEW_SGI_video_sync; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GLX_SUN_get_transparent_index + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21)) + { + ret = GLXEW_SUN_get_transparent_index; + continue; + } +#endif +#ifdef GLX_SUN_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SUN_video_resize; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#endif /* _WIN32 */ diff --git a/WDL/lice/glew/src/glewinfo.c b/WDL/lice/glew/src/glewinfo.c new file mode 100644 index 00000000..42e7173b --- /dev/null +++ b/WDL/lice/glew/src/glewinfo.c @@ -0,0 +1,7180 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#if defined(_WIN32) +#include +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +#include +#endif + +static FILE* f; + +#ifdef GLEW_MX +GLEWContext _glewctx; +#define glewGetContext() (&_glewctx) +#ifdef _WIN32 +WGLEWContext _wglewctx; +#define wglewGetContext() (&_wglewctx) +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +GLXEWContext _glxewctx; +#define glxewGetContext() (&_glxewctx) +#endif +#endif + +#if defined(_WIN32) +GLboolean glewCreateContext (int* pixelformat); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +GLboolean glewCreateContext (const char* display, int* visual); +#else +GLboolean glewCreateContext (); +#endif + +#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +GLboolean glewParseArgs (int argc, char** argv, char** display, int* visual); +#endif + +void glewDestroyContext (); + +/* ------------------------------------------------------------------------- */ + +static void glewPrintExt (const char* name, GLboolean def1, GLboolean def2, GLboolean def3) +{ + unsigned int i; + fprintf(f, "\n%s:", name); + for (i=0; i<62-strlen(name); i++) fprintf(f, " "); + fprintf(f, "%s ", def1 ? "OK" : "MISSING"); + if (def1 != def2) + fprintf(f, "[%s] ", def2 ? "OK" : "MISSING"); + if (def1 != def3) + fprintf(f, "[%s]\n", def3 ? "OK" : "MISSING"); + else + fprintf(f, "\n"); + for (i=0; i= 199901L) +#include + +static void _glewInfo_GLX_OML_sync_control (void) +{ + glewPrintExt("GLX_OML_sync_control", GLXEW_OML_sync_control, glxewIsSupported("GLX_OML_sync_control"), glxewGetExtension("GLX_OML_sync_control")); + + glewInfoFunc("glXGetMscRateOML", glXGetMscRateOML == NULL); + glewInfoFunc("glXGetSyncValuesOML", glXGetSyncValuesOML == NULL); + glewInfoFunc("glXSwapBuffersMscOML", glXSwapBuffersMscOML == NULL); + glewInfoFunc("glXWaitForMscOML", glXWaitForMscOML == NULL); + glewInfoFunc("glXWaitForSbcOML", glXWaitForSbcOML == NULL); +} + +#endif /* GLX_OML_sync_control */ + +#ifdef GLX_SGIS_blended_overlay + +static void _glewInfo_GLX_SGIS_blended_overlay (void) +{ + glewPrintExt("GLX_SGIS_blended_overlay", GLXEW_SGIS_blended_overlay, glxewIsSupported("GLX_SGIS_blended_overlay"), glxewGetExtension("GLX_SGIS_blended_overlay")); +} + +#endif /* GLX_SGIS_blended_overlay */ + +#ifdef GLX_SGIS_color_range + +static void _glewInfo_GLX_SGIS_color_range (void) +{ + glewPrintExt("GLX_SGIS_color_range", GLXEW_SGIS_color_range, glxewIsSupported("GLX_SGIS_color_range"), glxewGetExtension("GLX_SGIS_color_range")); +} + +#endif /* GLX_SGIS_color_range */ + +#ifdef GLX_SGIS_multisample + +static void _glewInfo_GLX_SGIS_multisample (void) +{ + glewPrintExt("GLX_SGIS_multisample", GLXEW_SGIS_multisample, glxewIsSupported("GLX_SGIS_multisample"), glxewGetExtension("GLX_SGIS_multisample")); +} + +#endif /* GLX_SGIS_multisample */ + +#ifdef GLX_SGIS_shared_multisample + +static void _glewInfo_GLX_SGIS_shared_multisample (void) +{ + glewPrintExt("GLX_SGIS_shared_multisample", GLXEW_SGIS_shared_multisample, glxewIsSupported("GLX_SGIS_shared_multisample"), glxewGetExtension("GLX_SGIS_shared_multisample")); +} + +#endif /* GLX_SGIS_shared_multisample */ + +#ifdef GLX_SGIX_fbconfig + +static void _glewInfo_GLX_SGIX_fbconfig (void) +{ + glewPrintExt("GLX_SGIX_fbconfig", GLXEW_SGIX_fbconfig, glxewIsSupported("GLX_SGIX_fbconfig"), glxewGetExtension("GLX_SGIX_fbconfig")); + + glewInfoFunc("glXChooseFBConfigSGIX", glXChooseFBConfigSGIX == NULL); + glewInfoFunc("glXCreateContextWithConfigSGIX", glXCreateContextWithConfigSGIX == NULL); + glewInfoFunc("glXCreateGLXPixmapWithConfigSGIX", glXCreateGLXPixmapWithConfigSGIX == NULL); + glewInfoFunc("glXGetFBConfigAttribSGIX", glXGetFBConfigAttribSGIX == NULL); + glewInfoFunc("glXGetFBConfigFromVisualSGIX", glXGetFBConfigFromVisualSGIX == NULL); + glewInfoFunc("glXGetVisualFromFBConfigSGIX", glXGetVisualFromFBConfigSGIX == NULL); +} + +#endif /* GLX_SGIX_fbconfig */ + +#ifdef GLX_SGIX_hyperpipe + +static void _glewInfo_GLX_SGIX_hyperpipe (void) +{ + glewPrintExt("GLX_SGIX_hyperpipe", GLXEW_SGIX_hyperpipe, glxewIsSupported("GLX_SGIX_hyperpipe"), glxewGetExtension("GLX_SGIX_hyperpipe")); + + glewInfoFunc("glXBindHyperpipeSGIX", glXBindHyperpipeSGIX == NULL); + glewInfoFunc("glXDestroyHyperpipeConfigSGIX", glXDestroyHyperpipeConfigSGIX == NULL); + glewInfoFunc("glXHyperpipeAttribSGIX", glXHyperpipeAttribSGIX == NULL); + glewInfoFunc("glXHyperpipeConfigSGIX", glXHyperpipeConfigSGIX == NULL); + glewInfoFunc("glXQueryHyperpipeAttribSGIX", glXQueryHyperpipeAttribSGIX == NULL); + glewInfoFunc("glXQueryHyperpipeBestAttribSGIX", glXQueryHyperpipeBestAttribSGIX == NULL); + glewInfoFunc("glXQueryHyperpipeConfigSGIX", glXQueryHyperpipeConfigSGIX == NULL); + glewInfoFunc("glXQueryHyperpipeNetworkSGIX", glXQueryHyperpipeNetworkSGIX == NULL); +} + +#endif /* GLX_SGIX_hyperpipe */ + +#ifdef GLX_SGIX_pbuffer + +static void _glewInfo_GLX_SGIX_pbuffer (void) +{ + glewPrintExt("GLX_SGIX_pbuffer", GLXEW_SGIX_pbuffer, glxewIsSupported("GLX_SGIX_pbuffer"), glxewGetExtension("GLX_SGIX_pbuffer")); + + glewInfoFunc("glXCreateGLXPbufferSGIX", glXCreateGLXPbufferSGIX == NULL); + glewInfoFunc("glXDestroyGLXPbufferSGIX", glXDestroyGLXPbufferSGIX == NULL); + glewInfoFunc("glXGetSelectedEventSGIX", glXGetSelectedEventSGIX == NULL); + glewInfoFunc("glXQueryGLXPbufferSGIX", glXQueryGLXPbufferSGIX == NULL); + glewInfoFunc("glXSelectEventSGIX", glXSelectEventSGIX == NULL); +} + +#endif /* GLX_SGIX_pbuffer */ + +#ifdef GLX_SGIX_swap_barrier + +static void _glewInfo_GLX_SGIX_swap_barrier (void) +{ + glewPrintExt("GLX_SGIX_swap_barrier", GLXEW_SGIX_swap_barrier, glxewIsSupported("GLX_SGIX_swap_barrier"), glxewGetExtension("GLX_SGIX_swap_barrier")); + + glewInfoFunc("glXBindSwapBarrierSGIX", glXBindSwapBarrierSGIX == NULL); + glewInfoFunc("glXQueryMaxSwapBarriersSGIX", glXQueryMaxSwapBarriersSGIX == NULL); +} + +#endif /* GLX_SGIX_swap_barrier */ + +#ifdef GLX_SGIX_swap_group + +static void _glewInfo_GLX_SGIX_swap_group (void) +{ + glewPrintExt("GLX_SGIX_swap_group", GLXEW_SGIX_swap_group, glxewIsSupported("GLX_SGIX_swap_group"), glxewGetExtension("GLX_SGIX_swap_group")); + + glewInfoFunc("glXJoinSwapGroupSGIX", glXJoinSwapGroupSGIX == NULL); +} + +#endif /* GLX_SGIX_swap_group */ + +#ifdef GLX_SGIX_video_resize + +static void _glewInfo_GLX_SGIX_video_resize (void) +{ + glewPrintExt("GLX_SGIX_video_resize", GLXEW_SGIX_video_resize, glxewIsSupported("GLX_SGIX_video_resize"), glxewGetExtension("GLX_SGIX_video_resize")); + + glewInfoFunc("glXBindChannelToWindowSGIX", glXBindChannelToWindowSGIX == NULL); + glewInfoFunc("glXChannelRectSGIX", glXChannelRectSGIX == NULL); + glewInfoFunc("glXChannelRectSyncSGIX", glXChannelRectSyncSGIX == NULL); + glewInfoFunc("glXQueryChannelDeltasSGIX", glXQueryChannelDeltasSGIX == NULL); + glewInfoFunc("glXQueryChannelRectSGIX", glXQueryChannelRectSGIX == NULL); +} + +#endif /* GLX_SGIX_video_resize */ + +#ifdef GLX_SGIX_visual_select_group + +static void _glewInfo_GLX_SGIX_visual_select_group (void) +{ + glewPrintExt("GLX_SGIX_visual_select_group", GLXEW_SGIX_visual_select_group, glxewIsSupported("GLX_SGIX_visual_select_group"), glxewGetExtension("GLX_SGIX_visual_select_group")); +} + +#endif /* GLX_SGIX_visual_select_group */ + +#ifdef GLX_SGI_cushion + +static void _glewInfo_GLX_SGI_cushion (void) +{ + glewPrintExt("GLX_SGI_cushion", GLXEW_SGI_cushion, glxewIsSupported("GLX_SGI_cushion"), glxewGetExtension("GLX_SGI_cushion")); + + glewInfoFunc("glXCushionSGI", glXCushionSGI == NULL); +} + +#endif /* GLX_SGI_cushion */ + +#ifdef GLX_SGI_make_current_read + +static void _glewInfo_GLX_SGI_make_current_read (void) +{ + glewPrintExt("GLX_SGI_make_current_read", GLXEW_SGI_make_current_read, glxewIsSupported("GLX_SGI_make_current_read"), glxewGetExtension("GLX_SGI_make_current_read")); + + glewInfoFunc("glXGetCurrentReadDrawableSGI", glXGetCurrentReadDrawableSGI == NULL); + glewInfoFunc("glXMakeCurrentReadSGI", glXMakeCurrentReadSGI == NULL); +} + +#endif /* GLX_SGI_make_current_read */ + +#ifdef GLX_SGI_swap_control + +static void _glewInfo_GLX_SGI_swap_control (void) +{ + glewPrintExt("GLX_SGI_swap_control", GLXEW_SGI_swap_control, glxewIsSupported("GLX_SGI_swap_control"), glxewGetExtension("GLX_SGI_swap_control")); + + glewInfoFunc("glXSwapIntervalSGI", glXSwapIntervalSGI == NULL); +} + +#endif /* GLX_SGI_swap_control */ + +#ifdef GLX_SGI_video_sync + +static void _glewInfo_GLX_SGI_video_sync (void) +{ + glewPrintExt("GLX_SGI_video_sync", GLXEW_SGI_video_sync, glxewIsSupported("GLX_SGI_video_sync"), glxewGetExtension("GLX_SGI_video_sync")); + + glewInfoFunc("glXGetVideoSyncSGI", glXGetVideoSyncSGI == NULL); + glewInfoFunc("glXWaitVideoSyncSGI", glXWaitVideoSyncSGI == NULL); +} + +#endif /* GLX_SGI_video_sync */ + +#ifdef GLX_SUN_get_transparent_index + +static void _glewInfo_GLX_SUN_get_transparent_index (void) +{ + glewPrintExt("GLX_SUN_get_transparent_index", GLXEW_SUN_get_transparent_index, glxewIsSupported("GLX_SUN_get_transparent_index"), glxewGetExtension("GLX_SUN_get_transparent_index")); + + glewInfoFunc("glXGetTransparentIndexSUN", glXGetTransparentIndexSUN == NULL); +} + +#endif /* GLX_SUN_get_transparent_index */ + +#ifdef GLX_SUN_video_resize + +static void _glewInfo_GLX_SUN_video_resize (void) +{ + glewPrintExt("GLX_SUN_video_resize", GLXEW_SUN_video_resize, glxewIsSupported("GLX_SUN_video_resize"), glxewGetExtension("GLX_SUN_video_resize")); + + glewInfoFunc("glXGetVideoResizeSUN", glXGetVideoResizeSUN == NULL); + glewInfoFunc("glXVideoResizeSUN", glXVideoResizeSUN == NULL); +} + +#endif /* GLX_SUN_video_resize */ + +#endif /* _WIN32 */ + +/* ------------------------------------------------------------------------ */ + +static void glewInfo (void) +{ +#ifdef GL_VERSION_1_1 + _glewInfo_GL_VERSION_1_1(); +#endif /* GL_VERSION_1_1 */ +#ifdef GL_VERSION_1_2 + _glewInfo_GL_VERSION_1_2(); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_3 + _glewInfo_GL_VERSION_1_3(); +#endif /* GL_VERSION_1_3 */ +#ifdef GL_VERSION_1_4 + _glewInfo_GL_VERSION_1_4(); +#endif /* GL_VERSION_1_4 */ +#ifdef GL_VERSION_1_5 + _glewInfo_GL_VERSION_1_5(); +#endif /* GL_VERSION_1_5 */ +#ifdef GL_VERSION_2_0 + _glewInfo_GL_VERSION_2_0(); +#endif /* GL_VERSION_2_0 */ +#ifdef GL_VERSION_2_1 + _glewInfo_GL_VERSION_2_1(); +#endif /* GL_VERSION_2_1 */ +#ifdef GL_VERSION_3_0 + _glewInfo_GL_VERSION_3_0(); +#endif /* GL_VERSION_3_0 */ +#ifdef GL_3DFX_multisample + _glewInfo_GL_3DFX_multisample(); +#endif /* GL_3DFX_multisample */ +#ifdef GL_3DFX_tbuffer + _glewInfo_GL_3DFX_tbuffer(); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_3DFX_texture_compression_FXT1 + _glewInfo_GL_3DFX_texture_compression_FXT1(); +#endif /* GL_3DFX_texture_compression_FXT1 */ +#ifdef GL_APPLE_client_storage + _glewInfo_GL_APPLE_client_storage(); +#endif /* GL_APPLE_client_storage */ +#ifdef GL_APPLE_element_array + _glewInfo_GL_APPLE_element_array(); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + _glewInfo_GL_APPLE_fence(); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_float_pixels + _glewInfo_GL_APPLE_float_pixels(); +#endif /* GL_APPLE_float_pixels */ +#ifdef GL_APPLE_flush_buffer_range + _glewInfo_GL_APPLE_flush_buffer_range(); +#endif /* GL_APPLE_flush_buffer_range */ +#ifdef GL_APPLE_pixel_buffer + _glewInfo_GL_APPLE_pixel_buffer(); +#endif /* GL_APPLE_pixel_buffer */ +#ifdef GL_APPLE_specular_vector + _glewInfo_GL_APPLE_specular_vector(); +#endif /* GL_APPLE_specular_vector */ +#ifdef GL_APPLE_texture_range + _glewInfo_GL_APPLE_texture_range(); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_transform_hint + _glewInfo_GL_APPLE_transform_hint(); +#endif /* GL_APPLE_transform_hint */ +#ifdef GL_APPLE_vertex_array_object + _glewInfo_GL_APPLE_vertex_array_object(); +#endif /* GL_APPLE_vertex_array_object */ +#ifdef GL_APPLE_vertex_array_range + _glewInfo_GL_APPLE_vertex_array_range(); +#endif /* GL_APPLE_vertex_array_range */ +#ifdef GL_APPLE_ycbcr_422 + _glewInfo_GL_APPLE_ycbcr_422(); +#endif /* GL_APPLE_ycbcr_422 */ +#ifdef GL_ARB_color_buffer_float + _glewInfo_GL_ARB_color_buffer_float(); +#endif /* GL_ARB_color_buffer_float */ +#ifdef GL_ARB_depth_buffer_float + _glewInfo_GL_ARB_depth_buffer_float(); +#endif /* GL_ARB_depth_buffer_float */ +#ifdef GL_ARB_depth_texture + _glewInfo_GL_ARB_depth_texture(); +#endif /* GL_ARB_depth_texture */ +#ifdef GL_ARB_draw_buffers + _glewInfo_GL_ARB_draw_buffers(); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_draw_instanced + _glewInfo_GL_ARB_draw_instanced(); +#endif /* GL_ARB_draw_instanced */ +#ifdef GL_ARB_fragment_program + _glewInfo_GL_ARB_fragment_program(); +#endif /* GL_ARB_fragment_program */ +#ifdef GL_ARB_fragment_program_shadow + _glewInfo_GL_ARB_fragment_program_shadow(); +#endif /* GL_ARB_fragment_program_shadow */ +#ifdef GL_ARB_fragment_shader + _glewInfo_GL_ARB_fragment_shader(); +#endif /* GL_ARB_fragment_shader */ +#ifdef GL_ARB_framebuffer_object + _glewInfo_GL_ARB_framebuffer_object(); +#endif /* GL_ARB_framebuffer_object */ +#ifdef GL_ARB_framebuffer_sRGB + _glewInfo_GL_ARB_framebuffer_sRGB(); +#endif /* GL_ARB_framebuffer_sRGB */ +#ifdef GL_ARB_geometry_shader4 + _glewInfo_GL_ARB_geometry_shader4(); +#endif /* GL_ARB_geometry_shader4 */ +#ifdef GL_ARB_half_float_pixel + _glewInfo_GL_ARB_half_float_pixel(); +#endif /* GL_ARB_half_float_pixel */ +#ifdef GL_ARB_half_float_vertex + _glewInfo_GL_ARB_half_float_vertex(); +#endif /* GL_ARB_half_float_vertex */ +#ifdef GL_ARB_imaging + _glewInfo_GL_ARB_imaging(); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_instanced_arrays + _glewInfo_GL_ARB_instanced_arrays(); +#endif /* GL_ARB_instanced_arrays */ +#ifdef GL_ARB_map_buffer_range + _glewInfo_GL_ARB_map_buffer_range(); +#endif /* GL_ARB_map_buffer_range */ +#ifdef GL_ARB_matrix_palette + _glewInfo_GL_ARB_matrix_palette(); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multisample + _glewInfo_GL_ARB_multisample(); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + _glewInfo_GL_ARB_multitexture(); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + _glewInfo_GL_ARB_occlusion_query(); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_pixel_buffer_object + _glewInfo_GL_ARB_pixel_buffer_object(); +#endif /* GL_ARB_pixel_buffer_object */ +#ifdef GL_ARB_point_parameters + _glewInfo_GL_ARB_point_parameters(); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_point_sprite + _glewInfo_GL_ARB_point_sprite(); +#endif /* GL_ARB_point_sprite */ +#ifdef GL_ARB_shader_objects + _glewInfo_GL_ARB_shader_objects(); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shading_language_100 + _glewInfo_GL_ARB_shading_language_100(); +#endif /* GL_ARB_shading_language_100 */ +#ifdef GL_ARB_shadow + _glewInfo_GL_ARB_shadow(); +#endif /* GL_ARB_shadow */ +#ifdef GL_ARB_shadow_ambient + _glewInfo_GL_ARB_shadow_ambient(); +#endif /* GL_ARB_shadow_ambient */ +#ifdef GL_ARB_texture_border_clamp + _glewInfo_GL_ARB_texture_border_clamp(); +#endif /* GL_ARB_texture_border_clamp */ +#ifdef GL_ARB_texture_buffer_object + _glewInfo_GL_ARB_texture_buffer_object(); +#endif /* GL_ARB_texture_buffer_object */ +#ifdef GL_ARB_texture_compression + _glewInfo_GL_ARB_texture_compression(); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_compression_rgtc + _glewInfo_GL_ARB_texture_compression_rgtc(); +#endif /* GL_ARB_texture_compression_rgtc */ +#ifdef GL_ARB_texture_cube_map + _glewInfo_GL_ARB_texture_cube_map(); +#endif /* GL_ARB_texture_cube_map */ +#ifdef GL_ARB_texture_env_add + _glewInfo_GL_ARB_texture_env_add(); +#endif /* GL_ARB_texture_env_add */ +#ifdef GL_ARB_texture_env_combine + _glewInfo_GL_ARB_texture_env_combine(); +#endif /* GL_ARB_texture_env_combine */ +#ifdef GL_ARB_texture_env_crossbar + _glewInfo_GL_ARB_texture_env_crossbar(); +#endif /* GL_ARB_texture_env_crossbar */ +#ifdef GL_ARB_texture_env_dot3 + _glewInfo_GL_ARB_texture_env_dot3(); +#endif /* GL_ARB_texture_env_dot3 */ +#ifdef GL_ARB_texture_float + _glewInfo_GL_ARB_texture_float(); +#endif /* GL_ARB_texture_float */ +#ifdef GL_ARB_texture_mirrored_repeat + _glewInfo_GL_ARB_texture_mirrored_repeat(); +#endif /* GL_ARB_texture_mirrored_repeat */ +#ifdef GL_ARB_texture_non_power_of_two + _glewInfo_GL_ARB_texture_non_power_of_two(); +#endif /* GL_ARB_texture_non_power_of_two */ +#ifdef GL_ARB_texture_rectangle + _glewInfo_GL_ARB_texture_rectangle(); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_ARB_texture_rg + _glewInfo_GL_ARB_texture_rg(); +#endif /* GL_ARB_texture_rg */ +#ifdef GL_ARB_transpose_matrix + _glewInfo_GL_ARB_transpose_matrix(); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_vertex_array_object + _glewInfo_GL_ARB_vertex_array_object(); +#endif /* GL_ARB_vertex_array_object */ +#ifdef GL_ARB_vertex_blend + _glewInfo_GL_ARB_vertex_blend(); +#endif /* GL_ARB_vertex_blend */ +#ifdef GL_ARB_vertex_buffer_object + _glewInfo_GL_ARB_vertex_buffer_object(); +#endif /* GL_ARB_vertex_buffer_object */ +#ifdef GL_ARB_vertex_program + _glewInfo_GL_ARB_vertex_program(); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + _glewInfo_GL_ARB_vertex_shader(); +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_window_pos + _glewInfo_GL_ARB_window_pos(); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATIX_point_sprites + _glewInfo_GL_ATIX_point_sprites(); +#endif /* GL_ATIX_point_sprites */ +#ifdef GL_ATIX_texture_env_combine3 + _glewInfo_GL_ATIX_texture_env_combine3(); +#endif /* GL_ATIX_texture_env_combine3 */ +#ifdef GL_ATIX_texture_env_route + _glewInfo_GL_ATIX_texture_env_route(); +#endif /* GL_ATIX_texture_env_route */ +#ifdef GL_ATIX_vertex_shader_output_point_size + _glewInfo_GL_ATIX_vertex_shader_output_point_size(); +#endif /* GL_ATIX_vertex_shader_output_point_size */ +#ifdef GL_ATI_draw_buffers + _glewInfo_GL_ATI_draw_buffers(); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + _glewInfo_GL_ATI_element_array(); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + _glewInfo_GL_ATI_envmap_bumpmap(); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + _glewInfo_GL_ATI_fragment_shader(); +#endif /* GL_ATI_fragment_shader */ +#ifdef GL_ATI_map_object_buffer + _glewInfo_GL_ATI_map_object_buffer(); +#endif /* GL_ATI_map_object_buffer */ +#ifdef GL_ATI_pn_triangles + _glewInfo_GL_ATI_pn_triangles(); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + _glewInfo_GL_ATI_separate_stencil(); +#endif /* GL_ATI_separate_stencil */ +#ifdef GL_ATI_shader_texture_lod + _glewInfo_GL_ATI_shader_texture_lod(); +#endif /* GL_ATI_shader_texture_lod */ +#ifdef GL_ATI_text_fragment_shader + _glewInfo_GL_ATI_text_fragment_shader(); +#endif /* GL_ATI_text_fragment_shader */ +#ifdef GL_ATI_texture_compression_3dc + _glewInfo_GL_ATI_texture_compression_3dc(); +#endif /* GL_ATI_texture_compression_3dc */ +#ifdef GL_ATI_texture_env_combine3 + _glewInfo_GL_ATI_texture_env_combine3(); +#endif /* GL_ATI_texture_env_combine3 */ +#ifdef GL_ATI_texture_float + _glewInfo_GL_ATI_texture_float(); +#endif /* GL_ATI_texture_float */ +#ifdef GL_ATI_texture_mirror_once + _glewInfo_GL_ATI_texture_mirror_once(); +#endif /* GL_ATI_texture_mirror_once */ +#ifdef GL_ATI_vertex_array_object + _glewInfo_GL_ATI_vertex_array_object(); +#endif /* GL_ATI_vertex_array_object */ +#ifdef GL_ATI_vertex_attrib_array_object + _glewInfo_GL_ATI_vertex_attrib_array_object(); +#endif /* GL_ATI_vertex_attrib_array_object */ +#ifdef GL_ATI_vertex_streams + _glewInfo_GL_ATI_vertex_streams(); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_422_pixels + _glewInfo_GL_EXT_422_pixels(); +#endif /* GL_EXT_422_pixels */ +#ifdef GL_EXT_Cg_shader + _glewInfo_GL_EXT_Cg_shader(); +#endif /* GL_EXT_Cg_shader */ +#ifdef GL_EXT_abgr + _glewInfo_GL_EXT_abgr(); +#endif /* GL_EXT_abgr */ +#ifdef GL_EXT_bgra + _glewInfo_GL_EXT_bgra(); +#endif /* GL_EXT_bgra */ +#ifdef GL_EXT_bindable_uniform + _glewInfo_GL_EXT_bindable_uniform(); +#endif /* GL_EXT_bindable_uniform */ +#ifdef GL_EXT_blend_color + _glewInfo_GL_EXT_blend_color(); +#endif /* GL_EXT_blend_color */ +#ifdef GL_EXT_blend_equation_separate + _glewInfo_GL_EXT_blend_equation_separate(); +#endif /* GL_EXT_blend_equation_separate */ +#ifdef GL_EXT_blend_func_separate + _glewInfo_GL_EXT_blend_func_separate(); +#endif /* GL_EXT_blend_func_separate */ +#ifdef GL_EXT_blend_logic_op + _glewInfo_GL_EXT_blend_logic_op(); +#endif /* GL_EXT_blend_logic_op */ +#ifdef GL_EXT_blend_minmax + _glewInfo_GL_EXT_blend_minmax(); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_subtract + _glewInfo_GL_EXT_blend_subtract(); +#endif /* GL_EXT_blend_subtract */ +#ifdef GL_EXT_clip_volume_hint + _glewInfo_GL_EXT_clip_volume_hint(); +#endif /* GL_EXT_clip_volume_hint */ +#ifdef GL_EXT_cmyka + _glewInfo_GL_EXT_cmyka(); +#endif /* GL_EXT_cmyka */ +#ifdef GL_EXT_color_subtable + _glewInfo_GL_EXT_color_subtable(); +#endif /* GL_EXT_color_subtable */ +#ifdef GL_EXT_compiled_vertex_array + _glewInfo_GL_EXT_compiled_vertex_array(); +#endif /* GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_convolution + _glewInfo_GL_EXT_convolution(); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + _glewInfo_GL_EXT_coordinate_frame(); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_texture + _glewInfo_GL_EXT_copy_texture(); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + _glewInfo_GL_EXT_cull_vertex(); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_depth_bounds_test + _glewInfo_GL_EXT_depth_bounds_test(); +#endif /* GL_EXT_depth_bounds_test */ +#ifdef GL_EXT_direct_state_access + _glewInfo_GL_EXT_direct_state_access(); +#endif /* GL_EXT_direct_state_access */ +#ifdef GL_EXT_draw_buffers2 + _glewInfo_GL_EXT_draw_buffers2(); +#endif /* GL_EXT_draw_buffers2 */ +#ifdef GL_EXT_draw_instanced + _glewInfo_GL_EXT_draw_instanced(); +#endif /* GL_EXT_draw_instanced */ +#ifdef GL_EXT_draw_range_elements + _glewInfo_GL_EXT_draw_range_elements(); +#endif /* GL_EXT_draw_range_elements */ +#ifdef GL_EXT_fog_coord + _glewInfo_GL_EXT_fog_coord(); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + _glewInfo_GL_EXT_fragment_lighting(); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + _glewInfo_GL_EXT_framebuffer_blit(); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + _glewInfo_GL_EXT_framebuffer_multisample(); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_object + _glewInfo_GL_EXT_framebuffer_object(); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_framebuffer_sRGB + _glewInfo_GL_EXT_framebuffer_sRGB(); +#endif /* GL_EXT_framebuffer_sRGB */ +#ifdef GL_EXT_geometry_shader4 + _glewInfo_GL_EXT_geometry_shader4(); +#endif /* GL_EXT_geometry_shader4 */ +#ifdef GL_EXT_gpu_program_parameters + _glewInfo_GL_EXT_gpu_program_parameters(); +#endif /* GL_EXT_gpu_program_parameters */ +#ifdef GL_EXT_gpu_shader4 + _glewInfo_GL_EXT_gpu_shader4(); +#endif /* GL_EXT_gpu_shader4 */ +#ifdef GL_EXT_histogram + _glewInfo_GL_EXT_histogram(); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_array_formats + _glewInfo_GL_EXT_index_array_formats(); +#endif /* GL_EXT_index_array_formats */ +#ifdef GL_EXT_index_func + _glewInfo_GL_EXT_index_func(); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + _glewInfo_GL_EXT_index_material(); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_index_texture + _glewInfo_GL_EXT_index_texture(); +#endif /* GL_EXT_index_texture */ +#ifdef GL_EXT_light_texture + _glewInfo_GL_EXT_light_texture(); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_misc_attribute + _glewInfo_GL_EXT_misc_attribute(); +#endif /* GL_EXT_misc_attribute */ +#ifdef GL_EXT_multi_draw_arrays + _glewInfo_GL_EXT_multi_draw_arrays(); +#endif /* GL_EXT_multi_draw_arrays */ +#ifdef GL_EXT_multisample + _glewInfo_GL_EXT_multisample(); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_packed_depth_stencil + _glewInfo_GL_EXT_packed_depth_stencil(); +#endif /* GL_EXT_packed_depth_stencil */ +#ifdef GL_EXT_packed_float + _glewInfo_GL_EXT_packed_float(); +#endif /* GL_EXT_packed_float */ +#ifdef GL_EXT_packed_pixels + _glewInfo_GL_EXT_packed_pixels(); +#endif /* GL_EXT_packed_pixels */ +#ifdef GL_EXT_paletted_texture + _glewInfo_GL_EXT_paletted_texture(); +#endif /* GL_EXT_paletted_texture */ +#ifdef GL_EXT_pixel_buffer_object + _glewInfo_GL_EXT_pixel_buffer_object(); +#endif /* GL_EXT_pixel_buffer_object */ +#ifdef GL_EXT_pixel_transform + _glewInfo_GL_EXT_pixel_transform(); +#endif /* GL_EXT_pixel_transform */ +#ifdef GL_EXT_pixel_transform_color_table + _glewInfo_GL_EXT_pixel_transform_color_table(); +#endif /* GL_EXT_pixel_transform_color_table */ +#ifdef GL_EXT_point_parameters + _glewInfo_GL_EXT_point_parameters(); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + _glewInfo_GL_EXT_polygon_offset(); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_rescale_normal + _glewInfo_GL_EXT_rescale_normal(); +#endif /* GL_EXT_rescale_normal */ +#ifdef GL_EXT_scene_marker + _glewInfo_GL_EXT_scene_marker(); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + _glewInfo_GL_EXT_secondary_color(); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_separate_specular_color + _glewInfo_GL_EXT_separate_specular_color(); +#endif /* GL_EXT_separate_specular_color */ +#ifdef GL_EXT_shadow_funcs + _glewInfo_GL_EXT_shadow_funcs(); +#endif /* GL_EXT_shadow_funcs */ +#ifdef GL_EXT_shared_texture_palette + _glewInfo_GL_EXT_shared_texture_palette(); +#endif /* GL_EXT_shared_texture_palette */ +#ifdef GL_EXT_stencil_clear_tag + _glewInfo_GL_EXT_stencil_clear_tag(); +#endif /* GL_EXT_stencil_clear_tag */ +#ifdef GL_EXT_stencil_two_side + _glewInfo_GL_EXT_stencil_two_side(); +#endif /* GL_EXT_stencil_two_side */ +#ifdef GL_EXT_stencil_wrap + _glewInfo_GL_EXT_stencil_wrap(); +#endif /* GL_EXT_stencil_wrap */ +#ifdef GL_EXT_subtexture + _glewInfo_GL_EXT_subtexture(); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture + _glewInfo_GL_EXT_texture(); +#endif /* GL_EXT_texture */ +#ifdef GL_EXT_texture3D + _glewInfo_GL_EXT_texture3D(); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_array + _glewInfo_GL_EXT_texture_array(); +#endif /* GL_EXT_texture_array */ +#ifdef GL_EXT_texture_buffer_object + _glewInfo_GL_EXT_texture_buffer_object(); +#endif /* GL_EXT_texture_buffer_object */ +#ifdef GL_EXT_texture_compression_dxt1 + _glewInfo_GL_EXT_texture_compression_dxt1(); +#endif /* GL_EXT_texture_compression_dxt1 */ +#ifdef GL_EXT_texture_compression_latc + _glewInfo_GL_EXT_texture_compression_latc(); +#endif /* GL_EXT_texture_compression_latc */ +#ifdef GL_EXT_texture_compression_rgtc + _glewInfo_GL_EXT_texture_compression_rgtc(); +#endif /* GL_EXT_texture_compression_rgtc */ +#ifdef GL_EXT_texture_compression_s3tc + _glewInfo_GL_EXT_texture_compression_s3tc(); +#endif /* GL_EXT_texture_compression_s3tc */ +#ifdef GL_EXT_texture_cube_map + _glewInfo_GL_EXT_texture_cube_map(); +#endif /* GL_EXT_texture_cube_map */ +#ifdef GL_EXT_texture_edge_clamp + _glewInfo_GL_EXT_texture_edge_clamp(); +#endif /* GL_EXT_texture_edge_clamp */ +#ifdef GL_EXT_texture_env + _glewInfo_GL_EXT_texture_env(); +#endif /* GL_EXT_texture_env */ +#ifdef GL_EXT_texture_env_add + _glewInfo_GL_EXT_texture_env_add(); +#endif /* GL_EXT_texture_env_add */ +#ifdef GL_EXT_texture_env_combine + _glewInfo_GL_EXT_texture_env_combine(); +#endif /* GL_EXT_texture_env_combine */ +#ifdef GL_EXT_texture_env_dot3 + _glewInfo_GL_EXT_texture_env_dot3(); +#endif /* GL_EXT_texture_env_dot3 */ +#ifdef GL_EXT_texture_filter_anisotropic + _glewInfo_GL_EXT_texture_filter_anisotropic(); +#endif /* GL_EXT_texture_filter_anisotropic */ +#ifdef GL_EXT_texture_integer + _glewInfo_GL_EXT_texture_integer(); +#endif /* GL_EXT_texture_integer */ +#ifdef GL_EXT_texture_lod_bias + _glewInfo_GL_EXT_texture_lod_bias(); +#endif /* GL_EXT_texture_lod_bias */ +#ifdef GL_EXT_texture_mirror_clamp + _glewInfo_GL_EXT_texture_mirror_clamp(); +#endif /* GL_EXT_texture_mirror_clamp */ +#ifdef GL_EXT_texture_object + _glewInfo_GL_EXT_texture_object(); +#endif /* GL_EXT_texture_object */ +#ifdef GL_EXT_texture_perturb_normal + _glewInfo_GL_EXT_texture_perturb_normal(); +#endif /* GL_EXT_texture_perturb_normal */ +#ifdef GL_EXT_texture_rectangle + _glewInfo_GL_EXT_texture_rectangle(); +#endif /* GL_EXT_texture_rectangle */ +#ifdef GL_EXT_texture_sRGB + _glewInfo_GL_EXT_texture_sRGB(); +#endif /* GL_EXT_texture_sRGB */ +#ifdef GL_EXT_texture_shared_exponent + _glewInfo_GL_EXT_texture_shared_exponent(); +#endif /* GL_EXT_texture_shared_exponent */ +#ifdef GL_EXT_texture_swizzle + _glewInfo_GL_EXT_texture_swizzle(); +#endif /* GL_EXT_texture_swizzle */ +#ifdef GL_EXT_timer_query + _glewInfo_GL_EXT_timer_query(); +#endif /* GL_EXT_timer_query */ +#ifdef GL_EXT_transform_feedback + _glewInfo_GL_EXT_transform_feedback(); +#endif /* GL_EXT_transform_feedback */ +#ifdef GL_EXT_vertex_array + _glewInfo_GL_EXT_vertex_array(); +#endif /* GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_array_bgra + _glewInfo_GL_EXT_vertex_array_bgra(); +#endif /* GL_EXT_vertex_array_bgra */ +#ifdef GL_EXT_vertex_shader + _glewInfo_GL_EXT_vertex_shader(); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + _glewInfo_GL_EXT_vertex_weighting(); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_GREMEDY_frame_terminator + _glewInfo_GL_GREMEDY_frame_terminator(); +#endif /* GL_GREMEDY_frame_terminator */ +#ifdef GL_GREMEDY_string_marker + _glewInfo_GL_GREMEDY_string_marker(); +#endif /* GL_GREMEDY_string_marker */ +#ifdef GL_HP_convolution_border_modes + _glewInfo_GL_HP_convolution_border_modes(); +#endif /* GL_HP_convolution_border_modes */ +#ifdef GL_HP_image_transform + _glewInfo_GL_HP_image_transform(); +#endif /* GL_HP_image_transform */ +#ifdef GL_HP_occlusion_test + _glewInfo_GL_HP_occlusion_test(); +#endif /* GL_HP_occlusion_test */ +#ifdef GL_HP_texture_lighting + _glewInfo_GL_HP_texture_lighting(); +#endif /* GL_HP_texture_lighting */ +#ifdef GL_IBM_cull_vertex + _glewInfo_GL_IBM_cull_vertex(); +#endif /* GL_IBM_cull_vertex */ +#ifdef GL_IBM_multimode_draw_arrays + _glewInfo_GL_IBM_multimode_draw_arrays(); +#endif /* GL_IBM_multimode_draw_arrays */ +#ifdef GL_IBM_rasterpos_clip + _glewInfo_GL_IBM_rasterpos_clip(); +#endif /* GL_IBM_rasterpos_clip */ +#ifdef GL_IBM_static_data + _glewInfo_GL_IBM_static_data(); +#endif /* GL_IBM_static_data */ +#ifdef GL_IBM_texture_mirrored_repeat + _glewInfo_GL_IBM_texture_mirrored_repeat(); +#endif /* GL_IBM_texture_mirrored_repeat */ +#ifdef GL_IBM_vertex_array_lists + _glewInfo_GL_IBM_vertex_array_lists(); +#endif /* GL_IBM_vertex_array_lists */ +#ifdef GL_INGR_color_clamp + _glewInfo_GL_INGR_color_clamp(); +#endif /* GL_INGR_color_clamp */ +#ifdef GL_INGR_interlace_read + _glewInfo_GL_INGR_interlace_read(); +#endif /* GL_INGR_interlace_read */ +#ifdef GL_INTEL_parallel_arrays + _glewInfo_GL_INTEL_parallel_arrays(); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_texture_scissor + _glewInfo_GL_INTEL_texture_scissor(); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KTX_buffer_region + _glewInfo_GL_KTX_buffer_region(); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESAX_texture_stack + _glewInfo_GL_MESAX_texture_stack(); +#endif /* GL_MESAX_texture_stack */ +#ifdef GL_MESA_pack_invert + _glewInfo_GL_MESA_pack_invert(); +#endif /* GL_MESA_pack_invert */ +#ifdef GL_MESA_resize_buffers + _glewInfo_GL_MESA_resize_buffers(); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + _glewInfo_GL_MESA_window_pos(); +#endif /* GL_MESA_window_pos */ +#ifdef GL_MESA_ycbcr_texture + _glewInfo_GL_MESA_ycbcr_texture(); +#endif /* GL_MESA_ycbcr_texture */ +#ifdef GL_NV_blend_square + _glewInfo_GL_NV_blend_square(); +#endif /* GL_NV_blend_square */ +#ifdef GL_NV_conditional_render + _glewInfo_GL_NV_conditional_render(); +#endif /* GL_NV_conditional_render */ +#ifdef GL_NV_copy_depth_to_color + _glewInfo_GL_NV_copy_depth_to_color(); +#endif /* GL_NV_copy_depth_to_color */ +#ifdef GL_NV_depth_buffer_float + _glewInfo_GL_NV_depth_buffer_float(); +#endif /* GL_NV_depth_buffer_float */ +#ifdef GL_NV_depth_clamp + _glewInfo_GL_NV_depth_clamp(); +#endif /* GL_NV_depth_clamp */ +#ifdef GL_NV_depth_range_unclamped + _glewInfo_GL_NV_depth_range_unclamped(); +#endif /* GL_NV_depth_range_unclamped */ +#ifdef GL_NV_evaluators + _glewInfo_GL_NV_evaluators(); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_explicit_multisample + _glewInfo_GL_NV_explicit_multisample(); +#endif /* GL_NV_explicit_multisample */ +#ifdef GL_NV_fence + _glewInfo_GL_NV_fence(); +#endif /* GL_NV_fence */ +#ifdef GL_NV_float_buffer + _glewInfo_GL_NV_float_buffer(); +#endif /* GL_NV_float_buffer */ +#ifdef GL_NV_fog_distance + _glewInfo_GL_NV_fog_distance(); +#endif /* GL_NV_fog_distance */ +#ifdef GL_NV_fragment_program + _glewInfo_GL_NV_fragment_program(); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_fragment_program2 + _glewInfo_GL_NV_fragment_program2(); +#endif /* GL_NV_fragment_program2 */ +#ifdef GL_NV_fragment_program4 + _glewInfo_GL_NV_fragment_program4(); +#endif /* GL_NV_fragment_program4 */ +#ifdef GL_NV_fragment_program_option + _glewInfo_GL_NV_fragment_program_option(); +#endif /* GL_NV_fragment_program_option */ +#ifdef GL_NV_framebuffer_multisample_coverage + _glewInfo_GL_NV_framebuffer_multisample_coverage(); +#endif /* GL_NV_framebuffer_multisample_coverage */ +#ifdef GL_NV_geometry_program4 + _glewInfo_GL_NV_geometry_program4(); +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_geometry_shader4 + _glewInfo_GL_NV_geometry_shader4(); +#endif /* GL_NV_geometry_shader4 */ +#ifdef GL_NV_gpu_program4 + _glewInfo_GL_NV_gpu_program4(); +#endif /* GL_NV_gpu_program4 */ +#ifdef GL_NV_half_float + _glewInfo_GL_NV_half_float(); +#endif /* GL_NV_half_float */ +#ifdef GL_NV_light_max_exponent + _glewInfo_GL_NV_light_max_exponent(); +#endif /* GL_NV_light_max_exponent */ +#ifdef GL_NV_multisample_filter_hint + _glewInfo_GL_NV_multisample_filter_hint(); +#endif /* GL_NV_multisample_filter_hint */ +#ifdef GL_NV_occlusion_query + _glewInfo_GL_NV_occlusion_query(); +#endif /* GL_NV_occlusion_query */ +#ifdef GL_NV_packed_depth_stencil + _glewInfo_GL_NV_packed_depth_stencil(); +#endif /* GL_NV_packed_depth_stencil */ +#ifdef GL_NV_parameter_buffer_object + _glewInfo_GL_NV_parameter_buffer_object(); +#endif /* GL_NV_parameter_buffer_object */ +#ifdef GL_NV_pixel_data_range + _glewInfo_GL_NV_pixel_data_range(); +#endif /* GL_NV_pixel_data_range */ +#ifdef GL_NV_point_sprite + _glewInfo_GL_NV_point_sprite(); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_present_video + _glewInfo_GL_NV_present_video(); +#endif /* GL_NV_present_video */ +#ifdef GL_NV_primitive_restart + _glewInfo_GL_NV_primitive_restart(); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + _glewInfo_GL_NV_register_combiners(); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + _glewInfo_GL_NV_register_combiners2(); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_texgen_emboss + _glewInfo_GL_NV_texgen_emboss(); +#endif /* GL_NV_texgen_emboss */ +#ifdef GL_NV_texgen_reflection + _glewInfo_GL_NV_texgen_reflection(); +#endif /* GL_NV_texgen_reflection */ +#ifdef GL_NV_texture_compression_vtc + _glewInfo_GL_NV_texture_compression_vtc(); +#endif /* GL_NV_texture_compression_vtc */ +#ifdef GL_NV_texture_env_combine4 + _glewInfo_GL_NV_texture_env_combine4(); +#endif /* GL_NV_texture_env_combine4 */ +#ifdef GL_NV_texture_expand_normal + _glewInfo_GL_NV_texture_expand_normal(); +#endif /* GL_NV_texture_expand_normal */ +#ifdef GL_NV_texture_rectangle + _glewInfo_GL_NV_texture_rectangle(); +#endif /* GL_NV_texture_rectangle */ +#ifdef GL_NV_texture_shader + _glewInfo_GL_NV_texture_shader(); +#endif /* GL_NV_texture_shader */ +#ifdef GL_NV_texture_shader2 + _glewInfo_GL_NV_texture_shader2(); +#endif /* GL_NV_texture_shader2 */ +#ifdef GL_NV_texture_shader3 + _glewInfo_GL_NV_texture_shader3(); +#endif /* GL_NV_texture_shader3 */ +#ifdef GL_NV_transform_feedback + _glewInfo_GL_NV_transform_feedback(); +#endif /* GL_NV_transform_feedback */ +#ifdef GL_NV_vertex_array_range + _glewInfo_GL_NV_vertex_array_range(); +#endif /* GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_array_range2 + _glewInfo_GL_NV_vertex_array_range2(); +#endif /* GL_NV_vertex_array_range2 */ +#ifdef GL_NV_vertex_program + _glewInfo_GL_NV_vertex_program(); +#endif /* GL_NV_vertex_program */ +#ifdef GL_NV_vertex_program1_1 + _glewInfo_GL_NV_vertex_program1_1(); +#endif /* GL_NV_vertex_program1_1 */ +#ifdef GL_NV_vertex_program2 + _glewInfo_GL_NV_vertex_program2(); +#endif /* GL_NV_vertex_program2 */ +#ifdef GL_NV_vertex_program2_option + _glewInfo_GL_NV_vertex_program2_option(); +#endif /* GL_NV_vertex_program2_option */ +#ifdef GL_NV_vertex_program3 + _glewInfo_GL_NV_vertex_program3(); +#endif /* GL_NV_vertex_program3 */ +#ifdef GL_NV_vertex_program4 + _glewInfo_GL_NV_vertex_program4(); +#endif /* GL_NV_vertex_program4 */ +#ifdef GL_OES_byte_coordinates + _glewInfo_GL_OES_byte_coordinates(); +#endif /* GL_OES_byte_coordinates */ +#ifdef GL_OES_compressed_paletted_texture + _glewInfo_GL_OES_compressed_paletted_texture(); +#endif /* GL_OES_compressed_paletted_texture */ +#ifdef GL_OES_read_format + _glewInfo_GL_OES_read_format(); +#endif /* GL_OES_read_format */ +#ifdef GL_OES_single_precision + _glewInfo_GL_OES_single_precision(); +#endif /* GL_OES_single_precision */ +#ifdef GL_OML_interlace + _glewInfo_GL_OML_interlace(); +#endif /* GL_OML_interlace */ +#ifdef GL_OML_resample + _glewInfo_GL_OML_resample(); +#endif /* GL_OML_resample */ +#ifdef GL_OML_subsample + _glewInfo_GL_OML_subsample(); +#endif /* GL_OML_subsample */ +#ifdef GL_PGI_misc_hints + _glewInfo_GL_PGI_misc_hints(); +#endif /* GL_PGI_misc_hints */ +#ifdef GL_PGI_vertex_hints + _glewInfo_GL_PGI_vertex_hints(); +#endif /* GL_PGI_vertex_hints */ +#ifdef GL_REND_screen_coordinates + _glewInfo_GL_REND_screen_coordinates(); +#endif /* GL_REND_screen_coordinates */ +#ifdef GL_S3_s3tc + _glewInfo_GL_S3_s3tc(); +#endif /* GL_S3_s3tc */ +#ifdef GL_SGIS_color_range + _glewInfo_GL_SGIS_color_range(); +#endif /* GL_SGIS_color_range */ +#ifdef GL_SGIS_detail_texture + _glewInfo_GL_SGIS_detail_texture(); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + _glewInfo_GL_SGIS_fog_function(); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_generate_mipmap + _glewInfo_GL_SGIS_generate_mipmap(); +#endif /* GL_SGIS_generate_mipmap */ +#ifdef GL_SGIS_multisample + _glewInfo_GL_SGIS_multisample(); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_pixel_texture + _glewInfo_GL_SGIS_pixel_texture(); +#endif /* GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_point_line_texgen + _glewInfo_GL_SGIS_point_line_texgen(); +#endif /* GL_SGIS_point_line_texgen */ +#ifdef GL_SGIS_sharpen_texture + _glewInfo_GL_SGIS_sharpen_texture(); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + _glewInfo_GL_SGIS_texture4D(); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_border_clamp + _glewInfo_GL_SGIS_texture_border_clamp(); +#endif /* GL_SGIS_texture_border_clamp */ +#ifdef GL_SGIS_texture_edge_clamp + _glewInfo_GL_SGIS_texture_edge_clamp(); +#endif /* GL_SGIS_texture_edge_clamp */ +#ifdef GL_SGIS_texture_filter4 + _glewInfo_GL_SGIS_texture_filter4(); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIS_texture_lod + _glewInfo_GL_SGIS_texture_lod(); +#endif /* GL_SGIS_texture_lod */ +#ifdef GL_SGIS_texture_select + _glewInfo_GL_SGIS_texture_select(); +#endif /* GL_SGIS_texture_select */ +#ifdef GL_SGIX_async + _glewInfo_GL_SGIX_async(); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_async_histogram + _glewInfo_GL_SGIX_async_histogram(); +#endif /* GL_SGIX_async_histogram */ +#ifdef GL_SGIX_async_pixel + _glewInfo_GL_SGIX_async_pixel(); +#endif /* GL_SGIX_async_pixel */ +#ifdef GL_SGIX_blend_alpha_minmax + _glewInfo_GL_SGIX_blend_alpha_minmax(); +#endif /* GL_SGIX_blend_alpha_minmax */ +#ifdef GL_SGIX_clipmap + _glewInfo_GL_SGIX_clipmap(); +#endif /* GL_SGIX_clipmap */ +#ifdef GL_SGIX_convolution_accuracy + _glewInfo_GL_SGIX_convolution_accuracy(); +#endif /* GL_SGIX_convolution_accuracy */ +#ifdef GL_SGIX_depth_texture + _glewInfo_GL_SGIX_depth_texture(); +#endif /* GL_SGIX_depth_texture */ +#ifdef GL_SGIX_flush_raster + _glewInfo_GL_SGIX_flush_raster(); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_offset + _glewInfo_GL_SGIX_fog_offset(); +#endif /* GL_SGIX_fog_offset */ +#ifdef GL_SGIX_fog_texture + _glewInfo_GL_SGIX_fog_texture(); +#endif /* GL_SGIX_fog_texture */ +#ifdef GL_SGIX_fragment_specular_lighting + _glewInfo_GL_SGIX_fragment_specular_lighting(); +#endif /* GL_SGIX_fragment_specular_lighting */ +#ifdef GL_SGIX_framezoom + _glewInfo_GL_SGIX_framezoom(); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_interlace + _glewInfo_GL_SGIX_interlace(); +#endif /* GL_SGIX_interlace */ +#ifdef GL_SGIX_ir_instrument1 + _glewInfo_GL_SGIX_ir_instrument1(); +#endif /* GL_SGIX_ir_instrument1 */ +#ifdef GL_SGIX_list_priority + _glewInfo_GL_SGIX_list_priority(); +#endif /* GL_SGIX_list_priority */ +#ifdef GL_SGIX_pixel_texture + _glewInfo_GL_SGIX_pixel_texture(); +#endif /* GL_SGIX_pixel_texture */ +#ifdef GL_SGIX_pixel_texture_bits + _glewInfo_GL_SGIX_pixel_texture_bits(); +#endif /* GL_SGIX_pixel_texture_bits */ +#ifdef GL_SGIX_reference_plane + _glewInfo_GL_SGIX_reference_plane(); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_resample + _glewInfo_GL_SGIX_resample(); +#endif /* GL_SGIX_resample */ +#ifdef GL_SGIX_shadow + _glewInfo_GL_SGIX_shadow(); +#endif /* GL_SGIX_shadow */ +#ifdef GL_SGIX_shadow_ambient + _glewInfo_GL_SGIX_shadow_ambient(); +#endif /* GL_SGIX_shadow_ambient */ +#ifdef GL_SGIX_sprite + _glewInfo_GL_SGIX_sprite(); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + _glewInfo_GL_SGIX_tag_sample_buffer(); +#endif /* GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_texture_add_env + _glewInfo_GL_SGIX_texture_add_env(); +#endif /* GL_SGIX_texture_add_env */ +#ifdef GL_SGIX_texture_coordinate_clamp + _glewInfo_GL_SGIX_texture_coordinate_clamp(); +#endif /* GL_SGIX_texture_coordinate_clamp */ +#ifdef GL_SGIX_texture_lod_bias + _glewInfo_GL_SGIX_texture_lod_bias(); +#endif /* GL_SGIX_texture_lod_bias */ +#ifdef GL_SGIX_texture_multi_buffer + _glewInfo_GL_SGIX_texture_multi_buffer(); +#endif /* GL_SGIX_texture_multi_buffer */ +#ifdef GL_SGIX_texture_range + _glewInfo_GL_SGIX_texture_range(); +#endif /* GL_SGIX_texture_range */ +#ifdef GL_SGIX_texture_scale_bias + _glewInfo_GL_SGIX_texture_scale_bias(); +#endif /* GL_SGIX_texture_scale_bias */ +#ifdef GL_SGIX_vertex_preclip + _glewInfo_GL_SGIX_vertex_preclip(); +#endif /* GL_SGIX_vertex_preclip */ +#ifdef GL_SGIX_vertex_preclip_hint + _glewInfo_GL_SGIX_vertex_preclip_hint(); +#endif /* GL_SGIX_vertex_preclip_hint */ +#ifdef GL_SGIX_ycrcb + _glewInfo_GL_SGIX_ycrcb(); +#endif /* GL_SGIX_ycrcb */ +#ifdef GL_SGI_color_matrix + _glewInfo_GL_SGI_color_matrix(); +#endif /* GL_SGI_color_matrix */ +#ifdef GL_SGI_color_table + _glewInfo_GL_SGI_color_table(); +#endif /* GL_SGI_color_table */ +#ifdef GL_SGI_texture_color_table + _glewInfo_GL_SGI_texture_color_table(); +#endif /* GL_SGI_texture_color_table */ +#ifdef GL_SUNX_constant_data + _glewInfo_GL_SUNX_constant_data(); +#endif /* GL_SUNX_constant_data */ +#ifdef GL_SUN_convolution_border_modes + _glewInfo_GL_SUN_convolution_border_modes(); +#endif /* GL_SUN_convolution_border_modes */ +#ifdef GL_SUN_global_alpha + _glewInfo_GL_SUN_global_alpha(); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_mesh_array + _glewInfo_GL_SUN_mesh_array(); +#endif /* GL_SUN_mesh_array */ +#ifdef GL_SUN_read_video_pixels + _glewInfo_GL_SUN_read_video_pixels(); +#endif /* GL_SUN_read_video_pixels */ +#ifdef GL_SUN_slice_accum + _glewInfo_GL_SUN_slice_accum(); +#endif /* GL_SUN_slice_accum */ +#ifdef GL_SUN_triangle_list + _glewInfo_GL_SUN_triangle_list(); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + _glewInfo_GL_SUN_vertex(); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_phong_shading + _glewInfo_GL_WIN_phong_shading(); +#endif /* GL_WIN_phong_shading */ +#ifdef GL_WIN_specular_fog + _glewInfo_GL_WIN_specular_fog(); +#endif /* GL_WIN_specular_fog */ +#ifdef GL_WIN_swap_hint + _glewInfo_GL_WIN_swap_hint(); +#endif /* GL_WIN_swap_hint */ +} + +/* ------------------------------------------------------------------------ */ + +#ifdef _WIN32 + +static void wglewInfo () +{ +#ifdef WGL_3DFX_multisample + _glewInfo_WGL_3DFX_multisample(); +#endif /* WGL_3DFX_multisample */ +#ifdef WGL_3DL_stereo_control + _glewInfo_WGL_3DL_stereo_control(); +#endif /* WGL_3DL_stereo_control */ +#ifdef WGL_ARB_buffer_region + _glewInfo_WGL_ARB_buffer_region(); +#endif /* WGL_ARB_buffer_region */ +#ifdef WGL_ARB_create_context + _glewInfo_WGL_ARB_create_context(); +#endif /* WGL_ARB_create_context */ +#ifdef WGL_ARB_extensions_string + _glewInfo_WGL_ARB_extensions_string(); +#endif /* WGL_ARB_extensions_string */ +#ifdef WGL_ARB_framebuffer_sRGB + _glewInfo_WGL_ARB_framebuffer_sRGB(); +#endif /* WGL_ARB_framebuffer_sRGB */ +#ifdef WGL_ARB_make_current_read + _glewInfo_WGL_ARB_make_current_read(); +#endif /* WGL_ARB_make_current_read */ +#ifdef WGL_ARB_multisample + _glewInfo_WGL_ARB_multisample(); +#endif /* WGL_ARB_multisample */ +#ifdef WGL_ARB_pbuffer + _glewInfo_WGL_ARB_pbuffer(); +#endif /* WGL_ARB_pbuffer */ +#ifdef WGL_ARB_pixel_format + _glewInfo_WGL_ARB_pixel_format(); +#endif /* WGL_ARB_pixel_format */ +#ifdef WGL_ARB_pixel_format_float + _glewInfo_WGL_ARB_pixel_format_float(); +#endif /* WGL_ARB_pixel_format_float */ +#ifdef WGL_ARB_render_texture + _glewInfo_WGL_ARB_render_texture(); +#endif /* WGL_ARB_render_texture */ +#ifdef WGL_ATI_pixel_format_float + _glewInfo_WGL_ATI_pixel_format_float(); +#endif /* WGL_ATI_pixel_format_float */ +#ifdef WGL_ATI_render_texture_rectangle + _glewInfo_WGL_ATI_render_texture_rectangle(); +#endif /* WGL_ATI_render_texture_rectangle */ +#ifdef WGL_EXT_depth_float + _glewInfo_WGL_EXT_depth_float(); +#endif /* WGL_EXT_depth_float */ +#ifdef WGL_EXT_display_color_table + _glewInfo_WGL_EXT_display_color_table(); +#endif /* WGL_EXT_display_color_table */ +#ifdef WGL_EXT_extensions_string + _glewInfo_WGL_EXT_extensions_string(); +#endif /* WGL_EXT_extensions_string */ +#ifdef WGL_EXT_framebuffer_sRGB + _glewInfo_WGL_EXT_framebuffer_sRGB(); +#endif /* WGL_EXT_framebuffer_sRGB */ +#ifdef WGL_EXT_make_current_read + _glewInfo_WGL_EXT_make_current_read(); +#endif /* WGL_EXT_make_current_read */ +#ifdef WGL_EXT_multisample + _glewInfo_WGL_EXT_multisample(); +#endif /* WGL_EXT_multisample */ +#ifdef WGL_EXT_pbuffer + _glewInfo_WGL_EXT_pbuffer(); +#endif /* WGL_EXT_pbuffer */ +#ifdef WGL_EXT_pixel_format + _glewInfo_WGL_EXT_pixel_format(); +#endif /* WGL_EXT_pixel_format */ +#ifdef WGL_EXT_pixel_format_packed_float + _glewInfo_WGL_EXT_pixel_format_packed_float(); +#endif /* WGL_EXT_pixel_format_packed_float */ +#ifdef WGL_EXT_swap_control + _glewInfo_WGL_EXT_swap_control(); +#endif /* WGL_EXT_swap_control */ +#ifdef WGL_I3D_digital_video_control + _glewInfo_WGL_I3D_digital_video_control(); +#endif /* WGL_I3D_digital_video_control */ +#ifdef WGL_I3D_gamma + _glewInfo_WGL_I3D_gamma(); +#endif /* WGL_I3D_gamma */ +#ifdef WGL_I3D_genlock + _glewInfo_WGL_I3D_genlock(); +#endif /* WGL_I3D_genlock */ +#ifdef WGL_I3D_image_buffer + _glewInfo_WGL_I3D_image_buffer(); +#endif /* WGL_I3D_image_buffer */ +#ifdef WGL_I3D_swap_frame_lock + _glewInfo_WGL_I3D_swap_frame_lock(); +#endif /* WGL_I3D_swap_frame_lock */ +#ifdef WGL_I3D_swap_frame_usage + _glewInfo_WGL_I3D_swap_frame_usage(); +#endif /* WGL_I3D_swap_frame_usage */ +#ifdef WGL_NV_float_buffer + _glewInfo_WGL_NV_float_buffer(); +#endif /* WGL_NV_float_buffer */ +#ifdef WGL_NV_gpu_affinity + _glewInfo_WGL_NV_gpu_affinity(); +#endif /* WGL_NV_gpu_affinity */ +#ifdef WGL_NV_present_video + _glewInfo_WGL_NV_present_video(); +#endif /* WGL_NV_present_video */ +#ifdef WGL_NV_render_depth_texture + _glewInfo_WGL_NV_render_depth_texture(); +#endif /* WGL_NV_render_depth_texture */ +#ifdef WGL_NV_render_texture_rectangle + _glewInfo_WGL_NV_render_texture_rectangle(); +#endif /* WGL_NV_render_texture_rectangle */ +#ifdef WGL_NV_swap_group + _glewInfo_WGL_NV_swap_group(); +#endif /* WGL_NV_swap_group */ +#ifdef WGL_NV_vertex_array_range + _glewInfo_WGL_NV_vertex_array_range(); +#endif /* WGL_NV_vertex_array_range */ +#ifdef WGL_NV_video_output + _glewInfo_WGL_NV_video_output(); +#endif /* WGL_NV_video_output */ +#ifdef WGL_OML_sync_control + _glewInfo_WGL_OML_sync_control(); +#endif /* WGL_OML_sync_control */ +} + +#else /* _UNIX */ + +static void glxewInfo () +{ +#ifdef GLX_VERSION_1_2 + _glewInfo_GLX_VERSION_1_2(); +#endif /* GLX_VERSION_1_2 */ +#ifdef GLX_VERSION_1_3 + _glewInfo_GLX_VERSION_1_3(); +#endif /* GLX_VERSION_1_3 */ +#ifdef GLX_VERSION_1_4 + _glewInfo_GLX_VERSION_1_4(); +#endif /* GLX_VERSION_1_4 */ +#ifdef GLX_3DFX_multisample + _glewInfo_GLX_3DFX_multisample(); +#endif /* GLX_3DFX_multisample */ +#ifdef GLX_ARB_create_context + _glewInfo_GLX_ARB_create_context(); +#endif /* GLX_ARB_create_context */ +#ifdef GLX_ARB_fbconfig_float + _glewInfo_GLX_ARB_fbconfig_float(); +#endif /* GLX_ARB_fbconfig_float */ +#ifdef GLX_ARB_framebuffer_sRGB + _glewInfo_GLX_ARB_framebuffer_sRGB(); +#endif /* GLX_ARB_framebuffer_sRGB */ +#ifdef GLX_ARB_get_proc_address + _glewInfo_GLX_ARB_get_proc_address(); +#endif /* GLX_ARB_get_proc_address */ +#ifdef GLX_ARB_multisample + _glewInfo_GLX_ARB_multisample(); +#endif /* GLX_ARB_multisample */ +#ifdef GLX_ATI_pixel_format_float + _glewInfo_GLX_ATI_pixel_format_float(); +#endif /* GLX_ATI_pixel_format_float */ +#ifdef GLX_ATI_render_texture + _glewInfo_GLX_ATI_render_texture(); +#endif /* GLX_ATI_render_texture */ +#ifdef GLX_EXT_fbconfig_packed_float + _glewInfo_GLX_EXT_fbconfig_packed_float(); +#endif /* GLX_EXT_fbconfig_packed_float */ +#ifdef GLX_EXT_framebuffer_sRGB + _glewInfo_GLX_EXT_framebuffer_sRGB(); +#endif /* GLX_EXT_framebuffer_sRGB */ +#ifdef GLX_EXT_import_context + _glewInfo_GLX_EXT_import_context(); +#endif /* GLX_EXT_import_context */ +#ifdef GLX_EXT_scene_marker + _glewInfo_GLX_EXT_scene_marker(); +#endif /* GLX_EXT_scene_marker */ +#ifdef GLX_EXT_texture_from_pixmap + _glewInfo_GLX_EXT_texture_from_pixmap(); +#endif /* GLX_EXT_texture_from_pixmap */ +#ifdef GLX_EXT_visual_info + _glewInfo_GLX_EXT_visual_info(); +#endif /* GLX_EXT_visual_info */ +#ifdef GLX_EXT_visual_rating + _glewInfo_GLX_EXT_visual_rating(); +#endif /* GLX_EXT_visual_rating */ +#ifdef GLX_MESA_agp_offset + _glewInfo_GLX_MESA_agp_offset(); +#endif /* GLX_MESA_agp_offset */ +#ifdef GLX_MESA_copy_sub_buffer + _glewInfo_GLX_MESA_copy_sub_buffer(); +#endif /* GLX_MESA_copy_sub_buffer */ +#ifdef GLX_MESA_pixmap_colormap + _glewInfo_GLX_MESA_pixmap_colormap(); +#endif /* GLX_MESA_pixmap_colormap */ +#ifdef GLX_MESA_release_buffers + _glewInfo_GLX_MESA_release_buffers(); +#endif /* GLX_MESA_release_buffers */ +#ifdef GLX_MESA_set_3dfx_mode + _glewInfo_GLX_MESA_set_3dfx_mode(); +#endif /* GLX_MESA_set_3dfx_mode */ +#ifdef GLX_NV_float_buffer + _glewInfo_GLX_NV_float_buffer(); +#endif /* GLX_NV_float_buffer */ +#ifdef GLX_NV_present_video + _glewInfo_GLX_NV_present_video(); +#endif /* GLX_NV_present_video */ +#ifdef GLX_NV_swap_group + _glewInfo_GLX_NV_swap_group(); +#endif /* GLX_NV_swap_group */ +#ifdef GLX_NV_vertex_array_range + _glewInfo_GLX_NV_vertex_array_range(); +#endif /* GLX_NV_vertex_array_range */ +#ifdef GLX_NV_video_output + _glewInfo_GLX_NV_video_output(); +#endif /* GLX_NV_video_output */ +#ifdef GLX_OML_swap_method + _glewInfo_GLX_OML_swap_method(); +#endif /* GLX_OML_swap_method */ +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + _glewInfo_GLX_OML_sync_control(); +#endif /* GLX_OML_sync_control */ +#ifdef GLX_SGIS_blended_overlay + _glewInfo_GLX_SGIS_blended_overlay(); +#endif /* GLX_SGIS_blended_overlay */ +#ifdef GLX_SGIS_color_range + _glewInfo_GLX_SGIS_color_range(); +#endif /* GLX_SGIS_color_range */ +#ifdef GLX_SGIS_multisample + _glewInfo_GLX_SGIS_multisample(); +#endif /* GLX_SGIS_multisample */ +#ifdef GLX_SGIS_shared_multisample + _glewInfo_GLX_SGIS_shared_multisample(); +#endif /* GLX_SGIS_shared_multisample */ +#ifdef GLX_SGIX_fbconfig + _glewInfo_GLX_SGIX_fbconfig(); +#endif /* GLX_SGIX_fbconfig */ +#ifdef GLX_SGIX_hyperpipe + _glewInfo_GLX_SGIX_hyperpipe(); +#endif /* GLX_SGIX_hyperpipe */ +#ifdef GLX_SGIX_pbuffer + _glewInfo_GLX_SGIX_pbuffer(); +#endif /* GLX_SGIX_pbuffer */ +#ifdef GLX_SGIX_swap_barrier + _glewInfo_GLX_SGIX_swap_barrier(); +#endif /* GLX_SGIX_swap_barrier */ +#ifdef GLX_SGIX_swap_group + _glewInfo_GLX_SGIX_swap_group(); +#endif /* GLX_SGIX_swap_group */ +#ifdef GLX_SGIX_video_resize + _glewInfo_GLX_SGIX_video_resize(); +#endif /* GLX_SGIX_video_resize */ +#ifdef GLX_SGIX_visual_select_group + _glewInfo_GLX_SGIX_visual_select_group(); +#endif /* GLX_SGIX_visual_select_group */ +#ifdef GLX_SGI_cushion + _glewInfo_GLX_SGI_cushion(); +#endif /* GLX_SGI_cushion */ +#ifdef GLX_SGI_make_current_read + _glewInfo_GLX_SGI_make_current_read(); +#endif /* GLX_SGI_make_current_read */ +#ifdef GLX_SGI_swap_control + _glewInfo_GLX_SGI_swap_control(); +#endif /* GLX_SGI_swap_control */ +#ifdef GLX_SGI_video_sync + _glewInfo_GLX_SGI_video_sync(); +#endif /* GLX_SGI_video_sync */ +#ifdef GLX_SUN_get_transparent_index + _glewInfo_GLX_SUN_get_transparent_index(); +#endif /* GLX_SUN_get_transparent_index */ +#ifdef GLX_SUN_video_resize + _glewInfo_GLX_SUN_video_resize(); +#endif /* GLX_SUN_video_resize */ +} + +#endif /* _WIN32 */ + +/* ------------------------------------------------------------------------ */ + +#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +int main (int argc, char** argv) +#else +int main (void) +#endif +{ + GLuint err; + +#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + char* display = NULL; + int visual = -1; + + if (glewParseArgs(argc-1, argv+1, &display, &visual)) + { +#if defined(_WIN32) + fprintf(stderr, "Usage: glewinfo [-pf ]\n"); +#else + fprintf(stderr, "Usage: glewinfo [-display ] [-visual ]\n"); +#endif + return 1; + } +#endif + +#if defined(_WIN32) + if (GL_TRUE == glewCreateContext(&visual)) +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + if (GL_TRUE == glewCreateContext()) +#else + if (GL_TRUE == glewCreateContext(display, &visual)) +#endif + { + fprintf(stderr, "Error: glewCreateContext failed\n"); + glewDestroyContext(); + return 1; + } + glewExperimental = GL_TRUE; +#ifdef GLEW_MX + err = glewContextInit(glewGetContext()); +#ifdef _WIN32 + err = err || wglewContextInit(wglewGetContext()); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + err = err || glxewContextInit(glxewGetContext()); +#endif + +#else + err = glewInit(); +#endif + if (GLEW_OK != err) + { + fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); + glewDestroyContext(); + return 1; + } +#if defined(_WIN32) + f = fopen("glewinfo.txt", "w"); + if (f == NULL) f = stdout; +#else + f = stdout; +#endif + fprintf(f, "---------------------------\n"); + fprintf(f, " GLEW Extension Info\n"); + fprintf(f, "---------------------------\n\n"); + fprintf(f, "GLEW version %s\n", glewGetString(GLEW_VERSION)); +#if defined(_WIN32) + fprintf(f, "Reporting capabilities of pixelformat %d\n", visual); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + fprintf(f, "Reporting capabilities of display %s, visual 0x%x\n", + display == NULL ? getenv("DISPLAY") : display, visual); +#endif + fprintf(f, "Running on a %s from %s\n", + glGetString(GL_RENDERER), glGetString(GL_VENDOR)); + fprintf(f, "OpenGL version %s is supported\n", glGetString(GL_VERSION)); + glewInfo(); +#if defined(_WIN32) + wglewInfo(); +#else + glxewInfo(); +#endif + if (f != stdout) fclose(f); + glewDestroyContext(); + return 0; +} + +/* ------------------------------------------------------------------------ */ + +#if defined(_WIN32) || !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +GLboolean glewParseArgs (int argc, char** argv, char** display, int* visual) +{ + int p = 0; + while (p < argc) + { +#if defined(_WIN32) + if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) + { + if (++p >= argc) return GL_TRUE; + *display = 0; + *visual = strtol(argv[p++], NULL, 0); + } + else + return GL_TRUE; +#else + if (!strcmp(argv[p], "-display")) + { + if (++p >= argc) return GL_TRUE; + *display = argv[p++]; + } + else if (!strcmp(argv[p], "-visual")) + { + if (++p >= argc) return GL_TRUE; + *visual = (int)strtol(argv[p++], NULL, 0); + } + else + return GL_TRUE; +#endif + } + return GL_FALSE; +} +#endif + +/* ------------------------------------------------------------------------ */ + +#if defined(_WIN32) + +HWND wnd = NULL; +HDC dc = NULL; +HGLRC rc = NULL; + +GLboolean glewCreateContext (int* pixelformat) +{ + WNDCLASS wc; + PIXELFORMATDESCRIPTOR pfd; + /* register window class */ + ZeroMemory(&wc, sizeof(WNDCLASS)); + wc.hInstance = GetModuleHandle(NULL); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = "GLEW"; + if (0 == RegisterClass(&wc)) return GL_TRUE; + /* create window */ + wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL); + if (NULL == wnd) return GL_TRUE; + /* get the device context */ + dc = GetDC(wnd); + if (NULL == dc) return GL_TRUE; + /* find pixel format */ + ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); + if (*pixelformat == -1) /* find default */ + { + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + *pixelformat = ChoosePixelFormat(dc, &pfd); + if (*pixelformat == 0) return GL_TRUE; + } + /* set the pixel format for the dc */ + if (FALSE == SetPixelFormat(dc, *pixelformat, &pfd)) return GL_TRUE; + /* create rendering context */ + rc = wglCreateContext(dc); + if (NULL == rc) return GL_TRUE; + if (FALSE == wglMakeCurrent(dc, rc)) return GL_TRUE; + return GL_FALSE; +} + +void glewDestroyContext () +{ + if (NULL != rc) wglMakeCurrent(NULL, NULL); + if (NULL != rc) wglDeleteContext(wglGetCurrentContext()); + if (NULL != wnd && NULL != dc) ReleaseDC(wnd, dc); + if (NULL != wnd) DestroyWindow(wnd); + UnregisterClass("GLEW", GetModuleHandle(NULL)); +} + +/* ------------------------------------------------------------------------ */ + +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + +#include + +AGLContext ctx, octx; + +GLboolean glewCreateContext () +{ + int attrib[] = { AGL_RGBA, AGL_NONE }; + AGLPixelFormat pf; + /*int major, minor; + SetPortWindowPort(wnd); + aglGetVersion(&major, &minor); + fprintf(stderr, "GL %d.%d\n", major, minor);*/ + pf = aglChoosePixelFormat(NULL, 0, attrib); + if (NULL == pf) return GL_TRUE; + ctx = aglCreateContext(pf, NULL); + if (NULL == ctx || AGL_NO_ERROR != aglGetError()) return GL_TRUE; + aglDestroyPixelFormat(pf); + /*aglSetDrawable(ctx, GetWindowPort(wnd));*/ + octx = aglGetCurrentContext(); + if (NULL == aglSetCurrentContext(ctx)) return GL_TRUE; + return GL_FALSE; +} + +void glewDestroyContext () +{ + aglSetCurrentContext(octx); + if (NULL != ctx) aglDestroyContext(ctx); +} + +/* ------------------------------------------------------------------------ */ + +#else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ + +Display* dpy = NULL; +XVisualInfo* vi = NULL; +XVisualInfo* vis = NULL; +GLXContext ctx = NULL; +Window wnd = 0; +Colormap cmap = 0; + +GLboolean glewCreateContext (const char* display, int* visual) +{ + int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; + int erb, evb; + XSetWindowAttributes swa; + /* open display */ + dpy = XOpenDisplay(display); + if (NULL == dpy) return GL_TRUE; + /* query for glx */ + if (!glXQueryExtension(dpy, &erb, &evb)) return GL_TRUE; + /* choose visual */ + if (*visual == -1) + { + vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrib); + if (NULL == vi) return GL_TRUE; + *visual = (int)XVisualIDFromVisual(vi->visual); + } + else + { + int n_vis, i; + vis = XGetVisualInfo(dpy, 0, NULL, &n_vis); + for (i=0; iscreen), 0, 0, 1, 1, 1, 0, 0);*/ + cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); + swa.border_pixel = 0; + swa.colormap = cmap; + wnd = XCreateWindow(dpy, RootWindow(dpy, vi->screen), + 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap, &swa); + /* make context current */ + if (!glXMakeCurrent(dpy, wnd, ctx)) return GL_TRUE; + return GL_FALSE; +} + +void glewDestroyContext () +{ + if (NULL != dpy && NULL != ctx) glXDestroyContext(dpy, ctx); + if (NULL != dpy && 0 != wnd) XDestroyWindow(dpy, wnd); + if (NULL != dpy && 0 != cmap) XFreeColormap(dpy, cmap); + if (NULL != vis) + XFree(vis); + else if (NULL != vi) + XFree(vi); + if (NULL != dpy) XCloseDisplay(dpy); +} + +#endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ diff --git a/WDL/lice/glew/src/visualinfo.c b/WDL/lice/glew/src/visualinfo.c new file mode 100644 index 00000000..98c391c0 --- /dev/null +++ b/WDL/lice/glew/src/visualinfo.c @@ -0,0 +1,1173 @@ +/* +** visualinfo.c +** +** Copyright (C) Nate Robins, 1997 +** Michael Wimmer, 1999 +** Milan Ikits, 2002-2008 +** +** visualinfo is a small utility that displays all available visuals, +** aka. pixelformats, in an OpenGL system along with renderer version +** information. It shows a table of all the visuals that support OpenGL +** along with their capabilities. The format of the table is similar to +** that of glxinfo on Unix systems: +** +** visual ~= pixel format descriptor +** id = visual id (integer from 1 - max visuals) +** tp = type (wn: window, pb: pbuffer, wp: window & pbuffer, bm: bitmap) +** ac = acceleration (ge: generic, fu: full, no: none) +** fm = format (i: integer, f: float, c: color index) +** db = double buffer (y = yes) +** sw = swap method (x: exchange, c: copy, u: undefined) +** st = stereo (y = yes) +** sz = total # bits +** r = # bits of red +** g = # bits of green +** b = # bits of blue +** a = # bits of alpha +** axbf = # aux buffers +** dpth = # bits of depth +** stcl = # bits of stencil +*/ + +#include +#include +#include +#include +#if defined(_WIN32) +#include +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) +#include +#else +#include +#endif + +#ifdef GLEW_MX +GLEWContext _glewctx; +# define glewGetContext() (&_glewctx) +# ifdef _WIN32 +WGLEWContext _wglewctx; +# define wglewGetContext() (&_wglewctx) +# elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +GLXEWContext _glxewctx; +# define glxewGetContext() (&_glxewctx) +# endif +#endif /* GLEW_MX */ + +typedef struct GLContextStruct +{ +#ifdef _WIN32 + HWND wnd; + HDC dc; + HGLRC rc; +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + AGLContext ctx, octx; +#else + Display* dpy; + XVisualInfo* vi; + GLXContext ctx; + Window wnd; + Colormap cmap; +#endif +} GLContext; + +void InitContext (GLContext* ctx); +GLboolean CreateContext (GLContext* ctx); +void DestroyContext (GLContext* ctx); +void VisualInfo (GLContext* ctx); +void PrintExtensions (const char* s); +GLboolean ParseArgs (int argc, char** argv); + +int showall = 0; +int displaystdout = 0; +int verbose = 0; +int drawableonly = 0; + +char* display = NULL; +int visual = -1; + +FILE* file = 0; +GLContext ctx; + +int +main (int argc, char** argv) +{ + GLenum err; + + /* ---------------------------------------------------------------------- */ + /* parse arguments */ + if (GL_TRUE == ParseArgs(argc-1, argv+1)) + { +#if defined(_WIN32) + fprintf(stderr, "Usage: visualinfo [-a] [-s] [-h] [-pf ]\n"); + fprintf(stderr, " -a: show all visuals\n"); + fprintf(stderr, " -s: display to stdout instead of visualinfo.txt\n"); + fprintf(stderr, " -pf : use given pixelformat\n"); + fprintf(stderr, " -h: this screen\n"); +#else + fprintf(stderr, "Usage: visualinfo [-h] [-display ] [-visual ]\n"); + fprintf(stderr, " -h: this screen\n"); + fprintf(stderr, " -display : use given display\n"); + fprintf(stderr, " -visual : use given visual\n"); +#endif + return 1; + } + + /* ---------------------------------------------------------------------- */ + /* create OpenGL rendering context */ + InitContext(&ctx); + if (GL_TRUE == CreateContext(&ctx)) + { + fprintf(stderr, "Error: CreateContext failed\n"); + DestroyContext(&ctx); + return 1; + } + + /* ---------------------------------------------------------------------- */ + /* initialize GLEW */ + glewExperimental = GL_TRUE; +#ifdef GLEW_MX + err = glewContextInit(glewGetContext()); +# ifdef _WIN32 + err = err || wglewContextInit(wglewGetContext()); +# elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + err = err || glxewContextInit(glxewGetContext()); +# endif +#else + err = glewInit(); +#endif + if (GLEW_OK != err) + { + fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); + DestroyContext(&ctx); + return 1; + } + + /* ---------------------------------------------------------------------- */ + /* open file */ +#if defined(_WIN32) + if (!displaystdout) + file = fopen("visualinfo.txt", "w"); + if (file == NULL) + file = stdout; +#else + file = stdout; +#endif + + /* ---------------------------------------------------------------------- */ + /* output header information */ + /* OpenGL extensions */ + fprintf(file, "OpenGL vendor string: %s\n", glGetString(GL_VENDOR)); + fprintf(file, "OpenGL renderer string: %s\n", glGetString(GL_RENDERER)); + fprintf(file, "OpenGL version string: %s\n", glGetString(GL_VERSION)); + fprintf(file, "OpenGL extensions (GL_): \n"); + PrintExtensions((char*)glGetString(GL_EXTENSIONS)); + /* GLU extensions */ + fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION)); + fprintf(file, "GLU extensions (GLU_): \n"); + PrintExtensions((char*)gluGetString(GLU_EXTENSIONS)); + + /* ---------------------------------------------------------------------- */ + /* extensions string */ +#if defined(_WIN32) + /* WGL extensions */ + if (WGLEW_ARB_extensions_string || WGLEW_EXT_extensions_string) + { + fprintf(file, "WGL extensions (WGL_): \n"); + PrintExtensions(wglGetExtensionsStringARB ? + (char*)wglGetExtensionsStringARB(ctx.dc) : + (char*)wglGetExtensionsStringEXT()); + } +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + +#else + /* GLX extensions */ + fprintf(file, "GLX extensions (GLX_): \n"); + PrintExtensions(glXQueryExtensionsString(glXGetCurrentDisplay(), + DefaultScreen(glXGetCurrentDisplay()))); +#endif + + /* ---------------------------------------------------------------------- */ + /* enumerate all the formats */ + VisualInfo(&ctx); + + /* ---------------------------------------------------------------------- */ + /* release resources */ + DestroyContext(&ctx); + if (file != stdout) + fclose(file); + return 0; +} + +/* do the magic to separate all extensions with comma's, except + for the last one that _may_ terminate in a space. */ +void PrintExtensions (const char* s) +{ + char t[80]; + int i=0; + char* p=0; + + t[79] = '\0'; + while (*s) + { + t[i++] = *s; + if(*s == ' ') + { + if (*(s+1) != '\0') { + t[i-1] = ','; + t[i] = ' '; + p = &t[i++]; + } + else /* zoinks! last one terminated in a space! */ + { + t[i-1] = '\0'; + } + } + if(i > 80 - 5) + { + *p = t[i] = '\0'; + fprintf(file, " %s\n", t); + p++; + i = (int)strlen(p); + strcpy(t, p); + } + s++; + } + t[i] = '\0'; + fprintf(file, " %s.\n", t); +} + +/* ---------------------------------------------------------------------- */ + +#if defined(_WIN32) + +void +VisualInfoARB (GLContext* ctx) +{ + int attrib[32], value[32], n_attrib, n_pbuffer=0, n_float=0; + int i, pf, maxpf; + unsigned int c; + + /* to get pbuffer capable pixel formats */ + attrib[0] = WGL_DRAW_TO_PBUFFER_ARB; + attrib[1] = GL_TRUE; + attrib[2] = 0; + wglChoosePixelFormatARB(ctx->dc, attrib, 0, 1, &pf, &c); + /* query number of pixel formats */ + attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; + wglGetPixelFormatAttribivARB(ctx->dc, 0, 0, 1, attrib, value); + maxpf = value[0]; + for (i=0; i<32; i++) + value[i] = 0; + + attrib[0] = WGL_SUPPORT_OPENGL_ARB; + attrib[1] = WGL_DRAW_TO_WINDOW_ARB; + attrib[2] = WGL_DRAW_TO_BITMAP_ARB; + attrib[3] = WGL_ACCELERATION_ARB; + /* WGL_NO_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB */ + attrib[4] = WGL_SWAP_METHOD_ARB; + /* WGL_SWAP_EXCHANGE_ARB, WGL_SWAP_COPY_ARB, WGL_SWAP_UNDEFINED_ARB */ + attrib[5] = WGL_DOUBLE_BUFFER_ARB; + attrib[6] = WGL_STEREO_ARB; + attrib[7] = WGL_PIXEL_TYPE_ARB; + /* WGL_TYPE_RGBA_ARB, WGL_TYPE_COLORINDEX_ARB, + WGL_TYPE_RGBA_FLOAT_ATI (WGL_ATI_pixel_format_float) */ + /* Color buffer information */ + attrib[8] = WGL_COLOR_BITS_ARB; + attrib[9] = WGL_RED_BITS_ARB; + attrib[10] = WGL_GREEN_BITS_ARB; + attrib[11] = WGL_BLUE_BITS_ARB; + attrib[12] = WGL_ALPHA_BITS_ARB; + /* Accumulation buffer information */ + attrib[13] = WGL_ACCUM_BITS_ARB; + attrib[14] = WGL_ACCUM_RED_BITS_ARB; + attrib[15] = WGL_ACCUM_GREEN_BITS_ARB; + attrib[16] = WGL_ACCUM_BLUE_BITS_ARB; + attrib[17] = WGL_ACCUM_ALPHA_BITS_ARB; + /* Depth, stencil, and aux buffer information */ + attrib[18] = WGL_DEPTH_BITS_ARB; + attrib[19] = WGL_STENCIL_BITS_ARB; + attrib[20] = WGL_AUX_BUFFERS_ARB; + /* Layer information */ + attrib[21] = WGL_NUMBER_OVERLAYS_ARB; + attrib[22] = WGL_NUMBER_UNDERLAYS_ARB; + attrib[23] = WGL_SWAP_LAYER_BUFFERS_ARB; + attrib[24] = WGL_SAMPLES_ARB; + attrib[25] = WGL_SUPPORT_GDI_ARB; + n_attrib = 26; + if (WGLEW_ARB_pbuffer) + { + attrib[n_attrib] = WGL_DRAW_TO_PBUFFER_ARB; + n_pbuffer = n_attrib; + n_attrib++; + } + if (WGLEW_NV_float_buffer) + { + attrib[n_attrib] = WGL_FLOAT_COMPONENTS_NV; + n_float = n_attrib; + n_attrib++; + } + + if (!verbose) + { + /* print table header */ + fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); + fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); + fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); + fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); + /* loop through all the pixel formats */ + for(i = 1; i <= maxpf; i++) + { + wglGetPixelFormatAttribivARB(ctx->dc, i, 0, n_attrib, attrib, value); + /* only describe this format if it supports OpenGL */ + if (!value[0]) continue; + /* by default show only fully accelerated window or pbuffer capable visuals */ + if (!showall + && ((value[2] && !value[1]) + || (!WGLEW_ARB_pbuffer || !value[n_pbuffer]) + || (value[3] != WGL_FULL_ACCELERATION_ARB))) continue; + /* print out the information for this visual */ + /* visual id */ + fprintf(file, " |% 4d | ", i); + /* visual type */ + if (value[1]) + { + if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "wp "); + else fprintf(file, "wn "); + } + else + { + if (value[2]) fprintf(file, "bm "); + else if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "pb "); + } + /* acceleration */ + fprintf(file, "%s ", value[3] == WGL_FULL_ACCELERATION_ARB ? "fu" : + value[3] == WGL_GENERIC_ACCELERATION_ARB ? "ge" : + value[3] == WGL_NO_ACCELERATION_ARB ? "no" : ". "); + /* gdi support */ + fprintf(file, " %c ", value[25] ? 'y' : '.'); + /* format */ + if (WGLEW_NV_float_buffer && value[n_float]) fprintf(file, " f "); + else if (WGLEW_ATI_pixel_format_float && value[7] == WGL_TYPE_RGBA_FLOAT_ATI) fprintf(file, " f "); + else if (value[7] == WGL_TYPE_RGBA_ARB) fprintf(file, " i "); + else if (value[7] == WGL_TYPE_COLORINDEX_ARB) fprintf(file, " c "); + /* double buffer */ + fprintf(file, " %c ", value[5] ? 'y' : '.'); + /* swap method */ + if (value[4] == WGL_SWAP_EXCHANGE_ARB) fprintf(file, " x "); + else if (value[4] == WGL_SWAP_COPY_ARB) fprintf(file, " c "); + else if (value[4] == WGL_SWAP_UNDEFINED_ARB) fprintf(file, " . "); + else fprintf(file, " . "); + /* stereo */ + fprintf(file, " %c ", value[6] ? 'y' : '.'); + /* multisample */ + if (value[24] > 0) + fprintf(file, "%2d | ", value[24]); + else + fprintf(file, " . | "); + /* color size */ + if (value[8]) fprintf(file, "%3d ", value[8]); + else fprintf(file, " . "); + /* red */ + if (value[9]) fprintf(file, "%2d ", value[9]); + else fprintf(file, " . "); + /* green */ + if (value[10]) fprintf(file, "%2d ", value[10]); + else fprintf(file, " . "); + /* blue */ + if (value[11]) fprintf(file, "%2d ", value[11]); + else fprintf(file, " . "); + /* alpha */ + if (value[12]) fprintf(file, "%2d | ", value[12]); + else fprintf(file, " . | "); + /* aux buffers */ + if (value[20]) fprintf(file, "%2d ", value[20]); + else fprintf(file, " . "); + /* depth */ + if (value[18]) fprintf(file, "%2d ", value[18]); + else fprintf(file, " . "); + /* stencil */ + if (value[19]) fprintf(file, "%2d | ", value[19]); + else fprintf(file, " . | "); + /* accum size */ + if (value[13]) fprintf(file, "%3d ", value[13]); + else fprintf(file, " . "); + /* accum red */ + if (value[14]) fprintf(file, "%2d ", value[14]); + else fprintf(file, " . "); + /* accum green */ + if (value[15]) fprintf(file, "%2d ", value[15]); + else fprintf(file, " . "); + /* accum blue */ + if (value[16]) fprintf(file, "%2d ", value[16]); + else fprintf(file, " . "); + /* accum alpha */ + if (value[17]) fprintf(file, "%2d | ", value[17]); + else fprintf(file, " . | "); + /* overlay */ + if (value[21]) fprintf(file, "%2d ", value[21]); + else fprintf(file, " . "); + /* underlay */ + if (value[22]) fprintf(file, "%2d ", value[22]); + else fprintf(file, " . "); + /* layer swap */ + if (value[23]) fprintf(file, "y "); + else fprintf(file, " . "); + fprintf(file, "|\n"); + } + /* print table footer */ + fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); + fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); + fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); + fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); + } + else /* verbose */ + { +#if 0 + fprintf(file, "\n"); + /* loop through all the pixel formats */ + for(i = 1; i <= maxpf; i++) + { + DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + /* only describe this format if it supports OpenGL */ + if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) + || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; + fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, + pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); + fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); + fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); + fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); + fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); + fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); + fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); + fprintf(file, " Opaque.\n"); + } +#endif + } +} + +void +VisualInfoGDI (GLContext* ctx) +{ + int i, maxpf; + PIXELFORMATDESCRIPTOR pfd; + + /* calling DescribePixelFormat() with NULL pfd (!!!) return maximum + number of pixel formats */ + maxpf = DescribePixelFormat(ctx->dc, 1, 0, NULL); + + if (!verbose) + { + fprintf(file, "-----------------------------------------------------------------------------\n"); + fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); + fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); + fprintf(file, "-----------------------------------------------------------------------------\n"); + + /* loop through all the pixel formats */ + for(i = 1; i <= maxpf; i++) + { + DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + /* only describe this format if it supports OpenGL */ + if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) + || (drawableonly && (pfd.dwFlags & PFD_DRAW_TO_BITMAP))) continue; + /* other criteria could be tested here for actual pixel format + choosing in an application: + + for (...each pixel format...) { + if (pfd.dwFlags & PFD_SUPPORT_OPENGL && + pfd.dwFlags & PFD_DOUBLEBUFFER && + pfd.cDepthBits >= 24 && + pfd.cColorBits >= 24) + { + goto found; + } + } + ... not found so exit ... + found: + ... found so use it ... + */ + /* print out the information for this pixel format */ + fprintf(file, "0x%02x ", i); + fprintf(file, "%3d ", pfd.cColorBits); + if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) fprintf(file, "wn "); + else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) fprintf(file, "bm "); + else fprintf(file, "pb "); + /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ + fprintf(file, " . "); + fprintf(file, "%3d ", pfd.cColorBits); + /* bReserved field indicates number of over/underlays */ + if(pfd.bReserved) fprintf(file, " %d ", pfd.bReserved); + else fprintf(file, " . "); + fprintf(file, " %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + fprintf(file, "%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + fprintf(file, " %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.'); + /* added: */ + fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_FORMAT ? 'y' : '.'); + fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_ACCELERATED ? 'y' : '.'); + if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) + fprintf(file, "%2d ", pfd.cRedBits); + else fprintf(file, " . "); + if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) + fprintf(file, "%2d ", pfd.cGreenBits); + else fprintf(file, " . "); + if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) + fprintf(file, "%2d ", pfd.cBlueBits); + else fprintf(file, " . "); + if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) + fprintf(file, "%2d ", pfd.cAlphaBits); + else fprintf(file, " . "); + if(pfd.cAuxBuffers) fprintf(file, "%2d ", pfd.cAuxBuffers); + else fprintf(file, " . "); + if(pfd.cDepthBits) fprintf(file, "%2d ", pfd.cDepthBits); + else fprintf(file, " . "); + if(pfd.cStencilBits) fprintf(file, "%2d ", pfd.cStencilBits); + else fprintf(file, " . "); + if(pfd.cAccumBits) fprintf(file, "%3d ", pfd.cAccumBits); + else fprintf(file, " . "); + if(pfd.cAccumRedBits) fprintf(file, "%2d ", pfd.cAccumRedBits); + else fprintf(file, " . "); + if(pfd.cAccumGreenBits) fprintf(file, "%2d ", pfd.cAccumGreenBits); + else fprintf(file, " . "); + if(pfd.cAccumBlueBits) fprintf(file, "%2d ", pfd.cAccumBlueBits); + else fprintf(file, " . "); + if(pfd.cAccumAlphaBits) fprintf(file, "%2d ", pfd.cAccumAlphaBits); + else fprintf(file, " . "); + /* no multisample in win32 */ + fprintf(file, " . .\n"); + } + /* print table footer */ + fprintf(file, "-----------------------------------------------------------------------------\n"); + fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); + fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); + fprintf(file, "-----------------------------------------------------------------------------\n"); + } + else /* verbose */ + { + fprintf(file, "\n"); + /* loop through all the pixel formats */ + for(i = 1; i <= maxpf; i++) + { + DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + /* only describe this format if it supports OpenGL */ + if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) + || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; + fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, + pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); + fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%ld stereo=%ld\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); + fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); + fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); + fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); + fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); + fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); + fprintf(file, " Opaque.\n"); + } + } +} + +void +VisualInfo (GLContext* ctx) +{ + if (WGLEW_ARB_pixel_format) + VisualInfoARB(ctx); + else + VisualInfoGDI(ctx); +} + +/* ---------------------------------------------------------------------- */ + +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + +void +VisualInfo (GLContext* ctx) +{ +/* + int attrib[] = { AGL_RGBA, AGL_NONE }; + AGLPixelFormat pf; + GLint value; + pf = aglChoosePixelFormat(NULL, 0, attrib); + while (pf != NULL) + { + aglDescribePixelFormat(pf, GL_RGBA, &value); + fprintf(stderr, "%d\n", value); + pf = aglNextPixelFormat(pf); + } +*/ +} + +#else /* GLX */ + +void +VisualInfo (GLContext* ctx) +{ + int n_fbc; + GLXFBConfig* fbc; + int value, ret, i; + + fbc = glXGetFBConfigs(ctx->dpy, DefaultScreen(ctx->dpy), &n_fbc); + + if (fbc) + { + if (!verbose) + { + /* print table header */ + fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); + fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); + fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); + fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); + /* loop through all the fbcs */ + for (i=0; idpy, fbc[i], GLX_FBCONFIG_ID, &value); + if (ret != Success) + { + fprintf(file, "| ? |"); + } + else + { + fprintf(file, " |% 4d | ", value); + } + /* visual type */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DRAWABLE_TYPE, &value); + if (ret != Success) + { + fprintf(file, " ? "); + } + else + { + if (value & GLX_WINDOW_BIT) + { + if (value & GLX_PBUFFER_BIT) + { + fprintf(file, "wp "); + } + else + { + fprintf(file, "wn "); + } + } + else + { + if (value & GLX_PBUFFER_BIT) + { + fprintf(file, "pb "); + } + else if (value & GLX_PIXMAP_BIT) + { + fprintf(file, "pm "); + } + else + { + fprintf(file, " ? "); + } + } + } + /* x renderable */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_RENDERABLE, &value); + if (ret != Success) + { + fprintf(file, " ? "); + } + else + { + fprintf(file, value ? " y " : " n "); + } + /* class */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_VISUAL_TYPE, &value); + if (ret != Success) + { + fprintf(file, " ? "); + } + else + { + if (GLX_TRUE_COLOR == value) + fprintf(file, "tc "); + else if (GLX_DIRECT_COLOR == value) + fprintf(file, "dc "); + else if (GLX_PSEUDO_COLOR == value) + fprintf(file, "pc "); + else if (GLX_STATIC_COLOR == value) + fprintf(file, "sc "); + else if (GLX_GRAY_SCALE == value) + fprintf(file, "gs "); + else if (GLX_STATIC_GRAY == value) + fprintf(file, "sg "); + else if (GLX_X_VISUAL_TYPE == value) + fprintf(file, " . "); + else + fprintf(file, " ? "); + } + /* format */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RENDER_TYPE, &value); + if (ret != Success) + { + fprintf(file, " ? "); + } + else + { + if (GLXEW_NV_float_buffer) + { + int ret2, value2; + ret2 = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_FLOAT_COMPONENTS_NV, &value2); + if (Success == ret2 && GL_TRUE == value2) + { + fprintf(file, " f "); + } + else if (value & GLX_RGBA_BIT) + fprintf(file, " i "); + else if (value & GLX_COLOR_INDEX_BIT) + fprintf(file, " c "); + else + fprintf(file, " ? "); + } + else + { + if (value & GLX_RGBA_FLOAT_ATI_BIT) + fprintf(file, " f "); + else if (value & GLX_RGBA_BIT) + fprintf(file, " i "); + else if (value & GLX_COLOR_INDEX_BIT) + fprintf(file, " c "); + else + fprintf(file, " ? "); + } + } + /* double buffer */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DOUBLEBUFFER, &value); + fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); + /* stereo */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STEREO, &value); + fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); + /* level */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_LEVEL, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + fprintf(file, "%2d ", value); + } + /* transparency */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_TRANSPARENT_TYPE, &value); + if (Success != ret) + { + fprintf(file, " ? | "); + } + else + { + if (GLX_TRANSPARENT_RGB == value) + fprintf(file, " r | "); + else if (GLX_TRANSPARENT_INDEX == value) + fprintf(file, " i | "); + else if (GLX_NONE == value) + fprintf(file, " . | "); + else + fprintf(file, " ? | "); + } + /* color size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BUFFER_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%3d ", value); + else + fprintf(file, " . "); + } + /* red size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RED_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* green size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_GREEN_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* blue size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BLUE_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* alpha size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ALPHA_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? | "); + } + else + { + if (value) + fprintf(file, "%2d | ", value); + else + fprintf(file, " . | "); + } + /* aux buffers */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_AUX_BUFFERS, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* depth size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DEPTH_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* stencil size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STENCIL_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? | "); + } + else + { + if (value) + fprintf(file, "%2d | ", value); + else + fprintf(file, " . | "); + } + /* accum red size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_RED_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* accum green size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_GREEN_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* accum blue size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_BLUE_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + if (value) + fprintf(file, "%2d ", value); + else + fprintf(file, " . "); + } + /* accum alpha size */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_ALPHA_SIZE, &value); + if (Success != ret) + { + fprintf(file, " ? | "); + } + else + { + if (value) + fprintf(file, "%2d | ", value); + else + fprintf(file, " . | "); + } + /* multisample */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLES, &value); + if (Success != ret) + { + fprintf(file, " ? "); + } + else + { + fprintf(file, "%2d ", value); + } + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLE_BUFFERS, &value); + if (Success != ret) + { + fprintf(file, " ? | "); + } + else + { + fprintf(file, "%2d | ", value); + } + /* caveat */ + ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_CONFIG_CAVEAT, &value); + if (Success != ret) + { + fprintf(file, "???? |"); + } + else + { + if (GLX_NONE == value) + fprintf(file, "none |\n"); + else if (GLX_SLOW_CONFIG == value) + fprintf(file, "slow |\n"); + else if (GLX_NON_CONFORMANT_CONFIG == value) + fprintf(file, "ncft |\n"); + else + fprintf(file, "???? |\n"); + } + } + /* print table footer */ + fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); + fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); + fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); + fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); + } + } +} + +#endif + +/* ------------------------------------------------------------------------ */ + +#if defined(_WIN32) + +void InitContext (GLContext* ctx) +{ + ctx->wnd = NULL; + ctx->dc = NULL; + ctx->rc = NULL; +} + +GLboolean CreateContext (GLContext* ctx) +{ + WNDCLASS wc; + PIXELFORMATDESCRIPTOR pfd; + /* check for input */ + if (NULL == ctx) return GL_TRUE; + /* register window class */ + ZeroMemory(&wc, sizeof(WNDCLASS)); + wc.hInstance = GetModuleHandle(NULL); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = "GLEW"; + if (0 == RegisterClass(&wc)) return GL_TRUE; + /* create window */ + ctx->wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, + GetModuleHandle(NULL), NULL); + if (NULL == ctx->wnd) return GL_TRUE; + /* get the device context */ + ctx->dc = GetDC(ctx->wnd); + if (NULL == ctx->dc) return GL_TRUE; + /* find pixel format */ + ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); + if (visual == -1) /* find default */ + { + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + visual = ChoosePixelFormat(ctx->dc, &pfd); + if (0 == visual) return GL_TRUE; + } + /* set the pixel format for the dc */ + if (FALSE == SetPixelFormat(ctx->dc, visual, &pfd)) return GL_TRUE; + /* create rendering context */ + ctx->rc = wglCreateContext(ctx->dc); + if (NULL == ctx->rc) return GL_TRUE; + if (FALSE == wglMakeCurrent(ctx->dc, ctx->rc)) return GL_TRUE; + return GL_FALSE; +} + +void DestroyContext (GLContext* ctx) +{ + if (NULL == ctx) return; + if (NULL != ctx->rc) wglMakeCurrent(NULL, NULL); + if (NULL != ctx->rc) wglDeleteContext(wglGetCurrentContext()); + if (NULL != ctx->wnd && NULL != ctx->dc) ReleaseDC(ctx->wnd, ctx->dc); + if (NULL != ctx->wnd) DestroyWindow(ctx->wnd); + UnregisterClass("GLEW", GetModuleHandle(NULL)); +} + +/* ------------------------------------------------------------------------ */ + +#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) + +void InitContext (GLContext* ctx) +{ + ctx->ctx = NULL; + ctx->octx = NULL; +} + +GLboolean CreateContext (GLContext* ctx) +{ + int attrib[] = { AGL_RGBA, AGL_NONE }; + AGLPixelFormat pf; + /* check input */ + if (NULL == ctx) return GL_TRUE; + /*int major, minor; + SetPortWindowPort(wnd); + aglGetVersion(&major, &minor); + fprintf(stderr, "GL %d.%d\n", major, minor);*/ + pf = aglChoosePixelFormat(NULL, 0, attrib); + if (NULL == pf) return GL_TRUE; + ctx->ctx = aglCreateContext(pf, NULL); + if (NULL == ctx->ctx || AGL_NO_ERROR != aglGetError()) return GL_TRUE; + aglDestroyPixelFormat(pf); + /*aglSetDrawable(ctx, GetWindowPort(wnd));*/ + ctx->octx = aglGetCurrentContext(); + if (NULL == aglSetCurrentContext(ctx->ctx)) return GL_TRUE; + return GL_FALSE; +} + +void DestroyContext (GLContext* ctx) +{ + if (NULL == ctx) return; + aglSetCurrentContext(ctx->octx); + if (NULL != ctx->ctx) aglDestroyContext(ctx->ctx); +} + +/* ------------------------------------------------------------------------ */ + +#else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ + +void InitContext (GLContext* ctx) +{ + ctx->dpy = NULL; + ctx->vi = NULL; + ctx->ctx = NULL; + ctx->wnd = 0; + ctx->cmap = 0; +} + +GLboolean CreateContext (GLContext* ctx) +{ + int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; + int erb, evb; + XSetWindowAttributes swa; + /* check input */ + if (NULL == ctx) return GL_TRUE; + /* open display */ + ctx->dpy = XOpenDisplay(display); + if (NULL == ctx->dpy) return GL_TRUE; + /* query for glx */ + if (!glXQueryExtension(ctx->dpy, &erb, &evb)) return GL_TRUE; + /* choose visual */ + ctx->vi = glXChooseVisual(ctx->dpy, DefaultScreen(ctx->dpy), attrib); + if (NULL == ctx->vi) return GL_TRUE; + /* create context */ + ctx->ctx = glXCreateContext(ctx->dpy, ctx->vi, None, True); + if (NULL == ctx->ctx) return GL_TRUE; + /* create window */ + /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ + ctx->cmap = XCreateColormap(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), + ctx->vi->visual, AllocNone); + swa.border_pixel = 0; + swa.colormap = ctx->cmap; + ctx->wnd = XCreateWindow(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), + 0, 0, 1, 1, 0, ctx->vi->depth, InputOutput, ctx->vi->visual, + CWBorderPixel | CWColormap, &swa); + /* make context current */ + if (!glXMakeCurrent(ctx->dpy, ctx->wnd, ctx->ctx)) return GL_TRUE; + return GL_FALSE; +} + +void DestroyContext (GLContext* ctx) +{ + if (NULL != ctx->dpy && NULL != ctx->ctx) glXDestroyContext(ctx->dpy, ctx->ctx); + if (NULL != ctx->dpy && 0 != ctx->wnd) XDestroyWindow(ctx->dpy, ctx->wnd); + if (NULL != ctx->dpy && 0 != ctx->cmap) XFreeColormap(ctx->dpy, ctx->cmap); + if (NULL != ctx->vi) XFree(ctx->vi); + if (NULL != ctx->dpy) XCloseDisplay(ctx->dpy); +} + +#endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ + +GLboolean ParseArgs (int argc, char** argv) +{ + int p = 0; + while (p < argc) + { +#if defined(_WIN32) + if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) + { + if (++p >= argc) return GL_TRUE; + display = NULL; + visual = strtol(argv[p], NULL, 0); + } + else if (!strcmp(argv[p], "-a")) + { + showall = 1; + } + else if (!strcmp(argv[p], "-s")) + { + displaystdout = 1; + } + else if (!strcmp(argv[p], "-h")) + { + return GL_TRUE; + } + else + return GL_TRUE; +#else + if (!strcmp(argv[p], "-display")) + { + if (++p >= argc) return GL_TRUE; + display = argv[p]; + } + else if (!strcmp(argv[p], "-visual")) + { + if (++p >= argc) return GL_TRUE; + visual = (int)strtol(argv[p], NULL, 0); + } + else if (!strcmp(argv[p], "-h")) + { + return GL_TRUE; + } + else + return GL_TRUE; +#endif + p++; + } + return GL_FALSE; +} diff --git a/WDL/lice/lice.cpp b/WDL/lice/lice.cpp new file mode 100644 index 00000000..839a7ef5 --- /dev/null +++ b/WDL/lice/lice.cpp @@ -0,0 +1,2173 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice.cpp (LICE core processing) + See lice.h for license and other information +*/ + + +#ifndef __LICE_CPP_IMPLEMENTED__ +#define __LICE_CPP_IMPLEMENTED__ + +#include "lice.h" +#include +#include // only included in case we need to debug with sprintf etc + +#include "lice_combine.h" +#include "lice_extended.h" + +#ifndef _WIN32 +#include "../swell/swell.h" +#endif + +_LICE_ImageLoader_rec *LICE_ImageLoader_list; + +LICE_pixel LICE_CombinePixels(LICE_pixel dest, LICE_pixel src, float alpha, int mode) +{ + int r = LICE_GETR(src); + int g = LICE_GETG(src); + int b = LICE_GETB(src); + int a = LICE_GETA(src); + int al = (int)(alpha*256.0f); + +#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)&dest,r, g, b, a, al) + __LICE_ACTION_SRCALPHA(mode, al,false); +#undef __LICE__ACTION + + return dest; +} + + +void LICE_CombinePixels2(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode) +{ +#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia) + __LICE_ACTION_SRCALPHA(mode, ia, false); +#undef __LICE__ACTION +} +void LICE_CombinePixels2Clamp(LICE_pixel *destptr, int r, int g, int b, int a, int ia, int mode) +{ +#define __LICE__ACTION(COMBFUNC) COMBFUNC::doPix((LICE_pixel_chan*)destptr,r, g, b, a, ia) + __LICE_ACTION_SRCALPHA(mode, ia, true); +#undef __LICE__ACTION +} + + +LICE_MemBitmap::LICE_MemBitmap(int w, int h, unsigned int linealign) +{ + m_allocsize=0; + m_fb=0; + m_width=0; + m_height=0; + m_linealign = linealign > 1 ? ((linealign & ~(linealign-1))-1) : 0; // force to be contiguous bits + if (m_linealign>16) m_linealign=16; + if (w||h) resize(w,h); +} + +LICE_MemBitmap::~LICE_MemBitmap() { free(m_fb); } + +bool LICE_MemBitmap::resize(int w, int h) +{ + if (w!=m_width||h!=m_height) + { +#ifdef DEBUG_TIGHT_ALLOC // dont enable for anything you want to be even remotely fast + free(m_fb); + m_fb = (LICE_pixel *)malloc((m_allocsize = ((w+m_linealign)&~m_linealign)*h*sizeof(LICE_pixel)) + LICE_MEMBITMAP_ALIGNAMT); + m_width=m_fb?w:0; + m_height=m_fb?h:0; + return true; +#endif + int sz=(((m_width=w)+m_linealign)&~m_linealign)*(m_height=h)*sizeof(LICE_pixel); + + if (sz<=0) { free(m_fb); m_fb=0; m_allocsize=0; } + else if (!m_fb) m_fb=(LICE_pixel*)malloc((m_allocsize=sz) + LICE_MEMBITMAP_ALIGNAMT); + else + { + if (sz>m_allocsize) + { + void *op=m_fb; + if (!(m_fb=(LICE_pixel*)realloc(m_fb,(m_allocsize=sz+sz/4)+LICE_MEMBITMAP_ALIGNAMT))) + { + free(op); + m_fb=(LICE_pixel*)malloc((m_allocsize=sz)+LICE_MEMBITMAP_ALIGNAMT); + } + } + } + if (!m_fb) {m_width=m_height=0; } + + return true; + } + return false; +} + + + +#ifndef _LICE_NO_SYSBITMAPS_ + +LICE_SysBitmap::LICE_SysBitmap(int w, int h) +{ + m_allocw=m_alloch=0; +#ifdef _WIN32 + m_dc = CreateCompatibleDC(NULL); + m_bitmap = 0; + m_oldbitmap = 0; +#else + m_dc=0; +#endif + m_bits=0; + m_width=m_height=0; + + resize(w,h); +} + + +LICE_SysBitmap::~LICE_SysBitmap() +{ +#ifdef _WIN32 + if (m_oldbitmap && m_dc) SelectObject(m_dc,m_oldbitmap); + if (m_bitmap) DeleteObject(m_bitmap); + if (m_dc) DeleteDC(m_dc); +#else + if (m_dc) + SWELL_DeleteGfxContext(m_dc); +#endif +} + +bool LICE_SysBitmap::resize(int w, int h) +{ +#ifdef _WIN32 + if (!m_dc) { m_width=m_height=0; m_bits=0; return false; } +#endif + + if (m_width==w && m_height == h) return false; + + m_width=w; + m_height=h; + +#ifndef DEBUG_TIGHT_ALLOC + // dont resize down bitmaps + if (w && h && w <= m_allocw && h <= m_alloch && m_bits) + { +#ifndef _WIN32 + if (isFlipped()) + { + m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc); + m_bits += (m_alloch-h)*m_allocw; + } +#endif + return true; + } +#endif//!DEBUG_TIGHT_ALLOC + + w = (w+3)&~3; // always keep backing store a multiple of 4px wide + + + m_allocw=w; + m_alloch=h; + +#ifdef _WIN32 + if (m_oldbitmap) + { + SelectObject(m_dc,m_oldbitmap); + m_oldbitmap=0; + } + if (m_bitmap) DeleteObject(m_bitmap); + m_bitmap=0; + m_bits=0; + + + if (!w || !h) return false; + + BITMAPINFO pbmInfo = {0,}; + pbmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmInfo.bmiHeader.biWidth = w; + pbmInfo.bmiHeader.biHeight = isFlipped()?h:-h; + pbmInfo.bmiHeader.biPlanes = 1; + pbmInfo.bmiHeader.biBitCount = sizeof(LICE_pixel)*8; + pbmInfo.bmiHeader.biCompression = BI_RGB; + m_bitmap = CreateDIBSection( NULL, &pbmInfo, DIB_RGB_COLORS, (void **)&m_bits, NULL, 0); + + if (m_bitmap) m_oldbitmap=SelectObject(m_dc, m_bitmap); + else { m_width=m_height=0; m_bits=0; } +#else + if (m_dc) SWELL_DeleteGfxContext(m_dc); + m_dc=0; + m_bits=0; + + if (!w || !h) return false; + + m_dc=SWELL_CreateMemContext(0,w,h); + if (!m_dc) { m_width=m_height=0; m_bits=0; } + else m_bits=(LICE_pixel*)SWELL_GetCtxFrameBuffer(m_dc); +#endif + + return true; +} + +#endif // _LICE_NO_SYSBITMAPS_ + + + +#ifndef LICE_NO_BLIT_SUPPORT +void LICE_Copy(LICE_IBitmap *dest, LICE_IBitmap *src) // resizes dest +{ + if (src&&dest) + { + dest->resize(src->getWidth(),src->getHeight()); + LICE_Blit(dest,src,0,0,NULL,1.0,LICE_BLIT_MODE_COPY); + } +} +#endif + +template class _LICE_Template_Blit0 // these always templated +{ + public: + static void solidBlitFAST(LICE_pixel *dest, int w, int h, + LICE_pixel color, + int dest_span) + { + while (h--) + { + LICE_pixel *pout=dest; + int n=w; + while (n--) + { + COMBFUNC::doPixFAST(pout,color); + ++pout; + } + dest+=dest_span; + } + } + + + + static void scaleBlitFAST(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, + int icurx, int icury, int idx, int idy, int clipright, int clipbottom, + int src_span, int dest_span) + { + LICE_pixel* destpx = (LICE_pixel*) dest; + int destpxspan = dest_span*sizeof(LICE_pixel_chan)/sizeof(LICE_pixel); + + //LICE_pixel* srcpx = (LICE_pixel*) src; + //int srcpxspan = src_span*sizeof(LICE_pixel_chan)/sizeof(LICE_pixel); + // todo cast inptr back to LICE_pixel + + while (h--) + { + int cury = icury/65536; + if (cury >= 0 && cury < clipbottom) + { + int curx=icurx; + LICE_pixel_chan *inptr=src + cury * src_span; + LICE_pixel* pout = destpx; + int n=w; + while (n--) + { + int offs=curx/65536; + if (offs>=0 && offs +#endif +class _LICE_Template_Blit1 // these controlled by LICE_FAVOR_SIZE_EXTREME +{ +#ifdef LICE_FAVOR_SIZE_EXTREME + #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); +#else + #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); +#endif + public: + static void solidBlit(LICE_pixel_chan *dest, int w, int h, + int ir, int ig, int ib, int ia, + int dest_span +#ifdef LICE_FAVOR_SIZE_EXTREME + , LICE_COMBINEFUNC combFunc +#endif + ) + { + while (h--) + { + LICE_pixel_chan *pout=dest; + int n=w; + while (n--) + { + DOPIX(pout,ir,ig,ib,ia,ia); + pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + } + dest+=dest_span; + } + } + static void gradBlit(LICE_pixel_chan *dest, int w, int h, + int ir, int ig, int ib, int ia, + int drdx, int dgdx, int dbdx, int dadx, + int drdy, int dgdy, int dbdy, int dady, + int dest_span +#ifdef LICE_FAVOR_SIZE_EXTREME + , LICE_COMBINEFUNC combFunc +#endif + ) + { + while (h--) + { + int r=ir,g=ig,b=ib,a=ia; + ir+=drdy; ig+=dgdy; ib+=dbdy; ia+=dady; + LICE_pixel_chan *pout=dest; + int n=w; + while (n--) + { + int ia=a/65536; + DOPIX(pout,r/65536,g/65536,b/65536,ia,ia); + pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + r+=drdx; g+=dgdx; b+=dbdx; a+=dadx; + } + dest+=dest_span; + } + } + +#undef DOPIX +}; + + +#ifndef LICE_FAVOR_SIZE +template +#endif +class _LICE_Template_Blit2 // these controlled by LICE_FAVOR_SIZE +{ +#ifdef LICE_FAVOR_SIZE + #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); +#else + #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); +#endif + + public: + + static void blit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, int src_span, int dest_span, int ia +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + ) + { + while (h-->0) + { + int n=w; + LICE_pixel_chan *pin=src; + LICE_pixel_chan *pout=dest; + while (n--) + { + + DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia); + + pin += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + } + dest+=dest_span; + src += src_span; + } + } + + // this is only designed for filtering down an image approx 2:1 to 4:1 or so.. it'll work (poortly) for higher, and for less it's crap too. + // probably need to redo it using linear interpolation of the filter coefficients, but bleh I'm gonna go play some call of duty + static void scaleBlitFilterDown(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, + int icurx, int icury, int idx, int idy, int clipright, int clipbottom, + int src_span, int dest_span, int ia, int *filter, int filt_start, int filtsz +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + + ) + { + + while (h--) + { + int cury = icury/65536; + int curx=icurx; + int n=w; + if (cury >= 0 && cury < clipbottom) + { + LICE_pixel_chan *inptr=src + (cury+filt_start) * src_span; + LICE_pixel_chan *pout=dest; + while (n--) + { + int offs=curx/65536; + if (offs>=0 && offs= clipbottom) break; + + if (ypos >= 0) + { + int xpos=offs + filt_start; + LICE_pixel_chan *pin = rdptr; + int fx=filtsz; + while (fx--) + { + int tsc = *scaletab++; + if (xpos >= 0 && xpos < clipright) + { + r+=pin[LICE_PIXEL_R]*tsc; + g+=pin[LICE_PIXEL_G]*tsc; + b+=pin[LICE_PIXEL_B]*tsc; + a+=pin[LICE_PIXEL_A]*tsc; + sc+=tsc; + } + xpos++; + pin+=sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + } + } + else scaletab += filtsz; + + ypos++; + rdptr+=src_span; + } + if (sc>0) + { + DOPIX(pout,r/sc,g/sc,b/sc,a/sc,ia); + } + } + + pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + curx+=idx; + } + } + dest+=dest_span; + icury+=idy; + } + } + static void scaleBlit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, + int icurx, int icury, int idx, int idy, int clipright, int clipbottom, + int src_span, int dest_span, int ia, int filtermode +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + + ) + { + + if (filtermode == LICE_BLIT_FILTER_BILINEAR) + { + while (h--) + { + int cury = icury/65536; + int yfrac=icury&65535; + int curx=icurx; + LICE_pixel_chan *inptr=src + cury * src_span; + LICE_pixel_chan *pout=dest; + int n=w; + if (cury >= 0 && cury < clipbottom-1) + { + while (n--) + { + int offs=curx/65536; + LICE_pixel_chan *pin = inptr + offs*sizeof(LICE_pixel); + if (offs>=0 && offs=0 && offs= 0 && cury < clipbottom) + { + int curx=icurx; + LICE_pixel_chan *inptr=src + cury * src_span; + LICE_pixel_chan *pout=dest; + int n=w; + while (n--) + { + int offs=curx/65536; + if (offs>=0 && offs +#endif +class _LICE_Template_Blit3 // stuff controlled by LICE_FAVOR_SPEED +{ +#ifndef LICE_FAVOR_SPEED + #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); +#else + #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); +#endif + + public: + + static void deltaBlit(LICE_pixel_chan *dest, LICE_pixel_chan *src, int w, int h, + int isrcx, int isrcy, int idsdx, int idtdx, int idsdy, int idtdy, + int idsdxdy, int idtdxdy, + int src_left, int src_top, int src_right, int src_bottom, + int src_span, int dest_span, int ia, int filtermode +#ifndef LICE_FAVOR_SPEED + , LICE_COMBINEFUNC combFunc +#endif + ) + { + if (filtermode == LICE_BLIT_FILTER_BILINEAR) + { + while (h--) + { + int thisx=isrcx; + int thisy=isrcy; + LICE_pixel_chan *pout=dest; + int n=w; + while (n--) + { + int cury = thisy/65536; + int curx = thisx/65536; + if (cury >= src_top && cury < src_bottom-1) + { + if (curx >= src_left && curx < src_right-1) + { + LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); + int r,g,b,a; + + __LICE_BilinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisx&65535,thisy&65535); + + DOPIX(pout,r,g,b,a,ia); + } + else if (curx==src_right-1) + { + + LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); + int r,g,b,a; + + __LICE_LinearFilterI(&r,&g,&b,&a,pin,pin+src_span,thisy&65535); + DOPIX(pout,r,g,b,a,ia); + } + } + else if (cury==src_bottom-1) + { + if (curx>=src_left && curx= src_top && cury < src_bottom && curx >= src_left && curx < src_right) + { + + LICE_pixel_chan *pin = src + cury * src_span + curx*sizeof(LICE_pixel); + + DOPIX(pout,pin[LICE_PIXEL_R],pin[LICE_PIXEL_G],pin[LICE_PIXEL_B],pin[LICE_PIXEL_A],ia); + } + + pout += sizeof(LICE_pixel)/sizeof(LICE_pixel_chan); + thisx+=idsdx; + thisy+=idtdx; + } + idsdx+=idsdxdy; + idtdx+=idtdxdy; + isrcx+=idsdy; + isrcy+=idtdy; + dest+=dest_span; + } + } + } + +#undef DOPIX +}; + +#ifndef LICE_NO_GRADIENT_SUPPORT + +void LICE_GradRect(LICE_IBitmap *dest, int dstx, int dsty, int dstw, int dsth, + float ir, float ig, float ib, float ia, + float drdx, float dgdx, float dbdx, float dadx, + float drdy, float dgdy, float dbdy, float dady, + int mode) +{ + if (!dest) return; + + ir*=255.0; ig*=255.0; ib*=255.0; ia*=256.0; + drdx*=255.0; dgdx*=255.0; dbdx*=255.0; dadx*=256.0; + drdy*=255.0; dgdy*=255.0; dbdy*=255.0; dady*=256.0; + // dont scale alpha + + // clip to output + if (dstx < 0) { ir-=dstx*drdx; ig-=dstx*dgdx; ib-=dstx*dbdx; ia-=dstx*dadx; dstw+=dstx; dstx=0; } + if (dsty < 0) + { + ir -= dsty*drdy; ig-=dsty*dgdy; ib -= dsty*dbdy; ia -= dsty*dady; + dsth += dsty; + dsty=0; + } + if (dstx+dstw > dest->getWidth()) dstw =(dest->getWidth()-dstx); + if (dsty+dsth > dest->getHeight()) dsth = (dest->getHeight()-dsty); + + if (dstw<1 || dsth<1) return; + + int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); + LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); + if (!pdest) return; + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else + { + pdest += dsty*dest_span; + } + pdest+=dstx*sizeof(LICE_pixel); +#define TOFIX(a) ((int)((a)*65536.0)) + + int iir=TOFIX(ir), iig=TOFIX(ig), iib=TOFIX(ib), iia=TOFIX(ia), idrdx=TOFIX(drdx),idgdx=TOFIX(dgdx),idbdx=TOFIX(dbdx),idadx=TOFIX(dadx), + idrdy=TOFIX(drdy), idgdy=TOFIX(dgdy), idbdy=TOFIX(dbdy), idady=TOFIX(dady); + + +#ifdef LICE_FAVOR_SIZE_EXTREME + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; +#else + + #define __LICE__ACTION(comb) _LICE_Template_Blit1::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span) +#endif + + // todo: could predict whether or not the colors will ever go out of 0.255 range and optimize + + if ((mode & LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY && iia==65536 && idady==0 && idadx == 0) + { + __LICE__ACTION(_LICE_CombinePixelsClobberClamp); + } + else + { + __LICE_ACTION_NOSRCALPHA(mode,256,true); + } + #undef __LICE__ACTION + +#ifdef LICE_FAVOR_SIZE_EXTREME + if (blitfunc) _LICE_Template_Blit1::gradBlit(pdest,dstw,dsth,iir,iig,iib,iia,idrdx,idgdx,idbdx,idadx,idrdy,idgdy,idbdy,idady,dest_span,blitfunc); +#endif + +#undef TOFIX +} + +#endif + + +#ifndef LICE_NO_BLIT_SUPPORT +void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch, float alpha, int mode) +{ + RECT r={srcx,srcy,srcx+srcw,srcy+srch}; + LICE_Blit(dest,src,dstx,dsty,&r,alpha,mode); +} + +void LICE_Blit(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, RECT *srcrect, float alpha, int mode) +{ + if (!dest || !src || !alpha) return; + + RECT sr={0,0,src->getWidth(),src->getHeight()}; + if (srcrect) + { + sr=*srcrect; + if (sr.left < 0) { dstx-=sr.left; sr.left=0; } + if (sr.top < 0) { dsty-=sr.top; sr.top=0; } + if (sr.right > src->getWidth()) sr.right=src->getWidth(); + if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight(); + } + + // clip to output + if (dstx < 0) { sr.left -= dstx; dstx=0; } + if (dsty < 0) { sr.top -= dsty; dsty=0; } + if (dstx+sr.right-sr.left > dest->getWidth()) sr.right = sr.left + (dest->getWidth()-dstx); + if (dsty+sr.bottom-sr.top > dest->getHeight()) sr.bottom = sr.top + (dest->getHeight()-dsty); + + // ignore blits that are 0 + if (sr.right <= sr.left || sr.bottom <= sr.top) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_BLIT_ACCEL)) + { + LICE_Ext_Blit_acceldata data(src, dstx, dsty, + sr.left, sr.top, + sr.right-sr.left, sr.bottom-sr.top, + alpha, mode); + if (dest->Extended(LICE_EXT_BLIT_ACCEL, &data)) return; + } +#endif + + + int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); + int src_span=src->getRowSpan()*sizeof(LICE_pixel); + LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); + LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); + if (!psrc || !pdest) return; + + if (src->isFlipped()) + { + psrc += (src->getHeight()-sr.top - 1)*src_span; + src_span=-src_span; + } + else psrc += sr.top*src_span; + psrc += sr.left*sizeof(LICE_pixel); + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else pdest += dsty*dest_span; + pdest+=dstx*sizeof(LICE_pixel); + + int i=sr.bottom-sr.top; + int cpsize=sr.right-sr.left; + + if ((mode&LICE_BLIT_MODE_MASK) >= LICE_BLIT_MODE_CHANCOPY && (mode&LICE_BLIT_MODE_MASK) < LICE_BLIT_MODE_CHANCOPY+0x10) + { + while (i-->0) + { + LICE_pixel_chan *o=pdest+((mode>>2)&3); + LICE_pixel_chan *in=psrc+(mode&3); + int a=cpsize; + while (a--) + { + *o=*in; + o+=sizeof(LICE_pixel); + in+=sizeof(LICE_pixel); + } + pdest+=dest_span; + psrc += src_span; + } + } + // special fast case for copy with no source alpha and alpha=1.0 or 0.5 + else if ((mode&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (alpha==1.0||alpha==0.5)) + { + if (alpha==0.5) + { + while (i-->0) + { + int a=cpsize; + LICE_pixel *rd = (LICE_pixel *)psrc; + LICE_pixel *wr = (LICE_pixel *)pdest; + while (a-->0) + { + *wr = ((*wr>>1)&0x7f7f7f7f)+((*rd++>>1)&0x7f7f7f7f); + wr++; + } + + pdest+=dest_span; + psrc += src_span; + } + } + else + { + while (i-->0) + { + memcpy(pdest,psrc,cpsize*sizeof(LICE_pixel)); + pdest+=dest_span; + psrc += src_span; + } + } + } + else + { + int ia=(int)(alpha*256.0); + #ifdef LICE_FAVOR_SIZE + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + #else + #define __LICE__ACTION(comb) _LICE_Template_Blit2::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia) + #endif + + __LICE_ACTION_SRCALPHA(mode,ia,false); + + #undef __LICE__ACTION + + #ifdef LICE_FAVOR_SIZE + if (blitfunc) _LICE_Template_Blit2::blit(pdest,psrc,cpsize,i,src_span,dest_span,ia,blitfunc); + #endif + } +} + +#endif + +#ifndef LICE_NO_BLUR_SUPPORT + +void LICE_Blur(LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int srcx, int srcy, int srcw, int srch) // src and dest can overlap, however it may look fudgy if they do +{ + if (!dest || !src) return; + + RECT sr={srcx,srcy,srcx+srcw,srcy+srch}; + if (sr.left < 0) sr.left=0; + if (sr.top < 0) sr.top=0; + if (sr.right > src->getWidth()) sr.right=src->getWidth(); + if (sr.bottom > src->getHeight()) sr.bottom = src->getHeight(); + + // clip to output + if (dstx < 0) { sr.left -= dstx; dstx=0; } + if (dsty < 0) { sr.top -= dsty; dsty=0; } + if (dstx+sr.right-sr.left > dest->getWidth()) sr.right = sr.left + (dest->getWidth()-dstx); + if (dsty+sr.bottom-sr.top > dest->getHeight()) sr.bottom = sr.top + (dest->getHeight()-dsty); + + // ignore blits that are smaller than 2x2 + if (sr.right <= sr.left+1 || sr.bottom <= sr.top+1) return; + + int dest_span=dest->getRowSpan(); + int src_span=src->getRowSpan(); + LICE_pixel *psrc = (LICE_pixel *)src->getBits(); + LICE_pixel *pdest = (LICE_pixel *)dest->getBits(); + if (!psrc || !pdest) return; + + if (src->isFlipped()) + { + psrc += (src->getHeight()-sr.top - 1)*src_span; + src_span=-src_span; + } + else psrc += sr.top*src_span; + psrc += sr.left; + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else pdest += dsty*dest_span; + pdest+=dstx; + + LICE_pixel *tmpbuf=NULL; + int w=sr.right-sr.left; + + // buffer to save the last unprocessed lines for the cases where blurring from a bitmap to itself + LICE_pixel turdbuf[2048]; + if (src==dest) + { + if (w <= sizeof(turdbuf)/sizeof(turdbuf[0])/2) tmpbuf=turdbuf; + else tmpbuf=(LICE_pixel*)malloc(w*2*sizeof(LICE_pixel)); + } + + int i; + for (i = sr.top; i < sr.bottom; i ++) + { + if (tmpbuf) + memcpy(tmpbuf+((i&1)?w:0),psrc,w*sizeof(LICE_pixel)); + + if (i==sr.top || i==sr.bottom-1) + { + LICE_pixel *psrc2=psrc+(i==sr.top ? src_span : -src_span); + + LICE_pixel lp; + + pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) + + LICE_PIXEL_QUARTER(psrc[1]) + + LICE_PIXEL_QUARTER(psrc2[0]); + int x; + for (x = 1; x < w-1; x ++) + { + LICE_pixel tp; + pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) + + LICE_PIXEL_QUARTER(psrc2[x]) + + LICE_PIXEL_EIGHTH(psrc[x+1]) + + LICE_PIXEL_EIGHTH(lp); + lp=tp; + } + pdest[x] = LICE_PIXEL_HALF(psrc[x]) + + LICE_PIXEL_QUARTER(lp) + + LICE_PIXEL_QUARTER(psrc2[x]); + } + else + { + LICE_pixel *psrc2=psrc-src_span; + LICE_pixel *psrc3=psrc+src_span; + if (tmpbuf) + psrc2=tmpbuf + ((i&1) ? 0 : w); + + LICE_pixel lp; + pdest[0] = LICE_PIXEL_HALF(lp=psrc[0]) + + LICE_PIXEL_QUARTER(psrc[1]) + + LICE_PIXEL_EIGHTH(psrc2[0]) + + LICE_PIXEL_EIGHTH(psrc3[0]); + int x; + for (x = 1; x < w-1; x ++) + { + LICE_pixel tp; + pdest[x] = LICE_PIXEL_HALF(tp=psrc[x]) + + LICE_PIXEL_EIGHTH(psrc[x+1]) + + LICE_PIXEL_EIGHTH(lp) + + LICE_PIXEL_EIGHTH(psrc2[x]) + + LICE_PIXEL_EIGHTH(psrc3[x]); + lp=tp; + } + pdest[x] = LICE_PIXEL_HALF(psrc[x]) + + LICE_PIXEL_QUARTER(lp) + + LICE_PIXEL_EIGHTH(psrc2[x]) + + LICE_PIXEL_EIGHTH(psrc3[x]); + } + pdest+=dest_span; + psrc += src_span; + } + if (tmpbuf && tmpbuf != turdbuf) + free(tmpbuf); +} + +#endif + +#ifndef LICE_NO_BLIT_SUPPORT +void LICE_ScaledBlit(LICE_IBitmap *dest, LICE_IBitmap *src, + int dstx, int dsty, int dstw, int dsth, + float srcx, float srcy, float srcw, float srch, + float alpha, int mode) +{ + if (!dest || !src || !dstw || !dsth || !alpha) return; + + // non-scaling optimized omde + if (fabs(srcw-dstw)<0.001 && fabs(srch-dsth)<0.001) + { + // and if not bilinear filtering, or + // the source coordinates are near their integer counterparts + if ((mode&LICE_BLIT_FILTER_MASK)!=LICE_BLIT_FILTER_BILINEAR || + (fabs(srcx-floor(srcx+0.5f))<0.03 && fabs(srcy-floor(srcy+0.5f))<0.03)) + { + RECT sr={(int)(srcx+0.5f),(int)(srcy+0.5f),}; + sr.right=sr.left+dstw; + sr.bottom=sr.top+dsth; + LICE_Blit(dest,src,dstx,dsty,&sr,alpha,mode); + return; + } + } + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_SCALEDBLIT_ACCEL)) + { + LICE_Ext_ScaledBlit_acceldata data(src, dstx, dsty, dstw, dsth, srcx, srcy, srcw, srch, alpha, mode); + if (dest->Extended(LICE_EXT_SCALEDBLIT_ACCEL, &data)) return; + } +#endif + + if (dstw<0) + { + dstw=-dstw; + dstx-=dstw; + srcx+=srcw; + srcw=-srcw; + } + if (dsth<0) + { + dsth=-dsth; + dsty-=dsth; + srcy+=srch; + srch=-srch; + } + + double xadvance = srcw / dstw; + double yadvance = srch / dsth; + + if (dstx < 0) { srcx -= (float) (dstx*xadvance); dstw+=dstx; dstx=0; } + if (dsty < 0) { srcy -= (float) (dsty*yadvance); dsth+=dsty; dsty=0; } + if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; + if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; + + if (dstw<1 || dsth<1) return; // check before the below calcs since they arent necessary / will fuck up if these area small + + int idx=(int)(xadvance*65536.0); + int idy=(int)(yadvance*65536.0); + int icurx=(int) (srcx*65536.0); + int icury=(int) (srcy*65536.0); + + +#if 1 + // the clip area calculations need to be done fixed point so the results match runtime + + if (idx>0) + { + if (icurx < 0) // increase dstx, decrease dstw + { + int n = (idx-1-icurx)/idx; + dstw-=n; + dstx+=n; + icurx+=idx*n; + } + if ((icurx + idx*(dstw-1))/65536 >= src->getWidth()) + { + int neww = ((src->getWidth()-1)*65536 - icurx)/idx; + if (neww < dstw) dstw=neww; + } + } + else if (idx<0) + { + // todo: optimize source-clipping with reversed X axis + } + + if (idy > 0) + { + if (icury < 0) // increase dsty, decrease dsth + { + int n = (idy-1-icury)/idy; + dsth-=n; + dsty+=n; + icury+=idy*n; + } + if ((icury + idy*(dsth-1))/65536 >= src->getHeight()) + { + int newh = ((src->getHeight()-1)*65536 - icury)/idy; + if (newh < dsth) dsth=newh; + } + } + else if (idy<0) + { + // todo: optimize source-clipping with reversed Y axis (check icury against src->getHeight(), etc) + } + if (dstw<1 || dsth<1) return; +#endif + + + int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); + int src_span=src->getRowSpan()*sizeof(LICE_pixel); + + LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); + LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); + if (!psrc || !pdest) return; + + + if (src->isFlipped()) + { + psrc += (src->getHeight()-1)*src_span; + src_span=-src_span; + } + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else pdest += dsty*dest_span; + pdest+=dstx*sizeof(LICE_pixel); + + int clip_r=(int)(srcx+max(srcw,0)+0.999999); + int clip_b=(int)(srcy+max(srch,0)+0.999999); + if (clip_r>src->getWidth()) clip_r=src->getWidth(); + if (clip_b>src->getHeight()) clip_b=src->getHeight(); + + if (clip_r<1||clip_b<1) return; + + int ia=(int)(alpha*256.0); + + if ((mode&(LICE_BLIT_FILTER_MASK|LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA))==LICE_BLIT_MODE_COPY && (ia==128 || ia==256)) + { + if (ia==128) + { + _LICE_Template_Blit0<_LICE_CombinePixelsHalfMixFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span); + } + else + { + _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::scaleBlitFAST(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span); + } + } + else + { + if (xadvance>=1.7 && yadvance >=1.7 && (mode&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR) + { + int msc = max(idx,idy); + const int filtsz=msc>(3<<16) ? 5 : 3; + const int filt_start = - (filtsz/2); + + int filter[25]; // 5x5 max + { + int y; + // char buf[4096]; + // sprintf(buf,"filter, msc=%f: ",msc); + int *p=filter; + for(y=0;y1.0) *p++=65536; + else *p++=(int)(v*65536.0); + } + } + } +// OutputDebugString(buf); + } + + #ifdef LICE_FAVOR_SIZE + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + #else + #define __LICE__ACTION(comb) _LICE_Template_Blit2::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz) + #endif + __LICE_ACTION_SRCALPHA(mode,ia,false); + #undef __LICE__ACTION + + #ifdef LICE_FAVOR_SIZE + if (blitfunc) _LICE_Template_Blit2::scaleBlitFilterDown(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,filter,filt_start,filtsz,blitfunc); + #endif + + } + else + { + #ifdef LICE_FAVOR_SIZE + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + #else + #define __LICE__ACTION(comb) _LICE_Template_Blit2::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) + #endif + __LICE_ACTION_SRCALPHA(mode,ia,false); + #undef __LICE__ACTION + #ifdef LICE_FAVOR_SIZE + if (blitfunc) _LICE_Template_Blit2::scaleBlit(pdest,psrc,dstw,dsth,icurx,icury,idx,idy,clip_r,clip_b,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); + #endif + } + } +} + +void LICE_DeltaBlit(LICE_IBitmap *dest, LICE_IBitmap *src, + int dstx, int dsty, int dstw, int dsth, + float srcx, float srcy, float srcw, float srch, + double dsdx, double dtdx, double dsdy, double dtdy, + double dsdxdy, double dtdxdy, + bool cliptosourcerect, float alpha, int mode) +{ + if (!dest || !src || !dstw || !dsth) return; + + double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight(); + + if (cliptosourcerect) + { + if (srcx > src_left) src_left=srcx; + if (srcy > src_top) src_top=srcy; + if (srcx+srcw < src_right) src_right=srcx+srcw; + if (srcy+srch < src_bottom) src_bottom=srcy+srch; + } + + if (dstw<0) + { + dstw=-dstw; + dstx-=dstw; + srcx+=srcw; + srcw=-srcw; + } + if (dsth<0) + { + dsth=-dsth; + dsty-=dsth; + srcy+=srch; + srch=-srch; + } + + + if (dstx < 0) + { + srcx -= (float) (dstx*dsdx); + srcy -= (float) (dstx*dtdx); + dstw+=dstx; + dstx=0; + } + if (dsty < 0) + { + srcy -= (float) (dsty*dtdy); + srcx -= (float) (dsty*dsdy); + dsth+=dsty; + dsty=0; + } + if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; + if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; + + if (dstw<1 || dsth<1) return; + + + int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); + int src_span=src->getRowSpan()*sizeof(LICE_pixel); + + LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); + LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); + if (!psrc || !pdest) return; + + if (src->isFlipped()) + { + psrc += (src->getHeight()-1)*src_span; + src_span=-src_span; + } + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else pdest += dsty*dest_span; + pdest+=dstx*sizeof(LICE_pixel); + + int sl=(int)(src_left); + int sr=(int)(src_right); + int st=(int)(src_top); + int sb=(int)(src_bottom); + + int ia=(int)(alpha*256.0); + int isrcx=(int)(srcx*65536.0); + int isrcy=(int)(srcy*65536.0); + int idsdx=(int)(dsdx*65536.0); + int idtdx=(int)(dtdx*65536.0); + int idsdy=(int)(dsdy*65536.0); + int idtdy=(int)(dtdy*65536.0); + int idsdxdy=(int)(dsdxdy*65536.0); + int idtdxdy=(int)(dtdxdy*65536.0); + +#ifndef LICE_FAVOR_SPEED + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc = comb::doPix; +#else + #define __LICE__ACTION(comb) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) +#endif + __LICE_ACTION_SRCALPHA(mode,ia,false); + #undef __LICE__ACTION + +#ifndef LICE_FAVOR_SPEED + if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,idsdxdy,idtdxdy,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); +#endif + +} + + + +void LICE_RotatedBlit(LICE_IBitmap *dest, LICE_IBitmap *src, + int dstx, int dsty, int dstw, int dsth, + float srcx, float srcy, float srcw, float srch, + float angle, + bool cliptosourcerect, float alpha, int mode, float rotxcent, float rotycent) +{ + if (!dest || !src || !dstw || !dsth) return; + + double src_top=0.0,src_left=0.0,src_right=src->getWidth(),src_bottom=src->getHeight(); + + if (cliptosourcerect) + { + if (srcx > src_left) src_left=srcx; + if (srcy > src_top) src_top=srcy; + if (srcx+srcw < src_right) src_right=srcx+srcw; + if (srcy+srch < src_bottom) src_bottom=srcy+srch; + } + + if (dstw<0) + { + dstw=-dstw; + dstx-=dstw; + srcx+=srcw; + srcw=-srcw; + } + if (dsth<0) + { + dsth=-dsth; + dsty-=dsth; + srcy+=srch; + srch=-srch; + } + + double cosa=cos(angle); + double sina=sin(angle); + + double xsc=srcw / dstw; + double ysc=srch / dsth; + + double dsdx = xsc * cosa; + double dtdy = ysc * cosa; + double dsdy = xsc * sina; + double dtdx = ysc * -sina; + + srcx -= (float) (0.5 * (dstw*dsdx + dsth*dsdy - srcw) - rotxcent); + srcy -= (float) (0.5 * (dsth*dtdy + dstw*dtdx - srch) - rotycent); + + if (dstx < 0) + { + srcx -= (float) (dstx*dsdx); + srcy -= (float) (dstx*dtdx); + dstw+=dstx; + dstx=0; + } + if (dsty < 0) + { + srcy -= (float) (dsty*dtdy); + srcx -= (float) (dsty*dsdy); + dsth+=dsty; + dsty=0; + } + if (dstx+dstw > dest->getWidth()) dstw=dest->getWidth()-dstx; + if (dsty+dsth > dest->getHeight()) dsth=dest->getHeight()-dsty; + + if (dstw<1 || dsth<1) return; + + + int dest_span=dest->getRowSpan()*sizeof(LICE_pixel); + int src_span=src->getRowSpan()*sizeof(LICE_pixel); + + LICE_pixel_chan *psrc = (LICE_pixel_chan *)src->getBits(); + LICE_pixel_chan *pdest = (LICE_pixel_chan *)dest->getBits(); + if (!psrc || !pdest) return; + + if (src->isFlipped()) + { + psrc += (src->getHeight()-1)*src_span; + src_span=-src_span; + } + + if (dest->isFlipped()) + { + pdest += (dest->getHeight()-dsty - 1)*dest_span; + dest_span=-dest_span; + } + else pdest += dsty*dest_span; + pdest+=dstx*sizeof(LICE_pixel); + + int sl=(int)(src_left); + int sr=(int)(src_right); + int st=(int)(src_top); + int sb=(int)(src_bottom); + + int ia=(int)(alpha*256.0); + int isrcx=(int)(srcx*65536.0); + int isrcy=(int)(srcy*65536.0); + int idsdx=(int)(dsdx*65536.0); + int idtdx=(int)(dtdx*65536.0); + int idsdy=(int)(dsdy*65536.0); + int idtdy=(int)(dtdy*65536.0); + +#ifndef LICE_FAVOR_SPEED + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc = comb::doPix; +#else + #define __LICE__ACTION(comb) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK) +#endif + __LICE_ACTION_SRCALPHA(mode,ia,false); + #undef __LICE__ACTION + +#ifndef LICE_FAVOR_SPEED + if (blitfunc) _LICE_Template_Blit3::deltaBlit(pdest,psrc,dstw,dsth,isrcx,isrcy,idsdx,idtdx,idsdy,idtdy,0,0,sl,st,sr,sb,src_span,dest_span,ia,mode&LICE_BLIT_FILTER_MASK,blitfunc); +#endif +} + +#endif + + +void LICE_Clear(LICE_IBitmap *dest, LICE_pixel color) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_CLEAR_ACCEL)) + { + if (dest->Extended(LICE_EXT_CLEAR_ACCEL, &color)) return; + } +#endif + + LICE_pixel *p=dest->getBits(); + int h=dest->getHeight(); + int w=dest->getWidth(); + int sp=dest->getRowSpan(); + if (!p || w<1 || h<1 || sp<1) return; + + while (h-->0) + { + int n=w; + while (n--) *p++ = color; + p+=sp-w; + } +} + + + + +void LICE_MultiplyAddRect(LICE_IBitmap *dest, int x, int y, int w, int h, + float rsc, float gsc, float bsc, float asc, + float radd, float gadd, float badd, float aadd) +{ + if (!dest) return; + LICE_pixel *p=dest->getBits(); + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w>dest->getWidth()) w=dest->getWidth()-x; + if (y+h>dest->getHeight()) h=dest->getHeight()-y; + + int sp=dest->getRowSpan(); + if (!p || w<1 || h<1 || sp<1) return; + + if (dest->isFlipped()) + { + p+=(dest->getHeight() - y - h)*sp; + } + else p+=sp*y; + + p += x; + + int ir=(int)(rsc*256.0); + int ig=(int)(gsc*256.0); + int ib=(int)(bsc*256.0); + int ia=(int)(asc*256.0); + int ir2=(int)(radd*256.0); + int ig2=(int)(gadd*256.0); + int ib2=(int)(badd*256.0); + int ia2=(int)(aadd*256.0); + + while (h-->0) + { + int n=w; + while (n--) + { + LICE_pixel_chan *ptr=(LICE_pixel_chan *)p++; + _LICE_MakePixelClamp(ptr,(ptr[LICE_PIXEL_R]*ir+ir2)>>8, + (ptr[LICE_PIXEL_G]*ig+ig2)>>8, + (ptr[LICE_PIXEL_B]*ib+ib2)>>8, + (ptr[LICE_PIXEL_A]*ia+ia2)>>8); + } + p+=sp-w; + } +} + +void LICE_ProcessRect(LICE_IBitmap *dest, int x, int y, int w, int h, void (*procFunc)(LICE_pixel *p, void *parm), void *parm) +{ + if (!dest||!procFunc) return; + LICE_pixel *p=dest->getBits(); + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w>dest->getWidth()) w=dest->getWidth()-x; + if (y+h>dest->getHeight()) h=dest->getHeight()-y; + + int sp=dest->getRowSpan(); + if (!p || w<1 || h<1 || sp<1) return; + + if (dest->isFlipped()) + { + p+=(dest->getHeight() - y - h)*sp; + } + else p+=sp*y; + + p += x; + + while (h--) + { + LICE_pixel *pout=p; + int n=w; + while (n--) procFunc(pout++,parm); + p+=sp; + } + + +} + +void LICE_FillRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_FILLRECT_ACCEL)) + { + LICE_Ext_FillRect_acceldata data(x, y, w, h, color, alpha, mode); + if (dest->Extended(LICE_EXT_FILLRECT_ACCEL, &data)) return; + } +#endif + + if (mode & LICE_BLIT_USE_ALPHA) alpha *= LICE_GETA(color)/255.0f; + LICE_pixel *p=dest->getBits(); + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w>dest->getWidth()) w=dest->getWidth()-x; + if (y+h>dest->getHeight()) h=dest->getHeight()-y; + + int sp=dest->getRowSpan(); + if (!alpha || !p || w<1 || h<1 || sp<1) return; + + if (dest->isFlipped()) + { + p+=(dest->getHeight() - y - h)*sp; + } + else p+=sp*y; + + p += x; + + int ia=(int)(alpha*256.0); + // copy, alpha=1, alpha=0.5, 0.25, 0.75 optimizations + if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) + { + if (ia==256) + { + _LICE_Template_Blit0<_LICE_CombinePixelsClobberFAST>::solidBlitFAST(p,w,h,color,sp); + return; + } + if (ia==128) + { + // we use _LICE_CombinePixelsHalfMix2 because we pre-halve color here + _LICE_Template_Blit0<_LICE_CombinePixelsHalfMix2FAST>::solidBlitFAST(p,w,h,(color>>1)&0x7f7f7f7f,sp); + return; + } + if (ia==64) + { + _LICE_Template_Blit0<_LICE_CombinePixelsQuarterMix2FAST>::solidBlitFAST(p,w,h,(color>>2)&0x3f3f3f3f,sp); + return; + } + if (ia==192) + { + _LICE_Template_Blit0<_LICE_CombinePixelsThreeQuarterMix2FAST>::solidBlitFAST(p,w,h, + ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f),sp); + return; + } + } + +#ifdef LICE_FAVOR_SIZE_EXTREME + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; +#else + #define __LICE__ACTION(comb) _LICE_Template_Blit1::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel)) +#endif + + // we use __LICE_ACTION_NOSRCALPHA even though __LICE_ACTION_CONSTANTALPHA + // is valid, sinc we optimized the 1.0f/0.5f cases above + __LICE_ACTION_NOSRCALPHA(mode,ia,false); + #undef __LICE__ACTION + +#ifdef LICE_FAVOR_SIZE_EXTREME + if (blitfunc) _LICE_Template_Blit1::solidBlit((LICE_pixel_chan*)p,w,h,LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),ia,sp*sizeof(LICE_pixel),blitfunc); +#endif +} + +void LICE_ClearRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel mask, LICE_pixel orbits) +{ + if (!dest) return; + LICE_pixel *p=dest->getBits(); + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w>dest->getWidth()) w=dest->getWidth()-x; + if (y+h>dest->getHeight()) h=dest->getHeight()-y; + + int sp=dest->getRowSpan(); + if (!p || w<1 || h<1 || sp<1) return; + + if (dest->isFlipped()) + { + p+=(dest->getHeight() - y - h)*sp; + } + else p+=sp*y; + + p += x; + while (h-->0) + { + int n=w; + while (n--) + { + *p = (*p&mask)|orbits; + p++; + } + p+=sp-w; + } +} + + +LICE_pixel LICE_GetPixel(LICE_IBitmap *bm, int x, int y) +{ + if (!bm) return 0; + +#ifndef DISABLE_LICE_EXTENSIONS + if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_GETPIXEL_ACCEL)) + { + LICE_Ext_GetPixel_acceldata data(x, y); + if (bm->Extended(LICE_EXT_GETPIXEL_ACCEL, &data)) return data.px; + } +#endif + + LICE_pixel *px; + if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return 0; + if (bm->isFlipped()) return px[(bm->getHeight()-1-y) * bm->getRowSpan() + x]; + return px[y * bm->getRowSpan() + x]; +} + +void LICE_PutPixel(LICE_IBitmap *bm, int x, int y, LICE_pixel color, float alpha, int mode) +{ + if (!bm) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_PUTPIXEL_ACCEL)) + { + LICE_Ext_PutPixel_acceldata data(x, y, color, alpha, mode); + if (bm->Extended(LICE_EXT_PUTPIXEL_ACCEL, &data)) return; + } +#endif + + LICE_pixel *px; + if (!(px=bm->getBits()) || x < 0 || y < 0 || x >= bm->getWidth() || y>= bm->getHeight()) return; + + if (bm->isFlipped()) px+=x+(bm->getHeight()-1-y)*bm->getRowSpan(); + else px+=x+y*bm->getRowSpan(); + + int ia = (int)(alpha * 256.0f); + if ((mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) + { + if (ia==256) + { + *px = color; + return; + } + if (ia==128) + { + *px = ((*px>>1)&0x7f7f7f7f) + ((color>>1)&0x7f7f7f7f); + return; + } + if (ia==64) + { + *px = ((*px>>1)&0x7f7f7f7f) + ((*px>>2)&0x3f3f3f3f) + ((color>>2)&0x3f3f3f3f); + return; + } + if (ia==192) + { + *px = ((*px>>2)&0x3f3f3f3f) + ((color>>1)&0x7f7f7f7f) + ((color>>2)&0x3f3f3f3f); + return; + } + } +#define __LICE__ACTION(comb) comb::doPix((LICE_pixel_chan *)px, LICE_GETR(color),LICE_GETG(color),LICE_GETB(color),LICE_GETA(color), ia) + __LICE_ACTION_NOSRCALPHA(mode,ia,false); +#undef __LICE__ACTION +} + + +#ifndef LICE_NO_BLIT_SUPPORT +void LICE_TransformBlit(LICE_IBitmap *dest, LICE_IBitmap *src, + int dstx, int dsty, int dstw, int dsth, + float *srcpoints, int div_w, int div_h, // srcpoints coords should be div_w*div_h*2 long, and be in source image coordinates + float alpha, int mode) +{ + if (!dest || !src || dstw<1 || dsth<1 || div_w<2 || div_h<2) return; + + int cypos=dsty; + double ypos=dsty; + double dxpos=dstw/(float)(div_w-1); + double dypos=dsth/(float)(div_h-1); + int y; + float *curpoints=srcpoints; + for (y = 0; y < div_h-1; y ++) + { + int nypos=(int)(ypos+=dypos); + int x; + double xpos=dstx; + int cxpos=dstx; + + if (nypos != cypos) + { + double iy=1.0/(double)(nypos-cypos); + for (x = 0; x < div_w-1; x ++) + { + int nxpos=(int) (xpos+=dxpos); + if (nxpos != cxpos) + { + int offs=x*2; + double sx=curpoints[offs]; + double sy=curpoints[offs+1]; + double sw=curpoints[offs+2]-sx; + double sh=curpoints[offs+3]-sy; + + offs+=div_w*2; + double sxdiff=curpoints[offs]-sx; + double sydiff=curpoints[offs+1]-sy; + double sw3=curpoints[offs+2]-curpoints[offs]; + double sh3=curpoints[offs+3]-curpoints[offs+1]; + + double ix=1.0/(double)(nxpos-cxpos); + double dsdx=sw*ix; + double dtdx=sh*ix; + double dsdx2=sw3*ix; + double dtdx2=sh3*ix; + double dsdy=sxdiff*iy; + double dtdy=sydiff*iy; + double dsdxdy = (dsdx2-dsdx)*iy; + double dtdxdy = (dtdx2-dtdx)*iy; + + LICE_DeltaBlit(dest,src,cxpos,cypos,nxpos-cxpos,nypos-cypos, + (float)sx,(float)sy,(float)sw,(float)sh, + dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy,false,alpha,mode); + } + + cxpos=nxpos; + } + } + curpoints+=div_w*2; + cypos=nypos; + } + +} + + + +#endif + +#ifndef LICE_NO_MISC_SUPPORT + +void LICE_SetAlphaFromColorMask(LICE_IBitmap *dest, LICE_pixel color) +{ + if (!dest) return; + LICE_pixel *p=dest->getBits(); + int h=dest->getHeight(); + int w=dest->getWidth(); + int sp=dest->getRowSpan(); + if (!p || w<1 || h<1 || sp<1) return; + + while (h-->0) + { + int n=w; + while (n--) + { + if ((*p&LICE_RGBA(255,255,255,0)) == color) *p&=LICE_RGBA(255,255,255,0); + else *p|=LICE_RGBA(0,0,0,255); + p++; + } + p+=sp-w; + } +} + + +void LICE_SimpleFill(LICE_IBitmap *dest, int x, int y, LICE_pixel newcolor, + LICE_pixel comparemask, + LICE_pixel keepmask) +{ + if (!dest) return; + int dw=dest->getWidth(); + int dh=dest->getHeight(); + int rowsize=dest->getRowSpan(); + if (x<0||x>=dw||y<0||y>=dh) return; + LICE_pixel *ptr=dest->getBits(); + if (!ptr) return; + ptr += rowsize*y; + + LICE_pixel compval=ptr[x]&comparemask; + int ay; + for (ay=y;ay=0) + { + if ((ptr[ax]&comparemask)!=compval) break; + ptr[ax]=(ptr[ax]&keepmask)|newcolor; + } + + ptr+=rowsize; + } + ptr =dest->getBits()+rowsize*y; + + ay=y; + while (--ay>=0) + { + ptr-=rowsize; + if ((ptr[x]&comparemask)!=compval) break; + ptr[x]=(ptr[x]&keepmask)|newcolor; + + int ax; + for(ax=x+1;ax=0) + { + if ((ptr[ax]&comparemask)!=compval) break; + ptr[ax]=(ptr[ax]&keepmask)|newcolor; + } + } +} + +// stupid ass VS6 instantiates this wrong as a template function, needs to be a template class +template class GlyphDrawImpl +{ +public: + static void DrawGlyph(const LICE_pixel_chan* srcalpha, LICE_pixel* destpx, int src_w, int src_h, LICE_pixel color, int span, int src_span, int aa) + { + + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + int xi, yi; + for (yi = 0; yi < src_h; ++yi, srcalpha += src_span, destpx += span) { + const LICE_pixel_chan* tsrc = srcalpha; + LICE_pixel* tdest = destpx; + for (xi = 0; xi < src_w; ++xi, ++tsrc, ++tdest) { + if (*tsrc) { // glyphs should be expected to have a lot of "holes" + COMBFUNC::doPix((LICE_pixel_chan*) tdest, r, g, b, a, *tsrc*aa/256); + } + } + } + } +}; + +void LICE_DrawGlyphEx(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_span, int glyph_h, float alpha, int mode) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWGLYPH_ACCEL) && glyph_w == glyph_span) + { + LICE_Ext_DrawGlyph_acceldata data(x, y, color, alphas, glyph_w, glyph_h, alpha, mode); + if (dest->Extended(LICE_EXT_DRAWGLYPH_ACCEL, &data)) return; + } +#endif + + int ia= (int)(alpha*256.0f); + + int src_x = 0, src_y = 0, src_w = glyph_w, src_h = glyph_h; + if (x < 0) { + src_x -= x; + src_w += x; + x = 0; + } + if (x+src_w >= dest->getWidth()) { + src_w = dest->getWidth()-x; + } + if (y < 0) { + src_y -= y; + src_h += y; + y = 0; + } + if (y+src_h >= dest->getHeight()) { + src_h = dest->getHeight()-y; + } + + + LICE_pixel* destpx = dest->getBits(); + int span = dest->getRowSpan(); + if (dest->isFlipped()) { + destpx += (dest->getHeight()-y-1)*span+x; + span = -span; + } + else { + destpx += y*dest->getRowSpan()+x; + } + + const LICE_pixel_chan* srcalpha = alphas+src_y*glyph_span+src_x; + +#define __LICE__ACTION(COMBFUNC) GlyphDrawImpl::DrawGlyph(srcalpha,destpx, src_w, src_h, color,span,glyph_span,ia) + __LICE_ACTION_NOSRCALPHA(mode, ia, false); +#undef __LICE__ACTION +} + +void LICE_DrawGlyph(LICE_IBitmap* dest, int x, int y, LICE_pixel color, const LICE_pixel_chan* alphas, int glyph_w, int glyph_h, float alpha, int mode) +{ + LICE_DrawGlyphEx(dest,x,y,color,alphas,glyph_w,glyph_w,glyph_h,alpha,mode); +} + +void LICE_HalveBlitAA(LICE_IBitmap *dest, LICE_IBitmap *src) +{ + if (!dest||!src) return; + int w = dest->getWidth(); + if (w > src->getWidth()/2) w=src->getWidth()/2; + int h = dest->getHeight(); + if (h > src->getHeight()/2) h=src->getHeight()/2; + int src_span = src->getRowSpan(); + int dest_span = dest->getRowSpan(); + LICE_pixel *srcptr = src->getBits(); + LICE_pixel *destptr = dest->getBits(); + + while (h--) + { + LICE_pixel *sp = srcptr; + LICE_pixel *sp2 = srcptr+src_span; + LICE_pixel *dp = destptr; + int x=w/2; + // perhaps we should use more precision rather than chopping each src pixel to 6 bits, but oh well + while (x--) // unroll 2px at a time, about 5% faster on core2 and ICC + { + int r1=((sp[0]>>2)&0x3f3f3f3f); + int r2=((sp[2]>>2)&0x3f3f3f3f); + r1 += ((sp[1]>>2)&0x3f3f3f3f); + r2 += ((sp[3]>>2)&0x3f3f3f3f); + dp[0] = r1 + + ((sp2[0]>>2)&0x3f3f3f3f) + + ((sp2[1]>>2)&0x3f3f3f3f); + dp[1] = r2 + + ((sp2[2]>>2)&0x3f3f3f3f) + + ((sp2[3]>>2)&0x3f3f3f3f); + sp+=4; + sp2+=4; + dp+=2; + } + if (w&1) + { + *dp = + ((sp[0]>>2)&0x3f3f3f3f) + + ((sp[1]>>2)&0x3f3f3f3f) + + ((sp2[0]>>2)&0x3f3f3f3f) + + ((sp2[1]>>2)&0x3f3f3f3f); + } + srcptr+=src_span*2; + destptr+=dest_span; + } +} + +#endif // LICE_NO_MISC_SUPPORT + +int LICE_BitmapCmp(LICE_IBitmap* a, LICE_IBitmap* b, int *coordsOut) +{ + if (!a || !b) { + if (!a && b) return -1; + if (a && !b) return 1; + return 0; + } + + int aw = a->getWidth(), bw = b->getWidth(); + if (aw != bw) return bw-aw; + int ah = a->getHeight(), bh = b->getHeight(); + if (ah != bh) return bh-ah; + + //coordsOut + LICE_pixel *px1 = a->getBits(); + LICE_pixel *px2 = b->getBits(); + int span1 = a->getRowSpan(); + int span2 = b->getRowSpan(); + if (a->isFlipped()) + { + px1+=span1*(ah-1); + span1=-span1; + } + if (b->isFlipped()) + { + px2+=span2*(ah-1); + span2=-span2; + } + + int y; + if (!coordsOut) + { + for (y=0; y < ah; y ++) + { + int a = memcmp(px1,px2,aw*sizeof(LICE_pixel)); + if (a) return a; + px1+=span1; + px2+=span2; + } + } + else + { + int x; + + // find first row that differs + for (y=0; y < ah; y ++) + { + // check left side + for (x=0;x=ah) + { + memset(coordsOut,0,4*sizeof(int)); + return 0; // no differences + } + + int miny=y; + int minx=x; + // scan right edge of top differing row + for (x=aw-1;x>minx && px1[x]==px2[x];x--); + int maxx=x; + + // find last row that differs + px1+=span1 * (ah-1-y); + px2+=span2 * (ah-1-y); + for (y = ah-1; y > miny; y --) + { + int x; + // check left side + for (x=0;x miny) + { + if (x < minx) minx=x; + // scan right edge of bottom row that differs + for (x=aw-1;x>maxx && px1[x]==px2[x];x--); + maxx=x; + } + + + // find min/max x that differ + px1+=span1 * (miny+1-y); + px2+=span2 * (miny+1-y); + for (y=miny+1;y0 || maxxmaxx && px1[x]==px2[x];x--); + maxx=x; + + px1+=span1; + px2+=span2; + } + + coordsOut[0]=minx; + coordsOut[1]=miny; + coordsOut[2]=maxx-minx+1; + coordsOut[3]=maxy-miny+1; + + return 1; + } + + return 0; +} + +unsigned short _LICE_RGB2HSV_invtab[256]={ // 65536/idx - 1 + 0, 0xffff, 0x7fff, 0x5554, 0x3fff, 0x3332, 0x2aa9, 0x2491, + 0x1fff, 0x1c70, 0x1998, 0x1744, 0x1554, 0x13b0, 0x1248, 0x1110, + 0x0fff, 0x0f0e, 0x0e37, 0x0d78, 0x0ccb, 0x0c2f, 0x0ba1, 0x0b20, + 0x0aa9, 0x0a3c, 0x09d7, 0x097a, 0x0923, 0x08d2, 0x0887, 0x0841, + 0x07ff, 0x07c0, 0x0786, 0x074f, 0x071b, 0x06ea, 0x06bb, 0x068f, + 0x0665, 0x063d, 0x0617, 0x05f3, 0x05d0, 0x05af, 0x058f, 0x0571, + 0x0554, 0x0538, 0x051d, 0x0504, 0x04eb, 0x04d3, 0x04bc, 0x04a6, + 0x0491, 0x047c, 0x0468, 0x0455, 0x0443, 0x0431, 0x0420, 0x040f, + 0x03ff, 0x03ef, 0x03df, 0x03d1, 0x03c2, 0x03b4, 0x03a7, 0x039a, + 0x038d, 0x0380, 0x0374, 0x0368, 0x035d, 0x0352, 0x0347, 0x033c, + 0x0332, 0x0328, 0x031e, 0x0314, 0x030b, 0x0302, 0x02f9, 0x02f0, + 0x02e7, 0x02df, 0x02d7, 0x02cf, 0x02c7, 0x02bf, 0x02b8, 0x02b0, + 0x02a9, 0x02a2, 0x029b, 0x0294, 0x028e, 0x0287, 0x0281, 0x027b, + 0x0275, 0x026f, 0x0269, 0x0263, 0x025d, 0x0258, 0x0252, 0x024d, + 0x0248, 0x0242, 0x023d, 0x0238, 0x0233, 0x022f, 0x022a, 0x0225, + 0x0221, 0x021c, 0x0218, 0x0213, 0x020f, 0x020b, 0x0207, 0x0203, + 0x01ff, 0x01fb, 0x01f7, 0x01f3, 0x01ef, 0x01eb, 0x01e8, 0x01e4, + 0x01e0, 0x01dd, 0x01d9, 0x01d6, 0x01d3, 0x01cf, 0x01cc, 0x01c9, + 0x01c6, 0x01c2, 0x01bf, 0x01bc, 0x01b9, 0x01b6, 0x01b3, 0x01b1, + 0x01ae, 0x01ab, 0x01a8, 0x01a5, 0x01a3, 0x01a0, 0x019d, 0x019b, + 0x0198, 0x0196, 0x0193, 0x0191, 0x018e, 0x018c, 0x0189, 0x0187, + 0x0185, 0x0182, 0x0180, 0x017e, 0x017c, 0x0179, 0x0177, 0x0175, + 0x0173, 0x0171, 0x016f, 0x016d, 0x016b, 0x0169, 0x0167, 0x0165, + 0x0163, 0x0161, 0x015f, 0x015d, 0x015b, 0x0159, 0x0157, 0x0156, + 0x0154, 0x0152, 0x0150, 0x014f, 0x014d, 0x014b, 0x0149, 0x0148, + 0x0146, 0x0145, 0x0143, 0x0141, 0x0140, 0x013e, 0x013d, 0x013b, + 0x013a, 0x0138, 0x0137, 0x0135, 0x0134, 0x0132, 0x0131, 0x012f, + 0x012e, 0x012d, 0x012b, 0x012a, 0x0128, 0x0127, 0x0126, 0x0124, + 0x0123, 0x0122, 0x0120, 0x011f, 0x011e, 0x011d, 0x011b, 0x011a, + 0x0119, 0x0118, 0x0117, 0x0115, 0x0114, 0x0113, 0x0112, 0x0111, + 0x0110, 0x010e, 0x010d, 0x010c, 0x010b, 0x010a, 0x0109, 0x0108, + 0x0107, 0x0106, 0x0105, 0x0104, 0x0103, 0x0102, 0x0101, 0x0100, +}; + + +#endif//__LICE_CPP_IMPLEMENTED__ diff --git a/WDL/lice/lice.dsp b/WDL/lice/lice.dsp new file mode 100644 index 00000000..302bb1a9 --- /dev/null +++ b/WDL/lice/lice.dsp @@ -0,0 +1,942 @@ +# Microsoft Developer Studio Project File - Name="lice" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=lice - 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 "lice.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 "lice.mak" CFG="lice - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lice - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "lice - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "lice - Win32 Release Profile" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lice - 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 /MD /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /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)" == "lice - 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 /W3 /Gm /GX /ZI /Od /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_DEBUG" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /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 + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "lice___Win32_Release_Profile" +# PROP BASE Intermediate_Dir "lice___Win32_Release_Profile" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_Profile" +# PROP Intermediate_Dir "Release_Profile" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /D "PNG_WRITE_SUPPORTED" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /D "__MMX__" /D "PNG_HAVE_MMX_COMBINE_ROW" /D "PNG_HAVE_MMX_READ_INTERLACE" /D "PNG_HAVE_MMX_READ_FILTER_ROW" /D "PNG_WRITE_SUPPORTED" /FR /FD /c +# SUBTRACT CPP /YX +# 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 + +!ENDIF + +# Begin Target + +# Name "lice - Win32 Release" +# Name "lice - Win32 Debug" +# Name "lice - Win32 Release Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "libpng" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\libpng\png.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\png.h +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngconf.h +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngerror.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngget.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngmem.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngpread.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngread.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngrio.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngrtran.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngrutil.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngset.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngtest.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngtrans.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngwio.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngwrite.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngwtran.c +# End Source File +# Begin Source File + +SOURCE=..\libpng\pngwutil.c +# End Source File +# End Group +# Begin Group "zlib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\zlib\adler32.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\compress.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\crc32.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\crc32.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\deflate.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\infback.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\inffast.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\inffast.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\inffixed.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\inflate.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\inflate.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\inftrees.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\inftrees.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\trees.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\trees.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\uncompr.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\zlib.h +# End Source File +# Begin Source File + +SOURCE=..\zlib\zutil.c +# End Source File +# Begin Source File + +SOURCE=..\zlib\zutil.h +# End Source File +# End Group +# Begin Group "jpeglib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\jpeglib\jcapimin.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcapistd.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jccoefct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jccolor.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcdctmgr.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jchuff.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcinit.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcmainct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcmarker.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcmaster.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcomapi.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcparam.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcphuff.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcprepct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jcsample.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jctrans.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdapimin.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdapistd.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdatadst.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdatasrc.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdcoefct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdcolor.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jddctmgr.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdhuff.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdinput.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdmainct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdmarker.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdmaster.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdmerge.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdphuff.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdpostct.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdsample.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jdtrans.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jerror.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jfdctflt.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jfdctfst.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jfdctint.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jidctflt.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jidctfst.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jidctint.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jidctred.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jmemmgr.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jmemnobs.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jquant1.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jquant2.c +# End Source File +# Begin Source File + +SOURCE=..\jpeglib\jutils.c +# End Source File +# End Group +# Begin Group "giflib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\giflib\dgif_lib.c + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\giflib\egif_lib.c + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\giflib\gif_hash.c + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\giflib\gif_hash.h +# End Source File +# Begin Source File + +SOURCE=..\giflib\gif_lib.h +# End Source File +# Begin Source File + +SOURCE=..\giflib\gif_lib_private.h +# End Source File +# Begin Source File + +SOURCE=..\giflib\gifalloc.c + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +# ADD CPP /I "../giflib" /D "HAVE_CONFIG_H" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" +# ADD CPP /MD /I "../giflib" /D "HAVE_CONFIG_H" + +!ENDIF + +# End Source File +# End Group +# Begin Group "tinyxml" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\tinyxml\svgtiny_colors.c +# End Source File +# Begin Source File + +SOURCE=..\tinyxml\tinystr.cpp +# End Source File +# Begin Source File + +SOURCE=..\tinyxml\tinyxml.cpp +# End Source File +# Begin Source File + +SOURCE=..\tinyxml\tinyxml.h +# End Source File +# Begin Source File + +SOURCE=..\tinyxml\tinyxmlerror.cpp +# End Source File +# Begin Source File + +SOURCE=..\tinyxml\tinyxmlparser.cpp +# End Source File +# End Group +# Begin Source File + +SOURCE=.\lice.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_arc.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_bmp.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_colorspace.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_gif.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_gl_ctx.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_glbitmap.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_ico.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_jpg.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_jpg_write.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_line.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_palette.cpp +# End Source File +# Begin Source File + +SOURCE=.\lice_pcx.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_png.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_png_write.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_svg.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_texgen.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_text.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\lice_textnew.cpp + +!IF "$(CFG)" == "lice - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "lice - Win32 Debug" + +!ELSEIF "$(CFG)" == "lice - Win32 Release Profile" + +# ADD BASE CPP /D "USE_ICC" +# ADD CPP /D "USE_ICC" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\lice.h +# End Source File +# Begin Source File + +SOURCE=.\lice_combine.h +# End Source File +# Begin Source File + +SOURCE=.\lice_extended.h +# End Source File +# Begin Source File + +SOURCE=.\lice_gl_ctx.h +# End Source File +# Begin Source File + +SOURCE=.\lice_glbitmap.h +# End Source File +# Begin Source File + +SOURCE=.\lice_text.h +# End Source File +# End Group +# End Target +# End Project diff --git a/WDL/lice/lice.dsw b/WDL/lice/lice.dsw new file mode 100644 index 00000000..a057da40 --- /dev/null +++ b/WDL/lice/lice.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lice"=.\lice.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "plush2"=..\plush2\plush2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "test"=.\test\test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name lice + End Project Dependency + Begin Project Dependency + Project_Dep_Name plush2 + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/WDL/lice/lice.h b/WDL/lice/lice.h new file mode 100644 index 00000000..fed9f279 --- /dev/null +++ b/WDL/lice/lice.h @@ -0,0 +1,554 @@ +#ifndef _LICE_H +#define _LICE_H + +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + + Copyright (C) 2007 and later, Cockos Incorporated + Portions Copyright (C) 2007 "schwa" + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifdef _WIN32 +#include +#else +#include "../swell/swell-types.h" // use SWELL on other systems +#endif + + +// one of these can be defined in your project if you choose: +//#define LICE_FAVOR_SPEED // optimizes some stuff that doesnt seem to benefit much (like LICE_DeltaBlit/LICE_RotatedBlit/LICE_TransformBlit) +// (nothing) default probably good overall +//#define LICE_FAVOR_SIZE // reduces code size of normal/scaled blit functions +//#define LICE_FAVOR_SIZE_EXTREME // same as LICE_FAVOR_SIZE w/ smaller gains with bigger perf penalties (solid fills etc) + +#ifdef LICE_FAVOR_SPEED + #ifdef LICE_FAVOR_SIZE_EXTREME + #undef LICE_FAVOR_SIZE_EXTREME + #endif + #ifdef LICE_FAVOR_SIZE + #undef LICE_FAVOR_SIZE + #endif +#endif +#if defined(LICE_FAVOR_SIZE_EXTREME) && !defined(LICE_FAVOR_SIZE) +#define LICE_FAVOR_SIZE +#endif + + +typedef unsigned int LICE_pixel; +typedef unsigned char LICE_pixel_chan; + +#ifdef _WIN32 + +#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) +#define LICE_GETB(v) ((v)&0xff) +#define LICE_GETG(v) (((v)>>8)&0xff) +#define LICE_GETR(v) (((v)>>16)&0xff) +#define LICE_GETA(v) (((v)>>24)&0xff) + + +#define LICE_PIXEL_B 0 +#define LICE_PIXEL_G 1 +#define LICE_PIXEL_R 2 +#define LICE_PIXEL_A 3 + +#elif defined(__APPLE__) +// start apple +#define LICE_PIXEL_A 0 +#define LICE_PIXEL_R 1 +#define LICE_PIXEL_G 2 +#define LICE_PIXEL_B 3 + +#ifdef __ppc__ // same memory format, different endian + +#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) +#define LICE_GETB(v) ((v)&0xff) +#define LICE_GETG(v) (((v)>>8)&0xff) +#define LICE_GETR(v) (((v)>>16)&0xff) +#define LICE_GETA(v) (((v)>>24)&0xff) + +#else + +#define LICE_RGBA(r,g,b,a) (((a)&0xff)|(((r)&0xff)<<8)|(((g)&0xff)<<16)|(((b)&0xff)<<24)) +#define LICE_GETA(v) ((v)&0xff) +#define LICE_GETR(v) (((v)>>8)&0xff) +#define LICE_GETG(v) (((v)>>16)&0xff) +#define LICE_GETB(v) (((v)>>24)&0xff) + +#endif + +// end apple +#else + +//GDK etc (tested on linux 386/x86_64) +#define LICE_RGBA(r,g,b,a) (((b)&0xff)|(((g)&0xff)<<8)|(((r)&0xff)<<16)|(((a)&0xff)<<24)) +#define LICE_GETB(v) ((v)&0xff) +#define LICE_GETG(v) (((v)>>8)&0xff) +#define LICE_GETR(v) (((v)>>16)&0xff) +#define LICE_GETA(v) (((v)>>24)&0xff) + + +#define LICE_PIXEL_B 0 +#define LICE_PIXEL_G 1 +#define LICE_PIXEL_R 2 +#define LICE_PIXEL_A 3 + +#endif + + +static inline LICE_pixel LICE_RGBA_FROMNATIVE(LICE_pixel col, int alpha=0) +{ + return LICE_RGBA(GetRValue(col),GetGValue(col),GetBValue(col),alpha); +} + +// bitmap interface, and some built-in types (memory bitmap and system bitmap) + +class LICE_IBitmap +{ +public: + virtual ~LICE_IBitmap() { } + + virtual LICE_pixel *getBits()=0; + virtual int getWidth()=0; + virtual int getHeight()=0; + virtual int getRowSpan()=0; // includes any off-bitmap data + virtual bool isFlipped() { return false; } + virtual bool resize(int w, int h)=0; + + virtual HDC getDC() { return 0; } // only sysbitmaps have to implement this + + + virtual INT_PTR Extended(int id, void* data) { return 0; } +}; + + +#define LICE_MEMBITMAP_ALIGNAMT 63 + +class LICE_MemBitmap : public LICE_IBitmap +{ +public: + LICE_MemBitmap(int w=0, int h=0, unsigned int linealign=4); + virtual ~LICE_MemBitmap(); + + + // LICE_IBitmap interface + virtual LICE_pixel *getBits() + { + const UINT_PTR extra=LICE_MEMBITMAP_ALIGNAMT; + return (LICE_pixel *) (((UINT_PTR)m_fb + extra)&~extra); + } + virtual int getWidth() { return m_width; } + virtual int getHeight() { return m_height; } + virtual int getRowSpan() { return (m_width+m_linealign)&~m_linealign; } + virtual bool resize(int w, int h); // returns TRUE if a resize occurred + +private: + LICE_pixel *m_fb; + int m_width, m_height; + int m_allocsize; + unsigned int m_linealign; +}; + +class LICE_SysBitmap : public LICE_IBitmap +{ +public: + LICE_SysBitmap(int w=0, int h=0); + virtual ~LICE_SysBitmap(); + + // LICE_IBitmap interface + virtual LICE_pixel *getBits() { return m_bits; } + virtual int getWidth() { return m_width; } + virtual int getHeight() { return m_height; } + virtual int getRowSpan() { return m_allocw; }; + virtual bool resize(int w, int h); // returns TRUE if a resize occurred + + // sysbitmap specific calls + virtual HDC getDC() { return m_dc; } + + +private: + int m_width, m_height; + + HDC m_dc; + LICE_pixel *m_bits; + int m_allocw, m_alloch; +#ifdef _WIN32 + HBITMAP m_bitmap; + HGDIOBJ m_oldbitmap; +#endif +}; + +class LICE_WrapperBitmap : public LICE_IBitmap +{ + public: + LICE_WrapperBitmap(LICE_pixel *buf, int w, int h, int span, bool flipped) + { + m_buf=buf; + m_w=w; + m_h=h; + m_span=span; + m_flipped=flipped; + } + virtual ~LICE_WrapperBitmap() {} + + virtual bool resize(int w, int h) { return false; } + virtual LICE_pixel *getBits() { return m_buf; } + virtual int getWidth() { return m_w; } + virtual int getHeight() { return m_h; } + virtual int getRowSpan() { return m_span; } + + virtual HDC getDC() { return NULL; } + virtual bool isFlipped() { return m_flipped; } + + + LICE_pixel *m_buf; + int m_w,m_h,m_span; + bool m_flipped; +}; + + +class LICE_SubBitmap : public LICE_IBitmap // note: you should only keep these around as long as they are needed, and don't resize the parent while this is allocated +{ + public: + LICE_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h) + { + m_parent=parent; + if(x<0)x=0; + if(y<0)y=0; + m_x=x;m_y=y; + resize(w,h); + } + virtual ~LICE_SubBitmap() { } + + virtual bool resize(int w, int h) + { + m_w=0;m_h=0; + if (m_parent) + { + if(m_x+w>m_parent->getWidth()) w=m_parent->getWidth()-m_x; + if (w<0)w=0; + + if (m_y+h>m_parent->getHeight()) h=m_parent->getHeight()-m_y; + if (h<0)h=0; + + m_w=w; + m_h=h; + } + + return true; + } + + virtual bool isFlipped() { return m_parent && m_parent->isFlipped(); } + + virtual LICE_pixel *getBits() + { + if (!m_parent) return 0; + + LICE_pixel* parentptr=m_parent->getBits(); + if (m_parent->isFlipped()) parentptr += (m_parent->getHeight() - (m_y+m_h))*m_parent->getRowSpan()+m_x; + else parentptr += m_y*m_parent->getRowSpan()+m_x; + + return parentptr; + } + + virtual INT_PTR Extended(int id, void* data) + { + if (!m_parent) return 0; + return m_parent->Extended(id, data); + } + + virtual int getWidth() { return m_w; } + virtual int getHeight() { return m_h; } + virtual int getRowSpan() { return m_parent ? m_parent->getRowSpan() : 0; } + + virtual HDC getDC() { return NULL; } + + int m_w,m_h,m_x,m_y; + LICE_IBitmap *m_parent; + //LICE_pixel *m_parentptr; +}; + + +// flags that most blit functions can take + +#define LICE_BLIT_MODE_MASK 0xff +#define LICE_BLIT_MODE_COPY 0 +#define LICE_BLIT_MODE_ADD 1 +#define LICE_BLIT_MODE_DODGE 2 +#define LICE_BLIT_MODE_MUL 3 +#define LICE_BLIT_MODE_OVERLAY 4 +#define LICE_BLIT_MODE_HSVADJ 5 + +#define LICE_BLIT_MODE_CHANCOPY 0xf0 // in this mode, only available for LICE_Blit(), the low nibble is 2 bits of source channel (low 2), 2 bits of dest channel (high 2) + +#define LICE_BLIT_FILTER_MASK 0xff00 +#define LICE_BLIT_FILTER_NONE 0 +#define LICE_BLIT_FILTER_BILINEAR 0x100 // currently pretty slow! ack + + +#define LICE_BLIT_USE_ALPHA 0x10000 // use source's alpha channel + + +// Reaper exports most LICE functions, so the function declarations below +// will collide with reaper_plugin.h +#ifndef LICE_PROVIDED_BY_APP + + +// bitmap loaders + +// dispatch to a linked loader implementation based on file extension +LICE_IBitmap* LICE_LoadImage(const char* filename, LICE_IBitmap* bmp=NULL, bool tryIgnoreExtension=false); +char *LICE_GetImageExtensionList(bool wantAllSup=true, bool wantAllFiles=true); // returns doublenull terminated GetOpenFileName() style list -- free() when done. +bool LICE_ImageIsSupported(const char *filename); // must be a filename that ends in .jpg, etc. if you want to check the extension, pass .ext + + +// pass a bmp if you wish to load it into that bitmap. note that if it fails bmp will not be deleted. +LICE_IBitmap *LICE_LoadPNG(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitmap *bmp=NULL); +LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +#ifndef _WIN32 +LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +#endif + +LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success + +LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success + +LICE_IBitmap *LICE_LoadJPG(const char *filename, LICE_IBitmap *bmp=NULL); +LICE_IBitmap* LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap* bmp = 0); + +LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp=NULL, int *nframes=NULL); // if nframes set, will be set to number of images (stacked vertically), otherwise first frame used + +LICE_IBitmap *LICE_LoadPCX(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success + +LICE_IBitmap *LICE_LoadSVG(const char *filename, LICE_IBitmap *bmp=NULL); + +// bitmap saving +bool LICE_WritePNG(const char *filename, LICE_IBitmap *bmp, bool wantalpha=true); +bool LICE_WriteJPG(const char *filename, LICE_IBitmap *bmp, int quality=95, bool force_baseline=true); +bool LICE_WriteGIF(const char *filename, LICE_IBitmap *bmp, int transparent_alpha=0, bool dither=true); // if alpha + + + Debug + Win32 + + + Debug + X64 + + + Release + Win32 + + + Release + X64 + + + + {141B3F4B-4BA7-472F-A213-EC4D1C06A8FC} + + + + StaticLibrary + false + MultiByte + + + StaticLibrary + false + MultiByte + false + + + StaticLibrary + + + StaticLibrary + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.20506.1 + $(Platform)/$(Configuration)/ + $(Platform)/$(Configuration)/ + lice + .lib + $(Platform)/$(Configuration)/ + $(Platform)/$(Configuration)/ + lice + .lib + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + + Disabled + ../zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;PNG_USE_PNGVCRD;PNG_DEBUG;PNG_LIBPNG_SPECIALBUILD;__MMX__;PNG_HAVE_MMX_COMBINE_ROW;PNG_HAVE_MMX_READ_INTERLACE;PNG_HAVE_MMX_READ_FILTER_ROW;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/lice.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + + + true + .\Debug/lice.bsc + + + + + MaxSpeed + AnySuitable + true + Speed + false + ../zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;__MMX__;PNG_HAVE_MMX_COMBINE_ROW;PNG_HAVE_MMX_READ_INTERLACE;PNG_HAVE_MMX_READ_FILTER_ROW;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + Default + false + false + StreamingSIMDExtensions2 + Fast + false + .\Release/lice.pch + .\Release/ + .\Release/ + .\Release/ + + + Level3 + true + ProgramDatabase + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + + + true + .\Release/lice.bsc + + + + + StreamingSIMDExtensions2 + Fast + true + Speed + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WDL/lice/lice_arc.cpp b/WDL/lice/lice_arc.cpp new file mode 100644 index 00000000..3be69e61 --- /dev/null +++ b/WDL/lice/lice_arc.cpp @@ -0,0 +1,496 @@ +#include "lice.h" +#include "lice_combine.h" +#include + +#define _PI 3.141592653589793238f + +template inline void _SWAP(T& a, T& b) { T tmp = a; a = b; b = tmp; } + +#define A(x) ((LICE_pixel_chan)((x)*255.0+0.5)) + +static bool CachedCircle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) +{ + // fast draw for some small circles + if (r == 1.5f) + { + if (aa) + { + LICE_pixel_chan alphas[25] = + { + A(0.31), A(1.00), A(1.00), A(0.31), + A(1.00), A(0.06), A(0.06), A(1.00), + A(1.00), A(0.06), A(0.06), A(1.00), + A(0.31), A(1.00), A(1.00), A(0.31), + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 4, 4, alpha, mode); + } + else + { + LICE_pixel_chan alphas[25] = + { + A(0.00), A(1.00), A(1.00), A(0.00), + A(1.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(1.00), + A(0.00), A(1.00), A(1.00), A(0.00), + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 4, 4, alpha, mode); + } + return true; + } + else if (r == 2.0f) + { + if (aa) + { + LICE_pixel_chan alphas[25] = + { + A(0.06), A(0.75), A(1.00), A(0.75), A(0.06), + A(0.75), A(0.82), A(0.31), A(0.82), A(0.75), + A(1.00), A(0.31), A(0.00), A(0.31), A(1.00), + A(0.75), A(0.82), A(0.31), A(0.82), A(0.75), + A(0.06), A(0.75), A(1.00), A(0.75), A(0.06) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 5, 5, alpha, mode); + } + else + { + LICE_pixel_chan alphas[25] = + { + A(0.00), A(0.00), A(1.00), A(0.00), A(0.00), + A(0.00), A(1.00), A(0.00), A(1.00), A(0.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(0.00), A(1.00), A(0.00), A(1.00), A(0.00), + A(0.00), A(0.00), A(1.00), A(0.00), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 5, 5, alpha, mode); + } + return true; + } + else if (r == 2.5f) { + if (aa) { + LICE_pixel_chan alphas[36] = { + A(0.06), A(0.75), A(1.00), A(1.00), A(0.75), A(0.06), + A(0.75), A(0.82), A(0.31), A(0.31), A(0.82), A(0.75), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.31), A(1.00), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.31), A(1.00), + A(0.75), A(0.82), A(0.31), A(0.31), A(0.82), A(0.75), + A(0.06), A(0.75), A(1.00), A(1.00), A(0.75), A(0.06) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 6, 6, alpha, mode); + } + else { + LICE_pixel_chan alphas[36] = { + A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), + A(0.00), A(1.00), A(0.00), A(0.00), A(1.00), A(0.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(0.00), A(1.00), A(0.00), A(0.00), A(1.00), A(0.00), + A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 6, 6, alpha, mode); + } + return true; + } + else if (r == 3.0f) { + if (aa) { + LICE_pixel_chan alphas[49] = { + A(0.00), A(0.56), A(1.00), A(1.00), A(1.00), A(0.56), A(0.00), + A(0.56), A(1.00), A(0.38), A(0.25), A(0.38), A(1.00), A(0.56), + A(1.00), A(0.44), A(0.00), A(0.00), A(0.00), A(0.44), A(1.00), + A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), + A(1.00), A(0.44), A(0.00), A(0.00), A(0.00), A(0.44), A(1.00), + A(0.56), A(1.00), A(0.38), A(0.25), A(0.38), A(1.00), A(0.56), + A(0.00), A(0.56), A(1.00), A(1.00), A(1.00), A(0.56), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 7, 7, alpha, mode); + } + else { + LICE_pixel_chan alphas[49] = { + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), + A(0.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(0.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(0.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(0.00), + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 7, 7, alpha, mode); + } + return true; + } + else if (r == 3.5f) { + if (aa) { + LICE_pixel_chan alphas[64] = { + A(0.00), A(0.31), A(0.87), A(1.00), A(1.00), A(0.87), A(0.31), A(0.00), + A(0.31), A(1.00), A(0.69), A(0.25), A(0.25), A(0.69), A(1.00), A(0.31), + A(0.87), A(0.69), A(0.00), A(0.00), A(0.00), A(0.00), A(0.69), A(0.87), + A(1.00), A(0.25), A(0.00), A(0.00), A(0.00), A(0.00), A(0.25), A(1.00), + A(1.00), A(0.25), A(0.00), A(0.00), A(0.00), A(0.00), A(0.25), A(1.00), + A(0.87), A(0.69), A(0.00), A(0.00), A(0.00), A(0.00), A(0.69), A(0.87), + A(0.31), A(1.00), A(0.69), A(0.25), A(0.25), A(0.69), A(1.00), A(0.31), + A(0.00), A(0.31), A(0.87), A(1.00), A(1.00), A(0.87), A(0.31), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 8, 8, alpha, mode); + } + else { + LICE_pixel_chan alphas[64] = { + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), + A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), + A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), + A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 8, 8, alpha, mode); + } + return true; + } + else if (r == 4.0f) { + if (aa) { + LICE_pixel_chan alphas[81] = { + A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00), + A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), + A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), + A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), + A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), + A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), + A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 9, 9, alpha, mode); + } + else { + LICE_pixel_chan alphas[81] = { + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00), + A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), + A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), + A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), + A(0.00), A(1.00), A(1.00), A(0.00), A(0.00), A(0.00), A(1.00), A(1.00), A(0.00), + A(0.00), A(0.00), A(1.00), A(1.00), A(1.00), A(1.00), A(1.00), A(0.00), A(0.00) + }; + LICE_DrawGlyph(dest, cx-r, cy-r, color, alphas, 9, 9, alpha, mode); + } + return true; + } + + return false; +} + + +template class _LICE_CircleDrawer +{ +public: + + static void DrawClippedPt(LICE_IBitmap* dest, int x, int y, int clip[], + int r, int g, int b, int a, int alpha, bool doclip) + { + if (doclip && (x < clip[0] || x >= clip[2] || y < clip[1] || y >= clip[3])) return; + LICE_pixel* px = dest->getBits()+y*dest->getRowSpan()+x; + COMBFUNC::doPix((LICE_pixel_chan*)px, r, g, b, a, alpha); + } + + static void DrawClippedHorzLine(LICE_IBitmap* dest, int y, int xlo, int xhi, int clip[], + int r, int g, int b, int a, int alpha, bool doclip) + { + if (doclip) { + if (y < clip[1] || y >= clip[3]) return; + xlo = max(xlo, clip[0]); + xhi = min(xhi, clip[2]-1); + } + LICE_pixel* px = dest->getBits()+y*dest->getRowSpan()+xlo; + while (xlo <= xhi) { + COMBFUNC::doPix((LICE_pixel_chan*)px, r, g, b, a, alpha); + ++px; + ++xlo; + } + } + + static void DrawClippedCircleAA(LICE_IBitmap* dest, float cx, float cy, float rad, + int clip[], LICE_pixel color, int ai, bool filled, bool doclip) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + float r2 = rad*rad; + float x = 0.0f; + float y = rad; + while (x < y+1.0f) + { + float w = y-floor(y); + + if (w == 0.0f) + { + DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, ai, doclip); + } + else + { + int wa = (int)(ai*w); + int iwa = ai-wa; + + DrawClippedPt(dest, cx+x, cy+y+1, clip, r, g, b, a, wa, doclip); + DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, iwa, doclip); + + DrawClippedPt(dest, cx+x, cy-y+1, clip, r, g, b, a, iwa, doclip); + DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, wa, doclip); + + DrawClippedPt(dest, cx-x, cy+y+1, clip, r, g, b, a, wa, doclip); + DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, iwa, doclip); + + DrawClippedPt(dest, cx-x, cy-y+1, clip, r, g, b, a, iwa, doclip); + DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, wa, doclip); + + DrawClippedPt(dest, cx+y+1, cy+x, clip, r, g, b, a, wa, doclip); + DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, iwa, doclip); + + DrawClippedPt(dest, cx+y+1, cy-x, clip, r, g, b, a, wa, doclip); + DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, iwa, doclip); + + DrawClippedPt(dest, cx-y+1, cy+x, clip, r, g, b, a, iwa, doclip); + DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, wa, doclip); + + DrawClippedPt(dest, cx-y+1, cy-x, clip, r, g, b, a, iwa, doclip); + DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, wa, doclip); + } + + if (filled) + { + DrawClippedHorzLine(dest, cy-y+1, cx-x, cx+x, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy+y, cx-x, cx+x, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy-x, cx-y+1, cx+y, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy+x, cx-y+1, cx+y, clip, r, g, b, a, ai, doclip); + } + + x += 1; + y = sqrt(r2-x*x); + } + } + + static void DrawClippedCircle(LICE_IBitmap* dest, float cx, float cy, float rad, + int clip[], LICE_pixel color, int ai, bool filled, bool doclip) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + float x = 0.0; + float y = rad; + float p = (5.0-rad*4.0)/4.0; + + DrawClippedPt(dest, cx, cy+rad, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx, cy-rad, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+rad, cy, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-rad, cy, clip, r, g, b, a, ai, doclip); + + if (filled) { + DrawClippedHorzLine(dest, cy, cx-rad+1, cx+rad-1, clip, r, g, b, a, ai, doclip); + } + + while (x < y) { + x += 1.0f; + + if (p < 0) { + p += 2.0f*x+1.0f; + } + else { + y -= 1.0f; + p += 2.0*(x-y)+1.0f; + } + + DrawClippedPt(dest, cx+x, cy+y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-x, cy+y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+x, cy-y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-x, cy-y, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+y, cy+x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-y, cy+x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx+y, cy-x, clip, r, g, b, a, ai, doclip); + DrawClippedPt(dest, cx-y, cy-x, clip, r, g, b, a, ai, doclip); + + if (filled) { + DrawClippedHorzLine(dest, cy-y, cx-x+1, cx+x-1, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy+y, cx-x+1, cx+x-1, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy-x, cx-y+1, cx+y-1, clip, r, g, b, a, ai, doclip); + DrawClippedHorzLine(dest, cy+x, cx-y+1, cx+y-1, clip, r, g, b, a, ai, doclip); + } + } + } + + +}; + + +static void __DrawCircleClipped(LICE_IBitmap* dest, float cx, float cy, float rad, + LICE_pixel color, int ia, bool aa, bool filled, int mode, int *clip, bool doclip) +{ + // todo: more clipped/filled versions (to optimize constants out?) + if (aa) + { + #define __LICE__ACTION(COMBFUNC) _LICE_CircleDrawer::DrawClippedCircleAA(dest, cx, cy, rad, clip, color, ia, filled, doclip) + __LICE_ACTION_NOSRCALPHA(mode, ia,false) + #undef __LICE__ACTION + } + else + { + #define __LICE__ACTION(COMBFUNC) _LICE_CircleDrawer::DrawClippedCircle(dest, cx, cy, rad, clip, color, ia, filled, doclip) + __LICE_ACTION_CONSTANTALPHA(mode,ia,false) + #undef __LICE__ACTION + } +} + + +static void __DrawArc(int w, int h, LICE_IBitmap* dest, float cx, float cy, float rad, float anglo, float anghi, + LICE_pixel color, int ialpha, bool aa, int mode) +{ + // -2PI <= anglo <= anghi <= 2PI + + if (anglo < -_PI && anghi > -_PI) + { + __DrawArc(w,h,dest, cx, cy, rad, anglo, -_PI, color, ialpha, aa,mode); + anglo=-_PI; + } + + if (anglo < 0.0f && anghi > 0.0f) + { + __DrawArc(w,h,dest, cx, cy, rad, anglo+2.0f*_PI, 2.0f*_PI, color, ialpha, aa,mode); + anglo=0.0f; + } + + if (anglo < _PI && anghi > _PI) + { + __DrawArc(w,h,dest, cx, cy, rad, anglo, _PI, color, ialpha, aa,mode); + anglo=_PI; + } + + int ylo = (int) (cy-rad*cos(anglo)+0.5); + int yhi = (int) (cy-rad*cos(anghi)+0.5); + + if (yhi < ylo) { int tmp = ylo; ylo = yhi; yhi=tmp; } + + int clip[4]={0,max(0, ylo),w,min(h, yhi+1)}; + + if (anglo < -_PI || (anglo >= 0.0f && anglo < _PI)) + { + if (cx>0) clip[0]=cx; + } + else + { + if (cxisFlipped()) { cy=dest->getHeight()-1-cy; minAngle=_PI-minAngle; maxAngle=_PI-maxAngle; } + + if (maxAngle < minAngle) + { + float tmp=maxAngle; + maxAngle=minAngle; + minAngle=tmp; + } + + if (maxAngle - minAngle >= 2.0f*_PI) + { + LICE_Circle(dest,cx,cy,r,color,alpha,mode,aa); + return; + } + + if (maxAngle >= 2.0f*_PI) + { + float tmp = fmod(maxAngle,2.0f*_PI); + minAngle -= maxAngle - tmp; // reduce by factors of 2PI + maxAngle = tmp; + } + else if (minAngle <= -2.0f*_PI) + { + float tmp = fmod(minAngle,2.0f*_PI); + maxAngle -= minAngle - tmp; // toward zero by factors of 2pi + minAngle = tmp; + } + + // -2PI <= minAngle <= maxAngle <= 2PI + + int ia = (int) (alpha*256.0f); + if (!ia) return; + + __DrawArc(dest->getWidth(),dest->getHeight(),dest,cx,cy,r,minAngle,maxAngle,color,ia,aa,mode); +} + + + + +void LICE_Circle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) +{ + if (!dest) return; + if (CachedCircle(dest, cx, cy, r, color, alpha, mode, aa)) return; + + if (dest->isFlipped()) cy=dest->getHeight()-1-cy; + + int ia = (int) (alpha*256.0f); + if (!ia) return; + + int w = dest->getWidth(), h = dest->getHeight(); + int clip[4] = { 0, 0, w, h }; + + bool doclip = (cx-r-1 < 0 || cy-r-1 < 0 || cx+r+1 >= w || cy+r+1 >= h); + + __DrawCircleClipped(dest,cx,cy,r,color,ia,aa,false,mode,clip,doclip); +} + +void LICE_FillCircle(LICE_IBitmap* dest, float cx, float cy, float r, LICE_pixel color, float alpha, int mode, bool aa) +{ + if (!dest) return; + if (dest->isFlipped()) cy=dest->getHeight()-1-cy; + + int ia = (int) (alpha*256.0f); + if (!ia) return; + int w = dest->getWidth(), h = dest->getHeight(); + int clip[4] = { 0, 0, w, h }; + + bool doclip = (cx-r-1 < 0 || cy-r-1 < 0 || cx+r+1 >= w || cy+r+1 >= h); + __DrawCircleClipped(dest,cx,cy,r,color,ia,aa,true,mode,clip,doclip); +} + + +void LICE_RoundRect(LICE_IBitmap *drawbm, float xpos, float ypos, float w, float h, int cornerradius, + LICE_pixel col, float alpha, int mode, bool aa) +{ + if (cornerradius>0) + { + float cr=cornerradius; + if (cr > w*0.5) cr=w*0.5; + if (cr > h*0.5) cr=h*0.5; + cr=floor(cr); + if (cr>=2) + { + LICE_Line(drawbm,xpos+cr,ypos,xpos+w-cr,ypos,col,alpha,mode,aa); + LICE_Line(drawbm,xpos+cr-1,ypos+h,xpos+w-cr,ypos+h,col,alpha,mode,aa); + LICE_Line(drawbm,xpos+w,ypos+cr,xpos+w,ypos+h-cr,col,alpha,mode,aa); + LICE_Line(drawbm,xpos,ypos+cr-1,xpos,ypos+h-cr,col,alpha,mode,aa); + + + LICE_Arc(drawbm,xpos+cr,ypos+cr,cr,-_PI*0.5f,0,col,alpha,mode,aa); + LICE_Arc(drawbm,xpos+w-cr,ypos+cr,cr,0,_PI*0.5f,col,alpha,mode,aa); + LICE_Arc(drawbm,xpos+w-cr,ypos+h-cr,cr,_PI*0.5f,_PI,col,alpha,mode,aa); + LICE_Arc(drawbm,xpos+cr,ypos+h-cr,cr,_PI,_PI*1.5f,col,alpha,mode,aa); + + return; + } + } + + LICE_DrawRect(drawbm, xpos, ypos, w, h, col, alpha, mode); +} + diff --git a/WDL/lice/lice_bezier.h b/WDL/lice/lice_bezier.h new file mode 100644 index 00000000..d10381d1 --- /dev/null +++ b/WDL/lice/lice_bezier.h @@ -0,0 +1,295 @@ +#ifndef _LICE_BEZIER_ +#define _LICE_BEZIER_ + +#include "lice.h" +#include + +// Returns quadratic bezier x, y for a given t in [0,1]. +template +void LICE_Bezier(T ctrl_x1, T ctrl_x2, T ctrl_x3, + T ctrl_y1, T ctrl_y2, T ctrl_y3, double t, T* pX, T* pY) +{ + double it = 1.0 - t; + double a = it * it; + double b = 2.0 * it * t; + double c = t * t; + *pX = (T) (a * (double) ctrl_x1 + b * (double) ctrl_x2 + c * (double) ctrl_x3); + *pY = (T) (a * (double) ctrl_y1 + b * (double) ctrl_y2 + c * (double) ctrl_y3); +} + +template +void LICE_CBezier_GetCoeffs(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, + T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, + double* pAX, double* pBX, double* pCX, + double* pAY, double* pBY, double* pCY) +{ + double cx = *pCX = 3.0 * (double) (ctrl_x2 - ctrl_x1); + double bx = *pBX = 3.0 * (double) (ctrl_x3 - ctrl_x2) - cx; + *pAX = (double) (ctrl_x4 - ctrl_x1) - cx - bx; + double cy = *pCY = 3.0 * (double) (ctrl_y2 - ctrl_y1); + double by = *pBY = 3.0 * (double) (ctrl_y3 - ctrl_y2) - cy; + *pAY = (double) (ctrl_y4 - ctrl_y1) - cy - by; +} + +// Returns cubic bezier x, y for a given t in [0,1]. +template +void LICE_CBezier(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, + T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, double t, T* pX, T* pY) +{ + double ax, bx, cx, ay, by, cy; + LICE_CBezier_GetCoeffs(ctrl_x1, ctrl_x2, ctrl_x3, ctrl_x4, + ctrl_y1, ctrl_y2, ctrl_y3, ctrl_y4, + &ax, &bx, &cx, &ay, &by, &cy); + + double t2 = t * t; + double t3 = t * t2; + *pX = (T) (ax * t3 + bx * t2 + cx * t) + ctrl_x1; + *pY = (T) (ay * t3 + by * t2 + cy * t) + ctrl_y1; +} + +// Returns quadratic bezier y for a given x in [x1, x3] (for rasterizing). +// ctrl_x1 < ctrl_x3 required. +template +T LICE_Bezier_GetY(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_y1, T ctrl_y2, T ctrl_y3, T x, double* pt=0) +{ + if (x <= ctrl_x1) + { + if (pt) *pt = 0.0; + return ctrl_y1; + } + if (x >= ctrl_x3) + { + if (pt) *pt = 1.0; + return ctrl_y3; + } + + double a = (double) ctrl_x1 - (double) (2 * ctrl_x2) + (double) ctrl_x3; + if (a == 0.0) // linear + { + T y = ctrl_y1; + double t = 0.0; + if (ctrl_x1 != ctrl_x3) + { + t = (x-ctrl_x1)/(ctrl_x3-ctrl_x1); + y += t*(ctrl_y3-ctrl_y1); + } + if (pt) *pt = t; + return y; + } + + double b = (double) (2 * (ctrl_x2 - ctrl_x1)); + double c = (double) (ctrl_x1 - x); + double t = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a); + double it = 1.0 - t; + + a = it * it; + b = 2.0 * it * t; + c = t * t; + + if (pt) *pt = t; + return (T) (a * (double) ctrl_y1 + b * (double) ctrl_y2 + c * (double) ctrl_y3); +} + +// Special case for x = y = [0,1] +template +void LICE_Bezier_Norm(T ctrl_x2, T ctrl_y2, double t, T* pX, T* pY) +{ + double b = 2.0 * (1.0 - t) * t; + double c = t * t; + *pX = (T) (b * (double) ctrl_x2 + c); + *pY = (T) (b * (double) ctrl_y2 + c); +} + +// special case for x = y = [0,1]. +template +T LICE_Bezier_GetY_Norm(T ctrl_x2, T ctrl_y2, T x) +{ + if (x < (T) 0.0) { + return (T) 0.0; + } + if (x >= (T) 1.0) { + return (T) 1.0; + } + if (ctrl_x2 == (T) 0.5) { // linear + return x; + } + + double b = (double) (2 * ctrl_x2); + double a = 1.0 - b; + double c = (double) -x; + double t = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a); + + b = 2.0 * (1.0 - t) * t; + c = t * t; + return (T) (b * (double) ctrl_y2 + c); +} + +// Finds the cardinal bezier control points surrounding x2. +// Cubic bezier over (x1,x1b,x2a,x2), (y1,y1b,y2a,y2) or +// quadratic bezier over (x1,x1b,mid(x1b,x2a)), (y1,y1b,mid(y1b,y2a)) +// will smoothly interpolate between (x1,y1) and (x2,y2) while preserving all existing values. +// The lower alpha is, the more tame the bezier curve will be (0.25 = subtle). +template +void LICE_Bezier_FindCardinalCtlPts(double alpha, T x1, T x2, T x3, T y1, T y2, T y3, + T* ctrl_x2a, T* ctrl_x2b, T* ctrl_y2a, T* ctrl_y2b) +{ + double dxa = alpha * (double) (x2 - x1); + double dxb = alpha * (double) (x3 - x2); + if (ctrl_x2a) *ctrl_x2a = x2 - (T) dxa; + if (ctrl_x2b) *ctrl_x2b = x2 + (T) dxb; + + if (x1 == x3) + { + if (ctrl_y2a) *ctrl_y2a = y2; + if (ctrl_y2b) *ctrl_y2b = y2; + } + else + { + double m = (double) (y3 - y1) / (double) (x3 - x1); + if (ctrl_y2a) *ctrl_y2a = y2 - (T) (m * dxa); + if (ctrl_y2b) *ctrl_y2b = y2 + (T) (m * dxb); + } +} + +// Basic quadratic nurbs. Given a set of n (x,y) pairs, +// populate pDest with the unit-spaced nurbs curve. +// pDest must be passed in with size (int) (*(pX+n-1) - *pX). +// pX must be monotonically increasing and no duplicates. +template +inline void LICE_QNurbs(T* pDest, T* pX, T* pY, int n) +{ + double x1 = (double) *pX++, x2 = (double) *pX++; + double y1 = (double) *pY++, y2 = (double) *pY++; + double xm1, xm2 = 0.5 * (x1 + x2); + double ym1, ym2 = 0.5 * (y1 + y2); + + double m = (y2 - y1) / (x2 - x1); + double xi = x1, yi = y1; + for (/* */; xi < xm2; xi += 1.0, yi += m, ++pDest) + { + *pDest = (T) yi; + } + + for (int i = 2; i < n; ++i, ++pX, ++pY) + { + x1 = x2; + x2 = (double) *pX; + y1 = y2; + y2 = (double) *pY; + + xm1 = xm2; + xm2 = 0.5 * (x1 + x2); + ym1 = ym2; + ym2 = 0.5 * (y1 + y2); + + if (ym1 == ym2) + { + for (/* */; xi < xm2; xi += 1.0, ++pDest) + { + *pDest = (T) y1; + } + } + else + { + for (/* */; xi < xm2; xi += 1.0, ++pDest) + { + *pDest = (T) LICE_Bezier_GetY(xm1, x1, xm2, ym1, y1, ym2, xi); + } + } + } + + m = (y2 - y1) / (x2 - x1); + yi = ym2; + for (/* */; xi < x2; xi += 1.0, yi += m, ++pDest) + { + *pDest = (T) yi; + } +} + +#define CBEZ_ITERS 8 + +#define EVAL_CBEZ(tx,a,b,c,d,t) \ +{ \ + double _t2=t*t; \ + tx=(a*t*_t2+b*_t2+c*t+d); \ +} + +#define EVAL_CBEZXY(tx, ty, ax, bx, cx, dx, ay, by, cy, dy, t) \ +{ \ + double _t2=t*t; \ + double _t3=t*_t2; \ + tx=ax*_t3+bx*_t2+cx*t+dx; \ + ty=ay*_t3+by*_t2+cy*t+dy; \ +} + +template +T LICE_CBezier_GetY(T ctrl_x1, T ctrl_x2, T ctrl_x3, T ctrl_x4, + T ctrl_y1, T ctrl_y2, T ctrl_y3, T ctrl_y4, T x, + T* pNextX = 0, T* pdYdX = 0, double* ptLo = 0, double* ptHi = 0) +{ + if (x < ctrl_x1) + { + if (pNextX) *pNextX = ctrl_x1; + if (pdYdX) *pdYdX = (T) 0.0; + return ctrl_y1; + } + if (x >= ctrl_x4) + { + if (pNextX) *pNextX = ctrl_x4; + if (pdYdX) *pdYdX = (T) 0.0; + return ctrl_y4; + } + + double ax, bx, cx, ay, by, cy; + LICE_CBezier_GetCoeffs(ctrl_x1, ctrl_x2, ctrl_x3, ctrl_x4, + ctrl_y1, ctrl_y2, ctrl_y3, ctrl_y4, + &ax, &bx, &cx, &ay, &by, &cy); + + double tx, t, tLo = 0.0, tHi = 1.0; + double xLo, xHi, yLo, yHi; + int i; + for (i = 0; i < CBEZ_ITERS; ++i) + { + t = 0.5 * (tLo + tHi); + EVAL_CBEZ(tx, ax, bx, cx, (double) ctrl_x1, t); + if (tx < (double) x) + { + tLo = t; + xLo = tx; + } + else if (tx > (double) x) + { + tHi = t; + xHi = tx; + } + else + { + tLo = t; + xLo = tx; + tHi = t + 1.0/pow(2.0,CBEZ_ITERS); + if (tHi > 1.0) tHi = 1.0; // floating point error + EVAL_CBEZ(xHi, ax, bx, cx, (double) ctrl_x1, tHi); + break; + } + } + + if (tLo == 0.0) EVAL_CBEZ(xLo, ax, bx, cx, (double) ctrl_x1, 0.0); + if (tHi == 1.0) EVAL_CBEZ(xHi, ax, bx, cx, (double) ctrl_x1, 1.0); + + EVAL_CBEZ(yLo, ay, by, cy, (double) ctrl_y1, tLo); + EVAL_CBEZ(yHi, ay, by, cy, (double) ctrl_y1, tHi); + + double dYdX = (xLo == xHi ? 0.0 : (yHi - yLo) / (xHi - xLo)); + double y = yLo + ((double) x - xLo) * dYdX; + + if (pNextX) *pNextX = (T) xHi; + if (pdYdX) *pdYdX = (T) dYdX; + + if (ptLo) *ptLo = tLo; + if (ptHi) *ptHi = tHi; + + return (T) y; +} + +#endif + diff --git a/WDL/lice/lice_bmp.cpp b/WDL/lice/lice_bmp.cpp new file mode 100644 index 00000000..fab3d98b --- /dev/null +++ b/WDL/lice/lice_bmp.cpp @@ -0,0 +1,114 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_bmp.cpp (BMP loading for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" +#ifndef _WIN32 +#include "../swell/swell.h" +#endif + +static LICE_IBitmap *hbmToBit(HBITMAP hbm, LICE_IBitmap *bmp) +{ + BITMAP bm; + GetObject(hbm, sizeof(BITMAP), (LPSTR)&bm); + + LICE_SysBitmap sysbitmap(bm.bmWidth,bm.bmHeight); + +#ifdef _WIN32 + HDC hdc=CreateCompatibleDC(NULL); + HGDIOBJ oldBM=SelectObject(hdc,hbm); + + BitBlt(sysbitmap.getDC(),0,0,bm.bmWidth,bm.bmHeight,hdc,0,0,SRCCOPY); + GdiFlush(); + + if (!bmp) bmp=new LICE_MemBitmap(bm.bmWidth,bm.bmHeight); + LICE_Copy(bmp,&sysbitmap); + + SelectObject(hdc,oldBM); + DeleteDC(hdc); + #else + LICE_Clear(&sysbitmap,0); + RECT r={0,0,bm.bmWidth,bm.bmHeight}; + DrawImageInRect(sysbitmap.getDC(),hbm,&r); + if (!bmp) bmp=new LICE_MemBitmap(bm.bmWidth,bm.bmHeight); + LICE_Copy(bmp,&sysbitmap); + #endif + + LICE_FillRect(bmp,0,0,bmp->getWidth(),bmp->getHeight(),LICE_RGBA(0,0,0,255),1.0f,LICE_BLIT_MODE_ADD); + + return bmp; +} + + +LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +{ + HBITMAP bm=NULL; +#ifdef _WIN32 + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + bm = (HBITMAP) LoadImageW(NULL,wf,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); + } + + if (!bm) bm=(HBITMAP) LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); +#else + bm=(HBITMAP) LoadNamedImage(filename,false); +#endif + if (!bm) return 0; + + LICE_IBitmap *ret=hbmToBit(bm,bmp); + + DeleteObject(bm); + return ret; +} + +#ifdef _WIN32 +LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +{ + HBITMAP bm=(HBITMAP) LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); + if (!bm) return 0; + + LICE_IBitmap *ret=hbmToBit(bm,bmp); + + DeleteObject(bm); + return ret; +} +#endif + + + +class LICE_BMPLoader +{ +public: + _LICE_ImageLoader_rec rec; + LICE_BMPLoader() + { + rec.loadfunc = loadfunc; + rec.get_extlist = get_extlist; + rec._next = LICE_ImageLoader_list; + LICE_ImageLoader_list = &rec; + } + + static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) + { + if (checkFileName) + { + const char *p=filename; + while (*p)p++; + while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".bmp")) return 0; + } + return LICE_LoadBMP(filename,bmpbase); + } + static const char *get_extlist() + { + return "BMP files (*.BMP)\0*.BMP\0"; + } + +}; + +LICE_BMPLoader LICE_bmpldr; \ No newline at end of file diff --git a/WDL/lice/lice_colorspace.cpp b/WDL/lice/lice_colorspace.cpp new file mode 100644 index 00000000..433cfc94 --- /dev/null +++ b/WDL/lice/lice_colorspace.cpp @@ -0,0 +1,134 @@ +#include "lice.h" +#include + +#define LICE_COMBINE_IMPLEMENT_HSV +#include "lice_combine.h" + + +LICE_pixel LICE_AlterColorHSV_int(LICE_pixel color, int dH, int dS, int dV) // H is rolled over [0,384), S and V are clamped [0,255) +{ + int h, s, v; + LICE_RGB2HSV(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), &h, &s, &v); + + h += dH; + s += dS; + v += dV; + + if (h < 0) h += 384; + else if (h >= 384) h -= 384; + + if (s & ~255) + { + if (s<0) s = 0; + else s = 255; + } + + if (v&~255) + { + if (v < 0) v = 0.; + else v = 255; + } + + return LICE_HSV2Pix(h, s, v, LICE_GETA(color)); +} + +LICE_pixel LICE_AlterColorHSV(LICE_pixel color, float dH, float dS, float dV) // H is rolled over, S and V are clamped, all [0,1) +{ + int dHi = (int)(dH*384.0f); + int dSi = (int)(dS*255.0f); + int dVi = (int)(dV*255.0f); + return LICE_AlterColorHSV_int(color, dHi, dSi, dVi); +} + +void LICE_AlterBitmapHSV(LICE_IBitmap* src, float dH, float dS, float dV) // H is rolled over, S and V are clamped +{ + if (src) LICE_AlterRectHSV(src,0,0,src->getWidth(),src->getHeight(),dH,dS,dV); +} + +void LICE_AlterRectHSV(LICE_IBitmap* src, int x, int y, int w, int h, float dH, float dS, float dV) // H is rolled over, S and V are clamped +{ + if (!src) return; + + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + if (x+w > src->getWidth()) { + w = src->getWidth()-x; + } + if (y+h > src->getHeight()) { + h = src->getHeight()-y; + } + + int span = src->getRowSpan(); + LICE_pixel* px = src->getBits()+y*span+x; + + int dHi = (int)(dH*384.0f); + int dSi = (int)(dS*255.0f); + int dVi = (int)(dV*255.0f); + if (dHi > 383) dHi=383; + else if (dHi < -383) dHi=-383; + + + if (!dHi && !dSi && !dVi) return; // no mod + + if (w*h > 8192) + { + // generate a table of HSV translations with clip/clamp + unsigned char stab[256], vtab[256]; + short htab[384]; + int x; + for(x=0;x<256;x++) + { + int a=x+dSi; + if(a<0)a=0; else if (a>255)a=255; + stab[x]=a; + + a=x+dVi; + if(a<0)a=0; else if (a>255)a=255; + vtab[x]=a; + + a=x+dHi; + if(a<0)a+=384; else if (a>=384)a-=384; + htab[x]=a; + } + for(;x<384;x++) + { + int a=x+dHi; + if(a<0)a+=384; else if (a>=384)a-=384; + htab[x]=a; + } + + while (h-->0) + { + LICE_pixel* tpx = px; + px+=span; + int xi=w; + while (xi-->0) + { + LICE_pixel color = *tpx; + int h,s,v; + LICE_RGB2HSV(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), &h, &s, &v); + *tpx++ = LICE_HSV2Pix(htab[h],stab[s],vtab[v],LICE_GETA(color)); + } + } + } + else + { + while (h-->0) + { + LICE_pixel* tpx = px; + px+=span; + int xi=w; + while (xi-->0) + { + *tpx = LICE_AlterColorHSV_int(*tpx, dHi, dSi, dVi); + tpx++; + } + } + } +} diff --git a/WDL/lice/lice_combine.h b/WDL/lice/lice_combine.h new file mode 100644 index 00000000..1613e520 --- /dev/null +++ b/WDL/lice/lice_combine.h @@ -0,0 +1,831 @@ +#ifndef _LICE_COMBINE_H_ +#define _LICE_COMBINE_H_ + +#if defined(_MSC_VER) +#pragma warning(disable:4244) // float-to-int +#endif + +#define __LICE_BOUND(x,lo,hi) ((x)<(lo)?(lo):((x)>(hi)?(hi):(x))) + + + +#define LICE_PIXEL_HALF(x) (((x)>>1)&0x7F7F7F7F) +#define LICE_PIXEL_QUARTER(x) (((x)>>2)&0x3F3F3F3F) +#define LICE_PIXEL_EIGHTH(x) (((x)>>3)&0x1F1F1F1F) + + + +#if defined(_MSC_VER) && !defined(_WIN64) +static inline int __LICE_TOINT(double x) // don't use this _everywhere_ since it doesnt round the same as (int) +{ + int tmp; + __asm + { + fld x + fistp tmp + }; + return tmp; +} +#else +#define __LICE_TOINT(x) ((int)(x)) +#endif + + +static inline void __LICE_BilinearFilterI(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int xfrac, int yfrac) +{ + int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; + int f3=yfrac-f4; // (1.0-xfrac)*yfrac; + int f2=xfrac-f4; // xfrac*(1.0-yfrac); + int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); + #define DOCHAN(output, inchan) \ + (output)=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)/65536; + DOCHAN(*r,LICE_PIXEL_R) + DOCHAN(*g,LICE_PIXEL_G) + DOCHAN(*b,LICE_PIXEL_B) + DOCHAN(*a,LICE_PIXEL_A) + #undef DOCHAN +} + +static inline void __LICE_BilinearFilterIPixOut(LICE_pixel_chan *out, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int xfrac, int yfrac) +{ + int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; + int f3=yfrac-f4; // (1.0-xfrac)*yfrac; + int f2=xfrac-f4; // xfrac*(1.0-yfrac); + int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); + #define DOCHAN(inchan) \ + (out[inchan])=(pin[(inchan)]*f1 + pin[4+(inchan)]*f2 + pinnext[(inchan)]*f3 + pinnext[4+(inchan)]*f4)/65536; + DOCHAN(LICE_PIXEL_R) + DOCHAN(LICE_PIXEL_G) + DOCHAN(LICE_PIXEL_B) + DOCHAN(LICE_PIXEL_A) + #undef DOCHAN +} + + +static inline void __LICE_BilinearFilterI_2(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int npoffs, int xfrac, int yfrac) +{ + int f4=((unsigned int)xfrac*(unsigned int)yfrac)/65536; + int f3=yfrac-f4; // (1.0-xfrac)*yfrac; + int f2=xfrac-f4; // xfrac*(1.0-yfrac); + int f1=65536-yfrac-f2; // (1.0-xfrac)*(1.0-yfrac); + npoffs*=4; + *r=(pin[LICE_PIXEL_R]*f1 + pin[npoffs+LICE_PIXEL_R]*f2 + pinnext[LICE_PIXEL_R]*f3 + pinnext[npoffs+LICE_PIXEL_R]*f4)/65536; + *g=(pin[LICE_PIXEL_G]*f1 + pin[npoffs+LICE_PIXEL_G]*f2 + pinnext[LICE_PIXEL_G]*f3 + pinnext[npoffs+LICE_PIXEL_G]*f4)/65536; + *b=(pin[LICE_PIXEL_B]*f1 + pin[npoffs+LICE_PIXEL_B]*f2 + pinnext[LICE_PIXEL_B]*f3 + pinnext[npoffs+LICE_PIXEL_B]*f4)/65536; + *a=(pin[LICE_PIXEL_A]*f1 + pin[npoffs+LICE_PIXEL_A]*f2 + pinnext[LICE_PIXEL_A]*f3 + pinnext[npoffs+LICE_PIXEL_A]*f4)/65536; +} + + +static inline void __LICE_LinearFilterI(int *r, int *g, int *b, int *a, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int frac) +{ + int f=65536-frac; + *r=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)/65536; + *g=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)/65536; + *b=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)/65536; + *a=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)/65536; +} +static inline void __LICE_LinearFilterIPixOut(LICE_pixel_chan *out, LICE_pixel_chan *pin, LICE_pixel_chan *pinnext, int frac) +{ + int f=65536-frac; + out[LICE_PIXEL_R]=(pin[LICE_PIXEL_R]*f + pinnext[LICE_PIXEL_R]*frac)/65536; + out[LICE_PIXEL_G]=(pin[LICE_PIXEL_G]*f + pinnext[LICE_PIXEL_G]*frac)/65536; + out[LICE_PIXEL_B]=(pin[LICE_PIXEL_B]*f + pinnext[LICE_PIXEL_B]*frac)/65536; + out[LICE_PIXEL_A]=(pin[LICE_PIXEL_A]*f + pinnext[LICE_PIXEL_A]*frac)/65536; +} + +static void inline _LICE_MakePixelClamp(LICE_pixel_chan *out, int r, int g, int b, int a) +{ +#define LICE_PIX_MAKECHAN(a,b) out[a] = (b&~0xff) ? (b<0?0:255) : b; + LICE_PIX_MAKECHAN(LICE_PIXEL_B,b) + LICE_PIX_MAKECHAN(LICE_PIXEL_G,g) + LICE_PIX_MAKECHAN(LICE_PIXEL_R,r) + LICE_PIX_MAKECHAN(LICE_PIXEL_A,a) +#undef LICE_PIX_MAKECHAN +} + +static void inline _LICE_MakePixelNoClamp(LICE_pixel_chan *out, LICE_pixel_chan r, LICE_pixel_chan g, LICE_pixel_chan b, LICE_pixel_chan a) +{ +#define LICE_PIX_MAKECHAN(a,b) out[a] = b; + LICE_PIX_MAKECHAN(LICE_PIXEL_B,b) + LICE_PIX_MAKECHAN(LICE_PIXEL_G,g) + LICE_PIX_MAKECHAN(LICE_PIXEL_R,r) + LICE_PIX_MAKECHAN(LICE_PIXEL_A,a) +#undef LICE_PIX_MAKECHAN +} + + + +#define HSV_P v*(256-s)/256 +#define HSV_Q(hval) v*(16384-(hval)*s)/16384 +#define HSV_T(hval) v*(16384-(64-(hval))*s)/16384 +#define HSV_X v +extern unsigned short _LICE_RGB2HSV_invtab[256]; // 65536/idx - 1 + +#ifdef LICE_COMBINE_IMPLEMENT_HSV + LICE_pixel LICE_HSV2Pix(int h, int s, int v, int alpha) + #define __LICE_HSV2Pix LICE_HSV2Pix +#else + static inline LICE_pixel __LICE_HSV2Pix(int h, int s, int v, int alpha) +#endif +{ + if (h<192) + { + if (h<64) return LICE_RGBA(HSV_X,HSV_T(h),HSV_P,alpha); + if (h<128) return LICE_RGBA(HSV_Q(h-64),HSV_X,HSV_P,alpha); + return LICE_RGBA(HSV_P,HSV_X,HSV_T(h-128),alpha); + } + if (h < 256) return LICE_RGBA(HSV_P,HSV_Q(h-192),HSV_X,alpha); + if (h < 320) return LICE_RGBA(HSV_T(h-256),HSV_P,HSV_X,alpha); + return LICE_RGBA(HSV_X,HSV_P,HSV_Q(h-320),alpha); +} + +#ifdef LICE_COMBINE_IMPLEMENT_HSV +void LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b) +#define __LICE_HSV2RGB LICE_HSV2RGB +#else +static inline void __LICE_HSV2RGB(int h, int s, int v, int* r, int* g, int* b) +#endif +{ + if (h<192) + { + if (h<64) + { + *r = HSV_X; *g = HSV_T(h); *b = HSV_P; + } + else if (h<128) + { + *r = HSV_Q(h-64); *g = HSV_X; *b = HSV_P; + } + else + { + *r = HSV_P; *g = HSV_X; *b = HSV_T(h-128); + } + } + else + { + if (h < 256) + { + *r = HSV_P; *g = HSV_Q(h-192); *b = HSV_X; + } + else if (h < 320) + { + *r = HSV_T(h-256); *g = HSV_P; *b = HSV_X; + } + else + { + *r = HSV_X; *g = HSV_P; *b = HSV_Q(h-320); + } + } +} + + +#define LICE_RGB2HSV_USE_TABLE +// h = [0,384), s and v = [0,256) + +#ifdef LICE_COMBINE_IMPLEMENT_HSV + void LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v) + #define __LICE_RGB2HSV LICE_RGB2HSV +#else + static inline void __LICE_RGB2HSV(int r, int g, int b, int* h, int* s, int* v) +#endif +{ + + // this makes it just 3 conditional branches per call + int df,d,maxrgb; + int degoffs; + if (g > r) + { + if (g>b) // green max + { + maxrgb=g; + degoffs=128; + df = maxrgb - min(b,r); + d=b-r; + } + else // blue max + { + maxrgb=b; + degoffs=256; + df = maxrgb - min(g,r); + d=r-g; + } + } + else // r >= g + { + if (r > b) // red max + { + maxrgb=r; + + if (g>1) &0x7f7f7f7f) + ((src>>1)&0x7f7f7f7f); + } +}; + +class _LICE_CombinePixelsHalfMixClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + _LICE_MakePixelClamp(dest, + (dest[LICE_PIXEL_R]+r)/2, + (dest[LICE_PIXEL_G]+g)/2, + (dest[LICE_PIXEL_B]+b)/2, + (dest[LICE_PIXEL_A]+a)/2); + } + +}; + + +class _LICE_CombinePixelsHalfMix2FAST +{ +public: + static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-halfed and masked + { + *dest = ((*dest>>1) &0x7f7f7f7f) + src; + } +}; + +class _LICE_CombinePixelsQuarterMix2FAST +{ +public: + static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-quartered and masked + { + LICE_pixel tmp = *dest; + *dest = ((tmp>>1) &0x7f7f7f7f) + ((tmp>>2) &0x3f3f3f3f) + src; + } +}; + + +class _LICE_CombinePixelsThreeQuarterMix2FAST +{ +public: + static inline void doPixFAST(LICE_pixel *dest, LICE_pixel src) // src is pre-quartered and masked + { + *dest = ((*dest>>2) &0x3f3f3f3f) + src; + } +}; + +class _LICE_CombinePixelsCopyNoClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + int sc=(256-alpha); + + // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) + _LICE_MakePixelNoClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + a + ((dest[LICE_PIXEL_A]-a)*sc)/256); + } +}; + +class _LICE_CombinePixelsCopyClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + int sc=(256-alpha); + + // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) + _LICE_MakePixelClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + a + ((dest[LICE_PIXEL_A]-a)*sc)/256); + } +}; + +class _LICE_CombinePixelsCopySourceAlphaNoClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + int sc2=(alpha*(a+1))/256; + int sc = 256 - sc2; + + _LICE_MakePixelNoClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + min(255,sc2 + dest[LICE_PIXEL_A])); + } + } +}; + +class _LICE_CombinePixelsCopySourceAlphaClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + int sc2=(alpha*(a+1))/256; + int sc = 256 - sc2; + + _LICE_MakePixelClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + sc2 + dest[LICE_PIXEL_A]); + } + } +}; +class _LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmNoClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + if (a==255) + { + _LICE_MakePixelNoClamp(dest,r,g,b,a); + } + else + { + int sc=(255-a); + + _LICE_MakePixelNoClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + min(255,a + dest[LICE_PIXEL_A])); + } + } + } +}; +class _LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + if (a==255) + { + _LICE_MakePixelClamp(dest,r,g,b,a); + } + else + { + int sc=(255-a); + + _LICE_MakePixelClamp(dest, + r + ((dest[LICE_PIXEL_R]-r)*sc)/256, + g + ((dest[LICE_PIXEL_G]-g)*sc)/256, + b + ((dest[LICE_PIXEL_B]-b)*sc)/256, + a + dest[LICE_PIXEL_A]); + } + } + } +}; + +#ifndef LICE_DISABLE_BLEND_ADD + +class _LICE_CombinePixelsAdd +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + // don't check alpha=0 here, since the caller should (since alpha is usually used for static alphas) + + _LICE_MakePixelClamp(dest, + dest[LICE_PIXEL_R]+(r*alpha)/256, + dest[LICE_PIXEL_G]+(g*alpha)/256, + dest[LICE_PIXEL_B]+(b*alpha)/256, + dest[LICE_PIXEL_A]+(a*alpha)/256); + + } +}; +class _LICE_CombinePixelsAddSourceAlpha +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + alpha=(alpha*(a+1))/256; + _LICE_MakePixelClamp(dest, + dest[LICE_PIXEL_R]+(r*alpha)/256, + dest[LICE_PIXEL_G]+(g*alpha)/256, + dest[LICE_PIXEL_B]+(b*alpha)/256, + dest[LICE_PIXEL_A]+(a*alpha)/256); + } + } +}; + +#else // !LICE_DISABLE_BLEND_ADD +#define _LICE_CombinePixelsAddSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp +#define _LICE_CombinePixelsAdd _LICE_CombinePixelsCopyClamp +#endif + +#ifndef LICE_DISABLE_BLEND_DODGE + +class _LICE_CombinePixelsColorDodge +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + int src_r = 256-r*alpha/256; + int src_g = 256-g*alpha/256; + int src_b = 256-b*alpha/256; + int src_a = 256-a*alpha/256; + + _LICE_MakePixelClamp(dest, + src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R], + src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G], + src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B], + src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]); + } +}; + +class _LICE_CombinePixelsColorDodgeSourceAlpha +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + alpha=(alpha*(a+1))/256; + int src_r = 256-r*alpha/256; + int src_g = 256-g*alpha/256; + int src_b = 256-b*alpha/256; + int src_a = 256-a*alpha/256; + + _LICE_MakePixelClamp(dest, + src_r > 1 ? 256*dest[LICE_PIXEL_R] / src_r : 256*dest[LICE_PIXEL_R], + src_g > 1 ? 256*dest[LICE_PIXEL_G] / src_g : 256*dest[LICE_PIXEL_G], + src_b > 1 ? 256*dest[LICE_PIXEL_B] / src_b : 256*dest[LICE_PIXEL_B], + src_a > 1 ? 256*dest[LICE_PIXEL_A] / src_a : 256*dest[LICE_PIXEL_A]); + } +}; + +#else // !LICE_DISABLE_BLEND_DODGE +#define _LICE_CombinePixelsColorDodgeSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp +#define _LICE_CombinePixelsColorDodge _LICE_CombinePixelsCopyClamp +#endif + + +#ifndef LICE_DISABLE_BLEND_MUL + +class _LICE_CombinePixelsMulNoClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) + + int da=(256-alpha)*256; + _LICE_MakePixelNoClamp(dest, + (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, + (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, + (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, + (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); + + } +}; +class _LICE_CombinePixelsMulClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) + + int da=(256-alpha)*256; + _LICE_MakePixelClamp(dest, + (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, + (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, + (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, + (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); + + } +}; +class _LICE_CombinePixelsMulSourceAlphaNoClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + alpha=(alpha*(a+1))/256; + int da=(256-alpha)*256; + _LICE_MakePixelNoClamp(dest, + (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, + (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, + (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, + (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); + + } + } +}; +class _LICE_CombinePixelsMulSourceAlphaClamp +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + if (a) + { + alpha=(alpha*(a+1))/256; + int da=(256-alpha)*256; + _LICE_MakePixelClamp(dest, + (dest[LICE_PIXEL_R]*(da + (r*alpha)))/65536, + (dest[LICE_PIXEL_G]*(da + (g*alpha)))/65536, + (dest[LICE_PIXEL_B]*(da + (b*alpha)))/65536, + (dest[LICE_PIXEL_A]*(da + (a*alpha)))/65536); + + } + } +}; + +#else // !LICE_DISABLE_BLEND_MUL +#define _LICE_CombinePixelsMulSourceAlphaNoClamp _LICE_CombinePixelsCopySourceAlphaNoClamp +#define _LICE_CombinePixelsMulSourceAlphaClamp _LICE_CombinePixelsCopySourceAlphaClamp +#define _LICE_CombinePixelsMulNoClamp _LICE_CombinePixelsCopyNoClamp +#define _LICE_CombinePixelsMulClamp _LICE_CombinePixelsCopyClamp +#endif + +//#define LICE_DISABLE_BLEND_OVERLAY +#ifndef LICE_DISABLE_BLEND_OVERLAY + +class _LICE_CombinePixelsOverlay +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + // we could check alpha=0 here, but the caller should (since alpha is usually used for static alphas) + + int destr = dest[LICE_PIXEL_R], destg = dest[LICE_PIXEL_G], destb = dest[LICE_PIXEL_B], desta = dest[LICE_PIXEL_A]; + +#if 0 + int srcr = r*alpha, srcg = g*alpha, srcb = b*alpha, srca = a*alpha; + int da=(256-alpha)*256; + int mr = (destr*(da+srcr))/65536; + int mg = (destg*(da+srcg))/65536; + int mb = (destb*(da+srcb))/65536; + int ma = (desta*(da+srca))/65536; + int sr = 256-(65536-srcr)*(256-destr)/65536; + int sg = 256-(65536-srcg)*(256-destg)/65536; + int sb = 256-(65536-srcb)*(256-destb)/65536; + int sa = 256-(65536-srca)*(256-desta)/65536; + + destr = (destr*sr+(256-destr)*mr)/256; + destg = (destg*sg+(256-destg)*mg)/256; + destb = (destb*sb+(256-destb)*mb)/256; + desta = (desta*sa+(256-desta)*ma)/256; +#else + // can produce slightly diff (+-1) results from above due to rounding + int da=(256-alpha)*128; + int srcr = r*alpha+da, srcg = g*alpha+da, srcb = b*alpha+da, srca = a*alpha + da; + destr = ( destr*( (destr*(32768-srcr))/256 + srcr ) )/32768; + destg = ( destg*( (destg*(32768-srcg))/256 + srcg ) )/32768; + destb = ( destb*( (destb*(32768-srcb))/256 + srcb ) )/32768; + desta = ( desta*( (desta*(32768-srca))/256 + srca ) )/32768; + +#endif + + _LICE_MakePixelClamp(dest, destr, destg, destb, desta); + } +}; + +class _LICE_CombinePixelsOverlaySourceAlpha +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + _LICE_CombinePixelsOverlay::doPix(dest, r, g, b, a, (alpha*(a+1))/256); + } +}; + +#else // !LICE_DISABLE_BLEND_OVERLAY +#define _LICE_CombinePixelsOverlaySourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp +#define _LICE_CombinePixelsOverlay _LICE_CombinePixelsCopyClamp +#endif + + +//#define LICE_DISABLE_BLEND_HSVADJ +#ifndef LICE_DISABLE_BLEND_HSVADJ + +class _LICE_CombinePixelsHSVAdjust +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + int h,s,v; + __LICE_RGB2HSV(dest[LICE_PIXEL_R],dest[LICE_PIXEL_G],dest[LICE_PIXEL_B],&h,&s,&v); + h+=(((r+r/2) - 192) * alpha)/256; + if (h<0)h+=384; + else if (h>=384) h-=384; + s+=((g-128)*alpha)/128; + if (s&~0xff) + { + if (s<0)s=0; + else s=255; + } + v+=((b-128)*alpha)/128; + if (v&~0xff) + { + if (v<0)v=0; + else v=255; + } + + *(LICE_pixel *)dest = __LICE_HSV2Pix(h,s,v,a); + } +}; + +class _LICE_CombinePixelsHSVAdjustSourceAlpha +{ +public: + static inline void doPix(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha) + { + _LICE_CombinePixelsHSVAdjust::doPix(dest, r, g, b, a, (alpha*(a+1))/256); + } +}; + +#else // !LICE_DISABLE_BLEND_HSVADJ +#define _LICE_CombinePixelsHSVAdjustSourceAlpha _LICE_CombinePixelsCopySourceAlphaClamp +#define _LICE_CombinePixelsHSVAdjust _LICE_CombinePixelsCopyClamp +#endif + +// note: the "clamp" parameter would generally be false, unless you're working with +// input colors that need to be clamped (i.e. if you have a r value of >255 or <0, etc. +// if your input is LICE_pixel only then use false, and it will clamp as needed depending +// on the blend mode.. + +//#define __LICE__ACTION(comb) templateclass::function(parameters) +//__LICE_ACTION_SRCALPHA(mode,alpha,clamp); +//#undef __LICE__ACTION + + +// use this for paths that support LICE_BLIT_USE_ALPHA (source-alpha combining), but +// otherwise have constant alpha +#define __LICE_ACTION_SRCALPHA(mode,ia,clamp) \ + if ((ia)!=0) switch ((mode)&(LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA)) { \ + case LICE_BLIT_MODE_COPY: if ((ia)>0) { \ + if (clamp) { \ + if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } \ + else { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } \ + } else { \ + if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } \ + else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } \ + } \ + } \ + break; \ + case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ + case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ + case LICE_BLIT_MODE_MUL: \ + if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } \ + else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } \ + break; \ + case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ + case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ + case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA: \ + if (clamp) { \ + if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmClamp);} \ + else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaClamp); } \ + } else { \ + if ((ia)==256) { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaIgnoreAlphaParmNoClamp); } \ + else { __LICE__ACTION(_LICE_CombinePixelsCopySourceAlphaNoClamp); } \ + } \ + break; \ + case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA: \ + __LICE__ACTION(_LICE_CombinePixelsAddSourceAlpha); \ + break; \ + case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA: \ + __LICE__ACTION(_LICE_CombinePixelsColorDodgeSourceAlpha); \ + break; \ + case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA: \ + if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaClamp); } \ + else { __LICE__ACTION(_LICE_CombinePixelsMulSourceAlphaNoClamp); } \ + break; \ + case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA: \ + __LICE__ACTION(_LICE_CombinePixelsOverlaySourceAlpha); \ + break; \ + case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA: \ + __LICE__ACTION(_LICE_CombinePixelsHSVAdjustSourceAlpha); \ + break; \ + } + + +// use this for paths that can have per pixel alpha, but calculate it themselves +#define __LICE_ACTION_NOSRCALPHA(mode, ia,clamp) \ + if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \ + case LICE_BLIT_MODE_COPY: if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } break; \ + case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ + case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ + case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \ + case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ + case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ + } + +// For drawing where there is constant alpha and no per-pixel alpha. +#define __LICE_ACTION_CONSTANTALPHA(mode,ia,clamp) \ + if ((ia)!=0) switch ((mode)&LICE_BLIT_MODE_MASK) { \ + case LICE_BLIT_MODE_COPY: \ + if ((ia)==256) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsClobberClamp); } else { __LICE__ACTION(_LICE_CombinePixelsClobberNoClamp); } } \ + else if ((ia)==128) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsHalfMixClamp); } else { __LICE__ACTION(_LICE_CombinePixelsHalfMixNoClamp); } } \ + else if ((ia)>0) { if (clamp) { __LICE__ACTION(_LICE_CombinePixelsCopyClamp); } else { __LICE__ACTION(_LICE_CombinePixelsCopyNoClamp); } } \ + break; \ + case LICE_BLIT_MODE_ADD: __LICE__ACTION(_LICE_CombinePixelsAdd); break; \ + case LICE_BLIT_MODE_DODGE: __LICE__ACTION(_LICE_CombinePixelsColorDodge); break; \ + case LICE_BLIT_MODE_MUL: if (clamp) { __LICE__ACTION(_LICE_CombinePixelsMulClamp); } else { __LICE__ACTION(_LICE_CombinePixelsMulNoClamp); } break; \ + case LICE_BLIT_MODE_OVERLAY: __LICE__ACTION(_LICE_CombinePixelsOverlay); break; \ + case LICE_BLIT_MODE_HSVADJ: __LICE__ACTION(_LICE_CombinePixelsHSVAdjust); break; \ + } + +typedef void (*LICE_COMBINEFUNC)(LICE_pixel_chan *dest, int r, int g, int b, int a, int alpha); + +#endif // _LICE_COMBINE_H_ diff --git a/WDL/lice/lice_extended.h b/WDL/lice/lice_extended.h new file mode 100644 index 00000000..fb7ff937 --- /dev/null +++ b/WDL/lice/lice_extended.h @@ -0,0 +1,164 @@ +#ifndef _LICE_EXTENDED_ +#define _LICE_EXTENDED_ + +#include "lice.h" + +#define DISABLE_LICE_EXTENSIONS + +// stuff to pass to LICE_IBitmap::Extended + +enum // IDs +{ + LICE_EXT_SUPPORTS_ID, // data = ID, returns 1 if that extension ID is supported + LICE_EXT_CLEAR_ACCEL, + LICE_EXT_LINE_ACCEL, + LICE_EXT_FILLRECT_ACCEL, + LICE_EXT_DRAWCBEZIER_ACCEL, + LICE_EXT_DRAWGLYPH_ACCEL, + LICE_EXT_BLIT_ACCEL, + LICE_EXT_SCALEDBLIT_ACCEL, + LICE_EXT_GETFBOTEX_ACCEL, // if the bitmap is implemented as an openGL framebuffer object, get its texture backing store + LICE_EXT_DASHEDLINE_ACCEL, + LICE_EXT_GETPIXEL_ACCEL, + LICE_EXT_PUTPIXEL_ACCEL, + LICE_EXT_SETCLIP, // data == 0 to clear clip + LICE_EXT_WINDOW_BLIT, + LICE_EXT_FORGET, // optimizations can sometimes happen if a bitmap can be told it doesn't need to retain data after it's accessed + LICE_EXT_DRAWTRIANGLE_ACCEL, +}; + +struct LICE_Ext_Line_acceldata +{ + float x1, y1, x2, y2; + LICE_pixel color; + float alpha; + int mode; + bool aa; + + LICE_Ext_Line_acceldata(float _x1, float _y1, float _x2, float _y2, LICE_pixel _color, float _alpha, int _mode, bool _aa) + : x1(_x1), y1(_y1), x2(_x2), y2(_y2), color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} +}; + +struct LICE_Ext_FillRect_acceldata +{ + int x, y, w, h; + LICE_pixel color; + float alpha; + int mode; + + LICE_Ext_FillRect_acceldata(int _x, int _y, int _w, int _h, LICE_pixel _color, float _alpha, int _mode) + : x(_x), y(_y), w(_w), h(_h), color(_color), alpha(_alpha), mode(_mode) {} +}; + +struct LICE_Ext_DrawCBezier_acceldata +{ + float xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend; + LICE_pixel color; + float alpha; + int mode; + bool aa; + + LICE_Ext_DrawCBezier_acceldata(float _xstart, float _ystart, float _xctl1, float _yctl1, float _xctl2, float _yctl2, float _xend, float _yend, + LICE_pixel _color, float _alpha, int _mode, bool _aa) + : xstart(_xstart), ystart(_ystart), xctl1(_xctl1), yctl1(_yctl1), xctl2(_xctl2), yctl2(_yctl2), xend(_xend), yend(_yend), + color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} +}; + +struct LICE_Ext_DrawGlyph_acceldata +{ + int x; + int y; + LICE_pixel color; + const LICE_pixel_chan* alphas; + int glyph_w, glyph_h; + float alpha; + int mode; + + LICE_Ext_DrawGlyph_acceldata(int _x, int _y, LICE_pixel _color, LICE_pixel_chan* _alphas, int _glyph_w, int _glyph_h, float _alpha, int _mode) + : x(_x), y(_y), color(_color), alphas(_alphas), glyph_w(_glyph_w), glyph_h(_glyph_h), alpha(_alpha), mode(_mode) {} +}; + +struct LICE_Ext_Blit_acceldata +{ + LICE_IBitmap* src; + int dstx, dsty, srcx, srcy, srcw, srch; + float alpha; + int mode; + + LICE_Ext_Blit_acceldata(LICE_IBitmap* _src, int _dstx, int _dsty, int _srcx, int _srcy, int _srcw, int _srch, float _alpha, int _mode) + : src(_src), dstx(_dstx), dsty(_dsty), srcx(_srcx), srcy(_srcy), srcw(_srcw), srch(_srch), alpha(_alpha), mode(_mode) {} +}; + +struct LICE_Ext_ScaledBlit_acceldata +{ + LICE_IBitmap* src; + int dstx, dsty, dstw, dsth; + float srcx, srcy, srcw, srch; + float alpha; + int mode; + + LICE_Ext_ScaledBlit_acceldata(LICE_IBitmap* _src, int _dstx, int _dsty, int _dstw, int _dsth, float _srcx, float _srcy, float _srcw, float _srch, float _alpha, int _mode) + : src(_src), dstx(_dstx), dsty(_dsty), dstw(_dstw), dsth(_dsth), srcx(_srcx), srcy(_srcy), srcw(_srcw), srch(_srch), alpha(_alpha), mode(_mode) {} +}; + +struct LICE_Ext_DashedLine_acceldata +{ + float x1, y1, x2, y2; + int pxon, pxoff; + LICE_pixel color; + float alpha; + int mode; + bool aa; + + LICE_Ext_DashedLine_acceldata(float _x1, float _y1, float _x2, float _y2, int _pxon, int _pxoff, LICE_pixel _color, float _alpha, int _mode, bool _aa) + : x1(_x1), y1(_y1), x2(_x2), y2(_y2), pxon(_pxon), pxoff(_pxoff), color(_color), alpha(_alpha), mode(_mode), aa(_aa) {} +}; + +struct LICE_Ext_GetPixel_acceldata +{ + int x, y; + LICE_pixel px; // return + + LICE_Ext_GetPixel_acceldata(int _x, int _y) + : x(_x), y(_y), px(0) {} +}; + +struct LICE_Ext_PutPixel_acceldata +{ + int x, y; + LICE_pixel color; + float alpha; + int mode; + + LICE_Ext_PutPixel_acceldata(int _x, int _y, LICE_pixel _color, float _alpha, int _mode) + : x(_x), y(_y), color(_color), alpha(_alpha), mode(_mode) {} +}; + +struct LICE_Ext_SetClip_data +{ + int x, y, w, h; + + LICE_Ext_SetClip_data(int _x, int _y, int _w, int _h) + : x(_x), y(_y), w(_w), h(_h) {} +}; + +class pl_Mat; + +struct LICE_Ext_DrawTriangle_acceldata +{ + pl_Mat *mat; // will need to include plush.h to access this + double VertexShades[3][3]; // for solid element + float scrx[3], scry[3], scrz[3]; // scrz = 1/Zdist + double mapping_coords[2][3][2]; // [texture or texture2][vertex][uv] +}; + +struct LICE_Ext_WindowBlit_data +{ + HWND hwnd; + int destx, desty, srcx, srcy, w, h; + + LICE_Ext_WindowBlit_data(HWND _hwnd, int _destx, int _desty, int _srcx, int _srcy, int _w, int _h) + : hwnd(_hwnd), destx(_destx), desty(_desty), srcx(_srcx), srcy(_srcy), w(_w), h(_h) {} +}; + +#endif diff --git a/WDL/lice/lice_gif.cpp b/WDL/lice/lice_gif.cpp new file mode 100644 index 00000000..b68ea0cf --- /dev/null +++ b/WDL/lice/lice_gif.cpp @@ -0,0 +1,159 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_gif.cpp (GIF loading for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" + +extern "C" { + +#include "../giflib/gif_lib.h" +int _GifError; +}; + + +LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp, int *nframes) +{ + GifFileType *fp=DGifOpenFileName(filename); + if (!fp) + return 0; + + + GifRecordType RecordType; + GifByteType *Extension; + int ExtCode; + do + { + if (DGifGetRecordType(fp, &RecordType) == GIF_ERROR) + { + DGifCloseFile(fp); + return 0; + } + switch (RecordType) + { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(fp) == GIF_ERROR) + { + DGifCloseFile(fp); + return 0; + } + + // todo: support transparency + // todo: have it buffer all frames and output frame count + if (nframes) *nframes=1; // placeholder + + { + int width=fp->Image.Width,height=fp->Image.Height; + if (bmp) + { + bmp->resize(width,height); + if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) + { + DGifCloseFile(fp); + return 0; + } + } + else bmp=new LICE_MemBitmap(width,height); + + LICE_pixel *bmpptr = bmp->getBits(); + int dbmpptr=bmp->getRowSpan(); + if (bmp->isFlipped()) + { + bmpptr += dbmpptr*(bmp->getHeight()-1); + dbmpptr=-dbmpptr; + } + GifPixelType *linebuf=(GifPixelType*)malloc(width*sizeof(GifPixelType)); + int y; + int cmap[256]; + for (y=0;y<256;y++) + { + if (fp->SColorMap&&ySColorMap->ColorCount&&fp->SColorMap->Colors) + { + GifColorType *ct=fp->SColorMap->Colors+y; + cmap[y]=LICE_RGBA(ct->Red,ct->Green,ct->Blue,255); + } + else cmap[y]=0; + } + + for (y=0; y < height; y ++) + { + if (DGifGetLine(fp,linebuf,width)==GIF_ERROR) break; + + int x; + for (x = 0; x < width; x ++) + { + bmpptr[x]=cmap[linebuf[x]&0xff]; + } + bmpptr += dbmpptr; + } + + + + free(linebuf); + DGifCloseFile(fp); + return bmp; + } + break; + case EXTENSION_RECORD_TYPE: + if (DGifGetExtension(fp, &ExtCode, &Extension) == GIF_ERROR) + { + DGifCloseFile(fp); + return 0; + } + while (Extension != NULL) + { + if (DGifGetExtensionNext(fp, &Extension) == GIF_ERROR) + { + DGifCloseFile(fp); + return 0; + } + } + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + DGifCloseFile(fp); + return 0; + +} + + + +class LICE_GIFLoader +{ +public: + _LICE_ImageLoader_rec rec; + LICE_GIFLoader() + { + rec.loadfunc = loadfunc; + rec.get_extlist = get_extlist; + rec._next = LICE_ImageLoader_list; + LICE_ImageLoader_list = &rec; + } + + static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) + { + if (checkFileName) + { + const char *p=filename; + while (*p)p++; + while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".gif")) return 0; + } + return LICE_LoadGIF(filename,bmpbase,NULL); + } + static const char *get_extlist() + { + return "GIF files (*.GIF)\0*.GIF\0"; + } + +}; + +LICE_GIFLoader LICE_gifldr; \ No newline at end of file diff --git a/WDL/lice/lice_gif_write.cpp b/WDL/lice/lice_gif_write.cpp new file mode 100644 index 00000000..d9eceb36 --- /dev/null +++ b/WDL/lice/lice_gif_write.cpp @@ -0,0 +1,323 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_gif.cpp (GIF loading for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" + +extern "C" { + +#include "../giflib/gif_lib.h" +//int _GifError; +}; + + +struct liceGifWriteRec +{ + GifFileType *f; + ColorMapObject *cmap; + unsigned char from15to8bit[32][32][32];//r,g,b + GifPixelType *linebuf; + int transalpha; + int w,h; + bool dither; + bool has_had_frame; + bool has_global_cmap; + LICE_IBitmap *prevframe; // used when multiframe, transalpha<0 +}; + +static inline GifPixelType QuantPixel(LICE_pixel p, liceGifWriteRec *wr) +{ + return wr->from15to8bit[LICE_GETR(p)>>3][LICE_GETG(p)>>3][LICE_GETB(p)>>3]; +} + + +int LICE_SetGIFColorMapFromOctree(void *ww, void *octree, int numcolors) +{ + liceGifWriteRec *wr = (liceGifWriteRec *)ww; + if (!octree||!ww) return 0; + + ColorMapObject *cmap = wr->cmap; + + int palette_sz=0; + + // store palette + { + LICE_pixel* palette=0; + LICE_pixel tpalette[256]; + if (numcolors <= 256) palette = tpalette; + else palette = (LICE_pixel*)malloc(numcolors*sizeof(LICE_pixel)); + + palette_sz = LICE_ExtractOctreePalette(octree, palette); + + int i; + for (i = 0; i < palette_sz; ++i) + { + cmap->Colors[i].Red = LICE_GETR(palette[i]); + cmap->Colors[i].Green = LICE_GETG(palette[i]); + cmap->Colors[i].Blue = LICE_GETB(palette[i]); + } + for (i = palette_sz; i < numcolors; ++i) + { + cmap->Colors[i].Red = cmap->Colors[i].Green = cmap->Colors[i].Blue = 0; + } + + if (palette != tpalette) free(palette); + } + + // map palette to 16 bit + GifColorType *ct = cmap->Colors; + unsigned char r,g,b; + for(r=0;r<32;r++) + { + unsigned char cr = r<<3; + for (g=0;g<32;g++) + { + unsigned char cg = g<<3; + for (b=0;b<32;b++) + { + unsigned char cb = b<<3; + LICE_pixel col = LICE_RGBA(cr,cg,cb,0); + wr->from15to8bit[r][g][b] = LICE_FindInOctree(octree, col); + } + } + } + + wr->has_global_cmap=true; + + return palette_sz; +} + + +bool LICE_WriteGIFFrame(void *handle, LICE_IBitmap *frame, int xpos, int ypos, bool perImageColorMap, int frame_delay, int nreps) +{ + liceGifWriteRec *wr = (liceGifWriteRec*)handle; + if (!wr) return false; + + bool isFirst=false; + if (!wr->has_had_frame) + { + wr->has_had_frame=true; + isFirst=true; + + if (!perImageColorMap && !wr->has_global_cmap) + { + int ccnt = wr->cmap->ColorCount; + if (wr->transalpha && ccnt>255) ccnt=255; + void* octree = LICE_CreateOctree(ccnt); + if (octree) + { + LICE_BuildOctree(octree, frame); + // sets has_global_cmap + LICE_SetGIFColorMapFromOctree(wr, octree, ccnt); + LICE_DestroyOctree(octree); + } + } + + EGifPutScreenDesc(wr->f,wr->w,wr->h,8,0,wr->has_global_cmap ? wr->cmap : 0); + + } + + int usew=frame->getWidth(), useh=frame->getHeight(); + if (xpos+usew > wr->w) usew = wr->w-xpos; + if (ypos+useh > wr->h) useh = wr->h-ypos; + if (usew<1||useh<1) return false; + + unsigned char gce[4] = { 0, }; + if (wr->transalpha) + { + gce[0] |= 1; + gce[3] = 255; + } + + int a = frame_delay/10; + if(a<1&&frame_delay)a=1; + else if (a>60000) a=60000; + gce[1]=(a)&255; + gce[2]=(a)>>8; + + if (isFirst && frame_delay && nreps!=1) + { + int nr = nreps > 1 && nreps <= 65536 ? nreps-1 : 0; + unsigned char ext[]={0xB, 'N','E','T','S','C','A','P','E','2','.','0',3,1,(nr&0xff),(nr>>8)&0xff}; + EGifPutExtension(wr->f,0xFF, sizeof(ext),ext); + } + + if (gce[0]||gce[1]||gce[2]) + EGifPutExtension(wr->f, 0xF9, sizeof(gce), gce); + + + if (perImageColorMap && !wr->has_global_cmap) + { + int ccnt = wr->cmap->ColorCount; + if (wr->transalpha && ccnt>255) ccnt=255; + void* octree = LICE_CreateOctree(ccnt); + if (octree) + { + LICE_BuildOctree(octree, frame); + // sets has_global_cmap (clear below) + LICE_SetGIFColorMapFromOctree(wr, octree, ccnt); + LICE_DestroyOctree(octree); + wr->has_global_cmap=false; + } + } + + EGifPutImageDesc(wr->f, xpos, ypos, usew,useh, 0, wr->has_global_cmap ? NULL : wr->cmap); + + GifPixelType *linebuf = wr->linebuf; + int y; + int ta=wr->transalpha>0; + + if ((!isFirst || frame_delay) && wr->transalpha<0) + { + bool ignFr=false; + if (!wr->prevframe) + { + ignFr=true; + wr->prevframe = new LICE_MemBitmap(wr->w,wr->h); + LICE_Clear(wr->prevframe,0); + } + + LICE_SubBitmap tmp(wr->prevframe,xpos,ypos,usew,useh); + + for(y=0;yisFlipped()) rdy = frame->getHeight()-1-y; + if (tmp.isFlipped()) rdy2 = tmp.getHeight()-1-y; + LICE_pixel *in = frame->getBits() + rdy*frame->getRowSpan(); + LICE_pixel *in2 = tmp.getBits() + rdy2*tmp.getRowSpan(); + int x; + for(x=0;xf, linebuf, usew); + } + + + LICE_Blit(&tmp,frame,0,0,0,0,usew,useh,1.0f,LICE_BLIT_MODE_COPY); + + } + else for(y=0;yisFlipped()) rdy = frame->getHeight()-1-y; + LICE_pixel *in = frame->getBits() + rdy*frame->getRowSpan(); + int x; + for(x=0;xf, linebuf, usew); + } + + return true; +} + +void *LICE_WriteGIFBeginNoFrame(const char *filename, int w, int h, int transparent_alpha, bool dither) +{ + + EGifSetGifVersion("89a"); + + GifFileType *f = EGifOpenFileName(filename,0); + if (!f) return NULL; + + liceGifWriteRec *wr = (liceGifWriteRec*)calloc(sizeof(liceGifWriteRec),1); + wr->f = f; + wr->dither = dither; + wr->w=w; + wr->h=h; + wr->cmap = (ColorMapObject*)calloc(sizeof(ColorMapObject)+256*sizeof(GifColorType),1); + wr->cmap->Colors = (GifColorType*)(wr->cmap+1); + wr->cmap->ColorCount=256; + wr->cmap->BitsPerPixel=8; + wr->has_had_frame=false; + wr->has_global_cmap=false; + + wr->linebuf = (GifPixelType*)malloc(wr->w*sizeof(GifPixelType)); + wr->transalpha = transparent_alpha; + + return wr; +} +void *LICE_WriteGIFBegin(const char *filename, LICE_IBitmap *firstframe, int transparent_alpha, int frame_delay, bool dither, int nreps) +{ + if (!firstframe) return NULL; + + void *wr=LICE_WriteGIFBeginNoFrame(filename,firstframe->getWidth(),firstframe->getHeight(),transparent_alpha,dither); + if (wr) LICE_WriteGIFFrame(wr,firstframe,0,0,true,frame_delay,nreps); + + return wr; +} + + + +bool LICE_WriteGIFEnd(void *handle) +{ + liceGifWriteRec *wr = (liceGifWriteRec*)handle; + if (!wr) return false; + + int ret = EGifCloseFile(wr->f); + + free(wr->linebuf); + free(wr->cmap); + + delete wr->prevframe; + + free(wr); + + return ret!=GIF_ERROR; +} + + +bool LICE_WriteGIF(const char *filename, LICE_IBitmap *bmp, int transparent_alpha, bool dither) +{ + // todo: alpha? + if (!bmp) return false; + + int has_transparent = 0; + if (transparent_alpha>0) + { + int y=bmp->getHeight(); + LICE_pixel *p = bmp->getBits(); + int w = bmp->getWidth(); + while (y--&&!has_transparent) + { + int x=w; + while(x--) + { + if (LICE_GETA(*p) < transparent_alpha) + { + has_transparent=1; + break; + } + p++; + } + p+=bmp->getRowSpan()-w; + } + } + + + void *wr=LICE_WriteGIFBeginNoFrame(filename,bmp->getWidth(),bmp->getHeight(),has_transparent?transparent_alpha:0,dither); + if (!wr) return false; + + LICE_WriteGIFFrame(wr,bmp,0,0,false,0); + + return LICE_WriteGIFEnd(wr); +} diff --git a/WDL/lice/lice_gl_ctx.cpp b/WDL/lice/lice_gl_ctx.cpp new file mode 100644 index 00000000..1a91f5f6 --- /dev/null +++ b/WDL/lice/lice_gl_ctx.cpp @@ -0,0 +1,264 @@ +#include "lice_gl_ctx.h" + +#define MAX_CACHED_GLYPHS 4096 + +// create one hidden window per process to hold the openGL state, +// its GL render context stays current for the life of the process, +// we serve all framebuffers from the same render context + +class LICE_GL_ctx +{ +public: + + LICE_GL_ctx(); + ~LICE_GL_ctx(); + + bool IsValid(); + HWND GetWindow() { return m_hwnd; } + void Close(); + + GLUnurbsObj* GetNurbsObj(int linetol=8); // linetol = maximum number of straight-line pixels + + int GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h); + void ClearTex(); + + struct GlyphCache + { + unsigned int tex; + unsigned char* glyph; // lives on the heap + int glyph_w, glyph_h; + }; + +private: + + bool Init(); + + bool m_init_tried; + HINSTANCE m_gldll; + HWND m_hwnd; + HGLRC m_glrc; + + GLUnurbsObj* m_nurbs; // keep this here for easy reuse + + GlyphCache m_glyphCache[MAX_CACHED_GLYPHS]; + int m_nCachedGlyphs; +}; + +LICE_GL_ctx::LICE_GL_ctx() +{ + m_init_tried = false; + m_gldll = 0; + m_hwnd = 0; + m_glrc = 0; + m_nurbs = 0; + memset(m_glyphCache, 0, MAX_CACHED_GLYPHS*sizeof(GlyphCache)); + m_nCachedGlyphs = 0; +} + +LICE_GL_ctx::~LICE_GL_ctx() +{ + Close(); +} + +bool LICE_GL_ctx::Init() +{ + m_init_tried = true; + + m_gldll = LoadLibrary("opengl32.dll"); + if (!m_gldll) + { + Close(); + return false; + } + + // create a minimal GL render context to serve FBOs out of + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = "LICE_GL_ctx"; + RegisterClass(&wc); + m_hwnd = CreateWindow("LICE_GL_ctx", "LICE_GL_ctx", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); + HDC dc = GetDC(m_hwnd); + if (!dc) + { + Close(); + return false; + } + + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cAlphaBits = 8; + int pxfmt = ChoosePixelFormat(dc, &pfd); + if (!SetPixelFormat(dc, pxfmt, &pfd)) + { + Close(); + return false; + } + + m_glrc = wglCreateContext(dc); + if (!wglMakeCurrent(dc, m_glrc)) // render context should stay current throughout + { + Close(); + return false; + } + + char *rendstr = (char*) glGetString(GL_RENDERER); + if (!rendstr || strstr(rendstr, "GDI")) + { + Close(); + return false; + } + + // check now for all the extension functions we will ever need + if (glewInit() != GLEW_OK || + !glewIsSupported("GL_EXT_framebuffer_object") || + !glewIsSupported("GL_ARB_texture_rectangle")) + { + Close(); + return false; + } + + // any one-time initialization goes here + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + ReleaseDC(m_hwnd, dc); + + return true; +} + +bool LICE_GL_ctx::IsValid() +{ + if (m_gldll && m_glrc) return true; + if (!m_init_tried) return Init(); + return false; +} + +void LICE_GL_ctx::Close() +{ + ClearTex(); + if (m_nurbs) + { + gluDeleteNurbsRenderer(m_nurbs); + m_nurbs = 0; + } + if (m_glrc) + { + wglMakeCurrent(0, 0); + wglDeleteContext(m_glrc); + m_glrc = 0; + } + if (m_hwnd) + { + DestroyWindow(m_hwnd); + m_hwnd = 0; + } + if (m_gldll) + { + FreeLibrary(m_gldll); + m_gldll = 0; + } +} + +GLUnurbsObj* LICE_GL_ctx::GetNurbsObj(int linetol) +{ + if (!IsValid()) return 0; + if (!m_nurbs) m_nurbs = gluNewNurbsRenderer(); + if (m_nurbs) gluNurbsProperty(m_nurbs, GLU_SAMPLING_TOLERANCE, (float)linetol); + return m_nurbs; +} + +void LICE_GL_ctx::ClearTex() +{ + int i; + for (i = 0; i < m_nCachedGlyphs; ++i) + { + glDeleteTextures(1, &m_glyphCache[i].tex); + free(m_glyphCache[i].glyph); + memset(&m_glyphCache[i], 0, sizeof(GlyphCache)); + } + m_nCachedGlyphs = 0; +} + +static int _glyphcmp(const void* p1, const void* p2) +{ + LICE_GL_ctx::GlyphCache* gc1 = (LICE_GL_ctx::GlyphCache*) p1; + LICE_GL_ctx::GlyphCache* gc2 = (LICE_GL_ctx::GlyphCache*) p2; + + if (gc1->glyph_w < gc2->glyph_w) return -1; + if (gc1->glyph_w > gc2->glyph_w) return 1; + if (gc1->glyph_h < gc2->glyph_h) return -1; + if (gc1->glyph_h > gc2->glyph_h) return 1; + return memcmp(gc1->glyph, gc2->glyph, gc1->glyph_w*gc1->glyph_h); +} + +int LICE_GL_ctx::GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h) +{ + if (!IsValid()) return false; + + GlyphCache gc; + gc.tex = 0; + gc.glyph = (unsigned char *)glyph; + gc.glyph_w = glyph_w; + gc.glyph_h = glyph_h; + + GlyphCache* p = (GlyphCache*) bsearch(&gc, m_glyphCache, m_nCachedGlyphs, sizeof(GlyphCache), _glyphcmp); + if (p) return p->tex; + + glGenTextures(1, &gc.tex); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, gc.tex); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA8, glyph_w, glyph_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, glyph); + + if (m_nCachedGlyphs >= MAX_CACHED_GLYPHS) ClearTex(); // quick & dirty + + gc.glyph = (unsigned char*) malloc(glyph_w*glyph_h); + memcpy(gc.glyph, glyph, glyph_w*glyph_h); + m_glyphCache[m_nCachedGlyphs++] = gc; // copy + qsort(m_glyphCache, m_nCachedGlyphs, sizeof(GlyphCache), _glyphcmp); + + return gc.tex; +} + +//////// + +static LICE_GL_ctx s_glctx; // one static opengl context object per process + + +bool LICE_GL_IsValid() +{ + return s_glctx.IsValid(); +} + +HWND LICE_GL_GetWindow() +{ + if (s_glctx.IsValid()) return s_glctx.GetWindow(); + return 0; +} + +void LICE_GL_CloseCtx() +{ + s_glctx.Close(); +} + +GLUnurbsObj* LICE_GL_GetNurbsObj(int linetol) // linetol = maximum number of straight-line pixels +{ + return s_glctx.GetNurbsObj(linetol); +} + +GLuint LICE_GL_GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h) +{ + return s_glctx.GetTexFromGlyph(glyph, glyph_w, glyph_h); +} + +void LICE_GL_ClearTex() +{ + s_glctx.ClearTex(); +} + diff --git a/WDL/lice/lice_gl_ctx.h b/WDL/lice/lice_gl_ctx.h new file mode 100644 index 00000000..26ec4292 --- /dev/null +++ b/WDL/lice/lice_gl_ctx.h @@ -0,0 +1,27 @@ +#ifndef _GL_CTX_ +#define _GL_CTX_ + +#include "lice.h" + +#define GLEW_STATIC +#include "glew/include/gl/glew.h" +#include "glew/include/gl/wglew.h" +#include "glew/include/gl/wglext.h" + +// GL context functions +// opening and managing GL context is handled behind the scenes + + +bool LICE_GL_IsValid(); // GL context is initialized (will be lazy initialized on first call) and valid + +HWND LICE_GL_GetWindow(); // Get the window that owns the GL context (one per process) + +void LICE_GL_CloseCtx(); // Something failed, turn off GL context forever so we don't keep failing + +GLUnurbsObj* LICE_GL_GetNurbsObj(int linetol=8); // linetol = maximum number of straight-line pixels + +// facility for associating a glyph with a texture +GLuint LICE_GL_GetTexFromGlyph(const unsigned char* glyph, int glyph_w, int glyph_h); +void LICE_GL_ClearTex(); + +#endif diff --git a/WDL/lice/lice_glbitmap.cpp b/WDL/lice/lice_glbitmap.cpp new file mode 100644 index 00000000..31a59a4b --- /dev/null +++ b/WDL/lice/lice_glbitmap.cpp @@ -0,0 +1,708 @@ +#include "lice_glbitmap.h" +#include "lice_gl_ctx.h" + +#include "../plush2/plush.h" + +LICE_GLBitmap::LICE_GLBitmap() +{ + m_bmp = 0; + m_fbo = 0; + m_tex = 0; + m_bufloc = EMPTY; +} + +// This is separate from the constructor for initialization order reasons +void LICE_GLBitmap::Init(LICE_IBitmap* bmp, int w, int h) +{ + m_bmp = bmp; + if (w > 0 && h > 0) CreateFBO(w, h); +} + +bool LICE_GLBitmap::CreateFBO(int w, int h) +{ + if (LICE_GL_IsValid()) + { + if (m_fbo) ReleaseFBO(); + glGenFramebuffersEXT(1, &m_fbo); // create a new empty FBO + if (m_fbo) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // bind this FBO so it is the rendering target + glEnable(GL_TEXTURE_RECTANGLE_ARB); // enable texturing + glGenTextures(1, &m_tex); // create a new texture to be the backing store + if (m_tex) + { + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); // bind this texture so it is the texturing target + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // we won't be scaling it for this purpose + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_tex, 0); // attach the texture as the backing store for the FBO + } + glDisable(GL_TEXTURE_RECTANGLE_ARB); // done texturing + } + + return BindFBO(); // this tests the FBO for validity + } + return false; +} + +LICE_GL_SysBitmap::LICE_GL_SysBitmap(int w, int h) +: m_sysbmp(w, h) +{ + Init(&m_sysbmp, w, h); +} + +LICE_GL_MemBitmap::LICE_GL_MemBitmap(int w, int h) +: m_membmp(w, h) +{ + Init(&m_membmp, w, h); +} + +HDC LICE_GL_SysBitmap::getDC() +{ + // no known way to get a DC directly from an offscreen openGL render context, sadly + FramebufferFromGPU(); + OutputDebugString("GL to screen"); + return m_sysbmp.getDC(); +} + + +LICE_GL_SubBitmap::LICE_GL_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h) +{ + m_parent = parent; + m_x = x; + m_y = y; + m_w = w; + m_h = h; +} + +LICE_pixel* LICE_GL_SubBitmap::getBits() +{ + if (!m_parent) return 0; + return m_parent->getBits()+m_y*m_parent->getRowSpan()+m_x; +} + +bool LICE_GL_SubBitmap::resize(int w, int h) +{ + if (w == m_w && h == m_h) return false; + m_w = w; + m_h = h; + return true; +} + +INT_PTR LICE_GL_SubBitmap::Extended(int id, void* data) +{ + if (!m_parent) return 0; + + if (id == LICE_EXT_SUPPORTS_ID) return m_parent->Extended(id, data); + + LICE_Ext_SetClip_data clipdata(m_x, m_y, m_w, m_h); + if (!m_parent->Extended(LICE_EXT_SETCLIP, &clipdata)) return 0; + INT_PTR ret = m_parent->Extended(id, data); + m_parent->Extended(LICE_EXT_SETCLIP, 0); + + return ret; +} + +bool LICE_GLBitmap::SetClip_ext(LICE_Ext_SetClip_data* p) +{ + if (!FramebufferToGPU()) return false; + + if (p) + { + GLdouble c0[4] = { 1.0, 0.0, 0.0, -p->x }; + GLdouble c1[4] = { -1.0, 0.0, 0.0, p->x+p->w }; + GLdouble c2[4] = { 0.0, 1.0, 0.0, -p->y}; + GLdouble c3[4] = { 0.0, -1.0, 0.0, p->y+p->h }; + glClipPlane(GL_CLIP_PLANE0, c0); + glClipPlane(GL_CLIP_PLANE1, c1); + glClipPlane(GL_CLIP_PLANE2, c2); + glClipPlane(GL_CLIP_PLANE3, c3); + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); + } + else + { + glDisable(GL_CLIP_PLANE0); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE3); + } + + return true; +} + +LICE_GLBitmap::~LICE_GLBitmap() +{ + ReleaseFBO(); +} + +int LICE_GLBitmap::getWidth() +{ + return m_bmp->getWidth(); +} + +int LICE_GLBitmap::getHeight() +{ + return m_bmp->getHeight(); +} + +int LICE_GLBitmap::getRowSpan() +{ + return m_bmp->getRowSpan(); +} + +LICE_pixel* LICE_GLBitmap::getBits() +{ + FramebufferFromGPU(); + return m_bmp->getBits(); +} + +bool LICE_GLBitmap::resize(int w, int h) +{ + int oldw = getWidth(); + int oldh = getHeight(); + if (w == oldw && h == oldh) return false; + + if (oldw == 0 && oldh == 0 && w > 0 && h > 0) + { + m_bmp->resize(w, h); + CreateFBO(w, h); + return true; + } + + if (!m_fbo || !m_tex) return m_bmp->resize(w, h); + + OutputDebugString("GL resizing"); + + // the framebuffer/GPU transfer overhead is per-call, so it's important to be able + // to move the entire bitmap back and forth in one call, which means keeping m_sysbmp width == rowspan + + int oldloc = m_bufloc; + + FramebufferFromGPU(); // copy out the GPU data (this binds the FBO so it is the rendering target) + + glEnable(GL_TEXTURE_RECTANGLE_ARB); // enable texturing + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); // bind this texture so it is the texturing target + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // we won't be scaling it for this purpose + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_tex, 0); // attach the texture as the backing store for the FBO + glDisable(GL_TEXTURE_RECTANGLE_ARB); // done texturing + + if (!BindFBO()) return m_bmp->resize(w, h); // this tests the FBO for validity + + static LICE_MemBitmap tmpbmp; + tmpbmp.resize(w, h); + LICE_Blit(&tmpbmp, m_bmp, 0, 0, 0, 0, oldw, oldh, 1.0f, LICE_BLIT_MODE_COPY); + m_bmp->resize(0, 0); // force it to resize down + LICE_Copy(m_bmp, &tmpbmp); + + if (oldloc == EMPTY) m_bufloc = EMPTY; // else bufloc remains INMEM + + return true; +} + +bool LICE_GLBitmap::BindFBO() +{ + bool valid = false; + if (m_fbo) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // bind this FBO so it is the rendering target + valid = (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); + if (valid) + { + int w = getWidth(); + int h = getHeight(); + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, w, 0.0, h); + } + else + { + ReleaseFBO(); + LICE_GL_CloseCtx(); // if we fail once we're done with GL + } + } + return valid; +} + +void LICE_GLBitmap::ReleaseFBO() +{ + if (m_fbo) + { + glDeleteFramebuffersEXT(1, &m_fbo); + m_fbo = 0; + } + if (m_tex) + { + glDeleteTextures(1, &m_tex); + m_tex = 0; + } +} + +bool LICE_GLBitmap::FramebufferToGPU() +{ + if (BindFBO()) + { + if (m_bufloc == INMEM) + { + OutputDebugString("GL to GPU"); + glDisable(GL_BLEND); + glRasterPos2i(0, 0); + glDrawPixels(getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_bmp->getBits()); + } + m_bufloc = INGPU; + } + return (m_bufloc == INGPU); +} + +void LICE_GLBitmap::FramebufferFromGPU() +{ + if (m_bufloc == INGPU && BindFBO()) + { + OutputDebugString("GL to mem"); + glFinish(); + glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, m_bmp->getBits()); + } + m_bufloc = INMEM; +} + +INT_PTR LICE_GLBitmap::Extended(int id, void* data) +{ + if (id == LICE_EXT_SUPPORTS_ID) + { + int extid = (int) data; + if (extid == LICE_EXT_LINE_ACCEL) return 1; + if (extid == LICE_EXT_FILLRECT_ACCEL) return 1; + if (extid == LICE_EXT_DRAWCBEZIER_ACCEL) return 1; + if (extid == LICE_EXT_DRAWGLYPH_ACCEL) return 1; + if (extid == LICE_EXT_BLIT_ACCEL) return 1; + if (extid == LICE_EXT_SCALEDBLIT_ACCEL) return 1; + if (extid == LICE_EXT_GETFBOTEX_ACCEL) return 1; + if (extid == LICE_EXT_CLEAR_ACCEL) return 1; + if (extid == LICE_EXT_DASHEDLINE_ACCEL) return 1; + if (extid == LICE_EXT_GETPIXEL_ACCEL) return 1; + if (extid == LICE_EXT_PUTPIXEL_ACCEL) return 1; + if (extid == LICE_EXT_SETCLIP) return 1; + if (extid == LICE_EXT_WINDOW_BLIT) return 1; + if (extid == LICE_EXT_FORGET) return 1; + if (extid == LICE_EXT_DRAWTRIANGLE_ACCEL) return 1; + return 0; + } + + if (id == LICE_EXT_CLEAR_ACCEL) return Clear_accel((LICE_pixel*)data); + if (id == LICE_EXT_LINE_ACCEL) return Line_accel((LICE_Ext_Line_acceldata*)data); + if (id == LICE_EXT_FILLRECT_ACCEL) return FillRect_accel((LICE_Ext_FillRect_acceldata*) data); + if (id == LICE_EXT_DRAWCBEZIER_ACCEL) return DrawCBezier_accel((LICE_Ext_DrawCBezier_acceldata*)data); + if (id == LICE_EXT_DRAWGLYPH_ACCEL) return DrawGlyph_accel((LICE_Ext_DrawGlyph_acceldata*)data); + if (id == LICE_EXT_BLIT_ACCEL) return Blit_accel((LICE_Ext_Blit_acceldata*)data); + if (id == LICE_EXT_SCALEDBLIT_ACCEL) return ScaledBlit_accel((LICE_Ext_ScaledBlit_acceldata*)data); + if (id == LICE_EXT_DASHEDLINE_ACCEL) return DashedLine_accel((LICE_Ext_DashedLine_acceldata*)data); + if (id == LICE_EXT_GETPIXEL_ACCEL) return GetPixel_accel((LICE_Ext_GetPixel_acceldata*)data); + if (id == LICE_EXT_PUTPIXEL_ACCEL) return PutPixel_accel((LICE_Ext_PutPixel_acceldata*)data); + if (id == LICE_EXT_SETCLIP) return SetClip_ext((LICE_Ext_SetClip_data*)data); + if (id == LICE_EXT_DRAWTRIANGLE_ACCEL) return DrawTriangle_accel((LICE_Ext_DrawTriangle_acceldata*)data); + if (id == LICE_EXT_WINDOW_BLIT) return WindowBlit((LICE_Ext_WindowBlit_data*)data); + + if (id == LICE_EXT_FORGET) + { + m_bufloc = EMPTY; + return 1; + } + + if (id == LICE_EXT_GETFBOTEX_ACCEL) + { + if (FramebufferToGPU()) return m_tex; + return 0; + } + + return 0; +} + +static void SetGLAliasing(bool aa) +{ + if (aa) + { + glEnable(GL_LINE_SMOOTH); + } + else + { + glDisable(GL_LINE_SMOOTH); + } +} + +static void SetGLColor(LICE_pixel color, float alpha, int licemode) +{ + int a = 255; + if (licemode&LICE_BLIT_USE_ALPHA) a = LICE_GETA(color); + a = (float)a*alpha; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glColor4ub(LICE_GETB(color), LICE_GETG(color), LICE_GETR(color), a); + //glColor4ub(LICE_GETR(color), LICE_GETG(color), LICE_GETB(color), a); +} + +bool LICE_GLBitmap::Clear_accel(LICE_pixel* color) +{ + if (!color) return false; + LICE_pixel col = *color; + + if (!FramebufferToGPU()) return false; + + float r = (float)LICE_GETR(col)/255.0f; + float g = (float)LICE_GETG(col)/255.0f; + float b = (float)LICE_GETB(col)/255.0f; + float a = (float)LICE_GETA(col)/255.0f; + glClearColor(b, g, r, a); + //glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); + + return true; +} + +bool LICE_GLBitmap::Line_accel(LICE_Ext_Line_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + SetGLColor(p->color, p->alpha, p->mode); + SetGLAliasing(p->aa); + + glBegin(GL_LINES); + + glVertex2f(p->x1, p->y1); + glVertex2f(p->x2, p->y2); + + glEnd(); + + return true; +} + +bool LICE_GLBitmap::DashedLine_accel(LICE_Ext_DashedLine_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + SetGLColor(p->color, p->alpha, p->mode); + SetGLAliasing(p->aa); + + glEnable(GL_LINE_STIPPLE); + int n = (p->pxon+p->pxoff)/2; // todo properly when pxon != pxoff + glLineStipple(n, 0xAAAA); + + glBegin(GL_LINES); + + glVertex2f(p->x1, p->y1); + glVertex2f(p->x2, p->y2); + + glEnd(); + + glLineStipple(1, 65535); + glDisable(GL_LINE_STIPPLE); + + return true; +} + + +bool LICE_GLBitmap::FillRect_accel(LICE_Ext_FillRect_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + SetGLColor(p->color, p->alpha, p->mode); + + glBegin(GL_POLYGON); + + glVertex2i(p->x, p->y); + glVertex2i(p->x+p->w, p->y); + glVertex2i(p->x+p->w, p->y+p->h); + glVertex2i(p->x, p->y+p->h); + + glEnd(); + + return true; +} + +bool LICE_GLBitmap::DrawCBezier_accel(LICE_Ext_DrawCBezier_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + GLUnurbsObj* nurbs = LICE_GL_GetNurbsObj(); + if (!nurbs) return false; + +p->color = LICE_RGBA(255,255,255,255); // temp for easy ID of GL rendering + + SetGLColor(p->color, p->alpha, p->mode); + SetGLAliasing(p->aa); + + float ctlpts[] = + { + p->xstart, p->ystart, 0.0f, + p->xctl1, p->yctl1, 0.0f, + p->xctl2, p->yctl2, 0.0f, + p->xend, p->yend, 0.0f + }; + float knots[] = { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; + + gluBeginCurve(nurbs); + gluNurbsCurve(nurbs, 8, knots, 3, ctlpts, 4, GL_MAP1_VERTEX_3); + gluEndCurve(nurbs); + + return true; +} + +bool LICE_GLBitmap::DrawGlyph_accel(LICE_Ext_DrawGlyph_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + int texID = LICE_GL_GetTexFromGlyph(p->alphas, p->glyph_w, p->glyph_h); + if (!texID) return false; + + SetGLColor(p->color, p->alpha, p->mode); + + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID); + glBegin(GL_POLYGON); + + glTexCoord2i(0, 0); + glVertex2i(p->x, p->y); + glTexCoord2i(p->glyph_w, 0); + glVertex2i(p->x+p->glyph_w, p->y); + glTexCoord2i(p->glyph_w, p->glyph_h); + glVertex2i(p->x+p->glyph_w, p->y+p->glyph_h); + glTexCoord2i(0, p->glyph_h); + glVertex2i(p->x, p->y+p->glyph_h); + + glEnd(); + + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + return true; +} + +bool LICE_GLBitmap::Blit_accel(LICE_Ext_Blit_acceldata* p) +{ + if (!p || !p->src) return false; + if (!FramebufferToGPU()) return false; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + GLuint src_tex = p->src->Extended(LICE_EXT_GETFBOTEX_ACCEL, 0); // this binds the src's FBO + if (src_tex) + { + if (!BindFBO()) return false; // re-bind dest FBO + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); + glBegin(GL_POLYGON); + + glTexCoord2i(p->srcx, p->srcy); + glVertex2i(p->dstx, p->dsty); + glTexCoord2i(p->srcx+p->srcw, p->srcy); + glVertex2i(p->dstx+p->srcw, p->dsty); + glTexCoord2i(p->srcx+p->srcw, p->srcy+p->srch); + glVertex2i(p->dstx+p->srcw, p->dsty+p->srch); + glTexCoord2i(p->srcx, p->srcy+p->srch); + glVertex2i(p->dstx, p->dsty+p->srch); + + glEnd(); + + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + return true; + } + + int srcspan = p->src->getRowSpan(); + if (p->srcx == 0 && p->srcy == 0 && p->srcw == srcspan) + { + glRasterPos2i(p->dstx, p->dsty); + glDrawPixels(p->srcw, p->srch, GL_RGBA, GL_UNSIGNED_BYTE, p->src->getBits()); + return true; + } + + LICE_pixel* srcrow = p->src->getBits()+p->srcy*srcspan+p->srcx; + int y; + for (y = 0; y < p->srch; ++y, srcrow += srcspan) + { + glRasterPos2i(p->dstx, p->dsty+y); + glDrawPixels(p->srcw, 1, GL_RGBA, GL_UNSIGNED_BYTE, srcrow); + } + return true; +} + +bool LICE_GLBitmap::ScaledBlit_accel(LICE_Ext_ScaledBlit_acceldata* p) +{ + if (!p || !p->src) return false; + if (!FramebufferToGPU()) return false; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + GLuint src_tex = p->src->Extended(LICE_EXT_GETFBOTEX_ACCEL, 0); // this binds the src's FBO + bool src_has_tex = (src_tex > 0); + if (src_has_tex) + { + if (!BindFBO()) return false; // re-bind dest FBO + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); + } + else + { + // create texture from src bits + glGenTextures(1, &src_tex); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, src_tex); + + int srcspan = p->src->getRowSpan(); + if (p->srcx == 0 && p->srcy == 0 && srcspan == p->srcw) + { + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, p->srcw, p->srch, 0, GL_RGBA, GL_UNSIGNED_BYTE, p->src->getBits()); + } + else + { + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, p->srcw, p->srch, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // size the texture + LICE_pixel* srcrow = p->src->getBits()+(int)p->srcy*srcspan+(int)p->srcx; + int y; + for (y = 0; y < p->srch; ++y, srcrow += srcspan) + { + glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, y, p->srcw, 1, GL_RGBA, GL_UNSIGNED_BYTE, srcrow); + } + } + } + + if (!src_tex) return false; + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // filter + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glBegin(GL_POLYGON); + + glTexCoord2i(p->srcx, p->srcy); + glVertex2i(p->dstx, p->dsty); + glTexCoord2i(p->srcx+p->srcw, p->srcy); + glVertex2i(p->dstx+p->dstw, p->dsty); + glTexCoord2i(p->srcx+p->srcw, p->srcy+p->srch); + glVertex2i(p->dstx+p->dstw, p->dsty+p->dsth); + glTexCoord2i(p->srcx, p->srcy+p->srch); + glVertex2i(p->dstx, p->dsty+p->dsth); + + glEnd(); + + if (!src_has_tex) glDeleteTextures(1, &src_tex); + + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + return true; +} + +bool LICE_GLBitmap::GetPixel_accel(LICE_Ext_GetPixel_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + p->px = 0; + glReadPixels(p->x, p->y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &p->px); + + return true; +} + +bool LICE_GLBitmap::PutPixel_accel(LICE_Ext_PutPixel_acceldata* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + SetGLColor(p->color, p->alpha, p->mode); + + glBegin(GL_POINTS); + glVertex2i(p->x, p->y); + glEnd(); + + return true; +} + +bool LICE_GLBitmap::DrawTriangle_accel(LICE_Ext_DrawTriangle_acceldata *p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // todo: finish implementing zbuffering, (multi)texture mapping, alpha, etc + glColor4f(p->VertexShades[0][0], + p->VertexShades[0][1], + p->VertexShades[0][2], + p->mat->SolidOpacity); + + glBegin(GL_TRIANGLES); + + int x; + for(x=0;x<3;x++) + { + glVertex2i(p->scrx[x], p->scry[x]); + } + + glEnd(); + + return true; +} + +bool LICE_GLBitmap::WindowBlit(LICE_Ext_WindowBlit_data* p) +{ + if (!p) return false; + if (!FramebufferToGPU()) return false; + + HWND hwnd = p->hwnd; + if (hwnd != LICE_GL_GetWindow()) return 0; + + glFinish(); + + //HDC dc = GetDC(hwnd); + //HGLRC rc = wglCreateContext(dc); + //wglMakeCurrent(dc, rc); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + +/* + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, w, 0.0, h); +*/ + glEnable(GL_TEXTURE_RECTANGLE_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_tex); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // the src image is upside down + // todo positioning + glBegin(GL_POLYGON); + glTexCoord2i(0, p->h); + glVertex2i(0, 0); + glTexCoord2i(p->w, p->h); + glVertex2i(p->w, 0); + glTexCoord2i(p->w, 0); + glVertex2i(p->w-1, p->h); + glTexCoord2i(0, 0); + glVertex2i(0, p->h); + glEnd(); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + +//wglMakeCurrent(0, 0); +//wglDeleteContext(rc); + +// ReleaseDC(hwnd, dc); + + return true; +} diff --git a/WDL/lice/lice_glbitmap.h b/WDL/lice/lice_glbitmap.h new file mode 100644 index 00000000..0b3ca61c --- /dev/null +++ b/WDL/lice/lice_glbitmap.h @@ -0,0 +1,110 @@ +#include "lice.h" +#include "lice_extended.h" + +// interface class for LICE_GL_SysBitmap and LICE_GL_MemBitmap +class LICE_GLBitmap : public LICE_IBitmap +{ +public: + + LICE_GLBitmap(); + ~LICE_GLBitmap(); + + LICE_pixel* getBits(); + + int getWidth(); + int getHeight(); + int getRowSpan(); + + bool resize(int w, int h); + + virtual HDC getDC() = 0; // re-virtualize this to prevent instantiating LICE_GLBitmap directly + + INT_PTR Extended(int id, void* data); + +private: + + bool Clear_accel(LICE_pixel* color); + bool Line_accel(LICE_Ext_Line_acceldata* p); + bool FillRect_accel(LICE_Ext_FillRect_acceldata* p); + bool DrawCBezier_accel(LICE_Ext_DrawCBezier_acceldata* p); + bool DrawGlyph_accel(LICE_Ext_DrawGlyph_acceldata* p); + bool Blit_accel(LICE_Ext_Blit_acceldata* p); + bool ScaledBlit_accel(LICE_Ext_ScaledBlit_acceldata* p); + bool DashedLine_accel(LICE_Ext_DashedLine_acceldata* p); + bool GetPixel_accel(LICE_Ext_GetPixel_acceldata* p); + bool PutPixel_accel(LICE_Ext_PutPixel_acceldata* p); + bool SetClip_ext(LICE_Ext_SetClip_data* p); + bool DrawTriangle_accel(LICE_Ext_DrawTriangle_acceldata *p); + // etc + + bool WindowBlit(LICE_Ext_WindowBlit_data* p); + + bool CreateFBO(int w, int h); + bool BindFBO(); // bind this FBO so it is the current rendering target, and test for validity + void ReleaseFBO(); + + unsigned int m_fbo; // framebuffer object: rendering target for drawing on this glbitmap + unsigned int m_tex; // texture object: backing store for this framebuffer object + + enum { EMPTY, INGPU, INMEM }; + int m_bufloc; // where is the current framebuffer? + LICE_IBitmap* m_bmp; + +protected: + + void Init(LICE_IBitmap* bmp, int w, int h); + bool FramebufferToGPU(); + void FramebufferFromGPU(); +}; + +class LICE_GL_SysBitmap : public LICE_GLBitmap +{ +public: + + LICE_GL_SysBitmap(int w=0, int h=0); + + HDC getDC(); + +private: + + LICE_SysBitmap m_sysbmp; +}; + + +class LICE_GL_MemBitmap : public LICE_GLBitmap +{ +public: + + LICE_GL_MemBitmap(int w=0, int h=0); + + HDC getDC() { return 0; } + +private: + + LICE_MemBitmap m_membmp; +}; + + +class LICE_GL_SubBitmap : public LICE_IBitmap +{ +public: + + LICE_GL_SubBitmap(LICE_IBitmap *parent, int x, int y, int w, int h); + + LICE_pixel* getBits(); + + int getWidth() { return m_w; } + int getHeight() { return m_h; } + int getRowSpan() { return (m_parent ? m_parent->getRowSpan() : 0); } + + bool resize(int w, int h); + + HDC getDC() { return (m_parent ? m_parent->getDC() : 0); } + + INT_PTR Extended(int id, void* data); + +private: + + LICE_IBitmap* m_parent; + int m_x, m_y, m_w, m_h; +}; diff --git a/WDL/lice/lice_ico.cpp b/WDL/lice/lice_ico.cpp new file mode 100644 index 00000000..5f3f7ea7 --- /dev/null +++ b/WDL/lice/lice_ico.cpp @@ -0,0 +1,186 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_ico.cpp (ICO icon file loading for LICE) + See lice.h for license and other information + + This file contains some code from Microsoft's MSDN ICO loading sample + see: http://msdn2.microsoft.com/en-us/library/ms997538.aspx +*/ + +#include "lice.h" +#ifndef _WIN32 +#include "../swell/swell.h" +#endif + +static LICE_IBitmap *icoToBitmap(HICON icon, LICE_IBitmap *bmpOut) +{ + int icon_w = 16, icon_h=16; + +#ifdef _WIN32 + ICONINFO ii={0,}; + if (GetIconInfo(icon,&ii)) + { + bool blah=false; + if (ii.hbmColor) + { + BITMAP bm={0,}; + if (GetObject(ii.hbmColor,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) + { + icon_w=bm.bmWidth; + icon_h=bm.bmHeight; + blah=true; + } + DeleteObject(ii.hbmColor); + } + if (ii.hbmMask) + { + BITMAP bm={0,}; + if (!blah && GetObject(ii.hbmMask,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) + { + icon_w=bm.bmWidth; + icon_h=bm.bmHeight; + } + DeleteObject(ii.hbmMask); + } + } +#else + BITMAP bm={0,}; + if (GetObject(icon,sizeof(bm),&bm) && bm.bmWidth && bm.bmHeight) // SWELL's GetObject() works on icons + { + icon_w=bm.bmWidth; + icon_h=bm.bmHeight; + } + +#endif + + LICE_SysBitmap tempbm(icon_w*2,icon_h); + LICE_FillRect(&tempbm,0,0,icon_w,icon_h,LICE_RGBA(0,0,0,255),1.0f,LICE_BLIT_MODE_COPY); +#ifdef _WIN32 + DrawIconEx(tempbm.getDC(),0,0,icon,icon_w,icon_h,0,NULL,DI_NORMAL); +#else + { + RECT r={0,0,icon_w,icon_h}; + DrawImageInRect(tempbm.getDC(),icon,&r); + } +#endif + + LICE_FillRect(&tempbm,icon_w,0,icon_w,icon_h,LICE_RGBA(255,255,255,255),1.0f,LICE_BLIT_MODE_COPY); +#ifdef _WIN32 + DrawIconEx(tempbm.getDC(),icon_w,0,icon,icon_w,icon_h,0,NULL,DI_NORMAL); +#else + { + RECT r={icon_w,0,icon_w+icon_w,icon_h}; + DrawImageInRect(tempbm.getDC(),icon,&r); + } +#endif + + if (!bmpOut) bmpOut = new LICE_MemBitmap(icon_w,icon_h); + else bmpOut->resize(icon_w,icon_h); + + int y; // since we have the image drawn on white and on black, we can calculate the alpha channel... + for(y=0;y=255) alpha=255; + else if (alpha>0) + { + r1 = (r1*255)/alpha; // LICE stores its alpha channel non-premultiplied, so we need to scale these up. + g1 = (g1*255)/alpha; + b1 = (b1*255)/alpha; + if (r1>255)r1=255; + if (g1>255)g1=255; + if (b1>255)b1=255; + } + else alpha=0; + LICE_PutPixel(bmpOut,x,y,LICE_RGBA(r1,g1,b1,alpha),1.0f,LICE_BLIT_MODE_COPY); + } + } + + return bmpOut; +} + +LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +{ + if (reqiconsz<1) reqiconsz=16; + HICON icon = NULL; +#ifdef _WIN32 + + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + icon = (HICON)LoadImageW(NULL,wf,IMAGE_ICON,reqiconsz,reqiconsz,LR_LOADFROMFILE); + } + + if (!icon) icon = (HICON)LoadImage(NULL,filename,IMAGE_ICON,reqiconsz,reqiconsz,LR_LOADFROMFILE); + +#else + icon = (HICON)LoadNamedImage(filename,false); +#endif + if (!icon) return 0; + + LICE_IBitmap *ret=icoToBitmap(icon,bmp); + DestroyIcon(icon); + return ret; +} + +LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +{ +#ifdef _WIN32 + if (reqiconsz<1) reqiconsz=16; + HICON icon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_ICON,reqiconsz,reqiconsz,0); + if (!icon) return 0; + + LICE_IBitmap *ret=icoToBitmap(icon,bmp); + DestroyIcon(icon); + return ret; +#else + return 0; +#endif +} + + + + +class LICE_ICOLoader +{ +public: + _LICE_ImageLoader_rec rec; + LICE_ICOLoader() + { + rec.loadfunc = loadfunc; + rec.get_extlist = get_extlist; + rec._next = LICE_ImageLoader_list; + LICE_ImageLoader_list = &rec; + } + + static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) + { + if (checkFileName) + { + const char *p=filename; + while (*p)p++; + while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".ico")) return 0; + } + return LICE_LoadIcon(filename,16,bmpbase); + } + static const char *get_extlist() + { + return "ICO files (*.ICO)\0*.ICO\0"; + } + +}; + +LICE_ICOLoader LICE_icoldr; \ No newline at end of file diff --git a/WDL/lice/lice_image.cpp b/WDL/lice/lice_image.cpp new file mode 100644 index 00000000..49e9a699 --- /dev/null +++ b/WDL/lice/lice_image.cpp @@ -0,0 +1,148 @@ +#include "lice.h" + + + +LICE_IBitmap* LICE_LoadImage(const char* filename, LICE_IBitmap* bmp, bool tryIgnoreExtension) +{ + _LICE_ImageLoader_rec *hdr = LICE_ImageLoader_list; + while (hdr) + { + LICE_IBitmap *ret = hdr->loadfunc(filename,true,bmp); + if (ret) return ret; + hdr=hdr->_next; + } + if (tryIgnoreExtension) + { + hdr = LICE_ImageLoader_list; + while (hdr) + { + LICE_IBitmap *ret = hdr->loadfunc(filename,false,bmp); + if (ret) return ret; + hdr=hdr->_next; + } + } + + return 0; +} + + +static bool grow_buf(char **buf, int *bufsz, int *wrpos, const char *rd, int len) +{ + if (*wrpos + len > *bufsz) + { + char *nbuf=(char*)realloc(*buf,*bufsz = *wrpos+len+4096); + if (!nbuf) return true; // ugh + *buf = nbuf; + } + memcpy(*buf+*wrpos,rd,len); + *wrpos+=len; + return false; +} + +char *LICE_GetImageExtensionList(bool wantAllSup, bool wantAllFiles) +{ + _LICE_ImageLoader_rec *hdr = LICE_ImageLoader_list; + int bufsz=4096; + int wrpos=0; + char *buf=(char *)malloc(bufsz); + buf[0]=buf[1]=buf[2]=0; + + if (wantAllSup) + { + static const char af[]="All supported images"; + if (grow_buf(&buf,&bufsz,&wrpos,af,sizeof(af))) { free(buf); return NULL; } // fail + + int cnt=0; + while (hdr) + { + const char *rd = hdr->get_extlist(); + if (rd && *rd) + { + bool st=false; + const char *p=rd; + while (*p) + { + if (st) + { + if (cnt++) + if (grow_buf(&buf,&bufsz,&wrpos,";",1)) { free(buf); return NULL; } // fail + if (grow_buf(&buf,&bufsz,&wrpos,p,strlen(p)+1)) { free(buf); return NULL; } // fail + wrpos--; + } + while (*p) p++; + p++; + st=!st; + } + } + hdr=hdr->_next; + } + + if (!cnt) + { + wrpos=0; // reset if nothing meaningful added + buf[0]=buf[1]=buf[2]=0; + } + else wrpos++; + + hdr = LICE_ImageLoader_list; + } + + while (hdr) + { + const char *rd = hdr->get_extlist(); + if (rd && *rd) + { + const char *p=rd; + while (p[0] || p[1]) p++; // doublenull terminated list + + int len = p + 2 - rd; + if (len>2) + { + if (grow_buf(&buf,&bufsz,&wrpos,rd,len)) return buf; // fail + wrpos--; // remove doublenull on next round + } + } + hdr=hdr->_next; + } + if (wantAllFiles) + { + static const char af[]="All files (*.*)\0*.*\0"; + if (grow_buf(&buf,&bufsz,&wrpos,af,sizeof(af))) return buf; // fail + wrpos--; + } + + return buf; +} + +bool LICE_ImageIsSupported(const char *filename) +{ + const char *extension = filename; + while (*extension)extension++; + while (extension>=filename && *extension != '/' && *extension != '.' && *extension != '\\') extension--; + if (extensionget_extlist(); + if (el) + { + while (*el) el++; // skip desc + ++el; + + // scan rest of buffer + while (*el) + { + if (!strnicmp(el,extension,extlen)) + { + if (el[extlen] == 0|| el[extlen] == ';') return true; + } + el++; + } + } + hdr=hdr->_next; + } + return false; +} diff --git a/WDL/lice/lice_jpg.cpp b/WDL/lice/lice_jpg.cpp new file mode 100644 index 00000000..212a55c1 --- /dev/null +++ b/WDL/lice/lice_jpg.cpp @@ -0,0 +1,310 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_jpg.cpp (JPG loading for LICE) + See lice.h for license and other information +*/ + +#include +#include "lice.h" +#include + +extern "C" { +#include "../jpeglib/jpeglib.h" +}; + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +}; +static void LICEJPEG_Error(j_common_ptr cinfo) +{ + longjmp(((my_error_mgr*)cinfo->err)->setjmp_buffer,1); +} +static void LICEJPEG_EmitMsg(j_common_ptr cinfo, int msg_level) { } +static void LICEJPEG_FmtMsg(j_common_ptr cinfo, char *) { } +static void LICEJPEG_OutMsg(j_common_ptr cinfo) { } +static void LICEJPEG_reset_error_mgr(j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + cinfo->err->msg_code = 0; +} + +static void LICEJPEG_init_source(j_decompress_ptr cinfo) {} +static unsigned char EOI_data[2] = { 0xFF, 0xD9 }; +static boolean LICEJPEG_fill_input_buffer(j_decompress_ptr cinfo) +{ + cinfo->src->next_input_byte = EOI_data; + cinfo->src->bytes_in_buffer = 2; + return TRUE; +} +static void LICEJPEG_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + if (num_bytes > 0) + { + if (num_bytes > (long) cinfo->src->bytes_in_buffer) + { + num_bytes = (long) cinfo->src->bytes_in_buffer; + } + cinfo->src->next_input_byte += (size_t) num_bytes; + cinfo->src->bytes_in_buffer -= (size_t) num_bytes; + } +} +static void LICEJPEG_term_source(j_decompress_ptr cinfo) {} + + +LICE_IBitmap *LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) +{ +#ifdef _WIN32 + HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "JPG"); + if(!hResource) return NULL; + + DWORD imageSize = SizeofResource(hInst, hResource); + if(imageSize < 8) return NULL; + + HGLOBAL res = LoadResource(hInst, hResource); + const void* pResourceData = LockResource(res); + if(!pResourceData) return NULL; + + unsigned char *data = (unsigned char *)pResourceData; + + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr={0,}; + JSAMPARRAY buffer; + int row_stride; + + jerr.pub.error_exit = LICEJPEG_Error; + jerr.pub.emit_message = LICEJPEG_EmitMsg; + jerr.pub.output_message = LICEJPEG_OutMsg; + jerr.pub.format_message = LICEJPEG_FmtMsg; + jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; + + cinfo.err = &jerr.pub; + + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_decompress(&cinfo); + DeleteObject(res); + return 0; + } + jpeg_create_decompress(&cinfo); + + cinfo.src = (struct jpeg_source_mgr *) (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, sizeof (struct jpeg_source_mgr)); + + cinfo.src->init_source = LICEJPEG_init_source; + cinfo.src->fill_input_buffer = LICEJPEG_fill_input_buffer; + cinfo.src->skip_input_data = LICEJPEG_skip_input_data; + cinfo.src->resync_to_restart = jpeg_resync_to_restart; + cinfo.src->term_source = LICEJPEG_term_source; + + cinfo.src->next_input_byte = data; + cinfo.src->bytes_in_buffer = imageSize; + + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + row_stride = cinfo.output_width * cinfo.output_components; + + buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + if (bmp) + { + bmp->resize(cinfo.output_width,cinfo.output_height); + if (bmp->getWidth() != (int)cinfo.output_width || bmp->getHeight() != (int)cinfo.output_height) + { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + DeleteObject(res); + return 0; + } + } + else bmp=new LICE_MemBitmap(cinfo.output_width,cinfo.output_height); + + LICE_pixel *bmpptr = bmp->getBits(); + int dbmpptr=bmp->getRowSpan(); + if (bmp->isFlipped()) + { + bmpptr += dbmpptr*(bmp->getHeight()-1); + dbmpptr=-dbmpptr; + } + + 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. + */ + jpeg_read_scanlines(&cinfo, buffer, 1); + /* Assume put_scanline_someplace wants a pointer and sample count. */ +// put_scanline_someplace(buffer[0], row_stride); + if (cinfo.output_components==3) + { + int x; + for (x = 0; x < (int)cinfo.output_width; x++) + { + bmpptr[x]=LICE_RGBA(buffer[0][x*3],buffer[0][x*3+1],buffer[0][x*3+2],255); + } + } + else if (cinfo.output_components==1) + { + int x; + for (x = 0; x < (int)cinfo.output_width; x++) + { + int v=buffer[0][x]; + bmpptr[x]=LICE_RGBA(v,v,v,255); + } + } + else + { + memset(bmpptr,0,4*cinfo.output_width); + } + bmpptr+=dbmpptr; + } + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); // we created cinfo.src with some special alloc so I think it gets collected + DeleteObject(res); + + return bmp; + +#else + return 0; +#endif +} + + +LICE_IBitmap *LICE_LoadJPG(const char *filename, LICE_IBitmap *bmp) +{ + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr={{0},}; + JSAMPARRAY buffer; + int row_stride; + + FILE *fp=NULL; +#ifdef _WIN32 + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + fp = _wfopen(wf,L"rb"); + } +#endif + if (!fp) fp = fopen(filename,"rb"); + + if (!fp) return 0; + + jerr.pub.error_exit = LICEJPEG_Error; + jerr.pub.emit_message = LICEJPEG_EmitMsg; + jerr.pub.output_message = LICEJPEG_OutMsg; + jerr.pub.format_message = LICEJPEG_FmtMsg; + jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; + + cinfo.err = &jerr.pub; + + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_decompress(&cinfo); + fclose(fp); + return 0; + } + jpeg_create_decompress(&cinfo); + + jpeg_stdio_src(&cinfo, fp); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + row_stride = cinfo.output_width * cinfo.output_components; + + buffer = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + if (bmp) + { + bmp->resize(cinfo.output_width,cinfo.output_height); + if (bmp->getWidth() != (int)cinfo.output_width || bmp->getHeight() != (int)cinfo.output_height) + { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fp); + return 0; + } + } + else bmp=new LICE_MemBitmap(cinfo.output_width,cinfo.output_height); + + LICE_pixel *bmpptr = bmp->getBits(); + int dbmpptr=bmp->getRowSpan(); + if (bmp->isFlipped()) + { + bmpptr += dbmpptr*(bmp->getHeight()-1); + dbmpptr=-dbmpptr; + } + + 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. + */ + jpeg_read_scanlines(&cinfo, buffer, 1); + /* Assume put_scanline_someplace wants a pointer and sample count. */ +// put_scanline_someplace(buffer[0], row_stride); + if (cinfo.output_components==3) + { + int x; + for (x = 0; x < (int)cinfo.output_width; x++) + { + bmpptr[x]=LICE_RGBA(buffer[0][x*3],buffer[0][x*3+1],buffer[0][x*3+2],255); + } + } + else if (cinfo.output_components==1) + { + int x; + for (x = 0; x < (int)cinfo.output_width; x++) + { + int v=buffer[0][x]; + bmpptr[x]=LICE_RGBA(v,v,v,255); + } + } + else + memset(bmpptr,0,4*cinfo.output_width); + bmpptr+=dbmpptr; + } + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fp); + + return bmp; +} + + +class LICE_JPGLoader +{ +public: + _LICE_ImageLoader_rec rec; + LICE_JPGLoader() + { + rec.loadfunc = loadfunc; + rec.get_extlist = get_extlist; + rec._next = LICE_ImageLoader_list; + LICE_ImageLoader_list = &rec; + } + + static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) + { + if (checkFileName) + { + const char *p=filename; + while (*p)p++; + while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".jpg")&&stricmp(p,".jpeg")&&stricmp(p,".jfif")) return 0; + } + return LICE_LoadJPG(filename,bmpbase); + } + static const char *get_extlist() + { + return "JPEG files (*.JPG;*.JPEG;*.JFIF)\0*.JPG;*.JPEG;*.JFIF\0"; + } + +}; + +LICE_JPGLoader LICE_jgpldr; diff --git a/WDL/lice/lice_jpg_write.cpp b/WDL/lice/lice_jpg_write.cpp new file mode 100644 index 00000000..3f425854 --- /dev/null +++ b/WDL/lice/lice_jpg_write.cpp @@ -0,0 +1,117 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_jpg_write.cpp (JPG writing for LICE) + See lice.h for license and other information +*/ + +#include +#include "lice.h" +#include + +extern "C" { +#include "../jpeglib/jpeglib.h" +}; + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +}; +static void LICEJPEG_Error(j_common_ptr cinfo) +{ + longjmp(((my_error_mgr*)cinfo->err)->setjmp_buffer,1); +} +static void LICEJPEG_EmitMsg(j_common_ptr cinfo, int msg_level) { } +static void LICEJPEG_FmtMsg(j_common_ptr cinfo, char *) { } +static void LICEJPEG_OutMsg(j_common_ptr cinfo) { } +static void LICEJPEG_reset_error_mgr(j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + cinfo->err->msg_code = 0; +} + +bool LICE_WriteJPG(const char *filename, LICE_IBitmap *bmp, int quality, bool force_baseline) +{ + if (!bmp || !filename) return false; + + FILE *fp=NULL; +#ifdef _WIN32 + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + fp = _wfopen(wf,L"wb"); + } +#endif + if (!fp) fp = fopen(filename,"wb"); + + if (!fp) return false; + + struct jpeg_compress_struct cinfo; + struct my_error_mgr jerr={0,}; + jerr.pub.error_exit = LICEJPEG_Error; + jerr.pub.emit_message = LICEJPEG_EmitMsg; + jerr.pub.output_message = LICEJPEG_OutMsg; + jerr.pub.format_message = LICEJPEG_FmtMsg; + jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr; + + cinfo.err = &jerr.pub; + unsigned char *buf = NULL; + + if (setjmp(jerr.setjmp_buffer)) + { + jpeg_destroy_compress(&cinfo); + if (fp) fclose(fp); + free(buf); + return false; + } + jpeg_create_compress(&cinfo); + + jpeg_stdio_dest(&cinfo, fp); + + cinfo.image_width = bmp->getWidth(); /* image width and height, in pixels */ + cinfo.image_height = bmp->getHeight(); + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, !!force_baseline); + jpeg_start_compress(&cinfo, TRUE); + + buf = (unsigned char *)malloc(cinfo.image_width * 3); + LICE_pixel_chan *rd = (LICE_pixel_chan *)bmp->getBits(); + int rowspan = bmp->getRowSpan()*4; + if (bmp->isFlipped()) + { + rd += rowspan*(bmp->getHeight()-1); + rowspan=-rowspan; + } + while (cinfo.next_scanline < cinfo.image_height) + { + unsigned char *outp=buf; + LICE_pixel_chan *rdp = rd; + int x=cinfo.image_width; + while(x--) + { + outp[0] = rdp[LICE_PIXEL_R]; + outp[1] = rdp[LICE_PIXEL_G]; + outp[2] = rdp[LICE_PIXEL_B]; + outp+=3; + rdp+=4; + } + jpeg_write_scanlines(&cinfo, &buf, 1); + + rd+=rowspan; + } + free(buf); + buf=0; + + jpeg_finish_compress(&cinfo); + + if (fp) fclose(fp); + fp=0; + + jpeg_destroy_compress(&cinfo); + + return true; +} \ No newline at end of file diff --git a/WDL/lice/lice_lcf.cpp b/WDL/lice/lice_lcf.cpp new file mode 100644 index 00000000..4e0bc95e --- /dev/null +++ b/WDL/lice/lice_lcf.cpp @@ -0,0 +1,663 @@ +#include +#include + +#include "lice_lcf.h" + +#include "../filewrite.h" +#include "../fileread.h" + + +#define LCF_VERSION 0x11CEb001 + +LICECaptureCompressor::LICECaptureCompressor(const char *outfn, int w, int h, int interval, int bsize_w, int bsize_h) +{ + m_inframes = m_outframes=0; + m_file = new WDL_FileWrite(outfn,1,512*1024); + if (!m_file->IsOpen()) { delete m_file; m_file=0; } + + memset(&m_compstream,0,sizeof(m_compstream)); + if (m_file) + { + if (deflateInit(&m_compstream,9)!=Z_OK) + { + delete m_file; + m_file=0; + } + } + + m_inbytes=0; + m_outsize=0; + m_w=w; + m_h=h; + m_interval=interval; + m_bsize_w=bsize_w; + m_bsize_h=bsize_h; + m_state=0; + m_which=0; + m_outchunkpos=0; + m_numcols = (m_w+bsize_w-1) / (bsize_w>0?bsize_w:1); + if (m_numcols<1) m_numcols=1; + m_numrows = (m_h+bsize_h-1)/ (bsize_h>0?bsize_h:1); + + m_current_block_srcsize=0; +} + +void LICECaptureCompressor::OnFrame(LICE_IBitmap *fr, int delta_t_ms) +{ + if (fr) + { + if (fr->getWidth()!=m_w || fr->getHeight()!=m_h) return; + + frameRec *rec = m_framelists[m_which].Get(m_state); + if (!rec) + { + rec = new frameRec(m_w*m_h); + m_framelists[m_which].Add(rec); + } + rec->delta_t_ms=delta_t_ms; + BitmapToFrameRec(fr,rec); + m_state++; + m_inframes++; + } + + + bool isLastBlock = m_state >= m_interval || !fr; + + if (m_framelists[!m_which].GetSize()) + { + int compressTo; + if (isLastBlock) compressTo = m_numcols*m_numrows; + else compressTo = (m_state * m_numcols*m_numrows) / m_interval; + + frameRec **list = m_framelists[!m_which].GetList(); + int list_size = m_framelists[!m_which].GetSize(); + + // compress some data + int chunkpos = m_outchunkpos; + while (chunkpos < compressTo) + { + int xpos = (chunkpos%m_numcols) * m_bsize_w; + int ypos = (chunkpos/m_numcols) * m_bsize_h; + + int wid = m_w-xpos; + int hei = m_h-ypos; + if (wid > m_bsize_w) wid=m_bsize_w; + if (hei > m_bsize_h) hei=m_bsize_h; + + int i; + int rdoffs = xpos + ypos*m_w; + int rdspan = m_w; + + int repeat_cnt=0; + + for(i=0;idata + rdoffs; + if (i&&repeat_cnt<256) + { + unsigned short *rd1=rd; + unsigned short *rd2=list[i-1]->data+rdoffs; + int a=hei; + while(a--) + { + if (memcmp(rd1,rd2,wid*sizeof(short))) break; + rd1+=rdspan; + rd2+=rdspan; + } + if (a<0) + { + repeat_cnt++; + continue; + } + } + + if (i || repeat_cnt) + { + unsigned char c = (unsigned char)repeat_cnt; + DeflateBlock(&c,1,false); + repeat_cnt=0; + } + int a=hei; + while (a--) + { + DeflateBlock(rd,wid*sizeof(short),false); + rd+=rdspan; + } + } + if (repeat_cnt) + { + unsigned char c = (unsigned char)repeat_cnt; + DeflateBlock(&c,1,false); + } + + chunkpos++; + } + m_outchunkpos=chunkpos; + } + + if (isLastBlock) + { + if (m_framelists[!m_which].GetSize()) + { + m_outframes += m_framelists[!m_which].GetSize(); + + DeflateBlock(NULL,0,true); + + deflateReset(&m_compstream); + + m_hdrqueue.Clear(); + AddHdrInt(LCF_VERSION); + AddHdrInt(16); + AddHdrInt(m_w); + AddHdrInt(m_h); + AddHdrInt(m_bsize_w); + AddHdrInt(m_bsize_h); + int nf = m_framelists[!m_which].GetSize(); + AddHdrInt(nf); + int sz = m_current_block.Available(); + AddHdrInt(sz); + + int uncomp_sz = m_current_block_srcsize; + AddHdrInt(uncomp_sz); + + { + int x; + for(x=0;xdelta_t_ms); + } + } + + + m_file->Write(m_hdrqueue.Get(),m_hdrqueue.Available()); + m_outsize += m_hdrqueue.Available(); + m_file->Write(m_current_block.Get(),sz); + m_outsize += sz; + + m_current_block.Clear(); + m_current_block_srcsize=0; + } + + + int old_state=m_state; + m_state=0; + m_outchunkpos=0; + m_which=!m_which; + + + if (old_state>0 && !fr) + { + while (m_framelists[!m_which].GetSize() > old_state) + m_framelists[!m_which].Delete(m_framelists[!m_which].GetSize()-1,true); + + OnFrame(NULL,0); + } + + if (!fr) + { + m_framelists[0].Empty(true); + m_framelists[1].Empty(true); + } + } +} + +void LICECaptureCompressor::BitmapToFrameRec(LICE_IBitmap *fr, frameRec *dest) +{ + unsigned short *outptr = dest->data; + const LICE_pixel *p = fr->getBits(); + int span = fr->getRowSpan(); + if (fr->isFlipped()) + { + p+=(fr->getHeight()-1)*span; + span=-span; + } + int h = fr->getHeight(),w=fr->getWidth(); + while (h--) + { + int x=w; + const LICE_pixel *sp = p; + while (x--) + { + LICE_pixel pix = *sp++; + *outptr++ = (((int)LICE_GETR(pix)&0xF8)>>3) | (((int)LICE_GETG(pix)&0xFC)<<3) | (((int)LICE_GETB(pix)&0xF8)<<8); + } + p += span; + } +} + +void LICECaptureCompressor::DeflateBlock(void *data, int data_size, bool flush) +{ + m_current_block_srcsize += data_size; + m_inbytes += data_size; + int bytesout=0; + + m_compstream.next_in = (unsigned char *)data; + m_compstream.avail_in = data_size; + + for (;;) + { + int add_sz = data_size+32768; + m_compstream.next_out = (unsigned char *)m_current_block.Add(NULL,add_sz); + m_compstream.avail_out = add_sz; + + int e = deflate(&m_compstream,flush?Z_FULL_FLUSH:Z_NO_FLUSH); + + m_current_block.Add(NULL,-(int)m_compstream.avail_out); + + bytesout+=add_sz-m_compstream.avail_out; + + + if (e != Z_OK) + { + break; + } + + if (!m_compstream.avail_in && (!flush || add_sz==(int)m_compstream.avail_out)) break; + } + m_outsize += bytesout; + +} + + + +LICECaptureCompressor::~LICECaptureCompressor() +{ + // process any pending frames + if (m_file) + { + OnFrame(NULL,0); + deflateEnd(&m_compstream); + } + + delete m_file; + m_framelists[0].Empty(true); + m_framelists[1].Empty(true); +} + + + + + + + + + + + + + + +////////////////////////////////////////// +///////DECOMPRESS +////////////////////////////////////////// + + +LICECaptureDecompressor::LICECaptureDecompressor(const char *fn, bool want_seekable) : m_workbm(0,0,1) +{ + m_file_length_ms=0; + m_rd_which=0; + m_frameidx=0; + memset(&m_compstream,0,sizeof(m_compstream)); + memset(&m_curhdr,0,sizeof(m_curhdr)); + m_file = new WDL_FileRead(fn,2,1024*1024); + if (m_file->IsOpen()) + { + if (inflateInit(&m_compstream)!=Z_OK) + { + delete m_file; + m_file=0; + } + if (m_file) + { + m_file_frame_info.Clear(); + m_file_length_ms=0; + if (want_seekable) + { + unsigned int lastpos = 0; + while (ReadHdr(0)) + { + m_file_frame_info.Add(&lastpos,1); + unsigned int mst = m_file_length_ms; + if (m_frame_deltas[0].GetSize()) mst += m_frame_deltas[0].Get()[0]; // TOC is by time of first frames, ignore first delay when seeking + m_file_frame_info.Add(&mst,1); + + int x; + for(x=0;xSetPosition(lastpos = (unsigned int)(m_file->GetPosition() + m_curhdr[0].cdata_left)); + } + } + + Seek(0); + } + } + + if (m_curhdr[m_rd_which].bpp!=16) + { + delete m_file; + m_file=0; + } + +} + +LICECaptureDecompressor::~LICECaptureDecompressor() +{ + inflateEnd(&m_compstream); + delete m_file; +} + +bool LICECaptureDecompressor::NextFrame() // TRUE if out of frames +{ + if (++m_frameidx >= m_frame_deltas[m_rd_which].GetSize()) + { + m_rd_which=!m_rd_which; + + DecompressBlock(m_rd_which,1.0); + if (!ReadHdr(!m_rd_which)) + memset(&m_curhdr[!m_rd_which],0,sizeof(m_curhdr[!m_rd_which])); + m_frameidx=0; + if (!m_curhdr[m_rd_which].bpp) return false; + DecodeSlices(); + } + else + DecompressBlock(!m_rd_which,m_frameidx/(double)m_frame_deltas[m_rd_which].GetSize()); + return false; +} + +int LICECaptureDecompressor::Seek(unsigned int offset_ms) +{ + + memset(m_curhdr,0,sizeof(m_curhdr)); + if (!m_file) return -1; + + int rval=0; + + unsigned int seekpos=0; + m_frameidx=0; + if (offset_ms>0&&m_file_frame_info.GetSize()) + { + int x; + for(x=0;x0) rval=-1; + offset_ms=0; + } + + m_rd_which=0; + m_file->SetPosition(seekpos); + if (!ReadHdr(m_rd_which)||!DecompressBlock(m_rd_which,1.0)) + { + rval=-1; + memset(&m_curhdr,0,sizeof(m_curhdr)); + } + else + { + if (offset_ms>0 && rval==0) + { + int x; + for (x = 1; x < m_frame_deltas[m_rd_which].GetSize(); x++) + { + if (offset_ms < m_frame_deltas[m_rd_which].Get()[x]) + { + rval = offset_ms; + break; + } + offset_ms -= m_frame_deltas[m_rd_which].Get()[x]; + } + m_frameidx=x-1; + } + if (!ReadHdr(!m_rd_which)) + memset(&m_curhdr[!m_rd_which],0,sizeof(m_curhdr[!m_rd_which])); + + DecodeSlices(); + } + + return rval; +} + + +bool LICECaptureDecompressor::ReadHdr(int whdr) // todo: eventually make this read/decompress the next header as it goes +{ + m_tmp.Clear(); + int hdr_sz = (4*9); + if (m_file->Read(m_tmp.Add(NULL,hdr_sz),hdr_sz)!=hdr_sz) return false; + int ver; + m_tmp.GetTFromLE(&ver); + if (ver !=LCF_VERSION) return false; + m_tmp.GetTFromLE(&m_curhdr[whdr].bpp); + m_tmp.GetTFromLE(&m_curhdr[whdr].w); + m_tmp.GetTFromLE(&m_curhdr[whdr].h); + m_tmp.GetTFromLE(&m_curhdr[whdr].bsize_w); + m_tmp.GetTFromLE(&m_curhdr[whdr].bsize_h); + int nf; + m_tmp.GetTFromLE(&nf); + int csize; + m_tmp.GetTFromLE(&csize); + + int dsize; + m_tmp.GetTFromLE(&dsize); + + if (nf<1 || nf > 1024) return false; + + m_frame_deltas[whdr].Resize(nf); + + if (m_frame_deltas[whdr].GetSize()!=nf) return false; + + if (m_file->Read(m_frame_deltas[whdr].Get(),nf*4)!=nf*4) return false; + int x; + for(x=0;xpercent) break; + } + unsigned char buf[16384]; + m_compstream.next_in = buf; + m_compstream.avail_in = m_curhdr[whdr].cdata_left; + if (m_compstream.avail_in > (int)sizeof(buf)) m_compstream.avail_in=(int)sizeof(buf); + + m_compstream.avail_in = m_file->Read(buf,m_compstream.avail_in); + m_curhdr[whdr].cdata_left -= m_compstream.avail_in; + + int e = inflate(&m_compstream,0); + if (e != Z_OK&&e!=Z_STREAM_END) + { +// printf("inflate error: %d (%d/%d)\n",e,m_compstream.avail_in, m_curhdr[whdr].cdata_left); + return !m_compstream.avail_out; + } + if (!m_compstream.avail_out && !m_compstream.avail_in) break; + } + } + + return true; +} + +int LICECaptureDecompressor::GetTimeToNextFrame() +{ + int nf = m_frame_deltas[m_rd_which].GetSize(); + int fidx = m_frameidx; + + if (fidx<0&& nf) return m_frame_deltas[m_rd_which].Get()[0]; + + if (fidx+1 < nf) return m_frame_deltas[m_rd_which].Get()[fidx+1]; + + if (m_curhdr[!m_rd_which].bpp && m_frame_deltas[!m_rd_which].GetSize()) + return m_frame_deltas[!m_rd_which].Get()[0]; + + return 100; +} + +void LICECaptureDecompressor::DecodeSlices() +{ + int nf = m_frame_deltas[m_rd_which].GetSize(); + unsigned char *sp = (unsigned char *)m_decompdata[m_rd_which].Get(); + int sp_left = m_decompdata[m_rd_which].GetSize(); + hdrType *hdr = m_curhdr+m_rd_which; + int ns_x = (hdr->w + hdr->bsize_w-1)/hdr->bsize_w; + int ns_y = (hdr->h + hdr->bsize_h-1)/hdr->bsize_h; + + int ns_frame = ns_x*ns_y; + void **slicelist = m_slices.Resize(nf * ns_frame); + + // format of sp is: + // nf slices + // each slice is : + // initial value + // repeat cnt + // frame + // repeat cnt + // .. + + int ypos, + toth=hdr->h, + totw=hdr->w; + + int bytespersample = (hdr->bpp+7)/8; + + for (ypos = 0; ypos < toth; ypos+=hdr->bsize_h) + { + int hei = toth-ypos; + if (hei>hdr->bsize_h) hei=hdr->bsize_h; + int xpos; + for (xpos=0; xposbsize_w) + { + int wid = totw-xpos; + if (wid>hdr->bsize_w) wid=hdr->bsize_w; + + int sz1=wid*hei*bytespersample; + + int slicewritepos = 0,i = 0; + void *lvalid = NULL; + while (i0) + { + if (lvalid) + { + unsigned char c = *sp++; + sp_left--; + while (c-->0 && i++ < nf) + { + // repeat last slice + slicelist[slicewritepos] = lvalid; + slicewritepos += ns_frame; + } + } + if (i=0 && fidx < nf && m_slices.GetSize() && hdr->bsize_w && hdr->bsize_h) + { + int ns_x = (hdr->w + hdr->bsize_w-1)/hdr->bsize_w; + int ns_y = (hdr->h + hdr->bsize_h-1)/hdr->bsize_h; + + int ns_frame = ns_x*ns_y; + + if (m_slices.GetSize() != ns_frame*nf) + return NULL; // invalid slices + + if (hdr->bpp == 16) + { + m_workbm.resize(hdr->w,hdr->h); + //unsigned short * + // format of m_decompdata is: + // nf frames of slice1, nf frames of slice2, etc + + LICE_pixel *pout = m_workbm.getBits(); + int span = m_workbm.getRowSpan(); + + int ypos, + toth=hdr->h, + totw=hdr->w; + void **sliceptr = m_slices.Get() + ns_frame * fidx; + + for (ypos = 0; ypos < toth; ypos+=hdr->bsize_h) + { + int hei = toth-ypos; + if (hei>hdr->bsize_h) hei=hdr->bsize_h; + int xpos; + for (xpos=0; xposbsize_w) + { + int wid = totw-xpos; + if (wid>hdr->bsize_w) wid=hdr->bsize_w; + + int sz1=wid*hei; + + unsigned short *rdptr = (unsigned short *)*sliceptr; + + sliceptr++; + + LICE_pixel *dest = pout + xpos + ypos*span; + int y; + for (y=0;y>3)&0xFC,(px>>8)&0xF8,255); + } + dest+=span; + } + } + } + + + return &m_workbm; + } + } + return NULL; +} \ No newline at end of file diff --git a/WDL/lice/lice_lcf.h b/WDL/lice/lice_lcf.h new file mode 100644 index 00000000..b60801e0 --- /dev/null +++ b/WDL/lice/lice_lcf.h @@ -0,0 +1,110 @@ +#ifndef _LICE_LCF_H_ +#define _LICE_LCF_H_ + +#include "../zlib/zlib.h" +#include "lice.h" + +#include "../ptrlist.h" +#include "../queue.h" +class WDL_FileWrite; +class WDL_FileRead; + +class LICECaptureCompressor +{ +public: + LICECaptureCompressor(const char *outfn, int w, int h, int interval=20, int bsize_w=128, int bsize_h=16); + + ~LICECaptureCompressor(); + + bool IsOpen() { return !!m_file; } + void OnFrame(LICE_IBitmap *fr, int delta_t_ms); + + WDL_INT64 GetOutSize() { return m_outsize; } + WDL_INT64 GetInSize() { return m_inbytes; } + + +private: + WDL_FileWrite *m_file; + WDL_INT64 m_outsize,m_inbytes; + int m_inframes, m_outframes; + + int m_w,m_h,m_interval,m_bsize_w,m_bsize_h; + + + struct frameRec + { + frameRec(int sz) { data=(unsigned short *)malloc(sz*sizeof(short)); delta_t_ms=0; } + ~frameRec() { free(data); } + unsigned short *data; // shorts + int delta_t_ms; // time (ms) since last frame + }; + WDL_PtrList m_framelists[2]; + WDL_Queue m_current_block; + WDL_Queue m_hdrqueue; + + int m_state, m_which,m_outchunkpos,m_numrows,m_numcols; + int m_current_block_srcsize; + + z_stream m_compstream; + + void BitmapToFrameRec(LICE_IBitmap *fr, frameRec *dest); + void DeflateBlock(void *data, int data_size, bool flush); + void AddHdrInt(int a) { m_hdrqueue.AddToLE(&a); } + + +}; + + +class LICECaptureDecompressor +{ +public: + LICECaptureDecompressor(const char *fn, bool want_seekable=false); + ~LICECaptureDecompressor(); + + + bool IsOpen() { return !!m_file; } + + // only supported if want_seekable=true + int GetLength() { return m_file_length_ms; } // length in ms + int Seek(unsigned int offset_ms); // return -1 on fail (out of range), or >0 to tell you how far into the frame you seeked (0=exact hit) + + bool NextFrame(); // TRUE if out of frames + LICE_IBitmap *GetCurrentFrame(); // can return NULL if error + int GetTimeToNextFrame(); // delta in ms + + int GetWidth(){ return m_curhdr[m_rd_which].w; } + int GetHeight(){ return m_curhdr[m_rd_which].h; } + +private: + LICE_MemBitmap m_workbm; + + struct hdrType + { + int bpp; + int w, h; + int bsize_w, bsize_h; + int cdata_left; + } m_curhdr[2]; + + int m_rd_which; + int m_frameidx; + + bool ReadHdr(int whdr); + bool DecompressBlock(int whdr, double percent=1.0); + + z_stream m_compstream; + WDL_Queue m_tmp; + + WDL_FileRead *m_file; + + unsigned int m_file_length_ms; + WDL_TypedQueue m_file_frame_info; //pairs of offset_bytes, offset_ms + + WDL_TypedBuf m_frame_deltas[2]; + WDL_HeapBuf m_decompdata[2]; + WDL_TypedBuf m_slices; // indexed by [frame][slice] + + void DecodeSlices(); +}; + +#endif diff --git a/WDL/lice/lice_line.cpp b/WDL/lice/lice_line.cpp new file mode 100644 index 00000000..71eef6bb --- /dev/null +++ b/WDL/lice/lice_line.cpp @@ -0,0 +1,1612 @@ +#include "lice.h" +#include "lice_combine.h" +#include "lice_extended.h" +#include +#include +//#include + +template inline void SWAP(T& a, T& b) { T tmp = a; a = b; b = tmp; } + +enum { eOK = 0, eXLo = 1, eXHi = 2, eYLo = 4, eYHi = 8 }; + +static int OffscreenTest(int x, int y, int nX, int nY) +{ + int e = eOK; + if (x < 0) e |= eXLo; + else if (x >= nX) e |= eXHi; + if (y < 0) e |= eYLo; + else if (y >= nY) e |= eYHi; + return e; +} + +// Cohen-Sutherland. Returns false if the line is entirely offscreen. +static bool ClipLine(int* pX1, int* pY1, int* pX2, int* pY2, int nX, int nY) +{ + int x1 = *pX1, y1 = *pY1, x2 = *pX2, y2 = *pY2; + int e1 = OffscreenTest(x1, y1, nX, nY); + int e2 = OffscreenTest(x2, y2, nX, nY); + + bool accept = false, done = false; + do + { + if (!(e1 | e2)) { + accept = done = true; + } + else + if (e1 & e2) { + done = true; // Line is entirely offscreen. + } + else { + int x, y; + int eOut = e1 ? e1 : e2; + if (eOut & eYHi) { + x = x1 + (int) ((double) (x2 - x1) * (double) (nY - y1) / (double) (y2 - y1)); + y = nY - 1; + } + else + if (eOut & eYLo) { + x = x1 + (int) ((double) (x2 - x1) * (double) -y1 / (double) (y2 - y1)); + y = 0; + } + else + if (eOut & eXHi) { + y = y1 + (int) ((double) (y2 - y1) * (double) (nX - x1) / (double) (x2 - x1)); + x = nX - 1; + } + else { + y = y1 + (int) ((double) (y2 - y1) * (double) -x1 / (double) (x2 - x1)); + x = 0; + } + + if (eOut == e1) { + x1 = x; + y1 = y; + e1 = OffscreenTest(x1, y1, nX, nY); + } + else { + x2 = x; + y2 = y; + e2 = OffscreenTest(x2, y2, nX, nY); + } + } + } + while (!done); + + *pX1 = x1; + *pY1 = y1; + *pX2 = x2; + *pY2 = y2; + return accept; +} + +static int OffscreenFTest(float x, float y, float w, float h) +{ + int e = eOK; + if (x < 0.0f) e |= eXLo; + else if (x >= w) e |= eXHi; + if (y < 0.0f) e |= eYLo; + else if (y >= h) e |= eYHi; + return e; +} + +static bool ClipFLine(float* x1, float* y1, float* x2, float*y2, int w, int h) +{ + float tx1 = *x1, ty1 = *y1, tx2 = *x2, ty2 = *y2; + float tw = (float)(w-1), th = (float)(h-1); + + int e1 = OffscreenFTest(tx1, ty1, tw, th); + int e2 = OffscreenFTest(tx2, ty2, tw, th); + + bool accept = false, done = false; + do + { + if (!(e1|e2)) + { + accept = done = true; + } + else + if (e1&e2) + { + done = true; // Line is entirely offscreen. + } + else + { + float x, y; + int eOut = (e1 ? e1 : e2); + if (eOut&eYHi) + { + x = tx1+(tx2-tx1)*(th-ty1)/(ty2-ty1); + y = th-1.0f; + } + else if (eOut&eYLo) + { + x = tx1+(tx2-tx1)*ty1/(ty1-ty2); + y = 0.0f; + } + else if (eOut&eXHi) + { + y = ty1+(ty2-ty1)*(tw-tx1)/(tx2-tx1); + x = tw-1.0f; + } + else + { + y = ty1+(ty2-ty1)*tx1/(tx1-tx2); + x = 0.0f; + } + + if (eOut == e1) + { + tx1 = x; + ty1 = y; + e1 = OffscreenFTest(tx1, ty1, tw, th); + } + else + { + tx2 = x; + ty2 = y; + e2 = OffscreenFTest(tx2, ty2, tw, th); + } + } + } + while (!done); + + *x1 = tx1; + *y1 = ty1; + *x2 = tx2; + *y2 = ty2; + return accept; +} + + +inline static void LICE_DiagLineFAST(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, bool aa) +{ + int step = xstep+ystep; + if (aa) + { + LICE_pixel color75 = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); + LICE_pixel color25 = (color>>2)&0x3f3f3f3f; + while (n--) + { + _LICE_CombinePixelsThreeQuarterMix2FAST::doPixFAST(px, color75); + _LICE_CombinePixelsQuarterMix2FAST::doPixFAST(px+xstep, color25); + _LICE_CombinePixelsQuarterMix2FAST::doPixFAST(px+ystep, color25); + px += step; + } + _LICE_CombinePixelsThreeQuarterMix2FAST::doPixFAST(px, color75); + } + else + { + ++n; + while (n--) + { + *px = color; + px += step; + } + } +} + +inline static void LICE_DottedVertLineFAST(LICE_IBitmap* dest, int x, int y1, int y2, LICE_pixel color) +{ + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span+x; + + int n = (y2-y1+1)/2; + while (n--) + { + *px = color; + px += 2*span; + } +} + +// this is the white-color table, doing this properly requires correcting the destination color specifically +#define DO_AA_GAMMA_CORRECT 0 +static unsigned char AA_GAMMA_CORRECT[256] = +{ + // 1.8 gamma + 0,11,17,21,25,28,31,34,37,39,42,44,46,48,50,52,54,56,58,60,61,63,65,67,68,70,71,73,74,76,77,79,80,81,83,84,85,87,88,89,91,92,93,94,96,97,98,99,100,101,103,104,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,132,133,134,135,136,137,138,139,140,141,142,142,143,144,145,146,147,148,149,149,150,151,152,153,154,154,155,156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,170,170,171,172,173,173,174,175,176,176,177,178,179,179,180,181,182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202,203,204,204,205,206,206,207,208,208,209,210,210,211,212,212,213,214,214,215,215,216,217,217,218,219,219,220,220,221,222,222,223,224,224,225,225,226,227,227,228,228,229,230,230,231,231,232,233,233,234,234,235,236,236,237,237,238,239,239,240,240,241,241,242,243,243,244,244,245,245,246,247,247,248,248,249,249,250,251,251,252,252,253,253,254,255 + + // 2.0 gamma + //0,15,22,27,31,35,39,42,45,47,50,52,55,57,59,61,63,65,67,69,71,73,74,76,78,79,81,82,84,85,87,88,90,91,93,94,95,97,98,99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,141,142,143,144,145,146,147,148,148,149,150,151,152,153,153,154,155,156,157,158,158,159,160,161,162,162,163,164,165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,177,177,178,179,179,180,181,182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,201,202,203,203,204,205,205,206,206,207,208,208,209,210,210,211,211,212,213,213,214,214,215,216,216,217,217,218,218,219,220,220,221,221,222,222,223,224,224,225,225,226,226,227,228,228,229,229,230,230,231,231,232,233,233,234,234,235,235,236,236,237,237,238,238,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,255 + + // 2.2 gamma + //0,20,28,33,38,42,46,49,52,55,58,61,63,65,68,70,72,74,76,78,80,81,83,85,87,88,90,91,93,94,96,97,99,100,102,103,104,106,107,108,109,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,136,137,138,139,140,141,142,143,144,145,146,147,147,148,149,150,151,152,153,153,154,155,156,157,158,158,159,160,161,162,162,163,164,165,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,178,179,180,181,181,182,183,183,184,185,185,186,187,187,188,189,189,190,190,191,192,192,193,194,194,195,196,196,197,197,198,199,199,200,200,201,202,202,203,203,204,205,205,206,206,207,208,208,209,209,210,210,211,212,212,213,213,214,214,215,216,216,217,217,218,218,219,219,220,220,221,222,222,223,223,224,224,225,225,226,226,227,227,228,228,229,229,230,230,231,231,232,232,233,233,234,234,235,235,236,236,237,237,238,238,239,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,249,250,250,251,251,252,252,253,253,254,254,255 + + // 2.6 gamma + //0,30,39,46,51,56,60,63,67,70,73,76,78,81,83,85,87,89,91,93,95,97,99,101,102,104,105,107,109,110,111,113,114,116,117,118,120,121,122,123,125,126,127,128,129,130,131,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,148,149,150,151,152,153,154,155,155,156,157,158,159,160,160,161,162,163,164,164,165,166,167,167,168,169,170,170,171,172,173,173,174,175,175,176,177,177,178,179,179,180,181,181,182,183,183,184,185,185,186,187,187,188,188,189,190,190,191,192,192,193,193,194,195,195,196,196,197,197,198,199,199,200,200,201,201,202,203,203,204,204,205,205,206,206,207,207,208,208,209,210,210,211,211,212,212,213,213,214,214,215,215,216,216,217,217,218,218,219,219,220,220,221,221,222,222,223,223,223,224,224,225,225,226,226,227,227,228,228,229,229,230,230,230,231,231,232,232,233,233,234,234,234,235,235,236,236,237,237,237,238,238,239,239,240,240,240,241,241,242,242,243,243,243,244,244,245,245,245,246,246,247,247,247,248,248,249,249,249,250,250,251,251,251,252,252,253,253,253,254,254,255 +}; + +static void GetAAPxWeight(int err, int alpha, int* wt, int* iwt) +{ + int i = err/256; + int w = 255-i; + +#if DO_AA_GAMMA_CORRECT + w = AA_GAMMA_CORRECT[w]; + i = AA_GAMMA_CORRECT[i]; +#endif + + w = alpha*w/256; + i = alpha*i/256; + *wt = w; + *iwt = i; +} + +static void GetAAPxWeightFAST(int err, int* wt, int* iwt) +{ + int i = err/256; + int w = 255-i; + +#if DO_AA_GAMMA_CORRECT + w = AA_GAMMA_CORRECT[w]; + i = AA_GAMMA_CORRECT[i]; +#endif + + *wt = w; + *iwt = i; +} +template class __LICE_LineClassSimple +{ +public: + static void LICE_VertLineFAST(LICE_pixel *px, int span, int len, LICE_pixel color) + { + while (len--) + { + COMBFUNC::doPixFAST(px, color); + px+=span; + } + } + + static void LICE_HorizLineFAST(LICE_pixel *px, int n, LICE_pixel color) + { + while (n--) + { + COMBFUNC::doPixFAST(px, color); + px++; + } + } + static void LICE_VertLine(LICE_pixel *px, int span, int len, int color, int aw) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + while (len--) + { + COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); + px+=span; + } + } + + static void LICE_HorizLine(LICE_pixel *px, int n, LICE_pixel color, int aw) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + while (n--) + { + COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); + px++; + } + } + static void LICE_DiagLine(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, int aw) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + int step = xstep+ystep; + + for (int i = 0; i <= n; ++i, px += step) + { + COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, aw); + } + } + static void LICE_DiagLineAA(LICE_pixel *px, int span, int n, int xstep, int ystep, LICE_pixel color, int aw) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + int step = xstep+ystep; + +#if DO_AA_GAMMA_CORRECT + int iw = aw*AA_GAMMA_CORRECT[256*3/4]/256; + int dw = aw*AA_GAMMA_CORRECT[256/4]/256; +#else + int iw = aw*3/4; + int dw = aw/4; +#endif + for (int i = 0; i < n; ++i, px += step) + { + COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, iw); + COMBFUNC::doPix((LICE_pixel_chan*) (px+xstep), r, g, b, a, dw); + COMBFUNC::doPix((LICE_pixel_chan*) (px+ystep), r, g, b, a, dw); + } + COMBFUNC::doPix((LICE_pixel_chan*) px, r, g, b, a, iw); + } +}; + + +#ifndef LICE_FAVOR_SIZE +template +#endif +class __LICE_LineClass +{ +public: + +#ifdef LICE_FAVOR_SIZE + #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); +#else + #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); +#endif + + static void DashedLine(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int pxon, int pxoff, LICE_pixel color, int aw +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + ) + { + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span+x1; + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + if (x1 == x2) + { + int i, y; + for (y = y1; y < y2-pxon; y += pxon+pxoff) + { + for (i = 0; i < pxon; ++i, px += span) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) + px += pxoff*span; + } + for (i = 0; i < min(pxon, y2-y); px += span) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) + } + else if (y1 == y2) + { + int i, x; + for (x = x1; x < x2-pxon; x += pxon+pxoff) + { + for (i = 0; i < pxon; ++i, ++px) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) + px += pxoff; + } + for (i = 0; i < min(pxon, x2-x); ++px) DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) + } + } + + + + + static void LICE_LineImpl(LICE_pixel *px, LICE_pixel *px2, int derr, int astep, int da, int bstep, LICE_pixel color, int aw, bool aa +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + ) + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + int err = 0; + int i; + int n = (da+1)/2; + + if (aa) + { + DOPIX((LICE_pixel_chan*) px, r, g, b, a, aw) + DOPIX((LICE_pixel_chan*) px2, r, g, b, a, aw) + px += astep; + px2 -= astep; + err = derr; + + if (aw == 256) + { + for (i = 1; i < n; ++i) + { + int wt, iwt; + GetAAPxWeightFAST(err, &wt, &iwt); + DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) + DOPIX((LICE_pixel_chan*)px2, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px2-bstep), r, g, b, a, iwt) + + err += derr; + if (err >= 65536) + { + px += bstep; + px2 -= bstep; + err -= 65536; + } + px += astep; + px2 -= astep; + } + } + else // alpha<256 + { + for (i = 1; i < n; ++i) + { + int wt, iwt; + GetAAPxWeight(err, aw, &wt, &iwt); + DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) + DOPIX((LICE_pixel_chan*)px2, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px2-bstep), r, g, b, a, iwt) + + err += derr; + if (err >= 65536) + { + px += bstep; + px2 -= bstep; + err -= 65536; + } + px += astep; + px2 -= astep; + } + } + if (!(da%2)) + { + int wt, iwt; + if (aw == 256) GetAAPxWeightFAST(err, &wt, &iwt); + else GetAAPxWeight(err, aw, &wt, &iwt); + DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) + } + } + else // not aa + { + for (i = 0; i < n; ++i) + { + DOPIX((LICE_pixel_chan*)px, r, g, b, a, aw) + DOPIX((LICE_pixel_chan*)px2, r, g, b, a, aw) + err += derr; + if (err >= 65536/2) + { + px += bstep; + px2 -= bstep; + err -= 65536; + } + + px += astep; + px2 -= astep; + } + if (!(da%2)) + { + DOPIX((LICE_pixel_chan*)px, r, g, b, a, aw) + } + } + } + + static void LICE_FLineImpl(LICE_pixel *px, int n , int err, int derr, int astep, int bstep, LICE_pixel color, int aw +#ifdef LICE_FAVOR_SIZE + , LICE_COMBINEFUNC combFunc +#endif + + ) // only does AA + { + int r = LICE_GETR(color), g = LICE_GETG(color), b = LICE_GETB(color), a = LICE_GETA(color); + + + int wt, iwt; + int i; + + if (aw == 256) + { + for (i = 0; i <= n; ++i) + { + GetAAPxWeightFAST(err, &wt, &iwt); + DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) + + err += derr; + if (err >= 65536) + { + px += bstep; + err -= 65536; + } + px += astep; + } + } + else // alpha != 256 + { + for (i = 0; i <= n; ++i) + { + GetAAPxWeight(err, aw, &wt, &iwt); + DOPIX((LICE_pixel_chan*)px, r, g, b, a, wt) + DOPIX((LICE_pixel_chan*)(px+bstep), r, g, b, a, iwt) + + err += derr; + if (err >= 65536) + { + px += bstep; + err -= 65536; + } + px += astep; + } + } + } +#undef DOPIX +}; + + +void LICE_Line(LICE_IBitmap *dest, int x1, int y1, int x2, int y2, LICE_pixel color, float alpha, int mode, bool aa) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_LINE_ACCEL)) + { + LICE_Ext_Line_acceldata data(x1, y1, x2, y2, color, alpha, mode, aa); + if (dest->Extended(LICE_EXT_LINE_ACCEL, &data)) return; + } +#endif + + int w = dest->getWidth(); + int h = dest->getHeight(); + if (dest->isFlipped()) + { + y1 = h-1-y1; + y2 = h-1-y2; + } + + if (ClipLine(&x1, &y1, &x2, &y2, w, h)) + { + int xdiff = x2-x1; + if (y1 == y2) // horizontal line optimizations + { + if (x1 > x2) SWAP(x1, x2); + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span+x1; + int n=x2-x1+1; + + if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) + { + __LICE_LineClassSimple<_LICE_CombinePixelsClobberFAST>::LICE_HorizLineFAST(px, n, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.5f) + { + color = (color>>1)&0x7f7f7f7f; + __LICE_LineClassSimple<_LICE_CombinePixelsHalfMix2FAST>::LICE_HorizLineFAST(px, n, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.25f) + { + color = (color>>2)&0x3f3f3f3f; + __LICE_LineClassSimple<_LICE_CombinePixelsQuarterMix2FAST>::LICE_HorizLineFAST(px, n, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.75f) + { + color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); + __LICE_LineClassSimple<_LICE_CombinePixelsThreeQuarterMix2FAST>::LICE_HorizLineFAST(px, n, color); + } + else + { + int aw = (int)(256.0f*alpha); +#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_HorizLine(px, n, color, aw) + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); +#undef __LICE__ACTION + } + } + else if (!xdiff) // vertical line optimizations + { + if (y1 > y2) SWAP(y1, y2); + int len=y2+1-y1; + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span+x1; + int aw = (int)(256.0f*alpha); + if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) + { + __LICE_LineClassSimple<_LICE_CombinePixelsClobberFAST>::LICE_VertLineFAST(px, span, len, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.5f) + { + color = (color>>1)&0x7f7f7f7f; + __LICE_LineClassSimple<_LICE_CombinePixelsHalfMix2FAST>::LICE_VertLineFAST(px, span, len, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.25f) + { + color = (color>>2)&0x3f3f3f3f; + __LICE_LineClassSimple<_LICE_CombinePixelsQuarterMix2FAST>::LICE_VertLineFAST(px, span, len, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 0.75f) + { + color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); + __LICE_LineClassSimple<_LICE_CombinePixelsThreeQuarterMix2FAST>::LICE_VertLineFAST(px, span, len, color); + } + else + { +#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_VertLine(px, span, len, color,aw) + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); +#undef __LICE__ACTION + } + } + else if ((xdiff=abs(xdiff)) == abs(y2-y1)) // diagonal line optimizations + { + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span+x1; + int aw = (int)(256.0f*alpha); + int xstep = (x2 > x1 ? 1 : -1); + int ystep = (y2 > y1 ? span : -span); + if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) + { + LICE_DiagLineFAST(px,span, xdiff, xstep, ystep, color, aa); + } + else + { + if (aa) + { +#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_DiagLineAA(px,span, xdiff, xstep, ystep, color, aw) + __LICE_ACTION_NOSRCALPHA(mode, aw, false); +#undef __LICE__ACTION + } + else + { +#define __LICE__ACTION(COMBFUNC) __LICE_LineClassSimple::LICE_DiagLine(px,span, xdiff, xstep, ystep, color, aw) + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); +#undef __LICE__ACTION + } + } + } + else + { + + // common set-up for normal line draws + + int span = dest->getRowSpan(); + int aw = (int)(256.0f*alpha); + LICE_pixel* px = dest->getBits()+y1*span+x1; + LICE_pixel* px2 = dest->getBits()+y2*span+x2; + + int da, db; + int astep, bstep; + int dx = x2-x1; + int dy = y2-y1; + + if (abs(dx) > abs(dy)) + { + da = dx; + db = dy; + astep = 1; + bstep = span; + } + else + { + da = dy; + db = dx; + astep = span; + bstep = 1; + } + + if (da < 0) + { + da = -da; + db = -db; + SWAP(px, px2); + } + if (db < 0) + { + db = -db; + bstep = -bstep; + } + + double dbda = (double)db/(double)da; + + int derr = (int)(dbda*65536.0); + +#ifdef LICE_FAVOR_SIZE + + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + +#else + #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::LICE_LineImpl(px,px2, derr, astep, da, bstep, color, aw, aa) +#endif + if (aa) + { + __LICE_ACTION_NOSRCALPHA(mode, aw, false); + } + else + { + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); + } + + #undef __LICE__ACTION + +#ifdef LICE_FAVOR_SIZE + if (blitfunc) __LICE_LineClass::LICE_LineImpl(px,px2, derr, astep, da, bstep, color, aw, aa, blitfunc); +#endif + } + } +} + +void LICE_FLine(LICE_IBitmap* dest, float x1, float y1, float x2, float y2, LICE_pixel color, float alpha, int mode, bool aa) +{ + if (!dest) return; + if (!aa) + { + LICE_Line(dest,(int)x1,(int)y1,(int)x2,(int)y2,color,alpha,mode,false); + return; + } + + int w = dest->getWidth(); + int h = dest->getHeight(); + if (dest->isFlipped()) + { + y1 = (float)(h-1)-y1; + y2 = (float)(h-1)-y2; + } + + if (ClipFLine(&x1, &y1, &x2, &y2, w, h)) + { + if (x1 != x2 || y1 != y2) + { + int span = dest->getRowSpan(); + int aw = (int)(256.0f*alpha); + + float a1, a2, b1, b2, da, db; + int astep, bstep; + float dx = x2-x1; + float dy = y2-y1; + + if (fabs(dx) > fabs(dy)) + { + a1 = x1; + a2 = x2; + b1 = y1; + b2 = y2; + da = dx; + db = dy; + astep = 1; + bstep = span; + } + else + { + a1 = y1; + a2 = y2; + b1 = x1; + b2 = x2; + da = dy; + db = dx; + astep = span; + bstep = 1; + } + + if (da < 0.0f) + { + da = -da; + db = -db; + SWAP(a1, a2); + SWAP(b1, b2); + } + if (db < 0.0f) + { + bstep = -bstep; + } + + int n = (int)(floor(a2)-ceil(a1)); + float dbda = db/da; + + float ta = ceil(a1); + float tb = b1+(ta-a1)*dbda; + float bf = tb-floor(tb); + int err = (int)(bf*65536.0f); + if (bstep < 0) err = 65535-err; + int derr = (int)(fabs(dbda)*65536.0f); + + LICE_pixel* px = dest->getBits()+(int)ta*astep+(int)tb*abs(bstep); + + if (bstep < 0) px -= bstep; + +#ifdef LICE_FAVOR_SIZE + + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + +#else + + #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::LICE_FLineImpl(px,n,err,derr,astep,bstep, color, aw) +#endif + + __LICE_ACTION_NOSRCALPHA(mode, aw, false); + +#ifdef LICE_FAVOR_SIZE + if (blitfunc) __LICE_LineClass::LICE_FLineImpl(px,n,err,derr,astep,bstep, color, aw, blitfunc); +#endif + + #undef __LICE__ACTION + } + } +} + +void LICE_DashedLine(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int pxon, int pxoff, LICE_pixel color, float alpha, int mode, bool aa) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DASHEDLINE_ACCEL)) + { + LICE_Ext_DashedLine_acceldata data(x1, y1, x2, y2, pxon, pxoff, color, alpha, mode, aa); + if (dest->Extended(LICE_EXT_DASHEDLINE_ACCEL, &data)) return; + } +#endif + + int w = dest->getWidth(); + int h = dest->getHeight(); + if (ClipLine(&x1, &y1, &x2, &y2, w, h)) + { + if (y1 > y2) SWAP(y1, y2); + if (pxon == 1 && pxoff == 1 && x1 == x2 && (mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && alpha == 1.0f) + { + LICE_DottedVertLineFAST(dest, x1, y1, y2, color); + } + else + { + int aw = (int)(256.0f*alpha); + if (x1 > x2) SWAP(x1, x2); + +#ifdef LICE_FAVOR_SIZE + + LICE_COMBINEFUNC blitfunc=NULL; + #define __LICE__ACTION(comb) blitfunc=comb::doPix; + +#else + + #define __LICE__ACTION(COMBFUNC) __LICE_LineClass::DashedLine(dest, x1, y1, x2, y2, pxon, pxoff, color, aw); +#endif + + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); + +#ifdef LICE_FAVOR_SIZE + if (blitfunc) __LICE_LineClass::DashedLine(dest, x1, y1, x2, y2, pxon, pxoff, color, aw, blitfunc); +#endif + +#undef __LICE__ACTION + } + } +} + +bool LICE_ClipLine(int* pX1, int* pY1, int* pX2, int* pY2, int xLo, int yLo, int xHi, int yHi) +{ + int x1 = *pX1-xLo; + int y1 = *pY1-yLo; + int x2 = *pX2-xLo; + int y2 = *pY2-yLo; + bool onscreen = ClipLine(&x1, &y1, &x2, &y2, xHi-xLo, yHi-yLo); + *pX1 = x1+xLo; + *pY1 = y1+yLo; + *pX2 = x2+xLo; + *pY2 = y2+yLo; + return onscreen; +} + +bool LICE_ClipFLine(float* px1, float* py1, float* px2, float* py2, float xlo, float ylo, float xhi, float yhi) +{ + float x1 = *px1-xlo; + float y1 = *py1-ylo; + float x2 = *px2-xlo; + float y2 = *py2-ylo; + bool onscreen = ClipFLine(&x1, &y1, &x2, &y2, xhi-xlo, yhi-ylo); + *px1 = x1+xlo; + *py1 = y1+ylo; + *px2 = x2+xlo; + *py2 = y2+ylo; + return onscreen; +} + + +#include "lice_bezier.h" + +static void DoBezierFillSegment(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int yfill, LICE_pixel color, float alpha, int mode) +{ + if (x2 < x1) return; + if (x2 == x1) + { + int ylo = min(y1,yfill); + int yhi = max(y2,yfill); + if (yhi != yfill) --yhi; + LICE_Line(dest, x1, ylo, x1, yhi, color, alpha, mode, false); + return; + } + + if ((y1 < yfill) == (y2 < yfill)) + { + if (y1 < yfill) ++yfill; + int x[4] = { x1, x1, x2, x2 }; + int y[4] = { y1, yfill, y2, yfill }; + LICE_FillConvexPolygon(dest, x, y, 4, color, alpha, mode); + } + else + { + int x = x1+(int)((double)(yfill-y1)*(double)(x2-x1)/(double)(y2-y1)); + int yf = yfill; + if (y1 < yfill) ++yf; + LICE_FillTriangle(dest, x1, y1, x1, yf, x, yf, color, alpha, mode); + yf = yfill; + if (y2 < yfill) ++yf; + LICE_FillTriangle(dest, x, yf, x2, yf, x2, y2, color, alpha, mode); + } +} + +static void DoBezierFillSegmentX(LICE_IBitmap* dest, int x1, int y1, int x2, int y2, int xfill, LICE_pixel color, float alpha, int mode) +{ + if (y2 < y1) return; + if (y2 == y1) + { + int xlo = min(x1,xfill); + int xhi = max(x2,xfill); + if (xhi != xfill) --xhi; + LICE_Line(dest, xlo, y1, xhi, y1, color, alpha, mode, false); + return; + } + + if ((x1 < xfill) == (x2 < xfill)) + { + if (x1 < xfill) ++xfill; + int x[4] = { x1, xfill, x2, xfill }; + int y[4] = { y1, y1, y2+1, y2+1 }; + LICE_FillConvexPolygon(dest, x, y, 4, color, alpha, mode); + } + else + { + int y = y1+(int)((double)(xfill-x1)*(double)(y2-y1)/(double)(x2-x1)); + int xf = xfill; + if (x1 < xfill) ++xf; + LICE_FillTriangle(dest, x1, y1, xf, y1, xf, y, color, alpha, mode); + xf = xfill; + if (x2 < xfill) ++xf; + LICE_FillTriangle(dest, xf, y, xf, y2, x2, y2, color, alpha, mode); + } +} + + +// quadratic bezier ... NOT TESTED YET +// attempt to draw segments no longer than tol px +void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl, float yctl, float xend, float yend, + LICE_pixel color, float alpha, int mode, bool aa, float tol) +{ + if (!dest) return; + + int w = dest->getWidth(); + + if (xstart > xend) + { + SWAP(xstart, xend); + SWAP(ystart, yend); + } + + double len = sqrt((xctl-xstart)*(xctl-xstart)+(yctl-ystart)*(yctl-ystart)); + len += sqrt((xend-xctl)*(xend-xctl)+(yend-yctl)*(yend-yctl)); + + float xlo = xstart; + float xhi = xend; + float ylo = ystart; + float yhi = yend; + double tlo = 0.0; + double thi = 1.0; + + if (xlo < 0.0f) + { + xlo = 0.0f; + ylo = LICE_Bezier_GetY(xstart, xctl, xend, ystart, yctl, yend, xlo, &tlo); + } + if (xhi >= (float)w) + { + xhi = (float)(w-1); + yhi = LICE_Bezier_GetY(xstart, xctl, xend, ystart, yctl, yend, xhi, &thi); + } + if (xlo > xhi) return; + + len *= (thi-tlo); + if (tol <= 0.0f) tol = 1.0f; + int nsteps = (int)(len/tol); + if (nsteps <= 0) nsteps = 1; + + double dt = (thi-tlo)/(double)nsteps; + double t = tlo+dt; + + float lastx = xlo; + float lasty = ylo; + float x, y; + int i; + for (i = 1; i < nsteps; ++i) + { + LICE_Bezier(xstart, xctl, xend, ystart, yctl, yend, t, &x, &y); + LICE_FLine(dest, lastx, lasty, x, y, color, alpha, mode, aa); + lastx = x; + lasty = y; + t += dt; + } + LICE_FLine(dest, lastx, lasty, xhi, yhi, color, alpha, mode, aa); + +} + +static int CBezPrep(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, + float xctl2, float yctl2, float xend, float yend, float tol, bool xbasis, + double* ax, double* bx, double* cx, double* dx, double* ay, double* by, double* cy, double* dy, + float* xlo, float* xhi, float* ylo, float* yhi, double* tlo, double* thi) +{ + if (!dest) return 0; + + int w = dest->getWidth(); + + if ((xbasis && xstart > xend) || (!xbasis && ystart > yend)) + { + SWAP(xstart, xend); + SWAP(xctl1, xctl2); + SWAP(ystart, yend); + SWAP(yctl1, yctl2); + } + + double len = sqrt((xctl1-xstart)*(xctl1-xstart)+(yctl1-ystart)*(yctl1-ystart)); + len += sqrt((xctl2-xctl1)*(xctl2-xctl1)+(yctl2-yctl1)*(yctl2-yctl1)); + len += sqrt((xend-xctl2)*(xend-xctl2)+(yend-yctl2)*(yend-yctl2)); + + LICE_CBezier_GetCoeffs(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, ax, bx, cx, ay, by, cy); + *dx = xstart; + *dy = ystart; + + *xlo = xstart; + *xhi = xend; + *ylo = ystart; + *yhi = yend; + *tlo = 0.0; + *thi = 1.0; + + if (*xlo < 0.0f) + { + *xlo = 0.0f; + *ylo = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xlo, (float*)0, (float*)0, (double*)0, tlo); + } + if (*xhi > (float)w) + { + *xhi = (float)(w); + *yhi = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xhi, (float*)0, (float*)0, thi, (double*)0); + } + if ((xbasis && *xlo > *xhi) || (!xbasis && *ylo > *yhi)) + { + return 0; + } + + len *= (*thi-*tlo); + if (tol <= 0.0f) tol = 1.0f; + int nsteps = (int)(len/tol); + if (nsteps <= 0) nsteps = 1; + return nsteps; +} + +void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, + float xctl2, float yctl2, float xend, float yend, LICE_pixel color, float alpha, int mode, bool aa, float tol) +{ + if (!dest) return; + +#ifndef DISABLE_LICE_EXTENSIONS + if (dest->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWCBEZIER_ACCEL)) + { + LICE_Ext_DrawCBezier_acceldata data(xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, color, alpha, mode, aa); + if (dest->Extended(LICE_EXT_DRAWCBEZIER_ACCEL, &data)) return; + } +#endif + + double ax, bx, cx, dx, ay, by, cy, dy; + float xlo, xhi, ylo, yhi; + double tlo, thi; + int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, + &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); + if (!nsteps) return; + + double dt = (thi-tlo)/(double)nsteps; + double t = tlo+dt; + + float lastx = xlo; + float lasty = ylo; + float x, y; + int i; + for (i = 1; i < nsteps-1; ++i) + { + EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); + LICE_FLine(dest, lastx, lasty, x, y, color, alpha, mode, aa); + lastx = x; + lasty = y; + t += dt; + } + LICE_FLine(dest, lastx, lasty, xhi, yhi, color, alpha, mode, aa); +} + +void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, + float xctl2, float yctl2, float xend, float yend, int yfill, LICE_pixel color, float alpha, int mode, float tol) +{ + if (!dest) return; + + double ax, bx, cx, dx, ay, by, cy, dy; + float xlo, xhi, ylo, yhi; + double tlo, thi; + int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, + &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); + if (!nsteps) return; + + double dt = (thi-tlo)/(double)nsteps; + double t = tlo+dt; + + int lastfillx = (int)xlo; + int lastfilly = (int)(ylo+0.5f); + float x, y; + int i; + for (i = 1; i < nsteps-1; ++i) + { + EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); + if ((int)x >= lastfillx) + { + int xi = (int)x; + int yi = (int)(y+0.5f); + DoBezierFillSegment(dest, lastfillx, lastfilly, xi, yi, yfill, color, alpha, mode); + lastfillx = xi+1; + lastfilly = yi; + } + t += dt; + } + if ((int)(xhi-1.0f) >= lastfillx) + { + DoBezierFillSegment(dest, lastfillx, lastfilly, (int)(xhi-1.0f),(int)(yhi+0.5f), yfill, color, alpha, mode); + } +} + +void LICE_FillCBezierX(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, + float xctl2, float yctl2, float xend, float yend, int xfill, LICE_pixel color, float alpha, int mode, float tol) +{ + if (!dest) return; + + double ax, bx, cx, dx, ay, by, cy, dy; + float xlo, xhi, ylo, yhi; + double tlo, thi; + int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, false, + &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); + if (!nsteps) return; + + double dt = (thi-tlo)/(double)nsteps; + double t = tlo+dt; + + int lastfillx = (int)(xlo+0.5f); + int lastfilly = (int)ylo; + float x, y; + int i; + for (i = 1; i < nsteps-1; ++i) + { + EVAL_CBEZXY(x, y, ax, bx, cx, dx, ay, by, cy, dy, t); + if ((int)y >= lastfilly) + { + int xi = (int)(x+0.5f); + int yi = (int)y; + DoBezierFillSegmentX(dest, lastfillx, lastfilly, xi, yi, xfill, color, alpha, mode); + lastfillx = xi; + lastfilly = yi+1; + } + t += dt; + } + if ((int)(yhi-1.0f) >= lastfilly) + { + DoBezierFillSegmentX(dest, lastfillx, lastfilly, (int)(xhi+0.5),(int)(yhi-1.0f), xfill, color, alpha, mode); + } +} + + +void LICE_DrawRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha, int mode) +{ + LICE_Line(dest, x, y, x+w, y, color, alpha, mode, false); + LICE_Line(dest, x+w, y, x+w, y+h, color, alpha, mode, false); + LICE_Line(dest, x+w, y+h, x, y+h, color, alpha, mode, false); + LICE_Line(dest, x, y+h, x, y, color, alpha, mode, false); +} + +void LICE_BorderedRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel bgcolor, LICE_pixel fgcolor, float alpha, int mode) +{ + LICE_FillRect(dest, x+1, y+1, w-1, h-1, bgcolor, alpha, mode); + LICE_DrawRect(dest, x, y, w, h, fgcolor, alpha, mode); +} + + +#ifndef LICE_FAVOR_SIZE_EXTREME +template +#endif +class _LICE_Fill +{ + +#ifdef LICE_FAVOR_SIZE_EXTREME + #define DOPIX(pout,r,g,b,a,ia) combFunc(pout,r,g,b,a,ia); +#else + #define DOPIX(pout,r,g,b,a,ia) COMBFUNC::doPix(pout,r,g,b,a,ia); +#endif + +public: + + // da, db are [0..65536] + static void FillClippedTrapezoid(int wid, int span, LICE_pixel *px, int y, int xa, int xb, int da, int db, int a, int b, int astep, int bstep, int cr, int cg, int cb, int ca, int aw +#ifdef LICE_FAVOR_SIZE_EXTREME + , LICE_COMBINEFUNC combFunc +#endif + ) + { + if (!da && !db) + { + while (y-->0) + { + LICE_pixel* xpx = px; + int x=xb; + while (x--) + { + DOPIX((LICE_pixel_chan*)xpx, cr, cg, cb, ca, aw) + ++xpx; + } + px += span; + } + return; + } + + + while (y-->0) + { + int x1=max(xa,0); + int x2=min(xb,wid); + LICE_pixel* xpx = px + x1; + int cnt=x2-x1; + while (cnt-->0) + { + DOPIX((LICE_pixel_chan*)xpx, cr, cg, cb, ca, aw) + ++xpx; + } + + a += da; + b += db; + if (a >= 65536) + { + int na = a/65536; + a %= 65536; + if (astep<0)na=-na; + xa += na; + } + if (b >= 65536) + { + int nb = b/65536; + b %= 65536; + if (bstep<0)nb=-nb; + xb += nb; + } + px += span; + } + } +}; + + +template class _LICE_FillFast +{ +public: + + // da, db are [0..65536] + static void FillClippedTrapezoidFAST(int wid, int span, LICE_pixel *px, int y, int xa, int xb, int da, int db, int a, int b, int astep, int bstep, LICE_pixel color) + { + if (!da && !db) + { + while (y-->0) + { + LICE_pixel* xpx = px; + int x=xb; + while (x--) + { + COMBFUNC::doPixFAST(xpx, color); + ++xpx; + } + px += span; + } + return; + } + + + while (y-->0) + { + int x1=max(xa,0); + int x2=min(xb,wid); + LICE_pixel* xpx = px + x1; + int cnt=x2-x1; + while (cnt-->0) + { + COMBFUNC::doPixFAST(xpx, color); + ++xpx; + } + + a += da; + b += db; + if (a >= 65536) + { + int na = a/65536; + a %= 65536; + if (astep<0)na=-na; + xa += na; + } + if (b >= 65536) + { + int nb = b/65536; + b %= 65536; + if (bstep<0)nb=-nb; + xb += nb; + } + px += span; + } + } +}; + +static int FindXOnSegment(int x1, int y1, int x2, int y2, int ty) +{ + if (y1 > y2) + { + SWAP(x1, x2); + SWAP(y1, y2); + } + if (ty <= y1) return x1; + if (ty >= y2) return x2; + float dxdy = (float)(x2-x1)/(float)(y2-y1); + return x1+(int)((float)(ty-y1)*dxdy); +} + +static int FindYOnSegment(int x1, int y1, int x2, int y2, int tx) +{ + if (x1 > x2) + { + SWAP(x1, x2); + SWAP(y1, y2); + } + if (tx <= x1) return y1; + if (tx >= x2) return y2; + float dydx = (float)(y2-y1)/(float)(x2-x1); + return y1+(int)((float)(tx-x1)*dydx); +} + +void LICE_FillTrapezoid(LICE_IBitmap* dest, int x1a, int x1b, int y1, int x2a, int x2b, int y2, LICE_pixel color, float alpha, int mode) +{ + if (!dest) return; + if (y1 > y2) + { + SWAP(y1, y2); + SWAP(x1a, x2a); + SWAP(x1b, x2b); + } + if (x1a > x1b) SWAP(x1a, x1b); + if (x2a > x2b) SWAP(x2a, x2b); + + int w = dest->getWidth(); + int h = dest->getHeight(); + + if (x1b < 0 && x2b < 0) return; + if (x1a >= w && x2a >= w) return; + + if (x1a <= 0 && x2a <= 0) x1a = x2a = 0; + if (x1b >= w-1 && x2b >= w-1) x1b = x2b = w-1; + + if (y2 < 0 || y1 >= h) return; + + + int aw = (int)(alpha*256.0f); + + double idy = y2==y1 ? 0.0 : (65536.0/(y2-y1)); + + + const double maxv=(double)(1<<29); + double tmp = (x2a-x1a)*idy; + if (tmp > maxv) tmp=maxv; + else if (tmp < -maxv) tmp=-maxv; + int dxady = (int)tmp; + + tmp = ((x2b-x1b)*idy); + if (tmp > maxv) tmp=maxv; + else if (tmp < -maxv) tmp=-maxv; + int dxbdy = (int)tmp; + + int a = 0; + int b = 0; + int astep = 1; + int bstep = 1; + if (dxady < 0) + { + dxady = -dxady; + astep = -1; + } + if (dxbdy < 0) + { + dxbdy = -dxbdy; + bstep = -1; + } + + if (y1<0) + { + a -= dxady*y1; + b -= dxbdy*y1; + y1=0; + if (a >= 65536) + { + int na = a/65536; + a %= 65536; + if (astep<0)na=-na; + x1a += na; + } + if (b >= 65536) + { + int nb = b/65536; + b %= 65536; + if (bstep<0)nb=-nb; + x1b += nb; + } + } + if (y2 > h-1) y2 = h-1; + + int wid = dest->getWidth(); + int span = dest->getRowSpan(); + LICE_pixel* px = dest->getBits()+y1*span; + int y = y2-y1 + 1; + + x1b++; // from now on draw [x1a,x1b) + + if (!dxady && !dxbdy) + { + if (x1a<0)x1a=0; + x1b = min(x1b,wid)-x1a; + px+=x1a; + if (x1b<1) return; + } + + if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==256) + { + _LICE_FillFast<_LICE_CombinePixelsClobberFAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==128) + { + color = (color>>1)&0x7f7f7f7f; + _LICE_FillFast<_LICE_CombinePixelsHalfMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==64) + { + color = (color>>2)&0x3f3f3f3f; + _LICE_FillFast<_LICE_CombinePixelsQuarterMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, color); + } + else if ((mode&LICE_BLIT_MODE_MASK) == LICE_BLIT_MODE_COPY && aw==192) + { + color = ((color>>1)&0x7f7f7f7f)+((color>>2)&0x3f3f3f3f); + _LICE_FillFast<_LICE_CombinePixelsThreeQuarterMix2FAST>::FillClippedTrapezoidFAST(wid,span,px,y, x1a, x1b, dxady, dxbdy,a,b, astep,bstep, color); + } + else + { + int cr = LICE_GETR(color), cg = LICE_GETG(color), cb = LICE_GETB(color), ca = LICE_GETA(color); +#ifdef LICE_FAVOR_SIZE_EXTREME + + LICE_COMBINEFUNC blitfunc=NULL; +#define __LICE__ACTION(comb) blitfunc=comb::doPix; +#else +#define __LICE__ACTION(COMBFUNC) _LICE_Fill::FillClippedTrapezoid(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, cr,cg,cb,ca, aw); +#endif + + __LICE_ACTION_CONSTANTALPHA(mode, aw, false); + +#ifdef LICE_FAVOR_SIZE_EXTREME + if (blitfunc) _LICE_Fill::FillClippedTrapezoid(wid,span,px,y, x1a, x1b, dxady, dxbdy, a,b, astep,bstep, cr,cg,cb,ca, aw, blitfunc); +#endif + +#undef __LICE__ACTION + } +} + + +static int _ysort(const void* a, const void* b) +{ + int* xya = (int*)a; + int* xyb = (int*)b; + if (xya[1] < xyb[1]) return -1; + if (xya[1] > xyb[1]) return 1; + if (xya[0] < xyb[0]) return -1; + if (xya[0] > xyb[0]) return 1; + return 0; +} + +#define _X(i) xy[2*(i)] +#define _Y(i) xy[2*(i)+1] + +static int FindNextEdgeVertex(int* xy, int a, int n, int dir) +{ + bool init = false; + float dxdy_best; + int i, ilo = a; + + for (i = a+1; i < n; ++i) + { + if (_Y(i) == _Y(a)) continue; + float dxdy = (float)(_X(i)-_X(a))/(float)(_Y(i)-_Y(a)); + if (!init || dxdy == dxdy_best || (dir < 0 && dxdy < dxdy_best) || (dir > 0 && dxdy > dxdy_best)) + { + init = true; + ilo = i; + dxdy_best = dxdy; + } + } + return ilo; +} + +void LICE_FillConvexPolygon(LICE_IBitmap* dest, const int* x, const int* y, int npoints, LICE_pixel color, float alpha, int mode) +{ + if (!dest) return; + if (npoints < 3) return; + + int* xy = 0; + int xyt[1024]; // use stack space if small + bool usestack = (npoints <= sizeof(xyt)/sizeof(int)/2); + if (usestack) xy = xyt; + else xy = (int*)malloc(npoints*sizeof(int)*2); + + int i; + { + int min_x=dest->getWidth(),max_x=0; + for (i = 0; i < npoints; ++i) + { + int tx = x[i]; + if (tx < min_x) min_x=tx; + if (tx > max_x) max_x=tx; + _X(i) = tx; + _Y(i) = y[i]; + if (dest->isFlipped()) _Y(i) = dest->getHeight()-_Y(i)-1; + } + qsort(xy, npoints, 2*sizeof(int), _ysort); // sorts by y, at same y sorts by x + + + int ty=_Y(0); + if (ty == _Y(npoints-1)) + { + // special case 1px high polygon + if (ty >= 0 && ty < dest->getHeight() && min_x <= max_x) + { + LICE_FillTrapezoid(dest,min_x,max_x,ty,min_x,max_x,ty,color,alpha,mode); + } + if (!usestack) free(xy); + + return; + } + } + + int a1, b1; // index of previous vertex L and R + int a2, b2; // index of next vertex L and R + int y1; // top and bottom of current trapezoid + + a1 = b1 = 0; + y1 = _Y(0); + + for (i = 1; i < npoints && _Y(i) == y1; ++i) + { + if (_X(i) == _X(0)) a1 = i; + b1 = i; + } + + a2 = FindNextEdgeVertex(xy, a1, npoints, -1); + b2 = FindNextEdgeVertex(xy, b1, npoints, 1); + + while (a1 != a2 || b1 != b2) + { + int y_a2 = _Y(a2); + int y_b2 = _Y(b2); + + int y2 = min(y_a2, y_b2); + int x1a = FindXOnSegment(_X(a1), _Y(a1), _X(a2), y_a2, y1); + int x1b = FindXOnSegment(_X(b1), _Y(b1), _X(b2), y_b2, y1); + int x2a = FindXOnSegment(_X(a1), _Y(a1), _X(a2), y_a2, y2); + int x2b = FindXOnSegment(_X(b1), _Y(b1), _X(b2), y_b2, y2); + + LICE_FillTrapezoid(dest, x1a, x1b, y1, x2a, x2b, y2, color, alpha, mode); + + bool dir = y1<=y2; // should always be true + + y1 = y2; + if (y_a2 == y1) + { + a1 = a2; + a2 = FindNextEdgeVertex(xy, a2, npoints, -1); + } + if (y_b2 == y1) + { + b1 = b2; + b2 = FindNextEdgeVertex(xy, b2, npoints, 1); + } + + if (dir) y1++; + else y1--; + } + + if (!usestack) free(xy); +} + +#undef _X +#undef _Y + + +void LICE_FillTriangle(LICE_IBitmap *dest, int x1, int y1, int x2, int y2, int x3, int y3, LICE_pixel color, float alpha, int mode) +{ + int x[3] = { x1, x2, x3 }; + int y[3] = { y1, y2, y3 }; + LICE_FillConvexPolygon(dest, x, y, 3, color, alpha, mode); +} diff --git a/WDL/lice/lice_lvg.cpp b/WDL/lice/lice_lvg.cpp new file mode 100644 index 00000000..08a0c453 --- /dev/null +++ b/WDL/lice/lice_lvg.cpp @@ -0,0 +1,620 @@ +#include "lice.h" +#include +#include +#include "../projectcontext.h" +#include "../lineparse.h" +#include "../ptrlist.h" +#include "../assocarray.h" + +#define PI 3.1415926535897932384626433832795 + +static inline int chartohex(char c) +{ + if (c >= '0' && c<='9') return c-'0'; + else if (c>='A' && c<='F') return 10 + c - 'A'; + else if (c>='a' && c<='f') return 10 + c - 'a'; + return -1; +} +static int __boolval(const char *p, int defval) +{ + if (!stricmp(p,"yes") || + !stricmp(p,"true") || + !stricmp(p,"on") || + atoi(p)>0) return 1; + if (!stricmp(p,"no") || + !stricmp(p,"false") || + !stricmp(p,"off") || + !stricmp(p,"0")) return 0; + return defval; +} + +static LICE_pixel __colorval(const char *p, LICE_pixel def) +{ + int lp = strlen(p); + if (lp == 3) + { + int r = chartohex(p[0]); + int g = chartohex(p[1]); + int b = chartohex(p[2]); + if (r>=0&&g>=0&&b>=0) + def = LICE_RGBA(r+(r<<4),g+(g<<4),b+(b<<4),255); + } + else if (lp == 6||lp==8) + { + int r = chartohex(p[0]), r2 = chartohex(p[1]); + int g = chartohex(p[2]), g2 = chartohex(p[3]); + int b = chartohex(p[4]), b2 = chartohex(p[5]); + int a = 0xf, a2=0xf; + if (lp==8) { a=chartohex(p[6]); a2=chartohex(p[7]); } + if (r>=0&&g>=0&&b>=0&&r2>=0&&g2>=0&&b2>=0&&a>=0&&a2>=0) + def = LICE_RGBA((r<<4)+r2,(g<<4)+g2,(b<<4)+b2,(a<<4)+a2); + } + return def; +} + +class lvgRenderState +{ +public: + lvgRenderState() + { + m_color=LICE_RGBA(255,255,255,255); + m_alpha=1.0f; + m_blend = LICE_BLIT_MODE_COPY; + m_aa = false; + } + ~lvgRenderState() { } + + LICE_pixel m_color; + float m_alpha; + int m_blend; + bool m_aa; + + WDL_TypedBuf m_aa_stack; + WDL_TypedBuf m_alpha_stack; + WDL_TypedBuf m_color_stack; + WDL_TypedBuf m_blend_stack; + +///////// + + void parsealpha(const char *p) + { + int idx=0; + if (*p == '-') idx++; + if (p[idx] == '.' || (p[idx] >= '0' && p[idx] <= '9')) + m_alpha = (float)atof(p); + } + + void parseaa(const char *p) + { + int a = __boolval(p,-1); + if (a>=0) m_aa = !!a; + } + + void parseblend(const char *p) + { + if (!stricmp(p,"copy")) m_blend = LICE_BLIT_MODE_COPY; + else if (!stricmp(p,"add")) m_blend = LICE_BLIT_MODE_ADD; + else if (!stricmp(p,"dodge")) m_blend = LICE_BLIT_MODE_DODGE; + else if (!stricmp(p,"mul")||!stricmp(p,"multiply")) m_blend = LICE_BLIT_MODE_MUL; + else if (!stricmp(p,"overlay")) m_blend = LICE_BLIT_MODE_MUL; + else if (!stricmp(p,"hsvadj")) m_blend = LICE_BLIT_MODE_HSVADJ; + } + + void parsecolor(const char *p) + { + m_color = __colorval(p,m_color); + } + +#define DEF_PUSHPOP(name,defpopval) \ + void push##name() { int sz=m_##name##_stack.GetSize(); m_##name##_stack.Resize(sz+1,false)[sz] = m_##name; } \ + void pop##name() { int sz = m_##name##_stack.GetSize()-1; m_##name = sz>=0 ? m_##name##_stack.Get()[sz] : defpopval; m_##name##_stack.Resize(sz,false); } + DEF_PUSHPOP(color,LICE_RGBA(0,0,0,255)) + DEF_PUSHPOP(alpha,1.0f) + DEF_PUSHPOP(aa,false) + DEF_PUSHPOP(blend,LICE_BLIT_MODE_COPY) +#undef DEF_PUSHPOP + + bool processAttributeLine(LineParser *lp) + { + int i,numtok=lp->getnumtokens(); + switch (lp->gettoken_enum(0,"color\0" + "alpha\0" + "aa\0" + "blend\0" + "\0")) + { +#define PROCTYPE(v,name) \ + case v: for (i=1;igettoken_str(i); \ + if (!stricmp(p,"push")) push##name(); \ + else if (!stricmp(p,"pop")) pop##name(); \ + else parse##name(p); \ + } \ + return true; + + PROCTYPE(0,color) + PROCTYPE(1,alpha) + PROCTYPE(2,aa) + PROCTYPE(3,blend) +#undef PROCTYPE + + } + return false; + } + + +}; + +class lvgImageCtx +{ +public: + lvgImageCtx(lvgImageCtx *par) : m_images(true,deleteThis) + { + m_in_render=false; + m_par=par; + m_cachedImage=0; + m_base_w=0; + m_base_h=0; + } + ~lvgImageCtx() + { + delete m_cachedImage; + m_lines.Empty(true,free); + } + + WDL_PtrList m_lines; + LICE_IBitmap *m_cachedImage; + + lvgImageCtx *m_par; + WDL_StringKeyedArray m_images; + + int m_base_w,m_base_h; + bool m_in_render; + + void render(lvgRenderState *rstate, int wantw, int wanth); + +private: + static void deleteThis(lvgImageCtx *t) { delete t; } + + double parsecoord(const char *p, double scale, bool round) + { + if (!*p) return 0; + if (p[0] == 'a' && p[1]) return atoi(p+1); + if (p[0] == 'w') + { + scale = m_cachedImage ? m_cachedImage->getWidth() : 0.0; + p++; + } + else if (p[0] == 'h') + { + scale = m_cachedImage ? m_cachedImage->getHeight() : 0.0; + p++; + } + return atof(p) * scale + (round ? 0.5 : 0.0); + } + void processLvgLine(LineParser *lp, lvgRenderState *state, LICE_IBitmap *bm, double xscale, double yscale); + +}; + +#define DECL_OPT(type, cfunc) \ + static type getoption_##type(LineParser *lp, int startidx, const char *name, type def) { \ + int namelen = strlen(name); \ + for(;startidxgetnumtokens();startidx++) { \ + const char *p=lp->gettoken_str(startidx); \ + if (!strnicmp(name,p,namelen) && p[namelen]=='=') return cfunc(p+namelen+1,def); \ + } \ + return def; \ + } + +static int __intval(const char *p, int def) { return atoi(p); } +static double __dblval(const char *p, double def) { return atof(p); } + +DECL_OPT(bool,!!__boolval) +DECL_OPT(int,__intval) +DECL_OPT(double,__dblval) +DECL_OPT(LICE_pixel,__colorval) + +#undef DECL_OPT + +void lvgImageCtx::processLvgLine(LineParser *lp, lvgRenderState *state, LICE_IBitmap *bm, double xscale, double yscale) +{ + if (state->processAttributeLine(lp)) return; + + int numtok = lp->getnumtokens(); + const char *tok = lp->gettoken_str(0); + if (!stricmp(tok,"line")) + { + int i; + float lx,ly; + for (i = 1; i < numtok-1; i+= 2) + { + const char *p=lp->gettoken_str(i); + if (strstr(p,"=")) break; + float x=(float)parsecoord(p,xscale,false); + p=lp->gettoken_str(i+1); + if (strstr(p,"=")) break; + float y=(float)parsecoord(p,yscale,false); + + if (i!=1) LICE_FLine(bm,lx,ly,x,y,state->m_color,state->m_alpha,state->m_blend,state->m_aa); + + lx=x; + ly=y; + } + } + else if (!stricmp(tok,"circle")) + { + if (numtok>=4) + { + float x=(float)parsecoord(lp->gettoken_str(1),xscale,false); + float y=(float)parsecoord(lp->gettoken_str(2),yscale,false); + float r=(float)(atof(lp->gettoken_str(3))*min(xscale,yscale)); + if (getoption_bool(lp,1,"fill",false)) + { + LICE_FillCircle(bm,x,y,r,state->m_color,state->m_alpha,state->m_blend,state->m_aa); + } + else + LICE_Circle(bm,x,y,r,state->m_color,state->m_alpha,state->m_blend,state->m_aa); + } + } + else if (!stricmp(tok,"arc")) + { + if (numtok>=6) + { + float x=(float)parsecoord(lp->gettoken_str(1),xscale,false); + float y=(float)parsecoord(lp->gettoken_str(2),yscale,false); + float r=(float)(atof(lp->gettoken_str(3))*min(xscale,yscale)); + float a1=(float)(atof(lp->gettoken_str(4))*PI/180.0); + float a2=(float)(atof(lp->gettoken_str(5))*PI/180.0); + LICE_Arc(bm,x,y,r,a1,a2,state->m_color,state->m_alpha,state->m_blend,state->m_aa); + } + } + else if (!stricmp(tok,"fill")) + { + if (numtok>=3) // fill x y [cmask=xxxxxx kmask=xxxxxxx] + { + LICE_pixel cmask = getoption_LICE_pixel(lp,1,"cmask",LICE_RGBA(255,255,255,0)); + LICE_pixel kmask = getoption_LICE_pixel(lp,1,"kmask",LICE_RGBA(0,0,0,0)); + int x = (int)parsecoord(lp->gettoken_str(1),xscale,true); + int y = (int)parsecoord(lp->gettoken_str(2),yscale,true); + + LICE_SimpleFill(bm,x,y,state->m_color,cmask,kmask); + } + } + else if (!stricmp(tok,"rect")) + { + if (numtok>=5) // rect x y w h [dcdx=xxxxxxxx dcdy=xxxxxxxxx dcdxscale=1.0 dcdyscale=1.0] + { + LICE_pixel dcdx = getoption_LICE_pixel(lp,1,"dcdx",LICE_RGBA(0x80,0x80,0x80,0x80)); + LICE_pixel dcdy = getoption_LICE_pixel(lp,1,"dcdy",LICE_RGBA(0x80,0x80,0x80,0x80)); + double dcdxsc = getoption_double(lp,1,"dcdxscale",1.0); + double dcdysc = getoption_double(lp,1,"dcdyscale",1.0); + + // todo: any options? + int x = (int)parsecoord(lp->gettoken_str(1),xscale,true); + int y = (int)parsecoord(lp->gettoken_str(2),yscale,true); + int w = (int)parsecoord(lp->gettoken_str(3),xscale,true); + int h = (int)parsecoord(lp->gettoken_str(4),yscale,true); + if (w>0 && h>0) + { + if (dcdx!=LICE_RGBA(0x80,0x80,0x80,0x80) || + dcdy!=LICE_RGBA(0x80,0x80,0x80,0x80)) + { + LICE_pixel sc = state->m_color; + dcdxsc /= w*128.0; + dcdysc /= h*128.0; + LICE_GradRect(bm,x,y,w,h, + (float)(LICE_GETR(sc)/255.0), + (float)(LICE_GETG(sc)/255.0), + (float)(LICE_GETB(sc)/255.0), + (float)(LICE_GETA(sc)/255.0*state->m_alpha), + (float)(((int)LICE_GETR(dcdx)-0x80)*dcdxsc), + (float)(((int)LICE_GETG(dcdx)-0x80)*dcdxsc), + (float)(((int)LICE_GETB(dcdx)-0x80)*dcdxsc), + (float)(((int)LICE_GETA(dcdx)-0x80)*dcdxsc), + (float)(((int)LICE_GETR(dcdy)-0x80)*dcdysc), + (float)(((int)LICE_GETG(dcdy)-0x80)*dcdysc), + (float)(((int)LICE_GETB(dcdy)-0x80)*dcdysc), + (float)(((int)LICE_GETA(dcdy)-0x80)*dcdysc), + state->m_blend); + } + else + LICE_FillRect(bm,x,y,w,h,state->m_color,state->m_alpha,state->m_blend); + } + } + } + else if (!stricmp(tok,"rerender")) + { + if (numtok>=2) + { + int forcew=getoption_int(lp,1,"w",0),forceh=getoption_int(lp,1,"h",0); + bool useState=getoption_bool(lp,1,"usestate",false); + + lvgImageCtx *scan = this; + while (scan) + { + lvgImageCtx *p = scan->m_images.Get(lp->gettoken_str(1)); + if (p) + { + if (!p->m_in_render) + { + p->m_in_render=true; + p->render(useState ? state : NULL,forcew,forceh); + p->m_in_render=false; + } + break; + } + scan=scan->m_par; + } + } + } + else if (!stricmp(tok,"blit")) + { + if (numtok>=3) // blit image x y [options] + { + LICE_IBitmap *src=NULL; + lvgImageCtx *scan = this; + const char *rd = lp->gettoken_str(1); + + while (!strnicmp(rd,"parent:",7)) { scan = scan ? scan->m_par : NULL; rd += 7; } + + if (!stricmp(rd,"parent")) + { + if (scan) scan=scan->m_par; + if (scan) src=scan->m_cachedImage; + } + else if (!stricmp(rd,"self")) + { + if (scan) src=scan->m_cachedImage; + } + else while (scan&&!src) + { + lvgImageCtx *p = scan->m_images.Get(rd); + if (p) + { + if (!p->m_cachedImage && !p->m_in_render) + { + p->m_in_render=true; + p->render(NULL,0,0); + p->m_in_render=false; + } + src = p->m_cachedImage; + break; + } + scan=scan->m_par; + } + if (src) + { + int x = (int)parsecoord(lp->gettoken_str(2),xscale,true); + int y = (int)parsecoord(lp->gettoken_str(3),yscale,true); + + // these will be options filter= srcalpha= w= h= scale= + bool filter=getoption_bool(lp,1,"filter",true); + bool usesrcalpha = getoption_bool(lp,1,"srcalpha",true); + int w = getoption_int(lp,1,"w",src->getWidth()); + int h = getoption_int(lp,1,"h",src->getHeight()); + double sc = getoption_double(lp,1,"scale",1.0f); + if (fabs(sc-1.0)>0.0000000001) + { + w = (int)(w*sc+0.5); + h = (int)(h*sc+0.5); + } +// double ang = getoption_double(lp,1,"rotate",0.0) * PI / 180.0; + float sx=(float)getoption_double(lp,1,"srcx",0.0); + float sy=(float)getoption_double(lp,1,"srcy",0.0); + float sw=(float)getoption_double(lp,1,"srcw",src->getWidth()); + float sh=(float)getoption_double(lp,1,"srch",src->getHeight()); +// if (fabs(ang)>0.0001) LICE_RotatedBlit(bm,src,x,y,w,h,sx,sy,sw,sh,ang,true,state->m_alpha,state->m_blend,0,0); + //else + LICE_ScaledBlit(bm,src,x,y,w,h,sx,sy,sw,sh, + state->m_alpha,state->m_blend|(filter ? LICE_BLIT_FILTER_BILINEAR : 0)|(usesrcalpha ? LICE_BLIT_USE_ALPHA : 0)); + } + } + } +} + +void lvgImageCtx::render(lvgRenderState *rstate, int wantw, int wanth) +{ + if (wantw<1) wantw = m_base_w; + if (wanth<1) wanth = m_base_h; + + if (wantw<1||wanth<1) + { + if (m_cachedImage) m_cachedImage->resize(0,0); + return; + } + + if (!m_cachedImage) m_cachedImage = new LICE_MemBitmap(wantw,wanth); + else m_cachedImage->resize(wantw,wanth); + + LICE_Clear(m_cachedImage,LICE_RGBA(0,0,0,0)); + + lvgRenderState rs; + if (rstate) rs = *rstate; + + double xscale = wantw / max(m_base_w,1); + double yscale = wanth / max(m_base_h,1); + int x; + bool comment_state=false; + LineParser lp(comment_state); + for (x=0;x0) + processLvgLine(&lp,&rs,m_cachedImage,xscale,yscale); + } +} + +void *LICE_GetSubLVG(void *lvg, const char *subname) +{ + if (!lvg||!subname||!*subname) return NULL; + lvgImageCtx *t = (lvgImageCtx *)lvg; + return t->m_images.Get(subname); +} + +LICE_IBitmap *LICE_RenderLVG(void *lvg, int reqw, int reqh, LICE_IBitmap *bmOut) +{ + lvgImageCtx *t = (lvgImageCtx *)lvg; + if (!t || !t->m_lines.GetSize() || t->m_in_render) return NULL; + + if (bmOut) + { + delete t->m_cachedImage; + t->m_cachedImage = bmOut; + } + else if (!t->m_cachedImage) t->m_cachedImage = new LICE_MemBitmap; + + t->m_in_render=true; + t->render(NULL,reqw,reqh); + t->m_in_render=false; + + LICE_IBitmap *ret = t->m_cachedImage; + + t->m_cachedImage=NULL; + + return ret; +} + +void LICE_DestroyLVG(void *lvg) +{ + lvgImageCtx *t = (lvgImageCtx *)lvg; + if (t && !t->m_par) delete t; +} + +class lvgRdContext : public ProjectStateContext +{ +public: + lvgRdContext(FILE *fp) { m_fp=fp; } + virtual ~lvgRdContext() { } + + virtual void AddLine(const char *fmt, ...) {}; + virtual int GetLine(char *buf, int buflen) // returns -1 on eof + { + if (!m_fp) return -1; + for (;;) + { + buf[0]=0; + fgets(buf,buflen,m_fp); + if (!buf[0]) return -1; + + char *p=buf; + while (*p) p++; + while (p>buf && (p[-1] == '\r' || p[-1]=='\n')) p--; + *p=0; + if (*buf) return 0; + } + } + + virtual WDL_INT64 GetOutputSize() { return 0; } + virtual int GetTempFlag() { return 0; } + virtual void SetTempFlag(int flag) {} + + FILE *m_fp; +}; + +void *LICE_LoadLVGFromContext(ProjectStateContext *ctx, const char *nameInfo, int defw, int defh) +{ + if (!ctx) return NULL; + + bool err=false; + int ignoreBlockCnt=0; + + lvgImageCtx *retimg = new lvgImageCtx(NULL); + lvgImageCtx *curimg = NULL; + + if (nameInfo) + { + curimg = retimg; + curimg->m_base_w = defw; + curimg->m_base_h = defh; + } + + while (!err) + { + char line[4096]; + line[0]=0; + if (ctx->GetLine(line,sizeof(line))) break; + + char *p=line; + while (*p == ' ' || *p == '\t') p++; + if (!*p) continue; + + if (ignoreBlockCnt>0) + { + if (*p == '<') ignoreBlockCnt++; + else if (*p == '>') ignoreBlockCnt--; + } + else + { + if (*p == '<') + { + bool comment_state=false; + LineParser lp(comment_state); + if (!lp.parse(p)&&lp.getnumtokens()>=2 && !strcmp(lp.gettoken_str(0),"m_images.Insert(lp.gettoken_str(1),p); + curimg = p; + } + curimg->m_base_w = lp.gettoken_int(2); + curimg->m_base_h = lp.gettoken_int(3); + } + else ignoreBlockCnt++; + } + else if (curimg) + { + if (*p == '>') + { + curimg = curimg->m_par; + if (!curimg) break; // success! + } + else + { + curimg->m_lines.Add(strdup(p)); + } + } + + if (!curimg) err=true; // 24-bit RGB) + +struct ONode +{ + WDL_INT64 colorcount; // number of color instances at or below this node + WDL_INT64 sumrgb[3]; + int childflag; // 0=leaf, >0=index of single child, <0=branch + int leafidx; // populated at the end + ONode* next; // for OTree::branches + ONode* children[8]; +}; + +struct OTree +{ + int maxcolors; + int leafcount; + ONode* trunk; + ONode* branches[OCTREE_DEPTH]; // linked lists of branches for each level of the tree + LICE_pixel* palette; // populated at the end +}; + + + +int LICE_BuildPalette(LICE_IBitmap* bmp, LICE_pixel* palette, int maxcolors) +{ + void* tree = LICE_CreateOctree(maxcolors); + LICE_BuildOctree(tree, bmp); + int sz = LICE_ExtractOctreePalette(tree, palette); + LICE_DestroyOctree(tree); + return sz; +} + + +static void AddColorToTree(OTree*, unsigned char rgb[]); +static int FindColorInTree(OTree*, unsigned char rgb[]); +static int PruneTree(OTree*); +static void DeleteNode(OTree*, ONode*); +static int CollectLeaves(OTree*); +static int CollectNodeLeaves(ONode* node, LICE_pixel* palette, int colorcount); + + +void* LICE_CreateOctree(int maxcolors) +{ + OTree* tree = new OTree; + memset(tree, 0, sizeof(OTree)); + tree->maxcolors = maxcolors; + tree->trunk = new ONode; + memset(tree->trunk, 0, sizeof(ONode)); + return tree; +} + + +void LICE_DestroyOctree(void* octree) +{ + OTree* tree = (OTree*)octree; + DeleteNode(tree, tree->trunk); + free(tree->palette); + delete tree; +} + + +int LICE_BuildOctree(void* octree, LICE_IBitmap* bmp) +{ + OTree* tree = (OTree*)octree; + if (!tree) return 0; + + if (tree->palette) + { + free(tree->palette); + tree->palette=0; + } + + int x, y; + for (y = 0; y < bmp->getHeight(); ++y) + { + LICE_pixel* px = bmp->getBits()+y*bmp->getRowSpan(); + for (x = 0; x < bmp->getWidth(); ++x) + { + unsigned char rgb[3] = { LICE_GETR(px[x]), LICE_GETG(px[x]), LICE_GETB(px[x]) }; + AddColorToTree(tree, rgb); + if (tree->leafcount > tree->maxcolors) PruneTree(tree); + } + } + + return tree->leafcount; +} + + +int LICE_FindInOctree(void* octree, LICE_pixel color) +{ + OTree* tree = (OTree*)octree; + if (!tree) return 0; + + if (!tree->palette) CollectLeaves(tree); + + unsigned char rgb[3] = { LICE_GETR(color), LICE_GETG(color), LICE_GETB(color) }; + return FindColorInTree(tree, rgb); +} + + +int LICE_ExtractOctreePalette(void* octree, LICE_pixel* palette) +{ + OTree* tree = (OTree*)octree; + if (!tree || !palette) return 0; + + if (!tree->palette) CollectLeaves(tree); + + memcpy(palette, tree->palette, tree->maxcolors*sizeof(LICE_pixel)); + return tree->leafcount; +} + + + +void LICE_TestPalette(LICE_IBitmap* bmp, LICE_pixel* palette, int numcolors) +{ + int x, y; + for (y = 0; y < bmp->getHeight(); ++y) + { + LICE_pixel* px = bmp->getBits()+y*bmp->getRowSpan(); + for (x = 0; x < bmp->getWidth(); ++x) + { + unsigned char rgb[3] = { LICE_GETR(px[x]), LICE_GETG(px[x]), LICE_GETB(px[x]) }; + + int minerr; + int bestcol=-1; + int i; + for (i = 0; i < numcolors; ++i) + { + LICE_pixel palcol = palette[i]; + int rerr[3] = { rgb[0]-LICE_GETR(palcol), rgb[1]-LICE_GETG(palcol), rgb[2]-LICE_GETB(palcol) }; + int err = rerr[0]*rerr[0]+rerr[1]*rerr[1]+rerr[2]*rerr[2]; + if (bestcol < 0 || err < minerr) + { + bestcol=i; + minerr=err; + } + } + px[x] = palette[bestcol]; + } + } +} + + +void AddColorToTree(OTree* tree, unsigned char rgb[3]) +{ + ONode* p = tree->trunk; + p->colorcount++; + + int i; + for (i = OCTREE_DEPTH-1; i >= 0; --i) + { + int j = i+8-OCTREE_DEPTH; + unsigned char idx = (((rgb[0]>>(j-2))&4))|(((rgb[1]>>(j-1))&2))|((rgb[2]>>j)&1); + + ONode* np = p->children[idx]; + bool isleaf = false; + + if (np) + { + isleaf = !np->childflag; + } + else // add node + { + if (!p->childflag) // first time down this path + { + p->childflag=idx+1; + } + else if (p->childflag > 0) // creating a new branch + { + p->childflag = -1; + p->next = tree->branches[i]; + tree->branches[i] = p; + } + // else multiple branch, which we don't care about + + np = p->children[idx] = new ONode; + memset(np, 0, sizeof(ONode)); + } + + np->sumrgb[0] += rgb[0]; + np->sumrgb[1] += rgb[1]; + np->sumrgb[2] += rgb[2]; + np->colorcount++; + + if (isleaf) return; + + p=np; // continue downward + } + + // p is a new leaf at the bottom + tree->leafcount++; +} + +int FindColorInTree(OTree* tree, unsigned char rgb[3]) +{ + ONode* p = tree->trunk; + + int i; + for (i = OCTREE_DEPTH-1; i >= 0; --i) + { + if (!p->childflag) break; + + int j = i+8-OCTREE_DEPTH; + unsigned char idx = (((rgb[0]>>(j-2))&4))|(((rgb[1]>>(j-1))&2))|((rgb[2]>>j)&1); + + ONode* np = p->children[idx]; + if (!np) break; + + p = np; + } + + return p->leafidx; +} + + +int PruneTree(OTree* tree) +{ + ONode* branch=0; + int i; + for (i = 0; i < OCTREE_DEPTH; ++i) // prune at the furthest level from the trunk + { + branch = tree->branches[i]; + if (branch) + { + tree->branches[i] = branch->next; + branch->next=0; + break; + } + } + + if (branch) + { + int i; + for (i = 0; i < 8; ++i) + { + if (branch->children[i]) + { + DeleteNode(tree, branch->children[i]); + branch->children[i]=0; + } + } + branch->childflag=0; // now it's a leaf + tree->leafcount++; + } + + return tree->leafcount; +} + +int CollectLeaves(OTree* tree) +{ + if (tree->palette) free(tree->palette); + tree->palette = (LICE_pixel*)malloc(tree->maxcolors*sizeof(LICE_pixel)); + + int sz = CollectNodeLeaves(tree->trunk, tree->palette, 0); + memset(tree->palette+sz, 0, (tree->maxcolors-sz)*sizeof(LICE_pixel)); + + return sz; +} + +int CollectNodeLeaves(ONode* p, LICE_pixel* palette, int colorcount) +{ + if (!p->childflag) + { + p->leafidx = colorcount; + int r = (int)((double)p->sumrgb[0]/(double)p->colorcount); + int g = (int)((double)p->sumrgb[1]/(double)p->colorcount); + int b = (int)((double)p->sumrgb[2]/(double)p->colorcount); + palette[colorcount++] = LICE_RGBA(r, g, b, 255); + } + else + { + if (p->childflag > 0) + { + colorcount = CollectNodeLeaves(p->children[p->childflag-1], palette, colorcount); + } + else + { + int i; + for (i = 0; i < 8; ++i) + { + if (p->children[i]) + { + colorcount = CollectNodeLeaves(p->children[i], palette, colorcount); + } + } + } + // this is a branch or passthrough node, record the index + // of any downtree leaf here so that we can return it for + // color lookups that want to diverge off this node + p->leafidx = colorcount-1; + } + + // colorcount should == leafcount + return colorcount; +} + + +void DeleteNode(OTree* tree, ONode* p) +{ + if (!p->childflag) + { + tree->leafcount--; + } + else if (p->childflag > 0) + { + DeleteNode(tree, p->children[p->childflag-1]); + } + else + { + int i; + for (i = 0; i < 8; ++i) + { + if (p->children[i]) + { + DeleteNode(tree, p->children[i]); + } + } + } + + delete p; +} + diff --git a/WDL/lice/lice_pcx.cpp b/WDL/lice/lice_pcx.cpp new file mode 100644 index 00000000..f14b4a66 --- /dev/null +++ b/WDL/lice/lice_pcx.cpp @@ -0,0 +1,108 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_pcx.cpp (PCX loading for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" + + +#include + +// note: you'd never really want to use PCX files, but in case you do... + +LICE_IBitmap *LICE_LoadPCX(const char *filename, LICE_IBitmap *_bmp) +{ + FILE *fp = fopen(filename,"rb"); + if(!fp) return 0; + + fgetc(fp); + if (fgetc(fp) != 5) { fclose(fp); return NULL; } + if (fgetc(fp) != 1) { fclose(fp); return NULL; } + if (fgetc(fp) != 8) { fclose(fp); return NULL; } + + int sx = fgetc(fp); sx += fgetc(fp)<<8; + int sy = fgetc(fp); sy += fgetc(fp)<<8; + int ex = fgetc(fp); ex += fgetc(fp)<<8; + int ey = fgetc(fp); ey += fgetc(fp)<<8; + + + unsigned char pal[768]; + fseek(fp,-769,SEEK_END); + if (fgetc(fp) != 12) { fclose(fp); return NULL; } + fread(pal,1,768,fp); + if (feof(fp)) { fclose(fp); return NULL; } + + + LICE_IBitmap *usebmp = NULL; + if (_bmp) (usebmp=_bmp)->resize(ex-sx+1,ey-sy+1); + else usebmp = new LICE_MemBitmap(ex-sx+1,ey-sy+1); + + fseek(fp,128,SEEK_SET); + + LICE_Clear(usebmp,0); + int y = usebmp->getHeight(); + int w = usebmp->getWidth(); + int rowspan = usebmp->getRowSpan(); + LICE_pixel *pout = usebmp->getBits(); + if (usebmp->isFlipped()) + { + pout += rowspan*(y-1); + rowspan=-rowspan; + } + while (y--) + { + int xpos = 0; + while (xpos < w) + { + int c = fgetc(fp); + if (c&~255) break; + if ((c & 192) == 192) + { + int oc = (fgetc(fp))&255; + LICE_pixel t=LICE_RGBA(pal[oc*3],pal[oc*3+1],pal[oc*3+2],255); + + c&=63; + while (c-- && xposfilename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".pcx")) return 0; + } + return LICE_LoadPCX(filename,bmpbase); + } + static const char *get_extlist() + { + return "PCX files (*.PCX)\0*.PCX\0"; + } + +}; + +LICE_PCXLoader LICE_pcxldr; \ No newline at end of file diff --git a/WDL/lice/lice_png.cpp b/WDL/lice/lice_png.cpp new file mode 100644 index 00000000..16916531 --- /dev/null +++ b/WDL/lice/lice_png.cpp @@ -0,0 +1,364 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_png.cpp (PNG loading for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" + + +#include +#include "../libpng/png.h" + +#ifdef __APPLE__ +#include // for loading images from embedded resource +#endif + + +LICE_IBitmap *LICE_LoadPNG(const char *filename, LICE_IBitmap *bmp) +{ + FILE *fp = NULL; +#ifdef _WIN32 + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + fp = _wfopen(wf,L"rb"); + } +#endif + + if (!fp) fp = fopen(filename,"rb"); + if(!fp) return 0; + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) + { + fclose(fp); + return 0; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + fclose(fp); + return 0; + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fclose(fp); + return 0; + } + + png_init_io(png_ptr, fp); + + png_read_info(png_ptr, info_ptr); + + unsigned int width, height; + int bit_depth, color_type, interlace_type, compression_type, filter_method; + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_method); + + //convert whatever it is to RGBA + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + { + png_set_tRNS_to_alpha(png_ptr); + color_type |= PNG_COLOR_MASK_ALPHA; + } + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + + if (bit_depth < 8) + png_set_packing(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_swap_alpha(png_ptr); + else + png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); + + //get the bits + if (bmp) + { + bmp->resize(width,height); + if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(fp); + return 0; + } + } + else bmp=new LICE_MemBitmap(width,height); + + unsigned char **row_pointers=(unsigned char **)malloc(height*sizeof(unsigned char *));; + LICE_pixel *bmpptr = bmp->getBits(); + int dbmpptr=bmp->getRowSpan(); + if (bmp->isFlipped()) + { + bmpptr += dbmpptr*(bmp->getHeight()-1); + dbmpptr=-dbmpptr; + } + unsigned int i; + for(i=0;i0) + { + unsigned char a = bmpptr[0]; + unsigned char r = bmpptr[1]; + unsigned char g = bmpptr[2]; + unsigned char b = bmpptr[3]; + ((LICE_pixel*)bmpptr)[0] = LICE_RGBA(r,g,b,a); + bmpptr+=4; + } + } + #endif + free(row_pointers); + + return bmp; +} + +typedef struct +{ + unsigned char *data; + int len; +} pngReadStruct; + +static void staticPngReadFunc(png_structp png_ptr, png_bytep data, png_size_t length) +{ + pngReadStruct *readStruct = (pngReadStruct *)png_get_io_ptr(png_ptr); + memset(data, 0, length); + + int l = min((int)length, readStruct->len); + memcpy(data, readStruct->data, l); + readStruct->data += l; + readStruct->len -= l; +} + +#ifndef _WIN32 +LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +{ + char buf[2048]; + buf[0]=0; + if (strlen(name)>400) return NULL; // max name for this is 400 chars + +#ifdef __APPLE__ + CFBundleRef bund = CFBundleGetMainBundle(); + if (bund) + { + CFURLRef url=CFBundleCopyBundleURL(bund); + if (url) + { + CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf)-512); + CFRelease(url); + } + } + if (!buf[0]) return 0; + strcat(buf,"/Contents/Resources/"); +#else + char tmp[64]; + sprintf(tmp,"/proc/%d/exe",getpid()); + int sz = readlink(tmp, buf, sizeof(buf)-512); + if (sz<0) sz=0; + else if (sz >= sizeof(buf)-512) sz = sizeof(buf)-512-1; + buf[sz]=0; + char *p = buf; + while (*p) p++; + while (p > buf && *p != '/') p--; + *p=0; + strcat(buf,"/Resources/"); +#endif // !__APPLE__ + + strcat(buf,name); + return LICE_LoadPNG(buf,bmp); +} +#endif + +LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitmap *bmp) +{ + if (buflen<8) return NULL; + unsigned char *data = (unsigned char *)(void*)data_in; + if(png_sig_cmp(data, 0, 8)) return NULL; + + pngReadStruct readStruct = {data, buflen}; + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) + { + return 0; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 0; + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return 0; + } + + png_set_read_fn(png_ptr, &readStruct, staticPngReadFunc); + + png_read_info(png_ptr, info_ptr); + + unsigned int width, height; + int bit_depth, color_type, interlace_type, compression_type, filter_method; + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_method); + + //convert whatever it is to RGBA + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + { + png_set_tRNS_to_alpha(png_ptr); + color_type |= PNG_COLOR_MASK_ALPHA; + } + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + + if (bit_depth < 8) + png_set_packing(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_swap_alpha(png_ptr); + else + png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); + + //get the bits + if (bmp) + { + bmp->resize(width,height); + if (bmp->getWidth() != (int)width || bmp->getHeight() != (int)height) + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + return 0; + } + } + else bmp=new LICE_MemBitmap(width,height); + + unsigned char **row_pointers=(unsigned char **)malloc(height*sizeof(unsigned char *));; + LICE_pixel *bmpptr = bmp->getBits(); + int dbmpptr=bmp->getRowSpan(); + unsigned int i; + for(i=0;i0) + { + unsigned char a = bmpptr[0]; + unsigned char r = bmpptr[1]; + unsigned char g = bmpptr[2]; + unsigned char b = bmpptr[3]; + ((LICE_pixel*)bmpptr)[0] = LICE_RGBA(r,g,b,a); + bmpptr+=4; + } + } + #endif + free(row_pointers); + return bmp; +} +LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) +{ +#ifdef _WIN32 + HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "PNG"); + if(!hResource) return NULL; + + DWORD imageSize = SizeofResource(hInst, hResource); + if(imageSize < 8) return NULL; + + HGLOBAL res = LoadResource(hInst, hResource); + const void* pResourceData = LockResource(res); + if(!pResourceData) return NULL; + + LICE_IBitmap * ret = LICE_LoadPNGFromMemory(pResourceData,imageSize,bmp); + + // todo : cleanup res?? + + return ret; +#else + return 0; +#endif +} + + +class LICE_PNGLoader +{ +public: + _LICE_ImageLoader_rec rec; + LICE_PNGLoader() + { + rec.loadfunc = loadfunc; + rec.get_extlist = get_extlist; + rec._next = LICE_ImageLoader_list; + LICE_ImageLoader_list = &rec; + } + + static LICE_IBitmap *loadfunc(const char *filename, bool checkFileName, LICE_IBitmap *bmpbase) + { + if (checkFileName) + { + const char *p=filename; + while (*p)p++; + while (p>filename && *p != '\\' && *p != '/' && *p != '.') p--; + if (stricmp(p,".png")) return 0; + } + return LICE_LoadPNG(filename,bmpbase); + } + static const char *get_extlist() + { + return "PNG files (*.PNG)\0*.PNG\0"; + } + +}; + +LICE_PNGLoader LICE_pngldr; diff --git a/WDL/lice/lice_png_write.cpp b/WDL/lice/lice_png_write.cpp new file mode 100644 index 00000000..bb4e2af1 --- /dev/null +++ b/WDL/lice/lice_png_write.cpp @@ -0,0 +1,131 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_png_write.cpp (PNG saving for LICE) + See lice.h for license and other information +*/ + +#include "lice.h" + + +#include +#include "../libpng/png.h" + + +bool LICE_WritePNG(const char *filename, LICE_IBitmap *bmp, bool wantalpha /*=true*/) +{ + if (!bmp || !filename) return false; + /* + ** Joshua Teitelbaum 1/1/2008 + ** Gifted to cockos for toe nail clippings. + ** + ** JF> tweaked some + */ + png_structp png_ptr=NULL; + png_infop info_ptr=NULL; + unsigned char *rowbuf=NULL; + + FILE *fp=NULL; +#ifdef _WIN32 + if (GetVersion()<0x80000000) + { + WCHAR wf[2048]; + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048)) + fp = _wfopen(wf,L"wb"); + } +#endif + if (!fp) fp = fopen(filename,"wb"); + + if (fp == NULL) return false; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL); + + if (png_ptr == NULL) { + fclose(fp); + return false; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + fclose(fp); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + /* If we get here, we had a problem reading the file */ + if (fp) fclose(fp); + fp=0; + free(rowbuf); + rowbuf=0; + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; + } + + + png_init_io(png_ptr, fp); + int width=bmp->getWidth(); + int height = bmp->getHeight(); + +#define BITDEPTH 8 + png_set_IHDR(png_ptr, info_ptr, width, height, BITDEPTH, wantalpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + png_set_bgr(png_ptr); + + // kill alpha channel bytes if not wanted + if (!wantalpha) png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + + LICE_pixel *ptr=(LICE_pixel *)bmp->getBits(); + int rowspan=bmp->getRowSpan(); + if (bmp->isFlipped()) + { + ptr+=rowspan*(bmp->getHeight()-1); + rowspan=-rowspan; + } + + + if (LICE_PIXEL_B != 0 || LICE_PIXEL_G != 1 || LICE_PIXEL_R != 2 || LICE_PIXEL_A != 3) + { + rowbuf=(unsigned char *)malloc(width*4); + int k; + for (k = 0; k < height; k++) + { + int x; + unsigned char *bout = rowbuf; + LICE_pixel_chan *bin = (LICE_pixel_chan *) ptr; + for(x=0;x +#include +#include + +#include "../tinyxml/tinyxml.h" +#include "../wdlcstring.h" + +extern "C" int LICE_RGBA_from_SVG(const char* s, int len); + + +const double SVG_ID_MAT[6] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 }; // acebdf +const int SVG_MAT_SZ = sizeof(SVG_ID_MAT); + +#define SVGINT(x) ((int)(x+0.5)) + +static void SVGMSet(double m[], double a, double b, double c, double d, double e, double f) +{ + m[0] = a; + m[3] = b; + m[1] = c; + m[4] = d; + m[2] = e; + m[5] = f; +} + +static void SVGMMult(double m[], double a, double b, double c, double d, double e, double f) +{ + SVGMSet(m, + m[0]*a+m[1]*b, // 0 + m[3]*a+m[4]*b, // 3 + m[0]*c+m[1]*d, // 1 + m[3]*c+m[4]*d, // 4 + m[0]*e+m[1]*f+m[2], // 2 + m[3]*e+m[4]*f+m[5]); // 5 +} + +static void SVGMTransform(double m[], double* x, double* y) +{ + if (memcmp(m, SVG_ID_MAT, SVG_MAT_SZ)) + { + double tx = *x; + double ty = *y; + *x = tx*m[0]+ty*m[1]+m[2]; + *y = tx*m[3]+ty*m[4]+m[5]; + } +} + +static void SVGMScale(double m[], double* w, double* h) +{ + if (memcmp(m, SVG_ID_MAT, SVG_MAT_SZ)) + { + *w *= m[0]; + *h *= m[4]; + } +} + +static void SVGDrawLine(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, LICE_pixel color, float alpha, bool aa, int linewid=1) +{ + int i; + for (i = 0; i < linewid; ++i) + { + LICE_FLine(bmp, x1, y1, x2, y2, color, alpha, LICE_BLIT_MODE_COPY, aa); + + if (fabs(y2-y1) > fabs(x2-x1)) + { + x1 += 1.0; + x2 += 1.0; + } + else + { + y1 += 1.0; + y2 += 1.0; + } + } +} + +static void SVGDrawRect(LICE_IBitmap* bmp, double x, double y, int w, int h, LICE_pixel color, float alpha, int linewid=1) +{ + int xi = SVGINT(x), yi = SVGINT(y); + int wi = SVGINT(w), hi = SVGINT(h); + + int i; + for (i = 0; i < linewid; ++i) + { + LICE_DrawRect(bmp, xi, yi, wi, hi, color, alpha, LICE_BLIT_MODE_COPY); + ++xi; + ++yi; + } +} + +static void SVGDrawCircle(LICE_IBitmap* bmp, double cx, double cy, double r, LICE_pixel color, float alpha, bool aa, int linewid=1) +{ + int i; + for (i = 0; i < linewid; ++i) + { + LICE_Circle(bmp, cx, cy, r, color, alpha, LICE_BLIT_MODE_COPY, aa); + r += 1.0f; + } +} + +static void SVGDrawQBezier(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, double x3, double y3, + LICE_pixel color, float alpha, bool aa, int linewid=1) +{ + int i; + for (i = 0; i < linewid; ++i) + { + LICE_DrawQBezier(bmp, x1, y1, x2, y2, x3, y3, color, alpha, LICE_BLIT_MODE_COPY, aa); + + if (fabs(y3-y1) > fabs(x3-x1)) + { + x1 += 1.0; + x2 += 1.0; + x3 += 1.0; + } + else + { + y1 += 1.0; + y2 += 1.0; + y3 += 1.0; + } + } +} + +static void SVGDrawCBezier(LICE_IBitmap* bmp, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, + LICE_pixel color, float alpha, bool aa, int linewid=1) +{ + int i; + for (i = 0; i < linewid; ++i) + { + LICE_DrawCBezier(bmp, x1, y1, x2, y2, x3, y3, x4, y4, color, alpha, LICE_BLIT_MODE_COPY, aa); + + if (fabs(y4-y1) > fabs(x4-x1)) + { + x1 += 1.0; + x2 += 1.0; + x3 += 1.0; + x4 += 1.0; + } + else + { + y1 += 1.0; + y2 += 1.0; + y3 += 1.0; + y4 += 1.0; + } + } +} + +class LICE_SVGState +{ +public: + + LICE_IBitmap* m_bmp; + LICE_IBitmap* m_tmpbmp; + double m_x, m_y; + + LICE_pixel m_strokecolor; + float m_strokealpha; + int m_strokewidth; + + LICE_pixel m_fillcolor; + float m_fillalpha; + + LICE_CachedFont* m_font; + LOGFONT m_logfont; + bool m_fontdirty; + int m_textflags; + + double m_ctm[6]; // current transform matrix + + LICE_SVGState(LICE_IBitmap* bmp); + ~LICE_SVGState(); + + void SetXY(double x, double y); + + void DrawText(LICE_IBitmap* bmp, const char* str); + + bool ParseNode(TiXmlNode* xmlnode); + bool ParseLine(TiXmlElement* xmlelem); + bool ParseRect(TiXmlElement* xmlelem); + bool ParseCircle(TiXmlElement* xmlelem); + bool ParsePolyline(TiXmlElement* xmlelem, bool close); + bool ParseText(TiXmlElement* xmlelem); + + bool ParsePosition(TiXmlElement* xmlelem); + bool ParseTransform(TiXmlElement* xmlelem, double prevctm[]); + bool ParseColor(TiXmlElement* xmlelem); + bool ParseFont(TiXmlElement* xmlelem); + + bool ParsePath(TiXmlElement* xmlelem); +}; + + +LICE_SVGState::LICE_SVGState(LICE_IBitmap* bmp) +{ + m_bmp = bmp; + m_tmpbmp = 0; + + m_x = 0.0; + m_y = 0.0; + + m_strokecolor = 0; + m_strokealpha = 1.0f; + m_strokewidth = 1; + + m_fillcolor = 0; + m_fillalpha = 1.0f; + + m_font = 0; + memset(&m_logfont, 0, sizeof(LOGFONT)); + m_fontdirty = true; + m_textflags = 0; + + memcpy(m_ctm, SVG_ID_MAT, SVG_MAT_SZ); +} + +LICE_SVGState::~LICE_SVGState() +{ + delete(m_tmpbmp); + delete(m_font); +} + +void LICE_SVGState::SetXY(double x, double y) +{ + m_x = x; + m_y = y; +} + +void LICE_SVGState::DrawText(LICE_IBitmap* bmp, const char* str) +{ + if (!m_font) m_font = new LICE_CachedFont; + + if (m_fontdirty) + { + m_fontdirty = false; + HFONT hf = CreateFontIndirect(&m_logfont); + m_font->SetFromHFont(hf, LICE_FONT_FLAG_OWNS_HFONT); + } + m_font->SetTextColor(m_fillcolor); + + RECT r = { SVGINT(m_x), SVGINT(m_y), SVGINT(m_x), SVGINT(m_y) }; + m_font->DrawText(m_bmp, str, -1, &r, m_textflags|DT_NOCLIP); +} + +static const char* GetSVGStyleStr(const char* str, const char* name, int* len) +{ + const char* s = strstr(str, name); + if (s) + { + s += strlen(name); + while (*s == ' ') ++s; + int i; + const int MAXLEN = 256; + for (i = 0; i < MAXLEN && s[i] && s[i] != ';'; ++i) + { + // run through + } + if (i && i < MAXLEN) *len = i; + else s = 0; + } + return s; +} + +bool LICE_SVGState::ParseTransform(TiXmlElement* xmlelem, double prevctm[]) +{ + const char* str = xmlelem->Attribute("transform"); + while (str && *str == ' ') ++str; + + int ntrans = 0; + while (str && *str) + { + double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0; + int n = 0; + + bool ok = (sscanf(str, "matrix(%lf,%lf,%lf,%lf,%lf,%lf) %n", &a, &b, &c, &d, &e, &f, &n) == 6); + if (!ok) ok = (sscanf(str, "translate(%lf,%lf) %n", &e, &f, &n) == 2); + if (!ok) ok = (sscanf(str, "scale(%lf,%lf) %n", &a, &d, &n) == 2); + // todo rotate, skew + if (!ok || !n) break; + + if (!ntrans++) memcpy(prevctm, m_ctm, SVG_MAT_SZ); + SVGMMult(m_ctm, a, b, c, d, e, f); + str += n; + while (*str == ' ') ++str; + } + + return !!ntrans; +} + +bool LICE_SVGState::ParsePosition(TiXmlElement* xmlelem) +{ + double xf; + double yf; + if (xmlelem->Attribute("x", &xf) && xmlelem->Attribute("y", &yf)) + { + SVGMTransform(m_ctm, &xf, &yf); + SetXY(xf, yf); + } + return true; +} + +bool LICE_SVGState::ParseColor(TiXmlElement* xmlelem) +{ + const char* s; + int len; + + const char* str = xmlelem->Attribute("style"); + if (str) + { + s = GetSVGStyleStr(str, "fill:", &len); + if (s) m_fillcolor = LICE_RGBA_from_SVG(s, len); + else m_fillcolor = 0; + + s = GetSVGStyleStr(str, "stroke:", &len); + if (s) m_strokecolor = LICE_RGBA_from_SVG(s, len); + else m_strokecolor = 0; + + s = GetSVGStyleStr(str, "stroke-width:", &len); + if (s && *s >= '0' && *s <= '9') m_strokewidth = *s-'0'; + else m_strokewidth = 1; + } + return true; +} + +bool LICE_SVGState::ParseFont(TiXmlElement* xmlelem) +{ + const char* s; + int len; + + m_textflags = DT_LEFT|DT_TOP; + + const char* str = xmlelem->Attribute("style"); + if (str) + { + s = GetSVGStyleStr(str, "font-family:", &len); + if (s) + { + lstrcpyn_safe(m_logfont.lfFaceName, s, len); + m_fontdirty = true; + } + + s = GetSVGStyleStr(str, "font-size:", &len); + if (s) + { + double sz = atof(s); + if (sz > 0.0) + { + double xsz = sz, ysz = sz; + SVGMScale(m_ctm, &xsz, &ysz); + sz = max(xsz, ysz); + m_logfont.lfHeight = -abs((int)sz); + m_fontdirty = true; + } + } + + s = GetSVGStyleStr(str, "text-align:", &len); + if (s) + { + if (!strnicmp(s, "center", len)) + { + m_textflags &= ~(DT_LEFT|DT_TOP); + m_textflags |= (DT_CENTER|DT_VCENTER); + } + else if (!strnicmp(s, "start", len)) + { + m_textflags &= ~DT_TOP; + m_textflags |= DT_BOTTOM; + } + } + } + + return true; +} + +bool LICE_SVGState::ParseText(TiXmlElement* xmlelem) +{ + bool ok = true; + + ParseFont(xmlelem); + + const char* str = xmlelem->GetText(); + if (str && *str) DrawText(m_bmp, str); + + TiXmlElement* xmlchild; + for (xmlchild = xmlelem->FirstChildElement("tspan"); xmlchild; xmlchild = xmlchild->NextSiblingElement("tspan")) + { + // no transform for tspan + ParsePosition(xmlchild); + ParseColor(xmlchild); + if (!ParseText(xmlchild)) ok = false; + } + + return ok; +} + +bool LICE_SVGState::ParseRect(TiXmlElement* xmlelem) +{ + bool ok = false; + double w, h; + + double rx = 0.0, ry = 0.0; + xmlelem->Attribute("rx", &rx); + xmlelem->Attribute("ry", &ry); + + ok = (xmlelem->Attribute("width", &w) && xmlelem->Attribute("height", &h)); + + if (ok) + { + SVGMScale(m_ctm, &w, &h); + SVGMScale(m_ctm, &rx, &ry); + + if (m_fillcolor && m_fillalpha > 0.0f) + { + LICE_FillRect(m_bmp, SVGINT(m_x), SVGINT(m_y), SVGINT(w), SVGINT(h), m_fillcolor, m_fillalpha, LICE_BLIT_MODE_COPY); + } + if (m_strokecolor && m_strokealpha > 0.0f) + { + if (rx > 0.0) + { + LICE_RoundRect(m_bmp, SVGINT(m_x), SVGINT(m_y), SVGINT(w), SVGINT(h), (int) rx, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); + } + else + { + SVGDrawRect(m_bmp, m_x, m_y, w, h, m_strokecolor, m_strokealpha, m_strokewidth); + } + } + } + + return ok; +} + +bool LICE_SVGState::ParseCircle(TiXmlElement* xmlelem) +{ + bool ok = false; + + double cx, cy, r = 0.0; + ok = !!xmlelem->Attribute("cx", &cx); + if (ok) ok = !!xmlelem->Attribute("cy", &cy); + if (ok) ok = (!!xmlelem->Attribute("r", &r) && r > 0.0); + + if (ok) + { + SVGMTransform(m_ctm, &cx, &cy); + r = 0.5*floor(r*2.0+0.5); + + if (m_fillcolor && m_fillalpha > 0.0f) + { + LICE_FillCircle(m_bmp, cx, cy, r, m_fillcolor, m_fillalpha, LICE_BLIT_MODE_COPY, true); + } + if (m_strokecolor && m_strokealpha > 0.0f) + { + //LICE_Circle(m_bmp, cx, cy, r, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); + SVGDrawCircle(m_bmp, cx, cy, r, m_strokecolor, m_strokealpha, true, m_strokewidth); + } + } + + return ok; +} + +bool LICE_SVGState::ParseLine(TiXmlElement* xmlelem) +{ + bool ok = false; + double x1, y1, x2, y2; + + ok = (xmlelem->Attribute("x1", &x1) && xmlelem->Attribute("y1", &y1) + && xmlelem->Attribute("x2", &x2) && xmlelem->Attribute("y2", &y2)); + + if (ok) + { + SVGMTransform(m_ctm, &x1, &y1); + SVGMTransform(m_ctm, &x2, &y2); + //LICE_FLine(m_bmp, x1, y1, x2, y2, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); + SVGDrawLine(m_bmp, x1, y1, x2, y2, m_strokecolor, m_strokealpha, true, m_strokewidth); + SetXY(x2, y2); + } + + return ok; +} + +bool LICE_SVGState::ParsePolyline(TiXmlElement* xmlelem, bool close) +{ + bool ok = false; + + double firstx = m_x; + double firsty = m_y; + int npts = 0; + + const char* str = xmlelem->Attribute("points"); + while (str && *str == ' ') ++str; + + while (str && *str) + { + double x, y; + int n = 0; + + ok = (sscanf(str, "%lf,%lf %n", &x, &y, &n) == 2); + if (ok) + { + SVGMTransform(m_ctm, &x, &y); + if (!npts++) + { + firstx = x; + firsty = y; + } + else + { + //LICE_FLine(m_bmp, m_x, m_y, x, y, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); + SVGDrawLine(m_bmp, m_x, m_y, x, y, m_strokecolor, m_strokealpha, true, m_strokewidth); + } + SetXY(x, y); + } + + if (!ok || !n) break; + str += n; + while (*str == ' ') ++str; + } + + if (close && npts) + { + //LICE_FLine(m_bmp, m_x, m_y, firstx, firsty, m_strokecolor, m_strokealpha, LICE_BLIT_MODE_COPY, true); + SVGDrawLine(m_bmp, m_x, m_y, firstx, firsty, m_strokecolor, m_strokealpha, true, m_strokewidth); + SetXY(firstx, firsty); + } + + return ok; +} + +static void AdjRelXY(double* lastx, double* lasty, double* x, double* y, double m[], bool isrel, RECT* r) +{ + if (isrel) + { + *x += *lastx; + *y += *lasty; + } + *lastx = *x; + *lasty = *y; + SVGMTransform(m, x, y); + + if (r) + { + if (r->left < 0 || *x < r->left) r->left = *x-2; + if (r->right < 0 || *x >= r->right) r->right = *x+3; + if (r->top < 0 || *y < r->top) r->top = *y-2; + if (r->bottom < 0 || *y >= r->bottom) r->bottom = *y+3; + } +} + +static bool RenderSVGPath(const char* str, double m[], RECT* r, + LICE_IBitmap* bmp=0, LICE_pixel color=0xFFFFFFFF, float alpha=1.0f, bool aa=false, int strokewid=1, + double* lastx=0, double* lasty=0) +{ + bool allok = true; + + double firstx, firsty; // first point on subpath, global coords + double prevx, prevy; // previous point, local coords + double x0, y0; // point at end of previous move, global coords + + while (str && *str) + { + double x1, y1, x2, y2, x3, y3; + int n = 0; + bool ok = false; + + char c = str[0]; + bool isrel = (c == tolower(c)); + ++str; + while (*str == ' ') ++str; + + switch (toupper(c)) + { + case 'M': + case 'L': + ok = (sscanf(str, "%lf,%lf %n", &x1, &y1, &n) == 2); + if (ok) + { + AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); + if (c == 'M') + { + firstx = x1; + firsty = y1; + } + else if (bmp) + { + //LICE_FLine(bmp, x0, y0, x1, y1, color, alpha, LICE_BLIT_MODE_COPY, aa); + SVGDrawLine(bmp, x0, y0, x1, y1, color, alpha, aa, strokewid); + } + x0 = x1; + y0 = y1; + } + break; + + case 'Z': + ok = true; + --str; + n = 1; + if (ok) + { + if (bmp && x0 != firstx && y0 != firsty) + { + //LICE_FLine(bmp, x0, y0, firstx, firsty, color, alpha, LICE_BLIT_MODE_COPY, aa); + SVGDrawLine(bmp, x0, y0, firstx, firsty, color, alpha, aa, strokewid); + x0 = firstx; + y0 = firsty; + } + } + break; + + case 'Q': + ok = (sscanf(str, "%lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &n) == 4); + if (ok) + { + AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); + AdjRelXY(&prevx, &prevy, &x2, &y2, m, isrel, r); + if (bmp) + { + //LICE_DrawQBezier(bmp, x0, y0, x1, y1, x2, y2, color, alpha, LICE_BLIT_MODE_COPY, aa); + SVGDrawQBezier(bmp, x0, y1, x1, y1, x2, y2, color, alpha, aa, strokewid); + x0 = x2; + y0 = y2; + } + } + break; + + case 'C': + ok = (sscanf(str, "%lf,%lf %lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &x3, &y3, &n) == 6); + if (ok) + { + AdjRelXY(&prevx, &prevy, &x1, &y1, m, isrel, r); + AdjRelXY(&prevx, &prevy, &x2, &y2, m, isrel, r); + AdjRelXY(&prevx, &prevy, &x3, &y3, m, isrel, r); + if (bmp) + { + //LICE_DrawCBezier(bmp, x0, y0, x1, y1, x2, y2, x3, y3, color, alpha, LICE_BLIT_MODE_COPY, aa); + SVGDrawCBezier(bmp, x0, y0, x1, y1, x2, y2, x3, y3, color, alpha, aa, strokewid); + x0 = x3; + y0 = y3; + } + } + break; + } + + if (!ok) allok = false; + if (!ok || !n) break; + str += n; + while (*str == ' ') ++str; + } + + if (lastx) *lastx = x0; + if (lasty) *lasty = y0; + return allok; +} + +static bool FillSVGScanLine(LICE_IBitmap* dest, LICE_pixel* rowpx, LICE_pixel col, float alpha, RECT* r, int y, int dir) +{ + bool prevon = false; + bool dofill = false; + + int i, x, xstart; + int w = r->right-r->left; + for (i = 0; i < w; ++i) + { + x = (dir < 0 ? w-i-1 : i); + bool curon = !!rowpx[x]; + if (curon != prevon) + { + if (!curon) + { + xstart = x; + } + else + { + if (dofill) + { + LICE_Line(dest, r->left+xstart/*+dir*/, y, r->left+x/*-dir*/, y, col, alpha, LICE_BLIT_MODE_COPY, false); + } + dofill = !dofill; + } + prevon = curon; + } + } + + return !dofill; // if we ended before hitting the end of a fill, we nicked an edge +} + +static bool FillSVGShape(LICE_IBitmap* dest, LICE_IBitmap* src, LICE_pixel col, float alpha, RECT *r) +{ + bool ok = true; + + LICE_pixel* rowpx = src->getBits(); + int span = src->getRowSpan(); + + int y; + for (y = r->top; y < r->bottom; ++y, rowpx += span) + { + if (!FillSVGScanLine(dest, rowpx, col, alpha, r, y, 1) && + !FillSVGScanLine(dest, rowpx, col, alpha, r, y, -1)) + { + ok = false; + } + } + + return ok; +} + +bool LICE_SVGState::ParsePath(TiXmlElement* xmlelem) +{ + bool ok = true; + + const char* str = xmlelem->Attribute("d"); + while (str && *str == ' ') ++str; + + if (m_fillcolor && m_fillalpha > 0.0f) // fill + { + RECT r = { -1, -1, -1, -1 }; // bounding box + if (ok) ok = RenderSVGPath(str, m_ctm, &r); // measure + + double m[6]; + SVGMSet(m, 1.0, 0.0, 0.0, 1.0, -(double)r.left, -(double)r.top); // translate to tmpbmp on matrix LHS + SVGMMult(m, m_ctm[0], m_ctm[3], m_ctm[1], m_ctm[4], m_ctm[2], m_ctm[5]); + + if (!m_tmpbmp) m_tmpbmp = new LICE_MemBitmap; + m_tmpbmp->resize(r.right-r.left, r.bottom-r.top); + LICE_Clear(m_tmpbmp, 0); + + if (ok) ok = RenderSVGPath(str, m, 0, m_tmpbmp); // outline to tmpbmp + // debug LICE_Blit(m_bmp, m_tmpbmp, r.left, r.top, 0, 0, r.right-r.left, r.bottom-r.top, 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + if (ok) ok = FillSVGShape(m_bmp, m_tmpbmp, m_fillcolor, m_fillalpha, &r); // raytrace to dest + } + + if (m_strokecolor && m_strokealpha > 0.0f) // outline + { + if (ok) ok = RenderSVGPath(str, m_ctm, 0, m_bmp, m_strokecolor, m_strokealpha, true, m_strokewidth, &m_x, &m_y); + } + + return ok; +} + +bool LICE_SVGState::ParseNode(TiXmlNode* xmlnode) +{ + bool allok = true; + + TiXmlNode* xmlchild; + for (xmlchild = xmlnode->FirstChild(); xmlchild; xmlchild = xmlchild->NextSibling()) + { + if (xmlchild->Type() == TiXmlElement::ELEMENT) + { + bool ok = true; + + const char* name = xmlchild->Value(); + TiXmlElement* xmlelem = xmlchild->ToElement(); + + double prevctm[6]; + bool transform = ParseTransform(xmlelem, prevctm); + + ParsePosition(xmlelem); + ParseColor(xmlelem); + + if (!stricmp(name, "svg") || !stricmp(name, "g")) ok = ParseNode(xmlelem); + else if (!stricmp(name, "rect")) ok = ParseRect(xmlelem); + else if (!stricmp(name, "circle")) ok = ParseCircle(xmlelem); + else if (!stricmp(name, "line")) ok = ParseLine(xmlelem); + else if (!stricmp(name, "polyline")) ok = ParsePolyline(xmlelem, false); + else if (!stricmp(name, "polygon")) ok = ParsePolyline(xmlelem, true); + else if (!stricmp(name, "path")) ok = ParsePath(xmlelem); + else if (!stricmp(name, "text") || !stricmp(name, "tspan")) ok = ParseText(xmlelem); + // it's not an error not to recognize a tag + + if (!ok) + { + allok = false; + // log error and continue + } + + if (transform) memcpy(m_ctm, prevctm, SVG_MAT_SZ); + } + } + + return true; //allok; +} + +static LICE_IBitmap *LICE_RenderSVG(TiXmlDocument* xmldoc, LICE_IBitmap *bmp) +{ + if (!xmldoc) return 0; + + TiXmlElement* xmlroot = xmldoc->RootElement(); + if (!xmlroot || stricmp(xmlroot->Value(), "svg")) return 0; + + int srcw = 0; + int srch = 0; + if (!xmlroot->Attribute("width", &srcw) || !xmlroot->Attribute("height", &srch)) return 0; + if (!srcw || !srch) return 0; + + bool ourbmp = !bmp; + if (ourbmp) bmp = new LICE_MemBitmap; + LICE_SVGState svgstate(bmp); + +/* + int destw = bmp->getWidth(); + int desth = bmp->getHeight(); + + if (destw && desth) + { + double xscale = (double)destw/(double)srcw; + double yscale = (double)desth/(double)srch; + SVGMSet(svgstate.m_ctm, xscale, 0.0, 0.0, yscale, 0.0, 0.0); + } + else +*/ + { + bmp->resize(srcw, srch); + } + LICE_Clear(bmp, 0); + + if (!svgstate.ParseNode(xmlroot) && ourbmp) + { + delete(bmp); + bmp = 0; + } + return bmp; +} + +LICE_IBitmap* LICE_LoadSVG(const char* filename, LICE_IBitmap* bmp) +{ + TiXmlDocument xmldoc; + xmldoc.SetCondenseWhiteSpace(false); + if (!xmldoc.LoadFile(filename) || xmldoc.Error()) return 0; + return LICE_RenderSVG(&xmldoc, bmp); +} + +LICE_IBitmap* LICE_LoadSVGFromBuffer(const char* buffer, int buflen, LICE_IBitmap* bmp) +{ + TiXmlDocument xmldoc; + xmldoc.SetCondenseWhiteSpace(false); + if (!xmldoc.Parse(buffer) || xmldoc.Error()) return 0; + return LICE_RenderSVG(&xmldoc, bmp); +} + diff --git a/WDL/lice/lice_texgen.cpp b/WDL/lice/lice_texgen.cpp new file mode 100644 index 00000000..fe6e5ffd --- /dev/null +++ b/WDL/lice/lice_texgen.cpp @@ -0,0 +1,341 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: lice_texgen.cpp (LICE texture generator routines) + See lice.h for license and other information +*/ + + +#include "lice.h" +#include + +void LICE_TexGen_Marble(LICE_IBitmap *dest, RECT *rect, float rv, float gv, float bv, float intensity) +{ + int span=dest->getRowSpan(); + int w = dest->getWidth(); + int h = dest->getHeight(); + int x = 0; + int y = 0; + if(rect) + { + x = rect->left; + y = rect->top; + w = rect->right - rect->left; + h = rect->bottom - rect->top; + } + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w > dest->getWidth()) w=dest->getWidth()-x; + if (y+h > dest->getHeight()) h=dest->getHeight()-y; + + if (w<1 || h<1) return; + + LICE_pixel *startp = dest->getBits(); + if (dest->isFlipped()) + { + startp += x + (dest->getHeight()-1-y)*span; + span=-span; + } + else startp += x + y*span; + + //simple 16bit marble noise generator + +#define ROL(x,y) ((x<<(y))|(((unsigned short)x)>>(16-(y)))) +#define ROR(x,y) ((((unsigned short)x)>>(y))|(x<<(16-(y)))) + + intensity/=1024.0f; + int maxc = 0; + { + LICE_pixel *p = startp; + short n1 = 0, n2 = 0; + for(int i=0;i0) + { + c = p[j-span]; + if(j==0) + c2 = p[(w-1)-span]; + else + c2 = p[(j-1)-span]; + } + + int pix = (((c + c2)/2) + val); + if(pix>maxc) maxc = pix; + p[j] = pix; + } + p+=span; + } + } + + //normalize values and apply gamma + { + LICE_pixel *p = startp; + float sc=255.0f/maxc; + + for(int i=0;igetRowSpan(); + int w = dest->getWidth(); + int h = dest->getHeight(); + int x = 0; + int y = 0; + if(rect) + { + x = rect->left; + y = rect->top; + w = rect->right - rect->left; + h = rect->bottom - rect->top; + } + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w > dest->getWidth()) w=dest->getWidth()-x; + if (y+h > dest->getHeight()) h=dest->getHeight()-y; + + if (w<1 || h<1) return; + + LICE_pixel *startp = dest->getBits(); + if (dest->isFlipped()) + { + startp += x + (dest->getHeight()-1-y)*span; + span=-span; + } + else startp += x + y*span; + + { + LICE_pixel *p = startp; + for(int i=0;i=1) + { + switch(mode) + { + case NOISE_MODE_NORMAL: val += noise(x/size, y/size)*size; break; + case NOISE_MODE_WOOD: val += (float)cos( x/size + noise(x/size,y/size) )*size/2; break; + } + size /= 2; + } + float col = (float)fabs(val/smooth)*255; + if(col>255) col=255; + + p[j] = LICE_RGBA((int)(col*rv),(int)(col*gv),(int)(col*bv),255); + } + p+=span; + } + } +} + +float turbulence(float x, float y, float size) +{ + float value = 0.0, initialSize = size; + while(size >= 1) + { + value += noise(x / size, y / size) * size; + size /= 2.0; + } + return(128.0f * value / initialSize); +} + +void LICE_TexGen_CircNoise(LICE_IBitmap *dest, RECT *rect, float rv, float gv, float bv, float nrings, float power, int size) +{ + initNoise(); + + int span=dest->getRowSpan(); + int w = dest->getWidth(); + int h = dest->getHeight(); + int x = 0; + int y = 0; + if(rect) + { + x = rect->left; + y = rect->top; + w = rect->right - rect->left; + h = rect->bottom - rect->top; + } + + if (x<0) { w+=x; x=0; } + if (y<0) { h+=y; y=0; } + if (x+w > dest->getWidth()) w=dest->getWidth()-x; + if (y+h > dest->getHeight()) h=dest->getHeight()-y; + + if (w<1 || h<1) return; + + LICE_pixel *startp = dest->getBits(); + if (dest->isFlipped()) + { + startp += x + (dest->getHeight()-1-y)*span; + span=-span; + } + else startp += x + y*span; + + float xyPeriod = nrings; + float turbPower = power; + float turbSize = (float)size; + + { + LICE_pixel *p = startp; + for(int i=0;i' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0xfe, /* 11111110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xce, /* 11001110 */ + 0x7c, /* 01111100 */ + 0x0e, /* 00001110 */ + + /* 82 0x52 'R' */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x8c, /* 10001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + + /* 96 0x60 '`' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf8, /* 11111000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + + /* 104 0x68 'h' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + + /* 107 0x6b 'k' */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x4c, /* 01001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ +}; + + +void LICE_DrawChar(LICE_IBitmap *bm, int x, int y, char c, + LICE_pixel color, float alpha, int mode) +{ + LICE_pixel *fb; + if (c<1 || !bm || !(fb=bm->getBits()))return; + unsigned char *font = LICE_deffont + ((c-1)*LICE_FONT_HEIGHT); + int len = LICE_FONT_HEIGHT; + if (y < 0) + { + font -= y; + len += y; + y = 0; + } + if (y+LICE_FONT_HEIGHT >= bm->getHeight()) len = bm->getHeight()-y; + if (len<1) return; + + int smask=128; + int xlen=8; + if (x<0) + { + smask >>= -x; + xlen+=x; + x=0; + } + int ml=bm->getWidth()-x; + if (xlen>ml)xlen=ml; + + if (ml<1) return; + + int rs=bm->getRowSpan(); + if (bm->isFlipped()) + { + fb += x+((bm->getHeight()-1-y)*rs); + rs=-rs; + } + else + fb += x+(y*rs); + + int red=LICE_GETR(color), green=LICE_GETG(color), blue=LICE_GETB(color), alp=LICE_GETA(color), ialpha=(int) (alpha * 256.0f); + + while (len-->0) + { + LICE_pixel *outmem = fb; + fb+=rs; + unsigned char ch = *font++; + int a=smask; + int xleft = xlen; + while (a && xleft--) + { + if (ch & a) + { + #define __LICE__ACTION(comb) comb::doPix((LICE_pixel_chan *)outmem, red,green,blue,alp,ialpha) + __LICE_ACTION_NOSRCALPHA(mode,ialpha, false); + #undef __LICE__ACTION + } + outmem++; + a >>= 1; + } + } +} + +void LICE_DrawText(LICE_IBitmap *bm, int x, int y, const char *string, + LICE_pixel color, float alpha, int mode) +{ + if (!bm) return; + int w=bm->getWidth(); + int h=bm->getHeight(); + int xx = x; + while (*string) + { + switch (*string) + { + case '\n': y += LICE_FONT_HEIGHT; xx = x; break; + case ' ': xx += 8; break; + case '\r': break; + case '\t': xx += 8*5; break; + default: + if (xx>=-8 && xx= -LICE_FONT_HEIGHT && y < h) + LICE_DrawChar(bm,xx,y,*string, color,alpha,mode); + xx += 8; + break; + } + string++; + } +} + +void LICE_MeasureText(const char *string, int *w, int *h) +{ + if (w) *w=0; + if (h) *h=0; + int x=0,y=LICE_FONT_HEIGHT; + while (*string) + { + switch (*string) + { + case '\n': y += LICE_FONT_HEIGHT; x = 0; break; + case '\r': break; + case '\t': x += 8*4; + default: + x += 8; + if (w && x > *w) *w=x; + if (h && y > *h) *h=y; + break; + } + string++; + } +} + diff --git a/WDL/lice/lice_text.h b/WDL/lice/lice_text.h new file mode 100644 index 00000000..165eaf02 --- /dev/null +++ b/WDL/lice/lice_text.h @@ -0,0 +1,110 @@ +#ifndef _LICE_TEXT_H_ +#define _LICE_TEXT_H_ + +#include "lice.h" + +#include "../heapbuf.h" + +#define LICE_FONT_FLAG_VERTICAL 1 // rotate text to vertical (do not set the windows font to vertical though) +#define LICE_FONT_FLAG_VERTICAL_BOTTOMUP 2 + +#define LICE_FONT_FLAG_PRECALCALL 4 +//#define LICE_FONT_FLAG_ALLOW_NATIVE 8 +#define LICE_FONT_FLAG_FORCE_NATIVE 1024 + +#define LICE_FONT_FLAG_FX_BLUR 16 +#define LICE_FONT_FLAG_FX_INVERT 32 +#define LICE_FONT_FLAG_FX_MONO 64 // faster but no AA/etc + +#define LICE_FONT_FLAG_FX_SHADOW 128 // these imply MONO +#define LICE_FONT_FLAG_FX_OUTLINE 256 + +#define LICE_FONT_FLAG_OWNS_HFONT 512 + +// could do a mask for these flags +#define LICE_FONT_FLAGS_HAS_FX(flag) \ + (flag&(LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP| \ + LICE_FONT_FLAG_FX_BLUR|LICE_FONT_FLAG_FX_INVERT|LICE_FONT_FLAG_FX_MONO| \ + LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) + +#define LICE_DT_NEEDALPHA 0x80000000 // include in DrawText() if the output alpha channel is important +#define LICE_DT_USEFGALPHA 0x40000000 // uses alpha channel in fg color + +class LICE_IFont +{ + public: + virtual ~LICE_IFont() {} + + virtual void SetFromHFont(HFONT font, int flags=0)=0; // hfont must REMAIN valid, unless LICE_FONT_FLAG_PRECALCALL or LICE_FONT_FLAG_OWNS_HFONT set (OWNS means LICE_IFont will clean up hfont on font change or exit) + + virtual LICE_pixel SetTextColor(LICE_pixel color)=0; + virtual LICE_pixel SetBkColor(LICE_pixel color)=0; + virtual LICE_pixel SetEffectColor(LICE_pixel color)=0; + virtual int SetBkMode(int bkmode)=0; + virtual void SetCombineMode(int combine, float alpha=1.0f)=0; + + virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags)=0; + + virtual LICE_pixel GetTextColor()=0; + virtual HFONT GetHFont()=0; +}; + + +class LICE_CachedFont : public LICE_IFont +{ + public: + LICE_CachedFont(); + virtual ~LICE_CachedFont(); + + virtual void SetFromHFont(HFONT font, int flags=0); + + virtual LICE_pixel SetTextColor(LICE_pixel color) { LICE_pixel ret=m_fg; m_fg=color; return ret; } + virtual LICE_pixel SetBkColor(LICE_pixel color) { LICE_pixel ret=m_bg; m_bg=color; return ret; } + virtual LICE_pixel SetEffectColor(LICE_pixel color) { LICE_pixel ret=m_effectcol; m_effectcol=color; return ret; } + virtual int SetBkMode(int bkmode) { int bk = m_bgmode; m_bgmode=bkmode; return bk; } + virtual void SetCombineMode(int combine, float alpha=1.0f) { m_comb=combine; m_alpha=alpha; } + + virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags) + { + return DrawTextImpl(bm,str,strcnt,rect,dtFlags); + } + + virtual LICE_pixel GetTextColor() { return m_fg; } + virtual HFONT GetHFont() { return m_font; } + + void SetLineSpacingAdjust(int amt) { m_lsadj=amt; } + + private: + + int DrawTextImpl(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags); // cause swell defines DrawText to SWELL_DrawText etc + + bool DrawGlyph(LICE_IBitmap *bm, unsigned short c, int xpos, int ypos, RECT *clipR); + bool RenderGlyph(unsigned short idx); + + LICE_pixel m_fg,m_bg,m_effectcol; + int m_bgmode; + int m_comb; + float m_alpha; + int m_flags; + + int m_line_height,m_lsadj; + struct charEnt + { + int base_offset; // offset in m_cachestore+1, so 1=offset0, 0=unset, -1=failed to render + int width, height; + int advance; + int charid; // used by m_extracharlist + }; + charEnt *findChar(unsigned short c); + + charEnt m_lowchars[128]; // first 128 chars cached here + WDL_TypedBuf m_extracharlist; + WDL_TypedBuf m_cachestore; + + static int _charSortFunc(const void *a, const void *b); + + HFONT m_font; + +}; + +#endif//_LICE_TEXT_H_ diff --git a/WDL/lice/lice_textnew.cpp b/WDL/lice/lice_textnew.cpp new file mode 100644 index 00000000..eec87968 --- /dev/null +++ b/WDL/lice/lice_textnew.cpp @@ -0,0 +1,1014 @@ +#include "lice_text.h" +#include + + +#ifndef _WIN32 +#include "../swell/swell.h" +#endif + + +#include "lice_combine.h" +#include "lice_extended.h" + +#ifdef _WIN32 +static char __1ifNT2if98=0; // 2 for iswin98 +#endif + + +static int utf8makechar(char *ptrout, unsigned short charIn) +{ + unsigned char *pout = (unsigned char *)ptrout; + if (charIn < 128) { *pout = (unsigned char)charIn; return 1; } + if (charIn < 2048) { pout[0] = 0xC0 + (charIn>>6); pout[1] = 0x80 + (charIn&0x3f); return 2; } + pout[0] = 0xE0 + (charIn>>12); + pout[1] = 0x80 + ((charIn>>6)&0x3f); + pout[2] = 0x80 + (charIn&0x3f); + return 3; +} + +static int utf8char(const char *ptr, unsigned short *charOut) // returns char length +{ + const unsigned char *p = (const unsigned char *)ptr; + unsigned char tc = *p; + + if (tc < 128) + { + if (charOut) *charOut = (unsigned short) tc; + return 1; + } + else if (tc < 0xC2) // invalid chars (subsequent in sequence, or overlong which we disable for) + { + } + else if (tc < 0xE0) // 2 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0) + { + if (charOut) *charOut = ((tc&0x1f)<<6) | (p[1]&0x3f); + return 2; + } + } + else if (tc < 0xF0) // 3 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0) + { + if (charOut) *charOut = ((tc&0xf)<<12) | ((p[1]&0x3f)<<6) | ((p[2]&0x3f)); + return 3; + } + } + else if (tc < 0xF5) // 4 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0 && p[3] >= 0x80 && p[3] <= 0xC0) + { + if (charOut) *charOut = (unsigned short)' '; // dont support 4 byte sequences yet(ever?) + return 4; + } + } + if (charOut) *charOut = (unsigned short) tc; + return 1; +} + + + +//not threadsafe ---- +static LICE_SysBitmap s_tempbitmap; // keep a sysbitmap around for rendering fonts + + +int LICE_CachedFont::_charSortFunc(const void *a, const void *b) +{ + charEnt *aa = (charEnt *)a; + charEnt *bb = (charEnt *)b; + return aa->charid - bb->charid; +} + +LICE_CachedFont::LICE_CachedFont() : m_cachestore(65536) +{ + m_fg=0; + m_effectcol=m_bg=LICE_RGBA(255,255,255,255); + m_comb=0; + m_alpha=1.0f; + m_bgmode = TRANSPARENT; + m_flags=0; + m_line_height=0; + m_lsadj=0; + m_font=0; + memset(m_lowchars,0,sizeof(m_lowchars)); +} + +LICE_CachedFont::~LICE_CachedFont() +{ + if ((m_flags&LICE_FONT_FLAG_OWNS_HFONT) && m_font) { + DeleteObject(m_font); + } +} + +void LICE_CachedFont::SetFromHFont(HFONT font, int flags) +{ + if ((m_flags&LICE_FONT_FLAG_OWNS_HFONT) && m_font && m_font != font) + { + DeleteObject(m_font); + } + + m_flags=flags; + m_font=font; + if (font) + { + if (s_tempbitmap.getWidth() < 256 || s_tempbitmap.getHeight() < 256) + { + s_tempbitmap.resize(256,256); + ::SetTextColor(s_tempbitmap.getDC(),RGB(255,255,255)); + ::SetBkMode(s_tempbitmap.getDC(),OPAQUE); + ::SetBkColor(s_tempbitmap.getDC(),RGB(0,0,0)); + } + + TEXTMETRIC tm; + HGDIOBJ oldFont = 0; + if (font) oldFont = SelectObject(s_tempbitmap.getDC(),font); + GetTextMetrics(s_tempbitmap.getDC(),&tm); + if (oldFont) SelectObject(s_tempbitmap.getDC(),oldFont); + + m_line_height = tm.tmHeight; + } + + memset(m_lowchars,0,sizeof(m_lowchars)); + m_extracharlist.Resize(0,false); + m_cachestore.Resize(0); + if (flags&LICE_FONT_FLAG_PRECALCALL) + { + int x; + for(x=0;x<128;x++) + RenderGlyph(x); + } +} + +bool LICE_CachedFont::RenderGlyph(unsigned short idx) // return TRUE if ok +{ + bool needSort=false; + charEnt *ent; + if (idx>=128) + { +#ifdef _WIN32 + if (!__1ifNT2if98) __1ifNT2if98 = GetVersion()<0x80000000 ? 1 : 2; + + if (__1ifNT2if98==2) return false; +#endif + ent=findChar(idx); + if (!ent) + { + if (m_flags & LICE_FONT_FLAG_PRECALCALL) return false; + + int oldsz=m_extracharlist.GetSize(); + ent = m_extracharlist.Resize(oldsz+1) + oldsz; + memset(ent,0,sizeof(*ent)); + ent->charid = idx; + + needSort=true; + } + } + else ent = m_lowchars+idx; + + int bmsz=m_line_height; + if (bmsz<1) bmsz=1; + if (s_tempbitmap.getWidth() < bmsz || s_tempbitmap.getHeight() < bmsz) + { + s_tempbitmap.resize(bmsz,bmsz); + ::SetTextColor(s_tempbitmap.getDC(),RGB(255,255,255)); + ::SetBkMode(s_tempbitmap.getDC(),OPAQUE); + ::SetBkColor(s_tempbitmap.getDC(),RGB(0,0,0)); + } + + LICE_Clear(&s_tempbitmap,0); + + HGDIOBJ oldFont=0; + if (m_font) oldFont = SelectObject(s_tempbitmap.getDC(),m_font); + RECT r={0,0,0,0,}; + int advance; + +#ifdef _WIN32 + if (__1ifNT2if98==1) + { + WCHAR tmpstr[2]={(WCHAR)idx,0}; + ::DrawTextW(s_tempbitmap.getDC(),tmpstr,1,&r,DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); + advance=r.right; + if (idx>='A' && idx<='Z') r.right+=2; // extra space for A-Z + ::DrawTextW(s_tempbitmap.getDC(),tmpstr,1,&r,DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); + } + else +#endif + { + + char tmpstr[6]={(char)idx,0}; +#ifndef _WIN32 + if (idx>=128) utf8makechar(tmpstr,idx); +#endif + ::DrawText(s_tempbitmap.getDC(),tmpstr,-1,&r,DT_CALCRECT|DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); + advance=r.right; + if (idx>='A' && idx<='Z') r.right+=2; // extra space for A-Z + ::DrawText(s_tempbitmap.getDC(),tmpstr,-1,&r,DT_SINGLELINE|DT_LEFT|DT_TOP|DT_NOPREFIX); + } + + if (oldFont) SelectObject(s_tempbitmap.getDC(),oldFont); + + if (r.right < 1 || r.bottom < 1) + { + ent->base_offset=-1; + ent->advance=ent->width=ent->height=0; + } + else + { + ent->advance=advance; + int flags=m_flags; + if (flags&LICE_FONT_FLAG_FX_BLUR) + { + LICE_Blur(&s_tempbitmap,&s_tempbitmap,0,0,0,0,r.right,r.bottom); + } + LICE_pixel *srcbuf = s_tempbitmap.getBits(); + int span=s_tempbitmap.getRowSpan(); + + ent->base_offset=m_cachestore.GetSize()+1; + unsigned char *destbuf = m_cachestore.Resize(ent->base_offset-1+r.right*r.bottom) + ent->base_offset-1; + if (s_tempbitmap.isFlipped()) + { + srcbuf += (s_tempbitmap.getHeight()-1)*span; + span=-span; + } + int x,y; + for(y=0;y130 ? 255:0; + destbuf++; + } + + destbuf -= r.right*r.bottom; + } + if (flags&(LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) + { + for(y=0;y130 ? 255:0; + destbuf++; + } + + destbuf -= r.right*r.bottom; + if (flags&LICE_FONT_FLAG_FX_SHADOW) + { + for(y=0;y0) + { + if (destbuf[-1]==255) *destbuf=128; + else if (y>0 && destbuf[-r.right-1]==255) *destbuf=128; + } + if (y>0 && destbuf[-r.right]==255) *destbuf=128; + } + destbuf++; + } + } + else + { + for(y=0;y0 && destbuf[-r.right]==255) *destbuf=128; + else if (y0) + { + if (destbuf[-1]==255) *destbuf=128; + // else if (y>0 && destbuf[-r.right-1]==255) *destbuf=128; + // else if (y0 && destbuf[-r.right+1]==255) *destbuf=128; + // else if (ywidth = r.right; + ent->height = r.bottom; + } + if (needSort&&m_extracharlist.GetSize()>1) qsort(m_extracharlist.Get(),m_extracharlist.GetSize(),sizeof(charEnt),_charSortFunc); + + return true; +} + +template class GlyphRenderer +{ +public: + static void Normal(unsigned char *gsrc, LICE_pixel *pout, + int src_span, int dest_span, int width, int height, + int red, int green, int blue, int a256) + { + int y; + if (a256==256) + { + for(y=0;y256)a=256; + T::doPix((unsigned char *)(pout+x),red,green,blue,255,a); + } + } + gsrc += src_span; + pout += dest_span; + } + } + } + static void Mono(unsigned char *gsrc, LICE_pixel *pout, + int src_span, int dest_span, int width, int height, + int red, int green, int blue, int alpha) + { + int y; + for(y=0;ywidth <= clipR->left || xpos >= clipR->right || + ypos+ch->height <= clipR->top || ypos >= clipR->bottom) return false; + + unsigned char *gsrc = m_cachestore.Get() + ch->base_offset-1; + int src_span = ch->width; + int width = ch->width; + int height = ch->height; + +#ifndef DISABLE_LICE_EXTENSIONS + if (bm->Extended(LICE_EXT_SUPPORTS_ID, (void*) LICE_EXT_DRAWGLYPH_ACCEL)) + { + LICE_Ext_DrawGlyph_acceldata data(xpos, ypos, m_fg, gsrc, width, height, m_alpha, m_comb); + if (bm->Extended(LICE_EXT_DRAWGLYPH_ACCEL, &data)) return true; + } +#endif + + if (xpos < clipR->left) + { + width += (xpos-clipR->left); + gsrc += clipR->left-xpos; + xpos=clipR->left; + } + if (ypos < clipR->top) + { + gsrc += src_span*(clipR->top-ypos); + height += (ypos-clipR->top); + ypos=clipR->top; + } + int dest_span = bm->getRowSpan(); + LICE_pixel *pout = bm->getBits(); + + if (bm->isFlipped()) + { + pout += (bm->getHeight()-1)*dest_span; + dest_span=-dest_span; + } + + pout += xpos + ypos * dest_span; + + if (xpos+width >= clipR->right) width = clipR->right-xpos; + + if (ypos+height >= clipR->bottom) height = clipR->bottom-ypos; + + int mode=m_comb&~LICE_BLIT_USE_ALPHA; + float alpha=m_alpha; + + if (m_bgmode==OPAQUE) + LICE_FillRect(bm,xpos,ypos,width,height,m_bg,alpha,mode); + + int red=LICE_GETR(m_fg); + int green=LICE_GETG(m_fg); + int blue=LICE_GETB(m_fg); + + if (m_flags&LICE_FONT_FLAG_FX_MONO) + { + if (alpha==1.0 && (mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) // fast simple + { + LICE_pixel col=m_fg; + int y; + for(y=0;y256)avalint=256; + + #define __LICE__ACTION(comb) GlyphRenderer::Mono(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint) + __LICE_ACTION_NOSRCALPHA(mode,avalint, false); + #undef __LICE__ACTION + } + } + else if (m_flags&(LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE)) + { + LICE_pixel col=m_fg; + LICE_pixel bkcol=m_effectcol; + + if (alpha==1.0 && (mode&LICE_BLIT_MODE_MASK)==LICE_BLIT_MODE_COPY) + { + int y; + for(y=0;y256)avalint=256; + int r2=LICE_GETR(bkcol); + int g2=LICE_GETG(bkcol); + int b2=LICE_GETB(bkcol); + #define __LICE__ACTION(comb) GlyphRenderer::Effect(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint,r2,g2,b2) + __LICE_ACTION_NOSRCALPHA(mode,avalint, false); + #undef __LICE__ACTION + } + } + else + { + int avalint = (int) (alpha*256.0); + #define __LICE__ACTION(comb) GlyphRenderer::Normal(gsrc,pout,src_span,dest_span,width,height,red,green,blue,avalint) + __LICE_ACTION_NOSRCALPHA(mode,avalint, false); + #undef __LICE__ACTION + } + + return true; // drew glyph at all (for updating max extents) +} + + +static int LICE_Text_IsWine() +{ + static int isWine=-1; +#ifdef _WIN32 + if (isWine<0) + { + HKEY hk; + if (RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Wine",&hk)==ERROR_SUCCESS) + { + isWine=1; + RegCloseKey(hk); + } + else isWine=0; + } +#endif + return isWine>0; +} + +#ifdef _WIN32 +static BOOL LICE_Text_HasUTF8(const char *_str) +{ + const unsigned char *str = (const unsigned char *)_str; + if (!str) return FALSE; + while (*str) + { + unsigned char c = *str; + if (c >= 0xC2) // fuck overlongs + { + if (c <= 0xDF && str[1] >=0x80 && str[1] <= 0xBF) return TRUE; + else if (c <= 0xEF && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + else if (c <= 0xF4 && str[1] >=0x80 && str[1] <= 0xBF && str[2] >=0x80 && str[2] <= 0xBF) return TRUE; + } + str++; + } + return FALSE; +} +#endif + + +int LICE_CachedFont::DrawTextImpl(LICE_IBitmap *bm, const char *str, int strcnt, + RECT *rect, UINT dtFlags) +{ + if (!bm && !(dtFlags&DT_CALCRECT)) return 0; + + bool forceWantAlpha=false; + + if (dtFlags & LICE_DT_NEEDALPHA) + { + forceWantAlpha=true; + dtFlags &= ~LICE_DT_NEEDALPHA; + } + +#if 0 + if ((m_flags&LICE_FONT_FLAG_ALLOW_NATIVE) && + !(m_flags&LICE_FONT_FLAG_PRECALCALL)) + { + HDC hdc = (bm ? bm->getDC() : 0); + if (hdc) + { + ::SetTextColor(hdc,RGB(LICE_GETR(m_fg),LICE_GETG(m_fg),LICE_GETB(m_fg))); + ::SetBkMode(hdc,m_bgmode); + if (m_bgmode==OPAQUE) + ::SetBkColor(hdc,RGB(LICE_GETR(m_bg),LICE_GETG(m_bg),LICE_GETB(m_bg))); + + return ::DrawText(hdc,str,strcnt,rect,dtFlags|DT_NOPREFIX); + } + } +#endif + + // if using line-spacing adjustments (m_lsadj), don't allow native rendering + // todo: split rendering up into invidual lines and DrawText calls + if ((m_flags&LICE_FONT_FLAG_FORCE_NATIVE) && m_font && !forceWantAlpha &&!LICE_Text_IsWine() && + !(dtFlags & LICE_DT_USEFGALPHA) && + !(m_flags&LICE_FONT_FLAG_PRECALCALL) && !LICE_FONT_FLAGS_HAS_FX(m_flags) && + (!m_lsadj || (dtFlags&DT_SINGLELINE))) + { + + // on Win2000+, use wide versions if needed for UTF +#ifdef _WIN32 + WCHAR wtmpbuf[1024]; + WCHAR *wtmp=NULL; + static int win9x; + if (!win9x) win9x = GetVersion() < 0x80000000 ? -1 : 1; //>0 if win9x + if (win9x<0 && LICE_Text_HasUTF8(str)) + { + int req = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,NULL,0); + if (req < 1000) + { + int cnt=0; + if ((cnt=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,wtmpbuf,1024))) + { + wtmp=wtmpbuf; + wtmp[cnt]=0; + } + } + else + { + wtmp = (WCHAR *)malloc((req + 32)*sizeof(WCHAR)); + int cnt=-1; + if (wtmp && !(cnt=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,strcnt,wtmp,req+1))) + free(wtmp); + else if (cnt>0) wtmp[cnt]=0; + } + } +#endif + + HDC hdc = (bm ? bm->getDC() : 0); + int w = rect->right-rect->left; + int h = rect->bottom-rect->top; + HGDIOBJ oldfont = 0; + RECT srcr={0,}; + bool isTmp=false; + POINT blitPos={0,}; + + static LICE_SysBitmap s_nativerender_tempbitmap; + + if (!hdc) // use temp buffer + { + isTmp=true; + if (w<1)w=1; + if (h<1)h=1; + if (s_nativerender_tempbitmap.getWidth() < w || + s_nativerender_tempbitmap.getHeight() < h) + s_nativerender_tempbitmap.resize(w, h); + + + hdc = s_nativerender_tempbitmap.getDC(); + + oldfont = SelectObject(hdc, m_font); + + RECT blit_r = {0,0}; + int rv= +#ifdef _WIN32 + wtmp ? + ::DrawTextW(hdc,wtmp,-1,&blit_r,(dtFlags&~(DT_CENTER|DT_VCENTER|DT_TOP|DT_BOTTOM|DT_LEFT|DT_RIGHT))|DT_CALCRECT|DT_NOPREFIX) + : +#endif + ::DrawText(hdc,str,strcnt,&blit_r,(dtFlags&~(DT_CENTER|DT_VCENTER|DT_TOP|DT_BOTTOM|DT_LEFT|DT_RIGHT))|DT_CALCRECT|DT_NOPREFIX); + if (dtFlags & DT_CALCRECT) + { + SelectObject(hdc,oldfont); + rect->right = rect->left + blit_r.right - blit_r.left; + rect->bottom = rect->top + blit_r.bottom - blit_r.top; + +#ifdef _WIN32 + if (wtmp!=wtmpbuf)free(wtmp); +#endif + return rv; + } + + if (!bm) return 0; + + // if noclip, resize up + if (dtFlags&DT_NOCLIP) + { + w=blit_r.right-blit_r.left; + h=blit_r.bottom-blit_r.top; + } + + // set new width/height (if shrinking down) + if (blit_r.right-blit_r.left < w) + { + if (dtFlags & DT_RIGHT) blitPos.x = w-(blit_r.right-blit_r.left); + else if (dtFlags & DT_CENTER) blitPos.x=(w-(blit_r.right-blit_r.left))/2; + + w=blit_r.right-blit_r.left; + } + if (blit_r.bottom-blit_r.top < h) + { + if (dtFlags & DT_BOTTOM) blitPos.y = h-(blit_r.bottom-blit_r.top); + else if (dtFlags & DT_VCENTER) blitPos.y=(h-(blit_r.bottom-blit_r.top))/2; + + h=blit_r.bottom-blit_r.top; + } + + if (w > s_nativerender_tempbitmap.getWidth() || + h > s_nativerender_tempbitmap.getHeight()) + { + SelectObject(hdc,oldfont); + s_nativerender_tempbitmap.resize(w, h); + hdc = s_nativerender_tempbitmap.getDC(); + oldfont = SelectObject(hdc, m_font); + } + + blit_r.left=rect->left + blitPos.x; + blit_r.top = rect->top + blitPos.y; + blit_r.right = blit_r.left+w; + blit_r.bottom = blit_r.top+h; + LICE_Blit(&s_nativerender_tempbitmap, bm, 0, 0, &blit_r, 1.0f, LICE_BLIT_MODE_COPY); + srcr.right=w; + srcr.bottom=h; + } + else + { + oldfont = SelectObject(hdc, m_font); + srcr = *rect; + } + + ::SetTextColor(hdc,RGB(LICE_GETR(m_fg),LICE_GETG(m_fg),LICE_GETB(m_fg))); + ::SetBkMode(hdc,m_bgmode); + if (m_bgmode==OPAQUE) ::SetBkColor(hdc,RGB(LICE_GETR(m_bg),LICE_GETG(m_bg),LICE_GETB(m_bg))); + + int ret = +#ifdef _WIN32 + wtmp ? + ::DrawTextW(hdc,wtmp,-1,&srcr,dtFlags|DT_NOPREFIX) + : +#endif + ::DrawText(hdc,str,strcnt,&srcr,dtFlags|DT_NOPREFIX); + + if (isTmp) LICE_Blit(bm, &s_nativerender_tempbitmap, rect->left+blitPos.x, rect->top+blitPos.y, &srcr, m_alpha, LICE_BLIT_MODE_COPY); + else if (dtFlags & DT_CALCRECT) *rect = srcr; + + + SelectObject(hdc, oldfont); +#ifdef _WIN32 + if (wtmp!=wtmpbuf) free(wtmp); +#endif + return ret; + } + + + if (dtFlags & DT_CALCRECT) + { + int xpos=0; + int ypos=0; + int max_xpos=0; + int max_ypos=0; + while (*str && strcnt) + { + unsigned short c=' '; + int charlen = utf8char(str,&c); + str += charlen; + if (strcnt>0) + { + strcnt -= charlen; + if (strcnt<0) strcnt=0; + } + + if (c == '\r') continue; + if (c == '\n') + { + if (dtFlags & DT_SINGLELINE) c=' '; + else + { + if (m_flags&LICE_FONT_FLAG_VERTICAL) + { + xpos+=m_line_height+m_lsadj; + ypos=0; + } + else + { + ypos+=m_line_height+m_lsadj; + xpos=0; + } + continue; + } + } + + charEnt *ent = findChar(c); + if (!ent) + { + int os=m_extracharlist.GetSize(); + RenderGlyph(c); + if (m_extracharlist.GetSize()!=os) + ent = findChar(c); + } + + if (ent && ent->base_offset>=0) + { + if (ent->base_offset == 0) RenderGlyph(c); + + if (ent->base_offset > 0) + { + if (m_flags&LICE_FONT_FLAG_VERTICAL) + { + ypos += ent->advance; + if (xpos+ent->width>max_xpos) max_xpos=xpos+ent->width; + if (ypos>max_ypos) max_ypos=ypos; + } + else + { + xpos += ent->advance; + if (ypos+ent->height>max_ypos) max_ypos=ypos+ent->height; + if (xpos>max_xpos) max_xpos=xpos; + } + } + } + } + + rect->right = rect->left+max_xpos; + rect->bottom = rect->top+max_ypos; + + + return (m_flags&LICE_FONT_FLAG_VERTICAL) ? max_xpos : max_ypos; + } + float alphaSave = m_alpha; + + if (dtFlags & LICE_DT_USEFGALPHA) + { + m_alpha *= LICE_GETA(m_fg)/255.0; + } + + if (m_alpha==0.0) + { + m_alpha=alphaSave; + return 0; + } + + + RECT use_rect=*rect; + int xpos=use_rect.left; + int ypos=use_rect.top; + + bool isVertRev = false; + if ((m_flags&(LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP)) == (LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP)) + isVertRev=true; + + if (dtFlags & (DT_CENTER|DT_VCENTER|DT_RIGHT|DT_BOTTOM)) + { + RECT tr={0,}; + DrawTextImpl(bm,str,strcnt,&tr,DT_CALCRECT|(dtFlags & DT_SINGLELINE)|(forceWantAlpha?LICE_DT_NEEDALPHA:0)); + if (dtFlags & DT_CENTER) + { + xpos += (use_rect.right-use_rect.left-tr.right)/2; + } + else if (dtFlags & DT_RIGHT) + { + xpos = use_rect.right - tr.right; + } + + if (dtFlags & DT_VCENTER) + { + ypos += (use_rect.bottom-use_rect.top-tr.bottom)/2; + } + else if (dtFlags & DT_BOTTOM) + { + ypos = use_rect.bottom - tr.bottom; + } + if (isVertRev) + ypos += tr.bottom; + } + else if (isVertRev) + { + RECT tr={0,}; + DrawTextImpl(bm,str,strcnt,&tr,DT_CALCRECT|(dtFlags & DT_SINGLELINE)|(forceWantAlpha?LICE_DT_NEEDALPHA:0)); + ypos += tr.bottom; + } + + + int start_y=ypos; + int start_x=xpos; + int max_ypos=ypos; + int max_xpos=xpos; + + if (!(dtFlags & DT_NOCLIP)) + { + if (use_rect.left<0)use_rect.left=0; + if (use_rect.top<0) use_rect.top=0; + if (use_rect.right > bm->getWidth()) use_rect.right = bm->getWidth(); + if (use_rect.bottom > bm->getHeight()) use_rect.bottom = bm->getHeight(); + if (use_rect.right <= use_rect.left || use_rect.bottom <= use_rect.top) + { + m_alpha=alphaSave; + return 0; + } + } + else + { + use_rect.left=use_rect.top=0; + use_rect.right = bm->getWidth(); + use_rect.bottom = bm->getHeight(); + } + + + // todo: handle DT_END_ELLIPSIS etc + // thought: calculate length of "...", then when pos+length+widthofnextchar >= right, switch + // might need to precalc size to make sure it's needed, though + + while (*str && strcnt) + { + unsigned short c=' '; + int charlen = utf8char(str,&c); + str += charlen; + if (strcnt>0) + { + strcnt -= charlen; + if (strcnt<0) strcnt=0; + } + if (c == '\r') continue; + if (c == '\n') + { + if (dtFlags & DT_SINGLELINE) c=' '; + else + { + if (m_flags&LICE_FONT_FLAG_VERTICAL) + { + xpos+=m_line_height+m_lsadj; + ypos=start_y; + } + else + { + ypos+=m_line_height+m_lsadj; + xpos=start_x; + } + continue; + } + } + + charEnt *ent = findChar(c); + if (!ent) + { + int os=m_extracharlist.GetSize(); + RenderGlyph(c); + if (m_extracharlist.GetSize()!=os) + ent = findChar(c); + } + + if (ent && ent->base_offset>=0) + { + if (ent->base_offset==0) RenderGlyph(c); + + if (ent->base_offset > 0 && ent->base_offset < m_cachestore.GetSize()) + { + if (isVertRev) ypos -= ent->height; + + bool drawn = DrawGlyph(bm,c,xpos,ypos,&use_rect); + + if (m_flags&LICE_FONT_FLAG_VERTICAL) + { + if (!isVertRev) + { + ypos += ent->advance; + } + else ypos += ent->height - ent->advance; + if (drawn && xpos+ent->width > max_xpos) max_xpos=xpos; + } + else + { + xpos += ent->advance; + if (drawn && ypos+ent->height>max_ypos) max_ypos=ypos+ent->height; + } + } + } + } + + m_alpha=alphaSave; + return (m_flags&LICE_FONT_FLAG_VERTICAL) ? max_xpos - start_x : max_ypos - start_y; +} diff --git a/WDL/lice/makedist.bat b/WDL/lice/makedist.bat new file mode 100644 index 00000000..124c3cc7 --- /dev/null +++ b/WDL/lice/makedist.bat @@ -0,0 +1,2 @@ +del lice001.zip +zip -X9r lice001.zip . -i *.cpp *.c *.h *.rc *.ds? *.bmp *.png diff --git a/WDL/lice/test/Controller.h b/WDL/lice/test/Controller.h new file mode 100644 index 00000000..1256c094 --- /dev/null +++ b/WDL/lice/test/Controller.h @@ -0,0 +1,9 @@ +/* Controller */ + +#import + +@interface Controller : NSObject +{ +} +-(void)awakeFromNib; +@end diff --git a/WDL/lice/test/Controller.mm b/WDL/lice/test/Controller.mm new file mode 100644 index 00000000..84c418e0 --- /dev/null +++ b/WDL/lice/test/Controller.mm @@ -0,0 +1,40 @@ +#import "Controller.h" + +#include "../../SWELL/swell.h" +#include "../../SWELL/swell-dlggen.h" + +#include "main.cpp" // this would otherwise conflict in object name with main.m, which xcode made us. + +static HWND ccontrolCreator(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h) +{ + if (!stricmp(classname,"TestRenderingClass")) + { + HWND hw=CreateDialog(NULL,0,parent,(DLGPROC)testRenderDialogProc); + SetWindowLong(hw,GWL_ID,idx); + SetWindowPos(hw,HWND_TOP,x,y,w,h,SWP_NOZORDER|SWP_NOACTIVATE); + ShowWindow(hw,SW_SHOWNA); + return hw; + } + return 0; +} + +@implementation Controller +-(void)awakeFromNib +{ + SWELL_RegisterCustomControlCreator(ccontrolCreator); + HWND h=CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,dlgProc); + ShowWindow(h,SW_SHOW); +} +@end + + +// define our dialog box resource! + +SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG1,SWELL_DLG_WS_RESIZABLE|SWELL_DLG_WS_FLIPPED,"LICE Test",400,300,1.8) +BEGIN +CONTROL "",IDC_RECT,"TestRenderingClass",0,7,23,384,239 // we arae creating a custom control here because it will be opaque and therefor a LOT faster drawing +COMBOBOX IDC_COMBO1,7,7,181,170,CBS_DROPDOWNLIST | WS_VSCROLL | +WS_TABSTOP + +END +SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG1) \ No newline at end of file diff --git a/WDL/lice/test/English.lproj/InfoPlist.strings b/WDL/lice/test/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..997688e2fd53fd8d44166a1895730ea43ed42f47 GIT binary patch literal 202 zcmW-ZOAf&R6h+V2DjLH^R7?!S$b{#$5lbf^EkLAW3{7RTh oDE+A9pSg65nVdc!``%jXwyDfqOK2p + + + + IBDocumentLocation + 110 86 356 240 0 0 1440 878 + IBEditorPositions + + 29 + 109 299 338 44 0 0 1440 878 + + IBFramework Version + 446.1 + IBOpenObjects + + 29 + + IBSystem Version + 8R2232 + + diff --git a/WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib b/WDL/lice/test/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..21c91cb50aaa0a1ae9a0d9aa67cc97b7694c8b95 GIT binary patch literal 13648 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 I@6gQu0ZEVR#sB~S literal 0 HcmV?d00001 diff --git a/WDL/lice/test/Info.plist b/WDL/lice/test/Info.plist new file mode 100644 index 00000000..abca571a --- /dev/null +++ b/WDL/lice/test/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.test + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/WDL/lice/test/fly.cpp b/WDL/lice/test/fly.cpp new file mode 100644 index 00000000..93f8e4e3 --- /dev/null +++ b/WDL/lice/test/fly.cpp @@ -0,0 +1,286 @@ +#include "../lice.h" +#include "../../plush2/plush.h" + +#ifndef _WIN32 +#include "../../swell/swell.h" +#endif + + +/* Physical size of land */ +#define LAND_SIZE 65000 +/* Number of divisions of the land. Higher number == more polygons */ +#define LAND_DIV 32 + + // These are the amount the mouse has moved since the last frame + // mouse_b = button status, mouse_avail is whether or not mouse is + // available, mouse_buttons is number of buttons +static float mouse_sens = 8192.0/32768.0; + +static int draw_sky = 1; // do we draw the sky? +static int wait_vsync = 0; // do we wait for vsync? +static pl_Mat *mat[3+1]; // our materials, we have 1 extra for null + // termination for plMatMakeOptPal2() +static pl_Cam *cam; // our camera +static pl_Obj *land; // the land object +static pl_Obj *sky, *sky2; // the two skies +static pl_Light lights[16]; + +static void setup_materials(pl_Mat **mat); + // Sets up the landscape and skies +static pl_Obj *setup_landscape(pl_Mat *m, pl_Mat *sm, pl_Mat *sm2); + +void doFlyEffect(LICE_IBitmap *fb, HWND hwnd) +{ + static int initted; + if (!initted) + { + initted=1; + cam = new pl_Cam; + cam->Fov=90.0; + cam->WantZBuffer=true; + if (cam->WantZBuffer) cam->Sort = -1; + cam->Y = 800; // move the camera up from the ground + cam->Pitch = 180.0; + + setup_materials(mat); // intialize materials and palette + + land = setup_landscape(mat[0],mat[1],mat[2]); // create landscape + sky = land->Children.Get(0); // unhierarchicalize the sky from the land + land->Children.Delete(0); + sky2 = land->Children.Get(0); + land->Children.Delete(0); + + int x; + for(x=0;xBegin(fb); + + int x; + for(x=0;xRenderLight(&lights[x]); + + // lots of rendering special casing + if (draw_sky) { // if we're drawing the sky + if (cam->Y > 2000) { // if above the sky, only render the skies, with + // no far clip plane + + cam->RenderObject(sky); + cam->RenderObject(sky2); + } else { // otherwise, render the sky (but not the second sky), + // and the land, with a far clip plane + + + cam->RenderObject(sky); + cam->RenderObject(land); + } + } else { // not drawing sky, just render the land + + cam->RenderObject(land); + } + cam->End(); // finish rendering + + static POINT lpos; + POINT p; + GetCursorPos(&p); + int mouse_x = 0; + int mouse_y = 0; + int mouse_b=0; + + if (hwnd) + { + mouse_x = p.x-lpos.x; + mouse_y = p.y-lpos.y; + if (GetAsyncKeyState(VK_RBUTTON)&0x8000) mouse_b|=2; + + RECT r; + GetWindowRect(hwnd,&r); + p.x=(r.right+r.left)/2; + p.y=(r.bottom+r.top)/2; + SetCursorPos(p.x,p.y); + } + lpos=p; + // We calculate the amount of time in thousanths of seconds this frame took + double prevtime = 10; //((uclock() / (float) UCLOCKS_PER_SEC) - prevtime)*1000.0; + + if (mouse_b & 2) { // if right button hit, we go forward quickly + cam->X -= + prevtime*4*sin(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); + cam->Z += + prevtime*4*cos(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); + cam->Y += + prevtime*4*sin(cam->Pitch*PL_PI/180.0); + } else if (mouse_b & 1) { // if left button hit, we go forward slowly + cam->X -= + prevtime*2*sin(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); + cam->Z += + prevtime*2*cos(cam->Pan*PL_PI/180.0)*cos(cam->Pitch*PL_PI/180.0); + cam->Y += + prevtime*2*sin(cam->Pitch*PL_PI/180.0); + } + cam->Pitch += (mouse_y*mouse_sens); // update pitch and pan of ship + cam->Pan += (mouse_x*mouse_sens)*(-cos(cam->Pitch*PL_PI/180.0)); + + if (cam->X > LAND_SIZE/2) cam->X = LAND_SIZE/2; // make sure we don't go + if (cam->X < -LAND_SIZE/2) cam->X = -LAND_SIZE/2; // too far away + if (cam->Z > LAND_SIZE/2) cam->Z = LAND_SIZE/2; + if (cam->Z < -LAND_SIZE/2) cam->Z = -LAND_SIZE/2; + if (cam->Y < 0) cam->Y = 0; + if (cam->Y > 8999) cam->Y = 8999; +#if 0 + + while (kbhit()) switch(getch()) { // handle keystrokes + case 27: done++; break; // ESC == quit + // + is for zooming in. + case '=': case '+': cam->Fov -= 1.0; if (cam->Fov < 1.0) cam->Fov = 1.0; + sprintf(lastmessage,"FOV: %2.f",cam->Fov); + break; + // - is for zooming out + case '-': cam->Fov += 1.0; if (cam->Fov > 179.0) cam->Fov = 179.0; + sprintf(lastmessage,"FOV: %2.f",cam->Fov); + break; + // [ decreases mouse sensitivity + case '[': mouse_sens /= 1.1; + sprintf(lastmessage,"MouseSens: %.3f",mouse_sens); + break; + // ] increases mouse sensitivity + case ']': mouse_sens *= 1.1; + sprintf(lastmessage,"MouseSens: %.3f",mouse_sens); + break; + // v toggles vsync + case 'v': wait_vsync ^= 1; + sprintf(lastmessage,"VSync %s",wait_vsync ? "on" : "off"); + break; + // s toggles sky + case 's': draw_sky ^= 1; + sprintf(lastmessage,"Sky %s",draw_sky ? "on" : "off"); + break; + } +#endif + + //LICE_ScaledBlit(fb,mat[2]->Texture,0,0,fb->getWidth(),fb->getHeight(),0,0,mat[2]->Texture->getWidth(),mat[2]->Texture->getHeight(),1.0f,0); +} + + + + +static void setup_materials(pl_Mat **mat) { + // create our 3 materials, make the fourth null so that plMatMakeOptPal2() + // knows where to stop + mat[0] = new pl_Mat; + mat[1] = new pl_Mat; + mat[2] = new pl_Mat; + mat[3] = 0; + + extern LICE_IBitmap *bmp; + // set up material 0 (the ground) + mat[0]->Smoothing = true; + mat[0]->Lightable=true; + mat[0]->Ambient[0] = 0.0; // these calculations are to get the + mat[0]->Ambient[1] = 0.0; // distance shading to work right + mat[0]->Ambient[2] = 0.0; + mat[0]->Diffuse[0] = 1.0; + mat[0]->Diffuse[1] = 1.0; + mat[0]->Diffuse[2] = 1.0; + mat[0]->FadeDist = 10000.0; + mat[0]->Texture2 = LICE_LoadPCX("c:\\ground.pcx"); + if (!mat[0]->Texture2) + { + mat[0]->Texture2 = new LICE_MemBitmap(400,400); +// LICE_TexGen_Marble(mat[0]->Texture2,NULL,1.0,0.8,0.8,1.0f); + LICE_TexGen_Noise(mat[0]->Texture2,NULL,1.0,1.0,1.0,1.0f,NOISE_MODE_WOOD,8); + } + + mat[0]->Texture=mat[0]->Texture2; + mat[0]->Texture2=bmp; + mat[0]->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; + mat[0]->Tex2CombineMode=LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR; + mat[0]->Tex2Scaling[1]= + mat[0]->Tex2Scaling[0] = 40.0*LAND_SIZE/50000; + mat[0]->TexScaling[1]= + mat[0]->TexScaling[0] = 40.0*LAND_SIZE/50000; + mat[0]->Tex2MapIdx=0; + mat[0]->PerspectiveCorrect = 16; + mat[0]->BackfaceIllumination=1.0; + + // set up material 1 (the sky) + mat[1]->Lightable=true; + mat[1]->Ambient[0] = 0.4; // these calculations are to get the + mat[1]->Ambient[1] = 0.4; // distance shading to work right + mat[1]->Ambient[2] = 0.4; + mat[1]->Diffuse[0] = 1.0; + mat[1]->Diffuse[1] = 1.0; + mat[1]->Diffuse[2] = 1.0; + mat[1]->FadeDist = 10000.0; + mat[1]->Texture = LICE_LoadPCX("c:\\sky.pcx"); + mat[1]->TexCombineMode=LICE_BLIT_MODE_MUL; + mat[1]->TexScaling[1] = mat[1]->TexScaling[0] = 45.0*LAND_SIZE/50000; + mat[1]->PerspectiveCorrect = 32; + mat[1]->BackfaceCull=false; + mat[1]->BackfaceIllumination=1.0; + + if (!mat[1]->Texture) + { + mat[1]->Texture = new LICE_MemBitmap(400,400); + LICE_TexGen_Noise(mat[1]->Texture,NULL,0.0,0.0,1.0,1.0f,NOISE_MODE_WOOD,8); + } + mat[1]->Texture2=bmp; + mat[1]->Tex2CombineMode= LICE_BLIT_MODE_HSVADJ|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA; + mat[1]->Tex2Scaling[1] = mat[1]->Tex2Scaling[0] = 45.0*LAND_SIZE/50000*0.37; + mat[1]->Tex2MapIdx=0; + + // set up material 2 (the second sky) + mat[2]->Lightable=true; + mat[2]->Smoothing=false; + mat[2]->Ambient[0] = 0.2; // these calculations are to get the + mat[2]->Ambient[1] = 0.2; // distance shading to work right + mat[2]->Ambient[2] = 0.2; + mat[2]->Diffuse[0] = 0.0; + mat[2]->Diffuse[1] = 0.0; + mat[2]->Diffuse[2] = 0.0; + mat[2]->Texture = LICE_LoadPCX("c:\\sky2.pcx"); + if (!mat[2]->Texture) + { + mat[2]->Texture = new LICE_MemBitmap(400,400); + LICE_TexGen_Marble(mat[2]->Texture,NULL,0.3,0,0.4,0.4); + } + mat[2]->TexScaling[0] = mat[2]->TexScaling[1] = 10.0; //200.0*LAND_SIZE/50000; + mat[2]->TexCombineMode=LICE_BLIT_MODE_COPY; + mat[2]->PerspectiveCorrect = 16; + + mat[2]->Texture2=bmp; + mat[2]->Tex2CombineMode= LICE_BLIT_MODE_HSVADJ|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA; + mat[2]->Tex2Scaling[1] = mat[1]->Tex2Scaling[0] = 45.0*LAND_SIZE/50000*3.37; + mat[2]->Tex2MapIdx=0; + +} + +pl_Obj *setup_landscape(pl_Mat *m, pl_Mat *sm, pl_Mat *sm2) { + int i; + // make our root object the land + pl_Obj *o = plMakePlane(LAND_SIZE,LAND_SIZE,LAND_DIV-1,m); + // give it a nice random bumpy effect + for (i = 0; i < o->Vertices.GetSize(); i ++) + o->Vertices.Get()[i].y += (float) (rand()%1400)-700; + // gotta recalculate normals for backface culling to work right + o->CalculateNormals(); + + // Make our first child the first sky + o->Children.Add(plMakePlane(LAND_SIZE,LAND_SIZE,30,sm)); + o->Children.Get(0)->Yp = 2000; + + // and the second the second sky + o->Children.Add(plMakeSphere(LAND_SIZE,10,10,sm2)); + o->Children.Get(1)->Yp = 2000; + o->Children.Get(1)->FlipNormals(); + + return (o); +} + diff --git a/WDL/lice/test/image.png b/WDL/lice/test/image.png new file mode 100644 index 0000000000000000000000000000000000000000..ae855918e8c8a4f00eaf76e31df45bdfc43976fc GIT binary patch literal 4910 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 literal 0 HcmV?d00001 diff --git a/WDL/lice/test/imgs2gif.cpp b/WDL/lice/test/imgs2gif.cpp new file mode 100644 index 00000000..4d270a0b --- /dev/null +++ b/WDL/lice/test/imgs2gif.cpp @@ -0,0 +1,100 @@ +#include +#include + +#include "../lice.h" + +void usage(const char *a, const char *b) +{ + if (a||b) printf("%s: %s\n",a,b); + printf("Usage: imgs2gif [-w width] [-h height] [-d ms] [-skipempty] [-leaddelay ms] output.gif file1.jpg [file2.png ...]\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int delay=10; + int size_w=0,size_h=0; + int i; + int rv=0; + int leaddelay=0; + bool skipempty=false; + void *gifOut=NULL; + const char *fn=NULL; + + LICE_MemBitmap lastfr, fr,fr2; + int accum_lat=0; + + for (i=1;i= argc) usage("Missing parameter",argv[i-1]); + size_w = atoi(argv[i]); + } + else if (!strcmp(argv[i],"-h")) + { + if (++i >= argc) usage("Missing parameter",argv[i-1]); + size_h = atoi(argv[i]); + } + else if (!strcmp(argv[i],"-d")) + { + if (++i >= argc) usage("Missing parameter",argv[i-1]); + delay = atoi(argv[i]); + } + else if (!strcmp(argv[i],"-skipempty")) skipempty=true; + else if (!strcmp(argv[i],"-leaddelay")) + { + if (++i >= argc) usage("Missing parameter",argv[i-1]); + leaddelay=atoi(argv[i]); + } + else usage("Unknown option",argv[i]); + } + else if (!fn) fn=argv[i]; + else + { + printf("Loading %s\n",argv[i]); + if (!LICE_LoadImage(argv[i],&fr) || !fr.getWidth() || !fr.getHeight()) + { + printf("Error loading image: %s\n",argv[i]); + continue; + } + + if (!size_w) size_w=fr.getWidth(); + if (!size_h) size_h=fr.getHeight(); + LICE_MemBitmap *usefr = &fr; + if (fr.getWidth() != size_w || fr.getHeight() != size_h) + { + fr2.resize(size_w,size_h); + LICE_ScaledBlit(usefr=&fr2,&fr,0,0,size_w,size_h,0,0,fr.getWidth(),fr.getHeight(),1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + + if (!gifOut) + { + gifOut=LICE_WriteGIFBegin(fn,usefr,0,leaddelay?leaddelay:delay,false); + if (!gifOut) usage("Error writing to file",fn); + } + else + { + accum_lat += delay; + int diffcoords[4]={0,0,size_w,size_h}; + if (LICE_BitmapCmp(usefr,&lastfr,diffcoords)) + { + LICE_SubBitmap bm(usefr,diffcoords[0],diffcoords[1], diffcoords[2],diffcoords[3]); + LICE_WriteGIFFrame(gifOut,&bm,diffcoords[0],diffcoords[1], true, accum_lat); + accum_lat=0; + } + if (skipempty) accum_lat=0; + } + + LICE_Copy(&lastfr,usefr); + } + } + printf("finishing up\n"); + if (gifOut) LICE_WriteGIFEnd(gifOut); + + return rv; +} diff --git a/WDL/lice/test/main.cpp b/WDL/lice/test/main.cpp new file mode 100644 index 00000000..8e48bee0 --- /dev/null +++ b/WDL/lice/test/main.cpp @@ -0,0 +1,1026 @@ +/* + Cockos WDL - LICE - Lightweight Image Compositing Engine + Copyright (C) 2007 and later, Cockos Incorporated + File: main.cpp (example use of LICE) + See lice.h for license and other information +*/ + +#include "../lice.h" +#include "../../plush2/plush.h" +#include "../../MersenneTwister.h" +#include +#include + +#include "../lice_text.h" + +#include "../lice_glbitmap.h" +//#define GLEW_STATIC +//#include "../glew/include/gl/glew.h" +//#include "../glew/include/gl/wglew.h" + +//uncomment this to enable the ffmpeg video output in test 1 +//#define FFMPEG_TEST + +//#define TIMING +#include "../../timing.c" + +#ifdef FFMPEG_TEST +//ffmpeg encoding test +#include "../../ffmpeg.h" +#pragma comment(lib, "../../../sdks/ffmpeg/lib/avcodec.lib") +#pragma comment(lib, "../../../sdks/ffmpeg/lib/avformat.lib") +#pragma comment(lib, "../../../sdks/ffmpeg/lib/avutil.lib") +#pragma comment(lib, "../../../sdks/ffmpeg/lib/swscale.lib") +static WDL_VideoEncode *m_encoder; +static WDL_VideoDecode *m_decoder; +#endif + +#include "resource.h" + +#define NUM_EFFECTS 25 + +char *effect_names[NUM_EFFECTS] = +{ + "Rotated + Scaled blit", + "Simple alpha blit", + "Rotated blit", + "Scaled blit", + "GradRect", + "Marble generator", + "Wood generator", + "Noise generator", + "Circular noise generator", + "GradRect + text + rotated blit", + "PutPixel", + "Line", + "DrawText", + "Icon loading", + "Circles, Arc", + "Rotated + Multiply add blit", + "Transform blit", + "Plush 3D", + "3D Fly (use mouse)", + "SVG loading (C:\\test.svg)", + "GL acceleration (disabled)", + "Bezier curves", + "Convex polygon fill", + "Palette generator (C:\\test.png)", + "Triangle test", +}; + +HINSTANCE g_hInstance; +LICE_IBitmap *jpg; +LICE_IBitmap *bmp; +LICE_IBitmap *icon; +LICE_IBitmap *framebuffer; +static int m_effect = NUM_EFFECTS-1; +static int m_doeff = 0; + +static LICE_IBitmap* tmpbmp = 0; + +static DWORD m_start_time, m_frame_cnt; +bool m_cap; + + +static void DoPaint(HWND hwndDlg) +{ + PAINTSTRUCT ps; + + HDC dc = BeginPaint(hwndDlg, &ps); + RECT r; + GetClientRect(hwndDlg, &r); + +#ifdef _WIN32 + r.top+=40; + if (r.top >= r.bottom) r.top=r.bottom-1; +#endif + + if (framebuffer->resize(r.right-r.left,r.bottom-r.top)) + { + m_doeff=1; + // memset(framebuffer->getBits(),0,framebuffer->getWidth()*framebuffer->getHeight()*4); + } + + int x=rand()%(r.right+300)-150; + int y=rand()%(r.bottom+300)-150; + + static int s_preveff = -1; + if (m_effect != s_preveff) + { + s_preveff = m_effect; + LICE_Clear(framebuffer, 0); + } + + static MTRand s_rng; + + switch(m_effect) + { + case 23: + { + const int palnumcols=256; + + static int init=0; + static LICE_IBitmap* srcbmp=0; + static LICE_IBitmap* palbmp=0; + static LICE_pixel palette[palnumcols] = { 0 }; + + if (!init) + { + init=-1; + srcbmp = LICE_LoadPNG("C:\\test.png"); + if (srcbmp) + { + int n = LICE_BuildPalette(srcbmp, palette, palnumcols); + palbmp = new LICE_MemBitmap; + LICE_Copy(palbmp, srcbmp); + void LICE_TestPalette(LICE_IBitmap*, LICE_pixel*, int); + LICE_TestPalette(palbmp, palette, n); + init=1; + } + } + + if (init > 0) + { + static int lastw=0; + static int lasth=0; + if (lastw != framebuffer->getWidth() || lasth != framebuffer->getHeight()) + { + lastw = framebuffer->getWidth(); + lasth = framebuffer->getHeight(); + int y = framebuffer->getHeight()*3/4; + LICE_ScaledBlit(framebuffer, srcbmp, 0, 0, lastw/2, y, 0, 0, srcbmp->getWidth(), srcbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(framebuffer, palbmp, lastw/2, 0, lastw/2, y, 0, 0, palbmp->getWidth(), palbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + + int dy = (lasth-y)/4; + int dx = lastw/(palnumcols/4); + int i, j, k=0; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < palnumcols/4; ++j) + { + LICE_FillRect(framebuffer, j*dx, y+i*dy, dx, dy, palette[k++], 1.0f, LICE_BLIT_MODE_COPY); + } + } + } + } + } + break; + case 24: + { + LICE_MemBitmap bm(128,128); + LICE_Clear(framebuffer,0); + LICE_Clear(&bm,0); + + static POINT sp; + POINT p; + if (!sp.x&&!sp.y) GetCursorPos(&sp); + GetCursorPos(&p); + p.x-=sp.x; + p.y-=sp.y; + int th=p.y+16; + bool flip = th < 0; + if (flip) th=-th; + int tw=p.x+16; + int cx=(tw+1)/2; + int x=1,y=1; + LICE_pixel lc=LICE_RGBA(255,0,255,255); + LICE_Line(&bm,x,y,x+tw,y,lc,1.0f,LICE_BLIT_MODE_COPY); + LICE_Line(&bm,x,y+th,x+tw,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); + LICE_Line(&bm,x+tw,y,x+tw,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); + LICE_Line(&bm,x,y,x,y+th,lc,1.0f,LICE_BLIT_MODE_COPY); + + LICE_FillTriangle(&bm,x+tw,y+(flip?th:0)/*+th/4*/,x+cx,y+(flip?0:th),x,y+(flip?th:0),LICE_RGBA(255,255,255,255),0.75f,LICE_BLIT_MODE_COPY); + + int sc=16; + LICE_ScaledBlit(framebuffer,&bm,0,0,bm.getWidth()*sc,bm.getHeight()*sc,0,0,bm.getWidth(),bm.getHeight(),1.0,LICE_BLIT_MODE_COPY); + for (y=0;ygetWidth(); + int h = framebuffer->getHeight(); + + static bool init = false; + if (!init) + { + init = true; + for (i = 0; i < 16; ++i) + { + x[i] = s_rng.randInt(w-1); + y[i] = s_rng.randInt(h-1); + } + } + + for (i = 0; i < 16; ++i) + { + x[i] += s_rng.randNorm(0.0, 1.0)+0.5; + y[i] += s_rng.randNorm(0.0, 1.0)+0.5; + if (x[i] < 0) x[i] = 0; + else if (x[i] >= w) x[i] = w-1; + if (y[i] < 0) y[i] = 0; + else if (y[i] >= h) y[i] = h-1; + } + + LICE_Clear(framebuffer, 0); + LICE_FillConvexPolygon(framebuffer, x, y, 16, LICE_RGBA(96,96,96,255), 0.5f, LICE_BLIT_MODE_ADD); + + for (i = 0; i < 16; ++i) + { + LICE_Line(framebuffer, x[i]-1, y[i], x[i]+1, y[i], LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY); + LICE_Line(framebuffer, x[i], y[i]-1, x[i], y[i]+1, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY); + } + } + break; + + case 21: + { + int w = framebuffer->getWidth(); + int h = framebuffer->getHeight(); + + int x0, y0, x1, y1, x2, y2, x3, y3; + + bool aa = true; + float maxsegmentpx = 0.0f; + + x0 = w*rand()/RAND_MAX; + y0 = h*rand()/RAND_MAX; + x1 = w*rand()/RAND_MAX; + y1 = h*rand()/RAND_MAX; + x2 = w*rand()/RAND_MAX; + y2 = h*rand()/RAND_MAX; + LICE_DrawQBezier(framebuffer, x0, y0, x1, y1, x2, y2, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY, aa, maxsegmentpx); + + x0 = w*rand()/RAND_MAX; + y0 = h*rand()/RAND_MAX; + x1 = w*rand()/RAND_MAX; + y1 = h*rand()/RAND_MAX; + x2 = w*rand()/RAND_MAX; + y2 = h*rand()/RAND_MAX; + x3 = w*rand()/RAND_MAX; + y3 = h*rand()/RAND_MAX; + LICE_DrawCBezier(framebuffer, x0, y0, x1, y1, x2, y2, x3, y3, LICE_RGBA(0,255,0,255), 1.0f, LICE_BLIT_MODE_COPY, aa, maxsegmentpx); + } + break; + +#ifndef DISABLE_LICE_EXTENSIONS + case 20: // GL acceleration + { + int w = framebuffer->getWidth(); + int h = framebuffer->getHeight(); + + int x, y, tw, th; + + static LICE_IBitmap* glbmp = 0; + if (!glbmp) + { + glbmp = new LICE_GL_SysBitmap(0, 0); + glbmp->resize(w, h); + + glbmp = new LICE_GL_SubBitmap(glbmp, 20, 80, 50, 20); + + framebuffer = glbmp; + } + + if (!tmpbmp) + { + tmpbmp = new LICE_GL_MemBitmap(0, 0); + tmpbmp->resize(20, 20); + //tmpbmp = new LICE_MemBitmap(20, 20); + } + + LICE_Clear(tmpbmp, LICE_RGBA(255,0,0,255)); + LICE_Line(tmpbmp, 0, 0, 20, 20, LICE_RGBA(255,255,255,255), 1.0f, LICE_BLIT_MODE_COPY, true); + + static int _n = 0; + + //if (_n < 3) + { + //LICE_Clear(glbmp, LICE_RGBA(0,0,0,0)); + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + LICE_Blit(glbmp, tmpbmp, x, y, 0, 0, 20, 20, 1.0f, LICE_BLIT_MODE_COPY); // blit one GL bitmap to another + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + LICE_ScaledBlit(glbmp, tmpbmp, x, y, 40, 40, 0, 0, 20, 20, 1.0f, LICE_BLIT_MODE_COPY); // blit one GL bitmap to another + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + tw = (w-x)*rand()/RAND_MAX; + th = (h-y)*rand()/RAND_MAX; + int color = (_n%2 ? LICE_RGBA(63,63,63,255) : LICE_RGBA(0,0,0,255)); + LICE_FillRect(glbmp, x, y, tw, th, color, 1.0f, LICE_BLIT_MODE_COPY); + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + tw = (w-x)*rand()/RAND_MAX; + th = (h-y)*rand()/RAND_MAX; + LICE_Line(glbmp, x, y, x+tw, y+th, LICE_RGBA(255,0,0,255), 1.0f, LICE_BLIT_MODE_COPY, true); + + int x0 = w*rand()/RAND_MAX; + int y0 = h*rand()/RAND_MAX; + int x1 = w*rand()/RAND_MAX; + int y1 = h*rand()/RAND_MAX; + int x2 = w*rand()/RAND_MAX; + int y2 = h*rand()/RAND_MAX; + int x3 = w*rand()/RAND_MAX; + int y3 = h*rand()/RAND_MAX; + LICE_DrawCBezier(glbmp, x0, y0, x1, y1, x2, y2, x3, y3, LICE_RGBA(0,255,0,255), 1.0f, LICE_BLIT_MODE_COPY, true); + + #define A(x) ((LICE_pixel_chan)((x)*255.0+0.5)) + + LICE_pixel_chan alphas[81] = + { + A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00), + A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), + A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), + A(1.00), A(0.19), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.19), A(1.00), + A(1.00), A(0.31), A(0.00), A(0.00), A(0.00), A(0.00), A(0.00), A(0.31), A(1.00), + A(0.69), A(0.82), A(0.06), A(0.00), A(0.00), A(0.00), A(0.06), A(0.82), A(0.69), + A(0.12), A(0.94), A(0.82), A(0.31), A(0.25), A(0.31), A(0.82), A(0.94), A(0.12), + A(0.00), A(0.12), A(0.69), A(1.00), A(1.00), A(1.00), A(0.69), A(0.12), A(0.00) + }; + int gw = 9; + int gh = 9; + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + LICE_DrawGlyph(glbmp, x, y, LICE_RGBA(255,255,0,255), alphas, gw, gh, 1.0f, LICE_BLIT_MODE_COPY); + + static LICE_CachedFont* font = 0; + if (!font) + { + font = new LICE_CachedFont; + LOGFONT lf={ 12, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial"}; + HFONT hf = CreateFontIndirect(&lf); + font->SetFromHFont(hf, 0); + font->SetTextColor(LICE_RGBA(255,255,0,255)); + } + + x = w*rand()/RAND_MAX; + y = h*rand()/RAND_MAX; + RECT r = { x, y, x+40, y+10 }; + font->DrawText(glbmp, "foo bar", -1, &r, 0); + + } + ++_n; + } + break; +#endif + + case 18: + { + void doFlyEffect(LICE_IBitmap *fb,HWND); + doFlyEffect(framebuffer,m_cap ? hwndDlg : NULL); + } + break; + + case 17: + { + static pl_Obj *obj=NULL,*obj2=NULL; + if (!obj) + { + pl_Mat *mat = new pl_Mat; + pl_Mat *mat2 = new pl_Mat; + + mat2->Smoothing=false; + mat2->Ambient[0]=mat2->Ambient[1]=mat2->Ambient[2]=0.0; + mat2->Diffuse[0]=mat2->Diffuse[1]=0.6; + mat2->Diffuse[2]=1.0; + + mat->Ambient[0]=mat->Ambient[1]=mat->Ambient[2]=0.0; + mat->Diffuse[0]=mat->Diffuse[1]=1.9; + mat->Diffuse[2]=0.4; + + mat->PerspectiveCorrect=16; + mat->SolidCombineMode=LICE_BLIT_MODE_COPY; + mat->SolidOpacity=1.0; + mat->Smoothing=true; + mat->Lightable=true; + //mat->FadeDist = 300.0; + + mat2->Texture=bmp; + mat2->TexOpacity=0.5; + mat2->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; + mat2->SolidOpacity=0.4; + mat2->BackfaceCull=false; + mat2->BackfaceIllumination=1.0; + + mat->Texture=bmp; + LICE_TexGen_Marble(mat->Texture = new LICE_MemBitmap(r.right,r.bottom),NULL,0.3,0.4,0.0,1.0f); + + mat->TexOpacity=0.5; + mat->TexScaling[0]=mat->TexScaling[1]=3.0; + mat->TexCombineMode=LICE_BLIT_MODE_MUL|LICE_BLIT_FILTER_BILINEAR; + + LICE_TexGen_Noise(mat->Texture2 = new LICE_MemBitmap(r.right,r.bottom),NULL,0.3,0.4,0.0,1.0f); + // mat->Texture2=icon; + mat->Tex2MapIdx=-1; + mat->Tex2CombineMode=LICE_BLIT_MODE_ADD|LICE_BLIT_FILTER_BILINEAR; + mat->Tex2Opacity=0.8; + mat->Tex2Scaling[0]=2.0; + mat->Tex2Scaling[1]=-2.0; + + mat->BackfaceCull=true; + mat->BackfaceIllumination=0.0; + + obj=plMakeTorus(100.0,80.0,40,40,mat); + + int x; + if (0)for(x=1;x<3;x++) + { + pl_Obj *no = obj->Clone(); + no->Translate(0,40.0,-x*35.0); + obj->Children.Add(no); + no->Xa += 50.35*x; + no->Ya -= 30.13*x; + } + obj2=plMakeBox(130,130,130,mat2); + + /*pl_Obj *o = plRead3DSObj("c:\\temp\\suzanne.3ds",mat); + if (o) + { + o->Scale(30.0); + o->Translate(150.0,0,0); + obj->Children.Add(o); + } + */ + } + obj2->Xa+=0.3; + obj2->Ya+=-0.1; + obj->Ya+=0.1; + obj->Xa+=0.1; + obj->Za+=0.1; + obj->GenMatrix=true; + + if (1) LICE_Clear(framebuffer,0); + else { + double a=GetTickCount()/1000.0; + + double scale=(1.1+sin(a)*0.3); + + LICE_RotatedBlit(framebuffer,framebuffer,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,254/255.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + static pl_Cam cam; + LICE_SubBitmap tmpbm(framebuffer,10,10,framebuffer->getWidth()-20,framebuffer->getHeight()-20); + //cam.CenterX = (tmpbm.getWidth()/2+80); + //cam.CenterY = (tmpbm.getHeight()/2+80); + cam.AspectRatio = 1.0;//cam.frameBuffer->getWidth()* 3.0/4.0 / (double)cam.frameBuffer->getHeight(); + cam.X = cam.Y = 0.0; + cam.Z = -200.0; + cam.WantZBuffer=true; + cam.SetTarget(0,0,0); + + + + static pl_Light light; + light.Set(PL_LIGHT_POINT,500.0,0,-900.0,1.3f,0.5f,0.5f,1000.0); + static pl_Light light2; + light2.Set(PL_LIGHT_POINT,-500.0,0,-700.0,0.0f,1.0f,0.5f,1000.0); + cam.ClipBack=220.0; + + cam.Begin(&tmpbm); + cam.RenderLight(&light); + cam.RenderLight(&light2); + cam.RenderObject(obj); + cam.SortToCurrent(); + cam.RenderObject(obj2); + cam.End(); + + char buf[512]; + sprintf(buf,"tri: %d->%d->%d, pix=%.0f", + cam.RenderTrisIn, + cam.RenderTrisCulled, + cam.RenderTrisOut,cam.RenderPixelsOut); + LICE_DrawText(framebuffer,0,10,buf,LICE_RGBA(255,255,255,255),1.0f,0); + + } + break; + case 15: + case 0: + { + double a=.51;//GetTickCount()/1000.0; + + double scale=(1.1+sin(a)*0.3); + + if (0) // weirdness + { + LICE_RotatedBlit(framebuffer,framebuffer,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,254/255.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + else // artifact-free mode + { + LICE_MemBitmap framebuffer_back; + + LICE_Copy(&framebuffer_back,framebuffer); + LICE_RotatedBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,0+sin(a*0.3)*16.0,0+sin(a*0.21)*16.0,r.right,r.bottom,cos(a*0.5)*0.13,false,1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + timingEnter(0); + LICE_ScaledBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,-200,-200,3000,3000,0.1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + timingLeave(0); + timingEnter(1); + LICE_ScaledBlit(framebuffer,&framebuffer_back,0,0,r.right,r.bottom,0,0,r.right/2,r.bottom/2,0.1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + timingLeave(1); + } + //LICE_Clear(framebuffer,0); + if (bmp) LICE_RotatedBlit(framebuffer,bmp,r.right*scale,r.bottom*scale,r.right*(1.0-scale*2.0),r.bottom*(1.0-scale*2.0),0,0,bmp->getWidth(),bmp->getHeight(),cos(a*0.3)*13.0,false,0.3,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR); + + if (m_effect==15) + { + LICE_MultiplyAddRect(framebuffer,0,0,framebuffer->getWidth(),framebuffer->getHeight(),0.9,0.9,-0.3,1, + 3,2,200,0); + } + + +#ifdef FFMPEG_TEST + +#if 0 + //ffmpeg encoding test + if(!m_encoder) m_encoder = new WDL_VideoEncode("flv", framebuffer->getWidth(),framebuffer->getHeight(), 25, 1256, NULL, 44100, 1, 128); + if(m_encoder->isInited()) + { + //set the alpha bit to 0xff + //LICE_FillRect(framebuffer, 0, 0, framebuffer->getWidth(), framebuffer->getHeight(), LICE_RGBA(0,0,0,255), 1.0f, LICE_BLIT_MODE_ADD); + m_encoder->encodeVideo(framebuffer->getBits()); + + static short audiodata[2000]={0,}; + static int initaudio=0; + if(!initaudio) + { + float t = 0; + for(int j=0;j<2000;j++) + { + audiodata[j] = (int)(sin(t) * 10000); + t += 2 * M_PI * 440.0 / 44100; + } + initaudio = 1; + } + m_encoder->encodeAudio(audiodata, 44100/25); + + static WDL_HeapBuf h; + h.Resize(256*1024); + unsigned char *p = (unsigned char *)h.Get(); + int s = m_encoder->getBytes(p, 256*1024); + if(s) + { + FILE *fh = fopen("c:\\temp\\out.flv", "ab"); + fwrite(p, s, 1, fh); + fclose(fh); + } + } +#else + //ffmpeg decoding test + if(!m_decoder) m_decoder = new WDL_VideoDecode("c:\\test.avi"); + if(m_decoder->isInited()) + { + static LICE_IBitmap *m_tmpframe; + static double t = 0; + if(!m_tmpframe) + { + m_tmpframe = new LICE_MemBitmap(framebuffer->getWidth(), framebuffer->getHeight()); + } + m_decoder->GetVideoFrameAtTime(m_tmpframe, t, NULL, &t, true); + t+=0.0001; + LICE_Blit(framebuffer, m_tmpframe, 0, 0, 0, 0, m_tmpframe->getWidth(), m_tmpframe->getHeight(), 1.0f, 0); + } +#endif + +#endif + + + } + break; + case 1: + if (rand()%6==0) + LICE_Blit(framebuffer,bmp,x,y,NULL,-1.4,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA); + else + LICE_Blit(framebuffer,bmp,x,y,NULL,0.6,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + break; + case 2: + { + LICE_Clear(framebuffer,0); + double a=GetTickCount()/1000.0; + + double scale=(1.1+sin(a)*0.3); + if (bmp) LICE_RotatedBlit(framebuffer,bmp,r.right*scale,r.bottom*scale,r.right*(1.0-scale*2.0),r.bottom*(1.0-scale*2.0),0,0,bmp->getWidth(),bmp->getHeight(),cos(a*0.3)*13.0,false,1.0,LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR,0.0,-bmp->getHeight()/2); + } + break; + case 3: + { + LICE_Clear(framebuffer,LICE_RGBA(128,128,128,128)); + static double a; + a+=0.003; + int xsize=sin(a*1.1)*r.right*10.5; + int ysize=sin(a*1.7)*r.bottom*10.5; + int xp = sin(a*0.3+1515851)*r.right*0.5; + int yp = sin(a*0.3+15853)*r.bottom*0.5; + + if (bmp) + { +// if (rand()%3==0) + // LICE_ScaledBlit(framebuffer,bmp,r.right/2-xsize/2,r.bottom/2-ysize/2,xsize,ysize,0.0,0.0,bmp->getWidth(),bmp->getHeight(),-0.7,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_ADD|LICE_BLIT_FILTER_BILINEAR); + /// else + LICE_ScaledBlit(framebuffer,bmp,xp + r.right/2-xsize/2,yp + r.bottom/2-ysize/2,xsize,ysize,-300,-300,600+bmp->getWidth(),600+bmp->getHeight(),1,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + } + break; + case 4: + case 9: + + { + static double a; + a+=0.003; + + LICE_GradRect(framebuffer,0,0,framebuffer->getWidth(),framebuffer->getHeight(), + 0.5*sin(a*14.0),0.5*cos(a*2.0+1.3),0.5*sin(a*4.0),1.0, + (cos(a*37.0))/framebuffer->getWidth()*0.5,(sin(a*17.0))/framebuffer->getWidth()*0.5,(cos(a*7.0))/framebuffer->getWidth()*0.5,0, + (sin(a*12.0))/framebuffer->getHeight()*0.5,(cos(a*4.0))/framebuffer->getHeight()*0.5,(cos(a*3.0))/framebuffer->getHeight()*0.5,0, + LICE_BLIT_MODE_COPY); + + + if (m_effect==9) + { + /* LOGFONT lf={ + 140,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, + "Times New Roman" + }; + HFONT font=CreateFontIndirect(&lf); + + */ + + + LICE_SysBitmap bm(60,60); + LICE_Clear(&bm,LICE_RGBA(0,0,0,0)); + SetTextColor(bm.getDC(),RGB(255,255,255)); + SetBkMode(bm.getDC(),TRANSPARENT); + // HGDIOBJ of=SelectObject(bm.getDC(),font); + RECT r={0,0,bm.getWidth(),bm.getHeight()}; + DrawText(bm.getDC(),"LICE",-1,&r,DT_LEFT|DT_TOP|DT_SINGLELINE); + // SelectObject(bm.getDC(),of); + // DeleteObject(font); + + LICE_Blit(&bm,&bm,0,0,NULL,1.0,LICE_BLIT_MODE_CHANCOPY|LICE_PIXEL_R|(LICE_PIXEL_A<<2)); + + int bmw=bm.getWidth(); + int bmh=bm.getHeight(); + LICE_FillRect(framebuffer,framebuffer->getWidth()/2,framebuffer->getHeight()/2,bmh,bmw,0,0.5,LICE_BLIT_MODE_COPY); + LICE_RotatedBlit(framebuffer,&bm, + framebuffer->getWidth()/2,framebuffer->getHeight()/2, + bmh,bmw,0,0,bmw,bmh, + 3.14159*0.5,false,.4,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR,-bm.getWidth()/4,-bm.getHeight()/4); + } + + break; + } + case 5: + if(m_doeff) + { + LICE_TexGen_Marble(framebuffer, NULL, 1, 1, 1, 1); + } + break; + case 6: + if(m_doeff) + { + LICE_TexGen_Noise(framebuffer, NULL, 0.9, 0.3, 0.6, 6.0f, NOISE_MODE_WOOD, 2); + } + break; + case 7: + if(m_doeff) + { + LICE_TexGen_Noise(framebuffer, NULL, 1,1,1, 8.0f, NOISE_MODE_NORMAL, 8); + } + break; + case 8: + if(m_doeff) + { + LICE_TexGen_CircNoise(framebuffer, NULL, 0.5f,0.5f,0.5f, 12.0f, 0.1f, 32); + } + break; + case 10: + { + int x; + static double a; + double sc=sin(a)*0.024; + a+=0.03; + for (x = 0; x < 10000; x ++) + LICE_PutPixel(framebuffer,rand()%framebuffer->getWidth(),rand()%framebuffer->getHeight(),LICE_RGBA(255,255,255,255),sc,LICE_BLIT_MODE_ADD); + } + break; + case 11: + //line test + { + + LICE_pixel goodCol=LICE_RGBA(192,0,192,64); + LICE_Clear(framebuffer,goodCol); + int subx=30,suby=30,subw=300,subh=300; + LICE_SubBitmap bm(framebuffer,subx,suby,subw,subh); + LICE_Clear(&bm,LICE_RGBA(80,80,80,255)); + + int n; + int w = framebuffer->getWidth(), h = framebuffer->getHeight(); + for(n=0;n<10000;n++) + { + LICE_FLine(&bm, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); + } + int y; + for(y=0;y=subx+subw||y>=suby+subh) + { + if (LICE_GetPixel(framebuffer,x,y)!=goodCol) + { + LICE_Clear(framebuffer,LICE_RGBA(255,255,255,255)); + y=h; + break; + } + } + } + } + + // LICE_Line(framebuffer, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, rand()%(w*3/2)-w/4, rand()%(h*3/2)-h/4, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); + } + break; + case 12: + //lice draw text test + { + static double a; + a+=0.001; + LICE_DrawText(framebuffer,0.5*(1+sin(a))*(framebuffer->getWidth()-30),0.5*(1+sin(a*7.0+1.3))*(framebuffer->getHeight()-16),"LICE RULEZ",LICE_RGBA(255,0,0,0),sin(a*0.7),LICE_BLIT_MODE_ADD); + } + break; + case 13: + //icon loading test + { + LICE_Clear(framebuffer, LICE_RGBA(255,255,255,255)); + LICE_Blit(framebuffer,icon,0,0,NULL,1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + } + break; + case 14: + // circles/arcs + { + int w = framebuffer->getWidth(), h = framebuffer->getHeight(); + const double _PI = acos(-1.0); + static int m_init, m_x, m_y; + if (!m_init) { + m_init = true; + m_x = w/2; m_y = h/2; + } + int r = rand()%w; + float alpha = 1.0f; //(float) r / (float) w; + float aLo = 2*_PI*rand()/RAND_MAX; + float aHi = 2*_PI*rand()/RAND_MAX; + + //LICE_Clear(framebuffer, LICE_RGBA(0,0,0,0)); + LICE_Arc(framebuffer, m_x, m_y, r, aLo, aHi, LICE_RGBA(rand()%255,rand()%255,rand()%255,255),alpha); + //LICE_Circle(framebuffer, m_x, m_y, r, LICE_RGBA(rand()%255,rand()%255,rand()%255,255)); + } + break; + case 16: + { + int sw=framebuffer->getWidth(); + int sh=framebuffer->getHeight(); + + LICE_MemBitmap framebuffer_back; + { + static double a; + a+=0.003; + + static int turd; + if ((turd++&511) < 12) + LICE_GradRect(framebuffer,sw/4,sh/4,sw/2,sh/2, + 0.5*sin(a*14.0),0.5*cos(a*2.0+1.3),0.5*sin(a*4.0),0.1, + (cos(a*37.0))/framebuffer->getWidth()*0.5,(sin(a*17.0))/framebuffer->getWidth()*0.5,(cos(a*7.0))/framebuffer->getWidth()*0.5,0, + (sin(a*12.0))/framebuffer->getHeight()*0.5,(cos(a*4.0))/framebuffer->getHeight()*0.5,(cos(a*3.0))/framebuffer->getHeight()*0.5,0, + LICE_BLIT_MODE_ADD); + } + //LICE_TexGen_Marble(framebuffer, NULL, 1, 1, 1, 1); + LICE_Copy(&framebuffer_back,framebuffer); + + + const int divw=10; + const int divh=5; + float pts[2*divw*divh]; + static float angs[2*divw*divh]; + static float dangs[2*divw*divh]; + static int turd; + if (!turd) + { + turd++; + int a; + for (a = 0; a < 2*divw*divh; a ++) + { + dangs[a]=((rand()%1000)-500)*0.0001; + angs[a]=((rand()%1000)-500)*0.1; + } + } + int x,y; + for (y=0;ygetWidth(), + framebuffer->getHeight(),pts,divw,divh,0.8,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + + break; + case 19: + //SVG loading + { + static LICE_IBitmap* svgbmp = 0; + + if (!svgbmp) svgbmp = LICE_LoadSVG("c:\\test.svg", 0); + if (svgbmp) LICE_Blit(framebuffer, svgbmp, 0, 0, 0, 0, svgbmp->getWidth(), svgbmp->getHeight(), 1.0f, LICE_BLIT_MODE_COPY); + } + break; + } + + if(jpg) + { + LICE_ScaledBlit(framebuffer,jpg,0,0,framebuffer->getWidth(),framebuffer->getHeight(),0,0,jpg->getWidth(),jpg->getHeight(),0.5,LICE_BLIT_MODE_COPY); + } + + m_frame_cnt++; + + double sec=(GetTickCount()-m_start_time)*0.001; + //if (sec>0.0001) + if (false) + { + char buf[512]; + sprintf(buf,"%dx%d @ %.2ffps",framebuffer->getWidth(),framebuffer->getHeight(),m_frame_cnt / (double)sec); + LICE_DrawText(framebuffer,1,1,buf,LICE_RGBA(0,0,0,0),1,LICE_BLIT_MODE_COPY); + LICE_DrawText(framebuffer,0,0,buf,LICE_RGBA(255,255,255,0),1,LICE_BLIT_MODE_COPY); + } + + m_doeff = 0; + +#ifndef _WIN32 + SWELL_SyncCtxFrameBuffer(framebuffer->getDC()); // flush required on OS X +#endif + BitBlt(dc,r.left,r.top,framebuffer->getWidth(),framebuffer->getHeight(),framebuffer->getDC(),0,0,SRCCOPY); + // bmp->blitToDC(dc, NULL, 0, 0); + + +#if 0 + if (GetAsyncKeyState(VK_SHIFT)&0x8000) + if (GetAsyncKeyState(VK_MENU)&0x8000) + if (GetAsyncKeyState(VK_CONTROL)&0x8000) + { + LICE_WritePNG("/tmp/blah.png",framebuffer,false); + LICE_WriteJPG("/tmp/blah.jpg",framebuffer); + } +#endif + + EndPaint(hwndDlg, &ps); +} + + +// this is only used on OS X since it's way faster there +LRESULT WINAPI testRenderDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg==WM_PAINT) + { + DoPaint(hwndDlg); + return 0; + } + if (uMsg == WM_LBUTTONDOWN) + { + m_cap=true; + SetCapture(hwndDlg); + ShowCursor(FALSE); + } + else if (uMsg == WM_LBUTTONUP||uMsg==WM_CAPTURECHANGED) + { + m_cap=false; + ShowCursor(TRUE); + if (uMsg==WM_LBUTTONUP)ReleaseCapture(); + } + + return DefWindowProc(hwndDlg,uMsg,wParam,lParam); +} + +WDL_DLGRET WINAPI dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_LBUTTONDOWN) + { + m_cap=true; + SetCapture(hwndDlg); + ShowCursor(FALSE); + } + else if (uMsg == WM_LBUTTONUP||uMsg==WM_CAPTURECHANGED) + { + m_cap=false; + ShowCursor(TRUE); + if (uMsg==WM_LBUTTONUP)ReleaseCapture(); + } + + switch(uMsg) + { + case WM_INITDIALOG: + + framebuffer = new LICE_SysBitmap(0,0); + + //jpg=LICE_LoadJPG("C:/turds.jpg"); + +#ifdef _WIN32 + bmp = LICE_LoadPNGFromResource(g_hInstance, IDC_PNG1); + icon = LICE_LoadIconFromResource(g_hInstance, IDI_MAIN, 0); +#endif + + SetTimer(hwndDlg,1,3,NULL); + { + int x; + for (x = 0; x < NUM_EFFECTS; x ++) + { + char buf[512]; + wsprintf(buf,"Effect %d - %s",x+1,effect_names[x]); + SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)buf); + } + SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,m_effect,0); + + m_start_time=GetTickCount(); + m_frame_cnt=0; + } + return 0; + case WM_DESTROY: + + + delete icon; + delete bmp; + delete framebuffer; + return 0; + +#ifdef _WIN32 + case WM_TIMER: + InvalidateRect(hwndDlg,NULL,FALSE); + return 0; + case WM_PAINT: + DoPaint(hwndDlg); + break; +#else + case WM_SIZE: + { + RECT r; + GetClientRect(hwndDlg,&r); + r.top+=40; + SetWindowPos(GetDlgItem(hwndDlg,IDC_RECT),NULL,r.left,r.top,r.right-r.left,r.bottom-r.top,SWP_NOZORDER|SWP_NOACTIVATE); + } + return 0; + case WM_TIMER: + InvalidateRect(GetDlgItem(hwndDlg,IDC_RECT),NULL,FALSE); + return 0; +#endif + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_COMBO1: + m_effect = SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0); + m_doeff=1; + m_start_time=GetTickCount(); + m_frame_cnt=0; + break; + case IDCANCEL: +#ifdef _WIN32 + EndDialog(hwndDlg, 0); +#else + DestroyWindow(hwndDlg); // on mac we run modeless +#endif + break; + } + break; + } + return 0; +} + +#ifdef _WIN32 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd) +{ + + timingInit(); + g_hInstance=hInstance; + DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, dlgProc); + + timingPrint(); + + return 0; +} +#endif \ No newline at end of file diff --git a/WDL/lice/test/main.ico b/WDL/lice/test/main.ico new file mode 100644 index 0000000000000000000000000000000000000000..78c2e614c9a03ee5f7c2e010b2a6a5a5b316ae26 GIT binary patch literal 24942 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 literal 0 HcmV?d00001 diff --git a/WDL/lice/test/main.m b/WDL/lice/test/main.m new file mode 100644 index 00000000..a4476ab4 --- /dev/null +++ b/WDL/lice/test/main.m @@ -0,0 +1,14 @@ +// +// main.m +// test +// +// Created by Justin Frankel on 11/9/07. +// Copyright __MyCompanyName__ 2007. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/WDL/lice/test/resource.h b/WDL/lice/test/resource.h new file mode 100644 index 00000000..15d67f48 --- /dev/null +++ b/WDL/lice/test/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by test.rc +// +#define IDD_DIALOG1 101 +#define IDC_PNG1 102 +#define IDI_MAIN 103 +#define IDC_BUTTON1 1000 +#define IDC_RECT 1001 +#define IDC_BUTTON2 1002 +#define IDC_COMBO1 1002 +#define IDC_BUTTON3 1003 +#define IDC_BUTTON4 1004 +#define IDC_BUTTON5 1005 +#define IDC_BUTTON6 1006 +#define IDC_BUTTON7 1007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/WDL/lice/test/test.dsp b/WDL/lice/test/test.dsp new file mode 100644 index 00000000..ddfad7e5 --- /dev/null +++ b/WDL/lice/test/test.dsp @@ -0,0 +1,120 @@ +# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=test - 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 "test.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 "test.mak" CFG="test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "test - Win32 Release" +# Name "test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\fly.cpp +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\image.png +# End Source File +# Begin Source File + +SOURCE=.\test.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/WDL/lice/test/test.rc b/WDL/lice/test/test.rc new file mode 100644 index 00000000..f5371bcc --- /dev/null +++ b/WDL/lice/test/test.rc @@ -0,0 +1,107 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 398, 270 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "LICE Test App" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_RECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | + WS_DISABLED,7,23,384,239 + COMBOBOX IDC_COMBO1,7,7,181,170,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// PNG +// + +IDC_PNG1 PNG DISCARDABLE "image.png" +IDI_MAIN ICON DISCARDABLE "main.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 391 + TOPMARGIN, 7 + BOTTOMMARGIN, 263 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/WDL/lice/test/test.xcodeproj/project.pbxproj b/WDL/lice/test/test.xcodeproj/project.pbxproj new file mode 100644 index 00000000..9351adc8 --- /dev/null +++ b/WDL/lice/test/test.xcodeproj/project.pbxproj @@ -0,0 +1,918 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 33343C070CE4DB5D00FF8CE6 /* swell-dlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */; }; + 33343C130CE4DB7000FF8CE6 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */; }; + 33343C140CE4DB7000FF8CE6 /* swell-ini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */; }; + 33343C150CE4DB7000FF8CE6 /* swell-kb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */; }; + 33343C160CE4DB7000FF8CE6 /* swell-menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */; }; + 33343C170CE4DB7000FF8CE6 /* swell-miscdlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */; }; + 33343C180CE4DB7000FF8CE6 /* swell-wnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */; }; + 33343C190CE4DB7000FF8CE6 /* swell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C110CE4DB7000FF8CE6 /* swell.cpp */; }; + 33343C210CE4DB9E00FF8CE6 /* lice_arc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */; }; + 33343C2D0CE4DBBB00FF8CE6 /* lice_gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */; }; + 33343C2E0CE4DBBB00FF8CE6 /* lice_jpg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */; }; + 33343C2F0CE4DBBB00FF8CE6 /* lice_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */; }; + 33343C300CE4DBBB00FF8CE6 /* lice_png.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */; }; + 33343C310CE4DBBB00FF8CE6 /* lice_texgen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */; }; + 33343C320CE4DBBB00FF8CE6 /* lice_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */; }; + 33343C330CE4DBBB00FF8CE6 /* lice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */; }; + 33343C3C0CE4DBD200FF8CE6 /* dgif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; + 33343C3D0CE4DBD200FF8CE6 /* egif_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C360CE4DBD200FF8CE6 /* egif_lib.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; + 33343C3E0CE4DBD200FF8CE6 /* gif_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C370CE4DBD200FF8CE6 /* gif_hash.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; + 33343C3F0CE4DBD200FF8CE6 /* gifalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H"; }; }; + 33343C790CE4DBE200FF8CE6 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C400CE4DBE200FF8CE6 /* jcapimin.c */; }; + 33343C7A0CE4DBE200FF8CE6 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C410CE4DBE200FF8CE6 /* jcapistd.c */; }; + 33343C7B0CE4DBE200FF8CE6 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C420CE4DBE200FF8CE6 /* jccoefct.c */; }; + 33343C7C0CE4DBE200FF8CE6 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C430CE4DBE200FF8CE6 /* jccolor.c */; }; + 33343C7D0CE4DBE200FF8CE6 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */; }; + 33343C7E0CE4DBE200FF8CE6 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C450CE4DBE200FF8CE6 /* jchuff.c */; }; + 33343C7F0CE4DBE200FF8CE6 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C470CE4DBE200FF8CE6 /* jcinit.c */; }; + 33343C800CE4DBE200FF8CE6 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C480CE4DBE200FF8CE6 /* jcmainct.c */; }; + 33343C810CE4DBE200FF8CE6 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C490CE4DBE200FF8CE6 /* jcmarker.c */; }; + 33343C820CE4DBE200FF8CE6 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */; }; + 33343C830CE4DBE200FF8CE6 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */; }; + 33343C840CE4DBE200FF8CE6 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */; }; + 33343C850CE4DBE200FF8CE6 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */; }; + 33343C860CE4DBE200FF8CE6 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */; }; + 33343C870CE4DBE200FF8CE6 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C500CE4DBE200FF8CE6 /* jcsample.c */; }; + 33343C880CE4DBE200FF8CE6 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C510CE4DBE200FF8CE6 /* jctrans.c */; }; + 33343C890CE4DBE200FF8CE6 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C520CE4DBE200FF8CE6 /* jdapimin.c */; }; + 33343C8A0CE4DBE200FF8CE6 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C530CE4DBE200FF8CE6 /* jdapistd.c */; }; + 33343C8B0CE4DBE200FF8CE6 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C540CE4DBE200FF8CE6 /* jdatadst.c */; }; + 33343C8C0CE4DBE200FF8CE6 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */; }; + 33343C8D0CE4DBE200FF8CE6 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */; }; + 33343C8E0CE4DBE200FF8CE6 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C570CE4DBE200FF8CE6 /* jdcolor.c */; }; + 33343C8F0CE4DBE200FF8CE6 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */; }; + 33343C900CE4DBE200FF8CE6 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */; }; + 33343C910CE4DBE200FF8CE6 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */; }; + 33343C920CE4DBE200FF8CE6 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */; }; + 33343C930CE4DBE200FF8CE6 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */; }; + 33343C940CE4DBE200FF8CE6 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */; }; + 33343C950CE4DBE200FF8CE6 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C600CE4DBE200FF8CE6 /* jdmerge.c */; }; + 33343C960CE4DBE200FF8CE6 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C610CE4DBE200FF8CE6 /* jdphuff.c */; }; + 33343C970CE4DBE200FF8CE6 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C620CE4DBE200FF8CE6 /* jdpostct.c */; }; + 33343C980CE4DBE200FF8CE6 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C630CE4DBE200FF8CE6 /* jdsample.c */; }; + 33343C990CE4DBE200FF8CE6 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C640CE4DBE200FF8CE6 /* jdtrans.c */; }; + 33343C9A0CE4DBE200FF8CE6 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C650CE4DBE200FF8CE6 /* jerror.c */; }; + 33343C9B0CE4DBE200FF8CE6 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */; }; + 33343C9C0CE4DBE200FF8CE6 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */; }; + 33343C9D0CE4DBE200FF8CE6 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C690CE4DBE200FF8CE6 /* jfdctint.c */; }; + 33343C9E0CE4DBE200FF8CE6 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */; }; + 33343C9F0CE4DBE200FF8CE6 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */; }; + 33343CA00CE4DBE200FF8CE6 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */; }; + 33343CA10CE4DBE200FF8CE6 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */; }; + 33343CA20CE4DBE200FF8CE6 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */; }; + 33343CA30CE4DBE200FF8CE6 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */; }; + 33343CA40CE4DBE200FF8CE6 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C750CE4DBE200FF8CE6 /* jquant1.c */; }; + 33343CA50CE4DBE200FF8CE6 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C760CE4DBE200FF8CE6 /* jquant2.c */; }; + 33343CA60CE4DBE200FF8CE6 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343C770CE4DBE200FF8CE6 /* jutils.c */; }; + 33343CFE0CE4DCFB00FF8CE6 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE50CE4DCFB00FF8CE6 /* adler32.c */; }; + 33343CFF0CE4DCFB00FF8CE6 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE60CE4DCFB00FF8CE6 /* compress.c */; }; + 33343D000CE4DCFB00FF8CE6 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE70CE4DCFB00FF8CE6 /* crc32.c */; }; + 33343D010CE4DCFB00FF8CE6 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CE90CE4DCFB00FF8CE6 /* deflate.c */; }; + 33343D030CE4DCFB00FF8CE6 /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */; }; + 33343D040CE4DCFB00FF8CE6 /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CED0CE4DCFB00FF8CE6 /* infback.c */; }; + 33343D050CE4DCFB00FF8CE6 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */; }; + 33343D060CE4DCFB00FF8CE6 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF10CE4DCFB00FF8CE6 /* inflate.c */; }; + 33343D070CE4DCFB00FF8CE6 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */; }; + 33343D090CE4DCFB00FF8CE6 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF60CE4DCFB00FF8CE6 /* trees.c */; }; + 33343D0A0CE4DCFB00FF8CE6 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */; }; + 33343D0B0CE4DCFB00FF8CE6 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */; }; + 33343D210CE4DD1F00FF8CE6 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D0D0CE4DD1F00FF8CE6 /* png.c */; }; + 33343D220CE4DD1F00FF8CE6 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D100CE4DD1F00FF8CE6 /* pngerror.c */; }; + 33343D240CE4DD1F00FF8CE6 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D120CE4DD1F00FF8CE6 /* pngget.c */; }; + 33343D250CE4DD1F00FF8CE6 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D130CE4DD1F00FF8CE6 /* pngmem.c */; }; + 33343D260CE4DD1F00FF8CE6 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D140CE4DD1F00FF8CE6 /* pngpread.c */; }; + 33343D270CE4DD1F00FF8CE6 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D150CE4DD1F00FF8CE6 /* pngread.c */; }; + 33343D280CE4DD1F00FF8CE6 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D160CE4DD1F00FF8CE6 /* pngrio.c */; }; + 33343D290CE4DD1F00FF8CE6 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */; }; + 33343D2A0CE4DD1F00FF8CE6 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */; }; + 33343D2B0CE4DD1F00FF8CE6 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D190CE4DD1F00FF8CE6 /* pngset.c */; }; + 33343D2D0CE4DD1F00FF8CE6 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */; }; + 33343D2F0CE4DD1F00FF8CE6 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */; }; + 33343D300CE4DD1F00FF8CE6 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */; }; + 33343D310CE4DD1F00FF8CE6 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */; }; + 33343D320CE4DD1F00FF8CE6 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */; }; + 334560580CE4E727004D76AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 334560570CE4E727004D76AE /* Carbon.framework */; }; + 3350A9D2146B63B500702E1F /* lice_lvg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3350A9D0146B63B500702E1F /* lice_lvg.cpp */; }; + 3350A9D3146B63B500702E1F /* lice_palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3350A9D1146B63B500702E1F /* lice_palette.cpp */; }; + 33651CDE10B766A6005FF751 /* swell-misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33651CDD10B766A6005FF751 /* swell-misc.mm */; }; + 33651CE010B766B2005FF751 /* lice_svg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CDF10B766B2005FF751 /* lice_svg.cpp */; }; + 33651CEC10B766E1005FF751 /* libxml_tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */; }; + 33651CED10B766E1005FF751 /* svgtiny_colors.c in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE510B766E1005FF751 /* svgtiny_colors.c */; }; + 33651CEE10B766E1005FF751 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE610B766E1005FF751 /* tinystr.cpp */; }; + 33651CEF10B766E1005FF751 /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CE810B766E1005FF751 /* tinyxml.cpp */; }; + 33651CF010B766E1005FF751 /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */; }; + 33651CF110B766E1005FF751 /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */; }; + 33BD26B70ECF7811000A367A /* pl_cam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AC0ECF7811000A367A /* pl_cam.cpp */; }; + 33BD26B80ECF7811000A367A /* pl_make.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AD0ECF7811000A367A /* pl_make.cpp */; }; + 33BD26B90ECF7811000A367A /* pl_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AE0ECF7811000A367A /* pl_math.cpp */; }; + 33BD26BA0ECF7811000A367A /* pl_obj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26AF0ECF7811000A367A /* pl_obj.cpp */; }; + 33BD26BB0ECF7811000A367A /* pl_putface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B10ECF7811000A367A /* pl_putface.cpp */; }; + 33BD26BC0ECF7811000A367A /* pl_read_3ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */; }; + 33BD26BD0ECF7811000A367A /* pl_read_cob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */; }; + 33BD26BE0ECF7811000A367A /* pl_read_jaw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */; }; + 33BD26BF0ECF7811000A367A /* pl_spline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26B50ECF7811000A367A /* pl_spline.cpp */; }; + 33BD26C90ECF7830000A367A /* lice_bmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C10ECF7830000A367A /* lice_bmp.cpp */; }; + 33BD26CA0ECF7830000A367A /* lice_ico.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C20ECF7830000A367A /* lice_ico.cpp */; }; + 33BD26CB0ECF7830000A367A /* lice_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C30ECF7830000A367A /* lice_image.cpp */; }; + 33BD26CC0ECF7830000A367A /* lice_jpg_write.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */; }; + 33BD26CD0ECF7830000A367A /* lice_pcx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C50ECF7830000A367A /* lice_pcx.cpp */; }; + 33BD26CE0ECF7830000A367A /* lice_png_write.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C60ECF7830000A367A /* lice_png_write.cpp */; }; + 33BD26CF0ECF7830000A367A /* lice_textnew.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26C80ECF7830000A367A /* lice_textnew.cpp */; }; + 33BD26DF0ECF78C3000A367A /* fly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BD26DE0ECF78C3000A367A /* fly.cpp */; }; + 33E075650CE4DDD3005DDE14 /* Controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33E075640CE4DDD3005DDE14 /* Controller.mm */; }; + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-dlg.mm"; path = "../../swell/swell-dlg.mm"; sourceTree = SOURCE_ROOT; }; + 33343C080CE4DB7000FF8CE6 /* swell-dlggen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "swell-dlggen.h"; path = "../../swell/swell-dlggen.h"; sourceTree = SOURCE_ROOT; }; + 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../../swell/swell-gdi.mm"; sourceTree = SOURCE_ROOT; }; + 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "swell-ini.cpp"; path = "../../swell/swell-ini.cpp"; sourceTree = SOURCE_ROOT; }; + 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-kb.mm"; path = "../../swell/swell-kb.mm"; sourceTree = SOURCE_ROOT; }; + 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-menu.mm"; path = "../../swell/swell-menu.mm"; sourceTree = SOURCE_ROOT; }; + 33343C0E0CE4DB7000FF8CE6 /* swell-menugen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "swell-menugen.h"; path = "../../swell/swell-menugen.h"; sourceTree = SOURCE_ROOT; }; + 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-miscdlg.mm"; path = "../../swell/swell-miscdlg.mm"; sourceTree = SOURCE_ROOT; }; + 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-wnd.mm"; path = "../../swell/swell-wnd.mm"; sourceTree = SOURCE_ROOT; }; + 33343C110CE4DB7000FF8CE6 /* swell.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = swell.cpp; path = ../../swell/swell.cpp; sourceTree = SOURCE_ROOT; }; + 33343C120CE4DB7000FF8CE6 /* swell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = swell.h; path = ../../swell/swell.h; sourceTree = SOURCE_ROOT; }; + 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_arc.cpp; path = ../lice_arc.cpp; sourceTree = SOURCE_ROOT; }; + 33343C230CE4DBBB00FF8CE6 /* lice_combine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lice_combine.h; path = ../lice_combine.h; sourceTree = SOURCE_ROOT; }; + 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_gif.cpp; path = ../lice_gif.cpp; sourceTree = SOURCE_ROOT; }; + 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg.cpp; path = ../lice_jpg.cpp; sourceTree = SOURCE_ROOT; }; + 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_line.cpp; path = ../lice_line.cpp; sourceTree = SOURCE_ROOT; }; + 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png.cpp; path = ../lice_png.cpp; sourceTree = SOURCE_ROOT; }; + 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_texgen.cpp; path = ../lice_texgen.cpp; sourceTree = SOURCE_ROOT; }; + 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice_text.cpp; path = ../lice_text.cpp; sourceTree = SOURCE_ROOT; }; + 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lice.cpp; path = ../lice.cpp; sourceTree = SOURCE_ROOT; }; + 33343C2B0CE4DBBB00FF8CE6 /* lice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lice.h; path = ../lice.h; sourceTree = SOURCE_ROOT; }; + 33343C340CE4DBD200FF8CE6 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../../giflib/config.h; sourceTree = SOURCE_ROOT; }; + 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dgif_lib.c; path = ../../giflib/dgif_lib.c; sourceTree = SOURCE_ROOT; }; + 33343C360CE4DBD200FF8CE6 /* egif_lib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = egif_lib.c; path = ../../giflib/egif_lib.c; sourceTree = SOURCE_ROOT; }; + 33343C370CE4DBD200FF8CE6 /* gif_hash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gif_hash.c; path = ../../giflib/gif_hash.c; sourceTree = SOURCE_ROOT; }; + 33343C380CE4DBD200FF8CE6 /* gif_hash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_hash.h; path = ../../giflib/gif_hash.h; sourceTree = SOURCE_ROOT; }; + 33343C390CE4DBD200FF8CE6 /* gif_lib_private.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib_private.h; path = ../../giflib/gif_lib_private.h; sourceTree = SOURCE_ROOT; }; + 33343C3A0CE4DBD200FF8CE6 /* gif_lib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gif_lib.h; path = ../../giflib/gif_lib.h; sourceTree = SOURCE_ROOT; }; + 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gifalloc.c; path = ../../giflib/gifalloc.c; sourceTree = SOURCE_ROOT; }; + 33343C400CE4DBE200FF8CE6 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../../jpeglib/jcapimin.c; sourceTree = SOURCE_ROOT; }; + 33343C410CE4DBE200FF8CE6 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../../jpeglib/jcapistd.c; sourceTree = SOURCE_ROOT; }; + 33343C420CE4DBE200FF8CE6 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../../jpeglib/jccoefct.c; sourceTree = SOURCE_ROOT; }; + 33343C430CE4DBE200FF8CE6 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../../jpeglib/jccolor.c; sourceTree = SOURCE_ROOT; }; + 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../../jpeglib/jcdctmgr.c; sourceTree = SOURCE_ROOT; }; + 33343C450CE4DBE200FF8CE6 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../../jpeglib/jchuff.c; sourceTree = SOURCE_ROOT; }; + 33343C460CE4DBE200FF8CE6 /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../../jpeglib/jchuff.h; sourceTree = SOURCE_ROOT; }; + 33343C470CE4DBE200FF8CE6 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../../jpeglib/jcinit.c; sourceTree = SOURCE_ROOT; }; + 33343C480CE4DBE200FF8CE6 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../../jpeglib/jcmainct.c; sourceTree = SOURCE_ROOT; }; + 33343C490CE4DBE200FF8CE6 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../../jpeglib/jcmarker.c; sourceTree = SOURCE_ROOT; }; + 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../../jpeglib/jcmaster.c; sourceTree = SOURCE_ROOT; }; + 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../../jpeglib/jcomapi.c; sourceTree = SOURCE_ROOT; }; + 33343C4C0CE4DBE200FF8CE6 /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../../jpeglib/jconfig.h; sourceTree = SOURCE_ROOT; }; + 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../../jpeglib/jcparam.c; sourceTree = SOURCE_ROOT; }; + 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../../jpeglib/jcphuff.c; sourceTree = SOURCE_ROOT; }; + 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../../jpeglib/jcprepct.c; sourceTree = SOURCE_ROOT; }; + 33343C500CE4DBE200FF8CE6 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../../jpeglib/jcsample.c; sourceTree = SOURCE_ROOT; }; + 33343C510CE4DBE200FF8CE6 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../../jpeglib/jctrans.c; sourceTree = SOURCE_ROOT; }; + 33343C520CE4DBE200FF8CE6 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../../jpeglib/jdapimin.c; sourceTree = SOURCE_ROOT; }; + 33343C530CE4DBE200FF8CE6 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../../jpeglib/jdapistd.c; sourceTree = SOURCE_ROOT; }; + 33343C540CE4DBE200FF8CE6 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../../jpeglib/jdatadst.c; sourceTree = SOURCE_ROOT; }; + 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../../jpeglib/jdatasrc.c; sourceTree = SOURCE_ROOT; }; + 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../../jpeglib/jdcoefct.c; sourceTree = SOURCE_ROOT; }; + 33343C570CE4DBE200FF8CE6 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../../jpeglib/jdcolor.c; sourceTree = SOURCE_ROOT; }; + 33343C580CE4DBE200FF8CE6 /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdct.h; path = ../../jpeglib/jdct.h; sourceTree = SOURCE_ROOT; }; + 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../../jpeglib/jddctmgr.c; sourceTree = SOURCE_ROOT; }; + 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../../jpeglib/jdhuff.c; sourceTree = SOURCE_ROOT; }; + 33343C5B0CE4DBE200FF8CE6 /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdhuff.h; path = ../../jpeglib/jdhuff.h; sourceTree = SOURCE_ROOT; }; + 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../../jpeglib/jdinput.c; sourceTree = SOURCE_ROOT; }; + 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../../jpeglib/jdmainct.c; sourceTree = SOURCE_ROOT; }; + 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../../jpeglib/jdmarker.c; sourceTree = SOURCE_ROOT; }; + 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../../jpeglib/jdmaster.c; sourceTree = SOURCE_ROOT; }; + 33343C600CE4DBE200FF8CE6 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../../jpeglib/jdmerge.c; sourceTree = SOURCE_ROOT; }; + 33343C610CE4DBE200FF8CE6 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../../jpeglib/jdphuff.c; sourceTree = SOURCE_ROOT; }; + 33343C620CE4DBE200FF8CE6 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../../jpeglib/jdpostct.c; sourceTree = SOURCE_ROOT; }; + 33343C630CE4DBE200FF8CE6 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../../jpeglib/jdsample.c; sourceTree = SOURCE_ROOT; }; + 33343C640CE4DBE200FF8CE6 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../../jpeglib/jdtrans.c; sourceTree = SOURCE_ROOT; }; + 33343C650CE4DBE200FF8CE6 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../../jpeglib/jerror.c; sourceTree = SOURCE_ROOT; }; + 33343C660CE4DBE200FF8CE6 /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../../jpeglib/jerror.h; sourceTree = SOURCE_ROOT; }; + 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../../jpeglib/jfdctflt.c; sourceTree = SOURCE_ROOT; }; + 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../../jpeglib/jfdctfst.c; sourceTree = SOURCE_ROOT; }; + 33343C690CE4DBE200FF8CE6 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../../jpeglib/jfdctint.c; sourceTree = SOURCE_ROOT; }; + 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../../jpeglib/jidctflt.c; sourceTree = SOURCE_ROOT; }; + 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../../jpeglib/jidctfst.c; sourceTree = SOURCE_ROOT; }; + 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../../jpeglib/jidctint.c; sourceTree = SOURCE_ROOT; }; + 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../../jpeglib/jidctred.c; sourceTree = SOURCE_ROOT; }; + 33343C6E0CE4DBE200FF8CE6 /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jinclude.h; path = ../../jpeglib/jinclude.h; sourceTree = SOURCE_ROOT; }; + 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../../jpeglib/jmemmgr.c; sourceTree = SOURCE_ROOT; }; + 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../../jpeglib/jmemnobs.c; sourceTree = SOURCE_ROOT; }; + 33343C710CE4DBE200FF8CE6 /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmemsys.h; path = ../../jpeglib/jmemsys.h; sourceTree = SOURCE_ROOT; }; + 33343C720CE4DBE200FF8CE6 /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmorecfg.h; path = ../../jpeglib/jmorecfg.h; sourceTree = SOURCE_ROOT; }; + 33343C730CE4DBE200FF8CE6 /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpegint.h; path = ../../jpeglib/jpegint.h; sourceTree = SOURCE_ROOT; }; + 33343C740CE4DBE200FF8CE6 /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../../jpeglib/jpeglib.h; sourceTree = SOURCE_ROOT; }; + 33343C750CE4DBE200FF8CE6 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../../jpeglib/jquant1.c; sourceTree = SOURCE_ROOT; }; + 33343C760CE4DBE200FF8CE6 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../../jpeglib/jquant2.c; sourceTree = SOURCE_ROOT; }; + 33343C770CE4DBE200FF8CE6 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../jpeglib/jutils.c; sourceTree = SOURCE_ROOT; }; + 33343C780CE4DBE200FF8CE6 /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jversion.h; path = ../../jpeglib/jversion.h; sourceTree = SOURCE_ROOT; }; + 33343CE50CE4DCFB00FF8CE6 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ../../zlib/adler32.c; sourceTree = SOURCE_ROOT; }; + 33343CE60CE4DCFB00FF8CE6 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ../../zlib/compress.c; sourceTree = SOURCE_ROOT; }; + 33343CE70CE4DCFB00FF8CE6 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ../../zlib/crc32.c; sourceTree = SOURCE_ROOT; }; + 33343CE80CE4DCFB00FF8CE6 /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = ../../zlib/crc32.h; sourceTree = SOURCE_ROOT; }; + 33343CE90CE4DCFB00FF8CE6 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ../../zlib/deflate.c; sourceTree = SOURCE_ROOT; }; + 33343CEA0CE4DCFB00FF8CE6 /* deflate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = deflate.h; path = ../../zlib/deflate.h; sourceTree = SOURCE_ROOT; }; + 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gzio.c; path = ../../zlib/gzio.c; sourceTree = SOURCE_ROOT; }; + 33343CED0CE4DCFB00FF8CE6 /* infback.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ../../zlib/infback.c; sourceTree = SOURCE_ROOT; }; + 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../../zlib/inffast.c; sourceTree = SOURCE_ROOT; }; + 33343CEF0CE4DCFB00FF8CE6 /* inffast.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inffast.h; path = ../../zlib/inffast.h; sourceTree = SOURCE_ROOT; }; + 33343CF00CE4DCFB00FF8CE6 /* inffixed.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inffixed.h; path = ../../zlib/inffixed.h; sourceTree = SOURCE_ROOT; }; + 33343CF10CE4DCFB00FF8CE6 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ../../zlib/inflate.c; sourceTree = SOURCE_ROOT; }; + 33343CF20CE4DCFB00FF8CE6 /* inflate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inflate.h; path = ../../zlib/inflate.h; sourceTree = SOURCE_ROOT; }; + 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ../../zlib/inftrees.c; sourceTree = SOURCE_ROOT; }; + 33343CF40CE4DCFB00FF8CE6 /* inftrees.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = inftrees.h; path = ../../zlib/inftrees.h; sourceTree = SOURCE_ROOT; }; + 33343CF60CE4DCFB00FF8CE6 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ../../zlib/trees.c; sourceTree = SOURCE_ROOT; }; + 33343CF70CE4DCFB00FF8CE6 /* trees.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = trees.h; path = ../../zlib/trees.h; sourceTree = SOURCE_ROOT; }; + 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ../../zlib/uncompr.c; sourceTree = SOURCE_ROOT; }; + 33343CF90CE4DCFB00FF8CE6 /* zconf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zconf.h; path = ../../zlib/zconf.h; sourceTree = SOURCE_ROOT; }; + 33343CFA0CE4DCFB00FF8CE6 /* zconf.in.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zconf.in.h; path = ../../zlib/zconf.in.h; sourceTree = SOURCE_ROOT; }; + 33343CFB0CE4DCFB00FF8CE6 /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = ../../zlib/zlib.h; sourceTree = SOURCE_ROOT; }; + 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ../../zlib/zutil.c; sourceTree = SOURCE_ROOT; }; + 33343CFD0CE4DCFB00FF8CE6 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = ../../zlib/zutil.h; sourceTree = SOURCE_ROOT; }; + 33343D0D0CE4DD1F00FF8CE6 /* png.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../../libpng/png.c; sourceTree = SOURCE_ROOT; }; + 33343D0E0CE4DD1F00FF8CE6 /* png.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = png.h; path = ../../libpng/png.h; sourceTree = SOURCE_ROOT; }; + 33343D0F0CE4DD1F00FF8CE6 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = ../../libpng/pngconf.h; sourceTree = SOURCE_ROOT; }; + 33343D100CE4DD1F00FF8CE6 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../../libpng/pngerror.c; sourceTree = SOURCE_ROOT; }; + 33343D120CE4DD1F00FF8CE6 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../../libpng/pngget.c; sourceTree = SOURCE_ROOT; }; + 33343D130CE4DD1F00FF8CE6 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../../libpng/pngmem.c; sourceTree = SOURCE_ROOT; }; + 33343D140CE4DD1F00FF8CE6 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../../libpng/pngpread.c; sourceTree = SOURCE_ROOT; }; + 33343D150CE4DD1F00FF8CE6 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../../libpng/pngread.c; sourceTree = SOURCE_ROOT; }; + 33343D160CE4DD1F00FF8CE6 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../../libpng/pngrio.c; sourceTree = SOURCE_ROOT; }; + 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; }; + 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; }; + 33343D190CE4DD1F00FF8CE6 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../../libpng/pngset.c; sourceTree = SOURCE_ROOT; }; + 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; }; + 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../../libpng/pngwio.c; sourceTree = SOURCE_ROOT; }; + 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = ../../libpng/pngwrite.c; sourceTree = SOURCE_ROOT; }; + 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; }; + 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; }; + 334560570CE4E727004D76AE /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 3350A9D0146B63B500702E1F /* lice_lvg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_lvg.cpp; path = ../lice_lvg.cpp; sourceTree = SOURCE_ROOT; }; + 3350A9D1146B63B500702E1F /* lice_palette.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_palette.cpp; path = ../lice_palette.cpp; sourceTree = SOURCE_ROOT; }; + 33651CDD10B766A6005FF751 /* swell-misc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-misc.mm"; path = "../../swell/swell-misc.mm"; sourceTree = SOURCE_ROOT; }; + 33651CDF10B766B2005FF751 /* lice_svg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_svg.cpp; path = ../lice_svg.cpp; sourceTree = SOURCE_ROOT; }; + 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = libxml_tinyxml.cpp; path = ../../tinyxml/libxml_tinyxml.cpp; sourceTree = SOURCE_ROOT; }; + 33651CE410B766E1005FF751 /* libxml_tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libxml_tinyxml.h; path = ../../tinyxml/libxml_tinyxml.h; sourceTree = SOURCE_ROOT; }; + 33651CE510B766E1005FF751 /* svgtiny_colors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = svgtiny_colors.c; path = ../../tinyxml/svgtiny_colors.c; sourceTree = SOURCE_ROOT; }; + 33651CE610B766E1005FF751 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinystr.cpp; path = ../../tinyxml/tinystr.cpp; sourceTree = SOURCE_ROOT; }; + 33651CE710B766E1005FF751 /* tinystr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinystr.h; path = ../../tinyxml/tinystr.h; sourceTree = SOURCE_ROOT; }; + 33651CE810B766E1005FF751 /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml.cpp; path = ../../tinyxml/tinyxml.cpp; sourceTree = SOURCE_ROOT; }; + 33651CE910B766E1005FF751 /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml.h; path = ../../tinyxml/tinyxml.h; sourceTree = SOURCE_ROOT; }; + 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlerror.cpp; path = ../../tinyxml/tinyxmlerror.cpp; sourceTree = SOURCE_ROOT; }; + 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlparser.cpp; path = ../../tinyxml/tinyxmlparser.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26AC0ECF7811000A367A /* pl_cam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_cam.cpp; path = ../../plush2/pl_cam.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26AD0ECF7811000A367A /* pl_make.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_make.cpp; path = ../../plush2/pl_make.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26AE0ECF7811000A367A /* pl_math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_math.cpp; path = ../../plush2/pl_math.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26AF0ECF7811000A367A /* pl_obj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_obj.cpp; path = ../../plush2/pl_obj.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B00ECF7811000A367A /* pl_pf_tex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pl_pf_tex.h; path = ../../plush2/pl_pf_tex.h; sourceTree = SOURCE_ROOT; }; + 33BD26B10ECF7811000A367A /* pl_putface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_putface.cpp; path = ../../plush2/pl_putface.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_3ds.cpp; path = ../../plush2/pl_read_3ds.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_cob.cpp; path = ../../plush2/pl_read_cob.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_read_jaw.cpp; path = ../../plush2/pl_read_jaw.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B50ECF7811000A367A /* pl_spline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pl_spline.cpp; path = ../../plush2/pl_spline.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26B60ECF7811000A367A /* plush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plush.h; path = ../../plush2/plush.h; sourceTree = SOURCE_ROOT; }; + 33BD26C00ECF7830000A367A /* lice_bezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_bezier.h; path = ../lice_bezier.h; sourceTree = SOURCE_ROOT; }; + 33BD26C10ECF7830000A367A /* lice_bmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_bmp.cpp; path = ../lice_bmp.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C20ECF7830000A367A /* lice_ico.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_ico.cpp; path = ../lice_ico.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C30ECF7830000A367A /* lice_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_image.cpp; path = ../lice_image.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_jpg_write.cpp; path = ../lice_jpg_write.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C50ECF7830000A367A /* lice_pcx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_pcx.cpp; path = ../lice_pcx.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C60ECF7830000A367A /* lice_png_write.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_png_write.cpp; path = ../lice_png_write.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26C70ECF7830000A367A /* lice_text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lice_text.h; path = ../lice_text.h; sourceTree = SOURCE_ROOT; }; + 33BD26C80ECF7830000A367A /* lice_textnew.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lice_textnew.cpp; path = ../lice_textnew.cpp; sourceTree = SOURCE_ROOT; }; + 33BD26DE0ECF78C3000A367A /* fly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fly.cpp; sourceTree = ""; }; + 33E075630CE4DDD3005DDE14 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; + 33E075640CE4DDD3005DDE14 /* Controller.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = Controller.mm; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + 334560580CE4E727004D76AE /* Carbon.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 33E075630CE4DDD3005DDE14 /* Controller.h */, + 33E075640CE4DDD3005DDE14 /* Controller.mm */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 334560570CE4E727004D76AE /* Carbon.framework */, + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* test.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* test */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = test; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 33BD26DE0ECF78C3000A367A /* fly.cpp */, + 33BD26AA0ECF77F9000A367A /* plush2 */, + 33343C1B0CE4DB7B00FF8CE6 /* LICE */, + 33343C050CE4DB4A00FF8CE6 /* SWELL */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 33343C050CE4DB4A00FF8CE6 /* SWELL */ = { + isa = PBXGroup; + children = ( + 33651CDD10B766A6005FF751 /* swell-misc.mm */, + 33343C080CE4DB7000FF8CE6 /* swell-dlggen.h */, + 33343C0A0CE4DB7000FF8CE6 /* swell-gdi.mm */, + 33343C0B0CE4DB7000FF8CE6 /* swell-ini.cpp */, + 33343C0C0CE4DB7000FF8CE6 /* swell-kb.mm */, + 33343C0D0CE4DB7000FF8CE6 /* swell-menu.mm */, + 33343C0E0CE4DB7000FF8CE6 /* swell-menugen.h */, + 33343C0F0CE4DB7000FF8CE6 /* swell-miscdlg.mm */, + 33343C100CE4DB7000FF8CE6 /* swell-wnd.mm */, + 33343C110CE4DB7000FF8CE6 /* swell.cpp */, + 33343C120CE4DB7000FF8CE6 /* swell.h */, + 33343C060CE4DB5D00FF8CE6 /* swell-dlg.mm */, + ); + name = SWELL; + sourceTree = ""; + }; + 33343C1B0CE4DB7B00FF8CE6 /* LICE */ = { + isa = PBXGroup; + children = ( + 3350A9D0146B63B500702E1F /* lice_lvg.cpp */, + 3350A9D1146B63B500702E1F /* lice_palette.cpp */, + 33651CE110B766B6005FF751 /* tinyxml */, + 33651CDF10B766B2005FF751 /* lice_svg.cpp */, + 33BD26C00ECF7830000A367A /* lice_bezier.h */, + 33BD26C10ECF7830000A367A /* lice_bmp.cpp */, + 33BD26C20ECF7830000A367A /* lice_ico.cpp */, + 33BD26C30ECF7830000A367A /* lice_image.cpp */, + 33BD26C40ECF7830000A367A /* lice_jpg_write.cpp */, + 33BD26C50ECF7830000A367A /* lice_pcx.cpp */, + 33BD26C60ECF7830000A367A /* lice_png_write.cpp */, + 33BD26C70ECF7830000A367A /* lice_text.h */, + 33BD26C80ECF7830000A367A /* lice_textnew.cpp */, + 33343C230CE4DBBB00FF8CE6 /* lice_combine.h */, + 33343C240CE4DBBB00FF8CE6 /* lice_gif.cpp */, + 33343C250CE4DBBB00FF8CE6 /* lice_jpg.cpp */, + 33343C260CE4DBBB00FF8CE6 /* lice_line.cpp */, + 33343C270CE4DBBB00FF8CE6 /* lice_png.cpp */, + 33343C280CE4DBBB00FF8CE6 /* lice_texgen.cpp */, + 33343C290CE4DBBB00FF8CE6 /* lice_text.cpp */, + 33343C2A0CE4DBBB00FF8CE6 /* lice.cpp */, + 33343C2B0CE4DBBB00FF8CE6 /* lice.h */, + 33343C200CE4DB9E00FF8CE6 /* lice_arc.cpp */, + 33343C1F0CE4DB9200FF8CE6 /* giflib */, + 33343C1E0CE4DB8E00FF8CE6 /* JPeglib */, + 33343C1D0CE4DB8A00FF8CE6 /* Zlib */, + 33343C1C0CE4DB8100FF8CE6 /* PNGlib */, + ); + name = LICE; + sourceTree = ""; + }; + 33343C1C0CE4DB8100FF8CE6 /* PNGlib */ = { + isa = PBXGroup; + children = ( + 33343D0D0CE4DD1F00FF8CE6 /* png.c */, + 33343D0E0CE4DD1F00FF8CE6 /* png.h */, + 33343D0F0CE4DD1F00FF8CE6 /* pngconf.h */, + 33343D100CE4DD1F00FF8CE6 /* pngerror.c */, + 33343D120CE4DD1F00FF8CE6 /* pngget.c */, + 33343D130CE4DD1F00FF8CE6 /* pngmem.c */, + 33343D140CE4DD1F00FF8CE6 /* pngpread.c */, + 33343D150CE4DD1F00FF8CE6 /* pngread.c */, + 33343D160CE4DD1F00FF8CE6 /* pngrio.c */, + 33343D170CE4DD1F00FF8CE6 /* pngrtran.c */, + 33343D180CE4DD1F00FF8CE6 /* pngrutil.c */, + 33343D190CE4DD1F00FF8CE6 /* pngset.c */, + 33343D1B0CE4DD1F00FF8CE6 /* pngtrans.c */, + 33343D1D0CE4DD1F00FF8CE6 /* pngwio.c */, + 33343D1E0CE4DD1F00FF8CE6 /* pngwrite.c */, + 33343D1F0CE4DD1F00FF8CE6 /* pngwtran.c */, + 33343D200CE4DD1F00FF8CE6 /* pngwutil.c */, + ); + name = PNGlib; + sourceTree = ""; + }; + 33343C1D0CE4DB8A00FF8CE6 /* Zlib */ = { + isa = PBXGroup; + children = ( + 33343CE50CE4DCFB00FF8CE6 /* adler32.c */, + 33343CE60CE4DCFB00FF8CE6 /* compress.c */, + 33343CE70CE4DCFB00FF8CE6 /* crc32.c */, + 33343CE80CE4DCFB00FF8CE6 /* crc32.h */, + 33343CE90CE4DCFB00FF8CE6 /* deflate.c */, + 33343CEA0CE4DCFB00FF8CE6 /* deflate.h */, + 33343CEC0CE4DCFB00FF8CE6 /* gzio.c */, + 33343CED0CE4DCFB00FF8CE6 /* infback.c */, + 33343CEE0CE4DCFB00FF8CE6 /* inffast.c */, + 33343CEF0CE4DCFB00FF8CE6 /* inffast.h */, + 33343CF00CE4DCFB00FF8CE6 /* inffixed.h */, + 33343CF10CE4DCFB00FF8CE6 /* inflate.c */, + 33343CF20CE4DCFB00FF8CE6 /* inflate.h */, + 33343CF30CE4DCFB00FF8CE6 /* inftrees.c */, + 33343CF40CE4DCFB00FF8CE6 /* inftrees.h */, + 33343CF60CE4DCFB00FF8CE6 /* trees.c */, + 33343CF70CE4DCFB00FF8CE6 /* trees.h */, + 33343CF80CE4DCFB00FF8CE6 /* uncompr.c */, + 33343CF90CE4DCFB00FF8CE6 /* zconf.h */, + 33343CFA0CE4DCFB00FF8CE6 /* zconf.in.h */, + 33343CFB0CE4DCFB00FF8CE6 /* zlib.h */, + 33343CFC0CE4DCFB00FF8CE6 /* zutil.c */, + 33343CFD0CE4DCFB00FF8CE6 /* zutil.h */, + ); + name = Zlib; + sourceTree = ""; + }; + 33343C1E0CE4DB8E00FF8CE6 /* JPeglib */ = { + isa = PBXGroup; + children = ( + 33343C400CE4DBE200FF8CE6 /* jcapimin.c */, + 33343C410CE4DBE200FF8CE6 /* jcapistd.c */, + 33343C420CE4DBE200FF8CE6 /* jccoefct.c */, + 33343C430CE4DBE200FF8CE6 /* jccolor.c */, + 33343C440CE4DBE200FF8CE6 /* jcdctmgr.c */, + 33343C450CE4DBE200FF8CE6 /* jchuff.c */, + 33343C460CE4DBE200FF8CE6 /* jchuff.h */, + 33343C470CE4DBE200FF8CE6 /* jcinit.c */, + 33343C480CE4DBE200FF8CE6 /* jcmainct.c */, + 33343C490CE4DBE200FF8CE6 /* jcmarker.c */, + 33343C4A0CE4DBE200FF8CE6 /* jcmaster.c */, + 33343C4B0CE4DBE200FF8CE6 /* jcomapi.c */, + 33343C4C0CE4DBE200FF8CE6 /* jconfig.h */, + 33343C4D0CE4DBE200FF8CE6 /* jcparam.c */, + 33343C4E0CE4DBE200FF8CE6 /* jcphuff.c */, + 33343C4F0CE4DBE200FF8CE6 /* jcprepct.c */, + 33343C500CE4DBE200FF8CE6 /* jcsample.c */, + 33343C510CE4DBE200FF8CE6 /* jctrans.c */, + 33343C520CE4DBE200FF8CE6 /* jdapimin.c */, + 33343C530CE4DBE200FF8CE6 /* jdapistd.c */, + 33343C540CE4DBE200FF8CE6 /* jdatadst.c */, + 33343C550CE4DBE200FF8CE6 /* jdatasrc.c */, + 33343C560CE4DBE200FF8CE6 /* jdcoefct.c */, + 33343C570CE4DBE200FF8CE6 /* jdcolor.c */, + 33343C580CE4DBE200FF8CE6 /* jdct.h */, + 33343C590CE4DBE200FF8CE6 /* jddctmgr.c */, + 33343C5A0CE4DBE200FF8CE6 /* jdhuff.c */, + 33343C5B0CE4DBE200FF8CE6 /* jdhuff.h */, + 33343C5C0CE4DBE200FF8CE6 /* jdinput.c */, + 33343C5D0CE4DBE200FF8CE6 /* jdmainct.c */, + 33343C5E0CE4DBE200FF8CE6 /* jdmarker.c */, + 33343C5F0CE4DBE200FF8CE6 /* jdmaster.c */, + 33343C600CE4DBE200FF8CE6 /* jdmerge.c */, + 33343C610CE4DBE200FF8CE6 /* jdphuff.c */, + 33343C620CE4DBE200FF8CE6 /* jdpostct.c */, + 33343C630CE4DBE200FF8CE6 /* jdsample.c */, + 33343C640CE4DBE200FF8CE6 /* jdtrans.c */, + 33343C650CE4DBE200FF8CE6 /* jerror.c */, + 33343C660CE4DBE200FF8CE6 /* jerror.h */, + 33343C670CE4DBE200FF8CE6 /* jfdctflt.c */, + 33343C680CE4DBE200FF8CE6 /* jfdctfst.c */, + 33343C690CE4DBE200FF8CE6 /* jfdctint.c */, + 33343C6A0CE4DBE200FF8CE6 /* jidctflt.c */, + 33343C6B0CE4DBE200FF8CE6 /* jidctfst.c */, + 33343C6C0CE4DBE200FF8CE6 /* jidctint.c */, + 33343C6D0CE4DBE200FF8CE6 /* jidctred.c */, + 33343C6E0CE4DBE200FF8CE6 /* jinclude.h */, + 33343C6F0CE4DBE200FF8CE6 /* jmemmgr.c */, + 33343C700CE4DBE200FF8CE6 /* jmemnobs.c */, + 33343C710CE4DBE200FF8CE6 /* jmemsys.h */, + 33343C720CE4DBE200FF8CE6 /* jmorecfg.h */, + 33343C730CE4DBE200FF8CE6 /* jpegint.h */, + 33343C740CE4DBE200FF8CE6 /* jpeglib.h */, + 33343C750CE4DBE200FF8CE6 /* jquant1.c */, + 33343C760CE4DBE200FF8CE6 /* jquant2.c */, + 33343C770CE4DBE200FF8CE6 /* jutils.c */, + 33343C780CE4DBE200FF8CE6 /* jversion.h */, + ); + name = JPeglib; + sourceTree = ""; + }; + 33343C1F0CE4DB9200FF8CE6 /* giflib */ = { + isa = PBXGroup; + children = ( + 33343C340CE4DBD200FF8CE6 /* config.h */, + 33343C350CE4DBD200FF8CE6 /* dgif_lib.c */, + 33343C360CE4DBD200FF8CE6 /* egif_lib.c */, + 33343C370CE4DBD200FF8CE6 /* gif_hash.c */, + 33343C380CE4DBD200FF8CE6 /* gif_hash.h */, + 33343C390CE4DBD200FF8CE6 /* gif_lib_private.h */, + 33343C3A0CE4DBD200FF8CE6 /* gif_lib.h */, + 33343C3B0CE4DBD200FF8CE6 /* gifalloc.c */, + ); + name = giflib; + sourceTree = ""; + }; + 33651CE110B766B6005FF751 /* tinyxml */ = { + isa = PBXGroup; + children = ( + 33651CE310B766E1005FF751 /* libxml_tinyxml.cpp */, + 33651CE410B766E1005FF751 /* libxml_tinyxml.h */, + 33651CE510B766E1005FF751 /* svgtiny_colors.c */, + 33651CE610B766E1005FF751 /* tinystr.cpp */, + 33651CE710B766E1005FF751 /* tinystr.h */, + 33651CE810B766E1005FF751 /* tinyxml.cpp */, + 33651CE910B766E1005FF751 /* tinyxml.h */, + 33651CEA10B766E1005FF751 /* tinyxmlerror.cpp */, + 33651CEB10B766E1005FF751 /* tinyxmlparser.cpp */, + ); + name = tinyxml; + sourceTree = ""; + }; + 33BD26AA0ECF77F9000A367A /* plush2 */ = { + isa = PBXGroup; + children = ( + 33BD26AC0ECF7811000A367A /* pl_cam.cpp */, + 33BD26AD0ECF7811000A367A /* pl_make.cpp */, + 33BD26AE0ECF7811000A367A /* pl_math.cpp */, + 33BD26AF0ECF7811000A367A /* pl_obj.cpp */, + 33BD26B00ECF7811000A367A /* pl_pf_tex.h */, + 33BD26B10ECF7811000A367A /* pl_putface.cpp */, + 33BD26B20ECF7811000A367A /* pl_read_3ds.cpp */, + 33BD26B30ECF7811000A367A /* pl_read_cob.cpp */, + 33BD26B40ECF7811000A367A /* pl_read_jaw.cpp */, + 33BD26B50ECF7811000A367A /* pl_spline.cpp */, + 33BD26B60ECF7811000A367A /* plush.h */, + ); + name = plush2; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* test */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = test; + productInstallPath = "$(HOME)/Applications"; + productName = test; + productReference = 8D1107320486CEB800E47090 /* test.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */; + compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* test */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D1107260486CEB800E47090 /* test */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072D0486CEB800E47090 /* main.m in Sources */, + 33343C070CE4DB5D00FF8CE6 /* swell-dlg.mm in Sources */, + 33343C130CE4DB7000FF8CE6 /* swell-gdi.mm in Sources */, + 33343C140CE4DB7000FF8CE6 /* swell-ini.cpp in Sources */, + 33343C150CE4DB7000FF8CE6 /* swell-kb.mm in Sources */, + 33343C160CE4DB7000FF8CE6 /* swell-menu.mm in Sources */, + 33343C170CE4DB7000FF8CE6 /* swell-miscdlg.mm in Sources */, + 33343C180CE4DB7000FF8CE6 /* swell-wnd.mm in Sources */, + 33343C190CE4DB7000FF8CE6 /* swell.cpp in Sources */, + 33343C210CE4DB9E00FF8CE6 /* lice_arc.cpp in Sources */, + 33343C2D0CE4DBBB00FF8CE6 /* lice_gif.cpp in Sources */, + 33343C2E0CE4DBBB00FF8CE6 /* lice_jpg.cpp in Sources */, + 33343C2F0CE4DBBB00FF8CE6 /* lice_line.cpp in Sources */, + 33343C300CE4DBBB00FF8CE6 /* lice_png.cpp in Sources */, + 33343C310CE4DBBB00FF8CE6 /* lice_texgen.cpp in Sources */, + 33343C320CE4DBBB00FF8CE6 /* lice_text.cpp in Sources */, + 33343C330CE4DBBB00FF8CE6 /* lice.cpp in Sources */, + 33343C3C0CE4DBD200FF8CE6 /* dgif_lib.c in Sources */, + 33343C3D0CE4DBD200FF8CE6 /* egif_lib.c in Sources */, + 33343C3E0CE4DBD200FF8CE6 /* gif_hash.c in Sources */, + 33343C3F0CE4DBD200FF8CE6 /* gifalloc.c in Sources */, + 33343C790CE4DBE200FF8CE6 /* jcapimin.c in Sources */, + 33343C7A0CE4DBE200FF8CE6 /* jcapistd.c in Sources */, + 33343C7B0CE4DBE200FF8CE6 /* jccoefct.c in Sources */, + 33343C7C0CE4DBE200FF8CE6 /* jccolor.c in Sources */, + 33343C7D0CE4DBE200FF8CE6 /* jcdctmgr.c in Sources */, + 33343C7E0CE4DBE200FF8CE6 /* jchuff.c in Sources */, + 33343C7F0CE4DBE200FF8CE6 /* jcinit.c in Sources */, + 33343C800CE4DBE200FF8CE6 /* jcmainct.c in Sources */, + 33343C810CE4DBE200FF8CE6 /* jcmarker.c in Sources */, + 33343C820CE4DBE200FF8CE6 /* jcmaster.c in Sources */, + 33343C830CE4DBE200FF8CE6 /* jcomapi.c in Sources */, + 33343C840CE4DBE200FF8CE6 /* jcparam.c in Sources */, + 33343C850CE4DBE200FF8CE6 /* jcphuff.c in Sources */, + 33343C860CE4DBE200FF8CE6 /* jcprepct.c in Sources */, + 33343C870CE4DBE200FF8CE6 /* jcsample.c in Sources */, + 33343C880CE4DBE200FF8CE6 /* jctrans.c in Sources */, + 33343C890CE4DBE200FF8CE6 /* jdapimin.c in Sources */, + 33343C8A0CE4DBE200FF8CE6 /* jdapistd.c in Sources */, + 33343C8B0CE4DBE200FF8CE6 /* jdatadst.c in Sources */, + 33343C8C0CE4DBE200FF8CE6 /* jdatasrc.c in Sources */, + 33343C8D0CE4DBE200FF8CE6 /* jdcoefct.c in Sources */, + 33343C8E0CE4DBE200FF8CE6 /* jdcolor.c in Sources */, + 33343C8F0CE4DBE200FF8CE6 /* jddctmgr.c in Sources */, + 33343C900CE4DBE200FF8CE6 /* jdhuff.c in Sources */, + 33343C910CE4DBE200FF8CE6 /* jdinput.c in Sources */, + 33343C920CE4DBE200FF8CE6 /* jdmainct.c in Sources */, + 33343C930CE4DBE200FF8CE6 /* jdmarker.c in Sources */, + 33343C940CE4DBE200FF8CE6 /* jdmaster.c in Sources */, + 33343C950CE4DBE200FF8CE6 /* jdmerge.c in Sources */, + 33343C960CE4DBE200FF8CE6 /* jdphuff.c in Sources */, + 33343C970CE4DBE200FF8CE6 /* jdpostct.c in Sources */, + 33343C980CE4DBE200FF8CE6 /* jdsample.c in Sources */, + 33343C990CE4DBE200FF8CE6 /* jdtrans.c in Sources */, + 33343C9A0CE4DBE200FF8CE6 /* jerror.c in Sources */, + 33343C9B0CE4DBE200FF8CE6 /* jfdctflt.c in Sources */, + 33343C9C0CE4DBE200FF8CE6 /* jfdctfst.c in Sources */, + 33343C9D0CE4DBE200FF8CE6 /* jfdctint.c in Sources */, + 33343C9E0CE4DBE200FF8CE6 /* jidctflt.c in Sources */, + 33343C9F0CE4DBE200FF8CE6 /* jidctfst.c in Sources */, + 33343CA00CE4DBE200FF8CE6 /* jidctint.c in Sources */, + 33343CA10CE4DBE200FF8CE6 /* jidctred.c in Sources */, + 33343CA20CE4DBE200FF8CE6 /* jmemmgr.c in Sources */, + 33343CA30CE4DBE200FF8CE6 /* jmemnobs.c in Sources */, + 33343CA40CE4DBE200FF8CE6 /* jquant1.c in Sources */, + 33343CA50CE4DBE200FF8CE6 /* jquant2.c in Sources */, + 33343CA60CE4DBE200FF8CE6 /* jutils.c in Sources */, + 33343CFE0CE4DCFB00FF8CE6 /* adler32.c in Sources */, + 33343CFF0CE4DCFB00FF8CE6 /* compress.c in Sources */, + 33343D000CE4DCFB00FF8CE6 /* crc32.c in Sources */, + 33343D010CE4DCFB00FF8CE6 /* deflate.c in Sources */, + 33343D030CE4DCFB00FF8CE6 /* gzio.c in Sources */, + 33343D040CE4DCFB00FF8CE6 /* infback.c in Sources */, + 33343D050CE4DCFB00FF8CE6 /* inffast.c in Sources */, + 33343D060CE4DCFB00FF8CE6 /* inflate.c in Sources */, + 33343D070CE4DCFB00FF8CE6 /* inftrees.c in Sources */, + 33343D090CE4DCFB00FF8CE6 /* trees.c in Sources */, + 33343D0A0CE4DCFB00FF8CE6 /* uncompr.c in Sources */, + 33343D0B0CE4DCFB00FF8CE6 /* zutil.c in Sources */, + 33343D210CE4DD1F00FF8CE6 /* png.c in Sources */, + 33343D220CE4DD1F00FF8CE6 /* pngerror.c in Sources */, + 33343D240CE4DD1F00FF8CE6 /* pngget.c in Sources */, + 33343D250CE4DD1F00FF8CE6 /* pngmem.c in Sources */, + 33343D260CE4DD1F00FF8CE6 /* pngpread.c in Sources */, + 33343D270CE4DD1F00FF8CE6 /* pngread.c in Sources */, + 33343D280CE4DD1F00FF8CE6 /* pngrio.c in Sources */, + 33343D290CE4DD1F00FF8CE6 /* pngrtran.c in Sources */, + 33343D2A0CE4DD1F00FF8CE6 /* pngrutil.c in Sources */, + 33343D2B0CE4DD1F00FF8CE6 /* pngset.c in Sources */, + 33343D2D0CE4DD1F00FF8CE6 /* pngtrans.c in Sources */, + 33343D2F0CE4DD1F00FF8CE6 /* pngwio.c in Sources */, + 33343D300CE4DD1F00FF8CE6 /* pngwrite.c in Sources */, + 33343D310CE4DD1F00FF8CE6 /* pngwtran.c in Sources */, + 33343D320CE4DD1F00FF8CE6 /* pngwutil.c in Sources */, + 33E075650CE4DDD3005DDE14 /* Controller.mm in Sources */, + 33BD26B70ECF7811000A367A /* pl_cam.cpp in Sources */, + 33BD26B80ECF7811000A367A /* pl_make.cpp in Sources */, + 33BD26B90ECF7811000A367A /* pl_math.cpp in Sources */, + 33BD26BA0ECF7811000A367A /* pl_obj.cpp in Sources */, + 33BD26BB0ECF7811000A367A /* pl_putface.cpp in Sources */, + 33BD26BC0ECF7811000A367A /* pl_read_3ds.cpp in Sources */, + 33BD26BD0ECF7811000A367A /* pl_read_cob.cpp in Sources */, + 33BD26BE0ECF7811000A367A /* pl_read_jaw.cpp in Sources */, + 33BD26BF0ECF7811000A367A /* pl_spline.cpp in Sources */, + 33BD26C90ECF7830000A367A /* lice_bmp.cpp in Sources */, + 33BD26CA0ECF7830000A367A /* lice_ico.cpp in Sources */, + 33BD26CB0ECF7830000A367A /* lice_image.cpp in Sources */, + 33BD26CC0ECF7830000A367A /* lice_jpg_write.cpp in Sources */, + 33BD26CD0ECF7830000A367A /* lice_pcx.cpp in Sources */, + 33BD26CE0ECF7830000A367A /* lice_png_write.cpp in Sources */, + 33BD26CF0ECF7830000A367A /* lice_textnew.cpp in Sources */, + 33BD26DF0ECF78C3000A367A /* fly.cpp in Sources */, + 33651CDE10B766A6005FF751 /* swell-misc.mm in Sources */, + 33651CE010B766B2005FF751 /* lice_svg.cpp in Sources */, + 33651CEC10B766E1005FF751 /* libxml_tinyxml.cpp in Sources */, + 33651CED10B766E1005FF751 /* svgtiny_colors.c in Sources */, + 33651CEE10B766E1005FF751 /* tinystr.cpp in Sources */, + 33651CEF10B766E1005FF751 /* tinyxml.cpp in Sources */, + 33651CF010B766E1005FF751 /* tinyxmlerror.cpp in Sources */, + 33651CF110B766E1005FF751 /* tinyxmlparser.cpp in Sources */, + 3350A9D2146B63B500702E1F /* lice_lvg.cpp in Sources */, + 3350A9D3146B63B500702E1F /* lice_palette.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 29B97319FDCFA39411CA2CEA /* English */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = test; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = test; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + GCC_PREPROCESSOR_DEFINITIONS = PNG_WRITE_SUPPORTED; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + GCC_PREPROCESSOR_DEFINITIONS = PNG_WRITE_SUPPORTED; + GCC_VERSION = 4.0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/WDL/lineparse.h b/WDL/lineparse.h new file mode 100644 index 00000000..a0164a4f --- /dev/null +++ b/WDL/lineparse.h @@ -0,0 +1,331 @@ +/* + WDL - lineparse.h + Copyright (C) 2005 Cockos Incorporated + Copyright (C) 1999-2004 Nullsoft, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple line parsing class. This class is also used in NSIS, + http://nsis.sf.net. In particular, it allows for multiple space delimited tokens + on a line, with a choice of three quotes (`bla`, 'bla', or "bla") to contain any + items that may have spaces. + + For a bigger reference on the format, you can refer to NSIS's documentation. + +*/ + +#ifndef WDL_LINEPARSE_H_ +#define WDL_LINEPARSE_H_ + + +#ifndef WDL_LINEPARSE_IMPL_ONLY +class LineParser +{ + public: + int getnumtokens() const { return (m_nt-m_eat)>=0 ? (m_nt-m_eat) : 0; } + #ifdef WDL_LINEPARSE_INTF_ONLY + int parse(const char *line, int ignore_escaping=1); //-1 on error + + double gettoken_float(int token, int *success=NULL) const; + int gettoken_int(int token, int *success=NULL) const; + unsigned int gettoken_uint(int token, int *success=NULL) const; + const char *gettoken_str(int token) const; + int gettoken_enum(int token, const char *strlist) const; // null seperated list + + void set_one_token(const char *ptr); + #endif + + void eattoken() { m_eat++; } + bool InCommentBlock() const { return m_bCommentBlock; } + + + LineParser(bool bCommentBlock=false) + { + m_bCommentBlock=bCommentBlock; + m_nt=m_eat=0; + m_tokens=0; + m_tmpbuf_used=0; + } + + ~LineParser() + { + freetokens(); + } + +#endif // !WDL_LINEPARSE_IMPL_ONLY + + + +#ifndef WDL_LINEPARSE_INTF_ONLY + #ifdef WDL_LINEPARSE_IMPL_ONLY + #define WDL_LINEPARSE_PREFIX LineParser:: + #define WDL_LINEPARSE_DEFPARM(x) + #else + #define WDL_LINEPARSE_PREFIX + #define WDL_LINEPARSE_DEFPARM(x) =(x) + #endif + + int WDL_LINEPARSE_PREFIX parse(const char *line, int ignore_escaping WDL_LINEPARSE_DEFPARM(1)) + { + freetokens(); + bool bPrevCB=m_bCommentBlock; + int n=doline(line, ignore_escaping); + if (n) { m_nt=0; return n; } + if (m_nt) + { + m_bCommentBlock=bPrevCB; + m_tokens=(char**)tmpbufalloc(sizeof(char*)*m_nt); + if (m_tokens) memset(m_tokens,0,m_nt * sizeof(char*)); + n=doline(line, ignore_escaping); + if (n) + { + freetokens(); + return -1; + } + } + return 0; + } + void WDL_LINEPARSE_PREFIX set_one_token(const char *ptr) + { + freetokens(); + m_eat=0; + m_nt=1; + m_tokens=(char **)tmpbufalloc(sizeof(char *)); + m_tokens[0]=tmpbufalloc(strlen(ptr)+1); + if (m_tokens[0]) strcpy(m_tokens[0],ptr); + } + + double WDL_LINEPARSE_PREFIX gettoken_float(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const + { + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token]) + { + if (success) *success=0; + return 0.0; + } + char *t=m_tokens[token]; + if (success) + *success=*t?1:0; + + char buf[512]; + char *ot=buf; + while (*t&&(ot-buf)<500) + { + char c=*t++; + if (success && (c < '0' || c > '9')&&c != '.'&&c!=',') *success=0; + *ot++=c==','?'.':c; + } + *ot=0; + return atof(buf); + } + + int WDL_LINEPARSE_PREFIX gettoken_int(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const + { + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0]) + { + if (success) *success=0; + return 0; + } + char *tmp; + int l; + if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0); + else l=(int)strtoul(m_tokens[token],&tmp,0); + if (success) *success=! (int)(*tmp); + return l; + } + + unsigned int WDL_LINEPARSE_PREFIX gettoken_uint(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const + { + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0]) + { + if (success) *success=0; + return 0; + } + char *tmp; + const char* p=m_tokens[token]; + if (p[0] == '-') ++p; + unsigned int val=(int)strtoul(p, &tmp, 0); + if (success) *success=! (int)(*tmp); + return val; + } + + const char * WDL_LINEPARSE_PREFIX gettoken_str(int token) const + { + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token]) return ""; + return m_tokens[token]; + } + + int WDL_LINEPARSE_PREFIX gettoken_enum(int token, const char *strlist) const // null seperated list + { + int x=0; + const char *tt=gettoken_str(token); + if (tt && *tt) while (*strlist) + { +#ifdef _WIN32 + if (!stricmp(tt,strlist)) return x; +#else + if (!strcasecmp(tt,strlist)) return x; +#endif + strlist+=strlen(strlist)+1; + x++; + } + return -1; + } + +#ifndef WDL_LINEPARSE_IMPL_ONLY + private: +#endif + + void WDL_LINEPARSE_PREFIX freetokens() + { + if (m_tokens) + { + int x; + for (x = 0; x < m_nt; x ++) tmpbuffree(m_tokens[x]); + tmpbuffree((char*)m_tokens); + } + m_tmpbuf_used=0; + m_tokens=0; + m_nt=0; + } + + int WDL_LINEPARSE_PREFIX doline(const char *line, int ignore_escaping) + { + m_nt=0; + if ( m_bCommentBlock ) + { + while ( *line ) + { + if ( *line == '*' && *(line+1) == '/' ) + { + m_bCommentBlock=false; // Found end of comment block + line+=2; + break; + } + line++; + } + } + while (*line == ' ' || *line == '\t') line++; + while (*line) + { + int lstate=0; // 1=", 2=`, 4=' + if (*line == ';' || *line == '#') break; + if (*line == '/' && *(line+1) == '*') + { + m_bCommentBlock = true; + line+=2; + return doline(line, ignore_escaping); + } + if (*line == '\"') lstate=1; + else if (*line == '\'') lstate=2; + else if (*line == '`') lstate=4; + if (lstate) line++; + int nc=0; + const char *p = line; + while (*line) + { + if (line[0] == '$' && line[1] == '\\') { + switch (line[2]) { + case '"': + case '\'': + case '`': + nc += ignore_escaping ? 3 : 1; + line += 3; + continue; + } + } + if (lstate==1 && *line =='\"') break; + if (lstate==2 && *line =='\'') break; + if (lstate==4 && *line =='`') break; + if (!lstate && (*line == ' ' || *line == '\t')) break; + line++; + nc++; + } + if (m_tokens) + { + int i; + m_tokens[m_nt]=tmpbufalloc(nc+1); + for (i = 0; p < line; i++, p++) { + if (!ignore_escaping && p[0] == '$' && p[1] == '\\') { + switch (p[2]) { + case '"': + case '\'': + case '`': + p += 2; + } + } + m_tokens[m_nt][i] = *p; + } + m_tokens[m_nt][nc]=0; + } + m_nt++; + if (lstate) + { + if (*line) line++; + else return -2; + } + while (*line == ' ' || *line == '\t') line++; + } + return 0; + } + + char * WDL_LINEPARSE_PREFIX tmpbufalloc(int sz) + { + if (sz<1)sz=1; + if (sz+m_tmpbuf_used <= (int)sizeof(m_tmpbuf)) + { + m_tmpbuf_used+=sz; + return m_tmpbuf + m_tmpbuf_used - sz; + } + return (char *)malloc(sz); + } + void WDL_LINEPARSE_PREFIX tmpbuffree(char *p) + { + if (p < m_tmpbuf || p >= m_tmpbuf + sizeof(m_tmpbuf)) free(p); + } + + #undef WDL_LINEPARSE_PREFIX + #undef WDL_LINEPARSE_DEFPARM +#endif // ! WDL_LINEPARSE_INTF_ONLY + +#ifndef WDL_LINEPARSE_IMPL_ONLY + private: + +#ifdef WDL_LINEPARSE_INTF_ONLY + void freetokens(); + int doline(const char *line, int ignore_escaping); + char *tmpbufalloc(int sz); + void tmpbuffree(char *p); +#endif + + int m_eat; + int m_nt; + int m_tmpbuf_used; + bool m_bCommentBlock; + char **m_tokens; + char m_tmpbuf[2048]; +}; +#endif//!WDL_LINEPARSE_IMPL_ONLY +#endif//WDL_LINEPARSE_H_ + diff --git a/WDL/makedist.bat b/WDL/makedist.bat new file mode 100644 index 00000000..7cae1745 --- /dev/null +++ b/WDL/makedist.bat @@ -0,0 +1,13 @@ +del wdl.zip +cd.. +zip -X9r wdl\wdl.zip wdl -i *.c *.cpp *.cc *.h *.m *.mm *.png *.ico *.txt *.bat *.rc *.plist *.dsp *.dsw *.pbxproj *.strings *.nib *.php *.exp *.vcproj *.vcxproj *_prefix.pch *.r *.xib *.sln *.icns + +zip -X9r wdl\wdl.zip wdl\eel2\asm-nseel-x64-macho.o + +zip -X9r wdl\wdl.zip wdl\iplug\example\img.zip + +zip -X9r wdl\wdl.zip wdl\jnetlib\makefile +zip -X9r wdl\wdl.zip wdl\jpeglib\readme +zip -X9r wdl\wdl.zip wdl\giflib\authors wdl\giflib\changelog wdl\giflib\copying wdl\giflib\developers wdl\giflib\readme + +cd wdl diff --git a/WDL/mergesort.h b/WDL/mergesort.h new file mode 100644 index 00000000..549eebf4 --- /dev/null +++ b/WDL/mergesort.h @@ -0,0 +1,65 @@ +#ifndef _WDL_MERGESORT_H_ +#define _WDL_MERGESORT_H_ + + +static void WDL_mergesort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *), char *tmpspace) +{ + char *b1,*b2; + size_t n1, n2; + + if (nmemb < 2) return; + + n1 = nmemb / 2; + b1 = (char *) base; + n2 = nmemb - n1; + b2 = b1 + (n1 * size); + + if (nmemb>2) + { + WDL_mergesort(b1, n1, size, compar, tmpspace); + WDL_mergesort(b2, n2, size, compar, tmpspace); + } + + + do + { + if (compar(b1, b2) > 0) // out of order, go to full merge + { + int sofar = b1-(char*)base; + memcpy(tmpspace,base,sofar); + memcpy(tmpspace+sofar, b2, size); + b2 += size; + n2--; + + char *writeptr=tmpspace+sofar+size; + while (n1 > 0 && n2 > 0) + { + if (compar(b1, b2) > 0) + { + memcpy(writeptr, b2, size); + b2 += size; + n2--; + } + else + { + memcpy(writeptr, b1, size); + b1 += size; + n1--; + } + writeptr += size; + } + + if (n1 > 0) memcpy(writeptr, b1, n1 * size); + memcpy(base, tmpspace, (nmemb - n2) * size); + + break; + } + + // in order, just advance + b1 += size; + n1--; + } + while (n1 > 0 && n2 > 0); +} + +#endif//_WDL_MERGESORT_H_ \ No newline at end of file diff --git a/WDL/mp3write.h b/WDL/mp3write.h new file mode 100644 index 00000000..1dc97fbc --- /dev/null +++ b/WDL/mp3write.h @@ -0,0 +1,138 @@ +/* + WDL - mp3write.h + Copyright (C) 2005 Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple class for writing MP3 files (using lameencdec.h) + +*/ + + +#ifndef _MP3WRITE_H_ +#define _MP3WRITE_H_ + + +#include +#include "lameencdec.h" + +class mp3Writer +{ + public: + // appending doesnt check sample types + mp3Writer() + { + m_enc=0; + m_fp=0; + m_srate=0; + m_nch=0; + } + + mp3Writer(char *filename, int nch, int srate, int bitrate, int allow_append=1) + { + m_enc=0; + m_fp=0; + m_srate=0; + m_nch=0; + Open(filename,nch,srate,bitrate,allow_append); + + } + + int Open(char *filename, int nch, int srate, int bitrate, int allow_append=1) + { + m_fp=0; + if (allow_append) + { + m_fp=fopen(filename,"r+b"); + if (m_fp) + { + fseek(m_fp,0,SEEK_END); + } + } + if (!m_fp) + { + m_fp=fopen(filename,"wb"); + } + m_nch=nch>1?2:1; + m_srate=srate; + m_enc = new LameEncoder(srate,nch,bitrate); + if (m_enc->Status()) + { + delete m_enc; + m_enc=0; + } + return m_fp && m_enc; + } + + ~mp3Writer() + { + if (m_fp) + { + if (m_enc) + { + m_enc->Encode(NULL,0); + if (m_enc->outqueue.Available()) + { + fwrite(m_enc->outqueue.Get(),1,m_enc->outqueue.GetSize(),m_fp); + fflush(m_fp); + m_enc->outqueue.Advance(m_enc->outqueue.GetSize()); + m_enc->outqueue.Compact(); + } + } + + fclose(m_fp); + m_fp=0; + } + if (m_enc) + { + delete m_enc; + m_enc=0; + } + } + + int Status() { return m_enc && m_fp; } + + void WriteFloats(float *samples, int nsamples) + { + if (!m_fp || !m_enc) return; + + m_enc->Encode(samples,nsamples/m_nch); + if (m_enc->outqueue.Available()) + { + fwrite(m_enc->outqueue.Get(),1,m_enc->outqueue.GetSize(),m_fp); + fflush(m_fp); + m_enc->outqueue.Advance(m_enc->outqueue.GetSize()); + m_enc->outqueue.Compact(); + } + + } + + int get_nch() { return m_nch; } + int get_srate() { return m_srate; } + + private: + FILE *m_fp; + int m_nch,m_srate; + LameEncoder *m_enc; +}; + + +#endif//_MP3WRITE_H_ \ No newline at end of file diff --git a/WDL/mutex.h b/WDL/mutex.h new file mode 100644 index 00000000..6420986c --- /dev/null +++ b/WDL/mutex.h @@ -0,0 +1,238 @@ +/* + WDL - mutex.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + + This file provides a simple class that abstracts a mutex or critical section object. + On Windows it uses CRITICAL_SECTION, on everything else it uses pthread's mutex library. + It simulates the Critical Section behavior on non-Windows, as well (meaning a thread can + safely Enter the mutex multiple times, provided it Leaves the same number of times) + +*/ + +#ifndef _WDL_MUTEX_H_ +#define _WDL_MUTEX_H_ + +#ifdef _WIN32 +#include +#else + +#include +// define this if you wish to use carbon critical sections on OS X +// #define WDL_MAC_USE_CARBON_CRITSEC + +#ifdef WDL_MAC_USE_CARBON_CRITSEC +#include +#else +#include +#endif + +#ifdef __APPLE__ +#include +#endif + +#endif + +#include "wdltypes.h" + +class WDL_Mutex { + public: + WDL_Mutex() + { +#ifdef _DEBUG + _debug_cnt=0; +#endif + +#ifdef _WIN32 + InitializeCriticalSection(&m_cs); +#else +#ifdef WDL_MAC_USE_CARBON_CRITSEC + MPCreateCriticalRegion(&m_cr); +#else + m_ownerthread=0; + m_lockcnt=0; + pthread_mutex_init(&m_mutex,NULL); +#endif +#endif + } + ~WDL_Mutex() + { +#ifdef _WIN32 + DeleteCriticalSection(&m_cs); +#else +#ifdef WDL_MAC_USE_CARBON_CRITSEC + MPDeleteCriticalRegion(m_cr); +#else + pthread_mutex_destroy(&m_mutex); +#endif +#endif + } + + void Enter() + { +#ifdef _DEBUG + _debug_cnt++; +#endif + +#ifdef _WIN32 + EnterCriticalSection(&m_cs); +#else +#ifdef WDL_MAC_USE_CARBON_CRITSEC + MPEnterCriticalRegion(m_cr,kDurationForever); +#else + pthread_t tt=pthread_self(); + if (m_ownerthread==tt) m_lockcnt++; + else + { + pthread_mutex_lock(&m_mutex); + m_ownerthread=tt; + m_lockcnt=0; + } +#endif +#endif + } + + void Leave() + { +#ifdef _DEBUG + _debug_cnt--; +#endif +#ifdef _WIN32 + LeaveCriticalSection(&m_cs); +#else +#ifdef WDL_MAC_USE_CARBON_CRITSEC + MPExitCriticalRegion(m_cr); +#else + if (--m_lockcnt < 0) + { + m_ownerthread=0; + pthread_mutex_unlock(&m_mutex); + } +#endif +#endif + } + +#ifdef _DEBUG + int _debug_cnt; +#endif + + private: +#ifdef _WIN32 + CRITICAL_SECTION m_cs; +#else +#ifdef WDL_MAC_USE_CARBON_CRITSEC + MPCriticalRegionID m_cr; +#else + pthread_mutex_t m_mutex; + pthread_t m_ownerthread; + int m_lockcnt; +#endif +#endif + +} WDL_FIXALIGN; + +class WDL_MutexLock { +public: + WDL_MutexLock(WDL_Mutex *m) : m_m(m) { if (m) m->Enter(); } + ~WDL_MutexLock() { if (m_m) m_m->Leave(); } +private: + WDL_Mutex *m_m; +} WDL_FIXALIGN; + +class WDL_SharedMutex +{ + public: + WDL_SharedMutex() { m_sharedcnt=0; } + ~WDL_SharedMutex() { } + + void LockExclusive() // note: the calling thread must NOT have any shared locks, or deadlock WILL occur + { + m_mutex.Enter(); +#ifdef _WIN32 + while (m_sharedcnt>0) Sleep(1); +#else + while (m_sharedcnt>0) usleep(100); +#endif + } + void UnlockExclusive() { m_mutex.Leave(); } + + void LockShared() + { + m_mutex.Enter(); +#ifdef _WIN32 + InterlockedIncrement(&m_sharedcnt); +#elif defined (__APPLE__) + OSAtomicIncrement32(&m_sharedcnt); +#else + m_cntmutex.Enter(); + m_sharedcnt++; + m_cntmutex.Leave(); +#endif + + m_mutex.Leave(); + } + void UnlockShared() + { +#ifdef _WIN32 + InterlockedDecrement(&m_sharedcnt); +#elif defined(__APPLE__) + OSAtomicDecrement32(&m_sharedcnt); +#else + m_cntmutex.Enter(); + m_sharedcnt--; + m_cntmutex.Leave(); +#endif + } + + private: + WDL_Mutex m_mutex; +#ifdef _WIN32 + LONG m_sharedcnt; +#elif defined(__APPLE__) + int32_t m_sharedcnt; +#else + WDL_Mutex m_cntmutex; + int m_sharedcnt; +#endif +} WDL_FIXALIGN; + + + +class WDL_MutexLockShared { + public: + WDL_MutexLockShared(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockShared(); } + ~WDL_MutexLockShared() { if (m_m) m_m->UnlockShared(); } + private: + WDL_SharedMutex *m_m; +} WDL_FIXALIGN; + +class WDL_MutexLockExclusive { + public: + WDL_MutexLockExclusive(WDL_SharedMutex *m) : m_m(m) { if (m) m->LockExclusive(); } + ~WDL_MutexLockExclusive() { if (m_m) m_m->UnlockExclusive(); } + private: + WDL_SharedMutex *m_m; +} WDL_FIXALIGN; + + +#endif diff --git a/WDL/nsv/nsvbs.h b/WDL/nsv/nsvbs.h new file mode 100644 index 00000000..fcb0009a --- /dev/null +++ b/WDL/nsv/nsvbs.h @@ -0,0 +1,272 @@ +/* + LICENSE + ------- +Copyright 2005 Nullsoft, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Nullsoft nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/* +** nsvbs.h - NSV basic inline bitstream classes +** +** +** Note: these bitstream classes encode/decode everything in LSB. +** bits are stored from the lowest bit to the highest bit. +** putbits(4,0xE) will result in getbits(1)=0, getbits(1)=1, +** getbits(1)=1, getbits(1)=1 +** or of course, getbits(4) == 0xE :) +*/ + +#ifndef _NSVBS_H_ +#define _NSVBS_H_ + +#include +#include + +class nsv_GrowBuf +{ + public: + nsv_GrowBuf() { m_alloc=m_used=0; m_s=NULL; } + ~nsv_GrowBuf() { if (m_s) free(m_s); m_s=0; } + + int add(void *data, int len) + { + if (len<=0) return 0; + resize(m_used+len); + if (m_s) memcpy((char*)m_s+m_used-len,data,len); + return m_used-len; + } + + void set(void *data, int len) + { + resize(len); + if (m_s) memcpy((char*)m_s,data,len); + } + + void resize(int newlen) + { + m_used=newlen; + if (newlen > m_alloc) + { + void *ne; + m_alloc = newlen*2; + if (m_alloc < 1024) m_alloc =1024; + ne = realloc(m_s, m_alloc); + if (!ne) + { + ne=malloc(m_alloc); + if (ne) memcpy(ne,m_s,m_used); + free(m_s); + } + m_s=ne; + } + } + + int getlen() { return m_used; } + void *get() { return m_s; } + + private: + void *m_s; + int m_alloc; + int m_used; + +}; + + +class nsv_OutBS +{ +public: + nsv_OutBS() { m_used = 0; m_curb=0; } + ~nsv_OutBS() { } + + void putbits(int nbits, unsigned int value) + { + while (nbits-- > 0) + { + m_curb|=(value&1)<<(m_used&7); + if (!((++m_used)&7)) + { + m_bits.add(&m_curb,1); + m_curb=0; + } + value>>=1; + } + } + + // lets you put in any amount of data, but does not preserve endianness. + void putdata(int nbits, void *data) + { + unsigned char *c=(unsigned char *)data; + if (!(m_used&7) && nbits >= 8) + { + m_bits.add(c,nbits/8); + c+=nbits/8; + m_used+=nbits&~7; + nbits&=7; + } + while (nbits > 0) + { + int tb=nbits; + if (tb > 8) tb=8; + putbits(tb,*c++); + nbits-=tb; + } + } + + int getlen() { return m_used; } // in bits + + void *get(int *len) // len is in bytes, forces to byte aligned. + { + if (m_used&7) + { + m_bits.add(&m_curb,1); + m_used=(m_used+7)&~7; + m_curb=0; + } + *len=m_used/8; + return m_bits.get(); + } + + void clear() + { + m_used=0; + m_curb=0; + m_bits.resize(0); + } + +private: + nsv_GrowBuf m_bits; + int m_used; // bits + unsigned char m_curb; +}; + +class nsv_InBS { +public: + nsv_InBS() { m_bitpos=0; m_eof=0; } + ~nsv_InBS() { } + + void clear() + { + m_eof=0; + m_bitpos=0; + m_bits.resize(0); + } + + void add(void *data, int len) + { + m_bits.add(data,len); + m_eof=0; + } + + void addbyte(unsigned char byte) + { + add(&byte,1); + } + + void addint(unsigned int dword) + { + addbyte(dword&0xff); + addbyte((dword>>8)&0xff); + addbyte((dword>>16)&0xff); + addbyte((dword>>24)&0xff); + } + + void compact() + { + int bytepos=m_bitpos/8; + if (bytepos) + { + unsigned char *t=(unsigned char *)m_bits.get(); + int l=m_bits.getlen()-bytepos; + if (t) memcpy(t,t+bytepos,l); + m_bits.resize(l); + m_bitpos&=7; + } + m_eof=0; + } + + + void seek(int nbits) { m_bitpos+=nbits; if (m_bitpos < 0) m_bitpos=0; m_eof=m_bits.getlen()*8 < m_bitpos; } + void rewind() { m_bitpos=0; m_eof=0; } + int eof() { return m_eof; } + int avail() { if (m_eof) return 0; return m_bits.getlen()*8 - m_bitpos; } + + unsigned int getbits(int nbits) + { + unsigned int ret=0; + if (nbits <= 0) return ret; + unsigned char *t=(unsigned char *)m_bits.get(); + + if (!t || m_bits.getlen()*8 < m_bitpos+nbits) m_eof=1; + else + { + int sh=0; + t+=m_bitpos/8; + for (sh = 0; sh < nbits; sh ++) + { + ret|=((*t>>(m_bitpos&7))&1) << sh; + if (!((++m_bitpos)&7)) t++; + } + } + return ret; + } + + int getdata(int nbits, void *data) + { + unsigned char *t=(unsigned char *)data; + if (m_bits.getlen()*8 < m_bitpos+nbits) return 1; + if (!(m_bitpos&7) && nbits >= 8) + { + char *bitptr=(char*)m_bits.get(); + bitptr+=(m_bitpos/8); + if (bitptr) memcpy(t,bitptr,nbits/8); + m_bitpos+=nbits&~7; + + t+=nbits/8; + nbits&=7; + } + while (nbits > 0) + { + int nb=nbits; + if (nb > 8) nb=8; + *t++=getbits(nb); + nbits-=nb; + } + return 0; + } + + void *getcurbyteptr() + { + char *t=(char*)m_bits.get(); + if (t) return (void *)(t+(m_bitpos/8)); + return 0; + } + +private: + nsv_GrowBuf m_bits; + int m_bitpos; + int m_eof; +}; + +#endif//_NSVBS_H_ diff --git a/WDL/nsv/nsvlib.cpp b/WDL/nsv/nsvlib.cpp new file mode 100644 index 00000000..2f81d2de --- /dev/null +++ b/WDL/nsv/nsvlib.cpp @@ -0,0 +1,738 @@ +/* + LICENSE + ------- +Copyright 2005 Nullsoft, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Nullsoft nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/* +** nsvlib.cpp - NSV file/bitstream reading/writing code +** +*/ + +#include +#include +#include + +#include "nsvlib.h" + +#define NSV_HDR_DWORD (NSV_MAKETYPE('N','S','V','f')) + +#define NSV_SYNC_HEADERLEN_BITS 192 +#define NSV_SYNC_DWORD (NSV_MAKETYPE('N','S','V','s')) +#define NSV_NONSYNC_HEADERLEN_BITS 56 +#define NSV_NONSYNC_WORD 0xBEEF + +#define NSV_INVALID_SYNC_OFFSET 0x80000000 + +/* + NSV sync packet header + 32 bits: NSV_SYNC_DWORD + 32 bits: video format + 32 bits: audio format + 16 bits: width + 16 bits: height + 8 bits: framerate (see getfrate/setfrate) + + + 16 bits: audio/video sync offset + +or + + NSV nonsync packet header + 16 bits: NSV_NONSYNC_WORD + +then + +4 bits: # aux data channels present (max 15) +20 bits: video data + aux channels length +16 bits: audio data length + +-------------------------------- +sync: + 192 bit header, + 136 bits are invariant +nonsync: + 56 bit header + 16 bits are invariant + +*/ + + + + +static int is_type_char_valid(int c) +{ + c&=0xff; + return (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == ' ' || c == '-' || + c == '.' || c == '_'; +} + +static int is_type_valid(unsigned int t) +{ + return (t&0xff) != ' ' && + is_type_char_valid(t>>24) && + is_type_char_valid(t>>16) && + is_type_char_valid(t>>8) && + is_type_char_valid(t); +} + + +void nsv_type_to_string(unsigned int t, char *out) +{ + if (is_type_valid(t)) + { + out[0]=(t)&0xff; + out[1]=(t>>8)&0xff; + out[2]=(t>>16)&0xff; + out[3]=(t>>24)&0xff; + out[4]=0; + int x=3; + while (out[x]==' ' && x > 0) out[x--]=0; + } + else *out=0; +} + +unsigned int nsv_string_to_type(char *in) +{ + int n; + unsigned int ret=*in; + if (*in == ' ' || !is_type_char_valid(*in)) return 0; + in++; + for (n = 0; n < 3; n ++) + { + if (!is_type_char_valid(*in)) break; + ret|=(*in<<(8+8*n)); + in++; + } + if (*in) return 0; + return ret; +} + +// frate is specified +// XYYYYYZZ +// if !X, framerate is YYYYYZZ (1-127) +// otherwise: +// ZZ indexes base +// YYYYY is scale (0-32). +// if YYYYY < 16, then scale = 1/(YYYY+1) +// otherwise scale = YYYYY-15 + + +static double frate2double(unsigned char fr) +{ + static double fratetab[]= + { + 30.0, + 30.0*1000.0/1001.0, + 25.0, + 24.0*1000.0/1001.0, + }; + if (!(fr&0x80)) return (double)fr; + + double sc; + int d=(fr&0x7f)>>2; + if (d < 16) sc=1.0/(double)(d+1); + else sc=d-15; + + return fratetab[fr&3]*sc; +} + + + +static unsigned char double2frate(double fr) +{ + int best=0; + double best_v=1000000.0; + int x; + for (x = 0; x < 256; x ++) + { + double this_v=(fr-frate2double(x)); + + if (this_v<0) this_v=-this_v; + if (this_v < best_v) + { + best_v=this_v; + best=x; + } + } + return (unsigned char) best; +} + + + +nsv_Packeter::nsv_Packeter() +{ + vidfmt=audfmt=0; + width=height=0; + framerate_idx=0; + framerate=0.0; + syncoffset_cur=0; + video=NULL; + audio=NULL; + video_len=0; + audio_len=0; + aux_used=0; +} + +void nsv_Packeter::setVidFmt(unsigned int vfmt, unsigned int w, unsigned int h, double frt) +{ + vidfmt=vfmt; + width=w; + height=h; + framerate=frt; + framerate_idx=double2frate(frt); +} + +nsv_Packeter::~nsv_Packeter() +{ +} + +int nsv_Packeter::packet(nsv_OutBS &bs) +{ + int total_auxlen=0; + int x; + if (width >= (1<<16) || height >= (1<<16) || + !framerate_idx || framerate_idx > 255 || + !is_type_valid(audfmt) || + !is_type_valid(vidfmt) || + video_len > NSV_MAX_VIDEO_LEN || + audio_len > NSV_MAX_AUDIO_LEN || + aux_used > NSV_MAX_AUXSTREAMS || + aux_used < 0 + ) return -1; + + for (x = 0; x < aux_used; x ++) + { + if (aux_len[x] > NSV_MAX_AUX_LEN) return -1; + total_auxlen+=aux_len[x]+6; + } + + if (is_sync_frame) + { + bs.putbits(32,NSV_SYNC_DWORD); + bs.putbits(32,vidfmt); + bs.putbits(32,audfmt); + bs.putbits(16,width); + bs.putbits(16,height); + bs.putbits(8 ,framerate_idx); + bs.putbits(16,syncoffset_cur); + } + else + { + bs.putbits(16,NSV_NONSYNC_WORD); + } + + bs.putbits(4,aux_used); // no aux data channels for our streams yet + bs.putbits(20,video_len+total_auxlen); + bs.putbits(16,audio_len); + + for (x = 0; x < aux_used; x ++) + { + bs.putbits(16,aux_len[x]); // length of 0 for aux channels + bs.putbits(32,aux_types[x]); + if (aux_len[x]) bs.putdata(aux_len[x]*8,aux[x]); + } + + if (video_len) bs.putdata(video_len*8,video); + if (audio_len) bs.putdata(audio_len*8,audio); + + return 0; +} + + +void nsv_Unpacketer::reset(int full) +{ + synched=0; + is_sync_frame=0; + syncoffset_cur=0; + syncoffset=NSV_INVALID_SYNC_OFFSET; + + if (full) + { + m_auxbs=NULL; + m_audiobs=NULL; + m_videobs=NULL; + m_eof=0; + vidfmt=0; + audfmt=0; + valid=0; + width=0; + height=0; + framerate=0.0; + framerate_idx=0; + } +} + + +// returns 0 on success, >0 on needs (at least X bytes) more data, +// -1 on error (no header found in block) +int nsv_Unpacketer::unpacket(nsv_InBS &bs) +{ + int gotframe=0; + unsigned int num_aux=0; + unsigned int vl=0; + unsigned int al=0; + + while (bs.avail()>=NSV_NONSYNC_HEADERLEN_BITS) + { + if (valid && synched) + { + if (bs.avail() < NSV_NONSYNC_HEADERLEN_BITS) + return m_eof?-1:(NSV_NONSYNC_HEADERLEN_BITS-bs.avail())/8; + + unsigned int d=bs.getbits(16); + if (d == NSV_NONSYNC_WORD) + { + num_aux=bs.getbits(4); + vl=bs.getbits(20); + al=bs.getbits(16); + if (al >= NSV_MAX_AUDIO_LEN || + vl >= (NSV_MAX_VIDEO_LEN+num_aux*(NSV_MAX_AUX_LEN+6))) + { + bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); + } + else + { + if ((unsigned int)bs.avail() < 8*(vl+al)+(m_eof?0:32)) + { + int l=(al+vl+32/8)-bs.avail()/8; + bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); + return m_eof?-1:l; + } + + if ((unsigned int)bs.avail() >= 8*(vl+al)+32) + { + bs.seek(8*(vl+al)); + unsigned int a32=bs.getbits(32); + bs.seek(-32); + unsigned int a16=bs.getbits(16); + bs.seek(-16); + bs.seek(-8*(vl+al)); + if (a16 != NSV_NONSYNC_WORD && a32 != NSV_SYNC_DWORD) + { + bs.seek(-NSV_NONSYNC_HEADERLEN_BITS); + } + else gotframe=NSV_NONSYNC_HEADERLEN_BITS; + } + else gotframe=NSV_NONSYNC_HEADERLEN_BITS; + } + } + else bs.seek(-16); + } // inf.valid && inf.synched + + // gotframe is set if we successfully got a nonsync frame, otherwise + // let's see if we can't interpret this as a sync frame + + if (!gotframe) + { + if (bs.avail() < NSV_SYNC_HEADERLEN_BITS) + return m_eof?-1:(NSV_SYNC_HEADERLEN_BITS-bs.avail())/8; + unsigned int d=bs.getbits(32); + if (d != NSV_SYNC_DWORD) + { + bs.seek(8-32); // seek back 3 bytes + synched=0; + continue; + } + unsigned int vfmt=bs.getbits(32); + unsigned int afmt=bs.getbits(32); + unsigned int w=bs.getbits(16); + unsigned int h=bs.getbits(16); + unsigned char frt=bs.getbits(8); + unsigned int so=bs.getbits(16); + + num_aux=bs.getbits(4); + vl=bs.getbits(20); + al=bs.getbits(16); + + if (al >= NSV_MAX_AUDIO_LEN || + vl >= (NSV_MAX_VIDEO_LEN+num_aux*(NSV_MAX_AUX_LEN+6)) || + !frt || !is_type_valid(vfmt) || !is_type_valid(afmt) || + (valid && + (width != w || height != h || + vidfmt != vfmt || audfmt != afmt || framerate_idx != frt))) + { // frame is definately not valid + bs.seek(8-NSV_SYNC_HEADERLEN_BITS); // seek back what we just read + synched=0; + continue; + } + + if ((unsigned int)bs.avail() < (al+vl)*8+((m_eof||(valid&&synched))?0:32)) + { + int l=(al+vl)*8+NSV_SYNC_HEADERLEN_BITS-bs.avail(); + bs.seek(-NSV_SYNC_HEADERLEN_BITS); + return m_eof?-1:(l/8); + } + + if (valid && synched) + { + gotframe=NSV_SYNC_HEADERLEN_BITS; + } + else // we need to do more robust sync + { + int sk=(al+vl)*8; + bs.seek(sk); + unsigned int a16=bs.getbits(16); + bs.seek(-16); + unsigned int a32=bs.getbits(32); + bs.seek(-32); + if (a16 == NSV_NONSYNC_WORD) + { + sk+=16+4+20+16; + bs.seek(16+4); //skip hdr + aux bits + unsigned int _vl=bs.getbits(20); + unsigned int _al=bs.getbits(16); + if ((unsigned int)bs.avail() < (_vl+_al)*8 + 32) + { + int l=(_al+_vl+32)-bs.avail()/8; + bs.seek(-NSV_SYNC_HEADERLEN_BITS-sk); + return m_eof?-1:l; + } + bs.seek((_vl+_al)*8); + sk+=(_vl+_al)*8; + unsigned int a16=bs.getbits(16); + bs.seek(-16); + unsigned int a32=bs.getbits(32); + bs.seek(-32); + bs.seek(-sk); + if (a16 == NSV_NONSYNC_WORD || a32 == NSV_SYNC_DWORD) + gotframe=NSV_SYNC_HEADERLEN_BITS; + } + else if (a32 == NSV_SYNC_DWORD) + { + + sk+=32+32+32+16+16+8; + + bs.seek(32); + unsigned int _vfmt=bs.getbits(32); + unsigned int _afmt=bs.getbits(32); + unsigned int _w=bs.getbits(16); + unsigned int _h=bs.getbits(16); + unsigned char _frt=bs.getbits(8); + bs.seek(-sk); + + if (_vfmt==vfmt && _afmt==afmt && _w==w && _h==h && _frt==frt) // matches + { + gotframe=NSV_SYNC_HEADERLEN_BITS; + } + } + } + if (!gotframe) + { + synched=0; + bs.seek(8-NSV_SYNC_HEADERLEN_BITS); + } + else + { + if (so & 0x8000) so|=0xFFFF0000; + syncoffset_cur=so; + if (!valid || (unsigned int)syncoffset == NSV_INVALID_SYNC_OFFSET) syncoffset=so; + if (!valid) framerate=frate2double(frt); + framerate_idx=frt; + width=w; + height=h; + audfmt=afmt; + vidfmt=vfmt; + valid=1; + synched=1; + } + } + + if (gotframe) + { + is_sync_frame = (gotframe == NSV_SYNC_HEADERLEN_BITS); + // read aux channels + int rd=gotframe; + unsigned int x; + for (x = 0; x < num_aux; x ++) + { + unsigned int l=bs.getbits(16); + unsigned int fmt=bs.getbits(32); + vl -= 4+2; + rd += 16+32; + + if (l > NSV_MAX_AUX_LEN) break; + + if (m_auxbs) + { + m_auxbs->addint(l); + m_auxbs->addint(fmt); + m_auxbs->add(bs.getcurbyteptr(),l); + } + bs.seek(l*8); // toss aux + + vl-=l; + rd+=l*8; + + if (vl<0) break; // invalid frame (aux channels add up to more than video) + } + if (x < num_aux) // oh shit, invalid frame + { + synched=0; + bs.seek(8-rd); + gotframe=0; + continue; + } + + if (m_videobs) + { + m_videobs->addint(vl); + m_videobs->add(bs.getcurbyteptr(),vl); + } + bs.seek(vl*8); + + if (m_audiobs) + { + m_audiobs->addint(al); + m_audiobs->add(bs.getcurbyteptr(),al); + } + bs.seek(al*8); + + return 0; + } + } // while + return m_eof?-1:(NSV_NONSYNC_HEADERLEN_BITS-bs.avail())/8; +} + + + + + + + + + +/* NSV file header +4: NSV_HDR_DWORD +4: length of header in bytes + -- may not be 0 or 0xFFFFFFFF. :) +4: length of file, in bytes (including header - if this is 0 we are invalid) + -- can be 0xFFFFFFFF which means unknown length +4: length of file, in milliseconds (max file length, 24 days or so) + -- can be 0xFFFFFFFF which means unknown length +4: metadata length +4: number of TOC entries allocated +4: number of TOC entries used +mdlen: metadata +TOC_alloc*4:offset in file at time t. +*/ + +void nsv_writeheader(nsv_OutBS &bs, nsv_fileHeader *hdr, unsigned int padto) +{ + if (hdr->toc_alloc < hdr->toc_size) + hdr->toc_alloc=hdr->toc_size; + + if (hdr->toc_ex && hdr->toc_alloc <= hdr->toc_size*2) + hdr->toc_alloc=hdr->toc_size*2+1; + + hdr->header_size = 4+4+4+4+4+hdr->metadata_len+4+4+4*hdr->toc_alloc; + + bs.putbits(32,NSV_HDR_DWORD); + bs.putbits(32,hdr->header_size>padto?hdr->header_size:padto); + if (hdr->file_lenbytes == 0xFFFFFFFF) bs.putbits(32,hdr->file_lenbytes); + else bs.putbits(32,hdr->file_lenbytes+(hdr->header_size>padto?hdr->header_size:padto)); + bs.putbits(32,hdr->file_lenms); + bs.putbits(32,hdr->metadata_len); + bs.putbits(32,hdr->toc_alloc); + bs.putbits(32,hdr->toc_size); + bs.putdata(hdr->metadata_len*8,hdr->metadata); + + unsigned int numtoc=hdr->toc_alloc; + unsigned int numtocused=hdr->toc_size; + unsigned int *toc=hdr->toc; + unsigned int *toc_ex=hdr->toc_ex; + unsigned int numtocused2=(toc_ex && hdr->toc_alloc > hdr->toc_size*2) ? (hdr->toc_size + 1): 0; + + while (numtoc--) + { + if (!numtocused) + { + if (numtocused2) + { + if (--numtocused2 == hdr->toc_size) // signal extended TOC :) + bs.putbits(32,NSV_MAKETYPE('T','O','C','2')); + else + bs.putbits(32,*toc_ex++); + } + else // extra (unused by this implementation but could be used someday so we fill it with 0xFF) space + bs.putbits(32,~0); + } + else if (toc) + { + bs.putbits(32,*toc++); + numtocused--; + } + else bs.putbits(32,0); + } + + unsigned int x; + for (x = hdr->header_size; x < padto; x ++) bs.putbits(8,0); +} + + +int nsv_readheader(nsv_InBS &bs, nsv_fileHeader *hdr) +{ + int s=0; + hdr->metadata=(void*)NULL; + hdr->toc=(unsigned int *)NULL; + hdr->toc_ex=(unsigned int *)NULL; + hdr->header_size=0; + hdr->file_lenbytes=~0; + hdr->file_lenms=~0; + hdr->toc_alloc=0; + hdr->toc_size=0; + hdr->metadata_len=0; + + if (bs.avail()<64) { + return 8-bs.avail()/8; + } + s+=32; + if (bs.getbits(32) != NSV_HDR_DWORD) + { + bs.seek(-s); + return -1; + } + s+=32; + unsigned int headersize=bs.getbits(32); + + if ((unsigned int)bs.avail() < (headersize-4)*8) + { + int l=headersize-4-bs.avail()/8; + bs.seek(-s); + return l; + } + + s+=32; + unsigned int lenbytes=bs.getbits(32); + s+=32; + unsigned int lenms=bs.getbits(32); + s+=32; + unsigned int metadatalen=bs.getbits(32); + s+=32; + unsigned int tocalloc=bs.getbits(32); + s+=32; + unsigned int tocsize=bs.getbits(32); + + if (tocalloc < tocsize || lenbytes < headersize || tocalloc + metadatalen + s/8 > headersize) + { + bs.seek(-s); + return -1; + } + + void *metadata=NULL; + + if (metadatalen) + { + metadata=malloc(metadatalen+1); + if (!metadata) + { + bs.seek(-s); + return -1; + } + s+=metadatalen*8; + bs.getdata(metadatalen*8,metadata); + ((char*)metadata)[metadatalen]=0; + } + + unsigned int *toc=NULL; + unsigned int *toc_ex=NULL; + + if (tocalloc) + { + toc=(unsigned int *)malloc(tocsize * 4 * 2); + if (!toc) + { + free(metadata); + bs.seek(-s); + return -1; + } + unsigned int x; + int bitsread=0; + for (x = 0; x < tocsize; x ++) { toc[x] = bs.getbits(32); bitsread += 32; } + + if (tocalloc > tocsize*2) + { + bitsread += 32; + if (bs.getbits(32) == NSV_MAKETYPE('T','O','C','2')) + { + toc_ex=toc + tocsize; + for (x = 0; x < tocsize; x ++) { toc_ex[x] = bs.getbits(32); bitsread += 32; } + } + } + bs.seek((tocalloc-tocsize)*32 - bitsread); + s+=tocalloc*32; + } + + hdr->header_size=headersize; + if (lenbytes == 0xFFFFFFFF) hdr->file_lenbytes=lenbytes; + else hdr->file_lenbytes=lenbytes-headersize; + hdr->file_lenms=lenms; + hdr->metadata=metadata; + hdr->metadata_len=metadatalen; + hdr->toc=toc; + hdr->toc_ex=toc_ex; + hdr->toc_alloc=tocalloc; + hdr->toc_size=tocsize; + + return 0; +} + +char *nsv_getmetadata(void *metadata, char *name) +{ + if (!metadata) return NULL; + char *p=(char*)metadata; + int ln=strlen(name); + for (;;) + { + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; + if (!*p) break; + if (!strnicmp(p,name,ln) && p[ln]=='=' && p[ln+1] && p[ln+2]) + { + int cnt=0; + char *np=p+ln+1; + char c=*np++; + while (np[cnt] && np[cnt] != c) cnt++; + + char *s=(char*)malloc(cnt+1); + if (!s) return NULL; + memcpy(s,np,cnt); + s[cnt]=0; + return s; + } + + // advance to next item + while (*p && *p != '=') p++; + if (!*p++) break; + if (!*p) break; + char c=*p++; + while (*p && *p != c) p++; + if (*p) p++; + } + return NULL; +} diff --git a/WDL/nsv/nsvlib.h b/WDL/nsv/nsvlib.h new file mode 100644 index 00000000..f8dd5b0c --- /dev/null +++ b/WDL/nsv/nsvlib.h @@ -0,0 +1,390 @@ +/* + LICENSE + ------- +Copyright 2005 Nullsoft, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Nullsoft nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/* +** nsvlib.h - NSV file/bitstream reading/writing interface +** +*/ + +#ifndef _NSVLIB_H_ +#define _NSVLIB_H_ + +/********************************************************************* +** bitstream classes +*/ + +#include "nsvbs.h" + + +/********************************************************************* +** NSV packeting limits +*/ +#define NSV_MAX_AUDIO_LEN 0x8000 // 32kb +#define NSV_MAX_VIDEO_LEN 0x80000 // 512kb +#define NSV_MAX_AUX_LEN 0x8000 // 32kb for each aux stream +#define NSV_MAX_AUXSTREAMS 15 // 15 aux streams maximum + + +/********************************************************************* +** Constants for setting certain metadata items using addHdrMetaData() +*/ +#define METADATANAME_AUTHOR "Author" +#define METADATANAME_TITLE "Title" +#define METADATANAME_COPYRIGHT "Copyright" +#define METADATANAME_COMMENT "Comment" +#define METADATANAME_PROFILE "Profile" +#define METADATANAME_FILEID "File ID" + +/********************************************************************* +** NSV type utility functions/macros +*/ + +/* +** Use NSV_MAKETYPE() to quickly make NSV audio/video/aux types. +** ex: NSV_MAKETYPE('R','G','B','A') +*/ +#define NSV_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24)) + +/* +** These functions convert types to and from strings. +*/ + +/* nsv_type_to_string() converts an NSV type to a string. + * out must be at least 5 bytes long. If 't' is not a valid type, + * then out will be set to an empty string + * ex: + * char out[5]; + * nsv_type_to_string(NSV_MAKETYPE('R','G','B','A'),out); + * strcmp(out,"RGBA") == 0 + */ +void nsv_type_to_string(unsigned int t, char *out); + +/* nsv_string_to_type() converts a string to an NSV type. + * Returns 0 if the type is not valid. + * ex: nsv_string_to_type("RGBA") == NSV_MAKETYPE('R','G','B','A') + */ +unsigned int nsv_string_to_type(char *in); + + +/********************************************************************* +** NSV bitstream packeting/unpacketing classes +*/ + + +/* nsv_Packeter is used to packet audio/video/auxiliary data into + * a bitstream. + * + * ex: + * nsv_Packeter p; + * nsv_OutBS bs; + * p.setVidFmt(NSV_MAKETYPE('R','G','B','A'),320,240,30.0); + * p.setAudFmt(NSV_MAKETYPE('P','C','M',' ')); + * for (;;) { + * doEncodeAudioAndVideo(); + * p.setSyncFrame(is_keyframe); + * p.setSyncOffset(av_sync_offset); + * p.setAudio(audio_data,audio_len); + * p.setVideo(video_data,video_len); + * p.clearAuxChannels(); // you can add aux channels if you want + * if (p.packet(bs)) error(); + * int outbuflen; + * void *outbuf=bs.get(&outbuflen); + * fwrite(outbuf,outbuflen,1,fp); // write output + * bs.clear(); // clear bitstream + * } + * + */ + +class nsv_Packeter { + public: + nsv_Packeter(); + ~nsv_Packeter(); + + // init (per file) calls + void setVidFmt(unsigned int vfmt, unsigned int w, unsigned int h, double frt); + void setAudFmt(unsigned int afmt) { audfmt=afmt; } + + // per frame calls + void setSyncFrame(int is_syncframe) { is_sync_frame=is_syncframe; } + void setSyncOffset(int syncoffs) { syncoffset_cur=syncoffs; } + void setAudio(void *a, int a_len) { audio=a; audio_len=a_len; } + void setVideo(void *v, int v_len) { video=v; video_len=v_len; } + int addAuxChannel(unsigned int fmt, void *data, int data_len) // 0 on success + { + if (aux_used >= NSV_MAX_AUXSTREAMS) return -1; + aux[aux_used]=data; + aux_len[aux_used]=data_len; + aux_types[aux_used]=fmt; + aux_used++; + return 0; + } + void clearAuxChannels() { aux_used=0; } + + int packet(nsv_OutBS &bs); // returns 0 on success + + // some utility getting functions + unsigned int getAudFmt() { return audfmt; } + unsigned int getVidFmt() { return vidfmt; } + unsigned int getWidth() { return width; } + unsigned int getHeight() { return height; } + double getFrameRate() { return framerate; } + + private: + unsigned char framerate_idx; + unsigned int vidfmt; + unsigned int audfmt; + unsigned int width; + unsigned int height; + double framerate; + int syncoffset_cur; + + int aux_used; + void *aux[NSV_MAX_AUXSTREAMS]; + int aux_len[NSV_MAX_AUXSTREAMS]; + unsigned int aux_types[NSV_MAX_AUXSTREAMS]; + int is_sync_frame; + void *audio; + int audio_len; + void *video; + int video_len; +}; + + +/* nsv_Unpacketer is used to unpacket a bitstream into audio/video/auxiliary data + * to decode, use an nsv_InBS object with data, and call unpacket(). + * ex: + * nsv_Unpacketer up; + * nsv_InBS in; + * nsv_InBS videoout, audioout; + * up.setVideoOut(&videoout); + * up.setAudioOut(&audioout); + * for (;;) { + * int ret=up.unpacket(in); + * if (ret < 0) break; // eof + * if (ret > 0) add_data_to_bitstream(&in,ret); + * if (!ret) { // got frame + * int vl=videoout.getbits(32); + * int al=videoout.getbits(32); + * char *vd=(char*)videoout.getcurbyteptr(); + * char *ad=(char*)audioout.getcurbyteptr(); + * doDecode(vd,vl,ad,al); + * videoout.seek(vl*8); + * audioout.seek(al*8); + * videoout.compact(); // free memory up + * audioout.compact(); // free memory up + * in.compact(); // free memory up + * } + * } + */ + +class nsv_Unpacketer { + public: + nsv_Unpacketer() { reset(); } + ~nsv_Unpacketer() { } + + void reset(int full=1); // if full, full reset is done. + // if not, then it is a partial reset (ie for seeking) + + // when EOF is set, the unpacketer will fail instead of requesting more data at the + // end; it will also not require that the next frame be available for sync + // (normally it looks ahead to verify data) + void setEof(int eof=1) { m_eof=eof; } + int getEof() { return m_eof; } + + // use these to set where the unpacketer writes the output of each stream + // set to NULL to ignore output of that stream + + void setAudioOut(nsv_InBS *output=NULL) { m_audiobs=output; } + // the format of the audio data written to the output is: + // 32 bits: length of frame + // ? bytes: audio data + // (to read): + // int l=output->getbits(32); + // decode_audio(output->getcurbyteptr(),l); + // output->seek(l*8); + + + void setVideoOut(nsv_InBS *output=NULL) { m_videobs=output; } + // the format of the video data written to the output is: + // 32 bits: length of frame + // ? bytes: video data + // (to read): + // int l=output->getbits(32); + // decode_video(output->getcurbyteptr(),l); + // output->seek(l*8); + + void setAuxOut(nsv_InBS *output=NULL) { m_auxbs=output; } + // the format of the aux data written to the output is: + // 32 bits: length of frame + // 32 bits: type of aux data + // ? bytes: aux data + // (to read): + // int l=output->getbits(32); + // int type=output->getbits(32); + // decode_aux(output->getcurbyteptr(),l); + // output->seek(l*8); + // aux is different than audio/video in that it includes a 32 bit + // type value that is not included in the length. + + + // returns 0 on success, >0 on needs (at least X bytes) more data, + // -1 on error (eof and no header found) + int unpacket(nsv_InBS &bs); + + + // do we have enough sync to determine formats/widths/heights/framerates + int isValid() { return valid; } + + // are we fully synched? + int isSynched() { return synched; } + + // get sync offset from when we first synched up + signed int getSyncOffset() { return (signed int) syncoffset; } + + // get sync offset from current frame (not usually used) + signed int getCurSyncOffset() { return (signed int) syncoffset_cur; } + + // get video, audio, width, height, framerate formats. + unsigned int getVidFmt() { return vidfmt; } + unsigned int getAudFmt() { return audfmt; } + unsigned int getWidth() { return width; } + unsigned int getHeight() { return height; } + double getFrameRate() { return framerate; } + unsigned char getFrameRateIdx() { return framerate_idx; } + + // is current frame a sync frame? + int isSynchFrame() { return is_sync_frame; } + + private: + nsv_InBS *m_audiobs, *m_videobs, *m_auxbs; + int valid; // contents of stream info are valid for syncing + int synched; // turns off anal packet checking + unsigned int vidfmt; + unsigned int audfmt; + unsigned int width; + unsigned int height; + double framerate; + int is_sync_frame; + unsigned char framerate_idx; + int syncoffset; + int syncoffset_cur; + + int m_eof; +}; + + +/********************************************************************* +** NSV file header reading/writing functions +*/ + + +typedef struct { + // header_size is the size of NSV header. nsv_writeheader() and nsv_readheader() + // will set this automatically + unsigned int header_size; + + // file_lenbytes is the size of the NSV bitstream (not including the header size) + // this can be 0xFFFFFFFF to signify unknown length + unsigned int file_lenbytes; + + // file_lenms is the length of the NSV bitstream in milliseconds. + // this can be 0xFFFFFFFF to signify unknown length + unsigned int file_lenms; + + // metadata_len describes the length of the metadata. + unsigned int metadata_len; + + // toc_alloc describes the allocated length of the TOC (in entries). + // set this to zero to use toc_size (recommended). + unsigned int toc_alloc; + + // toc_size describes the used size of the TOC (in entries) + // set this to zero to disable the TOC. When using toc_ex, + // this must be < toc_alloc/2 (if using nsv_writeheader, and + // toc_size is too big, toc_alloc will be grown automatically. + unsigned int toc_size; + + // buffer which contains the TOC. this will be automatically + // allocated when using nsv_readheader(), but you should allocate + // this yourself when using nsv_writeheader() + unsigned int *toc; + + // if used, contains time pairs (in frames) for the offset. this will be + // automatically allocated when using nsv_readheader(), but you should allocate + // this yourself when using nsv_writeheader() + // DO NOT FREE THIS VALUE IF IT WAS ALLOCATED FROM NSV_READHEADER. :) + // (it is just an extension of toc, which should be freed with free()) + unsigned int *toc_ex; + + // buffer which contains metadata. allocated when using nsv_readheader(), + // but you should allocate this yourself when using nsv_writeheader() + // note that nsv_readheader() will NULL terminate this buffer. + void *metadata; + +} nsv_fileHeader; + +// nsv_writeheader() writes the NSV file header to the bitstream bs. +// the NSV file header will be at LEAST padto bytes long (usually +// you will leave padto to 0) +void nsv_writeheader(nsv_OutBS &bs, nsv_fileHeader *hdr, unsigned int padto); + +// nsv_readheader() reads an NSV file header from a bitstream bs. +// if the return value is less than zero, then there is no NSV +// file header in bs. if the return value is zero, the NSV file +// header was succesfully read. if the return value is positive, +// then at least that many more bytes are needed to decode the +// header. +// ex: +// nsv_InBS bs; +// nsv_fileHeader hdr; +// for (;;) { +// int ret=nsv_readheader(bs,&hdr); +// if (ret<=0) break; +// addBytesToBs(bs,ret); +// } +// if (hdr.header_size) { we_got_valid_header(&hdr); } +// + +int nsv_readheader(nsv_InBS &bs, nsv_fileHeader *hdr); + + +// nsv_getmetadata() retrieves a metadata item from the metadata +// block. if that item is not found, NULL is returned. +// Note that the value returned by nsv_getmetadata() has been +// malloc()'d, and you must free() it when you are done. +// ex: +// char *v=nsv_getmetadata(hdr.metadata,"TITLE"); +// if (v) printf("title=%s\n",v); +// free(v); +// + +char *nsv_getmetadata(void *metadata, char *name); + + +#endif//_NSVLIB_H_ diff --git a/WDL/pcmfmtcvt.h b/WDL/pcmfmtcvt.h new file mode 100644 index 00000000..d498865f --- /dev/null +++ b/WDL/pcmfmtcvt.h @@ -0,0 +1,528 @@ +/* + WDL - pcmfmtcvt.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides some simple functions for dealing with PCM audio. + Specifically: + + convert between 16/24/32 bit integer samples and flaots (only really tested on little-endian (i.e. x86) systems) + + mix (and optionally resample, using low quality linear interpolation) a block of floats to another. + +*/ + +#ifndef _PCMFMTCVT_H_ +#define _PCMFMTCVT_H_ + + +#include "wdltypes.h" + +#ifndef PCMFMTCVT_DBL_TYPE +#define PCMFMTCVT_DBL_TYPE double +#endif + +static inline int float2int(PCMFMTCVT_DBL_TYPE d) +{ + return (int) d; +// int tmp; + // __asm__ __volatile__ ("fistpl %0" : "=m" (tmp) : "t" (d) : "st") ; + // return tmp; +} + + +#define float_TO_INT16(out,in) \ + if ((in)<0.0) { if ((in) <= -1.0) (out) = -32768; else (out) = (short) (float2int(((in) * 32768.0)-0.5)); } \ + else { if ((in) >= (32766.5f/32768.0f)) (out) = 32767; else (out) = (short) float2int((in) * 32768.0 + 0.5); } + +#define INT16_TO_float(out,in) { (out) = (float)(((double)in)/32768.0); } + +#define double_TO_INT16(out,in) \ + if ((in)<0.0) { if ((in) <= -1.0) (out) = -32768; else (out) = (short) (float2int(((in) * 32768.0)-0.5)); } \ + else { if ((in) >= (32766.5/32768.0)) (out) = 32767; else (out) = (short) float2int((in) * 32768.0 + 0.5); } + +#define INT16_TO_double(out,in) { (out) = (((PCMFMTCVT_DBL_TYPE)in)/32768.0); } + + +static inline void i32_to_float(int i32, float *p) +{ + *p = (float) ((((double) i32)) * (1.0 / (2147483648.0))); +} + +static inline void float_to_i32(float *vv, int *i32) +{ + float v = *vv; + if (v < 0.0) + { + if (v < -1.0) *i32 = 0x80000000; + else *i32=float2int(v*2147483648.0-0.5); + } + else + { + if (v >= (2147483646.5f/2147483648.0f)) *i32 = 0x7FFFFFFF; + else *i32=float2int(v*2147483648.0+0.5); + } +} + + +static inline void i32_to_double(int i32, PCMFMTCVT_DBL_TYPE *p) +{ + *p = ((((PCMFMTCVT_DBL_TYPE) i32)) * (1.0 / (2147483648.0))); +} + +static inline void double_to_i32(PCMFMTCVT_DBL_TYPE *vv, int *i32) +{ + PCMFMTCVT_DBL_TYPE v = *vv; + if (v < 0.0) + { + if (v < -1.0) *i32 = 0x80000000; + else *i32=float2int(v*2147483648.0-0.5); + } + else + { + if (v >= (2147483646.5/2147483648.0)) *i32 = 0x7FFFFFFF; + else *i32=float2int(v*2147483648.0+0.5); + } +} + + + +static inline void i24_to_float(unsigned char *i24, float *p) +{ + int val=(i24[0]) | (i24[1]<<8) | (i24[2]<<16); + if (val&0x800000) + { + val|=0xFF000000; + *p = (float) ((((double) val)) * (1.0 / (8388608.0))); + } + else + { + val&=0xFFFFFF; + *p = (float) ((((double) val)) * (1.0 / (8388608.0))); + } + +} + +static inline void float_to_i24(float *vv, unsigned char *i24) +{ + float v = *vv; + if (v < 0.0) + { + if (v < -1.0) + { + i24[0]=i24[1]=0x00; + i24[2]=0x80; + } + else + { + int i=float2int(v*8388608.0-0.5); + i24[0]=(i)&0xff; + i24[1]=(i>>8)&0xff; + i24[2]=(i>>16)&0xff; + } + } + else + { + if (v >= (8388606.5f/8388608.0f)) + { + i24[0]=i24[1]=0xff; + i24[2]=0x7f; + } + else + { + + int i=float2int(v*8388608.0+0.5); + i24[0]=(i)&0xff; + i24[1]=(i>>8)&0xff; + i24[2]=(i>>16)&0xff; + } + } +} + + +static inline void i24_to_double(unsigned char *i24, PCMFMTCVT_DBL_TYPE *p) +{ + int val=(i24[0]) | (i24[1]<<8) | (i24[2]<<16); + if (val&0x800000) + { + val|=0xFF000000; + *p = ((((PCMFMTCVT_DBL_TYPE) val)) * (1.0 / (8388608.0))); + } + else + { + val&=0xFFFFFF; + *p = ((((PCMFMTCVT_DBL_TYPE) val)) * (1.0 / (8388608.0))); + } + +} + +static inline void double_to_i24(PCMFMTCVT_DBL_TYPE *vv, unsigned char *i24) +{ + PCMFMTCVT_DBL_TYPE v = *vv; + if (v < 0.0) + { + if (v < -1.0) + { + i24[0]=i24[1]=0x00; + i24[2]=0x80; + } + else + { + int i=float2int(v*8388608.0-0.5); + i24[0]=(i)&0xff; + i24[1]=(i>>8)&0xff; + i24[2]=(i>>16)&0xff; + } + } + else + { + if (v >= (8388606.5/8388608.0)) + { + i24[0]=i24[1]=0xff; + i24[2]=0x7f; + } + else + { + + int i=float2int(v*8388608.0+0.5); + i24[0]=(i)&0xff; + i24[1]=(i>>8)&0xff; + i24[2]=(i>>16)&0xff; + } + } +} + +static void pcmToFloats(void *src, int items, int bps, int src_spacing, float *dest, int dest_spacing) +{ + if (bps == 32) + { + int *i1=(int *)src; + while (items--) + { + i32_to_float(*i1,dest); + i1+=src_spacing; + dest+=dest_spacing; + } + } + else if (bps == 24) + { + unsigned char *i1=(unsigned char *)src; + int adv=3*src_spacing; + while (items--) + { + i24_to_float(i1,dest); + dest+=dest_spacing; + i1+=adv; + } + } + else if (bps == 16) + { + short *i1=(short *)src; + while (items--) + { + INT16_TO_float(*dest,*i1); + i1+=src_spacing; + dest+=dest_spacing; + } + } +} + +static void floatsToPcm(float *src, int src_spacing, int items, void *dest, int bps, int dest_spacing) +{ + if (bps==32) + { + int *o1=(int*)dest; + while (items--) + { + float_to_i32(src,o1); + src+=src_spacing; + o1+=dest_spacing; + } + } + else if (bps == 24) + { + unsigned char *o1=(unsigned char*)dest; + int adv=dest_spacing*3; + while (items--) + { + float_to_i24(src,o1); + src+=src_spacing; + o1+=adv; + } + } + else if (bps==16) + { + short *o1=(short*)dest; + while (items--) + { + float_TO_INT16(*o1,*src); + src+=src_spacing; + o1+=dest_spacing; + } + } +} + + +static void pcmToDoubles(void *src, int items, int bps, int src_spacing, PCMFMTCVT_DBL_TYPE *dest, int dest_spacing, int byteadvancefor24=0) +{ + if (bps == 32) + { + int *i1=(int *)src; + while (items--) + { + i32_to_double(*i1,dest); + i1+=src_spacing; + dest+=dest_spacing; + } + } + else if (bps == 24) + { + unsigned char *i1=(unsigned char *)src; + int adv=3*src_spacing+byteadvancefor24; + while (items--) + { + i24_to_double(i1,dest); + dest+=dest_spacing; + i1+=adv; + } + } + else if (bps == 16) + { + short *i1=(short *)src; + while (items--) + { + INT16_TO_double(*dest,*i1); + i1+=src_spacing; + dest+=dest_spacing; + } + } +} + +static void doublesToPcm(PCMFMTCVT_DBL_TYPE *src, int src_spacing, int items, void *dest, int bps, int dest_spacing, int byteadvancefor24=0) +{ + if (bps==32) + { + int *o1=(int*)dest; + while (items--) + { + double_to_i32(src,o1); + src+=src_spacing; + o1+=dest_spacing; + } + } + else if (bps == 24) + { + unsigned char *o1=(unsigned char*)dest; + int adv=dest_spacing*3+byteadvancefor24; + while (items--) + { + double_to_i24(src,o1); + src+=src_spacing; + o1+=adv; + } + } + else if (bps==16) + { + short *o1=(short*)dest; + while (items--) + { + double_TO_INT16(*o1,*src); + src+=src_spacing; + o1+=dest_spacing; + } + } +} + +static int resampleLengthNeeded(int src_srate, int dest_srate, int dest_len, double *state) +{ + // safety + if (!src_srate) src_srate=48000; + if (!dest_srate) dest_srate=48000; + if (src_srate == dest_srate) return dest_len; + return (int) (((double)src_srate*(double)dest_len/(double)dest_srate)+*state); + +} + +static void mixFloats(float *src, int src_srate, int src_nch, // lengths are sample pairs + float *dest, int dest_srate, int dest_nch, + int dest_len, float vol, float pan, double *state) +{ + // fucko: better resampling, this is shite + int x; + if (pan < -1.0f) pan=-1.0f; + else if (pan > 1.0f) pan=1.0f; + if (vol > 4.0f) vol=4.0f; + if (vol < 0.0f) vol=0.0f; + + if (!src_srate) src_srate=48000; + if (!dest_srate) dest_srate=48000; + + double vol1=vol,vol2=vol; + if (dest_nch == 2) + { + if (pan < 0.0f) vol2 *= 1.0f+pan; + else if (pan > 0.0f) vol1 *= 1.0f-pan; + } + + double rspos=*state; + double drspos = (double)src_srate/(double)dest_srate; + + for (x = 0; x < dest_len; x ++) + { + + double ls; + double rs; + if (src_srate != dest_srate) + { + int ipos = (int)rspos; + double fracpos=rspos-ipos; + if (src_nch == 2) + { + ipos+=ipos; + ls=src[ipos]*(1.0-fracpos) + src[ipos+2]*fracpos; + rs=src[ipos+1]*(1.0-fracpos) + src[ipos+3]*fracpos; + } + else + { + rs=ls=src[ipos]*(1.0-fracpos) + src[ipos+1]*fracpos; + } + } + else + { + if (src_nch == 2) + { + int t=x+x; + ls=src[t]; + rs=src[t+1]; + } + else + { + rs=ls=src[x]; + } + } + + rspos+=drspos; + + ls *= vol1; + if (ls > 1.0) ls=1.0; + else if (ls<-1.0) ls=-1.0; + + if (dest_nch == 2) + { + rs *= vol2; + if (rs > 1.0) rs=1.0; + else if (rs<-1.0) rs=-1.0; + + dest[0]+=(float) ls; + dest[1]+=(float) rs; + dest+=2; + } + else + { + dest[0]+=(float) ls; + dest++; + } + } + *state = rspos - (int)rspos; +} + +static void mixFloatsNIOutput(float *src, int src_srate, int src_nch, // lengths are sample pairs. input is interleaved samples, output not + float **dest, int dest_srate, int dest_nch, + int dest_len, float vol, float pan, double *state) +{ + // fucko: better resampling, this is shite + int x; + if (pan < -1.0f) pan=-1.0f; + else if (pan > 1.0f) pan=1.0f; + if (vol > 4.0f) vol=4.0f; + if (vol < 0.0f) vol=0.0f; + + if (!src_srate) src_srate=48000; + if (!dest_srate) dest_srate=48000; + + double vol1=vol,vol2=vol; + float *dest1=dest[0]; + float *dest2=NULL; + if (dest_nch > 1) + { + dest2=dest[1]; + if (pan < 0.0f) vol2 *= 1.0f+pan; + else if (pan > 0.0f) vol1 *= 1.0f-pan; + } + + + double rspos=*state; + double drspos = 1.0; + if (src_srate != dest_srate) drspos=(double)src_srate/(double)dest_srate; + + for (x = 0; x < dest_len; x ++) + { + double ls,rs; + if (src_srate != dest_srate) + { + int ipos = (int)rspos; + double fracpos=rspos-ipos; + if (src_nch == 2) + { + ipos+=ipos; + ls=src[ipos]*(1.0-fracpos) + src[ipos+2]*fracpos; + rs=src[ipos+1]*(1.0-fracpos) + src[ipos+3]*fracpos; + } + else + { + rs=ls=src[ipos]*(1.0-fracpos) + src[ipos+1]*fracpos; + } + rspos+=drspos; + + } + else + { + if (src_nch == 2) + { + int t=x+x; + ls=src[t]; + rs=src[t+1]; + } + else + { + rs=ls=src[x]; + } + } + + ls *= vol1; + if (ls > 1.0) ls=1.0; + else if (ls<-1.0) ls=-1.0; + + *dest1++ +=(float) ls; + + if (dest_nch > 1) + { + rs *= vol2; + if (rs > 1.0) rs=1.0; + else if (rs<-1.0) rs=-1.0; + + *dest2++ += (float) rs; + } + } + *state = rspos - (int)rspos; +} + + +#endif //_PCMFMTCVT_H_ \ No newline at end of file diff --git a/WDL/plush2/pl_cam.cpp b/WDL/plush2/pl_cam.cpp new file mode 100644 index 00000000..45996077 --- /dev/null +++ b/WDL/plush2/pl_cam.cpp @@ -0,0 +1,748 @@ +/****************************************************************************** +Plush Version 1.2 +cam.c +Camera and Rendering +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + + +#include "../lice/lice_extended.h" + +#include "../mergesort.h" + +#define MACRO_plMatrixApply(m,x,y,z,outx,outy,outz) \ + ( outx ) = ( x )*( m )[0] + ( y )*( m )[1] + ( z )*( m )[2] + ( m )[3];\ + ( outy ) = ( x )*( m )[4] + ( y )*( m )[5] + ( z )*( m )[6] + ( m )[7];\ + ( outz ) = ( x )*( m )[8] + ( y )*( m )[9] + ( z )*( m )[10] + ( m )[11] + +#define MACRO_plDotProduct(x1,y1,z1,x2,y2,z2) \ + ((( x1 )*( x2 ))+(( y1 )*( y2 ))+(( z1 )*( z2 ))) + +#define MACRO_plNormalizeVector(x,y,z) { \ + double length; \ + length = ( x )*( x )+( y )*( y )+( z )*( z ); \ + if (length > 0.0000000001) { \ + double __l = 1.0/sqrt(length); \ + ( x ) *= __l; \ + ( y ) *= __l; \ + ( z ) *= __l; \ + } \ +} + + +static void _FindNormal(double x2, double x3,double y2, double y3, + double zv, double *res) { + res[0] = zv*(y2-y3); + res[1] = zv*(x3-x2); + res[2] = x2*y3 - y2*x3; +} + + +void pl_Cam::SetTarget(pl_Float x, pl_Float y, pl_Float z) { + double dx, dy, dz; + dx = x - X; + dy = y - Y; + dz = z - Z; + Roll = 0; + if (dz > 0.0001f) { + Pan = (pl_Float) (-atan(dx/dz)*(180.0/PL_PI)); + dz /= cos(Pan*(PL_PI/180.0)); + Pitch = (pl_Float) (atan(dy/dz)*(180.0/PL_PI)); + } else if (dz < -0.0001f) { + Pan = (pl_Float) (180.0-atan(dx/dz)*(180.0/PL_PI)); + dz /= cos((Pan-180.0f)*(PL_PI/180.0)); + Pitch = (pl_Float) (-atan(dy/dz)*(180.0/PL_PI)); + } else { + Pan = 0.0f; + Pitch = -90.0f; + } +} + +void pl_Cam::RecalcFrustum() +{ + int fbw=frameBuffer->getWidth(); + int fbh=frameBuffer->getHeight(); + int cx = CenterX + fbw/2; + int cy = CenterY + fbh/2; + + m_adj_asp = 1.0 / AspectRatio; + m_fovfactor = fbw/tan(plMin(plMax(Fov,1.0),179.0)*(PL_PI/360.0)); + memset(m_clipPlanes,0,sizeof(m_clipPlanes)); + + /* Back */ + m_clipPlanes[0][2] = -1.0; + m_clipPlanes[0][3] = -ClipBack; + + /* Left */ + m_clipPlanes[1][3] = 0.00000001; + if (cx == 0) m_clipPlanes[1][0] = 1.0; + else + { + _FindNormal(-100,-100, + 100, -100, + m_fovfactor*100.0/cx, + m_clipPlanes[1]); + if (cx < 0) + { + m_clipPlanes[1][0] = -m_clipPlanes[1][0]; + m_clipPlanes[1][1] = -m_clipPlanes[1][1]; + m_clipPlanes[1][2] = -m_clipPlanes[1][2]; + } + } + + /* Right */ + m_clipPlanes[2][3] = 0.00000001; + if (fbw == cx) m_clipPlanes[2][0] = -1.0; + else + { + _FindNormal(100,100, + -100, 100, + m_fovfactor*100.0/(fbw-cx), + m_clipPlanes[2]); + if (cx > fbw) + { + m_clipPlanes[2][0] = -m_clipPlanes[2][0]; + m_clipPlanes[2][1] = -m_clipPlanes[2][1]; + m_clipPlanes[2][2] = -m_clipPlanes[2][2]; + } + } + + /* Top */ + m_clipPlanes[3][3] = 0.00000001; + if (cy == 0) m_clipPlanes[3][1] = 1.0; + else + { + _FindNormal(100, -100, + 100, 100, + m_fovfactor*m_adj_asp*-100.0/(cy), + m_clipPlanes[3]); + if (cy < 0) + { + m_clipPlanes[3][0] = -m_clipPlanes[3][0]; + m_clipPlanes[3][1] = -m_clipPlanes[3][1]; + m_clipPlanes[3][2] = -m_clipPlanes[3][2]; + } + } + + /* Bottom */ + m_clipPlanes[4][3] = 0.00000001; + if (cy == fbh) m_clipPlanes[4][1] = -1.0; + else + { + _FindNormal(-100, 100, + -100, -100, + m_fovfactor*m_adj_asp*100.0/(cy-fbh), + m_clipPlanes[4]); + if (cy > fbh) + { + m_clipPlanes[4][0] = -m_clipPlanes[4][0]; + m_clipPlanes[4][1] = -m_clipPlanes[4][1]; + m_clipPlanes[4][2] = -m_clipPlanes[4][2]; + } + } + +} + + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ +pl_uInt pl_Cam::_ClipToPlane(pl_uInt numVerts, pl_Float *plane) +{ + pl_uInt i, nextvert, curin, nextin; + double curdot, nextdot, scale; + pl_uInt invert, outvert; + invert = 0; + outvert = 0; + curdot = m_cl[0].newVertices[0].xformedx*plane[0] + + m_cl[0].newVertices[0].xformedy*plane[1] + + m_cl[0].newVertices[0].xformedz*plane[2]; + curin = (curdot >= plane[3]); + + for (i=0 ; i < numVerts; i++) { + nextvert = (i + 1) % numVerts; + if (curin) { + memcpy(&m_cl[1].ShadeInfos[outvert][0],&m_cl[0].ShadeInfos[invert][0],3*sizeof(pl_Float)); + int a; + for(a=0;a= plane[3]); + if (curin != nextin) { + scale = (plane[3] - curdot) / (nextdot - curdot); + m_cl[1].newVertices[outvert].xformedx = (pl_Float) (m_cl[0].newVertices[invert].xformedx + + (m_cl[0].newVertices[nextvert].xformedx - m_cl[0].newVertices[invert].xformedx) + * scale); + m_cl[1].newVertices[outvert].xformedy = (pl_Float) (m_cl[0].newVertices[invert].xformedy + + (m_cl[0].newVertices[nextvert].xformedy - m_cl[0].newVertices[invert].xformedy) + * scale); + m_cl[1].newVertices[outvert].xformedz = (pl_Float) (m_cl[0].newVertices[invert].xformedz + + (m_cl[0].newVertices[nextvert].xformedz - m_cl[0].newVertices[invert].xformedz) + * scale); + + m_cl[1].ShadeInfos[outvert][0] = m_cl[0].ShadeInfos[invert][0] + (m_cl[0].ShadeInfos[nextvert][0] - m_cl[0].ShadeInfos[invert][0]) * scale; + m_cl[1].ShadeInfos[outvert][1] = m_cl[0].ShadeInfos[invert][1] + (m_cl[0].ShadeInfos[nextvert][1] - m_cl[0].ShadeInfos[invert][1]) * scale; + m_cl[1].ShadeInfos[outvert][2] = m_cl[0].ShadeInfos[invert][2] + (m_cl[0].ShadeInfos[nextvert][2] - m_cl[0].ShadeInfos[invert][2]) * scale; + + int a; + for(a=0;agetWidth())/2; + int cy = CenterY + (frameBuffer->getHeight())/2; + + { + pl_Vertex *vlist=obj->Vertices.Get(); + int a; + for (a = 0; a < 3; a ++) { + m_cl[0].newVertices[a] = vlist[face->VertexIndices[a]]; + + memcpy(&m_cl[0].ShadeInfos[a][0],&face->Shades[a][0],3*sizeof(pl_Float)); + int b; + for(b=0;bMappingU[b][a]; + m_cl[0].MappingV[b][a] = face->MappingV[b][a]; + } + } + } + + pl_uInt numVerts = 3; + { + int a = (m_clipPlanes[0][3] < 0.0 ? 0 : 1); + while (a < PL_NUM_CLIP_PLANES && numVerts > 2) + { + numVerts = _ClipToPlane(numVerts, m_clipPlanes[a]); + memcpy(&m_cl[0],&m_cl[1],sizeof(m_cl[0])); + a++; + } + } + if (numVerts > 2) { + pl_Face newface; + memcpy(&newface,face,sizeof(pl_Face)); + int k; + for (k = 2; k < (int)numVerts; k ++) { + int a; + for (a = 0; a < 3; a ++) { + int w; + if (a == 0) w = 0; + else w = a+(k-2); ; + pl_Vertex *thisv=m_cl[0].newVertices+w; + newface.Shades[a][0] = m_cl[0].ShadeInfos[w][0]; + newface.Shades[a][1] = m_cl[0].ShadeInfos[w][1]; + newface.Shades[a][2] = m_cl[0].ShadeInfos[w][2]; + int b; + for(b=0;bxformedz; + double ytmp = m_fovfactor * newface.Scrz[a]; + double xtmp = ytmp*thisv->xformedx; + ytmp *= thisv->xformedy*m_adj_asp; + newface.Scrx[a] = xtmp+cx; + newface.Scry[a] = ytmp+cy; + } + RenderTrisOut++; + + // quick approx of triangle area + RenderPixelsOut += 0.5*fabs( + (newface.Scrx[1] - newface.Scrx[0]) * + (newface.Scry[2] - newface.Scry[0]) - + (newface.Scrx[2] - newface.Scrx[0]) * + (newface.Scry[1] - newface.Scry[0]) ); + + if (frameBuffer->Extended(LICE_EXT_SUPPORTS_ID,(void*)(INT_PTR)LICE_EXT_DRAWTRIANGLE_ACCEL)) + { + LICE_Ext_DrawTriangle_acceldata ac; + ac.mat = newface.Material; + int x,y; + for(x=0;x<3;x++) for(y=0;y<3;y++) ac.VertexShades[x][y]=newface.Shades[x][y]; + for(x=0;x<3;x++) + { + ac.scrx[x]=newface.Scrx[x]; + ac.scry[x]=newface.Scry[x]; + ac.scrz[x]=newface.Scrz[x]; + } + for(x=0;x<2;x++) + { + int tidx=x?newface.Material->TexMapIdx : newface.Material->Tex2MapIdx; + if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; + for(y=0;y<3;y++) + { + ac.mapping_coords[x][y][0]=newface.MappingU[tidx][y]; + ac.mapping_coords[x][y][1]=newface.MappingV[tidx][y]; + } + } + + frameBuffer->Extended(LICE_EXT_DRAWTRIANGLE_ACCEL,&ac); + } + else PutFace(&newface); + } + } +} + +pl_sInt pl_Cam::ClipNeeded(pl_Face *face, pl_Obj *obj) { + double dr,dl,db,dt; + double f; + int fbw=(frameBuffer->getWidth()); + int fbh=(frameBuffer->getHeight()); + int cx = CenterX + fbw/2; + int cy = CenterY + fbh/2; + dr = (fbw-cx); + dl = (-cx); + db = (fbh-cy); + dt = (-cy); + f = m_fovfactor*m_adj_asp; + pl_Vertex *vlist=obj->Vertices.Get(); + pl_Vertex *v0=vlist+face->VertexIndices[0]; + pl_Vertex *v1=vlist+face->VertexIndices[1]; + pl_Vertex *v2=vlist+face->VertexIndices[2]; + + return ((ClipBack <= 0.0 || + v0->xformedz <= ClipBack || + v1->xformedz <= ClipBack || + v2->xformedz <= ClipBack) && + (v0->xformedz >= 0 || + v1->xformedz >= 0 || + v2->xformedz >= 0) && + (v0->xformedx*m_fovfactor<=dr*v0->xformedz || + v1->xformedx*m_fovfactor<=dr*v1->xformedz || + v2->xformedx*m_fovfactor<=dr*v2->xformedz) && + (v0->xformedx*m_fovfactor>=dl*v0->xformedz || + v1->xformedx*m_fovfactor>=dl*v1->xformedz || + v2->xformedx*m_fovfactor>=dl*v2->xformedz) && + (v0->xformedy*f<=db*v0->xformedz || + v1->xformedy*f<=db*v1->xformedz || + v2->xformedy*f<=db*v2->xformedz) && + (v0->xformedy*f>=dt*v0->xformedz || + v1->xformedy*f>=dt*v1->xformedz || + v2->xformedy*f>=dt*v2->xformedz)); +} + + + + + + +void pl_Cam::Begin(LICE_IBitmap *fb, bool want_zbclear, pl_ZBuffer zbclear) { + if (frameBuffer||!fb) return; + + if (WantZBuffer) + { + int zbsz=fb->getWidth()*fb->getHeight(); + pl_ZBuffer *zb=zBuffer.Resize(zbsz); + if (want_zbclear) + { + if (!zbclear) memset(zb,0,zbsz*sizeof(pl_ZBuffer)); + else + { + int i=zbsz; + while(i--) *zb++=zbclear; + } + } + } + else zBuffer.Resize(0); + pl_Float tempMatrix[16]; + _numlights = 0; + _numfaces = _numfaces_sorted = 0; + frameBuffer = fb; + plMatrixRotate(_cMatrix,2,-Pan); + plMatrixRotate(tempMatrix,1,-Pitch); + plMatrixMultiply(_cMatrix,tempMatrix); + plMatrixRotate(tempMatrix,3,-Roll); + plMatrixMultiply(_cMatrix,tempMatrix); + + RecalcFrustum(); + + RenderTrisIn=RenderTrisCulled=RenderTrisOut=0; + RenderPixelsOut=0.0; + +} + +void pl_Cam::RenderLight(pl_Light *light) { + if (!light||!frameBuffer) return; + + pl_Float *pl, xp, yp, zp; + if (light->Type == PL_LIGHT_NONE) return; + if (_lights.GetSize()<=_numlights) _lights.Resize(_numlights+1); + pl = _lights.Get()[_numlights].l; + if (light->Type == PL_LIGHT_VECTOR) { + xp = light->Xp; + yp = light->Yp; + zp = light->Zp; + MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); + } else if (light->Type & PL_LIGHT_POINT) { + xp = light->Xp-X; + yp = light->Yp-Y; + zp = light->Zp-Z; + MACRO_plMatrixApply(_cMatrix,xp,yp,zp,pl[0],pl[1],pl[2]); + } + _lights.Get()[_numlights++].light = light; +} + +void pl_Cam::RenderObject(pl_Obj *obj, pl_Float *bmatrix, pl_Float *bnmatrix) { + if (!obj||!frameBuffer) return; + + pl_Float oMatrix[16], nMatrix[16], tempMatrix[16]; + + if (obj->GenMatrix) { + plMatrixRotate(nMatrix,1,obj->Xa); + plMatrixRotate(tempMatrix,2,obj->Ya); + plMatrixMultiply(nMatrix,tempMatrix); + plMatrixRotate(tempMatrix,3,obj->Za); + plMatrixMultiply(nMatrix,tempMatrix); + memcpy(oMatrix,nMatrix,sizeof(pl_Float)*16); + } else memcpy(nMatrix,obj->RotMatrix,sizeof(pl_Float)*16); + + if (bnmatrix) plMatrixMultiply(nMatrix,bnmatrix); + + if (obj->GenMatrix) { + plMatrixTranslate(tempMatrix, obj->Xp, obj->Yp, obj->Zp); + plMatrixMultiply(oMatrix,tempMatrix); + } else memcpy(oMatrix,obj->Matrix,sizeof(pl_Float)*16); + if (bmatrix) plMatrixMultiply(oMatrix,bmatrix); + + { + int i; + for (i = 0; i < obj->Children.GetSize(); i ++) + if (obj->Children.Get(i)) RenderObject(obj->Children.Get(i),oMatrix,nMatrix); + } + if (!obj->Faces.GetSize() || !obj->Vertices.GetSize()) return; + + plMatrixTranslate(tempMatrix, -X, -Y, -Z); + plMatrixMultiply(oMatrix,tempMatrix); + plMatrixMultiply(oMatrix,_cMatrix); + plMatrixMultiply(nMatrix,_cMatrix); + + { + pl_Vertex *vertex = obj->Vertices.Get(); + int i = obj->Vertices.GetSize(); + + while (i--) + { + MACRO_plMatrixApply(oMatrix,vertex->x,vertex->y,vertex->z, + vertex->xformedx, vertex->xformedy, vertex->xformedz); + MACRO_plMatrixApply(nMatrix,vertex->nx,vertex->ny,vertex->nz, + vertex->xformednx,vertex->xformedny,vertex->xformednz); + vertex++; + } + } + + if (_faces.GetSize() < _numfaces + obj->Faces.GetSize()) _faces.Resize(_numfaces + obj->Faces.GetSize()); + + + _faceInfo *facelistout = _faces.Get() + _numfaces; + + pl_Face *face = obj->Faces.Get(); + int facecnt = obj->Faces.GetSize(); + + RenderTrisIn += facecnt; + _numfaces += facecnt; + pl_Vertex *vlist = obj->Vertices.Get(); + + while (facecnt--) + { + double nx,ny,nz; + pl_Mat *mat=face->Material; + if (mat->BackfaceCull || (mat->Lightable && !mat->Smoothing)) + { + MACRO_plMatrixApply(nMatrix,face->nx,face->ny,face->nz,nx,ny,nz); + } + pl_Vertex *v0=vlist+face->VertexIndices[0]; + pl_Vertex *v1=vlist+face->VertexIndices[1]; + pl_Vertex *v2=vlist+face->VertexIndices[2]; + + if (!mat->BackfaceCull || (MACRO_plDotProduct(nx,ny,nz, v0->xformedx, v0->xformedy, v0->xformedz) < 0.0000001)) { + if (ClipNeeded(face,obj)) { + if (!mat->Smoothing && (mat->Lightable||mat->FadeDist)) { + pl_Float val[3]; + memcpy(val,face->sLighting,3*sizeof(pl_Float)); + if (mat->Lightable) { + _lightInfo *inf = _lights.Get(); + int i=_numlights; + while (i--) + { + pl_Light *light = inf->light; + double lightsc=0.0; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + double nx2 = inf->l[0] - v0->xformedx; + double ny2 = inf->l[1] - v0->xformedy; + double nz2 = inf->l[2] - v0->xformedz; + MACRO_plNormalizeVector(nx2,ny2,nz2); + lightsc = MACRO_plDotProduct(nx,ny,nz,nx2,ny2,nz2); + } + if (light->Type & PL_LIGHT_POINT_DISTANCE) { + double nx2 = inf->l[0] - v0->xformedx; + double ny2 = inf->l[1] - v0->xformedy; + double nz2 = inf->l[2] - v0->xformedz; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + nx2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ + light->HalfDistSquared)); + lightsc *= plMax(0,plMin(1.0,nx2)); + } else { + lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/ + light->HalfDistSquared)); + lightsc = plMax(0,plMin(1.0,lightsc)); + } + } + if (light->Type == PL_LIGHT_VECTOR) + lightsc = MACRO_plDotProduct(nx,ny,nz,inf->l[0],inf->l[1],inf->l[2]); + + if (lightsc>0.0) + { + val[0] += light->Intensity[0]*lightsc; + val[1] += light->Intensity[1]*lightsc; + val[2] += light->Intensity[2]*lightsc; + } + else if (mat->BackfaceIllumination) + { + val[0] -= light->Intensity[0]*lightsc*mat->BackfaceIllumination; + val[1] -= light->Intensity[1]*lightsc*mat->BackfaceIllumination; + val[2] -= light->Intensity[2]*lightsc*mat->BackfaceIllumination; + } + inf++; + } /* End of light loop */ + } /* End of flat shading if */ + + if (mat->FadeDist) + { + double lightsc = 1.0 - (v0->xformedz+v1->xformedz+v2->xformedz) / (mat->FadeDist*3.0); + if (lightsc<0.0) lightsc=0.0; + else if (lightsc>1.0)lightsc=1.0; + if (mat->Lightable) + { + val[0] *= lightsc; + val[1] *= lightsc; + val[2] *= lightsc; + } + else + { + val[0]+=lightsc; + val[1]+=lightsc; + val[2]+=lightsc; + } + } + face->Shades[0][0]=mat->Ambient[0] + mat->Diffuse[0]*val[0]; + face->Shades[0][1]=mat->Ambient[1] + mat->Diffuse[1]*val[1]; + face->Shades[0][2]=mat->Ambient[2] + mat->Diffuse[2]*val[2]; + } + else memcpy(face->Shades,mat->Ambient,sizeof(mat->Ambient)); // flat shading + + if ((mat->Texture && mat->TexMapIdx<0)||(mat->Texture2 && mat->Tex2MapIdx<0)) { + face->MappingU[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 + (v0->xformednx); + face->MappingV[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 - (v0->xformedny); + face->MappingU[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 + (v1->xformednx); + face->MappingV[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 - (v1->xformedny); + face->MappingU[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 + (v2->xformednx); + face->MappingV[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 - (v2->xformedny); + } + + if (mat->Smoothing && (mat->Lightable || mat->FadeDist)) + { + int a; + for (a = 0; a < 3; a ++) { + pl_Float val[3]; + memcpy(val,face->vsLighting[a],sizeof(val)); + pl_Vertex *thisvert = obj->Vertices.Get()+face->VertexIndices[a]; + + if (mat->Lightable) + { + int i=_numlights; + _lightInfo *inf = _lights.Get(); + while (i--) + { + double lightsc = 0.0; + pl_Light *light = inf->light; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + double nx2 = inf->l[0] - thisvert->xformedx; + double ny2 = inf->l[1] - thisvert->xformedy; + double nz2 = inf->l[2] - thisvert->xformedz; + MACRO_plNormalizeVector(nx2,ny2,nz2); + lightsc = MACRO_plDotProduct(thisvert->xformednx, + thisvert->xformedny, + thisvert->xformednz, + nx2,ny2,nz2); + } + if (light->Type & PL_LIGHT_POINT_DISTANCE) { + double nx2 = inf->l[0] - thisvert->xformedx; + double ny2 = inf->l[1] - thisvert->xformedy; + double nz2 = inf->l[2] - thisvert->xformedz; + if (light->Type & PL_LIGHT_POINT_ANGLE) { + double t= (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); + lightsc *= plMax(0,plMin(1.0,t)); + } else { + lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared)); + lightsc = plMax(0,plMin(1.0,lightsc)); + } + } + + if (light->Type == PL_LIGHT_VECTOR) + lightsc = MACRO_plDotProduct(thisvert->xformednx, + thisvert->xformedny, + thisvert->xformednz, + inf->l[0],inf->l[1],inf->l[2]); + if (lightsc > 0.0) + { + val[0] += lightsc * light->Intensity[0]; + val[1] += lightsc * light->Intensity[1]; + val[2] += lightsc * light->Intensity[2]; + } + else if (mat->BackfaceIllumination) + { + val[0] -= lightsc * light->Intensity[0]*mat->BackfaceIllumination; + val[1] -= lightsc * light->Intensity[1]*mat->BackfaceIllumination; + val[2] -= lightsc * light->Intensity[2]*mat->BackfaceIllumination; + } + inf++; + } /* End of light loop */ + } /* End of gouraud shading if */ + if (mat->FadeDist) + { + double lightsc = 1.0-thisvert->xformedz/mat->FadeDist; + if (lightsc<0.0) lightsc=0.0; + else if (lightsc>1.0)lightsc=1.0; + if (mat->Lightable) + { + val[0] *= lightsc; + val[1] *= lightsc; + val[2] *= lightsc; + } + else + { + val[0] += lightsc; + val[1] += lightsc; + val[2] += lightsc; + } + } + face->Shades[a][0] = mat->Ambient[0] + mat->Diffuse[0]*val[0]; + face->Shades[a][1] = mat->Ambient[1] + mat->Diffuse[1]*val[1]; + face->Shades[a][2] = mat->Ambient[2] + mat->Diffuse[2]*val[2]; + } /* End of vertex loop for */ + } /* End of gouraud shading mask if */ + else // flat modes, shade all vertices + { + memcpy(&face->Shades[1][0],&face->Shades[0][0],sizeof(pl_Float)*3); + memcpy(&face->Shades[2][0],&face->Shades[0][0],sizeof(pl_Float)*3); + } + + facelistout->zd = v0->xformedz+v1->xformedz+v2->xformedz; + facelistout->obj=obj; + facelistout->face = face; + facelistout++; + + + RenderTrisCulled++; + + } /* Is it in our area Check */ + } /* Backface Check */ + face++; + } + _numfaces = facelistout-_faces.Get(); +} +void pl_Cam::SortToCurrent() +{ + if (Sort && _numfaces > _numfaces_sorted+1) + { + WDL_mergesort(_faces.Get()+_numfaces_sorted, + _numfaces-_numfaces_sorted,sizeof(_faceInfo), + Sort > 0 ? sortFwdFunc : sortRevFunc, + (char*)_sort_tmpspace.Resize((_numfaces-_numfaces_sorted)*sizeof(_faceInfo),false)); + } + _numfaces_sorted=_numfaces; +} + +int pl_Cam::sortRevFunc(const void *a, const void *b) +{ + _faceInfo *aa = (_faceInfo*)a; + _faceInfo *bb = (_faceInfo*)b; + + if (aa->zd < bb->zd) return -1; + if (aa->zd > bb->zd) return 1; + return 0; +} + +int pl_Cam::sortFwdFunc(const void *a, const void *b) +{ + _faceInfo *aa = (_faceInfo*)a; + _faceInfo *bb = (_faceInfo*)b; + + if (aa->zd < bb->zd) return 1; + if (aa->zd > bb->zd) return -1; + return 0; +} + +void pl_Cam::End() { + if (!frameBuffer) return; + + SortToCurrent(); + + _faceInfo *f = _faces.Get(); + int n=_numfaces; + while (n-->0) + { + if (f->face->Material) + { + ClipRenderFace(f->face,f->obj); + } + f++; + } + frameBuffer=0; + _numfaces=0; + _numlights = 0; +} + + + + +void pl_Light::Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist) { + pl_Float m[16], m2[16]; + Type = mode; + Intensity[0] = intensity_r; + Intensity[1] = intensity_g; + Intensity[2] = intensity_b; + HalfDistSquared = halfDist*halfDist; + switch (mode) { + case PL_LIGHT_VECTOR: + plMatrixRotate(m,1,x); + plMatrixRotate(m2,2,y); + plMatrixMultiply(m,m2); + plMatrixRotate(m2,3,z); + plMatrixMultiply(m,m2); + plMatrixApply(m,0.0,0.0,-1.0,&Xp, &Yp, &Zp); + break; + case PL_LIGHT_POINT_ANGLE: + case PL_LIGHT_POINT_DISTANCE: + case PL_LIGHT_POINT: + Xp = x; + Yp = y; + Zp = z; + break; + } +} \ No newline at end of file diff --git a/WDL/plush2/pl_make.cpp b/WDL/plush2/pl_make.cpp new file mode 100644 index 00000000..4147a49e --- /dev/null +++ b/WDL/plush2/pl_make.cpp @@ -0,0 +1,480 @@ +/****************************************************************************** +Plush Version 1.2 +make.c +Object Primitives +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************* + Notes: + Most of these routines are highly unoptimized. + They could all use some work, such as more capable divisions (Box is + most notable), etc... The mapping coordinates are all set up nicely, + though. +******************************************************************************/ + +#include "plush.h" + +pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, pl_uInt divrad, + pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + double ravg, rt, a, da, al, dal; + pl_Float U,V,dU,dV; + if (divrot < 3) divrot = 3; + if (divrad < 3) divrad = 3; + ravg = (r1+r2)*0.5; + rt = (r2-r1)*0.5; + o = new pl_Obj(divrad*divrot,divrad*divrot*2); + if (!o) return 0; + v = o->Vertices.Get(); + a = 0.0; + da = 2*PL_PI/divrot; + for (y = 0; y < divrot; y ++) { + al = 0.0; + dal = 2*PL_PI/divrad; + for (x = 0; x < divrad; x ++) { + v->x = (pl_Float) (cos((double) a)*(ravg + cos((double) al)*rt)); + v->z = (pl_Float) (sin((double) a)*(ravg + cos((double) al)*rt)); + v->y = (pl_Float) (sin((double) al)*rt); + v++; + al += dal; + } + a += da; + } + v = o->Vertices.Get(); + f = o->Faces.Get(); + dV = 1.0/divrad; + dU = 1.0/divrot; + U = 0; + for (y = 0; y < divrot; y ++) { + V = -0.5; + for (x = 0; x < divrad; x ++) { + f->VertexIndices[0] = v+x+y*divrad - o->Vertices.Get(); + f->MappingU[0][0] = U; + f->MappingV[0][0] = V; + f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get(); + f->MappingU[0][1] = U; + f->MappingV[0][1] = V+dV; + f->VertexIndices[2] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); + f->MappingU[0][2] = U+dU; + f->MappingV[0][2] = V; + f->Material = m; + f++; + f->VertexIndices[0] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); + f->MappingU[0][0] = U+dU; + f->MappingV[0][0] = V; + f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get(); + f->MappingU[0][1] = U; + f->MappingV[0][1] = V+dV; + f->VertexIndices[2] = v+(x+1==divrad?0:x+1)+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get(); + f->MappingU[0][2] = U+dU; + f->MappingV[0][2] = V+dV; + f->Material = m; + f++; + V += dV; + } + U += dU; + } + o->CalculateNormals(); + return (o); +} + +pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + double a, da, yp, ya, yda, yf; + pl_Float U,V,dU,dV; + if (divh < 3) divh = 3; + if (divr < 3) divr = 3; + o = new pl_Obj(2+(divh-2)*(divr),2*divr+(divh-3)*divr*2); + if (!o) return 0; + v = o->Vertices.Get(); + v->x = v->z = 0.0; v->y = r; v++; + v->x = v->z = 0.0; v->y = -r; v++; + ya = 0.0; + yda = PL_PI/(divh-1); + da = (PL_PI*2.0)/divr; + for (y = 0; y < divh - 2; y ++) { + ya += yda; + yp = cos((double) ya)*r; + yf = sin((double) ya)*r; + a = 0.0; + for (x = 0; x < divr; x ++) { + v->y = (pl_Float) yp; + v->x = (pl_Float) (cos((double) a)*yf); + v->z = (pl_Float) (sin((double) a)*yf); + v++; + a += da; + } + } + f = o->Faces.Get(); + v = o->Vertices.Get() + 2; + a = 0.0; + U = 0; + dU = 1.0/divr; + dV = V = 1.0/divh; + for (x = 0; x < divr; x ++) { + f->VertexIndices[0] = 0; + f->VertexIndices[1] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get(); + f->VertexIndices[2] = v + x - o->Vertices.Get(); + f->MappingU[0][0] = U; + f->MappingV[0][0] = 0; + f->MappingU[0][1] = U+dU; + f->MappingV[0][1] = V; + f->MappingU[0][2] = U; + f->MappingV[0][2] = V; + f->Material = m; + f++; + U += dU; + } + da = 1.0/(divr+1); + v = o->Vertices.Get() + 2; + for (x = 0; x < (divh-3); x ++) { + U = 0; + for (y = 0; y < divr; y ++) { + f->VertexIndices[0] = v+y - o->Vertices.Get(); + f->VertexIndices[1] = v+divr+(y+1==divr?0:y+1) - o->Vertices.Get(); + f->VertexIndices[2] = v+y+divr - o->Vertices.Get(); + f->MappingU[0][0] = U; + f->MappingV[0][0] = V; + f->MappingU[0][1] = U+dU; + f->MappingV[0][1] = V+dV; + f->MappingU[0][2] = U; + f->MappingV[0][2] = V+dV; + f->Material = m; f++; + f->VertexIndices[0] = v+y - o->Vertices.Get(); + f->VertexIndices[1] = v+(y+1==divr?0:y+1) - o->Vertices.Get(); + f->VertexIndices[2] = v+(y+1==divr?0:y+1)+divr - o->Vertices.Get(); + f->MappingU[0][0] = U; + f->MappingV[0][0] = V; + f->MappingU[0][1] = U+dU; + f->MappingV[0][1] = V; + f->MappingU[0][2] = U+dU; + f->MappingV[0][2] = V+dV; + f->Material = m; f++; + U += dU; + } + V += dV; + v += divr; + } + v = o->Vertices.Get() + o->Vertices.GetSize() - divr; + U = 0; + for (x = 0; x < divr; x ++) { + f->VertexIndices[0] = 1; + f->VertexIndices[1] = v + x - o->Vertices.Get(); + f->VertexIndices[2] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get(); + f->MappingU[0][0] = U; + f->MappingV[0][0] = 1.0; + f->MappingU[0][1] = U; + f->MappingV[0][1] = V; + f->MappingU[0][2] = U+dU; + f->MappingV[0][2] = V; + f->Material = m; + f++; + U += dU; + } + o->CalculateNormals(); + return (o); +} + +pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, + pl_Bool capbottom, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v, *topverts, *bottomverts, *topcapvert=0, *bottomcapvert=0; + pl_Face *f; + pl_uInt32 i; + double a, da; + if (divr < 3) divr = 3; + o = new pl_Obj(divr*2+((divr==3)?0:(captop?1:0)+(capbottom?1:0)), + divr*2+(divr==3 ? (captop ? 1 : 0) + (capbottom ? 1 : 0) : + (captop ? divr : 0) + (capbottom ? divr : 0))); + if (!o) return 0; + a = 0.0; + da = (2.0*PL_PI)/divr; + v = o->Vertices.Get(); + topverts = v; + for (i = 0; i < divr; i ++) { + v->y = h/2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float)(r*sin(a)); + v->xformedx = (0.5 + (0.5*cos((double) a))); // temp + v->xformedy = (0.5 + (0.5*sin((double) a))); // use xf + v++; + a += da; + } + bottomverts = v; + a = 0.0; + for (i = 0; i < divr; i ++) { + v->y = -h/2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float) (r*sin(a)); + v->xformedx = (0.5 + (0.5*cos((double) a))); + v->xformedy = (0.5 + (0.5*sin((double) a))); + v++; a += da; + } + if (captop && divr != 3) { + topcapvert = v; + v->y = h / 2.0f; + v->x = v->z = 0.0f; + v++; + } + if (capbottom && divr != 3) { + bottomcapvert = v; + v->y = -h / 2.0f; + v->x = v->z = 0.0f; + v++; + } + f = o->Faces.Get(); + for (i = 0; i < divr; i ++) { + f->VertexIndices[0] = bottomverts + i - o->Vertices.Get(); + f->VertexIndices[1] = topverts + i - o->Vertices.Get(); + f->VertexIndices[2] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); + f->MappingV[0][0] = f->MappingV[0][2] = 1.0; f->MappingV[0][1] = 0; + f->MappingU[0][0] = f->MappingU[0][1] = i/(double)divr; + f->MappingU[0][2] = ((i+1))/(double)divr; + f->Material = m; f++; + f->VertexIndices[0] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); + f->VertexIndices[1] = topverts + i - o->Vertices.Get(); + f->VertexIndices[2] = topverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get(); + f->MappingV[0][1] = f->MappingV[0][2] = 0; f->MappingV[0][0] = 1.0; + f->MappingU[0][0] = f->MappingU[0][2] = ((i+1))/(double)divr; + f->MappingU[0][1] = (i)/(double)divr; + f->Material = m; f++; + } + if (captop) { + if (divr == 3) { + f->VertexIndices[0] = topverts + 0 - o->Vertices.Get(); + f->VertexIndices[1] = topverts + 2 - o->Vertices.Get(); + f->VertexIndices[2] = topverts + 1 - o->Vertices.Get(); + f->MappingU[0][0] = topverts[0].xformedx; + f->MappingV[0][0] = topverts[0].xformedy; + f->MappingU[0][1] = topverts[1].xformedx; + f->MappingV[0][1] = topverts[1].xformedy; + f->MappingU[0][2] = topverts[2].xformedx; + f->MappingV[0][2] = topverts[2].xformedy; + f->Material = m; f++; + } else { + for (i = 0; i < divr; i ++) { + f->VertexIndices[0] = topverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get(); + f->VertexIndices[1] = topverts + i - o->Vertices.Get(); + f->VertexIndices[2] = topcapvert - o->Vertices.Get(); + f->MappingU[0][0] = topverts[(i==divr-1?0:i+1)].xformedx; + f->MappingV[0][0] = topverts[(i==divr-1?0:i+1)].xformedy; + f->MappingU[0][1] = topverts[i].xformedx; + f->MappingV[0][1] = topverts[i].xformedy; + f->MappingU[0][2] = f->MappingV[0][2] = 0.5; + f->Material = m; f++; + } + } + } + if (capbottom) { + if (divr == 3) { + f->VertexIndices[0] = bottomverts + 0 - o->Vertices.Get(); + f->VertexIndices[1] = bottomverts + 1 - o->Vertices.Get(); + f->VertexIndices[2] = bottomverts + 2 - o->Vertices.Get(); + f->MappingU[0][0] = bottomverts[0].xformedx; + f->MappingV[0][0] = bottomverts[0].xformedy; + f->MappingU[0][1] = bottomverts[1].xformedx; + f->MappingV[0][1] = bottomverts[1].xformedy; + f->MappingU[0][2] = bottomverts[2].xformedx; + f->MappingV[0][2] = bottomverts[2].xformedy; + f->Material = m; f++; + } else { + for (i = 0; i < divr; i ++) { + f->VertexIndices[0] = bottomverts + i - o->Vertices.Get(); + f->VertexIndices[1] = bottomverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get(); + f->VertexIndices[2] = bottomcapvert - o->Vertices.Get(); + f->MappingU[0][0] = bottomverts[i].xformedx; + f->MappingV[0][0] = bottomverts[i].xformedy; + f->MappingU[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedx; + f->MappingV[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedy; + f->MappingU[0][2] = f->MappingV[0][2] = 0.5; + f->Material = m; f++; + } + } + } + o->CalculateNormals(); + return (o); +} + +pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, + pl_Bool cap, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt32 i; + double a, da; + if (div < 3) div = 3; + o = new pl_Obj(div + (div == 3 ? 1 : (cap ? 2 : 1)), + div + (div == 3 ? 1 : (cap ? div : 0))); + if (!o) return 0; + v = o->Vertices.Get(); + v->x = v->z = 0; v->y = h/2; + v->xformedx = 0.5; + v->xformedy = 0.5; + v++; + a = 0.0; + da = (2.0*PL_PI)/div; + for (i = 1; i <= div; i ++) { + v->y = h/-2.0f; + v->x = (pl_Float) (r*cos((double) a)); + v->z = (pl_Float) (r*sin((double) a)); + v->xformedx = (0.5 + (cos((double) a)*0.5)); + v->xformedy = (0.5 + (sin((double) a)*0.5)); + a += da; + v++; + } + if (cap && div != 3) { + v->y = h / -2.0f; + v->x = v->z = 0.0f; + v->xformedx = 0.5; + v->xformedy = 0.5; + v++; + } + f = o->Faces.Get(); + for (i = 1; i <= div; i ++) { + f->VertexIndices[0] = 0; + f->VertexIndices[1] = o->Vertices.Get() + (i == div ? 1 : i + 1) - o->Vertices.Get(); + f->VertexIndices[2] = o->Vertices.Get() + i - o->Vertices.Get(); + f->MappingU[0][0] = o->Vertices.Get()[0].xformedx; + f->MappingV[0][0] = o->Vertices.Get()[0].xformedy; + f->MappingU[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedx; + f->MappingV[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedy; + f->MappingU[0][2] = o->Vertices.Get()[i].xformedx; + f->MappingV[0][2] = o->Vertices.Get()[i].xformedy; + f->Material = m; + f++; + } + if (cap) { + if (div == 3) { + f->VertexIndices[0] = 1; + f->VertexIndices[1] = 2; + f->VertexIndices[2] = 3; + f->MappingU[0][0] = o->Vertices.Get()[1].xformedx; + f->MappingV[0][0] = o->Vertices.Get()[1].xformedy; + f->MappingU[0][1] = o->Vertices.Get()[2].xformedx; + f->MappingV[0][1] = o->Vertices.Get()[2].xformedy; + f->MappingU[0][2] = o->Vertices.Get()[3].xformedx; + f->MappingV[0][2] = o->Vertices.Get()[3].xformedy; + f->Material = m; + f++; + } else { + for (i = 1; i <= div; i ++) { + f->VertexIndices[0] = div + 1; + f->VertexIndices[1] = i; + f->VertexIndices[2] = (i==div ? 1 : i+1); + f->MappingU[0][0] = o->Vertices.Get()[div+1].xformedx; + f->MappingV[0][0] = o->Vertices.Get()[div+1].xformedy; + f->MappingU[0][1] = o->Vertices.Get()[i].xformedx; + f->MappingV[0][1] = o->Vertices.Get()[i].xformedy; + f->MappingU[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedx; + f->MappingV[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedy; + f->Material = m; + f++; + } + } + } + o->CalculateNormals(); + return (o); +} + +static pl_uChar verts[6*6] = { + 0,4,1, 1,4,5, 0,1,2, 3,2,1, 2,3,6, 3,7,6, + 6,7,4, 4,7,5, 1,7,3, 7,1,5, 2,6,0, 4,0,6 +}; +static pl_uChar map[24*2*3] = { + 1,0, 1,1, 0,0, 0,0, 1,1, 0,1, + 0,0, 1,0, 0,1, 1,1, 0,1, 1,0, + 0,0, 1,0, 0,1, 1,0, 1,1, 0,1, + 0,0, 1,0, 0,1, 0,1, 1,0, 1,1, + 1,0, 0,1, 0,0, 0,1, 1,0, 1,1, + 1,0, 1,1, 0,0, 0,1, 0,0, 1,1 +}; + + +pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m) { + pl_uChar *mm = map; + pl_uChar *vv = verts; + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x; + o = new pl_Obj(8,12); + if (!o) return 0; + v = o->Vertices.Get(); + v->x = -w/2; v->y = h/2; v->z = d/2; v++; + v->x = w/2; v->y = h/2; v->z = d/2; v++; + v->x = -w/2; v->y = h/2; v->z = -d/2; v++; + v->x = w/2; v->y = h/2; v->z = -d/2; v++; + v->x = -w/2; v->y = -h/2; v->z = d/2; v++; + v->x = w/2; v->y = -h/2; v->z = d/2; v++; + v->x = -w/2; v->y = -h/2; v->z = -d/2; v++; + v->x = w/2; v->y = -h/2; v->z = -d/2; v++; + f = o->Faces.Get(); + for (x = 0; x < 12; x ++) { + f->VertexIndices[0] = *vv++; + f->VertexIndices[1] = *vv++; + f->VertexIndices[2] = *vv++; + f->MappingU[0][0] = (pl_Float) *mm++; + f->MappingV[0][0] = (pl_Float) *mm++; + f->MappingU[0][1] = (pl_Float) *mm++; + f->MappingV[0][1] = (pl_Float) *mm++; + f->MappingU[0][2] = (pl_Float) *mm++; + f->MappingV[0][2] = (pl_Float) *mm++; + f->Material = m; + f++; + } + + o->CalculateNormals(); + return (o); +} + +pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m) { + pl_Obj *o; + pl_Vertex *v; + pl_Face *f; + pl_uInt x, y; + o = new pl_Obj((res+1)*(res+1),res*res*2); + if (!o) return 0; + v = o->Vertices.Get(); + for (y = 0; y <= res; y ++) { + for (x = 0; x <= res; x ++) { + v->y = 0; + v->x = ((x*w)/res) - w/2; + v->z = ((y*d)/res) - d/2; + v++; + } + } + f = o->Faces.Get(); + for (y = 0; y < res; y ++) { + for (x = 0; x < res; x ++) { + f->VertexIndices[0] = x+(y*(res+1)); + f->MappingU[0][0] = (x)/(double)res; + f->MappingV[0][0] = (y)/(double)res; + f->VertexIndices[2] = x+1+(y*(res+1)); + f->MappingU[0][2] = ((x+1))/(double)res; + f->MappingV[0][2] = (y)/(double)res; + f->VertexIndices[1] = x+((y+1)*(res+1)); + f->MappingU[0][1] = (x)/(double)res; + f->MappingV[0][1] = ((y+1))/(double)res; + f->Material = m; + f++; + f->VertexIndices[0] = x+((y+1)*(res+1)); + f->MappingU[0][0] = (x)/(double)res; + f->MappingV[0][0] = ((y+1))/(double)res; + f->VertexIndices[2] = x+1+(y*(res+1)); + f->MappingU[0][2] = ((x+1))/(double)res; + f->MappingV[0][2] = (y)/(double)res; + f->VertexIndices[1] = x+1+((y+1)*(res+1)); + f->MappingU[0][1] = ((x+1))/(double)res; + f->MappingV[0][1] = ((y+1))/(double)res; + f->Material = m; + f++; + } + } + o->CalculateNormals(); + return (o); +} diff --git a/WDL/plush2/pl_math.cpp b/WDL/plush2/pl_math.cpp new file mode 100644 index 00000000..dcedf6a2 --- /dev/null +++ b/WDL/plush2/pl_math.cpp @@ -0,0 +1,67 @@ +/****************************************************************************** +Plush Version 1.2 +math.c +Math and Matrix Control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg) { + pl_uChar m1, m2; + double c,s; + double d= Deg * PL_PI / 180.0; + memset(matrix,0,sizeof(pl_Float)*16); + matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0; + m1 = (m % 3); + m2 = ((m1+1) % 3); + c = cos(d); s = sin(d); + matrix[(m1<<2)+m1]=(pl_Float)c; matrix[(m1<<2)+m2]=(pl_Float)s; + matrix[(m2<<2)+m2]=(pl_Float)c; matrix[(m2<<2)+m1]=(pl_Float)-s; +} + +void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z) { + memset(m,0,sizeof(pl_Float)*16); + m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0; + m[0+3] = x; m[4+3] = y; m[8+3] = z; +} + +void plMatrixMultiply(pl_Float *dest, pl_Float src[]) { + pl_Float temp[16]; + pl_uInt i; + memcpy(temp,dest,sizeof(pl_Float)*16); + for (i = 0; i < 16; i += 4) { + *dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+ + src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0]; + *dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+ + src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1]; + *dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+ + src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2]; + *dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+ + src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3]; + } +} + +void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, + pl_Float *outx, pl_Float *outy, pl_Float *outz) { + *outx = x*m[0] + y*m[1] + z*m[2] + m[3]; + *outy = x*m[4] + y*m[5] + z*m[6] + m[7]; + *outz = x*m[8] + y*m[9] + z*m[10] + m[11]; +} + +pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, + pl_Float x2, pl_Float y2, pl_Float z2) { + return ((x1*x2)+(y1*y2)+(z1*z2)); +} + +void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z) { + double length; + length = (*x)*(*x)+(*y)*(*y)+(*z)*(*z); + if (length > 0.0000000001) { + pl_Float t = (pl_Float)sqrt(length); + *x /= t; + *y /= t; + *z /= t; + } else *x = *y = *z = 0.0; +} + diff --git a/WDL/plush2/pl_obj.cpp b/WDL/plush2/pl_obj.cpp new file mode 100644 index 00000000..ca366f99 --- /dev/null +++ b/WDL/plush2/pl_obj.cpp @@ -0,0 +1,128 @@ +/****************************************************************************** +Plush Version 1.2 +obj.c +Object control +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void pl_Obj::Scale(pl_Float s) { + int i = Vertices.GetSize(); + pl_Vertex *v = Vertices.Get(); + while (i--) { + v->x *= s; v->y *= s; v->z *= s; v++; + } + for (i = 0; i < Children.GetSize(); i ++) + if (Children.Get(i)) Children.Get(i)->Scale(s); +} + +void pl_Obj::Stretch(pl_Float x, pl_Float y, pl_Float z) { + int i = Vertices.GetSize(); + pl_Vertex *v = Vertices.Get(); + while (i--) { + v->x *= x; v->y *= y; v->z *= z; v++; + } + for (i = 0; i < Children.GetSize(); i ++) + if (Children.Get(i)) Children.Get(i)->Stretch(x,y,z); +} + +void pl_Obj::Translate(pl_Float x, pl_Float y, pl_Float z) { + int i = Vertices.GetSize(); + pl_Vertex *v = Vertices.Get(); + while (i--) { + v->x += x; v->y += y; v->z += z; v++; + } + for (i = 0; i < Children.GetSize(); i ++) + if (Children.Get(i)) Children.Get(i)->Translate(x,y,z); +} + +void pl_Obj::FlipNormals() { + int i = Vertices.GetSize(); + pl_Vertex *v = Vertices.Get(); + pl_Face *f = Faces.Get(); + while (i--) { + v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++; + } + i = Faces.GetSize(); + while (i--) { + f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz; + f++; + } + for (i = 0; i < Children.GetSize(); i ++) + if (Children.Get(i)) Children.Get(i)->FlipNormals(); +} + + +pl_Obj *pl_Obj::Clone() { + int i; + pl_Obj *out; + if (!(out = new pl_Obj(Vertices.GetSize(),Faces.GetSize()))) return 0; + for (i = 0; i < Children.GetSize(); i ++) + out->Children.Add(Children.Get(i) ? Children.Get(i)->Clone() : NULL); + + out->Xa = Xa; out->Ya = Ya; out->Za = Za; + out->Xp = Xp; out->Yp = Yp; out->Zp = Zp; + out->GenMatrix = GenMatrix; + memcpy(out->Vertices.Get(), Vertices.Get(), sizeof(pl_Vertex) * Vertices.GetSize()); + memcpy(out->Faces.Get(),Faces.Get(),sizeof(pl_Face) * Faces.GetSize()); + return out; +} + +void pl_Obj::SetMaterial(pl_Mat *m, pl_Bool th) { + pl_sInt32 i = Faces.GetSize(); + pl_Face *f = Faces.Get(); + while (i--) (f++)->Material = m; + if (th) for (i = 0; i < Children.GetSize(); i++) + if (Children.Get(i)) Children.Get(i)->SetMaterial(m,true); +} + +void pl_Obj::CalculateNormals() { + int i; + pl_Vertex *v = Vertices.Get(); + pl_Face *f = Faces.Get(); + double x1, x2, y1, y2, z1, z2; + i = Vertices.GetSize(); + while (i--) { + v->nx = 0.0; v->ny = 0.0; v->nz = 0.0; + v++; + } + i = Faces.GetSize(); + while (i--) { + pl_Vertex *vp=Vertices.Get(); + pl_Vertex *fVertices[3] = { + vp+f->VertexIndices[0], + vp+f->VertexIndices[1], + vp+f->VertexIndices[2], + }; + x1 = fVertices[0]->x-fVertices[1]->x; + x2 = fVertices[0]->x-fVertices[2]->x; + y1 = fVertices[0]->y-fVertices[1]->y; + y2 = fVertices[0]->y-fVertices[2]->y; + z1 = fVertices[0]->z-fVertices[1]->z; + z2 = fVertices[0]->z-fVertices[2]->z; + f->nx = (pl_Float) (y1*z2 - z1*y2); + f->ny = (pl_Float) (z1*x2 - x1*z2); + f->nz = (pl_Float) (x1*y2 - y1*x2); + plNormalizeVector(&f->nx, &f->ny, &f->nz); + fVertices[0]->nx += f->nx; + fVertices[0]->ny += f->ny; + fVertices[0]->nz += f->nz; + fVertices[1]->nx += f->nx; + fVertices[1]->ny += f->ny; + fVertices[1]->nz += f->nz; + fVertices[2]->nx += f->nx; + fVertices[2]->ny += f->ny; + fVertices[2]->nz += f->nz; + f++; + } + v = Vertices.Get(); + i = Vertices.GetSize(); + do { + plNormalizeVector(&v->nx, &v->ny, &v->nz); + v++; + } while (--i); + + for (i = 0; i < Children.GetSize(); i ++) + if (Children.Get(i)) Children.Get(i)->CalculateNormals(); +} diff --git a/WDL/plush2/pl_pf_tex.h b/WDL/plush2/pl_pf_tex.h new file mode 100644 index 00000000..e8075813 --- /dev/null +++ b/WDL/plush2/pl_pf_tex.h @@ -0,0 +1,442 @@ + +static void +#ifdef PL_PF_MULTITEX +PLMTexTri +#else +PLTexTri +#endif +(LICE_pixel *gmem, int swidth, pl_Face *TriFace, pl_ZBuffer *zbuf, int zfb_width, + int solidalpha, int solidcomb, LICE_IBitmap *tex, pl_Float *texscales, int texalpha, int texcomb, int texmap +#ifdef PL_PF_MULTITEX + , LICE_IBitmap *tex2, int tex2alpha, int tex2comb, int texmap2 +#endif + + ) +{ + pl_sInt32 C1[3], C3[3], C2[3], dC2[3]={0}, dCL[3]={0},dC1[3]={0}, dX2=0, dX1=0; + pl_Float dZ2=0, dZL=0,dZ1=0; + + PUTFACE_SORT(); + + + solidcomb&=LICE_BLIT_MODE_MASK; + if (solidcomb == 0 && solidalpha == 256) solidcomb=-1; + else if (solidalpha==0) solidcomb=-2; // ignore + int solidalpha2=(256-solidalpha)*256; + + + pl_Float dU2=0,dV2=0,dUL=0,dVL=0; + pl_Float dU1=0, dV1=0; + bool bilinear = (texcomb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR; + texcomb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA; + if (texcomb==LICE_BLIT_MODE_COPY && texalpha==256) texcomb=-1; + else if (texalpha==0) texcomb=-2; + int texalpha2=(256-texalpha); + + int tex_rowspan=0; + LICE_pixel *texture=NULL; + int tex_w=16,tex_h=16; + +#if defined(PLUSH_NO_SOLIDGOURAUD) || defined(PLUSH_NO_TEXTURE) + if (tex) +#endif + { + texture=tex->getBits(); + tex_rowspan = tex->getRowSpan(); + if (tex->isFlipped()) + { + texture += tex_rowspan*(tex->getHeight()-1); + tex_rowspan=-tex_rowspan; + } + tex_w=tex->getWidth(); + tex_h=tex->getHeight(); + } + pl_sInt32 MappingU_Max=tex_w<<16, MappingV_Max=tex_h<<16; + texscales[0]*=MappingU_Max; + texscales[1]*=MappingV_Max; + +#ifdef PL_PF_MULTITEX + + pl_Float dU2_2=0,dV2_2=0,dUL_2=0,dVL_2=0; + pl_Float dU1_2=0, dV1_2=0; + int tex_w_2=16,tex_h_2=16; + bool bilinear2 = (tex2comb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR; + tex2comb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA; + if (tex2comb==LICE_BLIT_MODE_COPY && tex2alpha==256) tex2comb=-1; + else if (tex2alpha==0) tex2comb=-2; + int tex2alpha2=(256-tex2alpha); + LICE_pixel *texture_2=NULL; + int tex_rowspan_2 = 0; + pl_sInt32 MappingU_Max_2, MappingV_Max_2; + +#ifdef PLUSH_NO_TEXTURE + if (tex2) +#endif + { + tex_w_2=tex2->getWidth(); + tex_h_2=tex2->getHeight(); + texture_2=tex2->getBits(); + tex_rowspan_2 = tex2->getRowSpan(); + if (tex2->isFlipped()) + { + texture_2 += tex_rowspan_2*(tex2->getHeight()-1); + tex_rowspan_2=-tex_rowspan_2; + } + } + MappingU_Max_2=tex_w_2<<16; + MappingV_Max_2=tex_h_2<<16; + texscales[2]*=MappingU_Max_2; + texscales[3]*=MappingV_Max_2; +#endif + + + pl_uChar nm = TriFace->Material->PerspectiveCorrect; + pl_uChar nmb = 0; while (nm) { nmb++; nm >>= 1; } + nmb = plMin(6,nmb); + nm = 1<Scrz[i0]; + pl_Float Z2 = TriFace->Scrz[i1]; + pl_Float Z3 = TriFace->Scrz[i2]; + + pl_Float MappingU1=TriFace->MappingU[texmap][i0]*texscales[0]*Z1; + pl_Float MappingV1=TriFace->MappingV[texmap][i0]*texscales[1]*Z1; + pl_Float MappingU2=TriFace->MappingU[texmap][i1]*texscales[0]*Z2; + pl_Float MappingV2=TriFace->MappingV[texmap][i1]*texscales[1]*Z2; + pl_Float MappingU3=TriFace->MappingU[texmap][i2]*texscales[0]*Z3; + pl_Float MappingV3=TriFace->MappingV[texmap][i2]*texscales[1]*Z3; + +#ifdef PL_PF_MULTITEX + pl_Float MappingU1_2=TriFace->MappingU[texmap2][i0]*texscales[2]*Z1; + pl_Float MappingV1_2=TriFace->MappingV[texmap2][i0]*texscales[3]*Z1; + pl_Float MappingU2_2=TriFace->MappingU[texmap2][i1]*texscales[2]*Z2; + pl_Float MappingV2_2=TriFace->MappingV[texmap2][i1]*texscales[3]*Z2; + pl_Float MappingU3_2=TriFace->MappingU[texmap2][i2]*texscales[2]*Z3; + pl_Float MappingV3_2=TriFace->MappingV[texmap2][i2]*texscales[3]*Z3; +#endif + + int a; + for(a=0;a<3;a++) + { + C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24)); + C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24)); + C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24)); + } + + pl_Float U1, U2; + U1 = U2 = MappingU1; + pl_Float V1,V2; + V1 = V2 = MappingV1; +#ifdef PL_PF_MULTITEX + pl_Float U1_2, U2_2; + U1_2 = U2_2 = MappingU1_2; + pl_Float V1_2, V2_2; + V1_2 = V2_2 = MappingV1_2; +#endif + + pl_sInt32 X2,X1; + X2 = X1 = Scrx[i0]; + pl_sInt32 Y0 = Scry[i0]; + pl_sInt32 Y1 = Scry[i1]; + pl_sInt32 Y2 = Scry[i2]; + + + { + pl_sInt32 dY = Y2-Y0; + if (dY) { + dX2 = (Scrx[i2] - X1) / dY; + + pl_Float v = 1.0/dY; + for(a=0;a<3;a++) dC2[a] = (pl_sInt32) ((C3[a] - C1[a]) * v); + dZ2 = (Z3 - Z1) * v; + dU2 = (MappingU3 - U1) * v; + dV2 = (MappingV3 - V1) * v; + #ifdef PL_PF_MULTITEX + dU2_2 = (MappingU3_2 - U1_2) * v; + dV2_2 = (MappingV3_2 - V1_2) * v; + #endif + } + dY = Y1-Y0; + if (dY) { + dX1 = (Scrx[i1] - X1) / dY; + pl_Float v=1.0/dY; + dZ1 = (Z2 - Z1) * v; + for(a=0;a<3;a++) dC1[a] = (pl_sInt32) ((C2[a] - C1[a]) * v); + dU1 = (MappingU2 - U1) * v; + dV1 = (MappingV2 - V1) * v; + #ifdef PL_PF_MULTITEX + dU1_2 = (MappingU2_2 - U1_2) * v; + dV1_2 = (MappingV2_2 - V1_2) * v; + #endif + if (dX2 < dX1) { + SWAP(dX1,dX2,pl_sInt32); + SWAP(dU1,dU2,pl_Float); + SWAP(dV1,dV2,pl_Float); + #ifdef PL_PF_MULTITEX + SWAP(dU1_2,dU2_2,pl_Float); + SWAP(dV1_2,dV2_2,pl_Float); + #endif + SWAP(dZ1,dZ2,pl_Float); + for(a=0;a<3;a++) + SWAP(dC1[a],dC2[a],pl_sInt32); + stat = 2; + } else stat = 1; + Z2 = Z1; + C2[0] = C1[0]; + C2[1] = C1[1]; + C2[2] = C1[2]; + + } else { + if (Scrx[i1] > X1) { + X2 = Scrx[i1]; + U2 = MappingU2; + V2 = MappingV2; + #ifdef PL_PF_MULTITEX + U2_2 = MappingU2_2; + V2_2 = MappingV2_2; + #endif + stat = 2|4; + } else { + X1 = Scrx[i1]; + SWAP(Z1,Z2,pl_Float) + for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32); + U1 = MappingU2; + V1 = MappingV2; + #ifdef PL_PF_MULTITEX + U1_2 = MappingU2_2; + V1_2 = MappingV2_2; + #endif + stat = 1|8; + } + } + pl_sInt32 tmp = (dX1-dX2)*dY; + if (tmp) { + pl_Float v=(1<>XPOS_BITS; + pl_sInt32 Xlen = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; + if (Xlen > 0) { + pl_sInt32 iUL, iVL, idUL, idVL, iULnext, iVLnext; + pl_Float UL = U1; + pl_Float VL = V1; +#ifdef PL_PF_MULTITEX + pl_sInt32 iUL_2, iVL_2, idUL_2, idVL_2, iULnext_2, iVLnext_2; + pl_Float UL_2 = U1_2; + pl_Float VL_2 = V1_2; +#endif + pl_sInt32 CL[3] = {C1[0],C1[1], C1[2]}; + pl_Float pZL,ZL; + pl_Float t = 1.0f / (pZL = ZL = Z1); + gmem += XL1; + zbuf += XL1; + + XL1 += Xlen; // update to new line end pos so we can adjust gmem/zbuf later + iULnext = ((pl_sInt32) (UL*t)); + iVLnext = ((pl_sInt32) (VL*t)); +#ifdef PL_PF_MULTITEX + iULnext_2 = ((pl_sInt32) (UL_2*t)); + iVLnext_2 = ((pl_sInt32) (VL_2*t)); +#endif + do { + UL += dUL; + VL += dVL; + iUL = iULnext; + iVL = iVLnext; + pZL += pdZL; + t = 1.0f/pZL; + iULnext = ((pl_sInt32) (UL*t)); + iVLnext = ((pl_sInt32) (VL*t)); + idUL = (iULnext - iUL)>>nmb; + idVL = (iVLnext - iVL)>>nmb; + if (idUL>MappingU_Max) idUL=MappingU_Max; + else if (idUL<-MappingU_Max) idUL=-MappingU_Max; + if (idVL>MappingV_Max) idVL=MappingV_Max; + else if (idVL<-MappingV_Max) idVL=-MappingV_Max; + + // todo: this is slow as shit, should we force textures to be powers of two? hehe + if (iUL<0) do iUL+=MappingU_Max; while (iUL<0); + else while (iUL >= MappingU_Max) iUL-=MappingU_Max; + if (iVL<0) do iVL+=MappingV_Max; while (iVL<0); + else while (iVL >= MappingV_Max) iVL-=MappingV_Max; + +#ifdef PL_PF_MULTITEX + UL_2 += dUL_2; + VL_2 += dVL_2; + iUL_2 = iULnext_2; + iVL_2 = iVLnext_2; + iULnext_2 = ((pl_sInt32) (UL_2*t)); + iVLnext_2 = ((pl_sInt32) (VL_2*t)); + idUL_2 = (iULnext_2 - iUL_2)>>nmb; + idVL_2 = (iVLnext_2 - iVL_2)>>nmb; + if (idUL_2>MappingU_Max_2) idUL_2=MappingU_Max_2; + else if (idUL_2<-MappingU_Max_2) idUL_2=-MappingU_Max_2; + if (idVL_2>MappingV_Max_2) idVL_2=MappingV_Max_2; + else if (idVL_2<-MappingV_Max_2) idVL_2=-MappingV_Max_2; + + // todo: this is slow as shit, should we force textures to be powers of two? hehe + if (iUL_2<0) do iUL_2+=MappingU_Max_2; while (iUL_2<0); + else while (iUL_2 >= MappingU_Max_2) iUL_2-=MappingU_Max_2; + if (iVL_2<0) do iVL_2+=MappingV_Max_2; while (iVL_2<0); + else while (iVL_2 >= MappingV_Max_2) iVL_2-=MappingV_Max_2; + +#endif + + pl_uInt n = nm; + Xlen -= n; + if (Xlen < 0) n += Xlen; + if (zfb_width) do { + if (*zbuf < ZL) { + *zbuf = (pl_ZBuffer) ZL; + + #ifdef PL_PF_MULTITEX + TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, + iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2, + bilinear2, iUL_2,iVL_2, + tex_w_2,tex_h_2, + texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2); + #else + TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL, + tex_w,tex_h, + texture,tex_rowspan,texcomb,texalpha,texalpha2); + #endif + + } + zbuf++; + gmem++; + ZL += dZL; + CL[0] += dCL[0]; + CL[1] += dCL[1]; + CL[2] += dCL[2]; + iUL += idUL; + iVL += idVL; + + if (iUL<0) iUL+=MappingU_Max; + else if (iUL >= MappingU_Max) iUL -= MappingU_Max; + if (iVL<0) iVL+=MappingV_Max; + else if (iVL >= MappingV_Max) iVL -= MappingV_Max; +#ifdef PL_PF_MULTITEX + iUL_2 += idUL_2; + iVL_2 += idVL_2; + + if (iUL_2<0) iUL_2+=MappingU_Max_2; + else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2; + if (iVL_2<0) iVL_2+=MappingV_Max_2; + else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2; +#endif + } while (--n); + else do { + + #ifdef PL_PF_MULTITEX + TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, + iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2, + bilinear2, iUL_2,iVL_2, + tex_w_2,tex_h_2, + texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2); + #else + TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL, + tex_w,tex_h, + texture,tex_rowspan,texcomb,texalpha,texalpha2); + #endif + + + gmem++; + CL[0] += dCL[0]; + CL[1] += dCL[1]; + CL[2] += dCL[2]; + iUL += idUL; + iVL += idVL; + + if (iUL<0) iUL+=MappingU_Max; + else if (iUL >= MappingU_Max) iUL -= MappingU_Max; + if (iVL<0) iVL+=MappingV_Max; + else if (iVL >= MappingV_Max) iVL -= MappingV_Max; + +#ifdef PL_PF_MULTITEX + iUL_2 += idUL_2; + iVL_2 += idVL_2; + + if (iUL_2<0) iUL_2+=MappingU_Max_2; + else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2; + if (iVL_2<0) iVL_2+=MappingV_Max_2; + else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2; +#endif + + } while (--n); + } while (Xlen > 0); + gmem += swidth-XL1; + zbuf += zfb_width-XL1; + } else { // xlen <=0 ,no drawing + gmem += swidth; + zbuf += zfb_width; + } + Z1 += dZ1; + U1 += dU1; + V1 += dV1; +#ifdef PL_PF_MULTITEX + U1_2 += dU1_2; + V1_2 += dV1_2; +#endif + X1 += dX1; + X2 += dX2; + C1[0] += dC1[0]; + C1[1] += dC1[1]; + C1[2] += dC1[2]; + } +} + + + diff --git a/WDL/plush2/pl_putface.cpp b/WDL/plush2/pl_putface.cpp new file mode 100644 index 00000000..259e82e4 --- /dev/null +++ b/WDL/plush2/pl_putface.cpp @@ -0,0 +1,707 @@ +#include "plush.h" +#include "../lice/lice_combine.h" + +//#define PLUSH_NO_SOLIDFLAT // make non-texturemapped flat shading optimized engine +//#define PLUSH_NO_SOLIDGOURAUD // disable non-texturemapped gouraud optimized engine +//#define PLUSH_NO_TEXTURE // disable single-texture optimized engine +//#define PLUSH_NO_MULTITEXTURE // disable multitexture (this can do any of em) +#define XPOS_BITS 19 // allows 2^13 max screen width, or 8192px + +#define SWAP(a,b,t) { t ____tmp=(a); (a)=(b); (b)=____tmp; } + +#define PUTFACE_SORT() \ + char i0 = 0; char i1 = 1; char i2 = 2; char stat; \ + if (TriFace->Scry[0] > TriFace->Scry[1]) { i0 = 1; i1 = 0; } \ + if (TriFace->Scry[i0] > TriFace->Scry[2]) { SWAP(i0,i2,char); } \ + if (TriFace->Scry[i1] > TriFace->Scry[i2]) { SWAP(i1,i2,char); } \ + int Scrx[3] = {(int)(TriFace->Scrx[0]*(1<Scrx[1]*(1<Scrx[2]*(1<Scry[0]+0.5), (int) (TriFace->Scry[1]+0.5), (int) (TriFace->Scry[2]+0.5)}; \ + +#define DO_STAT_XDELTAS \ + if (stat & 1) { \ + dX1 = (Scrx[i2]-(X1 = Scrx[i1]))/dY; \ + if (stat & 8) dX2 = (Scrx[i2]-(X2 = Scrx[i0]))/dY; \ + } \ + else if (stat & 2) { \ + dX2 = (Scrx[i2]-(X2 = Scrx[i1]))/dY; \ + if (stat & 4) dX1 = (Scrx[i2]-(X1 = Scrx[i0]))/dY; \ + } + + +static inline void OverlayBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int usea) +{ + int da=(256-usea)*128; + int srcr = r*usea+da, srcg = g*usea+da, srcb = b*usea+da, srca = usea*a + da; + red = ( red*( (red*(32768-srcr))/256 + srcr ) )/32768; + green = ( green*( (green*(32768-srcg))/256 + srcg ) )/32768; + blue = ( blue*( (blue*(32768-srcb))/256 + srcb ) )/32768; + alpha = ( alpha*( (alpha*(32768-srca))/256 + srca ) )/32768; +} + +static inline void MulBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta) +{ + int ta2=(256-ta)*256; + red = (r*ta*red + red*ta2)/65536; + green = (g*ta*green + green*ta2)/65536; + blue = (b*ta*blue + blue*ta2)/65536; + alpha = (a*ta*alpha + alpha*ta2)/65536; +} + + +static inline void AdjustHSV(int &red, int &green, int &blue, int r, int g, int b, int texalpha) +{ + int h,s,v; + __LICE_RGB2HSV(red,green,blue,&h,&s,&v); + h+=(((r+r/2) - 192) * texalpha)/256; + if (h<0)h+=384; + else if (h>=384) h-=384; + s+=((g-128)*texalpha)/256; + if (s&~0xff) + { + if (s<0)s=0; + else s=255; + } + v+=((b-128)*texalpha)/256; + if (v&~0xff) + { + if (v<0)v=0; + else v=255; + } + __LICE_HSV2RGB(h,s,v,&red,&green,&blue); +} + +static inline void DodgeBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta) +{ + int src_r = 256-r*ta/256; + int src_g = 256-g*ta/256; + int src_b = 256-b*ta/256; + int src_a = 256-(a*ta)/256; + + red = src_r > 1 ? 256*red / src_r : 256*red; + green = src_g > 1 ? 256*green / src_g : 256*green; + blue = src_b > 1 ? 256*blue / src_b : 256*blue; + alpha = src_a > 1 ? 256*alpha / src_a : 256*alpha; +} + + +static void inline DoTextureCombine(int texcomb, int r, int g, int b, int a, int &red, int &green, int &blue, int &alpha, int texalpha, int texalpha2) +{ + switch (texcomb) + { + case LICE_BLIT_MODE_COPY: + red = (r*texalpha + red*texalpha2)/256; + green = (g*texalpha + green*texalpha2)/256; + blue = (b*texalpha + blue*texalpha2)/256; + alpha = (a*texalpha + alpha*texalpha2)/256; + break; + case LICE_BLIT_MODE_ADD: + red += (r*texalpha)/256; + green += (g*texalpha)/256; + blue += (b*texalpha)/256; + alpha += (a*texalpha)/256; + break; + case LICE_BLIT_MODE_MUL: + MulBlend(red,green,blue,alpha,r,g,b,a,texalpha); + break; + case LICE_BLIT_MODE_DODGE: + DodgeBlend(red,green,blue,alpha,r,g,b,a,texalpha); + + break; + case LICE_BLIT_MODE_OVERLAY: + OverlayBlend(red,green,blue,alpha,r,g,b,a, texalpha); + break; + case LICE_BLIT_MODE_HSVADJ: + AdjustHSV(red,green,blue,r,g,b,texalpha); + break; + case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA: + { + int ta=(texalpha*(a+1)); + int ta2=(65536-ta); + red = (r*ta + red*ta2)/65536; + green = (g*ta + green*ta2)/65536; + blue = (b*ta + blue*ta2)/65536; + alpha = (a*ta + alpha*ta2)/65536; + } + break; + case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA: + { + int ta=(texalpha*(a+1)); + red += (r*ta)/65536; + green += (g*ta)/65536; + blue += (b*ta)/65536; + alpha += (a*ta)/65536; + } + break; + case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA: + { + int ta=(texalpha*(a+1))/256; + DodgeBlend(red,green,blue,alpha,r,g,b,a,ta); + } + break; + case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA: + MulBlend(red,green,blue,alpha,r,g,b,a,(texalpha*(a+1))/256); + break; + case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA: + OverlayBlend(red,green,blue,alpha,r,g,b,a, (texalpha*(a+1))/256); + break; + case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA: + AdjustHSV(red,green,blue,r,g,b,(texalpha*(a+1))/256); + break; + case -2: + break; + default: + red=r; green=g; blue=b; alpha=a; + break; + } +} + + +static void inline TextureMakePixelSolidCombine(int &red, int &green, int &blue, int &alpha, + pl_sInt32 *CL, int solidcomb, int solidalpha, + int solidalpha2, + LICE_pixel_chan *gmemptr) +{ + + switch (solidcomb) + { + case LICE_BLIT_MODE_COPY: + red = (CL[0]/256*solidalpha + gmemptr[LICE_PIXEL_R]*solidalpha2)/65536; + green = (CL[1]/256*solidalpha + gmemptr[LICE_PIXEL_G]*solidalpha2)/65536; + blue = (CL[2]/256*solidalpha + gmemptr[LICE_PIXEL_B]*solidalpha2)/65536; + alpha = solidalpha; + break; + case LICE_BLIT_MODE_ADD: + red = gmemptr[LICE_PIXEL_R] + (CL[0]/256*solidalpha)/65536; + green = gmemptr[LICE_PIXEL_G] + (CL[1]/256*solidalpha)/65536; + blue = gmemptr[LICE_PIXEL_B] + (CL[2]/256*solidalpha)/65536; + alpha = gmemptr[LICE_PIXEL_A] + solidalpha; + break; + case LICE_BLIT_MODE_DODGE: + red=gmemptr[LICE_PIXEL_R]; + green=gmemptr[LICE_PIXEL_G]; + blue=gmemptr[LICE_PIXEL_B]; + alpha=gmemptr[LICE_PIXEL_A]; + DodgeBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha,solidalpha); + break; + case LICE_BLIT_MODE_MUL: + red=gmemptr[LICE_PIXEL_R]; + green=gmemptr[LICE_PIXEL_G]; + blue=gmemptr[LICE_PIXEL_B]; + alpha=gmemptr[LICE_PIXEL_A]; + MulBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha,solidalpha); + break; + case LICE_BLIT_MODE_OVERLAY: + red=gmemptr[LICE_PIXEL_R]; + green=gmemptr[LICE_PIXEL_G]; + blue=gmemptr[LICE_PIXEL_B]; + alpha=gmemptr[LICE_PIXEL_A]; + OverlayBlend(red,green,blue,alpha,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha, solidalpha); + break; + case LICE_BLIT_MODE_HSVADJ: + red=gmemptr[LICE_PIXEL_R]; + green=gmemptr[LICE_PIXEL_G]; + blue=gmemptr[LICE_PIXEL_B]; + alpha=gmemptr[LICE_PIXEL_A]; + AdjustHSV(red,green,blue,CL[0]/65536,CL[1]/65536,CL[2]/65536,solidalpha); + break; + case -2: + red=gmemptr[LICE_PIXEL_R]; + green=gmemptr[LICE_PIXEL_G]; + blue=gmemptr[LICE_PIXEL_B]; + alpha=gmemptr[LICE_PIXEL_A]; + break; + default: + red=CL[0]/65536; + green=CL[1]/65536; + blue=CL[2]/65536; + alpha=solidalpha; + break; + } +} + + +static void inline TextureMakePixel2(LICE_pixel_chan *gmemptr, + int solidcomb, int solidalpha, int solidalpha2, + pl_sInt32 *CL, + bool bilinear, + pl_sInt32 iUL, pl_sInt32 iVL, + pl_sInt32 texwidth, pl_sInt32 texheight, + LICE_pixel *texture, int tex_rowspan, + int texcomb, + int texalpha, + int texalpha2, + bool bilinear2, + pl_sInt32 iUL_2, pl_sInt32 iVL_2, + pl_sInt32 texwidth_2, pl_sInt32 texheight_2, + LICE_pixel *texture2, int tex_rowspan_2, + int tex2comb, + int tex2alpha, + int tex2alpha2) +{ + + int red,green,blue,alpha; + + TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr); + + int r,g,b,a; + + int xpos=iUL>>16; + int ypos=iVL>>16; + LICE_pixel_chan *rd = (LICE_pixel_chan*)(texture + xpos+ypos*tex_rowspan); + +#if defined(PLUSH_NO_TEXTURE) + if (texture) +#endif + { + if (bilinear) + { + __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, + ypos < texheight - 1 ? (rd+tex_rowspan*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture+xpos), + xpos < texwidth - 1 ? 1 : 1-texwidth, + iUL&65535,iVL&65535); + } + else + { + r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; + } + + DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2); + } + +#ifdef PLUSH_NO_TEXTURE + if (texture2) +#endif + { + xpos=iUL_2>>16; + ypos=iVL_2>>16; + rd = (LICE_pixel_chan*)(texture2 + xpos+ypos*tex_rowspan_2); + + if (bilinear2) + { + __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, + ypos < texheight_2 - 1 ? (rd+tex_rowspan_2*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture2+xpos), + xpos < texwidth_2 - 1 ? 1 : 1-texwidth_2, + iUL_2&65535,iVL_2&65535); + } + else + { + r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; + } + + DoTextureCombine(tex2comb, r,g,b,a, red,green,blue,alpha,tex2alpha,tex2alpha2); + } + + _LICE_MakePixelClamp(gmemptr, red,green,blue,alpha); +} + +static void inline TextureMakePixel(LICE_pixel_chan *gmemptr, + int solidcomb, int solidalpha, int solidalpha2, + pl_sInt32 *CL, + bool bilinear, + pl_sInt32 iUL, pl_sInt32 iVL, + pl_sInt32 texwidth, pl_sInt32 texheight, + LICE_pixel *texture, int tex_rowspan, + int texcomb, + int texalpha, + int texalpha2) +{ + + int red,green,blue,alpha; + + if ( +#ifdef PLUSH_NO_SOLIDGOURAUD + !texture|| +#endif + texcomb!=-1) + TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr); + + + +#ifdef PLUSH_NO_SOLIDGOURAUD + if (texture) +#endif + { + int r,g,b,a; + int xpos=iUL>>16; + int ypos=iVL>>16; + LICE_pixel_chan *rd = (LICE_pixel_chan*)(texture + xpos+ypos*tex_rowspan); + + if (bilinear) + { + + __LICE_BilinearFilterI_2(&r,&g,&b,&a,rd, + ypos < texheight - 1 ? (rd+tex_rowspan*sizeof(LICE_pixel)) : (LICE_pixel_chan *)(texture+xpos), + xpos < texwidth - 1 ? 1 : 1-texwidth, + iUL&65535,iVL&65535); + } + else + { + r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A]; + } + + DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2); + } + + _LICE_MakePixelClamp(gmemptr, red,green,blue,alpha); +} + + + +#ifndef PLUSH_NO_TEXTURE +#include "pl_pf_tex.h" +#endif + +#ifndef PLUSH_NO_MULTITEXTURE +#define PL_PF_MULTITEX +#include "pl_pf_tex.h" +#endif + + + + +template class PLSolidPutFace +{ + public: +#ifndef PLUSH_NO_SOLIDGOURAUD + static void SolidGouraud(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width) + { + pl_Float dZL=0, dZ1=0, dZ2=0; + pl_sInt32 dX1=0, dX2=0, C1[3], C2[3], dC1[3]={0}, dC2[3]={0}, dCL[3]={0}, C3[3]; + + PUTFACE_SORT(); + + + int a; + for(a=0;a<3;a++) + { + C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24)); + C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24)); + C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24)); + } + pl_sInt32 X2,X1; + X2 = X1 = Scrx[i0]; + pl_Float Z1 = TriFace->Scrz[i0]; + pl_Float Z2 = TriFace->Scrz[i1]; + pl_Float Z3 = TriFace->Scrz[i2]; + + pl_sInt32 Y0 = Scry[i0]; + pl_sInt32 Y1 = Scry[i1]; + pl_sInt32 Y2 = Scry[i2]; + + { + pl_sInt32 dY = Y2 - Y0; + if (dY) { + dX2 = (Scrx[i2] - X1) / dY; + for(a=0;a<3;a++) dC2[a] = (C3[a] - C1[a]) / dY; + dZ2 = (Z3 - Z1) / dY; + } + dY = Y1 - Y0; + if (dY) { + dX1 = (Scrx[i1] - X1) / dY; + for(a=0;a<3;a++) + dC1[a] = (C2[a] - C1[a]) / dY; + dZ1 = (Z2 - Z1) / dY; + if (dX2 < dX1) { + SWAP(dX2,dX1,pl_sInt32); + for(a=0;a<3;a++) SWAP(dC1[a],dC2[a],pl_sInt32); + SWAP(dZ1,dZ2,pl_Float); + stat = 2; + } else stat = 1; + Z2 = Z1; + C2[0] = C1[0]; + C2[1] = C1[1]; + C2[2] = C1[2]; + } else { + if (Scrx[i1] > X1) { + X2 = Scrx[i1]; + stat = 2|4; + } else { + for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32); + SWAP(Z1,Z2,pl_Float); + X1 = Scrx[i1]; + stat = 1|8; + } + } + + pl_sInt32 tmp = (dX1-dX2)*dY; + if (tmp) { + double v=(1<>XPOS_BITS; + pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; + if (XL2 > 0) { + gmem += XL1; + XL1 += XL2; + pl_sInt32 CL[3] = {C1[0],C1[1],C1[2]}; + if (zbuf) + { + pl_Float ZL = Z1; + zbuf += XL1-XL2; + do { + if (*zbuf < ZL) { + *zbuf = (pl_ZBuffer) ZL; + + Comb::doPix((LICE_pixel_chan *)gmem,CL[0]/65536,CL[1]/65536,CL[2]/65536,255,alpha); + } + gmem++; + zbuf++; + ZL += dZL; + CL[0] += dCL[0]; + CL[1] += dCL[1]; + CL[2] += dCL[2]; + } while (--XL2); + zbuf -= XL1; + } + else do { + Comb::doPix((LICE_pixel_chan *)gmem,CL[0]/65536,CL[1]/65536,CL[2]/65536,255,alpha); + gmem++; + CL[0] += dCL[0]; + CL[1] += dCL[1]; + CL[2] += dCL[2]; + } while (--XL2); + gmem -= XL1; + } + gmem += swidth; + zbuf += zfb_width; + X1 += dX1; + X2 += dX2; + C1[0] += dC1[0]; + C1[1] += dC1[1]; + C1[2] += dC1[2]; + Z1 += dZ1; + Y0++; + } + } +#endif + +#ifndef PLUSH_NO_SOLIDFLAT + static void Solid(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width) + { + pl_sInt32 dX1=0, dX2=0; + pl_Float dZL=0, dZ1=0, dZ2=0; + + PUTFACE_SORT(); + + int col0 = (int) (TriFace->Shades[0][0]*255.0); + int col1 = (int) (TriFace->Shades[0][1]*255.0); + int col2 = (int) (TriFace->Shades[0][2]*255.0); + + pl_sInt32 X1,X2; + X2 = X1 = Scrx[i0]; + pl_sInt32 Y0 = Scry[i0]; + pl_sInt32 Y1 = Scry[i1]; + pl_sInt32 Y2 = Scry[i2]; + + pl_Float Z1 = TriFace->Scrz[i0]; + pl_Float Z2 = TriFace->Scrz[i1]; + pl_Float Z3 = TriFace->Scrz[i2]; + + { + pl_sInt32 dY = Y2-Y0; + if (dY) { + dX2 = (Scrx[i2] - X1) / dY; + dZ2 = (Z3 - Z1) / dY; + } + dY = Y1-Y0; + if (dY) { + dX1 = (Scrx[i1] - X1) / dY; + dZ1 = (Z2 - Z1) / dY; + if (dX2 < dX1) { + SWAP(dX1,dX2,pl_sInt32); + SWAP(dZ1,dZ2,pl_Float); + stat = 2; + } else stat = 1; + Z2 = Z1; + } else { + if (Scrx[i1] > X1) { + X2 = Scrx[i1]; + stat = 2|4; + } else { + X1 = Scrx[i1]; + SWAP(Z1,Z2,pl_Float); + stat = 1|8; + } + } + + if (zbuf) + { + pl_sInt32 tmp=(dX1-dX2)*dY; + if (tmp) dZL = ((dZ1-dZ2)*dY)*(double)(1<>XPOS_BITS; + pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1; + if (XL2 > 0) { + gmem += XL1; + XL1 += XL2; + if (zbuf) + { + pl_Float ZL = Z1; + zbuf += XL1-XL2; + do { + if (*zbuf < ZL) { + *zbuf = (pl_ZBuffer) ZL; + Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha); + } + gmem++; + zbuf++; + ZL += dZL; + } while (--XL2); + zbuf -= XL1; + } + else + { + do { + Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha); + gmem++; + } while (--XL2); + } + gmem -= XL1; + + } + gmem += swidth; + zbuf += zfb_width; + Z1 += dZ1; + X1 += dX1; + X2 += dX2; + Y0++; + } + } +#endif +}; + +void pl_Cam::PutFace(pl_Face *TriFace) +{ + LICE_pixel *gmem = frameBuffer->getBits(); + + int zfb_width = 0; + pl_ZBuffer *zb = NULL; + if (zBuffer.GetSize()&&TriFace->Material->zBufferable) + { + zfb_width = frameBuffer->getWidth(); + zb = zBuffer.Get(); + } + + int swidth = frameBuffer->getRowSpan(); + if (frameBuffer->isFlipped()) + { + gmem += swidth*(frameBuffer->getHeight()-1); + swidth=-swidth; + } + + pl_Mat *mat=TriFace->Material; + +#ifndef PLUSH_NO_MULTITEXTURE + + #ifndef PLUSH_NO_TEXTURE + if (mat->Texture&&mat->Texture2) + #else + #ifndef PLUSH_NO_SOLIDGOURAUD + if (mat->Texture||mat->Texture2) + #endif + #endif + { + pl_Float texsc[4]; + memcpy(texsc,mat->TexScaling,sizeof(mat->TexScaling)); + memcpy(texsc+2,mat->Tex2Scaling,sizeof(mat->Tex2Scaling)); + int tidx = mat->TexMapIdx; + if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; + int tidx2 = mat->Tex2MapIdx; + if (tidx2<0 || tidx2>=PLUSH_MAX_MAPCOORDS)tidx2=PLUSH_MAX_MAPCOORDS-1; + + PLMTexTri(gmem,swidth,TriFace,zb,zfb_width,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode, + mat->Texture,texsc,(int) (mat->TexOpacity*256.0),mat->TexCombineMode,tidx, + mat->Texture2,(int) (mat->Tex2Opacity*256.0),mat->Tex2CombineMode,tidx2 + ); + return; + } +#endif + + +#ifndef PLUSH_NO_TEXTURE + #ifndef PLUSH_NO_SOLIDGOURAUD + if (mat->Texture||mat->Texture2) + #endif + { + LICE_IBitmap *tex=mat->Texture ? mat->Texture : mat->Texture2; + int talpha = (int) (mat->Texture ? mat->TexOpacity*256.0 : mat->Tex2Opacity*256.0); + int tcomb = (int) (mat->Texture ? mat->TexCombineMode : mat->Tex2CombineMode); + int tidx = (mat->Texture ? mat->TexMapIdx: mat->Tex2MapIdx); + if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1; + pl_Float texsc[2]; + memcpy(texsc,mat->Texture ? mat->TexScaling : mat->Tex2Scaling,sizeof(texsc)); + PLTexTri(gmem,swidth,TriFace,zb,zfb_width,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,tex,texsc,talpha,tcomb,tidx); + return; + } +#endif + + int alpha=(int) (mat->SolidOpacity*256.0); + if (!alpha) return; +#ifndef PLUSH_NO_SOLIDGOURAUD +#ifndef PLUSH_NO_SOLIDFLAT + if (mat->Smoothing) +#endif + { + #define __LICE__ACTION(comb) PLSolidPutFace::SolidGouraud(gmem,swidth,TriFace,alpha,zb,zfb_width); + __LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true); + #undef __LICE__ACTION + return; + } +#endif + +#ifndef PLUSH_NO_SOLIDFLAT + + #define __LICE__ACTION(comb) PLSolidPutFace::Solid(gmem,swidth,TriFace,alpha,zb,zfb_width); + __LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true); + #undef __LICE__ACTION + +#endif // PLUSH_NO_SOLIDFLAT +} + + diff --git a/WDL/plush2/pl_read_3ds.cpp b/WDL/plush2/pl_read_3ds.cpp new file mode 100644 index 00000000..11086346 --- /dev/null +++ b/WDL/plush2/pl_read_3ds.cpp @@ -0,0 +1,347 @@ +/****************************************************************************** +Plush Version 1.2 +read_3ds.c +3DS Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +typedef struct +{ + pl_uInt16 id; + void (*func)(pl_uChar *ptr, pl_uInt32 p); +} _pl_3DSChunk; + +static pl_Obj *obj; +static pl_Obj *bobj; +static pl_Obj *lobj; +static pl_sInt16 currentobj; +static pl_Mat *_m; + +static pl_Float _pl3DSReadFloat(pl_uChar **ptr); +static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr); +static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr); +static void _pl3DSChunkReader(pl_uChar *ptr, int len); +static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p); +static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p); +static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as); +static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p); +static void _pl3DSTriMeshReader(pl_uChar *f, pl_uInt32 p); +static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p); +static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p); +static void _pl3DSFaceMatReader(pl_uChar *f, pl_uInt32 p); +static void MapListReader(pl_uChar *f, pl_uInt32 p); +static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id); + +static _pl_3DSChunk _pl3DSChunkNames[] = { + {0x4D4D,NULL}, /* Main */ + {0x3D3D,NULL}, /* Object Mesh */ + {0x4000,_pl3DSObjBlockReader}, + {0x4100,_pl3DSTriMeshReader}, + {0x4110,_pl3DSVertListReader}, + {0x4120,_pl3DSFaceListReader}, + {0x4130,_pl3DSFaceMatReader}, + {0x4140,MapListReader}, + {0xAFFF,NULL}, /* Material */ + {0xA010,NULL}, /* Ambient */ + {0xA020,NULL}, /* Diff */ + {0xA030,NULL}, /* Specular */ + {0xA200,NULL}, /* Texture */ + {0x0010,_pl3DSRGBFReader}, + {0x0011,_pl3DSRGBBReader}, +}; + +pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m) +{ + FILE *f = fopen(fn, "rb"); + if (!f) return 0; + fseek(f, 0, 2); + pl_uInt32 p = ftell(f); + rewind(f); + + WDL_HeapBuf buf; + buf.Resize(p); + int s = fread(buf.Get(), 1, p, f); + fclose(f); + + if(!s) return 0; + + return plRead3DSObj(buf.Get(), s, m); +} + +pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m) +{ +#ifdef _WIN32 + HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "3DS"); + if(!hResource) return NULL; + + DWORD imageSize = SizeofResource(hInst, hResource); + if(imageSize < 6) return NULL; + + HGLOBAL res = LoadResource(hInst, hResource); + const void* pResourceData = LockResource(res); + if(!pResourceData) return NULL; + + unsigned char *data = (unsigned char *)pResourceData; + + pl_Obj *o = plRead3DSObj(data, imageSize, m); + + DeleteObject(res); + + return o; +#else + return 0; +#endif +} + +pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m) +{ + _m = m; + obj = bobj = lobj = 0; + currentobj = 0; + + _pl3DSChunkReader((pl_uChar *)ptr, size); + + return bobj; +} + +static pl_Float _pl3DSReadFloat(pl_uChar **ptr) { + pl_uInt32 *i; + pl_IEEEFloat32 c; + i = (pl_uInt32 *) &c; + *i = _pl3DSReadDWord(ptr); + return ((pl_Float) c); +} + +static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr) +{ + pl_uInt32 r; + pl_uChar *p = *ptr; + r = *p++; + r |= (*p++)<<8; + r |= (*p++)<<16; + r |= (*p++)<<24; + *ptr += 4; + return r; +} + +static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr) +{ + pl_uInt16 r; + pl_uChar *p = *ptr; + r = *p++; + r |= (*p++)<<8; + *ptr += 2; + return r; +} + +static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p) +{ + pl_Float c[3]; + if(p < 3*4) return; + c[0] = _pl3DSReadFloat(&f); + c[1] = _pl3DSReadFloat(&f); + c[2] = _pl3DSReadFloat(&f); +} + +static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p) +{ + unsigned char c[3]; + if(p < 3) return; + memcpy(c, f, sizeof(c)); +} + +static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as) +{ + int l = 0; + while (*ptr && p>0) + { + if(as) *as++ = *ptr; + ptr++; + l++; + p--; + } + if(as) *as = 0; + return l+1; +} + +static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p) +{ + int l = _pl3DSASCIIZReader(ptr, p, 0); + ptr += l; + p -= l; + _pl3DSChunkReader(ptr, p); +} + +static void _pl3DSTriMeshReader(pl_uChar *ptr, pl_uInt32 p) +{ + pl_uInt32 i; + pl_Face *face; + obj = new pl_Obj; + _pl3DSChunkReader(ptr, p); + i = obj->Faces.GetSize(); + face = obj->Faces.Get(); + while (i--) + { + pl_Vertex *vp=obj->Vertices.Get(); + pl_Vertex *fVertices[3] = { + vp+face->VertexIndices[0], + vp+face->VertexIndices[1], + vp+face->VertexIndices[2], + }; + face->MappingU[0][0] = fVertices[0]->xformedx; + face->MappingV[0][0] = fVertices[0]->xformedy; + face->MappingU[0][1] = fVertices[1]->xformedx; + face->MappingV[0][1] = fVertices[1]->xformedy; + face->MappingU[0][2] = fVertices[2]->xformedx; + face->MappingV[0][2] = fVertices[2]->xformedy; + face++; + } + obj->CalculateNormals(); + if (currentobj == 0) + { + currentobj = 1; + lobj = bobj = obj; + } + else + { + lobj->Children.Add(obj); + lobj = obj; + } +} + +static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p) +{ + pl_uInt16 nv; + pl_Vertex *v; + int len = (int)p; + nv = _pl3DSReadWord(&f); + len -= 2; + if(len <= 0) return; + obj->Vertices.Resize(nv); + v = obj->Vertices.Get(); + while (nv--) + { + memset(v,0,sizeof(pl_Vertex)); + v->x = _pl3DSReadFloat(&f); + v->y = _pl3DSReadFloat(&f); + v->z = _pl3DSReadFloat(&f); + len -= 3*4; + if(len < 0) return; + v++; + } +} + +static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p) +{ + pl_uInt16 nv; + pl_uInt16 c[3]; + pl_uInt16 flags; + pl_Face *face; + int len = (int)p; + + nv = _pl3DSReadWord(&f); + len -= 2; + if(len <= 0) return; + obj->Faces.Resize(nv); + face = obj->Faces.Get(); + while (nv--) + { + memset(face,0,sizeof(pl_Face)); + c[0] = _pl3DSReadWord(&f); + c[1] = _pl3DSReadWord(&f); + c[2] = _pl3DSReadWord(&f); + flags = _pl3DSReadWord(&f); + len -= 4*2; + if(len < 0) return; + + face->VertexIndices[0] = (c[0]&0x0000FFFF); + face->VertexIndices[1] = (c[1]&0x0000FFFF); + face->VertexIndices[2] = (c[2]&0x0000FFFF); + face->Material = _m; + face++; + } + if(len) _pl3DSChunkReader(f, len); +} + +static void _pl3DSFaceMatReader(pl_uChar *ptr, pl_uInt32 p) +{ + pl_uInt16 n, nf; + + int l = _pl3DSASCIIZReader(ptr, p, 0); + ptr += l; + p -= l; + + n = _pl3DSReadWord(&ptr); + while (n--) + { + nf = _pl3DSReadWord(&ptr); + } +} + +static void MapListReader(pl_uChar *f, pl_uInt32 p) +{ + pl_uInt16 nv; + pl_Float c[2]; + pl_Vertex *v; + int len = (int) p; + nv = _pl3DSReadWord(&f); + len -= 2; + v = obj->Vertices.Get(); + if (nv == obj->Vertices.GetSize()) while (nv--) + { + c[0] = _pl3DSReadFloat(&f); + c[1] = _pl3DSReadFloat(&f); + len -= 2*4; + if (len < 0) return; + v->xformedx = c[0]; + v->xformedy = c[1]; + v++; + } +} + +static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id) +{ + pl_sInt16 i; + for (i = 0; i < sizeof(_pl3DSChunkNames)/sizeof(_pl3DSChunkNames[0]); i++) + if (id == _pl3DSChunkNames[i].id) return i; + return -1; +} + +static void _pl3DSChunkReader(pl_uChar *ptr, int len) +{ + pl_uInt32 hlen; + pl_uInt16 hid; + pl_sInt16 n; + + while (len > 0) + { + hid = _pl3DSReadWord(&ptr); + len -= 2; + if(len <= 0) return; + hlen = _pl3DSReadDWord(&ptr); + len -= 4; + if(len <= 0) return; + if (hlen == 0) return; + hlen -= 6; + n = _pl3DSFindChunk(hid); + if (n < 0) + { + ptr += hlen; + len -= hlen; + } + else + { + pl_uChar *p = ptr; + if (_pl3DSChunkNames[n].func != NULL) + _pl3DSChunkNames[n].func(p, hlen); + else + _pl3DSChunkReader(p, hlen); + + ptr += hlen; + len -= hlen; + } + } +} + diff --git a/WDL/plush2/pl_read_cob.cpp b/WDL/plush2/pl_read_cob.cpp new file mode 100644 index 00000000..1ed8187c --- /dev/null +++ b/WDL/plush2/pl_read_cob.cpp @@ -0,0 +1,181 @@ +/****************************************************************************** +Plush Version 1.2 +read_cob.c +ASCII COB Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +#define PL_COB_MAX_LINELENGTH 1024 + +pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat) { + FILE *fp = fopen(fn,"rt"); + int p1,m1,p2,m2,p3,m3; + char temp_string[PL_COB_MAX_LINELENGTH]; + float TransMatrix[4][4]; + pl_Obj *obj; + pl_sInt32 x,i2; + int numVertices, numMappingVertices, numFaces, i; + pl_Float *MappingVertices = 0; + if (!fp) return 0; + + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (memcmp("Caligari",temp_string,8)) { fclose(fp); return 0; } + + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Transform",temp_string,9)); + if (feof(fp)) { fclose(fp); return 0; } + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[0][0],&TransMatrix[0][1],&TransMatrix[0][2],&TransMatrix[0][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[1][0],&TransMatrix[1][1],&TransMatrix[1][2],&TransMatrix[1][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[2][0],&TransMatrix[2][1],&TransMatrix[2][2],&TransMatrix[2][3]); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string,"%f %f %f %f", + &TransMatrix[3][0],&TransMatrix[3][1],&TransMatrix[3][2],&TransMatrix[3][3]); + + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); + if (feof(fp) || sscanf(temp_string,"World Vertices %d",&numVertices) != 1) + { fclose(fp); return 0; } + + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); + if (feof(fp) || + sscanf(temp_string,"Texture Vertices %d",&numMappingVertices) != 1) { + fclose(fp); return 0; + } + + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Faces",temp_string,5)); + if (feof(fp) || sscanf(temp_string,"Faces %d",&numFaces) != 1) { + fclose(fp); return 0; + } + for (x = numFaces; x; x--) { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || sscanf(temp_string+4," verts %d",&i) != 1 || i < 3) { + fclose(fp); + return 0; + } + numFaces += i-3; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } + obj = new pl_Obj(numVertices,numFaces); + if (!obj) { fclose(fp); return 0; } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("World Vertices",temp_string,12)); + if (feof(fp)) { delete obj; fclose(fp); return 0; } + for (x = 0; x < numVertices; x ++) { + float xp, yp, zp; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || + sscanf(temp_string,"%f %f %f", &xp, &yp, &zp) != 3) { + delete obj; fclose(fp); return 0; + } + obj->Vertices.Get()[x].x = (TransMatrix[0][0]*xp+TransMatrix[0][1]*yp+ + TransMatrix[0][2]*zp+TransMatrix[0][3]); + obj->Vertices.Get()[x].y = (TransMatrix[1][0]*xp+TransMatrix[1][1]*yp+ + TransMatrix[1][2]*zp+TransMatrix[1][3]); + obj->Vertices.Get()[x].z = (TransMatrix[2][0]*xp+TransMatrix[2][1]*yp+ + TransMatrix[2][2]*zp+TransMatrix[2][3]); + } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Texture Vertices",temp_string,16)); + if (!feof(fp)) { + MappingVertices = (pl_Float *) + malloc(sizeof(pl_Float ) * numMappingVertices * 2); + if (MappingVertices) { + for (x = 0; x < numMappingVertices; x ++) { + float p1, p2; + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (feof(fp) || sscanf(temp_string,"%f %f", &p1, &p2) != 2) { + free(MappingVertices); delete obj; fclose(fp); return 0; + } + MappingVertices[x*2] = p1; + MappingVertices[x*2+1] = p2; + } + } + } + rewind(fp); + do { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + } while (!feof(fp) && memcmp("Faces",temp_string,5)); + if (feof(fp)) { + if (MappingVertices) free(MappingVertices); + delete obj; fclose(fp); return 0; + } + for (x = 0; x < numFaces; x ++) { + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + sscanf(temp_string+4," verts %d",&i); + fgets(temp_string,PL_COB_MAX_LINELENGTH,fp); + if (i == 3) { + if (feof(fp) || sscanf(temp_string,"<%d,%d> <%d,%d> <%d,%d>", + &p3,&m3,&p2,&m2,&p1,&m1) != 6) { + if (MappingVertices) free(MappingVertices); + delete obj; fclose(fp); return 0; + } + obj->Faces.Get()[x].VertexIndices[0] = p1; + obj->Faces.Get()[x].VertexIndices[1] = p2; + obj->Faces.Get()[x].VertexIndices[2] = p3; + if (MappingVertices) { + obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m1*2]; + obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m1*2+1]; + obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m2*2]; + obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m2*2+1]; + obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m3*2]; + obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m3*2+1]; + } + obj->Faces.Get()[x].Material = mat; + } else { + int p[16],m[16]; + if (feof(fp)) { + if (MappingVertices) free(MappingVertices); + delete obj; fclose(fp); return 0; + } + sscanf(temp_string, + "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " + "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " + "<%d,%d> <%d,%d> <%d,%d> <%d,%d> " + "<%d,%d> <%d,%d> <%d,%d> <%d,%d> ", + p+0,m+0,p+1,m+1,p+2,m+2,p+3,m+3, + p+4,m+4,p+5,m+5,p+6,m+6,p+7,m+7, + p+8,m+8,p+9,m+9,p+10,m+10,p+11,m+11, + p+12,m+12,p+13,m+13,p+14,m+14,p+15,m+15); + for (i2 = 1; i2 < (i-1); i2 ++) { + obj->Faces.Get()[x].VertexIndices[0] = p[0]; + obj->Faces.Get()[x].VertexIndices[1] = p[i2+1]; + obj->Faces.Get()[x].VertexIndices[2] = p[i2]; + if (MappingVertices) { + obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m[0]*2]; + obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m[0]*2+1]; + obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m[i2+1]*2]; + obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m[i2+1]*2+1]; + obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m[i2]*2]; + obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m[i2]*2+1]; + } + obj->Faces.Get()[x].Material = mat; + x++; + } + x--; + } + } + if (MappingVertices) free(MappingVertices); + obj->CalculateNormals(); + fclose(fp); + return obj; +} diff --git a/WDL/plush2/pl_read_jaw.cpp b/WDL/plush2/pl_read_jaw.cpp new file mode 100644 index 00000000..942e5e0c --- /dev/null +++ b/WDL/plush2/pl_read_jaw.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** +Plush Version 1.2 +read_jaw.c +Jaw3D Object Reader +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************* + Notes on .JAW files: + This is a file format created by Jawed Karim for Jaw3D + (http://jaw3d.home.ml.org). + -- updated 11/6/00 - www.jawed.com + It is very simple, and lets one easily create ones own models using only + a text editor. The format is pretty simple: + The first line must be "Light: (x,y,z)" where x,y, and z are the x y and + z components of the lightsource vector (I think ;) + A series of lines, numbered 0 to n, in the format of + "i: x y z", where i is the vertex number (which should be listed in + order, and x y and z are the coordinates of that vertex. + A series of lines, having the format "tri a, b, c" where a b and c are + the vertices that the face uses. It is unclear at this time which + way the vertices are listed (ccw or cw), so just make em consistent + and you can always use plFlipObjectNormals() on the loaded object. + That is it! (I told ya it was simple). +******************************************************************************/ + +#include "plush.h" + +pl_Obj *plReadJAWObj(char *filename, pl_Mat *m) { + FILE *jawfile; + pl_Obj *obj; + pl_uInt32 i; + pl_sInt crap; + char line[256]; + pl_uInt32 total_points = 0, total_polys = 0; + if ((jawfile = fopen(filename, "r")) == NULL) return 0; + fgets(line, 256, jawfile); /* Ignores lightsource info */ + while (fgets(line, 256, jawfile) != NULL) + if (strstr(line, ":") != NULL) total_points++; + + rewind(jawfile); fgets(line, 256, jawfile); + while (fgets(line, 256, jawfile) != NULL) + if (strstr(line, "tri") != NULL) total_polys++; + + rewind(jawfile); fgets(line, 256, jawfile); + obj = new pl_Obj(total_points,total_polys); + + i = 0; + while (fgets(line, 256, jawfile) != NULL) if (strstr(line, ":") != NULL) { + float x, y, z; + sscanf(line, "%d: %f %f %f",&crap,&x,&y,&z); + obj->Vertices.Get()[i].x = (pl_Float) x; + obj->Vertices.Get()[i].y = (pl_Float) y; + obj->Vertices.Get()[i].z = (pl_Float) z; + i++; + } + rewind(jawfile); fgets(line, 256, jawfile); + i = 0; + while (fgets(line, 256, jawfile) != NULL) if (strstr(line, "tri") != NULL) { + pl_uInt32 a,b,c; + sscanf(line, "tri %ld, %ld, %ld", &a, &b, &c); + obj->Faces.Get()[i].VertexIndices[0] = a; + obj->Faces.Get()[i].VertexIndices[1] = c; + obj->Faces.Get()[i].VertexIndices[2] = b; + obj->Faces.Get()[i].Material = m; + i++; + } + fclose(jawfile); + obj->CalculateNormals(); + return obj; +} diff --git a/WDL/plush2/pl_spline.cpp b/WDL/plush2/pl_spline.cpp new file mode 100644 index 00000000..a4755eba --- /dev/null +++ b/WDL/plush2/pl_spline.cpp @@ -0,0 +1,50 @@ +/****************************************************************************** +Plush Version 1.2 +spline.c +n-th Dimensional Spline Interpolator +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +void pl_Spline::GetPoint(pl_Float frame, pl_Float *out) { + pl_sInt32 i, i_1, i0, i1, i2; + pl_Float time1,time2,time3; + pl_Float t1,t2,t3,t4,u1,u2,u3,u4,v1,v2,v3; + pl_Float a,b,c,d; + + int numKeys=keys.GetSize(); + pl_Float *keyptrs = keys.Get(); + + a = (1-tens)*(1+cont)*(1+bias); + b = (1-tens)*(1-cont)*(1-bias); + c = (1-tens)*(1-cont)*(1+bias); + d = (1-tens)*(1+cont)*(1-bias); + v1 = t1 = -a / 2.0; u1 = a; + u2 = (-6-2*a+2*b+c)/2.0; v2 = (a-b)/2.0; t2 = (4+a-b-c) / 2.0; + t3 = (-4+b+c-d) / 2.0; + u3 = (6-2*b-c+d)/2.0; + v3 = b/2.0; + t4 = d/2.0; u4 = -t4; + + i0 = (pl_uInt) frame; + i_1 = i0 - 1; + while (i_1 < 0) i_1 += numKeys; + i1 = i0 + 1; + while (i1 >= numKeys) i1 -= numKeys; + i2 = i0 + 2; + while (i2 >= numKeys) i2 -= numKeys; + time1 = frame - (pl_Float) ((pl_uInt) frame); + time2 = time1*time1; + time3 = time2*time1; + i0 *= keyWidth; + i1 *= keyWidth; + i2 *= keyWidth; + i_1 *= keyWidth; + for (i = 0; i < keyWidth; i ++) { + a = t1*keyptrs[i+i_1]+t2*keyptrs[i+i0]+t3*keyptrs[i+i1]+t4*keyptrs[i+i2]; + b = u1*keyptrs[i+i_1]+u2*keyptrs[i+i0]+u3*keyptrs[i+i1]+u4*keyptrs[i+i2]; + c = v1*keyptrs[i+i_1]+v2*keyptrs[i+i0]+v3*keyptrs[i+i1]; + *out++ = a*time3 + b*time2 + c*time1 + keyptrs[i+i0]; + } +} diff --git a/WDL/plush2/plush.h b/WDL/plush2/plush.h new file mode 100644 index 00000000..ac0ed30a --- /dev/null +++ b/WDL/plush2/plush.h @@ -0,0 +1,598 @@ +/****************************************************************************** + plush.h + PLUSH 3D VERSION 2.0 MAIN HEADER + Copyright (c) 1996-2000 Justin Frankel + Copyright (c) 1998-2000 Nullsoft, Inc. + Copyright (c) 2008 Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +******************************************************************************/ + +#ifndef _PLUSH_H_ +#define _PLUSH_H_ + +#include +#include +#include +#include + +#include "../lice/lice.h" // using LICE for images +#include "../ptrlist.h" +#include "../wdltypes.h" + +typedef float pl_ZBuffer; /* z-buffer type (must be float) */ +typedef double pl_Float; /* General floating point */ +typedef float pl_IEEEFloat32; /* IEEE 32 bit floating point */ +typedef signed int pl_sInt32; /* signed 32 bit integer */ +typedef unsigned int pl_uInt32; /* unsigned 32 bit integer */ +typedef signed short int pl_sInt16; /* signed 16 bit integer */ +typedef unsigned short int pl_uInt16; /* unsigned 16 bit integer */ +typedef signed int pl_sInt; /* signed optimal integer */ +typedef unsigned int pl_uInt; /* unsigned optimal integer */ +typedef bool pl_Bool; /* boolean */ +typedef unsigned char pl_uChar; /* unsigned 8 bit integer */ +typedef signed char pl_sChar; /* signed 8 bit integer */ + + + +/* pi! */ +#define PL_PI 3.141592653589793238 + +/* Utility min() and max() functions */ +#define plMin(x,y) (( ( x ) > ( y ) ? ( y ) : ( x ))) +#define plMax(x,y) (( ( x ) < ( y ) ? ( y ) : ( x ))) + + + +/* +** Light modes. Used with plLight.Type or plLightSet(). +** Note that PL_LIGHT_POINT_ANGLE assumes no falloff and uses the angle between +** the light and the point, PL_LIGHT_POINT_DISTANCE has falloff with proportion +** to distance**2 (see plLightSet() for setting it), PL_LIGHT_POINT does both. +*/ +#define PL_LIGHT_NONE (0x0) +#define PL_LIGHT_VECTOR (0x1) +#define PL_LIGHT_POINT (0x2|0x4) +#define PL_LIGHT_POINT_DISTANCE (0x2) +#define PL_LIGHT_POINT_ANGLE (0x4) + + +#define PLUSH_MAX_MAPCOORDS 3 // 2 + envmap slot + + +class pl_Mat +{ +public: + pl_Mat() + { + memset(Ambient,0,sizeof(Ambient)); + Diffuse[0]=Diffuse[1]=Diffuse[2]=1.0; + SolidOpacity=1.0; + SolidCombineMode= LICE_BLIT_MODE_COPY; + + Texture=NULL; + TexCombineMode = LICE_BLIT_MODE_ADD; //LICE_BLIT_USE_SOURCE_ALPHA? + TexOpacity=1.0; + TexScaling[0]=TexScaling[1]=1.0; + TexMapIdx=0; + + Texture2=NULL; + Tex2CombineMode = LICE_BLIT_MODE_ADD; + Tex2Opacity=1.0; + Tex2Scaling[0]=Tex2Scaling[1]=1.0; + Tex2MapIdx=-1; + + FadeDist=0.0; + Smoothing=Lightable=true; + zBufferable=true; + PerspectiveCorrect=16; + BackfaceCull=true; + BackfaceIllumination=0.0; + + cachedTexture=cachedTexture2=0; + cachesInvalid=true; + } + + ~pl_Mat() + { + delete cachedTexture; + delete cachedTexture2; + } + + + pl_Bool Smoothing; // smoothing of lighting + pl_Bool Lightable; // affected by lights + pl_Bool zBufferable; /* Can this material be zbuffered? */ + pl_uChar PerspectiveCorrect; /* Correct texture perspective every n pixels */ + + pl_Float FadeDist WDL_FIXALIGN; /* For distance fading, distance at which intensity is 0. set to 0.0 for no distance shading */ + + pl_Bool BackfaceCull; /* Are backfacing polys drawn? */ + pl_Float BackfaceIllumination WDL_FIXALIGN; /* Illuminated by lights behind them, and by how much of a factor? */ + + // colors + pl_Float Ambient[3]; /* RGB of surface (0-1 is a good range) */ + pl_Float Diffuse[3]; /* RGB of diffuse (0-1 is a good range) */ + pl_Float SolidOpacity; + int SolidCombineMode; /* LICE combine mode for first pass (color), default should be replace (or add-black for transparent) */ + + // textures + LICE_IBitmap *Texture; /* Texture map (not owned by Material but a reference)*/ + pl_Float TexScaling[2] WDL_FIXALIGN; /* Texture map scaling */ + pl_Float TexOpacity; + int TexCombineMode; /* Texture combine mode (generally should be additive) */ + int TexMapIdx; // -1 for env + + LICE_IBitmap *Texture2; + pl_Float Tex2Scaling[2] WDL_FIXALIGN; + pl_Float Tex2Opacity; + int Tex2CombineMode; + int Tex2MapIdx; // -1 for env + + + void InvalidateTextureCaches() { cachesInvalid=true; } // call this if you change Texture or Texture2 after rendering + +private: + bool cachesInvalid; + LICE_IBitmap *cachedTexture,*cachedTexture2; // these may need to be LICE_GL_MemBitmaps etc + +} WDL_FIXALIGN; + + +class pl_Vertex { +public: + pl_Vertex() { } + ~pl_Vertex () { } + + pl_Float x, y, z; /* Vertex coordinate (objectspace) */ + pl_Float nx, ny, nz; /* Unit vertex normal (objectspace) */ + + pl_Float xformedx, xformedy, xformedz; /* Transformed vertex coordinate (cameraspace) */ + pl_Float xformednx, xformedny, xformednz; /* Transformed unit vertex normal (cameraspace) */ +}; + +class pl_Face { +public: + pl_Face() + { + } + ~pl_Face() + { + } + + pl_Mat *Material; /* Material of triangle */ + int VertexIndices[3]; /* Vertices of triangle */ + + pl_Float nx WDL_FIXALIGN; + pl_Float ny; + pl_Float nz; /* Normal of triangle (object space) */ + + pl_Float MappingU[PLUSH_MAX_MAPCOORDS][3], MappingV[PLUSH_MAX_MAPCOORDS][3]; /* Texture mapping coordinates */ + + pl_Float sLighting[3]; /* Face static lighting. Should usually be 0.0 */ + pl_Float vsLighting[3][3]; /* Vertex static lighting. Should usually be 0.0 */ + + + // calculated: + pl_Float Shades[3][3]; /* colors (first 3 used for flat, all for Gouraud) */ + pl_Float Scrx[3], Scry[3]; /* Projected screen coordinates */ + pl_Float Scrz[3]; /* Projected 1/Z coordinates */ + +}; + + +class pl_Obj { +public: + pl_Obj(int nv=0, int nf=0) + { + if (nv) memset(Vertices.Resize(nv),0,nv*sizeof(pl_Vertex)); + if (nf) memset(Faces.Resize(nf),0,nf*sizeof(pl_Face)); + + GenMatrix=true; + Xp=Yp=Zp=Xa=Ya=Za=0.0; + } + ~pl_Obj() { Children.Empty(true); } + + pl_Obj *Clone(); + void Scale(pl_Float sc); + void Stretch(pl_Float x, pl_Float y, pl_Float z); // scales but preserves normals + void Translate(pl_Float x, pl_Float y, pl_Float z); + void FlipNormals(); + + void SetMaterial(pl_Mat *m, pl_Bool recurse=true); + void CalculateNormals(); + + + WDL_TypedBuf Vertices; + WDL_TypedBuf Faces; + WDL_PtrList Children; + /* Children */ + pl_Bool GenMatrix; /* Generate Matrix from the following + if set */ + pl_Float Xp WDL_FIXALIGN; + pl_Float Yp, Zp, Xa, Ya, Za; /* Position and rotation of object: + Note: rotations are around + X then Y then Z. Measured in degrees */ + pl_Float Matrix[16]; /* Transformation matrix */ + pl_Float RotMatrix[16]; /* Rotation only matrix (for normals) */ +}; + + +class pl_Spline { +public: + pl_Spline() { cont=1.0; bias=0.3; tens=0.3; keyWidth=1; } + ~pl_Spline () { } + void GetPoint(pl_Float frame, pl_Float *out); + WDL_TypedBuf keys; /* Key data, keyWidth*numKeys */ + pl_sInt keyWidth; /* Number of floats per key */ + + pl_Float cont WDL_FIXALIGN; /* Continuity. Should be -1.0 -> 1.0 */ + pl_Float bias; /* Bias. -1.0 -> 1.0 */ + pl_Float tens; /* Tension. -1.0 -> 1.0 */ +}; + + +class pl_Light { +public: + pl_Light() { Type = PL_LIGHT_VECTOR; Xp=Yp=0.0; Zp=1.0; Intensity[0]=Intensity[1]=Intensity[2]=1.0; } + ~pl_Light() { } + +/* + Set() sets up a light: + mode: the mode of the light (PL_LIGHT_*) + x,y,z: either the position of the light (PL_LIGHT_POINT*) or the angle + in degrees of the light (PL_LIGHT_VECTOR) + intensity: the intensity of the light (0.0-1.0) + halfDist: the distance at which PL_LIGHT_POINT_DISTANCE is 1/2 intensity +*/ + void Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist); + + + // privatestuff + pl_uChar Type; /* Type of light: PL_LIGHT_* */ + pl_Float Xp WDL_FIXALIGN; + pl_Float Yp, Zp; /* If Type=PL_LIGHT_POINT*, + this is Position (PL_LIGHT_POINT_*), + otherwise if PL_LIGHT_VECTOR, + Unit vector */ + pl_Float Intensity[3]; /* Intensity. 0.0 is off, 1.0 is full */ + pl_Float HalfDistSquared; /* Distance squared at which + PL_LIGHT_POINT_DISTANCE is 50% */ +}; + + +class pl_Cam { +public: + pl_Cam() + { + frameBuffer=0; + Fov=90.0; + AspectRatio=1.0; + Sort=1; + ClipBack=-1.0; + CenterX=CenterY=0; + X=Y=Z=0.0; + WantZBuffer=false; + Pitch=Pan=Roll=0.0; + } + ~pl_Cam() + { + } + + + void SetTarget(pl_Float x, pl_Float y, pl_Float z); + + + pl_Float Fov; /* FOV in degrees valid range is 1-179 */ + pl_Float AspectRatio; /* Aspect ratio (usually 1.0) */ + pl_sChar Sort; /* Sort polygons, -1 f-t-b, 1 b-t-f, 0 no */ + pl_Float ClipBack WDL_FIXALIGN; /* Far clipping ( < 0.0 is none) */ + pl_sInt CenterX, CenterY; /* Offset center of screen from actual center by this much... */ + pl_Float X WDL_FIXALIGN; + pl_Float Y, Z; /* Camera position in worldspace */ + + pl_Float Pitch, Pan, Roll; /* Camera angle in degrees in worldspace */ + + bool WantZBuffer; + + void Begin(LICE_IBitmap *fb, bool want_zbclear=true, pl_ZBuffer zbclear=0.0); + void RenderLight(pl_Light *light); + void RenderObject(pl_Obj *obj, pl_Float *bmatrix=NULL, pl_Float *bnmatrix=NULL); + void SortToCurrent(); // sorts all faces added since Begin() or last SortToCurrent() call. useful for if you use zbuffering with transparent objects (draw them last) + + LICE_IBitmap *GetFrameBuffer() { return frameBuffer; } + WDL_TypedBuf zBuffer; /* Z Buffer (validate size before using)*/ + + void End(); + + int RenderTrisIn; + int RenderTrisCulled; + int RenderTrisOut; + + double RenderPixelsOut WDL_FIXALIGN; + + void PutFace(pl_Face *TriFace); + +private: + LICE_IBitmap *frameBuffer; /* Framebuffer - note this is owned by the camera if you set it */ + + // internal use + void ClipRenderFace(pl_Face *face, pl_Obj *obj); + int ClipNeeded(pl_Face *face, pl_Obj *obj); // 0=no draw, 1=drawing (possibly splitting) necessary + void RecalcFrustum(); + + + #define PL_NUM_CLIP_PLANES 5 + + struct _clipInfo + { + pl_Vertex newVertices[8]; + pl_Float ShadeInfos[8][3]; + pl_Float MappingU[PLUSH_MAX_MAPCOORDS][8]; + pl_Float MappingV[PLUSH_MAX_MAPCOORDS][8]; + }; + + _clipInfo m_cl[2] WDL_FIXALIGN; + pl_Float m_clipPlanes[PL_NUM_CLIP_PLANES][4]; + pl_Float m_fovfactor, m_adj_asp; // recalculated + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ + pl_uInt _ClipToPlane(pl_uInt numVerts, pl_Float *plane); + + + struct _faceInfo { + pl_Float zd; + pl_Face *face; + pl_Obj *obj; + } WDL_FIXALIGN; + + struct _lightInfo { + pl_Float l[3]; + pl_Light *light; + } WDL_FIXALIGN; + + static int sortRevFunc(const void *a, const void *b); + static int sortFwdFunc(const void *a, const void *b); + + int _numfaces,_numfaces_sorted; + WDL_TypedBuf<_faceInfo> _faces; + + pl_Float _cMatrix[16] WDL_FIXALIGN; + + int _numlights; + WDL_TypedBuf<_lightInfo> _lights; + + void _RenderObj(pl_Obj *, pl_Float *, pl_Float *); + + WDL_HeapBuf _sort_tmpspace; + +}; + + + + +/****************************************************************************** +** Object Primitives Code (pl_make.cpp) +******************************************************************************/ + +/* + plMakePlane() makes a plane centered at the origin facing up the y axis. + Parameters: + w: width of the plane (along the x axis) + d: depth of the plane (along the z axis) + res: resolution of plane, i.e. subdivisions + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m); + +/* + plMakeBox() makes a box centered at the origin + Parameters: + w: width of the box (x axis) + d: depth of the box (z axis) + h: height of the box (y axis) + Returns: + pointer to object created. +*/ +pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m); + +/* + plMakeCone() makes a cone centered at the origin + Parameters: + r: radius of the cone (x-z axis) + h: height of the cone (y axis) + div: division of cone (>=3) + cap: close the big end? + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, pl_Bool cap, pl_Mat *m); + +/* + plMakeCylinder() makes a cylinder centered at the origin + Parameters: + r: radius of the cylinder (x-z axis) + h: height of the cylinder (y axis) + divr: division of of cylinder (around the circle) (>=3) + captop: close the top + capbottom: close the bottom + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop, + pl_Bool capbottom, pl_Mat *m); + +/* + plMakeSphere() makes a sphere centered at the origin. + Parameters: + r: radius of the sphere + divr: division of the sphere (around the y axis) (>=3) + divh: division of the sphere (around the x,z axis) (>=3) + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m); + +/* + plMakeTorus() makes a torus centered at the origin + Parameters: + r1: inner radius of the torus + r2: outer radius of the torus + divrot: division of the torus (around the y axis) (>=3) + divrad: division of the radius of the torus (x>=3) + m: material to use + Returns: + pointer to object created. +*/ +pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, + pl_uInt divrad, pl_Mat *m); + + +/****************************************************************************** +** File Readers (pl_read_*.cpp) +******************************************************************************/ + +/* + plRead3DSObj() reads a 3DS object + Parameters: + fn: filename of object to read + m: material to assign it + Returns: + pointer to object + Notes: + This reader organizes multiple objects like so: + 1) the first object is returned + 2) the second object is the first's first child + 3) the third object is the second's first child + 4) etc +*/ +pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m); +pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m); +pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m); + +/* + plReadCOBObj() reads an ascii .COB object + Parameters: + fn: filename of object to read + mat: material to assign it + Returns: + pointer to object + Notes: + This is Caligari's ASCII object format. + This reader doesn't handle multiple objects. It just reads the first one. + Polygons with lots of sides are not always tesselated correctly. Just + use the "Tesselate" button from within truespace to improve the results. +*/ +pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat); + +/* + plReadJAWObj() reads a .JAW object. + Parameters: + fn: filename of object to read + m: material to assign it + Returns: + pointer to object + Notes: + For information on the .JAW format, please see the jaw3D homepage, + http://www.tc.umn.edu/nlhome/g346/kari0022/jaw3d/ +*/ +pl_Obj *plReadJAWObj(char *fn, pl_Mat *m); + + + +/****************************************************************************** +** Math Code (pl_math.cpp) +******************************************************************************/ + +/* + plMatrixRotate() generates a rotation matrix + Parameters: + matrix: an array of 16 pl_Floats that is a 4x4 matrix + m: the axis to rotate around, 1=X, 2=Y, 3=Z. + Deg: the angle in degrees to rotate + Returns: + nothing +*/ +void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg); + +/* + plMatrixTranslate() generates a translation matrix + Parameters: + m: the matrix (see plMatrixRotate for more info) + x,y,z: the translation coordinates + Returns: + nothing +*/ +void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z); + +/* + plMatrixMultiply() multiplies two matrices + Parameters: + dest: destination matrix will be multipled by src + src: source matrix + Returns: + nothing + Notes: + this is the same as dest = dest*src (since the order *does* matter); +*/ +void plMatrixMultiply(pl_Float *dest, pl_Float src[]); + +/* + plMatrixApply() applies a matrix. + Parameters: + m: matrix to apply + x,y,z: input coordinate + outx,outy,outz: pointers to output coords. + Returns: + nothing + Notes: + applies the matrix to the 3d point to produce the transformed 3d point +*/ +void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z, + pl_Float *outx, pl_Float *outy, pl_Float *outz); + +/* + plNormalizeVector() makes a vector a unit vector + Parameters: + x,y,z: pointers to the vector + Returns: + nothing +*/ +void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z); + +/* + plDotProduct() returns the dot product of two vectors + Parameters: + x1,y1,z1: the first vector + x2,y2,z2: the second vector + Returns: + the dot product of the two vectors +*/ +pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1, + pl_Float x2, pl_Float y2, pl_Float z2); + + + + +#endif /* !_PLUSH_H_ */ diff --git a/WDL/plush2/plush2.dsp b/WDL/plush2/plush2.dsp new file mode 100644 index 00000000..215aa143 --- /dev/null +++ b/WDL/plush2/plush2.dsp @@ -0,0 +1,217 @@ +# Microsoft Developer Studio Project File - Name="plush2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=plush2 - 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 "plush2.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 "plush2.mak" CFG="plush2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "plush2 - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "plush2 - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +RSC=rc.exe + +!IF "$(CFG)" == "plush2 - 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 "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /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=xilink6.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "plush2 - 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 "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /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=xilink6.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "plush2 - Win32 Release" +# Name "plush2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=pl_cam.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_make.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_math.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_obj.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_putface.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_read_3ds.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_read_cob.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_read_jaw.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=pl_spline.cpp + +!IF "$(CFG)" == "plush2 - Win32 Release" + +# ADD CPP /D "USE_ICC" + +!ELSEIF "$(CFG)" == "plush2 - Win32 Debug" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=pl_pf_tex.h +# End Source File +# Begin Source File + +SOURCE=plush.h +# End Source File +# End Group +# End Target +# End Project diff --git a/WDL/poollist.h b/WDL/poollist.h new file mode 100644 index 00000000..4ad8129b --- /dev/null +++ b/WDL/poollist.h @@ -0,0 +1,155 @@ +/* + WDL - poollist.h + Copyright (C) 2006 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + + This file defines a template class for hosting lists of referenced count, string-identified objects. + + We mostly use it with WDL_ResourcePool, but any class like this can use it: + + + class SomeClass + { + public: + SomeClass(char *identstr) { WDL_POOLLIST_identstr=identstr; WDL_POOLLIST_refcnt=0; } + ~SomeClass() {} // do NOT free or delete WDL_POOLLIST_identstr + + + void Clear() {} // will be called if ReleasePool(x,false) is called and refcnt gets to 0 + int WDL_POOLLIST_refcnt; + char *WDL_POOLLIST_identstr; + }; + + + +*/ + + + +#ifndef _WDL_POOLLIST_H_ +#define _WDL_POOLLIST_H_ + +#include + +#include "mutex.h" + +template class WDL_PoolList +{ +public: + + WDL_PoolList() + { + } + ~WDL_PoolList() + { + int x; + for (x = 0; x < pool.GetSize(); x ++) + { + DATATYPE *p = pool.Get(x); + free(p->WDL_POOLLIST_identstr); + delete p; + } + } + + DATATYPE *Get(const char *filename) + { + WDL_MutexLock lock(&mutex); + + DATATYPE *t = Find(filename,false); + if (t) + { + t->WDL_POOLLIST_refcnt++; + return t; + } + + t = new DATATYPE(strdup(filename)); + t->WDL_POOLLIST_refcnt=1; + + int x; + for(x=0;xWDL_POOLLIST_identstr,filename)>0) break; + + pool.Insert(x,t); + + return t; + } + + DATATYPE *Find(const char *filename, bool lockMutex=true) // not threadsafe + { + if (lockMutex) mutex.Enter(); + DATATYPE **_tmp=NULL; + if (pool.GetSize()) + { + DATATYPE tmp((char *)filename),*t=&tmp; + _tmp = (DATATYPE**)bsearch(&t,pool.GetList(),pool.GetSize(),sizeof(void *),_sortfunc); + } + if (lockMutex) mutex.Leave(); + return _tmp ? *_tmp : NULL; + } + + int ReleaseByName(const char *filename, bool isFull=true) + { + WDL_MutexLock lock(&mutex); + return Release(Find(filename,false),isFull); + } + + int Release(DATATYPE *tp, bool isFull=true) + { + if (!tp) return -1; + WDL_MutexLock lock(&mutex); + + int refcnt; + if (!(refcnt=--tp->WDL_POOLLIST_refcnt)) + { + if (!isFull) + { + tp->Clear(); + } + else + { + int x; + for (x = 0; x < pool.GetSize() && pool.Get(x) != tp; x ++); + if (xWDL_POOLLIST_identstr); + delete tp; + } + // remove from list + } + return refcnt; + } + + WDL_Mutex mutex; + WDL_PtrList< DATATYPE > pool; + +private: + + static int _sortfunc(const void *a, const void *b) + { + DATATYPE *ta = *(DATATYPE **)a; + DATATYPE *tb = *(DATATYPE **)b; + + return stricmp(ta->WDL_POOLLIST_identstr,tb->WDL_POOLLIST_identstr); + } +}; + + +#endif \ No newline at end of file diff --git a/WDL/projectcontext.cpp b/WDL/projectcontext.cpp new file mode 100644 index 00000000..651672df --- /dev/null +++ b/WDL/projectcontext.cpp @@ -0,0 +1,678 @@ +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif +#include +#include +#include + +#include "projectcontext.h" + +#include "fileread.h" +#include "filewrite.h" +#include "heapbuf.h" +#include "wdlstring.h" +#include "lineparse.h" + + +//#define WDL_MEMPROJECTCONTEXT_USE_ZLIB 1 + +#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + +#define WDL_MEMPROJECTCONTEXT_ZLIB_CHUNKSIZE 65536 +#include "zlib/zlib.h" + +#endif + + +class ProjectStateContext_Mem : public ProjectStateContext +{ +public: + + ProjectStateContext_Mem(WDL_HeapBuf *hb) + { + m_heapbuf=hb; + m_pos=0; + m_tmpflag=0; +#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + memset(&m_compstream,0,sizeof(m_compstream)); + m_usecomp=0; +#endif + } + + virtual ~ProjectStateContext_Mem() + { + #ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + if (m_usecomp==1) + { + FlushComp(true); + deflateEnd(&m_compstream); + } + else if (m_usecomp==2) + { + inflateEnd(&m_compstream); + } + #endif + }; + + virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...); + virtual int GetLine(char *buf, int buflen); // returns -1 on eof + + virtual WDL_INT64 GetOutputSize() { return m_heapbuf ? m_heapbuf->GetSize() : 0; } + + virtual int GetTempFlag() { return m_tmpflag; } + virtual void SetTempFlag(int flag) { m_tmpflag=flag; } + + int m_pos; + WDL_HeapBuf *m_heapbuf; + int m_tmpflag; + +#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + int DecompressData() + { + if (m_pos >= m_heapbuf->GetSize()) return 1; + + m_compstream.next_in = (unsigned char *)m_heapbuf->Get() + m_pos; + m_compstream.avail_in = m_heapbuf->GetSize()-m_pos; + m_compstream.total_in = 0; + + int outchunk = 65536; + m_compstream.next_out = (unsigned char *)m_compdatabuf.Add(NULL,outchunk); + m_compstream.avail_out = outchunk; + m_compstream.total_out = 0; + + int e = inflate(&m_compstream,Z_NO_FLUSH); + + m_pos += m_compstream.total_in; + m_compdatabuf.Add(NULL,m_compstream.total_out - outchunk); // rewind + + return e != Z_OK; + } + + void FlushComp(bool eof) + { + while (m_compdatabuf.Available()>=WDL_MEMPROJECTCONTEXT_ZLIB_CHUNKSIZE || eof) + { + if (!m_heapbuf->GetSize()) m_heapbuf->SetGranul(256*1024); + m_compstream.next_in = (unsigned char *)m_compdatabuf.Get(); + m_compstream.avail_in = m_compdatabuf.Available(); + m_compstream.total_in = 0; + + int osz = m_heapbuf->GetSize(); + + int newsz=osz + max(m_compstream.avail_in,8192) + 256; + m_compstream.next_out = (unsigned char *)m_heapbuf->Resize(newsz, false) + osz; + if (m_heapbuf->GetSize()!=newsz) return; // ERROR + m_compstream.avail_out = newsz-osz; + m_compstream.total_out=0; + + deflate(&m_compstream,eof?Z_SYNC_FLUSH:Z_NO_FLUSH); + + m_heapbuf->Resize(osz+m_compstream.total_out,false); + m_compdatabuf.Advance(m_compstream.total_in); + if (m_compstream.avail_out) break; // no need to process anymore + + } + m_compdatabuf.Compact(); + } + + // these will be used for either decompression or compression, fear + int m_usecomp; // 0=?, -1 = fail, 1=yes + WDL_Queue m_compdatabuf; + z_stream m_compstream; +#endif + +}; + +void ProjectStateContext_Mem::AddLine(const char *fmt, ...) +{ + if (!m_heapbuf) return; + + char buf[8192]; + va_list va; + va_start(va,fmt); + + buf[0]=0; +#if defined(_WIN32) && defined(_MSC_VER) + int l = _vsnprintf(buf,sizeof(buf),fmt,va); // _vsnprintf() does not always null terminate + if (l < 0 || l >= sizeof(buf)) + { + buf[sizeof(buf)-1]=0; + l = strlen(buf); + } +#else + // vsnprintf() on non-win32, always null terminates + int l = vsnprintf(buf,sizeof(buf),fmt,va); + if (l>sizeof(buf)-1) l=sizeof(buf)-1; +#endif + va_end(va); + + l++; // include NULL term + +#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + if (!m_usecomp) + { + if (deflateInit(&m_compstream,WDL_MEMPROJECTCONTEXT_USE_ZLIB)==Z_OK) m_usecomp=1; + else m_usecomp=-1; + } + + if (m_usecomp==1) + { + m_compdatabuf.Add(buf,l); + FlushComp(false); + return; + } +#endif + + + int sz=m_heapbuf->GetSize(); + if (!sz) + { + m_heapbuf->SetGranul(256*1024); + } + + int newsz = sz + l; + char *p = (char *)m_heapbuf->Resize(newsz); + if (m_heapbuf->GetSize() != newsz) + { + // ERROR, resize to 0 and return + m_heapbuf->Resize(0); + m_heapbuf=0; + return; + } + memcpy(p+sz,buf,l); +} + +int ProjectStateContext_Mem::GetLine(char *buf, int buflen) // returns -1 on eof +{ + if (!m_heapbuf) return -1; + + buf[0]=0; + + +#ifdef WDL_MEMPROJECTCONTEXT_USE_ZLIB + if (!m_usecomp) + { + unsigned char hdr[]={0x78,0x01}; + if (m_heapbuf->GetSize()>2 && !memcmp(hdr,m_heapbuf->Get(),4) && inflateInit(&m_compstream)==Z_OK) m_usecomp=2; + else m_usecomp=-1; + } + if (m_usecomp==2) + { + int x=0; + for (;;) + { + const char *p = (const char*) m_compdatabuf.Get(); + for (x = 0; x < m_compdatabuf.Available() && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); + while (x >= m_compdatabuf.Available()) + { + int err = DecompressData(); + p = (const char *)m_compdatabuf.Get(); + for (; x < m_compdatabuf.Available() && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); + + if (err) break; + } + + if (x||!m_compdatabuf.Available()) break; + + m_compdatabuf.Advance(1); // skip over nul or newline char + } + + if (!x) return -1; + + if (buflen > 0 && buf) + { + int l = min(buflen-1,x); + memcpy(buf,m_compdatabuf.Get(),l); + buf[l]=0; + } + + m_compdatabuf.Advance(x+1); + m_compdatabuf.Compact(); + return 0; + } +#endif + + + int avail = m_heapbuf->GetSize() - m_pos; + const char *p=(const char *)m_heapbuf->Get() + m_pos; + while (avail > 0 && (p[0] =='\r'||p[0]=='\n'||!p[0]||p[0] == ' ' || p[0] == '\t')) + { + p++; + m_pos++; + avail--; + } + if (avail <= 0) return -1; + + int x; + for (x = 0; x < avail && p[x] && p[x] != '\r' && p[x] != '\n'; x ++); + m_pos += x+1; + + if (buflen > 0&&buf) + { + int l = buflen-1; + if (l>x) l=x; + memcpy(buf,p,l); + buf[l]=0; + } + return 0; +} + +class ProjectStateContext_File : public ProjectStateContext +{ +public: + + ProjectStateContext_File(WDL_FileRead *rd, WDL_FileWrite *wr) + { + m_rd=rd; + m_wr=wr; + m_indent=0; + m_bytesOut=0; + m_errcnt=false; + m_tmpflag=0; + } + virtual ~ProjectStateContext_File(){ delete m_rd; delete m_wr; }; + + virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...); + virtual int GetLine(char *buf, int buflen); // returns -1 on eof + + virtual WDL_INT64 GetOutputSize() { return m_bytesOut; } + + virtual int GetTempFlag() { return m_tmpflag; } + virtual void SetTempFlag(int flag) { m_tmpflag=flag; } + + bool HasError() { return m_errcnt; } + + WDL_INT64 m_bytesOut WDL_FIXALIGN; + + WDL_FileRead *m_rd; + WDL_FileWrite *m_wr; + int m_indent; + int m_tmpflag; + bool m_errcnt; +}; + +int ProjectStateContext_File::GetLine(char *buf, int buflen) +{ + if (!m_rd||buflen<2) return -1; + + buf[0]=0; + for (;;) + { + buf[0]=0; + int i=0; + while (iRead(buf+i,1)) { if (!i) return -1; break; } + + if (buf[i] == '\r' || buf[i] == '\n') + { + if (!i) continue; // skip over leading newlines + break; + } + + if (!i && (buf[0] == ' ' || buf[0] == '\t')) continue; // skip leading blanks + + i++; + } + if (i<1) continue; + + buf[i]=0; + + if (buf[0]) return 0; + } + return -1; +} + +void ProjectStateContext_File::AddLine(const char *fmt, ...) +{ + if (m_wr && !m_errcnt) + { + int err=0; + + int a=m_indent; + if (fmt[0] == '<') m_indent+=2; + else if (fmt[0] == '>') a=(m_indent-=2); + + if (a>0) + { + m_bytesOut+=a; + char tb[32]; + memset(tb,' ',sizeof(tb)); + while (a>0) + { + int tl = a; + if (tl>32)tl=32; + a-=tl; + m_wr->Write(tb,tl); + } + } + + + char buf[8192]; + va_list va; + va_start(va,fmt); + + buf[0]=0; + #if defined(_WIN32) && defined(_MSC_VER) + int l = _vsnprintf(buf,sizeof(buf),fmt,va); // _vsnprintf() does not always null terminate + if (l < 0 || l >= sizeof(buf)) + { + buf[sizeof(buf)-1] = 0; + l = strlen(buf); + } + #else + // vsnprintf() on non-win32, always null terminates + int l = vsnprintf(buf,sizeof(buf),fmt,va); + if (l>sizeof(buf)-1) l=sizeof(buf)-1; + #endif + + va_end(va); + + err |= m_wr->Write(buf,l) != l; + err |= m_wr->Write("\r\n",2) != 2; + m_bytesOut += 2 + l; + + if (err) m_errcnt=true; + } +} + + + +ProjectStateContext *ProjectCreateFileRead(const char *fn) +{ + WDL_FileRead *rd = new WDL_FileRead(fn); + if (!rd || !rd->IsOpen()) + { + delete rd; + return NULL; + } + return new ProjectStateContext_File(rd,NULL); +} +ProjectStateContext *ProjectCreateFileWrite(const char *fn) +{ + WDL_FileWrite *wr = new WDL_FileWrite(fn); + if (!wr || !wr->IsOpen()) + { + delete wr; + return NULL; + } + return new ProjectStateContext_File(NULL,wr); +} + + +ProjectStateContext *ProjectCreateMemCtx(WDL_HeapBuf *hb) +{ + return new ProjectStateContext_Mem(hb); +} + +bool ProjectContext_GetNextLine(ProjectStateContext *ctx, LineParser *lpOut) +{ + for (;;) + { + char linebuf[4096]; + if (ctx->GetLine(linebuf,sizeof(linebuf))) + { + lpOut->parse(""); + return false; + } + + if (lpOut->parse(linebuf)||lpOut->getnumtokens()<=0) continue; + + return true; // success! + + } +} + + +bool ProjectContext_EatCurrentBlock(ProjectStateContext *ctx) +{ + int child_count=1; + if (ctx) for (;;) + { + char linebuf[4096]; + if (ctx->GetLine(linebuf,sizeof(linebuf))) break; + + bool comment_state=false; + LineParser lp(comment_state); + if (lp.parse(linebuf)||lp.getnumtokens()<=0) continue; + if (lp.gettoken_str(0)[0] == '>') if (--child_count < 1) return true; + if (lp.gettoken_str(0)[0] == '<') child_count++; + } + + return false; +} + + +static void pc_base64encode(const unsigned char *in, char *out, int len) +{ + char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int shift = 0; + int accum = 0; + + while (len>0) + { + len--; + accum <<= 8; + shift += 8; + accum |= *in++; + while ( shift >= 6 ) + { + shift -= 6; + *out++ = alphabet[(accum >> shift) & 0x3F]; + } + } + if (shift == 4) + { + *out++ = alphabet[(accum & 0xF)<<2]; + *out++='='; + } + else if (shift == 2) + { + *out++ = alphabet[(accum & 0x3)<<4]; + *out++='='; + *out++='='; + } + + *out++=0; +} + +static int pc_base64decode(const char *src, unsigned char *dest, int destsize) +{ + unsigned char *olddest=dest; + + int accum=0; + int nbits=0; + while (*src) + { + int x=0; + char c=*src++; + if (c >= 'A' && c <= 'Z') x=c-'A'; + else if (c >= 'a' && c <= 'z') x=c-'a' + 26; + else if (c >= '0' && c <= '9') x=c-'0' + 52; + else if (c == '+') x=62; + else if (c == '/') x=63; + else break; + + accum <<= 6; + accum |= x; + nbits += 6; + + while (nbits >= 8) + { + if (--destsize<0) break; + nbits-=8; + *dest++ = (char)((accum>>nbits)&0xff); + } + + } + return dest-olddest; +} + + +int cfg_decode_binary(ProjectStateContext *ctx, WDL_HeapBuf *hb) // 0 on success, doesnt clear hb +{ + int child_count=1; + bool comment_state=false; + for (;;) + { + char linebuf[4096]; + if (ctx->GetLine(linebuf,sizeof(linebuf))) break; + + LineParser lp(comment_state); + if (lp.parse(linebuf)||lp.getnumtokens()<=0) continue; + + if (lp.gettoken_str(0)[0] == '<') child_count++; + else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; } + else if (child_count == 1) + { + unsigned char buf[8192]; + int buf_l=pc_base64decode(lp.gettoken_str(0),buf,sizeof(buf)); + int os=hb->GetSize(); + hb->Resize(os+buf_l); + memcpy((char *)hb->Get()+os,buf,buf_l); + } + } + return -1; +} + +void cfg_encode_binary(ProjectStateContext *ctx, const void *ptr, int len) +{ + const unsigned char *p=(const unsigned char *)ptr; + while (len>0) + { + char buf[80]; + int thiss=len; + if (thiss > 40) thiss=40; + pc_base64encode(p,buf,thiss); + + ctx->AddLine("%s",buf); + p+=thiss; + len-=thiss; + } +} + + +int cfg_decode_textblock(ProjectStateContext *ctx, WDL_String *str) // 0 on success, appends to str +{ + int child_count=1; + bool comment_state=false; + for (;;) + { + char linebuf[4096]; + if (ctx->GetLine(linebuf,sizeof(linebuf))) break; + + if (!linebuf[0]) continue; + LineParser lp(comment_state); + if (!lp.parse(linebuf)&&lp.getnumtokens()>0) + { + if (lp.gettoken_str(0)[0] == '<') { child_count++; continue; } + else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; continue; } + } + if (child_count == 1) + { + char *p=linebuf; + while (*p == ' ' || *p == '\t') p++; + if (*p == '|') + { + if (str->Get()[0]) str->Append("\r\n"); + str->Append(++p); + } + } + } + return -1; +} + +int cfg_decode_textblock(ProjectStateContext *ctx, WDL_FastString *str) // 0 on success, appends to str +{ + int child_count=1; + bool comment_state=false; + for (;;) + { + char linebuf[4096]; + if (ctx->GetLine(linebuf,sizeof(linebuf))) break; + + if (!linebuf[0]) continue; + LineParser lp(comment_state); + if (!lp.parse(linebuf)&&lp.getnumtokens()>0) + { + if (lp.gettoken_str(0)[0] == '<') { child_count++; continue; } + else if (lp.gettoken_str(0)[0] == '>') { if (child_count-- == 1) return 0; continue; } + } + if (child_count == 1) + { + char *p=linebuf; + while (*p == ' ' || *p == '\t') p++; + if (*p == '|') + { + if (str->Get()[0]) str->Append("\r\n"); + str->Append(++p); + } + } + } + return -1; +} + + +void cfg_encode_textblock(ProjectStateContext *ctx, const char *text) +{ + WDL_String tmpcopy(text); + char *txt=(char*)tmpcopy.Get(); + while (*txt) + { + char *ntext=txt; + while (*ntext && *ntext != '\r' && *ntext != '\n') ntext++; + if (ntext > txt || *ntext) + { + char ov=*ntext; + *ntext=0; + ctx->AddLine("|%s",txt); + *ntext=ov; + } + txt=ntext; + if (*txt == '\r') + { + if (*++txt== '\n') txt++; + } + else if (*txt == '\n') + { + if (*++txt == '\r') txt++; + } + } +} + + +void makeEscapedConfigString(const char *in, WDL_String *out) +{ + int flags=0; + const char *p=in; + while (*p && flags!=7) + { + char c=*p++; + if (c=='"') flags|=1; + else if (c=='\'') flags|=2; + else if (c=='`') flags|=4; + } + if (flags!=7) + { + const char *src=(flags&1)?((flags&2)?"`":"'"):"\""; + out->Set(src); + out->Append(in); + out->Append(src); + } + else // ick, change ` into ' + { + out->Set("`"); + out->Append(in); + out->Append("`"); + char *p=out->Get()+1; + while (*p && p[1]) + { + if (*p == '`') *p='\''; + p++; + } + } +} diff --git a/WDL/projectcontext.h b/WDL/projectcontext.h new file mode 100644 index 00000000..f6a53e40 --- /dev/null +++ b/WDL/projectcontext.h @@ -0,0 +1,50 @@ +#ifndef _PROJECTCONTEXT_H_ +#define _PROJECTCONTEXT_H_ + +#include "wdltypes.h" + +class WDL_String; +class WDL_FastString; +class WDL_HeapBuf; + +#ifndef _REAPER_PLUGIN_PROJECTSTATECONTEXT_DEFINED_ +#define _WDL_PROJECTSTATECONTEXT_DEFINED_ + +class ProjectStateContext // this is also defined in reaper_plugin.h (keep them identical, thx) +{ +public: + virtual ~ProjectStateContext(){}; + + virtual void WDL_VARARG_WARN(printf,2,3) AddLine(const char *fmt, ...) = 0; + virtual int GetLine(char *buf, int buflen)=0; // returns -1 on eof + + virtual WDL_INT64 GetOutputSize()=0; + + virtual int GetTempFlag()=0; + virtual void SetTempFlag(int flag)=0; +}; + +#endif + +ProjectStateContext *ProjectCreateFileRead(const char *fn); +ProjectStateContext *ProjectCreateFileWrite(const char *fn); +ProjectStateContext *ProjectCreateMemCtx(WDL_HeapBuf *hb); // read or write, be sure to delete it before accessing hb + + + +// helper functions +class LineParser; +bool ProjectContext_EatCurrentBlock(ProjectStateContext *ctx); // returns TRUE if got valid >, otherwise it means eof... +bool ProjectContext_GetNextLine(ProjectStateContext *ctx, LineParser *lpOut); // true if lpOut is valid + + +int cfg_decode_binary(ProjectStateContext *ctx, WDL_HeapBuf *hb); // 0 on success, doesnt clear hb +void cfg_encode_binary(ProjectStateContext *ctx, const void *ptr, int len); + +int cfg_decode_textblock(ProjectStateContext *ctx, WDL_String *str); // 0 on success, appends to str +int cfg_decode_textblock(ProjectStateContext *ctx, WDL_FastString *str); // 0 on success, appends to str +void cfg_encode_textblock(ProjectStateContext *ctx, const char *text); + +void makeEscapedConfigString(const char *in, WDL_String *out); + +#endif//_PROJECTCONTEXT_H_ diff --git a/WDL/ptrlist.h b/WDL/ptrlist.h new file mode 100644 index 00000000..2a62b6f1 --- /dev/null +++ b/WDL/ptrlist.h @@ -0,0 +1,223 @@ +/* + WDL - ptrlist.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple templated class for a list of pointers. By default this list + doesn't free any of the pointers, but you can call Empty(true) or Delete(x,true) to delete the pointer, + or you can use Empty(true,free) etc to call free (or any other function). + + Note: on certain compilers, instantiating with WDL_PtrList bla; will give a warning, since + the template will create code for "delete (void *)x;" which isn't technically valid. Oh well. + +*/ + +#ifndef _WDL_PTRLIST_H_ +#define _WDL_PTRLIST_H_ + +#include "heapbuf.h" + +template class WDL_PtrList +{ + public: + explicit WDL_PtrList(int defgran=4096) : m_hb(defgran WDL_HEAPBUF_TRACEPARM("WDL_PtrList")) + { + } + + ~WDL_PtrList() + { + } + + PTRTYPE **GetList() const { return (PTRTYPE**)m_hb.Get(); } + PTRTYPE *Get(INT_PTR index) const { if (GetList() && index >= 0 && index < (INT_PTR)GetSize()) return GetList()[index]; return NULL; } + int GetSize(void) const { return m_hb.GetSize()/sizeof(PTRTYPE *); } + + int Find(PTRTYPE *p) const + { + if (p) + { + int x; + PTRTYPE **list=(PTRTYPE **)m_hb.Get(); + for (x = 0; x < GetSize(); x ++) if (list[x] == p) return x; + } + return -1; + } + + PTRTYPE *Add(PTRTYPE *item) + { + int s=GetSize(); + m_hb.Resize((s+1)*sizeof(PTRTYPE*),false); + return Set(s,item); + } + + PTRTYPE *Set(int index, PTRTYPE *item) + { + if (index >= 0 && index < GetSize() && GetList()) return GetList()[index]=item; + return NULL; + } + + PTRTYPE *Insert(int index, PTRTYPE *item) + { + int s=GetSize(); + m_hb.Resize((s+1)*sizeof(PTRTYPE*),false); + + if (index<0) index=0; + else if (index > s) index=s; + + int x; + PTRTYPE **list = GetList(); + for (x = s; x > index; x --) list[x]=list[x-1]; + return (list[x] = item); + } + int FindSorted(PTRTYPE *p, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) const + { + bool m; + int i = LowerBound(p,&m,compar); + return m ? i : -1; + } + PTRTYPE *InsertSorted(PTRTYPE *item, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) + { + bool m; + return Insert(LowerBound(item,&m,compar),item); + } + + void Delete(int index) + { + PTRTYPE **list=GetList(); + int size=GetSize(); + if (list && index >= 0 && index < size) + { + if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); + m_hb.Resize(size * sizeof(PTRTYPE*),false); + } + } + void Delete(int index, bool wantDelete, void (*delfunc)(void *)=NULL) + { + PTRTYPE **list=GetList(); + int size=GetSize(); + if (list && index >= 0 && index < size) + { + if (wantDelete) + { + if (delfunc) delfunc(Get(index)); + else delete Get(index); + } + if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); + m_hb.Resize(size * sizeof(PTRTYPE*),false); + } + } + void Delete(int index, void (*delfunc)(PTRTYPE *)) + { + PTRTYPE **list=GetList(); + int size=GetSize(); + if (list && index >= 0 && index < size) + { + if (delfunc) delfunc(Get(index)); + if (index < --size) memmove(list+index,list+index+1,sizeof(PTRTYPE *)*(size-index)); + m_hb.Resize(size * sizeof(PTRTYPE*),false); + } + } + void Empty() + { + m_hb.Resize(0,false); + } + void Empty(bool wantDelete, void (*delfunc)(void *)=NULL) + { + if (wantDelete) + { + int x; + for (x = GetSize()-1; x >= 0; x --) + { + PTRTYPE* p = Get(x); + if (p) + { + if (delfunc) delfunc(p); + else delete p; + } + m_hb.Resize(x*sizeof(PTRTYPE *),false); + } + } + m_hb.Resize(0,false); + } + void Empty(void (*delfunc)(PTRTYPE *)) + { + int x; + for (x = GetSize()-1; x >= 0; x --) + { + PTRTYPE* p = Get(x); + if (delfunc && p) delfunc(p); + m_hb.Resize(x*sizeof(PTRTYPE *),false); + } + } + void EmptySafe(bool wantDelete=false,void (*delfunc)(void *)=NULL) + { + if (!wantDelete) Empty(); + else + { + WDL_PtrList tmp; + int x; + for(x=0;x 0) a = b+1; + else if (cmp < 0) c = b; + else + { + *ismatch = true; + return b; + } + } + *ismatch = false; + return a; + } + + private: + WDL_HeapBuf m_hb; + +}; + + +template class WDL_PtrList_DeleteOnDestroy : public WDL_PtrList +{ +public: + explicit WDL_PtrList_DeleteOnDestroy(void (*delfunc)(void *)=NULL, int defgran=4096) : WDL_PtrList(defgran), m_delfunc(delfunc) { } + ~WDL_PtrList_DeleteOnDestroy() + { + WDL_PtrList::EmptySafe(true,m_delfunc); + } +private: + void (*m_delfunc)(void *); +}; + +#endif + diff --git a/WDL/queue.h b/WDL/queue.h new file mode 100644 index 00000000..cdbba334 --- /dev/null +++ b/WDL/queue.h @@ -0,0 +1,273 @@ +/* + WDL - queue.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple class for a FIFO queue of bytes. It uses a simple buffer, + so should not generally be used for large quantities of data (it can advance the queue + pointer, but Compact() needs to be called regularly to keep memory usage down, and when + it is called, there's a memcpy() penalty for the remaining data. oh well, is what it is). + + You may also wish to look at fastqueue.h or circbuf.h if these limitations aren't acceptable. + +*/ + +#ifndef _WDL_QUEUE_H_ +#define _WDL_QUEUE_H_ + +#include "heapbuf.h" + + +class WDL_Queue +{ +public: + WDL_Queue() : m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { } + WDL_Queue(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_Queue")), m_pos(0) { } + ~WDL_Queue() { } + + template void* AddT(T* buf) + { + return Add(buf, sizeof(T)); + } + + void *Add(const void *buf, int len) + { + int olen=m_hb.GetSize(); + if (m_pos >= olen) m_pos=olen=0; // if queue is empty then autoreset it + + void *obuf=m_hb.Resize(olen+len,false); + if (m_hb.GetSize() != olen+len) return NULL; + + char* newbuf = (char*) obuf + olen; + if (buf) memcpy(newbuf,buf,len); + return newbuf; + } + + template T* GetT(T* val=0) + { + T* p = (T*) Get(sizeof(T)); + if (val && p) *val = *p; + return p; + } + + void* Get(int size) + { + void* p = Get(); + if (p) Advance(size); + return p; + } + + void *Get() const + { + void *buf=m_hb.Get(); + if (buf && m_pos >= 0 && m_pos < m_hb.GetSize()) return (char *)buf+m_pos; + return NULL; + } + + void* Rewind() + { + m_pos = 0; + return m_hb.Get(); + } + + int GetSize() const + { + return m_hb.GetSize()-m_pos; + } + int Available() const { return GetSize(); } + + void Clear() + { + m_pos=0; + m_hb.Resize(0,false); + } + + void Advance(int bytecnt) + { + m_pos+=bytecnt; + if (m_pos<0)m_pos=0; + else if (m_pos > m_hb.GetSize()) m_pos=m_hb.GetSize(); + } + + void Compact(bool allocdown=false, bool force=false) + { + int olen=m_hb.GetSize(); + if (m_pos > (force ? 0 : olen/2)) + { + if (m_pos < olen) + { + void *a=m_hb.Get(); + if (a) memmove(a,(char*)a+m_pos,olen-m_pos); + m_hb.Resize(olen-m_pos,allocdown); + } + else m_hb.Resize(0,allocdown); + m_pos=0; + } + } + + void SetGranul(int granul) { m_hb.SetGranul(granul); } + + + + + // endian-management stuff + + static void WDL_Queue__bswap_buffer(void *buf, int len) + { + #ifdef __ppc__ + char *p=(char *)buf; + char *ep=p+len; + while ((len-=2) >= 0) + { + char tmp=*p; *p++=*--ep; *ep=tmp; + } + #endif + } + + // older API of static functions (that endedu p warning a bit anyway) +#define WDL_Queue__AddToLE(q, v) (q)->AddToLE(v) +#define WDL_Queue__AddDataToLE(q,d,ds,us) (q)->AddDataToLE(d,ds,us) +#define WDL_Queue__GetTFromLE(q,v) (q)->GetTFromLE(v) +#define WDL_Queue__GetDataFromLE(q,ds,us) (q)->GetDataFromLE(ds,us) + + template void AddToLE(T *val) + { + WDL_Queue__bswap_buffer(AddT(val),sizeof(T)); + } + void AddDataToLE(void *data, int datasize, int unitsize) + { + #ifdef __ppc__ + char *dout = (char *)Add(data,datasize); + while (datasize >= unitsize) + { + WDL_Queue__bswap_buffer(dout,unitsize); + dout+=unitsize; + datasize-=unitsize; + } + #else + Add(data,datasize); + #endif + } + + + // NOTE: these thrash the contents of the queue if on LE systems. So for example if you are going to rewind it later or use it elsewhere, + // then get ready to get unhappy. + template T *GetTFromLE(T* val=0) + { + T *p = GetT(val); + if (p) { + WDL_Queue__bswap_buffer(p,sizeof(T)); + if (val) *val = *p; + } + return p; + } + + void *GetDataFromLE(int datasize, int unitsize) + { + void *data=Get(datasize); + #ifdef __ppc__ + char *dout=(char *)data; + if (dout) while (datasize >= unitsize) + { + WDL_Queue__bswap_buffer(dout,unitsize); + dout+=unitsize; + datasize-=unitsize; + } + #endif + return data; + } + + +private: + WDL_HeapBuf m_hb; + int m_pos; + int __pad; // keep 8 byte aligned +}; + +template class WDL_TypedQueue +{ +public: + WDL_TypedQueue() : m_pos(0), m_hb(4096 WDL_HEAPBUF_TRACEPARM("WDL_TypedQueue")) { } + ~WDL_TypedQueue() { } + + T *Add(const T *buf, int len) + { + int olen=m_hb.GetSize(); + if (m_pos >= olen) olen=m_pos=0; + len *= sizeof(T); + void *obuf=m_hb.Resize(olen+len,false); + if (!obuf||m_hb.GetSize()!=olen+len) return 0; + if (buf) memcpy((char*)obuf+olen,buf,len); + return (T*) ((char*)obuf+olen); + } + + T *Get() const + { + void *buf=m_hb.Get(); + if (buf && m_pos >= 0 && m_pos < m_hb.GetSize()) return (T*)((char *)buf+m_pos); + return NULL; + } + + int GetSize() const + { + return (m_hb.GetSize()-m_pos)/sizeof(T); + } + int Available() const { return GetSize(); } + + void Clear() + { + m_pos=0; + m_hb.Resize(0,false); + } + + void Advance(int cnt) + { + m_pos+=cnt*sizeof(T); + if (m_pos<0)m_pos=0; + else if (m_pos > m_hb.GetSize()) m_pos=m_hb.GetSize(); + } + + void Compact(bool allocdown=false, bool force=false) + { + int olen=m_hb.GetSize(); + if (m_pos > (force ? 0 : olen/2)) + { + if (m_pos < olen) + { + void *a=m_hb.Get(); + if (a) memmove(a,(char*)a+m_pos,olen-m_pos); + m_hb.Resize(olen-m_pos,allocdown); + } + else m_hb.Resize(0,allocdown); + m_pos=0; + } + } + + void SetGranul(int granul) { m_hb.SetGranul(granul); } + +private: + WDL_HeapBuf m_hb; + int m_pos; + int __pad; // keep 8 byte aligned +}; + +#endif diff --git a/WDL/reminder.h b/WDL/reminder.h new file mode 100644 index 00000000..4518c88b --- /dev/null +++ b/WDL/reminder.h @@ -0,0 +1,13 @@ +#ifndef REMINDER + + #define MAKE_QUOTE(str) #str + #define MAKE_STR(str) MAKE_QUOTE(str) + #if defined WIN32 + // This enables: #pragma REMINDER("change this line!") with click-through from VC++. + #define REMINDER(msg) message(__FILE__ "(" MAKE_STR(__LINE__) "): " msg) + #else + #define REMINDER(msg) // no-op + #endif + +#endif + diff --git a/WDL/resample.cpp b/WDL/resample.cpp new file mode 100644 index 00000000..ec36285f --- /dev/null +++ b/WDL/resample.cpp @@ -0,0 +1,597 @@ +/* +** Copyright (C) 2010 Cockos Incorporated +** LGPL +**/ +#include "resample.h" +#include + +#include "denormal.h" + +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef PI +#define PI 3.1415926535897932384626433832795 +#endif + +class WDL_Resampler::WDL_Resampler_IIRFilter +{ +public: + WDL_Resampler_IIRFilter() + { + m_fpos=-1; + Reset(); + } + ~WDL_Resampler_IIRFilter() + { + } + + void Reset() + { + memset(m_hist,0,sizeof(m_hist)); + } + + void setParms(double fpos, double Q) + { + if (fabs(fpos-m_fpos)<0.000001) return; + m_fpos=fpos; + + double pos = fpos * PI; + double cpos=cos(pos); + double spos=sin(pos); + + double alpha=spos/(2.0*Q); + + double sc=1.0/( 1 + alpha); + m_b1 = (1-cpos) * sc; + m_b2 = m_b0 = m_b1*0.5; + m_a1 = -2 * cpos * sc; + m_a2 = (1-alpha)*sc; + + } + + void Apply(WDL_ResampleSample *in1, WDL_ResampleSample *out1, int ns, int span, int w) + { + double b0=m_b0,b1=m_b1,b2=m_b2,a1=m_a1,a2=m_a2; + double *hist=m_hist[w]; + while (ns--) + { + double in=*in1; + in1+=span; + double out = (double) ( in*b0 + hist[0]*b1 + hist[1]*b2 - hist[2]*a1 - hist[3]*a2); + hist[1]=hist[0]; hist[0]=in; + hist[3]=hist[2]; *out1 = hist[2]=denormal_filter_double(out); + + out1+=span; + } + } + +private: + double m_fpos; + double m_a1,m_a2; + double m_b0,m_b1,m_b2; + double m_hist[WDL_RESAMPLE_MAX_FILTERS*WDL_RESAMPLE_MAX_NCH][4]; +}; + + +void inline WDL_Resampler::SincSample(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, int nch, WDL_SincFilterSample *filter, int filtsz) +{ + int oversize=m_lp_oversize; + int x; + fracpos *= oversize; + int ifpos=(int)fracpos; + filter += oversize-1-ifpos; + fracpos -= ifpos; + + for (x = 0; x < nch; x ++) + { + double sum=0.0,sum2=0.0; + WDL_SincFilterSample *fptr=filter; + WDL_ResampleSample *iptr=inptr+x; + int i=filtsz; + while (i--) + { + sum += fptr[0]*iptr[0]; + sum2 += fptr[1]*iptr[0]; + iptr+=nch; + fptr += oversize; + } + outptr[x]=sum*fracpos + sum2*(1.0-fracpos); + } + +} + +void inline WDL_Resampler::SincSample1(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz) +{ + int oversize=m_lp_oversize; + fracpos *= oversize; + int ifpos=(int)fracpos; + filter += oversize-1-ifpos; + fracpos -= ifpos; + + double sum=0.0,sum2=0.0; + WDL_SincFilterSample *fptr=filter; + WDL_ResampleSample *iptr=inptr; + int i=filtsz; + while (i--) + { + sum += fptr[0]*iptr[0]; + sum2 += fptr[1]*iptr[0]; + iptr++; + fptr += oversize; + } + outptr[0]=sum*fracpos+sum2*(1.0-fracpos); + +} + +void inline WDL_Resampler::SincSample2(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz) +{ + int oversize=m_lp_oversize; + fracpos *= oversize; + int ifpos=(int)fracpos; + filter += oversize-1-ifpos; + fracpos -= ifpos; + + double sum=0.0; + double sum2=0.0; + double sumb=0.0; + double sum2b=0.0; + WDL_SincFilterSample *fptr=filter; + WDL_ResampleSample *iptr=inptr; + int i=filtsz/2; + while (i--) + { + sum += fptr[0]*iptr[0]; + sum2 += fptr[0]*iptr[1]; + sumb += fptr[1]*iptr[0]; + sum2b += fptr[1]*iptr[1]; + sum += fptr[oversize]*iptr[2]; + sum2 += fptr[oversize]*iptr[3]; + sumb += fptr[oversize+1]*iptr[2]; + sum2b += fptr[oversize+1]*iptr[3]; + iptr+=4; + fptr += oversize*2; + } + outptr[0]=sum*fracpos + sumb*(1.0-fracpos); + outptr[1]=sum2*fracpos + sum2b*(1.0-fracpos); + +} + + + +WDL_Resampler::WDL_Resampler() +{ + m_filterq=0.707f; + m_filterpos=0.693f; // .792 ? + + m_sincoversize=0; + m_lp_oversize=1; + m_sincsize=0; + m_filtercnt=1; + m_interp=true; + m_feedmode=false; + + m_filter_coeffs_size=0; + m_sratein=44100.0; + m_srateout=44100.0; + m_ratio=1.0; + m_filter_ratio=-1.0; + m_iirfilter=0; + + Reset(); +} + +WDL_Resampler::~WDL_Resampler() +{ + delete m_iirfilter; +} + +void WDL_Resampler::Reset(double fracpos) +{ + m_last_requested=0; + m_filtlatency=0; + m_fracpos=fracpos; + m_samples_in_rsinbuf=0; + if (m_iirfilter) m_iirfilter->Reset(); +} + +void WDL_Resampler::SetMode(bool interp, int filtercnt, bool sinc, int sinc_size, int sinc_interpsize) +{ + m_sincsize = sinc && sinc_size>= 4 ? sinc_size > 8192 ? 8192 : sinc_size : 0; + m_sincoversize = m_sincsize ? (sinc_interpsize<= 1 ? 1 : sinc_interpsize>=4096 ? 4096 : sinc_interpsize) : 1; + + m_filtercnt = m_sincsize ? 0 : (filtercnt<=0?0 : filtercnt >= WDL_RESAMPLE_MAX_FILTERS ? WDL_RESAMPLE_MAX_FILTERS : filtercnt); + m_interp=interp && !m_sincsize; +// char buf[512]; +// sprintf(buf,"setting interp=%d, filtercnt=%d, sinc=%d,%d\n",m_interp,m_filtercnt,m_sincsize,m_sincoversize); +// OutputDebugString(buf); + + if (!m_sincsize) + { + m_filter_coeffs.Resize(0); + m_filter_coeffs_size=0; + } + if (!m_filtercnt) + { + delete m_iirfilter; + m_iirfilter=0; + } +} + +void WDL_Resampler::SetRates(double rate_in, double rate_out) +{ + if (rate_in<1.0) rate_in=1.0; + if (rate_out<1.0) rate_out=1.0; + if (rate_in != m_sratein || rate_out != m_srateout) + { + m_sratein=rate_in; + m_srateout=rate_out; + m_ratio=m_sratein / m_srateout; + } +} + + +void WDL_Resampler::BuildLowPass(double filtpos) // only called in sinc modes +{ + int wantsize=m_sincsize; + int wantinterp=m_sincoversize; + + if (m_filter_ratio!=filtpos || + m_filter_coeffs_size != wantsize || + m_lp_oversize != wantinterp) + { + m_lp_oversize = wantinterp; + m_filter_ratio=filtpos; + + // build lowpass filter + int allocsize = (wantsize+1)*m_lp_oversize; + WDL_SincFilterSample *cfout=m_filter_coeffs.Resize(allocsize); + if (m_filter_coeffs.GetSize()==allocsize) + { + m_filter_coeffs_size=wantsize; + + int sz=wantsize*m_lp_oversize; + int hsz=sz/2; + double filtpower=0.0; + double windowpos = 0.0; + double dwindowpos = 2.0 * PI/(double)(sz); + double dsincpos = PI / m_lp_oversize * filtpos; // filtpos is outrate/inrate, i.e. 0.5 is going to half rate + double sincpos = dsincpos * (double)(-hsz); + + int x; + for (x = -hsz; x < hsz+m_lp_oversize; x ++) + { + double val = 0.35875 - 0.48829 * cos(windowpos) + 0.14128 * cos(2*windowpos) - 0.01168 * cos(6*windowpos); // blackman-harris + if (x) val *= sin(sincpos) / sincpos; + + windowpos+=dwindowpos; + sincpos += dsincpos; + + cfout[hsz+x] = (WDL_SincFilterSample)val; + if (x < hsz) filtpower += val; + } + filtpower = m_lp_oversize/filtpower; + for (x = 0; x < sz+m_lp_oversize; x ++) + { + cfout[x] = (WDL_SincFilterSample) (cfout[x]*filtpower); + } + } + else m_filter_coeffs_size=0; + + } +} + +double WDL_Resampler::GetCurrentLatency() +{ + double v=((double)m_samples_in_rsinbuf-m_filtlatency)/m_sratein; + + if (v<0.0)v=0.0; + return v; +} + +int WDL_Resampler::ResamplePrepare(int out_samples, int nch, WDL_ResampleSample **inbuffer) +{ + if (nch > WDL_RESAMPLE_MAX_NCH || nch < 1) return 0; + + int fsize=0; + if (m_sincsize>1) fsize = m_sincsize; + + int hfs=fsize/2; + if (hfs>1 && m_samples_in_rsinbuf0) + { + WDL_ResampleSample *p = m_rsinbuf.Resize(m_samples_in_rsinbuf*nch,false); + memset(p,0,sizeof(WDL_ResampleSample)*m_rsinbuf.GetSize()); + } + } + + int sreq = 0; + + if (!m_feedmode) sreq = (int)(m_ratio * out_samples) + 4 + fsize - m_samples_in_rsinbuf; + else sreq = out_samples; + + if (sreq<0)sreq=0; + +again: + m_rsinbuf.Resize((m_samples_in_rsinbuf+sreq)*nch,false); + + int sz = m_rsinbuf.GetSize()/(nch?nch:1) - m_samples_in_rsinbuf; + if (sz!=sreq) + { + if (sreq>4 && !sz) + { + sreq/=2; + goto again; // try again with half the size + } + // todo: notify of error? + sreq=sz; + } + + *inbuffer = m_rsinbuf.Get() + m_samples_in_rsinbuf*nch; + + m_last_requested=sreq; + return sreq; +} + + + +int WDL_Resampler::ResampleOut(WDL_ResampleSample *out, int nsamples_in, int nsamples_out, int nch) +{ + if (nch > WDL_RESAMPLE_MAX_NCH || nch < 1) return 0; + + if (m_filtercnt>0) + { + if (m_ratio > 1.0 && nsamples_in > 0) // filter input + { + if (!m_iirfilter) m_iirfilter = new WDL_Resampler_IIRFilter; + + int n=m_filtercnt; + m_iirfilter->setParms((1.0/m_ratio)*m_filterpos,m_filterq); + + WDL_ResampleSample *buf=(WDL_ResampleSample *)m_rsinbuf.Get() + m_samples_in_rsinbuf*nch; + int a,x; + int offs=0; + for (x=0; x < nch; x ++) + for (a = 0; a < n; a ++) + m_iirfilter->Apply(buf+x,buf+x,nsamples_in,nch,offs++); + } + } + + m_samples_in_rsinbuf += min(nsamples_in,m_last_requested); // prevent the user from corrupting the internal state + + + int rsinbuf_availtemp = m_samples_in_rsinbuf; + + if (nsamples_in < m_last_requested) // flush out to ensure we can deliver + { + int fsize=(m_last_requested-nsamples_in)*2 + m_sincsize*2; + + int alloc_size=(m_samples_in_rsinbuf+fsize)*nch; + WDL_ResampleSample *zb=m_rsinbuf.Resize(alloc_size,false); + if (m_rsinbuf.GetSize()==alloc_size) + { + memset(zb+m_samples_in_rsinbuf*nch,0,fsize*nch*sizeof(WDL_ResampleSample)); + rsinbuf_availtemp = m_samples_in_rsinbuf+fsize; + } + } + + int ret=0; + double srcpos=m_fracpos; + double drspos = m_ratio; + WDL_ResampleSample *localin = m_rsinbuf.Get(); + + WDL_ResampleSample *outptr=out; + + int ns=nsamples_out; + + int outlatadj=0; + + if (m_sincsize) // sinc interpolating + { + if (m_ratio > 1.0) BuildLowPass(1.0 / (m_ratio*1.03)); + else BuildLowPass(1.0); + + int filtsz=m_filter_coeffs_size; + int filtlen = rsinbuf_availtemp - filtsz; + outlatadj=filtsz/2-1; + WDL_SincFilterSample *filter=m_filter_coeffs.Get(); + + if (nch == 1) + { + while (ns--) + { + int ipos = (int)srcpos; + + if (ipos >= filtlen-1) break; // quit decoding, not enough input samples + + SincSample1(outptr,localin + ipos,srcpos-ipos,filter,filtsz); + outptr ++; + srcpos+=drspos; + ret++; + } + } + else if (nch==2) + { + while (ns--) + { + int ipos = (int)srcpos; + + if (ipos >= filtlen-1) break; // quit decoding, not enough input samples + + SincSample2(outptr,localin + ipos*2,srcpos-ipos,filter,filtsz); + outptr+=2; + srcpos+=drspos; + ret++; + } + } + else + { + while (ns--) + { + int ipos = (int)srcpos; + + if (ipos >= filtlen-1) break; // quit decoding, not enough input samples + + SincSample(outptr,localin + ipos*nch,srcpos-ipos,nch,filter,filtsz); + outptr += nch; + srcpos+=drspos; + ret++; + } + } + } + else if (!m_interp) // point sampling + { + if (nch == 1) + { + while (ns--) + { + int ipos = (int)srcpos; + if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples + + *outptr++ = localin[ipos]; + srcpos+=drspos; + ret++; + } + } + else if (nch == 2) + { + while (ns--) + { + int ipos = (int)srcpos; + if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples + + ipos+=ipos; + + outptr[0] = localin[ipos]; + outptr[1] = localin[ipos+1]; + outptr+=2; + srcpos+=drspos; + ret++; + } + } + else + while (ns--) + { + int ipos = (int)srcpos; + if (ipos >= rsinbuf_availtemp) break; // quit decoding, not enough input samples + + memcpy(outptr,localin + ipos*nch,nch*sizeof(WDL_ResampleSample)); + outptr += nch; + srcpos+=drspos; + ret++; + } + } + else // linear interpolation + { + if (nch == 1) + { + while (ns--) + { + int ipos = (int)srcpos; + double fracpos=srcpos-ipos; + + if (ipos >= rsinbuf_availtemp-1) + { + break; // quit decoding, not enough input samples + } + + double ifracpos=1.0-fracpos; + WDL_ResampleSample *inptr = localin + ipos; + *outptr++ = inptr[0]*(ifracpos) + inptr[1]*(fracpos); + srcpos+=drspos; + ret++; + } + } + else if (nch == 2) + { + while (ns--) + { + int ipos = (int)srcpos; + double fracpos=srcpos-ipos; + + if (ipos >= rsinbuf_availtemp-1) + { + break; // quit decoding, not enough input samples + } + + double ifracpos=1.0-fracpos; + WDL_ResampleSample *inptr = localin + ipos*2; + outptr[0] = inptr[0]*(ifracpos) + inptr[2]*(fracpos); + outptr[1] = inptr[1]*(ifracpos) + inptr[3]*(fracpos); + outptr += 2; + srcpos+=drspos; + ret++; + } + } + else + { + while (ns--) + { + int ipos = (int)srcpos; + double fracpos=srcpos-ipos; + + if (ipos >= rsinbuf_availtemp-1) + { + break; // quit decoding, not enough input samples + } + + double ifracpos=1.0-fracpos; + int ch=nch; + WDL_ResampleSample *inptr = localin + ipos*nch; + while (ch--) + { + *outptr++ = inptr[0]*(ifracpos) + inptr[nch]*(fracpos); + inptr++; + } + srcpos+=drspos; + ret++; + } + } + } + + + if (m_filtercnt>0) + { + if (m_ratio < 1.0 && ret>0) // filter output + { + if (!m_iirfilter) m_iirfilter = new WDL_Resampler_IIRFilter; + int n=m_filtercnt; + m_iirfilter->setParms(m_ratio*m_filterpos,m_filterq); + + int x,a; + int offs=0; + for (x=0; x < nch; x ++) + for (a = 0; a < n; a ++) + m_iirfilter->Apply(out+x,out+x,ret,nch,offs++); + } + } + + + + if (ret>0 && rsinbuf_availtemp>m_samples_in_rsinbuf) // we had to pad!! + { + // check for the case where rsinbuf_availtemp>m_samples_in_rsinbuf, decrease ret down to actual valid samples + double adj=(srcpos-m_samples_in_rsinbuf + outlatadj) / drspos; + if (adj>0) + { + ret -= (int) (adj + 0.5); + if (ret<0)ret=0; + } + } + + int isrcpos=(int)srcpos; + m_fracpos = srcpos - isrcpos; + m_samples_in_rsinbuf -= isrcpos; + if (m_samples_in_rsinbuf <= 0) m_samples_in_rsinbuf=0; + else + memcpy(localin, localin + isrcpos*nch,m_samples_in_rsinbuf*sizeof(WDL_ResampleSample)*nch); + + + return ret; +} diff --git a/WDL/resample.h b/WDL/resample.h new file mode 100644 index 00000000..152ac8c5 --- /dev/null +++ b/WDL/resample.h @@ -0,0 +1,101 @@ +/* +** Copyright (C) 2010 Cockos Incorporated +** LGPL +**/ + +#ifndef _WDL_RESAMPLE_H_ +#define _WDL_RESAMPLE_H_ + +#include +#include +#include "wdltypes.h" +#include "heapbuf.h" + +// default to floats for sinc filter ceofficients +#ifdef WDL_RESAMPLE_FULL_SINC_PRECISION +typedef double WDL_SincFilterSample; +#else +typedef float WDL_SincFilterSample; +#endif + +// default to doubles for audio samples +#ifdef WDL_RESAMPLE_TYPE +typedef WDL_RESAMPLE_TYPE WDL_ResampleSample; +#else +typedef double WDL_ResampleSample; +#endif + + +#ifndef WDL_RESAMPLE_MAX_FILTERS +#define WDL_RESAMPLE_MAX_FILTERS 4 +#endif + +#ifndef WDL_RESAMPLE_MAX_NCH +#define WDL_RESAMPLE_MAX_NCH 64 +#endif + + +class WDL_Resampler +{ +public: + WDL_Resampler(); + ~WDL_Resampler(); + // if sinc set, it overrides interp or filtercnt + void SetMode(bool interp, int filtercnt, bool sinc, int sinc_size=64, int sinc_interpsize=32); + + void SetFilterParms(float filterpos=0.693, float filterq=0.707) { m_filterpos=filterpos; m_filterq=filterq; } // used for filtercnt>0 but not sinc + void SetFeedMode(bool wantInputDriven) { m_feedmode=wantInputDriven; } // if true, that means the first parameter to ResamplePrepare will specify however much input you have, not how much you want + + void Reset(double fracpos=0.0); + void SetRates(double rate_in, double rate_out); + + double GetCurrentLatency(); // amount of input that has been received but not yet converted to output, in seconds + + // req_samples is output samples desired if !wantInputDriven, or if wantInputDriven is input samples that we have + // returns number of samples desired (put these into *inbuffer) + // note that it is safe to call ResamplePrepare without calling ResampleOut (the next call of ResamplePrepare will function as normal) + int ResamplePrepare(int req_samples, int nch, WDL_ResampleSample **inbuffer); + + + // if numsamples_in < the value return by ResamplePrepare(), then it will be flushed to produce all remaining valid samples + // do NOT call with nsamples_in greater than the value returned from resamplerprpare()! the extra samples will be ignored. + // returns number of samples successfully outputted to out + int ResampleOut(WDL_ResampleSample *out, int nsamples_in, int nsamples_out, int nch); + + + +private: + void BuildLowPass(double filtpos); + void inline SincSample(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, int nch, WDL_SincFilterSample *filter, int filtsz); + void inline SincSample1(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz); + void inline SincSample2(WDL_ResampleSample *outptr, WDL_ResampleSample *inptr, double fracpos, WDL_SincFilterSample *filter, int filtsz); + + double m_sratein WDL_FIXALIGN; + double m_srateout; + double m_fracpos; + double m_ratio; + double m_filter_ratio; + float m_filterq, m_filterpos; + WDL_TypedBuf m_rsinbuf; + WDL_TypedBuf m_filter_coeffs; + + class WDL_Resampler_IIRFilter; + WDL_Resampler_IIRFilter *m_iirfilter; + + int m_filter_coeffs_size; + int m_last_requested; + int m_filtlatency; + int m_samples_in_rsinbuf; + int m_lp_oversize; + + int m_sincsize; + int m_filtercnt; + int m_sincoversize; + bool m_interp; + bool m_feedmode; + +}; + + + +#endif diff --git a/WDL/rfb_client.cpp b/WDL/rfb_client.cpp new file mode 100644 index 00000000..ce84bdc3 --- /dev/null +++ b/WDL/rfb_client.cpp @@ -0,0 +1,443 @@ +#include "rfb_client.h" +#include "lice/lice.h" + +#include "des.h" + +#define CONNECTION_TIMEOUT 30 +#define NORMAL_TIMEOUT 30 +#define OUR_VERSION_STRING "RFB 003.000\n" + + +//#define WANT_RRE // seems to be broken on many servers + +#define ENCODE_TYPE_RAW 0 +#define ENCODE_TYPE_SCREENSIZE -223 +#define ENCODE_TYPE_RRE 2 +//#define ENCODE_TYPE_CORRE 3 +//#define ENCODE_TYPE_HEXTILE 5 + + +WDL_RFB_Client::WDL_RFB_Client(JNL_IConnection *con, const char *password) +{ + m_skipdata=0; + m_req_x=m_req_y=m_req_w=m_req_h=m_needref=0; + m_errstr=0; + m_state=InitialState; + m_con=con; + m_password.Set(password?password:""); + m_screen_w=m_screen_h=0; + m_remote_ver=0; + instance_data=0; + DrawRectangleCallback=0; + time(&m_lastt); +} + +WDL_RFB_Client::~WDL_RFB_Client() +{ + delete m_con; +} + + +unsigned int WDL_RFB_Client::GetBE(int nb, int queueoffs, bool advance) +{ + unsigned char *buf=m_msg_buf.Get()+queueoffs; + + unsigned int a=0; + if (nb==4) a= (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + else if (nb==3) a=(buf[0]<<16) | (buf[1]<<8) | buf[2]; + else if (nb==2) a=(buf[0]<<8) | (buf[1]); + else if (nb==1) a=(buf[0]); + + if (advance) m_msg_buf.Advance(queueoffs+nb); + + return a; +} + +int WDL_RFB_Client::Run() +{ + if (!m_con||m_state == ErrorState) return -1; + + int cnt=0; + + while (m_state != ErrorState) + { + int bytes_needed=1; + int old_avail = m_msg_buf.Available(); + + switch (m_state) + { + case InitialState: + if (m_msg_buf.Available()>=12) + { + unsigned char *buf = m_msg_buf.Get(); + + if (memcmp(buf,"RFB ",4) || buf[7] != '.'||buf[11] != '\n') + { + m_state=ErrorState; + m_errstr = "Server gave invalid line"; + } + else + { + buf[7]=0; + buf[11]=0; + m_remote_ver = atoi((char*)buf+4)*1000 + atoi((char*)buf+8); + if (m_remote_ver < 3000 || m_remote_ver >= 4000) + { + m_state=ErrorState; + m_errstr = "Server gave invalid version"; + } + else + { + m_con->send_bytes(OUR_VERSION_STRING,strlen(OUR_VERSION_STRING)); + m_state = AuthWaitState; + } + } + m_msg_buf.Advance(12); + } + else bytes_needed=12; + break; + case AuthWaitState: + if (m_msg_buf.Available()>=4) + { + unsigned int type = GetBE(4,0,false); + if (type==0) + { + m_state=ErrorState; + m_errstr = "Server permission denied"; + } + else if (type==1) + { + m_state=ServerInitState; + m_msg_buf.Advance(4); + + char c=1; // allow sharing + m_con->send_bytes(&c,1); + } + else if (type == 2) + { + if (m_msg_buf.Available() >= 4+16) + { + m_msg_buf.Advance(4); + unsigned char challenge[16]; + memcpy(challenge,m_msg_buf.Get(),16); + m_msg_buf.Advance(16); + + unsigned char buf[8]; + memset(buf,0,sizeof(buf)); + memcpy(buf,m_password.Get(),min(strlen(m_password.Get()),8)); + WDL_DES des; + des.SetKey(buf,true); + des.Process8(challenge); + des.Process8(challenge+8); + m_con->send_bytes(challenge,16); + m_state=AuthWaitState2; + } + else bytes_needed=4+16; + } + else + { + m_state=ErrorState; + m_errstr = "Unknown authentication method"; + } + } + else bytes_needed=4; + break; + case AuthWaitState2: + if (m_msg_buf.Available()>=4) + { + unsigned int type = GetBE(); + if (type==0) + { + m_state=ServerInitState; + + char c=1; // allow sharing + m_con->send_bytes(&c,1); + } + else + { + m_state=ErrorState; + m_errstr = type==1 ? "Auth failed" : type==2 ? "Too many connections" : "Auth failed (unknown reason)"; + } + } + else bytes_needed=4; + break; + case ServerInitState: + { + if (m_msg_buf.Available()>=2+2+16+4) + { + unsigned int nl = GetBE(4,2+2+16,false); + if (m_msg_buf.Available()>=2+2+16+4 + nl) + { + m_screen_w = GetBE(2); + m_screen_h = GetBE(2); + + m_msg_buf.Advance(16+4); // skip color map and length + + memcpy(m_namebuf.Resize(nl+1),m_msg_buf.Get(),nl); + m_msg_buf.Advance(nl); + m_namebuf.Get()[nl]=0; + + // request our pixel format + + { + unsigned char buf[20]={0,}; + buf[0] = 0; // request pixel format + // 3 bytes padding + buf[4] = 32; + buf[5] = 24; + buf[6] = 0; // always LE + buf[7] = 1; // true-color + + buf[8] = 0; buf[9]=255; // masks + buf[10] = 0; buf[11]=255; + buf[12] = 0; buf[13]=255; + + buf[14] = LICE_PIXEL_R*8; // shifts + buf[15] = LICE_PIXEL_G*8; + buf[16] = LICE_PIXEL_B*8; + + // 3 bytes padding + + m_con->send_bytes(buf,sizeof(buf)); + } + // request encodings + { + const int encs[]={ +#ifdef WANT_RRE + ENCODE_TYPE_RRE, +#endif + ENCODE_TYPE_RAW,ENCODE_TYPE_SCREENSIZE,}; + const int nencs = sizeof(encs)/sizeof(encs[0]); + + unsigned char buf[4+nencs*4]={0,}; + buf[0]=2; //encodings + buf[2] = (nencs>>8)&0xff; + buf[3] = nencs&0xff; + int x; + for(x=0;x>24)&0xff; + buf[4+x*4+1] = (encs[x]>>16)&0xff; + buf[4+x*4+2] = (encs[x]>>8)&0xff; + buf[4+x*4+3] = (encs[x])&0xff; + } + m_con->send_bytes(buf,sizeof(buf)); + } + + m_state=RunState; + m_needref=2; + } + else bytes_needed=2+2+16+4+nl; + } + else bytes_needed=2+2+16+4; + } + break; + case RunState: + + if (m_needref) + { + unsigned char buf[10]={0,}; + buf[0]=3; + buf[1]=(m_needref & 2)?false:true; + if (!m_req_w || !m_req_h) + { + buf[6]=(m_screen_w>>8)&0xff; + buf[7]=m_screen_w&0xff; + buf[8]=(m_screen_h>>8)&0xff; + buf[9]=m_screen_h&0xff; + } + else + { + buf[2]=(m_req_x>>8)&0xff; + buf[3]=m_req_x&0xff; + buf[4]=(m_req_x>>8)&0xff; + buf[5]=m_req_x&0xff; + buf[6]=(m_req_w>>8)&0xff; + buf[7]=m_req_w&0xff; + buf[8]=(m_req_h>>8)&0xff; + buf[9]=m_req_h&0xff; + } + m_needref=0; + m_con->send_bytes(buf,sizeof(buf)); + } + + if (m_skipdata>0) + { + int a= min(m_msg_buf.Available(),m_skipdata); + m_msg_buf.Advance(a); + m_skipdata-=a; + } + + if (m_msg_buf.Available()>0) + { + m_skipdata=0; + unsigned char msg = *(unsigned char *)m_msg_buf.Get(); + switch (msg) + { + case 0: // framebuffer update + if (m_msg_buf.Available() >= 4) + { + unsigned char *buf=m_msg_buf.Get(); + m_msg_buf.Advance(4); + + m_msg_state=(buf[2]<<8)+buf[3]; + if (m_msg_state>0) + { + m_state=RunState_GettingRects; + } + } + else bytes_needed=4; + break; + case 1: // color map crap + if (m_msg_buf.Available()>=6) + { + m_skipdata = GetBE(2,4)*6; // skip 4 bytes, read 2, then skip that + } + break; + case 2: // bell, skip + m_msg_buf.Advance(1); + break; + case 3: // copy text, skip + if (m_msg_buf.Available()>=8) + { + m_skipdata=GetBE(4,4); // skip 4 bytes, read 4 + } + break; + default: + m_state=ErrorState; + sprintf(tmperrbuf,"Got unknown message: %d",msg); + m_errstr=tmperrbuf; + break; + } + } + break; + case RunState_GettingRects: + if (m_msg_state>0) + { + if (m_msg_buf.GetSize()>=12) + { + int xpos = GetBE(2,0,false); + int ypos = GetBE(2,2,false); + int w=GetBE(2,4,false); + int h=GetBE(2,6,false); + int enc = GetBE(4,8,false); + + switch (enc) + { + case ENCODE_TYPE_SCREENSIZE: + { + if (w>m_screen_w || h>m_screen_h) m_needref=2; + m_screen_w = w; + m_screen_h = h; + m_msg_buf.Advance(12); + } + break; + case ENCODE_TYPE_RRE: + if (m_msg_buf.GetSize()>=12+8) + { + unsigned int nr = GetBE(4,12,false); + if (m_msg_buf.GetSize()>=12+8 + nr*12) + { + LICE_pixel bgc = GetBE(4,12+4); + if (DrawRectangleCallback) + { + m_bm.resize(w,h); + LICE_FillRect(&m_bm,0,0,w,h,bgc,1.0f,LICE_BLIT_MODE_COPY); + + while (nr-->0) + { + bgc=GetBE(); + int lx=GetBE(2); + int ly=GetBE(2); + int lw=GetBE(2); + int lh=GetBE(2); + LICE_FillRect(&m_bm,lx,ly,lw,lh,bgc,1.0f,LICE_BLIT_MODE_COPY); + } + + DrawRectangleCallback(this,&m_bm,xpos,ypos,w,h); + } + else m_msg_buf.Advance(nr*12); + + --m_msg_state; + } + else bytes_needed = 12+8 + nr*12; + } + else bytes_needed=12+8; + break; + case ENCODE_TYPE_RAW: // raw + if (m_msg_buf.GetSize()>=12+w*h*4) // we only support 32bpp for now + { + if (DrawRectangleCallback) + { + LICE_pixel *src = (LICE_pixel *)(m_msg_buf.Get()+12); + m_bm.resize(w,h); + LICE_pixel *out = m_bm.getBits(); + int rs = m_bm.getRowSpan(); + int a; + for (a=0;arun(); + + while (m_msg_buf.Available()recv_bytes_available(); + if (a>0) + { + m_con->recv_bytes(m_msg_buf.Add(NULL,a),a); + time(&m_lastt); + } + else break; + + m_con->run(); + } + + if (old_avail == m_msg_buf.Available()|| + m_msg_buf.Available() m_lastt+(m_state < RunState ? CONNECTION_TIMEOUT : NORMAL_TIMEOUT) || m_con->get_state()==JNL_Connection::STATE_CLOSED|| m_con->get_state()==JNL_Connection::STATE_ERROR) + { + m_state=ErrorState; + m_errstr = "Timed out"; + } + + return cnt>0; +} + diff --git a/WDL/rfb_client.h b/WDL/rfb_client.h new file mode 100644 index 00000000..d69483cb --- /dev/null +++ b/WDL/rfb_client.h @@ -0,0 +1,70 @@ +#ifndef _WDL_RFBCLIENT_H_ +#define _WDL_RFBCLIENT_H_ + +#include "wdlstring.h" +#include "queue.h" +#include "jnetlib/jnetlib.h" +#include "lice/lice.h" + +class WDL_RFB_Client +{ +public: + WDL_RFB_Client(JNL_IConnection *con, const char *password); + ~WDL_RFB_Client(); + + int GetScreenWidth() { return m_screen_w; } + int GetScreenHeight() { return m_screen_h; } + + int Run(); // <0 on disconnect, + const char *GetError() { return m_errstr; } + + void Invalidate() { m_needref=2; } // tell server to re-send + void SetUpdateRegion(int x, int y, int w, int h) // if w or h are 0 then whole screen is used + { + m_req_x=x; + m_req_y=y; + m_req_w=w; + m_req_h=h; + + } + void RequestUpdate() { m_needref|=1; } + + void *instance_data; + void (*DrawRectangleCallback)(WDL_RFB_Client *_this, LICE_IBitmap *drawimg, int dest_x, int dest_y, int dest_w, int dest_h); + + +private: + + enum { ErrorState=-1, InitialState=0, AuthWaitState, AuthWaitState2, ServerInitState, RunState, RunState_GettingRects}; + + int m_remote_ver; // xxxyyy + + int m_state; + time_t m_lastt; + const char *m_errstr; + + WDL_String m_password; + JNL_IConnection *m_con; + + int m_screen_w, m_screen_h; + + int m_req_x,m_req_y,m_req_w,m_req_h, m_needref; + + WDL_TypedBuf m_namebuf; + WDL_TypedQueue m_msg_buf; + + int m_skipdata; + + int m_msg_state; // state specific value / data + + unsigned int GetBE(int nb=4, int queueoffs=0, bool advance=true); + + LICE_MemBitmap m_bm; + + char tmperrbuf[128]; +}; + + + + +#endif//_WDL_RFBCLIENT_H_ \ No newline at end of file diff --git a/WDL/rng.cpp b/WDL/rng.cpp new file mode 100644 index 00000000..073abbd1 --- /dev/null +++ b/WDL/rng.cpp @@ -0,0 +1,95 @@ +/* + WDL - rng.cpp + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides the implementation of a decent random number generator, + that internally uses a 256-bit state, and SHA-1 to iterate. + +*/ + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif +#endif + + +#include "rng.h" +#include "sha.h" + +static unsigned char state[32]; + +void WDL_RNG_addentropy(void *buf, int buflen) +{ + WDL_SHA1 tmp; + tmp.add(state,sizeof(state)); + tmp.result(state); + tmp.reset(); + tmp.add((unsigned char *)buf,buflen); + tmp.result(state+sizeof(state) - WDL_SHA1SIZE); +} + +static void rngcycle() +{ + int i; + for (i = 0; i < (int)sizeof(state) && state[i]++; i++); +} + +int WDL_RNG_int32() +{ + WDL_SHA1 tmp; + tmp.add(state,sizeof(state)); + rngcycle(); + union { + char buf[WDL_SHA1SIZE]; + int a; + } b; + tmp.result(b.buf); + return b.a; + +} + + +void WDL_RNG_bytes(void *buf, int buflen) +{ + char *b=(char *)buf; + while (buflen > 0) + { + char tb[WDL_SHA1SIZE]; + WDL_SHA1 tmp; + tmp.add(state,sizeof(state)); + rngcycle(); + + tmp.result(tb); + int l=min(buflen,WDL_SHA1SIZE); + memcpy(b,tb,l); + buflen-=l; + b+=l; + } +} + diff --git a/WDL/rng.h b/WDL/rng.h new file mode 100644 index 00000000..873486c7 --- /dev/null +++ b/WDL/rng.h @@ -0,0 +1,42 @@ +/* + WDL - rng.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This header provides the interface to a decent random number generator, + that internally uses a 256-bit state, and SHA-1 to iterate. We wouldn't consider + this RNG to be cryptographically secure, but it may be decent. + +*/ + +#ifndef _WDL_RNG_H_ +#define _WDL_RNG_H_ + + +void WDL_RNG_addentropy(void *buf, int buflen); // add entropy to the RNG + +int WDL_RNG_int32(); // get a random integer +void WDL_RNG_bytes(void *buf, int buflen); // get a random string of bytes + + +#endif + diff --git a/WDL/rpool.h b/WDL/rpool.h new file mode 100644 index 00000000..47f05bee --- /dev/null +++ b/WDL/rpool.h @@ -0,0 +1,186 @@ +/* + WDL - rpool.h + Copyright (C) 2006 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file defines a template for a class that stores a list of objects, and allows the caller + to periodically get an object, do something with it, and add it back into the pool. + + When the caller does this, it can set ownership of the object, and an expiration for that ownership. + + + The PTYPE1 and PTYPE2entries for the template are there to store additional information (for use with poollist.h) + + + This is pretty esoteric. But we use it for some things. + +*/ + + +#ifndef _WDL_RPOOL_H_ +#define _WDL_RPOOL_H_ + +// resource pool (time based) + +#include "ptrlist.h" +#include "mutex.h" + +class WDL_ResourcePool_ResInfo // include in class RTYPE as WDL_ResourcePool_ResInfo m_rpoolinfo; +{ +public: + WDL_ResourcePool_ResInfo(){ m_owneduntil=0; m_ownerptr=0; next=0; } + ~WDL_ResourcePool_ResInfo() {} + + unsigned int m_owneduntil; + void *m_ownerptr; + + void *next; +} WDL_FIXALIGN; + + +template class WDL_ResourcePool +{ + public: + WDL_ResourcePool(char *identstr) + { + WDL_POOLLIST_refcnt=0; + WDL_POOLLIST_identstr=identstr; + m_rlist=NULL; + extraInfo=0; + m_hadres=false; + } + ~WDL_ResourcePool() + { + while (m_rlist) + { + RTYPE *tp=m_rlist; + m_rlist=(RTYPE *)m_rlist->m_rpoolinfo.next; + delete tp; + } + delete extraInfo; + } + void Clear() + { + m_mutex.Enter(); + while (m_rlist) + { + RTYPE *tp=m_rlist; + m_rlist=(RTYPE *)m_rlist->m_rpoolinfo.next; + delete tp; + } + m_hadres=false; + m_mutex.Leave(); + } + bool HasResources() + { + return m_hadres; + } + + void AddResource(RTYPE *item, void *own, unsigned int until) + { + item->m_rpoolinfo.m_ownerptr = own; + item->m_rpoolinfo.m_owneduntil = until; + + m_mutex.Enter(); + item->m_rpoolinfo.next = m_rlist; + m_rlist = item; + m_hadres=true; + m_mutex.Leave(); + } + + void ReleaseResources(void *own) + { + m_mutex.Enter(); + RTYPE *ent=m_rlist; + while (ent) + { + if (ent->m_rpoolinfo.m_ownerptr == own) + { + ent->m_rpoolinfo.m_ownerptr = 0; + ent->m_rpoolinfo.m_owneduntil=0; + } + ent=(RTYPE *)ent->m_rpoolinfo.next; + } + m_mutex.Leave(); + } + + RTYPE *GetResource(void *own, unsigned int now) + { + m_mutex.Enter(); + RTYPE *ent=m_rlist, *lastent=NULL, *bestent=NULL, *bestlastent=NULL; + bool bestnoown=false; + while (ent) + { + if (ent->m_rpoolinfo.m_ownerptr == own) + { + if (lastent) lastent->m_rpoolinfo.next = ent->m_rpoolinfo.next; + else m_rlist = (RTYPE *)ent->m_rpoolinfo.next; + m_mutex.Leave(); + return ent; + } + + if (!bestnoown && (!ent->m_rpoolinfo.m_ownerptr || ent->m_rpoolinfo.m_owneduntil < now)) + { + bestent=ent; + bestlastent=lastent; + if (!ent->m_rpoolinfo.m_ownerptr || !ent->m_rpoolinfo.m_owneduntil) bestnoown=true; + } + lastent=ent; + ent=(RTYPE *)ent->m_rpoolinfo.next; + } + + if (bestent) + { + if (bestlastent) bestlastent->m_rpoolinfo.next = bestent->m_rpoolinfo.next; + else m_rlist = (RTYPE *)bestent->m_rpoolinfo.next; + } + + m_mutex.Leave(); + return bestent; + } + + int WDL_POOLLIST_refcnt; + char *WDL_POOLLIST_identstr; + bool m_hadres; + + EXTRAINFOTYPE *extraInfo; + + RTYPE *PeekList() + { + return m_rlist; + } + void LockList() + { + m_mutex.Enter(); + } + void UnlockList() + { + m_mutex.Leave(); + } + +private: + + WDL_Mutex m_mutex; + RTYPE *m_rlist; + +} WDL_FIXALIGN; + + + +#endif diff --git a/WDL/sc_bounce/stream-config.php b/WDL/sc_bounce/stream-config.php new file mode 100644 index 00000000..5ec731e7 --- /dev/null +++ b/WDL/sc_bounce/stream-config.php @@ -0,0 +1,21 @@ + array("password" => "somePassword", "listen_password" => "",), + +); + + +// performance tweaks ( safe to leave these as is for now ) + +$config_num_files = 4; +$config_file_timeout = 30; + +?> diff --git a/WDL/sc_bounce/stream.php b/WDL/sc_bounce/stream.php new file mode 100644 index 00000000..7ce2e64b --- /dev/null +++ b/WDL/sc_bounce/stream.php @@ -0,0 +1,243 @@ + $now-60)) && ($oldest_index<0 || $t < $oldest_time)) + { + $oldest_index = $x; + $oldest_time = $t; + } +} + + +if ($is_bc) +{ + if (trim($_POST['broadcast']) != $this_stream["password"]) + { + header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Password"); + die("invalid password"); + } + + if (!$_FILES || !($file = $_FILES["file"])) die("no file sent"); + + if (!is_dir($config_temp_dir)) @mkdir($config_temp_dir,0775); + + $sessinfo = read_session_file($sessfn); + + $last_sess = $sessinfo[0]; + $this_sess = filter_var($_REQUEST['session'],FILTER_SANITIZE_NUMBER_INT); + + if ($last_sess != $this_sess || + rtrim($_REQUEST['name']) != $sessinfo[1] || + rtrim($_REQUEST['title']) != $sessinfo[2] ) + write_session_file($sessfn,$this_sess,$_REQUEST['name'],$_REQUEST['title']); + + if ($last_sess != $this_sess) + { + for ($x = 0; $x < $config_num_files; $x ++) @unlink($fns[$x]); // clear out history + $oldest_index=0; + } + else if ($oldest_index<0) $oldest_index=0; + + @unlink($fns[$oldest_index]); + +// echo "suc maybe: '" . $file["tmp_name"] . "' to '" . $fns[$oldest_index] . "' '" . $file["size"] . "'\n"; + move_uploaded_file($file["tmp_name"], $fns[$oldest_index]); + die; +} + +// stream, validate password if set +if ($this_stream["listen_password"] != "" && + $this_stream["listen_password"] != trim($_REQUEST["password"])) +{ + header($_SERVER["SERVER_PROTOCOL"] . " 401 Invalid Stream Password"); + die("invalid password"); +} + +// make sure stream is up + +// advance past old item since it'll likely get replaced soon +if ($oldest_index>=0) +{ + $oldest_index += 1; + if ($oldest_index >= $config_num_files) $oldest_index = 0; +} + +if ($oldest_index < 0 || !($fp = @fopen($fns[$oldest_index],"rb"))) +{ + header($_SERVER["SERVER_PROTOCOL"] . " 403 Stream Inactive"); + die("stream inactive"); +} +$sessinfo = read_session_file($sessfn); +$sesstime = filemtime($sessfn); + +if ($_REQUEST['get'] == "title") die($sessinfo[2]); + +set_time_limit(3600*3); +header("Content-type: audio/x-mpeg"); +header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 +header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past +$streamname = trim($sessinfo[1]); +if ($streamname != "") header("icy-name: $streamname"); + +$want_title = rtrim($sessinfo[2]); + +$meta_block = ""; +$meta_int=$meta_pos=0; + +if ((int)$_SERVER['HTTP_ICY_METADATA'] > 0) +{ + $meta_int = 32000; + header("icy-metaint: $meta_int"); + if ($_SERVER["SERVER_PROTOCOL"] != "HTTP/1.0") + { + // VLC requires an invalid content-length to prevent chunked mode + if (strstr($_SERVER["HTTP_USER_AGENT"],"VLC")) header("Content-length:-1"); + } +} + +while (!connection_aborted()) +{ + if (!$fp) + { + clearstatcache(); + if ( ($t=@filemtime($fns[$oldest_index])) >= $oldest_time && + @filesize($fns[$oldest_index])>0 && + ($fp = @fopen($fns[$oldest_index],"rb"))) + { + $oldest_time = $t; + if ($meta_int > 0 && $want_title == "") + { + $t = filemtime($sessfn); + if ($t > $sesstime) + { + $oldtitle = rtrim($sessinfo[2]); + $sessinfo = read_session_file($sessfn); + $sesstime=$t; + if ($oldtitle != rtrim($sessinfo[2])) $want_title = rtrim($sessinfo[2]); + } + } + } + else + { + if (time() > $last_read_time + $config_file_timeout) + { + break; + } + usleep(250000); + } + } + else + { + $rdamt = 4096; + if ($meta_int > 0 && $rdamt > ($meta_int-$meta_pos)) $rdamt = ($meta_int - $meta_pos); + $buf = fread($fp,$rdamt); + if ($buf == '') + { + fclose($fp); + $fp = 0; + + $oldest_index += 1; + if ($oldest_index >= $config_num_files) $oldest_index = 0; + } + else + { + echo $buf; + $last_read_time = time(); + + if ($meta_int > 0) + { + $meta_pos += strlen($buf); + if ($meta_pos >= $meta_int) + { + $meta_pos=0; + if ($want_title != "") + { + $want_title = str_replace("'","",$want_title); + $want_title = "StreamTitle='$want_title';"; + $tb=(int) (((strlen($want_title) + 1 + 15)/16)); + echo chr($tb); + echo $want_title; + $tb = $tb*16 - strlen($want_title); + while ($tb-- > 0) echo chr(0); + $want_title=""; + } + else echo chr(0); + $meta_block = ""; + } + } + } + } +} + +if ($fp) fclose($fp); + + +?> diff --git a/WDL/scsrc.cpp b/WDL/scsrc.cpp new file mode 100644 index 00000000..3d9a7f35 --- /dev/null +++ b/WDL/scsrc.cpp @@ -0,0 +1,700 @@ +/* + WDL - scsrc.cpp + Copyright (C) 2007, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + + +*/ + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#include +typedef int DWORD; + +static void Sleep(int ms) +{ + usleep(ms?ms*1000:100); +} + +static unsigned int GetTickCount() +{ + struct timeval tm={0,}; + gettimeofday(&tm,NULL); + return tm.tv_sec*1000 + tm.tv_usec/1000; +} + +#endif // !_WIN32 + +#include + +#include "scsrc.h" +#include "jnetlib/jnetlib.h" +#include "wdlcstring.h" + +// maybe we need to do this better someday +#define POST_DIV_STRING "zzzASFIJAHFASJFHASLKFHZI8" +#define END_POST_BYTES "\r\n--" POST_DIV_STRING "--\r\n" + + +#define ERR_NOLAME -600 +#define ERR_CREATINGENCODER -599 + +#define ERR_TIMEOUT -4 +#define ERR_CONNECT -5 +#define ERR_AUTH -6 + +#define ST_OK 0 +#define ST_CONNECTING 1 +#define ERR_DISCONNECTED_AFTER_SUCCESS 32 +WDL_ShoutcastSource::WDL_ShoutcastSource(const char *host, const char *pass, const char *name, bool pub, + const char *genre, const char *url, + int nch, int srate, int kbps, const char *ircchan) +{ + m_post_postsleft=0; + m_postmode_session=GetTickCount(); + m_is_postmode = !!strstr(host,"/"); + + totalBitrate=0; + sendProcessor=0; + userData=0; + + JNL::open_socketlib(); + m_host.Set(host); + m_pass.Set(pass); + if (name) m_name.Set(name); + if (url) m_url.Set(url); + if (genre) m_genre.Set(genre); + if (ircchan) m_ircchan.Set(ircchan); + m_pub=pub; + m_br=kbps; + + m_state=ST_CONNECTING; // go to 0 when we + m_nch=nch==2?2:1; + m_bytesout=0; + m_srate=srate; + m_last_samples[0]=m_last_samples[1]=0.0; + m_rspos=0.0; + m_sendcon=0; + + m_needtitle=0; + m_title[0]=0; + m_titlecon=0; + m_titlecon_start=0; + m_encoder_splsin=0; + m_encoder=new LameEncoder(m_srate,m_nch,m_br); + int s=m_encoder->Status(); + if (s == 1) m_state=ERR_NOLAME; + else if (s) m_state=ERR_CREATINGENCODER; + + if (s) { delete m_encoder; m_encoder=0; } + + m_sendcon_start=time(NULL); + if (m_encoder) + { + if (m_is_postmode) + { + PostModeConnect(); + } + else + { + m_sendcon = new JNL_Connection(JNL_CONNECTION_AUTODNS,65536,65536); + WDL_String hb(m_host.Get()); + int port=8000; + char *p=strstr(hb.Get(),":"); + if (p) + { + *p++=0; + port = atoi(p); + if (!port) port=8000; + } + m_sendcon->connect(hb.Get(), port+1); + + m_sendcon->send_string(m_pass.Get()); + m_sendcon->send_string("\r\n"); + } + } + +} + +WDL_ShoutcastSource::~WDL_ShoutcastSource() +{ + delete m_titlecon; + delete m_sendcon; + delete m_encoder; +} + +int WDL_ShoutcastSource::GetStatus() // returns 0 if connected/connecting, >0 if disconnected, -1 if failed connect (or other error) from the start +{ + if (m_state= ERR_DISCONNECTED_AFTER_SUCCESS) return m_state; + return 0; +} + +void WDL_ShoutcastSource::GetStatusText(char *buf, int bufsz) // gets status text +{ + if (m_state == ST_OK) snprintf(buf,bufsz,"Connected. Sent %u bytes",m_bytesout); + else if (m_state == ST_CONNECTING) lstrcpyn_safe(buf,"Connecting...",bufsz); + else if (m_state == ERR_DISCONNECTED_AFTER_SUCCESS) snprintf(buf,bufsz,"Disconnected after sending %u bytes",m_bytesout); + else if (m_state == ERR_AUTH) lstrcpyn_safe(buf,"Error authenticating with server",bufsz); + else if (m_state == ERR_CONNECT) lstrcpyn_safe(buf,"Error connecting to server",bufsz); + else if (m_state == ERR_TIMEOUT) lstrcpyn_safe(buf,"Timed out connecting to server",bufsz); + else if (m_state == ERR_CREATINGENCODER) lstrcpyn_safe(buf,"Error creating encoder",bufsz); + else if (m_state == ERR_NOLAME) + #ifdef _WIN32 + lstrcpyn_safe(buf,"Error loading lame_enc.dll",bufsz); + #else + lstrcpyn_safe(buf,"Error loading libmp3lame.dylib",bufsz); + #endif + else lstrcpyn_safe(buf,"Error creating encoder",bufsz); + +} + +void WDL_ShoutcastSource::SetCurTitle(const char *title) +{ + m_titlemutex.Enter(); + lstrcpyn_safe(m_title,title,sizeof(m_title)); + m_needtitle=true; + m_titlemutex.Leave(); + +} + +void WDL_ShoutcastSource::OnSamples(float **samples, int nch, int chspread, int frames, double srate) +{ + m_samplemutex.Enter(); + + if (fabs(srate-m_srate)<1.0) + { + float *ob=m_rsbuf.Resize(frames*m_nch,false); + int x=frames; + int a=0; + if (nch < 2 && m_nch < 2) + { + while (x--) + { + *ob++ = samples[0][a]; + a+=chspread; + } + } + else if (nch < 2 && m_nch > 1) + { + while (x--) + { + ob[0] = ob[1] = samples[0][a]; + ob+=2; + a+=chspread; + } + } + else if (nch > 1 && m_nch > 1) + { + while (x--) + { + *ob++ = samples[0][a]; + *ob++ = samples[1][a]; + a+=chspread; + } + } + else + { + while (x--) + { + *ob++ = (samples[0][a]+samples[1][a])*0.5f; + a+=chspread; + } + } + if (m_samplequeue.Available() < (int)sizeof(float)*m_nch*96000*4 && + m_encoder && m_encoder->outqueue.Available() < 256*1024) + m_samplequeue.Add(m_rsbuf.Get(),frames*m_nch*sizeof(float)); + } + else + { + double rateratio = srate/m_srate; + + double fracpos=m_rspos; + int outlen=(int) ((frames+fracpos)/rateratio); + float *outptr=m_rsbuf.Resize(outlen*m_nch,false); + + int x; + int loffs=-1000; + double ls[2]={m_last_samples[0],m_last_samples[1]}; + for (x = 0; x < outlen; x ++) + { + int ioffs=(int)fracpos; + double fp=fracpos-ioffs; + + ioffs *= chspread; + + if (ioffs>0) + { + ls[0]=samples[0][ioffs-chspread]; + ls[1]=samples[nch-1][ioffs-chspread]; + } + + if (m_nch>1) + { + *outptr++ = (float) (samples[0][ioffs] * fp + ls[0]*(1-fp)); + if (nch>1) + *outptr++ = (float) (samples[1][ioffs] * fp + ls[1]*(1-fp)); + else + { + *outptr = outptr[-1]; + outptr++; + } + } + else + { + if (nch>1) + { + *outptr++ = (float) (((samples[0][ioffs]+samples[1][ioffs]) * fp + (ls[0]+ls[1])*(1-fp))*0.5); + } + else + *outptr++ = (float) (samples[0][ioffs] * fp + ls[0]*(1-fp)); + + } + + fracpos += rateratio; + } + m_last_samples[0]=samples[0][frames-1]; + m_last_samples[1]=samples[nch-1][frames-1]; + + if (m_samplequeue.Available() < (int)sizeof(float)*m_nch*96000*4 && + m_encoder && m_encoder->outqueue.Available() < 256*1024) + m_samplequeue.Add(m_rsbuf.Get(),outlen*m_nch*sizeof(float)); + + m_rspos=fracpos - floor(fracpos); + } + + m_samplemutex.Leave(); +} + + +static void url_encode(char *in, char *out, int max_out) +{ + while (*in && max_out > 4) + { + if ((*in >= 'A' && *in <= 'Z')|| + (*in >= 'a' && *in <= 'z')|| + (*in >= '0' && *in <= '9')|| *in == '.' || *in == '_' || *in == '-') + { + *out++=*in++; + max_out--; + } + else + { + int i=*in++; + *out++ = '%'; + int b=(i>>4)&15; + if (b < 10) *out++='0'+b; + else *out++='A'+b-10; + b=i&15; + if (b < 10) *out++='0'+b; + else *out++='A'+b-10; + max_out-=3; + } + } + *out=0; +} + +int WDL_ShoutcastSource::RunStuff() +{ + int ret=0; + // run connection + + if (m_sendcon) + { + if (m_encoder && m_encoder_splsin > 48000*60*60*3) // every 3 hours, reinit the mp3 encoder + { + m_encoder_splsin=0; + + WDL_Queue tmp; + if (m_encoder->outqueue.GetSize()) tmp.Add(m_encoder->outqueue.Get(),m_encoder->outqueue.GetSize()); + + delete m_encoder; + + int s=2; + m_encoder=new LameEncoder(m_srate,m_nch,m_br); + if (m_encoder && !(s=m_encoder->Status())) + { + // copy out queue from m_encoder to newnc + if (tmp.GetSize()) m_encoder->outqueue.Add(tmp.Get(),tmp.GetSize()); + } + else + { + if (s == 1) m_state=ERR_NOLAME; + else if (s) m_state=ERR_CREATINGENCODER; + delete m_encoder; + m_encoder=0; + } + + } + + if (m_encoder) + { + // encode data from m_samplequeue + int n=32; + int maxl=1152*2; + m_workbuf.Resize(maxl); + while (n--) + { + m_samplemutex.Enter(); + int d=m_samplequeue.Available()/sizeof(float); + if (d > 0) + { + if (d>maxl) d=maxl; + m_samplequeue.GetToBuf(0,m_workbuf.Get(),d*sizeof(float)); + m_samplequeue.Advance(d*sizeof(float)); + } + m_samplemutex.Leave(); + + if (!d) break; + + m_encoder_splsin+=d/m_nch; + m_encoder->Encode(m_workbuf.Get(),d/m_nch,1); + ret=1; + } + + if (m_encoder->outqueue.Available() > 128*1024) + { + m_encoder->outqueue.Advance(m_encoder->outqueue.Available()-64*1024); + } + + if (m_state==ST_OK) + { + WDL_Queue *srcq = &m_encoder->outqueue; + + if (sendProcessor) + { + sendProcessor(userData,&m_procdata,srcq); + srcq = &m_procdata; + } + + + int mb=srcq->Available(); + int mb2=m_sendcon->send_bytes_available(); + + if (mb>mb2) mb=mb2; + + if (m_is_postmode) + { + if (m_post_bytesleft<=0) PostModeConnect(); + + if (mb>m_post_bytesleft) mb = m_post_bytesleft; + } + + if (mb>0) + { + m_bytesout+=mb; + m_sendcon->send_bytes(srcq->Get(),mb); + if (m_is_postmode) m_post_bytesleft-=mb; + srcq->Advance(mb); + srcq->Compact(); + ret=1; + } + } + } + + m_sendcon->run(); + int s = m_sendcon->get_state(); + + if (m_state == ST_CONNECTING) + { + if (m_is_postmode) + { + m_state=ST_OK; + } + else if (m_sendcon->recv_lines_available()>0) + { + char buf[4096]; + m_sendcon->recv_line(buf, 4095); + if (strcmp(buf, "OK2")) + { + m_state=ERR_AUTH; + delete m_sendcon; + m_sendcon=0; + } + else + { + m_state=ST_OK; + m_sendcon->send_string("icy-name:"); + m_sendcon->send_string(m_name.Get()); + m_sendcon->send_string("\r\n"); + m_sendcon->send_string("icy-genre:"); + m_sendcon->send_string(m_genre.Get()); + m_sendcon->send_string("\r\n"); + m_sendcon->send_string("icy-pub:"); + m_sendcon->send_string(m_pub ? "1":"0"); + m_sendcon->send_string("\r\n"); + m_sendcon->send_string("icy-br:"); + char buf[64]; + snprintf(buf,sizeof(buf),"%d",totalBitrate ? totalBitrate : m_br); + m_sendcon->send_string(buf); + m_sendcon->send_string("\r\n"); + m_sendcon->send_string("icy-url:"); + m_sendcon->send_string(m_url.Get()); + m_sendcon->send_string("\r\n"); + if (m_ircchan.Get()[0]) + { + m_sendcon->send_string("icy-irc:"); + m_sendcon->send_string(m_ircchan.Get()); + m_sendcon->send_string("\r\n"); + } + m_sendcon->send_string("icy-genre:"); + m_sendcon->send_string(m_genre.Get()); + m_sendcon->send_string("\r\n"); + m_sendcon->send_string("icy-reset:1\r\n\r\n"); + } + } + } + if (!m_is_postmode) switch (s) + { + case JNL_Connection::STATE_ERROR: + case JNL_Connection::STATE_CLOSED: + if (m_state==ST_OK) m_state=ERR_DISCONNECTED_AFTER_SUCCESS; + else if (m_state>ST_OK && m_state < ERR_DISCONNECTED_AFTER_SUCCESS) m_state = ERR_CONNECT; + + delete m_sendcon; + m_sendcon=0; + break; + default: + if (m_state > ST_OK && m_state < ERR_DISCONNECTED_AFTER_SUCCESS && time(NULL) > m_sendcon_start+30) + { + m_state=ERR_TIMEOUT; + delete m_sendcon; + m_sendcon=0; + } + + break; + } + } + + if (m_titlecon) + { + if (m_titlecon->run() || time(NULL) > m_titlecon_start+30) + { + delete m_titlecon; + m_titlecon=0; + } + } + + if (m_needtitle && m_state==ST_OK && !m_is_postmode) + { + char title[512]; + m_titlemutex.Enter(); + url_encode(m_title,title,sizeof(title)-1); + m_needtitle=false; + m_titlemutex.Leave(); + + + WDL_String url; + url.Append("http://"); + url.Append(m_host.Get()); + url.Append("/admin.cgi?pass="); + url.Append(m_pass.Get()); + url.Append("&mode=updinfo&song="); + + url.Append(title); + + delete m_titlecon; + m_titlecon=new JNL_HTTPGet; + m_titlecon->addheader("User-Agent:Cockos WDL scsrc (Mozilla)"); + m_titlecon->addheader("Accept:*/*"); + m_titlecon->connect(url.Get()); + m_titlecon_start=time(NULL); + } + + return ret; +} + +static void AddTextField(WDL_String *s, const char *name, const char *value) +{ + s->AppendFormatted(4096,"--" POST_DIV_STRING "\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + name, + value); +} + +void WDL_ShoutcastSource::PostModeConnect() +{ + const char *hsrc = m_host.Get(); + if (!strnicmp(hsrc,"http://",7)) hsrc+=7; + WDL_String hb(hsrc); + int port=80; + char zb[32]={0,}; + char *req = zb, *parms=zb; + char *p=hb.Get(); + while (*p && *p != ':' && *p != '/' && *p != '?') p++; + if (*p == ':') + { + *p++=0; + port = atoi(p); + if (!port) port=80; + } + while (*p && *p != '/' && *p != '?') p++; + if (*p == '/') + { + *p++=0; + req = p; + } + while (*p && *p != '?') p++; + if (*p == '?') + { + *p++=0; + parms = p; + } + + bool allowReuse=false; + + if (m_sendcon) + { + m_sendcon->send_string(END_POST_BYTES); + m_sendcon->run(); + DWORD start=GetTickCount(); + bool done=false,hadResp=false; + while (GetTickCount() < start+1000 && !done) + { + Sleep(50); + m_sendcon->run(); + if (m_sendcon->get_state() == JNL_Connection::STATE_ERROR || + m_sendcon->get_state() > JNL_Connection::STATE_CONNECTED) break; + + while (m_sendcon->recv_lines_available()>0) + { + char buf[4096]; + m_sendcon->recv_line(buf, 4095); +// OutputDebugString(buf); + + if (!strnicmp(buf,"HTTP/",5)) hadResp=true; + if (!strnicmp(buf,"HTTP/1.1",8)) allowReuse=true; + + const char *con="Connection:"; + if (!strnicmp(buf,con,strlen(con))) + { + char *p=buf+strlen(con); + while (*p == ' ') p++; + if (!strnicmp(p,"close",5)) allowReuse=false; + else if (!strnicmp(p,"keep-alive",10)) allowReuse=true; + + done=true; + } + if (hadResp && (!buf[0] || buf[0] == '\r' || buf[0] == '\n')) + done=true; + + } + } + } + + if (m_sendcon) m_sendcon->run(); + + if (m_sendcon && + (!allowReuse || m_post_postsleft<=0 || + m_sendcon->get_state() == JNL_Connection::STATE_ERROR || + m_sendcon->get_state() > JNL_Connection::STATE_CONNECTED)) + + { + delete m_sendcon; + m_sendcon=0; + } + + if (!m_sendcon) + { +// OutputDebugString("new connection\n"); + m_sendcon = new JNL_Connection(JNL_CONNECTION_AUTODNS,65536,65536); + m_sendcon->connect(hb.Get(),port); + m_post_postsleft=16; // todo: some configurable amt? + } + + int csize = (totalBitrate ? totalBitrate*2 : m_br) * 2000 / 8 + 512; // 2s of audio plus pad + if (csize<16384) csize=16384; + + + WDL_String tmp; + tmp.SetFormatted(4096,"POST /%s HTTP/1.1\r\n" + "Connection: %s\r\n" + "Host: %s\r\n" + "User-Agent: WDLScSrc(Mozilla)\r\n" + "MIME-Version: 1.0\r\n" + "Content-type: multipart/form-data; boundary=" POST_DIV_STRING "\r\n" + "Content-length: %d\r\n" + "\r\n", + req, + --m_post_postsleft > 0 ? "Keep-Alive" : "close", + hb.Get(), + csize); + m_sendcon->send_string(tmp.Get()); + + m_post_bytesleft = csize - strlen(END_POST_BYTES); + + tmp.Set(""); + + p = parms; + while (*p) + { + char *eq = p; + while (*eq && *eq != '=') eq++; + if (!*eq) break; + *eq++=0; + char *np = eq; + while (*np && *np != '&') np++; + + AddTextField(&tmp,p,eq); + + + if (!*np) break; + p=np+1; + } + + AddTextField(&tmp,"broadcast",m_pass.Get()); + + if (m_title[0]) + { + m_titlemutex.Enter(); + if (m_title[0]) AddTextField(&tmp,"title",m_title); + m_titlemutex.Leave(); + } + + AddTextField(&tmp,"name",m_name.Get()); + + + { + char buf[512]; + sprintf(buf,"%u",m_postmode_session); + AddTextField(&tmp,"session",buf); + } + + tmp.AppendFormatted(4096,"--" POST_DIV_STRING "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"bla.dat\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-transfer-encoding: binary\r\n" + ); + + + tmp.Append("\r\n"); + + m_sendcon->send_string(tmp.Get()); + m_post_bytesleft -= strlen(tmp.Get()); + +} \ No newline at end of file diff --git a/WDL/scsrc.h b/WDL/scsrc.h new file mode 100644 index 00000000..289fb9c4 --- /dev/null +++ b/WDL/scsrc.h @@ -0,0 +1,114 @@ +/* + WDL - scsrc.h + Copyright (C) 2007, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides for an object to source a SHOUTcast (www.shoutcast.com) stream. + It uses the lameencdec.h interface (and lame_enc.dll) to encode, and JNetLib to send the data. + + + This object will not auto-reconnect on disconnect. If GetStatus() returns error, the callee needs to + delete the object and create a new one. + + +*/ + + +#ifndef _WDL_SCSRC_H_ +#define _WDL_SCSRC_H_ + +#include +#include "jnetlib/connection.h" +#include "jnetlib/httpget.h" +#include "lameencdec.h" +#include "wdlstring.h" +#include "fastqueue.h" +#include "queue.h" +#include "mutex.h" + +class WDL_ShoutcastSource +{ +public: + WDL_ShoutcastSource(const char *host, const char *pass, const char *name, bool pub=false, + const char *genre=NULL, const char *url=NULL, + + int nch=2, int srate=44100, int kbps=128, + const char *ircchan=NULL + ); + ~WDL_ShoutcastSource(); + + int GetStatus(); // returns 0 if connected/connecting, >0 if disconnected, -1 if failed connect (or other error) from the start + void GetStatusText(char *buf, int bufsz); // gets status text + + void SetCurTitle(const char *title); + + int GetSampleRate() { return m_srate; } + void OnSamples(float **samples, int nch, int chspread, int frames, double srate); + int RunStuff(); // returns nonzero if work done + + + void *userData; + int totalBitrate; // 0 for normal, otherwise if using NSV (below) set to kbps of total stream + // allows hooking to say, I dunno, package in some other format such as NSV? + void (*sendProcessor)(void *userData, WDL_Queue *dataout, WDL_Queue *data); + + int GetAudioBitrate() { return m_br*1000; } + +private: + + WDL_Queue m_procdata; + + LameEncoder *m_encoder; + int m_encoder_splsin; + + WDL_String m_host,m_pass,m_url,m_genre,m_name,m_ircchan; + int m_br; + bool m_pub; + + time_t m_titlecon_start,m_sendcon_start; + + unsigned int m_bytesout; + int m_state; + int m_nch,m_srate; + + double m_last_samples[2] WDL_FIXALIGN; + double m_rspos; // last resample fractional position + + WDL_FastQueue m_samplequeue; // interleaved samples (float) + + JNL_HTTPGet *m_titlecon; + JNL_Connection *m_sendcon; + + WDL_TypedBuf m_workbuf,m_rsbuf; + WDL_Mutex m_samplemutex; + WDL_Mutex m_titlemutex; + char m_title[512]; + bool m_needtitle; + + + bool m_is_postmode; + unsigned int m_postmode_session; + int m_post_bytesleft; + int m_post_postsleft; + + void PostModeConnect(); + +}; + +#endif // _WDL_SCSRC_H_ \ No newline at end of file diff --git a/WDL/sha.cpp b/WDL/sha.cpp new file mode 100644 index 00000000..07bfecaf --- /dev/null +++ b/WDL/sha.cpp @@ -0,0 +1,133 @@ +/* + WDL - sha.cpp + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides the implementation to the WDL_SHA1 object, which performs SHA-1 hashes + on data. + +*/ + +#include "sha.h" + +/// sha + +WDL_SHA1::WDL_SHA1() +{ + reset(); +} + +void WDL_SHA1::reset() +{ + lenW = 0; + size[0] = size[1] = 0; + H[0] = 0x67452301; + H[1] = 0xefcdab89; + H[2] = 0x98badcfe; + H[3] = 0x10325476; + H[4] = 0xc3d2e1f0; + int x; + for (x = 0; x < (int)(sizeof(W)/sizeof(W[0])); x ++) W[x]=0; +} + + +#define SHA_ROTL(X,n) ((((X)&0xffffffff) << (n)) | (((X)&0xffffffff) >> (32-(n)))) +#define SHUFFLE() E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP + +void WDL_SHA1::add(const void *data, int datalen) +{ + int i; + for (i = 0; i < datalen; i++) + { + W[lenW / 4] <<= 8; + W[lenW / 4] |= (unsigned int)((const unsigned char *)data)[i]; + if (!(++lenW & 63)) + { + int t; + + unsigned int A = H[0]; + unsigned int B = H[1]; + unsigned int C = H[2]; + unsigned int D = H[3]; + unsigned int E = H[4]; + + + for (t = 16; t < 80; t++) W[t] = SHA_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); + + for (t = 0; t < 20; t++) + { + unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x5a827999 + (((C^D)&B)^D); + SHUFFLE(); + } + for (; t < 40; t++) + { + unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x6ed9eba1 + (B^C^D); + SHUFFLE(); + } + for (; t < 60; t++) + { + unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0x8f1bbcdc + ((B&C)|(D&(B|C))); + SHUFFLE(); + } + for (; t < 80; t++) + { + unsigned int TEMP = SHA_ROTL(A,5) + E + W[t] + 0xca62c1d6 + (B^C^D); + SHUFFLE(); + } + + H[0] += A; + H[1] += B; + H[2] += C; + H[3] += D; + H[4] += E; + + lenW = 0; + } + size[0] += 8; + if (size[0] < 8) size[1]++; + } +} + +void WDL_SHA1::result(void *out) +{ + unsigned char pad0x80 = 0x80; + unsigned char pad0x00 = 0x00; + unsigned char padlen[8]; + int i; + padlen[0] = (unsigned char)((size[1] >> 24) & 0xff); + padlen[1] = (unsigned char)((size[1] >> 16) & 0xff); + padlen[2] = (unsigned char)((size[1] >> 8) & 0xff); + padlen[3] = (unsigned char)((size[1]) & 0xff); + padlen[4] = (unsigned char)((size[0] >> 24) & 0xff); + padlen[5] = (unsigned char)((size[0] >> 16) & 0xff); + padlen[6] = (unsigned char)((size[0] >> 8) & 0xff); + padlen[7] = (unsigned char)((size[0]) & 0xff); + add(&pad0x80, 1); + while (lenW != 56) add(&pad0x00, 1); + add(padlen, 8); + for (i = 0; i < 20; i++) + { + ((unsigned char *)out)[i] = (unsigned char)(H[i / 4] >> 24); + H[i / 4] <<= 8; + } + reset(); +} diff --git a/WDL/sha.h b/WDL/sha.h new file mode 100644 index 00000000..581403bb --- /dev/null +++ b/WDL/sha.h @@ -0,0 +1,54 @@ +/* + WDL - sha.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This header provides an interface to the WDL_SHA1 object, which performs SHA-1 hashes + on data. +*/ + +#ifndef _WDL_SHA_H_ +#define _WDL_SHA_H_ + + +#define WDL_SHA1SIZE 20 + +// sha + +class WDL_SHA1 { + +public: + WDL_SHA1(); + void add(const void *data, int datalen); + void result(void *out); + void reset(); + +private: + + unsigned int H[5]; + unsigned int W[80]; + int lenW; + unsigned int size[2]; +}; + +#endif + diff --git a/WDL/sharedpool.h b/WDL/sharedpool.h new file mode 100644 index 00000000..60b208d5 --- /dev/null +++ b/WDL/sharedpool.h @@ -0,0 +1,128 @@ +/* + WDL - sharedpool.h + Copyright (C) 2006 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + + This file defines a template for a simple object pool. + + Objects are keyed by string (filename, or otherwise). The caller can add or get an object, + increase or decrease its reference count (if it reaches zero the object is deleted). + + + If you delete the pool itself, all objects are deleted, regardless of their reference count. + +*/ + + +#ifndef _WDL_SHAREDPOOL_H_ +#define _WDL_SHAREDPOOL_H_ + +#include "ptrlist.h" + +template class WDL_SharedPool +{ + public: + WDL_SharedPool() { } + ~WDL_SharedPool() { m_listobjk.Empty(true); /* do not release m_list since it's redundant */ } + + void Add(OBJ *obj, const char *n) // no need to AddRef() after add, it defaults to a reference count of 1. + { + if (obj && n) + { + Ent *p = new Ent(obj,n); + m_list.InsertSorted(p,_sortfunc_name); + m_listobjk.InsertSorted(p,_sortfunc_obj); + } + } + + OBJ *Get(const char *s) + { + struct { void *obj; const char *name; } tmp = { NULL, s }; + Ent *t = m_list.Get(m_list.FindSorted((Ent *)&tmp,_sortfunc_name)); + + if (t && t->obj) + { + t->refcnt++; + return t->obj; + } + + return 0; + + } + + void AddRef(OBJ *obj) + { + Ent *ent = m_listobjk.Get(m_listobjk.FindSorted((Ent *)&obj,_sortfunc_obj)); + if (ent) ent->refcnt++; + } + + void Release(OBJ *obj) + { + int x = m_listobjk.FindSorted((Ent *)&obj,_sortfunc_obj); + Ent *ent = m_listobjk.Get(x); + if (ent && !--ent->refcnt) + { + m_list.Delete(m_list.FindSorted(ent,_sortfunc_name)); + m_listobjk.Delete(x,true); + } + } + + OBJ *EnumItems(int x) + { + Ent *e=m_list.Get(x); + return e?e->obj:NULL; + } + + private: + + class Ent + { + public: + OBJ *obj; // this order is used elsewhere for its own advantage + char *name; + + int refcnt; + + Ent(OBJ *o, const char *n) { obj=o; name=strdup(n); refcnt=1; } + ~Ent() { delete obj; free(name); } + + }; + + + + static int _sortfunc_name(const Ent **a, const Ent **b) + { + return stricmp((*a)->name,(*b)->name); + } + static int _sortfunc_obj(const Ent **a, const Ent **b) + { + if ((INT_PTR)(*a)->obj < (INT_PTR)(*b)->obj) return -1; + if ((INT_PTR)(*a)->obj > (INT_PTR)(*b)->obj) return 1; + return 0; + } + + WDL_PtrList m_list, // keyed by name + m_listobjk; // keyed by OBJ + + +}; + + +#endif//_WDL_SHAREDPOOL_H_ diff --git a/WDL/shm_connection.cpp b/WDL/shm_connection.cpp new file mode 100644 index 00000000..ed76e243 --- /dev/null +++ b/WDL/shm_connection.cpp @@ -0,0 +1,521 @@ +#include "shm_connection.h" + +#ifdef _WIN32 +#define SHM_MINSIZE 64 +#define SHM_HDRSIZE (4+4*4+2) + // 4 bytes: buffer size (each channel) + // 4 bytes: read pointer chan 0 + // 4 bytes: write pointer chan 0 + // 4 bytes: read pointer chan 1 + // 4 bytes: write pointer chan 1 + // 2 bytes: chan 0 refresh, chan 1 refresh + // data follows (2x buffer size) + + +WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, + const char *uniquestring, // identify + int shmsize, // bytes, whoever opens first decides + int timeout_sec, + int extra_flags // unused on win32 + + ) +{ + m_timeout_cnt=0; + m_timeout_sec=timeout_sec; + m_last_recvt=time(NULL)+2; // grace period + { // make shmsize the next power of two + int a = shmsize; + shmsize=2; + while (shmsize < SHM_MINSIZE || shmsize0) + { + DWORD d; + int a = sz; + if (a>sizeof(buf))a=sizeof(buf); + WriteFile(m_file,buf,a,&d,NULL); + sz-=a; + *(int *)buf = 0; + } + } + + if (m_file!=INVALID_HANDLE_VALUE) + m_filemap=CreateFileMapping(m_file,NULL,PAGE_READWRITE,0,0,NULL); + + if (m_filemap) + { + m_mem=(unsigned char *)MapViewOfFile(m_filemap,FILE_MAP_WRITE,0,0,0); + + tmp.Get()[tmp_l]=0; + tmp.Append(".1"); + m_events[0]=CreateEvent(NULL,false,false,tmp.Get()); + tmp.Get()[strlen(tmp.Get())-1]++; + m_events[1]=CreateEvent(NULL,false,false,tmp.Get()); + } + + if (mutex) + { + ReleaseMutex(mutex); + CloseHandle(mutex); + } + +} + + +WDL_SHM_Connection::~WDL_SHM_Connection() +{ + if (m_mem) UnmapViewOfFile(m_mem); + if (m_filemap) CloseHandle(m_filemap); + if (m_file != INVALID_HANDLE_VALUE) CloseHandle(m_file); + DeleteFile(m_tempfn.Get()); + + if (m_events[0]) CloseHandle(m_events[0]); + if (m_events[1]) CloseHandle(m_events[1]); + if (m_lockmutex) + { + ReleaseMutex(m_lockmutex); + CloseHandle(m_lockmutex); + } +} + +bool WDL_SHM_Connection::WantSendKeepAlive() { return false; } + +int WDL_SHM_Connection::Run() +{ + if (!m_mem) return -1; + + int *hdr = (int *)m_mem; + + int shm_size = hdr[0]; + + // todo: check to see if we just opened, if so, have a grace period + if (shm_size < SHM_MINSIZE) return -1; + + m_mem[4*5 + !!m_whichChan] = 1; + if (m_timeout_sec > 0) + { + if (m_mem[4*5 + !m_whichChan]) + { + m_timeout_cnt=0; + m_last_recvt=time(NULL); + m_mem[4*5 + !m_whichChan]=0; + } + else + { + if (time(NULL) > m_timeout_sec+m_last_recvt) + { + if (m_timeout_cnt >= 4) return -1; + + m_timeout_cnt++; + m_last_recvt=time(NULL); + } + } + } + + int didStuff=0; + + // process writes + int send_avail=send_queue.Available(); + if (send_avail>0) + { + int wc = !m_whichChan; + unsigned char *data=m_mem+SHM_HDRSIZE+shm_size*wc; + int rdptr = hdr[1 + wc*2]; // hopefully atomic + int wrptr = hdr[1 + wc*2+1]; + int wrlen = shm_size - (wrptr-rdptr); + if (wrlen > 0) + { + if (wrlen > send_avail) wrlen=send_avail; + if (wrlen > shm_size) wrlen=shm_size; // should never happen ! + + int idx = wrptr & (shm_size-1); + int l = shm_size - idx; + if (l > wrlen) l = wrlen; + memcpy(data+idx,send_queue.Get(),l); + if (l < wrlen) memcpy(data,(char*)send_queue.Get() + l,wrlen-l); + + hdr[1 + wc*2+1] = wrptr + wrlen; // advance write pointer, hopefluly atomic + + didStuff|=1; + + send_queue.Advance(wrlen); + send_queue.Compact(); + + } + } + + // process reads + { + int wc = m_whichChan; + unsigned char *data=m_mem+SHM_HDRSIZE+shm_size*wc; + int rdptr = hdr[1 + wc*2]; + int wrptr = hdr[1 + wc*2+1]; // hopefully atomic + int rdlen = wrptr-rdptr; + if (rdlen > 0) + { + if (rdlen > shm_size) rdlen=shm_size; // should never happen ! + + int idx = rdptr & (shm_size-1); + int l = shm_size - idx; + if (l > rdlen) l = rdlen; + recv_queue.Add(data+idx,l); + if (l < rdlen) recv_queue.Add(data,rdlen-l); + + hdr[1 + wc*2] = wrptr; // hopefully atomic, bring read pointer up to write pointer + didStuff|=2; + } + } + + if (didStuff) + { + if (m_events[!m_whichChan]) SetEvent(m_events[!m_whichChan]); + return 1; + } + + + return 0; +} + + +#else + +#include +#include +#include +#include +#include +#include +#include +#ifndef __APPLE__ +#include +#endif +#include "swell/swell-internal.h" + +static void sigpipehandler(int sig) { } + +// socket version +WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, // first created must be whichChan=0 + const char *uniquestring, // identify + int shmsize, + int timeout_sec, + int extra_flags // set 1 for lockfile use on master + ) +{ + m_sockbufsize = shmsize; + if (m_sockbufsize<16384) m_sockbufsize=16384; + else if (m_sockbufsize>1024*1024) m_sockbufsize=1024*1024; + + m_rdbufsize = min(m_sockbufsize,65536); + m_rdbuf = (char *)malloc(m_rdbufsize); + + static bool hasSigHandler; + if (!hasSigHandler) + { + signal(SIGPIPE,sigpipehandler); + hasSigHandler=true; + } + m_timeout_cnt=0; + m_timeout_sec=timeout_sec; + m_last_recvt=time(NULL)+3; // grace period + m_next_keepalive = time(NULL)+1; + + m_tempfn.Set("/tmp/WDL_SHM."); + m_tempfn.Append(uniquestring); + m_tempfn.Append(".tmp"); + + + m_sockaddr=malloc(sizeof(struct sockaddr_un) + strlen(m_tempfn.Get())); + m_lockhandle=-1; + m_listen_socket=-1; + m_socket=-1; + m_waitevt=0; + m_whichChan = whichChan; + + struct sockaddr_un *addr = (struct sockaddr_un *)m_sockaddr; + addr->sun_family = AF_UNIX; + strcpy(addr->sun_path,m_tempfn.Get()); + #ifdef __APPLE__ + int l = SUN_LEN(addr)+1; + if (l>255)l=255; + addr->sun_len=l; + #endif + + if (!whichChan) + { + if (extra_flags & 1) + { + m_lockfn.Set(m_tempfn.Get()); + m_lockfn.Append(".lock"); + m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT,0666); + if (m_lockhandle < 0) return; // error getting lockfile, fail + if (flock(m_lockhandle,LOCK_NB|LOCK_EX) < 0) + { + close(m_lockhandle); + m_lockhandle=-1; + return; // could not lock + } + } + acquireListener(); + if (m_listen_socket<0) return; + } + else + { + struct stat sbuf; + if (stat(addr->sun_path,&sbuf)) + { + return; // fail + } + + int s = socket(AF_UNIX,SOCK_STREAM,0); + if (s<0) return; + + int bsz=m_sockbufsize; + setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&bsz,sizeof(bsz)); + bsz=m_sockbufsize; + setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&bsz,sizeof(bsz)); + + if (connect(s,(struct sockaddr*)addr,SUN_LEN(addr))) + { + close(s); + } + else + { + fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); + m_socket=s; + + // clean up the filesystem, our connection has been made + unlink(m_tempfn.Get()); + } + } + + if (m_socket>=0 || m_listen_socket>=0) + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)malloc(sizeof(SWELL_InternalObjectHeader_SocketEvent)); + memset(se,0,sizeof(SWELL_InternalObjectHeader_SocketEvent)); + se->hdr.type = INTERNAL_OBJECT_EXTERNALSOCKET; + se->hdr.count = 1; + se->socket[0]=m_socket>=0? m_socket : m_listen_socket; + m_waitevt = (HANDLE)se; + } +} + +WDL_SHM_Connection::~WDL_SHM_Connection() +{ + if (m_listen_socket>=0 || m_socket>=0) + { + if (m_socket>=0) close(m_socket); + if (m_listen_socket>=0) close(m_listen_socket); + + // only delete temp socket file if the master and successfully had something open + if (!m_whichChan && m_tempfn.Get()[0]) unlink(m_tempfn.Get()); + } + + free(m_waitevt); // don't CloseHandle(), since it's just referencing our socket + free(m_sockaddr); + free(m_rdbuf); + + if (m_lockhandle>=0) + { + flock(m_lockhandle,LOCK_UN); + close(m_lockhandle); + unlink(m_lockfn.Get()); + } +} + +bool WDL_SHM_Connection::WantSendKeepAlive() +{ + return !send_queue.GetSize() && time(NULL) >= m_next_keepalive; +} + + +int WDL_SHM_Connection::Run() +{ + if (m_socket < 0) + { + if (m_listen_socket < 0) return -1; + + struct sockaddr_un remote={0,}; + socklen_t t = sizeof(struct sockaddr_un); + int s = accept(m_listen_socket,(struct sockaddr *)&remote,&t); + if (s>=0) + { + close(m_listen_socket); + m_listen_socket=-1; + + fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); // nonblocking + + int bsz=m_sockbufsize; + setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&bsz,sizeof(bsz)); + bsz=m_sockbufsize; + setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&bsz,sizeof(bsz)); + + if (m_waitevt) + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)m_waitevt; + se->socket[0]=s; + } + m_socket=s; + } + else + { + if (m_timeout_sec>0 && time(NULL) > m_timeout_sec+m_last_recvt) + { + if (m_timeout_cnt >= 2) return -1; + m_timeout_cnt++; + m_last_recvt=time(NULL); + } + return 0; + } + } + + bool sendcnt=false; + bool recvcnt=false; + for (;;) + { + bool hadAct=false; + while (recv_queue.Available()<128*1024*1024) + { + int n=read(m_socket,m_rdbuf,m_rdbufsize); + if (n>0) + { + recv_queue.Add(m_rdbuf,n); + hadAct=true; + recvcnt=true; + } + else if (n<0&&errno!=EAGAIN) goto abortClose; + else break; + } + while (send_queue.Available()>0) + { + int n = send_queue.Available(); + if (n > m_rdbufsize) n=m_rdbufsize; + n = write(m_socket,send_queue.Get(),n); + if (n > 0) + { + hadAct=true; + sendcnt=true; + send_queue.Advance(n); + } + else if (n<0&&errno!=EAGAIN) goto abortClose; + else break; + } + if (!hadAct) break; + } + if (sendcnt) send_queue.Compact(); + + if (m_timeout_sec>0) + { + time_t now = time(NULL); + if (recvcnt) + { + m_last_recvt=now; + m_timeout_cnt=0; + } + else if (now > m_timeout_sec+m_last_recvt) + { + if (m_timeout_cnt >= 3) return -1; + m_timeout_cnt++; + m_last_recvt=now; + } + + if (sendcnt||send_queue.GetSize()) m_next_keepalive = now + (m_timeout_sec+1)/2; + } + + return sendcnt||recvcnt; + +abortClose: + if (m_whichChan) return -1; + + acquireListener(); + recv_queue.Clear(); + send_queue.Clear(); + if (m_waitevt) + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent*)m_waitevt; + se->socket[0]=m_listen_socket; + } + close(m_socket); + m_socket=-1; + + return m_listen_socket >= 0 ? 0 : -1; +} + +void WDL_SHM_Connection::acquireListener() +{ + // only ever called from whichChan==0 + if (m_listen_socket>=0) return; // no need to re-open + + unlink(m_tempfn.Get()); + + int s = socket(AF_UNIX,SOCK_STREAM,0); + if (s<0) return; + struct sockaddr_un *addr = (struct sockaddr_un *)m_sockaddr; + if (bind(s,(struct sockaddr*)addr,SUN_LEN(addr)) < 0 || listen(s,1) < 0) + { + close(s); + } + else + { + fcntl(s, F_SETFL, fcntl(s,F_GETFL) | O_NONBLOCK); + m_listen_socket = s; + } +} +#endif diff --git a/WDL/shm_connection.h b/WDL/shm_connection.h new file mode 100644 index 00000000..ca012713 --- /dev/null +++ b/WDL/shm_connection.h @@ -0,0 +1,87 @@ +#ifndef _WDL_SHM_CONNECTION_H_ +#define _WDL_SHM_CONNECTION_H_ + +#ifdef _WIN32 +#include +#else +#include "swell/swell.h" +#include "swell/swell-internal.h" +#endif + +#include + +#include "wdlstring.h" +#include "wdltypes.h" +#include "queue.h" + +class WDL_SHM_Connection +{ +public: + WDL_SHM_Connection(bool whichChan, // a true con connects to a false con -- note on SHM false should be created FIRST. + const char *uniquestring, // identify + int shmsize=262144, // bytes, whoever opens first decides + int timeout_sec=0, + int extra_flags=0 // on posix, set 1 for the master to create a .lock file as well + ); + + ~WDL_SHM_Connection(); + + int Run(); // call as often as possible, returns <0 error, >0 if did something + + bool WantSendKeepAlive(); // called when it needs a keepalive to be sent (may be never, or whatever interval it decides) + + // wait for this if you want to see when data comes in + HANDLE GetWaitEvent() + { + #ifdef _WIN32 + return m_events[m_whichChan]; + #else + return m_waitevt; + #endif + } + + // receiving and sending data + WDL_Queue recv_queue; + WDL_Queue send_queue; + + +private: + + + int m_timeout_sec; + time_t m_last_recvt; + int m_timeout_cnt; + + WDL_String m_tempfn; + + int m_whichChan; // which channel we read from + +#ifdef _WIN32 + + HANDLE m_file, m_filemap; + HANDLE m_events[2]; // [m_whichChan] set when the other side did something useful + HANDLE m_lockmutex; + + unsigned char *m_mem; +#else + time_t m_next_keepalive; + + int m_sockbufsize; + + int m_rdbufsize; + char *m_rdbuf; // m_rdbufsize + + int m_listen_socket; + int m_socket; + + HANDLE m_waitevt; + void *m_sockaddr; + + void acquireListener(); + WDL_String m_lockfn; + int m_lockhandle; +#endif + +}; + +#endif diff --git a/WDL/shm_msgreply.cpp b/WDL/shm_msgreply.cpp new file mode 100644 index 00000000..a99f1507 --- /dev/null +++ b/WDL/shm_msgreply.cpp @@ -0,0 +1,346 @@ +#include "shm_msgreply.h" +#include "wdlcstring.h" + +//#define VERIFY_MESSAGES // this is not endian-aware (so it'll fail if enabled and doing ppc<->x86 etc) +#ifdef VERIFY_MESSAGES +#define WDL_SHA1 WDL_SHA1_msgreplydef +#include "sha.cpp" +#endif + +SHM_MsgReplyConnection::SHM_MsgReplyConnection(int bufsize, int maxqueuesize, bool dir, const char *uniquestr, int timeout_sec, int extra_flags) +{ + m_maxqueuesize=maxqueuesize; + m_has_had_error=false; + userData=0; + OnRecv=0; + IdleProc=0; + m_lastmsgid=1; + m_shm = 0; + m_spares=0; + m_waiting_replies=0; + + if (uniquestr) lstrcpyn_safe(m_uniq,uniquestr,sizeof(m_uniq)); + else + { +#ifdef _WIN32 + WDL_INT64 pid = (WDL_INT64) GetCurrentProcessId(); +#else + WDL_INT64 pid = (WDL_INT64) getpid(); +#endif + WDL_INT64 thisptr = (WDL_INT64) (INT_PTR) this; + static int cnt=0xdeadf00d; + sprintf(m_uniq,"%08x%08x%08x%08x", + (int)(pid&0xffffffff), + (int)(pid>>32), + (int)(thisptr&0xffffffff) ^ GetTickCount(), + (int)(thisptr>>32)^(cnt++)); + } + + m_shm = new WDL_SHM_Connection(dir,m_uniq,bufsize,timeout_sec,extra_flags); + +} + +SHM_MsgReplyConnection::~SHM_MsgReplyConnection() +{ + delete m_shm; + WaitingMessage *tmp=m_waiting_replies; + while (tmp) + { + WaitingMessage *p=tmp; + tmp=tmp->_next; + delete p; + } + tmp=m_spares; + while (tmp) + { + WaitingMessage *p=tmp; + tmp=tmp->_next; + delete p; + } +} + +void SHM_MsgReplyConnection::Reply(int msgID, const void *msg, int msglen) +{ + if (msgID) Send(0,msg,msglen,NULL,0,&msgID); +} + + +int SHM_MsgReplyConnection::Send(int type, const void *msg, int msglen, + void *replybuf, int maxretbuflen, const int *forceMsgID, + const void *secondchunk, int secondchunklen, + WDL_HeapBuf *hbreplyout) +{ + if (!m_shm||m_has_had_error) return -1; + + if (secondchunk && secondchunklen>0) msglen+=secondchunklen; + else secondchunklen=0; + + int msgid; + { + WDL_MutexLock lock(&m_shmmutex); + m_shm->send_queue.AddDataToLE(&type,4,4); + + if (forceMsgID) msgid = *forceMsgID; + else + { + if (!replybuf&&!hbreplyout) msgid=0; + else if (!(msgid = ++m_lastmsgid)) msgid = ++m_lastmsgid; + } + + m_shm->send_queue.AddDataToLE(&msgid,4,4); + m_shm->send_queue.AddDataToLE(&msglen,4,4); + if (msglen>secondchunklen) m_shm->send_queue.Add(msg,msglen-secondchunklen); + if (secondchunklen>0) m_shm->send_queue.Add(secondchunk,secondchunklen); + +#ifdef VERIFY_MESSAGES + WDL_SHA1 t; + t.add(&type,4); + t.add(&msgid,4); + t.add(&msglen,4); + if (msglen>secondchunklen) t.add(msg,msglen-secondchunklen); + if (secondchunklen>0) t.add(secondchunk,secondchunklen); + + char tb[WDL_SHA1SIZE]; + t.result(tb); + m_shm->send_queue.Add(tb,sizeof(tb)); +#endif + + + if ((!replybuf && !hbreplyout) || !msgid) m_shm->Run(); // get this reply out ASAP + } + + if ((hbreplyout||replybuf) && msgid) + { + int wait_cnt=30; // dont run idleproc for first Xms or so + + while (!m_has_had_error) + { + if (wait_cnt<=0 && IdleProc && IdleProc(this)) + { + m_has_had_error=true; + break; + } + + WaitingMessage *msg=NULL; + bool r = RunInternal(msgid,&msg); + + if (msg) + { + int rv = msg->m_msgdata.GetSize(); + + if (hbreplyout) + { + memcpy(hbreplyout->Resize(rv,false),msg->m_msgdata.Get(),rv); + } + + if (replybuf) + { + if (rv > maxretbuflen) rv=maxretbuflen; + if (rv>0) memcpy(replybuf,msg->m_msgdata.Get(),rv); + } + + m_shmmutex.Enter(); + msg->_next = m_spares; + m_spares=msg; + m_shmmutex.Leave(); + return rv; + } + else if (r) break; + + + if (wait_cnt>0) wait_cnt--; + + HANDLE evt=m_shm->GetWaitEvent(); + if (evt) WaitForSingleObject(evt,1); + else Sleep(1); + + } + } + + if (hbreplyout) hbreplyout->Resize(0,false); + + return -1; +} + +void SHM_MsgReplyConnection::Wait(HANDLE extraEvt) +{ + HANDLE evt=m_shm ? m_shm->GetWaitEvent() : extraEvt; + if (evt && extraEvt && evt != extraEvt) + { + HANDLE hds[2] = {evt,extraEvt}; +#ifdef _WIN32 + WaitForMultipleObjects(2,hds,FALSE,1); +#else + WaitForAnySocketObject(2,hds,1); +#endif + } + else if (evt) WaitForSingleObject(evt,1); + else Sleep(1); +} + +void SHM_MsgReplyConnection::ReturnSpares(WaitingMessage *msglist) +{ + if (msglist) + { + WaitingMessage *msgtail = msglist; + while (msgtail && msgtail->_next) msgtail=msgtail->_next; + + m_shmmutex.Enter(); + msgtail->_next = m_spares; + m_spares=msglist; + m_shmmutex.Leave(); + } +} + +bool SHM_MsgReplyConnection::Run(bool runFull) +{ + if (m_has_had_error) return true; + + if (runFull) return RunInternal(); + + m_shmmutex.Enter(); + int s=m_shm->Run(); + if (m_shm->send_queue.Available() > m_maxqueuesize) s=-1; + m_shmmutex.Leave(); + + if (s<0) m_has_had_error=true; + else if (m_shm && m_shm->WantSendKeepAlive()) + { + int zer=0; + Send(0,NULL,0,NULL,0,&zer); + } + + return s<0; +} + +bool SHM_MsgReplyConnection::RunInternal(int checkForReplyID, WaitingMessage **replyPtr) +{ + if (!m_shm||m_has_had_error) return true; + + if (replyPtr) *replyPtr=0; + + int s=0; + + do + { + m_shmmutex.Enter(); + + // autocompact on first time through + if (!s) m_shm->recv_queue.Compact(); + + s = m_shm->Run(); + if (m_shm->send_queue.Available() > m_maxqueuesize) s=-1; + + while (m_shm->recv_queue.GetSize()>=12) + { + int datasz = *(int *)((char *)m_shm->recv_queue.Get()+8); + WDL_Queue::WDL_Queue__bswap_buffer(&datasz,4); // convert to LE if needed + + if (m_shm->recv_queue.GetSize() < 12 + datasz) break; + +#ifdef VERIFY_MESSAGES + if (m_shm->recv_queue.GetSize() < 12 + datasz + WDL_SHA1SIZE) break; +#endif + + int type = *(int *)((char *)m_shm->recv_queue.Get()); + WDL_Queue::WDL_Queue__bswap_buffer(&type,4); // convert to LE if needed + + WaitingMessage *msg = m_spares; + if (msg) m_spares = m_spares->_next; + else msg = new WaitingMessage; + + msg->m_msgid = *(int *)((char *)m_shm->recv_queue.Get() + 4); + WDL_Queue::WDL_Queue__bswap_buffer(&msg->m_msgid,4); // convert to LE if needed + + msg->m_msgtype = type; + memcpy(msg->m_msgdata.Resize(datasz,false),(char *)m_shm->recv_queue.Get()+12, datasz); + + m_shm->recv_queue.Advance(12+datasz); + +#ifdef VERIFY_MESSAGES + WDL_SHA1 t; + t.add(&type,4); + t.add(&msg->m_msgid,4); + t.add(&datasz,4); + t.add(msg->m_msgdata.Get(),msg->m_msgdata.GetSize()); + char tb[WDL_SHA1SIZE]; + t.result(tb); + if (memcmp(m_shm->recv_queue.Get(),tb,WDL_SHA1SIZE)) + MessageBox(NULL,"FAIL","A",0); + m_shm->recv_queue.Advance(WDL_SHA1SIZE); +#endif + + + if (type==0) + { + if (checkForReplyID && replyPtr && !*replyPtr && + checkForReplyID == msg->m_msgid) + { + *replyPtr = msg; + s=0; + break; // we're done! + } + else + { + msg->_next = m_waiting_replies; + m_waiting_replies = msg; + } + } + else + { + m_shmmutex.Leave(); + + WaitingMessage *msgtail=NULL; + + if (OnRecv) + { + msg->_next=0; + msgtail = msg = OnRecv(this,msg); + while (msgtail && msgtail->_next) msgtail=msgtail->_next; + } + else if (msg->m_msgid) Reply(msg->m_msgid,"",0); // send an empty reply + + m_shmmutex.Enter(); // get shm again + + if (msg) + { + (msgtail?msgtail:msg)->_next = m_spares; + m_spares=msg; + } + } + } // while queue has stuff + + if (checkForReplyID && replyPtr && !*replyPtr) + { + WaitingMessage *m=m_waiting_replies; + WaitingMessage *lp=NULL; + + while (m) + { + if (m->m_msgid == checkForReplyID) + { + if (lp) lp->_next = m->_next; + else m_waiting_replies=m->_next; + + *replyPtr = m; + s=0; // make sure we return ASAP + break; + } + lp = m; + m=m->_next; + } + } + + m_shmmutex.Leave(); + + } while (s>0); + + if (s<0) m_has_had_error=true; + else if (m_shm && m_shm->WantSendKeepAlive()) + { + int zer=0; + Send(0,NULL,0,NULL,0,&zer); + } + return s<0; +} + diff --git a/WDL/shm_msgreply.h b/WDL/shm_msgreply.h new file mode 100644 index 00000000..f5d0ee3f --- /dev/null +++ b/WDL/shm_msgreply.h @@ -0,0 +1,86 @@ +#ifndef _WDL_SHM_MSGREPLY_ +#define _WDL_SHM_MSGREPLY_ + +#include +#include "shm_connection.h" +#include "mutex.h" + + +/* + 4 byte message type + + 4 byte unique message ID (0 for no reply needed/wanted) + + 4 byte message length (following) + + + type: 0 reply + call specific return data + type: all others user defined + +*/ +// type is user defined, however type=0 is reserved for reply +class SHM_MsgReplyConnection +{ + +public: + + class WaitingMessage + { + public: + WaitingMessage() { } + ~WaitingMessage() { } + + WaitingMessage *_next; + + int m_msgid; + int m_msgtype; + + WDL_HeapBuf m_msgdata; + }; + + + SHM_MsgReplyConnection(int bufsize, int maxqueuesize, bool dir, const char *uniquestr=NULL, int timeout_sec=0, int extra_flags=0); + ~SHM_MsgReplyConnection(); + + // be sure to set these, and have OnRecv() Reply() to any nonzero msgID ! + void *userData; + WaitingMessage *(*OnRecv)(SHM_MsgReplyConnection *con, WaitingMessage *msg); + bool (*IdleProc)(SHM_MsgReplyConnection *con); // return TRUE to abort (this will set the m_has_had_error to true / kill the connection) + // can return NULL To temporarily buffer msg, can return a chain of msgs too to return them to the spare list + + // run as you wish, Send() will also run internally when waiting for reply + // note: the checkForReplyID etc are for INTERNAL USE ONLY :) + + bool Run(bool runFull=true); + + // returns <0 if no reply, otherwise lenght of replybuf used + // no retbuf = no wait for reply + int Send(int type, const void *msg, int msglen, + void *replybuf, int maxretbuflen, const int *forceMsgID=NULL, + const void *secondchunk=NULL, int secondchunklen=0, // allow sending two blocks as one message (for speed in certain instances) + WDL_HeapBuf *hbreplyout=NULL); // if hbreplyout is set it will get the full message (replybuf can be NULL then) + void Reply(int msgID, const void *msg, int msglen); + void Wait(HANDLE extraEvt=NULL); + + const char *GetUniqueString() { return m_uniq; } + + void ReturnSpares(WaitingMessage *msglist); + +private: + bool RunInternal(int checkForReplyID=0, WaitingMessage **replyPtr=0); // nonzero on error + + char m_uniq[256]; + WDL_Mutex m_shmmutex; + WDL_SHM_Connection *m_shm; + + + WaitingMessage *m_waiting_replies; + WaitingMessage *m_spares; + + int m_lastmsgid; + int m_maxqueuesize; + bool m_has_had_error; +}; + +#endif diff --git a/WDL/simple_pitchshift.h b/WDL/simple_pitchshift.h new file mode 100644 index 00000000..62db26f7 --- /dev/null +++ b/WDL/simple_pitchshift.h @@ -0,0 +1,311 @@ +#ifndef _WDL_SIMPLEPITCHSHIFT_H_ +#define _WDL_SIMPLEPITCHSHIFT_H_ + + +#include "queue.h" + +#ifndef WDL_SIMPLEPITCHSHIFT_SAMPLETYPE +#define WDL_SIMPLEPITCHSHIFT_SAMPLETYPE double +#endif + + +#ifdef WDL_SIMPLEPITCHSHIFT_PARENTCLASS +class WDL_SimplePitchShifter : public WDL_SIMPLEPITCHSHIFT_PARENTCLASS +#else +class WDL_SimplePitchShifter +#endif +{ +public: + WDL_SimplePitchShifter() + { + m_last_nch=1; + m_srate=44100.0; + m_last_tempo=1.0; + m_last_shift=1.0; + m_qual=0; + + Reset(); + } + ~WDL_SimplePitchShifter() { } + + void Reset() + { + m_hadinput=0; + m_pspos=0.0; + m_pswritepos=0; + m_latpos=0; + m_tempo_fracpos=0.0; + m_queue.Clear(); + m_rsbuf.Resize(0,false); + m_psbuf.Resize(0,false); + } + + bool IsReset() + { + return !m_queue.Available() && !m_hadinput; + } + + + + void set_srate(double srate) { m_srate=srate; } + void set_nch(int nch) { if (m_last_nch!=nch) { m_queue.Clear(); m_last_nch=nch; m_tempo_fracpos=0.0; } } + void set_shift(double shift) { m_last_shift=shift; } + void set_tempo(double tempo) { m_last_tempo=tempo; } + void set_formant_shift(double shift) + { + } + + WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *GetBuffer(int size) + { + return m_inbuf.Resize(size*m_last_nch); + } + void BufferDone(int input_filled); + void FlushSamples() {} + + static const char *enumQual(int q); + static bool GetSizes(int qv, int *ws, int *os); + + int GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer); + + + void SetQualityParameter(int parm) + { + m_qual=parm; + } + + +private: + void PitchShiftBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, double pitch, int bsize, int olsize, double srate); + + +private: + double m_pspos WDL_FIXALIGN; + double m_tempo_fracpos; + double m_srate,m_last_tempo,m_last_shift; + + WDL_TypedBuf m_psbuf; + WDL_Queue m_queue; + WDL_TypedBuf m_inbuf; + WDL_TypedBuf m_rsbuf; + + int m_pswritepos; + int m_last_nch; + int m_qual; + int m_hadinput; + + int m_latpos; + +}; + + +#ifdef WDL_SIMPLEPITCHSHIFT_IMPLEMENT +void WDL_SimplePitchShifter::BufferDone(int input_filled) +{ + // perform pitch shifting + if (input_filled>0) + { + m_hadinput=1; + int ws,os; + GetSizes(m_qual,&ws,&os); + + int bsize=(int) (ws * 0.001 * m_srate); + if (bsize<16) bsize=16; + else if (bsize>128*1024)bsize=128*1024; + + int olsize=(int) (os * 0.001 * m_srate); + if (olsize > bsize/2) olsize=bsize/2; + if (olsize<1)olsize=1; + if (m_psbuf.GetSize() != bsize*m_last_nch) + { + memset(m_psbuf.Resize(bsize*m_last_nch,false),0,sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*bsize*m_last_nch); + m_pspos=(double) (bsize/2); + m_pswritepos=0; + } + + if (fabs(m_last_tempo-1.0)<0.0000000001) + { + PitchShiftBlock(m_inbuf.Get(),(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,input_filled*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)),m_last_nch,input_filled,m_last_shift,bsize,olsize,m_srate); + } + else + { + int needclear=m_rsbuf.GetSize() input_filled) a=input_filled; + m_latpos+=a; + fp += a; + } + + int outlen = (int) (input_filled*itempo-fp) + 128; // upper bound on possible sample count + if (outlen<0) + { + outlen=0; + } + + WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *bufo = (WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,outlen*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); + // resample bufi to bufo + int i,nch=m_last_nch; + for (i = 0; i < outlen; i ++) + { + double rdpos=floor(fp); + int idx=((int)rdpos); + if (idx>=input_filled) + { + // un-add any missing samples + m_queue.Add(NULL,(i-outlen)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); + break; + } + rdpos = (fp-rdpos); + int a; + idx*=nch; + for (a = 0; a < nch; a ++) + { + *bufo++ = bufi[idx+a]*(1.0-rdpos)+bufi[idx+nch+a]*rdpos; + } + fp += tempo; + } + + memcpy(bufi,bufi+m_last_nch*input_filled,m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); // save last sample for interpolation later + // + m_tempo_fracpos=fp-floor(fp); + } + } +} + +const char *WDL_SimplePitchShifter::enumQual(int q) +{ + int ws,os; + if (!GetSizes(q,&ws,&os)) return NULL; + static char buf[128]; + sprintf(buf,"%dms window, %dms fade",ws,os); + return buf; +} + +bool WDL_SimplePitchShifter::GetSizes(int qv, int *ws, int *os) +{ + int windows[]={50,75,100,150,225,300,40,30,20,10,5,3}; + int divs[]={2,3,5,7}; + + int wd=qv/(sizeof(divs)/sizeof(divs[0])); + if (wd >= sizeof(windows)/sizeof(windows[0])) wd=-1; + + *ws=windows[wd>=0?wd:0]; + *os = *ws / divs[qv%(sizeof(divs)/sizeof(divs[0]))]; + if (*os<1) *os=1; + + return wd>=0; +} + +int WDL_SimplePitchShifter::GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer) +{ + if (!m_last_nch||requested_output<1) return 0; + + int l=m_queue.Available()/sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)/m_last_nch; + + if (requested_output>l) requested_output=l; + int sz=requested_output*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*m_last_nch; + memcpy(buffer,m_queue.Get(),sz); + m_queue.Advance(sz); + m_queue.Compact(); + return requested_output; +} + +void WDL_SimplePitchShifter::PitchShiftBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, double pitch, int bsize, int olsize, double srate) +{ + double iolsize=1.0/olsize; + + WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *psbuf=m_psbuf.Get(); + + double dpi=pitch; + + double pspos=m_pspos; + int writepos=m_pswritepos; + int writeposnch = writepos*nch; + int bsizench = bsize*nch; + int olsizench = olsize*nch; + + int i=length; + while (i--) + { + int ipos1=(int)pspos; + double frac0=pspos-ipos1; + + ipos1*=nch; + + int ipos2=ipos1+nch; + + if (ipos2 >= bsizench) ipos2=0; + + int a; + for(a=0;a= 1.0) + { + if (tv > writepos) tv-=bsize; + + if (tv >= writepos-olsize && tv < writepos) + { + double tfrac=(writepos-tv)*iolsize; + int tmp=ipos1+olsizench; + if (tmp>=bsizench) tmp-=bsizench; + int tmp2=tmp+nch; + if (tmp2 >= bsizench) tmp2=0; + + for(a=0;a= writepos) pspos+=olsize; + } + + } + else + { + if (tv= writepos && tv < writepos+olsize) + { + double tfrac=(tv-writepos)*iolsize; + int tmp=ipos1+olsizench; + if (tmp>=bsizench) tmp -= bsizench; + int tmp2= tmp+nch; + if (tmp2 >= bsizench) tmp2=0; + for(a=0;a= writepos+olsize) pspos += olsize; + } + } + + + if ((pspos+=pitch) >= bsize) pspos -= bsize; + + + memcpy(psbuf+writeposnch,inputs,nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); + + writeposnch += nch; + if (++writepos >= bsize) writeposnch = writepos=0; + + inputs += nch; + outputs += nch; + } // sample loop + m_pspos=pspos; + m_pswritepos=writepos; +} + +#endif + +#endif diff --git a/WDL/simple_pitchshift2.h b/WDL/simple_pitchshift2.h new file mode 100644 index 00000000..0d084256 --- /dev/null +++ b/WDL/simple_pitchshift2.h @@ -0,0 +1,315 @@ +#ifndef _WDL_SIMPLEPITCHSHIFT_H_ +#define _WDL_SIMPLEPITCHSHIFT_H_ + + +#include "queue.h" + +#ifndef WDL_SIMPLEPITCHSHIFT_SAMPLETYPE +#define WDL_SIMPLEPITCHSHIFT_SAMPLETYPE double +#endif + + +// this one isnt done yet, but stretches, then (optionally) resamples + +#ifdef WDL_SIMPLEPITCHSHIFT_PARENTCLASS +class WDL_SimplePitchShifter2 : public WDL_SIMPLEPITCHSHIFT_PARENTCLASS +#else +class WDL_SimplePitchShifter2 +#endif +{ +public: + WDL_SimplePitchShifter2() + { + m_last_nch=1; + m_srate=44100.0; + m_last_tempo=1.0; + m_last_shift=1.0; + m_qual=0; + + Reset(); + } + ~WDL_SimplePitchShifter2() { } + + void Reset() + { + m_hadinput=0; + m_pspos=0.0; + m_pswritepos=0; + m_tempo_fracpos=0.0; + m_queue.Clear(); + m_rsbuf.Resize(0,false); + m_psbuf.Resize(0,false); + } + + bool IsReset() + { + return !m_queue.Available() && !m_hadinput; + } + + + + void set_srate(double srate) { m_srate=srate; } + void set_nch(int nch) { if (m_last_nch!=nch) { m_queue.Clear(); m_last_nch=nch; m_tempo_fracpos=0.0; } } + void set_shift(double shift) { m_last_shift=shift; } + void set_tempo(double tempo) { m_last_tempo=tempo; } + void set_formant_shift(double shift) + { + } + + WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *GetBuffer(int size) + { + return m_inbuf.Resize(size*m_last_nch); + } + void BufferDone(int input_filled); + void FlushSamples() {} + + static char *enumQual(int q); + static bool GetSizes(int qv, int *ws, int *os); + + int GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer); + + + void SetQualityParameter(int parm) + { + m_qual=parm; + } + + + int Stretch(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, double srate, int ws_ms, int os_ms); + +private: + int StretchBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, int bsize, int olsize, double srate); + + +private: + double m_pspos WDL_FIXALIGN; + double m_tempo_fracpos; + double m_srate,m_last_tempo,m_last_shift; + + WDL_TypedBuf m_psbuf; + WDL_Queue m_queue; + WDL_TypedBuf m_inbuf; + WDL_TypedBuf m_rsbuf; + + int m_pswritepos; + int m_last_nch; + int m_qual; + int m_hadinput; + +}; + + +#ifdef WDL_SIMPLEPITCHSHIFT_IMPLEMENT +void WDL_SimplePitchShifter2::BufferDone(int input_filled) +{ + if (input_filled>0) + { + m_hadinput=1; + int ws,os; + GetSizes(m_qual,&ws,&os); + int max_outputlen=(int) (input_filled * m_last_shift / m_last_tempo * 1.1f + 32.0f); + + if (fabs(m_last_shift-1.0)<0.0000000001) + { + int valid_amt = Stretch(m_inbuf.Get(),(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *)m_queue.Add(NULL,max_outputlen*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)),m_last_nch, + input_filled,max_outputlen,1.0/m_last_tempo,m_srate,ws,os); + + if (valid_amt < max_outputlen) + m_queue.Add(NULL,(valid_amt-max_outputlen)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); + } + else + { + int needclear=m_rsbuf.GetSize()=valid_amt) + { + // un-add any missing samples + m_queue.Add(NULL,(i-out_max)*m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); + break; + } + rdpos = (fp-rdpos); + int a; + idx*=nch; + for (a = 0; a < nch; a ++) + { + *bufo++ = bufi[idx+a]*(1.0-rdpos)+bufi[idx+nch+a]*rdpos; + } + fp += adv; + } + + memcpy(bufi,bufi+m_last_nch*valid_amt,m_last_nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)); // save last sample for interpolation later + // + m_tempo_fracpos=fp-floor(fp); + } + } +} + +char *WDL_SimplePitchShifter2::enumQual(int q) +{ + int ws,os; + if (!GetSizes(q,&ws,&os)) return NULL; + static char buf[128]; + sprintf(buf,"%dms window, %dms fade",ws,os); + return buf; +} + +bool WDL_SimplePitchShifter2::GetSizes(int qv, int *ws, int *os) +{ + int windows[]={50,75,100,150,225,300,40,30,20,10,5,3}; + int divs[]={2,3,5,7}; + + int wd=qv/(sizeof(divs)/sizeof(divs[0])); + if (wd >= sizeof(windows)/sizeof(windows[0])) wd=-1; + + *ws=windows[wd>=0?wd:0]; + *os = *ws / divs[qv%(sizeof(divs)/sizeof(divs[0]))]; + if (*os<1) *os=1; + + return wd>=0; +} + +int WDL_SimplePitchShifter2::GetSamples(int requested_output, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *buffer) +{ + if (!m_last_nch||requested_output<1) return 0; + + int l=m_queue.Available()/sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)/m_last_nch; + if (requested_output>l) requested_output=l; + int sz=requested_output*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*m_last_nch; + memcpy(buffer,m_queue.Get(),sz); + m_queue.Advance(sz); + m_queue.Compact(); + return requested_output; +} + +int WDL_SimplePitchShifter2::Stretch(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, double srate, int ws_ms, int os_ms) +{ + int bsize=(int) (ws_ms * 0.001 * srate); + if (bsize<16) bsize=16; + else if (bsize>128*1024)bsize=128*1024; + + int olsize=(int) (os_ms * 0.001 * srate); + if (olsize > bsize/2) olsize=bsize/2; + if (olsize<1)olsize=1; + if (m_psbuf.GetSize() != bsize*nch) + { + memset(m_psbuf.Resize(bsize*nch,false),0,sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE)*bsize*nch); + m_pspos=(double) (bsize/2); + m_pswritepos=0; + } + + return StretchBlock(inputs,outputs,nch,length,maxoutlen,stretch,bsize,olsize,srate); +} + +int WDL_SimplePitchShifter2::StretchBlock(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *inputs, WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *outputs, int nch, int length, int maxoutlen, double stretch, int bsize, int olsize, double srate) +{ + double iolsize=1.0/olsize; + + WDL_SIMPLEPITCHSHIFT_SAMPLETYPE *psbuf=m_psbuf.Get(); + + double pspos=m_pspos; + int writepos=m_pswritepos; + int writeposnch = writepos*nch; + int bsizench = bsize*nch; + int olsizench = olsize*nch; + int output_used=0; + int i=length; + int chunksize = nch*sizeof(WDL_SIMPLEPITCHSHIFT_SAMPLETYPE); + while (i--) + { + int cnt = (int) (pspos + stretch) - (int) pspos; + double pspos_fracadd=stretch - cnt; + while (cnt-- > 0) + { + if (output_used>=maxoutlen) return maxoutlen; + int ipos1=(int)pspos; + + ipos1*=nch; + + memcpy(outputs,psbuf+ipos1,chunksize); + + double tv=pspos; + if (stretch >= 1.0) + { + if (tv > writepos) tv-=bsize; + + if (tv >= writepos-olsize && tv < writepos) + { + double tfrac=(writepos-tv)*iolsize; + int tmp=ipos1+olsizench; + if (tmp>=bsizench) tmp-=bsizench; + + int a; + for(a=0;a= writepos) + { + pspos+=olsize; + } + } + + } + else + { + if (tv= writepos && tv < writepos+olsize) + { + double tfrac=(tv-writepos)*iolsize; + int tmp=ipos1+olsizench; + if (tmp>=bsizench) tmp -= bsizench; + int a; + for(a=0;a= writepos+olsize) pspos += olsize; + } + } + + + if ((pspos+=1) >= bsize) pspos -= bsize; + outputs += nch; + output_used++; + } + pspos += pspos_fracadd; + if (pspos>=bsize) pspos-=bsize; + + + + memcpy(psbuf+writeposnch,inputs,chunksize); + + writeposnch += nch; + if (++writepos >= bsize) writeposnch = writepos=0; + + inputs += nch; + } // sample loop + m_pspos=pspos; + m_pswritepos=writepos; + return output_used; + +} + +#endif + +#endif \ No newline at end of file diff --git a/WDL/sinewavegen.h b/WDL/sinewavegen.h new file mode 100644 index 00000000..7e8739d5 --- /dev/null +++ b/WDL/sinewavegen.h @@ -0,0 +1,59 @@ +#ifndef _WDL_SINEWAVEGEN_H_ +#define _WDL_SINEWAVEGEN_H_ + + +// note: calling new WDL_SineWaveGenerator isnt strictly necessary, you can also do WDL_SineWaveGenerator *gens = (WDL_SineWaveGenerator *)malloc(512*sizeof(WDL_SineWaveGenerator)); +// as long as you call Reset() and SetFreq() it should be fine. + + +// note: won't really work for high frequencies... + +class WDL_SineWaveGenerator +{ + double m_lastfreq; + double m_mul1,m_mul2; + double m_pos,m_vel; + +public: + WDL_SineWaveGenerator() { Reset(); m_mul1=m_mul2=m_pos=m_vel=0.0; } + ~WDL_SineWaveGenerator() { } + + void Reset() { m_lastfreq=0.0; } // must call this before anything + + void SetFreq(double freq) // be sure to call this before calling Gen(), or on freq change, or after a Reset() + // freq is frequency/(samplerate*0.5) (so 0..1 is valid, though over 0.3 is probably not a good idea) + { + freq*=3.1415926535897932384626433832795; // scale to freq*PI + + if (m_lastfreq<=0.0) + { + m_pos=0.0; + m_vel = 1.0/freq; + } + else + { + if (freq==m_lastfreq) return; + m_vel *= m_lastfreq/freq; + } + m_lastfreq=freq; + + double tmp2 = 1.0/(1.0+(freq*=freq)); + m_mul1 = (1.0-freq)*tmp2; + m_mul2 = freq*2.0*tmp2; + } + + double Gen() // returns sine + { + double rv=m_pos; + m_vel -= rv + (m_pos = rv*m_mul1 + m_vel*m_mul2); + return rv; + } + + double GetNextCos() // call BEFORE Gen() if you want the cosine of the next value + { + return m_vel * m_lastfreq; + } + +}; + +#endif diff --git a/WDL/stringpool.h b/WDL/stringpool.h new file mode 100644 index 00000000..f48fcafa --- /dev/null +++ b/WDL/stringpool.h @@ -0,0 +1,92 @@ +#ifndef _WDL_STRINGPOOL_H_ +#define _WDL_STRINGPOOL_H_ + + +#include "wdlstring.h" +#include "assocarray.h" +#include "mutex.h" + +class WDL_StringPool +{ + friend class WDL_PooledString; +public: + WDL_StringPool(bool wantMutex) : m_strings(true) { m_mutex = wantMutex ? new WDL_Mutex : NULL; }; + ~WDL_StringPool() { delete m_mutex; } + +private: + WDL_StringKeyedArray m_strings; +protected: + WDL_Mutex *m_mutex; + +}; + +class WDL_PooledString +{ +public: + WDL_PooledString(WDL_StringPool *pool, const char *value=NULL) { m_pool = pool; m_val = ""; Set(value); } + ~WDL_PooledString() { Set(""); } + + const char *Get() { return m_val; } + + void Set(const char *value) + { + if (!value) value=""; + if (strcmp(value,m_val)) + { + WDL_MutexLock(m_pool->m_mutex); // may or may not actually be a mutex + + const char *oldval = m_val; + + if (*value) + { + // set to new value + const char *keyptr=NULL; + int * ref = m_pool->m_strings.GetPtr(value,&keyptr); + if (ref) + { + ++*ref; + m_val=keyptr; + } + else m_pool->m_strings.Insert(value,1,&m_val); + } + else m_val=""; + + if (oldval[0]) + { + int *oldref = m_pool->m_strings.GetPtr(oldval); + if (oldref && --*oldref<=0) m_pool->m_strings.Delete(oldval); + } + } + } + + // utility for compat with WDL_String + void Append(const char *value) + { + if (value&&*value) + { + WDL_String tmp(Get()); + tmp.Append(value); + Set(tmp.Get()); + } + } + void Insert(const char *value, int pos) + { + WDL_String tmp(Get()); + tmp.Insert(value,pos); + Set(tmp.Get()); + } + void DeleteSub(int pos, int len) + { + WDL_String tmp(Get()); + tmp.DeleteSub(pos,len); + Set(tmp.Get()); + } + +private: + const char *m_val; + WDL_StringPool *m_pool; + +}; + + +#endif _WDL_STRINGPOOL_H_ \ No newline at end of file diff --git a/WDL/swell/Makefile.libSwell b/WDL/swell/Makefile.libSwell new file mode 100644 index 00000000..5d611c07 --- /dev/null +++ b/WDL/swell/Makefile.libSwell @@ -0,0 +1,65 @@ +# use make -f Makefile.libSwell +# or make -f Makefile.libSwell NOGDK=1 +# or make -f Makefile.libSwell DEBUG=1 +# etc + +ARCH := $(shell uname -m) + +CFLAGS = -pipe -malign-double -fvisibility=hidden -fno-strict-aliasing -fno-math-errno -fPIC -DPIC -Wall + +ifdef DEBUG +CFLAGS += -O0 -g +else +CFLAGS += -O2 -s +endif + +LINKEXTRA = -lpthread -ldl + + +EXTRA_OBJS = + + + + +vpath %.cpp .. ../lice + +SWELL_OBJS = swell.o swell-ini.o swell-miscdlg-generic.o swell-wnd-generic.o swell-menu-generic.o swell-kb-generic.o swell-dlg-generic.o \ + swell-gdi-generic.o swell-misc-generic.o swell-appstub-generic.o swell-modstub-generic.o swell-gdi-lice.o + +LICE_OBJS = lice.o lice_arc.o lice_colorspace.o lice_image.o lice_jpg.o lice_line.o lice_pcx.o lice_png.o lice_texgen.o lice_text.o \ + lice_textnew.o lice_ico.o lice_bmp.o lice_lvg.o + +OBJS = $(SWELL_OBJS) + +ifndef NOGDK + ifdef GDK2 + CFLAGS += -DSWELL_TARGET_GDK=2 $(shell pkg-config --cflags gdk-2.0) + LINKEXTRA += $(shell pkg-config --libs gdk-2.0) + else + CFLAGS += -DSWELL_TARGET_GDK=3 $(shell pkg-config --cflags gdk-3.0) + LINKEXTRA += $(shell pkg-config --libs gdk-3.0) + endif + CFLAGS += -DSWELL_LICE_GDI + OBJS += $(LICE_OBJS) + + ifndef NOFREETYPE + CFLAGS += -DSWELL_FREETYPE $(shell freetype-config --cflags) + LINKEXTRA += $(shell freetype-config --libs) + endif +endif + +CXXFLAGS = $(CFLAGS) + +default: libSwell.so + +.PHONY: clean + +libSwell.so: $(OBJS) + $(CXX) -shared -o $@ $(CFLAGS) $(LFLAGS) $(LINKEXTRA) $^ + +test: $(OBJS) test.o + $(CXX) -o test $(CFLAGS) $(LFLAGS) $(LINKEXTRA) $^ + +clean: + -rm $(OBJS) libSwell.so + diff --git a/WDL/swell/commctrl.h b/WDL/swell/commctrl.h new file mode 100644 index 00000000..776a87ce --- /dev/null +++ b/WDL/swell/commctrl.h @@ -0,0 +1 @@ +#include diff --git a/WDL/swell/mac_resgen.php b/WDL/swell/mac_resgen.php new file mode 100755 index 00000000..d9564c9d --- /dev/null +++ b/WDL/swell/mac_resgen.php @@ -0,0 +1,283 @@ +#!/usr/bin/php +=2) + { + $dlg_contents .= $y . "\n"; + if ($y == "END") + { + if ($dlg_state==2) $dlg_styles.="|SWELL_DLG_WS_OPAQUE"; + $retstr .= "#ifndef SET_$dlg_name" . "_SCALE\n"; + $retstr .= "#define SET_$dlg_name" . "_SCALE SWELL_DLG_SCALE_AUTOGEN\n"; + $retstr .= "#endif\n"; + $retstr .= "#ifndef SET_$dlg_name" . "_STYLE\n"; + $retstr .= "#define SET_$dlg_name" . "_STYLE $dlg_styles\n"; + $retstr .= "#endif\n"; + $retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_BEGIN($dlg_name,SET_$dlg_name" . "_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h,SET_$dlg_name" . "_SCALE)\n"; + $dlg_contents=str_replace("NOT WS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); + $dlg_contents=str_replace("NOT\nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); + $dlg_contents=str_replace("NOT \nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents); + $retstr .= $dlg_contents; + $retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END($dlg_name)\n\n\n"; + $dlg_state=0; + } + else if (strlen($y)>1) $dlg_state=3; + } + else + { + $parms = explode(" ", $y); + if (count($parms) > 0) + { + if ($dlg_state == 0) + { + // if (substr($parms[0],0,8) == "IDD_PREF") + if (count($parms)>4 && ($parms[1] == 'DIALOGEX'||$parms[1] == 'DIALOG')) + { + $dlg_name=$parms[0]; + $rdidx = 2; + if ($parms[$rdidx] == 'DISCARDABLE') $rdidx++; + while ($parms[$rdidx] == "" && $rdidx < count($parms)) $rdidx++; + $rdidx += 2; + $dlg_size_w = str_replace(",","",$parms[$rdidx++]); + $dlg_size_h = str_replace(",","",$parms[$rdidx++]); + if (count($parms) >= $rdidx && $dlg_size_w != "" && $dlg_size_h != "") + { + $dlg_title=""; + $dlg_styles="SWELL_DLG_FLAGS_AUTOGEN"; + $dlg_contents=""; + $dlg_state=1; + } + else $errstr .= "WARNING: corrupted $dlg_name resource\n"; + } + } + else if ($dlg_state == 1) + { + if ($parms[0] == "BEGIN") + { + $dlg_state=2; + $dlg_contents = $y ."\n"; + } + else + { + if ($parms[0] == "CAPTION") + { + $dlg_title = str_replace("\"","",trim(substr($y,8))); + } + else if ($parms[0] == "STYLE" || $parms[0] == "EXSTYLE") + { + $rep=0; + for (;;) + { + $next_line = fgets($fp,4096); + if (!($next_line )) { $next_line=""; break; } + if (substr($next_line,0,1)==" " || substr($next_line,0,1)=="\t") + { + $y .= " " . trim($next_line); + $rep++; + $next_line=""; + } + else break; + } + if ($rep) $parms = explode(" ", $y); + $opmode=0; + $rdidx=1; + while ($rdidx < count($parms)) + { + if ($parms[$rdidx] == '|') { $opmode=0; } + else if ($parms[$rdidx] == 'NOT') { $opmode=1; } + else if ($parms[$rdidx] == 'WS_CHILD') + { + if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_CHILD"; + } + else if ($parms[$rdidx] == 'WS_THICKFRAME') + { + if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_RESIZABLE"; + } + else if ($parms[$rdidx] == 'WS_EX_ACCEPTFILES') + { + if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_DROPTARGET"; + } + else $opmode=0; + $rdidx++; + } + } + } + } + } + } + } + if ($dlg_state != 0) + $errstr .= "WARNING: there may have been a truncated dialog resource ($dlg_name)\n"; + + $retstr .= "\n//EOF\n\n"; + $rv = array(); + $rv["data"] = $retstr; + $rv["error"] = $errstr; + return $rv; +} + +function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally ["error"] +{ + $retstr=""; + $errstr=""; + + fseek($fp,0,SEEK_SET); + + $menu_symbol=""; + $menu_depth=0; + while (($x=fgets($fp))) + { + $a=strpos($x, "\"\""); + if ($a) + { + $b=strpos($x, "\""); + $c=strpos($x, "\"", $a+1); + if ($b && $c && $b < $a && $c > $a) + { + $x=str_replace("\"\"", "\\\"", $x); + } + } + + $y=trim($x); + if ($menu_symbol == "") + { + $parms = explode(" ", $y); + $tok = "MENU"; + if (count($parms) >= 2 && $parms[1] == $tok) + { + $menu_symbol = $parms[0]; + $menu_depth=0; + $retstr .= "SWELL_DEFINE_MENU_RESOURCE_BEGIN($menu_symbol)\n"; + } + } + else + { + if ($y == "END") + { + $menu_depth-=1; + if ($menu_depth == 0) + { + $retstr .= "SWELL_DEFINE_MENU_RESOURCE_END($menu_symbol)\n\n\n"; + } + if ($menu_depth < 1) $menu_symbol=""; + } + if ($menu_depth>0) + { + if (substr($y,-strlen(", HELP")) == ", HELP") + { + $x=substr(rtrim($x),0,-strlen(", HELP")) . "\n"; + } + $retstr .= $x; + } + if ($y == "BEGIN") $menu_depth+=1; + } + } + + $retstr .= "\n//EOF\n\n"; + $rv = array(); + $rv["data"] = $retstr; + $rv["error"] = $errstr; + + return $rv; +} + +if (count($argv)<2) die("usage: mac_resgen.php [--force] file.rc ...\n"); + +$x=1; +$forcemode = 0; +if ($argv[$x] == "--force") { $forcemode=1; $x++; } + +$lp = dirname(__FILE__); +$proc=0; +$skipped=0; +$err=0; +for (; $x < count($argv); $x ++) +{ + $srcfn = $argv[$x]; + if (!stristr($srcfn,".rc") || !($fp = @fopen($srcfn,"r"))) + { + $err++; + echo "$srcfn: not valid or not found!\n"; + continue; + } + echo "$srcfn: "; + $ofnmenu = $srcfn . "_mac_menu"; + $ofndlg = $srcfn . "_mac_dlg"; + + $res = swell_rc2cpp_dialog($fp); + $res2 = swell_rc2cpp_menu($fp); + fclose($fp); + if ($res["error"] != "" || $res2["error"] != "") + { + $err++; + echo "error"; + if ($res["error"] != "") echo " dialog: " . $res["error"]; + if ($res2["error"] != "") echo " menu: " . $res2["error"]; + echo "\n"; + continue; + } + $f=""; + if ($forcemode || !file_exists($ofndlg) || file_get_contents($ofndlg) != $res["data"]) + { + $f .= "dlg updated"; + if (!file_put_contents($ofndlg,$res["data"],LOCK_EX)) { echo "error writing $ofndlg\n"; $err++; } + } + if ($forcemode || !file_exists($ofnmenu) || file_get_contents($ofnmenu) != $res2["data"]) + { + if ($f != "") $f .= ", "; + $f .= "menu updated"; + if (!file_put_contents($ofnmenu,$res2["data"],LOCK_EX)) { echo "error writing $ofnmenu\n"; $err++; } + } + + + if ($f) echo "$f\n"; + else echo "skipped\n"; + if ($f != "") $proc++; + else $skipped++; +} +echo "processed $proc, skipped $skipped, error $err\n"; + +?> diff --git a/WDL/swell/make-libSwells.sh b/WDL/swell/make-libSwells.sh new file mode 100644 index 00000000..764093c1 --- /dev/null +++ b/WDL/swell/make-libSwells.sh @@ -0,0 +1,10 @@ +#!/bin/sh +DESCSTR=libSwell-`uname -m`-`lsb_release -i -s | tr '[:upper:]' '[:lower:]'`-`lsb_release -c -s | tr '[:upper:]' '[:lower:]'` +make -f Makefile.libSwell NOGDK=1 clean +make -f Makefile.libSwell NOGDK=1 || exit 1 +tar cvJf $DESCSTR-headless.tar.xz libSwell.so || exit 1 + +make -f Makefile.libSwell clean +make -f Makefile.libSwell || exit 1 +tar cvJf $DESCSTR-gtk3.tar.xz libSwell.so || exit 1 + diff --git a/WDL/swell/sample_project/English.lproj/InfoPlist.strings b/WDL/swell/sample_project/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..5e45963c382ba690b781b953a00585212b898ac5 GIT binary patch literal 92 zcmW-XQ3`+{5C!MkQ~2$No+IcIkqMDxWCV8j>LCj|yTg2Mz+o9F%uHlf9u}h9EuK`F a!Y*1dX%G66ZqL#C$|bw0ZoP5@jOGW1ArT7z literal 0 HcmV?d00001 diff --git a/WDL/swell/sample_project/English.lproj/MainMenu.xib b/WDL/swell/sample_project/English.lproj/MainMenu.xib new file mode 100644 index 00000000..dc6f1700 --- /dev/null +++ b/WDL/swell/sample_project/English.lproj/MainMenu.xib @@ -0,0 +1,520 @@ + + + + 1050 + 9L30 + 677 + 949.54 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + NSApplication + + + FirstResponder + + + SWELLApplication + + + AMainMenu + + YES + + + SWELL Sample + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + SWELL Sample + + YES + + + About SWELL Sample + + 2147483647 + + + 40002 + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + UHJlZmVyZW5jZXPigKY + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide SWELL Sample + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit SWELL Sample + q + 1048576 + 2147483647 + + + 40001 + + + _NSAppleMenu + + + + _NSMainMenu + + + NSFontManager + + + SWELLAppController + + + + + YES + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + terminate: + + + + 449 + + + + onSysMenuCommand: + + + + 451 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + MainMenu + + + 56 + + + YES + + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 420 + + + + + 450 + + + Controller + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 420.IBPluginDependency + 450.IBPluginDependency + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{207, 285}, {144, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + {{219, 102}, {234, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 451 + + + + YES + + SWELLAppController + NSObject + + onSysMenuCommand: + id + + + IBDocumentRelativeSource + ../../swellappmain.h + + + + SWELLApplication + NSApplication + + + + + 0 + ../sample_project.xcodeproj + 3 + + diff --git a/WDL/swell/sample_project/Info.plist b/WDL/swell/sample_project/Info.plist new file mode 100644 index 00000000..1fe7bf0a --- /dev/null +++ b/WDL/swell/sample_project/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + SWELLApplication + + diff --git a/WDL/swell/sample_project/app_main.cpp b/WDL/swell/sample_project/app_main.cpp new file mode 100644 index 00000000..5c49eb13 --- /dev/null +++ b/WDL/swell/sample_project/app_main.cpp @@ -0,0 +1,198 @@ +#include "main.h" +#include "resource.h" + +/*** + How we created the xcode project that compiles this, too: + + New Project -> Mac OS X -> Application -> Cocoa Application + + Save as... + + Add to "Other sources/SWELL": (from swell path) swell-dlg.mm swell-gdi.mm swell-ini.cpp swell-kb.mm swell-menu.mm swell-misc.mm swell-miscdlg.mm swell-wnd.mm swell.cpp swell-appstub.mm swellappmain.mm + + Add app_main.cpp main_dialog.cpp to "Other sources" + + Go to Frameworks -> Linked Frameworks, add existing framework, Carbon.Framework + + go to terminal, to project dir, and run php /mac_resgen.php sample_project.rc + + Open mainmenu.xib in Interface Builder (doubleclick it in XCode) + + + Delete the default "Window" + + File->Read class files, find and select "swellappmain.h" + + Go to Library, Objects, scroll to "Object" , drag to "MainMenu.xib", rename to "Controller", then open its + properties (Cmd+Shift+I, go to class identity tab), choose for Class "SWELLAppController". + + Select "Application" in MainMenu.xib, go to (Cmd+Shift+I) application identity tab, select "SWELLApplication" for the class. + + + Customize the "NewApplication" menu. + + Properties on "About NewApplication": + + set the tag to 40002 (matching resource.h for about) + + on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand). + + Properties on "Quit NewApplication": + + set the tag to 40001 (matching resource.h for quit) + + on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand). + + Delete the file/edit/format/view/window/help menus, if you like (or keep some of them if you want) + + + Save and quit IB + + Go to Targets->sample_project, hit cmd+I, go to "Properties", and change Principal class to "SWELLApplication" + + + ...and then bleh you're done! :) + + */ + + + +HWND g_hwnd; // our main window (this corresponds to an NSView on OSX but we still use HWND) + +// these are not needed on OSX but defined anyway +HINSTANCE g_hInst; +UINT Scroll_Message; + + +#ifdef _WIN32 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd) +{ + g_hInst=hInstance; + // SWELLAPP_ONLOAD or so + + InitCommonControls(); + Scroll_Message = RegisterWindowMessage("MSWHEEL_ROLLMSG"); + + // create dialog (SWELLAPP_LOADED) + CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),MainDlgProc); + + for(;;) + { + MSG msg={0,}; + int vvv = GetMessage(&msg,NULL,0,0); + if (!vvv) break; + + if (vvv<0) + { + Sleep(10); + continue; + } + if (!msg.hwnd) + { + DispatchMessage(&msg); + continue; + } + + // if you want to hook any keyboard in here, the SWELL equiv is SWELLAPP_PROCESSMESSAGE + + + if (g_hwnd && IsDialogMessage(g_hwnd,&msg)) continue; + + // default processing for other dialogs + HWND hWndParent=NULL; + HWND temphwnd = msg.hwnd; + do + { + if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770) + { + hWndParent=temphwnd; + if (!(GetWindowLong(temphwnd,GWL_STYLE)&WS_CHILD)) break; // not a child, exit + } + } + while (temphwnd = GetParent(temphwnd)); + + if (hWndParent && IsDialogMessage(hWndParent,&msg)) continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + + } + + // in case g_hwnd didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly + if (g_hwnd) DestroyWindow(g_hwnd); + + return 0; +} +#else + +extern HMENU SWELL_app_stocksysmenu; +extern "C" { +INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) +{ + switch (msg) + { + case SWELLAPP_ONLOAD: + break; + case SWELLAPP_LOADED: + + if (SWELL_app_stocksysmenu) // set the SWELL default menu, using the .nib'd menu as the default settings + { + HMENU menu = CreatePopupMenu(); + HMENU nm=SWELL_DuplicateMenu(SWELL_app_stocksysmenu); + if (nm) + { + MENUITEMINFO mi={sizeof(mi),MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,0,0,nm,NULL,NULL,0,"SampleApp"}; + InsertMenuItem(menu,0,TRUE,&mi); + } + SWELL_SetDefaultModalWindowMenu(menu); + } + + { + HMENU menu = LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1)); + { + HMENU sm=GetSubMenu(menu,0); + DeleteMenu(sm,ID_QUIT,MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX + + // remove any trailing separators + int a= GetMenuItemCount(sm); + while (a > 0 && GetMenuItemID(sm,a-1)==0) DeleteMenu(sm,--a,MF_BYPOSITION); + } + // delete help menu from Windows menu (since we only use it for "About", which is in the system menu + DeleteMenu(menu,GetMenuItemCount(menu)-1,MF_BYPOSITION); + + if (SWELL_app_stocksysmenu) // insert the stock system menu + { + HMENU nm=SWELL_DuplicateMenu(SWELL_app_stocksysmenu); + if (nm) + { + MENUITEMINFO mi={sizeof(mi),MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,0,0,nm,NULL,NULL,0,"SampleApp"}; + InsertMenuItem(menu,0,TRUE,&mi); + } + } + + // if we want to set any default modifiers for items in the menus, we can use: + // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc. + + + HWND hwnd = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,MainDlgProc); + + SetMenu(hwnd,menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL + // we need to set it manually (and obviously we've edited the menu anyway) + } + break; + case SWELLAPP_ONCOMMAND: + // this is to catch commands coming from the system menu etc + if (g_hwnd && (parm1&0xffff)) SendMessage(g_hwnd,WM_COMMAND,parm1&0xffff,0); + break; + case SWELLAPP_DESTROY: + if (g_hwnd) DestroyWindow(g_hwnd); + break; + case SWELLAPP_PROCESSMESSAGE: + // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to + break; + } + return 0; +} +}; + +#endif + + + + +#ifndef _WIN32 // import the resources. Note: if you do not have these files, run "php ../mac_resgen.php sample_project.rc" from this directory + #include "../swell-dlggen.h" + + #include "sample_project.rc_mac_dlg" + + #include "../swell-menugen.h" + + #include "sample_project.rc_mac_menu" +#endif diff --git a/WDL/swell/sample_project/main.h b/WDL/swell/sample_project/main.h new file mode 100644 index 00000000..628f73ff --- /dev/null +++ b/WDL/swell/sample_project/main.h @@ -0,0 +1,23 @@ +#ifndef _SAMPLEPROJECT_MAIN_H_ +#define _SAMPLEPROJECT_MAIN_H_ + + +#ifdef _WIN32 +#include +#include +#else +#include "../swell.h" +#endif + +#include "../../wdltypes.h" + +extern WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +extern HINSTANCE g_hInst; +extern HWND g_hwnd; +extern UINT Scroll_Message; + + + +#endif//_SAMPLEPROJECT_MAIN_H_ + diff --git a/WDL/swell/sample_project/main.m b/WDL/swell/sample_project/main.m new file mode 100644 index 00000000..4f4a95cd --- /dev/null +++ b/WDL/swell/sample_project/main.m @@ -0,0 +1,14 @@ +// +// main.m +// sample_project +// +// Created by Justin Frankel on 11/24/09. +// Copyright Cockos Incorporated 2009. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/WDL/swell/sample_project/main_dialog.cpp b/WDL/swell/sample_project/main_dialog.cpp new file mode 100644 index 00000000..fb70346e --- /dev/null +++ b/WDL/swell/sample_project/main_dialog.cpp @@ -0,0 +1,55 @@ +#include "main.h" + +#include "resource.h" + + +WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + g_hwnd=hwndDlg; + + SetDlgItemText(hwndDlg,IDC_EDIT1,"Text yay"); + + ShowWindow(hwndDlg,SW_SHOW); + return 1; + case WM_DESTROY: + g_hwnd=NULL; + + #ifdef _WIN32 + PostQuitMessage(0); + #else + // this isnt just "PostQuitMessage", because the behaviors don't totally match -- i.e. + // it is relatively normal for the OS X app to get terminated without us calling this. Sooo, our exit handler + // code shouldn't rely on us having called this, etc... + SWELL_PostQuitMessage(hwndDlg); + #endif + + return 0; + case WM_CLOSE: + DestroyWindow(hwndDlg); + return 0; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case ID_QUIT: + DestroyWindow(hwndDlg); + return 0; + case ID_SOMETHING: + { + char buf[1024]; + if (GetDlgItemText(hwndDlg,IDC_EDIT1,buf,sizeof(buf))) + { + MessageBox(hwndDlg,buf,"The string!",MB_OK); + } + } + return 0; + case ID_ABOUT: + MessageBox(hwndDlg,"SWELL test app","Hooray",MB_OK); + return 0; + } + return 0; + } + return 0; +} diff --git a/WDL/swell/sample_project/resource.h b/WDL/swell/sample_project/resource.h new file mode 100644 index 00000000..376a461a --- /dev/null +++ b/WDL/swell/sample_project/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by sample_project.rc +// +#define IDD_DIALOG1 101 +#define IDR_MENU1 102 +#define IDC_EDIT1 1001 +#define ID_QUIT 40001 +#define ID_ABOUT 40002 +#define ID_SOMETHING 40003 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40004 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/WDL/swell/sample_project/sample_project.dsp b/WDL/swell/sample_project/sample_project.dsp new file mode 100644 index 00000000..9708f07d --- /dev/null +++ b/WDL/swell/sample_project/sample_project.dsp @@ -0,0 +1,119 @@ +# Microsoft Developer Studio Project File - Name="sample_project" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=sample_project - 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 "sample_project.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 "sample_project.mak" CFG="sample_project - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sample_project - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "sample_project - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sample_project - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "sample_project - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sample_project - Win32 Release" +# Name "sample_project - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\app_main.cpp +# End Source File +# Begin Source File + +SOURCE=.\main_dialog.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\main.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\sample_project.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/WDL/swell/sample_project/sample_project.dsw b/WDL/swell/sample_project/sample_project.dsw new file mode 100644 index 00000000..c74c29e1 --- /dev/null +++ b/WDL/swell/sample_project/sample_project.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sample_project"=.\sample_project.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/WDL/swell/sample_project/sample_project.rc b/WDL/swell/sample_project/sample_project.rc new file mode 100644 index 00000000..fb1c6264 --- /dev/null +++ b/WDL/swell/sample_project/sample_project.rc @@ -0,0 +1,118 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 264, 117 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Sample app" +MENU IDR_MENU1 +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_EDIT1,59,50,145,14,ES_AUTOHSCROLL + LTEXT "Enter some text here:",IDC_STATIC,59,39,73,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 257 + TOPMARGIN, 7 + BOTTOMMARGIN, 110 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "MessageBox the string", ID_SOMETHING + MENUITEM SEPARATOR + MENUITEM "&Quit", ID_QUIT + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_ABOUT + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns b/WDL/swell/sample_project/sample_project.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..62cb7015e09d6ea3e65d7f7949c4c07f9246a908 GIT binary patch literal 52318 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 WhsmLR^b3` +#endif diff --git a/WDL/swell/sample_project/version.plist b/WDL/swell/sample_project/version.plist new file mode 100644 index 00000000..5611992c --- /dev/null +++ b/WDL/swell/sample_project/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 3 + CFBundleVersion + 1.0 + ProductBuildVersion + 9M2729 + ProjectName + DevToolsWizardTemplates + SourceVersion + 11600000 + + diff --git a/WDL/swell/shlobj.h b/WDL/swell/shlobj.h new file mode 100644 index 00000000..776a87ce --- /dev/null +++ b/WDL/swell/shlobj.h @@ -0,0 +1 @@ +#include diff --git a/WDL/swell/swell-appstub-generic.cpp b/WDL/swell/swell-appstub-generic.cpp new file mode 100644 index 00000000..ad5caed2 --- /dev/null +++ b/WDL/swell/swell-appstub-generic.cpp @@ -0,0 +1,44 @@ +#include "swell.h" + + +#ifndef SWELL_PROVIDED_BY_APP + +// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins +// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm + +#undef _WDL_SWELL_H_API_DEFINED_ +#undef SWELL_API_DEFINE +#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func }, +static struct api_ent +{ + const char *name; + void *func; +} +api_table[]= +{ +#include "swell.h" +}; + +static int compfunc(const void *a, const void *b) +{ + return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name); +} + +extern "C" { +__attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) +{ + if (!name) return (void *)0x100; // version + static int a; + if (!a) + { + a=1; + qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); + } + struct api_ent find={name,NULL}; + struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); + if (res) return res->func; + return NULL; +} +}; + +#endif diff --git a/WDL/swell/swell-appstub.mm b/WDL/swell/swell-appstub.mm new file mode 100644 index 00000000..2984c3f7 --- /dev/null +++ b/WDL/swell/swell-appstub.mm @@ -0,0 +1,42 @@ +#include "swell.h" + + +#ifndef SWELL_PROVIDED_BY_APP + +// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins +// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm + +#undef _WDL_SWELL_H_API_DEFINED_ +#undef SWELL_API_DEFINE +#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func }, +static struct api_ent +{ + const char *name; + void *func; +} +api_table[]= +{ +#include "swell-functions.h" +}; + +static int compfunc(const void *a, const void *b) +{ + return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name); +} + +void *SWELLAPI_GetFunc(const char *name) +{ + if (!name) return (void *)0x100; // version + static int a; + if (!a) + { + a=1; + qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); + } + struct api_ent find={name,NULL}; + struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc); + if (res) return res->func; + return NULL; +} + +#endif diff --git a/WDL/swell/swell-dlg-generic.cpp b/WDL/swell/swell-dlg-generic.cpp new file mode 100644 index 00000000..63a30f08 --- /dev/null +++ b/WDL/swell/swell-dlg-generic.cpp @@ -0,0 +1,212 @@ +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-dlggen.h" + +#include "../ptrlist.h" + +static HMENU g_swell_defaultmenu,g_swell_defaultmenumodal; + +void (*SWELL_DDrop_onDragLeave)(); +void (*SWELL_DDrop_onDragOver)(POINT pt); +void (*SWELL_DDrop_onDragEnter)(void *hGlobal, POINT pt); +const char* (*SWELL_DDrop_getDroppedFileTargetPath)(const char* extension); + +bool SWELL_owned_windows_levelincrease=false; + +#include "swell-internal.h" + +static SWELL_DialogResourceIndex *resById(SWELL_DialogResourceIndex *reshead, const char *resid) +{ + SWELL_DialogResourceIndex *p=reshead; + while (p) + { + if (p->resid == resid) return p; + p=p->_next; + } + return 0; +} + +// keep list of modal dialogs +struct modalDlgRet { + HWND hwnd; + bool has_ret; + int ret; +}; + + +static WDL_PtrList s_modalDialogs; + +HWND DialogBoxIsActive() +{ + return s_modalDialogs.GetSize() ? s_modalDialogs.Get(s_modalDialogs.GetSize()-1)->hwnd : NULL; +} + +void EndDialog(HWND wnd, int ret) +{ + if (!wnd) return; + + int x; + for (x = 0; x < s_modalDialogs.GetSize(); x ++) + if (s_modalDialogs.Get(x)->hwnd == wnd) + { + s_modalDialogs.Get(x)->has_ret=true; + s_modalDialogs.Get(x)->ret = ret; + } + DestroyWindow(wnd); + // todo +} + +int SWELL_DialogBox(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) +{ + SWELL_DialogResourceIndex *p=resById(reshead,resid); + if (resid) // allow modal dialogs to be created without template + { + if (!p||(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) return -1; + } + + + int ret=-1; + HWND hwnd = SWELL_CreateDialog(reshead,resid,parent,dlgproc,param); + // create dialog + if (hwnd) + { + ReleaseCapture(); // force end of any captures + + WDL_PtrList enwnds; + extern HWND__ *SWELL_topwindows; + HWND a = SWELL_topwindows; + while (a) + { + if (a->m_enabled && a != hwnd) { EnableWindow(a,FALSE); enwnds.Add(a); } + a = a->m_next; + } + + modalDlgRet r = { hwnd,false, -1 }; + s_modalDialogs.Add(&r); + ShowWindow(hwnd,SW_SHOW); + while (s_modalDialogs.Find(&r)>=0 && !r.has_ret) + { + void SWELL_RunMessageLoop(); + SWELL_RunMessageLoop(); + Sleep(10); + } + ret=r.ret; + s_modalDialogs.Delete(s_modalDialogs.Find(&r)); + + a = SWELL_topwindows; + while (a) + { + if (!a->m_enabled && a != hwnd && enwnds.Find(a)>=0) EnableWindow(a,TRUE); + a = a->m_next; + } + } + // while in list, do something + return ret; +} + +HWND SWELL_CreateDialog(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) +{ + SWELL_DialogResourceIndex *p=resById(reshead,resid); + if (!p&&resid) return 0; + + RECT r={0,0,p?p->width : 300, p?p->height : 200}; + HWND owner=NULL; + + if ((!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD)) && parent) + { + } + else + { + owner = parent; + parent = NULL; // top level window + } + + HWND__ *h = new HWND__(parent,0,&r,NULL,false,NULL,NULL); + if (p && !(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) + { + if (p->windowTypeFlags&SWELL_DLG_WS_RESIZABLE) h->m_style |= WS_THICKFRAME|WS_CAPTION; + else h->m_style |= WS_CAPTION; + } + else if (!p && !parent) h->m_style |= WS_CAPTION; + else if (parent && (!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD))) h->m_style |= WS_CHILD; + + if (p) + { + p->createFunc(h,p->windowTypeFlags); + if (p->title) SetWindowText(h,p->title); + + h->m_dlgproc = dlgproc; + h->m_wndproc = SwellDialogDefaultWindowProc; + + //HWND hFoc=m_children; +// while (hFoc && !hFoc->m_wantfocus) hFoc=hFoc->m_next; + // if (!hFoc) hFoc=this; + // if (dlgproc(this,WM_INITDIALOG,(WPARAM)hFoc,0)&&hFoc) SetFocus(hFoc); + + h->m_dlgproc(h,WM_INITDIALOG,0,param); + } + else + { + h->m_wndproc = (WNDPROC)dlgproc; + h->m_wndproc(h,WM_CREATE,0,param); + } + + return h; +} + + +HMENU SWELL_GetDefaultWindowMenu() { return g_swell_defaultmenu; } +void SWELL_SetDefaultWindowMenu(HMENU menu) +{ + g_swell_defaultmenu=menu; +} +HMENU SWELL_GetDefaultModalWindowMenu() +{ + return g_swell_defaultmenumodal; +} +void SWELL_SetDefaultModalWindowMenu(HMENU menu) +{ + g_swell_defaultmenumodal=menu; +} + + + +SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; // this eventually will go into a per-module stub file + + +static char* s_dragdropsrcfn = 0; +static void (*s_dragdropsrccallback)(const char*) = 0; + +void SWELL_InitiateDragDrop(HWND hwnd, RECT* srcrect, const char* srcfn, void (*callback)(const char* dropfn)) +{ + SWELL_FinishDragDrop(); + + if (1) return; + + s_dragdropsrcfn = strdup(srcfn); + s_dragdropsrccallback = callback; + + char* p = s_dragdropsrcfn+strlen(s_dragdropsrcfn)-1; + while (p >= s_dragdropsrcfn && *p != '.') --p; + ++p; + +} + +// owner owns srclist, make copies here etc +void SWELL_InitiateDragDropOfFileList(HWND hwnd, RECT *srcrect, const char **srclist, int srccount, HICON icon) +{ + SWELL_FinishDragDrop(); + + if (1) return; + +} + +void SWELL_FinishDragDrop() +{ + free(s_dragdropsrcfn); + s_dragdropsrcfn = 0; + s_dragdropsrccallback = 0; +} + +#endif diff --git a/WDL/swell/swell-dlg.mm b/WDL/swell/swell-dlg.mm new file mode 100644 index 00000000..d273bf7e --- /dev/null +++ b/WDL/swell/swell-dlg.mm @@ -0,0 +1,3214 @@ +#ifndef SWELL_PROVIDED_BY_APP + + +#include "swell.h" +#include "swell-dlggen.h" + +#import +#include +#include + +#ifndef SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN +#define SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN 1 // 2 gives more performance, not correctly drawn window frames (try NSThemeFrame stuff? bleh) +#endif + +static HMENU g_swell_defaultmenu,g_swell_defaultmenumodal; + +void (*SWELL_DDrop_onDragLeave)(); +void (*SWELL_DDrop_onDragOver)(POINT pt); +void (*SWELL_DDrop_onDragEnter)(void *hGlobal, POINT pt); +const char* (*SWELL_DDrop_getDroppedFileTargetPath)(const char* extension); + +bool SWELL_owned_windows_levelincrease=false; + +#include "swell-internal.h" +#include "../wdlstring.h" + +#define NSColorFromCol(a) [NSColor colorWithCalibratedRed:GetRValue(a)/255.0f green:GetGValue(a)/255.0f blue:GetBValue(a)/255.0f alpha:1.0f] +extern int g_swell_terminating; + +static LRESULT sendSwellMessage(id obj, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (obj && [obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + return [(SWELL_hwndChild *)obj onSwellMessage:uMsg p1:wParam p2:lParam]; + return 0; +} + + +static BOOL useNoMiddleManCocoa() +{ + static char is105; + if (!is105) + { + SInt32 v=0x1040; + Gestalt(gestaltSystemVersion,&v); + is105 = v>=0x1050 ? 1 : -1; + } + return is105>0; +} + +void updateWindowCollection(NSWindow *w) +{ + static SInt32 ver; + if (!ver) + { + Gestalt(gestaltSystemVersion,&ver); + if (!ver) ver=0x1040; + } + if (ver>=0x1060) + { + const int NSWindowCollectionBehaviorParticipatesInCycle = 1 << 5; + const int NSWindowCollectionBehaviorManaged = 1 << 2; + [(SWELL_WindowExtensions*)w setCollectionBehavior:NSWindowCollectionBehaviorManaged|NSWindowCollectionBehaviorParticipatesInCycle]; + } +} + +static void DrawSwellViewRectImpl(SWELL_hwndChild *view, NSRect rect, HDC hdc); +static void swellRenderOptimizely(int passflags, SWELL_hwndChild *view, HDC hdc, BOOL doforce, WDL_PtrList *needdraws, const NSRect *rlist, int rlistcnt, int draw_xlate_x, int draw_xlate_y, bool iscv); + +static LRESULT SWELL_SendMouseMessage(NSView *slf, int msg, NSEvent *event); +static LRESULT SWELL_SendMouseMessageImpl(SWELL_hwndChild *slf, int msg, NSEvent *theEvent) +{ + + NSView *capv=(NSView *)GetCapture(); + if (capv && capv != slf && [capv window] == [slf window] && [capv isKindOfClass:[SWELL_hwndChild class]]) + return SWELL_SendMouseMessage((SWELL_hwndChild*)capv,msg,theEvent); + + if (slf->m_hashaddestroy||!slf->m_wndproc) return -1; + + NSPoint swellProcessMouseEvent(int msg, NSView *view, NSEvent *event); + + NSPoint p = swellProcessMouseEvent(msg,slf,theEvent); + unsigned short xpos=(int)floor(p.x); + unsigned short ypos=(int)floor(p.y); + + LRESULT htc=HTCLIENT; + if (msg != WM_MOUSEWHEEL && msg != WM_MOUSEHWHEEL && !capv) + { + DWORD p=GetMessagePos(); + htc=slf->m_wndproc((HWND)slf,WM_NCHITTEST,0,p); + if (slf->m_hashaddestroy||!slf->m_wndproc) return -1; // if somehow WM_NCHITTEST destroyed us, bail + + if (htc!=HTCLIENT) + { + if (msg==WM_MOUSEMOVE) return slf->m_wndproc((HWND)slf,WM_NCMOUSEMOVE,htc,p); + if (msg==WM_LBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONUP,htc,p); + if (msg==WM_LBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONDOWN,htc,p); + if (msg==WM_LBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCLBUTTONDBLCLK,htc,p); + if (msg==WM_RBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONUP,htc,p); + if (msg==WM_RBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONDOWN,htc,p); + if (msg==WM_RBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCRBUTTONDBLCLK,htc,p); + if (msg==WM_MBUTTONUP) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONUP,htc,p); + if (msg==WM_MBUTTONDOWN) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONDOWN,htc,p); + if (msg==WM_MBUTTONDBLCLK) return slf->m_wndproc((HWND)slf,WM_NCMBUTTONDBLCLK,htc,p); + } + } + + int l=0; + if (msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL) + { + float dw = (msg == WM_MOUSEWHEEL ? [theEvent deltaY] : [theEvent deltaX]); + //if (!dy) dy=[theEvent deltaX]; // shift+mousewheel sends deltaX instead of deltaY + l = (int)(dw*60.0); + l <<= 16; + + // put todo: modifiers into low word of l? + + POINT p; + GetCursorPos(&p); + return slf->m_wndproc((HWND)slf,msg,l,(p.x&0xffff) + (p.y<<16)); + } + + LRESULT ret=slf->m_wndproc((HWND)slf,msg,l,(xpos&0xffff) + (ypos<<16)); + + if (msg==WM_LBUTTONUP || msg==WM_RBUTTONUP || msg==WM_MOUSEMOVE || msg==WM_MBUTTONUP) { + if (!GetCapture() && (slf->m_hashaddestroy || !slf->m_wndproc || !slf->m_wndproc((HWND)slf,WM_SETCURSOR,(WPARAM)slf,htc | (msg<<16)))) { + NSCursor *arr= [NSCursor arrowCursor]; + if (GetCursor() != (HCURSOR)arr) SetCursor((HCURSOR)arr); + } + } + return ret; +} +static LRESULT SWELL_SendMouseMessage(NSView *slf, int msg, NSEvent *event) +{ + if (!slf) return 0; + [slf retain]; + LRESULT res=SWELL_SendMouseMessageImpl((SWELL_hwndChild*)slf,msg,event); + [slf release]; + return res; +} + +void SWELL_DoDialogColorUpdates(HWND hwnd, DLGPROC d, bool isUpdate) +{ + extern HDC__ *SWELL_GDP_CTX_NEW(); + NSArray *children = [(NSView *)hwnd subviews]; + + if (!d || !children || ![children count]) return; + + int had_flags=0; + + NSColor *staticFg=NULL; // had_flags&1, WM_CTLCOLORSTATIC + NSColor *editFg=NULL, *editBg=NULL; // had_flags&2, WM_CTLCOLOREDIT + NSColor *buttonFg=NULL; // had_flags&4, WM_CTLCOLORBTN + + int x; + for (x = 0; x < [children count]; x ++) + { + NSView *ch = [children objectAtIndex:x]; + if (ch) + { + if ([ch isKindOfClass:[NSButton class]] && [(NSButton *)ch image]) + { + if (!buttonFg && !(had_flags&4)) + { + had_flags|=4; + HDC__ *c = SWELL_GDP_CTX_NEW(); + if (c) + { + d(hwnd,WM_CTLCOLORBTN,(WPARAM)c,(LPARAM)ch); + if (c->curtextcol) buttonFg=NSColorFromCol(c->cur_text_color_int); + else if (isUpdate) buttonFg = [NSColor textColor]; // todo some other col? + if (buttonFg) [buttonFg retain]; + + SWELL_DeleteGfxContext((HDC)c); + } + } + if (buttonFg) [(NSTextField*)ch setTextColor:buttonFg]; // NSButton had this added below + } + else if ([ch isKindOfClass:[NSTextField class]] || [ch isKindOfClass:[NSBox class]]) + { + bool isbox = ([ch isKindOfClass:[NSBox class]]); + if (!isbox && [(NSTextField *)ch isEditable]) + { +#if 0 // no color overrides for editable text fields + if (!editFg && !editBg && !(had_flags&2)) + { + had_flags|=2; + HDC__ *c = SWELL_GDP_CTX_NEW(); + if (c) + { + d(hwnd,WM_CTLCOLOREDIT,(WPARAM)c,(LPARAM)ch); + if (c->curtextcol) + { + editFg=NSColorFromCol(c->cur_text_color_int); + editBg=[NSColor colorWithCalibratedRed:GetRValue(c->curbkcol)/255.0f green:GetGValue(c->curbkcol)/255.0f blue:GetBValue(c->curbkcol)/255.0f alpha:1.0f]; + } + else if (isUpdate) + { + editFg = [NSColor textColor]; + editBg = [NSColor textBackgroundColor]; + } + if (editFg) [editFg retain]; + if (editBg) [editBg retain]; + SWELL_DeleteGfxContext((HDC)c); + } + } + if (editFg) [(NSTextField*)ch setTextColor:editFg]; + if (editBg) [(NSTextField*)ch setBackgroundColor:editBg]; +#endif + } + else // isbox or noneditable + { + if (!staticFg && !(had_flags&1)) + { + had_flags|=1; + HDC__ *c = SWELL_GDP_CTX_NEW(); + if (c) + { + d(hwnd,WM_CTLCOLORSTATIC,(WPARAM)c,(LPARAM)ch); + if (c->curtextcol) staticFg=NSColorFromCol(c->cur_text_color_int); + else if (isUpdate) + { + staticFg = [NSColor textColor]; + } + if (staticFg) [staticFg retain]; + SWELL_DeleteGfxContext((HDC)c); + } + } + if (staticFg) + { + if (isbox) + { + [[(NSBox*)ch titleCell] setTextColor:staticFg]; + //[(NSBox*)ch setBorderColor:staticFg]; // see comment at SWELL_MakeGroupBox + } + else + { + [(NSTextField*)ch setTextColor:staticFg]; + } + } + } // noneditable + } //nstextfield + } // child + } // children + if (buttonFg) [buttonFg release]; + if (staticFg) [staticFg release]; + if (editFg) [editFg release]; + if (editBg) [editBg release]; +} + +static LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + DLGPROC d=(DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); + if (d) + { + if (uMsg == WM_PAINT) + { + if (!d(hwnd,WM_ERASEBKGND,0,0)) + { + bool nommc=useNoMiddleManCocoa(); + NSView *cv = [[(NSView *)hwnd window] contentView]; + bool isop = [(NSView *)hwnd isOpaque] || (nommc && [cv isOpaque]); + if (isop || cv == (NSView *)hwnd) + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r=ps.rcPaint; + if (!nommc && !(((SWELL_hwndChild*)hwnd)->m_isdirty&1)) + { + NSArray *ar = [(NSView *)hwnd subviews]; + int x,n=[ar count]; + for (x=0;x=n) r.right=r.left; // disable drawing + } + + if (r.right > r.left && r.bottom > r.top) + { + HBRUSH hbrush = (HBRUSH) d(hwnd,WM_CTLCOLORDLG,(WPARAM)ps.hdc,(LPARAM)hwnd); + if (hbrush && hbrush != (HBRUSH)1) + { + // char bf[512]; + // GetWindowText(hwnd,bf,sizeof(bf)); +// static int a; + // printf("%d filled custom bg, (%p %s) %d %d %d %d\n",a++,hwnd,bf,r.left,r.top,r.right-r.left,r.bottom-r.top); + FillRect(ps.hdc,&r,hbrush); + } + else if (isop) // no need to do this fill if it is a content view and is not opaque + { + // char bf[512]; + // GetWindowText(hwnd,bf,sizeof(bf)); + // static int a; + // printf("%d: filled stock bg, (%p %s) %d %d %d %d\n",a++,hwnd,bf,r.left,r.top,r.right-r.left,r.bottom-r.top); + SWELL_FillDialogBackground(ps.hdc,&r,3); + } + } + EndPaint(hwnd,&ps); + } + } + } + } + + LRESULT r=(LRESULT) d(hwnd,uMsg,wParam,lParam); + + if (r) return r; + } + return DefWindowProc(hwnd,uMsg,wParam,lParam); +} + +static SWELL_DialogResourceIndex *resById(SWELL_DialogResourceIndex *reshead, const char *resid) +{ + SWELL_DialogResourceIndex *p=reshead; + while (p) + { + if (p->resid == resid) return p; + p=p->_next; + } + return 0; +} + +static void DoPaintStuff(WNDPROC wndproc, HWND hwnd, HDC hdc, NSRect *modrect) +{ + RECT r,r2; + GetWindowRect(hwnd,&r); + if (r.top>r.bottom) { int tmp=r.top; r.top=r.bottom; r.bottom=tmp; } + r2=r; + wndproc(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&r); + wndproc(hwnd,WM_NCPAINT,(WPARAM)1,0); + modrect->origin.x += r.left-r2.left; + modrect->origin.y += r.top-r2.top; + + if (modrect->size.width >= 1 && modrect->size.height >= 1) + { + int a=0; + if (memcmp(&r,&r2,sizeof(r))) + { + RECT tr; + SWELL_PushClipRegion(hdc); + GetClientRect(hwnd,&tr); + SWELL_SetClipRegion(hdc,&tr); + a++; + } + wndproc(hwnd,WM_PAINT,(WPARAM)hdc,0); + if (a) SWELL_PopClipRegion(hdc); + } +} + + +static int DelegateMouseMove(NSView *view, NSEvent *theEvent) +{ + static int __nofwd; + if (__nofwd) return 0; + + NSWindow *w=[theEvent window]; + if (!w) return 0; + + NSPoint p=[theEvent locationInWindow]; + NSPoint screen_p=[w convertBaseToScreen:p]; + + NSWindow *bestwnd = w; + HWND cap = GetCapture(); + if (!cap) + { + // if not captured, find the window that should receive this event + + NSArray *windows=[NSApp orderedWindows]; + int x,cnt=windows ? [windows count] : 0; + NSWindow *kw = [NSApp keyWindow]; + if (kw && windows && [windows containsObject:kw]) kw=NULL; + // make sure the keywindow, if any, is checked, but not twice + + for (x = kw ? -1 : 0; x < cnt; x ++) + { + NSWindow *wnd = x < 0 ? kw : [windows objectAtIndex:x]; + if (wnd && [wnd isVisible]) + { + NSRect fr=[wnd frame]; + if (screen_p.x >= fr.origin.x && screen_p.x < fr.origin.x + fr.size.width && + screen_p.y >= fr.origin.y && screen_p.y < fr.origin.y + fr.size.height) + { + bestwnd=wnd; + break; + } + } + } + } + + if (bestwnd == w || [NSApp modalWindow]) + { + NSView *v=[[w contentView] hitTest:p]; + if (!v || v == view) return 0; // default processing if in view, or if in nonclient area + + __nofwd=1; + [v mouseMoved:theEvent]; + __nofwd=0; + return 1; + } + + // bestwnd != w + NSView *cv = [bestwnd contentView]; + if (cv && [cv isKindOfClass:[SWELL_hwndChild class]]) + { + p = [bestwnd convertScreenToBase:screen_p]; + NSView *v=[cv hitTest:p]; + if (v) + { + theEvent = [NSEvent mouseEventWithType:[theEvent type] + location:p + modifierFlags:[theEvent modifierFlags] + timestamp:[theEvent timestamp] + windowNumber:[bestwnd windowNumber] + context:[bestwnd graphicsContext] + eventNumber:[theEvent eventNumber] + clickCount:[theEvent clickCount] + pressure:[theEvent pressure]]; + __nofwd=1; + [v mouseMoved:theEvent]; + __nofwd=0; + return 1; + } + } + if (!cap) + { + // set default cursor, and eat message + NSCursor *arr= [NSCursor arrowCursor]; + if (GetCursor() != (HCURSOR)arr) SetCursor((HCURSOR)arr); + return 1; + } + return 0; +} + + + + +@implementation SWELL_hwndChild : NSView + +-(void)viewDidHide +{ + SendMessage((HWND)self, WM_SHOWWINDOW, FALSE, 0); +} +-(void) viewDidUnhide +{ + SendMessage((HWND)self, WM_SHOWWINDOW, TRUE, 0); +} + +- (void)SWELL_Timer:(id)sender +{ + extern HWND g_swell_only_timerhwnd; + if (g_swell_only_timerhwnd && (HWND)self != g_swell_only_timerhwnd) return; + + id uinfo=[sender userInfo]; + if ([uinfo respondsToSelector:@selector(getValue)]) + { + WPARAM idx=(WPARAM)[(SWELL_DataHold*)uinfo getValue]; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_TIMER,idx,0); + } +} + +- (int)swellCapChangeNotify { return YES; } + +- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam +{ + if (m_hashaddestroy) + { + if (m_hashaddestroy==2 || msg == WM_DESTROY || msg == WM_CAPTURECHANGED) return 0; + } + + + if (msg==WM_DESTROY) // only ever called once per window + { + m_hashaddestroy=1; + if (GetCapture()==(HWND)self) ReleaseCapture(); + SWELL_MessageQueue_Clear((HWND)self); + + LRESULT ret=m_wndproc ? m_wndproc((HWND)self,msg,wParam,lParam) : 0; + + if ([[self window] contentView] == self && [[self window] respondsToSelector:@selector(swellDestroyAllOwnedWindows)]) + [(SWELL_ModelessWindow*)[self window] swellDestroyAllOwnedWindows]; + + if (GetCapture()==(HWND)self) ReleaseCapture(); + SWELL_MessageQueue_Clear((HWND)self); + + if (m_menu) + { + if ((HMENU)[NSApp mainMenu] == m_menu && !g_swell_terminating) [NSApp setMainMenu:nil]; + SWELL_SetMenuDestination(m_menu,NULL); + [(NSMenu *)m_menu release]; + m_menu=0; + } + NSView *v=self; + NSArray *ar; + if (v && [v isKindOfClass:[NSView class]] && (ar=[v subviews]) && [ar count]>0) + { + int x; + for (x = 0; x < [ar count]; x ++) + { + NSView *sv=[ar objectAtIndex:x]; + sendSwellMessage(sv,WM_DESTROY,0,0); + } + } + KillTimer((HWND)self,~(UINT_PTR)0); + m_hashaddestroy=2; + + return ret; + } + + return m_wndproc ? m_wndproc((HWND)self,msg,wParam,lParam) : 0; +} + +- (void) setEnabled:(BOOL)en +{ + m_enabled=en; +} + +- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + if ([aTableView isKindOfClass:[SWELL_ListView class]]) + { + SWELL_ListView *f = (SWELL_ListView *)aTableView; + if (f->m_selColors&&[aTableView isRowSelected:rowIndex]) + { + int cnt = [f->m_selColors count]; + int offs = GetFocus() == (HWND)aTableView ? 0 : 2; + if (cnt>=offs+2) + { + if ([aCell respondsToSelector:@selector(setTextColor:)]) [aCell setTextColor:[f->m_selColors objectAtIndex:(offs+1)]]; + return; + } + } + + if (f->m_fgColor && [aCell respondsToSelector:@selector(setTextColor:)]) [aCell setTextColor:f->m_fgColor]; + } +} +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + if ([outlineView isKindOfClass:[SWELL_TreeView class]]) + { + SWELL_TreeView *f = (SWELL_TreeView *)outlineView; + if (f->m_selColors) + { + HTREEITEM sel = TreeView_GetSelection((HWND)outlineView); + if (sel && sel->m_dh == item) + { + int cnt = [f->m_selColors count]; + int offs = GetFocus() == (HWND)outlineView ? 0 : 2; + if (cnt>=offs+2) + { + if ([cell respondsToSelector:@selector(setTextColor:)]) [cell setTextColor:[f->m_selColors objectAtIndex:(offs+1)]]; + return; + } + } + } + if (f->m_fgColor && [cell respondsToSelector:@selector(setTextColor:)]) [cell setTextColor:f->m_fgColor]; + } +} + + +//- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item + +- (void)comboBoxWillPopUp:(NSNotification*)notification +{ + id sender=[notification object]; + int code=CBN_DROPDOWN; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); +} + +- (void)comboBoxSelectionDidChange:(NSNotification *)notification +{ + id sender=[notification object]; + int code=CBN_SELCHANGE; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); +} + +- (void)textDidEndEditing:(NSNotification *)aNotification +{ + id sender=[aNotification object]; + int code=EN_CHANGE; + if ([sender isKindOfClass:[NSComboBox class]]) return; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); +} + +- (void)controlTextDidChange:(NSNotification *)aNotification +{ + id sender=[aNotification object]; + int code=EN_CHANGE; + if ([sender isKindOfClass:[NSComboBox class]]) code=CBN_EDITCHANGE; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,([(NSControl*)sender tag])|(code<<16),(LPARAM)sender); +} + +- (void)menuNeedsUpdate:(NSMenu *)menu +{ + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_INITMENUPOPUP,(WPARAM)menu,0); +} + +-(void) swellOnControlDoubleClick:(id)sender +{ + if (!m_wndproc||m_hashaddestroy) return; + + if ([sender isKindOfClass:[NSTableView class]] && + [sender respondsToSelector:@selector(getSwellNotificationMode)]) + { + if ([(SWELL_ListView*)sender getSwellNotificationMode]) + m_wndproc((HWND)self,WM_COMMAND,(LBN_DBLCLK<<16)|[(NSControl*)sender tag],(LPARAM)sender); + else + { + SWELL_ListView* v = (SWELL_ListView*)sender; + NMLISTVIEW nmlv={{(HWND)sender,[(NSControl*)sender tag], NM_DBLCLK}, [v clickedRow], [sender clickedColumn], }; + SWELL_ListView_Row *row=v->m_items->Get(nmlv.iItem); + if (row) + nmlv.lParam = row->m_param; + m_wndproc((HWND)self,WM_NOTIFY,[(NSControl*)sender tag],(LPARAM)&nmlv); + } + } + else + { + NMCLICK nm={{(HWND)sender,[(NSControl*)sender tag],NM_DBLCLK}, }; + m_wndproc((HWND)self,WM_NOTIFY,[(NSControl*)sender tag],(LPARAM)&nm); + } +} + +- (void)outlineViewSelectionDidChange:(NSNotification *)notification +{ + NSOutlineView *sender=[notification object]; + NMTREEVIEW nmhdr={{(HWND)sender,(int)[sender tag],TVN_SELCHANGED},0,}; // todo: better treeview notifications + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); +} +- (void)tableViewSelectionDidChange:(NSNotification *)aNotification +{ + NSTableView *sender=[aNotification object]; + if ([sender respondsToSelector:@selector(getSwellNotificationMode)] && [(SWELL_ListView*)sender getSwellNotificationMode]) + { + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_COMMAND,(int)[sender tag] | (LBN_SELCHANGE<<16),(LPARAM)sender); + } + else + { + NMLISTVIEW nmhdr={{(HWND)sender,(int)[sender tag],LVN_ITEMCHANGED},(int)[sender selectedRow],0}; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); + + } +} + +- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn +{ + if ([tableView isKindOfClass:[SWELL_ListView class]] && + ((SWELL_ListView *)tableView)->m_cols && + !((SWELL_ListView *)tableView)->m_lbMode && + !(((SWELL_ListView *)tableView)->style & LVS_NOSORTHEADER) + ) + { + int col=((SWELL_ListView *)tableView)->m_cols->Find(tableColumn); + + NMLISTVIEW hdr={{(HWND)tableView,[tableView tag],LVN_COLUMNCLICK},-1,col}; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_NOTIFY,[tableView tag], (LPARAM) &hdr); + } +} + +-(void) onSwellCommand:(id)sender +{ + if (!m_wndproc || m_hashaddestroy) return; + + if ([sender isKindOfClass:[NSSlider class]]) + { + m_wndproc((HWND)self,WM_HSCROLL,0,(LPARAM)sender); + // WM_HSCROLL, WM_VSCROLL + } + else if ([sender isKindOfClass:[NSTableView class]]) + { + #if 0 + if ([sender isKindOfClass:[NSOutlineView class]]) + { +// NMTREEVIEW nmhdr={{(HWND)sender,(int)[sender tag],TVN_SELCHANGED},0,}; // todo: better treeview notifications + // m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); + } + else + { + + if ([sender respondsToSelector:@selector(getSwellNotificationMode)] && [(SWELL_ListView*)sender getSwellNotificationMode]) + { + m_wndproc((HWND)self,WM_COMMAND,(int)[sender tag] | (LBN_SELCHANGE<<16),(LPARAM)sender); + } + else + { + NMLISTVIEW nmhdr={{(HWND)sender,(int)[sender tag],LVN_ITEMCHANGED},(int)[sender clickedRow],0}; + m_wndproc((HWND)self,WM_NOTIFY,(int)[sender tag],(LPARAM)&nmhdr); + } + } + #endif + } + else + { + int cw=0; + if ([sender isKindOfClass:[NSComboBox class]]) return; // combo boxes will use delegate messages + else if ([sender isKindOfClass:[NSPopUpButton class]]) + { + cw=CBN_SELCHANGE; + } + else if ([sender isKindOfClass:[SWELL_Button class]]) + { + int rf; + if ((rf=(int)[(SWELL_Button*)sender swellGetRadioFlags])) + { + NSView *par=(NSView *)GetParent((HWND)sender); + if (par && [par isKindOfClass:[NSWindow class]]) par=[(NSWindow *)par contentView]; + if (par && [par isKindOfClass:[NSView class]]) + { + NSArray *ar=[par subviews]; + if (ar) + { + NSInteger x=[ar indexOfObject:sender]; + if (x != NSNotFound) + { + int n=[ar count]; + int a=x; + if (!(rf&2)) while (--a >= 0) + { + NSView *item=[ar objectAtIndex:a]; + if (!item || ![item isKindOfClass:[SWELL_Button class]]) break; // we may want to allow other controls in there, but for now if it's non-button we're done + int bla=(int)[(SWELL_Button*)item swellGetRadioFlags]; + if (bla&1) if ([(NSButton *)item state]!=NSOffState) [(NSButton *)item setState:NSOffState]; + if (bla&2) break; + } + a=x; + while (++a < n) + { + NSView *item=[ar objectAtIndex:a]; + if (!item || ![item isKindOfClass:[SWELL_Button class]]) break; // we may want to allow other controls in there, but for now if it's non-button we're done + int bla=(int)[(SWELL_Button*)item swellGetRadioFlags]; + if (bla&2) break; + if (bla&1) if ([(NSButton *)item state]!=NSOffState) [(NSButton *)item setState:NSOffState]; + } + } + } + } + } + } + else if ([sender isKindOfClass:[NSControl class]]) + { + NSEvent *evt=[NSApp currentEvent]; + int ty=evt?[evt type]:0; + if (evt && (ty==NSLeftMouseDown || ty==NSLeftMouseUp) && [evt clickCount] > 1) cw=STN_DBLCLK; + } + else if ([sender isKindOfClass:[NSMenuItem class]]) + { +// [[sender menu] update]; + // wish we could force the top level menu to update here, meh + } + m_wndproc((HWND)self,WM_COMMAND,[sender tag]|(cw<<16),(LPARAM)sender); + } + +} +-(void) dealloc +{ + + int x; + for (x=0;x=0&&idx=0&&idxhdc = m_paintctx_hdc; + ps->fErase=false; + ps->rcPaint.left = (int)m_paintctx_rect.origin.x; + ps->rcPaint.right = (int)ceil(m_paintctx_rect.origin.x+m_paintctx_rect.size.width); + ps->rcPaint.top = (int)m_paintctx_rect.origin.y; + ps->rcPaint.bottom = (int)ceil(m_paintctx_rect.origin.y+m_paintctx_rect.size.height); + } +} + +-(bool)swellCanPostMessage { return !m_hashaddestroy; } +-(int)swellEnumProps:(PROPENUMPROCEX)proc lp:(LPARAM)lParam +{ + WindowPropRec *p=m_props; + if (!p) return -1; + while (p) + { + WindowPropRec *ps=p; + p=p->_next; + if (!proc((HWND)self, ps->name, ps->data, lParam)) return 0; + } + return 1; +} + +-(void *)swellGetProp:(const char *)name wantRemove:(BOOL)rem +{ + WindowPropRec *p=m_props, *lp=NULL; + while (p) + { + if (p->name < (void *)65536) + { + if (name==p->name) break; + } + else if (name >= (void *)65536) + { + if (!strcmp(name,p->name)) break; + } + lp=p; p=p->_next; + } + if (!p) return NULL; + void *ret=p->data; + if (rem) + { + if (lp) lp->_next=p->_next; else m_props=p->_next; + free(p); + } + return ret; +} + +-(int)swellSetProp:(const char *)name value:(void *)val +{ + WindowPropRec *p=m_props; + while (p) + { + if (p->name < (void *)65536) + { + if (name==p->name) { p->data=val; return TRUE; }; + } + else if (name >= (void *)65536) + { + if (!strcmp(name,p->name)) { p->data=val; return TRUE; }; + } + p=p->_next; + } + p=(WindowPropRec*)malloc(sizeof(WindowPropRec)); + p->name = (name<(void*)65536) ? (char *)name : strdup(name); + p->data = val; p->_next=m_props; m_props=p; + return TRUE; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + if (m_enabled) + { + SendMessage((HWND)self, WM_MOUSEACTIVATE, 0, 0); + NSView* par=[self superview]; + if (par) SendMessage((HWND)par, WM_MOUSEACTIVATE, 0, 0); + return YES; + } + return NO; +} + +-(HMENU)swellGetMenu { return m_menu; } +-(BOOL)swellHasBeenDestroyed { return !!m_hashaddestroy; } +-(void)swellSetMenu:(HMENU)menu { + if (m_menu) SWELL_SetMenuDestination(m_menu,NULL); // don't free m_menu, but at least make it not point to us anymore + m_menu=menu; + if (m_menu) SWELL_SetMenuDestination(m_menu,(HWND)self); +} + + +- (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par +{ + NSRect contentRect=NSMakeRect(0,0,resstate ? resstate->width : 300,resstate ? resstate->height : 200); + if (!(self = [super initWithFrame:contentRect])) return self; + + memset(m_access_cacheptrs,0,sizeof(m_access_cacheptrs)); + m_isdirty=3; + m_glctx=NULL; + m_enabled=TRUE; + m_lastTopLevelOwner=NULL; + m_dlgproc=NULL; + m_wndproc=NULL; + m_userdata=0; + memset(&m_extradata,0,sizeof(m_extradata)); + m_tag=0; + m_isfakerightmouse=0; + m_hashaddestroy=false; + m_menu=0; + m_flip=0; + m_supports_ddrop=0; + m_paintctx_used=0; + m_paintctx_hdc=0; + m_props=0; + + m_titlestr[0]=0; + + m_wndproc=SwellDialogDefaultWindowProc; + + m_isopaque = !resstate || (resstate->windowTypeFlags&SWELL_DLG_WS_OPAQUE); + m_flip = !resstate || (resstate->windowTypeFlags&SWELL_DLG_WS_FLIPPED); + m_supports_ddrop = resstate && (resstate->windowTypeFlags&SWELL_DLG_WS_DROPTARGET); + + [self setHidden:YES]; + +// BOOL wasHid=[self isHidden]; + //if (!wasHid) [self setHidden:YES]; + + bool isChild=false; + + if ([parent isKindOfClass:[NSSavePanel class]]||[parent isKindOfClass:[NSOpenPanel class]]) + { + [(NSSavePanel *)parent setAccessoryView:self]; + [self setHidden:NO]; + } + else if ([parent isKindOfClass:[NSColorPanel class]]) + { + [(NSColorPanel *)parent setAccessoryView:self]; + [self setHidden:NO]; + } + else if ([parent isKindOfClass:[NSFontPanel class]]) + { + [(NSFontPanel *)parent setAccessoryView:self]; + [self setHidden:NO]; + } + else if ([parent isKindOfClass:[NSWindow class]]) + { + [(NSWindow *)parent setContentView:self]; + } + else + { + isChild=[parent isKindOfClass:[NSView class]]; + [parent addSubview:self]; + } + if (resstate) resstate->createFunc((HWND)self,resstate->windowTypeFlags); + + if (resstate) m_dlgproc=dlgproc; + else if (dlgproc) m_wndproc=(WNDPROC)dlgproc; + + if (resstate && (resstate->windowTypeFlags&SWELL_DLG_WS_DROPTARGET)) + { + [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSFilesPromisePboardType, nil]]; + } + + if (!resstate) + m_wndproc((HWND)self,WM_CREATE,0,par); + + if (m_dlgproc) + { + HWND hFoc=0; + NSArray *ar=[self subviews]; + if (ar && [ar count]>0) + { + int x; + for (x = 0; x < [ar count] && !hFoc; x ++) + { + NSView *v=[ar objectAtIndex:x]; + if (v && [v isKindOfClass:[NSScrollView class]]) v=[(NSScrollView *)v documentView]; + if (v && [v acceptsFirstResponder]) hFoc=(HWND)v; + } + } + + INT_PTR a; + if ((a=m_dlgproc((HWND)self,WM_INITDIALOG,(WPARAM)hFoc,par))) + { + // set first responder to first item in window + if (a == 0xbeef) hFoc = (HWND)self; // ret 0xbeef overrides to make the window itself focused (argh, need a cleaner way) + if (hFoc) + { + id wnd = [self window]; + if (wnd && [wnd firstResponder] != (id)hFoc) [wnd makeFirstResponder:(id)hFoc]; + } + + + if (parent && [self window] == (NSWindow *)parent && [(id)parent isKindOfClass:[SWELL_ModelessWindow class]] && ![(NSWindow *)parent isVisible]) + { + // on win32, if you do CreateDialog(), WM_INITDIALOG(ret=1), then ShowWindow(SW_SHOWNA), you get the + // window brought to front. this simulates that, hackishly. + ((SWELL_ModelessWindow *)parent)->m_wantInitialKeyWindowOnShow = true; + } + } + else + { + // if top level dialog,always set default focus if it wasn't set + // if this causes problems, change NSWindow to be SWELL_ModalDialog, as that would + // only affect DialogBox() and not CreateDialog(), which might be preferable. + if (hFoc && parent && [self window] == (NSWindow *)parent && [(id)parent isKindOfClass:[NSWindow class]]) + { + id fr = [(NSWindow *)parent firstResponder]; + if (!fr || fr == self || fr == (id)parent) [(NSWindow *)parent makeFirstResponder:(id)hFoc]; + + } + } + + SWELL_DoDialogColorUpdates((HWND)self,m_dlgproc,false); + } + +// if (!wasHid) + // [self setHidden:NO]; + + return self; +} + +-(void)setOpaque:(bool)isOpaque +{ + m_isopaque = isOpaque; +} + +-(BOOL)isOpaque +{ + return m_isopaque; +} + +- (void)setFrame:(NSRect)frameRect +{ + [super setFrame:frameRect]; + if (m_wndproc&&!m_hashaddestroy) m_wndproc((HWND)self,WM_SIZE,0,0); + InvalidateRect(GetParent((HWND)self),NULL,FALSE); +} + +- (void)keyDown:(NSEvent *)theEvent +{ + int flag,code=SWELL_MacKeyToWindowsKey(theEvent,&flag); + if (!m_wndproc || m_hashaddestroy || m_wndproc((HWND)self,WM_KEYDOWN,code,flag)==69) + { + [super keyDown:theEvent]; + } +} + +- (void)keyUp:(NSEvent *)theEvent +{ + int flag,code=SWELL_MacKeyToWindowsKey(theEvent,&flag); + if (!m_wndproc || m_hashaddestroy || m_wndproc((HWND)self,WM_KEYUP,code,flag)==69) + { + [super keyUp:theEvent]; + } +} + +#if SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN > 0 // not done yet + +- (void)didAddSubview:(NSView *)subview +{ + m_isdirty|=2; + NSView *view = [self superview]; + while (view) + { + if ([view isKindOfClass:[SWELL_hwndChild class]]) + { + if (((SWELL_hwndChild *)view)->m_isdirty&2) break; + ((SWELL_hwndChild *)view)->m_isdirty|=2; + } + view = [view superview]; + } +} +- (void)willRemoveSubview:(NSView *)subview +{ + m_isdirty|=3; + [self setNeedsDisplay:YES]; + NSView *view = [self superview]; + while (view) + { + if ([view isKindOfClass:[SWELL_hwndChild class]]) + { + if ((((SWELL_hwndChild *)view)->m_isdirty&3)==3) break; + ((SWELL_hwndChild *)view)->m_isdirty|=3; + } + [view setNeedsDisplay:YES]; + view = [view superview]; + } +} + +-(void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)vr rectIsVisibleRectForView:(NSView*)v topView:(NSView *)v2 +{ + + + + // once we figure out how to get other controls to notify their parents that the view is dirty, we can enable this for 10.4 + // 10.5+ has some nice property where it goes up the hierarchy + +// NSLog(@"r:%@ vr:%d v=%p tv=%p self=%p %p\n",NSStringFromRect(rect),vr,v,v2,self, [[self window] contentView]); + if (!useNoMiddleManCocoa() || ![self isOpaque] || [[self window] contentView] != self || [self isHiddenOrHasHiddenAncestor]) + { + [super _recursiveDisplayRectIfNeededIgnoringOpacity:rect isVisibleRect:vr rectIsVisibleRectForView:v topView:v2]; + return; + } + + if (!m_isdirty && ![self needsDisplay]) return; + + const NSRect *rlist=NULL; + NSInteger rlistcnt=0; + [self getRectsBeingDrawn:&rlist count:&rlistcnt]; + + + [self lockFocus]; + HDC hdc=SWELL_CreateGfxContext([NSGraphicsContext currentContext]); + + + const bool twoPassMode = false; // true makes it draw non-opaque items over all window backgrounds, but opaque children going last (so native controls over groups, etc) + // this is probably slower + + static WDL_PtrList ndlist; + int ndlist_oldsz=ndlist.GetSize(); + swellRenderOptimizely(twoPassMode?1:3,self,hdc,false,&ndlist,rlist,rlistcnt,0,0,true); + + while (ndlist.GetSize()>ndlist_oldsz+1) + { + NSView *v = (NSView *)ndlist.Get(ndlist.GetSize()-1); + ndlist.Delete(ndlist.GetSize()-1); + + int flag = (int)(INT_PTR) ndlist.Get(ndlist.GetSize()-1); + ndlist.Delete(ndlist.GetSize()-1); + + NSRect b = [v bounds]; + + if (rlistcnt && !(flag&1)) + { + int x; + for(x=0;x0 && r.size.height>0) + [v displayRectIgnoringOpacity:r]; + } + } + else + [v displayRectIgnoringOpacity:b]; + [v setNeedsDisplay:NO]; + [v release]; + } + + + if (twoPassMode) swellRenderOptimizely(2,self,hdc,false,&ndlist,rlist,rlistcnt,0,0,true); + SWELL_DeleteGfxContext(hdc); + [self unlockFocus]; + [self setNeedsDisplay:NO]; + +} +#endif + +-(void) drawRect:(NSRect)rect +{ + HDC hdc=SWELL_CreateGfxContext([NSGraphicsContext currentContext]); + DrawSwellViewRectImpl(self,rect,hdc); + SWELL_DeleteGfxContext(hdc); + m_isdirty=0; + +} + +- (void)rightMouseDragged:(NSEvent *)theEvent +{ + if (!m_enabled) return; + [self mouseDragged:theEvent]; +} +- (void)otherMouseDragged:(NSEvent *)theEvent +{ + if (!m_enabled) return; + [self mouseDragged:theEvent]; +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + if (!m_enabled) return; + + SWELL_SendMouseMessage(self,WM_MOUSEMOVE,theEvent); + if (SWELL_GetLastSetCursor()!=GetCursor()) SetCursor(SWELL_GetLastSetCursor()); +} +- (void)mouseMoved:(NSEvent *)theEvent +{ + if (DelegateMouseMove(self,theEvent)) return; + + if (m_enabled) if (!GetCapture() || GetCapture()==(HWND)self) { + SWELL_SendMouseMessage(self,WM_MOUSEMOVE, theEvent); + } +// [super mouseMoved:theEvent]; +} +- (void)mouseUp:(NSEvent *)theEvent +{ + if (!m_enabled) return; + if (m_isfakerightmouse) [self rightMouseUp:theEvent]; + else SWELL_SendMouseMessage(self,WM_LBUTTONUP,theEvent); +} +- (void)scrollWheel:(NSEvent *)theEvent +{ + if (!m_enabled) return; + if ([theEvent deltaY] != 0.0f) + { + SWELL_SendMouseMessage(self,WM_MOUSEWHEEL,theEvent); + } + if ([theEvent deltaX] != 0.0f) + { + SWELL_SendMouseMessage(self,WM_MOUSEHWHEEL,theEvent); + } +} +- (void)mouseDown:(NSEvent *)theEvent +{ + SWELL_FinishDragDrop(); + if (!m_enabled) return; + + m_isfakerightmouse=0; + if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) + { + [self rightMouseDown:theEvent]; + if ([theEvent clickCount]<2) m_isfakerightmouse=1; + return; + } + + SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_LBUTTONDBLCLK : WM_LBUTTONDOWN) ,theEvent); +} +- (void)rightMouseUp:(NSEvent *)theEvent +{ + if (!m_enabled) return; + m_isfakerightmouse=0; + SWELL_SendMouseMessage(self,WM_RBUTTONUP,theEvent); +} +- (void)rightMouseDown:(NSEvent *)theEvent +{ + m_isfakerightmouse=0; + if ([NSApp keyWindow] != [self window]) + { + SetFocus((HWND)[self window]); + } + SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_RBUTTONDBLCLK : WM_RBUTTONDOWN),theEvent); +} +- (void)otherMouseUp:(NSEvent *)theEvent +{ + if (!m_enabled) return; + SWELL_SendMouseMessage(self,WM_MBUTTONUP,theEvent); +} +- (void)otherMouseDown:(NSEvent *)theEvent +{ + if ([NSApp keyWindow] != [self window]) + { + SetFocus((HWND)[self window]); + } + SWELL_SendMouseMessage(self,([theEvent clickCount]>1 ? WM_MBUTTONDBLCLK : WM_MBUTTONDOWN),theEvent); +} + +// multitouch support + +static void MakeGestureInfo(NSEvent* evt, GESTUREINFO* gi, HWND hwnd, int type) +{ + memset(gi, 0, sizeof(GESTUREINFO)); + gi->cbSize = sizeof(GESTUREINFO); + + gi->hwndTarget = hwnd; + gi->dwID = type; + + NSWindow* wnd = [evt window]; + NSPoint pt = [evt locationInWindow]; + pt = [wnd convertBaseToScreen:pt]; + gi->ptsLocation.x = pt.x; + gi->ptsLocation.y = pt.y; +} + +- (void)magnifyWithEvent:(NSEvent*)evt +{ + GESTUREINFO gi; + MakeGestureInfo(evt, &gi, (HWND) self, GID_ZOOM); + + gi.dwFlags = GF_BEGIN; + gi.ullArguments = 1024; // arbitrary + SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); + + gi.dwFlags = GF_END; + float z = [evt deltaZ]; // should be the same as 10.6 [evt magnification] + int a = (int)(1024.0f*z+0.5); + if (!a) a = (z >= 0.0f ? 1 : -1); + a += 1024; + if (a < 512) a=512; + else if (a > 2048) a=2048; + gi.ullArguments = a; + SendMessage((HWND)self, WM_GESTURE, gi.ullArguments, (LPARAM)&gi); +} + +- (void)swipeWithEvent:(NSEvent*)evt +{ + GESTUREINFO gi; + MakeGestureInfo(evt, &gi, (HWND) self, GID_PAN); + + gi.dwFlags = GF_BEGIN; + gi.ullArguments = 0; // for this gesture we only care about ptsLocation + SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); + + gi.dwFlags = GF_END; + NSRect r = [self bounds]; + int dx=0; + int dy=0; + + // for swipe events, deltaX/Y is either -1 or +1, convert to "one page" + if ([evt deltaX] < 0.0f) dx = -r.size.width; + else if ([evt deltaX] > 0.0f) dx = r.size.width; + else if ([evt deltaY] < 0.0f) dy = r.size.height; + else if ([evt deltaY] > 0.0f) dy = -r.size.height; + + gi.ptsLocation.x += dx; + gi.ptsLocation.y += dy; + + SendMessage((HWND)self, WM_GESTURE, gi.ullArguments, (LPARAM)&gi); +} + +-(void) rotateWithEvent:(NSEvent*)evt +{ + GESTUREINFO gi; + MakeGestureInfo(evt, &gi, (HWND) self, GID_ROTATE); + + gi.dwFlags = GF_BEGIN; + gi.ullArguments = 0; // Windows sends the absolute starting rotation as the first message, Mac doesn't + SendMessage((HWND)self, WM_GESTURE, 0, (LPARAM)&gi); + + gi.dwFlags = GF_END; + float z = [evt rotation]; + int i = (int)32767.0f*z/60.0f; + if (!i) i = (z >= 0.0f ? 1 : -1); + i += 32767; + if (i < 0) i=0; + else if (i > 65535) i=65535; + gi.ullArguments = i; + SendMessage((HWND)self, WM_GESTURE, i, (LPARAM)&gi); +} + + +- (const char *)onSwellGetText { return m_titlestr; } +-(void)onSwellSetText:(const char *)buf { lstrcpyn(m_titlestr,buf,sizeof(m_titlestr)); } + + +// source-side drag/drop, only does something if source called SWELL_InitiateDragDrop while handling mouseDown +- (NSArray*) namesOfPromisedFilesDroppedAtDestination:(NSURL*) dropdestination +{ + NSArray* SWELL_DoDragDrop(NSURL*); + return SWELL_DoDragDrop(dropdestination); +} + + +/* +- (BOOL)becomeFirstResponder +{ + if (!m_enabled) return NO; + HWND foc=GetFocus(); + if (![super becomeFirstResponder]) return NO; + [self onSwellMessage:WM_ACTIVATE p1:WA_ACTIVE p2:(LPARAM)foc]; + return YES; +} + +- (BOOL)resignFirstResponder +{ + HWND foc=GetFocus(); + if (![super resignFirstResponder]) return NO; + [self onSwellMessage:WM_ACTIVATE p1:WA_INACTIVE p2:(LPARAM)foc]; + return YES; +} +*/ + +- (BOOL)acceptsFirstResponder +{ + if (m_enabled) + { + if (GetFocus() != (HWND)self) + { + SendMessage((HWND)self, WM_MOUSEACTIVATE, 0, 0); + } + return YES; + } + return NO; +} + +-(void)swellSetExtendedStyle:(LONG)st +{ + if (st&WS_EX_ACCEPTFILES) m_supports_ddrop=true; + else m_supports_ddrop=false; +} +-(LONG)swellGetExtendedStyle +{ + LONG ret=0; + if (m_supports_ddrop) ret|=WS_EX_ACCEPTFILES; + return ret; +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + if (!m_supports_ddrop) return NSDragOperationNone; + + if (SWELL_DDrop_onDragEnter) + { + HANDLE h = (HANDLE)[self swellExtendedDragOp:sender retGlob:YES]; + if (h) + { + NSPoint p=[[self window] convertBaseToScreen:[sender draggingLocation]]; + POINT pt={(int)(p.x+0.5),(int)(p.y+0.5)}; + SWELL_DDrop_onDragEnter(h,pt); + GlobalFree(h); + } + } + + return NSDragOperationGeneric; +} +- (BOOL) wantsPeriodicDraggingUpdates +{ + return NO; +} +- (NSDragOperation)draggingUpdated:(id )sender +{ + if (!m_supports_ddrop) return NSDragOperationNone; + + if (SWELL_DDrop_onDragOver) + { + NSPoint p=[[self window] convertBaseToScreen:[sender draggingLocation]]; + POINT pt={(int)(p.x+0.5),(int)(p.y+0.5)}; + SWELL_DDrop_onDragOver(pt); + } + + return NSDragOperationGeneric; + +} +- (void)draggingExited:(id )sender +{ + if (m_supports_ddrop && SWELL_DDrop_onDragLeave) SWELL_DDrop_onDragLeave(); +} + +-(HANDLE)swellExtendedDragOp:(id )sender retGlob:(BOOL)retG +{ + if (!m_supports_ddrop) return 0; + + NSPasteboard *pboard; + NSDragOperation sourceDragMask; + sourceDragMask = [sender draggingSourceOperationMask]; + pboard = [sender draggingPasteboard]; + + enum { PB_FILEREF=1, PB_FILEPROMISE }; + int pbtype = 0; + if ([[pboard types] containsObject:NSFilenamesPboardType]) pbtype |= PB_FILEREF; + if ([[pboard types] containsObject:NSFilesPromisePboardType]) pbtype |= PB_FILEPROMISE; + if (!pbtype) return 0; + + int sz=sizeof(DROPFILES); + + bool maketmpfn = false; + NSArray *files = 0; + if (pbtype&PB_FILEREF) + { + files = [pboard propertyListForType:NSFilenamesPboardType]; + } + else if (pbtype&PB_FILEPROMISE) + { + NSArray* exts = [pboard propertyListForType:NSFilesPromisePboardType]; // just the file extensions + if (retG) + { + files = exts; + maketmpfn = true; + } + else if (SWELL_DDrop_getDroppedFileTargetPath) + { + char ext[256]; + ext[0] = 0; + if ([exts objectAtIndex:0]) SWELL_CFStringToCString([exts objectAtIndex:0], ext, sizeof(ext)); + + const char* droppath = SWELL_DDrop_getDroppedFileTargetPath(ext); + if (!droppath || !droppath[0]) droppath = "/tmp/"; + NSString* pathstr = (NSString*)SWELL_CStringToCFString(droppath); + NSURL* dest = [NSURL fileURLWithPath:pathstr]; + + files = [sender namesOfPromisedFilesDroppedAtDestination:dest]; // tells the drag source to create the files + + if ([files count]) + { + NSMutableArray* paths=[NSMutableArray arrayWithCapacity:[files count]]; + int i; + for (i=0; i < [files count]; ++i) + { + NSString* fn=[files objectAtIndex:i]; + if (fn) + { + [paths addObject:[pathstr stringByAppendingPathComponent:fn]]; + } + } + files=paths; + } + + [pathstr release]; + } + } + if (!files) return 0; + + int x; + for (x = 0; x < [files count]; x ++) + { + NSString *sv=[files objectAtIndex:x]; + if (sv) + { + char text[4096]; + text[0]=0; + SWELL_CFStringToCString(sv,text,sizeof(text)); + sz+=strlen(text)+1; + if (maketmpfn) sz += strlen("tmp."); + } + } + + NSPoint tpt = [self convertPoint:[sender draggingLocation] fromView:nil]; + + HANDLE gobj=GlobalAlloc(0,sz+1); + DROPFILES *df=(DROPFILES*)gobj; + df->pFiles=sizeof(DROPFILES); + df->pt.x = (int)(tpt.x+0.5); + df->pt.y = (int)(tpt.y+0.5); + df->fNC = FALSE; + df->fWide = FALSE; + char *pout = (char *)(df+1); + for (x = 0; x < [files count]; x ++) + { + NSString *sv=[files objectAtIndex:x]; + if (sv) + { + char text[4096]; + text[0]=0; + SWELL_CFStringToCString(sv,text,sizeof(text)); + if (maketmpfn) + { + strcpy(pout, "tmp."); + pout += strlen("tmp."); + } + strcpy(pout,text); + pout+=strlen(pout)+1; + } + } + *pout=0; + + if (!retG) + { + [self onSwellMessage:WM_DROPFILES p1:(WPARAM)gobj p2:0]; + GlobalFree(gobj); + } + + return gobj; +} + +- (BOOL)performDragOperation:(id )sender +{ + if (m_supports_ddrop && SWELL_DDrop_onDragLeave) SWELL_DDrop_onDragLeave(); + + HWND cv = NULL; // view to disable "setwindowrepre()" for + + id dragsrc = [sender draggingSource]; + if ([dragsrc isKindOfClass:[NSView class]]) + { + if ([(NSView *)dragsrc window] == [self window]) // this means we're likely dragging from the titlebar, so we gotta disable setwindowrepre cause cocoa sucks + { + cv = (HWND) [[self window] contentView]; + } + } + + if (cv) SetProp(cv,"SWELL_DisableWindowRepre",(HANDLE)TRUE); + + NSView *v=[self hitTest:[[self superview] convertPoint:[sender draggingLocation] fromView:nil]]; + if (v && [v isDescendantOf:self]) + { + while (v && v!=self) + { + if ([v respondsToSelector:@selector(swellExtendedDragOp:retGlob:)]) + if ([(SWELL_hwndChild *)v swellExtendedDragOp:sender retGlob:NO]) + { + if (cv) RemoveProp(cv,"SWELL_DisableWindowRepre"); + return YES; + } + v=[v superview]; + } + } + + BOOL ret=!![self swellExtendedDragOp:sender retGlob:NO]; + if (cv) RemoveProp(cv,"SWELL_DisableWindowRepre"); + return ret; +} + +-(unsigned int)swellCreateWindowFlags +{ + return m_create_windowflags; +} + + + + +// NSAccessibility + + +- (id)accessibilityHitTest:(NSPoint)point +{ + id ret = NULL; + id use_obj = NULL; + SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); + if (use_obj) + { + ret = [use_obj accessibilityHitTest:point]; + if (ret == use_obj && [ret accessibilityIsIgnored]) ret = NULL; + } + + if (!ret) ret = [super accessibilityHitTest:point]; + return ret; +} +- (id)accessibilityFocusedUIElement +{ + id use_obj = NULL, ret = NULL; + SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); + if (use_obj) + { + ret = [use_obj accessibilityFocusedUIElement]; + if (ret == use_obj) ret= NULL; + } + if (!ret) ret = [super accessibilityFocusedUIElement]; + return ret; +} + +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + id ret = [super accessibilityAttributeValue:attribute]; + int wo=0; + if ([attribute isEqual:NSAccessibilityChildrenAttribute] || (wo = !![attribute isEqual:NSAccessibilityVisibleChildrenAttribute])) + { + id *cp = wo ? m_access_cacheptrs+3 : m_access_cacheptrs; + id use_obj = NULL; + SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); + if (use_obj) + { + if (cp[0] && cp[1] && use_obj == cp[2] && (ret==cp[1] || [ret isEqualToArray:cp[1]])) return cp[0]; + + NSArray *ar=NULL; + if (ret && [ret count]) + { + ar = [NSMutableArray arrayWithArray:ret]; + [(NSMutableArray *)ar addObject:use_obj]; + } + else ar = [NSArray arrayWithObject:use_obj]; + + int x; + for (x=0;x<3;x++) if (cp[x]) { [cp[x] release]; cp[x]=0; } + + //cp[1]=ret; + //cp[2]=use_obj; + + ret = NSAccessibilityUnignoredChildren(ar); + //cp[0]=ret; + + for (x=0;x<3;x++) if (cp[x]) [cp[x] retain]; + + return ret; + } + int x; + for (x=0;x<3;x++) if (cp[x]) { [cp[x] release]; cp[x]=0; } + } + + return ret; +} +// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. +- (BOOL)accessibilityIsIgnored +{ + if (![[self subviews] count]) + { + id use_obj = NULL; + SendMessage((HWND)self,WM_GETOBJECT,0x1001,(LPARAM)&use_obj); + + if (use_obj) + { + return YES; + } + } + return [super accessibilityIsIgnored]; +} + + + + + + +@end + + + + + +static HWND last_key_window; + + +#define SWELLDIALOGCOMMONIMPLEMENTS_WND(ISMODAL) \ +-(BOOL)acceptsFirstResponder { return m_enabled?YES:NO; } \ +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return m_enabled?YES:NO; } \ +- (void)setFrame:(NSRect)frameRect display:(BOOL)displayFlag \ +{ \ + [super setFrame:frameRect display:displayFlag]; \ + if((int)frameRect.size.width != (int)lastFrameSize.width || (int)frameRect.size.height != (int)lastFrameSize.height) { \ + SWELL_hwndChild *hc = (SWELL_hwndChild*)[self contentView]; \ + sendSwellMessage(hc,WM_SIZE,0,0); \ + if ([hc isOpaque]) InvalidateRect((HWND)hc,NULL,FALSE); \ + lastFrameSize=frameRect.size; \ + } \ +} \ +- (void)windowDidMove:(NSNotification *)aNotification { \ + NSRect f=[self frame]; \ + sendSwellMessage([self contentView], WM_MOVE,0, MAKELPARAM((int)f.origin.x,(int)f.origin.y)); \ +} \ +- (BOOL)accessibilityIsIgnored \ +{ \ + if (!([self styleMask] & NSTitledWindowMask) && ![[[self contentView] subviews] count]) return YES; \ + return [super accessibilityIsIgnored]; \ +} \ +-(void)swellDoDestroyStuff \ +{ \ + if (last_key_window==(HWND)self) last_key_window=0; \ + OwnedWindowListRec *p=m_ownedwnds; m_ownedwnds=0; \ + while (p) \ + { \ + OwnedWindowListRec *next=p->_next; \ + DestroyWindow((HWND)p->hwnd); \ + free(p); p=next; \ + } \ + if (last_key_window==(HWND)self) last_key_window=0; \ + if (m_owner) { \ + [(SWELL_ModelessWindow*)m_owner swellRemoveOwnedWindow:self]; \ + if ([NSApp keyWindow] == self) [(SWELL_ModelessWindow*)m_owner makeKeyWindow]; \ + m_owner=0; \ + } \ +} \ +-(void)dealloc \ +{ \ + [self swellDoDestroyStuff]; \ + [super dealloc]; \ +} \ +- (void)swellDestroyAllOwnedWindows \ +{ \ + OwnedWindowListRec *p=m_ownedwnds; m_ownedwnds=0; \ + while (p) \ + { \ + OwnedWindowListRec *next=p->_next; \ + DestroyWindow((HWND)p->hwnd); \ + free(p); p=next; \ + } \ +} \ +- (void)resignKeyWindow { \ + [super resignKeyWindow]; \ + if (g_swell_terminating) return; \ + sendSwellMessage([self contentView],WM_ACTIVATE,WA_INACTIVE,0); \ + last_key_window=(HWND)self; \ +} \ +-(void)becomeKeyWindow \ +{ \ + [super becomeKeyWindow]; \ + if (g_swell_terminating) return; \ + NSView *foc=last_key_window && IsWindow(last_key_window) ? [(NSWindow *)last_key_window contentView] : 0; \ + HMENU menu=0; \ + if (foc && [foc respondsToSelector:@selector(swellHasBeenDestroyed)] && [(SWELL_hwndChild*)foc swellHasBeenDestroyed]) foc=NULL; \ + NSView *cv = [self contentView]; \ + if (!cv || ![cv respondsToSelector:@selector(swellHasBeenDestroyed)] || ![(SWELL_hwndChild*)cv swellHasBeenDestroyed]) { \ + if ([cv respondsToSelector:@selector(swellGetMenu)]) menu = [(SWELL_hwndChild*)cv swellGetMenu]; \ + if (!menu) menu=ISMODAL && g_swell_defaultmenumodal ? g_swell_defaultmenumodal : g_swell_defaultmenu; \ + if (menu && menu != (HMENU)[NSApp mainMenu] && !g_swell_terminating) [NSApp setMainMenu:(NSMenu *)menu]; \ + sendSwellMessage(cv,WM_ACTIVATE,WA_ACTIVE,(LPARAM)foc); \ + sendSwellMessage(cv,WM_MOUSEACTIVATE,0,0); \ + } \ +} \ +-(BOOL)windowShouldClose:(id)sender \ +{ \ + NSView *v=[self contentView]; \ + if ([v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) \ + if (![(SWELL_hwndChild*)v onSwellMessage:WM_CLOSE p1:0 p2:0]) \ + [(SWELL_hwndChild*)v onSwellMessage:WM_COMMAND p1:IDCANCEL p2:0]; \ + return NO; \ +} \ +- (BOOL)canBecomeKeyWindow { return !!m_enabled && !g_swell_terminating; } \ +- (void **)swellGetOwnerWindowHead { return (void **)&m_ownedwnds; } \ +- (void)swellAddOwnedWindow:(NSWindow*)wnd \ +{ \ + OwnedWindowListRec *p=m_ownedwnds; \ + while (p) { \ + if (p->hwnd == wnd) return; \ + p=p->_next; \ + } \ + p=(OwnedWindowListRec*)malloc(sizeof(OwnedWindowListRec)); \ + p->hwnd=wnd; p->_next=m_ownedwnds; m_ownedwnds=p; \ + if ([wnd respondsToSelector:@selector(swellSetOwner:)]) [(SWELL_ModelessWindow*)wnd swellSetOwner:self]; \ + if (SWELL_owned_windows_levelincrease) if ([wnd isKindOfClass:[NSWindow class]]) \ + { \ + int extra = [wnd isKindOfClass:[SWELL_ModelessWindow class]] ? ((SWELL_ModelessWindow *)wnd)->m_wantraiseamt : 0; \ + if ([NSApp isActive]) [wnd setLevel:[self level]+1+extra]; \ + } \ +} \ +- (void)swellRemoveOwnedWindow:(NSWindow *)wnd \ +{ \ + OwnedWindowListRec *p=m_ownedwnds, *lp=NULL; \ + while (p) { \ + if (p->hwnd == wnd) { \ + if (lp) lp->_next=p->_next; \ + else m_ownedwnds=p->_next; \ + free(p); \ + return; \ + } \ + lp=p; \ + p=p->_next; \ + } \ +} \ +- (void)swellResetOwnedWindowLevels { \ + if (SWELL_owned_windows_levelincrease) { OwnedWindowListRec *p=m_ownedwnds; \ + bool active = [NSApp isActive]; \ + int l=[self level]+!!active; \ + while (p) { \ + if (p->hwnd) { \ + int extra = active && [(id)p->hwnd isKindOfClass:[SWELL_ModelessWindow class]] ? ((SWELL_ModelessWindow *)p->hwnd)->m_wantraiseamt : 0; \ + [(NSWindow *)p->hwnd setLevel:l+extra]; \ + if ([(id)p->hwnd respondsToSelector:@selector(swellResetOwnedWindowLevels)]) \ + [(id)p->hwnd swellResetOwnedWindowLevels]; \ + } \ + p=p->_next; \ + } \ + } \ +} \ +- (void)swellSetOwner:(id)owner { m_owner=owner; } \ +- (id)swellGetOwner { return m_owner; } \ +- (NSSize)minSize \ +{ \ + MINMAXINFO mmi={0}; \ + NSSize minsz=(NSSize)[super minSize]; \ + mmi.ptMinTrackSize.x=(int)minsz.width; mmi.ptMinTrackSize.y=(int)minsz.height; \ + sendSwellMessage([self contentView],WM_GETMINMAXINFO,0,(LPARAM)&mmi); \ + minsz.width=mmi.ptMinTrackSize.x; minsz.height=mmi.ptMinTrackSize.y; \ + return minsz; \ +} \ +- (NSSize)maxSize \ +{ \ + MINMAXINFO mmi={0}; \ + NSSize maxsz=(NSSize)[super maxSize]; NSSize tmp=maxsz;\ + if (tmp.width<1)tmp.width=1; else if (tmp.width > 1000000.0) tmp.width=1000000.0; \ + if (tmp.height<1)tmp.height=1; else if (tmp.height > 1000000.0) tmp.height=1000000.0; \ + mmi.ptMaxTrackSize.x=(int)tmp.width; mmi.ptMaxTrackSize.y=(int)tmp.height; \ + sendSwellMessage([self contentView], WM_GETMINMAXINFO, 0, (LPARAM)&mmi); \ + if (mmi.ptMaxTrackSize.x < 1000000) maxsz.width=mmi.ptMaxTrackSize.x; \ + if (mmi.ptMaxTrackSize.y < 1000000) maxsz.height=mmi.ptMaxTrackSize.y; \ + return maxsz; \ +} \ + + + +#define INIT_COMMON_VARS \ + m_enabled=TRUE; \ + m_owner=0; \ + m_ownedwnds=0; + + +#if 0 +#define DOWINDOWMINMAXSIZES(ch) \ +{ \ + MINMAXINFO mmi={0}; \ + NSSize minsz=(NSSize)[super contentMinSize]; \ + mmi.ptMinTrackSize.x=(int)minsz.width; mmi.ptMinTrackSize.y=(int)minsz.height; \ + sendSwellMessage(ch,WM_GETMINMAXINFO,0,(LPARAM)&mmi); \ + minsz.width=mmi.ptMinTrackSize.x; minsz.height=mmi.ptMinTrackSize.y; \ + [super setContentMinSize:minsz]; \ +} + +#endif + +static void GetInitialWndPos(HWND owner, int h, int* x, int* y) +{ + RECT r; + if (owner) GetWindowRect(owner, &r); + else SWELL_GetViewPort(&r, 0, false); + *x = r.left+50; + *y = r.bottom-h-100; +} + + +@implementation SWELL_ModelessWindow : NSWindow + +SWELLDIALOGCOMMONIMPLEMENTS_WND(0) + + +- (id)initModelessForChild:(HWND)child owner:(HWND)owner styleMask:(unsigned int)smask +{ + INIT_COMMON_VARS + m_wantInitialKeyWindowOnShow=0; + m_wantraiseamt=0; + lastFrameSize.width=lastFrameSize.height=0.0f; + + NSRect cr=[(NSView *)child bounds]; + + int wx, wy; + GetInitialWndPos(owner, cr.size.height, &wx, &wy); + NSRect contentRect=NSMakeRect(wx,wy,cr.size.width,cr.size.height); + if (!(self = [super initWithContentRect:contentRect styleMask:smask backing:NSBackingStoreBuffered defer:NO])) return self; + + [self setDelegate:(id)self]; + [self disableCursorRects]; + [self setAcceptsMouseMovedEvents:YES]; + [self setContentView:(NSView *)child]; + [self useOptimizedDrawing:YES]; + updateWindowCollection(self); + + if (owner && [(id)owner respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(id)owner swellAddOwnedWindow:self]; + } + else if (owner && [(id)owner isKindOfClass:[NSView class]]) + { + NSWindow *w=[(id)owner window]; + if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; + } + } + + [self display]; + return self; +} + +- (id)initModeless:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par outputHwnd:(HWND *)hwndOut forceStyles:(unsigned int)smask +{ + INIT_COMMON_VARS + m_wantInitialKeyWindowOnShow=0; + m_wantraiseamt=0; + + lastFrameSize.width=lastFrameSize.height=0.0f; + + int w = (resstate ? resstate->width : 10); + int h = (resstate ? resstate->height : 10); + + int wx, wy; + GetInitialWndPos(parent, h, &wx, &wy); + NSRect contentRect=NSMakeRect(wx,wy,w,h); + int sf=smask; + + if (resstate) + { + sf |= NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask; + if (resstate->windowTypeFlags&SWELL_DLG_WS_RESIZABLE) sf |= NSResizableWindowMask; + } + + if (!(self = [super initWithContentRect:contentRect styleMask:sf backing:NSBackingStoreBuffered defer:NO])) return self; + + [self disableCursorRects]; + [self setAcceptsMouseMovedEvents:YES]; + [self useOptimizedDrawing:YES]; + [self setDelegate:(id)self]; + updateWindowCollection(self); + + if (resstate&&resstate->title) SetWindowText((HWND)self, resstate->title); + + + if (parent && [(id)parent respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(id)parent swellAddOwnedWindow:self]; + } + else if (parent && [(id)parent isKindOfClass:[NSView class]]) + { + NSWindow *w=[(id)parent window]; + if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; + } + } + + [self retain]; // in case WM_INITDIALOG goes and releases us + + SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:resstate Parent:(NSView *)self dlgProc:dlgproc Param:par]; // create a new child view class + ch->m_create_windowflags=sf; + *hwndOut = (HWND)ch; + + [ch release]; + + [self display]; + [self release]; // matching retain above + + return self; +} +-(NSInteger)level +{ + //if (SWELL_owned_windows_levelincrease) return NSNormalWindowLevel; + return [super level]; +} + +#if SWELL_CUT_OUT_COMPOSITING_MIDDLEMAN > 1 +-(void) displayIfNeeded +{ + if (![[self contentView] isOpaque]) + { + [super displayIfNeeded]; + } + else + { + // NSThemeFrame + if ([self viewsNeedDisplay]) + { + [[self contentView] _recursiveDisplayRectIfNeededIgnoringOpacity:NSMakeRect(0,0,0,0) isVisibleRect:YES rectIsVisibleRectForView:[self contentView] topView:[self contentView]]; + [self setViewsNeedDisplay:NO]; + [self flushWindow]; + } + + } +} +#endif + +@end + + + + +@implementation SWELL_ModalDialog : NSPanel + +SWELLDIALOGCOMMONIMPLEMENTS_WND(1) + + + +- (id)initDialogBox:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par +{ + m_rv=0; + m_hasrv=false; + INIT_COMMON_VARS + + NSRect contentRect=NSMakeRect(0,0,resstate->width,resstate->height); + unsigned int sf=(NSTitledWindowMask|NSClosableWindowMask|((resstate->windowTypeFlags&SWELL_DLG_WS_RESIZABLE)? NSResizableWindowMask : 0)); + if (!(self = [super initWithContentRect:contentRect styleMask:sf backing:NSBackingStoreBuffered defer:NO])) return self; + + [self setAcceptsMouseMovedEvents:YES]; + [self disableCursorRects]; + [self useOptimizedDrawing:YES]; + [self setDelegate:(id)self]; + updateWindowCollection(self); + + if (parent && [(id)parent respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(id)parent swellAddOwnedWindow:self]; + } + else if (parent && [(id)parent isKindOfClass:[NSView class]]) + { + NSWindow *w=[(id)parent window]; + if (w && [w respondsToSelector:@selector(swellAddOwnedWindow:)]) + { + [(SWELL_ModelessWindow*)w swellAddOwnedWindow:self]; + } + } + if (resstate&&resstate->title) SetWindowText((HWND)self, resstate->title); + + SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:resstate Parent:(NSView *)self dlgProc:dlgproc Param:par]; // create a new child view class + ch->m_create_windowflags=sf; + [ch setHidden:NO]; +// DOWINDOWMINMAXSIZES(ch) + [ch release]; + + [self setHidesOnDeactivate:NO]; + [self display]; + + return self; +} + + +-(void)swellSetModalRetVal:(int)r +{ + m_hasrv=true; + m_rv=r; +} +-(int)swellGetModalRetVal +{ + return m_rv; +} +-(bool)swellHasModalRetVal +{ + return m_hasrv; +} + +@end + +void EndDialog(HWND wnd, int ret) +{ + if (!wnd) return; + + NSWindow *nswnd=NULL; + NSView *nsview = NULL; + if ([(id)wnd isKindOfClass:[NSView class]]) + { + nsview = (NSView *)wnd; + nswnd = [nsview window]; + } + else if ([(id)wnd isKindOfClass:[NSWindow class]]) + { + nswnd = (NSWindow *)wnd; + nsview = [nswnd contentView]; + } + if (!nswnd) return; + + if ([nswnd respondsToSelector:@selector(swellSetModalRetVal:)]) + [(SWELL_ModalDialog*)nswnd swellSetModalRetVal:ret]; + + if ([NSApp modalWindow] == nswnd) + { + sendSwellMessage(nsview,WM_DESTROY,0,0); + + NSEvent *evt=[NSApp currentEvent]; + if (evt && [evt window] == nswnd) + { + [NSApp stopModal]; + } + + [NSApp abortModal]; // always call this, otherwise if running in runModalForWindow: it can often require another even tto come through before things continue + + [nswnd close]; + } +} + + +int SWELL_DialogBox(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) +{ + SWELL_DialogResourceIndex *p=resById(reshead,resid); + if (!p||(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) return -1; + SWELL_ModalDialog *box = [[SWELL_ModalDialog alloc] initDialogBox:p Parent:parent dlgProc:dlgproc Param:param]; + + if (!box) return -1; + + if ([box swellHasModalRetVal]) // detect EndDialog() in WM_INITDIALOG + { + int ret=[box swellGetModalRetVal]; + sendSwellMessage([box contentView],WM_DESTROY,0,0); + [box release]; + return ret; + } + + if (0 && ![NSApp isActive]) // using this enables better background processing (i.e. if the app isnt active it still runs) + { + [NSApp activateIgnoringOtherApps:YES]; + NSModalSession session = [NSApp beginModalSessionForWindow:box]; + for (;;) + { + if ([NSApp runModalSession:session] != NSRunContinuesResponse) break; + Sleep(1); + } + [NSApp endModalSession:session]; + } + else + { + [NSApp runModalForWindow:box]; + } + int ret=[box swellGetModalRetVal]; + [box release]; + return ret; +} + +HWND SWELL_CreateModelessFrameForWindow(HWND childW, HWND ownerW, unsigned int windowFlags) +{ + SWELL_ModelessWindow *ch=[[SWELL_ModelessWindow alloc] initModelessForChild:childW owner:ownerW styleMask:windowFlags]; + return (HWND)ch; +} + + +HWND SWELL_CreateDialog(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param) +{ + unsigned int forceStyles=0; + if ((((INT_PTR)resid)&~0xf)==0x400000) + { + int a = (int)(INT_PTR)resid; + forceStyles = NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask; + if (a&1) forceStyles|=NSResizableWindowMask; + if (a&2) forceStyles&=~NSMiniaturizableWindowMask; + if (a&4) forceStyles&=~NSClosableWindowMask; + resid=NULL; + } + SWELL_DialogResourceIndex *p=resById(reshead,resid); + if (!p&&resid) return 0; + + NSView *parview=NULL; + if (parent && ([(id)parent isKindOfClass:[NSView class]] || + [(id)parent isKindOfClass:[NSSavePanel class]] || + [(id)parent isKindOfClass:[NSOpenPanel class]] || + [(id)parent isKindOfClass:[NSColorPanel class]] || + [(id)parent isKindOfClass:[NSFontPanel class]] + )) parview=(NSView *)parent; + else if (parent && [(id)parent isKindOfClass:[NSWindow class]]) parview=(NSView *)[(id)parent contentView]; + + if ((!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD)) && parview) + { + SWELL_hwndChild *ch=[[SWELL_hwndChild alloc] initChild:p Parent:parview dlgProc:dlgproc Param:param]; // create a new child view class + ch->m_create_windowflags=(NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask); + [ch release]; + return (HWND)ch; + } + else + { + HWND h=NULL; + [[SWELL_ModelessWindow alloc] initModeless:p Parent:parent dlgProc:dlgproc Param:param outputHwnd:&h forceStyles:forceStyles]; + return h; + } + + return 0; +} + + +HMENU SWELL_GetDefaultWindowMenu() { return g_swell_defaultmenu; } +void SWELL_SetDefaultWindowMenu(HMENU menu) +{ + g_swell_defaultmenu=menu; +} +HMENU SWELL_GetDefaultModalWindowMenu() +{ + return g_swell_defaultmenumodal; +} +void SWELL_SetDefaultModalWindowMenu(HMENU menu) +{ + g_swell_defaultmenumodal=menu; +} + + + +SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; // this eventually will go into a per-module stub file + + +#import + + +#if 0 +static void PrintAllHIViews(HIViewRef f, const char *bla) +{ + char tmp[4096]; + sprintf(tmp,"%s:%08x",bla,f); + + HIRect r; + HIViewGetFrame(f,&r); + printf("%s beg %f %f %f %f\n",tmp,r.origin.x,r.origin.y,r.size.width, r.size.height); + HIViewRef a=HIViewGetFirstSubview(f); + while (a) + { + PrintAllHIViews(a,tmp); + a=HIViewGetNextView(a); + } + printf("%s end\n",tmp); +} +#endif + +#ifndef __LP64__ +// carbon event handler for carbon-in-cocoa +OSStatus CarbonEvtHandler(EventHandlerCallRef nextHandlerRef, EventRef event, void* userdata) +{ + SWELL_hwndCarbonHost* _this = (SWELL_hwndCarbonHost*)userdata; + UInt32 evtkind = GetEventKind(event); + + switch (evtkind) + { + case kEventWindowActivated: + if (!g_swell_terminating) [NSApp setMainMenu:nil]; + break; + + case kEventWindowGetClickActivation: + { + ClickActivationResult car = kActivateAndHandleClick; + SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult, sizeof(ClickActivationResult), &car); + } + break; + + case kEventWindowHandleDeactivate: + { + if (_this) + { + WindowRef wndref = (WindowRef)[_this->m_cwnd windowRef]; + if (wndref) ActivateWindow(wndref, true); + } + } + break; + + case kEventControlBoundsChanged: + { + if (_this && !_this->m_whileresizing) + { + Rect prevr, curr; + GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, 0, sizeof(Rect), 0, &prevr); + GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0, sizeof(Rect), 0, &curr); + + RECT parr; + GetWindowRect((HWND)_this, &parr); + parr.left += curr.left-prevr.left; + parr.top += curr.top-prevr.top; + parr.right += curr.right-prevr.right; + parr.bottom += curr.bottom-prevr.bottom; + _this->m_whileresizing = true; + SetWindowPos((HWND)_this, 0, parr.left, parr.right, parr.right-parr.left, parr.bottom-parr.top, SWP_NOZORDER|SWP_NOACTIVATE); + _this->m_whileresizing = false; + } + } + break; + + case kEventRawKeyDown: + case kEventRawKeyUp: + case kEventRawKeyModifiersChanged: + { + if (_this->m_wantallkeys) return eventNotHandledErr; + + WindowRef wndref = (WindowRef)[_this->m_cwnd windowRef]; + if (wndref) + { + ControlRef ctlref=0; + GetKeyboardFocus(wndref, &ctlref); + if (ctlref) + { + ControlKind ctlkind = { 0, 0 }; + GetControlKind(ctlref, &ctlkind); + if (ctlkind.kind == kControlKindEditText || + ctlkind.kind == kControlKindEditUnicodeText || + ctlkind.kind == kControlKindHITextView) + { + // ControlDefinitions.h, HITextViews.h, etc list control types, + // we may want to pass on some other types too + return eventNotHandledErr; + } + } + } + + UInt32 keycode; + UInt32 modifiers; + char c[2] = { 0, 0 }; + GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(UInt32), 0, &keycode); + GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &modifiers); + GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(char), 0, &c[0]); + + NSEventType type; + if (evtkind == kEventRawKeyDown) type = NSKeyDown; + else if (evtkind == kEventRawKeyUp) type = NSKeyUp; + else if (evtkind == kEventRawKeyModifiersChanged) type = NSFlagsChanged; + + NSString* str = (NSString*)SWELL_CStringToCFString(c); + NSTimeInterval ts = 0; // [[NSApp currentevent] timestamp]; + NSEvent* evt = [NSEvent keyEventWithType:type location:NSMakePoint(0,0) + modifierFlags:modifiers + timestamp:ts windowNumber:0 + context:[NSGraphicsContext currentContext] + characters:str charactersIgnoringModifiers:str + isARepeat:NO keyCode:keycode]; + [str release]; + if (evt) [NSApp sendEvent:evt]; + return noErr; + } + } + return noErr; +} + +void SWELL_CarbonWndHost_SetWantAllKeys(void* carbonhost, bool want) +{ + SWELL_hwndCarbonHost* h = (SWELL_hwndCarbonHost*)carbonhost; + if (h) h->m_wantallkeys = want; +} + +#endif // __LP + +@implementation SWELL_hwndCarbonHost + +- (id)initCarbonChild:(NSView *)parent rect:(Rect*)r composit:(bool)wantComp +{ + if (!(self = [super initChild:nil Parent:parent dlgProc:nil Param:nil])) return self; + + m_wantallkeys=false; + +#ifndef __LP64__ + WindowRef wndref=0; + CreateNewWindow (kPlainWindowClass, (wantComp ? kWindowCompositingAttribute : 0) | kWindowStandardHandlerAttribute|kWindowNoShadowAttribute, r, &wndref); + if (wndref) + { + // eventually we should set this and have the real NSWindow parent call ActivateWindow when activated/deactivated + // SetWindowActivationScope( m_wndref, kWindowActivationScopeNone); + + // adding a Carbon event handler to catch special stuff that NSWindow::initWithWindowRef + // doesn't automatically redirect to a standard Cocoa window method + + ControlRef ctl=0; + if (!wantComp) CreateRootControl(wndref, &ctl); // creating root control here so callers must use GetRootControl + + EventTypeSpec winevts[] = + { + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowGetClickActivation }, + { kEventClassWindow, kEventWindowHandleDeactivate }, + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged }, + }; + int nwinevts = sizeof(winevts)/sizeof(EventTypeSpec); + + EventTypeSpec ctlevts[] = + { + //{ kEventClassControl, kEventControlInitialize }, + //{ kEventClassControl, kEventControlDraw }, + { kEventClassControl, kEventControlBoundsChanged }, + }; + int nctlevts = sizeof(ctlevts)/sizeof(EventTypeSpec); + + EventHandlerRef wndhandler=0, ctlhandler=0; + InstallWindowEventHandler(wndref, CarbonEvtHandler, nwinevts, winevts, self, &wndhandler); + if (!wantComp) InstallControlEventHandler(ctl, CarbonEvtHandler, nctlevts, ctlevts, self, &ctlhandler); + m_wndhandler = wndhandler; + m_ctlhandler = ctlhandler; + + // initWithWindowRef does not retain // MAKE SURE THIS IS NOT BAD TO DO + //CFRetain(wndref); + + m_cwnd = [[NSWindow alloc] initWithWindowRef:wndref]; + [m_cwnd setDelegate:self]; + + ShowWindow(wndref); + + //[[parent window] addChildWindow:m_cwnd ordered:NSWindowAbove]; + //[self swellDoRepos]; + SetTimer((HWND)self,1,10,NULL); + } +#endif + return self; +} + +-(BOOL)swellIsCarbonHostingView { return YES; } + + +-(void)close +{ + KillTimer((HWND)self,1); + +#ifndef __LP64__ + if (m_wndhandler) + { + EventHandlerRef wndhandler = (EventHandlerRef)m_wndhandler; + RemoveEventHandler(wndhandler); + m_wndhandler = 0; + } + if (m_ctlhandler) + { + EventHandlerRef ctlhandler = (EventHandlerRef)m_ctlhandler; + RemoveEventHandler(ctlhandler); + m_ctlhandler = 0; + } + + if (m_cwnd) + { + if ([m_cwnd parentWindow]) [[m_cwnd parentWindow] removeChildWindow:m_cwnd]; + [m_cwnd orderOut:self]; + [m_cwnd close]; // this disposes the owned wndref + m_cwnd=0; + } +#endif +} + +-(void)dealloc +{ + [self close]; + [super dealloc]; // ?! +} + +- (void)SWELL_Timer:(id)sender +{ +#ifndef __LP64__ + id uinfo=[sender userInfo]; + if ([uinfo respondsToSelector:@selector(getValue)]) + { + int idx=(int)(INT_PTR)[(SWELL_DataHold*)uinfo getValue]; + if (idx==1) + { + if (![self superview] || [[self superview] isHiddenOrHasHiddenAncestor]) + { + NSWindow *oldw=[m_cwnd parentWindow]; + if (oldw) + { + [oldw removeChildWindow:(NSWindow *)m_cwnd]; + [m_cwnd orderOut:self]; + } + } + else + { + if (![m_cwnd parentWindow]) + { + NSWindow *par = [self window]; + if (par) + { + [par addChildWindow:m_cwnd ordered:NSWindowAbove]; + [self swellDoRepos]; + } + } + else + { + if (GetCurrentEventButtonState()&7) + { + if ([NSApp keyWindow] == [self window]) + { + POINT p; + GetCursorPos(&p); + RECT r; + GetWindowRect((HWND)self,&r); + if (r.top>r.bottom) + { + int a=r.top; + r.top=r.bottom; + r.bottom=a; + } + if (m_cwnd && p.x >=r.left &&p.x < r.right && p.y >= r.top && p.y < r.bottom) + { + [(NSWindow *)m_cwnd makeKeyWindow]; + } + } + } + } + } + return; + } + KillTimer((HWND)self,idx); + return; + } +#endif +} +- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam +{ + if (msg == WM_DESTROY) + { + if (m_cwnd) + { + if ([NSApp keyWindow] == m_cwnd) // restore focus to highest window that is not us! + { + NSArray *ar = [NSApp orderedWindows]; + int x; + for (x = 0; x < (ar ? [ar count] : 0); x ++) + { + NSWindow *w=[ar objectAtIndex:x]; + if (w && w != m_cwnd && [w isVisible]) { [w makeKeyWindow]; break; } + } + } + + [self close]; + } + } + return [super onSwellMessage:msg p1:wParam p2:lParam]; +} +- (void)windowDidResignKey:(NSNotification *)aNotification +{ +} +- (void)windowDidBecomeKey:(NSNotification *)aNotification +{ +} + + +- (void)viewDidMoveToWindow +{ + [super viewDidMoveToWindow]; + if (m_cwnd) + { + // reparent m_cwnd to new owner + NSWindow *neww=[self window]; + NSWindow *oldw=[m_cwnd parentWindow]; + if (neww != oldw) + { + if (oldw) [oldw removeChildWindow:m_cwnd]; + } + } +} +-(void)swellDoRepos +{ +#ifndef __LP64__ + if (m_cwnd) + { + RECT r; + GetWindowRect((HWND)self,&r); + if (r.top>r.bottom) + { + int a=r.top; + r.top=r.bottom; + r.bottom=a; + } + + // [m_cwnd setFrameOrigin:NSMakePoint(r.left,r.top)]; + + { + Rect bounds; + bounds.left = r.left; + bounds.top = CGRectGetHeight(CGDisplayBounds(kCGDirectMainDisplay))-r.bottom; + // GetWindowBounds (m_wndref, kWindowContentRgn, &bounds); + bounds.right = bounds.left + (r.right-r.left); + bounds.bottom = bounds.top + (r.bottom-r.top); + + WindowRef wndref = (WindowRef)[m_cwnd windowRef]; + SetWindowBounds (wndref, kWindowContentRgn, &bounds); + + // might make sense to only do this on initial show, but doesnt seem to hurt to do it often + WindowAttributes wa=0; + GetWindowAttributes(wndref,&wa); + + if (wa&kWindowCompositingAttribute) + { +// [[m_cwnd contentView] setNeedsDisplay:YES]; + HIViewRef ref = HIViewGetRoot(wndref); + if (ref) + { + // PrintAllHIViews(ref,""); + + HIViewRef ref2=HIViewGetFirstSubview(ref); + while (ref2) + { + /* + HIRect r3=CGRectMake(0,0,bounds.right-bounds.left,bounds.bottom-bounds.top); + HIViewRef ref3=HIViewGetFirstSubview(ref2); + while (ref3) + { + HIViewSetVisible(ref3,true); + HIViewSetNeedsDisplay(ref3,true); + HIViewSetFrame(ref3,&r3); + ref3=HIViewGetNextView(ref3); + } + */ + + // HIViewSetVisible(ref2,true); + HIViewSetNeedsDisplay(ref2,true); + ref2=HIViewGetNextView(ref2); + } + //HIViewSetVisible(ref,true); + HIViewSetNeedsDisplay(ref,true); + HIViewRender(ref); + } + } + else + { + +#if 0 + ControlRef rc=NULL; + GetRootControl(m_wndref,&rc); + if (rc) + { + RgnHandle rgn=NewRgn(); + GetControlRegion(rc,kControlEntireControl,rgn); + UpdateControls(m_wndref,rgn); + CloseRgn(rgn); + } +#endif + // Rect r={0,0,bounds.bottom-bounds.top,bounds.right-bounds.left}; + // InvalWindowRect(m_wndref,&r); + + // or we could just do: + DrawControls(wndref); + } + } + } +#endif +} + +- (void)viewDidMoveToSuperview +{ + [super viewDidMoveToSuperview]; + [self swellDoRepos]; +} +- (void)setFrameSize:(NSSize)newSize +{ + [super setFrameSize:newSize]; + [self swellDoRepos]; +} +- (void)setFrame:(NSRect)frameRect +{ + [super setFrame:frameRect]; + [self swellDoRepos]; +} +- (void)setFrameOrigin:(NSPoint)newOrigin +{ + [super setFrameOrigin:newOrigin]; + [self swellDoRepos]; +} + + +-(BOOL)isOpaque +{ + return NO; +} + +@end + +HWND SWELL_GetAudioUnitCocoaView(HWND parent, AudioUnit aunit, AudioUnitCocoaViewInfo* viewinfo, RECT* r) +{ + NSString* classname = (NSString*)(viewinfo->mCocoaAUViewClass[0]); + if (!classname) return 0; + + NSBundle* bundle=0; + if ([NSBundle respondsToSelector:@selector(bundleWithURL:)]) + { + bundle=[NSBundle bundleWithURL:(NSURL*)viewinfo->mCocoaAUViewBundleLocation]; + } + + if (!bundle) + { + NSString* path = (NSString*)(CFURLCopyFileSystemPath(viewinfo->mCocoaAUViewBundleLocation,kCFURLPOSIXPathStyle)); + if (path) + { + bundle = [NSBundle bundleWithPath:path]; + [path release]; + } + } + + if (!bundle) return 0; + + Class factoryclass = [bundle classNamed:classname]; + if (![factoryclass conformsToProtocol: @protocol(AUCocoaUIBase)]) return 0; + if (![factoryclass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) return 0; + id viewfactory = [[factoryclass alloc] init]; + if (!viewfactory) return 0; + NSView* view = [viewfactory uiViewForAudioUnit:aunit withSize:NSMakeSize(r->right-r->left, r->bottom-r->top)]; + if (!view) + { + [viewfactory release]; + return 0; + } + + [(NSView*)parent addSubview:view]; + NSRect bounds = [view bounds]; + r->left = r->top = 0; + r->right = bounds.size.width; + r->bottom = bounds.size.height; + [viewfactory release]; + + return (HWND)view; +} + + +HWND SWELL_CreateCarbonWindowView(HWND viewpar, void **wref, RECT* r, bool wantcomp) // window is created with a root control +{ + RECT wndr = *r; + ClientToScreen(viewpar, (POINT*)&wndr); + ClientToScreen(viewpar, (POINT*)&wndr+1); + //Rect r2 = { wndr.top, wndr.left, wndr.bottom, wndr.right }; + Rect r2 = { wndr.bottom, wndr.left, wndr.top, wndr.right }; + SWELL_hwndCarbonHost *w = [[SWELL_hwndCarbonHost alloc] initCarbonChild:(NSView*)viewpar rect:&r2 composit:wantcomp]; + if (w) *wref = [w->m_cwnd windowRef]; + return (HWND)w; +} + +void* SWELL_GetWindowFromCarbonWindowView(HWND cwv) +{ + SWELL_hwndCarbonHost* w = (SWELL_hwndCarbonHost*)cwv; + if (w) return [w->m_cwnd windowRef]; + return 0; +} + +void SWELL_AddCarbonPaneToView(HWND cwv, void* pane) // not currently used +{ +#ifndef __LP64__ + SWELL_hwndCarbonHost* w = (SWELL_hwndCarbonHost*)cwv; + if (w) + { + WindowRef wndref = (WindowRef)[w->m_cwnd windowRef]; + if (wndref) + { + EventTypeSpec ctlevts[] = + { + //{ kEventClassControl, kEventControlInitialize }, + //{ kEventClassControl, kEventControlDraw }, + { kEventClassControl, kEventControlBoundsChanged }, + }; + int nctlevts = sizeof(ctlevts)/sizeof(EventTypeSpec); + + EventHandlerRef ctlhandler = (EventHandlerRef)w->m_ctlhandler; + InstallControlEventHandler((ControlRef)pane, CarbonEvtHandler, nctlevts, ctlevts, w, &ctlhandler); + } + } +#endif +} + + +@interface NSButton (TextColor) + +- (NSColor *)textColor; +- (void)setTextColor:(NSColor *)textColor; + +@end + +@implementation NSButton (TextColor) + +- (NSColor *)textColor +{ + NSAttributedString *attrTitle = [self attributedTitle]; + int len = [attrTitle length]; + NSRange range = NSMakeRange(0, MIN(len, 1)); // take color from first char + NSDictionary *attrs = [attrTitle fontAttributesInRange:range]; + NSColor *textColor = [NSColor controlTextColor]; + if (attrs) { + textColor = [attrs objectForKey:NSForegroundColorAttributeName]; + } + return textColor; +} + +- (void)setTextColor:(NSColor *)textColor +{ + NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] + initWithAttributedString:[self attributedTitle]]; + int len = [attrTitle length]; + NSRange range = NSMakeRange(0, len); + [attrTitle addAttribute:NSForegroundColorAttributeName + value:textColor + range:range]; + [attrTitle fixAttributesInRange:range]; + [self setAttributedTitle:attrTitle]; + [attrTitle release]; +} + +@end + + +static char* s_dragdropsrcfn = 0; +static void (*s_dragdropsrccallback)(const char*) = 0; + +void SWELL_InitiateDragDrop(HWND hwnd, RECT* srcrect, const char* srcfn, void (*callback)(const char* dropfn)) +{ + SWELL_FinishDragDrop(); + + if (![(id)hwnd isKindOfClass:[SWELL_hwndChild class]]) return; + + s_dragdropsrcfn = strdup(srcfn); + s_dragdropsrccallback = callback; + + char* p = s_dragdropsrcfn+strlen(s_dragdropsrcfn)-1; + while (p >= s_dragdropsrcfn && *p != '.') --p; + ++p; + + NSString* str = (NSString*)SWELL_CStringToCFString(p); + NSRect r = NSMakeRect(srcrect->left, srcrect->top, srcrect->right-srcrect->left, srcrect->bottom-srcrect->top); + NSEvent* evt = [NSApp currentEvent]; + [(NSView*)hwnd dragPromisedFilesOfTypes:[NSArray arrayWithObject:str] fromRect:r source:(NSView*)hwnd slideBack:YES event:evt]; + [str release]; +} + +// owner owns srclist, make copies here etc +void SWELL_InitiateDragDropOfFileList(HWND hwnd, RECT *srcrect, const char **srclist, int srccount, HICON icon) +{ + SWELL_FinishDragDrop(); + + if (![(id)hwnd isKindOfClass:[SWELL_hwndChild class]]) return; + + NSMutableArray *ar = [[NSMutableArray alloc] initWithCapacity:srccount]; + int x; + + for(x=0;xleft,srcrect->top) offset:NSMakeSize(0,0) event:[NSApp currentEvent] pasteboard:pb source:(id)hwnd slideBack:YES]; + + [ar release]; +} + + +static bool _file_exists(const char* fn) +{ + struct stat sb= { 0 }; + return !stat(fn, &sb); +} + +NSArray* SWELL_DoDragDrop(NSURL* droplocation) +{ + NSArray* fnarr=0; + if (s_dragdropsrcfn && s_dragdropsrccallback && droplocation) + { + const char* srcpath=s_dragdropsrcfn; + + const char* fn = srcpath+strlen(srcpath)-1; + while (fn >= srcpath && *fn != '/') --fn; + ++fn; + + WDL_String destpath; + destpath.SetFormatted(4096, "%s/%s", [[droplocation path] UTF8String], fn); + + bool ok=!_file_exists(destpath.Get()); + if (!ok) + { + int ret=NSRunAlertPanel(@"Copy", + @"An item named \"%s\" already exists in this location. Do you want to replace it with the one you're moving?", + @"Keep Both Files", @"Stop", @"Replace", fn); + + if (ret == -1) // replace + { + ok=true; + } + else if (ret == 1) // keep both + { + WDL_String base(destpath.Get()); + char* p=base.Get(); + int len=strlen(p); + const char* ext=""; + int incr=0; + + const char* q=fn+strlen(fn)-1; + while (q > fn && *q != '.') --q; + if (*q == '.') + { + ext=q; + len -= strlen(ext); + p[len]=0; + } + + int digits=0; + int i; + for (i=0; i < 3 && len > i+1 && isdigit(p[len-i-1]); ++i) ++digits; + if (len > digits+1 && (p[len-digits-1] == ' ' || p[len-digits-1] == '-' || p[len-digits-1] == '_')) + { + incr=atoi(p+len-digits); + p[len-digits]=0; + } + else + { + base.Append(" "); + } + + WDL_String trypath; + while (!ok && ++incr < 1000) + { + trypath.SetFormatted(4096, "%s%03d%s", base.Get(), incr, ext); + ok=!_file_exists(trypath.Get()); + } + + if (ok) destpath.Set(trypath.Get()); + } + } + + if (ok) + { + s_dragdropsrccallback(destpath.Get()); + ok=_file_exists(destpath.Get()); + } + + if (ok) + { + fn=destpath.Get(); + fn += strlen(fn)-1; + while (fn >= destpath.Get() && *fn != '/') --fn; + ++fn; + + NSString* nfn=(NSString*)SWELL_CStringToCFString(fn); + fnarr=[NSArray arrayWithObject:nfn]; + [nfn release]; + } + } + + SWELL_FinishDragDrop(); + return fnarr; +} + +void SWELL_FinishDragDrop() +{ + free(s_dragdropsrcfn); + s_dragdropsrcfn = 0; + s_dragdropsrccallback = 0; +} + +bool SWELL_SetGLContextToView(HWND h) +{ + if (!h) [NSOpenGLContext clearCurrentContext]; + else if ([(id)h isKindOfClass:[SWELL_hwndChild class]]) + { + SWELL_hwndChild *hc = (SWELL_hwndChild*)h; + if (hc->m_glctx) + { + [hc->m_glctx makeCurrentContext]; + return true; + } + } + return false; +} + +void SWELL_SetViewGL(HWND h, bool wantGL) +{ + if (h && [(id)h isKindOfClass:[SWELL_hwndChild class]]) + { + SWELL_hwndChild *hc = (SWELL_hwndChild*)h; + if (wantGL != !!hc->m_glctx) + { + if (wantGL) + { + NSOpenGLPixelFormatAttribute atr[] = {(NSOpenGLPixelFormatAttribute)0}; // todo: optionally add any attributes before the 0 + NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:atr]; + + hc->m_glctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil]; + [fmt release]; + } + else + { + if ([NSOpenGLContext currentContext] == hc->m_glctx) [NSOpenGLContext clearCurrentContext]; + [hc->m_glctx release]; + hc->m_glctx=0; + } + } + + } +} + +bool SWELL_GetViewGL(HWND h) +{ + return h && [(id)h isKindOfClass:[SWELL_hwndChild class]] && ((SWELL_hwndChild*)h)->m_glctx; +} +void DrawSwellViewRectImpl(SWELL_hwndChild *view, NSRect rect, HDC hdc) +{ + if (view->m_hashaddestroy) + { + return; + } + view->m_paintctx_hdc=hdc; + if (view->m_paintctx_hdc && view->m_glctx) + { + view->m_paintctx_hdc->GLgfxctx = view->m_glctx; + + [view->m_glctx setView:view]; + [view->m_glctx makeCurrentContext]; + [view->m_glctx update]; + } + view->m_paintctx_rect=rect; + view->m_paintctx_used=false; + DoPaintStuff(view->m_wndproc,(HWND)view,view->m_paintctx_hdc,&view->m_paintctx_rect); + + if (view->m_paintctx_hdc && view->m_glctx && [NSOpenGLContext currentContext] == view->m_glctx) + { + [NSOpenGLContext clearCurrentContext]; + } + view->m_paintctx_hdc=0; + if (!view->m_paintctx_used) { + /*[super drawRect:rect];*/ + } + +#if 0 + // debug: show everything + static CGColorSpaceRef cspace; + if (!cspace) cspace=CGColorSpaceCreateDeviceRGB(); + float cols[4]={0.0f,1.0f,0.0f,0.8f}; + CGColorRef color=CGColorCreate(cspace,cols); + + CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + CGContextSetStrokeColorWithColor(ctx,color); + CGContextStrokeRectWithWidth(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height), 1); + + CGColorRelease(color); + + cols[0]=1.0f; + cols[1]=0.0f; + cols[2]=0.0f; + cols[3]=1.0f; + color=CGColorCreate(cspace,cols); + + NSRect rect2=[view bounds]; + CGContextSetStrokeColorWithColor(ctx,color); + CGContextStrokeRectWithWidth(ctx, CGRectMake(rect2.origin.x,rect2.origin.y,rect2.size.width,rect2.size.height), 1); + + + CGColorRelease(color); + + cols[0]=0.0f; + cols[1]=0.0f; + cols[2]=1.0f; + cols[3]=0.7f; + color=CGColorCreate(cspace,cols); + cols[3]=0.25; + cols[2]=0.5; + CGColorRef color2=CGColorCreate(cspace,cols); + + NSArray *ar = [view subviews]; + if (ar) + { + int x; + for(x=0;x<[ar count];x++) + { + NSView *v = [ar objectAtIndex:x]; + if (v && ![v isHidden]) + { + NSRect rect = [v frame]; + CGContextSetStrokeColorWithColor(ctx,color); + CGContextStrokeRectWithWidth(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height), 1); + CGContextSetFillColorWithColor(ctx,color2); + CGContextFillRect(ctx, CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height)); + } + } + + // draw children + } + CGColorRelease(color); + CGColorRelease(color2); + +#endif + + + +} + +void swellRenderOptimizely(int passflags, SWELL_hwndChild *view, HDC hdc, BOOL doforce, WDL_PtrList *needdraws, const NSRect *rlist, int rlistcnt, int draw_xlate_x, int draw_xlate_y, bool iscv) +{ + if (view->m_isdirty&1) doforce=true; + NSArray *sv = [view subviews]; + if (doforce&&(passflags & ([sv count]?1:2))) + DrawSwellViewRectImpl(view,[view bounds], hdc); + + if (sv) + { + [sv retain]; + int x,n=[sv count]; + HBRUSH bgbr=0; + bool bgbr_valid=false; + for(x=0;xm_isdirty)|| [v needsDisplay]) + { + if (isSwellChild) + { + NSRect fr = [v frame]; + CGContextSaveGState(hdc->ctx); + CGContextClipToRect(hdc->ctx,CGRectMake(fr.origin.x,fr.origin.y,fr.size.width,fr.size.height)); + CGContextTranslateCTM(hdc->ctx, fr.origin.x,fr.origin.y); + swellRenderOptimizely(passflags,(SWELL_hwndChild*)v,hdc,doforce,needdraws,rlist,rlistcnt,draw_xlate_x-(int)fr.origin.x,draw_xlate_y-(int)fr.origin.y,false); + CGContextRestoreGState(hdc->ctx); + if (passflags&2) [v setNeedsDisplay:NO]; + bgbr_valid=false; // code in swellRenderOptimizely() may trigger WM_CTLCOLORDLG which may invalidate our brush, so clear the cached value here + } + else if (passflags&1) + { + if ([v isKindOfClass:[NSScrollView class]]) + { + NSView *sv = [(NSScrollView *)v contentView]; + if (sv) + { + [v retain]; + needdraws->Add((void*)(INT_PTR)(doforce?1:0)); + needdraws->Add(v); + v=sv; + } + } + [v retain]; + if (!doforce && ![v isOpaque]) + { + + NSRect fr= [v frame]; + + // we could recursively go up looking for WM_CTLCOLORDLG, but actually we just need to use the current window + if (!bgbr_valid) // note that any code in this loop that does anything that could trigger messages might invalidate bgbr, so it should clear bgbr_checked here + { + bgbr=(HGDIOBJ)SendMessage((HWND)view,WM_CTLCOLORDLG,(WPARAM)hdc,(LPARAM)view); + bgbr_valid=true; + } + + if (!iscv) fr = [view convertRect:fr toView:[[view window] contentView]]; + + int ri; + for(ri=0;ri0 && ff.size.height>0) + { + RECT r={(int)ff.origin.x,(int)ff.origin.y,(int)(ff.origin.x+ff.size.width),(int)(ff.origin.y+ff.size.height)}; + r.left+=draw_xlate_x; + r.right+=draw_xlate_x; + r.top+=draw_xlate_y; + r.bottom+=draw_xlate_y; + if (bgbr_valid && bgbr && bgbr != (HBRUSH)1) FillRect(hdc,&r,bgbr); + else SWELL_FillDialogBackground(hdc,&r,3); + } + } + } + needdraws->Add((void*)(INT_PTR)(doforce?1:0)); + needdraws->Add(v); + } + } + } + } + [sv release]; + } + if (passflags&2) + view->m_isdirty=0; +} + +#endif diff --git a/WDL/swell/swell-dlggen.h b/WDL/swell/swell-dlggen.h new file mode 100644 index 00000000..93c77ec9 --- /dev/null +++ b/WDL/swell/swell-dlggen.h @@ -0,0 +1,280 @@ + +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + DialogBox emulation is here. To declare the resource at a global level, use (in any source file that includes this file and resource.h): + + + #ifdef MAC + + + SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_SOMEDIALOG,0,"Dialog Box Title",222,55,1.8) // width, height, scale (1.8 is usually good) + + BEGIN + DEFPUSHBUTTON "OK",IDOK,117,33,47,14 + CONTROL "Expand MIDI tracks to new REAPER tracks ",IDC_CHECK1, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,7,214,10 + CONTROL "Merge MIDI tempo map to project tempo map at ", + IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,19, + 214,10 + PUSHBUTTON "Cancel",IDCANCEL,168,33,50,14 + END + + SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_SOMEDIALOG) + + + #endif + + + This file also provides functions to dynamically create controls in a view from a win32 resource script. + + + +*/ + + + + +#ifndef _SWELL_DLGGEN_H_ +#define _SWELL_DLGGEN_H_ + +#ifdef BEGIN +#undef BEGIN +#endif + +#ifdef END +#undef END +#endif + + +struct SWELL_DlgResourceEntry +{ + const char *str1; + int flag1; + const char *str2; + + int p1; // often used for ID + + // todo: see at runtime if some of these can be short instead of int (p2-p6 probably can, but not completely sure) -- i.e. do we use any + // big values in flags. note: it can't be unsigned short, because we want negative values. + int p2, p3, p4, p5, p6; // meaning is dependent on class +}; + + +#define BEGIN {NULL, +#define END }, + +#define PUSHBUTTON }, { "__SWELL_BUTTON", 0, +#define DEFPUSHBUTTON }, { "__SWELL_BUTTON", 1, +#define EDITTEXT }, { "__SWELL_EDIT", 0, "", +#define CTEXT }, { "__SWELL_LABEL", 0, +#define LTEXT }, { "__SWELL_LABEL", -1, +#define RTEXT }, { "__SWELL_LABEL", 1, +#define CONTROL }, { +#define COMBOBOX }, { "__SWELL_COMBO", 0, "", +#define GROUPBOX }, { "__SWELL_GROUP", 0, +#define CHECKBOX }, { "__SWELL_CHECKBOX", 0, +#define LISTBOX }, { "__SWELL_LISTBOX", 0, "", + +#define NOT + +// flags we may use +#define CBS_DROPDOWNLIST 0x0003L +#define CBS_DROPDOWN 0x0002L +#define CBS_SORT 0x0100L +#define ES_PASSWORD 0x0020L +#define ES_READONLY 0x0800L +#define ES_WANTRETURN 0x1000L +#define ES_NUMBER 0x2000L + +#define SS_LEFT 0 +#define SS_CENTER 0x1L +#define SS_BLACKRECT 0x4L +#define SS_BLACKFRAME (SS_BLACKRECT) +#define SS_LEFTNOWORDWRAP 0xCL +#define SS_TYPEMASK 0x1FL +#define SS_NOTIFY 0x0100L + +#define BS_CENTER 0x0300L +#define BS_LEFTTEXT 0x0020L +#define BS_GROUPBOX 0x20000000 +#define BS_DEFPUSHBUTTON 0x10000000 +#define BS_PUSHBUTTON 0x8000000 + +#define LVS_LIST 0 /* 0x0003 */ +#define LVS_NOCOLUMNHEADER 0x4000 +#define LVS_NOSORTHEADER 0x8000 +#define LVS_REPORT 0x0001 +#define LVS_TYPEMASK 0x0003 +#define LVS_SINGLESEL 0x0004 +#define LVS_OWNERDATA 0x1000 +#define LVS_SORTASCENDING 0x0010 +#define LVS_SORTDESCENDING 0x0020 + +#define LBS_SORT 0x0002L +#define LBS_OWNERDRAWFIXED 0x0010L +#define LBS_EXTENDEDSEL 0x0800L + +#define ES_LEFT 0 +#define ES_CENTER 1 +#define ES_RIGHT 2 + +// flags we ignore +#define LVS_SHOWSELALWAYS 0 +#define LVS_SHAREIMAGELISTS 0 +#define ES_AUTOHSCROLL 0 +#define ES_MULTILINE 0 +#define ES_AUTOVSCROLL 0 +#define GROUP 0 +#define PBS_SMOOTH 0 +#define CBS_AUTOHSCROLL 0 +#define TBS_NOTICKS 0 +#define TBS_TOP 0 +#define TBS_BOTH 0 +#define BS_BITMAP 0 +#define LBS_NOINTEGRALHEIGHT 0 +#define TVS_HASLINES 0 +#define TVS_SHOWSELALWAYS 0 +#define TVS_HASBUTTONS 0 +#define BS_FLAT 0 +#define TVS_DISABLEDRAGDROP 0 +#define TVS_TRACKSELECT 0 +#define TVS_NONEVENHEIGHT 0 +#define BS_LEFT 0 +#define SS_SUNKEN 0 +#define BS_RIGHT 0 +#define WS_EX_STATICEDGE 0 +#define WS_EX_RIGHT 0 +#define SS_CENTERIMAGE 0 +#define SS_NOPREFIX 0 + + +#ifndef IDC_STATIC +#define IDC_STATIC 0 +#endif + + + + +#define SWELL_DLG_WS_CHILD 1 +#define SWELL_DLG_WS_RESIZABLE 2 +#define SWELL_DLG_WS_FLIPPED 4 +#define SWELL_DLG_WS_NOAUTOSIZE 8 +#define SWELL_DLG_WS_OPAQUE 16 +#define SWELL_DLG_WS_DROPTARGET 32 + +typedef struct SWELL_DialogResourceIndex +{ + const char *resid; + const char *title; + int windowTypeFlags; + void (*createFunc)(HWND, int); + int width,height; + struct SWELL_DialogResourceIndex *_next; +} SWELL_DialogResourceIndex; + +typedef struct SWELL_CursorResourceIndex +{ + const char *resid; + const char *resname; + POINT hotspot; + HCURSOR cachedCursor; + struct SWELL_CursorResourceIndex *_next; +} SWELL_CursorResourceIndex; + + + +static inline HWND __SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags=0, int exstyle=0) +{ + return SWELL_MakeButton(def,label,idx,x,y,w,h,flags); +} +static inline HWND __SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags=0) +{ + return SWELL_MakeEditField(idx,x,y,w,h,flags); +} +static inline HWND __SWELL_MakeLabel(int align, const char *label, int idx, int x, int y, int w, int h, int flags=0, int exflags=0) +{ + return SWELL_MakeLabel(align,label,idx,x,y,w,h,flags); +} +static inline HWND __SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags=0) +{ + return SWELL_MakeCombo(idx,x,y,w,h,flags); +} +static inline HWND __SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles=0) +{ + return SWELL_MakeListBox(idx,x,y,w,h,styles); +} + +static inline HWND __SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle=0) +{ + return SWELL_MakeControl(cname,idx,classname,style,x,y,w,h,exstyle); +} + +static inline HWND __SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style=0) +{ + return SWELL_MakeGroupBox(name,idx,x,y,w,h,style); +} + +static void SWELL_Register_Cursor_Resource(const char *idx, const char *name, int hotspot_x, int hotspot_y) +{ + extern SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; + + SWELL_CursorResourceIndex *ri = (SWELL_CursorResourceIndex*)malloc(sizeof(SWELL_CursorResourceIndex)); + ri->hotspot.x = hotspot_x; + ri->hotspot.y = hotspot_y; + ri->resname=name; + ri->cachedCursor=0; + ri->resid = idx; + ri->_next = SWELL_curmodule_cursorresource_head; + SWELL_curmodule_cursorresource_head = ri; +} + + +class SWELL_DialogRegHelper { + public: + SWELL_DialogResourceIndex m_rec; + SWELL_DialogRegHelper(SWELL_DialogResourceIndex **h, void (*cf)(HWND,int), int recid, int flags, const char *titlestr, int wid, int hei, double scale) + { + if (recid) + { + m_rec.resid=MAKEINTRESOURCE(recid); + m_rec.title=titlestr; + m_rec.windowTypeFlags=flags; + m_rec.createFunc=cf; + m_rec.width=(int)((wid)*(scale)); + m_rec.height=(int)((hei)*(scale)); + m_rec._next=*h; + *h = &m_rec; + } + } +}; + +#define SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(recid, flags, titlestr, wid, hei, scale) \ + static void SWELL__dlg_cf__##recid(HWND view, int wflags); \ + static SWELL_DialogRegHelper __swell_dlg_helper_##recid(&SWELL_curmodule_dialogresource_head, SWELL__dlg_cf__##recid, recid,flags,titlestr,wid,hei,scale); \ + void SWELL__dlg_cf__##recid(HWND view, int wflags) { \ + SWELL_MakeSetCurParms(scale,scale,0,0,view,false,!(wflags&SWELL_DLG_WS_NOAUTOSIZE)); \ + static const SWELL_DlgResourceEntry list[]={ + + +#define SWELL_DEFINE_DIALOG_RESOURCE_END(recid ) }; SWELL_GenerateDialogFromList(list+1,sizeof(list)/sizeof(list[0])-1); } + + + +#endif diff --git a/WDL/swell/swell-functions.h b/WDL/swell/swell-functions.h new file mode 100644 index 00000000..d574d263 --- /dev/null +++ b/WDL/swell/swell-functions.h @@ -0,0 +1,1092 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) + Copyright (C) 2006-2010, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. + + */ + +#ifndef _WDL_SWELL_H_API_DEFINED_ +#define _WDL_SWELL_H_API_DEFINED_ + +//////////////////////////////////////////// +/////////// FUNCTIONS +//////////////////////////////////////////// + +#ifndef SWELL_API_DEFINE + + +#ifdef SWELL_PROVIDED_BY_APP + #ifdef __cplusplus + #define SWELL_API_DEFINE(ret,func,parms) extern "C" ret (*func)parms; + #else + #define SWELL_API_DEFINE(ret,func,parms) extern ret (*func)parms; + #endif +#else +#define SWELL_API_DEFINE(ret,func,parms) ret func parms ; +#endif +#endif + +// when adding APIs, add it using: +// SWELL_API_DEFINE(void, function_name, (int parm, int parm2)) +// rather than: +// void function_name(int parm, int parm2); + +/* +** lstrcpyn: this is provided because strncpy is braindead (filling with zeroes, and not +** NULL terminating if the destination buffer is too short? ASKING for trouble..) +** lstrpcyn always null terminates the string and doesnt fill anything extra. +*/ +SWELL_API_DEFINE(char *, lstrcpyn, (char *dest, const char *src, int l)) + + +/* +** MulDiv(): (parm1*parm2)/parm3 +** Implemented using long longs. +*/ +SWELL_API_DEFINE(int, MulDiv, (int, int, int)) + + +/* +** Sleep() sleeps for specified milliseconds. This maps to usleep, with a ms value of 0 +** usleeping for 100 microseconds. +*/ +SWELL_API_DEFINE(void, Sleep,(int ms)) + +/* +** GetTickCount() and timeGetTime() give you ms level timings via gettimeofday(). +** +** NOTE: This doesn't map to time since system start (like in win32), so a wrap around +** is slightly more likely (i.e. even if you booted your system an hour ago it could happen). +*/ +SWELL_API_DEFINE(DWORD, GetTickCount,()) +#ifndef timeGetTime +#define timeGetTime() GetTickCount() +#endif + +/* +** GetFileTime() gets the file time of a file (FILE *), and converts it to the Windows time. +** +** NOTE: while it returns a 64 bit time value, it is only accurate to the second since thats +** what fstat() returns. Takes an int filedes rather than a HANDLE. +*/ +SWELL_API_DEFINE(BOOL, GetFileTime,(int filedes, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime)) + +/* +** *PrivateProfileString/Int(): +** These are mostly thread-safe, mostly inter-process safe, and mostly module safe +** (i.e. writes from other modules) should be synchronized). +** +** NOTES: +** the filename used MUST be the full filename, unlike on Windows where files without paths go to +** C:/Windows, here they will be opened in the current directory. +** +** It's probably not a good idea to push your luck with simultaneous writes from multiple +** modules in different threads/processes, but in theory it should work. +*/ +SWELL_API_DEFINE(BOOL, WritePrivateProfileString, (const char *appname, const char *keyname, const char *val, const char *fn)) +SWELL_API_DEFINE(DWORD, GetPrivateProfileString, (const char *appname, const char *keyname, const char *def, char *ret, int retsize, const char *fn)) +SWELL_API_DEFINE(int, GetPrivateProfileInt,(const char *appname, const char *keyname, int def, const char *fn)) +SWELL_API_DEFINE(BOOL, GetPrivateProfileStruct,(const char *appname, const char *keyname, void *buf, int bufsz, const char *fn)) +SWELL_API_DEFINE(BOOL, WritePrivateProfileStruct,(const char *appname, const char *keyname, const void *buf, int bufsz, const char *fn)) +SWELL_API_DEFINE(BOOL, WritePrivateProfileSection, (const char *appname, const char *strings, const char *fn)) +SWELL_API_DEFINE(DWORD, GetPrivateProfileSection, (const char *appname, char *strout, DWORD strout_len, const char *fn)) + +/* +** GetModuleFileName() +** Can pass NULL (exe filename) or a hInstance from DllMain or LoadLibrary +*/ +SWELL_API_DEFINE(DWORD, GetModuleFileName,(HINSTANCE hInst, char *fn, DWORD nSize)) + +#ifdef SWELL_TARGET_OSX +/* +** SWELL_CStringToCFString(): Creates a CFString/NSString * from a C string. This is mostly +** used internally but you may wish to use it as well (though none of the SWELL APIs take +** CFString/NSString. +*/ +SWELL_API_DEFINE(void *,SWELL_CStringToCFString,(const char *str)) +SWELL_API_DEFINE(void, SWELL_CFStringToCString, (const void *str, char *buf, int buflen)) +#endif + + +/* +** PtInRect() should hopefully function just like it's win32 equivelent. +** there is #define funkiness because some Mac system headers define PtInRect as well. +*/ +#ifdef PtInRect +#undef PtInRect +#endif +#define PtInRect(r,p) SWELL_PtInRect(r,p) +SWELL_API_DEFINE(BOOL, SWELL_PtInRect,(RECT *r, POINT p)) + +/* +** ShellExecute(): +** NOTE: currently action is ignored, and it only works on content1 being a URL beginning with http://. +** TODO: finish implementation +*/ +SWELL_API_DEFINE(BOOL, ShellExecute,(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah)) + +/* +** MessageBox(). +*/ +SWELL_API_DEFINE(int, MessageBox,(HWND hwndParent, const char *text, const char *caption, int type)) + + +/* +** GetOpenFileName() / GetSaveFileName() +** These are a different API because we didnt feel like reeimplimenting the full API. +** Extlist is something similar you'd pass getopenfilename, +** initialdir and initialfile are optional (and NULL means not set). +*/ + +// free() the result of this, if non-NULL. +// if allowmul is set, the multiple files are specified the same way GetOpenFileName() returns. +SWELL_API_DEFINE(char *,BrowseForFiles,(const char *text, const char *initialdir, + const char *initialfile, bool allowmul, const char *extlist)) + +// returns TRUE if file was chosen. +SWELL_API_DEFINE(bool, BrowseForSaveFile,(const char *text, const char *initialdir, const char *initialfile, const char *extlist, + char *fn, int fnsize)) + +// returns TRUE if path was chosen. +SWELL_API_DEFINE(bool, BrowseForDirectory,(const char *text, const char *initialdir, char *fn, int fnsize)) + +// can use this before calling BrowseForFiles or BrowseForSaveFile to use a template dialog +SWELL_API_DEFINE(void,BrowseFile_SetTemplate,(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead)) + + +// Note that window functions are generally NOT threadsafe. +// all of these treat HWND as NSView and/or NSWindow (usually smartish about it) + + +/* +** GetDlgItem(hwnd,0) returns hwnd if hwnd is a NSView, or the contentview if hwnd is a NSWindow. +** Note that this GetDlgItem will actually search a view hierarchy for the tagged view, +** unlike Win32 where it will only look at immediate children. +*/ +SWELL_API_DEFINE(HWND, GetDlgItem,(HWND, int)) + +/* +** ShowWindow() works for hwnds that represent NSView and/or NSWindow. +** SW_SHOW, SW_SHOWNA, and SW_HIDE are defined, and some of the other common uses +** alias to these. +*/ +SWELL_API_DEFINE(void, ShowWindow,(HWND, int)) + + +/* +** DestroyWindow() works for both a NSWindow or NSView. +** Note that if the window is a fake window with a procedure +** (created via CreateDialog or DialogBox below) then WM_DESTROY +** will be called immediately, though the window/view may be freed +** sometime later via the autorelease pool. +*/ +SWELL_API_DEFINE(void, DestroyWindow,(HWND hwnd)) + +SWELL_API_DEFINE(BOOL, SWELL_GetGestureInfo, (LPARAM lParam, GESTUREINFO* gi)) + +SWELL_API_DEFINE(void, SWELL_HideApp,()) + +/* +** These should all work like their Win32 versions, though if idx=0 it gets/sets the +** value for the window. Note that SetDlgItemText() for an edit control does NOT send +** a WM_COMMAND notification like on win32, so you will have to do this yourself. +*/ +SWELL_API_DEFINE(BOOL, SetDlgItemText,(HWND, int idx, const char *text)) +SWELL_API_DEFINE(BOOL, SetDlgItemInt,(HWND, int idx, int val, int issigned)) +SWELL_API_DEFINE(int, GetDlgItemInt,(HWND, int idx, BOOL *translated, int issigned)) +SWELL_API_DEFINE(BOOL, GetDlgItemText,(HWND, int idx, char *text, int textlen)) + +#ifndef GetWindowText +#define GetWindowText(hwnd,text,textlen) GetDlgItemText(hwnd,0,text,textlen) +#define SetWindowText(hwnd,text) SetDlgItemText(hwnd,0,text) +#endif + + +SWELL_API_DEFINE(void, CheckDlgButton,(HWND hwnd, int idx, int check)) +SWELL_API_DEFINE(int, IsDlgButtonChecked,(HWND hwnd, int idx)) +SWELL_API_DEFINE(void, EnableWindow,(HWND hwnd, int enable)) +SWELL_API_DEFINE(void, SetFocus,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * +SWELL_API_DEFINE(HWND, GetFocus,()) +SWELL_API_DEFINE(void, SetForegroundWindow,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * +SWELL_API_DEFINE(HWND, GetForegroundWindow,()) +#ifndef GetActiveWindow +#define GetActiveWindow() GetForegroundWindow() +#endif +#ifndef SetActiveWindow +#define SetActiveWindow(x) SetForegroundWindow(x) +#endif + +/* +** GetCapture/SetCapture/ReleaseCapture are completely faked, with just an internal state. +** Mouse click+drag automatically captures the focus sending mouseDrag events in OSX, so +** these are as a porting aid. +** +** Updated: they actually send WM_CAPTURECHANGED messages now, if the window supports +** onSwellMessage:p1:p2: and swellCapChangeNotify (and swellCapChangeNotify returns YES). +** +** Note that any HWND that returns YES to swellCapChangeNotify should do the following on +** destroy or dealloc: if (GetCapture()==(HWND)self) ReleaseCapture(); Failure to do so +** can cause a dealloc'd window to get messages sent to it. +*/ +SWELL_API_DEFINE(HWND, SetCapture,(HWND hwnd)) +SWELL_API_DEFINE(HWND, GetCapture,()) +SWELL_API_DEFINE(void, ReleaseCapture,()) + +/* +** IsChild() +** Notes: hwndChild must be a NSView (if not then false is returned) +** hwndParent can be a NSWindow or NSView. +** NSWindow level ownership/children are not detected. +*/ +SWELL_API_DEFINE(int, IsChild,(HWND hwndParent, HWND hwndChild)) + + +/* +** GetParent() +** Notes: if hwnd is a NSView, then gets the parent view (or NSWindow +** if the parent view is the window's contentview). If hwnd is a NSWindow, +** then GetParent returns the owner window, if any. Note that the owner +** window system is not part of OSX, but rather part of SWELL. +*/ +SWELL_API_DEFINE(HWND, GetParent,(HWND hwnd)) + +/* +** SetParent() +** Notes: hwnd must be a NSView, newPar can be either NSView or NSWindow. +*/ +SWELL_API_DEFINE(HWND, SetParent,(HWND hwnd, HWND newPar)) + +/* +** GetWindow() +** Most of the standard GW_CHILD etc work. Does not do anything to prevent you from +** getting into infinite loops if you go changing the order on the fly etc. +*/ +SWELL_API_DEFINE(HWND, GetWindow,(HWND hwnd, int what)) + +SWELL_API_DEFINE(HWND,FindWindowEx,(HWND par, HWND lastw, const char *classname, const char *title)) + + +/* +** Notes: common win32 code like this: +** RECT r; +** GetWindowRect(hwnd,&r); +** ScreenToClient(otherhwnd,(LPPOINT)&r); +** ScreenToClient(otherhwnd,((LPPOINT)&r)+1); +** does work, however be aware that in certain instances r.bottom may be less +** than r.top, due to flipped coordinates. SetWindowPos and other functions +** handle negative heights gracefully, and you should too. +** +** Note: GetWindowContentViewRect gets the rectangle of the content view (pre-NCCALCSIZE etc) +*/ +SWELL_API_DEFINE(void, ClientToScreen,(HWND hwnd, POINT *p)) +SWELL_API_DEFINE(void, ScreenToClient,(HWND hwnd, POINT *p)) +SWELL_API_DEFINE(bool, GetWindowRect,(HWND hwnd, RECT *r)) +SWELL_API_DEFINE(void, GetWindowContentViewRect, (HWND hwnd, RECT *r)) +SWELL_API_DEFINE(void, GetClientRect,(HWND hwnd, RECT *r)) +SWELL_API_DEFINE(HWND, WindowFromPoint,(POINT p)) +SWELL_API_DEFINE(BOOL, WinOffsetRect, (LPRECT lprc, int dx, int dy)) +SWELL_API_DEFINE(BOOL, WinSetRect, (LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom)) +SWELL_API_DEFINE(void,WinUnionRect,(RECT *out, RECT *in1, RECT *in2)) +SWELL_API_DEFINE(int,WinIntersectRect,(RECT *out, RECT *in1, RECT *in2)) + + +/* +** SetWindowPos(): +** Notes: Z ordering stuff is ignored, as are most flags. +** SWP_NOMOVE and SWP_NOSIZE are the only flags used. +*/ +SWELL_API_DEFINE(void, SetWindowPos,(HWND hwnd, HWND unused, int x, int y, int cx, int cy, int flags)) + +SWELL_API_DEFINE(int, SWELL_SetWindowLevel, (HWND hwnd, int newlevel)) + +/* +** InvalidateRect() +** Notes: eraseBk is ignored, probably not threadsafe! hwnd can be NSWindow or NSView +*/ +SWELL_API_DEFINE(void,InvalidateRect,(HWND hwnd, RECT *r, int eraseBk)) + +/* +** UpdateWindow() +** Notes: not currently implemented but provided here in case someday it is necessary +*/ +SWELL_API_DEFINE(void,UpdateWindow,(HWND hwnd)) + + +/* +** GetWindowLong()/SetWindowLong() +** +** GWL_ID is supported for all objects that support the 'tag'/'setTag' methods, +** which would be controls and SWELL created windows/dialogs/controls. +** +** GWL_USERDATA is supported by SWELL created windows/dialogs/controls, using +** (int)getSwellUserData and setSwellUserData:(int). +** +** GWL_WNDPROC is supported by SWELL created windows/dialogs/controls, using +** (int)getSwellWindowProc and setSwellWindowProc:(int). +** +** DWL_DLGPROC is supported by SWELL created dialogs now (it might work in windows/controls but isnt recommended) +** +** GWL_STYLE is only supported for NSButton. Currently the only flags supported are +** BS_AUTO3STATE (BS_AUTOCHECKBOX is returned but also ignored). +** +** indices of >= 0 and < 128 (32 integers) are supported for SWELL created +** windows/dialogs/controls, via (int)getSwellExtraData:(int)idx and +** setSwellExtraData:(int)idx value:(int)val . +*/ +SWELL_API_DEFINE(LONG_PTR, GetWindowLong,(HWND hwnd, int idx)) +SWELL_API_DEFINE(LONG_PTR, SetWindowLong,(HWND hwnd, int idx, LONG_PTR val)) + + +SWELL_API_DEFINE(BOOL, ScrollWindow, (HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect)) + +/* +** GetProp() SetProp() RemoveProp() EnumPropsEx() +** These should work like in win32. Free your props otherwise they will leak. +** Restriction on what you can do in the PROPENUMPROCEX is similar to win32 +** (you can remove only the called prop, and can't add props within it). +** if the prop name is < (void *)65536 then it is treated as a short identifier. +*/ +SWELL_API_DEFINE(int, EnumPropsEx,(HWND, PROPENUMPROCEX, LPARAM)) +SWELL_API_DEFINE(HANDLE, GetProp, (HWND, const char *)) +SWELL_API_DEFINE(BOOL, SetProp, (HWND, const char *, HANDLE)) +SWELL_API_DEFINE(HANDLE, RemoveProp, (HWND, const char *)) + + +/* +** IsWindowVisible() +** if hwnd is a NSView, returns !isHiddenOrHasHiddenAncestor +** if hwnd is a NSWindow returns isVisible +** otherwise returns TRUE if non-null hwnd +*/ +SWELL_API_DEFINE(bool, IsWindowVisible,(HWND hwnd)) + +SWELL_API_DEFINE(bool, IsWindow, (HWND hwnd)) // very costly (compared to win32) -- enumerates all windows, searches for hwnd + + +/* +** SetTimer/KillTimer(): +** Notes: +** The timer API may be threadsafe though it is highly untested. +** Note also that the mechanism for sending timers is SWELL_Timer:(id). +** The fourth parameter to SetTimer() is not supported and will be ignored, so you must +** receive your timers via a WM_TIMER (or SWELL_Timer:(id)) +** +** You can kill all timers for a window using KillTimer(hwnd,-1); +** You MUST kill all timers for a window before destroying it. Note that SWELL created +** windows/dialogs/controls automatically do this, but if you use SetTimer() on a NSView * +** or NSWindow * directly, then you should kill all timers in -dealloc. +*/ +SWELL_API_DEFINE(UINT_PTR, SetTimer,(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc)) +SWELL_API_DEFINE(BOOL, KillTimer,(HWND hwnd, UINT_PTR timerid)) + +#ifdef SWELL_TARGET_OSX +/* +** These provide the interfaces for directly updating a combo box control. This is no longer +** required as SendMessage can now be used with CB_* etc. +** Combo boxes may be implemented using a NSComboBox or NSPopUpButton depending on the style. +** +** Notes: CB_SetItemData/CB_GetItemData only work for the non-user-editable version (using NSPopUpbutotn). +*/ +SWELL_API_DEFINE(int, SWELL_CB_AddString,(HWND hwnd, int idx, const char *str)) +SWELL_API_DEFINE(void, SWELL_CB_SetCurSel,(HWND hwnd, int idx, int sel)) +SWELL_API_DEFINE(int, SWELL_CB_GetCurSel,(HWND hwnd, int idx)) +SWELL_API_DEFINE(int, SWELL_CB_GetNumItems,(HWND hwnd, int idx)) +SWELL_API_DEFINE(void, SWELL_CB_SetItemData,(HWND hwnd, int idx, int item, LONG_PTR data)) // these two only work for the combo list version for now +SWELL_API_DEFINE(LONG_PTR, SWELL_CB_GetItemData,(HWND hwnd, int idx, int item)) +SWELL_API_DEFINE(void, SWELL_CB_Empty,(HWND hwnd, int idx)) +SWELL_API_DEFINE(int, SWELL_CB_InsertString,(HWND hwnd, int idx, int pos, const char *str)) +SWELL_API_DEFINE(int, SWELL_CB_GetItemText,(HWND hwnd, int idx, int item, char *buf, int bufsz)) +SWELL_API_DEFINE(void, SWELL_CB_DeleteString,(HWND hwnd, int idx, int wh)) +SWELL_API_DEFINE(int, SWELL_CB_FindString,(HWND hwnd, int idx, int startAfter, const char *str, bool exact)) + + +/* +** Trackbar API +** These provide the interfaces for directly updating a trackbar (implemented using NSSlider). +** Note that you can now use SendMessage with TBM_* instead. +*/ +SWELL_API_DEFINE(void, SWELL_TB_SetPos,(HWND hwnd, int idx, int pos)) +SWELL_API_DEFINE(void, SWELL_TB_SetRange,(HWND hwnd, int idx, int low, int hi)) +SWELL_API_DEFINE(int, SWELL_TB_GetPos,(HWND hwnd, int idx)) +SWELL_API_DEFINE(void, SWELL_TB_SetTic,(HWND hwnd, int idx, int pos)) + + +#endif + +/* +** ListView API. In owner data mode only LVN_GETDISPINFO is used (not ODFINDITEM etc). +** LVN_BEGINDRAG also should work as on windows. Imagelists state icons work as well. +*/ +SWELL_API_DEFINE(void, ListView_SetExtendedListViewStyleEx,(HWND h, int mask, int style)) +SWELL_API_DEFINE(void, ListView_InsertColumn,(HWND h, int pos, const LVCOLUMN *lvc)) +SWELL_API_DEFINE(bool, ListView_DeleteColumn,(HWND h, int pos)) +SWELL_API_DEFINE(void, ListView_SetColumn,(HWND h, int pos, const LVCOLUMN *lvc)) +SWELL_API_DEFINE(int, ListView_GetColumnWidth,(HWND h, int pos)) +SWELL_API_DEFINE(int, ListView_InsertItem,(HWND h, const LVITEM *item)) +SWELL_API_DEFINE(void, ListView_SetItemText,(HWND h, int ipos, int cpos, const char *txt)) +SWELL_API_DEFINE(bool, ListView_SetItem,(HWND h, LVITEM *item)) +SWELL_API_DEFINE(int, ListView_GetNextItem,(HWND h, int istart, int flags)) +SWELL_API_DEFINE(bool, ListView_GetItem,(HWND h, LVITEM *item)) +SWELL_API_DEFINE(int, ListView_GetItemState,(HWND h, int ipos, int mask)) +SWELL_API_DEFINE(void, ListView_DeleteItem,(HWND h, int ipos)) +SWELL_API_DEFINE(void, ListView_DeleteAllItems,(HWND h)) +SWELL_API_DEFINE(int, ListView_GetSelectedCount,(HWND h)) +SWELL_API_DEFINE(int, ListView_GetItemCount,(HWND h)) +SWELL_API_DEFINE(int, ListView_GetSelectionMark,(HWND h)) +SWELL_API_DEFINE(void, ListView_SetColumnWidth,(HWND h, int colpos, int wid)) +SWELL_API_DEFINE(bool, ListView_SetItemState,(HWND h, int item, int state, int statemask)) +SWELL_API_DEFINE(void, ListView_RedrawItems,(HWND h, int startitem, int enditem)) +SWELL_API_DEFINE(void, ListView_SetItemCount,(HWND h, int cnt)) +SWELL_API_DEFINE(void, ListView_EnsureVisible,(HWND h, int i, BOOL pok)) +SWELL_API_DEFINE(bool, ListView_GetSubItemRect,(HWND h, int item, int subitem, int code, RECT *r)) +SWELL_API_DEFINE(void, ListView_SetImageList,(HWND h, HIMAGELIST imagelist, int which)) +SWELL_API_DEFINE(int, ListView_HitTest,(HWND h, LVHITTESTINFO *pinf)) +SWELL_API_DEFINE(int, ListView_SubItemHitTest,(HWND h, LVHITTESTINFO *pinf)) +SWELL_API_DEFINE(void, ListView_GetItemText,(HWND hwnd, int item, int subitem, char *text, int textmax)) +SWELL_API_DEFINE(void, ListView_SortItems,(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm)) +SWELL_API_DEFINE(bool, ListView_GetItemRect,(HWND h, int item, RECT *r, int code)) +SWELL_API_DEFINE(bool, ListView_Scroll,(HWND h, int xscroll, int yscroll)) +SWELL_API_DEFINE(int, ListView_GetTopIndex,(HWND h)) +SWELL_API_DEFINE(int, ListView_GetCountPerPage,(HWND h)) +SWELL_API_DEFINE(BOOL, ListView_SetColumnOrderArray,(HWND h, int cnt, int* arr)) +SWELL_API_DEFINE(BOOL, ListView_GetColumnOrderArray,(HWND h, int cnt, int* arr)) +SWELL_API_DEFINE(HWND, ListView_GetHeader,(HWND h)) +SWELL_API_DEFINE(int, Header_GetItemCount,(HWND h)) +SWELL_API_DEFINE(BOOL, Header_GetItem,(HWND h, int col, HDITEM* hi)) +SWELL_API_DEFINE(BOOL, Header_SetItem,(HWND h, int col, HDITEM* hi)) + +SWELL_API_DEFINE(int, SWELL_GetListViewHeaderHeight, (HWND h)) + +#ifndef ImageList_Create +#define ImageList_Create(x,y,a,b,c) ImageList_CreateEx(); +#endif +SWELL_API_DEFINE(HIMAGELIST, ImageList_CreateEx,()) +SWELL_API_DEFINE(BOOL, ImageList_Remove, (HIMAGELIST list, int idx)) +SWELL_API_DEFINE(int, ImageList_ReplaceIcon,(HIMAGELIST list, int offset, HICON image)) +SWELL_API_DEFINE(void, ImageList_Destroy, (HIMAGELIST)) +/* +** TabCtrl api. +*/ +SWELL_API_DEFINE(int, TabCtrl_GetItemCount,(HWND hwnd)) +SWELL_API_DEFINE(BOOL, TabCtrl_DeleteItem,(HWND hwnd, int idx)) +SWELL_API_DEFINE(int, TabCtrl_InsertItem,(HWND hwnd, int idx, TCITEM *item)) +SWELL_API_DEFINE(int, TabCtrl_SetCurSel,(HWND hwnd, int idx)) +SWELL_API_DEFINE(int, TabCtrl_GetCurSel,(HWND hwnd)) +SWELL_API_DEFINE(BOOL, TabCtrl_AdjustRect, (HWND hwnd, BOOL fLarger, RECT *r)) + +/* +** TreeView +*/ + +SWELL_API_DEFINE(HTREEITEM, TreeView_InsertItem, (HWND hwnd, TV_INSERTSTRUCT *ins)) +SWELL_API_DEFINE(BOOL, TreeView_Expand,(HWND hwnd, HTREEITEM item, UINT flag)) +SWELL_API_DEFINE(HTREEITEM, TreeView_GetSelection,(HWND hwnd)) +SWELL_API_DEFINE(void, TreeView_DeleteItem,(HWND hwnd, HTREEITEM item)) +SWELL_API_DEFINE(void, TreeView_SelectItem,(HWND hwnd, HTREEITEM item)) +SWELL_API_DEFINE(BOOL, TreeView_GetItem,(HWND hwnd, LPTVITEM pitem)) +SWELL_API_DEFINE(BOOL, TreeView_SetItem,(HWND hwnd, LPTVITEM pitem)) +SWELL_API_DEFINE(HTREEITEM, TreeView_HitTest, (HWND hwnd, TVHITTESTINFO *hti)) +SWELL_API_DEFINE(BOOL, TreeView_SetIndent,(HWND hwnd, int indent)) + +SWELL_API_DEFINE(HTREEITEM, TreeView_GetChild, (HWND hwnd, HTREEITEM item)) +SWELL_API_DEFINE(HTREEITEM, TreeView_GetNextSibling, (HWND hwnd, HTREEITEM item)) +SWELL_API_DEFINE(HTREEITEM, TreeView_GetRoot, (HWND hwnd)) + +SWELL_API_DEFINE(void,TreeView_SetBkColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,TreeView_SetTextColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,ListView_SetBkColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,ListView_SetTextBkColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,ListView_SetTextColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,ListView_SetGridColor,(HWND hwnd, int color)) +SWELL_API_DEFINE(void,ListView_SetSelColors,(HWND hwnd, int *colors, int ncolors)) + +/* +** These are deprecated functions for launching a modal window but still running +** your own code. In general use DialogBox with a timer if needed instead. +*/ +SWELL_API_DEFINE(void *, SWELL_ModalWindowStart,(HWND hwnd)) +SWELL_API_DEFINE(bool, SWELL_ModalWindowRun,(void *ctx, int *ret)) // returns false and puts retval in *ret when done +SWELL_API_DEFINE(void, SWELL_ModalWindowEnd,(void *ctx)) +SWELL_API_DEFINE(void, SWELL_CloseWindow,(HWND hwnd)) + + +/* +** Menu functions +** HMENU is a NSMenu *. +*/ +SWELL_API_DEFINE(HMENU, CreatePopupMenu,()) +SWELL_API_DEFINE(HMENU, CreatePopupMenuEx,(const char *title)) +SWELL_API_DEFINE(void, DestroyMenu,(HMENU hMenu)) +SWELL_API_DEFINE(int, AddMenuItem,(HMENU hMenu, int pos, const char *name, int tagid)) +SWELL_API_DEFINE(HMENU, GetSubMenu,(HMENU hMenu, int pos)) +SWELL_API_DEFINE(int, GetMenuItemCount,(HMENU hMenu)) +SWELL_API_DEFINE(int, GetMenuItemID,(HMENU hMenu, int pos)) +SWELL_API_DEFINE(bool, SetMenuItemModifier,(HMENU hMenu, int idx, int flag, int code, unsigned int mask)) +SWELL_API_DEFINE(bool, SetMenuItemText,(HMENU hMenu, int idx, int flag, const char *text)) +SWELL_API_DEFINE(bool, EnableMenuItem,(HMENU hMenu, int idx, int en)) +SWELL_API_DEFINE(bool, DeleteMenu,(HMENU hMenu, int idx, int flag)) +SWELL_API_DEFINE(bool, CheckMenuItem,(HMENU hMenu, int idx, int chk)) +SWELL_API_DEFINE(void, InsertMenuItem,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) +SWELL_API_DEFINE(void,SWELL_InsertMenu,(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str)) +#ifdef InsertMenu +#undef InsertMenu +#endif +#define InsertMenu SWELL_InsertMenu + +SWELL_API_DEFINE(BOOL, GetMenuItemInfo,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) +SWELL_API_DEFINE(BOOL, SetMenuItemInfo,(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi)) +SWELL_API_DEFINE(void, DrawMenuBar,(HWND)) + + + +/* +** LoadMenu() +** Loads a menu created with SWELL_DEFINE_MENU_RESOURCE_BEGIN(), see swell-menugen.h +** Notes: the hinst parameter is ignored, the menu must have been defined in the same +** APP or DYLIB as the LoadMenu call. If you wish to load a menu from another module, +** you should somehow get its SWELL_curmodule_menuresource_head and pass it to SWELL_LoadMenu +** directly. +*/ +#ifndef LoadMenu +#define LoadMenu(hinst,resid) SWELL_LoadMenu(SWELL_curmodule_menuresource_head,(resid)) +#endif +SWELL_API_DEFINE(HMENU, SWELL_LoadMenu,(struct SWELL_MenuResourceIndex *head, const char *resid)) + +/* +** TrackPopupMenu +** Notes: the rectangle and many flags are ignored, but TPM_NONOTIFY is used. +** It always returns the command selected, even if TPM_RETURNCMD is not specified. +*/ +SWELL_API_DEFINE(int, TrackPopupMenu,(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r)) + +/* +** SWELL_SetMenuDestination: set the action destination for all items in a menu +** Notes: +** TrackPopupMenu and SetMenu use this internally, but it may be useful. +*/ +SWELL_API_DEFINE(void, SWELL_SetMenuDestination,(HMENU menu, HWND hwnd)) + +/* +** SWELL_DuplicateMenu: +** Copies an entire menu. +*/ +SWELL_API_DEFINE(HMENU, SWELL_DuplicateMenu,(HMENU menu)) + +/* +** SetMenu()/GetMenu() +** Notes: These work on SWELL created NSWindows, or objective C objects that respond to +** swellSetMenu:(HMENU) and swellGetMenu. +** Setting these values doesnt mean anything, except that the SWELL windows will automatically +** set the application menu via NSApp setMainMenu: when activated. +** +*/ +SWELL_API_DEFINE(BOOL, SetMenu,(HWND hwnd, HMENU menu)) +SWELL_API_DEFINE(HMENU, GetMenu,(HWND hwnd)) + +/* +** SWELL_SetDefaultWindowMenu()/SWELL_GetDefaultWindowMenu() +** these set an internal flag for the default window menu, which will be set +** when switching to a window that has no menu set. Set this to your application's +** main menu. +*/ +SWELL_API_DEFINE(HMENU, SWELL_GetDefaultWindowMenu,()) +SWELL_API_DEFINE(void, SWELL_SetDefaultWindowMenu,(HMENU)) +SWELL_API_DEFINE(HMENU, SWELL_GetDefaultModalWindowMenu,()) +SWELL_API_DEFINE(void, SWELL_SetDefaultModalWindowMenu,(HMENU)) +SWELL_API_DEFINE(HMENU, SWELL_GetCurrentMenu,()) +SWELL_API_DEFINE(void, SWELL_SetCurrentMenu,(HMENU)) + + + +/* +** SWELL dialog box/control/window/child dialog/etc creation +** DialogBox(), DialogBoxParam(), CreateDialog(), and CreateDialogParam() +** +** Notes: +** hInstance parameters are ignored. If you wish to load a dialog resource from another +** module (DYLIB), you should get its SWELL_curmodule_dialogresource_head via your own +** mechanism and pass it as the first parameter of SWELL_DialogBox or whichever API. +** +** If you are using CreateDialog() and creating a child window, you can use a resource ID of +** 0, which creates an opaque child window. Instead of passing a DLGPROC, you should pass a +** routine that retuns LRESULT (and cast it to DLGPROC). +** +*/ + +#ifndef DialogBox +#define DialogBox(hinst, resid, par, dlgproc) SWELL_DialogBox(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,0) +#define DialogBoxParam(hinst, resid, par, dlgproc, param) SWELL_DialogBox(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,param) +#define CreateDialog(hinst,resid,par,dlgproc) SWELL_CreateDialog(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,0) +#define CreateDialogParam(hinst,resid,par,dlgproc,param) SWELL_CreateDialog(SWELL_curmodule_dialogresource_head,(resid),par,dlgproc,param) +#endif +SWELL_API_DEFINE(int, SWELL_DialogBox,(struct SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)) +SWELL_API_DEFINE(HWND, SWELL_CreateDialog,(struct SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)) + + +/* +** SWELL_RegisterCustomControlCreator(), SWELL_UnregisterCustomControlCreator() +** Notes: +** Pass these a callback function that can create custom controls based on classname. +** Todo: document. +*/ + +SWELL_API_DEFINE(void, SWELL_RegisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) +SWELL_API_DEFINE(void, SWELL_UnregisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) + +/* +** DefWindowProc(). +** Notes: Doesnt do much but call it anyway from any child windows created with CreateDialog +** and a 0 resource-id window proc. +*/ +SWELL_API_DEFINE(LRESULT, DefWindowProc,(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)) + +/* +** EndDialog(): +** Notes: _ONLY_ use on a dialog created with DialogBox(). Will do nothing on other dialogs. +*/ +SWELL_API_DEFINE(void, EndDialog,(HWND, int)) + + +SWELL_API_DEFINE(int,SWELL_GetDefaultButtonID,(HWND hwndDlg, bool onlyIfEnabled)) + + +/* +** SendMessage() +** Notes: +** LIMITATION - SendMessage should only be used from the same thread that the window/view +** was created in. Cross-thread use SHOULD BE AVOIDED. It may work, but it may blow up. +** PostMessage (below) can be used in certain instances for asynchronous notifications. +** +** If the hwnd supports onSwellMessage:p1:p2: then the message is sent via this. +** Alternatively, buttons created via the dialog interface support BM_GETIMAGE/BM_SETIMAGE +** NSPopUpButton and NSComboBox controls support CB_* +** NSSlider controls support TBM_* +** If the receiver is a view and none of these work, the message goes to the window's onSwellMessage, if any +** If the receiver is a window and none of these work, the message goes to the window's contentview's onSwellMessage, if any +** +*/ +SWELL_API_DEFINE(LRESULT, SendMessage,(HWND, UINT, WPARAM, LPARAM)) +#ifndef SendDlgItemMessage +#define SendDlgItemMessage(hwnd,idx,msg,wparam,lparam) SendMessage(GetDlgItem(hwnd,idx),msg,wparam,lparam) +#endif + +SWELL_API_DEFINE(void,SWELL_BroadcastMessage,(UINT, WPARAM, LPARAM)) + +/* +** PostMessage() +** Notes: +** Queues a message into the application message queue. Note that you should only ever +** send messages to destinations that were created from the main thread. They will be +** processed later from a timer (in the main thread). +** When a window is destroyed any outstanding messages will be discarded for it. +*/ +SWELL_API_DEFINE(BOOL, PostMessage,(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)) + +/* +** SWELL_MessageQueue_Flush(): +** Notes: +** Processes all messages in the message queue. ONLY call from the main thread. +*/ +SWELL_API_DEFINE(void, SWELL_MessageQueue_Flush,()) + +/* +** SWELL_MessageQueue_Clear(): +** Notes: +** Discards all messages from the message queue if h is NULL, otherwise discards all messages +** to h. +*/ +SWELL_API_DEFINE(void, SWELL_MessageQueue_Clear,(HWND h)) + + + +/* +** keyboard/mouse support +*/ + +/* +** SWELL_MacKeyToWindowsKey() +** Pass a keyboard NSEvent *, and it will return a windows VK_ keycode (or ascii), and set flags, +** including (possibly) FSHIFT, FCONTROL (apple key), FALT, and FVIRTKEY. The ctrl key is not checked, +** as SWELL generally encourages this to be used soley for a right mouse button (as modifier). +*/ +#ifdef SWELL_TARGET_OSX +SWELL_API_DEFINE(int, SWELL_MacKeyToWindowsKey,(void *nsevent, int *flags)) +#endif +SWELL_API_DEFINE(int,SWELL_KeyToASCII,(int wParam, int lParam, int *newflags)) + + +/* +** GetAsyncKeyState() +** Notes: only supports MK_LBUTTON, MK_RBUTTON, MK_MBUTTON, VK_SHIFT, VK_MENU, and VK_CONTROL (apple key) for now. +*/ +SWELL_API_DEFINE(WORD, GetAsyncKeyState,(int key)) + +/* +** GetCursorPos(), GetMessagePos() +** Notes: GetMessagePos() currently returns the same coordinates as GetCursorPos(), +** this needs to be fixed. +*/ +SWELL_API_DEFINE(void, GetCursorPos,(POINT *pt)) +SWELL_API_DEFINE(DWORD, GetMessagePos,()) + +/* +** LoadCursor(). +** Notes: hinstance parameter ignored, currently only supports loading some of the predefined values. +** (IDC_SIZEALL etc). If it succeeds value is a NSCursor * +*/ +SWELL_API_DEFINE(HCURSOR, SWELL_LoadCursor,(const char *idx)) +#ifndef LoadCursor +#define LoadCursor(a,x) SWELL_LoadCursor(x) +#endif + +/* +** SetCursor() +** Sets a cursor as active (can be HCURSOR or NSCursor * cast as such). +*/ +#ifdef SetCursor +#undef SetCursor +#endif +#define SetCursor(x) SWELL_SetCursor(x) +SWELL_API_DEFINE(void, SWELL_SetCursor,(HCURSOR curs)) + + +#ifdef GetCursor +#undef GetCursor +#endif +#define GetCursor SWELL_GetCursor + +#ifdef ShowCursor +#undef ShowCursor +#endif +#define ShowCursor SWELL_ShowCursor + +#ifdef SetCursorPos +#undef SetCursorPos +#endif +#define SetCursorPos SWELL_SetCursorPos + +#ifdef ScrollWindowEx +#undef ScrollWindowEx +#endif +#define ScrollWindowEx(a,b,c,d,e,f,g,h) ScrollWindow(a,b,c,d,e) + + +/* +** Globally enable or disable emulating mouse right-click using control+left-click +*/ +SWELL_API_DEFINE(void, SWELL_EnableRightClickEmulate, (BOOL enable)) + + +/* +** GetCursor() gets the actual system cursor, +** SWELL_GetLastSetCursor() gets the last cursor set via SWELL (if they differ than some other window must have changed the cursor) +*/ +SWELL_API_DEFINE(HCURSOR, SWELL_GetCursor,()) +SWELL_API_DEFINE(HCURSOR, SWELL_GetLastSetCursor,()) + +SWELL_API_DEFINE(bool, SWELL_IsCursorVisible, ()) +SWELL_API_DEFINE(int, SWELL_ShowCursor, (BOOL bShow)) +SWELL_API_DEFINE(BOOL, SWELL_SetCursorPos, (int X, int Y)) + +/* +** SWELL_GetViewPort +** Gets screen information, for the screen that contains sourcerect. if wantWork is set +** it excluses the menu bar etc. +*/ +SWELL_API_DEFINE(void, SWELL_GetViewPort,(RECT *r, RECT *sourcerect, bool wantWork)) + +/* +** Clipboard API emulation +** Notes: setting multiple types may not work right +** +*/ +SWELL_API_DEFINE(bool, OpenClipboard,(HWND hwndDlg)) +SWELL_API_DEFINE(void, CloseClipboard,()) +SWELL_API_DEFINE(HANDLE, GetClipboardData,(UINT type)) + +SWELL_API_DEFINE(void, EmptyClipboard,()) +SWELL_API_DEFINE(void, SetClipboardData,(UINT type, HANDLE h)) +SWELL_API_DEFINE(UINT, RegisterClipboardFormat,(const char *desc)) +SWELL_API_DEFINE(UINT, EnumClipboardFormats,(UINT lastfmt)) + +#ifndef CF_TEXT +#define CF_TEXT (RegisterClipboardFormat("SWELL__CF_TEXT")) +#endif + +/* +** GlobalAlloc*() +** These are only currently used by the clipboard system, +** but should work normally. +*/ + +SWELL_API_DEFINE(HANDLE, GlobalAlloc,(int flags, int sz)) +SWELL_API_DEFINE(void *, GlobalLock,(HANDLE h)) +SWELL_API_DEFINE(int, GlobalSize,(HANDLE h)) +SWELL_API_DEFINE(void, GlobalUnlock,(HANDLE h)) +SWELL_API_DEFINE(void, GlobalFree,(HANDLE h)) + + +SWELL_API_DEFINE(HANDLE,CreateThread,(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut)) +SWELL_API_DEFINE(HANDLE,CreateEvent,(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored)) +SWELL_API_DEFINE(HANDLE,CreateEventAsSocket,(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored)) + + +#ifdef _beginthreadex +#undef _beginthreadex +#endif +#define _beginthreadex(a,b,c,d,e,f) ((UINT_PTR)CreateThread(a,b,(unsigned (*)(LPVOID))(c),d,e,(DWORD*)(f))) + +SWELL_API_DEFINE(DWORD,GetCurrentThreadId,()) +SWELL_API_DEFINE(DWORD,WaitForSingleObject,(HANDLE hand, DWORD msTO)) +SWELL_API_DEFINE(DWORD,WaitForAnySocketObject,(int numObjs, HANDLE *objs, DWORD msTO)) // waits for any number of socket objects +SWELL_API_DEFINE(BOOL,CloseHandle,(HANDLE hand)) +SWELL_API_DEFINE(BOOL,SetThreadPriority,(HANDLE evt, int prio)) +SWELL_API_DEFINE(BOOL,SetEvent,(HANDLE evt)) +SWELL_API_DEFINE(BOOL,ResetEvent,(HANDLE evt)) + +#ifdef SWELL_TARGET_OSX +SWELL_API_DEFINE(void,SWELL_EnsureMultithreadedCocoa,()) +SWELL_API_DEFINE(void *, SWELL_InitAutoRelease,()) +SWELL_API_DEFINE(void, SWELL_QuitAutoRelease,(void *p)) +#endif + +SWELL_API_DEFINE(HANDLE,SWELL_CreateProcess,(const char *exe, int nparams, const char **params)) + + +SWELL_API_DEFINE(HINSTANCE,LoadLibraryGlobals,(const char *fileName, bool symbolsAsGlobals)) +SWELL_API_DEFINE(HINSTANCE,LoadLibrary,(const char *fileName)) +SWELL_API_DEFINE(void *,GetProcAddress,(HINSTANCE hInst, const char *procName)) +SWELL_API_DEFINE(BOOL,FreeLibrary,(HINSTANCE hInst)) + +/* +** GDI functions. +** Everything should be all hunky dory, your windows may get WM_PAINT, call +** GetDC()/ReleaseDC(), etc. +** +** Or, there are these helper functions: +*/ + + +/* +** SWELL_CreateMemContext() +** Creates a memory context (that you can get the bits for, below) +** hdc is currently ignored. +*/ +SWELL_API_DEFINE(HDC, SWELL_CreateMemContext,(HDC hdc, int w, int h)) + +/* +** SWELL_DeleteGfxContext() +** Deletes a context created with SWELL_CreateMemContext() (or the internal SWELL_CreateGfxContext) +*/ +SWELL_API_DEFINE(void, SWELL_DeleteGfxContext,(HDC)) + +/* +** SWELL_GetCtxGC() +** Returns the CGContextRef of a HDC +*/ +SWELL_API_DEFINE(void *, SWELL_GetCtxGC,(HDC ctx)) + + +/* +** SWELL_GetCtxFrameBuffer() +** Gets the framebuffer of a memory context. NULL if none available. +*/ +SWELL_API_DEFINE(void *, SWELL_GetCtxFrameBuffer,(HDC ctx)) + + + +/* +** Some utility functions for pushing, setting, and popping the clip region. +*/ +SWELL_API_DEFINE(void, SWELL_PushClipRegion,(HDC ctx)) +SWELL_API_DEFINE(void, SWELL_SetClipRegion,(HDC ctx, RECT *r)) +SWELL_API_DEFINE(void, SWELL_PopClipRegion,(HDC ctx)) + + + +/* +** GDI emulation functions +** todo: document +*/ + +SWELL_API_DEFINE(HFONT, CreateFontIndirect,(LOGFONT *)) +SWELL_API_DEFINE(HFONT, CreateFont,(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, + char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, + char lfQuality, char lfPitchAndFamily, const char *lfFaceName)) + +SWELL_API_DEFINE(HPEN, CreatePen,(int attr, int wid, int col)) +SWELL_API_DEFINE(HBRUSH, CreateSolidBrush,(int col)) +SWELL_API_DEFINE(HPEN, CreatePenAlpha,(int attr, int wid, int col, float alpha)) +SWELL_API_DEFINE(HBRUSH, CreateSolidBrushAlpha,(int col, float alpha)) +SWELL_API_DEFINE(HGDIOBJ, SelectObject,(HDC ctx, HGDIOBJ pen)) +SWELL_API_DEFINE(HGDIOBJ, GetStockObject,(int wh)) +SWELL_API_DEFINE(void, DeleteObject,(HGDIOBJ)) +#ifndef DestroyIcon +#define DestroyIcon(x) DeleteObject(x) +#endif + +#ifdef LineTo +#undef LineTo +#endif +#ifdef SetPixel +#undef SetPixel +#endif +#ifdef FillRect +#undef FillRect +#endif +#ifdef DrawText +#undef DrawText +#endif +#ifdef Polygon +#undef Polygon +#endif + +#define DrawText SWELL_DrawText +#define FillRect SWELL_FillRect +#define LineTo SWELL_LineTo +#define SetPixel SWELL_SetPixel +#define Polygon(a,b,c) SWELL_Polygon(a,b,c) + +SWELL_API_DEFINE(void, SWELL_FillRect,(HDC ctx, RECT *r, HBRUSH br)) +SWELL_API_DEFINE(void, Rectangle,(HDC ctx, int l, int t, int r, int b)) +SWELL_API_DEFINE(void, Ellipse,(HDC ctx, int l, int t, int r, int b)) +SWELL_API_DEFINE(void, SWELL_Polygon,(HDC ctx, POINT *pts, int npts)) +SWELL_API_DEFINE(void, MoveToEx,(HDC ctx, int x, int y, POINT *op)) +SWELL_API_DEFINE(void, LineTo,(HDC ctx, int x, int y)) +SWELL_API_DEFINE(void, SetPixel,(HDC ctx, int x, int y, int c)) +SWELL_API_DEFINE(void, PolyBezierTo,(HDC ctx, POINT *pts, int np)) +SWELL_API_DEFINE(int, SWELL_DrawText,(HDC ctx, const char *buf, int len, RECT *r, int align)) +SWELL_API_DEFINE(void, SetTextColor,(HDC ctx, int col)) +SWELL_API_DEFINE(int, GetTextColor,(HDC ctx)) +SWELL_API_DEFINE(void, SetBkColor,(HDC ctx, int col)) +SWELL_API_DEFINE(void, SetBkMode,(HDC ctx, int col)) + +SWELL_API_DEFINE(void, RoundRect,(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd)) +SWELL_API_DEFINE(void, PolyPolyline,(HDC ctx, POINT *pts, DWORD *cnts, int nseg)) +SWELL_API_DEFINE(BOOL, GetTextMetrics,(HDC ctx, TEXTMETRIC *tm)) +#ifdef SWELL_TARGET_OSX +SWELL_API_DEFINE(void *, GetNSImageFromHICON,(HICON)) +#endif +SWELL_API_DEFINE(BOOL, GetObject, (HICON icon, int bmsz, void *_bm)) +SWELL_API_DEFINE(HICON, CreateIconIndirect, (ICONINFO* iconinfo)) +SWELL_API_DEFINE(HICON, LoadNamedImage,(const char *name, bool alphaFromMask)) +SWELL_API_DEFINE(void, DrawImageInRect,(HDC ctx, HICON img, RECT *r)) +SWELL_API_DEFINE(void, BitBlt,(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode)) +SWELL_API_DEFINE(void, StretchBlt,(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode)) +SWELL_API_DEFINE(int, GetSysColor,(int idx)) +SWELL_API_DEFINE(HBITMAP, CreateBitmap,(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits)) + +SWELL_API_DEFINE(void, SetOpaque, (HWND h, bool isopaque)) +#ifdef SWELL_TARGET_OSX +SWELL_API_DEFINE(void, SWELL_SetViewGL, (HWND h, bool wantGL)) +SWELL_API_DEFINE(bool, SWELL_GetViewGL, (HWND h)) +SWELL_API_DEFINE(bool, SWELL_SetGLContextToView, (HWND h)) // sets GL context to that view, returns TRUE if successs (use NULL to clear GL context) +#endif + +SWELL_API_DEFINE(HDC, BeginPaint,(HWND, PAINTSTRUCT *)) +SWELL_API_DEFINE(BOOL, EndPaint,(HWND, PAINTSTRUCT *)) + +SWELL_API_DEFINE(HDC, GetDC,(HWND)) // use these sparingly! they kinda work but shouldnt be overused!! +SWELL_API_DEFINE(HDC, GetWindowDC,(HWND)) +SWELL_API_DEFINE(void, ReleaseDC,(HWND, HDC)) + +#ifdef __APPLE__ +SWELL_API_DEFINE(void, SWELL_FlushWindow,(HWND)) +#endif + +SWELL_API_DEFINE(void, SWELL_FillDialogBackground,(HDC hdc, RECT *r, int level)) + +SWELL_API_DEFINE(HGDIOBJ,SWELL_CloneGDIObject,(HGDIOBJ a)) + +SWELL_API_DEFINE(int, GetSystemMetrics, (int)) + +SWELL_API_DEFINE(BOOL, DragQueryPoint,(HDROP,LPPOINT)) +SWELL_API_DEFINE(void, DragFinish,(HDROP)) +SWELL_API_DEFINE(UINT, DragQueryFile,(HDROP,UINT,char *,UINT)) + +// source drag/drop - callback is source implementing "create dropped files at droppath" +SWELL_API_DEFINE(void, SWELL_InitiateDragDrop, (HWND, RECT* srcrect, const char* srcfn, void (*callback)(const char* droppath))) +SWELL_API_DEFINE(void,SWELL_InitiateDragDropOfFileList,(HWND, RECT *srcrect, const char **srclist, int srccount, HICON icon)) +SWELL_API_DEFINE(void, SWELL_FinishDragDrop, ()) // cancels any outstanding InitiateDragDrop + + + +// r=NULL to "free" handle +// otherwise r is in hwndPar coordinates +SWELL_API_DEFINE(void,SWELL_DrawFocusRect,(HWND hwndPar, RECT *rct, void **handle)) + + +#ifdef SWELL_TARGET_OSX +SWELL_API_DEFINE(void,SWELL_SetWindowRepre,(HWND hwnd, const char *fn, bool isDirty)) // sets the represented file and edited state +SWELL_API_DEFINE(void,SWELL_PostQuitMessage,(void *sender)) +#endif + +/* +** Functions used by swell-dlggen.h and swell-menugen.h +** No need to really dig into these unless you're working on swell or debugging.. +*/ + +SWELL_API_DEFINE(void, SWELL_MakeSetCurParms,(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit)) + +SWELL_API_DEFINE(HWND, SWELL_MakeButton,(int def, const char *label, int idx, int x, int y, int w, int h, int flags)) +SWELL_API_DEFINE(HWND, SWELL_MakeEditField,(int idx, int x, int y, int w, int h, int flags)) +SWELL_API_DEFINE(HWND, SWELL_MakeLabel,(int align, const char *label, int idx, int x, int y, int w, int h, int flags)) +SWELL_API_DEFINE(HWND, SWELL_MakeControl,(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle)) +SWELL_API_DEFINE(HWND, SWELL_MakeCombo,(int idx, int x, int y, int w, int h, int flags)) +SWELL_API_DEFINE(HWND, SWELL_MakeGroupBox,(const char *name, int idx, int x, int y, int w, int h, int style)) +SWELL_API_DEFINE(HWND, SWELL_MakeCheckBox,(const char *name, int idx, int x, int y, int w, int h, int flags)) +SWELL_API_DEFINE(HWND, SWELL_MakeListBox,(int idx, int x, int y, int w, int h, int styles)) + +SWELL_API_DEFINE(void, SWELL_Menu_AddMenuItem,(HMENU hMenu, const char *name, int idx, int flags)) +SWELL_API_DEFINE(int, SWELL_GenerateMenuFromList,(HMENU hMenu, const void *list, int listsz)) // list is SWELL_MenuGen_Entry + +SWELL_API_DEFINE(void, SWELL_GenerateDialogFromList, (const void *list, int listsz)) + + +SWELL_API_DEFINE(unsigned int, _controlfp,(unsigned int flag, unsigned int mask)) + +SWELL_API_DEFINE(void,SWELL_Internal_PostMessage_Init,()) + + +SWELL_API_DEFINE(HCURSOR,SWELL_LoadCursorFromFile,(const char *fn)) +SWELL_API_DEFINE(void,SWELL_SetWindowWantRaiseAmt,(HWND h, int amt)) + +SWELL_API_DEFINE(void,SWELL_SetListViewFastClickMask,(HWND hList, int mask)) + + +#ifndef __APPLE__ +SWELL_API_DEFINE(void,SWELL_initargs,(int *argc, char ***argv)) +SWELL_API_DEFINE(void,SWELL_RunMessageLoop,()) +#endif + +#ifdef __APPLE__ +SWELL_API_DEFINE(void,SWELL_GenerateGUID,(void *g)) +#endif + +SWELL_API_DEFINE(BOOL,EnumChildWindows,(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam)) + + +SWELL_API_DEFINE(BOOL,SWELL_IsGroupBox,(HWND)) +SWELL_API_DEFINE(BOOL,SWELL_IsButton,(HWND)) +SWELL_API_DEFINE(BOOL,SWELL_IsStaticText,(HWND)) +SWELL_API_DEFINE(void,SWELL_GetDesiredControlSize,(HWND hwnd, RECT *r)) + + +#endif // _WDL_SWELL_H_API_DEFINED_ diff --git a/WDL/swell/swell-gdi-generic.cpp b/WDL/swell/swell-gdi-generic.cpp new file mode 100644 index 00000000..a46cd88a --- /dev/null +++ b/WDL/swell/swell-gdi-generic.cpp @@ -0,0 +1,676 @@ + +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic win32 GDI-->lice? translation. + +*/ + +#ifndef SWELL_LICE_GDI +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-internal.h" + +#include "../lice/lice.h" +#include "../mutex.h" +#include "../ptrlist.h" + +#include "swell-gdi-internalpool.h" + + +HDC SWELL_CreateGfxContext(void *c) +{ + HDC__ *ctx=SWELL_GDP_CTX_NEW(); + + + return ctx; +} + +HDC SWELL_CreateMemContext(HDC hdc, int w, int h) +{ + // we could use CGLayer here, but it's 10.4+ and seems to be slower than this +// if (w&1) w++; + void *buf=calloc(w*4,h); + if (!buf) return 0; + + HDC__ *ctx=SWELL_GDP_CTX_NEW(); + ctx->ownedData=buf; + + SetTextColor(ctx,0); + return ctx; +} + + +void SWELL_DeleteGfxContext(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)) + { + if (ct->ownedData) + { + free(ct->ownedData); + } + SWELL_GDP_CTX_DELETE(ct); + } +} +HPEN CreatePen(int attr, int wid, int col) +{ + return CreatePenAlpha(attr,wid,col,1.0f); +} + +HBRUSH CreateSolidBrush(int col) +{ + return CreateSolidBrushAlpha(col,1.0f); +} + +HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) +{ + HGDIOBJ__ *pen=GDP_OBJECT_NEW(); + pen->type=TYPE_PEN; + pen->wid=wid<0?0:wid; +// pen->color=CreateColor(col,alpha); + return pen; +} +HBRUSH CreateSolidBrushAlpha(int col, float alpha) +{ + HGDIOBJ__ *brush=GDP_OBJECT_NEW(); + brush->type=TYPE_BRUSH; +// brush->color=CreateColor(col,alpha); + brush->wid=0; + return brush; +} + +#define FONTSCALE 0.9 +HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, + char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, + char lfQuality, char lfPitchAndFamily, const char *lfFaceName) +{ + HGDIOBJ__ *font=GDP_OBJECT_NEW(); + font->type=TYPE_FONT; + float fontwid=lfHeight; + + + if (!fontwid) fontwid=lfWidth; + if (fontwid<0)fontwid=-fontwid; + + if (fontwid < 2 || fontwid > 8192) fontwid=10; + + return font; +} + + +HFONT CreateFontIndirect(LOGFONT *lf) +{ + return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, + lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, + lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); +} + +void DeleteObject(HGDIOBJ pen) +{ + if (HGDIOBJ_VALID(pen)) + { + HGDIOBJ__ *p=(HGDIOBJ__ *)pen; + if (--p->additional_refcnt < 0) + { + if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) + { + if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) + if (p->wid<0) return; + + GDP_OBJECT_DELETE(p); + } + // JF> don't free unknown objects, this should never happen anyway: else free(p); + } + } +} + + +HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *p=(HGDIOBJ__ *) pen; + HGDIOBJ__ **mod=0; + if (!HDC_VALID(c)||!p) return 0; + + if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen; + else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush; + else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont; + + if (mod) + { + HGDIOBJ__ *np=*mod; + *mod=0; + return np?np:p; + } + + if (!HGDIOBJ_VALID(p)) return 0; + + if (p->type == TYPE_PEN) mod=&c->curpen; + else if (p->type == TYPE_BRUSH) mod=&c->curbrush; + else if (p->type == TYPE_FONT) mod=&c->curfont; + else return 0; + + HGDIOBJ__ *op=*mod; + if (!op) op=(HGDIOBJ__ *)p->type; + if (op != p) + { + *mod=p; + + if (p->type == TYPE_FONT) + { +// CGContextSelectFont(c->ctx,p->fontface,(float)p->wid,kCGEncodingMacRoman); + } + } + return op; +} + + + +void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *b=(HGDIOBJ__ *) br; + if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return; + + if (b->wid<0) return; + + +} + +void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) +{ + xrnd/=3; + yrnd/=3; + POINT pts[10]={ // todo: curves between edges + {x,y+yrnd}, + {x+xrnd,y}, + {x2-xrnd,y}, + {x2,y+yrnd}, + {x2,y2-yrnd}, + {x2-xrnd,y2}, + {x+xrnd,y2}, + {x,y2-yrnd}, + {x,y+yrnd}, + {x+xrnd,y}, +}; + + WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); +} + +void Ellipse(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + //CGRect rect=CGRectMake(l,t,r-l,b-t); + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) + { + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + } +} + +void Rectangle(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + //CGRect rect=CGRectMake(l,t,r-l,b-t); + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + } +} + +HGDIOBJ GetStockObject(int wh) +{ + switch (wh) + { + case NULL_BRUSH: + { + static HGDIOBJ__ br={0,}; + br.type=TYPE_BRUSH; + br.wid=-1; + return &br; + } + case NULL_PEN: + { + static HGDIOBJ__ pen={0,}; + pen.type=TYPE_PEN; + pen.wid=-1; + return &pen; + } + } + return 0; +} + +void Polygon(HDC ctx, POINT *pts, int npts) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && + (!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return; + +// CGContextBeginPath(c->ctx); + // CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); + int x; + for (x = 1; x < npts; x ++) + { + // CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); + } + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + // CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) + { +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); + // CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + } +// CGContextDrawPath(c->ctx,c->curpen && c->curpen->wid>=0 && c->curbrush && c->curbrush->wid>=0 ? kCGPathFillStroke : c->curpen && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); +} + +void MoveToEx(HDC ctx, int x, int y, POINT *op) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (op) + { + op->x = (int) (c->lastpos_x); + op->y = (int) (c->lastpos_y); + } + c->lastpos_x=(float)x; + c->lastpos_y=(float)y; +} + +void PolyBezierTo(HDC ctx, POINT *pts, int np) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); +// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); + int x; + float xp,yp; + for (x = 0; x < np-2; x += 3) + { +/* CGContextAddCurveToPoint(c->ctx, + (float)pts[x].x,(float)pts[x].y, + (float)pts[x+1].x,(float)pts[x+1].y, +*/ + xp=(float)pts[x+2].x; + yp=(float)pts[x+2].y; + } + c->lastpos_x=(float)xp; + c->lastpos_y=(float)yp; +// CGContextStrokePath(c->ctx); +} + + +void SWELL_LineTo(HDC ctx, int x, int y) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); +// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); + float fx=(float)x,fy=(float)y; + +// CGContextAddLineToPoint(c->ctx,fx,fy); + c->lastpos_x=fx; + c->lastpos_y=fy; +// CGContextStrokePath(c->ctx); +} + +void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); + + while (nseg-->0) + { + DWORD cnt=*cnts++; + if (!cnt) continue; + if (!--cnt) { pts++; continue; } + + // CGContextMoveToPoint(c->ctx,(float)pts->x,(float)pts->y); + pts++; + + while (cnt--) + { +// CGContextAddLineToPoint(c->ctx,(float)pts->x,(float)pts->y); + pts++; + } + } +// CGContextStrokePath(c->ctx); +} +void *SWELL_GetCtxGC(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return 0; + return NULL; +} + + +void SWELL_SetPixel(HDC ctx, int x, int y, int c) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + /* CGContextBeginPath(ct->ctx); + CGContextMoveToPoint(ct->ctx,(float)x,(float)y); + CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); + CGContextSetLineWidth(ct->ctx,(float)1.5); + CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); + CGContextStrokePath(ct->ctx); +*/ +} + + +BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) +{ + HDC__ *ct=(HDC__ *)ctx; + if (tm) // give some sane defaults + { + tm->tmInternalLeading=3; + tm->tmAscent=12; + tm->tmDescent=4; + tm->tmHeight=16; + tm->tmAveCharWidth = 10; + } + if (!HDC_VALID(ct)||!tm) return 0; + + return 1; +} + + +int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return 0; + if (r && (align&DT_CALCRECT)) + { + r->top=r->left=0; + r->bottom=10; + r->right = ( buflen < 0 ? strlen(buf) : buflen ) *8; + } + else printf("DrawText: %s\n",buf); + return 10; +} + +void SetBkColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkcol=col; +} + +void SetBkMode(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkmode=col; +} +int GetTextColor(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return -1; + return ct->cur_text_color_int; +} + +void SetTextColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->cur_text_color_int = col; + +} + +HICON LoadNamedImage(const char *name, bool alphaFromMask) +{ + return 0; // todo +} + +void DrawImageInRect(HDC ctx, HICON img, RECT *r) +{ + // todo +} + + +BOOL GetObject(HICON icon, int bmsz, void *_bm) +{ + memset(_bm,0,bmsz); + if (bmsz != sizeof(BITMAP)) return false; + BITMAP *bm=(BITMAP *)_bm; + HGDIOBJ__ *i = (HGDIOBJ__ *)icon; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; + + return false; +/* + NSImage *img = i->bitmapptr; + if (!img) return false; + bm->bmWidth = (int) ([img size].width+0.5); + bm->bmHeight = (int) ([img size].height+0.5); + return true; +*/ +} + + +#define ColorFromNSColor(a,b) (b) +int GetSysColor(int idx) +{ + // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor + switch (idx) + { + case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_3DFACE: + case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); + case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); + case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); + case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); + case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; + case COLOR_INFOBK: return RGB(255,240,200); + case COLOR_INFOTEXT: return RGB(0,0,0); + + } + return 0; +} + +void BitBltAlphaFromMem(HDC hdcOut, int x, int y, int w, int h, void *inbufptr, int inbuf_span, int inbuf_h, int xin, int yin, int mode, bool useAlphaChannel, float opacity) +{ +} + +void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity) +{ +} + +void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) +{ +} + +void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode) +{ +} + +void SWELL_PushClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextSaveGState(ct->ctx); +} + +void SWELL_SetClipRegion(HDC ctx, RECT *r) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); + +} + +void SWELL_PopClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextRestoreGState(ct->ctx); +} + +void *SWELL_GetCtxFrameBuffer(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)) return ct->ownedData; + return 0; +} + + +HDC GetDC(HWND h) +{ + return NULL; +} + +HDC GetWindowDC(HWND h) +{ + return NULL; +} + +void ReleaseDC(HWND h, HDC hdc) +{ +} + +void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) +{ +} + +HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) +{ + if (HGDIOBJ_VALID(a)) + { + a->additional_refcnt++; + return a; + } + return NULL; +} + +HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) +{ + if (!ps) return 0; + memset(ps,0,sizeof(PAINTSTRUCT)); + if (!hwnd) return 0; + + return NULL; +} + + +HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) +{ + return NULL; +} + +HICON CreateIconIndirect(ICONINFO* iconinfo) +{ + return NULL; +} +HIMAGELIST ImageList_CreateEx() +{ + return (HIMAGELIST)new WDL_PtrList; +} +BOOL ImageList_Remove(HIMAGELIST list, int idx) +{ + WDL_PtrList* imglist=(WDL_PtrList*)list; + if (imglist && idx < imglist->GetSize()) + { + if (idx < 0) + { + int x,n=imglist->GetSize(); + for (x=0;xGet(x); + if (a) DeleteObject(a); + } + imglist->Empty(); + } + else + { + HGDIOBJ__ *a = imglist->Get(idx); + imglist->Set(idx, NULL); + if (a) DeleteObject(a); + } + return TRUE; + } + + return FALSE; +} + +void ImageList_Destroy(HIMAGELIST list) +{ + if (!list) return; + WDL_PtrList *p=(WDL_PtrList*)list; + ImageList_Remove(list,-1); + delete p; +} + +int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) +{ + if (!image || !list) return -1; + WDL_PtrList *l=(WDL_PtrList *)list; + + HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; + if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; + + HGDIOBJ__* icon=GDP_OBJECT_NEW(); + icon->type=TYPE_BITMAP; + icon->wid=1; + // todo: copy underlying image + + image = (HICON) icon; + + if (offset<0||offset>=l->GetSize()) + { + l->Add(image); + offset=l->GetSize()-1; + } + else + { + HICON old=l->Get(offset); + l->Set(offset,image); + if (old) DeleteObject(old); + } + return offset; +} + + + + +#endif +#endif // !SWELL_LICE_GDI diff --git a/WDL/swell/swell-gdi-internalpool.h b/WDL/swell/swell-gdi-internalpool.h new file mode 100644 index 00000000..df558d96 --- /dev/null +++ b/WDL/swell/swell-gdi-internalpool.h @@ -0,0 +1,194 @@ +// used for HDC/HGDIOBJ pooling (to avoid excess heap use), used by swell-gdi.mm and swell-gdi-generic.cpp + +#if defined(_DEBUG) + #define SWELL_GDI_DEBUG +#endif + +static WDL_Mutex *m_ctxpool_mutex; +#ifdef SWELL_GDI_DEBUG + #include + #include "../ptrlist.h" + static WDL_PtrList *m_ctxpool_debug; + static WDL_PtrList *m_objpool_debug; +#else + static HDC__ *m_ctxpool; + static int m_ctxpool_size; + static HGDIOBJ__ *m_objpool; + static int m_objpool_size; +#endif + + + +HDC__ *SWELL_GDP_CTX_NEW() +{ + if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; + + HDC__ *p=NULL; +#ifdef SWELL_GDI_DEBUG + m_ctxpool_mutex->Enter(); + if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList; + if (m_ctxpool_debug->GetSize() > 8192) + { + p = m_ctxpool_debug->Get(0); + m_ctxpool_debug->Delete(0); + memset(p,0,sizeof(*p)); + } + m_ctxpool_mutex->Leave(); +#else + if (m_ctxpool) + { + m_ctxpool_mutex->Enter(); + if ((p=m_ctxpool)) + { + m_ctxpool=p->_next; + m_ctxpool_size--; + memset(p,0,sizeof(*p)); + } + m_ctxpool_mutex->Leave(); + } +#endif + if (!p) + { +// printf("alloc ctx\n"); + p=(HDC__ *)calloc(sizeof(HDC__)+128,1); // extra space in case things want to use it (i.e. swell-gdi-lice does) + } + return p; +} +static void SWELL_GDP_CTX_DELETE(HDC__ *p) +{ + if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; + + if (!p) return; + + if (p->_infreelist) + { +#ifdef SWELL_GDI_DEBUG + assert(!p->_infreelist); +#endif + return; + } + + memset(p,0,sizeof(*p)); + +#ifdef SWELL_GDI_DEBUG + m_ctxpool_mutex->Enter(); + p->_infreelist=true; + if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList; + m_ctxpool_debug->Add(p); + m_ctxpool_mutex->Leave(); +#else + if (m_ctxpool_size<100) + { + m_ctxpool_mutex->Enter(); + p->_infreelist=true; + p->_next = m_ctxpool; + m_ctxpool = p; + m_ctxpool_size++; + m_ctxpool_mutex->Leave(); + } + else + { + // printf("free ctx\n"); + free(p); + } +#endif +} +static HGDIOBJ__ *GDP_OBJECT_NEW() +{ + if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; + HGDIOBJ__ *p=NULL; +#ifdef SWELL_GDI_DEBUG + m_ctxpool_mutex->Enter(); + if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList; + if (m_objpool_debug->GetSize()>8192) + { + p = m_objpool_debug->Get(0); + m_objpool_debug->Delete(0); + memset(p,0,sizeof(*p)); + } + m_ctxpool_mutex->Leave(); +#else + if (m_objpool) + { + m_ctxpool_mutex->Enter(); + if ((p=m_objpool)) + { + m_objpool = p->_next; + m_objpool_size--; + memset(p,0,sizeof(*p)); + } + m_ctxpool_mutex->Leave(); + } +#endif + if (!p) + { + // printf("alloc obj\n"); + p=(HGDIOBJ__ *)calloc(sizeof(HGDIOBJ__),1); + } + return p; +} +static void GDP_OBJECT_DELETE(HGDIOBJ__ *p) +{ + if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex; + if (!p) return; + + if (p->_infreelist) + { +#ifdef SWELL_GDI_DEBUG + assert(!p->_infreelist); +#endif + return; + } + + memset(p,0,sizeof(*p)); +#ifdef SWELL_GDI_DEBUG + m_ctxpool_mutex->Enter(); + p->_infreelist = true; + if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList; + m_objpool_debug->Add(p); + m_ctxpool_mutex->Leave(); +#else + if (m_objpool_size<200) + { + m_ctxpool_mutex->Enter(); + p->_infreelist = true; + p->_next = m_objpool; + m_objpool = p; + m_objpool_size++; + m_ctxpool_mutex->Leave(); + } + else + { + // printf("free obj\n"); + free(p); + } +#endif +} + +static bool HGDIOBJ_VALID(HGDIOBJ__ *p, int reqType=0) +{ + if (p == (HGDIOBJ__*)TYPE_PEN || p == (HGDIOBJ__*)TYPE_BRUSH || + p == (HGDIOBJ__*)TYPE_FONT || p == (HGDIOBJ__*)TYPE_BITMAP) return false; +#ifdef SWELL_GDI_DEBUG + if (p) { assert(!p->_infreelist); } +#endif + // insert breakpoints in these parts for debugging + if (p && !p->_infreelist) + { +#ifdef SWELL_GDI_DEBUG + if (reqType) { assert(reqType == p->type); } +#endif + + return !reqType || reqType == p->type; + } + return false; +} + +static bool HDC_VALID(HDC__ *ct) +{ +#ifdef SWELL_GDI_DEBUG + if (ct) { assert(!ct->_infreelist); } +#endif + // insert breakpoints in these parts for debugging + return ct && !ct->_infreelist; +} diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp new file mode 100644 index 00000000..55382396 --- /dev/null +++ b/WDL/swell/swell-gdi-lice.cpp @@ -0,0 +1,1284 @@ + +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic win32 GDI-->lice translation. + +*/ + +#ifdef SWELL_LICE_GDI +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-internal.h" + +#include "../mutex.h" +#include "../ptrlist.h" + +#include "swell-gdi-internalpool.h" + + +#ifdef SWELL_FREETYPE +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H + +static bool s_freetype_failed; +static FT_Library s_freetype; // todo: TLS for multithread support? + +#include "../dirscan.h" + +static int utf8char(const char *ptr, unsigned short *charOut) // returns char length +{ + const unsigned char *p = (const unsigned char *)ptr; + unsigned char tc = *p; + + if (tc < 128) + { + if (charOut) *charOut = (unsigned short) tc; + return 1; + } + else if (tc < 0xC2) // invalid chars (subsequent in sequence, or overlong which we disable for) + { + } + else if (tc < 0xE0) // 2 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0) + { + if (charOut) *charOut = ((tc&0x1f)<<6) | (p[1]&0x3f); + return 2; + } + } + else if (tc < 0xF0) // 3 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0) + { + if (charOut) *charOut = ((tc&0xf)<<12) | ((p[1]&0x3f)<<6) | ((p[2]&0x3f)); + return 3; + } + } + else if (tc < 0xF5) // 4 char seq + { + if (p[1] >= 0x80 && p[1] <= 0xC0 && p[2] >= 0x80 && p[2] <= 0xC0 && p[3] >= 0x80 && p[3] <= 0xC0) + { + if (charOut) *charOut = (unsigned short)' '; // dont support 4 byte sequences yet(ever?) + return 4; + } + } + if (charOut) *charOut = (unsigned short) tc; + return 1; +} + + + +#endif + +HDC SWELL_CreateMemContext(HDC hdc, int w, int h) +{ + LICE_MemBitmap * bm = new LICE_MemBitmap(w,h); + if (!bm) return 0; + + HDC__ *ctx=SWELL_GDP_CTX_NEW(); + ctx->surface = bm; + ctx->surface_offs.x=0; + ctx->surface_offs.y=0; + ctx->dirty_rect_valid=false; + + SetTextColor(ctx,0); + return ctx; +} + + +void SWELL_DeleteGfxContext(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)) + { + delete ct->surface; + ct->surface=0; + SWELL_GDP_CTX_DELETE(ct); + } +} + +HPEN CreatePen(int attr, int wid, int col) +{ + return CreatePenAlpha(attr,wid,col,1.0f); +} + +HBRUSH CreateSolidBrush(int col) +{ + return CreateSolidBrushAlpha(col,1.0f); +} + +HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) +{ + HGDIOBJ__ *pen=GDP_OBJECT_NEW(); + pen->type=TYPE_PEN; + pen->wid=wid<0?0:wid; + pen->color=LICE_RGBA_FROMNATIVE(col); + return pen; +} +HBRUSH CreateSolidBrushAlpha(int col, float alpha) +{ + HGDIOBJ__ *brush=GDP_OBJECT_NEW(); + brush->type=TYPE_BRUSH; + brush->color=LICE_RGBA_FROMNATIVE(col); + brush->wid=0; + return brush; +} + +void SetBkColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkcol=LICE_RGBA_FROMNATIVE(col,255); +} + +void SetBkMode(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkmode=col; +} + +HGDIOBJ GetStockObject(int wh) +{ + switch (wh) + { + case NULL_BRUSH: + { + static HGDIOBJ__ br={0,}; + br.type=TYPE_BRUSH; + br.wid=-1; + return &br; + } + case NULL_PEN: + { + static HGDIOBJ__ pen={0,}; + pen.type=TYPE_PEN; + pen.wid=-1; + return &pen; + } + } + return 0; +} + + +#define FONTSCALE 0.9 +HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, + char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, + char lfQuality, char lfPitchAndFamily, const char *lfFaceName) +{ + HGDIOBJ__ *font=NULL; +#ifdef SWELL_FREETYPE + FT_Face face=NULL; + if (!s_freetype_failed && !s_freetype) s_freetype_failed = !!FT_Init_FreeType(&s_freetype); + if (s_freetype) + { + if (!lfFaceName || !*lfFaceName) lfFaceName = "Arial"; + + int fn_len = strlen(lfFaceName); + + const char *leadpath = "/usr/share/fonts/truetype/msttcorefonts"; // todo: scan subdirs? + char tmp[1024]; + char bestmatch[512]; + bestmatch[0]=0; + snprintf(tmp,sizeof(tmp),"%s/%s.ttf",leadpath,lfFaceName); + FT_New_Face(s_freetype,tmp,0,&face); + if (!face) + { + WDL_DirScan ds; + if (!ds.First(leadpath)) do + { + if (!strnicmp(ds.GetCurrentFN(),lfFaceName,fn_len)) + { + if (!stricmp(ds.GetCurrentFN()+fn_len,".ttf")) + { + snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,ds.GetCurrentFN()); + FT_New_Face(s_freetype,tmp,0,&face); + } + else + { + // todo look for italic/bold/etc too + int sl = strlen(ds.GetCurrentFN()); + if (sl > 4 && !stricmp(ds.GetCurrentFN() + sl - 4, ".ttf") && (!bestmatch[0] || sl < strlen(bestmatch))) + { + lstrcpyn(bestmatch,ds.GetCurrentFN(),sizeof(bestmatch)); + } + } + } + } while (!face && !ds.Next()); + if (!face && bestmatch[0]) + { + snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,bestmatch); + FT_New_Face(s_freetype,tmp,0,&face); + } + } + if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/freefont/FreeSans.ttf",0,&face); + if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",0,&face); + } + + if (face) + { + font = GDP_OBJECT_NEW(); + font->type=TYPE_FONT; + font->fontface = face; + ////unsure here + if (lfWidth<0) lfWidth=-lfWidth; + if (lfHeight<0) lfHeight=-lfHeight; + FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi +// FT_Set_Pixel_Sizes(face,0,lfHeight); + } +#else + font->type=TYPE_FONT; +#endif + + return font; +} + + +HFONT CreateFontIndirect(LOGFONT *lf) +{ + return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, + lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, + lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); +} + +void DeleteObject(HGDIOBJ pen) +{ + if (HGDIOBJ_VALID(pen)) + { + HGDIOBJ__ *p=(HGDIOBJ__ *)pen; + if (--p->additional_refcnt < 0) + { + if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) + { + if (p->type == TYPE_FONT) + { +#ifdef SWELL_FREETYPE + if (p->fontface) + { + FT_Done_Face((FT_Face)p->fontface); + p->fontface = 0; + } +#endif + } + else if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) + { + if (p->wid<0) return; + } + + GDP_OBJECT_DELETE(p); + } + // JF> don't free unknown objects, this should never happen anyway: else free(p); + } + } +} + + +HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *p= pen; + HGDIOBJ__ **mod=0; + if (!HDC_VALID(c)||!p) return 0; + + if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen; + else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush; + else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont; + + if (mod) + { + HGDIOBJ__ *np=*mod; + *mod=0; + return np?np:p; + } + + if (!HGDIOBJ_VALID(p)) return 0; + + if (p->type == TYPE_PEN) mod=&c->curpen; + else if (p->type == TYPE_BRUSH) mod=&c->curbrush; + else if (p->type == TYPE_FONT) mod=&c->curfont; + else return 0; + + HGDIOBJ__ *op=*mod; + if (!op) op=(HGDIOBJ__ *)p->type; + if (op != p) + { + *mod=p; + } + return op; +} + + +static void swell_DirtyContext(HDC__ *out, int x1, int y1, int x2, int y2) +{ + if (x2surface_offs.x; + x2+=out->surface_offs.x; + y1+=out->surface_offs.y; + y2+=out->surface_offs.y; + + if (!out->dirty_rect_valid) + { + out->dirty_rect_valid=true; + out->dirty_rect.left = x1; + out->dirty_rect.top = y1; + out->dirty_rect.right = x2; + out->dirty_rect.bottom = y2; + } + else + { + if (out->dirty_rect.left > x1) out->dirty_rect.left=x1; + if (out->dirty_rect.top > y1) out->dirty_rect.top = y1; + if (out->dirty_rect.right < x2) out->dirty_rect.right = x2; + if (out->dirty_rect.bottom < y2) out->dirty_rect.bottom = y2; + } +} + + +void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *b=(HGDIOBJ__ *) br; + if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return; + if (!c->surface) return; + + if (b->wid<0) return; + LICE_FillRect(c->surface, + r->left+c->surface_offs.x, + r->top+c->surface_offs.y, + r->right-r->left,r->bottom-r->top,b->color,1.0f,LICE_BLIT_MODE_COPY); + +} + +void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) +{ + xrnd/=3; + yrnd/=3; + POINT pts[10]={ // todo: curves between edges + {x,y+yrnd}, + {x+xrnd,y}, + {x2-xrnd,y}, + {x2,y+yrnd}, + {x2,y2-yrnd}, + {x2-xrnd,y2}, + {x+xrnd,y2}, + {x,y2-yrnd}, + {x,y+yrnd}, + {x+xrnd,y}, +}; + + WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); +} + +void Ellipse(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + //CGRect rect=CGRectMake(l,t,r-l,b-t); + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) + { + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + } +} + +void Rectangle(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + //CGRect rect=CGRectMake(l,t,r-l,b-t); + + l += c->surface_offs.x; + t += c->surface_offs.y; + r += c->surface_offs.x; + b += c->surface_offs.y; + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + LICE_FillRect(c->surface,l,t,r-l,b-t,c->curbrush->color,1.0f,LICE_BLIT_MODE_COPY); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + LICE_DrawRect(c->surface,l,t,r-l,b-t,c->curpen->color,1.0f,LICE_BLIT_MODE_COPY); + } +} + +void Polygon(HDC ctx, POINT *pts, int npts) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && + (!HGDIOBJ_VALID(c->curpen,TYPE_PEN) ||c->curpen->wid<0)) || npts<2) return; + +// CGContextBeginPath(c->ctx); + // CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); + int x; + for (x = 1; x < npts; x ++) + { + // CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); + } + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + // CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) + { +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); + // CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + } +// CGContextDrawPath(c->ctx,c->curpen && c->curpen->wid>=0 && c->curbrush && c->curbrush->wid>=0 ? kCGPathFillStroke : c->curpen && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); +} + +void MoveToEx(HDC ctx, int x, int y, POINT *op) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (op) + { + op->x = (int) (c->lastpos_x); + op->y = (int) (c->lastpos_y); + } + c->lastpos_x=(float)x; + c->lastpos_y=(float)y; +} + +void PolyBezierTo(HDC ctx, POINT *pts, int np) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); +// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); + int x; + float xp,yp; + for (x = 0; x < np-2; x += 3) + { +/* CGContextAddCurveToPoint(c->ctx, + (float)pts[x].x,(float)pts[x].y, + (float)pts[x+1].x,(float)pts[x+1].y, +*/ + xp=(float)pts[x+2].x; + yp=(float)pts[x+2].y; + } + c->lastpos_x=(float)xp; + c->lastpos_y=(float)yp; +// CGContextStrokePath(c->ctx); +} + + +void SWELL_LineTo(HDC ctx, int x, int y) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); +// CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); + float fx=(float)x,fy=(float)y; + + int dx=c->surface_offs.x; + int dy=c->surface_offs.y; + LICE_Line(c->surface,x+dx,y+dy,(int)c->lastpos_x+dx,(int)c->lastpos_y+dy,c->curpen->color,1.0f,LICE_BLIT_MODE_COPY,false); + +// CGContextAddLineToPoint(c->ctx,fx,fy); + c->lastpos_x=fx; + c->lastpos_y=fy; +// CGContextStrokePath(c->ctx); +} + +void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; + +// CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); +// CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + +// CGContextBeginPath(c->ctx); + + while (nseg-->0) + { + DWORD cnt=*cnts++; + if (!cnt) continue; + if (!--cnt) { pts++; continue; } + + // CGContextMoveToPoint(c->ctx,(float)pts->x,(float)pts->y); + pts++; + + while (cnt--) + { +// CGContextAddLineToPoint(c->ctx,(float)pts->x,(float)pts->y); + pts++; + } + } +// CGContextStrokePath(c->ctx); +} +void *SWELL_GetCtxGC(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return 0; + return NULL; +} + + +void SWELL_SetPixel(HDC ctx, int x, int y, int c) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + /* CGContextBeginPath(ct->ctx); + CGContextMoveToPoint(ct->ctx,(float)x,(float)y); + CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); + CGContextSetLineWidth(ct->ctx,(float)1.5); + CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); + CGContextStrokePath(ct->ctx); +*/ +} + +#ifdef SWELL_FREETYPE +HFONT SWELL_GetDefaultFont() +{ + static HFONT def; + if (!def) + { + def = CreateFont(12,0,0,0,0,0,0,0,0,0,0,0,0,"Arial"); // todo better defaults + } + return def; +} +#endif + +BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) +{ + HDC__ *ct=(HDC__ *)ctx; + if (tm) // give some sane defaults + { + tm->tmInternalLeading=0; + tm->tmAscent=8; + tm->tmDescent=0; + tm->tmHeight=8; + tm->tmAveCharWidth = 8; + } + if (!HDC_VALID(ct)||!tm) return 0; + +#ifdef SWELL_FREETYPE + HGDIOBJ__ *font = HGDIOBJ_VALID(ct->curfont,TYPE_FONT) ? ct->curfont : SWELL_GetDefaultFont(); + if (font && font->fontface) + { + FT_Face face=(FT_Face) font->fontface; + tm->tmAscent = face->size->metrics.ascender/64; + tm->tmDescent = face->size->metrics.descender/64; + tm->tmHeight = face->size->metrics.height/64; + tm->tmAveCharWidth = face->size->metrics.max_advance/64; + tm->tmInternalLeading=0; + } +#endif + + return 1; +} + + +int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) +{ + const char *obuf=buf; + HDC__ *ct=(HDC__ *)ctx; + if (!r) return 0; + + int lineh = 8; + int charw = 8; + + HGDIOBJ__ *font = NULL; +#ifdef SWELL_FREETYPE + int ascent=0; + font = HDC_VALID(ct) && HGDIOBJ_VALID(ct->curfont,TYPE_FONT) ? ct->curfont : SWELL_GetDefaultFont(); + FT_Face face = NULL; + if (font && font->fontface) + { + face=(FT_Face)font->fontface; + lineh = face->size->metrics.height/64; + ascent = face->size->metrics.ascender/64; + charw = face->size->metrics.max_advance/64; + } +#endif + + if (align&DT_CALCRECT) + { + if (!font && (align&DT_SINGLELINE)) + { + r->right = r->left + ( buflen < 0 ? strlen(buf) : buflen ) * charw; + int h = r->right ? lineh:0; + r->bottom = r->top+h; + return h; + } + + int xpos=0; + int ypos=0; + + r->bottom=r->top; + bool in_prefix=false; + while (buflen && *buf) // if buflen<0, go forever + { + unsigned short c=0; + int charlen = utf8char(buf,&c); + buf+=charlen; + if (buflen > 0) + { + buflen -= charlen; + if (buflen < 0) buflen=0; + } + if (!c) break; + + if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) + { + in_prefix = true; + continue; + } + in_prefix=false; + + if (c == '\n') { ypos += lineh; xpos=0; } + else if (c != '\r') + { + if (font) + { +#ifdef SWELL_FREETYPE + if (!FT_Load_Char(face, c, FT_LOAD_DEFAULT) && face->glyph) + { + // measure character + FT_GlyphSlot g = face->glyph; + int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; + if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; + if (r->left+rext > r->right) r->right = r->left+rext; + xpos += g->metrics.horiAdvance/64; + + int bext = r->top + ypos + ascent + (g->metrics.height - g->metrics.horiBearingY)/64; + if (bext > r->bottom) r->bottom = bext; + continue; + } + } +#endif + xpos += c=='\t' ? charw*5 : charw; + if (r->top + ypos + lineh > r->bottom) r->bottom = r->top+ypos+lineh; + if (r->left+xpos>r->right) r->right=r->left+xpos; + } + } + return r->bottom-r->top; + } + if (!HDC_VALID(ct)) return 0; + + RECT use_r = *r; + use_r.left += ct->surface_offs.x; + use_r.right += ct->surface_offs.x; + use_r.top += ct->surface_offs.y; + use_r.bottom += ct->surface_offs.y; + + int xpos = use_r.left; + int ypos = use_r.top; + if (align&(DT_CENTER|DT_VCENTER|DT_RIGHT|DT_BOTTOM)) + { + RECT tr={0,}; + DrawText(ctx,buf,buflen,&tr,align|DT_CALCRECT); + + if (align&DT_CENTER) + xpos -= ((tr.right-tr.left) - (use_r.right-use_r.left))/2; + else if (align&DT_RIGHT) + xpos = use_r.right - (tr.right-tr.left); + + if (align&DT_VCENTER) + ypos -= ((tr.bottom-tr.top) - (use_r.bottom-use_r.top))/2; + else if (align&DT_BOTTOM) + ypos = use_r.bottom - (tr.bottom-tr.top); + } + LICE_IBitmap *surface = ct->surface; + int fgcol = ct->cur_text_color_int; + int bgcol = ct->curbkcol; + int bgmode = ct->curbkmode; + + + int clip_x1=max(use_r.left,0), clip_y1 = max(use_r.top,0); + int clip_w=0, clip_h=0; + if (surface) + { + clip_w = min(use_r.right,surface->getWidth())-clip_x1; + clip_h = min(use_r.bottom,surface->getHeight())-clip_y1; + if (clip_w<0)clip_w=0; + if (clip_h<0)clip_h=0; + } + + LICE_SubBitmap clipbm(surface,clip_x1,clip_y1,clip_w,clip_h); + if (surface && !(align&DT_NOCLIP)) { surface = &clipbm; xpos-=clip_x1; ypos-=clip_y1; } + + int left_xpos = xpos,ysize=0,max_xpos=0; + int start_ypos = ypos; + bool in_prefix=false; + + while (buflen && *buf) + { + unsigned short c=0; + int charlen = utf8char(buf,&c); + if (buflen>0) + { + buflen -= charlen; + if (buflen<0) buflen=0; + } + buf+=charlen; + + bool doUl=in_prefix; + + if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) + { + in_prefix = true; + continue; + } + in_prefix=false; + + if (c=='\n' && !(align&DT_SINGLELINE)) { xpos=left_xpos; ypos+=lineh; } + else if (c=='\r') {} + else + { + bool needr=true; + if (font) + { +#ifdef SWELL_FREETYPE + if (!FT_Load_Char(face, c, FT_LOAD_RENDER) && face->glyph) + { + FT_GlyphSlot g = face->glyph; + if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,g->metrics.horiAdvance/64,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); + + LICE_DrawGlyphEx(surface,xpos+g->bitmap_left,ypos+ascent-g->bitmap_top,fgcol,(LICE_pixel_chan *)g->bitmap.buffer,g->bitmap.width,g->bitmap.pitch,g->bitmap.rows,1.0f,LICE_BLIT_MODE_COPY); + + int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; + if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; + if (rext > max_xpos) max_xpos=rext; + xpos += g->metrics.horiAdvance/64; + int bext = ypos + lineh + (g->metrics.height - g->metrics.horiBearingY)/64; + if (ysize < bext) ysize=bext; + needr=false; + } +#endif + } + + if (needr) + { + if (c=='\t') + { + if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw*5,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); + xpos+=charw*5; + if (ysize < ypos+lineh) ysize=ypos+lineh; + } + else + { + if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); + LICE_DrawChar(surface,xpos,ypos,c,fgcol,1.0f,LICE_BLIT_MODE_COPY); + if (doUl) LICE_Line(surface,xpos,ypos+lineh+1,xpos+charw,ypos+lineh+1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + + if (ysize < ypos+lineh+(doUl ? 2:1)) ysize=ypos+lineh+(doUl ? 2:1); + xpos+=charw; + } + } + } + if(xpos>max_xpos)max_xpos=xpos; + } + if (surface==&clipbm) + swell_DirtyContext(ct,clip_x1+left_xpos,clip_y1+start_ypos,clip_x1+max_xpos,clip_y1+start_ypos+ysize); + else + swell_DirtyContext(ct,left_xpos,start_ypos,max_xpos,start_ypos+ysize); + return ysize; +} + + +int GetTextColor(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return -1; + return ct->cur_text_color_int; +} +void SetTextColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->cur_text_color_int = LICE_RGBA_FROMNATIVE(col,255); + +} + + +////////// todo: some sort of HICON emul + +HICON LoadNamedImage(const char *name, bool alphaFromMask) +{ + return 0; // todo +} + +void DrawImageInRect(HDC ctx, HICON img, RECT *r) +{ + // todo +} + + +BOOL GetObject(HICON icon, int bmsz, void *_bm) +{ + memset(_bm,0,bmsz); + if (bmsz != sizeof(BITMAP)) return false; + BITMAP *bm=(BITMAP *)_bm; + HGDIOBJ__ *i = (HGDIOBJ__ *)icon; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; + + return false; +/* + NSImage *img = i->bitmapptr; + if (!img) return false; + bm->bmWidth = (int) ([img size].width+0.5); + bm->bmHeight = (int) ([img size].height+0.5); + return true; +*/ +} + + +//////////////////////////////////// + +#define ColorFromNSColor(a,b) (b) +int GetSysColor(int idx) +{ + // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor + switch (idx) + { + case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_3DFACE: + case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); + case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); + case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); + case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); + case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; + case COLOR_INFOBK: return RGB(255,240,200); + case COLOR_INFOTEXT: return RGB(0,0,0); + + } + return 0; +} + +void BitBltAlphaFromMem(HDC hdcOut, int x, int y, int w, int h, void *inbufptr, int inbuf_span, int inbuf_h, int xin, int yin, int mode, bool useAlphaChannel, float opacity) +{ + // todo: use LICE_WrapperBitmap? +} + +void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity) +{ + HDC__ *in = (HDC__ *)hdcIn; + HDC__ *out = (HDC__ *)hdcOut; + if (!HDC_VALID(out) || !HDC_VALID(in)) return; + if (!in->surface || !out->surface) return; + LICE_Blit(out->surface,in->surface, + x+out->surface_offs.x,y+out->surface_offs.y, + xin+in->surface_offs.x,yin+in->surface_offs.y,w,h, + opacity,LICE_BLIT_MODE_COPY|(useAlphaChannel?LICE_BLIT_USE_ALPHA:0)); + swell_DirtyContext(out,x,y,x+w,y+h); +} + +void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) +{ + HDC__ *in = (HDC__ *)hdcIn; + HDC__ *out = (HDC__ *)hdcOut; + if (!HDC_VALID(out) || !HDC_VALID(in)) return; + if (!in->surface || !out->surface) return; + LICE_Blit(out->surface,in->surface, + x+out->surface_offs.x,y+out->surface_offs.y, + xin+in->surface_offs.x,yin+in->surface_offs.y,w,h, + 1.0f,LICE_BLIT_MODE_COPY); + swell_DirtyContext(out,x,y,x+w,y+h); +} + +void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode) +{ +} + +void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) +{ +} + +HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) +{ + if (HGDIOBJ_VALID(a)) + { + a->additional_refcnt++; + return a; + } + return NULL; +} + +void SWELL_PushClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextSaveGState(ct->ctx); +} + +void SWELL_SetClipRegion(HDC ctx, RECT *r) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); + +} + +void SWELL_PopClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; +// if (ct && ct->ctx) CGContextRestoreGState(ct->ctx); +} + +void *SWELL_GetCtxFrameBuffer(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)&&ct->surface) return ct->surface->getBits(); + return 0; +} + + + +struct swell_gdpLocalContext +{ + HDC__ ctx; + RECT clipr; +}; + + + +HDC SWELL_internalGetWindowDC(HWND h, bool calcsize_on_first) +{ + if (!h) return NULL; + + int xoffs=0,yoffs=0; + int wndw = h->m_position.right-h->m_position.left; + int wndh = h->m_position.bottom-h->m_position.top; + + HWND starth = h; + while (h) + { + if ((calcsize_on_first || h!=starth) && h->m_wndproc) + { + RECT r,r2; + GetWindowContentViewRect(h,&r); + r2=r; + h->m_wndproc(h,WM_NCCALCSIZE,FALSE,(LPARAM)&r); + + // todo: handle left edges and adjust postions/etc accordingly + if (h==starth) // if initial window, adjust rects to client area (this implies calcsize_on_first being false) + { + wndw=r.right-r.left; + wndh=r.bottom-r.top; + } + yoffs += r.top-r2.top; + xoffs += r.left-r2.left; + } + if (h->m_backingstore) break; // found our target window + + xoffs += h->m_position.left; + yoffs += h->m_position.top; + h = h->m_parent; + } + if (!h) return NULL; + + swell_gdpLocalContext *p = (swell_gdpLocalContext*)SWELL_GDP_CTX_NEW(); + // todo: GDI defaults? + p->ctx.surface=new LICE_SubBitmap(h->m_backingstore,xoffs,yoffs,wndw,wndh); + if (xoffs<0) p->ctx.surface_offs.x = xoffs; + if (yoffs<0) p->ctx.surface_offs.y = yoffs; + p->clipr.left=xoffs; + p->clipr.top=yoffs; + p->clipr.right=xoffs + p->ctx.surface->getWidth(); + p->clipr.bottom=yoffs + p->ctx.surface->getHeight(); + + return (HDC)p; +} +HDC GetWindowDC(HWND h) +{ + return SWELL_internalGetWindowDC(h,0); +} + +HDC GetDC(HWND h) +{ + return SWELL_internalGetWindowDC(h,1); +} + +void ReleaseDC(HWND h, HDC hdc) +{ + if (!h || !HDC_VALID(hdc)) return; + swell_gdpLocalContext *p = (swell_gdpLocalContext*)hdc; + + + if (!h->m_paintctx) + { + // handle blitting? + HWND par = h; + while (par && !par->m_backingstore) par=par->m_parent; + void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect); + if (par) + { + if (p->ctx.dirty_rect_valid) + { + RECT r = p->clipr, dr=p->ctx.dirty_rect; + dr.left += r.left; + dr.top += r.top; + dr.right += r.left; + dr.bottom += r.top; +#if 1 + if (dr.left > r.left) r.left=dr.left; + if (dr.top > r.top) r.top=dr.top; + if (dr.right < r.right) r.right=dr.right; + if (dr.bottom < r.bottom) r.bottom=dr.bottom; +#endif + + if (r.topctx.surface; + SWELL_GDP_CTX_DELETE(hdc); +} + + + +HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) +{ + if (!ps) return 0; + memset(ps,0,sizeof(PAINTSTRUCT)); + if (!hwnd) return 0; + if (!hwnd->m_paintctx) return NULL; + + swell_gdpLocalContext *ctx = (swell_gdpLocalContext *)hwnd->m_paintctx; + ps->rcPaint = ctx->clipr; + ps->hdc = &ctx->ctx; + return &ctx->ctx; +} + + +// paint hwnd into bmout, where bmout points at bmout_xpos,bmout_ypos in window coordinates +void SWELL_internalLICEpaint(HWND hwnd, LICE_IBitmap *bmout, int bmout_xpos, int bmout_ypos, bool forceref) +{ + // todo: check to see if any children completely intersect clip region, if so then we don't need to render ourselves + // todo: opaque flag for windows? (to disable above behavior) + // todo: implement/use per-window backing store. + // we would want to only really use them for top level windows, and on those, only update windows (and children of windows) who had backingstore invalidated. + if (hwnd->m_invalidated) forceref=true; + + if (forceref || hwnd->m_child_invalidated) + { + swell_gdpLocalContext ctx={0,}; // todo set up gdi context defaults? + ctx.ctx.surface = bmout; + ctx.ctx.surface_offs.x = -bmout_xpos; + ctx.ctx.surface_offs.y = -bmout_ypos; + ctx.clipr.left = bmout_xpos; + ctx.clipr.top = bmout_ypos; + ctx.clipr.right = ctx.clipr.left + bmout->getWidth(); + ctx.clipr.bottom = ctx.clipr.top + bmout->getHeight(); + + void *oldpaintctx = hwnd->m_paintctx; + if (forceref) hwnd->m_paintctx = &ctx; + + LICE_SubBitmap tmpsub(NULL,0,0,0,0); + if (hwnd->m_wndproc) // this happens after m_paintctx is set -- that way GetWindowDC()/GetDC()/ReleaseDC() know to not actually update the screen + { + RECT r,r2; + GetWindowContentViewRect(hwnd,&r); + r.right-=r.left; r.bottom-=r.top; r.left=r.top=0; + r2=r; + hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&r); + if (forceref) hwnd->m_wndproc(hwnd,WM_NCPAINT,(WPARAM)1,0); + + if (r.left!=r2.left) {} // todo: adjust drawing offsets, clip rects, accordingly + if (r.top!=r2.top) {} // todo: adjust drawing offsets, clip rects, accordingly + int dx = r.left-r2.left,dy=r.top-r2.top; + // dx,dy is offset from the window's root of + bmout_xpos -= dx; + bmout_ypos -= dy; + + if (dx||dy) + { + tmpsub.m_parent = ctx.ctx.surface; + tmpsub.m_x = dx; + tmpsub.m_y = dy; + tmpsub.m_w = ctx.ctx.surface->getWidth()-dx; + tmpsub.m_h = ctx.ctx.surface->getHeight()-dy; + if (tmpsub.m_w<0) tmpsub.m_w=0; + if (tmpsub.m_h<0) tmpsub.m_h=0; + ctx.ctx.surface_offs.x += dx; + ctx.ctx.surface_offs.y += dy; + ctx.ctx.surface = &tmpsub; + + ctx.clipr.left-=dx; + ctx.clipr.top-=dy; + ctx.clipr.right-=dx; + ctx.clipr.bottom-=dy; + } + + // adjust clip rects for right/bottom extents + int newr = r.right-r.left; + if (ctx.clipr.right > newr) ctx.clipr.right=newr; + int newb = r.bottom-r.top; + if (ctx.clipr.bottom > newb) ctx.clipr.bottom=newb; + } + + // paint + if (forceref) + { + if (hwnd->m_wndproc && ctx.clipr.right > ctx.clipr.left && ctx.clipr.bottom > ctx.clipr.top) + { + hwnd->m_wndproc(hwnd,WM_PAINT,(WPARAM)&ctx,0); + } + + hwnd->m_paintctx = oldpaintctx; + + // it might be good to blit here on some OSes, rather than from the top level caller... + hwnd->m_invalidated=false; + } + } + + if (forceref || hwnd->m_child_invalidated) + { + HWND h = hwnd->m_children; + while (h && h->m_next) h=h->m_next; + while (h) // go through list backwards (first in list = top of Z order) + { + if (h->m_visible && (forceref || h->m_invalidated||h->m_child_invalidated)) + { + int width = h->m_position.right - h->m_position.left, height = h->m_position.bottom - h->m_position.top; // max width possible for this window + int xp = h->m_position.left - bmout_xpos, yp = h->m_position.top - bmout_ypos; + + // if xp/yp < 0, that means that the clip region starts inside the window, so we need to pass a positive render offset, and decrease the potential draw width + // if xp/yp > 0, then the clip region starts before the window, so we use the subbitmap and pass 0 for the offset parm + int subx = 0, suby=0; + if (xp<0) width+=xp; + else { subx=xp; xp=0; } + + if (yp<0) height+=yp; + else { suby=yp; yp=0; } + + LICE_SubBitmap subbm(bmout,subx,suby,width,height); // the right/bottom will automatically be clipped to the clip rect etc + if (subbm.getWidth()>0 && subbm.getHeight()>0) + SWELL_internalLICEpaint(h,&subbm,-xp,-yp,forceref); + } + h = h->m_prev; + } + } + hwnd->m_child_invalidated=false; +} + +HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) +{ + return NULL; +} + +HICON CreateIconIndirect(ICONINFO* iconinfo) +{ + if (!iconinfo || !iconinfo->fIcon) return 0; + HGDIOBJ__* i=iconinfo->hbmColor; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP) ) return 0; +/* + if (!i->bitmapptr) return 0; + HGDIOBJ__* icon=GDP_OBJECT_NEW(); + icon->type=TYPE_BITMAP; + icon->wid=1; + return icon; +*/ + return NULL; +} + +HIMAGELIST ImageList_CreateEx() +{ + return (HIMAGELIST)new WDL_PtrList; +} + +BOOL ImageList_Remove(HIMAGELIST list, int idx) +{ + WDL_PtrList* imglist=(WDL_PtrList*)list; + if (imglist && idx < imglist->GetSize()) + { + if (idx < 0) + { + int x,n=imglist->GetSize(); + for (x=0;xGet(x); + if (a) DeleteObject(a); + } + imglist->Empty(); + } + else + { + HGDIOBJ__ *a = imglist->Get(idx); + imglist->Set(idx, NULL); + if (a) DeleteObject(a); + } + return TRUE; + } + + return FALSE; +} + +void ImageList_Destroy(HIMAGELIST list) +{ + if (!list) return; + WDL_PtrList *p=(WDL_PtrList*)list; + ImageList_Remove(list,-1); + delete p; +} + +int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) +{ + if (!image || !list) return -1; + WDL_PtrList *l=(WDL_PtrList *)list; + + HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; + if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; + + HGDIOBJ__* icon=GDP_OBJECT_NEW(); + icon->type=TYPE_BITMAP; + icon->wid=1; + // todo: copy underlying image + + image = (HICON) icon; + + if (offset<0||offset>=l->GetSize()) + { + l->Add(image); + offset=l->GetSize()-1; + } + else + { + HICON old=l->Get(offset); + l->Set(offset,image); + if (old) DeleteObject(old); + } + return offset; +} + + + +#endif + +#endif // SWELL_LICE_GDI diff --git a/WDL/swell/swell-gdi.mm b/WDL/swell/swell-gdi.mm new file mode 100644 index 00000000..8ba5c863 --- /dev/null +++ b/WDL/swell/swell-gdi.mm @@ -0,0 +1,1530 @@ + +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic win32 GDI-->Quartz translation. It uses features that require OS X 10.4+ + +*/ + +#ifndef SWELL_PROVIDED_BY_APP + +#import +#import +#import +#import +#include "swell.h" +#include "swell-internal.h" + +#include "../mutex.h" + + +static bool IsCoreTextSupported() +{ +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + static char is105; + if (!is105) + { + SInt32 v=0x1040; + Gestalt(gestaltSystemVersion,&v); + is105 = v>=0x1050 ? 1 : -1; + } + + return is105 > 0 && CTFontCreateWithName && CTLineDraw && CTFramesetterCreateWithAttributedString && CTFramesetterCreateFrame && + CTFrameGetLines && CTLineGetTypographicBounds && CTLineCreateWithAttributedString; +#else + // targetting 10.5+, CT is always valid + return true; +#endif +} + +static CTFontRef GetCoreTextDefaultFont() +{ + static CTFontRef deffr; + static bool ok; + if (!ok) + { + ok=true; + if (IsCoreTextSupported()) + { + deffr=(CTFontRef) [[NSFont labelFontOfSize:10.0] retain]; + } + } + return deffr; +} + + +static NSString *CStringToNSString(const char *str) +{ + if (!str) str=""; + NSString *ret; + + ret=(NSString *)CFStringCreateWithCString(NULL,str,kCFStringEncodingUTF8); + if (ret) return ret; + ret=(NSString *)CFStringCreateWithCString(NULL,str,kCFStringEncodingASCII); + return ret; +} + + +static CGColorRef CreateColor(int col, float alpha=1.0f) +{ + static CGColorSpaceRef cspace; + + if (!cspace) cspace=CGColorSpaceCreateDeviceRGB(); + + CGFloat cols[4]={GetRValue(col)/255.0,GetGValue(col)/255.0,GetBValue(col)/255.0,alpha}; + CGColorRef color=CGColorCreate(cspace,cols); + return color; +} + + +#include "swell-gdi-internalpool.h" + + +HDC SWELL_CreateGfxContext(void *c) +{ + HDC__ *ctx=SWELL_GDP_CTX_NEW(); + NSGraphicsContext *nsc = (NSGraphicsContext *)c; +// if (![nsc isFlipped]) +// nsc = [NSGraphicsContext graphicsContextWithGraphicsPort:[nsc graphicsPort] flipped:YES]; + + ctx->ctx=(CGContextRef)[nsc graphicsPort]; +// CGAffineTransform f={1,0,0,-1,0,0}; + //CGContextSetTextMatrix(ctx->ctx,f); + //SetTextColor(ctx,0); + + // CGContextSelectFont(ctx->ctx,"Arial",12.0,kCGEncodingMacRoman); + return ctx; +} + +#define ALIGN_EXTRA 63 +static void *ALIGN_FBUF(void *inbuf) +{ + const UINT_PTR extra = ALIGN_EXTRA; + return (void *) (((UINT_PTR)inbuf+extra)&~extra); +} + +HDC SWELL_CreateMemContext(HDC hdc, int w, int h) +{ + void *buf=calloc(w*4*h+ALIGN_EXTRA,1); + if (!buf) return 0; + CGColorSpaceRef cs=CGColorSpaceCreateDeviceRGB(); + CGContextRef c=CGBitmapContextCreate(ALIGN_FBUF(buf),w,h,8,w*4,cs, kCGImageAlphaNoneSkipFirst); + CGColorSpaceRelease(cs); + if (!c) + { + free(buf); + return 0; + } + + + CGContextTranslateCTM(c,0.0,h); + CGContextScaleCTM(c,1.0,-1.0); + + + HDC__ *ctx=SWELL_GDP_CTX_NEW(); + ctx->ctx=(CGContextRef)c; + ctx->ownedData=buf; + // CGContextSelectFont(ctx->ctx,"Arial",12.0,kCGEncodingMacRoman); + + SetTextColor(ctx,0); + return ctx; +} + +void SWELL_DeleteGfxContext(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)) + { + if (ct->ownedData) + { + CGContextRelease(ct->ctx); + free(ct->ownedData); + } + if (ct->curtextcol) CFRelease(ct->curtextcol); + SWELL_GDP_CTX_DELETE(ct); + } +} +HPEN CreatePen(int attr, int wid, int col) +{ + return CreatePenAlpha(attr,wid,col,1.0f); +} + +HBRUSH CreateSolidBrush(int col) +{ + return CreateSolidBrushAlpha(col,1.0f); +} + + + +HPEN CreatePenAlpha(int attr, int wid, int col, float alpha) +{ + HGDIOBJ__ *pen=GDP_OBJECT_NEW(); + pen->type=TYPE_PEN; + pen->wid=wid<0?0:wid; + pen->color=CreateColor(col,alpha); + return pen; +} +HBRUSH CreateSolidBrushAlpha(int col, float alpha) +{ + HGDIOBJ__ *brush=GDP_OBJECT_NEW(); + brush->type=TYPE_BRUSH; + brush->color=CreateColor(col,alpha); + brush->wid=0; + return brush; +} + + +HFONT CreateFontIndirect(LOGFONT *lf) +{ + return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic, + lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision, + lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName); +} + +static HGDIOBJ__ global_objs[2]; + +void DeleteObject(HGDIOBJ pen) +{ + HGDIOBJ__ *p=(HGDIOBJ__ *)pen; + if (p >= global_objs && p < global_objs + sizeof(global_objs)/sizeof(global_objs[0])) return; + + if (HGDIOBJ_VALID(p)) + { + if (--p->additional_refcnt < 0) + { + if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP) + { + if (p->type == TYPE_PEN || p->type == TYPE_BRUSH) + if (p->wid<0) return; + if (p->color) CGColorRelease(p->color); + + if (p->ct_FontRef) CFRelease(p->ct_FontRef); + +#ifdef SWELL_ATSUI_TEXT_SUPPORT + if (p->atsui_font_style) ATSUDisposeStyle(p->atsui_font_style); +#endif + + if (p->wid && p->bitmapptr) [p->bitmapptr release]; + GDP_OBJECT_DELETE(p); + } + // JF> don't free unknown objects, this shouldn't ever happen anyway: else free(p); + } + } +} + + +HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *p=(HGDIOBJ__*) pen; + HGDIOBJ__ **mod=0; + if (!HDC_VALID(c)) return 0; + + if (p == (HGDIOBJ__*)TYPE_PEN) mod=&c->curpen; + else if (p == (HGDIOBJ__*)TYPE_BRUSH) mod=&c->curbrush; + else if (p == (HGDIOBJ__*)TYPE_FONT) mod=&c->curfont; + + if (mod) // clearing a particular thing + { + HGDIOBJ__ *np=*mod; + *mod=0; + return HGDIOBJ_VALID(np,(int)(INT_PTR)p)?np:p; + } + + if (!HGDIOBJ_VALID(p)) return 0; + + if (p->type == TYPE_PEN) mod=&c->curpen; + else if (p->type == TYPE_BRUSH) mod=&c->curbrush; + else if (p->type == TYPE_FONT) mod=&c->curfont; + + if (!mod) return 0; + + HGDIOBJ__ *op=*mod; + if (!HGDIOBJ_VALID(op,p->type)) op=(HGDIOBJ__*)p->type; + if (op != p) *mod=p; + return op; +} + + + +void SWELL_FillRect(HDC ctx, RECT *r, HBRUSH br) +{ + HDC__ *c=(HDC__ *)ctx; + HGDIOBJ__ *b=(HGDIOBJ__*) br; + if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH) || b == (HGDIOBJ__*)TYPE_BRUSH || b->type != TYPE_BRUSH) return; + + if (b->wid<0) return; + + CGRect rect=CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top); + CGContextSetFillColorWithColor(c->ctx,b->color); + CGContextFillRect(c->ctx,rect); + +} + +void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd) +{ + xrnd/=3; + yrnd/=3; + POINT pts[10]={ // todo: curves between edges + {x,y+yrnd}, + {x+xrnd,y}, + {x2-xrnd,y}, + {x2,y+yrnd}, + {x2,y2-yrnd}, + {x2-xrnd,y2}, + {x+xrnd,y2}, + {x,y2-yrnd}, + {x,y+yrnd}, + {x+xrnd,y}, +}; + + WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0])); +} + +void Ellipse(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + CGRect rect=CGRectMake(l,t,r-l,b-t); + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0) + { + CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); + CGContextFillEllipseInRect(c->ctx,rect); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + CGContextStrokeEllipseInRect(c->ctx, rect); //, (float)max(1,c->curpen->wid)); + } +} + +void Rectangle(HDC ctx, int l, int t, int r, int b) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + + CGRect rect=CGRectMake(l,t,r-l,b-t); + + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); + CGContextFillRect(c->ctx,rect); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0) + { + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + CGContextStrokeRectWithWidth(c->ctx, rect, (float)max(1,c->curpen->wid)); + } +} + + +HGDIOBJ GetStockObject(int wh) +{ + switch (wh) + { + case NULL_BRUSH: + { + HGDIOBJ__ *p = &global_objs[0]; + p->type=TYPE_BRUSH; + p->wid=-1; + return p; + } + case NULL_PEN: + { + HGDIOBJ__ *p = &global_objs[1]; + p->type=TYPE_PEN; + p->wid=-1; + return p; + } + } + return 0; +} + +void Polygon(HDC ctx, POINT *pts, int npts) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) && (!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return; + + CGContextBeginPath(c->ctx); + CGContextMoveToPoint(c->ctx,(float)pts[0].x,(float)pts[0].y); + int x; + for (x = 1; x < npts; x ++) + { + CGContextAddLineToPoint(c->ctx,(float)pts[x].x,(float)pts[x].y); + } + if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0) + { + CGContextSetFillColorWithColor(c->ctx,c->curbrush->color); + } + if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0) + { + CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + } + CGContextDrawPath(c->ctx,HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0 && HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid>=0 ? kCGPathFillStroke : HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid>=0 ? kCGPathStroke : kCGPathFill); +} + +void MoveToEx(HDC ctx, int x, int y, POINT *op) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)) return; + if (op) + { + op->x = (int) (c->lastpos_x); + op->y = (int) (c->lastpos_y); + } + c->lastpos_x=(float)x; + c->lastpos_y=(float)y; +} + +void PolyBezierTo(HDC ctx, POINT *pts, int np) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return; + + CGContextSetLineWidth(c->ctx,(float)max(c->curpen->wid,1)); + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + + CGContextBeginPath(c->ctx); + CGContextMoveToPoint(c->ctx,c->lastpos_x,c->lastpos_y); + int x; + float xp,yp; + for (x = 0; x < np-2; x += 3) + { + CGContextAddCurveToPoint(c->ctx, + (float)pts[x].x,(float)pts[x].y, + (float)pts[x+1].x,(float)pts[x+1].y, + xp=(float)pts[x+2].x,yp=(float)pts[x+2].y); + } + c->lastpos_x=(float)xp; + c->lastpos_y=(float)yp; + CGContextStrokePath(c->ctx); +} + + +void SWELL_LineTo(HDC ctx, int x, int y) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return; + + float w = (float)max(c->curpen->wid,1); + CGContextSetLineWidth(c->ctx,w); + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + + CGContextBeginPath(c->ctx); + CGContextMoveToPoint(c->ctx,c->lastpos_x + w * 0.5,c->lastpos_y + w*0.5); + float fx=(float)x,fy=(float)y; + + CGContextAddLineToPoint(c->ctx,fx+w*0.5,fy+w*0.5); + c->lastpos_x=fx; + c->lastpos_y=fy; + CGContextStrokePath(c->ctx); +} + +void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg) +{ + HDC__ *c=(HDC__ *)ctx; + if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return; + + float w = (float)max(c->curpen->wid,1); + CGContextSetLineWidth(c->ctx,w); + CGContextSetStrokeColorWithColor(c->ctx,c->curpen->color); + + CGContextBeginPath(c->ctx); + + while (nseg-->0) + { + DWORD cnt=*cnts++; + if (!cnt) continue; + if (!--cnt) { pts++; continue; } + + CGContextMoveToPoint(c->ctx,(float)pts->x+w*0.5,(float)pts->y+w*0.5); + pts++; + + while (cnt--) + { + CGContextAddLineToPoint(c->ctx,(float)pts->x+w*0.5,(float)pts->y+w*0.5); + pts++; + } + } + CGContextStrokePath(c->ctx); +} +void *SWELL_GetCtxGC(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return 0; + return ct->ctx; +} + + +void SWELL_SetPixel(HDC ctx, int x, int y, int c) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + CGContextBeginPath(ct->ctx); + CGContextMoveToPoint(ct->ctx,(float)x-0.5,(float)y-0.5); + CGContextAddLineToPoint(ct->ctx,(float)x+0.5,(float)y+0.5); + CGContextSetLineWidth(ct->ctx,(float)1.0); + CGContextSetRGBStrokeColor(ct->ctx,GetRValue(c)/255.0,GetGValue(c)/255.0,GetBValue(c)/255.0,1.0); + CGContextStrokePath(ct->ctx); +} + + +HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, + char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, + char lfQuality, char lfPitchAndFamily, const char *lfFaceName) +{ + HGDIOBJ__ *font=GDP_OBJECT_NEW(); + font->type=TYPE_FONT; + float fontwid=lfHeight; + + if (!fontwid) fontwid=lfWidth; + if (fontwid<0)fontwid=-fontwid; + + if (fontwid < 2 || fontwid > 8192) fontwid=10; + + font->font_rotation = lfOrientation/10.0; + + if (IsCoreTextSupported()) + { + char buf[1024]; + lstrcpyn(buf,lfFaceName,900); + if (lfWeight >= FW_BOLD) strcat(buf," Bold"); + if (lfItalic) strcat(buf," Italic"); + + NSString *str=CStringToNSString(buf); + font->ct_FontRef = (void*)CTFontCreateWithName((CFStringRef)str,fontwid,NULL); + [str release]; + if (!font->ct_FontRef) font->ct_FontRef = (void*)[[NSFont labelFontOfSize:fontwid] retain]; + + // might want to make this conditional (i.e. only return font if created successfully), but I think we'd rather fallback to a system font than use ATSUI + return font; + } + +#ifdef SWELL_ATSUI_TEXT_SUPPORT + ATSUFontID fontid=kATSUInvalidFontID; + if (lfFaceName && lfFaceName[0]) + { + ATSUFindFontFromName(lfFaceName,strlen(lfFaceName),kFontFullName /* kFontFamilyName? */ ,(FontPlatformCode)kFontNoPlatform,kFontNoScriptCode,kFontNoLanguageCode,&fontid); + // if (fontid==kATSUInvalidFontID) printf("looked up %s and got %d\n",lfFaceName,fontid); + } + + if (ATSUCreateStyle(&font->atsui_font_style) == noErr && font->atsui_font_style) + { + Fixed fsize=Long2Fix(fontwid); + + Boolean isBold=lfWeight >= FW_BOLD; + Boolean isItal=!!lfItalic; + Boolean isUnder=!!lfUnderline; + + ATSUAttributeTag theTags[] = { kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag,kATSUSizeTag,kATSUFontTag }; + ByteCount theSizes[] = { sizeof(Boolean),sizeof(Boolean),sizeof(Boolean), sizeof(Fixed),sizeof(ATSUFontID) }; + ATSUAttributeValuePtr theValues[] = {&isBold, &isItal, &isUnder, &fsize, &fontid } ; + + int attrcnt=sizeof(theTags)/sizeof(theTags[0]); + if (fontid == kATSUInvalidFontID) attrcnt--; + + if (ATSUSetAttributes (font->atsui_font_style, + attrcnt, + theTags, + theSizes, + theValues)!=noErr) + { + ATSUDisposeStyle(font->atsui_font_style); + font->atsui_font_style=0; + } + } + else + font->atsui_font_style=0; + +#endif + + + return font; +} + + + +BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm) +{ + + HDC__ *ct=(HDC__ *)ctx; + if (tm) // give some sane defaults + { + tm->tmInternalLeading=3; + tm->tmAscent=12; + tm->tmDescent=4; + tm->tmHeight=16; + tm->tmAveCharWidth = 10; + } + if (!HDC_VALID(ct)||!tm) return 0; + + bool curfont_valid=HGDIOBJ_VALID(ct->curfont,TYPE_FONT); + +#ifdef SWELL_ATSUI_TEXT_SUPPORT + if (curfont_valid && ct->curfont->atsui_font_style) + { + ATSUTextMeasurement ascent=Long2Fix(10); + ATSUTextMeasurement descent=Long2Fix(3); + ATSUTextMeasurement sz=Long2Fix(0); + ATSUTextMeasurement width =Long2Fix(12); + ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUAscentTag, sizeof(ATSUTextMeasurement), &ascent,NULL); + ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUDescentTag, sizeof(ATSUTextMeasurement), &descent,NULL); + ATSUGetAttribute(ct->curfont->atsui_font_style, kATSUSizeTag, sizeof(ATSUTextMeasurement), &sz,NULL); + ATSUGetAttribute(ct->curfont->atsui_font_style, kATSULineWidthTag, sizeof(ATSUTextMeasurement),&width,NULL); + + float asc=Fix2X(ascent); + float desc=Fix2X(descent); + float size = Fix2X(sz); + + if (size < (asc+desc)*0.2) size=asc+desc; + + tm->tmAscent = (int)ceil(asc); + tm->tmDescent = (int)ceil(desc); + tm->tmInternalLeading=(int)ceil(asc+desc-size); + if (tm->tmInternalLeading<0)tm->tmInternalLeading=0; + tm->tmHeight=(int) ceil(asc+desc); + tm->tmAveCharWidth = (int) (ceil(asc+desc)*0.65); // (int)ceil(Fix2X(width)); + + return 1; + } +#endif + + CTFontRef fr = curfont_valid ? (CTFontRef)ct->curfont->ct_FontRef : NULL; + if (!fr) fr=GetCoreTextDefaultFont(); + + if (fr) + { + tm->tmInternalLeading = CTFontGetLeading(fr); + tm->tmAscent = CTFontGetAscent(fr); + tm->tmDescent = CTFontGetDescent(fr); + tm->tmHeight = (tm->tmInternalLeading + tm->tmAscent + tm->tmDescent); + tm->tmAveCharWidth = tm->tmHeight*2/3; // todo + + if (tm->tmHeight) tm->tmHeight++; + + return 1; + } + + + return 1; +} + + + +#ifdef SWELL_ATSUI_TEXT_SUPPORT + +static int DrawTextATSUI(HDC ctx, CFStringRef strin, RECT *r, int align, bool *err) +{ + HDC__ *ct=(HDC__ *)ctx; + HGDIOBJ__ *font=ct->curfont; // caller must specify a valid font + + UniChar strbuf[4096]; + int strbuf_len; + + { + strbuf[0]=0; + CFRange r = {0,CFStringGetLength(strin)}; + if (r.length > 4095) r.length=4095; + strbuf_len=CFStringGetBytes(strin,r,kCFStringEncodingUTF16,' ',false,(UInt8*)strbuf,sizeof(strbuf)-2,NULL); + if (strbuf_len<0)strbuf_len=0; + else if (strbuf_len>4095) strbuf_len=4095; + strbuf[strbuf_len]=0; + } + + { + RGBColor tcolor={GetRValue(ct->cur_text_color_int)*256,GetGValue(ct->cur_text_color_int)*256,GetBValue(ct->cur_text_color_int)*256}; + ATSUAttributeTag theTags[] = { kATSUColorTag, }; + ByteCount theSizes[] = { sizeof(RGBColor), }; + ATSUAttributeValuePtr theValues[] = {&tcolor, } ; + + // error check this? we can live with the wrong color maybe? + ATSUSetAttributes(font->atsui_font_style, sizeof(theTags)/sizeof(theTags[0]), theTags, theSizes, theValues); + } + + UniCharCount runLengths[1]={kATSUToTextEnd}; + ATSUTextLayout layout; + if (ATSUCreateTextLayoutWithTextPtr(strbuf, kATSUFromTextBeginning, kATSUToTextEnd, strbuf_len, 1, runLengths, &font->atsui_font_style, &layout)!=noErr) + { + *err=true; + return 0; + } + + { + Fixed frot = X2Fix(font->font_rotation); + + ATSULineTruncation tv = (align & DT_END_ELLIPSIS) ? kATSUTruncateEnd : kATSUTruncateNone; + ATSUAttributeTag theTags[] = { kATSUCGContextTag, kATSULineTruncationTag, kATSULineRotationTag }; + ByteCount theSizes[] = { sizeof (CGContextRef), sizeof(ATSULineTruncation), sizeof(Fixed)}; + ATSUAttributeValuePtr theValues[] = { &ct->ctx, &tv, &frot } ; + + + if (ATSUSetLayoutControls (layout, + + sizeof(theTags)/sizeof(theTags[0]), + + theTags, + + theSizes, + + theValues)!=noErr) + { + *err=true; + ATSUDisposeTextLayout(layout); + return 0; + } + } + + + ATSUTextMeasurement leftFixed, rightFixed, ascentFixed, descentFixed; + + if (ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, kATSUToTextEnd, &leftFixed, &rightFixed, &ascentFixed, &descentFixed)!=noErr) + { + *err=true; + ATSUDisposeTextLayout(layout); + return 0; + } + + int w=Fix2Long(rightFixed); + int descent=Fix2Long(descentFixed); + int h=descent + Fix2Long(ascentFixed); + if (align&DT_CALCRECT) + { + ATSUDisposeTextLayout(layout); + r->right=r->left+w; + r->bottom=r->top+h; + return h; + } + CGContextSaveGState(ct->ctx); + + if (!(align & DT_NOCLIP)) + CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); + + int l=r->left, t=r->top; + + if (fabs(font->font_rotation)<45.0) + { + if (align & DT_RIGHT) l = r->right-w; + else if (align & DT_CENTER) l = (r->right+r->left)/2 - w/2; + } + else l+=Fix2Long(ascentFixed); // 90 degree special case (we should generalize this to be correct throughout the rotation range, but oh well) + + if (align & DT_BOTTOM) t = r->bottom-h; + else if (align & DT_VCENTER) t = (r->bottom+r->top)/2 - h/2; + + CGContextTranslateCTM(ct->ctx,0,t); + CGContextScaleCTM(ct->ctx,1,-1); + CGContextTranslateCTM(ct->ctx,0,-t-h); + + if (ct->curbkmode == OPAQUE) + { + CGRect bgr = CGRectMake(l, t, w, h); + static CGColorSpaceRef csr; + if (!csr) csr = CGColorSpaceCreateDeviceRGB(); + float col[] = { (float)GetRValue(ct->curbkcol)/255.0f, (float)GetGValue(ct->curbkcol)/255.0f, (float)GetBValue(ct->curbkcol)/255.0f, 1.0f }; + CGColorRef bgc = CGColorCreate(csr, col); + CGContextSetFillColorWithColor(ct->ctx, bgc); + CGContextFillRect(ct->ctx, bgr); + CGColorRelease(bgc); + } + + if (ATSUDrawText(layout,kATSUFromTextBeginning,kATSUToTextEnd,Long2Fix(l),Long2Fix(t+descent))!=noErr) + *err=true; + + CGContextRestoreGState(ct->ctx); + + ATSUDisposeTextLayout(layout); + + return h; +} + +#endif + +int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return 0; + + bool has_ml=false; + char tmp[4096]; + const char *p=buf; + char *op=tmp; + while (*p && (op-tmp)curfont,TYPE_FONT); +#ifdef SWELL_ATSUI_TEXT_SUPPORT + if (curfont_valid && ct->curfont->atsui_font_style) + { + bool err=false; + int ret = DrawTextATSUI(ctx,(CFStringRef)str,r,align,&err); + [str release]; + + if (!err) return ret; + return 0; + } +#endif + + CTFontRef fr = curfont_valid ? (CTFontRef)ct->curfont->ct_FontRef : NULL; + if (!fr) fr=GetCoreTextDefaultFont(); + if (fr) + { + // Initialize string, font, and context + CFStringRef keys[] = { kCTFontAttributeName,kCTForegroundColorAttributeName }; + CFTypeRef values[] = { fr,ct->curtextcol }; + + int nk= sizeof(keys) / sizeof(keys[0]); + if (!values[1]) nk--; + + CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, nk, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFAttributedStringRef attrString = + CFAttributedStringCreate(kCFAllocatorDefault, (CFStringRef)str, attributes); + CFRelease(attributes); + [str release]; + + + CTFrameRef frame = NULL; + CFArrayRef lines = NULL; + CTLineRef line = NULL; + CGFloat asc=0; + int line_w=0,line_h=0; + if (has_ml) + { + CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString); + if (framesetter) + { + CGMutablePathRef path=CGPathCreateMutable(); + CGPathAddRect(path,NULL,CGRectMake(0,0,100000,100000)); + frame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL); + CFRelease(framesetter); + CFRelease(path); + } + if (frame) + { + lines = CTFrameGetLines(frame); + int n=CFArrayGetCount(lines); + int x; + for(x=0;xright = r->left+line_w; + r->bottom = r->top+line_h; + if (line) CFRelease(line); + if (frame) CFRelease(frame); + return line_h; + } + + float xo=r->left,yo=r->top; + if (align & DT_RIGHT) xo += (r->right-r->left) - line_w; + else if (align & DT_CENTER) xo += (r->right-r->left)/2 - line_w/2; + + if (align & DT_BOTTOM) yo += (r->bottom-r->top) - line_h; + else if (align & DT_VCENTER) yo += (r->bottom-r->top)/2 - line_h/2; + + + CGContextSaveGState(ct->ctx); + + CGAffineTransform f={1,0,0,-1,0,0}; + CGContextSetTextMatrix(ct->ctx, f); + + if (!(align & DT_NOCLIP)) + { + CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); + } + + CGColorRef bgc = NULL; + if (ct->curbkmode == OPAQUE) + { + CGColorSpaceRef csr = CGColorSpaceCreateDeviceRGB(); + CGFloat col[] = { (float)GetRValue(ct->curbkcol)/255.0f, (float)GetGValue(ct->curbkcol)/255.0f, (float)GetBValue(ct->curbkcol)/255.0f, 1.0f }; + bgc = CGColorCreate(csr, col); + CGColorSpaceRelease(csr); + } + + if (line) + { + if (bgc) + { + CGContextSetFillColorWithColor(ct->ctx, bgc); + CGContextFillRect(ct->ctx, CGRectMake(xo,yo,line_w,line_h)); + } + CGContextSetTextPosition(ct->ctx, xo, yo + asc); + CTLineDraw(line,ct->ctx); + + } + if (lines) + { + int n=CFArrayGetCount(lines); + int x; + for(x=0;xctx, bgc); + CGContextFillRect(ct->ctx, CGRectMake(xo,yo,lw,asc+desc+lead)); + } + CGContextSetTextPosition(ct->ctx, xo, yo + asc); + CTLineDraw(l,ct->ctx); + + yo += floor(asc+desc+lead+0.5); + } + } + + } + + CGContextRestoreGState(ct->ctx); + if (bgc) CGColorRelease(bgc); + if (line) CFRelease(line); + if (frame) CFRelease(frame); + + return line_h; + } + + + [str release]; + return 0; +} + + + + + + +void SetBkColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkcol=col; +} + +void SetBkMode(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->curbkmode=col; +} + +int GetTextColor(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return -1; + return ct->cur_text_color_int; +} + +void SetTextColor(HDC ctx, int col) +{ + HDC__ *ct=(HDC__ *)ctx; + if (!HDC_VALID(ct)) return; + ct->cur_text_color_int = col; + + if (ct->curtextcol) CFRelease(ct->curtextcol); + + static CGColorSpaceRef csr; + if (!csr) csr = CGColorSpaceCreateDeviceRGB(); + CGFloat ccol[] = { GetRValue(col)/255.0f,GetGValue(col)/255.0f,GetBValue(col)/255.0f,1.0 }; + ct->curtextcol = csr ? CGColorCreate(csr, ccol) : NULL; +} + + +HICON CreateIconIndirect(ICONINFO* iconinfo) +{ + if (!iconinfo || !iconinfo->fIcon) return 0; + HGDIOBJ__* i=iconinfo->hbmColor; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP) || !i->bitmapptr) return 0; + NSImage* img=i->bitmapptr; + if (!img) return 0; + + HGDIOBJ__* icon=GDP_OBJECT_NEW(); + icon->type=TYPE_BITMAP; + icon->wid=1; + [img retain]; + icon->bitmapptr=img; + return icon; +} + +HICON LoadNamedImage(const char *name, bool alphaFromMask) +{ + int needfree=0; + NSImage *img=0; + NSString *str=CStringToNSString(name); + if (strstr(name,"/")) + { + img=[[NSImage alloc] initWithContentsOfFile:str]; + if (img) needfree=1; + } + if (!img) img=[NSImage imageNamed:str]; + [str release]; + if (!img) + { + return 0; + } + + if (alphaFromMask) + { + NSSize sz=[img size]; + NSImage *newImage=[[NSImage alloc] initWithSize:sz]; + [newImage lockFocus]; + + [img setFlipped:YES]; + [img drawInRect:NSMakeRect(0,0,sz.width,sz.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; + int y; + CGContextRef myContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + for (y=0; y< sz.height; y ++) + { + int x; + for (x = 0; x < sz.width; x ++) + { + NSColor *col=NSReadPixel(NSMakePoint(x,y)); + if (col && [col numberOfComponents]<=4) + { + CGFloat comp[4]; + [col getComponents:comp]; // this relies on the format being RGB + if (comp[0] == 1.0 && comp[1] == 0.0 && comp[2] == 1.0 && comp[3]==1.0) + //fabs(comp[0]-1.0) < 0.0001 && fabs(comp[1]-.0) < 0.0001 && fabs(comp[2]-1.0) < 0.0001) + { + CGContextClearRect(myContext,CGRectMake(x,y,1,1)); + } + } + } + } + [newImage unlockFocus]; + + if (needfree) [img release]; + needfree=1; + img=newImage; + } + + HGDIOBJ__ *i=GDP_OBJECT_NEW(); + i->type=TYPE_BITMAP; + i->wid=needfree; + i->bitmapptr = img; + return i; +} + +void DrawImageInRect(HDC ctx, HICON img, RECT *r) +{ + HGDIOBJ__ *i = (HGDIOBJ__ *)img; + HDC__ *ct=(HDC__*)ctx; + if (!HDC_VALID(ct) || !HGDIOBJ_VALID(i,TYPE_BITMAP) || !i->bitmapptr) return; + //CGContextDrawImage(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top),(CGImage*)i->bitmapptr); + // probably a better way since this ignores the ctx + [NSGraphicsContext saveGraphicsState]; + NSGraphicsContext *gc=[NSGraphicsContext graphicsContextWithGraphicsPort:ct->ctx flipped:NO]; + [NSGraphicsContext setCurrentContext:gc]; + NSImage *nsi=i->bitmapptr; + NSRect rr=NSMakeRect(r->left,r->top,r->right-r->left,r->bottom-r->top); + [nsi setFlipped:YES]; + [nsi drawInRect:rr fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; + [nsi setFlipped:NO]; + [NSGraphicsContext restoreGraphicsState]; +// [gc release]; +} + + +BOOL GetObject(HICON icon, int bmsz, void *_bm) +{ + memset(_bm,0,bmsz); + if (bmsz != sizeof(BITMAP)) return false; + BITMAP *bm=(BITMAP *)_bm; + HGDIOBJ__ *i = (HGDIOBJ__ *)icon; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false; + NSImage *img = i->bitmapptr; + if (!img) return false; + bm->bmWidth = (int) ([img size].width+0.5); + bm->bmHeight = (int) ([img size].height+0.5); + return true; +} + + +void *GetNSImageFromHICON(HICON ico) +{ + HGDIOBJ__ *i = (HGDIOBJ__ *)ico; + if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return 0; + return i->bitmapptr; +} + +#if 0 +static int ColorFromNSColor(NSColor *color, int valifnul) +{ + if (!color) return valifnul; + float r,g,b; + NSColor *color2=[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + if (!color2) + { + NSLog(@"error converting colorspace from: %@\n",[color colorSpaceName]); + return valifnul; + } + + [color2 getRed:&r green:&g blue:&b alpha:NULL]; + return RGB((int)(r*255.0),(int)(g*255.0),(int)(b*255.0)); +} +#else +#define ColorFromNSColor(a,b) (b) +#endif +int GetSysColor(int idx) +{ + // NSColors that seem to be valid: textBackgroundColor, selectedTextBackgroundColor, textColor, selectedTextColor + + switch (idx) + { + case COLOR_WINDOW: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_3DFACE: + case COLOR_BTNFACE: return ColorFromNSColor([NSColor controlColor],RGB(192,192,192)); + case COLOR_SCROLLBAR: return ColorFromNSColor([NSColor controlColor],RGB(32,32,32)); + case COLOR_3DSHADOW: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96)); + case COLOR_3DHILIGHT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(224,224,224)); + case COLOR_BTNTEXT: return ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(0,0,0)); + case COLOR_3DDKSHADOW: return (ColorFromNSColor([NSColor selectedTextBackgroundColor],RGB(96,96,96))>>1)&0x7f7f7f; + case COLOR_INFOBK: return RGB(255,240,200); + case COLOR_INFOTEXT: return RGB(0,0,0); + + } + return 0; +} + + +void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode) +{ + StretchBlt(hdcOut,x,y,w,h,hdcIn,xin,yin,w,h,mode); +} + +void StretchBlt(HDC hdcOut, int x, int y, int destw, int desth, HDC hdcIn, int xin, int yin, int w, int h, int mode) +{ + if (!hdcOut || !hdcIn||w<1||h<1) return; + HDC__ *src=(HDC__*)hdcIn; + HDC__ *dest=(HDC__*)hdcOut; + if (!HDC_VALID(src) || !HDC_VALID(dest) || !src->ownedData || !src->ctx || !dest->ctx) return; + + if (w<1||h<1) return; + + int sw= CGBitmapContextGetWidth(src->ctx); + int sh= CGBitmapContextGetHeight(src->ctx); + + int preclip_w=w; + int preclip_h=h; + + if (xin<0) + { + x-=(xin*destw)/w; + w+=xin; + xin=0; + } + if (yin<0) + { + y-=(yin*desth)/h; + h+=yin; + yin=0; + } + if (xin+w > sw) w=sw-xin; + if (yin+h > sh) h=sh-yin; + + if (w<1||h<1) return; + + if (destw==preclip_w) destw=w; // no scaling, keep width the same + else if (w != preclip_w) destw = (w*destw)/preclip_w; + + if (desth == preclip_h) desth=h; + else if (h != preclip_h) desth = (h*desth)/preclip_h; + + CGImageRef img = NULL, subimg = NULL; + NSBitmapImageRep *rep = NULL; + + static char is105; + if (!is105) + { + SInt32 v=0x1040; + Gestalt(gestaltSystemVersion,&v); + is105 = v>=0x1050 ? 1 : -1; + } + + bool want_subimage=false; + + bool use_alphachannel = mode == SRCCOPY_USEALPHACHAN; + + if (is105>0) + { + // [NSBitmapImageRep CGImage] is not available pre-10.5 + unsigned char *p = (unsigned char *)ALIGN_FBUF(src->ownedData); + p += (xin + sw*yin)*4; + rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&p pixelsWide:w pixelsHigh:h + bitsPerSample:8 samplesPerPixel:(3+use_alphachannel) hasAlpha:use_alphachannel isPlanar:FALSE + colorSpaceName:NSDeviceRGBColorSpace bitmapFormat:(NSBitmapFormat)((use_alphachannel ? NSAlphaNonpremultipliedBitmapFormat : 0) |NSAlphaFirstBitmapFormat) bytesPerRow:sw*4 bitsPerPixel:32]; + img=(CGImageRef)objc_msgSend(rep,@selector(CGImage)); + if (img) CGImageRetain(img); + } + else + { + if (1) // this seems to be WAY better on 10.4 than the alternative (below) + { + static CGColorSpaceRef cs; + if (!cs) cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + unsigned char *p = (unsigned char *)ALIGN_FBUF(src->ownedData); + p += (xin + sw*yin)*4; + + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,p,4*sw*h,NULL); + img = CGImageCreate(w,h,8,32,4*sw,cs,use_alphachannel?kCGImageAlphaFirst:kCGImageAlphaNoneSkipFirst,provider,NULL,NO,kCGRenderingIntentDefault); + // CGColorSpaceRelease(cs); + CGDataProviderRelease(provider); + } + else + { + // causes lots of kernel messages, so avoid if possible, also doesnt support alpha bleh + img = CGBitmapContextCreateImage(src->ctx); + want_subimage = true; + } + } + + if (!img) return; + + if (want_subimage && (w != sw || h != sh)) + { + subimg = CGImageCreateWithImageInRect(img,CGRectMake(xin,yin,w,h)); + if (!subimg) + { + CGImageRelease(img); + return; + } + } + + CGContextRef output = (CGContextRef)dest->ctx; + + + CGContextSaveGState(output); + CGContextScaleCTM(output,1.0,-1.0); + CGContextDrawImage(output,CGRectMake(x,-desth-y,destw,desth),subimg ? subimg : img); + CGContextRestoreGState(output); + + if (subimg) CGImageRelease(subimg); + CGImageRelease(img); + if (rep) [rep release]; + +} + +void SWELL_PushClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct) && ct->ctx) CGContextSaveGState(ct->ctx); +} + +void SWELL_SetClipRegion(HDC ctx, RECT *r) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct) && ct->ctx) CGContextClipToRect(ct->ctx,CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top)); + +} + +void SWELL_PopClipRegion(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct) && ct->ctx) CGContextRestoreGState(ct->ctx); +} + +void *SWELL_GetCtxFrameBuffer(HDC ctx) +{ + HDC__ *ct=(HDC__ *)ctx; + if (HDC_VALID(ct)) return ALIGN_FBUF(ct->ownedData); + return 0; +} + + +HDC GetDC(HWND h) +{ + if (h && [(id)h isKindOfClass:[NSWindow class]]) + { + if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) + { + PAINTSTRUCT ps={0,}; + [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; + if (ps.hdc) + { + if ((ps.hdc)->ctx) CGContextSaveGState((ps.hdc)->ctx); + return ps.hdc; + } + } + h=(HWND)[(id)h contentView]; + } + + if (h && [(id)h isKindOfClass:[NSView class]]) + { + if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) + { + PAINTSTRUCT ps={0,}; + [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; + if (HDC_VALID((HDC__*)ps.hdc)) + { + if (((HDC__*)ps.hdc)->ctx) CGContextSaveGState((ps.hdc)->ctx); + return ps.hdc; + } + } + + if ([(NSView*)h lockFocusIfCanDraw]) + { + HDC ret= SWELL_CreateGfxContext([NSGraphicsContext currentContext]); + if (ret) + { + if ((ret)->ctx) CGContextSaveGState((ret)->ctx); + } + return ret; + } + } + return 0; +} + +HDC GetWindowDC(HWND h) +{ + HDC ret=GetDC(h); + if (ret) + { + NSView *v=NULL; + if ([(id)h isKindOfClass:[NSWindow class]]) v=[(id)h contentView]; + else if ([(id)h isKindOfClass:[NSView class]]) v=(NSView *)h; + + if (v) + { + NSRect b=[v bounds]; + float xsc=b.origin.x; + float ysc=b.origin.y; + if ((xsc || ysc) && (ret)->ctx) CGContextTranslateCTM((ret)->ctx,xsc,ysc); + } + } + return ret; +} + +void ReleaseDC(HWND h, HDC hdc) +{ + if (hdc) + { + if ((hdc)->ctx) CGContextRestoreGState((hdc)->ctx); + } + if (h && [(id)h isKindOfClass:[NSWindow class]]) + { + if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) + { + PAINTSTRUCT ps={0,}; + [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; + if (ps.hdc && ps.hdc==hdc) return; + } + h=(HWND)[(id)h contentView]; + } + bool isView=h && [(id)h isKindOfClass:[NSView class]]; + if (isView) + { + if ([(id)h respondsToSelector:@selector(getSwellPaintInfo:)]) + { + PAINTSTRUCT ps={0,}; + [(id)h getSwellPaintInfo:(PAINTSTRUCT *)&ps]; + if (ps.hdc && ps.hdc==hdc) return; + } + } + + if (hdc) SWELL_DeleteGfxContext(hdc); + if (isView && hdc) + { + [(NSView *)h unlockFocus]; +// if ([(NSView *)h window]) [[(NSView *)h window] flushWindow]; + } +} + +void SWELL_FillDialogBackground(HDC hdc, RECT *r, int level) +{ + CGContextRef ctx=(CGContextRef)SWELL_GetCtxGC(hdc); + if (ctx) + { + // level 0 for now = this + HIThemeSetFill(kThemeBrushDialogBackgroundActive,NULL,ctx,kHIThemeOrientationNormal); + CGRect rect=CGRectMake(r->left,r->top,r->right-r->left,r->bottom-r->top); + CGContextFillRect(ctx,rect); + } +} + +HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a) +{ + if (HGDIOBJ_VALID(a)) + { + a->additional_refcnt++; + return a; + } + return NULL; +} + + +HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits) +{ + int spp = bitsperpixel/8; + Boolean hasa = (bitsperpixel == 32); + Boolean hasp = (numplanes > 1); // won't actually work yet for planar data + NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 pixelsWide:width pixelsHigh:height + bitsPerSample:8 samplesPerPixel:spp + hasAlpha:hasa isPlanar:hasp + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:NSAlphaFirstBitmapFormat + bytesPerRow:0 bitsPerPixel:0]; + if (!rep) return 0; + unsigned char* p = [rep bitmapData]; + int pspan = [rep bytesPerRow]; // might not be the same as width + + int y; + for (y=0;ytype = TYPE_BITMAP; + obj->wid = 1; // need free + obj->bitmapptr = img; + return obj; +} + + +HIMAGELIST ImageList_CreateEx() +{ + return (HIMAGELIST)new WDL_PtrList; +} + +BOOL ImageList_Remove(HIMAGELIST list, int idx) +{ + WDL_PtrList* imglist=(WDL_PtrList*)list; + if (imglist && idx < imglist->GetSize()) + { + if (idx < 0) + { + int x,n=imglist->GetSize(); + for (x=0;xGet(x); + if (a) DeleteObject(a); + } + imglist->Empty(); + } + else + { + HGDIOBJ__ *a = imglist->Get(idx); + imglist->Set(idx, NULL); + if (a) DeleteObject(a); + } + return TRUE; + } + + return FALSE; +} + +void ImageList_Destroy(HIMAGELIST list) +{ + if (!list) return; + ImageList_Remove(list, -1); + delete (WDL_PtrList*)list; +} + +int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image) +{ + if (!image || !list) return -1; + WDL_PtrList *l=(WDL_PtrList *)list; + + HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image; + if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1; + + HGDIOBJ__* icon=GDP_OBJECT_NEW(); + icon->type=TYPE_BITMAP; + icon->wid=1; + icon->bitmapptr = imgsrc->bitmapptr; // no need to duplicate it, can just retain a copy + [icon->bitmapptr retain]; + image = (HICON) icon; + + if (offset<0||offset>=l->GetSize()) + { + l->Add(image); + offset=l->GetSize()-1; + } + else + { + HICON old=l->Get(offset); + l->Set(offset,image); + if (old) DeleteObject(old); + } + return offset; +} + + + +#endif diff --git a/WDL/swell/swell-ini.cpp b/WDL/swell/swell-ini.cpp new file mode 100644 index 00000000..ca3ab701 --- /dev/null +++ b/WDL/swell/swell-ini.cpp @@ -0,0 +1,551 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + This file implements basic win32 GetPrivateProfileString / etc support. + It works by caching reads, but writing through on every write that is required (to ensure + that updates take, especially when being updated from multiple modules who have their own + cache of the .ini file). + + It is threadsafe, but in theory if two processes are trying to access the same ini, + results may go a bit unpredictable (but in general the file should NOT get corrupted, + we hope). + +*/ + +#ifndef SWELL_PROVIDED_BY_APP + + +#include "swell.h" +#include "../assocarray.h" +#include "../mutex.h" +#include "../queue.h" +#include +#include +#include + +static void deleteStringKeyedArray(WDL_StringKeyedArray *p) { delete p; } + +struct iniFileContext +{ + iniFileContext() : m_sections(false,deleteStringKeyedArray) + { + m_curfn=NULL; + m_lastaccesscnt=0; + m_curfn_time=0; + m_curfn_sz=0; + } + ~iniFileContext() { } + + WDL_UINT64 m_lastaccesscnt; + time_t m_curfn_time; + int m_curfn_sz; + char *m_curfn; + + WDL_StringKeyedArray< WDL_StringKeyedArray * > m_sections; + +}; + +#define NUM_OPEN_CONTEXTS 32 +static iniFileContext s_ctxs[NUM_OPEN_CONTEXTS]; +static WDL_Mutex m_mutex; + +static time_t getfileupdtimesize(const char *fn, int *szOut) +{ + struct stat st; + *szOut = 0; + if (!fn || !fn[0] || stat(fn,&st)) return 0; + *szOut = (int)st.st_size; + return st.st_mtime; +} + +static bool fgets_to_typedbuf(WDL_TypedBuf *buf, FILE *fp) +{ + int rdpos=0; + while (rdpos < 1024*1024*32) + { + if (buf->GetSize()Resize(rdpos+8192); + if (buf->GetSize()Get()+rdpos; + *p=0; + fgets(p,buf->GetSize()-rdpos,fp); + if (!*p) break; + while (*p) p++; + if (p[-1] == '\r' || p[-1] == '\n') break; + + rdpos = p - buf->Get(); + } + return buf->GetSize()>0 && buf->Get()[0]; +} + + +// return true on success +static iniFileContext *GetFileContext(const char *name) +{ + static WDL_UINT64 acc_cnt; + int best_z = 0; + { + int w; + WDL_UINT64 bestcnt = 0; + bestcnt--; + + for (w=0;wm_lastaccesscnt=++acc_cnt; + + int sz=0; + if (!ctx->m_curfn || stricmp(ctx->m_curfn,name) || ctx->m_curfn_time != getfileupdtimesize(ctx->m_curfn,&sz) || sz != ctx->m_curfn_sz) + { + ctx->m_sections.DeleteAll(); +// printf("reinitting to %s\n",name); + if (!ctx->m_curfn || stricmp(ctx->m_curfn,name)) + { + free(ctx->m_curfn); + ctx->m_curfn=strdup(name); + } + FILE *fp = fopen(name,"r"); + + if (!fp) + { + ctx->m_curfn_time=0; + ctx->m_curfn_sz=0; + return ctx; // allow to proceed (empty file) + } + + flock(fileno(fp),LOCK_SH); + + // parse .ini file + WDL_StringKeyedArray *cursec=NULL; + + int lcnt=0; + for (;;) + { + static WDL_TypedBuf _buf; + if (!fgets_to_typedbuf(&_buf,fp)) break; + + char *buf = _buf.Get(); + char *p=buf; + if (lcnt++ == 8 && !ctx->m_sections.GetSize()) break; // dont bother reading more than 8 lines if no section encountered + + while (*p) p++; + + if (p>buf) + { + p--; + while (p >= buf && (*p==' ' || *p == '\r' || *p == '\n' || *p == '\t')) p--; + p[1]=0; + } + p=buf; + while (*p == ' ' || *p == '\t') p++; + if (p[0] == '[') + { + char *p2=p; + while (*p2 && *p2 != ']') p2++; + if (*p2) + { + *p2=0; + if (cursec) cursec->Resort(); + + if (p[1]) + { + cursec = ctx->m_sections.Get(p+1); + if (!cursec) + { + cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); + ctx->m_sections.Insert(p+1,cursec); + } + else cursec->DeleteAll(); + } + else cursec=0; + } + } + else if (cursec) + { + char *t=strstr(p,"="); + if (t) + { + *t++=0; + if (*p) + cursec->AddUnsorted(p,strdup(t)); + } + } + } + ctx->m_curfn_time = getfileupdtimesize(name,&ctx->m_curfn_sz); + flock(fileno(fp),LOCK_UN); + fclose(fp); + + if (cursec) cursec->Resort(); + } + return ctx; +} + +static void WriteBackFile(iniFileContext *ctx) +{ + if (!ctx||!ctx->m_curfn) return; + char newfn[1024]; + lstrcpyn(newfn,ctx->m_curfn,sizeof(newfn)-8); + { + char *p=newfn; + while (*p) p++; + while (p>newfn && p[-1] != '/') p--; + char lc = '.'; + while (*p) + { + char c = *p; + *p++ = lc; + lc = c; + } + *p++ = lc; + strcpy(p,".new"); + } + + FILE *fp = fopen(newfn,"w"); + if (!fp) return; + + flock(fileno(fp),LOCK_EX); + + int x; + for (x = 0; ; x ++) + { + const char *secname=NULL; + WDL_StringKeyedArray * cursec = ctx->m_sections.Enumerate(x,&secname); + if (!cursec || !secname) break; + + fprintf(fp,"[%s]\n",secname); + int y; + for (y=0;;y++) + { + const char *keyname = NULL; + const char *keyvalue = cursec->Enumerate(y,&keyname); + if (!keyvalue || !keyname) break; + if (*keyname) fprintf(fp,"%s=%s\n",keyname,keyvalue); + } + fprintf(fp,"\n"); + } + + fflush(fp); + flock(fileno(fp),LOCK_UN); + fclose(fp); + + if (!rename(newfn,ctx->m_curfn)) + { + ctx->m_curfn_time = getfileupdtimesize(ctx->m_curfn,&ctx->m_curfn_sz); + } + else + { + // error updating, hmm how to handle this? + } +} + +BOOL WritePrivateProfileSection(const char *appname, const char *strings, const char *fn) +{ + if (!appname || !fn) return FALSE; + WDL_MutexLock lock(&m_mutex); + iniFileContext *ctx = GetFileContext(fn); + if (!ctx) return FALSE; + + WDL_StringKeyedArray * cursec = ctx->m_sections.Get(appname); + if (!cursec) + { + if (!*strings) return TRUE; + + cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); + ctx->m_sections.Insert(appname,cursec); + } + else cursec->DeleteAll(); + + if (*strings) + { + while (*strings) + { + char buf[8192]; + lstrcpyn(buf,strings,sizeof(buf)); + char *p = buf; + while (*p && *p != '=') p++; + if (*p) + { + *p++=0; + cursec->Insert(buf,strdup(strings + (p-buf))); + } + + strings += strlen(strings)+1; + } + } + WriteBackFile(ctx); + + return TRUE; +} + + +BOOL WritePrivateProfileString(const char *appname, const char *keyname, const char *val, const char *fn) +{ + if (!appname || (keyname && !*keyname)) return FALSE; +// printf("writing %s %s %s %s\n",appname,keyname,val,fn); + WDL_MutexLock lock(&m_mutex); + + iniFileContext *ctx = GetFileContext(fn); + if (!ctx) return FALSE; + + if (!keyname) + { + if (ctx->m_sections.Get(appname)) + { + ctx->m_sections.Delete(appname); + WriteBackFile(ctx); + } + } + else + { + WDL_StringKeyedArray * cursec = ctx->m_sections.Get(appname); + if (!val) + { + if (cursec && cursec->Get(keyname)) + { + cursec->Delete(keyname); + WriteBackFile(ctx); + } + } + else + { + const char *p; + if (!cursec || !(p=cursec->Get(keyname)) || strcmp(p,val)) + { + if (!cursec) + { + cursec = new WDL_StringKeyedArray(false,WDL_StringKeyedArray::freecharptr); + ctx->m_sections.Insert(appname,cursec); + } + cursec->Insert(keyname,strdup(val)); + WriteBackFile(ctx); + } + } + + } + + return TRUE; +} + +DWORD GetPrivateProfileSection(const char *appname, char *strout, DWORD strout_len, const char *fn) +{ + WDL_MutexLock lock(&m_mutex); + + if (!strout || strout_len<2) + { + if (strout && strout_len==1) *strout=0; + return 0; + } + iniFileContext *ctx= GetFileContext(fn); + int szOut=0; + WDL_StringKeyedArray *cursec = ctx ? ctx->m_sections.Get(appname) : NULL; + + if (ctx && cursec) + { + int x; + for(x=0;xGetSize();x++) + { + const char *kv = NULL; + const char *val = cursec->Enumerate(x,&kv); + if (val && kv) + { + int l; + +#define WRSTR(v) \ + l= strlen(v); \ + if (l > strout_len - szOut - 2) l = strout_len - 2 - szOut; \ + if (l>0) { memcpy(strout+szOut,v,l); szOut+=l; } + + WRSTR(kv) + WRSTR("=") + WRSTR(val) + +#undef WRSTR + + l=1; + if (l > strout_len - szOut - 1) l = strout_len - 1 - szOut; + if (l>0) { memset(strout+szOut,0,l); szOut+=l; } + if (szOut >= strout_len-1) + { + strout[strout_len-1]=0; + return strout_len-2; + } + } + } + } + strout[szOut]=0; + if (!szOut) strout[1]=0; + return szOut; +} + +DWORD GetPrivateProfileString(const char *appname, const char *keyname, const char *def, char *ret, int retsize, const char *fn) +{ + WDL_MutexLock lock(&m_mutex); + +// printf("getprivateprofilestring: %s\n",fn); + iniFileContext *ctx= GetFileContext(fn); + + if (ctx) + { + if (!appname||!keyname) + { + WDL_Queue tmpbuf; + if (!appname) + { + int x; + for (x = 0;; x ++) + { + const char *secname=NULL; + if (!ctx->m_sections.Enumerate(x,&secname) || !secname) break; + if (*secname) tmpbuf.Add(secname,strlen(secname)+1); + } + } + else + { + WDL_StringKeyedArray *cursec = ctx->m_sections.Get(appname); + if (cursec) + { + int y; + for (y = 0; ; y ++) + { + const char *keyname=NULL; + if (!cursec->Enumerate(y,&keyname)||!keyname) break; + if (*keyname) tmpbuf.Add(keyname,strlen(keyname)+1); + } + } + } + + int sz=tmpbuf.GetSize()-1; + if (sz<0) + { + ret[0]=ret[1]=0; + return 0; + } + if (sz > retsize-2) sz=retsize-2; + memcpy(ret,tmpbuf.Get(),sz); + ret[sz]=ret[sz+1]=0; + + return sz; + } + + WDL_StringKeyedArray *cursec = ctx->m_sections.Get(appname); + if (cursec) + { + const char *val = cursec->Get(keyname); + if (val) + { + lstrcpyn(ret,val,retsize); + return strlen(ret); + } + } + } +// printf("def %s %s %s %s\n",appname,keyname,def,fn); + lstrcpyn(ret,def?def:"",retsize); + return strlen(ret); +} + +int GetPrivateProfileInt(const char *appname, const char *keyname, int def, const char *fn) +{ + char buf[512]; + GetPrivateProfileString(appname,keyname,"",buf,sizeof(buf),fn); + if (buf[0]) + { + int a=atoi(buf); + if (a||buf[0]=='0') return a; + } + return def; +} + +static bool __readbyte(char *src, unsigned char *out) +{ + unsigned char cv=0; + int s=4; + while(s>=0) + { + if (*src >= '0' && *src <= '9') cv += (*src-'0')<= 'a' && *src <= 'f') cv += (*src-'a' + 10)<= 'A' && *src <= 'F') cv += (*src-'A' + 10)<0) + { + if (!__readbyte(src,&cv)) break; + *bufout++ = cv; + sum += cv; + src+=2; + } + ret = bufsz<0 && __readbyte(src,&cv) && cv==sum; + } + free(tmp); + //printf("getprivateprofilestruct returning %d\n",ret); + return ret; +} + +BOOL WritePrivateProfileStruct(const char *appname, const char *keyname, const void *buf, int bufsz, const char *fn) +{ + if (!keyname || !buf) return WritePrivateProfileString(appname,keyname,(const char *)buf,fn); + char *tmp=(char *)malloc((bufsz+1)*2+1); + if (!tmp) return 0; + char *p = tmp; + unsigned char sum=0; + unsigned char *src=(unsigned char *)buf; + while (bufsz-- > 0) + { + sprintf(p,"%02X",*src); + sum+=*src++; + p+=2; + } + sprintf(p,"%02X",sum); + + BOOL ret=WritePrivateProfileString(appname,keyname,tmp,fn); + free(tmp); + return ret; +} + +#endif diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h new file mode 100644 index 00000000..dea3bcc6 --- /dev/null +++ b/WDL/swell/swell-internal.h @@ -0,0 +1,758 @@ +#ifndef _SWELL_INTERNAL_H_ +#define _SWELL_INTERNAL_H_ + +#include "../ptrlist.h" + +#ifdef SWELL_TARGET_OSX + +#if 0 + // at some point we should enable this and use it in most SWELL APIs that call Cocoa code... + #define SWELL_BEGIN_TRY @try { + #define SWELL_END_TRY(x) } @catch (NSException *ex) { NSLog(@"SWELL exception in %s:%d :: %@:%@\n",__FILE__,__LINE__,[ex name], [ex reason]); x } +#else + #define SWELL_BEGIN_TRY + #define SWELL_END_TRY(x) +#endif + +#define __SWELL_PREFIX_CLASSNAME3(a,b) a##b +#define __SWELL_PREFIX_CLASSNAME2(a,b) __SWELL_PREFIX_CLASSNAME3(a,b) +#define __SWELL_PREFIX_CLASSNAME(cname) __SWELL_PREFIX_CLASSNAME2(SWELL_APP_PREFIX,cname) + +// this defines interfaces to internal swell classes +#define SWELL_hwndChild __SWELL_PREFIX_CLASSNAME(_hwnd) +#define SWELL_hwndCarbonHost __SWELL_PREFIX_CLASSNAME(_hwndcarbonhost) + +#define SWELL_ModelessWindow __SWELL_PREFIX_CLASSNAME(_modelesswindow) +#define SWELL_ModalDialog __SWELL_PREFIX_CLASSNAME(_dialogbox) + +#define SWELL_TextField __SWELL_PREFIX_CLASSNAME(_textfield) +#define SWELL_ListView __SWELL_PREFIX_CLASSNAME(_listview) +#define SWELL_TreeView __SWELL_PREFIX_CLASSNAME(_treeview) +#define SWELL_TabView __SWELL_PREFIX_CLASSNAME(_tabview) +#define SWELL_ProgressView __SWELL_PREFIX_CLASSNAME(_progind) +#define SWELL_TextView __SWELL_PREFIX_CLASSNAME(_textview) +#define SWELL_BoxView __SWELL_PREFIX_CLASSNAME(_box) +#define SWELL_Button __SWELL_PREFIX_CLASSNAME(_button) +#define SWELL_PopUpButton __SWELL_PREFIX_CLASSNAME(_pub) +#define SWELL_ComboBox __SWELL_PREFIX_CLASSNAME(_cbox) + +#define SWELL_StatusCell __SWELL_PREFIX_CLASSNAME(_statuscell) +#define SWELL_ListViewCell __SWELL_PREFIX_CLASSNAME(_listviewcell) +#define SWELL_ODListViewCell __SWELL_PREFIX_CLASSNAME(_ODlistviewcell) +#define SWELL_ODButtonCell __SWELL_PREFIX_CLASSNAME(_ODbuttoncell) + +#define SWELL_FocusRectWnd __SWELL_PREFIX_CLASSNAME(_drawfocusrectwnd) + +#define SWELL_DataHold __SWELL_PREFIX_CLASSNAME(_sdh) +#define SWELL_ThreadTmp __SWELL_PREFIX_CLASSNAME(_thread) +#define SWELL_PopupMenuRecv __SWELL_PREFIX_CLASSNAME(_trackpopupmenurecv) + +#define SWELL_TimerFuncTarget __SWELL_PREFIX_CLASSNAME(_tft) + + +#define SWELL_Menu __SWELL_PREFIX_CLASSNAME(_menu) + +#ifdef __OBJC__ + + +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 +typedef int NSInteger; +typedef unsigned int NSUInteger; +#endif + +@interface SWELL_Menu : NSMenu +{ +} +-(void)dealloc; +- (id)copyWithZone:(NSZone *)zone; +@end + +@interface SWELL_DataHold : NSObject +{ + void *m_data; +} +-(id) initWithVal:(void *)val; +-(void *) getValue; +@end + +@interface SWELL_TimerFuncTarget : NSObject +{ + TIMERPROC m_cb; + HWND m_hwnd; + UINT_PTR m_timerid; +} +-(id) initWithId:(UINT_PTR)tid hwnd:(HWND)h callback:(TIMERPROC)cb; +-(void)SWELL_Timer:(id)sender; +@end + +typedef struct OwnedWindowListRec +{ + NSWindow *hwnd; + struct OwnedWindowListRec *_next; +} OwnedWindowListRec; + +typedef struct WindowPropRec +{ + char *name; // either <64k or a strdup'd name + void *data; + struct WindowPropRec *_next; +} WindowPropRec; + + +class SWELL_ListView_Row +{ +public: + SWELL_ListView_Row(); + ~SWELL_ListView_Row(); + WDL_PtrList m_vals; + LPARAM m_param; + int m_imageidx; + + int m_tmp; +}; + + +struct HTREEITEM__ +{ + HTREEITEM__(); + ~HTREEITEM__(); + bool FindItem(HTREEITEM it, HTREEITEM__ **parOut, int *idxOut); + + SWELL_DataHold *m_dh; + + bool m_haschildren; + char *m_value; + WDL_PtrList m_children; // only used in tree mode + LPARAM m_param; +}; + + + +@interface SWELL_TextField : NSTextField +- (void)setNeedsDisplay:(BOOL)flag; +- (void)setNeedsDisplayInRect:(NSRect)rect; +@end + +@interface SWELL_TabView : NSTabView +{ + NSInteger m_tag; + id m_dest; +} +@end + +@interface SWELL_ProgressView : NSProgressIndicator +{ + NSInteger m_tag; +} +@end + +@interface SWELL_ListViewCell : NSTextFieldCell +{ +} +@end + +@interface SWELL_StatusCell : NSTextFieldCell +{ + NSImage *status; +} +@end + +@interface SWELL_TreeView : NSOutlineView +{ + @public + bool m_fakerightmouse; + LONG style; + WDL_PtrList *m_items; + NSColor *m_fgColor; + NSMutableArray *m_selColors; +} +@end + +@interface SWELL_ListView : NSTableView +{ + int m_leftmousemovecnt; + bool m_fakerightmouse; + @public + LONG style; + int ownermode_cnt; + int m_start_item; + int m_start_subitem; + int m_start_item_clickmode; + int m_lbMode; + WDL_PtrList *m_items; + WDL_PtrList *m_cols; + WDL_PtrList *m_status_imagelist; + int m_status_imagelist_type; + int m_fastClickMask; + NSColor *m_fgColor; + NSMutableArray *m_selColors; +} +-(LONG)getSwellStyle; +-(void)setSwellStyle:(LONG)st; +-(int)getSwellNotificationMode; +-(void)setSwellNotificationMode:(int)lbMode; +-(int)columnAtPoint:(NSPoint)pt; +-(int)getColumnPos:(int)idx; // get current position of column that was originally at idx +-(int)getColumnIdx:(int)pos; // get original index of column that is currently at position +@end + +@interface SWELL_ODButtonCell : NSButtonCell +{ +} +@end + +@interface SWELL_ODListViewCell : NSCell +{ + SWELL_ListView *m_ownctl; + int m_lastidx; +} +-(void)setOwnerControl:(SWELL_ListView *)t; +-(void)setItemIdx:(int)idx; +@end + +@interface SWELL_Button : NSButton +{ + void *m_swellGDIimage; + LONG_PTR m_userdata; + int m_radioflags; +} +-(int)swellGetRadioFlags; +-(void)swellSetRadioFlags:(int)f; +-(LONG_PTR)getSwellUserData; +-(void)setSwellUserData:(LONG_PTR)val; +-(void)setSwellGDIImage:(void *)par; +-(void *)getSwellGDIImage; +@end + +@interface SWELL_TextView : NSTextView +{ + NSInteger m_tag; +} +-(NSInteger) tag; +-(void) setTag:(NSInteger)tag; +@end + +@interface SWELL_BoxView : NSBox +{ + NSInteger m_tag; +} +-(NSInteger) tag; +-(void) setTag:(NSInteger)tag; +@end + +@interface SWELL_FocusRectWnd : NSView +{ +} +@end + +@interface SWELL_ThreadTmp : NSObject +{ +@public + void *a, *b; +} +-(void)bla:(id)obj; +@end + + + +@interface SWELL_hwndChild : NSView // +{ +@public + BOOL m_enabled; + DLGPROC m_dlgproc; + WNDPROC m_wndproc; + LONG_PTR m_userdata; + LONG_PTR m_extradata[32]; + NSInteger m_tag; + int m_isfakerightmouse; + char m_hashaddestroy; // 2 = WM_DESTROY has finished completely + HMENU m_menu; + BOOL m_flip; + bool m_supports_ddrop; + bool m_paintctx_used; + HDC m_paintctx_hdc; + WindowPropRec *m_props; + NSRect m_paintctx_rect; + BOOL m_isopaque; + char m_titlestr[1024]; + unsigned int m_create_windowflags; + NSOpenGLContext *m_glctx; + char m_isdirty; // &1=self needs redraw, &2=children may need redraw + id m_lastTopLevelOwner; // save a copy of the owner, if any + id m_access_cacheptrs[6]; +} +- (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par; +- (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam; +-(HANDLE)swellExtendedDragOp:(id )sender retGlob:(BOOL)retG; +- (const char *)onSwellGetText; +-(void)onSwellSetText:(const char *)buf; +-(LONG)swellGetExtendedStyle; +-(void)swellSetExtendedStyle:(LONG)st; +-(HMENU)swellGetMenu; +-(BOOL)swellHasBeenDestroyed; +-(void)swellSetMenu:(HMENU)menu; +-(LONG_PTR)getSwellUserData; +-(void)setSwellUserData:(LONG_PTR)val; +-(void)setOpaque:(bool)isOpaque; +-(LPARAM)getSwellExtraData:(int)idx; +-(void)setSwellExtraData:(int)idx value:(LPARAM)val; +-(void)setSwellWindowProc:(WNDPROC)val; +-(WNDPROC)getSwellWindowProc; +-(void)setSwellDialogProc:(DLGPROC)val; +-(DLGPROC)getSwellDialogProc; + +- (NSArray*) namesOfPromisedFilesDroppedAtDestination:(NSURL*)droplocation; + +-(void) getSwellPaintInfo:(PAINTSTRUCT *)ps; +- (int)swellCapChangeNotify; +-(unsigned int)swellCreateWindowFlags; + +-(bool)swellCanPostMessage; +-(int)swellEnumProps:(PROPENUMPROCEX)proc lp:(LPARAM)lParam; +-(void *)swellGetProp:(const char *)name wantRemove:(BOOL)rem; +-(int)swellSetProp:(const char *)name value:(void *)val ; + + +// NSAccessibility + +// attribute methods +- (NSArray *)accessibilityAttributeNames; +- (id)accessibilityAttributeValue:(NSString *)attribute; +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; + +// parameterized attribute methods +- (NSArray *)accessibilityParameterizedAttributeNames; +- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter; + +// action methods +- (NSArray *)accessibilityActionNames; +- (NSString *)accessibilityActionDescription:(NSString *)action; +- (void)accessibilityPerformAction:(NSString *)action; + +// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. +- (BOOL)accessibilityIsIgnored; + +// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. +- (id)accessibilityHitTest:(NSPoint)point; + +// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. +- (id)accessibilityFocusedUIElement; + + + + +@end + +@interface SWELL_ModelessWindow : NSWindow +{ +@public + NSSize lastFrameSize; + id m_owner; + OwnedWindowListRec *m_ownedwnds; + BOOL m_enabled; + int m_wantraiseamt; + bool m_wantInitialKeyWindowOnShow; +} +- (id)initModeless:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par outputHwnd:(HWND *)hwndOut forceStyles:(unsigned int)smask; +- (id)initModelessForChild:(HWND)child owner:(HWND)owner styleMask:(unsigned int)smask; +- (void)swellDestroyAllOwnedWindows; +- (void)swellRemoveOwnedWindow:(NSWindow *)wnd; +- (void)swellSetOwner:(id)owner; +- (id)swellGetOwner; +- (void **)swellGetOwnerWindowHead; +-(void)swellDoDestroyStuff; +-(void)swellResetOwnedWindowLevels; +@end + +@interface SWELL_ModalDialog : NSPanel +{ + NSSize lastFrameSize; + id m_owner; + OwnedWindowListRec *m_ownedwnds; + + int m_rv; + bool m_hasrv; + BOOL m_enabled; +} +- (id)initDialogBox:(SWELL_DialogResourceIndex *)resstate Parent:(HWND)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par; +- (void)swellDestroyAllOwnedWindows; +- (void)swellRemoveOwnedWindow:(NSWindow *)wnd; +- (void)swellSetOwner:(id)owner; +- (id)swellGetOwner; +- (void **)swellGetOwnerWindowHead; +-(void)swellDoDestroyStuff; + +-(void)swellSetModalRetVal:(int)r; +-(int)swellGetModalRetVal; +-(bool)swellHasModalRetVal; +@end + + +@interface SWELL_hwndCarbonHost : SWELL_hwndChild +{ +@public + NSWindow *m_cwnd; + + bool m_whileresizing; + void* m_wndhandler; // won't compile if declared EventHandlerRef, wtf + void* m_ctlhandler; // not sure if these need to be separate but cant hurt + bool m_wantallkeys; +} +-(BOOL)swellIsCarbonHostingView; +-(void)swellDoRepos; +@end + + +@interface SWELL_PopupMenuRecv : NSObject +{ + int m_act; + HWND cbwnd; +} +-(id) initWithWnd:(HWND)wnd; +-(void) onSwellCommand:(id)sender; +-(int) isCommand; +- (void)menuNeedsUpdate:(NSMenu *)menu; + +@end + +@interface SWELL_PopUpButton : NSPopUpButton +{ + LONG m_style; +} +-(void)setSwellStyle:(LONG)style; +-(LONG)getSwellStyle; +@end + +@interface SWELL_ComboBox : NSComboBox +{ +@public + LONG m_style; + WDL_PtrList *m_ids; +} +-(id)init; +-(void)dealloc; +-(void)setSwellStyle:(LONG)style; +-(LONG)getSwellStyle; +@end + + + +// GDI internals + + +// 10.4 doesn't support CoreText, so allow ATSUI if targetting 10.4 SDK +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 +#ifndef __LP64__ +#define SWELL_ATSUI_TEXT_SUPPORT +#endif +#endif + +struct HGDIOBJ__ +{ + int type; + + int additional_refcnt; // refcnt of 0 means one owner (if >0, additional owners) + + // used by pen/brush + CGColorRef color; + int wid; + NSImage *bitmapptr; + + NSMutableDictionary *__old_fontdict; // unused, for ABI compat + // + // if ATSUI used, meaning IsCoreTextSupported() returned false + ATSUStyle atsui_font_style; + + float font_rotation; + + bool _infreelist; + struct HGDIOBJ__ *_next; + + // if using CoreText to draw text + void *ct_FontRef; +}; + +struct HDC__ { + CGContextRef ctx; + void *ownedData; // always use via SWELL_GetContextFrameBuffer() (which performs necessary alignment) + HGDIOBJ__ *curpen; + HGDIOBJ__ *curbrush; + HGDIOBJ__ *curfont; + + NSColor *__old_nstextcol; // provided for ABI compat, but unused + int cur_text_color_int; // text color as int + + int curbkcol; + int curbkmode; + float lastpos_x,lastpos_y; + + void *GLgfxctx; // optionally set + bool _infreelist; + struct HDC__ *_next; + + CGColorRef curtextcol; // text color as CGColor +}; + + + + + +// some extras so we can call functions available only on some OSX versions without warnings, and with the correct types +#define SWELL_DelegateExtensions __SWELL_PREFIX_CLASSNAME(_delext) +#define SWELL_ViewExtensions __SWELL_PREFIX_CLASSNAME(_viewext) +#define SWELL_AppExtensions __SWELL_PREFIX_CLASSNAME(_appext) +#define SWELL_WindowExtensions __SWELL_PREFIX_CLASSNAME(_wndext) +#define SWELL_TableColumnExtensions __SWELL_PREFIX_CLASSNAME(_tcolext) + +@interface SWELL_WindowExtensions : NSWindow +-(void)setCollectionBehavior:(NSUInteger)a; +@end +@interface SWELL_ViewExtensions : NSView +-(void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)vr rectIsVisibleRectForView:(NSView*)v topView:(NSView *)v2; +@end + +@interface SWELL_DelegateExtensions : NSObject +-(bool)swellPostMessage:(HWND)dest msg:(int)message wp:(WPARAM)wParam lp:(LPARAM)lParam; +-(void)swellPostMessageClearQ:(HWND)dest; +-(void)swellPostMessageTick:(id)sender; +@end + +@interface SWELL_AppExtensions : NSApplication +-(NSUInteger)presentationOptions; +-(void)setPresentationOptions:(NSUInteger)o; +@end +@interface SWELL_TableColumnExtensions : NSTableColumn +-(BOOL)isHidden; +-(void)setHidden:(BOOL)h; +@end + + + + + +#endif // __OBJC__ + +// 10.4 sdk just uses "float" +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 +typedef float CGFloat; +#endif + + +#elif defined(SWELL_TARGET_GDK) + +#include +#include + +#else +// generic + +#endif // end generic + +#ifndef SWELL_TARGET_OSX + +#ifdef SWELL_LICE_GDI +#include "../lice/lice.h" +#endif +#include "../assocarray.h" + +LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +struct HWND__ +{ + HWND__(HWND par, int wID=0, RECT *wndr=NULL, const char *label=NULL, bool visible=false, WNDPROC wndproc=NULL, DLGPROC dlgproc=NULL); + ~HWND__(); // DO NOT USE!!! We would make this private but it breaks PtrList using it on gcc. + + // using this API prevents the HWND from being valid -- it'll still get its resources destroyed via DestroyWindow() though. + // DestroyWindow() does cleanup, then the final Release(). + void Retain() { m_refcnt++; } + void Release() { if (!--m_refcnt) delete this; } + + + + + const char *m_classname; + + +#ifdef SWELL_TARGET_GDK + GdkWindow *m_oswindow; +#endif + char *m_title; + + HWND__ *m_children, *m_parent, *m_next, *m_prev; + HWND__ *m_owner, *m_owned; + RECT m_position; + int m_id; + int m_style, m_exstyle; + INT_PTR m_userdata; + WNDPROC m_wndproc; + DLGPROC m_dlgproc; + INT_PTR m_extra[64]; + INT_PTR m_private_data; // used by internal controls + + bool m_visible; + bool m_hashaddestroy; + bool m_enabled; + bool m_wantfocus; + + int m_refcnt; + + HMENU m_menu; + + WDL_StringKeyedArray m_props; + +#ifdef SWELL_LICE_GDI + void *m_paintctx; // temporarily set for calls to WM_PAINT + +// todo: + bool m_child_invalidated; // if a child is invalidated + bool m_invalidated; // set to true on direct invalidate. todo RECT instead? + + LICE_IBitmap *m_backingstore; // if NULL, unused (probably only should use on top level windows, but support caching?) +#endif +}; + +struct HMENU__ +{ + HMENU__() { } + ~HMENU__() { items.Empty(true,freeMenuItem); } + + WDL_PtrList items; + + HMENU__ *Duplicate(); + static void freeMenuItem(void *p); + +}; + + +struct HGDIOBJ__ +{ + int type; + int additional_refcnt; // refcnt of 0 means one owner (if >0, additional owners) + + int color; + int wid; + + struct HGDIOBJ__ *_next; + bool _infreelist; +#ifdef SWELL_FREETYPE + void *fontface; // FT_Face +#endif + +}; + + +struct HDC__ { +#ifdef SWELL_LICE_GDI + LICE_IBitmap *surface; // owned by context. can be (and usually is, if clipping is desired) LICE_SubBitmap + POINT surface_offs; // offset drawing into surface by this amount + + RECT dirty_rect; // in surface coordinates, used for GetWindowDC()/GetDC()/etc + bool dirty_rect_valid; +#else + void *ownedData; // for mem contexts, support a null rendering +#endif + + HGDIOBJ__ *curpen; + HGDIOBJ__ *curbrush; + HGDIOBJ__ *curfont; + + int cur_text_color_int; // text color as int + + int curbkcol; + int curbkmode; + float lastpos_x,lastpos_y; + + struct HDC__ *_next; + bool _infreelist; +}; + +#endif // !OSX + +HDC SWELL_CreateGfxContext(void *); + +// GDP internals +#define TYPE_PEN 1 +#define TYPE_BRUSH 2 +#define TYPE_FONT 3 +#define TYPE_BITMAP 4 + +typedef struct +{ + void *instptr; + void *bundleinstptr; + int refcnt; + + int (*SWELL_dllMain)(HINSTANCE, DWORD,LPVOID); //last parm=SWELLAPI_GetFunc + BOOL (*dllMain)(HINSTANCE, DWORD, LPVOID); + void *lastSymbolRequested; +} SWELL_HINSTANCE; + + +enum +{ + INTERNAL_OBJECT_START= 0x1000001, + INTERNAL_OBJECT_THREAD, + INTERNAL_OBJECT_EVENT, + INTERNAL_OBJECT_FILE, + INTERNAL_OBJECT_EXTERNALSOCKET, // socket not owned by us + INTERNAL_OBJECT_SOCKETEVENT, + INTERNAL_OBJECT_NSTASK, + INTERNAL_OBJECT_END +}; + +typedef struct +{ + int type; // INTERNAL_OBJECT_* + int count; // reference count +} SWELL_InternalObjectHeader; + +typedef struct +{ + SWELL_InternalObjectHeader hdr; + DWORD (*threadProc)(LPVOID); + void *threadParm; + pthread_t pt; + DWORD retv; + bool done; +} SWELL_InternalObjectHeader_Thread; + +typedef struct +{ + SWELL_InternalObjectHeader hdr; + + pthread_mutex_t mutex; + pthread_cond_t cond; + + bool isSignal; + bool isManualReset; + +} SWELL_InternalObjectHeader_Event; + + +// used for both INTERNAL_OBJECT_EXTERNALSOCKET and INTERNAL_OBJECT_SOCKETEVENT. +// if EXTERNALSOCKET, socket[1] ignored and autoReset ignored. +typedef struct +{ + SWELL_InternalObjectHeader hdr; + int socket[2]; + bool autoReset; +} SWELL_InternalObjectHeader_SocketEvent; + +typedef struct +{ + SWELL_InternalObjectHeader hdr; + + FILE *fp; +} SWELL_InternalObjectHeader_File; + +typedef struct +{ + SWELL_InternalObjectHeader hdr; + void *task; +} SWELL_InternalObjectHeader_NSTask; + + +bool IsRightClickEmulateEnabled(); + +#endif diff --git a/WDL/swell/swell-kb-generic.cpp b/WDL/swell/swell-kb-generic.cpp new file mode 100644 index 00000000..ecaaeab4 --- /dev/null +++ b/WDL/swell/swell-kb-generic.cpp @@ -0,0 +1,110 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux? + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic key and mouse cursor querying, as well as a key to windows key translation function. + + */ + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-dlggen.h" + +int SWELL_KeyToASCII(int wParam, int lParam, int *newflags) +{ + if (wParam >= '0' && wParam <= '9' && lParam == (FSHIFT|FVIRTKEY)) + { + // todo: some OS X API for this? + *newflags = lParam&~(FSHIFT|FVIRTKEY); + switch (wParam) + { + case '1': return '!'; + case '2': return '@'; + case '3': return '#'; + case '4': return '$'; + case '5': return '%'; + case '6': return '^'; + case '7': return '&'; + case '8': return '*'; + case '9': return '('; + case '0': return ')'; + } + } + return 0; +} + + +SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; + +HCURSOR SWELL_LoadCursor(const char *_idx) +{ + return NULL; +} + +static HCURSOR m_last_setcursor; + +void SWELL_SetCursor(HCURSOR curs) +{ + m_last_setcursor=curs; + // todo +} + +HCURSOR SWELL_GetCursor() +{ + return m_last_setcursor; +} +HCURSOR SWELL_GetLastSetCursor() +{ + return m_last_setcursor; +} + + + + +static int m_curvis_cnt; +bool SWELL_IsCursorVisible() +{ + return m_curvis_cnt>=0; +} +int SWELL_ShowCursor(BOOL bShow) +{ + m_curvis_cnt += (bShow?1:-1); + if (m_curvis_cnt==-1 && !bShow) + { + } + if (m_curvis_cnt==0 && bShow) + { + } + return m_curvis_cnt; +} + + +BOOL SWELL_SetCursorPos(int X, int Y) +{ + + return false; +} + +HCURSOR SWELL_LoadCursorFromFile(const char *fn) +{ + return NULL; +} + +#endif diff --git a/WDL/swell/swell-kb.mm b/WDL/swell/swell-kb.mm new file mode 100644 index 00000000..bf494385 --- /dev/null +++ b/WDL/swell/swell-kb.mm @@ -0,0 +1,601 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic key and mouse cursor querying, as well as a mac key to windows key translation function. + + */ + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-dlggen.h" +#import +#import + + + +static int MacKeyCodeToVK(int code) +{ + switch (code) + { + case 51: return VK_BACK; + case 65: return VK_DECIMAL; + case 67: return VK_MULTIPLY; + case 69: return VK_ADD; + case 71: return VK_NUMLOCK; + case 75: return VK_DIVIDE; + case 76: return VK_RETURN|0x8000; + case 78: return VK_SUBTRACT; + case 81: return VK_SEPARATOR; + case 82: return VK_NUMPAD0; + case 83: return VK_NUMPAD1; + case 84: return VK_NUMPAD2; + case 85: return VK_NUMPAD3; + case 86: return VK_NUMPAD4; + case 87: return VK_NUMPAD5; + case 88: return VK_NUMPAD6; + case 89: return VK_NUMPAD7; + case 91: return VK_NUMPAD8; + case 92: return VK_NUMPAD9; + case 96: return VK_F5; + case 97: return VK_F6; + case 98: return VK_F7; + case 99: return VK_F3; + case 100: return VK_F8; + case 101: return VK_F9; + case 109: return VK_F10; + case 103: return VK_F11; + case 105: return VK_SNAPSHOT; + case 111: return VK_F12; + case 114: return VK_INSERT; + case 115: return VK_HOME; + case 117: return VK_DELETE; + case 116: return VK_PRIOR; + case 118: return VK_F4; + case 119: return VK_END; + case 120: return VK_F2; + case 121: return VK_NEXT; + case 122: return VK_F1; + case 123: return VK_LEFT; + case 124: return VK_RIGHT; + case 125: return VK_DOWN; + case 126: return VK_UP; + } + return 0; +} + +bool IsRightClickEmulateEnabled(); + + +int SWELL_MacKeyToWindowsKey(void *nsevent, int *flags) +{ + NSEvent *theEvent = (NSEvent *)nsevent; + int mod=[theEvent modifierFlags];// & ( NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask); + // if ([theEvent isARepeat]) return; + + int flag=0; + if (mod & NSShiftKeyMask) flag|=FSHIFT; + if (mod & NSCommandKeyMask) flag|=FCONTROL; // todo: this should be command once we figure it out + if (mod & NSAlternateKeyMask) flag|=FALT; + if ((mod&NSControlKeyMask) && !IsRightClickEmulateEnabled()) flag|=FLWIN; + + int rawcode=[theEvent keyCode]; + + int code=MacKeyCodeToVK(rawcode); + if (!code) + { + NSString *str=[theEvent charactersIgnoringModifiers]; +// if (!str || ![str length]) str=[theEvent characters]; + + if (!str || ![str length]) + { + code = 1024+rawcode; // raw code + flag|=FVIRTKEY; + } + else + { + code=[str characterAtIndex:0]; + if (code >= 'a' && code <= 'z') code+='A'-'a'; + if (code == 25 && (flag&FSHIFT)) code=VK_TAB; + if (isalnum(code)||code==' ' || code == '\r' || code == '\n' || code ==27 || code == VK_TAB) flag|=FVIRTKEY; + } + } + else + { + flag|=FVIRTKEY; + if (code==8) code='\b'; + } + + if (!(flag&FVIRTKEY)) flag&=~FSHIFT; + + if (flags) *flags=flag; + return code; +} + +int SWELL_KeyToASCII(int wParam, int lParam, int *newflags) +{ + if (wParam >= '0' && wParam <= '9' && lParam == (FSHIFT|FVIRTKEY)) + { + *newflags = lParam&~(FSHIFT|FVIRTKEY); + if (!(lParam & (FCONTROL|FLWIN))) switch (wParam) + { + case '1': return '!'; + case '2': return '@'; + case '3': return '#'; + case '4': return '$'; + case '5': return '%'; + case '6': return '^'; + case '7': return '&'; + case '8': return '*'; + case '9': return '('; + case '0': return ')'; + } + } + return 0; +} + + +WORD GetAsyncKeyState(int key) +{ + int state=0; + if (key == VK_LBUTTON || key == VK_RBUTTON || key == VK_MBUTTON) + { + state=GetCurrentEventButtonState(); + } + else + { + state=CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState); + } + + if ((key == VK_LBUTTON && (state&1)) || + (key == VK_RBUTTON && (state&2)) || + (key == VK_MBUTTON && (state&4)) || + (key == VK_SHIFT && (state&kCGEventFlagMaskShift)) || + (key == VK_CONTROL && (state&kCGEventFlagMaskCommand)) || + (key == VK_MENU && (state&kCGEventFlagMaskAlternate)) || + (key == VK_LWIN && !IsRightClickEmulateEnabled() && (state&kCGEventFlagMaskControl))) + { + return 0x8000; + } + + return 0; +} + + +SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; + +static NSCursor* MakeCursorFromData(unsigned char* data, int hotspot_x, int hotspot_y) +{ + NSCursor *c=NULL; + NSBitmapImageRep* bmp = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:0 + pixelsWide:16 + pixelsHigh:16 + bitsPerSample:8 + samplesPerPixel:2 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSCalibratedWhiteColorSpace + bytesPerRow:(16*2) + bitsPerPixel:16]; + + if (bmp) + { + unsigned char* p = [bmp bitmapData]; + if (p) + { + int i; + for (i = 0; i < 16*16; ++i) + { + // tried 4 bits per sample and memcpy, didn't work + p[2*i] = (data[i]&0xF0) | data[i]>>4; + p[2*i+1] = (data[i]<<4) | (data[i]&0xf); + } + + NSImage *img = [[NSImage alloc] init]; + if (img) + { + [img addRepresentation:bmp]; + NSPoint hs = { hotspot_x, hotspot_y }; + c = [[NSCursor alloc] initWithImage:img hotSpot:hs]; + [img release]; + } + } + [bmp release]; + } + return c; +} + +static NSCursor* MakeSWELLSystemCursor(const char *id) +{ + // bytemaps are (white<<4)|(alpha) + const unsigned char B = 0xF; + const unsigned char W = 0xFF; + const unsigned char G = 0xF8; + + static NSCursor* carr[3] = { 0, 0, 0 }; + + NSCursor** pc=0; + if (id == IDC_SIZEALL) pc = &carr[0]; + else if (id == IDC_SIZENWSE) pc = &carr[1]; + else if (id == IDC_SIZENESW) pc = &carr[2]; + else return 0; + + if (!(*pc)) + { + if (id == IDC_SIZEALL) + { + static unsigned char p[16*16] = + { + 0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0, + 0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0, + 0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0, + 0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0, + G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G, + W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W, + W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W, + G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G, + 0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0, + 0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0, + 0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0, + 0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0, + }; + *pc = MakeCursorFromData(p, 8, 8); + } + else if (id == IDC_SIZENWSE || id == IDC_SIZENESW) + { + static unsigned char p[16*16] = + { + W, W, W, W, W, W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + W, G, G, G, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + W, G, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + W, W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, + W, G, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, G, W, + 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W, W, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, G, W, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, G, G, G, W, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W, W, W, W, W, W, + }; + if (id == IDC_SIZENESW) + { + int x, y; + for (y = 0; y < 16; ++y) + { + for (x = 0; x < 8; ++x) + { + unsigned char tmp = p[16*y+x]; + p[16*y+x] = p[16*y+16-x-1]; + p[16*y+16-x-1] = tmp; + } + } + } + *pc = MakeCursorFromData(p, 8, 8); + if (id == IDC_SIZENESW) // swap back! + { + int x, y; + for (y = 0; y < 16; ++y) + { + for (x = 0; x < 8; ++x) + { + unsigned char tmp = p[16*y+x]; + p[16*y+x] = p[16*y+16-x-1]; + p[16*y+16-x-1] = tmp; + } + } + } + } + else if (id == IDC_NO) + { + static unsigned char p[16*16] = + { + 0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0, + 0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0, + 0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0, + 0, W, B, B, W, W, G, 0, 0, G, W, G, B, B, W, 0, + G, W, B, W, G, 0, 0, 0, 0, G, W, B, G, B, W, G, + W, B, B, W, 0, 0, 0, 0, G, W, B, W, W, B, B, W, + W, B, W, G, 0, 0, 0, G, W, B, W, G, G, W, B, W, + W, B, W, 0, 0, 0, G, W, B, W, G, 0, 0, W, B, W, + W, B, W, 0, 0, G, W, B, W, G, 0, 0, 0, W, B, W, + W, B, W, G, G, W, B, W, G, 0, 0, 0, G, W, B, W, + W, B, B, W, W, B, W, G, 0, 0, 0, 0, W, B, B, W, + G, W, B, G, B, W, G, 0, 0, 0, 0, G, W, B, W, G, + 0, W, B, B, G, W, G, 0, 0, G, W, W, B, B, W, 0, + 0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0, + 0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0, + 0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0, + }; + *pc = MakeCursorFromData(p, 8, 8); + } + } + + return *pc; +} + +static NSImage *swell_imageFromCursorString(const char *name, POINT *hotSpot) +{ + NSImage *img=NULL; + FILE *fp = NULL; + bool isFullFn=false; + + if (!strstr(name,"/") && strlen(name)<1024) + { + char tmpn[4096]; + GetModuleFileName(NULL,tmpn,sizeof(tmpn)-128-strlen(name)); + strcat(tmpn,"/Contents/Resources/"); + strcat(tmpn,name); + strcat(tmpn,".cur"); + fp = fopen(tmpn,"rb"); + } + else + { + isFullFn=true; + if (strlen(name)>4 && !stricmp(name+strlen(name)-4,".cur")) fp = fopen(name,"rb"); + } + + if (fp) + { + unsigned char buf[4096]; + if (fread(buf,1,6,fp)==6 && !buf[0] && !buf[1] && buf[2] == 2 && buf[3] == 0 && buf[4] == 1 && buf[5] == 0) + { + static char tempfn[512]; + if (!tempfn[0]) + { + const char *p = getenv("TEMP"); + if (!p || !*p) p="/tmp"; + sprintf(tempfn,"%.200s/swellcur%x%x.ico",p,timeGetTime(),(int)getpid()); + } + + FILE *outfp = fopen(tempfn,"wb"); + if (outfp) + { + bool wantLoad=false; + buf[2]=1; // change to .ico + fwrite(buf,1,6,outfp); + + fread(buf,1,16,fp); + int xHot = buf[4]|(buf[5]<<8); + int yHot = buf[6]|(buf[7]<<8); + + buf[4]=1; buf[5]=0; // 1 color plane + buf[6]=0; buf[7]=0; // 0 for pixel depth means "auto" + + if (!buf[3]) + { + fwrite(buf,1,16,outfp); + for (;;) + { + int a = fread(buf,1,sizeof(buf),fp); + if (a<1) break; + fwrite(buf,1,a,outfp); + } + wantLoad=true; + } + + fclose(outfp); + if (wantLoad) + { + NSString *str = (NSString *)SWELL_CStringToCFString(tempfn); + img = [[NSImage alloc] initWithContentsOfFile:str]; + [str release]; + if (img && hotSpot) + { + hotSpot->x = xHot; + hotSpot->y = yHot; + } + // printf("loaded converted ico for %s %s %d\n",tempfn,name,!!img); + } + unlink(tempfn); + } + + } + + fclose(fp); + } + + if (!img) // fall back + { + NSString *str = (NSString *)SWELL_CStringToCFString(name); + + if (isFullFn) img = [[NSImage alloc] initWithContentsOfFile:str]; + else + { + img = [NSImage imageNamed:str]; + if (img) [img retain]; + } + [str release]; + } + + return img; +} + + +HCURSOR SWELL_LoadCursorFromFile(const char *fn) +{ + POINT hotspot={0,}; + NSImage *img = swell_imageFromCursorString(fn,&hotspot); + if (img) + { + HCURSOR ret=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(hotspot.x,hotspot.y)]; + [img release]; + return ret; + } + return NULL; +} + +// todo: support for loading from file +HCURSOR SWELL_LoadCursor(const char *_idx) +{ + if (_idx == IDC_NO||_idx==IDC_SIZENWSE || _idx == IDC_SIZENESW || _idx == IDC_SIZEALL) return (HCURSOR) MakeSWELLSystemCursor(_idx); + if (_idx == IDC_SIZEWE) return (HCURSOR)[NSCursor resizeLeftRightCursor]; + if (_idx == IDC_SIZENS) return (HCURSOR)[NSCursor resizeUpDownCursor]; + if (_idx == IDC_ARROW) return (HCURSOR)[NSCursor arrowCursor]; + if (_idx == IDC_HAND) return (HCURSOR)[NSCursor openHandCursor]; + if (_idx == IDC_UPARROW) return (HCURSOR)[NSCursor resizeUpCursor]; + if (_idx == IDC_IBEAM) return (HCURSOR)[NSCursor IBeamCursor]; + + // search registered cursor list + SWELL_CursorResourceIndex *p = SWELL_curmodule_cursorresource_head; + while (p) + { + if (p->resid == _idx) + { + if (p->cachedCursor) return p->cachedCursor; + + NSImage *img = swell_imageFromCursorString(p->resname,&p->hotspot); + if (img) + { + p->cachedCursor=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(p->hotspot.x,p->hotspot.y)]; + [img release]; + return p->cachedCursor; + } + } + p=p->_next; + } + return 0; +} + +static HCURSOR m_last_setcursor; + +void SWELL_SetCursor(HCURSOR curs) +{ + if (curs && [(id) curs isKindOfClass:[NSCursor class]]) + { + m_last_setcursor=curs; + [(NSCursor *)curs set]; + } + else + { + m_last_setcursor=NULL; + [[NSCursor arrowCursor] set]; + } +} + +HCURSOR SWELL_GetCursor() +{ + return (HCURSOR)[NSCursor currentCursor]; +} +HCURSOR SWELL_GetLastSetCursor() +{ + return m_last_setcursor; +} + +static POINT g_swell_mouse_relmode_curpos; // stored in osx-native coordinates (y=0=top of screen) +static bool g_swell_mouse_relmode; + + + +void GetCursorPos(POINT *pt) +{ + if (g_swell_mouse_relmode) + { + *pt=g_swell_mouse_relmode_curpos; + return; + } + NSPoint localpt=[NSEvent mouseLocation]; + pt->x=(int)floor(localpt.x); + pt->y=-(int)floor(-localpt.y); // floor() is used with negative sign, effectively ceil(), because screen coordinates are flipped and everywhere else we use nonflipped rounding +} + +DWORD GetMessagePos() +{ + if (g_swell_mouse_relmode) + { + return MAKELONG((int)g_swell_mouse_relmode_curpos.x,(int)g_swell_mouse_relmode_curpos.y); + } + NSPoint localpt=[NSEvent mouseLocation]; + return MAKELONG((int)floor(localpt.x), -(int)floor(-localpt.y)); // floor() is used with negative sign, effectively ceil(), because screen coordinates are flipped and everywhere else we use nonflipped rounding +} + + +NSPoint swellProcessMouseEvent(int msg, NSView *view, NSEvent *event) +{ + if (g_swell_mouse_relmode && msg==WM_MOUSEMOVE) // event will have relative coordinates + { + int idx=(int)[event deltaX]; + int idy=(int)[event deltaY]; + g_swell_mouse_relmode_curpos.x += idx; + g_swell_mouse_relmode_curpos.y -= idy; + } + if (g_swell_mouse_relmode) + { + POINT p=g_swell_mouse_relmode_curpos; + ScreenToClient((HWND)view,&p); + return NSMakePoint(p.x,p.y); + } + NSPoint localpt=[event locationInWindow]; + return [view convertPoint:localpt fromView:nil]; +} + +static int m_curvis_cnt; +bool SWELL_IsCursorVisible() +{ + return m_curvis_cnt>=0; +} +int SWELL_ShowCursor(BOOL bShow) +{ + m_curvis_cnt += (bShow?1:-1); + if (m_curvis_cnt==-1 && !bShow) + { + GetCursorPos(&g_swell_mouse_relmode_curpos); + CGDisplayHideCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(false); + g_swell_mouse_relmode=true; + } + if (m_curvis_cnt==0 && bShow) + { + CGDisplayShowCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(true); + g_swell_mouse_relmode=false; + SetCursorPos(g_swell_mouse_relmode_curpos.x,g_swell_mouse_relmode_curpos.y); + } + return m_curvis_cnt; +} + + +BOOL SWELL_SetCursorPos(int X, int Y) +{ + if (g_swell_mouse_relmode) + { + g_swell_mouse_relmode_curpos.x=X; + g_swell_mouse_relmode_curpos.y=Y; + return TRUE; + } + + + int h=CGDisplayPixelsHigh(CGMainDisplayID()); + CGPoint pos=CGPointMake(X,h-Y); + return CGWarpMouseCursorPosition(pos)==kCGErrorSuccess; +} + + + +#endif diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp new file mode 100644 index 00000000..65dd4afc --- /dev/null +++ b/WDL/swell/swell-menu-generic.cpp @@ -0,0 +1,631 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic windows menu API + + */ + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-menugen.h" + +#include "swell-internal.h" + +#include "../ptrlist.h" + +HMENU__ *HMENU__::Duplicate() +{ + HMENU__ *p = new HMENU__; + int x; + for (x = 0; x < items.GetSize(); x ++) + { + MENUITEMINFO *s = items.Get(x); + MENUITEMINFO *inf = (MENUITEMINFO*)calloc(sizeof(MENUITEMINFO),1); + + *inf = *s; + if (inf->dwTypeData) + { + // todo handle bitmap types + inf->dwTypeData=strdup(inf->dwTypeData); + } + if (inf->hSubMenu) inf->hSubMenu = inf->hSubMenu->Duplicate(); + + p->items.Add(inf); + } + return p; +} + +void HMENU__::freeMenuItem(void *p) +{ + MENUITEMINFO *inf = (MENUITEMINFO *)p; + if (!inf) return; + delete inf->hSubMenu; + free(inf->dwTypeData); // todo handle bitmap types + free(inf); +} + +static MENUITEMINFO *GetMenuItemByID(HMENU menu, int id, bool searchChildren=true) +{ + if (!menu) return 0; + int x; + for (x = 0; x < menu->items.GetSize(); x ++) + if (menu->items.Get(x)->wID == id) return menu->items.Get(x); + + if (searchChildren) for (x = 0; x < menu->items.GetSize(); x ++) + { + if (menu->items.Get(x)->hSubMenu) + { + MENUITEMINFO *ret = GetMenuItemByID(menu->items.Get(x)->hSubMenu,id,true); + if (ret) return ret; + } + } + + return 0; +} + +bool SetMenuItemText(HMENU hMenu, int idx, int flag, const char *text) +{ + MENUITEMINFO *item = hMenu ? ((flag & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; + if (!item) return false; + + item->fType = MFT_STRING; + free(item->dwTypeData); // todo handle bitmap types + item->dwTypeData=strdup(text?text:""); + + return true; +} + +bool EnableMenuItem(HMENU hMenu, int idx, int en) +{ + MENUITEMINFO *item = hMenu ? ((en & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; + if (!item) return false; + + int mask = MF_ENABLED|MF_DISABLED|MF_GRAYED; + item->fState &= ~mask; + item->fState |= en&mask; + + return true; +} + +bool CheckMenuItem(HMENU hMenu, int idx, int chk) +{ + MENUITEMINFO *item = hMenu ? ((chk & MF_BYPOSITION) ? hMenu->items.Get(idx) : GetMenuItemByID(hMenu,idx)) : NULL; + if (!item) return false; + + int mask = MF_CHECKED; + item->fState &= ~mask; + item->fState |= chk&mask; + + return true; +} +HMENU SWELL_GetCurrentMenu() +{ + return NULL; // not osx +} +void SWELL_SetCurrentMenu(HMENU hmenu) +{ +} + +HMENU GetSubMenu(HMENU hMenu, int pos) +{ + MENUITEMINFO *item = hMenu ? hMenu->items.Get(pos) : NULL; + if (item) return item->hSubMenu; + return 0; +} + +int GetMenuItemCount(HMENU hMenu) +{ + if (hMenu) return hMenu->items.GetSize(); + return 0; +} + +int GetMenuItemID(HMENU hMenu, int pos) +{ + MENUITEMINFO *item = hMenu ? hMenu->items.Get(pos) : NULL; + if (!item || item->hSubMenu) return -1; + return item->wID; +} + +bool SetMenuItemModifier(HMENU hMenu, int idx, int flag, int code, unsigned int mask) +{ + return false; +} + +HMENU CreatePopupMenu() +{ + return new HMENU__; +} +HMENU CreatePopupMenuEx(const char *title) +{ + return CreatePopupMenu(); +} + +void DestroyMenu(HMENU hMenu) +{ + delete hMenu; +} + +int AddMenuItem(HMENU hMenu, int pos, const char *name, int tagid) +{ + if (!hMenu) return -1; + MENUITEMINFO *inf = (MENUITEMINFO*)calloc(1,sizeof(MENUITEMINFO)); + inf->wID = tagid; + inf->dwTypeData = strdup(name?name:""); + hMenu->items.Insert(pos,inf); + return 0; +} + +bool DeleteMenu(HMENU hMenu, int idx, int flag) +{ + if (!hMenu) return false; + if (flag&MF_BYPOSITION) + { + if (hMenu->items.Get(idx)) + { + hMenu->items.Delete(idx,true,HMENU__::freeMenuItem); + return true; + } + return false; + } + else + { + int x; + int cnt=0; + for (x=0;xitems.GetSize(); x ++) + { + if (!hMenu->items.Get(x)->hSubMenu && hMenu->items.Get(x)->wID == idx) + { + hMenu->items.Delete(x--,true,HMENU__::freeMenuItem); + cnt++; + } + } + if (!cnt) + { + for (x=0;xitems.GetSize(); x ++) + { + if (hMenu->items.Get(x)->hSubMenu) cnt += DeleteMenu(hMenu->items.Get(x)->hSubMenu,idx,flag)?1:0; + } + } + return !!cnt; + } +} + + +BOOL SetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) +{ + if (!hMenu) return 0; + MENUITEMINFO *item = byPos ? hMenu->items.Get(pos) : GetMenuItemByID(hMenu, pos, true); + if (!item) return 0; + + if ((mi->fMask & MIIM_SUBMENU) && mi->hSubMenu != item->hSubMenu) + { + delete item->hSubMenu; + item->hSubMenu = mi->hSubMenu; + } + if (mi->fMask & MIIM_TYPE) + { + free(item->dwTypeData); // todo handle bitmap types + item->dwTypeData=0; + if (mi->fType == MFT_STRING && mi->dwTypeData) + { + item->dwTypeData = strdup( mi->dwTypeData ); + } + item->fType = mi->fType; + } + + if (mi->fMask & MIIM_STATE) item->fState = mi->fState; + if (mi->fMask & MIIM_ID) item->wID = mi->wID; + if (mi->fMask & MIIM_DATA) item->dwItemData = mi->dwItemData; + + return true; +} + +BOOL GetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) +{ + if (!hMenu) return 0; + MENUITEMINFO *item = byPos ? hMenu->items.Get(pos) : GetMenuItemByID(hMenu, pos, true); + if (!item) return 0; + + if (mi->fMask & MIIM_TYPE) + { + mi->fType = item->fType; + if (item->fType == MFT_STRING && mi->dwTypeData && mi->cch) + { + lstrcpyn(mi->dwTypeData,item->dwTypeData?item->dwTypeData:"",mi->cch); + } + } + + if (mi->fMask & MIIM_DATA) mi->dwItemData = item->dwItemData; + if (mi->fMask & MIIM_STATE) mi->fState = item->fState; + if (mi->fMask & MIIM_ID) mi->wID = item->wID; + if (mi->fMask & MIIM_SUBMENU) mi->hSubMenu = item->hSubMenu; + + return 1; + +} + +void SWELL_InsertMenu(HMENU menu, int pos, int flag, int idx, const char *str) +{ + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + (flag & ~MF_BYPOSITION),idx,NULL,NULL,NULL,0,(char *)str}; + InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); +} + +void SWELL_InsertMenu(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str) +{ + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + (flag & ~MF_BYPOSITION),(flag&MF_POPUP) ? 0 : (int)idx,NULL,NULL,NULL,0,(char *)str}; + + if (flag&MF_POPUP) + { + mi.hSubMenu = (HMENU)idx; + mi.fMask |= MIIM_SUBMENU; + mi.fState &= ~MF_POPUP; + } + + if (flag&MF_SEPARATOR) + { + mi.fMask=MIIM_TYPE; + mi.fType=MFT_SEPARATOR; + mi.fState &= ~MF_SEPARATOR; + } + + InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); +} + +void InsertMenuItem(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) +{ + if (!hMenu) return; + int ni=hMenu->items.GetSize(); + + if (!byPos) + { + int x; + for (x=0;xitems.Get(x)->wID != pos; x++); + pos = x; + } + if (pos < 0 || pos > ni) pos=ni; + + MENUITEMINFO *inf = (MENUITEMINFO*)calloc(sizeof(MENUITEMINFO),1); + inf->fType = mi->fType; + if (mi->fType == MFT_STRING) + { + inf->dwTypeData = strdup(mi->dwTypeData?mi->dwTypeData:""); + } + else if (mi->fType == MFT_BITMAP) + { // todo handle bitmap types + } + else if (mi->fType == MFT_SEPARATOR) + { + } + if (mi->fMask&MIIM_SUBMENU) inf->hSubMenu = mi->hSubMenu; + if (mi->fMask & MIIM_STATE) inf->fState = mi->fState; + if (mi->fMask & MIIM_DATA) inf->dwItemData = mi->dwItemData; + if (mi->fMask & MIIM_ID) inf->wID = mi->wID; + + hMenu->items.Insert(pos,inf); +} + + +void SWELL_SetMenuDestination(HMENU menu, HWND hwnd) +{ + // only needed for Cocoa +} + +static POINT m_trackingPt; +static int m_trackingFlags,m_trackingRet; +static HWND m_trackingPar; +static WDL_PtrList m_trackingMenus; // each HWND as userdata = HMENU + +static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + const int itemheight = 12, lcol=12, rcol=12, mcol=10; + switch (uMsg) + { + case WM_CREATE: + m_trackingMenus.Add(hwnd); + SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + + if (m_trackingPar && !(m_trackingFlags&TPM_NONOTIFY)) + SendMessage(m_trackingPar,WM_INITMENUPOPUP,(WPARAM)lParam,0); + + { + HDC hdc = GetDC(hwnd); + HMENU__ *menu = (HMENU__*)lParam; + int ht = menu->items.GetSize()*itemheight, wid=100,wid2=0; + int xpos=m_trackingPt.x; + int ypos=m_trackingPt.y; + int x; + for (x=0; x < menu->items.GetSize(); x++) + { + MENUITEMINFO *inf = menu->items.Get(x); + if (inf->fType == MFT_STRING && inf->dwTypeData) + { + RECT r={0,}; + const char *pt2 = strstr(inf->dwTypeData,"\t"); + DrawText(hdc,inf->dwTypeData,pt2 ? pt2-inf->dwTypeData : -1,&r,DT_CALCRECT|DT_SINGLELINE); + if (r.right > wid) wid=r.right; + if (pt2) + { + r.right=r.left; + DrawText(hdc,pt2+1,-1,&r,DT_CALCRECT|DT_SINGLELINE); + if (r.right > wid2) wid2=r.right; + } + } + } + wid+=lcol+rcol + (wid2?wid2+mcol:0); + ReleaseDC(hwnd,hdc); + RECT tr={xpos,ypos,xpos+wid,ypos+ht},vp; + SWELL_GetViewPort(&vp,&tr,true); + if (tr.bottom > vp.bottom) { tr.top += vp.bottom-tr.bottom; tr.bottom=vp.bottom; } + if (tr.right > vp.right) { tr.left += vp.right-tr.right; tr.right=vp.right; } + if (tr.left < vp.left) { tr.right += vp.left-tr.left; tr.left=vp.left; } + if (tr.top < vp.top) { tr.bottom += vp.top-tr.top; tr.top=vp.top; } + SetWindowPos(hwnd,NULL,tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top,SWP_NOZORDER); + } + SetWindowLong(hwnd,GWL_STYLE,GetWindowLong(hwnd,GWL_STYLE)&~WS_CAPTION); + ShowWindow(hwnd,SW_SHOW); + SetFocus(hwnd); + SetTimer(hwnd,1,250,NULL); + break; + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT cr; + GetClientRect(hwnd,&cr); + HBRUSH br=CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + HPEN pen=CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); + HGDIOBJ oldbr = SelectObject(ps.hdc,br); + HGDIOBJ oldpen = SelectObject(ps.hdc,pen); + Rectangle(ps.hdc,cr.left,cr.top,cr.right-1,cr.bottom-1); + SetBkMode(ps.hdc,TRANSPARENT); + int cols[2]={ GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_3DHILIGHT)}; + HMENU__ *menu = (HMENU__*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + int x; + for (x=0; x < menu->items.GetSize(); x++) + { + MENUITEMINFO *inf = menu->items.Get(x); + RECT r={lcol,x*itemheight,cr.right,(x+1)*itemheight}; + bool dis = !!(inf->fState & MF_GRAYED); + SetTextColor(ps.hdc,cols[dis]); + if (inf->fType == MFT_STRING && inf->dwTypeData) + { + const char *pt2 = strstr(inf->dwTypeData,"\t"); + DrawText(ps.hdc,inf->dwTypeData,pt2 ? pt2-inf->dwTypeData : -1,&r,DT_VCENTER|DT_SINGLELINE); + if (pt2) + { + RECT tr=r; tr.right-=rcol; + DrawText(ps.hdc,pt2+1,-1,&tr,DT_VCENTER|DT_SINGLELINE|DT_RIGHT); + } + } + else + { + MoveToEx(ps.hdc,r.left - lcol/2,(r.top+r.bottom)/2,NULL); + LineTo(ps.hdc,r.right - rcol*3/2,(r.top+r.bottom)/2); + } + if (inf->hSubMenu) + { + RECT r2=r; r2.left = r2.right - rcol; + DrawText(ps.hdc,">",-1,&r2,DT_VCENTER|DT_RIGHT|DT_SINGLELINE); + } + if (inf->fState&MF_CHECKED) + { + RECT r2=r; r2.left = 0; r2.right=lcol; + DrawText(ps.hdc,"X",-1,&r2,DT_VCENTER|DT_CENTER|DT_SINGLELINE); + } + } + SelectObject(ps.hdc,oldbr); + SelectObject(ps.hdc,oldpen); + DeleteObject(br); + DeleteObject(pen); + EndPaint(hwnd,&ps); + } + } + break; + case WM_TIMER: + if (wParam==1) + { + HWND GetFocusIncludeMenus(); + HWND h = GetFocusIncludeMenus(); + if (h!=hwnd) + { + int a = h ? m_trackingMenus.Find(h) : -1; + if (a<0 || a < m_trackingMenus.Find(hwnd)) DestroyWindow(hwnd); + } + } + break; + case WM_DESTROY: + { + int a = m_trackingMenus.Find(hwnd); + m_trackingMenus.Delete(a); + if (m_trackingMenus.Get(a)) DestroyWindow(m_trackingMenus.Get(a)); + RemoveProp(hwnd,"SWELL_MenuOwner"); + } + break; + case WM_LBUTTONUP: + case WM_RBUTTONUP: + { + RECT r; + GetClientRect(hwnd,&r); + if (GET_X_LPARAM(lParam)>=r.left && GET_X_LPARAM(lParam)items.Get(which); + if (inf) + { + if (inf->fState&MF_GRAYED){ } + else if (inf->hSubMenu) + { + int a = m_trackingMenus.Find(hwnd); + HWND next = m_trackingMenus.Get(a+1); + if (next) DestroyWindow(next); + + m_trackingPt.x=r.right; + m_trackingPt.y=r.top + which*itemheight; + ClientToScreen(hwnd,&m_trackingPt); + HWND hh; + submenuWndProc(hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL),WM_CREATE,0,(LPARAM)inf->hSubMenu); + SetProp(hh,"SWELL_MenuOwner",GetProp(hh,"SWELL_MenuOwner")); + } + else if (inf->wID) m_trackingRet = inf->wID; + } + else DestroyWindow(hwnd); + } + else DestroyWindow(hwnd); + } + break; + } + return DefWindowProc(hwnd,uMsg,wParam,lParam); +} + +int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r) +{ + if (!hMenu || m_trackingMenus.GetSize()) return 0; + + ReleaseCapture(); + m_trackingPar=hwnd; + m_trackingFlags=flags; + m_trackingRet=-1; + m_trackingPt.x=xpos; + m_trackingPt.y=ypos; + +// HWND oldFoc = GetFocus(); + // bool oldFoc_child = oldFoc && (IsChild(hwnd,oldFoc) || oldFoc == hwnd || oldFoc==GetParent(hwnd)); + + HWND hh; + submenuWndProc(hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL),WM_CREATE,0,(LPARAM)hMenu); + SetProp(hh,"SWELL_MenuOwner",(HANDLE)hwnd); + + while (m_trackingRet<0 && m_trackingMenus.GetSize()) + { + void SWELL_RunMessageLoop(); + SWELL_RunMessageLoop(); + Sleep(10); + } + + int x=m_trackingMenus.GetSize()-1; + while (x>=0) + { + HWND h = m_trackingMenus.Get(x); + m_trackingMenus.Delete(x); + if (h) DestroyWindow(h); + x--; + } + +// if (oldFoc_child) SetFocus(oldFoc); + + if (!(flags&TPM_NONOTIFY) && m_trackingRet>0) + SendMessage(hwnd,WM_COMMAND,m_trackingRet,0); + + return m_trackingRet>0?m_trackingRet:0; +} + + + + +void SWELL_Menu_AddMenuItem(HMENU hMenu, const char *name, int idx, int flags) +{ + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + (flags)?MFS_GRAYED:0,idx,NULL,NULL,NULL,0,(char *)name}; + if (!name) + { + mi.fType = MFT_SEPARATOR; + mi.fMask&=~(MIIM_STATE|MIIM_ID); + } + InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); +} + + +SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; // todo: move to per-module thingy + +static SWELL_MenuResourceIndex *resById(SWELL_MenuResourceIndex *head, const char *resid) +{ + SWELL_MenuResourceIndex *p=head; + while (p) + { + if (p->resid == resid) return p; + p=p->_next; + } + return 0; +} + +HMENU SWELL_LoadMenu(SWELL_MenuResourceIndex *head, const char *resid) +{ + SWELL_MenuResourceIndex *p; + + if (!(p=resById(head,resid))) return 0; + HMENU hMenu=CreatePopupMenu(); + if (hMenu) p->createFunc(hMenu); + return hMenu; +} + +HMENU SWELL_DuplicateMenu(HMENU menu) +{ + if (!menu) return 0; + return menu->Duplicate(); +} + +BOOL SetMenu(HWND hwnd, HMENU menu) +{ + if (!hwnd) return 0; + hwnd->m_menu = menu; + + return TRUE; +} + +HMENU GetMenu(HWND hwnd) +{ + if (!hwnd) return 0; + return hwnd->m_menu; +} + +void DrawMenuBar(HWND hwnd) +{ + InvalidateRect(hwnd,NULL,FALSE); +} + + +// copied from swell-menu.mm, can have a common impl someday +int SWELL_GenerateMenuFromList(HMENU hMenu, const void *_list, int listsz) +{ + SWELL_MenuGen_Entry *list = (SWELL_MenuGen_Entry *)_list; + const int l1=strlen(SWELL_MENUGEN_POPUP_PREFIX); + while (listsz>0) + { + int cnt=1; + if (!list->name) SWELL_Menu_AddMenuItem(hMenu,NULL,-1,0); + else if (!strcmp(list->name,SWELL_MENUGEN_ENDPOPUP)) return list + 1 - (SWELL_MenuGen_Entry *)_list; + else if (!strncmp(list->name,SWELL_MENUGEN_POPUP_PREFIX,l1)) + { + MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_STATE|MIIM_TYPE,MFT_STRING,0,0,CreatePopupMenuEx(list->name+l1),NULL,NULL,0,(char *)list->name+l1}; + cnt += SWELL_GenerateMenuFromList(mi.hSubMenu,list+1,listsz-1); + InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); + } + else SWELL_Menu_AddMenuItem(hMenu,list->name,list->idx,list->flags); + + list+=cnt; + listsz -= cnt; + } +} +#endif diff --git a/WDL/swell/swell-menu.mm b/WDL/swell/swell-menu.mm new file mode 100644 index 00000000..89e22bcd --- /dev/null +++ b/WDL/swell/swell-menu.mm @@ -0,0 +1,919 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic windows menu API to interface an NSMenu + + */ + +#ifndef SWELL_PROVIDED_BY_APP + +#import + +#include "swell.h" +#include "swell-menugen.h" + +#include "swell-internal.h" + + +static void __filtnametobuf(char *out, const char *in, int outsz) +{ + while (*in && outsz>1) + { + if (*in == '\t') break; + if (*in == '&') + { + in++; + } + *out++=*in++; + outsz--; + } + *out=0; +} + + + +bool SetMenuItemText(HMENU hMenu, int idx, int flag, const char *text) +{ + NSMenu *menu=(NSMenu *)hMenu; + + NSMenuItem *item; + if (flag & MF_BYPOSITION) item=[menu itemAtIndex:idx]; + else item =[menu itemWithTag:idx]; + if (!item) + { + if (!(flag & MF_BYPOSITION)) + { + int x; + int n=[menu numberOfItems]; + for (x = 0; x < n; x ++) + { + item=[menu itemAtIndex:x]; + if (item && [item hasSubmenu]) + { + NSMenu *m=[item submenu]; + if (m && SetMenuItemText((HMENU)m,idx,flag,text)) return true; + } + } + } + return false; + } + char buf[1024]; + __filtnametobuf(buf,text?text:"",sizeof(buf)); + NSString *label=(NSString *)SWELL_CStringToCFString(buf); + + [item setTitle:label]; + if ([item hasSubmenu] && [item submenu]) [[item submenu] setTitle:label]; + + [label release]; + return true; +} + +bool EnableMenuItem(HMENU hMenu, int idx, int en) +{ + NSMenu *menu=(NSMenu *)hMenu; + + NSMenuItem *item; + if (en & MF_BYPOSITION) item=[menu itemAtIndex:idx]; + else item =[menu itemWithTag:idx]; + if (!item) + { + if (!(en & MF_BYPOSITION)) + { + int x; + int n=[menu numberOfItems]; + for (x = 0; x < n; x ++) + { + item=[menu itemAtIndex:x]; + if (item && [item hasSubmenu]) + { + NSMenu *m=[item submenu]; + if (m && EnableMenuItem((HMENU)m,idx,en)) return true; + } + } + } + return false; + } + [item setEnabled:((en&MF_GRAYED)?NO:YES)]; + return true; +} + +bool CheckMenuItem(HMENU hMenu, int idx, int chk) +{ + NSMenu *menu=(NSMenu *)hMenu; + if (!menu) return false; + + NSMenuItem *item; + if (chk & MF_BYPOSITION) item=[menu itemAtIndex:idx]; + else item =[menu itemWithTag:idx]; + if (!item) + { + if (!(chk & MF_BYPOSITION)) + { + int x; + int n=[menu numberOfItems]; + for (x = 0; x < n; x ++) + { + item=[menu itemAtIndex:x]; + if (item && [item hasSubmenu]) + { + NSMenu *m=[item submenu]; + if (m && CheckMenuItem((HMENU)m,idx,chk)) return true; + } + } + } + return false; + } + [item setState:((chk&MF_CHECKED)?NSOnState:NSOffState)]; + + return true; +} +HMENU SWELL_GetCurrentMenu() +{ + return (HMENU)[NSApp mainMenu]; +} + +extern int g_swell_terminating; + +void SWELL_SetCurrentMenu(HMENU hmenu) +{ + if (hmenu && [(id)hmenu isKindOfClass:[NSMenu class]]) + { + if (!g_swell_terminating) [NSApp setMainMenu:(NSMenu *)hmenu]; + } +} + +HMENU GetSubMenu(HMENU hMenu, int pos) +{ + NSMenu *menu=(NSMenu *)hMenu; + + NSMenuItem *item=menu && pos >=0 && pos < [menu numberOfItems] ? [menu itemAtIndex:pos] : 0; + if (item && [item hasSubmenu]) return (HMENU)[item submenu]; + return 0; +} + +int GetMenuItemCount(HMENU hMenu) +{ + NSMenu *menu=(NSMenu *)hMenu; + return [menu numberOfItems]; +} + +int GetMenuItemID(HMENU hMenu, int pos) +{ + NSMenu *menu=(NSMenu *)hMenu; + if (pos < 0 || pos >= [menu numberOfItems]) return 0; + + NSMenuItem *item=[menu itemAtIndex:pos]; + if (item) + { + if ([item hasSubmenu]) return -1; + return [item tag]; + } + return 0; +} + +bool SetMenuItemModifier(HMENU hMenu, int idx, int flag, int code, unsigned int mask) +{ + +#if 0 // enable this once we make SWELL_KeyToASCII decent + int n2=0; + int n1 = SWELL_KeyToASCII(code,flag,&n2); + if (n1) + { + code=n1; + flag=n2; + } +#endif + + NSMenu *menu=(NSMenu *)hMenu; + + NSMenuItem *item; + if (flag & MF_BYPOSITION) item=[menu itemAtIndex:idx]; + else item =[menu itemWithTag:idx]; + if (!item) + { + if (!(flag & MF_BYPOSITION)) + { + int x; + int n=[menu numberOfItems]; + for (x = 0; x < n; x ++) + { + item=[menu itemAtIndex:x]; + if (item && [item hasSubmenu]) + { + NSMenu *m=[item submenu]; + if (m && SetMenuItemModifier((HMENU)m,idx,flag,code,mask)) return true; + } + } + } + return false; + } + + bool suppressShift = false; + unichar arrowKey = 0; + int codelow = code&127; + if ((code>='A' && code <='Z') || + (code>='0' && code <= '9') || + ( !(mask&FVIRTKEY) && + ( + codelow == '\'' || + codelow == '/' || + codelow == '\\' || + codelow == '|' || + codelow == '"' || + codelow == ',' || + codelow == '.' || + codelow == '!' || + codelow == '?' || + codelow == '[' || + codelow == ']' + ))) + { + arrowKey=codelow; + if (!(mask & FSHIFT) && arrowKey < 256) arrowKey=tolower(arrowKey); + + if (code>='A' && code<='Z') suppressShift=true; + } + else if (code >= VK_F1 && code <= VK_F12) + { + arrowKey = NSF1FunctionKey + code - VK_F1; + } + else switch (code&0xff) + { + #define DEFKP(wink,mack) case wink: arrowKey = mack; break; + DEFKP(VK_UP,NSUpArrowFunctionKey) + DEFKP(VK_DOWN,NSDownArrowFunctionKey) + DEFKP(VK_LEFT,NSLeftArrowFunctionKey) + DEFKP(VK_RIGHT,NSRightArrowFunctionKey) + DEFKP(VK_INSERT,NSInsertFunctionKey) + DEFKP(VK_DELETE,NSDeleteCharacter) + DEFKP(VK_BACK,NSBackspaceCharacter) + DEFKP(VK_HOME,NSHomeFunctionKey) + DEFKP(VK_END,NSEndFunctionKey) + DEFKP(VK_NEXT,NSPageDownFunctionKey) + DEFKP(VK_PRIOR,NSPageUpFunctionKey) + DEFKP(VK_SUBTRACT,'-') + } + + unsigned int mask2=0; + if (mask&FALT) mask2|=NSAlternateKeyMask; + if (!suppressShift) if (mask&FSHIFT) mask2|=NSShiftKeyMask; + if (mask&FCONTROL) mask2|=NSCommandKeyMask; + if (mask&FLWIN) mask2|=NSControlKeyMask; + + [item setKeyEquivalentModifierMask:mask2]; + [item setKeyEquivalent:arrowKey?[NSString stringWithCharacters:&arrowKey length:1]:@""]; + return true; +} + +// #define SWELL_MENU_ACCOUNTING + +#ifdef SWELL_MENU_ACCOUNTING +struct menuTmp +{ + NSMenu *menu; + NSString *lbl; +}; + +WDL_PtrList allMenus; +#endif + +@implementation SWELL_Menu +- (id)copyWithZone:(NSZone *)zone +{ + id rv = [super copyWithZone:zone]; +#ifdef SWELL_MENU_ACCOUNTING + if (rv) + { + menuTmp *mt = new menuTmp; + mt->menu=(NSMenu *)rv; + NSString *lbl = [(SWELL_Menu *)rv title]; + mt->lbl = lbl; + [lbl retain]; + allMenus.Add(mt); + NSLog(@"copy menu, new count=%d lbl=%@\n",allMenus.GetSize(),lbl); + } +#endif + return rv; +} +-(void)dealloc +{ +#ifdef SWELL_MENU_ACCOUNTING + int x; + bool f=false; + for(x=0;xmenu == self) + { + NSLog(@"dealloc menu, found self %@\n",allMenus.Get(x)->lbl); + allMenus.Delete(x); + f=true; + break; + } + } + + NSLog(@"dealloc menu, new count=%d %@\n",allMenus.GetSize(), [self title]); + if (!f) + { + NSLog(@"deleting unfound menu!!\n"); + } +#endif + [super dealloc]; +} +@end + +HMENU CreatePopupMenu() +{ + return CreatePopupMenuEx(NULL); +} +HMENU CreatePopupMenuEx(const char *title) +{ + SWELL_Menu *m; + if (title) + { + char buf[1024]; + __filtnametobuf(buf,title,sizeof(buf)); + NSString *lbl=(NSString *)SWELL_CStringToCFString(buf); + m=[[SWELL_Menu alloc] initWithTitle:lbl]; +#ifdef SWELL_MENU_ACCOUNTING + menuTmp *mt = new menuTmp; + mt->menu=m; + mt->lbl = lbl; + [lbl retain]; + allMenus.Add(mt); + NSLog(@"alloc menu, new count=%d lbl=%@\n",allMenus.GetSize(),lbl); +#endif + [lbl release]; + } + else + { + m=[[SWELL_Menu alloc] init]; +#ifdef SWELL_MENU_ACCOUNTING + menuTmp *mt = new menuTmp; + mt->menu=m; + mt->lbl = @""; + allMenus.Add(mt); + NSLog(@"alloc menu, new count=%d lbl=%@\n",allMenus.GetSize(),@""); +#endif + } + [m setAutoenablesItems:NO]; + + return (HMENU)m; +} + +void DestroyMenu(HMENU hMenu) +{ + if (hMenu) + { + SWELL_SetMenuDestination(hMenu,NULL); + NSMenu *m=(NSMenu *)hMenu; + [m release]; + } +} + + + +int AddMenuItem(HMENU hMenu, int pos, const char *name, int tagid) +{ + if (!hMenu) return -1; + NSMenu *m=(NSMenu *)hMenu; + NSString *label=(NSString *)SWELL_CStringToCFString(name); + NSMenuItem *item=[m insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; + [label release]; + [item setTag:tagid]; + [item setEnabled:YES]; + return 0; +} + +bool DeleteMenu(HMENU hMenu, int idx, int flag) +{ + if (!hMenu) return false; + NSMenu *m=(NSMenu *)hMenu; + NSMenuItem *item=NULL; + + if (flag&MF_BYPOSITION) + { + if (idx >=0 && idx < [m numberOfItems]) + item=[m itemAtIndex:idx]; + if (!item) return false; + } + else + { + item=[m itemWithTag:idx]; + if (!item) + { + int x,n=[m numberOfItems]; + for (x=0;xfMask & MIIM_SUBMENU) && mi->hSubMenu) // do this before MIIM_TYPE so we title the submenu properly + { + [m setSubmenu:(NSMenu*)mi->hSubMenu forItem:item]; + [((NSMenu*)mi->hSubMenu) release]; // let the parent menu free it + } + if (mi->fMask & MIIM_TYPE) + { + if (mi->fType == MFT_STRING && mi->dwTypeData) + { + char buf[1024]; + __filtnametobuf(buf,mi->dwTypeData?mi->dwTypeData:"(null)",sizeof(buf)); + NSString *label=(NSString *)SWELL_CStringToCFString(buf); + + [item setTitle:label]; + if ([item hasSubmenu] && [item submenu]) [[item submenu] setTitle:label]; + + [label release]; + } + } + if (mi->fMask & MIIM_STATE) + { + [item setState:((mi->fState&MFS_CHECKED)?NSOnState:NSOffState)]; + [item setEnabled:((mi->fState&MFS_GRAYED)?NO:YES)]; + } + if (mi->fMask & MIIM_ID) + { + [item setTag:mi->wID]; + } + if (mi->fMask & MIIM_DATA) + { + SWELL_DataHold* newh = [[SWELL_DataHold alloc] initWithVal:(void*)mi->dwItemData]; + [item setRepresentedObject:newh]; + [newh release]; + } + + return true; +} + +BOOL GetMenuItemInfo(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) +{ + if (!hMenu) return 0; + NSMenu *m=(NSMenu *)hMenu; + NSMenuItem *item; + if (byPos) + { + item=[m itemAtIndex:pos]; + } + else item=[m itemWithTag:pos]; + + if (!item) + { + if (!byPos) + { + int x; + int n=[m numberOfItems]; + for (x = 0; x < n; x ++) + { + item=[m itemAtIndex:x]; + if (item && [item hasSubmenu]) + { + NSMenu *m1=[item submenu]; + if (m1 && GetMenuItemInfo((HMENU)m1,pos,byPos,mi)) return true; + } + } + } + return 0; + } + + if (mi->fMask & MIIM_TYPE) + { + if ([item isSeparatorItem]) mi->fType = MFT_SEPARATOR; + else + { + mi->fType = MFT_STRING; + if (mi->dwTypeData && mi->cch) + { + mi->dwTypeData[0]=0; + SWELL_CFStringToCString([item title], (char *)mi->dwTypeData, mi->cch); + } + } + } + + if (mi->fMask & MIIM_DATA) + { + SWELL_DataHold *h=[item representedObject]; + mi->dwItemData = (INT_PTR)(h && [h isKindOfClass:[SWELL_DataHold class]]? [h getValue] : 0); + } + + if (mi->fMask & MIIM_STATE) + { + mi->fState=0; + if ([item state]) mi->fState|=MFS_CHECKED; + if (![item isEnabled]) mi->fState|=MFS_GRAYED; + } + + if (mi->fMask & MIIM_ID) + { + mi->wID = [item tag]; + } + + if(mi->fMask & MIIM_SUBMENU) + { + if ([item hasSubmenu]) + { + mi->hSubMenu = (HMENU)[item submenu]; + } + } + + return 1; + +} + +void SWELL_InsertMenu(HMENU menu, int pos, int flag, UINT_PTR idx, const char *str) +{ + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + (flag & ~MF_BYPOSITION),(flag&MF_POPUP) ? 0 : (int)idx,NULL,NULL,NULL,0,(char *)str}; + + if (flag&MF_POPUP) + { + mi.hSubMenu = (HMENU)idx; + mi.fMask |= MIIM_SUBMENU; + mi.fState &= ~MF_POPUP; + } + + if (flag&MF_SEPARATOR) + { + mi.fMask=MIIM_TYPE; + mi.fType=MFT_SEPARATOR; + mi.fState &= ~MF_SEPARATOR; + } + + if (flag&MF_BITMAP) + { + mi.fType=MFT_BITMAP; + mi.fState &= ~MF_BITMAP; + } + + InsertMenuItem(menu,pos,(flag&MF_BYPOSITION) ? TRUE : FALSE, &mi); +} + + +void InsertMenuItem(HMENU hMenu, int pos, BOOL byPos, MENUITEMINFO *mi) +{ + if (!hMenu) return; + NSMenu *m=(NSMenu *)hMenu; + NSMenuItem *item; + int ni=[m numberOfItems]; + + if (!byPos) + { + pos = [m indexOfItemWithTag:pos]; + } + if (pos < 0 || pos > ni) pos=ni; + + NSString *label=0; + if (mi->fType == MFT_STRING) + { + char buf[1024]; + __filtnametobuf(buf,mi->dwTypeData?mi->dwTypeData:"(null)",sizeof(buf)); + label=(NSString *)SWELL_CStringToCFString(buf); + item=[m insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; + } + else if (mi->fType == MFT_BITMAP) + { + item=[m insertItemWithTitle:@"(no image)" action:NULL keyEquivalent:@"" atIndex:pos]; + if (mi->dwTypeData) + { + NSImage *i=(NSImage *)GetNSImageFromHICON((HICON)mi->dwTypeData); + if (i) + { + [item setImage:i]; + [item setTitle:@""]; + } + } + } + else + { + item = [NSMenuItem separatorItem]; + [m insertItem:item atIndex:pos]; + } + + if ((mi->fMask & MIIM_SUBMENU) && mi->hSubMenu) + { + if (label) [(NSMenu *)mi->hSubMenu setTitle:label]; + [m setSubmenu:(NSMenu *)mi->hSubMenu forItem:item]; + [((NSMenu *)mi->hSubMenu) release]; // let the parent menu free it + } + if (label) [label release]; + + if (!ni) [m setAutoenablesItems:NO]; + [item setEnabled:YES]; + + if (mi->fMask & MIIM_STATE) + { + if (mi->fState&MFS_GRAYED) + { + [item setEnabled:NO]; + } + if (mi->fState&MFS_CHECKED) + { + [item setState:NSOnState]; + } + } + + if (mi->fMask & MIIM_DATA) + { + SWELL_DataHold *h=[[SWELL_DataHold alloc] initWithVal:(void*)mi->dwItemData]; + [item setRepresentedObject:h]; + [h release]; + } + else + { + [item setRepresentedObject:nil]; + } + + if (mi->fMask & MIIM_ID) + { + [item setTag:mi->wID]; + } + + NSMenuItem *fi=[m itemAtIndex:0]; + if (fi && fi != item) + { + if ([fi action]) [item setAction:[fi action]]; + if ([fi target]) [item setTarget:[fi target]]; + } +} + + + +@implementation SWELL_PopupMenuRecv +-(id) initWithWnd:(HWND)wnd +{ + if ((self = [super init])) + { + cbwnd=wnd; + m_act=0; + } + return self; +} + +-(void) onSwellCommand:(id)sender +{ + int tag=[sender tag]; + if (tag) + m_act=tag; +} + +-(int) isCommand +{ + return m_act; +} + +- (void)menuNeedsUpdate:(NSMenu *)menu +{ + if (cbwnd) + { + SendMessage(cbwnd,WM_INITMENUPOPUP,(WPARAM)menu,0); + SWELL_SetMenuDestination((HMENU)menu,(HWND)self); + } +} + +@end + +void SWELL_SetMenuDestination(HMENU menu, HWND hwnd) +{ + if (!menu || (hwnd && ![(id)hwnd respondsToSelector:@selector(onSwellCommand:)])) return; + + NSMenu *m=(NSMenu *)menu; + [m setDelegate:(id)hwnd]; + int x,n=[m numberOfItems]; + for (x = 0; x < n; x++) + { + NSMenuItem *item=[m itemAtIndex:x]; + if (item) + { + if ([item hasSubmenu]) + { + NSMenu *mm=[item submenu]; + if (mm) SWELL_SetMenuDestination((HMENU)mm,hwnd); + } + else + { + if ([item tag]) + { + [item setTarget:(id)hwnd]; + if (hwnd) [item setAction:@selector(onSwellCommand:)]; + } + } + } + } +} + +int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r) +{ + if (hMenu) + { + NSMenu *m=(NSMenu *)hMenu; + NSView *v=(NSView *)hwnd; + if (v && [v isKindOfClass:[NSWindow class]]) v=[(NSWindow *)v contentView]; + if (!v) v=[[NSApp mainWindow] contentView]; + if (!v) return 0; + + NSEvent *event = [NSApp currentEvent]; + + { + //create a new event at these coordinates, faking it + NSWindow *w = [v window]; + NSPoint pt = NSMakePoint(xpos, ypos); + pt=[w convertScreenToBase:pt]; + pt.y -= 4; + int wn = [w windowNumber]; // event ? [event windowNumber] : [w windowNumber]; + NSTimeInterval ts = event ? [event timestamp] : 0; + NSGraphicsContext *gctx = event ? [event context] : 0; + event = [NSEvent otherEventWithType:NSApplicationDefined location:pt modifierFlags:0 timestamp:ts windowNumber:wn context:gctx subtype:0 data1:0 data2:0]; + } + + SWELL_PopupMenuRecv *recv = [[SWELL_PopupMenuRecv alloc] initWithWnd:((flags & TPM_NONOTIFY) ? 0 : hwnd)]; + + SWELL_SetMenuDestination((HMENU)m,(HWND)recv); + + if (!(flags&TPM_NONOTIFY)&&hwnd) + { + SendMessage(hwnd,WM_INITMENUPOPUP,(WPARAM)m,0); + SWELL_SetMenuDestination((HMENU)m,(HWND)recv); + } + + [NSMenu popUpContextMenu:m withEvent:event forView:v]; + + int ret=[recv isCommand]; + SWELL_SetMenuDestination((HMENU)m,(HWND)NULL); + [recv release]; + + if (ret<=0) return 0; + + if (flags & TPM_RETURNCMD) return ret; + + if (hwnd) SendMessage(hwnd,WM_COMMAND,ret,0); + + return 1; + } + return 0; +} + + + + +void SWELL_Menu_AddMenuItem(HMENU hMenu, const char *name, int idx, int flags) +{ + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + (flags)?MFS_GRAYED:0,idx,NULL,NULL,NULL,0,(char *)name}; + if (!name) + { + mi.fType = MFT_SEPARATOR; + mi.fMask&=~(MIIM_STATE|MIIM_ID); + } + InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); +} + +int SWELL_GenerateMenuFromList(HMENU hMenu, const void *_list, int listsz) +{ + SWELL_MenuGen_Entry *list = (SWELL_MenuGen_Entry *)_list; + const int l1=strlen(SWELL_MENUGEN_POPUP_PREFIX); + while (listsz>0) + { + int cnt=1; + if (!list->name) SWELL_Menu_AddMenuItem(hMenu,NULL,-1,0); + else if (!strcmp(list->name,SWELL_MENUGEN_ENDPOPUP)) break; + else if (!strncmp(list->name,SWELL_MENUGEN_POPUP_PREFIX,l1)) + { + MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_STATE|MIIM_TYPE,MFT_STRING,0,0,CreatePopupMenuEx(list->name+l1),NULL,NULL,0,(char *)list->name+l1}; + cnt += SWELL_GenerateMenuFromList(mi.hSubMenu,list+1,listsz-1); + InsertMenuItem(hMenu,GetMenuItemCount(hMenu),TRUE,&mi); + } + else SWELL_Menu_AddMenuItem(hMenu,list->name,list->idx,list->flags); + + list+=cnt; + listsz -= cnt; + } + return list + 1 - (SWELL_MenuGen_Entry *)_list; +} + + +SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; // todo: move to per-module thingy + +static SWELL_MenuResourceIndex *resById(SWELL_MenuResourceIndex *head, const char *resid) +{ + SWELL_MenuResourceIndex *p=head; + while (p) + { + if (p->resid == resid) return p; + p=p->_next; + } + return 0; +} + +HMENU SWELL_LoadMenu(SWELL_MenuResourceIndex *head, const char *resid) +{ + SWELL_MenuResourceIndex *p; + + if (!(p=resById(head,resid))) return 0; + HMENU hMenu=CreatePopupMenu(); + if (hMenu) p->createFunc(hMenu); + return hMenu; +} + +HMENU SWELL_DuplicateMenu(HMENU menu) +{ + if (!menu) return 0; + NSMenu *ret = (NSMenu *)[(NSMenu *)menu copy]; + return (HMENU)ret; +} + +BOOL SetMenu(HWND hwnd, HMENU menu) +{ + if (!hwnd||![(id)hwnd respondsToSelector:@selector(swellSetMenu:)]) return FALSE; + if (g_swell_terminating) return FALSE; + + [(id)hwnd swellSetMenu:(HMENU)menu]; + NSWindow *nswnd = (NSWindow *)hwnd; + if ([nswnd isKindOfClass:[NSWindow class]] || + ([nswnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)nswnd window]) && hwnd == (HWND)[nswnd contentView])) + { + if ([NSApp keyWindow]==nswnd && + [NSApp mainMenu] != (NSMenu *)menu) + { + [NSApp setMainMenu:(NSMenu *)menu]; + if (menu) SendMessage(hwnd,WM_INITMENUPOPUP,(WPARAM)menu,0); // find a better place for this! TODO !!! + } + } + + return TRUE; +} + +HMENU GetMenu(HWND hwnd) +{ + if (!hwnd) return NULL; + if ([(id)hwnd isKindOfClass:[NSWindow class]]) hwnd = (HWND)[(NSWindow *)hwnd contentView]; + if ([(id)hwnd respondsToSelector:@selector(swellGetMenu)]) return (HMENU) [(id)hwnd swellGetMenu]; + return NULL; +} + +void DrawMenuBar(HWND hwnd) +{ +} + + +#endif diff --git a/WDL/swell/swell-menugen.h b/WDL/swell/swell-menugen.h new file mode 100644 index 00000000..5bf1baf3 --- /dev/null +++ b/WDL/swell/swell-menugen.h @@ -0,0 +1,94 @@ +#ifndef _SWELL_MENUGEN_H_ +#define _SWELL_MENUGEN_H_ + + +/** + SWELL - (Simple Windows Emulation Layer Library) + Copyright (C) 2006 and later, Cockos Incorporated. + Dynamic menu generation + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Usage: + + See: mac_resgen.php etc + + */ + + +#include "swell.h" + + +#ifdef BEGIN +#undef BEGIN +#endif + +#ifdef END +#undef END +#endif + + +typedef struct SWELL_MenuResourceIndex +{ + const char *resid; + void (*createFunc)(HMENU hMenu); + struct SWELL_MenuResourceIndex *_next; +} SWELL_MenuResourceIndex; +extern SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; + + +#define SWELL_MENUGEN_POPUP_PREFIX "/.BO^O:" +#define SWELL_MENUGEN_ENDPOPUP "EN%%%^:" +struct SWELL_MenuGen_Entry +{ + const char *name; // will begin with SWELL_MENUGEN_POPUP_PREFIX on submenus, and will be SWELL_MENUGEN_ENDPOPUP at the end of a submenu + unsigned short idx; + unsigned short flags; +}; + +class SWELL_MenuGenHelper +{ + public: + SWELL_MenuResourceIndex m_rec; + SWELL_MenuGenHelper(SWELL_MenuResourceIndex **h, void (*cf)(HMENU), int recid) + { + m_rec.resid=MAKEINTRESOURCE(recid); + m_rec.createFunc=cf; + m_rec._next=*h; + *h = &m_rec; + } +}; + +#define SWELL_DEFINE_MENU_RESOURCE_BEGIN(recid) \ + static void __swell_menu_cf__##recid(HMENU hMenu); \ + static SWELL_MenuGenHelper __swell_menu_cf_helper__##recid(&SWELL_curmodule_menuresource_head, __swell_menu_cf__##recid, recid); \ + static void __swell_menu_cf__##recid(HMENU hMenu) { static const SWELL_MenuGen_Entry list[]={{NULL,0,0 + +#define SWELL_DEFINE_MENU_RESOURCE_END(recid) } }; SWELL_GenerateMenuFromList(hMenu,list+1,sizeof(list)/sizeof(list[0])-1); } + + +#define GRAYED 1 +#define INACTIVE 2 +#define POPUP }, { SWELL_MENUGEN_POPUP_PREFIX +#define MENUITEM }, { +#define SEPARATOR NULL, -1 +#define BEGIN +#define END }, { SWELL_MENUGEN_ENDPOPUP + +#endif//_SWELL_MENUGEN_H_ + diff --git a/WDL/swell/swell-misc-generic.cpp b/WDL/swell/swell-misc-generic.cpp new file mode 100644 index 00000000..fb5fff1a --- /dev/null +++ b/WDL/swell/swell-misc-generic.cpp @@ -0,0 +1,20 @@ +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-internal.h" + +HANDLE SWELL_CreateProcess(const char *exe, int nparams, const char **params) +{ + return 0; // todo +} +bool IsRightClickEmulateEnabled() +{ + return false; +} + +void SWELL_EnableRightClickEmulate(BOOL enable) +{ +} + + +#endif diff --git a/WDL/swell/swell-misc.mm b/WDL/swell/swell-misc.mm new file mode 100644 index 00000000..9c9aa4ba --- /dev/null +++ b/WDL/swell/swell-misc.mm @@ -0,0 +1,566 @@ +#ifndef SWELL_PROVIDED_BY_APP + +//#import +#import +#include "swell.h" +#include "swell-internal.h" + +#include "../mutex.h" + +HWND g_swell_only_timerhwnd; + +@implementation SWELL_TimerFuncTarget + +-(id) initWithId:(UINT_PTR)tid hwnd:(HWND)h callback:(TIMERPROC)cb +{ + if ((self = [super init])) + { + m_hwnd=h; + m_cb=cb; + m_timerid = tid; + } + return self; +} +-(void)SWELL_Timer:(id)sender +{ + if (g_swell_only_timerhwnd && m_hwnd != g_swell_only_timerhwnd) return; + + m_cb(m_hwnd,WM_TIMER,m_timerid,GetTickCount()); +} +@end + +@implementation SWELL_DataHold +-(id) initWithVal:(void *)val +{ + if ((self = [super init])) + { + m_data=val; + } + return self; +} +-(void *) getValue +{ + return m_data; +} +@end + +void SWELL_CFStringToCString(const void *str, char *buf, int buflen) +{ + NSString *s = (NSString *)str; + if (buflen>0) *buf=0; + if (buflen <= 1 || !s || [s getCString:buf maxLength:buflen encoding:NSUTF8StringEncoding]) return; // should always work, I'd hope (ambiguous documentation ugh) + + NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; + if (!data) + { + [s getCString:buf maxLength:buflen-1]; + return; + } + int len = [data length]; + if (len > buflen-1) len=buflen-1; + [data getBytes:buf length:len]; + buf[len]=0; +} + +void *SWELL_CStringToCFString(const char *str) +{ + if (!str) str=""; + void *ret; + + ret=(void *)CFStringCreateWithCString(NULL,str,kCFStringEncodingUTF8); + if (ret) return ret; + ret=(void*)CFStringCreateWithCString(NULL,str,kCFStringEncodingASCII); + return ret; +} + +void SWELL_MakeProcessFront(HANDLE h) +{ + SWELL_InternalObjectHeader_NSTask *buf = (SWELL_InternalObjectHeader_NSTask*)h; + if (buf && buf->hdr.type == INTERNAL_OBJECT_NSTASK && buf->task) + { + ProcessSerialNumber psn; + + int pid=[(id)buf->task processIdentifier]; + // try for 1sec to get the PSN, if it fails + int n = 20; + while (GetProcessForPID(pid,&psn) != noErr && n-- > 0) + { + Sleep(50); + } + if (n>0) SetFrontProcess(&psn); + } +} + +void SWELL_ReleaseNSTask(void *p) +{ + NSTask *a =(NSTask*)p; + [a release]; +} +DWORD SWELL_WaitForNSTask(void *p, DWORD msTO) +{ + NSTask *a =(NSTask*)p; + DWORD t = msTO ? GetTickCount()+msTO : 0; + do + { + if (![a isRunning]) return WAIT_OBJECT_0; + if (t) Sleep(1); + } + while (GetTickCount()hdr.type = INTERNAL_OBJECT_NSTASK; + buf->hdr.count=1; + buf->task = tsk; + return buf; +} + + +@implementation SWELL_ThreadTmp +-(void)bla:(id)obj +{ + if (a) + { + DWORD (*func)(void *); + *(void **)(&func) = a; + func(b); + } + [NSThread exit]; +} +@end + +void SWELL_EnsureMultithreadedCocoa() +{ + static int a; + if (!a) + { + a++; + if (![NSThread isMultiThreaded]) // force cocoa into multithreaded mode + { + SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init]; + t->a=0; + t->b=0; + [NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t]; + /// [t release]; + } + } +} + +void CreateThreadNS(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut) +{ + SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init]; + t->a=(void*)ThreadProc; + t->b=parm; + return [NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t]; +} + + +// used by swell.cpp (lazy these should go elsewhere) +void *SWELL_InitAutoRelease() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + return (void *)pool; +} +void SWELL_QuitAutoRelease(void *p) +{ + if (p) + [(NSAutoreleasePool*)p release]; +} + +// timer stuff +typedef struct TimerInfoRec +{ + UINT_PTR timerid; + HWND hwnd; + NSTimer *timer; + struct TimerInfoRec *_next; +} TimerInfoRec; +static TimerInfoRec *m_timer_list; +static WDL_Mutex m_timermutex; +static pthread_t m_pmq_mainthread; +static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc); + +UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) +{ + if (!hwnd && !tProc) return 0; // must have either callback or hwnd + + if (hwnd && !timerid) return 0; + + if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) + { + SWELL_pmq_settimer(hwnd,timerid,(rate==(UINT)-1)?((UINT)-2):rate,tProc); + return timerid; + } + + + if (hwnd && ![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) + { + if (![(id)hwnd isKindOfClass:[NSWindow class]]) return 0; + hwnd=(HWND)[(id)hwnd contentView]; + if (![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) return 0; + } + + WDL_MutexLock lock(&m_timermutex); + TimerInfoRec *rec=NULL; + if (hwnd||timerid) + { + rec = m_timer_list; + while (rec) + { + if (rec->timerid == timerid && rec->hwnd == hwnd) // works for both kinds + break; + rec=rec->_next; + } + } + + bool recAdd=false; + if (!rec) + { + rec=(TimerInfoRec*)malloc(sizeof(TimerInfoRec)); + recAdd=true; + } + else + { + [rec->timer invalidate]; + rec->timer=0; + } + + rec->timerid=timerid; + rec->hwnd=hwnd; + + if (!hwnd || tProc) + { + // set timer to this unique ptr + if (!hwnd) timerid = rec->timerid = (UINT_PTR)rec; + + SWELL_TimerFuncTarget *t = [[SWELL_TimerFuncTarget alloc] initWithId:timerid hwnd:hwnd callback:tProc]; + rec->timer = [NSTimer scheduledTimerWithTimeInterval:(max(rate,1)*0.001) target:t selector:@selector(SWELL_Timer:) + userInfo:t repeats:YES]; + [t release]; + + } + else + { + SWELL_DataHold *t=[[SWELL_DataHold alloc] initWithVal:(void *)timerid]; + rec->timer = [NSTimer scheduledTimerWithTimeInterval:(max(rate,1)*0.001) target:(id)hwnd selector:@selector(SWELL_Timer:) + userInfo:t repeats:YES]; + + [t release]; + } + [[NSRunLoop currentRunLoop] addTimer:rec->timer forMode:(NSString*)kCFRunLoopCommonModes]; + + if (recAdd) + { + rec->_next=m_timer_list; + m_timer_list=rec; + } + + return timerid; +} +void SWELL_RunRunLoop(int ms) +{ + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]]; +} +void SWELL_RunRunLoopEx(int ms, HWND hwndOnlyTimer) +{ + HWND h=g_swell_only_timerhwnd; + g_swell_only_timerhwnd = hwndOnlyTimer; + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]]; + if (g_swell_only_timerhwnd == hwndOnlyTimer) g_swell_only_timerhwnd = h; +} + +BOOL KillTimer(HWND hwnd, UINT_PTR timerid) +{ + if (!hwnd && !timerid) return FALSE; + + WDL_MutexLock lock(&m_timermutex); + if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) + { + SWELL_pmq_settimer(hwnd,timerid,~(UINT)0,NULL); + return TRUE; + } + BOOL rv=FALSE; + + // don't allow removing all global timers + if (timerid!=~(UINT_PTR)0 || hwnd) + { + TimerInfoRec *rec = m_timer_list, *lrec=NULL; + while (rec) + { + + if (rec->hwnd == hwnd && (timerid==~(UINT_PTR)0 || rec->timerid == timerid)) + { + TimerInfoRec *nrec = rec->_next; + + // remove self from list + if (lrec) lrec->_next = nrec; + else m_timer_list = nrec; + + [rec->timer invalidate]; + free(rec); + + rv=TRUE; + if (timerid!=~(UINT_PTR)0) break; + + rec=nrec; + } + else + { + lrec=rec; + rec=rec->_next; + } + } + } + return rv; +} + + + +///////// PostMessage emulation + +BOOL PostMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + id del=[NSApp delegate]; + if (del && [del respondsToSelector:@selector(swellPostMessage:msg:wp:lp:)]) + return !![(SWELL_DelegateExtensions*)del swellPostMessage:hwnd msg:message wp:wParam lp:lParam]; + return FALSE; +} + +void SWELL_MessageQueue_Clear(HWND h) +{ + id del=[NSApp delegate]; + if (del && [del respondsToSelector:@selector(swellPostMessageClearQ:)]) + [(SWELL_DelegateExtensions*)del swellPostMessageClearQ:h]; +} + + + +// implementation of postmessage stuff + + + +typedef struct PMQ_rec +{ + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; + + struct PMQ_rec *next; + bool is_special_timer; // if set, then msg=interval(-1 for kill),wParam=timer id, lParam = timerproc +} PMQ_rec; + +static WDL_Mutex *m_pmq_mutex; +static PMQ_rec *m_pmq, *m_pmq_empty, *m_pmq_tail; +static int m_pmq_size; +static id m_pmq_timer; +#define MAX_POSTMESSAGE_SIZE 1024 + +void SWELL_Internal_PostMessage_Init() +{ + if (m_pmq_mutex) return; + id del = [NSApp delegate]; + if (!del || ![del respondsToSelector:@selector(swellPostMessageTick:)]) return; + + m_pmq_mainthread=pthread_self(); + m_pmq_mutex = new WDL_Mutex; + + m_pmq_timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:(id)del selector:@selector(swellPostMessageTick:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:m_pmq_timer forMode:(NSString*)kCFRunLoopCommonModes]; + // [ release]; + // set a timer to the delegate +} + + +void SWELL_MessageQueue_Flush() +{ + if (!m_pmq_mutex) return; + + m_pmq_mutex->Enter(); + PMQ_rec *p=m_pmq, *startofchain=m_pmq; + m_pmq=m_pmq_tail=0; + m_pmq_mutex->Leave(); + + int cnt=0; + // process out queue + while (p) + { + if (p->is_special_timer) + { + if (p->msg == ~(UINT)0) KillTimer(p->hwnd,p->wParam); + else SetTimer(p->hwnd,p->wParam,p->msg,(TIMERPROC)p->lParam); + } + else + SendMessage(p->hwnd,p->msg,p->wParam,p->lParam); + + cnt ++; + if (!p->next) // add the chain back to empties + { + m_pmq_mutex->Enter(); + m_pmq_size-=cnt; + p->next=m_pmq_empty; + m_pmq_empty=startofchain; + m_pmq_mutex->Leave(); + break; + } + p=p->next; + } +} + +void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd) +{ + if (!m_pmq_mutex) return; + + m_pmq_mutex->Enter(); + PMQ_rec *p=m_pmq; + PMQ_rec *lastrec=NULL; + while (p) + { + if (hwnd && p->hwnd != hwnd) { lastrec=p; p=p->next; } + else + { + PMQ_rec *next=p->next; + + p->next=m_pmq_empty; // add p to empty list + m_pmq_empty=p; + m_pmq_size--; + + + if (p==m_pmq_tail) m_pmq_tail=lastrec; // update tail + + if (lastrec) p = lastrec->next = next; + else p = m_pmq = next; + } + } + m_pmq_mutex->Leave(); +} + +static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc) +{ + if (!h||!m_pmq_mutex) return; + WDL_MutexLock lock(m_pmq_mutex); + + PMQ_rec *rec=m_pmq; + while (rec) + { + if (rec->is_special_timer && rec->hwnd == h && rec->wParam == timerid) + { + rec->msg = rate; // adjust to new rate + rec->lParam = (LPARAM)tProc; + return; + } + rec=rec->next; + } + + rec=m_pmq_empty; + if (rec) m_pmq_empty=rec->next; + else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); + rec->next=0; + rec->hwnd=h; + rec->msg=rate; + rec->wParam=timerid; + rec->lParam=(LPARAM)tProc; + rec->is_special_timer=true; + + if (m_pmq_tail) m_pmq_tail->next=rec; + else + { + PMQ_rec *p=m_pmq; + while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety + if (p) p->next=rec; + else m_pmq=rec; + } + m_pmq_tail=rec; + m_pmq_size++; +} + +BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (!hwnd||!m_pmq_mutex) return FALSE; + if (![(id)hwnd respondsToSelector:@selector(swellCanPostMessage)]) return FALSE; + + BOOL ret=FALSE; + m_pmq_mutex->Enter(); + + if ((m_pmq_empty||m_pmq_sizenext; + else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); + rec->next=0; + rec->hwnd=hwnd; + rec->msg=msg; + rec->wParam=wParam; + rec->lParam=lParam; + rec->is_special_timer=false; + + if (m_pmq_tail) m_pmq_tail->next=rec; + else + { + PMQ_rec *p=m_pmq; + while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety + if (p) p->next=rec; + else m_pmq=rec; + } + m_pmq_tail=rec; + m_pmq_size++; + + ret=TRUE; + } + + m_pmq_mutex->Leave(); + + return ret; +} + + +static bool s_rightclickemulate=true; + +bool IsRightClickEmulateEnabled() +{ + return s_rightclickemulate; +} + +void SWELL_EnableRightClickEmulate(BOOL enable) +{ + s_rightclickemulate=enable; +} + + +#endif diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp new file mode 100644 index 00000000..7c9374d5 --- /dev/null +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -0,0 +1,184 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic APIs for browsing for files, directories, and messageboxes. + + These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. + + */ + + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-internal.h" +#include "swell-dlggen.h" + +static const char *BFSF_Templ_dlgid; +static DLGPROC BFSF_Templ_dlgproc; +static struct SWELL_DialogResourceIndex *BFSF_Templ_reshead; +void BrowseFile_SetTemplate(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) +{ + BFSF_Templ_reshead=reshead; + BFSF_Templ_dlgid=dlgid; + BFSF_Templ_dlgproc=dlgProc; +} + +// return true +bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, + char *fn, int fnsize) +{ + return false; +} + +bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) +{ + return false; +} + + +char *BrowseForFiles(const char *text, const char *initialdir, + const char *initialfile, bool allowmul, const char *extlist) +{ + return NULL; +} + + +static LRESULT WINAPI swellMessageBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + if (lParam) // swell-specific + { + SetWindowLong(hwnd,GWL_WNDPROC,(LPARAM)SwellDialogDefaultWindowProc); + SetWindowLong(hwnd,DWL_DLGPROC,(LPARAM)swellMessageBoxProc); + void **parms = (void **)lParam; + if (parms[1]) SetWindowText(hwnd,(const char*)parms[1]); + + + int nbuttons=1; + const char *buttons[3] = { "OK", "", "" }; + int button_ids[3] = {IDOK,0,0}; + int button_sizes[3]; + + int mode = ((int)(INT_PTR)parms[2]); + if (mode == MB_RETRYCANCEL) { buttons[0]="Retry"; button_ids[0]=IDRETRY; } + if (mode == MB_YESNO || mode == MB_YESNOCANCEL) { buttons[0]="Yes"; button_ids[0] = IDYES; buttons[nbuttons] = "No"; button_ids[nbuttons] = IDNO; nbuttons++; } + if (mode == MB_OKCANCEL || mode == MB_YESNOCANCEL || mode == MB_RETRYCANCEL) { buttons[nbuttons] = "Cancel"; button_ids[nbuttons] = IDCANCEL; nbuttons++; } + + SWELL_MakeSetCurParms(1,1,0,0,hwnd,false,false); + RECT labsize = {0,0,300,20}; + HWND lab = SWELL_MakeLabel(-1,parms[0] ? (const char *)parms[0] : "", 0, 0,0,10,10,SS_CENTER); //we'll resize this manually + HDC dc=GetDC(lab); + if (lab && parms[0]) + { + DrawText(dc,(const char *)parms[0],-1,&labsize,DT_CALCRECT);// if dc isnt valid yet, try anyway + } + labsize.top += 10; + labsize.bottom += 18; + + int x; + const int button_spacing = 8; + int button_height=0, button_total_w=0;; + for (x = 0; x < nbuttons; x ++) + { + RECT r={0,0,35,12}; + DrawText(dc,buttons[x],-1,&r,DT_CALCRECT|DT_SINGLELINE); + button_sizes[x] = r.right-r.left + 8; + button_total_w += button_sizes[x] + (x ? button_spacing : 0); + if (r.bottom-r.top+10 > button_height) button_height = r.bottom-r.top+10; + } + + if (labsize.right < button_total_w+16) labsize.right = button_total_w+16; + + int xpos = labsize.right/2 - button_total_w/2; + for (x = 0; x < nbuttons; x ++) + { + SWELL_MakeButton(0,buttons[x],button_ids[x],xpos,labsize.bottom,button_sizes[x],button_height,0); + xpos += button_sizes[x] + button_spacing; + } + + if (dc) ReleaseDC(lab,dc); + SWELL_MakeSetCurParms(1,1,0,0,NULL,false,false); + if (lab) SetWindowPos(lab,NULL,0,0,labsize.right,labsize.bottom,SWP_NOACTIVATE|SWP_NOZORDER); + SetWindowPos(hwnd,NULL,0,0,labsize.right,labsize.bottom + button_height + 8,SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); + } + break; + case WM_COMMAND: + if (LOWORD(wParam) && HIWORD(wParam) == BN_CLICKED ) EndDialog(hwnd,LOWORD(wParam)); + break; + case WM_CLOSE: + if (GetDlgItem(hwnd,IDCANCEL)) EndDialog(hwnd,IDCANCEL); + else if (GetDlgItem(hwnd,IDNO)) EndDialog(hwnd,IDNO); + else if (GetDlgItem(hwnd,IDYES)) EndDialog(hwnd,IDYES); + else EndDialog(hwnd,IDOK); + break; + } + return 0; +} + +int MessageBox(HWND hwndParent, const char *text, const char *caption, int type) +{ + printf("MessageBox: %s %s\n",text,caption); + const void *parms[3]= {text,caption,(void*)(INT_PTR)type} ; + return DialogBoxParam(NULL,NULL,NULL,swellMessageBoxProc,(LPARAM)parms); + +#if 0 + int ret=0; + + if (type == MB_OK) + { + // todo + ret=IDOK; + } + else if (type == MB_OKCANCEL) + { + ret = 1; // todo + if (ret) ret=IDOK; + else ret=IDCANCEL; + } + else if (type == MB_YESNO) + { + ret = 1 ; // todo + if (ret) ret=IDYES; + else ret=IDNO; + } + else if (type == MB_RETRYCANCEL) + { + ret = 1; // todo + + if (ret) ret=IDRETRY; + else ret=IDCANCEL; + } + else if (type == MB_YESNOCANCEL) + { + ret = 1; // todo + + if (ret == 1) ret=IDYES; + else if (ret==-1) ret=IDNO; + else ret=IDCANCEL; + } + + return ret; +#endif +} + +#endif diff --git a/WDL/swell/swell-miscdlg-gtk.cpp b/WDL/swell/swell-miscdlg-gtk.cpp new file mode 100644 index 00000000..523ac2c7 --- /dev/null +++ b/WDL/swell/swell-miscdlg-gtk.cpp @@ -0,0 +1,141 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux + Copyright (C) 2006-2008, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic APIs for browsing for files, directories, and messageboxes. + + These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. + + + (GTK version) + */ + + +#ifndef SWELL_PROVIDED_BY_APP + +#include + +#include "swell.h" + +void BrowseFile_SetTemplate(int dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) +{ +} + +// return true +bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, + char *fn, int fnsize) +{ + return false; +} + +bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) +{ + return false; +} + + + +char *BrowseForFiles(const char *text, const char *initialdir, + const char *initialfile, bool allowmul, const char *extlist) +{ + return NULL; +} + + +static void messagebox_callback( GtkWidget *widget, gpointer data ) +{ + if (data) *(char*)data=1; + gtk_main_quit (); +} + +int MessageBox(HWND hwndParent, const char *text, const char *caption, int type) +{ + char has_clicks[3]={0,}; + int ids[3]={0,}; + const char *lbls[3]={0,}; + if (type == MB_OKCANCEL) + { + ids[0]=IDOK; lbls[0]="OK"; + ids[1]=IDCANCEL; lbls[1]="Cancel"; + } + else if (type == MB_YESNO) + { + ids[0]=IDYES; lbls[0]="Yes"; + ids[1]=IDNO; lbls[1]="No"; + } + else if (type == MB_YESNOCANCEL) + { + ids[0]=IDYES; lbls[0]="Yes"; + ids[1]=IDNO; lbls[1]="No"; + ids[2]=IDCANCEL; lbls[2]="Cancel"; + } + else // MB_OK? + { + ids[0]=IDOK; lbls[0]="OK"; + } + + GtkWidget *window; + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_modal(GTK_WINDOW(window), true); + gtk_window_set_destroy_with_parent(GTK_WINDOW(window), true); + gtk_window_set_resizable(GTK_WINDOW(window), false); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(window), caption); + g_signal_connect (G_OBJECT (window), "destroy", + G_CALLBACK (messagebox_callback), NULL); + + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + GtkWidget *outer_container = gtk_vbox_new(false, 4); + { + GtkWidget *label = gtk_label_new(text); + gtk_container_add(GTK_CONTAINER(outer_container),label); + gtk_widget_show(label); + } + { + GtkWidget *con = gtk_hbutton_box_new(); + int x; + for(x=0;x<3&&ids[x];x++) + { + GtkWidget *but = gtk_button_new_with_label(lbls[x]); + g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(messagebox_callback), &has_clicks[x]); + gtk_container_add(GTK_CONTAINER(con), but); + gtk_widget_show(but); + } + gtk_container_add(GTK_CONTAINER(outer_container),con); + gtk_widget_show(con); + } + + + gtk_container_add(GTK_CONTAINER(window), outer_container); + gtk_widget_show(outer_container); + gtk_widget_show(window); + + gtk_main (); + + int x; + for(x=0;x<3 && ids[x]; x++) + { + if (has_clicks[x]) return ids[x]; + } + if (x>0) x--; + return ids[x]; +} + +#endif diff --git a/WDL/swell/swell-miscdlg.mm b/WDL/swell/swell-miscdlg.mm new file mode 100644 index 00000000..e29637d6 --- /dev/null +++ b/WDL/swell/swell-miscdlg.mm @@ -0,0 +1,354 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic APIs for browsing for files, directories, and messageboxes. + + These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble. + + */ + + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#import +static NSMutableArray *extensionsFromList(const char *extlist) +{ + NSMutableArray *fileTypes = [[NSMutableArray alloc] initWithCapacity:30]; + while (*extlist) + { + extlist += strlen(extlist)+1; + if (!*extlist) break; + while (*extlist) + { + while (*extlist && *extlist != '.') extlist++; + if (!*extlist) break; + extlist++; + char tmp[32]; + lstrcpyn(tmp,extlist,sizeof(tmp)); + if (strstr(tmp,";")) strstr(tmp,";")[0]=0; + if (tmp[0] && tmp[0]!='*') + { + NSString *s=(NSString *)SWELL_CStringToCFString(tmp); + [fileTypes addObject:s]; + [s release]; + } + while (*extlist && *extlist != ';') extlist++; + if (*extlist == ';') extlist++; + } + extlist++; + } + + return fileTypes; +} + +static const char *BFSF_Templ_dlgid; +static DLGPROC BFSF_Templ_dlgproc; +static struct SWELL_DialogResourceIndex *BFSF_Templ_reshead; +void BrowseFile_SetTemplate(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead) +{ + BFSF_Templ_reshead=reshead; + BFSF_Templ_dlgid=dlgid; + BFSF_Templ_dlgproc=dlgProc; +} + +// return true +bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist, + char *fn, int fnsize) +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + NSString *title=(NSString *)SWELL_CStringToCFString(text); + [panel setTitle:title]; + [panel setAccessoryView:nil]; + HWND oh=NULL; + if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel + { + oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); + BFSF_Templ_dlgproc=0; + BFSF_Templ_dlgid=0; + } + + NSMutableArray *fileTypes = extensionsFromList(extlist); + + [panel setAllowedFileTypes:fileTypes]; + NSString *ifn=0; + NSString *idir=0; + + if (initialfile && *initialfile) + { + char s[2048]; + lstrcpyn(s,initialfile,sizeof(s)); + char *p=s; + while (*p) p++; + while (p >= s && *p != '/') p--; + if (p>=s) + { + *p=0; + ifn=(NSString *)SWELL_CStringToCFString(p+1); + idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/"); + } + else + ifn=(NSString *)SWELL_CStringToCFString(s); + } + if (!idir && initialdir && *initialdir) + { + idir=(NSString *)SWELL_CStringToCFString(initialdir); + } + + HMENU hm=SWELL_GetDefaultModalWindowMenu(); + if (hm) hm=SWELL_DuplicateMenu(hm); + SWELL_SetCurrentMenu(hm); + int result = [panel runModalForDirectory:idir file:ifn]; + SWELL_SetCurrentMenu(GetMenu(GetFocus())); + if (hm) DestroyMenu(hm); + + if (oh) SendMessage(oh,WM_DESTROY,0,0); + [panel setAccessoryView:nil]; + [title release]; + [fileTypes release]; + + if (result == NSOKButton) + { + char buf[2048]; + buf[0]=0; + buf[sizeof(buf)-1]=0; + SWELL_CFStringToCString([panel filename],buf,(sizeof(buf)-1)); + if (buf[0]) + { + lstrcpyn(fn,buf,fnsize); + return true; + } + } + + return false; + +} + +bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize) +{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + NSString *title=(NSString *)SWELL_CStringToCFString(text); + [panel setTitle:title]; + [panel setAllowsMultipleSelection:NO]; + [panel setCanChooseFiles:NO]; + [panel setCanCreateDirectories:YES]; + [panel setCanChooseDirectories:YES]; + [panel setResolvesAliases:YES]; + + HWND oh=NULL; + if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel + { + oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); + BFSF_Templ_dlgproc=0; + BFSF_Templ_dlgid=0; + } + + NSString *idir=0; + + if (initialdir && *initialdir) + { + idir=(NSString *)SWELL_CStringToCFString(initialdir); + } + + HMENU hm=SWELL_GetDefaultModalWindowMenu(); + if (hm) hm=SWELL_DuplicateMenu(hm); + SWELL_SetCurrentMenu(hm); + int result = [panel runModalForDirectory:idir file:nil types:nil]; + SWELL_SetCurrentMenu(GetMenu(GetFocus())); + if (hm) DestroyMenu(hm); + + if (oh) SendMessage(oh,WM_DESTROY,0,0); + [panel setAccessoryView:nil]; + + if (idir) [idir release]; + + [title release]; + + if (result != NSOKButton) return 0; + + NSArray *filesToOpen = [panel filenames]; + int count = [filesToOpen count]; + + if (!count) return 0; + + NSString *aFile = [filesToOpen objectAtIndex:0]; + if (!aFile) return 0; + SWELL_CFStringToCString(aFile,fn,(fnsize-1)); + fn[fnsize-1]=0; + return 1; +} + + +char *BrowseForFiles(const char *text, const char *initialdir, + const char *initialfile, bool allowmul, const char *extlist) +{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + NSString *title=(NSString *)SWELL_CStringToCFString(text); + HWND oh=NULL; + if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel + { + oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0); + BFSF_Templ_dlgproc=0; + BFSF_Templ_dlgid=0; + } + + [panel setTitle:title]; + [panel setAllowsMultipleSelection:(allowmul?YES:NO)]; + [panel setCanChooseFiles:YES]; + [panel setCanChooseDirectories:NO]; + [panel setResolvesAliases:YES]; + + NSMutableArray *fileTypes = extensionsFromList(extlist); + + NSString *ifn=0; + NSString *idir=0; + + if (initialfile && *initialfile) + { + char s[2048]; + lstrcpyn(s,initialfile,sizeof(s)); + char *p=s; + while (*p) p++; + while (p >= s && *p != '/') p--; + if (p>=s) + { + *p=0; + ifn=(NSString *)SWELL_CStringToCFString(p+1); + idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/"); + } + else + ifn=(NSString *)SWELL_CStringToCFString(s); + + } + if (!idir && initialdir && *initialdir) + { + idir=(NSString *)SWELL_CStringToCFString(initialdir); + } + + HMENU hm=SWELL_GetDefaultModalWindowMenu(); + if (hm) hm=SWELL_DuplicateMenu(hm); + SWELL_SetCurrentMenu(hm); + + int result = [panel runModalForDirectory:idir file:ifn types:fileTypes]; + + SWELL_SetCurrentMenu(GetMenu(GetFocus())); + if (hm) DestroyMenu(hm); + + if (oh) SendMessage(oh,WM_DESTROY,0,0); + [panel setAccessoryView:nil]; + + if (ifn) [ifn release]; + if (idir) [idir release]; + + [fileTypes release]; + [title release]; + + if (result != NSOKButton) return 0; + + NSArray *filesToOpen = [panel filenames]; + int i, count = [filesToOpen count]; + + if (!count) return 0; + + if (count==1||!allowmul) + { + NSString *aFile = [filesToOpen objectAtIndex:0]; + if (!aFile) return 0; + char fn[2048]; + SWELL_CFStringToCString(aFile,fn,(sizeof(fn)-1)); + fn[sizeof(fn)-1]=0; + char *ret=(char *)malloc(strlen(fn)+2); + memcpy(ret,fn,strlen(fn)); + ret[strlen(fn)]=0; + ret[strlen(fn)+1]=0; + return ret; + } + + int rsize=1; + char *ret=0; + for (i=0; i=nSize)sz=nSize-1; + fn[sz]=0; + char *p=fn; + while (*p) p++; + while (p >= fn && *p != '/') p--; + strcpy(++p,"libSwell.so"); + + void *tmp = dlopen(fn,RTLD_LAZY); + if (!tmp) + { + printf("Error loading '%s'\n",fn); + perror("dlopen:"); + exit(2); + } +#else + void *tmp = dlopen(NULL,RTLD_LAZY); +#endif + + if (tmp) *(void **)&SWELLAPI_GetFunc = dlsym(tmp,"SWELLAPI_GetFunc"); + //printf("tmp=%08x, SWELLAPI_GetFunc=%08x\n",tmp,SWELLAPI_GetFunc); + + if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)!=(void*)0x100) SWELLAPI_GetFunc=0; + +#ifdef SWELL_LOAD_SWELL_DYLIB + __loaded_getfunc = SWELLAPI_GetFunc; +#endif + int x; + for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) + { + *api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0; + if (!*api_tab[x].func) + { + printf("SWELL API not found: %s\n",api_tab[x].name); +#ifdef SWELL_LOAD_SWELL_DYLIB + exit(1); +#endif + *api_tab[x].func = (void*)&dummyFunc; + } + } + } + ~SwellAPPInitializer() + { + } +}; + +SwellAPPInitializer m_swell_appAPIinit; + +#ifdef SWELL_LOAD_SWELL_DYLIB +extern "C" __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) +{ + if (__loaded_getfunc) return __loaded_getfunc(name); + return NULL; +} + +#endif + +extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc) +{ + // this returning 1 allows DllMain to be called, if available + return 1; +} + +#endif diff --git a/WDL/swell/swell-modstub.mm b/WDL/swell/swell-modstub.mm new file mode 100644 index 00000000..cb5f88ff --- /dev/null +++ b/WDL/swell/swell-modstub.mm @@ -0,0 +1,70 @@ +#ifdef SWELL_PROVIDED_BY_APP + +#import +#import +#define SWELL_API_DEFPARM(x) +#define SWELL_API_DEFINE(ret,func,parms) ret (*func) parms ; +#include "swell.h" + +// only include this file in projects that are linked to swell.dylib + +struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; +struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; +struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; + +// define the functions + +static struct +{ + const char *name; + void **func; +} api_tab[]={ + +#undef _WDL_SWELL_H_API_DEFINED_ +#undef SWELL_API_DEFINE +#define SWELL_API_DEFINE(ret, func, parms) {#func, (void **)&func }, + +#include "swell-functions.h" + +}; + +static int dummyFunc() { return 0; } + +class SwellAPPInitializer +{ +public: + SwellAPPInitializer() + { + void *(*SWELLAPI_GetFunc)(const char *name)=NULL; + + id del = [NSApp delegate]; + if (del && [del respondsToSelector:@selector(swellGetAPPAPIFunc)]) + *(void **)&SWELLAPI_GetFunc = (void *)objc_msgSend(del,@selector(swellGetAPPAPIFunc)); + + if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)!=(void*)0x100) SWELLAPI_GetFunc=0; + + int x; + for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) + { + *api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0; + if (!*api_tab[x].func) + { + printf("SWELL API not found: %s\n",api_tab[x].name); + *api_tab[x].func = (void*)&dummyFunc; + } + } + } + ~SwellAPPInitializer() + { + } +}; + +SwellAPPInitializer m_swell_appAPIinit; + +extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc) +{ + // this returning 1 allows DllMain to be called, if available + return 1; +} + +#endif diff --git a/WDL/swell/swell-types.h b/WDL/swell/swell-types.h new file mode 100644 index 00000000..96e33520 --- /dev/null +++ b/WDL/swell/swell-types.h @@ -0,0 +1,1337 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) + Copyright (C) 2006-2010, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. + + */ + +#ifndef _WDL_SWELL_H_TYPES_DEFINED_ +#define _WDL_SWELL_H_TYPES_DEFINED_ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +typedef intptr_t INT_PTR, *PINT_PTR, LONG_PTR, *PLONG_PTR; +typedef uintptr_t UINT_PTR, *PUINT_PTR, ULONG_PTR, *PULONG_PTR, DWORD_PTR, *PDWORD_PTR; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef max +#define max(x,y) ((x)<(y)?(y):(x)) +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef S_OK +#define S_OK 0 +#endif +#ifndef E_FAIL +#define E_FAIL (-1) +#endif + + +// the byte ordering of RGB() etc is different than on win32 +#define RGB(r,g,b) (((r)<<16)|((g)<<8)|(b)) +#define GetRValue(x) (((x)>>16)&0xff) +#define GetGValue(x) (((x)>>8)&0xff) +#define GetBValue(x) ((x)&0xff) + +// basic platform compat defines +#define stricmp(x,y) strcasecmp(x,y) +#define strnicmp(x,y,z) strncasecmp(x,y,z) + +#define DeleteFile(x) (!unlink(x)) +#define MoveFile(x,y) (!rename(x,y)) +#define GetCurrentDirectory(sz,buf) (!getcwd(buf,sz)) +#define SetCurrentDirectory(buf) (!chdir(buf)) +#define CreateDirectory(x,y) (!mkdir((x),0755)) +#define wsprintf sprintf + +#ifndef LOWORD +#define MAKEWORD(a, b) ((unsigned short)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) +#define MAKELONG(a, b) ((int)(((unsigned short)(a)) | ((DWORD)((unsigned short)(b))) << 16)) +#define MAKEWPARAM(l, h) (WPARAM)MAKELONG(l, h) +#define MAKELPARAM(l, h) (LPARAM)MAKELONG(l, h) +#define MAKELRESULT(l, h) (LRESULT)MAKELONG(l, h) +#define LOWORD(l) ((unsigned short)(l)) +#define HIWORD(l) ((unsigned short)(((unsigned int)(l) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((BYTE)(w)) +#define HIBYTE(w) ((BYTE)(((unsigned short)(w) >> 8) & 0xFF)) +#endif + +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) + +#define UNREFERENCED_PARAMETER(P) (P) +#define _T(T) T + +#define CallWindowProc(A,B,C,D,E) ((WNDPROC)A)(B,C,D,E) +#define OffsetRect WinOffsetRect //to avoid OSX's OffsetRect function +#define SetRect WinSetRect //to avoid OSX's SetRect function +#define UnionRect WinUnionRect +#define IntersectRect WinIntersectRect + + +#define MAX_PATH 1024 + + + +// SWELLAPP stuff (swellappmain.mm) +#ifdef __cplusplus +extern "C" { +#endif +INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2); // to be implemented by app (if using swellappmain.mm) +#ifdef __cplusplus +}; +#endif + +#define SWELLAPP_ONLOAD 0x0001 // initialization of app vars etc +#define SWELLAPP_LOADED 0x0002 // create dialogs etc +#define SWELLAPP_DESTROY 0x0003 // about to destroy (cleanup etc) +#define SWELLAPP_SHOULDDESTROY 0x0004 // return 0 to allow app to terminate, >0 to prevent + +#define SWELLAPP_OPENFILE 0x0050 // parm1= (const char *)string, return >0 if allowed +#define SWELLAPP_NEWFILE 0x0051 // new file, return >0 if allowed +#define SWELLAPP_SHOULDOPENNEWFILE 0x0052 // allow opening new file? >0 if allowed + +#define SWELLAPP_ONCOMMAND 0x0099 // parm1 = (int) command ID, parm2 = (id) sender +#define SWELLAPP_PROCESSMESSAGE 0x0100 // parm1=(MSG *)msg (loosely), parm2= (NSEvent *) the event . return >0 to eat + +#define SWELLAPP_ACTIVATE 0x1000 // parm1 = (bool) isactive. return nonzero to prevent WM_ACTIVATEAPP from being broadcasted +// + + + + +// basic types +typedef signed char BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned int DWORD; +typedef DWORD COLORREF; +typedef unsigned int UINT; +typedef int INT; + +typedef ULONG_PTR WPARAM; +typedef LONG_PTR LPARAM; +typedef LONG_PTR LRESULT; + + +typedef void *LPVOID, *PVOID; + +#if defined(__APPLE__) && !defined(__LP64__) +typedef signed long HRESULT; +typedef signed long LONG; +typedef unsigned long ULONG; +#else +typedef signed int HRESULT; +typedef signed int LONG; +typedef unsigned int ULONG; +#endif + +typedef short SHORT; +typedef int *LPINT; +typedef char CHAR; +typedef char *LPSTR; +typedef const char *LPCSTR; + +#define __int64 long long // define rather than typedef, for unsigned __int64 support + +typedef unsigned __int64 ULONGLONG; + +typedef union { + unsigned long long QuadPart; + struct { + #ifdef __ppc__ + DWORD HighPart; + DWORD LowPart; + #else + DWORD LowPart; + DWORD HighPart; + #endif + }; +} ULARGE_INTEGER; + + +typedef struct HWND__ *HWND; +typedef struct HMENU__ *HMENU; +typedef void *HANDLE, *HINSTANCE, *HDROP; +typedef void *HGLOBAL; + +typedef void (*TIMERPROC)(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); + +typedef struct +{ + LONG x,y; +} POINT, *LPPOINT; + + +typedef struct +{ + SHORT x; + SHORT y; +} POINTS; + + +typedef struct +{ + LONG left,top, right, bottom; +} RECT, *LPRECT; + + +typedef struct { + unsigned char fVirt; + unsigned short key,cmd; +} ACCEL, *LPACCEL; + + +typedef struct { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME; + +typedef struct _GUID { + unsigned int Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; + +typedef struct { + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +} MSG, *LPMSG; + +typedef struct HDC__ *HDC; +typedef struct HCURSOR__ *HCURSOR; +typedef struct HRGN__ *HRGN; + +typedef struct HGDIOBJ__ *HBITMAP; +typedef struct HGDIOBJ__ *HICON; +typedef struct HGDIOBJ__ *HGDIOBJ; +typedef struct HGDIOBJ__ *HBRUSH; +typedef struct HGDIOBJ__ *HPEN; +typedef struct HGDIOBJ__ *HFONT; + + +typedef struct +{ + HWND hwndFrom; + UINT_PTR idFrom; + UINT code; +} NMHDR, *LPNMHDR; + + +typedef struct { + NMHDR hdr; + DWORD_PTR dwItemSpec; + DWORD_PTR dwItemData; + POINT pt; + DWORD dwHitInfo; +} NMMOUSE, *LPNMMOUSE; +typedef NMMOUSE NMCLICK; +typedef LPNMMOUSE LPNMCLICK; + +typedef struct +{ + int mask, fmt,cx; + char *pszText; + int cchTextMax, iSubItem; +} LVCOLUMN; +typedef struct +{ + int mask, iItem, iSubItem, state, stateMask; + char *pszText; + int cchTextMax, iImage; + LPARAM lParam; +} LVITEM; + +typedef int (*PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); + +typedef struct HIMAGELIST__ *HIMAGELIST; + +typedef struct +{ + POINT pt; + UINT flags; + int iItem; + int iSubItem; // this is was NOT in win95. valid only for LVM_SUBITEMHITTEST +} LVHITTESTINFO, *LPLVHITTESTINFO; + + +typedef struct +{ + NMHDR hdr; + int iItem; + int iSubItem; + UINT uNewState; + UINT uOldState; + UINT uChanged; + POINT ptAction; + LPARAM lParam; +} NMLISTVIEW, *LPNMLISTVIEW; + +typedef struct +{ + NMHDR hdr; + LVITEM item; +} NMLVDISPINFO, *LPNMLVDISPINFO; + +typedef struct +{ + UINT mask; + int cxy; + char* pszText; + HBITMAP hbm; + int cchTextMax; + int fmt; + LPARAM lParam; + int iImage; + int iOrder; + UINT type; + void *pvFilter; + UINT state; +} HDITEM, *LPHDITEM; + +typedef struct TCITEM +{ + UINT mask; + DWORD dwState; + DWORD dwStateMask; + char *pszText; + int cchTextMax; + int iImage; + + LPARAM lParam; +} TCITEM, *LPTCITEM; + +typedef struct tagDRAWITEMSTRUCT { + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + HWND hwndItem; + HDC hDC; + RECT rcItem; + DWORD_PTR itemData; +} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT; + +typedef struct tagBITMAP { + LONG bmWidth; + LONG bmHeight; +} BITMAP, *PBITMAP, *LPBITMAP; +#define ODT_MENU 1 +#define ODT_LISTBOX 2 +#define ODT_COMBOBOX 3 +#define ODT_BUTTON 4 + +#define ODS_SELECTED 0x0001 + + + + +typedef struct +{ + DWORD cbSize; + HWND hWnd; + UINT uID; + UINT uFlags; + UINT uCallbackMessage; + HICON hIcon; + CHAR szTip[64]; +} NOTIFYICONDATA,*PNOTIFYICONDATA, *LPNOTIFYICONDATA; + + +#define NIM_ADD 0x00000000 +#define NIM_MODIFY 0x00000001 +#define NIM_DELETE 0x00000002 + +#define NIF_MESSAGE 0x00000001 +#define NIF_ICON 0x00000002 +#define NIF_TIP 0x00000004 + + + +typedef struct HTREEITEM__ *HTREEITEM; + +#define TVIF_TEXT 0x0001 +#define TVIF_IMAGE 0x0002 +#define TVIF_PARAM 0x0004 +#define TVIF_STATE 0x0008 +#define TVIF_HANDLE 0x0010 +#define TVIF_SELECTEDIMAGE 0x0020 +#define TVIF_CHILDREN 0x0040 + +#define TVIS_SELECTED 0x0002 +#define TVIS_DROPHILITED 0x0008 +#define TVIS_BOLD 0x0010 +#define TVIS_EXPANDED 0x0020 + +#define TVE_COLLAPSE 0x0001 +#define TVE_EXPAND 0x0002 +#define TVE_TOGGLE 0x0003 + +#define TVN_FIRST (0U-400U) // treeview +#define TVN_SELCHANGED (TVN_FIRST-2) + +#define TVI_ROOT ((HTREEITEM)0xFFFF0000) +#define TVI_FIRST ((HTREEITEM)0xFFFF0001) +#define TVI_LAST ((HTREEITEM)0xFFFF0002) +#define TVI_SORT ((HTREEITEM)0xFFFF0003) + +#define TVHT_NOWHERE 0x0001 +#define TVHT_ONITEMICON 0x0002 +#define TVHT_ONITEMLABEL 0x0004 +#define TVHT_ONITEM (TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMSTATEICON) +#define TVHT_ONITEMINDENT 0x0008 +#define TVHT_ONITEMBUTTON 0x0010 +#define TVHT_ONITEMRIGHT 0x0020 +#define TVHT_ONITEMSTATEICON 0x0040 + +#define TVHT_ABOVE 0x0100 +#define TVHT_BELOW 0x0200 +#define TVHT_TORIGHT 0x0400 +#define TVHT_TOLEFT 0x0800 + +typedef struct { + UINT mask; + HTREEITEM hItem; + UINT state; + UINT stateMask; + char *pszText; + int cchTextMax; + int iImage; + int iSelectedImage; + int cChildren; + LPARAM lParam; +} TVITEM, TV_ITEM, *LPTVITEM, *LPTV_ITEM; + +typedef struct { + HTREEITEM hParent; + HTREEITEM hInsertAfter; + TVITEM item; +} TVINSERTSTRUCT, *LPTVINSERTSTRUCT, TV_INSERTSTRUCT, *LPTV_INSERTSTRUCT; + +typedef struct { + POINT pt; + UINT flags; + HTREEITEM hItem; +} TVHITTESTINFO, *LPTVHITTESTINFO; + +typedef struct { + NMHDR hdr; + UINT action; + TVITEM itemOld; + TVITEM itemNew; + POINT ptDrag; +} NMTREEVIEW, *LPNMTREEVIEW; + + +typedef struct +{ + unsigned int cbSize, fMask, fType, fState, wID; + HMENU hSubMenu; + HICON hbmpChecked,hbmpUnchecked; + DWORD_PTR dwItemData; + char *dwTypeData; + int cch; +} MENUITEMINFO; + +#define SetMenuDefaultItem(a,b,c) (0) + +typedef struct { + POINT ptReserved, ptMaxSize, ptMaxPosition, ptMinTrackSize, ptMaxTrackSize; +} MINMAXINFO, *LPMINMAXINFO; + + +typedef struct +{ + int lfHeight, lfWidth, lfEscapement,lfOrientation, lfWeight; + char lfItalic, lfUnderline, lfStrikeOut, lfCharSet, lfOutPrecision, lfClipPrecision, + lfQuality, lfPitchAndFamily; + char lfFaceName[32]; +} LOGFONT; +typedef struct +{ + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmAveCharWidth; + // todo: implement rest +} TEXTMETRIC; + +typedef struct { + HDC hdc; + BOOL fErase; + RECT rcPaint; +} PAINTSTRUCT; + +typedef struct +{ + UINT cbSize; + UINT fMask; + int nMin; + int nMax; + UINT nPage; + int nPos; + int nTrackPos; +} SCROLLINFO, *LPSCROLLINFO; + +typedef struct +{ + DWORD styleOld; + DWORD styleNew; +} STYLESTRUCT, *LPSTYLESTRUCT; + +typedef struct _DROPFILES { + DWORD pFiles; // offset of file list + POINT pt; // drop point (client coords) + BOOL fNC; // is it on NonClient area + // and pt is in screen coords + BOOL fWide; // WIDE character switch +} DROPFILES, *LPDROPFILES; + + +typedef struct +{ + HWND hwnd; + HWND hwndInsertAfter; + int x; + int y; + int cx; + int cy; + UINT flags; +} WINDOWPOS, *LPWINDOWPOS, *PWINDOWPOS; + +typedef struct +{ + RECT rgrc[3]; + PWINDOWPOS lppos; +} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS; + + + +typedef INT_PTR (*DLGPROC)(HWND, UINT, WPARAM, LPARAM); +typedef LRESULT (*WNDPROC)(HWND, UINT, WPARAM, LPARAM); + + + +#define GF_BEGIN 1 +#define GF_INERTIA 2 +#define GF_END 4 + +#define GID_BEGIN 1 +#define GID_END 2 +#define GID_ZOOM 3 +#define GID_PAN 4 +#define GID_ROTATE 5 +#define GID_TWOFINGERTAP 6 +#define GID_ROLLOVER 7 + +typedef struct tagGESTUREINFO +{ + UINT cbSize; + DWORD dwFlags; + DWORD dwID; + HWND hwndTarget; + POINTS ptsLocation; + DWORD dwInstanceID; + DWORD dwSequenceID; + ULONGLONG ullArguments; + UINT cbExtraArgs; +} GESTUREINFO; + +// not using this stuff yet +#define GC_PAN 1 +#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 2 +#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 4 + +typedef struct tagGESTURECONFIG +{ + DWORD dwID; + DWORD dwWant; + DWORD dwBlock; +} GESTURECONFIG; + + + +#ifndef WINAPI +#define WINAPI +#endif + +#ifndef CALLBACK +#define CALLBACK +#endif + + +typedef BOOL (*PROPENUMPROCEX)(HWND hwnd, const char *lpszString, HANDLE hData, LPARAM lParam); + +// swell specific type +typedef HWND (*SWELL_ControlCreatorProc)(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h); + +#define DLL_PROCESS_DETACH 0 +#define DLL_PROCESS_ATTACH 1 + +// if the user implements this (and links with swell-modstub[-generic], this will get called for DLL_PROCESS_[AT|DE]TACH +#ifdef __cplusplus +extern "C" { +#endif +__attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved); +#ifdef __cplusplus +}; +#endif + +/* + ** win32 specific constants + */ +#define MB_OK 0 +#define MB_OKCANCEL 1 +#define MB_YESNOCANCEL 3 +#define MB_YESNO 4 +#define MB_RETRYCANCEL 5 + +#define MB_ICONERROR 0 +#define MB_ICONSTOP 0 +#define MB_ICONINFORMATION 0 + +#define IDOK 1 +#define IDCANCEL 2 +#define IDABORT 3 +#define IDRETRY 4 +#define IDIGNORE 5 +#define IDYES 6 +#define IDNO 7 + +#define GW_HWNDFIRST 0 +#define GW_HWNDLAST 1 +#define GW_HWNDNEXT 2 +#define GW_HWNDPREV 3 +#define GW_OWNER 4 +#define GW_CHILD 5 + +#define GWL_USERDATA (-21) +#define GWL_ID (-12) +#define GWL_STYLE (-16) // only supported for BS_ for now I think +#define GWL_EXSTYLE (-20) +#define GWL_WNDPROC (-4) +#define DWL_DLGPROC (-8) + +#define SWELL_NOT_WS_VISIBLE 0x80000000L +#define WS_CHILDWINDOW (WS_CHILD) +#define WS_CHILD 0x40000000L +#define WS_DISABLED 0x08000000L +#define WS_CAPTION 0x00C00000L +#define WS_VSCROLL 0x00200000L +#define WS_HSCROLL 0x00100000L +#define WS_SYSMENU 0x00080000L +#define WS_THICKFRAME 0x00040000L +#define WS_GROUP 0x00020000L +#define WS_TABSTOP 0x00010000L + +#define WS_BORDER 0 // ignored for now +#define WS_VISIBLE 0 + + +#define WM_CTLCOLORMSGBOX 0x0132 +#define WM_CTLCOLOREDIT 0x0133 +#define WM_CTLCOLORLISTBOX 0x0134 +#define WM_CTLCOLORBTN 0x0135 +#define WM_CTLCOLORDLG 0x0136 +#define WM_CTLCOLORSCROLLBAR 0x0137 +#define WM_CTLCOLORSTATIC 0x0138 + +#define CB_ADDSTRING 0x0143 +#define CB_DELETESTRING 0x0144 +#define CB_GETCOUNT 0x0146 +#define CB_GETCURSEL 0x0147 +#define CB_GETLBTEXT 0x0148 +#define CB_INSERTSTRING 0x014A +#define CB_RESETCONTENT 0x014B +#define CB_FINDSTRING 0x014C +#define CB_SETCURSEL 0x014E +#define CB_GETITEMDATA 0x0150 +#define CB_SETITEMDATA 0x0151 +#define CB_FINDSTRINGEXACT 0x0158 +#define CB_INITSTORAGE 0x0161 + +#define LB_ADDSTRING 0x0180 +#define LB_INSERTSTRING 0x0181 +#define LB_DELETESTRING 0x0182 +#define LB_GETTEXT 0x0183 +#define LB_RESETCONTENT 0x0184 +#define LB_SETSEL 0x0185 +#define LB_SETCURSEL 0x0186 +#define LB_GETSEL 0x0187 +#define LB_GETCURSEL 0x0188 +#define LB_GETCOUNT 0x018B +#define LB_GETSELCOUNT 0x0190 +#define LB_GETITEMDATA 0x0199 +#define LB_SETITEMDATA 0x019A + +#define TBM_GETPOS (WM_USER) +#define TBM_SETTIC (WM_USER+4) +#define TBM_SETPOS (WM_USER+5) +#define TBM_SETRANGE (WM_USER+6) +#define TBM_SETSEL (WM_USER+10) + +#define PBM_SETRANGE (WM_USER+1) +#define PBM_SETPOS (WM_USER+2) +#define PBM_DELTAPOS (WM_USER+3) + +#define BM_GETCHECK 0x00F0 +#define BM_SETCHECK 0x00F1 +#define BM_GETIMAGE 0x00F6 +#define BM_SETIMAGE 0x00F7 +#define IMAGE_BITMAP 0 +#define IMAGE_ICON 1 + +#define NM_FIRST (0U- 0U) // generic to all controls +#define NM_LAST (0U- 99U) +#define NM_CLICK (NM_FIRST-2) // uses NMCLICK struct +#define NM_DBLCLK (NM_FIRST-3) +#define NM_RCLICK (NM_FIRST-5) // uses NMCLICK struct + + +#define LVSIL_STATE 1 +#define LVSIL_SMALL 2 + +#define LVIR_BOUNDS 0 +#define LVIR_ICON 1 +#define LVIR_LABEL 2 +#define LVIR_SELECTBOUNDS 3 + + +#define LVHT_NOWHERE 0x0001 +#define LVHT_ONITEMICON 0x0002 +#define LVHT_ONITEMLABEL 0x0004 +#define LVHT_ONITEMSTATEICON 0x0008 +#define LVHT_ONITEM (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON) + +#define LVHT_ABOVE 0x0010 +#define LVHT_BELOW 0x0020 +#define LVHT_TORIGHT 0x0040 +#define LVHT_TOLEFT 0x0080 + +#define LVCF_FMT 1 +#define LVCF_WIDTH 2 +#define LVCF_TEXT 4 + +#define LVCFMT_LEFT 0 +#define LVCFMT_RIGHT 1 +#define LVCFMT_CENTER 2 + +#define LVIF_TEXT 1 +#define LVIF_IMAGE 2 +#define LVIF_PARAM 4 +#define LVIF_STATE 8 + +#define LVIS_SELECTED 1 +#define LVIS_FOCUSED 2 +#define LVNI_SELECTED 1 +#define LVNI_FOCUSED 2 +#define INDEXTOSTATEIMAGEMASK(x) ((x)<<16) +#define LVIS_STATEIMAGEMASK (255<<16) + +#define LVN_FIRST (0U-100U) // listview +#define LVN_LAST (0U-199U) +#define LVN_BEGINDRAG (LVN_FIRST-9) +#define LVN_COLUMNCLICK (LVN_FIRST-8) +#define LVN_ITEMCHANGED (LVN_FIRST-1) +#define LVN_ODFINDITEM (LVN_FIRST-52) +#define LVN_GETDISPINFO (LVN_FIRST-50) + +#define LVS_EX_GRIDLINES 0x01 +#define LVS_EX_HEADERDRAGDROP 0x10 +#define LVS_EX_FULLROWSELECT 0x20 // ignored for now (enabled by default on OSX) + +#define HDI_FORMAT 0x4 +#define HDF_SORTUP 0x0400 +#define HDF_SORTDOWN 0x0200 + +#define TCIF_TEXT 0x0001 +#define TCIF_IMAGE 0x0002 +#define TCIF_PARAM 0x0008 +//#define TCIF_STATE 0x0010 + + + +#define TCN_FIRST (0U-550U) // tab control +#define TCN_LAST (0U-580U) +#define TCN_SELCHANGE (TCN_FIRST - 1) + + +#define BS_AUTOCHECKBOX 0x00000003L +#define BS_AUTO3STATE 0x00000006L +#define BS_AUTORADIOBUTTON 0x00000009L +#define BS_OWNERDRAW 0x0000000BL + + + +#define BST_CHECKED 1 +#define BST_UNCHECKED 0 +#define BST_INDETERMINATE 2 + +// note: these differ in values from their win32 counterparts, because we got them +// wrong to begin with, and we'd like to keep backwards compatability for things compiled +// against an old swell.h (and using the SWELL API via an exported mechanism, i.e. third party +// plug-ins). +#define SW_HIDE 0 +#define SW_SHOWNA 1 // 8 on win32 +#define SW_SHOW 2 // 1 on win32 +#define SW_SHOWMINIMIZED 3 // 2 on win32 + +// aliases (todo implement these as needed) +#define SW_SHOWNOACTIVATE SW_SHOWNA +#define SW_NORMAL SW_SHOW +#define SW_SHOWNORMAL SW_SHOW +#define SW_SHOWMAXIMIZED SW_SHOW +#define SW_SHOWDEFAULT SW_SHOWNORMAL +#define SW_RESTORE SW_SHOWNA + +#define SWP_NOMOVE 1 +#define SWP_NOSIZE 2 +#define SWP_NOZORDER 4 +#define SWP_NOACTIVATE 8 +#define SWP_SHOWWINDOW 16 +#define SWP_FRAMECHANGED 32 +#define SWP_NOCOPYBITS 0 +#define HWND_TOP ((HWND)0) +#define HWND_BOTTOM ((HWND)1) +#define HWND_TOPMOST ((HWND)-1) +#define HWND_NOTOPMOST ((HWND)-2) + +// most of these are ignored, actually, but TPM_NONOTIFY and TPM_RETURNCMD are now used +#define TPM_LEFTBUTTON 0x0000L +#define TPM_RIGHTBUTTON 0x0002L +#define TPM_LEFTALIGN 0x0000L +#define TPM_CENTERALIGN 0x0004L +#define TPM_RIGHTALIGN 0x0008L +#define TPM_TOPALIGN 0x0000L +#define TPM_VCENTERALIGN 0x0010L +#define TPM_BOTTOMALIGN 0x0020L +#define TPM_HORIZONTAL 0x0000L /* Horz alignment matters more */ +#define TPM_VERTICAL 0x0040L /* Vert alignment matters more */ +#define TPM_NONOTIFY 0x0080L /* Don't send any notification msgs */ +#define TPM_RETURNCMD 0x0100L + +#define MIIM_ID 1 +#define MIIM_STATE 2 +#define MIIM_TYPE 4 +#define MIIM_SUBMENU 8 +#define MIIM_DATA 16 + +#define MF_ENABLED 0 +#define MF_GRAYED 1 +#define MF_DISABLED 2 +#define MF_STRING 0 +#define MF_BITMAP 4 +#define MF_UNCHECKED 0 +#define MF_CHECKED 8 +#define MF_POPUP 0x10 +#define MF_BYCOMMAND 0 +#define MF_BYPOSITION 0x400 +#define MF_SEPARATOR 0x800 + +#define MFT_STRING MF_STRING +#define MFT_BITMAP MF_BITMAP +#define MFT_SEPARATOR MF_SEPARATOR +#define MFT_RADIOCHECK 0x200 + +#define MFS_GRAYED (MF_GRAYED|MF_DISABLED) +#define MFS_DISABLED MFS_GRAYED +#define MFS_CHECKED MF_CHECKED +#define MFS_ENABLED MF_ENABLED +#define MFS_UNCHECKED MF_UNCHECKED + +#define EN_CHANGE 0x0300 +#define STN_CLICKED 0 +#define STN_DBLCLK 1 +#define WM_CREATE 0x0001 +#define WM_DESTROY 0x0002 +#define WM_MOVE 0x0003 +#define WM_SIZE 0x0005 +#define WM_ACTIVATE 0x0006 +#define WM_SETTEXT 0x000C // not implemented on OSX, used internally on Linux +#define WM_PAINT 0x000F +#define WM_CLOSE 0x0010 +#define WM_ERASEBKGND 0x0014 +#define WM_SHOWWINDOW 0x0018 +#define WM_ACTIVATEAPP 0x001C +#define WM_SETCURSOR 0x0020 +#define WM_MOUSEACTIVATE 0x0021 +#define WM_GETMINMAXINFO 0x0024 +#define WM_DRAWITEM 0x002B +#define WM_SETFONT 0x0030 +#define WM_GETFONT 0x0031 +#define WM_GETOBJECT 0x003D // implemented differently than win32 -- see virtwnd/virtwnd-nsaccessibility.mm +#define WM_NOTIFY 0x004E + +#define WM_CONTEXTMENU 0x007B +#define WM_STYLECHANGED 0x007D +#define WM_DISPLAYCHANGE 0x007E +#define WM_NCDESTROY 0x0082 +#define WM_NCCALCSIZE 0x0083 +#define WM_NCHITTEST 0x0084 +#define WM_NCPAINT 0x0085 +#define WM_NCMOUSEMOVE 0x00A0 +#define WM_NCLBUTTONDOWN 0x00A1 +#define WM_NCLBUTTONUP 0x00A2 +#define WM_NCLBUTTONDBLCLK 0x00A3 +#define WM_NCRBUTTONDOWN 0x00A4 +#define WM_NCRBUTTONUP 0x00A5 +#define WM_NCRBUTTONDBLCLK 0x00A6 +#define WM_NCMBUTTONDOWN 0x00A7 +#define WM_NCMBUTTONUP 0x00A8 +#define WM_NCMBUTTONDBLCLK 0x00A9 +#define WM_KEYFIRST 0x0100 +#define WM_KEYDOWN 0x0100 +#define WM_KEYUP 0x0101 +#define WM_CHAR 0x0102 +#define WM_DEADCHAR 0x0103 +#define WM_SYSKEYDOWN 0x0104 +#define WM_SYSKEYUP 0x0105 +#define WM_SYSCHAR 0x0106 +#define WM_SYSDEADCHAR 0x0107 +#define WM_KEYLAST 0x0108 +#define WM_INITDIALOG 0x0110 +#define WM_COMMAND 0x0111 +#define WM_SYSCOMMAND 0x0112 +#define SC_CLOSE 0xF060 +#define WM_TIMER 0x0113 +#define WM_HSCROLL 0x0114 +#define WM_VSCROLL 0x0115 +#define WM_INITMENUPOPUP 0x0117 +#define WM_GESTURE 0x0119 +#define WM_MOUSEFIRST 0x0200 +#define WM_MOUSEMOVE 0x0200 +#define WM_LBUTTONDOWN 0x0201 +#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEWHEEL 0x020A +#define WM_MOUSEHWHEEL 0x020E +#define WM_MOUSELAST 0x020A +#define WM_CAPTURECHANGED 0x0215 +#define WM_DROPFILES 0x0233 +#define WM_USER 0x0400 + + +#define HTCAPTION 2 +#define HTBOTTOMRIGHT 17 + +#define WA_INACTIVE 0 +#define WA_ACTIVE 1 +#define WA_CLICKACTIVE 2 + +#define BN_CLICKED 0 + +#define LBN_SELCHANGE 1 +#define LBN_DBLCLK 2 +#define LB_ERR (-1) + +#define CBN_SELCHANGE 1 +#define CBN_EDITCHANGE 5 +#define CBN_DROPDOWN 7 +#define CB_ERR (-1) + +#define EM_GETSEL 0xF0B0 +#define EM_SETSEL 0xF0B1 +#define EM_SCROLL 0xF0B5 +#define EM_SETPASSWORDCHAR 0xF0CC + +#define SB_HORZ 0 +#define SB_VERT 1 +#define SB_CTL 2 +#define SB_BOTH 3 + +#define SB_LINEUP 0 +#define SB_LINELEFT 0 +#define SB_LINEDOWN 1 +#define SB_LINERIGHT 1 +#define SB_PAGEUP 2 +#define SB_PAGELEFT 2 +#define SB_PAGEDOWN 3 +#define SB_PAGERIGHT 3 +#define SB_THUMBPOSITION 4 +#define SB_THUMBTRACK 5 +#define SB_TOP 6 +#define SB_LEFT 6 +#define SB_BOTTOM 7 +#define SB_RIGHT 7 +#define SB_ENDSCROLL 8 + +#define DFCS_SCROLLUP 0x0000 +#define DFCS_SCROLLDOWN 0x0001 +#define DFCS_SCROLLLEFT 0x0002 +#define DFCS_SCROLLRIGHT 0x0003 +#define DFCS_SCROLLCOMBOBOX 0x0005 +#define DFCS_SCROLLSIZEGRIP 0x0008 +#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010 + +#define DFCS_INACTIVE 0x0100 +#define DFCS_PUSHED 0x0200 +#define DFCS_CHECKED 0x0400 +#define DFCS_FLAT 0x4000 + +#define DFCS_BUTTONPUSH 0x0010 + +#define DFC_SCROLL 3 +#define DFC_BUTTON 4 + +#define ESB_ENABLE_BOTH 0x0000 +#define ESB_DISABLE_BOTH 0x0003 + +#define ESB_DISABLE_LEFT 0x0001 +#define ESB_DISABLE_RIGHT 0x0002 + +#define ESB_DISABLE_UP 0x0001 +#define ESB_DISABLE_DOWN 0x0002 + +#define BDR_RAISEDOUTER 0x0001 +#define BDR_SUNKENOUTER 0x0002 +#define BDR_RAISEDINNER 0x0004 +#define BDR_SUNKENINNER 0x0008 + +#define BDR_OUTER 0x0003 +#define BDR_INNER 0x000c + +#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) +#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) +#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER) +#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER) + +#define BF_ADJUST 0x2000 +#define BF_FLAT 0x4000 +#define BF_LEFT 0x0001 +#define BF_TOP 0x0002 +#define BF_RIGHT 0x0004 +#define BF_BOTTOM 0x0008 +#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM) + +#define PATCOPY (DWORD)0x00F00021 + +#define HTHSCROLL 6 +#define HTVSCROLL 7 + +#define WS_EX_LEFTSCROLLBAR 0x00004000L +#define WS_EX_ACCEPTFILES 0x00000010L + +#define SIF_RANGE 0x0001 +#define SIF_PAGE 0x0002 +#define SIF_POS 0x0004 +#define SIF_DISABLENOSCROLL 0x0008 +#define SIF_TRACKPOS 0x0010 +#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) + +#define SIZE_RESTORED 0 +#define SIZE_MINIMIZED 1 +#define SIZE_MAXIMIZED 2 +#define SIZE_MAXSHOW 3 +#define SIZE_MAXHIDE 4 + + +#ifndef MAKEINTRESOURCE +#define MAKEINTRESOURCE(x) ((const char *)(UINT_PTR)(x)) +#endif + +#ifdef FSHIFT +#undef FSHIFT +#endif + +#define FVIRTKEY 1 +#define FSHIFT 0x04 +#define FCONTROL 0x08 +#define FALT 0x10 +#define FLWIN 0x20 + + +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_MBUTTON 0x04 + +#define VK_BACK 0x08 +#define VK_TAB 0x09 + +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 + +#define VK_ESCAPE 0x1B + +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F + +#define VK_LWIN 0x5B + +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 + +#define MK_LBUTTON 0x01 +#define MK_RBUTTON 0x02 +#define MK_MBUTTON 0x10 + + +#define IDC_SIZENESW MAKEINTRESOURCE(-1007) +#define IDC_SIZENWSE MAKEINTRESOURCE(-1006) +#define IDC_IBEAM MAKEINTRESOURCE(-1005) +#define IDC_UPARROW MAKEINTRESOURCE(-1004) +#define IDC_NO MAKEINTRESOURCE(-1003) +#define IDC_SIZEALL MAKEINTRESOURCE(-1002) +#define IDC_SIZENS MAKEINTRESOURCE(-1001) +#define IDC_SIZEWE MAKEINTRESOURCE(-1000) +#define IDC_ARROW MAKEINTRESOURCE(-999) +#define IDC_HAND MAKEINTRESOURCE(32649) + + + + +#define COLOR_3DSHADOW 0 +#define COLOR_3DHILIGHT 1 +#define COLOR_3DFACE 2 +#define COLOR_BTNTEXT 3 +#define COLOR_WINDOW 4 +#define COLOR_SCROLLBAR 5 +#define COLOR_3DDKSHADOW 6 +#define COLOR_BTNFACE 7 +#define COLOR_INFOBK 8 +#define COLOR_INFOTEXT 9 + +#define SRCCOPY 0 +#define SRCCOPY_USEALPHACHAN 0xdeadbeef +#define PS_SOLID 0 +#define DT_CALCRECT 1 +#define DT_VCENTER 2 +#define DT_CENTER 4 +#define DT_END_ELLIPSIS 8 +#define DT_BOTTOM 16 +#define DT_RIGHT 32 +#define DT_SINGLELINE 64 +#define DT_NOPREFIX 128 +#define DT_NOCLIP 256 +#define DT_WORDBREAK 512 + +#define DT_TOP 0 +#define DT_LEFT 0 + +#define FW_DONTCARE 0 +#define FW_THIN 100 +#define FW_EXTRALIGHT 200 +#define FW_LIGHT 300 +#define FW_NORMAL 400 +#define FW_MEDIUM 500 +#define FW_SEMIBOLD 600 +#define FW_BOLD 700 +#define FW_EXTRABOLD 800 +#define FW_HEAVY 900 + +#define FW_ULTRALIGHT FW_EXTRALIGHT +#define FW_REGULAR FW_NORMAL +#define FW_DEMIBOLD FW_SEMIBOLD +#define FW_ULTRABOLD FW_EXTRABOLD +#define FW_BLACK FW_HEAVY + +#define OUT_DEFAULT_PRECIS 0 +#define CLIP_DEFAULT_PRECIS 0 +#define DEFAULT_QUALITY 0 +#define DRAFT_QUALITY 1 +#define PROOF_QUALITY 2 +#define NONANTIALIASED_QUALITY 3 +#define ANTIALIASED_QUALITY 4 +#define DEFAULT_PITCH 0 +#define DEFAULT_CHARSET 0 +#define ANSI_CHARSET 0 +#define TRANSPARENT 0 +#define OPAQUE 1 + +#define NULL_PEN 1 +#define NULL_BRUSH 2 + +#define GMEM_ZEROINIT 1 +#define GMEM_FIXED 0 +#define GMEM_MOVEABLE 0 +#define GMEM_DDESHARE 0 +#define GMEM_DISCARDABLE 0 +#define GMEM_SHARE 0 +#define GMEM_LOWER 0 +#define GHND (GMEM_MOVEABLE|GM_ZEROINIT) +#define GPTR (GMEM_FIXED|GMEM_ZEROINIT) + + +#define _MCW_RC 0x00000300 /* Rounding Control */ +#define _RC_NEAR 0x00000000 /* near */ +#define _RC_DOWN 0x00000100 /* down */ +#define _RC_UP 0x00000200 /* up */ +#define _RC_CHOP 0x00000300 /* chop */ + + +extern struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; +extern struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; +extern struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head; + +#define HTNOWHERE 0 +#define HTCLIENT 1 +#define HTMENU 5 +#define HTHSCROLL 6 +#define HTVSCROLL 7 + +#define SM_CXSCREEN 0 +#define SM_CYSCREEN 1 +#define SM_CXVSCROLL 2 +#define SM_CYHSCROLL 3 +#define SM_CYVSCROLL 20 +#define SM_CXHSCROLL 21 + + +#if 0 // these are disabled until implemented + +#define SM_CYCAPTION 4 +#define SM_CXBORDER 5 +#define SM_CYBORDER 6 +#define SM_CXDLGFRAME 7 +#define SM_CYDLGFRAME 8 +#define SM_CYVTHUMB 9 +#define SM_CXHTHUMB 10 +#define SM_CXICON 11 +#define SM_CYICON 12 +#define SM_CXCURSOR 13 +#define SM_CYCURSOR 14 +#define SM_CYMENU 15 +#define SM_CXFULLSCREEN 16 +#define SM_CYFULLSCREEN 17 +#define SM_CYKANJIWINDOW 18 +#define SM_MOUSEPRESENT 19 +#define SM_DEBUG 22 +#define SM_SWAPBUTTON 23 +#define SM_CXMIN 28 +#define SM_CYMIN 29 +#define SM_CXSIZE 30 +#define SM_CYSIZE 31 +#define SM_CXFRAME 32 +#define SM_CYFRAME 33 +#define SM_CXMINTRACK 34 +#define SM_CYMINTRACK 35 +#define SM_CXDOUBLECLK 36 +#define SM_CYDOUBLECLK 37 +#define SM_CXICONSPACING 38 +#define SM_CYICONSPACING 39 + +#endif // unimplemented system metrics + + +#define THREAD_BASE_PRIORITY_LOWRT 15 +#define THREAD_BASE_PRIORITY_MAX 2 +#define THREAD_BASE_PRIORITY_MIN -2 +#define THREAD_BASE_PRIORITY_IDLE -15 +#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN +#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX +#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) +#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT +#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE + + + +#define WAIT_OBJECT_0 (0 ) +#define WAIT_TIMEOUT (0x00000102L) +#define WAIT_FAILED (DWORD)0xFFFFFFFF +#define INFINITE 0xFFFFFFFF + + +typedef struct _ICONINFO +{ + BOOL fIcon; + DWORD xHotspot; + DWORD yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; +} ICONINFO, *PICONINFO; + + +#endif //_WDL_SWELL_H_TYPES_DEFINED_ diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp new file mode 100644 index 00000000..4ca1dfae --- /dev/null +++ b/WDL/swell/swell-wnd-generic.cpp @@ -0,0 +1,3562 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux) + Copyright (C) 2006-2008, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + */ + + +#ifndef SWELL_PROVIDED_BY_APP + +#include "swell.h" +#include "swell-internal.h" + +#include +#include "../mutex.h" +#include "../ptrlist.h" +#include "../queue.h" + +#include "swell-dlggen.h" + +int g_swell_want_nice_style = 1; //unused but here for compat + +HWND__ *SWELL_topwindows; + + +static HWND s_captured_window; +HWND SWELL_g_focuswnd; // update from focus-in-event / focus-out-event signals, have to enable the GDK_FOCUS_CHANGE_MASK bits for the gdkwindow +static DWORD s_lastMessagePos; + +#ifdef SWELL_TARGET_GDK + +static GdkWindow *SWELL_g_focus_oswindow; +static int SWELL_gdk_active; + +HWND ChildWindowFromPoint(HWND h, POINT p); +bool IsWindowEnabled(HWND hwnd); + +static void swell_gdkEventHandler(GdkEvent *event, gpointer data); +void SWELL_initargs(int *argc, char ***argv) +{ + if (!SWELL_gdk_active) + { + // maybe make the main app call this with real parms + SWELL_gdk_active = gdk_init_check(argc,argv) ? 1 : -1; + if (SWELL_gdk_active > 0) + gdk_event_handler_set(swell_gdkEventHandler,NULL,NULL); + } +} + +static bool swell_initwindowsys() +{ + if (!SWELL_gdk_active) + { + // maybe make the main app call this with real parms + int argc=1; + char buf[32]; + strcpy(buf,"blah"); + char *argv[2]; + argv[0] = buf; + argv[1] = buf; + char **pargv = argv; + SWELL_initargs(&argc,&pargv); + } + + return SWELL_gdk_active>0; +} + +static void swell_destroyOSwindow(HWND hwnd) +{ + if (hwnd && hwnd->m_oswindow) + { + if (SWELL_g_focus_oswindow == hwnd->m_oswindow) SWELL_g_focus_oswindow=NULL; + gdk_window_destroy(hwnd->m_oswindow); + hwnd->m_oswindow=NULL; +#ifdef SWELL_LICE_GDI + delete hwnd->m_backingstore; + hwnd->m_backingstore=0; +#endif + } +} +static void swell_setOSwindowtext(HWND hwnd) +{ + if (hwnd && hwnd->m_oswindow) + { + gdk_window_set_title(hwnd->m_oswindow, hwnd->m_title ? hwnd->m_title : (char*)""); + } +} +static void swell_manageOSwindow(HWND hwnd, bool wantfocus) +{ + if (!hwnd) return; + + bool isVis = !!hwnd->m_oswindow; + bool wantVis = !hwnd->m_parent && hwnd->m_visible; + + if (isVis != wantVis) + { + if (!wantVis) swell_destroyOSwindow(hwnd); + else + { + if (swell_initwindowsys()) + { + HWND owner = NULL; // hwnd->m_owner; +// parent windows dont seem to work the way we'd want, yet, in gdk... +/* while (owner && !owner->m_oswindow) + { + if (owner->m_parent) owner = owner->m_parent; + else if (owner->m_owner) owner = owner->m_owner; + } +*/ + + RECT r = hwnd->m_position; + GdkWindowAttr attr={0,}; + attr.title = ""; + attr.event_mask = GDK_ALL_EVENTS_MASK|GDK_EXPOSURE_MASK; + attr.x = r.left; + attr.y = r.top; + attr.width = r.right-r.left; + attr.height = r.bottom-r.top; + attr.wclass = GDK_INPUT_OUTPUT; + attr.window_type = GDK_WINDOW_TOPLEVEL; + hwnd->m_oswindow = gdk_window_new(owner ? owner->m_oswindow : NULL,&attr,GDK_WA_X|GDK_WA_Y); + + if (hwnd->m_oswindow) + { + gdk_window_set_user_data(hwnd->m_oswindow,hwnd); + gdk_window_move_resize(hwnd->m_oswindow,r.left,r.top,r.right-r.left,r.bottom-r.top); + if (!wantfocus) gdk_window_set_focus_on_map(hwnd->m_oswindow,false); + HWND DialogBoxIsActive(); + if (!(hwnd->m_style & WS_CAPTION)) + { + gdk_window_set_override_redirect(hwnd->m_oswindow,true); + } + else if (/*hwnd == DialogBoxIsActive() || */ !(hwnd->m_style&WS_THICKFRAME)) + gdk_window_set_type_hint(hwnd->m_oswindow,GDK_WINDOW_TYPE_HINT_DIALOG); // this is a better default behavior + + gdk_window_show(hwnd->m_oswindow); + } + } + } + } + if (wantVis) swell_setOSwindowtext(hwnd); + +// if (wantVis && isVis && wantfocus && hwnd && hwnd->m_oswindow) gdk_window_raise(hwnd->m_oswindow); +} + +void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect) +{ +#ifdef SWELL_LICE_GDI + if (hwnd && hwnd->m_backingstore && hwnd->m_oswindow) + { + LICE_SubBitmap tmpbm(hwnd->m_backingstore,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top); + cairo_t * crc = gdk_cairo_create (hwnd->m_oswindow); + cairo_surface_t *temp_surface = cairo_image_surface_create_for_data((guchar*)tmpbm.getBits(), CAIRO_FORMAT_RGB24, tmpbm.getWidth(),tmpbm.getHeight(), tmpbm.getRowSpan()*4); + cairo_set_source_surface(crc, temp_surface, rect->left, rect->top); + cairo_paint(crc); + cairo_surface_destroy(temp_surface); + cairo_destroy(crc); + } +#endif +} + +static int swell_gdkConvertKey(int key) +{ + //gdk key to VK_ conversion + switch(key) + { + case GDK_KEY_Home: key = VK_HOME; break; + case GDK_KEY_End: key = VK_END; break; + case GDK_KEY_Up: key = VK_UP; break; + case GDK_KEY_Down: key = VK_DOWN; break; + case GDK_KEY_Left: key = VK_LEFT; break; + case GDK_KEY_Right: key = VK_RIGHT; break; + case GDK_KEY_Page_Up: key = VK_PRIOR; break; + case GDK_KEY_Page_Down: key = VK_NEXT; break; + case GDK_KEY_Insert: key = VK_INSERT; break; + case GDK_KEY_Delete: key = VK_DELETE; break; + case GDK_KEY_Escape: key = VK_ESCAPE; break; + } + return key; +} + +static LRESULT SendMouseMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (!hwnd || !hwnd->m_wndproc) return -1; + if (!IsWindowEnabled(hwnd)) + { + HWND DialogBoxIsActive(); + HWND h = DialogBoxIsActive(); + if (h) SetForegroundWindow(h); + return -1; + } + + LRESULT htc; + if (msg != WM_MOUSEWHEEL && !GetCapture()) + { + DWORD p=GetMessagePos(); + + htc=hwnd->m_wndproc(hwnd,WM_NCHITTEST,0,p); + if (hwnd->m_hashaddestroy||!hwnd->m_wndproc) + { + return -1; // if somehow WM_NCHITTEST destroyed us, bail + } + + if (htc!=HTCLIENT) + { + if (msg==WM_MOUSEMOVE) return hwnd->m_wndproc(hwnd,WM_NCMOUSEMOVE,htc,p); + if (msg==WM_LBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONUP,htc,p); + if (msg==WM_LBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONDOWN,htc,p); + if (msg==WM_LBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCLBUTTONDBLCLK,htc,p); + if (msg==WM_RBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONUP,htc,p); + if (msg==WM_RBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONDOWN,htc,p); + if (msg==WM_RBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCRBUTTONDBLCLK,htc,p); + if (msg==WM_MBUTTONUP) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONUP,htc,p); + if (msg==WM_MBUTTONDOWN) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONDOWN,htc,p); + if (msg==WM_MBUTTONDBLCLK) return hwnd->m_wndproc(hwnd,WM_NCMBUTTONDBLCLK,htc,p); + } + } + + + LRESULT ret=hwnd->m_wndproc(hwnd,msg,wParam,lParam); + + if (msg==WM_LBUTTONUP || msg==WM_RBUTTONUP || msg==WM_MOUSEMOVE || msg==WM_MBUTTONUP) + { + if (!GetCapture() && (hwnd->m_hashaddestroy || !hwnd->m_wndproc || !hwnd->m_wndproc(hwnd,WM_SETCURSOR,(WPARAM)hwnd,htc | (msg<<16)))) + { + // todo: set default cursor + } + } + + return ret; +} + +static void swell_gdkEventHandler(GdkEvent *evt, gpointer data) +{ + { + HWND hwnd = NULL; + if (((GdkEventAny*)evt)->window) gdk_window_get_user_data(((GdkEventAny*)evt)->window,(gpointer*)&hwnd); + + if (hwnd) // validate window (todo later have a window class that we check) + { + HWND a = SWELL_topwindows; + while (a && a != hwnd) a=a->m_next; + if (!a) hwnd=NULL; + } + + if (evt->type == GDK_FOCUS_CHANGE) + { + GdkEventFocus *fc = (GdkEventFocus *)evt; + if (fc->in) SWELL_g_focus_oswindow = hwnd ? fc->window : NULL; + } + + if (hwnd) switch (evt->type) + { + case GDK_DELETE: + if (IsWindowEnabled(hwnd) && !SendMessage(hwnd,WM_CLOSE,0,0)) + SendMessage(hwnd,WM_COMMAND,IDCANCEL,0); + break; + case GDK_EXPOSE: // paint! GdkEventExpose... + { + GdkEventExpose *exp = (GdkEventExpose*)evt; +#ifdef SWELL_LICE_GDI + // super slow + RECT r,cr; + + // don't use GetClientRect(),since we're getting it pre-NCCALCSIZE etc + + cr.right = gdk_window_get_width(hwnd->m_oswindow); + cr.bottom = gdk_window_get_height(hwnd->m_oswindow); + cr.left=cr.top=0; + + r.left = exp->area.x; + r.top=exp->area.y; + r.bottom=r.top+exp->area.height; + r.right=r.left+exp->area.width; + if (!hwnd->m_backingstore) + hwnd->m_backingstore = new LICE_MemBitmap; + + bool forceref = hwnd->m_backingstore->resize(cr.right-cr.left,cr.bottom-cr.top); + if (forceref) r = cr; + + LICE_SubBitmap tmpbm(hwnd->m_backingstore,r.left,r.top,r.right-r.left,r.bottom-r.top); + + if (tmpbm.getWidth()>0 && tmpbm.getHeight()>0) + { + void SWELL_internalLICEpaint(HWND hwnd, LICE_IBitmap *bmout, int bmout_xpos, int bmout_ypos, bool forceref); + SWELL_internalLICEpaint(hwnd, &tmpbm, r.left, r.top, forceref); + cairo_t *crc = gdk_cairo_create (exp->window); + cairo_surface_t *temp_surface = cairo_image_surface_create_for_data((guchar*)tmpbm.getBits(), CAIRO_FORMAT_RGB24, tmpbm.getWidth(),tmpbm.getHeight(), tmpbm.getRowSpan()*4); +// cairo_surface_t *sub_surface = cairo_surface_create_for_rectangle(hwnd->m_backingstore, 0, 0, cr.right, cr.bottom); + cairo_set_source_surface(crc, temp_surface, r.left, r.top); + cairo_paint(crc); + cairo_surface_destroy(temp_surface); + cairo_destroy(crc); + } +#endif + } + break; + case GDK_CONFIGURE: // size/move, GdkEventConfigure + { + GdkEventConfigure *cfg = (GdkEventConfigure*)evt; + int flag=0; + if (cfg->x != hwnd->m_position.left || cfg->y != hwnd->m_position.top) flag|=1; + if (cfg->width != hwnd->m_position.right-hwnd->m_position.left || cfg->height != hwnd->m_position.bottom - hwnd->m_position.top) flag|=2; + hwnd->m_position.left = cfg->x; + hwnd->m_position.top = cfg->y; + hwnd->m_position.right = cfg->x + cfg->width; + hwnd->m_position.bottom = cfg->y + cfg->height; + if (flag&1) SendMessage(hwnd,WM_MOVE,0,0); + if (flag&2) SendMessage(hwnd,WM_SIZE,0,0); + } + break; + case GDK_WINDOW_STATE: /// GdkEventWindowState for min/max + printf("minmax\n"); + break; + case GDK_GRAB_BROKEN: + { + GdkEventGrabBroken *bk = (GdkEventGrabBroken*)evt; + if (s_captured_window) + { + SendMessage(s_captured_window,WM_CAPTURECHANGED,0,0); + s_captured_window=0; + } + } + break; + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + { // todo: pass through app-specific default processing before sending to child window + GdkEventKey *k = (GdkEventKey *)evt; + //printf("key%s: %d %s\n", evt->type == GDK_KEY_PRESS ? "down" : "up", k->keyval, k->string); + int modifiers = FVIRTKEY; + if (k->state&GDK_SHIFT_MASK) modifiers|=FSHIFT; + if (k->state&GDK_CONTROL_MASK) modifiers|=FCONTROL; + if (k->state&GDK_MOD1_MASK) modifiers|=FALT; + + int kv = swell_gdkConvertKey(k->keyval); + kv=toupper(kv); + + HWND foc = GetFocus(); + if (foc && IsChild(hwnd,foc)) hwnd=foc; + MSG msg = { hwnd, evt->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP, kv, modifiers, }; + if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE,(INT_PTR)&msg,0)<=0) + SendMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + break; + case GDK_MOTION_NOTIFY: + { + GdkEventMotion *m = (GdkEventMotion *)evt; + s_lastMessagePos = MAKELONG(((int)m->x_root&0xffff),((int)m->y_root&0xffff)); +// printf("motion %d %d %d %d\n", (int)m->x, (int)m->y, (int)m->x_root, (int)m->y_root); + POINT p={m->x, m->y}; + HWND hwnd2 = GetCapture(); + if (!hwnd2) hwnd2=ChildWindowFromPoint(hwnd, p); +//char buf[1024]; +//GetWindowText(hwnd2,buf,sizeof(buf)); + // printf("%x %s\n", hwnd2,buf); + POINT p2={m->x_root, m->y_root}; + ScreenToClient(hwnd2, &p2); + //printf("%d %d\n", p2.x, p2.y); + if (hwnd2) hwnd2->Retain(); + SendMouseMessage(hwnd2, WM_MOUSEMOVE, 0, MAKELPARAM(p2.x, p2.y)); + if (hwnd2) hwnd2->Release(); + gdk_event_request_motions(m); + } + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + { + GdkEventButton *b = (GdkEventButton *)evt; + s_lastMessagePos = MAKELONG(((int)b->x_root&0xffff),((int)b->y_root&0xffff)); +// printf("button %d %d %d %d %d\n", evt->type, (int)b->x, (int)b->y, (int)b->x_root, (int)b->y_root); + POINT p={b->x, b->y}; + HWND hwnd2 = GetCapture(); + if (!hwnd2) hwnd2=ChildWindowFromPoint(hwnd, p); +// printf("%x\n", hwnd2); + POINT p2={b->x_root, b->y_root}; + ScreenToClient(hwnd2, &p2); + //printf("%d %d\n", p2.x, p2.y); + int msg=WM_LBUTTONDOWN; + if (b->button==2) msg=WM_MBUTTONDOWN; + else if (b->button==3) msg=WM_RBUTTONDOWN; + + if (hwnd && hwnd->m_oswindow && + SWELL_g_focus_oswindow != hwnd->m_oswindow) + SWELL_g_focus_oswindow = hwnd->m_oswindow; + + if(evt->type == GDK_BUTTON_RELEASE) msg++; // move from down to up + else if(evt->type == GDK_2BUTTON_PRESS) msg+=2; // move from down to up + if (hwnd2) hwnd2->Retain(); + SendMouseMessage(hwnd2, msg, 0, MAKELPARAM(p2.x, p2.y)); + if (hwnd2) hwnd2->Release(); + } + break; + default: + //printf("msg: %d\n",evt->type); + break; + } + + } +} + +void swell_runOSevents() +{ + if (SWELL_gdk_active>0) + { +// static GMainLoop *loop; +// if (!loop) loop = g_main_loop_new(NULL,TRUE); + gdk_window_process_all_updates(); + + GdkEvent *evt; + while (gdk_events_pending() && (evt = gdk_event_get())) + { + swell_gdkEventHandler(evt,(gpointer)1); + gdk_event_free(evt); + } + } +} + +#else +void SWELL_initargs(int *argc, char ***argv) +{ +} +void swell_OSupdateWindowToScreen(HWND hwnd, RECT *rect) +{ +} +#define swell_initwindowsys() (0) +#define swell_destroyOSwindow(x) +#define swell_manageOSwindow(x,y) +#define swell_runOSevents() +#define swell_setOSwindowtext(x) { if (x) printf("SWELL: swt '%s'\n",(x)->m_title ? (x)->m_title : ""); } +#endif + +HWND__::HWND__(HWND par, int wID, RECT *wndr, const char *label, bool visible, WNDPROC wndproc, DLGPROC dlgproc) +{ + m_refcnt=1; + m_private_data=0; + + m_classname = "unknown"; + m_wndproc=wndproc?wndproc:dlgproc?(WNDPROC)SwellDialogDefaultWindowProc:(WNDPROC)DefWindowProc; + m_dlgproc=dlgproc; + m_userdata=0; + m_style=0; + m_exstyle=0; + m_id=wID; + m_owned=m_owner=0; + m_children=m_parent=m_next=m_prev=0; + if (wndr) m_position = *wndr; + else memset(&m_position,0,sizeof(m_position)); + memset(&m_extra,0,sizeof(m_extra)); + m_visible=visible; + m_hashaddestroy=false; + m_enabled=true; + m_wantfocus=true; + m_menu=NULL; +#ifdef SWELL_TARGET_GDK + m_oswindow = 0; +#endif + +#ifdef SWELL_LICE_GDI + m_paintctx=0; + m_invalidated=true; + m_child_invalidated=true; + m_backingstore=0; +#endif + + m_title=label ? strdup(label) : NULL; + SetParent(this, par); + +} + +HWND__::~HWND__() +{ +} + + + +HWND GetParent(HWND hwnd) +{ + return hwnd ? hwnd->m_parent : NULL; +} + +HWND GetDlgItem(HWND hwnd, int idx) +{ + if (!idx) return hwnd; + if (hwnd) hwnd=hwnd->m_children; + while (hwnd && hwnd->m_id != idx) hwnd=hwnd->m_next; + return hwnd; +} + + +LONG_PTR SetWindowLong(HWND hwnd, int idx, LONG_PTR val) +{ + if (!hwnd) return 0; + if (idx==GWL_STYLE) + { + // todo: special case for buttons + LONG ret = hwnd->m_style; + hwnd->m_style=val; + return ret; + } + if (idx==GWL_EXSTYLE) + { + LONG ret = hwnd->m_exstyle; + hwnd->m_exstyle=val; + return ret; + } + if (idx==GWL_USERDATA) + { + LONG_PTR ret = hwnd->m_userdata; + hwnd->m_userdata=val; + return ret; + } + if (idx==GWL_ID) + { + LONG ret = hwnd->m_id; + hwnd->m_id=val; + return ret; + } + + if (idx==GWL_WNDPROC) + { + LONG_PTR ret = (LONG_PTR)hwnd->m_wndproc; + hwnd->m_wndproc=(WNDPROC)val; + return ret; + } + if (idx==DWL_DLGPROC) + { + LONG_PTR ret = (LONG_PTR)hwnd->m_dlgproc; + hwnd->m_dlgproc=(DLGPROC)val; + return ret; + } + + if (idx>=0 && idx < 64*(int)sizeof(INT_PTR)) + { + INT_PTR ret = hwnd->m_extra[idx/sizeof(INT_PTR)]; + hwnd->m_extra[idx/sizeof(INT_PTR)]=val; + return (LONG_PTR)ret; + } + return 0; +} + +LONG_PTR GetWindowLong(HWND hwnd, int idx) +{ + if (!hwnd) return 0; + if (idx==GWL_STYLE) + { + // todo: special case for buttons + return hwnd->m_style; + } + if (idx==GWL_EXSTYLE) + { + return hwnd->m_exstyle; + } + if (idx==GWL_USERDATA) + { + return hwnd->m_userdata; + } + if (idx==GWL_ID) + { + return hwnd->m_id; + } + + if (idx==GWL_WNDPROC) + { + return (LONG_PTR)hwnd->m_wndproc; + } + if (idx==DWL_DLGPROC) + { + return (LONG_PTR)hwnd->m_dlgproc; + } + + if (idx>=0 && idx < 64*(int)sizeof(INT_PTR)) + { + return (LONG_PTR)hwnd->m_extra[idx/sizeof(INT_PTR)]; + } + return 0; +} + + +bool IsWindow(HWND hwnd) +{ + // todo: verify window is valid (somehow) + return !!hwnd; +} + +bool IsWindowVisible(HWND hwnd) +{ + if (!hwnd) return false; + while (hwnd->m_visible) + { + hwnd = hwnd->m_parent; + if (!hwnd) return true; + } + return false; +} + +LRESULT SendMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (!hwnd) return 0; + WNDPROC wp = hwnd->m_wndproc; + + if (msg == WM_DESTROY) + { + if (hwnd->m_hashaddestroy) return 0;// todo: allow certain messages to pass? + hwnd->m_hashaddestroy=true; + if (GetCapture()==hwnd) ReleaseCapture(); + SWELL_MessageQueue_Clear(hwnd); + } + else if (msg==WM_CAPTURECHANGED && hwnd->m_hashaddestroy) return 0; + + int ret = wp ? wp(hwnd,msg,wParam,lParam) : 0; + + if (msg == WM_DESTROY) + { + if (GetCapture()==hwnd) ReleaseCapture(); + + SWELL_MessageQueue_Clear(hwnd); + // send WM_DESTROY to all children + HWND tmp=hwnd->m_children; + while (tmp) + { + SendMessage(tmp,WM_DESTROY,0,0); + tmp=tmp->m_next; + } + tmp=hwnd->m_owned; + while (tmp) + { + SendMessage(tmp,WM_DESTROY,0,0); + tmp=tmp->m_next; + } + KillTimer(hwnd,-1); + if (SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd=0; + } + return ret; +} + +static void swell_removeWindowFromNonChildren(HWND__ *hwnd) +{ + if (hwnd->m_next) hwnd->m_next->m_prev = hwnd->m_prev; + if (hwnd->m_prev) hwnd->m_prev->m_next = hwnd->m_next; + else + { + if (hwnd->m_parent && hwnd->m_parent->m_children == hwnd) hwnd->m_parent->m_children = hwnd->m_next; + if (hwnd->m_owner && hwnd->m_owner->m_owned == hwnd) hwnd->m_owner->m_owned = hwnd->m_next; + if (hwnd == SWELL_topwindows) SWELL_topwindows = hwnd->m_next; + } +} + +static void RecurseDestroyWindow(HWND hwnd) +{ + HWND tmp=hwnd->m_children; + while (tmp) + { + HWND old = tmp; + tmp=tmp->m_next; + RecurseDestroyWindow(old); + } + tmp=hwnd->m_owned; + while (tmp) + { + HWND old = tmp; + tmp=tmp->m_next; + RecurseDestroyWindow(old); + } + + if (s_captured_window == hwnd) s_captured_window=NULL; + if (SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd=NULL; + + swell_destroyOSwindow(hwnd); + + free(hwnd->m_title); + hwnd->m_title=0; + + if (hwnd->m_menu) DestroyMenu(hwnd->m_menu); + hwnd->m_menu=0; + +#ifdef SWELL_LICE_GDI + delete hwnd->m_backingstore; + hwnd->m_backingstore=0; +#endif + + hwnd->m_wndproc=NULL; + hwnd->Release(); +} + + +void DestroyWindow(HWND hwnd) +{ + if (!hwnd) return; + if (hwnd->m_hashaddestroy) return; + + // broadcast WM_DESTROY + SendMessage(hwnd,WM_DESTROY,0,0); + + // remove from parent/global lists + swell_removeWindowFromNonChildren(hwnd); + + // safe to delete this window and all children directly + RecurseDestroyWindow(hwnd); +} + + +bool IsWindowEnabled(HWND hwnd) +{ + if (!hwnd) return false; + while (hwnd && hwnd->m_enabled) + { + hwnd=hwnd->m_parent; + } + return !hwnd; +} + +void EnableWindow(HWND hwnd, int enable) +{ + if (!hwnd) return; + hwnd->m_enabled=!!enable; +#ifdef SWELL_TARGET_GDK + if (hwnd->m_oswindow) gdk_window_set_accept_focus(hwnd->m_oswindow,!!enable); +#endif + + if (!enable && SWELL_g_focuswnd == hwnd) SWELL_g_focuswnd = 0; +} + + +void SetFocus(HWND hwnd) +{ + if (!hwnd) return; + + SWELL_g_focuswnd = hwnd; +#ifdef SWELL_TARGET_GDK + while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; + if (hwnd) gdk_window_raise(hwnd->m_oswindow); + if (hwnd && hwnd->m_oswindow != SWELL_g_focus_oswindow) + { + gdk_window_focus(SWELL_g_focus_oswindow = hwnd->m_oswindow,GDK_CURRENT_TIME); + } +#endif +} +void SetForegroundWindow(HWND hwnd) +{ + SetFocus(hwnd); +} + + +int IsChild(HWND hwndParent, HWND hwndChild) +{ + if (!hwndParent || !hwndChild || hwndParent == hwndChild) return 0; + + while (hwndChild && hwndChild != hwndParent) hwndChild = hwndChild->m_parent; + + return hwndChild == hwndParent; +} + + +HWND GetForegroundWindowIncludeMenus() +{ +#ifdef SWELL_TARGET_GDK + if (!SWELL_g_focus_oswindow) return 0; + HWND a = SWELL_topwindows; + while (a && a->m_oswindow != SWELL_g_focus_oswindow) a=a->m_next; + return a; +#else + HWND h = SWELL_g_focuswnd; + while (h && h->m_parent) h=h->m_parent; + return h; +#endif +} + +HWND GetFocusIncludeMenus() +{ +#ifdef SWELL_TARGET_GDK + if (!SWELL_g_focus_oswindow) return 0; + HWND a = SWELL_topwindows; + while (a && a->m_oswindow != SWELL_g_focus_oswindow) a=a->m_next; + return a && IsChild(a,SWELL_g_focuswnd) ? SWELL_g_focuswnd : a; +#else + return SWELL_g_focuswnd; +#endif +} + +HWND GetForegroundWindow() +{ + HWND h =GetForegroundWindowIncludeMenus(); + HWND ho; + while (h && (ho=(HWND)GetProp(h,"SWELL_MenuOwner"))) h=ho; + return h; +} + +HWND GetFocus() +{ + HWND h =GetFocusIncludeMenus(); + HWND ho; + while (h && (ho=(HWND)GetProp(h,"SWELL_MenuOwner"))) h=ho; + return h; +} + + +void SWELL_GetViewPort(RECT *r, RECT *sourcerect, bool wantWork) +{ +#ifdef SWELL_TARGET_GDK + if (swell_initwindowsys()) + { + GdkScreen *defscr = gdk_screen_get_default(); + if (!defscr) { r->left=r->top=0; r->right=r->bottom=1024; return; } + gint idx = sourcerect ? gdk_screen_get_monitor_at_point(defscr, + (sourcerect->left+sourcerect->right)/2, + (sourcerect->top+sourcerect->bottom)/2) : 0; + GdkRectangle rc={0,0,1024,1024}; + gdk_screen_get_monitor_geometry(defscr,idx,&rc); + r->left=rc.x; r->top = rc.y; + r->right=rc.x+rc.width; + r->bottom=rc.y+rc.height; + return; + } +#endif + r->left=r->top=0; + r->right=1024; + r->bottom=768; +} + + +void ScreenToClient(HWND hwnd, POINT *p) +{ + if (!hwnd) return; + + int x=p->x,y=p->y; + + HWND tmp=hwnd, ltmp=0; + while (tmp +#ifdef SWELL_TARGET_GDK + && !tmp->m_oswindow +#endif + ) // top level window's m_position left/top should always be 0 anyway + { + RECT tr=tmp->m_position; + if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); + + x -= tr.left; + y -= tr.top; + tmp = tmp->m_parent; + } + + if (tmp) + { + RECT tr=tmp->m_position; + if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); + x -= tr.left - tmp->m_position.left; + y -= tr.top - tmp->m_position.top; + } + +#ifdef SWELL_TARGET_GDK + if (tmp && tmp->m_oswindow) + { + GdkWindow *wnd = tmp->m_oswindow; + gint px=0,py=0; + gdk_window_get_origin(wnd,&px,&py); // this is probably unreliable but ugh (use get_geometry?) + x-=px; + y-=py; + } +#endif + + p->x=x; + p->y=y; +} + +void ClientToScreen(HWND hwnd, POINT *p) +{ + if (!hwnd) return; + + int x=p->x,y=p->y; + + HWND tmp=hwnd,ltmp=0; + while (tmp +#ifdef SWELL_TARGET_GDK + && !tmp->m_oswindow +#endif + ) // top level window's m_position left/top should always be 0 anyway + { + RECT tr=tmp->m_position; + if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); + x += tr.left; + y += tr.top; + tmp = tmp->m_parent; + } + if (tmp) + { + RECT tr=tmp->m_position; + if (tmp->m_wndproc) tmp->m_wndproc(tmp,WM_NCCALCSIZE,0,(LPARAM)&tr); + x += tr.left - tmp->m_position.left; + y += tr.top - tmp->m_position.top; + } + +#ifdef SWELL_TARGET_GDK + if (tmp && tmp->m_oswindow) + { + GdkWindow *wnd = tmp->m_oswindow; + gint px=0,py=0; + gdk_window_get_origin(wnd,&px,&py); // this is probably unreliable but ugh (use get_geometry?) + x+=px; + y+=py; + } +#endif + + p->x=x; + p->y=y; +} + +bool GetWindowRect(HWND hwnd, RECT *r) +{ + if (!hwnd) return false; +#ifdef SWELL_TARGET_GDK + if (hwnd->m_oswindow) + { + GdkRectangle rc; + gdk_window_get_frame_extents(hwnd->m_oswindow,&rc); + r->left=rc.x; + r->top=rc.y; + r->right=rc.x+rc.width; + r->bottom = rc.y+rc.height; + return true; + } +#endif + + r->left=r->top=0; + ClientToScreen(hwnd,(LPPOINT)r); + r->right = r->left + hwnd->m_position.right - hwnd->m_position.left; + r->bottom = r->top + hwnd->m_position.bottom - hwnd->m_position.top; + return true; +} + +void GetWindowContentViewRect(HWND hwnd, RECT *r) +{ +#ifdef SWELL_TARGET_GDK + if (hwnd && hwnd->m_oswindow) + { + gint w=0,h=0,px=0,py=0; + gdk_window_get_position(hwnd->m_oswindow,&px,&py); + w = gdk_window_get_width(hwnd->m_oswindow); + h = gdk_window_get_height(hwnd->m_oswindow); + r->left=px; + r->top=py; + r->right = px+w; + r->bottom = py+h; + return; + } +#endif + GetWindowRect(hwnd,r); +} + +void GetClientRect(HWND hwnd, RECT *r) +{ + r->left=r->top=r->right=r->bottom=0; + if (!hwnd) return; + +#ifdef SWELL_TARGET_GDK + if (hwnd->m_oswindow) + { + r->right = gdk_window_get_width(hwnd->m_oswindow); + r->bottom = gdk_window_get_height(hwnd->m_oswindow); + + } + else +#endif + { + r->right = hwnd->m_position.right - hwnd->m_position.left; + r->bottom = hwnd->m_position.bottom - hwnd->m_position.top; + } + + RECT tr=*r; + SendMessage(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&tr); + r->right = r->left + (tr.right-tr.left); + r->bottom=r->top + (tr.bottom-tr.top); +} + + + +void SetWindowPos(HWND hwnd, HWND zorder, int x, int y, int cx, int cy, int flags) +{ + if (!hwnd) return; + // todo: handle SWP_SHOWWINDOW + RECT f = hwnd->m_position; + int reposflag = 0; + if (!(flags&SWP_NOZORDER)) + { + if (hwnd->m_parent && zorder != hwnd) + { + HWND tmp = hwnd->m_parent->m_children; + while (tmp && tmp != hwnd) tmp=tmp->m_next; + if (tmp) // we are in the list, so we can do a reorder + { + // take hwnd out of list + if (hwnd->m_prev) hwnd->m_prev->m_next = hwnd->m_next; + else hwnd->m_parent->m_children = hwnd->m_next; + if (hwnd->m_next) hwnd->m_next->m_prev = hwnd->m_prev; + hwnd->m_next=hwnd->m_prev=NULL;// leave hwnd->m_parent valid since it wont change + + // add back in + tmp = hwnd->m_parent->m_children; + if (zorder == HWND_TOP || !tmp || tmp == zorder) // no children, topmost, or zorder is at top already + { + if (tmp) tmp->m_prev=hwnd; + hwnd->m_next = tmp; + hwnd->m_parent->m_children = hwnd; + } + else if (zorder == HWND_BOTTOM) + { + while (tmp && tmp->m_next) tmp=tmp->m_next; + tmp->m_next=hwnd; + hwnd->m_prev=tmp; + } + else + { + HWND ltmp=NULL; + while (tmp && tmp != zorder) tmp=(ltmp=tmp)->m_next; + + hwnd->m_next = ltmp->m_next; + hwnd->m_prev = ltmp; + if (ltmp->m_next) ltmp->m_next->m_prev = hwnd; + ltmp->m_next = hwnd; + } + reposflag|=4; + } + } + } + if (!(flags&SWP_NOMOVE)) + { + int oldw = f.right-f.left; + int oldh = f.bottom-f.top; + f.left=x; + f.right=x+oldw; + f.top=y; + f.bottom=y+oldh; + reposflag|=1; + } + if (!(flags&SWP_NOSIZE)) + { + f.right = f.left + cx; + f.bottom = f.top + cy; + reposflag|=2; + } + if (reposflag) + { +#ifdef SWELL_TARGET_GDK + if (hwnd->m_oswindow) + { + //printf("repos %d,%d,%d,%d, %d\n",f.left,f.top,f.right,f.bottom,reposflag); + if ((reposflag&3)==3) gdk_window_move_resize(hwnd->m_oswindow,f.left,f.top,f.right-f.left,f.bottom-f.top); + else if (reposflag&2) gdk_window_resize(hwnd->m_oswindow,f.right-f.left,f.bottom-f.top); + else if (reposflag&1) gdk_window_move(hwnd->m_oswindow,f.left,f.top); + } + else // top level windows above get their position from gdk and cache it in m_position +#endif + { + if (reposflag&3) + { + hwnd->m_position = f; + SendMessage(hwnd,WM_SIZE,0,0); + } + InvalidateRect(hwnd->m_parent ? hwnd->m_parent : hwnd,NULL,FALSE); + } + } + +} + + + +HWND GetWindow(HWND hwnd, int what) +{ + if (!hwnd) return 0; + + if (what == GW_CHILD) return hwnd->m_children; + if (what == GW_OWNER) return hwnd->m_owner; + if (what == GW_HWNDNEXT) return hwnd->m_next; + if (what == GW_HWNDPREV) return hwnd->m_prev; + if (what == GW_HWNDFIRST) + { + while (hwnd->m_prev) hwnd = hwnd->m_prev; + return hwnd; + } + if (what == GW_HWNDLAST) + { + while (hwnd->m_next) hwnd = hwnd->m_next; + return hwnd; + } + return 0; +} + +HWND SetParent(HWND hwnd, HWND newPar) +{ + if (!hwnd) return NULL; + + swell_removeWindowFromNonChildren(hwnd); + + HWND oldPar = hwnd->m_parent; + hwnd->m_prev=0; + hwnd->m_next=0; + hwnd->m_parent = NULL; + hwnd->m_owner = NULL; // todo + + if (newPar) + { + hwnd->m_parent = newPar; + hwnd->m_next=newPar->m_children; + if (hwnd->m_next) hwnd->m_next->m_prev = hwnd; + newPar->m_children=hwnd; + } + else // add to top level windows + { + hwnd->m_next=SWELL_topwindows; + if (hwnd->m_next) hwnd->m_next->m_prev = hwnd; + SWELL_topwindows = hwnd; + } + + swell_manageOSwindow(hwnd,false); + return oldPar; +} + + + + +// timer stuff +typedef struct TimerInfoRec +{ + UINT_PTR timerid; + HWND hwnd; + UINT interval; + DWORD nextFire; + TIMERPROC tProc; + struct TimerInfoRec *_next; +} TimerInfoRec; + +static TimerInfoRec *m_timer_list; +static WDL_Mutex m_timermutex; +static pthread_t m_pmq_mainthread; + +void SWELL_RunMessageLoop() +{ + SWELL_MessageQueue_Flush(); + swell_runOSevents(); + + DWORD now = GetTickCount(); + WDL_MutexLock lock(&m_timermutex); + int x; + TimerInfoRec *rec = m_timer_list; + while (rec) + { + if (now > rec->nextFire || now < rec->nextFire - rec->interval*4) + { + rec->nextFire = now + rec->interval; + + HWND h = rec->hwnd; + TIMERPROC tProc = rec->tProc; + UINT_PTR tid = rec->timerid; + m_timermutex.Leave(); + + if (tProc) tProc(h,WM_TIMER,tid,now); + else if (h) SendMessage(h,WM_TIMER,tid,0); + + m_timermutex.Enter(); + TimerInfoRec *tr = m_timer_list; + while (tr && tr != rec) tr=tr->_next; + if (!tr) + { + rec = m_timer_list; // if no longer in the list, then abort + continue; + } + } + rec=rec->_next; + } +} + + +UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) +{ + if (!hwnd && !tProc) return 0; // must have either callback or hwnd + + if (hwnd && !timerid) return 0; + + WDL_MutexLock lock(&m_timermutex); + TimerInfoRec *rec=NULL; + if (hwnd||timerid) + { + rec = m_timer_list; + while (rec) + { + if (rec->timerid == timerid && rec->hwnd == hwnd) // works for both kinds + break; + rec=rec->_next; + } + } + + bool recAdd=false; + if (!rec) + { + rec=(TimerInfoRec*)malloc(sizeof(TimerInfoRec)); + recAdd=true; + } + + rec->tProc = tProc; + rec->timerid=timerid; + rec->hwnd=hwnd; + rec->interval = rate<1?1: rate; + rec->nextFire = GetTickCount() + rate; + + if (!hwnd) timerid = rec->timerid = (UINT_PTR)rec; + + if (recAdd) + { + rec->_next=m_timer_list; + m_timer_list=rec; + } + + return timerid; +} + +BOOL KillTimer(HWND hwnd, UINT_PTR timerid) +{ + if (!hwnd && !timerid) return FALSE; + + WDL_MutexLock lock(&m_timermutex); + BOOL rv=FALSE; + + // don't allow removing all global timers + if (timerid!=-1 || hwnd) + { + TimerInfoRec *rec = m_timer_list, *lrec=NULL; + while (rec) + { + if (rec->hwnd == hwnd && (timerid==-1 || rec->timerid == timerid)) + { + TimerInfoRec *nrec = rec->_next; + + // remove self from list + if (lrec) lrec->_next = nrec; + else m_timer_list = nrec; + + free(rec); + + rv=TRUE; + if (timerid!=-1) break; + + rec=nrec; + } + else + { + lrec=rec; + rec=rec->_next; + } + } + } + return rv; +} + +BOOL SetDlgItemText(HWND hwnd, int idx, const char *text) +{ + hwnd =(idx ? GetDlgItem(hwnd,idx) : hwnd); + if (!hwnd) return false; + + if (!text) text=""; + + + if (strcmp(hwnd->m_title ? hwnd->m_title : "", text)) + { + if (*text && hwnd->m_title && strlen(hwnd->m_title)>=strlen(text)) strcpy(hwnd->m_title,text); + else + { + free(hwnd->m_title); + hwnd->m_title = text[0] ? strdup(text) : NULL; + } + SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)text); + swell_setOSwindowtext(hwnd); + } + return true; +} + +BOOL GetDlgItemText(HWND hwnd, int idx, char *text, int textlen) +{ + *text=0; + hwnd = idx?GetDlgItem(hwnd,idx) : hwnd; + if (!hwnd) return false; + + // todo: sendmessage WM_GETTEXT etc? special casing for combo boxes etc + lstrcpyn(text,hwnd->m_title ? hwnd->m_title : "", textlen); + return true; +} + +void CheckDlgButton(HWND hwnd, int idx, int check) +{ + hwnd = GetDlgItem(hwnd,idx); + if (!hwnd) return; + SendMessage(hwnd,BM_SETCHECK,check,0); +} + + +int IsDlgButtonChecked(HWND hwnd, int idx) +{ + hwnd = GetDlgItem(hwnd,idx); + if (!hwnd) return 0; + return SendMessage(hwnd,BM_GETCHECK,0,0); +} + + +BOOL SetDlgItemInt(HWND hwnd, int idx, int val, int issigned) +{ + char buf[128]; + sprintf(buf,issigned?"%d":"%u",val); + return SetDlgItemText(hwnd,idx,buf); +} + +int GetDlgItemInt(HWND hwnd, int idx, BOOL *translated, int issigned) +{ + char buf[128]; + if (!GetDlgItemText(hwnd,idx,buf,sizeof(buf))) + { + if (translated) *translated=0; + return 0; + } + char *p=buf; + while (*p == ' ' || *p == '\t') p++; + int a=atoi(p); + if ((a<0 && !issigned) || (!a && p[0] != '0')) { if (translated) *translated=0; return 0; } + if (translated) *translated=1; + return a; +} + +void ShowWindow(HWND hwnd, int cmd) +{ + if (!hwnd) return; + + if (cmd==SW_SHOW||cmd==SW_SHOWNA) + { + hwnd->m_visible=true; + } + else if (cmd==SW_HIDE) hwnd->m_visible=false; + + swell_manageOSwindow(hwnd,cmd==SW_SHOW); + InvalidateRect(hwnd,NULL,FALSE); + +} + +void *SWELL_ModalWindowStart(HWND hwnd) +{ + return 0; +} + +bool SWELL_ModalWindowRun(void *ctx, int *ret) // returns false and puts retval in *ret when done +{ + return false; +} + +void SWELL_ModalWindowEnd(void *ctx) +{ + if (ctx) + { + } +} + +void SWELL_CloseWindow(HWND hwnd) +{ + DestroyWindow(hwnd); +} + + +#include "swell-dlggen.h" + +static HWND m_make_owner; +static RECT m_transform; +static bool m_doautoright; +static RECT m_lastdoauto; +static bool m_sizetofits; + +#define ACTIONTARGET (m_make_owner) + +void SWELL_MakeSetCurParms(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit) +{ + m_sizetofits=dosizetofit; + m_lastdoauto.left = 0; + m_lastdoauto.top = -100<<16; + m_lastdoauto.right = 0; + m_doautoright=doauto; + m_transform.left=(int)(xtrans*65536.0); + m_transform.top=(int)(ytrans*65536.0); + m_transform.right=(int)(xscale*65536.0); + m_transform.bottom=(int)(yscale*65536.0); + m_make_owner=parent; +} + +static void UpdateAutoCoords(RECT r) +{ + m_lastdoauto.right=r.left + r.right - m_lastdoauto.left; +} + + +static RECT MakeCoords(int x, int y, int w, int h, bool wantauto) +{ + if (w<0&&h<0) + { + RECT r = { -x, -y, -x-w, -y-h}; + return r; + } + + float ysc=m_transform.bottom/65536.0; + int newx=(int)((x+m_transform.left/65536.0)*m_transform.right/65536.0 + 0.5); + int newy=(int)(((((double)y+(double)m_transform.top/65536.0) )*ysc) + 0.5); + + RECT ret= { newx, + newy, + (int) (newx + w*(double)m_transform.right/65536.0+0.5), + (int) (newy + h*fabs(ysc)+0.5) + }; + + + RECT oret=ret; + if (wantauto && m_doautoright) + { + float dx = ret.left - m_lastdoauto.left; + if (fabs(dx)<32 && m_lastdoauto.top >= ret.top && m_lastdoauto.top < ret.bottom) + { + ret.left += (int) m_lastdoauto.right; + } + + m_lastdoauto.left = oret.right; + m_lastdoauto.top = (ret.top + ret.bottom)*0.5; + m_lastdoauto.right=0; + } + return ret; +} + +static const double minwidfontadjust=1.81; +#define TRANSFORMFONTSIZE ((m_transform.right/65536.0+1.0)*3.7) + + +#ifdef SWELL_LICE_GDI +//#define SWELL_ENABLE_VIRTWND_CONTROLS +#include "../wingui/virtwnd-controls.h" +#endif + +static LRESULT WINAPI virtwndWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +#ifdef SWELL_ENABLE_VIRTWND_CONTROLS + WDL_VWnd *vwnd = (WDL_VWnd *) ( msg == WM_CREATE ? (void*)lParam : GetProp(hwnd,"WDL_control_vwnd") ); + if (vwnd) switch (msg) + { + case WM_CREATE: + { + SetProp(hwnd,"WDL_control_vwnd",vwnd); + RECT r; + GetClientRect(hwnd,&r); + vwnd->SetRealParent(hwnd); + vwnd->SetPosition(&r); + vwnd->SetID(0xf); + } + return 0; + case WM_SIZE: + { + RECT r; + GetClientRect(hwnd,&r); + vwnd->SetPosition(&r); + InvalidateRect(hwnd,NULL,FALSE); + } + break; + case WM_COMMAND: + if (LOWORD(wParam)==0xf) SendMessage(GetParent(hwnd),WM_COMMAND,(wParam&0xffff0000) | GetWindowLong(hwnd,GWL_ID),NULL); + break; + case WM_DESTROY: + RemoveProp(hwnd,"WDL_control_vwnd"); + delete vwnd; + vwnd=0; + return 0; + case WM_LBUTTONDOWN: + SetCapture(hwnd); + vwnd->OnMouseDown(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); + return 0; + case WM_MOUSEMOVE: + vwnd->OnMouseMove(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); + return 0; + case WM_LBUTTONUP: + ReleaseCapture(); + vwnd->OnMouseUp(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); + return 0; + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + + HDC hdc = ps.hdc; + if (hdc) + { + RECT tr = ps.rcPaint; // todo: offset by surface_offs.x/y + vwnd->OnPaint(hdc->surface,hdc->surface_offs.x,hdc->surface_offs.y,&tr); + vwnd->OnPaintOver(hdc->surface,hdc->surface_offs.x,hdc->surface_offs.y,&tr); + } + + EndPaint(hwnd,&ps); + } + } + return 0; + case WM_SETTEXT: + if (lParam) + { + if (!strcmp(vwnd->GetType(),"vwnd_iconbutton")) + { + WDL_VirtualIconButton *b = (WDL_VirtualIconButton *) vwnd; + b->SetTextLabel((const char *)lParam); + } + } + break; + case BM_SETCHECK: + case BM_GETCHECK: + if (!strcmp(vwnd->GetType(),"vwnd_iconbutton")) + { + WDL_VirtualIconButton *b = (WDL_VirtualIconButton *) vwnd; + if (msg == BM_GETCHECK) return b->GetCheckState(); + + b->SetCheckState(wParam); + } + return 0; + } +#endif + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +#ifdef SWELL_ENABLE_VIRTWND_CONTROLS +static HWND swell_makeButton(HWND owner, int idx, RECT *tr, const char *label, bool vis, int style) +{ + WDL_VirtualIconButton *vwnd = new WDL_VirtualIconButton; + if (label) vwnd->SetTextLabel(label); + vwnd->SetForceBorder(true); + if (style & BS_AUTOCHECKBOX) vwnd->SetCheckState(0); + HWND hwnd = new HWND__(owner,idx,tr,label,vis,virtwndWindowProc); + hwnd->m_classname = "Button"; + hwnd->m_style = style|WS_CHILD; + hwnd->m_wndproc(hwnd,WM_CREATE,0,(LPARAM)vwnd); + return hwnd; +} + +#endif + + +#ifndef SWELL_ENABLE_VIRTWND_CONTROLS +static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_LBUTTONDOWN: + SetCapture(hwnd); + SendMessage(hwnd,WM_USER+100,0,0); // invalidate + return 0; + case WM_MOUSEMOVE: + return 0; + case WM_LBUTTONUP: + if (GetCapture()==hwnd) + { + ReleaseCapture(); // WM_CAPTURECHANGED will take care of the invalidate + RECT r; + GetClientRect(hwnd,&r); + POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; + if (PtInRect(&r,p) && hwnd->m_id && hwnd->m_parent) + { + int sf = (hwnd->m_style & 0xf); + if (sf == BS_AUTO3STATE) + { + int a = hwnd->m_private_data&3; + if (a==0) a=1; + else if (a==1) a=2; + else a=0; + hwnd->m_private_data = (a) | (hwnd->m_private_data&~3); + } + else if (sf == BS_AUTOCHECKBOX) + { + hwnd->m_private_data = (!(hwnd->m_private_data&3)) | (hwnd->m_private_data&~3); + } + else if (sf == BS_AUTORADIOBUTTON) + { + // todo: uncheck other nearby radios + } + SendMessage(hwnd->m_parent,WM_COMMAND,MAKEWPARAM(hwnd->m_id,BN_CLICKED),(LPARAM)hwnd); + } + } + return 0; + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + bool pressed = GetCapture()==hwnd; + + SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); + SetBkMode(ps.hdc,TRANSPARENT); + + int f=DT_VCENTER; + int sf = (hwnd->m_style & 0xf); + if (sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON) + { + const int chksz = 16; + RECT tr={r.left,(r.top+r.bottom)/2-chksz/2,r.left+chksz}; + tr.bottom = tr.top+chksz; + + HPEN pen=CreatePen(PS_SOLID,0,RGB(0,0,0)); + HGDIOBJ oldPen = SelectObject(ps.hdc,pen); + if (sf == BS_AUTOCHECKBOX || sf == BS_AUTO3STATE) + { + int st = (int)(hwnd->m_private_data&3); + if (st==3||(st==2 && (hwnd->m_style & 0xf) == BS_AUTOCHECKBOX)) st=1; + + HBRUSH br = CreateSolidBrush(st==2?RGB(192,192,192):RGB(255,255,255)); + FillRect(ps.hdc,&tr,br); + DeleteObject(br); + + if (st == 1||pressed) + { + RECT ar=tr; + ar.left+=2; + ar.right-=3; + ar.top+=2; + ar.bottom-=3; + if (pressed) + { + const int rsz=chksz/4; + ar.left+=rsz; + ar.top+=rsz; + ar.right-=rsz; + ar.bottom-=rsz; + } + MoveToEx(ps.hdc,ar.left,ar.top,NULL); + LineTo(ps.hdc,ar.right,ar.bottom); + MoveToEx(ps.hdc,ar.right,ar.top,NULL); + LineTo(ps.hdc,ar.left,ar.bottom); + } + } + else if (sf == BS_AUTORADIOBUTTON) + { + // todo radio circle + } + SelectObject(ps.hdc,oldPen); + DeleteObject(pen); + r.left += chksz + 4; + } + else + { + + HBRUSH br = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + FillRect(ps.hdc,&r,br); + DeleteObject(br); + + HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(pressed?COLOR_3DHILIGHT : COLOR_3DSHADOW)); + HPEN pen = CreatePen(PS_SOLID,0,GetSysColor((!pressed)?COLOR_3DHILIGHT : COLOR_3DSHADOW)); + HGDIOBJ oldpen = SelectObject(ps.hdc,pen); + MoveToEx(ps.hdc,r.left,r.bottom-1,NULL); + LineTo(ps.hdc,r.left,r.top); + LineTo(ps.hdc,r.right-1,r.top); + SelectObject(ps.hdc,pen2); + LineTo(ps.hdc,r.right-1,r.bottom-1); + LineTo(ps.hdc,r.left,r.bottom-1); + SelectObject(ps.hdc,oldpen); + DeleteObject(pen); + DeleteObject(pen2); + f|=DT_CENTER; + if (pressed) + { + r.left+=2; + r.top+=2; + } + } + + + char buf[512]; + buf[0]=0; + GetWindowText(hwnd,buf,sizeof(buf)); + if (buf[0]) DrawText(ps.hdc,buf,-1,&r,f); + + + EndPaint(hwnd,&ps); + } + } + return 0; + case BM_GETCHECK: + if (hwnd) + { + return (hwnd->m_private_data&3)==2 ? 1 : (hwnd->m_private_data&3); + } + return 0; + case BM_SETCHECK: + if (hwnd) + { + int check = (int)wParam; + INT_PTR op = hwnd->m_private_data; + hwnd->m_private_data=(check > 2 || check<0 ? 1 : (check&3)) | (hwnd->m_private_data&~3); + if (hwnd->m_private_data == op) break; + } + else + { + break; + } + // fall through (invalidating) + case WM_USER+100: + case WM_CAPTURECHANGED: + case WM_SETTEXT: + { + int sf = (hwnd->m_style & 0xf); + if (sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON) + { + InvalidateRect(hwnd,NULL,TRUE); + } + else InvalidateRect(hwnd,NULL,FALSE); + } + break; + } + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +static HWND swell_makeButton(HWND owner, int idx, RECT *tr, const char *label, bool vis, int style) +{ + HWND hwnd = new HWND__(owner,idx,tr,label,vis,buttonWindowProc); + hwnd->m_classname = "Button"; + hwnd->m_style = style|WS_CHILD; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + return hwnd; +} +#endif + +static LRESULT WINAPI groupWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + int col = GetSysColor(COLOR_BTNTEXT); + + const char *buf = hwnd->m_title; + int th=20; + int tw=0; + int xp=0; + if (buf && buf[0]) + { + RECT tr={0,}; + DrawText(ps.hdc,buf,-1,&tr,DT_CALCRECT); + th=tr.bottom-tr.top; + tw=tr.right-tr.left; + } + if (hwnd->m_style & SS_CENTER) + { + xp = r.right/2 - tw/2; + } + if (xp<8)xp=8; + if (xp+tw > r.right-8) tw=r.right-8-xp; + + HPEN pen = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT)); + HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); + HGDIOBJ oldPen=SelectObject(ps.hdc,pen); + + MoveToEx(ps.hdc,xp - (tw?4:0) + 1,th/2+1,NULL); + LineTo(ps.hdc,1,th/2+1); + LineTo(ps.hdc,1,r.bottom-1); + LineTo(ps.hdc,r.right-1,r.bottom-1); + LineTo(ps.hdc,r.right-1,th/2+1); + LineTo(ps.hdc,xp+tw + (tw?4:0),th/2+1); + + SelectObject(ps.hdc,pen2); + + MoveToEx(ps.hdc,xp - (tw?4:0),th/2,NULL); + LineTo(ps.hdc,0,th/2); + LineTo(ps.hdc,0,r.bottom-2); + LineTo(ps.hdc,r.right-2,r.bottom-2); + LineTo(ps.hdc,r.right-2,th/2); + LineTo(ps.hdc,xp+tw + (tw?4:0),th/2); + + + SelectObject(ps.hdc,oldPen); + DeleteObject(pen); + DeleteObject(pen2); + + SetTextColor(ps.hdc,col); + SetBkMode(ps.hdc,TRANSPARENT); + r.left = xp; + r.right = xp+tw; + r.bottom = th; + if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,DT_LEFT|DT_TOP); + EndPaint(hwnd,&ps); + } + } + return 0; + case WM_SETTEXT: + InvalidateRect(hwnd,NULL,TRUE); + break; + } + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + HBRUSH br = CreateSolidBrush(RGB(255,255,255)); // todo edit colors + FillRect(ps.hdc,&r,br); + DeleteObject(br); + SetTextColor(ps.hdc,RGB(0,0,0)); // todo edit colors + SetBkMode(ps.hdc,TRANSPARENT); + const char *buf = hwnd->m_title; + if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,DT_VCENTER); + EndPaint(hwnd,&ps); + } + } + return 0; + case WM_SETTEXT: + InvalidateRect(hwnd,NULL,FALSE); + break; + } + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +static LRESULT WINAPI labelWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + + SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); + SetBkMode(ps.hdc,TRANSPARENT); + const char *buf = hwnd->m_title; + if (buf && buf[0]) DrawText(ps.hdc,buf,-1,&r,((hwnd->m_style & SS_CENTER) ? DT_CENTER:0)|DT_VCENTER); + EndPaint(hwnd,&ps); + } + } + return 0; + case WM_SETTEXT: + InvalidateRect(hwnd,NULL,TRUE); + break; + } + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +struct __SWELL_ComboBoxInternalState_rec +{ + __SWELL_ComboBoxInternalState_rec(const char *_desc=NULL, LPARAM _parm=0) { desc=_desc?strdup(_desc):NULL; parm=_parm; } + ~__SWELL_ComboBoxInternalState_rec() { free(desc); } + char *desc; + LPARAM parm; + static int cmp(const __SWELL_ComboBoxInternalState_rec **a, const __SWELL_ComboBoxInternalState_rec **b) { return strcmp((*a)->desc, (*b)->desc); } +}; + +class __SWELL_ComboBoxInternalState +{ + public: + __SWELL_ComboBoxInternalState() { selidx=-1; } + ~__SWELL_ComboBoxInternalState() { } + + int selidx; + WDL_PtrList_DeleteOnDestroy<__SWELL_ComboBoxInternalState_rec> items; +}; + +static LRESULT WINAPI comboWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static const char *stateName = "__SWELL_COMBOBOXSTATE"; + if (msg >= CB_ADDSTRING && msg <= CB_INITSTORAGE) + { + __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); + if (!s) + { + s = new __SWELL_ComboBoxInternalState; + SetProp(hwnd,stateName,(HANDLE)s); + } + if (s) + { + switch (msg) + { + case CB_ADDSTRING: + + if (!(hwnd->m_style & CBS_SORT)) + { + s->items.Add(new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); + return s->items.GetSize() - 1; + } + else + { + __SWELL_ComboBoxInternalState_rec *r=new __SWELL_ComboBoxInternalState_rec((const char *)lParam); + // find position of insert for wParam + bool m; + int idx = s->items.LowerBound(r,&m,__SWELL_ComboBoxInternalState_rec::cmp); + s->items.Insert(idx,r); + return idx; + } + + case CB_INSERTSTRING: + if ((int)wParam == -1) + { + s->items.Add(new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); + return s->items.GetSize() - 1; + } + else + { + if (wParam > s->items.GetSize()) wParam=s->items.GetSize(); + s->items.Insert(wParam,new __SWELL_ComboBoxInternalState_rec((const char *)lParam)); + return wParam; + } + return 0; + + case CB_DELETESTRING: + if (wParam >= s->items.GetSize()) return CB_ERR; + s->items.Delete(wParam,true); + return s->items.GetSize(); + + case CB_GETCOUNT: return s->items.GetSize(); + case CB_GETCURSEL: return s->selidx >=0 && s->selidx < s->items.GetSize() ? s->selidx : -1; + + case CB_GETLBTEXT: + if (wParam < s->items.GetSize()) + { + if (lParam) + { + char *ptr=s->items.Get(wParam)->desc; + int l = strlen(ptr); + memcpy((char *)lParam,ptr,l+1); + return l; + } + } + return CB_ERR; + case CB_RESETCONTENT: + s->selidx=-1; + s->items.Empty(true); + return 0; + case CB_SETCURSEL: + if ((int) wParam == -1 || wParam >= s->items.GetSize()) + { + if (s->selidx!=-1) + { + s->selidx = -1; + SetWindowText(hwnd,""); + InvalidateRect(hwnd,NULL,FALSE); + } + } + else + { + if (s->selidx != wParam) + { + s->selidx=wParam; + char *ptr=s->items.Get(wParam)->desc; + SetWindowText(hwnd,ptr); + InvalidateRect(hwnd,NULL,FALSE); + } + } + case CB_GETITEMDATA: + if (wParam < s->items.GetSize()) + { + return s->items.Get(wParam)->parm; + } + return CB_ERR; + case CB_SETITEMDATA: + if (wParam < s->items.GetSize()) + { + s->items.Get(wParam)->parm=lParam; + return 0; + } + return CB_ERR; + case CB_INITSTORAGE: + return 0; + + case CB_FINDSTRINGEXACT: + case CB_FINDSTRING: + return CB_ERR; + } + } + } + + switch (msg) + { + case WM_DESTROY: + { + __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); + if (s) + { + SetProp(hwnd,stateName,NULL); + delete s; + } + } + break; + + case WM_LBUTTONDOWN: + SetCapture(hwnd); + InvalidateRect(hwnd,NULL,FALSE); + return 0; + case WM_MOUSEMOVE: + return 0; + case WM_LBUTTONUP: + if (GetCapture()==hwnd) + { + ReleaseCapture(); + __SWELL_ComboBoxInternalState *s = (__SWELL_ComboBoxInternalState*)GetProp(hwnd,stateName); + if (s && s->items.GetSize()) + { + int x; + HMENU menu = CreatePopupMenu(); + for (x=0;xitems.GetSize();x++) + { + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, + x == s->selidx?MFS_CHECKED:0,100+x,NULL,NULL,NULL,0,s->items.Get(x)->desc}; + InsertMenuItem(menu,x,TRUE,&mi); + } + RECT r; + GetWindowRect(hwnd,&r); + int a = TrackPopupMenu(menu,TPM_NONOTIFY|TPM_RETURNCMD|TPM_LEFTALIGN,r.left,r.bottom,0,hwnd,0); + DestroyMenu(menu); + if (a>=100 && a < s->items.GetSize()+100) + { + s->selidx = a-100; + char *ptr=s->items.Get(s->selidx)->desc; + SetWindowText(hwnd,ptr); + InvalidateRect(hwnd,NULL,FALSE); + SendMessage(GetParent(hwnd),WM_COMMAND,(GetWindowLong(hwnd,GWL_ID)&0xffff) | (CBN_SELCHANGE<<16),(LPARAM)hwnd); + } + } + } + return 0; + case WM_PAINT: + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + RECT r; + GetClientRect(hwnd,&r); + bool pressed = GetCapture()==hwnd; + + SetTextColor(ps.hdc,GetSysColor(COLOR_BTNTEXT)); + SetBkMode(ps.hdc,TRANSPARENT); + + int f=DT_VCENTER; + { + HBRUSH br = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + FillRect(ps.hdc,&r,br); + DeleteObject(br); + + HPEN pen2 = CreatePen(PS_SOLID,0,GetSysColor(pressed?COLOR_3DHILIGHT : COLOR_3DSHADOW)); + HPEN pen = CreatePen(PS_SOLID,0,GetSysColor((!pressed)?COLOR_3DHILIGHT : COLOR_3DSHADOW)); + HGDIOBJ oldpen = SelectObject(ps.hdc,pen); + MoveToEx(ps.hdc,r.left,r.bottom-1,NULL); + LineTo(ps.hdc,r.left,r.top); + LineTo(ps.hdc,r.right-1,r.top); + SelectObject(ps.hdc,pen2); + LineTo(ps.hdc,r.right-1,r.bottom-1); + LineTo(ps.hdc,r.left,r.bottom-1); + + + const int dw = 8; + const int dh = 4; + const int cx = r.right-dw/2-4; + const int cy = (r.bottom+r.top)/2; + MoveToEx(ps.hdc,cx-dw/2,cy-dh/2,NULL); + LineTo(ps.hdc,cx,cy+dh/2); + LineTo(ps.hdc,cx+dw/2,cy-dh/2); + + + SelectObject(ps.hdc,oldpen); + DeleteObject(pen); + DeleteObject(pen2); + + + if (pressed) + { + r.left+=2; + r.top+=2; + } + } + + char buf[512]; + buf[0]=0; + GetWindowText(hwnd,buf,sizeof(buf)); + if (buf[0]) DrawText(ps.hdc,buf,-1,&r,f); + + EndPaint(hwnd,&ps); + } + } + return 0; + + case WM_CAPTURECHANGED: + case WM_SETTEXT: + InvalidateRect(hwnd,NULL,FALSE); + break; + } + return DefWindowProc(hwnd,msg,wParam,lParam); +} + + +/// these are for swell-dlggen.h +HWND SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags) +{ + UINT_PTR a=(UINT_PTR)label; + if (a < 65536) label = "ICONTEMP"; + + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = swell_makeButton(m_make_owner,idx,&tr,label,!(flags&SWELL_NOT_WS_VISIBLE),0); + + if (m_doautoright) UpdateAutoCoords(tr); + if (def) { } + return hwnd; +} + + +HWND SWELL_MakeLabel( int align, const char *label, int idx, int x, int y, int w, int h, int flags) +{ + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,label, !(flags&SWELL_NOT_WS_VISIBLE),labelWindowProc); + hwnd->m_classname = "static"; + hwnd->m_style = (flags & ~SWELL_NOT_WS_VISIBLE)|WS_CHILD; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; +} +HWND SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags) +{ + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(flags&SWELL_NOT_WS_VISIBLE),editWindowProc); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "Edit"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; +} + + +HWND SWELL_MakeCheckBox(const char *name, int idx, int x, int y, int w, int h, int flags=0) +{ + return SWELL_MakeControl(name,idx,"Button",BS_AUTOCHECKBOX|flags,x,y,w,h,0); +} + +HWND SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles) +{ + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(styles&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "ListBox"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; +} + +typedef struct ccprocrec +{ + SWELL_ControlCreatorProc proc; + int cnt; + struct ccprocrec *next; +} ccprocrec; + +static ccprocrec *m_ccprocs; + +void SWELL_RegisterCustomControlCreator(SWELL_ControlCreatorProc proc) +{ + if (!proc) return; + + ccprocrec *p=m_ccprocs; + while (p && p->next) + { + if (p->proc == proc) + { + p->cnt++; + return; + } + p=p->next; + } + ccprocrec *ent = (ccprocrec*)malloc(sizeof(ccprocrec)); + ent->proc=proc; + ent->cnt=1; + ent->next=0; + + if (p) p->next=ent; + else m_ccprocs=ent; +} + +void SWELL_UnregisterCustomControlCreator(SWELL_ControlCreatorProc proc) +{ + if (!proc) return; + + ccprocrec *lp=NULL; + ccprocrec *p=m_ccprocs; + while (p) + { + if (p->proc == proc) + { + if (--p->cnt <= 0) + { + if (lp) lp->next=p->next; + else m_ccprocs=p->next; + free(p); + } + return; + } + lp=p; + p=p->next; + } +} + + +HWND SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle) +{ + if (m_ccprocs) + { + RECT poo=MakeCoords(x,y,w,h,false); + ccprocrec *p=m_ccprocs; + while (p) + { + HWND hhh=p->proc((HWND)m_make_owner,cname,idx,classname,style,poo.left,poo.top,poo.right-poo.left,poo.bottom-poo.top); + if (hhh) + { + if (exstyle) SetWindowLong(hhh,GWL_EXSTYLE,exstyle); + return hhh; + } + p=p->next; + } + } + if (!stricmp(classname,"SysTabControl32")) + { + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "SysTabControl32"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + SetWindowPos(hwnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + return hwnd; + } + else if (!stricmp(classname, "SysListView32")||!stricmp(classname, "SysListView32_LB")) + { + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "SysListView32"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + return hwnd; + } + else if (!stricmp(classname, "SysTreeView32")) + { + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "SysTreeView32"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + return hwnd; + } + else if (!stricmp(classname, "msctls_progress32")) + { + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(style&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "msctls_progress32"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + return hwnd; + } + else if (!stricmp(classname,"Edit")) + { + return SWELL_MakeEditField(idx,x,y,w,h,style); + } + else if (!stricmp(classname, "static")) + { + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,cname, !(style&SWELL_NOT_WS_VISIBLE),labelWindowProc); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "static"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; + } + else if (!stricmp(classname,"Button")) + { + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = swell_makeButton(m_make_owner,idx,&tr,cname,!(style&SWELL_NOT_WS_VISIBLE),(style&~SWELL_NOT_WS_VISIBLE)|WS_CHILD); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; + } + else if (!stricmp(classname,"REAPERhfader")||!stricmp(classname,"msctls_trackbar32")) + { + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,cname, !(style&SWELL_NOT_WS_VISIBLE)); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = !stricmp(classname,"REAPERhfader") ? "REAPERhfader" : "msctls_trackbar32"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + return hwnd; + } + return 0; +} + +HWND SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags) +{ + if (h>18)h=18; + RECT tr=MakeCoords(x,y,w,h,true); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,NULL, !(flags&SWELL_NOT_WS_VISIBLE),comboWindowProc); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "combobox"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + if (m_doautoright) UpdateAutoCoords(tr); + return hwnd; +} + +HWND SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style) +{ + RECT tr=MakeCoords(x,y,w,h,false); + HWND hwnd = new HWND__(m_make_owner,idx,&tr,name, !(style&SWELL_NOT_WS_VISIBLE),groupWindowProc); + hwnd->m_style |= WS_CHILD; + hwnd->m_classname = "groupbox"; + hwnd->m_wndproc(hwnd,WM_CREATE,0,0); + SetWindowPos(hwnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + return hwnd; +} + + +int TabCtrl_GetItemCount(HWND hwnd) +{ + if (!hwnd) return 0; + // todo + return 0; +} + +BOOL TabCtrl_AdjustRect(HWND hwnd, BOOL fLarger, RECT *r) +{ + if (!r || !hwnd) return FALSE; + + // todo + return FALSE; +} + + +BOOL TabCtrl_DeleteItem(HWND hwnd, int idx) +{ + if (!hwnd) return 0; + // todo + return 0; +} + +int TabCtrl_InsertItem(HWND hwnd, int idx, TCITEM *item) +{ + if (!item || !hwnd) return -1; + if (!(item->mask & TCIF_TEXT) || !item->pszText) return -1; + + return 0; // todo idx +} + +int TabCtrl_SetCurSel(HWND hwnd, int idx) +{ + if (!hwnd) return -1; + // todo + return 0; +} + +int TabCtrl_GetCurSel(HWND hwnd) +{ + if (!hwnd) return 0; + return 0; // todo +} + +void ListView_SetExtendedListViewStyleEx(HWND h, int flag, int mask) +{ +} + +void SWELL_SetListViewFastClickMask(HWND hList, int mask) +{ +} + +void ListView_SetImageList(HWND h, HIMAGELIST imagelist, int which) +{ + if (!h || !imagelist || which != LVSIL_STATE) return; + +} + +int ListView_GetColumnWidth(HWND h, int pos) +{ + if (!h) return 0; +// if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return 0; + +// return (int) floor(0.5+[col width]); + return 0; +} + +void ListView_InsertColumn(HWND h, int pos, const LVCOLUMN *lvc) +{ + if (!h || !lvc) return; +} +void ListView_SetColumn(HWND h, int pos, const LVCOLUMN *lvc) +{ +} + +void ListView_GetItemText(HWND hwnd, int item, int subitem, char *text, int textmax) +{ + LVITEM it={LVIF_TEXT,item,subitem,0,0,text,textmax,}; + ListView_GetItem(hwnd,&it); +} + +int ListView_InsertItem(HWND h, const LVITEM *item) +{ + if (!h || !item || item->iSubItem) return 0; + + return 0; +} + +void ListView_SetItemText(HWND h, int ipos, int cpos, const char *txt) +{ + if (!h || cpos < 0 || cpos >= 32) return; + +} + +int ListView_GetNextItem(HWND h, int istart, int flags) +{ + return -1; +} + +bool ListView_SetItem(HWND h, LVITEM *item) +{ + if (!item) return false; + if (!h) return false; + + return true; +} + +bool ListView_GetItem(HWND h, LVITEM *item) +{ + if (!item) return false; + if ((item->mask&LVIF_TEXT)&&item->pszText && item->cchTextMax > 0) item->pszText[0]=0; + item->state=0; + if (!h) return false; + + return true; +} +int ListView_GetItemState(HWND h, int ipos, int mask) +{ + if (!h) return 0; + int flag=0; + return flag; +} + +bool ListView_SetItemState(HWND h, int ipos, int state, int statemask) +{ + int doref=0; + if (!h) return false; + static int _is_doing_all; + + if (ipos == -1) + { + int x; + int n=ListView_GetItemCount(h); + _is_doing_all++; + for (x = 0; x < n; x ++) + ListView_SetItemState(h,x,state,statemask); + _is_doing_all--; + ListView_RedrawItems(h,0,n-1); + return true; + } + + if (!_is_doing_all) + { + if (0) // didsel) + { + static int __rent; + if (!__rent) + { + int tag=0; // todo + __rent=1; + NMLISTVIEW nm={{(HWND)h,tag,LVN_ITEMCHANGED},ipos,0,state,}; + SendMessage(GetParent(h),WM_NOTIFY,tag,(LPARAM)&nm); + __rent=0; + } + } + if (doref) + ListView_RedrawItems(h,ipos,ipos); + } + return true; +} +void ListView_RedrawItems(HWND h, int startitem, int enditem) +{ + if (!h) return; +} + +void ListView_DeleteItem(HWND h, int ipos) +{ + if (!h) return; + +} + +void ListView_DeleteAllItems(HWND h) +{ + if (!h) return; +} + +int ListView_GetSelectedCount(HWND h) +{ + if (!h) return 0; + return 0; +} + +int ListView_GetItemCount(HWND h) +{ + if (!h) return 0; + return 0; +} + +int ListView_GetSelectionMark(HWND h) +{ + if (!h) return 0; + return 0; +} +int SWELL_GetListViewHeaderHeight(HWND h) +{ + return 0; +} + +void ListView_SetColumnWidth(HWND h, int colpos, int wid) +{ +} + +int ListView_HitTest(HWND h, LVHITTESTINFO *pinf) +{ + if (!h) return -1; + return -1; +} +int ListView_SubItemHitTest(HWND h, LVHITTESTINFO *pinf) +{ + return -1; +} + +void ListView_SetItemCount(HWND h, int cnt) +{ + if (!h) return; +} + +void ListView_EnsureVisible(HWND h, int i, BOOL pok) +{ + if (!h) return; +} +bool ListView_GetSubItemRect(HWND h, int item, int subitem, int code, RECT *r) +{ + if (!h) return false; + return false; +} +bool ListView_GetItemRect(HWND h, int item, RECT *r, int code) +{ + return false; +} + +bool ListView_Scroll(HWND h, int xscroll, int yscroll) +{ + return false; +} +void ListView_SortItems(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm) +{ + if (!hwnd) return; +} +bool ListView_DeleteColumn(HWND h, int pos) +{ + return false; +} +int ListView_GetCountPerPage(HWND h) +{ + return 1; +} + +HWND ChildWindowFromPoint(HWND h, POINT p) +{ + if (!h) return 0; + + RECT r={0,}; + + for(;;) + { + HWND h2=h->m_children; + RECT sr; + + RECT tr=h->m_position; + if (h->m_wndproc) h->m_wndproc(h,WM_NCCALCSIZE,0,(LPARAM)&tr); + r.left += tr.left - h->m_position.left; + r.top += tr.top - h->m_position.top; + + while (h2) + { + sr = h2->m_position; + sr.left += r.left; + sr.right += r.left; + sr.top += r.top; + sr.bottom += r.top; + + if (h2->m_visible && PtInRect(&sr,p)) break; + + h2 = h2->m_next; + } + if (!h2) break; // h is the window we care about + + h=h2; // descend to h2 + r=sr; + } + + return h; +} + +HWND WindowFromPoint(POINT p) +{ + HWND h = SWELL_topwindows; + while (h) + { + RECT r; + GetWindowContentViewRect(h,&r); + if (PtInRect(&r,p)) + { + p.x -= r.left; + p.y -= r.top; + return ChildWindowFromPoint(h,p); + } + h = h->m_next; + } + return NULL; +} + +void UpdateWindow(HWND hwnd) +{ + if (hwnd) + { +#ifdef SWELL_TARGET_GDK + while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; + if (hwnd && hwnd->m_oswindow) gdk_window_process_updates(hwnd->m_oswindow,true); +#endif + } +} + +void InvalidateRect(HWND hwnd, RECT *r, int eraseBk) +{ + if (!hwnd) return; + HWND hwndCall=hwnd; +#ifdef SWELL_LICE_GDI + { + hwnd->m_invalidated=true; + HWND t=hwnd->m_parent; + while (t && !t->m_child_invalidated) + { + if (eraseBk) + { + t->m_invalidated=true; + eraseBk--; + } + t->m_child_invalidated=true; + t=t->m_parent; + } + } +#endif +#ifdef SWELL_TARGET_GDK + GdkRectangle rect; + if (r) { rect.x = r->left; rect.y = r->top; rect.width = r->right-r->left; rect.height = r->bottom - r->top; } + else + { + rect.x=rect.y=0; + rect.width = hwnd->m_position.right - hwnd->m_position.left; + rect.height = hwnd->m_position.bottom - hwnd->m_position.top; + } + while (hwnd && !hwnd->m_oswindow) + { + RECT tr=hwnd->m_position; + if (hwnd->m_wndproc) hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,0,(LPARAM)&tr); + rect.x += tr.left; + rect.y += tr.top; + hwnd=hwnd->m_parent; + } + if (hwnd && hwnd->m_oswindow) + { + RECT tr={0,0,hwnd->m_position.right-hwnd->m_position.left,hwnd->m_position.bottom-hwnd->m_position.top}; + if (hwnd->m_wndproc) hwnd->m_wndproc(hwnd,WM_NCCALCSIZE,0,(LPARAM)&tr); + rect.x += tr.left; + rect.y += tr.top; + + gdk_window_invalidate_rect(hwnd->m_oswindow,hwnd!=hwndCall || r ? &rect : NULL,true); + } +#endif +} + + +HWND GetCapture() +{ + return s_captured_window; +} + +HWND SetCapture(HWND hwnd) +{ + HWND oc = s_captured_window; + if (oc != hwnd) + { + s_captured_window=hwnd; + if (oc) SendMessage(oc,WM_CAPTURECHANGED,0,(LPARAM)hwnd); +#ifdef SWELL_TARGET_GDK +// this doesnt seem to be necessary +// if (gdk_pointer_is_grabbed()) gdk_pointer_ungrab(GDK_CURRENT_TIME); +// while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent; +// if (hwnd) gdk_pointer_grab(hwnd->m_oswindow,TRUE,GDK_ALL_EVENTS_MASK,hwnd->m_oswindow,NULL,GDK_CURRENT_TIME); +#endif + } + return oc; +} + +void ReleaseCapture() +{ + if (s_captured_window) + { + SendMessage(s_captured_window,WM_CAPTURECHANGED,0,0); + s_captured_window=0; +#ifdef SWELL_TARGET_GDK +// if (gdk_pointer_is_grabbed()) gdk_pointer_ungrab(GDK_CURRENT_TIME); +#endif + } +} + +LRESULT SwellDialogDefaultWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + DLGPROC d=(DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); + if (d) + { + if (uMsg == WM_PAINT) + { + PAINTSTRUCT ps; + if (BeginPaint(hwnd,&ps)) + { + HBRUSH hbrush = (HBRUSH) d(hwnd,WM_CTLCOLORDLG,(WPARAM)ps.hdc,(LPARAM)hwnd); + if (hbrush && hbrush != (HBRUSH)1) + { + FillRect(ps.hdc,&ps.rcPaint,hbrush); + } + else if (1) + { + hbrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW)); + FillRect(ps.hdc,&ps.rcPaint,hbrush); + DeleteObject(hbrush); + } + else if (0) // todo only on top level windows? + { + SWELL_FillDialogBackground(ps.hdc,&ps.rcPaint,3); + } + + EndPaint(hwnd,&ps); + } + } + + LRESULT r=(LRESULT) d(hwnd,uMsg,wParam,lParam); + + + if (r) return r; + } + return DefWindowProc(hwnd,uMsg,wParam,lParam); +} + +BOOL EndPaint(HWND hwnd, PAINTSTRUCT *ps) +{ + return TRUE; +} + +LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + const int menubar_size=12; // big for testing + const int menubar_xspacing=5; + switch (msg) + { + case WM_NCCALCSIZE: + if (!hwnd->m_parent && hwnd->m_menu) + { + RECT *r = (RECT*)lParam; + r->top += menubar_size; + } + break; + case WM_NCPAINT: + if (!hwnd->m_parent && hwnd->m_menu) + { + HDC dc = GetWindowDC(hwnd); + if (dc) + { + RECT r; + GetWindowContentViewRect(hwnd,&r); + r.right -= r.left; r.left=0; + r.bottom -= r.top; r.top=0; + if (r.bottom>menubar_size) r.bottom=menubar_size; + + HBRUSH br=CreateSolidBrush(GetSysColor(COLOR_3DFACE)); + FillRect(dc,&r,br); + DeleteObject(br); + + SetBkMode(dc,TRANSPARENT); + int cols[2]={ GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_3DHILIGHT)}; + + int x,xpos=0; + HMENU__ *menu = (HMENU__*)hwnd->m_menu; + for(x=0;xitems.GetSize();x++) + { + MENUITEMINFO *inf = menu->items.Get(x); + if (inf->fType == MFT_STRING && inf->dwTypeData) + { + bool dis = !!(inf->fState & MF_GRAYED); + SetTextColor(dc,cols[dis]); + RECT cr=r; cr.left=cr.right=xpos; + DrawText(dc,inf->dwTypeData,-1,&cr,DT_CALCRECT); + DrawText(dc,inf->dwTypeData,-1,&cr,DT_VCENTER|DT_LEFT); + xpos=cr.right+menubar_xspacing; + } + } + + ReleaseDC(hwnd,dc); + } + } + break; + case WM_RBUTTONUP: + case WM_NCRBUTTONUP: + { + POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; + HWND hwndDest=hwnd; + if (msg==WM_RBUTTONUP) + { + ClientToScreen(hwnd,&p); + HWND h=WindowFromPoint(p); + if (h && IsChild(hwnd,h)) hwndDest=h; + } + SendMessage(hwnd,WM_CONTEXTMENU,(WPARAM)hwndDest,(p.x&0xffff)|(p.y<<16)); + } + return 1; +// case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + if (!hwnd->m_parent && hwnd->m_menu) + { + RECT r; + GetWindowContentViewRect(hwnd,&r); + if (GET_Y_LPARAM(lParam)>=r.top && GET_Y_LPARAM(lParam) < r.top+menubar_size) + { + HDC dc = GetWindowDC(hwnd); + + int x,xpos=r.left; + HMENU__ *menu = (HMENU__*)hwnd->m_menu; + for(x=0;xitems.GetSize();x++) + { + MENUITEMINFO *inf = menu->items.Get(x); + if (inf->fType == MFT_STRING && inf->dwTypeData) + { + bool dis = !!(inf->fState & MF_GRAYED); + RECT cr=r; cr.left=cr.right=xpos; + DrawText(dc,inf->dwTypeData,-1,&cr,DT_CALCRECT); + + if (GET_X_LPARAM(lParam) >=cr.left && GET_X_LPARAM(lParam)<=cr.right) + { + if (!dis) + { + if (inf->hSubMenu) TrackPopupMenu(inf->hSubMenu,0,xpos,r.top+menubar_size,0,hwnd,NULL); + else if (inf->wID) SendMessage(hwnd,WM_COMMAND,inf->wID,0); + } + break; + } + + xpos=cr.right+menubar_xspacing; + } + } + + if (dc) ReleaseDC(hwnd,dc); + } + } + break; + case WM_NCHITTEST: + if (!hwnd->m_parent && hwnd->m_menu) + { + RECT r; + GetWindowContentViewRect(hwnd,&r); + if (GET_Y_LPARAM(lParam)>=r.top && GET_Y_LPARAM(lParam) < r.top+menubar_size) return HTMENU; + } + return HTCLIENT; + case WM_KEYDOWN: + case WM_KEYUP: return 69; + case WM_CONTEXTMENU: + return hwnd->m_parent ? SendMessage(hwnd->m_parent,msg,wParam,lParam) : 0; + case WM_GETFONT: +#ifdef SWELL_FREETYPE + { + HFONT SWELL_GetDefaultFont(); + return (LRESULT)SWELL_GetDefaultFont(); + } +#endif + + return 0; + } + return 0; +} + + + + + + + + + + + + + + + + + + +///////////////// clipboard compatability (NOT THREAD SAFE CURRENTLY) + + +BOOL DragQueryPoint(HDROP hDrop,LPPOINT pt) +{ + if (!hDrop) return 0; + DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); + BOOL rv=!df->fNC; + *pt=df->pt; + GlobalUnlock(hDrop); + return rv; +} + +void DragFinish(HDROP hDrop) +{ +//do nothing for now (caller will free hdrops) +} + +UINT DragQueryFile(HDROP hDrop, UINT wf, char *buf, UINT bufsz) +{ + if (!hDrop) return 0; + DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); + + UINT rv=0; + char *p=(char*)df + df->pFiles; + if (wf == 0xFFFFFFFF) + { + while (*p) + { + rv++; + p+=strlen(p)+1; + } + } + else + { + while (*p) + { + if (!wf--) + { + if (buf) + { + lstrcpyn(buf,p,bufsz); + rv=strlen(buf); + } + else rv=strlen(p); + + break; + } + p+=strlen(p)+1; + } + } + GlobalUnlock(hDrop); + return rv; +} + + + +static WDL_PtrList m_clip_recs; +//static WDL_PtrList m_clip_fmts; +static WDL_PtrList m_clip_curfmts; +bool OpenClipboard(HWND hwndDlg) +{ + m_clip_curfmts.Empty(); + return true; +} + +void CloseClipboard() // frees any remaining items in clipboard +{ + m_clip_recs.Empty(true,GlobalFree); +} + +UINT EnumClipboardFormats(UINT lastfmt) +{ + return 0; +} + +HANDLE GetClipboardData(UINT type) +{ + return 0; +} + + +void EmptyClipboard() +{ +} + +void SetClipboardData(UINT type, HANDLE h) +{ +} + +UINT RegisterClipboardFormat(const char *desc) +{ + return 0; +} + + + +///////// PostMessage emulation + +BOOL PostMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + return SWELL_Internal_PostMessage(hwnd,message,wParam,lParam); +} + +void SWELL_MessageQueue_Clear(HWND h) +{ + SWELL_Internal_PMQ_ClearAllMessages(h); +} + + + +// implementation of postmessage stuff + + + + +typedef struct PMQ_rec +{ + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; + + struct PMQ_rec *next; +} PMQ_rec; + +static WDL_Mutex *m_pmq_mutex; +static PMQ_rec *m_pmq, *m_pmq_empty, *m_pmq_tail; +static int m_pmq_size; + +#define MAX_POSTMESSAGE_SIZE 1024 + + +void SWELL_Internal_PostMessage_Init() +{ + if (m_pmq_mutex) return; + + m_pmq_mainthread=pthread_self(); + m_pmq_mutex = new WDL_Mutex; +} + +void SWELL_MessageQueue_Flush() +{ + if (!m_pmq_mutex) return; + + m_pmq_mutex->Enter(); + PMQ_rec *p=m_pmq, *startofchain=m_pmq; + m_pmq=m_pmq_tail=0; + m_pmq_mutex->Leave(); + + int cnt=0; + // process out queue + while (p) + { + // process this message + SendMessage(p->hwnd,p->msg,p->wParam,p->lParam); + + cnt ++; + if (!p->next) // add the chain back to empties + { + m_pmq_mutex->Enter(); + m_pmq_size-=cnt; + p->next=m_pmq_empty; + m_pmq_empty=startofchain; + m_pmq_mutex->Leave(); + break; + } + p=p->next; + } +} + +void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd) +{ + if (!m_pmq_mutex) return; + + m_pmq_mutex->Enter(); + PMQ_rec *p=m_pmq; + PMQ_rec *lastrec=NULL; + while (p) + { + if (hwnd && p->hwnd != hwnd) { lastrec=p; p=p->next; } + else + { + PMQ_rec *next=p->next; + + p->next=m_pmq_empty; // add p to empty list + m_pmq_empty=p; + m_pmq_size--; + + + if (p==m_pmq_tail) m_pmq_tail=lastrec; // update tail + + if (lastrec) p = lastrec->next = next; + else p = m_pmq = next; + } + } + m_pmq_mutex->Leave(); +} + +BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (!hwnd||!m_pmq_mutex) return FALSE; + + BOOL ret=FALSE; + m_pmq_mutex->Enter(); + + if (m_pmq_empty||m_pmq_sizenext; + else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec)); + rec->next=0; + rec->hwnd=hwnd; + rec->msg=msg; + rec->wParam=wParam; + rec->lParam=lParam; + + if (m_pmq_tail) m_pmq_tail->next=rec; + else + { + PMQ_rec *p=m_pmq; + while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety + if (p) p->next=rec; + else m_pmq=rec; + } + m_pmq_tail=rec; + m_pmq_size++; + + ret=TRUE; + } + + m_pmq_mutex->Leave(); + + return ret; +} + + +int EnumPropsEx(HWND hwnd, PROPENUMPROCEX proc, LPARAM lParam) +{ + if (!hwnd) return -1; + int x; + for (x =0 ; x < hwnd->m_props.GetSize(); x ++) + { + const char *k=""; + void *p = hwnd->m_props.Enumerate(x,&k); + if (!proc(hwnd,k,p,lParam)) return 0; + } + return 1; +} + +HANDLE GetProp(HWND hwnd, const char *name) +{ + if (!hwnd) return NULL; + return hwnd->m_props.Get(name); +} + +BOOL SetProp(HWND hwnd, const char *name, HANDLE val) +{ + if (!hwnd) return false; + hwnd->m_props.Insert(name,(void *)val); + return TRUE; +} + +HANDLE RemoveProp(HWND hwnd, const char *name) +{ + HANDLE h =GetProp(hwnd,name); + hwnd->m_props.Delete(name); + return h; +} + + +int GetSystemMetrics(int p) +{ + switch (p) + { + case SM_CXSCREEN: + case SM_CYSCREEN: + { + RECT r; + SWELL_GetViewPort(&r, NULL, false); + return p==SM_CXSCREEN ? r.right-r.left : r.bottom-r.top; + } + case SM_CXHSCROLL: return 16; + case SM_CYHSCROLL: return 16; + case SM_CXVSCROLL: return 16; + case SM_CYVSCROLL: return 16; + } + return 0; +} + +BOOL ScrollWindow(HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect) +{ + if (!hwnd || (!xamt && !yamt)) return FALSE; + + // move child windows only + hwnd = hwnd->m_children; + while (hwnd) + { + hwnd->m_position.left += xamt; + hwnd->m_position.right += xamt; + hwnd->m_position.top += yamt; + hwnd->m_position.bottom += yamt; + + hwnd=hwnd->m_next; + } + return TRUE; +} + +HWND FindWindowEx(HWND par, HWND lastw, const char *classname, const char *title) +{ + if (!par&&!lastw) return NULL; // need to implement this modes + HWND h=lastw?GetWindow(lastw,GW_HWNDNEXT):GetWindow(par,GW_CHILD); + while (h) + { + bool isOk=true; + if (title) + { + char buf[512]; + buf[0]=0; + GetWindowText(h,buf,sizeof(buf)); + if (strcmp(title,buf)) isOk=false; + } + if (classname) + { + // todo: other classname translations + } + + if (isOk) return h; + h=GetWindow(h,GW_HWNDNEXT); + } + return h; +} + + +HTREEITEM TreeView_InsertItem(HWND hwnd, TV_INSERTSTRUCT *ins) +{ + if (!hwnd || !ins) return 0; + + return NULL; +} + +BOOL TreeView_Expand(HWND hwnd, HTREEITEM item, UINT flag) +{ + if (!hwnd || !item) return false; + + return TRUE; + +} + +HTREEITEM TreeView_GetSelection(HWND hwnd) +{ + if (!hwnd) return NULL; + + return NULL; + +} + +void TreeView_DeleteItem(HWND hwnd, HTREEITEM item) +{ + if (!hwnd) return; +} + +void TreeView_SelectItem(HWND hwnd, HTREEITEM item) +{ + if (!hwnd) return; + +} + +BOOL TreeView_GetItem(HWND hwnd, LPTVITEM pitem) +{ + if (!hwnd || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; + + return TRUE; +} + +BOOL TreeView_SetItem(HWND hwnd, LPTVITEM pitem) +{ + if (!hwnd || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; + + return TRUE; +} + +HTREEITEM TreeView_HitTest(HWND hwnd, TVHITTESTINFO *hti) +{ + if (!hwnd || !hti) return NULL; + + return NULL; // todo implement +} + +HTREEITEM TreeView_GetRoot(HWND hwnd) +{ + if (!hwnd) return NULL; + return NULL; +} + +HTREEITEM TreeView_GetChild(HWND hwnd, HTREEITEM item) +{ + if (!hwnd) return NULL; + return NULL; +} +HTREEITEM TreeView_GetNextSibling(HWND hwnd, HTREEITEM item) +{ + if (!hwnd) return NULL; + + return NULL; +} +BOOL TreeView_SetIndent(HWND hwnd, int indent) +{ + return FALSE; +} +void TreeView_SetBkColor(HWND hwnd, int color) +{ +} +void TreeView_SetTextColor(HWND hwnd, int color) +{ +} +void ListView_SetBkColor(HWND hwnd, int color) +{ +} +void ListView_SetTextBkColor(HWND hwnd, int color) +{ +} +void ListView_SetTextColor(HWND hwnd, int color) +{ +} +void ListView_SetGridColor(HWND hwnd, int color) +{ +} +void ListView_SetSelColors(HWND hwnd, int *colors, int ncolors) +{ +} +int ListView_GetTopIndex(HWND h) +{ +} +BOOL ListView_GetColumnOrderArray(HWND h, int cnt, int* arr) +{ +} +BOOL ListView_SetColumnOrderArray(HWND h, int cnt, int* arr) +{ + return FALSE; +} +HWND ListView_GetHeader(HWND h) +{ + return 0; +} + +int Header_GetItemCount(HWND h) +{ + return 0; +} + +BOOL Header_GetItem(HWND h, int col, HDITEM* hi) +{ + return FALSE; +} + +BOOL Header_SetItem(HWND h, int col, HDITEM* hi) +{ + return FALSE; +} + + +BOOL EnumChildWindows(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam) +{ + if (hwnd && hwnd->m_children) + { + HWND n=hwnd->m_children; + while (n) + { + if (!cwEnumFunc(n,lParam) || !EnumChildWindows(n,cwEnumFunc,lParam)) return FALSE; + n = n->m_next; + } + } + return TRUE; +} +void SWELL_GetDesiredControlSize(HWND hwnd, RECT *r) +{ +} + +BOOL SWELL_IsGroupBox(HWND hwnd) +{ + //todo + return FALSE; +} +BOOL SWELL_IsButton(HWND hwnd) +{ + //todo + return FALSE; +} +BOOL SWELL_IsStaticText(HWND hwnd) +{ + //todo + return FALSE; +} + + +BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah) +{ + return FALSE; +} + + + + +// r=NULL to "free" handle +// otherwise r is in hwndPar coordinates +void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) +{ + if (!handle) return; +} + +void SWELL_BroadcastMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + + HWND h = SWELL_topwindows; + while (h) + { + SendMessage(h,uMsg,wParam,lParam); + h = h->m_next; + } +} + +int SWELL_SetWindowLevel(HWND hwnd, int newlevel) +{ + return 0; +} +void SetOpaque(HWND h, bool opaque) +{ +} +int SWELL_GetDefaultButtonID(HWND hwndDlg, bool onlyIfEnabled) +{ + return 0; +} + +void GetCursorPos(POINT *pt) +{ + pt->x=0; + pt->y=0; +#ifdef SWELL_TARGET_GDK + if (SWELL_gdk_active>0) + gdk_display_get_pointer(gdk_display_get_default(),NULL,&pt->x,&pt->y,NULL); +#endif +} + +WORD GetAsyncKeyState(int key) +{ +#ifdef SWELL_TARGET_GDK + if (SWELL_gdk_active>0) + { + GdkModifierType mod=(GdkModifierType)0; + HWND h = GetFocus(); + while (h && !h->m_oswindow) h = h->m_parent; + gdk_window_get_pointer(h? h->m_oswindow : gdk_get_default_root_window(),NULL,NULL,&mod); + + if (key == VK_LBUTTON) return (mod&GDK_BUTTON1_MASK)?0x8000:0; + if (key == VK_MBUTTON) return (mod&GDK_BUTTON2_MASK)?0x8000:0; + if (key == VK_RBUTTON) return (mod&GDK_BUTTON3_MASK)?0x8000:0; + + if (key == VK_CONTROL) return (mod&GDK_CONTROL_MASK)?0x8000:0; + if (key == VK_MENU) return (mod&GDK_MOD1_MASK)?0x8000:0; + if (key == VK_SHIFT) return (mod&GDK_SHIFT_MASK)?0x8000:0; + } +#endif + return 0; +} + + +DWORD GetMessagePos() +{ + return s_lastMessagePos; +} + +void SWELL_HideApp() +{ +} + +BOOL SWELL_GetGestureInfo(LPARAM lParam, GESTUREINFO* gi) +{ + return FALSE; +} + +void SWELL_SetWindowWantRaiseAmt(HWND h, int amt) +{ +} +int SWELL_GetWindowWantRaiseAmt(HWND h) +{ + return 0; +} + +// copied from swell-wnd.mm, can maybe have a common impl instead +void SWELL_GenerateDialogFromList(const void *_list, int listsz) +{ +#define SIXFROMLIST list->p1,list->p2,list->p3, list->p4, list->p5, list->p6 + SWELL_DlgResourceEntry *list = (SWELL_DlgResourceEntry*)_list; + while (listsz>0) + { + if (!strcmp(list->str1,"__SWELL_BUTTON")) + { + SWELL_MakeButton(list->flag1,list->str2, SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_EDIT")) + { + SWELL_MakeEditField(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_COMBO")) + { + SWELL_MakeCombo(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_LISTBOX")) + { + SWELL_MakeListBox(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_GROUP")) + { + SWELL_MakeGroupBox(list->str2,SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_CHECKBOX")) + { + SWELL_MakeCheckBox(list->str2,SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_LABEL")) + { + SWELL_MakeLabel(list->flag1, list->str2, SIXFROMLIST); + } + else if (*list->str2) + { + SWELL_MakeControl(list->str1, list->flag1, list->str2, SIXFROMLIST); + } + listsz--; + list++; + } +} + +#endif diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm new file mode 100644 index 00000000..962d17cc --- /dev/null +++ b/WDL/swell/swell-wnd.mm @@ -0,0 +1,6128 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides basic windows APIs for handling windows, as well as the stubs to enable swell-dlggen to work. + + */ + + +#ifndef SWELL_PROVIDED_BY_APP + +#import +#import +#include "swell.h" +#include "../mutex.h" +#include "../ptrlist.h" +#include "../queue.h" + +#include "swell-dlggen.h" +#include "swell-internal.h" + + + +static LRESULT sendSwellMessage(id obj, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (obj && [obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + return [(SWELL_hwndChild *)obj onSwellMessage:uMsg p1:wParam p2:lParam]; + return 0; +} +static void InvalidateSuperViews(NSView *view); +#define STANDARD_CONTROL_NEEDSDISPLAY_IMPL \ + - (void)setNeedsDisplay:(BOOL)flag \ + { \ + [super setNeedsDisplay:flag]; \ + if (flag) InvalidateSuperViews(self); \ + } \ + - (void)setNeedsDisplayInRect:(NSRect)rect \ + { \ + [super setNeedsDisplayInRect:rect]; \ + InvalidateSuperViews(self); \ + } + + +char* lstrcpyn(char* dest, const char* src, int l); + +int g_swell_want_nice_style = 1; +static void *SWELL_CStringToCFString_FilterPrefix(const char *str) +{ + int c=0; + while (str[c] && str[c] != '&' && c++<1024); + if (!str[c] || c>=1024 || strlen(str)>=1024) return SWELL_CStringToCFString(str); + char buf[1500]; + const char *p=str; + char *op=buf; + while (*p) + { + if (*p == '&') p++; + if (!*p) break; + *op++=*p++; + } + *op=0; + return SWELL_CStringToCFString(buf); + +} + +static int _nsStringSearchProc(const void *_a, const void *_b) +{ + NSString *a=(NSString *)_a; + NSString *b = (NSString *)_b; + return [a compare:b]; +} +static int _nsMenuSearchProc(const void *_a, const void *_b) +{ + NSString *a=(NSString *)_a; + NSMenuItem *b = (NSMenuItem *)_b; + return [a compare:[b title]]; +} +static int _listviewrowSearchFunc(const void *_a, const void *_b, const void *ctx) +{ + const char *a = (const char *)_a; + SWELL_ListView_Row *row = (SWELL_ListView_Row *)_b; + const char *b=""; + if (!row || !(b=row->m_vals.Get(0))) b=""; + return strcmp(a,b); +} +static int _listviewrowSearchFunc2(const void *_a, const void *_b, const void *ctx) +{ + const char *a = (const char *)_a; + SWELL_ListView_Row *row = (SWELL_ListView_Row *)_b; + const char *b=""; + if (!row || !(b=row->m_vals.Get(0))) b=""; + return strcmp(b,a); +} + +// modified bsearch: returns place item SHOULD be in if it's not found +static int arr_bsearch_mod(void *key, NSArray *arr, int (*compar)(const void *, const void *)) +{ + size_t nmemb = [arr count]; + int base=0; + int lim, cmp; + int p; + + for (lim = nmemb; lim != 0; lim >>= 1) { + p = base + (lim >> 1); + cmp = compar(key, [arr objectAtIndex:p]); + if (cmp == 0) return (p); + if (cmp > 0) { /* key > p: move right */ + // check to see if key is less than p+1, if it is, we're done + base = p + 1; + if (base >= nmemb || compar(key,[arr objectAtIndex:base])<=0) return base; + lim--; + } /* else move left */ + } + return 0; +} + + +template static int ptrlist_bsearch_mod(void *key, WDL_PtrList *arr, int (*compar)(const void *, const void *, const void *ctx), void *ctx) +{ + size_t nmemb = arr->GetSize(); + int base=0; + int lim, cmp; + int p; + + for (lim = nmemb; lim != 0; lim >>= 1) { + p = base + (lim >> 1); + cmp = compar(key, arr->Get(p),ctx); + if (cmp == 0) return (p); + if (cmp > 0) { /* key > p: move right */ + // check to see if key is less than p+1, if it is, we're done + base = p + 1; + if (base >= nmemb || compar(key,arr->Get(base),ctx)<=0) return base; + lim--; + } /* else move left */ + } + return 0; +} + + +SWELL_ListView_Row::SWELL_ListView_Row() +{ + m_imageidx=0; + m_param=0; +} +SWELL_ListView_Row::~SWELL_ListView_Row() +{ + m_vals.Empty(true,free); +} + +HTREEITEM__::HTREEITEM__() +{ + m_param=0; + m_value=0; + m_haschildren=false; + m_dh = [[SWELL_DataHold alloc] initWithVal:this]; +} +HTREEITEM__::~HTREEITEM__() +{ + free(m_value); + m_children.Empty(true); + [m_dh release]; +} + + +bool HTREEITEM__::FindItem(HTREEITEM it, HTREEITEM__ **parOut, int *idxOut) +{ + int a=m_children.Find((HTREEITEM__*)it); + if (a>=0) + { + *parOut=this; + *idxOut=a; + return true; + } + int x; + for (x = 0; x < m_children.GetSize(); x ++) + { + if (m_children.Get(x)->FindItem(it,parOut,idxOut)) return true; + } + return false; +} + +@implementation SWELL_TabView +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(void)setNotificationWindow:(id)dest +{ + m_dest=dest; +} +-(id)getNotificationWindow +{ + return m_dest; +} +-(NSInteger) tag +{ + return m_tag; +} +-(void) setTag:(NSInteger)tag +{ + m_tag=tag; +} +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if (m_dest) + { + NMHDR nm={(HWND)self,[self tag],TCN_SELCHANGE}; + SendMessage((HWND)m_dest,WM_NOTIFY,[self tag],(LPARAM)&nm); + } +} +@end + + +@implementation SWELL_ProgressView +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(NSInteger) tag +{ + return m_tag; +} +-(void) setTag:(NSInteger)tag +{ + m_tag=tag; +} +-(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam +{ + if (msg == PBM_SETRANGE) + { + [self setMinValue:LOWORD(lParam)]; + [self setMaxValue:HIWORD(lParam)]; + } + else if (msg==PBM_SETPOS) + { + [self setDoubleValue:(double)wParam]; + [self stopAnimation:self]; + } + else if (msg==PBM_DELTAPOS) + { + [self incrementBy:(double)wParam]; + } + return 0; +} + +@end + +@implementation SWELL_ListViewCell +-(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if ([controlView isKindOfClass:[SWELL_ListView class]] && ((SWELL_ListView *)controlView)->m_selColors) return nil; + if ([controlView isKindOfClass:[SWELL_TreeView class]] && ((SWELL_TreeView *)controlView)->m_selColors) return nil; + return [super highlightColorWithFrame:cellFrame inView:controlView]; +} +@end + +@implementation SWELL_StatusCell +-(id)initNewCell +{ + if ((self=[super initTextCell:@""])) + { + status=0; + } + return self; +} +-(void)setStatusImage:(NSImage *)img +{ + status=img; +} +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if (status) + { + [controlView lockFocus]; + [status drawInRect:NSMakeRect(cellFrame.origin.x,cellFrame.origin.y,cellFrame.size.height,cellFrame.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; + [controlView unlockFocus]; + } + cellFrame.origin.x += cellFrame.size.height + 2.0; + cellFrame.size.width -= cellFrame.size.height + 2.0; + [super drawWithFrame:cellFrame inView:controlView]; +} + +-(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if ([controlView isKindOfClass:[SWELL_ListView class]] && ((SWELL_ListView *)controlView)->m_selColors) return nil; + return [super highlightColorWithFrame:cellFrame inView:controlView]; +} + +@end + +@implementation SWELL_TreeView +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(id) init +{ + if ((self = [super init])) + { + m_fakerightmouse=false; + m_items=new WDL_PtrList; + m_fgColor=0; + m_selColors=0; + } + return self; +} +-(void) dealloc +{ + if (m_items) m_items->Empty(true); + delete m_items; + m_items=0; + [m_fgColor release]; + [m_selColors release]; + [super dealloc]; +} + +-(bool) findItem:(HTREEITEM)item parOut:(HTREEITEM__ **)par idxOut:(int *)idx +{ + if (!m_items||!item) return false; + int x=m_items->Find((HTREEITEM__*)item); + if (x>=0) + { + *par=NULL; + *idx=x; + return true; + } + for (x = 0; x < m_items->GetSize(); x++) + { + if (m_items->Get(x)->FindItem(item,par,idx)) return true; + } + + return false; +} + +-(NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +{ + if (item == nil) return m_items ? m_items->GetSize() : 0; + return ((HTREEITEM__*)[item getValue])->m_children.GetSize(); +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item +{ + if (item==nil) return YES; + HTREEITEM__ *it=(HTREEITEM__ *)[item getValue]; + + return it && it->m_haschildren; +} + +- (id)outlineView:(NSOutlineView *)outlineView + child:(NSInteger)index + ofItem:(id)item +{ + HTREEITEM__ *row=item ? ((HTREEITEM__*)[item getValue])->m_children.Get(index) : m_items ? m_items->Get(index) : 0; + + return (id)row->m_dh; +} + +- (id)outlineView:(NSOutlineView *)outlineView + objectValueForTableColumn:(NSTableColumn *)tableColumn + byItem:(id)item +{ + if (!item) return @""; + HTREEITEM__ *it=(HTREEITEM__ *)[item getValue]; + + if (!it || !it->m_value) return @""; + + NSString *str=(NSString *)SWELL_CStringToCFString(it->m_value); + + return [str autorelease]; +} + + + +-(void)mouseDown:(NSEvent *)theEvent +{ + if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) + { + m_fakerightmouse=1; + } + else + { + + NMCLICK nmlv={{(HWND)self,[self tag], NM_CLICK},}; + SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); + + m_fakerightmouse=0; + [super mouseDown:theEvent]; + } +} + +-(void)mouseDragged:(NSEvent *)theEvent +{ +} + +-(void)mouseUp:(NSEvent *)theEvent +{ + if (m_fakerightmouse||([theEvent modifierFlags] & NSControlKeyMask)) [self rightMouseUp:theEvent]; + else [super mouseUp:theEvent]; +} +- (void)rightMouseUp:(NSEvent *)theEvent +{ + bool wantContext=true; + + NMCLICK nmlv={{(HWND)self,[self tag], NM_RCLICK},}; + if (SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv)) wantContext=false; + + if (wantContext) + { + POINT p; + GetCursorPos(&p); + SendMessage((HWND)[self target],WM_CONTEXTMENU,(WPARAM)self,(p.x&0xffff)|(p.y<<16)); + } + + m_fakerightmouse=0; +} + +- (void)highlightSelectionInClipRect:(NSRect)theClipRect +{ + if (m_selColors) + { + int a = GetFocus() == (HWND)self ? 0 : 2; + if ([m_selColors count] >= a) + { + NSColor *c=[m_selColors objectAtIndex:a]; + if (c) + { + // calculate rect of selected items, combine with theClipRect, and fill these areas with our background (phew!) + + int x = [self selectedRow]; + if (x>=0) + { + NSRect r = [self rectOfRow:x]; + r = NSIntersectionRect(r,theClipRect); + if (r.size.height>0 && r.size.width>0) + { + [c setFill]; + NSRectFill(r); + } + } + return ; + } + } + } + return [super highlightSelectionInClipRect:theClipRect]; +} + + + + +@end + + + + + +@implementation SWELL_ListView +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(LONG)getSwellStyle { return style; } + +-(void)setSwellStyle:(LONG)st +{ + bool hdrchg= ((style&LVS_NOCOLUMNHEADER) != (st&LVS_NOCOLUMNHEADER)); + style=st; + if ((style&LVS_REPORT) && hdrchg) + { + // todo some crap with NSTableView::setHeaderView, but it's complicated + } +} + +-(id) init +{ + if ((self = [super init])) + { + m_selColors=0; + m_fgColor = 0; + ownermode_cnt=0; + m_status_imagelist_type=-1; + m_status_imagelist=0; + m_leftmousemovecnt=0; + m_fakerightmouse=false; + m_lbMode=0; + m_fastClickMask=0; + m_start_item=-1; + m_start_subitem=-1; + m_start_item_clickmode=0; // 0=clicked item, 1=clicked image, &2=sent drag message, &4=quickclick mode + m_cols = new WDL_PtrList; + m_items=new WDL_PtrList; + } + return self; +} +-(void) dealloc +{ + if (m_items) m_items->Empty(true); + delete m_items; + delete m_cols; + m_cols=0; + m_items=0; + [m_fgColor release]; + [m_selColors release]; + [super dealloc]; +} + +-(int)getColumnPos:(int)idx // get current position of column that was originally at idx +{ + int pos=idx; + if (m_cols) + { + NSTableColumn* col=m_cols->Get(idx); + if (col) + { + NSArray* arr=[self tableColumns]; + if (arr) + { + pos=[arr indexOfObject:col]; + } + } + } + return pos; +} + +- (void)highlightSelectionInClipRect:(NSRect)theClipRect +{ + if (m_selColors) + { + int a = GetFocus() == (HWND)self ? 0 : 2; + if ([m_selColors count] >= a) + { + NSColor *c=[m_selColors objectAtIndex:a]; + if (c) + { + // calculate rect of selected items, combine with theClipRect, and fill these areas with our background (phew!) + bool needfillset=true; + int x = [self rowAtPoint:NSMakePoint(0,theClipRect.origin.y)]; + if (x<0)x=0; + int n = [self numberOfRows]; + for (;x = theClipRect.origin.y + theClipRect.size.height) break; + + if ([self isRowSelected:x]) + { + r = NSIntersectionRect(r,theClipRect); + if (r.size.height>0 && r.size.width>0) + { + if (needfillset) { needfillset=false; [c setFill]; } + NSRectFill(r); + } + } + } + return ; + } + } + } + return [super highlightSelectionInClipRect:theClipRect]; +} +-(int)getColumnIdx:(int)pos // get original index of column that is currently at position +{ + int idx=pos; + NSArray* arr=[self tableColumns]; + if (arr && pos>=0 && pos < [arr count]) + { + NSTableColumn* col=[arr objectAtIndex:pos]; + if (col && m_cols) + { + idx=m_cols->Find(col); + } + } + return idx; +} + +-(int)columnAtPoint:(NSPoint)pt +{ + int pos=[super columnAtPoint:pt]; + return [self getColumnIdx:pos]; +} + + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return (!m_lbMode && (style & LVS_OWNERDATA)) ? ownermode_cnt : (m_items ? m_items->GetSize():0); +} + +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + NSString *str=NULL; + int image_idx=0; + + if (!m_lbMode && (style & LVS_OWNERDATA)) + { + HWND tgt=(HWND)[self target]; + + char buf[1024]; + NMLVDISPINFO nm={{(HWND)self, [self tag], LVN_GETDISPINFO}}; + nm.item.mask=LVIF_TEXT; + if (m_status_imagelist_type==LVSIL_STATE) nm.item.mask |= LVIF_STATE; + else if (m_status_imagelist_type == LVSIL_SMALL) nm.item.mask |= LVIF_IMAGE; + nm.item.iImage = -1; + nm.item.iItem=rowIndex; + nm.item.iSubItem=m_cols->Find(aTableColumn); + nm.item.pszText=buf; + nm.item.cchTextMax=sizeof(buf)-1; + buf[0]=0; + SendMessage(tgt,WM_NOTIFY,[self tag],(LPARAM)&nm); + + if (m_status_imagelist_type == LVSIL_STATE) image_idx=(nm.item.state>>16)&0xff; + else if (m_status_imagelist_type == LVSIL_SMALL) image_idx = nm.item.iImage + 1; + str=(NSString *)SWELL_CStringToCFString(nm.item.pszText); + } + else + { + char *p=NULL; + SWELL_ListView_Row *r=0; + if (m_items && m_cols && (r=m_items->Get(rowIndex))) + { + p=r->m_vals.Get(m_cols->Find(aTableColumn)); + if (m_status_imagelist_type == LVSIL_STATE || m_status_imagelist_type == LVSIL_SMALL) + { + image_idx=r->m_imageidx; + } + } + + str=(NSString *)SWELL_CStringToCFString(p); + + if (style & LBS_OWNERDRAWFIXED) + { + SWELL_ODListViewCell *cell=[aTableColumn dataCell]; + if ([cell isKindOfClass:[SWELL_ODListViewCell class]]) [cell setItemIdx:rowIndex]; + } + } + + if (!m_lbMode && m_status_imagelist) + { + SWELL_StatusCell *cell=(SWELL_StatusCell*)[aTableColumn dataCell]; + if ([cell isKindOfClass:[SWELL_StatusCell class]]) + { + HICON icon=m_status_imagelist->Get(image_idx-1); + NSImage *img=NULL; + if (icon) img=(NSImage *)GetNSImageFromHICON(icon); + [cell setStatusImage:img]; + } + } + + return [str autorelease]; + +} + + +-(void)mouseDown:(NSEvent *)theEvent +{ + if (([theEvent modifierFlags] & NSControlKeyMask) && IsRightClickEmulateEnabled()) + { + m_fakerightmouse=1; + m_start_item=-1; + m_start_subitem=-1; + } + else + { + m_leftmousemovecnt=0; + m_fakerightmouse=0; + + NSPoint pt=[theEvent locationInWindow]; + pt=[self convertPoint:pt fromView:nil]; + m_start_item=[self rowAtPoint:pt]; + m_start_subitem=[self columnAtPoint:pt]; + + + + m_start_item_clickmode=0; + if (m_start_item >=0 && (m_fastClickMask&(1<Get(nmlv.iItem); + if (row) + nmlv.lParam = row->m_param; + SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); + m_start_item_clickmode=4; + } + else + { + if (m_start_item>=0 && m_status_imagelist && LVSIL_STATE == m_status_imagelist_type && pt.x <= [self rowHeight]) // in left area + { + m_start_item_clickmode=1; + } + } + } +} + +-(void)mouseDragged:(NSEvent *)theEvent +{ + if (++m_leftmousemovecnt==4) + { + if (m_start_item>=0 && !(m_start_item_clickmode&3)) + { + if (!m_lbMode) + { + // if m_start_item isnt selected, change selection to it now + if (!(m_start_item_clickmode&4) && ![self isRowSelected:m_start_item]) + { + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:m_start_item] byExtendingSelection:!!(GetAsyncKeyState(VK_CONTROL)&0x8000)]; + } + NMLISTVIEW hdr={{(HWND)self,[self tag],LVN_BEGINDRAG},m_start_item,m_start_subitem,0,}; + SendMessage((HWND)[self target],WM_NOTIFY,[self tag], (LPARAM) &hdr); + m_start_item_clickmode |= 2; + } + } + } + else if (m_leftmousemovecnt > 4 && !(m_start_item_clickmode&1)) + { + HWND tgt=(HWND)[self target]; + POINT p; + GetCursorPos(&p); + ScreenToClient(tgt,&p); + + SendMessage(tgt,WM_MOUSEMOVE,0,(p.x&0xffff) + (((int)p.y)<<16)); + } +} + +-(void)mouseUp:(NSEvent *)theEvent +{ + if (m_fakerightmouse||([theEvent modifierFlags] & NSControlKeyMask)) + { + [self rightMouseUp:theEvent]; + } + else if (!(m_start_item_clickmode&1)) + { + if (m_leftmousemovecnt>=0 && m_leftmousemovecnt<4 && !(m_start_item_clickmode&4)) + { + if (m_lbMode && ![self allowsMultipleSelection]) // listboxes --- allow clicking to reset the selection + { + [self deselectAll:self]; + } + [super mouseDown:theEvent]; + [super mouseUp:theEvent]; + } + else if (m_leftmousemovecnt>=4) + { + HWND tgt=(HWND)[self target]; + POINT p; + GetCursorPos(&p); + ScreenToClient(tgt,&p); + SendMessage(tgt,WM_LBUTTONUP,0,(p.x&0xffff) + (((int)p.y)<<16)); + } + } + + if (!m_lbMode && !(m_start_item_clickmode&(2|4))) + { + NSPoint pt=[theEvent locationInWindow]; + pt=[self convertPoint:pt fromView:nil]; + int col = [self columnAtPoint:pt]; + NMLISTVIEW nmlv={{(HWND)self,[self tag], NM_CLICK}, [self rowAtPoint:pt], col, 0, 0, 0, {(int)floor(pt.x), (int)floor(pt.y)}, }; + SWELL_ListView_Row *row=m_items->Get(nmlv.iItem); + if (row) nmlv.lParam = row->m_param; + SendMessage((HWND)[self target],WM_NOTIFY,[self tag],(LPARAM)&nmlv); + } +} + +- (void)rightMouseUp:(NSEvent *)theEvent +{ + bool wantContext=true; + + if (!m_lbMode) + { + NSPoint pt=[theEvent locationInWindow]; + pt=[self convertPoint:pt fromView:nil]; + + // note, windows selects on right mousedown + int row=[self rowAtPoint:pt]; + if (row >= 0 && ![self isRowSelected:row]) + { + NSIndexSet* rows=[NSIndexSet indexSetWithIndex:row]; + [self deselectAll:self]; + [self selectRowIndexes:rows byExtendingSelection:NO]; + } + + NMLISTVIEW nmlv={{(HWND)self,[self tag], NM_RCLICK}, [self rowAtPoint:pt], [self columnAtPoint:pt], 0, 0, 0, {(int)floor(pt.x), (int)floor(pt.y)}, }; + if (SendMessage((HWND)[self target],WM_NOTIFY,nmlv.hdr.idFrom,(LPARAM)&nmlv)) wantContext=false; + } + if (wantContext) + { + POINT p; + GetCursorPos(&p); + SendMessage((HWND)[self target],WM_CONTEXTMENU,(WPARAM)self,(p.x&0xffff)|(p.y<<16)); + } + m_fakerightmouse=0; +} + +-(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam +{ + HWND hwnd=(HWND)self; + switch (msg) + { + case LB_RESETCONTENT: + ownermode_cnt=0; + if (m_items) + { + m_items->Empty(true); + [self reloadData]; + } + return 0; + case LB_ADDSTRING: + case LB_INSERTSTRING: + { + int cnt=ListView_GetItemCount(hwnd); + if (msg == LB_ADDSTRING && (style & LBS_SORT)) + { + SWELL_ListView *tv=(SWELL_ListView*)hwnd; + if (tv->m_lbMode && tv->m_items) + { + cnt=ptrlist_bsearch_mod((char *)lParam,tv->m_items,_listviewrowSearchFunc,NULL); + } + } + if (msg==LB_ADDSTRING) wParam=cnt; + else if (wParam > cnt) wParam=cnt; + LVITEM lvi={LVIF_TEXT,wParam,0,0,0,(char *)lParam}; + ListView_InsertItem(hwnd,&lvi); + } + return wParam; + case LB_GETCOUNT: return ListView_GetItemCount(hwnd); + case LB_SETSEL: + ListView_SetItemState(hwnd, lParam,wParam ? LVIS_SELECTED : 0,LVIS_SELECTED); + return 0; + case LB_GETTEXT: + if (lParam) + { + ListView_GetItemText(hwnd,wParam,0,(char *)lParam,4096); + } + return 0; + case LB_GETSEL: + return !!(ListView_GetItemState(hwnd,wParam,LVIS_SELECTED)&LVIS_SELECTED); + case LB_GETCURSEL: + return [self selectedRow]; + case LB_SETCURSEL: + { + if (wParamGet(wParam); + if (row) return row->m_param; + } + } + return 0; + case LB_SETITEMDATA: + { + if (m_items) + { + SWELL_ListView_Row *row=m_items->Get(wParam); + if (row) row->m_param=lParam; + } + } + return 0; + case LB_GETSELCOUNT: + return [[self selectedRowIndexes] count]; + case LB_DELETESTRING: + ListView_DeleteItem((HWND)self, wParam); + return 0; + } + return 0; +} + +-(int)getSwellNotificationMode +{ + return m_lbMode; +} +-(void)setSwellNotificationMode:(int)lbMode +{ + m_lbMode=lbMode; +} + +-(void)onSwellCommand:(int)cmd +{ + // ignore commands +} + +@end + + +@implementation SWELL_ODButtonCell +- (BOOL)isTransparent +{ + return YES; +} +- (BOOL)isOpaque +{ + return NO; +} + +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + NSView *ctl=[self controlView]; + if (!ctl) { [super drawWithFrame:cellFrame inView:controlView]; return; } + + HDC hdc=GetDC((HWND)controlView); + if (hdc) + { + HWND notWnd = GetParent((HWND)ctl); + RECT r={(int)(cellFrame.origin.x+0.5),(int)(cellFrame.origin.y+0.5)}; + r.right=r.left+(int)(cellFrame.size.width+0.5); + r.bottom=r.top+(int)(cellFrame.size.height+0.5); + DRAWITEMSTRUCT dis={ODT_BUTTON,[ctl tag],0,0,0,(HWND)ctl,hdc,{0,},0}; + dis.rcItem = r; + SendMessage(notWnd,WM_DRAWITEM,dis.CtlID,(LPARAM)&dis); + + ReleaseDC((HWND)controlView,hdc); + } + +} +@end + +@implementation SWELL_ODListViewCell +-(void)setOwnerControl:(SWELL_ListView *)t { m_ownctl=t; m_lastidx=0; } +-(void)setItemIdx:(int)idx +{ + m_lastidx=idx; +} +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if (!m_ownctl) { [super drawInteriorWithFrame:cellFrame inView:controlView]; return; } + + int itemidx=m_lastidx; + int itemData=0; // todo: get itemData + SWELL_ListView_Row *row=m_ownctl->m_items->Get(itemidx); + if (row) itemData=row->m_param; + + HDC hdc=GetDC((HWND)controlView); + if (hdc) + { + HWND notWnd = GetParent((HWND)m_ownctl); + RECT r={(int)(cellFrame.origin.x+0.5),(int)(cellFrame.origin.y+0.5)}; + r.right=r.left+(int)(cellFrame.size.width+0.5); + r.bottom=r.top+(int)(cellFrame.size.height+0.5); + DRAWITEMSTRUCT dis={ODT_LISTBOX,[m_ownctl tag],itemidx,0,0,(HWND)m_ownctl,hdc,{0,},itemData}; + dis.rcItem = r; + SendMessage(notWnd,WM_DRAWITEM,dis.CtlID,(LPARAM)&dis); + + ReleaseDC((HWND)controlView,hdc); + } +} + + +@end + + + + + +HWND GetDlgItem(HWND hwnd, int idx) +{ + if (!hwnd) return 0; + + NSView *v=0; + id pid=(id)hwnd; + if ([pid isKindOfClass:[NSWindow class]]) v=[((NSWindow *)pid) contentView]; + else if ([pid isKindOfClass:[NSView class]]) v=(NSView *)pid; + + if (!idx || !v) return (HWND)v; + + SWELL_BEGIN_TRY + + NSArray *ar = [v subviews]; + int n=[ar count]; + int x; + for (x=0;xhwnd && [rec->hwnd respondsToSelector:@selector(swellSetOwner:)]) + [(SWELL_ModelessWindow *)rec->hwnd swellSetOwner:(id)bla]; + rec=rec->_next; + } + } + } + } + // move all child and owned windows over to new window + NSArray *ar=[oldw childWindows]; + if (ar) + { + int x; + for (x = 0; x < [ar count]; x ++) + { + NSWindow *cw=[ar objectAtIndex:x]; + if (cw) + { + [cw retain]; + [oldw removeChildWindow:cw]; + [(NSWindow *)bla addChildWindow:cw ordered:NSWindowAbove]; + [cw release]; + + + } + } + } + + if (oldpar) [oldpar addChildWindow:(NSWindow *)bla ordered:NSWindowAbove]; + if (oldtitle[0]) SetWindowText(hwnd,oldtitle); + + [(NSWindow *)bla setFrame:fr display:dovis]; + [(NSWindow *)bla setLevel:oldlevel]; + if (dovis) ShowWindow(bla,SW_SHOW); + + DestroyWindow((HWND)oldw); + } + else + { + [oldw setContentView:tv]; + [tv release]; + } + + } + } + } + return 0; + } + + + if ([pid respondsToSelector:@selector(setSwellExtraData:value:)]) + { + LONG_PTR ov=0; + if ([pid respondsToSelector:@selector(getSwellExtraData:)]) ov=(LONG_PTR)[pid getSwellExtraData:idx]; + + [pid setSwellExtraData:idx value:val]; + + return ov; + } + + SWELL_END_TRY(;) + return 0; +} + +LONG_PTR GetWindowLong(HWND hwnd, int idx) +{ + if (!hwnd) return 0; + id pid=(id)hwnd; + + SWELL_BEGIN_TRY + + if (idx==GWL_EXSTYLE && [pid respondsToSelector:@selector(swellGetExtendedStyle)]) + { + return (LONG_PTR)[pid swellGetExtendedStyle]; + } + + if (idx==GWL_USERDATA && [pid respondsToSelector:@selector(getSwellUserData)]) + { + return (LONG_PTR)[pid getSwellUserData]; + } + if (idx==GWL_USERDATA && [pid isKindOfClass:[NSText class]]) + { + return 0xdeadf00b; + } + + if (idx==GWL_ID && [pid respondsToSelector:@selector(tag)]) + return [pid tag]; + + + if (idx==GWL_WNDPROC && [pid respondsToSelector:@selector(getSwellWindowProc)]) + { + return (LONG_PTR)[pid getSwellWindowProc]; + } + if (idx==DWL_DLGPROC && [pid respondsToSelector:@selector(getSwellDialogProc)]) + { + return (LONG_PTR)[pid getSwellDialogProc]; + } + if (idx==GWL_STYLE) + { + int ret=0; + if ([pid respondsToSelector:@selector(getSwellStyle)]) + { + return (LONG_PTR)[pid getSwellStyle]; + } + + if ([pid isKindOfClass:[NSButton class]]) + { + int tmp; + if ([pid allowsMixedState]) ret |= BS_AUTO3STATE; + else if ([pid isKindOfClass:[SWELL_Button class]] && (tmp = (int)[pid swellGetRadioFlags])) + { + ret |= BS_AUTORADIOBUTTON; + if (tmp&2) ret|=WS_GROUP; + } + else ret |= BS_AUTOCHECKBOX; + } + + if ([pid isKindOfClass:[NSView class]]) + { + if ([[pid window] contentView] != pid) ret |= WS_CHILDWINDOW; + else + { + unsigned int smask =[[pid window] styleMask]; + if (smask & NSTitledWindowMask) + { + ret|=WS_CAPTION; + if (smask & NSResizableWindowMask) ret|=WS_THICKFRAME; + } + } + } + + return ret; + } + if ([pid respondsToSelector:@selector(getSwellExtraData:)]) + { + return (LONG_PTR)[pid getSwellExtraData:idx]; + } + + SWELL_END_TRY(;) + return 0; +} + +static bool IsWindowImpl(NSView *ch, NSView *par) +{ + if (!par || ![par isKindOfClass:[NSView class]]) return false; + + NSArray *ar = [par subviews]; + if (!ar) return false; + [ar retain]; + int x,n=[ar count]; + for (x=0;xtype != TYPE_BITMAP) return 0; + return i->bitmapptr; +} + + +@implementation SWELL_Button : NSButton + +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(id) init { + self = [super init]; + if (self != nil) { + m_userdata=0; + m_swellGDIimage=0; + m_radioflags=0; + } + return self; +} +-(int)swellGetRadioFlags { return m_radioflags; } +-(void)swellSetRadioFlags:(int)f { m_radioflags=f; } +-(LONG_PTR)getSwellUserData { return m_userdata; } +-(void)setSwellUserData:(LONG_PTR)val { m_userdata=val; } + +-(void)setSwellGDIImage:(void *)par +{ + m_swellGDIimage=par; +} +-(void *)getSwellGDIImage +{ + return m_swellGDIimage; +} + +@end + +LRESULT SendMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (!hwnd) return 0; + + SWELL_BEGIN_TRY + id obj=(id)hwnd; + if ([obj respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + { + return (LRESULT) [obj onSwellMessage:msg p1:wParam p2:lParam]; + } + else + { + if (msg == BM_GETCHECK && [obj isKindOfClass:[NSButton class]]) + { + int a=[(NSButton*)obj state]; + if (a==NSMixedState) return BST_INDETERMINATE; + return a!=NSOffState; + } + if (msg == BM_SETCHECK && [obj isKindOfClass:[NSButton class]]) + { + [(NSButton*)obj setState:(wParam&BST_INDETERMINATE)?NSMixedState:((wParam&BST_CHECKED)?NSOnState:NSOffState)]; + return 0; + } + if ((msg==BM_GETIMAGE || msg == BM_SETIMAGE) && [obj isKindOfClass:[SWELL_Button class]]) + { + if (wParam != IMAGE_BITMAP && wParam != IMAGE_ICON) return 0; // ignore unknown types + LONG_PTR ret=(LONG_PTR) (void *)[obj getSwellGDIImage]; + if (msg==BM_SETIMAGE) + { + NSImage *img=NULL; + if (lParam) img=(NSImage *)__GetNSImageFromHICON((HICON)lParam); + [obj setImage:img]; + [obj setSwellGDIImage:(void *)(img?lParam:0)]; + } + return ret; + } + else if (msg >= CB_ADDSTRING && msg <= CB_INITSTORAGE && ([obj isKindOfClass:[NSPopUpButton class]] || [obj isKindOfClass:[NSComboBox class]])) + { + switch (msg) + { + case CB_ADDSTRING: return SWELL_CB_AddString(hwnd,0,(char*)lParam); + case CB_DELETESTRING: SWELL_CB_DeleteString(hwnd,0,wParam); return 1; + case CB_GETCOUNT: return SWELL_CB_GetNumItems(hwnd,0); + case CB_GETCURSEL: return SWELL_CB_GetCurSel(hwnd,0); + case CB_GETLBTEXT: return SWELL_CB_GetItemText(hwnd,0,wParam,(char *)lParam, 1024); + case CB_INSERTSTRING: return SWELL_CB_InsertString(hwnd,0,wParam,(char *)lParam); + case CB_RESETCONTENT: SWELL_CB_Empty(hwnd,0); return 0; + case CB_SETCURSEL: SWELL_CB_SetCurSel(hwnd,0,wParam); return 0; + case CB_GETITEMDATA: return SWELL_CB_GetItemData(hwnd,0,wParam); + case CB_SETITEMDATA: SWELL_CB_SetItemData(hwnd,0,wParam,lParam); return 0; + case CB_FINDSTRING: + case CB_FINDSTRINGEXACT: + if (lParam) return SWELL_CB_FindString(hwnd,0,(int)wParam,(const char *)lParam,msg==CB_FINDSTRINGEXACT); + return CB_ERR; + case CB_INITSTORAGE: return 0; + } + return 0; + } + else if (msg >= TBM_GETPOS && msg <= TBM_SETRANGE && ([obj isKindOfClass:[NSSlider class]])) + { + switch (msg) + { + case TBM_GETPOS: return SWELL_TB_GetPos(hwnd,0); + case TBM_SETTIC: SWELL_TB_SetTic(hwnd,0,lParam); return 1; + case TBM_SETPOS: SWELL_TB_SetPos(hwnd,0,lParam); return 1; + case TBM_SETRANGE: SWELL_TB_SetRange(hwnd,0,LOWORD(lParam),HIWORD(lParam)); return 1; + } + return 0; + } + else if ((msg == EM_SETSEL || msg == EM_GETSEL || msg == EM_SETPASSWORDCHAR) && ([obj isKindOfClass:[NSTextField class]])) + { + if (msg == EM_GETSEL) + { + NSRange range={0,}; + if ([[obj window] firstResponder] == obj) + { + NSText* text=[[obj window] fieldEditor:YES forObject:(NSTextField*)obj]; + if (text) range=[text selectedRange]; + } + if (wParam) *(int*)wParam=range.location; + if (lParam) *(int*)lParam=range.location+range.length; + } + else if (msg == EM_SETSEL) + { + // [(NSTextField*)obj selectText:obj]; // Force the window's text field editor onto this control + // don't force it, just ignore EM_GETSEL/EM_SETSEL if not in focus + if ([[obj window] firstResponder] == obj) + { + NSText* text = [[obj window] fieldEditor:YES forObject:(NSTextField*)obj]; // then get it from the window + int sl = [[text string] length]; + if (wParam == -1) lParam = wParam = 0; + else if (lParam == -1) lParam = sl; + if (wParam>sl) wParam=sl; + if (lParam>sl) lParam=sl; + if (text) [text setSelectedRange:NSMakeRange(wParam, max(lParam-wParam,0))]; // and set the range + } + } + else if (msg == EM_SETPASSWORDCHAR) + { + // not implemented, because it requires replacing obj within its parent window + // instead caller explicitly destroy the edit control and create a new one with ES_PASSWORD + } + return 0; + } + else + { + NSWindow *w; + NSView *v; + // if content view gets unhandled message send to window + if ([obj isKindOfClass:[NSView class]] && (w=[obj window]) && [w contentView] == obj && [w respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + { + return (LRESULT) [(SWELL_hwndChild *)w onSwellMessage:msg p1:wParam p2:lParam]; + } + // if window gets unhandled message send to content view + else if ([obj isKindOfClass:[NSWindow class]] && (v=[obj contentView]) && [v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + { + return (LRESULT) [(SWELL_hwndChild *)v onSwellMessage:msg p1:wParam p2:lParam]; + } + } + } + SWELL_END_TRY(;) + return 0; +} + +void DestroyWindow(HWND hwnd) +{ + if (!hwnd) return; + SWELL_BEGIN_TRY + id pid=(id)hwnd; + if ([pid isKindOfClass:[NSView class]]) + { + KillTimer(hwnd,~(UINT_PTR)0); + sendSwellMessage((id)pid,WM_DESTROY,0,0); + + NSWindow *pw = [(NSView *)pid window]; + if (pw && [pw contentView] == pid) // destroying contentview should destroy top level window + { + DestroyWindow((HWND)pw); + } + else + { + if (pw && [NSApp keyWindow] == pw) + { + id foc=[pw firstResponder]; + if (foc && (foc == pid || IsChild((HWND)pid,(HWND)foc))) + { + HWND h=GetParent((HWND)pid); + if (h) SetFocus(h); + } + } + [(NSView *)pid removeFromSuperview]; + } + } + else if ([pid isKindOfClass:[NSWindow class]]) + { + KillTimer(hwnd,~(UINT_PTR)0); + sendSwellMessage([(id)pid contentView],WM_DESTROY,0,0); + sendSwellMessage((id)pid,WM_DESTROY,0,0); + + if ([(id)pid respondsToSelector:@selector(swellDoDestroyStuff)]) + [(id)pid swellDoDestroyStuff]; + + NSWindow *par=[(NSWindow*)pid parentWindow]; + if (par) + { + [par removeChildWindow:(NSWindow*)pid]; + } + [(NSWindow *)pid close]; // this is probably bad, but close takes too long to close! + } + SWELL_END_TRY(;) +} + +void EnableWindow(HWND hwnd, int enable) +{ + if (!hwnd) return; + SWELL_BEGIN_TRY + id bla=(id)hwnd; + if ([bla isKindOfClass:[NSWindow class]]) bla = [bla contentView]; + + if (bla && [bla respondsToSelector:@selector(setEnabled:)]) + { + [bla setEnabled:(enable?YES:NO)]; + if ([bla isKindOfClass:[SWELL_TextField class]]) + { + NSTextField* txt = (NSTextField*)bla; + if (![txt isEditable] && ![txt isBordered] && ![txt drawsBackground]) // looks like a static text control + { + NSColor* col = [txt textColor]; + float alpha = (enable ? 1.0f : 0.5f); + [txt setTextColor:[col colorWithAlphaComponent:alpha]]; + } + } + } + SWELL_END_TRY(;) +} + +void SetForegroundWindow(HWND hwnd) +{ + SetFocus(hwnd); +} + +void SetFocus(HWND hwnd) // these take NSWindow/NSView, and return NSView * +{ + id r=(id) hwnd; + if (!r) return; + + SWELL_BEGIN_TRY + if ([r isKindOfClass:[NSWindow class]]) + { + [(NSWindow *)r makeFirstResponder:[(NSWindow *)r contentView]]; + if ([(NSWindow *)r isVisible]) [(NSWindow *)r makeKeyAndOrderFront:nil]; + } + else if ([r isKindOfClass:[NSView class]]) + { + NSWindow *wnd=[(NSView *)r window]; + if (wnd) + { + [wnd makeFirstResponder:r]; + if ([wnd isVisible]) + { + [wnd makeKeyAndOrderFront:nil]; + } + } + } + SWELL_END_TRY(;) +} + +void SWELL_GetViewPort(RECT *r, RECT *sourcerect, bool wantWork) +{ + SWELL_BEGIN_TRY + + NSArray *ar=[NSScreen screens]; + + int cnt=[ar count]; + int x; + int cx=0; + int cy=0; + if (sourcerect) + { + cx=(sourcerect->left+sourcerect->right)/2; + cy=(sourcerect->top+sourcerect->bottom)/2; + } + for (x = 0; x < cnt; x ++) + { + NSScreen *sc=[ar objectAtIndex:x]; + if (sc) + { + NSRect tr=wantWork ? [sc visibleFrame] : [sc frame]; + if (!x || (cx >= tr.origin.x && cx < tr.origin.x+tr.size.width && + cy >= tr.origin.y && cy < tr.origin.y+tr.size.height)) + { + r->left=(int)tr.origin.x; + r->right=(int)(tr.origin.x+tr.size.width+0.5); + r->top=(int)tr.origin.y; + r->bottom=(int)(tr.origin.y+tr.size.height+0.5); + } + } + } + if (!cnt) + { + r->left=r->top=0; + r->right=1600; + r->bottom=1200; + } + SWELL_END_TRY(;) +} + +void ScreenToClient(HWND hwnd, POINT *p) +{ + if (!hwnd) return; + // no need to try/catch, this should never have an issue *wince* + + id ch=(id)hwnd; + if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; + if (!ch || ![ch isKindOfClass:[NSView class]]) return; + + NSWindow *window=[ch window]; + + NSPoint wndpt = [window convertScreenToBase:NSMakePoint(p->x,p->y)]; + + // todo : WM_NCCALCSIZE + NSPoint po = [ch convertPoint:wndpt fromView:nil]; + + p->x=(int)(po.x+0.5); + p->y=(int)(po.y+0.5); +} + +void ClientToScreen(HWND hwnd, POINT *p) +{ + if (!hwnd) return; + + id ch=(id)hwnd; + if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; + if (!ch || ![ch isKindOfClass:[NSView class]]) return; + + NSWindow *window=[ch window]; + + NSPoint wndpt = [ch convertPoint:NSMakePoint(p->x,p->y) toView:nil]; + + NSPoint po = [window convertBaseToScreen:wndpt]; + // todo : WM_NCCALCSIZE + + p->x=(int)(po.x+0.5); + p->y=(int)(po.y+0.5); +} + +static NSView *NavigateUpScrollClipViews(NSView *ch) +{ + NSView *par=[ch superview]; + if (par && [par isKindOfClass:[NSClipView class]]) + { + par=[par superview]; + if (par && [par isKindOfClass:[NSScrollView class]]) + { + ch=par; + } + } + return ch; +} + +HWND SWELL_NavigateUpScrollClipViews(HWND h) +{ + NSView *v = 0; + if (h && [(id)h isKindOfClass:[NSView class]]) v = (NSView *)h; + else if (h && [(id)h isKindOfClass:[NSWindow class]]) v = [(NSWindow *)h contentView]; + if (v) + return (HWND)NavigateUpScrollClipViews(v); + return 0; +} + +bool GetWindowRect(HWND hwnd, RECT *r) +{ + r->left=r->top=r->right=r->bottom=0; + if (!hwnd) return false; + + SWELL_BEGIN_TRY + + id ch=(id)hwnd; + NSWindow *nswnd; + if ([ch isKindOfClass:[NSView class]] && (nswnd=[(NSView *)ch window]) && [nswnd contentView]==ch) + ch=nswnd; + + if ([ch isKindOfClass:[NSWindow class]]) + { + NSRect b=[ch frame]; + r->left=(int)(b.origin.x); + r->top=(int)(b.origin.y); + r->right = (int)(b.origin.x+b.size.width+0.5); + r->bottom= (int)(b.origin.y+b.size.height+0.5); + return true; + } + if (![ch isKindOfClass:[NSView class]]) return false; + ch=NavigateUpScrollClipViews(ch); + NSRect b=[ch bounds]; + r->left=(int)(b.origin.x); + r->top=(int)(b.origin.y); + r->right = (int)(b.origin.x+b.size.width+0.5); + r->bottom= (int)(b.origin.y+b.size.height+0.5); + ClientToScreen((HWND)ch,(POINT *)r); + ClientToScreen((HWND)ch,((POINT *)r)+1); + SWELL_END_TRY(return false;) + + return true; +} + +void GetWindowContentViewRect(HWND hwnd, RECT *r) +{ + SWELL_BEGIN_TRY + NSWindow *nswnd; + if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)hwnd window]) && [nswnd contentView]==(id)hwnd) + hwnd=(HWND)nswnd; + + if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) + { + NSView *ch=[(id)hwnd contentView]; + NSRect b=[ch bounds]; + r->left=(int)(b.origin.x); + r->top=(int)(b.origin.y); + r->right = (int)(b.origin.x+b.size.width+0.5); + r->bottom= (int)(b.origin.y+b.size.height+0.5); + ClientToScreen(hwnd,(POINT *)r); + ClientToScreen(hwnd,((POINT *)r)+1); + } + else GetWindowRect(hwnd,r); + SWELL_END_TRY(;) +} + + +void GetClientRect(HWND hwnd, RECT *r) +{ + r->left=r->top=r->right=r->bottom=0; + if (!hwnd) return; + + SWELL_BEGIN_TRY + id ch=(id)hwnd; + if ([ch isKindOfClass:[NSWindow class]]) ch=[((NSWindow *)ch) contentView]; + if (!ch || ![ch isKindOfClass:[NSView class]]) return; + ch=NavigateUpScrollClipViews(ch); + + NSRect b=[ch bounds]; + r->left=(int)(b.origin.x); + r->top=(int)(b.origin.y); + r->right = (int)(b.origin.x+b.size.width+0.5); + r->bottom= (int)(b.origin.y+b.size.height+0.5); + + // todo this may need more attention + RECT tr=*r; + SendMessage(hwnd,WM_NCCALCSIZE,FALSE,(LPARAM)&tr); + r->right = r->left + (tr.right-tr.left); + r->bottom = r->top + (tr.bottom-tr.top); + SWELL_END_TRY(;) +} + + + +void SetWindowPos(HWND hwnd, HWND hwndAfter, int x, int y, int cx, int cy, int flags) +{ + if (!hwnd) return; + + SWELL_BEGIN_TRY + NSWindow *nswnd; // content views = move window + if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && (nswnd=[(NSView *)hwnd window]) && [nswnd contentView]==(id)hwnd) + hwnd=(HWND)nswnd; + + // todo: handle SWP_SHOWWINDOW + id ch=(id)hwnd; + bool isview=false; + if ([ch isKindOfClass:[NSWindow class]] || (isview=[ch isKindOfClass:[NSView class]])) + { + if (isview) + { + ch=NavigateUpScrollClipViews(ch); + if (isview && !(flags&SWP_NOZORDER)) + { + NSView *v = (NSView *)ch; + NSView *par = [v superview]; + NSArray *subs = [par subviews]; + int idx = [subs indexOfObjectIdenticalTo:v], cnt=[subs count]; + + NSView *viewafter = NULL; + NSWindowOrderingMode omode = NSWindowAbove; + + if (cnt>1 && hwndAfter != (HWND)ch) + { + if (hwndAfter==HWND_TOPMOST||hwndAfter==HWND_NOTOPMOST) + { + } + else if (hwndAfter == HWND_TOP) + { + if (idx0) viewafter = [subs objectAtIndex:0]; + omode = NSWindowBelow; + } + else + { + NSInteger a=[subs indexOfObjectIdenticalTo:(NSView *)hwndAfter]; + if (a != NSNotFound && a != (idx-1)) viewafter = (NSView *)hwndAfter; + } + } + + if (viewafter) + { + HWND h = GetCapture(); + if (!h || (h!=(HWND)v && !IsChild((HWND)v,h))) // if this window is captured don't reorder! + { + NSView *oldfoc = (NSView*)[[v window] firstResponder]; + if (!oldfoc || ![oldfoc isKindOfClass:[NSView class]] || + (oldfoc != v && ![oldfoc isDescendantOf:v])) oldfoc=NULL; + + // better way to do this? maybe :/ + [v retain]; + [v removeFromSuperviewWithoutNeedingDisplay]; + [par addSubview:v positioned:omode relativeTo:viewafter]; + [v release]; + + if (oldfoc) [[v window] makeFirstResponder:oldfoc]; + } + } + } + } + NSRect f=[ch frame]; + bool repos=false; + if (!(flags&SWP_NOMOVE)) + { + f.origin.x=(float)x; + f.origin.y=(float)y; + repos=true; + } + if (!(flags&SWP_NOSIZE)) + { + f.size.width=(float)cx; + f.size.height=(float)cy; + if (f.size.height<0)f.size.height=-f.size.height; + repos=true; + } + if (repos) + { + if (!isview) + { + NSSize mins=[ch minSize]; + NSSize maxs=[ch maxSize]; + if (f.size.width < mins.width) f.size.width=mins.width; + else if (f.size.width > maxs.width) f.size.width=maxs.width; + if (f.size.height < mins.height) f.size.height=mins.height; + else if (f.size.height> maxs.height) f.size.height=maxs.height; + [ch setFrame:f display:NO]; + [ch display]; + } + else + { + // this doesnt seem to actually be a good idea anymore + // if ([[ch window] contentView] != ch && ![[ch superview] isFlipped]) +// f.origin.y -= f.size.height; + [ch setFrame:f]; + if ([ch isKindOfClass:[NSScrollView class]]) + { + NSView *cv=[ch documentView]; + if (cv && [cv isKindOfClass:[NSTextView class]]) + { + NSRect fr=[cv frame]; + NSSize sz=[ch contentSize]; + int a=0; + if (![ch hasHorizontalScroller]) {a ++; fr.size.width=sz.width; } + if (![ch hasVerticalScroller]) { a++; fr.size.height=sz.height; } + if (a) [cv setFrame:fr]; + } + } + } + } + return; + } + SWELL_END_TRY(;) +} + + +HWND GetWindow(HWND hwnd, int what) +{ + if (!hwnd) return 0; + SWELL_BEGIN_TRY + + if ([(id)hwnd isKindOfClass:[NSWindow class]]) hwnd=(HWND)[(id)hwnd contentView]; + if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return 0; + + NSView *v=(NSView *)hwnd; + if (what == GW_CHILD) + { + NSArray *ar=[v subviews]; + if (ar && [ar count]>0) + { + return (HWND)[ar objectAtIndex:0]; + } + return 0; + } + if (what == GW_OWNER) + { + v=NavigateUpScrollClipViews(v); + if ([[v window] contentView] == v) + { + if ([[v window] respondsToSelector:@selector(swellGetOwner)]) + { + return (HWND)[(SWELL_ModelessWindow*)[v window] swellGetOwner]; + } + return 0; + } + return (HWND)[v superview]; + } + + if (what >= GW_HWNDFIRST && what <= GW_HWNDPREV) + { + v=NavigateUpScrollClipViews(v); + if ([[v window] contentView] == v) + { + if (what <= GW_HWNDLAST) return (HWND)hwnd; // content view is only window + + return 0; // we're the content view so cant do next/prev + } + NSView *par=[v superview]; + if (par) + { + NSArray *ar=[par subviews]; + int cnt; + if (ar && (cnt=[ar count]) > 0) + { + if (what == GW_HWNDFIRST) + return (HWND)[ar objectAtIndex:0]; + if (what == GW_HWNDLAST) + return (HWND)[ar objectAtIndex:(cnt-1)]; + + NSInteger idx=[ar indexOfObjectIdenticalTo:v]; + if (idx == NSNotFound) return 0; + + if (what==GW_HWNDNEXT) idx++; + else if (what==GW_HWNDPREV) idx--; + + if (idx<0 || idx>=cnt) return 0; + + return (HWND)[ar objectAtIndex:idx]; + } + } + return 0; + } + SWELL_END_TRY(;) + return 0; +} + + +HWND GetParent(HWND hwnd) +{ + SWELL_BEGIN_TRY + if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) + { + hwnd=(HWND)NavigateUpScrollClipViews((NSView *)hwnd); + + NSView *cv=[[(NSView *)hwnd window] contentView]; + if (cv == (NSView *)hwnd) hwnd=(HWND)[(NSView *)hwnd window]; // passthrough to get window parent + else + { + HWND h=(HWND)[(NSView *)hwnd superview]; + return h; + } + } + + if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) + { + HWND h= (HWND)[(NSWindow *)hwnd parentWindow]; + if (h) h=(HWND)[(NSWindow *)h contentView]; + if (h) return h; + } + + if (hwnd && [(id)hwnd respondsToSelector:@selector(swellGetOwner)]) + { + HWND h= (HWND)[(SWELL_ModelessWindow *)hwnd swellGetOwner]; + if (h && [(id)h isKindOfClass:[NSWindow class]]) h=(HWND)[(NSWindow *)h contentView]; + return h; + } + + SWELL_END_TRY(;) + return 0; +} + +HWND SetParent(HWND hwnd, HWND newPar) +{ + SWELL_BEGIN_TRY + NSView *v=(NSView *)hwnd; + if (!v || ![(id)v isKindOfClass:[NSView class]]) return 0; + v=NavigateUpScrollClipViews(v); + + if ([(id)hwnd isKindOfClass:[NSView class]]) + { + NSView *tv=(NSView *)hwnd; + if ([[tv window] contentView] == tv) // if we're reparenting a contentview (aka top level window) + { + if (!newPar) return NULL; + + NSView *npv = (NSView *)newPar; + if ([npv isKindOfClass:[NSWindow class]]) npv=[(NSWindow *)npv contentView]; + if (!npv || ![npv isKindOfClass:[NSView class]]) + return NULL; + + char oldtitle[2048]; + oldtitle[0]=0; + GetWindowText(hwnd,oldtitle,sizeof(oldtitle)); + + NSWindow *oldwnd = [tv window]; + id oldown = NULL; + if ([oldwnd respondsToSelector:@selector(swellGetOwner)]) oldown=[(SWELL_ModelessWindow*)oldwnd swellGetOwner]; + + if ([tv isKindOfClass:[SWELL_hwndChild class]]) ((SWELL_hwndChild*)tv)->m_lastTopLevelOwner = oldown; + + [tv retain]; + SWELL_hwndChild *tmpview = [[SWELL_hwndChild alloc] initChild:nil Parent:(NSView *)oldwnd dlgProc:nil Param:0]; + [tmpview release]; + + [npv addSubview:tv]; + [tv release]; + + DestroyWindow((HWND)oldwnd); // close old window since its no longer used + if (oldtitle[0]) SetWindowText(hwnd,oldtitle); + return (HWND)npv; + } + else if (!newPar) // not content view, not parent (so making it a top level modeless dialog) + { + char oldtitle[2048]; + oldtitle[0]=0; + GetWindowText(hwnd,oldtitle,sizeof(oldtitle)); + + [tv retain]; + [tv removeFromSuperview]; + + + unsigned int wf=(NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask); + if ([tv respondsToSelector:@selector(swellCreateWindowFlags)]) + wf=(unsigned int)[(SWELL_hwndChild *)tv swellCreateWindowFlags]; + + HWND newOwner=NULL; + if ([tv isKindOfClass:[SWELL_hwndChild class]]) + { + id oldown = ((SWELL_hwndChild*)tv)->m_lastTopLevelOwner; + if (oldown) + { + NSArray *ch=[NSApp windows]; + int x,n=[ch count]; + for(x=0;x=0 && wh<[p numberOfItems]) + { + [p removeItemAtIndex:wh]; + if (((SWELL_ComboBox*)p)->m_ids) ((SWELL_ComboBox*)p)->m_ids->Delete(wh); + } + } + else if ( [p isKindOfClass:[NSPopUpButton class]]) + { + NSMenu *menu = [p menu]; + if (menu) + { + if (wh >= 0 && wh < [menu numberOfItems]) + [menu removeItemAtIndex:wh]; + } + } +} + + +int SWELL_CB_FindString(HWND hwnd, int idx, int startAfter, const char *str, bool exact) +{ + NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); + if (!p) return 0; + + int pos = startAfter; + if (pos<0)pos=0; + else pos++; + + int l1len =strlen(str); + int ni=[p numberOfItems]; + + if ([p isKindOfClass:[NSComboBox class]]) + { + for(;pos= ni) return 0; + + if ([p isKindOfClass:[NSComboBox class]]) + { + NSString *s=[p itemObjectValueAtIndex:item]; + if (s) + { + SWELL_CFStringToCString(s,buf,bufsz); +// [s getCString:buf maxLength:bufsz]; + return 1; + } + } + else + { + NSMenuItem *i=[(NSPopUpButton *)p itemAtIndex:item]; + if (i) + { + NSString *s=[i title]; + if (s) + { + SWELL_CFStringToCString(s,buf,bufsz); +// [s getCString:buf maxLength:bufsz]; + return 1; + } + } + } + return 0; +} + + +int SWELL_CB_InsertString(HWND hwnd, int idx, int pos, const char *str) +{ + NSString *label=(NSString *)SWELL_CStringToCFString(str); + NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); + if (!p) return 0; + + bool isAppend=false; + int ni=[p numberOfItems]; + if (pos == -1000) + { + isAppend=true; + pos=ni; + } + else if (pos < 0) pos=0; + else if (pos > ni) pos=ni; + + + if ([p isKindOfClass:[SWELL_ComboBox class]]) + { + if (isAppend && (((int)[(SWELL_ComboBox*)p getSwellStyle]) & CBS_SORT)) + { + pos=arr_bsearch_mod(label,[p objectValues],_nsStringSearchProc); + } + + if (pos==ni) + [p addItemWithObjectValue:label]; + else + [p insertItemWithObjectValue:label atIndex:pos]; + + if (((SWELL_ComboBox*)p)->m_ids) ((SWELL_ComboBox*)p)->m_ids->Insert(pos,(char*)0); + [p setNumberOfVisibleItems:(ni+1)]; + } + else + { + NSMenu *menu = [(NSPopUpButton *)p menu]; + if (menu) + { + if (isAppend && [p respondsToSelector:@selector(getSwellStyle)] && (((int)[(SWELL_PopUpButton*)p getSwellStyle]) & CBS_SORT)) + { + pos=arr_bsearch_mod(label,[menu itemArray],_nsMenuSearchProc); + } + NSMenuItem *item=[menu insertItemWithTitle:label action:NULL keyEquivalent:@"" atIndex:pos]; + [item setEnabled:YES]; + } + } + [label release]; + return pos; + +} + +int SWELL_CB_AddString(HWND hwnd, int idx, const char *str) +{ + return SWELL_CB_InsertString(hwnd,idx,-1000,str); +} + +int SWELL_CB_GetCurSel(HWND hwnd, int idx) +{ + NSComboBox *p=(NSComboBox *)GetDlgItem(hwnd,idx); + if (!p) return -1; + return [p indexOfSelectedItem]; +} + +void SWELL_CB_SetCurSel(HWND hwnd, int idx, int item) +{ + if (item>=0 && item= [cb numberOfItems]) return; + NSMenuItem *it=[cb itemAtIndex:item]; + if (!it) return; + + SWELL_DataHold *p=[[SWELL_DataHold alloc] initWithVal:(void *)data]; + [it setRepresentedObject:p]; + [p release]; + } + else if ([cb isKindOfClass:[SWELL_ComboBox class]]) + { + if (item < 0 || item >= [cb numberOfItems]) return; + if (((SWELL_ComboBox*)cb)->m_ids) ((SWELL_ComboBox*)cb)->m_ids->Set(item,(char*)data); + } +} + +LONG_PTR SWELL_CB_GetItemData(HWND hwnd, int idx, int item) +{ + id cb=(id)GetDlgItem(hwnd,idx); + if (!cb) return 0; + if ([cb isKindOfClass:[NSPopUpButton class]]) + { + if (item < 0 || item >= [cb numberOfItems]) return 0; + NSMenuItem *it=[cb itemAtIndex:item]; + if (!it) return 0; + id p= [it representedObject]; + if (!p || ![p isKindOfClass:[SWELL_DataHold class]]) return 0; + return (LONG_PTR) (void *)[p getValue]; + } + else if ([cb isKindOfClass:[SWELL_ComboBox class]]) + { + if (item < 0 || item >= [cb numberOfItems]) return 0; + if (((SWELL_ComboBox*)cb)->m_ids) return (LONG_PTR) ((SWELL_ComboBox*)cb)->m_ids->Get(item); + } + return 0; +} + +void SWELL_CB_Empty(HWND hwnd, int idx) +{ + id cb=(id)GetDlgItem(hwnd,idx); + if (!cb) return; + if ([cb isKindOfClass:[NSPopUpButton class]] || + [cb isKindOfClass:[NSComboBox class]]) [cb removeAllItems]; + + if ([cb isKindOfClass:[SWELL_ComboBox class]]) + { + if (((SWELL_ComboBox*)cb)->m_ids) ((SWELL_ComboBox*)cb)->m_ids->Empty(); + } +} + + +BOOL SetDlgItemInt(HWND hwnd, int idx, int val, int issigned) +{ + char buf[128]; + sprintf(buf,issigned?"%d":"%u",val); + return SetDlgItemText(hwnd,idx,buf); +} + +int GetDlgItemInt(HWND hwnd, int idx, BOOL *translated, int issigned) +{ + char buf[128]; + if (!GetDlgItemText(hwnd,idx,buf,sizeof(buf))) + { + if (translated) *translated=0; + return 0; + } + char *p=buf; + while (*p == ' ' || *p == '\t') p++; + int a=atoi(p); + if ((a<0 && !issigned) || (!a && p[0] != '0')) { if (translated) *translated=0; return 0; } + if (translated) *translated=1; + return a; +} + +void SWELL_HideApp() +{ + [NSApp hide:NSApp]; +} + + +BOOL SWELL_GetGestureInfo(LPARAM lParam, GESTUREINFO* gi) +{ + if (!lParam || !gi) return FALSE; + memcpy(gi, (GESTUREINFO*)lParam, sizeof(GESTUREINFO)); + return TRUE; +} + + +void ShowWindow(HWND hwnd, int cmd) +{ + id pid=(id)hwnd; + + if (pid && [pid isKindOfClass:[NSWindow class]]) + { + if (cmd == SW_SHOWNA && [pid isKindOfClass:[SWELL_ModelessWindow class]]) + { + if (((SWELL_ModelessWindow *)pid)->m_wantInitialKeyWindowOnShow) + { + ((SWELL_ModelessWindow *)pid)->m_wantInitialKeyWindowOnShow=false; + cmd = SW_SHOW; + } + } + if (cmd==SW_SHOW) + { + [pid makeKeyAndOrderFront:pid]; + } + else if (cmd==SW_SHOWNA) + { + [pid orderFront:pid]; + } + else if (cmd==SW_HIDE) + { + [pid orderOut:pid]; + } + else if (cmd == SW_SHOWMINIMIZED) + { + // this ought to work + //if ([NSApp mainWindow] == pid) + //{ + // [NSApp hide:pid]; + //} + //else + //{ + [pid miniaturize:pid]; + //} + } + return; + } + if (!pid || ![pid isKindOfClass:[NSView class]]) return; + + pid=NavigateUpScrollClipViews(pid); + + switch (cmd) + { + case SW_SHOW: + case SW_SHOWNA: + [((NSView *)pid) setHidden:NO]; + break; + case SW_HIDE: + { + NSWindow *pw=[pid window]; + if (pw && [NSApp keyWindow] == pw) + { + id foc=[pw firstResponder]; + if (foc && (foc == pid || IsChild((HWND)pid,(HWND)foc))) + { + HWND h=GetParent((HWND)pid); + if (h) SetFocus(h); + } + } + if (![((NSView *)pid) isHidden]) + { + if ((NSView *)pid != [pw contentView]) + { + HWND par = (HWND) [(NSView *)pid superview]; + if (par) + { + RECT r; + GetWindowRect((HWND)pid,&r); + ScreenToClient(par,(LPPOINT)&r); + ScreenToClient(par,((LPPOINT)&r)+1); + InvalidateRect(par,&r,FALSE); + } + } + [((NSView *)pid) setHidden:YES]; + } + } + break; + } + + NSWindow *nswnd; + if ((nswnd=[(NSView *)pid window]) && [nswnd contentView]==(id)pid) + { + ShowWindow((HWND)nswnd,cmd); + } +} + +void *SWELL_ModalWindowStart(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) hwnd=(HWND)[(NSView *)hwnd window]; + if (!hwnd) return 0; + return (void *)[NSApp beginModalSessionForWindow:(NSWindow *)hwnd]; +} + +bool SWELL_ModalWindowRun(void *ctx, int *ret) // returns false and puts retval in *ret when done +{ + if (!ctx) return false; + int r=[NSApp runModalSession:(NSModalSession)ctx]; + if (r==NSRunContinuesResponse) return true; + if (ret) *ret=r; + return false; +} + +void SWELL_ModalWindowEnd(void *ctx) +{ + if (ctx) + { + if ([NSApp runModalSession:(NSModalSession)ctx] == NSRunContinuesResponse) + { + [NSApp stopModal]; + while ([NSApp runModalSession:(NSModalSession)ctx]==NSRunContinuesResponse) Sleep(10); + } + [NSApp endModalSession:(NSModalSession)ctx]; + } +} + +void SWELL_CloseWindow(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) + { + [((NSWindow*)hwnd) close]; + } + else if (hwnd && [(id)hwnd isKindOfClass:[NSView class]]) + { + [[(NSView*)hwnd window] close]; + } +} + + +#include "swell-dlggen.h" + +static id m_make_owner; +static NSRect m_transform; +static float m_parent_h; +static bool m_doautoright; +static NSRect m_lastdoauto; +static bool m_sizetofits; + +#define ACTIONTARGET (m_make_owner) + +void SWELL_MakeSetCurParms(float xscale, float yscale, float xtrans, float ytrans, HWND parent, bool doauto, bool dosizetofit) +{ + m_sizetofits=dosizetofit; + m_lastdoauto.origin.x = 0; + m_lastdoauto.origin.y = -100; + m_lastdoauto.size.width = 0; + m_doautoright=doauto; + m_transform.origin.x=xtrans; + m_transform.origin.y=ytrans; + m_transform.size.width=xscale; + m_transform.size.height=yscale; + m_make_owner=(id)parent; + if ([m_make_owner isKindOfClass:[NSWindow class]]) m_make_owner=[(NSWindow *)m_make_owner contentView]; + m_parent_h=100.0; + if ([(id)m_make_owner isKindOfClass:[NSView class]]) + { + m_parent_h=[(NSView *)m_make_owner bounds].size.height; + if (m_transform.size.height > 0 && [(id)parent isFlipped]) + m_transform.size.height*=-1; + } +} + +static void UpdateAutoCoords(NSRect r) +{ + m_lastdoauto.size.width=r.origin.x + r.size.width - m_lastdoauto.origin.x; +} + +static NSRect MakeCoords(int x, int y, int w, int h, bool wantauto, bool ignorevscaleheight=false) +{ + if (w<0&&h<0) + { + return NSMakeRect(-x,-y,-w,-h); + } + float ysc=m_transform.size.height; + float ysc2 = ignorevscaleheight ? 1.0 : ysc; + int newx=(int)((x+m_transform.origin.x)*m_transform.size.width + 0.5); + int newy=(int)((ysc >= 0.0 ? m_parent_h - ((y+m_transform.origin.y) )*ysc + h*ysc2 : + ((y+m_transform.origin.y) )*-ysc) + 0.5); + + NSRect ret= NSMakeRect(newx, + newy, + (int) (w*m_transform.size.width+0.5), + (int) (h*fabs(ysc2)+0.5)); + + NSRect oret=ret; + if (wantauto && m_doautoright) + { + float dx = ret.origin.x - m_lastdoauto.origin.x; + if (fabs(dx)<32 && m_lastdoauto.origin.y >= ret.origin.y && m_lastdoauto.origin.y < ret.origin.y + ret.size.height) + { + ret.origin.x += (int) m_lastdoauto.size.width; + } + + m_lastdoauto.origin.x = oret.origin.x + oret.size.width; + m_lastdoauto.origin.y = ret.origin.y + ret.size.height*0.5; + m_lastdoauto.size.width=0; + } + return ret; +} + +static const double minwidfontadjust=1.81; +#define TRANSFORMFONTSIZE (m_transform.size.width<1?8:m_transform.size.width<2?10:12) +/// these are for swell-dlggen.h +HWND SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, int h, int flags) +{ + UINT_PTR a=(UINT_PTR)label; + if (a < 65536) label = "ICONTEMP"; + SWELL_Button *button=[[SWELL_Button alloc] init]; + + if (m_transform.size.width < minwidfontadjust) + { + [button setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + } + + [button setTag:idx]; + if (g_swell_want_nice_style==1) + [button setBezelStyle:NSShadowlessSquareBezelStyle ]; + else + [button setBezelStyle:NSRoundedBezelStyle ]; + NSRect tr=MakeCoords(x,y,w,h,true); + + + if (g_swell_want_nice_style!=1 && tr.size.height >= 18 && tr.size.height<24) + { + tr.size.height=24; + } + + [button setFrame:tr]; + NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(label); + [button setTitle:labelstr]; + [button setTarget:ACTIONTARGET]; + [button setAction:@selector(onSwellCommand:)]; + if (flags&SWELL_NOT_WS_VISIBLE) [button setHidden:YES]; + [m_make_owner addSubview:button]; + if (m_doautoright) UpdateAutoCoords([button frame]); + if (def) [[m_make_owner window] setDefaultButtonCell:(NSButtonCell*)button]; + [labelstr release]; + [button release]; + return (HWND) button; +} + + +@implementation SWELL_TextView + +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(NSInteger) tag +{ + return m_tag; +} + +-(void) setTag:(NSInteger)tag +{ + m_tag=tag; +} + +-(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam +{ + switch (msg) + { + case EM_SCROLL: + if (wParam == SB_TOP) + { + [self scrollRangeToVisible:NSMakeRange(0, 0)]; + } + else if (wParam == SB_BOTTOM) + { + int len = [[self string] length]; + [self scrollRangeToVisible:NSMakeRange(len, 0)]; + } + return 0; + + case EM_SETSEL: + { + int sl = [[self string] length]; + if (wParam == -1) lParam = wParam = 0; + else if (lParam == -1) lParam = sl; + + if (wParam>sl)wParam=sl; + if (lParam>sl)lParam=sl; + [self setSelectedRange:NSMakeRange(wParam, max(lParam-wParam,0))]; + } + return 0; + + case EM_GETSEL: + { + NSRange r = [self selectedRange]; + if (wParam) *(int*)wParam = r.location; + if (lParam) *(int*)lParam = r.location+r.length; + } + return 0; + + case WM_SETFONT: + { + HGDIOBJ__* obj = (HGDIOBJ__*)wParam; + if (obj && obj->type == TYPE_FONT) + { + if (obj->ct_FontRef) + { + [self setFont:(NSFont *)obj->ct_FontRef]; + } +#ifdef SWELL_ATSUI_TEXT_SUPPORT + else if (obj->atsui_font_style) + { + ATSUFontID fontid = kATSUInvalidFontID; + Fixed fsize = 0; + Boolean isbold = NO; + Boolean isital = NO; + Boolean isunder = NO; + if (ATSUGetAttribute(obj->atsui_font_style, kATSUFontTag, sizeof(ATSUFontID), &fontid, 0) == noErr && + ATSUGetAttribute(obj->atsui_font_style, kATSUSizeTag, sizeof(Fixed), &fsize, 0) == noErr && fsize && + ATSUGetAttribute(obj->atsui_font_style, kATSUQDBoldfaceTag, sizeof(Boolean), &isbold, 0) == noErr && + ATSUGetAttribute(obj->atsui_font_style, kATSUQDItalicTag, sizeof(Boolean), &isital, 0) == noErr && + ATSUGetAttribute(obj->atsui_font_style, kATSUQDUnderlineTag, sizeof(Boolean), &isunder, 0) == noErr) + { + char name[255]; + name[0]=0; + ByteCount namelen=0; + if (ATSUFindFontName(fontid, kFontFullName, (FontPlatformCode)kFontNoPlatform, kFontNoScriptCode, kFontNoLanguageCode, sizeof(name), name, &namelen, 0) == noErr && name[0] && namelen) + { + namelen /= 2; + int i; + for (i = 0; i < namelen; ++i) name[i] = name[2*i]; + name[namelen]=0; + + // todo bold/ital/underline + NSString* str = (NSString*)SWELL_CStringToCFString(name); + CGFloat sz = Fix2Long(fsize); + NSFont* font = [NSFont fontWithName:str size:sz]; + [str release]; + if (font) + { + [self setFont:font]; + [font release]; + } + } + } + } +#endif + } + } + return 0; + } + return 0; +} + +@end + + +@implementation SWELL_TextField +STANDARD_CONTROL_NEEDSDISPLAY_IMPL +@end + + + +HWND SWELL_MakeEditField(int idx, int x, int y, int w, int h, int flags) +{ + if ((flags&WS_VSCROLL) || (flags&WS_HSCROLL)) // || (flags & ES_READONLY)) + { + SWELL_TextView *obj=[[SWELL_TextView alloc] init]; + [obj setEditable:(flags & ES_READONLY)?NO:YES]; + if (m_transform.size.width < minwidfontadjust) + [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + [obj setTag:idx]; + [obj setDelegate:ACTIONTARGET]; + + [obj setHorizontallyResizable:NO]; + + if (flags & WS_VSCROLL) + { + NSRect fr=MakeCoords(x,y,w,h,true); + + [obj setVerticallyResizable:YES]; + NSScrollView *obj2=[[NSScrollView alloc] init]; + [obj2 setFrame:fr]; + if (flags&WS_VSCROLL) [obj2 setHasVerticalScroller:YES]; + if (flags&WS_HSCROLL) [obj2 setHasHorizontalScroller:YES]; + [obj2 setAutohidesScrollers:YES]; + [obj2 setDrawsBackground:NO]; + [obj2 setDocumentView:obj]; + [m_make_owner addSubview:obj2]; + if (m_doautoright) UpdateAutoCoords([obj2 frame]); + if (flags&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; + [obj2 release]; + + NSRect tr={0,}; + tr.size = [obj2 contentSize]; + [obj setFrame:tr]; + [obj release]; + + return (HWND)obj2; + } + else + { + [obj setFrame:MakeCoords(x,y,w,h,true)]; + [obj setVerticallyResizable:NO]; + if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if (m_doautoright) UpdateAutoCoords([obj frame]); + [obj release]; + return (HWND)obj; + } + } + + NSTextField *obj; + + if (flags & ES_PASSWORD) obj=[[NSSecureTextField alloc] init]; + else obj=[[SWELL_TextField alloc] init]; + [obj setEditable:(flags & ES_READONLY)?NO:YES]; + if (flags & ES_READONLY) [obj setSelectable:YES]; + if (m_transform.size.width < minwidfontadjust) + [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + + NSCell* cell = [obj cell]; + if (flags&ES_CENTER) [cell setAlignment:NSCenterTextAlignment]; + else if (flags&ES_RIGHT) [cell setAlignment:NSRightTextAlignment]; + if (abs(h) < 20) + { + [cell setWraps:NO]; + [cell setScrollable:YES]; + } + [obj setTag:idx]; + [obj setTarget:ACTIONTARGET]; + [obj setAction:@selector(onSwellCommand:)]; + [obj setDelegate:ACTIONTARGET]; + + [obj setFrame:MakeCoords(x,y,w,h,true)]; + if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if (m_doautoright) UpdateAutoCoords([obj frame]); + [obj release]; + + return (HWND)obj; +} + +HWND SWELL_MakeLabel( int align, const char *label, int idx, int x, int y, int w, int h, int flags) +{ + NSTextField *obj=[[SWELL_TextField alloc] init]; + [obj setEditable:NO]; + [obj setSelectable:NO]; + [obj setBordered:NO]; + [obj setBezeled:NO]; + [obj setDrawsBackground:NO]; + if (m_transform.size.width < minwidfontadjust) + [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + + if (flags & SS_NOTIFY) + { + [obj setTarget:ACTIONTARGET]; + [obj setAction:@selector(onSwellCommand:)]; + } + + NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(label); + [obj setStringValue:labelstr]; + [obj setAlignment:(align<0?NSLeftTextAlignment:align>0?NSRightTextAlignment:NSCenterTextAlignment)]; + + [[obj cell] setWraps:(h>12 ? YES : NO)]; + + [obj setTag:idx]; + [obj setFrame:MakeCoords(x,y,w,h,true)]; + if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if (m_sizetofits && strlen(label)>1)[obj sizeToFit]; + if (m_doautoright) UpdateAutoCoords([obj frame]); + [obj release]; + [labelstr release]; + return (HWND)obj; +} + + +HWND SWELL_MakeCheckBox(const char *name, int idx, int x, int y, int w, int h, int flags=0) +{ + return SWELL_MakeControl(name,idx,"Button",BS_AUTOCHECKBOX|flags,x,y,w,h,0); +} + +HWND SWELL_MakeListBox(int idx, int x, int y, int w, int h, int styles) +{ + HWND hw=SWELL_MakeControl("",idx,"SysListView32_LB",styles,x,y,w,h,0); +/* if (hw) + { + LVCOLUMN lvc={0,}; + RECT r; + GetClientRect(hw,&r); + lvc.cx=300;//yer.right-r.left; + lvc.pszText=""; + ListView_InsertColumn(hw,0,&lvc); + } + */ + return hw; +} + + +typedef struct ccprocrec +{ + SWELL_ControlCreatorProc proc; + int cnt; + struct ccprocrec *next; +} ccprocrec; + +static ccprocrec *m_ccprocs; + +void SWELL_RegisterCustomControlCreator(SWELL_ControlCreatorProc proc) +{ + if (!proc) return; + + ccprocrec *p=m_ccprocs; + while (p && p->next) + { + if (p->proc == proc) + { + p->cnt++; + return; + } + p=p->next; + } + ccprocrec *ent = (ccprocrec*)malloc(sizeof(ccprocrec)); + ent->proc=proc; + ent->cnt=1; + ent->next=0; + + if (p) p->next=ent; + else m_ccprocs=ent; +} + +void SWELL_UnregisterCustomControlCreator(SWELL_ControlCreatorProc proc) +{ + if (!proc) return; + + ccprocrec *lp=NULL; + ccprocrec *p=m_ccprocs; + while (p) + { + if (p->proc == proc) + { + if (--p->cnt <= 0) + { + if (lp) lp->next=p->next; + else m_ccprocs=p->next; + free(p); + } + return; + } + lp=p; + p=p->next; + } +} + + +HWND SWELL_MakeControl(const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h, int exstyle) +{ + if (m_ccprocs) + { + NSRect poo=MakeCoords(x,y,w,h,false); + ccprocrec *p=m_ccprocs; + while (p) + { + HWND h=p->proc((HWND)m_make_owner,cname,idx,classname,style,(int)(poo.origin.x+0.5),(int)(poo.origin.y+0.5),(int)(poo.size.width+0.5),(int)(poo.size.height+0.5)); + if (h) + { + if (exstyle) SetWindowLong(h,GWL_EXSTYLE,exstyle); + return h; + } + p=p->next; + } + } + if (!stricmp(classname,"SysTabControl32")) + { + SWELL_TabView *obj=[[SWELL_TabView alloc] init]; + if (1) // todo: only if on 10.4 maybe? + { + y-=1; + h+=6; + } + [obj setTag:idx]; + [obj setDelegate:(id)obj]; + [obj setAllowsTruncatedLabels:YES]; + [obj setNotificationWindow:ACTIONTARGET]; + [obj setHidden:NO]; + [obj setFrame:MakeCoords(x,y,w,h,false)]; + if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + [obj release]; + return (HWND)obj; + } + else if (!stricmp(classname, "SysListView32")||!stricmp(classname, "SysListView32_LB")) + { + SWELL_ListView *obj = [[SWELL_ListView alloc] init]; + [obj setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing]; + [obj setFocusRingType:NSFocusRingTypeNone]; + [obj setDataSource:(id)obj]; + obj->style=style; + + BOOL isLB=!stricmp(classname, "SysListView32_LB"); + [obj setSwellNotificationMode:isLB]; + + if (isLB) + { + [obj setHeaderView:nil]; + [obj setAllowsMultipleSelection:!!(style & LBS_EXTENDEDSEL)]; + } + else + { + if ((style & LVS_NOCOLUMNHEADER) || !(style & LVS_REPORT)) [obj setHeaderView:nil]; + [obj setAllowsMultipleSelection:!(style & LVS_SINGLESEL)]; + } + [obj setAllowsColumnReordering:NO]; + [obj setAllowsEmptySelection:YES]; + [obj setTag:idx]; + [obj setHidden:NO]; + id target=ACTIONTARGET; + [obj setDelegate:target]; + [obj setTarget:target]; + [obj setAction:@selector(onSwellCommand:)]; + if ([target respondsToSelector:@selector(swellOnControlDoubleClick:)]) + { + [obj setDoubleAction:@selector(swellOnControlDoubleClick:)]; + } + else + { + [obj setDoubleAction:@selector(onSwellCommand:)]; + } + NSScrollView *obj2=[[NSScrollView alloc] init]; + NSRect tr=MakeCoords(x,y,w,h,false); + [obj2 setFrame:tr]; + [obj2 setDocumentView:obj]; + [obj2 setHasVerticalScroller:YES]; + if (!isLB) [obj2 setHasHorizontalScroller:YES]; + [obj2 setAutohidesScrollers:YES]; + [obj2 setDrawsBackground:NO]; + [obj release]; + if (style&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; + [m_make_owner addSubview:obj2]; + [obj2 release]; + + if (isLB || !(style & LVS_REPORT)) + { + LVCOLUMN lvc={0,}; + lvc.cx=(int)ceil(max(tr.size.width,300.0)); + lvc.pszText=(char*)""; + ListView_InsertColumn((HWND)obj,0,&lvc); + if (isLB && (style & LBS_OWNERDRAWFIXED)) + { + NSArray *ar=[obj tableColumns]; + NSTableColumn *c; + if (ar && [ar count] && (c=[ar objectAtIndex:0])) + { + SWELL_ODListViewCell *t=[[SWELL_ODListViewCell alloc] init]; + [c setDataCell:t]; + [t setOwnerControl:obj]; + [t release]; + } + } + } + + return (HWND)obj; + } + else if (!stricmp(classname, "SysTreeView32")) + { + SWELL_TreeView *obj = [[SWELL_TreeView alloc] init]; + [obj setFocusRingType:NSFocusRingTypeNone]; + [obj setDataSource:(id)obj]; + obj->style=style; + id target=ACTIONTARGET; + [obj setHeaderView:nil]; + [obj setDelegate:target]; + [obj setAllowsColumnReordering:NO]; + [obj setAllowsMultipleSelection:NO]; + [obj setAllowsEmptySelection:YES]; + [obj setTag:idx]; + [obj setHidden:NO]; + [obj setTarget:target]; + [obj setAction:@selector(onSwellCommand:)]; + if ([target respondsToSelector:@selector(swellOnControlDoubleClick:)]) + [obj setDoubleAction:@selector(swellOnControlDoubleClick:)]; + else + [obj setDoubleAction:@selector(onSwellCommand:)]; + NSScrollView *obj2=[[NSScrollView alloc] init]; + NSRect tr=MakeCoords(x,y,w,h,false); + [obj2 setFrame:tr]; + [obj2 setDocumentView:obj]; + [obj2 setHasVerticalScroller:YES]; + [obj2 setAutohidesScrollers:YES]; + [obj2 setDrawsBackground:NO]; + [obj release]; + if (style&SWELL_NOT_WS_VISIBLE) [obj2 setHidden:YES]; + [m_make_owner addSubview:obj2]; + [obj2 release]; + + { + NSTableColumn *col=[[NSTableColumn alloc] init]; + SWELL_ListViewCell *cell = [[SWELL_ListViewCell alloc] initTextCell:@""]; + [col setDataCell:cell]; + [cell release]; + + [col setWidth:(int)ceil(max(tr.size.width,300.0))]; + [col setEditable:NO]; + [[col dataCell] setWraps:NO]; + [obj addTableColumn:col]; + [obj setOutlineTableColumn:col]; + + [col release]; + } +/// [obj setIndentationPerLevel:10.0]; + + return (HWND)obj; + } + else if (!stricmp(classname, "msctls_progress32")) + { + SWELL_ProgressView *obj=[[SWELL_ProgressView alloc] init]; + [obj setStyle:NSProgressIndicatorBarStyle]; + [obj setIndeterminate:NO]; + [obj setTag:idx]; + [obj setFrame:MakeCoords(x,y,w,h,false)]; + if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + [obj release]; + return (HWND)obj; + } + else if (!stricmp(classname,"Edit")) + { + return SWELL_MakeEditField(idx,x,y,w,h,style); + } + else if (!stricmp(classname, "static")) + { + NSTextField *obj=[[SWELL_TextField alloc] init]; + [obj setEditable:NO]; + [obj setSelectable:NO]; + [obj setBordered:NO]; + [obj setBezeled:NO]; + [obj setDrawsBackground:NO]; + if (m_transform.size.width < minwidfontadjust) + [obj setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + + if (cname && *cname) + { + NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(cname); + [obj setStringValue:labelstr]; + [labelstr release]; + } + + if ((style&SS_TYPEMASK) == SS_LEFTNOWORDWRAP) [[obj cell] setWraps:NO]; + if ((style&SS_TYPEMASK) == SS_CENTER) [[obj cell] setAlignment:NSCenterTextAlignment]; + [obj setTag:idx]; + [obj setFrame:MakeCoords(x,y,w,h,true)]; + if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if ((style & SS_TYPEMASK) == SS_BLACKRECT) + { + [obj setHidden:YES]; + } + [obj release]; + return (HWND)obj; + } + else if (!stricmp(classname,"Button")) + { + if (style & BS_GROUPBOX) + { + return SWELL_MakeGroupBox(cname, idx, x, y, w, h, style &~BS_GROUPBOX); + } + if (style & BS_DEFPUSHBUTTON) + { + return SWELL_MakeButton(1, cname, idx, x,y,w,h,style &~BS_DEFPUSHBUTTON); + } + if (style & BS_PUSHBUTTON) + { + return SWELL_MakeButton(0, cname, idx, x,y,w,h,style &~BS_PUSHBUTTON); + } + SWELL_Button *button=[[SWELL_Button alloc] init]; + [button setTag:idx]; + NSRect fr=MakeCoords(x,y,w,h,true); + if ((style & 0xf) == BS_AUTO3STATE) + { + [button setButtonType:NSSwitchButton]; + [button setAllowsMixedState:YES]; + } + else if ((style & 0xf) == BS_AUTOCHECKBOX) + { + [button setButtonType:NSSwitchButton]; + [button setAllowsMixedState:NO]; + } + else if ((style & 0xf) == BS_AUTORADIOBUTTON) + { + [button setButtonType:NSRadioButton]; + [button swellSetRadioFlags:(style & WS_GROUP)?3:1]; + } + else if ((style & 0xf) == BS_OWNERDRAW) + { + SWELL_ODButtonCell *cell = [[SWELL_ODButtonCell alloc] init]; + [button setCell:cell]; + [cell release]; + //NSButtonCell + } + else // normal button + { +// fr.size.width+=8; + } + + if (m_transform.size.width < minwidfontadjust) + [button setFont:[NSFont systemFontOfSize:TRANSFORMFONTSIZE]]; + [button setFrame:fr]; + NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(cname); + [button setTitle:labelstr]; + [button setTarget:ACTIONTARGET]; + [button setAction:@selector(onSwellCommand:)]; + if (style&BS_LEFTTEXT) [button setImagePosition:NSImageRight]; + if (style&SWELL_NOT_WS_VISIBLE) [button setHidden:YES]; + [m_make_owner addSubview:button]; + if (m_sizetofits && (style & 0xf) != BS_OWNERDRAW) [button sizeToFit]; + if (m_doautoright) UpdateAutoCoords([button frame]); + [labelstr release]; + [button release]; + return (HWND)button; + } + else if (!stricmp(classname,"REAPERhfader")||!stricmp(classname,"msctls_trackbar32")) + { + NSSlider *obj=[[NSSlider alloc] init]; + [obj setTag:idx]; + [obj setMinValue:0.0]; + [obj setMaxValue:1000.0]; + [obj setFrame:MakeCoords(x,y,w,h,false)]; + if (!stricmp(classname, "msctls_trackbar32")) + { + [[obj cell] setControlSize:NSMiniControlSize]; + } + [obj setTarget:ACTIONTARGET]; + [obj setAction:@selector(onSwellCommand:)]; + if (style&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + [obj release]; + return (HWND)obj; + } + return 0; +} + +HWND SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags) +{ + if ((flags & 0x3) == CBS_DROPDOWNLIST) + { + SWELL_PopUpButton *obj=[[SWELL_PopUpButton alloc] init]; + [obj setTag:idx]; + [obj setFont:[NSFont systemFontOfSize:10.0f]]; + NSRect rc=MakeCoords(x,y,w,18,true,true); + + [obj setSwellStyle:flags]; + [obj setFrame:rc]; + [obj setAutoenablesItems:NO]; + [obj setTarget:ACTIONTARGET]; + [obj setAction:@selector(onSwellCommand:)]; + + if (g_swell_want_nice_style==1) + { + [obj setBezelStyle:NSShadowlessSquareBezelStyle ]; + [[obj cell] setArrowPosition:NSPopUpArrowAtBottom]; + } + if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if (m_doautoright) UpdateAutoCoords([obj frame]); + [obj release]; + return (HWND)obj; + } + else + { + SWELL_ComboBox *obj=[[SWELL_ComboBox alloc] init]; + [obj setFocusRingType:NSFocusRingTypeNone]; + [obj setFont:[NSFont systemFontOfSize:10.0f]]; + [obj setEditable:(flags & 0x3) == CBS_DROPDOWNLIST?NO:YES]; + [obj setSwellStyle:flags]; + [obj setTag:idx]; + [obj setFrame:MakeCoords(x,y-1,w,22,true,true)]; + [obj setTarget:ACTIONTARGET]; + [obj setAction:@selector(onSwellCommand:)]; + [obj setDelegate:ACTIONTARGET]; + if (flags&SWELL_NOT_WS_VISIBLE) [obj setHidden:YES]; + [m_make_owner addSubview:obj]; + if (m_doautoright) UpdateAutoCoords([obj frame]); + [obj release]; + return (HWND)obj; + } +} + +@implementation SWELL_BoxView + +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(NSInteger) tag +{ + return m_tag; +} +-(void) setTag:(NSInteger)tag +{ + m_tag=tag; +} +@end + +HWND SWELL_MakeGroupBox(const char *name, int idx, int x, int y, int w, int h, int style) +{ + SWELL_BoxView *obj=[[SWELL_BoxView alloc] init]; + + // this just doesn't work, you can't color the border unless it's NSBoxCustom, + // and I can't get it to show the title text if it's NSBoxCustom + //[obj setBoxType:(NSBoxType)4]; // NSBoxCustom, so we can color the border + //[obj setTitlePosition:(NSTitlePosition)2]; // NSAtTop, default but NSBoxCustom unsets it + +// [obj setTag:idx]; + if (1) // todo: only if on 10.4 maybe? + { + y-=1; + h+=3; + } + NSString *labelstr=(NSString *)SWELL_CStringToCFString_FilterPrefix(name); + [obj setTitle:labelstr]; + [obj setTag:idx]; + [labelstr release]; + if (style & BS_CENTER) + { + [[obj titleCell] setAlignment:NSCenterTextAlignment]; + } + [obj setFrame:MakeCoords(x,y,w,h,false)]; + [m_make_owner addSubview:obj positioned:NSWindowBelow relativeTo:nil]; + [obj release]; + return (HWND)obj; +} + + +int TabCtrl_GetItemCount(HWND hwnd) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; + SWELL_TabView *tv=(SWELL_TabView*)hwnd; + return [tv numberOfTabViewItems]; +} + +BOOL TabCtrl_AdjustRect(HWND hwnd, BOOL fLarger, RECT *r) +{ + if (!r || !hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return FALSE; + + int sign=fLarger?-1:1; + r->left+=sign*7; // todo: correct this? + r->right-=sign*7; + r->top+=sign*26; + r->bottom-=sign*3; + return TRUE; +} + + +BOOL TabCtrl_DeleteItem(HWND hwnd, int idx) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; + SWELL_TabView *tv=(SWELL_TabView*)hwnd; + if (idx<0 || idx>= [tv numberOfTabViewItems]) return 0; + [tv removeTabViewItem:[tv tabViewItemAtIndex:idx]]; + return TRUE; +} + +int TabCtrl_InsertItem(HWND hwnd, int idx, TCITEM *item) +{ + if (!item || !hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return -1; + if (!(item->mask & TCIF_TEXT) || !item->pszText) return -1; + SWELL_TabView *tv=(SWELL_TabView*)hwnd; + if (idx<0) idx=0; + else if (idx>[tv numberOfTabViewItems]) idx=[tv numberOfTabViewItems]; + + NSTabViewItem *tabitem=[[NSTabViewItem alloc] init]; + NSString *str=(NSString *)SWELL_CStringToCFString(item->pszText); + [tabitem setLabel:str]; + [str release]; + id turd=[tv getNotificationWindow]; + [tv setNotificationWindow:nil]; + [tv insertTabViewItem:tabitem atIndex:idx]; + [tv setNotificationWindow:turd]; + [tabitem release]; + return idx; +} + +int TabCtrl_SetCurSel(HWND hwnd, int idx) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return -1; + SWELL_TabView *tv=(SWELL_TabView*)hwnd; + int ret=TabCtrl_GetCurSel(hwnd); + if (idx>=0 && idx < [tv numberOfTabViewItems]) + { + [tv selectTabViewItemAtIndex:idx]; + } + return ret; +} + +int TabCtrl_GetCurSel(HWND hwnd) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TabView class]]) return 0; + SWELL_TabView *tv=(SWELL_TabView*)hwnd; + NSTabViewItem *item=[tv selectedTabViewItem]; + if (!item) return 0; + return [tv indexOfTabViewItem:item]; +} + +void ListView_SetExtendedListViewStyleEx(HWND h, int mask, int style) +{ + if (!h) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *tv=(SWELL_ListView*)h; + + if (mask&LVS_EX_GRIDLINES) + { + int s=0; + if (style&LVS_EX_GRIDLINES) + { + s=NSTableViewSolidVerticalGridLineMask|NSTableViewSolidHorizontalGridLineMask; + } + [tv setGridStyleMask:s]; + } + + if (mask&LVS_EX_HEADERDRAGDROP) + { + [tv setAllowsColumnReordering:!!(style&LVS_EX_HEADERDRAGDROP)]; + } + + + // todo LVS_EX_FULLROWSELECT (enabled by default on OSX) +} + +void SWELL_SetListViewFastClickMask(HWND hList, int mask) +{ + if (!hList || ![(id)hList isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *lv = (SWELL_ListView *)hList; + lv->m_fastClickMask=mask; + +} + + +void ListView_SetImageList(HWND h, HIMAGELIST imagelist, int which) +{ + if (!h) return; + + SWELL_ListView *v=(SWELL_ListView *)h; + + v->m_status_imagelist_type=which; + v->m_status_imagelist=(WDL_PtrList *)imagelist; + if (v->m_cols && v->m_cols->GetSize()>0) + { + NSTableColumn *col=(NSTableColumn*)v->m_cols->Get(0); + if (![col isKindOfClass:[SWELL_StatusCell class]]) + { + SWELL_StatusCell *cell=[[SWELL_StatusCell alloc] initNewCell]; + [cell setWraps:NO]; + [col setDataCell:cell]; + [cell release]; + } + } +} + +int ListView_GetColumnWidth(HWND h, int pos) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + SWELL_ListView *v=(SWELL_ListView *)h; + if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return 0; + + NSTableColumn *col=v->m_cols->Get(pos); + if (!col) return 0; + + if ([col respondsToSelector:@selector(isHidden)] && [(SWELL_TableColumnExtensions*)col isHidden]) return 0; + return (int) floor(0.5+[col width]); +} + +void ListView_InsertColumn(HWND h, int pos, const LVCOLUMN *lvc) +{ + if (!h || !lvc) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_BEGIN_TRY + + SWELL_ListView *v=(SWELL_ListView *)h; + NSTableColumn *col=[[NSTableColumn alloc] init]; + // note, not looking at lvc->mask at all + + [col setEditable:NO]; + // [col setResizingMask:2]; // user resizable, this seems to be the default + + if (!lvc->cx && [col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; + else [col setWidth:lvc->cx]; + + if (lvc->fmt == LVCFMT_CENTER) [[col headerCell] setAlignment:NSCenterTextAlignment]; + else if (lvc->fmt == LVCFMT_RIGHT) [[col headerCell] setAlignment:NSRightTextAlignment]; + + if (!v->m_lbMode && !(v->style & LVS_NOCOLUMNHEADER)) + { + NSString *lbl=(NSString *)SWELL_CStringToCFString(lvc->pszText); + [[col headerCell] setStringValue:lbl]; + [lbl release]; + } + + if (!pos && v->m_status_imagelist) + { + SWELL_StatusCell *cell=[[SWELL_StatusCell alloc] initNewCell]; + [cell setWraps:NO]; + [col setDataCell:cell]; + [cell release]; + } + else + { + SWELL_ListViewCell *cell = [[SWELL_ListViewCell alloc] initTextCell:@""]; + [col setDataCell:cell]; + [cell setWraps:NO]; + + if (lvc->fmt == LVCFMT_CENTER) [cell setAlignment:NSCenterTextAlignment]; + else if (lvc->fmt == LVCFMT_RIGHT) [cell setAlignment:NSRightTextAlignment]; + [cell release]; + } + + [v addTableColumn:col]; + v->m_cols->Add(col); + [col release]; + SWELL_END_TRY(;) +} + +void ListView_SetColumn(HWND h, int pos, const LVCOLUMN *lvc) +{ + if (!h || !lvc || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *v=(SWELL_ListView *)h; + if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return; + + NSTableColumn *col=v->m_cols->Get(pos); + if (!col) return; + + if (lvc->mask&LVCF_FMT) + { + if (lvc->fmt == LVCFMT_LEFT) [[col headerCell] setAlignment:NSLeftTextAlignment]; + else if (lvc->fmt == LVCFMT_CENTER) [[col headerCell] setAlignment:NSCenterTextAlignment]; + else if (lvc->fmt == LVCFMT_RIGHT) [[col headerCell] setAlignment:NSRightTextAlignment]; + } + if (lvc->mask&LVCF_WIDTH) + { + if (!lvc->cx) + { + if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; + } + else + { + if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:NO]; + [col setWidth:lvc->cx]; + } + } + if (lvc->mask&LVCF_TEXT) + { + if (!v->m_lbMode && !(v->style&LVS_NOCOLUMNHEADER)) + { + NSString *lbl=(NSString *)SWELL_CStringToCFString(lvc->pszText); + [[col headerCell] setStringValue:lbl]; + [lbl release]; + } + } +} + +bool ListView_DeleteColumn(HWND h, int pos) +{ + if (!h) return false; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; + SWELL_ListView *v=(SWELL_ListView *)h; + if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return false; + [v removeTableColumn:v->m_cols->Get(pos)]; + v->m_cols->Delete(pos); + return true; +} + +void ListView_GetItemText(HWND hwnd, int item, int subitem, char *text, int textmax) +{ + LVITEM it={LVIF_TEXT,item,subitem,0,0,text,textmax,}; + ListView_GetItem(hwnd,&it); +} + +int ListView_InsertItem(HWND h, const LVITEM *item) +{ + if (!h || !item || item->iSubItem) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) return -1; + if (!tv->m_items) return -1; + + int a=item->iItem; + if (a<0)a=0; + else if (a > tv->m_items->GetSize()) a=tv->m_items->GetSize(); + + if (!tv->m_lbMode && (item->mask & LVIF_TEXT)) + { + if (tv->style & LVS_SORTASCENDING) + { + a=ptrlist_bsearch_mod((char *)item->pszText,tv->m_items,_listviewrowSearchFunc,NULL); + } + else if (tv->style & LVS_SORTDESCENDING) + { + a=ptrlist_bsearch_mod((char *)item->pszText,tv->m_items,_listviewrowSearchFunc2,NULL); + } + } + + SWELL_ListView_Row *nr=new SWELL_ListView_Row; + nr->m_vals.Add(strdup((item->mask & LVIF_TEXT) ? item->pszText : "")); + if (item->mask & LVIF_PARAM) nr->m_param = item->lParam; + tv->m_items->Insert(a,nr); + + + + if ((item->mask&LVIF_STATE) && (item->stateMask & (0xff<<16))) + { + nr->m_imageidx=(item->state>>16)&0xff; + } + + [tv reloadData]; + + if (a < tv->m_items->GetSize()-1) + { + NSIndexSet *sel=[tv selectedRowIndexes]; + if (sel && [sel count]) + { + NSMutableIndexSet *ms = [[NSMutableIndexSet alloc] initWithIndexSet:sel]; + [ms shiftIndexesStartingAtIndex:a by:1]; + [tv selectRowIndexes:ms byExtendingSelection:NO]; + [ms release]; + } + } + + if (item->mask & LVIF_STATE) + { + if (item->stateMask & LVIS_SELECTED) + { + if (item->state&LVIS_SELECTED) + { + bool isSingle = tv->m_lbMode ? !(tv->style & LBS_EXTENDEDSEL) : !!(tv->style&LVS_SINGLESEL); + [tv selectRowIndexes:[NSIndexSet indexSetWithIndex:a] byExtendingSelection:isSingle?NO:YES]; + } + } + } + + return a; +} + +void ListView_SetItemText(HWND h, int ipos, int cpos, const char *txt) +{ + if (!h || cpos < 0 || cpos >= 32) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) return; + if (!tv->m_items) return; + + SWELL_ListView_Row *p=tv->m_items->Get(ipos); + if (!p) return; + int x; + for (x = p->m_vals.GetSize(); x < cpos; x ++) + { + p->m_vals.Add(strdup("")); + } + if (cpos < p->m_vals.GetSize()) + { + free(p->m_vals.Get(cpos)); + p->m_vals.Set(cpos,strdup(txt)); + } + else p->m_vals.Add(strdup(txt)); + + [tv reloadData]; +} + +int ListView_GetNextItem(HWND h, int istart, int flags) +{ + if (flags==LVNI_FOCUSED||flags==LVNI_SELECTED) + { + if (!h) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView *tv=(SWELL_ListView*)h; + + if (flags==LVNI_SELECTED) + { + //int orig_start=istart; + if (istart++<0)istart=0; + int n = [tv numberOfRows]; + while (istart < n) + { + if ([tv isRowSelected:istart]) return istart; + istart++; + } + return -1; + } + + return [tv selectedRow]; + } + return -1; +} + +bool ListView_SetItem(HWND h, LVITEM *item) +{ + if (!item) return false; + if (!h) return false; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) + { + if (!tv->m_items) return false; + SWELL_ListView_Row *row=tv->m_items->Get(item->iItem); + if (!row) return false; + + if (item->mask & LVIF_PARAM) + { + row->m_param=item->lParam; + } + if ((item->mask & LVIF_TEXT) && item->pszText) + { + ListView_SetItemText(h,item->iItem,item->iSubItem,item->pszText); + } + if ((item->mask&LVIF_IMAGE) && item->iImage >= 0) + { + row->m_imageidx=item->iImage+1; + ListView_RedrawItems(h, item->iItem, item->iItem); + } + } + if ((item->mask & LVIF_STATE) && item->stateMask) + { + ListView_SetItemState(h,item->iItem,item->state,item->stateMask); + } + + return true; +} + +bool ListView_GetItem(HWND h, LVITEM *item) +{ + if (!item) return false; + if ((item->mask&LVIF_TEXT)&&item->pszText && item->cchTextMax > 0) item->pszText[0]=0; + item->state=0; + if (!h) return false; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; + + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) + { + if (!tv->m_items) return false; + + SWELL_ListView_Row *row=tv->m_items->Get(item->iItem); + if (!row) return false; + + if (item->mask & LVIF_PARAM) item->lParam=row->m_param; + if (item->mask & LVIF_TEXT) if (item->pszText && item->cchTextMax>0) + { + char *p=row->m_vals.Get(item->iSubItem); + lstrcpyn(item->pszText,p?p:"",item->cchTextMax); + } + if (item->mask & LVIF_STATE) + { + if (item->stateMask & (0xff<<16)) + { + item->state|=row->m_imageidx<<16; + } + } + } + else + { + if (item->iItem <0 || item->iItem >= tv->ownermode_cnt) return false; + } + if (item->mask & LVIF_STATE) + { + if ((item->stateMask&LVIS_SELECTED) && [tv isRowSelected:item->iItem]) item->state|=LVIS_SELECTED; + if ((item->stateMask&LVIS_FOCUSED) && [tv selectedRow] == item->iItem) item->state|=LVIS_FOCUSED; + } + + return true; +} +int ListView_GetItemState(HWND h, int ipos, int mask) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + SWELL_ListView *tv=(SWELL_ListView*)h; + int flag=0; + if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) + { + if (!tv->m_items) return 0; + SWELL_ListView_Row *row=tv->m_items->Get(ipos); + if (!row) return 0; + if (mask & (0xff<<16)) + { + flag|=row->m_imageidx<<16; + } + } + else + { + if (ipos<0 || ipos >= tv->ownermode_cnt) return 0; + } + + if ((mask&LVIS_SELECTED) && [tv isRowSelected:ipos]) flag|=LVIS_SELECTED; + if ((mask&LVIS_FOCUSED) && [tv selectedRow]==ipos) flag|=LVIS_FOCUSED; + return flag; +} + +bool ListView_SetItemState(HWND h, int ipos, int state, int statemask) +{ + int doref=0; + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return false; + SWELL_ListView *tv=(SWELL_ListView*)h; + static int _is_doing_all; + + if (ipos == -1) + { + int x; + int n=ListView_GetItemCount(h); + _is_doing_all++; + for (x = 0; x < n; x ++) + ListView_SetItemState(h,x,state,statemask); + _is_doing_all--; + ListView_RedrawItems(h,0,n-1); + return true; + } + + if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) + { + if (!tv->m_items) return false; + SWELL_ListView_Row *row=tv->m_items->Get(ipos); + if (!row) return false; + if (statemask & (0xff<<16)) + { + if (row->m_imageidx!=((state>>16)&0xff)) + { + row->m_imageidx=(state>>16)&0xff; + doref=1; + } + } + } + else + { + if (ipos<0 || ipos >= tv->ownermode_cnt) return 0; + } + bool didsel=false; + if (statemask & LVIS_SELECTED) + { + if (state & LVIS_SELECTED) + { + bool isSingle = tv->m_lbMode ? !(tv->style & LBS_EXTENDEDSEL) : !!(tv->style&LVS_SINGLESEL); + if (![tv isRowSelected:ipos]) { didsel=true; [tv selectRowIndexes:[NSIndexSet indexSetWithIndex:ipos] byExtendingSelection:isSingle?NO:YES]; } + } + else + { + if ([tv isRowSelected:ipos]) { didsel=true; [tv deselectRow:ipos]; } + } + } + if (statemask & LVIS_FOCUSED) + { + if (state&LVIS_FOCUSED) + { + } + else + { + + } + } + + if (!_is_doing_all) + { + if (didsel) + { + static int __rent; + if (!__rent) + { + __rent=1; + NMLISTVIEW nm={{(HWND)h,[tv tag],LVN_ITEMCHANGED},ipos,0,state,}; + SendMessage(GetParent(h),WM_NOTIFY,[tv tag],(LPARAM)&nm); + __rent=0; + } + } + if (doref) + ListView_RedrawItems(h,ipos,ipos); + } + return true; +} + +void ListView_RedrawItems(HWND h, int startitem, int enditem) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *tv=(SWELL_ListView*)h; + if (!tv->m_items) return; + [tv reloadData]; +} + +void ListView_DeleteItem(HWND h, int ipos) +{ + if (!h) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (!tv->m_items) return; + + if (ipos >=0 && ipos < tv->m_items->GetSize()) + { + if (ipos != tv->m_items->GetSize()-1) + { + NSIndexSet *sel=[tv selectedRowIndexes]; + if (sel && [sel count]) + { + NSMutableIndexSet *ms = [[NSMutableIndexSet alloc] initWithIndexSet:sel]; + [ms shiftIndexesStartingAtIndex:ipos+1 by:-1]; + [tv selectRowIndexes:ms byExtendingSelection:NO]; + [ms release]; + } + } + tv->m_items->Delete(ipos,true); + + [tv reloadData]; + + } +} + +void ListView_DeleteAllItems(HWND h) +{ + if (!h) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *tv=(SWELL_ListView*)h; + tv->ownermode_cnt=0; + if (tv->m_items) tv->m_items->Empty(true); + + [tv reloadData]; +} + +int ListView_GetSelectedCount(HWND h) +{ + if (!h) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView *tv=(SWELL_ListView*)h; + return [tv numberOfSelectedRows]; +} + +int ListView_GetItemCount(HWND h) +{ + if (!h) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (tv->m_lbMode || !(tv->style & LVS_OWNERDATA)) + { + if (!tv->m_items) return 0; + + return tv->m_items->GetSize(); + } + return tv->ownermode_cnt; +} + +int ListView_GetSelectionMark(HWND h) +{ + if (!h) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView *tv=(SWELL_ListView*)h; + return [tv selectedRow]; +} + +int SWELL_GetListViewHeaderHeight(HWND h) +{ + if (!h) return 0; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + + SWELL_ListView* tv=(SWELL_ListView*)h; + NSTableHeaderView* hv=[tv headerView]; + NSRect r=[hv bounds]; + return (int)(r.size.height+0.5); +} + +void ListView_SetColumnWidth(HWND h, int pos, int wid) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *v=(SWELL_ListView *)h; + if (!v->m_cols || pos < 0 || pos >= v->m_cols->GetSize()) return; + + NSTableColumn *col=v->m_cols->Get(pos); + if (!col) return; + + if (!wid) + { + if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:YES]; + } + else + { + if ([col respondsToSelector:@selector(setHidden:)]) [(SWELL_TableColumnExtensions*)col setHidden:NO]; + [col setWidth:wid]; + } +} + +BOOL ListView_GetColumnOrderArray(HWND h, int cnt, int* arr) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return FALSE; + SWELL_ListView* lv=(SWELL_ListView*)h; + if (!lv->m_cols || lv->m_cols->GetSize() != cnt) return FALSE; + + int i; + for (i=0; i < cnt; ++i) + { + arr[i]=[lv getColumnPos:i]; + } + + return TRUE; +} + +BOOL ListView_SetColumnOrderArray(HWND h, int cnt, int* arr) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return FALSE; + SWELL_ListView* lv=(SWELL_ListView*)h; + if (!lv->m_cols || lv->m_cols->GetSize() != cnt) return FALSE; + + int i; + for (i=0; i < cnt; ++i) + { + int pos=[lv getColumnPos:i]; + int dest=arr[i]; + [lv moveColumn:pos toColumn:dest]; + } + + return TRUE; +} + +HWND ListView_GetHeader(HWND h) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + return h; +} + +int Header_GetItemCount(HWND h) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]]) return 0; + SWELL_ListView* lv=(SWELL_ListView*)h; + if (lv->m_cols) return lv->m_cols->GetSize(); + return 0; +} + +BOOL Header_GetItem(HWND h, int col, HDITEM* hi) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]] || !hi) return FALSE; + SWELL_ListView* lv=(SWELL_ListView*)h; + if (!lv->m_cols || col < 0 || col >= lv->m_cols->GetSize()) return FALSE; + NSTableColumn* hcol=lv->m_cols->Get(col); + if (!hcol) return FALSE; + + if (hi->mask&HDI_FORMAT) + { + hi->fmt=0; + NSImage* img=[lv indicatorImageInTableColumn:hcol]; + if (img) + { + NSString* imgname=[img name]; + if (imgname) + { + if ([imgname isEqualToString:@"NSAscendingSortIndicator"]) hi->fmt |= HDF_SORTUP; + else if ([imgname isEqualToString:@"NSDescendingSortIndicator"]) hi->fmt |= HDF_SORTDOWN; + } + } + } + // etc todo + + return TRUE; +} + +BOOL Header_SetItem(HWND h, int col, HDITEM* hi) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_ListView class]] || !hi) return FALSE; + SWELL_ListView* lv=(SWELL_ListView*)h; + if (!lv->m_cols || col < 0 || col >= lv->m_cols->GetSize()) return FALSE; + NSTableColumn* hcol=lv->m_cols->Get(col); + if (!hcol) return FALSE; + + if (hi->mask&HDI_FORMAT) + { + NSImage* img=0; + if (hi->fmt&HDF_SORTUP) img=[NSImage imageNamed:@"NSAscendingSortIndicator"]; + else if (hi->fmt&HDF_SORTDOWN) img=[NSImage imageNamed:@"NSDescendingSortIndicator"]; + [lv setIndicatorImage:img inTableColumn:hcol]; + } + // etc todo + + return TRUE; +} + +int ListView_HitTest(HWND h, LVHITTESTINFO *pinf) +{ + if (!h || !pinf) return -1; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return -1; + + SWELL_ListView *tv=(SWELL_ListView*)h; + // return index + pinf->flags=0; + pinf->iItem=-1; + + // rowAtPoint will return a row even if it is scrolled out of the clip view + NSScrollView* sv=(NSScrollView *)NavigateUpScrollClipViews(tv); + if (![sv isKindOfClass:[NSScrollView class]] && ![sv isKindOfClass:[NSClipView class]]) sv=NULL; + + NSRect r=[sv documentVisibleRect]; + int x=pinf->pt.x-r.origin.x; + int y=pinf->pt.y-r.origin.y; + + if (x < 0) pinf->flags |= LVHT_TOLEFT; + if (x >= r.size.width) pinf->flags |= LVHT_TORIGHT; + if (y < 0) pinf->flags |= LVHT_ABOVE; + if (y >= r.size.height) pinf->flags |= LVHT_BELOW; + + if (!pinf->flags) + { + NSPoint pt = { pinf->pt.x, pinf->pt.y }; + pinf->iItem=[(NSTableView *)h rowAtPoint:pt]; + if (pinf->iItem >= 0) + { + if (tv->m_status_imagelist && pt.x <= [tv rowHeight]) + { + pinf->flags=LVHT_ONITEMSTATEICON; + } + else + { + pinf->flags=LVHT_ONITEMLABEL; + } + } + else + { + pinf->flags=LVHT_NOWHERE; + } + } + + return pinf->iItem; +} + +int ListView_SubItemHitTest(HWND h, LVHITTESTINFO *pinf) +{ + int row = ListView_HitTest(h, pinf); + + NSPoint pt={pinf->pt.x,pinf->pt.y}; + if (row < 0 && pt.y < 0) + { // Fake the point in the client area of the listview to get the column # (like win32) + pt.y = 0; + } + pinf->iSubItem=[(NSTableView *)h columnAtPoint:pt]; + return row; +} + +void ListView_SetItemCount(HWND h, int cnt) +{ + if (!h) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *tv=(SWELL_ListView*)h; + if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) + { + tv->ownermode_cnt=cnt; + } +} + +void ListView_EnsureVisible(HWND h, int i, BOOL pok) +{ + if (!h) return; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *tv=(SWELL_ListView*)h; + + if (i<0)i=0; + if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) + { + if (i >=tv->ownermode_cnt-1) i=tv->ownermode_cnt-1; + } + else + { + if (tv->m_items && i >= tv->m_items->GetSize()) i=tv->m_items->GetSize()-1; + } + if (i>=0) + { + [tv scrollRowToVisible:i]; + } +} + +static bool ListViewGetRectImpl(HWND h, int item, int subitem, RECT* r) // subitem<0 for full item rect +{ + if (!h) return false; + if (![(id)h isKindOfClass:[SWELL_ListView class]]) return false; + if (item < 0 || item > ListView_GetItemCount(h)) return false; + SWELL_ListView *tv=(SWELL_ListView*)h; + + if (subitem >= 0 && (!tv->m_cols || subitem >= tv->m_cols->GetSize())) return false; + subitem=[tv getColumnPos:subitem]; + + NSRect ar; + if (subitem < 0) ar = [tv rectOfRow:item]; + else ar=[tv frameOfCellAtColumn:subitem row:item]; + NSSize sp=[tv intercellSpacing]; + + r->left=(int)ar.origin.x; + r->top=(int)ar.origin.y; + r->right=(int)(ar.origin.x+ar.size.width+sp.width); + r->bottom=(int)(ar.origin.y+ar.size.height+sp.height); + + return true; +} + +bool ListView_GetSubItemRect(HWND h, int item, int subitem, int code, RECT *r) +{ + return ListViewGetRectImpl(h, item, subitem, r); +} + +bool ListView_GetItemRect(HWND h, int item, RECT *r, int code) +{ + return ListViewGetRectImpl(h, item, -1, r); +} + +int ListView_GetTopIndex(HWND h) +{ + NSTableView* tv = (NSTableView*)h; + if (!tv) return -1; + NSScrollView* sv = [tv enclosingScrollView]; + if (!sv) return -1; + + NSRect tvr = [sv documentVisibleRect]; + NSPoint pt = { 0, tvr.origin.y }; + return [tv rowAtPoint:pt]; +} + +int ListView_GetCountPerPage(HWND h) +{ + NSTableView* tv = (NSTableView*)h; + if (!tv) return 0; + NSScrollView* sv = [tv enclosingScrollView]; + if (!sv) return 0; + + NSRect tvr = [sv documentVisibleRect]; + int rowh = [tv rowHeight]; + return tvr.size.height/rowh; +} + +bool ListView_Scroll(HWND h, int xscroll, int yscroll) +{ + NSTableView* tv = (NSTableView*)h; + NSScrollView* sv = [tv enclosingScrollView]; + if (!sv) return false; + + NSRect tvr = [sv documentVisibleRect]; + NSPoint pt = { tvr.origin.x, tvr.origin.y }; + if (xscroll > 0) pt.x += tvr.size.width-1; + if (yscroll > 0) pt.y += tvr.size.height-1; + + int rowidx = [tv rowAtPoint:pt]; + if (rowidx < 0) rowidx=0; + else if (rowidx >= [tv numberOfRows]) rowidx=[tv numberOfRows]-1; + + int colidx = [tv columnAtPoint:pt]; + if (colidx < 0) colidx=0; + else if (colidx >= [tv numberOfColumns]) colidx = [tv numberOfColumns]-1; + + NSRect ir = [tv frameOfCellAtColumn:colidx row:rowidx]; + if (ir.size.width) xscroll /= ir.size.width; + else xscroll = 0; + if (ir.size.height) yscroll /= ir.size.height; + else yscroll = 0; + + rowidx += yscroll; + if (rowidx < 0) rowidx=0; + else if (rowidx >= [tv numberOfRows]) rowidx = [tv numberOfRows]-1; + + colidx += xscroll; + if (colidx < 0) colidx=0; + else if (colidx >= [tv numberOfColumns]) colidx = [tv numberOfColumns]-1; + + [tv scrollRowToVisible:rowidx]; + [tv scrollColumnToVisible:colidx]; + + return true; +} + +bool ListView_GetScroll(HWND h, POINT* p) +{ + NSTableView* tv = (NSTableView*)h; + NSScrollView* sv = [tv enclosingScrollView]; + if (sv) + { + NSRect cr = [sv documentVisibleRect]; + p->x = cr.origin.x; + p->y = cr.origin.y; + return true; + } + p->x=p->y=0; + return false; +} + +static int __listview_sortfunc(void *p1, void *p2, int (*compar)(LPARAM val1, LPARAM val2, LPARAM userval), LPARAM userval) +{ + SWELL_ListView_Row *a = *(SWELL_ListView_Row **)p1; + SWELL_ListView_Row *b = *(SWELL_ListView_Row **)p2; + return compar(a->m_param,b->m_param,userval); +} + +static void __listview_mergesort_internal(void *base, size_t nmemb, size_t size, + int (*compar)(LPARAM val1, LPARAM val2, LPARAM userval), + LPARAM parm, + char *tmpspace) +{ + char *b1,*b2; + size_t n1, n2; + + if (nmemb < 2) return; + + n1 = nmemb / 2; + b1 = (char *) base; + n2 = nmemb - n1; + b2 = b1 + (n1 * size); + + if (nmemb>2) + { + __listview_mergesort_internal(b1, n1, size, compar, parm, tmpspace); + __listview_mergesort_internal(b2, n2, size, compar, parm, tmpspace); + } + + char *p = tmpspace; + + do + { + if (__listview_sortfunc(b1, b2, compar,parm) > 0) + { + memcpy(p, b2, size); + b2 += size; + n2--; + } + else + { + memcpy(p, b1, size); + b1 += size; + n1--; + } + p += size; + } + while (n1 > 0 && n2 > 0); + + if (n1 > 0) memcpy(p, b1, n1 * size); + memcpy(base, tmpspace, (nmemb - n2) * size); +} + + +void ListView_SortItems(HWND hwnd, PFNLVCOMPARE compf, LPARAM parm) +{ + if (!hwnd) return; + if (![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; + SWELL_ListView *tv=(SWELL_ListView*)hwnd; + if (tv->m_lbMode || (tv->style & LVS_OWNERDATA) || !tv->m_items) return; + + WDL_HeapBuf tmp; + tmp.Resize(tv->m_items->GetSize()*sizeof(void *)); + int x; + int sc=0; + for(x=0;xm_items->GetSize();x++) + { + SWELL_ListView_Row *r = tv->m_items->Get(x); + if (r) + { + r->m_tmp = !![tv isRowSelected:x]; + sc++; + } + } + __listview_mergesort_internal(tv->m_items->GetList(),tv->m_items->GetSize(),sizeof(void *),compf,parm,(char*)tmp.Get()); + if (sc) + { + NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init]; + + for(x=0;xm_items->GetSize();x++) + { + SWELL_ListView_Row *r = tv->m_items->Get(x); + if (r && (r->m_tmp&1)) [indexSet addIndex:x]; + } + [tv selectRowIndexes:indexSet byExtendingSelection:NO]; + [indexSet release]; + } + + [tv reloadData]; +} + + +HWND WindowFromPoint(POINT p) +{ + NSArray *windows=[NSApp orderedWindows]; + int x; + int cnt=windows ? [windows count] : 0; + + NSWindow *kw = [NSApp keyWindow]; + if (kw && windows && [windows containsObject:kw]) kw=NULL; + + NSWindow *bestwnd=0; + for (x = kw ? -1 : 0; x < cnt; x ++) + { + NSWindow *wnd = kw; + if (x>=0) wnd=[windows objectAtIndex:x]; + if (wnd && [wnd isVisible]) + { + NSRect fr=[wnd frame]; + if (p.x >= fr.origin.x && p.x < fr.origin.x + fr.size.width && + p.y >= fr.origin.y && p.y < fr.origin.y + fr.size.height) + { + bestwnd=wnd; + break; + } + } + } + + if (!bestwnd) return 0; + NSPoint pt={p.x,p.y}; + NSPoint lpt=[bestwnd convertScreenToBase:pt]; + NSView *v=[[bestwnd contentView] hitTest:lpt]; + if (v) return (HWND)v; + return (HWND)[bestwnd contentView]; +} + +void UpdateWindow(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[NSView class]] && [(NSView *)hwnd needsDisplay]) + { + NSWindow *wnd = [(NSView *)hwnd window]; + [wnd displayIfNeeded]; + } +} + +void SWELL_FlushWindow(HWND h) +{ + if (h) + { + NSWindow *w=NULL; + if ([(id)h isKindOfClass:[NSView class]]) + { + if ([(NSView *)h needsDisplay]) return; + + w = [(NSView *)h window]; + } + else if ([(id)h isKindOfClass:[NSWindow class]]) w = (NSWindow *)h; + + if (w && ![w viewsNeedDisplay]) + { + [w flushWindow]; + } + } +} + +static void InvalidateSuperViews(NSView *view) +{ + if (!view) return; + view = [view superview]; + while (view) + { + if ([view isKindOfClass:[SWELL_hwndChild class]]) + { + if (((SWELL_hwndChild *)view)->m_isdirty&2) break; + ((SWELL_hwndChild *)view)->m_isdirty|=2; + } + view = [view superview]; + } +} + +void InvalidateRect(HWND hwnd, RECT *r, int eraseBk) +{ + if (!hwnd) return; + id view=(id)hwnd; + if ([view isKindOfClass:[NSWindow class]]) view=[view contentView]; + if ([view isKindOfClass:[NSView class]]) + { + + NSView *sv = view; + + bool skip_parent_invalidate=false; + if ([view isKindOfClass:[SWELL_hwndChild class]]) + { + if (!(((SWELL_hwndChild *)view)->m_isdirty&1)) + { + ((SWELL_hwndChild *)view)->m_isdirty|=1; + } + else skip_parent_invalidate=true; // if already dirty, then assume parents are already dirty too + } + if (!skip_parent_invalidate) + { + InvalidateSuperViews(view); + } + if (r) + { + RECT tr=*r; + if (tr.top>tr.bottom) + { + int a = tr.top; tr.top=tr.bottom; tr.bottom=a; + } + [sv setNeedsDisplayInRect:NSMakeRect(tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top)]; + } + else [sv setNeedsDisplay:YES]; + + } +} + +static HWND m_fakeCapture; +static BOOL m_capChangeNotify; +HWND GetCapture() +{ + + return m_fakeCapture; +} + +HWND SetCapture(HWND hwnd) +{ + HWND oc=m_fakeCapture; + int ocn=m_capChangeNotify; + m_fakeCapture=hwnd; + m_capChangeNotify = hwnd && [(id)hwnd respondsToSelector:@selector(swellCapChangeNotify)] && [(SWELL_hwndChild*)hwnd swellCapChangeNotify]; + + if (ocn && oc && oc != hwnd) SendMessage(oc,WM_CAPTURECHANGED,0,(LPARAM)hwnd); + return oc; +} + + +void ReleaseCapture() +{ + HWND h=m_fakeCapture; + m_fakeCapture=NULL; + if (m_capChangeNotify && h) + { + SendMessage(h,WM_CAPTURECHANGED,0,0); + } +} + + +HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps) +{ + if (!ps) return 0; + memset(ps,0,sizeof(PAINTSTRUCT)); + if (!hwnd) return 0; + id turd = (id)hwnd; + if (![turd respondsToSelector:@selector(getSwellPaintInfo:)]) return 0; + + [(SWELL_hwndChild*)turd getSwellPaintInfo:(PAINTSTRUCT *)ps]; + return ps->hdc; +} + +BOOL EndPaint(HWND hwnd, PAINTSTRUCT *ps) +{ + return TRUE; +} + +LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg==WM_RBUTTONUP||msg==WM_NCRBUTTONUP) + { + POINT p={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; + HWND hwndDest=hwnd; + if (msg==WM_RBUTTONUP) + { + ClientToScreen(hwnd,&p); + HWND h=WindowFromPoint(p); + if (h && IsChild(hwnd,h)) hwndDest=h; + } + SendMessage(hwnd,WM_CONTEXTMENU,(WPARAM)hwndDest,(p.x&0xffff)|(p.y<<16)); + return 1; + } + else if (msg==WM_CONTEXTMENU || msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL || msg == WM_GESTURE) + { + if ([(id)hwnd isKindOfClass:[NSView class]]) + { + NSView *h=(NSView *)hwnd; + while (h && [[h window] contentView] != h) + { + h=[h superview]; + if (h && [h respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + { + return SendMessage((HWND)h,msg,wParam,lParam); + } + } + } + } + else if (msg==WM_NCHITTEST) + { + return HTCLIENT; + } + else if (msg==WM_KEYDOWN || msg==WM_KEYUP) return 69; + else if (msg == WM_DISPLAYCHANGE) + { + if ([(id)hwnd isKindOfClass:[NSView class]]) + { + NSArray *ch = [(NSView *)hwnd subviews]; + if (ch) + { + int x; + for(x=0;x<[ch count]; x ++) + { + NSView *v = [ch objectAtIndex:x]; + sendSwellMessage(v,WM_DISPLAYCHANGE,wParam,lParam); + } + if (x) + { + void SWELL_DoDialogColorUpdates(HWND hwnd, DLGPROC d, bool isUpdate); + DLGPROC d = (DLGPROC)GetWindowLong(hwnd,DWL_DLGPROC); + if (d) SWELL_DoDialogColorUpdates(hwnd,d,true); + } + } + } + } + return 0; +} + +void SWELL_BroadcastMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + int x; + NSArray *ch=[NSApp orderedWindows]; + for(x=0;x<[ch count]; x ++) + { + NSView *v = [[ch objectAtIndex:x] contentView]; + if (v && [v respondsToSelector:@selector(onSwellMessage:p1:p2:)]) + { + [(SWELL_hwndChild *)v onSwellMessage:uMsg p1:wParam p2:lParam]; + + if (uMsg == WM_DISPLAYCHANGE) + InvalidateRect((HWND)v,NULL,FALSE); + } + } +} + + + + + + + + + + + + + + +///////////////// clipboard compatability (NOT THREAD SAFE CURRENTLY) + + +BOOL DragQueryPoint(HDROP hDrop,LPPOINT pt) +{ + if (!hDrop) return 0; + DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); + BOOL rv=!df->fNC; + *pt=df->pt; + GlobalUnlock(hDrop); + return rv; +} + +void DragFinish(HDROP hDrop) +{ +//do nothing for now (caller will free hdrops) +} + +UINT DragQueryFile(HDROP hDrop, UINT wf, char *buf, UINT bufsz) +{ + if (!hDrop) return 0; + DROPFILES *df=(DROPFILES*)GlobalLock(hDrop); + + UINT rv=0; + char *p=(char*)df + df->pFiles; + if (wf == 0xFFFFFFFF) + { + while (*p) + { + rv++; + p+=strlen(p)+1; + } + } + else + { + while (*p) + { + if (!wf--) + { + if (buf) + { + lstrcpyn(buf,p,bufsz); + rv=strlen(buf); + } + else rv=strlen(p); + + break; + } + p+=strlen(p)+1; + } + } + GlobalUnlock(hDrop); + return rv; +} + + + + + + + + + + + +static WDL_PtrList m_clip_recs; +static WDL_PtrList m_clip_fmts; +static WDL_PtrList m_clip_curfmts; +struct swell_pendingClipboardStates +{ + UINT type; + HANDLE h; + swell_pendingClipboardStates(UINT _type, HANDLE _h) + { + type = _type; + h = _h; + } + ~swell_pendingClipboardStates() + { + GlobalFree(h); + } +}; + +static WDL_PtrList m_clipsPending; + +bool OpenClipboard(HWND hwndDlg) +{ + m_clipsPending.Empty(true); + + CF_TEXT; // ensure this type is registered + + NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:@"SWELL_APP"]; + m_clip_curfmts.Empty(); + NSArray *ar=[pasteboard types]; + + + if (ar && [ar count]) + { + int x; + + for (x = 0; x < [ar count]; x ++) + { + NSString *s=[ar objectAtIndex:x]; + if (!s) continue; + int y; + for (y = 0; y < m_clip_fmts.GetSize(); y ++) + { + if ([s compare:(NSString *)m_clip_fmts.Get(y)]==NSOrderedSame) + { + if (m_clip_curfmts.Find((char*)(y+1))<0) + m_clip_curfmts.Add((char*)(y+1)); + break; + } + } + + } + } + return true; +} + +void CloseClipboard() // frees any remaining items in clipboard +{ + m_clip_recs.Empty(GlobalFree); + + if (m_clipsPending.GetSize()) + { + int x; + for (x=0;xtype != CF_TEXT;x++); + NSPasteboard *pasteboard = xtype-1); + if (fmt) [ar addObject:fmt]; + } + if ([ar count]) + { + [pasteboard declareTypes:ar owner:nil]; + for (x=0;xtype-1); + if (!fmt) continue; + + void *buf=GlobalLock(cs->h); + if (buf) + { + int bufsz=GlobalSize(cs->h); + if (cs->type == CF_TEXT) + { + char *t = (char *)malloc(bufsz+1); + if (t) + { + memcpy(t,buf,bufsz); + t[bufsz]=0; + NSString *s = (NSString*)SWELL_CStringToCFString(t); + [pasteboard setString:s forType:fmt]; + [s release]; + free(t); + } + } + else + { + NSData *data=[NSData dataWithBytes:buf length:bufsz]; + [pasteboard setData:data forType:fmt]; + } + GlobalUnlock(cs->h); + } + } + } + [ar release]; + m_clipsPending.Empty(true); + } +} + +UINT EnumClipboardFormats(UINT lastfmt) // won't enumerate CF_TEXT (since thats a separate pasteboard) +{ + if (!m_clip_curfmts.GetSize()) return 0; + if (lastfmt == 0) return (UINT)(INT_PTR)m_clip_curfmts.Get(0); + int x; + for (x = m_clip_curfmts.GetSize()-2; x >= 0; x--) // scan backwards to avoid dupes causing infinite loops + { + if ((UINT)(INT_PTR)m_clip_curfmts.Get(x) == lastfmt) + return (UINT)(INT_PTR)m_clip_curfmts.Get(x+1); + } + return 0; +} + +HANDLE GetClipboardData(UINT type) +{ + NSString *fmt=m_clip_fmts.Get(type-1); + if (!fmt) return 0; + NSPasteboard *pasteboard = type == CF_TEXT ? [NSPasteboard generalPasteboard] : [NSPasteboard pasteboardWithName:@"SWELL_APP"]; + + HANDLE h=0; + if (type == CF_TEXT) + { + [pasteboard types]; + NSString *str = [pasteboard stringForType:fmt]; + if (str) + { + int l = [str length]*4 + 32; + char *buf = (char *)malloc(l); + if (!buf) return 0; + SWELL_CFStringToCString(str,buf,l); + buf[l-1]=0; + l = strlen(buf)+1; + h=GlobalAlloc(0,l); + memcpy(GlobalLock(h),buf,l); + GlobalUnlock(h); + free(buf); + } + } + else + { + + NSData *data=[pasteboard dataForType:fmt]; + if (!data) return 0; + int l=[data length]; + h=GlobalAlloc(0,l); + memcpy(GlobalLock(h),[data bytes],l); + GlobalUnlock(h); + } + + if (h) m_clip_recs.Add(h); + return h; +} + +void EmptyClipboard() +{ + m_clipsPending.Empty(true); +} + + +void SetClipboardData(UINT type, HANDLE h) +{ + m_clipsPending.Add(new swell_pendingClipboardStates(type,h)); +} + +UINT RegisterClipboardFormat(const char *desc) +{ + NSString *s=NULL; + if (!strcmp(desc,"SWELL__CF_TEXT")) + { + s=NSStringPboardType; + [s retain]; + } + if (!s) s=(NSString*)SWELL_CStringToCFString(desc); + int x; + for (x = 0; x < m_clip_fmts.GetSize(); x ++) + { + NSString *ts=m_clip_fmts.Get(x); + if ([ts compare:s]==NSOrderedSame) + { + [s release]; + return x+1; + } + } + m_clip_fmts.Add(s); + return m_clip_fmts.GetSize(); +} + +int EnumPropsEx(HWND hwnd, PROPENUMPROCEX proc, LPARAM lParam) +{ + if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellEnumProps:lp:)]) return -1; + return (int)[(SWELL_hwndChild *)hwnd swellEnumProps:proc lp:lParam]; +} + +HANDLE GetProp(HWND hwnd, const char *name) +{ + if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellGetProp:wantRemove:)]) return NULL; + return (HANDLE)[(SWELL_hwndChild *)hwnd swellGetProp:name wantRemove:NO]; +} + +BOOL SetProp(HWND hwnd, const char *name, HANDLE val) +{ + if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellSetProp:value:)]) return FALSE; + return (BOOL)!![(SWELL_hwndChild *)hwnd swellSetProp:name value:val]; +} + +HANDLE RemoveProp(HWND hwnd, const char *name) +{ + if (!hwnd || ![(id)hwnd respondsToSelector:@selector(swellGetProp:wantRemove:)]) return NULL; + return (HANDLE)[(SWELL_hwndChild *)hwnd swellGetProp:name wantRemove:YES]; +} + + +int GetSystemMetrics(int p) +{ +switch (p) +{ +case SM_CXSCREEN: +case SM_CYSCREEN: +{ + NSScreen *s=[NSScreen mainScreen]; + if (!s) return 1024; + return p==SM_CXSCREEN ? [s frame].size.width : [s frame].size.height; +} +case SM_CXHSCROLL: return 16; +case SM_CYHSCROLL: return 16; +case SM_CXVSCROLL: return 16; +case SM_CYVSCROLL: return 16; +} +return 0; +} + +BOOL ScrollWindow(HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT *lpClipRect) +{ + if (hwnd && [(id)hwnd isKindOfClass:[NSWindow class]]) hwnd=(HWND)[(id)hwnd contentView]; + if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return FALSE; + + if (!xamt && !yamt) return FALSE; + + // move child windows only + if (1) + { + if (xamt || yamt) + { + NSArray *ar=[(NSView*)hwnd subviews]; + int i,c=[ar count]; + for(i=0;ihParent && ins->hParent != TVI_ROOT && ins->hParent != TVI_FIRST && ins->hParent != TVI_LAST && ins->hParent != TVI_SORT) + { + if ([tv findItem:ins->hParent parOut:&par idxOut:&inspos]) + { + par = (HTREEITEM__ *)ins->hParent; + } + else return 0; + } + + if (ins->hInsertAfter == TVI_FIRST) inspos=0; + else if (ins->hInsertAfter == TVI_LAST || ins->hInsertAfter == TVI_SORT || !ins->hInsertAfter) inspos=par ? par->m_children.GetSize() : tv->m_items ? tv->m_items->GetSize() : 0; + else inspos = par ? par->m_children.Find((HTREEITEM__*)ins->hInsertAfter)+1 : tv->m_items ? tv->m_items->Find((HTREEITEM__*)ins->hInsertAfter)+1 : 0; + + HTREEITEM__ *item=new HTREEITEM__; + if (ins->item.mask & TVIF_CHILDREN) + item->m_haschildren = !!ins->item.cChildren; + if (ins->item.mask & TVIF_PARAM) item->m_param = ins->item.lParam; + if (ins->item.mask & TVIF_TEXT) item->m_value = strdup(ins->item.pszText); + if (!par) + { + if (!tv->m_items) tv->m_items = new WDL_PtrList; + tv->m_items->Insert(inspos,item); + } + else par->m_children.Insert(inspos,item); + + [tv reloadData]; + return (HTREEITEM) item; +} + +BOOL TreeView_Expand(HWND hwnd, HTREEITEM item, UINT flag) +{ + if (!hwnd || !item) return false; + + if (![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return false; + + SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; + + id itemid=((HTREEITEM__*)item)->m_dh; + bool isExp=!![tv isItemExpanded:itemid]; + + if (flag == TVE_EXPAND && !isExp) [tv expandItem:itemid]; + else if (flag == TVE_COLLAPSE && isExp) [tv collapseItem:itemid]; + else if (flag==TVE_TOGGLE) + { + if (isExp) [tv collapseItem:itemid]; + else [tv expandItem:itemid]; + } + else return FALSE; + + return TRUE; + +} + +HTREEITEM TreeView_GetSelection(HWND hwnd) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; + + SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; + int idx=[tv selectedRow]; + if (idx<0) return NULL; + + SWELL_DataHold *t=[tv itemAtRow:idx]; + if (t) return (HTREEITEM)[t getValue]; + return NULL; + +} + +void TreeView_DeleteItem(HWND hwnd, HTREEITEM item) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; + SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; + + HTREEITEM__ *par=NULL; + int idx=0; + + if ([tv findItem:item parOut:&par idxOut:&idx]) + { + if (par) + { + par->m_children.Delete(idx,true); + } + else if (tv->m_items) + { + tv->m_items->Delete(idx,true); + } + [tv reloadData]; + } +} + +void TreeView_SelectItem(HWND hwnd, HTREEITEM item) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; + + int row=[(SWELL_TreeView*)hwnd rowForItem:((HTREEITEM__*)item)->m_dh]; + if (row>=0) + [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; + static int __rent; + if (!__rent) + { + __rent=1; + NMTREEVIEW nm={{(HWND)hwnd,[(SWELL_TreeView*)hwnd tag],TVN_SELCHANGED},}; + SendMessage(GetParent(hwnd),WM_NOTIFY,[(SWELL_TreeView*)hwnd tag],(LPARAM)&nm); + __rent=0; + } +} + +BOOL TreeView_GetItem(HWND hwnd, LPTVITEM pitem) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; + + HTREEITEM__ *ti = (HTREEITEM__*)pitem->hItem; + pitem->cChildren = ti->m_haschildren ? 1:0; + pitem->lParam = ti->m_param; + if ((pitem->mask&TVIF_TEXT)&&pitem->pszText&&pitem->cchTextMax>0) + { + lstrcpyn(pitem->pszText,ti->m_value?ti->m_value:"",pitem->cchTextMax); + } + pitem->state=0; + + + int itemRow = [(SWELL_TreeView*)hwnd rowForItem:ti->m_dh]; + if (itemRow >= 0 && [(SWELL_TreeView*)hwnd isRowSelected:itemRow]) + pitem->state |= TVIS_SELECTED; + if ([(SWELL_TreeView*)hwnd isItemExpanded:ti->m_dh]) + pitem->state |= TVIS_EXPANDED; + + return TRUE; +} + +BOOL TreeView_SetItem(HWND hwnd, LPTVITEM pitem) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !pitem || !(pitem->mask & TVIF_HANDLE) || !(pitem->hItem)) return FALSE; + + HTREEITEM__ *par=NULL; + int idx=0; + + if (![(SWELL_TreeView*)hwnd findItem:pitem->hItem parOut:&par idxOut:&idx]) return FALSE; + + HTREEITEM__ *ti = (HTREEITEM__*)pitem->hItem; + + if (pitem->mask & TVIF_CHILDREN) ti->m_haschildren = pitem->cChildren?1:0; + if (pitem->mask & TVIF_PARAM) ti->m_param = pitem->lParam; + + if ((pitem->mask&TVIF_TEXT)&&pitem->pszText) + { + free(ti->m_value); + ti->m_value=strdup(pitem->pszText); + InvalidateRect(hwnd, 0, FALSE); + } + + if (pitem->stateMask & TVIS_SELECTED) + { + int itemRow = [(SWELL_TreeView*)hwnd rowForItem:ti->m_dh]; + if (itemRow >= 0) + { + if (pitem->state&TVIS_SELECTED) + { + [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:NO]; + + static int __rent; + if (!__rent) + { + __rent=1; + NMTREEVIEW nm={{(HWND)hwnd,[(SWELL_TreeView*)hwnd tag],TVN_SELCHANGED},}; + SendMessage(GetParent(hwnd),WM_NOTIFY,[(SWELL_TreeView*)hwnd tag],(LPARAM)&nm); + __rent=0; + } + + } + else + { + // todo figure out unselect?! +// [(SWELL_TreeView*)hwnd selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:NO]; + } + } + } + + if (pitem->stateMask & TVIS_EXPANDED) + TreeView_Expand(hwnd,pitem->hItem,(pitem->state&TVIS_EXPANDED)?TVE_EXPAND:TVE_COLLAPSE); + + + return TRUE; +} + +HTREEITEM TreeView_HitTest(HWND hwnd, TVHITTESTINFO *hti) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]] || !hti) return NULL; + SWELL_TreeView* tv = (SWELL_TreeView*)hwnd; + int x = hti->pt.x; + int y = hti->pt.y; + + int i; + for (i = 0; i < [tv numberOfRows]; ++i) + { + NSRect r = [tv rectOfRow:i]; + if (x >= r.origin.x && x < r.origin.x+r.size.width && y >= r.origin.y && y < r.origin.y+r.size.height) + { + SWELL_DataHold* t = [tv itemAtRow:i]; + if (t) return (HTREEITEM)[t getValue]; + return 0; + } + } + + return NULL; // not hit +} + +HTREEITEM TreeView_GetRoot(HWND hwnd) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; + SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; + + if (!tv->m_items) return 0; + return (HTREEITEM) tv->m_items->Get(0); +} + +HTREEITEM TreeView_GetChild(HWND hwnd, HTREEITEM item) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; + + HTREEITEM__ *titem=(HTREEITEM__ *)item; + if (!titem) return TreeView_GetRoot(hwnd); + + return (HTREEITEM) titem->m_children.Get(0); +} +HTREEITEM TreeView_GetNextSibling(HWND hwnd, HTREEITEM item) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return NULL; + SWELL_TreeView *tv=(SWELL_TreeView*)hwnd; + + if (!item) return TreeView_GetRoot(hwnd); + + HTREEITEM__ *par=NULL; + int idx=0; + if ([tv findItem:item parOut:&par idxOut:&idx]) + { + if (par) + { + return par->m_children.Get(idx+1); + } + } + return 0; +} + +void TreeView_SetBkColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; + [(NSOutlineView*)hwnd setBackgroundColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]]; +} +void TreeView_SetTextColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_TreeView class]]) return; + + SWELL_TreeView *f = (SWELL_TreeView *)hwnd; + [f->m_fgColor release]; + f->m_fgColor = [NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]; + [f->m_fgColor retain]; +} +void ListView_SetBkColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; + [(NSTableView*)hwnd setBackgroundColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]]; +} + +void ListView_SetSelColors(HWND hwnd, int *colors, int ncolors) // this works for SWELL_ListView as well as SWELL_TreeView +{ + if (!hwnd) return; + NSMutableArray *ar=[[NSMutableArray alloc] initWithCapacity:ncolors]; + if (ncolors>0 && colors) + { + ar = [[NSMutableArray alloc] initWithCapacity:ncolors]; + while (ncolors-->0) + { + int color = *colors++; + [ar addObject:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]]; + } + } + + if ([(id)hwnd isKindOfClass:[SWELL_ListView class]]) + { + SWELL_ListView *lv = (SWELL_ListView*)hwnd; + [lv->m_selColors release]; + lv->m_selColors=ar; + } + else if ([(id)hwnd isKindOfClass:[SWELL_TreeView class]]) + { + SWELL_TreeView *lv = (SWELL_TreeView*)hwnd; + [lv->m_selColors release]; + lv->m_selColors=ar; + } + else + { + [ar release]; + } +} +void ListView_SetGridColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; + [(NSTableView*)hwnd setGridColor:[NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]]; +} +void ListView_SetTextBkColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; + // not implemented atm +} +void ListView_SetTextColor(HWND hwnd, int color) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[SWELL_ListView class]]) return; + + SWELL_ListView *f = (SWELL_ListView *)hwnd; + [f->m_fgColor release]; + f->m_fgColor = [NSColor colorWithCalibratedRed:GetRValue(color)/255.0f + green:GetGValue(color)/255.0f + blue:GetBValue(color)/255.0f alpha:1.0f]; + [f->m_fgColor retain]; +} + + +BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah) +{ + if (content1 && !strnicmp(content1,"http://",7)) + { + NSWorkspace *wk = [NSWorkspace sharedWorkspace]; + if (!wk) return FALSE; + NSString *fnstr=(NSString *)SWELL_CStringToCFString(content1); + BOOL ret=[wk openURL:[NSURL URLWithString:fnstr]]; + [fnstr release]; + return ret; + } + + if (content1 && !stricmp(content1,"explorer.exe")) content1=""; + else if (content1 && (!stricmp(content1,"notepad.exe")||!stricmp(content1,"notepad"))) content1="TextEdit.app"; + + if (content2 && !stricmp(content2,"explorer.exe")) content2=""; + + if (content1 && content2 && *content1 && *content2) + { + NSWorkspace *wk = [NSWorkspace sharedWorkspace]; + if (!wk) return FALSE; + NSString *appstr=(NSString *)SWELL_CStringToCFString(content1); + NSString *fnstr=(NSString *)SWELL_CStringToCFString(content2); + BOOL ret=[wk openFile:fnstr withApplication:appstr andDeactivate:YES]; + [fnstr release]; + [appstr release]; + return ret; + } + else if ((content1&&*content1) || (content2&&*content2)) + { + const char *fn = (content1 && *content1) ? content1 : content2; + NSWorkspace *wk = [NSWorkspace sharedWorkspace]; + if (!wk) return FALSE; + NSString *fnstr=(NSString *)SWELL_CStringToCFString(fn); + BOOL ret; + + if (strlen(fn)>4 && !stricmp(fn+strlen(fn)-4,".app")) ret=[wk launchApplication:fnstr]; + else ret=[wk openFile:fnstr]; + + [fnstr release]; + return ret; + } + return FALSE; +} + + + + +@implementation SWELL_FocusRectWnd + +-(BOOL)isOpaque { return YES; } +-(void) drawRect:(NSRect)rect +{ + NSColor *col=[NSColor colorWithCalibratedRed:0.5 green:0.5 blue:0.5 alpha:1.0]; + [col set]; + + CGRect r = CGRectMake(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); + + CGContextRef ctx = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + + CGContextFillRect(ctx,r); + +} +@end + +// r=NULL to "free" handle +// otherwise r is in hwndPar coordinates +void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) +{ + if (!handle) return; + NSWindow *wnd = (NSWindow *)*handle; + + if (!rct) + { + if (wnd) + { + NSWindow *ow=[wnd parentWindow]; + if (ow) [ow removeChildWindow:wnd]; +// [wnd setParentWindow:nil]; + [wnd close]; + *handle=0; + } + } + else + { + RECT r=*rct; + if (hwndPar) + { + ClientToScreen(hwndPar,((LPPOINT)&r)); + ClientToScreen(hwndPar,((LPPOINT)&r)+1); + } + else + { + // todo: flip? + } + if (r.top>r.bottom) { int a=r.top; r.top=r.bottom;r.bottom=a; } + NSRect rr=NSMakeRect(r.left,r.top,r.right-r.left,r.bottom-r.top); + + NSWindow *par=nil; + if (hwndPar) + { + if ([(id)hwndPar isKindOfClass:[NSWindow class]]) par=(NSWindow *)hwndPar; + else if ([(id)hwndPar isKindOfClass:[NSView class]]) par=[(NSView *)hwndPar window]; + else return; + } + + if (wnd && ([wnd parentWindow] != par)) + { + NSWindow *ow=[wnd parentWindow]; + if (ow) [ow removeChildWindow:wnd]; + // [wnd setParentWindow:nil]; + [wnd close]; + *handle=0; + wnd=0; + } + + if (!wnd) + { + *handle = wnd = [[NSWindow alloc] initWithContentRect:rr styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; + [wnd setOpaque:YES]; + [wnd setAlphaValue:0.5]; + [wnd setExcludedFromWindowsMenu:YES]; + [wnd setIgnoresMouseEvents:YES]; + [wnd setContentView:[[SWELL_FocusRectWnd alloc] init]]; + + if (par) [par addChildWindow:wnd ordered:NSWindowAbove]; + else + { + [wnd setLevel:NSPopUpMenuWindowLevel]; + [wnd orderFront:wnd]; + } + // [wnd setParentWindow:par]; +// [wnd orderWindow:NSWindowAbove relativeTo:[par windowNumber]]; + } + + [wnd setFrame:rr display:YES]; + } +} + + +@implementation SWELL_PopUpButton +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(void)setSwellStyle:(LONG)style { m_style=style; } +-(LONG)getSwellStyle { return m_style; } +@end + +@implementation SWELL_ComboBox +STANDARD_CONTROL_NEEDSDISPLAY_IMPL + +-(void)setSwellStyle:(LONG)style { m_style=style; } +-(LONG)getSwellStyle { return m_style; } +-(id)init { self = [super init]; if (self) { m_ids=new WDL_PtrList; } return self; } +-(void)dealloc { delete m_ids; [super dealloc]; } +@end + + + + +bool SWELL_HandleMouseEvent(NSEvent *evt) +{ + int etype = [evt type]; + if (GetCapture()) return false; + if (etype >= NSLeftMouseDown && etype <= NSRightMouseDragged) + { + } + else return false; + + NSWindow *w = [evt window]; + if (w) + { + NSView *cview = [w contentView]; + NSView *besthit=NULL; + if (cview) + { + NSPoint lpt = [evt locationInWindow]; + NSView *hitv=[cview hitTest:lpt]; + lpt = [w convertBaseToScreen:lpt]; + + int xpos=(int)floor(lpt.x); + int ypos=(int)floor(lpt.y); + + while (hitv) + { + int ht=(int)sendSwellMessage(hitv,WM_NCHITTEST,0,MAKELPARAM(xpos,ypos)); + if (ht && ht != HTCLIENT) besthit=hitv; + + if (hitv==cview) break; + hitv = [hitv superview]; + } + } + if (besthit) + { + if (etype == NSLeftMouseDown) [besthit mouseDown:evt]; + else if (etype == NSLeftMouseUp) [besthit mouseUp:evt]; + else if (etype == NSLeftMouseDragged) [besthit mouseDragged:evt]; + else if (etype == NSRightMouseDown) [besthit rightMouseDown:evt]; + else if (etype == NSRightMouseUp) [besthit rightMouseUp:evt]; + else if (etype == NSRightMouseDragged) [besthit rightMouseDragged:evt]; + else if (etype == NSMouseMoved) [besthit mouseMoved:evt]; + else return false; + + return true; + } + } + return false; +} + +int SWELL_GetWindowWantRaiseAmt(HWND h) +{ + SWELL_ModelessWindow* mw=0; + if ([(id)h isKindOfClass:[SWELL_ModelessWindow class]]) + { + mw=(SWELL_ModelessWindow*)h; + } + else if ([(id)h isKindOfClass:[NSView class]]) + { + NSWindow* wnd=[(NSView*)h window]; + if (wnd && [wnd isKindOfClass:[SWELL_ModelessWindow class]]) + { + mw=(SWELL_ModelessWindow*)wnd; + } + } + if (mw) return mw->m_wantraiseamt; + return 0; +} + +void SWELL_SetWindowWantRaiseAmt(HWND h, int amt) +{ + SWELL_ModelessWindow *mw=NULL; + if ([(id)h isKindOfClass:[SWELL_ModelessWindow class]]) mw=(SWELL_ModelessWindow *)h; + else if ([(id)h isKindOfClass:[NSView class]]) + { + NSWindow *w = [(NSView *)h window]; + if (w && [w isKindOfClass:[SWELL_ModelessWindow class]]) mw = (SWELL_ModelessWindow*)w; + } + if (mw) + { + int diff = amt - mw->m_wantraiseamt; + mw->m_wantraiseamt = amt; + if (diff && [NSApp isActive]) [mw setLevel:[mw level]+diff]; + } +} + + +int SWELL_SetWindowLevel(HWND hwnd, int newlevel) +{ + NSWindow *w = (NSWindow *)hwnd; + if (w && [w isKindOfClass:[NSView class]]) w= [(NSView *)w window]; + + if (w && [w isKindOfClass:[NSWindow class]]) + { + int ol = [w level]; + [w setLevel:newlevel]; + return ol; + } + return 0; +} + +void SetOpaque(HWND h, bool opaque) +{ + if (!h || ![(id)h isKindOfClass:[SWELL_hwndChild class]]) return; + SWELL_hwndChild* v = (SWELL_hwndChild*)h; + [v setOpaque:opaque]; +} + +void SetTransparent(HWND h) +{ + if (!h) return; + NSWindow* wnd=0; + if ([(id)h isKindOfClass:[NSWindow class]]) wnd=(NSWindow*)h; + else if ([(id)h isKindOfClass:[NSView class]]) wnd=[(NSView*)h window]; + if (wnd) + { + [wnd setBackgroundColor:[NSColor clearColor]]; + [wnd setOpaque:NO]; + } +} + +int SWELL_GetDefaultButtonID(HWND hwndDlg, bool onlyIfEnabled) +{ + if (![(id)hwndDlg isKindOfClass:[NSView class]]) return 0; + NSWindow *wnd = [(NSView *)hwndDlg window]; + NSButtonCell * cell = wnd ? [wnd defaultButtonCell] : nil; + NSView *view; + if (!cell || !(view=[cell controlView])) return 0; + int cmdid = [view tag]; + if (cmdid && onlyIfEnabled) + { + if (![cell isEnabled]) return 0; + } + return cmdid; +} + + +void SWELL_SetWindowRepre(HWND hwnd, const char *fn, bool isDirty) +{ + if (!hwnd) return; + NSWindow *w = NULL; + if ([(id)hwnd isKindOfClass:[NSWindow class]]) w=(NSWindow *)hwnd; + if ([(id)hwnd isKindOfClass:[NSView class]]) w=[(NSView *)hwnd window]; + + if (w) + { + if (GetProp((HWND)[w contentView],"SWELL_DisableWindowRepre")) return; + + [w setDocumentEdited:isDirty]; + + if (!fn || !*fn) [w setRepresentedFilename:@""]; + else + { + NSString *str = (NSString *)SWELL_CStringToCFString(fn); + [w setRepresentedFilename:str]; + [str release]; + } + } +} + +int g_swell_terminating; +void SWELL_PostQuitMessage(void *sender) +{ + g_swell_terminating=true; + + [NSApp terminate:(id)sender]; +} + +void SWELL_SetWindowShadow(HWND hwnd, bool shadow) +{ + if (!hwnd) return; + NSWindow *w = (NSWindow *)hwnd; + if ([w isKindOfClass:[NSView class]]) w = [(NSView *)w window]; + if (w && [w isKindOfClass:[NSWindow class]]) [w setHasShadow:shadow]; +} + +#if 0 // not sure if this will interfere with coolSB +BOOL ShowScrollBar(HWND hwnd, int nBar, BOOL vis) +{ + int v=0; + if (nBar == SB_HORZ || nBar == SB_BOTH) v |= WS_HSCROLL; + if (nBar == SB_VERT || nBar == SB_BOTH) v |= WS_VSCROLL; + if (v) + { + int s=GetWindowLong(hwnd, GWL_STYLE); + if (vis) s |= v; + else s &= ~v; + SetWindowLong(hwnd, GWL_STYLE, s); + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + return TRUE; + } + return FALSE; +} +#endif + + +void SWELL_GenerateDialogFromList(const void *_list, int listsz) +{ +#define SIXFROMLIST list->p1,list->p2,list->p3, list->p4, list->p5, list->p6 + SWELL_DlgResourceEntry *list = (SWELL_DlgResourceEntry*)_list; + while (listsz>0) + { + if (!strcmp(list->str1,"__SWELL_BUTTON")) + { + SWELL_MakeButton(list->flag1,list->str2, SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_EDIT")) + { + SWELL_MakeEditField(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_COMBO")) + { + SWELL_MakeCombo(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_LISTBOX")) + { + SWELL_MakeListBox(SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_GROUP")) + { + SWELL_MakeGroupBox(list->str2,SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_CHECKBOX")) + { + SWELL_MakeCheckBox(list->str2,SIXFROMLIST); + } + else if (!strcmp(list->str1,"__SWELL_LABEL")) + { + SWELL_MakeLabel(list->flag1, list->str2, SIXFROMLIST); + } + else if (*list->str2) + { + SWELL_MakeControl(list->str1, list->flag1, list->str2, SIXFROMLIST); + } + listsz--; + list++; + } +} + +BOOL EnumChildWindows(HWND hwnd, BOOL (*cwEnumFunc)(HWND,LPARAM),LPARAM lParam) +{ + if (!hwnd || ![(id)hwnd isKindOfClass:[NSView class]]) return TRUE; + NSArray *ar = [(NSView *)hwnd subviews]; + if (ar) + { + [ar retain]; + int x,n=[ar count]; + for (x=0;xleft=r->top=0; + r->right = (int)frnew.size.width; + r->bottom = (int)frnew.size.height; + } +} + +BOOL SWELL_IsGroupBox(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[SWELL_BoxView class]]) return TRUE; + return FALSE; +} +BOOL SWELL_IsButton(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[SWELL_Button class]]) return TRUE; + return FALSE; +} +BOOL SWELL_IsStaticText(HWND hwnd) +{ + if (hwnd && [(id)hwnd isKindOfClass:[NSTextField class]]) return TRUE; + //todo + return FALSE; +} + + +bool SWELL_SetAppAutoHideMenuAndDock(int ah) +{ + static char _init; + static NSUInteger _defpres; + if (!_init) + { + _init=-1; + SInt32 v=0x1040; + Gestalt(gestaltSystemVersion,&v); + if (v>=0x1060) + { + _init=1; + _defpres = [(SWELL_AppExtensions*)[NSApplication sharedApplication] presentationOptions]; + } + } + if (_init > 0) + { + const int NSApplicationPresentationAutoHideDock = (1 << 0), + NSApplicationPresentationHideDock = (1<<1), + NSApplicationPresentationAutoHideMenuBar = (1 << 2); + + if (ah>0) [(SWELL_AppExtensions*)[NSApplication sharedApplication] setPresentationOptions:((ah>=2?NSApplicationPresentationHideDock:NSApplicationPresentationAutoHideDock)|NSApplicationPresentationAutoHideMenuBar)]; + else [(SWELL_AppExtensions*)[NSApplication sharedApplication] setPresentationOptions:_defpres]; + return true; + } + return false; +} + +#endif diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp new file mode 100644 index 00000000..818bb486 --- /dev/null +++ b/WDL/swell/swell.cpp @@ -0,0 +1,909 @@ + +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Losers (who use OS X)) + Copyright (C) 2006-2007, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file implements a few Windows calls using their posix equivilents + + */ + +#ifndef SWELL_PROVIDED_BY_APP + + +#include "swell.h" +#include +#include +#include +#include +#include + + +#include "swell-internal.h" + + +#ifdef __APPLE__ +#include +#include +#include +#endif + + +#include + + +#include "../mutex.h" +#include "../assocarray.h" + +void Sleep(int ms) +{ + usleep(ms?ms*1000:100); +} + +DWORD GetTickCount() +{ + struct timeval tm={0,}; + gettimeofday(&tm,NULL); + return tm.tv_sec*1000 + tm.tv_usec/1000; +} + + +static void intToFileTime(time_t t, FILETIME *out) +{ + unsigned long long a=(unsigned long long)t; // seconds since january 1st, 1970 + a+=(60*60*24*(365*4+1)/4)*(long long)(1970-1601); // this is approximate + a*=1000*10000; // seconds to 1/10th microseconds (100 nanoseconds) + out->dwLowDateTime=a & 0xffffffff; + out->dwHighDateTime=a>>32; +} + +BOOL GetFileTime(int filedes, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime) +{ + if (filedes<0) return 0; + struct stat st; + if (fstat(filedes,&st)) return 0; + + if (lpCreationTime) intToFileTime(st.st_ctime,lpCreationTime); + if (lpLastAccessTime) intToFileTime(st.st_atime,lpLastAccessTime); + if (lpLastWriteTime) intToFileTime(st.st_mtime,lpLastWriteTime); + + return 1; +} + +BOOL SWELL_PtInRect(RECT *r, POINT p) +{ + if (!r) return FALSE; + int tp=r->top; + int bt=r->bottom; + if (tp>bt) + { + bt=tp; + tp=r->bottom; + } + return p.x>=r->left && p.xright && p.y >= tp && p.y < bt; +} + + +int MulDiv(int a, int b, int c) +{ + if(c == 0) return 0; + return (int)((double)a*(double)b/c); +} + +unsigned int _controlfp(unsigned int flag, unsigned int mask) +{ +#if !defined(__ppc__) && !defined(__LP64__) + unsigned short ret; + mask &= _MCW_RC; // don't let the caller set anything other than round control for now + __asm__ __volatile__("fnstcw %0\n\t":"=m"(ret)); + ret=(ret&~(mask<<2))|(flag<<2); + + if (mask) __asm__ __volatile__( + "fldcw %0\n\t"::"m"(ret)); + return (unsigned int) (ret>>2); +#else + return 0; +#endif +} + + +BOOL CloseHandle(HANDLE hand) +{ + SWELL_InternalObjectHeader *hdr=(SWELL_InternalObjectHeader*)hand; + if (!hdr) return FALSE; + if (hdr->type <= INTERNAL_OBJECT_START || hdr->type >= INTERNAL_OBJECT_END) return FALSE; + +#ifdef SWELL_TARGET_OSX + if (!OSAtomicDecrement32(&hdr->count)) +#else + if (!--hdr->count) // todo: atomic decrement on posix/ glib? +#endif + { + switch (hdr->type) + { + case INTERNAL_OBJECT_FILE: + { + SWELL_InternalObjectHeader_File *file = (SWELL_InternalObjectHeader_File*)hdr; + if (file->fp) fclose(file->fp); + } + break; + case INTERNAL_OBJECT_EXTERNALSOCKET: return FALSE; // pure sockets are not to be closed this way; + case INTERNAL_OBJECT_SOCKETEVENT: + { + SWELL_InternalObjectHeader_SocketEvent *se= (SWELL_InternalObjectHeader_SocketEvent *)hdr; + if (se->socket[0]>=0) close(se->socket[0]); + if (se->socket[1]>=0) close(se->socket[1]); + } + break; + case INTERNAL_OBJECT_EVENT: + { + SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hdr; + pthread_cond_destroy(&evt->cond); + pthread_mutex_destroy(&evt->mutex); + } + break; + case INTERNAL_OBJECT_THREAD: + { + SWELL_InternalObjectHeader_Thread *thr = (SWELL_InternalObjectHeader_Thread*)hdr; + void *tmp; + pthread_join(thr->pt,&tmp); + pthread_detach(thr->pt); + } + break; +#ifdef __APPLE__ + case INTERNAL_OBJECT_NSTASK: + { + SWELL_InternalObjectHeader_NSTask *nst = (SWELL_InternalObjectHeader_NSTask*)hdr; + extern void SWELL_ReleaseNSTask(void *); + if (nst->task) SWELL_ReleaseNSTask(nst->task); + } + break; +#endif + } + free(hdr); + } + return TRUE; +} + +HANDLE CreateEventAsSocket(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored) +{ + SWELL_InternalObjectHeader_SocketEvent *buf = (SWELL_InternalObjectHeader_SocketEvent*)malloc(sizeof(SWELL_InternalObjectHeader_SocketEvent)); + buf->hdr.type=INTERNAL_OBJECT_SOCKETEVENT; + buf->hdr.count=1; + buf->autoReset = !manualReset; + buf->socket[0]=buf->socket[1]=-1; + if (socketpair(AF_UNIX,SOCK_STREAM,0,buf->socket)<0) + { + free(buf); + return 0; + } + fcntl(buf->socket[0], F_SETFL, fcntl(buf->socket[0],F_GETFL) | O_NONBLOCK); // nonblocking + + char c=0; + if (initialSig&&buf->socket[1]>=0) write(buf->socket[1],&c,1); + + return buf; +} + +DWORD WaitForAnySocketObject(int numObjs, HANDLE *objs, DWORD msTO) // only supports special (socket) handles at the moment +{ + int max_s=0; + fd_set s; + FD_ZERO(&s); + int x; + for (x = 0; x < numObjs; x ++) + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)objs[x]; + if ((se->hdr.type == INTERNAL_OBJECT_EXTERNALSOCKET || se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) && se->socket[0]>=0) + { + FD_SET(se->socket[0],&s); + if (se->socket[0] > max_s) max_s = se->socket[0]; + } + } + + if (max_s>0) + { +again: + struct timeval tv={msTO/1000,(msTO%1000)*1000}; + if (select(max_s+1,&s,NULL,NULL,msTO==INFINITE?NULL:&tv)>0) for (x = 0; x < numObjs; x ++) + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)objs[x]; + if ((se->hdr.type == INTERNAL_OBJECT_EXTERNALSOCKET || se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) && se->socket[0]>=0) + { + if (FD_ISSET(se->socket[0],&s)) + { + if (se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT && se->autoReset) + { + char buf[128]; + if (read(se->socket[0],buf,sizeof(buf))<1) goto again; + } + return WAIT_OBJECT_0 + x; + } + } + } + } + + return WAIT_TIMEOUT; +} + +DWORD WaitForSingleObject(HANDLE hand, DWORD msTO) +{ + SWELL_InternalObjectHeader *hdr=(SWELL_InternalObjectHeader*)hand; + if (!hdr) return WAIT_FAILED; + + switch (hdr->type) + { +#ifdef __APPLE__ + case INTERNAL_OBJECT_NSTASK: + { + SWELL_InternalObjectHeader_NSTask *nst = (SWELL_InternalObjectHeader_NSTask*)hdr; + extern DWORD SWELL_WaitForNSTask(void *,DWORD); + if (nst->task) return SWELL_WaitForNSTask(nst->task,msTO); + } + break; +#endif + case INTERNAL_OBJECT_THREAD: + { + SWELL_InternalObjectHeader_Thread *thr = (SWELL_InternalObjectHeader_Thread*)hdr; + void *tmp; + if (!thr->done) + { + if (!msTO) return WAIT_TIMEOUT; + if (msTO != INFINITE) + { + DWORD d=GetTickCount()+msTO; + while (GetTickCount()done) Sleep(1); + if (!thr->done) return WAIT_TIMEOUT; + } + } + + if (!pthread_join(thr->pt,&tmp)) return WAIT_OBJECT_0; + } + break; + case INTERNAL_OBJECT_EXTERNALSOCKET: + case INTERNAL_OBJECT_SOCKETEVENT: + { + SWELL_InternalObjectHeader_SocketEvent *se = (SWELL_InternalObjectHeader_SocketEvent *)hdr; + if (se->socket[0]<0) Sleep(msTO!=INFINITE?msTO:1); + else + { + fd_set s; + FD_ZERO(&s); +again: + FD_SET(se->socket[0],&s); + struct timeval tv={msTO/1000,(msTO%1000)*1000}; + if (select(se->socket[0]+1,&s,NULL,NULL,msTO==INFINITE?NULL:&tv)>0 && FD_ISSET(se->socket[0],&s)) + { + if (se->hdr.type == INTERNAL_OBJECT_SOCKETEVENT && se->autoReset) + { + char buf[128]; + if (read(se->socket[0],buf,sizeof(buf))<1) goto again; + } + return WAIT_OBJECT_0; + } + return WAIT_TIMEOUT; + } + } + break; + case INTERNAL_OBJECT_EVENT: + { + SWELL_InternalObjectHeader_Event *evt = (SWELL_InternalObjectHeader_Event*)hdr; + int rv=WAIT_OBJECT_0; + pthread_mutex_lock(&evt->mutex); + if (msTO == 0) + { + if (!evt->isSignal) rv=WAIT_TIMEOUT; + } + else if (msTO == INFINITE) + { + while (!evt->isSignal) pthread_cond_wait(&evt->cond,&evt->mutex); + } + else + { + // timed wait + struct timespec ts={msTO/1000, (msTO%1000)*1000000}; + while (!evt->isSignal) + { +#ifdef SWELL_TARGET_OSX + if (pthread_cond_timedwait_relative_np(&evt->cond,&evt->mutex,&ts)==ETIMEDOUT) + { + rv = WAIT_TIMEOUT; + break; + } +#else +#if 1 + struct timeval tm={0,}; + gettimeofday(&tm,NULL); + ts.tv_sec += tm.tv_sec; + ts.tv_nsec += tm.tv_usec * 1000; +#else + struct timespec ts2={0,0,}; + clock_gettime(CLOCK_REALTIME,&ts2); + ts.tv_sec += ts2.tv_sec; + ts.tv_nsec += ts2.tv_nsec; +#endif + if (ts.tv_nsec>=1000000000) + { + int n = ts.tv_nsec/1000000000; + ts.tv_sec+=n; + ts.tv_nsec -= ((long long)n * (long long)1000000000); + } + if (pthread_cond_timedwait(&evt->cond,&evt->mutex,&ts)) + { + rv = WAIT_TIMEOUT; + break; + } +#endif + // we should track/correct the timeout amount here since in theory we could end up waiting a bit longer! + } + } + if (!evt->isManualReset && rv==WAIT_OBJECT_0) evt->isSignal=false; + pthread_mutex_unlock(&evt->mutex); + + return rv; + } + break; + } + + return WAIT_FAILED; +} + +static void *__threadproc(void *parm) +{ +#ifdef SWELL_TARGET_OSX + void *arp=SWELL_InitAutoRelease(); +#endif + + SWELL_InternalObjectHeader_Thread *t=(SWELL_InternalObjectHeader_Thread*)parm; + t->retv=t->threadProc(t->threadParm); + t->done=1; + CloseHandle(parm); + +#ifdef SWELL_TARGET_OSX + SWELL_QuitAutoRelease(arp); +#endif + + pthread_exit(0); + return 0; +} + +DWORD GetCurrentThreadId() +{ + return (DWORD)(INT_PTR)pthread_self(); // this is incorrect on x64 +} + +HANDLE CreateEvent(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored) +{ + SWELL_InternalObjectHeader_Event *buf = (SWELL_InternalObjectHeader_Event*)malloc(sizeof(SWELL_InternalObjectHeader_Event)); + buf->hdr.type=INTERNAL_OBJECT_EVENT; + buf->hdr.count=1; + buf->isSignal = !!initialSig; + buf->isManualReset = !!manualReset; + + pthread_mutex_init(&buf->mutex,NULL); + pthread_cond_init(&buf->cond,NULL); + + return (HANDLE)buf; +} + +HANDLE CreateThread(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut) +{ +#ifdef SWELL_TARGET_OSX + SWELL_EnsureMultithreadedCocoa(); +#endif + SWELL_InternalObjectHeader_Thread *buf = (SWELL_InternalObjectHeader_Thread *)malloc(sizeof(SWELL_InternalObjectHeader_Thread)); + buf->hdr.type=INTERNAL_OBJECT_THREAD; + buf->hdr.count=2; + buf->threadProc=ThreadProc; + buf->threadParm = parm; + buf->retv=0; + buf->pt=0; + buf->done=0; + pthread_create(&buf->pt,NULL,__threadproc,buf); + + if (tidOut) *tidOut=(DWORD)(INT_PTR)buf->pt; // incorrect on x64 + + return (HANDLE)buf; +} + + +BOOL SetThreadPriority(HANDLE hand, int prio) +{ + SWELL_InternalObjectHeader_Thread *evt=(SWELL_InternalObjectHeader_Thread*)hand; + if (!evt || evt->hdr.type != INTERNAL_OBJECT_THREAD) return FALSE; + + if (evt->done) return FALSE; + + int pol; + struct sched_param param; + if (!pthread_getschedparam(evt->pt,&pol,¶m)) + { + +// printf("thread prio %d(%d,%d), %d(FIFO=%d, RR=%d)\n",param.sched_priority, sched_get_priority_min(pol),sched_get_priority_max(pol), pol,SCHED_FIFO,SCHED_RR); + param.sched_priority = 31 + prio; + int mt=sched_get_priority_min(pol); + if (param.sched_priority (mt=sched_get_priority_max(pol)))param.sched_priority=mt; + + if (!pthread_setschedparam(evt->pt,pol,¶m)) + { + return TRUE; + } + } + + + + return FALSE; +} + +BOOL SetEvent(HANDLE hand) +{ + SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hand; + if (!evt) return FALSE; + if (evt->hdr.type == INTERNAL_OBJECT_EVENT) + { + pthread_mutex_lock(&evt->mutex); + if (!evt->isSignal) + { + evt->isSignal = true; + if (evt->isManualReset) pthread_cond_broadcast(&evt->cond); + else pthread_cond_signal(&evt->cond); + } + pthread_mutex_unlock(&evt->mutex); + return TRUE; + } + if (evt->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) + { + SWELL_InternalObjectHeader_SocketEvent *se=(SWELL_InternalObjectHeader_SocketEvent*)hand; + if (se->socket[1]>=0) + { + if (se->socket[0]>=0) + { + fd_set s; + FD_ZERO(&s); + FD_SET(se->socket[0],&s); + struct timeval tv={0,}; + if (select(se->socket[0]+1,&s,NULL,NULL,&tv)>0 && FD_ISSET(se->socket[0],&s)) return TRUE; // already set + } + char c=0; + write(se->socket[1],&c,1); + } + return TRUE; + } + return FALSE; +} +BOOL ResetEvent(HANDLE hand) +{ + SWELL_InternalObjectHeader_Event *evt=(SWELL_InternalObjectHeader_Event*)hand; + if (!evt) return FALSE; + if (evt->hdr.type == INTERNAL_OBJECT_EVENT) + { + evt->isSignal=false; + return TRUE; + } + if (evt->hdr.type == INTERNAL_OBJECT_SOCKETEVENT) + { + SWELL_InternalObjectHeader_SocketEvent *se=(SWELL_InternalObjectHeader_SocketEvent*)hand; + if (se->socket[0]>=0) + { + char buf[128]; + read(se->socket[0],buf,sizeof(buf)); + } + return TRUE; + } + return FALSE; +} + +HANDLE CreateFile( const char * lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + void *lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + return 0;// INVALID_HANDLE_VALUE; +} + +DWORD SetFilePointer(HANDLE hFile, DWORD low, DWORD *high) +{ + SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; + if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || (high && *high) || fseek(file->fp,low,SEEK_SET)==-1) { if (high) *high=0xffffffff; return 0xffffffff; } + return ftell(file->fp); +} + +DWORD GetFilePointer(HANDLE hFile, DWORD *high) +{ + int pos; + SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; + if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || (pos=ftell(file->fp))==-1) { if (high) *high=0xffffffff; return 0xffffffff; } + if (high) *high=0; + return (DWORD)pos; +} + +DWORD GetFileSize(HANDLE hFile, DWORD *high) +{ + SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; + if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp) { if (high) *high=0xffffffff; return 0xffffffff; } + + int a=ftell(file->fp); + fseek(file->fp,0,SEEK_END); + int ret=ftell(file->fp); + fseek(file->fp,a,SEEK_SET); + + if (high) *high=ret==-1 ? 0xffffffff: 0; + return (DWORD)ret; +} + + + +BOOL WriteFile(HANDLE hFile,void *buf, DWORD len, DWORD *lenOut, void *ovl) +{ + SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; + if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || !buf || !len) return FALSE; + int lo=fwrite(buf,1,len,file->fp); + if (lenOut) *lenOut = lo; + return !!lo; +} + +BOOL ReadFile(HANDLE hFile,void *buf, DWORD len, DWORD *lenOut, void *ovl) +{ + SWELL_InternalObjectHeader_File *file=(SWELL_InternalObjectHeader_File*)hFile; + if (!file || file->hdr.type != INTERNAL_OBJECT_FILE || !file->fp || !buf || !len) return FALSE; + int lo=fread(buf,1,len,file->fp); + if (lenOut) *lenOut = lo; + return !!lo; +} + +BOOL WinOffsetRect(LPRECT lprc, int dx, int dy) +{ + if(!lprc) return 0; + lprc->left+=dx; + lprc->top+=dy; + lprc->right+=dx; + lprc->bottom+=dy; + return TRUE; +} + +BOOL WinSetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom) +{ + if(!lprc) return 0; + lprc->left = xLeft; + lprc->top = yTop; + lprc->right = xRight; + lprc->bottom = yBottom; + return TRUE; +} + + +int WinIntersectRect(RECT *out, RECT *in1, RECT *in2) +{ + memset(out,0,sizeof(RECT)); + if (in1->right <= in1->left) return false; + if (in2->right <= in2->left) return false; + if (in1->bottom <= in1->top) return false; + if (in2->bottom <= in2->top) return false; + + // left is maximum of minimum of right edges and max of left edges + out->left = max(in1->left,in2->left); + out->right = min(in1->right,in2->right); + out->top=max(in1->top,in2->top); + out->bottom = min(in1->bottom,in2->bottom); + + return out->right>out->left && out->bottom>out->top; +} +void WinUnionRect(RECT *out, RECT *in1, RECT *in2) +{ + out->left = min(in1->left,in2->left); + out->top = min(in1->top,in2->top); + out->right=max(in1->right,in2->right); + out->bottom=max(in1->bottom,in2->bottom); +} + + +typedef struct +{ + int sz; + int refcnt; +} GLOBAL_REC; + + +void *GlobalLock(HANDLE h) +{ + if (!h) return 0; + GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; + rec->refcnt++; + return h; +} +int GlobalSize(HANDLE h) +{ + if (!h) return 0; + GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; + return rec->sz; +} + +void GlobalUnlock(HANDLE h) +{ + if (!h) return; + GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; + rec->refcnt--; +} +void GlobalFree(HANDLE h) +{ + if (!h) return; + GLOBAL_REC *rec=((GLOBAL_REC*)h)-1; + if (rec->refcnt) + { + // note error freeing locked ram + } + free(rec); + +} +HANDLE GlobalAlloc(int flags, int sz) +{ + if (sz<0)sz=0; + GLOBAL_REC *rec=(GLOBAL_REC*)malloc(sizeof(GLOBAL_REC)+sz); + if (!rec) return 0; + rec->sz=sz; + rec->refcnt=0; + if (flags&GMEM_FIXED) memset(rec+1,0,sz); + return rec+1; +} + +char *lstrcpyn(char *dest, const char *src, int l) +{ + if (l<1) return dest; + + char *dsrc=dest; + while (--l > 0) + { + char p=*src++; + if (!p) break; + *dest++=p; + } + *dest++=0; + + return dsrc; +} + +static WDL_Mutex s_libraryMutex; +static int libkeycomp(void **p1, void **p2) +{ + INT_PTR a=(INT_PTR)(*p1) - (INT_PTR)(*p2); + if (a<0)return -1; + if (a>0) return 1; + return 0; +} +static WDL_AssocArray s_loadedLibs(libkeycomp); // index by OS-provided handle (rather than filename since filenames could be relative etc) + +HINSTANCE LoadLibrary(const char *fn) +{ + return LoadLibraryGlobals(fn,false); +} +HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) +{ + if (!fn || !*fn) return NULL; + + void *inst = NULL, *bundleinst=NULL; + +#ifdef __APPLE__ + struct stat ss; + if (stat(fn,&ss) || (ss.st_mode&S_IFDIR)) + { + CFStringRef str=(CFStringRef)SWELL_CStringToCFString(fn); + CFURLRef r=CFURLCreateWithFileSystemPath(NULL,str,kCFURLPOSIXPathStyle,true); + CFRelease(str); + + bundleinst=(void *)CFBundleCreate(NULL,r); + CFRelease(r); + + if (bundleinst) + { + CFURLRef executableURL = CFBundleCopyExecutableURL((CFBundleRef)bundleinst); + char path[PATH_MAX]; + path[0]=0; + if (executableURL) + { + if (!CFURLGetFileSystemRepresentation(executableURL, true, (UInt8*)path, sizeof(path))) path[0]=0; + CFRelease(executableURL); + } + + if (path[0]) + { + + inst=dlopen(path,RTLD_NOW|(symbolsAsGlobals?RTLD_GLOBAL:RTLD_LOCAL)); + if (!inst) + { + CFRelease(bundleinst); + return 0; + } + } + } + } +#endif + + if (!inst && !bundleinst) + { + inst=dlopen(fn,RTLD_NOW|(symbolsAsGlobals?RTLD_GLOBAL:RTLD_LOCAL)); + if (!inst) return 0; + } + + WDL_MutexLock lock(&s_libraryMutex); + + SWELL_HINSTANCE *rec = s_loadedLibs.Get(bundleinst ? bundleinst : inst); + if (!rec) + { + rec = (SWELL_HINSTANCE *)calloc(sizeof(SWELL_HINSTANCE),1); + rec->instptr = inst; + rec->bundleinstptr = bundleinst; + rec->refcnt = 1; + s_loadedLibs.Insert(bundleinst ? bundleinst : inst,rec); + + int (*SWELL_dllMain)(HINSTANCE, DWORD, LPVOID) = 0; + BOOL (*dllMain)(HINSTANCE, DWORD, LPVOID) = 0; + *(void **)&SWELL_dllMain = GetProcAddress(rec,"SWELL_dllMain"); + if (SWELL_dllMain) + { + void *SWELLAPI_GetFunc(const char *name); + + if (!SWELL_dllMain(rec,DLL_PROCESS_ATTACH,(void*)NULL)) // todo: eventually pass SWELLAPI_GetFunc, maybe? + { + FreeLibrary(rec); + return 0; + } + *(void **)&dllMain = GetProcAddress(rec,"DllMain"); + if (dllMain) + { + if (!dllMain(rec,DLL_PROCESS_ATTACH,NULL)) + { + SWELL_dllMain(rec,DLL_PROCESS_DETACH,(void*)NULL); + FreeLibrary(rec); + return 0; + } + } + } + rec->SWELL_dllMain = SWELL_dllMain; + rec->dllMain = dllMain; + } + else rec->refcnt++; + + return rec; +} + +void *GetProcAddress(HINSTANCE hInst, const char *procName) +{ + if (!hInst) return 0; + + SWELL_HINSTANCE *rec=(SWELL_HINSTANCE*)hInst; + + void *ret = NULL; +#ifdef __APPLE__ + if (rec->bundleinstptr) + { + CFStringRef str=(CFStringRef)SWELL_CStringToCFString(procName); + ret = (void *)CFBundleGetFunctionPointerForName((CFBundleRef)rec->bundleinstptr, str); + if (ret) rec->lastSymbolRequested=ret; + CFRelease(str); + return ret; + } +#endif + if (rec->instptr) ret=(void *)dlsym(rec->instptr, procName); + if (ret) rec->lastSymbolRequested=ret; + return ret; +} + +BOOL FreeLibrary(HINSTANCE hInst) +{ + if (!hInst) return FALSE; + + WDL_MutexLock lock(&s_libraryMutex); + + bool dofree=false; + SWELL_HINSTANCE *rec=(SWELL_HINSTANCE*)hInst; + if (--rec->refcnt<=0) + { + dofree=true; + s_loadedLibs.Delete(rec->bundleinstptr ? rec->bundleinstptr : rec->instptr); + + if (rec->SWELL_dllMain) + { + rec->SWELL_dllMain(rec,DLL_PROCESS_DETACH,NULL); + if (rec->dllMain) rec->dllMain(rec,DLL_PROCESS_DETACH,NULL); + } + + } + +#ifdef __APPLE__ + if (rec->bundleinstptr) CFRelease((CFBundleRef)rec->bundleinstptr); +#endif + if (rec->instptr) dlclose(rec->instptr); + + if (dofree) free(rec); + return TRUE; +} + +DWORD GetModuleFileName(HINSTANCE hInst, char *fn, DWORD nSize) +{ + *fn=0; + + void *instptr = NULL, *bundleinstptr=NULL, *lastSymbolRequested=NULL; + if (hInst) + { + SWELL_HINSTANCE *p = (SWELL_HINSTANCE*)hInst; + instptr = p->instptr; + bundleinstptr = p->bundleinstptr; + lastSymbolRequested=p->lastSymbolRequested; + } +#ifdef __APPLE__ + if (!instptr || bundleinstptr) + { + CFBundleRef bund=bundleinstptr ? (CFBundleRef)bundleinstptr : CFBundleGetMainBundle(); + if (bund) + { + CFURLRef url=CFBundleCopyBundleURL(bund); + if (url) + { + char buf[8192]; + if (CFURLGetFileSystemRepresentation(url,true,(UInt8*)buf,sizeof(buf))) lstrcpyn(fn,buf,nSize); + CFRelease(url); + } + } + return strlen(fn); + } +#else + if (!instptr) // get exe file name + { + char tmp[64]; + sprintf(tmp,"/proc/%d/exe",getpid()); + int sz=readlink(tmp,fn,nSize); + if (sz<0)sz=0; + else if (sz>=nSize)sz=nSize-1; + fn[sz]=0; + return sz; + } +#endif + + if (instptr && lastSymbolRequested) + { + Dl_info inf={0,}; + dladdr(lastSymbolRequested,&inf); + if (inf.dli_fname) + { + lstrcpyn(fn,inf.dli_fname,nSize); + return strlen(fn); + } + } + return 0; +} + +#ifdef __APPLE__ + +void SWELL_GenerateGUID(void *g) +{ + CFUUIDRef r = CFUUIDCreate(NULL); + if (r) + { + CFUUIDBytes a = CFUUIDGetUUIDBytes(r); + if (g) memcpy(g,&a,16); + CFRelease(r); + } +} + +#endif + + +#endif diff --git a/WDL/swell/swell.h b/WDL/swell/swell.h new file mode 100644 index 00000000..08c7a47c --- /dev/null +++ b/WDL/swell/swell.h @@ -0,0 +1,147 @@ +/* Cockos SWELL (Simple/Small Win32 Emulation Layer for L****) + Copyright (C) 2006-2010, Cockos, Inc. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms. + + */ + + +#ifndef _WIN32 + + +#ifndef _WDL_SWELL_H_ // here purely for apps/other libraries (dirscan.h uses it), each section actually has its own define +#define _WDL_SWELL_H_ + + +#ifdef __APPLE__ +#define SWELL_TARGET_OSX +#define SWELL_TARGET_OSX_COCOA +#endif + +// for swell*generic +// #define SWELL_TARGET_GDK +// #define SWELL_LICE_GDI + +#endif + +#ifdef __APPLE__ +// go ahead and get this included before we define FSHIFT in swell-types.h +#include +#endif + +// IF YOU ADD TO SWELL: +// Adding types, defines, etc: add to swell-types.h +// Adding functions: put them in swell-functions.h + + +#include "swell-types.h" +#include "swell-functions.h" + + +#ifndef SWELL_PROVIDED_BY_APP +#ifndef _WDL_SWELL_H_UTIL_DEFINED_ +#define _WDL_SWELL_H_UTIL_DEFINED_ + +// these should never be called directly!!! put SWELL_POSTMESSAGE_DELEGATE_IMPL in your nsapp delegate, and call SWELL_POSTMESSAGE_INIT at some point from there too + +#define SWELL_POSTMESSAGE_INIT SWELL_Internal_PostMessage_Init(); +#define SWELL_POSTMESSAGE_DELEGATE_IMPL \ + -(bool)swellPostMessage:(HWND)dest msg:(int)message wp:(WPARAM)wParam lp:(LPARAM)lParam { \ + return SWELL_Internal_PostMessage(dest,message,wParam,lParam); \ + } \ + -(void)swellPostMessageClearQ:(HWND)dest { \ + SWELL_Internal_PMQ_ClearAllMessages(dest); \ + } \ + -(void)swellPostMessageTick:(id)sender { \ + SWELL_MessageQueue_Flush(); \ + } + +BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd); + + +// if you use this then include swell-appstub.mm in your project +#define SWELL_APPAPI_DELEGATE_IMPL \ + -(void *)swellGetAPPAPIFunc { \ + void *SWELLAPI_GetFunc(const char *name); \ + return (void*)SWELLAPI_GetFunc; \ + } + +#endif // _WDL_SWELL_H_UTIL_DEFINED_ +#endif // !SWELL_PROVIDED_BY_APP + +#endif // !_WIN32 + + +#ifndef SWELL_TARGET_OSX + +#ifndef SWELL_CB_InsertString + +#define SWELL_CB_InsertString(hwnd, idx, pos, str) SendDlgItemMessage(hwnd,idx,CB_INSERTSTRING,(pos),(LPARAM)(str)) +#define SWELL_CB_AddString(hwnd, idx, str) SendDlgItemMessage(hwnd,idx,CB_ADDSTRING,0,(LPARAM)(str)) +#define SWELL_CB_SetCurSel(hwnd,idx,val) SendDlgItemMessage(hwnd,idx,CB_SETCURSEL,(WPARAM)(val),0) +#define SWELL_CB_GetNumItems(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_GETCOUNT,0,0) +#define SWELL_CB_GetCurSel(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_GETCURSEL,0,0) +#define SWELL_CB_SetItemData(hwnd,idx,item,val) SendDlgItemMessage(hwnd,idx,CB_SETITEMDATA,(item),(val)) +#define SWELL_CB_GetItemData(hwnd,idx,item) SendDlgItemMessage(hwnd,idx,CB_GETITEMDATA,(item),0) +#define SWELL_CB_GetItemText(hwnd,idx,item,buf,bufsz) SendDlgItemMessage(hwnd,idx,CB_GETLBTEXT,(item),(LPARAM)(buf)) +#define SWELL_CB_Empty(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_RESETCONTENT,0,0) +#define SWELL_CB_DeleteString(hwnd,idx,str) SendDlgItemMessage(hwnd,idx,CB_DELETESTRING,str,0) + +#define SWELL_TB_SetPos(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx, TBM_SETPOS,TRUE,(pos)) +#define SWELL_TB_SetRange(hwnd, idx, low, hi) SendDlgItemMessage(hwnd,idx,TBM_SETRANGE,TRUE,(LPARAM)MAKELONG((low),(hi))) +#define SWELL_TB_GetPos(hwnd, idx) SendDlgItemMessage(hwnd,idx,TBM_GETPOS,0,0) +#define SWELL_TB_SetTic(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx,TBM_SETTIC,0,(pos)) + +#endif + +#endif// !SWELL_TARGET_OSX + + + + +#ifndef WDL_GDP_CTX // stupid GDP compatibility layer, deprecated + + +#define WDL_GDP_CTX HDC +#define WDL_GDP_PEN HPEN +#define WDL_GDP_BRUSH HBRUSH +#define WDL_GDP_CreatePen(col, wid) (WDL_GDP_PEN)CreatePen(PS_SOLID,(wid),(col)) +#define WDL_GDP_DeletePen(pen) DeleteObject((HGDIOBJ)(pen)) +#define WDL_GDP_SetPen(ctx, pen) ((WDL_GDP_PEN)SelectObject(ctx,(HGDIOBJ)(pen))) +#define WDL_GDP_SetBrush(ctx, brush) ((WDL_GDP_BRUSH)SelectObject(ctx,(HGDIOBJ)(brush))) +#define WDL_GDP_CreateBrush(col) (WDL_GDP_BRUSH)CreateSolidBrush(col) +#define WDL_GDP_DeleteBrush(brush) DeleteObject((HGDIOBJ)(brush)) +#define WDL_GDP_FillRectWithBrush(hdc,r,br) FillRect(hdc,r,(HBRUSH)(br)) +#define WDL_GDP_Rectangle(hdc,l,t,r,b) Rectangle(hdc,l,t,r,b) +#define WDL_GDP_Polygon(hdc,pts,n) Polygon(hdc,pts,n) +#define WDL_GDP_MoveToEx(hdc,x,y,op) MoveToEx(hdc,x,y,op) +#define WDL_GDP_LineTo(hdc,x,y) LineTo(hdc,x,y) +#define WDL_GDP_PutPixel(hdc,x,y,c) SetPixel(hdc,x,y,c) +#define WDL_GDP_PolyBezierTo(hdc,p,np) PolyBezierTo(hdc,p,np) + +#define SWELL_SyncCtxFrameBuffer(x) // no longer used + +#endif + +#if defined(_WIN32) && !defined(LoadLibraryGlobals) +#define LoadLibraryGlobals(a,b) LoadLibrary(a) +#endif + diff --git a/WDL/swell/swellappmain.h b/WDL/swell/swellappmain.h new file mode 100644 index 00000000..5069860f --- /dev/null +++ b/WDL/swell/swellappmain.h @@ -0,0 +1,14 @@ +#import + + +@interface SWELLApplication : NSApplication { + +} +- (void)sendEvent:(NSEvent *)anEvent; + +@end + +@interface SWELLAppController : NSObject { +} +-(IBAction)onSysMenuCommand:(id)sender; +@end \ No newline at end of file diff --git a/WDL/swell/swellappmain.mm b/WDL/swell/swellappmain.mm new file mode 100644 index 00000000..3c434aa9 --- /dev/null +++ b/WDL/swell/swellappmain.mm @@ -0,0 +1,232 @@ +#import "swellappmain.h" + +#include "swell.h" +#include "swell-internal.h" + + +HMENU SWELL_app_stocksysmenu; // exposed to app, simply the contents of the default system menu (as defined in the nib) +static bool IsMultiLineEditControl(NSView *cv, id fs) +{ + if (fs && [fs isKindOfClass:[NSTextView class]]) + { + NSTextView *v = (NSTextView *)fs; + if ([v isEditable]) + { + NSView *a=[v superview]; + while (a && a != cv) + { + if ([a isKindOfClass:[NSTextField class]]) return false; + a = [a superview]; + } + return true; + } + } + return false; +} + +@implementation SWELLApplication +- (void)sendEvent:(NSEvent *)anEvent +{ + int etype = [anEvent type]; + if (etype == NSKeyUp) + { + // toss keyup if next keydown is the same key + NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE]; + if (nextDown && [nextDown keyCode] == [anEvent keyCode]) return; + } + else if (etype == NSKeyDown) + { + NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE]; + if (nextDown && [nextDown keyCode] == [anEvent keyCode]) + { +#if 0 + // no need to check timestamps -- if a queued key is there, just ignore this one(prevent a backlog) + static double sc=0.0; + if (sc == 0.0) + { + struct mach_timebase_info inf={0,}; + mach_timebase_info(&inf); + if (inf.numer && inf.denom) sc = inf.numer / (inf.denom * 1000.0 * 1000.0 * 1000.0); + } + + if (sc != 0.0 && [anEvent timestamp] < (double) mach_absolute_time() * sc - 0.05) +#endif + return; + } + } + + + NSWindow *modalWindow = [NSApp modalWindow]; + + NSWindow *focwnd=[anEvent window]; + NSView *dest_view=NULL; // only valid when key message + + if (etype==NSKeyDown||etype==NSKeyUp) + { + int msgtype = etype==NSKeyDown ? WM_KEYDOWN : WM_KEYUP; + int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag); + + if (focwnd) + { + if (flag&(FCONTROL|FALT)) + { + NSWindow *f = focwnd; + // handle carbon windows, sending all cmd/alt modified keys to their parent NSView (to be handled later) + // perhaps it'd be good to have a flag on these to see if they want it .. i.e. SWELL_SetCarbonHostView_WantKeyFlgs().. + while (f) + { + if ((dest_view=[f delegate]) && [dest_view respondsToSelector:@selector(swellIsCarbonHostingView)] && [(SWELL_hwndCarbonHost*)dest_view swellIsCarbonHostingView]) + { + focwnd = [dest_view window]; + break; + } + dest_view=0; + f=[f parentWindow]; + } + } + if (!dest_view) // get default dest_view, and validate it as a NSView + { + if ((dest_view=(NSView *)[focwnd firstResponder]) && ![dest_view isKindOfClass:[NSView class]]) dest_view=NULL; + } + } + if (!modalWindow && (!focwnd || dest_view)) + { + MSG msg={(HWND)dest_view,msgtype,(WPARAM)code,(LPARAM)flag}; // LPARAM is treated differently (giving modifier flags/FVIRTKEY etc) in sWELL's WM_KEYDOWN than in windows, deal with it + + if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE,(INT_PTR)&msg,(INT_PTR)anEvent)>0) return; + } + } + // default window handling: + if (etype == NSKeyDown && focwnd && dest_view) + { + NSView *cv = [focwnd contentView]; + if (cv && [cv respondsToSelector:@selector(onSwellMessage:p1:p2:)]) //only work for swell windows + { + int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag); + int cmdid=0; + + // todo: other keys (such as shift+insert?) + if (((flag&~FVIRTKEY)==FCONTROL && (code=='V'||code=='C' ||code=='X')) && [dest_view isKindOfClass:[NSText class]]) + { + if (code=='V') [(NSText *)dest_view paste:(id)cv]; + else if (code=='C') [(NSText *)dest_view copy:(id)cv]; + else if (code=='X') [(NSText *)dest_view cut:(id)cv]; + return; + } + + if ((!(flag&~(FVIRTKEY|FSHIFT)) && code == VK_ESCAPE) || + ((flag&~FVIRTKEY)==FCONTROL && code=='W')) + { + if (code == 'W') cmdid= IDCANCEL; // cmd+w always idcancel's + else if (!dest_view || ![dest_view isKindOfClass:[NSTextView class]]) cmdid=IDCANCEL; // not text view, idcancel + else if (!(flag&FSHIFT) && !IsMultiLineEditControl(cv,dest_view)) cmdid=IDCANCEL; // if singleline edit and shift not set, idcancel + + if (!cmdid) + { + SetFocus((HWND)cv); + return; + } + } + else if (!(flag&~FVIRTKEY) && code == VK_RETURN) + { + // get default button command id, if any, if enabled + if (!IsMultiLineEditControl(cv,dest_view)) + { + cmdid = SWELL_GetDefaultButtonID((HWND)cv,true); + + if (!cmdid) // no action, set focus to parent + { + SetFocus((HWND)cv); + return; + } + } + } + + if (cmdid) + { + SendMessage((HWND)cv,WM_COMMAND,cmdid,0); + return; + } + } // is swell CV + } // key down + + [super sendEvent:anEvent]; +} +@end + + +@implementation SWELLAppController + +- (void)awakeFromNib +{ + SWELL_EnsureMultithreadedCocoa(); + [NSApp setDelegate:self]; + + SWELL_POSTMESSAGE_INIT + + HMENU stockMenu=(HMENU)[NSApp mainMenu]; + if (stockMenu) + { + HMENU nf = GetSubMenu(stockMenu,0); + if (nf) SWELL_app_stocksysmenu = SWELL_DuplicateMenu(nf); + } + + SWELLAppMain(SWELLAPP_ONLOAD,0,0); +} + +-(IBAction)onSysMenuCommand:(id)sender +{ + int a = [sender tag]; + if (a) SWELLAppMain(SWELLAPP_ONCOMMAND,a,(INT_PTR)sender); +} + +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + char buf[4096]; + buf[0]=0; + SWELL_CFStringToCString(filename,buf,sizeof(buf)); + return buf[0] && SWELLAppMain(SWELLAPP_OPENFILE,(INT_PTR)buf,0)>0; +} +- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication +{ + return SWELLAppMain(SWELLAPP_NEWFILE,0,0)>0; +} + +- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender +{ + return SWELLAppMain(SWELLAPP_SHOULDOPENNEWFILE,0,0)>0; +} + +-(void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + SWELLAppMain(SWELLAPP_LOADED,0,0); +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + return SWELLAppMain(SWELLAPP_SHOULDDESTROY,0,0) > 0 ? NSTerminateLater : NSTerminateNow; +} + +- (void)applicationWillTerminate:(NSNotification *)notification +{ + SWELLAppMain(SWELLAPP_DESTROY,0,0); +} + +- (void)applicationDidBecomeActive:(NSNotification *)aNotification +{ + if (!SWELLAppMain(SWELLAPP_ACTIVATE,TRUE,0)) + SWELL_BroadcastMessage(WM_ACTIVATEAPP,TRUE,0); +} + +- (void)applicationDidResignActive:(NSNotification *)aNotification +{ + if (!SWELLAppMain(SWELLAPP_ACTIVATE,FALSE,0)) + SWELL_BroadcastMessage(WM_ACTIVATEAPP,FALSE,0); +} + +SWELL_APPAPI_DELEGATE_IMPL + +SWELL_POSTMESSAGE_DELEGATE_IMPL + + +@end diff --git a/WDL/swell/test-gtk.cpp b/WDL/swell/test-gtk.cpp new file mode 100644 index 00000000..6f897d39 --- /dev/null +++ b/WDL/swell/test-gtk.cpp @@ -0,0 +1,16 @@ +#include + +int main( int argc, + char *argv[] ) +{ + GtkWidget *window; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + + gtk_main (); + + return 0; +} diff --git a/WDL/swell/test.cpp b/WDL/swell/test.cpp new file mode 100644 index 00000000..ece030fa --- /dev/null +++ b/WDL/swell/test.cpp @@ -0,0 +1,7 @@ +#include "swell.h" + +int main() +{ + MessageBox(NULL,"hello world","a",0); + return 0; +} diff --git a/WDL/swell/windows.h b/WDL/swell/windows.h new file mode 100644 index 00000000..2927ef7f --- /dev/null +++ b/WDL/swell/windows.h @@ -0,0 +1,165 @@ +#ifndef _SWELL_WINDOWS_H_ +#define _SWELL_WINDOWS_H_ + +#ifdef _WIN32 +#include +#else +#include "swell.h" + + +#define BIF_RETURNONLYFSDIRS 0x0001 +#define BIF_DONTGOBELOWDOMAIN 0x0002 +#define BIF_STATUSTEXT 0x0004 +#define BIF_RETURNFSANCESTORS 0x0008 +#define BIF_EDITBOX 0x0010 +#define BIF_VALIDATE 0x0020 + +#define BIF_BROWSEFORCOMPUTER 0x1000 +#define BIF_BROWSEFORPRINTER 0x2000 +#define BIF_BROWSEINCLUDEFILES 0x4000 + +#define BFFM_INITIALIZED 1 +#define BFFM_SELCHANGED 2 +typedef int (CALLBACK* BFFCALLBACK)(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData); + +typedef struct __ITEMIDLIST ITEMIDLIST; +typedef const ITEMIDLIST *LPCITEMIDLIST; + +typedef struct _browseinfoA { + HWND hwndOwner; + LPCITEMIDLIST pidlRoot; + LPSTR pszDisplayName; + LPCSTR lpszTitle; + UINT ulFlags; + BFFCALLBACK lpfn; + LPARAM lParam; + int iImage; +} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; + +#ifdef __cplusplus +class IMalloc +{ + public: + void Release() { delete this; } + void Free(void *p) { free(p); } +}; +#define SHGetMalloc(x) { *(x) = new IMalloc; } +#define SHGetPathFromIDList(src,dest) { if (src) {lstrcpyn(dest,(char *)src,MAX_PATH); } else *dest=0; } +#endif + +SWELL_API_DEFINE(ITEMIDLIST *, SHBrowseForFolder, (LPBROWSEINFO)) + +#define BFFM_SETSELECTION (WM_USER + 102) + +#define Shell_NotifyIcon(a,b) (0) +#define PostQuitMessage(x) { /* todo: mac quit message*/ } +#define SetClassLong(a,b,c) (0) +#define LoadIcon(a,b) ((HICON)0) +#define IsIconic(x) (0) +#define IsWindowEnabled(x) (1) +#define TrackPopupMenuEx(a,b,c,d,e,f) TrackPopupMenu(a,b,c,d,0,e,NULL) +#endif + +typedef UINT (CALLBACK *LPOFNHOOKPROC) (HWND, UINT, WPARAM, LPARAM); + +typedef struct tagOFNA { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCSTR lpstrFilter; + LPSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPSTR lpstrFile; + DWORD nMaxFile; + LPSTR lpstrFileTitle; + DWORD nMaxFileTitle; + LPCSTR lpstrInitialDir; + LPCSTR lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + LPCSTR lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + LPCSTR lpTemplateName; +} OPENFILENAME, *LPOPENFILENAME; + + +SWELL_API_DEFINE(BOOL,GetOpenFileName,(LPOPENFILENAME)); +SWELL_API_DEFINE(BOOL,GetSaveFileName,(LPOPENFILENAME)); + +#define OFN_READONLY 0x00000001 +#define OFN_OVERWRITEPROMPT 0x00000002 +#define OFN_HIDEREADONLY 0x00000004 +#define OFN_NOCHANGEDIR 0x00000008 +#define OFN_SHOWHELP 0x00000010 +#define OFN_ENABLEHOOK 0x00000020 +#define OFN_ENABLETEMPLATE 0x00000040 +#define OFN_ENABLETEMPLATEHANDLE 0x00000080 +#define OFN_NOVALIDATE 0x00000100 +#define OFN_ALLOWMULTISELECT 0x00000200 +#define OFN_EXTENSIONDIFFERENT 0x00000400 +#define OFN_PATHMUSTEXIST 0x00000800 +#define OFN_FILEMUSTEXIST 0x00001000 +#define OFN_CREATEPROMPT 0x00002000 +#define OFN_SHAREAWARE 0x00004000 +#define OFN_NOREADONLYRETURN 0x00008000 +#define OFN_NOTESTFILECREATE 0x00010000 +#define OFN_NONETWORKBUTTON 0x00020000 +#define OFN_NOLONGNAMES 0x00040000 +#define OFN_EXPLORER 0x00080000 +#define OFN_NODEREFERENCELINKS 0x00100000 +#define OFN_LONGNAMES 0x00200000 +#define OFN_ENABLEINCLUDENOTIFY 0x00400000 +#define OFN_ENABLESIZING 0x00800000 + + +#define MB_ICONHAND 0x00000010L +#define MB_ICONQUESTION 0x00000020L +#define MB_ICONEXCLAMATION 0x00000030L +#define MB_ICONASTERISK 0x00000040L + +typedef struct _SHELLEXECUTEINFOA +{ + DWORD cbSize; + ULONG fMask; + HWND hwnd; + LPCSTR lpVerb; + LPCSTR lpFile; + LPCSTR lpParameters; + LPCSTR lpDirectory; + int nShow; + HINSTANCE hInstApp; +} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO; + + +SWELL_API_DEFINE(BOOL, ShellExecuteEx,(LPSHELLEXECUTEINFO lpExecInfo)); +SWELL_API_DEFINE(BOOL,WriteFile,(HANDLE,void *, DWORD, DWORD *lenOut, void *ovl)) +SWELL_API_DEFINE(BOOL,ReadFile,(HANDLE,void *, DWORD, DWORD *lenOut, void *ovl)) +SWELL_API_DEFINE(HANDLE,CreateFile,( const char * lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,void *lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)) +SWELL_API_DEFINE(DWORD,SetFilePointer,(HANDLE, DWORD low, DWORD *high)) +SWELL_API_DEFINE(DWORD,GetFilePointer,(HANDLE, DWORD *high)) +SWELL_API_DEFINE(DWORD,GetFileSize,(HANDLE, DWORD *high)) + +#define InitCommonControls() { } +#define CoInitialize(x) { } + +/* +#define IsDialogMessage(wnd,a) (0) +#define TranslateMessage(a) { } +#define DispatchMessage(a) { } +*/ + +#define INVALID_HANDLE_VALUE ((HANDLE)((unsigned int)-1)) + +#define RemoveDirectory(x) (!rmdir(x)) + +#define CharNext(x) ((x)+1) +#define CharPrev(base,x) ( (x)>(base)?(x)-1:(base)) +#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n') + +#define lstrcpyA strcpy +#define lstrcpynA lstrcpyn + +#endif diff --git a/WDL/timing.c b/WDL/timing.c new file mode 100644 index 00000000..2871feb5 --- /dev/null +++ b/WDL/timing.c @@ -0,0 +1,85 @@ +#include "timing.h" + +#ifdef TIMING + +#include +#ifdef _WIN32 +#include +#endif + +static struct { + __int64 st_time; + __int64 cycles,mint,maxt; + int foo; + int calls; +} timingInfo[64]; + + +static void rdtsc(__int64 *t) +{ +#ifdef _WIN64 + LARGE_INTEGER now; + QueryPerformanceCounter(&now); + *t = now.QuadPart; +#else + __asm + { + mov esi, t + _emit 0xf + _emit 0x31 + mov [esi], eax + mov [esi+4], edx + } +#endif +} + +void _timingInit(void) +{ + memset(timingInfo,0,sizeof(timingInfo)); +} + +void _timingEnter(int which) +{ + rdtsc(&timingInfo[which].st_time); +} + +void _timingLeave(int which) +{ + __int64 t; + rdtsc(&t); + t -= timingInfo[which].st_time; + if (!timingInfo[which].mint || t < timingInfo[which].mint) timingInfo[which].mint=t?t:1; + if (t > timingInfo[which].maxt) timingInfo[which].maxt=t; + timingInfo[which].cycles += t; + timingInfo[which].calls += 1; +} + +void _timingPrint(void) +{ + int x,p=0; + for (x = 0; x < sizeof(timingInfo)/sizeof(timingInfo[0]); x ++) + { + char buf[512]; + if (timingInfo[x].calls) + { + p++; + sprintf(buf,"%d: %d calls, %.4f clocks/call (min=%.4f, max=%.4f). %.8f thingies of CPU time spent\n", + x,timingInfo[x].calls,(timingInfo[x].cycles/(double)timingInfo[x].calls), + (double)timingInfo[x].mint,(double)timingInfo[x].maxt, + (double)timingInfo[x].cycles +#ifdef _WIN64 + / 1000000.0 +#else + / (2.4*1000.0*1000.0*1000.0) +#endif + + ); + OutputDebugString(buf); + } + } + if (!p) OutputDebugString("no calls to timing lib\n"); + + timingInit(); +} + +#endif diff --git a/WDL/timing.h b/WDL/timing.h new file mode 100644 index 00000000..00781ee3 --- /dev/null +++ b/WDL/timing.h @@ -0,0 +1,43 @@ +/* + WDL - timing.h + + this is based on some public domain Pentium RDTSC timing code from usenet in 1996. + + To enable this, your app must #define TIMING, include timing.h, call timingInit(), then timingEnter(x)/timingLeave(x) a bunch + of times (where x is 0-64), then timingPrint at the end. + + on timingPrint(), C:\\timings.txt will be overwritten. + +*/ + +#ifndef _TIMING_H_ +#define _TIMING_H_ + + +//#define TIMING + + + +#if defined(TIMING) && !defined(__alpha) +#ifdef __cplusplus +extern "C" { +#endif +void _timingInit(void); +void _timingPrint(void); +void _timingEnter(int); +void _timingLeave(int); +#ifdef __cplusplus +} +#endif +#define timingPrint() _timingPrint() +#define timingInit() _timingInit() +#define timingLeave(x) _timingLeave(x) +#define timingEnter(x) _timingEnter(x) +#else +#define timingPrint() +#define timingInit() +#define timingLeave(x) +#define timingEnter(x) +#endif + +#endif \ No newline at end of file diff --git a/WDL/tinyxml/libxml_tinyxml.cpp b/WDL/tinyxml/libxml_tinyxml.cpp new file mode 100644 index 00000000..595cdce7 --- /dev/null +++ b/WDL/tinyxml/libxml_tinyxml.cpp @@ -0,0 +1,132 @@ +#include "libxml_tinyxml.h" +#include "tinyxml.h" + +xmlAttr* MakeAttrList(const TiXmlAttribute* attr) +{ + xmlAttr* xattr = 0; + if (attr) + { + xattr = new xmlAttr; + memset(xattr, 0, sizeof(xmlAttr)); + + xattr->name = attr->Name(); + xattr->content = attr->Value(); + + // svgtiny expect xattr->children to be a pointer back to the attribute, + // though in libxml it is supposed to always be NULL + xattr->children = xattr; + + xattr->next = MakeAttrList(attr->Next()); + } + return xattr; +} + +xmlNode* MakeNodeTree(TiXmlNode* node) +{ + xmlNode* xnode = 0; + if (node) + { + xnode = new xmlNode; + memset(xnode, 0, sizeof(xmlNode)); + + int type = node->Type(); + if (type == TiXmlNode::ELEMENT) + { + xnode->type = XML_ELEMENT_NODE; + xnode->name = node->Value(); + const TiXmlElement* elem = node->ToElement(); + if (elem) xnode->properties = MakeAttrList(elem->FirstAttribute()); + } + else if (type == TiXmlNode::TEXT) + { + xnode->type = XML_TEXT_NODE; + xnode->content = node->Value(); + } + else xnode->type = 0; + + xnode->children = MakeNodeTree(node->FirstChild()); + xnode->next = MakeNodeTree(node->NextSibling()); + } + return xnode; +} + + +xmlDoc* xmlReadMemory(const char* buffer, size_t size, const char* url, const char* encoding, int flags) +{ + if (buffer[size] != 0 || strlen(buffer) != size) return 0; + + if (!url) url = ""; + TiXmlDocument* doc = new TiXmlDocument(url); + doc->Parse(buffer); + if (doc->Error()) + { + delete(doc); + doc = 0; + } + + xmlDoc* xdoc = 0; + if (doc) + { + xdoc = new xmlDoc; + memset(xdoc, 0, sizeof(xmlDoc)); + xdoc->tinyxml_obj = doc; + xdoc->children = MakeNodeTree((TiXmlNode*) doc->RootElement()); + } + return xdoc; +} + +xmlNode* xmlDocGetRootElement(xmlDoc* xdoc) +{ + xmlNode* xnode = 0; + if (xdoc) xnode = xdoc->children; + return xnode; +} + +xmlAttr* xmlHasProp(xmlNode* xnode, const xmlChar* name) +{ + xmlAttr* xattr = 0; + if (xnode && name && name[0]) + { + xattr = xnode->properties; +#ifdef _WIN32 + while (xattr && (!xattr->name || stricmp(xattr->name, name))) xattr = xattr->next; +#else + while (xattr && (!xattr->name || strcasecmp(xattr->name, name))) xattr = xattr->next; +#endif + } + return xattr; +} + +xmlChar* xmlGetProp(xmlNode* xnode, const xmlChar* name) +{ + xmlChar* xcontent = 0; + xmlAttr* xattr = xmlHasProp(xnode, name); + if (xattr) xcontent = strdup(xattr->content); + return xcontent; +} + +void xmlFree(xmlChar* str) +{ + free(str); +} + +void xmlFreeDoc(xmlDoc* xdoc) +{ + if (xdoc) + { + delete((TiXmlDocument*)xdoc->tinyxml_obj); + xdoc->tinyxml_obj = 0; + // todo make sure tinyxmldoc owns all its nodes + xdoc->children = 0; + } +} + + +char* strndup(const char* s, size_t size) +{ + // no doubt the real strndup protects against s not being null-terminated + if (size < strlen(s)) size = strlen(s); + char* t = (char*) malloc(size+1); + strncpy(t, s, size); // strncpy should be ok since we checked size + return t; +} \ No newline at end of file diff --git a/WDL/tinyxml/libxml_tinyxml.h b/WDL/tinyxml/libxml_tinyxml.h new file mode 100644 index 00000000..9186c16e --- /dev/null +++ b/WDL/tinyxml/libxml_tinyxml.h @@ -0,0 +1,52 @@ +#ifndef LIBXML_TINYXML +#define LIBXML_TINYXML + +// libxml interface, tinyxml implementation + +#include + +enum { XML_PARSE_NONET=1, XML_PARSE_COMPACT=2 }; +enum { XML_ELEMENT_NODE=1, XML_TEXT_NODE=2 }; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _xmlNode +{ + void* tinyxml_obj; + unsigned short line; + int type; + const char* name; + const char* content; + struct _xmlNode* properties; + struct _xmlNode* children; + struct _xmlNode* next; +} xmlNode; + +typedef xmlNode xmlDoc; +typedef xmlNode xmlAttr; + +typedef char xmlChar; + + +xmlDoc* xmlReadMemory(const char* buffer, size_t size, const char* url, const char* encoding, int flags); + +xmlNode* xmlDocGetRootElement(xmlDoc* document); + +xmlAttr* xmlHasProp(xmlNode* node, const xmlChar* name); + +xmlChar* xmlGetProp(xmlNode* node, const xmlChar * name); // return is on the heap + +void xmlFree(xmlChar* str); + +void xmlFreeDoc(xmlDoc* document); + + +char* strndup(const char* s, size_t size); // argh + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/WDL/tinyxml/svgtiny_colors.c b/WDL/tinyxml/svgtiny_colors.c new file mode 100644 index 00000000..dc2a460b --- /dev/null +++ b/WDL/tinyxml/svgtiny_colors.c @@ -0,0 +1,955 @@ +/* ANSI-C code produced by gperf version 3.0.1 */ +/* Command-line: gperf colors.gperf */ +/* Computed positions: -k'1,3,6-8,12-13' */ + +#if 0 +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif +#endif + +//#line 15 "colors.gperf" + +#include +#include + +//#include "svgtiny.h" +//#include "svgtiny_internal.h" + +typedef int svgtiny_colour; // == LICE_pixel +#define svgtiny_RGB(r,g,b) (((b)&0xFF)|(((g)&0xFF)<<8)|(((r)&0xFF)<<16)|(0xFF<<24)) + +struct svgtiny_named_color +{ + const char *name; + svgtiny_colour color; +}; + +//#line 21 "colors.gperf" + +//struct svgtiny_named_color; + +#define TOTAL_KEYWORDS 147 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 20 +#define MIN_HASH_VALUE 4 +#define MAX_HASH_VALUE 565 +/* maximum key range = 562, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +svgtiny_color_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 5, 55, 0, + 35, 0, 75, 10, 5, 0, 566, 250, 10, 40, + 85, 60, 70, 144, 0, 20, 45, 10, 30, 185, + 95, 195, 566, 0, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + case 10: + case 9: + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + case 4: + case 3: + hval += asso_values[(unsigned char)str[2]+2]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +#ifdef __GNUC__ +__inline +#endif +const struct svgtiny_named_color * +svgtiny_color_lookup (register const char *str, register unsigned int len) +{ + static const struct svgtiny_named_color wordlist[] = + { +//#line 43 "colors.gperf" + {"cyan", svgtiny_RGB( 0, 255, 255)}, +//#line 76 "colors.gperf" + {"gray", svgtiny_RGB(128, 128, 128)}, +//#line 37 "colors.gperf" + {"chartreuse", svgtiny_RGB(127, 255, 0)}, +//#line 77 "colors.gperf" + {"grey", svgtiny_RGB(128, 128, 128)}, +//#line 78 "colors.gperf" + {"green", svgtiny_RGB( 0, 128, 0)}, +//#line 96 "colors.gperf" + {"lightgrey", svgtiny_RGB(211, 211, 211)}, +//#line 95 "colors.gperf" + {"lightgreen", svgtiny_RGB(144, 238, 144)}, +//#line 94 "colors.gperf" + {"lightgray", svgtiny_RGB(211, 211, 211)}, +//#line 152 "colors.gperf" + {"skyblue", svgtiny_RGB(135, 206, 235)}, +//#line 155 "colors.gperf" + {"slategrey", svgtiny_RGB(112, 128, 144)}, +//#line 150 "colors.gperf" + {"sienna", svgtiny_RGB(160, 82, 45)}, +//#line 154 "colors.gperf" + {"slategray", svgtiny_RGB(112, 128, 144)}, +//#line 149 "colors.gperf" + {"seashell", svgtiny_RGB(255, 245, 238)}, +//#line 160 "colors.gperf" + {"teal", svgtiny_RGB( 0, 128, 128)}, +//#line 39 "colors.gperf" + {"coral", svgtiny_RGB(255, 127, 80)}, +//#line 98 "colors.gperf" + {"lightsalmon", svgtiny_RGB(255, 160, 122)}, +//#line 102 "colors.gperf" + {"lightslategrey", svgtiny_RGB(119, 136, 153)}, +//#line 30 "colors.gperf" + {"black", svgtiny_RGB( 0, 0, 0)}, +//#line 101 "colors.gperf" + {"lightslategray", svgtiny_RGB(119, 136, 153)}, +//#line 128 "colors.gperf" + {"orange", svgtiny_RGB(255, 165, 0)}, +//#line 129 "colors.gperf" + {"orangered", svgtiny_RGB(255, 69, 0)}, +//#line 29 "colors.gperf" + {"bisque", svgtiny_RGB(255, 228, 196)}, +//#line 105 "colors.gperf" + {"lime", svgtiny_RGB( 0, 255, 0)}, +//#line 142 "colors.gperf" + {"red", svgtiny_RGB(255, 0, 0)}, +//#line 106 "colors.gperf" + {"limegreen", svgtiny_RGB( 50, 205, 50)}, +//#line 91 "colors.gperf" + {"lightcoral", svgtiny_RGB(240, 128, 128)}, +//#line 144 "colors.gperf" + {"royalblue", svgtiny_RGB( 65, 105, 225)}, +//#line 107 "colors.gperf" + {"linen", svgtiny_RGB(250, 240, 230)}, +//#line 71 "colors.gperf" + {"fuchsia", svgtiny_RGB(255, 0, 255)}, +//#line 48 "colors.gperf" + {"darkgreen", svgtiny_RGB( 0, 100, 0)}, +//#line 90 "colors.gperf" + {"lightblue", svgtiny_RGB(173, 216, 230)}, +//#line 54 "colors.gperf" + {"darkorchid", svgtiny_RGB(153, 50, 204)}, +//#line 157 "colors.gperf" + {"springgreen", svgtiny_RGB( 0, 255, 127)}, +//#line 108 "colors.gperf" + {"magenta", svgtiny_RGB(255, 0, 255)}, +//#line 74 "colors.gperf" + {"gold", svgtiny_RGB(255, 215, 0)}, +//#line 130 "colors.gperf" + {"orchid", svgtiny_RGB(218, 112, 214)}, +//#line 153 "colors.gperf" + {"slateblue", svgtiny_RGB(106, 90, 205)}, +//#line 51 "colors.gperf" + {"darkmagenta", svgtiny_RGB(139, 0, 139)}, +//#line 44 "colors.gperf" + {"darkblue", svgtiny_RGB( 0, 0, 139)}, +//#line 103 "colors.gperf" + {"lightsteelblue", svgtiny_RGB(176, 196, 222)}, +//#line 151 "colors.gperf" + {"silver", svgtiny_RGB(192, 192, 192)}, +//#line 148 "colors.gperf" + {"seagreen", svgtiny_RGB( 46, 139, 87)}, +//#line 158 "colors.gperf" + {"steelblue", svgtiny_RGB( 70, 130, 180)}, +//#line 159 "colors.gperf" + {"tan", svgtiny_RGB(210, 180, 140)}, +//#line 137 "colors.gperf" + {"peru", svgtiny_RGB(205, 133, 63)}, +//#line 141 "colors.gperf" + {"purple", svgtiny_RGB(128, 0, 128)}, +//#line 55 "colors.gperf" + {"darkred", svgtiny_RGB(139, 0, 0)}, +//#line 120 "colors.gperf" + {"mintcream", svgtiny_RGB(245, 255, 250)}, +//#line 68 "colors.gperf" + {"firebrick", svgtiny_RGB(178, 34, 34)}, +//#line 99 "colors.gperf" + {"lightseagreen", svgtiny_RGB( 32, 178, 170)}, +//#line 52 "colors.gperf" + {"darkolivegreen", svgtiny_RGB( 85, 107, 47)}, +//#line 121 "colors.gperf" + {"mistyrose", svgtiny_RGB(255, 228, 225)}, +//#line 83 "colors.gperf" + {"indigo", svgtiny_RGB( 75, 0, 130)}, +//#line 125 "colors.gperf" + {"oldlace", svgtiny_RGB(253, 245, 230)}, +//#line 138 "colors.gperf" + {"pink", svgtiny_RGB(255, 192, 203)}, +//#line 56 "colors.gperf" + {"darksalmon", svgtiny_RGB(233, 150, 122)}, +//#line 86 "colors.gperf" + {"lavender", svgtiny_RGB(230, 230, 250)}, +//#line 84 "colors.gperf" + {"ivory", svgtiny_RGB(255, 255, 240)}, +//#line 122 "colors.gperf" + {"moccasin", svgtiny_RGB(255, 228, 181)}, +//#line 36 "colors.gperf" + {"cadetblue", svgtiny_RGB( 95, 158, 160)}, +//#line 62 "colors.gperf" + {"darkviolet", svgtiny_RGB(148, 0, 211)}, +//#line 145 "colors.gperf" + {"saddlebrown", svgtiny_RGB(139, 69, 19)}, +//#line 58 "colors.gperf" + {"darkslateblue", svgtiny_RGB( 72, 61, 139)}, +//#line 132 "colors.gperf" + {"palegreen", svgtiny_RGB(152, 251, 152)}, +//#line 156 "colors.gperf" + {"snow", svgtiny_RGB(255, 250, 250)}, +//#line 82 "colors.gperf" + {"indianred", svgtiny_RGB(205, 92, 92)}, +//#line 93 "colors.gperf" + {"lightgoldenrodyellow", svgtiny_RGB(250, 250, 210)}, +//#line 162 "colors.gperf" + {"tomato", svgtiny_RGB(255, 99, 71)}, +//#line 89 "colors.gperf" + {"lemonchiffon", svgtiny_RGB(255, 250, 205)}, +//#line 97 "colors.gperf" + {"lightpink", svgtiny_RGB(255, 182, 193)}, +//#line 109 "colors.gperf" + {"maroon", svgtiny_RGB(128, 0, 0)}, +//#line 87 "colors.gperf" + {"lavenderblush", svgtiny_RGB(255, 240, 245)}, +//#line 163 "colors.gperf" + {"turquoise", svgtiny_RGB( 64, 224, 208)}, +//#line 53 "colors.gperf" + {"darkorange", svgtiny_RGB(255, 140, 0)}, +//#line 124 "colors.gperf" + {"navy", svgtiny_RGB( 0, 0, 128)}, +//#line 67 "colors.gperf" + {"dodgerblue", svgtiny_RGB( 30, 144, 255)}, +//#line 70 "colors.gperf" + {"forestgreen", svgtiny_RGB( 34, 139, 34)}, +//#line 119 "colors.gperf" + {"midnightblue", svgtiny_RGB( 25, 25, 112)}, +//#line 114 "colors.gperf" + {"mediumseagreen", svgtiny_RGB( 60, 179, 113)}, +//#line 57 "colors.gperf" + {"darkseagreen", svgtiny_RGB(143, 188, 143)}, +//#line 25 "colors.gperf" + {"aqua", svgtiny_RGB( 0, 255, 255)}, +//#line 27 "colors.gperf" + {"azure", svgtiny_RGB(240, 255, 255)}, +//#line 146 "colors.gperf" + {"salmon", svgtiny_RGB(250, 128, 114)}, +//#line 165 "colors.gperf" + {"wheat", svgtiny_RGB(245, 222, 179)}, +//#line 34 "colors.gperf" + {"brown", svgtiny_RGB(165, 42, 42)}, +//#line 26 "colors.gperf" + {"aquamarine", svgtiny_RGB(127, 255, 212)}, +//#line 38 "colors.gperf" + {"chocolate", svgtiny_RGB(210, 105, 30)}, +//#line 88 "colors.gperf" + {"lawngreen", svgtiny_RGB(124, 252, 0)}, +//#line 147 "colors.gperf" + {"sandybrown", svgtiny_RGB(244, 164, 96)}, +//#line 92 "colors.gperf" + {"lightcyan", svgtiny_RGB(224, 255, 255)}, +//#line 164 "colors.gperf" + {"violet", svgtiny_RGB(238, 130, 238)}, +//#line 104 "colors.gperf" + {"lightyellow", svgtiny_RGB(255, 255, 224)}, +//#line 111 "colors.gperf" + {"mediumblue", svgtiny_RGB( 0, 0, 205)}, +//#line 136 "colors.gperf" + {"peachpuff", svgtiny_RGB(255, 218, 185)}, +//#line 79 "colors.gperf" + {"greenyellow", svgtiny_RGB(173, 255, 47)}, +//#line 24 "colors.gperf" + {"antiquewhite", svgtiny_RGB(250, 235, 215)}, +//#line 32 "colors.gperf" + {"blue", svgtiny_RGB( 0, 0, 255)}, +//#line 118 "colors.gperf" + {"mediumvioletred", svgtiny_RGB(199, 21, 133)}, +//#line 113 "colors.gperf" + {"mediumpurple", svgtiny_RGB(147, 112, 219)}, +//#line 75 "colors.gperf" + {"goldenrod", svgtiny_RGB(218, 165, 32)}, +//#line 31 "colors.gperf" + {"blanchedalmond", svgtiny_RGB(255, 235, 205)}, +//#line 85 "colors.gperf" + {"khaki", svgtiny_RGB(240, 230, 140)}, +//#line 139 "colors.gperf" + {"plum", svgtiny_RGB(221, 160, 221)}, +//#line 112 "colors.gperf" + {"mediumorchid", svgtiny_RGB(186, 85, 211)}, +//#line 143 "colors.gperf" + {"rosybrown", svgtiny_RGB(188, 143, 143)}, +//#line 115 "colors.gperf" + {"mediumslateblue", svgtiny_RGB(123, 104, 238)}, +//#line 61 "colors.gperf" + {"darkturquoise", svgtiny_RGB( 0, 206, 209)}, +//#line 134 "colors.gperf" + {"palevioletred", svgtiny_RGB(219, 112, 147)}, +//#line 135 "colors.gperf" + {"papayawhip", svgtiny_RGB(255, 239, 213)}, +//#line 116 "colors.gperf" + {"mediumspringgreen", svgtiny_RGB( 0, 250, 154)}, +//#line 49 "colors.gperf" + {"darkgrey", svgtiny_RGB(169, 169, 169)}, +//#line 117 "colors.gperf" + {"mediumturquoise", svgtiny_RGB( 72, 209, 204)}, +//#line 47 "colors.gperf" + {"darkgray", svgtiny_RGB(169, 169, 169)}, +//#line 46 "colors.gperf" + {"darkgoldenrod", svgtiny_RGB(184, 134, 11)}, +//#line 66 "colors.gperf" + {"dimgrey", svgtiny_RGB(105, 105, 105)}, +//#line 65 "colors.gperf" + {"dimgray", svgtiny_RGB(105, 105, 105)}, +//#line 80 "colors.gperf" + {"honeydew", svgtiny_RGB(240, 255, 240)}, +//#line 28 "colors.gperf" + {"beige", svgtiny_RGB(245, 245, 220)}, +//#line 161 "colors.gperf" + {"thistle", svgtiny_RGB(216, 191, 216)}, +//#line 41 "colors.gperf" + {"cornsilk", svgtiny_RGB(255, 248, 220)}, +//#line 126 "colors.gperf" + {"olive", svgtiny_RGB(128, 128, 0)}, +//#line 33 "colors.gperf" + {"blueviolet", svgtiny_RGB(138, 43, 226)}, +//#line 110 "colors.gperf" + {"mediumaquamarine", svgtiny_RGB(102, 205, 170)}, +//#line 40 "colors.gperf" + {"cornflowerblue", svgtiny_RGB(100, 149, 237)}, +//#line 23 "colors.gperf" + {"aliceblue", svgtiny_RGB(240, 248, 255)}, +//#line 140 "colors.gperf" + {"powderblue", svgtiny_RGB(176, 224, 230)}, +//#line 133 "colors.gperf" + {"paleturquoise", svgtiny_RGB(175, 238, 238)}, +//#line 60 "colors.gperf" + {"darkslategrey", svgtiny_RGB( 47, 79, 79)}, +//#line 50 "colors.gperf" + {"darkkhaki", svgtiny_RGB(189, 183, 107)}, +//#line 59 "colors.gperf" + {"darkslategray", svgtiny_RGB( 47, 79, 79)}, +//#line 73 "colors.gperf" + {"ghostwhite", svgtiny_RGB(248, 248, 255)}, +//#line 127 "colors.gperf" + {"olivedrab", svgtiny_RGB(107, 142, 35)}, +//#line 131 "colors.gperf" + {"palegoldenrod", svgtiny_RGB(238, 232, 170)}, +//#line 45 "colors.gperf" + {"darkcyan", svgtiny_RGB( 0, 139, 139)}, +//#line 81 "colors.gperf" + {"hotpink", svgtiny_RGB(255, 105, 180)}, +//#line 72 "colors.gperf" + {"gainsboro", svgtiny_RGB(220, 220, 220)}, +//#line 63 "colors.gperf" + {"deeppink", svgtiny_RGB(255, 20, 147)}, +//#line 42 "colors.gperf" + {"crimson", svgtiny_RGB(220, 20, 60)}, +//#line 35 "colors.gperf" + {"burlywood", svgtiny_RGB(222, 184, 135)}, +//#line 69 "colors.gperf" + {"floralwhite", svgtiny_RGB(255, 250, 240)}, +//#line 166 "colors.gperf" + {"white", svgtiny_RGB(255, 255, 255)}, +//#line 123 "colors.gperf" + {"navajowhite", svgtiny_RGB(255, 222, 173)}, +//#line 168 "colors.gperf" + {"yellow", svgtiny_RGB(255, 255, 0)}, +//#line 169 "colors.gperf" + {"yellowgreen", svgtiny_RGB(154, 205, 50)}, +//#line 100 "colors.gperf" + {"lightskyblue", svgtiny_RGB(135, 206, 250)}, +//#line 64 "colors.gperf" + {"deepskyblue", svgtiny_RGB( 0, 191, 255)}, +//#line 167 "colors.gperf" + {"whitesmoke", svgtiny_RGB(245, 245, 245)} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = svgtiny_color_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) + { + register const struct svgtiny_named_color *resword; + + switch (key - 4) + { + case 0: + resword = &wordlist[0]; + goto compare; + case 10: + resword = &wordlist[1]; + goto compare; + case 16: + resword = &wordlist[2]; + goto compare; + case 20: + resword = &wordlist[3]; + goto compare; + case 21: + resword = &wordlist[4]; + goto compare; + case 25: + resword = &wordlist[5]; + goto compare; + case 26: + resword = &wordlist[6]; + goto compare; + case 30: + resword = &wordlist[7]; + goto compare; + case 33: + resword = &wordlist[8]; + goto compare; + case 35: + resword = &wordlist[9]; + goto compare; + case 37: + resword = &wordlist[10]; + goto compare; + case 40: + resword = &wordlist[11]; + goto compare; + case 44: + resword = &wordlist[12]; + goto compare; + case 45: + resword = &wordlist[13]; + goto compare; + case 46: + resword = &wordlist[14]; + goto compare; + case 52: + resword = &wordlist[15]; + goto compare; + case 55: + resword = &wordlist[16]; + goto compare; + case 56: + resword = &wordlist[17]; + goto compare; + case 60: + resword = &wordlist[18]; + goto compare; + case 62: + resword = &wordlist[19]; + goto compare; + case 65: + resword = &wordlist[20]; + goto compare; + case 67: + resword = &wordlist[21]; + goto compare; + case 70: + resword = &wordlist[22]; + goto compare; + case 74: + resword = &wordlist[23]; + goto compare; + case 75: + resword = &wordlist[24]; + goto compare; + case 76: + resword = &wordlist[25]; + goto compare; + case 80: + resword = &wordlist[26]; + goto compare; + case 81: + resword = &wordlist[27]; + goto compare; + case 83: + resword = &wordlist[28]; + goto compare; + case 85: + resword = &wordlist[29]; + goto compare; + case 90: + resword = &wordlist[30]; + goto compare; + case 91: + resword = &wordlist[31]; + goto compare; + case 92: + resword = &wordlist[32]; + goto compare; + case 93: + resword = &wordlist[33]; + goto compare; + case 95: + resword = &wordlist[34]; + goto compare; + case 97: + resword = &wordlist[35]; + goto compare; + case 100: + resword = &wordlist[36]; + goto compare; + case 102: + resword = &wordlist[37]; + goto compare; + case 104: + resword = &wordlist[38]; + goto compare; + case 105: + resword = &wordlist[39]; + goto compare; + case 107: + resword = &wordlist[40]; + goto compare; + case 109: + resword = &wordlist[41]; + goto compare; + case 110: + resword = &wordlist[42]; + goto compare; + case 114: + resword = &wordlist[43]; + goto compare; + case 115: + resword = &wordlist[44]; + goto compare; + case 117: + resword = &wordlist[45]; + goto compare; + case 118: + resword = &wordlist[46]; + goto compare; + case 120: + resword = &wordlist[47]; + goto compare; + case 125: + resword = &wordlist[48]; + goto compare; + case 129: + resword = &wordlist[49]; + goto compare; + case 130: + resword = &wordlist[50]; + goto compare; + case 135: + resword = &wordlist[51]; + goto compare; + case 137: + resword = &wordlist[52]; + goto compare; + case 138: + resword = &wordlist[53]; + goto compare; + case 140: + resword = &wordlist[54]; + goto compare; + case 141: + resword = &wordlist[55]; + goto compare; + case 144: + resword = &wordlist[56]; + goto compare; + case 145: + resword = &wordlist[57]; + goto compare; + case 149: + resword = &wordlist[58]; + goto compare; + case 155: + resword = &wordlist[59]; + goto compare; + case 156: + resword = &wordlist[60]; + goto compare; + case 157: + resword = &wordlist[61]; + goto compare; + case 159: + resword = &wordlist[62]; + goto compare; + case 160: + resword = &wordlist[63]; + goto compare; + case 164: + resword = &wordlist[64]; + goto compare; + case 165: + resword = &wordlist[65]; + goto compare; + case 166: + resword = &wordlist[66]; + goto compare; + case 167: + resword = &wordlist[67]; + goto compare; + case 168: + resword = &wordlist[68]; + goto compare; + case 170: + resword = &wordlist[69]; + goto compare; + case 172: + resword = &wordlist[70]; + goto compare; + case 174: + resword = &wordlist[71]; + goto compare; + case 175: + resword = &wordlist[72]; + goto compare; + case 176: + resword = &wordlist[73]; + goto compare; + case 180: + resword = &wordlist[74]; + goto compare; + case 181: + resword = &wordlist[75]; + goto compare; + case 182: + resword = &wordlist[76]; + goto compare; + case 183: + resword = &wordlist[77]; + goto compare; + case 185: + resword = &wordlist[78]; + goto compare; + case 188: + resword = &wordlist[79]; + goto compare; + case 190: + resword = &wordlist[80]; + goto compare; + case 191: + resword = &wordlist[81]; + goto compare; + case 192: + resword = &wordlist[82]; + goto compare; + case 196: + resword = &wordlist[83]; + goto compare; + case 200: + resword = &wordlist[84]; + goto compare; + case 201: + resword = &wordlist[85]; + goto compare; + case 209: + resword = &wordlist[86]; + goto compare; + case 210: + resword = &wordlist[87]; + goto compare; + case 211: + resword = &wordlist[88]; + goto compare; + case 215: + resword = &wordlist[89]; + goto compare; + case 221: + resword = &wordlist[90]; + goto compare; + case 222: + resword = &wordlist[91]; + goto compare; + case 226: + resword = &wordlist[92]; + goto compare; + case 230: + resword = &wordlist[93]; + goto compare; + case 232: + resword = &wordlist[94]; + goto compare; + case 238: + resword = &wordlist[95]; + goto compare; + case 240: + resword = &wordlist[96]; + goto compare; + case 241: + resword = &wordlist[97]; + goto compare; + case 243: + resword = &wordlist[98]; + goto compare; + case 245: + resword = &wordlist[99]; + goto compare; + case 250: + resword = &wordlist[100]; + goto compare; + case 251: + resword = &wordlist[101]; + goto compare; + case 255: + resword = &wordlist[102]; + goto compare; + case 258: + resword = &wordlist[103]; + goto compare; + case 260: + resword = &wordlist[104]; + goto compare; + case 261: + resword = &wordlist[105]; + goto compare; + case 263: + resword = &wordlist[106]; + goto compare; + case 269: + resword = &wordlist[107]; + goto compare; + case 271: + resword = &wordlist[108]; + goto compare; + case 278: + resword = &wordlist[109]; + goto compare; + case 279: + resword = &wordlist[110]; + goto compare; + case 281: + resword = &wordlist[111]; + goto compare; + case 284: + resword = &wordlist[112]; + goto compare; + case 289: + resword = &wordlist[113]; + goto compare; + case 293: + resword = &wordlist[114]; + goto compare; + case 298: + resword = &wordlist[115]; + goto compare; + case 299: + resword = &wordlist[116]; + goto compare; + case 306: + resword = &wordlist[117]; + goto compare; + case 308: + resword = &wordlist[118]; + goto compare; + case 309: + resword = &wordlist[119]; + goto compare; + case 311: + resword = &wordlist[120]; + goto compare; + case 316: + resword = &wordlist[121]; + goto compare; + case 321: + resword = &wordlist[122]; + goto compare; + case 330: + resword = &wordlist[123]; + goto compare; + case 335: + resword = &wordlist[124]; + goto compare; + case 336: + resword = &wordlist[125]; + goto compare; + case 338: + resword = &wordlist[126]; + goto compare; + case 344: + resword = &wordlist[127]; + goto compare; + case 345: + resword = &wordlist[128]; + goto compare; + case 349: + resword = &wordlist[129]; + goto compare; + case 350: + resword = &wordlist[130]; + goto compare; + case 355: + resword = &wordlist[131]; + goto compare; + case 364: + resword = &wordlist[132]; + goto compare; + case 369: + resword = &wordlist[133]; + goto compare; + case 373: + resword = &wordlist[134]; + goto compare; + case 380: + resword = &wordlist[135]; + goto compare; + case 384: + resword = &wordlist[136]; + goto compare; + case 398: + resword = &wordlist[137]; + goto compare; + case 410: + resword = &wordlist[138]; + goto compare; + case 426: + resword = &wordlist[139]; + goto compare; + case 436: + resword = &wordlist[140]; + goto compare; + case 437: + resword = &wordlist[141]; + goto compare; + case 467: + resword = &wordlist[142]; + goto compare; + case 482: + resword = &wordlist[143]; + goto compare; + case 483: + resword = &wordlist[144]; + goto compare; + case 552: + resword = &wordlist[145]; + goto compare; + case 561: + resword = &wordlist[146]; + goto compare; + } + return 0; + compare: + { + register const char *s = resword->name; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return resword; + } + } + } + return 0; +} + +int LICE_RGBA_from_SVG(const char* s,int len) // returns LICE_pixel +{ + int r = 0, g = 0, b = 0; + double rf = 0.0, gf = 0.0, bf = 0.0; + const struct svgtiny_named_color* c = 0; + +#ifdef _WIN32 + if (len == 4 && !strnicmp(s, "none", 4)) return 0; +#else + if (len == 4 && !strncasecmp(s, "none", 4)) return 0; +#endif + + if (len == 4 && s[0] == '#') + { + if (sscanf(s+1, "%1x%1x%1x", &r, &g, &b) == 3) + { + return svgtiny_RGB(r<<4,g<<4,b<<4); + } + } + else if (len == 7 && s[0] == '#') + { + if (sscanf(s+1, "%2x%2x%2x", &r, &g, &b) == 3) + { + return svgtiny_RGB(r, g, b); + } + } + else if (10 <= len && s[0] == 'r' && s[1] == 'g' && s[2] == 'b' && s[3] == '(' && s[len - 1] == ')') + { + if (sscanf(s+4, "%i,%i,%i", &r, &g, &b) == 3) + { + return svgtiny_RGB(r, g, b); + } + else + { + if (sscanf(s+4, "%f%%,%f%%,%f%%", &rf, &gf, &bf) == 3) + { + b = (int) (bf*2.55); + g = (int) (gf*2.55); + r = (int) (rf*2.55); + return svgtiny_RGB(r, g, b); + } + } + } + else + { + c = svgtiny_color_lookup(s, len); + if (c) return c->color; + } + + return 0; +} diff --git a/WDL/tinyxml/tinystr.cpp b/WDL/tinyxml/tinystr.cpp new file mode 100644 index 00000000..68125071 --- /dev/null +++ b/WDL/tinyxml/tinystr.cpp @@ -0,0 +1,116 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. + */ + + +#ifndef TIXML_USE_STL + +#include "tinystr.h" + +// Error value for find primitive +const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); + + +// Null rep. +TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; + + +void TiXmlString::reserve (size_type cap) +{ + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } +} + + +TiXmlString& TiXmlString::assign(const char* str, size_type len) +{ + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; +} + + +TiXmlString& TiXmlString::append(const char* str, size_type len) +{ + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; +} + + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) +{ + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; +} + +TiXmlString operator + (const TiXmlString & a, const char* b) +{ + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; +} + +TiXmlString operator + (const char* a, const TiXmlString & b) +{ + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; +} + + +#endif // TIXML_USE_STL diff --git a/WDL/tinyxml/tinystr.h b/WDL/tinyxml/tinystr.h new file mode 100644 index 00000000..8e03028b --- /dev/null +++ b/WDL/tinyxml/tinystr.h @@ -0,0 +1,320 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. + * + * - completely rewritten. compact, clean, and fast implementation. + * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) + * - fixed reserve() to work as per specification. + * - fixed buggy compares operator==(), operator<(), and operator>() + * - fixed operator+=() to take a const ref argument, following spec. + * - added "copy" constructor with length, and most compare operators. + * - added swap(), clear(), size(), capacity(), operator+(). + */ + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ + +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ + +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/WDL/tinyxml/tinyxml.cpp b/WDL/tinyxml/tinyxml.cpp new file mode 100644 index 00000000..5de21f6d --- /dev/null +++ b/WDL/tinyxml/tinyxml.cpp @@ -0,0 +1,1888 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include + +#ifdef TIXML_USE_STL +#include +#include +#endif + +#include "tinyxml.h" + + +bool TiXmlBase::condenseWhiteSpace = true; + +// Microsoft compiler security +FILE* TiXmlFOpen( const char* filename, const char* mode ) +{ + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + FILE* fp = 0; + errno_t err = fopen_s( &fp, filename, mode ); + if ( !err && fp ) + return fp; + return 0; + #else + return fopen( filename, mode ); + #endif +} + +void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + + if ( node->Type() == TiXmlNode::DOCUMENT ) + { + delete node; + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + + +const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + + +const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + #else + TiXmlAttribute* node = attributeSet.Find( name ); + #endif + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +const TiXmlElement* TiXmlNode::FirstChildElement() const +{ + const TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + const TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +void TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char* TiXmlElement::Attribute( const char* name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return node->Value(); + return 0; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return &node->ValueStr(); + return 0; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, int* i ) const +{ + const char* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s ); + } + else { + *i = 0; + } + } + return s; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const +{ + const std::string* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s->c_str() ); + } + else { + *i = 0; + } + } + return s; +} +#endif + + +const char* TiXmlElement::Attribute( const char* name, double* d ) const +{ + const char* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s ); + } + else { + *d = 0; + } + } + return s; +} + + +#ifdef TIXML_USE_STL +const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const +{ + const std::string* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s->c_str() ); + } + else { + *d = 0; + } + } + return s; +} +#endif + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); +} +#endif + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); +} + + +#ifdef TIXML_USE_STL +int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const +{ + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); +} +#endif + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + char buf[64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); + #else + sprintf( buf, "%d", val ); + #endif + SetAttribute( name, buf ); +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, int val ) +{ + std::ostringstream oss; + oss << val; + SetAttribute( name, oss.str() ); +} +#endif + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + char buf[256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); + #else + sprintf( buf, "%f", val ); + #endif + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) +{ + #ifdef TIXML_USE_STL + TIXML_STRING _name( cname ); + TIXML_STRING _value( cvalue ); + #else + const char* _name = cname; + const char* _value = cvalue; + #endif + + TiXmlAttribute* node = attributeSet.Find( _name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} +#endif + + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + assert( cfile ); + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + +bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, attributeSet.First() ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +const char* TiXmlElement::GetText() const +{ + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + // See STL_STRING_BUG below. + //StringToBuffer buf( value ); + + return LoadFile( Value(), encoding ); +} + + +bool TiXmlDocument::SaveFile() const +{ + // See STL_STRING_BUG below. +// StringToBuffer buf( value ); +// +// if ( buf.buffer && SaveFile( buf.buffer ) ) +// return true; +// +// return false; + return SaveFile( Value() ); +} + +bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) +{ + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the std::string to + // be called. What is strange, is that the std::string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // Add an extra string to avoid the crash. + TIXML_STRING filename( _filename ); + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = TiXmlFOpen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } +} + +bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) +{ + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length <= 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + delete [] buf; + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + const char* lastPos = buf; + const char* p = buf; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + if ( *p == 0xa ) { + // Newline character. No special rules for this. Append all the characters + // since the last string, and include the newline. + data.append( lastPos, (p-lastPos+1) ); // append, include the newline + ++p; // move past the newline + lastPos = p; // and point to the new buffer (may be 0) + assert( p <= (buf+length) ); + } + else if ( *p == 0xd ) { + // Carriage return. Append what we have so far, then + // handle moving forward in the buffer. + if ( (p-lastPos) > 0 ) { + data.append( lastPos, p-lastPos ); // do not add the CR + } + data += (char)0xa; // a proper newline + + if ( *(p+1) == 0xa ) { + // Carriage return - new line sequence + p += 2; + lastPos = p; + assert( p <= (buf+length) ); + } + else { + // it was followed by something else...that is presumably characters again. + ++p; + lastPos = p; + assert( p <= (buf+length) ); + } + } + else { + ++p; + } + } + // Handle any left over characters. + if ( p-lastPos ) { + data.append( lastPos, p-lastPos ); + } + delete [] buf; + buf = 0; + + Parse( data.c_str(), 0, encoding ); + + if ( Error() ) + return false; + else + return true; +} + + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = TiXmlFOpen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; +} + + +bool TiXmlDocument::SaveFile( FILE* fp ) const +{ + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return (ferror(fp) == 0); +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorId = errorId; + target->errorDesc = errorDesc; + target->tabsize = tabsize; + target->errorLocation = errorLocation; + target->useMicrosoftBOM = useMicrosoftBOM; + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + + +bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); +} + + +const TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +/* +TiXmlAttribute* TiXmlAttribute::Next() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} +*/ + +const TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +/* +TiXmlAttribute* TiXmlAttribute::Previous() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} +*/ + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + TIXML_STRING n, v; + + EncodeString( name, &n ); + EncodeString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) { + if ( cfile ) { + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; + } + } + else { + if ( cfile ) { + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; + } + } +} + + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); + #else + sprintf (buf, "%lf", _value); + #endif + SetValue (buf); +} + +int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int depth ) const +{ + assert( cfile ); + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i\n", value.c_str() ); // unformatted output + } + else + { + TIXML_STRING buffer; + EncodeString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); + target->cdata = cdata; +} + + +bool TiXmlText::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const +{ + if ( cfile ) fprintf( cfile, "" ); + if ( str ) (*str) += "?>"; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i", value.c_str() ); +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + #ifdef TIXML_USE_STL + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + #else + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + #endif + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + + +#ifdef TIXML_USE_STL +const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const +{ + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +/* +TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} +*/ +#endif + + +const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const +{ + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} + +/* +TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) +{ + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; +} +*/ + +#ifdef TIXML_USE_STL +std::istream& operator>> (std::istream & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +#ifdef TIXML_USE_STL +std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out << printer.Str(); + + return out; +} + + +std::string& operator<< (std::string& out, const TiXmlNode& base ) +{ + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out.append( printer.Str() ); + + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) +{ + return true; +} + +bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) +{ + DoIndent(); + buffer += "<"; + buffer += element.Value(); + + for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) + { + buffer += " "; + attrib->Print( 0, 0, &buffer ); + } + + if ( !element.FirstChild() ) + { + buffer += " />"; + DoLineBreak(); + } + else + { + buffer += ">"; + if ( element.FirstChild()->ToText() + && element.LastChild() == element.FirstChild() + && element.FirstChild()->ToText()->CDATA() == false ) + { + simpleTextPrint = true; + // no DoLineBreak()! + } + else + { + DoLineBreak(); + } + } + ++depth; + return true; +} + + +bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) +{ + --depth; + if ( !element.FirstChild() ) + { + // nothing. + } + else + { + if ( simpleTextPrint ) + { + simpleTextPrint = false; + } + else + { + DoIndent(); + } + buffer += ""; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlText& text ) +{ + if ( text.CDATA() ) + { + DoIndent(); + buffer += ""; + DoLineBreak(); + } + else if ( simpleTextPrint ) + { + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + } + else + { + DoIndent(); + TIXML_STRING str; + TiXmlBase::EncodeString( text.ValueTStr(), &str ); + buffer += str; + DoLineBreak(); + } + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) +{ + DoIndent(); + declaration.Print( 0, 0, &buffer ); + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlComment& comment ) +{ + DoIndent(); + buffer += ""; + DoLineBreak(); + return true; +} + + +bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) +{ + DoIndent(); + buffer += "<"; + buffer += unknown.Value(); + buffer += ">"; + DoLineBreak(); + return true; +} + diff --git a/WDL/tinyxml/tinyxml.h b/WDL/tinyxml/tinyxml.h new file mode 100644 index 00000000..e08f7cca --- /dev/null +++ b/WDL/tinyxml/tinyxml.h @@ -0,0 +1,1802 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 5; +const int TIXML_PATCH_VERSION = 3; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simple called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + const TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* Find( const char* _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + #ifdef TIXML_USE_STL + const TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* Find( const std::string& _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + + #endif + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + /* + This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" + but template specialization is hard to get working cross-compiler. Leaving the bug for now. + + // The above will fail for std::string because the space character is used as a seperator. + // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string + template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + */ + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && LoadFile( f.buffer, encoding )); + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && SaveFile( f.buffer )); + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i +#include + +#include "tinyxml.h" + +//#define DEBUG_PARSER +#if defined( DEBUG_PARSER ) +# if defined( DEBUG ) && defined( _MSC_VER ) +# include +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif +#endif + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + +const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The +// "assign" optimization removes over 10% of the execution time. +// +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + // Oddly, not supported on some comilers, + //name->clear(); + // So use this: + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + const char* start = p; + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + //(*name) += *p; // expensive + ++p; + } + if ( p-start > 0 ) { + name->assign( start, p-start ); + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + if ( p ) + p += strlen( endTag ); + return p; +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocument* doc = GetDocument(); + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: "; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // [ 1475201 ] TinyXML parses entities in comments + // Oops - ReadText doesn't work, because we don't want to parse the entities. + // p = ReadText( p, &value, false, endTag, false, encoding ); + // + // from the XML spec: + /* + [Definition: Comments may appear anywhere in a document outside other markup; in addition, + they may appear within the document type declaration at places allowed by the grammar. + They are not part of the document's character data; an XML processor MAY, but need not, + make it possible for an application to retrieve the text of comments. For compatibility, + the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity + references MUST NOT be recognized within comments. + + An example of a comment: + + + */ + + value = ""; + // Keep all the white space. + while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) + { + value.append( p, 1 ); + ++p; + } + if ( p ) + p += strlen( endTag ); + + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + +// int tabsize = 4; +// if ( document ) +// tabsize = document->TabSize(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + const char SINGLE_QUOTE = '\''; + const char DOUBLE_QUOTE = '\"'; + + if ( *p == SINGLE_QUOTE ) + { + ++p; + end = "\'"; // single quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == DOUBLE_QUOTE ) + { + ++p; + end = "\""; // double quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { + // [ 1451649 ] Attribute values with trailing quotes not handled correctly + // We did not have an opening quote but seem to have a + // closing one. Give up and throw an error. + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->peek(); + if ( !cdata && (c == '<' ) ) + { + return; + } + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); // "commits" the peek made above + + if ( cdata && c == '>' && tag->size() >= 3 ) { + size_t len = tag->size(); + if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { + // terminator of cdata. + return; + } + } + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = ""; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; + } +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i=buffer.GetSize()) bufidx = 0; + + return output; + } + void Reset() { memset(buffer.Get(),0,buffer.GetSize()*sizeof(double)); } + void setfeedback(double val) { feedback=val; } + +private: + double feedback; + WDL_TypedBuf buffer; + int bufidx; + int __pad; + +} WDL_FIXALIGN; + + +class WDL_ReverbComb +{ +public: + WDL_ReverbComb() { feedback=0.5; damp=0.5; filterstore=0; setsize(1); } + ~WDL_ReverbComb() { } + + void setsize(int size) + { + if (size<1)size=1; + if (buffer.GetSize()!=size) + { + bufidx=0; + buffer.Resize(size); + Reset(); + } + } + + double process(double inp) + { + double *bptr=buffer.Get()+bufidx; + double output = *bptr; + filterstore = denormal_filter_double((output*(1-damp)) + (filterstore*damp)); + + *bptr = inp + (filterstore*feedback); + + if(++bufidx>=buffer.GetSize()) bufidx = 0; + + return output; + } + void Reset() { memset(buffer.Get(),0,buffer.GetSize()*sizeof(double)); } + void setdamp(double val) { damp=val; } + void setfeedback(double val) { feedback=val; } + +private: + + double feedback; + double filterstore; + double damp; + WDL_TypedBuf buffer; + int bufidx; + int __pad; +} WDL_FIXALIGN; + + // these represent lengths in samples at 44.1khz but are scaled accordingly +const int wdl_verb__stereospread=23; +const short wdl_verb__combtunings[]={1116,1188,1277,1356,1422,1491,1557,1617,1685,1748}; +const short wdl_verb__allpasstunings[]={556,441,341,225,180,153}; + + +class WDL_ReverbEngine +{ +public: + WDL_ReverbEngine() + { + m_srate=44100.0; + m_roomsize=0.5; + m_damp=0.5; + SetWidth(1.0); + Reset(false); + } + ~WDL_ReverbEngine() + { + } + void SetSampleRate(double srate) + { + if (m_srate!=srate) + { + m_srate=srate; + Reset(true); + } + } + + void ProcessSampleBlock(double *spl0, double *spl1, double *outp0, double *outp1, int ns) + { + int x; + memset(outp0,0,ns*sizeof(double)); + memset(outp1,0,ns*sizeof(double)); + + for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x += 2) + { + int i=ns; + double *p0=outp0,*p1=outp1,*i0=spl0,*i1=spl1; + while (i--) + { + double a=*i0++,b=*i1++; + *p0+=m_combs[x][0].process(a); + *p1+=m_combs[x][1].process(b); + *p0+++=m_combs[x+1][0].process(a); + *p1+++=m_combs[x+1][1].process(b); + } + } + for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0])-2; x += 2) + { + int i=ns; + double *p0=outp0,*p1=outp1; + while (i--) + { + double tmp=m_allpasses[x][0].process(*p0); + double tmp2=m_allpasses[x][1].process(*p1); + *p0++=m_allpasses[x+1][0].process(tmp); + *p1++=m_allpasses[x+1][1].process(tmp2); + } + } + int i=ns; + double *p0=outp0,*p1=outp1; + while (i--) + { + double a=m_allpasses[x+1][0].process(m_allpasses[x][0].process(*p0))*0.015; + double b=m_allpasses[x+1][1].process(m_allpasses[x][1].process(*p1))*0.015; + + if (m_wid<0) + { + double m=-m_wid; + *p0 = b*m + a*(1.0-m); + *p1 = a*m + b*(1.0-m); + } + else + { + double m=m_wid; + *p0 = a*m + b*(1.0-m); + *p1 = b*m + a*(1.0-m); + } + p0++; + p1++; + } + + } + + void ProcessSample(double *spl0, double *spl1) + { + int x; + double in0=*spl0 * 0.015; + double in1=*spl1 * 0.015; + + double out0=0.0; + double out1=0.0; + for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x ++) + { + out0+=m_combs[x][0].process(in0); + out1+=m_combs[x][1].process(in1); + } + for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0]); x ++) + { + out0=m_allpasses[x][0].process(out0); + out1=m_allpasses[x][1].process(out1); + } + + if (m_wid<0) + { + double m=-m_wid; + *spl0 = out1*m + out0*(1.0-m); + *spl1 = out0*m + out1*(1.0-m); + } + else + { + double m=m_wid; + *spl0 = out0*m + out1*(1.0-m); + *spl1 = out1*m + out0*(1.0-m); + } + } + + void Reset(bool doclear=false) // call this after changing roomsize or dampening + { + int x; + double sc=m_srate / 44100.0; + for (x = 0; x < sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0]); x ++) + { + m_allpasses[x][0].setsize((int) (wdl_verb__allpasstunings[x] * sc)); + m_allpasses[x][1].setsize((int) ((wdl_verb__allpasstunings[x]+wdl_verb__stereospread) * sc)); + m_allpasses[x][0].setfeedback(0.5); + m_allpasses[x][1].setfeedback(0.5); + if (doclear) + { + m_allpasses[x][0].Reset(); + m_allpasses[x][1].Reset(); + } + } + for (x = 0; x < sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0]); x ++) + { + m_combs[x][0].setsize((int) (wdl_verb__combtunings[x] * sc)); + m_combs[x][1].setsize((int) ((wdl_verb__combtunings[x]+wdl_verb__stereospread) * sc)); + m_combs[x][0].setfeedback(m_roomsize); + m_combs[x][1].setfeedback(m_roomsize); + m_combs[x][0].setdamp(m_damp*0.4); + m_combs[x][1].setdamp(m_damp*0.4); + if (doclear) + { + m_combs[x][0].Reset(); + m_combs[x][1].Reset(); + } + } + + } + + void SetRoomSize(double sz) { m_roomsize=sz;; } // 0.3..0.99 or so + void SetDampening(double dmp) { m_damp=dmp; } // 0..1 + void SetWidth(double wid) + { + if (wid<-1) wid=-1; + else if (wid>1) wid=1; + wid*=0.5; + if (wid>=0.0) wid+=0.5; + else wid-=0.5; + m_wid=wid; + } // -1..1 + +private: + double m_wid; + double m_roomsize; + double m_damp; + double m_srate; + WDL_ReverbAllpass m_allpasses[sizeof(wdl_verb__allpasstunings)/sizeof(wdl_verb__allpasstunings[0])][2]; + WDL_ReverbComb m_combs[sizeof(wdl_verb__combtunings)/sizeof(wdl_verb__combtunings[0])][2]; + +}; + + +#endif \ No newline at end of file diff --git a/WDL/vorbisencdec.h b/WDL/vorbisencdec.h new file mode 100644 index 00000000..0835092d --- /dev/null +++ b/WDL/vorbisencdec.h @@ -0,0 +1,468 @@ +/* + WDL - vorbisencdec.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* + + This file provides simple interfaces for encoding and decoding of OGG Vorbis data. + It is a wrapper around what their SDKs expose, which is not too easy to use. + + This stuff is pretty limited and simple, but works, usually. + + For full control you probably want to #define VORBISENC_WANT_FULLCONFIG + but for compatibility with some older code, it's left disabled here. + +*/ + +#ifndef _VORBISENCDEC_H_ +#define _VORBISENCDEC_H_ + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS +#define OV_EXCLUDE_STATIC_CALLBACKS +#endif +#include "vorbis/vorbisenc.h" +#include "vorbis/codec.h" + +class VorbisDecoderInterface +{ +public: + virtual ~VorbisDecoderInterface(){} + virtual int GetSampleRate()=0; + virtual int GetNumChannels()=0; + virtual void *DecodeGetSrcBuffer(int srclen)=0; + virtual void DecodeWrote(int srclen)=0; + virtual void Reset()=0; + virtual int Available()=0; + virtual float *Get()=0; + virtual void Skip(int amt)=0; +}; + +class VorbisEncoderInterface +{ +public: + virtual ~VorbisEncoderInterface(){} + virtual void Encode(float *in, int inlen, int advance=1, int spacing=1)=0; // length in sample (PAIRS) + virtual int isError()=0; + virtual int Available()=0; + virtual void *Get()=0; + virtual void Advance(int)=0; + virtual void Compact()=0; + virtual void reinit(int bla=0)=0; +}; + + +#ifndef WDL_VORBIS_INTERFACE_ONLY + +#include "../WDL/queue.h" + +class VorbisDecoder : public VorbisDecoderInterface +{ + public: + VorbisDecoder() + { + m_samples_used=0; + packets=0; + memset(&oy,0,sizeof(oy)); + memset(&os,0,sizeof(os)); + memset(&og,0,sizeof(og)); + memset(&op,0,sizeof(op)); + memset(&vi,0,sizeof(vi)); + memset(&vc,0,sizeof(vc)); + memset(&vd,0,sizeof(vd)); + memset(&vb,0,sizeof(vb)); + + + ogg_sync_init(&oy); /* Now we can read pages */ + m_err=0; + } + ~VorbisDecoder() + { + ogg_stream_clear(&os); + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); + + ogg_sync_clear(&oy); + } + + int GetSampleRate() { return vi.rate; } + int GetNumChannels() { return vi.channels?vi.channels:1; } + + void *DecodeGetSrcBuffer(int srclen) + { + return ogg_sync_buffer(&oy,srclen); + } + + void DecodeWrote(int srclen) + { + ogg_sync_wrote(&oy,srclen); + + while(ogg_sync_pageout(&oy,&og)>0) + { + int serial=ogg_page_serialno(&og); + if (!packets) ogg_stream_init(&os,serial); + else if (serial!=os.serialno) + { + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); + + ogg_stream_clear(&os); + ogg_stream_init(&os,serial); + packets=0; + } + if (!packets) + { + vorbis_info_init(&vi); + vorbis_comment_init(&vc); + } + ogg_stream_pagein(&os,&og); + while(ogg_stream_packetout(&os,&op)>0) + { + if (packets<3) + { + if(vorbis_synthesis_headerin(&vi,&vc,&op)<0) return; + } + else + { + float ** pcm; + int samples; + if(vorbis_synthesis(&vb,&op)==0) vorbis_synthesis_blockin(&vd,&vb); + while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0) + { + int n,c; + + int newsize=(m_samples_used+(samples+4096)*vi.channels)*sizeof(float); + + if (m_samples.GetSize() < newsize) m_samples.Resize(newsize+32768); + + float *bufmem = (float *)m_samples.Get(); + + for(n=0;n0) + memcpy(sptr,sptr+amt,m_samples_used*sizeof(float)); + else m_samples_used=0; + } + + void Reset() + { + m_samples_used=0; + + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); + + ogg_stream_clear(&os); + packets=0; + } + + private: + + WDL_HeapBuf m_samples; // we let the size get as big as it needs to, so we don't worry about tons of mallocs/etc + + int m_err; + int packets; + int m_samples_used; + + ogg_sync_state oy; /* sync and verify incoming physical bitstream */ + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream + settings */ + vorbis_comment vc; /* struct that stores all the bitstream user comments */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + +} WDL_FIXALIGN; + + +class VorbisEncoder : public VorbisEncoderInterface +{ +public: +#ifdef VORBISENC_WANT_FULLCONFIG + VorbisEncoder(int srate, int nch, int serno, float qv, int cbr=-1, int minbr=-1, int maxbr=-1, const char *encname=NULL) +#elif defined(VORBISENC_WANT_QVAL) + VorbisEncoder(int srate, int nch, float qv, int serno, const char *encname=NULL) +#else + VorbisEncoder(int srate, int nch, int bitrate, int serno, const char *encname=NULL) +#endif + { + m_flushmode=false; + m_ds=0; + + memset(&vi,0,sizeof(vi)); + memset(&vc,0,sizeof(vc)); + memset(&vd,0,sizeof(vd)); + memset(&vb,0,sizeof(vb)); + + m_nch=nch; + vorbis_info_init(&vi); + +#ifdef VORBISENC_WANT_FULLCONFIG + + if (cbr > 0) + { + m_err=vorbis_encode_init(&vi,nch,srate,maxbr*1000,cbr*1000,minbr*1000); + } + else + m_err=vorbis_encode_init_vbr(&vi,nch,srate,qv); + +#else + + #ifndef VORBISENC_WANT_QVAL + float qv=0.0; + if (nch == 2) bitrate= (bitrate*5)/8; + // at least for mono 44khz + //-0.1 = ~40kbps + //0.0 == ~64kbps + //0.1 == 75 + //0.3 == 95 + //0.5 == 110 + //0.75== 140 + //1.0 == 240 + if (bitrate <= 32) + { + m_ds=1; + bitrate*=2; + } + + if (bitrate < 40) qv=-0.1f; + else if (bitrate < 64) qv=-0.10f + (bitrate-40)*(0.10f/24.0f); + else if (bitrate < 75) qv=(bitrate-64)*(0.1f/9.0f); + else if (bitrate < 95) qv=0.1f+(bitrate-75)*(0.2f/20.0f); + else if (bitrate < 110) qv=0.3f+(bitrate-95)*(0.2f/15.0f); + else if (bitrate < 140) qv=0.5f+(bitrate-110)*(0.25f/30.0f); + else qv=0.75f+(bitrate-140)*(0.25f/100.0f); + + if (qv<-0.10f)qv=-0.10f; + if (qv>1.0f)qv=1.0f; + #endif + + m_err=vorbis_encode_init_vbr(&vi,nch,srate>>m_ds,qv); +#endif + + vorbis_comment_init(&vc); + if (encname) vorbis_comment_add_tag(&vc,"ENCODER",(char *)encname); + vorbis_analysis_init(&vd,&vi); + vorbis_block_init(&vd,&vb); + ogg_stream_init(&os,m_ser=serno); + + if (m_err) return; + + + reinit(1); + } + + void reinit(int bla=0) + { + if (!bla) + { + ogg_stream_clear(&os); + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + + vorbis_analysis_init(&vd,&vi); + vorbis_block_init(&vd,&vb); + ogg_stream_init(&os,m_ser++); //++? + + outqueue.Advance(outqueue.Available()); + outqueue.Compact(); + } + + + ogg_packet header; + ogg_packet header_comm; + ogg_packet header_code; + vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); + ogg_stream_packetin(&os,&header); /* automatically placed in its own page */ + ogg_stream_packetin(&os,&header_comm); + ogg_stream_packetin(&os,&header_code); + + for (;;) + { + ogg_page og; + int result=ogg_stream_flush(&os,&og); + if(result==0)break; + outqueue.Add(og.header,og.header_len); + outqueue.Add(og.body,og.body_len); + } + } + + void Encode(float *in, int inlen, int advance=1, int spacing=1) // length in sample (PAIRS) + { + if (m_err) return; + + if (inlen == 0) + { + // disable this for now, it fucks us sometimes + // maybe we should throw some silence in instead? + vorbis_analysis_wrote(&vd,0); + } + else + { + inlen >>= m_ds; + float **buffer=vorbis_analysis_buffer(&vd,inlen); + int i,i2=0; + + if (m_nch==1) + { + for (i = 0; i < inlen; i ++) + { + buffer[0][i]=in[i2]; + i2+=advance<2) + { + int n=m_nch; + for (i = 0; i < inlen; i ++) + { + int a; + int i3=i2; + for(a=0;a +#include "pcmfmtcvt.h" +#include "wdlstring.h" + +class WaveWriter +{ + public: + // appending doesnt check sample types + WaveWriter() + { + m_fp=0; + m_bps=0; + m_srate=0; + m_nch=0; + } + + WaveWriter(const char *filename, int bps, int nch, int srate, int allow_append=1) + { + m_fp=0; + m_bps=0; + m_srate=0; + m_nch=0; + Open(filename,bps,nch,srate,allow_append); + + } + + int Open(const char *filename, int bps, int nch, int srate, int allow_append=1) + { + m_fn.Set(filename); + m_fp=0; + if (allow_append) + { + m_fp=fopen(filename,"r+b"); + if (m_fp) + { + fseek(m_fp,0,SEEK_END); + int pos=ftell(m_fp); + if (pos < 44) + { + char buf[44]={0,}; + fwrite(buf,1,44-pos,m_fp); + } + } + } + if (!m_fp) + { + m_fp=fopen(filename,"wb"); + if (!m_fp) return 0; + + char tbuf[44]; + fwrite(tbuf,1,44,m_fp); // room for header + } + m_bps=bps; + m_nch=nch>1?2:1; + m_srate=srate; + + return !!m_fp; + } + + ~WaveWriter() + { + if (m_fp) + { + int bytelen=ftell(m_fp)-44; + fseek(m_fp,0,SEEK_SET); + + // write header + fwrite("RIFF",1,4,m_fp); + int riff_size=bytelen+44-8; + int x; + for (x = 0; x < 32; x += 8) + { + unsigned char c=(riff_size>>x)&255; + fwrite(&c,1,1,m_fp); + } + fwrite("WAVEfmt \x10\0\0\0",1,12,m_fp); + fwrite("\1\0",1,2,m_fp); // PCM + + for (x = 0; x < 16; x += 8) // nch + { + char c=(m_nch>>x)&255; + fwrite(&c,1,1,m_fp); + } + for (x = 0; x < 32; x += 8) // srate + { + char c=(m_srate>>x)&255; + fwrite(&c,1,1,m_fp); + } + for (x = 0; x < 32; x += 8) // bytes_per_sec + { + char c=((m_nch * (m_bps/8) * m_srate)>>x)&255; + fwrite(&c,1,1,m_fp); + } + int blockalign=m_nch * (m_bps/8); + for (x = 0; x < 16; x += 8) // block alignment + { + char c=(blockalign>>x)&255; + fwrite(&c,1,1,m_fp); + } + for (x = 0; x < 16; x += 8) // bits/sample + { + char c=((m_bps&~7)>>x)&255; + fwrite(&c,1,1,m_fp); + } + fwrite("data",1,4,m_fp); + for (x = 0; x < 32; x += 8) // size + { + char c=((bytelen)>>x)&255; + fwrite(&c,1,1,m_fp); + } + + fclose(m_fp); + m_fp=0; + } + } + + const char *GetFileName() { return m_fn.Get(); } + + int Status() { return !!m_fp; } + + int BytesWritten() + { + if (m_fp) return ftell(m_fp)-44; + return 0; + } + + void WriteRaw(void *buf, int len) + { + if (m_fp) fwrite(buf,1,len,m_fp); + } + + void WriteFloats(float *samples, int nsamples) + { + if (!m_fp) return; + + if (m_bps == 16) + { + while (nsamples-->0) + { + short a; + float_TO_INT16(a,*samples); + unsigned char c=a&0xff; + fwrite(&c,1,1,m_fp); + c=a>>8; + fwrite(&c,1,1,m_fp); + samples++; + } + } + else if (m_bps == 24) + { + while (nsamples-->0) + { + unsigned char a[3]; + float_to_i24(samples,a); + fwrite(a,1,3,m_fp); + samples++; + } + } + } + + void WriteDoubles(double *samples, int nsamples) + { + if (!m_fp) return; + + if (m_bps == 16) + { + while (nsamples-->0) + { + short a; + double_TO_INT16(a,*samples); + unsigned char c=a&0xff; + fwrite(&c,1,1,m_fp); + c=a>>8; + fwrite(&c,1,1,m_fp); + samples++; + } + } + else if (m_bps == 24) + { + while (nsamples-->0) + { + unsigned char a[3]; + double_to_i24(samples,a); + fwrite(a,1,3,m_fp); + samples++; + } + } + } + + void WriteFloatsNI(float **samples, int offs, int nsamples, int nchsrc=0) + { + if (!m_fp) return; + + if (nchsrc < 1) nchsrc=m_nch; + + float *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL}; + + if (m_bps == 16) + { + while (nsamples-->0) + { + int ch; + for (ch = 0; ch < m_nch; ch ++) + { + short a; + float_TO_INT16(a,tmpptrs[ch][0]); + unsigned char c=a&0xff; + fwrite(&c,1,1,m_fp); + c=a>>8; + fwrite(&c,1,1,m_fp); + tmpptrs[ch]++; + } + } + } + else if (m_bps == 24) + { + while (nsamples-->0) + { + int ch; + for (ch = 0; ch < m_nch; ch ++) + { + unsigned char a[3]; + float_to_i24(tmpptrs[ch],a); + fwrite(a,1,3,m_fp); + tmpptrs[ch]++; + } + } + } + } + + void WriteDoublesNI(double **samples, int offs, int nsamples, int nchsrc=0) + { + if (!m_fp) return; + + if (nchsrc < 1) nchsrc=m_nch; + + double *tmpptrs[2]={samples[0]+offs,m_nch>1?(nchsrc>1?samples[1]+offs:samples[0]+offs):NULL}; + + if (m_bps == 16) + { + while (nsamples-->0) + { + int ch; + for (ch = 0; ch < m_nch; ch ++) + { + short a; + double_TO_INT16(a,tmpptrs[ch][0]); + unsigned char c=a&0xff; + fwrite(&c,1,1,m_fp); + c=a>>8; + fwrite(&c,1,1,m_fp); + tmpptrs[ch]++; + } + } + } + else if (m_bps == 24) + { + while (nsamples-->0) + { + int ch; + for (ch = 0; ch < m_nch; ch ++) + { + unsigned char a[3]; + double_to_i24(tmpptrs[ch],a); + fwrite(a,1,3,m_fp); + tmpptrs[ch]++; + } + } + } + } + + + int get_nch() { return m_nch; } + int get_srate() { return m_srate; } + int get_bps() { return m_bps; } + + private: + WDL_String m_fn; + FILE *m_fp; + int m_bps,m_nch,m_srate; +}; + + +#endif//_WAVWRITE_H_ \ No newline at end of file diff --git a/WDL/wdlcstring.h b/WDL/wdlcstring.h new file mode 100644 index 00000000..a6f92f15 --- /dev/null +++ b/WDL/wdlcstring.h @@ -0,0 +1,163 @@ +/* + WDL - wdlcstring.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* +C string manipulation utilities -- [v]snprintf for Win32, also snprintf_append, lstrcatn, etc + */ +#ifndef _WDL_CSTRING_H_ +#define _WDL_CSTRING_H_ + +#include +#include + +#include "wdltypes.h" + +#ifdef _WDL_CSTRING_IMPL_ONLY_ + #ifdef _WDL_CSTRING_IF_ONLY_ + #undef _WDL_CSTRING_IF_ONLY_ + #endif + #define _WDL_CSTRING_PREFIX +#else + #define _WDL_CSTRING_PREFIX static +#endif + + + +#if defined(_WIN32) && defined(_MSC_VER) + // provide snprintf()/vsnprintf() for win32 -- note that these have no way of knowing + // what the amount written was, code should(must) be written to not depend on this. + #ifdef snprintf + #undef snprintf + #endif + #define snprintf WDL_snprintf + + #ifdef vsnprintf + #undef vsnprintf + #endif + #define vsnprintf WDL_vsnprintf + +#endif // win32 snprintf/vsnprintf + +// use wdlcstring.h's lstrcpyn_safe rather than the real lstrcpyn. +#ifdef _WIN32 + #ifdef lstrcpyn + #undef lstrcpyn + #endif + #define lstrcpyn lstrcpyn_safe +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WDL_CSTRING_IF_ONLY_ + + void lstrcpyn_safe(char *o, const char *in, int count); + void lstrcatn(char *o, const char *in, int count); + void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...); + void vsnprintf_append(char *o, int count, const char *format, va_list va); + + #if defined(_WIN32) && defined(_MSC_VER) + void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args); + void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...); + #endif + +#else + + + #if defined(_WIN32) && defined(_MSC_VER) + + _WDL_CSTRING_PREFIX void WDL_vsnprintf(char *o, size_t count, const char *format, va_list args) + { + if (count>0) + { + int rv; + o[0]=0; + rv=_vsnprintf(o,count,format,args); // returns -1 if over, and does not null terminate, ugh + if (rv < 0 || rv>=(int)count-1) o[count-1]=0; + } + } + _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) WDL_snprintf(char *o, size_t count, const char *format, ...) + { + if (count>0) + { + int rv; + va_list va; + va_start(va,format); + o[0]=0; + rv=_vsnprintf(o,count,format,va); // returns -1 if over, and does not null terminate, ugh + va_end(va); + + if (rv < 0 || rv>=(int)count-1) o[count-1]=0; + } + } + #endif + + _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, int count) + { + if (count>0) + { + while (--count>0 && *in) *o++ = *in++; + *o=0; + } + } + + _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, int count) + { + if (count>0) + { + while (*o) { if (--count < 1) return; o++; } + while (--count>0 && *in) *o++ = *in++; + *o=0; + } + } + _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...) + { + if (count>0) + { + va_list va; + while (*o) { if (--count < 1) return; o++; } + va_start(va,format); + vsnprintf(o,count,format,va); + va_end(va); + } + } + + _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, int count, const char *format, va_list va) + { + if (count>0) + { + while (*o) { if (--count < 1) return; o++; } + vsnprintf(o,count,format,va); + } + } + +#endif + + +#ifdef __cplusplus +}; +#endif + +#undef _WDL_CSTRING_PREFIX + +#endif diff --git a/WDL/wdlstring.h b/WDL/wdlstring.h new file mode 100644 index 00000000..4030778c --- /dev/null +++ b/WDL/wdlstring.h @@ -0,0 +1,290 @@ +/* + WDL - wdlstring.h + Copyright (C) 2005 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides a simple class for variable-length string manipulation. + It provides only the simplest features, and does not do anything confusing like + operator overloading. It uses a WDL_HeapBuf for internal storage. + + Actually: there are WDL_String and WDL_FastString -- the latter's Get() returns const char, and tracks + the length of the string, which is often faster. Because of this, you are not permitted to directly modify + the buffer returned by Get(). + + +*/ + +#ifndef _WDL_STRING_H_ +#define _WDL_STRING_H_ + +#include "heapbuf.h" +#include +#include + +#ifndef WDL_STRING_IMPL_ONLY +class WDL_String +{ + public: + #ifdef WDL_STRING_INTF_ONLY + void Set(const char *str, int maxlen=0); + void Set(const WDL_String *str, int maxlen=0); + void Append(const char *str, int maxlen=0); + void Append(const WDL_String *str, int maxlen=0); + void DeleteSub(int position, int len); + void Insert(const char *str, int position, int maxlen=0); + void Insert(const WDL_String *str, int position, int maxlen=0); + void SetLen(int length, bool resizeDown=false); + void Ellipsize(int minlen, int maxlen); + + void SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist); + void WDL_VARARG_WARN(printf,3,4) SetFormatted(int maxlen, const char *fmt, ...); + void WDL_VARARG_WARN(printf,3,4) AppendFormatted(int maxlen, const char *fmt, ...); + #endif + + #ifdef WDL_STRING_FASTSUB_DEFINED + const char *Get() const { return m_hb.GetSize()?(char*)m_hb.Get():""; } + int GetLength() const { int a = m_hb.GetSize(); return a>0?a-1:0; } + #else + char *Get() const + { + if (m_hb.GetSize()) return (char *)m_hb.Get(); + static char c; c=0; return &c; // don't return "", in case it gets written to. + } + int GetLength() const { return m_hb.GetSize()?(int)strlen((const char*)m_hb.Get()):0; } + #endif + + explicit WDL_String(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_String(4)")) { } + explicit WDL_String(const char *initial=NULL, int initial_len=0) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String")) + { + if (initial) Set(initial,initial_len); + } + WDL_String(const WDL_String &s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(2)")) { Set(&s); } + WDL_String(const WDL_String *s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(3)")) { if (s && s != this) Set(s); } + ~WDL_String() { } +#endif // ! WDL_STRING_IMPL_ONLY + +#ifndef WDL_STRING_INTF_ONLY + #ifdef WDL_STRING_IMPL_ONLY + #define WDL_STRING_FUNCPREFIX WDL_String:: + #define WDL_STRING_DEFPARM(x) + #else + #define WDL_STRING_FUNCPREFIX + #define WDL_STRING_DEFPARM(x) =(x) + #endif + + void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0)) + { + int s=0; + if (maxlen>0) while (s < maxlen && str[s]) s++; + else s=(int)strlen(str); + __doSet(0,str,s,0); + } + + void WDL_STRING_FUNCPREFIX Set(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) + { + #ifdef WDL_STRING_FASTSUB_DEFINED + int s = str->GetLength(); + if (maxlen>0 && maxlenGet(),s,0); + #else + Set(str->Get(), maxlen); // might be faster: "partial" strlen + #endif + } + + void WDL_STRING_FUNCPREFIX Append(const char *str, int maxlen WDL_STRING_DEFPARM(0)) + { + int s=0; + if (maxlen>0) while (s < maxlen && str[s]) s++; + else s=(int)strlen(str); + + __doSet(GetLength(),str,s,0); + } + + void WDL_STRING_FUNCPREFIX Append(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0)) + { + #ifdef WDL_STRING_FASTSUB_DEFINED + int s = str->GetLength(); + if (maxlen>0 && maxlenGet(),s,0); + #else + Append(str->Get(), maxlen); // might be faster: "partial" strlen + #endif + } + + void WDL_STRING_FUNCPREFIX DeleteSub(int position, int len) + { + char *p=(char *)m_hb.Get(); + if (!m_hb.GetSize() || !*p) return; + int l=m_hb.GetSize()-1; + if (position < 0 || position >= l) return; + if (position+len > l) len=l-position; + if (len>0) + { + memmove(p+position,p+position+len,l-position-len+1); + m_hb.Resize(l+1-len,false); + } + } + + void WDL_STRING_FUNCPREFIX Insert(const char *str, int position, int maxlen WDL_STRING_DEFPARM(0)) + { + int ilen=0; + if (maxlen>0) while (ilen < maxlen && str[ilen]) ilen++; + else ilen=(int)strlen(str); + + int srclen = GetLength(); + if (position<0) position=0; + else if (position>srclen) position=srclen; + if (ilen>0) __doSet(position,str,ilen,srclen-position); + } + + void WDL_STRING_FUNCPREFIX Insert(const WDL_String *str, int position, int maxlen WDL_STRING_DEFPARM(0)) + { + #ifdef WDL_STRING_FASTSUB_DEFINED + int ilen = str->GetLength(); + if (maxlen>0 && maxlen0 ? m_hb.GetSize()-1 : 0; + if (position<0) position=0; + else if (position>srclen) position=srclen; + if (ilen>0) __doSet(position,str->Get(),ilen,srclen-position); + #else + Insert(str->Get(), position, maxlen); // might be faster: "partial" strlen + #endif + } + + void WDL_STRING_FUNCPREFIX SetLen(int length, bool resizeDown WDL_STRING_DEFPARM(false)) + { + #ifdef WDL_STRING_FASTSUB_DEFINED + int osz = m_hb.GetSize()?m_hb.GetSize()-1:0; + #endif + char *b=(char*)m_hb.Resize(length+1,resizeDown); + if (m_hb.GetSize()==length+1) + { + #ifdef WDL_STRING_FASTSUB_DEFINED + if (length > osz) memset(b+osz,' ',length-osz); + #endif + b[length]=0; + } + } + + void WDL_STRING_FUNCPREFIX SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist) + { + int offs = append ? GetLength() : 0; + char* b= (char*) m_hb.Resize(offs+maxlen+1,false)+offs; + if (m_hb.GetSize() != offs+maxlen+1) return; + + #ifdef _WIN32 + int written = _vsnprintf(b, maxlen+1, fmt, arglist); + if (written < 0 || written>=maxlen) b[written=b[0]?maxlen:0]=0; + #else + int written = vsnprintf(b, maxlen+1, fmt, arglist); + if (written > maxlen) written=maxlen; + #endif + + m_hb.Resize(offs + written + 1,false); + } + + void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX SetFormatted(int maxlen, const char *fmt, ...) + { + va_list arglist; + va_start(arglist, fmt); + SetAppendFormattedArgs(false,maxlen,fmt,arglist); + va_end(arglist); + } + + void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX AppendFormatted(int maxlen, const char *fmt, ...) + { + va_list arglist; + va_start(arglist, fmt); + SetAppendFormattedArgs(true,maxlen,fmt,arglist); + va_end(arglist); + } + + void WDL_STRING_FUNCPREFIX Ellipsize(int minlen, int maxlen) + { + if (maxlen >= 4 && m_hb.GetSize() && GetLength() > maxlen) + { + if (minlen<0) minlen=0; + char *b = (char *)m_hb.Get(); + int i; + for (i = maxlen-4; i >= minlen; --i) + { + if (b[i] == ' ') + { + memcpy(b+i, "...",4); + m_hb.Resize(i+4,false); + break; + } + } + if (i < minlen && maxlen >= 4) + { + memcpy(b+maxlen-4, "...",4); + m_hb.Resize(maxlen,false); + } + } + } + +#ifndef WDL_STRING_IMPL_ONLY + private: +#endif + void WDL_STRING_FUNCPREFIX __doSet(int offs, const char *str, int len, int trailkeep) + { + if (len>0 || (!trailkeep && !offs && m_hb.GetSize()>1)) // if non-empty, or (empty and allocated and Set() rather than append/insert), then allow update, otherwise do nothing + { + char *newbuf=(char*)m_hb.Resize(offs+len+trailkeep+1,false); + if (m_hb.GetSize()==offs+len+trailkeep+1) + { + if (trailkeep>0) memmove(newbuf+offs+len,newbuf+offs,trailkeep); + memcpy(newbuf+offs,str,len); + newbuf[offs+len+trailkeep]=0; + } + } + } + + #undef WDL_STRING_FUNCPREFIX + #undef WDL_STRING_DEFPARM +#endif // ! WDL_STRING_INTF_ONLY + +#ifndef WDL_STRING_IMPL_ONLY + + private: + #ifdef WDL_STRING_INTF_ONLY + void __doSet(int offs, const char *str, int len, int trailkeep); + #endif + + WDL_HeapBuf m_hb; +}; +#endif + +#ifndef WDL_STRING_FASTSUB_DEFINED +#undef _WDL_STRING_H_ +#define WDL_STRING_FASTSUB_DEFINED +#define WDL_String WDL_FastString +#include "wdlstring.h" +#undef WDL_STRING_FASTSUB_DEFINED +#undef WDL_String +#endif + +#endif + diff --git a/WDL/wdltypes.h b/WDL/wdltypes.h new file mode 100644 index 00000000..181b2121 --- /dev/null +++ b/WDL/wdltypes.h @@ -0,0 +1,77 @@ +#ifndef _WDLTYPES_ +#define _WDLTYPES_ + +#ifdef _MSC_VER + +typedef __int64 WDL_INT64; +typedef unsigned __int64 WDL_UINT64; + +#else + +typedef long long WDL_INT64; +typedef unsigned long long WDL_UINT64; + +#endif + +#define WDL_UINT64_CONST(x) ((WDL_UINT64)(x)) +#define WDL_INT64_CONST(x) ((WDL_INT64)(x)) + + +#if !defined(_MSC_VER) || _MSC_VER > 1200 +#define WDL_DLGRET INT_PTR CALLBACK +#else +#define WDL_DLGRET BOOL CALLBACK +#endif + + +#ifdef _WIN32 +#include +#else +#include +typedef intptr_t INT_PTR; +typedef uintptr_t UINT_PTR; +#endif + +#if defined(__ppc__) || !defined(__cplusplus) +typedef char WDL_bool; +#else +typedef bool WDL_bool; +#endif + +#ifndef GWLP_USERDATA +#define GWLP_USERDATA GWL_USERDATA +#define GWLP_WNDPROC GWL_WNDPROC +#define GWLP_HINSTANCE GWL_HINSTANCE +#define GWLP_HWNDPARENT GWL_HWNDPARENT +#define DWLP_USER DWL_USER +#define DWLP_DLGPROC DWL_DLGPROC +#define DWLP_MSGRESULT DWL_MSGRESULT +#define SetWindowLongPtr(a,b,c) SetWindowLong(a,b,c) +#define GetWindowLongPtr(a,b) GetWindowLong(a,b) +#define SetWindowLongPtrW(a,b,c) SetWindowLongW(a,b,c) +#define GetWindowLongPtrW(a,b) GetWindowLongW(a,b) +#define SetWindowLongPtrA(a,b,c) SetWindowLongA(a,b,c) +#define GetWindowLongPtrA(a,b) GetWindowLongA(a,b) + +#define GCLP_WNDPROC GCL_WNDPROC +#define GCLP_HICON GCL_HICON +#define GCLP_HICONSM GCL_HICONSM +#define SetClassLongPtr(a,b,c) SetClassLong(a,b,c) +#define GetClassLongPtr(a,b) GetClassLong(a,b) +#endif + + +#ifdef __GNUC__ +// for structures that contain doubles, or doubles in structures that are after stuff of questionable alignment (for OSX/linux) + #define WDL_FIXALIGN __attribute__ ((aligned (8))) +// usage: void func(int a, const char *fmt, ...) WDL_VARARG_WARN(printf,2,3); // note: if member function, this pointer is counted as well, so as member function that would be 3,4 + #define WDL_VARARG_WARN(x,n,s) __attribute__ ((format (x,n,s))) + +#else + #define WDL_FIXALIGN + #define WDL_VARARG_WARN(x,n,s) +#endif + + + +#endif diff --git a/WDL/win32_curses/curses.h b/WDL/win32_curses/curses.h new file mode 100644 index 00000000..398dbd8c --- /dev/null +++ b/WDL/win32_curses/curses.h @@ -0,0 +1,180 @@ +#ifndef _CURSES_WIN32SIM_H_ +#define _CURSES_WIN32SIM_H_ + +#if !defined(_WIN32) && !defined(MAC_NATIVE) && !defined(FORCE_WIN32_CURSES) + #ifdef MAC + #include + #else + #include + #endif +#else + + #ifdef _WIN32 + #include + #else + #include "../swell/swell.h" + #endif + #include "../queue.h" + +/* +** this implements a tiny subset of curses on win32. +** It creates a window (Resizeable by user), and gives you a callback to run +** your UI. +*/ + + +// if you need multiple contexts, define this in your sourcefiles BEFORE including curses.h +// if you don't need multiple contexts, declare win32CursesCtx g_curses_context; in one of your source files. +#ifndef CURSES_INSTANCE +#define CURSES_INSTANCE (&g_curses_context) +#endif + +#define LINES ((CURSES_INSTANCE)->lines) +#define COLS ((CURSES_INSTANCE)->cols) + +//ncurses WIN32 wrapper functions + + +#define addnstr(str,n) __addnstr(CURSES_INSTANCE,str,n) +#define addstr(str) __addnstr(CURSES_INSTANCE,str,-1) +#define addch(c) __addch(CURSES_INSTANCE,c) + +#define mvaddstr(x,y,str) __mvaddnstr(CURSES_INSTANCE,x,y,str,-1) +#define mvaddnstr(x,y,str,n) __mvaddnstr(CURSES_INSTANCE,x,y,str,n) +#define clrtoeol() __clrtoeol(CURSES_INSTANCE) +#define move(x,y) __move(CURSES_INSTANCE, x,y, 0) +#define attrset(a) (CURSES_INSTANCE)->m_cur_attr=(a) +#define bkgdset(a) (CURSES_INSTANCE)->m_cur_erase_attr=(a) +#define initscr() __initscr(CURSES_INSTANCE) +#define endwin() __endwin(CURSES_INSTANCE) +#define curses_erase(x) __curses_erase(x) +#define start_color() +#define init_pair(x,y,z) __init_pair((CURSES_INSTANCE),x,y,z) +#define has_colors() 1 + +#define A_NORMAL 0 +#define A_BOLD 1 +#define COLOR_PAIR(x) ((x)< +#include +#else +#include "../swell/swell.h" +#endif +#define CURSES_INSTANCE ___ERRROR_____ + +#include "curses.h" + +#include +#include + +#define CURSOR_BLINK_TIMER_MS 400 +#define CURSOR_BLINK_TIMER 2 +#define CURSOR_BLINK_TIMER_ZEROEVERY 3 + +#ifndef WIN32_CURSES_CURSORTYPE +#define WIN32_CURSES_CURSORTYPE 1 // 1 for vertical bar, 2 for horz bar, 0 for block +#endif +#define WIN32CURSES_CLASS_NAME "WDLCursesWindow" + +#define WIN32_CONSOLE_KBQUEUE + +static void doFontCalc(win32CursesCtx*, HDC); + +static void m_InvalidateArea(win32CursesCtx *ctx, int sx, int sy, int ex, int ey) +{ + doFontCalc(ctx,NULL); + + RECT r; + r.left=sx*ctx->m_font_w; + r.top=sy*ctx->m_font_h; + r.right=ex*ctx->m_font_w; + r.bottom=ey*ctx->m_font_h; + if (ctx->m_hwnd) InvalidateRect(ctx->m_hwnd,&r,FALSE); +} + +void __addnstr(win32CursesCtx *ctx, const char *str,int n) +{ + if (ctx->m_cursor_x<0) + { + int skip = -ctx->m_cursor_x; + ctx->m_cursor_x=0; + if (n>=0) + { + n -= skip; + if (n<0)n=0; + } + int slen = strlen(str); + str += min(slen,skip); + } + + int sx=ctx->m_cursor_x; + int sy=ctx->m_cursor_y; + if (n==0||!ctx->m_framebuffer || ctx->m_cursor_y < 0 || ctx->m_cursor_y >= ctx->lines) return; + char *p=(char *)ctx->m_framebuffer + 2*(ctx->m_cursor_x + ctx->m_cursor_y*ctx->cols); + while (n-- && *str) + { + p[0]=*str++; + p[1]=ctx->m_cur_attr; + p+=2; + if (++ctx->m_cursor_x >= ctx->cols) + { + ctx->m_cursor_y++; + ctx->m_cursor_x=0; + if (ctx->m_cursor_y >= ctx->lines) { ctx->m_cursor_y=ctx->lines-1; ctx->m_cursor_x=ctx->cols-1; break; } + } + } + m_InvalidateArea(ctx,sx,sy,sy < ctx->m_cursor_y ? ctx->cols : ctx->m_cursor_x+1,ctx->m_cursor_y+1); +} + +void __clrtoeol(win32CursesCtx *ctx) +{ + if (ctx->m_cursor_x<0)ctx->m_cursor_x=0; + int n = ctx->cols - ctx->m_cursor_x; + if (!ctx->m_framebuffer || ctx->m_cursor_y < 0 || ctx->m_cursor_y >= ctx->lines || n < 1) return; + char *p=(char *)ctx->m_framebuffer + 2*(ctx->m_cursor_x + ctx->m_cursor_y*ctx->cols); + int sx=ctx->m_cursor_x; + while (n--) + { + p[0]=0; + p[1]=ctx->m_cur_erase_attr; + p+=2; + } + m_InvalidateArea(ctx,sx,ctx->m_cursor_y,ctx->cols,ctx->m_cursor_y+1); +} + +void __curses_erase(win32CursesCtx *ctx) +{ + ctx->m_cur_attr=0; + ctx->m_cur_erase_attr=0; + if (ctx->m_framebuffer) memset(ctx->m_framebuffer,0,ctx->cols*ctx->lines*2); + ctx->m_cursor_x=0; + ctx->m_cursor_y=0; + m_InvalidateArea(ctx,0,0,ctx->cols,ctx->lines); +} + +void __move(win32CursesCtx *ctx, int x, int y, int noupdest) +{ + m_InvalidateArea(ctx,ctx->m_cursor_x,ctx->m_cursor_y,ctx->m_cursor_x+1,ctx->m_cursor_y+1); + ctx->m_cursor_x=y; + ctx->m_cursor_y=x; + if (!noupdest) m_InvalidateArea(ctx,ctx->m_cursor_x,ctx->m_cursor_y,ctx->m_cursor_x+1,ctx->m_cursor_y+1); +} + + +void __init_pair(win32CursesCtx *ctx, int pair, int fcolor, int bcolor) +{ + if (pair < 0 || pair >= COLOR_PAIRS) return; + + pair=COLOR_PAIR(pair); + + ctx->colortab[pair][0]=fcolor; + ctx->colortab[pair][1]=bcolor; + + if (fcolor & 0xff) fcolor|=0xff; + if (fcolor & 0xff00) fcolor|=0xff00; + if (fcolor & 0xff0000) fcolor|=0xff0000; + ctx->colortab[pair|A_BOLD][0]=fcolor; + ctx->colortab[pair|A_BOLD][1]=bcolor; + +} + +static int xlateKey(int msg, int wParam, int lParam) +{ + if (msg == WM_KEYDOWN) + { +#ifndef _WIN32 + if (lParam & FVIRTKEY) +#endif + switch (wParam) + { + case VK_HOME: return KEY_HOME; + case VK_UP: return KEY_UP; + case VK_PRIOR: return KEY_PPAGE; + case VK_LEFT: return KEY_LEFT; + case VK_RIGHT: return KEY_RIGHT; + case VK_END: return KEY_END; + case VK_DOWN: return KEY_DOWN; + case VK_NEXT: return KEY_NPAGE; + case VK_INSERT: return KEY_IC; + case VK_DELETE: return KEY_DC; + case VK_F1: return KEY_F1; + case VK_F2: return KEY_F2; + case VK_F3: return KEY_F3; + case VK_F4: return KEY_F4; + case VK_F5: return KEY_F5; + case VK_F6: return KEY_F6; + case VK_F7: return KEY_F7; + case VK_F8: return KEY_F8; + case VK_F9: return KEY_F9; + case VK_F10: return KEY_F10; + case VK_F11: return KEY_F11; + case VK_F12: return KEY_F12; +#ifndef _WIN32 + case VK_SUBTRACT: return (GetAsyncKeyState(VK_SHIFT)&0x8000)?'_':'-'; // numpad - +#endif + } + + switch (wParam) + { + case VK_RETURN: case VK_BACK: case VK_TAB: case VK_ESCAPE: return wParam; + case VK_CONTROL: break; + + default: + if(GetAsyncKeyState(VK_CONTROL)&0x8000) + { + if (wParam>='a' && wParam<='z') + { + wParam += 1-'a'; + return wParam; + } + if (wParam>='A' && wParam<='Z') + { + wParam += 1-'A'; + return wParam; + } + } + } + } + +#ifdef _WIN32 // todo : fix for nonwin32 + if (msg == WM_CHAR) + { + if(wParam>=32) return wParam; + } +#else + + //osx/linux + if (wParam >= 32) + { + if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) + { + if (wParam>='A' && wParam<='Z') + { + if ((GetAsyncKeyState(VK_MENU)&0x8000)) wParam -= 'A'-1; + else + wParam += 'a'-'A'; + } + } + else + { + if (wParam=='-') wParam='_'; + else if (wParam>='0' && wParam<='9') + { + if (wParam=='0') wParam = ')'; + else if (wParam=='1') wParam = '!'; + else if (wParam=='2') wParam = '@'; + else if (wParam=='3') wParam = '#'; + else if (wParam=='4') wParam = '$'; + else if (wParam=='5') wParam = '%'; + else if (wParam=='6') wParam = '^'; + else if (wParam=='7') wParam = '&'; + else if (wParam=='8') wParam = '*'; + else if (wParam=='9') wParam = '('; + } + } + return wParam; + } + +#endif + return ERR; +} + + +static void m_reinit_framebuffer(win32CursesCtx *ctx) +{ + doFontCalc(ctx,NULL); + RECT r; + + GetClientRect(ctx->m_hwnd,&r); + + ctx->lines=r.bottom / ctx->m_font_h; + ctx->cols=r.right / ctx->m_font_w; + if (ctx->lines<1) ctx->lines=1; + if (ctx->cols<1) ctx->cols=1; + ctx->m_cursor_x=0; + ctx->m_cursor_y=0; + ctx->m_framebuffer=(unsigned char *)realloc(ctx->m_framebuffer,2*ctx->lines*ctx->cols); + if (ctx->m_framebuffer) memset(ctx->m_framebuffer,0,2*ctx->lines*ctx->cols); +} +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 0x20A +#endif + +LRESULT CALLBACK cursesWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + win32CursesCtx *ctx = (win32CursesCtx*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + +#ifdef _WIN32 + + static int Scroll_Message; + if (!Scroll_Message) + { + Scroll_Message = (int)RegisterWindowMessage("MSWHEEL_ROLLMSG"); + if (!Scroll_Message) Scroll_Message=-1; + } + if (Scroll_Message > 0 && uMsg == (UINT)Scroll_Message) + { + uMsg=WM_MOUSEWHEEL; + wParam<<=16; + } +#endif + + if (ctx)switch (uMsg) + { + case WM_DESTROY: + ctx->m_hwnd=0; + return 0; +#ifdef WIN32_CONSOLE_KBQUEUE + case WM_CHAR: case WM_KEYDOWN: + + { + int a=xlateKey(uMsg,wParam,lParam); + if (a != ERR && ctx->m_kbq) + { + ctx->m_kbq->Add(&a,sizeof(int)); + } + } + case WM_KEYUP: + return 0; +#endif + case WM_GETMINMAXINFO: + { + LPMINMAXINFO p=(LPMINMAXINFO)lParam; + p->ptMinTrackSize.x = 160; + p->ptMinTrackSize.y = 120; + } + return 0; + case WM_SIZE: + if (wParam != SIZE_MINIMIZED) + { + m_reinit_framebuffer(ctx); + ctx->m_need_redraw=1; + } + return 0; + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + SetFocus(hwnd); + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_CAPTURECHANGED: + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + if (ctx && ctx->onMouseMessage) return ctx->onMouseMessage(ctx->user_data,hwnd,uMsg,wParam,lParam); + return 0; +#ifdef _WIN32 + case WM_GETDLGCODE: + if (GetParent(hwnd)) + { + return DLGC_WANTALLKEYS; + } + return 0; +#endif + case WM_TIMER: + if (wParam==CURSOR_BLINK_TIMER && ctx) + { + int la = ctx->m_cursor_state; + ctx->m_cursor_state= (ctx->m_cursor_state+1)%CURSOR_BLINK_TIMER_ZEROEVERY; + + if (!!ctx->m_cursor_state != !!la) + __move(ctx,ctx->m_cursor_y,ctx->m_cursor_x,1);// refresh cursor + } +#ifdef WIN32_CONSOLE_KBQUEUE + if (wParam == 1) + { + if (!ctx->m_intimer) + { + ctx->m_intimer=1; + if (ctx->ui_run) ctx->ui_run(ctx); + ctx->m_intimer=0; + } + } +#endif + return 0; + case WM_CREATE: + + // this only is called on osx or from standalone, it seems, since on win32 ctx isnt set up yet + ctx->m_hwnd=hwnd; + #ifdef WIN32_CONSOLE_KBQUEUE + SetTimer(hwnd,1,33,NULL); + #endif + #ifndef _WIN32 + m_reinit_framebuffer(ctx); + ctx->m_need_redraw=1; + #endif + SetTimer(hwnd,CURSOR_BLINK_TIMER,CURSOR_BLINK_TIMER_MS,NULL); + return 0; + case WM_ERASEBKGND: + return 0; + case WM_PAINT: + { + RECT r; +#ifdef _WIN32 + if (GetUpdateRect(hwnd,&r,FALSE)) +#else + GetClientRect(hwnd,&r); +#endif + { + PAINTSTRUCT ps; + HDC hdc=BeginPaint(hwnd,&ps); + if (hdc) + { + doFontCalc(ctx,ps.hdc); + + HGDIOBJ oldf=SelectObject(hdc,ctx->mOurFont); + int y,ypos; + int lattr=-1; +#ifdef _WIN32 + SetTextAlign(hdc,TA_TOP|TA_LEFT); +#endif + const char *ptr=(const char*)ctx->m_framebuffer; + RECT updr=r; + + r.left /= ctx->m_font_w; + r.top /= ctx->m_font_h; + r.bottom += ctx->m_font_h-1; + r.bottom /= ctx->m_font_h; + r.right += ctx->m_font_w-1; + r.right /= ctx->m_font_w; + + ypos = r.top * ctx->m_font_h; + ptr += 2*(r.top * ctx->cols); + + if (r.top < 0) r.top=0; + if (r.bottom > ctx->lines) r.bottom=ctx->lines; + if (r.left < 0) r.left=0; + if (r.right > ctx->cols) r.right=ctx->cols; + + HBRUSH bgbrushes[COLOR_PAIRS << NUM_ATTRBITS]; + for(y=0;ycolortab[y][1]); + + int cstate=ctx->m_cursor_state; + if (ctx->m_cursor_y != ctx->m_cursor_state_ly || + ctx->m_cursor_x != ctx->m_cursor_state_lx) + { + ctx->m_cursor_state_lx=ctx->m_cursor_x; + ctx->m_cursor_state_ly=ctx->m_cursor_y; + ctx->m_cursor_state=0; + cstate=1; + } + + if (ctx->m_framebuffer) for (y = r.top; y < r.bottom; y ++, ypos+=ctx->m_font_h, ptr += ctx->cols*2) + { + int x = r.left,xpos = r.left * ctx->m_font_w; + + const char *p = ptr + r.left*2; + + int defer_blanks=0; + + for (;; x ++, xpos+=ctx->m_font_w, p += 2) + { + char c=' ',attr=0; + + if (x < r.right) + { + c=p[0]; + attr=p[1]; + } + + bool isCursor = cstate && y == ctx->m_cursor_y && x == ctx->m_cursor_x; + bool isNotBlank = (isprint(c) && !isspace(c)); + + if (defer_blanks > 0 && (isNotBlank || isCursor || attr != lattr || x>=r.right)) + { + RECT tr={xpos - defer_blanks*ctx->m_font_w,ypos,xpos,ypos+ctx->m_font_h}; + FillRect(hdc,&tr,bgbrushes[lattr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]); + defer_blanks=0; + } + + if (x>=r.right) break; + +#if WIN32_CURSES_CURSORTYPE == 0 + if (isCursor) + { + SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); + SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); + lattr = -1; + } + else +#endif // WIN32_CURSES_CURSORTYPE == 0 + if (attr != lattr) + { + SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); + SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); + lattr=attr; + } + + if (isNotBlank||isCursor) + { + #ifdef _WIN32 + int txpos = xpos; + TextOut(hdc,txpos,ypos,isNotBlank ? p : " ",1); + #else + RECT tr={xpos,ypos,xpos+32,ypos+32}; + HBRUSH br=bgbrushes[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]; +#if WIN32_CURSES_CURSORTYPE == 0 + if (isCursor) + { + br = CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); + FillRect(hdc,&tr,br); + DeleteObject(br); + } + else +#endif + { + FillRect(hdc,&tr,br); + } + char tmp[2]={c,0}; + DrawText(hdc,isprint(c) && !isspace(c) ?tmp : " ",-1,&tr,DT_LEFT|DT_TOP|DT_NOPREFIX|DT_NOCLIP); + #endif +#if WIN32_CURSES_CURSORTYPE > 0 + if (isCursor) + { + #if WIN32_CURSES_CURSORTYPE == 1 + RECT r={xpos,ypos,xpos+2,ypos+ctx->m_font_h}; + #elif WIN32_CURSES_CURSORTYPE == 2 + RECT r={xpos,ypos+ctx->m_font_h-2,xpos+ctx->m_font_w,ypos+ctx->m_font_h}; + #endif + HBRUSH br=CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); + FillRect(hdc,&r,br); + DeleteObject(br); + } +#endif + } + else + { + defer_blanks++; + } + } + } + int rm=ctx->cols * ctx->m_font_w; + int bm=ctx->lines * ctx->m_font_h; + if (updr.right >= rm) + { + RECT tr={max(rm,updr.left),max(updr.top,0),updr.right,updr.bottom}; + FillRect(hdc,&tr,bgbrushes[0]); + } + if (updr.bottom >= bm) + { + RECT tr={max(0,updr.left),max(updr.top,bm),updr.right,updr.bottom}; + FillRect(hdc,&tr,bgbrushes[0]); + } + + for(y=0;ym_hwnd || !ctx->m_need_fontcalc) return; + + HDC hdc = hdcIn; + if (!hdc) hdc = GetDC(ctx->m_hwnd); + + if (!hdc) return; + + ctx->m_need_fontcalc=false; + HGDIOBJ oldf=SelectObject(hdc,ctx->mOurFont); + TEXTMETRIC tm; + GetTextMetrics(hdc,&tm); + ctx->m_font_h=tm.tmHeight; + ctx->m_font_w=tm.tmAveCharWidth; + SelectObject(hdc,oldf); + + if (hdc != hdcIn) ReleaseDC(ctx->m_hwnd,hdc); + +} + +static void reInitializeContext(win32CursesCtx *ctx) +{ + if (!ctx->mOurFont) ctx->mOurFont = CreateFont( +#ifdef _WIN32 + 16, +#else +#ifdef __LP64__ + 14, +#else + 13, +#endif +#endif + 0, // width + 0, // escapement + 0, // orientation +#ifdef _WIN32 + FW_NORMAL, // normal +#else + FW_BOLD, +#endif + FALSE, //italic + FALSE, //undelrine + FALSE, //strikeout + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY,//DEFAULT_QUALITY, +#ifdef _WIN32 + FF_MODERN, +#else + 0, +#endif + "Courier New"); + + ctx->m_need_fontcalc=true; + ctx->m_font_w=8; + ctx->m_font_h=8; + doFontCalc(ctx,NULL); +} + + + + +void __initscr(win32CursesCtx *ctx) +{ + __init_pair(ctx,0,RGB(192,192,192),RGB(0,0,0)); +} + +void __endwin(win32CursesCtx *ctx) +{ + if (ctx->m_hwnd) + curses_setWindowContext(ctx->m_hwnd,0); + ctx->m_hwnd=0; + free(ctx->m_framebuffer); + ctx->m_framebuffer=0; + delete ctx->m_kbq; + ctx->m_kbq=0; + if (ctx->mOurFont) DeleteObject(ctx->mOurFont); + ctx->mOurFont=0; + +} + + +int curses_getch(win32CursesCtx *ctx) +{ + if (!ctx->m_hwnd) return ERR; + + +#ifndef WIN32_CONSOLE_KBQUEUE + // if we're suppose to run the message pump ourselves (optional!) + MSG msg; + while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) + { + TranslateMessage(&msg); + int a=xlateKey(msg.message,msg.wParam,msg.lParam); + if (a != ERR) return a; + + DispatchMessage(&msg); + + } +#else + +#ifdef _WIN32 + if (ctx->want_getch_runmsgpump>0) + { + MSG msg; + if (ctx->want_getch_runmsgpump>1) + { + while(!(ctx->m_kbq && ctx->m_kbq->Available()>=(int)sizeof(int)) && GetMessage(&msg,NULL,0,0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +#endif + + if (ctx->m_kbq && ctx->m_kbq->Available()>=(int)sizeof(int)) + { + int a=*(int *) ctx->m_kbq->Get(); + ctx->m_kbq->Advance(sizeof(int)); + ctx->m_kbq->Compact(); + return a; + } +#endif + + if (ctx->m_need_redraw) + { + ctx->m_need_redraw=0; + InvalidateRect(ctx->m_hwnd,NULL,FALSE); + return 'L'-'A'+1; + } + + return ERR; +} + +void curses_setWindowContext(HWND hwnd, win32CursesCtx *ctx) +{ + SetWindowLongPtr(hwnd,GWLP_USERDATA,(INT_PTR)ctx); + if (ctx) + { + ctx->m_hwnd=hwnd; + delete ctx->m_kbq; + ctx->m_kbq=new WDL_Queue; + + free(ctx->m_framebuffer); + ctx->m_framebuffer=0; + + SetTimer(hwnd,CURSOR_BLINK_TIMER,CURSOR_BLINK_TIMER_MS,NULL); + reInitializeContext(ctx); + m_reinit_framebuffer(ctx); + InvalidateRect(hwnd,NULL,FALSE); + } +} + +static int m_regcnt; +void curses_unregisterChildClass(HINSTANCE hInstance) +{ +#ifdef _WIN32 + if (!--m_regcnt) + UnregisterClass(WIN32CURSES_CLASS_NAME,hInstance); +#endif +} + +void curses_registerChildClass(HINSTANCE hInstance) +{ +#ifdef _WIN32 + if (!m_regcnt++) + { + WNDCLASS wc={0,}; + wc.lpfnWndProc = cursesWindowProc; + wc.hInstance = hInstance; + wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.lpszClassName = WIN32CURSES_CLASS_NAME; + + RegisterClass(&wc); + } +#endif +} + +#ifndef _WIN32 +HWND curses_ControlCreator(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h) +{ + HWND hw=0; + if (!strcmp(classname,WIN32CURSES_CLASS_NAME)) + { + hw=CreateDialog(NULL,0,parent,(DLGPROC)cursesWindowProc); + } + + if (hw) + { + SetWindowLong(hw,GWL_ID,idx); + SetWindowPos(hw,HWND_TOP,x,y,w,h,SWP_NOZORDER|SWP_NOACTIVATE); + ShowWindow(hw,SW_SHOWNA); + return hw; + } + + return 0; +} + +#endif + +HWND curses_CreateWindow(HINSTANCE hInstance, win32CursesCtx *ctx, const char *title) +{ +#ifdef _WIN32 + ctx->m_hwnd = CreateWindowEx(0,WIN32CURSES_CLASS_NAME, title,WS_CAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX|WS_SYSMENU, + CW_USEDEFAULT,CW_USEDEFAULT,640,480, + NULL, NULL,hInstance,NULL); +#else + ctx->m_hwnd = CreateDialog(NULL,0,NULL,(DLGPROC)cursesWindowProc); + +#endif + if (ctx->m_hwnd) + { + curses_setWindowContext(ctx->m_hwnd,ctx); + ShowWindow(ctx->m_hwnd,SW_SHOW); + } + return ctx->m_hwnd; +} diff --git a/WDL/win32_curses/test.cpp b/WDL/win32_curses/test.cpp new file mode 100644 index 00000000..6be8ff80 --- /dev/null +++ b/WDL/win32_curses/test.cpp @@ -0,0 +1,80 @@ +#include "curses.h" + +#ifdef _WIN32 +win32CursesCtx g_curses_context; // we only need the one instance +#endif + +#ifdef _WIN32 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + g_curses_context.want_getch_runmsgpump = 1; // non-block + + curses_registerChildClass(hInstance); + curses_CreateWindow(hInstance,&g_curses_context,"Sample Test App"); +#else +int main() { +#endif + + + initscr(); + cbreak(); + noecho(); + nonl(); + intrflush(stdscr,FALSE); + keypad(stdscr,TRUE); + nodelay(stdscr,TRUE); + raw(); +#if !defined(_WIN32) && !defined(MAC_NATIVE) + ESCDELAY=0; // dont wait--at least on the console this seems to work. +#endif + + if (has_colors()) // we don't use color yet, but we could + { + start_color(); + init_pair(1, COLOR_WHITE, COLOR_BLUE); // normal status lines + init_pair(2, COLOR_BLACK, COLOR_CYAN); // value + } + + erase(); + refresh(); + + float xpos=0,ypos=0, xdir=0.7, ydir=1.5; + for (;;) + { + int t=getch(); + if (t==27) break; + else if (t== KEY_LEFT) xdir *=0.9; + else if (t== KEY_RIGHT) xdir *=1.1; + else if (t== KEY_UP) ydir *=1.1; + else if (t== KEY_DOWN) ydir *=0.9; + + xpos+=xdir; ypos+=ydir; + if (xpos >= COLS-1||xpos<1) { if (xpos<1)xpos=1; else xpos=COLS-1; xdir=-xdir; } + if (ypos >= LINES-1||ypos<1) { if (ypos<1)ypos=1; else ypos=LINES-1; ydir=-ydir; } + + erase(); + mvaddstr(ypos,xpos,"X"); + + + Sleep(10); +#ifdef _WIN32 + if (!g_curses_context.m_hwnd) break; +#endif + } + + + erase(); + refresh(); + endwin(); + +#ifdef _WIN32 + if (g_curses_context.m_hwnd) DestroyWindow(g_curses_context.m_hwnd); + curses_unregisterChildClass(hInstance); +#endif + + return 0; + + +} + + + diff --git a/WDL/win32_utf8.c b/WDL/win32_utf8.c new file mode 100644 index 00000000..7bebea52 --- /dev/null +++ b/WDL/win32_utf8.c @@ -0,0 +1,984 @@ +#include "win32_utf8.h" +#include "wdltypes.h" + +#ifdef _WIN32 + +#if !defined(WDL_NO_SUPPORT_UTF8) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef WDL_UTF8_MAXFNLEN +#define WDL_UTF8_MAXFNLEN 2048 +#endif + +#define MBTOWIDE(symbase, src) \ + int symbase##_size; \ + WCHAR symbase##_buf[1024]; \ + WCHAR *symbase = (symbase##_size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,NULL,0)) >= 1000 ? (WCHAR *)malloc(symbase##_size * sizeof(WCHAR) + 10) : symbase##_buf; \ + int symbase##_ok = symbase ? (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,src,-1,symbase,symbase##_size < 1 ? 1024 : symbase##_size)) : 0 + +#define MBTOWIDE_FREE(symbase) if (symbase != symbase##_buf) free(symbase) + + +#define WIDETOMB_ALLOC(symbase, length) \ + WCHAR symbase##_buf[1024]; \ + int symbase##_size = sizeof(symbase##_buf); \ + WCHAR *symbase = length > 1000 ? (WCHAR *)malloc(symbase##_size = (sizeof(WCHAR)*length + 10)) : symbase##_buf + +#define WIDETOMB_FREE(symbase) if (symbase != symbase##_buf) free(symbase) + +BOOL WDL_HasUTF8(const char *_str) +{ + const unsigned char *str = (const unsigned char *)_str; + BOOL hasUTF=FALSE; + + if (str) while (*str) + { + unsigned char c = *str++; + if (c<0x80) { } // allow 7 bit ascii straight through + else if (c < 0xC2 || c > 0xF7) return FALSE; // treat overlongs or other values in this range as indicators of non-utf8ness + else + { + hasUTF=TRUE; + if (str[0] < 0x80 || str[0] > 0xBF) return FALSE; + else if (c < 0xE0) str++; + else if (str[1] < 0x80 || str[1] > 0xBF) return FALSE; + else if (c < 0xF0) str+=2; + else if (str[2] < 0x80 || str[2] > 0xBF) return FALSE; + else str+=3; + } + } + return hasUTF; +} + +int GetWindowTextUTF8(HWND hWnd, LPTSTR lpString, int nMaxCount) +{ + if (lpString && nMaxCount>0 && GetVersion()< 0x80000000) + { + int alloc_size=nMaxCount; + + // prevent large values of nMaxCount from allocating memory unless the underlying text is big too + if (alloc_size > 512) + { + int l=GetWindowTextLengthW(hWnd); + if (l>=0 && l < 512) alloc_size=1000; + } + + { + WIDETOMB_ALLOC(wbuf, alloc_size); + if (wbuf) + { + GetWindowTextW(hWnd,wbuf,wbuf_size/sizeof(WCHAR)); + + if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpString,nMaxCount,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + lpString[nMaxCount-1]=0; + + WIDETOMB_FREE(wbuf); + + return strlen(lpString); + } + } + } + return GetWindowTextA(hWnd,lpString,nMaxCount); +} + +UINT GetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount) +{ + HWND h = GetDlgItem(hDlg,nIDDlgItem); + if (h) return GetWindowTextUTF8(h,lpString,nMaxCount); + return 0; +} + + +BOOL SetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPCTSTR lpString) +{ + HWND h = GetDlgItem(hDlg,nIDDlgItem); + if (h) return SetWindowTextUTF8(h,lpString); + return FALSE; +} + +BOOL SetWindowTextUTF8(HWND hwnd, LPCTSTR str) +{ + if (WDL_HasUTF8(str) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + BOOL rv=SetWindowTextW(hwnd,wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + + MBTOWIDE_FREE(wbuf); + } + + return SetWindowTextA(hwnd,str); +} + +int MessageBoxUTF8(HWND hwnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT fl) +{ + if ((WDL_HasUTF8(lpText)||WDL_HasUTF8(lpCaption)) && GetVersion()< 0x80000000) + { + int ret; + MBTOWIDE(wbuf,lpText); + if (wbuf_ok) + { + MBTOWIDE(wcap,lpCaption?lpCaption:""); + if (wcap_ok) + { + ret=MessageBoxW(hwnd,wbuf,lpCaption?wcap:NULL,fl); + MBTOWIDE_FREE(wcap); + MBTOWIDE_FREE(wbuf); + return ret; + } + MBTOWIDE_FREE(wbuf); + } + } + return MessageBoxA(hwnd,lpText,lpCaption,fl); +} + +int DragQueryFileUTF8(HDROP hDrop, int idx, char *buf, int bufsz) +{ + if (buf && bufsz && idx!=-1 && GetVersion()< 0x80000000) + { + int reqsz = DragQueryFileW(hDrop,idx,NULL,0)+32; + WIDETOMB_ALLOC(wbuf, reqsz); + if (wbuf) + { + int rv=DragQueryFileW(hDrop,idx,wbuf,wbuf_size/sizeof(WCHAR)); + if (rv) + { + if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,buf,bufsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + buf[bufsz-1]=0; + } + WIDETOMB_FREE(wbuf); + return rv; + } + } + return DragQueryFileA(hDrop,idx,buf,bufsz); +} + + +WCHAR *WDL_UTF8ToWC(const char *buf, BOOL doublenull, int minsize, DWORD *sizeout) +{ + if (doublenull) + { + int sz=1; + const char *p = (const char *)buf; + WCHAR *pout,*ret; + + while (*p) + { + int a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,p,-1,NULL,0); + int sp=strlen(p)+1; + if (a < sp)a=sp; // in case it needs to be ansi mapped + sz+=a; + p+=sp; + } + if (sz < minsize) sz=minsize; + + pout = (WCHAR *) malloc(sizeof(WCHAR)*(sz+4)); + ret=pout; + p = (const char *)buf; + while (*p) + { + int a; + *pout=0; + a = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,p,-1,pout,sz-(pout-ret)); + if (!a) + { + pout[0]=0; + a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,p,-1,pout,sz-(pout-ret)); + } + pout += a; + p+=strlen(p)+1; + } + *pout=0; + pout[1]=0; + if (sizeout) *sizeout=sz; + return ret; + } + else + { + int srclen = strlen(buf)+1; + int size=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,buf,srclen,NULL,0); + if (size < srclen)size=srclen; // for ansi code page + if (size1) + { + a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,buf,srclen,outbuf, size); + if (!a) + { + outbuf[0]=0; + a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,buf,srclen,outbuf,size); + } + } + if (sizeout) *sizeout = size; + return outbuf; + } + } +} + +static BOOL GetOpenSaveFileNameUTF8(LPOPENFILENAME lpofn, BOOL save) +{ + + OPENFILENAMEW tmp={sizeof(tmp),lpofn->hwndOwner,lpofn->hInstance,}; + BOOL ret; + + // allocate, convert input + if (lpofn->lpstrFilter) tmp.lpstrFilter = WDL_UTF8ToWC(lpofn->lpstrFilter,TRUE,0,0); + tmp.nFilterIndex = lpofn->nFilterIndex ; + + if (lpofn->lpstrFile) tmp.lpstrFile = WDL_UTF8ToWC(lpofn->lpstrFile,FALSE,lpofn->nMaxFile,&tmp.nMaxFile); + if (lpofn->lpstrFileTitle) tmp.lpstrFileTitle = WDL_UTF8ToWC(lpofn->lpstrFileTitle,FALSE,lpofn->nMaxFileTitle,&tmp.nMaxFileTitle); + if (lpofn->lpstrInitialDir) tmp.lpstrInitialDir = WDL_UTF8ToWC(lpofn->lpstrInitialDir,0,0,0); + if (lpofn->lpstrTitle) tmp.lpstrTitle = WDL_UTF8ToWC(lpofn->lpstrTitle,0,0,0); + if (lpofn->lpstrDefExt) tmp.lpstrDefExt = WDL_UTF8ToWC(lpofn->lpstrDefExt,0,0,0); + tmp.Flags = lpofn->Flags; + tmp.lCustData = lpofn->lCustData; + tmp.lpfnHook = lpofn->lpfnHook; + tmp.lpTemplateName = (const WCHAR *)lpofn->lpTemplateName ; + + ret=save ? GetSaveFileNameW(&tmp) : GetOpenFileNameW(&tmp); + + // free, convert output + if (ret) + { + if ((tmp.Flags & OFN_ALLOWMULTISELECT) && tmp.lpstrFile[wcslen(tmp.lpstrFile)+1]) + { + char *op = lpofn->lpstrFile; + WCHAR *ip = tmp.lpstrFile; + while (*ip) + { + int bcount = WideCharToMultiByte(CP_UTF8,0,ip,-1,NULL,0,NULL,NULL); + + int maxout=lpofn->nMaxFile -2 - (op - lpofn->lpstrFile); + if (maxout < 2+bcount) break; + op += WideCharToMultiByte(CP_UTF8,0,ip,-1,op,maxout,NULL,NULL); + ip += wcslen(ip)+1; + } + *op=0; + } + else + { + int len = WideCharToMultiByte(CP_UTF8,0,tmp.lpstrFile,-1,lpofn->lpstrFile,lpofn->nMaxFile-1,NULL,NULL); + if (len == 0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER) len = lpofn->nMaxFile-2; + lpofn->lpstrFile[len]=0; + if (!len) + { + lpofn->lpstrFile[len+1]=0; + ret=0; + } + } + // convert + } + + lpofn->nFileOffset = tmp.nFileOffset ; + lpofn->nFileExtension = tmp.nFileExtension; + lpofn->lCustData = tmp.lCustData; + + free((WCHAR *)tmp.lpstrFilter); + free((WCHAR *)tmp.lpstrFile); + free((WCHAR *)tmp.lpstrFileTitle); + free((WCHAR *)tmp.lpstrInitialDir); + free((WCHAR *)tmp.lpstrTitle); + free((WCHAR *)tmp.lpstrDefExt ); + + lpofn->nFilterIndex = tmp.nFilterIndex ; + return ret; +} + +BOOL GetOpenFileNameUTF8(LPOPENFILENAME lpofn) +{ + if (GetVersion()< 0x80000000) return GetOpenSaveFileNameUTF8(lpofn,FALSE); + return GetOpenFileNameA(lpofn); +} + +BOOL GetSaveFileNameUTF8(LPOPENFILENAME lpofn) +{ + if (GetVersion()< 0x80000000)return GetOpenSaveFileNameUTF8(lpofn,TRUE); + return GetSaveFileNameA(lpofn); +} + + +BOOL SetCurrentDirectoryUTF8(LPCTSTR path) +{ + if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,path); + if (wbuf_ok) + { + BOOL rv=SetCurrentDirectoryW(wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return SetCurrentDirectoryA(path); +} + +BOOL RemoveDirectoryUTF8(LPCTSTR path) +{ + if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,path); + if (wbuf_ok) + { + BOOL rv=RemoveDirectoryW(wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return RemoveDirectoryA(path); +} + +HINSTANCE LoadLibraryUTF8(LPCTSTR path) +{ + if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,path); + if (wbuf_ok) + { + HINSTANCE rv=LoadLibraryW(wbuf); + if (rv) + { + MBTOWIDE_FREE(wbuf); + return rv; + } + } + MBTOWIDE_FREE(wbuf); + } + return LoadLibraryA(path); +} + +BOOL CreateDirectoryUTF8(LPCTSTR path, LPSECURITY_ATTRIBUTES attr) +{ + if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,path); + if (wbuf_ok) + { + BOOL rv=CreateDirectoryW(wbuf,attr); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return CreateDirectoryA(path,attr); +} + +BOOL DeleteFileUTF8(LPCTSTR path) +{ + if (WDL_HasUTF8(path) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,path); + if (wbuf_ok) + { + BOOL rv=DeleteFileW(wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return DeleteFileA(path); +} + +BOOL MoveFileUTF8(LPCTSTR existfn, LPCTSTR newfn) +{ + if ((WDL_HasUTF8(existfn)||WDL_HasUTF8(newfn)) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,existfn); + if (wbuf_ok) + { + MBTOWIDE(wbuf2,newfn); + if (wbuf2_ok) + { + int rv=MoveFileW(wbuf,wbuf2); + MBTOWIDE_FREE(wbuf2); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf2); + } + MBTOWIDE_FREE(wbuf); + } + return MoveFileA(existfn,newfn); +} + +BOOL CopyFileUTF8(LPCTSTR existfn, LPCTSTR newfn, BOOL fie) +{ + if ((WDL_HasUTF8(existfn)||WDL_HasUTF8(newfn)) && GetVersion()< 0x80000000) + { + MBTOWIDE(wbuf,existfn); + if (wbuf_ok) + { + MBTOWIDE(wbuf2,newfn); + if (wbuf2_ok) + { + int rv=CopyFileW(wbuf,wbuf2,fie); + MBTOWIDE_FREE(wbuf2); + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf2); + } + MBTOWIDE_FREE(wbuf); + } + return CopyFileA(existfn,newfn,fie); +} + +DWORD GetCurrentDirectoryUTF8(DWORD nBufferLength, LPTSTR lpBuffer) +{ + if (lpBuffer && nBufferLength > 1 && GetVersion()< 0x80000000) + { + + WCHAR wbuf[WDL_UTF8_MAXFNLEN]; + wbuf[0]=0; + GetCurrentDirectoryW(WDL_UTF8_MAXFNLEN,wbuf); + if (wbuf[0]) + { + int rv=WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpBuffer,nBufferLength,NULL,NULL); + if (rv) return rv; + } + } + return GetCurrentDirectoryA(nBufferLength,lpBuffer); +} + +HANDLE CreateFileUTF8(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) +{ + if (WDL_HasUTF8(lpFileName) && GetVersion()<0x80000000) + { + HANDLE h = INVALID_HANDLE_VALUE; + + MBTOWIDE(wstr, lpFileName); + if (wstr_ok) h = CreateFileW(wstr,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); + MBTOWIDE_FREE(wstr); + + if (h != INVALID_HANDLE_VALUE) return h; + } + return CreateFileA(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); +} + + +int DrawTextUTF8(HDC hdc, LPCTSTR str, int nc, LPRECT lpRect, UINT format) +{ + if (WDL_HasUTF8(str) && GetVersion()<0x80000000) + { + if (nc<0) nc=strlen(str); + + { + MBTOWIDE(wstr, str); + if (wstr_ok) + { + int rv=DrawTextW(hdc,wstr,-1,lpRect,format);; + MBTOWIDE_FREE(wstr); + return rv; + } + MBTOWIDE_FREE(wstr); + } + + } + return DrawTextA(hdc,str,nc,lpRect,format); +} + + +BOOL InsertMenuUTF8(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR str) +{ + if (!(uFlags&(MF_BITMAP|MF_SEPARATOR)) && str && WDL_HasUTF8(str) && GetVersion()<0x80000000) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + BOOL rv=InsertMenuW(hMenu,uPosition,uFlags,uIDNewItem,wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + } + return InsertMenuA(hMenu,uPosition,uFlags,uIDNewItem,str); +} + +BOOL InsertMenuItemUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) +{ + if (lpmii && (lpmii->fMask & MIIM_TYPE) && (lpmii->fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING && lpmii->dwTypeData && WDL_HasUTF8(lpmii->dwTypeData) && GetVersion()<0x80000000) + { + BOOL rv; + MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; + MBTOWIDE(wbuf,lpmii->dwTypeData); + if (wbuf_ok) + { + + tmp.cbSize=sizeof(tmp); + tmp.dwTypeData = wbuf; + rv=InsertMenuItemW(hMenu,uItem,fByPosition,&tmp); + + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return InsertMenuItemA(hMenu,uItem,fByPosition,lpmii); +} +BOOL SetMenuItemInfoUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) +{ + if (lpmii && (lpmii->fMask & MIIM_TYPE) && (lpmii->fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING && lpmii->dwTypeData && WDL_HasUTF8(lpmii->dwTypeData) && GetVersion()<0x80000000) + { + BOOL rv; + MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; + MBTOWIDE(wbuf,lpmii->dwTypeData); + if (wbuf_ok) + { + tmp.cbSize=sizeof(tmp); + tmp.dwTypeData = wbuf; + rv=SetMenuItemInfoW(hMenu,uItem,fByPosition,&tmp); + + MBTOWIDE_FREE(wbuf); + return rv; + } + MBTOWIDE_FREE(wbuf); + } + return SetMenuItemInfoA(hMenu,uItem,fByPosition,lpmii); +} + +BOOL GetMenuItemInfoUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii) +{ + if (lpmii && (lpmii->fMask & MIIM_TYPE) && lpmii->dwTypeData && lpmii->cch && GetVersion()<0x80000000) + { + MENUITEMINFOW tmp = *(MENUITEMINFOW*)lpmii; + WIDETOMB_ALLOC(wbuf,lpmii->cch); + + if (wbuf) + { + BOOL rv; + char *otd=lpmii->dwTypeData; + int osz=lpmii->cbSize; + tmp.cbSize=sizeof(tmp); + tmp.dwTypeData = wbuf; + tmp.cch = wbuf_size/sizeof(WCHAR); + rv=GetMenuItemInfoW(hMenu,uItem,fByPosition,&tmp); + + if (rv && (tmp.fType&(MFT_SEPARATOR|MFT_STRING|MFT_BITMAP)) == MFT_STRING) + { + if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,lpmii->dwTypeData,lpmii->cch,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + { + lpmii->dwTypeData[lpmii->cch-1]=0; + } + + *lpmii = *(MENUITEMINFO*)&tmp; // copy results + lpmii->cbSize=osz; // restore old stuff + lpmii->dwTypeData = otd; + } + else rv=0; + + WIDETOMB_FREE(wbuf); + if (rv)return rv; + } + } + return GetMenuItemInfoA(hMenu,uItem,fByPosition,lpmii); +} + + +FILE *fopenUTF8(const char *filename, const char *mode) +{ + if (WDL_HasUTF8(filename) && GetVersion()<0x80000000) + { + MBTOWIDE(wbuf,filename); + if (wbuf_ok) + { + FILE *rv; + WCHAR tb[32]; + tb[0]=0; + MultiByteToWideChar(CP_UTF8,0,mode,-1,tb,32); + rv=tb[0] ? _wfopen(wbuf,tb) : NULL; + MBTOWIDE_FREE(wbuf); + if (rv) return rv; + } + } + return fopen(filename,mode); +} + +int statUTF8(const char *filename, struct stat *buffer) +{ + if (WDL_HasUTF8(filename) && GetVersion()<0x80000000) + { + MBTOWIDE(wbuf,filename); + if (wbuf_ok) + { + int rv=_wstat(wbuf,(struct _stat*)buffer); + MBTOWIDE_FREE(wbuf); + if (!rv) return rv; + } + else + { + MBTOWIDE_FREE(wbuf); + } + } + return stat(filename,buffer); +} + +LPSTR GetCommandParametersUTF8() +{ + char *buf; + int szneeded; + LPWSTR w=GetCommandLineW(); + if (!w) return NULL; + szneeded = WideCharToMultiByte(CP_UTF8,0,w,-1,NULL,0,NULL,NULL); + if (szneeded<1) return NULL; + buf = (char *)malloc(szneeded+10); + if (!buf) return NULL; + if (WideCharToMultiByte(CP_UTF8,0,w,-1,buf,szneeded+9,NULL,NULL)<1) return NULL; + while (*buf == ' ') buf++; + if (*buf == '\"') + { + buf++; + while (*buf && *buf != '\"') buf++; + } + else + { + while (*buf && *buf != ' ') buf++; + } + if (*buf) buf++; + while (*buf == ' ') buf++; + if (*buf) return buf; + + return NULL; +} + + +HINSTANCE ShellExecuteUTF8(HWND hwnd, LPCTSTR lpOp, LPCTSTR lpFile, LPCTSTR lpParm, LPCTSTR lpDir, INT nShowCmd) +{ + if (GetVersion()<0x80000000 && (WDL_HasUTF8(lpOp)||WDL_HasUTF8(lpFile)||WDL_HasUTF8(lpParm)||WDL_HasUTF8(lpDir))) + { + DWORD sz; + WCHAR *p1=lpOp ? WDL_UTF8ToWC(lpOp,0,0,&sz) : NULL; + WCHAR *p2=lpFile ? WDL_UTF8ToWC(lpFile,0,0,&sz) : NULL; + WCHAR *p3=lpParm ? WDL_UTF8ToWC(lpParm,0,0,&sz) : NULL; + WCHAR *p4=lpDir ? WDL_UTF8ToWC(lpDir,0,0,&sz) : NULL; + HINSTANCE rv= ShellExecuteW(hwnd,p1,p2,p3,p4,nShowCmd); + free(p1); + free(p2); + free(p3); + free(p4); + return rv; + } + return ShellExecuteA(hwnd,lpOp,lpFile,lpParm,lpDir,nShowCmd); +} + +#if defined(WDL_WIN32_UTF8_IMPL_NOTSTATIC) || defined(WDL_WIN32_UTF8_IMPL_STATICHOOKS) + + +#define WDL_UTF8_OLDPROCPROP "WDLUTF8OldProc" + +static LRESULT WINAPI cb_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); + if (!oldproc) return 0; + + if (msg==WM_NCDESTROY) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); + RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); + RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); + } + else if (msg == CB_ADDSTRING || msg == CB_INSERTSTRING || msg == LB_ADDSTRING || msg == LB_INSERTSTRING) + { + char *str=(char*)lParam; + if (lParam && WDL_HasUTF8(str)) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); + LRESULT rv=CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,(LPARAM)wbuf); + MBTOWIDE_FREE(wbuf); + return rv; + } + + MBTOWIDE_FREE(wbuf); + } + } + else if (msg == CB_GETLBTEXT && lParam) + { + WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); + int l = CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,CB_GETLBTEXTLEN,wParam,0)+1; + WIDETOMB_ALLOC(tmp,l); + if (tmp) + { + int rv=CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,(LPARAM)tmp)+1; + if (rv>=0) + { + *(char *)lParam=0; + rv=WideCharToMultiByte(CP_UTF8,0,tmp,-1,(char *)lParam,l*3 + 32,NULL,NULL); + if (rv>0) rv--; + } + WIDETOMB_FREE(tmp); + + return rv; + } + } + else if (msg == CB_GETLBTEXTLEN) + { + WNDPROC oldprocW = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP "W"); + return CallWindowProcW(oldprocW ? oldprocW : oldproc,hwnd,msg,wParam,lParam) * 3 + 32; // make sure caller allocates a lot extra + } + + return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); +} + +void WDL_UTF8_HookComboBox(HWND h) +{ + if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; + SetProp(h,WDL_UTF8_OLDPROCPROP "W",(HANDLE)GetWindowLongPtrW(h,GWLP_WNDPROC)); + SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)cb_newProc)); +} + +void WDL_UTF8_HookListBox(HWND h) +{ + WDL_UTF8_HookComboBox(h); +} + +static LRESULT WINAPI tc_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); + if (!oldproc) return 0; + + if (msg==WM_NCDESTROY) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); + RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); + } + else if (msg == TCM_INSERTITEMA) + { + LPTCITEM pItem = (LPTCITEM) lParam; + char *str; + if (pItem && (str=pItem->pszText) && (pItem->mask&TCIF_TEXT) && WDL_HasUTF8(str)) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + LRESULT rv; + pItem->pszText=(char*)wbuf; // set new buffer + rv=CallWindowProc(oldproc,hwnd,TCM_INSERTITEMW,wParam,lParam); + pItem->pszText = str; // restore old pointer + MBTOWIDE_FREE(wbuf); + return rv; + } + + MBTOWIDE_FREE(wbuf); + } + } + + + return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); +} + + +static LRESULT WINAPI tv_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); + if (!oldproc) return 0; + + if (msg==WM_NCDESTROY) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); + RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); + } + else if (msg == TVM_INSERTITEMA || msg == TVM_SETITEMA) + { + LPTVITEM pItem = msg == TVM_INSERTITEMA ? &((LPTVINSERTSTRUCT)lParam)->item : (LPTVITEM) lParam; + char *str; + if (pItem && (str=pItem->pszText) && (pItem->mask&TVIF_TEXT) && WDL_HasUTF8(str)) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + LRESULT rv; + pItem->pszText=(char*)wbuf; // set new buffer + rv=CallWindowProc(oldproc,hwnd,msg == TVM_INSERTITEMA ? TVM_INSERTITEMW : TVM_SETITEMW,wParam,lParam); + pItem->pszText = str; // restore old pointer + MBTOWIDE_FREE(wbuf); + return rv; + } + + MBTOWIDE_FREE(wbuf); + } + } + else if (msg==TVM_GETITEMA) + { + LPTVITEM pItem = (LPTVITEM) lParam; + char *obuf; + if (pItem && (pItem->mask & TVIF_TEXT) && (obuf=pItem->pszText) && pItem->cchTextMax > 3) + { + WIDETOMB_ALLOC(wbuf,pItem->cchTextMax); + if (wbuf) + { + LRESULT rv; + int oldsz=pItem->cchTextMax; + *wbuf=0; + *obuf=0; + pItem->cchTextMax=wbuf_size/sizeof(WCHAR); + pItem->pszText = (char *)wbuf; + rv=CallWindowProc(oldproc,hwnd,TVM_GETITEMW,wParam,lParam); + + if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,obuf,oldsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + obuf[oldsz-1]=0; + + pItem->cchTextMax=oldsz; + pItem->pszText=obuf; + WIDETOMB_FREE(wbuf); + + if (obuf[0]) return rv; + } + } + } + + return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); +} + +static LRESULT WINAPI lv_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetProp(hwnd,WDL_UTF8_OLDPROCPROP); + if (!oldproc) return 0; + + if (msg==WM_NCDESTROY) + { + SetWindowLongPtr(hwnd, GWLP_WNDPROC,(INT_PTR)oldproc); + RemoveProp(hwnd,WDL_UTF8_OLDPROCPROP); + } + else if (msg == LVM_INSERTCOLUMNA || msg==LVM_SETCOLUMNA) + { + LPLVCOLUMNA pCol = (LPLVCOLUMNA) lParam; + char *str; + if (pCol && (str=pCol->pszText) && (pCol->mask & LVCF_TEXT) && WDL_HasUTF8(str)) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + LRESULT rv; + pCol->pszText=(char*)wbuf; // set new buffer + rv=CallWindowProc(oldproc,hwnd,msg==LVM_INSERTCOLUMNA?LVM_INSERTCOLUMNW:LVM_SETCOLUMNW,wParam,lParam); + pCol->pszText = str; // restore old pointer + MBTOWIDE_FREE(wbuf); + return rv; + } + + } + } + else if (msg == LVM_INSERTITEMA || msg == LVM_SETITEMA || msg == LVM_SETITEMTEXTA) + { + LPLVITEMA pItem = (LPLVITEMA) lParam; + char *str; + if (pItem && (str=pItem->pszText) && (msg==LVM_SETITEMTEXTA || (pItem->mask&LVIF_TEXT)) && WDL_HasUTF8(str)) + { + MBTOWIDE(wbuf,str); + if (wbuf_ok) + { + LRESULT rv; + pItem->pszText=(char*)wbuf; // set new buffer + rv=CallWindowProc(oldproc,hwnd,msg == LVM_INSERTITEMA ? LVM_INSERTITEMW : msg == LVM_SETITEMA ? LVM_SETITEMW : LVM_SETITEMTEXTW,wParam,lParam); + pItem->pszText = str; // restore old pointer + MBTOWIDE_FREE(wbuf); + return rv; + } + + MBTOWIDE_FREE(wbuf); + } + } + else if (msg==LVM_GETITEMA||msg==LVM_GETITEMTEXTA) + { + LPLVITEMA pItem = (LPLVITEMA) lParam; + char *obuf; + if (pItem && (msg == LVM_GETITEMTEXTA || (pItem->mask & LVIF_TEXT)) && (obuf=pItem->pszText) && pItem->cchTextMax > 3) + { + WIDETOMB_ALLOC(wbuf,pItem->cchTextMax); + if (wbuf) + { + LRESULT rv; + int oldsz=pItem->cchTextMax; + *wbuf=0; + *obuf=0; + pItem->cchTextMax=wbuf_size/sizeof(WCHAR); + pItem->pszText = (char *)wbuf; + rv=CallWindowProc(oldproc,hwnd,msg==LVM_GETITEMTEXTA ? LVM_GETITEMTEXTW : LVM_GETITEMW,wParam,lParam); + + if (!WideCharToMultiByte(CP_UTF8,0,wbuf,-1,obuf,oldsz,NULL,NULL) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + obuf[oldsz-1]=0; + + pItem->cchTextMax=oldsz; + pItem->pszText=obuf; + WIDETOMB_FREE(wbuf); + + if (obuf[0]) return rv; + } + } + } + + return CallWindowProc(oldproc,hwnd,msg,wParam,lParam); +} + +void WDL_UTF8_HookListView(HWND h) +{ + if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; + SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)lv_newProc)); +} + +void WDL_UTF8_HookTreeView(HWND h) +{ + if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; + SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)tv_newProc)); +} + +void WDL_UTF8_HookTabCtrl(HWND h) +{ + if (!h||GetVersion()>=0x80000000||GetProp(h,WDL_UTF8_OLDPROCPROP)) return; + SetProp(h,WDL_UTF8_OLDPROCPROP,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(INT_PTR)tc_newProc)); +} + +void WDL_UTF8_ListViewConvertDispInfoToW(void *_di) +{ + NMLVDISPINFO *di = (NMLVDISPINFO *)_di; + if (di && (di->item.mask & LVIF_TEXT) && di->item.pszText && di->item.cchTextMax>0) + { + char tmp_buf[1024], *tmp=tmp_buf; + char *src = di->item.pszText; + + if (strlen(src) < 1024) strcpy(tmp,src); + else tmp = strdup(src); + + if (!MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,tmp,-1,(LPWSTR)di->item.pszText,di->item.cchTextMax)) + { + if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) + { + ((WCHAR *)di->item.pszText)[di->item.cchTextMax-1] = 0; + } + else + { + if (!MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,tmp,-1,(LPWSTR)di->item.pszText,di->item.cchTextMax) && GetLastError()==ERROR_INSUFFICIENT_BUFFER) + ((WCHAR *)di->item.pszText)[di->item.cchTextMax-1] = 0; + } + } + + if (tmp!=tmp_buf) free(tmp); + + } +} + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif + +#endif //_WIN32 diff --git a/WDL/win32_utf8.h b/WDL/win32_utf8.h new file mode 100644 index 00000000..091c9bbd --- /dev/null +++ b/WDL/win32_utf8.h @@ -0,0 +1,202 @@ +#ifndef _WDL_WIN32_UTF8_H_ +#define _WDL_WIN32_UTF8_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8) + +#ifndef WDL_WIN32_UTF8_IMPL +#define WDL_WIN32_UTF8_IMPL +#define WDL_WIN32_UTF8_IMPL_NOTSTATIC +#endif + +#include +#include +#include + +WDL_WIN32_UTF8_IMPL BOOL SetWindowTextUTF8(HWND hwnd, LPCTSTR str); +WDL_WIN32_UTF8_IMPL BOOL SetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPCTSTR lpString); +WDL_WIN32_UTF8_IMPL int GetWindowTextUTF8(HWND hWnd, LPTSTR lpString, int nMaxCount); +WDL_WIN32_UTF8_IMPL UINT GetDlgItemTextUTF8(HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount); +WDL_WIN32_UTF8_IMPL int MessageBoxUTF8(HWND hwnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT fl); + +WDL_WIN32_UTF8_IMPL BOOL CreateDirectoryUTF8(LPCTSTR path, LPSECURITY_ATTRIBUTES attr); +WDL_WIN32_UTF8_IMPL BOOL DeleteFileUTF8(LPCTSTR path); +WDL_WIN32_UTF8_IMPL BOOL MoveFileUTF8(LPCTSTR existfn, LPCTSTR newfn); +WDL_WIN32_UTF8_IMPL BOOL CopyFileUTF8(LPCTSTR existfn, LPCTSTR newfn, BOOL fie); +WDL_WIN32_UTF8_IMPL DWORD GetCurrentDirectoryUTF8(DWORD nBufferLength, LPTSTR lpBuffer); +WDL_WIN32_UTF8_IMPL BOOL SetCurrentDirectoryUTF8(LPCTSTR path); +WDL_WIN32_UTF8_IMPL BOOL RemoveDirectoryUTF8(LPCTSTR path); +WDL_WIN32_UTF8_IMPL HINSTANCE LoadLibraryUTF8(LPCTSTR path); + +WDL_WIN32_UTF8_IMPL HANDLE CreateFileUTF8(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); + +WDL_WIN32_UTF8_IMPL int DragQueryFileUTF8(HDROP hDrop, int idx, char *buf, int bufsz); + +WDL_WIN32_UTF8_IMPL int DrawTextUTF8(HDC hdc, LPCTSTR str, int nc, LPRECT lpRect, UINT format); + +WDL_WIN32_UTF8_IMPL BOOL GetOpenFileNameUTF8(LPOPENFILENAME lpofn); +WDL_WIN32_UTF8_IMPL BOOL GetSaveFileNameUTF8(LPOPENFILENAME lpofn); + + +WDL_WIN32_UTF8_IMPL HINSTANCE ShellExecuteUTF8(HWND hwnd, LPCTSTR lpOp, LPCTSTR lpFile, LPCTSTR lpParm, LPCTSTR lpDir, INT nShowCmd); + +WDL_WIN32_UTF8_IMPL BOOL InsertMenuUTF8(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR str); +WDL_WIN32_UTF8_IMPL BOOL InsertMenuItemUTF8( HMENU hMenu,UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii); +WDL_WIN32_UTF8_IMPL BOOL SetMenuItemInfoUTF8(HMENU hMenu, UINT uItem, BOOL fByPosition,LPMENUITEMINFO lpmii); +WDL_WIN32_UTF8_IMPL BOOL GetMenuItemInfoUTF8(HMENU hMenu, UINT uItem,BOOL fByPosition,LPMENUITEMINFO lpmii); + +WDL_WIN32_UTF8_IMPL int statUTF8(const char *filename, struct stat *buffer); +WDL_WIN32_UTF8_IMPL FILE *fopenUTF8(const char *filename, const char *mode); + + +WDL_WIN32_UTF8_IMPL WCHAR *WDL_UTF8ToWC(const char *buf, BOOL doublenull, int minsize, DWORD *sizeout); + +WDL_WIN32_UTF8_IMPL BOOL WDL_HasUTF8(const char *_str); + +WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookComboBox(HWND h); +WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookListView(HWND h); +WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookListBox(HWND h); +WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookTreeView(HWND h); +WDL_WIN32_UTF8_IMPL void WDL_UTF8_HookTabCtrl(HWND h); + +WDL_WIN32_UTF8_IMPL LPSTR GetCommandParametersUTF8(); +WDL_WIN32_UTF8_IMPL void WDL_UTF8_ListViewConvertDispInfoToW(void *di); //NMLVDISPINFO + +#ifdef SetWindowText +#undef SetWindowText +#endif +#define SetWindowText SetWindowTextUTF8 + +#ifdef SetDlgItemText +#undef SetDlgItemText +#endif +#define SetDlgItemText SetDlgItemTextUTF8 + + +#ifdef GetWindowText +#undef GetWindowText +#endif +#define GetWindowText GetWindowTextUTF8 + +#ifdef GetDlgItemText +#undef GetDlgItemText +#endif +#define GetDlgItemText GetDlgItemTextUTF8 + +#ifdef MessageBox +#undef MessageBox +#endif +#define MessageBox MessageBoxUTF8 + +#ifdef DragQueryFile +#undef DragQueryFile +#endif +#define DragQueryFile DragQueryFileUTF8 + +#ifdef GetOpenFileName +#undef GetOpenFileName +#endif +#define GetOpenFileName GetOpenFileNameUTF8 + +#ifdef GetSaveFileName +#undef GetSaveFileName +#endif +#define GetSaveFileName GetSaveFileNameUTF8 + +#ifdef ShellExecute +#undef ShellExecute +#endif +#define ShellExecute ShellExecuteUTF8 + + +#ifdef CreateDirectory +#undef CreateDirectory +#endif +#define CreateDirectory CreateDirectoryUTF8 + +#ifdef DeleteFile +#undef DeleteFile +#endif +#define DeleteFile DeleteFileUTF8 + +#ifdef MoveFile +#undef MoveFile +#endif +#define MoveFile MoveFileUTF8 + +#ifdef CopyFile +#undef CopyFile +#endif +#define CopyFile CopyFileUTF8 + +#ifdef GetCurrentDirectory +#undef GetCurrentDirectory +#endif +#define GetCurrentDirectory GetCurrentDirectoryUTF8 + +#ifdef SetCurrentDirectory +#undef SetCurrentDirectory +#endif +#define SetCurrentDirectory SetCurrentDirectoryUTF8 + + +#ifdef RemoveDirectory +#undef RemoveDirectory +#endif +#define RemoveDirectory RemoveDirectoryUTF8 + + +#ifdef CreateFile +#undef CreateFile +#endif +#define CreateFile CreateFileUTF8 + + +#ifdef InsertMenu +#undef InsertMenu +#endif +#define InsertMenu InsertMenuUTF8 + +#ifdef InsertMenuItem +#undef InsertMenuItem +#endif +#define InsertMenuItem InsertMenuItemUTF8 + +#ifdef SetMenuItemInfo +#undef SetMenuItemInfo +#endif +#define SetMenuItemInfo SetMenuItemInfoUTF8 + +#ifdef GetMenuItemInfo +#undef GetMenuItemInfo +#endif +#define GetMenuItemInfo GetMenuItemInfoUTF8 + +#ifdef LoadLibrary +#undef LoadLibrary +#endif +#define LoadLibrary LoadLibraryUTF8 + +#else + +// compat defines for when UTF disabled +#define DrawTextUTF8 DrawText +#define statUTF8 stat +#define fopenUTF8 fopen +#define WDL_UTF8_HookComboBox(x) +#define WDL_UTF8_HookListView(x) +#define WDL_UTF8_HookListBox(x) +#define WDL_UTF8_HookTreeView(x) +#define WDL_UTF8_HookTabCtrl(x) +#define WDL_UTF8_ListViewConvertDispInfoToW(x) + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/WDL/win7filedialog.cpp b/WDL/win7filedialog.cpp new file mode 100644 index 00000000..f212c990 --- /dev/null +++ b/WDL/win7filedialog.cpp @@ -0,0 +1,507 @@ +#include "win7filedialog.h" + +#include "ptrlist.h" +#include "win32_utf8.h" + + +Win7FileDialog::Win7FileDialog(const char *name, int issave) +{ + m_dlgid = 0; + m_inst = 0; + m_proc = NULL; + + if(!issave) + CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast(&m_fod)); + else + CoCreateInstance(__uuidof(FileSaveDialog), NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, reinterpret_cast(&m_fod)); + + if(m_fod != NULL) + { + m_fdc = m_fod; + +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[1024]; + mbstowcs(tmp, name, 1023); + tmp[1023]=0; + m_fod->SetTitle(tmp); +#else + WCHAR *tmp = WDL_UTF8ToWC(name, false, 0, NULL); + m_fod->SetTitle(tmp); + free(tmp); +#endif + } +} + +Win7FileDialog::~Win7FileDialog() +{ +} + +void Win7FileDialog::setFilterList(const char *list) +{ + //generate wchar filter list + WDL_PtrList wlist; + { + const char *p = list; + while(*p) + { +#if defined(WDL_NO_SUPPORT_UTF8) + int l = strlen(p); + WCHAR *n = (WCHAR*)malloc(sizeof(WCHAR)*(l+1)); + mbstowcs(n, p, l+1); + wlist.Add(n); +#else + wlist.Add(WDL_UTF8ToWC(p, false, 0, NULL)); +#endif + p+=strlen(p)+1; + } + } + m_fod->SetFileTypes(wlist.GetSize()/2, (_COMDLG_FILTERSPEC *)wlist.GetList()); + wlist.Empty(true,free); +} + +void Win7FileDialog::addOptions(DWORD o) +{ + DWORD fileOpenDialogOptions; + m_fod->GetOptions(&fileOpenDialogOptions); + fileOpenDialogOptions |= o; + m_fod->SetOptions(fileOpenDialogOptions); +} + +void Win7FileDialog::setDefaultExtension(const char *ext) +{ +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[1024]; + mbstowcs(tmp, ext, 1023); + tmp[1023]=0; + m_fod->SetDefaultExtension(tmp); +#else + WCHAR *tmp = WDL_UTF8ToWC(ext, false, 0, NULL); + m_fod->SetDefaultExtension(tmp); + free(tmp); +#endif +} + +void Win7FileDialog::setFileTypeIndex(int i) +{ + m_fod->SetFileTypeIndex(i); +} + +void Win7FileDialog::setFolder(const char *folder, int def) +{ + static HRESULT (WINAPI *my_SHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) = NULL; + if(!my_SHCreateItemFromParsingName) + { + HMODULE dll = LoadLibrary("shell32.dll"); + if(dll) + { + *((void **)(&my_SHCreateItemFromParsingName)) = (void *)GetProcAddress(dll, "SHCreateItemFromParsingName"); + } + } + if(!my_SHCreateItemFromParsingName) return; + +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[4096]; + mbstowcs(tmp, folder, 4095); + tmp[4095]=0; +#else + WCHAR *tmp = WDL_UTF8ToWC(folder, false, 0, NULL); +#endif + + IShellItemPtr si; + my_SHCreateItemFromParsingName(tmp, NULL, __uuidof(IShellItem), (void **)&si); + +#if !defined(WDL_NO_SUPPORT_UTF8) + free(tmp); +#endif + + if(si == NULL) return; + + if(def) + m_fod->SetDefaultFolder(si); + else + m_fod->SetFolder(si); +} + +void Win7FileDialog::addText(DWORD id, char *txt) +{ + if(m_fdc == NULL) return; +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[1024]; + mbstowcs(tmp, txt, 1023); + tmp[1023]=0; + m_fdc->AddText(id, tmp); +#else + WCHAR *tmp = WDL_UTF8ToWC(txt, false, 0, NULL); + m_fdc->AddText(id, tmp); + free(tmp); +#endif +} + +void Win7FileDialog::addCheckbox(char *name, DWORD id, int defval) +{ + if(m_fdc == NULL) return; + +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[1024]; + mbstowcs(tmp, name, 1023); + tmp[1023]=0; + m_fdc->AddCheckButton(id, tmp, defval); +#else + WCHAR *tmp = WDL_UTF8ToWC(name, false, 0, NULL); + m_fdc->AddCheckButton(id, tmp, defval); + free(tmp); +#endif +} + +void Win7FileDialog::startGroup(DWORD id, char *label) +{ + if(m_fdc == NULL) return; +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[1024]; + mbstowcs(tmp, label, 1023); + tmp[1023]=0; + m_fdc->StartVisualGroup(id, tmp); +#else + WCHAR *tmp = WDL_UTF8ToWC(label, false, 0, NULL); + m_fdc->StartVisualGroup(id, tmp); + free(tmp); +#endif +} + +void Win7FileDialog::endGroup() +{ + if(m_fdc == NULL) return; + m_fdc->EndVisualGroup(); +} + +void Win7FileDialog::getResult(char *fn, int maxlen) +{ + IShellItemPtr si; + m_fod->GetResult(&si); + if(si == NULL) + { + fn[0] = 0; + return; + } + WCHAR *res = NULL; + si->GetDisplayName(SIGDN_FILESYSPATH, &res); + if(!res) + { + fn[0] = 0; + return; + } + +#if defined(WDL_NO_SUPPORT_UTF8) + wcstombs(fn, res, maxlen); +#else + int len = WideCharToMultiByte(CP_UTF8,0,res,-1,fn,maxlen-1,NULL,NULL); + fn[len] = 0; +#endif + + CoTaskMemFree(res); +} + +int Win7FileDialog::getResult(int i, char *fn, int maxlen) +{ + //FIXME +#if 0 + IShellItemArrayPtr sia; + m_fod->GetResults(&sia); +#endif + return 0; +} + +int Win7FileDialog::getState(DWORD id) +{ + BOOL c = FALSE; + m_fdc->GetCheckButtonState(id, &c); + return c; +} + +static WNDPROC m_oldproc, m_oldproc2; +static LRESULT CALLBACK newWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if(msg == WM_SIZE) + { + //disable the win7 dialog to resize our custom dialog + static int reent = 0; + if(!reent) + { + reent = 1; + RECT r2; + GetWindowRect(hwnd, &r2); + SetWindowPos(hwnd, NULL, r2.left, r2.top, 1000, r2.bottom-r2.top, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); + reent = 0; + } + return 0; + } + if(msg == WM_GETDLGCODE) + { + int a=1; + } + return CallWindowProc(m_oldproc, hwnd, msg, wparam, lparam); +} + +class myEvent : public IFileDialogEvents +{ +public: + myEvent(HINSTANCE inst, char *dlgid, LPOFNHOOKPROC proc, char *statictxt) + { + m_didhook = 0; + m_didhook2 = 0; + m_inst = inst; + m_dlgid = dlgid; + m_proc = proc; + m_crwnd = NULL; + m_statictxt.Set(statictxt); + } + + STDMETHODIMP QueryInterface(REFIID riid, void **ppv) + { + return E_NOINTERFACE; + } + STDMETHODIMP_(ULONG) AddRef() + { + return 1; + } + STDMETHODIMP_(ULONG) Release() + { + if(m_crwnd) DestroyWindow(m_crwnd); + return 0; + } + + virtual HRESULT STDMETHODCALLTYPE OnFileOk( + /* [in] */ __RPC__in_opt IFileDialog *pfd) + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnFolderChanging( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psiFolder) + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnFolderChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) + { + doHook2(pfd); //post a msg for the actual hook + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnSelectionChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) + { + doHook2(pfd); //post a msg for the actual hook + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnShareViolation( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse) + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnTypeChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE OnOverwrite( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse) + { + return E_NOTIMPL; + } + + static BOOL CALLBACK enumProc(HWND hwnd, LPARAM lParam) + { + char tmp[1024]={0,}; + GetClassName(hwnd, tmp, 1023); + if(!stricmp(tmp,"FloatNotifySink")) + { + myEvent *me = (myEvent *)lParam; + if(!FindWindowEx(hwnd, NULL, NULL, me->m_statictxt.Get())) + return TRUE; + me->m_findwnd = hwnd; + return FALSE; + } + return TRUE; + } + + void doHook() + { + if(m_dlgid && !m_didhook) + { + IOleWindowPtr ow = m_lastpfd; + if(ow!=NULL) + { + HWND filehwnd = NULL; + ow->GetWindow(&filehwnd); + if(filehwnd) + { + m_findwnd = NULL; + EnumChildWindows(filehwnd, enumProc, (LPARAM)this); + if(m_findwnd) + { + //hide other button + HWND h3 = m_findwnd; + HWND h5 = FindWindowEx(h3, NULL, NULL, NULL); + ShowWindow(h5, SW_HIDE); + + //resize the sink + RECT r,r2; + GetWindowRect(h3, &r2); + SetWindowPos(h3, NULL, r2.left, r2.top, 1000, r2.bottom-r2.top, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); + + //put our own dialog instead + HWND h4 = CreateDialog(m_inst, m_dlgid, h3, (DLGPROC)m_proc); + + //SetWindowLong(h4, GWL_ID, 1001); + //SetWindowLong(h4, GWL_STYLE, GetWindowLong(h4, GWL_STYLE)&~(DS_CONTROL|DS_3DLOOK|DS_SETFONT)); + //SetWindowLong(h4, GWL_STYLE, GetWindowLong(h4, GWL_STYLE)|WS_GROUP); + SetWindowLong(h3, GWL_STYLE, GetWindowLong(h3, GWL_STYLE)|WS_TABSTOP); + + m_crwnd = h4; + ShowWindow(h4, SW_SHOW); + + GetClientRect(h3, &r); + SetWindowPos(h4, NULL, 0, 0, r.right, r.bottom, 0); + + //disable the win7 dialog to resize our custom dialog sink + m_oldproc = (WNDPROC)SetWindowLongPtr(h3, GWLP_WNDPROC, (LPARAM)&newWndProc); + m_didhook = 1; + } + } + } + } + } + + static LRESULT CALLBACK newWndProc2(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) + { + if(msg == WM_USER+666) + { + myEvent *me = (myEvent*)lparam; + me->doHook(); + } + return CallWindowProc(m_oldproc2, hwnd, msg, wparam, lparam); + } + + void doHook2(IFileDialog *pfd) + { + if(m_dlgid && !m_didhook2) + { + IOleWindowPtr ow = pfd; + HWND filehwnd = NULL; + ow->GetWindow(&filehwnd); + if(filehwnd) + { + m_lastpfd = pfd; + m_oldproc2 = (WNDPROC)SetWindowLongPtr(filehwnd, GWLP_WNDPROC, (LPARAM)&newWndProc2); + PostMessage(filehwnd, WM_USER+666,0,(LPARAM)this); + m_didhook2 = 1; + } + } + } + + int m_didhook, m_didhook2; + HINSTANCE m_inst; + char *m_dlgid; + LPOFNHOOKPROC m_proc; + HWND m_findwnd; + HWND m_crwnd; + WDL_String m_statictxt; + IFileDialog *m_lastpfd; +}; + +int Win7FileDialog::show(HWND parent) +{ + DWORD c; + myEvent *ev = new myEvent(m_inst, (char*)m_dlgid, m_proc, m_statictxt.Get()); + m_fod->Advise(ev, &c); + + int res = SUCCEEDED(m_fod->Show(parent)); + + m_fod->Unadvise(c); + delete ev; + return res; +} + +#ifndef DLGTEMPLATEEX +#pragma pack(push, 1) +typedef struct +{ + WORD dlgVer; + WORD signature; + DWORD helpID; + DWORD exStyle; + DWORD style; + WORD cDlgItems; + short x; + short y; + short cx; + short cy; +} DLGTEMPLATEEX; +#pragma pack(pop) +#endif + +void Win7FileDialog::setTemplate(HINSTANCE inst, const char *dlgid, LPOFNHOOKPROC proc) +{ + //get the dialog height size + HRSRC r = FindResource(inst, dlgid, RT_DIALOG); + if(!r) return; + HGLOBAL hTemplate = LoadResource(inst, r); + if(!hTemplate) return; + int ysizedlg = 0; + DLGTEMPLATEEX* pTemplate = (DLGTEMPLATEEX*)LockResource(hTemplate); + if(pTemplate->signature == 0xffff) + ysizedlg = pTemplate->cy; + else + { + DLGTEMPLATE *p2 = (DLGTEMPLATE*)pTemplate; + ysizedlg = p2->cy; + } + UnlockResource(hTemplate); + FreeResource(hTemplate); + + int ysize = ysizedlg/8; + + //make room for our custom template dialog + WDL_String txt("."); + if(ysize) + { + while(--ysize) + { + txt.Append("\n."); + } + } + addText(1, txt.Get()); + m_statictxt.Set(txt.Get()); + addText(2, ""); + + m_inst = inst; + m_dlgid = dlgid; + m_proc = proc; +} + +void Win7FileDialog::setFilename(const char *fn) +{ + if(m_fod == NULL) return; + +#if defined(WDL_NO_SUPPORT_UTF8) + WCHAR tmp[4096]; + mbstowcs(tmp, fn, 4095); + tmp[4095]=0; + m_fod->SetFileName(tmp); +#else + WCHAR *tmp = WDL_UTF8ToWC(fn, false, 0, NULL); + m_fod->SetFileName(tmp); + free(tmp); +#endif + +} diff --git a/WDL/win7filedialog.h b/WDL/win7filedialog.h new file mode 100644 index 00000000..e547d351 --- /dev/null +++ b/WDL/win7filedialog.h @@ -0,0 +1,2206 @@ +#ifndef _WIN7FILEDIALOG_H +#define _WIN7FILEDIALOG_H + +#ifdef _WIN32 + +#include +#include "wdlstring.h" + +#ifndef __RPC__in_opt +//defines for msvc6 +#define __RPC__in_opt +#define __RPC__in +#define __RPC__out +#define __RPC__deref_out_opt +#define __RPC__deref_out_opt_string +#define __RPC__in_ecount_full(x) +#define __RPC__out_ecount_part(x,y) +#ifndef __in +#define __in +#endif + +typedef ULONG SFGAOF; + +typedef /* [v1_enum] */ +enum tagFDE_OVERWRITE_RESPONSE +{ FDEOR_DEFAULT = 0, +FDEOR_ACCEPT = 0x1, +FDEOR_REFUSE = 0x2 + } FDE_OVERWRITE_RESPONSE; + +typedef /* [v1_enum] */ +enum tagFDE_SHAREVIOLATION_RESPONSE +{ FDESVR_DEFAULT = 0, +FDESVR_ACCEPT = 0x1, +FDESVR_REFUSE = 0x2 +} FDE_SHAREVIOLATION_RESPONSE; + +typedef /* [v1_enum] */ +enum tagFDAP +{ FDAP_BOTTOM = 0, +FDAP_TOP = 0x1 +} FDAP; + +typedef struct _COMDLG_FILTERSPEC +{ + LPCWSTR pszName; + LPCWSTR pszSpec; +} COMDLG_FILTERSPEC; + +typedef +enum tagSHCONTF +{ SHCONTF_FOLDERS = 0x20, +SHCONTF_NONFOLDERS = 0x40, +SHCONTF_INCLUDEHIDDEN = 0x80, +SHCONTF_INIT_ON_FIRST_NEXT = 0x100, +SHCONTF_NETPRINTERSRCH = 0x200, +SHCONTF_SHAREABLE = 0x400, +SHCONTF_STORAGE = 0x800, +SHCONTF_FASTITEMS = 0x2000, +SHCONTF_FLATLIST = 0x4000, +SHCONTF_ENABLE_ASYNC = 0x8000 +} SHCONT; + +typedef DWORD SHCONTF; + +enum tagGETPROPERTYSTOREFLAGS +{ GPS_DEFAULT = 0, +GPS_HANDLERPROPERTIESONLY = 0x1, +GPS_READWRITE = 0x2, +GPS_TEMPORARY = 0x4, +GPS_FASTPROPERTIESONLY = 0x8, +GPS_OPENSLOWITEM = 0x10, +GPS_DELAYCREATION = 0x20, +GPS_BESTEFFORT = 0x40, +GPS_MASK_VALID = 0x7f +} ; +typedef int GETPROPERTYSTOREFLAGS; + +typedef /* [v1_enum] */ +enum tagCDCONTROLSTATE +{ CDCS_INACTIVE = 0, +CDCS_ENABLED = 0x1, +CDCS_VISIBLE = 0x2 +} CDCONTROLSTATE; + +typedef DWORD CDCONTROLSTATEF; + +typedef void *REFPROPERTYKEY; + +class IPropertyStore; +class IPropertyDescriptionList; +class IFileOperationProgressSink; +//msvc6 +#else +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#endif +#endif + +#ifndef __IFileDialog_FWD_DEFINED__ +#define __IFileDialog_FWD_DEFINED__ +typedef interface IFileDialog IFileDialog; +#endif /* __IFileDialog_FWD_DEFINED__ */ + + + + +#ifndef __IShellItem_INTERFACE_DEFINED__ +#define __IShellItem_INTERFACE_DEFINED__ + +/* interface IShellItem */ +/* [unique][object][uuid][helpstring] */ + +typedef /* [v1_enum] */ +enum tagSIGDN + { SIGDN_NORMALDISPLAY = 0, + SIGDN_PARENTRELATIVEPARSING = ( int )0x80018001, + SIGDN_DESKTOPABSOLUTEPARSING = ( int )0x80028000, + SIGDN_PARENTRELATIVEEDITING = ( int )0x80031001, + SIGDN_DESKTOPABSOLUTEEDITING = ( int )0x8004c000, + SIGDN_FILESYSPATH = ( int )0x80058000, + SIGDN_URL = ( int )0x80068000, + SIGDN_PARENTRELATIVEFORADDRESSBAR = ( int )0x8007c001, + SIGDN_PARENTRELATIVE = ( int )0x80080001 + } SIGDN; + +/* [v1_enum] */ +enum tagSHELLITEMCOMPAREHINTF + { SICHINT_DISPLAY = 0, + SICHINT_ALLFIELDS = ( int )0x80000000, + SICHINT_CANONICAL = 0x10000000 + } ; +typedef DWORD SICHINTF; + + +EXTERN_C const IID IID_IShellItem; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("43826d1e-e718-42ee-bc55-a1e261c37bfe") + IShellItem : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE BindToHandler( + /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, + /* [in] */ __RPC__in REFGUID bhid, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetParent( + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayName( + /* [in] */ SIGDN sigdnName, + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppszName) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAttributes( + /* [in] */ SFGAOF sfgaoMask, + /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0; + + virtual HRESULT STDMETHODCALLTYPE Compare( + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ SICHINTF hint, + /* [out] */ __RPC__out int *piOrder) = 0; + + }; + +#else /* C style interface */ + + typedef struct IShellItemVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IShellItem * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IShellItem * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IShellItem * This); + + HRESULT ( STDMETHODCALLTYPE *BindToHandler )( + IShellItem * This, + /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, + /* [in] */ __RPC__in REFGUID bhid, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IShellItem * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + IShellItem * This, + /* [in] */ SIGDN sigdnName, + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppszName); + + HRESULT ( STDMETHODCALLTYPE *GetAttributes )( + IShellItem * This, + /* [in] */ SFGAOF sfgaoMask, + /* [out] */ __RPC__out SFGAOF *psfgaoAttribs); + + HRESULT ( STDMETHODCALLTYPE *Compare )( + IShellItem * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ SICHINTF hint, + /* [out] */ __RPC__out int *piOrder); + + END_INTERFACE + } IShellItemVtbl; + + interface IShellItem + { + CONST_VTBL struct IShellItemVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IShellItem_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IShellItem_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IShellItem_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IShellItem_BindToHandler(This,pbc,bhid,riid,ppv) \ + ( (This)->lpVtbl -> BindToHandler(This,pbc,bhid,riid,ppv) ) + +#define IShellItem_GetParent(This,ppsi) \ + ( (This)->lpVtbl -> GetParent(This,ppsi) ) + +#define IShellItem_GetDisplayName(This,sigdnName,ppszName) \ + ( (This)->lpVtbl -> GetDisplayName(This,sigdnName,ppszName) ) + +#define IShellItem_GetAttributes(This,sfgaoMask,psfgaoAttribs) \ + ( (This)->lpVtbl -> GetAttributes(This,sfgaoMask,psfgaoAttribs) ) + +#define IShellItem_Compare(This,psi,hint,piOrder) \ + ( (This)->lpVtbl -> Compare(This,psi,hint,piOrder) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IShellItem_INTERFACE_DEFINED__ */ + +#ifndef __IFileDialogEvents_INTERFACE_DEFINED__ +#define __IFileDialogEvents_INTERFACE_DEFINED__ + +/* interface IFileDialogEvents */ +/* [unique][object][uuid] */ + +EXTERN_C const IID IID_IFileDialogEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("973510db-7d7f-452b-8975-74a85828d354") + IFileDialogEvents : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnFileOk( + /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnFolderChanging( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psiFolder) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnFolderChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnSelectionChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnShareViolation( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTypeChange( + /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnOverwrite( + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse) = 0; + + }; + +#else /* C style interface */ + + typedef struct IFileDialogEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileDialogEvents * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFileDialogEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFileDialogEvents * This); + + HRESULT ( STDMETHODCALLTYPE *OnFileOk )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd); + + HRESULT ( STDMETHODCALLTYPE *OnFolderChanging )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psiFolder); + + HRESULT ( STDMETHODCALLTYPE *OnFolderChange )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd); + + HRESULT ( STDMETHODCALLTYPE *OnSelectionChange )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd); + + HRESULT ( STDMETHODCALLTYPE *OnShareViolation )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse); + + HRESULT ( STDMETHODCALLTYPE *OnTypeChange )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd); + + HRESULT ( STDMETHODCALLTYPE *OnOverwrite )( + IFileDialogEvents * This, + /* [in] */ __RPC__in_opt IFileDialog *pfd, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse); + + END_INTERFACE + } IFileDialogEventsVtbl; + + interface IFileDialogEvents + { + CONST_VTBL struct IFileDialogEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFileDialogEvents_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IFileDialogEvents_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IFileDialogEvents_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IFileDialogEvents_OnFileOk(This,pfd) \ + ( (This)->lpVtbl -> OnFileOk(This,pfd) ) + +#define IFileDialogEvents_OnFolderChanging(This,pfd,psiFolder) \ + ( (This)->lpVtbl -> OnFolderChanging(This,pfd,psiFolder) ) + +#define IFileDialogEvents_OnFolderChange(This,pfd) \ + ( (This)->lpVtbl -> OnFolderChange(This,pfd) ) + +#define IFileDialogEvents_OnSelectionChange(This,pfd) \ + ( (This)->lpVtbl -> OnSelectionChange(This,pfd) ) + +#define IFileDialogEvents_OnShareViolation(This,pfd,psi,pResponse) \ + ( (This)->lpVtbl -> OnShareViolation(This,pfd,psi,pResponse) ) + +#define IFileDialogEvents_OnTypeChange(This,pfd) \ + ( (This)->lpVtbl -> OnTypeChange(This,pfd) ) + +#define IFileDialogEvents_OnOverwrite(This,pfd,psi,pResponse) \ + ( (This)->lpVtbl -> OnOverwrite(This,pfd,psi,pResponse) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFileDialogEvents_INTERFACE_DEFINED__ */ + + +#ifndef __IModalWindow_INTERFACE_DEFINED__ +#define __IModalWindow_INTERFACE_DEFINED__ + +/* interface IModalWindow */ +/* [unique][object][uuid][helpstring] */ + + +EXTERN_C const IID IID_IModalWindow; + +#if defined(__cplusplus) && !defined(CINTERFACE) + +MIDL_INTERFACE("b4db1657-70d7-485e-8e3e-6fcb5a5c1802") +IModalWindow : public IUnknown +{ + public: + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Show( + /* [in] */ + __in HWND hwndParent) = 0; + + }; + +#else /* C style interface */ + + typedef struct IModalWindowVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IModalWindow * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IModalWindow * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IModalWindow * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( + IModalWindow * This, + /* [in] */ + __in HWND hwndParent); + + END_INTERFACE + } IModalWindowVtbl; + + interface IModalWindow + { + CONST_VTBL struct IModalWindowVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IModalWindow_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IModalWindow_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IModalWindow_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IModalWindow_Show(This,hwndParent) \ + ( (This)->lpVtbl -> Show(This,hwndParent) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + /* [call_as] */ HRESULT STDMETHODCALLTYPE IModalWindow_RemoteShow_Proxy( + IModalWindow * This, + /* [in] */ __RPC__in HWND hwndParent); + + + void __RPC_STUB IModalWindow_RemoteShow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IModalWindow_INTERFACE_DEFINED__ */ + +#ifndef __IShellItemFilter_INTERFACE_DEFINED__ +#define __IShellItemFilter_INTERFACE_DEFINED__ + + /* interface IShellItemFilter */ + /* [unique][uuid][object] */ + + + EXTERN_C const IID IID_IShellItemFilter; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2659B475-EEB8-48b7-8F07-B378810F48CF") +IShellItemFilter : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE IncludeItem( + /* [in] */ __RPC__in_opt IShellItem *psi) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetEnumFlagsForItem( + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out SHCONTF *pgrfFlags) = 0; + + }; + +#else /* C style interface */ + + typedef struct IShellItemFilterVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IShellItemFilter * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IShellItemFilter * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IShellItemFilter * This); + + HRESULT ( STDMETHODCALLTYPE *IncludeItem )( + IShellItemFilter * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *GetEnumFlagsForItem )( + IShellItemFilter * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [out] */ __RPC__out SHCONTF *pgrfFlags); + + END_INTERFACE + } IShellItemFilterVtbl; + + interface IShellItemFilter + { + CONST_VTBL struct IShellItemFilterVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IShellItemFilter_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IShellItemFilter_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IShellItemFilter_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IShellItemFilter_IncludeItem(This,psi) \ + ( (This)->lpVtbl -> IncludeItem(This,psi) ) + +#define IShellItemFilter_GetEnumFlagsForItem(This,psi,pgrfFlags) \ + ( (This)->lpVtbl -> GetEnumFlagsForItem(This,psi,pgrfFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IShellItemFilter_INTERFACE_DEFINED__ */ + + + + +#ifndef __IFileDialog_INTERFACE_DEFINED__ +#define __IFileDialog_INTERFACE_DEFINED__ + +/* interface IFileDialog */ +/* [unique][object][uuid] */ + + +enum tagFILEOPENDIALOGOPTIONS + { FOS_OVERWRITEPROMPT = 0x2, + FOS_STRICTFILETYPES = 0x4, + FOS_NOCHANGEDIR = 0x8, + FOS_PICKFOLDERS = 0x20, + FOS_FORCEFILESYSTEM = 0x40, + FOS_ALLNONSTORAGEITEMS = 0x80, + FOS_NOVALIDATE = 0x100, + FOS_ALLOWMULTISELECT = 0x200, + FOS_PATHMUSTEXIST = 0x800, + FOS_FILEMUSTEXIST = 0x1000, + FOS_CREATEPROMPT = 0x2000, + FOS_SHAREAWARE = 0x4000, + FOS_NOREADONLYRETURN = 0x8000, + FOS_NOTESTFILECREATE = 0x10000, + FOS_HIDEMRUPLACES = 0x20000, + FOS_HIDEPINNEDPLACES = 0x40000, + FOS_NODEREFERENCELINKS = 0x100000, + FOS_DONTADDTORECENT = 0x2000000, + FOS_FORCESHOWHIDDEN = 0x10000000, + FOS_DEFAULTNOMINIMODE = 0x20000000, + FOS_FORCEPREVIEWPANEON = 0x40000000 + } ; + +EXTERN_C const IID IID_IFileDialog; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("42f85136-db7e-439c-85f1-e4075d135fc8") + IFileDialog : public IModalWindow + { + public: + virtual HRESULT STDMETHODCALLTYPE SetFileTypes( + /* [in] */ UINT cFileTypes, + /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex( + /* [in] */ UINT iFileType) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex( + /* [out] */ __RPC__out UINT *piFileType) = 0; + + virtual HRESULT STDMETHODCALLTYPE Advise( + /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, + /* [out] */ __RPC__out DWORD *pdwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unadvise( + /* [in] */ DWORD dwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetOptions( + /* [in] */ DWORD fos) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetOptions( + /* [out] */ __RPC__out DWORD *pfos) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder( + /* [in] */ __RPC__in_opt IShellItem *psi) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFolder( + /* [in] */ __RPC__in_opt IShellItem *psi) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFolder( + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection( + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFileName( + /* [string][in] */ __RPC__in LPCWSTR pszName) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFileName( + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetTitle( + /* [string][in] */ __RPC__in LPCWSTR pszTitle) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel( + /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel( + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetResult( + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddPlace( + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ FDAP fdap) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension( + /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension) = 0; + + virtual HRESULT STDMETHODCALLTYPE Close( + /* [in] */ HRESULT hr) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetClientGuid( + /* [in] */ __RPC__in REFGUID guid) = 0; + + virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFilter( + /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0; + + }; + +#else /* C style interface */ + + typedef struct IFileDialogVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileDialog * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFileDialog * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFileDialog * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( + IFileDialog * This, + /* [in] */ + __in HWND hwndParent); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( + IFileDialog * This, + /* [in] */ UINT cFileTypes, + /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( + IFileDialog * This, + /* [in] */ UINT iFileType); + + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( + IFileDialog * This, + /* [out] */ __RPC__out UINT *piFileType); + + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileDialog * This, + /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, + /* [out] */ __RPC__out DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *Unadvise )( + IFileDialog * This, + /* [in] */ DWORD dwCookie); + + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileDialog * This, + /* [in] */ DWORD fos); + + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileDialog * This, + /* [out] */ __RPC__out DWORD *pfos); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszName); + + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileDialog * This, + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); + + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszTitle); + + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ FDAP fdap); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); + + HRESULT ( STDMETHODCALLTYPE *Close )( + IFileDialog * This, + /* [in] */ HRESULT hr); + + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileDialog * This, + /* [in] */ __RPC__in REFGUID guid); + + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( + IFileDialog * This); + + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileDialog * This, + /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); + + END_INTERFACE + } IFileDialogVtbl; + + interface IFileDialog + { + CONST_VTBL struct IFileDialogVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFileDialog_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IFileDialog_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IFileDialog_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IFileDialog_Show(This,hwndParent) \ + ( (This)->lpVtbl -> Show(This,hwndParent) ) + + +#define IFileDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ + ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) + +#define IFileDialog_SetFileTypeIndex(This,iFileType) \ + ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) + +#define IFileDialog_GetFileTypeIndex(This,piFileType) \ + ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) + +#define IFileDialog_Advise(This,pfde,pdwCookie) \ + ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) + +#define IFileDialog_Unadvise(This,dwCookie) \ + ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) + +#define IFileDialog_SetOptions(This,fos) \ + ( (This)->lpVtbl -> SetOptions(This,fos) ) + +#define IFileDialog_GetOptions(This,pfos) \ + ( (This)->lpVtbl -> GetOptions(This,pfos) ) + +#define IFileDialog_SetDefaultFolder(This,psi) \ + ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) + +#define IFileDialog_SetFolder(This,psi) \ + ( (This)->lpVtbl -> SetFolder(This,psi) ) + +#define IFileDialog_GetFolder(This,ppsi) \ + ( (This)->lpVtbl -> GetFolder(This,ppsi) ) + +#define IFileDialog_GetCurrentSelection(This,ppsi) \ + ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) + +#define IFileDialog_SetFileName(This,pszName) \ + ( (This)->lpVtbl -> SetFileName(This,pszName) ) + +#define IFileDialog_GetFileName(This,pszName) \ + ( (This)->lpVtbl -> GetFileName(This,pszName) ) + +#define IFileDialog_SetTitle(This,pszTitle) \ + ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) + +#define IFileDialog_SetOkButtonLabel(This,pszText) \ + ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) + +#define IFileDialog_SetFileNameLabel(This,pszLabel) \ + ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) + +#define IFileDialog_GetResult(This,ppsi) \ + ( (This)->lpVtbl -> GetResult(This,ppsi) ) + +#define IFileDialog_AddPlace(This,psi,fdap) \ + ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) + +#define IFileDialog_SetDefaultExtension(This,pszDefaultExtension) \ + ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) + +#define IFileDialog_Close(This,hr) \ + ( (This)->lpVtbl -> Close(This,hr) ) + +#define IFileDialog_SetClientGuid(This,guid) \ + ( (This)->lpVtbl -> SetClientGuid(This,guid) ) + +#define IFileDialog_ClearClientData(This) \ + ( (This)->lpVtbl -> ClearClientData(This) ) + +#define IFileDialog_SetFilter(This,pFilter) \ + ( (This)->lpVtbl -> SetFilter(This,pFilter) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#ifndef __IEnumShellItems_INTERFACE_DEFINED__ +#define __IEnumShellItems_INTERFACE_DEFINED__ + +/* interface IEnumShellItems */ +/* [unique][object][uuid][helpstring] */ + + +EXTERN_C const IID IID_IEnumShellItems; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("70629033-e363-4a28-a567-0db78006e6d7") + IEnumShellItems : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(celt, *pceltFetched) IShellItem **rgelt, + /* [out] */ __RPC__out ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenum) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumShellItemsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumShellItems * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumShellItems * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumShellItems * This); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumShellItems * This, + /* [in] */ ULONG celt, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(celt, *pceltFetched) IShellItem **rgelt, + /* [out] */ __RPC__out ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumShellItems * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumShellItems * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumShellItems * This, + /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenum); + + END_INTERFACE + } IEnumShellItemsVtbl; + + interface IEnumShellItems + { + CONST_VTBL struct IEnumShellItemsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumShellItems_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumShellItems_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumShellItems_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumShellItems_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IEnumShellItems_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IEnumShellItems_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumShellItems_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumShellItems_INTERFACE_DEFINED__ */ + + +#ifndef __IShellItemArray_INTERFACE_DEFINED__ +#define __IShellItemArray_INTERFACE_DEFINED__ + +/* interface IShellItemArray */ +/* [unique][object][uuid][helpstring] */ + +typedef /* [v1_enum] */ +enum tagSIATTRIBFLAGS + { SIATTRIBFLAGS_AND = 0x1, + SIATTRIBFLAGS_OR = 0x2, + SIATTRIBFLAGS_APPCOMPAT = 0x3, + SIATTRIBFLAGS_MASK = 0x3 + } SIATTRIBFLAGS; + + +EXTERN_C const IID IID_IShellItemArray; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b63ea76d-1f85-456f-a19c-48159efa858b") + IShellItemArray : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE BindToHandler( + /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, + /* [in] */ __RPC__in REFGUID rbhid, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppvOut) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPropertyStore( + /* [in] */ GETPROPERTYSTOREFLAGS flags, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPropertyDescriptionList( + /* [in] */ __RPC__in REFPROPERTYKEY keyType, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAttributes( + /* [in] */ SIATTRIBFLAGS dwAttribFlags, + /* [in] */ SFGAOF sfgaoMask, + /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCount( + /* [out] */ __RPC__out DWORD *pdwNumItems) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetItemAt( + /* [in] */ DWORD dwIndex, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumItems( + /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenumShellItems) = 0; + + }; + +#else /* C style interface */ + + typedef struct IShellItemArrayVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IShellItemArray * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IShellItemArray * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IShellItemArray * This); + + HRESULT ( STDMETHODCALLTYPE *BindToHandler )( + IShellItemArray * This, + /* [unique][in] */ __RPC__in_opt IBindCtx *pbc, + /* [in] */ __RPC__in REFGUID rbhid, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppvOut); + + HRESULT ( STDMETHODCALLTYPE *GetPropertyStore )( + IShellItemArray * This, + /* [in] */ GETPROPERTYSTOREFLAGS flags, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); + + HRESULT ( STDMETHODCALLTYPE *GetPropertyDescriptionList )( + IShellItemArray * This, + /* [in] */ __RPC__in REFPROPERTYKEY keyType, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ __RPC__deref_out_opt void **ppv); + + HRESULT ( STDMETHODCALLTYPE *GetAttributes )( + IShellItemArray * This, + /* [in] */ SIATTRIBFLAGS dwAttribFlags, + /* [in] */ SFGAOF sfgaoMask, + /* [out] */ __RPC__out SFGAOF *psfgaoAttribs); + + HRESULT ( STDMETHODCALLTYPE *GetCount )( + IShellItemArray * This, + /* [out] */ __RPC__out DWORD *pdwNumItems); + + HRESULT ( STDMETHODCALLTYPE *GetItemAt )( + IShellItemArray * This, + /* [in] */ DWORD dwIndex, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *EnumItems )( + IShellItemArray * This, + /* [out] */ __RPC__deref_out_opt IEnumShellItems **ppenumShellItems); + + END_INTERFACE + } IShellItemArrayVtbl; + + interface IShellItemArray + { + CONST_VTBL struct IShellItemArrayVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IShellItemArray_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IShellItemArray_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IShellItemArray_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IShellItemArray_BindToHandler(This,pbc,rbhid,riid,ppvOut) \ + ( (This)->lpVtbl -> BindToHandler(This,pbc,rbhid,riid,ppvOut) ) + +#define IShellItemArray_GetPropertyStore(This,flags,riid,ppv) \ + ( (This)->lpVtbl -> GetPropertyStore(This,flags,riid,ppv) ) + +#define IShellItemArray_GetPropertyDescriptionList(This,keyType,riid,ppv) \ + ( (This)->lpVtbl -> GetPropertyDescriptionList(This,keyType,riid,ppv) ) + +#define IShellItemArray_GetAttributes(This,dwAttribFlags,sfgaoMask,psfgaoAttribs) \ + ( (This)->lpVtbl -> GetAttributes(This,dwAttribFlags,sfgaoMask,psfgaoAttribs) ) + +#define IShellItemArray_GetCount(This,pdwNumItems) \ + ( (This)->lpVtbl -> GetCount(This,pdwNumItems) ) + +#define IShellItemArray_GetItemAt(This,dwIndex,ppsi) \ + ( (This)->lpVtbl -> GetItemAt(This,dwIndex,ppsi) ) + +#define IShellItemArray_EnumItems(This,ppenumShellItems) \ + ( (This)->lpVtbl -> EnumItems(This,ppenumShellItems) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IShellItemArray_INTERFACE_DEFINED__ */ + + + + + +#endif /* __IFileDialog_INTERFACE_DEFINED__ */ + +#ifndef __IFileOpenDialog_INTERFACE_DEFINED__ +#define __IFileOpenDialog_INTERFACE_DEFINED__ + +/* interface IFileOpenDialog */ +/* [unique][object][uuid] */ + + +EXTERN_C const IID IID_IFileOpenDialog; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("d57c7288-d4ad-4768-be02-9d969532d960") + IFileOpenDialog : public IFileDialog + { + public: + virtual HRESULT STDMETHODCALLTYPE GetResults( + /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSelectedItems( + /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai) = 0; + + }; + +#else /* C style interface */ + + typedef struct IFileOpenDialogVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileOpenDialog * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFileOpenDialog * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFileOpenDialog * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( + IFileOpenDialog * This, + /* [in] */ + __in HWND hwndParent); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( + IFileOpenDialog * This, + /* [in] */ UINT cFileTypes, + /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( + IFileOpenDialog * This, + /* [in] */ UINT iFileType); + + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( + IFileOpenDialog * This, + /* [out] */ __RPC__out UINT *piFileType); + + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileOpenDialog * This, + /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, + /* [out] */ __RPC__out DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *Unadvise )( + IFileOpenDialog * This, + /* [in] */ DWORD dwCookie); + + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileOpenDialog * This, + /* [in] */ DWORD fos); + + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileOpenDialog * This, + /* [out] */ __RPC__out DWORD *pfos); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileOpenDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileOpenDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileOpenDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileOpenDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileOpenDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszName); + + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileOpenDialog * This, + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); + + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileOpenDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszTitle); + + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileOpenDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileOpenDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileOpenDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileOpenDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ FDAP fdap); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileOpenDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); + + HRESULT ( STDMETHODCALLTYPE *Close )( + IFileOpenDialog * This, + /* [in] */ HRESULT hr); + + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileOpenDialog * This, + /* [in] */ __RPC__in REFGUID guid); + + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( + IFileOpenDialog * This); + + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileOpenDialog * This, + /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetResults )( + IFileOpenDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItemArray **ppenum); + + HRESULT ( STDMETHODCALLTYPE *GetSelectedItems )( + IFileOpenDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItemArray **ppsai); + + END_INTERFACE + } IFileOpenDialogVtbl; + + interface IFileOpenDialog + { + CONST_VTBL struct IFileOpenDialogVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFileOpenDialog_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IFileOpenDialog_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IFileOpenDialog_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IFileOpenDialog_Show(This,hwndParent) \ + ( (This)->lpVtbl -> Show(This,hwndParent) ) + + +#define IFileOpenDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ + ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) + +#define IFileOpenDialog_SetFileTypeIndex(This,iFileType) \ + ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) + +#define IFileOpenDialog_GetFileTypeIndex(This,piFileType) \ + ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) + +#define IFileOpenDialog_Advise(This,pfde,pdwCookie) \ + ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) + +#define IFileOpenDialog_Unadvise(This,dwCookie) \ + ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) + +#define IFileOpenDialog_SetOptions(This,fos) \ + ( (This)->lpVtbl -> SetOptions(This,fos) ) + +#define IFileOpenDialog_GetOptions(This,pfos) \ + ( (This)->lpVtbl -> GetOptions(This,pfos) ) + +#define IFileOpenDialog_SetDefaultFolder(This,psi) \ + ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) + +#define IFileOpenDialog_SetFolder(This,psi) \ + ( (This)->lpVtbl -> SetFolder(This,psi) ) + +#define IFileOpenDialog_GetFolder(This,ppsi) \ + ( (This)->lpVtbl -> GetFolder(This,ppsi) ) + +#define IFileOpenDialog_GetCurrentSelection(This,ppsi) \ + ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) + +#define IFileOpenDialog_SetFileName(This,pszName) \ + ( (This)->lpVtbl -> SetFileName(This,pszName) ) + +#define IFileOpenDialog_GetFileName(This,pszName) \ + ( (This)->lpVtbl -> GetFileName(This,pszName) ) + +#define IFileOpenDialog_SetTitle(This,pszTitle) \ + ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) + +#define IFileOpenDialog_SetOkButtonLabel(This,pszText) \ + ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) + +#define IFileOpenDialog_SetFileNameLabel(This,pszLabel) \ + ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) + +#define IFileOpenDialog_GetResult(This,ppsi) \ + ( (This)->lpVtbl -> GetResult(This,ppsi) ) + +#define IFileOpenDialog_AddPlace(This,psi,fdap) \ + ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) + +#define IFileOpenDialog_SetDefaultExtension(This,pszDefaultExtension) \ + ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) + +#define IFileOpenDialog_Close(This,hr) \ + ( (This)->lpVtbl -> Close(This,hr) ) + +#define IFileOpenDialog_SetClientGuid(This,guid) \ + ( (This)->lpVtbl -> SetClientGuid(This,guid) ) + +#define IFileOpenDialog_ClearClientData(This) \ + ( (This)->lpVtbl -> ClearClientData(This) ) + +#define IFileOpenDialog_SetFilter(This,pFilter) \ + ( (This)->lpVtbl -> SetFilter(This,pFilter) ) + + +#define IFileOpenDialog_GetResults(This,ppenum) \ + ( (This)->lpVtbl -> GetResults(This,ppenum) ) + +#define IFileOpenDialog_GetSelectedItems(This,ppsai) \ + ( (This)->lpVtbl -> GetSelectedItems(This,ppsai) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFileOpenDialog_INTERFACE_DEFINED__ */ + + +#ifndef __IFileDialogCustomize_INTERFACE_DEFINED__ +#define __IFileDialogCustomize_INTERFACE_DEFINED__ + +/* interface IFileDialogCustomize */ +/* [unique][object][uuid] */ + + +EXTERN_C const IID IID_IFileDialogCustomize; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e6fdd21a-163f-4975-9c8c-a69f1ba37034") + IFileDialogCustomize : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE EnableOpenDropDown( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddMenu( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddPushButton( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddComboBox( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddRadioButtonList( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddCheckButton( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel, + /* [in] */ BOOL bChecked) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddEditBox( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddSeparator( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddText( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetControlLabel( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetControlState( + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetControlState( + /* [in] */ DWORD dwIDCtl, + /* [in] */ CDCONTROLSTATEF dwState) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetEditBoxText( + /* [in] */ DWORD dwIDCtl, + /* [string][out] */ __RPC__deref_out_opt_string WCHAR **ppszText) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetEditBoxText( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCheckButtonState( + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out BOOL *pbChecked) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCheckButtonState( + /* [in] */ DWORD dwIDCtl, + /* [in] */ BOOL bChecked) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddControlItem( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE RemoveControlItem( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem) = 0; + + virtual HRESULT STDMETHODCALLTYPE RemoveAllControlItems( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetControlItemState( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetControlItemState( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [in] */ CDCONTROLSTATEF dwState) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSelectedControlItem( + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out DWORD *pdwIDItem) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetSelectedControlItem( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartVisualGroup( + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndVisualGroup( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE MakeProminent( + /* [in] */ DWORD dwIDCtl) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetControlItemText( + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [string][in] */ __RPC__in LPCWSTR pszLabel) = 0; + + }; + +#else /* C style interface */ + + typedef struct IFileDialogCustomizeVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileDialogCustomize * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFileDialogCustomize * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFileDialogCustomize * This); + + HRESULT ( STDMETHODCALLTYPE *EnableOpenDropDown )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *AddMenu )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *AddPushButton )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *AddComboBox )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *AddRadioButtonList )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *AddCheckButton )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel, + /* [in] */ BOOL bChecked); + + HRESULT ( STDMETHODCALLTYPE *AddEditBox )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *AddSeparator )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *AddText )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *SetControlLabel )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *GetControlState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState); + + HRESULT ( STDMETHODCALLTYPE *SetControlState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ CDCONTROLSTATEF dwState); + + HRESULT ( STDMETHODCALLTYPE *GetEditBoxText )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][out] */ __RPC__deref_out_opt_string WCHAR **ppszText); + + HRESULT ( STDMETHODCALLTYPE *SetEditBoxText )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *GetCheckButtonState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out BOOL *pbChecked); + + HRESULT ( STDMETHODCALLTYPE *SetCheckButtonState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ BOOL bChecked); + + HRESULT ( STDMETHODCALLTYPE *AddControlItem )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *RemoveControlItem )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem); + + HRESULT ( STDMETHODCALLTYPE *RemoveAllControlItems )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *GetControlItemState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [out] */ __RPC__out CDCONTROLSTATEF *pdwState); + + HRESULT ( STDMETHODCALLTYPE *SetControlItemState )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [in] */ CDCONTROLSTATEF dwState); + + HRESULT ( STDMETHODCALLTYPE *GetSelectedControlItem )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [out] */ __RPC__out DWORD *pdwIDItem); + + HRESULT ( STDMETHODCALLTYPE *SetSelectedControlItem )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem); + + HRESULT ( STDMETHODCALLTYPE *StartVisualGroup )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *EndVisualGroup )( + IFileDialogCustomize * This); + + HRESULT ( STDMETHODCALLTYPE *MakeProminent )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl); + + HRESULT ( STDMETHODCALLTYPE *SetControlItemText )( + IFileDialogCustomize * This, + /* [in] */ DWORD dwIDCtl, + /* [in] */ DWORD dwIDItem, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + END_INTERFACE + } IFileDialogCustomizeVtbl; + + interface IFileDialogCustomize + { + CONST_VTBL struct IFileDialogCustomizeVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFileDialogCustomize_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IFileDialogCustomize_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IFileDialogCustomize_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IFileDialogCustomize_EnableOpenDropDown(This,dwIDCtl) \ + ( (This)->lpVtbl -> EnableOpenDropDown(This,dwIDCtl) ) + +#define IFileDialogCustomize_AddMenu(This,dwIDCtl,pszLabel) \ + ( (This)->lpVtbl -> AddMenu(This,dwIDCtl,pszLabel) ) + +#define IFileDialogCustomize_AddPushButton(This,dwIDCtl,pszLabel) \ + ( (This)->lpVtbl -> AddPushButton(This,dwIDCtl,pszLabel) ) + +#define IFileDialogCustomize_AddComboBox(This,dwIDCtl) \ + ( (This)->lpVtbl -> AddComboBox(This,dwIDCtl) ) + +#define IFileDialogCustomize_AddRadioButtonList(This,dwIDCtl) \ + ( (This)->lpVtbl -> AddRadioButtonList(This,dwIDCtl) ) + +#define IFileDialogCustomize_AddCheckButton(This,dwIDCtl,pszLabel,bChecked) \ + ( (This)->lpVtbl -> AddCheckButton(This,dwIDCtl,pszLabel,bChecked) ) + +#define IFileDialogCustomize_AddEditBox(This,dwIDCtl,pszText) \ + ( (This)->lpVtbl -> AddEditBox(This,dwIDCtl,pszText) ) + +#define IFileDialogCustomize_AddSeparator(This,dwIDCtl) \ + ( (This)->lpVtbl -> AddSeparator(This,dwIDCtl) ) + +#define IFileDialogCustomize_AddText(This,dwIDCtl,pszText) \ + ( (This)->lpVtbl -> AddText(This,dwIDCtl,pszText) ) + +#define IFileDialogCustomize_SetControlLabel(This,dwIDCtl,pszLabel) \ + ( (This)->lpVtbl -> SetControlLabel(This,dwIDCtl,pszLabel) ) + +#define IFileDialogCustomize_GetControlState(This,dwIDCtl,pdwState) \ + ( (This)->lpVtbl -> GetControlState(This,dwIDCtl,pdwState) ) + +#define IFileDialogCustomize_SetControlState(This,dwIDCtl,dwState) \ + ( (This)->lpVtbl -> SetControlState(This,dwIDCtl,dwState) ) + +#define IFileDialogCustomize_GetEditBoxText(This,dwIDCtl,ppszText) \ + ( (This)->lpVtbl -> GetEditBoxText(This,dwIDCtl,ppszText) ) + +#define IFileDialogCustomize_SetEditBoxText(This,dwIDCtl,pszText) \ + ( (This)->lpVtbl -> SetEditBoxText(This,dwIDCtl,pszText) ) + +#define IFileDialogCustomize_GetCheckButtonState(This,dwIDCtl,pbChecked) \ + ( (This)->lpVtbl -> GetCheckButtonState(This,dwIDCtl,pbChecked) ) + +#define IFileDialogCustomize_SetCheckButtonState(This,dwIDCtl,bChecked) \ + ( (This)->lpVtbl -> SetCheckButtonState(This,dwIDCtl,bChecked) ) + +#define IFileDialogCustomize_AddControlItem(This,dwIDCtl,dwIDItem,pszLabel) \ + ( (This)->lpVtbl -> AddControlItem(This,dwIDCtl,dwIDItem,pszLabel) ) + +#define IFileDialogCustomize_RemoveControlItem(This,dwIDCtl,dwIDItem) \ + ( (This)->lpVtbl -> RemoveControlItem(This,dwIDCtl,dwIDItem) ) + +#define IFileDialogCustomize_RemoveAllControlItems(This,dwIDCtl) \ + ( (This)->lpVtbl -> RemoveAllControlItems(This,dwIDCtl) ) + +#define IFileDialogCustomize_GetControlItemState(This,dwIDCtl,dwIDItem,pdwState) \ + ( (This)->lpVtbl -> GetControlItemState(This,dwIDCtl,dwIDItem,pdwState) ) + +#define IFileDialogCustomize_SetControlItemState(This,dwIDCtl,dwIDItem,dwState) \ + ( (This)->lpVtbl -> SetControlItemState(This,dwIDCtl,dwIDItem,dwState) ) + +#define IFileDialogCustomize_GetSelectedControlItem(This,dwIDCtl,pdwIDItem) \ + ( (This)->lpVtbl -> GetSelectedControlItem(This,dwIDCtl,pdwIDItem) ) + +#define IFileDialogCustomize_SetSelectedControlItem(This,dwIDCtl,dwIDItem) \ + ( (This)->lpVtbl -> SetSelectedControlItem(This,dwIDCtl,dwIDItem) ) + +#define IFileDialogCustomize_StartVisualGroup(This,dwIDCtl,pszLabel) \ + ( (This)->lpVtbl -> StartVisualGroup(This,dwIDCtl,pszLabel) ) + +#define IFileDialogCustomize_EndVisualGroup(This) \ + ( (This)->lpVtbl -> EndVisualGroup(This) ) + +#define IFileDialogCustomize_MakeProminent(This,dwIDCtl) \ + ( (This)->lpVtbl -> MakeProminent(This,dwIDCtl) ) + +#define IFileDialogCustomize_SetControlItemText(This,dwIDCtl,dwIDItem,pszLabel) \ + ( (This)->lpVtbl -> SetControlItemText(This,dwIDCtl,dwIDItem,pszLabel) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFileDialogCustomize_INTERFACE_DEFINED__ */ + + +#ifndef __IFileSaveDialog_INTERFACE_DEFINED__ +#define __IFileSaveDialog_INTERFACE_DEFINED__ + +/* interface IFileSaveDialog */ +/* [unique][object][uuid] */ + + +EXTERN_C const IID IID_IFileSaveDialog; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("84bccd23-5fde-4cdb-aea4-af64b83d78ab") + IFileSaveDialog : public IFileDialog + { + public: + virtual HRESULT STDMETHODCALLTYPE SetSaveAsItem( + /* [in] */ __RPC__in_opt IShellItem *psi) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetProperties( + /* [in] */ __RPC__in_opt IPropertyStore *pStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCollectedProperties( + /* [in] */ __RPC__in_opt IPropertyDescriptionList *pList, + /* [in] */ BOOL fAppendDefault) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetProperties( + /* [out] */ __RPC__deref_out_opt IPropertyStore **ppStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE ApplyProperties( + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ __RPC__in_opt IPropertyStore *pStore, + /* [unique][in] */ __RPC__in_opt HWND hwnd, + /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pSink) = 0; + + }; + +#else /* C style interface */ + + typedef struct IFileSaveDialogVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFileSaveDialog * This, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFileSaveDialog * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFileSaveDialog * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Show )( + IFileSaveDialog * This, + /* [in] */ + __in HWND hwndParent); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypes )( + IFileSaveDialog * This, + /* [in] */ UINT cFileTypes, + /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec); + + HRESULT ( STDMETHODCALLTYPE *SetFileTypeIndex )( + IFileSaveDialog * This, + /* [in] */ UINT iFileType); + + HRESULT ( STDMETHODCALLTYPE *GetFileTypeIndex )( + IFileSaveDialog * This, + /* [out] */ __RPC__out UINT *piFileType); + + HRESULT ( STDMETHODCALLTYPE *Advise )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IFileDialogEvents *pfde, + /* [out] */ __RPC__out DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *Unadvise )( + IFileSaveDialog * This, + /* [in] */ DWORD dwCookie); + + HRESULT ( STDMETHODCALLTYPE *SetOptions )( + IFileSaveDialog * This, + /* [in] */ DWORD fos); + + HRESULT ( STDMETHODCALLTYPE *GetOptions )( + IFileSaveDialog * This, + /* [out] */ __RPC__out DWORD *pfos); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultFolder )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *SetFolder )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *GetFolder )( + IFileSaveDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentSelection )( + IFileSaveDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *SetFileName )( + IFileSaveDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszName); + + HRESULT ( STDMETHODCALLTYPE *GetFileName )( + IFileSaveDialog * This, + /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName); + + HRESULT ( STDMETHODCALLTYPE *SetTitle )( + IFileSaveDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszTitle); + + HRESULT ( STDMETHODCALLTYPE *SetOkButtonLabel )( + IFileSaveDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszText); + + HRESULT ( STDMETHODCALLTYPE *SetFileNameLabel )( + IFileSaveDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszLabel); + + HRESULT ( STDMETHODCALLTYPE *GetResult )( + IFileSaveDialog * This, + /* [out] */ __RPC__deref_out_opt IShellItem **ppsi); + + HRESULT ( STDMETHODCALLTYPE *AddPlace )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ FDAP fdap); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultExtension )( + IFileSaveDialog * This, + /* [string][in] */ __RPC__in LPCWSTR pszDefaultExtension); + + HRESULT ( STDMETHODCALLTYPE *Close )( + IFileSaveDialog * This, + /* [in] */ HRESULT hr); + + HRESULT ( STDMETHODCALLTYPE *SetClientGuid )( + IFileSaveDialog * This, + /* [in] */ __RPC__in REFGUID guid); + + HRESULT ( STDMETHODCALLTYPE *ClearClientData )( + IFileSaveDialog * This); + + HRESULT ( STDMETHODCALLTYPE *SetFilter )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItemFilter *pFilter); + + HRESULT ( STDMETHODCALLTYPE *SetSaveAsItem )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi); + + HRESULT ( STDMETHODCALLTYPE *SetProperties )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IPropertyStore *pStore); + + HRESULT ( STDMETHODCALLTYPE *SetCollectedProperties )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IPropertyDescriptionList *pList, + /* [in] */ BOOL fAppendDefault); + + HRESULT ( STDMETHODCALLTYPE *GetProperties )( + IFileSaveDialog * This, + /* [out] */ __RPC__deref_out_opt IPropertyStore **ppStore); + + HRESULT ( STDMETHODCALLTYPE *ApplyProperties )( + IFileSaveDialog * This, + /* [in] */ __RPC__in_opt IShellItem *psi, + /* [in] */ __RPC__in_opt IPropertyStore *pStore, + /* [unique][in] */ __RPC__in_opt HWND hwnd, + /* [unique][in] */ __RPC__in_opt IFileOperationProgressSink *pSink); + + END_INTERFACE + } IFileSaveDialogVtbl; + + interface IFileSaveDialog + { + CONST_VTBL struct IFileSaveDialogVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFileSaveDialog_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IFileSaveDialog_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IFileSaveDialog_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IFileSaveDialog_Show(This,hwndParent) \ + ( (This)->lpVtbl -> Show(This,hwndParent) ) + + +#define IFileSaveDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \ + ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) ) + +#define IFileSaveDialog_SetFileTypeIndex(This,iFileType) \ + ( (This)->lpVtbl -> SetFileTypeIndex(This,iFileType) ) + +#define IFileSaveDialog_GetFileTypeIndex(This,piFileType) \ + ( (This)->lpVtbl -> GetFileTypeIndex(This,piFileType) ) + +#define IFileSaveDialog_Advise(This,pfde,pdwCookie) \ + ( (This)->lpVtbl -> Advise(This,pfde,pdwCookie) ) + +#define IFileSaveDialog_Unadvise(This,dwCookie) \ + ( (This)->lpVtbl -> Unadvise(This,dwCookie) ) + +#define IFileSaveDialog_SetOptions(This,fos) \ + ( (This)->lpVtbl -> SetOptions(This,fos) ) + +#define IFileSaveDialog_GetOptions(This,pfos) \ + ( (This)->lpVtbl -> GetOptions(This,pfos) ) + +#define IFileSaveDialog_SetDefaultFolder(This,psi) \ + ( (This)->lpVtbl -> SetDefaultFolder(This,psi) ) + +#define IFileSaveDialog_SetFolder(This,psi) \ + ( (This)->lpVtbl -> SetFolder(This,psi) ) + +#define IFileSaveDialog_GetFolder(This,ppsi) \ + ( (This)->lpVtbl -> GetFolder(This,ppsi) ) + +#define IFileSaveDialog_GetCurrentSelection(This,ppsi) \ + ( (This)->lpVtbl -> GetCurrentSelection(This,ppsi) ) + +#define IFileSaveDialog_SetFileName(This,pszName) \ + ( (This)->lpVtbl -> SetFileName(This,pszName) ) + +#define IFileSaveDialog_GetFileName(This,pszName) \ + ( (This)->lpVtbl -> GetFileName(This,pszName) ) + +#define IFileSaveDialog_SetTitle(This,pszTitle) \ + ( (This)->lpVtbl -> SetTitle(This,pszTitle) ) + +#define IFileSaveDialog_SetOkButtonLabel(This,pszText) \ + ( (This)->lpVtbl -> SetOkButtonLabel(This,pszText) ) + +#define IFileSaveDialog_SetFileNameLabel(This,pszLabel) \ + ( (This)->lpVtbl -> SetFileNameLabel(This,pszLabel) ) + +#define IFileSaveDialog_GetResult(This,ppsi) \ + ( (This)->lpVtbl -> GetResult(This,ppsi) ) + +#define IFileSaveDialog_AddPlace(This,psi,fdap) \ + ( (This)->lpVtbl -> AddPlace(This,psi,fdap) ) + +#define IFileSaveDialog_SetDefaultExtension(This,pszDefaultExtension) \ + ( (This)->lpVtbl -> SetDefaultExtension(This,pszDefaultExtension) ) + +#define IFileSaveDialog_Close(This,hr) \ + ( (This)->lpVtbl -> Close(This,hr) ) + +#define IFileSaveDialog_SetClientGuid(This,guid) \ + ( (This)->lpVtbl -> SetClientGuid(This,guid) ) + +#define IFileSaveDialog_ClearClientData(This) \ + ( (This)->lpVtbl -> ClearClientData(This) ) + +#define IFileSaveDialog_SetFilter(This,pFilter) \ + ( (This)->lpVtbl -> SetFilter(This,pFilter) ) + + +#define IFileSaveDialog_SetSaveAsItem(This,psi) \ + ( (This)->lpVtbl -> SetSaveAsItem(This,psi) ) + +#define IFileSaveDialog_SetProperties(This,pStore) \ + ( (This)->lpVtbl -> SetProperties(This,pStore) ) + +#define IFileSaveDialog_SetCollectedProperties(This,pList,fAppendDefault) \ + ( (This)->lpVtbl -> SetCollectedProperties(This,pList,fAppendDefault) ) + +#define IFileSaveDialog_GetProperties(This,ppStore) \ + ( (This)->lpVtbl -> GetProperties(This,ppStore) ) + +#define IFileSaveDialog_ApplyProperties(This,psi,pStore,hwnd,pSink) \ + ( (This)->lpVtbl -> ApplyProperties(This,psi,pStore,hwnd,pSink) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFileSaveDialog_INTERFACE_DEFINED__ */ + + +class DECLSPEC_UUID("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7") FileOpenDialog; +class DECLSPEC_UUID("C0B4E2F3-BA21-4773-8DBA-335EC946EB8B") FileSaveDialog; + +_COM_SMARTPTR_TYPEDEF(IFileDialog, __uuidof(IFileDialog)); +_COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog)); +_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); +_COM_SMARTPTR_TYPEDEF(IFileDialogCustomize, __uuidof(IFileDialogCustomize)); +_COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray)); + +//helper class +class Win7FileDialog +{ +public: + Win7FileDialog(const char *name, int issave=0); + ~Win7FileDialog(); + + int inited() { return m_fod != NULL; } + int show(HWND parent); + + void setFilterList(const char *list); + void setDefaultExtension(const char *ext); + void setFileTypeIndex(int i); //1-based + void setFolder(const char *folder, int def=1); //def is for default folder + void setFilename(const char *fn); + void setTemplate(HINSTANCE inst, const char *dlgid, LPOFNHOOKPROC proc); + + void addOptions(DWORD o); + + void startGroup(DWORD id, char *label); + void addText(DWORD id, char *txt); + void addCheckbox(char *name, DWORD id, int defval); + void endGroup(); + + int getState(DWORD id); + void getResult(char *fn, int maxlen); + int getResult(int i, char *fn, int maxlen); + +private: + IFileDialogPtr m_fod; + IFileDialogCustomizePtr m_fdc; + + HINSTANCE m_inst; + const char *m_dlgid; + LPOFNHOOKPROC m_proc; + + WDL_String m_statictxt; +}; +#endif + +#endif diff --git a/WDL/wingui/dlgitemborder.h b/WDL/wingui/dlgitemborder.h new file mode 100644 index 00000000..ff7dd436 --- /dev/null +++ b/WDL/wingui/dlgitemborder.h @@ -0,0 +1,204 @@ +/* + WDL - dlgitemborder.h + Copyright (C) 1998-2003, Nullsoft Inc. + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides code to aide in drawing additional borders in dialogs. + + */ + + +#ifndef _WDL_DLGITEMBORDER_H_ +#define _WDL_DLGITEMBORDER_H_ + +#define DCW_SUNKENBORDER 0x00010000 +#define DCW_SUNKENBORDER_NOTOP 0x00020000 +#define DCW_DIVIDER_VERT 0x00030000 +#define DCW_DIVIDER_HORZ 0x00040000 +#define DCW_HWND_FOLLOW 0x40000000 + +#ifndef WDL_DLGITEMBORDER_NOIMPL + +static int RectInRect(RECT *rect1, RECT *rect2) +{ + // this has a bias towards true + + // this could probably be optimized a lot + return ((rect1->top >= rect2->top && rect1->top <= rect2->bottom) || + (rect1->bottom >= rect2->top && rect1->bottom <= rect2->bottom) || + (rect2->top >= rect1->top && rect2->top <= rect1->bottom) || + (rect2->bottom >= rect1->top && rect2->bottom <= rect1->bottom)) // vertical intersect + && + ((rect1->left >= rect2->left && rect1->left <= rect2->right) || + (rect1->right >= rect2->left && rect1->right <= rect2->right) || + (rect2->left >= rect1->left && rect2->left <= rect1->right) || + (rect2->right >= rect1->left && rect2->right <= rect1->right)) // horiz intersect + ; +} + +#ifdef _WIN32 +static void Dlg_removeFromRgn(HRGN hrgn, int left, int top, int right, int bottom) +{ + HRGN rgn2=CreateRectRgn(left,top,right,bottom); + CombineRgn(hrgn,hrgn,rgn2,RGN_DIFF); + DeleteObject(rgn2); +} +#else +#define Dlg_removeFromRgn(a,b,c,d,e) +#endif + +static void Dlg_DrawChildWindowBorders(HWND hwndDlg, INT_PTR *tab, int tabsize, int (*GSC)(int)=0, PAINTSTRUCT *__use_ps=NULL +#ifdef WDL_DLGITEMBORDER_CUSTOMPARMS + , WDL_DLGITEMBORDER_CUSTOMPARMS +#endif + + ) +{ + PAINTSTRUCT ps; + if (!__use_ps) + { + BeginPaint(hwndDlg,&ps); + __use_ps=&ps; + } + +#ifdef _WIN32 + HRGN hrgn=NULL; + if(__use_ps->fErase) + { + RECT r=__use_ps->rcPaint; + hrgn=CreateRectRgn(r.left,r.top,r.right,r.bottom); + } +#else + int hrgn=0; +#endif + + HPEN pen=CreatePen(PS_SOLID,0,GSC?GSC(COLOR_3DHILIGHT):GetSysColor(COLOR_3DHILIGHT)); + HPEN pen2=CreatePen(PS_SOLID,0,GSC?GSC(COLOR_3DSHADOW):GetSysColor(COLOR_3DSHADOW)); + + while (tabsize--) + { + RECT r; + int a=*tab++; + if (a & DCW_HWND_FOLLOW) + { + a&=~DCW_HWND_FOLLOW; + if (!tabsize) break; + GetWindowRect((HWND)*tab++,&r); + tabsize--; + + ScreenToClient(hwndDlg,(LPPOINT)&r); + ScreenToClient(hwndDlg,((LPPOINT)&r)+1); + } + else + { + int sa=a&0xffff; + if (sa == 0) + { + GetClientRect(hwndDlg,&r); + } + else + { + GetWindowRect(GetDlgItem(hwndDlg,sa),&r); + + #ifdef CUSTOM_CHILDWNDBORDERCODE + CUSTOM_CHILDWNDBORDERCODE + #endif + ScreenToClient(hwndDlg,(LPPOINT)&r); + ScreenToClient(hwndDlg,((LPPOINT)&r)+1); + } + } + + if (RectInRect(&__use_ps->rcPaint,&r)) + { + if ((a & 0xffff0000) == DCW_SUNKENBORDER || (a&0xffff0000) == DCW_SUNKENBORDER_NOTOP) + { + MoveToEx(__use_ps->hdc,r.left-1,r.bottom,NULL); + HGDIOBJ o=SelectObject(__use_ps->hdc,pen); + LineTo(__use_ps->hdc,r.right,r.bottom); + LineTo(__use_ps->hdc,r.right,r.top-1); + SelectObject(__use_ps->hdc,pen2); + if ((a&0xffff0000) == DCW_SUNKENBORDER_NOTOP) + MoveToEx(__use_ps->hdc,r.left-1,r.top-1,NULL); + else + LineTo(__use_ps->hdc,r.left-1,r.top-1); + LineTo(__use_ps->hdc,r.left-1,r.bottom); + SelectObject(__use_ps->hdc,o); + if(hrgn) + { + Dlg_removeFromRgn(hrgn,r.left,r.bottom,r.right,r.bottom+1); + Dlg_removeFromRgn(hrgn,r.right,r.top,r.right+1,r.bottom); + if ((a&0xffff0000) != DCW_SUNKENBORDER_NOTOP) + Dlg_removeFromRgn(hrgn,r.left,r.top-1,r.right,r.top); + Dlg_removeFromRgn(hrgn,r.left-1,r.top,r.left,r.bottom); + } + } + else if ((a & 0xffff0000) == DCW_DIVIDER_VERT || (a & 0xffff0000) == DCW_DIVIDER_HORZ) + { + if ((a & 0xffff0000) == DCW_DIVIDER_VERT) // vertical + { + int left=r.left; + HGDIOBJ o=SelectObject(__use_ps->hdc,pen2); + MoveToEx(__use_ps->hdc,left,r.top,NULL); + LineTo(__use_ps->hdc,left,r.bottom+1); + SelectObject(__use_ps->hdc,pen); + MoveToEx(__use_ps->hdc,left+1,r.top,NULL); + LineTo(__use_ps->hdc,left+1,r.bottom+1); + SelectObject(__use_ps->hdc,o); + if(hrgn) Dlg_removeFromRgn(hrgn,left,r.top,left+2,r.bottom); + } + else // horiz + { + int top=r.top+1; + HGDIOBJ o=SelectObject(__use_ps->hdc,pen2); + MoveToEx(__use_ps->hdc,r.left,top,NULL); + LineTo(__use_ps->hdc,r.right+1,top); + SelectObject(__use_ps->hdc,pen); + MoveToEx(__use_ps->hdc,r.left,top+1,NULL); + LineTo(__use_ps->hdc,r.right+1,top+1); + SelectObject(__use_ps->hdc,o); + if(hrgn) Dlg_removeFromRgn(hrgn,r.left,top,r.right,top+2); + } + } + } + } + + DeleteObject(pen); + DeleteObject(pen2); + +#ifdef _WIN32 + if(hrgn) { + //erase bkgnd while clipping out our own drawn stuff (for flickerless display) +#ifdef WDL_DLGITEMBORDER_CUSTOMBGCODE + WDL_DLGITEMBORDER_CUSTOMBGCODE +#else + HBRUSH b=CreateSolidBrush(GSC?GSC(COLOR_3DFACE):GetSysColor(COLOR_3DFACE)); + FillRgn(__use_ps->hdc,hrgn,b); + DeleteObject(b); +#endif + + DeleteObject(hrgn); + } +#endif + if (__use_ps == &ps) EndPaint(hwndDlg,&ps); +} + +#endif + +#endif \ No newline at end of file diff --git a/WDL/wingui/membitmap.h b/WDL/wingui/membitmap.h new file mode 100644 index 00000000..bed2700b --- /dev/null +++ b/WDL/wingui/membitmap.h @@ -0,0 +1,94 @@ +/* + WDL - membitmap.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides a wrapper around the win32 bitmaps, to allow the callee to easily + manage a framebuffer. It's mostly deprecated by LICE/, however. + + */ + + + +#ifndef _WDL_WINMEMBITMAP_H_ +#define _WDL_WINMEMBITMAP_H_ + +#ifndef _WIN32 +#include "../swell/swell.h" +#endif + +class WDL_WinMemBitmap +{ +public: + WDL_WinMemBitmap() + { + m_w=m_h=-100; + m_hdc=0; +#ifdef _WIN32 + m_bm=0; m_oldbm=0; +#endif + } + ~WDL_WinMemBitmap() + { +#ifdef _WIN32 + if (m_oldbm) SelectObject(m_hdc,m_oldbm); + if (m_bm) DeleteObject(m_bm); + + if (m_hdc) DeleteDC(m_hdc); +#else + if (m_hdc) SWELL_DeleteGfxContext(m_hdc); +#endif + } + + int DoSize(HDC compatDC, int w, int h) // returns 1 if it was resized + { + if (m_w == w && m_h == h && m_hdc +#ifdef _WIN32 + && m_bm +#endif + ) return 0; + +#ifdef _WIN32 + if (!m_hdc) m_hdc=CreateCompatibleDC(compatDC); + if (m_oldbm) SelectObject(m_hdc,m_oldbm); + if (m_bm) DeleteObject(m_bm); + m_bm=CreateCompatibleBitmap(compatDC,m_w=w,m_h=h); + m_oldbm=SelectObject(m_hdc,m_bm); +#else + if (m_hdc) SWELL_DeleteGfxContext(m_hdc); + m_hdc=SWELL_CreateMemContext(compatDC,m_w=w,m_h=h); +#endif + return 1; + } + int GetW() { return m_w; } + int GetH() { return m_h; } + HDC GetDC() { return m_hdc; } + +private: + + HDC m_hdc; +#ifdef _WIN32 + HBITMAP m_bm; + HGDIOBJ m_oldbm; +#endif + int m_w,m_h; +}; + + +#endif \ No newline at end of file diff --git a/WDL/wingui/richeditctrl.h b/WDL/wingui/richeditctrl.h new file mode 100644 index 00000000..5fca39ae --- /dev/null +++ b/WDL/wingui/richeditctrl.h @@ -0,0 +1,83 @@ +/* + WDL - richeditctrl.h + Copyright (C) 2005 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + */ + + +#ifndef _WDL_RICHEDITCTRL_H +#define _WDL_RICHEDITCTRL_H + +#include +#include + +class WDL_RichEditCtrl +{ + public: + WDL_RichEditCtrl() { setWnd(NULL); m_color=0; m_bold=0; } + WDL_RichEditCtrl(HWND hwnd) { setWnd(hwnd); m_color=0; m_bold=0; } + ~WDL_RichEditCtrl() { }; + + void setWnd(HWND hwnd) { + m_hwnd=hwnd; + if(hwnd) { + SendMessage(m_hwnd, EM_SETEVENTMASK, 0, ENM_LINK); + SendMessage(m_hwnd, EM_AUTOURLDETECT, 1, 0); + } + } + HWND getWnd() { return m_hwnd; } + + int getLength() { return GetWindowTextLength(m_hwnd); } + void getText(char *txt, int size) { GetWindowText(m_hwnd, txt, size); } + void setText(char *txt) { SetWindowText(m_hwnd, txt); } + void addText(char *txt) + { + setSel(getLength(), getLength()); + CHARFORMAT2 cf2; + cf2.cbSize=sizeof(cf2); + cf2.dwMask=CFM_COLOR|CFM_BOLD; + cf2.dwEffects=m_bold?CFE_BOLD:0; + cf2.crTextColor=m_color; + SendMessage(m_hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + replaceSel(txt); + + int mi,ma; + GetScrollRange(m_hwnd,SB_VERT,&mi,&ma); + SendMessage(m_hwnd, WM_VSCROLL, (ma<<16)+SB_THUMBPOSITION,0); + //SetScrollPos(m_hwnd,SB_VERT,ma,TRUE); + + //SendMessage(m_hwnd, WM_VSCROLL, SB_BOTTOM,0); // buggy on windows ME + } + void setSel(int start, int end) { SendMessage(m_hwnd, EM_SETSEL, start, end); } + void replaceSel(char *txt) { SendMessage(m_hwnd, EM_REPLACESEL, 0L, (LPARAM)txt); } + + void clear() { setText(""); } + + void setTextColor(int color) { m_color=color; } + + void setBold(int b) { m_bold=b; } + + protected: + HWND m_hwnd; + COLORREF m_color; + int m_bold; +}; + +#endif//_WDL_RICHEDITCTRL_H \ No newline at end of file diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp new file mode 100644 index 00000000..830b3aee --- /dev/null +++ b/WDL/wingui/scrollbar/coolscroll.cpp @@ -0,0 +1,3741 @@ +/* + WDL - Skinned/Resizing thumb scrollbar library + Based on the "Cool Scrollbar Library v1.2" by James Brown - http://www.catch22.net + + Original version Copyright(c) 2001 J Brown + Modifications copyright (C) 2006 and later Cockos Incorporated + + Note: for a more featureful and complete, less hacked up version, you may wish to + download the original from http://www.catch22.net. It has lots of added features, + whereas this version is very much tailored for Cockos' needs. + + License: + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Original readme from Cool Scrollbar Library Version 1.2 + + Copyright (c) J Brown 2001 + + This code is freeware, however, you may not publish + this code elsewhere or charge any money for it. This code + is supplied as-is. I make no guarantees about the suitability + of this code - use at your own risk. + + It would be nice if you credited me, in the event + that you use this code in a product. + + VERSION HISTORY: + + V1.2: TreeView problem fixed by Diego Tartara + Small problem in thumbsize calculation also fixed (thanks Diego!) + + V1.1: Added support for Right-left windows + Changed calling convention of APIs to WINAPI (__stdcall) + Completely standalone (no need for c-runtime) + Now supports ALL windows with appropriate USER32.DLL patching + (you provide!!) + + V1.0: Apr 2001: Initial Version + + IMPORTANT: + This whole library is based around code for a horizontal scrollbar. + All "vertical" scrollbar drawing / mouse interaction uses the + horizontal scrollbar functions, but uses a trick to convert the vertical + scrollbar coordinates into horizontal equivelants. When I started this project, + I quickly realised that the code for horz/vert bars was IDENTICAL, apart + from the fact that horizontal code uses left/right coords, and vertical code + uses top/bottom coords. On entry to a "vertical" drawing function, for example, + the coordinates are "rotated" before the horizontal function is called, and + then rotated back once the function has completed. When something needs to + be drawn, the coords are converted back again before drawing. + + This trick greatly reduces the amount of code required, and makes + maintanence much simpler. This way, only one function is needed to draw + a scrollbar, but this can be used for both horizontal and vertical bars + with careful thought. + + Notes on Cockos modifications: + + We tweaked this to support resizing thumbs, native zoom buttons, etc, and skinnability using LICE (if a skin image is supplied). + Additionally we modified it to support OS X using SWELL (since SWELL does not provide a scrollbar API, this can be used for that purpose). + We also shoved everything into one file, for various reasons. + +*/ + +#ifdef _WIN32 + #include + #include + #include + #include +#else + #include "../../swell/swell.h" + #define __stdcall + typedef char TCHAR; + #ifndef SWP_FRAMECHANGED + #define SWP_FRAMECHANGED 0 + #endif +#endif + +#include "../../lice/lice.h" +#include "../../ptrlist.h" + +#include "coolscroll.h" + +#define ZOOMBUTTON_RESIZER_SIZE(zbs) (max(((zbs)/4),2)) +#define MIN_SIZE_FOR_ZOOMBUTTONS(zbs) (6*(zbs)) + +// +// SCROLLBAR datatype. There are two of these structures per window +// +typedef struct +{ + UINT fScrollFlags; //flags + BOOL fScrollVisible; //if this scrollbar visible? + SCROLLINFO scrollInfo; //positional data (range, position, page size etc) + + int nBarType; //SB_HORZ / SB_VERT + + int nMinThumbSize; + + LICE_SysBitmap *liceBkgnd; + LICE_SysBitmap *liceThumb; + int liceBkgnd_ver; + int liceThumb_ver; + + int liceThumbState; + +} SCROLLBAR; + +// +// Container structure for a cool scrollbar window. +// +typedef struct +{ + UINT bars; //which of the scrollbars do we handle? SB_VERT / SB_HORZ / SB_BOTH + WNDPROC oldproc; //old window procedure to call for every message + + SCROLLBAR sbarHorz; //one scrollbar structure each for + SCROLLBAR sbarVert; //the horizontal and vertical scrollbars + + BOOL fThumbTracking; // are we currently thumb-tracking?? + BOOL fLeftScrollbar; // support the WS_EX_LEFTSCROLLBAR style + + //size of the window borders + int cxLeftEdge, cxRightEdge; + int cyTopEdge, cyBottomEdge; + + // To prevent calling original WindowProc in response + // to our own temporary style change (fixes TreeView problem) + BOOL bPreventStyleChange; + + BOOL resizingHthumb; + + + // internal state stuff + + UINT uScrollTimerMsg; + + UINT uMouseOverId; + UINT uScrollTimerId; + UINT uZoomTimerId, uZoomTimerMode; + + RECT MouseOverRect; + BOOL MouseOverRect_hasZoomButtons; + + UINT uCurrentScrollbar; + UINT uCurrentScrollPortion; + UINT uMouseOverScrollbar; + UINT uHitTestPortion; + UINT uLastHitTestPortion; + UINT uScrollTimerPortion; + + +} SCROLLWND; + + + +// +// Minimum size in pixels of a scrollbar thumb +// +#define MINTHUMBSIZE_NT4 8 +#define MINTHUMBSIZE_2000 6 +#define RESIZETHUMBSIZE 6 + + +// To complement the exisiting SB_HORZ, SB_VERT, SB_BOTH +// scrollbar identifiers +#define COOLSB_NONE (-1) + +// general scrollbar styles +// +// use the standard ESB_DISABLE_xxx flags to represent the +// enabled / disabled states. (defined in winuser.h) +// +#define CSBS_THUMBALWAYS 4 +#define CSBS_VISIBLE 8 + + +//define some more hittest values for our cool-scrollbar +#define HTSCROLL_LEFT (SB_LINELEFT) +#define HTSCROLL_RIGHT (SB_LINERIGHT) +#define HTSCROLL_UP (SB_LINEUP) +#define HTSCROLL_DOWN (SB_LINEDOWN) +#define HTSCROLL_THUMB (SB_THUMBTRACK) +#define HTSCROLL_PAGEGUP (SB_PAGEUP) +#define HTSCROLL_PAGEGDOWN (SB_PAGEDOWN) +#define HTSCROLL_PAGELEFT (SB_PAGELEFT) +#define HTSCROLL_PAGERIGHT (SB_PAGERIGHT) + +#define HTSCROLL_NONE (-1) +#define HTSCROLL_NORMAL (-1) + +#define HTSCROLL_INSERTED (128) +#define HTSCROLL_PRE (32 | HTSCROLL_INSERTED) +#define HTSCROLL_POST (64 | HTSCROLL_INSERTED) + +#define HTSCROLL_LRESIZER (256) +#define HTSCROLL_RRESIZER (256+1) + +#define HTSCROLL_RESIZER (256+2) + +#define HTSCROLL_ZOOMIN (256+3) +#define HTSCROLL_ZOOMOUT (256+4) + + +// +#define SM_CXVERTSB 1 +#define SM_CYVERTSB 0 +#define SM_CXHORZSB 0 +#define SM_CYHORZSB 1 +#define SM_SCROLL_WIDTH 1 +#define SM_SCROLL_LENGTH 0 + + + +#define InvertCOLORREF(col) ((col) ^ RGB(255,255,255)) + +#define COOLSB_TIMERID1 65533 //initial timer +#define COOLSB_TIMERID2 65534 //scroll message timer +#define COOLSB_TIMERID3 -14 //mouse hover timer +#define COOLSB_TIMERID4 0xfffef110 // used for when holding a zoom button +#define COOLSB_TIMERINTERVAL1 300 +#define COOLSB_TIMERINTERVAL2 55 +#define COOLSB_TIMERINTERVAL3 20 //mouse hover time +#define COOLSB_TIMERINTERVAL4 150 //holding the zoom buttons + + + + +static int g_coolsb_imageVersion; // liceBkgnd_ver, liceThumb_ver + +static LICE_IBitmap **m_scrollbar_bmp = NULL; +static int m_scrollbar_hasPink; +static int m_sb_thumbHV[5], m_sb_thumbVV[5]; // +static int m_sb_bkghl, m_sb_bkghr; +static int m_sb_bkgvt, m_sb_bkgvb; + + + + +// +// Special thumb-tracking variables +// +// + +static RECT rcThumbBounds; //area that the scroll thumb can travel in +static int nThumbSize; //(pixels) +static int nThumbPos; //(pixels) +static int nThumbMouseOffset; //(pixels) +static int nLastPos = -1; //(scrollbar units) +static int nThumbPos0; //(pixels) initial thumb position + +// +// Temporary state used to auto-generate timer messages +// + +static HWND hwndCurCoolSB = 0; +static float m_scale = 1.0; +static int m_thumbsize = 6; + +static LRESULT MouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam); + +static SCROLLWND *GetScrollWndFromHwnd(HWND hwnd); +// +// Provide this so there are NO dependencies on CRT +// + + +// +// swap the rectangle's x coords with its y coords +// +static void __stdcall RotateRect(RECT *rect) +{ + int temp; + temp = rect->left; + rect->left = rect->top; + rect->top = temp; + + temp = rect->right; + rect->right = rect->bottom; + rect->bottom = temp; +} + +// +// swap the coords if the scrollbar is a SB_VERT +// +static void __stdcall RotateRect0(SCROLLBAR *sb, RECT *rect) +{ + if(sb->nBarType == SB_VERT) + RotateRect(rect); +} + +// +// Calculate if the SCROLLINFO members produce +// an enabled or disabled scrollbar +// +static BOOL IsScrollInfoActive(SCROLLINFO *si) +{ + if((si->nPage > (UINT)si->nMax + || si->nMax <= si->nMin || si->nMax == 0)) + return FALSE; + else + return TRUE; +} + +// +// Return if the specified scrollbar is enabled or not +// +static BOOL IsScrollbarActive(SCROLLBAR *sb) +{ + SCROLLINFO *si = &sb->scrollInfo; + if(((sb->fScrollFlags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) || + !(sb->fScrollFlags & CSBS_THUMBALWAYS) && !IsScrollInfoActive(si)) + return FALSE; + else + return TRUE; +} + +#ifdef __APPLE__ +static void GET_WINDOW_RECT(HWND hwnd, RECT *r) +{ + GetWindowContentViewRect(hwnd,r); + if (r->top>r->bottom) + { + int tmp = r->top; + r->top = r->bottom; + r->bottom = tmp; + } + +} +#else +#define GET_WINDOW_RECT(hwnd, r) GetWindowRect(hwnd,r) +#endif + +#ifdef __APPLE__ +static void OSX_REMAP_SCREENY(HWND hwnd, LONG *y) +{ +// POINT p={0,0}; + //ClientToScreen(hwnd,&p); + POINT p={0,*y}; + RECT tr; + GetClientRect(hwnd,&tr); + ScreenToClient(hwnd,&p); + p.y-=tr.top; + RECT r; + GetWindowRect(hwnd,&r); + + *y=min(r.bottom,r.top)+p.y; +// map Y from "screen" coordinate +} + +#else + +#define OSX_REMAP_SCREENY(hwnd, y) +#endif + +static BOOL ownDrawEdge(HWND hwnd, HDC hdc, LPRECT qrc, UINT edge, UINT grfFlags) +{ + HPEN pen1 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT)); + HPEN pen2 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DSHADOW)); + HPEN pen3 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + HPEN pen4 = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); + HPEN oldpen = (HPEN)SelectObject(hdc,pen3); + + if(edge == EDGE_RAISED) + { + MoveToEx(hdc, qrc->left, qrc->top, NULL); + LineTo(hdc, qrc->right, qrc->top); + MoveToEx(hdc, qrc->left, qrc->top, NULL); + LineTo(hdc, qrc->left, qrc->bottom); + SelectObject(hdc,pen1); + MoveToEx(hdc, qrc->left+1, qrc->top+1, NULL); + LineTo(hdc, qrc->right-1, qrc->top+1); + MoveToEx(hdc, qrc->left+1, qrc->top+1, NULL); + LineTo(hdc, qrc->left+1, qrc->bottom-2); + SelectObject(hdc,pen2); + MoveToEx(hdc, qrc->left+1, qrc->bottom-2, NULL); + LineTo(hdc, qrc->right-1, qrc->bottom-2); + MoveToEx(hdc, qrc->right-2, qrc->bottom-2, NULL); + LineTo(hdc, qrc->right-2, qrc->top+1); + SelectObject(hdc,pen4); + MoveToEx(hdc, qrc->left, qrc->bottom-1, NULL); + LineTo(hdc, qrc->right, qrc->bottom-1); + MoveToEx(hdc, qrc->right-1, qrc->bottom-1, NULL); + LineTo(hdc, qrc->right-1, qrc->top); + } + else + { + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + FillRect(hdc, qrc, br); + DeleteObject(br); + + SelectObject(hdc, pen2); + MoveToEx(hdc, qrc->left, qrc->top, NULL); + LineTo(hdc, qrc->right, qrc->top); + MoveToEx(hdc, qrc->right-1, qrc->top, NULL); + LineTo(hdc, qrc->right-1, qrc->bottom); + MoveToEx(hdc, qrc->right-1, qrc->bottom-1, NULL); + LineTo(hdc, qrc->left, qrc->bottom-1); + MoveToEx(hdc, qrc->left, qrc->bottom-1, NULL); + LineTo(hdc, qrc->left, qrc->top); + } + + SelectObject(hdc, oldpen); + + DeleteObject(pen1); + DeleteObject(pen2); + DeleteObject(pen3); + DeleteObject(pen4); + + if(grfFlags & BF_ADJUST) + { + qrc->left+=2; + qrc->top+=2; + qrc->bottom-=2; + qrc->right-=2; + } + return 1; +} + + +static LRESULT CallWindowProcStyleMod(SCROLLWND *sw, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +#ifdef _WIN32 + bool restore=false; + DWORD dwStyle = GetWindowLong(hwnd,GWL_STYLE); + if (!sw->bPreventStyleChange && ( dwStyle & (WS_VSCROLL|WS_HSCROLL) )) + { + sw->bPreventStyleChange = TRUE; + SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~(WS_VSCROLL|WS_HSCROLL)); + restore = true; + } +#endif + + LRESULT ret = CallWindowProc(sw->oldproc,hwnd,msg,wParam,lParam); +#ifdef _WIN32 + if (restore) + { + SetWindowLong(hwnd, GWL_STYLE, dwStyle); + sw->bPreventStyleChange = FALSE; + } +#endif + return ret; +} + +static BOOL ownDrawFrameControl(HWND hwnd, HDC hdc, LPRECT lprc, UINT uType, UINT uState, int mouseOver) +{ + LICE_IBitmap *bmp; + if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) + { + static LICE_SysBitmap tmpbmp; + int w = lprc->right-lprc->left; + int h = lprc->bottom-lprc->top; + int startx = 116; + int starty = 121; + if((uState&0xf) == DFCS_SCROLLLEFT) starty += 20; + else if((uState&0xf) == DFCS_SCROLLRIGHT) starty += 40; + else if((uState&0xf) == DFCS_SCROLLDOWN) starty += 60; + if(uState & DFCS_PUSHED) startx += 34; + else if(mouseOver) startx += 17; + + if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) + tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); + + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + #ifndef _WIN32 + SWELL_SyncCtxFrameBuffer(tmpbmp.getDC()); + #endif + BitBlt(hdc, lprc->left, lprc->top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + return 1; + } + + RECT r = *lprc; + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + HBRUSH br2 = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNTEXT)); + HPEN pen = CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_BTNTEXT)); + HPEN oldpen; + HBRUSH oldbrush; + + ownDrawEdge(hwnd,hdc, &r, uState&DFCS_PUSHED?EDGE_ETCHED:EDGE_RAISED, BF_ADJUST); + FillRect(hdc, &r, br); + + if(uState & DFCS_PUSHED) + { + r.left++; + r.top++; + r.bottom++; + r.right++; + } + if(!((r.bottom-r.top)&1)) + { + if((uState&0xf) == DFCS_SCROLLRIGHT || (uState&0xf) == DFCS_SCROLLLEFT) + { + /*if ((uState&0xf) == DFCS_SCROLLLEFT) r.right++; + else r.left--; + r.top--;*/ + r.bottom--; + if ((uState&0xf) == DFCS_SCROLLRIGHT) + { + r.left--; + r.right--; + } + } + else + { + /*if ((uState&0xf) != DFCS_SCROLLUP) r.top--; + else r.bottom++; + r.left--;*/ + r.right--; + if ((uState&0xf) != DFCS_SCROLLUP) + { + r.top--; + r.bottom--; + } + else + { + r.top++; + r.bottom++; + } + } + } + oldpen = (HPEN)SelectObject(hdc, pen); + oldbrush = (HBRUSH)SelectObject(hdc, br2); + if((uState&0xf) == DFCS_SCROLLRIGHT) + { + int h = r.bottom-r.top-6; + POINT p[3]={{r.right-4,r.top+3+(h/2)},{r.left+5,r.top+2},{r.left+5,r.bottom-3}}; + Polygon(hdc, p, 3); + } + else if((uState&0xf) == DFCS_SCROLLLEFT) + { + int h = r.bottom-r.top-6; + POINT p[3]={{r.left+3,r.top+3+(h/2)},{r.right-6,r.top+2},{r.right-6,r.bottom-3}}; + Polygon(hdc, p, 3); + } + else if((uState&0xf) == DFCS_SCROLLDOWN) + { + int w = r.right-r.left-6; + POINT p[3]={{r.left+3+(w/2),r.bottom-4},{r.left+2,r.top+5},{r.right-3,r.top+5}}; + Polygon(hdc, p, 3); + } + else if((uState&0xf) == DFCS_SCROLLUP) + { + int w = r.right-r.left-6; + POINT p[3]={{r.left+3+(w/2),r.top+3},{r.left+2,r.bottom-6},{r.right-3,r.bottom-6}}; + Polygon(hdc, p, 3); + } + + SelectObject(hdc, oldpen); + SelectObject(hdc, oldbrush); + + DeleteObject(br); + DeleteObject(br2); + DeleteObject(pen); + + return 1; +} + +// +// Draw a standard scrollbar arrow +// +static int DrawScrollArrow(HWND hwnd, SCROLLBAR *sbar, HDC hdc, RECT *rect, UINT arrow, BOOL fMouseDown, BOOL fMouseOver) +{ + UINT ret; + UINT flags = arrow; + + //HACKY bit so this routine can be called by vertical and horizontal code + if(sbar->nBarType == SB_VERT) + { + if(flags & DFCS_SCROLLLEFT) flags = (flags & ~DFCS_SCROLLLEFT) | DFCS_SCROLLUP; + if(flags & DFCS_SCROLLRIGHT) flags = (flags & ~DFCS_SCROLLRIGHT) | DFCS_SCROLLDOWN; + } + + if(fMouseDown) flags |= (DFCS_FLAT | DFCS_PUSHED); + + + ret = ownDrawFrameControl(hwnd,hdc, rect, DFC_SCROLL, flags, fMouseOver); + + return ret; +} + +void CoolSB_SetScale(float scale) +{ + m_scale = scale; + m_thumbsize = (int)(RESIZETHUMBSIZE * scale); + if (m_thumbsize<2)m_thumbsize=2; +} + +// +// Return the size in pixels for the specified scrollbar metric, +// for the specified scrollbar +// +static int GetScrollMetric(BOOL isVert, int metric) +{ + if(!isVert) + { + if(metric == SM_CXHORZSB) + { + return (int)(GetSystemMetrics(SM_CXHSCROLL) * m_scale); + } + else + { + return (int)(GetSystemMetrics(SM_CYHSCROLL) * m_scale); + } + } + else + { + if(metric == SM_CYVERTSB) + { + return (int)(GetSystemMetrics(SM_CYVSCROLL) * m_scale); + } + else + { + return (int)(GetSystemMetrics(SM_CXVSCROLL) * m_scale); + } + } + + return 0; +} +static int GetZoomButtonSize(BOOL isVert) +{ + return (int)(GetSystemMetrics(isVert ? SM_CYVSCROLL : SM_CXHSCROLL) * m_scale); +} + + +// +// +// +static COLORREF GetSBForeColor(HWND hwnd) +{ + COLORREF c1 = CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT); + COLORREF c2 = CoolSB_GetSysColor(hwnd,COLOR_WINDOW); + + if(c1 != 0xffffff && c1 == c2) + { + return CoolSB_GetSysColor(hwnd,COLOR_BTNFACE); + } + else + { + return CoolSB_GetSysColor(hwnd,COLOR_3DHILIGHT); + } +} + +static COLORREF GetSBBackColor(HWND hwnd) +{ + return CoolSB_GetSysColor(hwnd,COLOR_SCROLLBAR); +} + +// +// Paint a checkered rectangle, with each alternate +// pixel being assigned a different colour +// +static void DrawCheckedRect(LICE_IBitmap *bmOut, HDC hdc, RECT *rect, COLORREF fg, COLORREF bg, SCROLLBAR *sb, const RECT *wndrect, int on, int offsx=0, int offsy=0) +{ + int isvert = sb->nBarType==SB_VERT; + + LICE_IBitmap *bmp; + if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) + { + int w = rect->right-rect->left; + int h = rect->bottom-rect->top; + int ww = wndrect->right - wndrect->left; + int wh = wndrect->bottom - wndrect->top; + if(isvert) + { + ww = wndrect->bottom - wndrect->top; + wh = wndrect->right - wndrect->left; + } + int nw = ww; + int nh = wh; + if(!isvert) nh *= 2; + else nw *= 2; + + if(!sb->liceBkgnd || sb->liceBkgnd->getWidth()!=nw || sb->liceBkgnd->getHeight()!=nh || sb->liceBkgnd_ver!=g_coolsb_imageVersion) + { + sb->liceBkgnd_ver=g_coolsb_imageVersion; + if(!sb->liceBkgnd) sb->liceBkgnd = new LICE_SysBitmap; + sb->liceBkgnd->resize(nw, nh); + if(!isvert) + { + int desth = nh/2; + if(m_scrollbar_hasPink) + { + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, m_sb_bkghl, desth, + 0, 0, m_sb_bkghl, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, m_sb_bkghl, 0, ww-m_sb_bkghl-m_sb_bkghr, desth, + m_sb_bkghl, 0, 204-m_sb_bkghl-m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, ww-m_sb_bkghr, 0, m_sb_bkghr, desth, + 204-m_sb_bkghr, 0, m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, desth, m_sb_bkghl, desth, + 0, 17, m_sb_bkghl, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, m_sb_bkghl, desth, ww-m_sb_bkghl-m_sb_bkghr, desth, + m_sb_bkghl, 17, 204-m_sb_bkghl-m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, ww-m_sb_bkghr, desth, m_sb_bkghr, desth, 204-m_sb_bkghr, + 17, m_sb_bkghr, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + } + else + { + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, ww, desth, 0, 0, 204, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, desth, ww, desth, 0, 17, 204, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + } + } + else + { + int destw = nw/2; + int starty = 34; + if(m_scrollbar_hasPink) + { + starty = 37; + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, destw, m_sb_bkgvt, + 170, starty, 17, m_sb_bkgvt, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, m_sb_bkgvt, destw, wh-m_sb_bkgvt-m_sb_bkgvb, + 170, starty+m_sb_bkgvt, 17, 238-starty-m_sb_bkgvt-m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, wh-m_sb_bkgvb, destw, m_sb_bkgvb, + 170, 238-m_sb_bkgvb, 17, m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, 0, destw, m_sb_bkgvt, + 187, starty, 17, m_sb_bkgvt, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, m_sb_bkgvt, destw, wh-m_sb_bkgvt-m_sb_bkgvb, + 187, starty+m_sb_bkgvt, 17, 238-starty-m_sb_bkgvt-m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, wh-m_sb_bkgvb, destw, m_sb_bkgvb, + 187, 238-m_sb_bkgvb, 17, m_sb_bkgvb, 1.0f, LICE_BLIT_FILTER_BILINEAR); + } + else + { + LICE_ScaledBlit(sb->liceBkgnd, bmp, 0, 0, destw, wh, 170, starty, 17, 238-starty, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceBkgnd, bmp, destw, 0, destw, wh, 187, starty, 17, 238-starty, 1.0f, LICE_BLIT_FILTER_BILINEAR); + } + } + } + if(!isvert) + { +// if (nh/2 != h) OutputDebugString("blah\n"); + if (bmOut) + LICE_ScaledBlit(bmOut, sb->liceBkgnd, rect->left,rect->top, w, h, + rect->left+offsx,on?nh/2:0, w, nh/2, 1.0f, LICE_BLIT_MODE_COPY); + else + { + BitBlt(hdc, rect->left, rect->top, w, h, sb->liceBkgnd->getDC(), rect->left+offsx, on?nh/2:0, SRCCOPY); + } + } + else + { +// if (nw/2 != w) OutputDebugString("blah2\n"); + if (bmOut) + LICE_ScaledBlit(bmOut, sb->liceBkgnd, rect->left,rect->top, w, h, on?nw/2:0, rect->top+offsy, nw/2, h, 1.0f, LICE_BLIT_MODE_COPY); + else + { + BitBlt(hdc, rect->left, rect->top, w, h, sb->liceBkgnd->getDC(), on?nw/2:0, rect->top+offsy, SRCCOPY); + } + } + return; + } + + static WORD wCheckPat[8] = + { + 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555 + }; + +#ifdef _WIN32 + HBITMAP hbmp; + HBRUSH hbr, hbrold; + COLORREF fgold, bgold; + + hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat); + hbr = CreatePatternBrush(hbmp); + + UnrealizeObject(hbr); + SetBrushOrgEx(hdc, rect->left, rect->top, 0); + + hbrold = (HBRUSH)SelectObject(hdc, hbr); + + fgold = SetTextColor(hdc, fg); + bgold = SetBkColor(hdc, bg); + + PatBlt(hdc, rect->left, rect->top, + rect->right - rect->left, + rect->bottom - rect->top, + PATCOPY); + + SetBkColor(hdc, bgold); + SetTextColor(hdc, fgold); + + SelectObject(hdc, hbrold); + DeleteObject(hbr); + DeleteObject(hbmp); +#else + HBRUSH br=CreateSolidBrush(RGB(100,100,100)); + FillRect(hdc,rect,br); + DeleteObject(br); + //FUCKO> osx version! +#endif + +} + +// +// Fill the specifed rectangle using a solid colour +// +static void PaintRect(HDC hdc, RECT *rect, COLORREF color) +{ +#ifdef _WIN32 + COLORREF oldcol = SetBkColor(hdc, color); + ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, _T(""), 0, 0); + SetBkColor(hdc, oldcol); +#else + HBRUSH br=CreateSolidBrush(color); + FillRect(hdc,rect,br); + DeleteObject(br); +#endif +} + +// +// Draw a simple blank scrollbar push-button. Can be used +// to draw a push button, or the scrollbar thumb +// drawflag - could set to BF_FLAT to make flat scrollbars +// +static void DrawBlankButton(HWND hwnd, HDC hdc, const RECT *rect) +{ + RECT rc = *rect; + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + + ownDrawEdge(hwnd,hdc, &rc, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &rc, br); + DeleteObject(br); +} + +// +// Send a WM_VSCROLL or WM_HSCROLL message +// +static void SendScrollMessage(HWND hwnd, UINT scrMsg, UINT scrId, UINT pos) +{ + SendMessage(hwnd, scrMsg, MAKEWPARAM(scrId, pos), 0); +} + +// +// Calculate the screen coordinates of the area taken by +// the horizontal scrollbar. Take into account the size +// of the window borders +// +static BOOL GetHScrollRect(SCROLLWND *sw, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) +{ + GET_WINDOW_RECT(hwnd, rect); + + if(sw->fLeftScrollbar) + { + rect->left += sw->cxLeftEdge + (sw->sbarVert.fScrollVisible ? + GetScrollMetric(TRUE, SM_CXVERTSB) : 0); + rect->right -= sw->cxRightEdge; + } + else + { + rect->left += sw->cxLeftEdge; //left window edge + + rect->right -= sw->cxRightEdge + //right window edge + (sw->sbarVert.fScrollVisible ? + GetScrollMetric(TRUE, SM_CXVERTSB) : 0); + } + + rect->bottom -= sw->cyBottomEdge; //bottom window edge + + rect->top = rect->bottom - + (sw->sbarHorz.fScrollVisible ? + GetScrollMetric(FALSE, SM_CYHORZSB) : 0); + + if (hasZoomButtons) *hasZoomButtons=0; + if(sw->resizingHthumb) + { + int zbs = GetZoomButtonSize(FALSE); + if (rect->right - rect->left >= MIN_SIZE_FOR_ZOOMBUTTONS(zbs)) + { + if (hasZoomButtons) *hasZoomButtons=1; + rect->right -= zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs); + } + } + //printf("ry=%d,%d\n",rect->top,rect->bottom); + + return TRUE; +} + +// +// Calculate the screen coordinates of the area taken by the +// vertical scrollbar +// +static BOOL GetVScrollRect(SCROLLWND *sw, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) +{ + GET_WINDOW_RECT(hwnd, rect); + rect->top += sw->cyTopEdge; //top window edge + + rect->bottom -= sw->cyBottomEdge + + (sw->sbarHorz.fScrollVisible ? //bottom window edge + GetScrollMetric(FALSE, SM_CYHORZSB) : 0); + + if(sw->fLeftScrollbar) + { + rect->left += sw->cxLeftEdge; + rect->right = rect->left + (sw->sbarVert.fScrollVisible ? + GetScrollMetric(TRUE, SM_CXVERTSB) : 0); + } + else + { + rect->right -= sw->cxRightEdge; + rect->left = rect->right - (sw->sbarVert.fScrollVisible ? + GetScrollMetric(TRUE, SM_CXVERTSB) : 0); + } + + if (hasZoomButtons) *hasZoomButtons=0; + if(sw->resizingHthumb) + { + int zbs = GetZoomButtonSize(TRUE); + if (rect->bottom - rect->top >= MIN_SIZE_FOR_ZOOMBUTTONS(zbs)) + { + if (hasZoomButtons) *hasZoomButtons=1; + rect->bottom -= zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs); + } + } + + return TRUE; +} + +// Depending on what type of scrollbar nBar refers to, call the +// appropriate Get?ScrollRect function +// +static BOOL GetScrollRect(SCROLLWND *sw, UINT nBar, HWND hwnd, RECT *rect, BOOL *hasZoomButtons) +{ + if(nBar == SB_HORZ) + return GetHScrollRect(sw, hwnd, rect,hasZoomButtons); + else if(nBar == SB_VERT) + return GetVScrollRect(sw, hwnd, rect,hasZoomButtons); + else + { + if (hasZoomButtons) *hasZoomButtons=0; + return FALSE; + } +} + + + +// +// Work out the scrollbar width/height for either type of scrollbar (SB_HORZ/SB_VERT) +// rect - coords of the scrollbar. +// store results into *thumbsize and *thumbpos +// +static int CalcThumbSize(SCROLLBAR *sbar, const RECT *rect, int *pthumbsize, int *pthumbpos) +{ + SCROLLINFO *si; + int scrollsize; //total size of the scrollbar including arrow buttons + int workingsize; //working area (where the thumb can slide) + int siMaxMin; + int butsize; + int startcoord; + int thumbpos = 0, thumbsize = 0; + + int adjust=0; + static int count=0; + + //work out the width (for a horizontal) or the height (for a vertical) + //of a standard scrollbar button + butsize = GetScrollMetric(sbar->nBarType == SB_VERT, SM_SCROLL_LENGTH); + + if(1) //sbar->nBarType == SB_HORZ) + { + scrollsize = rect->right - rect->left; + startcoord = rect->left; + } + /*else if(sbar->nBarType == SB_VERT) + { + scrollsize = rect->bottom - rect->top; + startcoord = rect->top; + } + else + { + return 0; + }*/ + + si = &sbar->scrollInfo; + siMaxMin = si->nMax - si->nMin + 1; + workingsize = scrollsize - butsize * 2; + + // + // Work out the scrollbar thumb SIZE + // + if(si->nPage == 0) + { + thumbsize = butsize; + } + else if(siMaxMin > 0) + { + thumbsize = MulDiv(si->nPage, workingsize, siMaxMin); + + if(thumbsize < sbar->nMinThumbSize) + thumbsize = sbar->nMinThumbSize; + } + + // + // Work out the scrollbar thumb position + // + if(siMaxMin > 0) + { + int pagesize = max(1, si->nPage); + thumbpos = MulDiv(si->nPos - si->nMin, workingsize-thumbsize, siMaxMin - pagesize); + + if(thumbpos < 0) + thumbpos = 0; + + if(thumbpos >= workingsize-thumbsize) + thumbpos = workingsize-thumbsize; + } + + thumbpos += startcoord + butsize; + + *pthumbpos = thumbpos; + *pthumbsize = thumbsize; + + return 1; +} + +// +// return a hit-test value for whatever part of the scrollbar x,y is located in +// rect, x, y: SCREEN coordinates +// the rectangle must not include space for any inserted buttons +// (i.e, JUST the scrollbar area) +// +static UINT GetHorzScrollPortion(SCROLLBAR *sbar, HWND hwnd, const RECT *rect, int x, int y, BOOL hasZoomButtons) +{ + int thumbwidth, thumbpos; + int butwidth = GetScrollMetric(sbar->nBarType == SB_VERT, SM_SCROLL_LENGTH); + int scrollwidth = rect->right-rect->left; + int workingwidth = scrollwidth - butwidth*2; + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + + if(y < rect->top || y >= rect->bottom) + return HTSCROLL_NONE; + + CalcThumbSize(sbar, rect, &thumbwidth, &thumbpos); + + //if we have had to scale the buttons to fit in the rect, + //then adjust the button width accordingly + if(scrollwidth <= butwidth * 2) + { + butwidth = scrollwidth / 2; + } + + if(sw->resizingHthumb&&hasZoomButtons) + { + //check for resizer + if(x>=rect->right) + { + const int zbs = GetZoomButtonSize(sbar->nBarType==SB_VERT); + const int zrs = ZOOMBUTTON_RESIZER_SIZE(zbs); + if (x < rect->right+zbs) return HTSCROLL_ZOOMIN; + if (x < rect->right+zbs+zrs) return HTSCROLL_RESIZER; + if (x < rect->right+zbs*2+zrs) return HTSCROLL_ZOOMOUT; + } + } + + //check for left button click + if(x >= rect->left && x < rect->left + butwidth) + { + return HTSCROLL_LEFT; + } + //check for right button click + else if(x >= rect->right-butwidth && x < rect->right) + { + return HTSCROLL_RIGHT; + } + + //if the thumb is too big to fit (i.e. it isn't visible) + //then return a NULL scrollbar area + if(thumbwidth >= workingwidth) + return HTSCROLL_NONE; + + //check for point in the thumbbar + if(x >= thumbpos && x < thumbpos+thumbwidth) + { + if(sw->resizingHthumb) + { + if(sbar->nBarType == SB_HORZ) //only for horizontal + { + if(x<=thumbpos+m_thumbsize) + return HTSCROLL_LRESIZER; + if(x>=(thumbpos+thumbwidth-m_thumbsize)) + return HTSCROLL_RRESIZER; + } + } + return HTSCROLL_THUMB; + } + //check for left margin + else if(x >= rect->left+butwidth && x < thumbpos) + { + return HTSCROLL_PAGELEFT; + } + else if(x >= thumbpos+thumbwidth && x < rect->right-butwidth) + { + return HTSCROLL_PAGERIGHT; + } + + return HTSCROLL_NONE; +} + +// +// For vertical scrollbars, rotate all coordinates by -90 degrees +// so that we can use the horizontal version of this function +// +static UINT GetVertScrollPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) +{ + UINT r; + + RotateRect(rect); + r = GetHorzScrollPortion(sb, hwnd, rect, y, x,hasZoomButtons); + RotateRect(rect); + return r; +} + + + +static void drawSkinThumb(HDC hdc, RECT r, int fBarHot, int pressed, int vert, const RECT *wndrect, SCROLLBAR *sb) +{ + LICE_IBitmap *bmp; + if(m_scrollbar_bmp && (bmp = *m_scrollbar_bmp)) + { + int w = r.right-r.left; + int h = r.bottom-r.top; + int startx = 0; + int starty = 187; + if(m_scrollbar_hasPink) starty = 37; + if(!vert) + { + static LICE_SysBitmap tmpbmp; + if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) + tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); + + //draw background first so alpha channel thumbs work + { + RECT bgr = {0,0,w,h}; + DrawCheckedRect(&tmpbmp,tmpbmp.getDC(), &bgr, 0, 0, sb, wndrect, 0, r.left); + } + + int st = (fBarHot?1:0) + (pressed?2:0); + int neww = w; + int part1 = 16, part2 = 10, part3 = 14, part4 = 10, part5 = 16; + if(m_scrollbar_hasPink) + { + part1 = m_sb_thumbHV[0]; part2 = m_sb_thumbHV[1]; part3 = m_sb_thumbHV[2]; part4 = m_sb_thumbHV[3]; part5 = m_sb_thumbHV[4]; + } + + double sc = h==16||h==17 ? 1.0 : h / 17.0; + + int part1_s = (int)(part1*sc+0.5); + int part3_s = (int)(part3*sc+0.5); + int part5_s = (int)(part5*sc+0.5); + int tl = part1_s+part3_s+part5_s; + if(wliceThumb || sb->liceThumb->getWidth()!=w || sb->liceThumb->getHeight()!=h || sb->liceThumbState!=st || sb->liceThumb_ver!=g_coolsb_imageVersion) + { + sb->liceThumb_ver=g_coolsb_imageVersion; + if(!sb->liceThumb) sb->liceThumb = new LICE_SysBitmap; + sb->liceThumb->resize(w, h); + sb->liceThumbState = st; + + if(fBarHot) starty += 17; + else if(pressed) starty += 17*2; + + int mid = (w-part3_s)/2; + LICE_ScaledBlit(sb->liceThumb, bmp, 0, 0, part1_s, h, startx, starty, part1, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, part1_s, 0, mid-part1_s, h, startx+part1, starty, part2, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, mid, 0, part3_s, h, startx+part1+part2, starty, part3, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, mid+part3_s, 0, w-(mid+part3_s)-part5, h, startx+part1+part2+part3, starty, part4, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, w-part5_s, 0, part5_s, h, startx+part1+part2+part3+part4, starty, part5, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + + } + + LICE_ScaledBlit(&tmpbmp, sb->liceThumb, 0, 0, neww, h, 0, 0, w, h, 1.0f, LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + BitBlt(hdc, r.left, r.top, neww, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + } + else + { + static LICE_SysBitmap tmpbmp; + if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) + tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); + starty = 116; + if(m_scrollbar_hasPink) starty = 91; + + //draw background first so alpha channel thumbs work + { + RECT bgr = {0,0,w,h}; + DrawCheckedRect(&tmpbmp,tmpbmp.getDC(), &bgr, 0, 0, sb, wndrect, 0, 0, r.top); + } + + int st = (fBarHot?1:0) + (pressed?2:0); + + int newh = h; + int part1 = 8, part2 = 16, part3 = 18, part4 = 16, part5 = 8; + if(m_scrollbar_hasPink) + { + part1 = m_sb_thumbVV[0]; part2 = m_sb_thumbVV[1]; part3 = m_sb_thumbVV[2]; part4 = m_sb_thumbVV[3]; part5 = m_sb_thumbVV[4]; + } + + double sc = w==16||w==17 ? 1.0 : w / 17.0; + + int part1_s = (int)(part1*sc+0.5); + int part3_s = (int)(part3*sc+0.5); + int part5_s = (int)(part5*sc+0.5); + int tl = part1_s+part3_s+part5_s; + if(hliceThumb || sb->liceThumb->getWidth()!=w || sb->liceThumb->getHeight()!=h || sb->liceThumbState!=st || sb->liceThumb_ver!=g_coolsb_imageVersion) + { + sb->liceThumb_ver = g_coolsb_imageVersion; + if(!sb->liceThumb) sb->liceThumb = new LICE_SysBitmap; + sb->liceThumb->resize(w, h); + + sb->liceThumbState = st; + + if(fBarHot) startx += 17; + else if(pressed) startx += 17*2; + + int mid = (h-part3)/2; + LICE_ScaledBlit(sb->liceThumb, bmp, 0, 0, w, part1_s, startx, starty, 17, part1, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, 0, part1_s, w, mid-part1_s, startx, starty+part1, 17, part2, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, 0, mid, w, part3_s, startx, starty+part1+part2, 17, part3, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, 0, mid+part3_s, w, h-(mid+part3_s)-part5_s, startx, starty+part1+part2+part3, 17, part4, 1.0f, LICE_BLIT_FILTER_BILINEAR); + LICE_ScaledBlit(sb->liceThumb, bmp, 0, h-part5_s, w, part5_s, startx, starty+part1+part2+part3+part4, 17, part5, 1.0f, LICE_BLIT_FILTER_BILINEAR); + } + + LICE_ScaledBlit(&tmpbmp, sb->liceThumb, 0, 0, w, newh, 0, 0, w, h, 1.0f, LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + BitBlt(hdc, r.left, r.top, w, newh, tmpbmp.getDC(), 0, 0, SRCCOPY); + } + } +} + + +// +// Draw a complete HORIZONTAL scrollbar in the given rectangle +// Don't draw any inserted buttons in this procedure +// +// uDrawFlags - hittest code, to say if to draw the +// specified portion in an active state or not. +// +// +static LRESULT NCDrawHScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) +{ + SCROLLINFO *si; + RECT ctrl, thumb; + RECT sbm; + int butwidth = GetScrollMetric(sb->nBarType == SB_VERT, SM_SCROLL_LENGTH); + int scrollwidth = rect->right-rect->left; + int workingwidth = scrollwidth - butwidth*2; + int thumbwidth = 0, thumbpos = 0; + int siMaxMin; + + BOOL fMouseDownL = 0, fMouseOverL = 0, fBarHot = 0; + BOOL fMouseDownR = 0, fMouseOverR = 0; + + COLORREF crCheck1 = GetSBForeColor(hwnd); + COLORREF crCheck2 = GetSBBackColor(hwnd); + COLORREF crInverse1 = InvertCOLORREF(crCheck1); + COLORREF crInverse2 = InvertCOLORREF(crCheck2); + + //drawing flags to modify the appearance of the scrollbar buttons + UINT uLeftButFlags = DFCS_SCROLLLEFT; + UINT uRightButFlags = DFCS_SCROLLRIGHT; + + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + + if(scrollwidth <= 0) + return 0; + + si = &sb->scrollInfo; + siMaxMin = si->nMax - si->nMin; + + int sbYoffs=0,sbXoffs=0; +#ifdef _WIN32 + // this is a stupid fix for now . this needs a ton of overhauling + { + RECT r; + POINT p={0,0}; + ClientToScreen(hwnd,&p); + GetWindowRect(hwnd,&r); + + if (sb == &sw->sbarVert) sbYoffs = r.top - p.y; + if (sb == &sw->sbarHorz) sbXoffs = r.left - p.x; + } +#endif + + + if(hwnd != hwndCurCoolSB) + uDrawFlags = HTSCROLL_NONE; + // + // work out the thumb size and position + // + CalcThumbSize(sb, rect, &thumbwidth, &thumbpos); + + if(sb->fScrollFlags & ESB_DISABLE_LEFT) uLeftButFlags |= DFCS_INACTIVE; + if(sb->fScrollFlags & ESB_DISABLE_RIGHT) uRightButFlags |= DFCS_INACTIVE; + + //if we need to grey the arrows because there is no data to scroll + if(!IsScrollInfoActive(si) && !(sb->fScrollFlags & CSBS_THUMBALWAYS)) + { + uLeftButFlags |= DFCS_INACTIVE; + uRightButFlags |= DFCS_INACTIVE; + } + + if(hwnd == hwndCurCoolSB) + { + fMouseDownL = (uDrawFlags == HTSCROLL_LEFT); + fMouseDownR = (uDrawFlags == HTSCROLL_RIGHT); + } + + + int fMouseOverPlus, fMouseOverMinus; + { + BOOL ldis = !(uLeftButFlags & DFCS_INACTIVE); + BOOL rdis = !(uRightButFlags & DFCS_INACTIVE); + + fBarHot = sb->nBarType == (int)sw->uMouseOverScrollbar; + + fMouseOverL = sw->uHitTestPortion == HTSCROLL_LEFT && fBarHot && ldis; + fMouseOverR = sw->uHitTestPortion == HTSCROLL_RIGHT && fBarHot && rdis; + fMouseOverPlus = sw->uHitTestPortion == HTSCROLL_ZOOMIN && fBarHot && ldis; + fMouseOverMinus = sw->uHitTestPortion == HTSCROLL_ZOOMOUT && fBarHot && ldis; + } + + // + // Draw the scrollbar now + // + if(scrollwidth > butwidth*2) + { + //LEFT ARROW + SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom); + + RotateRect0(sb, &ctrl); + + DrawScrollArrow(hwnd,sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL); + + RotateRect0(sb, &ctrl); + + //MIDDLE PORTION + //if we can fit the thumbbar in, then draw it + if(thumbwidth > 0 && thumbwidth <= workingwidth + && IsScrollInfoActive(si) && ((sb->fScrollFlags & ESB_DISABLE_BOTH) != ESB_DISABLE_BOTH)) + { + //Draw the scrollbar margin above the thumb + SetRect(&sbm, rect->left + butwidth, rect->top, thumbpos, rect->bottom); + + RotateRect0(sb, &sbm); + + if(uDrawFlags == HTSCROLL_PAGELEFT) + DrawCheckedRect(NULL,hdc, &sbm, crInverse1, crInverse2, sb, rect, 1,sbXoffs,sbYoffs); + else + DrawCheckedRect(NULL,hdc, &sbm, crCheck1, crCheck2, sb, rect, 0,sbXoffs,sbYoffs); + + RotateRect0(sb, &sbm); + + //Draw the margin below the thumb + sbm.left = thumbpos+thumbwidth; + sbm.right = rect->right - butwidth; + + RotateRect0(sb, &sbm); + if(uDrawFlags == HTSCROLL_PAGERIGHT) + DrawCheckedRect(NULL,hdc, &sbm, crInverse1, crInverse2, sb, rect, 1,sbXoffs,sbYoffs); + else + DrawCheckedRect(NULL,hdc, &sbm, crCheck1, crCheck2, sb, rect, 0,sbXoffs,sbYoffs); + RotateRect0(sb, &sbm); + + //Draw the THUMB finally + SetRect(&thumb, thumbpos, rect->top, thumbpos+thumbwidth, rect->bottom); + + RotateRect0(sb, &thumb); + + if(m_scrollbar_bmp && *m_scrollbar_bmp) + { + drawSkinThumb(hdc, thumb, sw->uHitTestPortion == HTSCROLL_THUMB, 0, sb->nBarType == SB_VERT, rect, sb); + } + else + { + //no skinning + + { + RECT r = thumb; + if(sw->resizingHthumb) + { + if(sb->nBarType == SB_HORZ) + { + r.left += m_thumbsize; + r.right -= m_thumbsize; + } + else + { + //disabled for now + /*r.top += m_thumbsize; + r.bottom -= m_thumbsize;*/ + } + } + DrawBlankButton(hwnd,hdc, &r); + } + + if(sw->resizingHthumb) + { + //draw left and right resizers + if(sb->nBarType == SB_HORZ) + { + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + { + RECT r={thumb.left, thumb.top, thumb.left+m_thumbsize, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + { + RECT r={thumb.right-m_thumbsize, thumb.top, thumb.right, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + DeleteObject(br); + } + else + { + //disabled for now + /*HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + { + RECT r={thumb.left, thumb.top, thumb.right, thumb.top+m_thumbsize}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + { + RECT r={thumb.left, thumb.bottom - m_thumbsizeE, thumb.right, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + DeleteObject(br);*/ + } + } + } + RotateRect0(sb, &thumb); + + } + //otherwise, just leave that whole area blank + else + { + OffsetRect(&ctrl, butwidth, 0); + ctrl.right = rect->right - butwidth; + + //if we always show the thumb covering the whole scrollbar, + //then draw it that way + if(!IsScrollInfoActive(si) && (sb->fScrollFlags & CSBS_THUMBALWAYS) + && ctrl.right - ctrl.left > sb->nMinThumbSize) + { + //leave a 1-pixel gap between the thumb + right button + ctrl.right --; + RotateRect0(sb, &ctrl); + + DrawBlankButton(hwnd,hdc, &ctrl); + + RotateRect0(sb, &ctrl); + + //draw the single-line gap + ctrl.left = ctrl.right; + ctrl.right += 1; + + RECT r2 = ctrl; + r2.right -= 1; + RotateRect0(sb, &ctrl); + RotateRect0(sb, &r2); + + PaintRect(hdc, &r2, CoolSB_GetSysColor(hwnd,COLOR_SCROLLBAR)); + + RotateRect0(sb, &ctrl); + } + //otherwise, paint a blank if the thumb doesn't fit in + else + { + RotateRect0(sb, &ctrl); + + DrawCheckedRect(NULL,hdc, &ctrl, crCheck1, crCheck2, sb, rect, 0, sbXoffs,sbYoffs); + + RotateRect0(sb, &ctrl); + } + } + + //RIGHT ARROW + SetRect(&ctrl, rect->right - butwidth, rect->top, rect->right, rect->bottom); + + RECT r2 = ctrl; + // r2.right -= 1; + RotateRect0(sb, &ctrl); + RotateRect0(sb, &r2); + + DrawScrollArrow(hwnd,sb, hdc, &r2, uRightButFlags, fMouseDownR, fMouseOverR); + + if(sw->resizingHthumb && hasZoomButtons) + { + //zoom/resize buttons + { + SetBkMode(hdc, TRANSPARENT); + if(sb->nBarType == SB_HORZ) + { + int zbs = GetZoomButtonSize(FALSE); + if(m_scrollbar_bmp && *m_scrollbar_bmp) + { + LICE_IBitmap *bmp = *m_scrollbar_bmp; + static LICE_SysBitmap tmpbmp; + + int w = zbs; + int h = ctrl.bottom-ctrl.top; + int startx = 116; + int starty = 201; + if(fMouseOverPlus) startx += 17; + if(uDrawFlags == HTSCROLL_ZOOMIN) startx = 116+17+17; + if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) + tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + + BitBlt(hdc, ctrl.right, ctrl.top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, ZOOMBUTTON_RESIZER_SIZE(zbs), h, 163, 101, 4, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + BitBlt(hdc, ctrl.right+zbs, ctrl.top, ZOOMBUTTON_RESIZER_SIZE(zbs), h, tmpbmp.getDC(), 0, 0, SRCCOPY); + + startx = 116; + starty = 221; + if(fMouseOverMinus) startx += 17; + if(uDrawFlags == HTSCROLL_ZOOMOUT) startx = 116+17+17; + + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + BitBlt(hdc, ctrl.right+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.top, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + } + else + { + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + HPEN pen=CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); + HGDIOBJ oldPen=SelectObject(hdc,pen); + // + + { + int pressed = (uDrawFlags == HTSCROLL_ZOOMIN); + RECT r = {ctrl.right+pressed, ctrl.top+pressed, ctrl.right + zbs, ctrl.bottom}; + ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + + + int cy=(ctrl.top+ctrl.bottom)/2+pressed, + cx=ctrl.right+zbs/2+pressed; + int sz=min(14,ctrl.bottom-ctrl.top)/4; + + MoveToEx(hdc,cx-sz,cy,NULL); + LineTo(hdc,cx+sz+1,cy); + MoveToEx(hdc,cx,cy-sz,NULL); + LineTo(hdc,cx,cy+sz+1); + } + // resize thumb + { + RECT r = {ctrl.right + zbs, ctrl.top, ctrl.right + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + // - + { + int pressed = (uDrawFlags == HTSCROLL_ZOOMOUT); + RECT r = {ctrl.right + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs) +pressed, ctrl.top+pressed, + ctrl.right + zbs*2 + ZOOMBUTTON_RESIZER_SIZE(zbs), ctrl.bottom}; + ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + int cy=(ctrl.top+ctrl.bottom)/2+pressed, + cx=ctrl.right+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs)+zbs/2+pressed; + int sz=min(14,ctrl.bottom-ctrl.top)/4; + + MoveToEx(hdc,cx-sz,cy,NULL); + LineTo(hdc,cx+sz+1,cy); + } + SelectObject(hdc,oldPen); + DeleteObject(pen); + DeleteObject(br); + } + } + else + { + int zbs = GetZoomButtonSize(TRUE); + if(m_scrollbar_bmp && *m_scrollbar_bmp) + { + LICE_IBitmap *bmp = *m_scrollbar_bmp; + static LICE_SysBitmap tmpbmp; + int w = ctrl.right - ctrl.left; + int h = zbs; + int startx = 116; + int starty = 201; + if(fMouseOverPlus) startx += 17; + if(uDrawFlags == HTSCROLL_ZOOMIN) startx = 116+17+17; + if (w>tmpbmp.getWidth() || h>tmpbmp.getHeight()) + tmpbmp.resize(max(w,tmpbmp.getWidth()), max(h,tmpbmp.getHeight())); + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + BitBlt(hdc, ctrl.left, ctrl.bottom, w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, ZOOMBUTTON_RESIZER_SIZE(zbs), 143, 114, 17, 4, 1.0f, LICE_BLIT_FILTER_BILINEAR); + BitBlt(hdc, ctrl.left, ctrl.bottom+zbs, w, ZOOMBUTTON_RESIZER_SIZE(zbs), tmpbmp.getDC(), 0, 0, SRCCOPY); + + startx = 116; + starty = 221; + if(fMouseOverMinus) startx += 17; + if(uDrawFlags == HTSCROLL_ZOOMOUT) startx = 116+17+17; + + LICE_ScaledBlit(&tmpbmp, bmp, 0, 0, w, h, startx, starty, 17, 17, 1.0f, LICE_BLIT_FILTER_BILINEAR); + BitBlt(hdc, ctrl.left, ctrl.bottom+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs), w, h, tmpbmp.getDC(), 0, 0, SRCCOPY); + } + else + { + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + HPEN pen=CreatePen(PS_SOLID, 0, CoolSB_GetSysColor(hwnd,COLOR_3DDKSHADOW)); + HGDIOBJ oldPen=SelectObject(hdc,pen); + // + + { + int pressed = (uDrawFlags == HTSCROLL_ZOOMIN); + RECT r = {ctrl.left+pressed, ctrl.bottom+pressed, ctrl.right, ctrl.bottom + zbs}; + ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + + int cx=(ctrl.left+ctrl.right)/2+pressed,cy=ctrl.bottom+zbs/2+pressed; + int sz=min(14,ctrl.right-ctrl.left)/4; + + MoveToEx(hdc,cx-sz,cy,NULL); + LineTo(hdc,cx+sz+1,cy); + MoveToEx(hdc,cx,cy-sz,NULL); + LineTo(hdc,cx,cy+sz+1); + } + // resize thumb + { + RECT r = {ctrl.left, ctrl.bottom + zbs, ctrl.right, ctrl.bottom + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs)}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + // - + { + int pressed = (uDrawFlags == HTSCROLL_ZOOMOUT); + RECT r = {ctrl.left+pressed, ctrl.bottom + zbs + ZOOMBUTTON_RESIZER_SIZE(zbs) + pressed, + ctrl.right, ctrl.bottom + ZOOMBUTTON_RESIZER_SIZE(zbs) + zbs*2}; + ownDrawEdge(hwnd,hdc, &r, pressed?0:EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + + int cx=(ctrl.left+ctrl.right)/2+pressed,cy=ctrl.bottom+zbs+ZOOMBUTTON_RESIZER_SIZE(zbs)+zbs/2+pressed; + int sz=min(14,ctrl.right-ctrl.left)/4; + + MoveToEx(hdc,cx-sz,cy,NULL); + LineTo(hdc,cx+sz+1,cy); + } + SelectObject(hdc,oldPen); + DeleteObject(pen); + DeleteObject(br); + } + } + } + } + RotateRect0(sb, &ctrl); + } + //not enough room for the scrollbar, so just draw the buttons (scaled in size to fit) + else + { + butwidth = scrollwidth / 2; + + //LEFT ARROW + SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom); + + RotateRect0(sb, &ctrl); + DrawScrollArrow(hwnd,sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL); + RotateRect0(sb, &ctrl); + + //RIGHT ARROW + OffsetRect(&ctrl, scrollwidth - butwidth, 0); + + RotateRect0(sb, &ctrl); + DrawScrollArrow(hwnd,sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR); + RotateRect0(sb, &ctrl); + + //if there is a gap between the buttons, fill it with a solid color + //if(butwidth & 0x0001) + if(ctrl.left != rect->left + butwidth) + { + ctrl.left --; + ctrl.right -= butwidth; + RotateRect0(sb, &ctrl); + + DrawCheckedRect(NULL,hdc, &ctrl, crCheck1, crCheck2, sb, rect, 0, sbXoffs, sbYoffs); + + RotateRect0(sb, &ctrl); + } + + } + + return FALSE; +} + +// +// Draw a vertical scrollbar using the horizontal draw routine, but +// with the coordinates adjusted accordingly +// +static LRESULT NCDrawVScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) +{ + LRESULT ret; + RECT rc; + + rc = *rect; + RotateRect(&rc); + ret = NCDrawHScrollbar(sb, hwnd, hdc, &rc, uDrawFlags,hasZoomButtons); + RotateRect(&rc); + + return ret; +} + +// +// Generic wrapper function for the scrollbar drawing +// +static LRESULT NCDrawScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, BOOL hasZoomButtons) +{ + if(sb->nBarType == SB_HORZ) + return NCDrawHScrollbar(sb, hwnd, hdc, rect, uDrawFlags,hasZoomButtons); + else + return NCDrawVScrollbar(sb, hwnd, hdc, rect, uDrawFlags,hasZoomButtons); +} + + + +static int getPink(int x, int y, int vert, int np=0, int add=1) +{ + LICE_IBitmap *bmp; + if(!m_scrollbar_bmp || !(bmp = *m_scrollbar_bmp)) return 0; + + int w = bmp->getWidth(); + int h = bmp->getHeight(); + int rs=bmp->getRowSpan(); + LICE_pixel *p = bmp->getBits(); + if(x>=w || y>=h) return 0; + p += rs * y + x; + if(!vert) + { + int l; + for(l=0;;l++) + { + if(np && *p==LICE_RGBA(255,0,255,255)) break; + if(!np && *p!=LICE_RGBA(255,0,255,255)) break; + p += add; + x += add; + if(x>=w || x<0) break; + } + return l; + } + + int l; + for(l=0;;l++) + { + if(np && *p==LICE_RGBA(255,0,255,255)) break; + if(!np && *p!=LICE_RGBA(255,0,255,255)) break; + p += rs*add; + y += add; + if(y>=h || y<0) break; + } + return l; +} + +static void initLiceBmp() +{ + m_scrollbar_bmp = (LICE_IBitmap **)GetIconThemePointer("scrollbar"); + if(!m_scrollbar_bmp) return; + + m_scrollbar_hasPink = getPink(0,35,0)>0; + if(m_scrollbar_hasPink) + { + LICE_IBitmap *bmp = *m_scrollbar_bmp; + memset(&m_sb_thumbHV, 0, sizeof(m_sb_thumbHV)); + memset(&m_sb_thumbVV, 0, sizeof(m_sb_thumbVV)); + int w = bmp->getWidth(); + int h = bmp->getHeight(); + { + int l = getPink(0,89,0); + m_sb_thumbHV[0] = l; + int x = l; + l = getPink(x, 89, 0, 1); + m_sb_thumbHV[1] = l; + x += l; + l = getPink(x, 89, 0); + m_sb_thumbHV[2] = l; + x += l; + l = getPink(x, 89, 0, 1); + m_sb_thumbHV[3] = l; + x += l; + l = getPink(x, 89, 0); + m_sb_thumbHV[4] = l; + + int y = 91; + l = getPink(52, y, 1); + m_sb_thumbVV[0] = l; + y += l; + l = getPink(52, y, 1, 1); + m_sb_thumbVV[1] = l; + y += l; + l = getPink(52, y, 1); + m_sb_thumbVV[2] = l; + y += l; + l = getPink(52, y, 1, 1); + m_sb_thumbVV[3] = l; + y += l; + l = getPink(52, y, 1); + m_sb_thumbVV[4] = l; + + m_sb_bkghl = getPink(0, 35, 0); + m_sb_bkghr = getPink(203, 35, 0, 0, -1); + + m_sb_bkgvt = getPink(168, 37, 1); + m_sb_bkgvb = getPink(168, 237, 1, 0, -1); + } + } +} + +static LRESULT NCPaint(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam, HDC hdcParam=NULL) +{ + SCROLLBAR *sb; + HDC hdc; + HRGN hrgn; + RECT winrect, rect; + HRGN clip; + BOOL fUpdateAll = (wParam == 1); + UINT ret; + + if(!m_scrollbar_bmp) + { + initLiceBmp(); + } + + GET_WINDOW_RECT(hwnd, &winrect); + + //if entire region needs painting, then make a region to cover the entire window +/* if(fUpdateAll) + hrgn = (HRGN)wParam; + else + */ + hrgn = (HRGN)wParam; + + //hdc = GetWindowDC(hwnd); + if(hdcParam != NULL) + hdc = hdcParam; + else + hdc = GetWindowDC(hwnd); + +// printf("wndrect: %d,%d,%d,%d hdc=%d hv=%d\n",winrect.left,winrect.top,winrect.right,winrect.bottom,hdc,sw->sbarHorz.fScrollVisible); + + // + // Only draw the horizontal scrollbar if the window is tall enough + // + sb = &sw->sbarHorz; + if(sb->fScrollVisible) + { + int hbarwidth = 0, leftright = 0; + + //get the screen coordinates of the whole horizontal scrollbar area + BOOL hasZoomButtons; + GetHScrollRect(sw, hwnd, &rect, &hasZoomButtons); + + //make the coordinates relative to the window for drawing + OffsetRect(&rect, -winrect.left, -winrect.top); + + + if(sw->uCurrentScrollbar == SB_HORZ) + NCDrawHScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); + else + NCDrawHScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); + } + + // + // Only draw the vertical scrollbar if the window is wide enough to accomodate it + // + sb = &sw->sbarVert; + if(sb->fScrollVisible) + { + int vbarheight = 0, updown = 0; + + //get the screen cooridinates of the whole horizontal scrollbar area + BOOL hasZoomButtons; + GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); + + //make the coordinates relative to the window for drawing + OffsetRect(&rect, -winrect.left, -winrect.top); + + + if(sw->uCurrentScrollbar == SB_VERT) + { + NCDrawVScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); + } + else + NCDrawVScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); + } + + //Call the default window procedure for WM_NCPAINT, with the + //new window region. ** region must be in SCREEN coordinates ** + + // If the window has WS_(H-V)SCROLL bits set, we should reset them + // to avoid windows taking the scrollbars into account. + // We temporarily set a flag preventing the subsecuent + // WM_STYLECHANGING/WM_STYLECHANGED to be forwarded to + // the original window procedure + + ret = CallWindowProcStyleMod(sw, hwnd, WM_NCPAINT, (WPARAM)hrgn, lParam); + + + + + // DRAW THE DEAD AREA + // only do this if the horizontal and vertical bars are visible + if(sw->sbarHorz.fScrollVisible && sw->sbarVert.fScrollVisible) + { + GET_WINDOW_RECT(hwnd, &rect); + OffsetRect(&rect, -winrect.left, -winrect.top); + + rect.bottom -= sw->cyBottomEdge; + rect.top = rect.bottom - GetScrollMetric(FALSE, SM_CYHORZSB); + + if(sw->fLeftScrollbar) + { + rect.left += sw->cxLeftEdge; + rect.right = rect.left + GetScrollMetric(TRUE, SM_CXVERTSB); + } + else + { + rect.right -= sw->cxRightEdge; + rect.left = rect.right - GetScrollMetric(TRUE, SM_CXVERTSB); + } + + { + //calculate the position of THIS window's dead area + //with the position of the PARENT window's client rectangle. + //if THIS window has been positioned such that its bottom-right + //corner sits in the parent's bottom-right corner, then we should + //show the sizing-grip. + //Otherwise, assume this window is not in the right place, and + //just draw a blank rectangle + RECT parent; + RECT rect2; + HWND hwndParent = GetParent(hwnd); + + GetClientRect(hwndParent, &parent); + //MapWindowPoints(hwndParent, 0, (POINT *)&parent, 2); + ClientToScreen(hwndParent, (LPPOINT)&parent); + ClientToScreen(hwndParent, ((LPPOINT)&parent)+1); + if (parent.bottomfLeftScrollbar && parent.right == rect2.right+sw->cxRightEdge && parent.bottom == rect2.bottom+sw->cyBottomEdge + || sw->fLeftScrollbar && parent.left == rect2.left -sw->cxLeftEdge && parent.bottom == rect2.bottom+sw->cyBottomEdge) + ownDrawFrameControl(hwnd,hdc, &rect, DFC_SCROLL, sw->fLeftScrollbar ? DFCS_SCROLLSIZEGRIPRIGHT : DFCS_SCROLLSIZEGRIP, 0 ); + else +#endif + PaintRect(hdc, &rect, CoolSB_GetSysColor(hwnd,COLOR_3DFACE)); + } + } + + UNREFERENCED_PARAMETER(clip); + + if(!hdcParam) ReleaseDC(hwnd, hdc); + return ret; +} + +// +// Need to detect if we have clicked in the scrollbar region or not +// +static LRESULT NCHitTest(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + RECT hrect; + RECT vrect; + POINT pt; + + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + OSX_REMAP_SCREENY(hwnd,&pt.y); + + //work out exactly where the Horizontal and Vertical scrollbars are + BOOL hasZoomButtons; + GetHScrollRect(sw, hwnd, &hrect, &hasZoomButtons); + if (hasZoomButtons && sw->resizingHthumb) + { + int zbs = GetZoomButtonSize(FALSE); + hrect.right += zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); + } + GetVScrollRect(sw, hwnd, &vrect,&hasZoomButtons); + if (hasZoomButtons && sw->resizingHthumb) + { + int zbs = GetZoomButtonSize(TRUE); + vrect.bottom += zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); + } + +#ifndef _WIN32 + if (sw->sbarHorz.fScrollVisible || sw->sbarVert.fScrollVisible) + { + int sz=sw->sbarHorz.fScrollVisible ? hrect.bottom-hrect.top : vrect.right-vrect.left; + if (sz<0)sz=-sz; + RECT r; + GetWindowRect(hwnd,&r); + int bot = max(r.top,r.bottom); + int v= (bot-pt.y) + (r.right-pt.x); + if (v < sz*3/4) return HTNOWHERE; + } +#endif + + + //Clicked in the horizontal scrollbar area + if(sw->sbarHorz.fScrollVisible && PtInRect(&hrect, pt)) + { + return HTHSCROLL; + } + //Clicked in the vertical scrollbar area + else if(sw->sbarVert.fScrollVisible && PtInRect(&vrect, pt)) + { + + return HTVSCROLL; + } +#ifndef _WIN32 + else if (sw->sbarHorz.fScrollVisible && sw->sbarVert.fScrollVisible && pt.y >= hrect.top && pt.y <= hrect.bottom && pt.x >= vrect.left && pt.x <= vrect.right) + { + return HTNOWHERE; + } +#endif + //clicked somewhere else + else + { + return CallWindowProc(sw->oldproc, hwnd, WM_NCHITTEST, wParam, lParam); + } +} + +// +// Return a HT* value indicating what part of the scrollbar was clicked +// Rectangle is not adjusted +// +static UINT GetHorzPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) +{ + RECT rc = *rect; + + if(y < rc.top || y >= rc.bottom) return HTSCROLL_NONE; + + + //Now we have the rectangle for the scrollbar itself, so work out + //what part we clicked on. + return GetHorzScrollPortion(sb, hwnd, &rc, x, y,hasZoomButtons); +} + +// +// Just call the horizontal version, with adjusted coordinates +// +static UINT GetVertPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) +{ + UINT ret; + RotateRect(rect); + ret = GetHorzPortion(sb, hwnd, rect, y, x,hasZoomButtons); + RotateRect(rect); + return ret; +} + +// +// Wrapper function for GetHorzPortion and GetVertPortion +// +static UINT GetPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, BOOL hasZoomButtons) +{ + if(sb->nBarType == SB_HORZ) + return GetHorzPortion(sb, hwnd, rect, x, y,hasZoomButtons); + else if(sb->nBarType == SB_VERT) + return GetVertPortion(sb, hwnd, rect, x, y,hasZoomButtons); + else + return HTSCROLL_NONE; +} + + +// +// Left button click in the non-client area +// +static LRESULT NCLButtonDown(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL isDouble) +{ + RECT rect, winrect; + HDC hdc; + SCROLLBAR *sb; + POINT pt; + + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + OSX_REMAP_SCREENY(hwnd,&pt.y); + + hwndCurCoolSB = hwnd; + + // + // HORIZONTAL SCROLLBAR PROCESSING + // + BOOL hasZoomButtons; + if(wParam == HTHSCROLL) + { + sw->uScrollTimerMsg = WM_HSCROLL; + sw->uCurrentScrollbar = SB_HORZ; + sb = &sw->sbarHorz; + + //get the total area of the normal Horz scrollbar area + GetHScrollRect(sw, hwnd, &rect,&hasZoomButtons); + sw->uCurrentScrollPortion = GetHorzPortion(sb, hwnd, &rect, pt.x,pt.y,hasZoomButtons); + } + // + // VERTICAL SCROLLBAR PROCESSING + // + else if(wParam == HTVSCROLL) + { + sw->uScrollTimerMsg = WM_VSCROLL; + sw->uCurrentScrollbar = SB_VERT; + sb = &sw->sbarVert; + + //get the total area of the normal Horz scrollbar area + GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); + sw->uCurrentScrollPortion = GetVertPortion(sb, hwnd, &rect, pt.x,pt.y,hasZoomButtons); + } + // + // NORMAL PROCESSING + // + else + { + sw->uCurrentScrollPortion = HTSCROLL_NONE; + return CallWindowProc(sw->oldproc, hwnd, WM_NCLBUTTONDOWN, wParam, lParam); + } + + // + // we can now share the same code for vertical + // and horizontal scrollbars + // + switch(sw->uCurrentScrollPortion) + { + //inserted buttons to the left/right + + case HTSCROLL_THUMB: + + //if the scrollbar is disabled, then do no further processing + if(!IsScrollbarActive(sb)) + return 0; + + if (isDouble) + { + SendMessage(hwnd,WM_SB_DBLCLK,wParam == HTVSCROLL ? SB_VERT : SB_HORZ,0); + } + else + { + + RotateRect0(sb, &rect); + CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); + RotateRect0(sb, &rect); + + //remember the bounding rectangle of the scrollbar work area + rcThumbBounds = rect; + + sw->fThumbTracking = TRUE; + sb->scrollInfo.nTrackPos = sb->scrollInfo.nPos; + + if(wParam == HTVSCROLL) + nThumbMouseOffset = pt.y - nThumbPos; + else + nThumbMouseOffset = pt.x - nThumbPos; + + nLastPos = sb->scrollInfo.nPos; + nThumbPos0 = nThumbPos; + +#if 0 + //if(sb->fFlatScrollbar) + //{ + GetWindowRect(hwnd, &winrect); + FIXWINDOWRECT(&winrect); + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_THUMB); + ReleaseDC(hwnd, hdc); + //} +#endif + + MouseMove(sw, hwnd, 0, 0); + } + + break; + + //Any part of the scrollbar + case HTSCROLL_LEFT: + if(sb->fScrollFlags & ESB_DISABLE_LEFT) return 0; + else goto target1; + + case HTSCROLL_RIGHT: + if(sb->fScrollFlags & ESB_DISABLE_RIGHT) return 0; + else goto target1; + + goto target1; + + case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: + + target1: + + //if the scrollbar is disabled, then do no further processing + if(!IsScrollbarActive(sb)) + break; + + //ajust the horizontal rectangle to NOT include + //any inserted buttons + + SendScrollMessage(hwnd, sw->uScrollTimerMsg, sw->uCurrentScrollPortion, 0); + + // Check what area the mouse is now over : + // If the scroll thumb has moved under the mouse in response to + // a call to SetScrollPos etc, then we don't hilight the scrollbar margin + if(sw->uCurrentScrollbar == SB_HORZ) + sw->uScrollTimerPortion = GetHorzScrollPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); + else + sw->uScrollTimerPortion = GetVertScrollPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); + + GET_WINDOW_RECT(hwnd, &winrect); + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + + NCDrawScrollbar(sb, hwnd, hdc, &rect, sw->uScrollTimerPortion,hasZoomButtons); + ReleaseDC(hwnd, hdc); + + //Post the scroll message!!!! + sw->uScrollTimerPortion = sw->uCurrentScrollPortion; + + //set a timer going on the first click. + //if this one expires, then we can start off a more regular timer + //to generate the auto-scroll behaviour + sw->uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID1, COOLSB_TIMERINTERVAL1, 0); + break; + case HTSCROLL_LRESIZER: + case HTSCROLL_RRESIZER: + if(wParam == HTVSCROLL) + nThumbMouseOffset = pt.y - nThumbPos; + else + nThumbMouseOffset = pt.x; + if(wParam == HTHSCROLL) + { + RECT rect; + int nThumbSize, nThumbPos; + GetHScrollRect(sw, hwnd, &rect,NULL); + CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); + SendMessage(hwnd, WM_SB_TRESIZE_START, nThumbSize, nThumbPos); + } + else + { + RECT rect; + int nThumbSize, nThumbPos; + GetVScrollRect(sw, hwnd, &rect,NULL); + RotateRect0(sb, &rect); + CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); + SendMessage(hwnd, WM_SB_TRESIZE_START, nThumbSize, nThumbPos); + } + break; + case HTSCROLL_RESIZER: + if(wParam == HTVSCROLL) + nThumbMouseOffset = pt.y; + else + nThumbMouseOffset = pt.x; + break; + case HTSCROLL_ZOOMIN: + SendMessage(hwnd, WM_SB_ZOOM, 0, (wParam == HTVSCROLL)); + if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); + sw->uZoomTimerId=SetTimer(hwnd,COOLSB_TIMERID4,COOLSB_TIMERINTERVAL4,NULL); + sw->uZoomTimerMode=wParam == HTVSCROLL; + sw->uScrollTimerPortion = HTSCROLL_ZOOMIN; + { + GET_WINDOW_RECT(hwnd, &winrect); + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_ZOOMIN,hasZoomButtons); + ReleaseDC(hwnd, hdc); + } + break; + case HTSCROLL_ZOOMOUT: + SendMessage(hwnd, WM_SB_ZOOM, 1, (wParam == HTVSCROLL)); + if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); + sw->uZoomTimerId=SetTimer(hwnd,COOLSB_TIMERID4,COOLSB_TIMERINTERVAL4,NULL); + sw->uZoomTimerMode=2 + (wParam == HTVSCROLL); + sw->uScrollTimerPortion = HTSCROLL_ZOOMOUT; + { + GET_WINDOW_RECT(hwnd, &winrect); + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_ZOOMOUT,hasZoomButtons); + ReleaseDC(hwnd, hdc); + } + break; + default: + return CallWindowProc(sw->oldproc, hwnd, WM_NCLBUTTONDOWN, wParam, lParam); + //return 0; + } + + SetCapture(hwnd); + return 0; +} + +// +// Left button released +// +static LRESULT LButtonUp(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + RECT rect; + //UINT thisportion; + HDC hdc; + POINT pt; + RECT winrect; + UINT buttonIdx = 0; + + if (sw->uZoomTimerId) KillTimer(hwnd,sw->uZoomTimerId); + sw->uZoomTimerId=0; + + //current scrollportion is the button that we clicked down on + if(sw->uCurrentScrollPortion != HTSCROLL_NONE) + { + SCROLLBAR *sb = &sw->sbarHorz; + lParam = GetMessagePos(); + ReleaseCapture(); +#ifndef _WIN32 + SetCursor(LoadCursor(NULL,IDC_ARROW)); // OS X seems to like this +#endif + GET_WINDOW_RECT(hwnd, &winrect); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + OSX_REMAP_SCREENY(hwnd,&pt.y); + BOOL hasZoomButtons=0; + + + //emulate the mouse input on a scrollbar here... + if(sw->uCurrentScrollbar == SB_HORZ) + { + //get the total area of the normal Horz scrollbar area + sb = &sw->sbarHorz; + GetHScrollRect(sw, hwnd, &rect,&hasZoomButtons); + } + else if(sw->uCurrentScrollbar == SB_VERT) + { + //get the total area of the normal Horz scrollbar area + sb = &sw->sbarVert; + GetVScrollRect(sw, hwnd, &rect,&hasZoomButtons); + } + + //we need to do different things depending on if the + //user is activating the scrollbar itself, or one of + //the inserted buttons + switch(sw->uCurrentScrollPortion) + { + + //The scrollbar is active + case HTSCROLL_LEFT: case HTSCROLL_RIGHT: + case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: + case HTSCROLL_NONE: + case HTSCROLL_ZOOMIN: + case HTSCROLL_ZOOMOUT: + + KillTimer(hwnd, sw->uScrollTimerId); + + case HTSCROLL_THUMB: + + //In case we were thumb tracking, make sure we stop NOW + if(sw->fThumbTracking == TRUE) + { + SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_THUMBPOSITION, nLastPos); + sw->fThumbTracking = FALSE; + } + + //send the SB_ENDSCROLL message now that scrolling has finished + SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_ENDSCROLL, 0); + + //adjust the total scroll area to become where the scrollbar + //really is (take into account the inserted buttons) + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + + //draw whichever scrollbar sb is + NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NORMAL,hasZoomButtons); + + ReleaseDC(hwnd, hdc); + break; + } + + //reset our state to default + sw->uCurrentScrollPortion = HTSCROLL_NONE; + sw->uScrollTimerPortion = HTSCROLL_NONE; + sw->uScrollTimerId = 0; + + sw->uScrollTimerMsg = 0; + sw->uCurrentScrollbar = COOLSB_NONE; + + return 0; + } + else + { + /* + // Can't remember why I did this! + if(GetCapture() == hwnd) + { + ReleaseCapture(); + }*/ + } + + return CallWindowProc(sw->oldproc, hwnd, WM_LBUTTONUP, wParam, lParam); +} + +// +// This function is called whenever the mouse is moved and +// we are dragging the scrollbar thumb about. +// +static LRESULT ThumbTrackHorz(SCROLLBAR *sbar, HWND hwnd, int x, int y) +{ + POINT pt; + RECT rc, winrect, rc2; + COLORREF crCheck1 = GetSBForeColor(hwnd); + COLORREF crCheck2 = GetSBBackColor(hwnd); + HDC hdc; + int thumbpos = nThumbPos; + int pos; + int siMaxMin = 0; + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + + SCROLLINFO *si; + si = &sbar->scrollInfo; + + pt.x = x; + pt.y = y; + + + int sbYoffs=0,sbXoffs=0; +#ifdef _WIN32 + // this is a stupid fix for now . this needs a ton of overhauling + { + RECT r; + POINT p={0,0}; + ClientToScreen(hwnd,&p); + GetWindowRect(hwnd,&r); + + if (sbar == &sw->sbarVert) sbYoffs = r.top - p.y; + if (sbar == &sw->sbarHorz) sbXoffs = r.left - p.x; + } +#endif + + //draw the thumb at whatever position + rc = rcThumbBounds; + +#define THUMBTRACK_SNAPDIST 24 + + SetRect(&rc2, rc.left - THUMBTRACK_SNAPDIST*2, rc.top - THUMBTRACK_SNAPDIST, + rc.right + THUMBTRACK_SNAPDIST*2, rc.bottom + THUMBTRACK_SNAPDIST); + + int adj = GetScrollMetric(sbar->nBarType == SB_VERT, SM_CXHORZSB); + rc.left += adj; + rc.right -= adj; + + //keep the thumb within the scrollbar limits + thumbpos = pt.x - nThumbMouseOffset; + if(thumbpos < rc.left) thumbpos = rc.left; + if(thumbpos > rc.right - nThumbSize) thumbpos = rc.right - nThumbSize; + + GET_WINDOW_RECT(hwnd, &winrect); + + if(sbar->nBarType == SB_VERT) + RotateRect(&winrect); + + hdc = GetWindowDC(hwnd); + + + OffsetRect(&rc, -winrect.left, -winrect.top); + thumbpos -= winrect.left; + + //draw the margin before the thumb + SetRect(&rc2, rc.left, rc.top, thumbpos, rc.bottom); + RotateRect0(sbar, &rc2); + + DrawCheckedRect(NULL,hdc, &rc2, crCheck1, crCheck2, sbar, &rcThumbBounds, 0,sbXoffs, sbYoffs ); + + RotateRect0(sbar, &rc2); + + //draw the margin after the thumb + SetRect(&rc2, thumbpos+nThumbSize, rc.top, rc.right, rc.bottom); + + RotateRect0(sbar, &rc2); + + DrawCheckedRect(NULL,hdc, &rc2, crCheck1, crCheck2, sbar, &rcThumbBounds, 0, sbXoffs, sbYoffs ); + + RotateRect0(sbar, &rc2); + + //finally draw the thumb itelf. This is how it looks on win2000, anyway + SetRect(&rc2, thumbpos, rc.top, thumbpos+nThumbSize, rc.bottom); + + RotateRect0(sbar, &rc2); + + if(m_scrollbar_bmp && *m_scrollbar_bmp) + { + drawSkinThumb(hdc, rc2, 0, 1, sbar->nBarType == SB_VERT, &rcThumbBounds, sbar); + } + else + { + // no skinning + { + RECT r = rc2; + if(sw->resizingHthumb) + { + if(sbar->nBarType == SB_HORZ) + { + r.left += m_thumbsize; + r.right -= m_thumbsize; + } + else + { + //disabled for now + /*r.top += m_thumbsize; + r.bottom -= m_thumbsize;*/ + } + } + DrawBlankButton(hwnd,hdc, &r); + } + + if(sw->resizingHthumb) + { + //draw left and right resizers + if(sbar->nBarType == SB_HORZ) + { + RECT thumb = rc2; + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + { + RECT r={thumb.left, thumb.top, thumb.left+m_thumbsize, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + { + RECT r={thumb.right-m_thumbsize, thumb.top, thumb.right, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + DeleteObject(br); + } + else + { + //disabled for now + /*RECT thumb = rc2; + HBRUSH br = CreateSolidBrush(CoolSB_GetSysColor(hwnd,COLOR_BTNFACE)); + { + RECT r={thumb.left, thumb.top, thumb.right, thumb.top+m_thumbsize}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + { + RECT r={thumb.left, thumb.bottom - m_thumbsize, thumb.right, thumb.bottom}; + ownDrawEdge(hwnd,hdc, &r, EDGE_RAISED, BF_RECT | BF_ADJUST); + FillRect(hdc, &r, br); + } + DeleteObject(br);*/ + } + } + } + + RotateRect0(sbar, &rc2); + ReleaseDC(hwnd, hdc); + + //post a SB_TRACKPOS message!!! + siMaxMin = si->nMax - si->nMin; + + if(siMaxMin > 0) + pos = MulDiv(thumbpos-rc.left, siMaxMin-si->nPage + 1, rc.right-rc.left-nThumbSize); + else + pos = thumbpos - rc.left; + + if(pos != nLastPos) + { + si->nTrackPos = pos; + SendScrollMessage(hwnd, sw->uScrollTimerMsg, SB_THUMBTRACK, pos); + } + + nLastPos = pos; + + + return 0; +} + +// +// remember to rotate the thumb bounds rectangle!! +// +static LRESULT ThumbTrackVert(SCROLLBAR *sb, HWND hwnd, int x, int y) +{ + //sw->swapcoords = TRUE; + RotateRect(&rcThumbBounds); + ThumbTrackHorz(sb, hwnd, y, x); + RotateRect(&rcThumbBounds); + //sw->swapcoords = FALSE; + + return 0; +} + +// +// Called when we have set the capture from the NCLButtonDown(...) +// +static LRESULT MouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + RECT rect; + UINT thisportion; + HDC hdc; + static UINT lastportion = 0; + static UINT lastbutton = 0; + POINT pt; + RECT winrect; + UINT buttonIdx = 0; + + if(sw->fThumbTracking == TRUE) + { + LONG x, y; + lParam = GetMessagePos(); + x = GET_X_LPARAM(lParam); + y = GET_Y_LPARAM(lParam); + OSX_REMAP_SCREENY(hwnd,&y); + + if(sw->uCurrentScrollbar == SB_HORZ) + return ThumbTrackHorz(&sw->sbarHorz, hwnd, x,y); + + + else if(sw->uCurrentScrollbar == SB_VERT) + return ThumbTrackVert(&sw->sbarVert, hwnd, x,y); + } + + if(sw->uCurrentScrollPortion == HTSCROLL_NONE) + { + return CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam); + } + else + { + LPARAM nlParam; + SCROLLBAR *sb = &sw->sbarHorz; + + nlParam = GetMessagePos(); + + GET_WINDOW_RECT(hwnd, &winrect); + + pt.x = GET_X_LPARAM(nlParam); + pt.y = GET_Y_LPARAM(nlParam); + OSX_REMAP_SCREENY(hwnd,&pt.y); + + //emulate the mouse input on a scrollbar here... + if(sw->uCurrentScrollbar == SB_HORZ) + { + sb = &sw->sbarHorz; + } + else if(sw->uCurrentScrollbar == SB_VERT) + { + sb = &sw->sbarVert; + } + + //get the total area of the normal scrollbar area + BOOL hasZoomButtons; + GetScrollRect(sw, sb->nBarType, hwnd, &rect,&hasZoomButtons); + + //see if we clicked in the inserted buttons / normal scrollbar + //thisportion = GetPortion(sb, hwnd, &rect, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + thisportion = GetPortion(sb, hwnd, &rect, pt.x, pt.y,hasZoomButtons); + + //we need to do different things depending on if the + //user is activating the scrollbar itself, or one of + //the inserted buttons + switch(sw->uCurrentScrollPortion) + { + + + //The scrollbar is active + case HTSCROLL_LEFT: case HTSCROLL_RIGHT:case HTSCROLL_THUMB: + case HTSCROLL_PAGELEFT: case HTSCROLL_PAGERIGHT: + case HTSCROLL_NONE: + + //adjust the total scroll area to become where the scrollbar + //really is (take into account the inserted buttons) + + OffsetRect(&rect, -winrect.left, -winrect.top); + hdc = GetWindowDC(hwnd); + + if(thisportion != sw->uCurrentScrollPortion) + { + sw->uScrollTimerPortion = HTSCROLL_NONE; + + if(lastportion != thisportion) + NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NORMAL,hasZoomButtons); + } + //otherwise, draw the button in its depressed / clicked state + else + { + sw->uScrollTimerPortion = sw->uCurrentScrollPortion; + + if(lastportion != thisportion) + NCDrawScrollbar(sb, hwnd, hdc, &rect, thisportion,hasZoomButtons); + } + + ReleaseDC(hwnd, hdc); + + break; + case HTSCROLL_LRESIZER: + case HTSCROLL_RRESIZER: + { + RECT rect; + int nThumbSize, nThumbPos; + int offs = pt.x - nThumbMouseOffset; + if(sw->uCurrentScrollbar == SB_VERT) offs = pt.y - nThumbMouseOffset; + if(sw->uCurrentScrollPortion == HTSCROLL_RRESIZER) offs = -offs; + + if((sw->uCurrentScrollbar == SB_VERT)) + { + GetVScrollRect(sw, hwnd, &rect,NULL); + RotateRect0(sb, &rect); + CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); + SendMessage(hwnd, (sw->uCurrentScrollPortion == HTSCROLL_RRESIZER?WM_SB_TRESIZE_VB:WM_SB_TRESIZE_VT), offs, ((nThumbSize&0xffff)<<16) + ((rect.right-rect.left)&0xffff)); + } + else + { + GetHScrollRect(sw, hwnd, &rect,NULL); + CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos); + SendMessage(hwnd, (sw->uCurrentScrollPortion == HTSCROLL_RRESIZER?WM_SB_TRESIZE_HR:WM_SB_TRESIZE_HL), offs, ((nThumbSize&0xffff)<<16) + ((rect.right-rect.left)&0xffff)); + } + + if(sw->uCurrentScrollbar == SB_VERT) + { + //nThumbMouseOffset = pt.y; + SetCursor(LoadCursor(NULL,IDC_SIZENS)); + } + else + { + //nThumbMouseOffset = pt.x; + SetCursor(LoadCursor(NULL,IDC_SIZEWE)); + } + } + break; + case HTSCROLL_RESIZER: + { + int offs = pt.x - nThumbMouseOffset; + if(sw->uCurrentScrollbar == SB_VERT) offs = pt.y - nThumbMouseOffset; + SendMessage(hwnd, WM_SB_RESIZE, offs, sw->uCurrentScrollbar == SB_VERT); + if(sw->uCurrentScrollbar == SB_VERT) + { + nThumbMouseOffset = pt.y; + SetCursor(LoadCursor(NULL,IDC_SIZENS)); + } + else + { + nThumbMouseOffset = pt.x; + SetCursor(LoadCursor(NULL,IDC_SIZEWE)); + } + } + break; + } + + + lastportion = thisportion; + lastbutton = buttonIdx; + + //must return zero here, because we might get cursor anomilies + //CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam); + return 0; + + } +} + + +// +// We must allocate from in the non-client area for our scrollbars +// Call the default window procedure first, to get the borders (if any) +// allocated some space, then allocate the space for the scrollbars +// if they fit +// +static LRESULT NCCalcSize(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + NCCALCSIZE_PARAMS *nccsp; + RECT *rect; + RECT oldrect; + BOOL fCalcValidRects = (wParam == TRUE); + SCROLLBAR *sb; + UINT ret; + + //Regardless of the value of fCalcValidRects, the first rectangle + //in the array specified by the rgrc structure member of the + //NCCALCSIZE_PARAMS structure contains the coordinates of the window, + //so we can use the exact same code to modify this rectangle, when + //wParam is TRUE and when it is FALSE. + nccsp = (NCCALCSIZE_PARAMS *)lParam; + rect = &nccsp->rgrc[0]; + oldrect = *rect; + + + //call the default procedure to get the borders allocated + ret = CallWindowProcStyleMod(sw,hwnd, WM_NCCALCSIZE, wParam, lParam); + + // calculate what the size of each window border is, + sw->cxLeftEdge = rect->left - oldrect.left; + sw->cxRightEdge = oldrect.right - rect->right; + sw->cyTopEdge = rect->top - oldrect.top; + sw->cyBottomEdge = oldrect.bottom - rect->bottom; + + sb = &sw->sbarHorz; + + //if there is room, allocate some space for the horizontal scrollbar + //NOTE: Change the ">" to a ">=" to make the horz bar totally fill the + //window before disappearing + + if((sb->fScrollFlags & CSBS_VISIBLE) && + rect->bottom - rect->top > GetScrollMetric(FALSE, SM_CYHORZSB)) + { + rect->bottom -= GetScrollMetric(FALSE, SM_CYHORZSB); + sb->fScrollVisible = TRUE; + } + else + { + sb->fScrollVisible = FALSE; + } + + sb = &sw->sbarVert; + + //if there is room, allocate some space for the vertical scrollbar + if((sb->fScrollFlags & CSBS_VISIBLE) && + rect->right - rect->left >= GetScrollMetric(TRUE, SM_CXVERTSB)) + { + if(sw->fLeftScrollbar) + rect->left += GetScrollMetric(TRUE, SM_CXVERTSB); + else + rect->right -= GetScrollMetric(TRUE, SM_CXVERTSB); + + sb->fScrollVisible = TRUE; + } + else + sb->fScrollVisible = FALSE; + +//printf("nccalcsize, %d,%d,%d,%d -> %d,%d,%d,%d\n",oldrect.left,oldrect.top,oldrect.right,oldrect.bottom, +// rect->left,rect->top,rect->right,rect->bottom); + + //don't return a value unless we actually modify the other rectangles + //in the NCCALCSIZE_PARAMS structure. In this case, we return 0 + //no matter what the value of fCalcValidRects is + return ret;//FALSE; +} + +// +// used for hot-tracking over the scroll buttons +// +static LRESULT NCMouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wHitTest, LPARAM lParam) +{ + { + LONG x, y; + int p; + RECT hr, vr; + lParam = GetMessagePos(); + x = GET_X_LPARAM(lParam); + y = GET_Y_LPARAM(lParam); + OSX_REMAP_SCREENY(hwnd,&y); + BOOL hasZoomButtons; + GetHScrollRect(sw, hwnd, &hr,&hasZoomButtons); + p = GetHorzPortion(&sw->sbarHorz, hwnd, &hr, x, y,hasZoomButtons); + if(p == HTSCROLL_NONE) + { + GetVScrollRect(sw, hwnd, &vr,&hasZoomButtons); + p = GetVertPortion(&sw->sbarVert, hwnd, &vr, x, y,hasZoomButtons); + } + if(p == HTSCROLL_RESIZER || p == HTSCROLL_LRESIZER || p == HTSCROLL_RRESIZER) + { + if(wHitTest == HTHSCROLL) + SetCursor(LoadCursor(NULL,IDC_SIZEWE)); + else + SetCursor(LoadCursor(NULL,IDC_SIZENS)); + } +#ifndef _WIN32 + else SetCursor(LoadCursor(NULL,IDC_ARROW)); +#endif + } + + //install a timer for the mouse-over events, if the mouse moves + //over one of the scrollbars + hwndCurCoolSB = hwnd; + if(wHitTest == HTHSCROLL) + { + if(sw->uMouseOverScrollbar == SB_HORZ) + return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); + + sw->uLastHitTestPortion = HTSCROLL_NONE; + sw->uHitTestPortion = HTSCROLL_NONE; + GetScrollRect(sw, SB_HORZ, hwnd, &sw->MouseOverRect, &sw->MouseOverRect_hasZoomButtons); + sw->uMouseOverScrollbar = SB_HORZ; + sw->uMouseOverId = SetTimer(hwnd, COOLSB_TIMERID3, COOLSB_TIMERINTERVAL3, 0); + + NCPaint(sw, hwnd, 1, 0); + } + else if(wHitTest == HTVSCROLL) + { + if(sw->uMouseOverScrollbar == SB_VERT) + return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); + + sw->uLastHitTestPortion = HTSCROLL_NONE; + sw->uHitTestPortion = HTSCROLL_NONE; + GetScrollRect(sw, SB_VERT, hwnd, &sw->MouseOverRect, &sw->MouseOverRect_hasZoomButtons); + sw->uMouseOverScrollbar = SB_VERT; + sw->uMouseOverId = SetTimer(hwnd, COOLSB_TIMERID3, COOLSB_TIMERINTERVAL3, 0); + + NCPaint(sw, hwnd, 1, 0); + } + + + return CallWindowProc(sw->oldproc, hwnd, WM_NCMOUSEMOVE, wHitTest, lParam); +} + +// +// Timer routine to generate scrollbar messages +// +static LRESULT CoolSB_Timer(SCROLLWND *swnd, HWND hwnd, WPARAM wTimerId, LPARAM lParam) +{ + //let all timer messages go past if we don't have a timer installed ourselves + if(swnd->uScrollTimerId == 0 && swnd->uMouseOverId == 0 && swnd->uZoomTimerId == 0) + { + return CallWindowProc(swnd->oldproc, hwnd, WM_TIMER, wTimerId, lParam); + } + + if (wTimerId == COOLSB_TIMERID4) + { + SendMessage(hwnd, WM_SB_ZOOM, swnd->uZoomTimerMode/2, swnd->uZoomTimerMode&1); + return 0; + } + + //mouse-over timer + if(wTimerId == COOLSB_TIMERID3) + { + POINT pt; + RECT rect, winrect; + HDC hdc; + SCROLLBAR *sbar; + + if(swnd->fThumbTracking) + return 0; + + //if the mouse moves outside the current scrollbar, + //then kill the timer.. + GetCursorPos(&pt); + + RECT mor = swnd->MouseOverRect; + BOOL hasZoomButtons = swnd->MouseOverRect_hasZoomButtons; + + if (hasZoomButtons && swnd->resizingHthumb) + { + int zbs = GetZoomButtonSize(swnd->uMouseOverScrollbar==SB_VERT); + int extrasz=zbs*2+ZOOMBUTTON_RESIZER_SIZE(zbs); + + if(swnd->uMouseOverScrollbar == SB_VERT) + mor.bottom += extrasz; + else + mor.right += extrasz; + } + + if(!PtInRect(&mor, pt)||WindowFromPoint(pt)!=hwnd) + { + KillTimer(hwnd, swnd->uMouseOverId); + swnd->uMouseOverId = 0; + swnd->uMouseOverScrollbar = COOLSB_NONE; + swnd->uLastHitTestPortion = HTSCROLL_NONE; + + swnd->uHitTestPortion = HTSCROLL_NONE; + NCPaint(swnd, hwnd, 1, 0); + } + else + { + if(swnd->uMouseOverScrollbar == SB_HORZ) + { + sbar = &swnd->sbarHorz; + swnd->uHitTestPortion = GetHorzPortion(sbar, hwnd, &swnd->MouseOverRect, pt.x, pt.y,hasZoomButtons); + } + else + { + sbar = &swnd->sbarVert; + swnd->uHitTestPortion = GetVertPortion(sbar, hwnd, &swnd->MouseOverRect, pt.x, pt.y,hasZoomButtons); + } + + if(swnd->uLastHitTestPortion != swnd->uHitTestPortion) + { + rect = swnd->MouseOverRect; + + GET_WINDOW_RECT(hwnd, &winrect); + OffsetRect(&rect, -winrect.left, -winrect.top); + + hdc = GetWindowDC(hwnd); + NCDrawScrollbar(sbar, hwnd, hdc, &rect, HTSCROLL_NONE,hasZoomButtons); + ReleaseDC(hwnd, hdc); + } + + swnd->uLastHitTestPortion = swnd->uHitTestPortion; + } + + return 0; + } + + //if the first timer goes off, then we can start a more + //regular timer interval to auto-generate scroll messages + //this gives a slight pause between first pressing the scroll arrow, and the + //actual scroll starting + if(wTimerId == COOLSB_TIMERID1) + { + KillTimer(hwnd, swnd->uScrollTimerId); + swnd->uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID2, COOLSB_TIMERINTERVAL2, 0); + return 0; + } + //send the scrollbar message repeatedly + else if(wTimerId == COOLSB_TIMERID2) + { + //need to process a spoof WM_MOUSEMOVE, so that + //we know where the mouse is each time the scroll timer goes off. + //This is so we can stop sending scroll messages if the thumb moves + //under the mouse. + POINT pt; + GetCursorPos(&pt); + ScreenToClient(hwnd, &pt); + + MouseMove(swnd, hwnd, MK_LBUTTON, MAKELPARAM(pt.x, pt.y)); + + if(swnd->uScrollTimerPortion != HTSCROLL_NONE) + SendScrollMessage(hwnd, swnd->uScrollTimerMsg, swnd->uScrollTimerPortion, 0); + + return 0; + } + else + { + return CallWindowProc(swnd->oldproc, hwnd, WM_TIMER, wTimerId, lParam); + } +} + +// +// We must intercept any calls to SetWindowLong, to check if +// left-scrollbars are taking effect or not +// +static LRESULT CoolSB_StyleChange(SCROLLWND *swnd, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + STYLESTRUCT *ss = (STYLESTRUCT *)lParam; + + if(wParam == GWL_EXSTYLE) + { + if(ss->styleNew & WS_EX_LEFTSCROLLBAR) + swnd->fLeftScrollbar = TRUE; + else + swnd->fLeftScrollbar = FALSE; + } + + return CallWindowProc(swnd->oldproc, hwnd, msg, wParam, lParam); +} + + + +// +// CoolScrollbar subclass procedure. +// Handle all messages needed to mimick normal windows scrollbars +// +static LRESULT CALLBACK CoolSBWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc; + SCROLLWND *swnd = GetScrollWndFromHwnd(hwnd); + static int count; + + switch(message) + { + case WM_NCDESTROY: + //this should NEVER be called, because the user + //should have called Uninitialize() themselves. + + //However, if the user tries to call Uninitialize().. + //after this window is destroyed, this window's entry in the lookup + //table will not be there, and the call will fail + oldproc = swnd->oldproc; + UninitializeCoolSB(hwnd); + + //we must call the original window procedure, otherwise it + //will never get the WM_NCDESTROY message, and it wouldn't + //be able to clean up etc. + return CallWindowProc(oldproc, hwnd, message, wParam, lParam); + + case WM_NCCALCSIZE: + return NCCalcSize(swnd, hwnd, wParam, lParam); + + case WM_NCPAINT: + return NCPaint(swnd, hwnd, wParam, lParam); + + case WM_NCHITTEST: + return NCHitTest(swnd, hwnd, wParam, lParam); + + #ifdef _WIN32 + case WM_NCRBUTTONDOWN: case WM_NCRBUTTONUP: + case WM_NCMBUTTONDOWN: case WM_NCMBUTTONUP: + if(wParam == HTHSCROLL || wParam == HTVSCROLL) + return 0; + break; + #endif + + case WM_NCLBUTTONDBLCLK: + if(wParam == HTHSCROLL || wParam == HTVSCROLL) + return NCLButtonDown(swnd, hwnd, wParam, lParam,TRUE); + else + break; + + case WM_NCLBUTTONDOWN: + return NCLButtonDown(swnd, hwnd, wParam, lParam,FALSE); + + + case WM_LBUTTONUP: + return LButtonUp(swnd, hwnd, wParam, lParam); + + case WM_MOUSEMOVE: + return MouseMove(swnd, hwnd, wParam, lParam); + + case WM_TIMER: + return CoolSB_Timer(swnd, hwnd, wParam, lParam); + + //case WM_STYLECHANGING: + // return CoolSB_StyleChange(swnd, hwnd, WM_STYLECHANGING, wParam, lParam); + case WM_STYLECHANGED: + + if(swnd->bPreventStyleChange) + { + // the NCPAINT handler has told us to eat this message! + return 0; + } + else + { + if (message == WM_STYLECHANGED) + return CoolSB_StyleChange(swnd, hwnd, WM_STYLECHANGED, wParam, lParam); + else + break; + } + + case WM_NCMOUSEMOVE: + return NCMouseMove(swnd, hwnd, wParam, lParam); + + + case WM_CAPTURECHANGED: + break; + +#ifdef _WIN32 + case WM_NCACTIVATE: // fix for floating windows etc on XPsp2 etc + case WM_SYSCOMMAND: // fix for MIDI editor when fully zoomed out on XPsp2 + + return CallWindowProcStyleMod(swnd,hwnd,message,wParam,lParam); +#endif + default: +#if 0 + if (message) + { + static int msgs[512]={0,}; + int x; + for(x=0;x<512&&msgs[x] && msgs[x]!=message;x++); + if (x<512 && !msgs[x]) + { + msgs[x]=message; + FILE *fp = fopen("C:/log.txt","a+"); + if (fp) { fprintf(fp,"%d\n",message); fclose(fp); } + + } + } +#endif + break; + } + + + return CallWindowProc(swnd->oldproc, hwnd, message, wParam, lParam); +} + +void CoolSB_OnColorThemeChange() +{ + m_scrollbar_bmp = NULL; + g_coolsb_imageVersion++; +} + + + + +#ifndef _WIN32 // SWELL does not yet emulate these, so we have some default behaviors here + +static BOOL GetScrollInfo(HWND hwnd, int sb, SCROLLINFO *si) +{ + si->nMin=0; si->nMax=1000; si->nPage=10; si->nPos=si->nTrackPos=0; + return FALSE; +} +static int GetScrollPos(HWND hwnd, int sb) +{ + return 0; +} + +static BOOL GetScrollRange(HWND hwnd, int sb, int *minpos, int *maxpos) +{ + if (minpos) *minpos=0; + if (maxpos) *maxpos=1000; + return 0; +} +static BOOL SetScrollInfo(HWND hwnd, int sb, SCROLLINFO *si, BOOL redraw) +{ + return 0; +} +static BOOL SetScrollRange(HWND hwnd, int nBar, int minv, int maxv, BOOL fRedraw) +{ +return 0; +} +static int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) +{ + return 0; +} +static BOOL ShowScrollBar(HWND hwnd, int nBar, BOOL vis) +{ + return 0; +} + + +#endif + +static TCHAR szPropStr[] = _T("CoolSBSubclassPtr"); + +SCROLLWND *GetScrollWndFromHwnd(HWND hwnd) +{ + return (SCROLLWND *)GetProp(hwnd, szPropStr); +} + +SCROLLBAR *GetScrollBarFromHwnd(HWND hwnd, UINT nBar) +{ + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + + if(!sw) return 0; + + if(nBar == SB_HORZ) + return &sw->sbarHorz; + else if(nBar == SB_VERT) + return &sw->sbarVert; + else + return 0; +} + +BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd) +{ + if(GetScrollWndFromHwnd(hwnd)) + return TRUE; + else + return FALSE; +} + +// +// Special support for USER32.DLL patching (using Detours library) +// The only place we call a real scrollbar API is in InitializeCoolSB, +// where we call EnableScrollbar. +// +// We HAVE to call the origial EnableScrollbar function, +// so we need to be able to set a pointer to this func when using +// using Detours (or any other LIB??) +// + + +static void RedrawNonClient(HWND hwnd, BOOL fFrameChanged) +{ + if(fFrameChanged == FALSE) + { + SendMessage(hwnd, WM_NCPAINT, (WPARAM)1, 0); + } + else + { +#ifdef _WIN32 + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE + | SWP_FRAMECHANGED | SWP_DRAWFRAME); +#endif + } +} + +// +// return the default minimum size of a scrollbar thumb +// +int WINAPI CoolSB_GetDefaultMinThumbSize(void) +{ +#ifdef _WIN32 + DWORD dwVersion = GetVersion(); + + // set the minimum thumb size for a scrollbar. This + // differs between NT4 and 2000, so need to check to see + // which platform we are running under + if(dwVersion < 0x80000000) // Windows NT/2000 + { + if(LOBYTE(LOWORD(dwVersion)) >= 5) + return MINTHUMBSIZE_2000; + else + return MINTHUMBSIZE_NT4; + } + else + { + return MINTHUMBSIZE_NT4; + } + #else + return MINTHUMBSIZE_2000; + #endif +} + + +static SCROLLINFO *GetScrollInfoFromHwnd(HWND hwnd, int fnBar) +{ + SCROLLBAR *sb = GetScrollBarFromHwnd(hwnd, fnBar); + + if(sb == 0) + return FALSE; + + if(fnBar == SB_HORZ) + { + return &sb->scrollInfo; + } + else if(fnBar == SB_VERT) + { + return &sb->scrollInfo; + } + else + return NULL; +} +// +// Initialize the cool scrollbars for a window by subclassing it +// and using the coolsb window procedure instead +// +BOOL WINAPI InitializeCoolSB(HWND hwnd) +{ + SCROLLWND *sw; + SCROLLINFO *si; + RECT rect; + DWORD dwCurStyle; + //BOOL fDisabled; + + + GetClientRect(hwnd, &rect); + + //if we have already initialized Cool Scrollbars for this window, + //then stop the user from doing it again + if(GetScrollWndFromHwnd(hwnd) != 0) + { + return FALSE; + } + + //allocate a private scrollbar structure which we + //will use to keep track of the scrollbar data +#ifdef _WIN32 + sw = (SCROLLWND *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCROLLWND)); +#else + sw = (SCROLLWND *)calloc(1,sizeof(SCROLLWND)); +#endif + + sw->uCurrentScrollbar = COOLSB_NONE; //SB_HORZ / SB_VERT + sw->uCurrentScrollPortion = HTSCROLL_NONE; + sw->uMouseOverScrollbar = COOLSB_NONE; + sw->uHitTestPortion = HTSCROLL_NONE; + sw->uLastHitTestPortion = HTSCROLL_NONE; + sw->uScrollTimerPortion = HTSCROLL_NONE; + + si = &sw->sbarHorz.scrollInfo; + si->cbSize = sizeof(SCROLLINFO); + si->fMask = SIF_ALL; + GetScrollInfo(hwnd, SB_HORZ, si); + + si = &sw->sbarVert.scrollInfo; + si->cbSize = sizeof(SCROLLINFO); + si->fMask = SIF_ALL; + GetScrollInfo(hwnd, SB_VERT, si); + + //check to see if the window has left-aligned scrollbars + if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR) + sw->fLeftScrollbar = TRUE; + else + sw->fLeftScrollbar = FALSE; + + dwCurStyle = GetWindowLong(hwnd, GWL_STYLE); + + SetProp(hwnd, szPropStr, (HANDLE)sw); + + + //scrollbars will automatically get enabled, even if + //they aren't to start with....sorry, but there isn't an + //easy alternative. + if(dwCurStyle & WS_HSCROLL) + sw->sbarHorz.fScrollFlags = CSBS_VISIBLE; + + if(dwCurStyle & WS_VSCROLL) + sw->sbarVert.fScrollFlags = CSBS_VISIBLE; + + //need to be able to distinguish between horizontal and vertical + //scrollbars in some instances + sw->sbarHorz.nBarType = SB_HORZ; + sw->sbarVert.nBarType = SB_VERT; + + sw->bPreventStyleChange = FALSE; + + sw->resizingHthumb = FALSE; + + sw->oldproc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR)CoolSBWndProc); + + CoolSB_SetMinThumbSize(hwnd, SB_BOTH, CoolSB_GetDefaultMinThumbSize()); + + + //send the window a frame changed message to update the scrollbars + RedrawNonClient(hwnd, TRUE); + + return TRUE; +} + + +BOOL WINAPI CoolSB_IsThumbTracking(HWND hwnd) +{ + SCROLLWND *sw; + + if((sw = GetScrollWndFromHwnd(hwnd)) == NULL) + return FALSE; + else + return sw->fThumbTracking; +} + + +BOOL WINAPI CoolSB_GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi) +{ + SCROLLINFO *mysi; + BOOL copied = FALSE; + + if(!lpsi) + return FALSE; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) + { + return GetScrollInfo(hwnd, fnBar, lpsi); + } + + if(lpsi->fMask & SIF_PAGE) + { + lpsi->nPage = mysi->nPage; + copied = TRUE; + } + + if(lpsi->fMask & SIF_POS) + { + lpsi->nPos = mysi->nPos; + copied = TRUE; + } + + if(lpsi->fMask & SIF_TRACKPOS) + { + lpsi->nTrackPos = mysi->nTrackPos; + copied = TRUE; + } + + if(lpsi->fMask & SIF_RANGE) + { + lpsi->nMin = mysi->nMin; + lpsi->nMax = mysi->nMax; + copied = TRUE; + } + + return copied; +} + +int WINAPI CoolSB_GetScrollPos (HWND hwnd, int nBar) +{ + SCROLLINFO *mysi; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) + return GetScrollPos(hwnd, nBar); + + return mysi->nPos; +} + +BOOL WINAPI CoolSB_GetScrollRange (HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) +{ + SCROLLINFO *mysi; + + if(!lpMinPos || !lpMaxPos) + return FALSE; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) + return GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); + + *lpMinPos = mysi->nMin; + *lpMaxPos = mysi->nMax; + + return TRUE; +} + +int WINAPI CoolSB_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw) +{ + SCROLLINFO *mysi; + SCROLLBAR *sbar; + BOOL fRecalcFrame = FALSE; + + if(!lpsi) + return FALSE; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) + return SetScrollInfo(hwnd, fnBar, lpsi, fRedraw); + + //if(CoolSB_IsThumbTracking(hwnd)) + // return mysi->nPos; + + if(lpsi->fMask & SIF_RANGE) + { + mysi->nMin = lpsi->nMin; + mysi->nMax = lpsi->nMax; + } + + //The nPage member must specify a value from 0 to nMax - nMin +1. + if(lpsi->fMask & SIF_PAGE) + { + UINT t = (UINT)(mysi->nMax - mysi->nMin + 1); + mysi->nPage = min(max(0, lpsi->nPage), t); + } + + //The nPos member must specify a value between nMin and nMax - max(nPage - 1, 0). + if(lpsi->fMask & SIF_POS) + { + mysi->nPos = max(lpsi->nPos, mysi->nMin); + mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); + } + + sbar = GetScrollBarFromHwnd(hwnd, fnBar); + + if((lpsi->fMask & SIF_DISABLENOSCROLL) || (sbar->fScrollFlags & CSBS_THUMBALWAYS)) + { + if(!sbar->fScrollVisible) + { + CoolSB_ShowScrollBar(hwnd, fnBar, TRUE); + fRecalcFrame = TRUE; + } + } + else + { + if( mysi->nPage > (UINT)mysi->nMax + || mysi->nPage == (UINT)mysi->nMax && mysi->nMax == 0 + || mysi->nMax <= mysi->nMin) + { + if(sbar->fScrollVisible) + { + CoolSB_ShowScrollBar(hwnd, fnBar, FALSE); + fRecalcFrame = TRUE; + } + } + else + { + if(!sbar->fScrollVisible) + { + CoolSB_ShowScrollBar(hwnd, fnBar, TRUE); + fRecalcFrame = TRUE; + } + + } + + } + + if(fRedraw && !CoolSB_IsThumbTracking(hwnd)) + RedrawNonClient(hwnd, fRecalcFrame); + + return mysi->nPos; +} + + +int WINAPI CoolSB_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) +{ + SCROLLINFO *mysi; + int oldpos; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) + { + return SetScrollPos(hwnd, nBar, nPos, fRedraw); + } + + //this is what should happen, but real scrollbars don't work like this.. + //if(CoolSB_IsThumbTracking(hwnd)) + // return mysi->nPos; + + //validate and set the scollbar position + oldpos = mysi->nPos; + mysi->nPos = max(nPos, mysi->nMin); + mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); + + if(fRedraw && !CoolSB_IsThumbTracking(hwnd)) + RedrawNonClient(hwnd, FALSE); + + return oldpos; +} + +int WINAPI CoolSB_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) +{ + SCROLLINFO *mysi; + + if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) + return SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); + + if(CoolSB_IsThumbTracking(hwnd)) + return mysi->nPos; + + //hide the scrollbar if nMin == nMax + //nMax-nMin must not be greater than MAXLONG + mysi->nMin = nMinPos; + mysi->nMax = nMaxPos; + + if(fRedraw) + RedrawNonClient(hwnd, FALSE); + + return TRUE; +} + +// +// Show or hide the specified scrollbars +// +BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow) +{ + SCROLLBAR *sbar; + BOOL bFailed = FALSE; + DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE); + + if(!CoolSB_IsCoolScrollEnabled(hwnd)) + { + return ShowScrollBar(hwnd, wBar, fShow); + } + if((wBar == SB_HORZ || wBar == SB_BOTH) && + (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) + { + sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; + sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); + //bFailed = TRUE; + + if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL); + else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL); + } + + if((wBar == SB_VERT || wBar == SB_BOTH) && + (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) + { + sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; + sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); + //bFailed = TRUE; + + if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL); + else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL); + } + + if(bFailed) + { + return FALSE; + } + else + { + //DWORD style = GetWindowLong(hwnd, GWL_STYLE); + //style |= WS_VSCROLL; + + //if(s + //SetWindowLong(hwnd, GWL_STYLE, style); + + SetWindowPos(hwnd, 0, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOACTIVATE | SWP_FRAMECHANGED); + + return TRUE; + } +} + +// +// Remove cool scrollbars from the specified window. +// +HRESULT WINAPI UninitializeCoolSB(HWND hwnd) +{ + int i = 0; + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + if(!sw) return E_FAIL; + + //restore the window procedure with the original one + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR)sw->oldproc); + + RemoveProp(hwnd, szPropStr); + //SetWindowLong(hwnd, GWL_USERDATA, 0); + + delete sw->sbarHorz.liceBkgnd; + delete sw->sbarHorz.liceThumb; + delete sw->sbarVert.liceBkgnd; + delete sw->sbarVert.liceThumb; + sw->sbarHorz.liceBkgnd = NULL; + sw->sbarHorz.liceThumb = NULL; + sw->sbarVert.liceBkgnd = NULL; + sw->sbarVert.liceThumb = NULL; + + //finally, release the memory needed for the cool scrollbars +#ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, sw); +#else + free(sw); +#endif + + //Force WM_NCCALCSIZE and WM_NCPAINT so the original scrollbars can kick in + RedrawNonClient(hwnd, TRUE); + + return S_OK; +} + + +// +// Set the minimum size, in pixels, that the thumb box will shrink to. +// +BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size) +{ + SCROLLBAR *sbar; + + if(!GetScrollWndFromHwnd(hwnd)) + return FALSE; + + if(size == -1) + size = CoolSB_GetDefaultMinThumbSize(); + + if((wBar == SB_HORZ || wBar == SB_BOTH) && + (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) + { + sbar->nMinThumbSize = size; + } + + if((wBar == SB_VERT || wBar == SB_BOTH) && + (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) + { + sbar->nMinThumbSize = size; + } + + return TRUE; +} + +BOOL WINAPI CoolSB_SetResizingThumb(HWND hwnd, BOOL active) +{ + SCROLLWND *swnd; + + if(!(swnd = GetScrollWndFromHwnd(hwnd))) + return FALSE; + + swnd->resizingHthumb = active; + + return TRUE; +} diff --git a/WDL/wingui/scrollbar/coolscroll.h b/WDL/wingui/scrollbar/coolscroll.h new file mode 100644 index 00000000..22ced403 --- /dev/null +++ b/WDL/wingui/scrollbar/coolscroll.h @@ -0,0 +1,93 @@ +#ifndef _COOLSBLIB_INCLUDED +#define _COOLSBLIB_INCLUDED + +/* + WDL - Skinned/Resizing thumb scrollbar library + Based on the "Cool Scrollbar Library v1.2" by James Brown - http://www.catch22.net + + Original version Copyright(c) 2001 J Brown + Modifications copyright (C) 2006 and later Cockos Incorporated + + Note: for a more featureful, less hacked up version, you may wish to download the + original from catch22.net. It has lots of added features, whereas this version is + very much tailored for Cockos' needs. + + License: + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + + Public interface to the Cool Scrollbar library + + +*/ + +// notifications sent on user actions +#define WM_SB_RESIZE (WM_USER+511) +#define WM_SB_ZOOM (WM_USER+512) +#define WM_SB_TRESIZE_HL (WM_USER+513) +#define WM_SB_TRESIZE_HR (WM_USER+514) +#define WM_SB_TRESIZE_VT (WM_USER+515) +#define WM_SB_TRESIZE_VB (WM_USER+516) +#define WM_SB_TRESIZE_START (WM_USER+517) +#define WM_SB_DBLCLK (WM_USER+518) // wParam has SB_HORZ or SB_VERT + + +#ifndef COOLSB_NO_FUNC_DEFS +BOOL WINAPI InitializeCoolSB(HWND hwnd); +HRESULT WINAPI UninitializeCoolSB(HWND hwnd); // call in WM_DESTROY -- not strictly required, but recommended + +BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size); +BOOL WINAPI CoolSB_IsThumbTracking(HWND hwnd); +BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd); + +// +BOOL WINAPI CoolSB_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi); +int WINAPI CoolSB_GetScrollPos(HWND hwnd, int nBar); +BOOL WINAPI CoolSB_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos); + +// +int WINAPI CoolSB_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw); +int WINAPI CoolSB_SetScrollPos (HWND hwnd, int nBar, int nPos, BOOL fRedraw); +int WINAPI CoolSB_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw); +BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow); + +BOOL WINAPI CoolSB_SetResizingThumb(HWND hwnd, BOOL active); +void CoolSB_SetScale(float scale); // sets scale to use for scrollbars (does not refresh, though -- set this at startup/etc) +void CoolSB_OnColorThemeChange(); // refreshes all + + + +// TO BE IMPLEMENTED BY APP: +void *GetIconThemePointer(const char *name); // implemented by calling app, can return a LICE_IBitmap **img for "scrollbar" +int CoolSB_GetSysColor(HWND hwnd, int val); // can be a passthrough to GetSysColor() + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/WDL/wingui/virtwnd-controls.h b/WDL/wingui/virtwnd-controls.h new file mode 100644 index 00000000..cb93607d --- /dev/null +++ b/WDL/wingui/virtwnd-controls.h @@ -0,0 +1,370 @@ +/* + WDL - virtwnd-controls.h + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + + + +#ifndef _WDL_VIRTWND_CONTROLS_H_ +#define _WDL_VIRTWND_CONTROLS_H_ + +#include "virtwnd.h" +#include "virtwnd-skin.h" + +#include "../lice/lice_text.h" + +// an app should implement these +extern int WDL_STYLE_WantGlobalButtonBorders(); +extern bool WDL_STYLE_WantGlobalButtonBackground(int *col); +extern int WDL_STYLE_GetSysColor(int); +extern void WDL_STYLE_ScaleImageCoords(int *x, int *y); +extern bool WDL_Style_WantTextShadows(int *col); + +// this is the default, you can override per painter if you want +extern bool WDL_STYLE_GetBackgroundGradient(double *gradstart, double *gradslope); // return values 0.0-1.0 for each, return false if no gradient desired + +// for slider +extern LICE_IBitmap *WDL_STYLE_GetSliderBitmap2(bool vert); +extern bool WDL_STYLE_AllowSliderMouseWheel(); +extern int WDL_STYLE_GetSliderDynamicCenterPos(); + + +// functions for handling knob drawing in non-vwnds +extern WDL_VirtualWnd_BGCfg *vwnd_slider_getknobimageforsize(WDL_VirtualWnd_BGCfg *knoblist, int nknoblist,int *vieww, int *viewh, int *ksw, int *ksh, int *ks_offs); +extern void vwnd_slider_drawknobstack(LICE_IBitmap *drawbm, double val, WDL_VirtualWnd_BGCfg *knobimage, int ksw, int ksh, int ks_offs, int dx, int dy, int dw, int dh, double alpha=1.0f); + + +/* recommended defaults for the above: + +int WDL_STYLE_WantGlobalButtonBorders() { return 0; } +bool WDL_STYLE_WantGlobalButtonBackground(int *col) { return false; } +int WDL_STYLE_GetSysColor(int p) { return GetSysColor(p); } +void WDL_STYLE_ScaleImageCoords(int *x, int *y) { } +bool WDL_Style_WantTextShadows(int *col) { return false; } +bool WDL_STYLE_GetBackgroundGradient(double *gradstart, double *gradslope) { return false; } +LICE_IBitmap *WDL_STYLE_GetSliderBitmap2(bool vert) { return NULL; } +bool WDL_STYLE_AllowSliderMouseWheel() { return true; } +int WDL_STYLE_GetSliderDynamicCenterPos() { return 500; } + +*/ + + + + +// virtwnd-iconbutton.cpp +class WDL_VirtualIconButton : public WDL_VWnd +{ + public: + WDL_VirtualIconButton(); + virtual ~WDL_VirtualIconButton(); + virtual const char *GetType() { return "vwnd_iconbutton"; } + + virtual int OnMouseDown(int xpos, int ypos); // return -1 to eat, >0 to capture + virtual void OnMouseMove(int xpos, int ypos); + virtual void OnMouseUp(int xpos, int ypos); + virtual bool OnMouseDblClick(int xpos, int ypos); + + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual void OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + + virtual bool WantsPaintOver(); + virtual void GetPositionPaintOverExtent(RECT *r); + + + void SetEnabled(bool en) {m_en=en; } + bool GetEnabled() { return m_en; } + + void SetGrayed(bool grayed) { m_grayed = grayed; SetEnabled(!grayed); } + + void SetIcon(WDL_VirtualIconButton_SkinConfig *cfg, float alpha=1.0f, bool buttonownsicon=false); + void SetIsButton(bool isbutton) { m_is_button=isbutton; } + bool GetIsButton() { return m_is_button; } + + void SetImmediate(bool immediate) { m_immediate=immediate; } // send message on mousedown, not mouseup + + void SetBGCol1Callback(int msg) { m_bgcol1_msg=msg; } + + void SetForceBorder(bool fb) { m_forceborder=fb; } + + // only used if no icon config set, or if force is set + void SetTextLabel(const char *text); // no change of alignment etc + void SetTextLabel(const char *text, int align, LICE_IFont *font=NULL); + const char* GetTextLabel() { return m_textlbl.Get(); } + void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } + void SetVMargins(int t, int b) { m_margin_t=t; m_margin_b=b; }; + + // if icon config is set, check state == 1 will swap the up and down image + void SetCheckState(char state); // -1 = no checkbox, 0=unchecked, 1=checked + char GetCheckState() { return m_checkstate; } + + WDL_VirtualIconButton_SkinConfig* GetIcon() { return m_iconCfg; } // note button does not own m_iconCfg + bool ButtonOwnsIcon() { return m_ownsicon; } + + void SetForceText(bool ft, int color=0) { m_forcetext=ft; m_forcetext_color=color; } + bool GetForceText() { return m_forcetext; } + void SetTextLabelAlign(char align) { m_textalign=align; } + + void SetFont(LICE_IFont *font, LICE_IFont *vfont=NULL) { m_textfont=font; m_textfontv=vfont; } + LICE_IFont *GetFont(bool vfont=false) { return vfont?m_textfontv:m_textfont; } + + protected: + + void DoSendCommand(int xpos, int ypos); + + WDL_VirtualIconButton_SkinConfig *m_iconCfg; + int m_bgcol1_msg; + int m_margin_r, m_margin_l; + int m_margin_t, m_margin_b; + float m_alpha; + bool m_is_button,m_forceborder; + char m_pressed; + bool m_en, m_grayed, m_ownsicon; + bool m_immediate; + char m_textalign; + char m_checkstate; + bool m_forcetext; + int m_forcetext_color; + + WDL_String m_textlbl; + LICE_IFont *m_textfont,*m_textfontv; +}; + + + +class WDL_VirtualStaticText : public WDL_VWnd +{ + public: + WDL_VirtualStaticText(); + virtual ~WDL_VirtualStaticText(); + + virtual const char *GetType() { return "vwnd_statictext"; } + + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual bool OnMouseDblClick(int xpos, int ypos); + virtual int OnMouseDown(int xpos, int ypos); + + virtual void GetPositionPaintExtent(RECT *r); // override in case m_bkbm has outer areas + + void SetWantSingleClick(bool ws) {m_wantsingle=ws; } + void SetFont(LICE_IFont *font, LICE_IFont *vfont=NULL) { m_font=font; m_vfont=vfont; } + LICE_IFont *GetFont(bool vfont=false) { return vfont?m_vfont:m_font; } + void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right + void SetText(const char *text); + void SetBorder(bool bor) { m_wantborder=bor; } + const char *GetText() { return m_text.Get(); } + void SetColors(int fg=0, int bg=0, bool tint=false) { m_fg=fg; m_bg=bg; m_dotint=tint; } + void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } + void SetVMargins(int t, int b) { m_margin_t=t; m_margin_b=b; }; + void SetBkImage(WDL_VirtualWnd_BGCfg *bm) { m_bkbm=bm; } + WDL_VirtualWnd_BGCfg* GetBkImage() { return m_bkbm; } + int GetCharFromCoord(int xpos, int ypos); // for "AB", -1=out of bounds left, 0="A", 1="B", 2=out of bounds right + void SetWantPreserveTrailingNumber(bool preserve); // if the text ends in a number, make sure the number is always displayed + + protected: + WDL_VirtualWnd_BGCfg *m_bkbm; + int m_align; + bool m_dotint; + int m_fg,m_bg; + int m_margin_r, m_margin_l; + int m_margin_t, m_margin_b; + bool m_wantborder; + bool m_wantsingle; + bool m_wantabbr; + LICE_IFont *m_font,*m_vfont; + WDL_String m_text; + bool m_didvert; // true if text was drawn vertically on the last paint + int m_didalign; // the actual alignment used on the last paint +}; + +class WDL_VirtualComboBox : public WDL_VWnd +{ + public: + WDL_VirtualComboBox(); + virtual ~WDL_VirtualComboBox(); + virtual const char *GetType() { return "vwnd_combobox"; } + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual int OnMouseDown(int xpos, int ypos); + + void SetFont(LICE_IFont *font) { m_font=font; } + LICE_IFont *GetFont() { return m_font; } + void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right + + int GetCurSel() { if (m_items.Get(m_curitem)) return m_curitem; return -1; } + void SetCurSel(int sel) { if (!m_items.Get(sel)) sel=-1; if (m_curitem != sel) { m_curitem=sel; RequestRedraw(NULL); } } + + int GetCount() { return m_items.GetSize(); } + void Empty() { m_items.Empty(true,free); m_itemdatas.Empty(); } + + int AddItem(const char *str, void *data=NULL) { m_items.Add(strdup(str)); m_itemdatas.Add(data); return m_items.GetSize()-1; } + const char *GetItem(int item) { return m_items.Get(item); } + void *GetItemData(int item) { return m_itemdatas.Get(item); } + + + protected: + int m_align; + int m_curitem; + LICE_IFont *m_font; + + WDL_PtrList m_items; + WDL_PtrList m_itemdatas; +}; + + + +class WDL_VirtualSlider : public WDL_VWnd +{ + public: + WDL_VirtualSlider(); + virtual ~WDL_VirtualSlider(); + virtual const char *GetType() { return "vwnd_slider"; } + + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual int OnMouseDown(int xpos, int ypos); + virtual void OnMouseMove(int xpos, int ypos); + virtual void OnMouseUp(int xpos, int ypos); + virtual bool OnMouseDblClick(int xpos, int ypos); + virtual bool OnMouseWheel(int xpos, int ypos, int amt); + virtual void GetPositionPaintExtent(RECT *r); + + virtual void OnCaptureLost(); + + void SetBGCol1Callback(int msg) { m_bgcol1_msg=msg; } + void SetScrollMessage(int msg) { m_scrollmsg=msg; } + void SetRange(int minr, int maxr, int center) { m_minr=minr; m_maxr=maxr; m_center=center; } + void GetRange(int *minr, int *maxr, int *center) { if (minr) *minr=m_minr; if (maxr) *maxr=m_maxr; if (center) *center=m_center; } + int GetSliderPosition(); + void SetSliderPosition(int pos); + bool GetIsVert(); + void SetNotifyOnClick(bool en) { m_sendmsgonclick=en; } // default false + + void SetDblClickCallback(int msg) { m_dblclickmsg=msg; } + int GetDblClickCallback() { return m_dblclickmsg; } + + void SetGrayed(bool grayed) { m_grayed = grayed; } + + void GetButtonSize(int *w, int *h); + + void SetSkinImageInfo(WDL_VirtualSlider_SkinConfig *cfg, WDL_VirtualWnd_BGCfg *knobbg=NULL, WDL_VirtualWnd_BGCfg *knobbgsm=NULL, WDL_VirtualWnd_BGCfg *knobstacks=NULL, int nknobstacks=0) + { + m_skininfo=cfg; + m_knobbg[0]=knobbgsm; + m_knobbg[1]=knobbg; + m_knobstacks=knobstacks; + m_nknobstacks=nknobstacks; + } + + void SetFGColors(int knobcol, int zlcol) { m_knob_color=knobcol; m_zl_color = zlcol; } + void SetKnobBias(int knobbias, int knobextrasize=0) { m_knobbias=knobbias; m_knob_lineextrasize=knobextrasize; } // 1=force knob, -1=prevent knob + + protected: + WDL_VirtualSlider_SkinConfig *m_skininfo; + WDL_VirtualWnd_BGCfg *m_knobbg[2]; + WDL_VirtualWnd_BGCfg *m_knobstacks; + int m_nknobstacks; + + int m_bgcol1_msg; + int m_scrollmsg; + int m_dblclickmsg; + + void OnMoveOrUp(int xpos, int ypos, int isup); + int m_minr, m_maxr, m_center, m_pos; + + int m_tl_extra, m_br_extra; + + int m_knob_color,m_zl_color; + + signed char m_knobbias; + signed char m_knob_lineextrasize; + bool m_captured; + bool m_needflush; + bool m_sendmsgonclick; + bool m_grayed; + bool m_is_knob; +}; + + +#define WDL_VWND_LISTBOX_ARROWINDEX 0x10000000 +#define WDL_VWND_LISTBOX_ARROWINDEX_LR 0x10000001 + +class WDL_VirtualListBox : public WDL_VWnd +{ + public: + WDL_VirtualListBox(); + virtual ~WDL_VirtualListBox(); + virtual const char *GetType() { return "vwnd_listbox"; } + + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual int OnMouseDown(int xpos, int ypos); + virtual bool OnMouseDblClick(int xpos, int ypos); + virtual bool OnMouseWheel(int xpos, int ypos, int amt); + virtual void OnMouseMove(int xpos, int ypos); + virtual void OnMouseUp(int xpos, int ypos); + + void SetFont(LICE_IFont *font) { m_font=font; } + LICE_IFont *GetFont() { return m_font; } + void SetAlign(int align) { m_align=align; } // -1=left,0=center,1=right + void SetRowHeight(int rh) { m_rh=rh; } + void SetMaxColWidth(int cw) { m_maxcolwidth=cw; } // 0 = default = allow any sized columns + void SetMinColWidth(int cw) { m_mincolwidth = cw; } // 0 = default = full width columns + void SetMargins(int l, int r) { m_margin_l=l; m_margin_r=r; } + void SetScrollButtonSize(int sz) { m_scrollbuttonsize=sz; } // def 14 + int GetRowHeight() { return m_rh; } + int GetMaxColWidth() { return m_maxcolwidth; } + int GetMinColWidth() { return m_mincolwidth; } + + void SetDroppedMessage(int msg) { m_dropmsg=msg; } + void SetClickedMessage(int msg) { m_clickmsg=msg; } + void SetDragBeginMessage(int msg) { m_dragbeginmsg=msg; } + int IndexFromPt(int x, int y); + bool GetItemRect(int item, RECT *r); // returns FALSE if not onscreen + + void SetGrayed(bool grayed) { m_grayed=grayed; } + + void SetViewOffset(int offs); + int GetViewOffset(); + + RECT *GetScrollButtonRect(bool isDown) { return m_lastscrollbuttons[isDown?1:0].left + +#include +#if !defined(_MSC_VER) || _MSC_VER < 1600 +#include +#else +#include +#endif + + +#include "virtwnd-controls.h" +#include "../wdltypes.h" +#include "../wdlcstring.h" + +static BSTR SysAllocStringUTF8(const char *str) +{ + WCHAR tmp[1024]; + int slen = strlen(str)+1; + WCHAR *wstr = slen < 1000 ? tmp : (WCHAR*)malloc(2*slen+32); + + wstr[0]=0; + int a=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,slen,wstr, slen<1000?1024:slen+16); + if (!a) + { + wstr[0]=0; + a=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,str,slen,wstr,slen<1000?1024:slen+16); + } + + BSTR ret = SysAllocString(wstr); + if (wstr != tmp) free(wstr); + return ret; +} + +class CVWndAccessible; +class VWndBridge : public WDL_VWnd_IAccessibleBridge +{ +public: + VWndBridge() { } + ~VWndBridge() { } + virtual void Release() { vwnd=0; } + + CVWndAccessible *par; + WDL_VWnd *vwnd; + +}; +static IAccessible *GetVWndIAccessible(WDL_VWnd *vwnd); + +static int g_freelist_acc_size; +static CVWndAccessible *g_freelist_acc; + +static HRESULT (WINAPI *__CreateStdAccessibleObject)( + HWND hwnd, + LONG idObject, + REFIID riidInterface, + void **ppvObject +); + + +static int allocated_cnt; +class CVWndAccessible : public IAccessible +{ +public: + CVWndAccessible(WDL_VWnd *vwnd) + { + m_br.vwnd=vwnd; + m_br.par = this; + m_refCnt = 1; + allocated_cnt++; + } + ~CVWndAccessible() + { + allocated_cnt--; + //char buf[512]; + //sprintf(buf,"allocated total = %d\n",allocated_cnt); + // OutputDebugString(buf); + } + + //IUnknown interface + STDMETHOD_(HRESULT, QueryInterface)(REFIID riid , void **ppObj) + { + if (IsEqualIID(riid, IID_IUnknown)) + { + *ppObj = this; + } + else if (IsEqualIID(riid, IID_IAccessible)) + { + *ppObj = this; + } + else if (IsEqualIID(riid, IID_IDispatch)) + { + *ppObj = this; + } + else + { + *ppObj = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; + } + STDMETHOD_(ULONG, AddRef)() + { + return InterlockedIncrement(&m_refCnt); + } + STDMETHOD_(ULONG, Release)() + { + LONG nRefCount=0; + nRefCount=InterlockedDecrement(&m_refCnt) ; + if (nRefCount == 0) + { + if (m_br.vwnd) + { + m_br.vwnd->SetAccessibilityBridge(NULL); + m_br.vwnd=0; + } + + if (g_freelist_acc_size<2048) + { + g_freelist_acc_size++; + _freelist_next = g_freelist_acc; + g_freelist_acc = this; + } + else + { + delete this; + } + } + return nRefCount; + } + + + //IDispatch + STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo ) + { + *pctinfo=0; + return NOERROR; + } + STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) + { + return S_OK; + } + STDMETHOD( GetIDsOfNames)( + REFIID riid, + OLECHAR FAR* FAR* rgszNames, + unsigned int cNames, + LCID lcid, + DISPID FAR* rgDispId + ) + { + *rgDispId=0; + return E_OUTOFMEMORY; + } + + STDMETHOD(Invoke)( + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS FAR* pDispParams, + VARIANT FAR* pVarResult, + EXCEPINFO FAR* pExcepInfo, + unsigned int FAR* puArgErr + ) + { + return DISP_E_BADPARAMCOUNT; + } + + // IAccessible + + + STDMETHOD(get_accParent)(THIS_ IDispatch * FAR* ppdispParent) + { + WDL_VWnd *par=m_br.vwnd ? m_br.vwnd->GetParent() : NULL; + if (par) + { + *ppdispParent = GetVWndIAccessible(par); + if (*ppdispParent) return S_OK; + } + + *ppdispParent = NULL; + return S_FALSE; + } +#define ISVWNDLIST(x) ((x)&&!strcmp((x)->GetType(),"vwnd_listbox")) + STDMETHOD(get_accChildCount)(THIS_ long FAR* pChildCount) + { + *pChildCount = m_br.vwnd ? m_br.vwnd->GetNumChildren() : 0; + HWND realparent; + if (__CreateStdAccessibleObject && m_br.vwnd && !m_br.vwnd->GetParent() && (realparent=m_br.vwnd->GetRealParent())) + { + HWND h=GetWindow(realparent,GW_CHILD); + while (h) + { + (*pChildCount) += 1; + h=GetWindow(h,GW_HWNDNEXT); + } + } + + if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + int c = 0; + if (list->m_GetItemInfo) c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if(c<0)c=0; + *pChildCount += c+2; + } + return S_OK; + } + STDMETHOD(get_accChild)(THIS_ VARIANT varChildIndex, IDispatch * FAR* ppdispChild) + { + *ppdispChild=0; + if (!m_br.vwnd || varChildIndex.vt != VT_I4) return E_INVALIDARG; + + WDL_VWnd *vw = m_br.vwnd->EnumChildren(varChildIndex.lVal-1); + if (vw) + { + *ppdispChild=GetVWndIAccessible(vw); + if (*ppdispChild) return S_OK; + } + + int index = varChildIndex.lVal-1 - m_br.vwnd->GetNumChildren(); + + if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + int c = 0; + if (list->m_GetItemInfo) c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if(c<0)c=0; + index -= c+2; + } + + + HWND realparent; + if (index >= 0 && __CreateStdAccessibleObject && m_br.vwnd && !m_br.vwnd->GetParent() && (realparent=m_br.vwnd->GetRealParent())) + { + HWND h=GetWindow(realparent,GW_CHILD); + while (h) + { + if (!index) break; + index--; + h=GetWindow(h,GW_HWNDNEXT); + } + + if (h) + { + *ppdispChild=0; + HRESULT res = __CreateStdAccessibleObject(h,OBJID_CLIENT,IID_IAccessible,(void**)ppdispChild); + if (SUCCEEDED(res)) + { + return S_OK; + } + + } + } + + + return S_FALSE; + } + + STDMETHOD(get_accName)(THIS_ VARIANT varChild, BSTR* pszOut) + { + *pszOut=NULL; + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (vw) + { + const char *txt=NULL; + const char *ctltype = vw->GetType(); + if (!strcmp(ctltype,"vwnd_iconbutton")) + txt = ((WDL_VirtualIconButton*)vw)->GetTextLabel(); + else if (!strcmp(ctltype,"vwnd_statictext")) + txt = ((WDL_VirtualStaticText*)vw)->GetText(); + else if (!strcmp(ctltype,"vwnd_combobox")) + txt = ((WDL_VirtualComboBox*)vw)->GetItem(((WDL_VirtualComboBox*)vw)->GetCurSel()); + + const char *p = vw->GetAccessDesc(); + if (p && *p && txt && *txt) + { + char buf[1024]; + sprintf(buf,"%.500s %.500s",p,txt); + *pszOut= SysAllocStringUTF8(buf); + } + else if (txt && *txt) + { + *pszOut= SysAllocStringUTF8(txt); + } + else if (p && *p) + { + *pszOut = SysAllocStringUTF8(p); + } + } + else if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); + int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + char buf[2048]; + buf[0]=0; + if (idx>=0&&idxm_GetItemInfo(list,idx,buf,512,NULL,NULL); + else if (idx==ni||idx==ni+1) + { + strcpy(buf,idx==ni?"Scroll previous" : "Scroll next"); + } + + // we put this in the desc field instead + /*const char *txt1 = list->GetAccessDesc(); + if (txt1) + { + if (buf[0]) strcat(buf," "); + lstrcpyn_safe(buf+strlen(buf),txt1,512); + }*/ + +// OutputDebugString(buf); + if (buf[0]) + *pszOut = SysAllocStringUTF8(buf); + } + } + return S_OK; + + } + STDMETHOD(get_accValue)(THIS_ VARIANT varChild, BSTR* pszValue) + { + *pszValue=NULL; + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + return DISP_E_MEMBERNOTFOUND; + } + STDMETHOD(get_accDescription)(THIS_ VARIANT varChild, BSTR FAR* pszOut) + { + *pszOut=NULL; + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + if (vw) + { + char buf[1024]; + buf[0]=0; + WDL_VWnd *p = vw->GetParent(); + if (0) // disabled for now + while (p && strlen(buf)<800) + { + const char *txt= p->GetAccessDesc(); + if (txt && *txt) + { + if (buf[0]) strcat(buf," "); + lstrcpyn_safe(buf+strlen(buf),txt,200); + } + p=p->GetParent(); + } + if (buf[0]) + { + *pszOut = SysAllocStringUTF8(buf); + return S_OK; + } + return S_FALSE; + } + else if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + const char *txt = list->GetAccessDesc(); + if (txt) + { + *pszOut = SysAllocStringUTF8(txt); + return S_OK; + } + } + } + return E_INVALIDARG; + } + + STDMETHOD(get_accRole)(THIS_ VARIANT varChild, VARIANT *pvarRole) + { + if (!m_br.vwnd || varChild.vt != VT_I4) + { + pvarRole->vt = VT_EMPTY; + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw && ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); + int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if (idx>=0&&idxvt = VT_I4; + pvarRole->lVal = ROLE_SYSTEM_LISTITEM; + return S_OK; + } + else if (idx==ni || idx==ni+1) + { + pvarRole->vt = VT_I4; + pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON; + return S_OK; + } + } + } + + if (!vw) + { + pvarRole->vt = VT_EMPTY; + return E_INVALIDARG; + } + + pvarRole->vt = VT_I4; + if (vw->GetNumChildren()) pvarRole->lVal = ROLE_SYSTEM_GROUPING; + else + { + + const char *type = vw->GetType(); + + if (!strcmp(type,"vwnd_iconbutton")) + { + WDL_VirtualIconButton *vb = (WDL_VirtualIconButton*)vw; + if (vb->GetIsButton()) + { + if (vb->GetCheckState()>=0) pvarRole->lVal = ROLE_SYSTEM_CHECKBUTTON; + else pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON; + } + else + pvarRole->lVal = ROLE_SYSTEM_STATICTEXT; + } + else if (!strcmp(type,"vwnd_statictext")) pvarRole->lVal = ROLE_SYSTEM_STATICTEXT; + else if (!strcmp(type,"vwnd_combobox")) pvarRole->lVal = ROLE_SYSTEM_COMBOBOX; + else if (!strcmp(type,"vwnd_slider")) pvarRole->lVal = ROLE_SYSTEM_SLIDER; + else if (!strcmp(type,"vwnd_listbox")) pvarRole->lVal = ROLE_SYSTEM_LIST; + else pvarRole->lVal=ROLE_SYSTEM_CLIENT; + } + + return S_OK; + } + + STDMETHOD(get_accState)(THIS_ VARIANT varChild, VARIANT *pvarState) + { + if (!m_br.vwnd || varChild.vt != VT_I4) + { + pvarState->vt = VT_EMPTY; + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw) + { + if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + int index = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); + int c=list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if (index>=0&&indexvt = VT_I4; + pvarState->lVal = 0; + RECT r; + if (list->GetItemRect(index,&r)) + { + } + else + pvarState->lVal|=STATE_SYSTEM_INVISIBLE; + + return S_OK; + } + else if (index==c||index==c+1) + { + pvarState->vt = VT_I4; + pvarState->lVal = 0; + if (!list->GetScrollButtonRect(index==c+1)) + pvarState->lVal |= STATE_SYSTEM_UNAVAILABLE; + return S_OK; + + } + } + } + + pvarState->vt = VT_EMPTY; + return E_INVALIDARG; + } + + const char *type = vw->GetType(); + pvarState->vt = VT_I4; + pvarState->lVal = 0; + if (!vw->IsVisible()) pvarState->lVal |= STATE_SYSTEM_INVISIBLE; + + if (!strcmp(type,"vwnd_iconbutton")) + { + WDL_VirtualIconButton *vb = (WDL_VirtualIconButton*)vw; + if (vb->GetIsButton()) + { + if (vb->GetCheckState()>0) pvarState->lVal |= STATE_SYSTEM_CHECKED; + } + } + + return S_OK; + } + STDMETHOD(get_accHelp)(THIS_ VARIANT varChild, BSTR* pszHelp) + { + *pszHelp=NULL; + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw) + { + return E_INVALIDARG; + } + return S_FALSE; + } + STDMETHOD(get_accHelpTopic)(THIS_ BSTR* pszHelpFile, VARIANT varChild, long* pidTopic) + { + return DISP_E_MEMBERNOTFOUND; + } + STDMETHOD(get_accKeyboardShortcut)(THIS_ VARIANT varChild, BSTR* pszKeyboardShortcut) + { + *pszKeyboardShortcut=NULL; + + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw) + { + return E_INVALIDARG; + } + return S_FALSE; + } + STDMETHOD(get_accFocus)(THIS_ VARIANT FAR * pvarFocusChild) + { + pvarFocusChild->vt= VT_EMPTY; + if (!m_br.vwnd) + { + return S_FALSE; + } + //return DISP_E_MEMBERNOTFOUND; + + if (!m_br.vwnd->GetParent() && + m_br.vwnd->GetRealParent() && + GetFocus()==m_br.vwnd->GetRealParent()) + { + pvarFocusChild->vt=VT_I4; + pvarFocusChild->lVal = CHILDID_SELF; + } + return S_OK; + } + STDMETHOD(get_accSelection)(THIS_ VARIANT FAR * pvarSelectedChildren) + { + pvarSelectedChildren->vt= VT_EMPTY; + if (!m_br.vwnd) + { + return S_FALSE; + } + return S_OK; + } + STDMETHOD(get_accDefaultAction)(THIS_ VARIANT varChild, BSTR* pszDefaultAction) + { + *pszDefaultAction=NULL; + + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw) + { + return E_INVALIDARG; + } + return S_FALSE; + } + + STDMETHOD(accSelect)(THIS_ long flagsSelect, VARIANT varChild) + { + return S_FALSE; + } + STDMETHOD(accLocation)(THIS_ long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild) + { + *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; + if (!m_br.vwnd || varChild.vt != VT_I4) + { + return E_INVALIDARG; + } + WDL_VWnd *vw = varChild.lVal == CHILDID_SELF ? m_br.vwnd : m_br.vwnd->EnumChildren(varChild.lVal-1); + + if (!vw && ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + int idx = varChild.lVal-1 - m_br.vwnd->GetNumChildren(); + int ni = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if (idx>=0&&idxGetItemRect(idx,&r2)) + { + HWND h = list->GetRealParent(); + RECT r; + list->GetPositionInTopVWnd(&r); + ClientToScreen(h,(LPPOINT)&r); + ClientToScreen(h,((LPPOINT)&r)+1); + *pxLeft=r.left+r2.left; + *pyTop=r.top+r2.top; + *pcxWidth=r2.right-r2.left; + *pcyHeight=r2.bottom-r2.top; + } + else *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; + return S_OK; + } + else if (idx==ni||idx==ni+1) + { + RECT *rr = list->GetScrollButtonRect(idx==ni+1); + if (rr) + { + HWND h = list->GetRealParent(); + RECT r; + list->GetPositionInTopVWnd(&r); + ClientToScreen(h,(LPPOINT)&r); + ClientToScreen(h,((LPPOINT)&r)+1); + *pxLeft=r.left+rr->left; + *pyTop=r.top+rr->top; + *pcxWidth=rr->right-rr->left; + *pcyHeight=rr->bottom-rr->top; + } + else *pxLeft=*pyTop=*pcxWidth=*pcyHeight=0; + return S_OK; + + } + } + } + if (!vw) return E_INVALIDARG; + + HWND h = vw->GetRealParent(); + if (h) + { + RECT r; + vw->GetPositionInTopVWnd(&r); + ClientToScreen(h,(LPPOINT)&r); + ClientToScreen(h,((LPPOINT)&r)+1); + *pxLeft=r.left; + *pyTop=r.top; + *pcxWidth=r.right-r.left; + *pcyHeight=r.bottom-r.top; + } + return S_OK; + } + + STDMETHOD(accNavigate)(THIS_ long navDir, VARIANT varStart, VARIANT * pvarEndUpAt) + { + return DISP_E_MEMBERNOTFOUND; + } + STDMETHOD(accHitTest)(THIS_ long xLeft, long yTop, VARIANT * pvarChildAtPoint) + { + pvarChildAtPoint->vt = VT_EMPTY; + + if (!m_br.vwnd) + { + return E_INVALIDARG; + } + + HWND h = m_br.vwnd->GetRealParent(); + if (!h) return S_FALSE; + + POINT p={xLeft,yTop}; + ScreenToClient(h,&p); + if (!m_br.vwnd->GetParent() && __CreateStdAccessibleObject) + { + HWND hhit = ChildWindowFromPoint(h,p); + if (hhit && hhit != h) + { + pvarChildAtPoint->pdispVal=0; + HRESULT res = __CreateStdAccessibleObject(hhit,OBJID_CLIENT,IID_IAccessible,(void**)&pvarChildAtPoint->pdispVal); + if (SUCCEEDED(res)) + { + pvarChildAtPoint->vt = VT_DISPATCH; + return S_OK; + } + } + } + + RECT r; + m_br.vwnd->GetPositionInTopVWnd(&r); + if (!PtInRect(&r,p)) return S_FALSE; + + WDL_VWnd *vw = m_br.vwnd->VirtWndFromPoint(p.x-r.left,p.y-r.top,0); + if (vw&&vw != m_br.vwnd) + { + IAccessible *pac = GetVWndIAccessible(vw); + if (pac) + { + pvarChildAtPoint->vt = VT_DISPATCH; + pvarChildAtPoint->pdispVal = pac; + return S_OK; + } + } + else if (ISVWNDLIST(m_br.vwnd)) + { + WDL_VirtualListBox *list=(WDL_VirtualListBox*)m_br.vwnd; + if (list->m_GetItemInfo) + { + int c = list->m_GetItemInfo(list,-1,NULL,0,NULL,NULL); + if (c<0)c=0; + int a= list->IndexFromPt(p.x-r.left,p.y-r.top); + if (a>=0 && avt = VT_I4; + pvarChildAtPoint->lVal = 1+list->GetNumChildren()+a;; + return S_OK; + } + else + { + POINT pp = { p.x-r.left, p.y-r.top}; + int x; + for(x=0;x<2;x++) + { + RECT *rr = list->GetScrollButtonRect(!!x); + if (rr && PtInRect(rr,pp)) + { + pvarChildAtPoint->vt = VT_I4; + pvarChildAtPoint->lVal = 1+list->GetNumChildren()+c+x;; + return S_OK; + } + } + } + } + } + + pvarChildAtPoint->vt = VT_I4; + pvarChildAtPoint->lVal = CHILDID_SELF; + return S_OK; + } + STDMETHOD(accDoDefaultAction)(THIS_ VARIANT varChild) + { + return DISP_E_MEMBERNOTFOUND; + } + + STDMETHOD(put_accName)(THIS_ VARIANT varChild, BSTR szName) + { + return E_NOTIMPL; + } + + STDMETHOD(put_accValue)(THIS_ VARIANT varChild, BSTR pszValue) + { + return E_NOTIMPL; + } + + VWndBridge m_br; + LONG m_refCnt; + + CVWndAccessible *_freelist_next; + +}; + + +static IAccessible *GetVWndIAccessible(WDL_VWnd *vwnd) +{ + if (!vwnd) return 0; + + WDL_VWnd_IAccessibleBridge *br = vwnd->GetAccessibilityBridge(); + if (!br) + { + CVWndAccessible *acc; + if (g_freelist_acc) + { + g_freelist_acc_size--; + acc=g_freelist_acc; + g_freelist_acc=acc->_freelist_next; + + acc->m_br.vwnd = vwnd; + acc->m_refCnt = 1; + } + else + acc = new CVWndAccessible(vwnd); + + br = &acc->m_br; + vwnd->SetAccessibilityBridge(br); + } + else ((VWndBridge*)br)->par->AddRef(); + + return ((VWndBridge*)br)->par; +} + + +LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) +{ + if (vw) + { + if ((DWORD)lParam != (DWORD)OBJID_CLIENT) return 0; + + static LRESULT (WINAPI *__LresultFromObject)(REFIID riid, WPARAM, LPUNKNOWN); + + static int init; + if (!init) + { + init=1; + HINSTANCE hInst = LoadLibrary("oleacc.dll"); + if (hInst) + { + *(FARPROC *)&__LresultFromObject = GetProcAddress(hInst,"LresultFromObject"); + *(FARPROC *)&__CreateStdAccessibleObject = GetProcAddress(hInst,"CreateStdAccessibleObject"); + } + } + if (!__LresultFromObject) return 0; + + IAccessible *ac = GetVWndIAccessible(vw); + if (!ac) return 0; + + + LRESULT res = __LresultFromObject(IID_IAccessible,wParam,ac); // lresultfromobject retains? + ac->Release(); + if (isDialog) + { + SetWindowLongPtr(hwnd,DWLP_MSGRESULT,res); + return 1; + } + return res; + } + return 0; +} + + +#else + +#ifdef _WIN32 +#include +#else +#include "../swell/swell.h" +#endif + + +#ifdef __APPLE__ + +// see virtwnd-nsaccessibility.mm + +#else + + +class WDL_VWnd; +LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) +{ + return 0; +} + +#endif + +#endif diff --git a/WDL/wingui/virtwnd-iconbutton.cpp b/WDL/wingui/virtwnd-iconbutton.cpp new file mode 100644 index 00000000..7ff8b636 --- /dev/null +++ b/WDL/wingui/virtwnd-iconbutton.cpp @@ -0,0 +1,1118 @@ +/* + WDL - virtwnd-iconbutton.cpp + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Implementation for virtual window icon buttons, icons, combo boxes, and static text controls. + +*/ + +#include +#include "virtwnd-controls.h" +#include "../lice/lice.h" + +#ifdef _WIN32 +#define WDL_WIN32_UTF8_IMPL static +#include "../win32_utf8.c" +#endif + +WDL_VirtualIconButton::WDL_VirtualIconButton() +{ + m_alpha=1.0; + m_checkstate=-1; + m_textfont=0; + m_textfontv=0; + m_textalign=0; + m_bgcol1_msg=0; + m_is_button=true; + m_pressed=0; + m_iconCfg=0; + m_en=true; + m_grayed = false; + m_forceborder=false; + m_forcetext=false; + m_forcetext_color=0; + m_ownsicon=false; + m_immediate=false; + m_margin_r = m_margin_l = 0; + m_margin_t = m_margin_b = 0; +} + +WDL_VirtualIconButton::~WDL_VirtualIconButton() +{ + if (m_ownsicon && m_iconCfg) + { + delete m_iconCfg->image; + delete m_iconCfg->olimage; + delete m_iconCfg; + } +} + +void WDL_VirtualIconButton::SetTextLabel(const char *text) +{ + m_textlbl.Set(text); + if (!m_iconCfg || m_forcetext) RequestRedraw(NULL); +} + +void WDL_VirtualIconButton::SetTextLabel(const char *text, int align, LICE_IFont *font) +{ + if (font) m_textfont=font; + m_textalign=align; + m_textlbl.Set(text); + if (!m_iconCfg || m_forcetext) RequestRedraw(NULL); +} + +void WDL_VirtualIconButton::SetCheckState(char state) +{ + if (state != m_checkstate) + { + m_checkstate=state; + RequestRedraw(NULL); + } +} + +void WDL_VirtualIconButton::SetIcon(WDL_VirtualIconButton_SkinConfig *cfg, float alpha, bool buttonownsicon) +{ + if (m_iconCfg != cfg || m_alpha != alpha) + { + bool combineRects=false; + RECT r; + if (m_iconCfg && m_iconCfg != cfg && m_iconCfg->olimage) + { + combineRects=true; + GetPositionPaintExtent(&r); + if (WantsPaintOver()) + { + RECT r3; + GetPositionPaintOverExtent(&r3); + if (r3.leftr.right) r.right=r3.right; + if (r3.bottom>r.bottom) r.bottom=r3.bottom; + } + } + if (m_ownsicon && m_iconCfg && m_iconCfg != cfg) + { + delete m_iconCfg->image; + delete m_iconCfg->olimage; + delete m_iconCfg; + } + m_alpha=alpha; + m_iconCfg=cfg; + + if (combineRects) + { + RECT r3; + GetPositionPaintExtent(&r3); + if (r3.leftr.right) r.right=r3.right; + if (r3.bottom>r.bottom) r.bottom=r3.bottom; + + if (WantsPaintOver()) + { + GetPositionPaintOverExtent(&r3); + if (r3.leftr.right) r.right=r3.right; + if (r3.bottom>r.bottom) r.bottom=r3.bottom; + } + + r.left -= m_position.left; + r.right -= m_position.left; + r.top -= m_position.top; + r.bottom -= m_position.top; + RequestRedraw(&r); + } + else + { + RequestRedraw(NULL); + } + } + m_ownsicon = buttonownsicon; + } + +void WDL_VirtualIconButton::OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + if (m_iconCfg && m_iconCfg->olimage) + { + int sx=0; + int sy=0; + int w=m_iconCfg->olimage->getWidth(); + int h=m_iconCfg->olimage->getHeight(); + if (m_iconCfg->image_ltrb_used.flags&1) { w-=2; h-= 2; sx++,sy++; } + + w/=3; + + if (w>0 && h>0) + { + if (m_is_button) + { + if ((m_pressed&2)) sx+=(m_pressed&1) ? w*2 : w; + } + + if (m_iconCfg->image_ltrb_used.flags&2) // use main image's stretch areas (outer areas become unstretched) + { + WDL_VirtualWnd_BGCfg cfg={0,}; + LICE_SubBitmap sb(m_iconCfg->olimage,sx,sy,w,h); + cfg.bgimage = &sb; + cfg.bgimage_lt[0] = m_iconCfg->image_ltrb_main[0]+1; // image_ltrb_main expects 1-based number + cfg.bgimage_lt[1] = m_iconCfg->image_ltrb_main[1]+1; + cfg.bgimage_rb[0] = m_iconCfg->image_ltrb_main[2]+1; + cfg.bgimage_rb[1] = m_iconCfg->image_ltrb_main[3]+1; + cfg.bgimage_lt_out[0] = m_iconCfg->image_ltrb_ol[0]+1; + cfg.bgimage_lt_out[1] = m_iconCfg->image_ltrb_ol[1]+1; + cfg.bgimage_rb_out[0] = m_iconCfg->image_ltrb_ol[2]+1; + cfg.bgimage_rb_out[1] = m_iconCfg->image_ltrb_ol[3]+1; + cfg.bgimage_noalphaflags=0; + + RECT r=m_position,r2; + GetPositionPaintOverExtent(&r2); + WDL_VirtualWnd_ScaledBlitBG(drawbm,&cfg, + r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, + r2.left+origin_x,r2.top+origin_y,r2.right-r2.left,r2.bottom-r2.top, + m_alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + } + else + { + RECT r; + GetPositionPaintOverExtent(&r); + LICE_ScaledBlit(drawbm,m_iconCfg->olimage,r.left+origin_x,r.top+origin_y, + r.right-r.left, + r.bottom-r.top, + (float)sx,(float)sy,(float)w,(float)h, m_alpha, // m_grayed? + LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + } + } + } +} + + +void WDL_VirtualIconButton::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + HDC hdc=drawbm->getDC(); + int col; + + float alpha = (m_grayed ? 0.25f : 1.0f) * m_alpha; + + bool isdown = !!(m_pressed&1); + bool ishover = !!(m_pressed&2); + + if (m_iconCfg && m_iconCfg->image && !m_iconCfg->image_issingle) + { + bool swapupdown = (m_checkstate > 0); + bool isdownimg = (swapupdown != isdown); + + RECT r=m_position; + + int sx=0; + int sy=0; + int w=m_iconCfg->image->getWidth(); + int h=m_iconCfg->image->getHeight(); + + if (w>0 && (m_iconCfg->image_ltrb_used.flags&2)) + w-=2; + + w/=3; + if (w>0 && h > 0) + { + if (m_is_button) + { + if (isdownimg) sx += w*2; + else if (ishover) sx += w; + } + + + if (m_iconCfg->image_ltrb_used.flags&2) + { + WDL_VirtualWnd_BGCfg cfg={0,}; + LICE_SubBitmap sb(m_iconCfg->image,sx+1,sy+1,w,h-2); + cfg.bgimage = &sb; + cfg.bgimage_lt[0] = m_iconCfg->image_ltrb_main[0]+1; // image_ltrb_main expects 1-based number + cfg.bgimage_lt[1] = m_iconCfg->image_ltrb_main[1]+1; + cfg.bgimage_rb[0] = m_iconCfg->image_ltrb_main[2]+1; + cfg.bgimage_rb[1] = m_iconCfg->image_ltrb_main[3]+1; + cfg.bgimage_noalphaflags=0; + + WDL_VirtualWnd_ScaledBlitBG(drawbm,&cfg, + r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, + r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, + alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + + } + else + LICE_ScaledBlit(drawbm,m_iconCfg->image,r.left+origin_x,r.top+origin_y, + r.right-r.left, + r.bottom-r.top, + (float)sx,(float)sy,(float)w,(float)h, alpha, + LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + } + } + else + { + RECT r=m_position; + r.left+=origin_x; + r.right+=origin_x; + r.top+=origin_y; + r.bottom+=origin_y; + if (m_is_button) + { + if (WDL_STYLE_WantGlobalButtonBackground(&col)) + { + LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,LICE_RGBA_FROMNATIVE(col,255),alpha,LICE_BLIT_MODE_COPY); + } + + if (ishover || m_forceborder || WDL_STYLE_WantGlobalButtonBorders()) + { + int cidx=isdown?COLOR_3DSHADOW:COLOR_3DHILIGHT; + + int pencol = GSC(cidx); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + + LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); + cidx = isdown?COLOR_3DHILIGHT:COLOR_3DSHADOW; + pencol = GSC(cidx); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); + } + } + if (m_iconCfg && m_iconCfg->image) + { + int sz=16,sz2=16; + WDL_STYLE_ScaleImageCoords(&sz,&sz2); + + //if (m_position.right-m_position.left > 24) sz=m_position.right-m_position.left-8; + + int x=r.left+((r.right-r.left)-sz)/2; + int y=r.top+((r.bottom-r.top)-sz2)/2; + if (m_is_button) + { + if (isdown && ishover) { x++; y++; } + } + + LICE_ScaledBlit(drawbm,m_iconCfg->image,x,y,sz,sz2,0.0f,0.0f, + (float)m_iconCfg->image->getWidth(), + (float)m_iconCfg->image->getHeight(),alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + + } + } + + if (!m_iconCfg || m_forcetext) + { + RECT r2=m_position; + r2.left+=origin_x; + r2.right+=origin_x; + r2.top+=origin_y; + r2.bottom+=origin_y; + + if (m_checkstate>=0 && !m_iconCfg) + { + RECT tr=r2; + int sz=tr.bottom-tr.top; + r2.left+=sz+2; + + tr.top+=2; + tr.bottom-=2; + sz-=4; + sz&=~1; + LICE_FillRect(drawbm ,tr.left,tr.top,sz,sz,LICE_RGBA(255,255,255,255),alpha,LICE_BLIT_MODE_COPY); + LICE_Line(drawbm,tr.left,tr.top,tr.left+sz,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,tr.left+sz,tr.top,tr.left+sz,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,tr.left+sz,tr.bottom,tr.left,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,tr.left,tr.bottom,tr.left,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); + int nl = (m_checkstate>0) ? 3:0; + if (isdown) nl ^= 2; + + if (nl&1) + LICE_Line(drawbm,tr.left+2,tr.bottom-2,tr.left+sz-2,tr.top+2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); + if (nl&2) + LICE_Line(drawbm,tr.left+2,tr.top+2,tr.left+sz-2,tr.bottom-2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); + + + } + + LICE_IFont *font = m_textfont; + bool isVert=false; + if (font && m_textfontv && m_position.right-m_position.left < m_position.bottom - m_position.top) + { + isVert=true; + font = m_textfontv; + } + // draw text + if (font&&m_textlbl.Get()[0]) + { + int fgc=m_forcetext_color ? m_forcetext_color : LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); + //font->SetCombineMode(LICE_BLIT_MODE_COPY, alpha); // this affects the glyphs that get cached + font->SetBkMode(TRANSPARENT); + font->SetTextColor(fgc); + + r2.left += m_margin_l; + r2.right -= m_margin_r; + r2.top += m_margin_t; + r2.bottom -= m_margin_b; + + if (isdown) + { + if (m_textalign<0) r2.left+=1; + else if (m_textalign>0) r2.right+=1; + else r2.left+=2; + r2.top+=2; + } + int f = DT_SINGLELINE|DT_NOPREFIX; + if (isVert) + { + f |= DT_CENTER | (m_textalign<0?DT_TOP:m_textalign>0?DT_BOTTOM:DT_VCENTER); + } + else + { + f |= DT_VCENTER|(m_textalign<0?DT_LEFT:m_textalign>0?DT_RIGHT:DT_CENTER); + } + font->DrawText(drawbm,m_textlbl.Get(),-1,&r2,f); + } + + } + + if (m_bgcol1_msg) + { + int brcol=-100; + SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); + if (brcol != -100) + { + RECT r=m_position; + + int bh=(r.bottom-r.top)/5; + if (bh<1) bh=1; + int bw=(r.right-r.left)/5; + if (bw<1) bw=1; + + LICE_FillRect(drawbm, + r.left+origin_x,r.top+origin_y, + r.right-r.left, + bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); + + LICE_FillRect(drawbm, + r.left+origin_x,r.top+origin_y+bh, + bw, + r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); + + LICE_FillRect(drawbm, + r.right+origin_x-bw,r.top+origin_y+bh, + bw, + r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); + + LICE_FillRect(drawbm, + r.left+origin_x,r.bottom+origin_y-bh, + r.right-r.left, + bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); + } + } + +} + + +void WDL_VirtualIconButton::OnMouseMove(int xpos, int ypos) +{ + if (m_en&&m_is_button) + { + int wp=m_pressed; + + WDL_VWnd *parhit = GetParent(); + if (parhit) + { + parhit = parhit->VirtWndFromPoint(m_position.left+xpos,m_position.top+ypos,0); + } + + if (parhit == this) + { + m_pressed|=2; + } + else + { + m_pressed&=~2; + } + + if ((m_pressed&3)!=(wp&3)) + { + RequestRedraw(NULL); + } + } +} + +int WDL_VirtualIconButton::OnMouseDown(int xpos, int ypos) +{ + if (m_en&&m_is_button) + { + m_pressed=3; + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnFocused(); + + if (m_immediate) + { + DoSendCommand(xpos, ypos); + } + + return 1; + } + return 0; +} + +bool WDL_VirtualIconButton::OnMouseDblClick(int xpos, int ypos) +{ + if (m_is_button) + { + DoSendCommand(xpos, ypos); + return true; + } + return false; +} + +void WDL_VirtualIconButton::OnMouseUp(int xpos, int ypos) +{ + if (!m_is_button) return; + + int waspress=!!m_pressed; + m_pressed&=~1; + RequestRedraw(NULL); + + if (waspress && !m_immediate) + { + DoSendCommand(xpos, ypos); + } +} + +void WDL_VirtualIconButton::DoSendCommand(int xpos, int ypos) +{ + if (m_en && + xpos >= 0 && + xpos < m_position.right-m_position.left && + ypos >= 0 && + ypos < m_position.bottom-m_position.top) + { + int code=GetID(); + if (!m_iconCfg && m_textlbl.Get()[0] && m_checkstate >= 0) + { + if (xpos < m_position.bottom-m_position.top) + { + code|=600<<16; + } + } + WDL_VWND_DCHK(a); + SendCommand(WM_COMMAND,code,0,this); + if (a.isOK() && m__iaccess && m_checkstate>=0) m__iaccess->OnStateChange(); + } +} + + +WDL_VirtualComboBox::WDL_VirtualComboBox() +{ + m_font=0; + m_align=-1; + m_curitem=-1; +} + +WDL_VirtualComboBox::~WDL_VirtualComboBox() +{ + m_items.Empty(true,free); +} + + +static void GenSubMenu(HMENU menu, int *x, WDL_PtrList *items, int curitem) +{ + int pos=0; + while (*x < items->GetSize()) + { + MENUITEMINFO mi={sizeof(mi),MIIM_ID|MIIM_STATE|MIIM_TYPE,MFT_STRING, 0,1000+*x,NULL,NULL,NULL,0}; + mi.dwTypeData = (char *)items->Get(*x); + mi.fState = curitem == *x ?MFS_CHECKED:0; + + (*x) ++; // advance to next item + + if (!strcmp(mi.dwTypeData,"")) mi.fType=MFT_SEPARATOR; + else if (!strcmp(mi.dwTypeData,"")) break; // done! + else if (!strncmp(mi.dwTypeData,"",5)) + { + mi.hSubMenu= CreatePopupMenu(); + GenSubMenu(mi.hSubMenu,x,items,curitem); + mi.fMask |= MIIM_SUBMENU; + mi.dwTypeData += 5; // skip + } + InsertMenuItem(menu,pos++,TRUE,&mi); + } +} + +int WDL_VirtualComboBox::OnMouseDown(int xpos, int ypos) +{ + if (m__iaccess) m__iaccess->OnFocused(); + if (m_items.GetSize()) + { + //SendCommand(WM_COMMAND, GetID()|(CBN_DROPDOWN<<16), 0, this); + + HMENU menu=CreatePopupMenu(); + int x=0; + GenSubMenu(menu,&x,&m_items,m_curitem); + + HWND h=GetRealParent(); + POINT p={0,}; + WDL_VirtualWnd *w=this; + while (w) + { + RECT r; + w->GetPosition(&r); + p.x+=r.left; + p.y+=w==this?r.bottom:r.top; + w=w->GetParent(); + } + if (h) + { + ClientToScreen(h,&p); + //SetFocus(h); + } + + int ret=TrackPopupMenu(menu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_NONOTIFY,p.x,p.y,0,h,NULL); + + if (ret>=1000) + { + m_curitem=ret-1000; + RequestRedraw(NULL); + // track menu + WDL_VWND_DCHK(a); + SendCommand(WM_COMMAND,GetID() | (CBN_SELCHANGE<<16),0,this); + if (a.isOK() && m__iaccess) m__iaccess->OnStateChange(); + } + } + return -1; +} + +void WDL_VirtualComboBox::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + { + if (m_font) m_font->SetBkMode(TRANSPARENT); + + RECT r=m_position; + r.left+=origin_x; + r.right+=origin_x; + r.top+=origin_y; + r.bottom+=origin_y; + + int col=GSC(COLOR_WINDOW); + col = LICE_RGBA_FROMNATIVE(col,255); + LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,col,1.0f,LICE_BLIT_MODE_COPY); + + { + RECT tr=r; + tr.left=tr.right-(tr.bottom-tr.top); + int col2=GSC(COLOR_BTNFACE); + col2 = LICE_RGBA_FROMNATIVE(col2,255); + + LICE_FillRect(drawbm,tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top,col,1.0f,LICE_BLIT_MODE_COPY); + } + + + int tcol=GSC(COLOR_BTNTEXT); + tcol=LICE_RGBA_FROMNATIVE(tcol,255); + if (m_font && m_items.Get(m_curitem)&&m_items.Get(m_curitem)[0]) + { + RECT tr=r; + tr.left+=2; + tr.right-=16; + m_font->SetTextColor(tcol); + m_font->DrawText(drawbm,m_items.Get(m_curitem),-1,&tr,DT_SINGLELINE|DT_VCENTER|(m_align<0?DT_LEFT:m_align>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); + } + + + // pen3=tcol + int pencol = GSC(COLOR_3DSHADOW); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + int pencol2 = GSC(COLOR_3DHILIGHT); + pencol2 = LICE_RGBA_FROMNATIVE(pencol2,255); + + // draw the down arrow button + { + int bs=(r.bottom-r.top); + int l=r.right-bs; + + int a=(bs/4)&~1; + + LICE_Line(drawbm,l,r.top,l,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,l-1,r.top,l-1,r.bottom-1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + + LICE_Line(drawbm,l+bs/2-a,r.top+bs/2-a/2, + l+bs/2,r.top+bs/2+a/2,tcol,1.0f,LICE_BLIT_MODE_COPY,true); + LICE_Line(drawbm,l+bs/2,r.top+bs/2+a/2, + l+bs/2+a,r.top+bs/2-a/2, tcol,1.0f,LICE_BLIT_MODE_COPY,true); + } + + + + // draw the border + LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,0,false); + LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,0,false); + LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol2,1.0f,0,false); + LICE_Line(drawbm,r.left,r.bottom-1,r.right-1,r.bottom-1,pencol2,1.0f,0,false); + + } +} + + + +WDL_VirtualStaticText::WDL_VirtualStaticText() +{ + m_dotint=false; + m_bkbm=0; + m_margin_r=m_margin_l=0; + m_margin_t=m_margin_b=0; + m_fg=m_bg=0; + m_wantborder=false; + m_vfont=m_font=0; + m_align=-1; + m_wantsingle=false; + m_didvert=0; + m_didalign=-1; + m_wantabbr=false; +} + +WDL_VirtualStaticText::~WDL_VirtualStaticText() +{ +} + +void WDL_VirtualStaticText::SetText(const char *text) +{ + if (strcmp(m_text.Get(),text)) + { + m_text.Set(text); + if (m_font) RequestRedraw(NULL); + } +} + +void WDL_VirtualStaticText::SetWantPreserveTrailingNumber(bool abbreviate) +{ + m_wantabbr=abbreviate; + if (m_font) RequestRedraw(NULL); +} + +void WDL_VirtualStaticText::GetPositionPaintExtent(RECT *r) +{ + // overridden in case m_bkbm has outer areas + *r = m_position; + if (m_bkbm && m_bkbm->bgimage) + { + if (m_bkbm->bgimage_lt[0]>0 && + m_bkbm->bgimage_lt[1]>0 && + m_bkbm->bgimage_rb[0]>0 && + m_bkbm->bgimage_rb[1]>0 && + m_bkbm->bgimage_lt_out[0]>0 && + m_bkbm->bgimage_lt_out[1]>0 && + m_bkbm->bgimage_rb_out[0]>0 && + m_bkbm->bgimage_rb_out[1]>0) + { + r->left -= m_bkbm->bgimage_lt_out[0]-1; + r->top -= m_bkbm->bgimage_lt_out[1]-1; + r->right += m_bkbm->bgimage_rb_out[0]-1; + r->bottom += m_bkbm->bgimage_rb_out[1]-1; + } + } +} + +int WDL_VirtualStaticText::OnMouseDown(int xpos, int ypos) +{ + int a = WDL_VWnd::OnMouseDown(xpos,ypos); + if (a) return a; + + if (m__iaccess) m__iaccess->OnFocused(); + + if (m_wantsingle) + { + SendCommand(WM_COMMAND,GetID() | (STN_CLICKED<<16),0,this); + return -1; + } + return 0; +} + +void WDL_VirtualStaticText::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + RECT r=m_position; + r.left+=origin_x; + r.right+=origin_x; + r.top += origin_y; + r.bottom += origin_y; + + if (m_bkbm && m_bkbm->bgimage) + { + WDL_VirtualWnd_ScaledBlitBG(drawbm,m_bkbm, + r.left,r.top,r.right-r.left,r.bottom-r.top, + r.left,r.top,r.right-r.left,r.bottom-r.top, + 1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + + if (m_dotint && LICE_GETA(m_bg)) + { + float amt = LICE_GETA(m_bg)/255.0f; + + // todo: apply amt + + float rv=LICE_GETR(m_bg)/255.0f; + float gv=LICE_GETG(m_bg)/255.0f; + float bv=LICE_GETB(m_bg)/255.0f; + + float avg=(rv+gv+bv)*0.33333f; + if (avg<0.05f)avg=0.05f; + + float sc=0.5f*amt; + float sc2 = (amt-sc)/avg; + + float sc3=32.0f * amt; + float sc4=64.0f*(avg-0.5f) * amt; + + // tint + LICE_MultiplyAddRect(drawbm, + r.left,r.top, + r.right-r.left, + r.bottom-r.top, + sc+rv*sc2 + (1.0-amt), + sc+gv*sc2 + (1.0-amt), + sc+bv*sc2 + (1.0-amt), + 1, + (rv-avg)*sc3+sc4, + (gv-avg)*sc3+sc4, + (bv-avg)*sc3+sc4, + 0); + } + } + else + { + if (LICE_GETA(m_bg)) + { + LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,m_bg,LICE_GETA(m_bg)/255.0f,LICE_BLIT_MODE_COPY); + } + + if (m_wantborder) + { + int cidx=COLOR_3DSHADOW; + + int pencol = GSC(cidx); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + + LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + cidx=COLOR_3DHILIGHT; + pencol = GSC(cidx); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + + r.left++; + r.bottom--; + r.top++; + r.right--; + + } + } + + if (m_text.Get()[0]) + { + r.left += m_margin_l; + r.right -= m_margin_r; + r.top += m_margin_t; + r.bottom -= m_margin_b; + + m_didvert=m_vfont && (r.right-r.left)<(r.bottom-r.top)/2; + LICE_IFont *font = m_didvert ? m_vfont : m_font; + + if (font) + { + font->SetBkMode(TRANSPARENT); + + m_didalign=m_align; + if (m_didalign==0) + { + RECT r2={0,0,0,0}; + font->DrawText(drawbm,m_text.Get(),-1,&r2,DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); + if (m_didvert) + { + if (r2.bottom > r.bottom-r.top) m_didalign=-1; + } + else + { + if (r2.right > r.right-r.left) m_didalign=-1; + } + } + + int dtflags=DT_SINGLELINE|DT_NOPREFIX; + + if (m_didvert) + { + dtflags |= DT_CENTER; + if (m_didalign < 0) dtflags |= DT_TOP; + else if (m_didalign > 0) dtflags |= DT_BOTTOM; + else dtflags |= DT_VCENTER; + } + else + { + dtflags|=DT_VCENTER; + + if (m_didalign < 0) dtflags |= DT_LEFT; + else if (m_didalign > 0) dtflags |= DT_RIGHT; + else dtflags |= DT_CENTER; + } + const char* txt=m_text.Get(); + + int abbrx=0; + char abbrbuf[64]; + abbrbuf[0]=0; + + if (m_wantabbr) + { + int len=strlen(txt); + if (len && isdigit(txt[len-1])) + { + RECT tr = { 0, 0, 0, 0 }; + font->DrawText(drawbm, txt, -1, &tr, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); + if (m_didvert ? (tr.bottom > r.bottom-r.top) : (tr.right > r.right-r.left)) + { + strcpy(abbrbuf, ".."); + int i; + for (i=len-1; i >= 0; --i) + { + if (!isdigit(txt[i]) || len-i > 4) break; + } + strcat(abbrbuf, txt+i+1); + + int f=dtflags&~(DT_TOP|DT_VCENTER|DT_BOTTOM|DT_LEFT|DT_CENTER|DT_RIGHT); + RECT tr2 = { 0, 0, 0, 0 }; + if (m_didvert) + { + font->DrawText(drawbm, abbrbuf, -1, &tr2, f|DT_CALCRECT); + abbrx=tr2.bottom; + } + else + { + font->DrawText(drawbm, abbrbuf, -1, &tr2, f|DT_CALCRECT); + abbrx=tr2.right; + } + } + } + } + + int tcol=m_fg ? m_fg : LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT)); + font->SetTextColor(tcol); + if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,LICE_GETA(m_fg)/255.0f); + + if (abbrx && abbrbuf[0]) + { + if (m_didvert) + { + int f=dtflags&~(DT_TOP|DT_VCENTER|DT_BOTTOM); + RECT r1 = { r.left, r.top, r.right, r.bottom-abbrx }; + font->DrawText(drawbm, txt, -1, &r1, f|DT_TOP); + RECT r2 = { r.left, r.bottom-abbrx, r.right, r.bottom }; + font->DrawText(drawbm, abbrbuf, -1, &r2, f|DT_BOTTOM); + } + else + { + int f=dtflags&~(DT_LEFT|DT_CENTER|DT_RIGHT); + RECT r1 = { r.left, r.top, r.right-abbrx, r.bottom }; + font->DrawText(drawbm, txt, -1, &r1, f|DT_LEFT); + RECT r2 = { r.right-abbrx, r.top, r.right, r.bottom }; + font->DrawText(drawbm, abbrbuf, -1, &r2, f|DT_RIGHT); + } + } + else + { + font->DrawText(drawbm,txt,-1,&r,dtflags); + } + + if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,1.0f); + } + + + } + WDL_VWnd::OnPaint(drawbm,origin_x,origin_y,cliprect); +} + + +int WDL_VirtualStaticText::GetCharFromCoord(int xpos, int ypos) +{ + LICE_IFont *font = (m_didvert ? m_vfont : m_font); + if (!font) return -1; + + const char* str = m_text.Get(); + int len = strlen(str); + if (!len) return -1; + + // for align left/right, we could DT_CALCRECT with 1 char, then 2, etc, but that won't work for align center + // so we'll just estimate + RECT tr = { 0, 0, m_position.right-m_position.left, m_position.bottom-m_position.top }; + font->DrawText(0, str, len, &tr, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT); + int tw = tr.right; + int th = tr.bottom; + + RECT r = m_position; + if (m_wantborder) + { + r.left++; + r.top++; + r.right--; + r.bottom--; + } + r.left += m_margin_l; + r.top += m_margin_t; + r.right -= m_margin_r; + r.bottom -= m_margin_b; + int w = r.right-r.left; + int h = r.bottom-r.top; + + if (m_didvert) + { + r.left += (w-tw)/2; + r.right -= (w-tw)/2; + } + else + { + r.top += (h-th)/2; + r.bottom -= (h-th)/2; + } + + if (m_didalign < 0) + { + if (m_didvert) r.bottom = r.top+th; + else r.right = r.left+tw; + } + else if (m_didalign > 0) + { + if (m_didvert) r.top = r.bottom-th; + else r.left = r.right-tw; + } + else + { + if (m_didvert) + { + r.top += (h-th)/2; + r.bottom -= (h-th)/2; + } + else + { + r.left += (w-tw)/2; + r.right -= (w-tw)/2; + } + } + + int c=-1; + if (m_didvert) + { + if (ypos < r.top) c=-1; + else if (ypos > r.bottom) c=len; + else c = (int)((double)len*(double)(ypos-r.top)/(double)(r.bottom-r.top)); + } + else + { + if (xpos < r.left) c=-1; + else if (xpos > r.right) c=len; + else c = (int)((double)len*(double)(xpos-r.left)/(double)(r.right-r.left)); + } + + return c; +} + + +bool WDL_VirtualStaticText::OnMouseDblClick(int xpos, int ypos) +{ + if (!WDL_VWnd::OnMouseDblClick(xpos,ypos)) + { + SendCommand(WM_COMMAND,GetID() | (STN_DBLCLK<<16),0,this); + } + + return true; +} + + +bool WDL_VirtualIconButton::WantsPaintOver() +{ + return m_is_button && m_iconCfg && m_iconCfg->image && m_iconCfg->olimage; +} + +void WDL_VirtualIconButton::GetPositionPaintOverExtent(RECT *r) +{ + *r=m_position; + if (m_iconCfg && m_iconCfg->image && m_iconCfg->olimage && (m_iconCfg->image_ltrb_used.flags&1)) + { + if (m_iconCfg->image_ltrb_used.flags&2) // main image has pink lines, use 1:1 pixel for outer area size + { + r->left -= m_iconCfg->image_ltrb_ol[0]; + r->top -= m_iconCfg->image_ltrb_ol[1]; + r->right += m_iconCfg->image_ltrb_ol[2]; + r->bottom += m_iconCfg->image_ltrb_ol[3]; + } + else + { + int w=(m_iconCfg->olimage->getWidth()-2)/3-m_iconCfg->image_ltrb_ol[0]-m_iconCfg->image_ltrb_ol[2]; + if (w<1)w=1; + double wsc=(r->right-r->left)/(double)w; + + int h=m_iconCfg->olimage->getHeight()-2-m_iconCfg->image_ltrb_ol[1]-m_iconCfg->image_ltrb_ol[3]; + if (h<1)h=1; + double hsc=(r->bottom-r->top)/(double)h; + + r->left-=(int) (m_iconCfg->image_ltrb_ol[0]*wsc); + r->top-=(int) (m_iconCfg->image_ltrb_ol[1]*hsc); + r->right+=(int) (m_iconCfg->image_ltrb_ol[2]*wsc); + r->bottom+=(int) (m_iconCfg->image_ltrb_ol[3]*hsc); + } + } +} +void WDL_VirtualIconButton_PreprocessSkinConfig(WDL_VirtualIconButton_SkinConfig *a) +{ + if (a && a->image) + { + a->image_ltrb_used.flags=0; + int wi; + for(wi=0;wi<2;wi++) + { + LICE_IBitmap *srcimg = wi ? a->image : a->olimage; + if (!srcimg) continue; + int w=srcimg->getWidth(); + int h=srcimg->getHeight(); + + if (LICE_GetPixel(srcimg,0,0)==LICE_RGBA(255,0,255,255)&& + LICE_GetPixel(srcimg,w-1,h-1)==LICE_RGBA(255,0,255,255)) + { + int lext=0,rext=0,bext=0,text=0; + int x; + for (x = 1; x < w/3 && LICE_GetPixel(srcimg,x,0)==LICE_RGBA(255,0,255,255); x ++); + lext=x-1; + for (x = 1; x < h && LICE_GetPixel(srcimg,0,x)==LICE_RGBA(255,0,255,255); x ++); + text=x-1; + + for (x = w-2; x >= (w*2/3) && LICE_GetPixel(srcimg,x,h-1)==LICE_RGBA(255,0,255,255); x --); + rext=w-2-x; + for (x = h-2; x >= text && LICE_GetPixel(srcimg,w-1,x)==LICE_RGBA(255,0,255,255); x --); + bext=h-2-x; + if (lext||text||rext||bext) + { + a->image_ltrb_used.flags |= 1 << wi; + short *buf = wi ? a->image_ltrb_main : a->image_ltrb_ol; + buf[0]=lext; + buf[1]=text; + buf[2]=rext; + buf[3]=bext; + } + } + } + } +} diff --git a/WDL/wingui/virtwnd-listbox.cpp b/WDL/wingui/virtwnd-listbox.cpp new file mode 100644 index 00000000..dab21b57 --- /dev/null +++ b/WDL/wingui/virtwnd-listbox.cpp @@ -0,0 +1,728 @@ +/* + WDL - virtwnd-listbox.cpp + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Implementation for virtual window listboxes. + +*/ + +#include "virtwnd-controls.h" +#include "../lice/lice.h" + +WDL_VirtualListBox::WDL_VirtualListBox() +{ + memset(m_lastscrollbuttons,0,sizeof(m_lastscrollbuttons)); + m_scrollbuttonsize=14; + m_cap_startitem=-1; + m_cap_state=0; + m_margin_l=m_margin_r=0; + m_GetItemInfo=0; + m_CustomDraw=0; + m_GetItemInfo_ctx=0; + m_viewoffs=0; + m_align=-1; + m_rh=14; + m_maxcolwidth=m_mincolwidth=0; + m_font=0; + m_clickmsg=0; + m_dropmsg=0; + m_dragbeginmsg=0; + m_grayed=false; +} + +WDL_VirtualListBox::~WDL_VirtualListBox() +{ +} + +void WDL_VirtualListBox::CalcLayout(int num_items, int *nrows, int *ncols, int *leftrightbuttonsize, int *updownbuttonsize, int *startpos, + int *usedw) +{ + *usedw = m_position.right - m_position.left; + *leftrightbuttonsize=*updownbuttonsize=0; + if (m_rh<7) m_rh=7; + + *ncols=1; + + *nrows= (m_position.bottom - m_position.top) / m_rh; + if (*nrows<1) *nrows=1; + + if (m_mincolwidth>0) + { + *ncols = (num_items+*nrows-1) / *nrows; // round up + if (*ncols<1) *ncols=1; + if ((m_position.right-m_position.left) < m_mincolwidth* *ncols) + *ncols = (m_position.right-m_position.left)/m_mincolwidth; + } + + if (m_maxcolwidth>0) + { + int oc = *ncols; + if (m_mincolwidth<=0 || (m_position.right-m_position.left) <= m_maxcolwidth * *ncols) + *ncols = (m_position.right-m_position.left) / m_maxcolwidth; // round down + } + + if (*ncols < 1) *ncols=1; + *startpos=0; + + if (num_items > *nrows * *ncols) + { + *startpos=m_viewoffs; + + if (*ncols > 1 && m_mincolwidth>0) // reduce columns to meet size requirements + { + if ((m_position.right-m_position.left - m_scrollbuttonsize*2) < m_mincolwidth* *ncols) + { + *ncols = (m_position.right-m_position.left - m_scrollbuttonsize*2)/m_mincolwidth; + if (*ncols < 1) *ncols=1; + } + } + + if (*ncols > 1) *leftrightbuttonsize = m_scrollbuttonsize; + else *updownbuttonsize = m_scrollbuttonsize; + + *nrows = (m_position.bottom - m_position.top - *updownbuttonsize) / m_rh; + if (*nrows<1) *nrows=1; + + if (m_maxcolwidth>0 && *ncols == 1 && *nrows ==1) + { + *leftrightbuttonsize = m_scrollbuttonsize; + *updownbuttonsize=0; + + *nrows = (m_position.bottom - m_position.top - *updownbuttonsize) / m_rh; + if (*nrows<1) *nrows=1; + } + + int tot=*nrows * *ncols - (*nrows-1); + if (*startpos > num_items-tot) *startpos=num_items-tot; + if (*startpos<0)*startpos=0; + + if (*ncols>1) + *startpos -= *startpos % *nrows; + } + + if (m_maxcolwidth > 0) + { + int maxw=*ncols*m_maxcolwidth + 2* *leftrightbuttonsize; + if (maxw < *usedw) *usedw=maxw; + } + +} + +static void maxSizePreservingAspect(int sw, int sh, int dw, int dh, int *outw, int *outh) +{ + *outw=dw; + *outh=dh; + if (sw < 1 || sh < 1) return; + int xwid = (sw * dh) / sh; // calculate width required if we make it dh pixels tall + if (xwid > dw) + { + // too wide, make maximum width and reduce height + *outh = (dw * sh) / sw; + } + else + { + // too narrow, use full height and reduce width + *outw = (dh * sw) / sh; + } +} + +static void DrawBkImage(LICE_IBitmap *drawbm, WDL_VirtualWnd_BGCfg *bkbm, int drawx, int drawy, int draww, int drawh, + RECT *cliprect, int drawsrcx, int drawsrcw, int bkbmstate, float alpha, int whichpass=0) +{ + bool haspink=bkbm->bgimage_lt[0]||bkbm->bgimage_lt[1]||bkbm->bgimage_rb[0] || bkbm->bgimage_rb[1]; + + if (whichpass==1) + { + int sw = (bkbm->bgimage->getWidth() - (haspink? 2 :0))/2; + int sh = (bkbm->bgimage->getHeight() - (haspink? 2 :0))/3; + + int usew,useh; + // scale drawing coords by image dimensions + maxSizePreservingAspect(sw,sh,draww,drawh,&usew,&useh); + + if (usew == sw-1 || usew == sw+1) usew=sw; + if (useh == sh-1 || useh == sh+1) useh=sh; + drawx += (draww-usew)/2; + drawy += (drawh-useh)/2; + draww = usew; + drawh = useh; + } + + int hh=bkbm->bgimage->getHeight()/3; + + if (haspink) + { + WDL_VirtualWnd_BGCfg tmp = *bkbm; + if ((tmp.bgimage_noalphaflags&0xffff)!=0xffff) tmp.bgimage_noalphaflags=0; // force alpha channel if any alpha + + if (drawsrcx>0) { drawsrcx--; drawsrcw++; } + LICE_SubBitmap bm(tmp.bgimage,drawsrcx,bkbmstate*hh,drawsrcw+1,hh+2); + tmp.bgimage = &bm; + + WDL_VirtualWnd_ScaledBlitBG(drawbm,&tmp, + drawx,drawy,draww,drawh, + cliprect->left,cliprect->top,cliprect->right-cliprect->left,cliprect->bottom-cliprect->top, + alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + else + { + LICE_ScaledBlit(drawbm,bkbm->bgimage, + drawx,drawy,draww,drawh, + drawsrcx,bkbmstate*hh, + drawsrcw,hh,alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } +} + + +void WDL_VirtualListBox::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + RECT r=m_position; + r.left+=origin_x; + r.right+=origin_x; + r.top+=origin_y; + r.bottom+=origin_y; + + WDL_VirtualWnd_BGCfg *mainbk=0; + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,&mainbk) : 0; + LICE_pixel bgc=GSC(COLOR_BTNFACE); + bgc=LICE_RGBA_FROMNATIVE(bgc,255); + + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + if (r.right > r.left + usedw) r.right=r.left+usedw; + + if (mainbk && mainbk->bgimage) + { + if (mainbk->bgimage->getWidth()>1 && mainbk->bgimage->getHeight()>1) + { + WDL_VirtualWnd_ScaledBlitBG(drawbm,mainbk, + r.left,r.top,r.right-r.left,r.bottom-r.top, + cliprect->left,cliprect->top,cliprect->right-cliprect->left,cliprect->bottom-cliprect->top, + 1.0,LICE_BLIT_USE_ALPHA|LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + } + } + else + { + LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,bgc,1.0f,LICE_BLIT_MODE_COPY); + } + + LICE_pixel pencol = GSC(COLOR_3DSHADOW); + LICE_pixel pencol2 = GSC(COLOR_3DHILIGHT); + pencol=LICE_RGBA_FROMNATIVE(pencol,255); + pencol2=LICE_RGBA_FROMNATIVE(pencol2,255); + + LICE_pixel tcol=GSC(COLOR_BTNTEXT); + if (m_font) m_font->SetBkMode(TRANSPARENT); + + float alpha = (m_grayed ? 0.25f : 1.0f); + + int endpos=r.bottom - updownbuttonsize; + int itempos=startpos; + + int colpos; + int y=0; + for (colpos = 0; colpos < num_cols; colpos ++) + { + int col_x = r.left + leftrightbuttonsize + ((r.right-r.left-leftrightbuttonsize*2)*colpos) / num_cols; + int col_w = r.left + leftrightbuttonsize + ((r.right-r.left-leftrightbuttonsize*2)*(colpos+1)) / num_cols - col_x; + for (y = r.top + m_rh; y <= endpos; y += m_rh) + { + int ly=y-m_rh; + WDL_VirtualWnd_BGCfg *bkbm=0; + if (m_GetItemInfo && ly >= r.top) + { + char buf[64]; + buf[0]=0; + int color=tcol; + + if (m_GetItemInfo(this,itempos++,buf,sizeof(buf),&color,&bkbm)) + { + color=LICE_RGBA_FROMNATIVE(color,0); + RECT thisr; + thisr.left = col_x; + thisr.right = col_x + col_w; + thisr.top = ly+1; + thisr.bottom = y-1; + int rev=0; + int bkbmstate=0; + if (m_cap_state==1 && m_cap_startitem==itempos-1) + { + if (bkbm) bkbmstate=1; + else color = ((color>>1)&0x7f7f7f7f)+LICE_RGBA(0x7f,0x7f,0x7f,0); + } + if (m_cap_state>=0x1000 && m_cap_startitem==itempos-1) + { + if (bkbm) bkbmstate=2; + else + { + rev=1; + LICE_FillRect(drawbm,thisr.left,thisr.top,thisr.right-thisr.left,thisr.bottom-thisr.top, color,alpha,LICE_BLIT_MODE_COPY); + } + } + if (bkbm && bkbm->bgimage) //draw image! + { + DrawBkImage(drawbm,bkbm, + thisr.left,thisr.top-1,thisr.right-thisr.left,thisr.bottom-thisr.top+2, + cliprect, + 0,bkbm->bgimage->getWidth(),bkbmstate,alpha); + + } + if (m_CustomDraw) + { + m_CustomDraw(this,itempos-1,&thisr,drawbm); + } + + if (buf[0]) + { + thisr.left+=m_margin_l; + thisr.right-=m_margin_r; + if (m_font) + { + m_font->SetTextColor(rev?bgc:color); + m_font->SetCombineMode(LICE_BLIT_MODE_COPY, alpha); // maybe gray text only if !bkbm->bgimage + m_font->DrawText(drawbm,buf,-1,&thisr,DT_VCENTER|(m_align<0?DT_LEFT:m_align>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); + } + } + } + } + + if (!bkbm) + { + LICE_Line(drawbm,col_x,y,col_x+col_w,y,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + } + } + } + memset(&m_lastscrollbuttons,0,sizeof(m_lastscrollbuttons)); + if (updownbuttonsize||leftrightbuttonsize) + { + WDL_VirtualWnd_BGCfg *bkbm[2]={0,}; + int a=m_GetItemInfo ? m_GetItemInfo(this, + leftrightbuttonsize ? WDL_VWND_LISTBOX_ARROWINDEX_LR : WDL_VWND_LISTBOX_ARROWINDEX,NULL,0,NULL,bkbm) : 0; + + if (!a) bkbm[0]=0; + + if (leftrightbuttonsize) + { + RECT br={0,0,r.right-r.left,r.bottom-r.top}; + + if (startpos>0) + { + m_lastscrollbuttons[0]=br; + m_lastscrollbuttons[0].right = br.left + m_scrollbuttonsize; + } + if (itempos < num_items) + { + m_lastscrollbuttons[1]=br; + m_lastscrollbuttons[1].left=br.right - m_scrollbuttonsize; + } + } + else + { + RECT br={0,y-r.top - m_rh,r.right-r.left,y-r.top - m_rh + m_scrollbuttonsize}; + if (startpos>0) + { + m_lastscrollbuttons[0]=br; + m_lastscrollbuttons[0].right = (br.left+br.right)/2; + } + if (itempos < num_items) + { + m_lastscrollbuttons[1]=br; + m_lastscrollbuttons[1].left = (br.left+br.right)/2; + } + } + + + int wb; + for (wb=0;wb<2;wb++) + { + if (bkbm[wb] && bkbm[wb]->bgimage) + { + int tw = bkbm[wb]->bgimage->getWidth(); + int bkbmstate=startpos>0 ? 2 : 1; + if (leftrightbuttonsize) + { + DrawBkImage(drawbm,bkbm[wb], + r.left,r.top,m_scrollbuttonsize,(r.bottom-r.top), + cliprect, + 0,tw/2,bkbmstate,1.0, wb); + + + bkbmstate=itemposbgimage || + !bkbm[1] || !bkbm[1]->bgimage) + { + bool butaa = true; + if (updownbuttonsize) + { + int cx=(r.left+r.right)/2; + int bs=5; + int bsh=8; + y -= m_rh-m_scrollbuttonsize; + + if (!bkbm[0] || !bkbm[0]->bgimage) + { + LICE_Line(drawbm,cx,y-m_scrollbuttonsize+2,cx,y-1,pencol2,1.0f,0,false); + LICE_Line(drawbm,r.left,y,r.right,y,pencol2,1.0f,0,false); + } + + y-=m_scrollbuttonsize/2+bsh/2; + + if (!bkbm[1] || !bkbm[1]->bgimage) + { + if (itempos0) + { + y-=2; + cx=(r.left+r.right)/4; + LICE_Line(drawbm,cx-bs+1,y+bsh,cx,y+3+1,pencol2,1.0f,0,butaa); + LICE_Line(drawbm,cx,y+3+1,cx+bs-1,y+bsh,pencol2,1.0f,0,butaa); + LICE_Line(drawbm,cx+bs-1,y+bsh,cx-bs+1,y+bsh,pencol2,1.0f,0,butaa); + + LICE_Line(drawbm,cx-bs-1,y+bsh+1,cx,y+3,pencol,1.0f,0,butaa); + LICE_Line(drawbm,cx,y+3,cx+bs+1,y+bsh+1,pencol,1.0f,0,butaa); + LICE_Line(drawbm,cx+bs+1,y+bsh+1, cx-bs-1,y+bsh+1, pencol,1.0f,0,butaa); + } + } + } + else // sideways buttons + { + if (!bkbm[1] || !bkbm[1]->bgimage) + { + #define LICE_LINEROT(bm,x1,y1,x2,y2,pc,al,mode,aa) LICE_Line(bm,y1,x1,y2,x2,pc,al,mode,aa) + int bs=5; + int bsh=8; + int cx = (r.bottom + r.top)/2; + if (itempos < num_items) + { + int y = r.right - leftrightbuttonsize/2 - bsh/2; + LICE_LINEROT(drawbm,cx-bs+1,y+2,cx,y+bsh-2,pencol2,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx,y+bsh-2,cx+bs-1,y+2,pencol2,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx+bs-1,y+2,cx-bs+1,y+2,pencol2,1.0f,0,butaa); + + LICE_LINEROT(drawbm,cx-bs-1,y+1,cx,y+bsh-1,pencol,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx,y+bsh-1,cx+bs+1,y+1,pencol,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx+bs+1,y+1,cx-bs-1,y+1,pencol,1.0f,0,butaa); + } + if (startpos>0) + { + int y = r.left + leftrightbuttonsize/2-bsh/2 - 2; + LICE_LINEROT(drawbm,cx-bs+1,y+bsh,cx,y+3+1,pencol2,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx,y+3+1,cx+bs-1,y+bsh,pencol2,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx+bs-1,y+bsh,cx-bs+1,y+bsh,pencol2,1.0f,0,butaa); + + LICE_LINEROT(drawbm,cx-bs-1,y+bsh+1,cx,y+3,pencol,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx,y+3,cx+bs+1,y+bsh+1,pencol,1.0f,0,butaa); + LICE_LINEROT(drawbm,cx+bs+1,y+bsh+1, cx-bs-1,y+bsh+1, pencol,1.0f,0,butaa); + } + #undef LICE_LINEROT + } + } + } + } + + + + if (!mainbk) + { + LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,0,false); + LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,0,false); + LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol2,1.0f,0,false); + LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol2,1.0f,0,false); + } + + +} + +bool WDL_VirtualListBox::HandleScrollClicks(int xpos, int ypos, int leftrightbuttonsize, int updownbuttonsize, int nrows, int num_cols, int num_items, int usedw) +{ + if (leftrightbuttonsize && (xpos= usedw-m_scrollbuttonsize)) + { + if (xpos0) + { + m_viewoffs-=nrows; + if (m_viewoffs<0)m_viewoffs=0; + RequestRedraw(NULL); + } + } + else + { + if (m_viewoffs+nrows*num_cols < num_items) + { + m_viewoffs+=nrows; + RequestRedraw(NULL); + } + } + m_cap_state=0; + m_cap_startitem=-1; + return true; + } + if (updownbuttonsize && ypos >= nrows*m_rh) + { + if (ypos < (nrows)*m_rh + m_scrollbuttonsize) + { + if (xpos < usedw/2) + { + if (m_viewoffs>0) + { + m_viewoffs--; + RequestRedraw(NULL); + } + } + else + { + if (m_viewoffs+nrows*num_cols < num_items) + { + m_viewoffs++; + RequestRedraw(NULL); + } + } + } + m_cap_state=0; + m_cap_startitem=-1; + return true; + } + return false; +} + +int WDL_VirtualListBox::OnMouseDown(int xpos, int ypos) +{ + if (m_grayed) return 0; + + if (m__iaccess) m__iaccess->OnFocused(); + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + + if (xpos >= usedw) return 0; + + if (HandleScrollClicks(xpos,ypos,leftrightbuttonsize,updownbuttonsize,nrows,num_cols,num_items,usedw)) return 1; + + + + m_cap_state=0x1000; + int usewid=(usedw-leftrightbuttonsize*2); + int col = num_cols > 0 && usewid>0 ? ((xpos-leftrightbuttonsize)*num_cols)/usewid : 0; + m_cap_startitem=startpos + (ypos)/m_rh + col*nrows; + RequestRedraw(NULL); + + return 1; +} + + +bool WDL_VirtualListBox::OnMouseDblClick(int xpos, int ypos) +{ + if (m_grayed) return false; + + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + + if (xpos >= usedw) return false; + + if (HandleScrollClicks(xpos,ypos,leftrightbuttonsize,updownbuttonsize,nrows,num_cols,num_items,usedw)) return true; + + return false; +} + +bool WDL_VirtualListBox::OnMouseWheel(int xpos, int ypos, int amt) +{ + if (m_grayed) return false; + + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + + if (xpos >= usedw) return false; + + if (num_items > nrows*num_cols) + { + if (amt>0 && m_viewoffs>0) + { + m_viewoffs-=(num_cols>1?nrows:1); + if (m_viewoffs<0)m_viewoffs=0; + RequestRedraw(NULL); + } + else if (amt<0) + { + if (m_viewoffs+nrows*num_cols < num_items) + { + m_viewoffs+=(num_cols>1?nrows:1); + RequestRedraw(NULL); + } + } + } + return true; +} + +void WDL_VirtualListBox::OnMouseMove(int xpos, int ypos) +{ + if (m_grayed) return; + + if (m_cap_state>=0x1000) + { + m_cap_state++; + if (m_cap_state==0x1008) + { + if (m_dragbeginmsg) + { + SendCommand(m_dragbeginmsg,(INT_PTR)this,m_cap_startitem,this); + } + } + } + else if (m_cap_state==0) + { + int a=IndexFromPt(xpos,ypos); + if (a>=0) + { + m_cap_startitem=a; + m_cap_state=1; + RequestRedraw(NULL); + } + } + else if (m_cap_state==1) + { + int a=IndexFromPt(xpos,ypos); + if (a>=0 && a != m_cap_startitem) + { + m_cap_startitem=a; + m_cap_state=1; + RequestRedraw(NULL); + } + else if (a<0) + { + m_cap_state=0; + RequestRedraw(NULL); + } + } +} + +void WDL_VirtualListBox::OnMouseUp(int xpos, int ypos) +{ + if (m_grayed) return; + + int hit=IndexFromPt(xpos,ypos); + if (m_cap_state>=0x1000 && m_cap_state<0x1008 && hit==m_cap_startitem) + { + if (m_clickmsg) + { + SendCommand(m_clickmsg,(INT_PTR)this,hit,this); + } + } + else if (m_cap_state>=0x1008) + { + // send a message saying drag & drop occurred + if (m_dropmsg) + SendCommand(m_dropmsg,(INT_PTR)this,m_cap_startitem,this); + } + + m_cap_state=0; + RequestRedraw(NULL); +} + +bool WDL_VirtualListBox::GetItemRect(int item, RECT *r) +{ + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos, usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + item -= startpos; + + if (r) + { + int col = item / nrows; + int row = item % nrows; + r->top = row * m_rh; + r->bottom = (row+1)*m_rh; + r->left = leftrightbuttonsize + (col * (usedw - leftrightbuttonsize*2)) / num_cols; + r->right = leftrightbuttonsize + ((col+1) * (usedw - leftrightbuttonsize*2)) / num_cols; + } + return item >= startpos && item < startpos + nrows*num_cols;; +} + +int WDL_VirtualListBox::IndexFromPt(int x, int y) +{ + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + int nrows,num_cols,updownbuttonsize,leftrightbuttonsize,startpos,usedw; + CalcLayout(num_items,&nrows,&num_cols,&leftrightbuttonsize,&updownbuttonsize,&startpos,&usedw); + + if (x>=usedw) return -2; + + if (y < 0 || y >= nrows*m_rh ||x= (usedw-leftrightbuttonsize)) return -1; + + int usewid=(usedw-leftrightbuttonsize*2); + int col = num_cols > 0 && usewid>0 ? ((x-leftrightbuttonsize)*num_cols)/usewid : 0; + + return startpos + (y)/m_rh + col * nrows; +} + +void WDL_VirtualListBox::SetViewOffset(int offs) +{ + int num_items = m_GetItemInfo ? m_GetItemInfo(this,-1,NULL,0,NULL,NULL) : 0; + if (num_items) + { + if (offs < 0) offs=0; + else if (offs >= num_items) offs = num_items-1; + if (offs != m_viewoffs) + { + m_viewoffs = offs; + RequestRedraw(0); + } + } +} + +int WDL_VirtualListBox::GetViewOffset() +{ + return m_viewoffs; +} diff --git a/WDL/wingui/virtwnd-nsaccessibility.mm b/WDL/wingui/virtwnd-nsaccessibility.mm new file mode 100644 index 00000000..c290c936 --- /dev/null +++ b/WDL/wingui/virtwnd-nsaccessibility.mm @@ -0,0 +1,644 @@ +#include "../swell/swell.h" + +#include "virtwnd-controls.h" + + +@class VWndNSAccessibility; +static VWndNSAccessibility *GetVWndNSAccessible(WDL_VWnd *vwnd); +static WDL_VWnd *__focus; +class VWndBridgeNS; + + +@interface VWndNSAccessibility : NSObject +{ +@public + VWndBridgeNS *m_br; + NSArray *m_cached_children; + int m_cached_children_lastcnt; + NSArray *m_cached_attrnames; +} +-(id) initWithVWnd:(WDL_VWnd *)vw; +-(void)dealloc; +-(void)clearCaches; + + +// attribute methods +- (NSArray *)accessibilityAttributeNames; +- (id)accessibilityAttributeValue:(NSString *)attribute; +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute; +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute; + +// parameterized attribute methods +- (NSArray *)accessibilityParameterizedAttributeNames; +- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter; + +// action methods +- (NSArray *)accessibilityActionNames; +- (NSString *)accessibilityActionDescription:(NSString *)action; +- (void)accessibilityPerformAction:(NSString *)action; + +// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. +- (BOOL)accessibilityIsIgnored; + +// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. +- (id)accessibilityHitTest:(NSPoint)point; + +// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. +- (id)accessibilityFocusedUIElement; + + +@end + + +class VWndBridgeNS : public WDL_VWnd_IAccessibleBridge +{ +public: + VWndBridgeNS(VWndNSAccessibility *p, WDL_VWnd *vw) + { + [(par=p) retain]; + (vwnd=vw)->SetAccessibilityBridge(this); + } + ~VWndBridgeNS() + { +// if (vwnd) printf("Destroying self before Released, wtf!\n"); + } + + virtual void Release() + { + if (__focus == vwnd) __focus=0; + + vwnd=0; + if (par) + { + NSAccessibilityPostNotification(par,NSAccessibilityUIElementDestroyedNotification); + [par release]; + // this is probably no longer valid! + } + } + virtual void ClearCaches() + { + if (par) [par clearCaches]; + } + virtual void OnFocused() + { + if (vwnd && __focus != vwnd && par) + { + __focus = vwnd; +// NSAccessibilityPostNotification(par,NSAccessibilityFocusedWindowChangedNotification); + NSAccessibilityPostNotification(par,NSAccessibilityFocusedUIElementChangedNotification); + } + } + virtual void OnStateChange() + { + if (par) NSAccessibilityPostNotification(par,NSAccessibilityValueChangedNotification); + } + + VWndNSAccessibility *par; + WDL_VWnd *vwnd; +}; + +@implementation VWndNSAccessibility +-(id) initWithVWnd:(WDL_VWnd *)vw +{ + if ((self = [super init])) + { + m_br = new VWndBridgeNS(self,vw); + m_cached_children=0; + m_cached_attrnames = 0; + m_cached_children_lastcnt=0; + } + return self; +} +-(void)clearCaches +{ + if (m_cached_children) + { + [m_cached_children release]; + m_cached_children=0; + m_cached_children_lastcnt=0; + } + if (m_cached_attrnames) + { + [m_cached_attrnames release]; + m_cached_attrnames = 0; + } +} +-(void)dealloc +{ + [self clearCaches]; + delete m_br; + [super dealloc]; +} + +- (NSArray *)accessibilityAttributeNames +{ + if (m_cached_attrnames) return m_cached_attrnames; + NSString *s[32]; + int sidx=0; + const char *type = NULL; + if (m_br->vwnd) + { + type = m_br->vwnd->GetType(); + if (!type) type = ""; + } + if (type) + { +// if (m_br->vwnd->GetNumChildren()) + { + s[sidx++] = NSAccessibilityChildrenAttribute; + s[sidx++] = NSAccessibilityVisibleChildrenAttribute; + } + s[sidx++]=NSAccessibilityTitleAttribute; + + if (!strcmp(type,"vwnd_iconbutton")) s[sidx++] = NSAccessibilityEnabledAttribute; + + s[sidx++] = NSAccessibilityFocusedAttribute; + s[sidx++] = NSAccessibilityParentAttribute; + + RECT r; + m_br->vwnd->GetPosition(&r); + if (m_br->vwnd->IsVisible() && r.right>r.left && r.bottom>r.top) + { + s[sidx++] = NSAccessibilityPositionAttribute; + s[sidx++] = NSAccessibilitySizeAttribute; + } + + s[sidx++] = NSAccessibilityRoleAttribute; + s[sidx++] = NSAccessibilityRoleDescriptionAttribute; + + if (!strcmp(type,"vwnd_statictext")) + { + // s[sidx++]=NSAccessibilityDescriptionAttribute; +// s[sidx++]=NSAccessibilityValueDescriptionAttribute; + } + + s[sidx++] = NSAccessibilityWindowAttribute; + bool hasState = false; + if (!strcmp(type,"vwnd_iconbutton")) + { + hasState = ((WDL_VirtualIconButton*)m_br->vwnd)->GetCheckState()>=0; + } + else if (!strcmp(type,"vwnd_combobox")) hasState=true; + else if (!strcmp(type,"vwnd_slider")) hasState=true; + + if (hasState) + { + s[sidx++] = NSAccessibilityMaxValueAttribute; + s[sidx++] = NSAccessibilityMinValueAttribute; + s[sidx++] = NSAccessibilityValueAttribute; + } + } + + if (m_cached_attrnames) [m_cached_attrnames release]; + m_cached_attrnames = [NSArray arrayWithObjects:s count:sidx]; + [m_cached_attrnames retain]; + return m_cached_attrnames; +} + +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + if (!m_br->vwnd) return nil; + const char *type = m_br->vwnd->GetType(); + if (!type) type=""; + + //NSLog(@"Requesting attribute: %@ %s %p\n",attribute,type,m_br->vwnd); + + int a = [attribute isEqual:NSAccessibilityChildrenAttribute]?1:0; + if (!a) a= [attribute isEqual:NSAccessibilityVisibleChildrenAttribute]?2:0; + if (a) // if 2, only add visible items + { + int nc = m_br->vwnd->GetNumChildren(); +// if (!nc) { if (m_cached_children) { [m_cached_children release]; m_cached_children=0; } printf("ret nil\n"); return nil; } + + if (m_cached_children && nc == m_cached_children_lastcnt) return m_cached_children; + + NSMutableArray *ar = [NSMutableArray arrayWithCapacity:nc]; + int x; + for (x=0;xvwnd->EnumChildren(x); + if (!ch) continue; + RECT r; + ch->GetPosition(&r); + if (a==1 || (ch->IsVisible() && r.right>r.left && r.bottom>r.top)) + { + VWndNSAccessibility *cid = GetVWndNSAccessible(ch); + if (cid) + { + [ar addObject:cid]; + [cid release]; + } + } + } + [m_cached_children release]; + m_cached_children_lastcnt = nc; + m_cached_children = NSAccessibilityUnignoredChildren(ar); + [m_cached_children retain]; + return m_cached_children; + } + + if ([attribute isEqual:NSAccessibilityEnabledAttribute]) + { + if (!strcmp(type,"vwnd_iconbutton")) + { + return [NSNumber numberWithBool:!!((WDL_VirtualIconButton *)m_br->vwnd)->GetEnabled()]; + } + return nil; + } + if ([attribute isEqual:NSAccessibilityFocusedAttribute]) + { + return [NSNumber numberWithBool:(__focus == m_br->vwnd || (m_br->vwnd && m_br->vwnd->IsDescendent(__focus)))]; // todo focus bleh + } + if ([attribute isEqual:NSAccessibilityParentAttribute]) + { + WDL_VWnd *parw = m_br->vwnd->GetParent(); + if (parw) + { + VWndNSAccessibility *cid = GetVWndNSAccessible(parw); + if (cid) return NSAccessibilityUnignoredAncestor([cid autorelease]); + } + HWND h =m_br->vwnd->GetRealParent(); + if (h) return NSAccessibilityUnignoredAncestor((id)h); + return NULL; + } + if ([attribute isEqual:NSAccessibilityPositionAttribute]) + { + RECT r; + m_br->vwnd->GetPosition(&r); + r.top = r.bottom; // this wants the lower left corner + WDL_VWnd *p = m_br->vwnd->GetParent(); + while (p) + { + RECT tr; + p->GetPosition(&tr); + r.left += tr.left; + r.top += tr.top; + p = p->GetParent(); + } + HWND h = m_br->vwnd->GetRealParent(); + if (h) + { + ClientToScreen(h,(LPPOINT)&r); + } + //printf("position of (%s) %d,%d\n",m_br->vwnd->GetAccessDesc()?m_br->vwnd->GetAccessDesc():"nul",r.left,r.top); + return [NSValue valueWithPoint:NSMakePoint(r.left,r.top)]; + } + if ([attribute isEqual:NSAccessibilitySizeAttribute]) + { + RECT r; + m_br->vwnd->GetPosition(&r); +// printf("size of (%s) %d,%d\n",m_br->vwnd->GetAccessDesc()?m_br->vwnd->GetAccessDesc():"nul",r.right-r.left,r.bottom-r.top); + return [NSValue valueWithSize:NSMakeSize(r.right-r.left,r.bottom-r.top)]; + } + if ([attribute isEqual:NSAccessibilityRoleDescriptionAttribute]) + { + const char *str= NULL; + if (!str || !*str) + { + if (!strcmp(type,"vwnd_statictext")) str = "text"; + else if (!strcmp(type,"vwnd_slider")) str = "slider"; + else if (!strcmp(type,"vwnd_combobox")) str = "selection box"; + else if (!strcmp(type,"vwnd_iconbutton")) + { + WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; + if (b->GetCheckState()>=0) str = "check box"; + else str = "button"; + } + if (!str) str = m_br->vwnd->GetAccessDesc(); + } + if (str && *str) return [(id)SWELL_CStringToCFString(str) autorelease]; + + } + if ([attribute isEqual:NSAccessibilityRoleAttribute]) + { + if (!strcmp(type,"vwnd_statictext")) return NSAccessibilityButtonRole; // fail: seems to need 10.5+ to deliver text? NSAccessibilityStaticTextRole; + if (!strcmp(type,"vwnd_slider")) return NSAccessibilitySliderRole; + if (!strcmp(type,"vwnd_combobox")) return NSAccessibilityPopUpButtonRole; + if (!strcmp(type,"vwnd_iconbutton")) + { + WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; + if (b->GetCheckState()>=0) + return NSAccessibilityCheckBoxRole; + return NSAccessibilityButtonRole; + } + return NSAccessibilityUnknownRole; + } + if ([attribute isEqual:NSAccessibilityTitleAttribute] || [attribute isEqual:NSAccessibilityDescriptionAttribute])// || [attribute isEqual:NSAccessibilityValueDescriptionAttribute]) + { + const char *str=NULL; + int cs=-1; + if (!strcmp(type,"vwnd_statictext")) + { + WDL_VirtualStaticText *t = (WDL_VirtualStaticText *)m_br->vwnd; + str = t->GetText(); + } + if (!strcmp(type,"vwnd_combobox")) + { + WDL_VirtualComboBox *cb = (WDL_VirtualComboBox *)m_br->vwnd; + str = cb->GetItem(cb->GetCurSel()); + } + if (!strcmp(type,"vwnd_iconbutton")) + { + WDL_VirtualIconButton *b = (WDL_VirtualIconButton *)m_br->vwnd; + str = b->GetTextLabel(); + cs = b->GetCheckState(); + } + char buf[2048]; + if (!str || !*str) str= m_br->vwnd->GetAccessDesc(); + else + { + const char *p = m_br->vwnd->GetAccessDesc(); + if (p && *p) + { + char buf[1024]; + sprintf(buf,"%.512s: %.512s",p,str); + str=buf; + } + } + + +#if 0 + if (cs>=0) + { + if (str!=buf) + { + lstrcpyn(buf,str?str:"",sizeof(buf)-128); + str=buf; + } +// strcat(buf,cs>0 ? " checked" : " unchecked"); + + } +#endif + + if (str && *str) return [(id)SWELL_CStringToCFString(str) autorelease]; + } + if ([attribute isEqual:NSAccessibilityWindowAttribute]) + { + HWND h = m_br->vwnd->GetRealParent(); + if (h) + { + return [(NSView *)h window]; + } + } + int s; + if ((s=!![attribute isEqual:NSAccessibilityMaxValueAttribute]) || + (s=[attribute isEqual:NSAccessibilityValueAttribute]?2:0) || + [attribute isEqual:NSAccessibilityMinValueAttribute]) + { + if (!strcmp(type,"vwnd_slider")) + { + WDL_VirtualSlider *slid = (WDL_VirtualSlider *)m_br->vwnd; + int v=0; + if (s!=2) slid->GetRange(s ? NULL : &v, s ? &v :NULL,NULL); + else v= slid->GetSliderPosition(); + return [NSNumber numberWithInt:v]; + } + if (!strcmp(type,"vwnd_combobox")) + { + int v=0; + if (s==1) v=((WDL_VirtualComboBox*)m_br->vwnd)->GetCount(); + else if (s==2) v= !!((WDL_VirtualComboBox *)m_br->vwnd)->GetCurSel(); + if (v<0)v=0; + return [NSNumber numberWithInt:v]; + } + if (!strcmp(type,"vwnd_iconbutton")) + { + int v=0; + if (s==1) v=1; + else if (s==2) v= !!((WDL_VirtualIconButton *)m_br->vwnd)->GetCheckState()>0; + return [NSNumber numberWithInt:v]; + } + } + return nil; +} +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + // NSLog(@"accessibilityIsAttributeSettable: %@ %s %p\n",attribute,type,m_br->vwnd); + } + + if ([attribute isEqual:NSAccessibilityFocusedAttribute]) return YES; + return false; +} +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilitySetValue: %@ %s %p\n",attribute,type,m_br->vwnd); + } + + if ([attribute isEqual:NSAccessibilityFocusedAttribute]) + { + if ([value isKindOfClass:[NSNumber class]]) + { + NSNumber *p = (NSNumber *)value; + if ([p boolValue]) __focus = m_br->vwnd; + else if (__focus == m_br->vwnd) __focus=NULL; + } + } +} + +// parameterized attribute methods +- (NSArray *)accessibilityParameterizedAttributeNames +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilityParameterizedAttributeNames: %@ %s %p\n",@"",type,m_br->vwnd); + } + return [NSArray arrayWithObjects:nil count:0]; + return nil; +} +- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilityAttributeValue: %@ %s %p\n",attribute,type,m_br->vwnd); + } + return nil; +} + +// action methods +- (NSArray *)accessibilityActionNames +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilityActionNames: %@ %s %p\n",@"",type,m_br->vwnd); + } + NSString *s[32]; + int sidx=0; + + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (type) + { + if (!strcmp(type,"vwnd_combobox") || + !strcmp(type,"vwnd_iconbutton") || + !strcmp(type,"vwnd_statictext") + ) s[sidx++] = NSAccessibilityPressAction; + + if (!strcmp(type,"vwnd_slider")) + { + s[sidx++] = NSAccessibilityDecrementAction; + s[sidx++] = NSAccessibilityIncrementAction; + } + } + + return [NSArray arrayWithObjects:s count:sidx]; +} +- (NSString *)accessibilityActionDescription:(NSString *)action +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilityActionDescription: %@ %s %p\n",action,type,m_br->vwnd); + } + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (type) + { + if ([action isEqual:NSAccessibilityPressAction]) + { + if (!strcmp(type,"vwnd_combobox")) return @"Choose item"; + if (!strcmp(type,"vwnd_iconbutton")) return @"Press button"; + if (!strcmp(type,"vwnd_statictext")) return @"Doubleclick text"; + } + else if (!strcmp(type,"vwnd_slider")) + { + if ([action isEqual:NSAccessibilityDecrementAction]) return @"Decrease value of control"; + else if ([action isEqual:NSAccessibilityIncrementAction])return @"Increase value of control"; + } + } + return nil; +} + +- (void)accessibilityPerformAction:(NSString *)action +{ + if (m_br->vwnd) + { + const char *type = m_br->vwnd->GetType(); + if (!type) type=""; + + if ([action isEqual:NSAccessibilityPressAction]) + { + if (!strcmp(type,"vwnd_statictext")) m_br->vwnd->OnMouseDblClick(0,0); + else + { + m_br->vwnd->OnMouseDown(0,0); + m_br->vwnd->OnMouseUp(0,0); + } + } + else if ([action isEqual:NSAccessibilityDecrementAction]) + { + m_br->vwnd->OnMouseWheel(0,0,-1); + } + else if ([action isEqual:NSAccessibilityIncrementAction]) + { + m_br->vwnd->OnMouseWheel(0,0,1); + } + //NSLog(@"accessibilityPerformAction: %@ %s %p\n",action,type,m_br->vwnd); + } + // todo +} + +// Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. +- (BOOL)accessibilityIsIgnored +{ + if (m_br->vwnd) + { + if (!m_br->vwnd->IsVisible()) return YES; + if (m_br->vwnd->GetNumChildren()) + { + const char *type = m_br->vwnd->GetType(); + if (type) if (!strcmp(type,"vwnd_unknown") || strstr(type,"container")) return YES; + } + else + { + RECT r; + m_br->vwnd->GetPosition(&r); + if (r.right <= r.left || r.bottom <= r.top) return YES; + } + } + return NO; +} + +// Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates. +- (id)accessibilityHitTest:(NSPoint)point +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; +// NSLog(@"accessibilityHitTest: %f,%f %s %p\n",point.x,point.y,type,m_br->vwnd); + } + + if (m_br->vwnd) + { + HWND h = m_br->vwnd->GetRealParent(); + if (h) + { + POINT pt = {(int)point.x,(int)point.y}; + ScreenToClient(h,&pt); + WDL_VWnd *par = m_br->vwnd; + while (par->GetParent()) par=par->GetParent(); + RECT r; + par->GetPosition(&r); + WDL_VWnd *hit = par->VirtWndFromPoint(pt.x-r.left,pt.y-r.top); + if (hit) + { + VWndNSAccessibility *a = GetVWndNSAccessible(hit); + if (a) + { + [a autorelease]; + return a; + } + } + } + } + return nil; +} +// Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus. +- (id)accessibilityFocusedUIElement +{ + { + const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; + if (!type) type=""; + //NSLog(@"accessibilityFocusedUIElement: %s %p\n",type,m_br->vwnd); + } + if (__focus && m_br && m_br->vwnd && m_br->vwnd->IsDescendent(__focus)) + { + VWndBridgeNS *p = (VWndBridgeNS *)__focus->GetAccessibilityBridge(); + if (p) return p->par; + } + return self; +} + + +@end + + + +static VWndNSAccessibility *GetVWndNSAccessible(WDL_VWnd *vwnd) +{ + if (!vwnd) return NULL; + VWndBridgeNS *p = (VWndBridgeNS *)vwnd->GetAccessibilityBridge(); + if (p) + { + if (p->par) [p->par retain]; + return p->par; + } + + return [[VWndNSAccessibility alloc] initWithVWnd:vwnd]; +} + +LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam) +{ + if (vw && lParam && wParam==0x1001) + { + VWndNSAccessibility *nsa = GetVWndNSAccessible(vw); + if (nsa) *(id *)lParam = nsa; + } + return 0; +} diff --git a/WDL/wingui/virtwnd-skin.h b/WDL/wingui/virtwnd-skin.h new file mode 100644 index 00000000..d6e79291 --- /dev/null +++ b/WDL/wingui/virtwnd-skin.h @@ -0,0 +1,91 @@ +#ifndef _WDL_VIRTWND_SKIN_H_ +#define _WDL_VIRTWND_SKIN_H_ + +class LICE_IBitmap; + +#include "../ptrlist.h" + +typedef struct // if set these override the default virtualwnd styles for this object +{ + LICE_IBitmap *bgimage; + int bgimage_lt[2],bgimage_rb[2]; // size of + int bgimage_lt_out[2],bgimage_rb_out[2]; // size of outside area (like shadows) + int bgimage_noalphaflags; // 4x4 flags of "no alpha", so 65535 is image has no alpha whatsoever +} WDL_VirtualWnd_BGCfg; + + + +class WDL_VirtualWnd_BGCfgCache_ar; + +class WDL_VirtualWnd_BGCfgCache +{ +public: + WDL_VirtualWnd_BGCfgCache(int want_size=15, int max_size=30); + ~WDL_VirtualWnd_BGCfgCache(); + + void Invalidate(); + + LICE_IBitmap *GetCachedBG(int w, int h, void *owner_hint, const LICE_IBitmap *bgbmp); + void SetCachedBG(int w, int h, LICE_IBitmap *bm, void *owner_hint, const LICE_IBitmap *bgbmp); + +private: + WDL_VirtualWnd_BGCfgCache_ar *m_ar; + + + int m_want_size, m_max_size; +}; + +void WDL_VirtualWnd_PreprocessBGConfig(WDL_VirtualWnd_BGCfg *a); + +// used by elements to draw a WDL_VirtualWnd_BGCfg +#define WDL_VWND_SCALEDBLITBG_IGNORE_LR 0x40000000 +#define WDL_VWND_SCALEDBLITBG_IGNORE_INSIDE 0x20000000 +#define WDL_VWND_SCALEDBLITBG_IGNORE_OUTSIDE 0x10000000 +void WDL_VirtualWnd_ScaledBlitBG(LICE_IBitmap *dest, + WDL_VirtualWnd_BGCfg *src, + int destx, int desty, int destw, int desth, + int clipx, int clipy, int clipw, int cliph, + float alpha, int mode); +int WDL_VirtualWnd_ScaledBG_GetPix(WDL_VirtualWnd_BGCfg *src, + int ww, int wh, + int x, int y); + +void WDL_VirtualWnd_ScaledBlitSubBG(LICE_IBitmap *dest, + WDL_VirtualWnd_BGCfg *src, + int destx, int desty, int destw, int desth, + int clipx, int clipy, int clipw, int cliph, + int srcx, int srcy, int srcw, int srch, // these coordinates are not including pink lines (i.e. if pink lines are present, use src->bgimage->getWidth()-2, etc) + float alpha, int mode); + + +typedef struct // if set these override the default virtualwnd styles for this object +{ + WDL_VirtualWnd_BGCfg bgimagecfg[2]; + LICE_IBitmap *thumbimage[2]; // h,v + int thumbimage_lt[2],thumbimage_rb[2]; + unsigned int zeroline_color; // needs alpha channel set! +} WDL_VirtualSlider_SkinConfig; + +void WDL_VirtualSlider_PreprocessSkinConfig(WDL_VirtualSlider_SkinConfig *a); + +typedef struct +{ + LICE_IBitmap *image; // 3x width, second third is "mouseover" image. then mousedown, or straight image if image_issingle set + LICE_IBitmap *olimage; // drawn in second pass + + union + { + char flags; // &1 = overlay, &2=main + bool asBool; // on PPC this is 4 bytes, need to preserve it + } + image_ltrb_used; + bool image_issingle; + short image_ltrb_ol[4]; // extents outside the rect + short image_ltrb_main[4]; // unscaled areas of main image (not used if single) +} WDL_VirtualIconButton_SkinConfig; + +void WDL_VirtualIconButton_PreprocessSkinConfig(WDL_VirtualIconButton_SkinConfig *a); + + + +#endif \ No newline at end of file diff --git a/WDL/wingui/virtwnd-slider.cpp b/WDL/wingui/virtwnd-slider.cpp new file mode 100644 index 00000000..88f3e1bd --- /dev/null +++ b/WDL/wingui/virtwnd-slider.cpp @@ -0,0 +1,1173 @@ +/* + WDL - virtwnd-slider.cpp + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Implementation for virtual window sliders. + +*/ + +#include +#include "virtwnd-controls.h" +#include "../lice/lice.h" + +void vwnd_slider_drawknobstack(LICE_IBitmap *drawbm, double val, WDL_VirtualWnd_BGCfg *knobimage, int ksw, int ksh, int ks_offs, int dx, int dy, int dw, int dh, double alpha) +{ + const bool v = knobimage->bgimage->getWidth() < knobimage->bgimage->getHeight(); + + const int ni=((v ? knobimage->bgimage->getHeight() : knobimage->bgimage->getWidth())-ks_offs*2) / (v ? ksh : ksw); + + if (val<0.0)val=0.0; + else if (val>1.0)val=1.0; + int p=(int) (val * (ni-1)); + if (p<0) p=0; + else if (p> ni-1) p=ni-1; + + p *= (v ? ksh : ksw); + + if (ks_offs && + knobimage->bgimage_lt_out[0] > 0 && + knobimage->bgimage_lt_out[1] > 0 && + knobimage->bgimage_rb_out[0] > 0 && + knobimage->bgimage_rb_out[1] > 0) + { + int l = knobimage->bgimage_lt_out[0]-1; + int t = knobimage->bgimage_lt_out[1]-1; + int r = knobimage->bgimage_rb_out[0]-1; + int b = knobimage->bgimage_rb_out[1]-1; + + int ww = ksw - l - r; + if (ww > 0) + { + dx -= (dw * l) / ww; + dw = (dw * ksw) / ww; + } + int wh=ksh - t -b; + if (wh) + { + dy -= (dh * t) / wh; + dh = (dh * ksh) / wh; + } + } + + LICE_ScaledBlit(drawbm,knobimage->bgimage,dx,dy,dw,dh,ks_offs + (v?0:p),ks_offs + (v?p:0),ksw,ksh,alpha,LICE_BLIT_USE_ALPHA|LICE_BLIT_FILTER_BILINEAR); +} + + +WDL_VirtualWnd_BGCfg *vwnd_slider_getknobimageforsize(WDL_VirtualWnd_BGCfg *knoblist, int nknoblist,int *vieww, int *viewh, int *ksw, int *ksh, int *ks_offs) +{ + if (!knoblist) return NULL; + WDL_VirtualWnd_BGCfg *knobimage=NULL; + int x; + int best_neww=*vieww, best_newh = *viewh; + + double bestdiff=0; + double target_area_inv=1.0 / ((double)*vieww * *viewh); + + double target_aspect_inv = *viewh / (double) *vieww; + + for(x=0;xgetWidth(), h=knoblist[x].bgimage->getHeight(); + const bool isVS = w < h; + + const int hasPink = knoblist[x].bgimage_lt[0] > 0 && + knoblist[x].bgimage_lt[1] > 0 && + knoblist[x].bgimage_rb[0] > 0 && + knoblist[x].bgimage_rb[1] > 0; + + const int slice_w = isVS ? (w - hasPink*2) : + hasPink && knoblist[x].bgimage_lt[0]>1 ? (knoblist[x].bgimage_lt[0]-1 + (knoblist[x].bgimage_lt_out[0]>1 ? knoblist[x].bgimage_lt_out[0]-1:0)) : + (h-hasPink*2); + const int slice_h = !isVS ? (h - hasPink*2) : + hasPink && knoblist[x].bgimage_lt[1]>1 ? (knoblist[x].bgimage_lt[1]-1 + (knoblist[x].bgimage_lt_out[1]>1 ? knoblist[x].bgimage_lt_out[1]-1:0)) : + (w-hasPink*2); + + + int fmtw = slice_w, fmth=slice_h; + if (hasPink && + knoblist[x].bgimage_lt_out[0] > 0 && + knoblist[x].bgimage_lt_out[1] > 0 && + knoblist[x].bgimage_rb_out[0] > 0 && + knoblist[x].bgimage_rb_out[1] > 0) + { + int l = knoblist[x].bgimage_lt_out[0]-1; + int t = knoblist[x].bgimage_lt_out[1]-1; + int r = knoblist[x].bgimage_rb_out[0]-1; + int b = knoblist[x].bgimage_rb_out[1]-1; + + if (fmtw > l+r) fmtw -= l+r; + if (fmth > b+t) fmth -= b+t; + } + + // prioritize getting the aspect ratio right, then add target area differences -- this needs testing! + double diff = ((double)fmtw / fmth) * target_aspect_inv; + if (diff < 1.0) diff=1.0/diff; + + double diff2 = ((fmtw * (double)fmth) * target_area_inv); + if (diff2 < 1.0) diff2=1.0/diff2; + + diff += diff2 * 0.01; + + if (slice_w > 0 && slice_h > 0 && (!knobimage || bestdiff > diff)) + { + knobimage=&knoblist[x]; + bestdiff=diff; + *ksw = slice_w; + *ksh = slice_h; + *ks_offs = hasPink; + + int tmp=(fmtw * *viewh) / fmth; + if (tmp <= *vieww) + { + best_neww = tmp; + best_newh = *viewh; + } + else + { + best_neww = *vieww; + best_newh = (fmth * *vieww) / fmtw; + } + } + } + } + if (knobimage) + { + *vieww=best_neww; + *viewh=best_newh; + } + return knobimage; +} + + +WDL_VirtualSlider::WDL_VirtualSlider() +{ + m_knob_lineextrasize=0; + m_knobbias=0; + m_zl_color = m_knob_color=0; + m_is_knob=false; + m_tl_extra=m_br_extra=0; + m_skininfo=0; + m_bgcol1_msg=0; + m_minr=0; + m_maxr=1000; + m_needflush=0; + m_pos=m_center=500; + m_captured=false; + m_grayed = false; + m_knobbg[0]=m_knobbg[1]=0; + m_knobstacks=0; + m_nknobstacks=0; + m_sendmsgonclick=false; + m_dblclickmsg=0; +} + +WDL_VirtualSlider::~WDL_VirtualSlider() +{ +} + +bool WDL_VirtualSlider::GetIsVert() +{ + return m_position.right-m_position.left < m_position.bottom-m_position.top; +} + +static void AdjustThumbImageSize(int wndw, int wndh, WDL_VirtualSlider_SkinConfig *a, bool vert, int *bmw, int *bmh, int *startoffs=NULL, bool *want_knob=NULL, int knob_bias=0) +{ + if (want_knob) *want_knob=knob_bias>0; + if (a) + { + int ret=a->thumbimage_rb[vert] - a->thumbimage_lt[vert]; + if (ret>0) + { + if (startoffs) *startoffs = a->thumbimage_lt[vert]; + if (vert) + { + if (*bmh > ret) (*bmw)--; + *bmh=ret; + } + else + { + if (*bmw > ret) (*bmh)--; + *bmw=ret; + } + } + } + if (vert) + { + if (want_knob && *bmh >= wndh*3/4 && !knob_bias) *want_knob=true; + if (*bmh > wndh/2) + { + if (startoffs) *startoffs += (*bmh - wndh/2)/2; + *bmh=wndh/2; + } + } + else + { + if (want_knob && *bmw >= wndw*3/4 && !knob_bias) *want_knob=true; + if (*bmw > wndw/2) + { + if (startoffs) *startoffs += (*bmw - wndw/2)/2; + *bmw=wndw/2; + } + } +} + +void WDL_VirtualSlider_PreprocessSkinConfig(WDL_VirtualSlider_SkinConfig *a) +{ + if (a&&a->thumbimage[0]) + { + int w=a->thumbimage[0]->getWidth(); + int h=a->thumbimage[0]->getHeight(); + int x; + for (x = 0; x < w && LICE_GetPixel(a->thumbimage[0],x,h-1)==LICE_RGBA(255,0,255,255); x ++); + a->thumbimage_lt[0] = x; + for (x = w-1; x > a->thumbimage_lt[0]+1 && LICE_GetPixel(a->thumbimage[0],x,h-1)==LICE_RGBA(255,0,255,255); x --); + a->thumbimage_rb[0] = x; + } + if (a&&a->thumbimage[1]) + { + int w=a->thumbimage[1]->getWidth(); + int h=a->thumbimage[1]->getHeight(); + int y; + for (y = 0; y < h-4 && LICE_GetPixel(a->thumbimage[1],w-1,y)==LICE_RGBA(255,0,255,255); y++); + a->thumbimage_lt[1] = y; + for (y = h-1; y > a->thumbimage_lt[1]+1 && LICE_GetPixel(a->thumbimage[1],w-1,y)==LICE_RGBA(255,0,255,255); y --); + a->thumbimage_rb[1] = y; + } + WDL_VirtualWnd_PreprocessBGConfig(&a->bgimagecfg[0]); + WDL_VirtualWnd_PreprocessBGConfig(&a->bgimagecfg[1]); +} + +void WDL_VirtualSlider::GetButtonSize(int *w, int *h) +{ + if (m_is_knob) + { + *w=*h=0; + return; + } + bool isVert = GetIsVert(); + LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; + if (bm_image) + { + *w = bm_image->getWidth(); + *h = bm_image->getHeight(); + AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,m_skininfo,isVert,w,h); + } + else + { + bm_image=WDL_STYLE_GetSliderBitmap2(isVert); + if (bm_image) + { + *w=bm_image->getWidth(); + *h=bm_image->getHeight(); + } + else *w=*h=16; + AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,NULL,isVert,w,h); + } +} + + +void WDL_VirtualSlider::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + origin_x += m_position.left; // convert drawing origin to local coords + origin_y += m_position.top; + + bool isVert = GetIsVert(); + + int rsize=m_maxr-m_minr; + if (rsize<1)rsize=1; + + int viewh=m_position.bottom-m_position.top; + int vieww=m_position.right-m_position.left; + + WDL_VirtualWnd_BGCfg *back_image=m_skininfo && m_skininfo->bgimagecfg[isVert].bgimage ? &m_skininfo->bgimagecfg[isVert] : 0; + LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; + int bm_w=16,bm_h=16,bm_w2=16,bm_h2=16; + int imgoffset=0; + HBITMAP bm=0; + bool wantKnob=false; + if (bm_image) + { + bm_w2=bm_w=bm_image->getWidth(); + bm_h2=bm_h=bm_image->getHeight(); + AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w2,&bm_h2,&imgoffset,&wantKnob,m_knobbias); + } + else + { + bm_image=WDL_STYLE_GetSliderBitmap2(isVert); + if (bm_image) + { + bm_w2=bm_w=bm_image->getWidth(); + bm_h2=bm_h=bm_image->getHeight(); + } + AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w2,&bm_h2,&imgoffset,&wantKnob,m_knobbias); + } + + float alpha = (m_grayed ? 0.25f : 1.0f); + + m_is_knob = wantKnob; + + if (isVert||wantKnob) + { + int pos = ((m_maxr-m_pos)*(viewh-bm_h2))/rsize; //viewh - bm_h2 - ((m_pos-m_minr) * (viewh - bm_h2))/rsize; + + const int old_vieww=vieww, old_viewh=viewh, old_origin_x=origin_x, old_origin_y=origin_y; + + if (wantKnob) + { + int sz= min(vieww,viewh); + origin_x += (vieww-sz)/2; + origin_y += (viewh-sz)/2; + vieww = viewh = sz; + back_image = m_knobbg[sz>28]; + + if (back_image && !back_image->bgimage) back_image=NULL; + } + + + if (back_image) + { + WDL_VirtualWnd_ScaledBlitBG(drawbm,back_image, + origin_x,origin_y,vieww,viewh, + origin_x,origin_y,vieww,viewh, + 1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + + if (m_bgcol1_msg) + { + int brcol=-100; + SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); + if (brcol != -100) + { + static LICE_MemBitmap tmpbm;//not threadsafe + tmpbm.resize(vieww,viewh); + WDL_VirtualWnd_ScaledBlitBG(&tmpbm,back_image,0,0,vieww,viewh, + 0,0,vieww,viewh,1.0f,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + + LICE_ClearRect(&tmpbm,0,0,vieww,viewh,LICE_RGBA(0,0,0,255),LICE_RGBA(GetRValue(brcol),GetGValue(brcol),GetBValue(brcol),0)); + + RECT r={0,0,vieww,viewh}; + LICE_Blit(drawbm,&tmpbm,origin_x,origin_y,&r,0.5,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + } + } + } + + if (!wantKnob) + { + int zlc = m_zl_color; + if (!zlc && m_skininfo) zlc = m_skininfo->zeroline_color; + if (!back_image || zlc) + { + int center=m_center; + if (center < 0) center=WDL_STYLE_GetSliderDynamicCenterPos(); + + int y=((m_maxr-center)*(viewh-bm_h2))/rsize + ((bm_h-1)/2-imgoffset); + + if (!zlc) zlc = LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); + LICE_Line(drawbm,origin_x+2,origin_y+y,origin_x+vieww-2,origin_y+y, zlc, LICE_GETA(zlc)/255.0, LICE_BLIT_MODE_COPY,false); + } + + + if (!back_image) + { + + LICE_pixel fgcol = GSC(COLOR_3DHILIGHT); + fgcol = LICE_RGBA_FROMNATIVE(fgcol,255); + LICE_pixel bgcol=GSC(COLOR_3DSHADOW); + if (m_bgcol1_msg) + SendCommand(m_bgcol1_msg,(INT_PTR)&bgcol,GetID(),this); + bgcol = LICE_RGBA_FROMNATIVE(bgcol,255); + + + int offs= (vieww - 4)/2; + // white with black border, mmm + + RECT r={origin_x + offs,origin_y + bm_h2/3, origin_x + offs + 5,origin_y + viewh - bm_h2/3}; + + LICE_FillRect(drawbm,r.left+1,r.top+1, + r.right-r.left-2,r.bottom-r.top-2,bgcol,1.0f,LICE_BLIT_MODE_COPY); + + LICE_Line(drawbm,r.left+1,r.top,r.right-2,r.top,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.left+1,r.bottom-1,r.right-2,r.bottom-1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + + LICE_Line(drawbm,r.left,r.top+1,r.left,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.right-1,r.top+1,r.right-1,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + + } + + if (bm_image) + { + int ypos=origin_y+pos-imgoffset; + int xpos=origin_x; + + RECT r={0,0,bm_w2,bm_h}; + /* if (vieww m_minr && (m_pos < center || center >= m_maxr)) val = (m_pos-center) / (double)(center-m_minr); + else val = (m_pos-center) / (double)(m_maxr-center); + + if (knobimage && ksw>0 && ksh>0) + { + vwnd_slider_drawknobstack(drawbm,(val+1.0)*0.5,knobimage,ksw,ksh,ks_offs, + old_origin_x + (old_vieww - vw)/2,old_origin_y+(old_viewh - vh)/2,vw,vh,alpha + ); + } + else + { + LICE_pixel col = m_knob_color ? m_knob_color : LICE_RGBA_FROMNATIVE(GSC(COLOR_3DHILIGHT),255); + + float alpha = LICE_GETA(col)/255.0f; + int cx=origin_x+vieww/2; + int cy=origin_y+viewh/2; + float rd = vieww/2-4 + m_knob_lineextrasize; + float r2=rd*0.125f; + if (!back_image) LICE_Circle(drawbm, cx, cy, rd, col, alpha, LICE_BLIT_MODE_COPY, true); + + #define KNOBANGLE_MAX (3.14159*7.0/8.0); + float a = val*KNOBANGLE_MAX; + float sina=sin(a); + float cosa=cos(a); + float x1=cx+r2*sina; + float y1=cy-r2*cosa; + float x2=cx+rd*sina; + float y2=cy-rd*cosa; + LICE_FLine(drawbm, x1, y1, x2, y2, col, alpha, LICE_BLIT_MODE_COPY, true); + } + } + } + else + { + int pos = ((m_pos-m_minr) * (vieww - bm_w2))/rsize; + + if (back_image) + { + WDL_VirtualWnd_ScaledBlitBG(drawbm,back_image, + origin_x,origin_y,vieww,viewh, + origin_x,origin_y,vieww,viewh, + 1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); + // blit, tint color too? + + if (m_bgcol1_msg) + { + int brcol=-100; + SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); + if (brcol != -100) + { + static LICE_MemBitmap tmpbm; //not threadsafe + tmpbm.resize(vieww,viewh); + + WDL_VirtualWnd_ScaledBlitBG(&tmpbm,back_image,0,0,vieww,viewh, + 0,0,vieww,viewh,1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR); + + LICE_ClearRect(&tmpbm,0,0,vieww,viewh,LICE_RGBA(0,0,0,255),LICE_RGBA(GetRValue(brcol),GetGValue(brcol),GetBValue(brcol),0)); + + RECT r={0,0,vieww,viewh}; + LICE_Blit(drawbm,&tmpbm,origin_x,origin_y,&r,0.5,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + } + } + + } + + int zlc = m_zl_color; + if (!zlc && m_skininfo) zlc = m_skininfo->zeroline_color; + if (!back_image || zlc) + { + int center=m_center; + if (center < 0) center=WDL_STYLE_GetSliderDynamicCenterPos(); + + int x=((center-m_minr)*(vieww-bm_w2))/rsize + bm_w/2 - imgoffset; + + if (!zlc) zlc = LICE_RGBA_FROMNATIVE(GSC(COLOR_BTNTEXT),255); + + LICE_Line(drawbm,origin_x+x,origin_y+2,origin_x+x,origin_y+viewh-2, + zlc, LICE_GETA(zlc)/255.0, LICE_BLIT_MODE_COPY,false); + } + + if (!back_image) + { + LICE_pixel fgcol = GSC(COLOR_3DHILIGHT); + fgcol = LICE_RGBA_FROMNATIVE(fgcol,255); + LICE_pixel bgcol=GSC(COLOR_3DSHADOW); + if (m_bgcol1_msg) + SendCommand(m_bgcol1_msg,(INT_PTR)&bgcol,GetID(),this); + bgcol = LICE_RGBA_FROMNATIVE(bgcol,255); + + int offs= (viewh - 4)/2; + // white with black border, mmm + RECT r={origin_x + bm_w2/3,origin_y + offs, origin_x + vieww - bm_w2/3,origin_y + offs + 5}; + + LICE_FillRect(drawbm,r.left+1,r.top+1, + r.right-r.left-2,r.bottom-r.top-2,bgcol,1.0f,LICE_BLIT_MODE_COPY); + + LICE_Line(drawbm,r.left+1,r.top,r.right-2,r.top,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.left+1,r.bottom-1,r.right-2,r.bottom-1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + + LICE_Line(drawbm,r.left,r.top+1,r.left,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(drawbm,r.right-1,r.top+1,r.right-1,r.bottom-2,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); + + } + + if (bm_image) + { + int xpos=origin_x+pos-imgoffset; + int ypos=origin_y; + + RECT r={0,0,bm_w,bm_h2}; + /*if (viewh origin_x+m_position.right-m_position.left) + r.right = origin_x+m_position.right-m_position.left - (xpos-r.left); +*/ + + LICE_Blit(drawbm,bm_image,xpos,ypos,&r,alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA); + } + } + +} + +static double m_move_offset; +static int m_click_pos,m_last_y,m_last_x, m_last_precmode; + + +int WDL_VirtualSlider::OnMouseDown(int xpos, int ypos) +{ + if (m_grayed) return 0; + m_needflush=0; + + if (m__iaccess) m__iaccess->OnFocused(); + + bool isVert = GetIsVert(); + int rsize=m_maxr-m_minr; + if (rsize<1)rsize=1; + + int viewh=m_position.bottom-m_position.top; + int vieww=m_position.right-m_position.left; + if (vieww<1) vieww=1; + if (viewh<1) viewh=1; + + LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; + int bm_w=16,bm_h=16; + bool wantKnob=false; + if (bm_image) + { + bm_w=bm_image->getWidth(); + bm_h=bm_image->getHeight(); + AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w,&bm_h,NULL,&wantKnob,m_knobbias); + } + else + { + bm_image=WDL_STYLE_GetSliderBitmap2(isVert); + if (bm_image) + { + bm_w=bm_image->getWidth(); + bm_h=bm_image->getHeight(); + } + AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w,&bm_h,NULL,&wantKnob,m_knobbias); + } + + m_is_knob = wantKnob; + + m_last_y=ypos; + m_last_x=xpos; + m_last_precmode=0; + + bool needsendcmd = m_sendmsgonclick; + if (m_is_knob) + { + m_move_offset=0; + m_click_pos=m_pos; + } + else if (isVert) + { + m_move_offset=ypos-( viewh - bm_h - ((double)((m_pos-m_minr) * (viewh-bm_h))/(double)rsize)); + m_click_pos=m_pos; + if (!m_is_knob && (m_move_offset < 0 || m_move_offset >= bm_h)) + { + int xcent=xpos - vieww/2; + bool hit; + + if (m_skininfo && m_skininfo->bgimagecfg[1].bgimage) + { + LICE_pixel pix=WDL_VirtualWnd_ScaledBG_GetPix(&m_skininfo->bgimagecfg[1], + vieww,viewh,xpos,ypos); + + hit = LICE_GETA(pix)>=64; + } + else hit= (xcent >= -2 && xcent < 3 && ypos >= bm_h/3 && ypos <= viewh-bm_h/3); + + if (hit) + { + m_move_offset=bm_h/2; + int pos=m_minr+((viewh-bm_h - (ypos-m_move_offset))*rsize)/(viewh-bm_h); + if (pos < m_minr)pos=m_minr; + else if (pos > m_maxr)pos=m_maxr; + m_pos=pos; + + needsendcmd=false; + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,SB_THUMBTRACK,GetID(),this); + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + } + else return 0; + } + } + else + { + m_move_offset=xpos-( ((double)((m_pos-m_minr) * (vieww-bm_w))/(double)rsize)); + m_click_pos=m_pos; + if (m_move_offset < 0 || m_move_offset >= bm_w) + { + int ycent=ypos - viewh/2; + + bool hit; + if (m_skininfo && m_skininfo->bgimagecfg[0].bgimage) + { + LICE_pixel pix=WDL_VirtualWnd_ScaledBG_GetPix(&m_skininfo->bgimagecfg[0], + vieww,viewh,xpos,ypos); + + hit = LICE_GETA(pix)>=64; + } + else hit = (ycent >= -2 && ycent < 3 && xpos >= bm_w/3 && xpos <= vieww-bm_w/3); + + if (hit) + { + m_move_offset=bm_w/2; + int pos=m_minr+((xpos-m_move_offset)*rsize)/(vieww-bm_w); + if (pos < m_minr)pos=m_minr; + else if (pos > m_maxr)pos=m_maxr; + m_pos=pos; + + needsendcmd=false; + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:WM_HSCROLL,SB_THUMBTRACK,GetID(),this); + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + } + else return 0; + } + } + + m_captured=true; + if (needsendcmd) + { + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,SB_THUMBTRACK,GetID(),this); + if (chk.isOK() && m__iaccess) m__iaccess->OnStateChange(); + } + return 1; +} + + +void WDL_VirtualSlider::OnMoveOrUp(int xpos, int ypos, int isup) +{ + int pos; + bool isVert = GetIsVert(); + int rsize=m_maxr-m_minr; + if (rsize<1)rsize=1; + + int viewh=m_position.bottom-m_position.top; + int vieww=m_position.right-m_position.left; + + LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; + int bm_w=16,bm_h=16; + if (bm_image) + { + bm_w=bm_image->getWidth(); + bm_h=bm_image->getHeight(); + AdjustThumbImageSize(vieww,viewh,m_skininfo,isVert,&bm_w,&bm_h); + } + else + { + bm_image=WDL_STYLE_GetSliderBitmap2(isVert); + if (bm_image) + { + bm_w=bm_image->getWidth(); + bm_h=bm_image->getHeight(); + } + AdjustThumbImageSize(vieww,viewh,NULL,isVert,&bm_w,&bm_h); + } + + int precmode=0; + if (m_is_knob) isVert=true; + + if (isVert) + { +#ifndef _WIN32 + if (isup) pos=m_pos; + else +#endif + if (viewh <= bm_h || m_is_knob || (GetAsyncKeyState(VK_CONTROL)&0x8000)) + { + int sc=m_is_knob && !(GetAsyncKeyState(VK_CONTROL)&0x8000)?4:1; + pos = m_pos- ((ypos-m_last_y) - (m_is_knob ?xpos-m_last_x:0))*sc; + precmode=1; + } + else + { + pos=m_minr+ (((double)(viewh-bm_h - ypos + m_move_offset)*(double)rsize)/(double)(viewh-bm_h)); + } + if (pos < m_minr)pos=m_minr; + else if (pos > m_maxr)pos=m_maxr; + + + if (pos != m_pos || isup) + { + if (ypos == m_last_y&&(m_is_knob && xpos==m_last_x)) + pos=m_pos; + + if ((GetAsyncKeyState(VK_MENU)&0x8000) && isup) + pos=m_click_pos; + + m_pos=pos; + + if (isup || ypos != m_last_y||(m_is_knob&&xpos!=m_last_x)) + { + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:WM_VSCROLL,isup?SB_ENDSCROLL:SB_THUMBTRACK,GetID(),this); + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + } + } + } + else + { +#ifndef _WIN32 + if (isup) pos=m_pos; + else +#endif + if ((GetAsyncKeyState(VK_CONTROL)&0x8000) || vieww <= bm_w || m_is_knob) + { + pos = m_pos+ (xpos-m_last_x); + precmode=1; + } + else + { + pos=m_minr + (((double)(xpos - m_move_offset)*(double)rsize)/(double)(vieww-bm_w)); + } + if (pos < m_minr)pos=m_minr; + else if (pos > m_maxr)pos=m_maxr; + + if (pos != m_pos || isup) + { + if (xpos == m_last_x) + pos=m_pos; + + if ((GetAsyncKeyState(VK_MENU)&0x8000) && isup) + pos=m_click_pos; + + m_pos=pos; + + if (isup || xpos != m_last_x) + { + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:WM_HSCROLL,isup?SB_ENDSCROLL:SB_THUMBTRACK,GetID(),this); + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + } + } + } + if (precmode&&GetRealParent()) + { + if (xpos != m_last_x || ypos != m_last_y) + { + POINT p; + GetCursorPos(&p); + p.x-=(xpos-m_last_x); +#ifdef _WIN32 + p.y-=(ypos-m_last_y); +#else + p.y+=(ypos-m_last_y); +#endif + + + #ifdef _WIN32 + if (!m_is_knob) + { + POINT pt={0,0}; + ClientToScreen(GetRealParent(),&pt); + WDL_VWnd *wnd=this; + while (wnd) + { + RECT r; + wnd->GetPosition(&r); + pt.x+=r.left; + pt.y+=r.top; + wnd=wnd->GetParent(); + } + + if (isVert) + { + m_last_y=( viewh - bm_h - (((m_pos-m_minr) * (viewh-bm_h))/rsize))+m_move_offset; + p.y=m_last_y+pt.y; + } + else + { + m_last_x=( (((m_pos-m_minr) * (vieww-bm_w))/rsize))+m_move_offset; + p.x=m_last_x+pt.x; + } + } + #endif + + if (!SetCursorPos(p.x,p.y)) + { + m_last_y = ypos; + m_last_x = xpos; + } + } + do m_last_precmode++; while (ShowCursor(FALSE)>=0); + } + else + { + m_last_y=ypos; + m_last_x=xpos; + while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } + } + m_needflush=0; +} + +void WDL_VirtualSlider::OnMouseMove(int xpos, int ypos) +{ + if (m_grayed) return; + + if (m_captured) OnMoveOrUp(xpos,ypos,0); + else if (m_needflush && (xpos <0 || xpos > m_position.right- m_position.left || ypos < 0|| ypos > m_position.bottom-m_position.top )) + { + bool isVert = GetIsVert(); + m_needflush=0; + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_ENDSCROLL,GetID(),this); + if (chk.isOK() && m__iaccess) m__iaccess->OnStateChange(); + } +} + +void WDL_VirtualSlider::OnCaptureLost() +{ + m_captured=false; + while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } +} + +void WDL_VirtualSlider::OnMouseUp(int xpos, int ypos) +{ + if (m_grayed) return; + + if (m_captured) + { + OnMoveOrUp(xpos,ypos,1); + while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } + } + m_captured=false; +} + +bool WDL_VirtualSlider::OnMouseDblClick(int xpos, int ypos) +{ + if (m_grayed) return false; + + if (m_dblclickmsg) + { + SendCommand(m_dblclickmsg, 0, 0, this); + return true; + } + + bool isVert = GetIsVert(); + int pos=m_center; + if (pos < 0) pos=WDL_STYLE_GetSliderDynamicCenterPos(); + m_pos=pos; + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_ENDSCROLL,GetID(),this); + + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + + m_captured=false; + return true; +} + +bool WDL_VirtualSlider::OnMouseWheel(int xpos, int ypos, int amt) +{ + if (m_grayed) return false; + + if (!WDL_STYLE_AllowSliderMouseWheel()) return false; + + bool isVert = GetIsVert(); + int l=amt; + if (!(GetAsyncKeyState(VK_CONTROL)&0x8000)) l *= 16; + l *= (m_maxr-m_minr); + l/=120000; + if (!l) { if (amt<0)l=-1; else if (amt>0) l=1; } + + int pos=m_pos+l; + if (pos < m_minr)pos=m_minr; + else if (pos > m_maxr)pos=m_maxr; + + m_pos=pos; + + m_needflush=1; + WDL_VWND_DCHK(chk); + SendCommand(m_scrollmsg?m_scrollmsg:(isVert?WM_VSCROLL:WM_HSCROLL),SB_THUMBTRACK,GetID(),this); + + if (chk.isOK()) + { + RequestRedraw(NULL); + if (m__iaccess) m__iaccess->OnStateChange(); + } + return true; +} + + + + +int WDL_VirtualSlider::GetSliderPosition() +{ + if (m_pos < m_minr) return m_minr; + if (m_pos > m_maxr) return m_maxr; + return m_pos; +} + +void WDL_VirtualSlider::SetSliderPosition(int pos) +{ + if (!m_captured) + { + if (pos < m_minr) pos=m_minr; + else if (pos>m_maxr) pos=m_maxr; + + if (pos != m_pos) + { + m_pos=pos; + RequestRedraw(NULL); + } + } +} + +void WDL_VirtualSlider::GetPositionPaintExtent(RECT *r) +{ + *r=m_position; + bool isVert=GetIsVert(); + bool wantKnob=m_knobbias > 0; + LICE_IBitmap *bm_image=m_skininfo ? m_skininfo->thumbimage[isVert] : 0; + if (!bm_image && !wantKnob) + { + bm_image=WDL_STYLE_GetSliderBitmap2(isVert); + } + if (bm_image && !wantKnob) + { + int bm_w=bm_image->getWidth(); + int bm_h=bm_image->getHeight(); + int s=0; + int bm_w2=bm_w; + int bm_h2=bm_h; + AdjustThumbImageSize(m_position.right-m_position.left,m_position.bottom-m_position.top,m_skininfo,isVert,&bm_w,&bm_h,&s,&wantKnob,m_knobbias); + + if (!wantKnob) + { + int rsize=m_maxr-m_minr; + int viewh=m_position.bottom-m_position.top; + int vieww=m_position.right-m_position.left; + + if (isVert) + { + if (bm_w > vieww) + { + r->left-=(bm_w-vieww)/2+1; + r->right+=(bm_w-vieww)/2+1; + } + + int tadj=m_tl_extra; + int badj=m_br_extra; + + int pos = viewh - bm_h - ((m_pos-m_minr) * (viewh - bm_h))/rsize-s; + + if (-pos > tadj) tadj=-pos; + if (pos+bm_h2 > viewh+badj) badj=pos+bm_h2-viewh; + + //m_tl_extra=m_br_extra= + r->top-=tadj; //s; + r->bottom += badj; //(bm_h2-bm_h)-s; + } + else + { + if (bm_h > viewh) + { + r->top-=(bm_h-viewh)/2+1; + r->bottom+=(bm_h-viewh)/2+1; + } + + int ladj=m_tl_extra; + int radj=m_br_extra; + + int pos = ((m_pos-m_minr) * (vieww - bm_w))/rsize - s; + + if (-pos > ladj) ladj=-pos; + if (pos+bm_w2 > vieww+radj) radj=pos+bm_w2-vieww; + + r->left-=ladj; //s; + r->right += radj; // (bm_w2-bm_w)-s; + } + } + } + + if (wantKnob) + { + const int viewh=m_position.bottom-m_position.top; + const int vieww=m_position.right-m_position.left; + { + int sz= min(vieww,viewh); + int ox = m_position.left + (vieww-sz)/2; + int oy = m_position.top + (viewh-sz)/2; + + WDL_VirtualWnd_BGCfg *back_image = m_knobbg[sz>28]; + if (back_image && back_image->bgimage && + back_image->bgimage_lt_out[0]>0 && + back_image->bgimage_lt_out[1]>0 && + back_image->bgimage_rb_out[0]>0 && + back_image->bgimage_rb_out[1]>0) + { + int tmp = ox - (back_image->bgimage_lt_out[0]-1); + if (tmp < r->left) r->left=tmp; + tmp = oy - (back_image->bgimage_lt_out[1]-1); + if (tmp < r->top) r->top=tmp; + tmp = ox+sz+(back_image->bgimage_rb_out[0]-1); + if (tmp > r->right) r->right = tmp; + tmp = oy+sz+(back_image->bgimage_rb_out[1]-1); + if (tmp > r->bottom) r->bottom = tmp; + } + } + + { + int kvw = vieww, kvh=viewh; + int ksw=0,ksh=0,kso=0; + WDL_VirtualWnd_BGCfg *knobimage=vwnd_slider_getknobimageforsize(m_knobstacks,m_nknobstacks,&kvw,&kvh,&ksw,&ksh,&kso); + + if (knobimage && kso && ksw>0 && ksh>0 && + knobimage->bgimage_lt_out[0] > 0 && + knobimage->bgimage_lt_out[1] > 0 && + knobimage->bgimage_rb_out[0] > 0 && + knobimage->bgimage_rb_out[1] > 0) + { + const int ox = m_position.left + (vieww - kvw)/2; + const int oy = m_position.top + (viewh - kvh)/2; + + int ww = ksw - (knobimage->bgimage_lt_out[0]-1) - (knobimage->bgimage_rb_out[0]-1); + int wh = ksh - (knobimage->bgimage_lt_out[1]-1) - (knobimage->bgimage_rb_out[1]-1); + + if (ww > 0) + { + int tmp = ox - (kvw * (knobimage->bgimage_lt_out[0]-1))/ww; + if (tmp < r->left) r->left=tmp; + tmp = ox + kvw + (kvw * (knobimage->bgimage_rb_out[0]-1))/ww; + if (tmp > r->right) r->right=tmp; + } + if (wh > 0) + { + int tmp = oy - (kvh * (knobimage->bgimage_lt_out[1]-1))/wh; + if (tmp < r->top) r->top=tmp; + tmp = oy + kvh + (kvh * (knobimage->bgimage_rb_out[1]-1))/wh; + if (tmp > r->bottom) r->bottom=tmp; + } + } + } + } + else if (m_skininfo && m_skininfo->bgimagecfg[isVert].bgimage) + { + // expand paintextent by background image outer extent if necessary + WDL_VirtualWnd_BGCfg *b = &m_skininfo->bgimagecfg[isVert]; + if (b->bgimage_lt[0]>0 && + b->bgimage_lt[1]>0 && + b->bgimage_rb[0]>0 && + b->bgimage_rb[1]>0 && + b->bgimage_lt_out[0]>0 && + b->bgimage_lt_out[1]>0 && + b->bgimage_rb_out[0]>0 && + b->bgimage_rb_out[1]>0) + { + int l = m_position.left - (b->bgimage_lt_out[0]-1); + int t = m_position.top - (b->bgimage_lt_out[1]-1); + int right = m_position.right + b->bgimage_rb_out[0]-1; + int bot = m_position.bottom + b->bgimage_rb_out[1]-1; + + if (l < r->left) r->left=l; + if (t < r->top) r->top=t; + if (right > r->right) r->right = right; + if (bot > r->bottom) r->bottom = bot; + } + } +} diff --git a/WDL/wingui/virtwnd.cpp b/WDL/wingui/virtwnd.cpp new file mode 100644 index 00000000..21d3850e --- /dev/null +++ b/WDL/wingui/virtwnd.cpp @@ -0,0 +1,1635 @@ +/* + WDL - virtwnd.cpp + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + Implementation for basic virtual window types. + +*/ + +#include "virtwnd-controls.h" +#include "../lice/lice.h" +#include "../assocarray.h" + +WDL_VWnd_Painter::WDL_VWnd_Painter() +{ + m_GSC=0; + m_bm=0; + m_bgbm=0; + + m_paint_xorig=m_paint_yorig=0; + m_cur_hwnd=0; + m_wantg=-1; + m_gradstart=0.5; + m_gradslope=0.2; + m_bgcache=0; +} + +WDL_VWnd_Painter::~WDL_VWnd_Painter() +{ + delete m_bm; +} + +void WDL_VWnd_Painter::SetGSC(int (*GSC)(int)) +{ + m_GSC=GSC; +} +int WDL_VWnd_Painter::GSC(int a) +{ + if (m_GSC) return m_GSC(a); + return GetSysColor(a); +} + +void WDL_VWnd_Painter::SetBGGradient(int wantGradient, double start, double slope) +{ + m_wantg=wantGradient; + m_gradstart=start; + m_gradslope=slope; +} + +void WDL_VWnd_Painter::DoPaintBackground(LICE_IBitmap *bmOut, int bgcolor, const RECT *clipr, int wnd_w, int wnd_h, int xoffs, int yoffs) +{ + if (!bmOut) return; + + if (m_bgbm&&m_bgbm->bgimage) + { + int srcw=m_bgbm->bgimage->getWidth(); + int srch=m_bgbm->bgimage->getHeight(); + if (srcw && srch) + { + int fflags=0; + if (srcw < wnd_w/4 || srch < wnd_h/4) + fflags|=LICE_BLIT_FILTER_BILINEAR; + + + if (m_bgcache && !xoffs && !yoffs) + { + LICE_IBitmap *tmp = m_bgcache->GetCachedBG(wnd_w,wnd_h,this,m_bgbm->bgimage); + if (tmp) + { +// OutputDebugString("got cached render\n"); + LICE_Blit(bmOut,tmp,clipr->left,clipr->top,clipr->left,clipr->top,clipr->right-clipr->left,clipr->bottom-clipr->top,1.0f,LICE_BLIT_MODE_COPY); + } + else + { +// char bf[4096]; +// sprintf(bf,"fail %d,%d %08x\n",wnd_w,wnd_h,m_bgbm->bgimage); +// OutputDebugString(bf); + WDL_VirtualWnd_ScaledBlitBG(bmOut,m_bgbm,0,0,wnd_w,wnd_h, + 0,0, + wnd_w, + wnd_h, + 1.0,LICE_BLIT_MODE_COPY|fflags); + m_bgcache->SetCachedBG(wnd_w,wnd_h,bmOut,this,m_bgbm->bgimage); + } + } + else + { + WDL_VirtualWnd_ScaledBlitBG(bmOut,m_bgbm,xoffs,yoffs,wnd_w,wnd_h, + clipr->left+xoffs,clipr->top+yoffs, + clipr->right-clipr->left, + clipr->bottom-clipr->top, + 1.0,LICE_BLIT_MODE_COPY|fflags); + } + + tintRect(bmOut,clipr,xoffs,yoffs); + + m_bgbm=0; + return; + } + } + + if (bgcolor<0) bgcolor=m_GSC?m_GSC(COLOR_3DFACE):GetSysColor(COLOR_3DFACE); + + double gradslope=m_gradslope; + double gradstart=m_gradstart; + bool wantGrad=m_wantg>0; + if (m_wantg<0) wantGrad=WDL_STYLE_GetBackgroundGradient(&gradstart,&gradslope); + + int needfill=1; + + if (wantGrad && gradslope >= 0.01) + { + + { + needfill=0; + + int spos = (int) (gradstart * wnd_h); + if (spos > 0) + { + if (spos > wnd_h) spos=wnd_h; + if (clipr->top < spos) + { + LICE_FillRect(bmOut,clipr->left+xoffs,clipr->top+yoffs, + clipr->right-clipr->left,spos-clipr->top, + LICE_RGBA_FROMNATIVE(bgcolor,255),1.0f,LICE_BLIT_MODE_COPY); + } + } + else spos=0; + + if (spos < wnd_h) + { + struct + { + int x,y,Red,Green,Blue; + } + vert[2]={{0,},}; + + double sr=GetRValue(bgcolor); + double sg=GetGValue(bgcolor); + double sb=GetBValue(bgcolor); + + vert [0] .x = clipr->left; + vert [1] .x = clipr->right; + + + vert[0].y=clipr->top; + vert[1].y=clipr->bottom; + + if (vert[0].y < spos) vert[0].y=spos; + if (vert[1].y>wnd_h) vert[1].y=wnd_h; + + wnd_h-=spos; + + int x; + for (x =0 ; x < 2; x ++) + { + double sc1=(wnd_h-(vert[x].y-spos)*gradslope)/(double)wnd_h * 256.0; + + vert[x].Red = (int) (sr * sc1); + vert[x].Green = (int) (sg * sc1); + vert[x].Blue = (int) (sb * sc1); + } + + { + + int bmh=vert[1].y-vert[0].y; + float s=(float) (1.0/(65535.0*bmh)); + + LICE_GradRect(bmOut,vert[0].x+xoffs,vert[0].y+yoffs,clipr->right-clipr->left,bmh, + vert[0].Red/65535.0f,vert[0].Green/65535.0f,vert[0].Blue/65535.0f,1.0,0,0,0,0, + (vert[1].Red-vert[0].Red)*s, + (vert[1].Green-vert[0].Green)*s, + (vert[1].Blue-vert[0].Blue)*s, + 0.0,LICE_BLIT_MODE_COPY); + } + } + } + } + + + + if (needfill) + { + LICE_FillRect(bmOut,clipr->left+xoffs, + clipr->top+yoffs, + clipr->right-clipr->left, + clipr->bottom-clipr->top,LICE_RGBA_FROMNATIVE(bgcolor,255),1.0f,LICE_BLIT_MODE_COPY); + } + +} + +void WDL_VWnd_Painter::PaintBegin(HWND hwnd, int bgcolor, const RECT *limitBGrect, const RECT *windowRect) +{ + if (!hwnd) return; + if (!m_cur_hwnd) + { + if (BeginPaint(hwnd,&m_ps)) + { + m_cur_hwnd=hwnd; + } + if (m_cur_hwnd) + { + RECT r; + if (windowRect) r=*windowRect; + else GetClientRect(m_cur_hwnd,&r); + int fwnd_w=r.right-r.left,fwnd_h=r.bottom-r.top; + if (fwnd_h<0)fwnd_h=-fwnd_h; + + int wnd_w,wnd_h; + + if (fwnd_w < 2048 && fwnd_h < 2048) + { + m_paint_xorig=m_paint_yorig=0; + wnd_w=fwnd_w; + wnd_h=fwnd_h; + } + else // alternate large canvas mode + { + m_bgcache=0; // force no caching in large canvas mode + + // note: there can be some slight background artifacts in this mode that need to be resolved (REAPER TCP bg bottom line on partial redraw etc) + m_paint_xorig=m_ps.rcPaint.left; + m_paint_yorig=m_ps.rcPaint.top; + wnd_w = m_ps.rcPaint.right-m_ps.rcPaint.left; + wnd_h = m_ps.rcPaint.bottom - m_ps.rcPaint.top; + } + + if (wnd_h<0)wnd_h=-wnd_h; + + if (!m_bm) m_bm=new LICE_SysBitmap; + + if (m_bm->getWidth()getHeight() < wnd_h) + { + m_bm->resize(max(m_bm->getWidth(),wnd_w),max(m_bm->getHeight(),wnd_h)); + } + + if (!limitBGrect || (limitBGrect->left <1 && limitBGrect->top < 1 && limitBGrect->right >= fwnd_w && limitBGrect->bottom >= fwnd_h)) + { + DoPaintBackground(m_bm,bgcolor,&m_ps.rcPaint, fwnd_w, fwnd_h, -m_paint_xorig, -m_paint_yorig); + } + else + { + RECT tr = m_ps.rcPaint; + if (tr.left < limitBGrect->left) tr.left = limitBGrect->left; + if (tr.top < limitBGrect->top) tr.top = limitBGrect->top; + if (tr.right > limitBGrect->right) tr.right = limitBGrect->right; + if (tr.bottom > limitBGrect->bottom) tr.bottom = limitBGrect->bottom; + + if (tr.left < tr.right && tr.top < tr.bottom) + { + int w=limitBGrect->right-limitBGrect->left; + int h=limitBGrect->bottom-limitBGrect->top; + + int x=limitBGrect->left - m_paint_xorig; + int y=limitBGrect->top - m_paint_yorig; + LICE_SubBitmap bm(m_bm,x,y,w,h); + tr.left -= max(x,0); + tr.right -= max(x,0); + tr.bottom -= max(y,0); + tr.top -= max(y,0); + DoPaintBackground(&bm,bgcolor,&tr, w,h,-m_paint_xorig + min(x,0), -m_paint_yorig + min(y,0)); + } + } + } + } +} + + +#ifdef _WIN32 +typedef struct +{ + HRGN rgn; + HWND par; + RECT *sr; +} enumInfo; + +static BOOL CALLBACK enumProc(HWND hwnd,LPARAM lParam) +{ + enumInfo *p=(enumInfo*)lParam; + if (IsWindowVisible(hwnd)) + { + RECT r; + GetWindowRect(hwnd,&r); + ScreenToClient(p->par,(LPPOINT)&r); + ScreenToClient(p->par,((LPPOINT)&r)+1); + if (!p->rgn) p->rgn=CreateRectRgnIndirect(p->sr); + + HRGN rgn2=CreateRectRgnIndirect(&r); + CombineRgn(p->rgn,p->rgn,rgn2,RGN_DIFF); + DeleteObject(rgn2); + } + return TRUE; +} +#endif + +void WDL_VWnd_Painter::PaintEnd() +{ + if (!m_cur_hwnd) return; + if (m_bm) + { +#ifdef _WIN32 + HRGN rgnsave=0; + if (1) + { + enumInfo a={0,m_cur_hwnd,&m_ps.rcPaint}; + EnumChildWindows(m_cur_hwnd,enumProc,(LPARAM)&a); + if (a.rgn) + { + rgnsave=CreateRectRgn(0,0,0,0); + GetClipRgn(m_ps.hdc,rgnsave); + + ExtSelectClipRgn(m_ps.hdc,a.rgn,RGN_AND); + DeleteObject(a.rgn); + } + } + BitBlt(m_ps.hdc,m_ps.rcPaint.left,m_ps.rcPaint.top, + m_ps.rcPaint.right-m_ps.rcPaint.left, + m_ps.rcPaint.bottom-m_ps.rcPaint.top, + m_bm->getDC(),m_ps.rcPaint.left-m_paint_xorig,m_ps.rcPaint.top-m_paint_yorig,SRCCOPY); + + if (rgnsave) + { + SelectClipRgn(m_ps.hdc,rgnsave); + DeleteObject(rgnsave); + } +#else + SWELL_SyncCtxFrameBuffer(m_bm->getDC()); + BitBlt(m_ps.hdc,m_ps.rcPaint.left,m_ps.rcPaint.top, + m_ps.rcPaint.right-m_ps.rcPaint.left, + m_ps.rcPaint.bottom-m_ps.rcPaint.top, + m_bm->getDC(),m_ps.rcPaint.left-m_paint_xorig,m_ps.rcPaint.top-m_paint_yorig,SRCCOPY); +#endif + } + EndPaint(m_cur_hwnd,&m_ps); + m_cur_hwnd=0; +} + +void WDL_VWnd_Painter::GetPaintInfo(RECT *rclip, int *xoffsdraw, int *yoffsdraw) +{ + if (rclip) *rclip = m_ps.rcPaint; + if (xoffsdraw) *xoffsdraw = -m_paint_xorig; + if (yoffsdraw) *yoffsdraw = -m_paint_yorig; +} + +void WDL_VWnd_Painter::tintRect(LICE_IBitmap *bmOut, const RECT *clipr, int xoffs, int yoffs) +{ + if (m_bgbmtintcolor>=0) + { + float rv=GetRValue(m_bgbmtintcolor)/255.0f; + float gv=GetGValue(m_bgbmtintcolor)/255.0f; + float bv=GetBValue(m_bgbmtintcolor)/255.0f; + + float avg=(rv+gv+bv)*0.33333f; + if (avg<0.05f)avg=0.05f; + + float sc=0.5f; + float sc2 = (1.0f-sc)/avg; + + float sc3=32.0f; + float sc4=64.0f*(avg-0.5f); + // tint + LICE_MultiplyAddRect(bmOut,clipr->left+xoffs,clipr->top+yoffs,clipr->right-clipr->left,clipr->bottom-clipr->top, + sc+rv*sc2,sc+gv*sc2,sc+bv*sc2,1, + (rv-avg)*sc3+sc4, + (gv-avg)*sc3+sc4, + (bv-avg)*sc3+sc4, + 0); + } +} + + +void WDL_VWnd_Painter::PaintBGCfg(WDL_VirtualWnd_BGCfg *bitmap, const RECT *coords, bool allowTint, float alpha, int mode) +{ + if (!bitmap || !coords || !bitmap->bgimage || !m_bm) return; + + + WDL_VirtualWnd_ScaledBlitBG(m_bm,bitmap,coords->left - m_paint_xorig, + coords->top - m_paint_yorig, + coords->right-coords->left, + coords->bottom-coords->top, + m_ps.rcPaint.left - m_paint_xorig, + m_ps.rcPaint.top - m_paint_yorig, + m_ps.rcPaint.right - m_ps.rcPaint.left, + m_ps.rcPaint.bottom - m_ps.rcPaint.top,alpha,mode); + + if (allowTint) + { + RECT rr={ + max(coords->left,m_ps.rcPaint.left), + max(coords->top,m_ps.rcPaint.top), + min(coords->right,m_ps.rcPaint.right), + min(coords->bottom,m_ps.rcPaint.bottom) + }; + + if (rr.right>rr.left && rr.bottom>rr.top) + tintRect(m_bm,&rr,-m_paint_xorig,-m_paint_yorig); + } + +} + +void WDL_VWnd_Painter::PaintVirtWnd(WDL_VWnd *vwnd, int borderflags) +{ + RECT tr=m_ps.rcPaint; + if (!m_bm||!m_cur_hwnd|| !vwnd->IsVisible()) return; + + RECT r; + vwnd->GetPosition(&r); // maybe should use GetPositionPaintExtent or GetPositionPaintOverExtent ? + + if (tr.leftr.right) tr.right=r.right; + if (tr.topr.bottom)tr.bottom=r.bottom; + + if (tr.bottom > tr.top && tr.right > tr.left) + { + tr.left -= m_paint_xorig; + tr.right -= m_paint_xorig; + tr.top -= m_paint_yorig; + tr.bottom -= m_paint_yorig; + vwnd->SetCurPainter(this); + vwnd->OnPaint(m_bm,-m_paint_xorig,-m_paint_yorig,&tr); + if (borderflags) + { + PaintBorderForRect(&r,borderflags); + } + if (vwnd->WantsPaintOver()) vwnd->OnPaintOver(m_bm,-m_paint_xorig,-m_paint_yorig,&tr); + vwnd->SetCurPainter(NULL); + + } +} + +void WDL_VWnd_Painter::PaintBorderForHWND(HWND hwnd, int borderflags) +{ +#ifdef _WIN32 + if (m_cur_hwnd) + { + RECT r; + GetWindowRect(hwnd,&r); + ScreenToClient(m_cur_hwnd,(LPPOINT)&r); + ScreenToClient(m_cur_hwnd,((LPPOINT)&r)+1); + PaintBorderForRect(&r,borderflags); + } +#endif +} + +void WDL_VWnd_Painter::PaintBorderForRect(const RECT *r, int borderflags) +{ + if (!m_bm|| !m_cur_hwnd||!borderflags) return; + RECT rrr = *r; + rrr.left-=m_paint_xorig; + rrr.right-=m_paint_xorig; + rrr.top-=m_paint_yorig; + rrr.bottom-=m_paint_yorig; + + LICE_pixel pencol = m_GSC?m_GSC(COLOR_3DHILIGHT):GetSysColor(COLOR_3DHILIGHT); + LICE_pixel pencol2 = m_GSC?m_GSC(COLOR_3DSHADOW):GetSysColor(COLOR_3DSHADOW); + pencol = LICE_RGBA_FROMNATIVE(pencol,255); + pencol2 = LICE_RGBA_FROMNATIVE(pencol2,255); + + if (borderflags== WDL_VWP_SUNKENBORDER || borderflags == WDL_VWP_SUNKENBORDER_NOTOP) + { + LICE_Line(m_bm,rrr.left-1,rrr.bottom,rrr.right,rrr.bottom,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(m_bm,rrr.right,rrr.bottom,rrr.right,rrr.top-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + + if (borderflags != WDL_VWP_SUNKENBORDER_NOTOP) + LICE_Line(m_bm,rrr.right,rrr.top-1,rrr.left-1,rrr.top-1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + + LICE_Line(m_bm,rrr.left-1,rrr.top-1,rrr.left-1,rrr.bottom,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + } + else if (borderflags == WDL_VWP_DIVIDER_VERT) // vertical + { + int left=rrr.left; + + LICE_Line(m_bm,left,rrr.top,left,rrr.bottom+1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(m_bm,left+1,rrr.top,left+1,rrr.bottom+1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + } + else if (borderflags == WDL_VWP_DIVIDER_HORZ) + { + int top=rrr.top+1; + LICE_Line(m_bm,rrr.left,top,rrr.right+1,top,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); + LICE_Line(m_bm,rrr.left,top+1,rrr.right+1,top+1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); + } +} + +WDL_VWnd::WDL_VWnd() +{ + m__iaccess=0; + m__iaccess_desc=0; + m_visible=true; m_id=0; + m_position.left=0; m_position.top=0; m_position.right=0; m_position.bottom=0; + m_parent=0; + m_children=0; + m_realparent=0; + m_captureidx=-1; + m_lastmouseidx=-1; + m_userdata=0; + m_curPainter=0; +} + +WDL_VWnd::~WDL_VWnd() +{ + if (m_children) + { + m_children->Empty(true); + delete m_children; + } + if (m__iaccess) m__iaccess->Release(); +} + +int WDL_VWnd::GSC(int a) +{ + return m_curPainter ? m_curPainter->GSC(a) : GetSysColor(a); +} + +INT_PTR WDL_VWnd::SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src) +{ + if (m_realparent) + { + return SendMessage(m_realparent,command,parm1,parm2); + } + else if (m_parent) return m_parent->SendCommand(command,parm1,parm2,src); + return 0; +} + +void WDL_VWnd::RequestRedraw(RECT *r) +{ + if (!IsVisible() || + m_position.right <= m_position.left || + m_position.bottom <= m_position.top) return; + + RECT r2; + + if (r) + { + r2=*r; + r2.left+=m_position.left; r2.right += m_position.left; + r2.top += m_position.top; r2.bottom += m_position.top; + } + else + { + GetPositionPaintExtent(&r2); + RECT r3; + if (WantsPaintOver()) + { + GetPositionPaintOverExtent(&r3); + if (r3.leftr2.right)r2.right=r3.right; + if (r3.bottom>r2.bottom)r2.bottom=r3.bottom; + } + } + + if (m_realparent) + { +#ifdef _WIN32 + HWND hCh; + if ((hCh=GetWindow(m_realparent,GW_CHILD))) + { + HRGN rgn=CreateRectRgnIndirect(&r2); + int n=30; // limit to 30 children + while (n-- && hCh) + { + if (IsWindowVisible(hCh)) + { + RECT r; + GetWindowRect(hCh,&r); + ScreenToClient(m_realparent,(LPPOINT)&r); + ScreenToClient(m_realparent,((LPPOINT)&r)+1); + HRGN tmprgn=CreateRectRgn(r.left,r.top,r.right,r.bottom); + CombineRgn(rgn,rgn,tmprgn,RGN_DIFF); + DeleteObject(tmprgn); + } + hCh=GetWindow(hCh,GW_HWNDNEXT); + } + InvalidateRgn(m_realparent,rgn,FALSE); + DeleteObject(rgn); + + } + else +#else + // OS X, expand region up slightly + r2.top--; +#endif + InvalidateRect(m_realparent,&r2,FALSE); + } + else if (m_parent) m_parent->RequestRedraw(&r2); +} + +bool WDL_VWnd::IsDescendent(WDL_VWnd *w) +{ + if (!w || !m_children) return false; + int x,n=m_children->GetSize(); + for(x=0;xGet(x) == w) return true; + for(x=0;xGet(x); + if (tmp && tmp->IsDescendent(w)) return true; + } + return false; +} + +void WDL_VWnd::SetChildPosition(WDL_VWnd *ch, int pos) +{ + if (!ch || !m_children) return; + int x; + for(x=0;xGetSize();x++) + { + if (m_children->Get(x) == ch) + { + if (pos>x) pos--; + if (pos != x) + { + m_children->Delete(x); + m_children->Insert(pos,ch); + } + return; + } + } +} + + +void WDL_VWnd::AddChild(WDL_VWnd *wnd, int pos) +{ + if (!wnd) return; + + wnd->SetParent(this); + if (!m_children) m_children=new WDL_PtrList; + if (pos<0||pos>=m_children->GetSize()) m_children->Add(wnd); + else m_children->Insert(pos,wnd); + if (m__iaccess) m__iaccess->ClearCaches(); +} + +WDL_VWnd *WDL_VWnd::GetChildByID(int id) +{ + if (m_children) + { + int x; + for (x = 0; x < m_children->GetSize(); x ++) + if (m_children->Get(x)->GetID()==id) return m_children->Get(x); + WDL_VWnd *r; + for (x = 0; x < m_children->GetSize(); x ++) if ((r=m_children->Get(x)->GetChildByID(id))) return r; + } + + return 0; +} + +void WDL_VWnd::RemoveChild(WDL_VWnd *wnd, bool dodel) +{ + int idx=m_children ? m_children->Find(wnd) : -1; + if (idx>=0) + { + if (!dodel) + { + WDL_VWnd *ch = m_children->Get(idx); + if (ch) ch->SetParent(NULL); + } + m_children->Delete(idx,dodel); + } + if (m__iaccess) m__iaccess->ClearCaches(); +} + + +void WDL_VWnd::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + int x; + if (m_children) for (x = m_children->GetSize()-1; x >=0; x --) + { + WDL_VWnd *ch=m_children->Get(x); + if (ch->IsVisible()) + { + RECT re; + ch->GetPosition(&re); + if (re.right>re.left&&re.bottom>re.top) + { + ch->GetPositionPaintExtent(&re); + re.left += origin_x + m_position.left; + re.right += origin_x + m_position.left; + re.top += origin_y + m_position.top; + re.bottom += origin_y + m_position.top; + + RECT cr=*cliprect; + if (cr.left < re.left) cr.left=re.left; + if (cr.right > re.right) cr.right=re.right; + if (cr.top < re.top) cr.top=re.top; + if (cr.bottom > re.bottom) cr.bottom=re.bottom; + + if (cr.left < cr.right && cr.top < cr.bottom) + { + ch->SetCurPainter(m_curPainter); + ch->OnPaint(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr); + ch->SetCurPainter(NULL); + } + } + } + } +} + +void WDL_VWnd::OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) +{ + int x; + if (m_children) for (x = m_children->GetSize()-1; x >=0; x --) + { + WDL_VWnd *ch=m_children->Get(x); + if (ch->IsVisible() && ch->WantsPaintOver()) + { + RECT re; + ch->GetPosition(&re); + if (re.right>re.left && re.bottom > re.top) + { + ch->GetPositionPaintOverExtent(&re); + re.left += origin_x + m_position.left; + re.right += origin_x + m_position.left; + re.top += origin_y + m_position.top; + re.bottom += origin_y + m_position.top; + + RECT cr=*cliprect; + + if (cr.left < re.left) cr.left=re.left; + if (cr.right > re.right) cr.right=re.right; + if (cr.top < re.top) cr.top=re.top; + if (cr.bottom > re.bottom) cr.bottom=re.bottom; + + if (cr.left < cr.right && cr.top < cr.bottom) + { + ch->SetCurPainter(m_curPainter); + ch->OnPaintOver(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr); + ch->SetCurPainter(NULL); + } + } + } + } +} + +int WDL_VWnd::GetNumChildren() +{ + return m_children ? m_children->GetSize() : 0; +} +WDL_VWnd *WDL_VWnd::EnumChildren(int x) +{ + return m_children ? m_children->Get(x) : 0; +} + +void WDL_VWnd::RemoveAllChildren(bool dodel) +{ + if (m_children) + { + if (!dodel) // update parent pointers + { + int x; + for (x = 0; x < m_children->GetSize(); x++) + { + WDL_VWnd *ch = m_children->Get(x); + if (ch) ch->SetParent(NULL); + } + } + m_children->Empty(dodel); + } +} + +WDL_VWnd *WDL_VWnd::VirtWndFromPoint(int xpos, int ypos, int maxdepth) +{ + int x; + if (m_children) for (x = 0; x < m_children->GetSize(); x++) + { + WDL_VWnd *wnd=m_children->Get(x); + if (wnd->IsVisible()) + { + RECT r; + wnd->GetPosition(&r); + if (xpos >= r.left && xpos < r.right && ypos >= r.top && ypos < r.bottom) + { + if (maxdepth!=0) + { + WDL_VWnd *cwnd=wnd->VirtWndFromPoint(xpos-r.left,ypos-r.top,maxdepth > 0 ? (maxdepth-1) : -1); + if (cwnd) return cwnd; + } + return wnd; + } + } + } + return 0; + +} + + +int WDL_VWnd::OnMouseDown(int xpos, int ypos) // returns TRUE if handled +{ + if (!m_children) return 0; + + WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); + if (!wnd) + { + m_captureidx=-1; + return 0; + } + RECT r; + wnd->GetPosition(&r); + WDL_VWND_DCHK(chk); + int a; + if ((a=wnd->OnMouseDown(xpos-r.left,ypos-r.top))) + { + if (a<0) return -1; + if (chk.isOK()) m_captureidx=m_children->Find(wnd); + return 1; + } + return 0; +} + +bool WDL_VWnd::OnMouseDblClick(int xpos, int ypos) // returns TRUE if handled +{ + WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); + if (!wnd) return false; + RECT r; + wnd->GetPosition(&r); + return wnd->OnMouseDblClick(xpos-r.left,ypos-r.top); +} + + +bool WDL_VWnd::OnMouseWheel(int xpos, int ypos, int amt) +{ + WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); + if (!wnd) return false; + RECT r; + wnd->GetPosition(&r); + return wnd->OnMouseWheel(xpos-r.left,ypos-r.top,amt); +} + + +bool WDL_VWnd::GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz) +{ + WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); + if (!wnd) return false; + + RECT r; + wnd->GetPosition(&r); + return wnd->GetToolTipString(xpos-r.left,ypos-r.top,bufOut,bufOutSz); +} + +int WDL_VWnd::UpdateCursor(int xpos, int ypos) +{ + WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0); + if (!wnd) return 0; + + RECT r; + wnd->GetPosition(&r); + return wnd->UpdateCursor(xpos-r.left,ypos-r.top); +} + +void WDL_VWnd::OnMouseMove(int xpos, int ypos) +{ + if (!m_children) return; + + WDL_VWnd *wnd=m_children->Get(m_captureidx); + + WDL_VWND_DCHK(chk); + if (!wnd) + { + wnd=VirtWndFromPoint(xpos,ypos,0); + if (wnd) // todo: stuff so if the mouse goes out of the window completely, the virtualwnd gets notified + { + int idx=m_children->Find(wnd); + if (idx != m_lastmouseidx) + { + WDL_VWnd *t=m_children->Get(m_lastmouseidx); + if (t) + { + RECT r; + t->GetPosition(&r); + t->OnMouseMove(xpos-r.left,ypos-r.top); + } + if (chk.isOK()) m_lastmouseidx=idx; + } + } + else + { + WDL_VWnd *t=m_children->Get(m_lastmouseidx); + if (t) + { + RECT r; + t->GetPosition(&r); + t->OnMouseMove(xpos-r.left,ypos-r.top); + } + if (chk.isOK()) m_lastmouseidx=-1; + } + } + + if (wnd && chk.isOK()) + { + RECT r; + wnd->GetPosition(&r); + wnd->OnMouseMove(xpos-r.left,ypos-r.top); + } +} + +void WDL_VWnd::OnCaptureLost() +{ + int oldcap=m_captureidx; + m_captureidx=-1; + if (m_children) + { + WDL_VWnd *wnd=m_children->Get(oldcap); + if (wnd) + { + wnd->OnCaptureLost(); + } + } +} + +void WDL_VWnd::OnMouseUp(int xpos, int ypos) +{ + int oldcap=m_captureidx; + m_captureidx=-1; // set this before passing to children, in case a child ends up destroying us + if (m_children) + { + WDL_VWnd *wnd=m_children->Get(oldcap); + + if (!wnd) + { + wnd=VirtWndFromPoint(xpos,ypos,0); + } + + if (wnd) + { + RECT r; + wnd->GetPosition(&r); + wnd->OnMouseUp(xpos-r.left,ypos-r.top); + } + } +} +void WDL_VWnd::GetPositionInTopVWnd(RECT *r) +{ + GetPosition(r); + WDL_VWnd *par=GetParent(); + while (par) + { + WDL_VWnd *tmp=par; + par=par->GetParent(); + if (par) + { + RECT t; + tmp->GetPosition(&t); + r->left+=t.left; + r->right+=t.left; + r->top+=t.top; + r->bottom+=t.top; + } + }; + +} + +class WDL_VirtualWnd_BGCfgCache_img +{ +public: + WDL_VirtualWnd_BGCfgCache_img(int szinfo, LICE_IBitmap *image, unsigned int now) + { + lastowner=0; + bgimage=image; + sizeinfo=szinfo; + lastused=now; + } + ~WDL_VirtualWnd_BGCfgCache_img() + { + delete bgimage; + } + + LICE_IBitmap *bgimage; + unsigned int sizeinfo; // (h<<16)+w + unsigned int lastused; // last used time + void *lastowner; + + static int compar(const WDL_VirtualWnd_BGCfgCache_img **a, const WDL_VirtualWnd_BGCfgCache_img ** b) + { + return (*a)->sizeinfo - (*b)->sizeinfo; + } +}; + + +class WDL_VirtualWnd_BGCfgCache_ar +{ +public: + WDL_VirtualWnd_BGCfgCache_ar() : m_cachelist(compar, NULL, NULL, destrval) { } + ~WDL_VirtualWnd_BGCfgCache_ar() { } + + WDL_AssocArray * > m_cachelist; + + static void destrval(WDL_PtrList *list) + { + if (list) list->Empty(true); + delete list; + } + static int compar(const LICE_IBitmap **a, const LICE_IBitmap ** b) + { + if ((*a) < (*b)) return -1; + if ((*a) > (*b)) return 1; + return 0; + } + +}; + + +WDL_VirtualWnd_BGCfgCache::WDL_VirtualWnd_BGCfgCache(int want_size, int max_size) +{ + m_ar = new WDL_VirtualWnd_BGCfgCache_ar; + m_want_size=want_size; + m_max_size = max_size; +} +WDL_VirtualWnd_BGCfgCache::~WDL_VirtualWnd_BGCfgCache() +{ + delete m_ar; +} + +void WDL_VirtualWnd_BGCfgCache::Invalidate() +{ + m_ar->m_cachelist.DeleteAll(); +} + +LICE_IBitmap *WDL_VirtualWnd_BGCfgCache::GetCachedBG(int w, int h, void *owner_hint, const LICE_IBitmap *bgbmp) +{ + if (w<1 || h<1 || w>65535 || h>65535) return NULL; + + WDL_PtrList *cache = m_ar->m_cachelist.Get(bgbmp); + if (!cache) return NULL; + + WDL_VirtualWnd_BGCfgCache_img tmp((h<<16)+w,NULL,0); + WDL_VirtualWnd_BGCfgCache_img *r = cache->Get(cache->FindSorted(&tmp,WDL_VirtualWnd_BGCfgCache_img::compar)); + if (r) + { + r->lastused = GetTickCount(); + if (owner_hint && r->lastowner != owner_hint) r->lastowner=0; + return r->bgimage; + } + return NULL; +} + +void WDL_VirtualWnd_BGCfgCache::SetCachedBG(int w, int h, LICE_IBitmap *bm, void *owner_hint, const LICE_IBitmap *bgbmp) +{ + if (!bm || w<1 || h<1 || w>65535 || h>65535) return; + + WDL_PtrList *cache = m_ar->m_cachelist.Get(bgbmp); + if (!cache) + { + cache = new WDL_PtrList; + m_ar->m_cachelist.Insert(bgbmp,cache); + } + + // caller should ALWAYS call GetCachedBG() and use that if present + + WDL_VirtualWnd_BGCfgCache_img *img = NULL; + unsigned int now = GetTickCount(); + bool cacheAtWantSize = cache->GetSize()>=m_want_size; + if (cacheAtWantSize || owner_hint) + { + int x; + int bestpos=-1; + unsigned int bestt=0xffffff00; + for(x=0;xGetSize();x++) + { + WDL_VirtualWnd_BGCfgCache_img *a = cache->Get(x); + if (owner_hint && a->lastowner == owner_hint) + { + cacheAtWantSize=true; + bestt = now-5000; + bestpos=x; + break; // FOUND exact match! + } + if (a->lastused < bestt) + { + bestt=a->lastused; + bestpos=x; + } + } + + if (cacheAtWantSize && (bestt < now-500 || cache->GetSize() >= m_max_size)) // use this slot if over 1000ms old, or if we're up against the max size + { + img = cache->Get(bestpos); + cache->Delete(bestpos,false); + if (img) + { + img->sizeinfo = (h<<16)+w; + img->lastused = now; + } + } + + } + + + if (!img) + { + LICE_IBitmap *bmcp = new LICE_MemBitmap(w,h); + if (bmcp->getWidth()==w && bmcp->getHeight()==h) img = new WDL_VirtualWnd_BGCfgCache_img((h<<16)+w,bmcp,now); + else delete bmcp; + } + + if (img) + { + img->lastowner = owner_hint; + LICE_Copy(img->bgimage,bm); + cache->InsertSorted(img,WDL_VirtualWnd_BGCfgCache_img::compar); + } + +} + +void WDL_VirtualWnd_PreprocessBGConfig(WDL_VirtualWnd_BGCfg *a) +{ + if (!a) return; + + if (!a->bgimage) return; + a->bgimage_lt[0]=a->bgimage_lt[1]=a->bgimage_rb[0]=a->bgimage_rb[1]=0; + a->bgimage_lt_out[0]=a->bgimage_lt_out[1]=a->bgimage_rb_out[0]=a->bgimage_rb_out[1]=1; + + int w=a->bgimage->getWidth(); + int h=a->bgimage->getHeight(); + if (w>1&&h>1 && LICE_GetPixel(a->bgimage,0,0)==LICE_RGBA(255,0,255,255) && + LICE_GetPixel(a->bgimage,w-1,h-1)==LICE_RGBA(255,0,255,255)) + { + int x; + for (x = 1; x < w && LICE_GetPixel(a->bgimage,x,0)==LICE_RGBA(255,0,255,255); x ++); + a->bgimage_lt[0] = x; + for (x = w-2; x >= a->bgimage_lt[0]+1 && LICE_GetPixel(a->bgimage,x,h-1)==LICE_RGBA(255,0,255,255); x --); + a->bgimage_rb[0] = w-1-x; + + for (x = 1; x < h && LICE_GetPixel(a->bgimage,0,x)==LICE_RGBA(255,0,255,255); x ++); + a->bgimage_lt[1] = x; + for (x = h-2; x >= a->bgimage_lt[1]+1 && LICE_GetPixel(a->bgimage,w-1,x)==LICE_RGBA(255,0,255,255); x --); + a->bgimage_rb[1] = h-1-x; + } + else if (w>1&&h>1 && LICE_GetPixel(a->bgimage,0,0)==LICE_RGBA(255,255,0,255) && + LICE_GetPixel(a->bgimage,w-1,h-1)==LICE_RGBA(255,255,0,255)) + { + + bool hadPink=false; + + //graphic image contains an outside area -- must contain at least one pink pixel in its definition or we assume it's just a yellow image... + int x, x2, x3; + for (x = 1, x2 = 0, x3 = 0; x < w; x++) + { + LICE_pixel p = LICE_GetPixel(a->bgimage,x,0); + if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } + else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } + else break; + } + a->bgimage_lt[0] = x2+1; + a->bgimage_lt_out[0] = x3+1; + for (x = w-2, x2 = 0, x3 = 0; x >= a->bgimage_lt[0]+1; x--) + { + LICE_pixel p = LICE_GetPixel(a->bgimage,x,h-1); + if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } + else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } + else break; + } + a->bgimage_rb[0] = x2+1; + a->bgimage_rb_out[0] = x3+1; + + for (x = 1, x2 = 0, x3 = 0; x < h;x++) + { + LICE_pixel p = LICE_GetPixel(a->bgimage,0,x); + if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } + else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } + else break; + } + a->bgimage_lt[1] = x2+1; + a->bgimage_lt_out[1] = x3+1; + for (x = h-2, x2 = 0, x3 = 0; x >= a->bgimage_lt[1]+1; x --) + { + LICE_pixel p = LICE_GetPixel(a->bgimage,w-1,x); + if(p==LICE_RGBA(255,0,255,255)) { hadPink=true; x2++; } + else if(p==LICE_RGBA(255,255,0,255)) { x3+=x2+1; x2=0; } + else break; + } + a->bgimage_rb[1] = x2+1; + a->bgimage_rb_out[1] = x3+1; + if (!hadPink) // yellow by itself isnt enough, need at least a bit of pink. + { + a->bgimage_lt[0]=a->bgimage_lt[1]=a->bgimage_rb[0]=a->bgimage_rb[1]=0; + a->bgimage_lt_out[0]=a->bgimage_lt_out[1]=a->bgimage_rb_out[0]=a->bgimage_rb_out[1]=1; + } + } + + + int flags=0xffff; + LICE_pixel_chan *ch = (LICE_pixel_chan *) a->bgimage->getBits(); + int span = a->bgimage->getRowSpan()*4; + if (a->bgimage->isFlipped()) + { + ch += span*(h-1); + span=-span; + } + + // not sure if this works yet -- it needs more testing for sure + bool isFull=true; + if (a->bgimage_lt[0] ||a->bgimage_lt[1] || a->bgimage_rb[0] || a->bgimage_rb[1]) + { + isFull=false; + ch += span; // skip a line + ch += 4; // skip a column + h-=2; + w-=2; + } + + // points at which we change to the next block + int xdivs[3] = { a->bgimage_lt[0]+a->bgimage_lt_out[0]-2, + w-a->bgimage_rb[0]-a->bgimage_rb_out[0]+2, + w-a->bgimage_rb_out[0]+1}; + int ydivs[3] = { a->bgimage_lt[1]+a->bgimage_lt_out[1]-2, + h-a->bgimage_rb[1]-a->bgimage_rb_out[1]+2, + h-a->bgimage_rb_out[1]+1}; + + int y,ystate=0; + for(y=0;y=ydivs[ystate]) ystate++; + int xstate=0; + + int x; + LICE_pixel_chan *chptr = ch + LICE_PIXEL_A; + for (x=0;x=xdivs[xstate]) xstate++; + + if (*chptr != 255) + { + if (isFull) + { + flags=0; + break; + } + else + { + flags &= ~(1<<(ystate*4 + xstate)); + if (!flags) break; + } + } + chptr+=4; + } + if (!flags) break; + + ch += span; + } + + a->bgimage_noalphaflags=flags; + +} + +static void __VirtClipBlit(int clipx, int clipy, int clipright, int clipbottom, + LICE_IBitmap *dest, LICE_IBitmap *src, int dstx, int dsty, int dstw, int dsth, + int _srcx, int _srcy, int _srcw, int _srch, float alpha, int mode) +{ + if (dstw<1||dsth<1 || dstx+dstw < clipx || dstx > clipright || + dsty+dsth < clipy || dsty > clipbottom) + { + return; // dont draw if fully outside + } + + double srcx = (double) _srcx; + double srcy = (double) _srcy; + double srcw = (double) _srcw; + double srch = (double) _srch; + + if (dstx < clipx || dsty < clipy || dstx+dstw > clipright || dsty+dsth > clipbottom) + { + double xsc=srcw/dstw; + double ysc=srch/dsth; + + if (dstx clipright) + { + int diff = dstx+dstw-clipright; //clipright-dstx-dstw; + dstw -= diff; + srcw -= diff*xsc; + } + if (dsty+dsth > clipbottom) + { + int diff = dsty+dsth-clipbottom; //clipbottom-dsty-dsth; + dsth -= diff; + srch -= diff*ysc; + } + + } + + if (dstw>0&&dsth>0) + { + const double eps=0.0005; + if (srcw > 0.0 && srcw < eps) srcw=eps; + if (srch > 0.0 && srch < eps) srch=eps; + LICE_ScaledBlit(dest,src,dstx,dsty,dstw,dsth,(float)srcx,(float)srcy,(float)srcw,(float)srch,alpha,mode); + } +} + +void WDL_VirtualWnd_ScaledBlitSubBG(LICE_IBitmap *dest, + WDL_VirtualWnd_BGCfg *src, + int destx, int desty, int destw, int desth, + int clipx, int clipy, int clipw, int cliph, + int srcx, int srcy, int srcw, int srch, // these coordinates are not including pink lines (i.e. if pink lines are present, use src->bgimage->getWidth()-2, etc) + float alpha, int mode) +{ + if (!src || !src->bgimage) return; + + int adj=2; + if (src->bgimage_lt[0] < 1 || src->bgimage_lt[1] < 1 || src->bgimage_rb[0] < 1 || src->bgimage_rb[1] < 1) + { + adj=0; + } + if (srcx == 0 && srcy == 0 && srcw+adj >= src->bgimage->getWidth() && srch+adj >= src->bgimage->getHeight()) + { + WDL_VirtualWnd_ScaledBlitBG(dest,src,destx,desty,destw,desth,clipx,clipy,clipw,cliph,alpha,mode); + return; + } + + LICE_SubBitmap bm(src->bgimage,srcx,srcy,srcw+adj,srch+adj); + WDL_VirtualWnd_BGCfg ts = *src; + ts.bgimage = &bm; + + if ((ts.bgimage_noalphaflags&0xffff)!=0xffff) ts.bgimage_noalphaflags=0; // force alpha channel if any alpha + + WDL_VirtualWnd_ScaledBlitBG(dest,&ts,destx,desty,destw,desth,clipx,clipy,clipw,cliph,alpha,mode); +} + +void WDL_VirtualWnd_ScaledBlitBG(LICE_IBitmap *dest, + WDL_VirtualWnd_BGCfg *src, + int destx, int desty, int destw, int desth, + int clipx, int clipy, int clipw, int cliph, + float alpha, int mode) +{ + // todo: blit clipping optimizations + if (!src || !src->bgimage) return; + + int left_margin=src->bgimage_lt[0]; + int top_margin=src->bgimage_lt[1]; + int right_margin=src->bgimage_rb[0]; + int bottom_margin=src->bgimage_rb[1]; + + int left_margin_out=src->bgimage_lt_out[0]; + int top_margin_out=src->bgimage_lt_out[1]; + int right_margin_out=src->bgimage_rb_out[0]; + int bottom_margin_out=src->bgimage_rb_out[1]; + + int sw=src->bgimage->getWidth(); + int sh=src->bgimage->getHeight(); + + int clipright=clipx+clipw; + int clipbottom=clipy+cliph; + + if (clipxdestx+destw) clipright=clipx+destw; + if (clipbottom>desty+desth) clipbottom=clipy+desth; + + if (left_margin<1||top_margin<1||right_margin<1||bottom_margin<1) + { + float xsc=(float)sw/destw; + float ysc=(float)sh/desth; + + if (mode&LICE_BLIT_USE_ALPHA) + { + if ((src->bgimage_noalphaflags & 0xffff)==0xffff) + { + mode &= ~LICE_BLIT_USE_ALPHA; + } + } + + + LICE_ScaledBlit(dest,src->bgimage, + clipx,clipy,clipright-clipx,clipbottom-clipy, + (clipx-destx)*xsc, + (clipy-desty)*ysc, + (clipright-clipx)*xsc, + (clipbottom-clipy)*ysc, + alpha,mode); + + return; + } + + // remove 1px additional margins from calculations + left_margin--; top_margin--; right_margin--; bottom_margin--; + left_margin_out--; top_margin_out--; right_margin_out--; bottom_margin_out--; + + if (left_margin+right_margin>destw) + { + int w=left_margin+right_margin; + left_margin = destw*left_margin/max(w,1); + right_margin=destw-left_margin; + } + if (top_margin+bottom_margin>desth) + { + int h=(top_margin+bottom_margin); + top_margin=desth*top_margin/max(h,1); + bottom_margin=desth-top_margin; + } + + int no_alpha_flags=src->bgimage_noalphaflags; + int pass; + int nbpass = 3; + if (bottom_margin_out>0) + nbpass = 4; + + bool no_inside = !!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_INSIDE); + bool no_outside = !!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_OUTSIDE); + + bool no_lr=!!(mode & WDL_VWND_SCALEDBLITBG_IGNORE_LR); + + + for (pass=(top_margin_out> 0 ? -1 : 0); passbgimage_lt[1]-1; + break; + case 1: + outy=desty+top_margin; + outh=desth-top_margin-bottom_margin; + iny=src->bgimage_lt[1]+top_margin_out; + inh=sh-src->bgimage_rb[1]-bottom_margin_out - iny; + break; + case 2: + outy=desty+desth-bottom_margin; + outh=bottom_margin; + iny=sh - src->bgimage_rb[1] - bottom_margin_out; + inh=src->bgimage_rb[1]-1; + break; + case 3: + outy=desty+desth; + outh=bottom_margin_out; + iny=sh-1-bottom_margin_out; + inh=bottom_margin_out; + clipbottom += bottom_margin_out; + break; + } + bool is_outer = pass<0 || pass>=3; + + if (no_outside && is_outer) + { + } + else if (outh > 0 && inh > 0) + { + + if (no_lr) + { + __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx,outy, + destw,outh, + src->bgimage_lt[0]+left_margin_out,iny, + sw-src->bgimage_lt[0]-src->bgimage_rb[0]-left_margin_out - right_margin_out, + inh,alpha,(no_alpha_flags&2) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + } + else + { + // left + if (left_margin_out>0 && !no_outside) + { + __VirtClipBlit(clipx-left_margin_out,this_clipy,clipright,clipbottom,dest,src->bgimage,destx-left_margin_out,outy,left_margin_out,outh, + 1,iny,left_margin_out,inh,alpha, + (no_alpha_flags&1) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + } + + if (!no_inside||is_outer) + { + if (left_margin > 0) + __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx,outy,left_margin,outh, + 1+left_margin_out,iny,src->bgimage_lt[0]-1,inh,alpha, + (no_alpha_flags&1) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + + + // center + __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx+left_margin,outy, + destw-right_margin-left_margin,outh, + src->bgimage_lt[0]+left_margin_out,iny, + sw-src->bgimage_lt[0]-src->bgimage_rb[0]-right_margin_out-left_margin_out, + inh,alpha,(no_alpha_flags&2) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + // right + if (right_margin > 0) + __VirtClipBlit(clipx,this_clipy,clipright,clipbottom,dest,src->bgimage,destx+destw-right_margin,outy, right_margin,outh, + sw-src->bgimage_rb[0]-right_margin_out,iny, + src->bgimage_rb[0]-1,inh,alpha,(no_alpha_flags&4) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + } + + // right outside area + if (right_margin_out>0 && !no_outside) + __VirtClipBlit(clipx,this_clipy,clipright+right_margin_out,clipbottom,dest,src->bgimage,destx+destw,outy,right_margin_out,outh, + sw-right_margin_out-1,iny, + right_margin_out,inh,alpha,(no_alpha_flags&8) ? (mode&~LICE_BLIT_USE_ALPHA) : mode); + + } + } + if (pass>=0) + no_alpha_flags>>=4; + } +} + +int WDL_VirtualWnd_ScaledBG_GetPix(WDL_VirtualWnd_BGCfg *src, + int ww, int wh, + int x, int y) +{ + if (!src->bgimage) return 0; + int imgw=src->bgimage->getWidth(); + int imgh=src->bgimage->getHeight(); + + int left_margin=src->bgimage_lt[0]; + int top_margin=src->bgimage_lt[1]; + int right_margin=src->bgimage_rb[0]; + int bottom_margin=src->bgimage_rb[1]; + + if (left_margin<1||top_margin<1||right_margin<1||bottom_margin<1) + { + if (ww<1)ww=1; + x=(x * imgw)/ww; + if (wh<1)wh=1; + y=(y * imgh)/wh; + } + else + { + // remove 1px additional margins from calculations + left_margin--; top_margin--; right_margin--; bottom_margin--; + int destw=ww,desth=wh; + if (left_margin+right_margin>destw) + { + int w=left_margin+right_margin; + left_margin = destw*left_margin/max(w,1); + right_margin=destw-left_margin; + } + if (top_margin+bottom_margin>desth) + { + int h=(top_margin+bottom_margin); + top_margin=desth*top_margin/max(h,1); + bottom_margin=desth-top_margin; + } + + if (x >= ww-right_margin) x=imgw-1- (ww-x); + else if (x >= left_margin) + { + int xd=ww-left_margin-right_margin; + if (xd<1)xd=1; + x=src->bgimage_lt[0] + + (x-left_margin) * (imgw-src->bgimage_lt[0]-src->bgimage_rb[0])/xd; + } + else x++; + + if (y >= wh-bottom_margin) y=imgh -1- (wh-y); + else if (y >= top_margin) + { + int yd=wh-top_margin-bottom_margin; + if (yd<1)yd=1; + y=src->bgimage_lt[1] + + (y-top_margin) * (imgh-src->bgimage_lt[1]-src->bgimage_rb[1])/yd; + } + else y++; + } + + return LICE_GetPixel(src->bgimage,x,y); +} + + +#ifdef _WIN32 + +static WNDPROC vwndDlgHost_oldProc; +static LRESULT CALLBACK vwndDlgHost_newProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg==WM_ERASEBKGND) return 1; + if (msg==WM_PAINT) + { + WNDPROC pc=(WNDPROC)GetWindowLongPtr(hwnd,DWLP_DLGPROC); + if (pc) + { + CallWindowProc(pc,hwnd,msg,wParam,lParam); + return 0; + } + } + + return CallWindowProc(vwndDlgHost_oldProc,hwnd,msg,wParam,lParam); +} + +#endif + +void WDL_VWnd_regHelperClass(const char *classname, void *icon1, void *icon2) +{ +#ifdef _WIN32 + static bool reg; + if (reg) return; + + reg=true; + + WNDCLASSEX wc={sizeof(wc),}; + GetClassInfoEx(NULL,"#32770",&wc); + wc.lpszClassName = (char*)classname; + if (icon1) wc.hIcon = (HICON)icon1; + if (icon2) wc.hIconSm = (HICON)icon2; + vwndDlgHost_oldProc=wc.lpfnWndProc; + wc.lpfnWndProc=vwndDlgHost_newProc; + RegisterClassEx(&wc); +#endif +} + diff --git a/WDL/wingui/virtwnd.h b/WDL/wingui/virtwnd.h new file mode 100644 index 00000000..8fc92652 --- /dev/null +++ b/WDL/wingui/virtwnd.h @@ -0,0 +1,224 @@ +/* + WDL - virtwnd.h + Copyright (C) 2006 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + This file provides interfaces for the WDL Virtual Windows layer, a system that allows + creating many controls within one system device context. + + The base class is a WDL_VWnd. + + If you create a WDL_VWnd, you should send it (or its parent) mouse messages etc. + + To paint a WDL_VWnd, use a WDL_VWnd_Painter in WM_PAINT etc. + + + More documentation should follow... +*/ + + + +#ifndef _WDL_VIRTWND_H_ +#define _WDL_VIRTWND_H_ + +#ifdef _WIN32 +#include +#else +#include "../swell/swell.h" +#endif +#include "../ptrlist.h" +#include "../wdlstring.h" + + + +class WDL_VWnd_Painter; +class LICE_IBitmap; + +// deprecated +#define WDL_VirtualWnd_ChildList WDL_VWnd +#define WDL_VirtualWnd WDL_VWnd +#define WDL_VirtualWnd_Painter WDL_VWnd_Painter + +class WDL_VWnd; + +class WDL_VWnd_IAccessibleBridge +{ +public: + virtual void Release()=0; + virtual void ClearCaches(){} + virtual void OnFocused() {} + virtual void OnStateChange() {} +}; + + +#include "../destroycheck.h" +#define WDL_VWND_DCHK(n) WDL_DestroyCheck n(&m_destroystate) + +class WDL_VWnd +{ +public: + WDL_VWnd(); + virtual ~WDL_VWnd(); + virtual const char *GetType() { return "vwnd_unknown"; } + + virtual void SetID(int id) { m_id=id; } + virtual int GetID() { return m_id; } + virtual INT_PTR GetUserData() { return m_userdata; } + virtual INT_PTR SetUserData(INT_PTR ud) { INT_PTR od=m_userdata; m_userdata=ud; return od; } + virtual void SetPosition(const RECT *r) { m_position=*r; } + virtual void GetPosition(RECT *r) { *r=m_position; } + virtual void GetPositionPaintExtent(RECT *r) { *r=m_position; } + virtual void GetPositionPaintOverExtent(RECT *r) { *r=m_position; } + virtual void SetVisible(bool vis) { m_visible=vis; } + virtual bool IsVisible() { return m_visible; } + virtual bool WantsPaintOver() { return m_children && m_children->GetSize(); } + virtual WDL_VWnd *GetParent() { return m_parent; } + virtual void SetParent(WDL_VWnd *par) { m_parent=par; } + + virtual void RequestRedraw(RECT *r); + virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + virtual void OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect); + + virtual int OnMouseDown(int xpos, int ypos); // return -1 to eat, >0 to capture + virtual bool OnMouseDblClick(int xpos, int ypos); + virtual bool OnMouseWheel(int xpos, int ypos, int amt); + + virtual void OnMouseMove(int xpos, int ypos); + virtual void OnMouseUp(int xpos, int ypos); + + // child windows + virtual WDL_VWnd *EnumChildren(int x); + virtual int GetNumChildren(); + virtual WDL_VWnd *GetChildByID(int id); + virtual void AddChild(WDL_VWnd *wnd, int pos=-1); + virtual void RemoveChild(WDL_VWnd *wnd, bool dodel=false); + virtual void RemoveAllChildren(bool dodel=true); + virtual WDL_VWnd *GetCaptureWnd() { return m_children ? m_children->Get(m_captureidx) : 0; } + virtual WDL_VWnd *VirtWndFromPoint(int xpos, int ypos, int maxdepth=-1); // maxdepth=0 only direct children, etc, -1 is unlimited + + // OS access + virtual HWND GetRealParent() { if (m_realparent) return m_realparent; if (GetParent()) return GetParent()->GetRealParent(); return 0; } + virtual void SetRealParent(HWND par) { m_realparent=par; } + + virtual INT_PTR SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src); + + // request if window has cursor + virtual int UpdateCursor(int xpos, int ypos); // >0 if set, 0 if cursor wasnt set , <0 if cursor should be default... + virtual bool GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz); // true if handled + + virtual void GetPositionInTopVWnd(RECT *r); + + // these do not store a copy, usually you set them to static strings etc, but a control can override, too... + virtual void SetAccessDesc(const char *desc) { m__iaccess_desc=desc; } + virtual const char *GetAccessDesc() { return m__iaccess_desc; } + + virtual WDL_VWnd_IAccessibleBridge *GetAccessibilityBridge() { return m__iaccess; } + virtual void SetAccessibilityBridge(WDL_VWnd_IAccessibleBridge *br) { m__iaccess=br; } + + virtual void SetChildPosition(WDL_VWnd *ch, int pos); + + virtual void SetCurPainter(WDL_VWnd_Painter *p) { m_curPainter=p; } + virtual bool IsDescendent(WDL_VWnd *w); + + virtual void OnCaptureLost(); +protected: + WDL_VWnd *m_parent; + WDL_VWnd_IAccessibleBridge *m__iaccess; + bool m_visible; + int m_id; + RECT m_position; + INT_PTR m_userdata; + + HWND m_realparent; + int m_captureidx; + int m_lastmouseidx; + WDL_PtrList *m_children; + + const char *m__iaccess_desc; + + WDL_VWnd_Painter *m_curPainter; + virtual int GSC(int a); + + WDL_DestroyState m_destroystate; +}; + + +// painting object (can be per window or per thread or however you like) +#define WDL_VWP_SUNKENBORDER 0x00010000 +#define WDL_VWP_SUNKENBORDER_NOTOP 0x00020000 +#define WDL_VWP_DIVIDER_VERT 0x00030000 +#define WDL_VWP_DIVIDER_HORZ 0x00040000 + + +#include "virtwnd-skin.h" + +class WDL_VWnd_Painter +{ +public: + WDL_VWnd_Painter(); + ~WDL_VWnd_Painter(); + + + void SetGSC(int (*GSC)(int)); + void PaintBegin(HWND hwnd, int bgcolor=-1, const RECT *limitBGrect=NULL, const RECT *windowRect=NULL); + void SetBGImage(WDL_VirtualWnd_BGCfg *bitmap, int tint=-1, WDL_VirtualWnd_BGCfgCache *cacheObj=NULL) { m_bgbm=bitmap; m_bgbmtintcolor=tint; m_bgcache=cacheObj; } // call before every paintbegin (resets if you dont) + void SetBGGradient(int wantGradient, double start, double slope); // wantg < 0 to use system defaults + + void PaintBGCfg(WDL_VirtualWnd_BGCfg *bitmap, const RECT *coords, bool allowTint=true, float alpha=1.0, int mode=0); + void PaintVirtWnd(WDL_VWnd *vwnd, int borderflags=0); + void PaintBorderForHWND(HWND hwnd, int borderflags); + void PaintBorderForRect(const RECT *r, int borderflags); + + void GetPaintInfo(RECT *rclip, int *xoffsdraw, int *yoffsdraw); + + LICE_IBitmap *GetBuffer(int *xo, int *yo) + { + *xo = -m_paint_xorig; + *yo = -m_paint_yorig; + return m_bm; + } + + void PaintEnd(); + + int GSC(int a); +private: + + double m_gradstart,m_gradslope; + + int m_wantg; + int (*m_GSC)(int); + void DoPaintBackground(LICE_IBitmap *bmOut, int bgcolor, const RECT *clipr, int wnd_w, int wnd_h, int xoffs, int yoffs); + void tintRect(LICE_IBitmap *bmOut, const RECT *clipr, int xoffs, int yoffs); + LICE_IBitmap *m_bm; + WDL_VirtualWnd_BGCfg *m_bgbm; + int m_bgbmtintcolor; + + WDL_VirtualWnd_BGCfgCache *m_bgcache; + HWND m_cur_hwnd; + PAINTSTRUCT m_ps; + int m_paint_xorig, m_paint_yorig; + +}; + +void WDL_VWnd_regHelperClass(const char *classname, void *icon=NULL, void *iconsm=NULL); // register this class if you wish to make your dialogs use it (better paint behavior) + +// in virtwnd-iaccessible.cpp +LRESULT WDL_AccessibilityHandleForVWnd(bool isDialog, HWND hwnd, WDL_VWnd *vw, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/WDL/wingui/wndsize.cpp b/WDL/wingui/wndsize.cpp new file mode 100644 index 00000000..faeda6c5 --- /dev/null +++ b/WDL/wingui/wndsize.cpp @@ -0,0 +1,349 @@ +/* + WDL - wndsize.cpp + Copyright (C) 2004 and later, Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* +For information on how to use this class, see wndsize.h :) +*/ + +#ifndef _WIN32 +#include "../swell/swell.h" +#else +#include +#endif + +#include "wndsize.h" +#include "virtwnd.h" + +void WDL_WndSizer::init(HWND hwndDlg, RECT *initr) +{ + m_hwnd=hwndDlg; + RECT r={0,}; + if (initr) + r=*initr; + else if (m_hwnd) + GetClientRect(m_hwnd,&r); + set_orig_rect(&r); + + m_list.Resize(0); + + memset(&m_margins,0,sizeof(m_margins)); +} + + +void WDL_WndSizer::init_item(int dlg_id, float *scales, RECT *initr) +{ + init_item(dlg_id,scales[0],scales[1],scales[2],scales[3],initr); +} +void WDL_WndSizer::init_itemvirt(WDL_VWnd *vwnd, float *scales) +{ + init_itemvirt(vwnd,scales[0],scales[1],scales[2],scales[3]); +} + +void WDL_WndSizer::init_itemvirt(WDL_VirtualWnd *vwnd, + float left_scale, float top_scale, float right_scale, float bottom_scale) +{ + RECT this_r={0,}; + if (vwnd) vwnd->GetPosition(&this_r); + int osize=m_list.GetSize(); + m_list.Resize(osize+sizeof(WDL_WndSizer__rec)); + + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()+osize); + + rec->hwnd=0; + rec->vwnd=vwnd; + rec->scales[0]=left_scale; + rec->scales[1]=top_scale; + rec->scales[2]=right_scale; + rec->scales[3]=bottom_scale; + rec->real_orig = rec->last = rec->orig = this_r; +} + +POINT WDL_WndSizer::get_min_size(bool applyMargins) +{ + POINT p = m_min_size; + if (applyMargins) + { + p.x += m_margins.left+m_margins.right; + p.y += m_margins.top+m_margins.bottom; + } + return p; +} + + +void WDL_WndSizer::init_itemhwnd(HWND h, float left_scale, float top_scale, float right_scale, float bottom_scale, RECT *srcr) +{ + RECT this_r={0,}; + if (srcr) this_r=*srcr; + else if (h) + { + GetWindowRect(h,&this_r); + if (m_hwnd) + { + ScreenToClient(m_hwnd,(LPPOINT) &this_r); + ScreenToClient(m_hwnd,((LPPOINT) &this_r)+1); + } + #ifndef _WIN32 + if (this_r.bottom < this_r.top) + { + int oh=this_r.top-this_r.bottom; + this_r.bottom=this_r.top; + this_r.top -= oh; + } + #endif + } + int osize=m_list.GetSize(); + m_list.Resize(osize+sizeof(WDL_WndSizer__rec)); + + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()+osize); + + rec->hwnd=h; + rec->vwnd=0; + rec->scales[0]=left_scale; + rec->scales[1]=top_scale; + rec->scales[2]=right_scale; + rec->scales[3]=bottom_scale; + + rec->real_orig = rec->last = rec->orig = this_r; +} + +void WDL_WndSizer::init_item(int dlg_id, float left_scale, float top_scale, float right_scale, float bottom_scale, RECT *initr) +{ + if (m_hwnd) + init_itemhwnd(GetDlgItem(m_hwnd,dlg_id),left_scale,top_scale,right_scale,bottom_scale,initr); +} + +#ifdef _WIN32 +BOOL CALLBACK WDL_WndSizer::enum_RegionRemove(HWND hwnd,LPARAM lParam) +{ + WDL_WndSizer *_this=(WDL_WndSizer *)lParam; +// if(GetParent(hwnd)!=_this->m_hwnd) return TRUE; + + if (IsWindowVisible(hwnd)) + { + RECT r; + GetWindowRect(hwnd,&r); + if (_this->m_hwnd) + { + ScreenToClient(_this->m_hwnd,(LPPOINT)&r); + ScreenToClient(_this->m_hwnd,((LPPOINT)&r)+1); + } + HRGN rgn2=CreateRectRgn(r.left,r.top,r.right,r.bottom); + CombineRgn(_this->m_enum_rgn,_this->m_enum_rgn,rgn2,RGN_DIFF); + DeleteObject(rgn2); + } + + return TRUE; +} +#endif + +void WDL_WndSizer::remove_item(int dlg_id) +{ + if (m_hwnd) remove_itemhwnd(GetDlgItem(m_hwnd,dlg_id)); +} + +void WDL_WndSizer::remove_itemhwnd(HWND h) +{ + WDL_WndSizer__rec *rec; + while ((rec=get_itembywnd(h))) + { + WDL_WndSizer__rec *list=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int list_size=m_list.GetSize()/sizeof(WDL_WndSizer__rec); + int idx=rec-list; + + if (idx >= 0 && idx < list_size-1) + memcpy(rec,rec+1,(list_size-(idx+1))*sizeof(WDL_WndSizer__rec)); + m_list.Resize((list_size-1)*sizeof(WDL_WndSizer__rec)); + } +} + +void WDL_WndSizer::remove_itemvirt(WDL_VirtualWnd *vwnd) +{ + WDL_WndSizer__rec *rec; + while ((rec=get_itembyvirt(vwnd))) + { + WDL_WndSizer__rec *list=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int list_size=m_list.GetSize()/sizeof(WDL_WndSizer__rec); + int idx=rec-list; + + if (idx >= 0 && idx < list_size-1) + memcpy(rec,rec+1,(list_size-(idx+1))*sizeof(WDL_WndSizer__rec)); + m_list.Resize((list_size-1)*sizeof(WDL_WndSizer__rec)); + } +} + +void WDL_WndSizer::transformRect(RECT *r, const float *scales, const RECT *wndSize) +{ + POINT sz = { wndSize->right, wndSize->bottom }; + + sz.x -= m_margins.left+m_margins.right; + sz.y -= m_margins.top+m_margins.bottom; + + if (sz.x < m_min_size.x) sz.x=m_min_size.x; + if (sz.y < m_min_size.y) sz.y=m_min_size.y; + + sz.x -= m_orig_size.x; + sz.y -= m_orig_size.y; + + if (scales[0] >= 1.0) r->left += sz.x; + else if (scales[0]>0.0) r->left += (int) (sz.x*scales[0]); + + if (scales[1] >= 1.0) r->top += sz.y; + else if (scales[1]>0.0) r->top += (int) (sz.y*scales[1]); + + if (scales[2] >= 1.0) r->right += sz.x; + else if (scales[2]>0.0) r->right += (int) (sz.x*scales[2]); + + if (scales[3] >= 1.0) r->bottom += sz.y; + else if (scales[3]>0.0) r->bottom += (int) (sz.y*scales[3]); + + r->left += m_margins.left; + r->right += m_margins.left; + r->top += m_margins.top; + r->bottom += m_margins.top; + + if (r->bottom < r->top) r->bottom=r->top; + if (r->right < r->left) r->right=r->left; +} + + +void WDL_WndSizer::onResize(HWND only, int notouch, int xtranslate, int ytranslate) +{ + if (!m_hwnd) return; + + RECT new_rect; + + GetClientRect(m_hwnd,&new_rect); +#ifdef _WIN32 + + m_enum_rgn=CreateRectRgn(new_rect.left,new_rect.top,new_rect.right,new_rect.bottom); + // EnumChildWindows(m_hwnd,enum_RegionRemove,(LPARAM)this); + + HDWP hdwndpos=NULL; + int has_dfwp=0; +#endif + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); + + int x; + for (x = 0; x < cnt; x ++) + { + + if ((rec->vwnd && !only) || (rec->hwnd && (!only || only == rec->hwnd))) + { + RECT r=rec->orig; + transformRect(&r,rec->scales,&new_rect); + + rec->last = r; + + if (!notouch) + { + if (rec->hwnd) + { +#ifdef _WIN32 + if (!has_dfwp) + { + has_dfwp=1; + if (!only && GetVersion() < 0x80000000) hdwndpos=BeginDeferWindowPos(cnt); + } + + + if (IsWindow(rec->hwnd)) + { + if (!hdwndpos) +#endif + SetWindowPos(rec->hwnd, NULL, r.left+xtranslate,r.top+ytranslate,r.right-r.left,r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE); + +#ifdef _WIN32 + else + { + hdwndpos=DeferWindowPos(hdwndpos, rec->hwnd, NULL, r.left+xtranslate,r.top+ytranslate,r.right-r.left,r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE); + } + } +#endif + } + if (rec->vwnd) + { + rec->vwnd->SetPosition(&r); + } + } + } + rec++; + } +#ifdef _WIN32 + if (hdwndpos) EndDeferWindowPos(hdwndpos); + + EnumChildWindows(m_hwnd,enum_RegionRemove,(LPARAM)this); + InvalidateRgn(m_hwnd,m_enum_rgn,FALSE); + DeleteObject(m_enum_rgn); +#endif +} + +WDL_WndSizer__rec *WDL_WndSizer::get_itembyindex(int id) +{ + if (id >= 0 && id < (m_list.GetSize() / (int)sizeof(WDL_WndSizer__rec))) + { + return ((WDL_WndSizer__rec *) m_list.Get())+id; + } + return NULL; +} + +WDL_WndSizer__rec *WDL_WndSizer::get_itembywnd(HWND h) +{ + if (h) + { + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); + while (cnt--) + { + if (rec->hwnd == h) return rec; + rec++; + } + } + return 0; +} + + +WDL_WndSizer__rec *WDL_WndSizer::get_itembyvirt(WDL_VirtualWnd *vwnd) +{ + if (!vwnd) return 0; + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); + while (cnt--) + { + if (rec->vwnd == vwnd) return rec; + rec++; + } + return 0; +} + +WDL_WndSizer__rec *WDL_WndSizer::get_item(int dlg_id) +{ + WDL_WndSizer__rec *rec=(WDL_WndSizer__rec *) ((char *)m_list.Get()); + int cnt=m_list.GetSize() / sizeof(WDL_WndSizer__rec); + while (cnt--) + { + if (rec->vwnd && rec->vwnd->GetID() == dlg_id) return rec; + rec++; + } + + return m_hwnd ? get_itembywnd(GetDlgItem(m_hwnd,dlg_id)) : 0; +} diff --git a/WDL/wingui/wndsize.h b/WDL/wingui/wndsize.h new file mode 100644 index 00000000..de90d5c1 --- /dev/null +++ b/WDL/wingui/wndsize.h @@ -0,0 +1,143 @@ +/* + WDL - wndsize.h + Copyright (C) 2004 and later Cockos Incorporated + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +*/ + +/* + + This file provides the interface for a simple class that allows one to easily + make resizeable dialogs and have controls that move according to ratios of the + new size. + + Usually, one does a + + static WDL_WndSizer resize; + + in their DlgProc, and in WM_INITDIALOG: + + resize.init(hwndDlg); + + // add a list of items + resize.init_item(IDC_MASTERVOL, // dialog id + 0.0, // left position, 0=left anchor, 1=right anchor, etc + 0.0, // top position, 0=anchored to its initial top position, 1=anchored to distance from bottom, etc + 0.7f, // right position + 0.0); // bottom position + ... + + + then, in WM_SIZE, + if (wParam != SIZE_MINIMIZED) + { + resize.onResize(); // don't actually resize, just compute the rects + } + + + is about all that's needed. + + +*/ + +#ifndef _WNDSIZE_H_ +#define _WNDSIZE_H_ + + +#include "../heapbuf.h" + +class WDL_VWnd; + +struct WDL_WndSizer__rec +{ + HWND hwnd; + RECT orig; + RECT real_orig; + RECT last; + float scales[4]; + WDL_VWnd *vwnd; + +}; + +class WDL_WndSizer +{ +public: + WDL_WndSizer() + { + m_hwnd=NULL; + memset(&m_min_size,0,sizeof(m_min_size)); + memset(&m_orig_size,0,sizeof(m_orig_size)); + memset(&m_margins,0,sizeof(m_margins)); + } + ~WDL_WndSizer() { } + + void init(HWND hwndDlg, RECT *initr=NULL); + + // 1.0 means it moves completely with the point, 0.0 = not at all + void init_item(int dlg_id, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0, RECT *initr=NULL); + void init_itemvirt(WDL_VWnd *vwnd, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0); + void init_item(int dlg_id, float *scales, RECT *initr=NULL); + void init_itemvirt(WDL_VWnd *vwnd, float *scales); + void init_itemhwnd(HWND h, float left_scale=0.0, float top_scale=0.0, float right_scale=1.0, float bottom_scale=1.0, RECT *srcr=NULL); + void remove_item(int dlg_id); + void remove_itemvirt(WDL_VWnd *vwnd); + void remove_itemhwnd(HWND h); + + WDL_WndSizer__rec *get_item(int dlg_id); + WDL_WndSizer__rec *get_itembyindex(int id); + WDL_WndSizer__rec *get_itembywnd(HWND h); + WDL_WndSizer__rec *get_itembyvirt(WDL_VWnd *vwnd); + + RECT get_orig_rect() { RECT r={0,0,m_orig_size.x,m_orig_size.y}; return r; } + void set_orig_rect(const RECT *r, const POINT *minSize=NULL) + { + if (r) { m_orig_size.x = r->right; m_orig_size.y = r->bottom; } + if (minSize) m_min_size = *minSize; + else m_min_size.x=m_min_size.y=0; + } + POINT get_min_size(bool applyMargins=false); + + void onResize(HWND only=0, int notouch=0, int xtranslate=0, int ytranslate=0); + + + void set_margins(int left, int top, int right, int bottom) { m_margins.left=left; m_margins.top=top; m_margins.right=right; m_margins.bottom=bottom; } + void get_margins(int *left, int *top, int *right, int *bottom) + { + if (left) *left=m_margins.left; + if (top) *top=m_margins.top; + if (right) *right=m_margins.right; + if (bottom) *bottom=m_margins.bottom; + } + + void transformRect(RECT *r, const float *scales, const RECT *wndSize); + +private: +#ifdef _WIN32 + static BOOL CALLBACK enum_RegionRemove(HWND hwnd,LPARAM lParam); + HRGN m_enum_rgn; +#endif + HWND m_hwnd; + POINT m_orig_size,m_min_size; + RECT m_margins; + + // treat as WDL_WndSizer__rec[] + WDL_HeapBuf m_list; + +}; + +#endif//_WNDSIZE_H_ \ No newline at end of file diff --git a/WDL/zlib/adler32.c b/WDL/zlib/adler32.c new file mode 100644 index 00000000..a868f073 --- /dev/null +++ b/WDL/zlib/adler32.c @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/WDL/zlib/compress.c b/WDL/zlib/compress.c new file mode 100644 index 00000000..ea4dfbe9 --- /dev/null +++ b/WDL/zlib/compress.c @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/WDL/zlib/crc32.c b/WDL/zlib/crc32.c new file mode 100644 index 00000000..cc711899 --- /dev/null +++ b/WDL/zlib/crc32.c @@ -0,0 +1,449 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# ifndef Z_SOLO +# include +# endif +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR + typedef u4 crc_table_t; +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else + typedef unsigned long crc_table_t; +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local crc_table_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const crc_table_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + crc_table_t c; + int n, k; + crc_table_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (crc_table_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (crc_table_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const crc_table_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const crc_table_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/WDL/zlib/crc32.h b/WDL/zlib/crc32.h new file mode 100644 index 00000000..c3e7171c --- /dev/null +++ b/WDL/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const crc_table_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/WDL/zlib/deflate.c b/WDL/zlib/deflate.c new file mode 100644 index 00000000..8bd480eb --- /dev/null +++ b/WDL/zlib/deflate.c @@ -0,0 +1,1965 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.6 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/WDL/zlib/deflate.h b/WDL/zlib/deflate.h new file mode 100644 index 00000000..fbac44d9 --- /dev/null +++ b/WDL/zlib/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/WDL/zlib/gzclose.c b/WDL/zlib/gzclose.c new file mode 100644 index 00000000..caeb99a3 --- /dev/null +++ b/WDL/zlib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/WDL/zlib/gzguts.h b/WDL/zlib/gzguts.h new file mode 100644 index 00000000..3107c363 --- /dev/null +++ b/WDL/zlib/gzguts.h @@ -0,0 +1,190 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef __TURBOC__ +# include +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# include +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifdef STDC +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/WDL/zlib/gzlib.c b/WDL/zlib/gzlib.c new file mode 100644 index 00000000..7aedab8e --- /dev/null +++ b/WDL/zlib/gzlib.c @@ -0,0 +1,564 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const char *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gz_statep state; + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + case 'T': + state->direct = 1; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ + state->path = malloc(strlen(path) + 1); + if (state->path == NULL) { + free(state); + return NULL; + } + strcpy(state->path, path); + + /* open the file with the appropriate mode (or just use fd) */ + state->fd = fd != -1 ? fd : + open(path, +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | ( + state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))), + 0666); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/WDL/zlib/gzread.c b/WDL/zlib/gzread.c new file mode 100644 index 00000000..46d40e0b --- /dev/null +++ b/WDL/zlib/gzread.c @@ -0,0 +1,584 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) + memmove(state->in, strm->next_in, strm->avail_in); + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to memcpy() above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzgetc_(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +#undef gzgetc +int ZEXPORT gzgetc(file) +gzFile file; +{ + return gzgetc_(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/WDL/zlib/gzwrite.c b/WDL/zlib/gzwrite.c new file mode 100644 index 00000000..caa35b61 --- /dev/null +++ b/WDL/zlib/gzwrite.c @@ -0,0 +1,593 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->x.pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->x.pos++; + return c & 0xff; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(state->in, format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf(state->in, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(state->in, size, format, va); + va_end(va); + len = strlen(state->in); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(state->in); +# else + len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} + +/* used by zlibVersion() to get the vsnprintf story from the horse's mouth */ +unsigned long ZEXPORT gzflags() +{ + unsigned long flags = 0; +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} diff --git a/WDL/zlib/infback.c b/WDL/zlib/infback.c new file mode 100644 index 00000000..981aff17 --- /dev/null +++ b/WDL/zlib/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/WDL/zlib/inffast.c b/WDL/zlib/inffast.c new file mode 100644 index 00000000..2f1d60b4 --- /dev/null +++ b/WDL/zlib/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/WDL/zlib/inffast.h b/WDL/zlib/inffast.h new file mode 100644 index 00000000..e5c1aa4c --- /dev/null +++ b/WDL/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/WDL/zlib/inffixed.h b/WDL/zlib/inffixed.h new file mode 100644 index 00000000..d6283277 --- /dev/null +++ b/WDL/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/WDL/zlib/inflate.c b/WDL/zlib/inflate.c new file mode 100644 index 00000000..cc89517b --- /dev/null +++ b/WDL/zlib/inflate.c @@ -0,0 +1,1501 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + unsigned char *next; + unsigned avail; + int ret; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + next = strm->next_out; + avail = strm->avail_out; + strm->next_out = (Bytef *)dictionary + dictLength; + strm->avail_out = 0; + ret = updatewindow(strm, dictLength); + strm->avail_out = avail; + strm->next_out = next; + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/WDL/zlib/inflate.h b/WDL/zlib/inflate.h new file mode 100644 index 00000000..95f4986d --- /dev/null +++ b/WDL/zlib/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/WDL/zlib/inftrees.c b/WDL/zlib/inftrees.c new file mode 100644 index 00000000..60bbd58b --- /dev/null +++ b/WDL/zlib/inftrees.c @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.6 Copyright 1995-2012 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 69}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/WDL/zlib/inftrees.h b/WDL/zlib/inftrees.h new file mode 100644 index 00000000..baa53a0b --- /dev/null +++ b/WDL/zlib/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/WDL/zlib/ioapi.c b/WDL/zlib/ioapi.c new file mode 100644 index 00000000..7f5c191b --- /dev/null +++ b/WDL/zlib/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/WDL/zlib/ioapi.h b/WDL/zlib/ioapi.h new file mode 100644 index 00000000..8dcbdb06 --- /dev/null +++ b/WDL/zlib/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/WDL/zlib/trees.c b/WDL/zlib/trees.c new file mode 100644 index 00000000..8c32b214 --- /dev/null +++ b/WDL/zlib/trees.c @@ -0,0 +1,1224 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/WDL/zlib/trees.h b/WDL/zlib/trees.h new file mode 100644 index 00000000..d35639d8 --- /dev/null +++ b/WDL/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/WDL/zlib/uncompr.c b/WDL/zlib/uncompr.c new file mode 100644 index 00000000..ad98be3a --- /dev/null +++ b/WDL/zlib/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/WDL/zlib/unzip.c b/WDL/zlib/unzip.c new file mode 100644 index 00000000..affad4bf --- /dev/null +++ b/WDL/zlib/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/WDL/zlib/unzip.h b/WDL/zlib/unzip.h new file mode 100644 index 00000000..3183968b --- /dev/null +++ b/WDL/zlib/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/WDL/zlib/zconf.h b/WDL/zlib/zconf.h new file mode 100644 index 00000000..51c80ac1 --- /dev/null +++ b/WDL/zlib/zconf.h @@ -0,0 +1,466 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflags z_gzflags +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# endif +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# ifndef Z_SOLO +# define gz_header_s z_gz_header_s +# endif +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define Z_LARGE +#endif + +#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0) +# define z_off64_t off64_t +#else +# if defined(_WIN32) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +#endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/WDL/zlib/zconf.in.h b/WDL/zlib/zconf.in.h new file mode 100644 index 00000000..e3b0c962 --- /dev/null +++ b/WDL/zlib/zconf.in.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/WDL/zlib/zip.c b/WDL/zlib/zip.c new file mode 100644 index 00000000..deb9b3a9 --- /dev/null +++ b/WDL/zlib/zip.c @@ -0,0 +1,2012 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + + +#ifndef NOCRYPT + #define NOCRYPT +#endif + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + (crcForCrypting); + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/WDL/zlib/zip.h b/WDL/zlib/zip.h new file mode 100644 index 00000000..8aaebb62 --- /dev/null +++ b/WDL/zlib/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/WDL/zlib/zlib.h b/WDL/zlib/zlib.h new file mode 100644 index 00000000..4e1aea89 --- /dev/null +++ b/WDL/zlib/zlib.h @@ -0,0 +1,1732 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.6, January 29th, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.6.f" +#define ZLIB_VERNUM 0x126f +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 6 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is not required to perform an + inflation in one step. However it may be used to inform inflate that a + faster approach can be used for the single inflate() call. Z_FINISH also + informs inflate to not maintain a sliding window if the stream completes, + which reduces inflate's memory footprint. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); +#define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc_(g)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#ifndef Z_SOLO + ZEXTERN unsigned long ZEXPORT gzflags OF((void)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/WDL/zlib/zutil.c b/WDL/zlib/zutil.c new file mode 100644 index 00000000..835b4d46 --- /dev/null +++ b/WDL/zlib/zutil.c @@ -0,0 +1,303 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + +#if 0 + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef Z_SOLO + return flags; +#else + return flags + gzflags(); +#endif +} +#endif + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/WDL/zlib/zutil.h b/WDL/zlib/zutil.h new file mode 100644 index 00000000..dff1112f --- /dev/null +++ b/WDL/zlib/zutil.h @@ -0,0 +1,248 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/English.lproj/InfoPlist.strings b/licecap/English.lproj/InfoPlist.strings similarity index 100% rename from English.lproj/InfoPlist.strings rename to licecap/English.lproj/InfoPlist.strings diff --git a/English.lproj/MainMenu.xib b/licecap/English.lproj/MainMenu.xib similarity index 100% rename from English.lproj/MainMenu.xib rename to licecap/English.lproj/MainMenu.xib diff --git a/background.png b/licecap/background.png similarity index 100% rename from background.png rename to licecap/background.png diff --git a/capturewindow.mm b/licecap/capturewindow.mm similarity index 100% rename from capturewindow.mm rename to licecap/capturewindow.mm diff --git a/icon1.ico b/licecap/icon1.ico similarity index 100% rename from icon1.ico rename to licecap/icon1.ico diff --git a/installer.nsi b/licecap/installer.nsi similarity index 100% rename from installer.nsi rename to licecap/installer.nsi diff --git a/licecap-Info.plist b/licecap/licecap-Info.plist similarity index 100% rename from licecap-Info.plist rename to licecap/licecap-Info.plist diff --git a/licecap.dsw b/licecap/licecap.dsw similarity index 100% rename from licecap.dsw rename to licecap/licecap.dsw diff --git a/licecap.icns b/licecap/licecap.icns similarity index 100% rename from licecap.icns rename to licecap/licecap.icns diff --git a/licecap.rc b/licecap/licecap.rc similarity index 100% rename from licecap.rc rename to licecap/licecap.rc diff --git a/licecap.xcodeproj/project.pbxproj b/licecap/licecap.xcodeproj/project.pbxproj similarity index 100% rename from licecap.xcodeproj/project.pbxproj rename to licecap/licecap.xcodeproj/project.pbxproj diff --git a/licecap_Prefix.pch b/licecap/licecap_Prefix.pch similarity index 100% rename from licecap_Prefix.pch rename to licecap/licecap_Prefix.pch diff --git a/licecap_cli.cpp b/licecap/licecap_cli.cpp similarity index 100% rename from licecap_cli.cpp rename to licecap/licecap_cli.cpp diff --git a/licecap_cli.dsp b/licecap/licecap_cli.dsp similarity index 100% rename from licecap_cli.dsp rename to licecap/licecap_cli.dsp diff --git a/licecap_gui.dsp b/licecap/licecap_gui.dsp similarity index 100% rename from licecap_gui.dsp rename to licecap/licecap_gui.dsp diff --git a/licecap_ui.cpp b/licecap/licecap_ui.cpp similarity index 100% rename from licecap_ui.cpp rename to licecap/licecap_ui.cpp diff --git a/licecap_version.h b/licecap/licecap_version.h similarity index 100% rename from licecap_version.h rename to licecap/licecap_version.h diff --git a/license.txt b/licecap/license.txt similarity index 100% rename from license.txt rename to licecap/license.txt diff --git a/main.m b/licecap/main.m similarity index 100% rename from main.m rename to licecap/main.m diff --git a/makedmg.sh b/licecap/makedmg.sh similarity index 100% rename from makedmg.sh rename to licecap/makedmg.sh diff --git a/pkg-dmg b/licecap/pkg-dmg similarity index 100% rename from pkg-dmg rename to licecap/pkg-dmg diff --git a/requires_wdl.txt b/licecap/requires_wdl.txt similarity index 100% rename from requires_wdl.txt rename to licecap/requires_wdl.txt diff --git a/resource.h b/licecap/resource.h similarity index 100% rename from resource.h rename to licecap/resource.h diff --git a/stage_DS_Store b/licecap/stage_DS_Store similarity index 100% rename from stage_DS_Store rename to licecap/stage_DS_Store diff --git a/whatsnew.txt b/licecap/whatsnew.txt similarity index 100% rename from whatsnew.txt rename to licecap/whatsnew.txt